@metaobjectsdev/codegen-ts-react 0.24.3 → 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 +8 -0
- package/dist/form-file.d.ts.map +1 -1
- package/dist/form-file.js +2 -2
- package/dist/form-file.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/reference-templates.d.ts +5 -0
- package/dist/reference-templates.d.ts.map +1 -0
- package/dist/reference-templates.js +12 -0
- package/dist/reference-templates.js.map +1 -0
- package/package.json +3 -3
- package/src/form-file.ts +5 -2
- package/src/index.ts +11 -0
- package/src/reference/form.ts +92 -0
- package/src/reference-templates.ts +16 -0
package/README.md
CHANGED
|
@@ -26,6 +26,14 @@ export default defineConfig({
|
|
|
26
26
|
targets". The form imports the entity module from wherever `entityFile()` is
|
|
27
27
|
routed (relative when same target, the entity-module target's `importBase` when not).
|
|
28
28
|
|
|
29
|
+
### The generator is yours
|
|
30
|
+
|
|
31
|
+
`formFile()` has a reference template: `meta eject form` copies it into `codegen/generators/form.ts`
|
|
32
|
+
for you to own. The emitted component is React with react-hook-form — if your framework needs a
|
|
33
|
+
marker directive or a different import shape, compose the exported renderer and change that one
|
|
34
|
+
step. Inside the ejected file's existing `if (!ctx.renderContext) throw …` guard, change only the
|
|
35
|
+
`content:` line: `content: '"use client";\n' + renderFormFile(entity, ctx.renderContext)`.
|
|
36
|
+
|
|
29
37
|
## Pairs with
|
|
30
38
|
|
|
31
39
|
- Runtime: [`@metaobjectsdev/react`](../../../../client/web/packages/react) — the generated forms import from here.
|
package/dist/form-file.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-file.d.ts","sourceRoot":"","sources":["../src/form-file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,EAA6B,KAAK,gBAAgB,
|
|
1
|
+
{"version":3,"file":"form-file.d.ts","sourceRoot":"","sources":["../src/form-file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,EAA6B,KAAK,gBAAgB,EAA6G,MAAM,4BAA4B,CAAC;AAGzM,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EA2ChB,gBAAgB,CAAC,YAAY,CAAC,CAAC"}
|
package/dist/form-file.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { OBJECT_ATTR_DISCRIMINATOR } from "@metaobjectsdev/metadata";
|
|
2
|
-
import { perEntity, entityOutputPath, servesWriteApi, isProjection, isTphSubtype, CODEGEN_ATTR_EMIT_FORM } from "@metaobjectsdev/codegen-ts";
|
|
2
|
+
import { perEntity, entityOutputPath, servesWriteApi, isProjection, isTphSubtype, CODEGEN_ATTR_EMIT_FORM, withClientDirective } from "@metaobjectsdev/codegen-ts";
|
|
3
3
|
import { renderFormFile } from "./templates/form-file.js";
|
|
4
4
|
/**
|
|
5
5
|
* Forms are opt-in: a user must add `formFile()` to config.generators.
|
|
@@ -42,7 +42,7 @@ export const formFile = function formFile(opts) {
|
|
|
42
42
|
}
|
|
43
43
|
return {
|
|
44
44
|
path: entityOutputPath(ctx.config.outputLayout ?? "flat", entity.package, `${entity.name}.form.tsx`),
|
|
45
|
-
content: renderFormFile(entity, ctx.renderContext),
|
|
45
|
+
content: withClientDirective(renderFormFile(entity, ctx.renderContext), ctx.renderContext.clientDirective),
|
|
46
46
|
};
|
|
47
47
|
}),
|
|
48
48
|
};
|
package/dist/form-file.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-file.js","sourceRoot":"","sources":["../src/form-file.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,SAAS,EAAyC,gBAAgB,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"form-file.js","sourceRoot":"","sources":["../src/form-file.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,SAAS,EAAyC,gBAAgB,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACzM,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAO1D;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,SAAS,QAAQ,CAAC,IAAmB;IAC3D,MAAM,UAAU,GAAG,IAAI,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,SAAS,GAAc;QAC3B,IAAI,EAAE,WAAW;QACjB,8DAA8D;QAC9D,oEAAoE;QACpE,qEAAqE;QACrE,4BAA4B;QAC5B,2EAA2E;QAC3E,yEAAyE;QACzE,6EAA6E;QAC7E,MAAM,EAAE,CAAC,CAAa,EAAE,EAAE;YACxB,6EAA6E;YAC7E,IAAI,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,KAAK,KAAK;gBAAE,OAAO,KAAK,CAAC;YAC3D,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;YACjC,IAAI,YAAY,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC,CAAC,mBAAmB;YACrD,wDAAwD;YACxD,4EAA4E;YAC5E,8EAA8E;YAC9E,IAAI,OAAO,CAAC,CAAC,OAAO,CAAC,yBAAyB,CAAC,KAAK,QAAQ;gBAAE,OAAO,KAAK,CAAC;YAC3E,gFAAgF;YAChF,8EAA8E;YAC9E,2EAA2E;YAC3E,wCAAwC;YACxC,OAAO,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC/C,CAAC;QACD,QAAQ,EAAE,SAAS,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;YAClC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;YAC/E,CAAC;YACD,OAAO;gBACL,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,WAAW,CAAC;gBACpG,OAAO,EAAE,mBAAmB,CAC1B,cAAc,CAAC,MAAM,EAAE,GAAG,CAAC,aAAa,CAAC,EACzC,GAAG,CAAC,aAAa,CAAC,eAAe,CAClC;aACF,CAAC;QACJ,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,CAAmC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
export { formFile, type FormFileOpts } from "./form-file.js";
|
|
2
|
+
export { renderFormFile } from "./templates/form-file.js";
|
|
3
|
+
export { resolveReferenceRoot, readReferenceTemplate, REFERENCE_GENERATOR_NAMES } from "./reference-templates.js";
|
|
4
|
+
export type { ReferenceGeneratorName } from "./reference-templates.js";
|
|
2
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAI7D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAI1D,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAGlH,YAAY,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
// Public API surface for @metaobjectsdev/codegen-ts-react.
|
|
2
2
|
export { formFile } from "./form-file.js";
|
|
3
|
+
// FR-040 §4.2(b) — public so an owned generator composes the engine rather than
|
|
4
|
+
// forking it. Signature is stable API: (entity, ctx) => string.
|
|
5
|
+
export { renderFormFile } from "./templates/form-file.js";
|
|
6
|
+
// FR-040 §4.1 — the copyable reference generator(s) this package ships in
|
|
7
|
+
// `src/reference/`, and the reader `meta init`/`meta eject` use to read them.
|
|
8
|
+
export { resolveReferenceRoot, readReferenceTemplate, REFERENCE_GENERATOR_NAMES } from "./reference-templates.js";
|
|
3
9
|
//# 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,2DAA2D;AAC3D,OAAO,EAAE,QAAQ,EAAqB,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,OAAO,EAAE,QAAQ,EAAqB,MAAM,gBAAgB,CAAC;AAE7D,gFAAgF;AAChF,gEAAgE;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,0EAA0E;AAC1E,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 ["form"];
|
|
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,mBAAoB,CAAC;AAC3D,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 = ["form"];
|
|
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,MAAM,CAAU,CAAC;AAG3D,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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metaobjectsdev/codegen-ts-react",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.5",
|
|
4
4
|
"description": "React codegen for metaobjects — emits <Entity>.form.tsx files using react-hook-form and @metaobjectsdev/react helpers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"access": "public"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@metaobjectsdev/metadata": "0.24.
|
|
49
|
-
"@metaobjectsdev/codegen-ts": "0.24.
|
|
48
|
+
"@metaobjectsdev/metadata": "0.24.5",
|
|
49
|
+
"@metaobjectsdev/codegen-ts": "0.24.5",
|
|
50
50
|
"ts-poet": "^6.10.0"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
package/src/form-file.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { MetaObject } from "@metaobjectsdev/metadata";
|
|
2
2
|
import { OBJECT_ATTR_DISCRIMINATOR } from "@metaobjectsdev/metadata";
|
|
3
|
-
import { perEntity, type Generator, type GeneratorFactory, entityOutputPath, servesWriteApi, isProjection, isTphSubtype, CODEGEN_ATTR_EMIT_FORM } from "@metaobjectsdev/codegen-ts";
|
|
3
|
+
import { perEntity, type Generator, type GeneratorFactory, entityOutputPath, servesWriteApi, isProjection, isTphSubtype, CODEGEN_ATTR_EMIT_FORM, withClientDirective } from "@metaobjectsdev/codegen-ts";
|
|
4
4
|
import { renderFormFile } from "./templates/form-file.js";
|
|
5
5
|
|
|
6
6
|
export interface FormFileOpts {
|
|
@@ -45,7 +45,10 @@ export const formFile = function formFile(opts?: FormFileOpts): Generator {
|
|
|
45
45
|
}
|
|
46
46
|
return {
|
|
47
47
|
path: entityOutputPath(ctx.config.outputLayout ?? "flat", entity.package, `${entity.name}.form.tsx`),
|
|
48
|
-
content:
|
|
48
|
+
content: withClientDirective(
|
|
49
|
+
renderFormFile(entity, ctx.renderContext),
|
|
50
|
+
ctx.renderContext.clientDirective,
|
|
51
|
+
),
|
|
49
52
|
};
|
|
50
53
|
}),
|
|
51
54
|
};
|
package/src/index.ts
CHANGED
|
@@ -1,2 +1,13 @@
|
|
|
1
1
|
// Public API surface for @metaobjectsdev/codegen-ts-react.
|
|
2
2
|
export { formFile, type FormFileOpts } from "./form-file.js";
|
|
3
|
+
|
|
4
|
+
// FR-040 §4.2(b) — public so an owned generator composes the engine rather than
|
|
5
|
+
// forking it. Signature is stable API: (entity, ctx) => string.
|
|
6
|
+
export { renderFormFile } from "./templates/form-file.js";
|
|
7
|
+
|
|
8
|
+
// FR-040 §4.1 — the copyable reference generator(s) this package ships in
|
|
9
|
+
// `src/reference/`, and the reader `meta init`/`meta eject` use to read them.
|
|
10
|
+
export { resolveReferenceRoot, readReferenceTemplate, REFERENCE_GENERATOR_NAMES } from "./reference-templates.js";
|
|
11
|
+
// The name union travels with the names array — codegen-ts exports both, and a
|
|
12
|
+
// consumer keying anything by ejectable name needs the type as much as the values.
|
|
13
|
+
export type { ReferenceGeneratorName } from "./reference-templates.js";
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// REFERENCE TEMPLATE — copy this into your repo (e.g. codegen/generators/form.ts) and own it.
|
|
2
|
+
// Then import it LOCALLY in metaobjects.config.ts:
|
|
3
|
+
// import { formFile } from "./codegen/generators/form.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: React with react-hook-form. The emitted component calls `useEntityForm`
|
|
8
|
+
// from `@metaobjectsdev/react`, 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 `renderFormFile`'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 generated form per writable entity.
|
|
14
|
+
// emits: <target>/<Entity>.form.tsx
|
|
15
|
+
// customize: this generator is YOURS. `renderFormFile` (exported from
|
|
16
|
+
// @metaobjectsdev/codegen-ts-react) produces the component body — wrap it,
|
|
17
|
+
// prepend to it, or replace the call entirely with your own renderer.
|
|
18
|
+
// composes-with: entity.ts (imports the schemas the form validates against).
|
|
19
|
+
|
|
20
|
+
import type { MetaObject } from "@metaobjectsdev/metadata";
|
|
21
|
+
import { OBJECT_ATTR_DISCRIMINATOR } from "@metaobjectsdev/metadata";
|
|
22
|
+
import {
|
|
23
|
+
perEntity,
|
|
24
|
+
type Generator,
|
|
25
|
+
type GeneratorFactory,
|
|
26
|
+
entityOutputPath,
|
|
27
|
+
servesWriteApi,
|
|
28
|
+
isProjection,
|
|
29
|
+
isTphSubtype,
|
|
30
|
+
CODEGEN_ATTR_EMIT_FORM,
|
|
31
|
+
withClientDirective,
|
|
32
|
+
} from "@metaobjectsdev/codegen-ts";
|
|
33
|
+
import { renderFormFile } from "@metaobjectsdev/codegen-ts-react";
|
|
34
|
+
|
|
35
|
+
export interface FormFileOpts {
|
|
36
|
+
filter?: (entity: MetaObject) => boolean;
|
|
37
|
+
target?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Forms are opt-in: a user must add `formFile()` to config.generators.
|
|
42
|
+
* Per-entity opt-out via `@emitForm: false` is honored.
|
|
43
|
+
* .tsx files are not piped through formatTs (Biome only handles .ts here).
|
|
44
|
+
*/
|
|
45
|
+
export const formFile = function formFile(opts?: FormFileOpts): Generator {
|
|
46
|
+
const userFilter = opts?.filter ?? (() => true);
|
|
47
|
+
const generator: Generator = {
|
|
48
|
+
name: "form-file",
|
|
49
|
+
// Always set: AND-composes the framework write-artifact guard
|
|
50
|
+
// (skips abstract types — no instance — and read-only projections —
|
|
51
|
+
// instantiable for read, never for write), the metadata opt-out, and
|
|
52
|
+
// the optional user filter.
|
|
53
|
+
// FR-017 Tier 3: forms are ALWAYS per-subtype. The discriminator base gets
|
|
54
|
+
// NO form (you can't create an abstract base), but each concrete subtype
|
|
55
|
+
// does — even though it has no own writable source (it inherits the base's).
|
|
56
|
+
filter: (e: MetaObject) => {
|
|
57
|
+
// ADR-0039: resolving — a concrete entity may inherit @emitForm via extends.
|
|
58
|
+
if (e.attr(CODEGEN_ATTR_EMIT_FORM) === false) return false;
|
|
59
|
+
if (!userFilter(e)) return false;
|
|
60
|
+
if (isTphSubtype(e)) return true; // per-subtype form
|
|
61
|
+
// A discriminator base is never form-rendered directly.
|
|
62
|
+
// ADR-0039: own — @discriminator identifies a TPH base level (read own so a
|
|
63
|
+
// subtype isn't mistaken for a base); e is already known not to be a subtype.
|
|
64
|
+
if (typeof e.ownAttr(OBJECT_ATTR_DISCRIMINATOR) === "string") return false;
|
|
65
|
+
// A form is a client of a WRITE endpoint. Ask whether one exists, not where the
|
|
66
|
+
// data is stored — see api-surface.ts. `!isProjection` stays explicit here: a
|
|
67
|
+
// read-only view is a UI-tier exclusion (nothing to submit), distinct from
|
|
68
|
+
// whether write endpoints exist at all.
|
|
69
|
+
return servesWriteApi(e) && !isProjection(e);
|
|
70
|
+
},
|
|
71
|
+
generate: perEntity((entity, ctx) => {
|
|
72
|
+
if (!ctx.renderContext) {
|
|
73
|
+
throw new Error("form-file: renderContext is required (provided by runGen)");
|
|
74
|
+
}
|
|
75
|
+
// The framework-coupled seam. `withClientDirective` applies the project-level
|
|
76
|
+
// `clientDirective` config knob (FR-040 §6.4); for a directive your framework
|
|
77
|
+
// needs that MetaObjects does not model, prepend it right here.
|
|
78
|
+
const body = withClientDirective(
|
|
79
|
+
renderFormFile(entity, ctx.renderContext),
|
|
80
|
+
ctx.renderContext.clientDirective,
|
|
81
|
+
);
|
|
82
|
+
return {
|
|
83
|
+
path: entityOutputPath(ctx.config.outputLayout ?? "flat", entity.package, `${entity.name}.form.tsx`),
|
|
84
|
+
content: body,
|
|
85
|
+
};
|
|
86
|
+
}),
|
|
87
|
+
};
|
|
88
|
+
if (opts?.target) {
|
|
89
|
+
generator.target = opts.target;
|
|
90
|
+
}
|
|
91
|
+
return generator;
|
|
92
|
+
} as GeneratorFactory<FormFileOpts>;
|
|
@@ -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 = ["form"] 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
|
+
}
|