|
| 1 | +/* eslint-disable no-undef */ |
| 2 | +/** |
| 3 | + * This is a minimal script to publish your package to "npm". |
| 4 | + * This is meant to be used as-is or customize as you see fit. |
| 5 | + * |
| 6 | + * This script is executed on "dist/path/to/library" as "cwd" by default. |
| 7 | + * |
| 8 | + * You might need to authenticate with NPM before running this script. |
| 9 | + */ |
| 10 | +import mainPackageJson from '../package.json' with { type: 'json' }; |
| 11 | + |
| 12 | +import { execSync } from 'child_process'; |
| 13 | +import { readFileSync, writeFileSync } from 'fs'; |
| 14 | +import minimist from 'minimist'; |
| 15 | + |
| 16 | +console.log('Version in package.json', mainPackageJson.version); |
| 17 | + |
| 18 | +function invariant(condition, message) { |
| 19 | + if (!condition) { |
| 20 | + console.error(message); |
| 21 | + process.exit(1); |
| 22 | + } |
| 23 | +} |
| 24 | + |
| 25 | +// Executing publish script: node path/to/publish.mjs {name} --version {version} --tag {tag} |
| 26 | +// Default "tag" to "next" so we won't publish the "latest" tag by accident. |
| 27 | +let params = minimist(process.argv); |
| 28 | +let version = params.version; |
| 29 | +const isDevelopment = params.development; |
| 30 | +const dry = params.dry === true || params.dry === 'true'; |
| 31 | +const tag = params.tag || 'next'; |
| 32 | +const name = mainPackageJson.name; |
| 33 | + |
| 34 | +console.info( |
| 35 | + `\nPublish run with next values:\nname=${name}\nversion=${version}\ndry=${dry}\ntag=${tag}\ndevelopment=${isDevelopment}\n`, |
| 36 | +); |
| 37 | + |
| 38 | +const getVersion = (version) => { |
| 39 | + let potentialVersion = version; |
| 40 | + |
| 41 | + if (isDevelopment && !version) { |
| 42 | + potentialVersion = getDevVersion(potentialVersion); |
| 43 | + invariant( |
| 44 | + potentialVersion !== 'dev', |
| 45 | + `Version calculated incorrectly - still equal 'dev'.`, |
| 46 | + ); |
| 47 | + } |
| 48 | + |
| 49 | + return potentialVersion || mainPackageJson.version; |
| 50 | +}; |
| 51 | +version = getVersion(version); |
| 52 | + |
| 53 | +// A simple SemVer validation to validate the version |
| 54 | +const validVersion = /^\d+\.\d+\.\d+(-\w+\.\d+)?/; |
| 55 | +invariant( |
| 56 | + version && (validVersion.test(version) || version === 'dev'), |
| 57 | + `No version provided or version did not match Semantic Versioning, expected: #.#.#-tag.# or #.#.# or special name 'dev', got ${version}.`, |
| 58 | +); |
| 59 | + |
| 60 | +try { |
| 61 | + const json = JSON.parse(readFileSync(`package.json`).toString()); |
| 62 | + console.info(`Setting version in package.json to ${version}`); |
| 63 | + json.version = version; |
| 64 | + |
| 65 | + writeFileSync(`package.json`, JSON.stringify(json, null, 2)); |
| 66 | +} catch { |
| 67 | + console.error(`Error reading package.json file from library build output.`); |
| 68 | +} |
| 69 | + |
| 70 | +try { |
| 71 | + console.log( |
| 72 | + `Running publish command: npm publish --access public --tag ${tag}`, |
| 73 | + ); |
| 74 | + // Execute "npm publish" to publish |
| 75 | + execSync(`npm publish --access public --tag ${tag}`); |
| 76 | +} catch { |
| 77 | + console.error(`Publish failed.`); |
| 78 | +} |
| 79 | + |
| 80 | +function getDevVersion(potentialVersion) { |
| 81 | + let result; |
| 82 | + try { |
| 83 | + result = JSON.parse( |
| 84 | + execSync(`npm view ${name} versions --json`).toString(), |
| 85 | + ); |
| 86 | + } catch (e) { |
| 87 | + if (JSON.parse(e.stdout).error.code === 'E404') { |
| 88 | + console.warn( |
| 89 | + `Could not get versions from registry. Version from package.json will be used.\n `, |
| 90 | + ); |
| 91 | + |
| 92 | + result = []; |
| 93 | + } else { |
| 94 | + throw new Error(`Could not get versions from registry.`); |
| 95 | + } |
| 96 | + } |
| 97 | + |
| 98 | + if (!result) { |
| 99 | + throw new Error(`Could not get version.`); |
| 100 | + } |
| 101 | + |
| 102 | + if (!Array.isArray(result) && typeof result === 'string') { |
| 103 | + result = [result]; |
| 104 | + } |
| 105 | + |
| 106 | + console.info( |
| 107 | + `Calculating version increment based on package version (${mainPackageJson.version}) and version from registry (${JSON.stringify(result)})`, |
| 108 | + ); |
| 109 | + |
| 110 | + const lastVersionToIncrement = result |
| 111 | + .filter((ver) => ver.startsWith(mainPackageJson.version)) |
| 112 | + .map((ver) => ver.match(/\d+$/)?.[0]) |
| 113 | + .filter(Boolean) |
| 114 | + .map((ver) => parseInt(ver, 10)) |
| 115 | + .sort((a, b) => a - b) |
| 116 | + .reverse()[0]; |
| 117 | + |
| 118 | + if (typeof lastVersionToIncrement === 'undefined') { |
| 119 | + potentialVersion = `${mainPackageJson.version}.0`; |
| 120 | + } else { |
| 121 | + const incrementedNum = lastVersionToIncrement + 1; |
| 122 | + potentialVersion = `${mainPackageJson.version}.${incrementedNum}`; |
| 123 | + } |
| 124 | + console.warn( |
| 125 | + `Version of development package for ${name} will be: ${potentialVersion}`, |
| 126 | + ); |
| 127 | + return potentialVersion; |
| 128 | +} |
0 commit comments