Skip to content

Commit 47d1cf7

Browse files
committed
no-mistakes(document): sync docs for declarative template-codegen scopes (SP-1a)
1 parent 407202a commit 47d1cf7

4 files changed

Lines changed: 88 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,23 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
88
## [Unreleased]
99

1010
### Added
11+
- **codegen-ts — declarative Mustache template-codegen (SP-1a):** a
12+
`templateGenerator` can now take its walk **declaratively** via `scope`
13+
(`"perEntity" | "perPackage" | "perModel"`) + `outputPattern` instead of a
14+
hand-written `walk` (the two are mutually exclusive — provide exactly one). The
15+
generator derives a **neutral, structural** template data dict per unit
16+
(`buildEntityTemplateData` / `buildPackageTemplateData` / `buildModelTemplateData`,
17+
with types `FieldTemplateData` / `EntityTemplateData` / `IdentityTemplateData` /
18+
`RelationshipTemplateData` / `PackageTemplateData` / `ModelTemplateData`) — raw
19+
structural facts only, distinct from the Markdown-flavored `EntityDocData`, and
20+
byte-gated as a cross-port contract by `fixtures/template-codegen-conformance/`.
21+
`outputPattern` supports `{name}` / `{Name}` / `{package}` (`::``/`; unknown
22+
placeholder throws), expandable via the exported `expandOutputPattern`. A JSON
23+
**template-spec** (`parseTemplateSpec` / `templateSpecToGenerators`, types
24+
`TemplateSpecEntry` / `TemplateSpecFile`, JSON Schema beside the source) is the
25+
surface the C#/Python CLI ports will reuse. New package-scope engine helper
26+
`perPackage(fn)` joins `perEntity` / `perModel`. All exported from the package
27+
main entry `@metaobjectsdev/codegen-ts`.
1128
- **cli — `meta init` scaffolds owned codegen generators (ADR-0034 scaffold-and-own, step 2):**
1229
`meta init` now copies the four codegen reference templates (step 1) into the
1330
consumer repo at `codegen/generators/{entity,queries,routes,barrel}.ts` and
@@ -34,6 +51,10 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
3451
generator-export deprecation, and the guidance rewrite are later steps.)
3552

3653
### Deprecated
54+
- **codegen-ts — `oncePerRun` scope helper (SP-1a):** renamed to `perModel`
55+
"run" is ambiguous under multi-target output (it reads as "per target"), while
56+
`perModel` names the data scope (the whole model). `oncePerRun` is kept as a
57+
soft-deprecated alias and still works.
3758
- **codegen-ts — `@metaobjectsdev/codegen-ts/generators` factory re-exports
3859
(ADR-0034 scaffold-and-own, step 2):** importing `entityFile` / `queriesFile` /
3960
`routesFile` / `barrel` from the package `/generators` export is deprecated in

docs/features/codegen-concepts.md

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,34 @@ whole-model are just different walks.
150150
**The model to expose.** Three scope helpers, so the scope is declared, not buried in
151151
custom iteration:
152152

153-
- **`perEntity(fn)`** — object scope. *(exists)*
154-
- **`perPackage(fn)`** — package scope: group matching objects by package, run `fn`
155-
once per package. *(the gap — Java never had this cleanly either, so this is an
156-
improvement on the predecessor, not just parity.)*
157-
- **`oncePerRun(fn)`** — app scope: run once over all matching objects. *(exists; an
158-
`appLevel` alias can make the intent explicit.)*
153+
- **`perEntity(fn)`** — object scope. Runs `fn` once per matched object.
154+
- **`perPackage(fn)`** — package scope: group matching objects by package (packages
155+
ascending, objects keeping `ctx.entities` order), run `fn` once per package. Groups
156+
by `effectivePackage` so objects with a bare FQN (FR5d) still bucket correctly.
157+
- **`perModel(fn)`** — app scope: run once over all matching objects. (`oncePerRun`
158+
is kept as a soft-deprecated alias — "run" is ambiguous under multi-target output;
159+
`perModel` names the data scope.)
159160

160161
A generator picks its scope by which helper it composes — the same way it picks
161-
object vs run today. Reference templates and the guidance call out the scope each
162+
object vs model today. Reference templates and the guidance call out the scope each
162163
starting point is for, so "I need a per-package service layer" maps to a clear
163164
pattern instead of hand-rolled grouping.
165+
166+
### Declarative template scopes
167+
168+
A `templateGenerator` can take the scope walk declaratively instead of a hand-written
169+
`walk` — pass `scope` (`"perEntity" | "perPackage" | "perModel"`) plus an
170+
`outputPattern`, and the generator derives the neutral template data dict per unit and
171+
names each file via the pattern. `walk` and `scope` are mutually exclusive — provide
172+
exactly one. The `outputPattern` placeholders are `{name}`, `{Name}`, and `{package}`
173+
(an unknown placeholder throws); `{package}` resolves through `effectivePackage` and
174+
renders `::`-separated segments as nested path directories.
175+
176+
```ts
177+
templateGenerator({
178+
name: "entity-doc",
179+
scope: "perEntity",
180+
outputPattern: "{package}/{Name}.md",
181+
template: "entity-doc",
182+
});
183+
```

docs/features/codegen-data-shapes.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,44 @@ trivial and cross-port walkers don't have to re-derive the rules.
6868
file into your project; the project's `templates/` directory takes precedence
6969
over the framework defaults. Same for any partial under `templates/docs/`.
7070

71+
### Neutral structural shapes → `EntityTemplateData` / `PackageTemplateData` / `ModelTemplateData`
72+
73+
The declarative template scopes (`scope: "perEntity" | "perPackage" | "perModel"`
74+
on `templateGenerator`) feed a **neutral, structural** data dict — deliberately
75+
distinct from the Markdown-flavored `EntityDocData` above. It carries raw
76+
structural facts only, so a consumer's template can emit any language's code from
77+
it. The field names are a byte-gated **cross-port contract** (the
78+
`fixtures/template-codegen-conformance/` corpus locks them) — change them only via
79+
the spec.
80+
81+
```ts
82+
interface FieldTemplateData {
83+
name: string;
84+
type: string; // neutral subtype: "string" | "int" | "currency" | "enum" | ...
85+
required: boolean;
86+
isArray: boolean; // arrayness is carried here, NOT appended to `type`
87+
maxLength?: number;
88+
enumValues?: string[]; // present only for field.enum
89+
}
90+
interface IdentityTemplateData { kind: string; fields: string[]; }
91+
interface RelationshipTemplateData { name: string; cardinality: string; targetRef: string; }
92+
interface EntityTemplateData {
93+
name: string;
94+
package: string; // effective package (`::`-separated), "" when none
95+
fields: FieldTemplateData[];
96+
identities: IdentityTemplateData[];
97+
relationships: RelationshipTemplateData[];
98+
}
99+
interface PackageTemplateData { package: string; entities: EntityTemplateData[]; }
100+
interface ModelTemplateData { packages: PackageTemplateData[]; } // packages ascending
101+
```
102+
103+
These types and their builders (`buildEntityTemplateData`,
104+
`buildPackageTemplateData`, `buildModelTemplateData`) are exported from the package
105+
**main entry** (`@metaobjectsdev/codegen-ts`), alongside `expandOutputPattern` and
106+
the JSON template-spec parser (`parseTemplateSpec`, `templateSpecToGenerators`).
107+
Abstract objects are excluded from every scope (they emit no instance artifact).
108+
71109
### Section-presence flags (`hasX`)
72110

73111
Mustache cleanly iterates an array (`{{#identities}}...{{/identities}}`) but

server/typescript/packages/codegen-ts/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ from the **owned local copies** that `meta init` scaffolds into
8686
`codegen/generators/` (ADR-0034 scaffold-and-own). Importing them from
8787
`@metaobjectsdev/codegen-ts/generators` still works but is **deprecated** — own a
8888
copy instead; the package export will be removed in a future major. The engine and
89-
primitives (`runGen`, `perEntity`, `oncePerRun`, `RenderContext`, the loader and
89+
primitives (`runGen`, the scope helpers `perEntity` / `perPackage` / `perModel`
90+
(`oncePerRun` is a soft-deprecated alias of `perModel`), `RenderContext`, the loader and
9091
render helpers) remain the stable, versioned import from `@metaobjectsdev/codegen-ts`,
9192
and an owned generator imports them from there.
9293

0 commit comments

Comments
 (0)