silgi 0.0.14 → 0.1.0-beta.10
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 +102 -1
- package/dist/_virtual/_rolldown/runtime.mjs +5 -0
- package/dist/adapters/_fetch-adapter.d.mts +18 -0
- package/dist/adapters/_fetch-adapter.mjs +53 -0
- package/dist/adapters/astro.d.mts +15 -0
- package/dist/adapters/astro.mjs +31 -0
- package/dist/adapters/aws-lambda.d.mts +42 -0
- package/dist/adapters/aws-lambda.mjs +92 -0
- package/dist/adapters/express.d.mts +16 -0
- package/dist/adapters/express.mjs +120 -0
- package/dist/adapters/message-port.d.mts +42 -0
- package/dist/adapters/message-port.mjs +132 -0
- package/dist/adapters/nestjs.d.mts +25 -0
- package/dist/adapters/nestjs.mjs +75 -0
- package/dist/adapters/nextjs.d.mts +14 -0
- package/dist/adapters/nextjs.mjs +29 -0
- package/dist/adapters/peer.d.mts +27 -0
- package/dist/adapters/peer.mjs +36 -0
- package/dist/adapters/remix.d.mts +15 -0
- package/dist/adapters/remix.mjs +30 -0
- package/dist/adapters/solidstart.d.mts +12 -0
- package/dist/adapters/solidstart.mjs +29 -0
- package/dist/adapters/sveltekit.d.mts +14 -0
- package/dist/adapters/sveltekit.mjs +30 -0
- package/dist/broker/index.d.mts +62 -0
- package/dist/broker/index.mjs +153 -0
- package/dist/broker/nats.d.mts +33 -0
- package/dist/broker/nats.mjs +31 -0
- package/dist/broker/redis.d.mts +51 -0
- package/dist/broker/redis.mjs +92 -0
- package/dist/builder.d.mts +55 -0
- package/dist/builder.mjs +70 -0
- package/dist/callable.d.mts +19 -0
- package/dist/callable.mjs +42 -0
- package/dist/caller.mjs +90 -0
- package/dist/client/adapters/fetch/index.d.mts +19 -0
- package/dist/client/adapters/fetch/index.mjs +82 -0
- package/dist/client/adapters/ofetch/index.d.mts +57 -0
- package/dist/client/adapters/ofetch/index.mjs +100 -0
- package/dist/client/adapters/websocket/index.d.mts +20 -0
- package/dist/client/adapters/websocket/index.mjs +101 -0
- package/dist/client/client.d.mts +37 -0
- package/dist/client/client.mjs +80 -0
- package/dist/client/consume.d.mts +50 -0
- package/dist/client/consume.mjs +66 -0
- package/dist/client/dynamic-link.d.mts +16 -0
- package/dist/client/dynamic-link.mjs +19 -0
- package/dist/client/index.d.mts +6 -0
- package/dist/client/index.mjs +5 -0
- package/dist/client/interceptor.d.mts +31 -0
- package/dist/client/interceptor.mjs +34 -0
- package/dist/client/openapi.d.mts +29 -0
- package/dist/client/openapi.mjs +89 -0
- package/dist/client/plugins/batch.d.mts +26 -0
- package/dist/client/plugins/batch.mjs +64 -0
- package/dist/client/plugins/circuit-breaker.d.mts +24 -0
- package/dist/client/plugins/circuit-breaker.mjs +60 -0
- package/dist/client/plugins/csrf.d.mts +13 -0
- package/dist/client/plugins/csrf.mjs +20 -0
- package/dist/client/plugins/dedupe.d.mts +10 -0
- package/dist/client/plugins/dedupe.mjs +28 -0
- package/dist/client/plugins/index.d.mts +8 -0
- package/dist/client/plugins/index.mjs +8 -0
- package/dist/client/plugins/otel.d.mts +12 -0
- package/dist/client/plugins/otel.mjs +27 -0
- package/dist/client/plugins/retry.d.mts +34 -0
- package/dist/client/plugins/retry.mjs +79 -0
- package/dist/client/plugins/timeout.d.mts +10 -0
- package/dist/client/plugins/timeout.mjs +14 -0
- package/dist/client/server.d.mts +16 -0
- package/dist/client/server.mjs +62 -0
- package/dist/client/types.d.mts +29 -0
- package/dist/codec/devalue.d.mts +21 -0
- package/dist/codec/devalue.mjs +33 -0
- package/dist/codec/msgpack.d.mts +18 -0
- package/dist/codec/msgpack.mjs +45 -0
- package/dist/codec/sanitize.mjs +38 -0
- package/dist/compile.d.mts +46 -0
- package/dist/compile.mjs +332 -0
- package/dist/contract.d.mts +36 -0
- package/dist/contract.mjs +40 -0
- package/dist/core/codec.mjs +67 -0
- package/dist/core/dispatch.mjs +62 -0
- package/dist/core/error.d.mts +104 -0
- package/dist/core/error.mjs +139 -0
- package/dist/core/handler.d.mts +6 -0
- package/dist/core/handler.mjs +148 -0
- package/dist/core/input.mjs +49 -0
- package/dist/core/iterator.d.mts +17 -0
- package/dist/core/iterator.mjs +79 -0
- package/dist/core/router-utils.d.mts +25 -0
- package/dist/core/router-utils.mjs +98 -0
- package/dist/core/schema.d.mts +20 -0
- package/dist/core/schema.mjs +33 -0
- package/dist/core/serve.d.mts +51 -0
- package/dist/core/serve.mjs +76 -0
- package/dist/core/sse.d.mts +18 -0
- package/dist/core/sse.mjs +98 -0
- package/dist/core/storage.d.mts +20 -0
- package/dist/core/storage.mjs +61 -0
- package/dist/core/task.d.mts +62 -0
- package/dist/core/task.mjs +165 -0
- package/dist/core/utils.mjs +24 -0
- package/dist/index.d.mts +18 -37
- package/dist/index.mjs +15 -7
- package/dist/integrations/ai/index.d.mts +25 -0
- package/dist/integrations/ai/index.mjs +117 -0
- package/dist/integrations/better-auth/index.d.mts +61 -0
- package/dist/integrations/better-auth/index.mjs +332 -0
- package/dist/integrations/drizzle/index.d.mts +27 -0
- package/dist/integrations/drizzle/index.mjs +286 -0
- package/dist/integrations/hey-api/index.d.mts +2 -0
- package/dist/integrations/hey-api/index.mjs +2 -0
- package/dist/integrations/hey-api/to-client.d.mts +20 -0
- package/dist/integrations/hey-api/to-client.mjs +39 -0
- package/dist/integrations/pinia-colada/general-utils.d.mts +13 -0
- package/dist/integrations/pinia-colada/general-utils.mjs +9 -0
- package/dist/integrations/pinia-colada/index.d.mts +6 -0
- package/dist/integrations/pinia-colada/index.mjs +5 -0
- package/dist/integrations/pinia-colada/key.d.mts +11 -0
- package/dist/integrations/pinia-colada/key.mjs +11 -0
- package/dist/integrations/pinia-colada/procedure-utils.d.mts +25 -0
- package/dist/integrations/pinia-colada/procedure-utils.mjs +33 -0
- package/dist/integrations/pinia-colada/router-utils.d.mts +17 -0
- package/dist/integrations/pinia-colada/router-utils.mjs +30 -0
- package/dist/integrations/pinia-colada/types.d.mts +25 -0
- package/dist/integrations/react/index.d.mts +83 -0
- package/dist/integrations/react/index.mjs +196 -0
- package/dist/integrations/tanstack-query/index.d.mts +120 -0
- package/dist/integrations/tanstack-query/index.mjs +100 -0
- package/dist/integrations/tanstack-query/ssr.d.mts +60 -0
- package/dist/integrations/tanstack-query/ssr.mjs +102 -0
- package/dist/integrations/zod/converter.d.mts +75 -0
- package/dist/integrations/zod/converter.mjs +345 -0
- package/dist/integrations/zod/index.d.mts +2 -0
- package/dist/integrations/zod/index.mjs +2 -0
- package/dist/lazy.d.mts +22 -0
- package/dist/lazy.mjs +34 -0
- package/dist/lifecycle.d.mts +36 -0
- package/dist/lifecycle.mjs +46 -0
- package/dist/map-input.d.mts +17 -0
- package/dist/map-input.mjs +47 -0
- package/dist/plugins/analytics.d.mts +236 -0
- package/dist/plugins/analytics.mjs +816 -0
- package/dist/plugins/batch-server.d.mts +20 -0
- package/dist/plugins/batch-server.mjs +91 -0
- package/dist/plugins/body-limit.d.mts +19 -0
- package/dist/plugins/body-limit.mjs +49 -0
- package/dist/plugins/cache.d.mts +170 -0
- package/dist/plugins/cache.mjs +212 -0
- package/dist/plugins/coerce.d.mts +24 -0
- package/dist/plugins/coerce.mjs +70 -0
- package/dist/plugins/cookies.d.mts +14 -0
- package/dist/plugins/cookies.mjs +48 -0
- package/dist/plugins/cors.d.mts +43 -0
- package/dist/plugins/cors.mjs +62 -0
- package/dist/plugins/file-upload.d.mts +38 -0
- package/dist/plugins/file-upload.mjs +102 -0
- package/dist/plugins/index.d.mts +14 -0
- package/dist/plugins/index.mjs +14 -0
- package/dist/plugins/otel.d.mts +35 -0
- package/dist/plugins/otel.mjs +40 -0
- package/dist/plugins/pino.d.mts +60 -0
- package/dist/plugins/pino.mjs +42 -0
- package/dist/plugins/pubsub.d.mts +50 -0
- package/dist/plugins/pubsub.mjs +53 -0
- package/dist/plugins/ratelimit.d.mts +53 -0
- package/dist/plugins/ratelimit.mjs +92 -0
- package/dist/plugins/signing.d.mts +41 -0
- package/dist/plugins/signing.mjs +118 -0
- package/dist/plugins/strict-get.d.mts +10 -0
- package/dist/plugins/strict-get.mjs +33 -0
- package/dist/scalar.d.mts +49 -0
- package/dist/scalar.mjs +311 -0
- package/dist/silgi.d.mts +144 -0
- package/dist/silgi.mjs +156 -0
- package/dist/trpc-interop.d.mts +22 -0
- package/dist/trpc-interop.mjs +68 -0
- package/dist/types.d.mts +108 -0
- package/dist/ws.d.mts +88 -0
- package/dist/ws.mjs +205 -0
- package/lib/dashboard/index.html +123 -0
- package/lib/ocache.d.mts +1 -0
- package/lib/ocache.mjs +1 -0
- package/lib/ofetch.d.mts +1 -0
- package/lib/ofetch.mjs +1 -0
- package/lib/srvx.d.mts +1 -0
- package/lib/srvx.mjs +1 -0
- package/lib/unstorage.d.mts +1 -0
- package/lib/unstorage.mjs +1 -0
- package/package.json +324 -65
- package/bin/silgi.mjs +0 -3
- package/dist/chunks/generate.mjs +0 -933
- package/dist/chunks/init.mjs +0 -21
- package/dist/cli/config.d.mts +0 -19
- package/dist/cli/config.d.ts +0 -19
- package/dist/cli/config.mjs +0 -5
- package/dist/cli/index.d.mts +0 -2
- package/dist/cli/index.d.ts +0 -2
- package/dist/cli/index.mjs +0 -119
- package/dist/index.d.ts +0 -37
- package/dist/plugins/openapi.d.mts +0 -138
- package/dist/plugins/openapi.d.ts +0 -138
- package/dist/plugins/openapi.mjs +0 -204
- package/dist/plugins/scalar.d.mts +0 -14
- package/dist/plugins/scalar.d.ts +0 -14
- package/dist/plugins/scalar.mjs +0 -66
- package/dist/shared/silgi.BMCYk2cR.mjs +0 -841
- package/dist/shared/silgi.D5qK9QOm.d.mts +0 -301
- package/dist/shared/silgi.D5qK9QOm.d.ts +0 -301
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
//#region src/integrations/zod/converter.ts
|
|
2
|
+
/**
|
|
3
|
+
* Composite converter — tries each converter in order.
|
|
4
|
+
*/
|
|
5
|
+
var CompositeSchemaConverter = class {
|
|
6
|
+
#converters;
|
|
7
|
+
constructor(converters) {
|
|
8
|
+
this.#converters = converters;
|
|
9
|
+
}
|
|
10
|
+
convert(schema, options) {
|
|
11
|
+
if (!schema) return [false, {}];
|
|
12
|
+
for (const converter of this.#converters) if (converter.condition(schema)) return converter.convert(schema, options);
|
|
13
|
+
return [false, {}];
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Zod v4 → JSON Schema converter.
|
|
18
|
+
*/
|
|
19
|
+
var ZodSchemaConverter = class {
|
|
20
|
+
#maxDepth;
|
|
21
|
+
constructor(options) {
|
|
22
|
+
this.#maxDepth = options?.maxDepth ?? 10;
|
|
23
|
+
}
|
|
24
|
+
condition(schema) {
|
|
25
|
+
return schema["~standard"]?.vendor === "zod";
|
|
26
|
+
}
|
|
27
|
+
convert(schema, options) {
|
|
28
|
+
return this.#convert(schema, options, 0);
|
|
29
|
+
}
|
|
30
|
+
#convert(schema, options, depth) {
|
|
31
|
+
if (depth > this.#maxDepth) return [true, {}];
|
|
32
|
+
const zod = schema._zod;
|
|
33
|
+
const def = zod?.def ?? schema._def;
|
|
34
|
+
const bag = zod?.bag;
|
|
35
|
+
if (!def) return [true, {}];
|
|
36
|
+
switch (def.type ?? def.typeName) {
|
|
37
|
+
case "string":
|
|
38
|
+
case "ZodString": return [true, this.#convertString(def, bag)];
|
|
39
|
+
case "number":
|
|
40
|
+
case "ZodNumber": {
|
|
41
|
+
const result = this.#convertNumber(def, bag);
|
|
42
|
+
if (bag?.format === "safeint" || this.#hasIntCheck(def)) result.type = "integer";
|
|
43
|
+
return [true, result];
|
|
44
|
+
}
|
|
45
|
+
case "int": return [true, {
|
|
46
|
+
...this.#convertNumber(def, bag),
|
|
47
|
+
type: "integer"
|
|
48
|
+
}];
|
|
49
|
+
case "boolean":
|
|
50
|
+
case "ZodBoolean": return [true, { type: "boolean" }];
|
|
51
|
+
case "bigint":
|
|
52
|
+
case "ZodBigInt": return [true, {
|
|
53
|
+
type: "string",
|
|
54
|
+
pattern: "^-?[0-9]+$",
|
|
55
|
+
"x-native-type": "bigint"
|
|
56
|
+
}];
|
|
57
|
+
case "date":
|
|
58
|
+
case "ZodDate": return [true, {
|
|
59
|
+
type: "string",
|
|
60
|
+
format: "date-time",
|
|
61
|
+
"x-native-type": "date"
|
|
62
|
+
}];
|
|
63
|
+
case "symbol":
|
|
64
|
+
case "ZodSymbol": return [true, {}];
|
|
65
|
+
case "undefined":
|
|
66
|
+
case "ZodUndefined": return [false, { not: {} }];
|
|
67
|
+
case "null":
|
|
68
|
+
case "ZodNull": return [true, { type: "null" }];
|
|
69
|
+
case "void":
|
|
70
|
+
case "ZodVoid": return [false, { type: "null" }];
|
|
71
|
+
case "any":
|
|
72
|
+
case "ZodAny": return [true, {}];
|
|
73
|
+
case "unknown":
|
|
74
|
+
case "ZodUnknown": return [true, {}];
|
|
75
|
+
case "never":
|
|
76
|
+
case "ZodNever": return [true, { not: {} }];
|
|
77
|
+
case "nan":
|
|
78
|
+
case "ZodNaN": return options.strategy === "input" ? [true, { not: {} }] : [true, { type: "null" }];
|
|
79
|
+
case "literal":
|
|
80
|
+
case "ZodLiteral": {
|
|
81
|
+
const values = def.values ?? [def.value];
|
|
82
|
+
return [true, values.length === 1 ? { const: values[0] } : { enum: values }];
|
|
83
|
+
}
|
|
84
|
+
case "enum":
|
|
85
|
+
case "ZodEnum": {
|
|
86
|
+
const entries = def.entries;
|
|
87
|
+
return [true, { enum: Array.isArray(def.values) ? def.values : entries ? Object.values(entries) : [] }];
|
|
88
|
+
}
|
|
89
|
+
case "nativeEnum":
|
|
90
|
+
case "ZodNativeEnum": return [true, { enum: Object.values(def.values ?? def.entries) }];
|
|
91
|
+
case "array":
|
|
92
|
+
case "ZodArray": {
|
|
93
|
+
const inner = def.element ?? def.type;
|
|
94
|
+
if (!inner) return [true, { type: "array" }];
|
|
95
|
+
const [, itemSchema] = this.#convert(inner, options, depth + 1);
|
|
96
|
+
const result = {
|
|
97
|
+
type: "array",
|
|
98
|
+
items: itemSchema
|
|
99
|
+
};
|
|
100
|
+
if (bag?.minimum != null) result.minItems = bag.minimum;
|
|
101
|
+
if (bag?.maximum != null) result.maxItems = bag.maximum;
|
|
102
|
+
if (def.minLength != null) result.minItems ??= def.minLength.value ?? def.minLength;
|
|
103
|
+
if (def.maxLength != null) result.maxItems ??= def.maxLength.value ?? def.maxLength;
|
|
104
|
+
return [true, result];
|
|
105
|
+
}
|
|
106
|
+
case "object":
|
|
107
|
+
case "ZodObject": {
|
|
108
|
+
const shape = def.shape ?? (typeof schema.shape === "function" ? schema.shape() : schema.shape);
|
|
109
|
+
if (!shape) return [true, { type: "object" }];
|
|
110
|
+
const properties = {};
|
|
111
|
+
const required = [];
|
|
112
|
+
for (const [key, value] of Object.entries(shape)) {
|
|
113
|
+
const [isRequired, propSchema] = this.#convert(value, options, depth + 1);
|
|
114
|
+
properties[key] = propSchema;
|
|
115
|
+
if (isRequired) required.push(key);
|
|
116
|
+
}
|
|
117
|
+
const result = {
|
|
118
|
+
type: "object",
|
|
119
|
+
properties
|
|
120
|
+
};
|
|
121
|
+
if (required.length > 0) result.required = required;
|
|
122
|
+
if (def.catchall) {
|
|
123
|
+
const [, catchSchema] = this.#convert(def.catchall, options, depth + 1);
|
|
124
|
+
result.additionalProperties = catchSchema;
|
|
125
|
+
} else if (def.unknownKeys === "strict") result.additionalProperties = false;
|
|
126
|
+
return [true, result];
|
|
127
|
+
}
|
|
128
|
+
case "union":
|
|
129
|
+
case "ZodUnion":
|
|
130
|
+
case "ZodDiscriminatedUnion": {
|
|
131
|
+
const unionOptions = def.options ?? def.members;
|
|
132
|
+
if (!Array.isArray(unionOptions)) return [true, {}];
|
|
133
|
+
return [true, { anyOf: unionOptions.map((o) => this.#convert(o, options, depth + 1)).map(([, s]) => s) }];
|
|
134
|
+
}
|
|
135
|
+
case "intersection":
|
|
136
|
+
case "ZodIntersection": {
|
|
137
|
+
const [, left] = this.#convert(def.left, options, depth + 1);
|
|
138
|
+
const [, right] = this.#convert(def.right, options, depth + 1);
|
|
139
|
+
return [true, { allOf: [left, right] }];
|
|
140
|
+
}
|
|
141
|
+
case "tuple":
|
|
142
|
+
case "ZodTuple": {
|
|
143
|
+
const result = {
|
|
144
|
+
type: "array",
|
|
145
|
+
prefixItems: (def.items ?? def.types ?? []).map((t) => this.#convert(t, options, depth + 1)[1])
|
|
146
|
+
};
|
|
147
|
+
if (def.rest) result.items = this.#convert(def.rest, options, depth + 1)[1];
|
|
148
|
+
return [true, result];
|
|
149
|
+
}
|
|
150
|
+
case "record":
|
|
151
|
+
case "ZodRecord": {
|
|
152
|
+
const [, valSchema] = this.#convert(def.valueType ?? def.element, options, depth + 1);
|
|
153
|
+
return [true, {
|
|
154
|
+
type: "object",
|
|
155
|
+
additionalProperties: valSchema
|
|
156
|
+
}];
|
|
157
|
+
}
|
|
158
|
+
case "map":
|
|
159
|
+
case "ZodMap": {
|
|
160
|
+
const [, keySchema] = this.#convert(def.keyType, options, depth + 1);
|
|
161
|
+
const [, valSchema] = this.#convert(def.valueType, options, depth + 1);
|
|
162
|
+
return [true, {
|
|
163
|
+
type: "array",
|
|
164
|
+
items: {
|
|
165
|
+
type: "array",
|
|
166
|
+
prefixItems: [keySchema, valSchema]
|
|
167
|
+
},
|
|
168
|
+
"x-native-type": "map"
|
|
169
|
+
}];
|
|
170
|
+
}
|
|
171
|
+
case "set":
|
|
172
|
+
case "ZodSet": {
|
|
173
|
+
const [, itemSchema] = this.#convert(def.valueType ?? def.element, options, depth + 1);
|
|
174
|
+
return [true, {
|
|
175
|
+
type: "array",
|
|
176
|
+
items: itemSchema,
|
|
177
|
+
uniqueItems: true,
|
|
178
|
+
"x-native-type": "set"
|
|
179
|
+
}];
|
|
180
|
+
}
|
|
181
|
+
case "optional":
|
|
182
|
+
case "ZodOptional": {
|
|
183
|
+
const inner = def.innerType ?? def.wrapped;
|
|
184
|
+
const [, innerSchema] = this.#convert(inner, options, depth + 1);
|
|
185
|
+
return [false, innerSchema];
|
|
186
|
+
}
|
|
187
|
+
case "nullable":
|
|
188
|
+
case "ZodNullable": {
|
|
189
|
+
const inner = def.innerType ?? def.wrapped;
|
|
190
|
+
const [req, innerSchema] = this.#convert(inner, options, depth + 1);
|
|
191
|
+
return [req, { anyOf: [innerSchema, { type: "null" }] }];
|
|
192
|
+
}
|
|
193
|
+
case "default":
|
|
194
|
+
case "ZodDefault": {
|
|
195
|
+
const inner = def.innerType ?? def.wrapped;
|
|
196
|
+
const [, innerSchema] = this.#convert(inner, options, depth + 1);
|
|
197
|
+
const defaultValue = typeof def.defaultValue === "function" ? def.defaultValue() : def.defaultValue;
|
|
198
|
+
return [false, {
|
|
199
|
+
...innerSchema,
|
|
200
|
+
default: defaultValue
|
|
201
|
+
}];
|
|
202
|
+
}
|
|
203
|
+
case "readonly":
|
|
204
|
+
case "ZodReadonly": {
|
|
205
|
+
const inner = def.innerType ?? def.wrapped;
|
|
206
|
+
const [req, innerSchema] = this.#convert(inner, options, depth + 1);
|
|
207
|
+
return [req, {
|
|
208
|
+
...innerSchema,
|
|
209
|
+
readOnly: true
|
|
210
|
+
}];
|
|
211
|
+
}
|
|
212
|
+
case "catch":
|
|
213
|
+
case "ZodCatch": {
|
|
214
|
+
const inner = def.innerType ?? def.wrapped;
|
|
215
|
+
return this.#convert(inner, options, depth + 1);
|
|
216
|
+
}
|
|
217
|
+
case "brand":
|
|
218
|
+
case "ZodBranded": {
|
|
219
|
+
const inner = def.type ?? def.wrapped;
|
|
220
|
+
return this.#convert(inner, options, depth + 1);
|
|
221
|
+
}
|
|
222
|
+
case "lazy":
|
|
223
|
+
case "ZodLazy": {
|
|
224
|
+
const getter = def.getter ?? def.get;
|
|
225
|
+
if (typeof getter === "function") return this.#convert(getter(), options, depth + 1);
|
|
226
|
+
return [true, {}];
|
|
227
|
+
}
|
|
228
|
+
case "promise":
|
|
229
|
+
case "ZodPromise": {
|
|
230
|
+
const inner = def.type ?? def.wrapped;
|
|
231
|
+
return this.#convert(inner, options, depth + 1);
|
|
232
|
+
}
|
|
233
|
+
case "transform":
|
|
234
|
+
case "ZodEffects": {
|
|
235
|
+
const inner = def.schema ?? def.in ?? def.wrapped;
|
|
236
|
+
if (!inner) return [true, {}];
|
|
237
|
+
if (options.strategy === "input") return this.#convert(inner, options, depth + 1);
|
|
238
|
+
return [true, {}];
|
|
239
|
+
}
|
|
240
|
+
case "pipe":
|
|
241
|
+
case "ZodPipeline":
|
|
242
|
+
if (options.strategy === "input") return this.#convert(def.in ?? def.from, options, depth + 1);
|
|
243
|
+
return this.#convert(def.out ?? def.to, options, depth + 1);
|
|
244
|
+
default: return [true, {}];
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
#convertString(def, bag) {
|
|
248
|
+
const result = { type: "string" };
|
|
249
|
+
const checks = def.checks ?? [];
|
|
250
|
+
bag = bag ?? {};
|
|
251
|
+
if (bag.minimum != null) result.minLength = bag.minimum;
|
|
252
|
+
if (bag.maximum != null) result.maxLength = bag.maximum;
|
|
253
|
+
if (bag.patterns) {
|
|
254
|
+
const patterns = Object.values(bag.patterns);
|
|
255
|
+
if (patterns.length > 0) result.pattern = patterns[0]?.source ?? String(patterns[0]);
|
|
256
|
+
}
|
|
257
|
+
if (bag.format) result.format = this.#normalizeFormat(bag.format);
|
|
258
|
+
for (const check of checks) switch (check.kind ?? check.type) {
|
|
259
|
+
case "min":
|
|
260
|
+
result.minLength = check.value;
|
|
261
|
+
break;
|
|
262
|
+
case "max":
|
|
263
|
+
result.maxLength = check.value;
|
|
264
|
+
break;
|
|
265
|
+
case "length":
|
|
266
|
+
result.minLength = check.value;
|
|
267
|
+
result.maxLength = check.value;
|
|
268
|
+
break;
|
|
269
|
+
case "email":
|
|
270
|
+
result.format = "email";
|
|
271
|
+
break;
|
|
272
|
+
case "url":
|
|
273
|
+
result.format = "uri";
|
|
274
|
+
break;
|
|
275
|
+
case "uuid":
|
|
276
|
+
result.format = "uuid";
|
|
277
|
+
break;
|
|
278
|
+
case "regex":
|
|
279
|
+
result.pattern = check.regex?.source ?? check.value;
|
|
280
|
+
break;
|
|
281
|
+
case "datetime":
|
|
282
|
+
result.format = "date-time";
|
|
283
|
+
break;
|
|
284
|
+
case "date":
|
|
285
|
+
result.format = "date";
|
|
286
|
+
break;
|
|
287
|
+
case "time":
|
|
288
|
+
result.format = "time";
|
|
289
|
+
break;
|
|
290
|
+
case "ip":
|
|
291
|
+
result.format = check.version === "v6" ? "ipv6" : "ipv4";
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
if (def.description) result.description = def.description;
|
|
295
|
+
return result;
|
|
296
|
+
}
|
|
297
|
+
#hasIntCheck(def) {
|
|
298
|
+
return (def.checks ?? []).some((c) => (c.kind ?? c.type ?? c._zod?.def?.check) === "int" || c.isInt === true || c._zod?.def?.format === "safeint");
|
|
299
|
+
}
|
|
300
|
+
#convertNumber(def, bag) {
|
|
301
|
+
const result = { type: "number" };
|
|
302
|
+
const checks = def.checks ?? [];
|
|
303
|
+
bag = bag ?? {};
|
|
304
|
+
if (bag.minimum != null) result.minimum = bag.minimum;
|
|
305
|
+
if (bag.maximum != null) result.maximum = bag.maximum;
|
|
306
|
+
if (bag.multipleOf != null) result.multipleOf = bag.multipleOf;
|
|
307
|
+
for (const check of checks) switch (check.kind ?? check.type) {
|
|
308
|
+
case "min":
|
|
309
|
+
result.minimum = check.value;
|
|
310
|
+
break;
|
|
311
|
+
case "max":
|
|
312
|
+
result.maximum = check.value;
|
|
313
|
+
break;
|
|
314
|
+
case "int":
|
|
315
|
+
result.type = "integer";
|
|
316
|
+
break;
|
|
317
|
+
case "multipleOf":
|
|
318
|
+
result.multipleOf = check.value;
|
|
319
|
+
break;
|
|
320
|
+
case "finite": break;
|
|
321
|
+
case "nonnegative":
|
|
322
|
+
result.minimum = 0;
|
|
323
|
+
break;
|
|
324
|
+
case "nonpositive":
|
|
325
|
+
result.maximum = 0;
|
|
326
|
+
break;
|
|
327
|
+
case "positive":
|
|
328
|
+
result.exclusiveMinimum = 0;
|
|
329
|
+
break;
|
|
330
|
+
case "negative":
|
|
331
|
+
result.exclusiveMaximum = 0;
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
if (def.description) result.description = def.description;
|
|
335
|
+
return result;
|
|
336
|
+
}
|
|
337
|
+
#normalizeFormat(format) {
|
|
338
|
+
return {
|
|
339
|
+
guid: "uuid",
|
|
340
|
+
url: "uri"
|
|
341
|
+
}[format] ?? format;
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
//#endregion
|
|
345
|
+
export { CompositeSchemaConverter, ZodSchemaConverter };
|
package/dist/lazy.d.mts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ProcedureDef, RouterDef } from "./types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/lazy.d.ts
|
|
4
|
+
interface LazyRouter {
|
|
5
|
+
readonly __lazy: true;
|
|
6
|
+
readonly load: () => Promise<{
|
|
7
|
+
default: RouterDef | ProcedureDef;
|
|
8
|
+
}>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Wrap a dynamic import for lazy loading.
|
|
12
|
+
* The module must export its router/procedure as `default`.
|
|
13
|
+
*/
|
|
14
|
+
declare function lazy(loader: () => Promise<{
|
|
15
|
+
default: RouterDef | ProcedureDef;
|
|
16
|
+
}>): LazyRouter;
|
|
17
|
+
/** Check if a value is a lazy router */
|
|
18
|
+
declare function isLazy(value: unknown): value is LazyRouter;
|
|
19
|
+
/** Resolve a lazy router (cached after first load, race-safe) */
|
|
20
|
+
declare function resolveLazy(value: LazyRouter): Promise<RouterDef | ProcedureDef>;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { LazyRouter, isLazy, lazy, resolveLazy };
|
package/dist/lazy.mjs
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/lazy.ts
|
|
2
|
+
const resolved = /* @__PURE__ */ new WeakMap();
|
|
3
|
+
const loading = /* @__PURE__ */ new WeakMap();
|
|
4
|
+
/**
|
|
5
|
+
* Wrap a dynamic import for lazy loading.
|
|
6
|
+
* The module must export its router/procedure as `default`.
|
|
7
|
+
*/
|
|
8
|
+
function lazy(loader) {
|
|
9
|
+
return {
|
|
10
|
+
__lazy: true,
|
|
11
|
+
load: loader
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/** Check if a value is a lazy router */
|
|
15
|
+
function isLazy(value) {
|
|
16
|
+
return typeof value === "object" && value !== null && value.__lazy === true;
|
|
17
|
+
}
|
|
18
|
+
/** Resolve a lazy router (cached after first load, race-safe) */
|
|
19
|
+
async function resolveLazy(value) {
|
|
20
|
+
const cached = resolved.get(value);
|
|
21
|
+
if (cached) return cached;
|
|
22
|
+
let pending = loading.get(value);
|
|
23
|
+
if (!pending) {
|
|
24
|
+
pending = value.load().then((mod) => {
|
|
25
|
+
resolved.set(value, mod.default);
|
|
26
|
+
loading.delete(value);
|
|
27
|
+
return mod.default;
|
|
28
|
+
});
|
|
29
|
+
loading.set(value, pending);
|
|
30
|
+
}
|
|
31
|
+
return pending;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { isLazy, lazy, resolveLazy };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { WrapDef } from "./types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/lifecycle.d.ts
|
|
4
|
+
interface LifecycleHooks<TCtx = Record<string, unknown>> {
|
|
5
|
+
/** Called before the procedure runs */
|
|
6
|
+
onStart?: (event: {
|
|
7
|
+
ctx: TCtx;
|
|
8
|
+
}) => void | Promise<void>;
|
|
9
|
+
/** Called after a successful result */
|
|
10
|
+
onSuccess?: (event: {
|
|
11
|
+
ctx: TCtx;
|
|
12
|
+
output: unknown;
|
|
13
|
+
durationMs: number;
|
|
14
|
+
}) => void | Promise<void>;
|
|
15
|
+
/** Called when the procedure throws */
|
|
16
|
+
onError?: (event: {
|
|
17
|
+
ctx: TCtx;
|
|
18
|
+
error: unknown;
|
|
19
|
+
durationMs: number;
|
|
20
|
+
}) => void | Promise<void>;
|
|
21
|
+
/** Called after the procedure completes (success or failure) */
|
|
22
|
+
onFinish?: (event: {
|
|
23
|
+
ctx: TCtx;
|
|
24
|
+
durationMs: number;
|
|
25
|
+
error?: unknown;
|
|
26
|
+
}) => void | Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create a wrap middleware with declarative lifecycle hooks.
|
|
30
|
+
*
|
|
31
|
+
* All hooks are optional. The procedure result is never modified —
|
|
32
|
+
* hooks are purely for side effects (logging, metrics, error reporting).
|
|
33
|
+
*/
|
|
34
|
+
declare function lifecycleWrap<TCtx = Record<string, unknown>>(hooks: LifecycleHooks<TCtx>): WrapDef<TCtx>;
|
|
35
|
+
//#endregion
|
|
36
|
+
export { LifecycleHooks, lifecycleWrap };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
//#region src/lifecycle.ts
|
|
2
|
+
/**
|
|
3
|
+
* Create a wrap middleware with declarative lifecycle hooks.
|
|
4
|
+
*
|
|
5
|
+
* All hooks are optional. The procedure result is never modified —
|
|
6
|
+
* hooks are purely for side effects (logging, metrics, error reporting).
|
|
7
|
+
*/
|
|
8
|
+
function lifecycleWrap(hooks) {
|
|
9
|
+
return {
|
|
10
|
+
kind: "wrap",
|
|
11
|
+
fn: async (ctx, next) => {
|
|
12
|
+
const typedCtx = ctx;
|
|
13
|
+
if (hooks.onStart) await hooks.onStart({ ctx: typedCtx });
|
|
14
|
+
const t0 = performance.now();
|
|
15
|
+
let error;
|
|
16
|
+
try {
|
|
17
|
+
const output = await next();
|
|
18
|
+
const durationMs = performance.now() - t0;
|
|
19
|
+
if (hooks.onSuccess) await hooks.onSuccess({
|
|
20
|
+
ctx: typedCtx,
|
|
21
|
+
output,
|
|
22
|
+
durationMs
|
|
23
|
+
});
|
|
24
|
+
return output;
|
|
25
|
+
} catch (err) {
|
|
26
|
+
error = err;
|
|
27
|
+
const durationMs = performance.now() - t0;
|
|
28
|
+
if (hooks.onError) await hooks.onError({
|
|
29
|
+
ctx: typedCtx,
|
|
30
|
+
error: err,
|
|
31
|
+
durationMs
|
|
32
|
+
});
|
|
33
|
+
throw err;
|
|
34
|
+
} finally {
|
|
35
|
+
const durationMs = performance.now() - t0;
|
|
36
|
+
if (hooks.onFinish) await hooks.onFinish({
|
|
37
|
+
ctx: typedCtx,
|
|
38
|
+
durationMs,
|
|
39
|
+
error
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { lifecycleWrap };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { WrapDef } from "./types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/map-input.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Create a wrap that transforms the procedure input before execution.
|
|
6
|
+
*
|
|
7
|
+
* The mapper function receives the raw input and returns the transformed input.
|
|
8
|
+
* The mapped input is set on the context as `__mappedInput` and picked up
|
|
9
|
+
* by the pipeline.
|
|
10
|
+
*
|
|
11
|
+
* Note: Since Silgi's pipeline receives input as a separate argument
|
|
12
|
+
* (not on ctx), mapInput works as a wrap that intercepts and transforms
|
|
13
|
+
* before calling next().
|
|
14
|
+
*/
|
|
15
|
+
declare function mapInput<TIn = unknown, TOut = unknown>(mapper: (input: TIn) => TOut | Promise<TOut>): WrapDef;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { mapInput };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { RAW_INPUT } from "./compile.mjs";
|
|
2
|
+
//#region src/map-input.ts
|
|
3
|
+
/**
|
|
4
|
+
* mapInput — transform the input shape before a procedure runs.
|
|
5
|
+
*
|
|
6
|
+
* Useful when the client sends data in one shape but the procedure
|
|
7
|
+
* expects a different shape, or when you want to pre-process input
|
|
8
|
+
* in a reusable way.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { mapInput } from "silgi"
|
|
13
|
+
*
|
|
14
|
+
* // Rename fields
|
|
15
|
+
* const mapUserId = mapInput((input: { userId: string }) => ({
|
|
16
|
+
* id: input.userId,
|
|
17
|
+
* }))
|
|
18
|
+
*
|
|
19
|
+
* const getUser = k
|
|
20
|
+
* .$use(mapUserId)
|
|
21
|
+
* .$resolve(({ input }) => db.users.find(input.id))
|
|
22
|
+
* // input is { id: string } after mapping
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Create a wrap that transforms the procedure input before execution.
|
|
27
|
+
*
|
|
28
|
+
* The mapper function receives the raw input and returns the transformed input.
|
|
29
|
+
* The mapped input is set on the context as `__mappedInput` and picked up
|
|
30
|
+
* by the pipeline.
|
|
31
|
+
*
|
|
32
|
+
* Note: Since Silgi's pipeline receives input as a separate argument
|
|
33
|
+
* (not on ctx), mapInput works as a wrap that intercepts and transforms
|
|
34
|
+
* before calling next().
|
|
35
|
+
*/
|
|
36
|
+
function mapInput(mapper) {
|
|
37
|
+
return {
|
|
38
|
+
kind: "wrap",
|
|
39
|
+
fn: async (ctx, next) => {
|
|
40
|
+
const rawInput = ctx[RAW_INPUT];
|
|
41
|
+
ctx[RAW_INPUT] = await mapper(rawInput);
|
|
42
|
+
return next();
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { mapInput };
|