integration-tour 1.0.6 → 1.0.8

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 (3) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +938 -408
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -2938,46 +2938,46 @@ function compiledPattern(pattern) {
2938
2938
  var DATE = /^(\d{4})-(\d{2})-(\d{2})$/;
2939
2939
  var TIME = /^(\d{2}):(\d{2}):(\d{2})(\.\d+)?(z|[+-]\d{2}(:?\d{2})?)$/i;
2940
2940
  var FORMATS = {
2941
- "date-time": (text2) => {
2942
- const [date, time] = text2.split(/t|\s/i);
2941
+ "date-time": (text3) => {
2942
+ const [date, time] = text3.split(/t|\s/i);
2943
2943
  return time !== void 0 && FORMATS.date(date) && FORMATS.time(time);
2944
2944
  },
2945
- date: (text2) => {
2946
- const m = text2.match(DATE);
2945
+ date: (text3) => {
2946
+ const m = text3.match(DATE);
2947
2947
  if (!m) return false;
2948
2948
  const month = Number(m[2]);
2949
2949
  const day = Number(m[3]);
2950
2950
  return month >= 1 && month <= 12 && day >= 1 && day <= new Date(Date.UTC(Number(m[1]), month, 0)).getUTCDate();
2951
2951
  },
2952
- time: (text2) => {
2953
- const m = text2.match(TIME);
2952
+ time: (text3) => {
2953
+ const m = text3.match(TIME);
2954
2954
  return Boolean(m) && Number(m[1]) <= 23 && Number(m[2]) <= 59 && Number(m[3]) <= 60;
2955
2955
  },
2956
- email: (text2) => /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test(text2),
2957
- uri: (text2) => /^[a-z][a-z0-9+.-]*:[^\s]*$/i.test(text2) && !/\s/.test(text2),
2958
- url: (text2) => /^[a-z][a-z0-9+.-]*:\/\/[^\s]+$/i.test(text2),
2956
+ email: (text3) => /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test(text3),
2957
+ uri: (text3) => /^[a-z][a-z0-9+.-]*:[^\s]*$/i.test(text3) && !/\s/.test(text3),
2958
+ url: (text3) => /^[a-z][a-z0-9+.-]*:\/\/[^\s]+$/i.test(text3),
2959
2959
  // Neither holds what RFC 3986 leaves out of a URI (a template's {expressions} aside): a placeholder's brackets, quotes, spaces.
2960
- "uri-reference": (text2) => !/[\s<>"\\^`{}|]/.test(text2),
2961
- "uri-template": (text2) => !/[\s<>"\\^`|]/.test(text2),
2962
- uuid: (text2) => /^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i.test(text2),
2963
- ipv4: (text2) => /^((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/.test(text2),
2964
- ipv6: (text2) => /^[0-9a-f:.]+$/i.test(text2) && text2.includes(":") && (text2.match(/::/g) ?? []).length <= 1,
2965
- hostname: (text2) => text2.length <= 253 && /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*\.?$/i.test(text2),
2966
- byte: (text2) => /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(text2),
2967
- duration: (text2) => /^P(?!$)(\d+(?:\.\d+)?Y)?(\d+(?:\.\d+)?M)?(\d+(?:\.\d+)?W)?(\d+(?:\.\d+)?D)?(T(?=\d)(\d+(?:\.\d+)?H)?(\d+(?:\.\d+)?M)?(\d+(?:\.\d+)?S)?)?$/.test(text2),
2968
- regex: (text2) => {
2960
+ "uri-reference": (text3) => !/[\s<>"\\^`{}|]/.test(text3),
2961
+ "uri-template": (text3) => !/[\s<>"\\^`|]/.test(text3),
2962
+ uuid: (text3) => /^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i.test(text3),
2963
+ ipv4: (text3) => /^((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/.test(text3),
2964
+ ipv6: (text3) => /^[0-9a-f:.]+$/i.test(text3) && text3.includes(":") && (text3.match(/::/g) ?? []).length <= 1,
2965
+ hostname: (text3) => text3.length <= 253 && /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*\.?$/i.test(text3),
2966
+ byte: (text3) => /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(text3),
2967
+ duration: (text3) => /^P(?!$)(\d+(?:\.\d+)?Y)?(\d+(?:\.\d+)?M)?(\d+(?:\.\d+)?W)?(\d+(?:\.\d+)?D)?(T(?=\d)(\d+(?:\.\d+)?H)?(\d+(?:\.\d+)?M)?(\d+(?:\.\d+)?S)?)?$/.test(text3),
2968
+ regex: (text3) => {
2969
2969
  try {
2970
- new RegExp(text2);
2970
+ new RegExp(text3);
2971
2971
  return true;
2972
2972
  } catch {
2973
2973
  return false;
2974
2974
  }
2975
2975
  },
2976
- "json-pointer": (text2) => /^(?:\/(?:[^~/]|~0|~1)*)*$/.test(text2)
2976
+ "json-pointer": (text3) => /^(?:\/(?:[^~/]|~0|~1)*)*$/.test(text3)
2977
2977
  };
2978
- function formatFits(format, text2) {
2978
+ function formatFits(format, text3) {
2979
2979
  const test = FORMATS[format];
2980
- return test ? test(text2) : true;
2980
+ return test ? test(text3) : true;
2981
2981
  }
2982
2982
 
2983
2983
  // ../../lib/oas/examples.ts
@@ -3045,10 +3045,10 @@ function documentedExample(media, kind) {
3045
3045
  }
3046
3046
  return void 0;
3047
3047
  }
3048
- function exampleValue(example, text2) {
3048
+ function exampleValue(example, text3) {
3049
3049
  if (!example || typeof example !== "object") return void 0;
3050
3050
  const serialized = typeof example.serializedValue === "string" ? example.serializedValue : void 0;
3051
- if (text2 && serialized !== void 0) return serialized;
3051
+ if (text3 && serialized !== void 0) return serialized;
3052
3052
  if (example.dataValue !== void 0) return example.dataValue;
3053
3053
  return example.value !== void 0 ? example.value : serialized;
3054
3054
  }
@@ -3144,24 +3144,24 @@ function writeXml(lines, name, value, schema2, depth, root = false) {
3144
3144
  const properties = propertiesOf(schema2);
3145
3145
  const attributes = [];
3146
3146
  const children = [];
3147
- let text2;
3147
+ let text3;
3148
3148
  for (const [key, child] of Object.entries(value)) {
3149
3149
  const prop = properties[key];
3150
3150
  const nodeType = prop?.xml?.nodeType ?? (prop?.xml?.attribute ? "attribute" : void 0);
3151
3151
  if (nodeType === "attribute") {
3152
3152
  if (child !== null && child !== void 0) attributes.push(` ${xmlName(prop?.xml?.name ?? key, prop)}="${escapeXml(String(child), true)}"`);
3153
3153
  } else if (nodeType === "text" || nodeType === "cdata") {
3154
- text2 = nodeType === "cdata" ? `<![CDATA[${String(child)}]]>` : escapeXml(String(child));
3154
+ text3 = nodeType === "cdata" ? `<![CDATA[${String(child)}]]>` : escapeXml(String(child));
3155
3155
  } else {
3156
3156
  children.push([key, child, prop]);
3157
3157
  }
3158
3158
  }
3159
3159
  const open = `${pad}<${qname}${namespaceAttr(schema2)}${attributes.join("")}`;
3160
3160
  if (!children.length) {
3161
- lines.push(text2 === void 0 ? `${open}/>` : `${open}>${text2}</${qname}>`);
3161
+ lines.push(text3 === void 0 ? `${open}/>` : `${open}>${text3}</${qname}>`);
3162
3162
  return;
3163
3163
  }
3164
- lines.push(`${open}>${text2 ?? ""}`);
3164
+ lines.push(`${open}>${text3 ?? ""}`);
3165
3165
  for (const [key, child, prop] of children) writeXml(lines, key, child, prop, depth + 1);
3166
3166
  lines.push(`${pad}</${qname}>`);
3167
3167
  }
@@ -3182,9 +3182,9 @@ function namespaceAttr(schema2) {
3182
3182
  if (!ns) return "";
3183
3183
  return ` xmlns${schema2?.xml?.prefix ? `:${schema2.xml.prefix}` : ""}="${escapeXml(ns, true)}"`;
3184
3184
  }
3185
- function escapeXml(text2, attribute = false) {
3186
- if (isPlaceholder(text2)) return `{${text2.slice(1, -1)}}`;
3187
- const out = text2.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
3185
+ function escapeXml(text3, attribute = false) {
3186
+ if (isPlaceholder(text3)) return `{${text3.slice(1, -1)}}`;
3187
+ const out = text3.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
3188
3188
  return attribute ? out.replace(/"/g, "&quot;") : out;
3189
3189
  }
3190
3190
  function isRecord2(value) {
@@ -3303,9 +3303,9 @@ function saysSomething(schema2, depth = 0) {
3303
3303
  const target = circularTarget(schema2);
3304
3304
  const parts = [...schema2.allOf ?? [], ...schema2.oneOf ?? [], ...schema2.anyOf ?? [], ...target ? [target] : []];
3305
3305
  const inside2 = [...Object.values(schema2.properties ?? {}), ...schema2.items && typeof schema2.items === "object" ? [schema2.items] : [], ...schema2.prefixItems ?? []];
3306
- const usable2 = (part) => part && typeof part === "object" && part.type !== "null";
3306
+ const usable3 = (part) => part && typeof part === "object" && part.type !== "null";
3307
3307
  const own = depth === 0 ? givesValue(schema2) : schema2.example !== void 0 || Array.isArray(schema2.examples) && schema2.examples.length > 0;
3308
- const says = own || parts.some((part) => usable2(part) && saysSomething(part, depth)) || inside2.some((part) => usable2(part) && saysSomething(part, depth + 1));
3308
+ const says = own || parts.some((part) => usable3(part) && saysSomething(part, depth)) || inside2.some((part) => usable3(part) && saysSomething(part, depth + 1));
3309
3309
  found[depth] = says;
3310
3310
  return says;
3311
3311
  }
@@ -3556,11 +3556,11 @@ function enumValue(values, description) {
3556
3556
  return ordered.find((v) => typeof v !== "string" || !ENDINGS.test(v)) ?? ordered[0] ?? values[0];
3557
3557
  }
3558
3558
  function fromVariant(schema2, variants, name, depth, mode, budget, owner) {
3559
- const usable2 = variants.filter((v) => v && typeof v === "object" && v.type !== "null" && Object.keys(v).some((k) => !/^(description|title|nullable)$/.test(k)));
3560
- const first = schema2.properties && usable2.find((v) => v.properties || v.type === "object") || usable2[0] || variants[0];
3559
+ const usable3 = variants.filter((v) => v && typeof v === "object" && v.type !== "null" && Object.keys(v).some((k) => !/^(description|title|nullable)$/.test(k)));
3560
+ const first = schema2.properties && usable3.find((v) => v.properties || v.type === "object") || usable3[0] || variants[0];
3561
3561
  const exclusive = Boolean(schema2.oneOf?.length);
3562
3562
  let made;
3563
- for (const variant of [first, ...usable2.filter((v) => v !== first)].slice(0, MAX_TRIES)) {
3563
+ for (const variant of [first, ...usable3.filter((v) => v !== first)].slice(0, MAX_TRIES)) {
3564
3564
  const value = fromOneVariant(schema2, variants, variant, exclusive, name, depth, mode, budget, owner);
3565
3565
  if (made === void 0) made = value;
3566
3566
  if (fits(value, schema2, mode)) return value;
@@ -3747,9 +3747,9 @@ function patternExample(pattern) {
3747
3747
  return void 0;
3748
3748
  }
3749
3749
  const readable = [pattern, ...REPEATED_GROUP2.test(pattern) ? [] : [withoutLookarounds(pattern)]];
3750
- for (const text2 of readable) {
3751
- if (text2 === void 0) continue;
3752
- const node2 = parsePattern(text2);
3750
+ for (const text3 of readable) {
3751
+ if (text3 === void 0) continue;
3752
+ const node2 = parsePattern(text3);
3753
3753
  if (!node2) continue;
3754
3754
  const value = sample(node2, { next: 0 });
3755
3755
  if (value !== void 0 && value.length <= 200 && whole.test(value)) return value;
@@ -3818,11 +3818,11 @@ function parsePattern(pattern) {
3818
3818
  } else if (c === "[") {
3819
3819
  const close = pattern.indexOf("]", pattern[i + 1] === "]" ? i + 2 : i + 1);
3820
3820
  if (close < 0) return fail();
3821
- const text2 = pattern.slice(i, close + 1);
3821
+ const text3 = pattern.slice(i, close + 1);
3822
3822
  i = close + 1;
3823
3823
  let set2;
3824
3824
  try {
3825
- set2 = new RegExp(`^${text2}$`);
3825
+ set2 = new RegExp(`^${text3}$`);
3826
3826
  } catch {
3827
3827
  return fail();
3828
3828
  }
@@ -3923,7 +3923,7 @@ function uuidLike(name) {
3923
3923
  function idWords(name) {
3924
3924
  const all = name.replace(/[_-]?(uu|s|g)?id$/i, "").replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z])([A-Z][a-z])/g, "$1_$2").toLowerCase().split(/[^a-z]+/).filter(Boolean);
3925
3925
  const kept = all.filter((w) => !ID_NOISE.test(w));
3926
- return (kept.length ? kept : all).map((w, i, list6) => i === list6.length - 1 ? singular(w) : w);
3926
+ return (kept.length ? kept : all).map((w, i, list7) => i === list7.length - 1 ? singular(w) : w);
3927
3927
  }
3928
3928
  function seedHash(seed) {
3929
3929
  let h = 2166136261;
@@ -4078,8 +4078,8 @@ function formPart(part) {
4078
4078
  if (part.name.includes("=")) return `--form-string ${shellQuote(`${part.name}=${value}`, true)}`;
4079
4079
  if (part.file) return `-F ${shellQuote(`${part.name}=${value}`, true)}`;
4080
4080
  if (part.type) {
4081
- const text2 = readsMore(value) ? `"${value.replace(/[\\"]/g, "\\$&")}"` : value;
4082
- return `-F '${escapeSingle(`${part.name}=${text2}${formType(part.type)}`)}'`;
4081
+ const text3 = readsMore(value) ? `"${value.replace(/[\\"]/g, "\\$&")}"` : value;
4082
+ return `-F '${escapeSingle(`${part.name}=${text3}${formType(part.type)}`)}'`;
4083
4083
  }
4084
4084
  return `${readsMore(value) ? "--form-string" : "-F"} ${shellQuote(`${part.name}=${value}`, true)}`;
4085
4085
  }
@@ -4089,19 +4089,19 @@ function formType(type2) {
4089
4089
  const kept = params.filter((p) => /^[\w.+-]+=[^\s"\\]*$/.test(p) && !/^(type|filename|headers|encoder)=/i.test(p));
4090
4090
  return `;type=${[essence, ...kept].join("; ")}`;
4091
4091
  }
4092
- function readsMore(text2) {
4093
- return /^[@<"\s]|;|\s$/.test(text2);
4092
+ function readsMore(text3) {
4093
+ return /^[@<"\s]|;|\s$/.test(text3);
4094
4094
  }
4095
4095
  function quotedData(lines) {
4096
4096
  const body = lines.map(escapeSingle);
4097
4097
  return body.length === 1 ? [` -d '${body[0]}'`] : [` -d '${body[0]}`, ...body.slice(1, -1).map((l) => ` ${l}`), ` ${body.at(-1)}'`];
4098
4098
  }
4099
- function shellQuote(text2, always = false) {
4100
- if (!always && !/[^\w@%+=:,./-]/.test(text2)) return text2;
4101
- return /["\\$`!]/.test(text2) ? `'${escapeSingle(text2)}'` : `"${text2}"`;
4099
+ function shellQuote(text3, always = false) {
4100
+ if (!always && !/[^\w@%+=:,./-]/.test(text3)) return text3;
4101
+ return /["\\$`!]/.test(text3) ? `'${escapeSingle(text3)}'` : `"${text3}"`;
4102
4102
  }
4103
- function escapeSingle(text2) {
4104
- return text2.replace(/'/g, `'\\''`);
4103
+ function escapeSingle(text3) {
4104
+ return text3.replace(/'/g, `'\\''`);
4105
4105
  }
4106
4106
  function javascript(req) {
4107
4107
  const kind = bodyKind(req);
@@ -4130,8 +4130,8 @@ function javascript(req) {
4130
4130
  body = ["body: file,"];
4131
4131
  } else if (kind === "text") {
4132
4132
  headers.push(["Content-Type", req.contentType ?? "text/plain"]);
4133
- const text2 = String(req.body);
4134
- body = text2.includes("\n") ? wrapLines("body: `", text2.replace(/[`\\]|\$\{/g, (m) => `\\${m}`).split("\n"), "`,") : [`body: ${jsString(text2)},`];
4133
+ const text3 = String(req.body);
4134
+ body = text3.includes("\n") ? wrapLines("body: `", text3.replace(/[`\\]|\$\{/g, (m) => `\\${m}`).split("\n"), "`,") : [`body: ${jsString(text3)},`];
4135
4135
  }
4136
4136
  const options = [
4137
4137
  ...req.method === "GET" ? [] : [`method: ${jsString(req.method)},`],
@@ -4141,8 +4141,8 @@ function javascript(req) {
4141
4141
  if (!options.length) return [...lines, `await fetch(${jsString(req.url)});`];
4142
4142
  return [...lines, `await fetch(${jsString(req.url)}, {`, ...options.map((l) => ` ${l}`), "});"];
4143
4143
  }
4144
- function jsString(text2) {
4145
- return JSON.stringify(text2);
4144
+ function jsString(text3) {
4145
+ return JSON.stringify(text3);
4146
4146
  }
4147
4147
  var PYTHON_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
4148
4148
  function python(req) {
@@ -4165,7 +4165,7 @@ function python(req) {
4165
4165
  const files = typed.length ? typed : parts;
4166
4166
  const fields = typed.length ? parts.filter((p) => !p.file && !p.type) : [];
4167
4167
  const file = (p) => p.file ? `open(${jsString(filePath(p.name))}, "rb")` : p.type ? `(None, ${jsString(p.text)}, ${jsString(p.type)})` : `(None, ${jsString(p.text)})`;
4168
- const twice = (list6) => new Set(list6.map((p) => p.name)).size < list6.length;
4168
+ const twice = (list7) => new Set(list7.map((p) => p.name)).size < list7.length;
4169
4169
  if (files.length) {
4170
4170
  args.push(twice(files) ? ["files=[", ...files.map((p) => ` (${jsString(p.name)}, ${file(p)}),`), "],"] : ["files={", ...files.map((p) => ` ${jsString(p.name)}: ${file(p)},`), "},"]);
4171
4171
  }
@@ -4174,8 +4174,8 @@ function python(req) {
4174
4174
  }
4175
4175
  } else if (kind === "binary") args.push([`data=open("file", "rb"),`]);
4176
4176
  else if (kind === "text") {
4177
- const text2 = String(req.body);
4178
- args.push(text2.includes("\n") ? wrapLines('data="""', text2.replace(/\\/g, "\\\\").replace(/"""/g, '\\"\\"\\"').split("\n"), '""",') : [`data=${jsString(text2)},`]);
4177
+ const text3 = String(req.body);
4178
+ args.push(text3.includes("\n") ? wrapLines('data="""', text3.replace(/\\/g, "\\\\").replace(/"""/g, '\\"\\"\\"').split("\n"), '""",') : [`data=${jsString(text3)},`]);
4179
4179
  }
4180
4180
  const call = PYTHON_METHODS.has(req.method) ? `requests.${req.method.toLowerCase()}(` : `requests.request(${jsString(req.method)},`;
4181
4181
  return [call, ...args.flat().map((l) => ` ${l}`), ")"];
@@ -4233,10 +4233,10 @@ function mcpWire(sb, scene, http) {
4233
4233
  }
4234
4234
  return [`curl ${shellQuote(sb.api.baseUrl)} \\`, ...headers.map(([n, v]) => ` -H ${shellQuote(`${n}: ${v}`, true)} \\`), ` --json '${escapeSingle(body)}'`];
4235
4235
  }
4236
- function headerValue(text2) {
4237
- const plain = /^[\x21-\x7e]([\x20-\x7e\t]*[\x21-\x7e])?$/.test(text2) && !/^=\?base64\?.*\?=$/.test(text2);
4238
- if (plain) return text2;
4239
- const bytes = new TextEncoder().encode(text2);
4236
+ function headerValue(text3) {
4237
+ const plain = /^[\x21-\x7e]([\x20-\x7e\t]*[\x21-\x7e])?$/.test(text3) && !/^=\?base64\?.*\?=$/.test(text3);
4238
+ if (plain) return text3;
4239
+ const bytes = new TextEncoder().encode(text3);
4240
4240
  let binary2 = "";
4241
4241
  for (const byte of bytes) binary2 += String.fromCharCode(byte);
4242
4242
  return `=?base64?${btoa(binary2)}?=`;
@@ -4309,23 +4309,23 @@ function wrapLines(head, lines, tail) {
4309
4309
  return [`${head}${lines[0]}`, ...lines.slice(1, -1), `${lines.at(-1)}${tail}`];
4310
4310
  }
4311
4311
  function pretty(value, as, indent) {
4312
- const text2 = JSON.stringify(value, null, indent) ?? "null";
4313
- if (as === "json") return text2.split("\n");
4314
- return text2.split("\n").map((line) => line.replace(/("(?:[^"\\]|\\.)*")|\b(true|false|null)\b/g, (_, str2, word) => str2 ?? { true: "True", false: "False", null: "None" }[word]));
4312
+ const text3 = JSON.stringify(value, null, indent) ?? "null";
4313
+ if (as === "json") return text3.split("\n");
4314
+ return text3.split("\n").map((line) => line.replace(/("(?:[^"\\]|\\.)*")|\b(true|false|null)\b/g, (_, str2, word) => str2 ?? { true: "True", false: "False", null: "None" }[word]));
4315
4315
  }
4316
4316
 
4317
4317
  // ../../lib/text.ts
4318
- function cut(text2, max) {
4318
+ function cut(text3, max) {
4319
4319
  const end = Math.max(0, max);
4320
- const last = text2.charCodeAt(end - 1);
4321
- return text2.slice(0, last >= 55296 && last <= 56319 ? end - 1 : end);
4320
+ const last = text3.charCodeAt(end - 1);
4321
+ return text3.slice(0, last >= 55296 && last <= 56319 ? end - 1 : end);
4322
4322
  }
4323
4323
  var HALVES = /[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDFFF]/g;
4324
- function wellFormed(text2) {
4325
- return text2.replace(HALVES, (c) => c.length === 2 ? c : "");
4324
+ function wellFormed(text3) {
4325
+ return text3.replace(HALVES, (c) => c.length === 2 ? c : "");
4326
4326
  }
4327
- function clip(text2, max) {
4328
- return text2.length > max ? `${cut(text2, max - 1)}\u2026` : text2;
4327
+ function clip(text3, max) {
4328
+ return text3.length > max ? `${cut(text3, max - 1)}\u2026` : text3;
4329
4329
  }
4330
4330
  function plainText(markdown) {
4331
4331
  return markdown.replace(/<[^>]+>/g, " ").replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\*\*|__|`/g, "").replace(/(^|\s)[*_]([^*_\s][^*_]*?)[*_](?=[\s.,;:!?)]|$)/g, "$1$2").replace(/^\s{0,3}(#{1,6}|>)\s+/gm, "").replace(/\s+/g, " ").trim();
@@ -4664,8 +4664,8 @@ function grid(L) {
4664
4664
  }
4665
4665
  return `<path d="${dots.join("")}" stroke="${C.panelEdge}" stroke-width="2" stroke-linecap="round" opacity="0.5"/>`;
4666
4666
  }
4667
- function stepLabel(L, text2, color) {
4668
- return `<text x="${L.caption.x}" y="${L.caption.y - L.caption.size - 10}" font-size="${L.stepSize}" font-weight="600" letter-spacing="1.5" fill="${color}">${esc(text2.toUpperCase())}</text>`;
4667
+ function stepLabel(L, text3, color) {
4668
+ return `<text x="${L.caption.x}" y="${L.caption.y - L.caption.size - 10}" font-size="${L.stepSize}" font-weight="600" letter-spacing="1.5" fill="${color}">${esc(text3.toUpperCase())}</text>`;
4669
4669
  }
4670
4670
  function captionText(L, caption) {
4671
4671
  const { x, y } = L.caption;
@@ -4700,10 +4700,10 @@ function lane(L) {
4700
4700
  const [x2, y2] = L.lane.to;
4701
4701
  return `<line x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" stroke="${C.panelEdge}" stroke-width="2" stroke-dasharray="6 8"/>`;
4702
4702
  }
4703
- function laneLabel(L, text2) {
4703
+ function laneLabel(L, text3) {
4704
4704
  const [x1, y1] = L.lane.from;
4705
4705
  const [x2] = L.lane.to;
4706
- return `<text x="${(x1 + x2) / 2}" y="${y1 - 16}" text-anchor="middle" font-family="${esc(MONO)}" font-size="16" fill="${C.muted}">${esc(fit(text2, x2 - x1 - 40, 16, true))}</text>`;
4706
+ return `<text x="${(x1 + x2) / 2}" y="${y1 - 16}" text-anchor="middle" font-family="${esc(MONO)}" font-size="16" fill="${C.muted}">${esc(fit(text3, x2 - x1 - 40, 16, true))}</text>`;
4707
4707
  }
4708
4708
  function packet(from, to, t, color) {
4709
4709
  const x = from[0] + (to[0] - from[0]) * t;
@@ -4732,17 +4732,17 @@ function card(L, header, color, value, note, opacity, { code, fold, form } = {})
4732
4732
  out.push(`</g>`);
4733
4733
  return out.join("");
4734
4734
  }
4735
- function badge(box2, text2, color, opacity) {
4735
+ function badge(box2, text3, color, opacity) {
4736
4736
  const size2 = 15;
4737
- const w = Math.min(box2.w, textWidth(text2, size2, true) + 28);
4737
+ const w = Math.min(box2.w, textWidth(text3, size2, true) + 28);
4738
4738
  const x = box2.x + box2.w - w;
4739
4739
  const y = box2.y - 40;
4740
- return `<g opacity="${opacity.toFixed(3)}"><rect x="${x}" y="${y}" width="${w}" height="30" rx="15" fill="${color}" opacity="0.18"/><rect x="${x}" y="${y}" width="${w}" height="30" rx="15" fill="none" stroke="${color}" stroke-width="1.5"/><text x="${x + w / 2}" y="${y + 20}" text-anchor="middle" font-family="${esc(MONO)}" font-size="${size2}" font-weight="700" fill="${color}">${esc(fit(text2, w - 20, size2, true))}</text></g>`;
4740
+ return `<g opacity="${opacity.toFixed(3)}"><rect x="${x}" y="${y}" width="${w}" height="30" rx="15" fill="${color}" opacity="0.18"/><rect x="${x}" y="${y}" width="${w}" height="30" rx="15" fill="none" stroke="${color}" stroke-width="1.5"/><text x="${x + w / 2}" y="${y + 20}" text-anchor="middle" font-family="${esc(MONO)}" font-size="${size2}" font-weight="700" fill="${color}">${esc(fit(text3, w - 20, size2, true))}</text></g>`;
4741
4741
  }
4742
- function recoveryNote(L, text2, opacity) {
4742
+ function recoveryNote(L, text3, opacity) {
4743
4743
  const box2 = L.stacked ? { x: L.card.x, y: L.client.y + L.client.h + 6 } : { x: L.client.x, y: L.client.y + L.client.h + 22 };
4744
4744
  const width = L.stacked ? L.card.w : L.client.w;
4745
- const lines = wrap(`\u21BB ${text2}`, width, 17, L.stacked ? 1 : 3);
4745
+ const lines = wrap(`\u21BB ${text3}`, width, 17, L.stacked ? 1 : 3);
4746
4746
  return `<g opacity="${opacity.toFixed(3)}">${lines.map((line, i) => `<text x="${box2.x}" y="${box2.y + 18 + i * 22}" font-size="17" font-weight="600" fill="${C.hook}">${esc(line)}</text>`).join("")}</g>`;
4747
4747
  }
4748
4748
  function progressBar(L, fraction) {
@@ -4754,14 +4754,14 @@ function watermark(L) {
4754
4754
  }
4755
4755
  var FOLDED = "\uE000";
4756
4756
  function jsonLines(value, maxLines, maxChars, fold) {
4757
- let text2;
4757
+ let text3;
4758
4758
  try {
4759
4759
  const replacer = fold ? (key, v) => fold.has(key) && isRecord3(v) ? FOLDED : v : void 0;
4760
- text2 = typeof value === "string" ? value : JSON.stringify(value, replacer, 2)?.replace(/"\uE000"/g, "{ \u2026 }") ?? "";
4760
+ text3 = typeof value === "string" ? value : JSON.stringify(value, replacer, 2)?.replace(/"\uE000"/g, "{ \u2026 }") ?? "";
4761
4761
  } catch {
4762
- text2 = String(value);
4762
+ text3 = String(value);
4763
4763
  }
4764
- let lines = text2.split("\n");
4764
+ let lines = text3.split("\n");
4765
4765
  if (lines.length > maxLines) lines = [...lines.slice(0, Math.max(1, maxLines - 1)), " \u2026"];
4766
4766
  const xml = typeof value === "string" && /^\s*</.test(value);
4767
4767
  return lines.map((raw) => {
@@ -4777,8 +4777,8 @@ function jsonLines(value, maxLines, maxChars, fold) {
4777
4777
  function formText(fields) {
4778
4778
  return Object.entries(fields).map(([key, value], i) => `${i ? "&" : ""}${key}=${typeof value === "string" ? value : JSON.stringify(value)}`).join("\n");
4779
4779
  }
4780
- function formTspans(text2, maxLines, maxChars) {
4781
- let lines = text2.split("\n");
4780
+ function formTspans(text3, maxLines, maxChars) {
4781
+ let lines = text3.split("\n");
4782
4782
  if (lines.length > maxLines) lines = [...lines.slice(0, Math.max(1, maxLines - 1)), "\u2026"];
4783
4783
  return lines.map((raw) => {
4784
4784
  const line = clip(raw, maxChars);
@@ -4830,21 +4830,21 @@ function softWrap(line, max) {
4830
4830
  }
4831
4831
  return [...out, clip(rest, max)];
4832
4832
  }
4833
- function colorValue(text2) {
4834
- const trimmed = text2.trim();
4833
+ function colorValue(text3) {
4834
+ const trimmed = text3.trim();
4835
4835
  const color = trimmed.startsWith('"') ? C.jsonString : /^[\d\-tfn]/.test(trimmed) ? C.jsonOther : C.muted;
4836
- return `<tspan fill="${color}">${esc(text2)}</tspan>`;
4836
+ return `<tspan fill="${color}">${esc(text3)}</tspan>`;
4837
4837
  }
4838
- function textWidth(text2, size2, mono = false) {
4839
- return text2.length * size2 * (mono ? 0.6 : 0.54);
4838
+ function textWidth(text3, size2, mono = false) {
4839
+ return text3.length * size2 * (mono ? 0.6 : 0.54);
4840
4840
  }
4841
- function fit(text2, width, size2, mono = false) {
4841
+ function fit(text3, width, size2, mono = false) {
4842
4842
  const max = Math.floor(width / (size2 * (mono ? 0.6 : 0.54)));
4843
- return text2.length > max ? cut(text2, Math.max(1, max - 1)) + "\u2026" : text2;
4843
+ return text3.length > max ? cut(text3, Math.max(1, max - 1)) + "\u2026" : text3;
4844
4844
  }
4845
- function wrap(text2, width, size2, maxLines) {
4845
+ function wrap(text3, width, size2, maxLines) {
4846
4846
  const max = Math.max(8, Math.floor(width / (size2 * 0.54)));
4847
- const words2 = text2.split(/\s+/).filter(Boolean);
4847
+ const words2 = text3.split(/\s+/).filter(Boolean);
4848
4848
  const lines = [];
4849
4849
  let current2 = "";
4850
4850
  for (const word of words2) {
@@ -4864,8 +4864,8 @@ function wrap(text2, width, size2, maxLines) {
4864
4864
  return lines;
4865
4865
  }
4866
4866
  var NOT_XML = /[\uD800-\uDBFF][\uDC00-\uDFFF]|[\u0000-\u0008\u000B\u000C\u000E-\u001F\uD800-\uDFFF￾￿]/g;
4867
- function esc(text2) {
4868
- return text2.replace(NOT_XML, (c) => c.length === 2 ? c : c < " " ? " " : "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
4867
+ function esc(text3) {
4868
+ return text3.replace(NOT_XML, (c) => c.length === 2 ? c : c < " " ? " " : "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
4869
4869
  }
4870
4870
  var REASONS = {
4871
4871
  "200": "OK",
@@ -4950,10 +4950,10 @@ function parseMcp(raw, name) {
4950
4950
  const title = server.info.title || server.info.name || name || UNNAMED_SERVER;
4951
4951
  const unschemed = server.tools.filter((tool) => !tool.inputSchema).length;
4952
4952
  if (unschemed) warnings.push(unschemed === server.tools.length ? "The tools are listed without input schemas, so their calls show no arguments." : `${unschemed} tools have no input schema, so their calls show no arguments.`);
4953
- const text2 = server.tools.filter((tool) => !tool.outputSchema).length;
4954
- if (text2 && server.tools.length) {
4953
+ const text3 = server.tools.filter((tool) => !tool.outputSchema).length;
4954
+ if (text3 && server.tools.length) {
4955
4955
  warnings.push(
4956
- text2 === server.tools.length ? "No tool has an output schema, so results are text written for the video: check them before you export." : `${text2} of ${server.tools.length} tools have no output schema, so their results are text written for the video.`
4956
+ text3 === server.tools.length ? "No tool has an output schema, so results are text written for the video: check them before you export." : `${text3} of ${server.tools.length} tools have no output schema, so their results are text written for the video.`
4957
4957
  );
4958
4958
  }
4959
4959
  if (server.auth) {
@@ -5281,10 +5281,29 @@ function secretName(name) {
5281
5281
  if (/idempotency/i.test(name)) return false;
5282
5282
  return /secret|passw(or)?d|pwd|token|api[-_]?key|apikey|credential|signature|session|cookie|bearer|jwt|^auth(orization)?$/i.test(name) || /(^|[_-])key$|[a-z0-9]Key$|^key$/i.test(name);
5283
5283
  }
5284
- var SECRET_VALUE = /^(sk|rk)_(live|test)_|^gh[pousr]_|^github_pat_|^xox[abposr]-|^AKIA[0-9A-Z]{12,}|^eyJ[\w-]+\.[\w-]+|^(bearer|basic)\s/i;
5285
- function readVariables(list6, into) {
5286
- if (!Array.isArray(list6)) return;
5287
- for (const v of list6) {
5284
+ var SECRET_VALUE = /^(sk|rk)_(live|test)_|^whsec_|^gh[pousr]_|^github_pat_|^xox[abposr]-|^(AKIA|ASIA)[0-9A-Z]{12,}|^eyJ[\w-]+\.[\w-]+|^(bearer|basic)\s|^sk-[\w-]{20,}|^AIza[\w-]{30,}|^ya29\.[\w-]{20,}|^SG\.[\w-]{16,}\.[\w-]{16,}|^npm_[A-Za-z0-9]{30,}|^glpat-[\w-]{20,}|^hf_[A-Za-z0-9]{30,}|^shp(at|ss|ca|pa)_[a-fA-F0-9]{32}|^sq0(atp|csp)-[\w-]{20,}|^-----BEGIN [A-Z ]*PRIVATE KEY-----/i;
5285
+ function credentialName(name) {
5286
+ if (/^key$/i.test(name.trim()) || /(type|kind|url|uri|endpoint|expires?(_?(in|at))?|name|count|length|hint|prefix)$/i.test(name)) return false;
5287
+ return secretName(name) || /(^|[^a-z])auth([^a-z]|$)/i.test(name);
5288
+ }
5289
+ function hiddenAs(name) {
5290
+ return /passw(or)?d|pwd/i.test(name) ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : placeholder(name || "secret");
5291
+ }
5292
+ function withoutCredential(name, value, hid) {
5293
+ if (!given(value) || !(credentialName(name) || SECRET_VALUE.test(value.trim()))) return value;
5294
+ hid.add(name || "a value");
5295
+ return hiddenAs(name);
5296
+ }
5297
+ function withoutCredentials(value, hid, name = "", depth = 0) {
5298
+ if (depth > 40) return value;
5299
+ if (typeof value === "string") return withoutCredential(name, value, hid);
5300
+ if (Array.isArray(value)) return value.map((v) => withoutCredentials(v, hid, name, depth + 1));
5301
+ if (isObj(value)) return Object.fromEntries(Object.entries(value).map(([key, v]) => [key, withoutCredentials(v, hid, key, depth + 1)]));
5302
+ return value;
5303
+ }
5304
+ function readVariables(list7, into) {
5305
+ if (!Array.isArray(list7)) return;
5306
+ for (const v of list7) {
5288
5307
  if (!isObj(v) || v.disabled === true || v.enabled === false) continue;
5289
5308
  const key = typeof v.key === "string" ? v.key.trim() : typeof v.id === "string" ? v.id.trim() : "";
5290
5309
  const value = typeof v.value === "string" ? v.value : typeof v.value === "number" || typeof v.value === "boolean" ? String(v.value) : isObj(v.value) || Array.isArray(v.value) ? JSON.stringify(v.value) : "";
@@ -5326,16 +5345,16 @@ var Variables = class {
5326
5345
  return depth > 4 ? v.value : this.fill(v.value, note, depth + 1);
5327
5346
  }
5328
5347
  /** Text with its variables filled in where they have a value; the rest stay as written. */
5329
- fill(text2, note = true, depth = 0) {
5330
- return text2.replace(VARIABLE, (whole, name) => {
5348
+ fill(text3, note = true, depth = 0) {
5349
+ return text3.replace(VARIABLE, (whole, name) => {
5331
5350
  const value = this.value(name.trim(), note, depth);
5332
5351
  return value === void 0 ? whole : String(value);
5333
5352
  });
5334
5353
  }
5335
5354
  };
5336
5355
  function textOf(description) {
5337
- const text2 = typeof description === "string" ? description : isObj(description) && typeof description.content === "string" ? description.content : void 0;
5338
- return text2?.trim() ? text2.trim() : void 0;
5356
+ const text3 = typeof description === "string" ? description : isObj(description) && typeof description.content === "string" ? description.content : void 0;
5357
+ return text3?.trim() ? text3.trim() : void 0;
5339
5358
  }
5340
5359
  function headerList(raw) {
5341
5360
  if (typeof raw === "string") {
@@ -5372,8 +5391,8 @@ function urlOf(request) {
5372
5391
  variables: Array.isArray(url.variable) ? url.variable : []
5373
5392
  };
5374
5393
  }
5375
- function parseUrl(text2) {
5376
- let rest = text2.trim();
5394
+ function parseUrl(text3) {
5395
+ let rest = text3.trim();
5377
5396
  const hash = rest.indexOf("#");
5378
5397
  if (hash >= 0) rest = rest.slice(0, hash);
5379
5398
  let search = "";
@@ -5394,11 +5413,11 @@ function parseUrl(text2) {
5394
5413
  });
5395
5414
  return { ...protocol ? { protocol: protocol[1] } : {}, host, ...port ? { port: port[1] } : {}, path: slash < 0 ? [] : rest.slice(slash + 1).split("/"), query, variables: [] };
5396
5415
  }
5397
- function decoded(text2) {
5416
+ function decoded(text3) {
5398
5417
  try {
5399
- return decodeURIComponent(text2.replace(/\+/g, " "));
5418
+ return decodeURIComponent(text3.replace(/\+/g, " "));
5400
5419
  } catch {
5401
- return text2;
5420
+ return text3;
5402
5421
  }
5403
5422
  }
5404
5423
  var LOCAL_HOST = /^(localhost|127\.\d+\.\d+\.\d+|0\.0\.0\.0|\[::1\])(:|\/|$)/i;
@@ -5472,7 +5491,7 @@ var BEARER = { name: "bearerAuth", scheme: { type: "http", scheme: "bearer" }, s
5472
5491
  function schemeOf(auth, vars, notes) {
5473
5492
  const type2 = typeof auth.type === "string" ? auth.type.toLowerCase() : "";
5474
5493
  const s = settingsOf(auth, type2);
5475
- const text2 = (v) => typeof v === "string" ? vars.fill(v, false).trim() : "";
5494
+ const text3 = (v) => typeof v === "string" ? vars.fill(v, false).trim() : "";
5476
5495
  switch (type2) {
5477
5496
  case "noauth":
5478
5497
  return "none";
@@ -5483,17 +5502,18 @@ function schemeOf(auth, vars, notes) {
5483
5502
  case "digest":
5484
5503
  return { name: "digestAuth", scheme: { type: "http", scheme: "digest" }, scopes: [] };
5485
5504
  case "apikey": {
5486
- const name = text2(s.key);
5487
- return { name: "apiKeyAuth", scheme: { type: "apiKey", name: name && !name.includes("{{") ? name : "X-API-Key", in: s.in === "query" ? "query" : "header" }, scopes: [] };
5505
+ const name = text3(s.key);
5506
+ const where = s.in === "query" || s.in === "cookie" ? s.in : "header";
5507
+ return { name: "apiKeyAuth", scheme: { type: "apiKey", name: name && !name.includes("{{") ? name : where === "cookie" ? "session" : "X-API-Key", in: where }, scopes: [] };
5488
5508
  }
5489
5509
  case "jwt":
5490
5510
  case "asap":
5491
- if (s.addTokenTo === "queryParam") return { name: "jwtAuth", scheme: { type: "apiKey", name: text2(s.queryParamKey) || "token", in: "query" }, scopes: [] };
5511
+ if (s.addTokenTo === "queryParam") return { name: "jwtAuth", scheme: { type: "apiKey", name: text3(s.queryParamKey) || "token", in: "query" }, scopes: [] };
5492
5512
  return { name: "bearerAuth", scheme: { type: "http", scheme: "bearer", bearerFormat: "JWT" }, scopes: [] };
5493
5513
  case "oauth2": {
5494
5514
  const flow = GRANTS[String(s.grant_type ?? "")] ?? "authorizationCode";
5495
5515
  const url = (v) => {
5496
- const u = text2(v);
5516
+ const u = text3(v);
5497
5517
  return /^https?:\/\/[^{}\s]+$/i.test(u) ? u : void 0;
5498
5518
  };
5499
5519
  const authorizationUrl = url(s.authUrl);
@@ -5503,7 +5523,7 @@ function schemeOf(auth, vars, notes) {
5503
5523
  notes.add("oauth2");
5504
5524
  return BEARER;
5505
5525
  }
5506
- const scopes = text2(s.scope).split(/[\s,]+/).filter(Boolean);
5526
+ const scopes = text3(s.scope).split(/[\s,]+/).filter(Boolean);
5507
5527
  const details = {
5508
5528
  ...flow === "implicit" || flow === "authorizationCode" ? { authorizationUrl } : {},
5509
5529
  ...flow === "implicit" ? {} : { tokenUrl },
@@ -5550,18 +5570,18 @@ function mainType(value) {
5550
5570
  const type2 = value?.split(";")[0].trim();
5551
5571
  return type2 && /^[\w.+-]+\/[\w.+-]+$/.test(type2) ? type2 : void 0;
5552
5572
  }
5553
- var looksJson = (text2) => /^\s*[[{]/.test(text2);
5554
- function jsonBody(text2, vars) {
5573
+ var looksJson = (text3) => /^\s*[[{]/.test(text3);
5574
+ function jsonBody(text3, vars) {
5555
5575
  let out = "";
5556
5576
  let inString = false;
5557
- for (let i = 0; i < text2.length; i++) {
5558
- const c = text2[i];
5559
- if (c === "{" && text2[i + 1] === "{") {
5560
- const end = text2.indexOf("}}", i + 2);
5561
- const name = end > 0 ? text2.slice(i + 2, end) : "";
5577
+ for (let i = 0; i < text3.length; i++) {
5578
+ const c = text3[i];
5579
+ if (c === "{" && text3[i + 1] === "{") {
5580
+ const end = text3.indexOf("}}", i + 2);
5581
+ const name = end > 0 ? text3.slice(i + 2, end) : "";
5562
5582
  if (/^[^{}"\r\n]+$/.test(name) && name.trim()) {
5563
5583
  const value = vars.value(name.trim());
5564
- const written2 = text2.slice(i, end + 2);
5584
+ const written2 = text3.slice(i, end + 2);
5565
5585
  if (inString) out += value === void 0 ? written2 : JSON.stringify(String(value)).slice(1, -1);
5566
5586
  else out += value === void 0 ? JSON.stringify(written2) : jsonLiteral(value);
5567
5587
  i = end + 1;
@@ -5571,24 +5591,24 @@ function jsonBody(text2, vars) {
5571
5591
  if (inString) {
5572
5592
  out += c;
5573
5593
  if (c === "\\") {
5574
- out += text2[i + 1] ?? "";
5594
+ out += text3[i + 1] ?? "";
5575
5595
  i++;
5576
5596
  } else if (c === '"') inString = false;
5577
5597
  continue;
5578
5598
  }
5579
5599
  if (c === '"') inString = true;
5580
- else if (c === "/" && text2[i + 1] === "/") {
5581
- const end = text2.indexOf("\n", i);
5582
- i = end < 0 ? text2.length : end - 1;
5600
+ else if (c === "/" && text3[i + 1] === "/") {
5601
+ const end = text3.indexOf("\n", i);
5602
+ i = end < 0 ? text3.length : end - 1;
5583
5603
  continue;
5584
- } else if (c === "/" && text2[i + 1] === "*") {
5585
- const end = text2.indexOf("*/", i + 2);
5586
- i = end < 0 ? text2.length : end + 1;
5604
+ } else if (c === "/" && text3[i + 1] === "*") {
5605
+ const end = text3.indexOf("*/", i + 2);
5606
+ i = end < 0 ? text3.length : end + 1;
5587
5607
  continue;
5588
5608
  } else if (c === ",") {
5589
5609
  let j = i + 1;
5590
- while (j < text2.length && /\s/.test(text2[j])) j++;
5591
- if (text2[j] === "}" || text2[j] === "]") continue;
5610
+ while (j < text3.length && /\s/.test(text3[j])) j++;
5611
+ if (text3[j] === "}" || text3[j] === "]") continue;
5592
5612
  }
5593
5613
  out += c;
5594
5614
  }
@@ -5607,9 +5627,9 @@ function jsonLiteral(value) {
5607
5627
  return JSON.stringify(value);
5608
5628
  }
5609
5629
  }
5610
- function parseJson(text2) {
5630
+ function parseJson(text3) {
5611
5631
  try {
5612
- return JSON.parse(text2);
5632
+ return JSON.parse(text3);
5613
5633
  } catch {
5614
5634
  return void 0;
5615
5635
  }
@@ -5661,22 +5681,22 @@ function payloadOf(value, required) {
5661
5681
  if (holdsPlaceholder(value)) return { schema: schemaOf(value, { required, examples: true }) };
5662
5682
  return { schema: schemaOf(value, { required }), example: value };
5663
5683
  }
5664
- function bodyOf(raw, contentType, vars) {
5684
+ function bodyOf(raw, contentType, vars, hid) {
5665
5685
  if (!isObj(raw) || raw.disabled === true) return void 0;
5666
5686
  const mode = typeof raw.mode === "string" ? raw.mode : "";
5667
5687
  switch (mode) {
5668
5688
  case "raw": {
5669
- const text2 = typeof raw.raw === "string" ? raw.raw : "";
5670
- if (!text2.trim()) return void 0;
5689
+ const text3 = typeof raw.raw === "string" ? raw.raw : "";
5690
+ if (!text3.trim()) return void 0;
5671
5691
  const options = isObj(raw.options) && isObj(raw.options.raw) ? raw.options.raw : {};
5672
5692
  const language = typeof options.language === "string" ? options.language.toLowerCase() : "";
5673
- const type2 = contentType ?? RAW_TYPES[language] ?? (looksJson(text2) ? "application/json" : "text/plain");
5693
+ const type2 = contentType ?? RAW_TYPES[language] ?? (looksJson(text3) ? "application/json" : "text/plain");
5674
5694
  if (/json/i.test(type2)) {
5675
- const value = jsonBody(text2, vars);
5676
- if (value !== void 0) return { media: type2, ...payloadOf(value, true) };
5677
- return { media: "text/plain", schema: { type: "string" }, example: vars.fill(text2) };
5695
+ const value = jsonBody(text3, vars);
5696
+ if (value !== void 0) return { media: type2, ...payloadOf(withoutCredentials(value, hid), true) };
5697
+ return { media: "text/plain", schema: { type: "string" }, example: vars.fill(text3) };
5678
5698
  }
5679
- return { media: type2, schema: { type: "string" }, example: vars.fill(text2) };
5699
+ return { media: type2, schema: { type: "string" }, example: vars.fill(text3) };
5680
5700
  }
5681
5701
  case "urlencoded":
5682
5702
  case "formdata": {
@@ -5684,7 +5704,10 @@ function bodyOf(raw, contentType, vars) {
5684
5704
  const fields = pairs(raw[mode]);
5685
5705
  if (!fields.length) return void 0;
5686
5706
  const files = new Set(Array.isArray(raw[mode]) ? raw[mode].flatMap((f) => multipart && isObj(f) && f.type === "file" && typeof f.key === "string" ? [f.key.trim()] : []) : []);
5687
- const entries = fields.map((f) => ({ key: vars.fill(f.key, false), file: files.has(f.key), value: vars.fill(f.value, !f.disabled), field: f }));
5707
+ const entries = fields.map((f) => {
5708
+ const key = vars.fill(f.key, false);
5709
+ return { key, file: files.has(f.key), value: withoutCredential(key, vars.fill(f.value, !f.disabled), hid), field: f };
5710
+ });
5688
5711
  const properties = Object.fromEntries(
5689
5712
  entries.map(({ key, file, value, field }) => {
5690
5713
  if (file) return [key, { type: "string", format: "binary" }];
@@ -5705,7 +5728,8 @@ function bodyOf(raw, contentType, vars) {
5705
5728
  const g = isObj(raw.graphql) ? raw.graphql : {};
5706
5729
  const query = typeof g.query === "string" ? vars.fill(g.query) : "";
5707
5730
  if (!query.trim()) return void 0;
5708
- const variables = typeof g.variables === "string" && g.variables.trim() ? jsonBody(g.variables, vars) : isObj(g.variables) ? g.variables : void 0;
5731
+ const sent = typeof g.variables === "string" && g.variables.trim() ? jsonBody(g.variables, vars) : isObj(g.variables) ? g.variables : void 0;
5732
+ const variables = sent === void 0 ? void 0 : withoutCredentials(sent, hid);
5709
5733
  const example = { query, ...variables !== void 0 ? { variables } : {} };
5710
5734
  return { media: "application/json", ...payloadOf(example, true) };
5711
5735
  }
@@ -5713,7 +5737,7 @@ function bodyOf(raw, contentType, vars) {
5713
5737
  return void 0;
5714
5738
  }
5715
5739
  }
5716
- function responsesOf(saved, requestName) {
5740
+ function responsesOf(saved, requestName, hid) {
5717
5741
  const out = {};
5718
5742
  for (const r of saved) {
5719
5743
  if (!isObj(r)) continue;
@@ -5728,7 +5752,7 @@ function responsesOf(saved, requestName) {
5728
5752
  const body = typeof r.body === "string" ? r.body : "";
5729
5753
  if (body.trim()) {
5730
5754
  const value = (type2 ? /json/i.test(type2) : looksJson(body)) ? parseJson(body) : void 0;
5731
- if (value !== void 0) response.content = { [type2 ?? "application/json"]: payloadOf(value, "all") };
5755
+ if (value !== void 0) response.content = { [type2 ?? "application/json"]: payloadOf(withoutCredentials(value, hid), "all") };
5732
5756
  else response.content = { [type2 && !/json/i.test(type2) ? type2 : "text/plain"]: { schema: { type: "string" }, example: body } };
5733
5757
  }
5734
5758
  out[status] = response;
@@ -5771,7 +5795,7 @@ function collect(items, folder, auth, out, counts, depth = 0) {
5771
5795
  continue;
5772
5796
  }
5773
5797
  const description = textOf(request.description) ?? textOf(item.description);
5774
- out.push({ name, ...folder ? { folder } : {}, request, responses: Array.isArray(item.response) ? item.response : [], auth: ownAuth(request.auth) ?? auth, ...description ? { description } : {} });
5798
+ out.push({ ...typeof item.id === "string" && item.id ? { id: item.id } : {}, name, ...folder ? { folder } : {}, request, responses: Array.isArray(item.response) ? item.response : [], auth: ownAuth(request.auth) ?? auth, ...description ? { description } : {} });
5775
5799
  }
5776
5800
  }
5777
5801
  function versionOf(v) {
@@ -5784,7 +5808,8 @@ var sameRequirement = (a, b) => JSON.stringify(a ?? null) === JSON.stringify(b ?
5784
5808
  function list2(names) {
5785
5809
  return `${names.slice(0, 3).join(", ")}${names.length > 3 ? "\u2026" : ""}`;
5786
5810
  }
5787
- function convertPostman(raw, environments = []) {
5811
+ function convertPostman(raw, environments = [], source) {
5812
+ const app = source?.app ?? "Postman";
5788
5813
  const collection = collectionIn(raw);
5789
5814
  if (!collection) throw new Error("Not a Postman collection.");
5790
5815
  const info = collection.info;
@@ -5796,7 +5821,7 @@ function convertPostman(raw, environments = []) {
5796
5821
  if (envs[0]) readVariables(envs[0].values, values);
5797
5822
  const vars = new Variables(values);
5798
5823
  const format = typeof info.schema === "string" ? info.schema.match(SCHEMA_URL) : null;
5799
- const warnings = [`This is a Postman collection${format ? ` (format ${format[2]}.${format[3]})` : ""}, converted to OpenAPI 3.0 when it loaded.`];
5824
+ const warnings = [source?.intro ?? `This is a Postman collection${format ? ` (format ${format[2]}.${format[3]})` : ""}, converted to OpenAPI 3.0 when it loaded.`];
5800
5825
  const envName = (e) => typeof e.name === "string" && e.name.trim() ? `"${e.name.trim()}"` : "uploaded with it";
5801
5826
  if (envs.length === 1) warnings.push(`Its variables are filled in from the environment ${envName(envs[0])}.`);
5802
5827
  if (envs.length > 1) warnings.push(`Its variables are filled in from the first environment uploaded, ${envName(envs[0])}; the other environments were left out.`);
@@ -5805,6 +5830,7 @@ function convertPostman(raw, environments = []) {
5805
5830
  collect(collection.item, void 0, ownAuth(collection.auth), saved, counts);
5806
5831
  const schemes = new Schemes();
5807
5832
  const notes = /* @__PURE__ */ new Set();
5833
+ const hid = /* @__PURE__ */ new Set();
5808
5834
  const requirementOf = (auth, headers) => {
5809
5835
  const scheme = auth ? schemeOf(auth, vars, notes) : void 0;
5810
5836
  const parts = [];
@@ -5849,13 +5875,14 @@ function convertPostman(raw, environments = []) {
5849
5875
  const item = paths[path] ??= {};
5850
5876
  const slots = FIXED_METHODS.has(method) ? item : item.additionalOperations ??= {};
5851
5877
  const name = bareName(vars.fill(r.name, false));
5852
- const responses = responsesOf(r.responses, r.name);
5878
+ const responses = responsesOf(r.responses, r.name, hid);
5853
5879
  const success = Object.keys(responses).some((s) => /^2/.test(s));
5854
5880
  const existing = slots[method];
5855
5881
  if (isObj(existing)) {
5856
5882
  const into = existing.responses;
5857
5883
  if (success && into["200"]?.[UNSAVED]) delete into["200"];
5858
5884
  for (const [status, response] of Object.entries(responses)) into[status] ??= response;
5885
+ if (source?.idsField && r.id) existing[source.idsField]?.push(r.id);
5859
5886
  merged++;
5860
5887
  continue;
5861
5888
  }
@@ -5873,15 +5900,19 @@ function convertPostman(raw, environments = []) {
5873
5900
  else if (/^cookie$/i.test(h.key)) {
5874
5901
  for (const part of h.value.split(";")) {
5875
5902
  const eq = part.indexOf("=");
5876
- if (eq > 0) parameters.push({ name: part.slice(0, eq).trim(), in: "cookie", required: true, schema: { type: "string" }, example: vars.fill(part.slice(eq + 1).trim()) });
5903
+ if (eq <= 0) continue;
5904
+ const cookie = part.slice(0, eq).trim();
5905
+ const value = vars.fill(part.slice(eq + 1).trim());
5906
+ if (given(value)) hid.add(cookie);
5907
+ parameters.push({ name: cookie, in: "cookie", required: true, schema: { type: "string" }, example: given(value) ? hiddenAs(cookie) : value });
5877
5908
  }
5878
- } else parameters.push({ name: h.key, in: "header", required: true, ...valueOf(vars.fill(h.value)), ...h.description ? { description: h.description } : {} });
5909
+ } else parameters.push({ name: h.key, in: "header", required: true, ...valueOf(withoutCredential(h.key, vars.fill(h.value), hid)), ...h.description ? { description: h.description } : {} });
5879
5910
  }
5880
5911
  const query = /* @__PURE__ */ new Map();
5881
5912
  for (const q of url.query) {
5882
5913
  const key = vars.fill(q.key, false).trim();
5883
5914
  if (!key) continue;
5884
- const value = vars.fill(q.value, !q.disabled);
5915
+ const value = withoutCredential(key, vars.fill(q.value, !q.disabled), hid);
5885
5916
  const entry = query.get(key);
5886
5917
  if (!entry) query.set(key, { values: [value], required: !q.disabled, ...q.description ? { description: q.description } : {} });
5887
5918
  else if (!q.disabled) {
@@ -5895,7 +5926,7 @@ function convertPostman(raw, environments = []) {
5895
5926
  const value = many ? { schema: { type: "array", items: { type: "string" } }, example: q.values } : valueOf(q.values[0]);
5896
5927
  parameters.push({ name: key, in: "query", required: q.required, ...value, ...q.description ? { description: q.description } : {} });
5897
5928
  }
5898
- const body = bodyOf(r.request.body, contentType, vars);
5929
+ const body = bodyOf(r.request.body, contentType, vars, hid);
5899
5930
  const lowered = method.toLowerCase();
5900
5931
  const operationId = namesUrl(name) ? void 0 : operationIdFor(name, usedIds);
5901
5932
  const op = {
@@ -5906,7 +5937,8 @@ function convertPostman(raw, environments = []) {
5906
5937
  ...parameters.length ? { parameters } : {},
5907
5938
  ...body ? { requestBody: { ...BODILESS.has(lowered) ? {} : { required: true }, content: { [body.media]: { schema: body.schema, ...body.example !== void 0 ? { example: body.example } : {} } } } } : {},
5908
5939
  // A call with no successful response saved still succeeds in the video, with no body to show.
5909
- responses: success ? responses : { "200": { description: "OK", [UNSAVED]: true }, ...responses }
5940
+ responses: success ? responses : { "200": { description: "OK", [UNSAVED]: true }, ...responses },
5941
+ ...source?.idsField && r.id ? { [source.idsField]: [r.id] } : {}
5910
5942
  };
5911
5943
  const requirement = requirementOf(r.auth, keyHeaders);
5912
5944
  if (!sameRequirement(requirement, topRequirement)) op.security = requirement ? [requirement] : [];
@@ -5928,22 +5960,25 @@ function convertPostman(raw, environments = []) {
5928
5960
  }
5929
5961
  }
5930
5962
  const named = [...unsetHosts].filter(Boolean);
5931
- if (named.length) warnings.push(`The collection gives ${list2(named.map((n) => `{{${n}}}`))} no value, so the video puts the API on api.example.com. Upload the collection together with its environment, or give the variable a value in Postman.`);
5963
+ const giveIt = app === "Postman" ? "Upload the collection together with its environment, or give the variable a value in Postman." : `Give the variable a value in one of the collection's environments in ${app}.`;
5964
+ if (named.length) warnings.push(`The collection gives ${list2(named.map((n) => `{{${n}}}`))} no value, so the video puts the API on api.example.com. ${giveIt}`);
5932
5965
  else if (unsetHosts.has("")) warnings.push("Some requests give no host, so the video puts them on api.example.com.");
5933
5966
  const unset = [...vars.unset].filter((n) => !unsetHosts.has(n));
5934
5967
  if (unset.length) warnings.push(`Some variables have no value in the collection, so the video shows them as written, or an id an earlier call returned: ${list2(unset.map((n) => `{{${n}}}`))}.`);
5968
+ if (hid.size) warnings.push(`Credentials written out in the requests or their saved responses, rather than kept in variables, show hidden: ${list2([...hid])}.`);
5935
5969
  if (vars.secret.size) warnings.push(`Variables that look like credentials aren't filled in, so the video shows them as written: ${list2([...vars.secret].map((n) => `{{${n}}}`))}.`);
5936
- if (placed.length && unsaved === placed.length) warnings.push("None of the requests has a successful response saved as an example, so the calls show no response body. Save a response as an example in Postman to show it.");
5970
+ if (placed.length && unsaved === placed.length && app !== "Postman") warnings.push(`${app}'s exports hold no responses, so the calls show no response body. A design document's spec gives them.`);
5971
+ else if (placed.length && unsaved === placed.length) warnings.push("None of the requests has a successful response saved as an example, so the calls show no response body. Save a response as an example in Postman to show it.");
5937
5972
  else if (unsaved) warnings.push(`${unsaved} of ${placed.length} requests have no successful response saved as an example, so those calls show no response body.`);
5938
- if (merged) warnings.push(`${merged} ${merged === 1 ? "request shares its method and path with an earlier one, so it was" : "requests share their method and path with an earlier one, so each was"} read as part of that call, with its saved responses.`);
5973
+ if (merged) warnings.push(`${merged} ${merged === 1 ? "request shares its method and path with an earlier one, so it was" : "requests share their method and path with an earlier one, so each was"} read as part of that call${app === "Postman" ? ", with its saved responses" : ""}.`);
5939
5974
  if (counts.noRequest) warnings.push(`${counts.noRequest} ${counts.noRequest === 1 ? "item has no request URL, so it was" : "items have no request URL, so they were"} left out.`);
5940
5975
  if (notes.has("oauth2")) warnings.push("The OAuth 2.0 settings don't give the URLs its grant needs, so the video shows the access token being sent, not fetched.");
5941
5976
  const unknown = [...notes].filter((n) => n !== "oauth2");
5942
- if (unknown.length) warnings.push(`Postman's ${list2(unknown)} auth can't be shown, so requests that use it show none.`);
5977
+ if (unknown.length) warnings.push(`${app}'s ${list2(unknown)} auth can't be shown, so requests that use it show none.`);
5943
5978
  const description = textOf(info.description);
5944
5979
  const doc = {
5945
5980
  openapi: custom ? "3.2.0" : "3.0.3",
5946
- info: { title: typeof info.name === "string" && info.name.trim() ? info.name.trim() : "Postman collection", version: versionOf(info.version), ...description ? { description } : {} },
5981
+ info: { title: typeof info.name === "string" && info.name.trim() ? info.name.trim() : `${app} collection`, version: versionOf(info.version), ...description ? { description } : {} },
5947
5982
  servers: [{ url: top }],
5948
5983
  paths,
5949
5984
  ...Object.keys(schemes.byName).length ? { components: { securitySchemes: schemes.byName } } : {},
@@ -5953,16 +5988,473 @@ function convertPostman(raw, environments = []) {
5953
5988
  return { doc, warnings };
5954
5989
  }
5955
5990
 
5956
- // ../../lib/oas/swagger1.ts
5991
+ // ../../lib/oas/insomnia.ts
5957
5992
  var isObj2 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
5993
+ var V5_TYPE = /^(collection|spec|environment|mock|mcpClient)\.insomnia(\.rest)?\/5\.\d+$/;
5994
+ var INSOMNIA_IDS = "x-insomnia-requests";
5995
+ function insomniaKind(raw) {
5996
+ if (!isObj2(raw)) return void 0;
5997
+ if (typeof raw.type === "string") {
5998
+ const kind = raw.type.match(V5_TYPE)?.[1];
5999
+ return kind === "spec" ? "design" : kind === "mcpClient" ? "mcp" : kind;
6000
+ }
6001
+ if (raw._type !== "export" || !Array.isArray(raw.resources)) return void 0;
6002
+ const resources = raw.resources.filter(isObj2);
6003
+ const workspace = resources.find((r) => r._type === "workspace");
6004
+ if (workspace?.scope === "design" || resources.some((r) => r._type === "api_spec" && typeof r.contents === "string" && r.contents.trim())) return "design";
6005
+ if (workspace || resources.some((r) => r._type === "request")) return "collection";
6006
+ if (resources.some((r) => r._type === "environment")) return "environment";
6007
+ return "collection";
6008
+ }
6009
+ function insomniaMcpUrl(raw) {
6010
+ const request = isObj2(raw) && isObj2(raw.mcpRequest) ? raw.mcpRequest : void 0;
6011
+ return typeof request?.url === "string" && /^https?:\/\//i.test(request.url.trim()) ? request.url.trim() : void 0;
6012
+ }
6013
+ function readInsomnia(raw, parseYaml2) {
6014
+ if (!isObj2(raw)) throw new Error("Not an Insomnia export.");
6015
+ const workspace = typeof raw.type === "string" ? fromV5(raw) : fromV4(raw, parseYaml2);
6016
+ const notes = [...workspace.notes];
6017
+ if (isOpenApi(workspace.spec)) {
6018
+ if (workspace.items.length) notes.push("Its spec is read, not the requests saved with it.");
6019
+ return { spec: workspace.spec, label: `the spec in the Insomnia design document "${workspace.name}"`, notes };
6020
+ }
6021
+ if (workspace.specFile && !workspace.items.length) throw new Error(`This design document keeps its spec in another file, ${workspace.specFile}: give that file instead.`);
6022
+ const converted = toPostman(workspace);
6023
+ return { ...converted, label: `an Insomnia collection (export format ${workspace.format})`, notes: [...notes, ...converted.notes] };
6024
+ }
6025
+ function isOpenApi(doc) {
6026
+ return isObj2(doc) && (doc.openapi !== void 0 || doc.swagger !== void 0);
6027
+ }
6028
+ var text = (v) => typeof v === "string" ? v : "";
6029
+ var textOrUndefined = (v) => typeof v === "string" && v.trim() ? v.trim() : void 0;
6030
+ var sortKey = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
6031
+ var bySortKey = (nodes2) => nodes2.map((n, i) => ({ n, i })).sort((a, b) => a.n.sortKey - b.n.sortKey || a.i - b.i).map(({ n }) => n);
6032
+ function fromV5(raw) {
6033
+ const meta = isObj2(raw.meta) ? raw.meta : {};
6034
+ const spec = isObj2(raw.spec) ? raw.spec : void 0;
6035
+ const environments = isObj2(raw.environments) ? raw.environments : void 0;
6036
+ const subs = Array.isArray(environments?.subEnvironments) ? environments.subEnvironments.filter(isObj2).map(v5Environment) : [];
6037
+ return {
6038
+ name: textOrUndefined(raw.name) ?? "Insomnia collection",
6039
+ ...textOrUndefined(meta.description) ? { description: textOrUndefined(meta.description) } : {},
6040
+ format: "5",
6041
+ ...spec && isObj2(spec.contents) && Object.keys(spec.contents).length ? { spec: spec.contents } : {},
6042
+ ...spec && typeof spec.file === "string" ? { specFile: spec.file } : {},
6043
+ items: v5Nodes(raw.collection, 0),
6044
+ ...environments ? { base: v5Environment(environments) } : {},
6045
+ subs,
6046
+ notes: []
6047
+ };
6048
+ }
6049
+ function v5Environment(env) {
6050
+ const meta = isObj2(env.meta) ? env.meta : {};
6051
+ const secret = new Set(Array.isArray(env.confidentialKeys) ? env.confidentialKeys.filter((k) => typeof k === "string") : []);
6052
+ return { name: textOrUndefined(env.name) ?? "Environment", data: isObj2(env.data) ? env.data : {}, secret, private: meta.isPrivate === true, sortKey: sortKey(meta.sortKey) };
6053
+ }
6054
+ function v5Nodes(list7, depth) {
6055
+ if (!Array.isArray(list7) || depth > 50) return [];
6056
+ return list7.filter(isObj2).map((item) => {
6057
+ const meta = isObj2(item.meta) ? item.meta : {};
6058
+ const id = text(meta.id);
6059
+ const base = { id, name: text(item.name).trim(), ...textOrUndefined(meta.description) ? { description: textOrUndefined(meta.description) } : {}, private: meta.isPrivate === true, sortKey: sortKey(meta.sortKey) };
6060
+ if (Array.isArray(item.children) || item.method === void 0 && item.url === void 0) {
6061
+ return { ...base, children: v5Nodes(item.children, depth + 1), fields: item };
6062
+ }
6063
+ return { ...base, fields: item, ...typeof item.method === "string" && !/^(greq|ws-req|socketio-req|mcp)/.test(id) ? {} : { other: true } };
6064
+ });
6065
+ }
6066
+ function fromV4(raw, parseYaml2) {
6067
+ const resources = raw.resources.filter(isObj2);
6068
+ const notes = [];
6069
+ const children = /* @__PURE__ */ new Map();
6070
+ for (const r of resources) {
6071
+ const parent = typeof r.parentId === "string" ? r.parentId : "";
6072
+ const siblings = children.get(parent);
6073
+ if (siblings) siblings.push(r);
6074
+ else children.set(parent, [r]);
6075
+ }
6076
+ const workspaces = resources.filter((r) => r._type === "workspace");
6077
+ const specOf = (w) => resources.find((r) => r._type === "api_spec" && (!w || r.parentId === w._id) && typeof r.contents === "string" && r.contents.trim());
6078
+ const hasRequests = (id, depth = 0) => depth < 50 && (children.get(id) ?? []).some((r) => r._type === "request" || r._type === "request_group" && hasRequests(String(r._id), depth + 1));
6079
+ const shown = workspaces.find((w) => specOf(w) || hasRequests(String(w._id)));
6080
+ const others = workspaces.filter((w) => w !== shown && (specOf(w) || hasRequests(String(w._id))));
6081
+ if (shown && others.length) notes.push(`The export holds ${others.length + 1} workspaces: the video is of the first, "${text(shown.name).trim() || "Insomnia"}".`);
6082
+ const workspaceId = shown ? String(shown._id) : resources.find((r) => r._type === "request" || r._type === "request_group")?.parentId ?? "";
6083
+ const specResource = specOf(shown);
6084
+ let spec;
6085
+ if (specResource) {
6086
+ const contents = text(specResource.contents);
6087
+ const read2 = (parse2) => {
6088
+ try {
6089
+ return parse2?.(contents);
6090
+ } catch {
6091
+ return void 0;
6092
+ }
6093
+ };
6094
+ spec = (contents.trimStart().startsWith("{") ? read2(JSON.parse) : void 0) ?? read2(parseYaml2);
6095
+ if (!isOpenApi(spec)) notes.push("The design document's spec couldn't be read, so its requests are.");
6096
+ }
6097
+ const nodes2 = (parent, depth) => depth > 50 ? [] : (children.get(parent) ?? []).flatMap((r) => {
6098
+ const base2 = { id: String(r._id ?? ""), name: text(r.name).trim(), ...textOrUndefined(r.description) ? { description: textOrUndefined(r.description) } : {}, private: r.isPrivate === true, sortKey: sortKey(r.metaSortKey), fields: r };
6099
+ if (r._type === "request_group") return [{ ...base2, children: nodes2(String(r._id), depth + 1) }];
6100
+ if (r._type === "request") return [base2];
6101
+ if (/request$/.test(text(r._type))) return [{ ...base2, other: true }];
6102
+ return [];
6103
+ });
6104
+ const environments = (children.get(workspaceId) ?? []).filter((r) => r._type === "environment");
6105
+ const base = environments[0];
6106
+ const env = (r) => ({
6107
+ name: textOrUndefined(r.name) ?? "Environment",
6108
+ data: isObj2(r.data) ? r.data : {},
6109
+ secret: new Set(Array.isArray(r.kvPairData) ? r.kvPairData.filter((p) => isObj2(p) && (p.type === "secret" || p.isConfidential === true) && typeof p.name === "string").map((p) => String(p.name)) : []),
6110
+ private: r.isPrivate === true,
6111
+ sortKey: sortKey(r.metaSortKey)
6112
+ });
6113
+ return {
6114
+ name: text(shown?.name).trim() || "Insomnia collection",
6115
+ ...textOrUndefined(shown?.description) ? { description: textOrUndefined(shown?.description) } : {},
6116
+ format: String(raw.__export_format ?? 4),
6117
+ ...spec !== void 0 ? { spec } : {},
6118
+ items: nodes2(workspaceId, 0),
6119
+ ...base ? { base: env(base) } : {},
6120
+ subs: base ? (children.get(String(base._id)) ?? []).filter((r) => r._type === "environment").map(env) : [],
6121
+ notes
6122
+ };
6123
+ }
6124
+ var PUBLIC_ENV = /prod|live|public|sandbox/i;
6125
+ var LOCAL_ENV = /local|dev|test|mock|stag/i;
6126
+ var THIS_MACHINE = /\b(localhost|127\.\d+\.\d+\.\d+|0\.0\.0\.0|host\.docker\.internal)\b|\[::1\]/i;
6127
+ var usable = (subs) => bySortKey(subs.filter((s) => !s.private && Object.keys(s.data).length));
6128
+ function pickEnvironment(subs) {
6129
+ const reachable = usable(subs).filter((s) => !THIS_MACHINE.test(JSON.stringify(s.data)));
6130
+ return reachable.find((s) => PUBLIC_ENV.test(s.name)) ?? reachable.find((s) => !LOCAL_ENV.test(s.name)) ?? reachable[0];
6131
+ }
6132
+ function flatten(data, secret, into, prefix = "", depth = 0) {
6133
+ if (depth > 10) return;
6134
+ for (const [key, value] of Object.entries(data)) {
6135
+ const name = prefix ? `${prefix}.${key}` : key;
6136
+ const marked = secret.has(name) || secret.has(key);
6137
+ if (isObj2(value)) {
6138
+ into.set(name, { value: JSON.stringify(value), secret: marked });
6139
+ flatten(value, secret, into, name, depth + 1);
6140
+ } else if (Array.isArray(value)) into.set(name, { value: JSON.stringify(value), secret: marked });
6141
+ else if (value !== null && value !== void 0) into.set(name, { value: String(value), secret: marked });
6142
+ }
6143
+ }
6144
+ var MAX_TEMPLATE = 2e3;
6145
+ function replaceSpans(source, open, close, replace) {
6146
+ let out = "";
6147
+ let from = 0;
6148
+ for (; ; ) {
6149
+ const start = source.indexOf(open, from);
6150
+ const end = start < 0 ? -1 : source.indexOf(close, start + open.length);
6151
+ if (end < 0) break;
6152
+ const inside2 = source.slice(start + open.length, end);
6153
+ const replaced = inside2.length <= MAX_TEMPLATE ? replace(inside2) : void 0;
6154
+ out += source.slice(from, start) + (replaced ?? source.slice(start, end + close.length));
6155
+ from = end + close.length;
6156
+ }
6157
+ return out + source.slice(from);
6158
+ }
6159
+ var bare = (inside2) => inside2.replace(/^-/, "").replace(/-$/, "").trim();
6160
+ function variableName(expression) {
6161
+ let e = expression.split(/\s\|\s?|\|(?=\s*[A-Za-z])/)[0].trim();
6162
+ if (e.startsWith("_.")) e = e.slice(2);
6163
+ else if (e.startsWith("_[")) e = e.slice(1);
6164
+ e = e.replace(/\[\s*(['"])(.*?)\1\s*\]/g, ".$2").replace(/^\./, "");
6165
+ return e && !/[{}"']/.test(e) ? e : void 0;
6166
+ }
6167
+ function tagArgs(source) {
6168
+ const out = [];
6169
+ for (const m of source.matchAll(/'((?:[^'\\]|\\.)*)'|"((?:[^"\\]|\\.)*)"|(-?\d+(?:\.\d+)?)|\b(true|false)\b/g)) {
6170
+ if (m[1] !== void 0 || m[2] !== void 0) out.push(decodeArg((m[1] ?? m[2]).replace(/\\(.)/g, "$1")));
6171
+ else if (m[3] !== void 0) out.push(Number(m[3]));
6172
+ else out.push(m[4] === "true");
6173
+ }
6174
+ return out;
6175
+ }
6176
+ function decodeArg(arg) {
6177
+ const m = arg.match(/^b64::([A-Za-z0-9+/=_-]*)::46b$/);
6178
+ if (!m) return arg;
6179
+ try {
6180
+ return new TextDecoder().decode(Uint8Array.from(atob(m[1].replace(/-/g, "+").replace(/_/g, "/")), (c) => c.charCodeAt(0)));
6181
+ } catch {
6182
+ return arg;
6183
+ }
6184
+ }
6185
+ function responseField(args, requests) {
6186
+ const [attribute, from, path] = args;
6187
+ if (typeof path === "string" && path.trim()) {
6188
+ if (attribute === "header") return path.trim().replace(/[^\w.-]+/g, "_");
6189
+ if (attribute === "body") {
6190
+ const keys = [...path.matchAll(/[A-Za-z_][\w-]*(?!\s*\()/g)].map((m) => m[0]);
6191
+ const key = keys[keys.length - 1];
6192
+ const source = typeof from === "string" ? requests.get(from) : void 0;
6193
+ const resource = key === "id" && source ? resourceOf(text(source.fields.url)) : void 0;
6194
+ if (key) return resource ? `${resource}_id` : key;
6195
+ }
6196
+ }
6197
+ return "response";
6198
+ }
6199
+ function resourceOf(url) {
6200
+ const path = url.replace(/^[a-z][\w+.-]*:\/\/[^/]*/i, "").split("?")[0];
6201
+ const segments = path.split("/").filter((s) => s && !/[{}:]/.test(s) && !/^v\d+(\.\d+)*$/i.test(s));
6202
+ const last = segments[segments.length - 1];
6203
+ return last ? singular(last).replace(/[^A-Za-z0-9]+/g, "_").replace(/^_|_$/g, "").toLowerCase() || void 0 : void 0;
6204
+ }
6205
+ var wordsName = (label, fallback) => label.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "").slice(0, 40) || fallback;
6206
+ function translate(source, names, context) {
6207
+ if (!source.includes("{")) return source;
6208
+ const withTags = replaceSpans(source, "{%", "%}", (inside2) => {
6209
+ const tag2 = bare(inside2).match(/^([A-Za-z][\w-]*)([\s\S]*)$/);
6210
+ return tag2 ? tagValue(tag2[1], tagArgs(tag2[2]), names, context) : void 0;
6211
+ });
6212
+ return replaceSpans(withTags, "{{", "}}", (inside2) => {
6213
+ const expression = bare(inside2);
6214
+ if (!expression || expression.startsWith("$") || /[{}]/.test(expression)) return void 0;
6215
+ const name = variableName(expression);
6216
+ return name ? `{{${names.get(name) ?? name}}}` : void 0;
6217
+ });
6218
+ }
6219
+ function unclaimed(name, defined) {
6220
+ return defined.has(name) ? `${name}_returned` : name;
6221
+ }
6222
+ function tagValue(tag2, args, names, context) {
6223
+ const { defined } = context;
6224
+ switch (tag2) {
6225
+ case "uuid":
6226
+ return "{{$guid}}";
6227
+ case "now":
6228
+ return args[0] === "millis" ? "1767261600000" : args[0] === "unix" ? "{{$timestamp}}" : "{{$isoTimestamp}}";
6229
+ case "faker":
6230
+ return typeof args[0] === "string" && /^\w+$/.test(args[0]) ? `{{$${args[0]}}}` : void 0;
6231
+ case "response":
6232
+ return `{{${unclaimed(responseField(args, context.requests), defined)}}}`;
6233
+ case "prompt": {
6234
+ const [title, label, value, , masked] = args;
6235
+ if (typeof value === "string" && value && masked !== true) return translate(value, names, context);
6236
+ return `{{${unclaimed(wordsName(String(label || title || ""), "prompt"), defined)}}}`;
6237
+ }
6238
+ case "base64": {
6239
+ const [action, , value] = args;
6240
+ if (action === "encode" && typeof value === "string" && !/[{%]/.test(value)) {
6241
+ const bytes = new TextEncoder().encode(value);
6242
+ return btoa(String.fromCharCode(...bytes));
6243
+ }
6244
+ return `{{${unclaimed(tag2, defined)}}}`;
6245
+ }
6246
+ default:
6247
+ return `{{${unclaimed(tag2.replace(/[^\w]+/g, "_"), defined)}}}`;
6248
+ }
6249
+ }
6250
+ var OWN_HEADER = (name, value) => /^user-agent$/i.test(name) && /^insomnia\//i.test(value.trim());
6251
+ function pairsOf(list7) {
6252
+ if (!Array.isArray(list7)) return [];
6253
+ return list7.filter(isObj2).flatMap((p) => {
6254
+ const name = text(p.name);
6255
+ if (!name.trim()) return [];
6256
+ return [{ name, value: typeof p.value === "string" ? p.value : p.value === void 0 || p.value === null ? "" : String(p.value), disabled: p.disabled === true, ...textOrUndefined(p.description) ? { description: textOrUndefined(p.description) } : {} }];
6257
+ });
6258
+ }
6259
+ function ownAuth2(auth) {
6260
+ return isObj2(auth) && typeof auth.type === "string" && auth.type !== "none" && auth.disabled !== true ? auth : void 0;
6261
+ }
6262
+ var GRANTS2 = {
6263
+ authorization_code: "authorization_code",
6264
+ client_credentials: "client_credentials",
6265
+ password: "password_credentials",
6266
+ implicit: "implicit",
6267
+ mcp_auth_flow: "authorization_code"
6268
+ };
6269
+ function postmanAuth(auth, tr) {
6270
+ const s = (key) => tr(text(auth[key]));
6271
+ const list7 = (entries) => Object.entries(entries).map(([key, value]) => ({ key, value, type: "string" }));
6272
+ switch (auth.type) {
6273
+ case "bearer": {
6274
+ const prefix = text(auth.prefix).trim();
6275
+ if (prefix && !/^bearer$/i.test(prefix)) return { header: { name: "Authorization", value: `${prefix} ${s("token")}`, disabled: false } };
6276
+ return { auth: { type: "bearer", bearer: list7({ token: s("token") }) } };
6277
+ }
6278
+ case "singleToken":
6279
+ return { auth: { type: "bearer", bearer: list7({ token: s("token") }) } };
6280
+ case "basic":
6281
+ return { auth: { type: "basic", basic: list7({ username: s("username"), password: s("password") }) } };
6282
+ case "apikey":
6283
+ return { auth: { type: "apikey", apikey: list7({ key: s("key"), value: s("value"), in: auth.addTo === "queryParams" ? "query" : auth.addTo === "cookie" ? "cookie" : "header" }) } };
6284
+ case "oauth2": {
6285
+ const grant = GRANTS2[text(auth.grantType)] ?? "authorization_code";
6286
+ return { auth: { type: "oauth2", oauth2: list7({ grant_type: auth.usePkce === true && grant === "authorization_code" ? "authorization_code_with_pkce" : grant, accessTokenUrl: s("accessTokenUrl"), authUrl: s("authorizationUrl"), scope: s("scope") }) } };
6287
+ }
6288
+ case "iam":
6289
+ return { auth: { type: "awsv4" } };
6290
+ default:
6291
+ return { auth: { type: text(auth.type) } };
6292
+ }
6293
+ }
6294
+ var JSON_TYPE = /[/+]json$/i;
6295
+ function postmanBody(body, tr) {
6296
+ if (!isObj2(body)) return {};
6297
+ const media = text(body.mimeType).trim().toLowerCase();
6298
+ const params = pairsOf(body.params);
6299
+ if (media === "application/x-www-form-urlencoded") {
6300
+ return params.length ? { body: { mode: "urlencoded", urlencoded: params.map((p) => ({ key: tr(p.name), value: tr(p.value), disabled: p.disabled, ...p.description ? { description: p.description } : {} })) }, media } : {};
6301
+ }
6302
+ if (media.startsWith("multipart/")) {
6303
+ const raw = Array.isArray(body.params) ? body.params.filter(isObj2) : [];
6304
+ const fields = raw.filter((p) => text(p.name).trim());
6305
+ return fields.length ? { body: { mode: "formdata", formdata: fields.map((p) => ({ key: tr(text(p.name)), value: tr(text(p.value)), type: p.type === "file" ? "file" : "text", ...text(p.fileName) ? { src: text(p.fileName) } : {}, disabled: p.disabled === true })) }, media: "multipart/form-data" } : {};
6306
+ }
6307
+ const source = text(body.text);
6308
+ if (media === "application/graphql") {
6309
+ let parsed;
6310
+ try {
6311
+ parsed = JSON.parse(tr(source));
6312
+ } catch {
6313
+ parsed = void 0;
6314
+ }
6315
+ if (isObj2(parsed) && typeof parsed.query === "string" && parsed.query.trim()) {
6316
+ return { body: { mode: "graphql", graphql: { query: parsed.query, ...parsed.variables !== void 0 && parsed.variables !== null ? { variables: JSON.stringify(parsed.variables) } : {} } }, media: "application/json" };
6317
+ }
6318
+ return {};
6319
+ }
6320
+ if (text(body.fileName) && !source.trim()) return { body: { mode: "file", file: { src: text(body.fileName) } }, media: media || "application/octet-stream" };
6321
+ if (!source.trim()) return {};
6322
+ return { body: { mode: "raw", raw: tr(source), ...JSON_TYPE.test(media) ? { options: { raw: { language: "json" } } } : {} }, ...media ? { media } : {} };
6323
+ }
6324
+ function folderNames(items, taken, into) {
6325
+ const byNode = /* @__PURE__ */ new Map();
6326
+ const walk = (nodes2, inherited, depth) => {
6327
+ for (const node2 of nodes2) {
6328
+ if (!node2.children || depth > 50) continue;
6329
+ const names = new Map(inherited);
6330
+ const env = node2.fields.environment;
6331
+ if (isObj2(env) && Object.keys(env).length) {
6332
+ const values = /* @__PURE__ */ new Map();
6333
+ const secret = new Set([...Array.isArray(node2.fields.confidentialKeys) ? node2.fields.confidentialKeys : [], ...Array.isArray(node2.fields.kvPairData) ? node2.fields.kvPairData.filter((p) => isObj2(p) && p.type === "secret").map((p) => p.name) : []].filter((k) => typeof k === "string"));
6334
+ flatten(env, secret, values);
6335
+ for (const [name, v] of values) {
6336
+ const known = into.get(name) ?? taken.get(name);
6337
+ let unique = name;
6338
+ if (known && (known.value !== v.value || known.secret !== v.secret)) {
6339
+ for (let n = 2; into.has(unique) || taken.has(unique); n++) unique = `${name}_${n}`;
6340
+ }
6341
+ into.set(unique, v);
6342
+ names.set(name, unique);
6343
+ }
6344
+ }
6345
+ byNode.set(node2, names);
6346
+ walk(node2.children, names, depth + 1);
6347
+ }
6348
+ };
6349
+ walk(items, /* @__PURE__ */ new Map(), 0);
6350
+ return byNode;
6351
+ }
6352
+ function toPostman(w) {
6353
+ const base = /* @__PURE__ */ new Map();
6354
+ if (w.base) flatten(w.base.data, w.base.secret, base);
6355
+ const sub = pickEnvironment(w.subs);
6356
+ const subValues = /* @__PURE__ */ new Map();
6357
+ if (sub) flatten(sub.data, sub.secret, subValues);
6358
+ const all = new Map([...base, ...subValues]);
6359
+ const folderValues = /* @__PURE__ */ new Map();
6360
+ const scopes = folderNames(w.items, all, folderValues);
6361
+ const requests = /* @__PURE__ */ new Map();
6362
+ const index = (nodes2, depth = 0) => {
6363
+ for (const node2 of nodes2) {
6364
+ if (node2.children && depth < 50) index(node2.children, depth + 1);
6365
+ else if (node2.id) requests.set(node2.id, node2);
6366
+ }
6367
+ };
6368
+ index(w.items);
6369
+ const context = { defined: new Map([...all, ...folderValues]), requests };
6370
+ const left = { other: 0, private: 0 };
6371
+ const variables = (values, names = /* @__PURE__ */ new Map()) => [...values].map(([key, v]) => ({ key, value: translate(v.value, names, context), type: v.secret || secretName(key) || SECRET_VALUE.test(v.value.trim()) ? "secret" : "default" }));
6372
+ const items = (nodes2, inheritedHeaders, names, depth) => bySortKey(nodes2).flatMap((node2) => {
6373
+ if (node2.private) {
6374
+ left.private++;
6375
+ return [];
6376
+ }
6377
+ if (node2.children) {
6378
+ const own = scopes.get(node2) ?? names;
6379
+ const tr = (s) => translate(s, own, context);
6380
+ const headers = [...inheritedHeaders, ...pairsOf(node2.fields.headers).filter((h) => !h.disabled)];
6381
+ const auth = ownAuth2(node2.fields.authentication);
6382
+ const converted = auth ? postmanAuth(auth, tr) : {};
6383
+ const folderHeaders = converted.header ? [...headers, converted.header] : headers;
6384
+ return [{ id: node2.id, name: node2.name, ...node2.description ? { description: node2.description } : {}, ...converted.auth ? { auth: converted.auth } : {}, item: items(node2.children, folderHeaders, own, depth + 1) }];
6385
+ }
6386
+ if (node2.other) {
6387
+ left.other++;
6388
+ return [];
6389
+ }
6390
+ return [postmanRequest(node2, inheritedHeaders, (s) => translate(s, names, context))];
6391
+ });
6392
+ const collection = {
6393
+ info: { name: w.name, ...w.description ? { description: w.description } : {}, schema: "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" },
6394
+ item: items(w.items, [], /* @__PURE__ */ new Map(), 0),
6395
+ variable: [...variables(base), ...variables(folderValues)]
6396
+ };
6397
+ const environment = sub ? { name: sub.name, values: variables(subValues), _postman_variable_scope: "environment" } : void 0;
6398
+ const notes = [];
6399
+ const others = usable(w.subs).filter((s) => s !== sub).map((s) => `"${s.name}"`);
6400
+ if (others.length) notes.push(sub ? `The collection's other environments (${list3(others)}) were left out.` : `Its base environment fills in its variables: ${list3(others)} ${others.length === 1 ? "points" : "point"} at this machine, so ${others.length === 1 ? "it was" : "they were"} left out.`);
6401
+ if (left.other) notes.push(`${left.other} ${left.other === 1 ? "request isn't an HTTP one (gRPC, WebSocket, Socket.IO or MCP), so it was" : "requests aren't HTTP ones (gRPC, WebSocket, Socket.IO or MCP), so they were"} left out.`);
6402
+ if (left.private) notes.push(`${left.private} private ${left.private === 1 ? "request or folder was" : "requests or folders were"} left out.`);
6403
+ return { collection, ...environment ? { environment } : {}, notes };
6404
+ }
6405
+ function list3(names) {
6406
+ return `${names.slice(0, 3).join(", ")}${names.length > 3 ? "\u2026" : ""}`;
6407
+ }
6408
+ function postmanRequest(node2, inheritedHeaders, tr) {
6409
+ const f = node2.fields;
6410
+ const auth = ownAuth2(f.authentication);
6411
+ const converted = auth ? postmanAuth(auth, tr) : {};
6412
+ const { body, media } = postmanBody(f.body, tr);
6413
+ const own = pairsOf(f.headers).filter((h) => !h.disabled);
6414
+ const headers = [...inheritedHeaders.filter((h) => !own.some((o) => o.name.toLowerCase() === h.name.toLowerCase())), ...own, ...converted.header ? [converted.header] : []].filter((h) => !OWN_HEADER(h.name, h.value));
6415
+ if (media && !headers.some((h) => /^content-type$/i.test(h.name))) headers.push({ name: "Content-Type", value: media, disabled: false });
6416
+ const url = tr(text(f.url)).trim();
6417
+ const q = url.indexOf("?");
6418
+ const query = [
6419
+ ...q < 0 ? [] : url.slice(q + 1).split("&").filter(Boolean).map((pair) => {
6420
+ const eq = pair.indexOf("=");
6421
+ return { key: decoded2(eq < 0 ? pair : pair.slice(0, eq)), value: eq < 0 ? "" : decoded2(pair.slice(eq + 1)) };
6422
+ }),
6423
+ ...pairsOf(f.parameters).map((p) => ({ key: tr(p.name), value: tr(p.value), ...p.disabled ? { disabled: true } : {}, ...p.description ? { description: p.description } : {} }))
6424
+ ];
6425
+ const pathParameters = Array.isArray(f.pathParameters) ? f.pathParameters.filter(isObj2) : [];
6426
+ return {
6427
+ id: node2.id,
6428
+ name: node2.name,
6429
+ request: {
6430
+ method: text(f.method).trim() || "GET",
6431
+ url: { raw: url, query, variable: pathParameters.map((p) => ({ key: text(p.name), value: tr(text(p.value)) })) },
6432
+ header: headers.map((h) => ({ key: tr(h.name), value: tr(h.value), ...h.description ? { description: h.description } : {} })),
6433
+ ...body ? { body } : {},
6434
+ ...converted.auth ? { auth: converted.auth } : {},
6435
+ ...node2.description ? { description: node2.description } : {}
6436
+ },
6437
+ response: []
6438
+ };
6439
+ }
6440
+ function decoded2(value) {
6441
+ try {
6442
+ return decodeURIComponent(value.replace(/\+/g, " "));
6443
+ } catch {
6444
+ return value;
6445
+ }
6446
+ }
6447
+
6448
+ // ../../lib/oas/swagger1.ts
6449
+ var isObj3 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
5958
6450
  function isSwagger1(doc) {
5959
- return isObj2(doc) && doc.swaggerVersion !== void 0 && doc.swagger === void 0 && doc.openapi === void 0;
6451
+ return isObj3(doc) && doc.swaggerVersion !== void 0 && doc.swagger === void 0 && doc.openapi === void 0;
5960
6452
  }
5961
6453
  function namesDeclarations(doc) {
5962
- return !inline(doc) && arr(doc.apis).some((api) => isObj2(api) && typeof api.path === "string");
6454
+ return !inline(doc) && arr(doc.apis).some((api) => isObj3(api) && typeof api.path === "string");
5963
6455
  }
5964
6456
  function inline(doc) {
5965
- return doc.resourcePath !== void 0 || arr(doc.apis).some((api) => isObj2(api) && api.operations !== void 0);
6457
+ return doc.resourcePath !== void 0 || arr(doc.apis).some((api) => isObj3(api) && api.operations !== void 0);
5966
6458
  }
5967
6459
  function declarationUrls(listing, url) {
5968
6460
  const out = /* @__PURE__ */ new Map();
@@ -5977,7 +6469,7 @@ function declarationUrls(listing, url) {
5977
6469
  }
5978
6470
  if (String(listing.swaggerVersion) === "1.0" && /\.json$/i.test(base.pathname)) base = new URL(".", base);
5979
6471
  for (const api of arr(listing.apis)) {
5980
- if (!isObj2(api) || typeof api.path !== "string" || api.operations !== void 0) continue;
6472
+ if (!isObj3(api) || typeof api.path !== "string" || api.operations !== void 0) continue;
5981
6473
  const path = api.path.replace("{format}", "json");
5982
6474
  try {
5983
6475
  const target = /^[a-z][a-z\d+.-]*:/i.test(path) ? new URL(path) : new URL(`${base.href.replace(/\/$/, "")}/${path.replace(/^\//, "")}`);
@@ -5994,9 +6486,9 @@ function convertSwagger1(root, declaration = () => void 0) {
5994
6486
  if (inline(root)) resources.push({ doc: root });
5995
6487
  else {
5996
6488
  for (const api of arr(root.apis)) {
5997
- if (!isObj2(api) || typeof api.path !== "string") continue;
6489
+ if (!isObj3(api) || typeof api.path !== "string") continue;
5998
6490
  const doc2 = declaration(api.path);
5999
- if (!isObj2(doc2)) {
6491
+ if (!isObj3(doc2)) {
6000
6492
  missing.push(api.path);
6001
6493
  continue;
6002
6494
  }
@@ -6004,13 +6496,13 @@ function convertSwagger1(root, declaration = () => void 0) {
6004
6496
  resources.push({ doc: doc2, tag: name ? { name, ...typeof api.description === "string" ? { description: api.description } : {} } : void 0 });
6005
6497
  }
6006
6498
  }
6007
- const models = new Set(resources.flatMap(({ doc: doc2 }) => isObj2(doc2.models) ? Object.keys(doc2.models) : []));
6499
+ const models = new Set(resources.flatMap(({ doc: doc2 }) => isObj3(doc2.models) ? Object.keys(doc2.models) : []));
6008
6500
  const types2 = new TypeMapper(models);
6009
- const { definitions: securityDefinitions, names: securityNames } = securityDefinitionsOf(isObj2(root.authorizations) ? root.authorizations : {});
6501
+ const { definitions: securityDefinitions, names: securityNames } = securityDefinitionsOf(isObj3(root.authorizations) ? root.authorizations : {});
6010
6502
  const security = (auth) => {
6011
- if (!isObj2(auth)) return void 0;
6503
+ if (!isObj3(auth)) return void 0;
6012
6504
  return Object.entries(auth).flatMap(
6013
- ([name, scopes]) => (securityNames.get(name) ?? [name]).map((n) => ({ [n]: arr(scopes).flatMap((s) => isObj2(s) && typeof s.scope === "string" ? [s.scope] : []) }))
6505
+ ([name, scopes]) => (securityNames.get(name) ?? [name]).map((n) => ({ [n]: arr(scopes).flatMap((s) => isObj3(s) && typeof s.scope === "string" ? [s.scope] : []) }))
6014
6506
  );
6015
6507
  };
6016
6508
  const bases = resources.map(({ doc: doc2 }) => baseOf(doc2.basePath ?? root.basePath, root.basePath));
@@ -6022,7 +6514,7 @@ function convertSwagger1(root, declaration = () => void 0) {
6022
6514
  const definitions = {};
6023
6515
  let anySecurity = false;
6024
6516
  resources.forEach(({ doc: doc2, tag: tag2 }, i) => {
6025
- Object.assign(definitions, definitionsOf(isObj2(doc2.models) ? doc2.models : {}, types2));
6517
+ Object.assign(definitions, definitionsOf(isObj3(doc2.models) ? doc2.models : {}, types2));
6026
6518
  const defaults = {
6027
6519
  produces: strings(doc2.produces),
6028
6520
  consumes: strings(doc2.consumes),
@@ -6030,11 +6522,11 @@ function convertSwagger1(root, declaration = () => void 0) {
6030
6522
  tags: tag2 ? [tag2.name] : void 0
6031
6523
  };
6032
6524
  for (const api of arr(doc2.apis)) {
6033
- if (!isObj2(api) || typeof api.path !== "string" || !Array.isArray(api.operations)) continue;
6525
+ if (!isObj3(api) || typeof api.path !== "string" || !Array.isArray(api.operations)) continue;
6034
6526
  const path = `${prefixes[i].slice(common2.length)}/${api.path.replace(/^\//, "").replace("{format}", "json")}`.replace(/\/$/, "") || "/";
6035
- const item = isObj2(paths[path]) ? paths[path] : paths[path] = {};
6527
+ const item = isObj3(paths[path]) ? paths[path] : paths[path] = {};
6036
6528
  for (const op of api.operations) {
6037
- if (!isObj2(op)) continue;
6529
+ if (!isObj3(op)) continue;
6038
6530
  const method = String(op.method ?? op.httpMethod ?? "get").toLowerCase();
6039
6531
  const opSecurity = security(op.authorizations) ?? defaults.security;
6040
6532
  if (opSecurity?.length) anySecurity = true;
@@ -6046,7 +6538,7 @@ function convertSwagger1(root, declaration = () => void 0) {
6046
6538
  deprecated: lenient(op.deprecated) === true ? true : void 0,
6047
6539
  produces: strings(op.produces) ?? defaults.produces,
6048
6540
  consumes: strings(op.consumes) ?? defaults.consumes,
6049
- parameters: arr(op.parameters).flatMap((p) => isObj2(p) ? [parameterOf(p, types2)] : []),
6541
+ parameters: arr(op.parameters).flatMap((p) => isObj3(p) ? [parameterOf(p, types2)] : []),
6050
6542
  responses: responsesOf2(op, types2),
6051
6543
  security: opSecurity
6052
6544
  });
@@ -6057,7 +6549,7 @@ function convertSwagger1(root, declaration = () => void 0) {
6057
6549
  });
6058
6550
  const firstScheme = Object.keys(securityDefinitions)[0];
6059
6551
  const host = origin && origin !== "null" ? new URL(origin) : void 0;
6060
- const info = isObj2(root.info) ? root.info : {};
6552
+ const info = isObj3(root.info) ? root.info : {};
6061
6553
  const doc = clean({
6062
6554
  swagger: "2.0",
6063
6555
  info: clean({
@@ -6130,11 +6622,11 @@ var TypeMapper = class {
6130
6622
  const out = this.named(old.type ?? old.dataType ?? old.responseClass ?? old.$ref, allowRef);
6131
6623
  if (old.items !== void 0) {
6132
6624
  const items = typeof old.items === "string" ? { type: old.items } : old.items;
6133
- if (isObj2(items)) out.items = this.data(items, allowRef);
6625
+ if (isObj3(items)) out.items = this.data(items, allowRef);
6134
6626
  }
6135
- if (out.type === "array" && !isObj2(out.items)) out.items = {};
6627
+ if (out.type === "array" && !isObj3(out.items)) out.items = {};
6136
6628
  const defaultValue = old.defaultValue ?? old.default;
6137
- const allowable = isObj2(old.allowableValues) ? old.allowableValues : void 0;
6629
+ const allowable = isObj3(old.allowableValues) ? old.allowableValues : void 0;
6138
6630
  const valueType = String(allowable?.valueType ?? "").toUpperCase();
6139
6631
  return clean({
6140
6632
  ...out,
@@ -6184,14 +6676,14 @@ function parameterOf(old, types2) {
6184
6676
  if (where === "body") return { ...base, schema: types2.data(old, true) };
6185
6677
  let schema2 = types2.data(old, false);
6186
6678
  if (schema2.type === void 0 || schema2.$ref !== void 0) schema2 = { ...schema2, $ref: void 0, type: "string" };
6187
- if (schema2.type === "array" && isObj2(schema2.items) && schema2.items.type === void 0) schema2.items = { ...schema2.items, type: "string" };
6679
+ if (schema2.type === "array" && isObj3(schema2.items) && schema2.items.type === void 0) schema2.items = { ...schema2.items, type: "string" };
6188
6680
  if (lenient(old.allowMultiple) === true && schema2.type !== "array") schema2 = { type: "array", items: schema2 };
6189
6681
  return clean({ ...base, ...schema2 });
6190
6682
  }
6191
6683
  function responsesOf2(op, types2) {
6192
6684
  const responses = {};
6193
6685
  for (const r of [...arr(op.responseMessages), ...arr(op.errorResponses)]) {
6194
- if (!isObj2(r) || r.code === void 0) continue;
6686
+ if (!isObj3(r) || r.code === void 0) continue;
6195
6687
  const schema2 = types2.named(r.responseModel, true);
6196
6688
  responses[String(r.code)] = clean({ description: String(r.message ?? r.reason ?? ""), schema: Object.keys(schema2).length ? schema2 : void 0 });
6197
6689
  }
@@ -6203,10 +6695,10 @@ function responsesOf2(op, types2) {
6203
6695
  }
6204
6696
  function definitionsOf(models, types2) {
6205
6697
  const out = {};
6206
- for (const [id, model] of Object.entries(models)) if (isObj2(model)) out[id] = modelOf(model, types2);
6698
+ for (const [id, model] of Object.entries(models)) if (isObj3(model)) out[id] = modelOf(model, types2);
6207
6699
  for (const [id, parent] of Object.entries(models)) {
6208
- for (const child of arr(isObj2(parent) ? parent.subTypes : void 0)) {
6209
- if (typeof child !== "string" || !isObj2(out[child])) continue;
6700
+ for (const child of arr(isObj3(parent) ? parent.subTypes : void 0)) {
6701
+ if (typeof child !== "string" || !isObj3(out[child])) continue;
6210
6702
  const current2 = out[child];
6211
6703
  out[child] = { allOf: [...Array.isArray(current2.allOf) ? current2.allOf : [current2], { $ref: `#/definitions/${id}` }] };
6212
6704
  }
@@ -6216,8 +6708,8 @@ function definitionsOf(models, types2) {
6216
6708
  function modelOf(old, types2) {
6217
6709
  const properties = {};
6218
6710
  const required = Array.isArray(old.required) ? old.required.filter((r) => typeof r === "string") : [];
6219
- for (const [name, prop] of Object.entries(isObj2(old.properties) ? old.properties : {})) {
6220
- if (!isObj2(prop)) continue;
6711
+ for (const [name, prop] of Object.entries(isObj3(old.properties) ? old.properties : {})) {
6712
+ if (!isObj3(prop)) continue;
6221
6713
  if (lenient(prop.required) === true && !required.includes(name)) required.push(name);
6222
6714
  properties[name] = modelOf(prop, types2);
6223
6715
  }
@@ -6229,15 +6721,15 @@ function modelOf(old, types2) {
6229
6721
  properties: Object.keys(properties).length ? properties : void 0,
6230
6722
  discriminator: typeof old.discriminator === "string" ? old.discriminator : void 0,
6231
6723
  example: old.example,
6232
- items: isObj2(old.items) ? modelOf(old.items, types2) : void 0
6724
+ items: isObj3(old.items) ? modelOf(old.items, types2) : void 0
6233
6725
  });
6234
6726
  }
6235
6727
  function securityDefinitionsOf(old) {
6236
6728
  const definitions = {};
6237
6729
  const names = /* @__PURE__ */ new Map();
6238
6730
  for (const [name, auth] of Object.entries(old)) {
6239
- if (!isObj2(auth)) continue;
6240
- const scopes = Object.fromEntries(arr(auth.scopes).flatMap((s) => isObj2(s) && typeof s.scope === "string" ? [[s.scope, typeof s.description === "string" ? s.description : s.scope]] : []));
6731
+ if (!isObj3(auth)) continue;
6732
+ const scopes = Object.fromEntries(arr(auth.scopes).flatMap((s) => isObj3(s) && typeof s.scope === "string" ? [[s.scope, typeof s.description === "string" ? s.description : s.scope]] : []));
6241
6733
  if (auth.type === "basicAuth" || auth.type === "basic") {
6242
6734
  definitions[name] = { type: "basic" };
6243
6735
  names.set(name, [name]);
@@ -6245,11 +6737,11 @@ function securityDefinitionsOf(old) {
6245
6737
  definitions[name] = { type: "apiKey", in: auth.passAs === "query" ? "query" : "header", name: typeof auth.keyname === "string" ? auth.keyname : "api_key" };
6246
6738
  names.set(name, [name]);
6247
6739
  } else if (auth.type === "oauth2") {
6248
- const grants = isObj2(auth.grantTypes) ? Object.entries(auth.grantTypes) : [];
6740
+ const grants = isObj3(auth.grantTypes) ? Object.entries(auth.grantTypes) : [];
6249
6741
  const made = [];
6250
6742
  for (const [grant, detail] of grants) {
6251
- const d = isObj2(detail) ? detail : {};
6252
- const endpoint = (key2) => isObj2(d[key2]) && typeof d[key2].url === "string" ? d[key2].url : void 0;
6743
+ const d = isObj3(detail) ? detail : {};
6744
+ const endpoint = (key2) => isObj3(d[key2]) && typeof d[key2].url === "string" ? d[key2].url : void 0;
6253
6745
  const flow = grant === "implicit" ? clean({ flow: "implicit", authorizationUrl: endpoint("loginEndpoint") }) : grant === "authorization_code" ? clean({ flow: "accessCode", authorizationUrl: endpoint("tokenRequestEndpoint"), tokenUrl: endpoint("tokenEndpoint") }) : void 0;
6254
6746
  if (!flow) continue;
6255
6747
  const key = grants.length > 1 ? `${name}_${flow.flow}` : name;
@@ -6278,7 +6770,7 @@ function clean(obj) {
6278
6770
  for (const [key, value] of Object.entries(obj)) {
6279
6771
  if (value === void 0) continue;
6280
6772
  if (Array.isArray(value) && value.length === 0) continue;
6281
- if (isObj2(value) && Object.keys(value).length === 0 && key !== "paths" && key !== "schema" && key !== "items") continue;
6773
+ if (isObj3(value) && Object.keys(value).length === 0 && key !== "paths" && key !== "schema" && key !== "items") continue;
6282
6774
  out[key] = value;
6283
6775
  }
6284
6776
  return out;
@@ -6291,27 +6783,27 @@ function strings(value) {
6291
6783
  }
6292
6784
 
6293
6785
  // ../../lib/oas/swagger2.ts
6294
- var isObj3 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
6786
+ var isObj4 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
6295
6787
  var SCHEMA_FIELDS = ["type", "format", "items", "enum", "default", "minimum", "maximum", "exclusiveMinimum", "exclusiveMaximum", "minLength", "maxLength", "pattern", "minItems", "maxItems", "uniqueItems", "multipleOf"];
6296
6788
  var OAUTH_FLOWS = { implicit: "implicit", password: "password", application: "clientCredentials", accessCode: "authorizationCode" };
6297
6789
  function convertSwagger2(doc) {
6298
6790
  const consumes = strings2(doc.consumes) ?? ["application/json"];
6299
6791
  const produces = strings2(doc.produces) ?? ["application/json"];
6300
- const sharedParams = isObj3(doc.parameters) ? doc.parameters : {};
6792
+ const sharedParams = isObj4(doc.parameters) ? doc.parameters : {};
6301
6793
  const resolveParam = (p) => {
6302
- const ref = isObj3(p) && typeof p.$ref === "string" ? p.$ref.match(/^#\/parameters\/(.+)$/)?.[1] : void 0;
6794
+ const ref = isObj4(p) && typeof p.$ref === "string" ? p.$ref.match(/^#\/parameters\/(.+)$/)?.[1] : void 0;
6303
6795
  return ref !== void 0 ? sharedParams[decodePointer(ref)] : p;
6304
6796
  };
6305
6797
  const paths = {};
6306
- for (const [path, rawItem] of Object.entries(isObj3(doc.paths) ? doc.paths : {})) {
6307
- if (!isObj3(rawItem)) continue;
6798
+ for (const [path, rawItem] of Object.entries(isObj4(doc.paths) ? doc.paths : {})) {
6799
+ if (!isObj4(rawItem)) continue;
6308
6800
  const item = {};
6309
6801
  const pathParams = arr2(rawItem.parameters).map(resolveParam);
6310
- const plain = pathParams.filter((p) => isObj3(p) && p.in !== "body" && p.in !== "formData");
6802
+ const plain = pathParams.filter((p) => isObj4(p) && p.in !== "body" && p.in !== "formData");
6311
6803
  if (plain.length) item.parameters = plain.map(convertParameter);
6312
6804
  for (const method of ["get", "put", "post", "delete", "options", "head", "patch"]) {
6313
6805
  const op = rawItem[method];
6314
- if (!isObj3(op)) continue;
6806
+ if (!isObj4(op)) continue;
6315
6807
  const params = mergeParams(pathParams, arr2(op.parameters).map(resolveParam));
6316
6808
  const out2 = {};
6317
6809
  for (const key of ["operationId", "summary", "description", "tags", "deprecated", "security", "externalDocs"]) if (op[key] !== void 0) out2[key] = op[key];
@@ -6325,9 +6817,9 @@ function convertSwagger2(doc) {
6325
6817
  paths[path] = item;
6326
6818
  }
6327
6819
  const components = {};
6328
- if (isObj3(doc.definitions)) components.schemas = convertSchemas(doc.definitions);
6329
- if (isObj3(doc.responses)) components.responses = Object.fromEntries(Object.entries(doc.responses).map(([k, r]) => [k, convertResponse(r, produces)]));
6330
- if (isObj3(doc.securityDefinitions)) components.securitySchemes = Object.fromEntries(Object.entries(doc.securityDefinitions).map(([k, s]) => [k, convertSecurity(s)]));
6820
+ if (isObj4(doc.definitions)) components.schemas = convertSchemas(doc.definitions);
6821
+ if (isObj4(doc.responses)) components.responses = Object.fromEntries(Object.entries(doc.responses).map(([k, r]) => [k, convertResponse(r, produces)]));
6822
+ if (isObj4(doc.securityDefinitions)) components.securitySchemes = Object.fromEntries(Object.entries(doc.securityDefinitions).map(([k, s]) => [k, convertSecurity(s)]));
6331
6823
  const out = { openapi: "3.0.3", info: doc.info, paths, ...Object.keys(components).length ? { components } : {} };
6332
6824
  const servers = serversOf(doc);
6333
6825
  if (servers.length) out.servers = servers;
@@ -6346,11 +6838,11 @@ function serversOf(doc) {
6346
6838
  }
6347
6839
  function mergeParams(shared, own) {
6348
6840
  const byKey = /* @__PURE__ */ new Map();
6349
- for (const p of [...shared, ...own]) if (isObj3(p) && typeof p.name === "string") byKey.set(`${p.in}:${p.name}`, p);
6841
+ for (const p of [...shared, ...own]) if (isObj4(p) && typeof p.name === "string") byKey.set(`${p.in}:${p.name}`, p);
6350
6842
  return [...byKey.values()];
6351
6843
  }
6352
6844
  function convertParameter(raw) {
6353
- const p = isObj3(raw) ? raw : {};
6845
+ const p = isObj4(raw) ? raw : {};
6354
6846
  const out = { name: p.name, in: p.in };
6355
6847
  for (const key of ["description", "required", "deprecated", "allowEmptyValue"]) if (p[key] !== void 0) out[key] = p[key];
6356
6848
  out.schema = schemaFromFields(p);
@@ -6359,7 +6851,7 @@ function convertParameter(raw) {
6359
6851
  }
6360
6852
  function schemaFromFields(p) {
6361
6853
  const schema2 = {};
6362
- for (const key of SCHEMA_FIELDS) if (p[key] !== void 0) schema2[key] = key === "items" && isObj3(p.items) ? schemaFromFields(p.items) : p[key];
6854
+ for (const key of SCHEMA_FIELDS) if (p[key] !== void 0) schema2[key] = key === "items" && isObj4(p.items) ? schemaFromFields(p.items) : p[key];
6363
6855
  if (schema2.type === "file") return { type: "string", format: "binary" };
6364
6856
  return schema2;
6365
6857
  }
@@ -6381,15 +6873,15 @@ function requestBody(params, consumes) {
6381
6873
  }
6382
6874
  function convertResponses(raw, produces) {
6383
6875
  const out = {};
6384
- for (const [status, response] of Object.entries(isObj3(raw) ? raw : {})) out[status] = convertResponse(response, produces);
6876
+ for (const [status, response] of Object.entries(isObj4(raw) ? raw : {})) out[status] = convertResponse(response, produces);
6385
6877
  return out;
6386
6878
  }
6387
6879
  function convertResponse(raw, produces) {
6388
- const r = isObj3(raw) ? raw : {};
6880
+ const r = isObj4(raw) ? raw : {};
6389
6881
  if (typeof r.$ref === "string") return { $ref: r.$ref };
6390
6882
  const out = { description: typeof r.description === "string" ? r.description : "" };
6391
- if (isObj3(r.headers)) out.headers = Object.fromEntries(Object.entries(r.headers).map(([name, h]) => [name, { ...isObj3(h) && typeof h.description === "string" ? { description: h.description } : {}, schema: schemaFromFields(isObj3(h) ? h : {}) }]));
6392
- const examples = isObj3(r.examples) ? r.examples : {};
6883
+ if (isObj4(r.headers)) out.headers = Object.fromEntries(Object.entries(r.headers).map(([name, h]) => [name, { ...isObj4(h) && typeof h.description === "string" ? { description: h.description } : {}, schema: schemaFromFields(isObj4(h) ? h : {}) }]));
6884
+ const examples = isObj4(r.examples) ? r.examples : {};
6393
6885
  if (r.schema !== void 0 || Object.keys(examples).length) {
6394
6886
  const types2 = [.../* @__PURE__ */ new Set([...produces, ...Object.keys(examples)])];
6395
6887
  out.content = Object.fromEntries(
@@ -6403,7 +6895,7 @@ function convertSchemas(defs) {
6403
6895
  }
6404
6896
  function convertSchema(raw) {
6405
6897
  if (Array.isArray(raw)) return raw.map(convertSchema);
6406
- if (!isObj3(raw)) return raw;
6898
+ if (!isObj4(raw)) return raw;
6407
6899
  const out = {};
6408
6900
  for (const [key, value] of Object.entries(raw)) {
6409
6901
  if (key === "x-nullable") out.nullable = value;
@@ -6417,12 +6909,12 @@ function convertSchema(raw) {
6417
6909
  return out;
6418
6910
  }
6419
6911
  function convertSecurity(raw) {
6420
- const s = isObj3(raw) ? raw : {};
6912
+ const s = isObj4(raw) ? raw : {};
6421
6913
  if (s.type === "basic") return { type: "http", scheme: "basic", ...typeof s.description === "string" ? { description: s.description } : {} };
6422
6914
  if (s.type === "apiKey") return { type: "apiKey", name: s.name, in: s.in };
6423
6915
  if (s.type === "oauth2") {
6424
6916
  const flow = OAUTH_FLOWS[String(s.flow)] ?? "clientCredentials";
6425
- const details = { scopes: isObj3(s.scopes) ? s.scopes : {} };
6917
+ const details = { scopes: isObj4(s.scopes) ? s.scopes : {} };
6426
6918
  if (typeof s.authorizationUrl === "string") details.authorizationUrl = s.authorizationUrl;
6427
6919
  if (typeof s.tokenUrl === "string") details.tokenUrl = s.tokenUrl;
6428
6920
  return { type: "oauth2", flows: { [flow]: details } };
@@ -6431,7 +6923,7 @@ function convertSecurity(raw) {
6431
6923
  }
6432
6924
  function rewriteRefs(node2) {
6433
6925
  if (Array.isArray(node2)) return node2.map(rewriteRefs);
6434
- if (!isObj3(node2)) return node2;
6926
+ if (!isObj4(node2)) return node2;
6435
6927
  const out = {};
6436
6928
  for (const [key, value] of Object.entries(node2)) {
6437
6929
  if (key === "$ref" && typeof value === "string") out[key] = value.replace(/^#\/definitions\//, "#/components/schemas/").replace(/^#\/responses\//, "#/components/responses/");
@@ -6455,12 +6947,12 @@ var HTTP_METHODS = ["get", "post", "put", "patch", "delete", "head", "options",
6455
6947
  var SAFE_METHODS = /* @__PURE__ */ new Set(["get", "head", "options", "trace", "query"]);
6456
6948
  var METHOD_TOKEN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
6457
6949
  function operationsOf(item) {
6458
- if (!isObj4(item)) return [];
6950
+ if (!isObj5(item)) return [];
6459
6951
  const out = [];
6460
- for (const method of HTTP_METHODS) if (isObj4(item[method])) out.push([method, item[method]]);
6461
- if (isObj4(item.additionalOperations)) {
6952
+ for (const method of HTTP_METHODS) if (isObj5(item[method])) out.push([method, item[method]]);
6953
+ if (isObj5(item.additionalOperations)) {
6462
6954
  for (const [method, op] of Object.entries(item.additionalOperations)) {
6463
- if (isObj4(op) && METHOD_TOKEN.test(method) && !HTTP_METHODS.includes(method.toLowerCase())) out.push([method, op]);
6955
+ if (isObj5(op) && METHOD_TOKEN.test(method) && !HTTP_METHODS.includes(method.toLowerCase())) out.push([method, op]);
6464
6956
  }
6465
6957
  }
6466
6958
  return out;
@@ -6468,7 +6960,7 @@ function operationsOf(item) {
6468
6960
  function methodName(method) {
6469
6961
  return HTTP_METHODS.includes(method) ? method.toUpperCase() : method;
6470
6962
  }
6471
- function isObj4(value) {
6963
+ function isObj5(value) {
6472
6964
  return typeof value === "object" && value !== null && !Array.isArray(value);
6473
6965
  }
6474
6966
 
@@ -6523,8 +7015,8 @@ function wrongKindWarning(wrong) {
6523
7015
  const named = [...wrong].slice(0, 3).map(([key, kind]) => `"${key}" should be ${kind}`);
6524
7016
  return `Some fields hold the wrong kind of value, so they were left out: ${named.join(", ")}${wrong.size > 3 ? "\u2026" : ""}.`;
6525
7017
  }
6526
- function checkSize(text2) {
6527
- if (text2.length > MAX_SPEC_BYTES) {
7018
+ function checkSize(text3) {
7019
+ if (text3.length > MAX_SPEC_BYTES) {
6528
7020
  throw new SpecError(`Spec is larger than ${MAX_SPEC_BYTES / 1024 / 1024} MB.`);
6529
7021
  }
6530
7022
  }
@@ -6533,11 +7025,37 @@ function parseSpec(input, options = {}) {
6533
7025
  let raw = input;
6534
7026
  const warnings = [];
6535
7027
  const missing = [];
7028
+ let environments = options.environments;
7029
+ let source;
7030
+ const insomnia = insomniaKind(raw);
7031
+ if (insomnia === "environment") throw new SpecError("This is an Insomnia environment, which holds a collection's variables but no requests.", ["Export the collection or design document that uses it."]);
7032
+ if (insomnia === "mock") throw new SpecError("This is an Insomnia mock server, which answers requests but holds no flow of them.", ["Export the collection or design document it mocks."]);
7033
+ if (insomnia === "mcp") {
7034
+ const url = insomniaMcpUrl(raw);
7035
+ throw new SpecError("This is an Insomnia MCP client, which holds the server's address but none of its tools.", [url ? `Load the MCP server from its URL instead: ${url}` : "Load the MCP server from its URL instead."]);
7036
+ }
7037
+ if (insomnia) {
7038
+ let read2;
7039
+ try {
7040
+ read2 = readInsomnia(raw, options.parseYaml);
7041
+ } catch (err) {
7042
+ throw new SpecError(`This Insomnia export can't be read. ${err.message}`);
7043
+ }
7044
+ if (read2.spec !== void 0) {
7045
+ warnings.push(`This is ${read2.label}.`, ...read2.notes);
7046
+ raw = read2.spec;
7047
+ } else {
7048
+ raw = read2.collection;
7049
+ environments = read2.environment ? [read2.environment] : [];
7050
+ source = { app: "Insomnia", intro: `This is ${read2.label}, converted to OpenAPI 3.0 when it loaded.`, idsField: INSOMNIA_IDS };
7051
+ warnings.push(...read2.notes);
7052
+ }
7053
+ }
6536
7054
  const postman = isPostmanCollection(raw);
6537
7055
  if (postman) {
6538
- const converted = convertPostman(raw, options.environments);
6539
- if (!Object.keys(converted.doc.paths).length) throw new SpecError("This Postman collection has no requests to animate.");
6540
- warnings.push(...converted.warnings);
7056
+ const converted = convertPostman(raw, environments, source);
7057
+ if (!Object.keys(converted.doc.paths).length) throw new SpecError(`This ${source?.app ?? "Postman"} collection has no ${source ? "HTTP " : ""}requests to animate.`);
7058
+ warnings.unshift(...converted.warnings);
6541
7059
  raw = converted.doc;
6542
7060
  } else if (isPostmanEnvironment(raw)) {
6543
7061
  throw new SpecError("This is a Postman environment, which holds a collection's variables but no requests.", ["Upload it together with its collection."]);
@@ -6552,12 +7070,12 @@ function parseSpec(input, options = {}) {
6552
7070
  return url === void 0 ? void 0 : options.external?.docs.get(url);
6553
7071
  });
6554
7072
  if (converted.missing.length && !Object.keys(converted.doc.paths ?? {}).length) {
6555
- throw new SpecError(`This Swagger ${version2} resource listing keeps its API in other files: ${list3(converted.missing)}.`, [
7073
+ throw new SpecError(`This Swagger ${version2} resource listing keeps its API in other files: ${list4(converted.missing)}.`, [
6556
7074
  options.external && !options.external.url.startsWith(UPLOAD_ORIGIN) ? "Those files didn't load. Check that the site serves them, or upload the listing together with them." : "Load the listing from its URL, or upload it together with those files."
6557
7075
  ]);
6558
7076
  }
6559
7077
  warnings.push(`This is a Swagger ${version2} spec, converted to OpenAPI 3.0 when it loaded.`, ...converted.warnings);
6560
- if (converted.missing.length) warnings.push(`Couldn't load the API declarations for ${list3(converted.missing)}.`);
7078
+ if (converted.missing.length) warnings.push(`Couldn't load the API declarations for ${list4(converted.missing)}.`);
6561
7079
  missing.push(...converted.missing);
6562
7080
  raw = converted.doc;
6563
7081
  }
@@ -6573,12 +7091,22 @@ function parseSpec(input, options = {}) {
6573
7091
  if (!postman) collectWarnings(resolved, warnings);
6574
7092
  return { doc: resolved, warnings, ...missing.length ? { missing } : {} };
6575
7093
  }
6576
- function decode(text2, options) {
6577
- const trimmed = text2.trimStart();
7094
+ function tryYaml(text3, options) {
7095
+ try {
7096
+ const value = options.parseYaml?.(text3);
7097
+ return value !== null && typeof value === "object" ? value : void 0;
7098
+ } catch {
7099
+ return void 0;
7100
+ }
7101
+ }
7102
+ function decode(text3, options) {
7103
+ const trimmed = text3.trimStart();
6578
7104
  if (trimmed.startsWith("{")) {
6579
7105
  try {
6580
7106
  return JSON.parse(trimmed);
6581
7107
  } catch (err) {
7108
+ const yaml2 = tryYaml(text3, options);
7109
+ if (yaml2 !== void 0) return yaml2;
6582
7110
  throw new SpecError("The file looks like JSON but could not be parsed.", [String(err.message)]);
6583
7111
  }
6584
7112
  }
@@ -6586,7 +7114,7 @@ function decode(text2, options) {
6586
7114
  throw new SpecError("YAML specs need a YAML parser; none was provided.");
6587
7115
  }
6588
7116
  try {
6589
- return options.parseYaml(text2);
7117
+ return options.parseYaml(text3);
6590
7118
  } catch (err) {
6591
7119
  throw new SpecError("The file could not be parsed as YAML.", [String(err.message)]);
6592
7120
  }
@@ -6760,10 +7288,10 @@ function dereference(root, warnings, external, missing = []) {
6760
7288
  const fetched = [...absent].filter((ref) => !uploaded.includes(ref));
6761
7289
  if (uploaded.length) {
6762
7290
  warnings.push(
6763
- external ? `Some references point to files that weren't uploaded with the spec: ${list3(uploaded)}` : `References to other files are only followed for a spec loaded from its URL, or uploaded together with those files: ${list3(uploaded)}`
7291
+ external ? `Some references point to files that weren't uploaded with the spec: ${list4(uploaded)}` : `References to other files are only followed for a spec loaded from its URL, or uploaded together with those files: ${list4(uploaded)}`
6764
7292
  );
6765
7293
  }
6766
- if (fetched.length) warnings.push(`Couldn't load the files some references point to: ${list3(fetched)}`);
7294
+ if (fetched.length) warnings.push(`Couldn't load the files some references point to: ${list4(fetched)}`);
6767
7295
  const leftOut = wrongKindWarning(wrong);
6768
7296
  if (leftOut) warnings.push(leftOut);
6769
7297
  missing.push(...absent);
@@ -6847,11 +7375,11 @@ function absolute(ref, base) {
6847
7375
  return void 0;
6848
7376
  }
6849
7377
  }
6850
- function safeDecode(text2) {
7378
+ function safeDecode(text3) {
6851
7379
  try {
6852
- return decodeURIComponent(text2);
7380
+ return decodeURIComponent(text3);
6853
7381
  } catch {
6854
- return text2;
7382
+ return text3;
6855
7383
  }
6856
7384
  }
6857
7385
  function setKey(out, key, value) {
@@ -6862,7 +7390,7 @@ function stripHash(url) {
6862
7390
  const hash = url.indexOf("#");
6863
7391
  return hash < 0 ? url : url.slice(0, hash);
6864
7392
  }
6865
- function list3(items) {
7393
+ function list4(items) {
6866
7394
  return `${items.slice(0, 3).join(", ")}${items.length > 3 ? "\u2026" : ""}`;
6867
7395
  }
6868
7396
  function collectWarnings(doc, warnings) {
@@ -7256,7 +7784,7 @@ function toolOperation(shape, prefix, idFor, context, requiresAuth, style) {
7256
7784
  summary: firstSentence(tool.description) ?? tool.title ?? label,
7257
7785
  label,
7258
7786
  tags: [],
7259
- deprecated: [tool.title, firstSentence(tool.description)].some((text2) => typeof text2 === "string" && /\[deprecated\]|\(deprecated\)|^\W*deprecated\b/i.test(text2)),
7787
+ deprecated: [tool.title, firstSentence(tool.description)].some((text3) => typeof text3 === "string" && /\[deprecated\]|\(deprecated\)|^\W*deprecated\b/i.test(text3)),
7260
7788
  resource: shape.provides ?? shape.noun,
7261
7789
  ...shape.verb ? { action: shape.verb } : {},
7262
7790
  pathParams: [],
@@ -7354,7 +7882,7 @@ function templateOperation(template, requiresAuth, style) {
7354
7882
  }
7355
7883
  function readOperation(id, uri, name, description, mimeType, params, examples, requiresAuth, style) {
7356
7884
  const label = /^read\b/i.test(name) ? name : `Read ${name}`;
7357
- const text2 = /json/i.test(mimeType ?? "") ? "{ \u2026 }" : /markdown/i.test(mimeType ?? "") ? `# ${name}
7885
+ const text3 = /json/i.test(mimeType ?? "") ? "{ \u2026 }" : /markdown/i.test(mimeType ?? "") ? `# ${name}
7358
7886
  \u2026` : "\u2026";
7359
7887
  return {
7360
7888
  id,
@@ -7370,7 +7898,7 @@ function readOperation(id, uri, name, description, mimeType, params, examples, r
7370
7898
  bodyFields: [],
7371
7899
  requiredBodyFields: [],
7372
7900
  request: void 0,
7373
- success: { status: "result", payload: fixed({ contents: [{ uri, ...mimeType ? { mimeType } : {}, text: text2 }], ...resultFields(style, READ_TTL_MS) }, true) },
7901
+ success: { status: "result", payload: fixed({ contents: [{ uri, ...mimeType ? { mimeType } : {}, text: text3 }], ...resultFields(style, READ_TTL_MS) }, true) },
7374
7902
  errors: [],
7375
7903
  callbacks: [],
7376
7904
  requiresAuth,
@@ -7451,20 +7979,20 @@ function objectShape(schema2, depth = 0) {
7451
7979
  if (Array.isArray(schema2.required)) required.push(...schema2.required.filter((r) => typeof r === "string"));
7452
7980
  return { properties, required: [...new Set(required)] };
7453
7981
  }
7454
- function firstSentence(text2) {
7455
- if (!text2) return void 0;
7456
- const plain = text2.replace(/\s+/g, " ").trim();
7982
+ function firstSentence(text3) {
7983
+ if (!text3) return void 0;
7984
+ const plain = text3.replace(/\s+/g, " ").trim();
7457
7985
  if (!plain) return void 0;
7458
7986
  const match = plain.match(/^(.{1,140}?[.!?])(\s|$)/);
7459
7987
  return match ? match[1] : cut(plain, 140);
7460
7988
  }
7461
- function sentenceCase(text2) {
7462
- const words2 = text2.split(" ");
7463
- if (!words2.slice(1).every((w) => /^[A-Z0-9]/.test(w) || /^(a|an|the|and|or|of|to|for|in|on|as|by|with|from)$/.test(w))) return text2;
7989
+ function sentenceCase(text3) {
7990
+ const words2 = text3.split(" ");
7991
+ if (!words2.slice(1).every((w) => /^[A-Z0-9]/.test(w) || /^(a|an|the|and|or|of|to|for|in|on|as|by|with|from)$/.test(w))) return text3;
7464
7992
  return words2.map((w, i) => i > 0 && /^[A-Z][a-z]+$/.test(w) ? w.toLowerCase() : w).join(" ");
7465
7993
  }
7466
- function capitalize(text2) {
7467
- return text2.charAt(0).toUpperCase() + text2.slice(1);
7994
+ function capitalize(text3) {
7995
+ return text3.charAt(0).toUpperCase() + text3.slice(1);
7468
7996
  }
7469
7997
  var INITIALISMS = new Map(
7470
7998
  Object.entries({ id: "ID", ids: "IDs", url: "URL", urls: "URLs", uri: "URI", pr: "PR", prs: "PRs", api: "API", sql: "SQL", json: "JSON", html: "HTML", http: "HTTP", csv: "CSV", pdf: "PDF", ui: "UI", mcp: "MCP" })
@@ -7509,8 +8037,8 @@ function buildModel(doc) {
7509
8037
  var PATH_EXTENSION = /\.(json|xml|csv|ya?ml|html?|txt)$/i;
7510
8038
  function routeSegments(path) {
7511
8039
  return path.replace(/#.*$/, "").split("/").filter(Boolean).flatMap((segment) => {
7512
- const bare = segment.replace(PATH_EXTENSION, "");
7513
- return /^[A-Za-z_][\w-]*(\.[A-Za-z_][\w-]*)+$/.test(bare) ? bare.split(".") : [bare];
8040
+ const bare2 = segment.replace(PATH_EXTENSION, "");
8041
+ return /^[A-Za-z_][\w-]*(\.[A-Za-z_][\w-]*)+$/.test(bare2) ? bare2.split(".") : [bare2];
7514
8042
  });
7515
8043
  }
7516
8044
  var RPC_VERBS = new Set(
@@ -7713,7 +8241,7 @@ function queryPairs(name, value, style, explode) {
7713
8241
  return [[name, scalarText(value)]];
7714
8242
  }
7715
8243
  function pairsText(pairs3) {
7716
- const encode = (text2) => isPlaceholder(text2) ? text2 : encodeURIComponent(wellFormed(text2)).replace(/%(5B|5D|2C|3A|2F|40)/gi, (m) => decodeURIComponent(m));
8244
+ const encode = (text3) => isPlaceholder(text3) ? text3 : encodeURIComponent(wellFormed(text3)).replace(/%(5B|5D|2C|3A|2F|40)/gi, (m) => decodeURIComponent(m));
7717
8245
  return pairs3.map(([k, v]) => `${encode(k)}=${encode(v)}`).join("&") || void 0;
7718
8246
  }
7719
8247
  function scalarText(value) {
@@ -7792,9 +8320,9 @@ function withoutTemplates(value, depth = 0) {
7792
8320
  return Object.fromEntries(Object.entries(value).filter(([, v]) => !(typeof v === "string" && TEMPLATE.test(v))).map(([k, v]) => [k, withoutTemplates(v, depth + 1)]));
7793
8321
  }
7794
8322
  var TEMPLATE = /^VAR_[A-Za-z0-9_]+$/;
7795
- function parseJson2(text2) {
8323
+ function parseJson2(text3) {
7796
8324
  try {
7797
- return JSON.parse(text2);
8325
+ return JSON.parse(text3);
7798
8326
  } catch {
7799
8327
  return void 0;
7800
8328
  }
@@ -7818,8 +8346,8 @@ function lazyPayload(contentType, media, mode, subject) {
7818
8346
  const get = () => {
7819
8347
  if (!memo) {
7820
8348
  const example = exampleForMedia(media, mode, contentType, subject);
7821
- const text2 = typeof example.value === "string" && isTextKind(mediaKind(contentType));
7822
- const value = mode === "request" ? wholeRequest(example.value, text2, media.schema) : wholeResponse(example.value, text2, media.schema);
8349
+ const text3 = typeof example.value === "string" && isTextKind(mediaKind(contentType));
8350
+ const value = mode === "request" ? wholeRequest(example.value, text3, media.schema) : wholeResponse(example.value, text3, media.schema);
7823
8351
  memo = { value, generated: example.generated };
7824
8352
  }
7825
8353
  return memo;
@@ -7864,12 +8392,12 @@ function pickMedia(content) {
7864
8392
  const chosen = json2 ?? entries[0];
7865
8393
  return chosen ? [chosen[0], chosen[1] ?? {}] : [void 0, void 0];
7866
8394
  }
7867
- var GRANTS2 = ["clientCredentials", "authorizationCode", "deviceAuthorization", "password", "implicit"];
8395
+ var GRANTS3 = ["clientCredentials", "authorizationCode", "deviceAuthorization", "password", "implicit"];
7868
8396
  function schemesOf(doc) {
7869
8397
  return isObject2(doc.components?.securitySchemes) ? doc.components.securitySchemes : {};
7870
8398
  }
7871
8399
  var requirementNames = (r) => isObject2(r) ? Object.keys(r) : [];
7872
- function usable(schemes, r) {
8400
+ function usable2(schemes, r) {
7873
8401
  return requirementNames(r).length > 0 && requirementNames(r).every((n) => isObject2(schemes[n]) && schemeInfo(n, schemes[n], []) !== void 0);
7874
8402
  }
7875
8403
  function current(schemes, r) {
@@ -7887,7 +8415,7 @@ function requirementsOf(doc, security) {
7887
8415
  const memo = requirementsMemo.get(security);
7888
8416
  if (memo) return memo;
7889
8417
  const schemes = schemesOf(doc);
7890
- const shown = security.filter((r) => usable(schemes, r));
8418
+ const shown = security.filter((r) => usable2(schemes, r));
7891
8419
  const ordered = [...shown.filter((r) => current(schemes, r)), ...shown.filter((r) => !current(schemes, r))];
7892
8420
  const infos = ordered.flatMap((r) => requirementInfo(schemes, requirementNames(r), (name) => Array.isArray(r[name]) ? r[name].filter((s) => typeof s === "string") : []) ?? []);
7893
8421
  requirementsMemo.set(security, infos);
@@ -7902,7 +8430,7 @@ function authOf2(doc) {
7902
8430
  for (const item of Object.values(doc.paths ?? {})) {
7903
8431
  for (const [, op] of operationsOf(item)) if (Array.isArray(op.security)) requirements.push(...op.security);
7904
8432
  }
7905
- const chosen = requirements.find((r) => usable(schemes, r) && current(schemes, r)) ?? requirements.find((r) => usable(schemes, r));
8433
+ const chosen = requirements.find((r) => usable2(schemes, r) && current(schemes, r)) ?? requirements.find((r) => usable2(schemes, r));
7906
8434
  const fallback = Object.keys(schemes).find((n) => isObject2(schemes[n]) && !schemes[n].deprecated && schemeInfo(n, schemes[n], []));
7907
8435
  const picked = chosen ? requirementNames(chosen) : fallback ? [fallback] : [];
7908
8436
  const scopesFor = (name) => [...new Set(requirements.flatMap((r) => isObject2(r) && Array.isArray(r[name]) ? r[name] : []))];
@@ -7912,7 +8440,7 @@ function schemeInfo(name, scheme, scopes) {
7912
8440
  if (!isObject2(scheme)) return void 0;
7913
8441
  switch (scheme.type) {
7914
8442
  case "oauth2": {
7915
- const flowName = GRANTS2.find((f) => isObject2(scheme.flows?.[f]));
8443
+ const flowName = GRANTS3.find((f) => isObject2(scheme.flows?.[f]));
7916
8444
  const flow = flowName ? scheme.flows?.[flowName] : void 0;
7917
8445
  return {
7918
8446
  schemeName: name,
@@ -7955,17 +8483,17 @@ function serverUrl(server) {
7955
8483
  return value === void 0 || value === null || value === "" ? "example" : String(value);
7956
8484
  }).replace(/\/$/, "");
7957
8485
  }
7958
- function said(text2) {
7959
- return typeof text2 === "string" && text2.trim() ? text2 : void 0;
8486
+ function said(text3) {
8487
+ return typeof text3 === "string" && text3.trim() ? text3 : void 0;
7960
8488
  }
7961
- function firstSentence2(text2) {
7962
- if (!text2) return void 0;
7963
- const plain = text2.replace(/<[^>]+>/g, "").replace(/\s+/g, " ").trim();
8489
+ function firstSentence2(text3) {
8490
+ if (!text3) return void 0;
8491
+ const plain = text3.replace(/<[^>]+>/g, "").replace(/\s+/g, " ").trim();
7964
8492
  const match = plain.match(/^(.{1,90}?[.!?])(\s|$)/);
7965
8493
  return match ? match[1] : cut(plain, 90);
7966
8494
  }
7967
8495
  function saysDeprecated(op) {
7968
- return [op.summary, firstSentence2(op.description)].some((text2) => typeof text2 === "string" && /\[deprecated\]|\(deprecated\)|^\W*deprecated\b/i.test(text2));
8496
+ return [op.summary, firstSentence2(op.description)].some((text3) => typeof text3 === "string" && /\[deprecated\]|\(deprecated\)|^\W*deprecated\b/i.test(text3));
7969
8497
  }
7970
8498
  var PRE_RELEASE = /\b(beta|preview|alpha|experimental)\b/i;
7971
8499
  var STAGE_FIELDS = ["x-release-status", "x-stability", "x-stability-level", "x-maturity", "x-status", "x-lifecycle"];
@@ -7976,13 +8504,13 @@ function inPreview(doc, op, item) {
7976
8504
  if (fields["x-beta"] === true || fields["x-preview"] === true || fields["x-experimental"] === true || isObject2(meta) && meta.beta === true) return true;
7977
8505
  for (const field of STAGE_FIELDS) {
7978
8506
  const stage = fields[field] ?? item[field];
7979
- const text2 = Array.isArray(stage) ? stage.join(" ") : stage;
7980
- if (typeof text2 === "string" && PRE_RELEASE.test(text2)) return true;
8507
+ const text3 = Array.isArray(stage) ? stage.join(" ") : stage;
8508
+ if (typeof text3 === "string" && PRE_RELEASE.test(text3)) return true;
7981
8509
  }
7982
8510
  if (typeof op.summary === "string" && /[[(](beta|preview|alpha|experimental)[\])]/i.test(op.summary)) return true;
7983
8511
  let tags = previewTagsOf.get(doc);
7984
8512
  if (!tags) {
7985
- const named = (list6) => Array.isArray(list6) ? list6 : [];
8513
+ const named = (list7) => Array.isArray(list7) ? list7 : [];
7986
8514
  tags = new Set(named(doc.tags).flatMap((tag2) => isObject2(tag2) && typeof tag2.name === "string" && PRE_RELEASE.test(tag2.name) ? [tag2.name] : []));
7987
8515
  for (const group of named(doc["x-tagGroups"])) {
7988
8516
  if (isObject2(group) && typeof group.name === "string" && PRE_RELEASE.test(group.name)) for (const tag2 of named(group.tags)) tags.add(String(tag2));
@@ -8001,14 +8529,14 @@ var LABEL_MAX = 60;
8001
8529
  function specLabel(op) {
8002
8530
  const texts = [op.summary, firstSentence2(op.description)];
8003
8531
  if (!op.summary && !op.description && op.operationId && !/^(post|put|patch|head|options)/i.test(op.operationId)) texts.push(op.operationId);
8004
- for (const text2 of texts) {
8005
- const label = typeof text2 === "string" ? asLabel(text2) : void 0;
8532
+ for (const text3 of texts) {
8533
+ const label = typeof text3 === "string" ? asLabel(text3) : void 0;
8006
8534
  if (label) return label;
8007
8535
  }
8008
8536
  return void 0;
8009
8537
  }
8010
- function asLabel(text2) {
8011
- let plain = text2.replace(/<[^>]+>/g, " ").replace(/\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\*\*|__|`/g, "").split("\n")[0].replace(/\s+/g, " ").trim();
8538
+ function asLabel(text3) {
8539
+ let plain = text3.replace(/<[^>]+>/g, " ").replace(/\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\*\*|__|`/g, "").split("\n")[0].replace(/\s+/g, " ").trim();
8012
8540
  plain = (plain.match(/^(.+?[.!?])(\s|$)/)?.[1] ?? plain).replace(/\s*[[(](deprecated|beta|preview|legacy|experimental|new)[\])]\s*/gi, " ").replace(/[\s.:;,!?]+$/, "").trim();
8013
8541
  if (!/\s/.test(plain)) plain = plain.replace(/[_./-]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z])([A-Z][a-z])/g, "$1 $2").toLowerCase();
8014
8542
  const words2 = plain.split(" ").filter(Boolean);
@@ -8054,8 +8582,8 @@ var MAX_STRING = 80;
8054
8582
  var MAX_CHARS = 6e3;
8055
8583
  var MAX_TEXT_LINES = 60;
8056
8584
  var MAX_WHOLE_CHARS = 64e3;
8057
- function wholeRequest(value, text2, schema2) {
8058
- if (text2) return value.length > MAX_WHOLE_CHARS ? trimText(value) : value;
8585
+ function wholeRequest(value, text3, schema2) {
8586
+ if (text3) return value.length > MAX_WHOLE_CHARS ? trimText(value) : value;
8059
8587
  let size2 = Infinity;
8060
8588
  try {
8061
8589
  size2 = JSON.stringify(value)?.length ?? 0;
@@ -8063,8 +8591,8 @@ function wholeRequest(value, text2, schema2) {
8063
8591
  }
8064
8592
  return size2 > MAX_WHOLE_CHARS ? trimForDisplay(value, 0, void 0, schema2) : value;
8065
8593
  }
8066
- function wholeResponse(value, text2, schema2) {
8067
- const kept = wholeRequest(value, text2, schema2);
8594
+ function wholeResponse(value, text3, schema2) {
8595
+ const kept = wholeRequest(value, text3, schema2);
8068
8596
  return kept === value ? idsFirst(value) : kept;
8069
8597
  }
8070
8598
  function idsFirst(value, depth = 0) {
@@ -8077,9 +8605,9 @@ function idsFirst(value, depth = 0) {
8077
8605
  function trimForDisplay(value, depth = 0, budget = { left: MAX_CHARS }, schema2) {
8078
8606
  if (typeof value === "string") {
8079
8607
  const formed = schema2 && (schema2.enum || schema2.const !== void 0 || schema2.format || schema2.pattern);
8080
- const text2 = formed ? value : clip(value, MAX_STRING);
8081
- budget.left -= text2.length + 3;
8082
- return text2;
8608
+ const text3 = formed ? value : clip(value, MAX_STRING);
8609
+ budget.left -= text3.length + 3;
8610
+ return text3;
8083
8611
  }
8084
8612
  if (Array.isArray(value)) {
8085
8613
  if (depth >= 4) return [];
@@ -8124,8 +8652,8 @@ function alternativeOf(value, schema2) {
8124
8652
  }
8125
8653
  return best ? { allOf: [{ ...schema2, oneOf: void 0, anyOf: void 0 }, best.variant] } : schema2;
8126
8654
  }
8127
- function trimText(text2) {
8128
- let lines = text2.split("\n");
8655
+ function trimText(text3) {
8656
+ let lines = text3.split("\n");
8129
8657
  if (lines.length > MAX_TEXT_LINES) lines = [...lines.slice(0, MAX_TEXT_LINES), "\u2026"];
8130
8658
  const out = lines.join("\n");
8131
8659
  return clip(out, MAX_CHARS);
@@ -8446,15 +8974,15 @@ function hooksOf(ops, webhooks) {
8446
8974
  const writes = /* @__PURE__ */ new Map();
8447
8975
  for (const op of ops) {
8448
8976
  if (isRead(op)) continue;
8449
- const list6 = writes.get(op.resource);
8450
- if (list6) list6.push(op);
8977
+ const list7 = writes.get(op.resource);
8978
+ if (list7) list7.push(op);
8451
8979
  else writes.set(op.resource, [op]);
8452
8980
  }
8453
8981
  return { named: webhooks.filter((w) => !w.sourceOperationId).map((hook) => ({ hook, name: words(hook.name).map(singular) })), writes };
8454
8982
  }
8455
8983
  var FOLLOWS_CREATE = /^(created|opened|added|new|submitted|sent|posted|placed|filed|registered|started|initiated|scheduled|queued|received|delivered|succeeded|completed|ready|processed|paid|published|accepted|confirmed)$/;
8456
- function words(text2) {
8457
- return text2.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
8984
+ function words(text3) {
8985
+ return text3.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
8458
8986
  }
8459
8987
  function findNoun(name, noun) {
8460
8988
  for (let i = 0; i + noun.length <= name.length; i++) {
@@ -8468,8 +8996,8 @@ function verbStem(op) {
8468
8996
  if (!["post", "put", "patch"].includes(op.method)) return normName(op.method).replace(/e$/, "");
8469
8997
  return op.method === "post" && !isItemPath(op.path) ? "creat" : "updat";
8470
8998
  }
8471
- function normName(text2) {
8472
- return text2.toLowerCase().replace(/-/g, "_");
8999
+ function normName(text3) {
9000
+ return text3.toLowerCase().replace(/-/g, "_");
8473
9001
  }
8474
9002
  function isItemPath(path) {
8475
9003
  return Boolean(routeSegments(path.trim()).at(-1)?.startsWith("{"));
@@ -8516,11 +9044,11 @@ function describe(steps, webhook) {
8516
9044
  const parts = steps.map((s) => `${methodName(s.method)} ${s.path}`);
8517
9045
  return webhook ? `${parts.join(", then ")}; the API then sends the ${webhook.name} webhook.` : `${parts.join(", then ")}.`;
8518
9046
  }
8519
- function humanize(text2) {
8520
- return text2.replace(/[_-]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase();
9047
+ function humanize(text3) {
9048
+ return text3.replace(/[_-]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase();
8521
9049
  }
8522
- function capitalize2(text2) {
8523
- return text2.charAt(0).toUpperCase() + text2.slice(1);
9050
+ function capitalize2(text3) {
9051
+ return text3.charAt(0).toUpperCase() + text3.slice(1);
8524
9052
  }
8525
9053
 
8526
9054
  // ../../lib/storyboard/links.ts
@@ -8562,8 +9090,8 @@ function fillPath(template, links, values) {
8562
9090
  return clip(path, MAX_PATH);
8563
9091
  }
8564
9092
  function pathValue(name, value, style) {
8565
- const text2 = wellFormed(String(value));
8566
- const encoded = isPlaceholder(text2) ? text2 : style === "reserved" || /^[+#]/.test(name) ? encodeURI(text2) : encodeURIComponent(text2).replace(/%(3A|40)/gi, (m) => decodeURIComponent(m));
9093
+ const text3 = wellFormed(String(value));
9094
+ const encoded = isPlaceholder(text3) ? text3 : style === "reserved" || /^[+#]/.test(name) ? encodeURI(text3) : encodeURIComponent(text3).replace(/%(3A|40)/gi, (m) => decodeURIComponent(m));
8567
9095
  return style === "label" ? `.${encoded}` : style === "matrix" ? `;${name}=${encoded}` : encoded;
8568
9096
  }
8569
9097
  var TAKEN = ["number", "login", "username", "handle", "slug", "name", "email", "sha"];
@@ -8613,17 +9141,17 @@ function toolIds(result, noun) {
8613
9141
  look(result.structuredContent, 0);
8614
9142
  for (const block of Array.isArray(result.content) ? result.content : []) {
8615
9143
  if (found.id !== void 0 || !isObject2(block) || typeof block.text !== "string") continue;
8616
- const text2 = block.text;
8617
- if (/^\s*[[{]/.test(text2)) {
9144
+ const text3 = block.text;
9145
+ if (/^\s*[[{]/.test(text3)) {
8618
9146
  try {
8619
- look(JSON.parse(text2), 0);
9147
+ look(JSON.parse(text3), 0);
8620
9148
  continue;
8621
9149
  } catch {
8622
9150
  }
8623
9151
  }
8624
- const number = text2.match(/#(\d+)\b/)?.[1];
9152
+ const number = text3.match(/#(\d+)\b/)?.[1];
8625
9153
  if (found.number === void 0 && number) found.number = Number(number);
8626
- const id = text2.match(/<[A-Za-z0-9_.-]*_id(?:_\d+)?>/)?.[0] ?? text2.match(/\b([a-z]{2,8}_(?=[A-Za-z0-9]*\d)[A-Za-z0-9]{6,})\b/)?.[1] ?? text2.match(/\b[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}\b/i)?.[0];
9154
+ const id = text3.match(/<[A-Za-z0-9_.-]*_id(?:_\d+)?>/)?.[0] ?? text3.match(/\b([a-z]{2,8}_(?=[A-Za-z0-9]*\d)[A-Za-z0-9]{6,})\b/)?.[1] ?? text3.match(/\b[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}\b/i)?.[0];
8627
9155
  if (id) found.id = id;
8628
9156
  }
8629
9157
  return found.id !== void 0 || found.number !== void 0 ? found : void 0;
@@ -8912,8 +9440,8 @@ function signInScene(id, auth, endpoint) {
8912
9440
  summaryLine: "Sign in with OAuth, then send the token on every request"
8913
9441
  };
8914
9442
  }
8915
- function lowerFirst(text2) {
8916
- return /^[A-Z][a-z]/.test(text2) ? text2.charAt(0).toLowerCase() + text2.slice(1) : text2;
9443
+ function lowerFirst(text3) {
9444
+ return /^[A-Z][a-z]/.test(text3) ? text3.charAt(0).toLowerCase() + text3.slice(1) : text3;
8917
9445
  }
8918
9446
  function theServer(title) {
8919
9447
  if (!saysMcp(title)) return `the ${title} MCP server`;
@@ -9226,8 +9754,8 @@ function formatOf2(schema2) {
9226
9754
  return variants.map(formatOf2).find((f) => f !== void 0);
9227
9755
  }
9228
9756
  var TIMESTAMP = /^(\d{4}-\d{2}-\d{2})[Tt ](\d{2}:\d{2}:\d{2}(?:\.\d+)?)(?:([Zz])|([+-])(\d{2}):?(\d{2})?)$/;
9229
- function asDateTime(text2) {
9230
- const m = text2.match(TIMESTAMP);
9757
+ function asDateTime(text3) {
9758
+ const m = text3.match(TIMESTAMP);
9231
9759
  if (!m) return void 0;
9232
9760
  const [, date, time, zulu, sign, hours, minutes] = m;
9233
9761
  return `${date}T${time}${zulu ? "Z" : `${sign}${hours}:${minutes ?? "00"}`}`;
@@ -9275,8 +9803,8 @@ function declaredProperty(schema2, field) {
9275
9803
  function nextDigits(id) {
9276
9804
  return `${id.slice(0, -1)}${(Number(id.slice(-1)) + 1) % 10}`;
9277
9805
  }
9278
- function eventWords(text2) {
9279
- return text2.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter(Boolean).map(singular);
9806
+ function eventWords(text3) {
9807
+ return text3.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter(Boolean).map(singular);
9280
9808
  }
9281
9809
  function mentions(event, resource) {
9282
9810
  const words2 = eventWords(event);
@@ -9654,7 +10182,7 @@ function namesOther(value, field, fields, depth = 0) {
9654
10182
  if (depth > 3) return false;
9655
10183
  if (Array.isArray(value)) return value.some((item) => namesOther(item, field, fields, depth + 1));
9656
10184
  if (!isObject2(value)) return false;
9657
- const word = (name, text2) => new RegExp(`(^|[^\\w])${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}([^\\w]|$)`, "i").test(text2);
10185
+ const word = (name, text3) => new RegExp(`(^|[^\\w])${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}([^\\w]|$)`, "i").test(text3);
9658
10186
  return Object.entries(value).some(([key, item]) => {
9659
10187
  if (typeof item === "string" && FIELD_KEYS.test(key)) return item !== field;
9660
10188
  if (typeof item === "string" && key === "pointer" && item.includes("/")) return item.split("/").pop() !== field;
@@ -9941,8 +10469,8 @@ function statusCode(status) {
9941
10469
  if (range) return `${range[1]}00`;
9942
10470
  return status.replace(/\W/g, "").slice(0, 8) || "200";
9943
10471
  }
9944
- function lowerFirst2(text2) {
9945
- return text2.charAt(0).toLowerCase() + text2.slice(1);
10472
+ function lowerFirst2(text3) {
10473
+ return text3.charAt(0).toLowerCase() + text3.slice(1);
9946
10474
  }
9947
10475
  function authLabel(auth) {
9948
10476
  const also = auth.also?.length ? ` and ${auth.also.map(shortAuthLabel).join(" and ")}` : "";
@@ -10318,23 +10846,23 @@ function rebuild(file, model, documented = [], options = {}) {
10318
10846
  }
10319
10847
  function reportLines(report) {
10320
10848
  const lines = [];
10321
- for (const r of report.removed) lines.push(`${capital(r.scene)} isn't in the spec any more${r.edits.length ? `, so its ${list4(r.edits)} edits are lost` : ""}.`);
10849
+ for (const r of report.removed) lines.push(`${capital(r.scene)} isn't in the spec any more${r.edits.length ? `, so its ${list5(r.edits)} edits are lost` : ""}.`);
10322
10850
  for (const a of report.added) lines.push(`${capital(a)} is new, so it was added where the builder puts it.`);
10323
10851
  for (const l of report.lost) lines.push(`An edit to ${l} had nowhere to go, so it was left out.`);
10324
10852
  if (report.failure) lines.push(`The ${report.failure.wanted} failure isn't documented any more, so the video shows ${report.failure.shown ?? "no failure"} instead.`);
10325
10853
  for (const c of report.changed) lines.push(`The spec also changed ${c}; your edit is kept.`);
10326
10854
  return lines;
10327
10855
  }
10328
- function capital(text2) {
10329
- return text2.charAt(0).toUpperCase() + text2.slice(1);
10856
+ function capital(text3) {
10857
+ return text3.charAt(0).toUpperCase() + text3.slice(1);
10330
10858
  }
10331
- function list4(items) {
10859
+ function list5(items) {
10332
10860
  return items.length < 2 ? items.join("") : `${items.slice(0, -1).join(", ")} and ${items[items.length - 1]}`;
10333
10861
  }
10334
- function parseFlowFile(text2, parseYaml2) {
10862
+ function parseFlowFile(text3, parseYaml2) {
10335
10863
  let raw;
10336
10864
  try {
10337
- raw = parseYaml2(text2);
10865
+ raw = parseYaml2(text3);
10338
10866
  } catch (err) {
10339
10867
  throw new FlowFileError("The flow file isn't valid YAML.", [err.message]);
10340
10868
  }
@@ -10358,7 +10886,7 @@ function readFile(raw, problems) {
10358
10886
  return void 0;
10359
10887
  }
10360
10888
  unknownKeys(raw, ["version", "spec", "flow", "look", "brand", "names", "scenes", "deleted"], "The file", problems);
10361
- const flow = raw.flow === void 0 ? void 0 : text(raw.flow, 300, "`flow`", problems);
10889
+ const flow = raw.flow === void 0 ? void 0 : text2(raw.flow, 300, "`flow`", problems);
10362
10890
  if (flow !== void 0 && !flow.startsWith("arazzo:")) problems.push("`flow` names an Arazzo workflow, as arazzo:<workflowId>.");
10363
10891
  const look = {};
10364
10892
  const lookRaw = mapping(raw.look, "`look`", problems);
@@ -10382,7 +10910,7 @@ function readFile(raw, problems) {
10382
10910
  if (typeof color === "string" && /^#[0-9a-f]{6}$/i.test(color)) brand.color = color.toLowerCase();
10383
10911
  else if (color !== void 0) problems.push('`brand.color` is a color like "#4f46e5".');
10384
10912
  if (brandRaw.logo !== void 0) {
10385
- const logo = text(brandRaw.logo, 300, "`brand.logo`", problems);
10913
+ const logo = text2(brandRaw.logo, 300, "`brand.logo`", problems);
10386
10914
  if (logo !== void 0 && (/^([a-z]+:|\/)/i.test(logo) || logo.split(/[\\/]/).includes(".."))) problems.push("`brand.logo` is a file next to the flow file, or in a folder below it.");
10387
10915
  else if (logo !== void 0) brand.logo = logo;
10388
10916
  }
@@ -10393,7 +10921,7 @@ function readFile(raw, problems) {
10393
10921
  unknownKeys(namesRaw, ["client", "api", "webhook"], "`names`", problems);
10394
10922
  for (const key of ["client", "api", "webhook"]) {
10395
10923
  if (namesRaw[key] === void 0) continue;
10396
- const name = text(namesRaw[key], LIMITS.name, `\`names.${key}\``, problems, true);
10924
+ const name = text2(namesRaw[key], LIMITS.name, `\`names.${key}\``, problems, true);
10397
10925
  if (name !== void 0) names[key] = name;
10398
10926
  }
10399
10927
  }
@@ -10424,7 +10952,7 @@ var SCENE_FIELDS = {
10424
10952
  webhook: ["caption", "speech", "payload"],
10425
10953
  summary: ["caption", "speech"]
10426
10954
  };
10427
- function readScene(item, where, problems, bare = false) {
10955
+ function readScene(item, where, problems, bare2 = false) {
10428
10956
  if (typeof item === "string") {
10429
10957
  if (item === "title" || item === "auth" || item === "summary") return [{ kind: item }];
10430
10958
  problems.push(`${where} is "${item.slice(0, 40)}": a scene is title, auth or summary, or a mapping such as \`call: POST /v1/customers\`.`);
@@ -10440,24 +10968,24 @@ function readScene(item, where, problems, bare = false) {
10440
10968
  return [];
10441
10969
  }
10442
10970
  const kind = kinds[0];
10443
- const allowed = bare ? kind === "call" ? ["operation"] : [] : SCENE_FIELDS[kind];
10971
+ const allowed = bare2 ? kind === "call" ? ["operation"] : [] : SCENE_FIELDS[kind];
10444
10972
  unknownKeys(item, [kind, ...allowed], where, problems);
10445
- const edits = bare ? {} : readEdits(item, kind, where, problems);
10973
+ const edits = bare2 ? {} : readEdits(item, kind, where, problems);
10446
10974
  switch (kind) {
10447
10975
  case "call": {
10448
- const call = text(item.call, 1100, `${where}'s \`call\``, problems, true);
10976
+ const call = text2(item.call, 1100, `${where}'s \`call\``, problems, true);
10449
10977
  if (call !== void 0 && !/^[A-Za-z]+ \/\S*$/.test(call) && !MCP_CALL.test(call)) problems.push(`${where}'s \`call\` is a method and a path, like "POST /v1/customers", or an MCP call, like "tools/call search_flights".`);
10450
- const operation = item.operation === void 0 ? void 0 : text(item.operation, 300, `${where}'s \`operation\``, problems, true);
10451
- const failure = item.failure === void 0 || bare ? void 0 : readFailure(item.failure, `${where}'s failure`, problems);
10978
+ const operation = item.operation === void 0 ? void 0 : text2(item.operation, 300, `${where}'s \`operation\``, problems, true);
10979
+ const failure = item.failure === void 0 || bare2 ? void 0 : readFailure(item.failure, `${where}'s failure`, problems);
10452
10980
  return call === void 0 ? [] : [{ kind, call, ...operation !== void 0 ? { operation } : {}, ...edits, ...failure ? { failure } : {} }];
10453
10981
  }
10454
10982
  case "webhook": {
10455
- const event = text(item.webhook, 300, `${where}'s \`webhook\``, problems, true);
10983
+ const event = text2(item.webhook, 300, `${where}'s \`webhook\``, problems, true);
10456
10984
  return event === void 0 ? [] : [{ kind, event, ...edits }];
10457
10985
  }
10458
10986
  case "title": {
10459
- const title = item.title === null || item.title === void 0 ? void 0 : text(item.title, LIMITS.title, `${where}'s title`, problems);
10460
- const subtitle = item.subtitle === void 0 ? void 0 : text(item.subtitle, LIMITS.subtitle, `${where}'s subtitle`, problems);
10987
+ const title = item.title === null || item.title === void 0 ? void 0 : text2(item.title, LIMITS.title, `${where}'s title`, problems);
10988
+ const subtitle = item.subtitle === void 0 ? void 0 : text2(item.subtitle, LIMITS.subtitle, `${where}'s subtitle`, problems);
10461
10989
  return [{ kind, ...title !== void 0 ? { title } : {}, ...subtitle !== void 0 ? { subtitle } : {}, ...edits }];
10462
10990
  }
10463
10991
  default:
@@ -10475,17 +11003,17 @@ function readFailure(raw, where, problems) {
10475
11003
  unknownKeys(raw, ["status", "caption", "speech", "request", "response", "recovery"], where, problems);
10476
11004
  const s = status(raw.status);
10477
11005
  if (s === void 0) problems.push(`${where} needs a \`status\`, like 429.`);
10478
- const recovery = raw.recovery === void 0 ? void 0 : text(raw.recovery, LIMITS.recovery, `${where}'s recovery note`, problems);
11006
+ const recovery = raw.recovery === void 0 ? void 0 : text2(raw.recovery, LIMITS.recovery, `${where}'s recovery note`, problems);
10479
11007
  return s === void 0 ? void 0 : { status: s, ...readEdits(raw, "call", where, problems), ...recovery !== void 0 ? { recovery } : {} };
10480
11008
  }
10481
11009
  function readEdits(raw, kind, where, problems) {
10482
11010
  const edits = {};
10483
11011
  if (raw.caption !== void 0) {
10484
- const caption = text(raw.caption, LIMITS.caption, `${where}'s caption`, problems);
11012
+ const caption = text2(raw.caption, LIMITS.caption, `${where}'s caption`, problems);
10485
11013
  if (caption !== void 0) edits.caption = caption;
10486
11014
  }
10487
11015
  if (raw.speech !== void 0) {
10488
- const speech = text(raw.speech, LIMITS.speech, `${where}'s spoken words`, problems);
11016
+ const speech = text2(raw.speech, LIMITS.speech, `${where}'s spoken words`, problems);
10489
11017
  if (speech !== void 0) edits.speech = speech;
10490
11018
  }
10491
11019
  for (const field of ["request", "response", "payload"]) {
@@ -10506,7 +11034,7 @@ function mapping(raw, where, problems) {
10506
11034
  problems.push(`${where} is a mapping.`);
10507
11035
  return void 0;
10508
11036
  }
10509
- function text(raw, max, where, problems, required = false) {
11037
+ function text2(raw, max, where, problems, required = false) {
10510
11038
  if (typeof raw === "number" || typeof raw === "boolean") raw = String(raw);
10511
11039
  if (typeof raw !== "string" || required && !raw.trim()) {
10512
11040
  problems.push(`${where} should be some text.`);
@@ -10523,7 +11051,7 @@ function unknownKeys(raw, known, where, problems) {
10523
11051
  }
10524
11052
 
10525
11053
  // package.json
10526
- var version = "1.0.6";
11054
+ var version = "1.0.8";
10527
11055
 
10528
11056
  // src/files.ts
10529
11057
  var import_node_fs = require("node:fs");
@@ -13599,9 +14127,9 @@ var {
13599
14127
  // ../../components/yaml.ts
13600
14128
  var SCHEMA = CORE_SCHEMA.extend({ implicit: [types.merge] });
13601
14129
  var ANCHOR = /(^|[\s:[{,-])&[^\s,[\]{}]+(\s|$)/m;
13602
- function parseYaml(text2) {
13603
- const value = load(text2, { schema: SCHEMA, json: true });
13604
- if (ANCHOR.test(text2)) checkExpansion(value, Math.max(1e6, text2.length * 4));
14130
+ function parseYaml(text3) {
14131
+ const value = load(text3, { schema: SCHEMA, json: true });
14132
+ if (ANCHOR.test(text3)) checkExpansion(value, Math.max(1e6, text3.length * 4));
13605
14133
  return value;
13606
14134
  }
13607
14135
  function checkExpansion(root, budget) {
@@ -13805,9 +14333,9 @@ function signIn(url, challenge) {
13805
14333
  async function readAnswer(res, id) {
13806
14334
  const type2 = res.headers.get("content-type") ?? "";
13807
14335
  if (/text\/event-stream/i.test(type2)) return readEvents(res, id);
13808
- const text2 = await readCapped(res);
14336
+ const text3 = await readCapped(res);
13809
14337
  try {
13810
- const parsed = JSON.parse(text2);
14338
+ const parsed = JSON.parse(text3);
13811
14339
  const messages = Array.isArray(parsed) ? parsed : [parsed];
13812
14340
  return messages.find((m) => isObject3(m) && (m.id === id || m.id === null && "error" in m) && ("result" in m || "error" in m));
13813
14341
  } catch {
@@ -13846,9 +14374,9 @@ async function readEvents(res, id) {
13846
14374
  }
13847
14375
  }
13848
14376
  async function readCapped(res) {
13849
- const text2 = await res.text();
13850
- if (text2.length > MAX_SPEC_BYTES) throw new SpecError("The MCP server sent more than the app reads.");
13851
- return text2;
14377
+ const text3 = await res.text();
14378
+ if (text3.length > MAX_SPEC_BYTES) throw new SpecError("The MCP server sent more than the app reads.");
14379
+ return text3;
13852
14380
  }
13853
14381
  function isObject3(value) {
13854
14382
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -13860,12 +14388,12 @@ var SPEC_PATH = /\.(json|ya?ml)$/i;
13860
14388
  var MCP_PATH = /\/(mcp|sse)\/?$/i;
13861
14389
  var MCP_HINT = "If it's an MCP server, open it in MCP Inspector (npx @modelcontextprotocol/inspector), list its tools, and paste the result here.";
13862
14390
  function specUrl(input, base) {
13863
- const text2 = input.trim();
13864
- if (!text2) throw new SpecError("Enter the URL of an OpenAPI spec.");
13865
- const invalid = new SpecError(`That isn't a valid URL: ${text2.length > 80 ? `${text2.slice(0, 79)}\u2026` : text2}`);
14391
+ const text3 = input.trim();
14392
+ if (!text3) throw new SpecError("Enter the URL of an OpenAPI spec.");
14393
+ const invalid = new SpecError(`That isn't a valid URL: ${text3.length > 80 ? `${text3.slice(0, 79)}\u2026` : text3}`);
13866
14394
  let url;
13867
14395
  try {
13868
- url = new URL(/^[a-z][a-z\d+.-]*:\/\//i.test(text2) || text2.startsWith("/") ? text2 : `https://${text2}`, base);
14396
+ url = new URL(/^[a-z][a-z\d+.-]*:\/\//i.test(text3) || text3.startsWith("/") ? text3 : `https://${text3}`, base);
13869
14397
  } catch {
13870
14398
  throw invalid;
13871
14399
  }
@@ -13940,11 +14468,11 @@ async function fetchSpecText(url, options = {}) {
13940
14468
  throw notFile(new SpecError("That URL streams events rather than sending a file."), "stream");
13941
14469
  }
13942
14470
  if (Number(res.headers.get("content-length")) > maxBytes) throw tooLarge(maxBytes);
13943
- const text2 = await readCapped2(res, maxBytes, progress);
13944
- if (/^\s*</.test(text2)) {
14471
+ const text3 = await readCapped2(res, maxBytes, progress);
14472
+ if (/^\s*</.test(text3)) {
13945
14473
  throw notFile(new SpecError("That URL returned a web page, not a JSON or YAML file.", ["If it's a docs page, link to the raw spec file instead."]), "answer");
13946
14474
  }
13947
- return text2;
14475
+ return text3;
13948
14476
  } catch (err) {
13949
14477
  if (err instanceof SpecError) throw err;
13950
14478
  if (controller.signal.aborted) {
@@ -13984,17 +14512,17 @@ async function readCapped2(res, maxBytes, progress) {
13984
14512
  const reader2 = res.body.getReader();
13985
14513
  const decoder = new TextDecoder();
13986
14514
  let size2 = 0;
13987
- let text2 = "";
14515
+ let text3 = "";
13988
14516
  for (; ; ) {
13989
14517
  const { done, value } = await reader2.read();
13990
- if (done) return text2 + decoder.decode();
14518
+ if (done) return text3 + decoder.decode();
13991
14519
  progress();
13992
14520
  size2 += value.byteLength;
13993
14521
  if (size2 > maxBytes) {
13994
14522
  await reader2.cancel().catch(() => void 0);
13995
14523
  throw tooLarge(maxBytes);
13996
14524
  }
13997
- text2 += decoder.decode(value, { stream: true });
14525
+ text3 += decoder.decode(value, { stream: true });
13998
14526
  }
13999
14527
  }
14000
14528
  function isLoopback(hostname) {
@@ -14017,8 +14545,8 @@ function arazzoTitle(doc) {
14017
14545
  }
14018
14546
  function arazzoWorkflows(doc, model, source) {
14019
14547
  const notes = /* @__PURE__ */ new Set();
14020
- const list6 = (Array.isArray(doc.workflows) ? doc.workflows : []).filter((w) => isObject2(w) && typeof w.workflowId === "string");
14021
- const byId = new Map(list6.map((w) => [w.workflowId, w]));
14548
+ const list7 = (Array.isArray(doc.workflows) ? doc.workflows : []).filter((w) => isObject2(w) && typeof w.workflowId === "string");
14549
+ const byId = new Map(list7.map((w) => [w.workflowId, w]));
14022
14550
  const byOperationId = new Map(model.operations.map((op) => [op.id, op]));
14023
14551
  const prefix = `$sourceDescriptions.${source}.`;
14024
14552
  const operationFor = (step) => {
@@ -14074,8 +14602,8 @@ function arazzoWorkflows(doc, model, source) {
14074
14602
  if (where === "path" && !isExpression(value) && (typeof value === "string" || typeof value === "number")) pathParams[p.name] = value;
14075
14603
  else if (where === "query") {
14076
14604
  const shown = isExpression(value) ? standIn(p.name) : value;
14077
- const text2 = wellFormed(Array.isArray(shown) ? shown.join(",") : String(shown));
14078
- query.push(`${encodeURIComponent(wellFormed(p.name))}=${isPlaceholder(text2) ? text2 : encodeURIComponent(text2)}`);
14605
+ const text3 = wellFormed(Array.isArray(shown) ? shown.join(",") : String(shown));
14606
+ query.push(`${encodeURIComponent(wellFormed(p.name))}=${isPlaceholder(text3) ? text3 : encodeURIComponent(text3)}`);
14079
14607
  }
14080
14608
  }
14081
14609
  if (Object.keys(pathParams).length) out.pathParams = pathParams;
@@ -14087,8 +14615,8 @@ function arazzoWorkflows(doc, model, source) {
14087
14615
  }
14088
14616
  return steps;
14089
14617
  };
14090
- const expression = (text2, scope) => {
14091
- const m = text2.match(/^\$inputs\.([\w-]+)(#\/.*)?$/);
14618
+ const expression = (text3, scope) => {
14619
+ const m = text3.match(/^\$inputs\.([\w-]+)(#\/.*)?$/);
14092
14620
  if (!m) return void 0;
14093
14621
  const [, name, pointer2] = m;
14094
14622
  if (scope.given?.has(name)) {
@@ -14110,9 +14638,9 @@ function arazzoWorkflows(doc, model, source) {
14110
14638
  if (typeof value === "string") {
14111
14639
  const whole = value.match(/^\{?(\$[^{}\s]+)\}?$/);
14112
14640
  if (whole) return expression(whole[1], scope) ?? (example !== void 0 ? example : key ? standIn(key) : value);
14113
- return value.replace(/\{(\$[^{}\s]+)\}/g, (text2, expr) => {
14641
+ return value.replace(/\{(\$[^{}\s]+)\}/g, (text3, expr) => {
14114
14642
  const filled = expression(expr, scope);
14115
- return filled === void 0 ? text2 : typeof filled === "string" ? filled : JSON.stringify(filled);
14643
+ return filled === void 0 ? text3 : typeof filled === "string" ? filled : JSON.stringify(filled);
14116
14644
  });
14117
14645
  }
14118
14646
  if (Array.isArray(value)) return value.map((v, i) => resolve4(v, scope, Array.isArray(example) ? example[i] : void 0, key));
@@ -14136,7 +14664,7 @@ function arazzoWorkflows(doc, model, source) {
14136
14664
  return isObject2(resolved) ? resolved : {};
14137
14665
  };
14138
14666
  const workflows = [];
14139
- for (const workflow of list6) {
14667
+ for (const workflow of list7) {
14140
14668
  const steps = expand(workflow, { inputs: inputsOf(workflow) }, 0);
14141
14669
  if (!steps.length) {
14142
14670
  notes.add(`The workflow ${workflow.workflowId} has no steps on this API description, so it isn't offered.`);
@@ -14184,19 +14712,19 @@ function follow(value, pointer2) {
14184
14712
  return node2;
14185
14713
  }
14186
14714
  function decodePointer2(part) {
14187
- let text2 = part;
14715
+ let text3 = part;
14188
14716
  try {
14189
- text2 = decodeURIComponent(part);
14717
+ text3 = decodeURIComponent(part);
14190
14718
  } catch {
14191
14719
  }
14192
- return text2.replace(/~1/g, "/").replace(/~0/g, "~");
14720
+ return text3.replace(/~1/g, "/").replace(/~0/g, "~");
14193
14721
  }
14194
14722
  function encodePointer(part) {
14195
14723
  return part.replace(/~/g, "~0").replace(/\//g, "~1");
14196
14724
  }
14197
- function firstSentence3(text2) {
14198
- if (typeof text2 !== "string" || !text2.trim()) return void 0;
14199
- const plain = text2.replace(/\s+/g, " ").trim();
14725
+ function firstSentence3(text3) {
14726
+ if (typeof text3 !== "string" || !text3.trim()) return void 0;
14727
+ const plain = text3.replace(/\s+/g, " ").trim();
14200
14728
  const sentence = plain.match(/^(.+?[.!?])(\s|$)/)?.[1] ?? plain;
14201
14729
  return /[.!?]$/.test(sentence) ? sentence : `${sentence}.`;
14202
14730
  }
@@ -14312,9 +14840,9 @@ async function readSpec(raw, url, options) {
14312
14840
  return { parsed: parseSpec(raw, { parseYaml: parseYaml2, external: url || docs.size ? { url: address, docs } : void 0, ...environments.length ? { environments } : {} }), named };
14313
14841
  }
14314
14842
  function uploadedEnvironments(files, parseYaml2) {
14315
- return [...files.values()].flatMap((text2) => {
14843
+ return [...files.values()].flatMap((text3) => {
14316
14844
  try {
14317
- const doc = decode(text2, { parseYaml: parseYaml2 });
14845
+ const doc = decode(text3, { parseYaml: parseYaml2 });
14318
14846
  return isPostmanEnvironment(doc) ? [doc] : [];
14319
14847
  } catch {
14320
14848
  return [];
@@ -14370,9 +14898,9 @@ async function readFirst(urls, read2) {
14370
14898
  }
14371
14899
  function uploadedDeclarations(files, parseYaml2) {
14372
14900
  const out = /* @__PURE__ */ new Map();
14373
- for (const [address, text2] of files) {
14901
+ for (const [address, text3] of files) {
14374
14902
  try {
14375
- const doc = decode(text2, { parseYaml: parseYaml2 });
14903
+ const doc = decode(text3, { parseYaml: parseYaml2 });
14376
14904
  if (!isSwagger1(doc) || doc.resourcePath === void 0) continue;
14377
14905
  out.set(resourceKey2(String(doc.resourcePath)), { at: address, doc });
14378
14906
  const file = resourceKey2(address.split("/").pop() ?? "");
@@ -14385,9 +14913,9 @@ function uploadedDeclarations(files, parseYaml2) {
14385
14913
  function resourceKey2(path) {
14386
14914
  return decodeURIComponent(path.replace("{format}", "json")).replace(/\.(json|ya?ml)$/i, "").replace(/\/$/, "").split("/").pop()?.toLowerCase() ?? "";
14387
14915
  }
14388
- async function loadDocument(text2, url, options) {
14389
- checkSize(text2);
14390
- const raw = decode(text2, { parseYaml: options.parseYaml });
14916
+ async function loadDocument(text3, url, options) {
14917
+ checkSize(text3);
14918
+ const raw = decode(text3, { parseYaml: options.parseYaml });
14391
14919
  if (isArazzo(raw)) return loadArazzo(raw, url, options);
14392
14920
  if (isMcpDocument(raw)) return { parsed: parseMcp(raw, url ? nameOf(url) : options.name && fileTitle(options.name)) };
14393
14921
  const { parsed, named } = await readSpec(raw, url, options);
@@ -14414,8 +14942,8 @@ async function loadArazzo(doc, url, options) {
14414
14942
  if (!options.read && target.origin === UPLOAD_ORIGIN && uploadedFile(options.files, target) === void 0) {
14415
14943
  throw new SpecError(`This Arazzo file runs against ${source.url}, which wasn't uploaded with it.`, ["Upload the two together, or load the Arazzo file from its URL."]);
14416
14944
  }
14417
- const text2 = await readText(target, options);
14418
- const { parsed, named } = await readSpec(decode(text2, { parseYaml: options.parseYaml }), target, options);
14945
+ const text3 = await readText(target, options);
14946
+ const { parsed, named } = await readSpec(decode(text3, { parseYaml: options.parseYaml }), target, options);
14419
14947
  const { workflows, notes } = arazzoWorkflows(doc, buildModel(parsed.doc), source.name);
14420
14948
  if (!workflows.length) throw new SpecError("None of this Arazzo file's workflows match the API description it names.", notes);
14421
14949
  return {
@@ -14476,8 +15004,8 @@ function isPrivateAddress(address) {
14476
15004
  function hextets(ip) {
14477
15005
  const dotted = ip.match(/^(.*:)(\d+\.\d+\.\d+\.\d+)$/);
14478
15006
  const tail = dotted ? dotted[2].split(".").map(Number) : [];
14479
- const text2 = dotted ? `${dotted[1]}${(tail[0] << 8 | tail[1]).toString(16)}:${(tail[2] << 8 | tail[3]).toString(16)}` : ip;
14480
- const [head, rest] = text2.split("::");
15007
+ const text3 = dotted ? `${dotted[1]}${(tail[0] << 8 | tail[1]).toString(16)}:${(tail[2] << 8 | tail[3]).toString(16)}` : ip;
15008
+ const [head, rest] = text3.split("::");
14481
15009
  const front = head ? head.split(":") : [];
14482
15010
  const back = rest === void 0 ? [] : rest ? rest.split(":") : [];
14483
15011
  const words2 = [...front, ...Array(8 - front.length - back.length).fill("0"), ...back].map((w) => parseInt(w, 16));
@@ -14574,13 +15102,13 @@ async function loadSpec(spec, options = {}) {
14574
15102
  }
14575
15103
  const file = (0, import_node_path.resolve)(spec);
14576
15104
  const root = repoRoot((0, import_node_path.dirname)(file));
14577
- let text2;
15105
+ let text3;
14578
15106
  try {
14579
- text2 = await (0, import_promises.readFile)(file, "utf8");
15107
+ text3 = await (0, import_promises.readFile)(file, "utf8");
14580
15108
  } catch {
14581
15109
  throw new SpecError(`Can't read the spec, ${(0, import_node_path.relative)(process.cwd(), file) || spec}.`);
14582
15110
  }
14583
- return { ...await loadDocument(text2, addressOf(root, file), { parseYaml, read: reader(root, downloads(void 0, options.allowPrivateRefs), unread) }), unread };
15111
+ return { ...await loadDocument(text3, addressOf(root, file), { parseYaml, read: reader(root, downloads(void 0, options.allowPrivateRefs), unread) }), unread };
14584
15112
  }
14585
15113
 
14586
15114
  // ../../lib/publicKey.ts
@@ -14632,18 +15160,18 @@ function readLicense(payload) {
14632
15160
  if (v !== 1 || typeof id !== "string" || !id || typeof org !== "string" || !org.trim() || typeof until !== "string" || !isDay(until)) return void 0;
14633
15161
  return { id, org, until };
14634
15162
  }
14635
- function isDay(text2) {
14636
- const time = /^\d{4}-\d{2}-\d{2}$/.test(text2) ? Date.parse(`${text2}T00:00:00Z`) : NaN;
14637
- return !Number.isNaN(time) && new Date(time).toISOString().slice(0, 10) === text2;
15163
+ function isDay(text3) {
15164
+ const time = /^\d{4}-\d{2}-\d{2}$/.test(text3) ? Date.parse(`${text3}T00:00:00Z`) : NaN;
15165
+ return !Number.isNaN(time) && new Date(time).toISOString().slice(0, 10) === text3;
14638
15166
  }
14639
- function utf8(text2) {
14640
- return new Uint8Array(new TextEncoder().encode(text2));
15167
+ function utf8(text3) {
15168
+ return new Uint8Array(new TextEncoder().encode(text3));
14641
15169
  }
14642
- function fromBase64url(text2) {
14643
- if (!/^[A-Za-z0-9_-]+$/.test(text2)) return void 0;
15170
+ function fromBase64url(text3) {
15171
+ if (!/^[A-Za-z0-9_-]+$/.test(text3)) return void 0;
14644
15172
  let binary2;
14645
15173
  try {
14646
- binary2 = atob(text2.replace(/-/g, "+").replace(/_/g, "/"));
15174
+ binary2 = atob(text3.replace(/-/g, "+").replace(/_/g, "/"));
14647
15175
  } catch {
14648
15176
  return void 0;
14649
15177
  }
@@ -14792,8 +15320,10 @@ input[type="range"] { flex: 1; min-width: 120px; margin: 0 8px; accent-color: va
14792
15320
  }
14793
15321
 
14794
15322
  // ../../lib/storyboard/command.ts
14795
- function fileSlug(text2) {
14796
- return text2.toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, 60).replace(/^-|-$/g, "") || "integration-tour";
15323
+ var INSOMNIA_PLUGIN = "insomnia-plugin-integration-tour";
15324
+ var INSOMNIA_INSTALL = `insomnia://plugins/install?name=${INSOMNIA_PLUGIN}`;
15325
+ function fileSlug(text3) {
15326
+ return text3.toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, 60).replace(/^-|-$/g, "") || "integration-tour";
14797
15327
  }
14798
15328
  function shortName(title) {
14799
15329
  const slug = fileSlug(title);
@@ -14821,8 +15351,8 @@ function u16(n) {
14821
15351
  function u32(n) {
14822
15352
  return Uint8Array.of(n >>> 24 & 255, n >>> 16 & 255, n >>> 8 & 255, n & 255);
14823
15353
  }
14824
- function ascii(text2) {
14825
- return Uint8Array.from(text2, (c) => c.charCodeAt(0) & 127);
15354
+ function ascii(text3) {
15355
+ return Uint8Array.from(text3, (c) => c.charCodeAt(0) & 127);
14826
15356
  }
14827
15357
  function zeros(n) {
14828
15358
  return new Uint8Array(n);
@@ -15581,12 +16111,12 @@ async function openSpec(spec, options = {}) {
15581
16111
  }
15582
16112
  return { model: buildModel(loaded.parsed.doc), workflows: loaded.workflows, notes: loaded.parsed.warnings };
15583
16113
  }
15584
- function isFlowFile(text2) {
16114
+ function isFlowFile(text3) {
15585
16115
  let raw;
15586
16116
  try {
15587
- raw = parseYaml(text2);
16117
+ raw = parseYaml(text3);
15588
16118
  } catch {
15589
- return /^scenes:/m.test(text2);
16119
+ return /^scenes:/m.test(text3);
15590
16120
  }
15591
16121
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return false;
15592
16122
  const keys = Object.keys(raw);
@@ -15606,20 +16136,20 @@ function flowNames(flows) {
15606
16136
  const whole = flows.map((flow, i) => shared(short)(short[i]) ? fileSlug(flow.name) : short[i]);
15607
16137
  return whole.map((name, i) => shared(whole)(name) ? `${name.slice(0, 54).replace(/-$/, "")}-${tag(flows[i].id)}` : name);
15608
16138
  }
15609
- function tag(text2) {
16139
+ function tag(text3) {
15610
16140
  let hash = 2166136261;
15611
- for (let i = 0; i < text2.length; i++) hash = Math.imul(hash ^ text2.charCodeAt(i), 16777619) >>> 0;
16141
+ for (let i = 0; i < text3.length; i++) hash = Math.imul(hash ^ text3.charCodeAt(i), 16777619) >>> 0;
15612
16142
  return hash.toString(36).padStart(5, "0").slice(-5);
15613
16143
  }
15614
16144
  async function editedVideo(spec, flowFile, fonts) {
15615
- let text2;
16145
+ let text3;
15616
16146
  try {
15617
- text2 = await (0, import_promises2.readFile)(flowFile, "utf8");
16147
+ text3 = await (0, import_promises2.readFile)(flowFile, "utf8");
15618
16148
  } catch {
15619
16149
  throw new FlowFileError(/[*?]/.test((0, import_node_path3.basename)(flowFile)) ? `No file matches ${flowFile}. Save a flow file from the app's Generate from a command, or leave out --edits for the spec's own flows.` : `Can't read ${flowFile}.`);
15620
16150
  }
15621
- if (!isFlowFile(text2)) throw new FlowFileError(`${flowFile} isn't a flow file. Give the spec first, and only flow files after --edits.`);
15622
- const file = parseFlowFile(text2, parseYaml);
16151
+ if (!isFlowFile(text3)) throw new FlowFileError(`${flowFile} isn't a flow file. Give the spec first, and only flow files after --edits.`);
16152
+ const file = parseFlowFile(text3, parseYaml);
15623
16153
  let logo;
15624
16154
  if (file.brand.logo) {
15625
16155
  const path = (0, import_node_path3.resolve)((0, import_node_path3.dirname)(flowFile), file.brand.logo);
@@ -15660,9 +16190,9 @@ Usage:
15660
16190
  integration-tour check <spec file or URL> [--edits <flow files or folder>]
15661
16191
  [--allow-private-refs]
15662
16192
 
15663
- The spec is OpenAPI, Swagger, a Postman collection or an Arazzo file, as a file or a URL, or
15664
- an MCP server's URL, whose tools it reads by connecting to it. --edits takes the flow files
15665
- saved from the app, which hold your edits to a video, or a folder of them.
16193
+ The spec is OpenAPI, Swagger, a Postman collection, an Insomnia export or an Arazzo file, as a
16194
+ file or a URL, or an MCP server's URL, whose tools it reads by connecting to it. --edits takes
16195
+ the flow files saved from the app, which hold your edits to a video, or a folder of them.
15666
16196
 
15667
16197
  render Without --edits, makes a video of each of the top three flows the spec suggests (an
15668
16198
  Arazzo file's workflows, every one), unedited, named after the flow; pick another in
@@ -15785,7 +16315,7 @@ async function main(argv, env = process.env, fontsDir = (0, import_node_path4.jo
15785
16315
  };
15786
16316
  const madeFor = /* @__PURE__ */ new Map();
15787
16317
  const announce = (total) => {
15788
- const made = command === "render" ? `, as ${list5(formats.map((format) => format.toUpperCase()))}` : "";
16318
+ const made = command === "render" ? `, as ${list6(formats.map((format) => format.toUpperCase()))}` : "";
15789
16319
  console.log(` ${command === "render" ? "Making" : "Checking"} ${total} video${total === 1 ? "" : "s"}${made}:`);
15790
16320
  };
15791
16321
  const heading = (n, total, label) => ` Video ${n} of ${total} \xB7 ${label}`;
@@ -15896,7 +16426,7 @@ function distance(a, b) {
15896
16426
  }
15897
16427
  return above[b.length];
15898
16428
  }
15899
- function list5(items) {
16429
+ function list6(items) {
15900
16430
  return items.length < 2 ? items.join("") : `${items.slice(0, -1).join(", ")} and ${items.at(-1)}`;
15901
16431
  }
15902
16432
  function size(bytes) {