postgraphile
Version:
Automatic, high performance, and highly customizable GraphQL API for PostgreSQL
145 lines • 6.74 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PostGraphileRelayPreset = exports.PgRelayPlugin = void 0;
require("../index.js");
const version_ts_1 = require("../version.js");
const RELAY_HIDDEN_COLUMN_BEHAVIORS = [
"-select",
"-update",
"-base",
"-filterBy",
"-orderBy",
];
/** @experimental */
exports.PgRelayPlugin = {
name: "PgRelayPlugin",
description: "[EXPERIMENTAL] Adds behaviors, inflectors, and other accomodations to better hone your schema for Relay usage",
version: version_ts_1.version,
after: ["PostGraphileV4CompatibilityPlugin"],
inflection: {
replace: {
nodeIdFieldName() {
return "id";
},
_attributeName(previous, options, details) {
const name = previous(details);
if (!details.skipRowId && name.toLowerCase() === "id")
return "row_id";
return name;
},
},
ignoreReplaceIfNotExists: ["attribute"],
},
schema: {
globalBehavior: [
"node",
"connection",
"-list",
"-query:resource:single",
"nodeId:filterBy",
"nodeId:resource:update",
"-constraint:resource:update",
"nodeId:resource:delete",
"-constraint:resource:delete",
"nodeId:insert",
"nodeId:update",
"nodeId:base",
],
entityBehavior: {
pgCodecAttribute: {
inferred(behavior, [codec, attributeName], build) {
const newBehavior = [behavior];
const attr = codec.attributes[attributeName];
const resource = codec.polymorphism?.mode === "union"
? Object.values(build.input.pgRegistry.pgResources).find((r) => {
if (r.parameters)
return false;
if (r.isVirtual)
return false;
if (r.isUnique)
return false;
if (r.uniques.length === 0)
return false;
const name = codec.extensions?.tags?.name ?? codec.name;
const impl = r.codec.extensions?.tags?.implements;
const implArr = impl
? Array.isArray(impl)
? impl
: [impl]
: [];
if (!implArr.includes(name))
return false;
return true;
})
: Object.values(build.input.pgRegistry.pgResources).find((r) => {
if (r.codec !== codec)
return false;
if (r.parameters)
return false;
if (r.isVirtual)
return false;
if (r.isUnique)
return false;
if (r.uniques.length === 0)
return false;
return true;
});
const pk = resource?.uniques.find((u) => u.isPrimary);
// If the column is a primary key, don't include it (since it will be in the NodeID instead)
if (pk?.attributes.includes(attributeName)) {
// Do not include this column in the schema (other than for create)
newBehavior.push(...RELAY_HIDDEN_COLUMN_BEHAVIORS);
}
else {
// If the column is available via a singular relation, don't include the column itself
const relationsMap = build.input.pgRegistry.pgRelations[codec.name];
const relations = relationsMap
? Object.values(build.input.pgRegistry.pgRelations[codec.name] ?? {})
: [];
const singularRelationsUsingThisColumn = relations.filter((r) => {
// NOTE: We do this even if the end table is not visible, because
// otherwise making the end table visible would be a breaking schema
// change. Users should make sure these columns are hidden from the
// schema if they are also hiding the target table.
if (!r.isUnique)
return false;
if (r.isReferencee)
return false;
if (!r.localAttributes.includes(attributeName))
return false;
return true;
});
if (singularRelationsUsingThisColumn.length > 0 &&
!attr.codec.extensions?.isEnumTableEnum) {
// Do not include this column in the schema (other than for create)
newBehavior.push(...RELAY_HIDDEN_COLUMN_BEHAVIORS);
}
}
const relations = Object.values(build.input.pgRegistry.pgRelations[codec.name] ?? {}).filter((r) => !r.isReferencee && r.isUnique);
const isPartOfRelation = !attr.codec.extensions?.isEnumTableEnum &&
relations.some((r) => r.localAttributes.includes(attributeName));
if (isPartOfRelation) {
// `nodeId:filterBy` handles this
newBehavior.push(`-attribute:filterBy`);
// `nodeId:insert` handles this
newBehavior.push(`-attribute:insert`);
// `nodeId:update` handles this
newBehavior.push(`-attribute:update`);
// `nodeId:base` handles this
newBehavior.push(`-attribute:base`);
}
return newBehavior;
},
},
},
},
};
/** @experimental */
exports.PostGraphileRelayPreset = {
plugins: [exports.PgRelayPlugin],
schema: {
pgMutationPayloadRelations: false,
pgFunctionsPreferNodeId: true,
},
};
//# sourceMappingURL=relay.js.map