langium-zod 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-present Pradeep Mouli
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # langium-zod
2
+
3
+ Generate Zod schemas from Langium grammars.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pnpm add langium-zod
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```ts
14
+ import { generateZodSchemas } from 'langium-zod';
15
+
16
+ const source = generateZodSchemas({ grammar, services });
17
+ ```
18
+
19
+ Generated output uses Zod 4 and exports named schemas like `<TypeName>Schema`.
20
+
21
+ ## Requirements
22
+
23
+ - Node.js >= 20
24
+ - Langium 4.x
25
+ - Zod 4.x
package/dist/api.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { ZodGeneratorConfig } from './config.js';
2
+ export declare function generateZodSchemas(config: ZodGeneratorConfig): string;
3
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AActD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CA2BrE"}
package/dist/api.js ADDED
@@ -0,0 +1,40 @@
1
+ import { mkdirSync, writeFileSync } from 'node:fs';
2
+ import { dirname } from 'node:path';
3
+ import { collectAst } from 'langium/grammar';
4
+ import { ZodGeneratorError } from './errors.js';
5
+ import { extractTypeDescriptors } from './extractor.js';
6
+ import { generateZodCode } from './generator.js';
7
+ import { detectRecursiveTypes } from './recursion-detector.js';
8
+ function resolveAstTypes(astTypes) {
9
+ return {
10
+ interfaces: astTypes.interfaces ?? [],
11
+ unions: astTypes.unions ?? []
12
+ };
13
+ }
14
+ export function generateZodSchemas(config) {
15
+ let rawAstTypes;
16
+ if (config.astTypes) {
17
+ rawAstTypes = config.astTypes;
18
+ }
19
+ else if (config.grammar) {
20
+ rawAstTypes = collectAst(config.grammar);
21
+ }
22
+ else {
23
+ throw new ZodGeneratorError('Missing grammar or astTypes in ZodGeneratorConfig', {
24
+ suggestion: "Provide astTypes from Langium's collectAst() or pass a grammar object"
25
+ });
26
+ }
27
+ const astTypes = resolveAstTypes(rawAstTypes);
28
+ const descriptors = extractTypeDescriptors(astTypes, {
29
+ include: config.include,
30
+ exclude: config.exclude
31
+ });
32
+ const recursiveTypes = detectRecursiveTypes(descriptors);
33
+ const source = generateZodCode(descriptors, recursiveTypes);
34
+ if (config.outputPath) {
35
+ mkdirSync(dirname(config.outputPath), { recursive: true });
36
+ writeFileSync(config.outputPath, source, 'utf8');
37
+ }
38
+ return source;
39
+ }
40
+ //# sourceMappingURL=api.js.map
@@ -0,0 +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,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/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;IAE9C,MAAM,WAAW,GAAG,sBAAsB,CAAC,QAAQ,EAAE;QACpD,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,MAAM,CAAC,OAAO;KACvB,CAAC,CAAC;IACH,MAAM,cAAc,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAE5D,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,OAAO,MAAM,CAAC;AACf,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { Grammar, LangiumCoreServices } from 'langium';
2
+ import type { AstTypesLike } from './types.js';
3
+ export interface FilterConfig {
4
+ include?: string[];
5
+ exclude?: string[];
6
+ }
7
+ export interface ZodGeneratorConfig extends FilterConfig {
8
+ grammar?: Grammar | Grammar[];
9
+ services?: LangiumCoreServices;
10
+ outputPath?: string;
11
+ astTypes?: AstTypesLike;
12
+ }
13
+ export declare const DEFAULT_OUTPUT_PATH = "src/generated/zod-schemas.ts";
14
+ export declare function normalizeFilterConfig(config?: FilterConfig): Required<FilterConfig>;
15
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC5B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACvD,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,EAAE,CAAC;IAC9B,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,YAAY,CAAC;CACxB;AAED,eAAO,MAAM,mBAAmB,iCAAiC,CAAC;AAElE,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC,CAKnF"}
package/dist/config.js ADDED
@@ -0,0 +1,8 @@
1
+ export const DEFAULT_OUTPUT_PATH = 'src/generated/zod-schemas.ts';
2
+ export function normalizeFilterConfig(config) {
3
+ return {
4
+ include: config?.include ?? [],
5
+ exclude: config?.exclude ?? []
6
+ };
7
+ }
8
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAeA,MAAM,CAAC,MAAM,mBAAmB,GAAG,8BAA8B,CAAC;AAElE,MAAM,UAAU,qBAAqB,CAAC,MAAqB;IAC1D,OAAO;QACN,OAAO,EAAE,MAAM,EAAE,OAAO,IAAI,EAAE;QAC9B,OAAO,EAAE,MAAM,EAAE,OAAO,IAAI,EAAE;KAC9B,CAAC;AACH,CAAC"}
package/dist/di.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ import type { Grammar, LangiumCoreServices, Module } from 'langium';
2
+ import type { ZodGeneratorConfig } from './config.js';
3
+ export interface ZodSchemaGenerator {
4
+ generate(grammar: Grammar, config?: Partial<ZodGeneratorConfig>): string;
5
+ }
6
+ export declare class DefaultZodSchemaGenerator implements ZodSchemaGenerator {
7
+ #private;
8
+ constructor(services: LangiumCoreServices);
9
+ generate(grammar: Grammar, config?: Partial<ZodGeneratorConfig>): string;
10
+ }
11
+ export type ZodSchemaGeneratorServices = {
12
+ shared: {
13
+ ZodSchemaGenerator: ZodSchemaGenerator;
14
+ };
15
+ };
16
+ export declare const ZodSchemaGeneratorModule: Module<ZodSchemaGeneratorServices, Partial<ZodSchemaGeneratorServices>>;
17
+ //# sourceMappingURL=di.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"di.d.ts","sourceRoot":"","sources":["../src/di.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGtD,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,MAAM,CAAC;CACzE;AAED,qBAAa,yBAA0B,YAAW,kBAAkB;;gBAGvD,QAAQ,EAAE,mBAAmB;IAIzC,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,MAAM;CASxE;AAED,MAAM,MAAM,0BAA0B,GAAG;IACxC,MAAM,EAAE;QACP,kBAAkB,EAAE,kBAAkB,CAAC;KACvC,CAAC;CACF,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAIrB,MAAM,CAAC,0BAA0B,EAAE,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC"}
package/dist/di.js ADDED
@@ -0,0 +1,22 @@
1
+ import { generateZodSchemas } from './api.js';
2
+ export class DefaultZodSchemaGenerator {
3
+ #services;
4
+ constructor(services) {
5
+ this.#services = services;
6
+ }
7
+ generate(grammar, config) {
8
+ return generateZodSchemas({
9
+ grammar,
10
+ services: this.#services,
11
+ include: config?.include,
12
+ exclude: config?.exclude,
13
+ outputPath: config?.outputPath
14
+ });
15
+ }
16
+ }
17
+ export const ZodSchemaGeneratorModule = {
18
+ shared: {
19
+ ZodSchemaGenerator: (services) => new DefaultZodSchemaGenerator(services)
20
+ }
21
+ };
22
+ //# sourceMappingURL=di.js.map
package/dist/di.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"di.js","sourceRoot":"","sources":["../src/di.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAM9C,MAAM,OAAO,yBAAyB;IACrC,SAAS,CAAsB;IAE/B,YAAY,QAA6B;QACxC,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,QAAQ,CAAC,OAAgB,EAAE,MAAoC;QAC9D,OAAO,kBAAkB,CAAC;YACzB,OAAO;YACP,QAAQ,EAAE,IAAI,CAAC,SAAS;YACxB,OAAO,EAAE,MAAM,EAAE,OAAO;YACxB,OAAO,EAAE,MAAM,EAAE,OAAO;YACxB,UAAU,EAAE,MAAM,EAAE,UAAU;SAC9B,CAAC,CAAC;IACJ,CAAC;CACD;AAQD,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACvC,MAAM,EAAE;QACP,kBAAkB,EAAE,CAAC,QAA6B,EAAE,EAAE,CAAC,IAAI,yBAAyB,CAAC,QAAQ,CAAC;KAC9F;CACqF,CAAC"}
@@ -0,0 +1,13 @@
1
+ export interface ZodGeneratorErrorOptions {
2
+ grammarElement?: string;
3
+ typeName?: string;
4
+ suggestion?: string;
5
+ cause?: unknown;
6
+ }
7
+ export declare class ZodGeneratorError extends Error {
8
+ readonly grammarElement?: string;
9
+ readonly typeName?: string;
10
+ readonly suggestion?: string;
11
+ constructor(message: string, options?: ZodGeneratorErrorOptions);
12
+ }
13
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,wBAAwB;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,qBAAa,iBAAkB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;gBAEjB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,wBAAwB;CAW/D"}
package/dist/errors.js ADDED
@@ -0,0 +1,16 @@
1
+ export class ZodGeneratorError extends Error {
2
+ grammarElement;
3
+ typeName;
4
+ suggestion;
5
+ constructor(message, options) {
6
+ super(message);
7
+ this.name = 'ZodGeneratorError';
8
+ this.grammarElement = options?.grammarElement;
9
+ this.typeName = options?.typeName;
10
+ this.suggestion = options?.suggestion;
11
+ if (options?.cause !== undefined) {
12
+ this.cause = options.cause;
13
+ }
14
+ }
15
+ }
16
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAClC,cAAc,CAAU;IACxB,QAAQ,CAAU;IAClB,UAAU,CAAU;IAE7B,YAAY,OAAe,EAAE,OAAkC;QAC9D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,cAAc,GAAG,OAAO,EAAE,cAAc,CAAC;QAC9C,IAAI,CAAC,QAAQ,GAAG,OAAO,EAAE,QAAQ,CAAC;QAClC,IAAI,CAAC,UAAU,GAAG,OAAO,EAAE,UAAU,CAAC;QAEtC,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACjC,IAAoC,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC7D,CAAC;IACF,CAAC;CACD"}
@@ -0,0 +1,4 @@
1
+ import type { AstTypesLike, ZodTypeDescriptor } from './types.js';
2
+ import type { FilterConfig } from './config.js';
3
+ export declare function extractTypeDescriptors(astTypes: AstTypesLike, config?: FilterConfig): ZodTypeDescriptor[];
4
+ //# sourceMappingURL=extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../src/extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,YAAY,EAKZ,iBAAiB,EACjB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAyFhD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,iBAAiB,EAAE,CAqEzG"}
@@ -0,0 +1,130 @@
1
+ import { ZodGeneratorError } from './errors.js';
2
+ import { mapPropertyType } from './type-mapper.js';
3
+ function toStringSet(value) {
4
+ if (!value) {
5
+ return new Set();
6
+ }
7
+ if (value instanceof Set) {
8
+ return new Set(Array.from(value).filter((entry) => typeof entry === 'string'));
9
+ }
10
+ if (Array.isArray(value)) {
11
+ return new Set(value.filter((entry) => typeof entry === 'string'));
12
+ }
13
+ return new Set();
14
+ }
15
+ function shouldInclude(name, config) {
16
+ const include = config?.include ?? [];
17
+ const exclude = config?.exclude ?? [];
18
+ if (include.length > 0) {
19
+ return include.includes(name);
20
+ }
21
+ if (exclude.length > 0) {
22
+ return !exclude.includes(name);
23
+ }
24
+ return true;
25
+ }
26
+ function resolveProperties(typeMap, typeName, visiting = new Set()) {
27
+ if (visiting.has(typeName)) {
28
+ return [];
29
+ }
30
+ visiting.add(typeName);
31
+ const current = typeMap.get(typeName);
32
+ if (!current) {
33
+ return [];
34
+ }
35
+ const merged = new Map();
36
+ for (const superType of toStringSet(current.superTypes)) {
37
+ for (const inherited of resolveProperties(typeMap, superType, visiting)) {
38
+ merged.set(inherited.name, inherited);
39
+ }
40
+ }
41
+ for (const property of current.properties ?? []) {
42
+ merged.set(property.name, property);
43
+ }
44
+ visiting.delete(typeName);
45
+ return Array.from(merged.values());
46
+ }
47
+ function extractUnionMembers(unionType) {
48
+ if (Array.isArray(unionType.members)) {
49
+ return unionType.members.filter((member) => typeof member === 'string');
50
+ }
51
+ const source = unionType.type;
52
+ const alternatives = source?.types ?? source?.alternatives ?? [];
53
+ if (!Array.isArray(alternatives)) {
54
+ return [];
55
+ }
56
+ const members = [];
57
+ for (const item of alternatives) {
58
+ if (typeof item === 'string') {
59
+ members.push(item);
60
+ continue;
61
+ }
62
+ if (item && typeof item === 'object') {
63
+ const maybeName = item.name ?? item.type;
64
+ if (typeof maybeName === 'string') {
65
+ members.push(maybeName);
66
+ }
67
+ }
68
+ }
69
+ return members;
70
+ }
71
+ export function extractTypeDescriptors(astTypes, config) {
72
+ const interfaces = astTypes.interfaces ?? [];
73
+ const unions = astTypes.unions ?? [];
74
+ const typeMap = new Map(interfaces.map((type) => [type.name, type]));
75
+ const objectDescriptors = [];
76
+ for (const entry of interfaces) {
77
+ if (!shouldInclude(entry.name, config)) {
78
+ continue;
79
+ }
80
+ const properties = [
81
+ {
82
+ name: '$type',
83
+ zodType: { kind: 'literal', value: entry.name },
84
+ optional: false
85
+ }
86
+ ];
87
+ for (const property of resolveProperties(typeMap, entry.name)) {
88
+ if (property.name.startsWith('$') && property.name !== '$type') {
89
+ continue;
90
+ }
91
+ const zodType = mapPropertyType(property);
92
+ if (zodType.kind === 'reference' && zodType.typeName === 'unknown') {
93
+ throw new ZodGeneratorError('Failed to map property type to Zod schema', {
94
+ typeName: entry.name,
95
+ grammarElement: property.name,
96
+ suggestion: 'Use a resolvable terminal or AST type reference in grammar assignments'
97
+ });
98
+ }
99
+ properties.push({
100
+ name: property.name,
101
+ zodType,
102
+ optional: Boolean(property.optional)
103
+ });
104
+ }
105
+ objectDescriptors.push({
106
+ name: entry.name,
107
+ kind: 'object',
108
+ properties
109
+ });
110
+ }
111
+ const includedTypeNames = new Set(objectDescriptors.map((descriptor) => descriptor.name));
112
+ const unionDescriptors = [];
113
+ for (const entry of unions) {
114
+ if (!shouldInclude(entry.name, config)) {
115
+ continue;
116
+ }
117
+ const filteredMembers = extractUnionMembers(entry).filter((member) => includedTypeNames.has(member));
118
+ if (filteredMembers.length === 0) {
119
+ continue;
120
+ }
121
+ unionDescriptors.push({
122
+ name: entry.name,
123
+ kind: 'union',
124
+ members: filteredMembers,
125
+ discriminator: '$type'
126
+ });
127
+ }
128
+ return [...objectDescriptors, ...unionDescriptors];
129
+ }
130
+ //# sourceMappingURL=extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractor.js","sourceRoot":"","sources":["../src/extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ZodTypeDescriptor } from './types.js';
2
+ export declare function generateZodCode(descriptors: ZodTypeDescriptor[], recursiveTypes: Set<string>): string;
3
+ //# sourceMappingURL=generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAkD,iBAAiB,EAAqB,MAAM,YAAY,CAAC;AAkJvH,wBAAgB,eAAe,CAAC,WAAW,EAAE,iBAAiB,EAAE,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CA8DrG"}
@@ -0,0 +1,180 @@
1
+ import { build } from 'x-to-zod/builders';
2
+ function expressionToBuilder(expression) {
3
+ switch (expression.kind) {
4
+ case 'primitive':
5
+ if (expression.primitive === 'string') {
6
+ return build.string();
7
+ }
8
+ if (expression.primitive === 'number') {
9
+ return build.number();
10
+ }
11
+ return build.boolean();
12
+ case 'literal':
13
+ return build.literal(expression.value);
14
+ case 'reference':
15
+ return build.raw(`${expression.typeName}Schema`);
16
+ case 'array':
17
+ return build.array(expressionToBuilder(expression.element));
18
+ case 'crossReference':
19
+ return build.raw('ReferenceSchema');
20
+ case 'union':
21
+ return build.union(expression.members.map((member) => expressionToBuilder(member)));
22
+ case 'lazy':
23
+ return build.lazy(expressionToBuilder(expression.inner));
24
+ }
25
+ }
26
+ function containsCrossReference(expression) {
27
+ switch (expression.kind) {
28
+ case 'crossReference':
29
+ return true;
30
+ case 'array':
31
+ return containsCrossReference(expression.element);
32
+ case 'union':
33
+ return expression.members.some((member) => containsCrossReference(member));
34
+ case 'lazy':
35
+ return containsCrossReference(expression.inner);
36
+ default:
37
+ return false;
38
+ }
39
+ }
40
+ function containsReferenceTo(expression, typeName) {
41
+ switch (expression.kind) {
42
+ case 'reference':
43
+ return expression.typeName === typeName;
44
+ case 'array':
45
+ return containsReferenceTo(expression.element, typeName);
46
+ case 'union':
47
+ return expression.members.some((member) => containsReferenceTo(member, typeName));
48
+ case 'lazy':
49
+ return containsReferenceTo(expression.inner, typeName);
50
+ default:
51
+ return false;
52
+ }
53
+ }
54
+ function propertyReferencesAnyCycleMember(zodType, recursiveTypes) {
55
+ for (const rt of recursiveTypes) {
56
+ if (containsReferenceTo(zodType, rt)) {
57
+ return true;
58
+ }
59
+ }
60
+ return false;
61
+ }
62
+ function propertyLine(property, ownerTypeName, recursiveTypes) {
63
+ const builder = expressionToBuilder(property.zodType);
64
+ if (property.optional) {
65
+ builder.optional();
66
+ }
67
+ const withOptional = builder.text();
68
+ const shouldUseGetter = recursiveTypes.has(ownerTypeName) && propertyReferencesAnyCycleMember(property.zodType, recursiveTypes);
69
+ if (shouldUseGetter) {
70
+ return `\tget ${property.name}() { return ${withOptional}; }`;
71
+ }
72
+ return `\t${property.name}: ${withOptional}`;
73
+ }
74
+ /**
75
+ * Topologically sorts object descriptors so that each type's dependencies are
76
+ * emitted before it. References within a cycle (recursiveTypes) are safe
77
+ * regardless of order because they are emitted using getter syntax.
78
+ */
79
+ function topoSortObjectDescriptors(descriptors, recursiveTypes) {
80
+ const nameToDesc = new Map(descriptors.map((d) => [d.name, d]));
81
+ const sorted = [];
82
+ const visited = new Set();
83
+ const visiting = new Set();
84
+ function visit(name) {
85
+ if (visited.has(name)) {
86
+ return;
87
+ }
88
+ visiting.add(name);
89
+ const d = nameToDesc.get(name);
90
+ if (d) {
91
+ for (const property of d.properties) {
92
+ for (const ref of collectReferenceTypeNames(property.zodType)) {
93
+ if (nameToDesc.has(ref) && !visiting.has(ref)) {
94
+ const shouldUseGetter = recursiveTypes.has(name) &&
95
+ propertyReferencesAnyCycleMember(property.zodType, recursiveTypes);
96
+ if (!shouldUseGetter) {
97
+ visit(ref);
98
+ }
99
+ }
100
+ }
101
+ }
102
+ }
103
+ visiting.delete(name);
104
+ visited.add(name);
105
+ if (d) {
106
+ sorted.push(d);
107
+ }
108
+ }
109
+ for (const d of descriptors) {
110
+ visit(d.name);
111
+ }
112
+ return sorted;
113
+ }
114
+ function collectReferenceTypeNames(expression) {
115
+ switch (expression.kind) {
116
+ case 'reference':
117
+ return [expression.typeName];
118
+ case 'array':
119
+ return collectReferenceTypeNames(expression.element);
120
+ case 'union':
121
+ return expression.members.flatMap((m) => collectReferenceTypeNames(m));
122
+ case 'lazy':
123
+ return collectReferenceTypeNames(expression.inner);
124
+ default:
125
+ return [];
126
+ }
127
+ }
128
+ export function generateZodCode(descriptors, recursiveTypes) {
129
+ const lines = [
130
+ "import { z } from 'zod';",
131
+ ''
132
+ ];
133
+ const hasCrossReferences = descriptors.some((descriptor) => descriptor.kind === 'object' && descriptor.properties.some((property) => containsCrossReference(property.zodType)));
134
+ if (hasCrossReferences) {
135
+ const referenceBuilder = build
136
+ .object({
137
+ $refText: build.string(),
138
+ ref: build.unknown().optional()
139
+ })
140
+ .loose();
141
+ lines.push(`export const ReferenceSchema = ${referenceBuilder.text()};`);
142
+ lines.push('');
143
+ }
144
+ const objectDescriptors = descriptors.filter((d) => d.kind === 'object');
145
+ const sortedObjects = topoSortObjectDescriptors(objectDescriptors, recursiveTypes);
146
+ for (const descriptor of sortedObjects) {
147
+ const hasRecursiveGetter = recursiveTypes.has(descriptor.name) && descriptor.properties.some((property) => propertyReferencesAnyCycleMember(property.zodType, recursiveTypes));
148
+ if (hasRecursiveGetter) {
149
+ lines.push(`export const ${descriptor.name}Schema = z.looseObject({`);
150
+ for (const property of descriptor.properties) {
151
+ lines.push(`${propertyLine(property, descriptor.name, recursiveTypes)},`);
152
+ }
153
+ lines.push('});');
154
+ lines.push('');
155
+ continue;
156
+ }
157
+ const objectProperties = {};
158
+ for (const property of descriptor.properties) {
159
+ const builder = expressionToBuilder(property.zodType);
160
+ if (property.optional) {
161
+ builder.optional();
162
+ }
163
+ objectProperties[property.name] = builder;
164
+ }
165
+ const objectBuilder = build.object(objectProperties).loose();
166
+ lines.push(`export const ${descriptor.name}Schema = ${objectBuilder.text()};`);
167
+ lines.push('');
168
+ }
169
+ for (const descriptor of descriptors) {
170
+ if (descriptor.kind !== 'union') {
171
+ continue;
172
+ }
173
+ const members = descriptor.members.map((member) => build.raw(`${member}Schema`));
174
+ const unionBuilder = build.discriminatedUnion(descriptor.discriminator, members);
175
+ lines.push(`export const ${descriptor.name}Schema = ${unionBuilder.text()};`);
176
+ lines.push('');
177
+ }
178
+ return `${lines.join('\n').trim()}\n`;
179
+ }
180
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export { generateZodSchemas } from './api.js';
2
+ export { DEFAULT_OUTPUT_PATH } from './config.js';
3
+ export type { FilterConfig, ZodGeneratorConfig } from './config.js';
4
+ export { ZodGeneratorError } from './errors.js';
5
+ export { extractTypeDescriptors } from './extractor.js';
6
+ export { generateZodCode } from './generator.js';
7
+ export { detectRecursiveTypes } from './recursion-detector.js';
8
+ export type { AstTypesLike, InterfaceTypeLike, PropertyLike, UnionTypeLike, ZodPropertyDescriptor, ZodTypeDescriptor, ZodTypeExpression } from './types.js';
9
+ export { DefaultZodSchemaGenerator, ZodSchemaGeneratorModule } from './di.js';
10
+ export type { ZodSchemaGenerator, ZodSchemaGeneratorServices } from './di.js';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACpE,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,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,YAAY,EACX,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAC9E,YAAY,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export { generateZodSchemas } from './api.js';
2
+ export { DEFAULT_OUTPUT_PATH } from './config.js';
3
+ export { ZodGeneratorError } from './errors.js';
4
+ export { extractTypeDescriptors } from './extractor.js';
5
+ export { generateZodCode } from './generator.js';
6
+ export { detectRecursiveTypes } from './recursion-detector.js';
7
+ export { DefaultZodSchemaGenerator, ZodSchemaGeneratorModule } from './di.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,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,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAU/D,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ZodTypeDescriptor } from './types.js';
2
+ export declare function detectRecursiveTypes(descriptors: ZodTypeDescriptor[]): Set<string>;
3
+ //# sourceMappingURL=recursion-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recursion-detector.d.ts","sourceRoot":"","sources":["../src/recursion-detector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyB,iBAAiB,EAAqB,MAAM,YAAY,CAAC;AAqB9F,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,iBAAiB,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAmDlF"}
@@ -0,0 +1,62 @@
1
+ function collectReferenceTypeNames(expression) {
2
+ switch (expression.kind) {
3
+ case 'reference':
4
+ return [expression.typeName];
5
+ case 'array':
6
+ return collectReferenceTypeNames(expression.element);
7
+ case 'union':
8
+ return expression.members.flatMap((member) => collectReferenceTypeNames(member));
9
+ case 'lazy':
10
+ return collectReferenceTypeNames(expression.inner);
11
+ default:
12
+ return [];
13
+ }
14
+ }
15
+ function propertyReferences(property) {
16
+ return collectReferenceTypeNames(property.zodType);
17
+ }
18
+ export function detectRecursiveTypes(descriptors) {
19
+ const edges = new Map();
20
+ for (const descriptor of descriptors) {
21
+ if (descriptor.kind !== 'object') {
22
+ continue;
23
+ }
24
+ const refs = new Set();
25
+ for (const property of descriptor.properties) {
26
+ for (const typeName of propertyReferences(property)) {
27
+ refs.add(typeName);
28
+ }
29
+ }
30
+ edges.set(descriptor.name, refs);
31
+ }
32
+ const recursive = new Set();
33
+ const visited = new Set();
34
+ const visiting = new Set();
35
+ const dfs = (node, path) => {
36
+ if (visiting.has(node)) {
37
+ const cycleStart = path.indexOf(node);
38
+ const cycle = cycleStart >= 0 ? path.slice(cycleStart) : [node];
39
+ for (const item of cycle) {
40
+ recursive.add(item);
41
+ }
42
+ return;
43
+ }
44
+ if (visited.has(node)) {
45
+ return;
46
+ }
47
+ visited.add(node);
48
+ visiting.add(node);
49
+ for (const next of edges.get(node) ?? []) {
50
+ if (!edges.has(next)) {
51
+ continue;
52
+ }
53
+ dfs(next, [...path, node]);
54
+ }
55
+ visiting.delete(node);
56
+ };
57
+ for (const node of edges.keys()) {
58
+ dfs(node, []);
59
+ }
60
+ return recursive;
61
+ }
62
+ //# sourceMappingURL=recursion-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recursion-detector.js","sourceRoot":"","sources":["../src/recursion-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { PropertyLike, ZodTypeExpression } from './types.js';
2
+ export declare function mapTerminalToZod(terminalName: string): ZodTypeExpression | undefined;
3
+ export declare function mapPropertyType(property: PropertyLike): ZodTypeExpression;
4
+ //# sourceMappingURL=type-mapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-mapper.d.ts","sourceRoot":"","sources":["../src/type-mapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAElE,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAcpF;AAwDD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,iBAAiB,CAsCzE"}
@@ -0,0 +1,90 @@
1
+ export function mapTerminalToZod(terminalName) {
2
+ if (terminalName === 'ID' || terminalName === 'STRING' || terminalName === 'string') {
3
+ return { kind: 'primitive', primitive: 'string' };
4
+ }
5
+ if (terminalName === 'INT' || terminalName === 'number') {
6
+ return { kind: 'primitive', primitive: 'number' };
7
+ }
8
+ if (terminalName === 'boolean') {
9
+ return { kind: 'primitive', primitive: 'boolean' };
10
+ }
11
+ return undefined;
12
+ }
13
+ function normalizePropertyType(propertyType) {
14
+ if (typeof propertyType === 'string') {
15
+ return {
16
+ typeName: propertyType,
17
+ isArray: false,
18
+ isCrossRef: false
19
+ };
20
+ }
21
+ if (!propertyType || typeof propertyType !== 'object') {
22
+ return { isArray: false, isCrossRef: false };
23
+ }
24
+ const candidate = propertyType;
25
+ if (candidate.elementType) {
26
+ const nested = normalizePropertyType(candidate.elementType);
27
+ return {
28
+ typeName: nested.typeName,
29
+ isArray: true,
30
+ isCrossRef: nested.isCrossRef
31
+ };
32
+ }
33
+ if (candidate.type) {
34
+ const nested = normalizePropertyType(candidate.type);
35
+ return {
36
+ typeName: nested.typeName,
37
+ isArray: false,
38
+ isCrossRef: nested.isCrossRef
39
+ };
40
+ }
41
+ const typeName = typeof candidate.referenceType === 'string'
42
+ ? candidate.referenceType
43
+ : typeof candidate.name === 'string'
44
+ ? candidate.name
45
+ : undefined;
46
+ return {
47
+ typeName,
48
+ isArray: false,
49
+ isCrossRef: Boolean(candidate.isCrossRef || candidate.crossRef)
50
+ };
51
+ }
52
+ export function mapPropertyType(property) {
53
+ const assignmentOperator = property.assignment ?? property.operator ?? '=';
54
+ if (assignmentOperator === '?=') {
55
+ return { kind: 'primitive', primitive: 'boolean' };
56
+ }
57
+ const normalized = normalizePropertyType(property.type);
58
+ const sourceTypeName = property.referenceType ?? normalized.typeName ?? '';
59
+ const primitive = mapTerminalToZod(sourceTypeName);
60
+ let base;
61
+ if (property.isCrossRef || normalized.isCrossRef) {
62
+ base = {
63
+ kind: 'crossReference',
64
+ targetType: sourceTypeName || 'unknown'
65
+ };
66
+ }
67
+ else if (primitive) {
68
+ base = primitive;
69
+ }
70
+ else if (sourceTypeName) {
71
+ base = {
72
+ kind: 'reference',
73
+ typeName: sourceTypeName
74
+ };
75
+ }
76
+ else {
77
+ base = {
78
+ kind: 'reference',
79
+ typeName: 'unknown'
80
+ };
81
+ }
82
+ if (assignmentOperator === '+=' || normalized.isArray) {
83
+ return {
84
+ kind: 'array',
85
+ element: base
86
+ };
87
+ }
88
+ return base;
89
+ }
90
+ //# sourceMappingURL=type-mapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-mapper.js","sourceRoot":"","sources":["../src/type-mapper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ export type ZodPrimitive = 'string' | 'number' | 'boolean';
2
+ export type ZodTypeExpression = {
3
+ kind: 'primitive';
4
+ primitive: ZodPrimitive;
5
+ } | {
6
+ kind: 'literal';
7
+ value: string;
8
+ } | {
9
+ kind: 'reference';
10
+ typeName: string;
11
+ } | {
12
+ kind: 'array';
13
+ element: ZodTypeExpression;
14
+ } | {
15
+ kind: 'crossReference';
16
+ targetType: string;
17
+ } | {
18
+ kind: 'union';
19
+ members: ZodTypeExpression[];
20
+ } | {
21
+ kind: 'lazy';
22
+ inner: ZodTypeExpression;
23
+ };
24
+ export interface ZodPropertyDescriptor {
25
+ name: string;
26
+ zodType: ZodTypeExpression;
27
+ optional: boolean;
28
+ }
29
+ export interface ZodObjectTypeDescriptor {
30
+ name: string;
31
+ kind: 'object';
32
+ properties: ZodPropertyDescriptor[];
33
+ }
34
+ export interface ZodUnionTypeDescriptor {
35
+ name: string;
36
+ kind: 'union';
37
+ members: string[];
38
+ discriminator: string;
39
+ }
40
+ export type ZodTypeDescriptor = ZodObjectTypeDescriptor | ZodUnionTypeDescriptor;
41
+ export interface InterfaceTypeLike {
42
+ name: string;
43
+ properties?: PropertyLike[];
44
+ superTypes?: Set<string> | string[];
45
+ }
46
+ export interface UnionTypeLike {
47
+ name: string;
48
+ type?: unknown;
49
+ members?: string[];
50
+ }
51
+ export interface PropertyLike {
52
+ name: string;
53
+ type?: unknown;
54
+ optional?: boolean;
55
+ operator?: '=' | '+=' | '?=';
56
+ assignment?: '=' | '+=' | '?=';
57
+ isCrossRef?: boolean;
58
+ referenceType?: string;
59
+ }
60
+ export interface AstTypesLike {
61
+ interfaces: InterfaceTypeLike[];
62
+ unions: UnionTypeLike[];
63
+ }
64
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE3D,MAAM,MAAM,iBAAiB,GAC1B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,YAAY,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,iBAAiB,EAAE,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAE9C,MAAM,WAAW,qBAAqB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,iBAAiB,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,qBAAqB,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,iBAAiB,GAAG,uBAAuB,GAAG,sBAAsB,CAAC;AAEjF,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;IAC7B,UAAU,CAAC,EAAE,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC5B,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,MAAM,EAAE,aAAa,EAAE,CAAC;CACxB"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "langium-zod",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Langium generator plugin that derives Zod schemas from grammar definitions",
6
+ "keywords": [
7
+ "langium",
8
+ "zod",
9
+ "codegen",
10
+ "typescript",
11
+ "ast"
12
+ ],
13
+ "homepage": "https://github.com/pradeepmouli/langium-zod#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/pradeepmouli/langium-zod/issues"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/pradeepmouli/langium-zod.git",
20
+ "directory": "packages/langium-zod"
21
+ },
22
+ "license": "MIT",
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "main": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "import": "./dist/index.js"
32
+ }
33
+ },
34
+ "files": [
35
+ "dist"
36
+ ],
37
+ "dependencies": {
38
+ "langium": "^4.2.1",
39
+ "x-to-zod": "^0.7.0",
40
+ "zod": "^4.3.6"
41
+ },
42
+ "devDependencies": {
43
+ "langium-cli": "^4.2.0",
44
+ "typescript": "^5.9.3",
45
+ "vitest": "^4.0.18"
46
+ },
47
+ "scripts": {
48
+ "build": "tsc -p tsconfig.json",
49
+ "clean": "rm -rf dist tsconfig.tsbuildinfo",
50
+ "test": "vitest run",
51
+ "type-check": "tsc -p tsconfig.json --noEmit"
52
+ }
53
+ }