UNPKG

graphql-gene

Version:

Generates automatically an executable schema out of your ORM models

320 lines (315 loc) 9.98 kB
import { isScalarType as b, extendSchema as A, parse as O, buildSchema as w, GraphQLObjectType as E, GraphQLSchema as M, parseType as q } from "graphql"; import { parseSchemaOption as Q, getFieldDefinition as H, lookDeepInSchema as G, printSchemaWithDirectives as N, isArrayFieldConfig as $, isObjectFieldConfig as z, getGloballyExtendedTypes as I, isUsingDefaultResolver as T, normalizeFieldConfig as j, getReturnTypeName as S, getGeneConfigFromOptions as m, getDefaultTypeDefLinesObject as x, isObject as R, getDefaultFieldLinesObject as J, isListType as P, setGeneConfigByType as U, isFieldIncluded as _, getGraphqlType as B } from "./utils/index.js"; import { addResolversToSchema as V } from "./resolvers.js"; import { generateDefaultQueryFilterTypeDefs as F, populateArgsDefForDefaultResolver as W } from "./defaultResolver.js"; const X = `<!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 fe(e) { const r = e.resolvers ? Object.values(e.resolvers).filter((o) => b(o)).map(({ name: o }) => o) : [], n = Q(e.schema, r), { typeDefsString: s, typeDefLines: t } = Y({ ...e, schema: n }), i = n ? A(n, O(s)) : w(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 M({ ...i.toConfig(), ...g, types: Object.values(a) }); return c = V({ typeDefLines: t, schema: c, plugins: e.plugins || [], types: e.types }), { schema: c, get schemaString() { return N(c); }, get typeDefs() { return O(this.schemaString); }, get resolvers() { const o = {}; return G({ schema: c, each({ field: y, fieldDef: p, parentType: h }) { p.resolve && (o[h] = o[h] || {}, o[h][y] = p.resolve); } }), o; }, get schemaHtml() { return X.replace("<%= code %>", this.schemaString); } }; } function Y(e) { const r = {}, n = {}, 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 } = Z({ directiveDefs: r, typeDefLines: n, types: e.types, schema: e.schema, resolvers: e.resolvers, plugin: o, modelKey: g, model: a, dataTypeMap: e.dataTypeMap }); s.push(...p), K({ typeDefLines: n, modelKey: g, model: a }), c = !0; break; } !c && ($(a) || z(a)) && D({ directiveDefs: r, typeDefLines: n, graphqlType: g, fieldConfigs: a }); }); const t = I(); Object.entries(t.config).forEach(([g, a]) => { D({ directiveDefs: r, typeDefLines: n, graphqlType: g, fieldConfigs: a }), Object.entries(a).forEach(([c, o]) => { const y = j(o); T(y) && F({ typeDefLines: n, graphqlType: g, fieldKey: c, fieldType: S(y.returnType) }); }); }), s.forEach((g) => g()); const i = []; let f = n; if ("Query" in n) { const { Query: g, ...a } = n; f = { Query: g, ...a }; } Object.entries(f).forEach(([g, a]) => { const c = ee(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: n }; } function Z(e) { const r = [], { afterTypeDefHooks: n } = L(e); r.push(...n), v(e); const s = m(e); return Object.entries(s?.aliases || {}).forEach(([t, i]) => { const { afterTypeDefHooks: f } = L({ ...e, geneConfig: i, modelKey: t }); r.push(...f), v({ ...e, geneConfig: i }); }), { afterTypeDefHooks: r }; } function K(e) { C(e); const r = m(e); r?.types && Object.entries(r?.aliases || {}).forEach(([, n]) => { C({ ...e, geneConfig: n }); }); } function L(e) { const r = m(e), n = []; U(e.modelKey, r); const s = { typeDefLines: e.typeDefLines, model: e.model, typeName: e.modelKey, isFieldIncluded: (t) => _(r, t), schemaOptions: e }; if (e.plugin.populateTypeDefs) { const { afterTypeDefHooks: t } = e.plugin.populateTypeDefs(s); n.push(...t); } else { const t = e.plugin.getTypeDef(s); e.typeDefLines[e.modelKey] = t; } return k({ // @ts-expect-error Fix type issue raised by incompatible TSource configs: r?.directives, defs: e.directiveDefs, each: ({ directiveDef: t }) => { e.typeDefLines[e.modelKey].directives.add(t); } }), { afterTypeDefHooks: n }; } function v(e) { const r = m(e); r?.types && Object.entries(r.types).forEach(([n, s]) => { D({ ...e, graphqlType: n, fieldConfigs: s }); }); } function D(e) { let r = e.fieldConfigs; if (e.typeDefLines[e.graphqlType] = { ...x(), ...e.typeDefLines[e.graphqlType] }, R(r) && "geneConfig" in r && r.geneConfig?.varType) { const n = r.geneConfig.varType; if (e.typeDefLines[e.graphqlType].varType = n, n === "union") { const s = {}; Object.keys(r).filter((t) => t !== "geneConfig").forEach((t) => s[t] = ""), r = s; } } if ($(e.fieldConfigs)) { e.typeDefLines[e.graphqlType].varType = "enum"; const n = {}; e.fieldConfigs.forEach((s) => n[s] = ""), r = n; } else { const n = e.fieldConfigs.geneConfig; n?.varType && (e.typeDefLines[e.graphqlType].varType = n.varType); } Object.entries(r).forEach(([n, s]) => { if (n === "geneConfig") return; const t = j(s); e.typeDefLines[e.graphqlType].lines[n] = { ...J(), ...e.typeDefLines[e.graphqlType].lines[n] }; const i = e.typeDefLines[e.graphqlType].lines[n]; t.returnType && (i.typeDef = t.returnType), T(t) ? W({ fieldLineConfig: i, graphqlType: e.graphqlType, fieldKey: n, isList: P(q(i.typeDef)) }) : t.args && Object.entries(t.args).forEach(([f, l]) => { typeof l == "string" && (i.argsDef[f] = i.argsDef[f] || /* @__PURE__ */ new Set([]), i.argsDef[f].add(l)); }), t.directives && k({ configs: t.directives, defs: e.directiveDefs, each: ({ directiveDef: f }) => { e.typeDefLines[e.graphqlType].lines[n].directives.add(f); } }); }); } function C(e) { const r = e.model, n = r ? m({ model: r, ...e }) : void 0; n?.types && Object.entries(n.types).forEach(([s, t]) => { Object.entries(t).forEach(([i, f]) => { const l = j(f); T(l) && F({ typeDefLines: e.typeDefLines, graphqlType: s, fieldKey: i, fieldType: S(l.returnType) }); }); }); } function k(e) { e.configs?.forEach((r) => { e.defs[r.name] = e.defs[r.name] || { argsDef: {} }, r.args && Object.entries(r.args).forEach(([s, t]) => { Array.isArray(t) && !t.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( t === null ? null : Array.isArray(t) && !t.length ? [] : B(t) )); }); const n = re(r); e.each({ directiveDef: n, directive: r }); }); } function ee(e, r) { const n = (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}${n(f.directives)}`), a; }); if (!s.length) return ""; const t = (i = " ", f = ` `) => s.map((l) => `${i}${l}`).join(f); return r.varType === "union" ? `union ${e} = ${t("", " | ")}` : [ `${r.varType} ${e}${n(r.directives)} {`, t(), "}" ].join(` `); } function re(e) { let r = `@${e.name}`; if (e.args) { const n = Object.entries(e.args).filter(([, s]) => Array.isArray(s) ? !!s.length : s !== null); n.length && (r += "(", r += n.map(([s, t]) => { const i = Array.isArray(t) ? `[${t.filter((f) => f !== null).map((f) => JSON.stringify(f)).join(", ")}]` : JSON.stringify(t); return `${s}: ${i}`; }).join(", "), r += ")"); } return r; } export { fe as generateSchema }; //# sourceMappingURL=schema.js.map