@temporary-name/server 1.9.3-alpha.1a5ff4923d25c9d83e80d717687ebc859f5312f2 → 1.9.3-alpha.205fb2d0874fa3b8bbf83112a63016937380442e

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 (46) hide show
  1. package/dist/adapters/aws-lambda/index.d.mts +5 -7
  2. package/dist/adapters/aws-lambda/index.d.ts +5 -7
  3. package/dist/adapters/aws-lambda/index.mjs +5 -6
  4. package/dist/adapters/fetch/index.d.mts +8 -86
  5. package/dist/adapters/fetch/index.d.ts +8 -86
  6. package/dist/adapters/fetch/index.mjs +17 -157
  7. package/dist/adapters/node/index.d.mts +9 -64
  8. package/dist/adapters/node/index.d.ts +9 -64
  9. package/dist/adapters/node/index.mjs +15 -122
  10. package/dist/handler/index.d.mts +28 -0
  11. package/dist/handler/index.d.ts +28 -0
  12. package/dist/handler/index.mjs +8 -0
  13. package/dist/helpers/index.mjs +3 -29
  14. package/dist/index.d.mts +366 -213
  15. package/dist/index.d.ts +366 -213
  16. package/dist/index.mjs +484 -178
  17. package/dist/openapi/index.d.mts +18 -53
  18. package/dist/openapi/index.d.ts +18 -53
  19. package/dist/openapi/index.mjs +391 -368
  20. package/dist/shared/server.B5ntjz_x.d.mts +800 -0
  21. package/dist/shared/server.B5ntjz_x.d.ts +800 -0
  22. package/dist/shared/server.BGG3eatg.mjs +315 -0
  23. package/dist/shared/server.BM9lK_Yv.mjs +523 -0
  24. package/dist/shared/server.BxyeakF-.d.mts +39 -0
  25. package/dist/shared/server.C1RJffw4.mjs +30 -0
  26. package/dist/shared/server.CjPiuQYH.d.mts +51 -0
  27. package/dist/shared/server.CjPiuQYH.d.ts +51 -0
  28. package/dist/shared/server.CmNVzZVe.mjs +156 -0
  29. package/dist/shared/server.Coz0LFSE.d.ts +39 -0
  30. package/dist/shared/server.X8F6e8eV.mjs +499 -0
  31. package/package.json +13 -31
  32. package/dist/adapters/standard/index.d.mts +0 -31
  33. package/dist/adapters/standard/index.d.ts +0 -31
  34. package/dist/adapters/standard/index.mjs +0 -9
  35. package/dist/plugins/index.d.mts +0 -160
  36. package/dist/plugins/index.d.ts +0 -160
  37. package/dist/plugins/index.mjs +0 -288
  38. package/dist/shared/server.B--sAUhn.mjs +0 -254
  39. package/dist/shared/server.BCcLYvdF.d.mts +0 -56
  40. package/dist/shared/server.CHV9AQHl.mjs +0 -412
  41. package/dist/shared/server.CdeqmULw.d.ts +0 -56
  42. package/dist/shared/server.DHezmW6C.d.mts +0 -23
  43. package/dist/shared/server.Da-qLzdU.d.ts +0 -23
  44. package/dist/shared/server.DecvGKtb.d.mts +0 -242
  45. package/dist/shared/server.DecvGKtb.d.ts +0 -242
  46. package/dist/shared/server.Kxw442A9.mjs +0 -247
package/dist/index.mjs CHANGED
@@ -1,11 +1,80 @@
1
- import { mergePrefix, mergeTags, ContractProcedure, mergeErrorMap, mergeMeta, mergeRoute, prefixRoute, initialSchemas, isContractProcedure, getContractRouter } from '@temporary-name/contract';
2
- export { ValidationError, eventIterator, validateORPCError } from '@temporary-name/contract';
3
- import { onError, resolveMaybeOptionalOptions } from '@temporary-name/shared';
4
- export { AsyncIteratorClass, EventPublisher, ORPCError, asyncIteratorToStream as eventIteratorToStream, isDefinedError, onError, onFinish, onStart, onSuccess, safe, streamToAsyncIteratorClass as streamToEventIterator } from '@temporary-name/shared';
5
- import { SchemaClass, gatingContext } from '@temporary-name/zod';
6
- import { P as Procedure, c as createProcedureClient, e as enhanceRouter, a as addMiddleware, s as setHiddenRouterContract, l as lazyInternal, g as getLazyMeta, u as unlazy, i as isProcedure, b as isLazy, d as getRouter } from './shared/server.CHV9AQHl.mjs';
7
- export { L as LAZY_SYMBOL, p as createAccessibleLazyRouter, f as createORPCErrorConstructorMap, o as getHiddenRouterContract, k as isStartWithMiddlewares, h as lazy, m as mergeCurrentContext, n as mergeMiddlewares, j as middlewareOutputFn, r as resolveContractProcedures, t as traverseContractProcedures, q as unlazyRouter } from './shared/server.CHV9AQHl.mjs';
1
+ import { assertNever, splitFirst, onError, isObject, toArray, guard, resolveMaybeOptionalOptions, isTypescriptObject, isPropertyKey } from '@temporary-name/shared';
2
+ export { AsyncIteratorClass, EventPublisher, asyncIteratorToStream as eventIteratorToStream, onError, onFinish, onStart, onSuccess, streamToAsyncIteratorClass as streamToEventIterator } from '@temporary-name/shared';
3
+ import * as z from '@temporary-name/zod';
4
+ import { SchemaClass, object, core, gatingContext } from '@temporary-name/zod';
5
+ export { z as baseZ };
6
+ import { U as UnauthorizedError, P as Procedure, m as mergePrefix, a as mergeTags, b as enhanceRouter, C as Contract, p as parseEndpointDefinition, c as mergeRoute, d as prefixRoute, f as addMiddleware, l as lazyInternal, h as getLazyMeta, u as unlazy, j as isProcedure } from './shared/server.X8F6e8eV.mjs';
7
+ export { A as APIError, B as BadRequestError, F as ForbiddenError, I as InternalServerError, L as LAZY_SYMBOL, N as NotFoundError, V as ValidationError, x as createAccessibleLazyRouter, e as encodeError, D as endpointRegex, g as getDynamicParams, w as getRouter, i as isAPIErrorStatus, E as isDevelopment, o as isLazy, q as isStartWithMiddlewares, n as lazy, k as makeErrors, v as mergeMiddlewares, r as resolveContractProcedures, s as standardizeHTTPPath, t as toAPIError, y as traverseContractProcedures, z as unlazyRouter } from './shared/server.X8F6e8eV.mjs';
8
+ import { g as getCookie } from './shared/server.C1RJffw4.mjs';
9
+ import { c as createProcedureClient } from './shared/server.CmNVzZVe.mjs';
10
+ export { m as mergeCurrentContext, a as middlewareOutputFn } from './shared/server.CmNVzZVe.mjs';
11
+ import { J as JsonSchemaXNativeType } from './shared/server.BM9lK_Yv.mjs';
12
+ export { b as JSON_SCHEMA_INPUT_REGISTRY, c as JSON_SCHEMA_OUTPUT_REGISTRY, a as JSON_SCHEMA_REGISTRY, Z as ZodToJsonSchemaConverter, e as eventIterator, g as getEventIteratorSchemaDetails } from './shared/server.BM9lK_Yv.mjs';
8
13
  export { getEventMeta, withEventMeta } from '@temporary-name/standard-server';
14
+ import 'cookie';
15
+ import '@temporary-name/server/openapi';
16
+ import 'zod/v4/core';
17
+
18
+ function validateTokenPrefix(prefix, token) {
19
+ if (prefix && !token.startsWith(prefix)) {
20
+ throw new UnauthorizedError({ message: `Invalid auth token. It must start with "${prefix}"` });
21
+ }
22
+ }
23
+ function validateTokenAuth(config, token, options) {
24
+ const { tokenPrefix, validate } = config;
25
+ validateTokenPrefix(tokenPrefix, token);
26
+ return validate(token, options);
27
+ }
28
+ function runAuth(config, options) {
29
+ switch (config.type) {
30
+ case "header": {
31
+ const authHeader = options.request.headers.get(config.name);
32
+ return authHeader ? validateTokenAuth(config, authHeader, options) : void 0;
33
+ }
34
+ case "query": {
35
+ const { name, tokenPrefix, validate } = config;
36
+ const query = options.request.url.searchParams;
37
+ const token = query.get(name);
38
+ if (!token) return void 0;
39
+ validateTokenPrefix(tokenPrefix, token);
40
+ return validate(token, options);
41
+ }
42
+ case "cookie": {
43
+ const cookie = getCookie(options.request.headers, config.name);
44
+ return cookie ? validateTokenAuth(config, cookie, options) : void 0;
45
+ }
46
+ case "bearer": {
47
+ const authHeader = options.request.headers.get("Authorization");
48
+ if (!authHeader) return void 0;
49
+ const [authType, bearer] = splitFirst(authHeader, " ");
50
+ return authType === "Bearer" ? validateTokenAuth(config, bearer, options) : void 0;
51
+ }
52
+ case "basic": {
53
+ const authHeader = options.request.headers.get("Authorization");
54
+ if (!authHeader) return void 0;
55
+ const [authType, encoded] = splitFirst(authHeader, " ");
56
+ if (authType !== "Basic") return void 0;
57
+ const decoded = Buffer.from(encoded, "base64").toString("utf-8");
58
+ const [username, password] = splitFirst(decoded, ":");
59
+ validateTokenPrefix(config.tokenPrefix, password);
60
+ return config.validate(username, password, options);
61
+ }
62
+ case "none": {
63
+ return false;
64
+ }
65
+ default: {
66
+ assertNever(config);
67
+ }
68
+ }
69
+ }
70
+ function authDescription(config) {
71
+ const { type } = config;
72
+ return type === "basic" ? "a Basic Authentication header" : type === "bearer" ? "a Bearer Authentication header" : type === "header" ? `a header named "${config.name}"` : type === "query" ? `a query parameter named "${config.name}"` : type === "cookie" ? `a cookie named "${config.name}"` : type === "none" ? "no authentication" : assertNever(type);
73
+ }
74
+
75
+ function mergeMeta(meta1, meta2) {
76
+ return { ...meta1, ...meta2 };
77
+ }
9
78
 
10
79
  class DecoratedProcedure extends Procedure {
11
80
  /**
@@ -26,24 +95,19 @@ class DecoratedProcedure extends Procedure {
26
95
  }
27
96
  }
28
97
 
29
- class ProcedureBuilder extends ContractProcedure {
98
+ const initialSchemas = {
99
+ pathSchema: z.strictObject({}),
100
+ querySchema: z.strictObject({}),
101
+ bodySchema: z.strictObject({}),
102
+ outputSchema: z.unknown()
103
+ };
104
+
105
+ class ProcedureBuilder extends Contract {
30
106
  z;
31
107
  constructor(def) {
32
108
  super(def);
33
109
  this.z = new SchemaClass();
34
110
  }
35
- /**
36
- * Adds type-safe custom errors to the contract.
37
- * The provided errors are spared-merged with any existing errors in the contract.
38
- *
39
- * @see {@link https://orpc.unnoq.com/docs/error-handling#type%E2%80%90safe-error-handling Type-Safe Error Handling Docs}
40
- */
41
- errors(errors) {
42
- return new ProcedureBuilder({
43
- ...this["~orpc"],
44
- errorMap: mergeErrorMap(this["~orpc"].errorMap, errors)
45
- });
46
- }
47
111
  /**
48
112
  * Sets or updates the metadata for the contract.
49
113
  * The provided metadata is spared-merged with any existing metadata in the contract.
@@ -56,6 +120,19 @@ class ProcedureBuilder extends ContractProcedure {
56
120
  meta: mergeMeta(this["~orpc"].meta, meta)
57
121
  });
58
122
  }
123
+ endpoint(stringsOrEndpoint, ...values) {
124
+ const { method, path, pathSchema } = parseEndpointDefinition(stringsOrEndpoint, values);
125
+ const { prefix } = this["~orpc"];
126
+ const route = { method, path };
127
+ return new ProcedureBuilder({
128
+ ...this["~orpc"],
129
+ route: mergeRoute(this["~orpc"].route, prefix ? prefixRoute(route, prefix) : route),
130
+ schemas: {
131
+ ...this["~orpc"].schemas,
132
+ pathSchema
133
+ }
134
+ });
135
+ }
59
136
  /**
60
137
  * Sets or updates the route definition for the contract.
61
138
  * The provided route is spared-merged with any existing route in the contract.
@@ -64,29 +141,19 @@ class ProcedureBuilder extends ContractProcedure {
64
141
  * @see {@link https://orpc.unnoq.com/docs/openapi/routing OpenAPI Routing Docs}
65
142
  * @see {@link https://orpc.unnoq.com/docs/openapi/input-output-structure OpenAPI Input/Output Structure Docs}
66
143
  */
67
- route(route) {
144
+ endpointOpts(route) {
68
145
  const { prefix } = this["~orpc"];
69
146
  return new ProcedureBuilder({
70
147
  ...this["~orpc"],
71
148
  route: mergeRoute(this["~orpc"].route, prefix ? prefixRoute(route, prefix) : route)
72
149
  });
73
150
  }
74
- path(schema) {
75
- return new ProcedureBuilder({
76
- ...this["~orpc"],
77
- schemas: {
78
- ...this["~orpc"].schemas,
79
- pathSchema: schema
80
- },
81
- inputValidationIndex: this["~orpc"].middlewares.length
82
- });
83
- }
84
151
  query(schema) {
85
152
  return new ProcedureBuilder({
86
153
  ...this["~orpc"],
87
154
  schemas: {
88
155
  ...this["~orpc"].schemas,
89
- querySchema: schema
156
+ querySchema: schema instanceof core.$ZodType ? schema : object(schema)
90
157
  },
91
158
  inputValidationIndex: this["~orpc"].middlewares.length
92
159
  });
@@ -96,7 +163,7 @@ class ProcedureBuilder extends ContractProcedure {
96
163
  ...this["~orpc"],
97
164
  schemas: {
98
165
  ...this["~orpc"].schemas,
99
- bodySchema: schema
166
+ bodySchema: schema instanceof core.$ZodType ? schema : object(schema)
100
167
  },
101
168
  inputValidationIndex: this["~orpc"].middlewares.length
102
169
  });
@@ -111,24 +178,51 @@ class ProcedureBuilder extends ContractProcedure {
111
178
  ...this["~orpc"],
112
179
  schemas: {
113
180
  ...this["~orpc"].schemas,
114
- outputSchema: schema
181
+ outputSchema: schema instanceof core.$ZodType ? schema : object(schema)
115
182
  },
116
183
  outputValidationIndex: this["~orpc"].middlewares.length
117
184
  });
118
185
  }
119
- /**
120
- * Uses a middleware to modify the context or improve the pipeline.
121
- *
122
- * @info Supports both normal middleware and inline middleware implementations.
123
- * @note The current context must be satisfy middleware dependent-context
124
- * @see {@link https://orpc.unnoq.com/docs/middleware Middleware Docs}
125
- */
126
186
  use(middleware) {
127
187
  return new this.constructor({
128
188
  ...this["~orpc"],
129
189
  middlewares: addMiddleware(this["~orpc"].middlewares, middleware)
130
190
  });
131
191
  }
192
+ useErrors(errorMap) {
193
+ return new this.constructor({
194
+ ...this["~orpc"],
195
+ errorMap
196
+ });
197
+ }
198
+ // The default of false for ValidatedAuthContext is used when you pass in the type 'none'. We use false
199
+ // because we can't use null or undefined (see ValidatedAuthContext) but we still want it to be falsy.
200
+ useAuth(config) {
201
+ const middleware = baseApi.$context().middleware(async (options) => {
202
+ const { next, context } = options;
203
+ if (context.auth) return next();
204
+ const auth = await runAuth(config, options);
205
+ if (auth === void 0) {
206
+ const { authConfigs } = options.procedure["~orpc"];
207
+ if (context.auth !== false && config === authConfigs.at(-1)) {
208
+ let authDescriptions = authConfigs.map(authDescription).join(", ");
209
+ if (authConfigs.length > 1) {
210
+ authDescriptions = `one of: ${authDescriptions}`;
211
+ }
212
+ throw new UnauthorizedError({
213
+ message: `Authentication required. You must provide ${authDescriptions}`
214
+ });
215
+ }
216
+ return next();
217
+ }
218
+ return next({ context: { auth } });
219
+ });
220
+ return new this.constructor({
221
+ ...this["~orpc"],
222
+ authConfigs: [...this["~orpc"].authConfigs, config],
223
+ middlewares: addMiddleware(this["~orpc"].middlewares, middleware)
224
+ });
225
+ }
132
226
  useGating(gates, isGateEnabled) {
133
227
  return this.use(({ next, context }) => {
134
228
  return gatingContext.run(
@@ -143,6 +237,9 @@ class ProcedureBuilder extends ContractProcedure {
143
237
  * @see {@link https://orpc.unnoq.com/docs/procedure Procedure Docs}
144
238
  */
145
239
  handler(handler) {
240
+ if (this["~orpc"].schemas.outputSchema === initialSchemas.outputSchema) {
241
+ throw new Error("You must call .output() before calling .handler()");
242
+ }
146
243
  return new DecoratedProcedure({
147
244
  ...this["~orpc"],
148
245
  handler
@@ -194,31 +291,6 @@ function decorateMiddleware(middleware) {
194
291
  );
195
292
  return mapped;
196
293
  };
197
- decorated.concat = (concatMiddleware, mapInput) => {
198
- const mapped = mapInput ? decorateMiddleware(concatMiddleware).mapInput(mapInput) : concatMiddleware;
199
- const concatted = decorateMiddleware((options, input, output, ...rest) => {
200
- const merged = middleware(
201
- {
202
- ...options,
203
- next: (...[nextOptions1]) => mapped(
204
- {
205
- ...options,
206
- context: { ...options.context, ...nextOptions1?.context },
207
- next: (...[nextOptions2]) => options.next({ context: { ...nextOptions1?.context, ...nextOptions2?.context } })
208
- },
209
- input,
210
- output,
211
- ...rest
212
- )
213
- },
214
- input,
215
- output,
216
- ...rest
217
- );
218
- return merged;
219
- });
220
- return concatted;
221
- };
222
294
  return decorated;
223
295
  }
224
296
 
@@ -240,98 +312,348 @@ class Builder extends BuilderWithMiddlewares {
240
312
  return decorateMiddleware(middleware);
241
313
  }
242
314
  }
243
- function createApiBuilder(opts = {}) {
244
- return new Builder({
245
- route: {},
246
- meta: opts.meta ?? {},
247
- errorMap: {},
248
- inputValidationIndex: 0,
249
- outputValidationIndex: 0,
250
- middlewares: [
251
- onError((error, _options) => {
252
- console.dir(error, { depth: null });
253
- })
254
- ],
255
- schemas: initialSchemas,
256
- // NB: this is a relic from orpc -- I'm not convinced there's a need for this (or if there is, that it's
257
- // the best solution). For now I've removed the interface to configure it externally.
258
- dedupeLeadingMiddlewares: true
259
- });
260
- }
261
- const os = createApiBuilder();
315
+ const baseApi = new Builder({
316
+ route: {},
317
+ meta: {},
318
+ errorMap: {},
319
+ inputValidationIndex: 0,
320
+ outputValidationIndex: 0,
321
+ middlewares: [
322
+ onError((error, _options) => {
323
+ console.dir(error, { depth: null });
324
+ })
325
+ ],
326
+ schemas: initialSchemas,
327
+ // NB: this is a relic from orpc -- I'm not convinced there's a need for this (or if there is, that it's
328
+ // the best solution). For now I've removed the interface to configure it externally.
329
+ dedupeLeadingMiddlewares: true,
330
+ authConfigs: []
331
+ });
262
332
 
263
- function implementerInternal(contract, middlewares) {
264
- if (isContractProcedure(contract)) {
265
- const impl2 = new Builder({
266
- ...contract["~orpc"],
267
- middlewares,
268
- inputValidationIndex: middlewares.length,
269
- outputValidationIndex: middlewares.length,
270
- dedupeLeadingMiddlewares: true
271
- });
272
- return impl2;
333
+ const FLEXIBLE_DATE_FORMAT_REGEX = /^[^-]+-[^-]+-[^-]+$/;
334
+ class experimental_JsonSchemaCoercer {
335
+ coerce(schema, value, options = {}) {
336
+ const [, coerced] = this.#coerce(schema, value, options);
337
+ return coerced;
273
338
  }
274
- const impl = new Proxy(contract, {
275
- get: (target, key) => {
276
- if (typeof key !== "string") {
277
- return Reflect.get(target, key);
278
- }
279
- let method;
280
- if (key === "middleware") {
281
- method = (mid) => decorateMiddleware(mid);
282
- } else if (key === "use") {
283
- method = (mid) => {
284
- return implementerInternal(contract, addMiddleware(middlewares, mid));
285
- };
286
- } else if (key === "router") {
287
- method = (router) => {
288
- const adapted = enhanceRouter(router, {
289
- middlewares,
290
- errorMap: {},
291
- prefix: void 0,
292
- tags: void 0,
293
- dedupeLeadingMiddlewares: true
294
- });
295
- return setHiddenRouterContract(adapted, contract);
296
- };
339
+ #coerce(schema, originalValue, options) {
340
+ if (typeof schema === "boolean") {
341
+ return [schema, originalValue];
342
+ }
343
+ if (Array.isArray(schema.type)) {
344
+ return this.#coerce(
345
+ {
346
+ anyOf: schema.type.map((type) => ({ ...schema, type }))
347
+ },
348
+ originalValue,
349
+ options
350
+ );
351
+ }
352
+ let coerced = originalValue;
353
+ let satisfied = true;
354
+ if (typeof schema.$ref === "string") {
355
+ const refSchema = options?.components?.[schema.$ref];
356
+ if (refSchema !== void 0) {
357
+ const [subSatisfied, subCoerced] = this.#coerce(refSchema, coerced, options);
358
+ coerced = subCoerced;
359
+ satisfied = subSatisfied;
297
360
  }
298
- const next = getContractRouter(target, [key]);
299
- if (!next) {
300
- return method ?? next;
361
+ }
362
+ const enumValues = schema.const !== void 0 ? [schema.const] : schema.enum;
363
+ if (enumValues !== void 0 && !enumValues.includes(coerced)) {
364
+ if (typeof coerced === "string") {
365
+ const numberValue = this.#stringToNumber(coerced);
366
+ if (enumValues.includes(numberValue)) {
367
+ coerced = numberValue;
368
+ } else {
369
+ const booleanValue = this.#stringToBoolean(coerced);
370
+ if (enumValues.includes(booleanValue)) {
371
+ coerced = booleanValue;
372
+ } else {
373
+ satisfied = false;
374
+ }
375
+ }
376
+ } else {
377
+ satisfied = false;
301
378
  }
302
- const nextImpl = implementerInternal(next, middlewares);
303
- if (method) {
304
- return new Proxy(method, {
305
- get(_, key2) {
306
- return Reflect.get(nextImpl, key2);
379
+ }
380
+ if (typeof schema.type === "string") {
381
+ switch (schema.type) {
382
+ case "null": {
383
+ if (coerced !== null) {
384
+ satisfied = false;
385
+ }
386
+ break;
387
+ }
388
+ case "string": {
389
+ if (typeof coerced !== "string") {
390
+ satisfied = false;
391
+ }
392
+ break;
393
+ }
394
+ case "number": {
395
+ if (typeof coerced === "string") {
396
+ coerced = this.#stringToNumber(coerced);
397
+ }
398
+ if (typeof coerced !== "number") {
399
+ satisfied = false;
400
+ }
401
+ break;
402
+ }
403
+ case "integer": {
404
+ if (typeof coerced === "string") {
405
+ coerced = this.#stringToInteger(coerced);
406
+ }
407
+ if (typeof coerced !== "number" || !Number.isInteger(coerced)) {
408
+ satisfied = false;
409
+ }
410
+ break;
411
+ }
412
+ case "boolean": {
413
+ if (typeof coerced === "string") {
414
+ coerced = this.#stringToBoolean(coerced);
415
+ }
416
+ if (typeof coerced !== "boolean") {
417
+ satisfied = false;
418
+ }
419
+ break;
420
+ }
421
+ case "array": {
422
+ if (Array.isArray(coerced)) {
423
+ const prefixItemSchemas = "prefixItems" in schema ? toArray(schema.prefixItems) : Array.isArray(schema.items) ? schema.items : [];
424
+ const itemSchema = Array.isArray(schema.items) ? schema.additionalItems : schema.items;
425
+ let shouldUseCoercedItems = false;
426
+ const coercedItems = coerced.map((item, i) => {
427
+ const subSchema = prefixItemSchemas[i] ?? itemSchema;
428
+ if (subSchema === void 0) {
429
+ satisfied = false;
430
+ return item;
431
+ }
432
+ const [subSatisfied, subCoerced] = this.#coerce(subSchema, item, options);
433
+ if (!subSatisfied) {
434
+ satisfied = false;
435
+ }
436
+ if (subCoerced !== item) {
437
+ shouldUseCoercedItems = true;
438
+ }
439
+ return subCoerced;
440
+ });
441
+ if (coercedItems.length < prefixItemSchemas.length) {
442
+ satisfied = false;
443
+ }
444
+ if (shouldUseCoercedItems) {
445
+ coerced = coercedItems;
446
+ }
447
+ } else {
448
+ satisfied = false;
449
+ }
450
+ break;
451
+ }
452
+ case "object": {
453
+ if (Array.isArray(coerced)) {
454
+ coerced = { ...coerced };
455
+ }
456
+ if (isObject(coerced)) {
457
+ let shouldUseCoercedItems = false;
458
+ const coercedItems = {};
459
+ const patternProperties = Object.entries(schema.patternProperties ?? {}).map(
460
+ ([key, value]) => [new RegExp(key), value]
461
+ );
462
+ for (const key in coerced) {
463
+ const value = coerced[key];
464
+ const subSchema = schema.properties?.[key] ?? patternProperties.find(([pattern]) => pattern.test(key))?.[1] ?? schema.additionalProperties;
465
+ if (value === void 0 && !schema.required?.includes(key)) {
466
+ coercedItems[key] = value;
467
+ } else if (subSchema === void 0) {
468
+ coercedItems[key] = value;
469
+ satisfied = false;
470
+ } else {
471
+ const [subSatisfied, subCoerced] = this.#coerce(subSchema, value, options);
472
+ coercedItems[key] = subCoerced;
473
+ if (!subSatisfied) {
474
+ satisfied = false;
475
+ }
476
+ if (subCoerced !== value) {
477
+ shouldUseCoercedItems = true;
478
+ }
479
+ }
480
+ }
481
+ if (schema.required?.some((key) => !Object.hasOwn(coercedItems, key))) {
482
+ satisfied = false;
483
+ }
484
+ if (shouldUseCoercedItems) {
485
+ coerced = coercedItems;
486
+ }
487
+ } else {
488
+ satisfied = false;
307
489
  }
308
- });
490
+ break;
491
+ }
309
492
  }
310
- return nextImpl;
311
493
  }
312
- });
313
- return impl;
314
- }
315
- function implement(contract) {
316
- const implInternal = implementerInternal(contract, []);
317
- const impl = new Proxy(implInternal, {
318
- get: (target, key) => {
319
- let method;
320
- if (key === "$context") {
321
- method = () => impl;
494
+ if ("x-native-type" in schema && typeof schema["x-native-type"] === "string") {
495
+ switch (schema["x-native-type"]) {
496
+ case JsonSchemaXNativeType.Date: {
497
+ if (typeof coerced === "string") {
498
+ coerced = this.#stringToDate(coerced);
499
+ }
500
+ if (!(coerced instanceof Date)) {
501
+ satisfied = false;
502
+ }
503
+ break;
504
+ }
505
+ case JsonSchemaXNativeType.BigInt: {
506
+ switch (typeof coerced) {
507
+ case "string":
508
+ coerced = this.#stringToBigInt(coerced);
509
+ break;
510
+ case "number":
511
+ coerced = this.#numberToBigInt(coerced);
512
+ break;
513
+ }
514
+ if (typeof coerced !== "bigint") {
515
+ satisfied = false;
516
+ }
517
+ break;
518
+ }
519
+ case JsonSchemaXNativeType.RegExp: {
520
+ if (typeof coerced === "string") {
521
+ coerced = this.#stringToRegExp(coerced);
522
+ }
523
+ if (!(coerced instanceof RegExp)) {
524
+ satisfied = false;
525
+ }
526
+ break;
527
+ }
528
+ case JsonSchemaXNativeType.Url: {
529
+ if (typeof coerced === "string") {
530
+ coerced = this.#stringToURL(coerced);
531
+ }
532
+ if (!(coerced instanceof URL)) {
533
+ satisfied = false;
534
+ }
535
+ break;
536
+ }
537
+ case JsonSchemaXNativeType.Set: {
538
+ if (Array.isArray(coerced)) {
539
+ coerced = this.#arrayToSet(coerced);
540
+ }
541
+ if (!(coerced instanceof Set)) {
542
+ satisfied = false;
543
+ }
544
+ break;
545
+ }
546
+ case JsonSchemaXNativeType.Map: {
547
+ if (Array.isArray(coerced)) {
548
+ coerced = this.#arrayToMap(coerced);
549
+ }
550
+ if (!(coerced instanceof Map)) {
551
+ satisfied = false;
552
+ }
553
+ break;
554
+ }
322
555
  }
323
- const next = Reflect.get(target, key);
324
- if (!method || !next || typeof next !== "function" && typeof next !== "object") {
325
- return method || next;
556
+ }
557
+ if (schema.allOf) {
558
+ for (const subSchema of schema.allOf) {
559
+ const [subSatisfied, subCoerced] = this.#coerce(subSchema, coerced, options);
560
+ coerced = subCoerced;
561
+ if (!subSatisfied) {
562
+ satisfied = false;
563
+ }
326
564
  }
327
- return new Proxy(method, {
328
- get(_, key2) {
329
- return Reflect.get(next, key2);
565
+ }
566
+ for (const key of ["anyOf", "oneOf"]) {
567
+ if (schema[key]) {
568
+ let bestOptions;
569
+ for (const subSchema of schema[key]) {
570
+ const [subSatisfied, subCoerced] = this.#coerce(subSchema, coerced, options);
571
+ if (subSatisfied) {
572
+ if (!bestOptions || subCoerced === coerced) {
573
+ bestOptions = { coerced: subCoerced, satisfied: subSatisfied };
574
+ }
575
+ if (subCoerced === coerced) {
576
+ break;
577
+ }
578
+ }
330
579
  }
331
- });
580
+ coerced = bestOptions ? bestOptions.coerced : coerced;
581
+ satisfied = bestOptions ? bestOptions.satisfied : false;
582
+ }
583
+ }
584
+ if (typeof schema.not !== "undefined") {
585
+ const [notSatisfied] = this.#coerce(schema.not, coerced, options);
586
+ if (notSatisfied) {
587
+ satisfied = false;
588
+ }
589
+ }
590
+ return [satisfied, coerced];
591
+ }
592
+ #stringToNumber(value) {
593
+ const num = Number.parseFloat(value);
594
+ if (Number.isNaN(num) || num !== Number(value)) {
595
+ return value;
596
+ }
597
+ return num;
598
+ }
599
+ #stringToInteger(value) {
600
+ const num = Number.parseInt(value);
601
+ if (Number.isNaN(num) || num !== Number(value)) {
602
+ return value;
603
+ }
604
+ return num;
605
+ }
606
+ #stringToBoolean(value) {
607
+ const lower = value.toLowerCase();
608
+ if (lower === "false" || lower === "off") {
609
+ return false;
610
+ }
611
+ if (lower === "true" || lower === "on") {
612
+ return true;
613
+ }
614
+ return value;
615
+ }
616
+ #stringToBigInt(value) {
617
+ return guard(() => BigInt(value)) ?? value;
618
+ }
619
+ #numberToBigInt(value) {
620
+ return guard(() => BigInt(value)) ?? value;
621
+ }
622
+ #stringToDate(value) {
623
+ const date = new Date(value);
624
+ if (Number.isNaN(date.getTime()) || !FLEXIBLE_DATE_FORMAT_REGEX.test(value)) {
625
+ return value;
626
+ }
627
+ return date;
628
+ }
629
+ #stringToRegExp(value) {
630
+ const match = value.match(/^\/(.*)\/([a-z]*)$/);
631
+ if (match) {
632
+ const [, pattern, flags] = match;
633
+ return guard(() => new RegExp(pattern, flags)) ?? value;
634
+ }
635
+ return value;
636
+ }
637
+ #stringToURL(value) {
638
+ return guard(() => new URL(value)) ?? value;
639
+ }
640
+ #arrayToSet(value) {
641
+ const set = new Set(value);
642
+ if (set.size !== value.length) {
643
+ return value;
644
+ }
645
+ return set;
646
+ }
647
+ #arrayToMap(value) {
648
+ if (value.some((item) => !Array.isArray(item) || item.length !== 2)) {
649
+ return value;
332
650
  }
333
- });
334
- return impl;
651
+ const result = new Map(value);
652
+ if (result.size !== value.length) {
653
+ return value;
654
+ }
655
+ return result;
656
+ }
335
657
  }
336
658
 
337
659
  function createAssertedLazyProcedure(lazied) {
@@ -348,42 +670,26 @@ function createAssertedLazyProcedure(lazied) {
348
670
  }, getLazyMeta(lazied));
349
671
  return lazyProcedure;
350
672
  }
351
- function createContractedProcedure(procedure, contract) {
352
- return new Procedure({
353
- ...procedure["~orpc"],
354
- errorMap: contract["~orpc"].errorMap,
355
- route: contract["~orpc"].route,
356
- meta: contract["~orpc"].meta
357
- });
358
- }
359
673
  function call(procedure, input, ...rest) {
360
674
  const options = resolveMaybeOptionalOptions(rest);
361
675
  return createProcedureClient(procedure, options)(input, options);
362
676
  }
363
677
 
364
- function createRouterClient(router, ...rest) {
365
- const options = resolveMaybeOptionalOptions(rest);
366
- if (isProcedure(router)) {
367
- const caller = createProcedureClient(router, options);
368
- return caller;
369
- }
370
- const procedureCaller = isLazy(router) ? createProcedureClient(createAssertedLazyProcedure(router), options) : {};
371
- const recursive = new Proxy(procedureCaller, {
372
- get(target, key) {
373
- if (typeof key !== "string") {
374
- return Reflect.get(target, key);
375
- }
376
- const next = getRouter(router, [key]);
377
- if (!next) {
378
- return Reflect.get(target, key);
379
- }
380
- return createRouterClient(next, {
381
- ...rest[0],
382
- path: [...rest[0]?.path ?? [], key]
383
- });
678
+ function isSchemaIssue(issue) {
679
+ if (!isTypescriptObject(issue) || typeof issue.message !== "string") {
680
+ return false;
681
+ }
682
+ if (issue.path !== void 0) {
683
+ if (!Array.isArray(issue.path)) {
684
+ return false;
384
685
  }
385
- });
386
- return recursive;
686
+ if (!issue.path.every(
687
+ (segment) => isPropertyKey(segment) || isTypescriptObject(segment) && isPropertyKey(segment.key)
688
+ )) {
689
+ return false;
690
+ }
691
+ }
692
+ return true;
387
693
  }
388
694
 
389
- export { Builder, BuilderWithMiddlewares, DecoratedProcedure, Procedure, ProcedureBuilder, addMiddleware, call, createApiBuilder, createAssertedLazyProcedure, createContractedProcedure, createProcedureClient, createRouterClient, decorateMiddleware, enhanceRouter, getLazyMeta, getRouter, implement, implementerInternal, isLazy, isProcedure, lazyInternal, os, setHiddenRouterContract, unlazy };
695
+ export { Builder, BuilderWithMiddlewares, Contract, DecoratedProcedure, JsonSchemaXNativeType, Procedure, ProcedureBuilder, UnauthorizedError, addMiddleware, baseApi, call, createAssertedLazyProcedure, createProcedureClient, decorateMiddleware, enhanceRouter, experimental_JsonSchemaCoercer, getLazyMeta, initialSchemas, isProcedure, isSchemaIssue, lazyInternal, mergeMeta, parseEndpointDefinition, unlazy };