@temporary-name/server 1.9.3-alpha.e2d8d164da72fb570c2b14a4fa956c80f9e33cdc → 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.
Files changed (44) hide show
  1. package/dist/adapters/aws-lambda/index.d.mts +4 -6
  2. package/dist/adapters/aws-lambda/index.d.ts +4 -6
  3. package/dist/adapters/aws-lambda/index.mjs +4 -4
  4. package/dist/adapters/fetch/index.d.mts +8 -86
  5. package/dist/adapters/fetch/index.d.ts +8 -86
  6. package/dist/adapters/fetch/index.mjs +16 -155
  7. package/dist/adapters/node/index.d.mts +8 -63
  8. package/dist/adapters/node/index.d.ts +8 -63
  9. package/dist/adapters/node/index.mjs +14 -120
  10. package/dist/adapters/standard/index.d.mts +10 -7
  11. package/dist/adapters/standard/index.d.ts +10 -7
  12. package/dist/adapters/standard/index.mjs +4 -4
  13. package/dist/helpers/index.mjs +3 -29
  14. package/dist/index.d.mts +376 -242
  15. package/dist/index.d.ts +376 -242
  16. package/dist/index.mjs +482 -359
  17. package/dist/openapi/index.d.mts +18 -53
  18. package/dist/openapi/index.d.ts +18 -53
  19. package/dist/openapi/index.mjs +337 -347
  20. package/dist/shared/server.BCY45g2x.mjs +160 -0
  21. package/dist/shared/server.BETu17rq.mjs +319 -0
  22. package/dist/shared/server.B_oW_rPl.mjs +525 -0
  23. package/dist/shared/server.C1RJffw4.mjs +30 -0
  24. package/dist/shared/server.CQIFwyhc.mjs +40 -0
  25. package/dist/shared/server.CjPiuQYH.d.mts +51 -0
  26. package/dist/shared/server.CjPiuQYH.d.ts +51 -0
  27. package/dist/shared/server.Cq7SBLD5.mjs +403 -0
  28. package/dist/shared/server.DGH2Bq4t.d.mts +41 -0
  29. package/dist/shared/server.nQoUObAJ.d.ts +41 -0
  30. package/dist/shared/server.zsKBRxsz.d.mts +388 -0
  31. package/dist/shared/server.zsKBRxsz.d.ts +388 -0
  32. package/package.json +10 -28
  33. package/dist/plugins/index.d.mts +0 -160
  34. package/dist/plugins/index.d.ts +0 -160
  35. package/dist/plugins/index.mjs +0 -288
  36. package/dist/shared/server.B93y_8tj.d.mts +0 -23
  37. package/dist/shared/server.BYYf0Wn6.mjs +0 -202
  38. package/dist/shared/server.C3RuMHWl.d.mts +0 -192
  39. package/dist/shared/server.C3RuMHWl.d.ts +0 -192
  40. package/dist/shared/server.CT1xhSmE.d.mts +0 -56
  41. package/dist/shared/server.CqTex_jI.mjs +0 -265
  42. package/dist/shared/server.D_fags8X.d.ts +0 -23
  43. package/dist/shared/server.Kxw442A9.mjs +0 -247
  44. package/dist/shared/server.cjcgLdr1.d.ts +0 -56
@@ -1,10 +1,13 @@
1
- import { isProcedure, resolveContractProcedures, ORPCError, createRouterClient } from '@temporary-name/server';
2
- import { fallbackContractConfig, getEventIteratorSchemaDetails } from '@temporary-name/contract';
3
- import { isObject, stringifyJSON, findDeepMatches, toArray, clone, value, toHttpPath, isORPCErrorStatus, fallbackORPCErrorStatus, fallbackORPCErrorMessage, resolveMaybeOptionalOptions, createORPCErrorFromJson } from '@temporary-name/shared';
4
- import { a as standardizeHTTPPath, j as jsonSerialize, g as getDynamicParams, d as deserialize, s as serialize } from '../shared/server.Kxw442A9.mjs';
1
+ import { isObject, stringifyJSON, findDeepMatches, clone, value, fallbackContractConfig, toHttpPath, assertNever, isORPCErrorStatus } from '@temporary-name/shared';
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.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
+ 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) {
@@ -22,20 +25,12 @@ function getCustomOpenAPIOperation(o) {
22
25
  }
23
26
  function applyCustomOpenAPIOperation(operation, contract) {
24
27
  const operationCustoms = [];
25
- for (const errorItem of Object.values(contract["~orpc"].errorMap)) {
26
- const maybeExtender = errorItem ? getCustomOpenAPIOperation(errorItem) : void 0;
28
+ for (const middleware of contract["~orpc"].middlewares) {
29
+ const maybeExtender = getCustomOpenAPIOperation(middleware);
27
30
  if (maybeExtender) {
28
31
  operationCustoms.push(maybeExtender);
29
32
  }
30
33
  }
31
- if (isProcedure(contract)) {
32
- for (const middleware of contract["~orpc"].middlewares) {
33
- const maybeExtender = getCustomOpenAPIOperation(middleware);
34
- if (maybeExtender) {
35
- operationCustoms.push(maybeExtender);
36
- }
37
- }
38
- }
39
34
  let currentOperation = operation;
40
35
  for (const custom of operationCustoms) {
41
36
  if (typeof custom === "function") {
@@ -362,381 +357,376 @@ function resolveOpenAPIJsonSchemaRef(doc, schema) {
362
357
  return resolved ?? schema;
363
358
  }
364
359
 
365
- class CompositeSchemaConverter {
366
- converters;
367
- constructor(converters) {
368
- this.converters = converters;
369
- }
370
- async convert(schema, options) {
371
- for (const converter of this.converters) {
372
- if (await converter.condition(schema, options)) {
373
- 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;
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}`;
374
391
  }
392
+ namesByAuthConfig.set(authConfig, oasName);
393
+ authConfigNames.add(oasName);
375
394
  }
376
- return [false, {}];
377
395
  }
378
- }
379
-
380
- class OpenAPIGeneratorError extends Error {
381
- }
382
- class OpenAPIGenerator {
383
- converter;
384
- constructor(options = {}) {
385
- 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
+ }
386
402
  }
387
- /**
388
- * Generates OpenAPI specifications from oRPC routers/contracts.
389
- *
390
- * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
391
- */
392
- async generate(router, options = {}) {
393
- const filter = options.filter ?? (({ contract, path }) => {
394
- return !(options.exclude?.(contract, path) ?? false);
395
- });
396
- const doc = {
397
- ...clone(options),
398
- info: options.info ?? { title: "API Reference", version: "0.0.0" },
399
- openapi: "3.1.1",
400
- exclude: void 0,
401
- filter: void 0,
402
- commonSchemas: void 0
403
- };
404
- const { baseSchemaConvertOptions, undefinedErrorJsonSchema } = await this.#resolveCommonSchemas(
405
- doc,
406
- options.commonSchemas
407
- );
408
- const contracts = [];
409
- await resolveContractProcedures({ path: [], router }, (traverseOptions) => {
410
- if (!value(filter, traverseOptions)) {
411
- return;
412
- }
413
- contracts.push(traverseOptions);
414
- });
415
- const errors = [];
416
- for (const { contract, path } of contracts) {
417
- const stringPath = path.join(".");
418
- try {
419
- const def = contract["~orpc"];
420
- const method = toOpenAPIMethod(fallbackContractConfig("defaultMethod", def.route.method));
421
- const httpPath = toOpenAPIPath(def.route.path ?? toHttpPath(path));
422
- let operationObjectRef;
423
- if (def.route.spec !== void 0 && typeof def.route.spec !== "function") {
424
- operationObjectRef = def.route.spec;
425
- } else {
426
- operationObjectRef = {
427
- operationId: def.route.operationId ?? stringPath,
428
- summary: def.route.summary,
429
- description: def.route.description,
430
- deprecated: def.route.deprecated,
431
- tags: def.route.tags?.map((tag) => tag)
432
- };
433
- await this.#request(doc, operationObjectRef, def, baseSchemaConvertOptions);
434
- await this.#successResponse(doc, operationObjectRef, def, baseSchemaConvertOptions);
435
- await this.#errorResponse(
436
- operationObjectRef,
437
- def,
438
- baseSchemaConvertOptions,
439
- undefinedErrorJsonSchema
440
- );
441
- }
442
- if (typeof def.route.spec === "function") {
443
- operationObjectRef = def.route.spec(operationObjectRef);
444
- }
445
- doc.paths ??= {};
446
- doc.paths[httpPath] ??= {};
447
- doc.paths[httpPath][method] = applyCustomOpenAPIOperation(operationObjectRef, contract);
448
- } catch (e) {
449
- if (!(e instanceof OpenAPIGeneratorError)) {
450
- throw e;
451
- }
452
- errors.push(
453
- `[OpenAPIGenerator] Error occurred while generating OpenAPI for procedure at path: ${stringPath}
454
- ${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)]: [] }
455
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);
456
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;
439
+ }
440
+ errors.push(
441
+ `[OpenAPIGenerator] Error occurred while generating OpenAPI for procedure at path: ${stringPath}
442
+ ${e.message}`
443
+ );
457
444
  }
458
- if (errors.length) {
459
- throw new OpenAPIGeneratorError(
460
- `Some error occurred during OpenAPI generation:
445
+ }
446
+ if (errors.length) {
447
+ throw new OpenAPIGeneratorError(
448
+ `Some error occurred during OpenAPI generation:
461
449
 
462
450
  ${errors.join("\n\n")}`
463
- );
464
- }
465
- return jsonSerialize(doc)[0];
451
+ );
466
452
  }
467
- async #resolveCommonSchemas(doc, commonSchemas) {
468
- let undefinedErrorJsonSchema = {
469
- type: "object",
470
- properties: {
471
- defined: { const: false },
472
- code: { type: "string" },
473
- status: { type: "number" },
474
- message: { type: "string" },
475
- data: {}
476
- },
477
- required: ["defined", "code", "status", "message"]
478
- };
479
- const baseSchemaConvertOptions = {};
480
- if (commonSchemas) {
481
- baseSchemaConvertOptions.components = [];
482
- for (const key in commonSchemas) {
483
- const options = commonSchemas[key];
484
- if (options.schema === void 0) {
485
- 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");
486
482
  }
487
- const { schema, strategy = "input" } = options;
488
- const [required, json] = await this.converter.convert(schema, { strategy });
489
- const allowedStrategies = [strategy];
490
- if (strategy === "input") {
491
- const [outputRequired, outputJson] = await this.converter.convert(schema, { strategy: "output" });
492
- if (outputRequired === required && stringifyJSON(outputJson) === stringifyJSON(json)) {
493
- allowedStrategies.push("output");
494
- }
495
- } else if (strategy === "output") {
496
- const [inputRequired, inputJson] = await this.converter.convert(schema, { strategy: "input" });
497
- if (inputRequired === required && stringifyJSON(inputJson) === stringifyJSON(json)) {
498
- allowedStrategies.push("input");
499
- }
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");
500
487
  }
501
- baseSchemaConvertOptions.components.push({
502
- schema,
503
- required,
504
- ref: `#/components/schemas/${key}`,
505
- allowedStrategies
506
- });
507
488
  }
508
- doc.components ??= {};
509
- doc.components.schemas ??= {};
510
- for (const key in commonSchemas) {
511
- const options = commonSchemas[key];
512
- if (options.schema === void 0) {
513
- if (options.error === "UndefinedError") {
514
- doc.components.schemas[key] = toOpenAPISchema(undefinedErrorJsonSchema);
515
- undefinedErrorJsonSchema = { $ref: `#/components/schemas/${key}` };
516
- }
517
- 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}` };
518
504
  }
519
- const { schema, strategy = "input" } = options;
520
- const [, json] = await this.converter.convert(schema, {
521
- ...baseSchemaConvertOptions,
522
- strategy,
523
- minStructureDepthForRef: 1
524
- // not allow use $ref for root schemas
525
- });
526
- doc.components.schemas[key] = toOpenAPISchema(json);
505
+ continue;
527
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);
515
+ }
516
+ }
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;
534
+ }
535
+ if (!checkParamsSchema(pathSchema, dynamicParams)) {
536
+ throw error;
537
+ }
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;
528
549
  }
529
- return { baseSchemaConvertOptions, undefinedErrorJsonSchema };
530
550
  }
531
- async #request(doc, ref, def, baseSchemaConvertOptions) {
532
- const method = fallbackContractConfig("defaultMethod", def.route.method);
533
- const details = getEventIteratorSchemaDetails(def.inputSchema);
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");
560
+ }
561
+ ref.parameters ??= [];
562
+ ref.parameters.push(...toOpenAPIParameters(resolvedSchema, "query"));
563
+ }
564
+ if (method !== "GET") {
565
+ const details = getEventIteratorSchemaDetails(def.schemas.bodySchema);
534
566
  if (details) {
535
567
  ref.requestBody = {
536
568
  required: true,
537
569
  content: toOpenAPIEventIteratorContent(
538
- await this.converter.convert(details.yields, { ...baseSchemaConvertOptions, strategy: "input" }),
539
- await this.converter.convert(details.returns, { ...baseSchemaConvertOptions, strategy: "input" })
570
+ await converter(details.yields, { ...baseSchemaConvertOptions, strategy: "input" }),
571
+ await converter(details.returns, { ...baseSchemaConvertOptions, strategy: "input" })
540
572
  )
541
573
  };
542
- return;
543
- }
544
- const dynamicParams = getDynamicParams(def.route.path)?.map((v) => v.name);
545
- let [required, schema] = await this.converter.convert(def.inputSchema, {
546
- ...baseSchemaConvertOptions,
547
- strategy: "input",
548
- minStructureDepthForRef: dynamicParams?.length ? 1 : 0
549
- });
550
- if (isAnySchema(schema) && !dynamicParams?.length) {
551
- return;
552
- }
553
- if (dynamicParams?.length) {
554
- const error = new OpenAPIGeneratorError(
555
- 'When input structure is "compact", and path has dynamic params, input schema must be an object with all dynamic params as required.'
556
- );
557
- if (!isObjectSchema(schema)) {
558
- throw error;
559
- }
560
- const [paramsSchema, rest] = separateObjectSchema(schema, dynamicParams);
561
- schema = rest;
562
- required = rest.required ? rest.required.length !== 0 : false;
563
- if (!checkParamsSchema(paramsSchema, dynamicParams)) {
564
- throw error;
565
- }
566
- ref.parameters ??= [];
567
- ref.parameters.push(...toOpenAPIParameters(paramsSchema, "path"));
568
- }
569
- if (method === "GET") {
570
- const resolvedSchema = resolveOpenAPIJsonSchemaRef(doc, schema);
571
- if (!isObjectSchema(resolvedSchema)) {
572
- throw new OpenAPIGeneratorError(
573
- 'When method is "GET", input schema must satisfy: object | any | unknown'
574
- );
575
- }
576
- ref.parameters ??= [];
577
- ref.parameters.push(...toOpenAPIParameters(resolvedSchema, "query"));
578
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
+ }
579
583
  ref.requestBody = {
580
- required,
581
- content: toOpenAPIContent(schema)
584
+ required: bodyRequired,
585
+ content: toOpenAPIContent(bodySchema)
582
586
  };
583
587
  }
584
588
  }
585
- async #successResponse(doc, ref, def, baseSchemaConvertOptions) {
586
- const outputSchema = def.outputSchema;
587
- const status = fallbackContractConfig("defaultSuccessStatus", def.route.successStatus);
588
- const description = fallbackContractConfig("defaultSuccessDescription", def.route?.successDescription);
589
- const eventIteratorSchemaDetails = getEventIteratorSchemaDetails(outputSchema);
590
- const outputStructure = fallbackContractConfig("defaultOutputStructure", def.route.outputStructure);
591
- if (eventIteratorSchemaDetails) {
592
- ref.responses ??= {};
593
- ref.responses[status] = {
594
- description,
595
- content: toOpenAPIEventIteratorContent(
596
- await this.converter.convert(eventIteratorSchemaDetails.yields, {
597
- ...baseSchemaConvertOptions,
598
- strategy: "output"
599
- }),
600
- await this.converter.convert(eventIteratorSchemaDetails.returns, {
601
- ...baseSchemaConvertOptions,
602
- strategy: "output"
603
- })
604
- )
605
- };
606
- return;
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
+ }
635
+
636
+ But got: ${stringifyJSON(item)}
637
+ `);
638
+ if (!isObjectSchema(item)) {
639
+ throw error;
607
640
  }
608
- const [required, json] = await this.converter.convert(outputSchema, {
609
- ...baseSchemaConvertOptions,
610
- strategy: "output",
611
- minStructureDepthForRef: outputStructure === "detailed" ? 1 : 0
612
- });
613
- if (outputStructure === "compact") {
614
- ref.responses ??= {};
615
- ref.responses[status] = {
616
- description
617
- };
618
- ref.responses[status].content = toOpenAPIContent(applySchemaOptionality(required, json));
619
- return;
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)) {
646
+ throw error;
647
+ }
648
+ schemaStatus = statusSchema.const;
649
+ schemaDescription = statusSchema.description;
620
650
  }
621
- const handledStatuses = /* @__PURE__ */ new Set();
622
- for (const item of expandUnionSchema(json)) {
623
- const error = new OpenAPIGeneratorError(`
624
- When output structure is "detailed", output schema must satisfy:
625
- {
626
- status?: number, // must be a literal number and in the range of 200-399
627
- headers?: Record<string, unknown>,
628
- body?: unknown
629
- }
630
-
631
- But got: ${stringifyJSON(item)}
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.
632
657
  `);
633
- if (!isObjectSchema(item)) {
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)) {
634
667
  throw error;
635
668
  }
636
- let schemaStatus;
637
- let schemaDescription;
638
- if (item.properties?.status !== void 0) {
639
- const statusSchema = resolveOpenAPIJsonSchemaRef(doc, item.properties.status);
640
- if (typeof statusSchema !== "object" || statusSchema.const === void 0 || typeof statusSchema.const !== "number" || !Number.isInteger(statusSchema.const) || isORPCErrorStatus(statusSchema.const)) {
641
- throw error;
642
- }
643
- schemaStatus = statusSchema.const;
644
- schemaDescription = statusSchema.description;
645
- }
646
- const itemStatus = schemaStatus ?? status;
647
- const itemDescription = schemaDescription ?? description;
648
- if (handledStatuses.has(itemStatus)) {
649
- throw new OpenAPIGeneratorError(`
650
- When output structure is "detailed", each success status must be unique.
651
- But got status: ${itemStatus} used more than once.
652
- `);
653
- }
654
- handledStatuses.add(itemStatus);
655
- ref.responses ??= {};
656
- ref.responses[itemStatus] = {
657
- description: itemDescription
658
- };
659
- if (item.properties?.headers !== void 0) {
660
- const headersSchema = resolveOpenAPIJsonSchemaRef(doc, item.properties.headers);
661
- if (!isObjectSchema(headersSchema)) {
662
- throw error;
663
- }
664
- for (const key in headersSchema.properties) {
665
- const headerSchema = headersSchema.properties[key];
666
- if (headerSchema !== void 0) {
667
- ref.responses[itemStatus].headers ??= {};
668
- ref.responses[itemStatus].headers[key] = {
669
- schema: toOpenAPISchema(headerSchema),
670
- required: item.required?.includes("headers") && headersSchema.required?.includes(key)
671
- };
672
- }
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
+ };
673
677
  }
674
678
  }
675
- if (item.properties?.body !== void 0) {
676
- ref.responses[itemStatus].content = toOpenAPIContent(
677
- applySchemaOptionality(item.required?.includes("body") ?? false, item.properties.body)
678
- );
679
- }
680
- }
681
- }
682
- async #errorResponse(ref, def, baseSchemaConvertOptions, undefinedErrorSchema) {
683
- const errorMap = def.errorMap;
684
- const errors = {};
685
- for (const code in errorMap) {
686
- const config = errorMap[code];
687
- if (!config) {
688
- continue;
689
- }
690
- const status = fallbackORPCErrorStatus(code, config.status);
691
- const message = fallbackORPCErrorMessage(code, config.message);
692
- const [dataRequired, dataSchema] = await this.converter.convert(config.data, {
693
- ...baseSchemaConvertOptions,
694
- strategy: "output"
695
- });
696
- errors[status] ??= [];
697
- errors[status].push({
698
- type: "object",
699
- properties: {
700
- defined: { const: true },
701
- code: { const: code },
702
- status: { const: status },
703
- message: { type: "string", default: message },
704
- data: dataSchema
705
- },
706
- required: dataRequired ? ["defined", "code", "status", "message", "data"] : ["defined", "code", "status", "message"]
707
- });
708
679
  }
709
- ref.responses ??= {};
710
- for (const status in errors) {
711
- const schemas = errors[status];
712
- ref.responses[status] = {
713
- description: status,
714
- content: toOpenAPIContent({
715
- oneOf: [...schemas, undefinedErrorSchema]
716
- })
717
- };
680
+ if (item.properties?.body !== void 0) {
681
+ ref.responses[itemStatus].content = toOpenAPIContent(
682
+ applySchemaOptionality(item.required?.includes("body") ?? false, item.properties.body)
683
+ );
718
684
  }
719
685
  }
720
686
  }
721
-
722
- function createJsonifiedRouterClient(router, ...rest) {
723
- const options = resolveMaybeOptionalOptions(rest);
724
- options.interceptors ??= [];
725
- options.interceptors.unshift(async (options2) => {
726
- try {
727
- return deserialize(serialize(await options2.next()));
728
- } catch (e) {
729
- if (e instanceof ORPCError) {
730
- throw createORPCErrorFromJson(deserialize(serialize(e.toJSON(), { outputFormat: "plain" })));
731
- }
732
- throw e;
733
- }
734
- });
735
- return createRouterClient(router, options);
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}`);
725
+ }
736
726
  }
737
727
 
738
728
  const oo = {
739
729
  spec: customOpenAPIOperation
740
730
  };
741
731
 
742
- export { CompositeSchemaConverter, LOGIC_KEYWORDS, OpenAPIGenerator, applyCustomOpenAPIOperation, applySchemaOptionality, checkParamsSchema, createJsonifiedRouterClient, 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 };