@lovrozagar/honey 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1596 -6
- package/dist/accepts.d.ts +6 -0
- package/dist/accepts.d.ts.map +1 -0
- package/dist/body-limit.d.ts +22 -0
- package/dist/body-limit.d.ts.map +1 -0
- package/dist/build/index.d.ts +42 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/client/error.d.ts +14 -0
- package/dist/client/error.d.ts.map +1 -0
- package/dist/client/http.d.ts +88 -0
- package/dist/client/http.d.ts.map +1 -0
- package/dist/client/index.d.ts +22 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/sdk.d.ts +34 -0
- package/dist/client/sdk.d.ts.map +1 -0
- package/dist/client/sse.d.ts +10 -0
- package/dist/client/sse.d.ts.map +1 -0
- package/dist/client/types.d.ts +124 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/ws.d.ts +15 -0
- package/dist/client/ws.d.ts.map +1 -0
- package/dist/client-mcp/server.d.ts +10 -0
- package/dist/client-mcp/server.d.ts.map +1 -0
- package/dist/client-mcp/types.d.ts +16 -0
- package/dist/client-mcp/types.d.ts.map +1 -0
- package/dist/cloudflare/realtime.d.ts +30 -0
- package/dist/cloudflare/realtime.d.ts.map +1 -0
- package/dist/codegen-go-cli.d.ts +22 -0
- package/dist/codegen-go-cli.d.ts.map +1 -0
- package/dist/codegen-go.d.ts +29 -0
- package/dist/codegen-go.d.ts.map +1 -0
- package/dist/codegen-hash.d.ts +3 -0
- package/dist/codegen-hash.d.ts.map +1 -0
- package/dist/codegen-ir.d.ts +123 -0
- package/dist/codegen-ir.d.ts.map +1 -0
- package/dist/codegen-loaders.d.ts +12 -0
- package/dist/codegen-loaders.d.ts.map +1 -0
- package/dist/codegen-mcp.d.ts +13 -0
- package/dist/codegen-mcp.d.ts.map +1 -0
- package/dist/codegen-python.d.ts +21 -0
- package/dist/codegen-python.d.ts.map +1 -0
- package/dist/codegen-rust.d.ts +18 -0
- package/dist/codegen-rust.d.ts.map +1 -0
- package/dist/codegen-sanitize.d.ts +3 -0
- package/dist/codegen-sanitize.d.ts.map +1 -0
- package/dist/codegen-schema-naming.d.ts +22 -0
- package/dist/codegen-schema-naming.d.ts.map +1 -0
- package/dist/codegen.d.ts +178 -0
- package/dist/codegen.d.ts.map +1 -0
- package/dist/context.d.ts +56 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/cookie-sign.d.ts +3 -0
- package/dist/cookie-sign.d.ts.map +1 -0
- package/dist/cookie.d.ts +12 -0
- package/dist/cookie.d.ts.map +1 -0
- package/dist/cors.d.ts +13 -0
- package/dist/cors.d.ts.map +1 -0
- package/dist/crypto.d.ts +2 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/csrf.d.ts +9 -0
- package/dist/csrf.d.ts.map +1 -0
- package/dist/curl-logger.d.ts +33 -0
- package/dist/curl-logger.d.ts.map +1 -0
- package/dist/detect-runtime.d.ts +16 -0
- package/dist/detect-runtime.d.ts.map +1 -0
- package/dist/error.d.ts +21 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/errors.d.ts +40 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/etag.d.ts +9 -0
- package/dist/etag.d.ts.map +1 -0
- package/dist/feature-load.d.ts +3 -0
- package/dist/feature-load.d.ts.map +1 -0
- package/dist/go-type-emitter.d.ts +33 -0
- package/dist/go-type-emitter.d.ts.map +1 -0
- package/dist/honey-response.d.ts +82 -0
- package/dist/honey-response.d.ts.map +1 -0
- package/dist/i18n-slot.d.ts +7 -0
- package/dist/i18n-slot.d.ts.map +1 -0
- package/dist/i18n.d.ts +26 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/index.d.ts +470 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/init.d.ts +7 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/input.d.ts +6 -0
- package/dist/input.d.ts.map +1 -0
- package/dist/ip-restrict.d.ts +12 -0
- package/dist/ip-restrict.d.ts.map +1 -0
- package/dist/logger.d.ts +45 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/meta-spec.d.ts +81 -0
- package/dist/meta-spec.d.ts.map +1 -0
- package/dist/middleware.d.ts +60 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/node-request.d.ts +59 -0
- package/dist/node-request.d.ts.map +1 -0
- package/dist/node.d.ts +13 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/openapi/register.d.ts +3 -0
- package/dist/openapi/register.d.ts.map +1 -0
- package/dist/openapi/scalar.d.ts +12 -0
- package/dist/openapi/scalar.d.ts.map +1 -0
- package/dist/openapi/spec-factory.d.ts +31 -0
- package/dist/openapi/spec-factory.d.ts.map +1 -0
- package/dist/openapi/spec.d.ts +19 -0
- package/dist/openapi/spec.d.ts.map +1 -0
- package/dist/openapi/swagger.d.ts +12 -0
- package/dist/openapi/swagger.d.ts.map +1 -0
- package/dist/plugin.d.ts +167 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/powered-by.d.ts +7 -0
- package/dist/powered-by.d.ts.map +1 -0
- package/dist/pretty-json.d.ts +10 -0
- package/dist/pretty-json.d.ts.map +1 -0
- package/dist/proxy.d.ts +51 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/python-type-emitter.d.ts +11 -0
- package/dist/python-type-emitter.d.ts.map +1 -0
- package/dist/realtime/buffer.d.ts +18 -0
- package/dist/realtime/buffer.d.ts.map +1 -0
- package/dist/realtime/bus.d.ts +11 -0
- package/dist/realtime/bus.d.ts.map +1 -0
- package/dist/realtime/longpoll.d.ts +23 -0
- package/dist/realtime/longpoll.d.ts.map +1 -0
- package/dist/realtime/protocol.d.ts +50 -0
- package/dist/realtime/protocol.d.ts.map +1 -0
- package/dist/realtime/route.d.ts +42 -0
- package/dist/realtime/route.d.ts.map +1 -0
- package/dist/realtime/runtime.d.ts +74 -0
- package/dist/realtime/runtime.d.ts.map +1 -0
- package/dist/request-id.d.ts +12 -0
- package/dist/request-id.d.ts.map +1 -0
- package/dist/request-to-curl.d.ts +9 -0
- package/dist/request-to-curl.d.ts.map +1 -0
- package/dist/response.d.ts +57 -0
- package/dist/response.d.ts.map +1 -0
- package/dist/rust-type-emitter.d.ts +32 -0
- package/dist/rust-type-emitter.d.ts.map +1 -0
- package/dist/secure-headers.d.ts +16 -0
- package/dist/secure-headers.d.ts.map +1 -0
- package/dist/serve-register.d.ts +2 -0
- package/dist/serve-register.d.ts.map +1 -0
- package/dist/serve-slot.d.ts +6 -0
- package/dist/serve-slot.d.ts.map +1 -0
- package/dist/serve.d.ts +21 -0
- package/dist/serve.d.ts.map +1 -0
- package/dist/server-timing.d.ts +9 -0
- package/dist/server-timing.d.ts.map +1 -0
- package/dist/static.d.ts +12 -0
- package/dist/static.d.ts.map +1 -0
- package/dist/telemetry/otel.d.ts +59 -0
- package/dist/telemetry/otel.d.ts.map +1 -0
- package/dist/testing.d.ts +24 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/timeout.d.ts +7 -0
- package/dist/timeout.d.ts.map +1 -0
- package/dist/tree.d.ts +90 -0
- package/dist/tree.d.ts.map +1 -0
- package/dist/ts-type-emitter.d.ts +4 -0
- package/dist/ts-type-emitter.d.ts.map +1 -0
- package/dist/type-emitter.d.ts +8 -0
- package/dist/type-emitter.d.ts.map +1 -0
- package/dist/type-extractor.d.ts +39 -0
- package/dist/type-extractor.d.ts.map +1 -0
- package/dist/types.d.ts +451 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/validation.d.ts +18 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/ws/bun.d.ts +28 -0
- package/dist/ws/bun.d.ts.map +1 -0
- package/dist/ws/cloudflare.d.ts +55 -0
- package/dist/ws/cloudflare.d.ts.map +1 -0
- package/dist/ws/deno.d.ts +13 -0
- package/dist/ws/deno.d.ts.map +1 -0
- package/dist/ws/node.d.ts +10 -0
- package/dist/ws/node.d.ts.map +1 -0
- package/dist/yaml.d.ts +4 -0
- package/dist/yaml.d.ts.map +1 -0
- package/docs/api-ref/go.md +82 -82
- package/docs/api-ref/python.md +82 -82
- package/docs/api-ref/rust.md +82 -82
- package/docs/api-ref/typescript.md +82 -82
- package/docs/invalidate-spec.md +13 -13
- package/docs/meta-spec.md +513 -0
- package/docs/packaging.md +85 -0
- package/docs/sdk.md +87 -73
- package/package.json +195 -51
- package/src/body-limit.ts +2 -1
- package/src/build/index.ts +2 -9
- package/src/cli.ts +2 -3
- package/src/client/http.ts +204 -223
- package/src/client/index.ts +6 -14
- package/src/client/sdk.ts +24 -17
- package/src/client/types.ts +4 -9
- package/src/client/ws.ts +3 -5
- package/src/client-mcp/server.ts +1 -4
- package/src/cloudflare/realtime.ts +8 -10
- package/src/codegen-go-cli.ts +74 -67
- package/src/codegen-go.ts +71 -51
- package/src/codegen-ir.ts +16 -27
- package/src/codegen-loaders.ts +5 -8
- package/src/codegen-mcp.ts +9 -27
- package/src/codegen-python.ts +47 -27
- package/src/codegen-rust.ts +110 -66
- package/src/codegen-sanitize.ts +1 -7
- package/src/codegen-schema-naming.ts +8 -2
- package/src/codegen.ts +299 -196
- package/src/context.ts +91 -95
- package/src/cookie-sign.ts +5 -13
- package/src/cookie.ts +1 -2
- package/src/cors.ts +4 -6
- package/src/crypto.ts +1 -4
- package/src/csrf.ts +3 -3
- package/src/curl-logger.ts +14 -32
- package/src/detect-runtime.ts +1 -3
- package/src/errors.ts +1 -3
- package/src/etag.ts +3 -4
- package/src/go-type-emitter.ts +45 -40
- package/src/honey-response.ts +1 -3
- package/src/i18n.ts +3 -12
- package/src/index.ts +1168 -1412
- package/src/ip-restrict.ts +2 -1
- package/src/logger.ts +13 -13
- package/src/meta-spec.ts +0 -0
- package/src/middleware.ts +111 -79
- package/src/node-request.ts +2 -1
- package/src/node.ts +9 -10
- package/src/openapi/register.ts +1 -2
- package/src/openapi/scalar.ts +9 -9
- package/src/openapi/spec-factory.ts +2 -2
- package/src/openapi/spec.ts +26 -19
- package/src/openapi/swagger.ts +9 -9
- package/src/plugin.ts +226 -256
- package/src/powered-by.ts +2 -1
- package/src/pretty-json.ts +2 -1
- package/src/proxy.ts +1 -3
- package/src/python-type-emitter.ts +37 -12
- package/src/realtime/route.ts +1 -1
- package/src/realtime/runtime.ts +9 -12
- package/src/request-id.ts +3 -4
- package/src/request-to-curl.ts +1 -4
- package/src/response.ts +150 -199
- package/src/rust-type-emitter.ts +66 -25
- package/src/secure-headers.ts +2 -1
- package/src/serve.ts +3 -12
- package/src/server-timing.ts +2 -1
- package/src/static.ts +3 -4
- package/src/telemetry/otel.ts +1 -6
- package/src/testing.ts +2 -11
- package/src/timeout.ts +2 -1
- package/src/tree.ts +12 -27
- package/src/ts-type-emitter.ts +71 -15
- package/src/type-emitter.ts +226 -237
- package/src/type-extractor.ts +260 -334
- package/src/types.ts +168 -68
- package/src/validation.ts +7 -30
- package/src/ws/bun.ts +2 -9
- package/src/ws/cloudflare.ts +13 -16
- package/src/ws/deno.ts +31 -40
- package/src/ws/node.ts +4 -19
package/src/type-emitter.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { StandardSchemaLike } from "./types.ts"
|
|
1
|
+
import type { StandardSchemaLike } from "./types.ts"
|
|
2
2
|
|
|
3
|
-
const SAFE_KEY_RE = /^[a-zA-Z_$][a-zA-Z0-9_$]
|
|
3
|
+
const SAFE_KEY_RE = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/
|
|
4
4
|
|
|
5
5
|
function quoteKey(key: string): string {
|
|
6
|
-
return SAFE_KEY_RE.test(key) ? key : `"${key}"
|
|
6
|
+
return SAFE_KEY_RE.test(key) ? key : `"${key}"`
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
/** Wrap element type in parens when it contains union/intersection before appending [] */
|
|
@@ -17,13 +17,13 @@ function arrayOf(el: string): string {
|
|
|
17
17
|
* Unknown vendors return "unknown".
|
|
18
18
|
*/
|
|
19
19
|
export function emitSchemaType(schema: StandardSchemaLike): string {
|
|
20
|
-
const vendor = schema["~standard"].vendor
|
|
21
|
-
if (vendor === "zod") return emitZod(schema)
|
|
22
|
-
if (vendor === "valibot") return emitValibot(schema)
|
|
23
|
-
if (vendor === "arktype") return emitArkType(schema)
|
|
24
|
-
if (vendor === "yup") return emitYup(schema)
|
|
25
|
-
if (vendor === "effect") return emitEffect(schema)
|
|
26
|
-
return "unknown"
|
|
20
|
+
const vendor = schema["~standard"].vendor
|
|
21
|
+
if (vendor === "zod") return emitZod(schema)
|
|
22
|
+
if (vendor === "valibot") return emitValibot(schema)
|
|
23
|
+
if (vendor === "arktype") return emitArkType(schema)
|
|
24
|
+
if (vendor === "yup") return emitYup(schema)
|
|
25
|
+
if (vendor === "effect") return emitEffect(schema)
|
|
26
|
+
return "unknown"
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/* ---- Zod emitter (handles both full zod and zod/mini) ---- */
|
|
@@ -32,7 +32,14 @@ export function emitSchemaType(schema: StandardSchemaLike): string {
|
|
|
32
32
|
function zodIsOptional(def: Record<string, unknown>): boolean {
|
|
33
33
|
const t = (def.typeName as string) ?? (def.type as string)
|
|
34
34
|
if (t === "ZodOptional" || t === "optional") return true
|
|
35
|
-
if (
|
|
35
|
+
if (
|
|
36
|
+
t === "ZodNullable" ||
|
|
37
|
+
t === "nullable" ||
|
|
38
|
+
t === "ZodDefault" ||
|
|
39
|
+
t === "default" ||
|
|
40
|
+
t === "ZodCatch" ||
|
|
41
|
+
t === "catch"
|
|
42
|
+
) {
|
|
36
43
|
const inner = def.innerType as unknown
|
|
37
44
|
if (inner) return zodIsOptional(zodDef(inner))
|
|
38
45
|
}
|
|
@@ -40,485 +47,467 @@ function zodIsOptional(def: Record<string, unknown>): boolean {
|
|
|
40
47
|
}
|
|
41
48
|
|
|
42
49
|
function zodDef(schema: unknown): Record<string, unknown> {
|
|
43
|
-
const s = schema as Record<string, unknown
|
|
44
|
-
return (s._def ?? s.def) as Record<string, unknown
|
|
50
|
+
const s = schema as Record<string, unknown>
|
|
51
|
+
return (s._def ?? s.def) as Record<string, unknown>
|
|
45
52
|
}
|
|
46
53
|
|
|
47
54
|
function emitZod(schema: unknown): string {
|
|
48
|
-
const def = zodDef(schema)
|
|
49
|
-
if (!def) return "unknown"
|
|
50
|
-
const typeName = (def.typeName ?? def.type) as string
|
|
55
|
+
const def = zodDef(schema)
|
|
56
|
+
if (!def) return "unknown"
|
|
57
|
+
const typeName = (def.typeName ?? def.type) as string
|
|
51
58
|
|
|
52
59
|
switch (typeName) {
|
|
53
60
|
case "ZodString":
|
|
54
61
|
case "string":
|
|
55
|
-
return "string"
|
|
62
|
+
return "string"
|
|
56
63
|
case "ZodNumber":
|
|
57
64
|
case "number":
|
|
58
|
-
return "number"
|
|
65
|
+
return "number"
|
|
59
66
|
case "ZodBoolean":
|
|
60
67
|
case "boolean":
|
|
61
|
-
return "boolean"
|
|
68
|
+
return "boolean"
|
|
62
69
|
case "ZodBigInt":
|
|
63
70
|
case "bigint":
|
|
64
|
-
return "bigint"
|
|
71
|
+
return "bigint"
|
|
65
72
|
case "ZodDate":
|
|
66
73
|
case "date":
|
|
67
|
-
return "Date"
|
|
74
|
+
return "Date"
|
|
68
75
|
case "ZodUndefined":
|
|
69
76
|
case "undefined":
|
|
70
|
-
return "undefined"
|
|
77
|
+
return "undefined"
|
|
71
78
|
case "ZodNull":
|
|
72
79
|
case "null":
|
|
73
|
-
return "null"
|
|
80
|
+
return "null"
|
|
74
81
|
case "ZodVoid":
|
|
75
82
|
case "void":
|
|
76
|
-
return "void"
|
|
83
|
+
return "void"
|
|
77
84
|
case "ZodAny":
|
|
78
85
|
case "ZodUnknown":
|
|
79
86
|
case "any":
|
|
80
87
|
case "unknown":
|
|
81
|
-
return "unknown"
|
|
88
|
+
return "unknown"
|
|
82
89
|
case "ZodNever":
|
|
83
90
|
case "never":
|
|
84
|
-
return "never"
|
|
91
|
+
return "never"
|
|
85
92
|
case "ZodLiteral":
|
|
86
93
|
case "literal": {
|
|
87
94
|
/* v4: single value, v3: values array */
|
|
88
|
-
const val = def.value as unknown
|
|
89
|
-
if (val !== undefined)
|
|
90
|
-
|
|
91
|
-
const values = def.values as unknown[];
|
|
95
|
+
const val = def.value as unknown
|
|
96
|
+
if (val !== undefined) return typeof val === "string" ? `"${val}"` : String(val)
|
|
97
|
+
const values = def.values as unknown[]
|
|
92
98
|
if (values.length === 1) {
|
|
93
|
-
const v0 = values[0]
|
|
94
|
-
return typeof v0 === "string" ? `"${v0}"` : String(v0)
|
|
99
|
+
const v0 = values[0]
|
|
100
|
+
return typeof v0 === "string" ? `"${v0}"` : String(v0)
|
|
95
101
|
}
|
|
96
|
-
return values
|
|
97
|
-
.map((v0) => (typeof v0 === "string" ? `"${v0}"` : String(v0)))
|
|
98
|
-
.join(" | ");
|
|
102
|
+
return values.map((v0) => (typeof v0 === "string" ? `"${v0}"` : String(v0))).join(" | ")
|
|
99
103
|
}
|
|
100
104
|
case "ZodEnum":
|
|
101
105
|
case "enum": {
|
|
102
106
|
/* v4: values array, v3/mini: entries record */
|
|
103
|
-
const vals = (def.values ?? def.entries) as unknown
|
|
104
|
-
if (Array.isArray(vals)) return vals.map((v0) => `"${v0}"`).join(" | ")
|
|
107
|
+
const vals = (def.values ?? def.entries) as unknown
|
|
108
|
+
if (Array.isArray(vals)) return vals.map((v0) => `"${v0}"`).join(" | ")
|
|
105
109
|
return Object.values(vals as Record<string, string>)
|
|
106
110
|
.map((v0) => `"${v0}"`)
|
|
107
|
-
.join(" | ")
|
|
111
|
+
.join(" | ")
|
|
108
112
|
}
|
|
109
113
|
case "ZodObject":
|
|
110
114
|
case "object": {
|
|
111
|
-
const rawShape = def.shape as
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const keys = Object.keys(shape);
|
|
116
|
-
if (keys.length === 0) return "{}";
|
|
115
|
+
const rawShape = def.shape as Record<string, unknown> | (() => Record<string, unknown>)
|
|
116
|
+
const shape = typeof rawShape === "function" ? rawShape() : rawShape
|
|
117
|
+
const keys = Object.keys(shape)
|
|
118
|
+
if (keys.length === 0) return "{}"
|
|
117
119
|
return `{ ${keys
|
|
118
120
|
.map((k) => {
|
|
119
|
-
const propDef = zodDef(shape[k])
|
|
120
|
-
const isOpt = propDef && zodIsOptional(propDef)
|
|
121
|
-
return `${quoteKey(k)}${isOpt ? "?" : ""}: ${emitZod(shape[k])}
|
|
121
|
+
const propDef = zodDef(shape[k])
|
|
122
|
+
const isOpt = propDef && zodIsOptional(propDef)
|
|
123
|
+
return `${quoteKey(k)}${isOpt ? "?" : ""}: ${emitZod(shape[k])}`
|
|
122
124
|
})
|
|
123
|
-
.join("; ")} }
|
|
125
|
+
.join("; ")} }`
|
|
124
126
|
}
|
|
125
127
|
case "ZodArray":
|
|
126
128
|
/* v4: _def.type is the element schema */
|
|
127
|
-
return arrayOf(emitZod((def.type ?? def.element) as unknown))
|
|
129
|
+
return arrayOf(emitZod((def.type ?? def.element) as unknown))
|
|
128
130
|
case "array":
|
|
129
|
-
return arrayOf(emitZod(def.element as unknown))
|
|
131
|
+
return arrayOf(emitZod(def.element as unknown))
|
|
130
132
|
case "ZodOptional":
|
|
131
133
|
case "optional":
|
|
132
|
-
return `${emitZod(def.innerType as unknown)} | undefined
|
|
134
|
+
return `${emitZod(def.innerType as unknown)} | undefined`
|
|
133
135
|
case "ZodNullable":
|
|
134
136
|
case "nullable":
|
|
135
|
-
return `${emitZod(def.innerType as unknown)} | null
|
|
137
|
+
return `${emitZod(def.innerType as unknown)} | null`
|
|
136
138
|
case "ZodUnion":
|
|
137
139
|
case "ZodDiscriminatedUnion":
|
|
138
140
|
case "union":
|
|
139
|
-
return (def.options as unknown[]).map((o) => emitZod(o)).join(" | ")
|
|
141
|
+
return (def.options as unknown[]).map((o) => emitZod(o)).join(" | ")
|
|
140
142
|
case "ZodIntersection":
|
|
141
143
|
case "intersection":
|
|
142
|
-
return `${emitZod(def.left as unknown)} & ${emitZod(def.right as unknown)}
|
|
144
|
+
return `${emitZod(def.left as unknown)} & ${emitZod(def.right as unknown)}`
|
|
143
145
|
case "ZodRecord":
|
|
144
146
|
case "record":
|
|
145
|
-
return `Partial<Record<${emitZod(def.keyType as unknown)}, ${emitZod(def.valueType as unknown)}
|
|
147
|
+
return `Partial<Record<${emitZod(def.keyType as unknown)}, ${emitZod(def.valueType as unknown)}>>`
|
|
146
148
|
case "ZodTuple":
|
|
147
149
|
case "tuple":
|
|
148
|
-
return `[${(def.items as unknown[]).map((i) => emitZod(i)).join(", ")}]
|
|
150
|
+
return `[${(def.items as unknown[]).map((i) => emitZod(i)).join(", ")}]`
|
|
149
151
|
case "ZodDefault":
|
|
150
152
|
case "ZodCatch":
|
|
151
153
|
case "default":
|
|
152
154
|
case "catch":
|
|
153
|
-
return emitZod(def.innerType as unknown)
|
|
155
|
+
return emitZod(def.innerType as unknown)
|
|
154
156
|
case "ZodReadonly":
|
|
155
157
|
case "readonly":
|
|
156
|
-
return `Readonly<${emitZod(def.innerType as unknown)}
|
|
158
|
+
return `Readonly<${emitZod(def.innerType as unknown)}>`
|
|
157
159
|
case "ZodPipeline":
|
|
158
160
|
case "pipe":
|
|
159
|
-
return emitZod(def.out as unknown)
|
|
161
|
+
return emitZod(def.out as unknown)
|
|
160
162
|
case "ZodBranded":
|
|
161
|
-
return emitZod(def.type as unknown)
|
|
163
|
+
return emitZod(def.type as unknown)
|
|
162
164
|
case "ZodLazy":
|
|
163
165
|
case "lazy":
|
|
164
|
-
return "unknown"
|
|
166
|
+
return "unknown"
|
|
165
167
|
default:
|
|
166
|
-
return "unknown"
|
|
168
|
+
return "unknown"
|
|
167
169
|
}
|
|
168
170
|
}
|
|
169
171
|
|
|
170
172
|
/* ---- Valibot emitter ---- */
|
|
171
173
|
|
|
172
174
|
function emitValibot(schema: unknown): string {
|
|
173
|
-
const s = schema as Record<string, unknown
|
|
174
|
-
const type = s.type as string | undefined
|
|
175
|
-
if (!type) return "unknown"
|
|
175
|
+
const s = schema as Record<string, unknown>
|
|
176
|
+
const type = s.type as string | undefined
|
|
177
|
+
if (!type) return "unknown"
|
|
176
178
|
|
|
177
179
|
switch (type) {
|
|
178
180
|
case "string":
|
|
179
|
-
return "string"
|
|
181
|
+
return "string"
|
|
180
182
|
case "number":
|
|
181
|
-
return "number"
|
|
183
|
+
return "number"
|
|
182
184
|
case "boolean":
|
|
183
|
-
return "boolean"
|
|
185
|
+
return "boolean"
|
|
184
186
|
case "bigint":
|
|
185
|
-
return "bigint"
|
|
187
|
+
return "bigint"
|
|
186
188
|
case "date":
|
|
187
|
-
return "Date"
|
|
189
|
+
return "Date"
|
|
188
190
|
case "undefined":
|
|
189
|
-
return "undefined"
|
|
191
|
+
return "undefined"
|
|
190
192
|
case "null":
|
|
191
|
-
return "null"
|
|
193
|
+
return "null"
|
|
192
194
|
case "void":
|
|
193
|
-
return "void"
|
|
195
|
+
return "void"
|
|
194
196
|
case "any":
|
|
195
197
|
case "unknown":
|
|
196
|
-
return "unknown"
|
|
198
|
+
return "unknown"
|
|
197
199
|
case "never":
|
|
198
|
-
return "never"
|
|
200
|
+
return "never"
|
|
199
201
|
case "literal": {
|
|
200
|
-
const val = s.literal as unknown
|
|
201
|
-
return typeof val === "string" ? `"${val}"` : String(val)
|
|
202
|
+
const val = s.literal as unknown
|
|
203
|
+
return typeof val === "string" ? `"${val}"` : String(val)
|
|
202
204
|
}
|
|
203
205
|
case "enum": {
|
|
204
|
-
const enumObj = s.enum as Record<string, string
|
|
206
|
+
const enumObj = s.enum as Record<string, string>
|
|
205
207
|
return Object.values(enumObj)
|
|
206
208
|
.map((val) => `"${val}"`)
|
|
207
|
-
.join(" | ")
|
|
209
|
+
.join(" | ")
|
|
208
210
|
}
|
|
209
211
|
case "picklist": {
|
|
210
|
-
const options = s.options as unknown[]
|
|
211
|
-
return options
|
|
212
|
-
.map((val) => (typeof val === "string" ? `"${val}"` : String(val)))
|
|
213
|
-
.join(" | ");
|
|
212
|
+
const options = s.options as unknown[]
|
|
213
|
+
return options.map((val) => (typeof val === "string" ? `"${val}"` : String(val))).join(" | ")
|
|
214
214
|
}
|
|
215
215
|
case "object": {
|
|
216
|
-
const entries = s.entries as Record<string, unknown
|
|
217
|
-
const keys = Object.keys(entries)
|
|
218
|
-
if (keys.length === 0) return "{}"
|
|
216
|
+
const entries = s.entries as Record<string, unknown>
|
|
217
|
+
const keys = Object.keys(entries)
|
|
218
|
+
if (keys.length === 0) return "{}"
|
|
219
219
|
return `{ ${keys
|
|
220
220
|
.map((k) => {
|
|
221
|
-
const propType = (entries[k] as Record<string, unknown>).type as
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const isOpt = propType === "optional" || propType === "nullish";
|
|
225
|
-
return `${quoteKey(k)}${isOpt ? "?" : ""}: ${emitValibot(entries[k])}`;
|
|
221
|
+
const propType = (entries[k] as Record<string, unknown>).type as string | undefined
|
|
222
|
+
const isOpt = propType === "optional" || propType === "nullish"
|
|
223
|
+
return `${quoteKey(k)}${isOpt ? "?" : ""}: ${emitValibot(entries[k])}`
|
|
226
224
|
})
|
|
227
|
-
.join("; ")} }
|
|
225
|
+
.join("; ")} }`
|
|
228
226
|
}
|
|
229
227
|
case "array":
|
|
230
|
-
return arrayOf(emitValibot(s.item as unknown))
|
|
228
|
+
return arrayOf(emitValibot(s.item as unknown))
|
|
231
229
|
case "optional":
|
|
232
|
-
return `${emitValibot(s.wrapped as unknown)} | undefined
|
|
230
|
+
return `${emitValibot(s.wrapped as unknown)} | undefined`
|
|
233
231
|
case "nullable":
|
|
234
|
-
return `${emitValibot(s.wrapped as unknown)} | null
|
|
232
|
+
return `${emitValibot(s.wrapped as unknown)} | null`
|
|
235
233
|
case "nullish":
|
|
236
|
-
return `${emitValibot(s.wrapped as unknown)} | null | undefined
|
|
234
|
+
return `${emitValibot(s.wrapped as unknown)} | null | undefined`
|
|
237
235
|
case "union":
|
|
238
|
-
return (s.options as unknown[]).map((o) => emitValibot(o)).join(" | ")
|
|
236
|
+
return (s.options as unknown[]).map((o) => emitValibot(o)).join(" | ")
|
|
239
237
|
case "intersect":
|
|
240
|
-
return (s.options as unknown[]).map((o) => emitValibot(o)).join(" & ")
|
|
238
|
+
return (s.options as unknown[]).map((o) => emitValibot(o)).join(" & ")
|
|
241
239
|
case "record":
|
|
242
|
-
return `Record<${emitValibot(s.key as unknown)}, ${emitValibot(s.value as unknown)}
|
|
240
|
+
return `Record<${emitValibot(s.key as unknown)}, ${emitValibot(s.value as unknown)}>`
|
|
243
241
|
case "tuple":
|
|
244
|
-
return `[${(s.items as unknown[]).map((i) => emitValibot(i)).join(", ")}]
|
|
242
|
+
return `[${(s.items as unknown[]).map((i) => emitValibot(i)).join(", ")}]`
|
|
245
243
|
default:
|
|
246
|
-
return "unknown"
|
|
244
|
+
return "unknown"
|
|
247
245
|
}
|
|
248
246
|
}
|
|
249
247
|
|
|
250
248
|
/* ---- ArkType emitter ---- */
|
|
251
249
|
|
|
252
250
|
function emitArkType(schema: unknown): string {
|
|
253
|
-
const s = schema as Record<string, unknown
|
|
254
|
-
const json = s.json as unknown
|
|
255
|
-
if (json === undefined || json === null) return "unknown"
|
|
256
|
-
return emitArkJson(json)
|
|
251
|
+
const s = schema as Record<string, unknown>
|
|
252
|
+
const json = s.json as unknown
|
|
253
|
+
if (json === undefined || json === null) return "unknown"
|
|
254
|
+
return emitArkJson(json)
|
|
257
255
|
}
|
|
258
256
|
|
|
259
|
-
type ArkEntry = { key: string; value: unknown }
|
|
257
|
+
type ArkEntry = { key: string; value: unknown }
|
|
260
258
|
|
|
261
259
|
function isBooleanUnion(node: unknown[]): boolean {
|
|
262
|
-
if (node.length !== 2) return false
|
|
260
|
+
if (node.length !== 2) return false
|
|
263
261
|
const units = node.map((n) => {
|
|
264
262
|
if (typeof n === "object" && n !== null && "unit" in n) {
|
|
265
|
-
return (n as Record<string, unknown>).unit
|
|
263
|
+
return (n as Record<string, unknown>).unit
|
|
266
264
|
}
|
|
267
|
-
return undefined
|
|
268
|
-
})
|
|
269
|
-
return (
|
|
270
|
-
(units[0] === false && units[1] === true) ||
|
|
271
|
-
(units[0] === true && units[1] === false)
|
|
272
|
-
);
|
|
265
|
+
return undefined
|
|
266
|
+
})
|
|
267
|
+
return (units[0] === false && units[1] === true) || (units[0] === true && units[1] === false)
|
|
273
268
|
}
|
|
274
269
|
|
|
275
270
|
function emitArkJson(node: unknown): string {
|
|
276
|
-
if (typeof node === "string") return mapArkDomain(node)
|
|
271
|
+
if (typeof node === "string") return mapArkDomain(node)
|
|
277
272
|
|
|
278
273
|
if (Array.isArray(node)) {
|
|
279
|
-
if (node.length === 0) return "never"
|
|
280
|
-
if (isBooleanUnion(node)) return "boolean"
|
|
281
|
-
return node.map((n) => emitArkJson(n)).join(" | ")
|
|
274
|
+
if (node.length === 0) return "never"
|
|
275
|
+
if (isBooleanUnion(node)) return "boolean"
|
|
276
|
+
return node.map((n) => emitArkJson(n)).join(" | ")
|
|
282
277
|
}
|
|
283
278
|
|
|
284
|
-
const obj = node as Record<string, unknown
|
|
279
|
+
const obj = node as Record<string, unknown>
|
|
285
280
|
|
|
286
281
|
if ("unit" in obj) {
|
|
287
|
-
const val = obj.unit
|
|
288
|
-
if (val === null) return "null"
|
|
282
|
+
const val = obj.unit
|
|
283
|
+
if (val === null) return "null"
|
|
289
284
|
/* arktype serializes undefined as the string "undefined" in JSON */
|
|
290
|
-
if (val === "undefined") return "undefined"
|
|
291
|
-
return typeof val === "string" ? `"${val}"` : String(val)
|
|
285
|
+
if (val === "undefined") return "undefined"
|
|
286
|
+
return typeof val === "string" ? `"${val}"` : String(val)
|
|
292
287
|
}
|
|
293
288
|
|
|
294
289
|
if ("sequence" in obj) {
|
|
295
|
-
return arrayOf(emitArkJson(obj.sequence))
|
|
290
|
+
return arrayOf(emitArkJson(obj.sequence))
|
|
296
291
|
}
|
|
297
292
|
|
|
298
293
|
if ("proto" in obj) {
|
|
299
|
-
return mapArkProto(obj.proto as string)
|
|
294
|
+
return mapArkProto(obj.proto as string)
|
|
300
295
|
}
|
|
301
296
|
|
|
302
297
|
if ("domain" in obj) {
|
|
303
|
-
const domain = obj.domain as string
|
|
298
|
+
const domain = obj.domain as string
|
|
304
299
|
|
|
305
300
|
if (domain === "object") {
|
|
306
|
-
const required = (obj.required as ArkEntry[] | undefined) ?? []
|
|
307
|
-
const optional = (obj.optional as ArkEntry[] | undefined) ?? []
|
|
308
|
-
if (required.length === 0 && optional.length === 0) return "{}"
|
|
309
|
-
const parts: string[] = []
|
|
301
|
+
const required = (obj.required as ArkEntry[] | undefined) ?? []
|
|
302
|
+
const optional = (obj.optional as ArkEntry[] | undefined) ?? []
|
|
303
|
+
if (required.length === 0 && optional.length === 0) return "{}"
|
|
304
|
+
const parts: string[] = []
|
|
310
305
|
for (const entry of required) {
|
|
311
|
-
parts.push(
|
|
312
|
-
`${quoteKey(String(entry.key))}: ${emitArkJson(entry.value)}`,
|
|
313
|
-
);
|
|
306
|
+
parts.push(`${quoteKey(String(entry.key))}: ${emitArkJson(entry.value)}`)
|
|
314
307
|
}
|
|
315
308
|
for (const entry of optional) {
|
|
316
|
-
parts.push(
|
|
317
|
-
`${quoteKey(String(entry.key))}?: ${emitArkJson(entry.value)}`,
|
|
318
|
-
);
|
|
309
|
+
parts.push(`${quoteKey(String(entry.key))}?: ${emitArkJson(entry.value)}`)
|
|
319
310
|
}
|
|
320
|
-
return `{ ${parts.join("; ")} }
|
|
311
|
+
return `{ ${parts.join("; ")} }`
|
|
321
312
|
}
|
|
322
313
|
|
|
323
|
-
return mapArkDomain(domain)
|
|
314
|
+
return mapArkDomain(domain)
|
|
324
315
|
}
|
|
325
316
|
|
|
326
|
-
return "unknown"
|
|
317
|
+
return "unknown"
|
|
327
318
|
}
|
|
328
319
|
|
|
329
320
|
function mapArkDomain(domain: string): string {
|
|
330
321
|
switch (domain) {
|
|
331
322
|
case "string":
|
|
332
|
-
return "string"
|
|
323
|
+
return "string"
|
|
333
324
|
case "number":
|
|
334
325
|
case "integer":
|
|
335
|
-
return "number"
|
|
326
|
+
return "number"
|
|
336
327
|
case "boolean":
|
|
337
|
-
return "boolean"
|
|
328
|
+
return "boolean"
|
|
338
329
|
case "bigint":
|
|
339
|
-
return "bigint"
|
|
330
|
+
return "bigint"
|
|
340
331
|
case "symbol":
|
|
341
|
-
return "symbol"
|
|
332
|
+
return "symbol"
|
|
342
333
|
case "undefined":
|
|
343
|
-
return "undefined"
|
|
334
|
+
return "undefined"
|
|
344
335
|
case "null":
|
|
345
|
-
return "null"
|
|
336
|
+
return "null"
|
|
346
337
|
case "object":
|
|
347
|
-
return "object"
|
|
338
|
+
return "object"
|
|
348
339
|
default:
|
|
349
|
-
return "unknown"
|
|
340
|
+
return "unknown"
|
|
350
341
|
}
|
|
351
342
|
}
|
|
352
343
|
|
|
353
344
|
function mapArkProto(proto: string): string {
|
|
354
345
|
switch (proto) {
|
|
355
346
|
case "Date":
|
|
356
|
-
return "Date"
|
|
347
|
+
return "Date"
|
|
357
348
|
case "Array":
|
|
358
|
-
return "unknown[]"
|
|
349
|
+
return "unknown[]"
|
|
359
350
|
case "RegExp":
|
|
360
|
-
return "RegExp"
|
|
351
|
+
return "RegExp"
|
|
361
352
|
case "Map":
|
|
362
|
-
return "Map<unknown, unknown>"
|
|
353
|
+
return "Map<unknown, unknown>"
|
|
363
354
|
case "Set":
|
|
364
|
-
return "Set<unknown>"
|
|
355
|
+
return "Set<unknown>"
|
|
365
356
|
default:
|
|
366
|
-
return "unknown"
|
|
357
|
+
return "unknown"
|
|
367
358
|
}
|
|
368
359
|
}
|
|
369
360
|
|
|
370
361
|
/* ---- Yup emitter ---- */
|
|
371
362
|
|
|
372
363
|
type YupDesc = {
|
|
373
|
-
fields?: Record<string, YupDesc
|
|
374
|
-
innerType?: YupDesc | YupDesc[]
|
|
375
|
-
nullable?: boolean
|
|
376
|
-
oneOf?: unknown[]
|
|
377
|
-
optional?: boolean
|
|
378
|
-
type: string
|
|
379
|
-
}
|
|
364
|
+
fields?: Record<string, YupDesc>
|
|
365
|
+
innerType?: YupDesc | YupDesc[]
|
|
366
|
+
nullable?: boolean
|
|
367
|
+
oneOf?: unknown[]
|
|
368
|
+
optional?: boolean
|
|
369
|
+
type: string
|
|
370
|
+
}
|
|
380
371
|
|
|
381
372
|
function emitYup(schema: unknown): string {
|
|
382
|
-
const s = schema as Record<string, unknown
|
|
383
|
-
if (typeof s.describe !== "function") return "unknown"
|
|
384
|
-
const desc = s.describe() as YupDesc
|
|
385
|
-
return emitYupDesc(desc)
|
|
373
|
+
const s = schema as Record<string, unknown>
|
|
374
|
+
if (typeof s.describe !== "function") return "unknown"
|
|
375
|
+
const desc = s.describe() as YupDesc
|
|
376
|
+
return emitYupDesc(desc)
|
|
386
377
|
}
|
|
387
378
|
|
|
388
379
|
function emitYupDesc(desc: YupDesc): string {
|
|
389
|
-
let base = emitYupBase(desc)
|
|
390
|
-
if (desc.nullable) base = `${base} | null
|
|
391
|
-
return base
|
|
380
|
+
let base = emitYupBase(desc)
|
|
381
|
+
if (desc.nullable) base = `${base} | null`
|
|
382
|
+
return base
|
|
392
383
|
}
|
|
393
384
|
|
|
394
385
|
function emitYupBase(desc: YupDesc): string {
|
|
395
386
|
switch (desc.type) {
|
|
396
387
|
case "string":
|
|
397
|
-
return "string"
|
|
388
|
+
return "string"
|
|
398
389
|
case "number":
|
|
399
|
-
return "number"
|
|
390
|
+
return "number"
|
|
400
391
|
case "boolean":
|
|
401
|
-
return "boolean"
|
|
392
|
+
return "boolean"
|
|
402
393
|
case "date":
|
|
403
|
-
return "Date"
|
|
394
|
+
return "Date"
|
|
404
395
|
case "object": {
|
|
405
|
-
if (!desc.fields) return "{}"
|
|
406
|
-
const keys = Object.keys(desc.fields)
|
|
407
|
-
if (keys.length === 0) return "{}"
|
|
396
|
+
if (!desc.fields) return "{}"
|
|
397
|
+
const keys = Object.keys(desc.fields)
|
|
398
|
+
if (keys.length === 0) return "{}"
|
|
408
399
|
const parts = keys.map((k) => {
|
|
409
|
-
const field = desc.fields?.[k]
|
|
410
|
-
if (!field) return `${quoteKey(k)}: unknown
|
|
411
|
-
const opt = field.optional ? "?" : ""
|
|
412
|
-
return `${quoteKey(k)}${opt}: ${emitYupDesc(field)}
|
|
413
|
-
})
|
|
414
|
-
return `{ ${parts.join("; ")} }
|
|
400
|
+
const field = desc.fields?.[k]
|
|
401
|
+
if (!field) return `${quoteKey(k)}: unknown`
|
|
402
|
+
const opt = field.optional ? "?" : ""
|
|
403
|
+
return `${quoteKey(k)}${opt}: ${emitYupDesc(field)}`
|
|
404
|
+
})
|
|
405
|
+
return `{ ${parts.join("; ")} }`
|
|
415
406
|
}
|
|
416
407
|
case "array": {
|
|
417
|
-
if (!desc.innerType || Array.isArray(desc.innerType)) return "unknown[]"
|
|
418
|
-
return arrayOf(emitYupDesc(desc.innerType))
|
|
408
|
+
if (!desc.innerType || Array.isArray(desc.innerType)) return "unknown[]"
|
|
409
|
+
return arrayOf(emitYupDesc(desc.innerType))
|
|
419
410
|
}
|
|
420
411
|
case "tuple": {
|
|
421
|
-
if (!Array.isArray(desc.innerType)) return "unknown"
|
|
422
|
-
return `[${desc.innerType.map((i) => emitYupDesc(i)).join(", ")}]
|
|
412
|
+
if (!Array.isArray(desc.innerType)) return "unknown"
|
|
413
|
+
return `[${desc.innerType.map((i) => emitYupDesc(i)).join(", ")}]`
|
|
423
414
|
}
|
|
424
415
|
case "mixed": {
|
|
425
416
|
if (desc.oneOf && desc.oneOf.length > 0) {
|
|
426
|
-
return desc.oneOf
|
|
427
|
-
.map((val) => (typeof val === "string" ? `"${val}"` : String(val)))
|
|
428
|
-
.join(" | ");
|
|
417
|
+
return desc.oneOf.map((val) => (typeof val === "string" ? `"${val}"` : String(val))).join(" | ")
|
|
429
418
|
}
|
|
430
|
-
return "unknown"
|
|
419
|
+
return "unknown"
|
|
431
420
|
}
|
|
432
421
|
case "lazy":
|
|
433
|
-
return "unknown"
|
|
422
|
+
return "unknown"
|
|
434
423
|
default:
|
|
435
|
-
return "unknown"
|
|
424
|
+
return "unknown"
|
|
436
425
|
}
|
|
437
426
|
}
|
|
438
427
|
|
|
439
428
|
/* ---- Effect Schema emitter ---- */
|
|
440
429
|
|
|
441
430
|
type EffectAST = {
|
|
442
|
-
_tag: string
|
|
443
|
-
elements?: Array<{ isOptional: boolean; type: EffectAST }
|
|
444
|
-
indexSignatures?: Array<{ parameter: EffectAST; type: EffectAST }
|
|
445
|
-
literal?: unknown
|
|
431
|
+
_tag: string
|
|
432
|
+
elements?: Array<{ isOptional: boolean; type: EffectAST }>
|
|
433
|
+
indexSignatures?: Array<{ parameter: EffectAST; type: EffectAST }>
|
|
434
|
+
literal?: unknown
|
|
446
435
|
propertySignatures?: Array<{
|
|
447
|
-
isOptional: boolean
|
|
448
|
-
name: string
|
|
449
|
-
type: EffectAST
|
|
450
|
-
}
|
|
451
|
-
rest?: Array<{ type: EffectAST }
|
|
452
|
-
types?: EffectAST[]
|
|
453
|
-
}
|
|
436
|
+
isOptional: boolean
|
|
437
|
+
name: string
|
|
438
|
+
type: EffectAST
|
|
439
|
+
}>
|
|
440
|
+
rest?: Array<{ type: EffectAST }>
|
|
441
|
+
types?: EffectAST[]
|
|
442
|
+
}
|
|
454
443
|
|
|
455
444
|
function emitEffect(schema: unknown): string {
|
|
456
|
-
const s = schema as Record<string, unknown
|
|
457
|
-
const ast = s.ast as EffectAST | undefined
|
|
458
|
-
if (!ast) return "unknown"
|
|
459
|
-
return emitEffectAst(ast)
|
|
445
|
+
const s = schema as Record<string, unknown>
|
|
446
|
+
const ast = s.ast as EffectAST | undefined
|
|
447
|
+
if (!ast) return "unknown"
|
|
448
|
+
return emitEffectAst(ast)
|
|
460
449
|
}
|
|
461
450
|
|
|
462
451
|
function emitEffectAst(ast: EffectAST): string {
|
|
463
452
|
switch (ast._tag) {
|
|
464
453
|
case "StringKeyword":
|
|
465
|
-
return "string"
|
|
454
|
+
return "string"
|
|
466
455
|
case "NumberKeyword":
|
|
467
|
-
return "number"
|
|
456
|
+
return "number"
|
|
468
457
|
case "BooleanKeyword":
|
|
469
|
-
return "boolean"
|
|
458
|
+
return "boolean"
|
|
470
459
|
case "BigIntKeyword":
|
|
471
|
-
return "bigint"
|
|
460
|
+
return "bigint"
|
|
472
461
|
case "SymbolKeyword":
|
|
473
|
-
return "symbol"
|
|
462
|
+
return "symbol"
|
|
474
463
|
case "UndefinedKeyword":
|
|
475
|
-
return "undefined"
|
|
464
|
+
return "undefined"
|
|
476
465
|
case "VoidKeyword":
|
|
477
|
-
return "void"
|
|
466
|
+
return "void"
|
|
478
467
|
case "UnknownKeyword":
|
|
479
468
|
case "AnyKeyword":
|
|
480
|
-
return "unknown"
|
|
469
|
+
return "unknown"
|
|
481
470
|
case "NeverKeyword":
|
|
482
|
-
return "never"
|
|
471
|
+
return "never"
|
|
483
472
|
case "ObjectKeyword":
|
|
484
|
-
return "object"
|
|
473
|
+
return "object"
|
|
485
474
|
case "Literal": {
|
|
486
|
-
const val = ast.literal
|
|
487
|
-
if (val === null) return "null"
|
|
488
|
-
return typeof val === "string" ? `"${val}"` : String(val)
|
|
475
|
+
const val = ast.literal
|
|
476
|
+
if (val === null) return "null"
|
|
477
|
+
return typeof val === "string" ? `"${val}"` : String(val)
|
|
489
478
|
}
|
|
490
479
|
case "Union":
|
|
491
|
-
return (ast.types ?? []).map((t) => emitEffectAst(t)).join(" | ")
|
|
480
|
+
return (ast.types ?? []).map((t) => emitEffectAst(t)).join(" | ")
|
|
492
481
|
case "TypeLiteral": {
|
|
493
|
-
const props = ast.propertySignatures ?? []
|
|
494
|
-
const idxSigs = ast.indexSignatures ?? []
|
|
495
|
-
if (props.length === 0 && idxSigs.length === 0) return "{}"
|
|
482
|
+
const props = ast.propertySignatures ?? []
|
|
483
|
+
const idxSigs = ast.indexSignatures ?? []
|
|
484
|
+
if (props.length === 0 && idxSigs.length === 0) return "{}"
|
|
496
485
|
if (props.length === 0 && idxSigs.length === 1) {
|
|
497
|
-
return `Record<${emitEffectAst(idxSigs[0].parameter)}, ${emitEffectAst(idxSigs[0].type)}
|
|
486
|
+
return `Record<${emitEffectAst(idxSigs[0].parameter)}, ${emitEffectAst(idxSigs[0].type)}>`
|
|
498
487
|
}
|
|
499
488
|
const parts = props.map((p) => {
|
|
500
|
-
const opt = p.isOptional ? "?" : ""
|
|
501
|
-
return `${quoteKey(p.name as string)}${opt}: ${emitEffectAst(p.type)}
|
|
502
|
-
})
|
|
503
|
-
return `{ ${parts.join("; ")} }
|
|
489
|
+
const opt = p.isOptional ? "?" : ""
|
|
490
|
+
return `${quoteKey(p.name as string)}${opt}: ${emitEffectAst(p.type)}`
|
|
491
|
+
})
|
|
492
|
+
return `{ ${parts.join("; ")} }`
|
|
504
493
|
}
|
|
505
494
|
case "TupleType": {
|
|
506
|
-
const elems = ast.elements ?? []
|
|
507
|
-
const rest = ast.rest
|
|
495
|
+
const elems = ast.elements ?? []
|
|
496
|
+
const rest = ast.rest
|
|
508
497
|
if (elems.length === 0 && rest && rest.length === 1) {
|
|
509
|
-
return arrayOf(emitEffectAst(rest[0].type))
|
|
498
|
+
return arrayOf(emitEffectAst(rest[0].type))
|
|
510
499
|
}
|
|
511
500
|
if (elems.length > 0 && (!rest || rest.length === 0)) {
|
|
512
|
-
return `[${elems.map((e) => emitEffectAst(e.type)).join(", ")}]
|
|
501
|
+
return `[${elems.map((e) => emitEffectAst(e.type)).join(", ")}]`
|
|
513
502
|
}
|
|
514
|
-
if (elems.length === 0) return "unknown[]"
|
|
515
|
-
return `[${elems.map((e) => emitEffectAst(e.type)).join(", ")}]
|
|
503
|
+
if (elems.length === 0) return "unknown[]"
|
|
504
|
+
return `[${elems.map((e) => emitEffectAst(e.type)).join(", ")}]`
|
|
516
505
|
}
|
|
517
506
|
case "Declaration":
|
|
518
|
-
return "unknown"
|
|
507
|
+
return "unknown"
|
|
519
508
|
case "Suspend":
|
|
520
|
-
return "unknown"
|
|
509
|
+
return "unknown"
|
|
521
510
|
default:
|
|
522
|
-
return "unknown"
|
|
511
|
+
return "unknown"
|
|
523
512
|
}
|
|
524
513
|
}
|