@temporary-name/server 1.9.3-alpha.65222302f1b71807a849530b3fe0fa0326d3c1a2 → 1.9.3-alpha.6a735c9469d995338b7d51335ea70485e18a4dca

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/adapters/aws-lambda/index.d.mts +5 -7
  2. package/dist/adapters/aws-lambda/index.d.ts +5 -7
  3. package/dist/adapters/aws-lambda/index.mjs +5 -8
  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 +17 -159
  7. package/dist/adapters/node/index.d.mts +9 -64
  8. package/dist/adapters/node/index.d.ts +9 -64
  9. package/dist/adapters/node/index.mjs +15 -124
  10. package/dist/handler/index.d.mts +29 -0
  11. package/dist/handler/index.d.ts +29 -0
  12. package/dist/handler/index.mjs +8 -0
  13. package/dist/helpers/index.mjs +3 -29
  14. package/dist/index.d.mts +384 -288
  15. package/dist/index.d.ts +384 -288
  16. package/dist/index.mjs +516 -409
  17. package/dist/openapi/index.d.mts +18 -53
  18. package/dist/openapi/index.d.ts +18 -53
  19. package/dist/openapi/index.mjs +335 -380
  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.CjPiuQYH.d.mts +51 -0
  25. package/dist/shared/server.CjPiuQYH.d.ts +51 -0
  26. package/dist/shared/server.CunymBH3.d.mts +39 -0
  27. package/dist/shared/server.DGMnYd7G.d.ts +39 -0
  28. package/dist/shared/server.xNz5cP2B.mjs +321 -0
  29. package/dist/shared/server.zsKBRxsz.d.mts +388 -0
  30. package/dist/shared/server.zsKBRxsz.d.ts +388 -0
  31. package/package.json +13 -30
  32. package/dist/adapters/standard/index.d.mts +0 -42
  33. package/dist/adapters/standard/index.d.ts +0 -42
  34. package/dist/adapters/standard/index.mjs +0 -11
  35. package/dist/plugins/index.d.mts +0 -160
  36. package/dist/plugins/index.d.ts +0 -160
  37. package/dist/plugins/index.mjs +0 -288
  38. package/dist/shared/server.BEHw7Eyx.mjs +0 -247
  39. package/dist/shared/server.BKSOrA6h.d.mts +0 -192
  40. package/dist/shared/server.BKSOrA6h.d.ts +0 -192
  41. package/dist/shared/server.BKh8I1Ny.mjs +0 -239
  42. package/dist/shared/server.BeuTpcmO.d.mts +0 -23
  43. package/dist/shared/server.C1fnTLq0.d.mts +0 -57
  44. package/dist/shared/server.CQyYNJ1H.d.ts +0 -57
  45. package/dist/shared/server.DLsti1Pv.mjs +0 -293
  46. package/dist/shared/server.SLLuK6_v.d.ts +0 -23
@@ -1,10 +1,12 @@
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.BEHw7Eyx.mjs';
5
- import '@temporary-name/standard-server';
1
+ import { isObject, stringifyJSON, findDeepMatches, clone, value, fallbackContractConfig, toHttpPath, assertNever, isORPCErrorStatus } from '@temporary-name/shared';
2
+ import { Z as ZodToJsonSchemaConverter, g as getEventIteratorSchemaDetails } from '../shared/server.B_oW_rPl.mjs';
3
+ import { s as standardizeHTTPPath, r as resolveContractProcedures, g as getDynamicParams } from '../shared/server.BETu17rq.mjs';
6
4
  import { TypeName } from '@temporary-name/interop/json-schema-typed/draft-2020-12';
7
5
  export { ContentEncoding as JSONSchemaContentEncoding, Format as JSONSchemaFormat, TypeName as JSONSchemaTypeName } from '@temporary-name/interop/json-schema-typed/draft-2020-12';
6
+ import '@temporary-name/standard-server';
7
+ import '@temporary-name/zod';
8
+ import '@temporary-name/server/openapi';
9
+ import 'zod/v4/core';
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,415 +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);
374
- }
375
- }
376
- return [false, {}];
377
- }
378
- }
379
-
380
359
  class OpenAPIGeneratorError extends Error {
381
360
  }
382
- class OpenAPIGenerator {
383
- converter;
384
- constructor(options = {}) {
385
- this.converter = new CompositeSchemaConverter(toArray(options.schemaConverters));
386
- }
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;
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;
412
385
  }
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}`
455
- );
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}`;
456
390
  }
391
+ namesByAuthConfig.set(authConfig, oasName);
392
+ authConfigNames.add(oasName);
457
393
  }
458
- if (errors.length) {
459
- throw new OpenAPIGeneratorError(
460
- `Some error occurred during OpenAPI generation:
461
-
462
- ${errors.join("\n\n")}`
463
- );
394
+ }
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);
464
400
  }
465
- return jsonSerialize(doc)[0];
466
401
  }
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;
486
- }
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
- }
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)]: [] }
422
+ );
423
+ if (security.length > 0) {
424
+ operationObjectRef.security = security;
500
425
  }
501
- baseSchemaConvertOptions.components.push({
502
- schema,
503
- required,
504
- ref: `#/components/schemas/${key}`,
505
- allowedStrategies
506
- });
426
+ await handleRequest(doc, operationObjectRef, def, baseSchemaConvertOptions, converter);
427
+ await handleSuccessResponse(doc, operationObjectRef, def, baseSchemaConvertOptions, converter);
507
428
  }
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;
518
- }
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);
429
+ if (typeof def.route.spec === "function") {
430
+ operationObjectRef = def.route.spec(operationObjectRef);
527
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
+ );
528
443
  }
529
- return { baseSchemaConvertOptions, undefinedErrorJsonSchema };
530
444
  }
531
- async #request(doc, ref, def, baseSchemaConvertOptions) {
532
- const method = fallbackContractConfig("defaultMethod", def.route.method);
533
- const details = getEventIteratorSchemaDetails(def.inputSchema);
534
- if (details) {
535
- ref.requestBody = {
536
- required: true,
537
- content: toOpenAPIEventIteratorContent(
538
- await this.converter.convert(details.yields, { ...baseSchemaConvertOptions, strategy: "input" }),
539
- await this.converter.convert(details.returns, { ...baseSchemaConvertOptions, strategy: "input" })
540
- )
541
- };
542
- return;
543
- }
544
- const dynamicParams = getDynamicParams(def.route.path)?.map((v) => v.name);
545
- const inputStructure = fallbackContractConfig("defaultInputStructure", def.route.inputStructure);
546
- let [required, schema] = await this.converter.convert(def.inputSchema, {
547
- ...baseSchemaConvertOptions,
548
- strategy: "input",
549
- minStructureDepthForRef: dynamicParams?.length || inputStructure === "detailed" ? 1 : 0
550
- });
551
- if (isAnySchema(schema) && !dynamicParams?.length) {
552
- return;
553
- }
554
- if (inputStructure === "compact") {
555
- if (dynamicParams?.length) {
556
- const error2 = new OpenAPIGeneratorError(
557
- 'When input structure is "compact", and path has dynamic params, input schema must be an object with all dynamic params as required.'
558
- );
559
- if (!isObjectSchema(schema)) {
560
- throw error2;
445
+ if (errors.length) {
446
+ throw new OpenAPIGeneratorError(
447
+ `Some error occurred during OpenAPI generation:
448
+
449
+ ${errors.join("\n\n")}`
450
+ );
451
+ }
452
+ return doc;
453
+ }
454
+ async function resolveCommonSchemas(doc, commonSchemas, converter) {
455
+ let undefinedErrorJsonSchema = {
456
+ type: "object",
457
+ properties: {
458
+ defined: { const: false },
459
+ code: { type: "string" },
460
+ status: { type: "number" },
461
+ message: { type: "string" },
462
+ data: {}
463
+ },
464
+ required: ["defined", "code", "status", "message"]
465
+ };
466
+ const baseSchemaConvertOptions = {};
467
+ if (commonSchemas) {
468
+ baseSchemaConvertOptions.components = [];
469
+ for (const key in commonSchemas) {
470
+ const options = commonSchemas[key];
471
+ if (options.schema === void 0) {
472
+ continue;
473
+ }
474
+ const { schema, strategy = "input" } = options;
475
+ const [required, json] = await converter(schema, { strategy });
476
+ const allowedStrategies = [strategy];
477
+ if (strategy === "input") {
478
+ const [outputRequired, outputJson] = await converter(schema, { strategy: "output" });
479
+ if (outputRequired === required && stringifyJSON(outputJson) === stringifyJSON(json)) {
480
+ allowedStrategies.push("output");
561
481
  }
562
- const [paramsSchema, rest] = separateObjectSchema(schema, dynamicParams);
563
- schema = rest;
564
- required = rest.required ? rest.required.length !== 0 : false;
565
- if (!checkParamsSchema(paramsSchema, dynamicParams)) {
566
- throw error2;
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");
567
486
  }
568
- ref.parameters ??= [];
569
- ref.parameters.push(...toOpenAPIParameters(paramsSchema, "path"));
570
487
  }
571
- if (method === "GET") {
572
- const resolvedSchema = resolveOpenAPIJsonSchemaRef(doc, schema);
573
- if (!isObjectSchema(resolvedSchema)) {
574
- throw new OpenAPIGeneratorError(
575
- 'When method is "GET", input schema must satisfy: object | any | unknown'
576
- );
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}` };
577
503
  }
578
- ref.parameters ??= [];
579
- ref.parameters.push(...toOpenAPIParameters(resolvedSchema, "query"));
580
- } else {
581
- ref.requestBody = {
582
- required,
583
- content: toOpenAPIContent(schema)
584
- };
504
+ continue;
585
505
  }
586
- return;
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);
587
514
  }
515
+ }
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) {
588
527
  const error = new OpenAPIGeneratorError(
589
- 'When input structure is "detailed", input schema must satisfy: { params?: Record<string, unknown>, query?: Record<string, unknown>, headers?: Record<string, unknown>, body?: unknown }'
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.'
590
530
  );
591
- if (!isObjectSchema(schema)) {
531
+ if (!isObjectSchema(pathSchema)) {
592
532
  throw error;
593
533
  }
594
- const resolvedParamSchema = schema.properties?.params !== void 0 ? resolveOpenAPIJsonSchemaRef(doc, schema.properties.params) : void 0;
595
- if (dynamicParams?.length && (resolvedParamSchema === void 0 || !isObjectSchema(resolvedParamSchema) || !checkParamsSchema(resolvedParamSchema, dynamicParams))) {
596
- throw new OpenAPIGeneratorError(
597
- 'When input structure is "detailed" and path has dynamic params, the "params" schema must be an object with all dynamic params as required.'
598
- );
534
+ if (!checkParamsSchema(pathSchema, dynamicParams)) {
535
+ throw error;
599
536
  }
600
- for (const from of ["params", "query", "headers"]) {
601
- const fromSchema = schema.properties?.[from];
602
- if (fromSchema !== void 0) {
603
- const resolvedSchema = resolveOpenAPIJsonSchemaRef(doc, fromSchema);
604
- if (!isObjectSchema(resolvedSchema)) {
605
- throw error;
606
- }
607
- const parameterIn = from === "params" ? "path" : from === "headers" ? "header" : "query";
608
- ref.parameters ??= [];
609
- ref.parameters.push(...toOpenAPIParameters(resolvedSchema, parameterIn));
610
- }
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;
611
544
  }
612
- if (schema.properties?.body !== void 0) {
613
- ref.requestBody = {
614
- required: schema.required?.includes("body"),
615
- content: toOpenAPIContent(schema.properties.body)
616
- };
545
+ if (!checkParamsSchema(pathSchema, [])) {
546
+ console.log("BAR", pathSchema);
547
+ throw error;
617
548
  }
618
549
  }
619
- async #successResponse(doc, ref, def, baseSchemaConvertOptions) {
620
- const outputSchema = def.outputSchema;
621
- const status = fallbackContractConfig("defaultSuccessStatus", def.route.successStatus);
622
- const description = fallbackContractConfig("defaultSuccessDescription", def.route?.successDescription);
623
- const eventIteratorSchemaDetails = getEventIteratorSchemaDetails(outputSchema);
624
- const outputStructure = fallbackContractConfig("defaultOutputStructure", def.route.outputStructure);
625
- if (eventIteratorSchemaDetails) {
626
- ref.responses ??= {};
627
- ref.responses[status] = {
628
- 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,
629
568
  content: toOpenAPIEventIteratorContent(
630
- await this.converter.convert(eventIteratorSchemaDetails.yields, {
631
- ...baseSchemaConvertOptions,
632
- strategy: "output"
633
- }),
634
- await this.converter.convert(eventIteratorSchemaDetails.returns, {
635
- ...baseSchemaConvertOptions,
636
- strategy: "output"
637
- })
569
+ await converter(details.yields, { ...baseSchemaConvertOptions, strategy: "input" }),
570
+ await converter(details.returns, { ...baseSchemaConvertOptions, strategy: "input" })
638
571
  )
639
572
  };
640
- return;
641
- }
642
- const [required, json] = await this.converter.convert(outputSchema, {
643
- ...baseSchemaConvertOptions,
644
- strategy: "output",
645
- minStructureDepthForRef: outputStructure === "detailed" ? 1 : 0
646
- });
647
- if (outputStructure === "compact") {
648
- ref.responses ??= {};
649
- ref.responses[status] = {
650
- 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)
651
585
  };
652
- ref.responses[status].content = toOpenAPIContent(applySchemaOptionality(required, json));
653
- return;
654
586
  }
655
- const handledStatuses = /* @__PURE__ */ new Set();
656
- for (const item of expandUnionSchema(json)) {
657
- const error = new OpenAPIGeneratorError(`
658
- When output structure is "detailed", output schema must satisfy:
659
- {
660
- status?: number, // must be a literal number and in the range of 200-399
661
- headers?: Record<string, unknown>,
662
- body?: unknown
663
- }
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
+ }
664
634
 
665
- But got: ${stringifyJSON(item)}
666
- `);
667
- 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)) {
668
645
  throw error;
669
646
  }
670
- let schemaStatus;
671
- let schemaDescription;
672
- if (item.properties?.status !== void 0) {
673
- const statusSchema = resolveOpenAPIJsonSchemaRef(doc, item.properties.status);
674
- if (typeof statusSchema !== "object" || statusSchema.const === void 0 || typeof statusSchema.const !== "number" || !Number.isInteger(statusSchema.const) || isORPCErrorStatus(statusSchema.const)) {
675
- throw error;
676
- }
677
- schemaStatus = statusSchema.const;
678
- schemaDescription = statusSchema.description;
679
- }
680
- const itemStatus = schemaStatus ?? status;
681
- const itemDescription = schemaDescription ?? description;
682
- if (handledStatuses.has(itemStatus)) {
683
- throw new OpenAPIGeneratorError(`
684
- When output structure is "detailed", each success status must be unique.
685
- But got status: ${itemStatus} used more than once.
686
- `);
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;
687
667
  }
688
- handledStatuses.add(itemStatus);
689
- ref.responses ??= {};
690
- ref.responses[itemStatus] = {
691
- description: itemDescription
692
- };
693
- if (item.properties?.headers !== void 0) {
694
- const headersSchema = resolveOpenAPIJsonSchemaRef(doc, item.properties.headers);
695
- if (!isObjectSchema(headersSchema)) {
696
- throw error;
697
- }
698
- for (const key in headersSchema.properties) {
699
- const headerSchema = headersSchema.properties[key];
700
- if (headerSchema !== void 0) {
701
- ref.responses[itemStatus].headers ??= {};
702
- ref.responses[itemStatus].headers[key] = {
703
- schema: toOpenAPISchema(headerSchema),
704
- required: item.required?.includes("headers") && headersSchema.required?.includes(key)
705
- };
706
- }
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
+ };
707
676
  }
708
677
  }
709
- if (item.properties?.body !== void 0) {
710
- ref.responses[itemStatus].content = toOpenAPIContent(
711
- applySchemaOptionality(item.required?.includes("body") ?? false, item.properties.body)
712
- );
713
- }
714
678
  }
715
- }
716
- async #errorResponse(ref, def, baseSchemaConvertOptions, undefinedErrorSchema) {
717
- const errorMap = def.errorMap;
718
- const errors = {};
719
- for (const code in errorMap) {
720
- const config = errorMap[code];
721
- if (!config) {
722
- continue;
723
- }
724
- const status = fallbackORPCErrorStatus(code, config.status);
725
- const message = fallbackORPCErrorMessage(code, config.message);
726
- const [dataRequired, dataSchema] = await this.converter.convert(config.data, {
727
- ...baseSchemaConvertOptions,
728
- strategy: "output"
729
- });
730
- errors[status] ??= [];
731
- errors[status].push({
732
- type: "object",
733
- properties: {
734
- defined: { const: true },
735
- code: { const: code },
736
- status: { const: status },
737
- message: { type: "string", default: message },
738
- data: dataSchema
739
- },
740
- required: dataRequired ? ["defined", "code", "status", "message", "data"] : ["defined", "code", "status", "message"]
741
- });
742
- }
743
- ref.responses ??= {};
744
- for (const status in errors) {
745
- const schemas = errors[status];
746
- ref.responses[status] = {
747
- description: status,
748
- content: toOpenAPIContent({
749
- oneOf: [...schemas, undefinedErrorSchema]
750
- })
751
- };
679
+ if (item.properties?.body !== void 0) {
680
+ ref.responses[itemStatus].content = toOpenAPIContent(
681
+ applySchemaOptionality(item.required?.includes("body") ?? false, item.properties.body)
682
+ );
752
683
  }
753
684
  }
754
685
  }
755
-
756
- function createJsonifiedRouterClient(router, ...rest) {
757
- const options = resolveMaybeOptionalOptions(rest);
758
- options.interceptors ??= [];
759
- options.interceptors.unshift(async (options2) => {
760
- try {
761
- return deserialize(serialize(await options2.next()));
762
- } catch (e) {
763
- if (e instanceof ORPCError) {
764
- throw createORPCErrorFromJson(deserialize(serialize(e.toJSON(), { outputFormat: "plain" })));
765
- }
766
- throw e;
767
- }
768
- });
769
- 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
+ }
770
725
  }
771
726
 
772
727
  const oo = {
773
728
  spec: customOpenAPIOperation
774
729
  };
775
730
 
776
- 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 };