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