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.
Files changed (34) hide show
  1. package/README.md +58 -58
  2. package/dist/config/index.d.ts +6 -6
  3. package/dist/config/index.js +6 -6
  4. package/dist/core/helper/get-variable-name-helper.js +1 -1
  5. package/dist/core/helper/get-variable-schema-name-helper.js +1 -1
  6. package/dist/core/schema/references/extract-refs.d.ts +2 -0
  7. package/dist/core/schema/references/extract-refs.js +26 -0
  8. package/dist/core/schema/references/get-ref-schema-name.d.ts +11 -0
  9. package/dist/core/schema/references/get-ref-schema-name.js +23 -0
  10. package/dist/core/schema/references/resolve-schemas-dependencies.js +45 -12
  11. package/dist/core/validator/is-nullable-schema.d.ts +8 -0
  12. package/dist/core/validator/is-nullable-schema.js +12 -0
  13. package/dist/core/validator/is-ref-object.d.ts +6 -0
  14. package/dist/core/validator/is-ref-object.js +6 -0
  15. package/dist/generators/hono/generate-zod-openapi-hono.js +1 -1
  16. package/dist/generators/openapi/components/allof/generate-allof-code.d.ts +10 -0
  17. package/dist/generators/openapi/components/allof/generate-allof-code.js +26 -0
  18. package/dist/generators/openapi/components/allof/process/process-alllof.d.ts +15 -0
  19. package/dist/generators/openapi/components/allof/process/process-alllof.js +23 -0
  20. package/dist/generators/openapi/components/anyof/generate-anyof-code.d.ts +3 -0
  21. package/dist/generators/openapi/components/anyof/generate-anyof-code.js +16 -0
  22. package/dist/generators/openapi/components/generate-components-code.js +1 -1
  23. package/dist/generators/openapi/components/oneof/generate-oneof-code.d.ts +3 -0
  24. package/dist/generators/openapi/components/oneof/generate-oneof-code.js +16 -0
  25. package/dist/generators/response/schemas/generate-response-schema.js +2 -2
  26. package/dist/generators/zod/generate-zod-partial-schema.d.ts +1 -0
  27. package/dist/generators/zod/{generate-partial-schema.js → generate-zod-partial-schema.js} +2 -2
  28. package/dist/generators/zod/generate-zod-properties-schema.js +2 -2
  29. package/dist/generators/zod/generate-zod-schema.js +34 -3
  30. package/dist/generators/zod/sub/generate-zod-schema-from-sub-schema.d.ts +10 -0
  31. package/dist/generators/zod/sub/generate-zod-schema-from-sub-schema.js +15 -0
  32. package/dist/types/index.d.ts +13 -2
  33. package/package.json +1 -1
  34. package/dist/generators/zod/generate-partial-schema.d.ts +0 -1
package/README.md CHANGED
@@ -5,64 +5,7 @@
5
5
  ![img](https://raw.githubusercontent.com/nakita628/hono-takibi/refs/heads/main/assets/img/hono-takibi.png)
6
6
 
7
7
  ```bash
8
- npm add -D hono-takibi
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
@@ -1,11 +1,11 @@
1
1
  export type Config = {
2
- schemaOptions: {
3
- namingCase: 'camelCase' | 'PascalCase';
4
- exportEnabled: boolean;
2
+ schema: {
3
+ name: 'camelCase' | 'PascalCase';
4
+ export: boolean;
5
5
  };
6
- typeOptions: {
7
- namingCase: 'camelCase' | 'PascalCase';
8
- exportEnabled: boolean;
6
+ type: {
7
+ name: 'camelCase' | 'PascalCase';
8
+ export: boolean;
9
9
  };
10
10
  input?: string;
11
11
  output?: string;
@@ -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
- schemaOptions: {
11
- namingCase: 'camelCase',
12
- exportEnabled: false,
10
+ schema: {
11
+ name: 'camelCase',
12
+ export: false,
13
13
  },
14
- typeOptions: {
15
- namingCase: 'PascalCase',
16
- exportEnabled: false,
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.typeOptions.namingCase === 'camelCase' ? (0, decapitalize_1.decapitalize)(name) : (0, capitalize_1.capitalize)(name);
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.schemaOptions.namingCase === 'camelCase'
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,2 @@
1
+ import type { Schema } from '../../../types';
2
+ export declare function extractRefs(schema: Schema): string[];
@@ -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 resolve_schema_order_1 = require("./resolve-schema-order");
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
- // 1. get schema reference relations as a map
55
- const dependencies = (0, resolve_schema_references_1.resolveSchemaReferences)(schemas);
56
- // 2. initialize ordered list and visited set
57
- const ordered = [];
58
- const visited = new Set();
59
- // 3. resolve schema order
60
- for (const name of Object.keys(schemas)) {
61
- (0, resolve_schema_order_1.resolveSchemaOrder)(name, dependencies, visited, ordered);
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
- // 4. return ordered list
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
+ }
@@ -0,0 +1,6 @@
1
+ type RefObject = {
2
+ $ref?: string;
3
+ [key: string]: unknown;
4
+ };
5
+ export declare function isRefObject(value: unknown): value is RefObject;
6
+ export {};
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isRefObject = isRefObject;
4
+ function isRefObject(value) {
5
+ return typeof value === 'object' && value !== null;
6
+ }
@@ -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.typeOptions.exportEnabled) {
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,3 @@
1
+ import type { Schema } from '../../../../types';
2
+ import type { Config } from '../../../../config';
3
+ export declare function generateAnyOfCode(schema: Schema, config: Config): string;
@@ -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.schemaOptions.exportEnabled) {
52
+ if (config.schema.export) {
53
53
  return `${schemaDefinitions}\n\n${exports}`;
54
54
  }
55
55
  return schemaDefinitions;
@@ -0,0 +1,3 @@
1
+ import type { Schema } from '../../../../types';
2
+ import type { Config } from '../../../../config';
3
+ export declare function generateOneOfCode(schema: Schema, config: Config): string;
@@ -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.generatePartialSchema = generatePartialSchema;
4
- function generatePartialSchema(objectProperties) {
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 generate_partial_schema_1 = require("./generate-partial-schema");
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, generate_partial_schema_1.generatePartialSchema)(objectProperties);
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 (!schema.properties)
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
- console.warn(`Unknown type: ${schema.type}, falling back to z.any()`);
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
+ }
@@ -83,7 +83,7 @@ type SecurityRequirementObject = {
83
83
  * Operation definition
84
84
  */
85
85
  export type Operation = {
86
- tags: string[];
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: string;
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,7 +1,7 @@
1
1
  {
2
2
  "name": "hono-takibi",
3
3
  "description": "Hono Takibi is a CLI tool that generates Hono routes from OpenAPI specifications.",
4
- "version": "0.2.2",
4
+ "version": "0.3.0",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "hono",
@@ -1 +0,0 @@
1
- export declare function generatePartialSchema(objectProperties: string[]): string;