@smoothbricks/cli 0.10.2 → 0.10.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -23
- package/dist/bun/preload.d.ts +13 -0
- package/dist/bun/preload.d.ts.map +1 -0
- package/dist/bun/preload.js +12 -0
- package/dist/cli.js +36 -4
- package/dist/generate/index.d.ts.map +1 -1
- package/dist/generate/index.js +0 -6
- package/dist/github-ci/index.d.ts +17 -2
- package/dist/github-ci/index.d.ts.map +1 -1
- package/dist/github-ci/index.js +192 -26
- package/dist/github-ci/outputs.d.ts +22 -0
- package/dist/github-ci/outputs.d.ts.map +1 -0
- package/dist/github-ci/outputs.js +648 -0
- package/dist/lib/cli-package.js +2 -2
- package/dist/lib/json.d.ts +118 -11
- package/dist/lib/json.d.ts.map +1 -1
- package/dist/lib/json.js +317 -29
- package/dist/lib/workspace.d.ts +7 -14
- package/dist/lib/workspace.d.ts.map +1 -1
- package/dist/lib/workspace.js +76 -82
- package/dist/monorepo/ci-workflow.d.ts +2 -0
- package/dist/monorepo/ci-workflow.d.ts.map +1 -1
- package/dist/monorepo/ci-workflow.js +28 -2
- package/dist/monorepo/git-config.js +2 -2
- package/dist/monorepo/index.d.ts +3 -1
- package/dist/monorepo/index.d.ts.map +1 -1
- package/dist/monorepo/index.js +6 -2
- package/dist/monorepo/lockfile.d.ts +13 -1
- package/dist/monorepo/lockfile.d.ts.map +1 -1
- package/dist/monorepo/lockfile.js +33 -21
- package/dist/monorepo/managed-files.d.ts +12 -0
- package/dist/monorepo/managed-files.d.ts.map +1 -1
- package/dist/monorepo/managed-files.js +86 -28
- package/dist/monorepo/package-policy.d.ts.map +1 -1
- package/dist/monorepo/package-policy.js +78 -45
- package/dist/monorepo/packed-manifest.d.ts +5 -2
- package/dist/monorepo/packed-manifest.d.ts.map +1 -1
- package/dist/monorepo/packed-manifest.js +16 -47
- package/dist/monorepo/packed-package.d.ts.map +1 -1
- package/dist/monorepo/packed-package.js +28 -16
- package/dist/monorepo/packs/index.d.ts +3 -0
- package/dist/monorepo/packs/index.d.ts.map +1 -1
- package/dist/monorepo/packs/index.js +18 -6
- package/dist/monorepo/publish-workflow.d.ts +1 -0
- package/dist/monorepo/publish-workflow.d.ts.map +1 -1
- package/dist/monorepo/publish-workflow.js +242 -3
- package/dist/monorepo/runtime.d.ts +15 -0
- package/dist/monorepo/runtime.d.ts.map +1 -1
- package/dist/monorepo/runtime.js +66 -12
- package/dist/monorepo/tool-validation.d.ts.map +1 -1
- package/dist/monorepo/tool-validation.js +32 -23
- package/dist/monorepo/wrangler.d.ts.map +1 -1
- package/dist/monorepo/wrangler.js +13 -13
- package/dist/nx/index.d.ts +12 -4
- package/dist/nx/index.d.ts.map +1 -1
- package/dist/nx/index.js +86 -19
- package/dist/pr/index.d.ts.map +1 -1
- package/dist/pr/index.js +28 -32
- package/dist/release/candidates.d.ts +3 -2
- package/dist/release/candidates.d.ts.map +1 -1
- package/dist/release/candidates.js +4 -5
- package/dist/release/github-release.d.ts +3 -0
- package/dist/release/github-release.d.ts.map +1 -1
- package/dist/release/github-release.js +11 -0
- package/dist/release/index.d.ts +20 -1
- package/dist/release/index.d.ts.map +1 -1
- package/dist/release/index.js +221 -89
- package/dist/release/orchestration.d.ts +8 -1
- package/dist/release/orchestration.d.ts.map +1 -1
- package/dist/release/orchestration.js +38 -1
- package/dist/wrangler/prepare-env.d.ts +0 -1
- package/dist/wrangler/prepare-env.d.ts.map +1 -1
- package/dist/wrangler/prepare-env.js +100 -51
- package/dist/wrangler/scaffold.d.ts.map +1 -1
- package/dist/wrangler/scaffold.js +12 -12
- package/managed/raw/git-format-staged.yml +19 -1
- package/managed/raw/tooling/direnv/github-actions-bootstrap.sh +6 -0
- package/managed/raw/tooling/direnv/merge-newer-pins.sh +3 -3
- package/managed/raw/tooling/direnv/setup-environment.ts +187 -19
- package/managed/raw/tooling/git-hooks/pre-commit.sh +0 -6
- package/managed/templates/github/actions/cache-nix-devenv/action.yml +12 -10
- package/managed/templates/github/actions/cache-node-modules/action.yml +6 -2
- package/managed/templates/github/actions/cache-nx/action.yml +2 -2
- package/managed/templates/github/actions/cache-ttsc-plugins/action.yml +19 -0
- package/managed/templates/github/actions/save-nix-devenv/action.yml +11 -3
- package/managed/templates/github/actions/setup-devenv/action.yml +5 -0
- package/managed/templates/github/workflows/managed-files.yml +80 -0
- package/package.json +18 -4
- package/src/bun/preload.ts +12 -0
- package/src/cli.ts +49 -11
- package/src/generate/index.ts +0 -6
- package/src/github-ci/index.test.ts +486 -0
- package/src/github-ci/index.ts +220 -30
- package/src/github-ci/outputs.ts +505 -0
- package/src/lib/cli-package.ts +2 -2
- package/src/lib/json.ts +291 -32
- package/src/lib/workspace.ts +88 -100
- package/src/monorepo/__tests__/ci-workflow.test.ts +14 -3
- package/src/monorepo/__tests__/publish-workflow.test.ts +222 -1
- package/src/monorepo/ci-workflow.ts +28 -2
- package/src/monorepo/git-config.ts +2 -2
- package/src/monorepo/index.ts +6 -2
- package/src/monorepo/lockfile.test.ts +35 -36
- package/src/monorepo/lockfile.ts +48 -24
- package/src/monorepo/managed-files.test.ts +63 -0
- package/src/monorepo/managed-files.ts +94 -34
- package/src/monorepo/package-policy.test.ts +70 -51
- package/src/monorepo/package-policy.ts +104 -59
- package/src/monorepo/packed-manifest.ts +18 -52
- package/src/monorepo/packed-package.ts +43 -22
- package/src/monorepo/packs/index.test.ts +18 -1
- package/src/monorepo/packs/index.ts +20 -7
- package/src/monorepo/publish-workflow.ts +482 -3
- package/src/monorepo/runtime.test.ts +42 -3
- package/src/monorepo/runtime.ts +90 -12
- package/src/monorepo/tool-validation.ts +35 -25
- package/src/monorepo/wrangler.test.ts +11 -15
- package/src/monorepo/wrangler.ts +15 -15
- package/src/nx/index.test.ts +43 -0
- package/src/nx/index.ts +110 -23
- package/src/pr/index.ts +42 -36
- package/src/release/__tests__/candidates.test.ts +5 -4
- package/src/release/__tests__/fixture-repo.test.ts +18 -16
- package/src/release/__tests__/github-release.test.ts +11 -0
- package/src/release/__tests__/orchestration.test.ts +57 -2
- package/src/release/__tests__/trust-publisher.test.ts +98 -2
- package/src/release/candidates.ts +10 -17
- package/src/release/github-release.ts +12 -0
- package/src/release/index.ts +321 -112
- package/src/release/orchestration.ts +55 -3
- package/src/wrangler/prepare-env.ts +75 -54
- package/src/wrangler/scaffold.test.ts +9 -12
- package/src/wrangler/scaffold.ts +13 -13
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process';
|
|
2
|
-
import { existsSync, lstatSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { appendFileSync, existsSync, lstatSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import { dirname, join, resolve } from 'node:path';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { PLATFORM_TARGET_GLOBS } from '@smoothbricks/nx-plugin/workspace-config-policy';
|
|
6
|
+
import { parseNxProjectJsonText, parseStringArrayText } from '../lib/json.js';
|
|
5
7
|
import { listReleasePackages, readPackageJson } from '../lib/workspace.js';
|
|
6
8
|
import { renderCiWorkflowYaml } from './ci-workflow.js';
|
|
7
9
|
import { renderPublishWorkflowYaml } from './publish-workflow.js';
|
|
@@ -155,6 +157,11 @@ const managedFiles = [
|
|
|
155
157
|
target: '.github/workflows/publish.yml',
|
|
156
158
|
releasePackagesOnly: true,
|
|
157
159
|
},
|
|
160
|
+
{
|
|
161
|
+
kind: 'template',
|
|
162
|
+
source: 'github/workflows/managed-files.yml',
|
|
163
|
+
target: '.github/workflows/managed-files.yml',
|
|
164
|
+
},
|
|
158
165
|
{
|
|
159
166
|
kind: 'template',
|
|
160
167
|
source: 'github/actions/cache-nix-devenv/action.yml',
|
|
@@ -175,6 +182,11 @@ const managedFiles = [
|
|
|
175
182
|
source: 'github/actions/cache-node-modules/action.yml',
|
|
176
183
|
target: '.github/actions/cache-node-modules/action.yml',
|
|
177
184
|
},
|
|
185
|
+
{
|
|
186
|
+
kind: 'template',
|
|
187
|
+
source: 'github/actions/cache-ttsc-plugins/action.yml',
|
|
188
|
+
target: '.github/actions/cache-ttsc-plugins/action.yml',
|
|
189
|
+
},
|
|
178
190
|
{
|
|
179
191
|
kind: 'template',
|
|
180
192
|
source: 'github/actions/cache-nx/action.yml',
|
|
@@ -234,6 +246,7 @@ function getManagedContent(file, context) {
|
|
|
234
246
|
deploy: context.hasProductionDeployTargets,
|
|
235
247
|
deployProvider: context.productionDeployProvider,
|
|
236
248
|
repoName: context.repoName,
|
|
249
|
+
platformTargetGlobs: context.platformTargetGlobs,
|
|
237
250
|
});
|
|
238
251
|
}
|
|
239
252
|
throw new Error(`Unknown generated managed file source ${file.source}`);
|
|
@@ -252,6 +265,7 @@ function getManagedFileContext(root) {
|
|
|
252
265
|
const ciPushBranches = getCiPushBranches(packageJson?.json);
|
|
253
266
|
const stagingDeploy = getDeployTargetInfo(root, 'staging');
|
|
254
267
|
const productionDeploy = getDeployTargetInfo(root, 'production');
|
|
268
|
+
const platformTargetGlobs = platformTargetGlobsForTest(readResolvedNxTargetNames(root));
|
|
255
269
|
const nodeModulesCacheKey = existsSync(join(root, 'bun.lock'))
|
|
256
270
|
? `$${"{{ hashFiles('bun.lock', 'package.json', 'packages/*/package.json') }}"}`
|
|
257
271
|
: `$${"{{ hashFiles('bun.lockb', 'package.json', 'packages/*/package.json') }}"}`;
|
|
@@ -264,8 +278,43 @@ function getManagedFileContext(root) {
|
|
|
264
278
|
ciPushBranches,
|
|
265
279
|
nodeModulesCacheKey,
|
|
266
280
|
repoName,
|
|
281
|
+
platformTargetGlobs,
|
|
267
282
|
};
|
|
268
283
|
}
|
|
284
|
+
export function platformTargetGlobsForTest(targetNames) {
|
|
285
|
+
const names = [...targetNames];
|
|
286
|
+
return PLATFORM_TARGET_GLOBS.filter((glob) => {
|
|
287
|
+
const suffix = glob.startsWith('*') ? glob.slice(1) : glob;
|
|
288
|
+
return names.some((name) => name.endsWith(suffix));
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
function readResolvedNxTargetNames(root) {
|
|
292
|
+
const output = execFileSync('nx', ['show', 'projects', '--json'], {
|
|
293
|
+
cwd: root,
|
|
294
|
+
encoding: 'utf8',
|
|
295
|
+
stdio: ['ignore', 'pipe', 'inherit'],
|
|
296
|
+
});
|
|
297
|
+
const projects = parseStringArrayText(output);
|
|
298
|
+
if (!projects) {
|
|
299
|
+
return [];
|
|
300
|
+
}
|
|
301
|
+
const targetNames = new Set();
|
|
302
|
+
for (const project of projects) {
|
|
303
|
+
const projectOutput = execFileSync('nx', ['show', 'project', project, '--json'], {
|
|
304
|
+
cwd: root,
|
|
305
|
+
encoding: 'utf8',
|
|
306
|
+
stdio: ['ignore', 'pipe', 'inherit'],
|
|
307
|
+
});
|
|
308
|
+
const projectJson = parseNxProjectJsonText(projectOutput);
|
|
309
|
+
const targets = projectJson?.targets;
|
|
310
|
+
if (targets) {
|
|
311
|
+
for (const targetName of Object.keys(targets)) {
|
|
312
|
+
targetNames.add(targetName);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return [...targetNames];
|
|
317
|
+
}
|
|
269
318
|
function renderTemplate(context, template) {
|
|
270
319
|
return template
|
|
271
320
|
.replaceAll('{{REPO_NAME}}', context.repoName)
|
|
@@ -278,8 +327,8 @@ function getDeployTargetInfo(root, configuration) {
|
|
|
278
327
|
encoding: 'utf8',
|
|
279
328
|
stdio: ['ignore', 'pipe', 'inherit'],
|
|
280
329
|
});
|
|
281
|
-
const projects =
|
|
282
|
-
if (!
|
|
330
|
+
const projects = parseStringArrayText(output);
|
|
331
|
+
if (!projects) {
|
|
283
332
|
return { exists: false };
|
|
284
333
|
}
|
|
285
334
|
let exists = false;
|
|
@@ -300,41 +349,23 @@ function nxDeployTarget(root, project, configuration) {
|
|
|
300
349
|
encoding: 'utf8',
|
|
301
350
|
stdio: ['ignore', 'pipe', 'inherit'],
|
|
302
351
|
});
|
|
303
|
-
const
|
|
304
|
-
const
|
|
305
|
-
const
|
|
306
|
-
const deploy = recordValue(targets?.deploy);
|
|
307
|
-
const configurations = recordValue(deploy?.configurations);
|
|
308
|
-
const config = recordValue(configurations?.[configuration]);
|
|
352
|
+
const projectJson = parseNxProjectJsonText(output);
|
|
353
|
+
const deploy = projectJson?.targets?.deploy;
|
|
354
|
+
const config = deploy?.configurations?.[configuration];
|
|
309
355
|
if (!config) {
|
|
310
356
|
return { exists: false };
|
|
311
357
|
}
|
|
312
|
-
const
|
|
358
|
+
const commandValue = config.command ?? config.options?.command ?? deploy?.options?.command;
|
|
359
|
+
const command = typeof commandValue === 'string' ? commandValue : '';
|
|
313
360
|
return { exists: true, provider: command.includes('wrangler ') ? 'cloudflare' : undefined };
|
|
314
361
|
}
|
|
315
|
-
function deployCommand(deploy, config) {
|
|
316
|
-
const command = stringValue(config.command) ?? stringValue(recordValue(config.options)?.command);
|
|
317
|
-
return command ?? stringValue(recordValue(deploy?.options)?.command) ?? '';
|
|
318
|
-
}
|
|
319
|
-
function stringValue(value) {
|
|
320
|
-
return typeof value === 'string' ? value : undefined;
|
|
321
|
-
}
|
|
322
362
|
function getCiPushBranches(packageJson) {
|
|
323
363
|
const configured = readCiPushBranches(packageJson);
|
|
324
364
|
return configured.length > 0 ? configured : ['main'];
|
|
325
365
|
}
|
|
326
366
|
function readCiPushBranches(packageJson) {
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
const github = recordValue(smoo?.github);
|
|
330
|
-
const branches = Array.isArray(github?.pushBranches) ? github.pushBranches : [];
|
|
331
|
-
return branches.filter((branch) => typeof branch === 'string' && branch.length > 0);
|
|
332
|
-
}
|
|
333
|
-
function recordValue(value) {
|
|
334
|
-
return isRecord(value) ? value : undefined;
|
|
335
|
-
}
|
|
336
|
-
function isRecord(value) {
|
|
337
|
-
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
367
|
+
const branches = packageJson?.smoo?.github?.pushBranches ?? [];
|
|
368
|
+
return branches.filter((branch) => branch.length > 0);
|
|
338
369
|
}
|
|
339
370
|
function renderYamlFlowList(values) {
|
|
340
371
|
return JSON.stringify(values);
|
|
@@ -357,3 +388,30 @@ export function validateManagedFiles(root) {
|
|
|
357
388
|
}
|
|
358
389
|
return failures;
|
|
359
390
|
}
|
|
391
|
+
/**
|
|
392
|
+
* Non-blocking drift report: prints the per-file table and surfaces drift as
|
|
393
|
+
* GitHub Actions warning annotations (plain stderr elsewhere) without failing
|
|
394
|
+
* the run. Managed-file drift is derived state with its own remediation flow
|
|
395
|
+
* (the persistent managed-files PR); only `monorepo check` without --warn and
|
|
396
|
+
* PR-scoped gates treat it as an error.
|
|
397
|
+
*
|
|
398
|
+
* Under GitHub Actions the drifted-file count is published as the step output
|
|
399
|
+
* `drifted`, so downstream steps gate declaratively instead of parsing logs.
|
|
400
|
+
*/
|
|
401
|
+
export function warnOnManagedFileDrift(root) {
|
|
402
|
+
const results = applyManagedFiles(root, 'check');
|
|
403
|
+
printResults(results);
|
|
404
|
+
const drifted = results.filter((result) => result.action === 'drifted');
|
|
405
|
+
if (process.env.GITHUB_OUTPUT) {
|
|
406
|
+
appendFileSync(process.env.GITHUB_OUTPUT, `drifted=${drifted.length}\n`);
|
|
407
|
+
}
|
|
408
|
+
if (drifted.length === 0) {
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
if (process.env.GITHUB_ACTIONS === 'true') {
|
|
412
|
+
for (const result of drifted) {
|
|
413
|
+
console.log(`::warning title=Managed file drift::${result.target} drifted from the @smoothbricks/cli template; run 'smoo monorepo update'`);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
console.error(`${drifted.length} managed monorepo file(s) drifted (non-blocking). Run: smoo monorepo update`);
|
|
417
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-policy.d.ts","sourceRoot":"","sources":["../../src/monorepo/package-policy.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAC5B,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAGL,2BAA2B,EAC3B,uBAAuB,EACxB,MAAM,+CAA+C,CAAC;
|
|
1
|
+
{"version":3,"file":"package-policy.d.ts","sourceRoot":"","sources":["../../src/monorepo/package-policy.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAC5B,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAGL,2BAA2B,EAC3B,uBAAuB,EACxB,MAAM,+CAA+C,CAAC;AAoCvD,YAAY,EAAE,0BAA0B,IAAI,iCAAiC,EAAE,sBAAsB,EAAE,CAAC;AACxG,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,CAAC;AAYhE,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAI/D;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAuB1D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMxD;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CA0C7D;AAED,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,0BAA+B,GAAG,IAAI,CAwB7G;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMzD;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAoB7D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAEvE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAczD;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAsC9D;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAW5D;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAwB3D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAcvD;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgElE;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,0BAA+B,GAAG,MAAM,CAkC5G"}
|
|
@@ -4,7 +4,7 @@ import { applyPackageTargetPolicy, checkPackageTargetPolicy, } from '@smoothbric
|
|
|
4
4
|
import { applyReleaseConfigPolicy, checkReleaseConfigPolicy, SMOO_NX_RELEASE_TAG_PATTERN, SMOO_NX_VERSION_ACTIONS, } from '@smoothbricks/nx-plugin/release-config-policy';
|
|
5
5
|
import { applyTypecheckTestPolicy, checkTypecheckTestPolicy } from '@smoothbricks/nx-plugin/typecheck-test-policy';
|
|
6
6
|
import { applyWorkspaceConfigPolicy, checkWorkspaceConfigPolicy, } from '@smoothbricks/nx-plugin/workspace-config-policy';
|
|
7
|
-
import {
|
|
7
|
+
import { ensureNx, ensurePublishConfig, ensureRepositoryObject, ensureScripts, readJsonObject, requiredJsonObject, setMissingPackageStringField, setMissingRepositoryField, setNxName, setPublishAccess, setRepositoryField, setStringProperty, writeJsonObject, } from '../lib/json.js';
|
|
8
8
|
import { getWorkspacePackageManifests, getWorkspacePackages, listPackageJsonRecords, listPublicPackages, packageRepositoryInfo, repositoryInfo, sameRepositoryAfterNormalization, workspaceDependencyFields, } from '../lib/workspace.js';
|
|
9
9
|
export { SMOO_NX_RELEASE_TAG_PATTERN, SMOO_NX_VERSION_ACTIONS };
|
|
10
10
|
const extraCommitScopes = ['release'];
|
|
@@ -27,12 +27,12 @@ export function applyRootScriptDefaults(root) {
|
|
|
27
27
|
if (!rootPackage) {
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
|
-
const scripts =
|
|
30
|
+
const scripts = ensureScripts(rootPackage);
|
|
31
31
|
let changed = false;
|
|
32
32
|
for (const [name, command] of Object.entries(rootScriptPolicy)) {
|
|
33
33
|
changed = setStringProperty(scripts, name, command) || changed;
|
|
34
34
|
}
|
|
35
|
-
const nx =
|
|
35
|
+
const nx = ensureNx(rootPackage);
|
|
36
36
|
if (!Array.isArray(nx.includedScripts) || nx.includedScripts.length !== 0) {
|
|
37
37
|
nx.includedScripts = [];
|
|
38
38
|
changed = true;
|
|
@@ -56,7 +56,7 @@ export function applyNxPluginDefaults(root) {
|
|
|
56
56
|
}
|
|
57
57
|
export function applyPublicPackageDefaults(root) {
|
|
58
58
|
const rootPackage = requiredJsonObject(join(root, 'package.json'));
|
|
59
|
-
const rootLicense =
|
|
59
|
+
const rootLicense = rootPackage.license;
|
|
60
60
|
const rootRepository = repositoryInfo(rootPackage);
|
|
61
61
|
for (const pkg of listPublicPackages(root)) {
|
|
62
62
|
let changed = false;
|
|
@@ -66,17 +66,19 @@ export function applyPublicPackageDefaults(root) {
|
|
|
66
66
|
existingRepository.url === rootRepository.url &&
|
|
67
67
|
rootLicense &&
|
|
68
68
|
rootLicense !== 'UNLICENSED') {
|
|
69
|
-
changed =
|
|
69
|
+
changed = setMissingPackageStringField(pkg.json, 'license', rootLicense) || changed;
|
|
70
70
|
}
|
|
71
|
-
const publishConfig =
|
|
72
|
-
changed =
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
71
|
+
const publishConfig = ensurePublishConfig(pkg.json);
|
|
72
|
+
changed = setPublishAccess(publishConfig, 'public') || changed;
|
|
73
|
+
if (typeof pkg.json.repository !== 'string') {
|
|
74
|
+
const repository = ensureRepositoryObject(pkg.json);
|
|
75
|
+
changed =
|
|
76
|
+
setRepositoryField(repository, 'type', existingRepository?.type ?? rootRepository?.type ?? 'git') || changed;
|
|
77
|
+
if (existingRepository) {
|
|
78
|
+
changed = setMissingRepositoryField(repository, 'url', existingRepository.url) || changed;
|
|
79
|
+
}
|
|
80
|
+
changed = setRepositoryField(repository, 'directory', pkg.path.replaceAll('\\', '/')) || changed;
|
|
78
81
|
}
|
|
79
|
-
changed = setStringProperty(repository, 'directory', pkg.path.replaceAll('\\', '/')) || changed;
|
|
80
82
|
changed = normalizeExportConditionOrder(pkg.json.exports) || changed;
|
|
81
83
|
if (hasDevelopmentSourceExport(pkg.json.exports)) {
|
|
82
84
|
changed = addFileEntry(pkg.json, 'src') || changed;
|
|
@@ -128,7 +130,7 @@ export function applyNxReleaseDefaults(root) {
|
|
|
128
130
|
}
|
|
129
131
|
export function applyNxProjectNameDefaults(root) {
|
|
130
132
|
const rootPackage = requiredJsonObject(join(root, 'package.json'));
|
|
131
|
-
const rootName =
|
|
133
|
+
const rootName = rootPackage.name;
|
|
132
134
|
if (!rootName) {
|
|
133
135
|
return;
|
|
134
136
|
}
|
|
@@ -137,8 +139,8 @@ export function applyNxProjectNameDefaults(root) {
|
|
|
137
139
|
if (!suggestedName) {
|
|
138
140
|
continue;
|
|
139
141
|
}
|
|
140
|
-
const nx =
|
|
141
|
-
const changed =
|
|
142
|
+
const nx = ensureNx(pkg.json);
|
|
143
|
+
const changed = setNxName(nx, suggestedName);
|
|
142
144
|
if (changed) {
|
|
143
145
|
writeJsonObject(pkg.packageJsonPath, pkg.json);
|
|
144
146
|
console.log(`updated ${pkg.path}/package.json nx.name`);
|
|
@@ -153,11 +155,10 @@ export function listValidCommitScopes(root) {
|
|
|
153
155
|
}
|
|
154
156
|
export function listNxProjectNames(root) {
|
|
155
157
|
const rootPackage = readJsonObject(join(root, 'package.json'));
|
|
156
|
-
const rootName = rootPackage
|
|
158
|
+
const rootName = rootPackage?.name ?? null;
|
|
157
159
|
const names = [];
|
|
158
160
|
for (const pkg of getWorkspacePackageManifests(root)) {
|
|
159
|
-
const
|
|
160
|
-
const configuredName = nx ? stringProperty(nx, 'name') : null;
|
|
161
|
+
const configuredName = pkg.json.nx?.name;
|
|
161
162
|
const suggestedName = rootName ? suggestNxProjectName(rootName, pkg.name) : null;
|
|
162
163
|
if (configuredName) {
|
|
163
164
|
names.push(configuredName);
|
|
@@ -175,11 +176,11 @@ export function validateRootPackagePolicy(root) {
|
|
|
175
176
|
return 1;
|
|
176
177
|
}
|
|
177
178
|
let failures = 0;
|
|
178
|
-
if (!
|
|
179
|
+
if (!rootPackage.name) {
|
|
179
180
|
console.error('package.json must define name');
|
|
180
181
|
failures++;
|
|
181
182
|
}
|
|
182
|
-
if (!
|
|
183
|
+
if (!rootPackage.license) {
|
|
183
184
|
console.error('package.json must define repo-wide license');
|
|
184
185
|
failures++;
|
|
185
186
|
}
|
|
@@ -189,19 +190,19 @@ export function validateRootPackagePolicy(root) {
|
|
|
189
190
|
}
|
|
190
191
|
failures += validateRootScripts(rootPackage);
|
|
191
192
|
failures += validateRootNxScriptInference(rootPackage);
|
|
192
|
-
const packageManager =
|
|
193
|
+
const packageManager = rootPackage.packageManager;
|
|
193
194
|
if (!packageManager?.startsWith('bun@')) {
|
|
194
195
|
console.error('package.json packageManager must use bun@<version>');
|
|
195
196
|
failures++;
|
|
196
197
|
}
|
|
197
198
|
const bunVersion = packageManager?.startsWith('bun@') ? packageManager.slice('bun@'.length) : null;
|
|
198
|
-
const devDependencies =
|
|
199
|
+
const devDependencies = rootPackage.devDependencies;
|
|
199
200
|
if (!bunVersion || !devDependencies || devDependencies['@types/bun'] !== bunVersion) {
|
|
200
201
|
console.error('package.json devDependencies.@types/bun must match packageManager bun version');
|
|
201
202
|
failures++;
|
|
202
203
|
}
|
|
203
|
-
const engines =
|
|
204
|
-
if (!engines
|
|
204
|
+
const engines = rootPackage.engines;
|
|
205
|
+
if (!engines?.node) {
|
|
205
206
|
console.error('package.json engines.node must be defined');
|
|
206
207
|
failures++;
|
|
207
208
|
}
|
|
@@ -221,7 +222,7 @@ export function validateNxReleaseConfig(root) {
|
|
|
221
222
|
}
|
|
222
223
|
export function validateNxProjectNames(root) {
|
|
223
224
|
const rootPackage = readJsonObject(join(root, 'package.json'));
|
|
224
|
-
const rootName = rootPackage
|
|
225
|
+
const rootName = rootPackage?.name ?? null;
|
|
225
226
|
if (!rootName) {
|
|
226
227
|
return 0;
|
|
227
228
|
}
|
|
@@ -231,8 +232,7 @@ export function validateNxProjectNames(root) {
|
|
|
231
232
|
if (!suggestedName) {
|
|
232
233
|
continue;
|
|
233
234
|
}
|
|
234
|
-
const
|
|
235
|
-
const configuredName = nx ? stringProperty(nx, 'name') : null;
|
|
235
|
+
const configuredName = pkg.json.nx?.name ?? null;
|
|
236
236
|
if (configuredName !== suggestedName) {
|
|
237
237
|
console.error(`${pkg.path}: package.json nx.name must be "${suggestedName}" so fix(${suggestedName}): maps to this project`);
|
|
238
238
|
failures++;
|
|
@@ -267,16 +267,18 @@ export function validatePublicPackageMetadata(root) {
|
|
|
267
267
|
console.error(`${pkg.path}: npm:public package must not be private`);
|
|
268
268
|
failures++;
|
|
269
269
|
}
|
|
270
|
-
if (!
|
|
270
|
+
if (!pkg.json.license) {
|
|
271
271
|
console.error(`${pkg.path}: public package must define license`);
|
|
272
272
|
failures++;
|
|
273
273
|
}
|
|
274
|
-
const publishConfig =
|
|
275
|
-
if (
|
|
274
|
+
const publishConfig = pkg.json.publishConfig;
|
|
275
|
+
if (publishConfig?.access !== 'public') {
|
|
276
276
|
console.error(`${pkg.path}: public package must define publishConfig.access = public`);
|
|
277
277
|
failures++;
|
|
278
278
|
}
|
|
279
|
-
const repository =
|
|
279
|
+
const repository = pkg.json.repository !== null && pkg.json.repository !== undefined && typeof pkg.json.repository !== 'string'
|
|
280
|
+
? pkg.json.repository
|
|
281
|
+
: null;
|
|
280
282
|
const packageRepository = packageRepositoryInfo(pkg);
|
|
281
283
|
if (!packageRepository) {
|
|
282
284
|
console.error(`${pkg.path}: public package must define repository.url`);
|
|
@@ -290,11 +292,11 @@ export function validatePublicPackageMetadata(root) {
|
|
|
290
292
|
`Use ${rootRepository.url}`);
|
|
291
293
|
failures++;
|
|
292
294
|
}
|
|
293
|
-
if (!repository
|
|
295
|
+
if (!repository?.type) {
|
|
294
296
|
console.error(`${pkg.path}: public package must define repository.type`);
|
|
295
297
|
failures++;
|
|
296
298
|
}
|
|
297
|
-
if (!repository ||
|
|
299
|
+
if (!repository || repository.directory !== pkg.path.replaceAll('\\', '/')) {
|
|
298
300
|
console.error(`${pkg.path}: public package repository.directory must be ${pkg.path.replaceAll('\\', '/')}`);
|
|
299
301
|
failures++;
|
|
300
302
|
}
|
|
@@ -302,11 +304,13 @@ export function validatePublicPackageMetadata(root) {
|
|
|
302
304
|
console.error(`${pkg.path}: public package must define files`);
|
|
303
305
|
failures++;
|
|
304
306
|
}
|
|
305
|
-
|
|
307
|
+
const hasBin = typeof pkg.json.bin === 'string' ||
|
|
308
|
+
(pkg.json.bin !== null && pkg.json.bin !== undefined && typeof pkg.json.bin === 'object');
|
|
309
|
+
if (!isPackageExportMap(pkg.json.exports) && !hasBin) {
|
|
306
310
|
console.error(`${pkg.path}: public package must define exports or bin`);
|
|
307
311
|
failures++;
|
|
308
312
|
}
|
|
309
|
-
if (
|
|
313
|
+
if (typeof pkg.json.types !== 'string' && !hasBin) {
|
|
310
314
|
console.error(`${pkg.path}: public library package must define types`);
|
|
311
315
|
failures++;
|
|
312
316
|
}
|
|
@@ -315,10 +319,11 @@ export function validatePublicPackageMetadata(root) {
|
|
|
315
319
|
}
|
|
316
320
|
export function validateWorkspaceDependencies(root, options = {}) {
|
|
317
321
|
let failures = 0;
|
|
322
|
+
failures += validateCiSkipTags(root, options);
|
|
318
323
|
const workspaceNames = new Set(getWorkspacePackages(root).map((pkg) => pkg.name));
|
|
319
324
|
for (const pkg of listPackageJsonRecords(root)) {
|
|
320
325
|
for (const field of workspaceDependencyFields) {
|
|
321
|
-
const dependencies =
|
|
326
|
+
const dependencies = pkg.json[field];
|
|
322
327
|
if (!dependencies) {
|
|
323
328
|
continue;
|
|
324
329
|
}
|
|
@@ -347,13 +352,38 @@ export function validateWorkspaceDependencies(root, options = {}) {
|
|
|
347
352
|
}
|
|
348
353
|
return failures;
|
|
349
354
|
}
|
|
355
|
+
const ciSkipTagPrefix = 'ci:skip:';
|
|
356
|
+
const invalidCiSkipTargetSyntax = /[,*?[\]{}]/;
|
|
357
|
+
function validateCiSkipTags(root, options) {
|
|
358
|
+
let failures = 0;
|
|
359
|
+
for (const pkg of getWorkspacePackages(root)) {
|
|
360
|
+
const resolved = options.resolvedTargetsByProject?.get(pkg.projectName);
|
|
361
|
+
const resolvedTargets = resolved && 'targets' in resolved ? resolved.targets : resolved;
|
|
362
|
+
for (const tag of pkg.tags) {
|
|
363
|
+
if (tag !== 'ci:skip' && !tag.startsWith(ciSkipTagPrefix)) {
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
const target = tag.startsWith(ciSkipTagPrefix) ? tag.slice(ciSkipTagPrefix.length) : '';
|
|
367
|
+
if (!target || invalidCiSkipTargetSyntax.test(target)) {
|
|
368
|
+
console.error(`${pkg.path}: nx tag ${tag} must use ci:skip:<target> with one exact Nx target name`);
|
|
369
|
+
failures++;
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
if (resolvedTargets && !resolvedTargets.has(target)) {
|
|
373
|
+
console.error(`${pkg.path}: nx tag ${tag} names missing Nx target ${target}`);
|
|
374
|
+
failures++;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return failures;
|
|
379
|
+
}
|
|
350
380
|
// ---------------------------------------------------------------------------
|
|
351
381
|
// Helpers kept in CLI (not Nx-specific)
|
|
352
382
|
// ---------------------------------------------------------------------------
|
|
353
383
|
function fixWorkspaceDependencyRanges(pkg, workspaceNames) {
|
|
354
384
|
let changed = false;
|
|
355
385
|
for (const field of workspaceDependencyFields) {
|
|
356
|
-
const dependencies =
|
|
386
|
+
const dependencies = pkg[field];
|
|
357
387
|
if (!dependencies) {
|
|
358
388
|
continue;
|
|
359
389
|
}
|
|
@@ -367,7 +397,7 @@ function fixWorkspaceDependencyRanges(pkg, workspaceNames) {
|
|
|
367
397
|
return changed;
|
|
368
398
|
}
|
|
369
399
|
function validateRootScripts(rootPackage) {
|
|
370
|
-
const scripts =
|
|
400
|
+
const scripts = rootPackage.scripts;
|
|
371
401
|
let failures = 0;
|
|
372
402
|
for (const [name, command] of Object.entries(rootScriptPolicy)) {
|
|
373
403
|
if (scripts?.[name] !== command) {
|
|
@@ -382,8 +412,8 @@ function validateRootScripts(rootPackage) {
|
|
|
382
412
|
return failures;
|
|
383
413
|
}
|
|
384
414
|
function validateRootNxScriptInference(rootPackage) {
|
|
385
|
-
const
|
|
386
|
-
if (
|
|
415
|
+
const includedScripts = rootPackage.nx?.includedScripts;
|
|
416
|
+
if (Array.isArray(includedScripts) && includedScripts.length === 0) {
|
|
387
417
|
return 0;
|
|
388
418
|
}
|
|
389
419
|
console.error('package.json nx.includedScripts must be [] so root scripts do not become recursive Nx targets.');
|
|
@@ -405,7 +435,7 @@ function unscopedPackageName(packageName) {
|
|
|
405
435
|
}
|
|
406
436
|
function recordKeysAreSorted(record) {
|
|
407
437
|
const keys = Object.keys(record);
|
|
408
|
-
return keys.every((key, index) => index === 0 || keys[index - 1] <= key);
|
|
438
|
+
return keys.every((key, index) => index === 0 || (keys[index - 1] ?? '') <= key);
|
|
409
439
|
}
|
|
410
440
|
function sortRecordInPlace(record) {
|
|
411
441
|
if (recordKeysAreSorted(record)) {
|
|
@@ -420,8 +450,11 @@ function sortRecordInPlace(record) {
|
|
|
420
450
|
}
|
|
421
451
|
return true;
|
|
422
452
|
}
|
|
453
|
+
function isPackageExportMap(value) {
|
|
454
|
+
return value !== null && value !== undefined && typeof value === 'object';
|
|
455
|
+
}
|
|
423
456
|
function normalizeExportConditionOrder(value) {
|
|
424
|
-
if (!
|
|
457
|
+
if (!isPackageExportMap(value)) {
|
|
425
458
|
return false;
|
|
426
459
|
}
|
|
427
460
|
let changed = false;
|
|
@@ -450,7 +483,7 @@ function normalizeExportConditionOrder(value) {
|
|
|
450
483
|
return true;
|
|
451
484
|
}
|
|
452
485
|
function hasDevelopmentSourceExport(value) {
|
|
453
|
-
if (!
|
|
486
|
+
if (!isPackageExportMap(value)) {
|
|
454
487
|
return false;
|
|
455
488
|
}
|
|
456
489
|
for (const [key, child] of Object.entries(value)) {
|
|
@@ -468,7 +501,7 @@ function addFileEntry(pkg, entry) {
|
|
|
468
501
|
if (!Array.isArray(files) || files.includes(entry)) {
|
|
469
502
|
return false;
|
|
470
503
|
}
|
|
471
|
-
const firstNegated = files.findIndex((file) =>
|
|
504
|
+
const firstNegated = files.findIndex((file) => file.startsWith('!'));
|
|
472
505
|
if (firstNegated === -1) {
|
|
473
506
|
files.push(entry);
|
|
474
507
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { type PackageJson } from '../lib/json.js';
|
|
1
2
|
import type { PackageInfo } from '../lib/workspace.js';
|
|
2
|
-
export declare function readPackedPackageJson(root: string, tarball: string, packageName: string): Promise<
|
|
3
|
-
export declare function validatePackedWorkspaceDependencies(root: string, sourcePackage: PackageInfo, packedPackage:
|
|
3
|
+
export declare function readPackedPackageJson(root: string, tarball: string, packageName: string): Promise<PackageJson>;
|
|
4
|
+
export declare function validatePackedWorkspaceDependencies(root: string, sourcePackage: PackageInfo, packedPackage: PackageJson, options?: {
|
|
5
|
+
mode?: 'install' | 'publish';
|
|
6
|
+
}): string[];
|
|
4
7
|
//# sourceMappingURL=packed-manifest.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packed-manifest.d.ts","sourceRoot":"","sources":["../../src/monorepo/packed-manifest.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"packed-manifest.d.ts","sourceRoot":"","sources":["../../src/monorepo/packed-manifest.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,WAAW,EAAwB,MAAM,gBAAgB,CAAC;AAExE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIvD,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAUpH;AAED,wBAAgB,mCAAmC,CACjD,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,WAAW,EAC1B,aAAa,EAAE,WAAW,EAC1B,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;CAAO,GAC7C,MAAM,EAAE,CAyCV"}
|
|
@@ -1,32 +1,31 @@
|
|
|
1
|
-
import { execSync } from 'node:child_process';
|
|
2
1
|
import { $ } from 'bun';
|
|
3
|
-
import {
|
|
2
|
+
import { parsePackageJsonText } from '../lib/json.js';
|
|
4
3
|
import { decode } from '../lib/run.js';
|
|
5
4
|
import { getWorkspacePackages, workspaceDependencyFields } from '../lib/workspace.js';
|
|
5
|
+
import { publishPackDependencyVersion } from './lockfile.js';
|
|
6
6
|
export async function readPackedPackageJson(root, tarball, packageName) {
|
|
7
7
|
const result = await $ `tar -xOf ${tarball} package/package.json`.cwd(root).quiet().nothrow();
|
|
8
8
|
if (result.exitCode !== 0) {
|
|
9
9
|
throw new Error(`${packageName}: unable to inspect packed package.json.`);
|
|
10
10
|
}
|
|
11
|
-
const parsed =
|
|
12
|
-
if (!
|
|
13
|
-
throw new Error(`${packageName}: packed package.json is
|
|
11
|
+
const parsed = parsePackageJsonText(decode(result.stdout));
|
|
12
|
+
if (!parsed) {
|
|
13
|
+
throw new Error(`${packageName}: packed package.json is invalid.`);
|
|
14
14
|
}
|
|
15
15
|
return parsed;
|
|
16
16
|
}
|
|
17
|
-
export function validatePackedWorkspaceDependencies(root, sourcePackage, packedPackage) {
|
|
17
|
+
export function validatePackedWorkspaceDependencies(root, sourcePackage, packedPackage, options = {}) {
|
|
18
|
+
const mode = options.mode ?? 'publish';
|
|
18
19
|
const workspacePackages = getWorkspacePackages(root);
|
|
19
|
-
const workspaceVersions = new Map(workspacePackages.map((pkg) => [pkg.name, pkg.version]));
|
|
20
|
-
const projectNameByPackage = new Map(workspacePackages.map((pkg) => [pkg.name, pkg.projectName]));
|
|
21
20
|
const failures = [];
|
|
22
21
|
for (const field of workspaceDependencyFields) {
|
|
23
|
-
const sourceDependencies =
|
|
24
|
-
const packedDependencies =
|
|
22
|
+
const sourceDependencies = sourcePackage.json[field];
|
|
23
|
+
const packedDependencies = packedPackage[field];
|
|
25
24
|
if (!sourceDependencies && !packedDependencies) {
|
|
26
25
|
continue;
|
|
27
26
|
}
|
|
28
27
|
for (const [name, range] of Object.entries(packedDependencies ?? {})) {
|
|
29
|
-
if (
|
|
28
|
+
if (range.startsWith('workspace:')) {
|
|
30
29
|
failures.push(`${sourcePackage.path}: packed ${field}.${name} must not contain ${range}`);
|
|
31
30
|
}
|
|
32
31
|
}
|
|
@@ -34,51 +33,21 @@ export function validatePackedWorkspaceDependencies(root, sourcePackage, packedP
|
|
|
34
33
|
continue;
|
|
35
34
|
}
|
|
36
35
|
for (const [name, sourceRange] of Object.entries(sourceDependencies)) {
|
|
37
|
-
const
|
|
38
|
-
if (!
|
|
36
|
+
const dep = workspacePackages.find((pkg) => pkg.name === name);
|
|
37
|
+
if (!dep) {
|
|
39
38
|
continue;
|
|
40
39
|
}
|
|
41
40
|
const packedRange = packedDependencies?.[name];
|
|
42
41
|
if (sourceRange !== 'workspace:*') {
|
|
43
42
|
failures.push(`${sourcePackage.path}: source ${field}.${name} must use workspace:*`);
|
|
44
43
|
}
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
const projectName = projectNameByPackage.get(name);
|
|
49
|
-
const expectedVersion = workspaceVersion.includes('-') && projectName
|
|
50
|
-
? (latestStableTagVersion(root, projectName) ?? workspaceVersion)
|
|
51
|
-
: workspaceVersion;
|
|
44
|
+
// install: what day-to-day pack embeds (package.json / lockfile aligned)
|
|
45
|
+
// publish: what pre-publish sync embeds (unpublished -next → last stable tag)
|
|
46
|
+
const expectedVersion = mode === 'publish' ? publishPackDependencyVersion(root, dep.projectName, dep.version) : dep.version;
|
|
52
47
|
if (packedRange !== expectedVersion) {
|
|
53
|
-
failures.push(`${sourcePackage.path}: packed ${field}.${name} must be ${expectedVersion}, got ${
|
|
48
|
+
failures.push(`${sourcePackage.path}: packed ${field}.${name} must be ${expectedVersion}, got ${packedRange ?? '<missing>'}`);
|
|
54
49
|
}
|
|
55
50
|
}
|
|
56
51
|
}
|
|
57
52
|
return failures;
|
|
58
53
|
}
|
|
59
|
-
function formatRange(value) {
|
|
60
|
-
return typeof value === 'string' ? value : '<missing>';
|
|
61
|
-
}
|
|
62
|
-
function latestStableTagVersion(root, projectName) {
|
|
63
|
-
try {
|
|
64
|
-
const output = execSync(`git tag --list '${projectName}@*' --sort=-v:refname`, {
|
|
65
|
-
cwd: root,
|
|
66
|
-
encoding: 'utf8',
|
|
67
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
68
|
-
});
|
|
69
|
-
const prefix = `${projectName}@`;
|
|
70
|
-
for (const line of output.split('\n')) {
|
|
71
|
-
const tag = line.trim();
|
|
72
|
-
if (!tag.startsWith(prefix))
|
|
73
|
-
continue;
|
|
74
|
-
const version = tag.slice(prefix.length);
|
|
75
|
-
if (version && !version.includes('-')) {
|
|
76
|
-
return version;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
catch {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packed-package.d.ts","sourceRoot":"","sources":["../../src/monorepo/packed-package.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"packed-package.d.ts","sourceRoot":"","sources":["../../src/monorepo/packed-package.ts"],"names":[],"mappings":"AAcA,wBAAsB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMhF;AAED,wBAAsB,kCAAkC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMtF;AAED,wBAAsB,mCAAmC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMvF;AAED,wBAAsB,gCAAgC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMpF"}
|