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.
- package/README.md +1 -1
- package/dist/cli.js +938 -408
- 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": (
|
|
2942
|
-
const [date, time] =
|
|
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: (
|
|
2946
|
-
const m =
|
|
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: (
|
|
2953
|
-
const m =
|
|
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: (
|
|
2957
|
-
uri: (
|
|
2958
|
-
url: (
|
|
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": (
|
|
2961
|
-
"uri-template": (
|
|
2962
|
-
uuid: (
|
|
2963
|
-
ipv4: (
|
|
2964
|
-
ipv6: (
|
|
2965
|
-
hostname: (
|
|
2966
|
-
byte: (
|
|
2967
|
-
duration: (
|
|
2968
|
-
regex: (
|
|
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(
|
|
2970
|
+
new RegExp(text3);
|
|
2971
2971
|
return true;
|
|
2972
2972
|
} catch {
|
|
2973
2973
|
return false;
|
|
2974
2974
|
}
|
|
2975
2975
|
},
|
|
2976
|
-
"json-pointer": (
|
|
2976
|
+
"json-pointer": (text3) => /^(?:\/(?:[^~/]|~0|~1)*)*$/.test(text3)
|
|
2977
2977
|
};
|
|
2978
|
-
function formatFits(format,
|
|
2978
|
+
function formatFits(format, text3) {
|
|
2979
2979
|
const test = FORMATS[format];
|
|
2980
|
-
return test ? test(
|
|
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,
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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(
|
|
3161
|
+
lines.push(text3 === void 0 ? `${open}/>` : `${open}>${text3}</${qname}>`);
|
|
3162
3162
|
return;
|
|
3163
3163
|
}
|
|
3164
|
-
lines.push(`${open}>${
|
|
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(
|
|
3186
|
-
if (isPlaceholder(
|
|
3187
|
-
const out =
|
|
3185
|
+
function escapeXml(text3, attribute = false) {
|
|
3186
|
+
if (isPlaceholder(text3)) return `{${text3.slice(1, -1)}}`;
|
|
3187
|
+
const out = text3.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
3188
3188
|
return attribute ? out.replace(/"/g, """) : 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
|
|
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) =>
|
|
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
|
|
3560
|
-
const first = schema2.properties &&
|
|
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, ...
|
|
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
|
|
3751
|
-
if (
|
|
3752
|
-
const node2 = parsePattern(
|
|
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
|
|
3821
|
+
const text3 = pattern.slice(i, close + 1);
|
|
3822
3822
|
i = close + 1;
|
|
3823
3823
|
let set2;
|
|
3824
3824
|
try {
|
|
3825
|
-
set2 = new RegExp(`^${
|
|
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,
|
|
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
|
|
4082
|
-
return `-F '${escapeSingle(`${part.name}=${
|
|
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(
|
|
4093
|
-
return /^[@<"\s]|;|\s$/.test(
|
|
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(
|
|
4100
|
-
if (!always && !/[^\w@%+=:,./-]/.test(
|
|
4101
|
-
return /["\\$`!]/.test(
|
|
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(
|
|
4104
|
-
return
|
|
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
|
|
4134
|
-
body =
|
|
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(
|
|
4145
|
-
return JSON.stringify(
|
|
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 = (
|
|
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
|
|
4178
|
-
args.push(
|
|
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(
|
|
4237
|
-
const plain = /^[\x21-\x7e]([\x20-\x7e\t]*[\x21-\x7e])?$/.test(
|
|
4238
|
-
if (plain) return
|
|
4239
|
-
const bytes = new TextEncoder().encode(
|
|
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
|
|
4313
|
-
if (as === "json") return
|
|
4314
|
-
return
|
|
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(
|
|
4318
|
+
function cut(text3, max) {
|
|
4319
4319
|
const end = Math.max(0, max);
|
|
4320
|
-
const last =
|
|
4321
|
-
return
|
|
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(
|
|
4325
|
-
return
|
|
4324
|
+
function wellFormed(text3) {
|
|
4325
|
+
return text3.replace(HALVES, (c) => c.length === 2 ? c : "");
|
|
4326
4326
|
}
|
|
4327
|
-
function clip(
|
|
4328
|
-
return
|
|
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,
|
|
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(
|
|
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,
|
|
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(
|
|
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,
|
|
4735
|
+
function badge(box2, text3, color, opacity) {
|
|
4736
4736
|
const size2 = 15;
|
|
4737
|
-
const w = Math.min(box2.w, textWidth(
|
|
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(
|
|
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,
|
|
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 ${
|
|
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
|
|
4757
|
+
let text3;
|
|
4758
4758
|
try {
|
|
4759
4759
|
const replacer = fold ? (key, v) => fold.has(key) && isRecord3(v) ? FOLDED : v : void 0;
|
|
4760
|
-
|
|
4760
|
+
text3 = typeof value === "string" ? value : JSON.stringify(value, replacer, 2)?.replace(/"\uE000"/g, "{ \u2026 }") ?? "";
|
|
4761
4761
|
} catch {
|
|
4762
|
-
|
|
4762
|
+
text3 = String(value);
|
|
4763
4763
|
}
|
|
4764
|
-
let lines =
|
|
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(
|
|
4781
|
-
let lines =
|
|
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(
|
|
4834
|
-
const trimmed =
|
|
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(
|
|
4836
|
+
return `<tspan fill="${color}">${esc(text3)}</tspan>`;
|
|
4837
4837
|
}
|
|
4838
|
-
function textWidth(
|
|
4839
|
-
return
|
|
4838
|
+
function textWidth(text3, size2, mono = false) {
|
|
4839
|
+
return text3.length * size2 * (mono ? 0.6 : 0.54);
|
|
4840
4840
|
}
|
|
4841
|
-
function fit(
|
|
4841
|
+
function fit(text3, width, size2, mono = false) {
|
|
4842
4842
|
const max = Math.floor(width / (size2 * (mono ? 0.6 : 0.54)));
|
|
4843
|
-
return
|
|
4843
|
+
return text3.length > max ? cut(text3, Math.max(1, max - 1)) + "\u2026" : text3;
|
|
4844
4844
|
}
|
|
4845
|
-
function wrap(
|
|
4845
|
+
function wrap(text3, width, size2, maxLines) {
|
|
4846
4846
|
const max = Math.max(8, Math.floor(width / (size2 * 0.54)));
|
|
4847
|
-
const words2 =
|
|
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(
|
|
4868
|
-
return
|
|
4867
|
+
function esc(text3) {
|
|
4868
|
+
return text3.replace(NOT_XML, (c) => c.length === 2 ? c : c < " " ? " " : "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
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
|
|
4954
|
-
if (
|
|
4953
|
+
const text3 = server.tools.filter((tool) => !tool.outputSchema).length;
|
|
4954
|
+
if (text3 && server.tools.length) {
|
|
4955
4955
|
warnings.push(
|
|
4956
|
-
|
|
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
|
|
5285
|
-
function
|
|
5286
|
-
if (
|
|
5287
|
-
|
|
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(
|
|
5330
|
-
return
|
|
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
|
|
5338
|
-
return
|
|
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(
|
|
5376
|
-
let rest =
|
|
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(
|
|
5416
|
+
function decoded(text3) {
|
|
5398
5417
|
try {
|
|
5399
|
-
return decodeURIComponent(
|
|
5418
|
+
return decodeURIComponent(text3.replace(/\+/g, " "));
|
|
5400
5419
|
} catch {
|
|
5401
|
-
return
|
|
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
|
|
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 =
|
|
5487
|
-
|
|
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:
|
|
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 =
|
|
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 =
|
|
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 = (
|
|
5554
|
-
function jsonBody(
|
|
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 <
|
|
5558
|
-
const c =
|
|
5559
|
-
if (c === "{" &&
|
|
5560
|
-
const end =
|
|
5561
|
-
const name = end > 0 ?
|
|
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 =
|
|
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 +=
|
|
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 === "/" &&
|
|
5581
|
-
const end =
|
|
5582
|
-
i = end < 0 ?
|
|
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 === "/" &&
|
|
5585
|
-
const end =
|
|
5586
|
-
i = end < 0 ?
|
|
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 <
|
|
5591
|
-
if (
|
|
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(
|
|
5630
|
+
function parseJson(text3) {
|
|
5611
5631
|
try {
|
|
5612
|
-
return JSON.parse(
|
|
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
|
|
5670
|
-
if (!
|
|
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(
|
|
5693
|
+
const type2 = contentType ?? RAW_TYPES[language] ?? (looksJson(text3) ? "application/json" : "text/plain");
|
|
5674
5694
|
if (/json/i.test(type2)) {
|
|
5675
|
-
const value = jsonBody(
|
|
5676
|
-
if (value !== void 0) return { media: type2, ...payloadOf(value, true) };
|
|
5677
|
-
return { media: "text/plain", schema: { type: "string" }, example: vars.fill(
|
|
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(
|
|
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) =>
|
|
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
|
|
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
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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() :
|
|
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/
|
|
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
|
|
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) =>
|
|
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) =>
|
|
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 (!
|
|
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 (!
|
|
6489
|
+
if (!isObj3(api) || typeof api.path !== "string") continue;
|
|
5998
6490
|
const doc2 = declaration(api.path);
|
|
5999
|
-
if (!
|
|
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 }) =>
|
|
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(
|
|
6501
|
+
const { definitions: securityDefinitions, names: securityNames } = securityDefinitionsOf(isObj3(root.authorizations) ? root.authorizations : {});
|
|
6010
6502
|
const security = (auth) => {
|
|
6011
|
-
if (!
|
|
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) =>
|
|
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(
|
|
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 (!
|
|
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 =
|
|
6527
|
+
const item = isObj3(paths[path]) ? paths[path] : paths[path] = {};
|
|
6036
6528
|
for (const op of api.operations) {
|
|
6037
|
-
if (!
|
|
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) =>
|
|
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 =
|
|
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 (
|
|
6625
|
+
if (isObj3(items)) out.items = this.data(items, allowRef);
|
|
6134
6626
|
}
|
|
6135
|
-
if (out.type === "array" && !
|
|
6627
|
+
if (out.type === "array" && !isObj3(out.items)) out.items = {};
|
|
6136
6628
|
const defaultValue = old.defaultValue ?? old.default;
|
|
6137
|
-
const allowable =
|
|
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" &&
|
|
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 (!
|
|
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 (
|
|
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(
|
|
6209
|
-
if (typeof child !== "string" || !
|
|
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(
|
|
6220
|
-
if (!
|
|
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:
|
|
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 (!
|
|
6240
|
-
const scopes = Object.fromEntries(arr(auth.scopes).flatMap((s) =>
|
|
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 =
|
|
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 =
|
|
6252
|
-
const endpoint = (key2) =>
|
|
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 (
|
|
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
|
|
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 =
|
|
6792
|
+
const sharedParams = isObj4(doc.parameters) ? doc.parameters : {};
|
|
6301
6793
|
const resolveParam = (p) => {
|
|
6302
|
-
const ref =
|
|
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(
|
|
6307
|
-
if (!
|
|
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) =>
|
|
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 (!
|
|
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 (
|
|
6329
|
-
if (
|
|
6330
|
-
if (
|
|
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 (
|
|
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 =
|
|
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" &&
|
|
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(
|
|
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 =
|
|
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 (
|
|
6392
|
-
const 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 (!
|
|
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 =
|
|
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:
|
|
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 (!
|
|
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 (!
|
|
6950
|
+
if (!isObj5(item)) return [];
|
|
6459
6951
|
const out = [];
|
|
6460
|
-
for (const method of HTTP_METHODS) if (
|
|
6461
|
-
if (
|
|
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 (
|
|
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
|
|
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(
|
|
6527
|
-
if (
|
|
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,
|
|
6539
|
-
if (!Object.keys(converted.doc.paths).length) throw new SpecError(
|
|
6540
|
-
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: ${
|
|
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 ${
|
|
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
|
|
6577
|
-
|
|
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(
|
|
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: ${
|
|
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: ${
|
|
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(
|
|
7378
|
+
function safeDecode(text3) {
|
|
6851
7379
|
try {
|
|
6852
|
-
return decodeURIComponent(
|
|
7380
|
+
return decodeURIComponent(text3);
|
|
6853
7381
|
} catch {
|
|
6854
|
-
return
|
|
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
|
|
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((
|
|
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
|
|
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:
|
|
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(
|
|
7455
|
-
if (!
|
|
7456
|
-
const plain =
|
|
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(
|
|
7462
|
-
const words2 =
|
|
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
|
|
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(
|
|
7467
|
-
return
|
|
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
|
|
7513
|
-
return /^[A-Za-z_][\w-]*(\.[A-Za-z_][\w-]*)+$/.test(
|
|
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 = (
|
|
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(
|
|
8323
|
+
function parseJson2(text3) {
|
|
7796
8324
|
try {
|
|
7797
|
-
return JSON.parse(
|
|
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
|
|
7822
|
-
const value = mode === "request" ? wholeRequest(example.value,
|
|
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
|
|
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
|
|
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) =>
|
|
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) =>
|
|
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 =
|
|
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(
|
|
7959
|
-
return typeof
|
|
8486
|
+
function said(text3) {
|
|
8487
|
+
return typeof text3 === "string" && text3.trim() ? text3 : void 0;
|
|
7960
8488
|
}
|
|
7961
|
-
function firstSentence2(
|
|
7962
|
-
if (!
|
|
7963
|
-
const plain =
|
|
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((
|
|
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
|
|
7980
|
-
if (typeof
|
|
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 = (
|
|
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
|
|
8005
|
-
const label = typeof
|
|
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(
|
|
8011
|
-
let plain =
|
|
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,
|
|
8058
|
-
if (
|
|
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,
|
|
8067
|
-
const kept = wholeRequest(value,
|
|
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
|
|
8081
|
-
budget.left -=
|
|
8082
|
-
return
|
|
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(
|
|
8128
|
-
let lines =
|
|
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
|
|
8450
|
-
if (
|
|
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(
|
|
8457
|
-
return
|
|
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(
|
|
8472
|
-
return
|
|
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(
|
|
8520
|
-
return
|
|
9047
|
+
function humanize(text3) {
|
|
9048
|
+
return text3.replace(/[_-]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase();
|
|
8521
9049
|
}
|
|
8522
|
-
function capitalize2(
|
|
8523
|
-
return
|
|
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
|
|
8566
|
-
const encoded = isPlaceholder(
|
|
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
|
|
8617
|
-
if (/^\s*[[{]/.test(
|
|
9144
|
+
const text3 = block.text;
|
|
9145
|
+
if (/^\s*[[{]/.test(text3)) {
|
|
8618
9146
|
try {
|
|
8619
|
-
look(JSON.parse(
|
|
9147
|
+
look(JSON.parse(text3), 0);
|
|
8620
9148
|
continue;
|
|
8621
9149
|
} catch {
|
|
8622
9150
|
}
|
|
8623
9151
|
}
|
|
8624
|
-
const number =
|
|
9152
|
+
const number = text3.match(/#(\d+)\b/)?.[1];
|
|
8625
9153
|
if (found.number === void 0 && number) found.number = Number(number);
|
|
8626
|
-
const id =
|
|
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(
|
|
8916
|
-
return /^[A-Z][a-z]/.test(
|
|
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(
|
|
9230
|
-
const m =
|
|
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(
|
|
9279
|
-
return
|
|
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,
|
|
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(
|
|
9945
|
-
return
|
|
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 ${
|
|
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(
|
|
10329
|
-
return
|
|
10856
|
+
function capital(text3) {
|
|
10857
|
+
return text3.charAt(0).toUpperCase() + text3.slice(1);
|
|
10330
10858
|
}
|
|
10331
|
-
function
|
|
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(
|
|
10862
|
+
function parseFlowFile(text3, parseYaml2) {
|
|
10335
10863
|
let raw;
|
|
10336
10864
|
try {
|
|
10337
|
-
raw = parseYaml2(
|
|
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 :
|
|
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 =
|
|
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 =
|
|
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,
|
|
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 =
|
|
10971
|
+
const allowed = bare2 ? kind === "call" ? ["operation"] : [] : SCENE_FIELDS[kind];
|
|
10444
10972
|
unknownKeys(item, [kind, ...allowed], where, problems);
|
|
10445
|
-
const edits =
|
|
10973
|
+
const edits = bare2 ? {} : readEdits(item, kind, where, problems);
|
|
10446
10974
|
switch (kind) {
|
|
10447
10975
|
case "call": {
|
|
10448
|
-
const call =
|
|
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 :
|
|
10451
|
-
const failure = item.failure === void 0 ||
|
|
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 =
|
|
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 :
|
|
10460
|
-
const subtitle = item.subtitle === void 0 ? void 0 :
|
|
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 :
|
|
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 =
|
|
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 =
|
|
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
|
|
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.
|
|
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(
|
|
13603
|
-
const value = load(
|
|
13604
|
-
if (ANCHOR.test(
|
|
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
|
|
14336
|
+
const text3 = await readCapped(res);
|
|
13809
14337
|
try {
|
|
13810
|
-
const parsed = JSON.parse(
|
|
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
|
|
13850
|
-
if (
|
|
13851
|
-
return
|
|
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
|
|
13864
|
-
if (!
|
|
13865
|
-
const invalid = new SpecError(`That isn't a valid URL: ${
|
|
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(
|
|
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
|
|
13944
|
-
if (/^\s*</.test(
|
|
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
|
|
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
|
|
14515
|
+
let text3 = "";
|
|
13988
14516
|
for (; ; ) {
|
|
13989
14517
|
const { done, value } = await reader2.read();
|
|
13990
|
-
if (done) return
|
|
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
|
-
|
|
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
|
|
14021
|
-
const byId = new Map(
|
|
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
|
|
14078
|
-
query.push(`${encodeURIComponent(wellFormed(p.name))}=${isPlaceholder(
|
|
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 = (
|
|
14091
|
-
const m =
|
|
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, (
|
|
14641
|
+
return value.replace(/\{(\$[^{}\s]+)\}/g, (text3, expr) => {
|
|
14114
14642
|
const filled = expression(expr, scope);
|
|
14115
|
-
return filled === void 0 ?
|
|
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
|
|
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
|
|
14715
|
+
let text3 = part;
|
|
14188
14716
|
try {
|
|
14189
|
-
|
|
14717
|
+
text3 = decodeURIComponent(part);
|
|
14190
14718
|
} catch {
|
|
14191
14719
|
}
|
|
14192
|
-
return
|
|
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(
|
|
14198
|
-
if (typeof
|
|
14199
|
-
const plain =
|
|
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((
|
|
14843
|
+
return [...files.values()].flatMap((text3) => {
|
|
14316
14844
|
try {
|
|
14317
|
-
const doc = decode(
|
|
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,
|
|
14901
|
+
for (const [address, text3] of files) {
|
|
14374
14902
|
try {
|
|
14375
|
-
const doc = decode(
|
|
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(
|
|
14389
|
-
checkSize(
|
|
14390
|
-
const raw = decode(
|
|
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
|
|
14418
|
-
const { parsed, named } = await readSpec(decode(
|
|
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
|
|
14480
|
-
const [head, rest] =
|
|
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
|
|
15105
|
+
let text3;
|
|
14578
15106
|
try {
|
|
14579
|
-
|
|
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(
|
|
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(
|
|
14636
|
-
const time = /^\d{4}-\d{2}-\d{2}$/.test(
|
|
14637
|
-
return !Number.isNaN(time) && new Date(time).toISOString().slice(0, 10) ===
|
|
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(
|
|
14640
|
-
return new Uint8Array(new TextEncoder().encode(
|
|
15167
|
+
function utf8(text3) {
|
|
15168
|
+
return new Uint8Array(new TextEncoder().encode(text3));
|
|
14641
15169
|
}
|
|
14642
|
-
function fromBase64url(
|
|
14643
|
-
if (!/^[A-Za-z0-9_-]+$/.test(
|
|
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(
|
|
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
|
-
|
|
14796
|
-
|
|
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(
|
|
14825
|
-
return Uint8Array.from(
|
|
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(
|
|
16114
|
+
function isFlowFile(text3) {
|
|
15585
16115
|
let raw;
|
|
15586
16116
|
try {
|
|
15587
|
-
raw = parseYaml(
|
|
16117
|
+
raw = parseYaml(text3);
|
|
15588
16118
|
} catch {
|
|
15589
|
-
return /^scenes:/m.test(
|
|
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(
|
|
16139
|
+
function tag(text3) {
|
|
15610
16140
|
let hash = 2166136261;
|
|
15611
|
-
for (let i = 0; i <
|
|
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
|
|
16145
|
+
let text3;
|
|
15616
16146
|
try {
|
|
15617
|
-
|
|
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(
|
|
15622
|
-
const file = parseFlowFile(
|
|
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
|
|
15664
|
-
an MCP server's URL, whose tools it reads by connecting to it. --edits takes
|
|
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 ${
|
|
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
|
|
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) {
|