@storm-software/workspace-tools
Version:
Tools for managing a Storm workspace, including various Nx generators and executors for common development tasks.
525 lines (483 loc) • 23.7 kB
JavaScript
;Object.defineProperty(exports, "__esModule", {value: true}); async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
var _chunkMKJITWLNjs = require('./chunk-MKJITWLN.js');
var _chunkGUO7GHMYjs = require('./chunk-GUO7GHMY.js');
var _chunkA5RNIDQZjs = require('./chunk-A5RNIDQZ.js');
var _chunkLMYTVXGXjs = require('./chunk-LMYTVXGX.js');
var _chunkCQDBLKPFjs = require('./chunk-CQDBLKPF.js');
// ../npm-tools/src/helpers/get-registry.ts
var _child_process = require('child_process');
// ../npm-tools/src/constants.ts
var DEFAULT_NPM_REGISTRY = "https://registry.npmjs.org";
// ../npm-tools/src/helpers/get-registry.ts
async function getRegistry(executable = "npm") {
return new Promise((resolve, reject) => {
_child_process.exec.call(void 0, `${executable} config get registry`, (error, stdout, stderr) => {
if (error && !error.message.toLowerCase().trim().startsWith("npm warn")) {
return reject(error);
}
if (stderr && !stderr.toLowerCase().trim().startsWith("npm warn")) {
return reject(stderr);
}
return resolve(stdout.trim());
});
});
}
async function getNpmRegistry() {
if (process.env.STORM_REGISTRY_NPM) {
return process.env.STORM_REGISTRY_NPM;
}
const workspaceConfig = await _chunkA5RNIDQZjs.getConfig.call(void 0, );
if (_optionalChain([workspaceConfig, 'optionalAccess', _ => _.registry, 'optionalAccess', _2 => _2.npm])) {
return _optionalChain([workspaceConfig, 'optionalAccess', _3 => _3.registry, 'optionalAccess', _4 => _4.npm]);
}
return DEFAULT_NPM_REGISTRY;
}
// ../pnpm-tools/src/helpers/replace-deps-aliases.ts
var _devkit = require('@nx/devkit');
var _fs = require('fs');
var _promises = require('fs/promises');
var _prettier = require('prettier');
// ../npm-tools/src/helpers/get-version.ts
// ../pnpm-tools/src/helpers/catalog.ts
var _semver = require('semver');
// ../pnpm-tools/src/helpers/pnpm-workspace.ts
var _yaml = require('yaml');
function getPnpmWorkspaceFilePath(workspaceRoot = _chunkLMYTVXGXjs.findWorkspaceRoot.call(void 0, process.cwd())) {
const pnpmWorkspacePath = _chunkCQDBLKPFjs.joinPaths.call(void 0, workspaceRoot, "pnpm-workspace.yaml");
if (!_fs.existsSync.call(void 0, pnpmWorkspacePath)) {
throw new Error(
`No \`pnpm-workspace.yaml\` file found in workspace root (searched in: ${pnpmWorkspacePath}).`
);
}
return pnpmWorkspacePath;
}
async function readPnpmWorkspaceFile(workspaceRoot = _chunkLMYTVXGXjs.findWorkspaceRoot.call(void 0, process.cwd())) {
const result = await _promises.readFile.call(void 0,
getPnpmWorkspaceFilePath(workspaceRoot),
"utf8"
);
if (!result) {
return void 0;
}
return _yaml.parse.call(void 0, result);
}
// ../pnpm-tools/src/helpers/catalog.ts
async function getCatalogSafe(workspaceRoot = _chunkLMYTVXGXjs.findWorkspaceRoot.call(void 0, process.cwd())) {
const pnpmWorkspaceFile = await readPnpmWorkspaceFile(workspaceRoot);
if (!pnpmWorkspaceFile) {
throw new Error("No pnpm-workspace.yaml file found");
}
if (_optionalChain([pnpmWorkspaceFile, 'optionalAccess', _5 => _5.catalog])) {
return Object.fromEntries(
Object.entries(pnpmWorkspaceFile.catalog).map(([key, value]) => {
return [key, value.replaceAll('"', "").replaceAll("'", "")];
})
);
} else {
console.warn(
`No catalog found in pnpm-workspace.yaml file located in workspace root: ${workspaceRoot}
File content: ${JSON.stringify(
pnpmWorkspaceFile,
null,
2
)}`
);
}
return void 0;
}
async function getCatalog(workspaceRoot = _chunkLMYTVXGXjs.findWorkspaceRoot.call(void 0, process.cwd())) {
const catalog = await getCatalogSafe(workspaceRoot);
if (!catalog) {
throw new Error("No catalog entries found in pnpm-workspace.yaml file");
}
return catalog;
}
// ../pnpm-tools/src/helpers/replace-deps-aliases.ts
async function replaceDepsAliases(packageRoot = process.cwd(), workspaceRoot = _chunkLMYTVXGXjs.findWorkspaceRoot.call(void 0, packageRoot)) {
const packageJsonPath = _chunkCQDBLKPFjs.joinPaths.call(void 0, packageRoot, "package.json");
const packageJsonFile = await _promises.readFile.call(void 0, packageJsonPath, "utf8");
if (!packageJsonFile) {
throw new Error(
"No package.json file found in package root: " + packageRoot
);
}
const catalog = await getCatalog(workspaceRoot);
const packageJson = JSON.parse(packageJsonFile);
const pnpmWorkspacePath = _chunkCQDBLKPFjs.joinPaths.call(void 0, workspaceRoot, "pnpm-workspace.yaml");
if (!_fs.existsSync.call(void 0, pnpmWorkspacePath)) {
console.warn(
`No \`pnpm-workspace.yaml\` file found in workspace root (searching in: ${pnpmWorkspacePath}). Skipping pnpm catalog read for now.`
);
return packageJson;
}
if (!catalog) {
console.warn(
`No pnpm catalog found. Skipping dependencies replacement for now.`
);
return;
}
for (const dependencyType of [
"dependencies",
"devDependencies",
"peerDependencies"
]) {
const dependencies = packageJson[dependencyType];
if (!dependencies) {
continue;
}
for (const dependencyName of Object.keys(dependencies)) {
if (dependencies[dependencyName] === "catalog:") {
if (!catalog) {
throw new Error(
`Dependency ${dependencyName} is marked as \`catalog:\`, but no catalog exists in the workspace root's \`pnpm-workspace.yaml\` file.`
);
}
const catalogVersion = catalog[dependencyName];
if (!catalogVersion) {
throw new Error("Missing pnpm catalog version for " + dependencyName);
}
dependencies[dependencyName] = catalogVersion;
} else if (dependencies[dependencyName].startsWith("catalog:")) {
throw new Error("multiple named catalogs not supported");
}
}
}
let projectGraph;
try {
projectGraph = _devkit.readCachedProjectGraph.call(void 0, );
} catch (e) {
await _devkit.createProjectGraphAsync.call(void 0, );
projectGraph = _devkit.readCachedProjectGraph.call(void 0, );
}
const workspacePackages = {};
if (projectGraph) {
await Promise.all(
Object.keys(projectGraph.nodes).map(async (node) => {
const projectNode = projectGraph.nodes[node];
if (_optionalChain([projectNode, 'optionalAccess', _6 => _6.data, 'access', _7 => _7.root])) {
const projectPackageJsonPath = _chunkCQDBLKPFjs.joinPaths.call(void 0,
workspaceRoot,
projectNode.data.root,
"package.json"
);
if (_fs.existsSync.call(void 0, projectPackageJsonPath)) {
const projectPackageJsonContent = await _promises.readFile.call(void 0,
projectPackageJsonPath,
"utf8"
);
const projectPackageJson = JSON.parse(projectPackageJsonContent);
if (projectPackageJson.private !== true) {
workspacePackages[projectPackageJson.name] = projectPackageJson.version;
}
}
}
})
);
}
for (const dependencyType of [
"dependencies",
"devDependencies",
"peerDependencies"
]) {
const dependencies = packageJson[dependencyType];
if (!dependencies) {
continue;
}
for (const dependencyName of Object.keys(dependencies)) {
if (dependencies[dependencyName].startsWith("workspace:")) {
if (workspacePackages[dependencyName]) {
dependencies[dependencyName] = `^${workspacePackages[dependencyName]}`;
} else {
throw new Error(
`Workspace dependency ${dependencyName} not found in workspace packages.`
);
}
}
}
}
return _promises.writeFile.call(void 0,
packageJsonPath,
await _prettier.format.call(void 0, JSON.stringify(packageJson), {
parser: "json",
proseWrap: "preserve",
trailingComma: "none",
tabWidth: 2,
semi: true,
singleQuote: false,
quoteProps: "as-needed",
insertPragma: false,
bracketSameLine: true,
printWidth: 80,
bracketSpacing: true,
arrowParens: "avoid",
endOfLine: "lf",
plugins: ["prettier-plugin-packagejson"]
})
);
}
// src/executors/npm-publish/executor.ts
var LARGE_BUFFER = 1024 * 1e6;
async function npmPublishExecutorFn(options, context) {
const workspaceConfig = await _chunkA5RNIDQZjs.getConfig.call(void 0, context.root);
const github = await _chunkMKJITWLNjs.getGitHubTools.call(void 0, workspaceConfig);
const isDryRun = process.env.NX_DRY_RUN === "true" || options.dryRun || false;
if (!context.projectName) {
github.error("The `npm-publish` executor requires a `projectName`.");
return { success: false };
}
const projectConfig = _optionalChain([context, 'access', _8 => _8.projectsConfigurations, 'optionalAccess', _9 => _9.projects, 'optionalAccess', _10 => _10[context.projectName]]);
if (!projectConfig) {
github.error(
`Could not find project configuration for \`${context.projectName}\``
);
return { success: false };
}
const packageRoot = _chunkCQDBLKPFjs.joinPaths.call(void 0,
context.root,
options.packageRoot || _chunkCQDBLKPFjs.joinPaths.call(void 0, "dist", projectConfig.root)
);
const projectRoot = _optionalChain([context, 'access', _11 => _11.projectsConfigurations, 'access', _12 => _12.projects, 'access', _13 => _13[context.projectName], 'optionalAccess', _14 => _14.root]) ? _chunkCQDBLKPFjs.joinPaths.call(void 0,
context.root,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
context.projectsConfigurations.projects[context.projectName].root
) : packageRoot;
const packageJsonPath = _chunkCQDBLKPFjs.joinPaths.call(void 0, packageRoot, "package.json");
const packageJsonFile = await _promises.readFile.call(void 0, packageJsonPath, "utf8");
if (!packageJsonFile) {
github.error(`Could not find \`package.json\` at ${packageJsonPath}`);
return { success: false };
}
const packageJson = JSON.parse(packageJsonFile);
const projectPackageJsonPath = _chunkCQDBLKPFjs.joinPaths.call(void 0, projectRoot, "package.json");
const projectPackageJsonFile = await _promises.readFile.call(void 0, projectPackageJsonPath, "utf8");
if (!projectPackageJsonFile) {
github.error(
`Could not find \`package.json\` at ${projectPackageJsonPath}`
);
return { success: false };
}
const projectPackageJson = JSON.parse(projectPackageJsonFile);
if (packageJson.version !== projectPackageJson.version) {
console.warn(
`The version in the package.json file at ${packageJsonPath} (current: ${packageJson.version}) does not match the version in the package.json file at ${projectPackageJsonPath} (current: ${projectPackageJson.version}). This file will be updated to match the version in the project package.json file.`
);
if (projectPackageJson.version) {
packageJson.version = projectPackageJson.version;
await _promises.writeFile.call(void 0,
packageJsonPath,
await _prettier.format.call(void 0, JSON.stringify(packageJson), {
parser: "json",
proseWrap: "preserve",
trailingComma: "none",
tabWidth: 2,
semi: true,
singleQuote: false,
quoteProps: "as-needed",
insertPragma: false,
bracketSameLine: true,
printWidth: 80,
bracketSpacing: true,
arrowParens: "avoid",
endOfLine: "lf",
plugins: ["prettier-plugin-packagejson"]
})
);
}
}
const packageName = packageJson.name;
console.info(
`\u{1F680} Running Storm NPM Publish executor on the ${packageName} package`
);
const packageTxt = packageName === context.projectName ? `package "${packageName}"` : `package "${packageName}" from project "${context.projectName}"`;
if (packageJson.private === true) {
console.warn(
`Skipped ${packageTxt}, because it has \`"private": true\` in ${packageJsonPath}`
);
return { success: true };
}
await replaceDepsAliases(packageRoot, context.root);
await _chunkGUO7GHMYjs.addPackageJsonGitHead.call(void 0, packageRoot);
const npmPublishCommandSegments = [`npm publish --json`];
const npmViewCommandSegments = [
`npm view ${packageName} versions dist-tags --json`
];
const registry = await Promise.resolve(
await _asyncNullishCoalesce(options.registry, async () => ( (await getRegistry() || getNpmRegistry())))
);
if (registry) {
npmPublishCommandSegments.push(`--registry="${registry}" `);
npmViewCommandSegments.push(`--registry="${registry}" `);
}
if (options.otp) {
npmPublishCommandSegments.push(`--otp="${options.otp}" `);
}
let token;
if (!options.otp) {
token = await github.getIDToken(
`npm:${registry.replace(/^https?:\/\//, "")}`
);
if (!token) {
github.warning(
`Either a One time password (OTP) or an OpenID Connect (OIDC) token is generally required to publish ${packageTxt} to NPM. Usually the OIDC token should be provided automatically via GitHub Actions (see: https://github.com/actions/toolkit/tree/main/packages/core#oidc-token); however, the release process was unable to retrieve it. Please provide a \`otp\` executor option, or investigate why the OIDC token could not be retrieved.`
);
}
}
npmPublishCommandSegments.push("--provenance --access=public ");
if (isDryRun) {
npmPublishCommandSegments.push("--dry-run");
}
const tag = options.tag || _child_process.execSync.call(void 0, "npm config get tag", {
cwd: packageRoot,
env: {
NPM_ID_TOKEN: token,
...process.env,
FORCE_COLOR: "true"
},
maxBuffer: LARGE_BUFFER,
killSignal: "SIGTERM"
}).toString().trim();
if (tag) {
npmPublishCommandSegments.push(`--tag="${tag}" `);
}
if (!isDryRun) {
const currentVersion = options.version || packageJson.version;
try {
try {
const result = _child_process.execSync.call(void 0, npmViewCommandSegments.join(" "), {
cwd: packageRoot,
env: {
NPM_ID_TOKEN: token,
...process.env,
FORCE_COLOR: "true"
},
maxBuffer: LARGE_BUFFER,
killSignal: "SIGTERM"
});
const resultJson = JSON.parse(result.toString());
const distTags = resultJson["dist-tags"] || {};
if (distTags[tag] === currentVersion) {
console.warn(
`Skipped ${packageTxt} because v${currentVersion} already exists in ${registry} with tag "${tag}"`
);
return { success: true };
}
} catch (err) {
console.debug(
`An error occurred while checking for existing dist-tags. Please note: if this is the first time this package has been published to npm, this can be ignored.
Error: ${JSON.stringify(
err,
null,
2
)}`
);
}
try {
if (!isDryRun) {
const command = `npm dist-tag add ${packageName}@${currentVersion} ${tag} --registry="${registry}" `;
console.debug(
`Adding the dist-tag ${tag} - preparing to run the following: ${command}`
);
const result = _child_process.execSync.call(void 0, command, {
cwd: packageRoot,
env: {
NPM_ID_TOKEN: token,
...process.env,
FORCE_COLOR: "true"
},
maxBuffer: LARGE_BUFFER,
killSignal: "SIGTERM"
});
console.info(
`Added the dist-tag ${tag} to v${currentVersion} for registry "${registry}".
Execution response: ${result.toString()}`
);
} else {
console.info(
`Would have added the dist-tag ${tag} to v${currentVersion} for registry "${registry}", but [dry-run] was set.
`
);
}
return { success: true };
} catch (err) {
try {
const stdoutData = JSON.parse(_optionalChain([err, 'access', _15 => _15.stdout, 'optionalAccess', _16 => _16.toString, 'call', _17 => _17()]) || "{}");
if (_optionalChain([stdoutData, 'optionalAccess', _18 => _18.error]) && !(_optionalChain([stdoutData, 'access', _19 => _19.error, 'optionalAccess', _20 => _20.code, 'optionalAccess', _21 => _21.includes, 'call', _22 => _22("E404")]) && _optionalChain([stdoutData, 'access', _23 => _23.error, 'optionalAccess', _24 => _24.summary, 'optionalAccess', _25 => _25.includes, 'call', _26 => _26("no such package available")])) && !(_optionalChain([err, 'access', _27 => _27.stderr, 'optionalAccess', _28 => _28.toString, 'call', _29 => _29(), 'access', _30 => _30.includes, 'call', _31 => _31("E404")]) && _optionalChain([err, 'access', _32 => _32.stderr, 'optionalAccess', _33 => _33.toString, 'call', _34 => _34(), 'access', _35 => _35.includes, 'call', _36 => _36("no such package available")]))) {
const errorMessage = `An unexpected error occured while running the npm dist-tag add command:
${_optionalChain([stdoutData, 'optionalAccess', _37 => _37.error, 'optionalAccess', _38 => _38.summary]) ? `Summary: ${_optionalChain([stdoutData, 'optionalAccess', _39 => _39.error, 'optionalAccess', _40 => _40.summary])}${_optionalChain([stdoutData, 'optionalAccess', _41 => _41.error, 'optionalAccess', _42 => _42.code]) ? ` (${_optionalChain([stdoutData, 'optionalAccess', _43 => _43.error, 'optionalAccess', _44 => _44.code])})` : ""}
` : ""}${_optionalChain([stdoutData, 'optionalAccess', _45 => _45.error, 'optionalAccess', _46 => _46.detail]) ? `Detail: ${_optionalChain([stdoutData, 'optionalAccess', _47 => _47.error, 'optionalAccess', _48 => _48.detail])}
` : ""}`;
github.error(errorMessage);
return { success: false };
}
} catch (err2) {
const stdoutData = JSON.parse(_optionalChain([err2, 'access', _49 => _49.stdout, 'optionalAccess', _50 => _50.toString, 'call', _51 => _51()]) || "{}");
const errorMessage = `An unexpected error occured while processing the npm dist-tag add output:
${_optionalChain([stdoutData, 'optionalAccess', _52 => _52.error, 'optionalAccess', _53 => _53.summary]) ? `Summary: ${_optionalChain([stdoutData, 'optionalAccess', _54 => _54.error, 'optionalAccess', _55 => _55.summary])}${_optionalChain([stdoutData, 'optionalAccess', _56 => _56.error, 'optionalAccess', _57 => _57.code]) ? ` (${_optionalChain([stdoutData, 'optionalAccess', _58 => _58.error, 'optionalAccess', _59 => _59.code])})` : ""}
` : ""}${_optionalChain([stdoutData, 'optionalAccess', _60 => _60.error, 'optionalAccess', _61 => _61.detail]) ? `Detail: ${_optionalChain([stdoutData, 'optionalAccess', _62 => _62.error, 'optionalAccess', _63 => _63.detail])}
` : ""}`;
github.error(errorMessage);
return { success: false };
}
}
} catch (err) {
const stdoutData = JSON.parse(_optionalChain([err, 'access', _64 => _64.stdout, 'optionalAccess', _65 => _65.toString, 'call', _66 => _66()]) || "{}");
if (!(_optionalChain([stdoutData, 'access', _67 => _67.error, 'optionalAccess', _68 => _68.code, 'optionalAccess', _69 => _69.includes, 'call', _70 => _70("E404")]) && _optionalChain([stdoutData, 'access', _71 => _71.error, 'optionalAccess', _72 => _72.summary, 'optionalAccess', _73 => _73.toLowerCase, 'call', _74 => _74(), 'access', _75 => _75.includes, 'call', _76 => _76("not found")])) && !(_optionalChain([err, 'access', _77 => _77.stderr, 'optionalAccess', _78 => _78.toString, 'call', _79 => _79(), 'access', _80 => _80.includes, 'call', _81 => _81("E404")]) && _optionalChain([err, 'access', _82 => _82.stderr, 'optionalAccess', _83 => _83.toString, 'call', _84 => _84(), 'access', _85 => _85.toLowerCase, 'call', _86 => _86(), 'access', _87 => _87.includes, 'call', _88 => _88("not found")]))) {
const errorMessage = `An unexpected error occured while checking for existing dist-tags:
${_optionalChain([stdoutData, 'optionalAccess', _89 => _89.error, 'optionalAccess', _90 => _90.summary]) ? `Summary: ${_optionalChain([stdoutData, 'optionalAccess', _91 => _91.error, 'optionalAccess', _92 => _92.summary])}${_optionalChain([stdoutData, 'optionalAccess', _93 => _93.error, 'optionalAccess', _94 => _94.code]) ? ` (${_optionalChain([stdoutData, 'optionalAccess', _95 => _95.error, 'optionalAccess', _96 => _96.code])})` : ""}
` : ""}${_optionalChain([stdoutData, 'optionalAccess', _97 => _97.error, 'optionalAccess', _98 => _98.detail]) ? `Detail: ${_optionalChain([stdoutData, 'optionalAccess', _99 => _99.error, 'optionalAccess', _100 => _100.detail])}
` : ""}`;
github.error(errorMessage);
return { success: false };
}
}
}
try {
const cwd = packageRoot;
const command = npmPublishCommandSegments.join(" ");
console.info(
`Running publish command "${command}" in current working directory: "${cwd}" `
);
const result = _child_process.execSync.call(void 0, command, {
cwd,
env: {
NPM_ID_TOKEN: token,
...process.env,
FORCE_COLOR: "true"
},
maxBuffer: LARGE_BUFFER,
killSignal: "SIGTERM"
});
if (isDryRun) {
console.info(
`Would publish tag "${tag}" to ${registry}, but [dry-run] was set. ${result ? `
Execution response: ${result.toString()}` : ""}`
);
} else {
console.info(
`Published tag "${tag}" to ${registry}. ${result ? `
Execution response: ${result.toString()}` : ""}`
);
}
return { success: true };
} catch (err) {
try {
const stdoutData = JSON.parse(_optionalChain([err, 'access', _101 => _101.stdout, 'optionalAccess', _102 => _102.toString, 'call', _103 => _103()]) || "{}");
const errorMessage = `An error occurred while publishing the npm package:
${_optionalChain([stdoutData, 'optionalAccess', _104 => _104.error, 'optionalAccess', _105 => _105.summary]) ? `Summary: ${_optionalChain([stdoutData, 'optionalAccess', _106 => _106.error, 'optionalAccess', _107 => _107.summary])}${_optionalChain([stdoutData, 'optionalAccess', _108 => _108.error, 'optionalAccess', _109 => _109.code]) ? ` (${_optionalChain([stdoutData, 'optionalAccess', _110 => _110.error, 'optionalAccess', _111 => _111.code])})` : ""}
` : ""}${_optionalChain([stdoutData, 'optionalAccess', _112 => _112.error, 'optionalAccess', _113 => _113.detail]) ? `Detail: ${_optionalChain([stdoutData, 'optionalAccess', _114 => _114.error, 'optionalAccess', _115 => _115.detail])}
` : ""}`;
github.error(errorMessage);
return { success: false };
} catch (err2) {
const errorMessage = `Something unexpected went wrong when processing the npm publish output.
Error: ${JSON.stringify(
Buffer.isBuffer(err2) ? err2.toString() : err2,
null,
2
)}`;
github.error(errorMessage);
return { success: false };
}
}
}
exports.LARGE_BUFFER = LARGE_BUFFER; exports.npmPublishExecutorFn = npmPublishExecutorFn;