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