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                3x                     928x 928x 928x 927x 927x   928x 2784x   928x                     28x                         4x                   7x 7x 7x 7x 7x                     4x                 5x     5x 5x 3x                   4x 4x 4x 4x 4x    
/**
 * 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));
}