UNPKG

postgraphile

Version:

Automatic, high performance, and highly customizable GraphQL API for PostgreSQL

145 lines 6.74 kB
"use strict"; 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