@akumzy/gri-prisma-select
Version:
Generate Prisma select object from GraphQL Resolve Info.
225 lines • 8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.toPrismaSelect = void 0;
const graphql_1 = require("graphql");
async function toPrismaSelect(info, options = {}) {
const parsed = info.fieldNodes.reduce((prev, cur) => {
if (cur.selectionSet) {
return [...prev, ...parseQueryFields(cur, info)];
}
return prev;
}, []);
const parsedSelection = parseSelections(parsed).select;
if (typeof parsedSelection === "boolean") {
return {};
}
return Object.values(parsedSelection)[0];
}
exports.toPrismaSelect = toPrismaSelect;
function parseQueryFields(field, info) {
const hasIncludeOrSkip = (field) => {
if (field.directives) {
const include = field.directives.find((a) => a.name.value === "include");
const skip = field.directives.find((a) => a.name.value === "skip");
return include || skip;
}
return false;
};
const ignoreField = (field) => {
if (field.directives && field.directives[0]) {
const directive = field.directives[0];
const name = directive.name.value;
const args = directive.arguments;
if (hasIncludeOrSkip(field)) {
if (args) {
const arg = args[0];
if (arg.value.kind === graphql_1.Kind.VARIABLE) {
const value = info.variableValues[arg.value.name.value];
if (name === "skip") {
if (value) {
return true;
}
}
else {
if (name === "include") {
if (!value) {
return true;
}
}
}
}
}
}
}
return false;
};
const parse = (field, prev = []) => {
switch (field.kind) {
case "Field": {
if (!ignoreField(field)) {
let fieldName = field.name.value;
if (fieldName === "__typename") {
return prev;
}
field.directives;
const w = getArgument(field, info);
prev.push({
field: fieldName,
selections: field.selectionSet
? field.selectionSet.selections.reduce((acc, node) => [...acc, ...parseQueryFields(node, info)], [])
: null,
...(w || {}),
});
}
break;
}
case "FragmentSpread":
{
if (!ignoreField(field)) {
const fragment = info.fragments[field.name.value];
const fields = fragment.selectionSet.selections.reduce((acc, node) => [...acc, ...parseQueryFields(node, info)], []);
prev.push(...fields);
}
}
break;
default:
break;
}
return prev;
};
const { selectionSet } = field;
if (!selectionSet) {
return parse(field);
}
const w = getArgument(field, info);
let selections = selectionSet.selections.reduce((prev, field) => {
return [...prev, ...parse(field)];
}, []);
return [{ selections, where: "where" in w ? w.where : w, field: field.name.value }];
}
function parseSelections(selections) {
const parsed = {
select: {},
where: {},
take: 0,
skip: 0,
};
selections.forEach((selection) => {
if (selection.selections) {
const parsedSelections = parseSelections(selection.selections);
parsed.select[selection.field] = parsedSelections;
}
else {
parsed.select[selection.field] = true;
}
if (Object.keys(selection.where || {}).length) {
parsed.select[selection.field] = parsed.select[selection.field] || {};
// @ts-ignore
parsed.select[selection.field].where = selection.where;
}
else {
delete parsed.where;
}
;
["take", "skip"].forEach((key) => {
switch (key) {
case "take":
case "skip":
if (selection[key]) {
parsed.select[selection.field] = parsed.select[selection.field] || {};
// @ts-ignore
parsed.select[selection.field][key] = +selection[key];
}
else {
delete parsed[key];
}
break;
default:
break;
}
});
});
return parsed;
}
function getArgument(field, info) {
var _a;
let w = {};
if ("arguments" in field) {
(_a = field.arguments) === null || _a === void 0 ? void 0 : _a.forEach((arg) => {
const name = arg.name.value;
switch (arg.value.kind) {
case graphql_1.Kind.OBJECT:
let v = parseArguments(arg.value.fields, info);
w[name] = getObjectValue(v);
break;
case graphql_1.Kind.VARIABLE:
const value = info.variableValues[arg.value.name.value];
if (value) {
w[name] = value;
}
break;
case graphql_1.Kind.ENUM:
w[name] = arg.value.value;
break;
case graphql_1.Kind.NULL:
w[name] = null;
break;
default:
// @ts-ignore
w[name] = arg.value.value;
break;
}
});
}
return w;
}
function parseArguments(fields, info) {
return fields.reduce((prev, cur) => {
if (cur.kind === graphql_1.Kind.OBJECT_FIELD) {
switch (cur.value.kind) {
case graphql_1.Kind.VARIABLE:
prev[cur.name.value] = info.variableValues[cur.value.name.value];
break;
case graphql_1.Kind.LIST:
prev[cur.name.value] = cur.value.values.map((v) => {
if (v.kind === graphql_1.Kind.OBJECT) {
return parseArguments(v.fields, info);
}
return v;
});
break;
case graphql_1.Kind.OBJECT:
prev[cur.name.value] = parseArguments(cur.value.fields, info);
break;
default:
prev[cur.name.value] = cur.value;
break;
}
}
else {
prev[cur.name.value] = cur.value;
}
return prev;
}, {});
}
// map through an object recursively and check if any of it's properties value is not an ObjectValueNode and if so, return the key with the name value
function getObjectValue(obj) {
let newObj = {};
if (typeof obj === "object") {
for (const [key, value] of Object.entries(obj)) {
if (typeof value === "object") {
if (value && "kind" in value) {
// @ts-ignore
newObj[key] = value.value;
}
else {
newObj[key] = getObjectValue(value);
}
}
else
newObj[key] = value;
}
}
return newObj;
}
//# sourceMappingURL=toPrismaSelect.js.map