hono-takibi 0.8.6 → 0.8.7

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 (63) hide show
  1. package/dist/cli/index.d.ts +7 -4
  2. package/dist/cli/index.js +11 -5
  3. package/dist/cli/takibi.d.ts +7 -4
  4. package/dist/cli/takibi.js +11 -7
  5. package/dist/generator/zod-openapi-hono/openapi/components/index.js +2 -3
  6. package/dist/generator/zod-openapi-hono/openapi/route/index.js +0 -4
  7. package/dist/generator/zod-openapi-hono/openapi/route/params/params-object.js +4 -5
  8. package/dist/generator/zod-openapi-hono/openapi/route/params/request-parameter.js +2 -2
  9. package/dist/generator/zod-openapi-hono/openapi/route/response/index.js +2 -2
  10. package/dist/generator/zod-to-openapi/index.d.ts +2 -0
  11. package/dist/generator/zod-to-openapi/index.js +141 -0
  12. package/dist/generator/zod-to-openapi/z/array.js +17 -0
  13. package/dist/generator/{zod → zod-to-openapi}/z/enum.d.ts +0 -3
  14. package/dist/generator/zod-to-openapi/z/enum.js +41 -0
  15. package/dist/generator/{zod → zod-to-openapi}/z/index.d.ts +0 -2
  16. package/dist/generator/{zod → zod-to-openapi}/z/index.js +0 -2
  17. package/dist/generator/{zod → zod-to-openapi}/z/integer.js +1 -3
  18. package/dist/generator/{zod → zod-to-openapi}/z/number.js +1 -3
  19. package/dist/generator/zod-to-openapi/z/object.js +40 -0
  20. package/dist/generator/{zod → zod-to-openapi}/z/string.js +1 -3
  21. package/dist/helper/index.d.ts +1 -6
  22. package/dist/helper/index.js +1 -6
  23. package/dist/{generator/zod/helper → helper}/properties-schema.d.ts +1 -1
  24. package/dist/{generator/zod/helper → helper}/properties-schema.js +3 -3
  25. package/dist/helper/wrap.d.ts +1 -1
  26. package/dist/helper/wrap.js +21 -6
  27. package/dist/index.js +1 -1
  28. package/dist/openapi/index.d.ts +1 -1
  29. package/dist/utils/index.d.ts +4 -23
  30. package/dist/utils/index.js +7 -32
  31. package/package.json +1 -5
  32. package/dist/generator/zod/helper/index.d.ts +0 -2
  33. package/dist/generator/zod/helper/index.js +0 -2
  34. package/dist/generator/zod/helper/property-schema.d.ts +0 -27
  35. package/dist/generator/zod/helper/property-schema.js +0 -45
  36. package/dist/generator/zod/index.d.ts +0 -54
  37. package/dist/generator/zod/index.js +0 -113
  38. package/dist/generator/zod/z/array.js +0 -23
  39. package/dist/generator/zod/z/boolean.d.ts +0 -2
  40. package/dist/generator/zod/z/boolean.js +0 -5
  41. package/dist/generator/zod/z/date.d.ts +0 -2
  42. package/dist/generator/zod/z/date.js +0 -5
  43. package/dist/generator/zod/z/enum.js +0 -63
  44. package/dist/generator/zod/z/object.js +0 -55
  45. package/dist/helper/allof.d.ts +0 -2
  46. package/dist/helper/allof.js +0 -34
  47. package/dist/helper/anyof.d.ts +0 -14
  48. package/dist/helper/anyof.js +0 -26
  49. package/dist/helper/const.d.ts +0 -2
  50. package/dist/helper/const.js +0 -5
  51. package/dist/helper/normalize-types.d.ts +0 -2
  52. package/dist/helper/normalize-types.js +0 -3
  53. package/dist/helper/not.d.ts +0 -2
  54. package/dist/helper/not.js +0 -16
  55. package/dist/helper/oneof.d.ts +0 -12
  56. package/dist/helper/oneof.js +0 -30
  57. package/dist/helper/zod-to-openapi.d.ts +0 -21
  58. package/dist/helper/zod-to-openapi.js +0 -39
  59. /package/dist/generator/{zod → zod-to-openapi}/z/array.d.ts +0 -0
  60. /package/dist/generator/{zod → zod-to-openapi}/z/integer.d.ts +0 -0
  61. /package/dist/generator/{zod → zod-to-openapi}/z/number.d.ts +0 -0
  62. /package/dist/generator/{zod → zod-to-openapi}/z/object.d.ts +0 -0
  63. /package/dist/generator/{zod → zod-to-openapi}/z/string.d.ts +0 -0
@@ -1,9 +1,12 @@
1
- import type { Result } from '../result/index.js';
2
1
  /**
3
2
  * CLI entry point for `hono-takibi`.
4
3
  *
5
4
  * @returns A `Result` containing help text or CLI execution result.
6
5
  */
7
- export declare function honoTakibi(): Promise<Result<{
8
- message: string;
9
- }, string>>;
6
+ export declare function honoTakibi(): Promise<{
7
+ ok: true;
8
+ value: string;
9
+ } | {
10
+ ok: false;
11
+ error: string;
12
+ }>;
package/dist/cli/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { asyncAndThen, ok } from '../result/index.js';
1
+ import { asyncAndThen } from '../result/index.js';
2
2
  import { parseCli } from '../utils/index.js';
3
3
  import { takibi } from './takibi.js';
4
4
  const HELP_TEXT = `Usage: hono-takibi <input.{yaml,json,tsp}> -o <routes.ts> [options]
@@ -22,9 +22,15 @@ export async function honoTakibi() {
22
22
  return args.length === 1 && (args[0] === '--help' || args[0] === '-h');
23
23
  };
24
24
  if (isHelpRequested(args)) {
25
- return ok({
26
- message: HELP_TEXT,
27
- });
25
+ return {
26
+ ok: true,
27
+ value: HELP_TEXT,
28
+ };
28
29
  }
29
- return await asyncAndThen(parseCli(args), async (cli) => asyncAndThen(await takibi(cli.input, cli.output, cli.exportSchema ?? false, cli.exportType ?? false, cli.template ?? false, cli.test ?? false, cli.basePath), async (result) => ok(result)));
30
+ return await asyncAndThen(parseCli(args), async (cli) => asyncAndThen(await takibi(cli.input, cli.output, cli.exportSchema ?? false, cli.exportType ?? false, cli.template ?? false, cli.test ?? false, cli.basePath), async (result) => {
31
+ return {
32
+ ok: true,
33
+ value: result,
34
+ };
35
+ }));
30
36
  }
@@ -1,4 +1,3 @@
1
- import type { Result } from '../result/index.js';
2
1
  /**
3
2
  * Generates TypeScript code from an OpenAPI spec and optional templates.
4
3
  *
@@ -11,6 +10,10 @@ import type { Result } from '../result/index.js';
11
10
  * @param basePath - Optional base path for template output.
12
11
  * @returns A `Result` containing a success message or an error string.
13
12
  */
14
- export declare function takibi(input: `${string}.yaml` | `${string}.json` | `${string}.tsp`, output: `${string}.ts`, exportSchema: boolean, exportType: boolean, template: boolean, test: boolean, basePath?: string): Promise<Result<{
15
- message: string;
16
- }, string>>;
13
+ export declare function takibi(input: `${string}.yaml` | `${string}.json` | `${string}.tsp`, output: `${string}.ts`, exportSchema: boolean, exportType: boolean, template: boolean, test: boolean, basePath?: string): Promise<{
14
+ ok: true;
15
+ value: string;
16
+ } | {
17
+ ok: false;
18
+ error: string;
19
+ }>;
@@ -3,7 +3,7 @@ import { fmt } from '../format/index.js';
3
3
  import { mkdir, writeFile } from '../fsp/index.js';
4
4
  import zodOpenAPIHono from '../generator/zod-openapi-hono/openapi/index.js';
5
5
  import { parseOpenAPI } from '../openapi/index.js';
6
- import { asyncAndThen, ok } from '../result/index.js';
6
+ import { asyncAndThen } from '../result/index.js';
7
7
  import { templateCode } from './template-code.js';
8
8
  /**
9
9
  * Generates TypeScript code from an OpenAPI spec and optional templates.
@@ -19,10 +19,14 @@ import { templateCode } from './template-code.js';
19
19
  */
20
20
  export async function takibi(input, output, exportSchema, exportType, template, test, basePath) {
21
21
  return await asyncAndThen(await parseOpenAPI(input), async (openAPI) => asyncAndThen(await fmt(zodOpenAPIHono(openAPI, exportSchema, exportType)), async (code) => asyncAndThen(await mkdir(path.dirname(output)), async () => asyncAndThen(await writeFile(output, code), async () => template && output.includes('/')
22
- ? asyncAndThen(await templateCode(openAPI, output, test, basePath), async () => ok({
23
- message: 'Generated code and template files written',
24
- }))
25
- : ok({
26
- message: `Generated code written to ${output}`,
27
- })))));
22
+ ? asyncAndThen(await templateCode(openAPI, output, test, basePath), async () => {
23
+ return {
24
+ ok: true,
25
+ value: 'Generated code and template files written',
26
+ };
27
+ })
28
+ : {
29
+ ok: true,
30
+ value: `Generated code written to ${output}`,
31
+ }))));
28
32
  }
@@ -1,7 +1,6 @@
1
1
  import { resolveSchemasDependencies } from '../../../../helper/resolve-schemas-dependencies.js';
2
- import { zodToOpenAPI } from '../../../../helper/zod-to-openapi.js';
3
2
  import { zodToOpenAPISchema } from '../../../../helper/zod-to-openapi-schema.js';
4
- import zod from '../../../zod/index.js';
3
+ import { zodToOpenAPI } from '../../../zod-to-openapi/index.js';
5
4
  /**
6
5
  * Converts OpenAPI component schemas to Zod-based TypeScript definitions.
7
6
  *
@@ -33,7 +32,7 @@ export function componentsCode(components, exportSchema, exportType) {
33
32
  // 4.1 get schema definition corresponding to schema name
34
33
  const schema = schemas[schemaName];
35
34
  // 4.2 generate zod schema
36
- const zodSchema = zodToOpenAPI(zod(schema), schema);
35
+ const zodSchema = zodToOpenAPI(schema);
37
36
  // 4.3 generate zod schema definition
38
37
  return zodToOpenAPISchema(schemaName, zodSchema, exportSchema, exportType);
39
38
  })
@@ -1,4 +1,3 @@
1
- import { isHttpMethod } from '../../../../utils/index.js';
2
1
  import { route } from './route.js';
3
2
  /**
4
3
  * Generates TypeScript code for all valid Hono routes from OpenAPI paths.
@@ -24,9 +23,6 @@ export function routeCode(openAPIPaths) {
24
23
  // 3.1. skip parameters key and undefined operations
25
24
  if (method === 'parameters' || !pathItemValue)
26
25
  continue;
27
- // 3.2. check if the method is an HTTP method
28
- if (!isHttpMethod(method))
29
- throw new Error('Invalid HTTP method');
30
26
  // 3.3 exclude the possibility of string or Parameter[]
31
27
  if (typeof pathItemValue === 'string' || Array.isArray(pathItemValue))
32
28
  continue;
@@ -1,6 +1,5 @@
1
- import { zodToOpenAPI } from '../../../../../helper/zod-to-openapi.js';
2
1
  import { getToSafeIdentifier } from '../../../../../utils/index.js';
3
- import zod from '../../../../zod/index.js';
2
+ import { zodToOpenAPI } from '../../../../zod-to-openapi/index.js';
4
3
  import { queryParameter } from './index.js';
5
4
  /**
6
5
  * Converts OpenAPI component schemas into TypeScript code using Zod.
@@ -17,12 +16,12 @@ import { queryParameter } from './index.js';
17
16
  */
18
17
  export function paramsObject(parameters) {
19
18
  return parameters.reduce((acc, param) => {
20
- const z = zod(param.schema);
19
+ // const z = zod(param.schema)
21
20
  const optionalSuffix = param.required ? '' : '.optional()';
22
21
  // path params are generated with the param name
23
22
  const baseSchema = param.in
24
- ? zodToOpenAPI(z, param.schema, param.name, param.in)
25
- : zodToOpenAPI(z, param.schema, param.name);
23
+ ? zodToOpenAPI(param.schema, param.name, param.in)
24
+ : zodToOpenAPI(param.schema, param.name);
26
25
  // Initialize section if it doesn't exist
27
26
  if (!acc[param.in]) {
28
27
  acc[param.in] = {};
@@ -1,5 +1,5 @@
1
1
  import { requestParamsArray } from '../../../../../utils/index.js';
2
- import { propertySchema } from '../../../../zod/helper/property-schema.js';
2
+ import { zodToOpenAPI } from '../../../../zod-to-openapi/index.js';
3
3
  import { requestBody } from '../request/body/index.js';
4
4
  import { paramsObject } from './index.js';
5
5
  /**
@@ -35,7 +35,7 @@ export function requestParameter(parameters, body) {
35
35
  const uniqueSchemas = new Map();
36
36
  for (const contentType of requestBodyContentTypes) {
37
37
  const { schema } = body.content[contentType];
38
- const z = propertySchema(schema);
38
+ const z = zodToOpenAPI(schema);
39
39
  uniqueSchemas.set(z, z);
40
40
  }
41
41
  const request_body_required = body.required ?? false;
@@ -1,5 +1,5 @@
1
1
  import { escapeStringLiteral, isUniqueContentSchema } from '../../../../../utils/index.js';
2
- import { propertySchema } from '../../../../zod/helper/property-schema.js';
2
+ import { zodToOpenAPI } from '../../../../zod-to-openapi/index.js';
3
3
  /**
4
4
  * Generates a Zod-compatible response schema definition from OpenAPI responses.
5
5
  *
@@ -29,7 +29,7 @@ export function response(responses) {
29
29
  const contentParts = [];
30
30
  for (const contentType of contentTypes) {
31
31
  const content = response.content[contentType];
32
- const zodSchema = propertySchema(content.schema);
32
+ const zodSchema = zodToOpenAPI(content.schema);
33
33
  const examples = content.examples;
34
34
  const exampleString = examples && Object.keys(examples).length > 0
35
35
  ? `,examples:{${Object.entries(examples)
@@ -0,0 +1,2 @@
1
+ import type { Schema } from '../../openapi/index.js';
2
+ export declare function zodToOpenAPI(schema: Schema, paramName?: string, paramIn?: 'path' | 'query' | 'header' | 'cookie'): string;
@@ -0,0 +1,141 @@
1
+ import { wrap } from '../../helper/wrap.js';
2
+ import { normalizeTypes, refSchema } from '../../utils/index.js';
3
+ import { array } from './z/array.js';
4
+ import { _enum } from './z/enum.js';
5
+ import { integer } from './z/integer.js';
6
+ import { number } from './z/number.js';
7
+ import { object } from './z/object.js';
8
+ import { string } from './z/string.js';
9
+ export function zodToOpenAPI(schema, paramName, paramIn) {
10
+ if (schema === undefined)
11
+ throw new Error('hono-takibi: only #/components/schemas/* is supported');
12
+ // ref
13
+ if (schema.$ref) {
14
+ if (Boolean(schema.$ref) === true) {
15
+ return wrap(refSchema(schema.$ref), schema, paramName, paramIn);
16
+ }
17
+ if (schema.type === 'array' && Boolean(schema.items?.$ref)) {
18
+ if (schema.items?.$ref) {
19
+ const ref = wrap(refSchema(schema.items.$ref), schema.items);
20
+ return `z.array(${ref})`;
21
+ }
22
+ const z = 'z.array(z.any())';
23
+ return wrap(z, schema, paramName, paramIn);
24
+ }
25
+ const z = 'z.any()';
26
+ return wrap(z, schema, paramName, paramIn);
27
+ }
28
+ /* combinators */
29
+ // allOf
30
+ if (schema.allOf) {
31
+ if (!schema.allOf || schema.allOf.length === 0) {
32
+ return wrap('z.any()', schema);
33
+ }
34
+ const { schemas, nullable } = schema.allOf.reduce((acc, s) => {
35
+ const isOnlyNullable = (typeof s === 'object' && s.type === 'null') ||
36
+ (typeof s === 'object' && s?.nullable === true && Object.keys(s).length === 1);
37
+ if (isOnlyNullable) {
38
+ return {
39
+ schemas: acc.schemas,
40
+ nullable: true,
41
+ };
42
+ }
43
+ const z = zodToOpenAPI(s, paramName, paramIn);
44
+ return {
45
+ schemas: [...acc.schemas, wrap(z, s)],
46
+ nullable: acc.nullable,
47
+ };
48
+ }, {
49
+ schemas: [],
50
+ nullable: schema.nullable === true ||
51
+ (Array.isArray(schema.type) ? schema.type.includes('null') : schema.type === 'null'),
52
+ });
53
+ if (schemas.length === 0) {
54
+ return wrap('z.any()', { ...schema, nullable }, paramName, paramIn);
55
+ }
56
+ if (schemas.length === 1) {
57
+ return wrap(schemas[0], { ...schema, nullable }, paramName, paramIn);
58
+ }
59
+ const z = `z.intersection(${schemas.join(',')})`;
60
+ return wrap(z, schema, paramName, paramIn);
61
+ }
62
+ // anyOf
63
+ if (schema.anyOf) {
64
+ if (!schema.anyOf || schema.anyOf.length === 0) {
65
+ return 'z.any()';
66
+ }
67
+ const schemas = schema.anyOf.map((subSchema) => {
68
+ return zodToOpenAPI(subSchema, paramName, paramIn);
69
+ });
70
+ const z = `z.union([${schemas.join(',')}])`;
71
+ return wrap(z, schema);
72
+ }
73
+ // oneOf
74
+ if (schema.oneOf) {
75
+ if (!schema.oneOf || schema.oneOf.length === 0) {
76
+ return 'z.any()';
77
+ }
78
+ const schemas = schema.oneOf.map((schema) => {
79
+ return zodToOpenAPI(schema, paramName, paramIn);
80
+ });
81
+ // discriminatedUnion Support hesitant
82
+ // This is because using intersection causes a type error.
83
+ // const discriminator = schema.discriminator?.propertyName
84
+ // const z = discriminator
85
+ // ? `z.discriminatedUnion('${discriminator}',[${schemas.join(',')}])`
86
+ // : `z.union([${schemas.join(',')}])`
87
+ const z = `z.union([${schemas.join(',')}])`;
88
+ return wrap(z, schema, paramName, paramIn);
89
+ }
90
+ // not
91
+ if (schema.not) {
92
+ if (typeof schema.not === 'object' && schema.not.type && typeof schema.not.type === 'string') {
93
+ const predicate = `(v) => typeof v !== '${schema.not.type}'`;
94
+ return `z.any().refine(${predicate})`;
95
+ }
96
+ if (typeof schema.not === 'object' && Array.isArray(schema.not.enum)) {
97
+ const list = JSON.stringify(schema.not.enum);
98
+ const predicate = `(v) => !${list}.includes(v)`;
99
+ return `z.any().refine(${predicate})`;
100
+ }
101
+ return 'z.any()';
102
+ }
103
+ // const
104
+ if (schema.const) {
105
+ const z = `z.literal(${JSON.stringify(schema.const)})`;
106
+ return wrap(z, schema, paramName, paramIn);
107
+ }
108
+ /* enum */
109
+ if (schema.enum)
110
+ return wrap(_enum(schema), schema, paramName, paramIn);
111
+ /* properties */
112
+ if (schema.properties)
113
+ return wrap(object(schema), schema, paramName, paramIn);
114
+ const t = normalizeTypes(schema.type);
115
+ /* string */
116
+ if (t.includes('string'))
117
+ return wrap(string(schema), schema, paramName, paramIn);
118
+ /* number */
119
+ if (t.includes('number'))
120
+ return wrap(number(schema), schema, paramName, paramIn);
121
+ /* integer & bigint */
122
+ if (t.includes('integer'))
123
+ return wrap(integer(schema), schema, paramName, paramIn);
124
+ /* boolean */
125
+ if (t.includes('boolean'))
126
+ return wrap('z.boolean()', schema, paramName, paramIn);
127
+ /* array */
128
+ if (t.includes('array'))
129
+ return wrap(array(schema), schema, paramName, paramIn);
130
+ /* object */
131
+ if (t.includes('object'))
132
+ return wrap(object(schema), schema, paramName, paramIn);
133
+ /* date */
134
+ if (t.includes('date'))
135
+ return wrap('z.date()', schema, paramName, paramIn);
136
+ /* null only */
137
+ if (t.length === 1 && t[0] === 'null')
138
+ return wrap('z.null()', schema, paramName, paramIn);
139
+ console.warn(`fallback to z.any(): schema=${JSON.stringify(schema)}`);
140
+ return wrap('z.any()', schema, paramName, paramIn);
141
+ }
@@ -0,0 +1,17 @@
1
+ import { zodToOpenAPI } from '../index.js';
2
+ export function array(schema) {
3
+ const array = `z.array(${schema.items ? zodToOpenAPI(schema.items) : 'z.any()'})`;
4
+ if (typeof schema.minItems === 'number' && typeof schema.maxItems === 'number') {
5
+ if (schema.minItems === schema.maxItems) {
6
+ return `${array}.length(${schema.minItems})`;
7
+ }
8
+ return `${array}.min(${schema.minItems}).max(${schema.maxItems})`;
9
+ }
10
+ if (typeof schema.minItems === 'number') {
11
+ return `${array}.min(${schema.minItems})`;
12
+ }
13
+ if (typeof schema.maxItems === 'number') {
14
+ return `${array}.max(${schema.maxItems})`;
15
+ }
16
+ return array;
17
+ }
@@ -1,5 +1,2 @@
1
1
  import type { Schema } from '../../../openapi/index.js';
2
- /**
3
- * Generate a Zod enum schema string from an OpenAPI Schema object (nullable対応含む).
4
- */
5
2
  export declare function _enum(schema: Schema): string;
@@ -0,0 +1,41 @@
1
+ export function _enum(schema) {
2
+ /* -------------------------- helpers -------------------------- */
3
+ const hasType = (t) => schema.type === t || (Array.isArray(schema.type) && schema.type.some((x) => x === t));
4
+ const lit = (v) => v === null ? 'null' : typeof v === 'string' ? `'${v}'` : String(v);
5
+ const tuple = (arr) => `z.tuple([${arr.map((i) => `z.literal(${lit(i)})`).join(',')}])`;
6
+ /* --------------------------- guard --------------------------- */
7
+ if (!schema.enum || schema.enum.length === 0)
8
+ return 'z.any()';
9
+ /* ------------------- number / integer enum ------------------- */
10
+ if (hasType('number') || hasType('integer')) {
11
+ return schema.enum.length > 1
12
+ ? `z.union([${schema.enum.map((v) => `z.literal(${v})`).join(',')}])`
13
+ : `z.literal(${schema.enum[0]})`;
14
+ }
15
+ /* ----------------------- boolean enum ------------------------ */
16
+ if (hasType('boolean')) {
17
+ return schema.enum.length > 1
18
+ ? `z.union([${schema.enum.map((v) => `z.literal(${v})`).join(',')}])`
19
+ : `z.literal(${schema.enum[0]})`;
20
+ }
21
+ /* ----------------------- array enum -------------------------- */
22
+ if (hasType('array')) {
23
+ if (schema.enum.length === 1 && Array.isArray(schema.enum[0])) {
24
+ return tuple(schema.enum[0]);
25
+ }
26
+ const parts = schema.enum.map((v) => (Array.isArray(v) ? tuple(v) : `z.literal(${lit(v)})`));
27
+ return `z.union([${parts.join(',')}])`;
28
+ }
29
+ /* ----------------------- string enum ------------------------- */
30
+ if (schema.enum.every((v) => typeof v === 'string')) {
31
+ return schema.enum.length > 1
32
+ ? `z.enum(${JSON.stringify(schema.enum)})`
33
+ : `z.literal('${schema.enum[0]}')`;
34
+ }
35
+ /* -------------------- mixed / null only ---------------------- */
36
+ if (schema.enum.length > 1) {
37
+ const parts = schema.enum.map((v) => `z.literal(${lit(v)})`);
38
+ return `z.union([${parts.join(',')}])`;
39
+ }
40
+ return `z.literal(${lit(schema.enum[0])})`;
41
+ }
@@ -1,6 +1,4 @@
1
1
  export { array } from './array.js';
2
- export { boolean } from './boolean.js';
3
- export { date } from './date.js';
4
2
  export { _enum } from './enum.js';
5
3
  export { integer } from './integer.js';
6
4
  export { number } from './number.js';
@@ -1,6 +1,4 @@
1
1
  export { array } from './array.js';
2
- export { boolean } from './boolean.js';
3
- export { date } from './date.js';
4
2
  export { _enum } from './enum.js';
5
3
  export { integer } from './integer.js';
6
4
  export { number } from './number.js';
@@ -1,4 +1,3 @@
1
- import { wrap } from '../../../helper/wrap.js';
2
1
  /**
3
2
  * Generates a Zod schema for integer types based on OpenAPI schema.
4
3
  * Supports int32, int64, and bigint formats.
@@ -88,6 +87,5 @@ export function integer(schema) {
88
87
  if (schema.multipleOf !== undefined && typeof schema.multipleOf === 'number') {
89
88
  o.push(`.multipleOf(${lit(schema.multipleOf)})`);
90
89
  }
91
- const z = o.join('');
92
- return wrap(z, schema);
90
+ return o.join('');
93
91
  }
@@ -1,4 +1,3 @@
1
- import { wrap } from '../../../helper/wrap.js';
2
1
  /**
3
2
  * Generates a Zod schema for number types based on OpenAPI schema.
4
3
  * Supports float, float32, float64, and number formats.
@@ -78,6 +77,5 @@ export function number(schema) {
78
77
  if (schema.multipleOf !== undefined) {
79
78
  o.push(`.multipleOf(${schema.multipleOf})`);
80
79
  }
81
- const z = o.join('');
82
- return wrap(z, schema);
80
+ return o.join('');
83
81
  }
@@ -0,0 +1,40 @@
1
+ import { propertiesSchema } from '../../../helper/properties-schema.js';
2
+ import { zodToOpenAPI } from '../index.js';
3
+ /**
4
+ * Generates a Zod object schema from an OpenAPI schema definition.
5
+ *
6
+ * @param schema - Schema definition.
7
+ * @returns The Zod object schema string.
8
+ */
9
+ export function object(schema) {
10
+ // // allOf, oneOf, anyOf, not
11
+ if (schema.oneOf)
12
+ return zodToOpenAPI(schema);
13
+ if (schema.anyOf)
14
+ return zodToOpenAPI(schema);
15
+ if (schema.allOf)
16
+ return zodToOpenAPI(schema);
17
+ if (schema.not)
18
+ return zodToOpenAPI(schema);
19
+ if (schema.additionalProperties) {
20
+ if (typeof schema.additionalProperties === 'boolean') {
21
+ if (schema.properties) {
22
+ const s = propertiesSchema(schema.properties, Array.isArray(schema.required) ? schema.required : []);
23
+ if (schema.additionalProperties === true) {
24
+ return s.replace('object', 'looseObject');
25
+ }
26
+ }
27
+ return 'z.any()';
28
+ }
29
+ const s = zodToOpenAPI(schema.additionalProperties);
30
+ return `z.record(z.string(),${s})`;
31
+ }
32
+ if (schema.properties) {
33
+ const s = propertiesSchema(schema.properties, Array.isArray(schema.required) ? schema.required : []);
34
+ if (schema.additionalProperties === false) {
35
+ return s.replace('object', 'strictObject');
36
+ }
37
+ return s;
38
+ }
39
+ return 'z.object({})';
40
+ }
@@ -1,4 +1,3 @@
1
- import { wrap } from '../../../helper/wrap.js';
2
1
  import { regex } from '../../../utils/index.js';
3
2
  const FORMAT_STRING = {
4
3
  email: 'email()',
@@ -51,6 +50,5 @@ export function string(schema) {
51
50
  o.push(`.max(${schema.maxLength})`);
52
51
  }
53
52
  }
54
- const z = o.join('');
55
- return wrap(z, schema);
53
+ return o.join('');
56
54
  }
@@ -1,11 +1,6 @@
1
- export { allOf } from './allof.js';
2
- export { anyOf } from './anyof.js';
3
1
  export { docs } from './docs.js';
4
2
  export { getRouteMaps } from './get-route-maps.js';
5
- export { normalizeTypes } from './normalize-types.js';
6
- export { not } from './not.js';
7
- export { oneOf } from './oneof.js';
3
+ export { propertiesSchema } from './properties-schema.js';
8
4
  export { resolveSchemasDependencies } from './resolve-schemas-dependencies.js';
9
5
  export { wrap } from './wrap.js';
10
- export { zodToOpenAPI } from './zod-to-openapi.js';
11
6
  export { zodToOpenAPISchema } from './zod-to-openapi-schema.js';
@@ -1,11 +1,6 @@
1
- export { allOf } from './allof.js';
2
- export { anyOf } from './anyof.js';
3
1
  export { docs } from './docs.js';
4
2
  export { getRouteMaps } from './get-route-maps.js';
5
- export { normalizeTypes } from './normalize-types.js';
6
- export { not } from './not.js';
7
- export { oneOf } from './oneof.js';
3
+ export { propertiesSchema } from './properties-schema.js';
8
4
  export { resolveSchemasDependencies } from './resolve-schemas-dependencies.js';
9
5
  export { wrap } from './wrap.js';
10
- export { zodToOpenAPI } from './zod-to-openapi.js';
11
6
  export { zodToOpenAPISchema } from './zod-to-openapi-schema.js';
@@ -1,4 +1,4 @@
1
- import type { Schema } from '../../../openapi/index.js';
1
+ import type { Schema } from '../openapi/index.js';
2
2
  /**
3
3
  * Generates a Zod object schema string from a set of OpenAPI properties.
4
4
  *
@@ -1,5 +1,5 @@
1
- import { getToSafeIdentifier } from '../../../utils/index.js';
2
- import { propertySchema } from './property-schema.js';
1
+ import { zodToOpenAPI } from '../generator/zod-to-openapi/index.js';
2
+ import { getToSafeIdentifier } from '../utils/index.js';
3
3
  /**
4
4
  * Generates a Zod object schema string from a set of OpenAPI properties.
5
5
  *
@@ -48,7 +48,7 @@ export function propertiesSchema(properties, required) {
48
48
  const objectProperties = Object.entries(properties).map(([key, schema]) => {
49
49
  const isRequired = required.includes(key);
50
50
  const safeKey = getToSafeIdentifier(key);
51
- return `${safeKey}:${propertySchema(schema)}${isRequired ? '' : '.optional()'}`;
51
+ return `${safeKey}:${zodToOpenAPI(schema)}${isRequired ? '' : '.optional()'}`;
52
52
  });
53
53
  // Check if all properties are optional
54
54
  const allOptional = objectProperties.every((prop) => prop.includes('.optional()'));
@@ -1,2 +1,2 @@
1
1
  import type { Schema } from '../openapi/index.js';
2
- export declare function wrap(zod: string, schema: Schema): string;
2
+ export declare function wrap(zod: string, schema: Schema, paramName?: string, paramIn?: string): string;
@@ -1,4 +1,4 @@
1
- export function wrap(zod, schema) {
1
+ export function wrap(zod, schema, paramName, paramIn) {
2
2
  const formatLiteral = (v) => {
3
3
  // boolean true or false
4
4
  if (typeof v === 'boolean') {
@@ -14,9 +14,6 @@ export function wrap(zod, schema) {
14
14
  }
15
15
  return `${v}`;
16
16
  }
17
- if (typeof v === 'bigint') {
18
- return `${v}n`;
19
- }
20
17
  // date
21
18
  if (schema.type === 'date' && typeof v === 'string') {
22
19
  return `new Date(${JSON.stringify(v)})`;
@@ -29,8 +26,26 @@ export function wrap(zod, schema) {
29
26
  return JSON.stringify(v);
30
27
  };
31
28
  // why schema.default !== undefined becasue schema.default === 0 // → falsy
32
- const z = schema.default !== undefined ? `${zod}.default(${formatLiteral(schema.default)})` : zod;
29
+ const s = schema.default !== undefined ? `${zod}.default(${formatLiteral(schema.default)})` : zod;
33
30
  const isNullable = schema.nullable === true ||
34
31
  (Array.isArray(schema.type) ? schema.type.includes('null') : schema.type === 'null');
35
- return isNullable ? `${z}.nullable()` : z;
32
+ const z = isNullable ? `${s}.nullable()` : s;
33
+ const openapiProps = [];
34
+ if (paramIn && paramName) {
35
+ const required = paramIn === 'path' ? true : !!schema.required;
36
+ openapiProps.push(`param:{in:"${paramIn}",name:${JSON.stringify(paramName)},required:${required}}`);
37
+ }
38
+ // Add 'example' if defined
39
+ if ('example' in schema && schema.example !== undefined) {
40
+ openapiProps.push(`example:${JSON.stringify(schema.example)}`);
41
+ }
42
+ // Add 'examples' if defined
43
+ if ('examples' in schema && Array.isArray(schema.examples) && schema.examples.length > 0) {
44
+ openapiProps.push(`examples:${JSON.stringify(schema.examples)}`);
45
+ }
46
+ // Add 'description' if defined
47
+ if ('description' in schema && schema.description !== undefined) {
48
+ openapiProps.push(`description:${JSON.stringify(schema.description)}`);
49
+ }
50
+ return openapiProps.length === 0 ? z : `${z}.openapi({${openapiProps.join(',')}})`;
36
51
  }
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ import { honoTakibi } from './cli/index.js';
18
18
  */
19
19
  honoTakibi().then((result) => {
20
20
  if (result.ok) {
21
- console.log(result.value.message);
21
+ console.log(result.value);
22
22
  process.exit(0);
23
23
  }
24
24
  else {
@@ -126,7 +126,7 @@ export type Schema = {
126
126
  example?: unknown;
127
127
  examples?: unknown;
128
128
  properties?: Record<string, Schema>;
129
- required?: string[] | boolean;
129
+ required?: string[];
130
130
  items?: Schema;
131
131
  enum?: (string | number | boolean | null | (string | number | boolean | null)[])[];
132
132
  nullable?: boolean;