@metaobjectsdev/cli 1.0.3 → 1.0.4-rc.1
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
|
@@ -249,11 +249,10 @@ function rewriteImportSpecifiers(source: string, aliasMap: Record<string, string
|
|
|
249
249
|
* than set to `undefined`, which is what lets `loadMemory` apply its own defaults.
|
|
250
250
|
*/
|
|
251
251
|
export function loadMemoryOptionsFrom(
|
|
252
|
-
cfg: Pick<MetaobjectsGenConfig, "providers"
|
|
253
|
-
): { providers?: readonly MetaDataTypeProvider[]
|
|
252
|
+
cfg: Pick<MetaobjectsGenConfig, "providers"> | undefined,
|
|
253
|
+
): { providers?: readonly MetaDataTypeProvider[] } {
|
|
254
254
|
return {
|
|
255
255
|
...(cfg?.providers !== undefined ? { providers: cfg.providers } : {}),
|
|
256
|
-
...(cfg?.libraries !== undefined ? { libraries: cfg.libraries } : {}),
|
|
257
256
|
};
|
|
258
257
|
}
|
|
259
258
|
|
|
@@ -518,24 +517,19 @@ export async function loadMetaobjectsConfig(projectRoot: string): Promise<Metaob
|
|
|
518
517
|
if (!cfg || typeof cfg !== "object" || !Array.isArray(cfg.generators)) {
|
|
519
518
|
throw new Error(`metaobjects.config.ts at ${fullPath} did not export a valid MetaobjectsGenConfig (missing 'generators' array).`);
|
|
520
519
|
}
|
|
521
|
-
//
|
|
522
|
-
//
|
|
523
|
-
//
|
|
524
|
-
//
|
|
525
|
-
// into
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
throw new Error(
|
|
535
|
-
`metaobjects.config.ts at ${fullPath}: 'libraries' names unknown package(s) ` +
|
|
536
|
-
`${JSON.stringify(unknown)}; available: ${JSON.stringify(available)}.`,
|
|
537
|
-
);
|
|
538
|
-
}
|
|
520
|
+
// `libraries` used to be validated here. It moved to `.metaobjects/config.json`
|
|
521
|
+
// (FR-043 Amendment 1), and so did its validation — see `assertKnownLibraries`,
|
|
522
|
+
// called from `resolveCollection`'s readers. A config still carrying the old key
|
|
523
|
+
// gets a pointed error rather than silence, because silence is what turns a moved
|
|
524
|
+
// key into "my library stopped loading and nothing said why".
|
|
525
|
+
if ("libraries" in (cfg as unknown as Record<string, unknown>)) {
|
|
526
|
+
throw new Error(
|
|
527
|
+
`metaobjects.config.ts at ${fullPath}: 'libraries' moved to ` +
|
|
528
|
+
`.metaobjects/config.json (FR-043). Which designs a project adopts is a fact ` +
|
|
529
|
+
`about the PROJECT, not about how one port generates code from it, and that ` +
|
|
530
|
+
`file is the port-neutral one every port already reads. Move the array across ` +
|
|
531
|
+
`verbatim — the tokens are unchanged.`,
|
|
532
|
+
);
|
|
539
533
|
}
|
|
540
534
|
return cfg;
|
|
541
535
|
} finally {
|
|
@@ -42,6 +42,10 @@ import {
|
|
|
42
42
|
type MetaRequirement,
|
|
43
43
|
type RequirementStatus,
|
|
44
44
|
} from "@metaobjectsdev/metadata";
|
|
45
|
+
// FR-043 §5.4 — the provenance key for coverage activation. A node-only subpath, which
|
|
46
|
+
// is why it is a second import rather than a name on the barrel above: the library
|
|
47
|
+
// module reaches the filesystem and the root barrel stays browser-safe.
|
|
48
|
+
import { libraryPackages } from "@metaobjectsdev/metadata/library";
|
|
45
49
|
|
|
46
50
|
export type Severity = "error" | "warn";
|
|
47
51
|
|
|
@@ -82,8 +86,11 @@ export interface RequirementSummary {
|
|
|
82
86
|
undecided: number;
|
|
83
87
|
/** deferred entries naming no ticket, so nobody will be reminded. */
|
|
84
88
|
deferredUntracked: number;
|
|
85
|
-
|
|
86
|
-
|
|
89
|
+
/** ABSENT when coverage was not measured — FR-043 §5.4. A number here is a
|
|
90
|
+
* ratio the project is held to; absence is the honest reading of "this project
|
|
91
|
+
* has authored no requirement of its own, so it asked to be held to none". */
|
|
92
|
+
entitiesTotal?: number;
|
|
93
|
+
entitiesClaimed?: number;
|
|
87
94
|
}
|
|
88
95
|
|
|
89
96
|
/** Severity of the object-coverage gate. Promotion to `"error"` is a one-line
|
|
@@ -255,16 +262,61 @@ export interface RequirementScan {
|
|
|
255
262
|
* Threaded through so BOTH `coverableEntities` call sites (the gate and the
|
|
256
263
|
* summary) inherit the same narrowing — see `coverableEntities`. */
|
|
257
264
|
readonly coverable?: (fqn: string) => boolean;
|
|
265
|
+
/** FR-043 §5.4 — whether object coverage applies at all on this run. See
|
|
266
|
+
* {@link projectAuthoredRequirements}. Read by BOTH the gate and the summary from
|
|
267
|
+
* this one scan, for the same reason `claimedObjects` is shared: a summary that
|
|
268
|
+
* printed a ratio the gate had not enforced would be a measurement nobody could
|
|
269
|
+
* reconcile with the diagnostics beneath it. */
|
|
270
|
+
readonly measureCoverage: boolean;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Did the ADOPTER author any of these requirements?
|
|
275
|
+
*
|
|
276
|
+
* FR-043 §5.4, and the rule exists because `checkRequirements` activates object
|
|
277
|
+
* coverage on the presence of any requirement at all. A library ships its own ledger
|
|
278
|
+
* — `iam` ships eleven entries — so without this, opting into a library would switch
|
|
279
|
+
* the unclaimed-entity gate on across a project that has never written a requirement,
|
|
280
|
+
* and report every entity in it. The gate would then be measuring the LIBRARY's
|
|
281
|
+
* decision to ship a ledger rather than anything the adopter did.
|
|
282
|
+
*
|
|
283
|
+
* Provenance is the library's declared PACKAGE. That is a manifest fact the standalone
|
|
284
|
+
* library gate resolves against the library loaded alone, whereas a node's source id
|
|
285
|
+
* differs between the on-disk dev layout (an absolute path) and the embedded one
|
|
286
|
+
* (`library:<ref>.yaml`) — a rule keyed on source would hold in this repo and stop
|
|
287
|
+
* holding in an installed build.
|
|
288
|
+
*
|
|
289
|
+
* An adopter OVERLAYING a library requirement (§5.5) is deliberately not authoring one:
|
|
290
|
+
* the overlay merges into the library's node, in the library's package, and disagreeing
|
|
291
|
+
* with a shipped verdict is a statement about the library's design rather than about
|
|
292
|
+
* what the adopter's own model is for. Treating it as activation would mean correcting
|
|
293
|
+
* one library entry silently acquired a coverage gate over the whole estate.
|
|
294
|
+
*/
|
|
295
|
+
function projectAuthoredRequirements(addressed: readonly AddressedRequirement[]): boolean {
|
|
296
|
+
const libPkgs = libraryPackages();
|
|
297
|
+
return addressed.some((r) => {
|
|
298
|
+
const pkg = r.node.package ?? r.node.fileDefaultPackage ?? "";
|
|
299
|
+
return !libPkgs.has(pkg);
|
|
300
|
+
});
|
|
258
301
|
}
|
|
259
302
|
|
|
260
303
|
export function scanRequirements(
|
|
261
304
|
root: MetaData,
|
|
262
|
-
opts?: {
|
|
305
|
+
opts?: {
|
|
306
|
+
coverable?: (fqn: string) => boolean;
|
|
307
|
+
/** Force coverage on or off instead of deriving it. The one caller that legitimately
|
|
308
|
+
* knows better is the gate over a SHIPPED library loaded standalone: there the
|
|
309
|
+
* library IS the project under test, and "every entity this library ships is claimed
|
|
310
|
+
* by its own ledger" is exactly what is being asserted — so the derivation would
|
|
311
|
+
* switch the check off precisely where it is the point. */
|
|
312
|
+
measureCoverage?: boolean;
|
|
313
|
+
},
|
|
263
314
|
): RequirementScan {
|
|
264
315
|
const addressed = collectAddressedRequirements(root);
|
|
265
316
|
return {
|
|
266
317
|
addressed,
|
|
267
318
|
claimedObjects: claimedObjectKeys(root, addressed.map((r) => r.node)),
|
|
319
|
+
measureCoverage: opts?.measureCoverage ?? projectAuthoredRequirements(addressed),
|
|
268
320
|
// `exactOptionalPropertyTypes` — an omitted key, never an explicit `undefined`.
|
|
269
321
|
...(opts?.coverable !== undefined ? { coverable: opts.coverable } : {}),
|
|
270
322
|
};
|
|
@@ -350,7 +402,7 @@ function coverableEntities(root: MetaData, coverable?: (fqn: string) => boolean)
|
|
|
350
402
|
*/
|
|
351
403
|
export function checkRequirements(root: MetaData, scan: RequirementScan = scanRequirements(root)): Diagnostic[] {
|
|
352
404
|
const out: Diagnostic[] = [];
|
|
353
|
-
const { addressed, claimedObjects, coverable } = scan;
|
|
405
|
+
const { addressed, claimedObjects, coverable, measureCoverage } = scan;
|
|
354
406
|
if (addressed.length === 0) return out; // opt-in by declaration — no requirements, nothing to say
|
|
355
407
|
|
|
356
408
|
for (const { node: req, path: reqPath } of addressed) {
|
|
@@ -564,7 +616,9 @@ export function checkRequirements(root: MetaData, scan: RequirementScan = scanRe
|
|
|
564
616
|
//
|
|
565
617
|
// So a green run means "every entity is claimed by something", not "every node is
|
|
566
618
|
// described". The stronger reading would be false.
|
|
567
|
-
|
|
619
|
+
// ADOPTER-AUTHORED ONLY. FR-043 §5.4 — see `projectAuthoredRequirements`. A library's
|
|
620
|
+
// ledger is counted and checked, but it cannot volunteer you for coverage.
|
|
621
|
+
for (const ent of measureCoverage ? coverableEntities(root, coverable) : []) {
|
|
568
622
|
const key = ent.resolutionKey();
|
|
569
623
|
if (!claimedObjects.has(key)) {
|
|
570
624
|
out.push({
|
|
@@ -601,8 +655,8 @@ export function summariseRequirements(
|
|
|
601
655
|
byStatus: {},
|
|
602
656
|
undecided: 0,
|
|
603
657
|
deferredUntracked: 0,
|
|
604
|
-
|
|
605
|
-
|
|
658
|
+
// The coverage pair is filled in below only when the run measures coverage —
|
|
659
|
+
// `exactOptionalPropertyTypes`, so the keys are absent rather than undefined.
|
|
606
660
|
};
|
|
607
661
|
|
|
608
662
|
for (const req of reqs) {
|
|
@@ -621,10 +675,16 @@ export function summariseRequirements(
|
|
|
621
675
|
// Both sides of the ratio come from the SAME scan the gate read, so the printed
|
|
622
676
|
// summary cannot disagree with the diagnostics printed beneath it — previously
|
|
623
677
|
// the same helper, now literally the same result.
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
678
|
+
if (scan.measureCoverage) {
|
|
679
|
+
const claimed = scan.claimedObjects;
|
|
680
|
+
let total = 0;
|
|
681
|
+
let claimedCount = 0;
|
|
682
|
+
for (const ent of coverableEntities(root, scan.coverable)) {
|
|
683
|
+
total++;
|
|
684
|
+
if (claimed.has(ent.resolutionKey())) claimedCount++;
|
|
685
|
+
}
|
|
686
|
+
summary.entitiesTotal = total;
|
|
687
|
+
summary.entitiesClaimed = claimedCount;
|
|
628
688
|
}
|
|
629
689
|
|
|
630
690
|
return summary;
|