@metaobjectsdev/cli 1.0.3 → 1.0.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 +13 -5
- package/dist/src/commands/eject.d.ts +2 -1
- package/dist/src/commands/eject.d.ts.map +1 -1
- package/dist/src/commands/eject.js +235 -75
- package/dist/src/commands/eject.js.map +1 -1
- package/dist/src/commands/gen.d.ts.map +1 -1
- package/dist/src/commands/gen.js +119 -29
- package/dist/src/commands/gen.js.map +1 -1
- package/dist/src/commands/init.d.ts +5 -9
- package/dist/src/commands/init.d.ts.map +1 -1
- package/dist/src/commands/init.js +80 -384
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/verify.d.ts.map +1 -1
- package/dist/src/commands/verify.js +40 -14
- package/dist/src/commands/verify.js.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +36 -14
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib/advisory.d.ts +6 -0
- package/dist/src/lib/advisory.d.ts.map +1 -1
- package/dist/src/lib/advisory.js +10 -0
- package/dist/src/lib/advisory.js.map +1 -1
- package/dist/src/lib/args.d.ts +18 -2
- package/dist/src/lib/args.d.ts.map +1 -1
- package/dist/src/lib/args.js +15 -3
- package/dist/src/lib/args.js.map +1 -1
- package/dist/src/lib/catalog-listing.d.ts +92 -0
- package/dist/src/lib/catalog-listing.d.ts.map +1 -0
- package/dist/src/lib/catalog-listing.js +268 -0
- package/dist/src/lib/catalog-listing.js.map +1 -0
- package/dist/src/lib/catalog.d.ts +41 -0
- package/dist/src/lib/catalog.d.ts.map +1 -0
- package/dist/src/lib/catalog.js +89 -0
- package/dist/src/lib/catalog.js.map +1 -0
- package/dist/src/lib/collection-load-options.d.ts +1 -1
- package/dist/src/lib/collection-load-options.d.ts.map +1 -1
- package/dist/src/lib/collection-load-options.js +6 -0
- package/dist/src/lib/collection-load-options.js.map +1 -1
- package/dist/src/lib/install-set.d.ts +31 -0
- package/dist/src/lib/install-set.d.ts.map +1 -0
- package/dist/src/lib/install-set.js +103 -0
- package/dist/src/lib/install-set.js.map +1 -0
- package/dist/src/lib/library-eject.d.ts +79 -0
- package/dist/src/lib/library-eject.d.ts.map +1 -0
- package/dist/src/lib/library-eject.js +241 -0
- package/dist/src/lib/library-eject.js.map +1 -0
- package/dist/src/lib/library-listing.d.ts +63 -0
- package/dist/src/lib/library-listing.d.ts.map +1 -0
- package/dist/src/lib/library-listing.js +178 -0
- package/dist/src/lib/library-listing.js.map +1 -0
- package/dist/src/lib/library-prefix-advisory.d.ts +17 -0
- package/dist/src/lib/library-prefix-advisory.d.ts.map +1 -0
- package/dist/src/lib/library-prefix-advisory.js +67 -0
- package/dist/src/lib/library-prefix-advisory.js.map +1 -0
- package/dist/src/lib/load-metaobjects-config.d.ts +1 -2
- package/dist/src/lib/load-metaobjects-config.d.ts.map +1 -1
- package/dist/src/lib/load-metaobjects-config.js +11 -17
- package/dist/src/lib/load-metaobjects-config.js.map +1 -1
- package/dist/src/lib/requirement-check.d.ts +17 -2
- package/dist/src/lib/requirement-check.d.ts.map +1 -1
- package/dist/src/lib/requirement-check.js +51 -9
- package/dist/src/lib/requirement-check.js.map +1 -1
- package/package.json +10 -10
- package/src/commands/eject.ts +304 -90
- package/src/commands/gen.ts +128 -28
- package/src/commands/init.ts +82 -390
- package/src/commands/verify.ts +47 -15
- package/src/index.ts +36 -14
- package/src/lib/advisory.ts +13 -0
- package/src/lib/args.ts +29 -5
- package/src/lib/catalog-listing.ts +369 -0
- package/src/lib/catalog.ts +107 -0
- package/src/lib/collection-load-options.ts +7 -1
- package/src/lib/install-set.ts +116 -0
- package/src/lib/library-eject.ts +298 -0
- package/src/lib/library-listing.ts +258 -0
- package/src/lib/library-prefix-advisory.ts +78 -0
- package/src/lib/load-metaobjects-config.ts +15 -21
- package/src/lib/requirement-check.ts +71 -11
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// The TypeScript port's generator CATALOG — the one place all three registry slices
|
|
2
|
+
// are visible at once (ADR-0021 D3; opt-in-codegen design §D2a).
|
|
3
|
+
//
|
|
4
|
+
// `codegen-ts` owns the entry type and its own entries, but cannot import
|
|
5
|
+
// `codegen-ts-react` / `codegen-ts-tanstack` (dependency direction), so each of those
|
|
6
|
+
// exports its own slice and the CLI unions them here — exactly how `eject.ts` already
|
|
7
|
+
// composes its `SOURCES` table over the same three packages.
|
|
8
|
+
//
|
|
9
|
+
// Before this existed, `meta gen --list` read the codegen-ts registry and
|
|
10
|
+
// `meta eject --list` read the reference-template lists, so an agent asking "what can I
|
|
11
|
+
// turn on" got two different answers. After it, they are one table with two views.
|
|
12
|
+
//
|
|
13
|
+
// (The Angular generators stay out until ADR-0048's promotion bar is met — a
|
|
14
|
+
// source-only package is not a catalog entry.)
|
|
15
|
+
import { generatorRegistry, GENERATOR_LAYERS, } from "@metaobjectsdev/codegen-ts";
|
|
16
|
+
import { reactGeneratorRegistry } from "@metaobjectsdev/codegen-ts-react";
|
|
17
|
+
import { tanstackGeneratorRegistry } from "@metaobjectsdev/codegen-ts-tanstack";
|
|
18
|
+
/** The slices, in install-boundary order: the engine, then its framework packages. */
|
|
19
|
+
const SLICES = [
|
|
20
|
+
["@metaobjectsdev/codegen-ts", generatorRegistry],
|
|
21
|
+
["@metaobjectsdev/codegen-ts-react", reactGeneratorRegistry],
|
|
22
|
+
["@metaobjectsdev/codegen-ts-tanstack", tanstackGeneratorRegistry],
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* Which npm package a catalog entry comes from.
|
|
26
|
+
*
|
|
27
|
+
* This is the fact composition ADDS: a slice cannot know its own package name without
|
|
28
|
+
* hard-coding it in every entry, and the package is precisely what `meta eject` has to
|
|
29
|
+
* name in an install command. Undefined for a name no slice registers.
|
|
30
|
+
*/
|
|
31
|
+
export function packageOf(name) {
|
|
32
|
+
return SLICES.find(([, slice]) => name in slice)?.[0];
|
|
33
|
+
}
|
|
34
|
+
/** Every `@metaobjectsdev` package that contributes catalog entries. */
|
|
35
|
+
export function catalogPackages() {
|
|
36
|
+
return SLICES.map(([pkg]) => pkg);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The composed catalog, keyed by stable name.
|
|
40
|
+
*
|
|
41
|
+
* Throws on a name registered by two packages. A stable name identifies ONE generator
|
|
42
|
+
* across the whole catalog — that is the entire content of ADR-0021 D3 — so a collision
|
|
43
|
+
* is a build-time defect, not something to resolve by precedence. Silently letting the
|
|
44
|
+
* last slice win would make `meta gen --list` describe one generator and `meta gen` run
|
|
45
|
+
* another.
|
|
46
|
+
*/
|
|
47
|
+
export function composeCatalog() {
|
|
48
|
+
return composeSlices(SLICES);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The composition itself, over any slice list.
|
|
52
|
+
*
|
|
53
|
+
* Separate from {@link composeCatalog} so the REFUSAL is reachable from a test. With the
|
|
54
|
+
* live `SLICES` closed over, the only thing a test could assert is that today's three
|
|
55
|
+
* packages happen not to collide — which stays true if the check above is deleted, so
|
|
56
|
+
* the guard that makes a collision a build failure was never covered by anything.
|
|
57
|
+
*/
|
|
58
|
+
export function composeSlices(slices) {
|
|
59
|
+
const out = {};
|
|
60
|
+
const from = {};
|
|
61
|
+
for (const [pkg, slice] of slices) {
|
|
62
|
+
for (const [name, entry] of Object.entries(slice)) {
|
|
63
|
+
if (name in out) {
|
|
64
|
+
throw new Error(`generator "${name}" is registered by both ${from[name]} and ${pkg} — a stable ` +
|
|
65
|
+
"name identifies ONE generator across the whole catalog (ADR-0021 D3). Rename " +
|
|
66
|
+
"one of them, or delete the duplicate registration.");
|
|
67
|
+
}
|
|
68
|
+
out[name] = entry;
|
|
69
|
+
from[name] = pkg;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Every catalog entry, grouped by layer in {@link GENERATOR_LAYERS} order and
|
|
76
|
+
* alphabetical within a layer.
|
|
77
|
+
*
|
|
78
|
+
* Layer order, not tier order: `layer` is the axis an adopter selects by, so it is the
|
|
79
|
+
* axis the listing is organized along. `tier` still travels on each row.
|
|
80
|
+
*/
|
|
81
|
+
export function listCatalog() {
|
|
82
|
+
return Object.values(composeCatalog()).sort((a, b) => GENERATOR_LAYERS.indexOf(a.layer) - GENERATOR_LAYERS.indexOf(b.layer) ||
|
|
83
|
+
a.name.localeCompare(b.name));
|
|
84
|
+
}
|
|
85
|
+
/** Resolve one catalog entry by stable name, or undefined. */
|
|
86
|
+
export function catalogEntry(name) {
|
|
87
|
+
return composeCatalog()[name];
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../../src/lib/catalog.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,iEAAiE;AACjE,EAAE;AACF,0EAA0E;AAC1E,sFAAsF;AACtF,sFAAsF;AACtF,6DAA6D;AAC7D,EAAE;AACF,0EAA0E;AAC1E,wFAAwF;AACxF,mFAAmF;AACnF,EAAE;AACF,6EAA6E;AAC7E,+CAA+C;AAE/C,OAAO,EACL,iBAAiB,EACjB,gBAAgB,GAEjB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAEhF,sFAAsF;AACtF,MAAM,MAAM,GAA6E;IACvF,CAAC,4BAA4B,EAAE,iBAAiB,CAAC;IACjD,CAAC,kCAAkC,EAAE,sBAAsB,CAAC;IAC5D,CAAC,qCAAqC,EAAE,yBAAyB,CAAC;CACnE,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,eAAe;IAC7B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAgF;IAEhF,MAAM,GAAG,GAA2C,EAAE,CAAC;IACvD,MAAM,IAAI,GAA2B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;QAClC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAClD,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;gBAChB,MAAM,IAAI,KAAK,CACb,cAAc,IAAI,2BAA2B,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,cAAc;oBAC9E,+EAA+E;oBAC/E,oDAAoD,CACvD,CAAC;YACJ,CAAC;YACD,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;YAClB,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,IAAI,CACzC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;QACrE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAC/B,CAAC;AACJ,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,cAAc,EAAE,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -9,5 +9,5 @@ import type { Collection, LoadMemoryOptions } from "@metaobjectsdev/sdk";
|
|
|
9
9
|
* hand-written shape, so renaming or retyping an option there is a compile
|
|
10
10
|
* error here rather than a silently-dropped key.
|
|
11
11
|
*/
|
|
12
|
-
export declare function collectionLoadOptions(collection: Collection): Required<Pick<LoadMemoryOptions, "files" | "fileIds" | "importedPackages" | "importedNodes">>;
|
|
12
|
+
export declare function collectionLoadOptions(collection: Collection): Required<Pick<LoadMemoryOptions, "files" | "fileIds" | "importedPackages" | "importedNodes" | "libraries">>;
|
|
13
13
|
//# sourceMappingURL=collection-load-options.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-load-options.d.ts","sourceRoot":"","sources":["../../../src/lib/collection-load-options.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEzE;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,GACrB,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,GAAG,SAAS,GAAG,kBAAkB,GAAG,eAAe,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"collection-load-options.d.ts","sourceRoot":"","sources":["../../../src/lib/collection-load-options.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEzE;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,GACrB,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,GAAG,SAAS,GAAG,kBAAkB,GAAG,eAAe,GAAG,WAAW,CAAC,CAAC,CAa7G"}
|
|
@@ -14,6 +14,12 @@ export function collectionLoadOptions(collection) {
|
|
|
14
14
|
fileIds: collection.fileIds,
|
|
15
15
|
importedPackages: collection.importedPackages,
|
|
16
16
|
importedNodes: collection.importedNodes,
|
|
17
|
+
// FR-043 — the shipped-library selection moved here from metaobjects.config.ts, so
|
|
18
|
+
// it now rides the same helper as everything else the collection contributes. That
|
|
19
|
+
// is the point of the move as much as the neutrality is: `libraries` used to be
|
|
20
|
+
// threaded by `loadMemoryOptionsFrom`, a SECOND helper, and #333 is on record as the
|
|
21
|
+
// bug where one of the two reached every command and the other reached none.
|
|
22
|
+
libraries: collection.libraries,
|
|
17
23
|
};
|
|
18
24
|
}
|
|
19
25
|
//# sourceMappingURL=collection-load-options.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-load-options.js","sourceRoot":"","sources":["../../../src/lib/collection-load-options.ts"],"names":[],"mappings":"AAgBA;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CACnC,UAAsB;IAEtB,OAAO;QACL,KAAK,EAAE,UAAU,CAAC,KAAK;QACvB,OAAO,EAAE,UAAU,CAAC,OAAO;QAC3B,gBAAgB,EAAE,UAAU,CAAC,gBAAgB;QAC7C,aAAa,EAAE,UAAU,CAAC,aAAa;
|
|
1
|
+
{"version":3,"file":"collection-load-options.js","sourceRoot":"","sources":["../../../src/lib/collection-load-options.ts"],"names":[],"mappings":"AAgBA;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CACnC,UAAsB;IAEtB,OAAO;QACL,KAAK,EAAE,UAAU,CAAC,KAAK;QACvB,OAAO,EAAE,UAAU,CAAC,OAAO;QAC3B,gBAAgB,EAAE,UAAU,CAAC,gBAAgB;QAC7C,aAAa,EAAE,UAAU,CAAC,aAAa;QACvC,mFAAmF;QACnF,mFAAmF;QACnF,gFAAgF;QAChF,qFAAqF;QACrF,6EAA6E;QAC7E,SAAS,EAAE,UAAU,CAAC,SAAS;KAChC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { GeneratorRegistryEntry } from "@metaobjectsdev/codegen-ts";
|
|
2
|
+
/**
|
|
3
|
+
* A package's declared peer ranges, or `{}` if they cannot be read.
|
|
4
|
+
*
|
|
5
|
+
* Resolves the package's ENTRY and walks up to the nearest manifest, rather than asking
|
|
6
|
+
* for `"<pkg>/package.json"` directly. The direct form is the obvious one and it is
|
|
7
|
+
* WRONG: a package's `exports` map gates every subpath, and `@metaobjectsdev/runtime-ts`
|
|
8
|
+
* exports `.` / `./drivers` / `./fastify` / `./drizzle-fastify` / `./hono` and no
|
|
9
|
+
* `./package.json`, so under real Node it throws ERR_PACKAGE_PATH_NOT_EXPORTED. It
|
|
10
|
+
* appeared to work in-repo only because bun resolves a symlinked source tree; against
|
|
11
|
+
* the published package it failed silently on the first try. Resolving the entry is
|
|
12
|
+
* never gated — `.` is the one subpath every package exports.
|
|
13
|
+
*/
|
|
14
|
+
export declare function peerRangesOf(packageName: string): Record<string, string>;
|
|
15
|
+
export interface InstallSet {
|
|
16
|
+
/** Build-time packages, `name@range`. */
|
|
17
|
+
dev: string[];
|
|
18
|
+
/** Application-runtime packages, `name@range` (or bare `name` if no range is known). */
|
|
19
|
+
runtime: string[];
|
|
20
|
+
/** A paste-ready shell line, or "" when there is nothing to install. */
|
|
21
|
+
command: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The consolidated install set for a group of catalog entries.
|
|
25
|
+
*
|
|
26
|
+
* Consolidated, not per-entry: ejecting `hooks` and `grid` needs
|
|
27
|
+
* `@metaobjectsdev/codegen-ts-tanstack` ONCE, and an adopter handed the same package
|
|
28
|
+
* twice reasonably wonders which one to run.
|
|
29
|
+
*/
|
|
30
|
+
export declare function installSetFor(entries: readonly GeneratorRegistryEntry[]): InstallSet;
|
|
31
|
+
//# sourceMappingURL=install-set.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-set.d.ts","sourceRoot":"","sources":["../../../src/lib/install-set.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAKzE;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAwBxE;AAED,MAAM,WAAW,UAAU;IACzB,yCAAyC;IACzC,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,wFAAwF;IACxF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,SAAS,sBAAsB,EAAE,GAAG,UAAU,CA8BpF"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// What a catalog entry costs to install — the one derivation behind both
|
|
2
|
+
// `meta gen --list --format json` and `meta eject --format json`.
|
|
3
|
+
//
|
|
4
|
+
// Two kinds of package, resolved two different ways:
|
|
5
|
+
//
|
|
6
|
+
// dev the `@metaobjectsdev/codegen-*` package the generator lives in. Its range
|
|
7
|
+
// is the CLI's own version: the engine and the CLI ship in lockstep, so a
|
|
8
|
+
// generator from a different minor is a version mismatch, not a choice.
|
|
9
|
+
// runtime the `@metaobjectsdev` runtime the EMITTED code imports, plus the
|
|
10
|
+
// third-party packages it imports. The runtime's range is the CLI's version
|
|
11
|
+
// for the same reason; the third-party RANGES are read from that runtime
|
|
12
|
+
// package's own `peerDependencies` and are never written here.
|
|
13
|
+
//
|
|
14
|
+
// That last rule is the point of this module. A second copy of a peer range in the CLI
|
|
15
|
+
// is a second thing to keep in step, and the failure mode of drift is an adopter
|
|
16
|
+
// installing a major nothing was tested against — the ERESOLVE trap FR-040 §4.4
|
|
17
|
+
// documented, closed by construction rather than by a warning. If a range cannot be
|
|
18
|
+
// read, the package is reported WITHOUT one rather than guessed at.
|
|
19
|
+
import { createRequire } from "node:module";
|
|
20
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
21
|
+
import { dirname, join } from "node:path";
|
|
22
|
+
import { cliVersion } from "./version.js";
|
|
23
|
+
import { packageOf } from "./catalog.js";
|
|
24
|
+
/**
|
|
25
|
+
* A package's declared peer ranges, or `{}` if they cannot be read.
|
|
26
|
+
*
|
|
27
|
+
* Resolves the package's ENTRY and walks up to the nearest manifest, rather than asking
|
|
28
|
+
* for `"<pkg>/package.json"` directly. The direct form is the obvious one and it is
|
|
29
|
+
* WRONG: a package's `exports` map gates every subpath, and `@metaobjectsdev/runtime-ts`
|
|
30
|
+
* exports `.` / `./drivers` / `./fastify` / `./drizzle-fastify` / `./hono` and no
|
|
31
|
+
* `./package.json`, so under real Node it throws ERR_PACKAGE_PATH_NOT_EXPORTED. It
|
|
32
|
+
* appeared to work in-repo only because bun resolves a symlinked source tree; against
|
|
33
|
+
* the published package it failed silently on the first try. Resolving the entry is
|
|
34
|
+
* never gated — `.` is the one subpath every package exports.
|
|
35
|
+
*/
|
|
36
|
+
export function peerRangesOf(packageName) {
|
|
37
|
+
try {
|
|
38
|
+
const req = createRequire(import.meta.url);
|
|
39
|
+
let dir = dirname(req.resolve(packageName));
|
|
40
|
+
// The entry sits under dist/; the manifest is at the package root above it.
|
|
41
|
+
for (let hops = 0; hops < 8; hops++) {
|
|
42
|
+
const candidate = join(dir, "package.json");
|
|
43
|
+
if (existsSync(candidate)) {
|
|
44
|
+
const manifest = JSON.parse(readFileSync(candidate, "utf8"));
|
|
45
|
+
// Guard against stopping at a nested manifest that is not the package itself.
|
|
46
|
+
if (manifest.name === packageName) {
|
|
47
|
+
return (manifest.peerDependencies ?? {});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const up = dirname(dir);
|
|
51
|
+
if (up === dir)
|
|
52
|
+
break;
|
|
53
|
+
dir = up;
|
|
54
|
+
}
|
|
55
|
+
return {};
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return {};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function spec(name, range) {
|
|
62
|
+
return range === undefined ? name : `${name}@${range}`;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The consolidated install set for a group of catalog entries.
|
|
66
|
+
*
|
|
67
|
+
* Consolidated, not per-entry: ejecting `hooks` and `grid` needs
|
|
68
|
+
* `@metaobjectsdev/codegen-ts-tanstack` ONCE, and an adopter handed the same package
|
|
69
|
+
* twice reasonably wonders which one to run.
|
|
70
|
+
*/
|
|
71
|
+
export function installSetFor(entries) {
|
|
72
|
+
const version = cliVersion();
|
|
73
|
+
const dev = new Set();
|
|
74
|
+
const runtime = new Set();
|
|
75
|
+
for (const entry of entries) {
|
|
76
|
+
const pkg = packageOf(entry.name);
|
|
77
|
+
if (pkg !== undefined)
|
|
78
|
+
dev.add(spec(pkg, `^${version}`));
|
|
79
|
+
for (const rt of entry.runtimePackages ?? [])
|
|
80
|
+
runtime.add(spec(rt, `^${version}`));
|
|
81
|
+
if (entry.runtimePeers !== undefined && entry.runtimePeers.length > 0) {
|
|
82
|
+
// Ranges come from whichever runtime package declares these as peers — the union
|
|
83
|
+
// over this generator's runtimes, since a generator emitting against two of them
|
|
84
|
+
// may take a peer from either. A generator with third-party peers but no runtime
|
|
85
|
+
// package of its own has none to read, so its peers are named UNPINNED: honest,
|
|
86
|
+
// and better than a made-up bound.
|
|
87
|
+
const ranges = {};
|
|
88
|
+
for (const rt of entry.runtimePackages ?? [])
|
|
89
|
+
Object.assign(ranges, peerRangesOf(rt));
|
|
90
|
+
for (const peer of entry.runtimePeers)
|
|
91
|
+
runtime.add(spec(peer, ranges[peer]));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const devList = [...dev].sort();
|
|
95
|
+
const runtimeList = [...runtime].sort();
|
|
96
|
+
const parts = [];
|
|
97
|
+
if (devList.length > 0)
|
|
98
|
+
parts.push(`npm i -D ${devList.join(" ")}`);
|
|
99
|
+
if (runtimeList.length > 0)
|
|
100
|
+
parts.push(`npm i ${runtimeList.join(" ")}`);
|
|
101
|
+
return { dev: devList, runtime: runtimeList, command: parts.join(" && ") };
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=install-set.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-set.js","sourceRoot":"","sources":["../../../src/lib/install-set.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { type MetaData } from "@metaobjectsdev/metadata";
|
|
2
|
+
/** The first line of every ejected file — the marker `--list` scans for. */
|
|
3
|
+
export declare const EJECT_MARKER = "# meta-eject:";
|
|
4
|
+
/** True when `name` is a shipped library rather than a generator. */
|
|
5
|
+
export declare function isLibraryName(name: string): boolean;
|
|
6
|
+
/** Every shipped library name, sorted. */
|
|
7
|
+
export declare function ejectableLibraryNames(): string[];
|
|
8
|
+
/**
|
|
9
|
+
* Where an ejected ref lands: `meta.<library>.<file>.yaml`.
|
|
10
|
+
*
|
|
11
|
+
* Not the library's own basename. `model.yaml` / `db.yaml` / `requirements.yaml` are
|
|
12
|
+
* meaningful inside `library/iam/` and meaningless in a directory holding an
|
|
13
|
+
* application's whole model — and three libraries ejected into one root would collide
|
|
14
|
+
* outright. The `meta.<concept>.<...>` shape is the file-naming convention this project
|
|
15
|
+
* documents.
|
|
16
|
+
*/
|
|
17
|
+
export declare function ejectedFileName(library: string, ref: string): string;
|
|
18
|
+
export interface EjectedLibraryFile {
|
|
19
|
+
ref: string;
|
|
20
|
+
/** Path relative to the project root. */
|
|
21
|
+
path: string;
|
|
22
|
+
status: "created" | "preserved" | "replaced";
|
|
23
|
+
}
|
|
24
|
+
export interface LibraryEjectResult {
|
|
25
|
+
library: string;
|
|
26
|
+
/** Absolute destination directory. */
|
|
27
|
+
root: string;
|
|
28
|
+
files: EjectedLibraryFile[];
|
|
29
|
+
/** The tokens for this library the project currently declares — what to remove. */
|
|
30
|
+
stillOptedIn: readonly string[];
|
|
31
|
+
}
|
|
32
|
+
export declare function ejectLibrary(opts: {
|
|
33
|
+
cwd: string;
|
|
34
|
+
name: string;
|
|
35
|
+
force?: boolean;
|
|
36
|
+
}): Promise<LibraryEjectResult>;
|
|
37
|
+
export interface LibraryStaleness {
|
|
38
|
+
library: string;
|
|
39
|
+
/** Files in this project carrying the eject marker for this library. */
|
|
40
|
+
files: string[];
|
|
41
|
+
verdict: "identical" | "differs" | "unreadable";
|
|
42
|
+
/** Nodes present in both whose own-mode serialization differs. */
|
|
43
|
+
changed: number;
|
|
44
|
+
/** Nodes the SHIPPED tree has that the ejected copy does not — upstream moved. */
|
|
45
|
+
upstreamOnly: number;
|
|
46
|
+
/** Nodes the ejected copy has that the shipped tree does not — your additions. */
|
|
47
|
+
localOnly: number;
|
|
48
|
+
/** Why the comparison could not be made, when `verdict` is "unreadable". */
|
|
49
|
+
reason?: string;
|
|
50
|
+
/** Still named in `libraries` — the ejection is not finished. */
|
|
51
|
+
stillOptedIn: boolean;
|
|
52
|
+
}
|
|
53
|
+
/** Root-level nodes keyed by their package path RELATIVE to the library's own root
|
|
54
|
+
* package, canonically serialized in OWN mode.
|
|
55
|
+
*
|
|
56
|
+
* Relative rather than by resolution key, because §3.4 says an adopter who ejects "may
|
|
57
|
+
* rename the package freely" — keying on the FQN would report every node of a renamed
|
|
58
|
+
* copy as both upstream-only and local-only, which is the least useful answer
|
|
59
|
+
* available. Relative rather than by BARE NAME, because a library free to use two
|
|
60
|
+
* packages is free to declare `User` in both, and one key for two declarations means
|
|
61
|
+
* the one serialized last silently wins: a real divergence in the other is reported as
|
|
62
|
+
* `identical`. The relative path is what survives the rename — moving the root leaves
|
|
63
|
+
* every suffix below it exactly where it was — so it distinguishes without giving that
|
|
64
|
+
* edit anything to catch on. A single-package library yields the bare names it always
|
|
65
|
+
* did. Own mode, because the question is what each file DECLARES; the effective tree
|
|
66
|
+
* would fold a shipped base's fields into a subtype and report a difference that is not
|
|
67
|
+
* in either file. */
|
|
68
|
+
export declare function ownNodesByName(root: MetaData): Map<string, string>;
|
|
69
|
+
/**
|
|
70
|
+
* Per-library staleness for the copies THIS project owns.
|
|
71
|
+
*
|
|
72
|
+
* The same gap `--list` closes for generators, one level up: an ejected copy can sit any
|
|
73
|
+
* number of releases behind the tree it came from and nothing compares the two. The
|
|
74
|
+
* comparison is structural, through the canonical serializer, so re-indentation and key
|
|
75
|
+
* order never show up — the only thing that can be reported is a declaration that
|
|
76
|
+
* actually changed.
|
|
77
|
+
*/
|
|
78
|
+
export declare function libraryStaleness(cwd: string): Promise<LibraryStaleness[]>;
|
|
79
|
+
//# sourceMappingURL=library-eject.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"library-eject.d.ts","sourceRoot":"","sources":["../../../src/lib/library-eject.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAyD,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAQhH,4EAA4E;AAC5E,eAAO,MAAM,YAAY,kBAAkB,CAAC;AAE5C,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,0CAA0C;AAC1C,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEpE;AAkBD,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;CAC9C;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,mFAAmF;IACnF,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAUD,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAqC9B;AAMD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,WAAW,GAAG,SAAS,GAAG,YAAY,CAAC;IAChD,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,YAAY,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,YAAY,EAAE,OAAO,CAAC;CACvB;AAkBD;;;;;;;;;;;;;;sBAcsB;AACtB,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAuBlE;AAoBD;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAuD/E"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
// `meta eject <library>` — FR-043 §3.4, the copy door for a shipped library's METADATA.
|
|
2
|
+
//
|
|
3
|
+
// ADR-0034 ruled that a reference GENERATOR is copied into the adopter's repo because
|
|
4
|
+
// the adopter owns their code. §3.4 extends the same ruling to declared design, and
|
|
5
|
+
// makes it the EXPECTED mode rather than the fallback: a library is first a reference —
|
|
6
|
+
// something to copy, rename, and cut down. Using one in place, tracking upstream, is the
|
|
7
|
+
// deliberate minority choice.
|
|
8
|
+
//
|
|
9
|
+
// Two things follow, and both are here rather than in the generator path:
|
|
10
|
+
//
|
|
11
|
+
// The destination is `Collection.sourceRoots[0]` — the project's first DECLARED
|
|
12
|
+
// source root, resolved through `resolveCollection()`. Never `metaobjects/`: that
|
|
13
|
+
// string is the default value of `sources` and nothing else (CLAUDE.md names the five
|
|
14
|
+
// sites allowed to spell it, and this is not one of them).
|
|
15
|
+
//
|
|
16
|
+
// Every file carries a provenance header. It is what makes the copy's origin legible
|
|
17
|
+
// a year later, what `--list` reads to report staleness against the shipped tree, and
|
|
18
|
+
// what carries the ONE instruction that makes the eject complete: remove the library
|
|
19
|
+
// from `libraries`, or both trees load and merge (ERR_LIBRARY_PACKAGE_COLLISION).
|
|
20
|
+
import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
21
|
+
import { basename, join } from "node:path";
|
|
22
|
+
import { MetaDataLoader, PACKAGE_SEPARATOR, canonicalSerialize } from "@metaobjectsdev/metadata";
|
|
23
|
+
import { libraryManifests, libraryRefSource, libraryRefs, librarySources, knownLibraryTokens, splitLayerToken, } from "@metaobjectsdev/metadata/library";
|
|
24
|
+
import { resolveCollection } from "@metaobjectsdev/sdk";
|
|
25
|
+
import { cliVersion } from "./version.js";
|
|
26
|
+
/** The first line of every ejected file — the marker `--list` scans for. */
|
|
27
|
+
export const EJECT_MARKER = "# meta-eject:";
|
|
28
|
+
/** True when `name` is a shipped library rather than a generator. */
|
|
29
|
+
export function isLibraryName(name) {
|
|
30
|
+
return name in libraryManifests();
|
|
31
|
+
}
|
|
32
|
+
/** Every shipped library name, sorted. */
|
|
33
|
+
export function ejectableLibraryNames() {
|
|
34
|
+
return Object.keys(libraryManifests()).sort();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Where an ejected ref lands: `meta.<library>.<file>.yaml`.
|
|
38
|
+
*
|
|
39
|
+
* Not the library's own basename. `model.yaml` / `db.yaml` / `requirements.yaml` are
|
|
40
|
+
* meaningful inside `library/iam/` and meaningless in a directory holding an
|
|
41
|
+
* application's whole model — and three libraries ejected into one root would collide
|
|
42
|
+
* outright. The `meta.<concept>.<...>` shape is the file-naming convention this project
|
|
43
|
+
* documents.
|
|
44
|
+
*/
|
|
45
|
+
export function ejectedFileName(library, ref) {
|
|
46
|
+
return `meta.${library}.${basename(ref)}.yaml`;
|
|
47
|
+
}
|
|
48
|
+
function header(library, ref) {
|
|
49
|
+
return [
|
|
50
|
+
`${EJECT_MARKER} library=${library} ref=${ref} cli=${cliVersion()}`,
|
|
51
|
+
`# Copied from the MetaObjects shipped library "${library}". YOU OWN THIS FILE: rename`,
|
|
52
|
+
`# the package, delete what you do not need, change anything. Nothing regenerates it,`,
|
|
53
|
+
`# and no gate compares it to the shipped tree except \`meta eject --list\`.`,
|
|
54
|
+
`#`,
|
|
55
|
+
`# ONE STEP REMAINS: remove "${library}" (and any "${library}/<layer>") from`,
|
|
56
|
+
`# \`libraries\` in .metaobjects/config.json. Left there, the shipped tree and this`,
|
|
57
|
+
`# copy BOTH load and merge — additions take effect and deletions do not, because the`,
|
|
58
|
+
`# library still declares what you removed. The loader refuses that outright`,
|
|
59
|
+
`# (ERR_LIBRARY_PACKAGE_COLLISION) rather than letting it run.`,
|
|
60
|
+
"",
|
|
61
|
+
].join("\n");
|
|
62
|
+
}
|
|
63
|
+
async function fileExists(p) {
|
|
64
|
+
try {
|
|
65
|
+
return (await stat(p)).isFile();
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export async function ejectLibrary(opts) {
|
|
72
|
+
const manifest = libraryManifests()[opts.name];
|
|
73
|
+
if (manifest === undefined) {
|
|
74
|
+
throw new Error(`unknown library "${opts.name}". Shipped libraries: ${ejectableLibraryNames().join(", ")}.`);
|
|
75
|
+
}
|
|
76
|
+
const collection = await resolveCollection(opts.cwd);
|
|
77
|
+
const root = collection.sourceRoots[0];
|
|
78
|
+
if (root === undefined) {
|
|
79
|
+
throw new Error(`this project declares no metadata source root, so there is nowhere to put ` +
|
|
80
|
+
`"${opts.name}". Declare "sources" in .metaobjects/config.json, or run 'meta init'.`);
|
|
81
|
+
}
|
|
82
|
+
await mkdir(root, { recursive: true });
|
|
83
|
+
const files = [];
|
|
84
|
+
for (const ref of libraryRefs(opts.name)) {
|
|
85
|
+
const text = header(opts.name, ref) + (await libraryRefSource(ref).read());
|
|
86
|
+
const name = ejectedFileName(opts.name, ref);
|
|
87
|
+
const abs = join(root, name);
|
|
88
|
+
const existed = await fileExists(abs);
|
|
89
|
+
if (existed && opts.force !== true) {
|
|
90
|
+
files.push({ ref, path: name, status: "preserved" });
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
await writeFile(abs, text, "utf8");
|
|
94
|
+
files.push({ ref, path: name, status: existed ? "replaced" : "created" });
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
library: opts.name,
|
|
98
|
+
root,
|
|
99
|
+
files,
|
|
100
|
+
stillOptedIn: collection.libraries.filter((t) => splitLayerToken(t)[0] === opts.name),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/** The longest package prefix every node shares — the library's own root package.
|
|
104
|
+
*
|
|
105
|
+
* Segment-wise, never by string prefix: `acme::identity` and `acme::identityhub` share
|
|
106
|
+
* six characters and no package at all. */
|
|
107
|
+
function commonPackagePrefix(packages) {
|
|
108
|
+
if (packages.length === 0)
|
|
109
|
+
return "";
|
|
110
|
+
let common = packages[0].split(PACKAGE_SEPARATOR);
|
|
111
|
+
for (const pkg of packages.slice(1)) {
|
|
112
|
+
const segments = pkg.split(PACKAGE_SEPARATOR);
|
|
113
|
+
let i = 0;
|
|
114
|
+
while (i < common.length && i < segments.length && common[i] === segments[i])
|
|
115
|
+
i++;
|
|
116
|
+
common = common.slice(0, i);
|
|
117
|
+
}
|
|
118
|
+
return common.join(PACKAGE_SEPARATOR);
|
|
119
|
+
}
|
|
120
|
+
/** Root-level nodes keyed by their package path RELATIVE to the library's own root
|
|
121
|
+
* package, canonically serialized in OWN mode.
|
|
122
|
+
*
|
|
123
|
+
* Relative rather than by resolution key, because §3.4 says an adopter who ejects "may
|
|
124
|
+
* rename the package freely" — keying on the FQN would report every node of a renamed
|
|
125
|
+
* copy as both upstream-only and local-only, which is the least useful answer
|
|
126
|
+
* available. Relative rather than by BARE NAME, because a library free to use two
|
|
127
|
+
* packages is free to declare `User` in both, and one key for two declarations means
|
|
128
|
+
* the one serialized last silently wins: a real divergence in the other is reported as
|
|
129
|
+
* `identical`. The relative path is what survives the rename — moving the root leaves
|
|
130
|
+
* every suffix below it exactly where it was — so it distinguishes without giving that
|
|
131
|
+
* edit anything to catch on. A single-package library yields the bare names it always
|
|
132
|
+
* did. Own mode, because the question is what each file DECLARES; the effective tree
|
|
133
|
+
* would fold a shipped base's fields into a subtype and report a difference that is not
|
|
134
|
+
* in either file. */
|
|
135
|
+
export function ownNodesByName(root) {
|
|
136
|
+
const nodes = [...root.children()];
|
|
137
|
+
const packageOf = (node) => node.package ?? node.fileDefaultPackage ?? "";
|
|
138
|
+
// The ROOT package, neutralized in every node's serialization — for the same reason
|
|
139
|
+
// the keying is relative to it. A rename reaches the `package` key AND every `extends`
|
|
140
|
+
// inside the node, so comparing the raw text would report a renamed copy as wholly
|
|
141
|
+
// changed: the loudest possible answer to the one edit §3.4 explicitly invites. The
|
|
142
|
+
// root rather than each node's own package, so that a deeper node's reference back up
|
|
143
|
+
// to the root package is neutralized in it too.
|
|
144
|
+
const rootPackage = commonPackagePrefix(nodes.map(packageOf));
|
|
145
|
+
const out = new Map();
|
|
146
|
+
for (const node of nodes) {
|
|
147
|
+
const pkg = packageOf(node);
|
|
148
|
+
const suffix = rootPackage === "" ? pkg
|
|
149
|
+
: pkg === rootPackage ? ""
|
|
150
|
+
: pkg.slice(rootPackage.length + PACKAGE_SEPARATOR.length);
|
|
151
|
+
const key = suffix === "" ? node.name : `${suffix}${PACKAGE_SEPARATOR}${node.name}`;
|
|
152
|
+
const text = canonicalSerialize(node);
|
|
153
|
+
out.set(key, rootPackage === "" ? text : text.replaceAll(rootPackage, "<package>"));
|
|
154
|
+
}
|
|
155
|
+
return out;
|
|
156
|
+
}
|
|
157
|
+
/** Every project file carrying an eject marker, grouped by library. */
|
|
158
|
+
async function ejectedFilesByLibrary(files) {
|
|
159
|
+
const out = new Map();
|
|
160
|
+
for (const file of files) {
|
|
161
|
+
let head;
|
|
162
|
+
try {
|
|
163
|
+
head = (await readFile(file, "utf8")).slice(0, 400);
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const match = new RegExp(`^${EJECT_MARKER} library=(\\S+)`, "m").exec(head);
|
|
169
|
+
const library = match?.[1];
|
|
170
|
+
if (library === undefined)
|
|
171
|
+
continue;
|
|
172
|
+
out.set(library, [...(out.get(library) ?? []), file]);
|
|
173
|
+
}
|
|
174
|
+
return out;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Per-library staleness for the copies THIS project owns.
|
|
178
|
+
*
|
|
179
|
+
* The same gap `--list` closes for generators, one level up: an ejected copy can sit any
|
|
180
|
+
* number of releases behind the tree it came from and nothing compares the two. The
|
|
181
|
+
* comparison is structural, through the canonical serializer, so re-indentation and key
|
|
182
|
+
* order never show up — the only thing that can be reported is a declaration that
|
|
183
|
+
* actually changed.
|
|
184
|
+
*/
|
|
185
|
+
export async function libraryStaleness(cwd) {
|
|
186
|
+
let collection;
|
|
187
|
+
try {
|
|
188
|
+
collection = await resolveCollection(cwd);
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
return []; // no project — nothing is ejected here
|
|
192
|
+
}
|
|
193
|
+
const byLibrary = await ejectedFilesByLibrary(collection.ownFiles);
|
|
194
|
+
const selected = new Set(collection.libraries.map((t) => splitLayerToken(t)[0]));
|
|
195
|
+
const rows = [];
|
|
196
|
+
for (const [library, files] of [...byLibrary].sort(([a], [b]) => a.localeCompare(b))) {
|
|
197
|
+
const row = {
|
|
198
|
+
library,
|
|
199
|
+
files: files.map((f) => f.slice(cwd.length + 1)),
|
|
200
|
+
verdict: "identical",
|
|
201
|
+
changed: 0,
|
|
202
|
+
upstreamOnly: 0,
|
|
203
|
+
localOnly: 0,
|
|
204
|
+
stillOptedIn: selected.has(library),
|
|
205
|
+
};
|
|
206
|
+
if (!(library in libraryManifests())) {
|
|
207
|
+
rows.push({ ...row, verdict: "unreadable", reason: `this build ships no library "${library}"` });
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
// Both trees WHOLE, never file by file: a db layer is nothing but `overlay: true`
|
|
211
|
+
// redeclarations, so loading one alone is ERR_OVERLAY_NO_TARGET by construction.
|
|
212
|
+
const tokens = knownLibraryTokens().filter((t) => splitLayerToken(t)[0] === library);
|
|
213
|
+
const shipped = await new MetaDataLoader({ strict: true }).load(librarySources(tokens));
|
|
214
|
+
const { FileSource } = await import("@metaobjectsdev/metadata/core");
|
|
215
|
+
const local = await new MetaDataLoader({ strict: true }).load(files.map((f) => new FileSource(f)));
|
|
216
|
+
if (local.errors.length > 0) {
|
|
217
|
+
rows.push({
|
|
218
|
+
...row,
|
|
219
|
+
verdict: "unreadable",
|
|
220
|
+
reason: `the ejected copy does not load on its own: ${local.errors[0].message}`,
|
|
221
|
+
});
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
const up = ownNodesByName(shipped.root);
|
|
225
|
+
const mine = ownNodesByName(local.root);
|
|
226
|
+
for (const [name, text] of up) {
|
|
227
|
+
if (!mine.has(name))
|
|
228
|
+
row.upstreamOnly++;
|
|
229
|
+
else if (mine.get(name) !== text)
|
|
230
|
+
row.changed++;
|
|
231
|
+
}
|
|
232
|
+
for (const name of mine.keys())
|
|
233
|
+
if (!up.has(name))
|
|
234
|
+
row.localOnly++;
|
|
235
|
+
row.verdict =
|
|
236
|
+
row.changed + row.upstreamOnly + row.localOnly === 0 ? "identical" : "differs";
|
|
237
|
+
rows.push(row);
|
|
238
|
+
}
|
|
239
|
+
return rows;
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=library-eject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"library-eject.js","sourceRoot":"","sources":["../../../src/lib/library-eject.ts"],"names":[],"mappings":"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"}
|