@temporary-name/server 1.9.3-alpha.6a70825f6d8c3dc99b87e4e5b778aea0fa007417 → 1.9.3-alpha.6a735c9469d995338b7d51335ea70485e18a4dca
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 -7
- package/dist/adapters/aws-lambda/index.d.ts +5 -7
- package/dist/adapters/aws-lambda/index.mjs +4 -6
- package/dist/adapters/fetch/index.d.mts +8 -86
- package/dist/adapters/fetch/index.d.ts +8 -86
- package/dist/adapters/fetch/index.mjs +16 -157
- package/dist/adapters/node/index.d.mts +9 -64
- package/dist/adapters/node/index.d.ts +9 -64
- package/dist/adapters/node/index.mjs +14 -122
- package/dist/{adapters/standard → handler}/index.d.mts +5 -7
- package/dist/{adapters/standard → handler}/index.d.ts +5 -7
- package/dist/handler/index.mjs +8 -0
- package/dist/helpers/index.mjs +3 -29
- package/dist/index.d.mts +368 -202
- package/dist/index.d.ts +368 -202
- package/dist/index.mjs +462 -176
- package/dist/openapi/index.d.mts +18 -53
- package/dist/openapi/index.d.ts +18 -53
- package/dist/openapi/index.mjs +340 -369
- 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 -31
- package/dist/adapters/standard/index.mjs +0 -10
- package/dist/plugins/index.d.mts +0 -160
- package/dist/plugins/index.d.ts +0 -160
- package/dist/plugins/index.mjs +0 -288
- package/dist/shared/server.BCcLYvdF.d.mts +0 -56
- package/dist/shared/server.CHV9AQHl.mjs +0 -412
- package/dist/shared/server.CdeqmULw.d.ts +0 -56
- package/dist/shared/server.DHezmW6C.d.mts +0 -23
- package/dist/shared/server.DN9mVGfv.mjs +0 -11
- package/dist/shared/server.DWwaAM-a.mjs +0 -255
- package/dist/shared/server.Da-qLzdU.d.ts +0 -23
- package/dist/shared/server.DecvGKtb.d.mts +0 -242
- package/dist/shared/server.DecvGKtb.d.ts +0 -242
- package/dist/shared/server.JtIZ8YG7.mjs +0 -237
package/dist/openapi/index.mjs
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { j as jsonSerialize, d as deserialize, s as serialize } from '../shared/server.JtIZ8YG7.mjs';
|
|
5
|
-
import '@temporary-name/standard-server';
|
|
6
|
-
import { s as standardizeHTTPPath, g as getDynamicParams } from '../shared/server.DN9mVGfv.mjs';
|
|
1
|
+
import { isObject, stringifyJSON, findDeepMatches, clone, value, fallbackContractConfig, toHttpPath, assertNever, isORPCErrorStatus } from '@temporary-name/shared';
|
|
2
|
+
import { Z as ZodToJsonSchemaConverter, g as getEventIteratorSchemaDetails } from '../shared/server.B_oW_rPl.mjs';
|
|
3
|
+
import { s as standardizeHTTPPath, r as resolveContractProcedures, g as getDynamicParams } from '../shared/server.BETu17rq.mjs';
|
|
7
4
|
import { TypeName } from '@temporary-name/interop/json-schema-typed/draft-2020-12';
|
|
8
5
|
export { ContentEncoding as JSONSchemaContentEncoding, Format as JSONSchemaFormat, TypeName as JSONSchemaTypeName } from '@temporary-name/interop/json-schema-typed/draft-2020-12';
|
|
6
|
+
import '@temporary-name/standard-server';
|
|
7
|
+
import '@temporary-name/zod';
|
|
8
|
+
import '@temporary-name/server/openapi';
|
|
9
|
+
import 'zod/v4/core';
|
|
9
10
|
|
|
10
11
|
const OPERATION_EXTENDER_SYMBOL = Symbol("ORPC_OPERATION_EXTENDER");
|
|
11
12
|
function customOpenAPIOperation(o, extend) {
|
|
@@ -23,20 +24,12 @@ function getCustomOpenAPIOperation(o) {
|
|
|
23
24
|
}
|
|
24
25
|
function applyCustomOpenAPIOperation(operation, contract) {
|
|
25
26
|
const operationCustoms = [];
|
|
26
|
-
for (const
|
|
27
|
-
const maybeExtender =
|
|
27
|
+
for (const middleware of contract["~orpc"].middlewares) {
|
|
28
|
+
const maybeExtender = getCustomOpenAPIOperation(middleware);
|
|
28
29
|
if (maybeExtender) {
|
|
29
30
|
operationCustoms.push(maybeExtender);
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
|
-
if (isProcedure(contract)) {
|
|
33
|
-
for (const middleware of contract["~orpc"].middlewares) {
|
|
34
|
-
const maybeExtender = getCustomOpenAPIOperation(middleware);
|
|
35
|
-
if (maybeExtender) {
|
|
36
|
-
operationCustoms.push(maybeExtender);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
33
|
let currentOperation = operation;
|
|
41
34
|
for (const custom of operationCustoms) {
|
|
42
35
|
if (typeof custom === "function") {
|
|
@@ -363,398 +356,376 @@ function resolveOpenAPIJsonSchemaRef(doc, schema) {
|
|
|
363
356
|
return resolved ?? schema;
|
|
364
357
|
}
|
|
365
358
|
|
|
366
|
-
class
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
359
|
+
class OpenAPIGeneratorError extends Error {
|
|
360
|
+
}
|
|
361
|
+
async function generateOpenApiSpec(router, options = {}) {
|
|
362
|
+
const converter = typeof options.schemaConverter === "function" ? options.schemaConverter : new ZodToJsonSchemaConverter(options.schemaConverter ?? {}).convert;
|
|
363
|
+
const filter = options.filter ?? (({ contract, path }) => {
|
|
364
|
+
return !(options.exclude?.(contract, path) ?? false);
|
|
365
|
+
});
|
|
366
|
+
const doc = {
|
|
367
|
+
...clone(options.spec),
|
|
368
|
+
info: options.spec?.info ?? { title: "API Reference", version: "0.0.0" },
|
|
369
|
+
openapi: "3.1.1"
|
|
370
|
+
};
|
|
371
|
+
const { baseSchemaConvertOptions } = await resolveCommonSchemas(doc, options.commonSchemas, converter);
|
|
372
|
+
const contracts = [];
|
|
373
|
+
await resolveContractProcedures({ path: [], router }, (traverseOptions) => {
|
|
374
|
+
if (!value(filter, traverseOptions)) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
contracts.push(traverseOptions);
|
|
378
|
+
});
|
|
379
|
+
const namesByAuthConfig = /* @__PURE__ */ new Map();
|
|
380
|
+
const authConfigNames = /* @__PURE__ */ new Set();
|
|
381
|
+
for (const { contract } of contracts) {
|
|
382
|
+
for (const authConfig of contract["~orpc"].authConfigs) {
|
|
383
|
+
if (authConfig.type === "none" || namesByAuthConfig.has(authConfig)) {
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
const oasNameBase = authConfig.oasName ?? `${authConfig.type}Auth`;
|
|
387
|
+
let oasName = oasNameBase;
|
|
388
|
+
for (let i = 2; authConfigNames.has(oasName); i++) {
|
|
389
|
+
oasName = `${oasNameBase}${i}`;
|
|
375
390
|
}
|
|
391
|
+
namesByAuthConfig.set(authConfig, oasName);
|
|
392
|
+
authConfigNames.add(oasName);
|
|
376
393
|
}
|
|
377
|
-
return [false, {}];
|
|
378
394
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
constructor(options = {}) {
|
|
386
|
-
this.converter = new CompositeSchemaConverter(toArray(options.schemaConverters));
|
|
395
|
+
if (namesByAuthConfig.size > 0) {
|
|
396
|
+
doc.components ??= {};
|
|
397
|
+
const schemes = doc.components.securitySchemes ??= {};
|
|
398
|
+
for (const [authConfig, name] of namesByAuthConfig) {
|
|
399
|
+
schemes[name] ??= authConfigToSecurityScheme(authConfig);
|
|
400
|
+
}
|
|
387
401
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
);
|
|
409
|
-
const contracts = [];
|
|
410
|
-
await resolveContractProcedures({ path: [], router }, (traverseOptions) => {
|
|
411
|
-
if (!value(filter, traverseOptions)) {
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
contracts.push(traverseOptions);
|
|
415
|
-
});
|
|
416
|
-
const errors = [];
|
|
417
|
-
for (const { contract, path } of contracts) {
|
|
418
|
-
const stringPath = path.join(".");
|
|
419
|
-
try {
|
|
420
|
-
const def = contract["~orpc"];
|
|
421
|
-
const method = toOpenAPIMethod(fallbackContractConfig("defaultMethod", def.route.method));
|
|
422
|
-
const httpPath = toOpenAPIPath(def.route.path ?? toHttpPath(path));
|
|
423
|
-
let operationObjectRef;
|
|
424
|
-
if (def.route.spec !== void 0 && typeof def.route.spec !== "function") {
|
|
425
|
-
operationObjectRef = def.route.spec;
|
|
426
|
-
} else {
|
|
427
|
-
operationObjectRef = {
|
|
428
|
-
operationId: def.route.operationId ?? stringPath,
|
|
429
|
-
summary: def.route.summary,
|
|
430
|
-
description: def.route.description,
|
|
431
|
-
deprecated: def.route.deprecated,
|
|
432
|
-
tags: def.route.tags?.map((tag) => tag)
|
|
433
|
-
};
|
|
434
|
-
await this.#request(doc, operationObjectRef, def, baseSchemaConvertOptions);
|
|
435
|
-
await this.#successResponse(doc, operationObjectRef, def, baseSchemaConvertOptions);
|
|
436
|
-
await this.#errorResponse(
|
|
437
|
-
operationObjectRef,
|
|
438
|
-
def,
|
|
439
|
-
baseSchemaConvertOptions,
|
|
440
|
-
undefinedErrorJsonSchema
|
|
441
|
-
);
|
|
442
|
-
}
|
|
443
|
-
if (typeof def.route.spec === "function") {
|
|
444
|
-
operationObjectRef = def.route.spec(operationObjectRef);
|
|
445
|
-
}
|
|
446
|
-
doc.paths ??= {};
|
|
447
|
-
doc.paths[httpPath] ??= {};
|
|
448
|
-
doc.paths[httpPath][method] = applyCustomOpenAPIOperation(operationObjectRef, contract);
|
|
449
|
-
} catch (e) {
|
|
450
|
-
if (!(e instanceof OpenAPIGeneratorError)) {
|
|
451
|
-
throw e;
|
|
452
|
-
}
|
|
453
|
-
errors.push(
|
|
454
|
-
`[OpenAPIGenerator] Error occurred while generating OpenAPI for procedure at path: ${stringPath}
|
|
455
|
-
${e.message}`
|
|
402
|
+
const errors = [];
|
|
403
|
+
for (const { contract, path } of contracts) {
|
|
404
|
+
const stringPath = path.join(".");
|
|
405
|
+
try {
|
|
406
|
+
const def = contract["~orpc"];
|
|
407
|
+
const method = toOpenAPIMethod(fallbackContractConfig("defaultMethod", def.route.method));
|
|
408
|
+
const httpPath = toOpenAPIPath(def.route.path ?? toHttpPath(path));
|
|
409
|
+
let operationObjectRef;
|
|
410
|
+
if (def.route.spec !== void 0 && typeof def.route.spec !== "function") {
|
|
411
|
+
operationObjectRef = def.route.spec;
|
|
412
|
+
} else {
|
|
413
|
+
operationObjectRef = {
|
|
414
|
+
operationId: def.route.operationId ?? stringPath,
|
|
415
|
+
summary: def.route.summary,
|
|
416
|
+
description: def.route.description,
|
|
417
|
+
deprecated: def.route.deprecated,
|
|
418
|
+
tags: def.route.tags?.map((tag) => tag)
|
|
419
|
+
};
|
|
420
|
+
const security = def.authConfigs.map(
|
|
421
|
+
(authConfig) => authConfig.type === "none" ? {} : { [namesByAuthConfig.get(authConfig)]: [] }
|
|
456
422
|
);
|
|
423
|
+
if (security.length > 0) {
|
|
424
|
+
operationObjectRef.security = security;
|
|
425
|
+
}
|
|
426
|
+
await handleRequest(doc, operationObjectRef, def, baseSchemaConvertOptions, converter);
|
|
427
|
+
await handleSuccessResponse(doc, operationObjectRef, def, baseSchemaConvertOptions, converter);
|
|
428
|
+
}
|
|
429
|
+
if (typeof def.route.spec === "function") {
|
|
430
|
+
operationObjectRef = def.route.spec(operationObjectRef);
|
|
431
|
+
}
|
|
432
|
+
doc.paths ??= {};
|
|
433
|
+
doc.paths[httpPath] ??= {};
|
|
434
|
+
doc.paths[httpPath][method] = applyCustomOpenAPIOperation(operationObjectRef, contract);
|
|
435
|
+
} catch (e) {
|
|
436
|
+
if (!(e instanceof OpenAPIGeneratorError)) {
|
|
437
|
+
throw e;
|
|
457
438
|
}
|
|
439
|
+
errors.push(
|
|
440
|
+
`[OpenAPIGenerator] Error occurred while generating OpenAPI for procedure at path: ${stringPath}
|
|
441
|
+
${e.message}`
|
|
442
|
+
);
|
|
458
443
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
444
|
+
}
|
|
445
|
+
if (errors.length) {
|
|
446
|
+
throw new OpenAPIGeneratorError(
|
|
447
|
+
`Some error occurred during OpenAPI generation:
|
|
462
448
|
|
|
463
449
|
${errors.join("\n\n")}`
|
|
464
|
-
|
|
465
|
-
}
|
|
466
|
-
return jsonSerialize(doc)[0];
|
|
450
|
+
);
|
|
467
451
|
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
},
|
|
478
|
-
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
452
|
+
return doc;
|
|
453
|
+
}
|
|
454
|
+
async function resolveCommonSchemas(doc, commonSchemas, converter) {
|
|
455
|
+
let undefinedErrorJsonSchema = {
|
|
456
|
+
type: "object",
|
|
457
|
+
properties: {
|
|
458
|
+
defined: { const: false },
|
|
459
|
+
code: { type: "string" },
|
|
460
|
+
status: { type: "number" },
|
|
461
|
+
message: { type: "string" },
|
|
462
|
+
data: {}
|
|
463
|
+
},
|
|
464
|
+
required: ["defined", "code", "status", "message"]
|
|
465
|
+
};
|
|
466
|
+
const baseSchemaConvertOptions = {};
|
|
467
|
+
if (commonSchemas) {
|
|
468
|
+
baseSchemaConvertOptions.components = [];
|
|
469
|
+
for (const key in commonSchemas) {
|
|
470
|
+
const options = commonSchemas[key];
|
|
471
|
+
if (options.schema === void 0) {
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
474
|
+
const { schema, strategy = "input" } = options;
|
|
475
|
+
const [required, json] = await converter(schema, { strategy });
|
|
476
|
+
const allowedStrategies = [strategy];
|
|
477
|
+
if (strategy === "input") {
|
|
478
|
+
const [outputRequired, outputJson] = await converter(schema, { strategy: "output" });
|
|
479
|
+
if (outputRequired === required && stringifyJSON(outputJson) === stringifyJSON(json)) {
|
|
480
|
+
allowedStrategies.push("output");
|
|
487
481
|
}
|
|
488
|
-
|
|
489
|
-
const [
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
const [outputRequired, outputJson] = await this.converter.convert(schema, { strategy: "output" });
|
|
493
|
-
if (outputRequired === required && stringifyJSON(outputJson) === stringifyJSON(json)) {
|
|
494
|
-
allowedStrategies.push("output");
|
|
495
|
-
}
|
|
496
|
-
} else if (strategy === "output") {
|
|
497
|
-
const [inputRequired, inputJson] = await this.converter.convert(schema, { strategy: "input" });
|
|
498
|
-
if (inputRequired === required && stringifyJSON(inputJson) === stringifyJSON(json)) {
|
|
499
|
-
allowedStrategies.push("input");
|
|
500
|
-
}
|
|
482
|
+
} else if (strategy === "output") {
|
|
483
|
+
const [inputRequired, inputJson] = await converter(schema, { strategy: "input" });
|
|
484
|
+
if (inputRequired === required && stringifyJSON(inputJson) === stringifyJSON(json)) {
|
|
485
|
+
allowedStrategies.push("input");
|
|
501
486
|
}
|
|
502
|
-
baseSchemaConvertOptions.components.push({
|
|
503
|
-
schema,
|
|
504
|
-
required,
|
|
505
|
-
ref: `#/components/schemas/${key}`,
|
|
506
|
-
allowedStrategies
|
|
507
|
-
});
|
|
508
487
|
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
488
|
+
baseSchemaConvertOptions.components.push({
|
|
489
|
+
schema,
|
|
490
|
+
required,
|
|
491
|
+
ref: `#/components/schemas/${key}`,
|
|
492
|
+
allowedStrategies
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
doc.components ??= {};
|
|
496
|
+
doc.components.schemas ??= {};
|
|
497
|
+
for (const key in commonSchemas) {
|
|
498
|
+
const options = commonSchemas[key];
|
|
499
|
+
if (options.schema === void 0) {
|
|
500
|
+
if (options.error === "UndefinedError") {
|
|
501
|
+
doc.components.schemas[key] = toOpenAPISchema(undefinedErrorJsonSchema);
|
|
502
|
+
undefinedErrorJsonSchema = { $ref: `#/components/schemas/${key}` };
|
|
519
503
|
}
|
|
520
|
-
|
|
521
|
-
const [, json] = await this.converter.convert(schema, {
|
|
522
|
-
...baseSchemaConvertOptions,
|
|
523
|
-
strategy,
|
|
524
|
-
minStructureDepthForRef: 1
|
|
525
|
-
// not allow use $ref for root schemas
|
|
526
|
-
});
|
|
527
|
-
doc.components.schemas[key] = toOpenAPISchema(json);
|
|
504
|
+
continue;
|
|
528
505
|
}
|
|
506
|
+
const { schema, strategy = "input" } = options;
|
|
507
|
+
const [, json] = await converter(schema, {
|
|
508
|
+
...baseSchemaConvertOptions,
|
|
509
|
+
strategy,
|
|
510
|
+
minStructureDepthForRef: 1
|
|
511
|
+
// not allow use $ref for root schemas
|
|
512
|
+
});
|
|
513
|
+
doc.components.schemas[key] = toOpenAPISchema(json);
|
|
529
514
|
}
|
|
530
|
-
return { baseSchemaConvertOptions, undefinedErrorJsonSchema };
|
|
531
515
|
}
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
throw error;
|
|
550
|
-
}
|
|
551
|
-
ref.parameters ??= [];
|
|
552
|
-
ref.parameters.push(...toOpenAPIParameters(pathSchema, "path"));
|
|
553
|
-
} else {
|
|
554
|
-
const error = new OpenAPIGeneratorError("Params set via path do not match those on the route");
|
|
555
|
-
if (!isObjectSchema(pathSchema)) {
|
|
556
|
-
console.log("FOO", pathSchema);
|
|
557
|
-
throw error;
|
|
558
|
-
}
|
|
559
|
-
if (!checkParamsSchema(pathSchema, [])) {
|
|
560
|
-
console.log("BAR", pathSchema);
|
|
561
|
-
throw error;
|
|
562
|
-
}
|
|
516
|
+
return { baseSchemaConvertOptions, undefinedErrorJsonSchema };
|
|
517
|
+
}
|
|
518
|
+
async function handleRequest(doc, ref, def, baseSchemaConvertOptions, converter) {
|
|
519
|
+
const method = fallbackContractConfig("defaultMethod", def.route.method);
|
|
520
|
+
const dynamicParams = getDynamicParams(def.route.path)?.map((v) => v.name);
|
|
521
|
+
const [_pathRequired, pathSchema] = await converter(def.schemas.pathSchema, {
|
|
522
|
+
...baseSchemaConvertOptions,
|
|
523
|
+
strategy: "input",
|
|
524
|
+
minStructureDepthForRef: 1
|
|
525
|
+
});
|
|
526
|
+
if (dynamicParams?.length) {
|
|
527
|
+
const error = new OpenAPIGeneratorError(
|
|
528
|
+
// TODO: fix this error
|
|
529
|
+
'When input structure is "compact", and path has dynamic params, input schema must be an object with all dynamic params as required.'
|
|
530
|
+
);
|
|
531
|
+
if (!isObjectSchema(pathSchema)) {
|
|
532
|
+
throw error;
|
|
563
533
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
strategy: "input",
|
|
567
|
-
minStructureDepthForRef: 0
|
|
568
|
-
});
|
|
569
|
-
if (!isAnySchema(querySchema)) {
|
|
570
|
-
const resolvedSchema = resolveOpenAPIJsonSchemaRef(doc, querySchema);
|
|
571
|
-
if (!isObjectSchema(resolvedSchema)) {
|
|
572
|
-
throw new OpenAPIGeneratorError("Query param schema must satisfy: object | any | unknown");
|
|
573
|
-
}
|
|
574
|
-
ref.parameters ??= [];
|
|
575
|
-
ref.parameters.push(...toOpenAPIParameters(resolvedSchema, "query"));
|
|
534
|
+
if (!checkParamsSchema(pathSchema, dynamicParams)) {
|
|
535
|
+
throw error;
|
|
576
536
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
const [bodyRequired, bodySchema] = await this.converter.convert(def.schemas.bodySchema, {
|
|
589
|
-
...baseSchemaConvertOptions,
|
|
590
|
-
strategy: "input",
|
|
591
|
-
minStructureDepthForRef: 0
|
|
592
|
-
});
|
|
593
|
-
if (isAnySchema(bodySchema)) {
|
|
594
|
-
return;
|
|
595
|
-
}
|
|
596
|
-
ref.requestBody = {
|
|
597
|
-
required: bodyRequired,
|
|
598
|
-
content: toOpenAPIContent(bodySchema)
|
|
599
|
-
};
|
|
600
|
-
}
|
|
537
|
+
ref.parameters ??= [];
|
|
538
|
+
ref.parameters.push(...toOpenAPIParameters(pathSchema, "path"));
|
|
539
|
+
} else {
|
|
540
|
+
const error = new OpenAPIGeneratorError("Params set via path do not match those on the route");
|
|
541
|
+
if (!isObjectSchema(pathSchema)) {
|
|
542
|
+
console.log("FOO", pathSchema);
|
|
543
|
+
throw error;
|
|
544
|
+
}
|
|
545
|
+
if (!checkParamsSchema(pathSchema, [])) {
|
|
546
|
+
console.log("BAR", pathSchema);
|
|
547
|
+
throw error;
|
|
601
548
|
}
|
|
602
549
|
}
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
550
|
+
const [_queryRequired, querySchema] = await converter(def.schemas.querySchema, {
|
|
551
|
+
...baseSchemaConvertOptions,
|
|
552
|
+
strategy: "input",
|
|
553
|
+
minStructureDepthForRef: 0
|
|
554
|
+
});
|
|
555
|
+
if (!isAnySchema(querySchema)) {
|
|
556
|
+
const resolvedSchema = resolveOpenAPIJsonSchemaRef(doc, querySchema);
|
|
557
|
+
if (!isObjectSchema(resolvedSchema)) {
|
|
558
|
+
throw new OpenAPIGeneratorError("Query param schema must satisfy: object | any | unknown");
|
|
559
|
+
}
|
|
560
|
+
ref.parameters ??= [];
|
|
561
|
+
ref.parameters.push(...toOpenAPIParameters(resolvedSchema, "query"));
|
|
562
|
+
}
|
|
563
|
+
if (method !== "GET") {
|
|
564
|
+
const details = getEventIteratorSchemaDetails(def.schemas.bodySchema);
|
|
565
|
+
if (details) {
|
|
566
|
+
ref.requestBody = {
|
|
567
|
+
required: true,
|
|
613
568
|
content: toOpenAPIEventIteratorContent(
|
|
614
|
-
await
|
|
615
|
-
|
|
616
|
-
strategy: "output"
|
|
617
|
-
}),
|
|
618
|
-
await this.converter.convert(eventIteratorSchemaDetails.returns, {
|
|
619
|
-
...baseSchemaConvertOptions,
|
|
620
|
-
strategy: "output"
|
|
621
|
-
})
|
|
569
|
+
await converter(details.yields, { ...baseSchemaConvertOptions, strategy: "input" }),
|
|
570
|
+
await converter(details.returns, { ...baseSchemaConvertOptions, strategy: "input" })
|
|
622
571
|
)
|
|
623
572
|
};
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
ref.
|
|
634
|
-
|
|
573
|
+
} else {
|
|
574
|
+
const [bodyRequired, bodySchema] = await converter(def.schemas.bodySchema, {
|
|
575
|
+
...baseSchemaConvertOptions,
|
|
576
|
+
strategy: "input",
|
|
577
|
+
minStructureDepthForRef: 0
|
|
578
|
+
});
|
|
579
|
+
if (isAnySchema(bodySchema)) {
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
ref.requestBody = {
|
|
583
|
+
required: bodyRequired,
|
|
584
|
+
content: toOpenAPIContent(bodySchema)
|
|
635
585
|
};
|
|
636
|
-
ref.responses[status].content = toOpenAPIContent(applySchemaOptionality(required, json));
|
|
637
|
-
return;
|
|
638
586
|
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
async function handleSuccessResponse(doc, ref, def, baseSchemaConvertOptions, converter) {
|
|
590
|
+
const outputSchema = def.schemas.outputSchema;
|
|
591
|
+
const status = fallbackContractConfig("defaultSuccessStatus", def.route.successStatus);
|
|
592
|
+
const description = fallbackContractConfig("defaultSuccessDescription", def.route?.successDescription);
|
|
593
|
+
const eventIteratorSchemaDetails = getEventIteratorSchemaDetails(outputSchema);
|
|
594
|
+
const outputStructure = fallbackContractConfig("defaultOutputStructure", def.route.outputStructure);
|
|
595
|
+
if (eventIteratorSchemaDetails) {
|
|
596
|
+
ref.responses ??= {};
|
|
597
|
+
ref.responses[status] = {
|
|
598
|
+
description,
|
|
599
|
+
content: toOpenAPIEventIteratorContent(
|
|
600
|
+
await converter(eventIteratorSchemaDetails.yields, {
|
|
601
|
+
...baseSchemaConvertOptions,
|
|
602
|
+
strategy: "output"
|
|
603
|
+
}),
|
|
604
|
+
await converter(eventIteratorSchemaDetails.returns, {
|
|
605
|
+
...baseSchemaConvertOptions,
|
|
606
|
+
strategy: "output"
|
|
607
|
+
})
|
|
608
|
+
)
|
|
609
|
+
};
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
const [required, json] = await converter(outputSchema, {
|
|
613
|
+
...baseSchemaConvertOptions,
|
|
614
|
+
strategy: "output",
|
|
615
|
+
minStructureDepthForRef: outputStructure === "detailed" ? 1 : 0
|
|
616
|
+
});
|
|
617
|
+
if (outputStructure === "compact") {
|
|
618
|
+
ref.responses ??= {};
|
|
619
|
+
ref.responses[status] = {
|
|
620
|
+
description
|
|
621
|
+
};
|
|
622
|
+
ref.responses[status].content = toOpenAPIContent(applySchemaOptionality(required, json));
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
const handledStatuses = /* @__PURE__ */ new Set();
|
|
626
|
+
for (const item of expandUnionSchema(json)) {
|
|
627
|
+
const error = new OpenAPIGeneratorError(`
|
|
628
|
+
When output structure is "detailed", output schema must satisfy:
|
|
629
|
+
{
|
|
630
|
+
status?: number, // must be a literal number and in the range of 200-399
|
|
631
|
+
headers?: Record<string, unknown>,
|
|
632
|
+
body?: unknown
|
|
633
|
+
}
|
|
648
634
|
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
635
|
+
But got: ${stringifyJSON(item)}
|
|
636
|
+
`);
|
|
637
|
+
if (!isObjectSchema(item)) {
|
|
638
|
+
throw error;
|
|
639
|
+
}
|
|
640
|
+
let schemaStatus;
|
|
641
|
+
let schemaDescription;
|
|
642
|
+
if (item.properties?.status !== void 0) {
|
|
643
|
+
const statusSchema = resolveOpenAPIJsonSchemaRef(doc, item.properties.status);
|
|
644
|
+
if (typeof statusSchema !== "object" || statusSchema.const === void 0 || typeof statusSchema.const !== "number" || !Number.isInteger(statusSchema.const) || isORPCErrorStatus(statusSchema.const)) {
|
|
652
645
|
throw error;
|
|
653
646
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
647
|
+
schemaStatus = statusSchema.const;
|
|
648
|
+
schemaDescription = statusSchema.description;
|
|
649
|
+
}
|
|
650
|
+
const itemStatus = schemaStatus ?? status;
|
|
651
|
+
const itemDescription = schemaDescription ?? description;
|
|
652
|
+
if (handledStatuses.has(itemStatus)) {
|
|
653
|
+
throw new OpenAPIGeneratorError(`
|
|
654
|
+
When output structure is "detailed", each success status must be unique.
|
|
655
|
+
But got status: ${itemStatus} used more than once.
|
|
656
|
+
`);
|
|
657
|
+
}
|
|
658
|
+
handledStatuses.add(itemStatus);
|
|
659
|
+
ref.responses ??= {};
|
|
660
|
+
ref.responses[itemStatus] = {
|
|
661
|
+
description: itemDescription
|
|
662
|
+
};
|
|
663
|
+
if (item.properties?.headers !== void 0) {
|
|
664
|
+
const headersSchema = resolveOpenAPIJsonSchemaRef(doc, item.properties.headers);
|
|
665
|
+
if (!isObjectSchema(headersSchema)) {
|
|
666
|
+
throw error;
|
|
671
667
|
}
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
throw error;
|
|
681
|
-
}
|
|
682
|
-
for (const key in headersSchema.properties) {
|
|
683
|
-
const headerSchema = headersSchema.properties[key];
|
|
684
|
-
if (headerSchema !== void 0) {
|
|
685
|
-
ref.responses[itemStatus].headers ??= {};
|
|
686
|
-
ref.responses[itemStatus].headers[key] = {
|
|
687
|
-
schema: toOpenAPISchema(headerSchema),
|
|
688
|
-
required: item.required?.includes("headers") && headersSchema.required?.includes(key)
|
|
689
|
-
};
|
|
690
|
-
}
|
|
668
|
+
for (const key in headersSchema.properties) {
|
|
669
|
+
const headerSchema = headersSchema.properties[key];
|
|
670
|
+
if (headerSchema !== void 0) {
|
|
671
|
+
ref.responses[itemStatus].headers ??= {};
|
|
672
|
+
ref.responses[itemStatus].headers[key] = {
|
|
673
|
+
schema: toOpenAPISchema(headerSchema),
|
|
674
|
+
required: item.required?.includes("headers") && headersSchema.required?.includes(key)
|
|
675
|
+
};
|
|
691
676
|
}
|
|
692
677
|
}
|
|
693
|
-
if (item.properties?.body !== void 0) {
|
|
694
|
-
ref.responses[itemStatus].content = toOpenAPIContent(
|
|
695
|
-
applySchemaOptionality(item.required?.includes("body") ?? false, item.properties.body)
|
|
696
|
-
);
|
|
697
|
-
}
|
|
698
678
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
for (const code in errorMap) {
|
|
704
|
-
const config = errorMap[code];
|
|
705
|
-
if (!config) {
|
|
706
|
-
continue;
|
|
707
|
-
}
|
|
708
|
-
const status = fallbackORPCErrorStatus(code, config.status);
|
|
709
|
-
const message = fallbackORPCErrorMessage(code, config.message);
|
|
710
|
-
const [dataRequired, dataSchema] = await this.converter.convert(config.data, {
|
|
711
|
-
...baseSchemaConvertOptions,
|
|
712
|
-
strategy: "output"
|
|
713
|
-
});
|
|
714
|
-
errors[status] ??= [];
|
|
715
|
-
errors[status].push({
|
|
716
|
-
type: "object",
|
|
717
|
-
properties: {
|
|
718
|
-
defined: { const: true },
|
|
719
|
-
code: { const: code },
|
|
720
|
-
status: { const: status },
|
|
721
|
-
message: { type: "string", default: message },
|
|
722
|
-
data: dataSchema
|
|
723
|
-
},
|
|
724
|
-
required: dataRequired ? ["defined", "code", "status", "message", "data"] : ["defined", "code", "status", "message"]
|
|
725
|
-
});
|
|
726
|
-
}
|
|
727
|
-
ref.responses ??= {};
|
|
728
|
-
for (const status in errors) {
|
|
729
|
-
const schemas = errors[status];
|
|
730
|
-
ref.responses[status] = {
|
|
731
|
-
description: status,
|
|
732
|
-
content: toOpenAPIContent({
|
|
733
|
-
oneOf: [...schemas, undefinedErrorSchema]
|
|
734
|
-
})
|
|
735
|
-
};
|
|
679
|
+
if (item.properties?.body !== void 0) {
|
|
680
|
+
ref.responses[itemStatus].content = toOpenAPIContent(
|
|
681
|
+
applySchemaOptionality(item.required?.includes("body") ?? false, item.properties.body)
|
|
682
|
+
);
|
|
736
683
|
}
|
|
737
684
|
}
|
|
738
685
|
}
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
686
|
+
function authConfigToSecurityScheme(authConfig) {
|
|
687
|
+
switch (authConfig.type) {
|
|
688
|
+
case "basic":
|
|
689
|
+
return {
|
|
690
|
+
type: "http",
|
|
691
|
+
scheme: "basic",
|
|
692
|
+
description: authConfig.oasDescription
|
|
693
|
+
};
|
|
694
|
+
case "bearer":
|
|
695
|
+
return {
|
|
696
|
+
type: "http",
|
|
697
|
+
scheme: "bearer",
|
|
698
|
+
description: authConfig.oasDescription,
|
|
699
|
+
bearerFormat: authConfig.oasBearerFormat
|
|
700
|
+
};
|
|
701
|
+
case "header":
|
|
702
|
+
return {
|
|
703
|
+
type: "apiKey",
|
|
704
|
+
in: "header",
|
|
705
|
+
name: authConfig.name,
|
|
706
|
+
description: authConfig.oasDescription
|
|
707
|
+
};
|
|
708
|
+
case "query":
|
|
709
|
+
return {
|
|
710
|
+
type: "apiKey",
|
|
711
|
+
in: "query",
|
|
712
|
+
name: authConfig.name,
|
|
713
|
+
description: authConfig.oasDescription
|
|
714
|
+
};
|
|
715
|
+
case "cookie":
|
|
716
|
+
return {
|
|
717
|
+
type: "apiKey",
|
|
718
|
+
in: "cookie",
|
|
719
|
+
name: authConfig.name,
|
|
720
|
+
description: authConfig.oasDescription
|
|
721
|
+
};
|
|
722
|
+
default:
|
|
723
|
+
assertNever(authConfig, `Unsupported auth config type: ${authConfig.type}`);
|
|
724
|
+
}
|
|
754
725
|
}
|
|
755
726
|
|
|
756
727
|
const oo = {
|
|
757
728
|
spec: customOpenAPIOperation
|
|
758
729
|
};
|
|
759
730
|
|
|
760
|
-
export {
|
|
731
|
+
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 };
|