All files / packages/design-system/scripts/scs version-utils.js

100% Statements 30/30
95% Branches 19/20
100% Functions 9/9
100% Lines 26/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108                2x                     774x 774x 774x 773x 773x   774x 2322x   774x                     24x                         4x                   5x 5x 5x 5x 5x                     2x                 4x     4x 4x 2x                   2x 2x 2x 2x 2x    
/**
 * Version Utilities
 * Lightweight replacement for auto-version-js, providing the same API
 * surface used by the SCS scripts.
 */
import fs from 'node:fs';
import path from 'node:path';
 
const versionRegex = /(\d+)\.?(\d+)?.?(\d+)?/i;
 
/**
 * Parse a version string (or any string containing a version) into components
 * @param {string} versionString - String containing a version number
 * @returns {{ major: number, minor: number, patch: number }}
 * @example
 * parse('1.4.2')  // --> { major: 1, minor: 4, patch: 2 }
 * parse('slds-2.30.0.css')  // --> { major: 2, minor: 30, patch: 0 }
 */
export function parse(versionString) {
  let versionObject = { major: 0, minor: 0, patch: 0 };
  const match = versionString.match(versionRegex);
  if (match) {
    const [, major, minor, patch] = match;
    versionObject = { major, minor, patch };
  }
  Object.entries(versionObject).forEach(([key, value]) =>
    !value ? (versionObject[key] = 0) : (versionObject[key] = parseInt(value)),
  );
  return versionObject;
}
 
/**
 * Stringify a version object back to a version string
 * @param {{ major: number, minor: number, patch: number }} versionObject
 * @returns {string}
 * @example
 * stringify({ major: 1, minor: 4, patch: 2 })  // --> '1.4.2'
 */
export function stringify(versionObject) {
  return Object.values(versionObject).reduce((prev, curr) => `${prev}.${curr}`);
}
 
/**
 * Convert a version string to semver standard (X.Y.Z)
 * @param {string} versionString
 * @returns {string}
 * @example
 * toSemver('1.3.5')      // --> '1.3.5'
 * toSemver('1.3')         // --> '1.3.0'
 * toSemver('v1.3.5')      // --> '1.3.5'
 */
export function toSemver(versionString) {
  return stringify(parse(versionString));
}
 
/**
 * Increment the version at the given level
 * @param {string} version
 * @param {'major'|'minor'|'patch'} level
 * @returns {string}
 */
export function increment(version, level) {
  const v = parse(version);
  v[level.toLowerCase()]++;
  if (level === 'major' || level === 'minor') v.patch = 0;
  if (level === 'major') v.minor = 0;
  return stringify(v);
}
 
/**
 * Bump the patch version
 * @param {string} version
 * @returns {string}
 * @example
 * patch('1.0.0')  // --> '1.0.1'
 */
export function patch(version) {
  return increment(version, 'patch');
}
 
/**
 * Read the version from a package.json file
 * @param {string} pathname - Path to a directory containing package.json, or to package.json itself
 * @returns {string} The version string
 */
export function getVersion(pathname) {
  const pkgPath = pathname.endsWith('package.json')
    ? pathname
    : path.resolve(pathname, 'package.json');
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
  if (!pkg || !pkg.version) throw new Error(`Unable to read version from ${pkgPath}`);
  return pkg.version;
}
 
/**
 * Write a version to the package.json in the current working directory
 * @param {string} version - The version to set
 * @param {string} [pathname] - Path to directory containing package.json (defaults to cwd)
 * @param {number} [indentation=2] - JSON indentation
 */
export function setVersion(version, pathname, indentation) {
  const dir = pathname || process.cwd();
  const pkgPath = path.resolve(dir, 'package.json');
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
  pkg.version = version;
  fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, indentation || 2));
}