@memberjunction/cli 6.1.0-edge.2 → 6.1.0-edge.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/LICENSE +180 -4
- package/README.md +1 -1
- package/dist/commands/codegen/manifest.d.ts +14 -0
- package/dist/commands/codegen/manifest.d.ts.map +1 -1
- package/dist/commands/codegen/manifest.js +26 -7
- package/dist/commands/codegen/manifest.js.map +1 -1
- package/dist/commands/dev/index.d.ts +7 -0
- package/dist/commands/dev/index.d.ts.map +1 -0
- package/dist/commands/dev/index.js +11 -0
- package/dist/commands/dev/index.js.map +1 -0
- package/dist/commands/dev/usage.d.ts +7 -0
- package/dist/commands/dev/usage.d.ts.map +1 -0
- package/dist/commands/dev/usage.js +10 -0
- package/dist/commands/dev/usage.js.map +1 -0
- package/dist/commands/dev/workspace/clean.d.ts +27 -0
- package/dist/commands/dev/workspace/clean.d.ts.map +1 -0
- package/dist/commands/dev/workspace/clean.js +87 -0
- package/dist/commands/dev/workspace/clean.js.map +1 -0
- package/dist/commands/dev/workspace/doctor.d.ts +28 -0
- package/dist/commands/dev/workspace/doctor.d.ts.map +1 -0
- package/dist/commands/dev/workspace/doctor.js +62 -0
- package/dist/commands/dev/workspace/doctor.js.map +1 -0
- package/dist/commands/dev/workspace/index.d.ts +60 -0
- package/dist/commands/dev/workspace/index.d.ts.map +1 -0
- package/dist/commands/dev/workspace/index.js +279 -0
- package/dist/commands/dev/workspace/index.js.map +1 -0
- package/dist/commands/dev/workspace/status.d.ts +19 -0
- package/dist/commands/dev/workspace/status.d.ts.map +1 -0
- package/dist/commands/dev/workspace/status.js +46 -0
- package/dist/commands/dev/workspace/status.js.map +1 -0
- package/dist/commands/migrate/convert.d.ts +25 -0
- package/dist/commands/migrate/convert.d.ts.map +1 -1
- package/dist/commands/migrate/convert.js +61 -8
- package/dist/commands/migrate/convert.js.map +1 -1
- package/dist/commands/migrate/index.d.ts +9 -0
- package/dist/commands/migrate/index.d.ts.map +1 -1
- package/dist/commands/migrate/index.js +41 -1
- package/dist/commands/migrate/index.js.map +1 -1
- package/dist/lib/cli-plugins.d.ts.map +1 -1
- package/dist/lib/cli-plugins.js +5 -0
- package/dist/lib/cli-plugins.js.map +1 -1
- package/dist/lib/dev-workspace/build.d.ts +180 -0
- package/dist/lib/dev-workspace/build.d.ts.map +1 -0
- package/dist/lib/dev-workspace/build.js +570 -0
- package/dist/lib/dev-workspace/build.js.map +1 -0
- package/dist/lib/dev-workspace/clean.d.ts +40 -0
- package/dist/lib/dev-workspace/clean.d.ts.map +1 -0
- package/dist/lib/dev-workspace/clean.js +193 -0
- package/dist/lib/dev-workspace/clean.js.map +1 -0
- package/dist/lib/dev-workspace/detect.d.ts +56 -0
- package/dist/lib/dev-workspace/detect.d.ts.map +1 -0
- package/dist/lib/dev-workspace/detect.js +343 -0
- package/dist/lib/dev-workspace/detect.js.map +1 -0
- package/dist/lib/dev-workspace/dir-flag.d.ts +23 -0
- package/dist/lib/dev-workspace/dir-flag.d.ts.map +1 -0
- package/dist/lib/dev-workspace/dir-flag.js +24 -0
- package/dist/lib/dev-workspace/dir-flag.js.map +1 -0
- package/dist/lib/dev-workspace/doctor.d.ts +96 -0
- package/dist/lib/dev-workspace/doctor.d.ts.map +1 -0
- package/dist/lib/dev-workspace/doctor.js +400 -0
- package/dist/lib/dev-workspace/doctor.js.map +1 -0
- package/dist/lib/dev-workspace/lockfile.d.ts +62 -0
- package/dist/lib/dev-workspace/lockfile.d.ts.map +1 -0
- package/dist/lib/dev-workspace/lockfile.js +456 -0
- package/dist/lib/dev-workspace/lockfile.js.map +1 -0
- package/dist/lib/dev-workspace/member-installs.d.ts +35 -0
- package/dist/lib/dev-workspace/member-installs.d.ts.map +1 -0
- package/dist/lib/dev-workspace/member-installs.js +139 -0
- package/dist/lib/dev-workspace/member-installs.js.map +1 -0
- package/dist/lib/dev-workspace/pnpm.d.ts +29 -0
- package/dist/lib/dev-workspace/pnpm.d.ts.map +1 -0
- package/dist/lib/dev-workspace/pnpm.js +59 -0
- package/dist/lib/dev-workspace/pnpm.js.map +1 -0
- package/dist/lib/dev-workspace/status.d.ts +16 -0
- package/dist/lib/dev-workspace/status.d.ts.map +1 -0
- package/dist/lib/dev-workspace/status.js +185 -0
- package/dist/lib/dev-workspace/status.js.map +1 -0
- package/dist/lib/dev-workspace/types.d.ts +312 -0
- package/dist/lib/dev-workspace/types.d.ts.map +1 -0
- package/dist/lib/dev-workspace/types.js +14 -0
- package/dist/lib/dev-workspace/types.js.map +1 -0
- package/dist/lib/dev-workspace/usage.d.ts +30 -0
- package/dist/lib/dev-workspace/usage.d.ts.map +1 -0
- package/dist/lib/dev-workspace/usage.js +177 -0
- package/dist/lib/dev-workspace/usage.js.map +1 -0
- package/dist/lib/dev-workspace/write.d.ts +25 -0
- package/dist/lib/dev-workspace/write.d.ts.map +1 -0
- package/dist/lib/dev-workspace/write.js +75 -0
- package/dist/lib/dev-workspace/write.js.map +1 -0
- package/dist/light-commands.d.ts.map +1 -1
- package/dist/light-commands.js +7 -0
- package/dist/light-commands.js.map +1 -1
- package/oclif.manifest.json +1228 -969
- package/package.json +22 -22
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dir-flag.d.ts","sourceRoot":"","sources":["../../../src/lib/dev-workspace/dir-flag.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,kFAAkF;AAClF,eAAO,MAAM,qBAAqB,yBAAyB,CAAC;AAE5D;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAIjG;AAED,4DAA4D;AAC5D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAI3D"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Environment variable every dev workspace command binds to its `--dir` flag. */
|
|
2
|
+
export const WORKSPACE_DIR_ENV_VAR = 'MJ_DEV_WORKSPACE_DIR';
|
|
3
|
+
/**
|
|
4
|
+
* Determines which input supplied `--dir`, mirroring oclif's own precedence: an
|
|
5
|
+
* explicit flag beats the environment variable, which beats the default. Pure —
|
|
6
|
+
* the caller passes its raw argv and the environment value, so this never reads
|
|
7
|
+
* `process.env` itself.
|
|
8
|
+
*/
|
|
9
|
+
export function ResolveDirSource(argv, envValue) {
|
|
10
|
+
if (argv.some((arg) => arg === '--dir' || arg.startsWith('--dir=')))
|
|
11
|
+
return 'flag';
|
|
12
|
+
if (envValue !== undefined && envValue.length > 0)
|
|
13
|
+
return 'env';
|
|
14
|
+
return 'default';
|
|
15
|
+
}
|
|
16
|
+
/** How a resolved `--dir` should be described in output. */
|
|
17
|
+
export function DescribeDirSource(source) {
|
|
18
|
+
if (source === 'flag')
|
|
19
|
+
return '--dir flag';
|
|
20
|
+
if (source === 'env')
|
|
21
|
+
return `$${WORKSPACE_DIR_ENV_VAR}`;
|
|
22
|
+
return 'default (current directory)';
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=dir-flag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dir-flag.js","sourceRoot":"","sources":["../../../src/lib/dev-workspace/dir-flag.ts"],"names":[],"mappings":"AAYA,kFAAkF;AAClF,MAAM,CAAC,MAAM,qBAAqB,GAAG,sBAAsB,CAAC;AAE5D;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAuB,EAAE,QAA4B;IACpF,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,OAAO,IAAI,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IACnF,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAChE,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,iBAAiB,CAAC,MAAiB;IACjD,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,YAAY,CAAC;IAC3C,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,IAAI,qBAAqB,EAAE,CAAC;IACzD,OAAO,6BAA6B,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { DirSource } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Packages that MUST resolve to exactly one copy across a joined workspace.
|
|
4
|
+
* Angular's DI, RxJS's operator identity checks and MJ's Global Object Store all
|
|
5
|
+
* key off module identity, so a second copy is not a duplicate — it is a second,
|
|
6
|
+
* mutually invisible runtime.
|
|
7
|
+
*/
|
|
8
|
+
export declare const SINGLETON_PACKAGES: readonly string[];
|
|
9
|
+
/**
|
|
10
|
+
* Outcome of one health check. `skip` means the check did not apply — it is never a
|
|
11
|
+
* claim of health, which is exactly why it is not folded into `pass`.
|
|
12
|
+
*/
|
|
13
|
+
export type DoctorSeverity = 'pass' | 'warn' | 'fail' | 'skip';
|
|
14
|
+
/** One health-check result: what was checked, how it went, and for warn/fail what to do. */
|
|
15
|
+
export interface DoctorCheck {
|
|
16
|
+
Name: string;
|
|
17
|
+
Severity: DoctorSeverity;
|
|
18
|
+
Detail: string;
|
|
19
|
+
}
|
|
20
|
+
/** One decoded pnpm virtual-store directory name. */
|
|
21
|
+
export interface StoreEntry {
|
|
22
|
+
/** Package name with the scope separator decoded (`@angular+core` -> `@angular/core`). */
|
|
23
|
+
Name: string;
|
|
24
|
+
/** Concrete version, peer suffix stripped. */
|
|
25
|
+
Version: string;
|
|
26
|
+
}
|
|
27
|
+
/** Distinct versions of one singleton package found in the parent's store. */
|
|
28
|
+
export interface SingletonVersions {
|
|
29
|
+
Package: string;
|
|
30
|
+
/** Sorted distinct versions — always at least one entry. */
|
|
31
|
+
Versions: string[];
|
|
32
|
+
}
|
|
33
|
+
/** What the one-copy census read out of `<parent>/node_modules/.pnpm`. */
|
|
34
|
+
export interface StoreCensus {
|
|
35
|
+
/** False when the parent has no virtual store — nothing has been installed there. */
|
|
36
|
+
StorePresent: boolean;
|
|
37
|
+
/** Every singleton package present in the store. Packages absent from it are omitted, not zero-filled. */
|
|
38
|
+
Packages: SingletonVersions[];
|
|
39
|
+
/**
|
|
40
|
+
* Store entries that are not `name@version` (the store's own `node_modules`,
|
|
41
|
+
* `file:`/`link:` entries). Counted and reported rather than silently dropped.
|
|
42
|
+
*/
|
|
43
|
+
UnparsedEntryCount: number;
|
|
44
|
+
}
|
|
45
|
+
/** Everything `dev workspace doctor` reports. */
|
|
46
|
+
export interface DoctorReport {
|
|
47
|
+
ParentDir: string;
|
|
48
|
+
DirSource: DirSource;
|
|
49
|
+
Checks: DoctorCheck[];
|
|
50
|
+
Census: StoreCensus;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Decodes one `<parent>/node_modules/.pnpm` directory name into package name and
|
|
54
|
+
* version, or null when the entry is not a resolved package (the store's own
|
|
55
|
+
* `node_modules`, `file+..+repo@file+..+repo` link entries, and anything else whose
|
|
56
|
+
* version segment does not start with a digit).
|
|
57
|
+
*
|
|
58
|
+
* Peer suffixes come in BOTH shapes and both are handled — pnpm 10.33 writes the
|
|
59
|
+
* underscore form (verified against a real store: `@angular+core@21.1.3_@angular+
|
|
60
|
+
* compiler@21.1.3_rxjs@7.8.2_zone.js@0.16.0`), other versions write the parenthesised
|
|
61
|
+
* form (`@angular+common@21.1.3(@angular+core@21.1.3)`). Both carry `@` characters
|
|
62
|
+
* INSIDE the suffix, which is why the version is taken from the name/version
|
|
63
|
+
* separator forwards and then truncated, never from the LAST `@` backwards — on the
|
|
64
|
+
* entry above, the last `@` yields `0.16.0`, a version of a different package.
|
|
65
|
+
* Splitting the VERSION segment (not the whole entry) at `_` is safe: semver forbids
|
|
66
|
+
* `_` in a version, and a package name containing one is never reached. Pure.
|
|
67
|
+
*/
|
|
68
|
+
export declare function ParseStoreEntry(entryName: string): StoreEntry | null;
|
|
69
|
+
/**
|
|
70
|
+
* Counts the distinct versions of each singleton package in the parent's pnpm
|
|
71
|
+
* virtual store, reading DIRECTORY NAMES ONLY — a store entry name already carries
|
|
72
|
+
* `name@version`, so no package.json is opened and the whole census is one
|
|
73
|
+
* `readdirSync`. An absent store is reported as `StorePresent: false`, never as a
|
|
74
|
+
* clean bill of health.
|
|
75
|
+
*
|
|
76
|
+
* KNOWN LIMIT, stated so the PASS is not read as more than it is: pnpm gives
|
|
77
|
+
* workspace-linked packages no virtual-store entry at all (verified — an MJ
|
|
78
|
+
* checkout's own store holds zero `@memberjunction+core@…` entries), so this counts
|
|
79
|
+
* copies IN THE PARENT STORE. A registry copy sitting alongside a workspace link is
|
|
80
|
+
* one store entry and reads as one copy. Catching that is the job of the family
|
|
81
|
+
* `workspace:*` overrides the generator emits, not of this census.
|
|
82
|
+
*
|
|
83
|
+
* SIDE EFFECT: one read-only directory listing.
|
|
84
|
+
*/
|
|
85
|
+
export declare function CollectSingletonCensus(parentDir: string): StoreCensus;
|
|
86
|
+
/**
|
|
87
|
+
* Runs every health check at a parent directory. `activePnpmVersion` comes from the
|
|
88
|
+
* caller (a spawn — see `pnpm.ts`) and `dirSource` likewise, so this module reads
|
|
89
|
+
* neither processes nor the environment. Read-only.
|
|
90
|
+
*/
|
|
91
|
+
export declare function CollectDoctorReport(parentDir: string, activePnpmVersion: string | null, dirSource: DirSource): DoctorReport;
|
|
92
|
+
/** True when any check failed — the command's exit-code decision. Pure. */
|
|
93
|
+
export declare function DoctorHasFailures(report: DoctorReport): boolean;
|
|
94
|
+
/** Renders a DoctorReport as the terminal report. Pure. */
|
|
95
|
+
export declare function RenderDoctor(report: DoctorReport): string;
|
|
96
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/lib/dev-workspace/doctor.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,YAAY,CAAC;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAQ/C,CAAC;AAQF;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAE/D,4FAA4F;AAC5F,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qDAAqD;AACrD,MAAM,WAAW,UAAU;IACzB,0FAA0F;IAC1F,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,8EAA8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,0EAA0E;AAC1E,MAAM,WAAW,WAAW;IAC1B,qFAAqF;IACrF,YAAY,EAAE,OAAO,CAAC;IACtB,0GAA0G;IAC1G,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B;;;OAGG;IACH,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,iDAAiD;AACjD,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,MAAM,EAAE,WAAW,CAAC;CACrB;AAoBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQpE;AAgDD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,CAOrE;AAiMD;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,GAAG,IAAI,EAChC,SAAS,EAAE,SAAS,GACnB,YAAY,CAsBd;AAUD,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAE/D;AAWD,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAYzD"}
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Health checks for `mj dev workspace doctor`.
|
|
3
|
+
*
|
|
4
|
+
* SIDE EFFECTS: READ-ONLY filesystem access, and nothing else. Two reads happen
|
|
5
|
+
* here — the workspace state collection delegated to `status.ts` (existence checks
|
|
6
|
+
* plus small file reads), and ONE `readdirSync` of the parent's pnpm virtual store
|
|
7
|
+
* for the one-copy census. Doctor never writes, never deletes, never spawns a
|
|
8
|
+
* process (the active pnpm version is probed by the command and passed in, the same
|
|
9
|
+
* contract `CollectWorkspaceStatus` uses) and never touches the network.
|
|
10
|
+
*
|
|
11
|
+
* The census exists because the failure that actually bites a joined workspace is
|
|
12
|
+
* not a missing file — it is TWO COPIES of a package the runtime requires exactly
|
|
13
|
+
* one of. Two `@angular/core`s give `NG0203 inject() must be called from an
|
|
14
|
+
* injection context`; two `@memberjunction/global`s give two Global Object Stores,
|
|
15
|
+
* so every `BaseSingleton` silently becomes two singletons. Both look like
|
|
16
|
+
* application bugs and neither names the real cause, so doctor names it.
|
|
17
|
+
*
|
|
18
|
+
* @module lib/dev-workspace/doctor
|
|
19
|
+
*/
|
|
20
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
21
|
+
import path from 'node:path';
|
|
22
|
+
import chalk from 'chalk';
|
|
23
|
+
import { SENTINEL_MARKER } from './build.js';
|
|
24
|
+
import { LOCKFILE_NAME, NODE_MODULES_NAME } from './clean.js';
|
|
25
|
+
import { DescribeDirSource } from './dir-flag.js';
|
|
26
|
+
import { CollectWorkspaceStatus } from './status.js';
|
|
27
|
+
import { SENTINEL_FILE_NAME } from './write.js';
|
|
28
|
+
/**
|
|
29
|
+
* Packages that MUST resolve to exactly one copy across a joined workspace.
|
|
30
|
+
* Angular's DI, RxJS's operator identity checks and MJ's Global Object Store all
|
|
31
|
+
* key off module identity, so a second copy is not a duplicate — it is a second,
|
|
32
|
+
* mutually invisible runtime.
|
|
33
|
+
*/
|
|
34
|
+
export const SINGLETON_PACKAGES = [
|
|
35
|
+
'@angular/core',
|
|
36
|
+
'@angular/common',
|
|
37
|
+
'@angular/compiler',
|
|
38
|
+
'rxjs',
|
|
39
|
+
'zone.js',
|
|
40
|
+
'@memberjunction/core',
|
|
41
|
+
'@memberjunction/global',
|
|
42
|
+
];
|
|
43
|
+
/** Hard cap on virtual-store entries the census will read; exceeding it throws rather than truncating. */
|
|
44
|
+
const MAX_STORE_ENTRIES = 100_000;
|
|
45
|
+
/** The pnpm virtual store, relative to the workspace parent. */
|
|
46
|
+
const STORE_REL_PATH = path.join(NODE_MODULES_NAME, '.pnpm');
|
|
47
|
+
/**
|
|
48
|
+
* Index of the `@` that separates name from version in a store directory name:
|
|
49
|
+
* the SECOND `@` for a scoped package (`@angular+core@21.1.3`), the first
|
|
50
|
+
* otherwise (`rxjs@7.8.1`). Returns -1 when there is none.
|
|
51
|
+
*
|
|
52
|
+
* Deliberately not "the last `@`": a peer-suffixed entry carries `@` characters
|
|
53
|
+
* INSIDE its suffix — `@angular+common@21.1.3(@angular+core@21.1.3)` — so the last
|
|
54
|
+
* `@` sits in the parentheses and the naive split yields nonsense.
|
|
55
|
+
*/
|
|
56
|
+
function findVersionSeparator(entry) {
|
|
57
|
+
return entry.startsWith('@') ? entry.indexOf('@', 1) : entry.indexOf('@');
|
|
58
|
+
}
|
|
59
|
+
/** pnpm encodes the scope separator as `+`, and only that one: `@angular+core` -> `@angular/core`. */
|
|
60
|
+
function decodeStoreName(encodedName) {
|
|
61
|
+
return encodedName.startsWith('@') ? encodedName.replace('+', '/') : encodedName;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Decodes one `<parent>/node_modules/.pnpm` directory name into package name and
|
|
65
|
+
* version, or null when the entry is not a resolved package (the store's own
|
|
66
|
+
* `node_modules`, `file+..+repo@file+..+repo` link entries, and anything else whose
|
|
67
|
+
* version segment does not start with a digit).
|
|
68
|
+
*
|
|
69
|
+
* Peer suffixes come in BOTH shapes and both are handled — pnpm 10.33 writes the
|
|
70
|
+
* underscore form (verified against a real store: `@angular+core@21.1.3_@angular+
|
|
71
|
+
* compiler@21.1.3_rxjs@7.8.2_zone.js@0.16.0`), other versions write the parenthesised
|
|
72
|
+
* form (`@angular+common@21.1.3(@angular+core@21.1.3)`). Both carry `@` characters
|
|
73
|
+
* INSIDE the suffix, which is why the version is taken from the name/version
|
|
74
|
+
* separator forwards and then truncated, never from the LAST `@` backwards — on the
|
|
75
|
+
* entry above, the last `@` yields `0.16.0`, a version of a different package.
|
|
76
|
+
* Splitting the VERSION segment (not the whole entry) at `_` is safe: semver forbids
|
|
77
|
+
* `_` in a version, and a package name containing one is never reached. Pure.
|
|
78
|
+
*/
|
|
79
|
+
export function ParseStoreEntry(entryName) {
|
|
80
|
+
const withoutPeers = entryName.split('(')[0];
|
|
81
|
+
const separator = findVersionSeparator(withoutPeers);
|
|
82
|
+
if (separator <= 0)
|
|
83
|
+
return null;
|
|
84
|
+
const encodedName = withoutPeers.slice(0, separator);
|
|
85
|
+
const version = withoutPeers.slice(separator + 1).split('_')[0];
|
|
86
|
+
if (!/^\d/.test(version))
|
|
87
|
+
return null;
|
|
88
|
+
return { Name: decodeStoreName(encodedName), Version: version };
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Directory names in the virtual store. Reads the directory exactly once and is
|
|
92
|
+
* bounded by {@link MAX_STORE_ENTRIES} — hitting the cap throws rather than
|
|
93
|
+
* silently censusing a prefix of the store, which would be a false PASS.
|
|
94
|
+
*/
|
|
95
|
+
function readStoreEntries(storeDir) {
|
|
96
|
+
let dirents;
|
|
97
|
+
try {
|
|
98
|
+
dirents = readdirSync(storeDir, { withFileTypes: true });
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
102
|
+
throw new Error(`Cannot read the package store at ${storeDir}: ${message}`);
|
|
103
|
+
}
|
|
104
|
+
if (dirents.length > MAX_STORE_ENTRIES) {
|
|
105
|
+
throw new Error(`${storeDir} holds ${dirents.length} entries, over the ${MAX_STORE_ENTRIES} cap — refusing to census it`);
|
|
106
|
+
}
|
|
107
|
+
return dirents.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
108
|
+
}
|
|
109
|
+
/** Groups parsed store entries into the distinct versions of each singleton package. Pure. */
|
|
110
|
+
function tallySingletons(entryNames) {
|
|
111
|
+
const wanted = new Set(SINGLETON_PACKAGES);
|
|
112
|
+
const found = new Map();
|
|
113
|
+
let unparsed = 0;
|
|
114
|
+
for (const entryName of entryNames) {
|
|
115
|
+
const entry = ParseStoreEntry(entryName);
|
|
116
|
+
if (entry === null) {
|
|
117
|
+
unparsed++;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (!wanted.has(entry.Name))
|
|
121
|
+
continue;
|
|
122
|
+
const versions = found.get(entry.Name) ?? new Set();
|
|
123
|
+
versions.add(entry.Version);
|
|
124
|
+
found.set(entry.Name, versions);
|
|
125
|
+
}
|
|
126
|
+
const packages = [];
|
|
127
|
+
for (const name of SINGLETON_PACKAGES) {
|
|
128
|
+
const versions = found.get(name);
|
|
129
|
+
if (versions === undefined)
|
|
130
|
+
continue;
|
|
131
|
+
packages.push({ Package: name, Versions: [...versions].sort() });
|
|
132
|
+
}
|
|
133
|
+
return { StorePresent: true, Packages: packages, UnparsedEntryCount: unparsed };
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Counts the distinct versions of each singleton package in the parent's pnpm
|
|
137
|
+
* virtual store, reading DIRECTORY NAMES ONLY — a store entry name already carries
|
|
138
|
+
* `name@version`, so no package.json is opened and the whole census is one
|
|
139
|
+
* `readdirSync`. An absent store is reported as `StorePresent: false`, never as a
|
|
140
|
+
* clean bill of health.
|
|
141
|
+
*
|
|
142
|
+
* KNOWN LIMIT, stated so the PASS is not read as more than it is: pnpm gives
|
|
143
|
+
* workspace-linked packages no virtual-store entry at all (verified — an MJ
|
|
144
|
+
* checkout's own store holds zero `@memberjunction+core@…` entries), so this counts
|
|
145
|
+
* copies IN THE PARENT STORE. A registry copy sitting alongside a workspace link is
|
|
146
|
+
* one store entry and reads as one copy. Catching that is the job of the family
|
|
147
|
+
* `workspace:*` overrides the generator emits, not of this census.
|
|
148
|
+
*
|
|
149
|
+
* SIDE EFFECT: one read-only directory listing.
|
|
150
|
+
*/
|
|
151
|
+
export function CollectSingletonCensus(parentDir) {
|
|
152
|
+
if (!path.isAbsolute(parentDir)) {
|
|
153
|
+
throw new Error(`CollectSingletonCensus requires an absolute path, got: ${parentDir}`);
|
|
154
|
+
}
|
|
155
|
+
const storeDir = path.join(parentDir, STORE_REL_PATH);
|
|
156
|
+
if (!existsSync(storeDir))
|
|
157
|
+
return { StorePresent: false, Packages: [], UnparsedEntryCount: 0 };
|
|
158
|
+
return tallySingletons(readStoreEntries(storeDir));
|
|
159
|
+
}
|
|
160
|
+
/** The parent must be a plain directory holding sibling clones — never a git repo root itself. */
|
|
161
|
+
function checkParentShape(status) {
|
|
162
|
+
if (!status.ParentIsGitRepo) {
|
|
163
|
+
return { Name: 'parent directory', Severity: 'pass', Detail: 'a plain directory, not a git repo root' };
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
Name: 'parent directory',
|
|
167
|
+
Severity: 'fail',
|
|
168
|
+
Detail: 'this directory is a git repo root (.git present) — a workspace parent must be the plain directory that ' +
|
|
169
|
+
'HOLDS the sibling clones; re-run with --dir pointing at their common parent',
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
/** All generated files must be present; a missing one means the workspace was never (fully) generated. */
|
|
173
|
+
function checkGeneratedFiles(status) {
|
|
174
|
+
const missing = status.Files.filter((file) => !file.Exists).map((file) => file.Name);
|
|
175
|
+
if (missing.length === 0) {
|
|
176
|
+
return { Name: 'workspace files', Severity: 'pass', Detail: `all ${status.Files.length} generated files present` };
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
Name: 'workspace files',
|
|
180
|
+
Severity: 'fail',
|
|
181
|
+
Detail: `missing: ${missing.join(', ')} — run \`mj dev workspace --dir ${status.ParentDir}\` to generate them`,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
/** The lockfile and node_modules come from `pnpm install`, not the generator — absence is incomplete, not broken. */
|
|
185
|
+
function checkInstallArtifacts(status) {
|
|
186
|
+
const missing = [];
|
|
187
|
+
if (!status.LockfileExists)
|
|
188
|
+
missing.push(LOCKFILE_NAME);
|
|
189
|
+
if (!status.NodeModulesExists)
|
|
190
|
+
missing.push(NODE_MODULES_NAME);
|
|
191
|
+
if (missing.length === 0) {
|
|
192
|
+
return { Name: 'install', Severity: 'pass', Detail: `${LOCKFILE_NAME} and ${NODE_MODULES_NAME} present` };
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
Name: 'install',
|
|
196
|
+
Severity: 'warn',
|
|
197
|
+
Detail: `missing ${missing.join(' and ')} — run \`pnpm install\` at ${status.ParentDir}`,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/** The sentinel is what proves this workspace came from the generator, and what `clean` requires. */
|
|
201
|
+
function checkSentinel(status) {
|
|
202
|
+
const sentinel = status.Sentinel;
|
|
203
|
+
if (sentinel.Kind === 'valid') {
|
|
204
|
+
const members = sentinel.Sentinel.members.join(', ') || '(none recorded)';
|
|
205
|
+
return { Name: 'sentinel', Severity: 'pass', Detail: `${SENTINEL_FILE_NAME} written by ${SENTINEL_MARKER} (members: ${members})` };
|
|
206
|
+
}
|
|
207
|
+
if (sentinel.Kind === 'invalid') {
|
|
208
|
+
return {
|
|
209
|
+
Name: 'sentinel',
|
|
210
|
+
Severity: 'warn',
|
|
211
|
+
Detail: `${SENTINEL_FILE_NAME} is present but not ours (${sentinel.Reason}) — clean needs --force`,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
Name: 'sentinel',
|
|
216
|
+
Severity: 'warn',
|
|
217
|
+
Detail: `no ${SENTINEL_FILE_NAME} — hand-made or pre-sentinel workspace; clean needs --force`,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
/** The generated pin and the pnpm actually running at the parent must be the same version. */
|
|
221
|
+
function checkPnpmVersion(status) {
|
|
222
|
+
const pinned = status.PinnedPnpm === null ? null : status.PinnedPnpm.slice('pnpm@'.length);
|
|
223
|
+
if (pinned === null) {
|
|
224
|
+
return { Name: 'pnpm version', Severity: 'skip', Detail: 'no pnpm pin at the parent (no generated package.json)' };
|
|
225
|
+
}
|
|
226
|
+
if (status.ActivePnpmVersion === null) {
|
|
227
|
+
return { Name: 'pnpm version', Severity: 'warn', Detail: `pinned ${pinned}, but pnpm is not runnable at the parent` };
|
|
228
|
+
}
|
|
229
|
+
if (status.ActivePnpmVersion === pinned) {
|
|
230
|
+
return { Name: 'pnpm version', Severity: 'pass', Detail: `pinned ${pinned}, active ${status.ActivePnpmVersion} — match` };
|
|
231
|
+
}
|
|
232
|
+
return {
|
|
233
|
+
Name: 'pnpm version',
|
|
234
|
+
Severity: 'warn',
|
|
235
|
+
Detail: `pinned ${pinned}, active ${status.ActivePnpmVersion} — MISMATCH; run \`corepack enable\` so the pin is honored`,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Every member named in pnpm-workspace.yaml must exist on disk. This is a FAIL, not
|
|
240
|
+
* a warning: the generated parent manifest carries a `workspace:*` override for each
|
|
241
|
+
* member-provided package name, so a member whose checkout is gone makes the next
|
|
242
|
+
* `pnpm install` fail outright rather than degrade.
|
|
243
|
+
*/
|
|
244
|
+
function checkMemberDirs(status) {
|
|
245
|
+
if (status.Members.length === 0) {
|
|
246
|
+
return { Name: 'member dirs', Severity: 'skip', Detail: 'no pnpm-workspace.yaml — no members to check' };
|
|
247
|
+
}
|
|
248
|
+
if (status.MissingMemberDirs.length === 0) {
|
|
249
|
+
return { Name: 'member dirs', Severity: 'pass', Detail: `all ${status.Members.length} member directories present` };
|
|
250
|
+
}
|
|
251
|
+
return {
|
|
252
|
+
Name: 'member dirs',
|
|
253
|
+
Severity: 'fail',
|
|
254
|
+
Detail: `in pnpm-workspace.yaml but missing on disk: ${status.MissingMemberDirs.join(', ')} — the parent manifest ` +
|
|
255
|
+
`overrides each member-provided package to workspace:*, so pnpm install will fail; re-clone them or ` +
|
|
256
|
+
`re-run \`mj dev workspace --force\` to regenerate without them`,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
/** Repos on disk that qualify as members but are not in the workspace resolve against their own installs. */
|
|
260
|
+
function checkCandidates(status) {
|
|
261
|
+
if (status.DetectedCandidates.length === 0) {
|
|
262
|
+
return { Name: 'candidates', Severity: 'skip', Detail: 'no member-candidate repos detected at the parent' };
|
|
263
|
+
}
|
|
264
|
+
if (status.CandidatesNotInWorkspace.length === 0) {
|
|
265
|
+
return {
|
|
266
|
+
Name: 'candidates',
|
|
267
|
+
Severity: 'pass',
|
|
268
|
+
Detail: `all ${status.DetectedCandidates.length} detected repos are workspace members`,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
return {
|
|
272
|
+
Name: 'candidates',
|
|
273
|
+
Severity: 'warn',
|
|
274
|
+
Detail: `detected on disk but not in the workspace: ${status.CandidatesNotInWorkspace.join(', ')} — they resolve ` +
|
|
275
|
+
`against their own installs, not this workspace; re-run \`mj dev workspace --force\` to include them`,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* A member carrying its OWN package store has forked resolution away from the
|
|
280
|
+
* workspace. Note what does NOT count: a plain `node_modules` inside a member is
|
|
281
|
+
* what a healthy parent install creates (symlinks into the parent store) — only a
|
|
282
|
+
* member-root `.pnpm` store or npm's `.package-lock.json` marker proves a
|
|
283
|
+
* standalone install, which is the distinction `status.ts` already encodes.
|
|
284
|
+
*
|
|
285
|
+
* Scope, stated in the PASS text rather than implied: this reads the member ROOT
|
|
286
|
+
* only. A repo whose root tree was deleted but whose nested per-package trees
|
|
287
|
+
* survive (the half-finished cleanup #3795 describes) passes here — enumerating
|
|
288
|
+
* those is `--clean-members`' depth-independent walk, not a health check's job.
|
|
289
|
+
*/
|
|
290
|
+
function checkStandaloneInstalls(status) {
|
|
291
|
+
if (status.MembersWithStandaloneInstalls.length === 0) {
|
|
292
|
+
return {
|
|
293
|
+
Name: 'standalone installs',
|
|
294
|
+
Severity: 'pass',
|
|
295
|
+
Detail: 'no member root carries its own package store (a member node_modules from the parent install is normal; ' +
|
|
296
|
+
'nested per-package trees are not scanned — `dev workspace --clean-members` removes those)',
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
return {
|
|
300
|
+
Name: 'standalone installs',
|
|
301
|
+
Severity: 'fail',
|
|
302
|
+
Detail: `${status.MembersWithStandaloneInstalls.join(', ')} — each has its own package store, so its code resolves ` +
|
|
303
|
+
`against that store instead of this workspace (split singletons, stale deps). ` +
|
|
304
|
+
`Fix: re-run \`mj dev workspace --clean-members\`.`,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
/** Appends the unparsed-entry tally to a census detail, so dropped store entries are never silent. */
|
|
308
|
+
function withUnparsedNote(detail, census) {
|
|
309
|
+
const count = census.UnparsedEntryCount;
|
|
310
|
+
if (count === 0)
|
|
311
|
+
return detail;
|
|
312
|
+
const noun = count === 1 ? 'entry is' : 'entries are';
|
|
313
|
+
return `${detail} (${count} store ${noun} not name@version — links and the store's own node_modules)`;
|
|
314
|
+
}
|
|
315
|
+
/** Exactly one version of each singleton package may exist in the parent's store. */
|
|
316
|
+
function checkOneCopyCensus(census) {
|
|
317
|
+
const name = 'one-copy census';
|
|
318
|
+
if (!census.StorePresent) {
|
|
319
|
+
return { Name: name, Severity: 'skip', Detail: `no ${STORE_REL_PATH} at the parent — no pnpm package store to census` };
|
|
320
|
+
}
|
|
321
|
+
if (census.Packages.length === 0) {
|
|
322
|
+
return { Name: name, Severity: 'skip', Detail: withUnparsedNote('none of the single-copy packages are installed here', census) };
|
|
323
|
+
}
|
|
324
|
+
const duplicated = census.Packages.filter((entry) => entry.Versions.length > 1);
|
|
325
|
+
if (duplicated.length === 0) {
|
|
326
|
+
const listed = census.Packages.map((entry) => `${entry.Package}@${entry.Versions[0]}`).join(', ');
|
|
327
|
+
return { Name: name, Severity: 'pass', Detail: withUnparsedNote(`one copy each in the parent store: ${listed}`, census) };
|
|
328
|
+
}
|
|
329
|
+
const broken = duplicated.map((entry) => `${entry.Package} (${entry.Versions.join(', ')})`).join('; ');
|
|
330
|
+
return {
|
|
331
|
+
Name: name,
|
|
332
|
+
Severity: 'fail',
|
|
333
|
+
Detail: `more than one version in the parent store: ${broken} — these must be single-copy (Angular DI and MJ's ` +
|
|
334
|
+
`Global Object Store key off module identity, so a second copy is a second, invisible runtime). ` +
|
|
335
|
+
`Fix: re-run \`mj dev workspace --force\` to re-derive the pins, then \`pnpm install\` at the parent.`,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Runs every health check at a parent directory. `activePnpmVersion` comes from the
|
|
340
|
+
* caller (a spawn — see `pnpm.ts`) and `dirSource` likewise, so this module reads
|
|
341
|
+
* neither processes nor the environment. Read-only.
|
|
342
|
+
*/
|
|
343
|
+
export function CollectDoctorReport(parentDir, activePnpmVersion, dirSource) {
|
|
344
|
+
if (!path.isAbsolute(parentDir)) {
|
|
345
|
+
throw new Error(`CollectDoctorReport requires an absolute path, got: ${parentDir}`);
|
|
346
|
+
}
|
|
347
|
+
const status = CollectWorkspaceStatus(parentDir, activePnpmVersion, dirSource);
|
|
348
|
+
const census = CollectSingletonCensus(parentDir);
|
|
349
|
+
return {
|
|
350
|
+
ParentDir: parentDir,
|
|
351
|
+
DirSource: dirSource,
|
|
352
|
+
Census: census,
|
|
353
|
+
Checks: [
|
|
354
|
+
checkParentShape(status),
|
|
355
|
+
checkGeneratedFiles(status),
|
|
356
|
+
checkInstallArtifacts(status),
|
|
357
|
+
checkSentinel(status),
|
|
358
|
+
checkPnpmVersion(status),
|
|
359
|
+
checkMemberDirs(status),
|
|
360
|
+
checkCandidates(status),
|
|
361
|
+
checkStandaloneInstalls(status),
|
|
362
|
+
checkOneCopyCensus(census),
|
|
363
|
+
],
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
/** Severity tag printed at the head of each line. */
|
|
367
|
+
const SEVERITY_TAGS = {
|
|
368
|
+
pass: chalk.green('[PASS]'),
|
|
369
|
+
warn: chalk.yellow('[WARN]'),
|
|
370
|
+
fail: chalk.red('[FAIL]'),
|
|
371
|
+
skip: chalk.dim('[SKIP]'),
|
|
372
|
+
};
|
|
373
|
+
/** True when any check failed — the command's exit-code decision. Pure. */
|
|
374
|
+
export function DoctorHasFailures(report) {
|
|
375
|
+
return report.Checks.some((check) => check.Severity === 'fail');
|
|
376
|
+
}
|
|
377
|
+
/** Counts each severity and states the exit-code consequence plainly. Pure. */
|
|
378
|
+
function renderSummary(report) {
|
|
379
|
+
const countOf = (severity) => report.Checks.filter((check) => check.Severity === severity).length;
|
|
380
|
+
const failed = countOf('fail');
|
|
381
|
+
const summary = `${countOf('pass')} passed, ${countOf('warn')} warned, ${failed} failed, ${countOf('skip')} skipped`;
|
|
382
|
+
if (failed === 0)
|
|
383
|
+
return chalk.green(`${summary} — no failures.`);
|
|
384
|
+
return chalk.red(`${summary} — doctor exits non-zero.`);
|
|
385
|
+
}
|
|
386
|
+
/** Renders a DoctorReport as the terminal report. Pure. */
|
|
387
|
+
export function RenderDoctor(report) {
|
|
388
|
+
const lines = [
|
|
389
|
+
chalk.bold(`Workspace doctor: ${report.ParentDir}`),
|
|
390
|
+
chalk.dim(` resolved from: ${DescribeDirSource(report.DirSource)}`),
|
|
391
|
+
'',
|
|
392
|
+
];
|
|
393
|
+
for (const check of report.Checks) {
|
|
394
|
+
lines.push(`${SEVERITY_TAGS[check.Severity]} ${check.Name}: ${check.Detail}`);
|
|
395
|
+
}
|
|
396
|
+
lines.push('');
|
|
397
|
+
lines.push(renderSummary(report));
|
|
398
|
+
return lines.join('\n');
|
|
399
|
+
}
|
|
400
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/lib/dev-workspace/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { DevDepConflict, MemberLockfile, UnsupportedLockfile } from './types.js';
|
|
2
|
+
/** True when the string is a plain concrete semver version. */
|
|
3
|
+
export declare function IsResolvedVersion(version: string): boolean;
|
|
4
|
+
/** Major-version number of a concrete resolution. Throws on non-semver input (precondition). */
|
|
5
|
+
export declare function MajorOf(version: string): number;
|
|
6
|
+
/**
|
|
7
|
+
* Compares two CONCRETE versions: numeric triple first; on a triple tie a
|
|
8
|
+
* release beats a prerelease, and two prereleases compare by tag string.
|
|
9
|
+
* Throws on non-semver input — callers filter through {@link IsResolvedVersion} first.
|
|
10
|
+
*/
|
|
11
|
+
export declare function CompareResolvedVersions(a: string, b: string): number;
|
|
12
|
+
/** Parses a committed pnpm-lock.yaml. Only v9+ is readable; older formats return an unsupported marker. */
|
|
13
|
+
export declare function ParsePnpmLockfile(lockText: string): MemberLockfile | UnsupportedLockfile;
|
|
14
|
+
/** Parses a committed npm package-lock.json. Only lockfileVersion 2/3 is readable. */
|
|
15
|
+
export declare function ParseNpmLockfile(lockText: string): MemberLockfile | UnsupportedLockfile;
|
|
16
|
+
/**
|
|
17
|
+
* Reads a member's committed lockfile: `pnpm-lock.yaml` first, `package-lock.json`
|
|
18
|
+
* otherwise, null when the repo commits neither. An unsupported format comes back
|
|
19
|
+
* as a marker (the command warns); unparseable content throws — a corrupt
|
|
20
|
+
* lockfile must never silently become "no pins for this member".
|
|
21
|
+
*/
|
|
22
|
+
export declare function ReadMemberLockfile(repoPath: string): MemberLockfile | UnsupportedLockfile | null;
|
|
23
|
+
/** The pure result of the cross-member pin derivation. */
|
|
24
|
+
export interface LockfilePinsResult {
|
|
25
|
+
/**
|
|
26
|
+
* Override entries, sorted by key. Values are EXACT versions. Keys are plain
|
|
27
|
+
* names for single-major names, per-major selectors (`name@^N`) otherwise.
|
|
28
|
+
*/
|
|
29
|
+
Pins: Record<string, string>;
|
|
30
|
+
/** Same-major disagreements the highest committed exact resolution won (key names the emitted selector). */
|
|
31
|
+
Conflicts: DevDepConflict[];
|
|
32
|
+
/** Names excluded because a workspace member provides them (workspace:* covers those). */
|
|
33
|
+
ExcludedFamilyNames: string[];
|
|
34
|
+
}
|
|
35
|
+
/** One member's candidate resolutions, tagged with the repo for conflict reporting. */
|
|
36
|
+
export interface MemberLockfileCandidates {
|
|
37
|
+
Repo: string;
|
|
38
|
+
Lockfile: MemberLockfile;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Derives the parent `pnpm.overrides` pins from the members' committed lockfiles.
|
|
42
|
+
* Pure.
|
|
43
|
+
*
|
|
44
|
+
* AUTHORITY RULE (adversarial-review round 3): a version may vote only where a
|
|
45
|
+
* member DIRECTLY declares the name (its importers resolve it), plus `@types/*`
|
|
46
|
+
* at any depth minus those parented solely by registry copies of family
|
|
47
|
+
* packages. At-depth resolutions of ordinary packages are NOT candidates — a
|
|
48
|
+
* bizapps lockfile resolved with registry `@memberjunction/*` describes a graph
|
|
49
|
+
* that cannot exist in the generated workspace, and letting it vote handed the
|
|
50
|
+
* field's floated versions (`@cerebras` 1.91.0, `@foblex` 18.6.1) a win over
|
|
51
|
+
* MJ's committed 1.64.1/18.0.0.
|
|
52
|
+
*
|
|
53
|
+
* KEY SCOPING: at-depth majors still decide the KEY SHAPE — when any member's
|
|
54
|
+
* graph holds another major of a pinned name anywhere, the pin is emitted as a
|
|
55
|
+
* `name@^N` selector so transitive consumers of the other majors float within
|
|
56
|
+
* their declared ranges (never forced cross-major); only majors present among
|
|
57
|
+
* the candidates get a selector at all. Values are EXACT — `^resolved` provably
|
|
58
|
+
* passed 6 of 7 field-measured breaks through. Disagreements within a major
|
|
59
|
+
* among direct declarations are genuine: highest committed exact wins, reported.
|
|
60
|
+
*/
|
|
61
|
+
export declare function DeriveLockfilePins(members: readonly MemberLockfileCandidates[], familyNames: ReadonlySet<string>): LockfilePinsResult;
|
|
62
|
+
//# sourceMappingURL=lockfile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lockfile.d.ts","sourceRoot":"","sources":["../../../src/lib/dev-workspace/lockfile.ts"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EAAE,cAAc,EAAgB,cAAc,EAAqB,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAWvH,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED,gGAAgG;AAChG,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAepE;AAwID,2GAA2G;AAC3G,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,mBAAmB,CAkBxF;AA4DD,sFAAsF;AACtF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,mBAAmB,CA4BvF;AAyBD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,mBAAmB,GAAG,IAAI,CAahG;AAED,0DAA0D;AAC1D,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,4GAA4G;IAC5G,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,0FAA0F;IAC1F,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,uFAAuF;AACvF,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,cAAc,CAAC;CAC1B;AA2BD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,wBAAwB,EAAE,EAAE,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,kBAAkB,CA8BrI"}
|