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.
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +12 -6
- package/dist/format/index.d.ts +9 -2
- package/dist/fsp/index.d.ts +21 -4
- package/dist/fsp/index.js +16 -7
- package/dist/generator/zod/helper/index.d.ts +0 -3
- package/dist/generator/zod/helper/index.js +0 -3
- package/dist/generator/zod/helper/property-schema.js +12 -6
- package/dist/generator/zod/index.js +10 -23
- package/dist/generator/zod/z/array.js +19 -10
- package/dist/generator/zod/z/boolean.d.ts +2 -0
- package/dist/generator/zod/z/boolean.js +6 -0
- package/dist/generator/zod/z/date.d.ts +2 -0
- package/dist/generator/zod/z/date.js +6 -0
- package/dist/generator/zod/z/enum.js +21 -12
- package/dist/generator/zod/z/index.d.ts +2 -0
- package/dist/generator/zod/z/index.js +2 -0
- package/dist/generator/zod/z/integer.js +5 -4
- package/dist/generator/zod/z/number.js +4 -4
- package/dist/generator/zod/z/object.js +24 -17
- package/dist/generator/zod/z/string.js +5 -3
- package/dist/generator/zod-openapi-hono/app/index.js +8 -4
- package/dist/generator/zod-openapi-hono/handler/zod-openapi-hono-handler.js +2 -2
- package/dist/generator/zod-openapi-hono/openapi/route/params/index.d.ts +0 -1
- package/dist/generator/zod-openapi-hono/openapi/route/params/index.js +0 -1
- package/dist/generator/zod-openapi-hono/openapi/route/params/request-parameter.js +12 -6
- package/dist/helper/allof.js +7 -4
- package/dist/helper/anyof.js +0 -1
- package/dist/helper/const.d.ts +2 -0
- package/dist/helper/const.js +9 -0
- package/dist/{generator/zod-openapi-hono/app/helper → helper}/docs.d.ts +1 -1
- package/dist/{generator/zod-openapi-hono/app/helper → helper}/get-route-maps.d.ts +1 -1
- package/dist/{generator/zod-openapi-hono/app/helper → helper}/get-route-maps.js +1 -1
- package/dist/helper/index.d.ts +3 -0
- package/dist/helper/index.js +3 -0
- package/dist/helper/not.d.ts +2 -0
- package/dist/helper/not.js +25 -0
- package/dist/helper/oneof.js +12 -5
- package/dist/openapi/index.d.ts +8 -5
- package/dist/openapi/index.js +4 -5
- package/dist/typespec/index.d.ts +7 -2
- package/dist/typespec/index.js +9 -4
- package/dist/utils/index.d.ts +29 -117
- package/dist/utils/index.js +67 -158
- package/dist/vite-plugin/index.js +8 -26
- package/package.json +2 -2
- package/dist/cli/parse.d.ts +0 -16
- package/dist/cli/parse.js +0 -25
- package/dist/generator/zod/helper/array-reference-schema.d.ts +0 -31
- package/dist/generator/zod/helper/array-reference-schema.js +0 -40
- package/dist/generator/zod/helper/reference-schema.d.ts +0 -26
- package/dist/generator/zod/helper/reference-schema.js +0 -35
- package/dist/generator/zod/helper/zod-schema-from-sub-schema.d.ts +0 -22
- package/dist/generator/zod/helper/zod-schema-from-sub-schema.js +0 -25
- package/dist/generator/zod-openapi-hono/openapi/route/params/request-params-array.d.ts +0 -13
- package/dist/generator/zod-openapi-hono/openapi/route/params/request-params-array.js +0 -35
- /package/dist/{generator/zod-openapi-hono/app/helper → helper}/docs.js +0 -0
package/dist/cli/index.d.ts
CHANGED
package/dist/cli/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { asyncAndThen, ok } from '../result/index.js';
|
|
2
|
-
import {
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
}
|
package/dist/format/index.d.ts
CHANGED
|
@@ -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<
|
|
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
|
+
}>;
|
package/dist/fsp/index.d.ts
CHANGED
|
@@ -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<
|
|
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<
|
|
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<
|
|
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
|
|
11
|
+
return {
|
|
12
|
+
ok: true,
|
|
13
|
+
value: undefined,
|
|
14
|
+
};
|
|
13
15
|
}
|
|
14
16
|
catch (e) {
|
|
15
|
-
return
|
|
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
|
|
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
|
|
52
|
+
return { ok: true, value: undefined };
|
|
44
53
|
}
|
|
45
54
|
catch (e) {
|
|
46
|
-
return
|
|
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 {
|
|
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
|
-
|
|
31
|
+
if (schema.$ref) {
|
|
32
|
+
const ref = refName(schema.$ref);
|
|
33
|
+
return `${ref}Schema`;
|
|
34
|
+
}
|
|
35
|
+
return 'z.any()';
|
|
34
36
|
}
|
|
35
|
-
if (
|
|
36
|
-
|
|
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
|
-
|
|
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 (
|
|
85
|
+
if (types.includes('object')) {
|
|
86
86
|
return object(schema);
|
|
87
87
|
}
|
|
88
88
|
/* date */
|
|
89
89
|
if (types.includes('date')) {
|
|
90
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
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
|
-
|
|
9
|
-
? `${
|
|
10
|
-
: `${
|
|
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
|
-
|
|
13
|
-
? `${
|
|
14
|
-
: `${
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
30
|
+
const z = isNullable ? `${array}.nullable()` : array;
|
|
31
|
+
return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
|
|
23
32
|
}
|
|
@@ -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,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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
67
|
+
const z = isNullable ? `${_enum}.nullable()` : _enum;
|
|
68
|
+
return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
|
|
61
69
|
}
|
|
62
|
-
|
|
70
|
+
const z = isNullable ? 'z.any().nullable()' : 'z.any()';
|
|
71
|
+
return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
|
|
63
72
|
}
|
|
@@ -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
|
-
//
|
|
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
|
-
|
|
22
|
+
if (isNullable) {
|
|
23
|
+
return `${z.replace('object', 'looseObject')}.nullable()`;
|
|
24
|
+
}
|
|
25
|
+
return z.replace('object', 'looseObject');
|
|
23
26
|
}
|
|
24
27
|
}
|
|
25
|
-
|
|
28
|
+
const z = isNullable ? 'z.any().nullable()' : 'z.any()';
|
|
29
|
+
return schema.default ? `${z}.default(${JSON.stringify(schema.default)})` : z;
|
|
26
30
|
}
|
|
27
|
-
const
|
|
28
|
-
|
|
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
|
|
36
|
+
const s = propertiesSchema(schema.properties, Array.isArray(schema.required) ? schema.required : []);
|
|
32
37
|
if (schema.additionalProperties === false) {
|
|
33
|
-
|
|
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
|
-
|
|
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
|
-
|
|
49
|
-
return 'z.unknown().nullable()';
|
|
50
|
-
}
|
|
51
|
-
return 'z.unknown()';
|
|
57
|
+
return not(schema);
|
|
52
58
|
}
|
|
53
|
-
|
|
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 {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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${
|
|
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,
|
|
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 =
|
|
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')
|