@temporary-name/server 1.9.3-alpha.f9f5ce625d5edee78250b87b3a64f1d9760c2244 → 1.9.3-alpha.fb7b7d19964e1b2def7056f4345b63d6fcacce10

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 (42) hide show
  1. package/dist/adapters/aws-lambda/index.d.mts +4 -5
  2. package/dist/adapters/aws-lambda/index.d.ts +4 -5
  3. package/dist/adapters/aws-lambda/index.mjs +4 -4
  4. package/dist/adapters/fetch/index.d.mts +8 -85
  5. package/dist/adapters/fetch/index.d.ts +8 -85
  6. package/dist/adapters/fetch/index.mjs +16 -155
  7. package/dist/adapters/node/index.d.mts +8 -62
  8. package/dist/adapters/node/index.d.ts +8 -62
  9. package/dist/adapters/node/index.mjs +14 -120
  10. package/dist/adapters/standard/index.d.mts +5 -6
  11. package/dist/adapters/standard/index.d.ts +5 -6
  12. package/dist/adapters/standard/index.mjs +4 -4
  13. package/dist/helpers/index.mjs +3 -29
  14. package/dist/index.d.mts +110 -199
  15. package/dist/index.d.ts +110 -199
  16. package/dist/index.mjs +144 -153
  17. package/dist/openapi/index.d.mts +17 -53
  18. package/dist/openapi/index.d.ts +17 -53
  19. package/dist/openapi/index.mjs +339 -367
  20. package/dist/shared/server.B0LJ_wu-.d.ts +41 -0
  21. package/dist/shared/server.BQZMQrPe.d.mts +41 -0
  22. package/dist/shared/server.C1RJffw4.mjs +30 -0
  23. package/dist/shared/server.CQIFwyhc.mjs +40 -0
  24. package/dist/shared/server.CYa9puL2.mjs +403 -0
  25. package/dist/shared/server.ChOv1yG3.mjs +319 -0
  26. package/dist/shared/server.Cza0RB3u.mjs +160 -0
  27. package/dist/shared/server.DXPMDozZ.d.mts +388 -0
  28. package/dist/shared/server.DXPMDozZ.d.ts +388 -0
  29. package/dist/shared/server.YUvuxHty.mjs +48 -0
  30. package/package.json +11 -28
  31. package/dist/plugins/index.d.mts +0 -84
  32. package/dist/plugins/index.d.ts +0 -84
  33. package/dist/plugins/index.mjs +0 -122
  34. package/dist/shared/server.7aL9gcoU.d.mts +0 -23
  35. package/dist/shared/server.BL2R5jcp.d.mts +0 -228
  36. package/dist/shared/server.BL2R5jcp.d.ts +0 -228
  37. package/dist/shared/server.CVBLzkro.mjs +0 -255
  38. package/dist/shared/server.ClhVCxfg.mjs +0 -413
  39. package/dist/shared/server.D6Qs_UcF.d.mts +0 -55
  40. package/dist/shared/server.DFptr1Nz.d.ts +0 -23
  41. package/dist/shared/server.DpoO_ER_.d.ts +0 -55
  42. package/dist/shared/server.JtIZ8YG7.mjs +0 -237
@@ -1,10 +1,12 @@
1
- import { isProcedure, resolveContractProcedures, ORPCError, createRouterClient } from '@temporary-name/server';
2
- import { standardizeHTTPPath, fallbackContractConfig, getDynamicParams, 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 { j as jsonSerialize, d as deserialize, s as serialize } from '../shared/server.JtIZ8YG7.mjs';
1
+ import { ZodToJsonSchemaConverter } from '@temporary-name/json-schema';
2
+ import { isObject, stringifyJSON, findDeepMatches, clone, value, fallbackContractConfig, toHttpPath, assertNever, isORPCErrorStatus } from '@temporary-name/shared';
3
+ import { j as jsonSerialize } from '../shared/server.CQIFwyhc.mjs';
5
4
  import '@temporary-name/standard-server';
5
+ import { g as getEventIteratorSchemaDetails } from '../shared/server.YUvuxHty.mjs';
6
+ import { s as standardizeHTTPPath, r as resolveContractProcedures, g as getDynamicParams } from '../shared/server.ChOv1yG3.mjs';
6
7
  import { TypeName } from '@temporary-name/interop/json-schema-typed/draft-2020-12';
7
8
  export { ContentEncoding as JSONSchemaContentEncoding, Format as JSONSchemaFormat, TypeName as JSONSchemaTypeName } from '@temporary-name/interop/json-schema-typed/draft-2020-12';
9
+ import '@temporary-name/zod';
8
10
 
9
11
  const OPERATION_EXTENDER_SYMBOL = Symbol("ORPC_OPERATION_EXTENDER");
10
12
  function customOpenAPIOperation(o, extend) {
@@ -22,20 +24,12 @@ function getCustomOpenAPIOperation(o) {
22
24
  }
23
25
  function applyCustomOpenAPIOperation(operation, contract) {
24
26
  const operationCustoms = [];
25
- for (const errorItem of Object.values(contract["~orpc"].errorMap)) {
26
- const maybeExtender = errorItem ? getCustomOpenAPIOperation(errorItem) : void 0;
27
+ for (const middleware of contract["~orpc"].middlewares) {
28
+ const maybeExtender = getCustomOpenAPIOperation(middleware);
27
29
  if (maybeExtender) {
28
30
  operationCustoms.push(maybeExtender);
29
31
  }
30
32
  }
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
33
  let currentOperation = operation;
40
34
  for (const custom of operationCustoms) {
41
35
  if (typeof custom === "function") {
@@ -362,398 +356,376 @@ function resolveOpenAPIJsonSchemaRef(doc, schema) {
362
356
  return resolved ?? schema;
363
357
  }
364
358
 
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);
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}`;
374
390
  }
391
+ namesByAuthConfig.set(authConfig, oasName);
392
+ authConfigNames.add(oasName);
375
393
  }
376
- return [false, {}];
377
394
  }
378
- }
379
-
380
- class OpenAPIGeneratorError extends Error {
381
- }
382
- class OpenAPIGenerator {
383
- converter;
384
- constructor(options = {}) {
385
- 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
+ }
386
401
  }
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}`
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)]: [] }
455
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);
456
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;
438
+ }
439
+ errors.push(
440
+ `[OpenAPIGenerator] Error occurred while generating OpenAPI for procedure at path: ${stringPath}
441
+ ${e.message}`
442
+ );
457
443
  }
458
- if (errors.length) {
459
- throw new OpenAPIGeneratorError(
460
- `Some error occurred during OpenAPI generation:
444
+ }
445
+ if (errors.length) {
446
+ throw new OpenAPIGeneratorError(
447
+ `Some error occurred during OpenAPI generation:
461
448
 
462
449
  ${errors.join("\n\n")}`
463
- );
464
- }
465
- return jsonSerialize(doc)[0];
450
+ );
466
451
  }
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;
452
+ return jsonSerialize(doc)[0];
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");
486
481
  }
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
- }
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");
500
486
  }
501
- baseSchemaConvertOptions.components.push({
502
- schema,
503
- required,
504
- ref: `#/components/schemas/${key}`,
505
- allowedStrategies
506
- });
507
487
  }
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;
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}` };
518
503
  }
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);
504
+ continue;
527
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);
528
514
  }
529
- return { baseSchemaConvertOptions, undefinedErrorJsonSchema };
530
515
  }
531
- async #request(doc, ref, def, baseSchemaConvertOptions) {
532
- const method = fallbackContractConfig("defaultMethod", def.route.method);
533
- const dynamicParams = getDynamicParams(def.route.path)?.map((v) => v.name);
534
- const [_pathRequired, pathSchema] = await this.converter.convert(def.schemas.pathSchema, {
535
- ...baseSchemaConvertOptions,
536
- strategy: "input",
537
- minStructureDepthForRef: 1
538
- });
539
- if (dynamicParams?.length) {
540
- const error = new OpenAPIGeneratorError(
541
- // TODO: fix this error
542
- 'When input structure is "compact", and path has dynamic params, input schema must be an object with all dynamic params as required.'
543
- );
544
- if (!isObjectSchema(pathSchema)) {
545
- throw error;
546
- }
547
- if (!checkParamsSchema(pathSchema, dynamicParams)) {
548
- throw error;
549
- }
550
- ref.parameters ??= [];
551
- ref.parameters.push(...toOpenAPIParameters(pathSchema, "path"));
552
- } else {
553
- const error = new OpenAPIGeneratorError("Params set via path do not match those on the route");
554
- if (!isObjectSchema(pathSchema)) {
555
- console.log("FOO", pathSchema);
556
- throw error;
557
- }
558
- if (!checkParamsSchema(pathSchema, [])) {
559
- console.log("BAR", pathSchema);
560
- throw error;
561
- }
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;
562
533
  }
563
- const [_queryRequired, querySchema] = await this.converter.convert(def.schemas.querySchema, {
564
- ...baseSchemaConvertOptions,
565
- strategy: "input",
566
- minStructureDepthForRef: 0
567
- });
568
- if (!isAnySchema(querySchema)) {
569
- const resolvedSchema = resolveOpenAPIJsonSchemaRef(doc, querySchema);
570
- if (!isObjectSchema(resolvedSchema)) {
571
- throw new OpenAPIGeneratorError("Query param schema must satisfy: object | any | unknown");
572
- }
573
- ref.parameters ??= [];
574
- ref.parameters.push(...toOpenAPIParameters(resolvedSchema, "query"));
534
+ if (!checkParamsSchema(pathSchema, dynamicParams)) {
535
+ throw error;
575
536
  }
576
- if (method !== "GET") {
577
- const details = getEventIteratorSchemaDetails(def.schemas.bodySchema);
578
- if (details) {
579
- ref.requestBody = {
580
- required: true,
581
- content: toOpenAPIEventIteratorContent(
582
- await this.converter.convert(details.yields, { ...baseSchemaConvertOptions, strategy: "input" }),
583
- await this.converter.convert(details.returns, { ...baseSchemaConvertOptions, strategy: "input" })
584
- )
585
- };
586
- } else {
587
- const [bodyRequired, bodySchema] = await this.converter.convert(def.schemas.bodySchema, {
588
- ...baseSchemaConvertOptions,
589
- strategy: "input",
590
- minStructureDepthForRef: 0
591
- });
592
- if (isAnySchema(bodySchema)) {
593
- return;
594
- }
595
- ref.requestBody = {
596
- required: bodyRequired,
597
- content: toOpenAPIContent(bodySchema)
598
- };
599
- }
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;
600
548
  }
601
549
  }
602
- async #successResponse(doc, ref, def, baseSchemaConvertOptions) {
603
- const outputSchema = def.schemas.outputSchema;
604
- const status = fallbackContractConfig("defaultSuccessStatus", def.route.successStatus);
605
- const description = fallbackContractConfig("defaultSuccessDescription", def.route?.successDescription);
606
- const eventIteratorSchemaDetails = getEventIteratorSchemaDetails(outputSchema);
607
- const outputStructure = fallbackContractConfig("defaultOutputStructure", def.route.outputStructure);
608
- if (eventIteratorSchemaDetails) {
609
- ref.responses ??= {};
610
- ref.responses[status] = {
611
- description,
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,
612
568
  content: toOpenAPIEventIteratorContent(
613
- await this.converter.convert(eventIteratorSchemaDetails.yields, {
614
- ...baseSchemaConvertOptions,
615
- strategy: "output"
616
- }),
617
- await this.converter.convert(eventIteratorSchemaDetails.returns, {
618
- ...baseSchemaConvertOptions,
619
- strategy: "output"
620
- })
569
+ await converter(details.yields, { ...baseSchemaConvertOptions, strategy: "input" }),
570
+ await converter(details.returns, { ...baseSchemaConvertOptions, strategy: "input" })
621
571
  )
622
572
  };
623
- return;
624
- }
625
- const [required, json] = await this.converter.convert(outputSchema, {
626
- ...baseSchemaConvertOptions,
627
- strategy: "output",
628
- minStructureDepthForRef: outputStructure === "detailed" ? 1 : 0
629
- });
630
- if (outputStructure === "compact") {
631
- ref.responses ??= {};
632
- ref.responses[status] = {
633
- description
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)
634
585
  };
635
- ref.responses[status].content = toOpenAPIContent(applySchemaOptionality(required, json));
636
- return;
637
586
  }
638
- const handledStatuses = /* @__PURE__ */ new Set();
639
- for (const item of expandUnionSchema(json)) {
640
- const error = new OpenAPIGeneratorError(`
641
- When output structure is "detailed", output schema must satisfy:
642
- {
643
- status?: number, // must be a literal number and in the range of 200-399
644
- headers?: Record<string, unknown>,
645
- body?: unknown
646
- }
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
+ }
647
634
 
648
- But got: ${stringifyJSON(item)}
649
- `);
650
- if (!isObjectSchema(item)) {
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)) {
651
645
  throw error;
652
646
  }
653
- let schemaStatus;
654
- let schemaDescription;
655
- if (item.properties?.status !== void 0) {
656
- const statusSchema = resolveOpenAPIJsonSchemaRef(doc, item.properties.status);
657
- if (typeof statusSchema !== "object" || statusSchema.const === void 0 || typeof statusSchema.const !== "number" || !Number.isInteger(statusSchema.const) || isORPCErrorStatus(statusSchema.const)) {
658
- throw error;
659
- }
660
- schemaStatus = statusSchema.const;
661
- schemaDescription = statusSchema.description;
662
- }
663
- const itemStatus = schemaStatus ?? status;
664
- const itemDescription = schemaDescription ?? description;
665
- if (handledStatuses.has(itemStatus)) {
666
- throw new OpenAPIGeneratorError(`
667
- When output structure is "detailed", each success status must be unique.
668
- But got status: ${itemStatus} used more than once.
669
- `);
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;
670
667
  }
671
- handledStatuses.add(itemStatus);
672
- ref.responses ??= {};
673
- ref.responses[itemStatus] = {
674
- description: itemDescription
675
- };
676
- if (item.properties?.headers !== void 0) {
677
- const headersSchema = resolveOpenAPIJsonSchemaRef(doc, item.properties.headers);
678
- if (!isObjectSchema(headersSchema)) {
679
- throw error;
680
- }
681
- for (const key in headersSchema.properties) {
682
- const headerSchema = headersSchema.properties[key];
683
- if (headerSchema !== void 0) {
684
- ref.responses[itemStatus].headers ??= {};
685
- ref.responses[itemStatus].headers[key] = {
686
- schema: toOpenAPISchema(headerSchema),
687
- required: item.required?.includes("headers") && headersSchema.required?.includes(key)
688
- };
689
- }
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
+ };
690
676
  }
691
677
  }
692
- if (item.properties?.body !== void 0) {
693
- ref.responses[itemStatus].content = toOpenAPIContent(
694
- applySchemaOptionality(item.required?.includes("body") ?? false, item.properties.body)
695
- );
696
- }
697
- }
698
- }
699
- async #errorResponse(ref, def, baseSchemaConvertOptions, undefinedErrorSchema) {
700
- const errorMap = def.errorMap;
701
- const errors = {};
702
- for (const code in errorMap) {
703
- const config = errorMap[code];
704
- if (!config) {
705
- continue;
706
- }
707
- const status = fallbackORPCErrorStatus(code, config.status);
708
- const message = fallbackORPCErrorMessage(code, config.message);
709
- const [dataRequired, dataSchema] = await this.converter.convert(config.data, {
710
- ...baseSchemaConvertOptions,
711
- strategy: "output"
712
- });
713
- errors[status] ??= [];
714
- errors[status].push({
715
- type: "object",
716
- properties: {
717
- defined: { const: true },
718
- code: { const: code },
719
- status: { const: status },
720
- message: { type: "string", default: message },
721
- data: dataSchema
722
- },
723
- required: dataRequired ? ["defined", "code", "status", "message", "data"] : ["defined", "code", "status", "message"]
724
- });
725
678
  }
726
- ref.responses ??= {};
727
- for (const status in errors) {
728
- const schemas = errors[status];
729
- ref.responses[status] = {
730
- description: status,
731
- content: toOpenAPIContent({
732
- oneOf: [...schemas, undefinedErrorSchema]
733
- })
734
- };
679
+ if (item.properties?.body !== void 0) {
680
+ ref.responses[itemStatus].content = toOpenAPIContent(
681
+ applySchemaOptionality(item.required?.includes("body") ?? false, item.properties.body)
682
+ );
735
683
  }
736
684
  }
737
685
  }
738
-
739
- function createJsonifiedRouterClient(router, ...rest) {
740
- const options = resolveMaybeOptionalOptions(rest);
741
- options.interceptors ??= [];
742
- options.interceptors.unshift(async (options2) => {
743
- try {
744
- return deserialize(serialize(await options2.next()));
745
- } catch (e) {
746
- if (e instanceof ORPCError) {
747
- throw createORPCErrorFromJson(deserialize(serialize(e.toJSON(), { outputFormat: "plain" })));
748
- }
749
- throw e;
750
- }
751
- });
752
- return createRouterClient(router, options);
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
+ }
753
725
  }
754
726
 
755
727
  const oo = {
756
728
  spec: customOpenAPIOperation
757
729
  };
758
730
 
759
- 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 };
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 };