agent-shim 8.28.0 → 8.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -18556,10 +18556,10 @@ var require_mock_utils = __commonJS({
18556
18556
  }
18557
18557
  }
18558
18558
  function buildHeadersFromArray(headers) {
18559
- const clone2 = headers.slice();
18559
+ const clone3 = headers.slice();
18560
18560
  const entries = [];
18561
- for (let index = 0; index < clone2.length; index += 2) {
18562
- entries.push([clone2[index], clone2[index + 1]]);
18561
+ for (let index = 0; index < clone3.length; index += 2) {
18562
+ entries.push([clone3[index], clone3[index + 1]]);
18563
18563
  }
18564
18564
  return Object.fromEntries(entries);
18565
18565
  }
@@ -48113,9 +48113,9 @@ function compileValidator(schema, parser) {
48113
48113
  function compile(schema, options) {
48114
48114
  try {
48115
48115
  const parser = compileFn(schema);
48116
- const clone2 = withParser(schema, parser);
48117
- clone2._zod.bag.validator = compileValidator(schema, parser);
48118
- return clone2;
48116
+ const clone3 = withParser(schema, parser);
48117
+ clone3._zod.bag.validator = compileValidator(schema, parser);
48118
+ return clone3;
48119
48119
  } catch (err) {
48120
48120
  if (options?.strict)
48121
48121
  throw err;
@@ -48126,7 +48126,7 @@ function withParser(schema, parser) {
48126
48126
  if (isRecursiveSchema(schema)) {
48127
48127
  throw new ZodCompileUnsupportedError("a schema whose subtree contains a reference cycle");
48128
48128
  }
48129
- const clone2 = clone(schema);
48129
+ const clone3 = clone(schema);
48130
48130
  const liveRun = schema._zod.run;
48131
48131
  const originalRun = liveRun.__originalRun ?? liveRun;
48132
48132
  const wrapped = (payload, ctx) => {
@@ -48146,12 +48146,12 @@ function withParser(schema, parser) {
48146
48146
  return originalRun(payload, ctx);
48147
48147
  };
48148
48148
  wrapped.__originalRun = originalRun;
48149
- clone2._zod.bag.fallbackRun = originalRun;
48150
- clone2._zod.bag.validator = parser;
48151
- clone2._zod.run = wrapped;
48149
+ clone3._zod.bag.fallbackRun = originalRun;
48150
+ clone3._zod.bag.validator = parser;
48151
+ clone3._zod.run = wrapped;
48152
48152
  if (!liveRun.__originalRun)
48153
- installCompiledUserMethods(clone2, schema, parser);
48154
- return clone2;
48153
+ installCompiledUserMethods(clone3, schema, parser);
48154
+ return clone3;
48155
48155
  }
48156
48156
  function installCompiledUserMethods(target, source, parser) {
48157
48157
  const targetAny = target;
@@ -61796,7 +61796,7 @@ function registerIdentityCommand(program2, deps) {
61796
61796
  // package.json
61797
61797
  var package_default = {
61798
61798
  name: "agent-shim",
61799
- version: "8.28.0",
61799
+ version: "8.30.0",
61800
61800
  description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
61801
61801
  license: "MIT",
61802
61802
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -61847,6 +61847,7 @@ var package_default = {
61847
61847
  dependencies: {
61848
61848
  "@clack/prompts": "^1.8.0",
61849
61849
  "@orpc/client": "1.15.4",
61850
+ "@orpc/openapi": "1.15.4",
61850
61851
  "@orpc/server": "1.15.4",
61851
61852
  commander: "^15.0.0",
61852
61853
  cosmiconfig: "^10.0.1",
@@ -68796,6 +68797,21 @@ function parseEmptyableJSON(text2) {
68796
68797
  function stringifyJSON(value2) {
68797
68798
  return JSON.stringify(value2);
68798
68799
  }
68800
+ function findDeepMatches(check2, payload, segments = [], maps = [], values = []) {
68801
+ if (check2(payload)) {
68802
+ maps.push(segments);
68803
+ values.push(payload);
68804
+ } else if (Array.isArray(payload)) {
68805
+ payload.forEach((v, i2) => {
68806
+ findDeepMatches(check2, v, [...segments, i2], maps, values);
68807
+ });
68808
+ } else if (isObject4(payload)) {
68809
+ for (const key in payload) {
68810
+ findDeepMatches(check2, payload[key], [...segments, key], maps, values);
68811
+ }
68812
+ }
68813
+ return { maps, values };
68814
+ }
68799
68815
  function getConstructor(value2) {
68800
68816
  if (!isTypescriptObject(value2)) {
68801
68817
  return null;
@@ -68812,6 +68828,22 @@ function isObject4(value2) {
68812
68828
  function isTypescriptObject(value2) {
68813
68829
  return !!value2 && (typeof value2 === "object" || typeof value2 === "function");
68814
68830
  }
68831
+ function clone2(value2) {
68832
+ if (Array.isArray(value2)) {
68833
+ return value2.map(clone2);
68834
+ }
68835
+ if (isObject4(value2)) {
68836
+ const result = {};
68837
+ for (const key in value2) {
68838
+ result[key] = clone2(value2[key]);
68839
+ }
68840
+ for (const sym of Object.getOwnPropertySymbols(value2)) {
68841
+ result[sym] = clone2(value2[sym]);
68842
+ }
68843
+ return result;
68844
+ }
68845
+ return value2;
68846
+ }
68815
68847
  function setOwn(object2, key, value2) {
68816
68848
  if (key === "__proto__") {
68817
68849
  Object.defineProperty(object2, key, {
@@ -69874,6 +69906,10 @@ var CheckRunInputSchema = external_exports.strictObject({
69874
69906
  path: external_exports.string().min(1),
69875
69907
  identity: external_exports.string().min(1).optional()
69876
69908
  }).refine((input2) => import_node_path33.default.isAbsolute(input2.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
69909
+ var PoolPickInputSchema = external_exports.strictObject({
69910
+ pool: external_exports.string().min(1),
69911
+ path: external_exports.string().min(1)
69912
+ }).refine((input2) => import_node_path33.default.isAbsolute(input2.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
69877
69913
  var DoctorFindingSchema = external_exports.strictObject({
69878
69914
  section: external_exports.enum(DOCTOR_SECTIONS),
69879
69915
  subject: external_exports.string().optional(),
@@ -70894,6 +70930,12 @@ function eventIterator(yields, returns) {
70894
70930
  }
70895
70931
  };
70896
70932
  }
70933
+ function getEventIteratorSchemaDetails(schema) {
70934
+ if (schema === void 0) {
70935
+ return void 0;
70936
+ }
70937
+ return schema["~standard"][EVENT_ITERATOR_DETAILS_SYMBOL];
70938
+ }
70897
70939
 
70898
70940
  // node_modules/.pnpm/@orpc+server@1.15.4/node_modules/@orpc/server/dist/shared/server.DEBcqOjg.mjs
70899
70941
  var LAZY_SYMBOL = /* @__PURE__ */ Symbol("ORPC_LAZY_SYMBOL");
@@ -71234,6 +71276,19 @@ function traverseContractProcedures(options, callback, lazyOptions = []) {
71234
71276
  }
71235
71277
  return lazyOptions;
71236
71278
  }
71279
+ async function resolveContractProcedures(options, callback) {
71280
+ const pending = [options];
71281
+ for (const options2 of pending) {
71282
+ const lazyOptions = traverseContractProcedures(options2, callback);
71283
+ for (const options3 of lazyOptions) {
71284
+ const { default: router } = await unlazy(options3.router);
71285
+ pending.push({
71286
+ router,
71287
+ path: options3.path
71288
+ });
71289
+ }
71290
+ }
71291
+ }
71237
71292
  function createContractedProcedure(procedure, contract) {
71238
71293
  return new Procedure({
71239
71294
  ...procedure["~orpc"],
@@ -71628,6 +71683,1173 @@ var RPCLink = class extends StandardRPCLink {
71628
71683
  }
71629
71684
  };
71630
71685
 
71686
+ // node_modules/.pnpm/@orpc+openapi-client@1.15.4/node_modules/@orpc/openapi-client/dist/shared/openapi-client.t9fCAe3x.mjs
71687
+ var StandardBracketNotationSerializer = class {
71688
+ maxArrayIndex;
71689
+ constructor(options = {}) {
71690
+ this.maxArrayIndex = options.maxBracketNotationArrayIndex ?? 9999;
71691
+ }
71692
+ serialize(data, segments = [], result = []) {
71693
+ if (Array.isArray(data)) {
71694
+ data.forEach((item, i2) => {
71695
+ this.serialize(item, [...segments, i2], result);
71696
+ });
71697
+ } else if (isObject4(data)) {
71698
+ for (const key in data) {
71699
+ this.serialize(data[key], [...segments, key], result);
71700
+ }
71701
+ } else {
71702
+ result.push([this.stringifyPath(segments), data]);
71703
+ }
71704
+ return result;
71705
+ }
71706
+ deserialize(serialized) {
71707
+ if (serialized.length === 0) {
71708
+ return {};
71709
+ }
71710
+ const arrayPushStyles = /* @__PURE__ */ new WeakSet();
71711
+ const ref = { value: [] };
71712
+ for (const [path46, value2] of serialized) {
71713
+ const segments = this.parsePath(path46);
71714
+ let currentRef = ref;
71715
+ let nextSegment = "value";
71716
+ segments.forEach((segment, i2) => {
71717
+ if (!Array.isArray(currentRef[nextSegment]) && !isObject4(currentRef[nextSegment])) {
71718
+ currentRef[nextSegment] = [];
71719
+ }
71720
+ if (i2 !== segments.length - 1) {
71721
+ if (Array.isArray(currentRef[nextSegment]) && !isValidArrayIndex(segment, this.maxArrayIndex)) {
71722
+ if (arrayPushStyles.has(currentRef[nextSegment])) {
71723
+ arrayPushStyles.delete(currentRef[nextSegment]);
71724
+ currentRef[nextSegment] = pushStyleArrayToObject(currentRef[nextSegment]);
71725
+ } else {
71726
+ currentRef[nextSegment] = arrayToObject(currentRef[nextSegment]);
71727
+ }
71728
+ }
71729
+ } else {
71730
+ if (Array.isArray(currentRef[nextSegment])) {
71731
+ if (segment === "") {
71732
+ if (currentRef[nextSegment].length && !arrayPushStyles.has(currentRef[nextSegment])) {
71733
+ currentRef[nextSegment] = arrayToObject(currentRef[nextSegment]);
71734
+ }
71735
+ } else {
71736
+ if (arrayPushStyles.has(currentRef[nextSegment])) {
71737
+ arrayPushStyles.delete(currentRef[nextSegment]);
71738
+ currentRef[nextSegment] = pushStyleArrayToObject(currentRef[nextSegment]);
71739
+ } else if (!isValidArrayIndex(segment, this.maxArrayIndex)) {
71740
+ currentRef[nextSegment] = arrayToObject(currentRef[nextSegment]);
71741
+ }
71742
+ }
71743
+ }
71744
+ }
71745
+ currentRef = currentRef[nextSegment];
71746
+ nextSegment = segment;
71747
+ });
71748
+ if (Array.isArray(currentRef) && nextSegment === "") {
71749
+ arrayPushStyles.add(currentRef);
71750
+ currentRef.push(value2);
71751
+ } else if (nextSegment in currentRef) {
71752
+ if (Array.isArray(currentRef[nextSegment])) {
71753
+ currentRef[nextSegment].push(value2);
71754
+ } else {
71755
+ currentRef[nextSegment] = [currentRef[nextSegment], value2];
71756
+ }
71757
+ } else {
71758
+ currentRef[nextSegment] = value2;
71759
+ }
71760
+ }
71761
+ return ref.value;
71762
+ }
71763
+ stringifyPath(segments) {
71764
+ return segments.map((segment) => {
71765
+ return segment.toString().replace(/[\\[\]]/g, (match) => {
71766
+ switch (match) {
71767
+ case "\\":
71768
+ return "\\\\";
71769
+ case "[":
71770
+ return "\\[";
71771
+ case "]":
71772
+ return "\\]";
71773
+ /* v8 ignore next 2 */
71774
+ default:
71775
+ return match;
71776
+ }
71777
+ });
71778
+ }).reduce((result, segment, i2) => {
71779
+ if (i2 === 0) {
71780
+ return segment;
71781
+ }
71782
+ return `${result}[${segment}]`;
71783
+ }, "");
71784
+ }
71785
+ parsePath(path46) {
71786
+ const segments = [];
71787
+ let inBrackets = false;
71788
+ let currentSegment = "";
71789
+ let backslashCount = 0;
71790
+ for (let i2 = 0; i2 < path46.length; i2++) {
71791
+ const char = path46[i2];
71792
+ const nextChar = path46[i2 + 1];
71793
+ if (inBrackets && char === "]" && (nextChar === void 0 || nextChar === "[") && backslashCount % 2 === 0) {
71794
+ if (nextChar === void 0) {
71795
+ inBrackets = false;
71796
+ }
71797
+ segments.push(currentSegment);
71798
+ currentSegment = "";
71799
+ i2++;
71800
+ } else if (segments.length === 0 && char === "[" && backslashCount % 2 === 0) {
71801
+ inBrackets = true;
71802
+ segments.push(currentSegment);
71803
+ currentSegment = "";
71804
+ } else if (char === "\\") {
71805
+ backslashCount++;
71806
+ } else {
71807
+ currentSegment += "\\".repeat(backslashCount / 2) + char;
71808
+ backslashCount = 0;
71809
+ }
71810
+ }
71811
+ return inBrackets || segments.length === 0 ? [path46] : segments;
71812
+ }
71813
+ };
71814
+ function isValidArrayIndex(value2, maxIndex) {
71815
+ return /^0$|^[1-9]\d*$/.test(value2) && Number(value2) <= maxIndex;
71816
+ }
71817
+ function arrayToObject(array2) {
71818
+ const obj = new NullProtoObj();
71819
+ array2.forEach((item, i2) => {
71820
+ obj[i2] = item;
71821
+ });
71822
+ return obj;
71823
+ }
71824
+ function pushStyleArrayToObject(array2) {
71825
+ const obj = new NullProtoObj();
71826
+ obj[""] = array2.length === 1 ? array2[0] : array2;
71827
+ return obj;
71828
+ }
71829
+
71830
+ // node_modules/.pnpm/@orpc+openapi-client@1.15.4/node_modules/@orpc/openapi-client/dist/shared/openapi-client.B2Q9qU5m.mjs
71831
+ var StandardOpenAPIJsonSerializer = class {
71832
+ customSerializers;
71833
+ constructor(options = {}) {
71834
+ this.customSerializers = options.customJsonSerializers ?? [];
71835
+ }
71836
+ serialize(data, hasBlobRef = { value: false }) {
71837
+ for (const custom2 of this.customSerializers) {
71838
+ if (custom2.condition(data)) {
71839
+ const result = this.serialize(custom2.serialize(data), hasBlobRef);
71840
+ return result;
71841
+ }
71842
+ }
71843
+ if (data instanceof Blob) {
71844
+ hasBlobRef.value = true;
71845
+ return [data, hasBlobRef.value];
71846
+ }
71847
+ if (data instanceof Set) {
71848
+ return this.serialize(Array.from(data), hasBlobRef);
71849
+ }
71850
+ if (data instanceof Map) {
71851
+ return this.serialize(Array.from(data.entries()), hasBlobRef);
71852
+ }
71853
+ if (Array.isArray(data)) {
71854
+ const json2 = data.map((v) => v === void 0 ? null : this.serialize(v, hasBlobRef)[0]);
71855
+ return [json2, hasBlobRef.value];
71856
+ }
71857
+ if (isObject4(data)) {
71858
+ const json2 = {};
71859
+ for (const k in data) {
71860
+ if (k === "toJSON" && typeof data[k] === "function") {
71861
+ continue;
71862
+ }
71863
+ json2[k] = this.serialize(data[k], hasBlobRef)[0];
71864
+ }
71865
+ return [json2, hasBlobRef.value];
71866
+ }
71867
+ if (typeof data === "bigint" || data instanceof RegExp || data instanceof URL) {
71868
+ return [data.toString(), hasBlobRef.value];
71869
+ }
71870
+ if (data instanceof Date) {
71871
+ return [Number.isNaN(data.getTime()) ? null : data.toISOString(), hasBlobRef.value];
71872
+ }
71873
+ if (Number.isNaN(data)) {
71874
+ return [null, hasBlobRef.value];
71875
+ }
71876
+ return [data, hasBlobRef.value];
71877
+ }
71878
+ };
71879
+ function standardizeHTTPPath(path46) {
71880
+ return `/${path46.replace(/\/{2,}/g, "/").replace(/^\/|\/$/g, "")}`;
71881
+ }
71882
+ function getDynamicParams(path46) {
71883
+ return path46 ? standardizeHTTPPath(path46).match(/\/\{[^}]+\}/g)?.map((v) => ({
71884
+ raw: v,
71885
+ name: v.match(/\{\+?([^}]+)\}/)[1]
71886
+ })) : void 0;
71887
+ }
71888
+ var StandardOpenAPISerializer = class {
71889
+ constructor(jsonSerializer, bracketNotation) {
71890
+ this.jsonSerializer = jsonSerializer;
71891
+ this.bracketNotation = bracketNotation;
71892
+ }
71893
+ serialize(data, options = {}) {
71894
+ if (isAsyncIteratorObject(data) && !options.outputFormat) {
71895
+ return mapEventIterator(data, {
71896
+ value: async (value2) => this.#serialize(value2, { outputFormat: "plain" }),
71897
+ error: async (e) => {
71898
+ return new ErrorEvent({
71899
+ data: this.#serialize(toORPCError(e).toJSON(), { outputFormat: "plain" }),
71900
+ cause: e
71901
+ });
71902
+ }
71903
+ });
71904
+ }
71905
+ return this.#serialize(data, options);
71906
+ }
71907
+ #serialize(data, options) {
71908
+ const [json2, hasBlob] = this.jsonSerializer.serialize(data);
71909
+ if (options.outputFormat === "plain") {
71910
+ return json2;
71911
+ }
71912
+ if (options.outputFormat === "URLSearchParams") {
71913
+ const params = new URLSearchParams();
71914
+ for (const [path46, value2] of this.bracketNotation.serialize(json2)) {
71915
+ if (typeof value2 === "string" || typeof value2 === "number" || typeof value2 === "boolean") {
71916
+ params.append(path46, value2.toString());
71917
+ }
71918
+ }
71919
+ return params;
71920
+ }
71921
+ if (json2 instanceof Blob || json2 === void 0 || !hasBlob) {
71922
+ return json2;
71923
+ }
71924
+ const form = new FormData();
71925
+ for (const [path46, value2] of this.bracketNotation.serialize(json2)) {
71926
+ if (typeof value2 === "string" || typeof value2 === "number" || typeof value2 === "boolean") {
71927
+ form.append(path46, value2.toString());
71928
+ } else if (value2 instanceof Blob) {
71929
+ form.append(path46, value2);
71930
+ }
71931
+ }
71932
+ return form;
71933
+ }
71934
+ deserialize(data) {
71935
+ if (data instanceof URLSearchParams || data instanceof FormData) {
71936
+ return this.bracketNotation.deserialize(Array.from(data.entries()));
71937
+ }
71938
+ if (isAsyncIteratorObject(data)) {
71939
+ return mapEventIterator(data, {
71940
+ value: async (value2) => value2,
71941
+ error: async (e) => {
71942
+ if (e instanceof ErrorEvent && isORPCErrorJson(e.data)) {
71943
+ return createORPCErrorFromJson(e.data, { cause: e });
71944
+ }
71945
+ return e;
71946
+ }
71947
+ });
71948
+ }
71949
+ return data;
71950
+ }
71951
+ };
71952
+
71953
+ // node_modules/.pnpm/json-schema-typed@8.0.2/node_modules/json-schema-typed/draft_2020_12.js
71954
+ var ContentEncoding;
71955
+ (function(ContentEncoding2) {
71956
+ ContentEncoding2["7bit"] = "7bit";
71957
+ ContentEncoding2["8bit"] = "8bit";
71958
+ ContentEncoding2["Base64"] = "base64";
71959
+ ContentEncoding2["Binary"] = "binary";
71960
+ ContentEncoding2["IETFToken"] = "ietf-token";
71961
+ ContentEncoding2["QuotedPrintable"] = "quoted-printable";
71962
+ ContentEncoding2["XToken"] = "x-token";
71963
+ })(ContentEncoding || (ContentEncoding = {}));
71964
+ var Format;
71965
+ (function(Format2) {
71966
+ Format2["Date"] = "date";
71967
+ Format2["DateTime"] = "date-time";
71968
+ Format2["Duration"] = "duration";
71969
+ Format2["Email"] = "email";
71970
+ Format2["Hostname"] = "hostname";
71971
+ Format2["IDNEmail"] = "idn-email";
71972
+ Format2["IDNHostname"] = "idn-hostname";
71973
+ Format2["IPv4"] = "ipv4";
71974
+ Format2["IPv6"] = "ipv6";
71975
+ Format2["IRI"] = "iri";
71976
+ Format2["IRIReference"] = "iri-reference";
71977
+ Format2["JSONPointer"] = "json-pointer";
71978
+ Format2["JSONPointerURIFragment"] = "json-pointer-uri-fragment";
71979
+ Format2["RegEx"] = "regex";
71980
+ Format2["RelativeJSONPointer"] = "relative-json-pointer";
71981
+ Format2["Time"] = "time";
71982
+ Format2["URI"] = "uri";
71983
+ Format2["URIReference"] = "uri-reference";
71984
+ Format2["URITemplate"] = "uri-template";
71985
+ Format2["UUID"] = "uuid";
71986
+ })(Format || (Format = {}));
71987
+ var TypeName;
71988
+ (function(TypeName2) {
71989
+ TypeName2["Array"] = "array";
71990
+ TypeName2["Boolean"] = "boolean";
71991
+ TypeName2["Integer"] = "integer";
71992
+ TypeName2["Null"] = "null";
71993
+ TypeName2["Number"] = "number";
71994
+ TypeName2["Object"] = "object";
71995
+ TypeName2["String"] = "string";
71996
+ })(TypeName || (TypeName = {}));
71997
+
71998
+ // node_modules/.pnpm/@orpc+openapi@1.15.4/node_modules/@orpc/openapi/dist/shared/openapi.BwdtJjDu.mjs
71999
+ var OPERATION_EXTENDER_SYMBOL = /* @__PURE__ */ Symbol("ORPC_OPERATION_EXTENDER");
72000
+ function getCustomOpenAPIOperation(o) {
72001
+ return o[OPERATION_EXTENDER_SYMBOL];
72002
+ }
72003
+ function applyCustomOpenAPIOperation(operation, contract) {
72004
+ const operationCustoms = [];
72005
+ for (const errorItem of Object.values(contract["~orpc"].errorMap)) {
72006
+ const maybeExtender = errorItem ? getCustomOpenAPIOperation(errorItem) : void 0;
72007
+ if (maybeExtender) {
72008
+ operationCustoms.push(maybeExtender);
72009
+ }
72010
+ }
72011
+ if (isProcedure(contract)) {
72012
+ for (const middleware of contract["~orpc"].middlewares) {
72013
+ const maybeExtender = getCustomOpenAPIOperation(middleware);
72014
+ if (maybeExtender) {
72015
+ operationCustoms.push(maybeExtender);
72016
+ }
72017
+ }
72018
+ }
72019
+ let currentOperation = operation;
72020
+ for (const custom2 of operationCustoms) {
72021
+ if (typeof custom2 === "function") {
72022
+ currentOperation = custom2(currentOperation, contract);
72023
+ } else {
72024
+ currentOperation = {
72025
+ ...currentOperation,
72026
+ ...custom2
72027
+ };
72028
+ }
72029
+ }
72030
+ return currentOperation;
72031
+ }
72032
+ var LOGIC_KEYWORDS = [
72033
+ "$dynamicRef",
72034
+ "$ref",
72035
+ "additionalItems",
72036
+ "additionalProperties",
72037
+ "allOf",
72038
+ "anyOf",
72039
+ "const",
72040
+ "contains",
72041
+ "contentEncoding",
72042
+ "contentMediaType",
72043
+ "contentSchema",
72044
+ "dependencies",
72045
+ "dependentRequired",
72046
+ "dependentSchemas",
72047
+ "else",
72048
+ "enum",
72049
+ "exclusiveMaximum",
72050
+ "exclusiveMinimum",
72051
+ "format",
72052
+ "if",
72053
+ "items",
72054
+ "maxContains",
72055
+ "maximum",
72056
+ "maxItems",
72057
+ "maxLength",
72058
+ "maxProperties",
72059
+ "minContains",
72060
+ "minimum",
72061
+ "minItems",
72062
+ "minLength",
72063
+ "minProperties",
72064
+ "multipleOf",
72065
+ "not",
72066
+ "oneOf",
72067
+ "pattern",
72068
+ "patternProperties",
72069
+ "prefixItems",
72070
+ "properties",
72071
+ "propertyNames",
72072
+ "required",
72073
+ "then",
72074
+ "type",
72075
+ "unevaluatedItems",
72076
+ "unevaluatedProperties",
72077
+ "uniqueItems"
72078
+ ];
72079
+ function isFileSchema(schema) {
72080
+ return isObject4(schema) && schema.type === "string" && typeof schema.contentMediaType === "string";
72081
+ }
72082
+ function isObjectSchema(schema) {
72083
+ return isObject4(schema) && schema.type === "object";
72084
+ }
72085
+ function isAnySchema(schema) {
72086
+ if (schema === true) {
72087
+ return true;
72088
+ }
72089
+ if (Object.keys(schema).filter((v) => schema[v] !== void 0).every((k) => !LOGIC_KEYWORDS.includes(k))) {
72090
+ return true;
72091
+ }
72092
+ return false;
72093
+ }
72094
+ function isNeverSchema(schema) {
72095
+ if (schema === false) {
72096
+ return true;
72097
+ }
72098
+ if (typeof schema === "object" && schema.not !== void 0) {
72099
+ if (schema.not === true) {
72100
+ return true;
72101
+ }
72102
+ if (typeof schema.not === "object" && Object.keys(schema.not).length === 0) {
72103
+ return true;
72104
+ }
72105
+ }
72106
+ return false;
72107
+ }
72108
+ function separateObjectSchema(schema, separatedProperties) {
72109
+ if (Object.keys(schema).some(
72110
+ (k) => !["type", "properties", "required", "additionalProperties"].includes(k) && LOGIC_KEYWORDS.includes(k) && schema[k] !== void 0
72111
+ )) {
72112
+ return [{ type: "object" }, schema];
72113
+ }
72114
+ const matched = { ...schema };
72115
+ const rest = { ...schema };
72116
+ matched.properties = separatedProperties.reduce((acc, key) => {
72117
+ const keySchema = schema.properties?.[key] ?? schema.additionalProperties;
72118
+ if (keySchema !== void 0) {
72119
+ acc[key] = keySchema;
72120
+ }
72121
+ return acc;
72122
+ }, {});
72123
+ if (Object.keys(matched.properties).length === 0) {
72124
+ matched.properties = void 0;
72125
+ }
72126
+ matched.required = schema.required?.filter((key) => separatedProperties.includes(key));
72127
+ if (matched.required?.length === 0) {
72128
+ matched.required = void 0;
72129
+ }
72130
+ matched.examples = schema.examples?.map((example) => {
72131
+ if (!isObject4(example)) {
72132
+ return example;
72133
+ }
72134
+ return Object.entries(example).reduce((acc, [key, value2]) => {
72135
+ if (separatedProperties.includes(key)) {
72136
+ acc[key] = value2;
72137
+ }
72138
+ return acc;
72139
+ }, {});
72140
+ });
72141
+ rest.properties = schema.properties && Object.entries(schema.properties).filter(([key]) => !separatedProperties.includes(key)).reduce((acc = {}, [key, value2]) => {
72142
+ acc[key] = value2;
72143
+ return acc;
72144
+ }, void 0);
72145
+ rest.required = schema.required?.filter((key) => !separatedProperties.includes(key));
72146
+ if (rest.required?.length === 0) {
72147
+ rest.required = void 0;
72148
+ }
72149
+ rest.examples = schema.examples?.map((example) => {
72150
+ if (!isObject4(example)) {
72151
+ return example;
72152
+ }
72153
+ return Object.entries(example).reduce((acc, [key, value2]) => {
72154
+ if (!separatedProperties.includes(key)) {
72155
+ acc[key] = value2;
72156
+ }
72157
+ return acc;
72158
+ }, {});
72159
+ });
72160
+ return [matched, rest];
72161
+ }
72162
+ function filterSchemaBranches(schema, check2, matches = []) {
72163
+ if (check2(schema)) {
72164
+ matches.push(schema);
72165
+ return [matches, void 0];
72166
+ }
72167
+ if (isObject4(schema)) {
72168
+ for (const keyword of ["anyOf", "oneOf"]) {
72169
+ if (schema[keyword] && Object.keys(schema).every(
72170
+ (k) => k === keyword || !LOGIC_KEYWORDS.includes(k)
72171
+ )) {
72172
+ const rest = schema[keyword].map((s) => filterSchemaBranches(s, check2, matches)[1]).filter((v) => !!v);
72173
+ if (rest.length === 1 && typeof rest[0] === "object") {
72174
+ return [matches, { ...schema, [keyword]: void 0, ...rest[0] }];
72175
+ }
72176
+ return [matches, { ...schema, [keyword]: rest }];
72177
+ }
72178
+ }
72179
+ }
72180
+ return [matches, schema];
72181
+ }
72182
+ function applySchemaOptionality(required2, schema) {
72183
+ if (required2) {
72184
+ return schema;
72185
+ }
72186
+ return {
72187
+ anyOf: [
72188
+ schema,
72189
+ { not: {} }
72190
+ ]
72191
+ };
72192
+ }
72193
+ function expandUnionSchema(schema) {
72194
+ if (typeof schema === "object") {
72195
+ for (const keyword of ["anyOf", "oneOf"]) {
72196
+ if (schema[keyword] && Object.keys(schema).every(
72197
+ (k) => k === keyword || !LOGIC_KEYWORDS.includes(k)
72198
+ )) {
72199
+ return schema[keyword].flatMap((s) => expandUnionSchema(s));
72200
+ }
72201
+ }
72202
+ }
72203
+ return [schema];
72204
+ }
72205
+ function expandArrayableSchema(schema) {
72206
+ const schemas = expandUnionSchema(schema);
72207
+ if (schemas.length !== 2) {
72208
+ return void 0;
72209
+ }
72210
+ const arraySchema = schemas.find(
72211
+ (s) => typeof s === "object" && s.type === "array" && Object.keys(s).filter((k) => LOGIC_KEYWORDS.includes(k)).every((k) => k === "type" || k === "items")
72212
+ );
72213
+ if (arraySchema === void 0) {
72214
+ return void 0;
72215
+ }
72216
+ const items1 = arraySchema.items;
72217
+ const items2 = schemas.find((s) => s !== arraySchema);
72218
+ if (stringifyJSON(items1) !== stringifyJSON(items2)) {
72219
+ return void 0;
72220
+ }
72221
+ return [items2, arraySchema];
72222
+ }
72223
+ var PRIMITIVE_SCHEMA_TYPES = /* @__PURE__ */ new Set([
72224
+ TypeName.String,
72225
+ TypeName.Number,
72226
+ TypeName.Integer,
72227
+ TypeName.Boolean,
72228
+ TypeName.Null
72229
+ ]);
72230
+ function isPrimitiveSchema(schema) {
72231
+ return expandUnionSchema(schema).every((s) => {
72232
+ if (typeof s === "boolean") {
72233
+ return false;
72234
+ }
72235
+ if (typeof s.type === "string" && PRIMITIVE_SCHEMA_TYPES.has(s.type)) {
72236
+ return true;
72237
+ }
72238
+ if (s.const !== void 0) {
72239
+ return true;
72240
+ }
72241
+ return false;
72242
+ });
72243
+ }
72244
+ function toOpenAPIPath(path46) {
72245
+ return standardizeHTTPPath(path46).replace(/\/\{\+([^}]+)\}/g, "/{$1}");
72246
+ }
72247
+ function toOpenAPIMethod(method) {
72248
+ return method.toLocaleLowerCase();
72249
+ }
72250
+ function toOpenAPIContent(schema) {
72251
+ const content = {};
72252
+ const [matches, restSchema] = filterSchemaBranches(schema, isFileSchema);
72253
+ for (const file2 of matches) {
72254
+ content[file2.contentMediaType] = {
72255
+ schema: toOpenAPISchema(file2)
72256
+ };
72257
+ }
72258
+ if (restSchema !== void 0 && !isAnySchema(restSchema) && !isNeverSchema(restSchema)) {
72259
+ content["application/json"] = {
72260
+ schema: toOpenAPISchema(restSchema)
72261
+ };
72262
+ const isStillHasFileSchema = findDeepMatches((v) => isObject4(v) && isFileSchema(v), restSchema).values.length > 0;
72263
+ if (isStillHasFileSchema) {
72264
+ content["multipart/form-data"] = {
72265
+ schema: toOpenAPISchema(restSchema)
72266
+ };
72267
+ }
72268
+ }
72269
+ return content;
72270
+ }
72271
+ function toOpenAPIEventIteratorContent([yieldsRequired, yieldsSchema], [returnsRequired, returnsSchema]) {
72272
+ return {
72273
+ "text/event-stream": {
72274
+ schema: toOpenAPISchema({
72275
+ oneOf: [
72276
+ {
72277
+ type: "object",
72278
+ properties: {
72279
+ event: { const: "message" },
72280
+ data: yieldsSchema,
72281
+ id: { type: "string" },
72282
+ retry: { type: "number" }
72283
+ },
72284
+ required: yieldsRequired ? ["event", "data"] : ["event"]
72285
+ },
72286
+ {
72287
+ type: "object",
72288
+ properties: {
72289
+ event: { const: "done" },
72290
+ data: returnsSchema,
72291
+ id: { type: "string" },
72292
+ retry: { type: "number" }
72293
+ },
72294
+ required: returnsRequired ? ["event", "data"] : ["event"]
72295
+ },
72296
+ {
72297
+ type: "object",
72298
+ properties: {
72299
+ event: { const: "error" },
72300
+ data: {},
72301
+ id: { type: "string" },
72302
+ retry: { type: "number" }
72303
+ },
72304
+ required: ["event"]
72305
+ }
72306
+ ]
72307
+ })
72308
+ }
72309
+ };
72310
+ }
72311
+ function toOpenAPIParameters(schema, parameterIn) {
72312
+ const parameters = [];
72313
+ for (const key in schema.properties) {
72314
+ const keySchema = schema.properties[key];
72315
+ let isDeepObjectStyle = true;
72316
+ if (parameterIn !== "query") {
72317
+ isDeepObjectStyle = false;
72318
+ } else if (isPrimitiveSchema(keySchema)) {
72319
+ isDeepObjectStyle = false;
72320
+ } else {
72321
+ const [item] = expandArrayableSchema(keySchema) ?? [];
72322
+ if (item !== void 0 && isPrimitiveSchema(item)) {
72323
+ isDeepObjectStyle = false;
72324
+ }
72325
+ }
72326
+ parameters.push({
72327
+ name: key,
72328
+ in: parameterIn,
72329
+ required: schema.required?.includes(key),
72330
+ schema: toOpenAPISchema(keySchema),
72331
+ style: isDeepObjectStyle ? "deepObject" : void 0,
72332
+ explode: isDeepObjectStyle ? true : void 0,
72333
+ allowEmptyValue: parameterIn === "query" ? true : void 0,
72334
+ allowReserved: parameterIn === "query" ? true : void 0
72335
+ });
72336
+ }
72337
+ return parameters;
72338
+ }
72339
+ function checkParamsSchema(schema, params) {
72340
+ const properties = Object.keys(schema.properties ?? {});
72341
+ const required2 = schema.required ?? [];
72342
+ if (properties.length !== params.length || properties.some((v) => !params.includes(v))) {
72343
+ return false;
72344
+ }
72345
+ if (required2.length !== params.length || required2.some((v) => !params.includes(v))) {
72346
+ return false;
72347
+ }
72348
+ return true;
72349
+ }
72350
+ function toOpenAPISchema(schema) {
72351
+ return schema === true ? {} : schema === false ? { not: {} } : schema;
72352
+ }
72353
+ var OPENAPI_JSON_SCHEMA_REF_PREFIX = "#/components/schemas/";
72354
+ function resolveOpenAPIJsonSchemaRef(doc, schema) {
72355
+ if (typeof schema !== "object" || !schema.$ref?.startsWith(OPENAPI_JSON_SCHEMA_REF_PREFIX)) {
72356
+ return schema;
72357
+ }
72358
+ const name = schema.$ref.slice(OPENAPI_JSON_SCHEMA_REF_PREFIX.length);
72359
+ const resolved = doc.components?.schemas?.[name];
72360
+ return resolved ?? schema;
72361
+ }
72362
+ function simplifyComposedObjectJsonSchemasAndRefs(schema, doc) {
72363
+ if (doc) {
72364
+ schema = resolveOpenAPIJsonSchemaRef(doc, schema);
72365
+ }
72366
+ if (typeof schema !== "object" || !schema.anyOf && !schema.oneOf && !schema.allOf) {
72367
+ return schema;
72368
+ }
72369
+ const unionSchemas = [
72370
+ ...toArray(schema.anyOf?.map((s) => simplifyComposedObjectJsonSchemasAndRefs(s, doc))),
72371
+ ...toArray(schema.oneOf?.map((s) => simplifyComposedObjectJsonSchemasAndRefs(s, doc)))
72372
+ ];
72373
+ const objectUnionSchemas = [];
72374
+ for (const u3 of unionSchemas) {
72375
+ if (!isObjectSchema(u3)) {
72376
+ return schema;
72377
+ }
72378
+ objectUnionSchemas.push(u3);
72379
+ }
72380
+ const mergedUnionPropertyMap = /* @__PURE__ */ new Map();
72381
+ for (const u3 of objectUnionSchemas) {
72382
+ if (u3.properties) {
72383
+ for (const [key, value2] of Object.entries(u3.properties)) {
72384
+ let entry = mergedUnionPropertyMap.get(key);
72385
+ if (!entry) {
72386
+ const required2 = objectUnionSchemas.every((s) => s.required?.includes(key));
72387
+ entry = { required: required2, schemas: [] };
72388
+ mergedUnionPropertyMap.set(key, entry);
72389
+ }
72390
+ entry.schemas.push(value2);
72391
+ }
72392
+ }
72393
+ }
72394
+ const intersectionSchemas = toArray(schema.allOf?.map((s) => simplifyComposedObjectJsonSchemasAndRefs(s, doc)));
72395
+ const objectIntersectionSchemas = [];
72396
+ for (const u3 of intersectionSchemas) {
72397
+ if (!isObjectSchema(u3)) {
72398
+ return schema;
72399
+ }
72400
+ objectIntersectionSchemas.push(u3);
72401
+ }
72402
+ if (isObjectSchema(schema)) {
72403
+ objectIntersectionSchemas.push(schema);
72404
+ }
72405
+ const mergedInteractionPropertyMap = /* @__PURE__ */ new Map();
72406
+ for (const u3 of objectIntersectionSchemas) {
72407
+ if (u3.properties) {
72408
+ for (const [key, value2] of Object.entries(u3.properties)) {
72409
+ let entry = mergedInteractionPropertyMap.get(key);
72410
+ if (!entry) {
72411
+ const required2 = objectIntersectionSchemas.some((s) => s.required?.includes(key));
72412
+ entry = { required: required2, schemas: [] };
72413
+ mergedInteractionPropertyMap.set(key, entry);
72414
+ }
72415
+ entry.schemas.push(value2);
72416
+ }
72417
+ }
72418
+ }
72419
+ const resultObjectSchema = { type: "object", properties: {}, required: [] };
72420
+ const keys = /* @__PURE__ */ new Set([
72421
+ ...mergedUnionPropertyMap.keys(),
72422
+ ...mergedInteractionPropertyMap.keys()
72423
+ ]);
72424
+ if (keys.size === 0) {
72425
+ return schema;
72426
+ }
72427
+ const deduplicateSchemas = (schemas) => {
72428
+ const seen = /* @__PURE__ */ new Set();
72429
+ const result = [];
72430
+ for (const schema2 of schemas) {
72431
+ const key = stringifyJSON(schema2);
72432
+ if (!seen.has(key)) {
72433
+ seen.add(key);
72434
+ result.push(schema2);
72435
+ }
72436
+ }
72437
+ return result;
72438
+ };
72439
+ for (const key of keys) {
72440
+ const unionEntry = mergedUnionPropertyMap.get(key);
72441
+ const intersectionEntry = mergedInteractionPropertyMap.get(key);
72442
+ resultObjectSchema.properties[key] = (() => {
72443
+ const dedupedUnionSchemas = unionEntry ? deduplicateSchemas(unionEntry.schemas) : [];
72444
+ const dedupedIntersectionSchemas = intersectionEntry ? deduplicateSchemas(intersectionEntry.schemas) : [];
72445
+ if (!dedupedUnionSchemas.length) {
72446
+ return dedupedIntersectionSchemas.length === 1 ? dedupedIntersectionSchemas[0] : { allOf: dedupedIntersectionSchemas };
72447
+ }
72448
+ if (!dedupedIntersectionSchemas.length) {
72449
+ return dedupedUnionSchemas.length === 1 ? dedupedUnionSchemas[0] : { anyOf: dedupedUnionSchemas };
72450
+ }
72451
+ const allOf = deduplicateSchemas([
72452
+ ...dedupedIntersectionSchemas,
72453
+ dedupedUnionSchemas.length === 1 ? dedupedUnionSchemas[0] : { anyOf: dedupedUnionSchemas }
72454
+ ]);
72455
+ return allOf.length === 1 ? allOf[0] : { allOf };
72456
+ })();
72457
+ if (unionEntry?.required || intersectionEntry?.required) {
72458
+ resultObjectSchema.required.push(key);
72459
+ }
72460
+ }
72461
+ return resultObjectSchema;
72462
+ }
72463
+ var CompositeSchemaConverter = class {
72464
+ converters;
72465
+ constructor(converters) {
72466
+ this.converters = converters;
72467
+ }
72468
+ async convert(schema, options) {
72469
+ for (const converter of this.converters) {
72470
+ if (await converter.condition(schema, options)) {
72471
+ return converter.convert(schema, options);
72472
+ }
72473
+ }
72474
+ return [false, {}];
72475
+ }
72476
+ };
72477
+ var OpenAPIGeneratorError = class extends Error {
72478
+ };
72479
+ var OpenAPIGenerator = class {
72480
+ serializer;
72481
+ converter;
72482
+ constructor(options = {}) {
72483
+ this.serializer = new StandardOpenAPIJsonSerializer(options);
72484
+ this.converter = new CompositeSchemaConverter(toArray(options.schemaConverters));
72485
+ }
72486
+ /**
72487
+ * Generates OpenAPI specifications from oRPC routers/contracts.
72488
+ *
72489
+ * @see {@link https://orpc.dev/docs/openapi/openapi-specification OpenAPI Specification Docs}
72490
+ */
72491
+ async generate(router, { customErrorResponseBodySchema, commonSchemas, filter: baseFilter, exclude, ...baseDoc } = {}) {
72492
+ const filter = baseFilter ?? (({ contract, path: path46 }) => {
72493
+ return !(exclude?.(contract, path46) ?? false);
72494
+ });
72495
+ const doc = {
72496
+ ...clone2(baseDoc),
72497
+ info: baseDoc.info ?? { title: "API Reference", version: "0.0.0" },
72498
+ openapi: "3.1.1"
72499
+ };
72500
+ const { baseSchemaConvertOptions, undefinedErrorJsonSchema } = await this.#resolveCommonSchemas(doc, commonSchemas);
72501
+ const contracts = [];
72502
+ await resolveContractProcedures({ path: [], router }, (traverseOptions) => {
72503
+ if (!value(filter, traverseOptions)) {
72504
+ return;
72505
+ }
72506
+ contracts.push(traverseOptions);
72507
+ });
72508
+ const errors = [];
72509
+ for (const { contract, path: path46 } of contracts) {
72510
+ const stringPath = path46.join(".");
72511
+ try {
72512
+ const def = contract["~orpc"];
72513
+ const method = toOpenAPIMethod(fallbackContractConfig("defaultMethod", def.route.method));
72514
+ const httpPath = toOpenAPIPath(def.route.path ?? toHttpPath(path46));
72515
+ let operationObjectRef;
72516
+ if (def.route.spec !== void 0 && typeof def.route.spec !== "function") {
72517
+ operationObjectRef = def.route.spec;
72518
+ } else {
72519
+ operationObjectRef = {
72520
+ operationId: def.route.operationId ?? stringPath,
72521
+ summary: def.route.summary,
72522
+ description: def.route.description,
72523
+ deprecated: def.route.deprecated,
72524
+ tags: def.route.tags?.map((tag) => tag)
72525
+ };
72526
+ await this.#request(doc, operationObjectRef, def, baseSchemaConvertOptions);
72527
+ await this.#successResponse(doc, operationObjectRef, def, baseSchemaConvertOptions);
72528
+ await this.#errorResponse(operationObjectRef, def, baseSchemaConvertOptions, undefinedErrorJsonSchema, customErrorResponseBodySchema);
72529
+ }
72530
+ if (typeof def.route.spec === "function") {
72531
+ operationObjectRef = def.route.spec(operationObjectRef);
72532
+ }
72533
+ doc.paths ??= {};
72534
+ doc.paths[httpPath] ??= {};
72535
+ doc.paths[httpPath][method] = applyCustomOpenAPIOperation(operationObjectRef, contract);
72536
+ } catch (e) {
72537
+ if (!(e instanceof OpenAPIGeneratorError)) {
72538
+ throw e;
72539
+ }
72540
+ errors.push(
72541
+ `[OpenAPIGenerator] Error occurred while generating OpenAPI for procedure at path: ${stringPath}
72542
+ ${e.message}`
72543
+ );
72544
+ }
72545
+ }
72546
+ if (errors.length) {
72547
+ throw new OpenAPIGeneratorError(
72548
+ `Some error occurred during OpenAPI generation:
72549
+
72550
+ ${errors.join("\n\n")}`
72551
+ );
72552
+ }
72553
+ return this.serializer.serialize(doc)[0];
72554
+ }
72555
+ async #resolveCommonSchemas(doc, commonSchemas) {
72556
+ let undefinedErrorJsonSchema = {
72557
+ type: "object",
72558
+ properties: {
72559
+ defined: { const: false },
72560
+ code: { type: "string" },
72561
+ status: { type: "number" },
72562
+ message: { type: "string" },
72563
+ data: {}
72564
+ },
72565
+ required: ["defined", "code", "status", "message"]
72566
+ };
72567
+ const baseSchemaConvertOptions = {};
72568
+ if (commonSchemas) {
72569
+ baseSchemaConvertOptions.components = [];
72570
+ for (const key in commonSchemas) {
72571
+ const options = commonSchemas[key];
72572
+ if (options.schema === void 0) {
72573
+ continue;
72574
+ }
72575
+ const { schema, strategy = "input" } = options;
72576
+ const [required2, json2] = await this.converter.convert(schema, { strategy });
72577
+ const allowedStrategies = [strategy];
72578
+ if (strategy === "input") {
72579
+ const [outputRequired, outputJson] = await this.converter.convert(schema, { strategy: "output" });
72580
+ if (outputRequired === required2 && stringifyJSON(outputJson) === stringifyJSON(json2)) {
72581
+ allowedStrategies.push("output");
72582
+ }
72583
+ } else if (strategy === "output") {
72584
+ const [inputRequired, inputJson] = await this.converter.convert(schema, { strategy: "input" });
72585
+ if (inputRequired === required2 && stringifyJSON(inputJson) === stringifyJSON(json2)) {
72586
+ allowedStrategies.push("input");
72587
+ }
72588
+ }
72589
+ baseSchemaConvertOptions.components.push({
72590
+ schema,
72591
+ required: required2,
72592
+ ref: `#/components/schemas/${key}`,
72593
+ allowedStrategies
72594
+ });
72595
+ }
72596
+ doc.components ??= {};
72597
+ doc.components.schemas ??= {};
72598
+ for (const key in commonSchemas) {
72599
+ const options = commonSchemas[key];
72600
+ if (options.schema === void 0) {
72601
+ if (options.error === "UndefinedError") {
72602
+ doc.components.schemas[key] = toOpenAPISchema(undefinedErrorJsonSchema);
72603
+ undefinedErrorJsonSchema = { $ref: `#/components/schemas/${key}` };
72604
+ }
72605
+ continue;
72606
+ }
72607
+ const { schema, strategy = "input" } = options;
72608
+ const [, json2] = await this.converter.convert(
72609
+ schema,
72610
+ {
72611
+ ...baseSchemaConvertOptions,
72612
+ strategy,
72613
+ minStructureDepthForRef: 1
72614
+ // not allow use $ref for root schemas
72615
+ }
72616
+ );
72617
+ doc.components.schemas[key] = toOpenAPISchema(json2);
72618
+ }
72619
+ }
72620
+ return { baseSchemaConvertOptions, undefinedErrorJsonSchema };
72621
+ }
72622
+ async #request(doc, ref, def, baseSchemaConvertOptions) {
72623
+ const method = fallbackContractConfig("defaultMethod", def.route.method);
72624
+ const details = getEventIteratorSchemaDetails(def.inputSchema);
72625
+ if (details) {
72626
+ ref.requestBody = {
72627
+ required: true,
72628
+ content: toOpenAPIEventIteratorContent(
72629
+ await this.converter.convert(details.yields, { ...baseSchemaConvertOptions, strategy: "input" }),
72630
+ await this.converter.convert(details.returns, { ...baseSchemaConvertOptions, strategy: "input" })
72631
+ )
72632
+ };
72633
+ return;
72634
+ }
72635
+ const dynamicParams = getDynamicParams(def.route.path)?.map((v) => v.name);
72636
+ const inputStructure = fallbackContractConfig("defaultInputStructure", def.route.inputStructure);
72637
+ let [required2, schema] = await this.converter.convert(
72638
+ def.inputSchema,
72639
+ {
72640
+ ...baseSchemaConvertOptions,
72641
+ strategy: "input"
72642
+ }
72643
+ );
72644
+ let omitResponseBody = false;
72645
+ if (isAnySchema(schema) && !dynamicParams?.length) {
72646
+ return;
72647
+ }
72648
+ if (inputStructure === "detailed" || inputStructure === "compact" && (dynamicParams?.length || method === "GET")) {
72649
+ schema = simplifyComposedObjectJsonSchemasAndRefs(schema, doc);
72650
+ }
72651
+ if (inputStructure === "compact") {
72652
+ if (dynamicParams?.length) {
72653
+ const error210 = new OpenAPIGeneratorError(
72654
+ 'When input structure is "compact", and path has dynamic params, input schema must be an object with all dynamic params as required.'
72655
+ );
72656
+ if (!isObjectSchema(schema)) {
72657
+ throw error210;
72658
+ }
72659
+ const [paramsSchema, rest] = separateObjectSchema(schema, dynamicParams);
72660
+ schema = rest;
72661
+ required2 = rest.required ? rest.required.length !== 0 : false;
72662
+ omitResponseBody = !required2 && !rest.properties;
72663
+ if (!checkParamsSchema(paramsSchema, dynamicParams)) {
72664
+ throw error210;
72665
+ }
72666
+ ref.parameters ??= [];
72667
+ ref.parameters.push(...toOpenAPIParameters(paramsSchema, "path"));
72668
+ }
72669
+ if (method === "GET") {
72670
+ if (!isObjectSchema(schema)) {
72671
+ throw new OpenAPIGeneratorError(
72672
+ 'When method is "GET", input schema must satisfy: object | any | unknown'
72673
+ );
72674
+ }
72675
+ ref.parameters ??= [];
72676
+ ref.parameters.push(...toOpenAPIParameters(schema, "query"));
72677
+ } else if (!omitResponseBody) {
72678
+ ref.requestBody = {
72679
+ required: required2,
72680
+ content: toOpenAPIContent(schema)
72681
+ };
72682
+ }
72683
+ return;
72684
+ }
72685
+ const error62 = new OpenAPIGeneratorError(
72686
+ 'When input structure is "detailed", input schema must satisfy: { params?: Record<string, unknown>, query?: Record<string, unknown>, headers?: Record<string, unknown>, body?: unknown }'
72687
+ );
72688
+ if (!isObjectSchema(schema)) {
72689
+ throw error62;
72690
+ }
72691
+ const resolvedParamSchema = schema.properties?.params !== void 0 ? simplifyComposedObjectJsonSchemasAndRefs(schema.properties.params, doc) : void 0;
72692
+ if (dynamicParams?.length && (resolvedParamSchema === void 0 || !isObjectSchema(resolvedParamSchema) || !checkParamsSchema(resolvedParamSchema, dynamicParams))) {
72693
+ throw new OpenAPIGeneratorError(
72694
+ 'When input structure is "detailed" and path has dynamic params, the "params" schema must be an object with all dynamic params as required.'
72695
+ );
72696
+ }
72697
+ for (const from of ["params", "query", "headers"]) {
72698
+ const fromSchema = schema.properties?.[from];
72699
+ if (fromSchema !== void 0) {
72700
+ const resolvedSchema = simplifyComposedObjectJsonSchemasAndRefs(fromSchema, doc);
72701
+ if (!isObjectSchema(resolvedSchema)) {
72702
+ throw error62;
72703
+ }
72704
+ const parameterIn = from === "params" ? "path" : from === "headers" ? "header" : "query";
72705
+ ref.parameters ??= [];
72706
+ ref.parameters.push(...toOpenAPIParameters(resolvedSchema, parameterIn));
72707
+ }
72708
+ }
72709
+ if (schema.properties?.body !== void 0) {
72710
+ ref.requestBody = {
72711
+ required: schema.required?.includes("body"),
72712
+ content: toOpenAPIContent(schema.properties.body)
72713
+ };
72714
+ }
72715
+ }
72716
+ async #successResponse(doc, ref, def, baseSchemaConvertOptions) {
72717
+ const outputSchema = def.outputSchema;
72718
+ const status = fallbackContractConfig("defaultSuccessStatus", def.route.successStatus);
72719
+ const description = fallbackContractConfig("defaultSuccessDescription", def.route?.successDescription);
72720
+ const eventIteratorSchemaDetails = getEventIteratorSchemaDetails(outputSchema);
72721
+ const outputStructure = fallbackContractConfig("defaultOutputStructure", def.route.outputStructure);
72722
+ if (eventIteratorSchemaDetails) {
72723
+ ref.responses ??= {};
72724
+ ref.responses[status] = {
72725
+ description,
72726
+ content: toOpenAPIEventIteratorContent(
72727
+ await this.converter.convert(eventIteratorSchemaDetails.yields, { ...baseSchemaConvertOptions, strategy: "output" }),
72728
+ await this.converter.convert(eventIteratorSchemaDetails.returns, { ...baseSchemaConvertOptions, strategy: "output" })
72729
+ )
72730
+ };
72731
+ return;
72732
+ }
72733
+ const [required2, json2] = await this.converter.convert(
72734
+ outputSchema,
72735
+ {
72736
+ ...baseSchemaConvertOptions,
72737
+ strategy: "output",
72738
+ minStructureDepthForRef: outputStructure === "detailed" ? 1 : 0
72739
+ }
72740
+ );
72741
+ if (outputStructure === "compact") {
72742
+ ref.responses ??= {};
72743
+ ref.responses[status] = {
72744
+ description
72745
+ };
72746
+ ref.responses[status].content = toOpenAPIContent(applySchemaOptionality(required2, json2));
72747
+ return;
72748
+ }
72749
+ const handledStatuses = /* @__PURE__ */ new Set();
72750
+ for (const item of expandUnionSchema(json2)) {
72751
+ const error62 = new OpenAPIGeneratorError(`
72752
+ When output structure is "detailed", output schema must satisfy:
72753
+ {
72754
+ status?: number, // must be a literal number and in the range of 200-399
72755
+ headers?: Record<string, unknown>,
72756
+ body?: unknown
72757
+ }
72758
+
72759
+ But got: ${stringifyJSON(item)}
72760
+ `);
72761
+ const simplifiedItem = simplifyComposedObjectJsonSchemasAndRefs(item, doc);
72762
+ if (!isObjectSchema(simplifiedItem)) {
72763
+ throw error62;
72764
+ }
72765
+ let schemaStatus;
72766
+ let schemaDescription;
72767
+ if (simplifiedItem.properties?.status !== void 0) {
72768
+ const statusSchema = resolveOpenAPIJsonSchemaRef(doc, simplifiedItem.properties.status);
72769
+ if (typeof statusSchema !== "object" || statusSchema.const === void 0 || typeof statusSchema.const !== "number" || !Number.isInteger(statusSchema.const) || isORPCErrorStatus(statusSchema.const)) {
72770
+ throw error62;
72771
+ }
72772
+ schemaStatus = statusSchema.const;
72773
+ schemaDescription = statusSchema.description;
72774
+ }
72775
+ const itemStatus = schemaStatus ?? status;
72776
+ const itemDescription = schemaDescription ?? description;
72777
+ if (handledStatuses.has(itemStatus)) {
72778
+ throw new OpenAPIGeneratorError(`
72779
+ When output structure is "detailed", each success status must be unique.
72780
+ But got status: ${itemStatus} used more than once.
72781
+ `);
72782
+ }
72783
+ handledStatuses.add(itemStatus);
72784
+ ref.responses ??= {};
72785
+ ref.responses[itemStatus] = {
72786
+ description: itemDescription
72787
+ };
72788
+ if (simplifiedItem.properties?.headers !== void 0) {
72789
+ const headersSchema = simplifyComposedObjectJsonSchemasAndRefs(simplifiedItem.properties.headers, doc);
72790
+ if (!isObjectSchema(headersSchema)) {
72791
+ throw error62;
72792
+ }
72793
+ for (const key in headersSchema.properties) {
72794
+ const headerSchema = headersSchema.properties[key];
72795
+ if (headerSchema !== void 0) {
72796
+ ref.responses[itemStatus].headers ??= {};
72797
+ ref.responses[itemStatus].headers[key] = {
72798
+ schema: toOpenAPISchema(headerSchema),
72799
+ required: simplifiedItem.required?.includes("headers") && headersSchema.required?.includes(key)
72800
+ };
72801
+ }
72802
+ }
72803
+ }
72804
+ if (simplifiedItem.properties?.body !== void 0) {
72805
+ ref.responses[itemStatus].content = toOpenAPIContent(
72806
+ applySchemaOptionality(simplifiedItem.required?.includes("body") ?? false, simplifiedItem.properties.body)
72807
+ );
72808
+ }
72809
+ }
72810
+ }
72811
+ async #errorResponse(ref, def, baseSchemaConvertOptions, undefinedErrorSchema, customErrorResponseBodySchema) {
72812
+ const errorMap = def.errorMap;
72813
+ const errorResponsesByStatus = {};
72814
+ for (const code in errorMap) {
72815
+ const config2 = errorMap[code];
72816
+ if (!config2) {
72817
+ continue;
72818
+ }
72819
+ const status = fallbackORPCErrorStatus(code, config2.status);
72820
+ const defaultMessage = fallbackORPCErrorMessage(code, config2.message);
72821
+ errorResponsesByStatus[status] ??= { status, definedErrorDefinitions: [], errorSchemaVariants: [] };
72822
+ const [dataRequired, dataSchema] = await this.converter.convert(config2.data, { ...baseSchemaConvertOptions, strategy: "output" });
72823
+ errorResponsesByStatus[status].definedErrorDefinitions.push([code, defaultMessage, dataRequired, dataSchema]);
72824
+ errorResponsesByStatus[status].errorSchemaVariants.push({
72825
+ type: "object",
72826
+ properties: {
72827
+ defined: { const: true },
72828
+ code: { const: code },
72829
+ status: { const: status },
72830
+ message: { type: "string", default: defaultMessage },
72831
+ data: dataSchema
72832
+ },
72833
+ required: dataRequired ? ["defined", "code", "status", "message", "data"] : ["defined", "code", "status", "message"]
72834
+ });
72835
+ }
72836
+ ref.responses ??= {};
72837
+ for (const statusString in errorResponsesByStatus) {
72838
+ const errorResponse2 = errorResponsesByStatus[statusString];
72839
+ const customBodySchema = value(customErrorResponseBodySchema, errorResponse2.definedErrorDefinitions, errorResponse2.status);
72840
+ ref.responses[statusString] = {
72841
+ description: statusString,
72842
+ content: toOpenAPIContent(customBodySchema ?? {
72843
+ oneOf: [
72844
+ ...errorResponse2.errorSchemaVariants,
72845
+ undefinedErrorSchema
72846
+ ]
72847
+ })
72848
+ };
72849
+ }
72850
+ }
72851
+ };
72852
+
71631
72853
  // node_modules/.pnpm/@orpc+standard-server-node@1.15.4/node_modules/@orpc/standard-server-node/dist/index.mjs
71632
72854
  var import_node_buffer = require("node:buffer");
71633
72855
  var import_node_stream = require("node:stream");
@@ -72156,21 +73378,386 @@ var RPCHandler = class extends NodeHttpHandler {
72156
73378
  }
72157
73379
  };
72158
73380
 
73381
+ // node_modules/.pnpm/rou3@0.7.12/node_modules/rou3/dist/index.mjs
73382
+ var NullProtoObj2 = /* @__PURE__ */ (() => {
73383
+ const e = function() {
73384
+ };
73385
+ return e.prototype = /* @__PURE__ */ Object.create(null), Object.freeze(e.prototype), e;
73386
+ })();
73387
+ function createRouter() {
73388
+ return {
73389
+ root: { key: "" },
73390
+ static: new NullProtoObj2()
73391
+ };
73392
+ }
73393
+ function splitPath(path46) {
73394
+ const [_, ...s] = path46.split("/");
73395
+ return s[s.length - 1] === "" ? s.slice(0, -1) : s;
73396
+ }
73397
+ function getMatchParams(segments, paramsMap) {
73398
+ const params = new NullProtoObj2();
73399
+ for (const [index, name] of paramsMap) {
73400
+ const segment = index < 0 ? segments.slice(-(index + 1)).join("/") : segments[index];
73401
+ if (typeof name === "string") params[name] = segment;
73402
+ else {
73403
+ const match = segment.match(name);
73404
+ if (match) for (const key in match.groups) params[key] = match.groups[key];
73405
+ }
73406
+ }
73407
+ return params;
73408
+ }
73409
+ function addRoute(ctx, method = "", path46, data) {
73410
+ method = method.toUpperCase();
73411
+ if (path46.charCodeAt(0) !== 47) path46 = `/${path46}`;
73412
+ path46 = path46.replace(/\\:/g, "%3A");
73413
+ const segments = splitPath(path46);
73414
+ let node2 = ctx.root;
73415
+ let _unnamedParamIndex = 0;
73416
+ const paramsMap = [];
73417
+ const paramsRegexp = [];
73418
+ for (let i2 = 0; i2 < segments.length; i2++) {
73419
+ let segment = segments[i2];
73420
+ if (segment.startsWith("**")) {
73421
+ if (!node2.wildcard) node2.wildcard = { key: "**" };
73422
+ node2 = node2.wildcard;
73423
+ paramsMap.push([
73424
+ -(i2 + 1),
73425
+ segment.split(":")[1] || "_",
73426
+ segment.length === 2
73427
+ ]);
73428
+ break;
73429
+ }
73430
+ if (segment === "*" || segment.includes(":")) {
73431
+ if (!node2.param) node2.param = { key: "*" };
73432
+ node2 = node2.param;
73433
+ if (segment === "*") paramsMap.push([
73434
+ i2,
73435
+ `_${_unnamedParamIndex++}`,
73436
+ true
73437
+ ]);
73438
+ else if (segment.includes(":", 1)) {
73439
+ const regexp = getParamRegexp(segment);
73440
+ paramsRegexp[i2] = regexp;
73441
+ node2.hasRegexParam = true;
73442
+ paramsMap.push([
73443
+ i2,
73444
+ regexp,
73445
+ false
73446
+ ]);
73447
+ } else paramsMap.push([
73448
+ i2,
73449
+ segment.slice(1),
73450
+ false
73451
+ ]);
73452
+ continue;
73453
+ }
73454
+ if (segment === "\\*") segment = segments[i2] = "*";
73455
+ else if (segment === "\\*\\*") segment = segments[i2] = "**";
73456
+ const child = node2.static?.[segment];
73457
+ if (child) node2 = child;
73458
+ else {
73459
+ const staticNode = { key: segment };
73460
+ if (!node2.static) node2.static = new NullProtoObj2();
73461
+ node2.static[segment] = staticNode;
73462
+ node2 = staticNode;
73463
+ }
73464
+ }
73465
+ const hasParams = paramsMap.length > 0;
73466
+ if (!node2.methods) node2.methods = new NullProtoObj2();
73467
+ node2.methods[method] ??= [];
73468
+ node2.methods[method].push({
73469
+ data: data || null,
73470
+ paramsRegexp,
73471
+ paramsMap: hasParams ? paramsMap : void 0
73472
+ });
73473
+ if (!hasParams) ctx.static["/" + segments.join("/")] = node2;
73474
+ }
73475
+ function getParamRegexp(segment) {
73476
+ const regex = segment.replace(/:(\w+)/g, (_, id) => `(?<${id}>[^/]+)`).replace(/\./g, "\\.");
73477
+ return /* @__PURE__ */ new RegExp(`^${regex}$`);
73478
+ }
73479
+ function findRoute(ctx, method = "", path46, opts) {
73480
+ if (path46.charCodeAt(path46.length - 1) === 47) path46 = path46.slice(0, -1);
73481
+ const staticNode = ctx.static[path46];
73482
+ if (staticNode && staticNode.methods) {
73483
+ const staticMatch = staticNode.methods[method] || staticNode.methods[""];
73484
+ if (staticMatch !== void 0) return staticMatch[0];
73485
+ }
73486
+ const segments = splitPath(path46);
73487
+ const match = _lookupTree(ctx, ctx.root, method, segments, 0)?.[0];
73488
+ if (match === void 0) return;
73489
+ if (opts?.params === false) return match;
73490
+ return {
73491
+ data: match.data,
73492
+ params: match.paramsMap ? getMatchParams(segments, match.paramsMap) : void 0
73493
+ };
73494
+ }
73495
+ function _lookupTree(ctx, node2, method, segments, index) {
73496
+ if (index === segments.length) {
73497
+ if (node2.methods) {
73498
+ const match = node2.methods[method] || node2.methods[""];
73499
+ if (match) return match;
73500
+ }
73501
+ if (node2.param && node2.param.methods) {
73502
+ const match = node2.param.methods[method] || node2.param.methods[""];
73503
+ if (match) {
73504
+ const pMap = match[0].paramsMap;
73505
+ if (pMap?.[pMap?.length - 1]?.[2]) return match;
73506
+ }
73507
+ }
73508
+ if (node2.wildcard && node2.wildcard.methods) {
73509
+ const match = node2.wildcard.methods[method] || node2.wildcard.methods[""];
73510
+ if (match) {
73511
+ const pMap = match[0].paramsMap;
73512
+ if (pMap?.[pMap?.length - 1]?.[2]) return match;
73513
+ }
73514
+ }
73515
+ return;
73516
+ }
73517
+ const segment = segments[index];
73518
+ if (node2.static) {
73519
+ const staticChild = node2.static[segment];
73520
+ if (staticChild) {
73521
+ const match = _lookupTree(ctx, staticChild, method, segments, index + 1);
73522
+ if (match) return match;
73523
+ }
73524
+ }
73525
+ if (node2.param) {
73526
+ const match = _lookupTree(ctx, node2.param, method, segments, index + 1);
73527
+ if (match) {
73528
+ if (node2.param.hasRegexParam) {
73529
+ const exactMatch = match.find((m2) => m2.paramsRegexp[index]?.test(segment)) || match.find((m2) => !m2.paramsRegexp[index]);
73530
+ return exactMatch ? [exactMatch] : void 0;
73531
+ }
73532
+ return match;
73533
+ }
73534
+ }
73535
+ if (node2.wildcard && node2.wildcard.methods) return node2.wildcard.methods[method] || node2.wildcard.methods[""];
73536
+ }
73537
+
73538
+ // node_modules/.pnpm/@orpc+openapi@1.15.4/node_modules/@orpc/openapi/dist/shared/openapi.DPiCV5hl.mjs
73539
+ var StandardOpenAPICodec = class {
73540
+ constructor(serializer, options = {}) {
73541
+ this.serializer = serializer;
73542
+ this.customErrorResponseBodyEncoder = options.customErrorResponseBodyEncoder;
73543
+ }
73544
+ customErrorResponseBodyEncoder;
73545
+ async decode(request7, params, procedure) {
73546
+ const inputStructure = fallbackContractConfig("defaultInputStructure", procedure["~orpc"].route.inputStructure);
73547
+ if (inputStructure === "compact") {
73548
+ const data = request7.method === "GET" ? this.serializer.deserialize(request7.url.searchParams) : this.serializer.deserialize(await request7.body());
73549
+ if (data === void 0) {
73550
+ return params;
73551
+ }
73552
+ if (isObject4(data)) {
73553
+ return {
73554
+ ...params,
73555
+ ...data
73556
+ };
73557
+ }
73558
+ return data;
73559
+ }
73560
+ const deserializeSearchParams = () => {
73561
+ return this.serializer.deserialize(request7.url.searchParams);
73562
+ };
73563
+ return {
73564
+ params,
73565
+ get query() {
73566
+ const value2 = deserializeSearchParams();
73567
+ Object.defineProperty(this, "query", { value: value2, writable: true });
73568
+ return value2;
73569
+ },
73570
+ set query(value2) {
73571
+ Object.defineProperty(this, "query", { value: value2, writable: true });
73572
+ },
73573
+ headers: request7.headers,
73574
+ body: this.serializer.deserialize(await request7.body())
73575
+ };
73576
+ }
73577
+ encode(output2, procedure) {
73578
+ const successStatus = fallbackContractConfig("defaultSuccessStatus", procedure["~orpc"].route.successStatus);
73579
+ const outputStructure = fallbackContractConfig("defaultOutputStructure", procedure["~orpc"].route.outputStructure);
73580
+ if (outputStructure === "compact") {
73581
+ if (output2 instanceof ReadableStream) {
73582
+ return {
73583
+ status: successStatus,
73584
+ headers: {},
73585
+ body: output2
73586
+ };
73587
+ }
73588
+ return {
73589
+ status: successStatus,
73590
+ headers: {},
73591
+ body: this.serializer.serialize(output2)
73592
+ };
73593
+ }
73594
+ if (!this.#isDetailedOutput(output2)) {
73595
+ throw new Error(`
73596
+ Invalid "detailed" output structure:
73597
+ \u2022 Expected an object with optional properties:
73598
+ - status (number 200-399)
73599
+ - headers (Record<string, string | string[]>)
73600
+ - body (any)
73601
+ \u2022 No extra keys allowed.
73602
+
73603
+ Actual value:
73604
+ ${stringifyJSON(output2)}
73605
+ `);
73606
+ }
73607
+ if (output2.body instanceof ReadableStream) {
73608
+ return {
73609
+ status: output2.status ?? successStatus,
73610
+ headers: output2.headers ?? {},
73611
+ body: output2.body
73612
+ };
73613
+ }
73614
+ return {
73615
+ status: output2.status ?? successStatus,
73616
+ headers: output2.headers ?? {},
73617
+ body: this.serializer.serialize(output2.body)
73618
+ };
73619
+ }
73620
+ encodeError(error62) {
73621
+ const body = this.customErrorResponseBodyEncoder?.(error62) ?? error62.toJSON();
73622
+ return {
73623
+ status: error62.status,
73624
+ headers: {},
73625
+ body: this.serializer.serialize(body, { outputFormat: "plain" })
73626
+ };
73627
+ }
73628
+ #isDetailedOutput(output2) {
73629
+ if (!isObject4(output2)) {
73630
+ return false;
73631
+ }
73632
+ if (output2.headers && !isObject4(output2.headers)) {
73633
+ return false;
73634
+ }
73635
+ if (output2.status !== void 0 && (typeof output2.status !== "number" || !Number.isInteger(output2.status) || isORPCErrorStatus(output2.status))) {
73636
+ return false;
73637
+ }
73638
+ return true;
73639
+ }
73640
+ };
73641
+ function toRou3Pattern(path46) {
73642
+ return standardizeHTTPPath(path46).replace(/\/\{\+([^}]+)\}/g, "/**:$1").replace(/\/\{([^}]+)\}/g, "/:$1");
73643
+ }
73644
+ function decodeParams(params) {
73645
+ return Object.fromEntries(Object.entries(params).map(([key, value2]) => [key, tryDecodeURIComponent(value2)]));
73646
+ }
73647
+ var StandardOpenAPIMatcher = class {
73648
+ filter;
73649
+ tree = createRouter();
73650
+ pendingRouters = [];
73651
+ constructor(options = {}) {
73652
+ this.filter = options.filter ?? true;
73653
+ }
73654
+ init(router, path46 = []) {
73655
+ const laziedOptions = traverseContractProcedures({ router, path: path46 }, (traverseOptions) => {
73656
+ if (!value(this.filter, traverseOptions)) {
73657
+ return;
73658
+ }
73659
+ const { path: path210, contract } = traverseOptions;
73660
+ const method = fallbackContractConfig("defaultMethod", contract["~orpc"].route.method);
73661
+ const httpPath = toRou3Pattern(contract["~orpc"].route.path ?? toHttpPath(path210));
73662
+ if (isProcedure(contract)) {
73663
+ addRoute(this.tree, method, httpPath, {
73664
+ path: path210,
73665
+ contract,
73666
+ procedure: contract,
73667
+ // this mean dev not used contract-first so we can used contract as procedure directly
73668
+ router
73669
+ });
73670
+ } else {
73671
+ addRoute(this.tree, method, httpPath, {
73672
+ path: path210,
73673
+ contract,
73674
+ procedure: void 0,
73675
+ router
73676
+ });
73677
+ }
73678
+ });
73679
+ this.pendingRouters.push(...laziedOptions.map((option) => ({
73680
+ ...option,
73681
+ httpPathPrefix: toHttpPath(option.path),
73682
+ laziedPrefix: getLazyMeta(option.router).prefix
73683
+ })));
73684
+ }
73685
+ async match(method, pathname) {
73686
+ while (true) {
73687
+ const pendingRouter = this.pendingRouters.find(
73688
+ (pendingRouter2) => !pendingRouter2.laziedPrefix || pathname.startsWith(pendingRouter2.laziedPrefix) || pathname.startsWith(pendingRouter2.httpPathPrefix)
73689
+ );
73690
+ if (!pendingRouter) {
73691
+ break;
73692
+ }
73693
+ pendingRouter.initPromise ??= unlazy(pendingRouter.router).then(({ default: router }) => {
73694
+ this.init(router, pendingRouter.path);
73695
+ this.pendingRouters.splice(this.pendingRouters.indexOf(pendingRouter), 1);
73696
+ }).catch((error62) => {
73697
+ pendingRouter.initPromise = void 0;
73698
+ throw error62;
73699
+ });
73700
+ await pendingRouter.initPromise;
73701
+ }
73702
+ const match = findRoute(this.tree, method, pathname);
73703
+ if (!match) {
73704
+ return void 0;
73705
+ }
73706
+ if (!match.data.procedure) {
73707
+ const { default: maybeProcedure } = await unlazy(getRouter(match.data.router, match.data.path));
73708
+ if (!isProcedure(maybeProcedure)) {
73709
+ throw new Error(`
73710
+ [Contract-First] Missing or invalid implementation for procedure at path: ${toHttpPath(match.data.path)}.
73711
+ Ensure that the procedure is correctly defined and matches the expected contract.
73712
+ `);
73713
+ }
73714
+ match.data.procedure = createContractedProcedure(maybeProcedure, match.data.contract);
73715
+ }
73716
+ return {
73717
+ path: match.data.path,
73718
+ procedure: match.data.procedure,
73719
+ params: match.params ? decodeParams(match.params) : void 0
73720
+ };
73721
+ }
73722
+ };
73723
+ var StandardOpenAPIHandler = class extends StandardHandler {
73724
+ constructor(router, options) {
73725
+ const jsonSerializer = new StandardOpenAPIJsonSerializer(options);
73726
+ const bracketNotationSerializer = new StandardBracketNotationSerializer(options);
73727
+ const serializer = new StandardOpenAPISerializer(jsonSerializer, bracketNotationSerializer);
73728
+ const matcher = new StandardOpenAPIMatcher(options);
73729
+ const codec2 = new StandardOpenAPICodec(serializer, options);
73730
+ super(router, matcher, codec2, options);
73731
+ }
73732
+ };
73733
+
73734
+ // node_modules/.pnpm/@orpc+openapi@1.15.4/node_modules/@orpc/openapi/dist/adapters/node/index.mjs
73735
+ var OpenAPIHandler = class extends NodeHttpHandler {
73736
+ constructor(router, options = {}) {
73737
+ super(new StandardOpenAPIHandler(router, options), options);
73738
+ }
73739
+ };
73740
+
72159
73741
  // src/frontdoor/rcApi.ts
72160
73742
  var import_undici2 = __toESM(require_undici(), 1);
72161
73743
  var RC_ORPC_PATH_PREFIX = "/__agent-shim/orpc";
73744
+ var RC_OPENAPI_DOC_PATH = "/openapi.json";
72162
73745
  var RC_SUBSCRIBER_BUFFER_EVENTS = 100;
73746
+ function doorApiBearer(headers) {
73747
+ const presented = headers.authorization;
73748
+ const bearerPrefix = "bearer ".length;
73749
+ return typeof presented === "string" && presented.slice(0, bearerPrefix).toLowerCase() === "bearer " ? presented.slice(bearerPrefix) : void 0;
73750
+ }
72163
73751
  function doorApiAuth(expectedToken) {
72164
73752
  return os7.$context().use(({ context, next }) => {
72165
- const presented = context.headers.authorization;
72166
- const bearerPrefix = "bearer ".length;
72167
- const token = typeof presented === "string" && presented.slice(0, bearerPrefix).toLowerCase() === "bearer " ? presented.slice(bearerPrefix) : void 0;
73753
+ const token = doorApiBearer(context.headers);
72168
73754
  if (token === void 0 || !isLiveCapability(token, [expectedToken])) {
72169
73755
  throw new ORPCError("UNAUTHORIZED", { message: "the front door's typed API demands this generation's control token as a Bearer credential" });
72170
73756
  }
72171
73757
  return next();
72172
73758
  });
72173
73759
  }
73760
+ var RC_API_TAG = "remote-control";
72174
73761
  function createRcApiRouter(deps) {
72175
73762
  const authed = doorApiAuth(deps.expectedToken);
72176
73763
  const delivered = (sessionId, result) => {
@@ -72190,41 +73777,41 @@ function createRcApiRouter(deps) {
72190
73777
  };
72191
73778
  return {
72192
73779
  rc: {
72193
- list: authed.output(RcListOutputSchema).handler(() => ({ sessions: deps.list() })),
72194
- status: authed.input(RcSessionQuerySchema).output(RcStatusOutputSchema).handler(({ input: input2 }) => {
73780
+ list: authed.route({ method: "GET", path: "/rest/rc/sessions", summary: "List the observed Remote Control sessions", tags: [RC_API_TAG] }).output(RcListOutputSchema).handler(() => ({ sessions: deps.list() })),
73781
+ status: authed.route({ method: "GET", path: "/rest/rc/status", summary: "Read session status, one session's when named", tags: [RC_API_TAG] }).input(RcSessionQuerySchema).output(RcStatusOutputSchema).handler(({ input: input2 }) => {
72195
73782
  const statuses = deps.statusOf(input2.session);
72196
73783
  if (input2.session !== void 0 && !statuses.some((entry) => entry.id === input2.session)) {
72197
73784
  throw new ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input2.session) });
72198
73785
  }
72199
73786
  return { statuses };
72200
73787
  }),
72201
- pending: authed.input(RcSessionQuerySchema).output(RcPendingOutputSchema).handler(({ input: input2 }) => {
73788
+ pending: authed.route({ method: "GET", path: "/rest/rc/pending", summary: "Read the control requests awaiting an answer", tags: [RC_API_TAG] }).input(RcSessionQuerySchema).output(RcPendingOutputSchema).handler(({ input: input2 }) => {
72202
73789
  const pending = deps.pendingOf(input2.session);
72203
73790
  if (input2.session !== void 0 && deps.statusOf(input2.session).length === 0) {
72204
73791
  throw new ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input2.session) });
72205
73792
  }
72206
73793
  return { pending };
72207
73794
  }),
72208
- send: authed.input(RcSendInputSchema).output(RcWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, sequenceNums: delivered(input2.session, await deps.inject(input2.session, input2.text)) })),
72209
- answer: authed.input(RcAnswerInputSchema).output(RcAnswerOutputSchema).handler(async ({ input: input2 }) => {
73795
+ send: authed.route({ method: "POST", path: "/rest/rc/send", summary: "Send one message into a session", tags: [RC_API_TAG] }).input(RcSendInputSchema).output(RcWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, sequenceNums: delivered(input2.session, await deps.inject(input2.session, input2.text)) })),
73796
+ answer: authed.route({ method: "POST", path: "/rest/rc/answer", summary: "Answer one pending control request", tags: [RC_API_TAG] }).input(RcAnswerInputSchema).output(RcAnswerOutputSchema).handler(async ({ input: input2 }) => {
72210
73797
  const decision = { approve: input2.approve, message: input2.approve || input2.text === void 0 ? void 0 : input2.text };
72211
73798
  return { session: input2.session, request: input2.request, sequenceNums: delivered(input2.session, await deps.answer(input2.session, input2.request, decision)) };
72212
73799
  }),
72213
- interrupt: authed.input(RcInterruptInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.interrupt(input2.session)) })),
72214
- setModel: authed.input(RcSetModelInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.setModel(input2.session, input2.model)) })),
72215
- setPermissionMode: authed.input(RcSetPermissionModeInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.setPermissionMode(input2.session, input2.mode)) })),
72216
- endSession: authed.input(RcEndSessionInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.endSession(input2.session, input2.reason)) })),
72217
- getUsage: authed.input(RcGetUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.getUsage(input2.session, input2.skipBehaviors)) })),
72218
- getContextUsage: authed.input(RcGetContextUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.getContextUsage(input2.session, input2.detail)) })),
72219
- readFile: authed.input(RcReadFileInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.readFile(input2.session, input2.path, { ...input2.maxBytes === void 0 ? {} : { maxBytes: input2.maxBytes }, ...input2.encoding === void 0 ? {} : { encoding: input2.encoding } })) })),
72220
- fileSuggestions: authed.input(RcFileSuggestionsInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.fileSuggestions(input2.session, input2.query)) })),
72221
- keepAlive: authed.input(RcKeepAliveInputSchema).output(RcWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, sequenceNums: delivered(input2.session, await deps.keepAlive(input2.session)) })),
72222
- mcpStatus: authed.input(RcMcpStatusInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.mcpStatus(input2.session)) })),
72223
- mcpReconnect: authed.input(RcMcpReconnectInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.mcpReconnect(input2.session, input2.serverName)) })),
72224
- mcpAuthenticate: authed.input(RcMcpAuthenticateInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.mcpAuthenticate(input2.session, input2.serverName, input2.redirectUri)) })),
72225
- mcpOAuthCallbackUrl: authed.input(RcMcpOAuthCallbackUrlInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.mcpOAuthCallbackUrl(input2.session, input2.serverName, input2.callbackUrl)) })),
72226
- teleport: authed.input(RcTeleportInputSchema).output(RcWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, sequenceNums: delivered(input2.session, await deps.teleport(input2.session, input2.marker)) })),
72227
- subscribe: authed.input(RcSessionQuerySchema).output(eventIterator(RcStreamEventSchema)).handler(async function* ({ input: input2, signal }) {
73800
+ interrupt: authed.route({ method: "POST", path: "/rest/rc/interrupt", summary: "Interrupt a session's running turn", tags: [RC_API_TAG] }).input(RcInterruptInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.interrupt(input2.session)) })),
73801
+ setModel: authed.route({ method: "POST", path: "/rest/rc/set-model", summary: "Switch a session's model", tags: [RC_API_TAG] }).input(RcSetModelInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.setModel(input2.session, input2.model)) })),
73802
+ setPermissionMode: authed.route({ method: "POST", path: "/rest/rc/set-permission-mode", summary: "Switch a session's permission mode", tags: [RC_API_TAG] }).input(RcSetPermissionModeInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.setPermissionMode(input2.session, input2.mode)) })),
73803
+ endSession: authed.route({ method: "POST", path: "/rest/rc/end-session", summary: "End a session", tags: [RC_API_TAG] }).input(RcEndSessionInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.endSession(input2.session, input2.reason)) })),
73804
+ getUsage: authed.route({ method: "POST", path: "/rest/rc/get-usage", summary: "Ask a session for its usage snapshot", tags: [RC_API_TAG] }).input(RcGetUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.getUsage(input2.session, input2.skipBehaviors)) })),
73805
+ getContextUsage: authed.route({ method: "POST", path: "/rest/rc/get-context-usage", summary: "Ask a session for its context usage", tags: [RC_API_TAG] }).input(RcGetContextUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.getContextUsage(input2.session, input2.detail)) })),
73806
+ readFile: authed.route({ method: "POST", path: "/rest/rc/read-file", summary: "Ask a session to read one file", tags: [RC_API_TAG] }).input(RcReadFileInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.readFile(input2.session, input2.path, { ...input2.maxBytes === void 0 ? {} : { maxBytes: input2.maxBytes }, ...input2.encoding === void 0 ? {} : { encoding: input2.encoding } })) })),
73807
+ fileSuggestions: authed.route({ method: "POST", path: "/rest/rc/file-suggestions", summary: "Ask a session for file-path suggestions", tags: [RC_API_TAG] }).input(RcFileSuggestionsInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.fileSuggestions(input2.session, input2.query)) })),
73808
+ keepAlive: authed.route({ method: "POST", path: "/rest/rc/keep-alive", summary: "Keep a session's bridge alive", tags: [RC_API_TAG] }).input(RcKeepAliveInputSchema).output(RcWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, sequenceNums: delivered(input2.session, await deps.keepAlive(input2.session)) })),
73809
+ mcpStatus: authed.route({ method: "POST", path: "/rest/rc/mcp-status", summary: "Ask a session for its MCP servers' status", tags: [RC_API_TAG] }).input(RcMcpStatusInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.mcpStatus(input2.session)) })),
73810
+ mcpReconnect: authed.route({ method: "POST", path: "/rest/rc/mcp-reconnect", summary: "Ask a session to reconnect one MCP server", tags: [RC_API_TAG] }).input(RcMcpReconnectInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.mcpReconnect(input2.session, input2.serverName)) })),
73811
+ mcpAuthenticate: authed.route({ method: "POST", path: "/rest/rc/mcp-authenticate", summary: "Start OAuth for one MCP server on a session", tags: [RC_API_TAG] }).input(RcMcpAuthenticateInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.mcpAuthenticate(input2.session, input2.serverName, input2.redirectUri)) })),
73812
+ mcpOAuthCallbackUrl: authed.route({ method: "POST", path: "/rest/rc/mcp-oauth-callback-url", summary: "Hand a completed MCP OAuth callback to a session", tags: [RC_API_TAG] }).input(RcMcpOAuthCallbackUrlInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, ...deliveredControl(input2.session, await deps.mcpOAuthCallbackUrl(input2.session, input2.serverName, input2.callbackUrl)) })),
73813
+ teleport: authed.route({ method: "POST", path: "/rest/rc/teleport", summary: "Teleport a session to a conversation marker", tags: [RC_API_TAG] }).input(RcTeleportInputSchema).output(RcWriteOutputSchema).handler(async ({ input: input2 }) => ({ session: input2.session, sequenceNums: delivered(input2.session, await deps.teleport(input2.session, input2.marker)) })),
73814
+ subscribe: authed.route({ method: "GET", path: "/rest/rc/events", summary: "Stream a session's Remote Control events (SSE)", tags: [RC_API_TAG] }).input(RcSessionQuerySchema).output(eventIterator(RcStreamEventSchema)).handler(async function* ({ input: input2, signal }) {
72228
73815
  const queue = [];
72229
73816
  let wake;
72230
73817
  const detach = deps.fanout.subscribe(input2.session, (event) => {
@@ -72261,11 +73848,40 @@ function createRcApiRouter(deps) {
72261
73848
  }
72262
73849
  };
72263
73850
  }
72264
- function doorApiNodeHandlerOf(router) {
72265
- const handler = new RPCHandler(router, { plugins: [new BodyLimitPlugin({ maxBodySize: CONTROL_BODY_CAP_BYTES })] });
73851
+ function doorApiNodeHandlerOf(router, expectedToken) {
73852
+ const plugins = [new BodyLimitPlugin({ maxBodySize: CONTROL_BODY_CAP_BYTES })];
73853
+ const rpcHandler = new RPCHandler(router, { plugins });
73854
+ const restHandler = new OpenAPIHandler(router, { plugins });
73855
+ let document;
73856
+ const documentOf = async () => document ??= new OpenAPIGenerator().generate(router, { info: { title: "agent-shim front door API", version: package_default.version } });
72266
73857
  return {
72267
73858
  pathPrefix: RC_ORPC_PATH_PREFIX,
72268
- handle: async (request7, response) => await handler.handle(request7, response, { context: { headers: request7.headers }, prefix: RC_ORPC_PATH_PREFIX })
73859
+ handle: async (request7, response) => {
73860
+ if (request7.method === "GET" && request7.url === `${RC_ORPC_PATH_PREFIX}${RC_OPENAPI_DOC_PATH}`) {
73861
+ const token = doorApiBearer(request7.headers);
73862
+ if (token === void 0 || !isLiveCapability(token, [expectedToken])) {
73863
+ const refusal = new ORPCError("UNAUTHORIZED", { message: "the front door's OpenAPI document demands this generation's control token as a Bearer credential" });
73864
+ response.writeHead(HTTP_STATUS.unauthorized, { "content-type": "application/json" });
73865
+ response.end(JSON.stringify(refusal.toJSON()));
73866
+ return { matched: true };
73867
+ }
73868
+ try {
73869
+ const doc = await documentOf();
73870
+ response.writeHead(HTTP_STATUS.ok, { "content-type": "application/json" });
73871
+ response.end(JSON.stringify(doc));
73872
+ } catch (error62) {
73873
+ const refusal = new ORPCError("INTERNAL_SERVER_ERROR", { message: `the OpenAPI document could not be generated from the door's own router: ${error62 instanceof Error ? error62.message : String(error62)}` });
73874
+ response.writeHead(HTTP_STATUS.internalServerError, { "content-type": "application/json" });
73875
+ response.end(JSON.stringify(refusal.toJSON()));
73876
+ }
73877
+ return { matched: true };
73878
+ }
73879
+ const rest = await restHandler.handle(request7, response, { context: { headers: request7.headers }, prefix: RC_ORPC_PATH_PREFIX });
73880
+ if (rest.matched) {
73881
+ return rest;
73882
+ }
73883
+ return await rpcHandler.handle(request7, response, { context: { headers: request7.headers }, prefix: RC_ORPC_PATH_PREFIX });
73884
+ }
72269
73885
  };
72270
73886
  }
72271
73887
  function frontDoorApiLink(port, ca, token) {
@@ -72311,11 +73927,12 @@ var LaunchLifecycleEventSchema = external_exports.strictObject({
72311
73927
  });
72312
73928
 
72313
73929
  // src/frontdoor/eventsApi.ts
73930
+ var EVENTS_API_TAG = "events";
72314
73931
  function createEventsApiRouter(deps) {
72315
73932
  const authed = doorApiAuth(deps.expectedToken);
72316
73933
  return {
72317
73934
  events: {
72318
- subscribe: authed.input(DoorEventSourceQuerySchema).output(eventIterator(DoorEventSchema)).handler(async function* ({ input: input2, signal }) {
73935
+ subscribe: authed.route({ method: "GET", path: "/rest/events", summary: "Stream the door's every event source (SSE)", tags: [EVENTS_API_TAG] }).input(DoorEventSourceQuerySchema).output(eventIterator(DoorEventSchema)).handler(async function* ({ input: input2, signal }) {
72319
73936
  if (input2.sources !== void 0) {
72320
73937
  const live = deps.events.sources();
72321
73938
  const unknown2 = input2.sources.filter((source) => !live.includes(source));
@@ -72348,12 +73965,17 @@ function createEventsApiRouter(deps) {
72348
73965
  }
72349
73966
 
72350
73967
  // src/frontdoor/controlApi.ts
73968
+ var USAGE_API_TAG = "usage";
73969
+ var FRONTDOOR_API_TAG = "frontdoor";
73970
+ var CHECK_API_TAG = "check";
73971
+ var DOCTOR_API_TAG = "doctor";
73972
+ var POOL_API_TAG = "pool";
72351
73973
  function createControlApiRouter(deps) {
72352
73974
  const authed = doorApiAuth(deps.expectedToken);
72353
73975
  return {
72354
73976
  usage: {
72355
- list: authed.output(UsageListOutputSchema).handler(() => ({ snapshots: deps.usageSnapshots() })),
72356
- effectiveWindow: authed.input(UsageWindowsInputSchema).output(UsageWindowsOutputSchema).handler(({ input: input2 }) => {
73977
+ list: authed.route({ method: "GET", path: "/rest/usage/snapshots", summary: "List every identity's usage snapshot", tags: [USAGE_API_TAG] }).output(UsageListOutputSchema).handler(() => ({ snapshots: deps.usageSnapshots() })),
73978
+ effectiveWindow: authed.route({ method: "GET", path: "/rest/usage/windows", summary: "Read one identity's effective quota windows", tags: [USAGE_API_TAG] }).input(UsageWindowsInputSchema).output(UsageWindowsOutputSchema).handler(({ input: input2 }) => {
72357
73979
  const snapshot = deps.usageSnapshotOf(input2.identity);
72358
73980
  if (snapshot === void 0) {
72359
73981
  throw new ORPCError("NOT_FOUND", { message: `identity ${input2.identity} has no usage snapshot yet, so no quota window has been observed for it` });
@@ -72370,7 +73992,7 @@ function createControlApiRouter(deps) {
72370
73992
  ...unified?.sevenDay === void 0 ? {} : { sevenDay: effectiveWindow(unified.sevenDay, now) }
72371
73993
  };
72372
73994
  }),
72373
- live: authed.input(RcSessionQuerySchema).output(UsageLiveOutputSchema).handler(({ input: input2 }) => {
73995
+ live: authed.route({ method: "GET", path: "/rest/usage/live", summary: "Read the live rate-limit observations the event backbone files", tags: [USAGE_API_TAG] }).input(RcSessionQuerySchema).output(UsageLiveOutputSchema).handler(({ input: input2 }) => {
72374
73996
  const sessions = deps.liveRateLimits(input2.session);
72375
73997
  if (input2.session !== void 0 && sessions.length === 0) {
72376
73998
  if (deps.list().some((session) => session.id === input2.session)) {
@@ -72382,15 +74004,27 @@ function createControlApiRouter(deps) {
72382
74004
  })
72383
74005
  },
72384
74006
  frontdoor: {
72385
- status: authed.output(FrontDoorStatusOutputSchema).handler(() => deps.frontDoorStatus()),
72386
- sessions: authed.output(FrontDoorSessionsOutputSchema).handler(() => ({ sessions: deps.frontDoorStatus().sessions }))
74007
+ status: authed.route({ method: "GET", path: "/rest/frontdoor/status", summary: "Read the front door's status", tags: [FRONTDOOR_API_TAG] }).output(FrontDoorStatusOutputSchema).handler(() => deps.frontDoorStatus()),
74008
+ sessions: authed.route({ method: "GET", path: "/rest/frontdoor/sessions", summary: "Read the front door's session registry", tags: [FRONTDOOR_API_TAG] }).output(FrontDoorSessionsOutputSchema).handler(() => ({ sessions: deps.frontDoorStatus().sessions }))
72387
74009
  },
72388
74010
  check: {
72389
74011
  // The report's own JSON shape is the contract (the same one `check --json` prints and `checkReportSchema.ts` defines), so the procedure returns exactly that conversion.
72390
- run: authed.input(CheckRunInputSchema).output(CheckReportJsonSchema).handler(({ input: input2 }) => checkReportToJson(deps.checkReport(input2.path, input2.identity)))
74012
+ run: authed.route({ method: "GET", path: "/rest/check", summary: "Run the check report for one directory", tags: [CHECK_API_TAG] }).input(CheckRunInputSchema).output(CheckReportJsonSchema).handler(({ input: input2 }) => checkReportToJson(deps.checkReport(input2.path, input2.identity)))
72391
74013
  },
72392
74014
  doctor: {
72393
- run: authed.output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
74015
+ run: authed.route({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] }).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
74016
+ },
74017
+ pool: {
74018
+ pick: authed.route({ method: "GET", path: "/rest/pool/pick", summary: "Rank one pool exactly as a launch from a directory would right now", tags: [POOL_API_TAG] }).input(PoolPickInputSchema).output(PoolPickReportSchema).handler(({ input: input2 }) => {
74019
+ const report = deps.poolPick(input2.pool, input2.path);
74020
+ if (report === void 0) {
74021
+ const live = deps.poolNames();
74022
+ throw new ORPCError("NOT_FOUND", {
74023
+ message: live.length === 0 ? `no pools are configured, so none is named ${input2.pool}` : `no pool is named ${input2.pool}; the live pools are ${live.map((name) => `"${name}"`).join(", ")}`
74024
+ });
74025
+ }
74026
+ return report;
74027
+ })
72394
74028
  }
72395
74029
  };
72396
74030
  }
@@ -72398,7 +74032,7 @@ function createDoorApiRouter(deps) {
72398
74032
  return { ...createRcApiRouter(deps), ...createControlApiRouter(deps), ...createEventsApiRouter(deps) };
72399
74033
  }
72400
74034
  function createDoorApiNodeHandler(deps) {
72401
- return doorApiNodeHandlerOf(createDoorApiRouter(deps));
74035
+ return doorApiNodeHandlerOf(createDoorApiRouter(deps), deps.expectedToken);
72402
74036
  }
72403
74037
 
72404
74038
  // src/frontdoor/eventHub.ts
@@ -72689,10 +74323,10 @@ function createRoutedResponse(response, context) {
72689
74323
  let headersSent = false;
72690
74324
  let bodyObservers = [];
72691
74325
  let finished = false;
72692
- const observeBody = (call) => {
74326
+ const observeBody = (call2) => {
72693
74327
  bodyObservers = bodyObservers.filter((observer) => {
72694
74328
  try {
72695
- call(observer);
74329
+ call2(observer);
72696
74330
  return true;
72697
74331
  } catch (error62) {
72698
74332
  deps.log(`front door: response body observer threw for ${route}: ${describeThrown(error62)}`);
@@ -76997,7 +78631,13 @@ function realFrontDoorSupervisorPorts(paths) {
76997
78631
  now: () => Date.now(),
76998
78632
  frontDoorStatus: () => collectFrontDoorStatus(realFarmFs, realHeadroomSocketTrust, paths, realIsProcessRunning),
76999
78633
  checkReport: (target, identity) => collectCheckReport({ paths, cwd: target, ...identity === void 0 ? {} : { identity }, env: process.env }),
77000
- doctorReport: () => collectDoctorReport({ paths, env: process.env })
78634
+ doctorReport: () => collectDoctorReport({ paths, env: process.env }),
78635
+ // The pool table is read per call, not captured here, so a pool created or removed after the door started is ranked or refused by its live name the same moment the CLI would see it.
78636
+ poolPick: (pool, directory) => {
78637
+ const pools = readPools(paths);
78638
+ return pools[pool] === void 0 ? void 0 : collectPoolPick({ paths, fs: realFsPort, usageFs: realFarmFs, poolName: pool, pools, directory, nowMs: Date.now() });
78639
+ },
78640
+ poolNames: () => Object.keys(readPools(paths)).sort()
77001
78641
  };
77002
78642
  realFarmFs.mkdirp(paths.frontdoorDir);
77003
78643
  realFarmFs.writeFilePrivate(paths.frontdoorControlTokenFile, `${rcControlToken}