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