@metaobjectsdev/cli 0.24.0 → 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.
package/src/index.ts CHANGED
@@ -21,7 +21,7 @@ COMMANDS:
21
21
  gen [<entity>...] Codegen TS targets from your declared metadata
22
22
  types [query] Search the metadata vocabulary (types, subtypes, @attrs) by name or description
23
23
  export Flatten loaded metadata to one canonical JSON artifact
24
- docs <metadata> --out <dir> Generate neutral metadata documentation (entity + template pages; --site for HTML site)
24
+ docs [<project-root>] --out <dir> Generate neutral metadata documentation (entity + template pages; --site for HTML site)
25
25
  verify Drift gate — subverbs: --templates / --db / --codegen (bare = --templates)
26
26
  upgrade Rewrite retired metadata vocabulary (previews; --apply writes)
27
27
  prompt-snapshot Snapshot rendered template.* output; --check gates drift
@@ -42,9 +42,11 @@ EXPORT FLAGS:
42
42
  --out <file> Write output to a file (default: stdout)
43
43
 
44
44
  DOCS FLAGS:
45
- <metadata> Project root to resolve metadata from; passing it SCOPES the run (default: cwd)
45
+ [<project-root>] PROJECT ROOT to resolve metadata from the directory that CONTAINS
46
+ your metadata, NOT the metadata directory. Passing it SCOPES the run
47
+ (default: cwd)
46
48
  --out <dir>, -o Output directory for the pages (default: ./docs)
47
- --templates <dir> Project root to resolve adopter templates/ overrides (default: <metadata>)
49
+ --templates <dir> Project root to resolve adopter templates/ overrides (default: <project-root>)
48
50
  --prompts <dir> Extra dir holding prompt .mustache sources for --site (e.g. data/templates/)
49
51
 
50
52
  VERIFY FLAGS (ADR-0021 D2 — explicit subverbs; combine any; exit 1 on ANY drift):
@@ -163,12 +165,15 @@ FLAGS:
163
165
  docs: `meta docs — generate neutral metadata documentation (entity + template pages)
164
166
 
165
167
  USAGE:
166
- meta docs [<metadata>] [flags]
168
+ meta docs [<project-root>] [flags]
167
169
 
168
170
  FLAGS:
169
- <metadata> Project root to resolve metadata from. Passing it SCOPES the run to
170
- that directory's own sources; no ancestor .metaobjects/config.json is
171
- consulted. Omitted (default), the project is discovered by walking up.
171
+ [<project-root>] PROJECT ROOT to resolve metadata from the directory that CONTAINS
172
+ your metadata, NOT the metadata directory itself. (The Python and C#
173
+ 'docs' positionals mean the metadata dir; this one does not.) Passing
174
+ it SCOPES the run to that directory's own sources; no ancestor
175
+ .metaobjects/config.json is consulted. Omitted (default), the project
176
+ is discovered by walking up.
172
177
  --out <dir>, -o Output directory for the pages (default: ./docs)
173
178
  --model Emit the markdown model surface (entity + template pages)
174
179
  --api Emit the markdown api surface (generated SDK reference)
@@ -177,7 +182,7 @@ FLAGS:
177
182
  --metamodel Document the built-in metamodel vocabulary (no metadata needed)
178
183
  --site Generate the browsable HTML documentation site (<out>/site/)
179
184
  --scaffold-site Copy the site's templates + assets into codegen/docs-site/ to own (theme) them
180
- --templates <dir> Project root to resolve adopter templates/ overrides (default: <metadata>)
185
+ --templates <dir> Project root to resolve adopter templates/ overrides (default: <project-root>)
181
186
  --prompts <dir> Extra dir holding prompt .mustache sources (for --site) when they
182
187
  live outside the metadata sources or templates/ (e.g. data/templates/)
183
188
  --help, -h Print this help
@@ -6,6 +6,7 @@ import { fileURLToPath } from "node:url";
6
6
  import { randomBytes } from "node:crypto";
7
7
  import { createJiti } from "jiti";
8
8
  import type { MetaDataTypeProvider, MetaobjectsGenConfig } from "@metaobjectsdev/codegen-ts";
9
+ import { resolveCollection, type Collection } from "@metaobjectsdev/sdk";
9
10
 
10
11
  const CONFIG_FILE = "metaobjects.config.ts";
11
12
 
@@ -212,6 +213,50 @@ export function resolveGenConfigDir(startDir: string, fallback: string): string
212
213
  return fallback;
213
214
  }
214
215
 
216
+ /**
217
+ * The collection a TypeScript package GENERATES FROM (#340).
218
+ *
219
+ * #326/#327 established that the two config files answer different questions, and gave
220
+ * `metaobjects.config.ts` its own walk. This is the remaining half of the same split:
221
+ * a sub-project whose TS config sits below the collection root was still LOADING the
222
+ * ancestor's whole source set, so its `src/generated` absorbed metadata belonging to
223
+ * unrelated parts of the repository — one adopter's web app went from 376 files to 831,
224
+ * the surplus being another module's server-side prompt payload DTOs. It fails OPEN
225
+ * (`tsc` passes, tests pass), so the only symptom is a directory that quietly doubled.
226
+ *
227
+ * The rule: an ancestor `.metaobjects/config.json` is the DEFAULT for a package that
228
+ * declares no sources of its own, never an ADDITION to one that does. So when the TS
229
+ * config sits somewhere the collection did not, that directory is re-resolved as a
230
+ * collection in its own right, and it wins if it actually resolves any metadata.
231
+ *
232
+ * It can only ever NARROW, and only in a shape that could not have worked before:
233
+ * - the two directories coincide (every `meta init` project, and every run from a
234
+ * project root) — returns the original, untouched, without a second resolve;
235
+ * - the sub-project declares no sources — the pinned resolve throws
236
+ * `ERR_SOURCE_UNRESOLVED` or comes back empty, and the ancestor stands, so a
237
+ * package that genuinely lives off an ancestor tree keeps working;
238
+ * - the sub-project has its own metadata — it generates from exactly that, which is
239
+ * what it did before source resolution learned to walk upward.
240
+ *
241
+ * Deliberately NOT applied to `.metaobjects/` STATE. Migrations, snapshots and the
242
+ * operational block stay keyed on the discovered collection's directory (#326 settled
243
+ * that); this narrows what is LOADED, and nothing about where state lives.
244
+ */
245
+ export async function resolveGenCollection(
246
+ collection: Collection,
247
+ genConfigDir: string,
248
+ ): Promise<Collection> {
249
+ if (resolve(genConfigDir) === resolve(collection.configDir)) return collection;
250
+ try {
251
+ const pinned = await resolveCollection(genConfigDir, { explicitDir: genConfigDir });
252
+ return pinned.files.length > 0 ? pinned : collection;
253
+ } catch {
254
+ // The sub-project declares nothing resolvable of its own — inherit, exactly as a
255
+ // package with no config always has.
256
+ return collection;
257
+ }
258
+ }
259
+
215
260
  export async function loadMetaobjectsConfig(projectRoot: string): Promise<MetaobjectsGenConfig> {
216
261
  const fullPath = resolve(projectRoot, CONFIG_FILE);
217
262
  if (!existsSync(fullPath)) {