graphql-gene
Version:
Generates automatically an executable schema out of your ORM models
320 lines (315 loc) • 10 kB
JavaScript
import { isScalarType as b, extendSchema as w, parse as O, buildSchema as M, GraphQLObjectType as E, GraphQLSchema as q, parseType as Q } from "graphql";
import { parseSchemaOption as G, getFieldDefinition as H, lookDeepInSchema as N, printSchemaWithDirectives as z, isArrayFieldConfig as $, isObjectFieldConfig as I, getGloballyExtendedTypes as x, isUsingDefaultResolver as T, normalizeFieldConfig as j, getReturnTypeName as S, getGeneConfigFromOptions as m, getDefaultTypeDefLinesObject as R, isObject as J, getDefaultFieldLinesObject as P, isListType as U, parseGetterConfig as F, setGeneConfigByType as _, isFieldIncluded as B, getGraphqlType as V } from "./utils/index.js";
import { addResolversToSchema as W } from "./resolvers.js";
import { generateDefaultQueryFilterTypeDefs as k, populateArgsDefForDefaultResolver as X } from "./defaultResolver.js";
const Y = `<!doctype html>
<html lang="en" class="hljs">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>GraphQL Schema</title>
<link rel="stylesheet" href="https://unpkg.com/initialize-css@1.2.0/dist/initialize.min.css" />
<link
rel="stylesheet"
href="https://unpkg.com/@highlightjs/cdn-assets@11.9.0/styles/atom-one-dark-reasonable.css"
/>
</head>
<body>
<pre><code class="language-graphql lineHeightNormal"><%= code %></code></pre>
<script src="https://unpkg.com/@highlightjs/cdn-assets@11.9.0/highlight.min.js"><\/script>
<script>
hljs.highlightAll()
<\/script>
</body>
</html>
`;
function ae(e) {
const r = e.resolvers ? Object.values(e.resolvers).filter((o) => b(o)).map(({ name: o }) => o) : [], t = G(e.schema, r), { typeDefsString: s, typeDefLines: n } = Z({
...e,
schema: t
}), i = t ? w(t, O(s)) : M(s), f = i.getType("Query"), l = i.getType("Mutation");
if (!f)
throw new Error("Query root type must be provided.");
if (!(f instanceof E))
throw new Error("Query type is not a GraphQLObjectType.");
const g = {
query: f
}, a = i.getTypeMap();
if (l) {
if (!(l instanceof E))
throw new Error("Mutation type is not a GraphQLObjectType.");
g.mutation = l;
}
e.resolvers && Object.entries(e.resolvers).forEach(([o, y]) => {
if (b(y)) {
Object.assign(a[o], y);
return;
}
Object.entries(y).forEach(([p, h]) => {
const u = H({ schema: i, parent: o, field: p });
if (u) u.resolve = h;
else throw new Error(`No field definition found for "${p}" of type "${o}.`);
});
});
let c = new q({
...i.toConfig(),
...g,
types: Object.values(a)
});
return c = W({
typeDefLines: n,
schema: c,
plugins: e.plugins || [],
types: e.types
}), {
schema: c,
get schemaString() {
return z(c);
},
get typeDefs() {
return O(this.schemaString);
},
get resolvers() {
const o = {};
return N({
schema: c,
each({ field: y, fieldDef: p, parentType: h }) {
p.resolve && (o[h] = o[h] || {}, o[h][y] = p.resolve);
}
}), o;
},
get schemaHtml() {
return Y.replace("<%= code %>", this.schemaString);
}
};
}
function Z(e) {
const r = {}, t = {}, s = [];
Object.entries(e.types).forEach(([g, a]) => {
let c = !1;
for (const o of e.plugins || []) {
if (!o.isMatching(a)) continue;
const { afterTypeDefHooks: p } = K({
directiveDefs: r,
typeDefLines: t,
types: e.types,
schema: e.schema,
resolvers: e.resolvers,
plugin: o,
modelKey: g,
model: a,
dataTypeMap: e.dataTypeMap
});
s.push(...p), ee({
typeDefLines: t,
modelKey: g,
model: a
}), c = !0;
break;
}
!c && ($(a) || I(a)) && D({
directiveDefs: r,
typeDefLines: t,
graphqlType: g,
fieldConfigs: a
});
});
const n = x();
Object.entries(n.config).forEach(([g, a]) => {
D({
directiveDefs: r,
typeDefLines: t,
graphqlType: g,
fieldConfigs: a
}), Object.entries(a).forEach(([c, o]) => {
const y = j(o);
T(y) && k({
typeDefLines: t,
graphqlType: g,
fieldKey: c,
fieldType: S(y.returnType)
});
});
}), s.forEach((g) => g());
const i = [];
let f = t;
if ("Query" in t) {
const { Query: g, ...a } = t;
f = { Query: g, ...a };
}
Object.entries(f).forEach(([g, a]) => {
const c = re(g, a);
c && i.push(c);
});
let l = i.join(`
`);
return Object.entries(r).forEach(([g, a]) => {
let c = `directive @${g}`;
const y = Object.entries(a.argsDef).filter(([, h]) => [...h].some((u) => u !== null)), p = (h) => {
const u = [...h];
return [
u.filter((d) => d !== null),
h.has(null) || u.some((d) => /^\[/.test(String(d))) ? "" : "!"
].join("");
};
y.length && (c += `(
`, c += y.map(([h, u]) => ` ${h}: ${p(u)}`).join(`
`), c += `
)`), c += " on OBJECT | FIELD_DEFINITION", l = `${c}
${l}`;
}), { typeDefsString: l, typeDefLines: t };
}
function K(e) {
const r = [], { afterTypeDefHooks: t } = L(e);
r.push(...t), C(e);
const s = m(e);
return Object.entries(s?.aliases || {}).forEach(([n, i]) => {
const { afterTypeDefHooks: f } = L({
...e,
geneConfig: i,
modelKey: n
});
r.push(...f), C({ ...e, geneConfig: i });
}), { afterTypeDefHooks: r };
}
function ee(e) {
v(e);
const r = m(e);
r?.types && Object.entries(r?.aliases || {}).forEach(([, t]) => {
v({ ...e, geneConfig: t });
});
}
function L(e) {
const r = m(e), t = [];
_(e.modelKey, r);
const s = {
typeDefLines: e.typeDefLines,
model: e.model,
typeName: e.modelKey,
isFieldIncluded: (n) => B(r, n),
schemaOptions: e
};
if (e.plugin.populateTypeDefs) {
const { afterTypeDefHooks: n } = e.plugin.populateTypeDefs(s);
t.push(...n);
} else {
const n = e.plugin.getTypeDef(s);
e.typeDefLines[e.modelKey] = n;
}
return A({
// @ts-expect-error Fix type issue raised by incompatible TSource
configs: F(r?.directives),
defs: e.directiveDefs,
each: ({ directiveDef: n }) => {
e.typeDefLines[e.modelKey].directives.add(n);
}
}), { afterTypeDefHooks: t };
}
function C(e) {
const r = m(e);
r?.types && Object.entries(r.types).forEach(([t, s]) => {
D({ ...e, graphqlType: t, fieldConfigs: s });
});
}
function D(e) {
let r = e.fieldConfigs;
if (e.typeDefLines[e.graphqlType] = {
...R(),
...e.typeDefLines[e.graphqlType]
}, J(r) && "geneConfig" in r && r.geneConfig?.varType) {
const t = r.geneConfig.varType;
if (e.typeDefLines[e.graphqlType].varType = t, t === "union") {
const s = {};
Object.keys(r).filter((n) => n !== "geneConfig").forEach((n) => s[n] = ""), r = s;
}
}
if ($(e.fieldConfigs)) {
e.typeDefLines[e.graphqlType].varType = "enum";
const t = {};
e.fieldConfigs.forEach((s) => t[s] = ""), r = t;
} else {
const t = e.fieldConfigs.geneConfig;
t?.varType && (e.typeDefLines[e.graphqlType].varType = t.varType);
}
Object.entries(r).forEach(([t, s]) => {
if (t === "geneConfig") return;
const n = j(s);
e.typeDefLines[e.graphqlType].lines[t] = {
...P(),
...e.typeDefLines[e.graphqlType].lines[t]
};
const i = e.typeDefLines[e.graphqlType].lines[t];
n.returnType && (i.typeDef = n.returnType), T(n) ? X({
fieldLineConfig: i,
graphqlType: e.graphqlType,
fieldKey: t,
isList: U(Q(i.typeDef))
}) : n.args && Object.entries(n.args).forEach(([f, l]) => {
typeof l == "string" && (i.argsDef[f] = i.argsDef[f] || /* @__PURE__ */ new Set([]), i.argsDef[f].add(l));
}), n.directives && A({
configs: F(n.directives),
defs: e.directiveDefs,
each: ({ directiveDef: f }) => {
e.typeDefLines[e.graphqlType].lines[t].directives.add(f);
}
});
});
}
function v(e) {
const r = e.model, t = r ? m({ model: r, ...e }) : void 0;
t?.types && Object.entries(t.types).forEach(([s, n]) => {
Object.entries(n).forEach(([i, f]) => {
const l = j(f);
T(l) && k({
typeDefLines: e.typeDefLines,
graphqlType: s,
fieldKey: i,
fieldType: S(l.returnType)
});
});
});
}
function A(e) {
e.configs?.forEach((r) => {
e.defs[r.name] = e.defs[r.name] || { argsDef: {} }, r.args && Object.entries(r.args).forEach(([s, n]) => {
Array.isArray(n) && !n.length || (e.defs[r.name].argsDef = e.defs[r.name].argsDef || {}, e.defs[r.name].argsDef[s] = e.defs[r.name].argsDef[s] || /* @__PURE__ */ new Set([]), e.defs[r.name].argsDef[s].add(
n === null ? null : Array.isArray(n) && !n.length ? [] : V(n)
));
});
const t = te(r);
e.each({ directiveDef: t, directive: r });
});
}
function re(e, r) {
const t = (i) => i.size ? ` ${[...i].join(" ")}` : "", s = Object.entries(r.lines).map(([i, f]) => {
let l = "";
const g = Object.entries(f.argsDef);
g.length && (l += "(", l += g.map(([c, o]) => `${c}: ${[...o].join(" | ")}`).join(", "), l += ")");
let a = `${i}${l}`;
return f.typeDef && (a += `: ${f.typeDef}${t(f.directives)}`), a;
});
if (!s.length) return "";
const n = (i = " ", f = `
`) => s.map((l) => `${i}${l}`).join(f);
return r.varType === "union" ? `union ${e} = ${n("", " | ")}` : [
`${r.varType} ${e}${t(r.directives)} {`,
n(),
"}"
].join(`
`);
}
function te(e) {
let r = `@${e.name}`;
if (e.args) {
const t = Object.entries(e.args).filter(([, s]) => Array.isArray(s) ? !!s.length : s !== null);
t.length && (r += "(", r += t.map(([s, n]) => {
const i = Array.isArray(n) ? `[${n.filter((f) => f !== null).map((f) => JSON.stringify(f)).join(", ")}]` : JSON.stringify(n);
return `${s}: ${i}`;
}).join(", "), r += ")");
}
return r;
}
export {
ae as generateSchema
};
//# sourceMappingURL=schema.js.map