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