@scalar/api-client
Version:
the open source API testing client
338 lines (337 loc) • 10.1 kB
JavaScript
import { collectionSchema as A, requestSchema as O, serverSchema as R, tagSchema as b, securitySchemeSchema as S, createExampleFromRequest as D } from "@scalar/oas-utils/entities/spec";
import { schemaModel as v, isHttpMethod as N } from "@scalar/oas-utils/helpers";
import { getNestedValue as M } from "@scalar/object-utils/nested";
import k from "microdiff";
import { z as p } from "zod";
const x = (e, n = []) => {
const t = [];
let s = !1;
for (let u = 0; u < e.length; u++) {
if (s) {
s = !1;
continue;
}
const a = e[u], r = e[u + 1];
if (a) {
if (n.length)
a.path = [...n, ...a.path], r && (r.path = [...n, ...r.path]);
else if (a.path[0] !== "paths") {
t.push(a);
continue;
}
if (a.type === "REMOVE" && r?.type === "CREATE") {
const [, i, o] = a.path, [, l, f] = r.path, c = ["paths", l].filter((d) => typeof d == "string");
if (i !== l && t.push({
type: "CHANGE",
path: ["paths", "path"],
oldValue: i,
value: l
}), o && typeof f == "string" && o !== f && l && (t.push({
type: "CHANGE",
path: ["paths", l, "method"],
oldValue: o,
value: f
}), c.push(f)), n.length === 0) {
const d = k(a.oldValue, r.value);
if (d.length) {
const T = x(d, c);
t.push(...T);
}
}
s = !0;
} else a.type === "CREATE" && a.path.length > 3 && typeof a.path.at(-1) != "number" ? t.push({ ...a, type: "CHANGE", oldValue: void 0 }) : a.type === "REMOVE" && a.path.length > 3 && typeof a.path.at(-1) != "number" ? t.push({ ...a, type: "CHANGE", value: void 0 }) : t.push(a);
}
}
return t;
}, E = (e, n, t) => {
for (const s of e) {
const u = n[s];
if (u && t(u))
return u;
}
return null;
}, h = (e) => {
if (e instanceof p.ZodOptional) {
const n = e.unwrap();
if (n instanceof p.ZodType)
return h(n);
}
if (e instanceof p.ZodDefault) {
const n = e._zod.def.innerType;
if (n instanceof p.ZodType)
return h(n);
}
if (e instanceof p.ZodCatch) {
const n = e._zod.def.innerType;
if (n instanceof p.ZodType)
return h(n);
}
if (e instanceof p.ZodPipe) {
const n = e._zod.def.in;
if (n instanceof p.ZodType)
return h(n);
}
return e;
}, H = (e, n) => {
let t = e;
for (const s of n) {
if (t = h(t), t instanceof p.ZodAny)
return t;
if (t instanceof p.ZodObject && typeof s == "string" && s in t.shape) {
const u = t.shape[s];
if (u instanceof p.ZodType)
t = u;
else
return null;
} else if (t instanceof p.ZodArray)
if (typeof s == "number")
if (t.element instanceof p.ZodType)
t = t.element;
else
return null;
else if (typeof s == "string") {
if (t.element instanceof p.ZodType)
t = t.element;
else
return null;
if (t instanceof p.ZodObject && s in t.shape) {
const u = t.shape[s];
if (u instanceof p.ZodType)
t = u;
else
return null;
} else
return null;
} else
return null;
else if (t instanceof p.ZodRecord) {
const u = t._zod.def.valueType;
if (!u || !(u instanceof p.ZodType))
return null;
if (typeof s == "string")
t = u, t = h(t);
else if (typeof s == "number") {
if (t = u, t = h(t), t instanceof p.ZodArray)
if (t.element instanceof p.ZodType)
t = t.element;
else
return null;
} else
t = u;
} else
return null;
t = h(t);
}
return t;
}, m = (e, n) => {
const t = H(e, n.path);
if (!t)
return null;
const s = n.path.join("."), u = n.path.slice(0, -1).join(".");
if (n.type === "REMOVE")
return {
path: s,
pathMinusOne: u,
value: void 0
};
const a = v(n.value, t, !1);
return typeof a > "u" || a === null ? null : {
path: s,
pathMinusOne: u,
value: a
};
}, F = (e, { activeCollection: n }, { collectionMutators: t }) => {
if (!n.value)
return !1;
if (typeof e.path[e.path.length - 1] == "number" && (e.type === "CREATE" || e.type === "REMOVE")) {
const s = m(A, {
...e,
path: e.path
});
if (!s)
return !1;
const u = [...M(n.value, s.pathMinusOne)];
e.type === "CREATE" ? u.push(s.value) : e.type === "REMOVE" && u.pop(), t.edit(n.value.uid, s.pathMinusOne, u);
} else {
const s = m(A, e);
if (!s)
return !1;
t.edit(n.value.uid, s.path, s.value);
}
return !0;
}, _ = (e, n) => {
const { requests: t, requestExamples: s, requestExampleMutators: u } = n, a = t[e];
a?.examples.forEach((r) => {
const i = D(a, s[r]?.name ?? "Default");
i && u.set({
...i,
uid: r
});
});
}, K = (e, { activeCollection: n }, t) => {
if (!n.value)
return !1;
const { requests: s, requestMutators: u } = t, [, a, r, ...i] = e.path;
if (a === "path" && e.type === "CHANGE")
n.value.requests.forEach((o) => {
s[o]?.path === e.oldValue && u.edit(o, "path", e.value);
});
else if (r === "method" && e.type === "CHANGE")
n.value.requests.forEach((o) => {
s[o]?.method === e.oldValue && s[o]?.path === a && u.edit(o, "method", e.value);
});
else if (e.type !== "CHANGE" && typeof i.at(-1) == "number") {
const o = E(
n.value.requests,
s,
(c) => c.path === a && c.method === r
), l = m(O, {
...e,
path: e.path.slice(3)
});
if (!o || !l)
return !1;
const f = [...M(o, l.pathMinusOne)];
e.type === "CREATE" ? f.push(l.value) : e.type === "REMOVE" && f.pop(), u.edit(o.uid, l.pathMinusOne, f), (e.path[3] === "parameters" || e.path[3] === "requestBody") && _(o.uid, t);
} else if (e.type === "CREATE") {
const [o] = Object.entries(e.value ?? {}), [l, f] = o ?? [], c = r ? e.value : f, d = r || l, T = R.array().parse(c.servers ?? []), { security: g, ...z } = c, V = {
...z,
method: N(d) ? d : "get",
path: a,
parameters: c.parameters ?? [],
servers: T.map((y) => y.uid)
};
g?.length && (V.security = g.map((y) => {
if (Object.keys(y).length) {
const [Z] = Object.keys(y);
return Z ? {
[Z]: y[Z]
} : y;
}
return y;
}));
const q = v(V, O, !1);
if (!q)
return !1;
u.add(q, n.value.uid);
} else if (e.type === "REMOVE") {
const o = E(
n.value.requests,
s,
(l) => l.path === a && l.method === r
);
if (!o)
return !1;
u.delete(o, n.value.uid);
} else if (e.type === "CHANGE") {
const o = E(
n.value.requests,
s,
(f) => f.path === a && f.method === r
), l = m(O, { ...e, path: i });
if (!o || !l)
return !1;
u.edit(o.uid, l.path, l.value), (e.path[3] === "parameters" || e.path[3] === "requestBody") && _(o.uid, t);
}
return !0;
}, W = (e, { activeCollection: n }, { servers: t, serverMutators: s }) => {
if (!n.value)
return !1;
const [, u, ...a] = e.path;
if (a?.length) {
const r = n.value.servers[u];
if (!r)
return !1;
const i = t[r], o = m(R, { ...e, path: a });
if (!i || !o)
return !1;
const f = e.type === "REMOVE" && a[a.length - 1] === "variables" ? {} : o.value;
s.edit(r, o.path, f);
} else if (e.type === "REMOVE") {
if (!n.value.servers[u])
return !1;
s.delete(n.value.servers[u], n.value.uid);
} else if (e.type === "CREATE") {
const r = v(e.value, R, !1);
if (!r)
return !1;
s.add(r, n.value.uid);
}
return !0;
}, I = (e, { activeCollection: n }, { tags: t, tagMutators: s }) => {
if (!n.value)
return !1;
const [, u, ...a] = e.path;
if (a?.length) {
const r = n.value.tags[u];
if (!r)
return !1;
const i = t[r], o = m(b, { ...e, path: a });
if (!i || !o)
return !1;
s.edit(r, o.path, o.value);
} else if (e.type === "REMOVE") {
const r = n.value.tags[u];
if (!r)
return !1;
const i = t[r];
if (!i)
return !1;
s.delete(i, n.value.uid);
} else if (e.type === "CREATE") {
const r = v(e.value, b, !1);
if (!r)
return !1;
s.add(r, n.value.uid);
}
return !0;
}, j = (e, n, t) => {
const s = h(e);
if (s instanceof p.ZodUnion || s instanceof p.ZodDiscriminatedUnion)
for (const u of s.options) {
if (!(u instanceof p.ZodType))
continue;
const a = h(u);
if (a instanceof p.ZodObject && n in a.shape) {
const r = h(a.shape[n]);
if (r instanceof p.ZodLiteral && r.value === t || r instanceof p.ZodDefault && r._zod.def.innerType instanceof p.ZodLiteral && r._zod.def.innerType.value === t || r instanceof p.ZodOptional && r._zod.def.innerType instanceof p.ZodLiteral && r._zod.def.innerType.value === t || r instanceof p.ZodDefault && r._zod.def.innerType instanceof p.ZodOptional && r._zod.def.innerType._zod.def.innerType instanceof p.ZodLiteral && r._zod.def.innerType._zod.def.innerType.value === t)
return a;
}
}
return null;
}, J = (e, { activeCollection: n }, { securitySchemes: t, securitySchemeMutators: s }) => {
if (!n.value)
return !1;
const [, , u, ...a] = e.path, r = t[u] ?? E(
n.value.securitySchemes,
t,
(i) => i.nameKey === u
);
if (a?.length) {
const i = j(S, "type", r?.type ?? "");
if (!i || !r)
return !1;
const o = m(i, { ...e, path: a });
if (!o)
return !1;
const l = o.path;
s.edit(r.uid, l, o.value);
} else if (e.type === "REMOVE") {
if (!r)
return !1;
s.delete(r.uid);
} else e.type === "CREATE" && s.add(S.parse(e.value), n.value.uid);
return !0;
};
export {
x as combineRenameDiffs,
E as findResource,
F as mutateCollectionDiff,
K as mutateRequestDiff,
J as mutateSecuritySchemeDiff,
W as mutateServerDiff,
I as mutateTagDiff,
j as narrowUnionSchema,
m as parseDiff,
H as traverseZodSchema
};