zod-to-x 1.4.2 → 1.4.4
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 +65 -179
- package/dist/converters/index.d.ts +2 -0
- package/dist/converters/index.js +7 -0
- package/dist/converters/protobuf_v3/options.d.ts +13 -0
- package/dist/{transpilers → converters}/protobuf_v3/options.js +1 -1
- package/dist/converters/protobuf_v3/runner.d.ts +20 -0
- package/dist/{transpilers → converters}/protobuf_v3/runner.js +26 -10
- package/dist/core/ast_node.d.ts +7 -3
- package/dist/core/ast_node.js +41 -15
- package/dist/core/ast_types.d.ts +1 -6
- package/dist/core/transpiler.d.ts +9 -1
- package/dist/core/transpiler.js +23 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +20 -11
- package/dist/layered-modeling/model.d.ts +0 -1
- package/dist/transpilers/cpp/options.d.ts +5 -0
- package/dist/transpilers/cpp/options.js +1 -0
- package/dist/transpilers/cpp/runner.js +7 -7
- package/dist/transpilers/index.d.ts +0 -1
- package/dist/transpilers/index.js +4 -6
- package/dist/transpilers/typescript/options.d.ts +5 -0
- package/dist/transpilers/typescript/options.js +1 -0
- package/dist/transpilers/typescript/runner.js +8 -7
- package/dist/utils/string_utils.d.ts +8 -0
- package/dist/utils/string_utils.js +12 -0
- package/package.json +3 -2
- package/dist/transpilers/protobuf_v3/options.d.ts +0 -12
- package/dist/transpilers/protobuf_v3/runner.d.ts +0 -80
- /package/dist/{utils → converters}/json_schema_definitions.d.ts +0 -0
- /package/dist/{utils → converters}/json_schema_definitions.js +0 -0
package/README.md
CHANGED
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
- [Intersections and Unions](#intersections-and-unions)
|
|
28
28
|
- [Layered modeling](#layered-modeling) <sup>*(new)*</sup>
|
|
29
29
|
- [Supported output languages](#supported-output-languages)
|
|
30
|
-
- [Mapping of supported Zod Types](#mapping-of-supported-zod-types)
|
|
31
30
|
- [Additional utils](#additional-utils)
|
|
31
|
+
- [Mapping of supported Zod Types by Language](#mapping-of-supported-zod-types-by-langauge)
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
|
|
@@ -126,13 +126,6 @@ console.log(tsVisitorAsClass)
|
|
|
126
126
|
```
|
|
127
127
|
|
|
128
128
|
|
|
129
|
-
Example of supported schemas with its outputs can be found in the `test` folder:
|
|
130
|
-
- [Zod Schemas](test/common)
|
|
131
|
-
- [Typescript outputs](test/test_zod2ts)
|
|
132
|
-
- [Protobuf V3 outputs](test/test_zod2proto3/)
|
|
133
|
-
- [C++ outputs](test/test_zod2cpp/)
|
|
134
|
-
|
|
135
|
-
|
|
136
129
|
|
|
137
130
|
## Intersections and Unions
|
|
138
131
|
Starting from `v1.3.0`, a best practices helper is enabled by default when handling data intersections and unions:
|
|
@@ -281,7 +274,7 @@ class UserModels extends Zod2XModel {
|
|
|
281
274
|
}
|
|
282
275
|
|
|
283
276
|
const userModels = new UserModels();
|
|
284
|
-
console.log(userModels.transpile(
|
|
277
|
+
console.log(userModels.transpile(Zod2XTranspilers.Zod2Ts));
|
|
285
278
|
// Output:
|
|
286
279
|
// export enum UserRole {
|
|
287
280
|
// Admin = "Admin",
|
|
@@ -353,6 +346,8 @@ console.log(userDtos.transpile(Zod2XTranspilers.Zod2Ts))
|
|
|
353
346
|
3 - Are your models too large? Simplify them!
|
|
354
347
|
If you are dealing with complex models whose definitions are too extensive, split them into multiple classes and then combine them using `Zod2XMixin` as shown below:
|
|
355
348
|
```ts
|
|
349
|
+
import { Zod2XMixin } from "zod-to-x";
|
|
350
|
+
|
|
356
351
|
// Sub-models do not require a layer decorator; it is applied automatically when inherited by the main model.
|
|
357
352
|
|
|
358
353
|
// Sub-model 1
|
|
@@ -480,190 +475,81 @@ Common options:
|
|
|
480
475
|
### 1) Typescript
|
|
481
476
|
- Options:
|
|
482
477
|
- **outType**: Output transpilation using Typescript interfaces or Classes. Defaults to `interface`.
|
|
478
|
+
- **keepKeys**: Specifies whether property names should follow the TypeScript naming convention (false) or remain as originally defined (true). The default is `false`.
|
|
479
|
+
- [Examples](https://github.com/rroumenov/zod-to-x/blob/main/test/test_zod2ts)
|
|
483
480
|
|
|
484
|
-
### 2)
|
|
485
|
-
- Options:
|
|
486
|
-
- **packageName**: Name of the protobuf file package.
|
|
487
|
-
- **useCamelCase**: Protobuf follows the snake_case convention for field names, but camelCase can also be used. Defaults to `false`.
|
|
488
|
-
|
|
489
|
-
- Limitations:
|
|
490
|
-
- `ZodTuple` is supported only for items of the same type.
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
### 3) C++
|
|
481
|
+
### 2) C++
|
|
494
482
|
`Nlohmann` dependency is used for data serialization/deserialization. For *C++11*, `Boost` dependency is used. For *C++17* or newer, standard libraries are used.
|
|
495
483
|
- Options:
|
|
496
484
|
- **includeNulls**: When serializing, include all values even if `null`. Defaults to `false`.
|
|
497
485
|
- **namespace**: Name of the namespace containing the output code.
|
|
498
486
|
- **outType**: Output transpilation using C++ Structs or Classes. Defaults to `struct`.
|
|
499
487
|
- **skipSerialize**: Remove Nlohmann JSON serialization/deserialization. Defaults to `false`.
|
|
488
|
+
- **keepKeys**: Specifies whether property names should follow the C++ naming convention (false) or remain as originally defined (true). The default is `false`.
|
|
489
|
+
- [Examples](https://github.com/rroumenov/zod-to-x/blob/main/test/test_zod2cpp)
|
|
500
490
|
|
|
501
491
|
|
|
502
492
|
|
|
503
|
-
## Mapping of supported Zod Types
|
|
504
|
-
|
|
505
|
-
| Zod Type | TypeScript | Protobuf | C++ |
|
|
506
|
-
|-----------------------|-----------------------------|-----------------------------------------------|-----------------------------------------------|
|
|
507
|
-
| `z.string()` | `string` | `string` | `std::string`
|
|
508
|
-
| `z.number()` | `number` | `double`, `uint32`, `uint64`, `ìnt32`, `int64`| `double`, `uint32_t`, `uint64_t`, `ìnt32_t`, `int64_t`
|
|
509
|
-
| `z.bigint()` | `number` | `int64`, `uint64` | `int64_t`, `uint64_t`
|
|
510
|
-
| `z.boolean()` | `boolean` | `bool` | `bool`
|
|
511
|
-
| `z.date()` | `Date` | `google.protobuf.Timestamp` | Not supported
|
|
512
|
-
| `z.literal()` | Literal value (`'value'`) | As number or string | As string
|
|
513
|
-
| `z.enum()` | `enum` | `enum` | `enum class T: int`
|
|
514
|
-
| `z.nativeEnum()` | Native `enum` | `enum` | `enum class T: int`
|
|
515
|
-
| `z.array()` | `T[]` | `repeated` field | `std::vector<T>`
|
|
516
|
-
| `z.set()` | `Set<T>` | `repeated` field | `std::set<T>`
|
|
517
|
-
| `z.tuple()` | `[T1, T2, T3]` | `repeated` field | `std::tuple<T1, T2, T3>`
|
|
518
|
-
| `z.object()` | `interface` or `class` | `message` | `struct` or `class`
|
|
519
|
-
| `z.record()` | `Record<string, T>` | `map<string, K>` | `std::unordered_map<T>`
|
|
520
|
-
| `z.map()` | `Map<string, T>` | `map<string, K>` | `std::unordered_map<T>`
|
|
521
|
-
| `z.union()` <sup>(2)</sup> | `T1 \| T2` or `type` | `oneof` | `std::variant<T, K>` (`boost::variant<T, K>` for C++11)
|
|
522
|
-
| `z.discriminatedUnion()`| `T1 \| T2` or `type` | `oneof` | `std::variant<T, K>` (`boost::variant<T, K>` for C++11)
|
|
523
|
-
| `z.intersection()` <sup>(1)</sup> | `T1 & T2` or `type` | Not supported | `struct` or `class` with `inheritance`
|
|
524
|
-
| `z.any()` | `any` | `google.protobuf.Any` | `nlohmann::json`
|
|
525
|
-
| `z.optional()` | `T \| undefined` | Not supported | `std::optional<T>` (`boost::optional<T>` for C++11)
|
|
526
|
-
| `z.nullable()` | `T \| null` | Not supported | `std::optional<T>` (`boost::optional<T>` for C++11)
|
|
527
|
-
|
|
528
|
-
<sup>(1)</sup> Consider to use Zod's merge instead of ZodIntersection when possible.
|
|
529
|
-
<sup>(2)</sup> Consider to use ZodDiscriminatedUnion when possible. In languages like C++, deserialization is O(1) against the O(n) of the ZodUnion.
|
|
530
|
-
|
|
531
493
|
## Additional utils
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
494
|
+
Additional useful tools to convert Zod Schemas into different formats.
|
|
495
|
+
|
|
496
|
+
### 1) `zod2JsonSchemaDefinitions`
|
|
497
|
+
In case of use of libraries like [`@zod-to-json-schema`](https://github.com/StefanTerdell/zod-to-json-schema), the provided zod extension can also be used as a JSON Schema definitions mapper. Check out this [input example](https://github.com/rroumenov/zod-to-x/blob/main/test/test_zod2jschema_def/user_schema.ts) and its [output](https://github.com/rroumenov/zod-to-x/blob/main/test/test_zod2jschema_def/user_schema.json) (\*).
|
|
498
|
+
|
|
499
|
+
<sup>*(\*) Output is generated using definitions from `zod2JsonSchemaDefinitions` and [`@zod-to-json-schema`](https://github.com/StefanTerdell/zod-to-json-schema) to create the schema with them.*</sup>
|
|
500
|
+
|
|
535
501
|
```ts
|
|
536
502
|
import { z } from 'zod';
|
|
537
|
-
import { extendZod,
|
|
503
|
+
import { extendZod, Zod2XConverters } from 'zod-to-x';
|
|
538
504
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
505
|
+
extendZod(z);
|
|
506
|
+
|
|
507
|
+
// Example using model from `Quick-start` section
|
|
508
|
+
const visitorDefinitions = Zod2XConverters.zod2JsonSchemaDefinitions(VisitorSchema);
|
|
509
|
+
const visitorJsonSchema = zodToJsonSchema(
|
|
510
|
+
VisitorSchema,
|
|
511
|
+
{definitions: visitorDefinitions}
|
|
512
|
+
);
|
|
513
|
+
console.log(visitorJsonSchema); // JSON Schema with definitions
|
|
514
|
+
|
|
515
|
+
// Example using model from `Layer modeling` section
|
|
516
|
+
const createUserDtoDefinitions = Zod2XConverters.zod2JsonSchemaDefinitions(userDtos.createUserUseCaseDto);
|
|
517
|
+
const createUserDtoJsonSchema = zodToJsonSchema(
|
|
518
|
+
userDtos.createUserUseCaseDto,
|
|
519
|
+
{definitions: createUserDtoDefinitions}
|
|
520
|
+
);
|
|
521
|
+
console.log(createUserDtoJsonSchema); // JSON Schema with definitions
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### 2) `zod2ProtoV3`
|
|
525
|
+
In case of use of Google protobuf to improve communication performance, you can automatically generate `proto` files directly from your models. Check out this [input example](https://github.com/rroumenov/zod-to-x/blob/main/test/test_zod2proto3/proto3_supported_schemas.ts) and its [output](https://github.com/rroumenov/zod-to-x/blob/main/test/test_zod2proto3/proto3_supported_schemas.expect.proto)
|
|
539
526
|
|
|
527
|
+
- Options:
|
|
528
|
+
- **packageName**: Name of the protobuf file package.
|
|
529
|
+
- **header**: Text to add as a comment at the beginning of the output.
|
|
530
|
+
- **indent**: Number of spaces to use for indentation in the generated code. Defaults to 4 if not specified.
|
|
531
|
+
- **includeComments**: Determines whether to include comments in the transpiled code. Defaults to true.
|
|
532
|
+
- **keepKeys**: Specifies whether property names should follow the Google Protobuf naming convention (false) or remain as originally defined (true). The default is `false`.
|
|
533
|
+
|
|
534
|
+
- Limitations:
|
|
535
|
+
- ZodTuple is supported only for items of the same type.
|
|
536
|
+
|
|
537
|
+
```ts
|
|
538
|
+
import { z } from 'zod';
|
|
539
|
+
import { extendZod, Zod2XConverters } from 'zod-to-x';
|
|
540
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
540
541
|
extendZod(z);
|
|
541
542
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
'active',
|
|
556
|
-
'inactive',
|
|
557
|
-
'pending']
|
|
558
|
-
)
|
|
559
|
-
.describe("This is a UserStatus enumerate description.")
|
|
560
|
-
.zod2x("UserStatus");
|
|
561
|
-
|
|
562
|
-
export const UserModel = z.object({
|
|
563
|
-
address: Address,
|
|
564
|
-
roles: z.array(UserRole),
|
|
565
|
-
status: StatusEnum,
|
|
566
|
-
friends: z.lazy((): ZodType => UserModel.array().optional().nullable()),
|
|
567
|
-
// [... more attributes]
|
|
568
|
-
})
|
|
569
|
-
.describe("This is a UserModel interface description.")
|
|
570
|
-
.zod2x("UserModel");
|
|
571
|
-
|
|
572
|
-
const userDefinitions = zod2JsonSchemaDefinitions(UserModel);
|
|
573
|
-
const userJsonSchema = zodToJsonSchema(UserModel, {definitions: userDefinitions});
|
|
574
|
-
console.log(userJsonSchema);
|
|
575
|
-
// output:
|
|
576
|
-
// {
|
|
577
|
-
// "$ref": "#/definitions/UserModel",
|
|
578
|
-
// "definitions": {
|
|
579
|
-
// "UserAddress": {
|
|
580
|
-
// "type": "object",
|
|
581
|
-
// "properties": {
|
|
582
|
-
// "street": {
|
|
583
|
-
// "type": "string"
|
|
584
|
-
// },
|
|
585
|
-
// "city": {
|
|
586
|
-
// "type": "string"
|
|
587
|
-
// },
|
|
588
|
-
// "zipCode": {
|
|
589
|
-
// "type": [
|
|
590
|
-
// "string",
|
|
591
|
-
// "null"
|
|
592
|
-
// ]
|
|
593
|
-
// }
|
|
594
|
-
// },
|
|
595
|
-
// "required": [
|
|
596
|
-
// "street",
|
|
597
|
-
// "city",
|
|
598
|
-
// "zipCode"
|
|
599
|
-
// ],
|
|
600
|
-
// "additionalProperties": false
|
|
601
|
-
// },
|
|
602
|
-
// "UserRole": {
|
|
603
|
-
// "type": "string",
|
|
604
|
-
// "enum": [
|
|
605
|
-
// "admin",
|
|
606
|
-
// "editor",
|
|
607
|
-
// "viewer"
|
|
608
|
-
// ]
|
|
609
|
-
// },
|
|
610
|
-
// "UserStatus": {
|
|
611
|
-
// "type": "string",
|
|
612
|
-
// "enum": [
|
|
613
|
-
// "active",
|
|
614
|
-
// "inactive",
|
|
615
|
-
// "pending"
|
|
616
|
-
// ],
|
|
617
|
-
// "description": "This is a UserStatus enumerate description."
|
|
618
|
-
// },
|
|
619
|
-
// "UserModel": {
|
|
620
|
-
// "type": "object",
|
|
621
|
-
// "properties": {
|
|
622
|
-
// "address": {
|
|
623
|
-
// "$ref": "#/definitions/UserAddress"
|
|
624
|
-
// },
|
|
625
|
-
// "roles": {
|
|
626
|
-
// "type": "array",
|
|
627
|
-
// "items": {
|
|
628
|
-
// "$ref": "#/definitions/UserRole"
|
|
629
|
-
// }
|
|
630
|
-
// },
|
|
631
|
-
// "status": {
|
|
632
|
-
// "$ref": "#/definitions/UserStatus"
|
|
633
|
-
// },
|
|
634
|
-
// "friends": {
|
|
635
|
-
// "anyOf": [
|
|
636
|
-
// {
|
|
637
|
-
// "anyOf": [
|
|
638
|
-
// {
|
|
639
|
-
// "not": {}
|
|
640
|
-
// },
|
|
641
|
-
// {
|
|
642
|
-
// "type": "array",
|
|
643
|
-
// "items": {
|
|
644
|
-
// "$ref": "#/definitions/UserModel"
|
|
645
|
-
// },
|
|
646
|
-
// "description": "This is a UserModel interface description."
|
|
647
|
-
// }
|
|
648
|
-
// ],
|
|
649
|
-
// "description": "This is a UserModel interface description."
|
|
650
|
-
// },
|
|
651
|
-
// {
|
|
652
|
-
// "type": "null"
|
|
653
|
-
// }
|
|
654
|
-
// ],
|
|
655
|
-
// "description": "This is a UserModel interface description."
|
|
656
|
-
// },
|
|
657
|
-
// },
|
|
658
|
-
// "required": [
|
|
659
|
-
// "address",
|
|
660
|
-
// "roles",
|
|
661
|
-
// "status",
|
|
662
|
-
// ],
|
|
663
|
-
// "additionalProperties": false,
|
|
664
|
-
// "description": "This is a UserModel interface description."
|
|
665
|
-
// }
|
|
666
|
-
// },
|
|
667
|
-
// "$schema": "http://json-schema.org/draft-07/schema#"
|
|
668
|
-
// }
|
|
669
|
-
```
|
|
543
|
+
// Example using model from `Quick-start` section
|
|
544
|
+
const visitorProtobuf = Zod2XConverters.zod2ProtoV3(VisitorSchema);
|
|
545
|
+
console.log(visitorProtobuf); // Proto file of Visitor's model
|
|
546
|
+
|
|
547
|
+
// Example using model from `Layer modeling` section
|
|
548
|
+
const createUserDtoProtobuf = Zod2XConverters.zod2ProtoV3(userDtos.createUserUseCaseDto);
|
|
549
|
+
console.log(createUserDtoProtobuf); // Proto file of CreateUserUseCaseDto's model
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
## Mapping of supported Zod Types by Langauge
|
|
555
|
+
For a detailed mapping of supported Zod types across supported targets, please refer to the [SUPPORTED_ZOD_TYPES.md](https://github.com/rroumenov/zod-to-x/blob/main/SUPPORTED_ZOD_TYPES.md) file.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.zod2JsonSchemaDefinitions = exports.zod2ProtoV3 = void 0;
|
|
4
|
+
var runner_1 = require("./protobuf_v3/runner");
|
|
5
|
+
Object.defineProperty(exports, "zod2ProtoV3", { enumerable: true, get: function () { return runner_1.zod2ProtoV3; } });
|
|
6
|
+
var json_schema_definitions_1 = require("./json_schema_definitions");
|
|
7
|
+
Object.defineProperty(exports, "zod2JsonSchemaDefinitions", { enumerable: true, get: function () { return json_schema_definitions_1.zod2JsonSchemaDefinitions; } });
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { IZodToXOpt } from "../../core";
|
|
2
|
+
export interface IZod2ProtoV3Opt extends IZodToXOpt {
|
|
3
|
+
/**
|
|
4
|
+
* Name of the protobuf file package.
|
|
5
|
+
*/
|
|
6
|
+
packageName?: string;
|
|
7
|
+
/**
|
|
8
|
+
* By default (false), structure/class property names are converted according to the target
|
|
9
|
+
* language's naming conventions. If set to true, the original property names are preserved.
|
|
10
|
+
*/
|
|
11
|
+
keepKeys?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare const defaultOpts: IZod2ProtoV3Opt;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ZodObject, ZodRawShape } from "zod";
|
|
2
|
+
import { IZod2AstOpt } from "../../core";
|
|
3
|
+
import { IZod2ProtoV3Opt } from "./options";
|
|
4
|
+
/**
|
|
5
|
+
* Converts a Zod schema into a Protocol Buffers v3 definition.
|
|
6
|
+
*
|
|
7
|
+
* @template T - The shape of the Zod schema.
|
|
8
|
+
* @param schema - The Zod object schema to be converted.
|
|
9
|
+
* @param opt - Optional configuration for the conversion process.
|
|
10
|
+
* @param opt.strict - Whether to enforce strict mode during AST generation.
|
|
11
|
+
* @param opt.packageName - The package name to use in the generated Protocol Buffers definition.
|
|
12
|
+
* @param opt.keepKeys - Whether to keep the original property names in the generated file instead
|
|
13
|
+
* of converting them to snake_case as per Protobuf conventions.
|
|
14
|
+
* @param opt.header - Custom header text to include in the generated file.
|
|
15
|
+
* @param opt.indent - The indentation style to use in the generated file.
|
|
16
|
+
* @param opt.includeComments - Whether to include comments in the generated Protocol Buffers
|
|
17
|
+
* definition.
|
|
18
|
+
* @returns The Protocol Buffers v3 definition as a string.
|
|
19
|
+
*/
|
|
20
|
+
export declare function zod2ProtoV3<T extends ZodRawShape>(schema: ZodObject<T>, opt?: Pick<IZod2AstOpt, "strict"> & Pick<IZod2ProtoV3Opt, "packageName" | "keepKeys" | "header" | "indent" | "includeComments">): string;
|
|
@@ -3,10 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.zod2ProtoV3 = zod2ProtoV3;
|
|
7
7
|
const case_1 = __importDefault(require("case"));
|
|
8
8
|
const core_1 = require("../../core");
|
|
9
9
|
const number_limits_1 = require("../../utils/number_limits");
|
|
10
|
+
const string_utils_1 = __importDefault(require("../../utils/string_utils"));
|
|
10
11
|
const options_1 = require("./options");
|
|
11
12
|
const allowedKeyTypes = [
|
|
12
13
|
"int32",
|
|
@@ -22,10 +23,6 @@ const allowedKeyTypes = [
|
|
|
22
23
|
"bool",
|
|
23
24
|
"string",
|
|
24
25
|
];
|
|
25
|
-
/**
|
|
26
|
-
* @deprecated Zod2ProtoV3 will not be considered as a transpilerable programming language, but as
|
|
27
|
-
* another utility such as `zod2JsonSchemaDefinitions`.
|
|
28
|
-
*/
|
|
29
26
|
class Zod2ProtoV3 extends core_1.Zod2X {
|
|
30
27
|
constructor(opt = {}) {
|
|
31
28
|
super(Object.assign(Object.assign({}, options_1.defaultOpts), opt));
|
|
@@ -198,9 +195,9 @@ class Zod2ProtoV3 extends core_1.Zod2X {
|
|
|
198
195
|
throw new core_1.NotTranspilerableTypeError("Map and Repeated fields are not suported by Protobuf oneOf");
|
|
199
196
|
}
|
|
200
197
|
this.push0(`message ${data.name} {`);
|
|
201
|
-
this.push1(`oneof ${this._adaptField(data.name + "Oneof")} {`);
|
|
198
|
+
this.push1(`oneof ${string_utils_1.default.lowerFirstChar(this._adaptField(data.name + "Oneof"))} {`);
|
|
202
199
|
attributesTypes.forEach((item, index) => {
|
|
203
|
-
this.push2(`${item} ${this._adaptField(item)} = ${index + 1};`);
|
|
200
|
+
this.push2(`${item} ${string_utils_1.default.lowerFirstChar(this._adaptField(item))} = ${index + 1};`);
|
|
204
201
|
});
|
|
205
202
|
this.push1(`}`);
|
|
206
203
|
this.push0("}\n");
|
|
@@ -219,12 +216,31 @@ class Zod2ProtoV3 extends core_1.Zod2X {
|
|
|
219
216
|
* @returns
|
|
220
217
|
*/
|
|
221
218
|
_adaptField(fieldName) {
|
|
222
|
-
if (this.opt.
|
|
223
|
-
return
|
|
219
|
+
if (this.opt.keepKeys === true) {
|
|
220
|
+
return fieldName;
|
|
224
221
|
}
|
|
225
222
|
else {
|
|
226
223
|
return case_1.default.snake(fieldName);
|
|
227
224
|
}
|
|
228
225
|
}
|
|
229
226
|
}
|
|
230
|
-
|
|
227
|
+
/**
|
|
228
|
+
* Converts a Zod schema into a Protocol Buffers v3 definition.
|
|
229
|
+
*
|
|
230
|
+
* @template T - The shape of the Zod schema.
|
|
231
|
+
* @param schema - The Zod object schema to be converted.
|
|
232
|
+
* @param opt - Optional configuration for the conversion process.
|
|
233
|
+
* @param opt.strict - Whether to enforce strict mode during AST generation.
|
|
234
|
+
* @param opt.packageName - The package name to use in the generated Protocol Buffers definition.
|
|
235
|
+
* @param opt.keepKeys - Whether to keep the original property names in the generated file instead
|
|
236
|
+
* of converting them to snake_case as per Protobuf conventions.
|
|
237
|
+
* @param opt.header - Custom header text to include in the generated file.
|
|
238
|
+
* @param opt.indent - The indentation style to use in the generated file.
|
|
239
|
+
* @param opt.includeComments - Whether to include comments in the generated Protocol Buffers
|
|
240
|
+
* definition.
|
|
241
|
+
* @returns The Protocol Buffers v3 definition as a string.
|
|
242
|
+
*/
|
|
243
|
+
function zod2ProtoV3(schema, opt = {}) {
|
|
244
|
+
const astNode = new core_1.Zod2Ast({ strict: opt.strict }).build(schema);
|
|
245
|
+
return new Zod2ProtoV3(opt).transpile(astNode);
|
|
246
|
+
}
|
package/dist/core/ast_node.d.ts
CHANGED
|
@@ -44,9 +44,13 @@ export declare class Zod2Ast {
|
|
|
44
44
|
private _getTranspilerableFile;
|
|
45
45
|
/**
|
|
46
46
|
* Transpilerable items are treated as references in the AST
|
|
47
|
-
* @param ref
|
|
48
|
-
* @param refType
|
|
49
|
-
* @param discriminantValue
|
|
47
|
+
* @param ref - Output type name
|
|
48
|
+
* @param refType - Type of the output type
|
|
49
|
+
* @param discriminantValue - Discriminant value (for ZodDiscriminatedUnion)
|
|
50
|
+
* @param parentNamespace - For Layered modeling, the namespace of the parent type if does not
|
|
51
|
+
* belong to the same file.
|
|
52
|
+
* @param parentFile - For Layered modeling, the file of the parent type if does not belong to
|
|
53
|
+
* the same file.
|
|
50
54
|
* @returns
|
|
51
55
|
*/
|
|
52
56
|
private _createDefinition;
|
package/dist/core/ast_node.js
CHANGED
|
@@ -27,17 +27,38 @@ class Zod2Ast {
|
|
|
27
27
|
*/
|
|
28
28
|
_getTranspilerableFile(itemName, metadata) {
|
|
29
29
|
var _a;
|
|
30
|
-
|
|
31
|
-
if (this.opt.layer && layer) {
|
|
32
|
-
if (
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
let layer;
|
|
31
|
+
if (this.opt.layer !== undefined && (metadata === null || metadata === void 0 ? void 0 : metadata.layer) !== undefined) {
|
|
32
|
+
if (metadata.layer.file === this.opt.layer.file) {
|
|
33
|
+
// Case 1: Only layer exists and belongs to the same file
|
|
34
|
+
// Case 2: Layer (belongs to same file) and parentLayer exist
|
|
35
|
+
// Behaviour: New type is created extending the parent layer (if any)
|
|
36
|
+
layer = (_a = metadata.parentLayer) !== null && _a !== void 0 ? _a : metadata.layer;
|
|
37
|
+
if (this.opt.layer.index < layer.index) {
|
|
38
|
+
throw new errors_1.BadLayerDefinitionError(`${itemName}: Layer with number ${this.opt.layer.index} can only use models` +
|
|
39
|
+
`from the same or lower layer. Found layer with number ${layer.index}`);
|
|
40
|
+
}
|
|
41
|
+
if (this.opt.layer.file !== layer.file) {
|
|
42
|
+
return {
|
|
43
|
+
parentFile: layer.file,
|
|
44
|
+
parentNamespace: layer.namespace,
|
|
45
|
+
parentTypeName: metadata === null || metadata === void 0 ? void 0 : metadata.parentTypeName,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
35
48
|
}
|
|
36
|
-
|
|
49
|
+
else {
|
|
50
|
+
// Case 3: Only layer exists and belongs to a different file
|
|
51
|
+
// Case 4: Layer (belongs to different file) and parentLayer exist
|
|
52
|
+
// Behaviour: Type is imported from Layer file
|
|
53
|
+
layer = metadata.layer;
|
|
54
|
+
if (this.opt.layer.index < layer.index) {
|
|
55
|
+
throw new errors_1.BadLayerDefinitionError(`${itemName}: Layer with number ${this.opt.layer.index} can only use models` +
|
|
56
|
+
`from the same or lower layer. Found layer with number ${layer.index}`);
|
|
57
|
+
}
|
|
37
58
|
return {
|
|
38
59
|
parentFile: layer.file,
|
|
39
60
|
parentNamespace: layer.namespace,
|
|
40
|
-
parentTypeName:
|
|
61
|
+
parentTypeName: undefined,
|
|
41
62
|
};
|
|
42
63
|
}
|
|
43
64
|
}
|
|
@@ -45,18 +66,23 @@ class Zod2Ast {
|
|
|
45
66
|
}
|
|
46
67
|
/**
|
|
47
68
|
* Transpilerable items are treated as references in the AST
|
|
48
|
-
* @param ref
|
|
49
|
-
* @param refType
|
|
50
|
-
* @param discriminantValue
|
|
69
|
+
* @param ref - Output type name
|
|
70
|
+
* @param refType - Type of the output type
|
|
71
|
+
* @param discriminantValue - Discriminant value (for ZodDiscriminatedUnion)
|
|
72
|
+
* @param parentNamespace - For Layered modeling, the namespace of the parent type if does not
|
|
73
|
+
* belong to the same file.
|
|
74
|
+
* @param parentFile - For Layered modeling, the file of the parent type if does not belong to
|
|
75
|
+
* the same file.
|
|
51
76
|
* @returns
|
|
52
77
|
*/
|
|
53
|
-
_createDefinition(ref, refType, discriminantValue, parentNamespace) {
|
|
78
|
+
_createDefinition(ref, refType, discriminantValue, parentNamespace, parentFile) {
|
|
54
79
|
return {
|
|
55
80
|
type: "definition",
|
|
56
81
|
reference: ref,
|
|
57
82
|
referenceType: refType,
|
|
58
83
|
discriminantValue,
|
|
59
84
|
parentNamespace,
|
|
85
|
+
parentFile,
|
|
60
86
|
};
|
|
61
87
|
}
|
|
62
88
|
/**
|
|
@@ -170,7 +196,7 @@ class Zod2Ast {
|
|
|
170
196
|
if (!this.nodes.has(name)) {
|
|
171
197
|
this.nodes.set(name, item);
|
|
172
198
|
}
|
|
173
|
-
return this._createDefinition(name, zodTypeName, undefined, parentNamespace);
|
|
199
|
+
return this._createDefinition(name, zodTypeName, undefined, parentNamespace, parentFile);
|
|
174
200
|
}
|
|
175
201
|
_getObjectAst(schema, opt) {
|
|
176
202
|
const { name, zodTypeName, parentFile, parentNamespace, parentTypeName } = this._getNames(schema, "ZodObject type must have a typeName. Use zod2x method to provide one.");
|
|
@@ -205,7 +231,7 @@ class Zod2Ast {
|
|
|
205
231
|
}
|
|
206
232
|
}
|
|
207
233
|
}
|
|
208
|
-
return this._createDefinition(name, zodTypeName, discriminantValue, parentTypeName ? undefined : parentNamespace);
|
|
234
|
+
return this._createDefinition(name, zodTypeName, discriminantValue, parentTypeName ? undefined : parentNamespace, parentTypeName ? undefined : parentFile);
|
|
209
235
|
}
|
|
210
236
|
_getUnionAst(schema) {
|
|
211
237
|
const def = schema._def;
|
|
@@ -241,7 +267,7 @@ class Zod2Ast {
|
|
|
241
267
|
if (name && !this.nodes.has(name)) {
|
|
242
268
|
this.nodes.set(name, item);
|
|
243
269
|
}
|
|
244
|
-
return this._createDefinition(name, zodTypeName, undefined, parentTypeName ? undefined : parentNamespace);
|
|
270
|
+
return this._createDefinition(name, zodTypeName, undefined, parentTypeName ? undefined : parentNamespace, parentTypeName ? undefined : parentFile);
|
|
245
271
|
}
|
|
246
272
|
_getIntersectionAst(schema) {
|
|
247
273
|
const def = schema._def;
|
|
@@ -274,7 +300,7 @@ class Zod2Ast {
|
|
|
274
300
|
if (name && !this.nodes.has(name)) {
|
|
275
301
|
this.nodes.set(name, item);
|
|
276
302
|
}
|
|
277
|
-
return this._createDefinition(name, zodTypeName, undefined, parentTypeName ? undefined : parentNamespace);
|
|
303
|
+
return this._createDefinition(name, zodTypeName, undefined, parentTypeName ? undefined : parentNamespace, parentTypeName ? undefined : parentFile);
|
|
278
304
|
}
|
|
279
305
|
/**
|
|
280
306
|
* Build the AST node of provided Zod Schema
|
package/dist/core/ast_types.d.ts
CHANGED
|
@@ -116,12 +116,7 @@ export type ASTDefintion = ASTCommon & {
|
|
|
116
116
|
reference: string;
|
|
117
117
|
referenceType: ZodFirstPartyTypeKind;
|
|
118
118
|
discriminantValue?: string;
|
|
119
|
-
|
|
120
|
-
* Namespace where the transpilerable model is defined. Used to use import statements in the
|
|
121
|
-
* transpiled code.
|
|
122
|
-
*/
|
|
123
|
-
parentNamespace?: string;
|
|
124
|
-
};
|
|
119
|
+
} & Omit<ASTLayerMetadata, "parentTypeName">;
|
|
125
120
|
/**
|
|
126
121
|
* Represents a general AST node, encompassing various Zod schema types.
|
|
127
122
|
*/
|
|
@@ -187,6 +187,14 @@ export declare abstract class Zod2X<T extends IZodToXOpt> {
|
|
|
187
187
|
* @returns A string representing the type in the target language.
|
|
188
188
|
*/
|
|
189
189
|
protected getAttributeType(token: ASTNode | TranspilerableTypes): string;
|
|
190
|
+
/**
|
|
191
|
+
* Determines whether a given type is an external type import.
|
|
192
|
+
*
|
|
193
|
+
* @param item - An object containing the `parentFile` and `parentNamespace`
|
|
194
|
+
* properties of the type to evaluate.
|
|
195
|
+
* @returns `true` if the type is an external type import; otherwise, `false`.
|
|
196
|
+
*/
|
|
197
|
+
protected isExternalTypeImport(item: Pick<TranspilerableTypes, "parentFile" | "parentNamespace">): boolean;
|
|
190
198
|
/**
|
|
191
199
|
* Adds an external type import to the transpiler's imports if the provided transpiled item
|
|
192
200
|
* is located into another file and namespace, and if the `useImports` option is not disabled.
|
|
@@ -195,7 +203,7 @@ export declare abstract class Zod2X<T extends IZodToXOpt> {
|
|
|
195
203
|
* about the type to be imported, including its parent file and namespace.
|
|
196
204
|
* @returns `true` if the import was successfully added, otherwise `false`.
|
|
197
205
|
*/
|
|
198
|
-
protected addExternalTypeImport(item: TranspilerableTypes): boolean;
|
|
206
|
+
protected addExternalTypeImport(item: Pick<TranspilerableTypes, "parentFile" | "parentNamespace">): boolean;
|
|
199
207
|
/**
|
|
200
208
|
* Transpiles a single item from the transpiler queue.
|
|
201
209
|
* @param item - The transpilerable type to transpile.
|
package/dist/core/transpiler.js
CHANGED
|
@@ -55,10 +55,16 @@ class Zod2X {
|
|
|
55
55
|
varType = token.name;
|
|
56
56
|
}
|
|
57
57
|
else if (token.type === "definition") {
|
|
58
|
-
|
|
59
|
-
this.
|
|
60
|
-
|
|
61
|
-
: token.
|
|
58
|
+
if (this.opt.useImports === true && token.parentNamespace) {
|
|
59
|
+
varType = this.getTypeFromExternalNamespace(token.parentNamespace, token.reference);
|
|
60
|
+
this.addExternalTypeImport({
|
|
61
|
+
parentNamespace: token.parentNamespace,
|
|
62
|
+
parentFile: token.parentFile,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
varType = token.reference;
|
|
67
|
+
}
|
|
62
68
|
}
|
|
63
69
|
else if (token.type === zod_1.ZodFirstPartyTypeKind.ZodString) {
|
|
64
70
|
varType = this.getStringType();
|
|
@@ -106,6 +112,18 @@ class Zod2X {
|
|
|
106
112
|
}
|
|
107
113
|
return token.arrayDimension ? this.getArrayType(varType, token.arrayDimension) : varType;
|
|
108
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Determines whether a given type is an external type import.
|
|
117
|
+
*
|
|
118
|
+
* @param item - An object containing the `parentFile` and `parentNamespace`
|
|
119
|
+
* properties of the type to evaluate.
|
|
120
|
+
* @returns `true` if the type is an external type import; otherwise, `false`.
|
|
121
|
+
*/
|
|
122
|
+
isExternalTypeImport(item) {
|
|
123
|
+
return (item.parentFile !== undefined &&
|
|
124
|
+
item.parentNamespace !== undefined &&
|
|
125
|
+
this.opt.useImports !== false);
|
|
126
|
+
}
|
|
109
127
|
/**
|
|
110
128
|
* Adds an external type import to the transpiler's imports if the provided transpiled item
|
|
111
129
|
* is located into another file and namespace, and if the `useImports` option is not disabled.
|
|
@@ -115,7 +133,7 @@ class Zod2X {
|
|
|
115
133
|
* @returns `true` if the import was successfully added, otherwise `false`.
|
|
116
134
|
*/
|
|
117
135
|
addExternalTypeImport(item) {
|
|
118
|
-
if (
|
|
136
|
+
if (this.isExternalTypeImport(item)) {
|
|
119
137
|
this.imports.add(this.addImportFromFile(item.parentFile, item.parentNamespace));
|
|
120
138
|
return true;
|
|
121
139
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,4 +4,4 @@ export { Zod2Ast } from "./core/ast_node";
|
|
|
4
4
|
export { Zod2X } from "./core/transpiler";
|
|
5
5
|
export * from "./layered-modeling";
|
|
6
6
|
export * as Zod2XTranspilers from "./transpilers";
|
|
7
|
-
export
|
|
7
|
+
export * as Zod2XConverters from "./converters";
|
package/dist/index.js
CHANGED
|
@@ -15,18 +15,28 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
26
36
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
27
37
|
};
|
|
28
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.
|
|
39
|
+
exports.Zod2XConverters = exports.Zod2XTranspilers = exports.Zod2X = exports.Zod2Ast = exports.Zod2XTypes = exports.extendZod = void 0;
|
|
30
40
|
// Core
|
|
31
41
|
var zod_ext_1 = require("./lib/zod_ext");
|
|
32
42
|
Object.defineProperty(exports, "extendZod", { enumerable: true, get: function () { return zod_ext_1.extendZod; } });
|
|
@@ -38,6 +48,5 @@ Object.defineProperty(exports, "Zod2X", { enumerable: true, get: function () { r
|
|
|
38
48
|
__exportStar(require("./layered-modeling"), exports);
|
|
39
49
|
// Transpilers
|
|
40
50
|
exports.Zod2XTranspilers = __importStar(require("./transpilers"));
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
Object.defineProperty(exports, "zod2JsonSchemaDefinitions", { enumerable: true, get: function () { return json_schema_definitions_1.zod2JsonSchemaDefinitions; } });
|
|
51
|
+
// Converters
|
|
52
|
+
exports.Zod2XConverters = __importStar(require("./converters"));
|
|
@@ -42,7 +42,6 @@ export declare class Zod2XModel {
|
|
|
42
42
|
*/
|
|
43
43
|
transpile(target: Target<"Zod2Cpp">, opt?: TargetOpt<"Zod2Cpp">, astOpt?: AstOpt): string;
|
|
44
44
|
transpile(target: Target<"Zod2Cpp17">, opt?: TargetOpt<"Zod2Cpp17">, astOpt?: AstOpt): string;
|
|
45
|
-
transpile(target: Target<"Zod2ProtoV3">, opt?: TargetOpt<"Zod2ProtoV3">, astOpt?: AstOpt): string;
|
|
46
45
|
transpile(target: Target<"Zod2Ts">, opt?: TargetOpt<"Zod2Ts">, astOpt?: AstOpt): string;
|
|
47
46
|
}
|
|
48
47
|
export {};
|
|
@@ -20,5 +20,10 @@ export interface IZod2CppOpt extends IZodToXOpt {
|
|
|
20
20
|
* Remove Nlohmann JSON serialization/deserialization. Default is false.
|
|
21
21
|
*/
|
|
22
22
|
skipSerialize?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* By default (false), structure/class property names are converted according to the target
|
|
25
|
+
* language's naming conventions. If set to true, the original property names are preserved.
|
|
26
|
+
*/
|
|
27
|
+
keepKeys?: boolean;
|
|
23
28
|
}
|
|
24
29
|
export declare const defaultOpts: IZod2CppOpt;
|
|
@@ -166,7 +166,7 @@ class Zod2Cpp extends core_1.Zod2X {
|
|
|
166
166
|
* }
|
|
167
167
|
*/
|
|
168
168
|
transpileEnum(data) {
|
|
169
|
-
if (this.
|
|
169
|
+
if (this.isExternalTypeImport(data)) {
|
|
170
170
|
return;
|
|
171
171
|
}
|
|
172
172
|
this.addComment(data.description);
|
|
@@ -196,7 +196,7 @@ class Zod2Cpp extends core_1.Zod2X {
|
|
|
196
196
|
* }
|
|
197
197
|
*/
|
|
198
198
|
transpileIntersection(data) {
|
|
199
|
-
if (this.
|
|
199
|
+
if (this.isExternalTypeImport(data)) {
|
|
200
200
|
if (data.parentTypeName) {
|
|
201
201
|
this.addExtendedType(data.name, data.parentNamespace, data.parentTypeName);
|
|
202
202
|
}
|
|
@@ -232,7 +232,7 @@ class Zod2Cpp extends core_1.Zod2X {
|
|
|
232
232
|
}
|
|
233
233
|
/** Ex: using TypeC = boost::variant<TypeA, TypeB> */
|
|
234
234
|
transpileUnion(data) {
|
|
235
|
-
if (this.
|
|
235
|
+
if (this.isExternalTypeImport(data)) {
|
|
236
236
|
if (data.parentTypeName) {
|
|
237
237
|
this.addExtendedType(data.name, data.parentNamespace, data.parentTypeName, true);
|
|
238
238
|
}
|
|
@@ -251,7 +251,7 @@ class Zod2Cpp extends core_1.Zod2X {
|
|
|
251
251
|
this._createUnionDeserializer(data.name, attributesData, data.discriminantKey);
|
|
252
252
|
}
|
|
253
253
|
transpileStruct(data) {
|
|
254
|
-
if (this.
|
|
254
|
+
if (this.isExternalTypeImport(data)) {
|
|
255
255
|
if (data.parentTypeName) {
|
|
256
256
|
this.addExtendedType(data.name, data.parentNamespace, data.parentTypeName);
|
|
257
257
|
}
|
|
@@ -275,7 +275,7 @@ class Zod2Cpp extends core_1.Zod2X {
|
|
|
275
275
|
this.push0(`struct ${data.name} {`);
|
|
276
276
|
const serializeData = [];
|
|
277
277
|
Object.entries(data.properties).forEach(([key, value]) => {
|
|
278
|
-
const snakeName = case_1.default.snake(key);
|
|
278
|
+
const snakeName = this.opt.keepKeys === true ? key : case_1.default.snake(key);
|
|
279
279
|
const origType = this._transpileMember(snakeName, value);
|
|
280
280
|
serializeData.push({
|
|
281
281
|
origName: key,
|
|
@@ -310,7 +310,7 @@ class Zod2Cpp extends core_1.Zod2X {
|
|
|
310
310
|
const setterGetter = [];
|
|
311
311
|
const serializeData = [];
|
|
312
312
|
Object.entries(data.properties).forEach(([key, value]) => {
|
|
313
|
-
const snakeName = case_1.default.snake(key);
|
|
313
|
+
const snakeName = this.opt.keepKeys === true ? key : case_1.default.snake(key);
|
|
314
314
|
const origType = this._transpileMember(snakeName, value);
|
|
315
315
|
setterGetter.push(...this._createSetterGetter(snakeName, origType, !(value.isNullable || value.isOptional)));
|
|
316
316
|
serializeData.push({
|
|
@@ -351,7 +351,7 @@ class Zod2Cpp extends core_1.Zod2X {
|
|
|
351
351
|
if (memberNode.isOptional || memberNode.isNullable) {
|
|
352
352
|
keyType = this._getOptional(keyType);
|
|
353
353
|
}
|
|
354
|
-
this.push1(`${keyType} ${
|
|
354
|
+
this.push1(`${keyType} ${memberName};`);
|
|
355
355
|
return origType;
|
|
356
356
|
}
|
|
357
357
|
/**
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Zod2Cpp17 = exports.Zod2Cpp = exports.
|
|
3
|
+
exports.Zod2Cpp17 = exports.Zod2Cpp = exports.Zod2Ts = void 0;
|
|
4
4
|
var runner_1 = require("./typescript/runner");
|
|
5
5
|
Object.defineProperty(exports, "Zod2Ts", { enumerable: true, get: function () { return runner_1.Zod2Ts; } });
|
|
6
|
-
var runner_2 = require("./
|
|
7
|
-
Object.defineProperty(exports, "
|
|
8
|
-
|
|
9
|
-
Object.defineProperty(exports, "Zod2Cpp", { enumerable: true, get: function () { return runner_3.Zod2Cpp; } });
|
|
10
|
-
Object.defineProperty(exports, "Zod2Cpp17", { enumerable: true, get: function () { return runner_3.Zod2Cpp17; } });
|
|
6
|
+
var runner_2 = require("./cpp/runner");
|
|
7
|
+
Object.defineProperty(exports, "Zod2Cpp", { enumerable: true, get: function () { return runner_2.Zod2Cpp; } });
|
|
8
|
+
Object.defineProperty(exports, "Zod2Cpp17", { enumerable: true, get: function () { return runner_2.Zod2Cpp17; } });
|
|
@@ -4,5 +4,10 @@ export interface IZod2TsOpt extends IZodToXOpt {
|
|
|
4
4
|
* Output transpilation using Typescript interfaces or Classes.
|
|
5
5
|
*/
|
|
6
6
|
outType?: "interface" | "class";
|
|
7
|
+
/**
|
|
8
|
+
* By default (false), structure/class property names are converted according to the target
|
|
9
|
+
* language's naming conventions. If set to true, the original property names are preserved.
|
|
10
|
+
*/
|
|
11
|
+
keepKeys?: boolean;
|
|
7
12
|
}
|
|
8
13
|
export declare const defaultOpts: IZod2TsOpt;
|
|
@@ -91,7 +91,7 @@ class Zod2Ts extends core_1.Zod2X {
|
|
|
91
91
|
* }
|
|
92
92
|
*/
|
|
93
93
|
transpileEnum(data) {
|
|
94
|
-
if (this.
|
|
94
|
+
if (this.isExternalTypeImport(data)) {
|
|
95
95
|
return;
|
|
96
96
|
}
|
|
97
97
|
this.addComment(data.description);
|
|
@@ -123,7 +123,7 @@ class Zod2Ts extends core_1.Zod2X {
|
|
|
123
123
|
* */
|
|
124
124
|
transpileIntersection(data) {
|
|
125
125
|
var _a;
|
|
126
|
-
if (this.
|
|
126
|
+
if (this.isExternalTypeImport(data)) {
|
|
127
127
|
if (data.parentTypeName) {
|
|
128
128
|
this.addExtendedType(data.name, data.parentNamespace, data.parentTypeName);
|
|
129
129
|
}
|
|
@@ -140,7 +140,7 @@ class Zod2Ts extends core_1.Zod2X {
|
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
transpileStruct(data) {
|
|
143
|
-
if (this.
|
|
143
|
+
if (this.isExternalTypeImport(data)) {
|
|
144
144
|
if (data.parentTypeName) {
|
|
145
145
|
this.addExtendedType(data.name, data.parentNamespace, data.parentTypeName);
|
|
146
146
|
}
|
|
@@ -171,7 +171,7 @@ class Zod2Ts extends core_1.Zod2X {
|
|
|
171
171
|
* */
|
|
172
172
|
transpileUnion(data) {
|
|
173
173
|
var _a;
|
|
174
|
-
if (this.
|
|
174
|
+
if (this.isExternalTypeImport(data)) {
|
|
175
175
|
if (data.parentTypeName) {
|
|
176
176
|
this.addExtendedType(data.name, data.parentNamespace, data.parentTypeName, {
|
|
177
177
|
isUnion: data.type === zod_1.ZodFirstPartyTypeKind.ZodUnion,
|
|
@@ -199,7 +199,7 @@ class Zod2Ts extends core_1.Zod2X {
|
|
|
199
199
|
_transpileStructuAsInterface(data) {
|
|
200
200
|
this.push0(`export interface ${data.name} {`);
|
|
201
201
|
for (const [key, value] of Object.entries(data.properties)) {
|
|
202
|
-
this._transpileMember(case_1.default.camel(key), value);
|
|
202
|
+
this._transpileMember(this.opt.keepKeys === true ? key : case_1.default.camel(key), value);
|
|
203
203
|
}
|
|
204
204
|
this.push0("}\n");
|
|
205
205
|
}
|
|
@@ -218,8 +218,9 @@ class Zod2Ts extends core_1.Zod2X {
|
|
|
218
218
|
this.push0(`export class ${data.name} {`);
|
|
219
219
|
const constructorBody = [];
|
|
220
220
|
for (const [key, value] of Object.entries(data.properties)) {
|
|
221
|
-
this.
|
|
222
|
-
|
|
221
|
+
const keyName = this.opt.keepKeys === true ? key : case_1.default.camel(key);
|
|
222
|
+
this._transpileMember(keyName, value);
|
|
223
|
+
constructorBody.push(`this.${keyName} = data.${keyName};`);
|
|
223
224
|
}
|
|
224
225
|
this.push0("");
|
|
225
226
|
this.push1(`constructor(data: ${data.name}) {`);
|
|
@@ -10,4 +10,12 @@ export default class StringUtils {
|
|
|
10
10
|
* size.
|
|
11
11
|
*/
|
|
12
12
|
static getIndentationLevels(indentSize: number): [string, string, string, string, string];
|
|
13
|
+
/**
|
|
14
|
+
* Converts the first character of a string to lowercase while leaving the rest of the string
|
|
15
|
+
* unchanged.
|
|
16
|
+
*
|
|
17
|
+
* @param str - The input string to process.
|
|
18
|
+
* @returns A new string with the first character converted to lowercase.
|
|
19
|
+
*/
|
|
20
|
+
static lowerFirstChar(str: string): string;
|
|
13
21
|
}
|
|
@@ -18,5 +18,17 @@ class StringUtils {
|
|
|
18
18
|
" ".repeat(indentSize * 4),
|
|
19
19
|
];
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Converts the first character of a string to lowercase while leaving the rest of the string
|
|
23
|
+
* unchanged.
|
|
24
|
+
*
|
|
25
|
+
* @param str - The input string to process.
|
|
26
|
+
* @returns A new string with the first character converted to lowercase.
|
|
27
|
+
*/
|
|
28
|
+
static lowerFirstChar(str) {
|
|
29
|
+
if (str.length === 0)
|
|
30
|
+
return str;
|
|
31
|
+
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
32
|
+
}
|
|
21
33
|
}
|
|
22
34
|
exports.default = StringUtils;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zod-to-x",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.4",
|
|
4
4
|
"description": "Multi language types generation from Zod schemas.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"files": [
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"ts-node": "^10.9.2",
|
|
62
62
|
"tsc-alias": "^1.8.10",
|
|
63
63
|
"tsconfig-paths": "4.2.0",
|
|
64
|
-
"typescript": "^5.6.3"
|
|
64
|
+
"typescript": "^5.6.3",
|
|
65
|
+
"zod-to-json-schema": "^3.21.4"
|
|
65
66
|
}
|
|
66
67
|
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { IZodToXOpt } from "../../core";
|
|
2
|
-
export interface IZod2ProtoV3Opt extends Omit<IZodToXOpt, "skipDiscriminatorNodes"> {
|
|
3
|
-
/**
|
|
4
|
-
* Name of the protobuf file package.
|
|
5
|
-
*/
|
|
6
|
-
packageName?: string;
|
|
7
|
-
/**
|
|
8
|
-
* Protobuf follows the snake_case convention for field names, but camelCase can also be used.
|
|
9
|
-
*/
|
|
10
|
-
useCamelCase?: boolean;
|
|
11
|
-
}
|
|
12
|
-
export declare const defaultOpts: IZod2ProtoV3Opt;
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { ASTCommon, ASTDiscriminatedUnion, ASTEnum, ASTIntersection, ASTNativeEnum, ASTObject, ASTUnion, Zod2X } from "../../core";
|
|
2
|
-
import { IZod2ProtoV3Opt } from "./options";
|
|
3
|
-
/**
|
|
4
|
-
* @deprecated Zod2ProtoV3 will not be considered as a transpilerable programming language, but as
|
|
5
|
-
* another utility such as `zod2JsonSchemaDefinitions`.
|
|
6
|
-
*/
|
|
7
|
-
export declare class Zod2ProtoV3 extends Zod2X<IZod2ProtoV3Opt> {
|
|
8
|
-
constructor(opt?: IZod2ProtoV3Opt);
|
|
9
|
-
protected getUnionType: () => string;
|
|
10
|
-
protected addImportFromFile(filename: string, namespace: string): string;
|
|
11
|
-
protected getTypeFromExternalNamespace(namespace: string, typeName: string): string;
|
|
12
|
-
protected addExtendedType(name: string, parentNamespace: string, parentTypeName: string): void;
|
|
13
|
-
protected getComment: (data: string, indent?: string) => string;
|
|
14
|
-
protected getBooleanType: () => string;
|
|
15
|
-
protected getStringType: () => string;
|
|
16
|
-
protected getNumberType: (isInt: boolean, range: {
|
|
17
|
-
min?: number;
|
|
18
|
-
max?: number;
|
|
19
|
-
}) => string;
|
|
20
|
-
protected getAnyType: () => string;
|
|
21
|
-
protected getDateType: () => string;
|
|
22
|
-
protected getSetType: (itemType: string) => string;
|
|
23
|
-
/**
|
|
24
|
-
* @description Determines the equivalent Protobuf type for a tuple based on its item types.
|
|
25
|
-
*
|
|
26
|
-
* Protobuf v3 does not directly support tuples. However, if all the types
|
|
27
|
-
* in the tuple are identical, it can be represented as a `repeated` field
|
|
28
|
-
* of that type. If the tuple contains mixed types, Protobuf cannot represent
|
|
29
|
-
* it directly, and an alternative approach (e.g., defining a Protobuf message)
|
|
30
|
-
* should be considered.
|
|
31
|
-
*
|
|
32
|
-
* @param itemsType - An array of strings representing the types of the tuple elements.
|
|
33
|
-
* @returns A string representing the Protobuf type for the tuple.
|
|
34
|
-
* If all tuple elements are of the same type, it returns a `repeated` field of that
|
|
35
|
-
* type.
|
|
36
|
-
* @throws NotTranspilerableTypeError if the tuple contains mixed types.
|
|
37
|
-
*/
|
|
38
|
-
protected getTupleType: (itemsType: string[]) => string;
|
|
39
|
-
protected getIntersectionType: (itemsType: string[]) => string;
|
|
40
|
-
protected getArrayType(arrayType: string, arrayDeep: number): string;
|
|
41
|
-
protected getLiteralStringType(value: string | number): string | number;
|
|
42
|
-
protected getMapType(keyType: string, valueType: string): string;
|
|
43
|
-
protected getRecordType(keyType: string, valueType: string): string;
|
|
44
|
-
protected transpileEnum(data: (ASTEnum | ASTNativeEnum) & ASTCommon): void;
|
|
45
|
-
protected transpileIntersection(data: ASTIntersection & ASTCommon): void;
|
|
46
|
-
protected transpileStruct(data: ASTObject & ASTCommon): void;
|
|
47
|
-
/**
|
|
48
|
-
* Transpiles a Zod union or discriminated union into a Protobuf-compatible `oneof` message.
|
|
49
|
-
*
|
|
50
|
-
* @limitations Currently supports `oneOf` for options that can be represented as a
|
|
51
|
-
* Protobuf message or enum. Other types are not yet supported.
|
|
52
|
-
* @param data The AST representation of a union or discriminated union, including its
|
|
53
|
-
* common metadata.
|
|
54
|
-
* @example
|
|
55
|
-
* Input:
|
|
56
|
-
* {
|
|
57
|
-
* name: "UserContact",
|
|
58
|
-
* options: ["EmailContact", "PhoneContact", "SocialContact"],
|
|
59
|
-
* description: "Represents different ways to contact a user."
|
|
60
|
-
* }
|
|
61
|
-
*
|
|
62
|
-
* Generated Output:
|
|
63
|
-
* message UserContact {
|
|
64
|
-
* oneof user_contact_oneof {
|
|
65
|
-
* EmailContact email_contact = 1;
|
|
66
|
-
* PhoneContact phone_contact = 2;
|
|
67
|
-
* SocialContact social_contact = 3;
|
|
68
|
-
* }
|
|
69
|
-
* }
|
|
70
|
-
*/
|
|
71
|
-
protected transpileUnion(data: (ASTUnion | ASTDiscriminatedUnion) & ASTCommon): void;
|
|
72
|
-
protected runBefore(): void;
|
|
73
|
-
protected runAfter(): void;
|
|
74
|
-
/**
|
|
75
|
-
* Adapt field name according to user input.
|
|
76
|
-
* @param fieldName
|
|
77
|
-
* @returns
|
|
78
|
-
*/
|
|
79
|
-
private _adaptField;
|
|
80
|
-
}
|
|
File without changes
|
|
File without changes
|