UNPKG

graphile-settings

Version:
122 lines (121 loc) 4.92 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ManyToManyOptInPreset = exports.ManyToManyOptInPlugin = void 0; const pg_many_to_many_1 = require("@graphile-contrib/pg-many-to-many"); /** * Many-to-Many Preset with OPT-IN behavior (disabled by default). * * WHY THIS EXISTS: * The default @graphile-contrib/pg-many-to-many plugin adds many-to-many connection * fields to EVERY junction table automatically. This can bloat the API with fields * that may never be used. * * OUR FIX: * We override the default behavior to be OPT-IN instead of OPT-OUT: * - By default, NO many-to-many fields are generated * - To enable for a specific junction table, use: @behavior +manyToMany * * USAGE: * To enable many-to-many for a specific junction table, add a smart comment: * * ```sql * -- Enable many-to-many through this junction table * COMMENT ON TABLE post_tags IS E'@behavior +manyToMany'; * * -- Or enable on a specific constraint * COMMENT ON CONSTRAINT post_tags_tag_id_fkey ON post_tags IS E'@behavior +manyToMany'; * ``` * * SOURCE CODE REFERENCE: * The many-to-many plugin uses the behavior system to control field generation: * https://github.com/graphile-contrib/pg-many-to-many/blob/v2.0.0-rc.1/src/PgManyToManyRelationPlugin.ts#L478-L503 * * The plugin defines these behaviors: * - `manyToMany` - Controls whether many-to-many fields are generated * - `connection` - Controls whether connection fields are generated * - `list` - Controls whether list fields are generated * * By default, the plugin's entityBehavior for pgManyToMany includes: * `["manyToMany", "connection", "list", behavior]` * * We override this to be `-manyToMany` by default, requiring explicit opt-in. */ /** * Plugin that makes many-to-many fields opt-in by default. * * This overrides the default behavior from @graphile-contrib/pg-many-to-many * to require explicit `@behavior +manyToMany` smart tags. * * NOTE ON TYPE REGISTRATION: * The upstream plugin's init hook registers GraphQL types (edge/connection) * for ALL discovered relationships unconditionally — before behavior filtering. * Our pgManyToMany behavior only gates field creation, not type registration. * If two junction tables produce the same inflected type name, the duplicate * registration will crash graphile-build. The build hook below wraps * registerObjectType to catch such collisions and skip the duplicate, * preventing the crash without modifying the upstream plugin. */ exports.ManyToManyOptInPlugin = { name: 'ManyToManyOptInPlugin', version: '1.0.0', description: 'Makes many-to-many fields opt-in by default (disabled unless explicitly enabled)', schema: { entityBehavior: { pgManyToMany: { // Override the default behavior to be opt-out (disabled by default) // The 'inferred' phase runs before 'override', so we use 'inferred' // to set the default before any smart tags are processed. inferred: { provides: ['manyToManyOptIn'], before: ['default'], callback(behavior) { // Default to disabled - require explicit @behavior +manyToMany return ['-manyToMany', behavior]; }, }, }, }, hooks: { build(build) { const originalRegister = build.registerObjectType; build.registerObjectType = function (...args) { try { return originalRegister.apply(this, args); } catch (e) { const origin = args[3]; if (e.message?.includes('type naming conflict') && typeof origin === 'string' && origin.includes('many-to-many')) { // Silently skip duplicate many-to-many type registration. // The first registration wins; the duplicate is harmless // because the inflector already produced a unique field name. return; } throw e; } }; return build; }, }, }, }; /** * Preset that includes the many-to-many plugin with opt-in behavior. * * Use this in your main preset's `extends` array: * ```typescript * const preset: GraphileConfig.Preset = { * extends: [ * MinimalPreset, * ManyToManyOptInPreset, * // ... other presets * ], * }; * ``` */ exports.ManyToManyOptInPreset = { extends: [pg_many_to_many_1.PgManyToManyPreset], plugins: [exports.ManyToManyOptInPlugin], }; exports.default = exports.ManyToManyOptInPreset;