hono-takibi 0.2.2 → 0.3.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 +58 -58
- package/dist/config/index.d.ts +6 -6
- package/dist/config/index.js +6 -6
- package/dist/core/helper/get-variable-name-helper.js +1 -1
- package/dist/core/helper/get-variable-schema-name-helper.js +1 -1
- package/dist/core/schema/references/extract-refs.d.ts +2 -0
- package/dist/core/schema/references/extract-refs.js +26 -0
- package/dist/core/schema/references/get-ref-schema-name.d.ts +11 -0
- package/dist/core/schema/references/get-ref-schema-name.js +23 -0
- package/dist/core/schema/references/resolve-schemas-dependencies.js +45 -12
- package/dist/core/validator/is-nullable-schema.d.ts +8 -0
- package/dist/core/validator/is-nullable-schema.js +12 -0
- package/dist/core/validator/is-ref-object.d.ts +6 -0
- package/dist/core/validator/is-ref-object.js +6 -0
- package/dist/generators/hono/generate-zod-openapi-hono.js +1 -1
- package/dist/generators/openapi/components/allof/generate-allof-code.d.ts +10 -0
- package/dist/generators/openapi/components/allof/generate-allof-code.js +26 -0
- package/dist/generators/openapi/components/allof/process/process-alllof.d.ts +15 -0
- package/dist/generators/openapi/components/allof/process/process-alllof.js +23 -0
- package/dist/generators/openapi/components/anyof/generate-anyof-code.d.ts +3 -0
- package/dist/generators/openapi/components/anyof/generate-anyof-code.js +16 -0
- package/dist/generators/openapi/components/generate-components-code.js +1 -1
- package/dist/generators/openapi/components/oneof/generate-oneof-code.d.ts +3 -0
- package/dist/generators/openapi/components/oneof/generate-oneof-code.js +16 -0
- package/dist/generators/response/schemas/generate-response-schema.js +2 -2
- package/dist/generators/zod/generate-zod-partial-schema.d.ts +1 -0
- package/dist/generators/zod/{generate-partial-schema.js → generate-zod-partial-schema.js} +2 -2
- package/dist/generators/zod/generate-zod-properties-schema.js +2 -2
- package/dist/generators/zod/generate-zod-schema.js +34 -3
- package/dist/generators/zod/sub/generate-zod-schema-from-sub-schema.d.ts +10 -0
- package/dist/generators/zod/sub/generate-zod-schema-from-sub-schema.js +15 -0
- package/dist/types/index.d.ts +13 -2
- package/package.json +1 -1
- package/dist/generators/zod/generate-partial-schema.d.ts +0 -1
package/README.md
CHANGED
|
@@ -5,64 +5,7 @@
|
|
|
5
5
|

|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Configuration
|
|
12
|
-
|
|
13
|
-
You can customize the code generation behavior by creating a `hono-takibi.json` file in your project root.
|
|
14
|
-
|
|
15
|
-
### Schema Options
|
|
16
|
-
|
|
17
|
-
| Option | Type | Default | Description |
|
|
18
|
-
|--------|------|---------|-------------|
|
|
19
|
-
| `namingCase` | `"camelCase"` \| `"PascalCase"` | `"camelCase"` | Naming convention for generated schema variables |
|
|
20
|
-
| `exportEnabled` | `boolean` | `false` | When true, exports all schema definitions |
|
|
21
|
-
|
|
22
|
-
### Type Options
|
|
23
|
-
|
|
24
|
-
| Option | Type | Default | Description |
|
|
25
|
-
|--------|------|---------|-------------|
|
|
26
|
-
| `namingCase` | `"camelCase"` \| `"PascalCase"` | `"PascalCase"` | Naming convention for generated type definitions |
|
|
27
|
-
| `exportEnabled` | `boolean` | `false` | When true, exports all type definitions |
|
|
28
|
-
|
|
29
|
-
## Input and Output
|
|
30
|
-
|
|
31
|
-
You can specify input and output paths in two ways:
|
|
32
|
-
|
|
33
|
-
1. Command line arguments:
|
|
34
|
-
|
|
35
|
-
2. Configuration file (`hono-takibi.json`):
|
|
36
|
-
|
|
37
|
-
| Option | Type | Default | Description |
|
|
38
|
-
|--------|------|---------|-------------|
|
|
39
|
-
| `input` | `string` | `""` | Input file path |
|
|
40
|
-
| `output` | `string` | `""` | Output file path |
|
|
41
|
-
|
|
42
|
-
> **⚠️** When using a configuration file, command line arguments are not required. The configuration file settings take precedence over command line arguments.
|
|
43
|
-
>
|
|
44
|
-
> **🔥** When you have configured `hono-takibi.json`, you can simply run:
|
|
45
|
-
> ```bash
|
|
46
|
-
> npx hono-takibi
|
|
47
|
-
> ```
|
|
48
|
-
|
|
49
|
-
### Examples
|
|
50
|
-
|
|
51
|
-
* Default Behavior (camelCase schemas, PascalCase types)
|
|
52
|
-
|
|
53
|
-
```json
|
|
54
|
-
{
|
|
55
|
-
"input": "src/openapi/openapi.yaml",
|
|
56
|
-
"output": "src/openapi/index.ts",
|
|
57
|
-
"schemaOptions": {
|
|
58
|
-
"namingCase": "camelCase",
|
|
59
|
-
"exportEnabled": false
|
|
60
|
-
},
|
|
61
|
-
"typeOptions": {
|
|
62
|
-
"namingCase": "PascalCase",
|
|
63
|
-
"exportEnabled": false
|
|
64
|
-
}
|
|
65
|
-
}
|
|
8
|
+
npm install -D hono-takibi
|
|
66
9
|
```
|
|
67
10
|
|
|
68
11
|
## Migrate Legacy APIs to Hono
|
|
@@ -501,6 +444,63 @@ export const deletePostsIdRoute = createRoute({
|
|
|
501
444
|
})
|
|
502
445
|
```
|
|
503
446
|
|
|
447
|
+
## Configuration
|
|
448
|
+
|
|
449
|
+
You can customize the code generation behavior by creating a `hono-takibi.json` file in your project root.
|
|
450
|
+
|
|
451
|
+
### Schema Options
|
|
452
|
+
|
|
453
|
+
| Option | Type | Default | Description |
|
|
454
|
+
|--------|------|---------|-------------|
|
|
455
|
+
| `name` | `"camelCase"` \| `"PascalCase"` | `"camelCase"` | Naming convention for generated schema variables |
|
|
456
|
+
| `export` | `boolean` | `false` | When true, exports all schema definitions |
|
|
457
|
+
|
|
458
|
+
### Type Options
|
|
459
|
+
|
|
460
|
+
| Option | Type | Default | Description |
|
|
461
|
+
|--------|------|---------|-------------|
|
|
462
|
+
| `name` | `"camelCase"` \| `"PascalCase"` | `"PascalCase"` | Naming convention for generated type definitions |
|
|
463
|
+
| `export` | `boolean` | `false` | When true, exports all type definitions |
|
|
464
|
+
|
|
465
|
+
## Input and Output
|
|
466
|
+
|
|
467
|
+
You can specify input and output paths in two ways:
|
|
468
|
+
|
|
469
|
+
1. Command line arguments:
|
|
470
|
+
|
|
471
|
+
2. Configuration file (`hono-takibi.json`):
|
|
472
|
+
|
|
473
|
+
| Option | Type | Default | Description |
|
|
474
|
+
|--------|------|---------|-------------|
|
|
475
|
+
| `input` | `string` | `""` | Input file path |
|
|
476
|
+
| `output` | `string` | `""` | Output file path |
|
|
477
|
+
|
|
478
|
+
> **⚠️** When using a configuration file, command line arguments are not required. The configuration file settings take precedence over command line arguments.
|
|
479
|
+
>
|
|
480
|
+
> **🔥** When you have configured `hono-takibi.json`, you can simply run:
|
|
481
|
+
> ```bash
|
|
482
|
+
> npx hono-takibi
|
|
483
|
+
> ```
|
|
484
|
+
|
|
485
|
+
### Examples
|
|
486
|
+
|
|
487
|
+
* Default Behavior (camelCase schemas, PascalCase types)
|
|
488
|
+
|
|
489
|
+
```json
|
|
490
|
+
{
|
|
491
|
+
"input": "src/openapi/openapi.yaml",
|
|
492
|
+
"output": "src/openapi/index.ts",
|
|
493
|
+
"schema": {
|
|
494
|
+
"name": "camelCase",
|
|
495
|
+
"export": false
|
|
496
|
+
},
|
|
497
|
+
"type": {
|
|
498
|
+
"name": "PascalCase",
|
|
499
|
+
"export": false
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
```
|
|
503
|
+
|
|
504
504
|
This project is in **early development** and being maintained by a developer with about 2 years of experience. While I'm doing my best to create a useful tool:
|
|
505
505
|
|
|
506
506
|
### ⚠️ WARNING: Potential Breaking Changes Without Notice
|
package/dist/config/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export type Config = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
schema: {
|
|
3
|
+
name: 'camelCase' | 'PascalCase';
|
|
4
|
+
export: boolean;
|
|
5
5
|
};
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
type: {
|
|
7
|
+
name: 'camelCase' | 'PascalCase';
|
|
8
|
+
export: boolean;
|
|
9
9
|
};
|
|
10
10
|
input?: string;
|
|
11
11
|
output?: string;
|
package/dist/config/index.js
CHANGED
|
@@ -7,13 +7,13 @@ exports.DEFAULT_CONFIG = void 0;
|
|
|
7
7
|
exports.getConfig = getConfig;
|
|
8
8
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
9
|
exports.DEFAULT_CONFIG = {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
schema: {
|
|
11
|
+
name: 'camelCase',
|
|
12
|
+
export: false,
|
|
13
13
|
},
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
type: {
|
|
15
|
+
name: 'PascalCase',
|
|
16
|
+
export: false,
|
|
17
17
|
},
|
|
18
18
|
};
|
|
19
19
|
/**
|
|
@@ -4,6 +4,6 @@ exports.getVariableNameHelper = void 0;
|
|
|
4
4
|
const capitalize_1 = require("../text/capitalize");
|
|
5
5
|
const decapitalize_1 = require("../text/decapitalize");
|
|
6
6
|
const getVariableNameHelper = (name, config) => {
|
|
7
|
-
return config.
|
|
7
|
+
return config.type.name === 'camelCase' ? (0, decapitalize_1.decapitalize)(name) : (0, capitalize_1.capitalize)(name);
|
|
8
8
|
};
|
|
9
9
|
exports.getVariableNameHelper = getVariableNameHelper;
|
|
@@ -4,7 +4,7 @@ exports.getVariableSchemaNameHelper = void 0;
|
|
|
4
4
|
const get_camel_case_schema_name_1 = require("../schema/references/get-camel-case-schema-name");
|
|
5
5
|
const get_pascal_case_schema_name_1 = require("../schema/references/get-pascal-case-schema-name");
|
|
6
6
|
const getVariableSchemaNameHelper = (name, config) => {
|
|
7
|
-
return config.
|
|
7
|
+
return config.schema.name === 'camelCase'
|
|
8
8
|
? (0, get_camel_case_schema_name_1.getCamelCaseSchemaName)(name)
|
|
9
9
|
: (0, get_pascal_case_schema_name_1.getPascalCaseSchemaName)(name);
|
|
10
10
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractRefs = extractRefs;
|
|
4
|
+
const is_ref_object_1 = require("../../validator/is-ref-object");
|
|
5
|
+
function extractRefs(schema) {
|
|
6
|
+
const refs = [];
|
|
7
|
+
const traverse = (obj) => {
|
|
8
|
+
if (!(0, is_ref_object_1.isRefObject)(obj))
|
|
9
|
+
return;
|
|
10
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
11
|
+
if (key !== '$ref') {
|
|
12
|
+
if ((0, is_ref_object_1.isRefObject)(value)) {
|
|
13
|
+
traverse(value);
|
|
14
|
+
}
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (typeof value !== 'string')
|
|
18
|
+
continue;
|
|
19
|
+
const refParts = value.split('/');
|
|
20
|
+
const refName = refParts[refParts.length - 1];
|
|
21
|
+
refs.push(refName);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
traverse(schema);
|
|
25
|
+
return refs;
|
|
26
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Config } from '../../../config';
|
|
2
|
+
import type { Schema } from '../../../types';
|
|
3
|
+
/**
|
|
4
|
+
* Retrieves the referenced schema name from a schema object.
|
|
5
|
+
*
|
|
6
|
+
* @param schema - The schema object
|
|
7
|
+
* @param config - The configuration object
|
|
8
|
+
* @returns The referenced schema name
|
|
9
|
+
* @throws Will throw an error if the $ref property or the reference name is not found
|
|
10
|
+
*/
|
|
11
|
+
export declare function getRefSchemaName(schema: Schema, config: Config): string;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getRefSchemaName = getRefSchemaName;
|
|
4
|
+
const get_variable_schema_name_helper_1 = require("../../helper/get-variable-schema-name-helper");
|
|
5
|
+
const get_ref_name_1 = require("./get-ref-name");
|
|
6
|
+
/**
|
|
7
|
+
* Retrieves the referenced schema name from a schema object.
|
|
8
|
+
*
|
|
9
|
+
* @param schema - The schema object
|
|
10
|
+
* @param config - The configuration object
|
|
11
|
+
* @returns The referenced schema name
|
|
12
|
+
* @throws Will throw an error if the $ref property or the reference name is not found
|
|
13
|
+
*/
|
|
14
|
+
function getRefSchemaName(schema, config) {
|
|
15
|
+
if (!schema.$ref) {
|
|
16
|
+
throw new Error('refName is not found');
|
|
17
|
+
}
|
|
18
|
+
const refName = (0, get_ref_name_1.getRefName)(schema.$ref);
|
|
19
|
+
if (!refName) {
|
|
20
|
+
throw new Error('refName is not found');
|
|
21
|
+
}
|
|
22
|
+
return (0, get_variable_schema_name_helper_1.getVariableSchemaNameHelper)(refName, config);
|
|
23
|
+
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.resolveSchemasDependencies = resolveSchemasDependencies;
|
|
4
|
-
const
|
|
5
|
-
const resolve_schema_references_1 = require("./resolve-schema-references");
|
|
4
|
+
const extract_refs_1 = require("./extract-refs");
|
|
6
5
|
/**
|
|
7
6
|
* Resolves dependencies between schemas and returns them in topological order for safe processing
|
|
8
7
|
*
|
|
@@ -50,16 +49,50 @@ const resolve_schema_references_1 = require("./resolve-schema-references");
|
|
|
50
49
|
* - Uses depth-first search for dependency resolution
|
|
51
50
|
* - Automatically handles circular dependencies by preventing infinite recursion
|
|
52
51
|
*/
|
|
52
|
+
// export function resolveSchemasDependencies(schemas: Record<string, Schema>): string[] {
|
|
53
|
+
// // 1. get schema reference relations as a map
|
|
54
|
+
// const dependencies = resolveSchemaReferences(schemas)
|
|
55
|
+
// // 2. initialize ordered list and visited set
|
|
56
|
+
// const ordered: string[] = []
|
|
57
|
+
// const visited = new Set<string>()
|
|
58
|
+
// // 3. resolve schema order
|
|
59
|
+
// for (const name of Object.keys(schemas)) {
|
|
60
|
+
// resolveSchemaOrder(name, dependencies, visited, ordered)
|
|
61
|
+
// }
|
|
62
|
+
// // 4. return ordered list
|
|
63
|
+
// return ordered
|
|
64
|
+
// }
|
|
53
65
|
function resolveSchemasDependencies(schemas) {
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
const visited = {};
|
|
67
|
+
const temp = {};
|
|
68
|
+
const result = [];
|
|
69
|
+
const visit = (schemaName) => {
|
|
70
|
+
if (temp[schemaName]) {
|
|
71
|
+
throw new Error(`bad schema: ${schemaName}`);
|
|
72
|
+
}
|
|
73
|
+
if (!visited[schemaName]) {
|
|
74
|
+
temp[schemaName] = true;
|
|
75
|
+
const schema = schemas[schemaName];
|
|
76
|
+
if (schema) {
|
|
77
|
+
const refs = (0, extract_refs_1.extractRefs)(schema);
|
|
78
|
+
for (const ref of refs) {
|
|
79
|
+
if (schemas[ref]) {
|
|
80
|
+
visit(ref);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
console.warn(`not found schema: ${ref}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
visited[schemaName] = true;
|
|
88
|
+
temp[schemaName] = false;
|
|
89
|
+
result.push(schemaName);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
for (const schemaName of Object.keys(schemas)) {
|
|
93
|
+
if (!visited[schemaName]) {
|
|
94
|
+
visit(schemaName);
|
|
95
|
+
}
|
|
62
96
|
}
|
|
63
|
-
|
|
64
|
-
return ordered;
|
|
97
|
+
return result;
|
|
65
98
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Schema } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Determines whether a given sub-schema is `nullable`.
|
|
4
|
+
*
|
|
5
|
+
* @param subSchema - The sub-schema to evaluate
|
|
6
|
+
* @returns `true` if `nullable` is set to `true` and it is the only key in the schema, otherwise `false`
|
|
7
|
+
*/
|
|
8
|
+
export declare function isNullableSchema(schema: Schema): boolean;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isNullableSchema = isNullableSchema;
|
|
4
|
+
/**
|
|
5
|
+
* Determines whether a given sub-schema is `nullable`.
|
|
6
|
+
*
|
|
7
|
+
* @param subSchema - The sub-schema to evaluate
|
|
8
|
+
* @returns `true` if `nullable` is set to `true` and it is the only key in the schema, otherwise `false`
|
|
9
|
+
*/
|
|
10
|
+
function isNullableSchema(schema) {
|
|
11
|
+
return 'nullable' in schema && schema.nullable === true && Object.keys(schema).length === 1;
|
|
12
|
+
}
|
|
@@ -28,7 +28,7 @@ function generateZodOpenAPIHono(openAPISpec, config) {
|
|
|
28
28
|
// 5. generate types code
|
|
29
29
|
const typesCode = (0, generate_types_code_1.generateTypesCode)(components, config);
|
|
30
30
|
// 6. generate hono code
|
|
31
|
-
if (config.
|
|
31
|
+
if (config.type.export) {
|
|
32
32
|
return `${IMPORT_CODE}\n\n${componentsCode}\n\n${typesCode}\n\n${routeCode}`.trimEnd();
|
|
33
33
|
}
|
|
34
34
|
return `${IMPORT_CODE}\n\n${componentsCode}\n\n${routeCode}`.trimEnd();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Schema } from '../../../../types';
|
|
2
|
+
import type { Config } from '../../../../config';
|
|
3
|
+
/**
|
|
4
|
+
* Converts an `allOf` schema into a Zod schema.
|
|
5
|
+
*
|
|
6
|
+
* @param schema - The OpenAPI schema object.
|
|
7
|
+
* @param config - The configuration object.
|
|
8
|
+
* @returns The generated Zod schema as a string.
|
|
9
|
+
*/
|
|
10
|
+
export declare function generateAllOfCode(schema: Schema, config: Config): string;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateAllOfCode = generateAllOfCode;
|
|
4
|
+
const process_alllof_1 = require("./process/process-alllof");
|
|
5
|
+
/**
|
|
6
|
+
* Converts an `allOf` schema into a Zod schema.
|
|
7
|
+
*
|
|
8
|
+
* @param schema - The OpenAPI schema object.
|
|
9
|
+
* @param config - The configuration object.
|
|
10
|
+
* @returns The generated Zod schema as a string.
|
|
11
|
+
*/
|
|
12
|
+
function generateAllOfCode(schema, config) {
|
|
13
|
+
if (!schema.allOf || schema.allOf.length === 0) {
|
|
14
|
+
console.warn('not exists allOf');
|
|
15
|
+
return 'z.any()';
|
|
16
|
+
}
|
|
17
|
+
const { nullable, schemas } = (0, process_alllof_1.processAllOf)(schema.allOf, config);
|
|
18
|
+
if (schemas.length === 0) {
|
|
19
|
+
return nullable ? 'z.any().nullable()' : 'z.any()';
|
|
20
|
+
}
|
|
21
|
+
if (schemas.length === 1) {
|
|
22
|
+
return nullable ? `${schemas[0]}.nullable()` : schemas[0];
|
|
23
|
+
}
|
|
24
|
+
const intersection = `z.intersection(${schemas.join(',')})${nullable ? '.nullable()' : ''}`;
|
|
25
|
+
return intersection;
|
|
26
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Config } from '../../../../../config';
|
|
2
|
+
import type { Schema } from '../../../../../types';
|
|
3
|
+
type Accumulator = {
|
|
4
|
+
nullable: boolean;
|
|
5
|
+
schemas: string[];
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Processes the `allOf` array, separating the `nullable` flag and the array of schemas.
|
|
9
|
+
*
|
|
10
|
+
* @param allOf - The `allOf` array.
|
|
11
|
+
* @param config - The configuration object.
|
|
12
|
+
* @returns An object containing the `nullable` flag and the generated array of schemas.
|
|
13
|
+
*/
|
|
14
|
+
export declare function processAllOf(allOf: Schema[], config: Config): Accumulator;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.processAllOf = processAllOf;
|
|
4
|
+
const is_nullable_schema_1 = require("../../../../../core/validator/is-nullable-schema");
|
|
5
|
+
const generate_zod_schema_from_sub_schema_1 = require("../../../../zod/sub/generate-zod-schema-from-sub-schema");
|
|
6
|
+
/**
|
|
7
|
+
* Processes the `allOf` array, separating the `nullable` flag and the array of schemas.
|
|
8
|
+
*
|
|
9
|
+
* @param allOf - The `allOf` array.
|
|
10
|
+
* @param config - The configuration object.
|
|
11
|
+
* @returns An object containing the `nullable` flag and the generated array of schemas.
|
|
12
|
+
*/
|
|
13
|
+
function processAllOf(allOf, config) {
|
|
14
|
+
return allOf.reduce((acc, subSchema) => {
|
|
15
|
+
if ((0, is_nullable_schema_1.isNullableSchema)(subSchema)) {
|
|
16
|
+
acc.nullable = true;
|
|
17
|
+
return acc;
|
|
18
|
+
}
|
|
19
|
+
const zodSchema = (0, generate_zod_schema_from_sub_schema_1.generateZodSchemaFromSubSchema)(subSchema, config);
|
|
20
|
+
acc.schemas.push(zodSchema);
|
|
21
|
+
return acc;
|
|
22
|
+
}, { nullable: false, schemas: [] });
|
|
23
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateAnyOfCode = generateAnyOfCode;
|
|
4
|
+
const generate_zod_schema_1 = require("../../../zod/generate-zod-schema");
|
|
5
|
+
const get_ref_schema_name_1 = require("../../../../core/schema/references/get-ref-schema-name");
|
|
6
|
+
function generateAnyOfCode(schema, config) {
|
|
7
|
+
if (!schema.anyOf || schema.anyOf.length === 0) {
|
|
8
|
+
console.warn('not exists anyOf');
|
|
9
|
+
return 'z.any()';
|
|
10
|
+
}
|
|
11
|
+
const zodSchemas = schema.anyOf.map((subSchema) => {
|
|
12
|
+
subSchema.$ref ? (0, get_ref_schema_name_1.getRefSchemaName)(subSchema, config) : (0, generate_zod_schema_1.generateZodSchema)(config, subSchema);
|
|
13
|
+
return (0, generate_zod_schema_1.generateZodSchema)(config, subSchema);
|
|
14
|
+
});
|
|
15
|
+
return `z.union([${zodSchemas.join(', ')}])`;
|
|
16
|
+
}
|
|
@@ -49,7 +49,7 @@ config) {
|
|
|
49
49
|
// 5. generate export statement
|
|
50
50
|
const exports = (0, generate_schemas_export_1.generateSchemasExport)(orderedSchemas, config);
|
|
51
51
|
// 6. final code assembly
|
|
52
|
-
if (config.
|
|
52
|
+
if (config.schema.export) {
|
|
53
53
|
return `${schemaDefinitions}\n\n${exports}`;
|
|
54
54
|
}
|
|
55
55
|
return schemaDefinitions;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateOneOfCode = generateOneOfCode;
|
|
4
|
+
const generate_zod_schema_1 = require("../../../zod/generate-zod-schema");
|
|
5
|
+
const get_ref_schema_name_1 = require("../../../../core/schema/references/get-ref-schema-name");
|
|
6
|
+
function generateOneOfCode(schema, config) {
|
|
7
|
+
if (!schema.oneOf || schema.oneOf.length === 0) {
|
|
8
|
+
console.warn('not exists oneOf');
|
|
9
|
+
return 'z.any()';
|
|
10
|
+
}
|
|
11
|
+
const zodSchemas = schema.oneOf.map((subSchema) => {
|
|
12
|
+
subSchema.$ref ? (0, get_ref_schema_name_1.getRefSchemaName)(subSchema, config) : (0, generate_zod_schema_1.generateZodSchema)(config, subSchema);
|
|
13
|
+
return (0, generate_zod_schema_1.generateZodSchema)(config, subSchema);
|
|
14
|
+
});
|
|
15
|
+
return `z.union([${zodSchemas.join(',')}])`;
|
|
16
|
+
}
|
|
@@ -34,7 +34,7 @@ config) {
|
|
|
34
34
|
const response = responses[code];
|
|
35
35
|
// 2.1 no content (description only response)
|
|
36
36
|
if (!response.content)
|
|
37
|
-
return `${code}:{description:'${(0, escape_quote_1.escapeQuote)(response.description)}',},`;
|
|
37
|
+
return `${code}:{description:'${(0, escape_quote_1.escapeQuote)(response.description ?? '')}',},`;
|
|
38
38
|
// check duplication
|
|
39
39
|
const contentTypes = Object.keys(response.content);
|
|
40
40
|
const isUniqueSchema = (0, is_unique_content_schema_1.isUniqueContentSchema)(contentTypes, response.content);
|
|
@@ -46,7 +46,7 @@ config) {
|
|
|
46
46
|
const zodSchema = (0, generate_zod_property_schema_1.generatePropertySchema)(content.schema, config);
|
|
47
47
|
contentParts.push(`'${contentType}':{schema:${zodSchema}}`);
|
|
48
48
|
}
|
|
49
|
-
return `${code}:{description:'${(0, escape_quote_1.escapeQuote)(response.description)}',content:{${contentParts.join(',')}},},`;
|
|
49
|
+
return `${code}:{description:'${(0, escape_quote_1.escapeQuote)(response.description ?? '')}',content:{${contentParts.join(',')}},},`;
|
|
50
50
|
}
|
|
51
51
|
});
|
|
52
52
|
// 3.combine all response definitions
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function generateZodPartialSchema(objectProperties: string[]): string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
function
|
|
3
|
+
exports.generateZodPartialSchema = generateZodPartialSchema;
|
|
4
|
+
function generateZodPartialSchema(objectProperties) {
|
|
5
5
|
const cleanProperties = objectProperties.map((prop) => prop.replace('.optional()', ''));
|
|
6
6
|
return `z.object({${cleanProperties}}).partial()`;
|
|
7
7
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateZodPropertiesSchema = generateZodPropertiesSchema;
|
|
4
4
|
const is_all_optional_1 = require("../../core/validator/is-all-optional");
|
|
5
|
-
const
|
|
5
|
+
const generate_zod_partial_schema_1 = require("./generate-zod-partial-schema");
|
|
6
6
|
const generate_zod_property_schema_1 = require("./generate-zod-property-schema");
|
|
7
7
|
/**
|
|
8
8
|
* Generates a Zod object schema with properties and their requirements
|
|
@@ -64,7 +64,7 @@ config) {
|
|
|
64
64
|
const allOptional = (0, is_all_optional_1.isAllOptional)(objectProperties);
|
|
65
65
|
// If all properties are optional and no required properties, return partial schema
|
|
66
66
|
if (required.length === 0 && allOptional) {
|
|
67
|
-
return (0,
|
|
67
|
+
return (0, generate_zod_partial_schema_1.generateZodPartialSchema)(objectProperties);
|
|
68
68
|
}
|
|
69
69
|
return `z.object({${objectProperties}})`;
|
|
70
70
|
}
|
|
@@ -8,6 +8,10 @@ const generate_zod_record_schema_1 = require("./generate-zod-record-schema");
|
|
|
8
8
|
const is_format_string_1 = require("../../core/validator/is-format-string");
|
|
9
9
|
const generate_zod_number_schema_1 = require("./generate-zod-number-schema");
|
|
10
10
|
const generate_zod_integer_schema_1 = require("./generate-zod-integer-schema");
|
|
11
|
+
const generate_allof_code_1 = require("../openapi/components/allof/generate-allof-code");
|
|
12
|
+
const generate_anyof_code_1 = require("../openapi/components/anyof/generate-anyof-code");
|
|
13
|
+
const generate_oneof_code_1 = require("../openapi/components/oneof/generate-oneof-code");
|
|
14
|
+
const get_variable_schema_name_helper_1 = require("../../core/helper/get-variable-schema-name-helper");
|
|
11
15
|
/**
|
|
12
16
|
* Mapping of OpenAPI/JSON Schema types to Zod schema strings
|
|
13
17
|
*
|
|
@@ -98,8 +102,19 @@ function generateZodSchema(config, schema, paramName, isPath) {
|
|
|
98
102
|
if (schema.type === 'object') {
|
|
99
103
|
if (schema.additionalProperties)
|
|
100
104
|
return (0, generate_zod_record_schema_1.generateZodRecordSchema)(schema.additionalProperties, config);
|
|
101
|
-
if (
|
|
105
|
+
if (schema.allOf) {
|
|
106
|
+
return (0, generate_allof_code_1.generateAllOfCode)(schema, config);
|
|
107
|
+
}
|
|
108
|
+
if (schema.oneOf) {
|
|
109
|
+
return (0, generate_oneof_code_1.generateOneOfCode)(schema, config);
|
|
110
|
+
}
|
|
111
|
+
if (schema.anyOf) {
|
|
112
|
+
return (0, generate_anyof_code_1.generateAnyOfCode)(schema, config);
|
|
113
|
+
}
|
|
114
|
+
if (!schema.properties) {
|
|
115
|
+
// console.log(schema)
|
|
102
116
|
return 'z.object({})';
|
|
117
|
+
}
|
|
103
118
|
return (0, generate_zod_properties_schema_1.generateZodPropertiesSchema)(schema.properties, schema.required || [], config);
|
|
104
119
|
}
|
|
105
120
|
// string
|
|
@@ -145,9 +160,25 @@ function generateZodSchema(config, schema, paramName, isPath) {
|
|
|
145
160
|
// array
|
|
146
161
|
if (schema.type === 'array' && schema.items)
|
|
147
162
|
return (0, generate_zod_array_1.generateZodArray)(generateZodSchema(config, schema.items, undefined, undefined));
|
|
163
|
+
if (schema.allOf) {
|
|
164
|
+
return (0, generate_allof_code_1.generateAllOfCode)(schema, config);
|
|
165
|
+
}
|
|
166
|
+
if (schema.anyOf) {
|
|
167
|
+
return (0, generate_anyof_code_1.generateAnyOfCode)(schema, config);
|
|
168
|
+
}
|
|
169
|
+
if (schema.oneOf) {
|
|
170
|
+
return (0, generate_oneof_code_1.generateOneOfCode)(schema, config);
|
|
171
|
+
}
|
|
172
|
+
if (schema.$ref) {
|
|
173
|
+
const refParts = schema.$ref.split('/');
|
|
174
|
+
const refName = refParts[refParts.length - 1];
|
|
175
|
+
const schemaName = (0, get_variable_schema_name_helper_1.getVariableSchemaNameHelper)(refName, config);
|
|
176
|
+
return schemaName;
|
|
177
|
+
}
|
|
148
178
|
// fallback
|
|
149
|
-
if (schema.type)
|
|
179
|
+
if (schema.type) {
|
|
150
180
|
return TYPE_TO_ZOD_SCHEMA[schema.type];
|
|
151
|
-
|
|
181
|
+
}
|
|
182
|
+
console.warn(`Unknown type: ${schema.type}, ${JSON.stringify(schema)} falling back to z.any()`);
|
|
152
183
|
return 'z.any()';
|
|
153
184
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Config } from '../../../config';
|
|
2
|
+
import type { Schema } from '../../../types';
|
|
3
|
+
/**
|
|
4
|
+
* Generates a Zod schema from a sub-schema.
|
|
5
|
+
*
|
|
6
|
+
* @param subSchema - The sub-schema object.
|
|
7
|
+
* @param config - The configuration object.
|
|
8
|
+
* @returns The generated Zod schema as a string.
|
|
9
|
+
*/
|
|
10
|
+
export declare function generateZodSchemaFromSubSchema(subSchema: Schema, config: Config): string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateZodSchemaFromSubSchema = generateZodSchemaFromSubSchema;
|
|
4
|
+
const get_ref_schema_name_1 = require("../../../core/schema/references/get-ref-schema-name");
|
|
5
|
+
const generate_zod_schema_1 = require("../generate-zod-schema");
|
|
6
|
+
/**
|
|
7
|
+
* Generates a Zod schema from a sub-schema.
|
|
8
|
+
*
|
|
9
|
+
* @param subSchema - The sub-schema object.
|
|
10
|
+
* @param config - The configuration object.
|
|
11
|
+
* @returns The generated Zod schema as a string.
|
|
12
|
+
*/
|
|
13
|
+
function generateZodSchemaFromSubSchema(subSchema, config) {
|
|
14
|
+
return subSchema.$ref ? (0, get_ref_schema_name_1.getRefSchemaName)(subSchema, config) : (0, generate_zod_schema_1.generateZodSchema)(config, subSchema);
|
|
15
|
+
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -83,7 +83,7 @@ type SecurityRequirementObject = {
|
|
|
83
83
|
* Operation definition
|
|
84
84
|
*/
|
|
85
85
|
export type Operation = {
|
|
86
|
-
tags
|
|
86
|
+
tags?: string[];
|
|
87
87
|
summary?: string;
|
|
88
88
|
description?: string;
|
|
89
89
|
operationId?: string;
|
|
@@ -96,8 +96,9 @@ export type Operation = {
|
|
|
96
96
|
* Response definition with description and content
|
|
97
97
|
*/
|
|
98
98
|
export type ResponseDefinition = {
|
|
99
|
-
description
|
|
99
|
+
description?: string;
|
|
100
100
|
content?: Content;
|
|
101
|
+
$ref?: string;
|
|
101
102
|
headers?: {
|
|
102
103
|
[key: string]: {
|
|
103
104
|
description?: string;
|
|
@@ -130,6 +131,7 @@ export type Schema = {
|
|
|
130
131
|
required?: string[];
|
|
131
132
|
items?: Schema;
|
|
132
133
|
enum?: string[];
|
|
134
|
+
nullable?: boolean;
|
|
133
135
|
additionalProperties?: {
|
|
134
136
|
type: Type;
|
|
135
137
|
format: Format;
|
|
@@ -140,6 +142,15 @@ export type Schema = {
|
|
|
140
142
|
wrapped?: boolean;
|
|
141
143
|
};
|
|
142
144
|
security?: SecurityRequirementObject[];
|
|
145
|
+
oneOf?: Schema[];
|
|
146
|
+
allOf?: Schema[];
|
|
147
|
+
anyOf?: Schema[];
|
|
148
|
+
discriminator?: {
|
|
149
|
+
propertyName?: string;
|
|
150
|
+
};
|
|
151
|
+
externalDocs?: {
|
|
152
|
+
url?: string;
|
|
153
|
+
};
|
|
143
154
|
};
|
|
144
155
|
/**
|
|
145
156
|
* Components section of OpenAPI spec
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function generatePartialSchema(objectProperties: string[]): string;
|