@metaobjectsdev/sdk 0.23.2 → 0.24.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.
Files changed (75) hide show
  1. package/agent-context/skills/metaobjects-audit/SKILL.md +20 -7
  2. package/agent-context/skills/metaobjects-audit/references/capability-checklist.md +65 -19
  3. package/agent-context/skills/metaobjects-audit/references/csharp.md +2 -1
  4. package/agent-context/skills/metaobjects-audit/references/java.md +3 -2
  5. package/agent-context/skills/metaobjects-audit/references/kotlin.md +2 -1
  6. package/agent-context/skills/metaobjects-audit/references/requirements.md +3 -4
  7. package/agent-context/skills/metaobjects-audit/references/typescript.md +1 -1
  8. package/agent-context/skills/metaobjects-authoring/SKILL.md +53 -10
  9. package/agent-context/skills/metaobjects-authoring/references/requirements.md +49 -23
  10. package/agent-context/skills/metaobjects-codegen/SKILL.md +4 -3
  11. package/agent-context/skills/metaobjects-codegen/references/csharp.md +12 -2
  12. package/agent-context/skills/metaobjects-codegen/references/java.md +3 -3
  13. package/agent-context/skills/metaobjects-codegen/references/kotlin.md +4 -4
  14. package/agent-context/skills/metaobjects-codegen/references/python.md +12 -2
  15. package/agent-context/skills/metaobjects-codegen/references/typescript.md +14 -3
  16. package/agent-context/skills/metaobjects-fit-assessment/SKILL.md +4 -4
  17. package/agent-context/skills/metaobjects-prompts/SKILL.md +53 -32
  18. package/agent-context/skills/metaobjects-prompts/references/csharp.md +26 -21
  19. package/agent-context/skills/metaobjects-prompts/references/java.md +24 -18
  20. package/agent-context/skills/metaobjects-prompts/references/kotlin.md +25 -20
  21. package/agent-context/skills/metaobjects-prompts/references/python.md +68 -26
  22. package/agent-context/skills/metaobjects-prompts/references/typescript.md +29 -23
  23. package/agent-context/skills/metaobjects-verify/references/migration.md +1 -1
  24. package/agent-context/skills/metaobjects-verify/references/requirements.md +36 -22
  25. package/agent-context/templates/always-on.md.mustache +3 -1
  26. package/dist/agent-docs/body.d.ts +1 -1
  27. package/dist/agent-docs/body.d.ts.map +1 -1
  28. package/dist/agent-docs/body.js +24 -2
  29. package/dist/agent-docs/body.js.map +1 -1
  30. package/dist/collection.d.ts +71 -0
  31. package/dist/collection.d.ts.map +1 -0
  32. package/dist/collection.js +203 -0
  33. package/dist/collection.js.map +1 -0
  34. package/dist/config.d.ts +51 -21
  35. package/dist/config.d.ts.map +1 -1
  36. package/dist/config.js +76 -10
  37. package/dist/config.js.map +1 -1
  38. package/dist/discovery.d.ts +43 -0
  39. package/dist/discovery.d.ts.map +1 -0
  40. package/dist/discovery.js +100 -0
  41. package/dist/discovery.js.map +1 -0
  42. package/dist/index.d.ts +10 -1
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +17 -4
  45. package/dist/index.js.map +1 -1
  46. package/dist/memory.d.ts +42 -19
  47. package/dist/memory.d.ts.map +1 -1
  48. package/dist/memory.js +38 -95
  49. package/dist/memory.js.map +1 -1
  50. package/dist/metadata-files.d.ts +67 -0
  51. package/dist/metadata-files.d.ts.map +1 -0
  52. package/dist/metadata-files.js +155 -0
  53. package/dist/metadata-files.js.map +1 -0
  54. package/dist/records/any.d.ts +8 -8
  55. package/dist/records/decision.d.ts +2 -2
  56. package/dist/records/glossary.d.ts +4 -4
  57. package/dist/records/principle.d.ts +2 -2
  58. package/dist/scope.d.ts +16 -0
  59. package/dist/scope.d.ts.map +1 -0
  60. package/dist/scope.js +75 -0
  61. package/dist/scope.js.map +1 -0
  62. package/dist/sources.d.ts +86 -0
  63. package/dist/sources.d.ts.map +1 -0
  64. package/dist/sources.js +130 -0
  65. package/dist/sources.js.map +1 -0
  66. package/package.json +2 -2
  67. package/src/agent-docs/body.ts +24 -2
  68. package/src/collection.ts +268 -0
  69. package/src/config.ts +80 -12
  70. package/src/discovery.ts +110 -0
  71. package/src/index.ts +26 -9
  72. package/src/memory.ts +65 -99
  73. package/src/metadata-files.ts +158 -0
  74. package/src/scope.ts +95 -0
  75. package/src/sources.ts +160 -0
@@ -0,0 +1,71 @@
1
+ import { type ResolvedSource } from "./sources.js";
2
+ export interface Collection {
3
+ /** Directory whose config declared this collection (or the resolved start
4
+ * directory, when nothing was discovered and the default applies). */
5
+ readonly configDir: string;
6
+ /** Canonically-ordered absolute metadata file paths — see `resolveSources`.
7
+ * Canonical, not sorted: within a directory source the walk order the
8
+ * toolchain has always used is preserved, because it survives into
9
+ * generated output. */
10
+ readonly files: readonly string[];
11
+ /** Same set, carrying the contributing spec for provenance. */
12
+ readonly sources: readonly ResolvedSource[];
13
+ /** The distinct roots the declared source specs resolve to, absolute, in the
14
+ * same canonical (content) order `files` uses. Derived from the DECLARED
15
+ * specs, not from the resolved files, so a source directory that legitimately
16
+ * holds no metadata still appears — a consumer listing "where this model
17
+ * comes from" (`meta docs --site` groups its pages by source root) must not
18
+ * silently lose a declared source because it happens to be empty today. */
19
+ readonly sourceRoots: readonly string[];
20
+ /**
21
+ * Output filter for codegen: does this fully-qualified name survive the
22
+ * collection's `scope`? Always defined — an unconfigured project compiles to
23
+ * an empty include/exclude, which admits everything, so callers pass this
24
+ * through unconditionally rather than branching.
25
+ *
26
+ * A PREDICATE rather than the `CompiledScope` it closes over, because nothing
27
+ * consumes a compiled scope as a compiled scope: every consumer immediately
28
+ * wrapped it in exactly this lambda, and `migrateScopePatterns` exists
29
+ * precisely because the compiled form cannot be shown to a human.
30
+ * `compileScope`/`matchesScope` stay exported for the conformance corpus.
31
+ */
32
+ readonly inScope: (fqn: string) => boolean;
33
+ /** Output filter for migrate/verify --db (`migrate.scope`). Undefined => the
34
+ * command governs everything loaded, and that undefined is load-bearing: it
35
+ * is what leaves the expected schema untouched (migrate-ts `scope.ts`). */
36
+ readonly inMigrateScope: ((fqn: string) => boolean) | undefined;
37
+ /** The patterns `inMigrateScope` was compiled FROM, for diagnostics only —
38
+ * `compileScope` produces RegExps, and a regex source is not something to
39
+ * show an author who wrote `acme::platform::**`. Carried so the "your scope
40
+ * matched nothing" refusal can name the patterns that missed. Always in
41
+ * lockstep with `inMigrateScope`: both undefined, or both present. */
42
+ readonly migrateScopePatterns: readonly string[] | undefined;
43
+ }
44
+ /**
45
+ * THE single authority on where metadata lives. Every read path routes
46
+ * through this — `metaobjects/` is the DEFAULT value of `sources`, never an
47
+ * assumption baked into a call site.
48
+ *
49
+ * Resolution order: an explicit `opts.explicitDir` wins outright; otherwise
50
+ * `discoverCollectionRoot` walks up from `startDir` for the nearest directory
51
+ * carrying `.metaobjects/config.json` — the ONLY project marker (`discovery.ts`
52
+ * says why a directory that merely holds metadata is not one) — falling back to
53
+ * `startDir` itself when none is found. When the resolved directory carries a
54
+ * config, its declared `sources`/`scope`/`migrate.scope` govern. Only a
55
+ * genuinely ABSENT `config.json` falls through to `DEFAULT_SOURCES` — the same
56
+ * directory the pre-source-resolution toolchain always read; a config.json
57
+ * that EXISTS but fails to load (malformed JSON, schema violation) is the
58
+ * author's error and propagates rather than silently degrading — a source
59
+ * that fails to resolve must never look like one that was never declared.
60
+ * Throws `ERR_COLLECTION_NOT_FOUND` only when BOTH have failed: no
61
+ * `sources` were declared AND the default source directory does not exist
62
+ * either.
63
+ *
64
+ * A declared source that fails to resolve is a different, louder failure —
65
+ * `resolveSources` throws `ERR_SOURCE_UNRESOLVED` for that case; only the
66
+ * DEFAULT is allowed to be silently absent.
67
+ */
68
+ export declare function resolveCollection(startDir: string, opts?: {
69
+ explicitDir?: string;
70
+ }): Promise<Collection>;
71
+ //# sourceMappingURL=collection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAmBA,OAAO,EAKL,KAAK,cAAc,EAEpB,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,UAAU;IACzB;2EACuE;IACvE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;4BAGwB;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IAC5C;;;;;gFAK4E;IAC5E,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3C;;gFAE4E;IAC5E,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,SAAS,CAAC;IAChE;;;;2EAIuE;IACvE,QAAQ,CAAC,oBAAoB,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CAC9D;AA8ED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9B,OAAO,CAAC,UAAU,CAAC,CA6FrB"}
@@ -0,0 +1,203 @@
1
+ // server/typescript/packages/sdk/src/collection.ts
2
+ //
3
+ // Phase-1 metadata-source-resolution — the single authority.
4
+ //
5
+ // `resolveCollection()` composes discovery (`discovery.ts`), config
6
+ // (`config.ts`), source resolution (`sources.ts`) and the scope engine
7
+ // (`scope.ts`) into one function that decides where a project's metadata
8
+ // lives. `metaobjects/` is the DEFAULT value of `sources`, never a
9
+ // requirement — a project that declares nothing still resolves exactly as
10
+ // today (`DEFAULT_SOURCES` in `sources.ts`); a project that declares
11
+ // `sources` can point anywhere. No other call site may assume the directory
12
+ // name — this is where that assumption is allowed to live, exactly once.
13
+ import { dirname, extname, join, resolve } from "node:path";
14
+ import { readdir, readFile } from "node:fs/promises";
15
+ import { ParseError, codeSource, SUBTYPE_ROOT, TYPE_METADATA } from "@metaobjectsdev/metadata";
16
+ import { CONFIG_FILE, loadConfig } from "./config.js";
17
+ import { discoverCollectionRoot, exists, isDir } from "./discovery.js";
18
+ import { compileScope, matchesScope } from "./scope.js";
19
+ import { DEFAULT_METADATA_DIR, DEFAULT_METAOBJECTS_DIR, isMetadataFile } from "./metadata-files.js";
20
+ import { DEFAULT_SOURCES, orderedPathSpecs, resolveSpecPath, resolveSources, } from "./sources.js";
21
+ /** The canonical-JSON document root key (`metadata.root`) and the sigil-free
22
+ * YAML root mapping key (`metadata:`, at column 0 — ADR-0006), built from the
23
+ * metamodel constants rather than spelled out. */
24
+ const JSON_ROOT_KEY = `${TYPE_METADATA}.${SUBTYPE_ROOT}`;
25
+ const YAML_ROOT_KEY = new RegExp(`^${TYPE_METADATA}\\s*:`, "m");
26
+ /** Bound on the sniff below: one hit is enough to diagnose, and this runs only
27
+ * on a path that has already failed. */
28
+ const MAX_SNIFFED_FILES = 20;
29
+ /**
30
+ * Cheap "is this file a metadata DOCUMENT?" sniff — for a diagnostic, never for
31
+ * loading. It decides whether to change an error MESSAGE; nothing downstream
32
+ * reads its answer, and a false negative costs only the generic message.
33
+ *
34
+ * A file-EXTENSION test cannot answer this: `package.json` and `tsconfig.json`
35
+ * carry a recognized metadata extension ({@link isMetadataFile}), so every JS
36
+ * project root that has no metadata yet would be misdiagnosed as a metadata
37
+ * directory — a confidently wrong hint, which is worse than the generic one it
38
+ * would replace. The document root is `metadata.root` in canonical JSON and the
39
+ * sigil-free `metadata:` key in YAML authoring (ADR-0006), so those are what
40
+ * this looks for.
41
+ */
42
+ async function sniffsAsMetadataDocument(file) {
43
+ const text = await readFile(file, "utf8").catch(() => undefined);
44
+ if (text === undefined)
45
+ return false;
46
+ if (extname(file).toLowerCase() !== ".json") {
47
+ // YAML: the root mapping key, at column 0. Not a parse — this package has
48
+ // no YAML parser, and acquiring one to improve an error message would be a
49
+ // dependency bought with nothing.
50
+ return YAML_ROOT_KEY.test(text);
51
+ }
52
+ try {
53
+ const doc = JSON.parse(text);
54
+ return typeof doc === "object" && doc !== null && JSON_ROOT_KEY in doc;
55
+ }
56
+ catch {
57
+ return false;
58
+ }
59
+ }
60
+ /**
61
+ * Does `dir` hold metadata but carry no project marker — i.e. is it the
62
+ * METADATA directory, handed to a command whose directory argument is the
63
+ * PROJECT ROOT? (#344)
64
+ *
65
+ * That mistake is predictable rather than careless: the sibling `docs`
66
+ * positionals in the Python and C# ports ARE the metadata directory, and all
67
+ * three are spelled the same way. The generic diagnostic then advises declaring
68
+ * `sources`, which from inside the metadata directory is a dead end.
69
+ *
70
+ * Only the top level is scanned. A metadata directory has metadata files in it;
71
+ * recursing would walk `node_modules/` on the very input this must NOT
72
+ * misdiagnose.
73
+ */
74
+ async function holdsMetadataButIsNoRoot(dir, hasConfig) {
75
+ // A directory carrying the marker IS a project root, by the only definition
76
+ // of one there is (`discovery.ts`). Nothing to diagnose.
77
+ if (hasConfig)
78
+ return false;
79
+ const entries = await readdir(dir).catch(() => []);
80
+ for (const entry of entries.filter(isMetadataFile).slice(0, MAX_SNIFFED_FILES)) {
81
+ if (await sniffsAsMetadataDocument(join(dir, entry)))
82
+ return true;
83
+ }
84
+ return false;
85
+ }
86
+ /** Narrow the zod-inferred `Config["scope"]` (whose `.optional()` fields are
87
+ * typed `T | undefined` even when present) down to `Scope`'s
88
+ * exactOptionalPropertyTypes-safe shape — a key is omitted entirely rather
89
+ * than assigned `undefined`. */
90
+ function toScope(spec) {
91
+ return {
92
+ ...(spec?.include !== undefined && { include: spec.include }),
93
+ ...(spec?.exclude !== undefined && { exclude: spec.exclude }),
94
+ };
95
+ }
96
+ /**
97
+ * THE single authority on where metadata lives. Every read path routes
98
+ * through this — `metaobjects/` is the DEFAULT value of `sources`, never an
99
+ * assumption baked into a call site.
100
+ *
101
+ * Resolution order: an explicit `opts.explicitDir` wins outright; otherwise
102
+ * `discoverCollectionRoot` walks up from `startDir` for the nearest directory
103
+ * carrying `.metaobjects/config.json` — the ONLY project marker (`discovery.ts`
104
+ * says why a directory that merely holds metadata is not one) — falling back to
105
+ * `startDir` itself when none is found. When the resolved directory carries a
106
+ * config, its declared `sources`/`scope`/`migrate.scope` govern. Only a
107
+ * genuinely ABSENT `config.json` falls through to `DEFAULT_SOURCES` — the same
108
+ * directory the pre-source-resolution toolchain always read; a config.json
109
+ * that EXISTS but fails to load (malformed JSON, schema violation) is the
110
+ * author's error and propagates rather than silently degrading — a source
111
+ * that fails to resolve must never look like one that was never declared.
112
+ * Throws `ERR_COLLECTION_NOT_FOUND` only when BOTH have failed: no
113
+ * `sources` were declared AND the default source directory does not exist
114
+ * either.
115
+ *
116
+ * A declared source that fails to resolve is a different, louder failure —
117
+ * `resolveSources` throws `ERR_SOURCE_UNRESOLVED` for that case; only the
118
+ * DEFAULT is allowed to be silently absent.
119
+ */
120
+ export async function resolveCollection(startDir, opts) {
121
+ const explicit = opts?.explicitDir;
122
+ // Whether `configDir` carries a `config.json` — threaded through rather
123
+ // than re-`stat`'d below. On the non-explicit path, `discoverCollectionRoot`
124
+ // already proved it either way: it reports `hasConfig` from the same
125
+ // `.metaobjects/config.json` probe that decided where to stop, and reports
126
+ // false only after confirming that file is absent at every directory it
127
+ // examined, `resolve(startDir)` included. A second `stat` of the identical
128
+ // file would just re-prove what discovery established. The check is only
129
+ // load-bearing on the `explicitDir` path, where discovery never runs at all.
130
+ let configDir;
131
+ let hasConfig;
132
+ if (explicit !== undefined) {
133
+ configDir = resolve(explicit);
134
+ hasConfig = await exists(join(configDir, DEFAULT_METAOBJECTS_DIR, CONFIG_FILE));
135
+ }
136
+ else {
137
+ ({ dir: configDir, hasConfig } = await discoverCollectionRoot(startDir));
138
+ }
139
+ let specs = DEFAULT_SOURCES;
140
+ let scopeSpec;
141
+ let migrateSpec;
142
+ if (hasConfig) {
143
+ // No try/catch here: a config.json that EXISTS but fails to load
144
+ // (malformed JSON, a ConfigSchema violation) propagates. Swallowing it
145
+ // would make a typo'd config behave identically to no config at all —
146
+ // silently generating from a possibly-stale `metaobjects/` with no
147
+ // diagnostic, which is a worse failure than the one this design exists
148
+ // to remove.
149
+ const cfg = await loadConfig(join(configDir, DEFAULT_METAOBJECTS_DIR));
150
+ if (cfg.sources.length > 0)
151
+ specs = cfg.sources;
152
+ scopeSpec = cfg.scope;
153
+ migrateSpec = cfg.migrate?.scope;
154
+ }
155
+ // Only the DEFAULT is allowed to be absent — an explicitly declared source
156
+ // that does not resolve is `resolveSources`'s ERR_SOURCE_UNRESOLVED, not this.
157
+ //
158
+ // This re-`stat`s a directory the non-explicit discovery walk may already
159
+ // have probed, and that redundancy is intentional: it exists to produce the
160
+ // friendlier `ERR_COLLECTION_NOT_FOUND` diagnostic below rather than the raw
161
+ // `ERR_SOURCE_UNRESOLVED` `resolveSources` would throw on a genuinely missing
162
+ // default directory. Trading that clearer error for one syscall is a bad
163
+ // trade. It is also load-bearing outright on the `explicitDir` path and
164
+ // whenever a discovered config declares no `sources`, where nothing has
165
+ // probed it at all.
166
+ if (specs === DEFAULT_SOURCES && !(await isDir(join(configDir, DEFAULT_METADATA_DIR)))) {
167
+ // #344 — name the one wrong answer worth naming before falling back to the
168
+ // generic advice. Told "declare sources" while standing in the metadata
169
+ // directory, an author declares the metadata FILES, and the config schema
170
+ // then rejects a bare string (a `sources` entry is `{ "path": … }`) — two
171
+ // dead ends in a row for a caller whose only mistake was passing the
172
+ // directory the sibling ports' `docs` positional wants.
173
+ if (await holdsMetadataButIsNoRoot(configDir, hasConfig)) {
174
+ const parent = dirname(configDir);
175
+ const near = await discoverCollectionRoot(parent);
176
+ const suggested = near.hasConfig ? near.dir : parent;
177
+ throw new ParseError(`${configDir} looks like a metadata directory, not a project root — it holds metadata ` +
178
+ `files but carries no ${DEFAULT_METAOBJECTS_DIR}/${CONFIG_FILE}. A directory argument here is ` +
179
+ `the PROJECT ROOT that CONTAINS your metadata; where the metadata lives is then the root's ` +
180
+ `"sources" (default: the "${DEFAULT_METADATA_DIR}" directory beneath it). Try ${suggested} instead.`, { code: "ERR_COLLECTION_NOT_FOUND", source: codeSource("resolveCollection") });
181
+ }
182
+ throw new ParseError(`no metadata sources declared in ${configDir} and no default "${DEFAULT_METADATA_DIR}" directory found. ` +
183
+ `Declare "sources" in ${DEFAULT_METAOBJECTS_DIR}/${CONFIG_FILE} — each entry is an OBJECT, ` +
184
+ `e.g. "sources": [{ "path": "model" }] — or run 'meta init' to scaffold.`, { code: "ERR_COLLECTION_NOT_FOUND", source: codeSource("resolveCollection") });
185
+ }
186
+ const sources = await resolveSources(configDir, specs);
187
+ const scope = compileScope(toScope(scopeSpec));
188
+ const migrateScope = migrateSpec === undefined ? undefined : compileScope({ include: migrateSpec });
189
+ return {
190
+ configDir,
191
+ files: sources.map((s) => s.file),
192
+ sources,
193
+ // Canonical (content) order, from `resolveSources`'s own ordering — so this
194
+ // list is a pure function of the source SET, exactly like `files`.
195
+ sourceRoots: [
196
+ ...new Set(orderedPathSpecs(specs).map((spec) => resolveSpecPath(configDir, spec))),
197
+ ],
198
+ inScope: (fqn) => matchesScope(fqn, scope),
199
+ inMigrateScope: migrateScope === undefined ? undefined : (fqn) => matchesScope(fqn, migrateScope),
200
+ migrateScopePatterns: migrateSpec,
201
+ };
202
+ }
203
+ //# sourceMappingURL=collection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection.js","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,6DAA6D;AAC7D,EAAE;AACF,oEAAoE;AACpE,uEAAuE;AACvE,yEAAyE;AACzE,mEAAmE;AACnE,0EAA0E;AAC1E,qEAAqE;AACrE,4EAA4E;AAC5E,yEAAyE;AACzE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC/F,OAAO,EAAE,WAAW,EAAE,UAAU,EAAe,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAc,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACpG,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,cAAc,GAGf,MAAM,cAAc,CAAC;AA6CtB;;mDAEmD;AACnD,MAAM,aAAa,GAAG,GAAG,aAAa,IAAI,YAAY,EAAE,CAAC;AACzD,MAAM,aAAa,GAAG,IAAI,MAAM,CAAC,IAAI,aAAa,OAAO,EAAE,GAAG,CAAC,CAAC;AAEhE;yCACyC;AACzC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAE7B;;;;;;;;;;;;GAYG;AACH,KAAK,UAAU,wBAAwB,CAAC,IAAY;IAClD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACjE,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,OAAO,EAAE,CAAC;QAC5C,0EAA0E;QAC1E,2EAA2E;QAC3E,kCAAkC;QAClC,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtC,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,aAAa,IAAI,GAAG,CAAC;IACzE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,KAAK,UAAU,wBAAwB,CAAC,GAAW,EAAE,SAAkB;IACrE,4EAA4E;IAC5E,yDAAyD;IACzD,IAAI,SAAS;QAAE,OAAO,KAAK,CAAC;IAC5B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAc,CAAC,CAAC;IAC/D,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,EAAE,CAAC;QAC/E,IAAI,MAAM,wBAAwB,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;IACpE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;iCAGiC;AACjC,SAAS,OAAO,CAAC,IAAqB;IACpC,OAAO;QACL,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;QAC7D,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;KAC9D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,QAAgB,EAChB,IAA+B;IAE/B,MAAM,QAAQ,GAAG,IAAI,EAAE,WAAW,CAAC;IAEnC,wEAAwE;IACxE,6EAA6E;IAC7E,qEAAqE;IACrE,2EAA2E;IAC3E,wEAAwE;IACxE,2EAA2E;IAC3E,yEAAyE;IACzE,6EAA6E;IAC7E,IAAI,SAAiB,CAAC;IACtB,IAAI,SAAkB,CAAC;IACvB,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9B,SAAS,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,uBAAuB,EAAE,WAAW,CAAC,CAAC,CAAC;IAClF,CAAC;SAAM,CAAC;QACN,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,MAAM,sBAAsB,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,KAAK,GAA0B,eAAe,CAAC;IACnD,IAAI,SAA0B,CAAC;IAC/B,IAAI,WAAiC,CAAC;IAEtC,IAAI,SAAS,EAAE,CAAC;QACd,iEAAiE;QACjE,uEAAuE;QACvE,sEAAsE;QACtE,mEAAmE;QACnE,uEAAuE;QACvE,aAAa;QACb,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC,CAAC;QACvE,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC;QAChD,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC;QACtB,WAAW,GAAG,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC;IACnC,CAAC;IAED,2EAA2E;IAC3E,+EAA+E;IAC/E,EAAE;IACF,0EAA0E;IAC1E,4EAA4E;IAC5E,6EAA6E;IAC7E,8EAA8E;IAC9E,yEAAyE;IACzE,wEAAwE;IACxE,wEAAwE;IACxE,oBAAoB;IACpB,IAAI,KAAK,KAAK,eAAe,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC;QACvF,2EAA2E;QAC3E,wEAAwE;QACxE,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,wDAAwD;QACxD,IAAI,MAAM,wBAAwB,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,CAAC;YACzD,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;YAClC,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC,MAAM,CAAC,CAAC;YAClD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;YACrD,MAAM,IAAI,UAAU,CAClB,GAAG,SAAS,2EAA2E;gBACrF,wBAAwB,uBAAuB,IAAI,WAAW,iCAAiC;gBAC/F,4FAA4F;gBAC5F,4BAA4B,oBAAoB,gCAAgC,SAAS,WAAW,EACtG,EAAE,IAAI,EAAE,0BAA0B,EAAE,MAAM,EAAE,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAC9E,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,UAAU,CAClB,mCAAmC,SAAS,oBAAoB,oBAAoB,qBAAqB;YACvG,wBAAwB,uBAAuB,IAAI,WAAW,8BAA8B;YAC5F,yEAAyE,EAC3E,EAAE,IAAI,EAAE,0BAA0B,EAAE,MAAM,EAAE,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAC9E,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IAC/C,MAAM,YAAY,GAChB,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;IACjF,OAAO;QACL,SAAS;QACT,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACjC,OAAO;QACP,4EAA4E;QAC5E,mEAAmE;QACnE,WAAW,EAAE;YACX,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;SACpF;QACD,OAAO,EAAE,CAAC,GAAW,EAAW,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC;QAC3D,cAAc,EACZ,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAW,EAAW,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,YAAY,CAAC;QACpG,oBAAoB,EAAE,WAAW;KAClC,CAAC;AACJ,CAAC"}
package/dist/config.d.ts CHANGED
@@ -11,7 +11,7 @@ import { z } from "zod";
11
11
  * `adopt-view`/`drop-identity-default` were added to `cli` without a
12
12
  * matching update here).
13
13
  */
14
- export declare const AllowTokenEnum: z.ZodEnum<["drop-column", "drop-table", "type-change", "drop-index", "drop-fk", "drop-check", "drop-view", "drop-view-cascade", "adopt-view", "nullable-to-not-null", "drop-identity-default"]>;
14
+ export declare const AllowTokenEnum: z.ZodEnum<["drop-column", "drop-table", "type-change", "drop-index", "drop-fk", "drop-check", "drop-view", "drop-view-cascade", "adopt-view", "nullable-to-not-null", "drop-identity-default", "drop-unmanaged"]>;
15
15
  export declare const ConfigSchema: z.ZodObject<{
16
16
  schema_version: z.ZodLiteral<1>;
17
17
  pending_in_git: z.ZodDefault<z.ZodBoolean>;
@@ -26,24 +26,36 @@ export declare const ConfigSchema: z.ZodObject<{
26
26
  drift_warn?: number | undefined;
27
27
  }>>;
28
28
  sources: z.ZodDefault<z.ZodArray<z.ZodUnion<[z.ZodObject<{
29
- kind: z.ZodLiteral<"path">;
30
29
  path: z.ZodString;
31
- }, "strip", z.ZodTypeAny, {
30
+ }, "strict", z.ZodTypeAny, {
32
31
  path: string;
33
- kind: "path";
34
32
  }, {
35
33
  path: string;
36
- kind: "path";
37
34
  }>, z.ZodObject<{
38
- kind: z.ZodLiteral<"package">;
35
+ resource: z.ZodString;
36
+ }, "strict", z.ZodTypeAny, {
37
+ resource: string;
38
+ }, {
39
+ resource: string;
40
+ }>, z.ZodObject<{
39
41
  package: z.ZodString;
40
- }, "strip", z.ZodTypeAny, {
41
- kind: "package";
42
+ }, "strict", z.ZodTypeAny, {
42
43
  package: string;
43
44
  }, {
44
- kind: "package";
45
45
  package: string;
46
46
  }>]>, "many">>;
47
+ /** Output filter applied across every command — see `./scope.ts`. Absent
48
+ * means "everything" (no filtering), matching `Scope`'s own contract. */
49
+ scope: z.ZodOptional<z.ZodObject<{
50
+ include: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
51
+ exclude: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
52
+ }, "strict", z.ZodTypeAny, {
53
+ include?: string[] | undefined;
54
+ exclude?: string[] | undefined;
55
+ }, {
56
+ include?: string[] | undefined;
57
+ exclude?: string[] | undefined;
58
+ }>>;
47
59
  extract: z.ZodDefault<z.ZodObject<{
48
60
  metaignore: z.ZodOptional<z.ZodString>;
49
61
  }, "strip", z.ZodTypeAny, {
@@ -57,13 +69,13 @@ export declare const ConfigSchema: z.ZodObject<{
57
69
  dialect: z.ZodOptional<z.ZodEnum<["sqlite", "postgres", "d1"]>>;
58
70
  format: z.ZodOptional<z.ZodEnum<["default", "flyway"]>>;
59
71
  onAmbiguous: z.ZodOptional<z.ZodEnum<["abort", "rename", "drop-add"]>>;
60
- allow: z.ZodOptional<z.ZodArray<z.ZodEnum<["drop-column", "drop-table", "type-change", "drop-index", "drop-fk", "drop-check", "drop-view", "drop-view-cascade", "adopt-view", "nullable-to-not-null", "drop-identity-default"]>, "many">>;
72
+ allow: z.ZodOptional<z.ZodArray<z.ZodEnum<["drop-column", "drop-table", "type-change", "drop-index", "drop-fk", "drop-check", "drop-view", "drop-view-cascade", "adopt-view", "nullable-to-not-null", "drop-identity-default", "drop-unmanaged"]>, "many">>;
61
73
  d1: z.ZodOptional<z.ZodObject<{
62
74
  binding: z.ZodOptional<z.ZodString>;
63
75
  remote: z.ZodOptional<z.ZodBoolean>;
64
76
  autoApply: z.ZodOptional<z.ZodBoolean>;
65
77
  wranglerConfigPath: z.ZodOptional<z.ZodString>;
66
- }, "strip", z.ZodTypeAny, {
78
+ }, "strict", z.ZodTypeAny, {
67
79
  binding?: string | undefined;
68
80
  remote?: boolean | undefined;
69
81
  autoApply?: boolean | undefined;
@@ -74,7 +86,8 @@ export declare const ConfigSchema: z.ZodObject<{
74
86
  autoApply?: boolean | undefined;
75
87
  wranglerConfigPath?: string | undefined;
76
88
  }>>;
77
- }, "strip", z.ZodTypeAny, {
89
+ scope: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
90
+ }, "strict", z.ZodTypeAny, {
78
91
  d1?: {
79
92
  binding?: string | undefined;
80
93
  remote?: boolean | undefined;
@@ -86,7 +99,8 @@ export declare const ConfigSchema: z.ZodObject<{
86
99
  dialect?: "sqlite" | "postgres" | "d1" | undefined;
87
100
  format?: "default" | "flyway" | undefined;
88
101
  onAmbiguous?: "abort" | "rename" | "drop-add" | undefined;
89
- allow?: ("drop-column" | "drop-table" | "type-change" | "drop-index" | "drop-fk" | "drop-check" | "drop-view" | "drop-view-cascade" | "adopt-view" | "nullable-to-not-null" | "drop-identity-default")[] | undefined;
102
+ allow?: ("drop-column" | "drop-table" | "type-change" | "drop-index" | "drop-fk" | "drop-check" | "drop-view" | "drop-view-cascade" | "adopt-view" | "nullable-to-not-null" | "drop-identity-default" | "drop-unmanaged")[] | undefined;
103
+ scope?: string[] | undefined;
90
104
  }, {
91
105
  d1?: {
92
106
  binding?: string | undefined;
@@ -99,9 +113,10 @@ export declare const ConfigSchema: z.ZodObject<{
99
113
  dialect?: "sqlite" | "postgres" | "d1" | undefined;
100
114
  format?: "default" | "flyway" | undefined;
101
115
  onAmbiguous?: "abort" | "rename" | "drop-add" | undefined;
102
- allow?: ("drop-column" | "drop-table" | "type-change" | "drop-index" | "drop-fk" | "drop-check" | "drop-view" | "drop-view-cascade" | "adopt-view" | "nullable-to-not-null" | "drop-identity-default")[] | undefined;
116
+ allow?: ("drop-column" | "drop-table" | "type-change" | "drop-index" | "drop-fk" | "drop-check" | "drop-view" | "drop-view-cascade" | "adopt-view" | "nullable-to-not-null" | "drop-identity-default" | "drop-unmanaged")[] | undefined;
117
+ scope?: string[] | undefined;
103
118
  }>>;
104
- }, "strip", z.ZodTypeAny, {
119
+ }, "strict", z.ZodTypeAny, {
105
120
  schema_version: 1;
106
121
  pending_in_git: boolean;
107
122
  confidence_thresholds: {
@@ -110,14 +125,18 @@ export declare const ConfigSchema: z.ZodObject<{
110
125
  };
111
126
  sources: ({
112
127
  path: string;
113
- kind: "path";
114
128
  } | {
115
- kind: "package";
129
+ resource: string;
130
+ } | {
116
131
  package: string;
117
132
  })[];
118
133
  extract: {
119
134
  metaignore?: string | undefined;
120
135
  };
136
+ scope?: {
137
+ include?: string[] | undefined;
138
+ exclude?: string[] | undefined;
139
+ } | undefined;
121
140
  migrate?: {
122
141
  d1?: {
123
142
  binding?: string | undefined;
@@ -130,10 +149,15 @@ export declare const ConfigSchema: z.ZodObject<{
130
149
  dialect?: "sqlite" | "postgres" | "d1" | undefined;
131
150
  format?: "default" | "flyway" | undefined;
132
151
  onAmbiguous?: "abort" | "rename" | "drop-add" | undefined;
133
- allow?: ("drop-column" | "drop-table" | "type-change" | "drop-index" | "drop-fk" | "drop-check" | "drop-view" | "drop-view-cascade" | "adopt-view" | "nullable-to-not-null" | "drop-identity-default")[] | undefined;
152
+ allow?: ("drop-column" | "drop-table" | "type-change" | "drop-index" | "drop-fk" | "drop-check" | "drop-view" | "drop-view-cascade" | "adopt-view" | "nullable-to-not-null" | "drop-identity-default" | "drop-unmanaged")[] | undefined;
153
+ scope?: string[] | undefined;
134
154
  } | undefined;
135
155
  }, {
136
156
  schema_version: 1;
157
+ scope?: {
158
+ include?: string[] | undefined;
159
+ exclude?: string[] | undefined;
160
+ } | undefined;
137
161
  pending_in_git?: boolean | undefined;
138
162
  confidence_thresholds?: {
139
163
  pending_promote?: number | undefined;
@@ -141,9 +165,9 @@ export declare const ConfigSchema: z.ZodObject<{
141
165
  } | undefined;
142
166
  sources?: ({
143
167
  path: string;
144
- kind: "path";
145
168
  } | {
146
- kind: "package";
169
+ resource: string;
170
+ } | {
147
171
  package: string;
148
172
  })[] | undefined;
149
173
  extract?: {
@@ -161,11 +185,17 @@ export declare const ConfigSchema: z.ZodObject<{
161
185
  dialect?: "sqlite" | "postgres" | "d1" | undefined;
162
186
  format?: "default" | "flyway" | undefined;
163
187
  onAmbiguous?: "abort" | "rename" | "drop-add" | undefined;
164
- allow?: ("drop-column" | "drop-table" | "type-change" | "drop-index" | "drop-fk" | "drop-check" | "drop-view" | "drop-view-cascade" | "adopt-view" | "nullable-to-not-null" | "drop-identity-default")[] | undefined;
188
+ allow?: ("drop-column" | "drop-table" | "type-change" | "drop-index" | "drop-fk" | "drop-check" | "drop-view" | "drop-view-cascade" | "adopt-view" | "nullable-to-not-null" | "drop-identity-default" | "drop-unmanaged")[] | undefined;
189
+ scope?: string[] | undefined;
165
190
  } | undefined;
166
191
  }>;
167
192
  export type Config = z.infer<typeof ConfigSchema>;
168
193
  export declare const DEFAULT_CONFIG: Config;
194
+ /** `config.json`'s basename — the single owner. `discovery.ts` and
195
+ * `collection.ts` import this rather than each keeping their own copy of
196
+ * the literal (a duplication that had drifted into three separate
197
+ * declarations of the same string). */
198
+ export declare const CONFIG_FILE = "config.json";
169
199
  export declare function loadConfig(metaRoot: string): Promise<Config>;
170
200
  export declare function saveConfig(metaRoot: string, config: Config): Promise<void>;
171
201
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,iMAYzB,CAAC;AAsBH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBvB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD,eAAO,MAAM,cAAc,EAAE,MAAkD,CAAC;AAIhF,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGlE;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOhF"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,mNAazB,CAAC;AAwFH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAUvB;8EAC0E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQjE,CAAC;AAEZ,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD,eAAO,MAAM,cAAc,EAAE,MAAkD,CAAC;AAEhF;;;wCAGwC;AACxC,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGlE;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOhF"}
package/dist/config.js CHANGED
@@ -27,13 +27,17 @@ export const AllowTokenEnum = z.enum([
27
27
  "adopt-view",
28
28
  "nullable-to-not-null",
29
29
  "drop-identity-default",
30
+ "drop-unmanaged",
30
31
  ]);
32
+ // .strict(), like every other object in this schema: `.partial()` alone leaves
33
+ // zod's default STRIP policy in place, so a misspelled key is silently deleted
34
+ // and the block reads as if the author never wrote it.
31
35
  const D1Block = z.object({
32
36
  binding: z.string(),
33
37
  remote: z.boolean(),
34
38
  autoApply: z.boolean(),
35
39
  wranglerConfigPath: z.string(),
36
- }).partial();
40
+ }).partial().strict();
37
41
  /** #192 — migration output-format adapters; orthogonal to dialect. */
38
42
  const MigrateFormatEnum = z.enum(["default", "flyway"]);
39
43
  const MigrateBlock = z.object({
@@ -44,7 +48,67 @@ const MigrateBlock = z.object({
44
48
  onAmbiguous: OnAmbiguousEnum,
45
49
  allow: z.array(AllowTokenEnum),
46
50
  d1: D1Block,
47
- }).partial();
51
+ /** Restricts a `meta migrate` run to a subset of the loaded metadata, by the
52
+ * same package-glob pattern grammar as top-level `scope` (see `scope.ts`).
53
+ * Include-only — there's no `migrate.scope.exclude`, since a migration run
54
+ * is scoped to what it's touching, not filtered down from "everything". */
55
+ scope: z.array(z.string().min(1)),
56
+ // .strict() for the same reason as the top level and the source arms below, and
57
+ // with sharper teeth here: `{ migrate: { scopee: [...], dialect: "postgres" } }`
58
+ // used to parse to `{ dialect: "postgres" }`, so a typo'd `scope` key meant
59
+ // "unscoped" — silently governing every table in the database, which is the
60
+ // hazard `migrate.scope` exists to remove.
61
+ }).partial().strict();
62
+ /**
63
+ * Mirrors the hand-written `SourceSpec` union in `./sources.ts` — a
64
+ * declared source kind, one of `path` (resolves today), `resource`, or
65
+ * `package` (both reserved, throw `ERR_SOURCE_KIND_UNSUPPORTED` until a
66
+ * later phase). `.strict()` on every arm: this project is fail-closed on
67
+ * undeclared keys everywhere else (ADR-0023 makes an unregistered metadata
68
+ * attribute a hard error for the same reason) — a config schema that
69
+ * silently strips an unknown key would let `{ path: "model", pathh: "typo"
70
+ * }` parse clean and resolve one source instead of erroring on the typo.
71
+ * The pre-phase-1 `{ kind: "path", path: "..." }` shape (the dead 2-arm
72
+ * discriminated union this replaces) never shipped to an adopter — `meta
73
+ * init` has only ever scaffolded `"sources": []`, and nothing under `src/`
74
+ * ever read the old shape — so there is no live config to be lenient for;
75
+ * it only ever existed in this package's own tests, updated alongside this
76
+ * schema.
77
+ */
78
+ const SourceSpecSchema = z.union([
79
+ z.object({ path: z.string().min(1) }).strict(),
80
+ z.object({ resource: z.string().min(1) }).strict(),
81
+ z.object({ package: z.string().min(1) }).strict(),
82
+ ]);
83
+ // Compile-time parity, BOTH directions: if SourceSpecSchema and the
84
+ // hand-written SourceSpec (./sources.ts) ever drift, one of these two
85
+ // assignments stops compiling. Each direction alone catches only HALF the
86
+ // drift — `z.infer<...>` assignable to `SourceSpec` catches an arm added to
87
+ // the schema but missing from SourceSpec, while `SourceSpec` assignable to
88
+ // `z.infer<...>` catches the opposite: an arm added to the hand-written
89
+ // SourceSpec that the schema never gained. A single one-directional
90
+ // assignment (the prior form of this guard) let a SourceSpec-only addition
91
+ // compile clean — proven by deliberately breaking each direction in
92
+ // isolation; see the quality-pass report for both failing `tsc` outputs. A
93
+ // conditional type (`X extends Y ? true : never`) would silently resolve to
94
+ // `never` instead of erroring — this direct-assignment form fails for real.
95
+ const _sourceSpecParityInferToSpec = {};
96
+ const _sourceSpecParitySpecToInfer = {};
97
+ void _sourceSpecParityInferToSpec;
98
+ void _sourceSpecParitySpecToInfer;
99
+ /** Mirrors the hand-written `Scope` interface in `./scope.ts`. An absent or
100
+ * empty `include` means "everything" — see `matchesScope`. */
101
+ const ScopeSchema = z
102
+ .object({
103
+ include: z.array(z.string().min(1)).optional(),
104
+ exclude: z.array(z.string().min(1)).optional(),
105
+ })
106
+ .strict();
107
+ // .strict() at the TOP level too, not just the source-spec arms and the
108
+ // scope block: without it, a misspelled top-level key (e.g. "scopes" for
109
+ // "scope") is silently stripped by zod and the collection resolves as
110
+ // "everything in scope" — the exact silent fail-open .strict() on the
111
+ // nested arms exists to prevent, one level up.
48
112
  export const ConfigSchema = z.object({
49
113
  schema_version: z.literal(1),
50
114
  pending_in_git: z.boolean().default(true),
@@ -54,21 +118,23 @@ export const ConfigSchema = z.object({
54
118
  drift_warn: z.number().min(0).max(1).default(0.7),
55
119
  })
56
120
  .default({}),
57
- sources: z
58
- .array(z.union([
59
- z.object({ kind: z.literal("path"), path: z.string() }),
60
- z.object({ kind: z.literal("package"), package: z.string() }),
61
- ]))
62
- .default([]),
121
+ sources: z.array(SourceSpecSchema).default([]),
122
+ /** Output filter applied across every command — see `./scope.ts`. Absent
123
+ * means "everything" (no filtering), matching `Scope`'s own contract. */
124
+ scope: ScopeSchema.optional(),
63
125
  extract: z
64
126
  .object({
65
127
  metaignore: z.string().optional(),
66
128
  })
67
129
  .default({}),
68
130
  migrate: MigrateBlock.optional(),
69
- });
131
+ }).strict();
70
132
  export const DEFAULT_CONFIG = ConfigSchema.parse({ schema_version: 1 });
71
- const CONFIG_FILE = "config.json";
133
+ /** `config.json`'s basename — the single owner. `discovery.ts` and
134
+ * `collection.ts` import this rather than each keeping their own copy of
135
+ * the literal (a duplication that had drifted into three separate
136
+ * declarations of the same string). */
137
+ export const CONFIG_FILE = "config.json";
72
138
  export async function loadConfig(metaRoot) {
73
139
  const raw = await readFile(join(metaRoot, CONFIG_FILE), "utf8");
74
140
  return ConfigSchema.parse(JSON.parse(raw));
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}