graphile-build-pg
Version:
Build a GraphQL schema by reflection over a PostgreSQL schema. Easy to customize since it's built with plugins on graphile-build
103 lines (102 loc) • 3.67 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getComputedColumnDetails = exports.default = void 0;
const getComputedColumnDetails = (build, table, proc) => {
if (!proc.isStable) return null;
if (proc.namespaceId !== table.namespaceId) return null;
if (!proc.name.startsWith(`${table.name}_`)) return null;
if (proc.argTypeIds.length < 1) return null;
if (proc.argTypeIds[0] !== table.type.id) return null;
const argTypes = proc.argTypeIds.reduce((prev, typeId, idx) => {
if (proc.argModes.length === 0 ||
// all args are `in`
proc.argModes[idx] === "i" ||
// this arg is `in`
proc.argModes[idx] === "b" // this arg is `inout`
) {
prev.push(build.pgIntrospectionResultsByKind.typeById[typeId]);
}
return prev;
}, []);
if (argTypes.slice(1).some(type => type.type === "c" && type.class && type.class.isSelectable)) {
// Accepts two input tables? Skip.
return null;
}
const pseudoColumnName = proc.name.slice(table.name.length + 1);
return {
argTypes,
pseudoColumnName
};
};
exports.getComputedColumnDetails = getComputedColumnDetails;
var PgComputedColumnsPlugin = function PgComputedColumnsPlugin(builder, {
pgSimpleCollections
}) {
builder.hook("GraphQLObjectType:fields", (fields, build, context) => {
const {
scope: {
isPgRowType,
isPgCompoundType,
isInputType,
pgIntrospection: table
},
fieldWithHooks,
Self
} = context;
if (isInputType || !(isPgRowType || isPgCompoundType) || !table || table.kind !== "class" || !table.namespace) {
return fields;
}
const {
extend,
pgIntrospectionResultsByKind: introspectionResultsByKind,
inflection,
pgOmit: omit,
pgMakeProcField: makeProcField,
swallowError,
describePgEntity,
sqlCommentByAddingTags
} = build;
const tableType = table.type;
if (!tableType) {
throw new Error("Could not determine the type for this table");
}
return extend(fields, introspectionResultsByKind.procedure.reduce((memo, proc) => {
if (omit(proc, "execute")) return memo;
const computedColumnDetails = getComputedColumnDetails(build, table, proc);
if (!computedColumnDetails) return memo;
const {
pseudoColumnName
} = computedColumnDetails;
function makeField(forceList) {
const fieldName = forceList ? inflection.computedColumnList(pseudoColumnName, proc, table) : inflection.computedColumn(pseudoColumnName, proc, table);
try {
memo = extend(memo, {
[fieldName]: makeProcField(fieldName, proc, build, {
fieldWithHooks,
computed: true,
forceList
})
}, `Adding computed column for ${describePgEntity(proc)}. You can rename this field with a 'Smart Comment':\n\n ${sqlCommentByAddingTags(proc, {
fieldName: "newNameHere"
})}`);
} catch (e) {
swallowError(e);
}
}
const simpleCollections = proc.tags.simpleCollections || pgSimpleCollections;
const hasConnections = simpleCollections !== "only";
const hasSimpleCollections = simpleCollections === "only" || simpleCollections === "both";
if (!proc.returnsSet || hasConnections) {
makeField(false);
}
if (proc.returnsSet && hasSimpleCollections) {
makeField(true);
}
return memo;
}, {}), `Adding computed column to '${Self.name}'`);
}, ["PgComputedColumns"]);
};
exports.default = PgComputedColumnsPlugin;
//# sourceMappingURL=PgComputedColumnsPlugin.js.map