@kurotako/gen-angular 0.1.0 → 0.2.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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/generator.ts","../src/artifact.ts","../src/names.ts","../src/zod-artifact.ts","../src/emit/barrel.ts","../src/render/imports.ts","../src/render/controls.ts","../src/render/relations.ts","../src/render/variants.ts","../src/render/reactive.ts","../src/render/signal.ts","../src/emit/entity.ts","../src/emit/runtime.ts","../src/options.ts"],"sourcesContent":["/**\n * `@kurotako/gen-angular` error classes.\n *\n * `AngularGenError` is a plain `Error` subclass carrying a stable `code`; the\n * Angular generator has no dependency on `@kurotako/core` at runtime, and\n * `@kurotako/core` wraps any throw from `generate()` as a `DriverError` for the\n * CLI's single `instanceof TakoError` catch.\n *\n * Codes: `angular_missing_zod_symbol`, `angular_missing_zod_namespace`.\n */\n\nexport class AngularGenError extends Error {\n readonly code: string;\n\n constructor(code: string, message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = new.target.name;\n this.code = code;\n }\n}\n\n/**\n * The Zod artifact has no entry (or no `role` symbol) for `${ns}.${entity}`.\n * `dependsOn: ['zod']` guarantees the dependency ran, but a role can still be\n * absent if the consumed `gen-zod` version predates it.\n */\nexport class MissingZodSymbolError extends AngularGenError {\n readonly entityKey: string;\n readonly role: string;\n\n constructor(entityKey: string, role: string) {\n super(\n 'angular_missing_zod_symbol',\n `Zod artifact for '${entityKey}' has no '${role}' symbol; regenerate with a gen-zod version that exposes it`,\n );\n this.entityKey = entityKey;\n this.role = role;\n }\n}\n\n/** The Zod artifact's `extra.perNamespace` has no entry for a namespace the IR carries. */\nexport class MissingZodNamespaceError extends AngularGenError {\n readonly namespace: string;\n\n constructor(namespace: string) {\n super(\n 'angular_missing_zod_namespace',\n `Zod artifact has no 'extra.perNamespace[${JSON.stringify(namespace)}]' entry`,\n );\n this.namespace = namespace;\n }\n}\n","/**\n * `angularGenerator` — the `@kurotako/gen-angular` driver.\n *\n * Hard `dependsOn: ['zod']`: core rejects a config that enables `angular`\n * without `zod`, and the topological order guarantees `ctx.dependencies.zod` is\n * always present here. `generate` is synchronous and pure: same IR + same Zod\n * artifact + same options -> deep-equal `GenOutput` (drift-guard requirement).\n */\nimport { defineGenerator } from '@kurotako/config';\nimport type { GenerateContext, GenOutput, VirtualFile } from '@kurotako/core';\nimport { buildArtifact } from './artifact.js';\nimport { emitBarrel } from './emit/barrel.js';\nimport { emitEntity } from './emit/entity.js';\nimport { emitRuntime } from './emit/runtime.js';\nimport { AngularGeneratorOptions } from './options.js';\n\nexport const angularGenerator = defineGenerator({\n name: 'angular',\n dependsOn: ['zod'],\n optionsSchema: AngularGeneratorOptions,\n\n generate(ctx: GenerateContext, options): GenOutput {\n const zod = ctx.dependencies.zod;\n if (zod === undefined) {\n throw new Error(\n \"gen-angular: 'zod' dependency artifact is missing at runtime despite dependsOn: ['zod']\",\n );\n }\n\n const files: VirtualFile[] = [];\n\n for (const [namespace, source] of Object.entries(ctx.ir.sources)) {\n const prefix = `${namespace}/angular`;\n const entities = Object.values(source.entities);\n\n if (entities.length > 0 && options.forms.length > 0) {\n files.push({\n path: `${prefix}/zod-forms.runtime.ts`,\n content: emitRuntime(source, options),\n });\n }\n for (const entity of entities) {\n files.push({\n path: `${prefix}/${entity.name}.form.ts`,\n content: emitEntity(\n entity,\n namespace,\n source,\n options,\n zod,\n ctx.logger,\n ),\n });\n }\n files.push({\n path: `${prefix}/index.ts`,\n content: emitBarrel(source, options),\n });\n }\n\n return { files, artifact: buildArtifact(ctx.ir, zod, options) };\n },\n});\n","/**\n * Assemble the `GeneratorArtifact` (entities symbol matrix +\n * `AngularArtifactExtra`). No generator depends on `angular` in v1; the\n * artifact exists for uniformity and future consumers\n * (`generator-angular/technical.md` §Artifact).\n */\nimport type { EntitySymbols, GeneratorArtifact } from '@kurotako/core';\nimport type { IR } from '@kurotako/ir';\nimport { iterEntities } from '@kurotako/ir';\nimport {\n barrelModule,\n controlsTypeName,\n entityModule,\n factoryName,\n formTypeName,\n modelFactoryName,\n runtimeModule,\n signalFormFactoryName,\n signalSchemaName,\n} from './names.js';\nimport type { AngularGeneratorOptions } from './options.js';\nimport { zodExtra } from './zod-artifact.js';\n\nexport interface AngularArtifactExtra {\n forms: ('reactive' | 'signal')[];\n relations: 'flat' | 'deep';\n /** Echoed from the consumed `ZodArtifactExtra`. */\n zodVersion: 3 | 4;\n perNamespace: Record<\n string,\n {\n runtimeModule: string;\n barrelModule: string;\n }\n >;\n}\n\nfunction entitySymbols(\n entityName: string,\n options: AngularGeneratorOptions,\n): Record<string, string> {\n const symbols: Record<string, string> = {};\n const deep = options.relations === 'deep';\n const family = deep ? 'Deep' : ('' as const);\n\n if (options.forms.includes('reactive')) {\n const createControls = controlsTypeName(entityName, 'Create', family);\n const createForm = formTypeName(entityName, 'Create', family);\n const updateControls = controlsTypeName(entityName, 'Update', family);\n const updateForm = formTypeName(entityName, 'Update', family);\n\n symbols.createControls = createControls;\n symbols.createForm = createForm;\n symbols.updateControls = updateControls;\n symbols.updateForm = updateForm;\n symbols.factory = factoryName(entityName);\n\n if (deep) {\n symbols.createDeepControls = createControls;\n symbols.createDeepForm = createForm;\n symbols.updateDeepControls = updateControls;\n symbols.updateDeepForm = updateForm;\n }\n }\n\n if (options.forms.includes('signal')) {\n symbols.createSchema = signalSchemaName(entityName, 'Create');\n symbols.updateSchema = signalSchemaName(entityName, 'Update');\n symbols.createModel = modelFactoryName(entityName, 'Create');\n symbols.updateModel = modelFactoryName(entityName, 'Update');\n symbols.createSignalForm = signalFormFactoryName(entityName, 'Create');\n symbols.updateSignalForm = signalFormFactoryName(entityName, 'Update');\n }\n\n return symbols;\n}\n\nexport function buildArtifact(\n ir: IR,\n zod: GeneratorArtifact,\n options: AngularGeneratorOptions,\n): GeneratorArtifact {\n const entities: Record<string, EntitySymbols> = {};\n for (const { namespace, entity } of iterEntities(ir)) {\n entities[`${namespace}.${entity.name}`] = {\n module: entityModule(namespace, entity.name),\n symbols: entitySymbols(entity.name, options),\n };\n }\n\n const perNamespace: AngularArtifactExtra['perNamespace'] = {};\n for (const namespace of Object.keys(ir.sources)) {\n perNamespace[namespace] = {\n runtimeModule: runtimeModule(namespace),\n barrelModule: barrelModule(namespace),\n };\n }\n\n const extra: AngularArtifactExtra = {\n forms: options.forms,\n relations: options.relations,\n zodVersion: zodExtra(zod).zodVersion,\n perNamespace,\n };\n\n const peerDependencies = options.forms.includes('signal')\n ? { '@angular/core': '>=22', '@angular/forms': '>=22' }\n : { '@angular/core': '>=17', '@angular/forms': '>=17' };\n\n return { entities, peerDependencies, extra };\n}\n","/**\n * Deterministic identifier and module-specifier helpers.\n *\n * Identifiers are never namespace-prefixed (ADR-0004); the namespace only drives\n * the output location. The `angular/` sub-tree segment on every module specifier\n * is the output-modes amendment (one sub-tree per generator).\n */\n\n/** PascalCase form-variant token embedded in an identifier. */\nexport type Variant = 'Create' | 'Update';\n\n/** Relation family token embedded in a control-tree identifier. */\nexport type Family = '' | 'Deep';\n\nfunction lowerFirst(s: string): string {\n return s.length === 0 ? s : s.charAt(0).toLowerCase() + s.slice(1);\n}\n\n/** `${Entity}${Variant}${Family}FormControls`. */\nexport function controlsTypeName(\n entity: string,\n variant: Variant,\n family: Family = '',\n): string {\n return `${entity}${variant}${family}FormControls`;\n}\n\n/** `${Entity}${Variant}${Family}Form` — the `FormGroup<...>` type alias. */\nexport function formTypeName(\n entity: string,\n variant: Variant,\n family: Family = '',\n): string {\n return `${entity}${variant}${family}Form`;\n}\n\n/** `${Entity}FormFactory` — one `@Injectable` service per entity. */\nexport function factoryName(entity: string): string {\n return `${entity}FormFactory`;\n}\n\n/** `create${Variant}Form` — the factory method name. No suffix in deep mode. */\nexport function factoryMethod(variant: Variant): string {\n return `create${variant}Form`;\n}\n\n/**\n * `add${Relation}${Variant}` — the deep-mode nested-control builder method.\n * Variant-suffixed: `UserFormFactory` builds both `Create` and `Update` trees,\n * and a relation's target control type differs between them, so the two\n * variants cannot share one method name (would collide as a duplicate\n * implementation).\n */\nexport function relationBuilderMethod(\n relationName: string,\n variant: Variant,\n): string {\n const cap = `${relationName.charAt(0).toUpperCase()}${relationName.slice(1)}`;\n return `add${cap}${variant}`;\n}\n\n/** `${entity}${Variant}FormSchema`, camelCase — the Signal Forms schema const. */\nexport function signalSchemaName(entity: string, variant: Variant): string {\n return `${lowerFirst(entity)}${variant}FormSchema`;\n}\n\n/** `create${Entity}${Variant}Model` — the Signal Forms model-factory function. */\nexport function modelFactoryName(entity: string, variant: Variant): string {\n return `create${entity}${variant}Model`;\n}\n\n/**\n * `create${Entity}${Variant}Form` — the Signal Forms `form(signal(model), schema)`\n * convenience wrapper. Safe to call from anywhere `inject()` would work (a\n * component field initializer or constructor): `form()` resolves its\n * injector from the ambient injection context when none is passed\n * explicitly, same as calling it inline.\n */\nexport function signalFormFactoryName(\n entity: string,\n variant: Variant,\n): string {\n return `create${entity}${variant}Form`;\n}\n\n// --- module specifiers (POSIX, extension-less) -------------------------------\n\n/** `${ns}/angular/${entity}.form`. */\nexport function entityModule(namespace: string, entity: string): string {\n return `${namespace}/angular/${entity}.form`;\n}\n\n/** `${ns}/angular/zod-forms.runtime`. */\nexport function runtimeModule(namespace: string): string {\n return `${namespace}/angular/zod-forms.runtime`;\n}\n\n/** `${ns}/angular` — this generator's own sub-tree barrel. */\nexport function barrelModule(namespace: string): string {\n return `${namespace}/angular`;\n}\n","/**\n * Typed reader over `ctx.dependencies.zod` (the `GeneratorArtifact` produced by\n * `@kurotako/gen-zod`). `dependsOn: ['zod']` guarantees the entry is present;\n * this module only resolves identifiers + module specifiers, never re-derives a\n * Zod name (`generator-angular/technical.md` §Naming).\n *\n * Role keys consumed here (a subset of `gen-zod`'s full matrix): `createSchema`,\n * `createType`, `updateSchema`, `updateType`, and — in `relations: 'deep'` mode\n * only — `createDeepSchema`, `createDeepType`, `updateDeepSchema`,\n * `updateDeepType`.\n */\nimport type { EntitySymbols, GeneratorArtifact } from '@kurotako/core';\nimport type { ZodArtifactExtra } from '@kurotako/gen-zod';\nimport { MissingZodNamespaceError, MissingZodSymbolError } from './errors.js';\n\nexport type ZodRole =\n | 'createSchema'\n | 'createType'\n | 'updateSchema'\n | 'updateType'\n | 'createDeepSchema'\n | 'createDeepType'\n | 'updateDeepSchema'\n | 'updateDeepType';\n\n/** `${namespace}.${entity}` — the artifact's entity key. */\nexport function entityKey(namespace: string, entity: string): string {\n return `${namespace}.${entity}`;\n}\n\n/** The Zod `{ module, symbols }` entry for an entity, or throw if absent. */\nexport function zodEntity(\n zod: GeneratorArtifact,\n namespace: string,\n entity: string,\n): EntitySymbols {\n const key = entityKey(namespace, entity);\n const entry = zod.entities[key];\n if (entry === undefined) {\n throw new MissingZodSymbolError(key, '<entity>');\n }\n return entry;\n}\n\n/** Resolve one `role` on an entity to its Zod-emitted identifier. */\nexport function zodSymbol(\n zod: GeneratorArtifact,\n namespace: string,\n entity: string,\n role: ZodRole,\n): string {\n const key = entityKey(namespace, entity);\n const entry = zodEntity(zod, namespace, entity);\n const id = entry.symbols[role];\n if (id === undefined) {\n throw new MissingZodSymbolError(key, role);\n }\n return id;\n}\n\n/** The module specifier a sibling generator imports an entity's Zod schema from. */\nexport function zodModule(\n zod: GeneratorArtifact,\n namespace: string,\n entity: string,\n): string {\n return zodEntity(zod, namespace, entity).module;\n}\n\n/** `zod.extra`, cast to the published `ZodArtifactExtra` shape. */\nexport function zodExtra(zod: GeneratorArtifact): ZodArtifactExtra {\n return zod.extra as ZodArtifactExtra;\n}\n\n/** `extra.perNamespace[ns]`, or throw if the Zod artifact never saw that namespace. */\nexport function zodNamespaceExtra(\n zod: GeneratorArtifact,\n namespace: string,\n): ZodArtifactExtra['perNamespace'][string] {\n const per = zodExtra(zod).perNamespace[namespace];\n if (per === undefined) {\n throw new MissingZodNamespaceError(namespace);\n }\n return per;\n}\n\n/** `{ typeName, module }` for an enum ref, resolved via `extra.perNamespace[ns].enums`. */\nexport function zodEnum(\n zod: GeneratorArtifact,\n namespace: string,\n ref: string,\n): { typeName: string; module: string } {\n const per = zodNamespaceExtra(zod, namespace);\n const def = per.enums[ref];\n if (def === undefined) {\n throw new MissingZodSymbolError(`${namespace}.<enum>`, ref);\n }\n return { typeName: def.typeName, module: def.module };\n}\n","/**\n * `<ns>/angular/index.ts` — this generator's own sub-tree barrel. Re-exports\n * `./zod-forms.runtime` (when emitted) and every `./<entity>.form`. A\n * zero-entity source still yields a valid `index.ts`.\n */\nimport type { SourceIR } from '@kurotako/ir';\nimport type { AngularGeneratorOptions } from '../options.js';\n\nexport function emitBarrel(\n source: SourceIR,\n options: AngularGeneratorOptions,\n): string {\n const lines: string[] = [];\n const entities = Object.values(source.entities);\n\n if (entities.length > 0 && options.forms.length > 0) {\n lines.push(\"export * from './zod-forms.runtime';\");\n }\n for (const entity of entities) {\n lines.push(`export * from './${entity.name}.form';`);\n }\n\n return `${lines.join('\\n')}\\n`;\n}\n","/**\n * Import-block accumulator shared by `render/reactive.ts`, `render/signal.ts`\n * and `emit/entity.ts`. Collects the module specifiers + identifiers a rendered\n * entity file needs while it is being assembled, so the final `import` block can\n * be built once, sorted, and split into value vs. type-only lines\n * (`generator-angular/technical.md` §Determinism: import lines sorted by module\n * specifier, named imports sorted).\n */\n\nexport class ImportsRecorder {\n private readonly values = new Map<string, Set<string>>();\n private readonly types = new Map<string, Set<string>>();\n\n value(module: string, name: string): void {\n add(this.values, module, name);\n }\n\n type(module: string, name: string): void {\n add(this.types, module, name);\n }\n\n /** The full `import ...` block text, one statement per line, no trailing blank line. */\n render(): string {\n const lines: { spec: string; rank: 0 | 1; stmt: string }[] = [];\n for (const [spec, names] of this.values) {\n lines.push({ spec, rank: 0, stmt: importStmt(spec, [...names], false) });\n }\n for (const [spec, names] of this.types) {\n lines.push({ spec, rank: 1, stmt: importStmt(spec, [...names], true) });\n }\n lines.sort((a, b) => a.spec.localeCompare(b.spec) || a.rank - b.rank);\n return lines.map((l) => l.stmt).join('\\n');\n }\n}\n\nfunction add(\n map: Map<string, Set<string>>,\n module: string,\n name: string,\n): void {\n const set = map.get(module) ?? new Set<string>();\n set.add(name);\n map.set(module, set);\n}\n\nfunction importStmt(spec: string, names: string[], typeOnly: boolean): string {\n const sorted = [...names].sort((a, b) => a.localeCompare(b)).join(', ');\n const kw = typeOnly ? 'import type' : 'import';\n return `${kw} { ${sorted} } from '${spec}';`;\n}\n","/**\n * `Field` -> typed `FormControl<T>` control-tree text.\n *\n * `T` mirrors the Zod-inferred type of the field, reconstructed from the IR\n * `Field` directly (never by parsing Zod source text) — see\n * `generator-angular/technical.md` §Control type per scalar.\n */\nimport type { Entity, Field, ScalarType, SourceIR } from '@kurotako/ir';\nimport { resolveEnum } from '@kurotako/ir';\nimport type { Variant } from '../names.js';\n\n/** Resolve an enum ref (`FieldType.kind === 'enum'`) to the Zod-emitted union type name. */\nexport type ZodEnumTypeName = (ref: string) => string;\n\nconst SCALAR_BASE: Record<ScalarType, string> = {\n string: 'string',\n uuid: 'string',\n decimal: 'string',\n bytes: 'string',\n int: 'number',\n float: 'number',\n bigint: 'bigint',\n boolean: 'boolean',\n date: 'Date',\n datetime: 'Date',\n json: 'unknown',\n};\n\nfunction baseType(field: Field, zodEnumTypeName: ZodEnumTypeName): string {\n switch (field.type.kind) {\n case 'scalar':\n return SCALAR_BASE[field.type.scalar];\n case 'enum':\n return zodEnumTypeName(field.type.ref);\n case 'unknown':\n return 'unknown';\n }\n}\n\n/** The `FormControl<T>` type argument for a field: `list` wraps, then `nullable`. */\nexport function controlType(\n field: Field,\n zodEnumTypeName: ZodEnumTypeName,\n): string {\n let t = baseType(field, zodEnumTypeName);\n if (field.list) {\n t = `${t}[]`;\n }\n if (field.nullable) {\n t = `${t} | null`;\n }\n return t;\n}\n\n/** Resolve an enum ref to a real member literal for `initExpr`'s enum zero. */\nexport type EnumZero = (ref: string) => string | undefined;\n\n/** `EnumZero` backed by the IR: the enum's first declared member, in source order. */\nexport function enumZeroFromSource(source: SourceIR, entity: Entity): EnumZero {\n return (ref) => resolveEnum(source, entity, ref)?.values[0]?.name;\n}\n\n/**\n * A valid, always-assignable non-null literal for the field's base type. Never\n * `null` — the Zod-inferred DTO type for a field with no literal default is\n * `T` (required) or `T | undefined` (optional), never `T | null`; only a\n * `field.nullable` field's DTO type includes `null`, and `initExpr` handles\n * that case itself rather than folding it in here.\n */\nfunction zeroValue(field: Field, enumZero?: EnumZero): string {\n if (field.type.kind === 'scalar') {\n switch (field.type.scalar) {\n case 'string':\n case 'uuid':\n case 'decimal':\n case 'bytes':\n return \"''\";\n case 'int':\n case 'float':\n return '0';\n case 'bigint':\n return '0n';\n case 'boolean':\n return 'false';\n case 'date':\n case 'datetime':\n return 'new Date(0)';\n case 'json':\n // control type is `unknown`: `| undefined` is trivially assignable.\n return 'undefined';\n }\n }\n if (field.type.kind === 'enum') {\n // Unlike a scalar zero, `x ?? undefined` never actually strips\n // `| undefined` from `x`'s type (TS keeps it, since the fallback's own\n // type still includes it) — so a non-nullable enum control with no\n // literal default needs a *real* member literal, not `undefined`, or\n // `new FormControl(..., { nonNullable: true })` fails to type-check\n // against the field's exact union type.\n const value = enumZero?.(field.type.ref);\n return value === undefined ? 'undefined' : JSON.stringify(value);\n }\n return 'undefined';\n}\n\n/** The control's initial-value expression: a literal default, else the type's zero. */\nexport function initExpr(field: Field, enumZero?: EnumZero): string {\n if (field.list) {\n return field.default?.kind === 'value'\n ? JSON.stringify(field.default.value)\n : '[]';\n }\n if (field.default?.kind === 'value') {\n return JSON.stringify(field.default.value);\n }\n if (field.nullable) {\n return 'null';\n }\n return zeroValue(field, enumZero);\n}\n\n/**\n * `new FormControl(...)` construction expression for a field.\n * `typeArg` is the field's already-resolved `controlType(...)` text; `sourceExpr`\n * is the value expression to seed the control from (an `init?.x ?? <zero>` for\n * `Create`, a bare `value.x` for `Update` — the caller decides). `sourceExpr` is\n * already `null`-inclusive when `field.nullable` (via `initExpr`'s own fallback,\n * or the Update DTO's own field type) — appending another `?? null` here would\n * be provably-redundant code TS flags as an error (`This expression is never\n * nullish`), not just dead weight.\n */\nexport function controlExpr(\n field: Field,\n typeArg: string,\n sourceExpr: string,\n): string {\n if (field.nullable) {\n return `new FormControl<${typeArg}>(${sourceExpr})`;\n }\n return `new FormControl(${sourceExpr}, { nonNullable: true })`;\n}\n\nexport interface ControlEntry {\n name: string;\n /** The full control-tree member type, e.g. `FormControl<string>` or (deep mode) `FormGroup<PostCreateDeepFormControls>`. */\n fullType: string;\n}\n\n/** One `ControlEntry` for a scalar/enum field: `name: FormControl<T>`. */\nexport function fieldControlEntry(\n field: Field,\n zodEnumTypeName: ZodEnumTypeName,\n): ControlEntry {\n return {\n name: field.name,\n fullType: `FormControl<${controlType(field, zodEnumTypeName)}>`,\n };\n}\n\n/** `export interface <Entity><Variant>[Deep]FormControls { ... }` text. */\nexport function controlsInterface(\n interfaceName: string,\n entries: ControlEntry[],\n): string {\n if (entries.length === 0) {\n return `export interface ${interfaceName} {}`;\n }\n const body = entries.map((e) => ` ${e.name}: ${e.fullType};`).join('\\n');\n return `export interface ${interfaceName} {\\n${body}\\n}`;\n}\n\nexport type { Variant };\n","/**\n * `relations: 'deep'` control-tree entries: nested `FormGroup` for a to-one\n * relation, `FormArray` for a to-many one. `relations: 'flat'` (default) emits\n * nothing for relation objects — the caller simply never calls this module\n * (`generator-angular/technical.md` §Relations).\n *\n * Cross-source relations always degrade to flat (FK scalar only) + a `debug`\n * log, consistent with `gen-zod`'s deep family.\n */\nimport type { Logger } from '@kurotako/core';\nimport type { Entity, Relation } from '@kurotako/ir';\nimport { isCrossSource } from '@kurotako/ir';\nimport type { Variant } from '../names.js';\nimport {\n controlsTypeName,\n formTypeName,\n relationBuilderMethod,\n} from '../names.js';\nimport type { ControlEntry } from './controls.js';\n\nexport interface DeepRelation {\n relation: Relation;\n many: boolean;\n /** The `ControlEntry` this relation contributes to the deep control-tree interface. */\n entry: ControlEntry;\n /** `<Target><Variant>DeepForm` — the target's `FormGroup<...>` type alias. */\n targetFormType: string;\n /** `add<Relation><Variant>` — the builder method name on the reactive factory. */\n builderMethod: string;\n}\n\n/**\n * Every non-cross-source relation on `entity`, rendered as a deep control-tree\n * entry. Cross-source relations are skipped (flat degrade) and logged.\n */\nexport function deepRelations(\n entity: Entity,\n variant: Variant,\n namespace: string,\n logger?: Logger,\n): DeepRelation[] {\n const out: DeepRelation[] = [];\n for (const relation of entity.relations) {\n if (isCrossSource(namespace, relation)) {\n logger?.debug(\n `gen-angular: relation '${relation.name}' targets another source ('${relation.target.namespace}.${relation.target.entity}'); degrading to the flat FK scalar in deep mode`,\n );\n continue;\n }\n\n const many = relation.cardinality === 'many';\n const targetControls = controlsTypeName(\n relation.target.entity,\n variant,\n 'Deep',\n );\n const targetFormType = formTypeName(\n relation.target.entity,\n variant,\n 'Deep',\n );\n const groupType = `FormGroup<${targetControls}>`;\n const fullType = many ? `FormArray<${groupType}>` : groupType;\n\n out.push({\n relation,\n many,\n entry: { name: relation.name, fullType },\n targetFormType,\n builderMethod: relationBuilderMethod(relation.name, variant),\n });\n }\n return out;\n}\n","/**\n * Per-entity field-set derivation for the two form variants.\n *\n * The `Create` / `Update` field selection comes from `@kurotako/ir`'s\n * shared-decision helpers (`createFields`, `updateFields`) — the same helpers\n * `gen-zod` calls — so the control tree and the Zod schema it delegates\n * validation to agree by construction, not by two implementations happening to\n * match (`generator-angular/technical.md` §Variant field sets).\n */\nimport type { Entity, Field } from '@kurotako/ir';\nimport { createFields, updateFields } from '@kurotako/ir';\nimport type { Variant } from '../names.js';\n\n/** The scalar/enum field set for a form variant, in IR declaration order. */\nexport function variantFields(entity: Entity, variant: Variant): Field[] {\n return variant === 'Create' ? createFields(entity) : updateFields(entity);\n}\n","/**\n * Reactive typed-forms surface: control-tree interfaces, `FormGroup` type\n * aliases, and one `@Injectable({ providedIn: 'root' })` factory service per\n * entity (`generator-angular/technical.md` §Reactive factory service).\n *\n * `relations: 'deep'`: Angular's `FormGroup<TControl>` requires every control\n * to be a concrete `AbstractControl` — a control key typed `FormGroup<X> |\n * undefined` fails `FormGroup`'s own generic constraint — so a to-one\n * relation's nested group is built eagerly, by delegating to the target\n * entity's own injected `FormFactory`. A to-many relation's `FormArray`\n * starts empty (no eager nested item), which is what keeps a realistic\n * (many-side-breaks-the-cycle) entity graph from recursing forever; a\n * required one-to-one cycle on both sides would still recurse at runtime —\n * accepted, rare/pathological shape, same spirit as `gen-zod`'s deep-family\n * limitations. `add<Relation><Variant>()` methods let the consumer replace a\n * to-one nested group or push a new to-many item after construction.\n */\nimport type { GeneratorArtifact, Logger } from '@kurotako/core';\nimport type { Entity, SourceIR } from '@kurotako/ir';\nimport {\n controlsTypeName,\n factoryMethod,\n factoryName,\n formTypeName,\n type Variant,\n} from '../names.js';\nimport type { AngularGeneratorOptions } from '../options.js';\nimport { zodEnum, zodModule, zodSymbol } from '../zod-artifact.js';\nimport {\n type ControlEntry,\n controlExpr,\n controlsInterface,\n controlType,\n type EnumZero,\n enumZeroFromSource,\n fieldControlEntry,\n initExpr,\n} from './controls.js';\nimport type { ImportsRecorder } from './imports.js';\nimport { deepRelations } from './relations.js';\nimport { variantFields } from './variants.js';\n\nfunction lowerFirst(s: string): string {\n return s.length === 0 ? s : s.charAt(0).toLowerCase() + s.slice(1);\n}\n\nexport function reactiveEntity(\n entity: Entity,\n namespace: string,\n source: SourceIR,\n options: AngularGeneratorOptions,\n zod: GeneratorArtifact,\n imports: ImportsRecorder,\n logger?: Logger,\n): string {\n const deep = options.relations === 'deep';\n const enumZero = enumZeroFromSource(source, entity);\n imports.value('@angular/core', 'Injectable');\n imports.value('@angular/forms', 'FormControl');\n imports.value('@angular/forms', 'FormGroup');\n\n const zodEnumTypeName = (ref: string): string => {\n const e = zodEnum(zod, namespace, ref);\n imports.type(e.module, e.typeName);\n return e.typeName;\n };\n\n const blocks: string[] = [];\n const injectedFactories = new Map<string, string>(); // target entity -> ctor param name\n\n for (const variant of ['Create', 'Update'] as Variant[]) {\n const family = deep ? 'Deep' : '';\n const schemaRole = deep\n ? variant === 'Create'\n ? ('createDeepSchema' as const)\n : ('updateDeepSchema' as const)\n : variant === 'Create'\n ? ('createSchema' as const)\n : ('updateSchema' as const);\n const typeRole = deep\n ? variant === 'Create'\n ? ('createDeepType' as const)\n : ('updateDeepType' as const)\n : variant === 'Create'\n ? ('createType' as const)\n : ('updateType' as const);\n\n const module = zodModule(zod, namespace, entity.name);\n const schemaId = zodSymbol(zod, namespace, entity.name, schemaRole);\n const typeId = zodSymbol(zod, namespace, entity.name, typeRole);\n imports.value(module, schemaId);\n imports.type(module, typeId);\n imports.value(`${namespace}/angular/zod-forms.runtime`, 'zodValidator');\n\n const interfaceName = controlsTypeName(entity.name, variant, family);\n const formType = formTypeName(entity.name, variant, family);\n\n const fieldEntries: ControlEntry[] = variantFields(entity, variant).map(\n (field) => fieldControlEntry(field, zodEnumTypeName),\n );\n\n const relations = deep\n ? deepRelations(entity, variant, namespace, logger)\n : [];\n const manyRelations = relations.filter((r) => r.many);\n if (manyRelations.length > 0) {\n imports.value('@angular/forms', 'FormArray');\n }\n for (const rel of relations) {\n const targetModule = `${namespace}/angular/${rel.relation.target.entity}.form`;\n imports.type(\n targetModule,\n controlsTypeName(rel.relation.target.entity, variant, 'Deep'),\n );\n imports.type(targetModule, rel.targetFormType);\n if (!injectedFactories.has(rel.relation.target.entity)) {\n const paramName = `${lowerFirst(rel.relation.target.entity)}FormFactory`;\n injectedFactories.set(rel.relation.target.entity, paramName);\n imports.value(targetModule, factoryName(rel.relation.target.entity));\n }\n // The `add<Relation><Variant>()` builder (to-many only) takes an\n // `init` / `value` for the *target* entity's own create/update DTO.\n if (rel.many) {\n const targetTypeRole =\n deep && variant === 'Create'\n ? ('createDeepType' as const)\n : deep && variant === 'Update'\n ? ('updateDeepType' as const)\n : variant === 'Create'\n ? ('createType' as const)\n : ('updateType' as const);\n const targetZodModule = zodModule(\n zod,\n namespace,\n rel.relation.target.entity,\n );\n const targetTypeId = zodSymbol(\n zod,\n namespace,\n rel.relation.target.entity,\n targetTypeRole,\n );\n imports.type(targetZodModule, targetTypeId);\n }\n }\n\n blocks.push(\n controlsInterface(interfaceName, [\n ...fieldEntries,\n ...relations.map((r) => r.entry),\n ]),\n );\n blocks.push(`export type ${formType} = FormGroup<${interfaceName}>;`);\n }\n\n blocks.push(\n renderFactoryClass(\n entity,\n namespace,\n options,\n zod,\n injectedFactories,\n enumZero,\n ),\n );\n\n return blocks.join('\\n\\n');\n}\n\nfunction renderFactoryClass(\n entity: Entity,\n namespace: string,\n options: AngularGeneratorOptions,\n zod: GeneratorArtifact,\n injectedFactories: Map<string, string>,\n enumZero: EnumZero,\n): string {\n const deep = options.relations === 'deep';\n const className = factoryName(entity.name);\n\n const ctorParams = [...injectedFactories.entries()]\n .map(\n ([target, param]) => `private readonly ${param}: ${factoryName(target)}`,\n )\n .join(', ');\n const ctor =\n ctorParams.length > 0 ? `\\n constructor(${ctorParams}) {}\\n` : '';\n\n const methods: string[] = [];\n for (const variant of ['Create', 'Update'] as Variant[]) {\n methods.push(\n renderFactoryMethod(\n entity,\n namespace,\n variant,\n options,\n zod,\n injectedFactories,\n enumZero,\n ),\n );\n }\n\n if (deep) {\n for (const variant of ['Create', 'Update'] as Variant[]) {\n // Only the to-many side needs a builder: a to-one nested group is\n // already built eagerly (see the module docstring), and its target\n // factory's Update method requires a value this method has no natural\n // source for.\n const relations = deepRelations(\n entity,\n variant,\n namespace,\n undefined,\n ).filter((r) => r.many);\n for (const rel of relations) {\n methods.push(\n renderBuilderMethod(\n entity,\n namespace,\n variant,\n options,\n zod,\n rel,\n injectedFactories,\n ),\n );\n }\n }\n }\n\n const body = [\n ctor,\n ...methods.map((m) => `\\n ${m.split('\\n').join('\\n ')}\\n`),\n ]\n .join('')\n .trimEnd();\n\n return `@Injectable({ providedIn: 'root' })\\nexport class ${className} {\\n${body}\\n}`;\n}\n\nfunction renderFactoryMethod(\n entity: Entity,\n namespace: string,\n variant: Variant,\n options: AngularGeneratorOptions,\n zod: GeneratorArtifact,\n injectedFactories: Map<string, string>,\n enumZero: EnumZero,\n): string {\n const deep = options.relations === 'deep';\n const family = deep ? 'Deep' : '';\n const typeRole =\n deep && variant === 'Create'\n ? ('createDeepType' as const)\n : deep && variant === 'Update'\n ? ('updateDeepType' as const)\n : variant === 'Create'\n ? ('createType' as const)\n : ('updateType' as const);\n const schemaRole =\n deep && variant === 'Create'\n ? ('createDeepSchema' as const)\n : deep && variant === 'Update'\n ? ('updateDeepSchema' as const)\n : variant === 'Create'\n ? ('createSchema' as const)\n : ('updateSchema' as const);\n\n const typeId = zodSymbol(zod, namespace, entity.name, typeRole);\n const schemaId = zodSymbol(zod, namespace, entity.name, schemaRole);\n const interfaceName = controlsTypeName(entity.name, variant, family);\n const formType = formTypeName(entity.name, variant, family);\n const methodName = factoryMethod(variant);\n\n const zodEnumTypeName = (ref: string): string => ref;\n const fields = variantFields(entity, variant);\n const lines = fields.map((field) => {\n const typeArg = controlType(field, zodEnumTypeName);\n // The Update Zod DTO is a whole-object `.partial()` (gen-zod), so every\n // field — including one that is otherwise required — is `T | undefined`\n // there too; both variants therefore need the same `?? <zero>` fallback.\n const accessor =\n variant === 'Create' ? `init?.${field.name}` : `value.${field.name}`;\n const source = `${accessor} ?? ${initExpr(field, enumZero)}`;\n return ` ${field.name}: ${controlExpr(field, typeArg, source)},`;\n });\n\n const relations = deep\n ? deepRelations(entity, variant, namespace, undefined)\n : [];\n const relationLines = relations.map((r) => {\n if (r.many) {\n const targetControls = controlsTypeName(\n r.relation.target.entity,\n variant,\n 'Deep',\n );\n return ` ${r.entry.name}: new FormArray<FormGroup<${targetControls}>>([]),`;\n }\n const factoryParam =\n injectedFactories.get(r.relation.target.entity) ??\n `${lowerFirst(r.relation.target.entity)}FormFactory`;\n // The Update DTO's whole-object `.partial()` also makes a required\n // relation optional at the type level (same as scalar fields above);\n // `createUpdateForm` itself still requires a concrete value, so the\n // caller is expected to supply the nested relation on a value it read\n // back — asserted here rather than defaulted (there is no meaningful\n // \"empty\" nested entity to fall back to).\n const nestedArg =\n variant === 'Create'\n ? `init?.${r.relation.name}`\n : `value.${r.relation.name}!`;\n return ` ${r.entry.name}: this.${factoryParam}.${factoryMethod(variant)}(${nestedArg}),`;\n });\n\n const groupBody = [...lines, ...relationLines].join('\\n');\n const paramList =\n variant === 'Create' ? `init?: Partial<${typeId}>` : `value: ${typeId}`;\n\n return `${methodName}(${paramList}): ${formType} {\\n return new FormGroup<${interfaceName}>({\\n${groupBody}\\n }, { validators: [zodValidator(${schemaId})] });\\n}`;\n}\n\n/** Only ever called for a to-many relation (see the caller). */\nfunction renderBuilderMethod(\n entity: Entity,\n namespace: string,\n variant: Variant,\n options: AngularGeneratorOptions,\n zod: GeneratorArtifact,\n rel: ReturnType<typeof deepRelations>[number],\n injectedFactories: Map<string, string>,\n): string {\n const deep = options.relations === 'deep';\n const target = rel.relation.target.entity;\n const factoryParam =\n injectedFactories.get(target) ?? `${lowerFirst(target)}FormFactory`;\n const formType = formTypeName(entity.name, variant, 'Deep');\n const targetFormType = rel.targetFormType;\n const method = rel.builderMethod;\n\n const targetTypeRole =\n deep && variant === 'Create'\n ? ('createDeepType' as const)\n : deep && variant === 'Update'\n ? ('updateDeepType' as const)\n : variant === 'Create'\n ? ('createType' as const)\n : ('updateType' as const);\n const targetTypeId = zodSymbol(zod, namespace, target, targetTypeRole);\n\n const param =\n variant === 'Create'\n ? `init?: Partial<${targetTypeId}>`\n : `value: ${targetTypeId}`;\n const createCall = `this.${factoryParam}.${factoryMethod(variant)}(${variant === 'Create' ? 'init' : 'value'})`;\n\n return `${method}(form: ${formType}, ${param}): ${targetFormType} {\\n const group = ${createCall};\\n form.controls.${rel.relation.name}.push(group);\\n return group;\\n}`;\n}\n","/**\n * Signal Forms surface: pure exported `schema` + model-factory functions, no DI\n * wrapper (`generator-angular/technical.md` §Signal Forms schema + model\n * factory), plus a `create<Entity><Variant>Form` convenience wrapper around\n * `form(signal(model), schema)`. Every `@angular/forms/signals` call site\n * lives here and in `emit/runtime.ts` (the `zodTreeValidate` half) so a\n * secondary-API change on that experimental surface is a single-file update.\n *\n * The wrapper is a plain function, not a DI service — `form()` resolves its\n * injector from Angular's ambient injection context when none is passed\n * explicitly (same rule `inject()` follows), so calling the wrapper from a\n * component field initializer or constructor works exactly like calling\n * `form()` inline there.\n */\nimport type { GeneratorArtifact, Logger } from '@kurotako/core';\nimport type { Entity, SourceIR } from '@kurotako/ir';\nimport {\n modelFactoryName,\n signalFormFactoryName,\n signalSchemaName,\n type Variant,\n} from '../names.js';\nimport type { AngularGeneratorOptions } from '../options.js';\nimport { zodModule, zodSymbol } from '../zod-artifact.js';\nimport { enumZeroFromSource, initExpr } from './controls.js';\nimport type { ImportsRecorder } from './imports.js';\nimport { deepRelations } from './relations.js';\nimport { variantFields } from './variants.js';\n\nexport function signalEntity(\n entity: Entity,\n namespace: string,\n source: SourceIR,\n options: AngularGeneratorOptions,\n zod: GeneratorArtifact,\n imports: ImportsRecorder,\n logger?: Logger,\n): string {\n const deep = options.relations === 'deep';\n const enumZero = enumZeroFromSource(source, entity);\n imports.value('@angular/forms/signals', 'schema');\n imports.value('@angular/forms/signals', 'form');\n imports.type('@angular/forms/signals', 'FieldTree');\n imports.value('@angular/core', 'signal');\n\n const blocks: string[] = [];\n for (const variant of ['Create', 'Update'] as Variant[]) {\n const typeRole =\n deep && variant === 'Create'\n ? ('createDeepType' as const)\n : deep && variant === 'Update'\n ? ('updateDeepType' as const)\n : variant === 'Create'\n ? ('createType' as const)\n : ('updateType' as const);\n const schemaRole =\n deep && variant === 'Create'\n ? ('createDeepSchema' as const)\n : deep && variant === 'Update'\n ? ('updateDeepSchema' as const)\n : variant === 'Create'\n ? ('createSchema' as const)\n : ('updateSchema' as const);\n\n const module = zodModule(zod, namespace, entity.name);\n const typeId = zodSymbol(zod, namespace, entity.name, typeRole);\n const schemaId = zodSymbol(zod, namespace, entity.name, schemaRole);\n imports.type(module, typeId);\n imports.value(module, schemaId);\n imports.value(`${namespace}/angular/zod-forms.runtime`, 'zodTreeValidate');\n\n const fields = variantFields(entity, variant);\n const fieldLines = fields.map(\n (field) =>\n ` ${field.name}: init?.${field.name} ?? ${initExpr(field, enumZero)},`,\n );\n\n const relations = deep\n ? deepRelations(entity, variant, namespace, logger)\n : [];\n // A to-one relation the Zod deep DTO marks required (any relation that\n // isn't itself optional, in the Create variant) can't be seeded with\n // `undefined` — build it eagerly via the target's own model factory\n // instead, imported as a value from its `.form` module.\n const relationLines = relations.map((rel) => {\n if (rel.many) {\n return ` ${rel.relation.name}: [],`;\n }\n const targetModule = `${namespace}/angular/${rel.relation.target.entity}.form`;\n const targetModelFactory = modelFactoryName(\n rel.relation.target.entity,\n variant,\n );\n imports.value(targetModule, targetModelFactory);\n return ` ${rel.relation.name}: ${targetModelFactory}(init?.${rel.relation.name}),`;\n });\n\n const modelBody = [...fieldLines, ...relationLines].join('\\n');\n const modelName = modelFactoryName(entity.name, variant);\n blocks.push(\n `export function ${modelName}(init?: Partial<${typeId}>): ${typeId} {\\n return {\\n${modelBody}\\n };\\n}`,\n );\n\n const schemaConst = signalSchemaName(entity.name, variant);\n blocks.push(\n `export const ${schemaConst} = schema<${typeId}>((path) => {\\n zodTreeValidate(path, ${schemaId});\\n});`,\n );\n\n const formFactoryName = signalFormFactoryName(entity.name, variant);\n blocks.push(\n `export function ${formFactoryName}(init?: Partial<${typeId}>): FieldTree<${typeId}> {\\n return form(signal(${modelName}(init)), ${schemaConst});\\n}`,\n );\n }\n\n return blocks.join('\\n\\n');\n}\n","/**\n * One entity -> `<ns>/angular/<entity>.form.ts` source text: a sorted import\n * block, then the reactive block (control-tree interfaces + `@Injectable`\n * factory, when `forms` includes `'reactive'`) and the Signal Forms block\n * (schema + model factory, when `forms` includes `'signal'`)\n * (`generator-angular/technical.md` §File layout).\n */\nimport type { GeneratorArtifact, Logger } from '@kurotako/core';\nimport type { Entity, SourceIR } from '@kurotako/ir';\nimport type { AngularGeneratorOptions } from '../options.js';\nimport { ImportsRecorder } from '../render/imports.js';\nimport { reactiveEntity } from '../render/reactive.js';\nimport { signalEntity } from '../render/signal.js';\n\nexport function emitEntity(\n entity: Entity,\n namespace: string,\n source: SourceIR,\n options: AngularGeneratorOptions,\n zod: GeneratorArtifact,\n logger?: Logger,\n): string {\n const imports = new ImportsRecorder();\n const blocks: string[] = [];\n\n if (options.forms.includes('reactive')) {\n blocks.push(\n reactiveEntity(entity, namespace, source, options, zod, imports, logger),\n );\n }\n if (options.forms.includes('signal')) {\n blocks.push(\n signalEntity(entity, namespace, source, options, zod, imports, logger),\n );\n }\n\n const importBlock = imports.render();\n return `${[importBlock, '', ...blocks].join('\\n').trimEnd()}\\n`;\n}\n","/**\n * `<ns>/angular/zod-forms.runtime.ts` — hand-written, deterministic source (no\n * per-entity content). Emitted once per namespace whenever the source has >= 1\n * entity and `forms` is non-empty (`generator-angular/technical.md` §File\n * layout).\n *\n * `zodValidator` (reactive half): a group-level `ValidatorFn` that\n * `safeParse`s against the Zod schema and distributes each issue onto the\n * matching descendant control by `issue.path`, clearing stale `zod` keys and\n * guarding against a `setErrors`-triggered validation loop\n * (`generator-angular/technical.md` §`zodValidator`).\n *\n * `zodTreeValidate` (Signal Forms half): wraps `@angular/forms/signals`'\n * tree-level validator primitive. This is the *only* file (besides\n * `render/signal.ts`) referencing that experimental surface, so a secondary-API\n * shift on a future Angular minor is a single-file update\n * (`generator-angular/technical.md` §Signal Forms schema + model factory).\n */\nimport type { SourceIR } from '@kurotako/ir';\nimport type { AngularGeneratorOptions } from '../options.js';\n\nconst ZOD_VALIDATOR = `export function zodValidator(schema: ZodType): ValidatorFn {\n return (group: AbstractControl) => {\n const result = schema.safeParse(group.getRawValue());\n const touched = new Set<AbstractControl>();\n const rootIssues: { path: (string | number)[]; message: string }[] = [];\n\n if (!result.success) {\n for (const issue of result.error.issues) {\n const path = issue.path.map(String).join('.');\n const control = path === '' ? null : group.get(path);\n if (control !== null && control !== undefined) {\n setZodError(control, issue.message);\n touched.add(control);\n } else {\n rootIssues.push({ path: issue.path as (string | number)[], message: issue.message });\n }\n }\n }\n\n for (const control of collectControls(group)) {\n if (control !== group && !touched.has(control)) {\n clearZodError(control);\n }\n }\n\n if (rootIssues.length === 0) {\n clearZodError(group);\n return null;\n }\n\n const formErrors: string[] = [];\n const fieldErrors: Record<string, string[]> = {};\n for (const issue of rootIssues) {\n if (issue.path.length === 0) {\n formErrors.push(issue.message);\n } else {\n const key = String(issue.path[0]);\n (fieldErrors[key] ??= []).push(issue.message);\n }\n }\n\n const zodError = { formErrors, fieldErrors };\n setZodError(group, zodError);\n return { zod: zodError };\n };\n}\n\nfunction setZodError(control: AbstractControl, message: unknown): void {\n const current = control.errors;\n if (current !== null && sameZodError(current.zod, message)) {\n return;\n }\n control.setErrors({ ...current, zod: message }, { emitEvent: false });\n}\n\nfunction clearZodError(control: AbstractControl): void {\n const current = control.errors;\n if (current === null || current === undefined || !('zod' in current)) {\n return;\n }\n const { zod: _discard, ...rest } = current;\n control.setErrors(Object.keys(rest).length > 0 ? rest : null, {\n emitEvent: false,\n });\n}\n\nfunction sameZodError(a: unknown, b: unknown): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\nfunction collectControls(control: AbstractControl): AbstractControl[] {\n const out: AbstractControl[] = [control];\n const children = (control as { controls?: unknown }).controls;\n if (children !== null && typeof children === 'object') {\n for (const child of Object.values(children as Record<string, AbstractControl>)) {\n out.push(...collectControls(child));\n }\n }\n return out;\n}`;\n\nconst ZOD_TREE_VALIDATE = `export function zodTreeValidate<T>(\n path: SchemaPath<T>,\n schema: ZodType<T>,\n): void {\n validateTree(path, (ctx) => {\n const result = schema.safeParse(ctx.value());\n if (result.success) {\n return undefined;\n }\n return result.error.issues.map((issue) => ({\n kind: 'custom' as const,\n message: issue.message,\n // Dynamically walked from the Zod issue path against the field tree's\n // runtime shape; ValidationError.fieldTree accepts undefined for a\n // pathless issue, so a same-shaped object (rather than branching on\n // whether one was found) keeps this a single, uniform return type.\n fieldTree: resolveFieldTree(ctx.fieldTree, issue.path) as\n | ReadonlyFieldTree<unknown>\n | undefined,\n }));\n });\n}\n\nfunction resolveFieldTree(root: unknown, path: readonly PropertyKey[]): unknown {\n return path.reduce<unknown>((node, key) => {\n if (node === null || typeof node !== 'object') {\n return undefined;\n }\n return (node as Record<PropertyKey, unknown>)[key];\n }, root);\n}`;\n\nexport function emitRuntime(\n _source: SourceIR,\n options: AngularGeneratorOptions,\n): string {\n const reactive = options.forms.includes('reactive');\n const signal = options.forms.includes('signal');\n\n const imports: string[] = [];\n if (reactive) {\n imports.push(\n \"import type { AbstractControl, ValidatorFn } from '@angular/forms';\",\n );\n }\n if (signal) {\n imports.push(\n \"import type { ReadonlyFieldTree, SchemaPath } from '@angular/forms/signals';\",\n \"import { validateTree } from '@angular/forms/signals';\",\n );\n }\n imports.push(\"import type { ZodType } from 'zod';\");\n\n const blocks: string[] = [];\n if (reactive) {\n blocks.push(ZOD_VALIDATOR);\n }\n if (signal) {\n blocks.push(ZOD_TREE_VALIDATE);\n }\n\n return `${[imports.join('\\n'), '', ...blocks].join('\\n').trimEnd()}\\n`;\n}\n","/**\n * Valibot schema for `@kurotako/gen-angular`'s `options`, plus the inferred type.\n * `@kurotako/config` validates a config entry's `options` against this schema and\n * curries it away before `@kurotako/core` sees the generator.\n */\nimport * as v from 'valibot';\n\nexport const AngularGeneratorOptions = v.object({\n /** Which form surfaces to emit. Default: both. */\n forms: v.optional(v.array(v.picklist(['reactive', 'signal'])), [\n 'reactive',\n 'signal',\n ]),\n /** Relation handling: flat (FK scalars only) or deep (nested FormGroup / FormArray). */\n relations: v.optional(v.picklist(['flat', 'deep']), 'flat'),\n});\n\nexport type AngularGeneratorOptions = v.InferOutput<\n typeof AngularGeneratorOptions\n>;\n"],"mappings":"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","names":["entityKey","lowerFirst"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/generator.ts","../src/artifact.ts","../src/names.ts","../src/zod-artifact.ts","../src/emit/barrel.ts","../src/render/imports.ts","../src/render/controls.ts","../src/render/unions.ts","../src/render/relations.ts","../src/render/variants.ts","../src/render/reactive.ts","../src/render/signal.ts","../src/emit/entity.ts","../src/emit/runtime.ts","../src/options.ts"],"sourcesContent":["/**\n * `@kurotako/gen-angular` error classes.\n *\n * `AngularGenError` is a plain `Error` subclass carrying a stable `code`; the\n * Angular generator has no dependency on `@kurotako/core` at runtime, and\n * `@kurotako/core` wraps any throw from `generate()` as a `DriverError` for the\n * CLI's single `instanceof TakoError` catch.\n *\n * Codes: `angular_missing_zod_symbol`, `angular_missing_zod_namespace`.\n */\n\nexport class AngularGenError extends Error {\n readonly code: string;\n\n constructor(code: string, message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = new.target.name;\n this.code = code;\n }\n}\n\n/**\n * The Zod artifact has no entry (or no `role` symbol) for `${ns}.${entity}`.\n * `dependsOn: ['zod']` guarantees the dependency ran, but a role can still be\n * absent if the consumed `gen-zod` version predates it.\n */\nexport class MissingZodSymbolError extends AngularGenError {\n readonly entityKey: string;\n readonly role: string;\n\n constructor(entityKey: string, role: string) {\n super(\n 'angular_missing_zod_symbol',\n `Zod artifact for '${entityKey}' has no '${role}' symbol; regenerate with a gen-zod version that exposes it`,\n );\n this.entityKey = entityKey;\n this.role = role;\n }\n}\n\n/** The Zod artifact's `extra.perNamespace` has no entry for a namespace the IR carries. */\nexport class MissingZodNamespaceError extends AngularGenError {\n readonly namespace: string;\n\n constructor(namespace: string) {\n super(\n 'angular_missing_zod_namespace',\n `Zod artifact has no 'extra.perNamespace[${JSON.stringify(namespace)}]' entry`,\n );\n this.namespace = namespace;\n }\n}\n","/**\n * `angularGenerator` — the `@kurotako/gen-angular` driver.\n *\n * Hard `dependsOn: ['zod']`: core rejects a config that enables `angular`\n * without `zod`, and the topological order guarantees `ctx.dependencies.zod` is\n * always present here. `generate` is synchronous and pure: same IR + same Zod\n * artifact + same options -> deep-equal `GenOutput` (drift-guard requirement).\n */\nimport { defineGenerator } from '@kurotako/config';\nimport type { GenerateContext, GenOutput, VirtualFile } from '@kurotako/core';\nimport { buildArtifact } from './artifact.js';\nimport { emitBarrel } from './emit/barrel.js';\nimport { emitEntity } from './emit/entity.js';\nimport { emitRuntime } from './emit/runtime.js';\nimport { AngularGeneratorOptions } from './options.js';\n\nexport const angularGenerator = defineGenerator({\n name: 'angular',\n dependsOn: ['zod'],\n optionsSchema: AngularGeneratorOptions,\n\n generate(ctx: GenerateContext, options): GenOutput {\n const zod = ctx.dependencies.zod;\n if (zod === undefined) {\n throw new Error(\n \"gen-angular: 'zod' dependency artifact is missing at runtime despite dependsOn: ['zod']\",\n );\n }\n\n const files: VirtualFile[] = [];\n\n for (const [namespace, source] of Object.entries(ctx.ir.sources)) {\n const prefix = `${namespace}/angular`;\n const entities = Object.values(source.entities);\n const cyclicRefs = new Set<string>();\n for (const key of ctx.cycles) {\n const dot = key.indexOf('.');\n if (dot > 0 && key.slice(0, dot) === namespace) {\n cyclicRefs.add(key.slice(dot + 1));\n }\n }\n\n if (entities.length > 0 && options.forms.length > 0) {\n files.push({\n path: `${prefix}/zod-forms.runtime.ts`,\n content: emitRuntime(source, options),\n });\n }\n for (const entity of entities) {\n files.push({\n path: `${prefix}/${entity.name}.form.ts`,\n content: emitEntity(\n entity,\n namespace,\n source,\n options,\n zod,\n cyclicRefs,\n ctx.logger,\n ),\n });\n }\n files.push({\n path: `${prefix}/index.ts`,\n content: emitBarrel(source, options),\n });\n }\n\n return { files, artifact: buildArtifact(ctx.ir, zod, options) };\n },\n});\n","/**\n * Assemble the `GeneratorArtifact` (entities symbol matrix +\n * `AngularArtifactExtra`). No generator depends on `angular` in v1; the\n * artifact exists for uniformity and future consumers\n * (`generator-angular/technical.md` §Artifact).\n */\nimport type { EntitySymbols, GeneratorArtifact } from '@kurotako/core';\nimport type { IR } from '@kurotako/ir';\nimport { iterEntities } from '@kurotako/ir';\nimport {\n barrelModule,\n controlsTypeName,\n entityModule,\n factoryName,\n formTypeName,\n modelFactoryName,\n runtimeModule,\n signalFormFactoryName,\n signalSchemaName,\n} from './names.js';\nimport type { AngularGeneratorOptions } from './options.js';\nimport { zodExtra } from './zod-artifact.js';\n\nexport interface AngularArtifactExtra {\n forms: ('reactive' | 'signal')[];\n relations: 'flat' | 'deep';\n /** Echoed from the consumed `ZodArtifactExtra`. */\n zodVersion: 3 | 4;\n perNamespace: Record<\n string,\n {\n runtimeModule: string;\n barrelModule: string;\n }\n >;\n}\n\nfunction entitySymbols(\n entityName: string,\n options: AngularGeneratorOptions,\n): Record<string, string> {\n const symbols: Record<string, string> = {};\n const deep = options.relations === 'deep';\n const family = deep ? 'Deep' : ('' as const);\n\n if (options.forms.includes('reactive')) {\n const createControls = controlsTypeName(entityName, 'Create', family);\n const createForm = formTypeName(entityName, 'Create', family);\n const updateControls = controlsTypeName(entityName, 'Update', family);\n const updateForm = formTypeName(entityName, 'Update', family);\n\n symbols.createControls = createControls;\n symbols.createForm = createForm;\n symbols.updateControls = updateControls;\n symbols.updateForm = updateForm;\n symbols.factory = factoryName(entityName);\n\n if (deep) {\n symbols.createDeepControls = createControls;\n symbols.createDeepForm = createForm;\n symbols.updateDeepControls = updateControls;\n symbols.updateDeepForm = updateForm;\n }\n }\n\n if (options.forms.includes('signal')) {\n symbols.createSchema = signalSchemaName(entityName, 'Create');\n symbols.updateSchema = signalSchemaName(entityName, 'Update');\n symbols.createModel = modelFactoryName(entityName, 'Create');\n symbols.updateModel = modelFactoryName(entityName, 'Update');\n symbols.createSignalForm = signalFormFactoryName(entityName, 'Create');\n symbols.updateSignalForm = signalFormFactoryName(entityName, 'Update');\n }\n\n return symbols;\n}\n\nexport function buildArtifact(\n ir: IR,\n zod: GeneratorArtifact,\n options: AngularGeneratorOptions,\n): GeneratorArtifact {\n const entities: Record<string, EntitySymbols> = {};\n for (const { namespace, entity } of iterEntities(ir)) {\n entities[`${namespace}.${entity.name}`] = {\n module: entityModule(namespace, entity.name),\n symbols: entitySymbols(entity.name, options),\n };\n }\n // Type aliases produce no Angular form of their own and no `angular`-owned\n // export — `gen-zod`'s artifact already owns the alias schema/type symbols\n // and its `<ns>/zod/aliases.ts` is the single exporter. Re-declaring them\n // here would make the root-barrel ambiguity check flag a phantom conflict.\n // No generator depends on `angular` in v1, so nothing needs the re-exposure.\n\n const perNamespace: AngularArtifactExtra['perNamespace'] = {};\n for (const namespace of Object.keys(ir.sources)) {\n perNamespace[namespace] = {\n runtimeModule: runtimeModule(namespace),\n barrelModule: barrelModule(namespace),\n };\n }\n\n const extra: AngularArtifactExtra = {\n forms: options.forms,\n relations: options.relations,\n zodVersion: zodExtra(zod).zodVersion,\n perNamespace,\n };\n\n const peerDependencies = options.forms.includes('signal')\n ? { '@angular/core': '>=22', '@angular/forms': '>=22' }\n : { '@angular/core': '>=17', '@angular/forms': '>=17' };\n\n return { entities, peerDependencies, extra };\n}\n","/**\n * Deterministic identifier and module-specifier helpers.\n *\n * Identifiers are never namespace-prefixed (ADR-0004); the namespace only drives\n * the output location. The `angular/` sub-tree segment on every module specifier\n * is the output-modes amendment (one sub-tree per generator).\n */\n\n/** PascalCase form-variant token embedded in an identifier. */\nexport type Variant = 'Create' | 'Update';\n\n/** Relation family token embedded in a control-tree identifier. */\nexport type Family = '' | 'Deep';\n\nfunction lowerFirst(s: string): string {\n return s.length === 0 ? s : s.charAt(0).toLowerCase() + s.slice(1);\n}\n\n/** `${Entity}${Variant}${Family}FormControls`. */\nexport function controlsTypeName(\n entity: string,\n variant: Variant,\n family: Family = '',\n): string {\n return `${entity}${variant}${family}FormControls`;\n}\n\n/** `${Entity}${Variant}${Family}Form` — the `FormGroup<...>` type alias. */\nexport function formTypeName(\n entity: string,\n variant: Variant,\n family: Family = '',\n): string {\n return `${entity}${variant}${family}Form`;\n}\n\n/** `${Entity}FormFactory` — one `@Injectable` service per entity. */\nexport function factoryName(entity: string): string {\n return `${entity}FormFactory`;\n}\n\n/** `create${Variant}Form` — the factory method name. No suffix in deep mode. */\nexport function factoryMethod(variant: Variant): string {\n return `create${variant}Form`;\n}\n\n/**\n * `add${Relation}${Variant}` — the deep-mode nested-control builder method.\n * Variant-suffixed: `UserFormFactory` builds both `Create` and `Update` trees,\n * and a relation's target control type differs between them, so the two\n * variants cannot share one method name (would collide as a duplicate\n * implementation).\n */\nexport function relationBuilderMethod(\n relationName: string,\n variant: Variant,\n): string {\n const cap = `${relationName.charAt(0).toUpperCase()}${relationName.slice(1)}`;\n return `add${cap}${variant}`;\n}\n\n/** `${entity}${Variant}FormSchema`, camelCase — the Signal Forms schema const. */\nexport function signalSchemaName(entity: string, variant: Variant): string {\n return `${lowerFirst(entity)}${variant}FormSchema`;\n}\n\n/** `create${Entity}${Variant}Model` — the Signal Forms model-factory function. */\nexport function modelFactoryName(entity: string, variant: Variant): string {\n return `create${entity}${variant}Model`;\n}\n\n/**\n * `create${Entity}${Variant}Form` — the Signal Forms `form(signal(model), schema)`\n * convenience wrapper. Safe to call from anywhere `inject()` would work (a\n * component field initializer or constructor): `form()` resolves its\n * injector from the ambient injection context when none is passed\n * explicitly, same as calling it inline.\n */\nexport function signalFormFactoryName(\n entity: string,\n variant: Variant,\n): string {\n return `create${entity}${variant}Form`;\n}\n\n// --- module specifiers (POSIX, extension-less) -------------------------------\n\n/** `${ns}/angular/${entity}.form`. */\nexport function entityModule(namespace: string, entity: string): string {\n return `${namespace}/angular/${entity}.form`;\n}\n\n/** `${ns}/angular/zod-forms.runtime`. */\nexport function runtimeModule(namespace: string): string {\n return `${namespace}/angular/zod-forms.runtime`;\n}\n\n/** `${ns}/angular` — this generator's own sub-tree barrel. */\nexport function barrelModule(namespace: string): string {\n return `${namespace}/angular`;\n}\n","/**\n * Typed reader over `ctx.dependencies.zod` (the `GeneratorArtifact` produced by\n * `@kurotako/gen-zod`). `dependsOn: ['zod']` guarantees the entry is present;\n * this module only resolves identifiers + module specifiers, never re-derives a\n * Zod name (`generator-angular/technical.md` §Naming).\n *\n * Role keys consumed here (a subset of `gen-zod`'s full matrix): `createSchema`,\n * `createType`, `updateSchema`, `updateType`, and — in `relations: 'deep'` mode\n * only — `createDeepSchema`, `createDeepType`, `updateDeepSchema`,\n * `updateDeepType`.\n */\nimport type { EntitySymbols, GeneratorArtifact } from '@kurotako/core';\nimport type { ZodArtifactExtra } from '@kurotako/gen-zod';\nimport { MissingZodNamespaceError, MissingZodSymbolError } from './errors.js';\n\nexport type ZodRole =\n | 'createSchema'\n | 'createType'\n | 'updateSchema'\n | 'updateType'\n | 'createDeepSchema'\n | 'createDeepType'\n | 'updateDeepSchema'\n | 'updateDeepType';\n\n/** `${namespace}.${entity}` — the artifact's entity key. */\nexport function entityKey(namespace: string, entity: string): string {\n return `${namespace}.${entity}`;\n}\n\n/** The Zod `{ module, symbols }` entry for an entity, or throw if absent. */\nexport function zodEntity(\n zod: GeneratorArtifact,\n namespace: string,\n entity: string,\n): EntitySymbols {\n const key = entityKey(namespace, entity);\n const entry = zod.entities[key];\n if (entry === undefined) {\n throw new MissingZodSymbolError(key, '<entity>');\n }\n return entry;\n}\n\n/** Resolve one `role` on an entity to its Zod-emitted identifier. */\nexport function zodSymbol(\n zod: GeneratorArtifact,\n namespace: string,\n entity: string,\n role: ZodRole,\n): string {\n const key = entityKey(namespace, entity);\n const entry = zodEntity(zod, namespace, entity);\n const id = entry.symbols[role];\n if (id === undefined) {\n throw new MissingZodSymbolError(key, role);\n }\n return id;\n}\n\n/** The module specifier a sibling generator imports an entity's Zod schema from. */\nexport function zodModule(\n zod: GeneratorArtifact,\n namespace: string,\n entity: string,\n): string {\n return zodEntity(zod, namespace, entity).module;\n}\n\n/**\n * `{ typeName, module }` for a `{ kind: 'ref' }` target — an `Entity` DTO or a\n * `TypeAlias`, both exposed through the Zod artifact's `entities` matrix under\n * the `type` role (`gen-zod` adds one `${ns}.${aliasName}` entry per alias).\n */\nexport function zodRefType(\n zod: GeneratorArtifact,\n namespace: string,\n ref: string,\n): { typeName: string; module: string } {\n const key = entityKey(namespace, ref);\n const entry = zod.entities[key];\n if (entry === undefined) {\n throw new MissingZodSymbolError(key, 'type');\n }\n const id = entry.symbols.type;\n if (id === undefined) {\n throw new MissingZodSymbolError(key, 'type');\n }\n return { typeName: id, module: entry.module };\n}\n\n/** `zod.extra`, cast to the published `ZodArtifactExtra` shape. */\nexport function zodExtra(zod: GeneratorArtifact): ZodArtifactExtra {\n return zod.extra as ZodArtifactExtra;\n}\n\n/** `extra.perNamespace[ns]`, or throw if the Zod artifact never saw that namespace. */\nexport function zodNamespaceExtra(\n zod: GeneratorArtifact,\n namespace: string,\n): ZodArtifactExtra['perNamespace'][string] {\n const per = zodExtra(zod).perNamespace[namespace];\n if (per === undefined) {\n throw new MissingZodNamespaceError(namespace);\n }\n return per;\n}\n\n/** `{ typeName, module }` for an enum ref, resolved via `extra.perNamespace[ns].enums`. */\nexport function zodEnum(\n zod: GeneratorArtifact,\n namespace: string,\n ref: string,\n): { typeName: string; module: string } {\n const per = zodNamespaceExtra(zod, namespace);\n const def = per.enums[ref];\n if (def === undefined) {\n throw new MissingZodSymbolError(`${namespace}.<enum>`, ref);\n }\n return { typeName: def.typeName, module: def.module };\n}\n","/**\n * `<ns>/angular/index.ts` — this generator's own sub-tree barrel. Re-exports\n * `./zod-forms.runtime` (when emitted) and every `./<entity>.form`. A\n * zero-entity source still yields a valid `index.ts`.\n */\nimport type { SourceIR } from '@kurotako/ir';\nimport type { AngularGeneratorOptions } from '../options.js';\n\nexport function emitBarrel(\n source: SourceIR,\n options: AngularGeneratorOptions,\n): string {\n const lines: string[] = [];\n const entities = Object.values(source.entities);\n\n if (entities.length > 0 && options.forms.length > 0) {\n lines.push(\"export * from './zod-forms.runtime';\");\n }\n for (const entity of entities) {\n lines.push(`export * from './${entity.name}.form';`);\n }\n\n return `${lines.join('\\n')}\\n`;\n}\n","/**\n * Import-block accumulator shared by `render/reactive.ts`, `render/signal.ts`\n * and `emit/entity.ts`. Collects the module specifiers + identifiers a rendered\n * entity file needs while it is being assembled, so the final `import` block can\n * be built once, sorted, and split into value vs. type-only lines\n * (`generator-angular/technical.md` §Determinism: import lines sorted by module\n * specifier, named imports sorted).\n */\n\nexport class ImportsRecorder {\n private readonly values = new Map<string, Set<string>>();\n private readonly types = new Map<string, Set<string>>();\n\n value(module: string, name: string): void {\n add(this.values, module, name);\n }\n\n type(module: string, name: string): void {\n add(this.types, module, name);\n }\n\n /** The full `import ...` block text, one statement per line, no trailing blank line. */\n render(): string {\n const lines: { spec: string; rank: 0 | 1; stmt: string }[] = [];\n for (const [spec, names] of this.values) {\n lines.push({ spec, rank: 0, stmt: importStmt(spec, [...names], false) });\n }\n for (const [spec, names] of this.types) {\n lines.push({ spec, rank: 1, stmt: importStmt(spec, [...names], true) });\n }\n lines.sort((a, b) => a.spec.localeCompare(b.spec) || a.rank - b.rank);\n return lines.map((l) => l.stmt).join('\\n');\n }\n}\n\nfunction add(\n map: Map<string, Set<string>>,\n module: string,\n name: string,\n): void {\n const set = map.get(module) ?? new Set<string>();\n set.add(name);\n map.set(module, set);\n}\n\nfunction importStmt(spec: string, names: string[], typeOnly: boolean): string {\n const sorted = [...names].sort((a, b) => a.localeCompare(b)).join(', ');\n const kw = typeOnly ? 'import type' : 'import';\n return `${kw} { ${sorted} } from '${spec}';`;\n}\n","/**\n * `Field` -> typed `FormControl<T>` control-tree text.\n *\n * `T` mirrors the Zod-inferred type of the field, reconstructed from the IR\n * `Field` directly (never by parsing Zod source text) — see\n * `generator-angular/technical.md` §Control type per scalar.\n */\nimport type { Entity, Field, ScalarType, SourceIR } from '@kurotako/ir';\nimport { resolveEnum } from '@kurotako/ir';\nimport type { Variant } from '../names.js';\nimport { type RefTypeName, unionType } from './unions.js';\n\n/** Resolve an enum ref (`FieldType.kind === 'enum'`) to the Zod-emitted union type name. */\nexport type ZodEnumTypeName = (ref: string) => string;\n\n/**\n * Resolvers a field's control type needs beyond its own IR shape: enum refs and\n * `{ kind: 'ref' }` targets both resolve to a Zod-emitted type name, and\n * `cyclicRefs` (`${name}` members of a `ref` cycle, from\n * `GenerateContext.cycles`) lets a recursive union branch be widened.\n */\nexport interface TypeResolvers {\n enumTypeName: ZodEnumTypeName;\n refTypeName: RefTypeName;\n cyclicRefs: ReadonlySet<string>;\n}\n\nconst SCALAR_BASE: Record<ScalarType, string> = {\n string: 'string',\n uuid: 'string',\n decimal: 'string',\n bytes: 'string',\n int: 'number',\n float: 'number',\n bigint: 'bigint',\n boolean: 'boolean',\n date: 'Date',\n datetime: 'Date',\n json: 'unknown',\n};\n\nfunction baseType(field: Field, resolvers: TypeResolvers): string {\n switch (field.type.kind) {\n case 'scalar':\n return SCALAR_BASE[field.type.scalar];\n case 'enum':\n return resolvers.enumTypeName(field.type.ref);\n case 'unknown':\n return 'unknown';\n case 'ref':\n return resolvers.refTypeName(field.type.ref);\n case 'union':\n return unionType(\n field.type,\n resolvers.refTypeName,\n resolvers.enumTypeName,\n resolvers.cyclicRefs,\n ).text;\n }\n}\n\n/** The `FormControl<T>` type argument for a field: `list` wraps, then `nullable`. */\nexport function controlType(field: Field, resolvers: TypeResolvers): string {\n let t = baseType(field, resolvers);\n if (field.list) {\n t = `${t}[]`;\n }\n if (field.nullable) {\n t = `${t} | null`;\n }\n return t;\n}\n\n/** Resolve an enum ref to a real member literal for `initExpr`'s enum zero. */\nexport type EnumZero = (ref: string) => string | undefined;\n\n/** `EnumZero` backed by the IR: the enum's first declared member, in source order. */\nexport function enumZeroFromSource(source: SourceIR, entity: Entity): EnumZero {\n return (ref) => resolveEnum(source, entity, ref)?.values[0]?.name;\n}\n\n/**\n * A valid, always-assignable non-null literal for the field's base type. Never\n * `null` — the Zod-inferred DTO type for a field with no literal default is\n * `T` (required) or `T | undefined` (optional), never `T | null`; only a\n * `field.nullable` field's DTO type includes `null`, and `initExpr` handles\n * that case itself rather than folding it in here.\n */\nfunction zeroValue(field: Field, enumZero?: EnumZero): string {\n if (field.type.kind === 'scalar') {\n switch (field.type.scalar) {\n case 'string':\n case 'uuid':\n case 'decimal':\n case 'bytes':\n return \"''\";\n case 'int':\n case 'float':\n return '0';\n case 'bigint':\n return '0n';\n case 'boolean':\n return 'false';\n case 'date':\n case 'datetime':\n return 'new Date(0)';\n case 'json':\n // control type is `unknown`: `| undefined` is trivially assignable.\n return 'undefined';\n }\n }\n if (field.type.kind === 'enum') {\n // Unlike a scalar zero, `x ?? undefined` never actually strips\n // `| undefined` from `x`'s type (TS keeps it, since the fallback's own\n // type still includes it) — so a non-nullable enum control with no\n // literal default needs a *real* member literal, not `undefined`, or\n // `new FormControl(..., { nonNullable: true })` fails to type-check\n // against the field's exact union type.\n const value = enumZero?.(field.type.ref);\n return value === undefined ? 'undefined' : JSON.stringify(value);\n }\n // `ref` / non-discriminated `union`: no synthesisable zero — the control type\n // is `RefDto` / `A | B` and the seed is cast (`controlExpr`); `zodValidator`\n // flags the still-empty control until the consumer fills it\n // (`ir-union-type/technical.md` §8).\n return 'undefined';\n}\n\n/** The control's initial-value expression: a literal default, else the type's zero. */\nexport function initExpr(field: Field, enumZero?: EnumZero): string {\n if (field.list) {\n return field.default?.kind === 'value'\n ? JSON.stringify(field.default.value)\n : '[]';\n }\n if (field.default?.kind === 'value') {\n return JSON.stringify(field.default.value);\n }\n if (field.nullable) {\n return 'null';\n }\n return zeroValue(field, enumZero);\n}\n\n/**\n * `new FormControl(...)` construction expression for a field.\n * `typeArg` is the field's already-resolved `controlType(...)` text; `sourceExpr`\n * is the value expression to seed the control from (an `init?.x ?? <zero>` for\n * `Create`, a bare `value.x` for `Update` — the caller decides). `sourceExpr` is\n * already `null`-inclusive when `field.nullable` (via `initExpr`'s own fallback,\n * or the Update DTO's own field type) — appending another `?? null` here would\n * be provably-redundant code TS flags as an error (`This expression is never\n * nullish`), not just dead weight.\n */\nexport function controlExpr(\n field: Field,\n typeArg: string,\n sourceExpr: string,\n): string {\n if (field.nullable) {\n return `new FormControl<${typeArg}>(${sourceExpr})`;\n }\n // A `ref` / non-discriminated `union` fallback control has no `nonNullable`\n // seed literal — the seed is `init?.x ?? undefined`, cast to the exact\n // control type; `zodValidator(schema)` is what actually validates it. The\n // union case also carries a note (the ticket reserves it for the fallback).\n if (field.type.kind === 'union') {\n return `new FormControl<${typeArg}>((${sourceExpr}) as ${typeArg}) /* union: validated by zodValidator(schema) */`;\n }\n if (field.type.kind === 'ref') {\n return `new FormControl<${typeArg}>((${sourceExpr}) as ${typeArg})`;\n }\n return `new FormControl(${sourceExpr}, { nonNullable: true })`;\n}\n\nexport interface ControlEntry {\n name: string;\n /** The full control-tree member type, e.g. `FormControl<string>` or (deep mode) `FormGroup<PostCreateDeepFormControls>`. */\n fullType: string;\n}\n\n/** One `ControlEntry` for a scalar / enum / free-`FormControl` field. */\nexport function fieldControlEntry(\n field: Field,\n resolvers: TypeResolvers,\n): ControlEntry {\n return {\n name: field.name,\n fullType: `FormControl<${controlType(field, resolvers)}>`,\n };\n}\n\n/** `export interface <Entity><Variant>[Deep]FormControls { ... }` text. */\nexport function controlsInterface(\n interfaceName: string,\n entries: ControlEntry[],\n): string {\n if (entries.length === 0) {\n return `export interface ${interfaceName} {}`;\n }\n const body = entries.map((e) => ` ${e.name}: ${e.fullType};`).join('\\n');\n return `export interface ${interfaceName} {\\n${body}\\n}`;\n}\n\nexport type { Variant };\n","/**\n * Union / ref control support for `render/controls.ts` and `render/reactive.ts`.\n *\n * Two shapes come out of a `{ kind: 'union' }` field:\n *\n * - **Discriminated sub-`FormGroup`** — `discriminator.mapping` is present and\n * every mapped target resolves to an `Entity` in the same source. The field\n * becomes a `FormGroup` holding a discriminator `FormControl` plus one nested\n * `FormGroup<<Variant>FormControls>` per discriminator value, built by\n * delegating to the target entity's own injected `FormFactory` (same\n * mechanism as `relations: 'deep'`). A runtime switch\n * (`switchDiscriminatedGroup`) toggles the active sub-group on the\n * discriminator control's `valueChanges` and rewrites the group's\n * `getRawValue()` to the flat active-variant shape so the root\n * `zodValidator` sees a value `z.discriminatedUnion` can parse\n * (`ir-union-type/technical.md` §8, resolving the `overview.md` open\n * question).\n * - **Free `FormControl` fallback** — no discriminator, an alias / unresolved\n * target, a `list` / `nullable` union, or a recursive branch. Emits\n * `FormControl<A | B>` (`FormControl<unknown>` when a branch is recursive)\n * plus a `// union: validated by zodValidator(schema)` comment and a\n * `logger.warn`.\n */\nimport type { Field, FieldType, SourceIR } from '@kurotako/ir';\nimport { flattenUnion } from '@kurotako/ir';\n\n/** Resolve a `{ kind: 'ref' }` name to the Zod-emitted DTO / alias type name. */\nexport type RefTypeName = (ref: string) => string;\n\nexport interface DiscriminatedVariant {\n /** The discriminator value this variant is selected by. */\n value: string;\n /** The target entity name (always an `Entity` in the same source). */\n entity: string;\n}\n\nexport interface DiscriminatedUnion {\n /** The discriminator property name (`z.discriminatedUnion` first arg). */\n discriminator: string;\n /** One entry per `discriminator.mapping` pair, in declaration order. */\n variants: DiscriminatedVariant[];\n}\n\n/**\n * A `{ kind: 'union' }` field that qualifies for a discriminated sub-`FormGroup`,\n * or `undefined` when it must fall back to a free `FormControl`.\n */\nexport function discriminatedUnion(\n field: Field,\n source: SourceIR,\n): DiscriminatedUnion | undefined {\n const type = field.type;\n if (type.kind !== 'union' || type.discriminator?.mapping === undefined) {\n return undefined;\n }\n // A `list` / `nullable` discriminated union has no single active sub-object;\n // fall back to a free control.\n if (field.list || field.nullable) {\n return undefined;\n }\n\n const variants: DiscriminatedVariant[] = [];\n for (const [value, ref] of Object.entries(type.discriminator.mapping)) {\n // Only an entity has its own `FormFactory` to delegate the sub-group to;\n // an alias target (or an unresolved ref) means the free-control fallback.\n if (source.entities[ref] === undefined) {\n return undefined;\n }\n variants.push({ value, entity: ref });\n }\n return variants.length >= 2\n ? { discriminator: type.discriminator.propertyName, variants }\n : undefined;\n}\n\n/** Every `{ kind: 'ref' }` name a field type references (recursively). */\nfunction refNames(type: FieldType, into: Set<string> = new Set()): Set<string> {\n if (type.kind === 'ref') {\n into.add(type.ref);\n } else if (type.kind === 'union') {\n for (const variant of type.variants) {\n refNames(variant, into);\n }\n }\n return into;\n}\n\nconst SCALAR_BASE: Record<string, string> = {\n string: 'string',\n uuid: 'string',\n decimal: 'string',\n bytes: 'string',\n int: 'number',\n float: 'number',\n bigint: 'bigint',\n boolean: 'boolean',\n date: 'Date',\n datetime: 'Date',\n json: 'unknown',\n};\n\n/** TS type text for a single non-union variant. */\nfunction variantType(\n type: FieldType,\n refTypeName: RefTypeName,\n enumTypeName: RefTypeName,\n cyclicRefs: ReadonlySet<string>,\n): string {\n switch (type.kind) {\n case 'scalar':\n return SCALAR_BASE[type.scalar] ?? 'unknown';\n case 'enum':\n return enumTypeName(type.ref);\n case 'ref':\n return refTypeName(type.ref);\n case 'unknown':\n return 'unknown';\n case 'union':\n return unionType(type, refTypeName, enumTypeName, cyclicRefs).text;\n }\n}\n\nexport interface UnionTypeResult {\n /** The `FormControl<T>` type argument, e.g. `string | number`. */\n text: string;\n /** A ref branch chains into a cycle — the control was widened to `unknown`. */\n recursive: boolean;\n}\n\n/**\n * The free-`FormControl` type argument for a `{ kind: 'union' }` field: variant\n * types joined with ` | `. A ref branch that names a member of `cyclicRefs` (a\n * `ref` cycle, from `GenerateContext.cycles`) widens the whole control to\n * `unknown` (Angular reactive forms have no lazy control type).\n */\nexport function unionType(\n type: Extract<FieldType, { kind: 'union' }>,\n refTypeName: RefTypeName,\n enumTypeName: RefTypeName,\n cyclicRefs: ReadonlySet<string> = new Set(),\n): UnionTypeResult {\n const variants = flattenUnion(type);\n if (variants.length === 0) {\n return { text: 'unknown', recursive: false };\n }\n const recursive = [...refNames(type)].some((ref) => cyclicRefs.has(ref));\n if (recursive) {\n return { text: 'unknown', recursive: true };\n }\n const text = variants\n .map((variant) => {\n const inner = variantType(variant, refTypeName, enumTypeName, cyclicRefs);\n return variant.kind === 'union' ? `(${inner})` : inner;\n })\n .join(' | ');\n return { text, recursive: false };\n}\n","/**\n * `relations: 'deep'` control-tree entries: nested `FormGroup` for a to-one\n * relation, `FormArray` for a to-many one. `relations: 'flat'` (default) emits\n * nothing for relation objects — the caller simply never calls this module\n * (`generator-angular/technical.md` §Relations).\n *\n * Cross-source relations always degrade to flat (FK scalar only) + a `debug`\n * log, consistent with `gen-zod`'s deep family.\n */\nimport type { Logger } from '@kurotako/core';\nimport type { Entity, Relation } from '@kurotako/ir';\nimport { isCrossSource } from '@kurotako/ir';\nimport type { Variant } from '../names.js';\nimport {\n controlsTypeName,\n formTypeName,\n relationBuilderMethod,\n} from '../names.js';\nimport type { ControlEntry } from './controls.js';\n\nexport interface DeepRelation {\n relation: Relation;\n many: boolean;\n /** The `ControlEntry` this relation contributes to the deep control-tree interface. */\n entry: ControlEntry;\n /** `<Target><Variant>DeepForm` — the target's `FormGroup<...>` type alias. */\n targetFormType: string;\n /** `add<Relation><Variant>` — the builder method name on the reactive factory. */\n builderMethod: string;\n}\n\n/**\n * Every non-cross-source relation on `entity`, rendered as a deep control-tree\n * entry. Cross-source relations are skipped (flat degrade) and logged.\n */\nexport function deepRelations(\n entity: Entity,\n variant: Variant,\n namespace: string,\n logger?: Logger,\n): DeepRelation[] {\n const out: DeepRelation[] = [];\n for (const relation of entity.relations) {\n if (isCrossSource(namespace, relation)) {\n logger?.debug(\n `gen-angular: relation '${relation.name}' targets another source ('${relation.target.namespace}.${relation.target.entity}'); degrading to the flat FK scalar in deep mode`,\n );\n continue;\n }\n\n const many = relation.cardinality === 'many';\n const targetControls = controlsTypeName(\n relation.target.entity,\n variant,\n 'Deep',\n );\n const targetFormType = formTypeName(\n relation.target.entity,\n variant,\n 'Deep',\n );\n const groupType = `FormGroup<${targetControls}>`;\n const fullType = many ? `FormArray<${groupType}>` : groupType;\n\n out.push({\n relation,\n many,\n entry: { name: relation.name, fullType },\n targetFormType,\n builderMethod: relationBuilderMethod(relation.name, variant),\n });\n }\n return out;\n}\n","/**\n * Per-entity field-set derivation for the two form variants.\n *\n * The `Create` / `Update` field selection comes from `@kurotako/ir`'s\n * shared-decision helpers (`createFields`, `updateFields`) — the same helpers\n * `gen-zod` calls — so the control tree and the Zod schema it delegates\n * validation to agree by construction, not by two implementations happening to\n * match (`generator-angular/technical.md` §Variant field sets).\n */\nimport type { Entity, Field } from '@kurotako/ir';\nimport { createFields, updateFields } from '@kurotako/ir';\nimport type { Variant } from '../names.js';\n\n/** The scalar/enum field set for a form variant, in IR declaration order. */\nexport function variantFields(entity: Entity, variant: Variant): Field[] {\n return variant === 'Create' ? createFields(entity) : updateFields(entity);\n}\n","/**\n * Reactive typed-forms surface: control-tree interfaces, `FormGroup` type\n * aliases, and one `@Injectable({ providedIn: 'root' })` factory service per\n * entity (`generator-angular/technical.md` §Reactive factory service).\n *\n * `relations: 'deep'`: Angular's `FormGroup<TControl>` requires every control\n * to be a concrete `AbstractControl` — a control key typed `FormGroup<X> |\n * undefined` fails `FormGroup`'s own generic constraint — so a to-one\n * relation's nested group is built eagerly, by delegating to the target\n * entity's own injected `FormFactory`. A to-many relation's `FormArray`\n * starts empty (no eager nested item), which is what keeps a realistic\n * (many-side-breaks-the-cycle) entity graph from recursing forever; a\n * required one-to-one cycle on both sides would still recurse at runtime —\n * accepted, rare/pathological shape, same spirit as `gen-zod`'s deep-family\n * limitations. `add<Relation><Variant>()` methods let the consumer replace a\n * to-one nested group or push a new to-many item after construction.\n */\nimport type { GeneratorArtifact, Logger } from '@kurotako/core';\nimport type { Entity, SourceIR } from '@kurotako/ir';\nimport {\n controlsTypeName,\n factoryMethod,\n factoryName,\n formTypeName,\n type Variant,\n} from '../names.js';\nimport type { AngularGeneratorOptions } from '../options.js';\nimport { zodEnum, zodModule, zodRefType, zodSymbol } from '../zod-artifact.js';\nimport {\n type ControlEntry,\n controlExpr,\n controlsInterface,\n controlType,\n type EnumZero,\n enumZeroFromSource,\n fieldControlEntry,\n initExpr,\n type TypeResolvers,\n} from './controls.js';\nimport type { ImportsRecorder } from './imports.js';\nimport { deepRelations } from './relations.js';\nimport {\n type DiscriminatedUnion,\n discriminatedUnion,\n unionType,\n} from './unions.js';\nimport { variantFields } from './variants.js';\n\n/**\n * `ControlEntry` for a discriminated union field: a `FormGroup` holding the\n * discriminator `FormControl` plus one nested `FormGroup<<Variant>FormControls>`\n * per discriminator value.\n */\nfunction discriminatedControlEntry(\n union: DiscriminatedUnion,\n fieldName: string,\n variant: Variant,\n family: '' | 'Deep',\n): ControlEntry {\n const lit = union.variants.map((v) => JSON.stringify(v.value)).join(' | ');\n const subs = union.variants\n .map(\n (v) =>\n `${JSON.stringify(v.value)}: FormGroup<${controlsTypeName(v.entity, variant, family)}>`,\n )\n .join('; ');\n return {\n name: fieldName,\n fullType: `FormGroup<{ ${JSON.stringify(union.discriminator)}: FormControl<${lit}>; ${subs} }>`,\n };\n}\n\n/**\n * The IIFE that builds a discriminated union field's `FormGroup` in a factory\n * method: eager nested sub-groups via the injected target `FormFactory`, then\n * `switchDiscriminatedGroup` to wire the active-variant toggle + `getRawValue`\n * rewrite.\n */\nfunction discriminatedFactoryExpr(\n union: DiscriminatedUnion,\n fieldName: string,\n variant: Variant,\n deep: boolean,\n zod: GeneratorArtifact,\n namespace: string,\n injectedFactories: Map<string, string>,\n): string {\n const lit = union.variants.map((v) => JSON.stringify(v.value)).join(' | ');\n const first = JSON.stringify(union.variants[0]?.value ?? '');\n const method = factoryMethod(variant);\n const subLines = union.variants\n .map((v) => {\n const param =\n injectedFactories.get(v.entity) ?? `${lowerFirst(v.entity)}FormFactory`;\n if (variant === 'Create') {\n return ` ${JSON.stringify(v.value)}: this.${param}.${method}(),`;\n }\n const role = deep ? ('updateDeepType' as const) : ('updateType' as const);\n const dto = zodSymbol(zod, namespace, v.entity, role);\n return ` ${JSON.stringify(v.value)}: this.${param}.${method}(value.${fieldName} as unknown as ${dto}),`;\n })\n .join('\\n');\n return `(() => {\n const g = new FormGroup({\n ${JSON.stringify(union.discriminator)}: new FormControl<${lit}>(${first}, { nonNullable: true }),\n${subLines}\n });\n switchDiscriminatedGroup(g, ${JSON.stringify(union.discriminator)});\n return g;\n})()`;\n}\n\nfunction lowerFirst(s: string): string {\n return s.length === 0 ? s : s.charAt(0).toLowerCase() + s.slice(1);\n}\n\nexport function reactiveEntity(\n entity: Entity,\n namespace: string,\n source: SourceIR,\n options: AngularGeneratorOptions,\n zod: GeneratorArtifact,\n imports: ImportsRecorder,\n cyclicRefs: ReadonlySet<string>,\n logger?: Logger,\n): string {\n const deep = options.relations === 'deep';\n const enumZero = enumZeroFromSource(source, entity);\n imports.value('@angular/core', 'Injectable');\n imports.value('@angular/forms', 'FormControl');\n imports.value('@angular/forms', 'FormGroup');\n\n const zodEnumTypeName = (ref: string): string => {\n const e = zodEnum(zod, namespace, ref);\n imports.type(e.module, e.typeName);\n return e.typeName;\n };\n\n const blocks: string[] = [];\n const injectedFactories = new Map<string, string>(); // target entity -> ctor param name\n const warnedUnionFields = new Set<string>(); // warn once per field, not per variant\n\n for (const variant of ['Create', 'Update'] as Variant[]) {\n const family = deep ? 'Deep' : '';\n const schemaRole = deep\n ? variant === 'Create'\n ? ('createDeepSchema' as const)\n : ('updateDeepSchema' as const)\n : variant === 'Create'\n ? ('createSchema' as const)\n : ('updateSchema' as const);\n const typeRole = deep\n ? variant === 'Create'\n ? ('createDeepType' as const)\n : ('updateDeepType' as const)\n : variant === 'Create'\n ? ('createType' as const)\n : ('updateType' as const);\n\n const module = zodModule(zod, namespace, entity.name);\n const schemaId = zodSymbol(zod, namespace, entity.name, schemaRole);\n const typeId = zodSymbol(zod, namespace, entity.name, typeRole);\n imports.value(module, schemaId);\n imports.type(module, typeId);\n imports.value(`${namespace}/angular/zod-forms.runtime`, 'zodValidator');\n\n const interfaceName = controlsTypeName(entity.name, variant, family);\n const formType = formTypeName(entity.name, variant, family);\n\n const resolvers: TypeResolvers = {\n enumTypeName: zodEnumTypeName,\n refTypeName: (ref) => {\n const r = zodRefType(zod, namespace, ref);\n imports.type(r.module, r.typeName);\n return r.typeName;\n },\n cyclicRefs,\n };\n\n const fieldEntries: ControlEntry[] = variantFields(entity, variant).map(\n (field) => {\n const union =\n field.type.kind === 'union'\n ? discriminatedUnion(field, source)\n : undefined;\n if (union !== undefined) {\n imports.value(\n `${namespace}/angular/zod-forms.runtime`,\n 'switchDiscriminatedGroup',\n );\n for (const v of union.variants) {\n const targetModule = `${namespace}/angular/${v.entity}.form`;\n imports.type(\n targetModule,\n controlsTypeName(v.entity, variant, family),\n );\n if (!injectedFactories.has(v.entity)) {\n injectedFactories.set(\n v.entity,\n `${lowerFirst(v.entity)}FormFactory`,\n );\n imports.value(targetModule, factoryName(v.entity));\n }\n if (variant === 'Update') {\n const role = deep\n ? ('updateDeepType' as const)\n : ('updateType' as const);\n imports.type(\n zodModule(zod, namespace, v.entity),\n zodSymbol(zod, namespace, v.entity, role),\n );\n }\n }\n return discriminatedControlEntry(union, field.name, variant, family);\n }\n if (field.type.kind === 'union' && !warnedUnionFields.has(field.name)) {\n warnedUnionFields.add(field.name);\n const recursive = unionType(\n field.type,\n resolvers.refTypeName,\n resolvers.enumTypeName,\n cyclicRefs,\n ).recursive;\n const cause = recursive\n ? 'a recursive ref branch (chains into a cycle)'\n : 'no discriminator mapping, an alias target, or a list/nullable union';\n logger?.warn(\n `gen-angular: union field '${entity.name}.${field.name}' has no usable discriminated sub-form (${cause}); emitting a free FormControl${recursive ? '<unknown>' : ''} validated by zodValidator`,\n );\n }\n return fieldControlEntry(field, resolvers);\n },\n );\n\n const relations = deep\n ? deepRelations(entity, variant, namespace, logger)\n : [];\n const manyRelations = relations.filter((r) => r.many);\n if (manyRelations.length > 0) {\n imports.value('@angular/forms', 'FormArray');\n }\n for (const rel of relations) {\n const targetModule = `${namespace}/angular/${rel.relation.target.entity}.form`;\n imports.type(\n targetModule,\n controlsTypeName(rel.relation.target.entity, variant, 'Deep'),\n );\n imports.type(targetModule, rel.targetFormType);\n if (!injectedFactories.has(rel.relation.target.entity)) {\n const paramName = `${lowerFirst(rel.relation.target.entity)}FormFactory`;\n injectedFactories.set(rel.relation.target.entity, paramName);\n imports.value(targetModule, factoryName(rel.relation.target.entity));\n }\n // The `add<Relation><Variant>()` builder (to-many only) takes an\n // `init` / `value` for the *target* entity's own create/update DTO.\n if (rel.many) {\n const targetTypeRole =\n deep && variant === 'Create'\n ? ('createDeepType' as const)\n : deep && variant === 'Update'\n ? ('updateDeepType' as const)\n : variant === 'Create'\n ? ('createType' as const)\n : ('updateType' as const);\n const targetZodModule = zodModule(\n zod,\n namespace,\n rel.relation.target.entity,\n );\n const targetTypeId = zodSymbol(\n zod,\n namespace,\n rel.relation.target.entity,\n targetTypeRole,\n );\n imports.type(targetZodModule, targetTypeId);\n }\n }\n\n blocks.push(\n controlsInterface(interfaceName, [\n ...fieldEntries,\n ...relations.map((r) => r.entry),\n ]),\n );\n blocks.push(`export type ${formType} = FormGroup<${interfaceName}>;`);\n }\n\n blocks.push(\n renderFactoryClass(\n entity,\n namespace,\n source,\n options,\n zod,\n injectedFactories,\n enumZero,\n cyclicRefs,\n ),\n );\n\n return blocks.join('\\n\\n');\n}\n\nfunction renderFactoryClass(\n entity: Entity,\n namespace: string,\n source: SourceIR,\n options: AngularGeneratorOptions,\n zod: GeneratorArtifact,\n injectedFactories: Map<string, string>,\n enumZero: EnumZero,\n cyclicRefs: ReadonlySet<string>,\n): string {\n const deep = options.relations === 'deep';\n const className = factoryName(entity.name);\n\n const ctorParams = [...injectedFactories.entries()]\n .map(\n ([target, param]) => `private readonly ${param}: ${factoryName(target)}`,\n )\n .join(', ');\n const ctor =\n ctorParams.length > 0 ? `\\n constructor(${ctorParams}) {}\\n` : '';\n\n const methods: string[] = [];\n for (const variant of ['Create', 'Update'] as Variant[]) {\n methods.push(\n renderFactoryMethod(\n entity,\n namespace,\n source,\n variant,\n options,\n zod,\n injectedFactories,\n enumZero,\n cyclicRefs,\n ),\n );\n }\n\n if (deep) {\n for (const variant of ['Create', 'Update'] as Variant[]) {\n // Only the to-many side needs a builder: a to-one nested group is\n // already built eagerly (see the module docstring), and its target\n // factory's Update method requires a value this method has no natural\n // source for.\n const relations = deepRelations(\n entity,\n variant,\n namespace,\n undefined,\n ).filter((r) => r.many);\n for (const rel of relations) {\n methods.push(\n renderBuilderMethod(\n entity,\n namespace,\n variant,\n options,\n zod,\n rel,\n injectedFactories,\n ),\n );\n }\n }\n }\n\n const body = [\n ctor,\n ...methods.map((m) => `\\n ${m.split('\\n').join('\\n ')}\\n`),\n ]\n .join('')\n .trimEnd();\n\n return `@Injectable({ providedIn: 'root' })\\nexport class ${className} {\\n${body}\\n}`;\n}\n\nfunction renderFactoryMethod(\n entity: Entity,\n namespace: string,\n source: SourceIR,\n variant: Variant,\n options: AngularGeneratorOptions,\n zod: GeneratorArtifact,\n injectedFactories: Map<string, string>,\n enumZero: EnumZero,\n cyclicRefs: ReadonlySet<string>,\n): string {\n const deep = options.relations === 'deep';\n const family = deep ? 'Deep' : '';\n const typeRole =\n deep && variant === 'Create'\n ? ('createDeepType' as const)\n : deep && variant === 'Update'\n ? ('updateDeepType' as const)\n : variant === 'Create'\n ? ('createType' as const)\n : ('updateType' as const);\n const schemaRole =\n deep && variant === 'Create'\n ? ('createDeepSchema' as const)\n : deep && variant === 'Update'\n ? ('updateDeepSchema' as const)\n : variant === 'Create'\n ? ('createSchema' as const)\n : ('updateSchema' as const);\n\n const typeId = zodSymbol(zod, namespace, entity.name, typeRole);\n const schemaId = zodSymbol(zod, namespace, entity.name, schemaRole);\n const interfaceName = controlsTypeName(entity.name, variant, family);\n const formType = formTypeName(entity.name, variant, family);\n const methodName = factoryMethod(variant);\n\n const resolvers: TypeResolvers = {\n enumTypeName: (ref) => ref,\n refTypeName: (ref) => zodRefType(zod, namespace, ref).typeName,\n cyclicRefs,\n };\n const fields = variantFields(entity, variant);\n const lines = fields.map((field) => {\n const union =\n field.type.kind === 'union'\n ? discriminatedUnion(field, source)\n : undefined;\n if (union !== undefined) {\n return ` ${field.name}: ${discriminatedFactoryExpr(\n union,\n field.name,\n variant,\n deep,\n zod,\n namespace,\n injectedFactories,\n )},`;\n }\n const typeArg = controlType(field, resolvers);\n // The Update Zod DTO is a whole-object `.partial()` (gen-zod), so every\n // field — including one that is otherwise required — is `T | undefined`\n // there too; both variants therefore need the same `?? <zero>` fallback.\n const accessor =\n variant === 'Create' ? `init?.${field.name}` : `value.${field.name}`;\n const seed = `${accessor} ?? ${initExpr(field, enumZero)}`;\n return ` ${field.name}: ${controlExpr(field, typeArg, seed)},`;\n });\n\n const relations = deep\n ? deepRelations(entity, variant, namespace, undefined)\n : [];\n const relationLines = relations.map((r) => {\n if (r.many) {\n const targetControls = controlsTypeName(\n r.relation.target.entity,\n variant,\n 'Deep',\n );\n return ` ${r.entry.name}: new FormArray<FormGroup<${targetControls}>>([]),`;\n }\n const factoryParam =\n injectedFactories.get(r.relation.target.entity) ??\n `${lowerFirst(r.relation.target.entity)}FormFactory`;\n // The Update DTO's whole-object `.partial()` also makes a required\n // relation optional at the type level (same as scalar fields above);\n // `createUpdateForm` itself still requires a concrete value, so the\n // caller is expected to supply the nested relation on a value it read\n // back — asserted here rather than defaulted (there is no meaningful\n // \"empty\" nested entity to fall back to).\n const nestedArg =\n variant === 'Create'\n ? `init?.${r.relation.name}`\n : `value.${r.relation.name}!`;\n return ` ${r.entry.name}: this.${factoryParam}.${factoryMethod(variant)}(${nestedArg}),`;\n });\n\n const groupBody = [...lines, ...relationLines].join('\\n');\n const paramList =\n variant === 'Create' ? `init?: Partial<${typeId}>` : `value: ${typeId}`;\n\n return `${methodName}(${paramList}): ${formType} {\\n return new FormGroup<${interfaceName}>({\\n${groupBody}\\n }, { validators: [zodValidator(${schemaId})] });\\n}`;\n}\n\n/** Only ever called for a to-many relation (see the caller). */\nfunction renderBuilderMethod(\n entity: Entity,\n namespace: string,\n variant: Variant,\n options: AngularGeneratorOptions,\n zod: GeneratorArtifact,\n rel: ReturnType<typeof deepRelations>[number],\n injectedFactories: Map<string, string>,\n): string {\n const deep = options.relations === 'deep';\n const target = rel.relation.target.entity;\n const factoryParam =\n injectedFactories.get(target) ?? `${lowerFirst(target)}FormFactory`;\n const formType = formTypeName(entity.name, variant, 'Deep');\n const targetFormType = rel.targetFormType;\n const method = rel.builderMethod;\n\n const targetTypeRole =\n deep && variant === 'Create'\n ? ('createDeepType' as const)\n : deep && variant === 'Update'\n ? ('updateDeepType' as const)\n : variant === 'Create'\n ? ('createType' as const)\n : ('updateType' as const);\n const targetTypeId = zodSymbol(zod, namespace, target, targetTypeRole);\n\n const param =\n variant === 'Create'\n ? `init?: Partial<${targetTypeId}>`\n : `value: ${targetTypeId}`;\n const createCall = `this.${factoryParam}.${factoryMethod(variant)}(${variant === 'Create' ? 'init' : 'value'})`;\n\n return `${method}(form: ${formType}, ${param}): ${targetFormType} {\\n const group = ${createCall};\\n form.controls.${rel.relation.name}.push(group);\\n return group;\\n}`;\n}\n","/**\n * Signal Forms surface: pure exported `schema` + model-factory functions, no DI\n * wrapper (`generator-angular/technical.md` §Signal Forms schema + model\n * factory), plus a `create<Entity><Variant>Form` convenience wrapper around\n * `form(signal(model), schema)`. Every `@angular/forms/signals` call site\n * lives here and in `emit/runtime.ts` (the `zodTreeValidate` half) so a\n * secondary-API change on that experimental surface is a single-file update.\n *\n * The wrapper is a plain function, not a DI service — `form()` resolves its\n * injector from Angular's ambient injection context when none is passed\n * explicitly (same rule `inject()` follows), so calling the wrapper from a\n * component field initializer or constructor works exactly like calling\n * `form()` inline there.\n */\nimport type { GeneratorArtifact, Logger } from '@kurotako/core';\nimport type { Entity, SourceIR } from '@kurotako/ir';\nimport {\n modelFactoryName,\n signalFormFactoryName,\n signalSchemaName,\n type Variant,\n} from '../names.js';\nimport type { AngularGeneratorOptions } from '../options.js';\nimport { zodModule, zodSymbol } from '../zod-artifact.js';\nimport { enumZeroFromSource, initExpr } from './controls.js';\nimport type { ImportsRecorder } from './imports.js';\nimport { deepRelations } from './relations.js';\nimport { variantFields } from './variants.js';\n\nexport function signalEntity(\n entity: Entity,\n namespace: string,\n source: SourceIR,\n options: AngularGeneratorOptions,\n zod: GeneratorArtifact,\n imports: ImportsRecorder,\n logger?: Logger,\n): string {\n const deep = options.relations === 'deep';\n const enumZero = enumZeroFromSource(source, entity);\n imports.value('@angular/forms/signals', 'schema');\n imports.value('@angular/forms/signals', 'form');\n imports.type('@angular/forms/signals', 'FieldTree');\n imports.value('@angular/core', 'signal');\n\n const blocks: string[] = [];\n for (const variant of ['Create', 'Update'] as Variant[]) {\n const typeRole =\n deep && variant === 'Create'\n ? ('createDeepType' as const)\n : deep && variant === 'Update'\n ? ('updateDeepType' as const)\n : variant === 'Create'\n ? ('createType' as const)\n : ('updateType' as const);\n const schemaRole =\n deep && variant === 'Create'\n ? ('createDeepSchema' as const)\n : deep && variant === 'Update'\n ? ('updateDeepSchema' as const)\n : variant === 'Create'\n ? ('createSchema' as const)\n : ('updateSchema' as const);\n\n const module = zodModule(zod, namespace, entity.name);\n const typeId = zodSymbol(zod, namespace, entity.name, typeRole);\n const schemaId = zodSymbol(zod, namespace, entity.name, schemaRole);\n imports.type(module, typeId);\n imports.value(module, schemaId);\n imports.value(`${namespace}/angular/zod-forms.runtime`, 'zodTreeValidate');\n\n const fields = variantFields(entity, variant);\n const fieldLines = fields.map((field) => {\n // `ref` / `union` field types have no synthesisable model zero (the\n // Signal Forms model is a plain object, not a control tree, so there is\n // no discriminated sub-form here — the union rides as one field,\n // validated by `zodTreeValidate`). Seed from `init`, cast to the exact\n // DTO field type; a still-missing value is what the validator flags.\n if (field.type.kind === 'ref' || field.type.kind === 'union') {\n return ` ${field.name}: (init?.${field.name} ?? undefined) as ${typeId}[${JSON.stringify(field.name)}],`;\n }\n return ` ${field.name}: init?.${field.name} ?? ${initExpr(field, enumZero)},`;\n });\n\n const relations = deep\n ? deepRelations(entity, variant, namespace, logger)\n : [];\n // A to-one relation the Zod deep DTO marks required (any relation that\n // isn't itself optional, in the Create variant) can't be seeded with\n // `undefined` — build it eagerly via the target's own model factory\n // instead, imported as a value from its `.form` module.\n const relationLines = relations.map((rel) => {\n if (rel.many) {\n return ` ${rel.relation.name}: [],`;\n }\n const targetModule = `${namespace}/angular/${rel.relation.target.entity}.form`;\n const targetModelFactory = modelFactoryName(\n rel.relation.target.entity,\n variant,\n );\n imports.value(targetModule, targetModelFactory);\n return ` ${rel.relation.name}: ${targetModelFactory}(init?.${rel.relation.name}),`;\n });\n\n const modelBody = [...fieldLines, ...relationLines].join('\\n');\n const modelName = modelFactoryName(entity.name, variant);\n blocks.push(\n `export function ${modelName}(init?: Partial<${typeId}>): ${typeId} {\\n return {\\n${modelBody}\\n };\\n}`,\n );\n\n const schemaConst = signalSchemaName(entity.name, variant);\n blocks.push(\n `export const ${schemaConst} = schema<${typeId}>((path) => {\\n zodTreeValidate(path, ${schemaId});\\n});`,\n );\n\n const formFactoryName = signalFormFactoryName(entity.name, variant);\n blocks.push(\n `export function ${formFactoryName}(init?: Partial<${typeId}>): FieldTree<${typeId}> {\\n return form(signal(${modelName}(init)), ${schemaConst});\\n}`,\n );\n }\n\n return blocks.join('\\n\\n');\n}\n","/**\n * One entity -> `<ns>/angular/<entity>.form.ts` source text: a sorted import\n * block, then the reactive block (control-tree interfaces + `@Injectable`\n * factory, when `forms` includes `'reactive'`) and the Signal Forms block\n * (schema + model factory, when `forms` includes `'signal'`)\n * (`generator-angular/technical.md` §File layout).\n */\nimport type { GeneratorArtifact, Logger } from '@kurotako/core';\nimport type { Entity, SourceIR } from '@kurotako/ir';\nimport type { AngularGeneratorOptions } from '../options.js';\nimport { ImportsRecorder } from '../render/imports.js';\nimport { reactiveEntity } from '../render/reactive.js';\nimport { signalEntity } from '../render/signal.js';\n\nexport function emitEntity(\n entity: Entity,\n namespace: string,\n source: SourceIR,\n options: AngularGeneratorOptions,\n zod: GeneratorArtifact,\n cyclicRefs: ReadonlySet<string>,\n logger?: Logger,\n): string {\n const imports = new ImportsRecorder();\n const blocks: string[] = [];\n\n if (options.forms.includes('reactive')) {\n blocks.push(\n reactiveEntity(\n entity,\n namespace,\n source,\n options,\n zod,\n imports,\n cyclicRefs,\n logger,\n ),\n );\n }\n if (options.forms.includes('signal')) {\n blocks.push(\n signalEntity(entity, namespace, source, options, zod, imports, logger),\n );\n }\n\n const importBlock = imports.render();\n return `${[importBlock, '', ...blocks].join('\\n').trimEnd()}\\n`;\n}\n","/**\n * `<ns>/angular/zod-forms.runtime.ts` — hand-written, deterministic source (no\n * per-entity content). Emitted once per namespace whenever the source has >= 1\n * entity and `forms` is non-empty (`generator-angular/technical.md` §File\n * layout).\n *\n * `zodValidator` (reactive half): a group-level `ValidatorFn` that\n * `safeParse`s against the Zod schema and distributes each issue onto the\n * matching descendant control by `issue.path`, clearing stale `zod` keys and\n * guarding against a `setErrors`-triggered validation loop\n * (`generator-angular/technical.md` §`zodValidator`).\n *\n * `switchDiscriminatedGroup` (reactive half): wires a discriminated-union\n * sub-`FormGroup` — enables only the sub-group selected by the discriminator\n * control (disabling the rest, kept in sync on `valueChanges`) and rewrites the\n * group's `getRawValue()` to the flat active-variant shape a\n * `z.discriminatedUnion` schema parses (`ir-union-type/technical.md` §8).\n *\n * `zodTreeValidate` (Signal Forms half): wraps `@angular/forms/signals`'\n * tree-level validator primitive. This is the *only* file (besides\n * `render/signal.ts`) referencing that experimental surface, so a secondary-API\n * shift on a future Angular minor is a single-file update\n * (`generator-angular/technical.md` §Signal Forms schema + model factory).\n */\nimport type { SourceIR } from '@kurotako/ir';\nimport type { AngularGeneratorOptions } from '../options.js';\n\nconst ZOD_VALIDATOR = `export function zodValidator(schema: ZodType): ValidatorFn {\n return (group: AbstractControl) => {\n const result = schema.safeParse(group.getRawValue());\n const touched = new Set<AbstractControl>();\n const rootIssues: { path: (string | number)[]; message: string }[] = [];\n\n if (!result.success) {\n for (const issue of result.error.issues) {\n const path = issue.path.map(String).join('.');\n const control = path === '' ? null : group.get(path);\n if (control !== null && control !== undefined) {\n setZodError(control, issue.message);\n touched.add(control);\n } else {\n rootIssues.push({ path: issue.path as (string | number)[], message: issue.message });\n }\n }\n }\n\n for (const control of collectControls(group)) {\n if (control !== group && !touched.has(control)) {\n clearZodError(control);\n }\n }\n\n if (rootIssues.length === 0) {\n clearZodError(group);\n return null;\n }\n\n const formErrors: string[] = [];\n const fieldErrors: Record<string, string[]> = {};\n for (const issue of rootIssues) {\n if (issue.path.length === 0) {\n formErrors.push(issue.message);\n } else {\n const key = String(issue.path[0]);\n (fieldErrors[key] ??= []).push(issue.message);\n }\n }\n\n const zodError = { formErrors, fieldErrors };\n setZodError(group, zodError);\n return { zod: zodError };\n };\n}\n\nfunction setZodError(control: AbstractControl, message: unknown): void {\n const current = control.errors;\n if (current !== null && sameZodError(current.zod, message)) {\n return;\n }\n control.setErrors({ ...current, zod: message }, { emitEvent: false });\n}\n\nfunction clearZodError(control: AbstractControl): void {\n const current = control.errors;\n if (current === null || current === undefined || !('zod' in current)) {\n return;\n }\n const { zod: _discard, ...rest } = current;\n control.setErrors(Object.keys(rest).length > 0 ? rest : null, {\n emitEvent: false,\n });\n}\n\nfunction sameZodError(a: unknown, b: unknown): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\nfunction collectControls(control: AbstractControl): AbstractControl[] {\n const out: AbstractControl[] = [control];\n const children = (control as { controls?: unknown }).controls;\n if (children !== null && typeof children === 'object') {\n for (const child of Object.values(children as Record<string, AbstractControl>)) {\n out.push(...collectControls(child));\n }\n }\n return out;\n}`;\n\nconst SWITCH_DISCRIMINATED_GROUP = `/**\n * Wire a discriminated-union sub-FormGroup: enable only the sub-group named by\n * the discriminator control's value (disable the rest), keep it in sync on\n * valueChanges, and rewrite the group's getRawValue() to the flat\n * active-variant shape a z.discriminatedUnion schema can parse.\n */\nexport function switchDiscriminatedGroup(\n group: AbstractControl,\n discriminator: string,\n): void {\n const controls = (group as unknown as {\n controls: Record<string, AbstractControl>;\n }).controls;\n const selector = controls[discriminator];\n if (selector === undefined) {\n return;\n }\n const variantKeys = Object.keys(controls).filter(\n (key) => key !== discriminator,\n );\n\n const apply = (active: unknown): void => {\n for (const key of variantKeys) {\n const sub = controls[key];\n if (sub === undefined) {\n continue;\n }\n if (key === active) {\n sub.enable({ emitEvent: false });\n } else {\n sub.disable({ emitEvent: false });\n }\n }\n };\n\n apply(selector.value);\n selector.valueChanges.subscribe(apply);\n\n (group as { getRawValue: () => unknown }).getRawValue = () => {\n const active = controls[String(selector.value)];\n const variant =\n active === undefined || active === selector\n ? {}\n : (active.getRawValue() as Record<string, unknown>);\n return { ...variant, [discriminator]: selector.value };\n };\n}`;\n\nconst ZOD_TREE_VALIDATE = `export function zodTreeValidate<T>(\n path: SchemaPath<T>,\n schema: ZodType<T>,\n): void {\n validateTree(path, (ctx) => {\n const result = schema.safeParse(ctx.value());\n if (result.success) {\n return undefined;\n }\n return result.error.issues.map((issue) => ({\n kind: 'custom' as const,\n message: issue.message,\n // Dynamically walked from the Zod issue path against the field tree's\n // runtime shape; ValidationError.fieldTree accepts undefined for a\n // pathless issue, so a same-shaped object (rather than branching on\n // whether one was found) keeps this a single, uniform return type.\n fieldTree: resolveFieldTree(ctx.fieldTree, issue.path) as\n | ReadonlyFieldTree<unknown>\n | undefined,\n }));\n });\n}\n\nfunction resolveFieldTree(root: unknown, path: readonly PropertyKey[]): unknown {\n return path.reduce<unknown>((node, key) => {\n if (node === null || typeof node !== 'object') {\n return undefined;\n }\n return (node as Record<PropertyKey, unknown>)[key];\n }, root);\n}`;\n\nexport function emitRuntime(\n _source: SourceIR,\n options: AngularGeneratorOptions,\n): string {\n const reactive = options.forms.includes('reactive');\n const signal = options.forms.includes('signal');\n\n const imports: string[] = [];\n if (reactive) {\n imports.push(\n \"import type { AbstractControl, ValidatorFn } from '@angular/forms';\",\n );\n }\n if (signal) {\n imports.push(\n \"import type { ReadonlyFieldTree, SchemaPath } from '@angular/forms/signals';\",\n \"import { validateTree } from '@angular/forms/signals';\",\n );\n }\n imports.push(\"import type { ZodType } from 'zod';\");\n\n const blocks: string[] = [];\n if (reactive) {\n blocks.push(ZOD_VALIDATOR, SWITCH_DISCRIMINATED_GROUP);\n }\n if (signal) {\n blocks.push(ZOD_TREE_VALIDATE);\n }\n\n return `${[imports.join('\\n'), '', ...blocks].join('\\n').trimEnd()}\\n`;\n}\n","/**\n * Valibot schema for `@kurotako/gen-angular`'s `options`, plus the inferred type.\n * `@kurotako/config` validates a config entry's `options` against this schema and\n * curries it away before `@kurotako/core` sees the generator.\n */\nimport * as v from 'valibot';\n\nexport const AngularGeneratorOptions = v.object({\n /** Which form surfaces to emit. Default: both. */\n forms: v.optional(v.array(v.picklist(['reactive', 'signal'])), [\n 'reactive',\n 'signal',\n ]),\n /** Relation handling: flat (FK scalars only) or deep (nested FormGroup / FormArray). */\n relations: v.optional(v.picklist(['flat', 'deep']), 'flat'),\n});\n\nexport type AngularGeneratorOptions = v.InferOutput<\n typeof AngularGeneratorOptions\n>;\n"],"mappings":"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","names":["entityKey","SCALAR_BASE","v","lowerFirst"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kurotako/gen-angular",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "kurotako generator that emits Angular reactive forms from the intermediate representation.",
5
5
  "keywords": [
6
6
  "kurotako",