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.
Files changed (34) hide show
  1. package/README.md +24 -6
  2. package/dist/config/index.d.ts +17 -0
  3. package/dist/config/index.js +29 -0
  4. package/dist/core/schema/references/get-pascal-case-schema-name.d.ts +8 -0
  5. package/dist/core/schema/references/get-pascal-case-schema-name.js +15 -0
  6. package/dist/generators/hono/generate-zod-openapi-hono.d.ts +2 -1
  7. package/dist/generators/hono/generate-zod-openapi-hono.js +10 -4
  8. package/dist/generators/openapi/components/generate-components-code.d.ts +1 -1
  9. package/dist/generators/openapi/components/generate-components-code.js +13 -7
  10. package/dist/generators/openapi/paths/generate-route-code.d.ts +1 -1
  11. package/dist/generators/openapi/paths/generate-route-code.js +2 -2
  12. package/dist/generators/openapi/paths/generate-route.d.ts +1 -1
  13. package/dist/generators/openapi/paths/generate-route.js +3 -3
  14. package/dist/generators/openapi/paths/generate-schemas-export.d.ts +1 -1
  15. package/dist/generators/openapi/paths/generate-schemas-export.js +10 -3
  16. package/dist/generators/request/params/generate-params-object.d.ts +1 -1
  17. package/dist/generators/request/params/generate-params-object.js +3 -3
  18. package/dist/generators/request/params/generate-request-parameter.d.ts +1 -1
  19. package/dist/generators/request/params/generate-request-parameter.js +3 -3
  20. package/dist/generators/response/schemas/generate-response-schema.d.ts +1 -1
  21. package/dist/generators/response/schemas/generate-response-schema.js +2 -2
  22. package/dist/generators/types/generate-types-code.d.ts +3 -0
  23. package/dist/generators/types/generate-types-code.js +35 -0
  24. package/dist/generators/zod/generate-zod-infer.d.ts +8 -0
  25. package/dist/generators/zod/generate-zod-infer.js +20 -0
  26. package/dist/generators/zod/generate-zod-properties-schema.d.ts +1 -1
  27. package/dist/generators/zod/generate-zod-properties-schema.js +9 -4
  28. package/dist/generators/zod/generate-zod-property-schema.d.ts +1 -1
  29. package/dist/generators/zod/generate-zod-property-schema.js +12 -6
  30. package/dist/generators/zod/generate-zod-schema.d.ts +1 -1
  31. package/dist/generators/zod/generate-zod-schema.js +37 -39
  32. package/dist/index.d.ts +2 -1
  33. package/dist/index.js +3 -2
  34. 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
- 1. **Schema Naming Convention**
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 hono code
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 camelCase schema name
40
- const camelCaseSchemaName = (0, get_camel_case_schema_name_1.getCamelCaseSchemaName)(schemaName);
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)(camelCaseSchemaName, zodSchema, schemaName);
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
- return `${schemaDefinitions}\n\n${exports}`;
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
- const camelCaseSchemas = orderedSchemas.map((schemaName) => (0, get_camel_case_schema_name_1.getCamelCaseSchemaName)(schemaName));
17
- return `export const schemas = {\n${camelCaseSchemas.join(',\n')}\n}`;
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,3 @@
1
+ import type { Components } from '../../types';
2
+ import type { Config } from '../../config';
3
+ export declare function generateTypesCode(components: Components, config: Config): string;
@@ -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
- // Maybe you don't need to use .partial().
60
- return `z.object({${objectProperties}})${required ? '' : '.partial()'}`;
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 camelCaseRefName = (0, get_camel_case_schema_name_1.getCamelCaseSchemaName)(refName);
37
- return (0, get_ref_name_1.getRefName)(camelCaseRefName) || 'z.any()';
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 camelCaseRefName = (0, get_camel_case_schema_name_1.getCamelCaseSchemaName)(refName);
44
- return (0, generate_zod_array_1.generateZodArray)(camelCaseRefName);
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 (enumValues) {
94
- if (example) {
95
- return `z.enum(${JSON.stringify(enumValues)}).openapi({example:${JSON.stringify(example)}})`;
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(enumValues)})`;
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: defaultValue,
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: defaultValue,
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: defaultValue,
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',
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.1.5",
4
+ "version": "0.2.1",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "hono",