@temporary-name/server 1.9.3-alpha.2957dbc009ec31fa21575f028b83c96651cba827 → 1.9.3-alpha.305aebe633f301e28426c6b15cdfd58ddf45641c
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 +3 -3
- package/dist/adapters/aws-lambda/index.d.ts +3 -3
- package/dist/adapters/aws-lambda/index.mjs +3 -3
- package/dist/adapters/fetch/index.d.mts +3 -3
- package/dist/adapters/fetch/index.d.ts +3 -3
- package/dist/adapters/fetch/index.mjs +3 -3
- package/dist/adapters/node/index.d.mts +3 -3
- package/dist/adapters/node/index.d.ts +3 -3
- package/dist/adapters/node/index.mjs +3 -3
- package/dist/adapters/standard/index.d.mts +3 -3
- package/dist/adapters/standard/index.d.ts +3 -3
- package/dist/adapters/standard/index.mjs +3 -3
- package/dist/index.d.mts +338 -34
- package/dist/index.d.ts +338 -34
- package/dist/index.mjs +424 -96
- package/dist/openapi/index.d.mts +16 -34
- package/dist/openapi/index.d.ts +16 -34
- package/dist/openapi/index.mjs +339 -298
- package/dist/shared/{server.DfUs5c4R.d.ts → server.B0LJ_wu-.d.ts} +3 -3
- package/dist/shared/{server.L8lRAYBR.d.mts → server.BQZMQrPe.d.mts} +3 -3
- package/dist/shared/{server.CpS0m3at.mjs → server.CYa9puL2.mjs} +3 -3
- package/dist/shared/server.ChOv1yG3.mjs +319 -0
- package/dist/shared/server.CjPiuQYH.d.mts +51 -0
- package/dist/shared/server.CjPiuQYH.d.ts +51 -0
- package/dist/shared/server.Cza0RB3u.mjs +160 -0
- package/dist/shared/{server.DPD7R7h_.d.mts → server.DXPMDozZ.d.mts} +182 -20
- package/dist/shared/{server.DPD7R7h_.d.ts → server.DXPMDozZ.d.ts} +182 -20
- package/dist/shared/server.Ny4yD6yY.mjs +525 -0
- package/package.json +10 -11
- package/dist/shared/server.B7tjiDal.mjs +0 -354
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { ValidationError, eventIterator } from '@temporary-name/contract';
|
|
3
|
-
import { assertNever, splitFirst, ORPCError, onError, resolveMaybeOptionalOptions } from '@temporary-name/shared';
|
|
1
|
+
import { assertNever, splitFirst, ORPCError, onError, isObject, toArray, guard, resolveMaybeOptionalOptions, isTypescriptObject, isPropertyKey } from '@temporary-name/shared';
|
|
4
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
5
|
import { g as getCookie } from './shared/server.C1RJffw4.mjs';
|
|
7
|
-
import { P as Procedure,
|
|
8
|
-
export { L as LAZY_SYMBOL,
|
|
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, h as isLazy, j as getRouter } from './shared/server.ChOv1yG3.mjs';
|
|
7
|
+
export { L as LAZY_SYMBOL, V as ValidationError, q as createAccessibleLazyRouter, w as endpointRegex, g as getDynamicParams, n as isStartWithMiddlewares, k as lazy, o as mergeMiddlewares, r as resolveContractProcedures, s as standardizeHTTPPath, t as traverseContractProcedures, v as unlazyRouter } from './shared/server.ChOv1yG3.mjs';
|
|
8
|
+
import { c as createProcedureClient } from './shared/server.Cza0RB3u.mjs';
|
|
9
|
+
export { m as mergeCurrentContext, a as middlewareOutputFn } from './shared/server.Cza0RB3u.mjs';
|
|
10
|
+
import { J as JsonSchemaXNativeType } from './shared/server.Ny4yD6yY.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.Ny4yD6yY.mjs';
|
|
9
12
|
export { getEventMeta, withEventMeta } from '@temporary-name/standard-server';
|
|
10
13
|
import 'cookie';
|
|
14
|
+
import '@temporary-name/server/openapi';
|
|
15
|
+
import 'zod/v4/core';
|
|
11
16
|
|
|
12
17
|
function validateTokenPrefix(prefix, token) {
|
|
13
18
|
if (prefix && !token.startsWith(prefix)) {
|
|
@@ -19,47 +24,57 @@ function validateTokenAuth(config, token, options) {
|
|
|
19
24
|
validateTokenPrefix(tokenPrefix, token);
|
|
20
25
|
return validate(token, options);
|
|
21
26
|
}
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
+
}
|
|
57
68
|
}
|
|
58
69
|
function authDescription(config) {
|
|
59
70
|
const { type } = config;
|
|
60
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);
|
|
61
72
|
}
|
|
62
73
|
|
|
74
|
+
function mergeMeta(meta1, meta2) {
|
|
75
|
+
return { ...meta1, ...meta2 };
|
|
76
|
+
}
|
|
77
|
+
|
|
63
78
|
class DecoratedProcedure extends Procedure {
|
|
64
79
|
/**
|
|
65
80
|
* Make this procedure callable (works like a function while still being a procedure).
|
|
@@ -79,6 +94,13 @@ class DecoratedProcedure extends Procedure {
|
|
|
79
94
|
}
|
|
80
95
|
}
|
|
81
96
|
|
|
97
|
+
const initialSchemas = {
|
|
98
|
+
pathSchema: z.strictObject({}),
|
|
99
|
+
querySchema: z.strictObject({}),
|
|
100
|
+
bodySchema: z.strictObject({}),
|
|
101
|
+
outputSchema: z.unknown()
|
|
102
|
+
};
|
|
103
|
+
|
|
82
104
|
class ProcedureBuilder extends Contract {
|
|
83
105
|
z;
|
|
84
106
|
constructor(def) {
|
|
@@ -160,28 +182,19 @@ class ProcedureBuilder extends Contract {
|
|
|
160
182
|
outputValidationIndex: this["~orpc"].middlewares.length
|
|
161
183
|
});
|
|
162
184
|
}
|
|
163
|
-
/**
|
|
164
|
-
* Uses a middleware to modify the context or improve the pipeline.
|
|
165
|
-
*
|
|
166
|
-
* @info Supports both normal middleware and inline middleware implementations.
|
|
167
|
-
* @note The current context must be satisfy middleware dependent-context
|
|
168
|
-
* @see {@link https://orpc.unnoq.com/docs/middleware Middleware Docs}
|
|
169
|
-
*/
|
|
170
185
|
use(middleware) {
|
|
171
186
|
return new this.constructor({
|
|
172
187
|
...this["~orpc"],
|
|
173
188
|
middlewares: addMiddleware(this["~orpc"].middlewares, middleware)
|
|
174
189
|
});
|
|
175
190
|
}
|
|
176
|
-
// `& {}` is so AuthType will be expanded in parameter info tooltips.
|
|
177
191
|
// The default of false for ValidatedAuthContext is used when you pass in the type 'none'. We use false
|
|
178
192
|
// because we can't use null or undefined (see ValidatedAuthContext) but we still want it to be falsy.
|
|
179
|
-
useAuth(
|
|
180
|
-
const
|
|
181
|
-
const middleware = os.$context().middleware(async (options) => {
|
|
193
|
+
useAuth(config) {
|
|
194
|
+
const middleware = baseApi.$context().middleware(async (options) => {
|
|
182
195
|
const { next, context } = options;
|
|
183
196
|
if (context.auth) return next();
|
|
184
|
-
const auth = await
|
|
197
|
+
const auth = await runAuth(config, options);
|
|
185
198
|
if (auth === void 0) {
|
|
186
199
|
const { authConfigs } = options.procedure["~orpc"];
|
|
187
200
|
if (context.auth !== false && config === authConfigs.at(-1)) {
|
|
@@ -271,31 +284,6 @@ function decorateMiddleware(middleware) {
|
|
|
271
284
|
);
|
|
272
285
|
return mapped;
|
|
273
286
|
};
|
|
274
|
-
decorated.concat = (concatMiddleware, mapInput) => {
|
|
275
|
-
const mapped = mapInput ? decorateMiddleware(concatMiddleware).mapInput(mapInput) : concatMiddleware;
|
|
276
|
-
const concatted = decorateMiddleware((options, input, output, ...rest) => {
|
|
277
|
-
const merged = middleware(
|
|
278
|
-
{
|
|
279
|
-
...options,
|
|
280
|
-
next: (...[nextOptions1]) => mapped(
|
|
281
|
-
{
|
|
282
|
-
...options,
|
|
283
|
-
context: { ...options.context, ...nextOptions1?.context },
|
|
284
|
-
next: (...[nextOptions2]) => options.next({ context: { ...nextOptions1?.context, ...nextOptions2?.context } })
|
|
285
|
-
},
|
|
286
|
-
input,
|
|
287
|
-
output,
|
|
288
|
-
...rest
|
|
289
|
-
)
|
|
290
|
-
},
|
|
291
|
-
input,
|
|
292
|
-
output,
|
|
293
|
-
...rest
|
|
294
|
-
);
|
|
295
|
-
return merged;
|
|
296
|
-
});
|
|
297
|
-
return concatted;
|
|
298
|
-
};
|
|
299
287
|
return decorated;
|
|
300
288
|
}
|
|
301
289
|
|
|
@@ -317,25 +305,348 @@ class Builder extends BuilderWithMiddlewares {
|
|
|
317
305
|
return decorateMiddleware(middleware);
|
|
318
306
|
}
|
|
319
307
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
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
|
+
});
|
|
324
|
+
|
|
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;
|
|
330
|
+
}
|
|
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;
|
|
352
|
+
}
|
|
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;
|
|
370
|
+
}
|
|
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);
|
|
398
|
+
}
|
|
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
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
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
|
+
}
|
|
547
|
+
}
|
|
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
|
+
}
|
|
556
|
+
}
|
|
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
|
+
}
|
|
571
|
+
}
|
|
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;
|
|
595
|
+
}
|
|
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
|
+
}
|
|
337
649
|
}
|
|
338
|
-
const os = createApiBuilder();
|
|
339
650
|
|
|
340
651
|
function createAssertedLazyProcedure(lazied) {
|
|
341
652
|
const lazyProcedure = lazyInternal(async () => {
|
|
@@ -381,4 +692,21 @@ function createRouterClient(router, ...rest) {
|
|
|
381
692
|
return recursive;
|
|
382
693
|
}
|
|
383
694
|
|
|
384
|
-
|
|
695
|
+
function isSchemaIssue(issue) {
|
|
696
|
+
if (!isTypescriptObject(issue) || typeof issue.message !== "string") {
|
|
697
|
+
return false;
|
|
698
|
+
}
|
|
699
|
+
if (issue.path !== void 0) {
|
|
700
|
+
if (!Array.isArray(issue.path)) {
|
|
701
|
+
return false;
|
|
702
|
+
}
|
|
703
|
+
if (!issue.path.every(
|
|
704
|
+
(segment) => isPropertyKey(segment) || isTypescriptObject(segment) && isPropertyKey(segment.key)
|
|
705
|
+
)) {
|
|
706
|
+
return false;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
return true;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
export { Builder, BuilderWithMiddlewares, Contract, DecoratedProcedure, JsonSchemaXNativeType, Procedure, ProcedureBuilder, addMiddleware, baseApi, call, createAssertedLazyProcedure, createProcedureClient, createRouterClient, decorateMiddleware, enhanceRouter, experimental_JsonSchemaCoercer, getLazyMeta, getRouter, initialSchemas, isLazy, isProcedure, isSchemaIssue, lazyInternal, mergeMeta, parseEndpointDefinition, unlazy };
|
package/dist/openapi/index.d.mts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import {
|
|
1
|
+
import { Contract } from '@temporary-name/server';
|
|
2
|
+
import { OpenAPI, Promisable, Value, HTTPPath, HTTPMethod } from '@temporary-name/shared';
|
|
3
|
+
export { OpenAPI } from '@temporary-name/shared';
|
|
4
|
+
import { Z as ZodToJsonSchemaConverterOptions } from '../shared/server.CjPiuQYH.mjs';
|
|
5
|
+
import { d as AnySchema, b as Contract$1, a9 as TraverseContractProcedureCallbackOptions, $ as ContractRouter, u as AnyRouter } from '../shared/server.DXPMDozZ.mjs';
|
|
5
6
|
import { JSONSchema } from '@temporary-name/interop/json-schema-typed/draft-2020-12';
|
|
6
7
|
export { JSONSchema, ContentEncoding as JSONSchemaContentEncoding, Format as JSONSchemaFormat, TypeName as JSONSchemaTypeName } from '@temporary-name/interop/json-schema-typed/draft-2020-12';
|
|
8
|
+
import '@temporary-name/server/openapi';
|
|
9
|
+
import '@temporary-name/zod';
|
|
7
10
|
|
|
8
11
|
type OverrideOperationValue = Partial<OpenAPI.OperationObject> | ((current: OpenAPI.OperationObject, procedure: Contract) => OpenAPI.OperationObject);
|
|
9
12
|
/**
|
|
@@ -54,29 +57,18 @@ interface SchemaConvertOptions {
|
|
|
54
57
|
*/
|
|
55
58
|
minStructureDepthForRef?: number;
|
|
56
59
|
}
|
|
57
|
-
|
|
58
|
-
convert(schemas: AnySchema | undefined, options: SchemaConvertOptions): Promisable<[required: boolean, jsonSchema: JSONSchema]>;
|
|
59
|
-
}
|
|
60
|
-
interface ConditionalSchemaConverter extends SchemaConverter {
|
|
61
|
-
condition(schema: AnySchema | undefined, options: SchemaConvertOptions): Promisable<boolean>;
|
|
62
|
-
}
|
|
63
|
-
declare class CompositeSchemaConverter implements SchemaConverter {
|
|
64
|
-
private readonly converters;
|
|
65
|
-
constructor(converters: readonly ConditionalSchemaConverter[]);
|
|
66
|
-
convert(schema: AnySchema | undefined, options: SchemaConvertOptions): Promise<[required: boolean, jsonSchema: JSONSchema]>;
|
|
67
|
-
}
|
|
60
|
+
type SchemaConverter = (schemas: AnySchema | undefined, options: SchemaConvertOptions) => Promisable<[required: boolean, jsonSchema: JSONSchema]>;
|
|
68
61
|
|
|
69
|
-
interface
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
interface OpenAPIGeneratorGenerateOptions extends Partial<Omit<OpenAPI.Document, 'openapi'>> {
|
|
62
|
+
interface OpenAPIGeneratorGenerateOptions {
|
|
63
|
+
spec?: Partial<Omit<OpenAPI.Document, 'openapi'>>;
|
|
64
|
+
schemaConverter?: ZodToJsonSchemaConverterOptions | SchemaConverter;
|
|
73
65
|
/**
|
|
74
66
|
* Exclude procedures from the OpenAPI specification.
|
|
75
67
|
*
|
|
76
68
|
* @deprecated Use `filter` option instead.
|
|
77
69
|
* @default () => false
|
|
78
70
|
*/
|
|
79
|
-
exclude?: (procedure: Contract, path: readonly string[]) => boolean;
|
|
71
|
+
exclude?: (procedure: Contract$1, path: readonly string[]) => boolean;
|
|
80
72
|
/**
|
|
81
73
|
* Filter procedures. Return `false` to exclude a procedure from the OpenAPI specification.
|
|
82
74
|
*
|
|
@@ -116,21 +108,11 @@ interface OpenAPIGeneratorGenerateOptions extends Partial<Omit<OpenAPI.Document,
|
|
|
116
108
|
}>;
|
|
117
109
|
}
|
|
118
110
|
/**
|
|
119
|
-
*
|
|
111
|
+
* Generates OpenAPI specifications from oRPC routers/contracts.
|
|
120
112
|
*
|
|
121
113
|
* @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
|
|
122
114
|
*/
|
|
123
|
-
declare
|
|
124
|
-
#private;
|
|
125
|
-
private readonly converter;
|
|
126
|
-
constructor(options?: OpenAPIGeneratorOptions);
|
|
127
|
-
/**
|
|
128
|
-
* Generates OpenAPI specifications from oRPC routers/contracts.
|
|
129
|
-
*
|
|
130
|
-
* @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
|
|
131
|
-
*/
|
|
132
|
-
generate(router: ContractRouter | AnyRouter, options?: OpenAPIGeneratorGenerateOptions): Promise<OpenAPI.Document>;
|
|
133
|
-
}
|
|
115
|
+
declare function generateOpenApiSpec(router: ContractRouter | AnyRouter, options?: OpenAPIGeneratorGenerateOptions): Promise<OpenAPI.Document>;
|
|
134
116
|
|
|
135
117
|
/**
|
|
136
118
|
* @internal
|
|
@@ -199,5 +181,5 @@ declare const oo: {
|
|
|
199
181
|
spec: typeof customOpenAPIOperation;
|
|
200
182
|
};
|
|
201
183
|
|
|
202
|
-
export {
|
|
203
|
-
export type {
|
|
184
|
+
export { LOGIC_KEYWORDS, applyCustomOpenAPIOperation, applySchemaOptionality, checkParamsSchema, customOpenAPIOperation, expandArrayableSchema, expandUnionSchema, filterSchemaBranches, generateOpenApiSpec, getCustomOpenAPIOperation, isAnySchema, isFileSchema, isObjectSchema, isPrimitiveSchema, oo, resolveOpenAPIJsonSchemaRef, separateObjectSchema, toOpenAPIContent, toOpenAPIEventIteratorContent, toOpenAPIMethod, toOpenAPIParameters, toOpenAPIPath, toOpenAPISchema };
|
|
185
|
+
export type { FileSchema, ObjectSchema, OpenAPIGeneratorGenerateOptions, OverrideOperationValue, SchemaConvertOptions, SchemaConverter, SchemaConverterComponent };
|