@metaobjectsdev/codegen-ts 0.7.0-rc.9 → 0.7.0

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 (56) hide show
  1. package/dist/generator.d.ts +9 -0
  2. package/dist/generator.d.ts.map +1 -1
  3. package/dist/generator.js.map +1 -1
  4. package/dist/generators/docs-data-builder.d.ts +16 -0
  5. package/dist/generators/docs-data-builder.d.ts.map +1 -0
  6. package/dist/generators/docs-data-builder.js +381 -0
  7. package/dist/generators/docs-data-builder.js.map +1 -0
  8. package/dist/generators/docs-data.d.ts +98 -0
  9. package/dist/generators/docs-data.d.ts.map +1 -0
  10. package/dist/generators/docs-data.js +43 -0
  11. package/dist/generators/docs-data.js.map +1 -0
  12. package/dist/generators/docs-file.d.ts +8 -0
  13. package/dist/generators/docs-file.d.ts.map +1 -0
  14. package/dist/generators/docs-file.js +77 -0
  15. package/dist/generators/docs-file.js.map +1 -0
  16. package/dist/generators/index.d.ts +4 -0
  17. package/dist/generators/index.d.ts.map +1 -1
  18. package/dist/generators/index.js +3 -0
  19. package/dist/generators/index.js.map +1 -1
  20. package/dist/generators/template-generator.d.ts +41 -0
  21. package/dist/generators/template-generator.d.ts.map +1 -0
  22. package/dist/generators/template-generator.js +62 -0
  23. package/dist/generators/template-generator.js.map +1 -0
  24. package/dist/index.d.ts +6 -2
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +7 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/overwrite-policy.d.ts +39 -2
  29. package/dist/overwrite-policy.d.ts.map +1 -1
  30. package/dist/overwrite-policy.js +233 -13
  31. package/dist/overwrite-policy.js.map +1 -1
  32. package/dist/render-engine/framework-provider.d.ts +28 -0
  33. package/dist/render-engine/framework-provider.d.ts.map +1 -0
  34. package/dist/render-engine/framework-provider.js +104 -0
  35. package/dist/render-engine/framework-provider.js.map +1 -0
  36. package/dist/runner.d.ts +15 -1
  37. package/dist/runner.d.ts.map +1 -1
  38. package/dist/runner.js +44 -6
  39. package/dist/runner.js.map +1 -1
  40. package/dist/templates/docs-file.d.ts +17 -0
  41. package/dist/templates/docs-file.d.ts.map +1 -0
  42. package/dist/templates/docs-file.js +37 -0
  43. package/dist/templates/docs-file.js.map +1 -0
  44. package/package.json +5 -5
  45. package/src/generator.ts +9 -0
  46. package/src/generators/docs-data-builder.ts +470 -0
  47. package/src/generators/docs-data.ts +154 -0
  48. package/src/generators/docs-file.ts +87 -0
  49. package/src/generators/index.ts +16 -0
  50. package/src/generators/template-generator.ts +106 -0
  51. package/src/index.ts +33 -2
  52. package/src/overwrite-policy.ts +325 -14
  53. package/src/render-engine/framework-provider.ts +107 -0
  54. package/src/runner.ts +65 -6
  55. package/src/templates/docs-file.ts +51 -0
  56. package/templates/docs/entity-page.md.mustache +54 -0
@@ -0,0 +1,77 @@
1
+ // docsFile() — emits `<Entity>.md` next to each generated entity module.
2
+ //
3
+ // rc.12+: structured around a shared Mustache template at
4
+ // `templates/docs/entity-page.md.mustache` + a data builder at
5
+ // `docs-data-builder.ts`. Adopters can override the framework template by
6
+ // dropping their own `templates/docs/entity-page.md.mustache` into the
7
+ // project root (resolved via the project-then-framework provider chain).
8
+ //
9
+ // docsFile() calls `render()` directly rather than wrapping
10
+ // `templateGenerator()` because the per-entity output path depends on
11
+ // `GenContext.config.outputLayout`, which the generic templateGenerator
12
+ // `walk(root)` signature doesn't expose. Other future docs-style adopters
13
+ // with ctx-free walks (single-file aggregators, etc.) compose
14
+ // `templateGenerator()` directly.
15
+ //
16
+ // The conformance fixture (`fixtures/conformance/docs-file-basic`) gates
17
+ // byte-identity — the codegen output must match the hand-coded rc.11
18
+ // byte-for-byte. If you're hacking on this and the conformance test
19
+ // breaks, the refactor is the bug, not the fixture.
20
+ import { render } from "@metaobjectsdev/render";
21
+ import { entityOutputPath } from "../import-path.js";
22
+ import { projectProvider } from "../render-engine/framework-provider.js";
23
+ import { buildEntityDocData } from "./docs-data-builder.js";
24
+ /** The names of the generators that may emit sibling files for an entity.
25
+ * We always list them in the "Generated code" section — adopters cross-
26
+ * reference their own metaobjects.config.ts to confirm which are wired in.
27
+ * Matches the rc.11 behavior. */
28
+ const KNOWN_SIBLING_GENERATORS = new Set([
29
+ "queries-file",
30
+ "routes-file",
31
+ "routes-file-hono",
32
+ ]);
33
+ const TEMPLATE_REF = "docs/entity-page.md";
34
+ export const docsFile = function docsFile(opts) {
35
+ const generator = {
36
+ name: "docs-file",
37
+ async generate(ctx) {
38
+ if (!ctx.renderContext) {
39
+ throw new Error("docs-file: renderContext is required (provided by runGen)");
40
+ }
41
+ const rc = ctx.renderContext;
42
+ const provider = projectProvider(ctx.projectRoot ?? process.cwd());
43
+ const layout = ctx.config.outputLayout ?? "flat";
44
+ return ctx.loadedRoot.objects().filter(ctx.matches).map((entity) => {
45
+ const path = entityOutputPath(layout, entity.package, `${entity.name}.md`);
46
+ const payload = buildEntityDocData(entity, {
47
+ dialect: rc.dialect,
48
+ ...(rc.columnNamingStrategy !== undefined && {
49
+ columnNamingStrategy: rc.columnNamingStrategy,
50
+ }),
51
+ loadedRoot: rc.loadedRoot,
52
+ generatorNames: KNOWN_SIBLING_GENERATORS,
53
+ });
54
+ let content;
55
+ try {
56
+ content = render({
57
+ ref: TEMPLATE_REF,
58
+ payload,
59
+ provider,
60
+ format: "markdown",
61
+ });
62
+ }
63
+ catch (err) {
64
+ const msg = err instanceof Error ? err.message : String(err);
65
+ throw new Error(`docs-file: failed rendering '${TEMPLATE_REF}' for '${path}': ${msg}`, { cause: err instanceof Error ? err : undefined });
66
+ }
67
+ return { path, content };
68
+ });
69
+ },
70
+ };
71
+ if (opts?.filter)
72
+ generator.filter = opts.filter;
73
+ if (opts?.target)
74
+ generator.target = opts.target;
75
+ return generator;
76
+ };
77
+ //# sourceMappingURL=docs-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs-file.js","sourceRoot":"","sources":["../../src/generators/docs-file.ts"],"names":[],"mappings":"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"}
@@ -6,4 +6,8 @@ export { barrel, type BarrelOpts } from "./barrel.js";
6
6
  export { mermaidErDiagram, type MermaidErOptions } from "./mermaid-er.js";
7
7
  export { promptRender, type PromptRenderOpts } from "./prompt-render-file.js";
8
8
  export { outputParser, type OutputParserOpts } from "./output-parser-file.js";
9
+ export { docsFile, type DocsFileOpts } from "./docs-file.js";
10
+ export { templateGenerator, type TemplateGeneratorOpts, type TemplateWalkResult, type TemplateFormat, } from "./template-generator.js";
11
+ export type { EntityDocData, StorageFieldDoc, IdentityDoc, RelationshipDoc, UsedByDoc, GeneratedFileDoc, } from "./docs-data.js";
12
+ export { buildEntityDocData } from "./docs-data-builder.js";
9
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EACL,iBAAiB,EACjB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,cAAc,GACpB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,aAAa,EACb,eAAe,EACf,WAAW,EACX,eAAe,EACf,SAAS,EACT,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -6,4 +6,7 @@ export { barrel } from "./barrel.js";
6
6
  export { mermaidErDiagram } from "./mermaid-er.js";
7
7
  export { promptRender } from "./prompt-render-file.js";
8
8
  export { outputParser } from "./output-parser-file.js";
9
+ export { docsFile } from "./docs-file.js";
10
+ export { templateGenerator, } from "./template-generator.js";
11
+ export { buildEntityDocData } from "./docs-data-builder.js";
9
12
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAuB,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAwB,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAuB,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,cAAc,EAA2B,MAAM,uBAAuB,CAAC;AAChF,OAAO,EAAE,MAAM,EAAmB,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAyB,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAyB,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAyB,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAuB,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAwB,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAuB,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,cAAc,EAA2B,MAAM,uBAAuB,CAAC;AAChF,OAAO,EAAE,MAAM,EAAmB,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAyB,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAyB,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAyB,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAqB,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EACL,iBAAiB,GAIlB,MAAM,yBAAyB,CAAC;AASjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { MetaRoot, MetaObject } from "@metaobjectsdev/metadata";
2
+ import { type Provider, type RenderFormat } from "@metaobjectsdev/render";
3
+ import type { GeneratorFactory } from "../generator.js";
4
+ export type TemplateFormat = RenderFormat;
5
+ export interface TemplateWalkResult {
6
+ /** The data dict to render against. Templates reference its keys; the
7
+ * shape is the public-API contract template authors consume. */
8
+ data: object;
9
+ /** Output path RELATIVE to the generator's target outDir. */
10
+ outputPath: string;
11
+ }
12
+ export interface TemplateGeneratorOpts {
13
+ /** kebab-case identifier; surfaces in diagnostics and the overwrite-policy
14
+ * per-file snapshot key. */
15
+ name: string;
16
+ /** Walk the loaded metadata tree and produce `{ data, outputPath }` tuples
17
+ * — one per emitted file. Pattern A (per-entity), pattern B (single
18
+ * aggregator), pattern C (mixed), pattern D (filter inline) all fit. */
19
+ walk: (root: MetaRoot) => TemplateWalkResult[] | Promise<TemplateWalkResult[]>;
20
+ /** Template reference. Resolved by the configured Provider chain — by
21
+ * default the project's `templates/<ref>.mustache` first, then the
22
+ * framework defaults at `codegen-ts/templates/<ref>.mustache`. */
23
+ template: string;
24
+ /** Drives the render engine's escaper. Defaults to "text". */
25
+ format?: TemplateFormat;
26
+ /** Optional per-entity filter for adopters who want to scope a generator
27
+ * via the standard `Generator.filter` plumbing. Not consulted by the
28
+ * default `walk` — adopters apply filters inside their walk function. */
29
+ filter?: (entity: MetaObject) => boolean;
30
+ /** Override the Provider used for template resolution. When omitted the
31
+ * generator resolves via `projectProvider(ctx.projectRoot)`, which layers
32
+ * the project's `templates/` over the framework defaults. (The project
33
+ * root is the directory holding `.metaobjects/config.json`, threaded
34
+ * through `GenContext` by the runner. Adopters needing a different
35
+ * lookup chain can pass an explicit provider.) */
36
+ provider?: Provider;
37
+ /** Optional named target — same as the other generators. */
38
+ target?: string;
39
+ }
40
+ export declare const templateGenerator: GeneratorFactory<TemplateGeneratorOpts>;
41
+ //# sourceMappingURL=template-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-generator.d.ts","sourceRoot":"","sources":["../../src/generators/template-generator.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAU,KAAK,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,KAAK,EAAsC,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAG5F,MAAM,MAAM,cAAc,GAAG,YAAY,CAAC;AAE1C,MAAM,WAAW,kBAAkB;IACjC;qEACiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC;iCAC6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb;;6EAEyE;IACzE,IAAI,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,kBAAkB,EAAE,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC/E;;uEAEmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB;;8EAE0E;IAC1E,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC;IACzC;;;;;uDAKmD;IACnD,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,iBAAiB,EA8CzB,gBAAgB,CAAC,qBAAqB,CAAC,CAAC"}
@@ -0,0 +1,62 @@
1
+ // templateGenerator() — the missing primitive identified by the
2
+ // template-driven-codegen design (2026-05-28). Walks the loaded MetaRoot
3
+ // → renders shared Mustache templates via @metaobjectsdev/render → emits
4
+ // EmittedFile[]. Same Generator interface as the per-port hand-coded
5
+ // generators; just adds the "Mustache template" + "walk that yields a
6
+ // data dict per output" primitives.
7
+ //
8
+ // Design line we adopted (from the design doc):
9
+ // Code → hand-coded generators (ts-poet, idiomatic per-port).
10
+ // Documents → templateGenerator (shared Mustache templates).
11
+ //
12
+ // docsFile() is the first templateGenerator instance (rc.12). OpenAPI specs,
13
+ // Mermaid diagrams, HTML doc sites, etc. follow as templates + a walk
14
+ // function each.
15
+ import { render } from "@metaobjectsdev/render";
16
+ import { projectProvider } from "../render-engine/framework-provider.js";
17
+ export const templateGenerator = function templateGenerator(opts) {
18
+ const fmt = opts.format ?? "text";
19
+ const generator = {
20
+ name: opts.name,
21
+ async generate(ctx) {
22
+ let provider;
23
+ if (opts.provider !== undefined) {
24
+ provider = opts.provider;
25
+ }
26
+ else if (ctx.projectRoot !== undefined) {
27
+ provider = projectProvider(ctx.projectRoot);
28
+ }
29
+ else {
30
+ ctx.warn("templateGenerator: ctx.projectRoot is undefined; falling back to process.cwd() for project-template resolution. " +
31
+ "Project-scoped template overrides will resolve relative to the current working directory, which is fragile under " +
32
+ "`meta gen` invoked from a sub-directory. Drive via runGen(opts.projectRoot) to remove this warning.");
33
+ provider = projectProvider(process.cwd());
34
+ }
35
+ const walkRes = await opts.walk(ctx.loadedRoot);
36
+ const files = [];
37
+ for (const { data, outputPath } of walkRes) {
38
+ let content;
39
+ try {
40
+ content = render({
41
+ ref: opts.template,
42
+ payload: data,
43
+ provider,
44
+ format: fmt,
45
+ });
46
+ }
47
+ catch (err) {
48
+ const msg = err instanceof Error ? err.message : String(err);
49
+ throw new Error(`templateGenerator(${opts.name}) failed rendering '${opts.template}' for '${outputPath}': ${msg}`, { cause: err instanceof Error ? err : undefined });
50
+ }
51
+ files.push({ path: outputPath, content });
52
+ }
53
+ return files;
54
+ },
55
+ };
56
+ if (opts.filter)
57
+ generator.filter = opts.filter;
58
+ if (opts.target)
59
+ generator.target = opts.target;
60
+ return generator;
61
+ };
62
+ //# sourceMappingURL=template-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-generator.js","sourceRoot":"","sources":["../../src/generators/template-generator.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,yEAAyE;AACzE,yEAAyE;AACzE,qEAAqE;AACrE,sEAAsE;AACtE,oCAAoC;AACpC,EAAE;AACF,gDAAgD;AAChD,gEAAgE;AAChE,+DAA+D;AAC/D,EAAE;AACF,6EAA6E;AAC7E,sEAAsE;AACtE,iBAAiB;AAGjB,OAAO,EAAE,MAAM,EAAoC,MAAM,wBAAwB,CAAC;AAElF,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC;AAyCzE,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,iBAAiB,CACzD,IAA2B;IAE3B,MAAM,GAAG,GAAmB,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC;IAClD,MAAM,SAAS,GAAc;QAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,CAAC,QAAQ,CAAC,GAAe;YAC5B,IAAI,QAAkB,CAAC;YACvB,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAChC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC3B,CAAC;iBAAM,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;gBACzC,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YAC9C,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,IAAI,CACN,kHAAkH;oBAClH,mHAAmH;oBACnH,qGAAqG,CACtG,CAAC;gBACF,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YAC5C,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAChD,MAAM,KAAK,GAAkB,EAAE,CAAC;YAChC,KAAK,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,OAAO,EAAE,CAAC;gBAC3C,IAAI,OAAe,CAAC;gBACpB,IAAI,CAAC;oBACH,OAAO,GAAG,MAAM,CAAC;wBACf,GAAG,EAAE,IAAI,CAAC,QAAQ;wBAClB,OAAO,EAAE,IAAI;wBACb,QAAQ;wBACR,MAAM,EAAE,GAAG;qBACZ,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBAC7D,MAAM,IAAI,KAAK,CACb,qBAAqB,IAAI,CAAC,IAAI,uBAAuB,IAAI,CAAC,QAAQ,UAAU,UAAU,MAAM,GAAG,EAAE,EACjG,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAClD,CAAC;gBACJ,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;YAC5C,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;IACF,IAAI,IAAI,CAAC,MAAM;QAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAChD,IAAI,IAAI,CAAC,MAAM;QAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAChD,OAAO,SAAS,CAAC;AACnB,CAA4C,CAAC"}
package/dist/index.d.ts CHANGED
@@ -12,8 +12,8 @@ export type { RelationEntry, RelationMap } from "./relation-resolver.js";
12
12
  export { buildRelationMap } from "./relation-resolver.js";
13
13
  export type { RenderContext } from "./render-context.js";
14
14
  export { makeRenderContext } from "./render-context.js";
15
- export type { WriteStatus, WriteResult, MergeStrategy } from "./overwrite-policy.js";
16
- export { decideAndWrite } from "./overwrite-policy.js";
15
+ export type { WriteStatus, WriteResult, MergeStrategy, BaselineMode, DecideAndWriteOpts, } from "./overwrite-policy.js";
16
+ export { decideAndWrite, GitMissingError } from "./overwrite-policy.js";
17
17
  export { CodegenError } from "./errors.js";
18
18
  export { GENERATED_HEADER, EXTRA_SUFFIX, DEFAULT_OUT_DIR } from "./constants.js";
19
19
  export { formatTs } from "./format.js";
@@ -27,4 +27,8 @@ export { emitViewDdl } from "./projection/view-ddl-emit.js";
27
27
  export type { EmitOptions as ViewDdlEmitOptions } from "./projection/view-ddl-emit.js";
28
28
  export type { JoinNode, JoinTree, SelectColumn, SelectSpec, ViewSpec } from "./projection/view-spec.js";
29
29
  export { generatePayloadInterfaces, generatePayloadInterfacesBatch, generateRenderHandle } from "./payload-codegen.js";
30
+ export { templateGenerator, type TemplateGeneratorOpts, type TemplateWalkResult, type TemplateFormat, } from "./generators/template-generator.js";
31
+ export { FileSystemProvider, ProviderChain, frameworkTemplatesProvider, projectProvider, } from "./render-engine/framework-provider.js";
32
+ export type { EntityDocData, StorageFieldDoc, IdentityDoc, RelationshipDoc, UsedByDoc, GeneratedFileDoc, } from "./generators/docs-data.js";
33
+ export { buildEntityDocData } from "./generators/docs-data-builder.js";
30
34
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE5D,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC3F,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEvD,YAAY,EAAE,oBAAoB,EAAE,8BAA8B,EAAE,iBAAiB,EAAE,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACtL,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAExE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,YAAY,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjF,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE1G,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACxM,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAErE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACpE,YAAY,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,YAAY,EAAE,WAAW,IAAI,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACvF,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAExG,OAAO,EAAE,yBAAyB,EAAE,8BAA8B,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ export { mapColumnType } from "./column-mapper.js";
9
9
  export { buildPkMap } from "./pk-resolver.js";
10
10
  export { buildRelationMap } from "./relation-resolver.js";
11
11
  export { makeRenderContext } from "./render-context.js";
12
- export { decideAndWrite } from "./overwrite-policy.js";
12
+ export { decideAndWrite, GitMissingError } from "./overwrite-policy.js";
13
13
  export { CodegenError } from "./errors.js";
14
14
  export { GENERATED_HEADER, EXTRA_SUFFIX, DEFAULT_OUT_DIR } from "./constants.js";
15
15
  export { formatTs } from "./format.js";
@@ -20,4 +20,10 @@ export { extractViewSpec } from "./projection/extract-view-spec.js";
20
20
  export { emitViewDdl } from "./projection/view-ddl-emit.js";
21
21
  // Prompt construction (FR-004): typed payload + render-handle codegen.
22
22
  export { generatePayloadInterfaces, generatePayloadInterfacesBatch, generateRenderHandle } from "./payload-codegen.js";
23
+ // Template-driven codegen (rc.12). Factory + framework Provider for adopters
24
+ // who want to wire their own templateGenerator instances. The default
25
+ // docsFile() uses this internally.
26
+ export { templateGenerator, } from "./generators/template-generator.js";
27
+ export { FileSystemProvider, ProviderChain, frameworkTemplatesProvider, projectProvider, } from "./render-engine/framework-provider.js";
28
+ export { buildEntityDocData } from "./generators/docs-data-builder.js";
23
29
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,yCAAyC;AACzC,wEAAwE;AAExE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAGxE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjF,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE1G,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAGxM,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAG5D,uEAAuE;AACvE,OAAO,EAAE,yBAAyB,EAAE,8BAA8B,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,yCAAyC;AACzC,wEAAwE;AAExE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAGxE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AASxD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjF,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE1G,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAGxM,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAG5D,uEAAuE;AACvE,OAAO,EAAE,yBAAyB,EAAE,8BAA8B,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEvH,6EAA6E;AAC7E,sEAAsE;AACtE,mCAAmC;AACnC,OAAO,EACL,iBAAiB,GAIlB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,0BAA0B,EAC1B,eAAe,GAChB,MAAM,uCAAuC,CAAC;AAS/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC"}
@@ -1,8 +1,45 @@
1
- export type WriteStatus = "new" | "overwrite" | "refused" | "skipped";
1
+ export type WriteStatus = "new" | "unchanged" | "overwrite" | "merged" | "conflict" | "refused" | "skipped";
2
+ /**
3
+ * "overwrite" — default; three-way merge if .gen-state exists, else write-if-
4
+ * different / first-time-existing flow.
5
+ * "skip-existing" — never write over an existing file; status "skipped".
6
+ * Useful for `meta gen --dry-run` style flows.
7
+ */
2
8
  export type MergeStrategy = "overwrite" | "skip-existing";
9
+ /** "default" — the standard three-way merge flow described in the file header.
10
+ * "fresh" — opt-in via `meta gen --baseline=fresh`. When .gen-state is absent
11
+ * but the file exists, OVERWRITE with fresh content and seed .gen-state from
12
+ * the fresh content (caveat 3 escape hatch). */
13
+ export type BaselineMode = "default" | "fresh";
14
+ export interface DecideAndWriteOpts {
15
+ strategy?: MergeStrategy;
16
+ /** Absolute path to the .gen-state/ root for this project. When undefined,
17
+ * we fall back to a process-isolated tmpdir — fine for tests but the CLI
18
+ * always supplies the real project value via runGen(). */
19
+ genStateDir?: string;
20
+ /** Path the snapshot is keyed by — usually the path relative to the
21
+ * project root, but ANY stable identifier works. When undefined, derived
22
+ * from `path` (so unit tests can call without supplying it). */
23
+ outputRelPath?: string;
24
+ /** First-time-existing-file behavior. */
25
+ baseline?: BaselineMode;
26
+ }
3
27
  export interface WriteResult {
4
28
  path: string;
5
29
  status: WriteStatus;
30
+ /** Present when status is "conflict" — human-readable hint identifying the
31
+ * file the user must resolve. */
32
+ conflictHint?: string;
33
+ }
34
+ /** Thrown when git is unavailable. Surfaces as a clear CLI error rather than
35
+ * a generic ENOENT halfway through a regen. */
36
+ export declare class GitMissingError extends Error {
37
+ constructor();
6
38
  }
7
- export declare function decideAndWrite(path: string, content: string, strategy?: MergeStrategy): WriteResult;
39
+ /**
40
+ * The main entry point. Backward-compatible with the rc.11 signature: passing
41
+ * a `MergeStrategy` string as the third argument continues to work; passing
42
+ * an options object opts into three-way merge.
43
+ */
44
+ export declare function decideAndWrite(path: string, content: string, optsOrStrategy?: DecideAndWriteOpts | MergeStrategy): WriteResult;
8
45
  //# sourceMappingURL=overwrite-policy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"overwrite-policy.d.ts","sourceRoot":"","sources":["../src/overwrite-policy.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;AACtE,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,eAAe,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,aAA2B,GACpC,WAAW,CAmBb"}
1
+ {"version":3,"file":"overwrite-policy.d.ts","sourceRoot":"","sources":["../src/overwrite-policy.ts"],"names":[],"mappings":"AAqCA,MAAM,MAAM,WAAW,GACnB,KAAK,GACL,WAAW,GACX,WAAW,GACX,QAAQ,GACR,UAAU,GACV,SAAS,GACT,SAAS,CAAC;AAEd;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,eAAe,CAAC;AAE1D;;;iDAGiD;AACjD,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,CAAC;AAE/C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB;;+DAE2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;qEAEiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB;sCACkC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAoED;gDACgD;AAChD,qBAAa,eAAgB,SAAQ,KAAK;;CAQzC;AAsFD;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,cAAc,GAAE,kBAAkB,GAAG,aAAkB,GACtD,WAAW,CAgGb"}
@@ -1,23 +1,243 @@
1
- // Overwrite policy: drives the per-file write decision based on the @generated header.
2
- // Per design §8 read-only generated files; refuse to clobber hand-written code.
3
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
4
- import { dirname } from "node:path";
5
- import { GENERATED_HEADER } from "./constants.js";
6
- export function decideAndWrite(path, content, strategy = "overwrite") {
7
- // 'skip-existing' only skips overwrites, not new files.
1
+ // Overwrite policy: per-file write decision using three-way merge against a
2
+ // canonical snapshot kept under `.metaobjects/.gen-state/`.
3
+ //
4
+ // Replaces the rc.11 marker-based clobber-or-refuse policy (strategy (a) from
5
+ // spike 002) with strategy (b) — git-merge-file-driven three-way merge. The
6
+ // `@generated` marker becomes purely informational (templates may still emit
7
+ // it for human readers); the policy no longer consults it.
8
+ //
9
+ // Per-file flow:
10
+ //
11
+ // 1. Render fresh content to a tmpfile.
12
+ // 2. If the output doesn't exist → write + copy to .gen-state/.
13
+ // 3. If .gen-state/<relPath> exists → run `git merge-file --diff3` against
14
+ // (current, .gen-state snapshot, fresh tmpfile). Exit 0 → clean merge,
15
+ // advance .gen-state to fresh content. Exit > 0 → leave conflict markers
16
+ // in the output file, do NOT advance .gen-state; status "conflict".
17
+ // 4. If .gen-state/<relPath> is absent but the file exists ("first-time
18
+ // regen on an existing file") → write-if-different against the existing
19
+ // file as the baseline (no merge, no clobber). The `baseline: "fresh"`
20
+ // flag opts into "overwrite from fresh and re-baseline".
21
+ //
22
+ // Integrity (caveat 2 from the spike): we keep a sha-256 of each canonical
23
+ // snapshot at `.gen-state/.hashes.json`. On load, mismatch → fall back to
24
+ // first-time semantics and warn naming the file so the user can investigate.
25
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync, } from "node:fs";
26
+ import { dirname, join, isAbsolute, relative, resolve } from "node:path";
27
+ import { spawnSync } from "node:child_process";
28
+ import { tmpdir } from "node:os";
29
+ import { createHash, randomBytes } from "node:crypto";
30
+ const HASHES_FILE = ".hashes.json";
31
+ function sha256(content) {
32
+ return createHash("sha256").update(content).digest("hex");
33
+ }
34
+ function loadHashes(genStateDir) {
35
+ const f = join(genStateDir, HASHES_FILE);
36
+ if (!existsSync(f))
37
+ return {};
38
+ try {
39
+ const txt = readFileSync(f, "utf-8");
40
+ const parsed = JSON.parse(txt);
41
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
42
+ return parsed;
43
+ }
44
+ return {};
45
+ }
46
+ catch {
47
+ return {};
48
+ }
49
+ }
50
+ function saveHashes(genStateDir, hashes) {
51
+ mkdirSync(genStateDir, { recursive: true });
52
+ writeFileSync(join(genStateDir, HASHES_FILE), JSON.stringify(hashes, null, 2) + "\n");
53
+ }
54
+ function snapshotPath(genStateDir, relPath) {
55
+ // `.hashes.json` is reserved at the top of .gen-state/; relPath must never
56
+ // collide with it. Output paths derived from entity names ("Post.ts" etc.)
57
+ // are JS-identifier-shape so this is a non-issue in practice.
58
+ return join(genStateDir, relPath);
59
+ }
60
+ /** Synchronously copy `src` content into the snapshot at `<genStateDir>/<relPath>`
61
+ * and refresh the hash for `relPath`. */
62
+ function advanceSnapshot(genStateDir, relPath, content) {
63
+ const dest = snapshotPath(genStateDir, relPath);
64
+ mkdirSync(dirname(dest), { recursive: true });
65
+ writeFileSync(dest, content);
66
+ const hashes = loadHashes(genStateDir);
67
+ hashes[relPath] = sha256(content);
68
+ saveHashes(genStateDir, hashes);
69
+ }
70
+ /** Return the snapshot text iff present AND the hash matches; else undefined. */
71
+ function readSnapshotChecked(genStateDir, relPath) {
72
+ const path = snapshotPath(genStateDir, relPath);
73
+ if (!existsSync(path))
74
+ return undefined;
75
+ const text = readFileSync(path, "utf-8");
76
+ const hashes = loadHashes(genStateDir);
77
+ const expected = hashes[relPath];
78
+ if (expected !== undefined && expected !== sha256(text)) {
79
+ return undefined;
80
+ }
81
+ return { text };
82
+ }
83
+ /** Thrown when git is unavailable. Surfaces as a clear CLI error rather than
84
+ * a generic ENOENT halfway through a regen. */
85
+ export class GitMissingError extends Error {
86
+ constructor() {
87
+ super("meta gen: `git` binary not found on PATH. Three-way-merge regen " +
88
+ "requires git (any modern version). Install git and re-run.");
89
+ this.name = "GitMissingError";
90
+ }
91
+ }
92
+ /** Run `git merge-file --diff3 -L<...> <out> <base> <fresh>`. The output is
93
+ * written in-place into `outPath`. Returns the exit code (0 = clean, > 0 =
94
+ * conflicts) and the resulting file contents.
95
+ *
96
+ * The git binary is "git" by default; set `META_GEN_GIT` in the environment
97
+ * to a different path (useful for tests that simulate "git not installed"). */
98
+ function runGitMergeFile(outPath, basePath, freshPath) {
99
+ const gitBin = process.env.META_GEN_GIT ?? "git";
100
+ let res;
101
+ try {
102
+ res = spawnSync(gitBin, [
103
+ "merge-file",
104
+ "--diff3",
105
+ "-L",
106
+ "your edits",
107
+ "-L",
108
+ "last generated",
109
+ "-L",
110
+ "fresh from meta gen",
111
+ outPath,
112
+ basePath,
113
+ freshPath,
114
+ ], { encoding: "utf-8" });
115
+ }
116
+ catch (err) {
117
+ const msg = err.message ?? "";
118
+ if (msg.includes("ENOENT"))
119
+ throw new GitMissingError();
120
+ throw err;
121
+ }
122
+ if (res.error) {
123
+ const code = res.error.code;
124
+ if (code === "ENOENT")
125
+ throw new GitMissingError();
126
+ throw res.error;
127
+ }
128
+ // `git merge-file` returns the conflict count (0 = clean, > 0 = conflicts,
129
+ // < 0 = error). Negative is unexpected — surface verbatim.
130
+ const exitCode = res.status ?? 0;
131
+ if (exitCode < 0) {
132
+ throw new Error(`git merge-file failed for ${outPath}: ${res.stderr || res.stdout}`);
133
+ }
134
+ const mergedContent = readFileSync(outPath, "utf-8");
135
+ return { exitCode, stderr: res.stderr ?? "", mergedContent };
136
+ }
137
+ /** Write `content` to a freshly-named tmpfile under the OS tmpdir; return the
138
+ * path. Caller is responsible for cleanup (acceptable for codegen — tmpdir
139
+ * is process-scoped). */
140
+ function writeTmpfile(content) {
141
+ const dir = join(tmpdir(), "meta-gen-merge");
142
+ mkdirSync(dir, { recursive: true });
143
+ const path = join(dir, `${Date.now()}-${randomBytes(6).toString("hex")}.tmp`);
144
+ writeFileSync(path, content);
145
+ return path;
146
+ }
147
+ /** Resolve the snapshot key for a given output path. Falls back to a stable
148
+ * hash-of-path so unit tests that pass arbitrary tmpdir outputs still get a
149
+ * consistent .gen-state key. */
150
+ function defaultOutputRelPath(outputPath) {
151
+ // Use sha256 of the absolute path → hex; lets tests work without supplying
152
+ // an explicit relPath. NOT used by the runner — runGen always passes the
153
+ // real project-relative path.
154
+ return sha256(resolve(outputPath)).slice(0, 32);
155
+ }
156
+ /**
157
+ * The main entry point. Backward-compatible with the rc.11 signature: passing
158
+ * a `MergeStrategy` string as the third argument continues to work; passing
159
+ * an options object opts into three-way merge.
160
+ */
161
+ export function decideAndWrite(path, content, optsOrStrategy = {}) {
162
+ const opts = typeof optsOrStrategy === "string"
163
+ ? { strategy: optsOrStrategy }
164
+ : optsOrStrategy;
165
+ const strategy = opts.strategy ?? "overwrite";
166
+ const baseline = opts.baseline ?? "default";
167
+ const genStateDir = opts.genStateDir !== undefined
168
+ ? (isAbsolute(opts.genStateDir)
169
+ ? opts.genStateDir
170
+ : resolve(opts.genStateDir))
171
+ : join(tmpdir(), "meta-gen-state-fallback");
172
+ const relPath = opts.outputRelPath ?? defaultOutputRelPath(path);
173
+ // 1. First-time write — file doesn't exist.
8
174
  if (!existsSync(path)) {
9
175
  mkdirSync(dirname(path), { recursive: true });
10
176
  writeFileSync(path, content);
177
+ advanceSnapshot(genStateDir, relPath, content);
11
178
  return { path, status: "new" };
12
179
  }
13
- const current = readFileSync(path, "utf-8");
14
- if (!current.includes(GENERATED_HEADER)) {
15
- return { path, status: "refused" };
16
- }
17
180
  if (strategy === "skip-existing") {
18
181
  return { path, status: "skipped" };
19
182
  }
20
- writeFileSync(path, content);
21
- return { path, status: "overwrite" };
183
+ // 2. File exists. Load the canonical snapshot if any.
184
+ const snapshot = readSnapshotChecked(genStateDir, relPath);
185
+ // 3. First-time regen on a pre-existing file (no snapshot).
186
+ if (snapshot === undefined) {
187
+ const current = readFileSync(path, "utf-8");
188
+ if (baseline === "fresh") {
189
+ // Opt-in escape hatch: overwrite and seed the snapshot from fresh.
190
+ if (current === content) {
191
+ advanceSnapshot(genStateDir, relPath, content);
192
+ return { path, status: "unchanged" };
193
+ }
194
+ writeFileSync(path, content);
195
+ advanceSnapshot(genStateDir, relPath, content);
196
+ return { path, status: "overwrite" };
197
+ }
198
+ // Default: write-if-different. The EXISTING file is treated as the
199
+ // canonical baseline so subsequent runs do real three-way merges. If
200
+ // fresh output is identical, just seed the snapshot. If different, write
201
+ // the fresh content + seed snapshot — there's no marker policy left to
202
+ // refuse on, but this is the contract documented in the runbook (no
203
+ // marker check; users with hand-written files should never have the
204
+ // codegen output path colliding with them).
205
+ if (current === content) {
206
+ advanceSnapshot(genStateDir, relPath, current);
207
+ return { path, status: "unchanged" };
208
+ }
209
+ writeFileSync(path, content);
210
+ advanceSnapshot(genStateDir, relPath, content);
211
+ return { path, status: "overwrite" };
212
+ }
213
+ // 4. Snapshot exists — real three-way merge.
214
+ const current = readFileSync(path, "utf-8");
215
+ // Fast path: nothing changed.
216
+ if (current === content && snapshot.text === content) {
217
+ return { path, status: "unchanged" };
218
+ }
219
+ const baseTmp = writeTmpfile(snapshot.text);
220
+ const freshTmp = writeTmpfile(content);
221
+ const outcome = runGitMergeFile(path, baseTmp, freshTmp);
222
+ if (outcome.exitCode === 0) {
223
+ // Clean merge — advance the canonical snapshot to fresh.
224
+ advanceSnapshot(genStateDir, relPath, content);
225
+ // Distinguish "user had no changes vs canonical" from "merge integrated
226
+ // edits". The fresh equals snapshot case happened above (fast path) — so
227
+ // if outcome.mergedContent equals fresh we report a plain overwrite,
228
+ // otherwise it's a merge that pulled in user edits.
229
+ if (outcome.mergedContent === content) {
230
+ return { path, status: "overwrite" };
231
+ }
232
+ return { path, status: "merged" };
233
+ }
234
+ // Conflict — do NOT advance the snapshot. The output now contains diff3
235
+ // markers from git merge-file.
236
+ return {
237
+ path,
238
+ status: "conflict",
239
+ conflictHint: "merge conflict — resolve `<<<<<<<` markers and re-run `meta gen` to " +
240
+ "advance the canonical state.",
241
+ };
22
242
  }
23
243
  //# sourceMappingURL=overwrite-policy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"overwrite-policy.js","sourceRoot":"","sources":["../src/overwrite-policy.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,kFAAkF;AAElF,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAUlD,MAAM,UAAU,cAAc,CAC5B,IAAY,EACZ,OAAe,EACf,WAA0B,WAAW;IAErC,wDAAwD;IACxD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACjC,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5C,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACxC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IACrC,CAAC;IAED,IAAI,QAAQ,KAAK,eAAe,EAAE,CAAC;QACjC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IACrC,CAAC;IAED,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;AACvC,CAAC"}
1
+ {"version":3,"file":"overwrite-policy.js","sourceRoot":"","sources":["../src/overwrite-policy.ts"],"names":[],"mappings":"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"}