@metaobjectsdev/codegen-ts-tanstack 0.24.4 → 0.24.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -57,6 +57,15 @@ the entity module from wherever `entityFile()` is routed (relative when same tar
57
57
  the entity-module target's `importBase` when not); the grid-hook imports its sibling
58
58
  `<Entity>.columns` from within its own target.
59
59
 
60
+ ### The generator is yours
61
+
62
+ Each of `tanstackQuery()`, `tanstackGrid()` and `tanstackGridHook()` has a reference template:
63
+ `meta eject hooks` / `grid` / `grid-hook` copies one into `codegen/generators/` for you to own. Each
64
+ renderer (`renderHooksFile`, `renderColumnsFile`, `renderGridHookFile`) is exported, so retargeting
65
+ is usually a wrapper, not a rewrite — compose it and change the one step your framework needs.
66
+ Inside the ejected file's existing `if (!ctx.renderContext) throw …` guard, change only the
67
+ `content:` line, e.g. `content: '"use client";\n' + renderHooksFile(entity, ctx.renderContext)`.
68
+
60
69
  ## Pairs with
61
70
 
62
71
  - Runtime: [`@metaobjectsdev/tanstack`](../../../../client/web/packages/tanstack) — generated hooks and columns import from here.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,10 @@
1
1
  export { tanstackQuery, type TanstackQueryOpts } from "./tanstack-query.js";
2
2
  export { tanstackGrid, type TanstackGridOpts } from "./tanstack-grid.js";
3
3
  export { tanstackGridHook, type TanstackGridHookOpts } from "./tanstack-grid-hook.js";
4
+ export { renderHooksFile } from "./templates/hooks-file.js";
5
+ export { renderColumnsFile } from "./templates/columns-file.js";
6
+ export { renderGridHookFile } from "./templates/grid-hook-file.js";
7
+ export { hasDataGridLayout, warnMissingDataGridLayout } from "./data-grid-gate.js";
8
+ export { resolveReferenceRoot, readReferenceTemplate, REFERENCE_GENERATOR_NAMES } from "./reference-templates.js";
9
+ export type { ReferenceGeneratorName } from "./reference-templates.js";
4
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,KAAK,oBAAoB,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,KAAK,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAItF,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAMnE,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAInF,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAGlH,YAAY,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/index.js CHANGED
@@ -2,4 +2,17 @@
2
2
  export { tanstackQuery } from "./tanstack-query.js";
3
3
  export { tanstackGrid } from "./tanstack-grid.js";
4
4
  export { tanstackGridHook } from "./tanstack-grid-hook.js";
5
+ // FR-040 §4.2(b) — public so an owned generator composes the engine rather than
6
+ // forking it. Signatures are stable API: (entity, ctx) => string.
7
+ export { renderHooksFile } from "./templates/hooks-file.js";
8
+ export { renderColumnsFile } from "./templates/columns-file.js";
9
+ export { renderGridHookFile } from "./templates/grid-hook-file.js";
10
+ // FR-040 §4.2(b) — the grid/grid-hook data-grid opt-in gate is a STEP in the pipeline
11
+ // those two owned templates compose, not an internal detail either may fork. Public so
12
+ // `grid.ts` and `grid-hook.ts` import one shared implementation instead of each
13
+ // carrying its own copy.
14
+ export { hasDataGridLayout, warnMissingDataGridLayout } from "./data-grid-gate.js";
15
+ // FR-040 §4.1 — the copyable reference generators this package ships in
16
+ // `src/reference/`, and the reader `meta init`/`meta eject` use to read them.
17
+ export { resolveReferenceRoot, readReferenceTemplate, REFERENCE_GENERATOR_NAMES } from "./reference-templates.js";
5
18
  //# 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,8DAA8D;AAC9D,OAAO,EAAE,aAAa,EAA0B,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAyB,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAA6B,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,OAAO,EAAE,aAAa,EAA0B,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAyB,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAA6B,MAAM,yBAAyB,CAAC;AAEtF,gFAAgF;AAChF,kEAAkE;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,sFAAsF;AACtF,uFAAuF;AACvF,gFAAgF;AAChF,yBAAyB;AACzB,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAEnF,wEAAwE;AACxE,8EAA8E;AAC9E,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare const REFERENCE_GENERATOR_NAMES: readonly ["hooks", "grid", "grid-hook"];
2
+ export type ReferenceGeneratorName = (typeof REFERENCE_GENERATOR_NAMES)[number];
3
+ export declare function resolveReferenceRoot(): string;
4
+ export declare function readReferenceTemplate(name: ReferenceGeneratorName): string;
5
+ //# sourceMappingURL=reference-templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference-templates.d.ts","sourceRoot":"","sources":["../src/reference-templates.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,yBAAyB,yCAA0C,CAAC;AACjF,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC;AAIhF,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,sBAAsB,GAAG,MAAM,CAE1E"}
@@ -0,0 +1,12 @@
1
+ // FR-040 §4.1 — this package hosts its own copyable reference generators in
2
+ // `src/reference/`, read through the shared factory so the resolver is not duplicated.
3
+ import { makeReferenceReader } from "@metaobjectsdev/codegen-ts";
4
+ export const REFERENCE_GENERATOR_NAMES = ["hooks", "grid", "grid-hook"];
5
+ const reader = makeReferenceReader(import.meta.url, REFERENCE_GENERATOR_NAMES);
6
+ export function resolveReferenceRoot() {
7
+ return reader.resolveReferenceRoot();
8
+ }
9
+ export function readReferenceTemplate(name) {
10
+ return reader.readReferenceTemplate(name);
11
+ }
12
+ //# sourceMappingURL=reference-templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference-templates.js","sourceRoot":"","sources":["../src/reference-templates.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,uFAAuF;AACvF,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAU,CAAC;AAGjF,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,yBAAyB,CAAC,CAAC;AAE/E,MAAM,UAAU,oBAAoB;IAClC,OAAO,MAAM,CAAC,oBAAoB,EAAE,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAA4B;IAChE,OAAO,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tanstack-grid-hook.d.ts","sourceRoot":"","sources":["../src/tanstack-grid-hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAA6B,KAAK,gBAAgB,EAAyJ,MAAM,4BAA4B,CAAC;AAIrP,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAuDxB,gBAAgB,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"tanstack-grid-hook.d.ts","sourceRoot":"","sources":["../src/tanstack-grid-hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAA6B,KAAK,gBAAgB,EAExD,MAAM,4BAA4B,CAAC;AAIpC,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EA0DxB,gBAAgB,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC"}
@@ -1,4 +1,4 @@
1
- import { perEntity, formatTs, entityOutputPath, entityMetaFileName, renderEntityMetaFile, servesReadApi, isTphSubtype, CODEGEN_ATTR_EMIT_TANSTACK, CODEGEN_ATTR_EMIT_GRID } from "@metaobjectsdev/codegen-ts";
1
+ import { perEntity, formatTs, entityOutputPath, entityMetaFileName, renderEntityMetaFile, servesReadApi, isTphSubtype, CODEGEN_ATTR_EMIT_TANSTACK, CODEGEN_ATTR_EMIT_GRID, withClientDirective, } from "@metaobjectsdev/codegen-ts";
2
2
  import { hasDataGridLayout, warnMissingDataGridLayout } from "./data-grid-gate.js";
3
3
  import { renderGridHookFile } from "./templates/grid-hook-file.js";
4
4
  /**
@@ -42,7 +42,7 @@ export const tanstackGridHook = function tanstackGridHook(opts) {
42
42
  content: await formatTs(renderEntityMetaFile(entity, ctx.renderContext.apiPrefix)),
43
43
  }, {
44
44
  path: entityOutputPath(ctx.renderContext.outputLayout, entity.package, `${entity.name}.grid.ts`),
45
- content: await formatTs(renderGridHookFile(entity, ctx.renderContext)),
45
+ content: withClientDirective(await formatTs(renderGridHookFile(entity, ctx.renderContext)), ctx.renderContext.clientDirective),
46
46
  }];
47
47
  });
48
48
  const generator = {
@@ -1 +1 @@
1
- {"version":3,"file":"tanstack-grid-hook.js","sourceRoot":"","sources":["../src/tanstack-grid-hook.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAyC,QAAQ,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,aAAa,EAAE,YAAY,EAAE,0BAA0B,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACrP,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAOnE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,SAAS,gBAAgB,CAAC,IAA2B;IACnF,MAAM,UAAU,GAAG,IAAI,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAChD,gFAAgF;IAChF,iFAAiF;IACjF,gFAAgF;IAChF,0BAA0B;IAC1B,EAAE;IACF,sFAAsF;IACtF,wFAAwF;IACxF,yFAAyF;IACzF,uFAAuF;IACvF,oFAAoF;IACpF,mFAAmF;IACnF,sFAAsF;IACtF,yDAAyD;IACzD,MAAM,gBAAgB,GAAG,CAAC,CAAa,EAAW,EAAE,CAClD,aAAa,CAAC,CAAC,CAAC;QAChB,2FAA2F;WACxF,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,KAAK,KAAK;WAC5C,UAAU,CAAC,CAAC,CAAC;WACb,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,KAAK,IAAI,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,MAAkB,EAAE,GAAG,EAAE,EAAE;QACvD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;QACxF,CAAC;QACD,0EAA0E;QAC1E,8EAA8E;QAC9E,+EAA+E;QAC/E,+EAA+E;QAC/E,2BAA2B;QAC3B,OAAO,CAAC;gBACN,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,aAAa,CAAC,YAAY,EAAE,MAAM,CAAC,OAAO,EACnE,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAClC,OAAO,EAAE,MAAM,QAAQ,CAAC,oBAAoB,CAAC,MAAM,EAAE,GAAG,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;aACnF,EAAE;gBACD,IAAI,EAAE,gBAAgB,CACpB,GAAG,CAAC,aAAa,CAAC,YAAY,EAC9B,MAAM,CAAC,OAAO,EACd,GAAG,MAAM,CAAC,IAAI,UAAU,CACzB;gBACD,OAAO,EAAE,MAAM,QAAQ,CAAC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC;aACvE,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,SAAS,GAAc;QAC3B,IAAI,EAAE,oBAAoB;QAC1B,MAAM,EAAE,CAAC,CAAa,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC;QACtE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YACtB,yBAAyB,CAAC,GAAG,EAAE,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;YACrE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;KACF,CAAC;IACF,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;QACjB,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACjC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAkD,CAAC"}
1
+ {"version":3,"file":"tanstack-grid-hook.js","sourceRoot":"","sources":["../src/tanstack-grid-hook.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAyC,QAAQ,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,aAAa,EAAE,YAAY,EAAE,0BAA0B,EAAE,sBAAsB,EAC9M,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAOnE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,SAAS,gBAAgB,CAAC,IAA2B;IACnF,MAAM,UAAU,GAAG,IAAI,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAChD,gFAAgF;IAChF,iFAAiF;IACjF,gFAAgF;IAChF,0BAA0B;IAC1B,EAAE;IACF,sFAAsF;IACtF,wFAAwF;IACxF,yFAAyF;IACzF,uFAAuF;IACvF,oFAAoF;IACpF,mFAAmF;IACnF,sFAAsF;IACtF,yDAAyD;IACzD,MAAM,gBAAgB,GAAG,CAAC,CAAa,EAAW,EAAE,CAClD,aAAa,CAAC,CAAC,CAAC;QAChB,2FAA2F;WACxF,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,KAAK,KAAK;WAC5C,UAAU,CAAC,CAAC,CAAC;WACb,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,KAAK,IAAI,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,MAAkB,EAAE,GAAG,EAAE,EAAE;QACvD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;QACxF,CAAC;QACD,0EAA0E;QAC1E,8EAA8E;QAC9E,+EAA+E;QAC/E,+EAA+E;QAC/E,2BAA2B;QAC3B,OAAO,CAAC;gBACN,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,aAAa,CAAC,YAAY,EAAE,MAAM,CAAC,OAAO,EACnE,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAClC,OAAO,EAAE,MAAM,QAAQ,CAAC,oBAAoB,CAAC,MAAM,EAAE,GAAG,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;aACnF,EAAE;gBACD,IAAI,EAAE,gBAAgB,CACpB,GAAG,CAAC,aAAa,CAAC,YAAY,EAC9B,MAAM,CAAC,OAAO,EACd,GAAG,MAAM,CAAC,IAAI,UAAU,CACzB;gBACD,OAAO,EAAE,mBAAmB,CAC1B,MAAM,QAAQ,CAAC,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC,EAC7D,GAAG,CAAC,aAAa,CAAC,eAAe,CAClC;aACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,SAAS,GAAc;QAC3B,IAAI,EAAE,oBAAoB;QAC1B,MAAM,EAAE,CAAC,CAAa,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC;QACtE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YACtB,yBAAyB,CAAC,GAAG,EAAE,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;YACrE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;KACF,CAAC;IACF,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;QACjB,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACjC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAkD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tanstack-grid.d.ts","sourceRoot":"","sources":["../src/tanstack-grid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAA6B,KAAK,gBAAgB,EAA+G,MAAM,4BAA4B,CAAC;AAI3M,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAqCpB,gBAAgB,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"tanstack-grid.d.ts","sourceRoot":"","sources":["../src/tanstack-grid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAA6B,KAAK,gBAAgB,EAExD,MAAM,4BAA4B,CAAC;AAIpC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAwCpB,gBAAgB,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC"}
@@ -1,4 +1,4 @@
1
- import { perEntity, formatTs, entityOutputPath, servesReadApi, isTphSubtype, CODEGEN_ATTR_EMIT_TANSTACK, CODEGEN_ATTR_EMIT_GRID } from "@metaobjectsdev/codegen-ts";
1
+ import { perEntity, formatTs, entityOutputPath, servesReadApi, isTphSubtype, CODEGEN_ATTR_EMIT_TANSTACK, CODEGEN_ATTR_EMIT_GRID, withClientDirective, } from "@metaobjectsdev/codegen-ts";
2
2
  import { hasDataGridLayout, warnMissingDataGridLayout } from "./data-grid-gate.js";
3
3
  import { renderColumnsFile } from "./templates/columns-file.js";
4
4
  /**
@@ -27,7 +27,7 @@ export const tanstackGrid = function tanstackGrid(opts) {
27
27
  }
28
28
  return {
29
29
  path: entityOutputPath(ctx.renderContext.outputLayout, entity.package, `${entity.name}.columns.tsx`),
30
- content: await formatTs(renderColumnsFile(entity, ctx.renderContext)),
30
+ content: withClientDirective(await formatTs(renderColumnsFile(entity, ctx.renderContext)), ctx.renderContext.clientDirective),
31
31
  };
32
32
  });
33
33
  const generator = {
@@ -1 +1 @@
1
- {"version":3,"file":"tanstack-grid.js","sourceRoot":"","sources":["../src/tanstack-grid.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAyC,QAAQ,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,0BAA0B,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAC3M,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAOhE;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,SAAS,YAAY,CAAC,IAAuB;IACvE,MAAM,UAAU,GAAG,IAAI,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAChD,gFAAgF;IAChF,2EAA2E;IAC3E,0EAA0E;IAC1E,iFAAiF;IACjF,kFAAkF;IAClF,0BAA0B;IAC1B,iFAAiF;IACjF,iFAAiF;IACjF,MAAM,gBAAgB,GAAG,CAAC,CAAa,EAAW,EAAE,CAClD,aAAa,CAAC,CAAC,CAAC;QAChB,2FAA2F;WACxF,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,KAAK,KAAK;WAC5C,UAAU,CAAC,CAAC,CAAC;WACb,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,KAAK,IAAI,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,MAAkB,EAAE,GAAG,EAAE,EAAE;QACvD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;QACnF,CAAC;QACD,OAAO;YACL,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,aAAa,CAAC,YAAY,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,cAAc,CAAC;YACpG,OAAO,EAAE,MAAM,QAAQ,CAAC,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC;SACtE,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,MAAM,SAAS,GAAc;QAC3B,IAAI,EAAE,eAAe;QACrB,MAAM,EAAE,CAAC,CAAa,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC;QACtE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YACtB,yBAAyB,CAAC,GAAG,EAAE,gBAAgB,EAAE,sBAAsB,CAAC,CAAC;YACzE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;KACF,CAAC;IACF,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;QACjB,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACjC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAA8C,CAAC"}
1
+ {"version":3,"file":"tanstack-grid.js","sourceRoot":"","sources":["../src/tanstack-grid.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAyC,QAAQ,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,0BAA0B,EAAE,sBAAsB,EACpK,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAOhE;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,SAAS,YAAY,CAAC,IAAuB;IACvE,MAAM,UAAU,GAAG,IAAI,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAChD,gFAAgF;IAChF,2EAA2E;IAC3E,0EAA0E;IAC1E,iFAAiF;IACjF,kFAAkF;IAClF,0BAA0B;IAC1B,iFAAiF;IACjF,iFAAiF;IACjF,MAAM,gBAAgB,GAAG,CAAC,CAAa,EAAW,EAAE,CAClD,aAAa,CAAC,CAAC,CAAC;QAChB,2FAA2F;WACxF,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,KAAK,KAAK;WAC5C,UAAU,CAAC,CAAC,CAAC;WACb,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,KAAK,IAAI,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,MAAkB,EAAE,GAAG,EAAE,EAAE;QACvD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;QACnF,CAAC;QACD,OAAO;YACL,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,aAAa,CAAC,YAAY,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,cAAc,CAAC;YACpG,OAAO,EAAE,mBAAmB,CAC1B,MAAM,QAAQ,CAAC,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC,EAC5D,GAAG,CAAC,aAAa,CAAC,eAAe,CAClC;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,MAAM,SAAS,GAAc;QAC3B,IAAI,EAAE,eAAe;QACrB,MAAM,EAAE,CAAC,CAAa,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC;QACtE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YACtB,yBAAyB,CAAC,GAAG,EAAE,gBAAgB,EAAE,sBAAsB,CAAC,CAAC;YACzE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;KACF,CAAC;IACF,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;QACjB,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACjC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAA8C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tanstack-query.d.ts","sourceRoot":"","sources":["../src/tanstack-query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAA6B,KAAK,gBAAgB,EAAiI,MAAM,4BAA4B,CAAC;AAG7N,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,EAqCrB,gBAAgB,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"tanstack-query.d.ts","sourceRoot":"","sources":["../src/tanstack-query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAA6B,KAAK,gBAAgB,EAExD,MAAM,4BAA4B,CAAC;AAGpC,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,EA0CrB,gBAAgB,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC"}
@@ -1,4 +1,4 @@
1
- import { perEntity, formatTs, entityOutputPath, entityMetaFileName, renderEntityMetaFile, servesReadApi, isTphSubtype, CODEGEN_ATTR_EMIT_TANSTACK } from "@metaobjectsdev/codegen-ts";
1
+ import { perEntity, formatTs, entityOutputPath, entityMetaFileName, renderEntityMetaFile, servesReadApi, isTphSubtype, CODEGEN_ATTR_EMIT_TANSTACK, withClientDirective, } from "@metaobjectsdev/codegen-ts";
2
2
  import { renderHooksFile } from "./templates/hooks-file.js";
3
3
  /**
4
4
  * Per-entity generator that emits <Entity>.hooks.ts — a query-key factory
@@ -33,7 +33,9 @@ export const tanstackQuery = function tanstackQuery(opts) {
33
33
  };
34
34
  return [metaFile, {
35
35
  path: entityOutputPath(ctx.renderContext.outputLayout, entity.package, `${entity.name}.hooks.ts`),
36
- content: await formatTs(renderHooksFile(entity, ctx.renderContext)),
36
+ // Outside formatTs deliberately: the directive must stay the module's first
37
+ // token, and a formatter is entitled to move a leading string expression.
38
+ content: withClientDirective(await formatTs(renderHooksFile(entity, ctx.renderContext)), ctx.renderContext.clientDirective),
37
39
  }];
38
40
  }),
39
41
  };
@@ -1 +1 @@
1
- {"version":3,"file":"tanstack-query.js","sourceRoot":"","sources":["../src/tanstack-query.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAyC,QAAQ,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,aAAa,EAAE,YAAY,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAC7N,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAO5D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,SAAS,aAAa,CAAC,IAAwB;IAC1E,MAAM,UAAU,GAAG,IAAI,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,SAAS,GAAc;QAC3B,IAAI,EAAE,gBAAgB;QACtB,6EAA6E;QAC7E,6EAA6E;QAC7E,6EAA6E;QAC7E,0EAA0E;QAC1E,+EAA+E;QAC/E,iFAAiF;QACjF,iFAAiF;QACjF,MAAM,EAAE,CAAC,CAAa,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,KAAK,KAAK,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC;QAChI,QAAQ,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;YACxC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;YACJ,CAAC,CAAM,0EAA0E;YACjF,yEAAyE;YACzE,+EAA+E;YAC/E,gFAAgF;YAChF,qCAAqC;YACrC,MAAM,QAAQ,GAAG;gBACf,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,aAAa,CAAC,YAAY,EAAE,MAAM,CAAC,OAAO,EACnE,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAClC,OAAO,EAAE,MAAM,QAAQ,CAAC,oBAAoB,CAAC,MAAM,EAAE,GAAG,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;aACnF,CAAC;YACF,OAAO,CAAC,QAAQ,EAAE;oBAChB,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,aAAa,CAAC,YAAY,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,WAAW,CAAC;oBACjG,OAAO,EAAE,MAAM,QAAQ,CAAC,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC;iBACpE,CAAC,CAAC;QACL,CAAC,CAAC;KACH,CAAC;IACF,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;QACjB,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACjC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAA+C,CAAC"}
1
+ {"version":3,"file":"tanstack-query.js","sourceRoot":"","sources":["../src/tanstack-query.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAyC,QAAQ,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,aAAa,EAAE,YAAY,EAAE,0BAA0B,EACtL,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAO5D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,SAAS,aAAa,CAAC,IAAwB;IAC1E,MAAM,UAAU,GAAG,IAAI,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,SAAS,GAAc;QAC3B,IAAI,EAAE,gBAAgB;QACtB,6EAA6E;QAC7E,6EAA6E;QAC7E,6EAA6E;QAC7E,0EAA0E;QAC1E,+EAA+E;QAC/E,iFAAiF;QACjF,iFAAiF;QACjF,MAAM,EAAE,CAAC,CAAa,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,KAAK,KAAK,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC;QAChI,QAAQ,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;YACxC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;YACJ,CAAC,CAAM,0EAA0E;YACjF,yEAAyE;YACzE,+EAA+E;YAC/E,gFAAgF;YAChF,qCAAqC;YACrC,MAAM,QAAQ,GAAG;gBACf,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,aAAa,CAAC,YAAY,EAAE,MAAM,CAAC,OAAO,EACnE,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAClC,OAAO,EAAE,MAAM,QAAQ,CAAC,oBAAoB,CAAC,MAAM,EAAE,GAAG,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;aACnF,CAAC;YACF,OAAO,CAAC,QAAQ,EAAE;oBAChB,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,aAAa,CAAC,YAAY,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,WAAW,CAAC;oBACjG,4EAA4E;oBAC5E,0EAA0E;oBAC1E,OAAO,EAAE,mBAAmB,CAC1B,MAAM,QAAQ,CAAC,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC,EAC1D,GAAG,CAAC,aAAa,CAAC,eAAe,CAClC;iBACF,CAAC,CAAC;QACL,CAAC,CAAC;KACH,CAAC;IACF,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;QACjB,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACjC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAA+C,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metaobjectsdev/codegen-ts-tanstack",
3
- "version": "0.24.4",
3
+ "version": "0.24.5",
4
4
  "description": "TanStack codegen for metaobjects — TanStack Query hooks for every entity, plus TanStack Table column definitions and grid-state hooks for entities declaring a layout.dataGrid.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -44,8 +44,8 @@
44
44
  "access": "public"
45
45
  },
46
46
  "dependencies": {
47
- "@metaobjectsdev/metadata": "0.24.4",
48
- "@metaobjectsdev/codegen-ts": "0.24.4",
47
+ "@metaobjectsdev/metadata": "0.24.5",
48
+ "@metaobjectsdev/codegen-ts": "0.24.5",
49
49
  "ts-poet": "^6.10.0"
50
50
  },
51
51
  "peerDependencies": {
package/src/index.ts CHANGED
@@ -2,3 +2,22 @@
2
2
  export { tanstackQuery, type TanstackQueryOpts } from "./tanstack-query.js";
3
3
  export { tanstackGrid, type TanstackGridOpts } from "./tanstack-grid.js";
4
4
  export { tanstackGridHook, type TanstackGridHookOpts } from "./tanstack-grid-hook.js";
5
+
6
+ // FR-040 §4.2(b) — public so an owned generator composes the engine rather than
7
+ // forking it. Signatures are stable API: (entity, ctx) => string.
8
+ export { renderHooksFile } from "./templates/hooks-file.js";
9
+ export { renderColumnsFile } from "./templates/columns-file.js";
10
+ export { renderGridHookFile } from "./templates/grid-hook-file.js";
11
+
12
+ // FR-040 §4.2(b) — the grid/grid-hook data-grid opt-in gate is a STEP in the pipeline
13
+ // those two owned templates compose, not an internal detail either may fork. Public so
14
+ // `grid.ts` and `grid-hook.ts` import one shared implementation instead of each
15
+ // carrying its own copy.
16
+ export { hasDataGridLayout, warnMissingDataGridLayout } from "./data-grid-gate.js";
17
+
18
+ // FR-040 §4.1 — the copyable reference generators this package ships in
19
+ // `src/reference/`, and the reader `meta init`/`meta eject` use to read them.
20
+ export { resolveReferenceRoot, readReferenceTemplate, REFERENCE_GENERATOR_NAMES } from "./reference-templates.js";
21
+ // The name union travels with the names array — codegen-ts exports both, and a
22
+ // consumer keying anything by ejectable name needs the type as much as the values.
23
+ export type { ReferenceGeneratorName } from "./reference-templates.js";
@@ -0,0 +1,114 @@
1
+ // REFERENCE TEMPLATE — copy this into your repo (e.g. codegen/generators/grid-hook.ts) and own it.
2
+ // Then import it LOCALLY in metaobjects.config.ts:
3
+ // import { tanstackGridHook } from "./codegen/generators/grid-hook.js";
4
+ //
5
+ // RUNTIME: this file executes under whatever runs `meta gen` — NODE, even in a Bun
6
+ // project. Do not reach for `Bun.*` globals here.
7
+ // targets: TanStack Query. The emitted hook calls `useEntityFetcher()` from
8
+ // `@metaobjectsdev/tanstack`, so the module is a CLIENT component.
9
+ // If your framework compiles server and client from one tree and resolves
10
+ // each half under different conditions, the emitted file may need a marker
11
+ // directive — prepend it to `renderGridHookFile`'s result below. That is a
12
+ // one-line change in THIS file and is the intended way to do it.
13
+ // use-when: you want a use<Entity><Grid>Grid() state hook — sort/filter/pagination
14
+ // wired to TanStack Query — for each `layout.dataGrid` an entity declares.
15
+ // emits: <target>/<Entity>.grid.ts, plus the DB-free <Entity>.meta.ts descriptor
16
+ // the hook module imports from. Emissions byte-identical to another UI
17
+ // generator's copy of the same descriptor collapse to one file (#266).
18
+ // customize: this generator is YOURS. `renderGridHookFile` (exported from
19
+ // @metaobjectsdev/codegen-ts-tanstack) produces the hook body — wrap it,
20
+ // prepend to it, or replace the call entirely with your own renderer.
21
+ // composes-with: grid.ts (the column definitions this hook's grid state pairs with).
22
+
23
+ import { type MetaObject } from "@metaobjectsdev/metadata";
24
+ import {
25
+ perEntity,
26
+ type Generator,
27
+ type GeneratorFactory,
28
+ formatTs,
29
+ entityOutputPath,
30
+ entityMetaFileName,
31
+ renderEntityMetaFile,
32
+ servesReadApi,
33
+ isTphSubtype,
34
+ CODEGEN_ATTR_EMIT_TANSTACK,
35
+ CODEGEN_ATTR_EMIT_GRID,
36
+ withClientDirective,
37
+ } from "@metaobjectsdev/codegen-ts";
38
+ import {
39
+ renderGridHookFile,
40
+ hasDataGridLayout,
41
+ warnMissingDataGridLayout,
42
+ } from "@metaobjectsdev/codegen-ts-tanstack";
43
+
44
+ export interface TanstackGridHookOpts {
45
+ filter?: (entity: MetaObject) => boolean;
46
+ target?: string;
47
+ }
48
+
49
+ /**
50
+ * Per-entity generator that emits <Entity>.grid.ts — one
51
+ * use<Entity><Grid>Grid() hook per layout[dataGrid] declared on the entity.
52
+ *
53
+ * Per-entity opt-out via @emitTanstack: false. Per-entity opt-IN: presence of
54
+ * at least one dataGrid layout on the object (mirrors tanstackGrid).
55
+ */
56
+ export const tanstackGridHook = function tanstackGridHook(opts?: TanstackGridHookOpts): Generator {
57
+ const userFilter = opts?.filter ?? (() => true);
58
+ // Every gate EXCEPT the dataGrid-layout opt-in: the framework instance-artifact
59
+ // guard (skips abstract types), the metadata opt-out, and the user filter. Split
60
+ // out so the discoverability note can name exactly the entities the LAYOUT gate
61
+ // alone held back (#287).
62
+ //
63
+ // The TPH clause must MATCH tanstackGrid's exactly. A TPH subtype inherits its base's
64
+ // dataGrid layout via extends, so `hasDataGridLayout` is true for it — but tanstackGrid
65
+ // deliberately emits no per-subtype columns without an own `@emitGrid: true` (the base's
66
+ // polymorphic grid is the single source of truth). Without the same clause here, a TPH
67
+ // subtype got a `<Sub>.grid.ts` whose sibling `<Sub>.columns.tsx` is never emitted:
68
+ // a dangling `use<Sub>DefaultGrid()` with nothing to pair it with, and an outright
69
+ // TS2307 when the inherited layout carries an `@filter` preset (the hook then imports
70
+ // `<sub>DefaultFilter` from the missing columns module).
71
+ const passesOtherGates = (e: MetaObject): boolean =>
72
+ servesReadApi(e)
73
+ // ADR-0039: resolving — a concrete entity may inherit its @emit* opt-out flag via extends.
74
+ && e.attr(CODEGEN_ATTR_EMIT_TANSTACK) !== false
75
+ && userFilter(e)
76
+ && (!isTphSubtype(e) || e.attr(CODEGEN_ATTR_EMIT_GRID) === true);
77
+ const emit = perEntity(async (entity: MetaObject, ctx) => {
78
+ if (!ctx.renderContext) {
79
+ throw new Error("tanstack-grid-hook: renderContext is required (provided by runGen)");
80
+ }
81
+ // Also emit the DB-free descriptor module this file imports from. Each UI
82
+ // generator emits it rather than relying on the consumer wiring an extra one:
83
+ // the entity generator is scaffold-and-own (ADR-0034), so it cannot be changed
84
+ // from the package. Emissions are byte-identical between generators, which the
85
+ // runner collapses (#266).
86
+ return [{
87
+ path: entityOutputPath(ctx.renderContext.outputLayout, entity.package,
88
+ entityMetaFileName(entity.name)),
89
+ content: await formatTs(renderEntityMetaFile(entity, ctx.renderContext.apiPrefix)),
90
+ }, {
91
+ path: entityOutputPath(
92
+ ctx.renderContext.outputLayout,
93
+ entity.package,
94
+ `${entity.name}.grid.ts`,
95
+ ),
96
+ content: withClientDirective(
97
+ await formatTs(renderGridHookFile(entity, ctx.renderContext)),
98
+ ctx.renderContext.clientDirective,
99
+ ),
100
+ }];
101
+ });
102
+ const generator: Generator = {
103
+ name: "tanstack-grid-hook",
104
+ filter: (e: MetaObject) => passesOtherGates(e) && hasDataGridLayout(e),
105
+ generate: async (ctx) => {
106
+ warnMissingDataGridLayout(ctx, passesOtherGates, "<Entity>.grid.ts");
107
+ return emit(ctx);
108
+ },
109
+ };
110
+ if (opts?.target) {
111
+ generator.target = opts.target;
112
+ }
113
+ return generator;
114
+ } as GeneratorFactory<TanstackGridHookOpts | void>;
@@ -0,0 +1,93 @@
1
+ // REFERENCE TEMPLATE — copy this into your repo (e.g. codegen/generators/grid.ts) and own it.
2
+ // Then import it LOCALLY in metaobjects.config.ts:
3
+ // import { tanstackGrid } from "./codegen/generators/grid.js";
4
+ //
5
+ // RUNTIME: this file executes under whatever runs `meta gen` — NODE, even in a Bun
6
+ // project. Do not reach for `Bun.*` globals here.
7
+ // targets: TanStack Table. The emitted module's `ColumnDef` comes from
8
+ // `@tanstack/react-table`, so it is a CLIENT component.
9
+ // If your framework compiles server and client from one tree and resolves
10
+ // each half under different conditions, the emitted file may need a marker
11
+ // directive — prepend it to `renderColumnsFile`'s result below. That is a
12
+ // one-line change in THIS file and is the intended way to do it.
13
+ // use-when: you want generated grid column definitions for any entity declaring a
14
+ // `layout.dataGrid` child.
15
+ // emits: <target>/<Entity>.columns.tsx — one column set per declared dataGrid
16
+ // layout; a TPH discriminator base's grid folds in its subtypes' fields.
17
+ // customize: this generator is YOURS. `renderColumnsFile` (exported from
18
+ // @metaobjectsdev/codegen-ts-tanstack) produces the column definitions —
19
+ // wrap it, prepend to it, or replace the call entirely with your own
20
+ // renderer.
21
+ // composes-with: entity.ts (imports the Row type the columns are typed against),
22
+ // hooks.ts (the query hook a grid usually pairs with).
23
+
24
+ import { type MetaObject } from "@metaobjectsdev/metadata";
25
+ import {
26
+ perEntity,
27
+ type Generator,
28
+ type GeneratorFactory,
29
+ formatTs,
30
+ entityOutputPath,
31
+ servesReadApi,
32
+ isTphSubtype,
33
+ CODEGEN_ATTR_EMIT_TANSTACK,
34
+ CODEGEN_ATTR_EMIT_GRID,
35
+ withClientDirective,
36
+ } from "@metaobjectsdev/codegen-ts";
37
+ import {
38
+ renderColumnsFile,
39
+ hasDataGridLayout,
40
+ warnMissingDataGridLayout,
41
+ } from "@metaobjectsdev/codegen-ts-tanstack";
42
+
43
+ export interface TanstackGridOpts {
44
+ filter?: (entity: MetaObject) => boolean;
45
+ target?: string;
46
+ }
47
+
48
+ /**
49
+ * Per-entity opt-out via `@emitTanstack: false`. Per-entity opt-IN: presence of
50
+ * at least one `dataGrid` layout on the object. If both pass and the user-supplied
51
+ * filter passes, the generator emits.
52
+ */
53
+ export const tanstackGrid = function tanstackGrid(opts?: TanstackGridOpts): Generator {
54
+ const userFilter = opts?.filter ?? (() => true);
55
+ // Every gate EXCEPT the dataGrid-layout opt-in: the framework instance-artifact
56
+ // guard (skips abstract types), the metadata opt-out, and the user filter.
57
+ // FR-017 Tier 3: a TPH discriminator base emits ONE polymorphic grid. Its
58
+ // subtypes inherit the base's dataGrid layout via extends, but per-subtype grids
59
+ // are opt-IN only (own `@emitGrid: true`) — otherwise the polymorphic grid is the
60
+ // single source of truth.
61
+ // Split out so the discoverability note can name exactly the entities the LAYOUT
62
+ // gate alone held back (#287) — an opted-out or abstract type is not a surprise.
63
+ const passesOtherGates = (e: MetaObject): boolean =>
64
+ servesReadApi(e)
65
+ // ADR-0039: resolving — a concrete entity may inherit its @emit* opt-out flag via extends.
66
+ && e.attr(CODEGEN_ATTR_EMIT_TANSTACK) !== false
67
+ && userFilter(e)
68
+ && (!isTphSubtype(e) || e.attr(CODEGEN_ATTR_EMIT_GRID) === true);
69
+ const emit = perEntity(async (entity: MetaObject, ctx) => {
70
+ if (!ctx.renderContext) {
71
+ throw new Error("tanstack-grid: renderContext is required (provided by runGen)");
72
+ }
73
+ return {
74
+ path: entityOutputPath(ctx.renderContext.outputLayout, entity.package, `${entity.name}.columns.tsx`),
75
+ content: withClientDirective(
76
+ await formatTs(renderColumnsFile(entity, ctx.renderContext)),
77
+ ctx.renderContext.clientDirective,
78
+ ),
79
+ };
80
+ });
81
+ const generator: Generator = {
82
+ name: "tanstack-grid",
83
+ filter: (e: MetaObject) => passesOtherGates(e) && hasDataGridLayout(e),
84
+ generate: async (ctx) => {
85
+ warnMissingDataGridLayout(ctx, passesOtherGates, "<Entity>.columns.tsx");
86
+ return emit(ctx);
87
+ },
88
+ };
89
+ if (opts?.target) {
90
+ generator.target = opts.target;
91
+ }
92
+ return generator;
93
+ } as GeneratorFactory<TanstackGridOpts | void>;
@@ -0,0 +1,93 @@
1
+ // REFERENCE TEMPLATE — copy this into your repo (e.g. codegen/generators/hooks.ts) and own it.
2
+ // Then import it LOCALLY in metaobjects.config.ts:
3
+ // import { tanstackQuery } from "./codegen/generators/hooks.js";
4
+ //
5
+ // RUNTIME: this file executes under whatever runs `meta gen` — NODE, even in a Bun
6
+ // project. Do not reach for `Bun.*` globals here.
7
+ // targets: TanStack Query. The emitted hooks call `useEntityFetcher()` from
8
+ // `@metaobjectsdev/tanstack`, so the module is a CLIENT component.
9
+ // If your framework compiles server and client from one tree and resolves
10
+ // each half under different conditions, the emitted file may need a marker
11
+ // directive — prepend it to `renderHooksFile`'s result below. That is a
12
+ // one-line change in THIS file and is the intended way to do it.
13
+ // use-when: you want a query-key factory plus 2 query hooks and 3 mutation hooks,
14
+ // backed by TanStack Query, per entity.
15
+ // emits: <target>/<Entity>.hooks.ts, plus the DB-free <Entity>.meta.ts descriptor
16
+ // the hooks module imports from. Emissions byte-identical to another UI
17
+ // generator's copy of the same descriptor collapse to one file (#266).
18
+ // customize: this generator is YOURS. `renderHooksFile` (exported from
19
+ // @metaobjectsdev/codegen-ts-tanstack) produces the hooks body — wrap it,
20
+ // prepend to it, or replace the call entirely with your own renderer.
21
+ // composes-with: entity.ts (imports the table/schemas these hooks fetch/validate against).
22
+
23
+ import { type MetaObject } from "@metaobjectsdev/metadata";
24
+ import {
25
+ perEntity,
26
+ type Generator,
27
+ type GeneratorFactory,
28
+ formatTs,
29
+ entityOutputPath,
30
+ entityMetaFileName,
31
+ renderEntityMetaFile,
32
+ servesReadApi,
33
+ isTphSubtype,
34
+ CODEGEN_ATTR_EMIT_TANSTACK,
35
+ withClientDirective,
36
+ } from "@metaobjectsdev/codegen-ts";
37
+ import { renderHooksFile } from "@metaobjectsdev/codegen-ts-tanstack";
38
+
39
+ export interface TanstackQueryOpts {
40
+ filter?: (entity: MetaObject) => boolean;
41
+ target?: string;
42
+ }
43
+
44
+ /**
45
+ * Per-entity generator that emits <Entity>.hooks.ts — a query-key factory
46
+ * plus 2 query hooks and 3 mutation hooks backed by useEntityFetcher().
47
+ *
48
+ * Per-entity opt-out via `@emitTanstack: false` is honored. If the user
49
+ * supplies their own filter, both must pass (AND).
50
+ */
51
+ export const tanstackQuery = function tanstackQuery(opts?: TanstackQueryOpts): Generator {
52
+ const userFilter = opts?.filter ?? (() => true);
53
+ const generator: Generator = {
54
+ name: "tanstack-query",
55
+ // AND-composes the framework instance-artifact guard (skips abstract types —
56
+ // they contribute shape via inheritance only and have no instance to query),
57
+ // the metadata opt-out, and the optional user filter. Projections still pass
58
+ // here and get read-only hooks via renderHooksFile's isProjection branch.
59
+ // FR-017 Tier 3: TPH subtypes get no standalone hooks file — their per-subtype
60
+ // hooks live in the discriminator base's hooks file (polymorphic + per-subtype).
61
+ // ADR-0039: resolving — a concrete entity may inherit @emitTanstack via extends.
62
+ filter: (e: MetaObject) => servesReadApi(e) && e.attr(CODEGEN_ATTR_EMIT_TANSTACK) !== false && !isTphSubtype(e) && userFilter(e),
63
+ generate: perEntity(async (entity, ctx) => {
64
+ if (!ctx.renderContext) {
65
+ throw new Error(
66
+ "tanstack-query: renderContext is required (provided by runGen)",
67
+ );
68
+ } // Also emit the DB-free descriptor module this file imports from. Each UI
69
+ // generator emits it rather than relying on the consumer wiring an extra
70
+ // generator: the entity generator is scaffold-and-own (ADR-0034), so it cannot
71
+ // be changed from the package. Emissions are byte-identical between generators,
72
+ // which the runner collapses (#266).
73
+ const metaFile = {
74
+ path: entityOutputPath(ctx.renderContext.outputLayout, entity.package,
75
+ entityMetaFileName(entity.name)),
76
+ content: await formatTs(renderEntityMetaFile(entity, ctx.renderContext.apiPrefix)),
77
+ };
78
+ return [metaFile, {
79
+ path: entityOutputPath(ctx.renderContext.outputLayout, entity.package, `${entity.name}.hooks.ts`),
80
+ // Outside formatTs deliberately: the directive must stay the module's first
81
+ // token, and a formatter is entitled to move a leading string expression.
82
+ content: withClientDirective(
83
+ await formatTs(renderHooksFile(entity, ctx.renderContext)),
84
+ ctx.renderContext.clientDirective,
85
+ ),
86
+ }];
87
+ }),
88
+ };
89
+ if (opts?.target) {
90
+ generator.target = opts.target;
91
+ }
92
+ return generator;
93
+ } as GeneratorFactory<TanstackQueryOpts | void>;
@@ -0,0 +1,16 @@
1
+ // FR-040 §4.1 — this package hosts its own copyable reference generators in
2
+ // `src/reference/`, read through the shared factory so the resolver is not duplicated.
3
+ import { makeReferenceReader } from "@metaobjectsdev/codegen-ts";
4
+
5
+ export const REFERENCE_GENERATOR_NAMES = ["hooks", "grid", "grid-hook"] as const;
6
+ export type ReferenceGeneratorName = (typeof REFERENCE_GENERATOR_NAMES)[number];
7
+
8
+ const reader = makeReferenceReader(import.meta.url, REFERENCE_GENERATOR_NAMES);
9
+
10
+ export function resolveReferenceRoot(): string {
11
+ return reader.resolveReferenceRoot();
12
+ }
13
+
14
+ export function readReferenceTemplate(name: ReferenceGeneratorName): string {
15
+ return reader.readReferenceTemplate(name);
16
+ }
@@ -1,5 +1,7 @@
1
1
  import type { MetaObject } from "@metaobjectsdev/metadata";
2
- import { perEntity, type Generator, type GeneratorFactory, formatTs, entityOutputPath, entityMetaFileName, renderEntityMetaFile, servesReadApi, isTphSubtype, CODEGEN_ATTR_EMIT_TANSTACK, CODEGEN_ATTR_EMIT_GRID } from "@metaobjectsdev/codegen-ts";
2
+ import { perEntity, type Generator, type GeneratorFactory, formatTs, entityOutputPath, entityMetaFileName, renderEntityMetaFile, servesReadApi, isTphSubtype, CODEGEN_ATTR_EMIT_TANSTACK, CODEGEN_ATTR_EMIT_GRID,
3
+ withClientDirective,
4
+ } from "@metaobjectsdev/codegen-ts";
3
5
  import { hasDataGridLayout, warnMissingDataGridLayout } from "./data-grid-gate.js";
4
6
  import { renderGridHookFile } from "./templates/grid-hook-file.js";
5
7
 
@@ -55,7 +57,10 @@ export const tanstackGridHook = function tanstackGridHook(opts?: TanstackGridHoo
55
57
  entity.package,
56
58
  `${entity.name}.grid.ts`,
57
59
  ),
58
- content: await formatTs(renderGridHookFile(entity, ctx.renderContext)),
60
+ content: withClientDirective(
61
+ await formatTs(renderGridHookFile(entity, ctx.renderContext)),
62
+ ctx.renderContext.clientDirective,
63
+ ),
59
64
  }];
60
65
  });
61
66
  const generator: Generator = {
@@ -1,5 +1,7 @@
1
1
  import type { MetaObject } from "@metaobjectsdev/metadata";
2
- import { perEntity, type Generator, type GeneratorFactory, formatTs, entityOutputPath, servesReadApi, isTphSubtype, CODEGEN_ATTR_EMIT_TANSTACK, CODEGEN_ATTR_EMIT_GRID } from "@metaobjectsdev/codegen-ts";
2
+ import { perEntity, type Generator, type GeneratorFactory, formatTs, entityOutputPath, servesReadApi, isTphSubtype, CODEGEN_ATTR_EMIT_TANSTACK, CODEGEN_ATTR_EMIT_GRID,
3
+ withClientDirective,
4
+ } from "@metaobjectsdev/codegen-ts";
3
5
  import { hasDataGridLayout, warnMissingDataGridLayout } from "./data-grid-gate.js";
4
6
  import { renderColumnsFile } from "./templates/columns-file.js";
5
7
 
@@ -35,7 +37,10 @@ export const tanstackGrid = function tanstackGrid(opts?: TanstackGridOpts): Gene
35
37
  }
36
38
  return {
37
39
  path: entityOutputPath(ctx.renderContext.outputLayout, entity.package, `${entity.name}.columns.tsx`),
38
- content: await formatTs(renderColumnsFile(entity, ctx.renderContext)),
40
+ content: withClientDirective(
41
+ await formatTs(renderColumnsFile(entity, ctx.renderContext)),
42
+ ctx.renderContext.clientDirective,
43
+ ),
39
44
  };
40
45
  });
41
46
  const generator: Generator = {
@@ -1,5 +1,7 @@
1
1
  import type { MetaObject } from "@metaobjectsdev/metadata";
2
- import { perEntity, type Generator, type GeneratorFactory, formatTs, entityOutputPath, entityMetaFileName, renderEntityMetaFile, servesReadApi, isTphSubtype, CODEGEN_ATTR_EMIT_TANSTACK } from "@metaobjectsdev/codegen-ts";
2
+ import { perEntity, type Generator, type GeneratorFactory, formatTs, entityOutputPath, entityMetaFileName, renderEntityMetaFile, servesReadApi, isTphSubtype, CODEGEN_ATTR_EMIT_TANSTACK,
3
+ withClientDirective,
4
+ } from "@metaobjectsdev/codegen-ts";
3
5
  import { renderHooksFile } from "./templates/hooks-file.js";
4
6
 
5
7
  export interface TanstackQueryOpts {
@@ -43,7 +45,12 @@ export const tanstackQuery = function tanstackQuery(opts?: TanstackQueryOpts): G
43
45
  };
44
46
  return [metaFile, {
45
47
  path: entityOutputPath(ctx.renderContext.outputLayout, entity.package, `${entity.name}.hooks.ts`),
46
- content: await formatTs(renderHooksFile(entity, ctx.renderContext)),
48
+ // Outside formatTs deliberately: the directive must stay the module's first
49
+ // token, and a formatter is entitled to move a leading string expression.
50
+ content: withClientDirective(
51
+ await formatTs(renderHooksFile(entity, ctx.renderContext)),
52
+ ctx.renderContext.clientDirective,
53
+ ),
47
54
  }];
48
55
  }),
49
56
  };