zod-to-x 1.0.3 → 1.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/README.md CHANGED
@@ -10,7 +10,6 @@
10
10
  - [Supported output languages](#supported-output-languages)
11
11
  - [Mapping of supported Zod Types](#mapping-of-supported-zod-types)
12
12
  - [Additional utils](#additional-utils)
13
- - [Known limitations](#known-limitations)
14
13
 
15
14
 
16
15
 
@@ -140,6 +139,7 @@ A complete and more complex schema definition with its outputs can be found in t
140
139
  - [Zod Schemas](test/data)
141
140
  - [Typescript outputs](test/test_zod2ts)
142
141
  - [Protobuf V3 outputs](test/test_zod2proto3/)
142
+ - [C++ 11 outputs](test/test_zod2cpp/)
143
143
 
144
144
 
145
145
 
@@ -148,44 +148,61 @@ Common options:
148
148
  - **header**: Text to add as a comment at the beginning of the output.
149
149
  - **indent**: Number of spaces to use for indentation in the generated code. Defaults to 4 if not specified.
150
150
  - **includeComments**: Determines whether to include comments in the transpiled code. Defaults to `true`.
151
+ - **skipDiscriminatorNodes**: prevents the inclusion of `ZodEnum` or `ZodNativeEnum` schemas that are used solely as discriminator keys in a `ZodDiscriminatedUnion`. Defaults to `false`.
151
152
 
152
- ### · **Typescript**
153
- Options:
154
- - **outType**: Output transpilation using Typescript interfaces or Classes.
153
+ ### Typescript
154
+ #### Options:
155
+ - **outType**: Output transpilation using Typescript interfaces or Classes. Defaults to `interface`.
155
156
 
156
- ### · Protobuf V3
157
- Options:
157
+ ### Protobuf V3
158
+ #### Options:
158
159
  - **packageName**: Name of the protobuf file package.
159
160
  - **useCamelCase**: Protobuf follows the snake_case convention for field names, but camelCase can also be used. Defaults to `false`.
160
161
 
161
- ### · C++ (upcoming)
162
+ #### Limitations:
163
+ - `oneof` fields support only unions of `ZodObject` schemas.
162
164
 
163
165
 
166
+ ### C++
167
+ - `Nlohmann` dependency is used for data serialization/deserialization.
168
+ - For *C++11*, `Boost` dependency is used. For *C++17* or newer, standard libraries are used.
169
+ #### Options:
170
+ - **includeNulls**: When serializing, include all values even if `null`. Defaults to `false`.
171
+ - **namespace**: Name of the namespace containing the output code.
172
+ - **outType**: Output transpilation using C++ Structs or Classes. Defaults to `struct`.
173
+ - **skipSerialize**: Remove Nlohmann JSON serialization/deserialization. Defaults to `false`.
174
+
175
+ #### Limitations:
176
+ - `ZodIntersection` is supported only for intersection of `ZodObject` schemas.
164
177
 
165
- ## Mapping of supported Zod Types
166
178
 
167
- | Zod Type | TypeScript | Protobuf |
168
- |-------------------|-----------------------------|-----------------------------------------------|
169
- | `z.string()` | `string` | `string` |
170
- | `z.number()` | `number` | `double`, `uint32`, `uint64`, `ìnt32`, `int64`|
171
- | `z.bigint()` | `number` | `int64`, `uint64` |
172
- | `z.boolean()` | `boolean` | `bool` |
173
- | `z.date()` | `Date` | `google.protobuf.Timestamp` |
174
- | `z.literal()` | Literal value (`'value'`) | `number` or `string` |
175
- | `z.enum()` | `enum` | `enum` |
176
- | `z.nativeEnum()` | Native `enum` | `enum` |
177
- | `z.array()` | `T[]` | `repeated` field |
178
- | `z.set()` | `Set<T>` | `repeated` field |
179
- | `z.tuple()` | `[T1, T2, T3]` | Not supported |
180
- | `z.object()` | `interface` or `class` | `message` |
181
- | `z.record()` | `Record<string, T>` | `map<string, K>` |
182
- | `z.union()` | `T1 \| T2` or `type` | `oneof` |
183
- | `z.intersection()`| `T1 & T2` or `type` | Not supported |
184
- | `z.any()` | `any` | `google.protobuf.Any` |
185
- | `z.optional()` | `T \| undefined` | Not supported |
186
- | `z.nullable()` | `T \| null` | Not supported |
187
179
 
180
+ ## Mapping of supported Zod Types
188
181
 
182
+ | Zod Type | TypeScript | Protobuf | C++ |
183
+ |-----------------------|-----------------------------|-----------------------------------------------|-----------------------------------------------|
184
+ | `z.string()` | `string` | `string` | `std::string`
185
+ | `z.number()` | `number` | `double`, `uint32`, `uint64`, `ìnt32`, `int64`| `double`, `uint32_t`, `uint64_t`, `ìnt32_t`, `int64_t`
186
+ | `z.bigint()` | `number` | `int64`, `uint64` | `int64_t`, `uint64_t`
187
+ | `z.boolean()` | `boolean` | `bool` | `bool`
188
+ | `z.date()` | `Date` | `google.protobuf.Timestamp` | Not supported
189
+ | `z.literal()` | Literal value (`'value'`) | As number or string | As string
190
+ | `z.enum()` | `enum` | `enum` | `enum class T: int`
191
+ | `z.nativeEnum()` | Native `enum` | `enum` | `enum class T: int`
192
+ | `z.array()` | `T[]` | `repeated` field | `std::vector<T>`
193
+ | `z.set()` | `Set<T>` | `repeated` field | `std::set<T>`
194
+ | `z.tuple()` | `[T1, T2, T3]` | `repeated` field <sup>(1)</sup> | `std::tuple<T1, T2, T3>`
195
+ | `z.object()` | `interface` or `class` | `message` | `struct` or `class`
196
+ | `z.record()` | `Record<string, T>` | `map<string, K>` | `std::unordered_map<T>`
197
+ | `z.map()` | `Map<string, T>` | `map<string, K>` | `std::unordered_map<T>`
198
+ | `z.union()` | `T1 \| T2` or `type` | `oneof` | `std::variant<T, K>` (`boost::variant<T, K>` for C++11)
199
+ | `z.intersection()` <sup>(2)</sup>| `T1 & T2` or `type` | Not supported | `struct` or `class` with `inheritance`
200
+ | `z.any()` | `any` | `google.protobuf.Any` | `nlohmann::json`
201
+ | `z.optional()` | `T \| undefined` | Not supported | `std::optional<T>` (`boost::optional<T>` for C++11)
202
+ | `z.nullable()` | `T \| null` | Not supported | `std::optional<T>` (`boost::optional<T>` for C++11)
203
+
204
+ <sup>(1)</sup> Only for tuple with items of the same type.
205
+ <sup>(2)</sup> Consider to use Zod's merge instead of ZodIntersection when possible.
189
206
 
190
207
  ## Additional utils
191
208
  - `zod2JsonSchemaDefinitions`
@@ -325,10 +342,4 @@ console.log(userJsonSchema);
325
342
  // },
326
343
  // "$schema": "http://json-schema.org/draft-07/schema#"
327
344
  // }
328
- ```
329
-
330
-
331
-
332
- ## Known limitations
333
- - Protobuf V3:
334
- - `oneof` fields support only unions of `ZodObject` schemas.
345
+ ```
@@ -1,5 +1,5 @@
1
- import { ZodObject, ZodRawShape, ZodTypeAny } from 'zod';
2
- import { ASTNode, ASTNodes } from './ast_types';
1
+ import { ZodObject, ZodRawShape } from "zod";
2
+ import { ASTNodes } from "./ast_types";
3
3
  export declare class Zod2Ast {
4
4
  private nodes;
5
5
  private discriminatorNodes;
@@ -7,8 +7,6 @@ export declare class Zod2Ast {
7
7
  constructor();
8
8
  private _createDefinition;
9
9
  private _getEnumValues;
10
- zodToAST(schema: ZodTypeAny, state?: {
11
- isUnionDiscriminator?: boolean;
12
- }): ASTNode;
10
+ private zodToAST;
13
11
  build<T extends ZodRawShape>(schema: ZodObject<T>): ASTNodes;
14
12
  }
@@ -8,13 +8,12 @@ class Zod2Ast {
8
8
  this.discriminatorNodes = new Map();
9
9
  this.lazyPointers = [];
10
10
  }
11
- _createDefinition(ref) {
12
- return { type: "definition", reference: ref };
11
+ _createDefinition(ref, refType, discriminantValue) {
12
+ return { type: "definition", reference: ref, referenceType: refType, discriminantValue };
13
13
  }
14
14
  _getEnumValues(schema) {
15
15
  if (schema instanceof zod_1.ZodEnum) {
16
- return Object.entries(schema.Enum)
17
- .map(([key, value]) => {
16
+ return Object.entries(schema.Enum).map(([key, value]) => {
18
17
  key = isNaN(Number(key.at(0))) ? key : `"${key}"`;
19
18
  return [key, value];
20
19
  });
@@ -28,44 +27,43 @@ class Zod2Ast {
28
27
  });
29
28
  }
30
29
  }
31
- zodToAST(schema, state) {
30
+ zodToAST(schema, opt) {
32
31
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
33
32
  const def = schema._def;
34
33
  if (schema instanceof zod_1.ZodString) {
35
34
  return {
36
35
  type: zod_1.ZodFirstPartyTypeKind.ZodString,
37
- description: schema.description
36
+ description: schema.description,
38
37
  };
39
38
  }
40
- else if (schema instanceof zod_1.ZodNumber ||
41
- schema instanceof zod_1.ZodBigInt) {
39
+ else if (schema instanceof zod_1.ZodNumber || schema instanceof zod_1.ZodBigInt) {
42
40
  return {
43
41
  type: zod_1.ZodFirstPartyTypeKind.ZodNumber,
44
42
  constraints: {
45
- min: (_a = def.checks.find((i) => i.kind === 'min')) === null || _a === void 0 ? void 0 : _a.value,
46
- max: (_b = def.checks.find((i) => i.kind === 'max')) === null || _b === void 0 ? void 0 : _b.value,
47
- isInt: (schema instanceof zod_1.ZodBigInt ||
48
- def.checks.find((i) => i.kind === 'int') != undefined)
43
+ min: (_a = def.checks.find((i) => i.kind === "min")) === null || _a === void 0 ? void 0 : _a.value,
44
+ max: (_b = def.checks.find((i) => i.kind === "max")) === null || _b === void 0 ? void 0 : _b.value,
45
+ isInt: schema instanceof zod_1.ZodBigInt ||
46
+ def.checks.find((i) => i.kind === "int") != undefined,
49
47
  },
50
- description: schema.description
48
+ description: schema.description,
51
49
  };
52
50
  }
53
51
  else if (schema instanceof zod_1.ZodBoolean) {
54
52
  return {
55
53
  type: zod_1.ZodFirstPartyTypeKind.ZodBoolean,
56
- description: schema.description
54
+ description: schema.description,
57
55
  };
58
56
  }
59
57
  else if (schema instanceof zod_1.ZodDate) {
60
58
  return {
61
59
  type: zod_1.ZodFirstPartyTypeKind.ZodDate,
62
- description: schema.description
60
+ description: schema.description,
63
61
  };
64
62
  }
65
63
  else if (schema instanceof zod_1.ZodAny) {
66
64
  return {
67
65
  type: zod_1.ZodFirstPartyTypeKind.ZodAny,
68
- description: schema.description
66
+ description: schema.description,
69
67
  };
70
68
  }
71
69
  else if (schema instanceof zod_1.ZodNullable) {
@@ -86,14 +84,14 @@ class Zod2Ast {
86
84
  return {
87
85
  type: zod_1.ZodFirstPartyTypeKind.ZodSet,
88
86
  value: this.zodToAST(def.valueType),
89
- description: schema.description
87
+ description: schema.description,
90
88
  };
91
89
  }
92
90
  else if (schema instanceof zod_1.ZodLiteral) {
93
91
  return {
94
92
  type: zod_1.ZodFirstPartyTypeKind.ZodLiteral,
95
93
  value: def.value,
96
- description: schema.description
94
+ description: schema.description,
97
95
  };
98
96
  }
99
97
  else if (schema instanceof zod_1.ZodRecord) {
@@ -101,12 +99,12 @@ class Zod2Ast {
101
99
  type: zod_1.ZodFirstPartyTypeKind.ZodRecord,
102
100
  key: this.zodToAST(def.keyType),
103
101
  value: this.zodToAST(def.valueType),
104
- description: schema.description
102
+ description: schema.description,
105
103
  };
106
104
  }
107
105
  else if (schema instanceof zod_1.ZodLazy) {
108
106
  const lazySchema = def.getter();
109
- const lazyPointer = this._createDefinition("pending");
107
+ const lazyPointer = this._createDefinition("pending", zod_1.ZodFirstPartyTypeKind.ZodAny);
110
108
  this.lazyPointers.push([lazyPointer, lazySchema]);
111
109
  return lazyPointer;
112
110
  }
@@ -114,7 +112,7 @@ class Zod2Ast {
114
112
  return {
115
113
  type: zod_1.ZodFirstPartyTypeKind.ZodTuple,
116
114
  items: def.items.map(this.zodToAST.bind(this)),
117
- description: schema.description
115
+ description: schema.description,
118
116
  };
119
117
  }
120
118
  else if (schema instanceof zod_1.ZodMap) {
@@ -122,11 +120,10 @@ class Zod2Ast {
122
120
  type: zod_1.ZodFirstPartyTypeKind.ZodMap,
123
121
  key: this.zodToAST(def.keyType),
124
122
  value: this.zodToAST(def.valueType),
125
- description: schema.description
123
+ description: schema.description,
126
124
  };
127
125
  }
128
- else if (schema instanceof zod_1.ZodNativeEnum ||
129
- schema instanceof zod_1.ZodEnum) {
126
+ else if (schema instanceof zod_1.ZodNativeEnum || schema instanceof zod_1.ZodEnum) {
130
127
  let name = (_c = def.zod2x) === null || _c === void 0 ? void 0 : _c.typeName;
131
128
  const item = {
132
129
  type: def.typeName,
@@ -134,9 +131,8 @@ class Zod2Ast {
134
131
  values: this._getEnumValues(schema),
135
132
  description: def.description,
136
133
  };
137
- if (state === null || state === void 0 ? void 0 : state.isUnionDiscriminator) {
138
- if (!this.nodes.has(name) &&
139
- !this.discriminatorNodes.has(name)) {
134
+ if (opt === null || opt === void 0 ? void 0 : opt.isUnionDiscriminator) {
135
+ if (!this.nodes.has(name) && !this.discriminatorNodes.has(name)) {
140
136
  this.discriminatorNodes.set(name, item);
141
137
  }
142
138
  }
@@ -148,41 +144,48 @@ class Zod2Ast {
148
144
  this.discriminatorNodes.delete(name);
149
145
  }
150
146
  }
151
- return this._createDefinition(name);
147
+ return this._createDefinition(name, def.typeName);
152
148
  }
153
149
  else if (schema instanceof zod_1.ZodObject) {
154
150
  let name = (_e = def.zod2x) === null || _e === void 0 ? void 0 : _e.typeName;
151
+ let discriminantValue = undefined;
155
152
  if (!this.nodes.has(name)) {
156
153
  const properties = {};
157
154
  for (const key in def.shape()) {
158
155
  properties[key] = this.zodToAST(def.shape()[key]);
156
+ if ((opt === null || opt === void 0 ? void 0 : opt.discriminantKey) && key === (opt === null || opt === void 0 ? void 0 : opt.discriminantKey)) {
157
+ if (properties[key].type === zod_1.ZodFirstPartyTypeKind.ZodLiteral) {
158
+ discriminantValue = String(properties[key].value);
159
+ }
160
+ else {
161
+ console.warn(`Consider to set '${key}' key of '${name}' as ZodLiteral`);
162
+ }
163
+ }
159
164
  }
160
165
  this.nodes.set(name, {
161
166
  type: zod_1.ZodFirstPartyTypeKind.ZodObject,
162
167
  name: (_f = def.zod2x) === null || _f === void 0 ? void 0 : _f.typeName,
163
168
  properties,
164
- description: schema.description
169
+ description: schema.description,
165
170
  });
166
171
  }
167
- ;
168
- return this._createDefinition(name);
172
+ return this._createDefinition(name, def.typeName, discriminantValue);
169
173
  }
170
- else if (schema instanceof zod_1.ZodUnion ||
171
- schema instanceof zod_1.ZodDiscriminatedUnion) {
174
+ else if (schema instanceof zod_1.ZodUnion || schema instanceof zod_1.ZodDiscriminatedUnion) {
172
175
  let name = (_g = def.zod2x) === null || _g === void 0 ? void 0 : _g.typeName;
173
176
  const item = {
174
177
  type: def.typeName,
175
178
  name: (_h = def.zod2x) === null || _h === void 0 ? void 0 : _h.typeName,
176
- options: def.options.map(this.zodToAST.bind(this)),
177
- description: schema.description
179
+ options: def.options.map((i) => this.zodToAST(i, { discriminantKey: def.discriminator })),
180
+ description: schema.description,
181
+ discriminantKey: def.discriminator,
178
182
  };
179
183
  if ((_j = def.zod2x) === null || _j === void 0 ? void 0 : _j.discriminatorEnum) {
180
184
  this.zodToAST((_k = def.zod2x) === null || _k === void 0 ? void 0 : _k.discriminatorEnum, { isUnionDiscriminator: true });
181
185
  }
182
- if (name &&
183
- !this.nodes.has(name)) {
186
+ if (name && !this.nodes.has(name)) {
184
187
  this.nodes.set(name, item);
185
- return this._createDefinition(name);
188
+ return this._createDefinition(name, def.typeName);
186
189
  }
187
190
  return item;
188
191
  }
@@ -193,12 +196,11 @@ class Zod2Ast {
193
196
  name: (_m = def.zod2x) === null || _m === void 0 ? void 0 : _m.typeName,
194
197
  left: this.zodToAST(def.left),
195
198
  right: this.zodToAST(def.right),
196
- description: schema.description
199
+ description: schema.description,
197
200
  };
198
- if (name &&
199
- !this.nodes.has(name)) {
201
+ if (name && !this.nodes.has(name)) {
200
202
  this.nodes.set(name, item);
201
- return this._createDefinition(name);
203
+ return this._createDefinition(name, def.typeName);
202
204
  }
203
205
  return item;
204
206
  }
@@ -210,7 +212,7 @@ class Zod2Ast {
210
212
  while (this.lazyPointers.length > 0) {
211
213
  const [pointer, schema] = this.lazyPointers.shift();
212
214
  const lazyResolve = this.zodToAST(schema);
213
- Object.keys(pointer).forEach(key => {
215
+ Object.keys(pointer).forEach((key) => {
214
216
  delete pointer[key];
215
217
  });
216
218
  Object.entries(lazyResolve).forEach(([key, value]) => {
@@ -219,7 +221,7 @@ class Zod2Ast {
219
221
  }
220
222
  return {
221
223
  nodes: [...this.nodes.values()],
222
- discriminatorNodes: [...this.discriminatorNodes.values()]
224
+ discriminatorNodes: [...this.discriminatorNodes.values()],
223
225
  };
224
226
  }
225
227
  }
@@ -53,6 +53,7 @@ export type ASTDiscriminatedUnion = {
53
53
  type: ZodFirstPartyTypeKind.ZodDiscriminatedUnion;
54
54
  name: string;
55
55
  options: ASTNode[];
56
+ discriminantKey?: string;
56
57
  };
57
58
  export type ASTIntersection = {
58
59
  type: ZodFirstPartyTypeKind.ZodIntersection;
@@ -66,10 +67,12 @@ export type ASTCommon = {
66
67
  isNullable?: boolean;
67
68
  isOptional?: boolean;
68
69
  };
69
- export type ASTDefintion = ASTCommon & ({
70
+ export type ASTDefintion = ASTCommon & {
70
71
  type: "definition";
71
72
  reference: string;
72
- });
73
+ referenceType: ZodFirstPartyTypeKind;
74
+ discriminantValue?: string;
75
+ };
73
76
  export type ASTNode = ASTCommon & ({
74
77
  type: ZodFirstPartyTypeKind.ZodString;
75
78
  } | {
@@ -1,4 +1,5 @@
1
- import { ASTCommon, ASTDiscriminatedUnion, ASTEnum, ASTIntersection, ASTNativeEnum, ASTNode, ASTNodes, ASTObject, ASTUnion, TranspilerableTypes } from './ast_types';
1
+ import { TIndentationLevels } from "../utils/string_utils";
2
+ import { ASTCommon, ASTDiscriminatedUnion, ASTEnum, ASTIntersection, ASTNativeEnum, ASTNode, ASTNodes, ASTObject, ASTUnion, TranspilerableTypes } from "./ast_types";
2
3
  export interface IZodToXOpt extends Record<string, any> {
3
4
  header?: string;
4
5
  indent?: number;
@@ -8,16 +9,16 @@ export interface IZodToXOpt extends Record<string, any> {
8
9
  interface IInternalOpts {
9
10
  enableCompositeTypes: boolean;
10
11
  }
11
- export declare abstract class Zod2X {
12
- protected output: string;
13
- protected indent: string;
12
+ export declare abstract class Zod2X<T extends IZodToXOpt> {
13
+ protected output: string[];
14
+ protected indent: TIndentationLevels;
14
15
  protected imports: Set<string>;
15
- protected opt: Partial<IZodToXOpt>;
16
+ protected opt: Partial<T>;
16
17
  private inOpt;
17
- protected constructor(inOpt: IInternalOpts, opt: Partial<IZodToXOpt>);
18
+ protected constructor(inOpt: IInternalOpts, opt: Partial<T>);
18
19
  protected abstract runBefore(): void;
19
20
  protected abstract runAfter(): void;
20
- protected abstract addComment(data?: string, indent?: string): void;
21
+ protected abstract getComment(data: string, indent?: string): string;
21
22
  protected abstract getStringType(): string;
22
23
  protected abstract getBooleanType(): string;
23
24
  protected abstract getNumberType(isInt: boolean, range: {
@@ -39,6 +40,11 @@ export declare abstract class Zod2X {
39
40
  protected abstract transpileUnion(data: (ASTUnion | ASTDiscriminatedUnion) & ASTCommon): void;
40
41
  protected abstract transpileIntersection(data: ASTIntersection & ASTCommon): void;
41
42
  protected isTranspilerable(token: TranspilerableTypes): boolean | "";
43
+ protected push0: (data: string) => number;
44
+ protected push1: (data: string) => number;
45
+ protected push2: (data: string) => number;
46
+ protected push3: (data: string) => number;
47
+ protected addComment(data?: string, indent?: string): void;
42
48
  private _checkCompositeFlag;
43
49
  protected getAttributeType(token: ASTNode | TranspilerableTypes): string;
44
50
  private _transpileItem;
@@ -1,26 +1,36 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.Zod2X = void 0;
4
7
  const zod_1 = require("zod");
8
+ const string_utils_1 = __importDefault(require("../utils/string_utils"));
5
9
  class Zod2X {
6
10
  constructor(inOpt, opt) {
7
- var _a;
8
- this.output = "";
11
+ this.push0 = (data) => this.output.push(`${this.indent[0]}${data}`);
12
+ this.push1 = (data) => this.output.push(`${this.indent[1]}${data}`);
13
+ this.push2 = (data) => this.output.push(`${this.indent[2]}${data}`);
14
+ this.push3 = (data) => this.output.push(`${this.indent[3]}${data}`);
15
+ this.output = [];
9
16
  this.imports = new Set();
10
- this.indent = " ".repeat((_a = opt === null || opt === void 0 ? void 0 : opt.indent) !== null && _a !== void 0 ? _a : 4);
17
+ this.indent = string_utils_1.default.getIndentationLevels(opt.indent || 4);
11
18
  this.opt = opt;
12
19
  this.inOpt = inOpt;
13
- if (opt === null || opt === void 0 ? void 0 : opt.header) {
14
- this.addComment(opt.header);
15
- }
16
20
  }
17
21
  isTranspilerable(token) {
18
22
  return (token.type === zod_1.ZodFirstPartyTypeKind.ZodEnum ||
19
23
  token.type === zod_1.ZodFirstPartyTypeKind.ZodNativeEnum ||
20
24
  token.type === zod_1.ZodFirstPartyTypeKind.ZodObject ||
21
- (token.name && (token.type === zod_1.ZodFirstPartyTypeKind.ZodUnion ||
22
- token.type === zod_1.ZodFirstPartyTypeKind.ZodDiscriminatedUnion ||
23
- token.type === zod_1.ZodFirstPartyTypeKind.ZodIntersection)));
25
+ (token.name &&
26
+ (token.type === zod_1.ZodFirstPartyTypeKind.ZodUnion ||
27
+ token.type === zod_1.ZodFirstPartyTypeKind.ZodDiscriminatedUnion ||
28
+ token.type === zod_1.ZodFirstPartyTypeKind.ZodIntersection)));
29
+ }
30
+ addComment(data = "", indent = "") {
31
+ if (data && this.opt.includeComments) {
32
+ this.output.push(this.getComment(data, indent));
33
+ }
24
34
  }
25
35
  _checkCompositeFlag() {
26
36
  if (!this.inOpt.enableCompositeTypes) {
@@ -55,7 +65,10 @@ class Zod2X {
55
65
  varType = this.getSetType(this.getAttributeType(token.value));
56
66
  }
57
67
  else if (token.type === zod_1.ZodFirstPartyTypeKind.ZodNumber) {
58
- varType = this.getNumberType(token.constraints.isInt, { min: token.constraints.min, max: token.constraints.max });
68
+ varType = this.getNumberType(token.constraints.isInt, {
69
+ min: token.constraints.min,
70
+ max: token.constraints.max,
71
+ });
59
72
  }
60
73
  else if (token.type === zod_1.ZodFirstPartyTypeKind.ZodTuple) {
61
74
  const tupleAttributeTypes = token.items.map(this.getAttributeType.bind(this));
@@ -77,8 +90,9 @@ class Zod2X {
77
90
  const items = [token.left, token.right].map(this.getAttributeType.bind(this));
78
91
  varType = this.getIntersectionType(items);
79
92
  }
80
- else if (!token.name && (token.type === zod_1.ZodFirstPartyTypeKind.ZodUnion ||
81
- token.type === zod_1.ZodFirstPartyTypeKind.ZodDiscriminatedUnion)) {
93
+ else if (!token.name &&
94
+ (token.type === zod_1.ZodFirstPartyTypeKind.ZodUnion ||
95
+ token.type === zod_1.ZodFirstPartyTypeKind.ZodDiscriminatedUnion)) {
82
96
  this._checkCompositeFlag();
83
97
  const items = token.options.map(this.getAttributeType.bind(this));
84
98
  varType = this.getUnionType(items);
@@ -108,16 +122,25 @@ class Zod2X {
108
122
  }
109
123
  }
110
124
  transpile(transpilerQueue) {
125
+ var _a;
111
126
  this.runBefore();
112
127
  if (this.opt.skipDiscriminatorNodes !== true) {
113
128
  transpilerQueue.discriminatorNodes.forEach(this._transpileItem.bind(this));
114
129
  }
115
130
  transpilerQueue.nodes.forEach(this._transpileItem.bind(this));
131
+ this.runAfter();
132
+ let header = [];
133
+ if (this.opt.header) {
134
+ header.push(...this.opt.header.split("\n").map((i) => this.getComment(i)));
135
+ }
116
136
  if (this.imports.size > 0) {
117
- this.output = [...this.imports.keys()].join('\n') + `\n\n${this.output}`;
137
+ header.push(...this.imports);
138
+ if (!((_a = header.at(-1)) === null || _a === void 0 ? void 0 : _a.endsWith("\n"))) {
139
+ header.push("");
140
+ }
118
141
  }
119
- this.runAfter();
120
- return this.output;
142
+ this.output = [...header, ...this.output];
143
+ return this.output.join("\n");
121
144
  }
122
145
  }
123
146
  exports.Zod2X = Zod2X;
package/dist/index.d.ts CHANGED
@@ -3,4 +3,4 @@ export * from "./core/ast_types";
3
3
  export { Zod2Ast } from "./core/ast_node";
4
4
  export { Zod2X } from "./core/transpiler";
5
5
  export * from "./transpilers";
6
- export { zod2JsonSchemaDefinitions } from './utils/json_schema_definitions';
6
+ export { zod2JsonSchemaDefinitions } from "./utils/json_schema_definitions";
@@ -1,9 +1,9 @@
1
- import { EnumLike, UnknownKeysParam, z, ZodEnum, ZodNativeEnum, ZodRawShape, ZodTypeAny, ZodUnionOptions } from 'zod';
1
+ import { EnumLike, UnknownKeysParam, z, ZodEnum, ZodNativeEnum, ZodRawShape, ZodTypeAny, ZodUnionOptions } from "zod";
2
2
  export interface Zod2xMetadata {
3
3
  typeName: string;
4
4
  discriminatorEnum?: ZodEnum<any> | ZodNativeEnum<any>;
5
5
  }
6
- declare module 'zod' {
6
+ declare module "zod" {
7
7
  interface ZodTypeDef {
8
8
  zod2x?: Zod2xMetadata;
9
9
  }
@@ -3,26 +3,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.extendZod = extendZod;
4
4
  function getZod2XConstructor() {
5
5
  return function (opt) {
6
- return new this.constructor(Object.assign(Object.assign({}, this._def), { zod2x: typeof opt === 'string' ? { typeName: opt } : opt }));
6
+ return new this.constructor(Object.assign(Object.assign({}, this._def), { zod2x: typeof opt === "string" ? { typeName: opt } : opt }));
7
7
  };
8
8
  }
9
9
  function extendZod(zod) {
10
- if (typeof zod.ZodObject.prototype.zod2x === 'undefined') {
10
+ if (typeof zod.ZodObject.prototype.zod2x === "undefined") {
11
11
  zod.ZodObject.prototype.zod2x = getZod2XConstructor();
12
12
  }
13
- if (typeof zod.ZodEnum.prototype.zod2x === 'undefined') {
13
+ if (typeof zod.ZodEnum.prototype.zod2x === "undefined") {
14
14
  zod.ZodEnum.prototype.zod2x = getZod2XConstructor();
15
15
  }
16
- if (typeof zod.ZodNativeEnum.prototype.zod2x === 'undefined') {
16
+ if (typeof zod.ZodNativeEnum.prototype.zod2x === "undefined") {
17
17
  zod.ZodNativeEnum.prototype.zod2x = getZod2XConstructor();
18
18
  }
19
- if (typeof zod.ZodDiscriminatedUnion.prototype.zod2x === 'undefined') {
19
+ if (typeof zod.ZodDiscriminatedUnion.prototype.zod2x === "undefined") {
20
20
  zod.ZodDiscriminatedUnion.prototype.zod2x = getZod2XConstructor();
21
21
  }
22
- if (typeof zod.ZodUnion.prototype.zod2x === 'undefined') {
22
+ if (typeof zod.ZodUnion.prototype.zod2x === "undefined") {
23
23
  zod.ZodUnion.prototype.zod2x = getZod2XConstructor();
24
24
  }
25
- if (typeof zod.ZodIntersection.prototype.zod2x === 'undefined') {
25
+ if (typeof zod.ZodIntersection.prototype.zod2x === "undefined") {
26
26
  zod.ZodIntersection.prototype.zod2x = getZod2XConstructor();
27
27
  }
28
28
  }
@@ -0,0 +1,15 @@
1
+ export declare function getLibs(useBoost: boolean): {
2
+ exceptions: string;
3
+ integers: string;
4
+ map: string;
5
+ nlohmann: string;
6
+ set: string;
7
+ string: string;
8
+ tuple: string;
9
+ vector: string;
10
+ optional: string;
11
+ variant: string;
12
+ };
13
+ export declare const USING: {
14
+ nlohmann: string;
15
+ };
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.USING = void 0;
4
+ exports.getLibs = getLibs;
5
+ function getLibs(useBoost) {
6
+ return {
7
+ exceptions: "#include <stdexcept>",
8
+ integers: "#include <cstdint>",
9
+ map: "#include <unordered_map>",
10
+ nlohmann: "#include <nlohmann/json.hpp>",
11
+ set: "#include <set>",
12
+ string: "#include <string>",
13
+ tuple: "#include <tuple>",
14
+ vector: "#include <vector>",
15
+ optional: useBoost ? "#include <boost/optional.hpp>" : "#include <optional>",
16
+ variant: useBoost ? "#include <boost/variant.hpp>" : "#include <variant>",
17
+ };
18
+ }
19
+ exports.USING = {
20
+ nlohmann: "using nlohmann::json;",
21
+ };
@@ -0,0 +1 @@
1
+ export declare function getNlohmannOptionalHelper(indent: number, useBoost?: boolean): string[];
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getNlohmannOptionalHelper = getNlohmannOptionalHelper;
4
+ function getNlohmannOptionalHelper(indent, useBoost) {
5
+ const optType = useBoost ? "boost::optional" : "std::optional";
6
+ return [
7
+ "#ifndef NLOHMANN_OPTIONAL_HELPER_zodtocpp",
8
+ "#define NLOHMANN_OPTIONAL_HELPER_zodtocpp",
9
+ "template <typename T>",
10
+ `${optType}<T> get_opt(const json& j, const std::string& key) {`,
11
+ `${" ".repeat(indent)}auto it = j.find(key);`,
12
+ `${" ".repeat(indent)}if (it != j.end() && !it->is_null()) {`,
13
+ `${" ".repeat(indent * 2)}return it->get<T>();`,
14
+ `${" ".repeat(indent)}}`,
15
+ `${" ".repeat(indent)}return ${optType}<T>();`,
16
+ `}\n`,
17
+ `template <typename T>`,
18
+ `void set_opt(json& j, const std::string& key, const ${optType}<T>& opt) {`,
19
+ `${" ".repeat(indent)}if (opt) {`,
20
+ `${" ".repeat(indent * 2)}j[key] = *opt;`,
21
+ `${" ".repeat(indent)}}`,
22
+ `}`,
23
+ `#endif\n`,
24
+ ];
25
+ }