feat(codegen-ts): add copyable reference template library#86
Merged
Conversation
…wn, step 1)
Adds src/reference/{entity,queries,routes,barrel}.ts — self-contained COPYABLE
reference generators a consumer copies into their repo and owns, importing only the
public engine (@metaobjectsdev/codegen-ts) + ts-poet + @metaobjectsdev/metadata. Each
carries a use-when / emits / customize / composes-with header. entity relocates the
full renderEntityFile composition (full ownership); queries owns the vanilla-CRUD
composition and delegates TPH/projection variants; barrel relocates renderBarrel;
routes stays generator-level (its vanilla composition pulls in internal M:N junction
logic — renderM2mMounts — that we deliberately do NOT promote; the header documents
how to copy renderRoutesFile's body for deeper ownership).
Promotes the composition's assembly helpers to public (re-exports only — already
exported from their modules): renderTphDiscriminatorUnion, hasWritableRdbSource,
renderSharedEnumsFile, SHARED_ENUMS_BASENAME, and the queries CRUD-block renderers
(renderFindByIdFn/List/Create/Update/DeleteById + getPkInfo).
Purely additive — no existing generator or export removed (deprecation + the meta init
scaffolding + guidance rewrite are later steps). reference/ excluded from the tsc build
(scaffold assets). Verified: byte-identical built-in-vs-reference over 5 fixtures (68
assertions), full codegen-ts suite 831 pass, tsc --noEmit strict of reference/* against
the public API clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuZWKnWzYGVnESijL7uuky
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
ADR-0034 Phase-1 step-1: add a reference template library to @metaobjectsdev/codegen-ts (the shadcn-for-codegen pivot). Adds src/reference/{entity,queries,routes,barrel}.ts — self-contained COPYABLE reference generators a consumer copies into their repo and owns, importing only the public engine (@metaobjectsdev/codegen-ts) + ts-poet + @metaobjectsdev/metadata, each with a use-when/emits/customize/composes-with header. entity relocates the full renderEntityFile composition; queries owns the vanilla-CRUD composition + delegates TPH/projection variants to the public renderQueriesFile; barrel relocates renderBarrel; routes deliberately STAYS generator-level (its composition pulls in internal M:N junction logic renderM2mMounts that we intentionally do NOT promote — the header documents the deeper-ownership path). Promotes only re-exports of already-exported assembly helpers (renderTphDiscriminatorUnion, hasWritableRdbSource, renderSharedEnumsFile, SHARED_ENUMS_BASENAME, the queries CRUD-block renderers). PURELY ADDITIVE — no existing generator or export removed; meta init scaffolding + deprecation + guidance rewrite are later steps. reference/ is excluded from the tsc build (scaffold assets). Verified locally: byte-identical built-in-vs-reference over 5 fixtures (68 assertions), full codegen-ts suite 831 pass 0 fail, tsc --noEmit strict of reference/* against the public API clean. Run tests LOCALLY in this worktree; GitHub Actions CI skipped (CI is local, only the PR on GitHub).
What Changed
src/reference/{entity,queries,routes,barrel}.tsto@metaobjectsdev/codegen-ts— self-contained, copyable reference generators (ADR-0034 scaffold-and-own, step 1) that a consumer copies into their repo and owns, importing only the public engine plusts-poetand@metaobjectsdev/metadata.entityrelocates the fullrenderEntityFilecomposition,queriesowns vanilla-CRUD and delegates TPH/projection variants to the publicrenderQueriesFile,barrelrelocatesrenderBarrel, androutesstays generator-level (its internal M:N junction logic is intentionally not promoted, documented in the header).src/index.ts(already-exported assembly helpers:renderTphDiscriminatorUnion,hasWritableRdbSource,renderSharedEnumsFile,SHARED_ENUMS_BASENAME, the queries CRUD-block renderers) — purely additive, no existing generator or export removed;reference/is excluded from the tsc build as scaffold assets.test/reference-byte-identical.test.tsasserting the reference generators produce byte-identical output to the built-in generators across 5 fixtures (68 assertions), and documented the library inCHANGELOG.md.Risk Assessment
✅ Low: Purely additive scaffold assets: no existing generator or export is removed, the relocated compositions are byte-identical to the built-ins they mirror, and a dedicated test asserts that equivalence across five fixtures.
Testing
Exercised the scaffold-and-own guarantee end-to-end: the existing byte-identical conformance test (5 fixtures, 68 assertions) passes, the full codegen-ts suite is 831 pass/0 fail, and a fresh end-to-end run drove the copyable reference generators through the public runGen() on a real fixture — all 7 generated files (Drizzle table + Zod + queries + Fastify routes + barrel) came out byte-identical to the built-in generators, and I persisted the actual generated code as reviewer-visible artifacts. I also confirmed the templates strict-typecheck against the built public dist (the surface a consumer imports) with zero diagnostics, the package tsc build passes with reference/ excluded, and the index.ts change is re-exports only (purely additive). This is a library/codegen change with no UI surface, so artifacts are the generated code and CLI transcripts rather than screenshots. No failures or setup issues.
Evidence: Reference-vs-built-in end-to-end transcript (7 files byte-identical)
fixture: two-entities-fk.json reference generators emitted 7 files: Post.queries.ts, Post.routes.ts, Post.ts, User.queries.ts, User.routes.ts, User.ts, index.ts ✓ byte-identical Post.queries.ts (1760 bytes) ✓ byte-identical Post.routes.ts (1105 bytes) ✓ byte-identical Post.ts (2610 bytes) ✓ byte-identical User.queries.ts (1760 bytes) ✓ byte-identical User.routes.ts (1105 bytes) ✓ byte-identical User.ts (2200 bytes) ✓ byte-identical index.ts (107 bytes) ALL FILES BYTE-IDENTICAL (reference == built-in): trueEvidence: Real generated User.ts produced by the copyable reference/entity.ts template
Evidence: Generated User.queries.ts (reference queries template)
Evidence: Generated User.routes.ts (built-in routes via reference composition)
Evidence: Strict tsc --noEmit of reference/* against public API dist (clean)
$ tsc --noEmit --strict over src/reference/*.ts, with @metaobjectsdev/codegen-ts mapped to ./dist (the public API a consumer imports) (tsc produced NO diagnostics) EXIT=0 — reference templates are type-clean against the published public engine surfacePipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
server/typescript/packages/codegen-ts/tsconfig.json:8- src/reference/* is excluded from the package tsc build (tsconfig exclude). The byte-identical runtime test exercises the reference generators and would catch behavioral drift, but a future public-API change that breaks the reference files only at the type level (e.g. a renamed/removed type that leaves the runtime symbol intact) would not fail any automated gate going forward — the tsc --noEmit check against the public API was a one-time manual verification. Consider wiring a CI typecheck of reference/* against the built public API to institutionalize that guard.✅ **Test** - passed
✅ No issues found.
bun test test/reference-byte-identical.test.ts— 5 fixtures / 68 assertions, reference vs built-in byte-identical (pass)bun test(full codegen-ts package suite) — 831 pass / 0 failBuilt workspace deps thenbun run build(tsc -p .) for codegen-ts — passes with src/reference excluded as scaffold assetsStricttsc --noEmitover src/reference/*.ts with@metaobjectsdev/codegen-tsmapped to ./dist (public-API view) — no diagnostics, exit 0End-to-end: ran the reference generators via public runGen() on the two-entities-fk fixture; all 7 emitted files byte-identical to built-in output; persisted real generated entity/queries/routes artifactsgit diffof src/index.ts confirms re-exports added only (additive);git statusclean after test cleanupserver/typescript/packages/codegen-ts/README.md- The consumer-facing codegen-ts README and the metaobjects-codegen guidance/skill still teach importing built-in generators from @metaobjectsdev/codegen-ts/generators and do not yet describe the scaffold-and-own copy-a-reference-template path. This is intentionally deferred to later ADR-0034 steps (meta init scaffolding, generator-export deprecation, guidance rewrite), not an oversight from this additive step-1 change — flagged only so a reviewer knows it was a deliberate no-op, not a missed gap.✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.