langium-zod 0.5.3 → 0.6.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.
Files changed (54) hide show
  1. package/README.md +23 -0
  2. package/dist/api.d.ts +123 -0
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +151 -0
  5. package/dist/api.js.map +1 -1
  6. package/dist/cli.d.ts +76 -0
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +105 -12
  9. package/dist/cli.js.map +1 -1
  10. package/dist/config.d.ts +133 -0
  11. package/dist/config.d.ts.map +1 -1
  12. package/dist/config.js +15 -0
  13. package/dist/config.js.map +1 -1
  14. package/dist/conformance.d.ts.map +1 -1
  15. package/dist/conformance.js.map +1 -1
  16. package/dist/di.d.ts +154 -0
  17. package/dist/di.d.ts.map +1 -1
  18. package/dist/di.js +98 -0
  19. package/dist/di.js.map +1 -1
  20. package/dist/emitters/domain.d.ts +23 -0
  21. package/dist/emitters/domain.d.ts.map +1 -0
  22. package/dist/emitters/domain.js +269 -0
  23. package/dist/emitters/domain.js.map +1 -0
  24. package/dist/errors.d.ts +62 -0
  25. package/dist/errors.d.ts.map +1 -1
  26. package/dist/errors.js +62 -0
  27. package/dist/errors.js.map +1 -1
  28. package/dist/extractor.d.ts +83 -0
  29. package/dist/extractor.d.ts.map +1 -1
  30. package/dist/extractor.js +91 -3
  31. package/dist/extractor.js.map +1 -1
  32. package/dist/generator.d.ts +81 -0
  33. package/dist/generator.d.ts.map +1 -1
  34. package/dist/generator.js +99 -14
  35. package/dist/generator.js.map +1 -1
  36. package/dist/index.d.ts +26 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +25 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/projection.d.ts.map +1 -1
  41. package/dist/projection.js.map +1 -1
  42. package/dist/recursion-detector.d.ts +66 -0
  43. package/dist/recursion-detector.d.ts.map +1 -1
  44. package/dist/recursion-detector.js +66 -0
  45. package/dist/recursion-detector.js.map +1 -1
  46. package/dist/ref-utils.d.ts +79 -0
  47. package/dist/ref-utils.d.ts.map +1 -1
  48. package/dist/ref-utils.js +79 -0
  49. package/dist/ref-utils.js.map +1 -1
  50. package/dist/type-mapper.d.ts.map +1 -1
  51. package/dist/type-mapper.js.map +1 -1
  52. package/dist/types.d.ts +163 -0
  53. package/dist/types.d.ts.map +1 -1
  54. package/package.json +9 -7
package/README.md CHANGED
@@ -64,3 +64,26 @@ Generated output uses Zod 4 and exports named schemas like `<TypeName>Schema`.
64
64
  - Langium 4.x
65
65
  - Zod 4.x
66
66
 
67
+ ## Domain target (experimental)
68
+
69
+ Besides Zod schemas, langium-zod can emit a **domain surface** — quirk-free read
70
+ interfaces, a `toDomain(node)` read projection, and field-precise write accessors:
71
+
72
+ langium-zod generate --domain --domain-out src/generated/domain.ts
73
+
74
+ Mechanical rules are generic (a single cross-reference flattens to a `$refText`
75
+ string). Project-specific renames and read-only merges are supplied via
76
+ `domainOverlays` in `langium-zod.config.js`:
77
+
78
+ export default {
79
+ domainOverlays: {
80
+ types: {
81
+ Choice: { renames: { attributes: 'options' } },
82
+ RosettaFunction: { merges: [{ from: ['conditions', 'postConditions'], to: 'conditions' }] }
83
+ }
84
+ }
85
+ };
86
+
87
+ Merges are read-only on the merged name; write accessors target the source
88
+ fields (`addConditions`, `addPostConditions`) — there is no merged setter.
89
+
package/dist/api.d.ts CHANGED
@@ -1,4 +1,127 @@
1
1
  import type { ZodGeneratorConfig } from './config.js';
2
2
  export type PublicZodGeneratorConfig = ZodGeneratorConfig;
3
+ /**
4
+ * Main entry point for programmatic Zod schema generation from a Langium grammar.
5
+ *
6
+ * Accepts a {@link ZodGeneratorConfig} that specifies either a parsed Langium
7
+ * `Grammar` object or a pre-built {@link AstTypesLike} descriptor, then runs the
8
+ * full extraction → projection → code-generation pipeline and returns the
9
+ * generated TypeScript source as a string. When `config.outputPath` is set the
10
+ * result is also written to disk. Conformance artifacts are generated when
11
+ * `config.conformance` is provided.
12
+ *
13
+ * @remarks
14
+ * This is the primary API for most consumers. It combines {@link extractTypeDescriptors},
15
+ * {@link detectRecursiveTypes}, and {@link generateZodCode} into a single call. Use the
16
+ * lower-level functions directly only when you need fine-grained control over individual
17
+ * pipeline stages (e.g. to inspect descriptors before code generation, or to cache
18
+ * extraction results across multiple code-generation runs).
19
+ *
20
+ * The function is synchronous and writes to disk only when `config.outputPath` is set.
21
+ * It does not shell out or spawn child processes.
22
+ *
23
+ * **Config option decision tree:**
24
+ * - Does your grammar have recursive rules (e.g. `Expression: ... | left=Expression`)? →
25
+ * no action needed; cycle detection is automatic. If you run a custom pipeline, pass the
26
+ * *full* (unprojected) descriptor set to `detectRecursiveTypes` first.
27
+ * - Does your grammar have cross-references (`ref:` properties)? →
28
+ * if you need runtime ref-text validation in a live language server, enable
29
+ * `crossRefValidation: true` and use the emitted `create*Schema()` factories.
30
+ * Otherwise leave it off — unconstrained `ReferenceSchema` is lighter and sufficient for
31
+ * batch/offline validation.
32
+ * - Do you want to strip Langium internal bookkeeping fields (`$container`, `$document`,
33
+ * `$cstNode`, etc.)? → set `stripInternals: true`. These fields are never meaningful
34
+ * in a validation context and inflate the generated schema.
35
+ * - Do you need form labels and descriptions driven by the grammar? → enable `formMetadata: true`.
36
+ * Only properties whose grammar rule has a JSDoc/grammar comment get a `description`; every
37
+ * property gets a humanized `title` regardless.
38
+ * - Are you using Zod 4's `z.looseObject`? → the default `objectStyle: 'loose'` emits
39
+ * `z.looseObject(...)`. Switch to `objectStyle: 'strict'` + `.strict()` on the schema only
40
+ * when you need hard rejection of unknown properties (e.g. strict API request validation).
41
+ *
42
+ * @param config - Generator configuration including the grammar or AST types,
43
+ * optional output path, include/exclude filters, projection, and feature flags.
44
+ * @returns The generated TypeScript source containing all Zod schema exports.
45
+ * @throws {@link ZodGeneratorError} when required configuration is missing, when
46
+ * `conformance` is enabled without `outputPath`, or when a grammar property type
47
+ * cannot be mapped to a Zod schema.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * import { createLangiumGrammarServices } from 'langium/grammar';
52
+ * import { NodeFileSystem } from 'langium/node';
53
+ * import { generateZodSchemas } from 'langium-zod';
54
+ *
55
+ * const { grammar } = createLangiumGrammarServices(NodeFileSystem);
56
+ * // assume `parsedGrammar` is a Grammar node obtained from Langium
57
+ * const source = generateZodSchemas({
58
+ * grammar: parsedGrammar,
59
+ * outputPath: 'src/generated/zod-schemas.ts',
60
+ * stripInternals: true,
61
+ * });
62
+ * console.log(source); // TypeScript source with Zod schema exports
63
+ * ```
64
+ *
65
+ * @example
66
+ * ```ts
67
+ * // Using a pre-built AstTypesLike descriptor (skips grammar parsing)
68
+ * import { generateZodSchemas } from 'langium-zod';
69
+ * import { collectAst } from 'langium/grammar';
70
+ *
71
+ * const astTypes = collectAst(myGrammar);
72
+ * const source = generateZodSchemas({ astTypes });
73
+ * ```
74
+ *
75
+ * @useWhen
76
+ * - You have a parsed Langium `Grammar` object and want Zod schemas as a TypeScript string.
77
+ * - You are integrating langium-zod into a build pipeline (Vite plugin, codegen script, etc.).
78
+ * - You need conformance artifacts (type-guard files) alongside the schema output.
79
+ * - You want to write generated schemas to disk in a single call.
80
+ *
81
+ * @avoidWhen
82
+ * - You only need to inspect the intermediate type descriptors without generating code —
83
+ * use {@link extractTypeDescriptors} directly instead.
84
+ * - You are running inside the Langium DI container — prefer {@link DefaultZodSchemaGenerator}
85
+ * which injects services automatically.
86
+ * - You want to generate schemas for only a subset of types at runtime — pass `include`/`exclude`
87
+ * in the config rather than post-processing the output.
88
+ *
89
+ * @never
90
+ * - NEVER omit both `grammar` and `astTypes` — the function throws {@link ZodGeneratorError}
91
+ * immediately. BECAUSE there is no default grammar source and no way to recover silently.
92
+ * FIX: provide at least `{ grammar: parsedGrammar }` or `{ astTypes: collectAst(grammar) }`.
93
+ * - NEVER enable `conformance` without setting `outputPath` — the function will throw before
94
+ * writing any output. BECAUSE the conformance module needs to derive a sibling output path
95
+ * from the schema file's directory. FIX: always set `outputPath` when `conformance` is truthy.
96
+ * - NEVER pass a `Grammar[]` array when grammars share type names across files without
97
+ * verifying that Langium's `collectAst()` merges them correctly. BECAUSE duplicate type names
98
+ * will silently overwrite each other in the type map, producing truncated schemas.
99
+ * FIX: run `collectAst` separately and inspect the merged map before generation.
100
+ * - NEVER call with `crossRefValidation: true` on grammars with no cross-reference properties —
101
+ * it emits dead `create*Schema` factory functions that add noise without benefit.
102
+ * FIX: only enable `crossRefValidation` when your grammar has at least one `ref:` property.
103
+ * - NEVER remove the `// @ts-nocheck` comment from generated output files. BECAUSE the
104
+ * getter-based recursive property syntax (emitted for self-referential types) is not always
105
+ * accepted by TypeScript's strict object-literal type checker — removing the comment causes
106
+ * immediate TS build failures in grammars with recursive rules. FIX: treat generated files as
107
+ * opaque artifacts; place any hand-written extensions in a separate file that imports the schema.
108
+ * - NEVER commit generated schemas as the sole copy of your schema logic. BECAUSE any grammar
109
+ * edit (new rule, renamed property, changed cardinality) produces stale schemas that pass
110
+ * TypeScript but fail at Zod validation runtime. FIX: wire `langium-zod generate` as a
111
+ * pre-build or CI step so schema freshness is enforced automatically.
112
+ *
113
+ * @category Generation
114
+ * @see {@link extractTypeDescriptors}
115
+ * @see {@link detectRecursiveTypes}
116
+ * @see {@link generateZodCode}
117
+ * @see {@link ZodGeneratorConfig}
118
+ */
3
119
  export declare function generateZodSchemas(config: ZodGeneratorConfig): string;
120
+ /**
121
+ * Programmatic entry point for the domain target. Runs the same extract pipeline
122
+ * as {@link generateZodSchemas}, then emits the domain surface (read interfaces +
123
+ * `toDomain` projection + field-precise write accessors). Writes to
124
+ * `config.domainOutputPath` when set.
125
+ */
126
+ export declare function generateDomainSchemas(config: ZodGeneratorConfig): string;
4
127
  //# sourceMappingURL=api.d.ts.map
package/dist/api.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAStD,MAAM,MAAM,wBAAwB,GAAG,kBAAkB,CAAC;AAS1D,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAgGrE"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAUtD,MAAM,MAAM,wBAAwB,GAAG,kBAAkB,CAAC;AAS1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmHG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAkGrE;AAcD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CA4BxE"}
package/dist/api.js CHANGED
@@ -6,6 +6,7 @@ import { ZodGeneratorError } from './errors.js';
6
6
  import { extractTypeDescriptors } from './extractor.js';
7
7
  import { generateZodCode } from './generator.js';
8
8
  import { applyProjectionToDescriptors, resolveEffectiveStripFields } from './projection.js';
9
+ import { generateDomainCode } from './emitters/domain.js';
9
10
  import { detectRecursiveTypes } from './recursion-detector.js';
10
11
  function resolveAstTypes(astTypes) {
11
12
  return {
@@ -13,6 +14,122 @@ function resolveAstTypes(astTypes) {
13
14
  unions: astTypes.unions ?? []
14
15
  };
15
16
  }
17
+ /**
18
+ * Main entry point for programmatic Zod schema generation from a Langium grammar.
19
+ *
20
+ * Accepts a {@link ZodGeneratorConfig} that specifies either a parsed Langium
21
+ * `Grammar` object or a pre-built {@link AstTypesLike} descriptor, then runs the
22
+ * full extraction → projection → code-generation pipeline and returns the
23
+ * generated TypeScript source as a string. When `config.outputPath` is set the
24
+ * result is also written to disk. Conformance artifacts are generated when
25
+ * `config.conformance` is provided.
26
+ *
27
+ * @remarks
28
+ * This is the primary API for most consumers. It combines {@link extractTypeDescriptors},
29
+ * {@link detectRecursiveTypes}, and {@link generateZodCode} into a single call. Use the
30
+ * lower-level functions directly only when you need fine-grained control over individual
31
+ * pipeline stages (e.g. to inspect descriptors before code generation, or to cache
32
+ * extraction results across multiple code-generation runs).
33
+ *
34
+ * The function is synchronous and writes to disk only when `config.outputPath` is set.
35
+ * It does not shell out or spawn child processes.
36
+ *
37
+ * **Config option decision tree:**
38
+ * - Does your grammar have recursive rules (e.g. `Expression: ... | left=Expression`)? →
39
+ * no action needed; cycle detection is automatic. If you run a custom pipeline, pass the
40
+ * *full* (unprojected) descriptor set to `detectRecursiveTypes` first.
41
+ * - Does your grammar have cross-references (`ref:` properties)? →
42
+ * if you need runtime ref-text validation in a live language server, enable
43
+ * `crossRefValidation: true` and use the emitted `create*Schema()` factories.
44
+ * Otherwise leave it off — unconstrained `ReferenceSchema` is lighter and sufficient for
45
+ * batch/offline validation.
46
+ * - Do you want to strip Langium internal bookkeeping fields (`$container`, `$document`,
47
+ * `$cstNode`, etc.)? → set `stripInternals: true`. These fields are never meaningful
48
+ * in a validation context and inflate the generated schema.
49
+ * - Do you need form labels and descriptions driven by the grammar? → enable `formMetadata: true`.
50
+ * Only properties whose grammar rule has a JSDoc/grammar comment get a `description`; every
51
+ * property gets a humanized `title` regardless.
52
+ * - Are you using Zod 4's `z.looseObject`? → the default `objectStyle: 'loose'` emits
53
+ * `z.looseObject(...)`. Switch to `objectStyle: 'strict'` + `.strict()` on the schema only
54
+ * when you need hard rejection of unknown properties (e.g. strict API request validation).
55
+ *
56
+ * @param config - Generator configuration including the grammar or AST types,
57
+ * optional output path, include/exclude filters, projection, and feature flags.
58
+ * @returns The generated TypeScript source containing all Zod schema exports.
59
+ * @throws {@link ZodGeneratorError} when required configuration is missing, when
60
+ * `conformance` is enabled without `outputPath`, or when a grammar property type
61
+ * cannot be mapped to a Zod schema.
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * import { createLangiumGrammarServices } from 'langium/grammar';
66
+ * import { NodeFileSystem } from 'langium/node';
67
+ * import { generateZodSchemas } from 'langium-zod';
68
+ *
69
+ * const { grammar } = createLangiumGrammarServices(NodeFileSystem);
70
+ * // assume `parsedGrammar` is a Grammar node obtained from Langium
71
+ * const source = generateZodSchemas({
72
+ * grammar: parsedGrammar,
73
+ * outputPath: 'src/generated/zod-schemas.ts',
74
+ * stripInternals: true,
75
+ * });
76
+ * console.log(source); // TypeScript source with Zod schema exports
77
+ * ```
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * // Using a pre-built AstTypesLike descriptor (skips grammar parsing)
82
+ * import { generateZodSchemas } from 'langium-zod';
83
+ * import { collectAst } from 'langium/grammar';
84
+ *
85
+ * const astTypes = collectAst(myGrammar);
86
+ * const source = generateZodSchemas({ astTypes });
87
+ * ```
88
+ *
89
+ * @useWhen
90
+ * - You have a parsed Langium `Grammar` object and want Zod schemas as a TypeScript string.
91
+ * - You are integrating langium-zod into a build pipeline (Vite plugin, codegen script, etc.).
92
+ * - You need conformance artifacts (type-guard files) alongside the schema output.
93
+ * - You want to write generated schemas to disk in a single call.
94
+ *
95
+ * @avoidWhen
96
+ * - You only need to inspect the intermediate type descriptors without generating code —
97
+ * use {@link extractTypeDescriptors} directly instead.
98
+ * - You are running inside the Langium DI container — prefer {@link DefaultZodSchemaGenerator}
99
+ * which injects services automatically.
100
+ * - You want to generate schemas for only a subset of types at runtime — pass `include`/`exclude`
101
+ * in the config rather than post-processing the output.
102
+ *
103
+ * @never
104
+ * - NEVER omit both `grammar` and `astTypes` — the function throws {@link ZodGeneratorError}
105
+ * immediately. BECAUSE there is no default grammar source and no way to recover silently.
106
+ * FIX: provide at least `{ grammar: parsedGrammar }` or `{ astTypes: collectAst(grammar) }`.
107
+ * - NEVER enable `conformance` without setting `outputPath` — the function will throw before
108
+ * writing any output. BECAUSE the conformance module needs to derive a sibling output path
109
+ * from the schema file's directory. FIX: always set `outputPath` when `conformance` is truthy.
110
+ * - NEVER pass a `Grammar[]` array when grammars share type names across files without
111
+ * verifying that Langium's `collectAst()` merges them correctly. BECAUSE duplicate type names
112
+ * will silently overwrite each other in the type map, producing truncated schemas.
113
+ * FIX: run `collectAst` separately and inspect the merged map before generation.
114
+ * - NEVER call with `crossRefValidation: true` on grammars with no cross-reference properties —
115
+ * it emits dead `create*Schema` factory functions that add noise without benefit.
116
+ * FIX: only enable `crossRefValidation` when your grammar has at least one `ref:` property.
117
+ * - NEVER remove the `// @ts-nocheck` comment from generated output files. BECAUSE the
118
+ * getter-based recursive property syntax (emitted for self-referential types) is not always
119
+ * accepted by TypeScript's strict object-literal type checker — removing the comment causes
120
+ * immediate TS build failures in grammars with recursive rules. FIX: treat generated files as
121
+ * opaque artifacts; place any hand-written extensions in a separate file that imports the schema.
122
+ * - NEVER commit generated schemas as the sole copy of your schema logic. BECAUSE any grammar
123
+ * edit (new rule, renamed property, changed cardinality) produces stale schemas that pass
124
+ * TypeScript but fail at Zod validation runtime. FIX: wire `langium-zod generate` as a
125
+ * pre-build or CI step so schema freshness is enforced automatically.
126
+ *
127
+ * @category Generation
128
+ * @see {@link extractTypeDescriptors}
129
+ * @see {@link detectRecursiveTypes}
130
+ * @see {@link generateZodCode}
131
+ * @see {@link ZodGeneratorConfig}
132
+ */
16
133
  export function generateZodSchemas(config) {
17
134
  let rawAstTypes;
18
135
  if (config.astTypes) {
@@ -104,4 +221,38 @@ function buildDescriptorPipeline(astTypes, config) {
104
221
  });
105
222
  return descriptors;
106
223
  }
224
+ /**
225
+ * Programmatic entry point for the domain target. Runs the same extract pipeline
226
+ * as {@link generateZodSchemas}, then emits the domain surface (read interfaces +
227
+ * `toDomain` projection + field-precise write accessors). Writes to
228
+ * `config.domainOutputPath` when set.
229
+ */
230
+ export function generateDomainSchemas(config) {
231
+ let rawAstTypes;
232
+ if (config.astTypes) {
233
+ rawAstTypes = config.astTypes;
234
+ }
235
+ else if (config.grammar) {
236
+ rawAstTypes = collectAst(config.grammar);
237
+ }
238
+ else {
239
+ throw new ZodGeneratorError('Missing grammar or astTypes in ZodGeneratorConfig', {
240
+ suggestion: "Provide astTypes from Langium's collectAst() or pass a grammar object"
241
+ });
242
+ }
243
+ const astTypes = resolveAstTypes(rawAstTypes);
244
+ const descriptors = buildDescriptorPipeline(astTypes, config);
245
+ // Note: regexOverrides (regex-enum upgrades) are intentionally NOT applied here —
246
+ // the domain surface uses type references + primitives, never regex-enum shapes.
247
+ const source = generateDomainCode(descriptors, {
248
+ projection: config.projection,
249
+ stripInternals: config.stripInternals,
250
+ overlays: config.domainOverlays
251
+ });
252
+ if (config.domainOutputPath) {
253
+ mkdirSync(dirname(config.domainOutputPath), { recursive: true });
254
+ writeFileSync(config.domainOutputPath, source, 'utf8');
255
+ }
256
+ return source;
257
+ }
107
258
  //# sourceMappingURL=api.js.map
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,4BAA4B,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAC5F,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAK/D,SAAS,eAAe,CAAC,QAAsB;IAC9C,OAAO;QACN,UAAU,EAAE,QAAQ,CAAC,UAAU,IAAI,EAAE;QACrC,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,EAAE;KAC7B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAA0B;IAC5D,IAAI,WAAyB,CAAC;IAC9B,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACrB,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC/B,CAAC;SAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC3B,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,OAAO,CAA4B,CAAC;IACrE,CAAC;SAAM,CAAC;QACP,MAAM,IAAI,iBAAiB,CAAC,mDAAmD,EAAE;YAChF,UAAU,EAAE,uEAAuE;SACnF,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;IAC9C,MAAM,cAAc,GAAG,uBAAuB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAEjE,gFAAgF;IAChF,4EAA4E;IAC5E,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,IAAI,EAAE,CAAC;IAC9C,MAAM,WAAW,GAAwB,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACjE,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,QAAQ,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,EAAE,CAAC;YAC3E,OAAO;gBACN,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,IAAI,EAAE,YAAY;gBAClB,KAAK,EAAE,QAAQ;gBACf,QAAQ,EAAE,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAE,CAA4B,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;aAC9C,CAAC;QACpC,CAAC;QACD,OAAO,CAAC,CAAC;IACV,CAAC,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;IACzD,MAAM,kBAAkB,GAAG,4BAA4B,CAAC,WAAW,EAAE;QACpE,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,cAAc,EAAE,MAAM,CAAC,cAAc;KACrC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,EAAE,cAAc,EAAE;QAC3D,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;QAC7C,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,WAAW,EAAE,MAAM,CAAC,WAAW;KAC/B,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACvB,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,aAAa,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;IAED,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACxB,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YACxB,MAAM,IAAI,iBAAiB,CAAC,4CAA4C,EAAE;gBACzE,UAAU,EAAE,2DAA2D;aACvE,CAAC,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC;YACtC,MAAM,IAAI,iBAAiB,CAAC,8CAA8C,EAAE;gBAC3E,UAAU,EAAE,yEAAyE;aACrF,CAAC,CAAC;QACJ,CAAC;QAED,MAAM,eAAe,GAAG,kBAAkB;aACxC,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,KAAK,QAAQ,CAAC;aACpD,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAEvC,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,oFAAoF,CAAC,CAAC;YACnG,OAAO,MAAM,CAAC;QACf,CAAC;QAED,MAAM,qBAAqB,GAAG,0BAA0B,CACvD,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,WAAW,CAAC,UAAU,CAC7B,CAAC;QACF,MAAM,WAAW,GAAG,yBAAyB,CAAC;YAC7C,gBAAgB,EAAE,MAAM,CAAC,UAAU;YACnC,qBAAqB;YACrB,YAAY,EAAE,MAAM,CAAC,WAAW,CAAC,YAAY;YAC7C,eAAe;YACf,WAAW,EAAE,2BAA2B,CAAC;gBACxC,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,cAAc,EAAE,MAAM,CAAC,cAAc;aACrC,CAAC;YACF,UAAU,EAAE,MAAM,CAAC,UAAU;SAC7B,CAAC,CAAC;QAEH,KAAK,MAAM,WAAW,IAAI,WAAW,CAAC,eAAe,EAAE,CAAC;YACvD,OAAO,CAAC,IAAI,CAAC,oDAAoD,WAAW,aAAa,CAAC,CAAC;QAC5F,CAAC;QAED,SAAS,CAAC,OAAO,CAAC,qBAAqB,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,aAAa,CAAC,qBAAqB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC;AAED,SAAS,uBAAuB,CAAC,QAAsB,EAAE,MAA0B;IAClF,MAAM,WAAW,GAAG,sBAAsB,CAAC,QAAQ,EAAE;QACpD,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,MAAM,CAAC,OAAO;KACvB,CAAC,CAAC;IAEH,OAAO,WAAW,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts CHANGED
@@ -10,14 +10,90 @@ export interface LangiumZodConfig extends Omit<ZodGeneratorConfig, 'grammar' | '
10
10
  /** Explicit output path. Overrides derived path from langium-config.json `out` field. */
11
11
  outputPath?: string;
12
12
  }
13
+ /**
14
+ * Merges CLI `--include` / `--exclude` flag values with the base filter from a
15
+ * user config file, producing a deduplicated, conflict-free filter pair.
16
+ *
17
+ * CLI arguments take precedence over the config file values. Any name that appears
18
+ * in both `include` and `exclude` is removed from `include` so that the exclude
19
+ * list is authoritative.
20
+ *
21
+ * @param base - Baseline include/exclude arrays from the user's
22
+ * `langium-zod.config.js`, used when the corresponding CLI flag is absent.
23
+ * @param includeArg - Raw comma-separated string from `--include`, or `undefined`
24
+ * when the flag was not passed.
25
+ * @param excludeArg - Raw comma-separated string from `--exclude`, or `undefined`
26
+ * when the flag was not passed.
27
+ * @returns A resolved `{ include, exclude }` pair ready to merge into the
28
+ * generator config.
29
+ */
13
30
  export declare function resolveFilterOverrides(base: Pick<LangiumZodConfig, 'include' | 'exclude'>, includeArg?: string, excludeArg?: string): Pick<LangiumZodConfig, 'include' | 'exclude'>;
31
+ /**
32
+ * Returns the subset of `requested` names that are not present in
33
+ * `availableTypeNames`.
34
+ *
35
+ * Used to surface warnings when the user's `--include` or `--exclude` list
36
+ * references type names that do not exist in the parsed grammar, helping catch
37
+ * typos before generation runs.
38
+ *
39
+ * @param requested - The type names requested by the user (include or exclude
40
+ * list). Returns an empty array immediately when this is `undefined` or empty.
41
+ * @param availableTypeNames - All type names present in the parsed Langium grammar
42
+ * (both interface types and union/datatype rule types).
43
+ * @returns An array of names from `requested` that are absent from
44
+ * `availableTypeNames`.
45
+ */
14
46
  export declare function getUnknownFilterNames(requested: string[] | undefined, availableTypeNames: string[]): string[];
47
+ /**
48
+ * Options accepted by the programmatic {@link generate} function.
49
+ *
50
+ * Allows the core generation logic to be invoked directly from other tools or
51
+ * scripts without going through the CLI argument parser.
52
+ */
15
53
  export interface GenerateOptions {
16
54
  /** Absolute path to langium-config.json */
17
55
  langiumConfigPath: string;
18
56
  /** Merged generator config (from user's langium-zod.config.js + CLI flags) */
19
57
  config?: LangiumZodConfig;
20
58
  }
59
+ /**
60
+ * Programmatic entry point for the `langium-zod generate` command.
61
+ *
62
+ * Loads `langium-config.json` from `opts.langiumConfigPath`, resolves the grammar
63
+ * file path, parses the grammar with Langium services (including eager import
64
+ * loading so cross-file references link correctly), then calls
65
+ * {@link generateZodSchemas} with the merged configuration. Prints a success
66
+ * message to stdout when generation completes.
67
+ *
68
+ * @param opts - {@link GenerateOptions} specifying the langium config path and
69
+ * optional pre-merged generator config.
70
+ * @throws `Error` when the langium-config.json or grammar file cannot be found, or
71
+ * when the config defines no languages.
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * import { generate } from 'langium-zod';
76
+ * import { resolve } from 'node:path';
77
+ *
78
+ * await generate({
79
+ * langiumConfigPath: resolve(process.cwd(), 'langium-config.json'),
80
+ * config: {
81
+ * outputPath: 'src/generated/zod-schemas.ts',
82
+ * stripInternals: true,
83
+ * },
84
+ * });
85
+ * // Prints: ✓ Generated Zod schemas → src/generated/zod-schemas.ts
86
+ * ```
87
+ */
21
88
  export declare function generate(opts: GenerateOptions): Promise<void>;
89
+ /**
90
+ * CLI entry point executed when the `langium-zod` binary is invoked directly.
91
+ *
92
+ * Parses `process.argv`, resolves `langium-config.json`, loads an optional
93
+ * `langium-zod.config.js` from the same directory, merges all CLI flag overrides
94
+ * (--out, --include, --exclude, --projection, --strip-internals, --conformance,
95
+ * --cross-ref-validation), then delegates to {@link generate}. Exits the process
96
+ * with code 1 on error.
97
+ */
22
98
  export declare function main(): Promise<void>;
23
99
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAgBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAQtD,kEAAkE;AAClE,MAAM,WAAW,gBAChB,SAAQ,IAAI,CAAC,kBAAkB,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;IACrE;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yFAAyF;IACzF,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAuCD,wBAAgB,sBAAsB,CACrC,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,SAAS,CAAC,EACnD,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,GACjB,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,SAAS,CAAC,CAc/C;AAoBD,wBAAgB,qBAAqB,CACpC,SAAS,EAAE,MAAM,EAAE,GAAG,SAAS,EAC/B,kBAAkB,EAAE,MAAM,EAAE,GAC1B,MAAM,EAAE,CAOV;AAyED,MAAM,WAAW,eAAe;IAC/B,2CAA2C;IAC3C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA0FnE;AAMD,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAmG1C"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAgBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAQtD,kEAAkE;AAClE,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAC5C,kBAAkB,EAClB,SAAS,GAAG,UAAU,GAAG,UAAU,CACpC;IACC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yFAAyF;IACzF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAuCD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,SAAS,CAAC,EACnD,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,GAClB,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,SAAS,CAAC,CAc/C;AAkBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EAAE,GAAG,SAAS,EAC/B,kBAAkB,EAAE,MAAM,EAAE,GAC3B,MAAM,EAAE,CAOV;AA2ED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,2CAA2C;IAC3C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA2GnE;AAMD;;;;;;;;GAQG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CA6G1C"}
package/dist/cli.js CHANGED
@@ -12,7 +12,7 @@ import { pathToFileURL } from 'node:url';
12
12
  import { URI } from 'langium';
13
13
  import { createLangiumGrammarServices, resolveImportUri } from 'langium/grammar';
14
14
  import { NodeFileSystem } from 'langium/node';
15
- import { generateZodSchemas } from './api.js';
15
+ import { generateZodSchemas, generateDomainSchemas } from './api.js';
16
16
  import { resolveAstTypesPath } from './conformance.js';
17
17
  import { loadProjectionConfig } from './projection.js';
18
18
  function parseCsvList(value) {
@@ -39,6 +39,23 @@ function getArgValue(args, flag) {
39
39
  }
40
40
  return value;
41
41
  }
42
+ /**
43
+ * Merges CLI `--include` / `--exclude` flag values with the base filter from a
44
+ * user config file, producing a deduplicated, conflict-free filter pair.
45
+ *
46
+ * CLI arguments take precedence over the config file values. Any name that appears
47
+ * in both `include` and `exclude` is removed from `include` so that the exclude
48
+ * list is authoritative.
49
+ *
50
+ * @param base - Baseline include/exclude arrays from the user's
51
+ * `langium-zod.config.js`, used when the corresponding CLI flag is absent.
52
+ * @param includeArg - Raw comma-separated string from `--include`, or `undefined`
53
+ * when the flag was not passed.
54
+ * @param excludeArg - Raw comma-separated string from `--exclude`, or `undefined`
55
+ * when the flag was not passed.
56
+ * @returns A resolved `{ include, exclude }` pair ready to merge into the
57
+ * generator config.
58
+ */
42
59
  export function resolveFilterOverrides(base, includeArg, excludeArg) {
43
60
  const includeFromCli = includeArg === undefined ? undefined : parseCsvList(includeArg);
44
61
  const excludeFromCli = excludeArg === undefined ? undefined : parseCsvList(excludeArg);
@@ -56,11 +73,24 @@ function warnUnknownFilterNames(filterName, requested, availableTypeNames) {
56
73
  if (unknown.length === 0) {
57
74
  return;
58
75
  }
59
- const availableList = availableTypeNames.length > 0
60
- ? availableTypeNames.join(', ')
61
- : '(none)';
76
+ const availableList = availableTypeNames.length > 0 ? availableTypeNames.join(', ') : '(none)';
62
77
  console.warn(`Warning: Unknown ${filterName} type name(s): ${unknown.join(', ')}. Available types: ${availableList}`);
63
78
  }
79
+ /**
80
+ * Returns the subset of `requested` names that are not present in
81
+ * `availableTypeNames`.
82
+ *
83
+ * Used to surface warnings when the user's `--include` or `--exclude` list
84
+ * references type names that do not exist in the parsed grammar, helping catch
85
+ * typos before generation runs.
86
+ *
87
+ * @param requested - The type names requested by the user (include or exclude
88
+ * list). Returns an empty array immediately when this is `undefined` or empty.
89
+ * @param availableTypeNames - All type names present in the parsed Langium grammar
90
+ * (both interface types and union/datatype rule types).
91
+ * @returns An array of names from `requested` that are absent from
92
+ * `availableTypeNames`.
93
+ */
64
94
  export function getUnknownFilterNames(requested, availableTypeNames) {
65
95
  if (!requested || requested.length === 0) {
66
96
  return [];
@@ -89,6 +119,8 @@ OPTIONS
89
119
  --ast-types <path> Path to generated AST declarations (ast.ts)
90
120
  --conformance-out <path> Output path for conformance artifact
91
121
  --cross-ref-validation Emit runtime cross-reference schema factories
122
+ --domain Also emit the domain surface (domain.ts)
123
+ --domain-out <path> Output path for the domain surface
92
124
  --help Show this help message
93
125
 
94
126
  CONFIGURATION
@@ -128,6 +160,35 @@ async function eagerLoad(document, documents, visited = new Set()) {
128
160
  }
129
161
  }
130
162
  }
163
+ /**
164
+ * Programmatic entry point for the `langium-zod generate` command.
165
+ *
166
+ * Loads `langium-config.json` from `opts.langiumConfigPath`, resolves the grammar
167
+ * file path, parses the grammar with Langium services (including eager import
168
+ * loading so cross-file references link correctly), then calls
169
+ * {@link generateZodSchemas} with the merged configuration. Prints a success
170
+ * message to stdout when generation completes.
171
+ *
172
+ * @param opts - {@link GenerateOptions} specifying the langium config path and
173
+ * optional pre-merged generator config.
174
+ * @throws `Error` when the langium-config.json or grammar file cannot be found, or
175
+ * when the config defines no languages.
176
+ *
177
+ * @example
178
+ * ```ts
179
+ * import { generate } from 'langium-zod';
180
+ * import { resolve } from 'node:path';
181
+ *
182
+ * await generate({
183
+ * langiumConfigPath: resolve(process.cwd(), 'langium-config.json'),
184
+ * config: {
185
+ * outputPath: 'src/generated/zod-schemas.ts',
186
+ * stripInternals: true,
187
+ * },
188
+ * });
189
+ * // Prints: ✓ Generated Zod schemas → src/generated/zod-schemas.ts
190
+ * ```
191
+ */
131
192
  export async function generate(opts) {
132
193
  const { langiumConfigPath } = opts;
133
194
  const userConfig = opts.config ?? {};
@@ -177,7 +238,7 @@ export async function generate(opts) {
177
238
  await eagerLoad(entryDocument, langiumDocuments);
178
239
  // Build (parse + link) all loaded documents
179
240
  await documentBuilder.build(langiumDocuments.all.toArray(), {
180
- validation: false,
241
+ validation: false
181
242
  });
182
243
  const grammar = entryDocument.parseResult.value;
183
244
  const availableTypeNames = [
@@ -189,17 +250,39 @@ export async function generate(opts) {
189
250
  warnUnknownFilterNames('include', userConfig.include, availableTypeNames);
190
251
  warnUnknownFilterNames('exclude', userConfig.exclude, availableTypeNames);
191
252
  // ── 4. Generate schemas ──────────────────────────────────────────────────
192
- const { langiumConfig: _ignored, outputPath: _op, ...restConfig } = userConfig;
253
+ const { langiumConfig: _ignored, outputPath: _op, emitDomain: _emitDomain, domainOutputPath: _domainOutputPath, ...restConfig } = userConfig;
193
254
  generateZodSchemas({
194
255
  grammar,
195
256
  outputPath,
196
- ...restConfig,
257
+ ...restConfig
197
258
  });
198
259
  console.log(`✓ Generated Zod schemas → ${outputPath}`);
260
+ if (userConfig.emitDomain) {
261
+ const domainOutputPath = userConfig.domainOutputPath ?? join(outDir, 'domain.ts');
262
+ generateDomainSchemas({
263
+ grammar,
264
+ domainOutputPath,
265
+ stripInternals: restConfig.stripInternals,
266
+ projection: restConfig.projection,
267
+ domainOverlays: restConfig.domainOverlays,
268
+ include: restConfig.include,
269
+ exclude: restConfig.exclude
270
+ });
271
+ console.log(`✓ Generated domain surface → ${domainOutputPath}`);
272
+ }
199
273
  }
200
274
  // ────────────────────────────────────────────────────────────────────────────
201
275
  // CLI entry point
202
276
  // ────────────────────────────────────────────────────────────────────────────
277
+ /**
278
+ * CLI entry point executed when the `langium-zod` binary is invoked directly.
279
+ *
280
+ * Parses `process.argv`, resolves `langium-config.json`, loads an optional
281
+ * `langium-zod.config.js` from the same directory, merges all CLI flag overrides
282
+ * (--out, --include, --exclude, --projection, --strip-internals, --conformance,
283
+ * --cross-ref-validation), then delegates to {@link generate}. Exits the process
284
+ * with code 1 on error.
285
+ */
203
286
  export async function main() {
204
287
  const args = process.argv.slice(2);
205
288
  if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
@@ -225,16 +308,15 @@ export async function main() {
225
308
  const stripInternalsEnabled = args.includes('--strip-internals');
226
309
  const conformanceEnabled = args.includes('--conformance');
227
310
  const crossRefValidationEnabled = args.includes('--cross-ref-validation');
311
+ const domainEnabled = args.includes('--domain');
312
+ const domainOutFlagValue = getArgValue(args, '--domain-out');
228
313
  // ── Locate langium-config.json ───────────────────────────────────────────
229
314
  const configFileName = configFlagValue ?? 'langium-config.json';
230
315
  const langiumConfigPath = resolve(process.cwd(), configFileName);
231
316
  // ── Load optional langium-zod.config.js ──────────────────────────────────
232
317
  const configDir = dirname(langiumConfigPath);
233
318
  let userConfig = {};
234
- for (const candidate of [
235
- 'langium-zod.config.js',
236
- 'langium-zod.config.mjs',
237
- ]) {
319
+ for (const candidate of ['langium-zod.config.js', 'langium-zod.config.mjs']) {
238
320
  const candidatePath = join(configDir, candidate);
239
321
  if (existsSync(candidatePath)) {
240
322
  const mod = await import(pathToFileURL(candidatePath).href);
@@ -269,7 +351,9 @@ export async function main() {
269
351
  ...userConfig,
270
352
  conformance: {
271
353
  astTypesPath: astTypesFlagValue ? resolve(process.cwd(), astTypesFlagValue) : undefined,
272
- outputPath: conformanceOutFlagValue ? resolve(process.cwd(), conformanceOutFlagValue) : undefined
354
+ outputPath: conformanceOutFlagValue
355
+ ? resolve(process.cwd(), conformanceOutFlagValue)
356
+ : undefined
273
357
  }
274
358
  };
275
359
  }
@@ -279,6 +363,15 @@ export async function main() {
279
363
  crossRefValidation: true
280
364
  };
281
365
  }
366
+ if (domainEnabled) {
367
+ userConfig = {
368
+ ...userConfig,
369
+ emitDomain: true,
370
+ domainOutputPath: domainOutFlagValue
371
+ ? resolve(process.cwd(), domainOutFlagValue)
372
+ : userConfig.domainOutputPath
373
+ };
374
+ }
282
375
  try {
283
376
  await generate({ langiumConfigPath, config: userConfig });
284
377
  }