hono-takibi 0.1.5 → 0.2.1
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 +24 -6
- package/dist/config/index.d.ts +17 -0
- package/dist/config/index.js +29 -0
- package/dist/core/schema/references/get-pascal-case-schema-name.d.ts +8 -0
- package/dist/core/schema/references/get-pascal-case-schema-name.js +15 -0
- package/dist/generators/hono/generate-zod-openapi-hono.d.ts +2 -1
- package/dist/generators/hono/generate-zod-openapi-hono.js +10 -4
- package/dist/generators/openapi/components/generate-components-code.d.ts +1 -1
- package/dist/generators/openapi/components/generate-components-code.js +13 -7
- package/dist/generators/openapi/paths/generate-route-code.d.ts +1 -1
- package/dist/generators/openapi/paths/generate-route-code.js +2 -2
- package/dist/generators/openapi/paths/generate-route.d.ts +1 -1
- package/dist/generators/openapi/paths/generate-route.js +3 -3
- package/dist/generators/openapi/paths/generate-schemas-export.d.ts +1 -1
- package/dist/generators/openapi/paths/generate-schemas-export.js +10 -3
- package/dist/generators/request/params/generate-params-object.d.ts +1 -1
- package/dist/generators/request/params/generate-params-object.js +3 -3
- package/dist/generators/request/params/generate-request-parameter.d.ts +1 -1
- package/dist/generators/request/params/generate-request-parameter.js +3 -3
- package/dist/generators/response/schemas/generate-response-schema.d.ts +1 -1
- package/dist/generators/response/schemas/generate-response-schema.js +2 -2
- package/dist/generators/types/generate-types-code.d.ts +3 -0
- package/dist/generators/types/generate-types-code.js +35 -0
- package/dist/generators/zod/generate-zod-infer.d.ts +8 -0
- package/dist/generators/zod/generate-zod-infer.js +20 -0
- package/dist/generators/zod/generate-zod-properties-schema.d.ts +1 -1
- package/dist/generators/zod/generate-zod-properties-schema.js +9 -4
- package/dist/generators/zod/generate-zod-property-schema.d.ts +1 -1
- package/dist/generators/zod/generate-zod-property-schema.js +12 -6
- package/dist/generators/zod/generate-zod-schema.d.ts +1 -1
- package/dist/generators/zod/generate-zod-schema.js +37 -39
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,6 +8,29 @@
|
|
|
8
8
|
npm add -D hono-takibi
|
|
9
9
|
```
|
|
10
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
|
+
|
|
16
|
+
### Schema Options
|
|
17
|
+
|
|
18
|
+
| Option | Type | Default | Description |
|
|
19
|
+
|--------|------|---------|-------------|
|
|
20
|
+
| `namingCase` | `"camelCase"` \| `"PascalCase"` | `"camelCase"` | Naming convention for generated schema variables |
|
|
21
|
+
| `exportEnabled` | `boolean` | `false` | When true, exports all schema definitions |
|
|
22
|
+
|
|
23
|
+
### Type Options
|
|
24
|
+
|
|
25
|
+
| Option | Type | Default | Description |
|
|
26
|
+
|--------|------|---------|-------------|
|
|
27
|
+
| `namingCase` | `"camelCase"` \| `"PascalCase"` | `"PascalCase"` | Naming convention for generated type definitions |
|
|
28
|
+
| `exportEnabled` | `boolean` | `false` | When true, exports all type definitions |
|
|
29
|
+
|
|
30
|
+
### Examples
|
|
31
|
+
|
|
32
|
+
#### Default Behavior (camelCase schemas, PascalCase types)
|
|
33
|
+
|
|
11
34
|
## Migrate Legacy APIs to Hono
|
|
12
35
|
|
|
13
36
|
**Hono Takibi** is an OpenAPI-to-Hono code generator, specifically developed to assist in migrating APIs from various programming languages to Hono. This tool automates the creation of type-safe Hono routes from your existing OpenAPI specifications, making it easier to transition from legacy systems (Ruby, Perl, PHP, etc.) to a modern Hono architecture.
|
|
@@ -465,12 +488,7 @@ We welcome feedback and contributions to improve the tool!
|
|
|
465
488
|
|
|
466
489
|
### Current Limitations
|
|
467
490
|
|
|
468
|
-
|
|
469
|
-
- Only generates camelCase schema names
|
|
470
|
-
- Example: `Post` in OpenAPI becomes `postSchema` in generated code
|
|
471
|
-
- No support for custom naming conventions yet
|
|
472
|
-
|
|
473
|
-
2. **OpenAPI Support**
|
|
491
|
+
**OpenAPI Support**
|
|
474
492
|
- Not all OpenAPI features are supported
|
|
475
493
|
- Complex schemas might not convert correctly
|
|
476
494
|
- Limited support for certain response types
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type Config = {
|
|
2
|
+
schemaOptions: {
|
|
3
|
+
namingCase: 'camelCase' | 'PascalCase';
|
|
4
|
+
exportEnabled: boolean;
|
|
5
|
+
};
|
|
6
|
+
typeOptions: {
|
|
7
|
+
namingCase: 'camelCase' | 'PascalCase';
|
|
8
|
+
exportEnabled: boolean;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export declare const DEFAULT_CONFIG: Config;
|
|
12
|
+
/**
|
|
13
|
+
* Loads the configuration from the `hono-takibi.json` file or returns the default configuration.
|
|
14
|
+
*
|
|
15
|
+
* @returns The configuration object.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getConfig(): Config;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DEFAULT_CONFIG = void 0;
|
|
7
|
+
exports.getConfig = getConfig;
|
|
8
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
|
+
exports.DEFAULT_CONFIG = {
|
|
10
|
+
schemaOptions: {
|
|
11
|
+
namingCase: 'camelCase',
|
|
12
|
+
exportEnabled: false,
|
|
13
|
+
},
|
|
14
|
+
typeOptions: {
|
|
15
|
+
namingCase: 'PascalCase',
|
|
16
|
+
exportEnabled: false,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Loads the configuration from the `hono-takibi.json` file or returns the default configuration.
|
|
21
|
+
*
|
|
22
|
+
* @returns The configuration object.
|
|
23
|
+
*/
|
|
24
|
+
function getConfig() {
|
|
25
|
+
const config = node_fs_1.default.existsSync('hono-takibi.json')
|
|
26
|
+
? { ...exports.DEFAULT_CONFIG, ...JSON.parse(node_fs_1.default.readFileSync('hono-takibi.json', 'utf-8')) }
|
|
27
|
+
: exports.DEFAULT_CONFIG;
|
|
28
|
+
return config;
|
|
29
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates a PascalCase schema name from a given schema name.
|
|
3
|
+
*
|
|
4
|
+
* @function getPascalCaseSchemaName
|
|
5
|
+
* @param schemaName - The original schema name.
|
|
6
|
+
* @returns The PascalCase schema name.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getPascalCaseSchemaName(schemaName: string): string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getPascalCaseSchemaName = getPascalCaseSchemaName;
|
|
4
|
+
const capitalize_1 = require("../../text/capitalize");
|
|
5
|
+
/**
|
|
6
|
+
* Generates a PascalCase schema name from a given schema name.
|
|
7
|
+
*
|
|
8
|
+
* @function getPascalCaseSchemaName
|
|
9
|
+
* @param schemaName - The original schema name.
|
|
10
|
+
* @returns The PascalCase schema name.
|
|
11
|
+
*/
|
|
12
|
+
function getPascalCaseSchemaName(schemaName) {
|
|
13
|
+
const capitalizedSchemaName = (0, capitalize_1.capitalize)(schemaName);
|
|
14
|
+
return `${capitalizedSchemaName}Schema`;
|
|
15
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Config } from '../../config';
|
|
1
2
|
import type { OpenAPISpec } from '../../types';
|
|
2
3
|
/**
|
|
3
4
|
* Generates TypeScript code from OpenAPI specification for Hono/zod-openapi
|
|
@@ -6,4 +7,4 @@ import type { OpenAPISpec } from '../../types';
|
|
|
6
7
|
* @param openAPISpec - OpenAPI specification object containing components and paths
|
|
7
8
|
* @returns Generated TypeScript code
|
|
8
9
|
*/
|
|
9
|
-
export declare function generateZodOpenAPIHono(openAPISpec: OpenAPISpec): string;
|
|
10
|
+
export declare function generateZodOpenAPIHono(openAPISpec: OpenAPISpec, config: Config): string;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.generateZodOpenAPIHono = generateZodOpenAPIHono;
|
|
4
4
|
const generate_components_code_1 = require("../openapi/components/generate-components-code");
|
|
5
5
|
const generate_route_code_1 = require("../openapi/paths/generate-route-code");
|
|
6
|
+
const generate_types_code_1 = require("../types/generate-types-code");
|
|
6
7
|
/**
|
|
7
8
|
* Import statement for Hono's zod-openapi package
|
|
8
9
|
* @constant
|
|
@@ -15,15 +16,20 @@ const IMPORT_CODE = "import { createRoute, z } from '@hono/zod-openapi';";
|
|
|
15
16
|
* @param openAPISpec - OpenAPI specification object containing components and paths
|
|
16
17
|
* @returns Generated TypeScript code
|
|
17
18
|
*/
|
|
18
|
-
function generateZodOpenAPIHono(openAPISpec) {
|
|
19
|
+
function generateZodOpenAPIHono(openAPISpec, config) {
|
|
19
20
|
// 1. get components
|
|
20
21
|
const components = openAPISpec.components;
|
|
21
22
|
// 2. get paths
|
|
22
23
|
const { paths } = openAPISpec;
|
|
23
24
|
// 3. generate components code
|
|
24
|
-
const componentsCode = (0, generate_components_code_1.generateComponentsCode)(components);
|
|
25
|
+
const componentsCode = (0, generate_components_code_1.generateComponentsCode)(components, config.schemaOptions.namingCase, config.schemaOptions.exportEnabled);
|
|
25
26
|
// 4. generate route code
|
|
26
|
-
const routeCode = (0, generate_route_code_1.generateRouteCode)(paths);
|
|
27
|
-
// 5. generate
|
|
27
|
+
const routeCode = (0, generate_route_code_1.generateRouteCode)(paths, config.schemaOptions.namingCase);
|
|
28
|
+
// 5. generate types code
|
|
29
|
+
const typesCode = (0, generate_types_code_1.generateTypesCode)(components, config);
|
|
30
|
+
// 6. generate hono code
|
|
31
|
+
if (config.typeOptions.exportEnabled) {
|
|
32
|
+
return `${IMPORT_CODE}\n\n${componentsCode}\n\n${typesCode}\n\n${routeCode}`.trimEnd();
|
|
33
|
+
}
|
|
28
34
|
return `${IMPORT_CODE}\n\n${componentsCode}\n\n${routeCode}`.trimEnd();
|
|
29
35
|
}
|
|
@@ -15,4 +15,4 @@ import type { Components } from '../../../types';
|
|
|
15
15
|
* 5. Creates exports for all schemas
|
|
16
16
|
* 6. Returns the complete code with proper ordering to avoid reference errors
|
|
17
17
|
*/
|
|
18
|
-
export declare function generateComponentsCode(components: Components): string;
|
|
18
|
+
export declare function generateComponentsCode(components: Components, namingCase?: 'camelCase' | 'PascalCase', exportEnabled?: boolean): string;
|
|
@@ -6,6 +6,7 @@ const generate_zod_schema_1 = require("../../../generators/zod/generate-zod-sche
|
|
|
6
6
|
const resolve_schemas_dependencies_1 = require("../../../core/schema/references/resolve-schemas-dependencies");
|
|
7
7
|
const get_camel_case_schema_name_1 = require("../../../core/schema/references/get-camel-case-schema-name");
|
|
8
8
|
const generate_schemas_export_1 = require("../paths/generate-schemas-export");
|
|
9
|
+
const get_pascal_case_schema_name_1 = require("../../../core/schema/references/get-pascal-case-schema-name");
|
|
9
10
|
/**
|
|
10
11
|
* Generates TypeScript code for OpenAPI components, converting them to Zod schemas.
|
|
11
12
|
* If no schemas are present, returns an empty string.
|
|
@@ -22,7 +23,7 @@ const generate_schemas_export_1 = require("../paths/generate-schemas-export");
|
|
|
22
23
|
* 5. Creates exports for all schemas
|
|
23
24
|
* 6. Returns the complete code with proper ordering to avoid reference errors
|
|
24
25
|
*/
|
|
25
|
-
function generateComponentsCode(components) {
|
|
26
|
+
function generateComponentsCode(components, namingCase = 'camelCase', exportEnabled = true) {
|
|
26
27
|
// 1. schema extraction
|
|
27
28
|
const { schemas } = components;
|
|
28
29
|
// 2. resolve schema dependencies to obtain proper ordering
|
|
@@ -36,16 +37,21 @@ function generateComponentsCode(components) {
|
|
|
36
37
|
.map((schemaName) => {
|
|
37
38
|
// 4.1 get schema definition corresponding to schema name
|
|
38
39
|
const schema = schemas[schemaName];
|
|
39
|
-
// 4.2 get
|
|
40
|
-
const
|
|
40
|
+
// 4.2 get variable name
|
|
41
|
+
const variableName = namingCase === 'camelCase'
|
|
42
|
+
? (0, get_camel_case_schema_name_1.getCamelCaseSchemaName)(schemaName)
|
|
43
|
+
: (0, get_pascal_case_schema_name_1.getPascalCaseSchemaName)(schemaName);
|
|
41
44
|
// 4.3 generate zod schema
|
|
42
|
-
const zodSchema = (0, generate_zod_schema_1.generateZodSchema)(schema);
|
|
45
|
+
const zodSchema = (0, generate_zod_schema_1.generateZodSchema)(schema, undefined, undefined, namingCase);
|
|
43
46
|
// 4.4 generate zod schema definition
|
|
44
|
-
return (0, generate_zod_schema_definition_1.generateZodSchemaDefinition)(
|
|
47
|
+
return (0, generate_zod_schema_definition_1.generateZodSchemaDefinition)(variableName, zodSchema, schemaName);
|
|
45
48
|
})
|
|
46
49
|
.join('\n\n');
|
|
47
50
|
// 5. generate export statement
|
|
48
|
-
const exports = (0, generate_schemas_export_1.generateSchemasExport)(orderedSchemas);
|
|
51
|
+
const exports = (0, generate_schemas_export_1.generateSchemasExport)(orderedSchemas, namingCase);
|
|
49
52
|
// 6. final code assembly
|
|
50
|
-
|
|
53
|
+
if (exportEnabled) {
|
|
54
|
+
return `${schemaDefinitions}\n\n${exports}`;
|
|
55
|
+
}
|
|
56
|
+
return schemaDefinitions;
|
|
51
57
|
}
|
|
@@ -18,4 +18,4 @@ import type { OpenAPIPaths } from '../../../types';
|
|
|
18
18
|
* - Generates type-safe route handlers using zod validation
|
|
19
19
|
* - Combines all routes with proper spacing
|
|
20
20
|
*/
|
|
21
|
-
export declare function generateRouteCode(openAPIPaths: OpenAPIPaths): string;
|
|
21
|
+
export declare function generateRouteCode(openAPIPaths: OpenAPIPaths, namingCase?: 'camelCase' | 'PascalCase'): string;
|
|
@@ -23,7 +23,7 @@ const is_operation_1 = require("../../../core/validator/is-operation");
|
|
|
23
23
|
* - Generates type-safe route handlers using zod validation
|
|
24
24
|
* - Combines all routes with proper spacing
|
|
25
25
|
*/
|
|
26
|
-
function generateRouteCode(openAPIPaths) {
|
|
26
|
+
function generateRouteCode(openAPIPaths, namingCase = 'camelCase') {
|
|
27
27
|
const routes = [];
|
|
28
28
|
// 1. flattening and processing OpenAPI paths
|
|
29
29
|
for (const [path, pathItem] of Object.entries(openAPIPaths)) {
|
|
@@ -45,7 +45,7 @@ function generateRouteCode(openAPIPaths) {
|
|
|
45
45
|
if (!(0, is_operation_1.isOperation)(pathItemValue))
|
|
46
46
|
continue;
|
|
47
47
|
// 3.5 generating the root code and adding it to the array
|
|
48
|
-
routes.push((0, generate_route_1.generateRoute)(path, method, pathItemValue));
|
|
48
|
+
routes.push((0, generate_route_1.generateRoute)(path, method, pathItemValue, namingCase));
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
// 4. exclude invalid routes and join them with a newline
|
|
@@ -21,4 +21,4 @@ import type { Operation } from '../../../types';
|
|
|
21
21
|
* - Handles optional parameters appropriately
|
|
22
22
|
* - Integrates with Hono's createRoute function
|
|
23
23
|
*/
|
|
24
|
-
export declare function generateRoute(path: string, method: string, operation: Operation): string;
|
|
24
|
+
export declare function generateRoute(path: string, method: string, operation: Operation, namingCase: 'camelCase' | 'PascalCase'): string;
|
|
@@ -28,11 +28,11 @@ const escape_quote_1 = require("../../../core/text/escape-quote");
|
|
|
28
28
|
* - Handles optional parameters appropriately
|
|
29
29
|
* - Integrates with Hono's createRoute function
|
|
30
30
|
*/
|
|
31
|
-
function generateRoute(path, method, operation) {
|
|
31
|
+
function generateRoute(path, method, operation, namingCase) {
|
|
32
32
|
const { tags, summary, description, security, parameters, requestBody, responses } = operation;
|
|
33
33
|
const routeName = (0, generate_route_name_1.generateRouteName)(method, path);
|
|
34
34
|
const tagList = tags ? JSON.stringify(tags) : '[]';
|
|
35
|
-
const requestParams = (0, generate_request_parameter_1.generateRequestParameter)(parameters, requestBody);
|
|
35
|
+
const requestParams = (0, generate_request_parameter_1.generateRequestParameter)(parameters, requestBody, namingCase);
|
|
36
36
|
const create_args = {
|
|
37
37
|
routeName,
|
|
38
38
|
tagsCode: `tags:${tagList},`,
|
|
@@ -42,7 +42,7 @@ function generateRoute(path, method, operation) {
|
|
|
42
42
|
descriptionCode: description ? `description:'${(0, escape_quote_1.escapeQuote)(description)}',` : '',
|
|
43
43
|
securityCode: security ? `security:${JSON.stringify(security)},` : '',
|
|
44
44
|
requestParams: requestParams ? `${requestParams}` : '',
|
|
45
|
-
responsesCode: responses ? `responses:{${(0, generate_response_schema_1.generateResponseSchema)(responses)}}` : '',
|
|
45
|
+
responsesCode: responses ? `responses:{${(0, generate_response_schema_1.generateResponseSchema)(responses, namingCase)}}` : '',
|
|
46
46
|
};
|
|
47
47
|
return (0, generate_create_route_1.generateCreateRoute)(create_args);
|
|
48
48
|
}
|
|
@@ -8,4 +8,4 @@
|
|
|
8
8
|
* @example
|
|
9
9
|
* // Returns: 'export const schemas = { userSchema, postSchema }'
|
|
10
10
|
*/
|
|
11
|
-
export declare function generateSchemasExport(orderedSchemas: string[]): string;
|
|
11
|
+
export declare function generateSchemasExport(orderedSchemas: string[], namingCase?: 'camelCase' | 'PascalCase'): string | undefined;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateSchemasExport = generateSchemasExport;
|
|
4
4
|
const get_camel_case_schema_name_1 = require("../../../core/schema/references/get-camel-case-schema-name");
|
|
5
|
+
const get_pascal_case_schema_name_1 = require("../../../core/schema/references/get-pascal-case-schema-name");
|
|
5
6
|
/**
|
|
6
7
|
* Generates a TypeScript export for a list of schema names
|
|
7
8
|
*
|
|
@@ -12,7 +13,13 @@ const get_camel_case_schema_name_1 = require("../../../core/schema/references/ge
|
|
|
12
13
|
* @example
|
|
13
14
|
* // Returns: 'export const schemas = { userSchema, postSchema }'
|
|
14
15
|
*/
|
|
15
|
-
function generateSchemasExport(orderedSchemas) {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
function generateSchemasExport(orderedSchemas, namingCase = 'camelCase') {
|
|
17
|
+
if (namingCase === 'camelCase') {
|
|
18
|
+
const camelCaseSchemas = orderedSchemas.map((schemaName) => (0, get_camel_case_schema_name_1.getCamelCaseSchemaName)(schemaName));
|
|
19
|
+
return `export const schemas = {\n${camelCaseSchemas.join(',\n')}\n}`;
|
|
20
|
+
}
|
|
21
|
+
if (namingCase === 'PascalCase') {
|
|
22
|
+
const pascalCaseSchemas = orderedSchemas.map((schemaName) => (0, get_pascal_case_schema_name_1.getPascalCaseSchemaName)(schemaName));
|
|
23
|
+
return `export const schemas = {\n${pascalCaseSchemas.join(',\n')}\n}`;
|
|
24
|
+
}
|
|
18
25
|
}
|
|
@@ -12,4 +12,4 @@ import type { ParamsObject, Parameters } from '../../../types';
|
|
|
12
12
|
* - Organizes parameters into appropriate objects based on their location
|
|
13
13
|
* - Maintains empty objects for unused parameter locations
|
|
14
14
|
*/
|
|
15
|
-
export declare function generateParamsObject(parameters: Parameters[]): ParamsObject;
|
|
15
|
+
export declare function generateParamsObject(parameters: Parameters[], namingCase?: 'camelCase' | 'PascalCase'): ParamsObject;
|
|
@@ -16,13 +16,13 @@ const generate_zod_schema_1 = require("../../zod/generate-zod-schema");
|
|
|
16
16
|
* - Organizes parameters into appropriate objects based on their location
|
|
17
17
|
* - Maintains empty objects for unused parameter locations
|
|
18
18
|
*/
|
|
19
|
-
function generateParamsObject(parameters) {
|
|
19
|
+
function generateParamsObject(parameters, namingCase = 'camelCase') {
|
|
20
20
|
return parameters.reduce((acc, param) => {
|
|
21
21
|
const optionalSuffix = param.required ? '' : '.optional()';
|
|
22
22
|
// path params are generated with the param name
|
|
23
23
|
const baseSchema = param.in === 'path'
|
|
24
|
-
? (0, generate_zod_schema_1.generateZodSchema)(param.schema, param.name, true)
|
|
25
|
-
: (0, generate_zod_schema_1.generateZodSchema)(param.schema);
|
|
24
|
+
? (0, generate_zod_schema_1.generateZodSchema)(param.schema, param.name, true, namingCase)
|
|
25
|
+
: (0, generate_zod_schema_1.generateZodSchema)(param.schema, namingCase);
|
|
26
26
|
// Initialize section if it doesn't exist
|
|
27
27
|
if (!acc[param.in]) {
|
|
28
28
|
acc[param.in] = {};
|
|
@@ -19,4 +19,4 @@ import type { Parameters, RequestBody } from '../../../types';
|
|
|
19
19
|
* - Properly combines parameters and body when both are present
|
|
20
20
|
* - Handles schema references and inline schemas
|
|
21
21
|
*/
|
|
22
|
-
export declare function generateRequestParameter(parameters: Parameters[] | undefined, requestBody: RequestBody | undefined): string;
|
|
22
|
+
export declare function generateRequestParameter(parameters: Parameters[] | undefined, requestBody: RequestBody | undefined, namingCase?: 'camelCase' | 'PascalCase'): string;
|
|
@@ -28,7 +28,7 @@ const generate_zod_property_schema_1 = require("../../zod/generate-zod-property-
|
|
|
28
28
|
* - Properly combines parameters and body when both are present
|
|
29
29
|
* - Handles schema references and inline schemas
|
|
30
30
|
*/
|
|
31
|
-
function generateRequestParameter(parameters, requestBody) {
|
|
31
|
+
function generateRequestParameter(parameters, requestBody, namingCase = 'camelCase') {
|
|
32
32
|
// Early return if no parameters or content
|
|
33
33
|
if (!(parameters || requestBody?.content)) {
|
|
34
34
|
return '';
|
|
@@ -36,7 +36,7 @@ function generateRequestParameter(parameters, requestBody) {
|
|
|
36
36
|
const requestBodyContentTypes = Object.keys(requestBody?.content || {});
|
|
37
37
|
const params = parameters
|
|
38
38
|
? (() => {
|
|
39
|
-
const paramsObj = (0, generate_params_object_1.generateParamsObject)(parameters);
|
|
39
|
+
const paramsObj = (0, generate_params_object_1.generateParamsObject)(parameters, namingCase);
|
|
40
40
|
const requestParamsArr = (0, generate_request_params_array_1.generateRequestParamsArray)(paramsObj);
|
|
41
41
|
return requestParamsArr.length ? (0, generate_format_request_object_1.generateFormatRequestObject)(requestParamsArr) : '';
|
|
42
42
|
})()
|
|
@@ -46,7 +46,7 @@ function generateRequestParameter(parameters, requestBody) {
|
|
|
46
46
|
const uniqueSchemas = new Map();
|
|
47
47
|
for (const contentType of requestBodyContentTypes) {
|
|
48
48
|
const { schema } = requestBody.content[contentType];
|
|
49
|
-
const zodSchema = (0, generate_zod_property_schema_1.generatePropertySchema)(schema);
|
|
49
|
+
const zodSchema = (0, generate_zod_property_schema_1.generatePropertySchema)(schema, namingCase);
|
|
50
50
|
uniqueSchemas.set(zodSchema, zodSchema);
|
|
51
51
|
}
|
|
52
52
|
const request_body_required = requestBody.required ?? false;
|
|
@@ -19,4 +19,4 @@ import type { Responses } from '../../../types';
|
|
|
19
19
|
* - Handles nested schema structures
|
|
20
20
|
* - Automatically resolves schema references
|
|
21
21
|
*/
|
|
22
|
-
export declare function generateResponseSchema(responses: Responses): string;
|
|
22
|
+
export declare function generateResponseSchema(responses: Responses, namingCase?: 'camelCase' | 'PascalCase'): string;
|
|
@@ -24,7 +24,7 @@ const generate_zod_property_schema_1 = require("../../zod/generate-zod-property-
|
|
|
24
24
|
* - Handles nested schema structures
|
|
25
25
|
* - Automatically resolves schema references
|
|
26
26
|
*/
|
|
27
|
-
function generateResponseSchema(responses) {
|
|
27
|
+
function generateResponseSchema(responses, namingCase = 'camelCase') {
|
|
28
28
|
// 1. get response codes (200, 404, etc.)
|
|
29
29
|
const responseCodes = Object.keys(responses);
|
|
30
30
|
// 2. processing for each response code
|
|
@@ -41,7 +41,7 @@ function generateResponseSchema(responses) {
|
|
|
41
41
|
const contentParts = [];
|
|
42
42
|
for (const contentType of contentTypes) {
|
|
43
43
|
const content = response.content[contentType];
|
|
44
|
-
const zodSchema = (0, generate_zod_property_schema_1.generatePropertySchema)(content.schema);
|
|
44
|
+
const zodSchema = (0, generate_zod_property_schema_1.generatePropertySchema)(content.schema, namingCase);
|
|
45
45
|
contentParts.push(`'${contentType}':{schema:${zodSchema}}`);
|
|
46
46
|
}
|
|
47
47
|
return `${code}:{description:'${(0, escape_quote_1.escapeQuote)(response.description)}',content:{${contentParts.join(',')}},},`;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// import { resolveSchemasDependencies } from "../../core/schema/references/resolve-schemas-dependencies";
|
|
3
|
+
// import type { Components } from "../../types";
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.generateTypesCode = generateTypesCode;
|
|
6
|
+
// export function generateTypesCode(components: Components) {
|
|
7
|
+
// // 1. schema extraction
|
|
8
|
+
// const { schemas } = components
|
|
9
|
+
// // 2. resolve schema dependencies to obtain proper ordering
|
|
10
|
+
// const orderedSchemas = resolveSchemasDependencies(schemas)
|
|
11
|
+
// // 3. if there are no schemas, return an empty string
|
|
12
|
+
// if (orderedSchemas.length === 0) {
|
|
13
|
+
// return ''
|
|
14
|
+
// }
|
|
15
|
+
// // 4. generate code for each schema
|
|
16
|
+
// }
|
|
17
|
+
const resolve_schemas_dependencies_1 = require("../../core/schema/references/resolve-schemas-dependencies");
|
|
18
|
+
// import { getCamelCaseSchemaName } from '../../core/schema/references/get-camel-case-schema-name'
|
|
19
|
+
// import { getPascalCaseSchemaName } from '../../core/schema/references/get-pascal-case-schema-name'
|
|
20
|
+
const generate_zod_infer_1 = require("../zod/generate-zod-infer");
|
|
21
|
+
function generateTypesCode(components, config) {
|
|
22
|
+
// 1. schema extraction
|
|
23
|
+
const { schemas } = components;
|
|
24
|
+
// 2. resolve schema dependencies to obtain proper ordering
|
|
25
|
+
const orderedSchemas = (0, resolve_schemas_dependencies_1.resolveSchemasDependencies)(schemas);
|
|
26
|
+
// 3. if there are no schemas, return an empty string
|
|
27
|
+
if (orderedSchemas.length === 0) {
|
|
28
|
+
return '';
|
|
29
|
+
}
|
|
30
|
+
// 4. generate code for each schema
|
|
31
|
+
const typeDefinitions = orderedSchemas.map((schemaName) => {
|
|
32
|
+
return (0, generate_zod_infer_1.generateZodInfer)(schemaName, config);
|
|
33
|
+
});
|
|
34
|
+
return typeDefinitions.join('\n\n');
|
|
35
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Config } from '../../config';
|
|
2
|
+
/**
|
|
3
|
+
* Generates a TypeScript type definition for an inferred Zod schema.
|
|
4
|
+
*
|
|
5
|
+
* @param schemaName - The name of the Zod schema to infer.
|
|
6
|
+
* @returns A string containing the inferred type definition.
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateZodInfer(schema: string, config: Config): string;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateZodInfer = generateZodInfer;
|
|
4
|
+
const get_camel_case_schema_name_1 = require("../../core/schema/references/get-camel-case-schema-name");
|
|
5
|
+
const get_pascal_case_schema_name_1 = require("../../core/schema/references/get-pascal-case-schema-name");
|
|
6
|
+
const capitalize_1 = require("../../core/text/capitalize");
|
|
7
|
+
const decapitalize_1 = require("../../core/text/decapitalize");
|
|
8
|
+
/**
|
|
9
|
+
* Generates a TypeScript type definition for an inferred Zod schema.
|
|
10
|
+
*
|
|
11
|
+
* @param schemaName - The name of the Zod schema to infer.
|
|
12
|
+
* @returns A string containing the inferred type definition.
|
|
13
|
+
*/
|
|
14
|
+
function generateZodInfer(schema, config) {
|
|
15
|
+
const schemaName = config?.schemaOptions?.namingCase === 'camelCase'
|
|
16
|
+
? (0, get_camel_case_schema_name_1.getCamelCaseSchemaName)(schema)
|
|
17
|
+
: (0, get_pascal_case_schema_name_1.getPascalCaseSchemaName)(schema);
|
|
18
|
+
const variableName = config?.typeOptions?.namingCase === 'camelCase' ? (0, decapitalize_1.decapitalize)(schema) : (0, capitalize_1.capitalize)(schema);
|
|
19
|
+
return `export type ${variableName} = z.infer<typeof ${schemaName}>`;
|
|
20
|
+
}
|
|
@@ -47,4 +47,4 @@ import type { Schema } from '../../types';
|
|
|
47
47
|
* - Uses .partial() when no properties are required
|
|
48
48
|
* - Maintains property order from input
|
|
49
49
|
*/
|
|
50
|
-
export declare function generateZodPropertiesSchema(properties: Record<string, Schema>, required: string[]): string;
|
|
50
|
+
export declare function generateZodPropertiesSchema(properties: Record<string, Schema>, required: string[], namingCase?: 'camelCase' | 'PascalCase'): string;
|
|
@@ -50,12 +50,17 @@ const generate_zod_property_schema_1 = require("./generate-zod-property-schema")
|
|
|
50
50
|
* - Uses .partial() when no properties are required
|
|
51
51
|
* - Maintains property order from input
|
|
52
52
|
*/
|
|
53
|
-
function generateZodPropertiesSchema(properties, required) {
|
|
53
|
+
function generateZodPropertiesSchema(properties, required, namingCase = 'camelCase') {
|
|
54
54
|
const objectProperties = Object.entries(properties).map(([key, schema]) => {
|
|
55
55
|
const isRequired = required.includes(key);
|
|
56
|
-
const propertySchema = (0, generate_zod_property_schema_1.generatePropertySchema)(schema);
|
|
56
|
+
const propertySchema = (0, generate_zod_property_schema_1.generatePropertySchema)(schema, namingCase);
|
|
57
57
|
return `${key}:${propertySchema}${isRequired ? '' : '.optional()'}`;
|
|
58
58
|
});
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
const allOptional = objectProperties.every((prop) => prop.includes('.optional()'));
|
|
60
|
+
if (required.length === 0 && allOptional) {
|
|
61
|
+
const cleanProperties = objectProperties.map((prop) => prop.replace('.optional()', ''));
|
|
62
|
+
return `z.object({${cleanProperties}}).partial()`;
|
|
63
|
+
}
|
|
64
|
+
return `z.object({${objectProperties}})`;
|
|
65
|
+
// return `z.object({${objectProperties}})${required.length === 0 ? '.partial()' : ''}`
|
|
61
66
|
}
|
|
@@ -22,4 +22,4 @@ import type { Schema } from '../../types';
|
|
|
22
22
|
* generatePropertySchema({ type: 'string' })
|
|
23
23
|
* // Returns: 'z.string()'
|
|
24
24
|
*/
|
|
25
|
-
export declare function generatePropertySchema(schema: Schema): string;
|
|
25
|
+
export declare function generatePropertySchema(schema: Schema, namingCase?: 'camelCase' | 'PascalCase'): string;
|
|
@@ -5,6 +5,7 @@ const get_ref_name_1 = require("../../core/schema/references/get-ref-name");
|
|
|
5
5
|
const generate_zod_array_1 = require("./generate-zod-array");
|
|
6
6
|
const generate_zod_schema_1 = require("./generate-zod-schema");
|
|
7
7
|
const get_camel_case_schema_name_1 = require("../../core/schema/references/get-camel-case-schema-name");
|
|
8
|
+
const get_pascal_case_schema_name_1 = require("../../core/schema/references/get-pascal-case-schema-name");
|
|
8
9
|
// import { generateZodOpenAPIExample } from './generate-zod-openapi-example'
|
|
9
10
|
/**
|
|
10
11
|
* Generates a Zod schema string for a given OpenAPI schema definition
|
|
@@ -29,20 +30,25 @@ const get_camel_case_schema_name_1 = require("../../core/schema/references/get-c
|
|
|
29
30
|
* generatePropertySchema({ type: 'string' })
|
|
30
31
|
* // Returns: 'z.string()'
|
|
31
32
|
*/
|
|
32
|
-
function generatePropertySchema(schema) {
|
|
33
|
+
function generatePropertySchema(schema, namingCase = 'camelCase') {
|
|
33
34
|
if (schema.$ref) {
|
|
34
35
|
const refName = (0, get_ref_name_1.getRefName)(schema.$ref);
|
|
35
36
|
if (refName) {
|
|
36
|
-
const
|
|
37
|
-
|
|
37
|
+
const variableName = namingCase === 'camelCase'
|
|
38
|
+
? (0, get_camel_case_schema_name_1.getCamelCaseSchemaName)(refName)
|
|
39
|
+
: (0, get_pascal_case_schema_name_1.getPascalCaseSchemaName)(refName);
|
|
40
|
+
// return getRefName(variableName) || 'z.any()'
|
|
41
|
+
return variableName || 'z.any()';
|
|
38
42
|
}
|
|
39
43
|
}
|
|
40
44
|
if (schema.type === 'array' && schema.items?.$ref) {
|
|
41
45
|
const refName = (0, get_ref_name_1.getRefName)(schema.items.$ref);
|
|
42
46
|
if (refName) {
|
|
43
|
-
const
|
|
44
|
-
|
|
47
|
+
const variableName = namingCase === 'camelCase'
|
|
48
|
+
? (0, get_camel_case_schema_name_1.getCamelCaseSchemaName)(refName)
|
|
49
|
+
: (0, get_pascal_case_schema_name_1.getPascalCaseSchemaName)(refName);
|
|
50
|
+
return (0, generate_zod_array_1.generateZodArray)(variableName);
|
|
45
51
|
}
|
|
46
52
|
}
|
|
47
|
-
return (0, generate_zod_schema_1.generateZodSchema)(schema);
|
|
53
|
+
return (0, generate_zod_schema_1.generateZodSchema)(schema, undefined, undefined, namingCase);
|
|
48
54
|
}
|
|
@@ -56,4 +56,4 @@ import type { Schema } from '../../types';
|
|
|
56
56
|
* - Falls back to basic type mapping for simple types
|
|
57
57
|
* - Returns z.any() for unknown types with a warning
|
|
58
58
|
*/
|
|
59
|
-
export declare function generateZodSchema(schema: Schema, paramName?: string, isPath?: boolean): string;
|
|
59
|
+
export declare function generateZodSchema(schema: Schema, paramName?: string, isPath?: boolean, namingCase?: 'camelCase' | 'PascalCase'): string;
|
|
@@ -86,70 +86,68 @@ const TYPE_TO_ZOD_SCHEMA = {
|
|
|
86
86
|
* - Falls back to basic type mapping for simple types
|
|
87
87
|
* - Returns z.any() for unknown types with a warning
|
|
88
88
|
*/
|
|
89
|
-
function generateZodSchema(schema, paramName, isPath) {
|
|
90
|
-
const { type, format, pattern, minLength, maxLength, minimum, maximum, default: defaultValue, // reserved word
|
|
91
|
-
example, properties, required = [], items, enum: enumValues, additionalProperties, } = schema;
|
|
89
|
+
function generateZodSchema(schema, paramName, isPath, namingCase = 'camelCase') {
|
|
92
90
|
// enum
|
|
93
|
-
if (
|
|
94
|
-
if (example) {
|
|
95
|
-
return `z.enum(${JSON.stringify(
|
|
91
|
+
if (schema.enum) {
|
|
92
|
+
if (schema.example) {
|
|
93
|
+
return `z.enum(${JSON.stringify(schema.enum)}).openapi({example:${JSON.stringify(schema.example)}})`;
|
|
96
94
|
}
|
|
97
|
-
return `z.enum(${JSON.stringify(
|
|
95
|
+
return `z.enum(${JSON.stringify(schema.enum)})`;
|
|
98
96
|
}
|
|
99
97
|
// object
|
|
100
|
-
if (type === 'object') {
|
|
101
|
-
if (additionalProperties)
|
|
102
|
-
return (0, generate_zod_record_schema_1.generateZodRecordSchema)(additionalProperties);
|
|
103
|
-
if (!properties)
|
|
98
|
+
if (schema.type === 'object') {
|
|
99
|
+
if (schema.additionalProperties)
|
|
100
|
+
return (0, generate_zod_record_schema_1.generateZodRecordSchema)(schema.additionalProperties);
|
|
101
|
+
if (!schema.properties)
|
|
104
102
|
return 'z.object({})';
|
|
105
|
-
return (0, generate_zod_properties_schema_1.generateZodPropertiesSchema)(properties, required);
|
|
103
|
+
return (0, generate_zod_properties_schema_1.generateZodPropertiesSchema)(schema.properties, schema.required || [], namingCase);
|
|
106
104
|
}
|
|
107
105
|
// string
|
|
108
|
-
if (type === 'string') {
|
|
106
|
+
if (schema.type === 'string') {
|
|
109
107
|
return (0, generate_zod_string_schema_1.generateZodStringSchema)({
|
|
110
|
-
pattern,
|
|
111
|
-
minLength,
|
|
112
|
-
maxLength,
|
|
113
|
-
format: format && (0, is_format_string_1.isFormatString)(format) ? format : undefined,
|
|
114
|
-
default:
|
|
115
|
-
example,
|
|
108
|
+
pattern: schema.pattern,
|
|
109
|
+
minLength: schema.minLength,
|
|
110
|
+
maxLength: schema.maxLength,
|
|
111
|
+
format: schema.format && (0, is_format_string_1.isFormatString)(schema.format) ? schema.format : undefined,
|
|
112
|
+
default: schema.default,
|
|
113
|
+
example: schema.example,
|
|
116
114
|
paramName,
|
|
117
115
|
isPath,
|
|
118
116
|
});
|
|
119
117
|
}
|
|
120
118
|
// number
|
|
121
|
-
if (type === 'number') {
|
|
119
|
+
if (schema.type === 'number') {
|
|
122
120
|
return (0, generate_zod_number_schema_1.generateZodNumberSchema)({
|
|
123
|
-
pattern,
|
|
124
|
-
minLength,
|
|
125
|
-
maxLength,
|
|
126
|
-
minimum,
|
|
127
|
-
maximum,
|
|
128
|
-
default:
|
|
129
|
-
example,
|
|
121
|
+
pattern: schema.pattern,
|
|
122
|
+
minLength: schema.minLength,
|
|
123
|
+
maxLength: schema.maxLength,
|
|
124
|
+
minimum: schema.minimum,
|
|
125
|
+
maximum: schema.maximum,
|
|
126
|
+
default: schema.default,
|
|
127
|
+
example: schema.example,
|
|
130
128
|
paramName,
|
|
131
129
|
isPath,
|
|
132
130
|
});
|
|
133
131
|
}
|
|
134
132
|
// integer
|
|
135
|
-
if (type === 'integer') {
|
|
133
|
+
if (schema.type === 'integer') {
|
|
136
134
|
return (0, generate_zod_integer_schema_1.generateZodIntegerSchema)({
|
|
137
|
-
minLength,
|
|
138
|
-
maxLength,
|
|
139
|
-
minimum,
|
|
140
|
-
maximum,
|
|
141
|
-
default:
|
|
142
|
-
example,
|
|
135
|
+
minLength: schema.minLength,
|
|
136
|
+
maxLength: schema.maxLength,
|
|
137
|
+
minimum: schema.minimum,
|
|
138
|
+
maximum: schema.maximum,
|
|
139
|
+
default: schema.default,
|
|
140
|
+
example: schema.example,
|
|
143
141
|
paramName,
|
|
144
142
|
isPath,
|
|
145
143
|
});
|
|
146
144
|
}
|
|
147
145
|
// array
|
|
148
|
-
if (type === 'array' && items)
|
|
149
|
-
return (0, generate_zod_array_1.generateZodArray)(generateZodSchema(items));
|
|
146
|
+
if (schema.type === 'array' && schema.items)
|
|
147
|
+
return (0, generate_zod_array_1.generateZodArray)(generateZodSchema(schema.items, undefined, undefined, namingCase));
|
|
150
148
|
// fallback
|
|
151
|
-
if (type)
|
|
152
|
-
return TYPE_TO_ZOD_SCHEMA[type];
|
|
153
|
-
console.warn(`Unknown type: ${type}, falling back to z.any()`);
|
|
149
|
+
if (schema.type)
|
|
150
|
+
return TYPE_TO_ZOD_SCHEMA[schema.type];
|
|
151
|
+
console.warn(`Unknown type: ${schema.type}, falling back to z.any()`);
|
|
154
152
|
return 'z.any()';
|
|
155
153
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import type { Config } from './config';
|
|
2
3
|
/**
|
|
3
4
|
* CLI entry point for hono-takibi
|
|
4
5
|
*
|
|
@@ -17,4 +18,4 @@
|
|
|
17
18
|
* npx hono-takibi openapi.yaml -o routes.ts
|
|
18
19
|
* ```
|
|
19
20
|
*/
|
|
20
|
-
export declare function main(dev?: boolean): Promise<boolean>;
|
|
21
|
+
export declare function main(dev?: boolean, config?: Config): Promise<boolean>;
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ const node_fs_1 = __importDefault(require("node:fs"));
|
|
|
10
10
|
const node_path_1 = __importDefault(require("node:path"));
|
|
11
11
|
const prettier_1 = require("prettier");
|
|
12
12
|
const generate_zod_openapi_hono_1 = require("./generators/hono/generate-zod-openapi-hono");
|
|
13
|
+
const config_1 = require("./config");
|
|
13
14
|
/**
|
|
14
15
|
* CLI entry point for hono-takibi
|
|
15
16
|
*
|
|
@@ -28,7 +29,7 @@ const generate_zod_openapi_hono_1 = require("./generators/hono/generate-zod-open
|
|
|
28
29
|
* npx hono-takibi openapi.yaml -o routes.ts
|
|
29
30
|
* ```
|
|
30
31
|
*/
|
|
31
|
-
async function main(dev = false) {
|
|
32
|
+
async function main(dev = false, config = (0, config_1.getConfig)()) {
|
|
32
33
|
// 1. argv ['**/bin/node', '**/dist/index.js', 'example/pet-store.yaml', '-o', 'routes/petstore-index.ts']
|
|
33
34
|
// 2. slice [ 'example/pet-store.yaml', '-o', 'routes/petstore-index.ts' ]
|
|
34
35
|
const args = process.argv.slice(2);
|
|
@@ -40,7 +41,7 @@ async function main(dev = false) {
|
|
|
40
41
|
// 5. parse OpenAPI YAML or JSON
|
|
41
42
|
const openAPI = (await swagger_parser_1.default.parse(input));
|
|
42
43
|
// 6. generate Hono code
|
|
43
|
-
const hono = (0, generate_zod_openapi_hono_1.generateZodOpenAPIHono)(openAPI);
|
|
44
|
+
const hono = (0, generate_zod_openapi_hono_1.generateZodOpenAPIHono)(openAPI, config);
|
|
44
45
|
// 7. format code
|
|
45
46
|
const formattedCode = await (0, prettier_1.format)(hono, {
|
|
46
47
|
parser: 'typescript',
|