silgi 0.0.14 → 0.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/README.md +102 -1
  2. package/dist/_virtual/_rolldown/runtime.mjs +5 -0
  3. package/dist/adapters/astro.d.mts +17 -0
  4. package/dist/adapters/astro.mjs +24 -0
  5. package/dist/adapters/aws-lambda.d.mts +31 -0
  6. package/dist/adapters/aws-lambda.mjs +85 -0
  7. package/dist/adapters/elysia.d.mts +17 -0
  8. package/dist/adapters/elysia.mjs +76 -0
  9. package/dist/adapters/express.d.mts +16 -0
  10. package/dist/adapters/express.mjs +78 -0
  11. package/dist/adapters/fastify.d.mts +15 -0
  12. package/dist/adapters/fastify.mjs +78 -0
  13. package/dist/adapters/message-port.d.mts +37 -0
  14. package/dist/adapters/message-port.mjs +129 -0
  15. package/dist/adapters/nestjs.d.mts +25 -0
  16. package/dist/adapters/nestjs.mjs +91 -0
  17. package/dist/adapters/nextjs.d.mts +21 -0
  18. package/dist/adapters/nextjs.mjs +30 -0
  19. package/dist/adapters/peer.d.mts +27 -0
  20. package/dist/adapters/peer.mjs +36 -0
  21. package/dist/adapters/remix.d.mts +17 -0
  22. package/dist/adapters/remix.mjs +24 -0
  23. package/dist/adapters/solidstart.d.mts +14 -0
  24. package/dist/adapters/solidstart.mjs +30 -0
  25. package/dist/adapters/sveltekit.d.mts +18 -0
  26. package/dist/adapters/sveltekit.mjs +33 -0
  27. package/dist/analyze.mjs +26 -0
  28. package/dist/broker/index.d.mts +62 -0
  29. package/dist/broker/index.mjs +153 -0
  30. package/dist/broker/nats.d.mts +33 -0
  31. package/dist/broker/nats.mjs +31 -0
  32. package/dist/broker/redis.d.mts +51 -0
  33. package/dist/broker/redis.mjs +92 -0
  34. package/dist/builder.d.mts +36 -0
  35. package/dist/builder.mjs +51 -0
  36. package/dist/callable.d.mts +17 -0
  37. package/dist/callable.mjs +42 -0
  38. package/dist/client/adapters/fetch/index.d.mts +17 -0
  39. package/dist/client/adapters/fetch/index.mjs +61 -0
  40. package/dist/client/adapters/ofetch/index.d.mts +41 -0
  41. package/dist/client/adapters/ofetch/index.mjs +92 -0
  42. package/dist/client/client.d.mts +29 -0
  43. package/dist/client/client.mjs +54 -0
  44. package/dist/client/dynamic-link.d.mts +15 -0
  45. package/dist/client/dynamic-link.mjs +16 -0
  46. package/dist/client/index.d.mts +7 -0
  47. package/dist/client/index.mjs +6 -0
  48. package/dist/client/interceptor.d.mts +31 -0
  49. package/dist/client/interceptor.mjs +34 -0
  50. package/dist/client/merge.d.mts +28 -0
  51. package/dist/client/merge.mjs +30 -0
  52. package/dist/client/openapi.d.mts +29 -0
  53. package/dist/client/openapi.mjs +89 -0
  54. package/dist/client/plugins/batch.d.mts +20 -0
  55. package/dist/client/plugins/batch.mjs +64 -0
  56. package/dist/client/plugins/csrf.d.mts +13 -0
  57. package/dist/client/plugins/csrf.mjs +20 -0
  58. package/dist/client/plugins/dedupe.d.mts +10 -0
  59. package/dist/client/plugins/dedupe.mjs +28 -0
  60. package/dist/client/plugins/index.d.mts +5 -0
  61. package/dist/client/plugins/index.mjs +5 -0
  62. package/dist/client/plugins/retry.d.mts +11 -0
  63. package/dist/client/plugins/retry.mjs +21 -0
  64. package/dist/client/server.d.mts +16 -0
  65. package/dist/client/server.mjs +60 -0
  66. package/dist/client/types.d.mts +29 -0
  67. package/dist/codec/devalue.d.mts +21 -0
  68. package/dist/codec/devalue.mjs +32 -0
  69. package/dist/codec/msgpack.d.mts +21 -0
  70. package/dist/codec/msgpack.mjs +59 -0
  71. package/dist/compile.d.mts +54 -0
  72. package/dist/compile.mjs +305 -0
  73. package/dist/contract.d.mts +36 -0
  74. package/dist/contract.mjs +40 -0
  75. package/dist/core/error.d.mts +104 -0
  76. package/dist/core/error.mjs +139 -0
  77. package/dist/core/handler.mjs +546 -0
  78. package/dist/core/iterator.d.mts +17 -0
  79. package/dist/core/iterator.mjs +79 -0
  80. package/dist/core/router-utils.mjs +16 -0
  81. package/dist/core/schema.d.mts +19 -0
  82. package/dist/core/schema.mjs +26 -0
  83. package/dist/core/serve.mjs +38 -0
  84. package/dist/core/sse.d.mts +16 -0
  85. package/dist/core/sse.mjs +95 -0
  86. package/dist/core/storage.d.mts +21 -0
  87. package/dist/core/storage.mjs +63 -0
  88. package/dist/core/utils.mjs +21 -0
  89. package/dist/fast-stringify.mjs +125 -0
  90. package/dist/index.d.mts +15 -37
  91. package/dist/index.mjs +13 -7
  92. package/dist/integrations/ai/index.d.mts +25 -0
  93. package/dist/integrations/ai/index.mjs +116 -0
  94. package/dist/integrations/react/index.d.mts +83 -0
  95. package/dist/integrations/react/index.mjs +197 -0
  96. package/dist/integrations/tanstack-query/index.d.mts +120 -0
  97. package/dist/integrations/tanstack-query/index.mjs +100 -0
  98. package/dist/integrations/tanstack-query/ssr.d.mts +51 -0
  99. package/dist/integrations/tanstack-query/ssr.mjs +89 -0
  100. package/dist/integrations/zod/converter.d.mts +75 -0
  101. package/dist/integrations/zod/converter.mjs +345 -0
  102. package/dist/integrations/zod/index.d.mts +2 -0
  103. package/dist/integrations/zod/index.mjs +2 -0
  104. package/dist/lazy.d.mts +24 -0
  105. package/dist/lazy.mjs +27 -0
  106. package/dist/lifecycle.d.mts +36 -0
  107. package/dist/lifecycle.mjs +46 -0
  108. package/dist/map-input.d.mts +17 -0
  109. package/dist/map-input.mjs +24 -0
  110. package/dist/plugins/analytics.d.mts +168 -0
  111. package/dist/plugins/analytics.mjs +459 -0
  112. package/dist/plugins/batch-server.d.mts +20 -0
  113. package/dist/plugins/batch-server.mjs +86 -0
  114. package/dist/plugins/body-limit.d.mts +16 -0
  115. package/dist/plugins/body-limit.mjs +44 -0
  116. package/dist/plugins/cache.d.mts +170 -0
  117. package/dist/plugins/cache.mjs +200 -0
  118. package/dist/plugins/coerce.d.mts +21 -0
  119. package/dist/plugins/coerce.mjs +46 -0
  120. package/dist/plugins/compression.d.mts +19 -0
  121. package/dist/plugins/compression.mjs +23 -0
  122. package/dist/plugins/cookies.d.mts +44 -0
  123. package/dist/plugins/cookies.mjs +67 -0
  124. package/dist/plugins/cors.d.mts +39 -0
  125. package/dist/plugins/cors.mjs +56 -0
  126. package/dist/plugins/custom-serializer.d.mts +57 -0
  127. package/dist/plugins/custom-serializer.mjs +40 -0
  128. package/dist/plugins/file-upload.d.mts +38 -0
  129. package/dist/plugins/file-upload.mjs +100 -0
  130. package/dist/plugins/index.d.mts +16 -0
  131. package/dist/plugins/index.mjs +16 -0
  132. package/dist/plugins/otel.d.mts +35 -0
  133. package/dist/plugins/otel.mjs +40 -0
  134. package/dist/plugins/pino.d.mts +60 -0
  135. package/dist/plugins/pino.mjs +42 -0
  136. package/dist/plugins/pubsub.d.mts +50 -0
  137. package/dist/plugins/pubsub.mjs +53 -0
  138. package/dist/plugins/ratelimit.d.mts +51 -0
  139. package/dist/plugins/ratelimit.mjs +81 -0
  140. package/dist/plugins/signing.d.mts +41 -0
  141. package/dist/plugins/signing.mjs +115 -0
  142. package/dist/plugins/strict-get.d.mts +10 -0
  143. package/dist/plugins/strict-get.mjs +33 -0
  144. package/dist/route/add.mjs +240 -0
  145. package/dist/route/compiler.mjs +373 -0
  146. package/dist/route/context.mjs +12 -0
  147. package/dist/route/types.d.mts +11 -0
  148. package/dist/route/utils.mjs +17 -0
  149. package/dist/scalar.d.mts +53 -0
  150. package/dist/scalar.mjs +330 -0
  151. package/dist/silgi.d.mts +139 -0
  152. package/dist/silgi.mjs +113 -0
  153. package/dist/trpc-interop.d.mts +22 -0
  154. package/dist/trpc-interop.mjs +68 -0
  155. package/dist/types.d.mts +82 -0
  156. package/dist/ws.d.mts +42 -0
  157. package/dist/ws.mjs +137 -0
  158. package/lib/dashboard/index.html +123 -0
  159. package/lib/ocache.d.mts +1 -0
  160. package/lib/ocache.mjs +1 -0
  161. package/lib/ofetch.d.mts +1 -0
  162. package/lib/ofetch.mjs +1 -0
  163. package/lib/srvx.d.mts +1 -0
  164. package/lib/srvx.mjs +1 -0
  165. package/lib/unstorage.d.mts +1 -0
  166. package/lib/unstorage.mjs +1 -0
  167. package/package.json +291 -65
  168. package/bin/silgi.mjs +0 -3
  169. package/dist/chunks/generate.mjs +0 -933
  170. package/dist/chunks/init.mjs +0 -21
  171. package/dist/cli/config.d.mts +0 -19
  172. package/dist/cli/config.d.ts +0 -19
  173. package/dist/cli/config.mjs +0 -5
  174. package/dist/cli/index.d.mts +0 -2
  175. package/dist/cli/index.d.ts +0 -2
  176. package/dist/cli/index.mjs +0 -119
  177. package/dist/index.d.ts +0 -37
  178. package/dist/plugins/openapi.d.mts +0 -138
  179. package/dist/plugins/openapi.d.ts +0 -138
  180. package/dist/plugins/openapi.mjs +0 -204
  181. package/dist/plugins/scalar.d.mts +0 -14
  182. package/dist/plugins/scalar.d.ts +0 -14
  183. package/dist/plugins/scalar.mjs +0 -66
  184. package/dist/shared/silgi.BMCYk2cR.mjs +0 -841
  185. package/dist/shared/silgi.D5qK9QOm.d.mts +0 -301
  186. package/dist/shared/silgi.D5qK9QOm.d.ts +0 -301
@@ -0,0 +1,75 @@
1
+ import { AnySchema } from "../../core/schema.mjs";
2
+
3
+ //#region src/integrations/zod/converter.d.ts
4
+ type JSONSchema = {
5
+ type?: string | string[];
6
+ format?: string;
7
+ properties?: Record<string, JSONSchema>;
8
+ required?: string[];
9
+ items?: JSONSchema;
10
+ prefixItems?: JSONSchema[];
11
+ anyOf?: JSONSchema[];
12
+ oneOf?: JSONSchema[];
13
+ allOf?: JSONSchema[];
14
+ not?: JSONSchema;
15
+ enum?: unknown[];
16
+ const?: unknown;
17
+ $ref?: string;
18
+ description?: string;
19
+ title?: string;
20
+ default?: unknown;
21
+ examples?: unknown[];
22
+ deprecated?: boolean;
23
+ readOnly?: boolean;
24
+ minimum?: number;
25
+ maximum?: number;
26
+ exclusiveMinimum?: number;
27
+ exclusiveMaximum?: number;
28
+ multipleOf?: number;
29
+ minLength?: number;
30
+ maxLength?: number;
31
+ pattern?: string;
32
+ minItems?: number;
33
+ maxItems?: number;
34
+ uniqueItems?: boolean;
35
+ minProperties?: number;
36
+ maxProperties?: number;
37
+ additionalProperties?: boolean | JSONSchema;
38
+ 'x-native-type'?: string;
39
+ [key: string]: unknown;
40
+ };
41
+ interface ConvertOptions {
42
+ /** 'input' uses pre-transform types, 'output' uses post-transform */
43
+ strategy: 'input' | 'output';
44
+ /** Max recursion depth before falling back to {} */
45
+ maxDepth?: number;
46
+ }
47
+ /**
48
+ * Convert a Standard Schema to JSON Schema.
49
+ * Returns [required, jsonSchema] tuple.
50
+ */
51
+ interface SchemaConverter {
52
+ condition(schema: AnySchema): boolean;
53
+ convert(schema: AnySchema, options: ConvertOptions): [required: boolean, schema: JSONSchema];
54
+ }
55
+ /**
56
+ * Composite converter — tries each converter in order.
57
+ */
58
+ declare class CompositeSchemaConverter {
59
+ #private;
60
+ constructor(converters: SchemaConverter[]);
61
+ convert(schema: AnySchema | undefined, options: ConvertOptions): [boolean, JSONSchema];
62
+ }
63
+ /**
64
+ * Zod v4 → JSON Schema converter.
65
+ */
66
+ declare class ZodSchemaConverter implements SchemaConverter {
67
+ #private;
68
+ constructor(options?: {
69
+ maxDepth?: number;
70
+ });
71
+ condition(schema: AnySchema): boolean;
72
+ convert(schema: AnySchema, options: ConvertOptions): [boolean, JSONSchema];
73
+ }
74
+ //#endregion
75
+ export { CompositeSchemaConverter, ConvertOptions, JSONSchema, SchemaConverter, ZodSchemaConverter };
@@ -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 };
@@ -0,0 +1,2 @@
1
+ import { CompositeSchemaConverter, ConvertOptions, JSONSchema, SchemaConverter, ZodSchemaConverter } from "./converter.mjs";
2
+ export { CompositeSchemaConverter, type ConvertOptions, type JSONSchema, type SchemaConverter, ZodSchemaConverter };
@@ -0,0 +1,2 @@
1
+ import { CompositeSchemaConverter, ZodSchemaConverter } from "./converter.mjs";
2
+ export { CompositeSchemaConverter, ZodSchemaConverter };
@@ -0,0 +1,24 @@
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
+ _resolved?: RouterDef | ProcedureDef;
10
+ _loading?: Promise<RouterDef | ProcedureDef>;
11
+ }
12
+ /**
13
+ * Wrap a dynamic import for lazy loading.
14
+ * The module must export its router/procedure as `default`.
15
+ */
16
+ declare function lazy(loader: () => Promise<{
17
+ default: RouterDef | ProcedureDef;
18
+ }>): LazyRouter;
19
+ /** Check if a value is a lazy router */
20
+ declare function isLazy(value: unknown): value is LazyRouter;
21
+ /** Resolve a lazy router (cached after first load, race-safe) */
22
+ declare function resolveLazy(value: LazyRouter): Promise<RouterDef | ProcedureDef>;
23
+ //#endregion
24
+ export { LazyRouter, isLazy, lazy, resolveLazy };
package/dist/lazy.mjs ADDED
@@ -0,0 +1,27 @@
1
+ //#region src/lazy.ts
2
+ /**
3
+ * Wrap a dynamic import for lazy loading.
4
+ * The module must export its router/procedure as `default`.
5
+ */
6
+ function lazy(loader) {
7
+ return {
8
+ __lazy: true,
9
+ load: loader
10
+ };
11
+ }
12
+ /** Check if a value is a lazy router */
13
+ function isLazy(value) {
14
+ return typeof value === "object" && value !== null && value.__lazy === true;
15
+ }
16
+ /** Resolve a lazy router (cached after first load, race-safe) */
17
+ async function resolveLazy(value) {
18
+ if (value._resolved) return value._resolved;
19
+ if (value._loading) return value._loading;
20
+ value._loading = value.load().then((mod) => {
21
+ value._resolved = mod.default;
22
+ return mod.default;
23
+ });
24
+ return value._loading;
25
+ }
26
+ //#endregion
27
+ 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,24 @@
1
+ //#region src/map-input.ts
2
+ /**
3
+ * Create a wrap that transforms the procedure input before execution.
4
+ *
5
+ * The mapper function receives the raw input and returns the transformed input.
6
+ * The mapped input is set on the context as `__mappedInput` and picked up
7
+ * by the pipeline.
8
+ *
9
+ * Note: Since Silgi's pipeline receives input as a separate argument
10
+ * (not on ctx), mapInput works as a wrap that intercepts and transforms
11
+ * before calling next().
12
+ */
13
+ function mapInput(mapper) {
14
+ return {
15
+ kind: "wrap",
16
+ fn: async (ctx, next) => {
17
+ const rawInput = ctx.__rawInput;
18
+ ctx.__rawInput = await mapper(rawInput);
19
+ return next();
20
+ }
21
+ };
22
+ }
23
+ //#endregion
24
+ export { mapInput };