hono-takibi 0.8.3 → 0.8.4

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 (57) hide show
  1. package/dist/cli/index.d.ts +1 -1
  2. package/dist/cli/index.js +12 -6
  3. package/dist/format/index.d.ts +9 -2
  4. package/dist/fsp/index.d.ts +21 -4
  5. package/dist/fsp/index.js +16 -7
  6. package/dist/generator/zod/helper/index.d.ts +0 -3
  7. package/dist/generator/zod/helper/index.js +0 -3
  8. package/dist/generator/zod/helper/property-schema.js +12 -6
  9. package/dist/generator/zod/index.js +10 -23
  10. package/dist/generator/zod/z/array.js +19 -10
  11. package/dist/generator/zod/z/boolean.d.ts +2 -0
  12. package/dist/generator/zod/z/boolean.js +6 -0
  13. package/dist/generator/zod/z/date.d.ts +2 -0
  14. package/dist/generator/zod/z/date.js +6 -0
  15. package/dist/generator/zod/z/enum.js +21 -12
  16. package/dist/generator/zod/z/index.d.ts +2 -0
  17. package/dist/generator/zod/z/index.js +2 -0
  18. package/dist/generator/zod/z/integer.js +5 -4
  19. package/dist/generator/zod/z/number.js +4 -4
  20. package/dist/generator/zod/z/object.js +24 -17
  21. package/dist/generator/zod/z/string.js +5 -3
  22. package/dist/generator/zod-openapi-hono/app/index.js +8 -4
  23. package/dist/generator/zod-openapi-hono/handler/zod-openapi-hono-handler.js +2 -2
  24. package/dist/generator/zod-openapi-hono/openapi/route/params/index.d.ts +0 -1
  25. package/dist/generator/zod-openapi-hono/openapi/route/params/index.js +0 -1
  26. package/dist/generator/zod-openapi-hono/openapi/route/params/request-parameter.js +12 -6
  27. package/dist/helper/allof.js +7 -4
  28. package/dist/helper/anyof.js +0 -1
  29. package/dist/helper/const.d.ts +2 -0
  30. package/dist/helper/const.js +9 -0
  31. package/dist/{generator/zod-openapi-hono/app/helper → helper}/docs.d.ts +1 -1
  32. package/dist/{generator/zod-openapi-hono/app/helper → helper}/get-route-maps.d.ts +1 -1
  33. package/dist/{generator/zod-openapi-hono/app/helper → helper}/get-route-maps.js +1 -1
  34. package/dist/helper/index.d.ts +3 -0
  35. package/dist/helper/index.js +3 -0
  36. package/dist/helper/not.d.ts +2 -0
  37. package/dist/helper/not.js +25 -0
  38. package/dist/helper/oneof.js +12 -5
  39. package/dist/openapi/index.d.ts +8 -5
  40. package/dist/openapi/index.js +4 -5
  41. package/dist/typespec/index.d.ts +7 -2
  42. package/dist/typespec/index.js +9 -4
  43. package/dist/utils/index.d.ts +29 -117
  44. package/dist/utils/index.js +67 -158
  45. package/dist/vite-plugin/index.js +8 -26
  46. package/package.json +2 -2
  47. package/dist/cli/parse.d.ts +0 -16
  48. package/dist/cli/parse.js +0 -25
  49. package/dist/generator/zod/helper/array-reference-schema.d.ts +0 -31
  50. package/dist/generator/zod/helper/array-reference-schema.js +0 -40
  51. package/dist/generator/zod/helper/reference-schema.d.ts +0 -26
  52. package/dist/generator/zod/helper/reference-schema.js +0 -35
  53. package/dist/generator/zod/helper/zod-schema-from-sub-schema.d.ts +0 -22
  54. package/dist/generator/zod/helper/zod-schema-from-sub-schema.js +0 -25
  55. package/dist/generator/zod-openapi-hono/openapi/route/params/request-params-array.d.ts +0 -13
  56. package/dist/generator/zod-openapi-hono/openapi/route/params/request-params-array.js +0 -35
  57. /package/dist/{generator/zod-openapi-hono/app/helper → helper}/docs.js +0 -0
@@ -1,4 +1,4 @@
1
- import { type Result } from '../result/index.js';
1
+ import type { Result } from '../result/index.js';
2
2
  /**
3
3
  * CLI entry point for `hono-takibi`.
4
4
  *
package/dist/cli/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { asyncAndThen, ok } from '../result/index.js';
2
- import { isHelpRequested, sliceArgv } from '../utils/index.js';
3
- import { parseCli } from './parse.js';
2
+ import { parseCli } from '../utils/index.js';
4
3
  import { takibi } from './takibi.js';
5
4
  const HELP_TEXT = `Usage: hono-takibi <input.{yaml,json,tsp}> -o <routes.ts> [options]
6
5
 
@@ -17,8 +16,15 @@ Options:
17
16
  * @returns A `Result` containing help text or CLI execution result.
18
17
  */
19
18
  export async function honoTakibi() {
20
- const args = sliceArgv(process.argv);
21
- return isHelpRequested(sliceArgv(process.argv))
22
- ? ok({ message: HELP_TEXT })
23
- : 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)));
19
+ // Slice the arguments to remove the first two (node and script path)
20
+ const args = process.argv.slice(2);
21
+ const isHelpRequested = (args) => {
22
+ return args.length === 1 && (args[0] === '--help' || args[0] === '-h');
23
+ };
24
+ if (isHelpRequested(args)) {
25
+ return ok({
26
+ message: HELP_TEXT,
27
+ });
28
+ }
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)));
24
30
  }
@@ -1,8 +1,15 @@
1
- import type { Result } from '../result/index.js';
2
1
  /**
3
2
  * Formats TypeScript source with Prettier.
4
3
  *
5
4
  * @param code - Source code to format.
6
5
  * @returns A `Result` containing the formatted code or an error message.
7
6
  */
8
- export declare function fmt(code: string): Promise<Result<string, string>>;
7
+ export declare function fmt(code: string): Promise<{
8
+ ok: true;
9
+ value: string;
10
+ error?: undefined;
11
+ } | {
12
+ ok: false;
13
+ error: string;
14
+ value?: undefined;
15
+ }>;
@@ -1,18 +1,29 @@
1
- import type { Result } from '../result/index.js';
2
1
  /**
3
2
  * Creates a directory if it does not already exist.
4
3
  *
5
4
  * @param dir - Directory path to create.
6
5
  * @returns A `Result` that is `ok` on success, otherwise an error message.
7
6
  */
8
- export declare function mkdir(dir: string): Promise<Result<void, string>>;
7
+ export declare function mkdir(dir: string): Promise<{
8
+ ok: false;
9
+ error: string;
10
+ } | {
11
+ ok: true;
12
+ value: undefined;
13
+ }>;
9
14
  /**
10
15
  * Reads the contents of a directory.
11
16
  *
12
17
  * @param dir - Directory to read.
13
18
  * @returns A `Result` with the file list on success, otherwise an error message.
14
19
  */
15
- export declare function readdir(dir: string): Promise<Result<string[], string>>;
20
+ export declare function readdir(dir: string): Promise<{
21
+ ok: false;
22
+ error: string;
23
+ } | {
24
+ ok: true;
25
+ value: string[];
26
+ }>;
16
27
  /**
17
28
  * Writes UTF-8 text to a file, creating it if necessary.
18
29
  *
@@ -20,4 +31,10 @@ export declare function readdir(dir: string): Promise<Result<string[], string>>;
20
31
  * @param data - Text data to write.
21
32
  * @returns A `Result` that is `ok` on success, otherwise an error message.
22
33
  */
23
- export declare function writeFile(path: string, data: string): Promise<Result<void, string>>;
34
+ export declare function writeFile(path: string, data: string): Promise<{
35
+ ok: true;
36
+ value: undefined;
37
+ } | {
38
+ ok: false;
39
+ error: string;
40
+ }>;
package/dist/fsp/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import fsp from 'node:fs/promises';
2
- import { err, ok } from '../result/index.js';
3
2
  /**
4
3
  * Creates a directory if it does not already exist.
5
4
  *
@@ -9,10 +8,16 @@ import { err, ok } from '../result/index.js';
9
8
  export async function mkdir(dir) {
10
9
  try {
11
10
  await fsp.mkdir(dir, { recursive: true });
12
- return ok(undefined);
11
+ return {
12
+ ok: true,
13
+ value: undefined,
14
+ };
13
15
  }
14
16
  catch (e) {
15
- return err(e instanceof Error ? e.message : String(e));
17
+ return {
18
+ ok: false,
19
+ error: e instanceof Error ? e.message : String(e),
20
+ };
16
21
  }
17
22
  }
18
23
  /**
@@ -24,10 +29,14 @@ export async function mkdir(dir) {
24
29
  export async function readdir(dir) {
25
30
  try {
26
31
  const files = await fsp.readdir(dir);
27
- return ok(files);
32
+ // return ok(files)
33
+ return { ok: true, value: files };
28
34
  }
29
35
  catch (e) {
30
- return err(e instanceof Error ? e.message : String(e));
36
+ return {
37
+ ok: false,
38
+ error: e instanceof Error ? e.message : String(e),
39
+ };
31
40
  }
32
41
  }
33
42
  /**
@@ -40,9 +49,9 @@ export async function readdir(dir) {
40
49
  export async function writeFile(path, data) {
41
50
  try {
42
51
  await fsp.writeFile(path, data, 'utf-8');
43
- return ok(undefined);
52
+ return { ok: true, value: undefined };
44
53
  }
45
54
  catch (e) {
46
- return err(e instanceof Error ? e.message : String(e));
55
+ return { ok: false, error: e instanceof Error ? e.message : String(e) };
47
56
  }
48
57
  }
@@ -1,5 +1,2 @@
1
- export { arrayReferenceSchema } from './array-reference-schema.js';
2
1
  export { propertiesSchema } from './properties-schema.js';
3
2
  export { propertySchema } from './property-schema.js';
4
- export { referenceSchema } from './reference-schema.js';
5
- export { zodSchemaFromSubSchema } from './zod-schema-from-sub-schema.js';
@@ -1,5 +1,2 @@
1
- export { arrayReferenceSchema } from './array-reference-schema.js';
2
1
  export { propertiesSchema } from './properties-schema.js';
3
2
  export { propertySchema } from './property-schema.js';
4
- export { referenceSchema } from './reference-schema.js';
5
- export { zodSchemaFromSubSchema } from './zod-schema-from-sub-schema.js';
@@ -1,8 +1,6 @@
1
1
  import { zodToOpenAPI } from '../../../helper/zod-to-openapi.js';
2
- import { isArrayWithSchemaReference } from '../../../utils/index.js';
2
+ import { refName } from '../../../utils/index.js';
3
3
  import { zod } from '../index.js';
4
- import { arrayReferenceSchema } from './array-reference-schema.js';
5
- import { referenceSchema } from './reference-schema.js';
6
4
  /**
7
5
  * Generates a Zod-compatible schema string for a given property.
8
6
  *
@@ -30,10 +28,18 @@ import { referenceSchema } from './reference-schema.js';
30
28
  */
31
29
  export function propertySchema(schema) {
32
30
  if (Boolean(schema.$ref) === true) {
33
- return referenceSchema(schema);
31
+ if (schema.$ref) {
32
+ const ref = refName(schema.$ref);
33
+ return `${ref}Schema`;
34
+ }
35
+ return 'z.any()';
34
36
  }
35
- if (isArrayWithSchemaReference(schema)) {
36
- return arrayReferenceSchema(schema);
37
+ if (schema.type === 'array' && Boolean(schema.items?.$ref)) {
38
+ if (schema.items?.$ref) {
39
+ const ref = refName(schema.items.$ref);
40
+ return `z.array(${ref}Schema)`;
41
+ }
42
+ return 'z.array(z.any())';
37
43
  }
38
44
  return zodToOpenAPI(zod(schema), schema);
39
45
  }
@@ -1,8 +1,10 @@
1
1
  import { allOf } from '../../helper/allof.js';
2
2
  import { anyOf } from '../../helper/anyof.js';
3
+ import { _const } from '../../helper/const.js';
4
+ import { not } from '../../helper/not.js';
3
5
  import { oneOf } from '../../helper/oneof.js';
4
6
  import { refName } from '../../utils/index.js';
5
- import { _enum, array, integer, number, object, string } from './z/index.js';
7
+ import { _enum, array, boolean, date, integer, number, object, string } from './z/index.js';
6
8
  /**
7
9
  * Converts an OpenAPI `Schema` object into a Zod schema string.
8
10
  *
@@ -65,15 +67,13 @@ export function zod(schema) {
65
67
  }
66
68
  /* const */
67
69
  if (schema.const !== undefined) {
68
- const base = `z.literal(${JSON.stringify(schema.const)})`;
69
- const isNullable = schema.nullable === true ||
70
- (Array.isArray(schema.type) ? schema.type.includes('null') : schema.type === 'null');
71
- return isNullable ? `${base}.nullable()` : base;
70
+ return _const(schema);
72
71
  }
73
72
  /* enum */
74
73
  if (schema.enum) {
75
74
  return _enum(schema);
76
75
  }
76
+ /* properties */
77
77
  if (schema.properties) {
78
78
  return object(schema);
79
79
  }
@@ -82,16 +82,12 @@ export function zod(schema) {
82
82
  };
83
83
  const types = pickTypes(schema.type);
84
84
  /* object */
85
- if (pickTypes(schema.type).includes('object')) {
85
+ if (types.includes('object')) {
86
86
  return object(schema);
87
87
  }
88
88
  /* date */
89
89
  if (types.includes('date')) {
90
- const addNullable = (expr) => schema.nullable === true ||
91
- (Array.isArray(schema.type) ? schema.type.includes('null') : schema.type === 'null')
92
- ? `${expr}.nullable()`
93
- : expr;
94
- return addNullable('z.date()');
90
+ return date(schema);
95
91
  }
96
92
  /* string */
97
93
  if (types.includes('string')) {
@@ -111,11 +107,7 @@ export function zod(schema) {
111
107
  }
112
108
  /* boolean */
113
109
  if (types.includes('boolean')) {
114
- const addNullable = (expr) => schema.nullable === true ||
115
- (Array.isArray(schema.type) ? schema.type.includes('null') : schema.type === 'null')
116
- ? `${expr}.nullable()`
117
- : expr;
118
- return addNullable('z.boolean()');
110
+ return boolean(schema);
119
111
  }
120
112
  /* combinators */
121
113
  if (schema.oneOf) {
@@ -128,17 +120,12 @@ export function zod(schema) {
128
120
  return allOf(schema);
129
121
  }
130
122
  if (schema.not) {
131
- const isNullable = schema.nullable === true ||
132
- (Array.isArray(schema.type) ? schema.type.includes('null') : schema.type === 'null');
133
- if (isNullable) {
134
- return 'z.unknown().nullable()';
135
- }
136
- return 'z.unknown()';
123
+ return not(schema);
137
124
  }
138
125
  /* null only */
139
126
  if (types.length === 1 && types[0] === 'null') {
140
127
  return 'z.null()';
141
128
  }
142
- console.warn(`Unknown schema: ${JSON.stringify(schema)} - fallback to z.any()`);
129
+ console.warn('fallback to z.any()');
143
130
  return 'z.any()';
144
131
  }
@@ -1,23 +1,32 @@
1
1
  import { zod } from '../index.js';
2
2
  export function array(schema) {
3
- const z = `z.array(${schema.items ? zod(schema.items) : 'z.any()'})`;
3
+ const array = `z.array(${schema.items ? zod(schema.items) : 'z.any()'})`;
4
4
  const isNullable = schema.nullable === true ||
5
5
  (Array.isArray(schema.type) ? schema.type.includes('null') : schema.type === 'null');
6
6
  if (typeof schema.minItems === 'number' && typeof schema.maxItems === 'number') {
7
7
  if (schema.minItems === schema.maxItems) {
8
- return isNullable
9
- ? `${z}.length(${schema.minItems}).nullable()`
10
- : `${z}.length(${schema.minItems})`;
8
+ const z = isNullable
9
+ ? `${array}.length(${schema.minItems}).nullable()`
10
+ : `${array}.length(${schema.minItems})`;
11
+ return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
11
12
  }
12
- return isNullable
13
- ? `${z}.min(${schema.minItems}).max(${schema.maxItems}).nullable()`
14
- : `${z}.min(${schema.minItems}).max(${schema.maxItems})`;
13
+ const z = isNullable
14
+ ? `${array}.min(${schema.minItems}).max(${schema.maxItems}).nullable()`
15
+ : `${array}.min(${schema.minItems}).max(${schema.maxItems})`;
16
+ return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
15
17
  }
16
18
  if (typeof schema.minItems === 'number') {
17
- return isNullable ? `${z}.min(${schema.minItems}).nullable()` : `${z}.min(${schema.minItems})`;
19
+ const z = isNullable
20
+ ? `${array}.min(${schema.minItems}).nullable()`
21
+ : `${array}.min(${schema.minItems})`;
22
+ return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
18
23
  }
19
24
  if (typeof schema.maxItems === 'number') {
20
- return isNullable ? `${z}.max(${schema.maxItems}).nullable()` : `${z}.max(${schema.maxItems})`;
25
+ const z = isNullable
26
+ ? `${array}.max(${schema.maxItems}).nullable()`
27
+ : `${array}.max(${schema.maxItems})`;
28
+ return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
21
29
  }
22
- return isNullable ? `${z}.nullable()` : z;
30
+ const z = isNullable ? `${array}.nullable()` : array;
31
+ return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
23
32
  }
@@ -0,0 +1,2 @@
1
+ import type { Schema } from '../../../openapi/index.js';
2
+ export declare function boolean(schema: Schema): string;
@@ -0,0 +1,6 @@
1
+ export function boolean(schema) {
2
+ const isNullable = schema.nullable === true ||
3
+ (Array.isArray(schema.type) ? schema.type.includes('null') : schema.type === 'null');
4
+ const z = isNullable ? 'z.boolean().nullable()' : 'z.boolean()';
5
+ return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
6
+ }
@@ -0,0 +1,2 @@
1
+ import type { Schema } from '../../../openapi/index.js';
2
+ export declare function date(schema: Schema): string;
@@ -0,0 +1,6 @@
1
+ export function date(schema) {
2
+ const isNullable = schema.nullable === true ||
3
+ (Array.isArray(schema.type) ? schema.type.includes('null') : schema.type === 'null');
4
+ const z = isNullable ? 'z.date().nullable()' : 'z.date()';
5
+ return schema.default ? `${z}.default(new Date(${JSON.stringify(schema.default)}))` : z;
6
+ }
@@ -4,24 +4,25 @@
4
4
  export function _enum(schema) {
5
5
  const isNullable = schema.nullable === true ||
6
6
  (Array.isArray(schema.type) ? schema.type.includes('null') : schema.type === 'null');
7
- const wrapNullable = (expr) => (isNullable ? `${expr}.nullable()` : expr);
8
7
  // number
9
8
  if (schema.type === 'number' && schema.enum) {
10
- const expr = schema.enum.length > 1
9
+ const _enum = schema.enum.length > 1
11
10
  ? `z.union([${schema.enum.map((v) => `z.literal(${v})`).join(',')}])`
12
11
  : `z.literal(${schema.enum[0]})`;
13
- return wrapNullable(expr);
12
+ const z = isNullable ? `${_enum}.nullable()` : _enum;
13
+ return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
14
14
  }
15
15
  // integer
16
16
  if (schema.type === 'integer' && schema.enum) {
17
- const expr = schema.enum.length > 1
17
+ const _enum = schema.enum.length > 1
18
18
  ? `z.union([${schema.enum.map((v) => `z.literal(${v})`).join(',')}])`
19
19
  : `z.literal(${schema.enum[0]})`;
20
- return wrapNullable(expr);
20
+ const z = isNullable ? `${_enum}.nullable()` : _enum;
21
+ return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
21
22
  }
22
23
  // array
23
24
  if (schema.type === 'array' && Array.isArray(schema.enum)) {
24
- const expr = (() => {
25
+ const _enum = (() => {
25
26
  if (schema.enum.length === 1 && Array.isArray(schema.enum[0])) {
26
27
  const tupleItems = schema.enum[0].map((item) => `z.literal(${item})`).join(', ');
27
28
  return `z.tuple([${tupleItems}])`;
@@ -35,29 +36,37 @@ export function _enum(schema) {
35
36
  });
36
37
  return `z.union([${unionParts.join(',')}])`;
37
38
  })();
38
- return wrapNullable(expr);
39
+ const z = isNullable ? `${_enum}.nullable()` : _enum;
40
+ return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
39
41
  }
40
42
  // boolean
41
43
  if (schema.type === 'boolean' && schema.enum) {
42
- const expr = schema.enum.length > 1
44
+ const _enum = schema.enum.length > 1
43
45
  ? `z.union([${schema.enum.map((v) => `z.literal(${v})`).join(',')}])`
44
46
  : `z.literal(${schema.enum[0]})`;
45
- return wrapNullable(expr);
47
+ const z = isNullable ? `${_enum}.nullable()` : _enum;
48
+ return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
46
49
  }
50
+ // enum
47
51
  if (schema.enum) {
48
- const expr = (() => {
52
+ const _enum = (() => {
49
53
  if (schema.enum.length > 1) {
50
54
  const allStrings = schema.enum.every((v) => typeof v === 'string');
51
55
  if (allStrings) {
52
56
  return `z.enum(${JSON.stringify(schema.enum)})`;
53
57
  }
54
58
  const unionLiterals = schema.enum.map((v) => v === null ? 'z.null()' : `z.literal(${typeof v === 'string' ? `'${v}'` : v})`);
59
+ // if (schema.discriminator?.propertyName) {
60
+ // return `z.discriminatedUnion('${schema.discriminator.propertyName}',[${unionLiterals.join(',')}])`
61
+ // }
55
62
  return `z.union([${unionLiterals.join(',')}])`;
56
63
  }
57
64
  const v = schema.enum[0];
58
65
  return `z.literal(${typeof v === 'string' ? `'${v}'` : v})`;
59
66
  })();
60
- return wrapNullable(expr);
67
+ const z = isNullable ? `${_enum}.nullable()` : _enum;
68
+ return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
61
69
  }
62
- return 'z.any()';
70
+ const z = isNullable ? 'z.any().nullable()' : 'z.any()';
71
+ return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
63
72
  }
@@ -1,4 +1,6 @@
1
1
  export { array } from './array.js';
2
+ export { boolean } from './boolean.js';
3
+ export { date } from './date.js';
2
4
  export { _enum } from './enum.js';
3
5
  export { integer } from './integer.js';
4
6
  export { number } from './number.js';
@@ -1,4 +1,6 @@
1
1
  export { array } from './array.js';
2
+ export { boolean } from './boolean.js';
3
+ export { date } from './date.js';
2
4
  export { _enum } from './enum.js';
3
5
  export { integer } from './integer.js';
4
6
  export { number } from './number.js';
@@ -87,14 +87,15 @@ export function integer(schema) {
87
87
  if (schema.multipleOf !== undefined && typeof schema.multipleOf === 'number') {
88
88
  o.push(`.multipleOf(${lit(schema.multipleOf)})`);
89
89
  }
90
- // default (always last)
91
- if (schema.default !== undefined && typeof schema.default === 'number') {
92
- o.push(`.default(${lit(schema.default)})`);
93
- }
90
+ // nullable
94
91
  const isNullable = schema.nullable === true ||
95
92
  (Array.isArray(schema.type) ? schema.type.includes('null') : schema.type === 'null');
96
93
  if (isNullable) {
97
94
  o.push('.nullable()');
98
95
  }
96
+ // default (always last)
97
+ if (schema.default !== undefined && typeof schema.default === 'number') {
98
+ o.push(`.default(${lit(schema.default)})`);
99
+ }
99
100
  return o.join('');
100
101
  }
@@ -77,15 +77,15 @@ export function number(schema) {
77
77
  if (schema.multipleOf !== undefined) {
78
78
  o.push(`.multipleOf(${schema.multipleOf})`);
79
79
  }
80
- // default
81
- if (schema.default !== undefined) {
82
- o.push(`.default(${JSON.stringify(schema.default)})`);
83
- }
84
80
  // nullable
85
81
  const isNullable = schema.nullable === true ||
86
82
  (Array.isArray(schema.type) ? schema.type.includes('null') : schema.type === 'null');
87
83
  if (isNullable) {
88
84
  o.push('.nullable()');
89
85
  }
86
+ // default (always last)
87
+ if (schema.default !== undefined) {
88
+ o.push(`.default(${JSON.stringify(schema.default)})`);
89
+ }
90
90
  return o.join('');
91
91
  }
@@ -1,5 +1,6 @@
1
1
  import { allOf } from '../../../helper/allof.js';
2
2
  import { anyOf } from '../../../helper/anyof.js';
3
+ import { not } from '../../../helper/not.js';
3
4
  import { oneOf } from '../../../helper/oneof.js';
4
5
  import { zodToOpenAPI } from '../../../helper/zod-to-openapi.js';
5
6
  import { propertiesSchema } from '../helper/properties-schema.js';
@@ -13,42 +14,48 @@ import { zod } from '../index.js';
13
14
  export function object(schema) {
14
15
  const isNullable = schema.nullable === true ||
15
16
  (Array.isArray(schema.type) ? schema.type.includes('null') : schema.type === 'null');
16
- const addNullable = (expr) => (isNullable ? `${expr}.nullable()` : expr);
17
17
  if (schema.additionalProperties) {
18
18
  if (typeof schema.additionalProperties === 'boolean') {
19
19
  if (schema.properties) {
20
20
  const z = propertiesSchema(schema.properties, Array.isArray(schema.required) ? schema.required : []);
21
21
  if (schema.additionalProperties === true) {
22
- return addNullable(z.replace('object', 'looseObject'));
22
+ if (isNullable) {
23
+ return `${z.replace('object', 'looseObject')}.nullable()`;
24
+ }
25
+ return z.replace('object', 'looseObject');
23
26
  }
24
27
  }
25
- return addNullable('z.any()');
28
+ const z = isNullable ? 'z.any().nullable()' : 'z.any()';
29
+ return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
26
30
  }
27
- const value = zodToOpenAPI(zod(schema.additionalProperties), schema.additionalProperties);
28
- return addNullable(`z.record(z.string(),${value})`);
31
+ const s = zodToOpenAPI(zod(schema.additionalProperties), schema.additionalProperties);
32
+ const z = isNullable ? `z.record(z.string(),${s}).nullable()` : `z.record(z.string(),${s})`;
33
+ return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
29
34
  }
30
35
  if (schema.properties) {
31
- const zodSchema = propertiesSchema(schema.properties, Array.isArray(schema.required) ? schema.required : []);
36
+ const s = propertiesSchema(schema.properties, Array.isArray(schema.required) ? schema.required : []);
32
37
  if (schema.additionalProperties === false) {
33
- return addNullable(zodSchema.replace('object', 'strictObject'));
38
+ const z = isNullable
39
+ ? `${s.replace('object', 'strictObject')}.nullable()`
40
+ : s.replace('object', 'strictObject');
41
+ return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
34
42
  }
35
- return addNullable(zodSchema);
36
- }
37
- // call allOf, oneOf, anyOf, or not use addNullable
38
- if (schema.allOf) {
39
- return allOf(schema);
43
+ const z = isNullable ? `${s}.nullable()` : s;
44
+ return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
40
45
  }
46
+ // allOf, oneOf, anyOf, not
41
47
  if (schema.oneOf) {
42
48
  return oneOf(schema);
43
49
  }
44
50
  if (schema.anyOf) {
45
51
  return anyOf(schema);
46
52
  }
53
+ if (schema.allOf) {
54
+ return allOf(schema);
55
+ }
47
56
  if (schema.not) {
48
- if (isNullable) {
49
- return 'z.unknown().nullable()';
50
- }
51
- return 'z.unknown()';
57
+ return not(schema);
52
58
  }
53
- return addNullable('z.object({})');
59
+ const z = isNullable ? 'z.object({}).nullable()' : 'z.object({})';
60
+ return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
54
61
  }
@@ -32,9 +32,11 @@ export function string(schema) {
32
32
  const o = [];
33
33
  const format = schema.format && FORMAT_STRING[schema.format];
34
34
  o.push(format ? `z.${format}` : 'z.string()');
35
+ // pattern
35
36
  if (schema.pattern) {
36
37
  o.push(regex(schema.pattern));
37
38
  }
39
+ // length
38
40
  if (schema.minLength !== undefined &&
39
41
  schema.maxLength !== undefined &&
40
42
  schema.minLength === schema.maxLength) {
@@ -48,13 +50,13 @@ export function string(schema) {
48
50
  o.push(`.max(${schema.maxLength})`);
49
51
  }
50
52
  }
51
- if (schema.default !== undefined) {
52
- o.push(`.default(${JSON.stringify(schema.default)})`);
53
- }
54
53
  const isNullable = schema.nullable === true ||
55
54
  (Array.isArray(schema.type) ? schema.type.includes('null') : schema.type === 'null');
56
55
  if (isNullable) {
57
56
  o.push('.nullable()');
58
57
  }
58
+ if (schema.default !== undefined) {
59
+ o.push(`.default(${JSON.stringify(schema.default)})`);
60
+ }
59
61
  return o.join('');
60
62
  }
@@ -1,6 +1,6 @@
1
- import { applyOpenapiRoutes, getHandlerImports, importHandlers, importMap, importRoutes, registerComponent, } from '../../../utils/index.js';
2
- import { docs } from './helper/docs.js';
3
- import { getRouteMaps } from './helper/get-route-maps.js';
1
+ import { docs } from '../../../helper/docs.js';
2
+ import { getRouteMaps } from '../../../helper/get-route-maps.js';
3
+ import { getHandlerImports, importHandlers, importMap, importRoutes, registerComponent, } from '../../../utils/index.js';
4
4
  /**
5
5
  * Generates a Hono app with OpenAPI and Swagger UI integration.
6
6
  *
@@ -26,7 +26,11 @@ export function app(openapi, output, basePath) {
26
26
  basePath
27
27
  ? `${'const app = new OpenAPIHono()'}.basePath('${basePath}')`
28
28
  : 'const app = new OpenAPIHono()',
29
- `export const api = ${`app${applyOpenapiRoutes(routeMappings)}`}`,
29
+ `export const api = ${`app${routeMappings
30
+ .map(({ routeName, handlerName }) => {
31
+ return `.openapi(${routeName},${handlerName})`;
32
+ })
33
+ .join('\n')}`}`,
30
34
  swagger,
31
35
  'export type AddType = typeof api',
32
36
  'export default app',
@@ -1,6 +1,6 @@
1
1
  import { fmt } from '../../../format/index.js';
2
2
  import { mkdir, writeFile } from '../../../fsp/index.js';
3
- import { groupHandlersByFileName, handler, routeName } from '../../../utils/index.js';
3
+ import { groupHandlersByFileName, routeName } from '../../../utils/index.js';
4
4
  /**
5
5
  * Generates route handler files for a Hono app using Zod and OpenAPI.
6
6
  *
@@ -14,7 +14,7 @@ export async function zodOpenapiHonoHandler(openapi, output, test) {
14
14
  const handlers = [];
15
15
  for (const [path, pathItem] of Object.entries(paths)) {
16
16
  for (const [method] of Object.entries(pathItem)) {
17
- const routeHandlerContent = handler(`${routeName(method, path)}Handler`, routeName(method, path));
17
+ const routeHandlerContent = `export const ${routeName(method, path)}Handler:RouteHandler<typeof ${routeName(method, path)}>=async(c)=>{}`;
18
18
  const rawSegment = path.replace(/^\/+/, '').split('/')[0] ?? '';
19
19
  const pathName = (rawSegment === '' ? 'index' : rawSegment)
20
20
  .replace(/\{([^}]+)\}/g, '$1')
@@ -1,4 +1,3 @@
1
1
  export { paramsObject } from './params-object.js';
2
2
  export { queryParameter } from './query-parameter.js';
3
3
  export { requestParameter } from './request-parameter.js';
4
- export { requestParamsArray } from './request-params-array.js';
@@ -1,4 +1,3 @@
1
1
  export { paramsObject } from './params-object.js';
2
2
  export { queryParameter } from './query-parameter.js';
3
3
  export { requestParameter } from './request-parameter.js';
4
- export { requestParamsArray } from './request-params-array.js';