Created
March 15, 2023 23:47
-
-
Save tshddx/7ba7730c4cfa599a214e5145e687a9e3 to your computer and use it in GitHub Desktop.
PostGraphile plugin to disable all filtering and sorting by default, and require you to opt in to each table and column you want to filter or sort.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Plugin } from 'postgraphile'; | |
import type { PgClass, PgAttribute } from 'graphile-build-pg'; | |
// | |
// This plugin disables all filtering and sorting by default, and requires you | |
// to opt in to each table and column you want to filter or sort. | |
// | |
// PostGraphile's default behavior is: | |
// - Every GraphQL type and connection has `condition` and `orderBy` args. | |
// - All columns are filterable and sortable. | |
// - To disable filtering or sorting on a table or column, you need to use the | |
// @omit smart tag. | |
// | |
// The behavior with this plugin is: | |
// - There are no `condition` or `orderBy` args by default. | |
// - To enable filtering or sorting for a certain table, you must add the | |
// @filterable or @sortable smart tag to the table. | |
// - You must also add the @filterable or @sortable smart tag to EACH column | |
// you want to be filterable or sortable. | |
// - Note that you must add the @filterable smart tag to a table in order to | |
// add custom filters to that table (e.g. our | |
// ValidationConsensusStatusFilter.ts plugin) | |
// | |
export const DisableFilteringAndSortingByDefaultPlugin: Plugin = (builder) => { | |
builder.hook('build', (build) => { | |
const { pgIntrospectionResultsByKind } = build; | |
const tables: PgClass[] = pgIntrospectionResultsByKind.class; | |
tables | |
.filter((table) => table.isSelectable && table.namespace) | |
.forEach((table) => { | |
// | |
// Omit filtering from every table and column that does not have @filterable | |
// | |
if (table.tags.filterable === true) { | |
let attributes: PgAttribute[] = | |
pgIntrospectionResultsByKind.attribute; | |
attributes = attributes.filter( | |
(attribute) => attribute.class.id === table.id | |
); | |
attributes.forEach((attribute) => { | |
if (attribute.tags.filterable !== true) { | |
omit('filter', attribute.tags); | |
} | |
}); | |
} else { | |
// @omit filtering from the table. | |
omit('filter', table.tags); | |
} | |
// | |
// Omit sorting from every table and column that does not have @sortable | |
// | |
if (table.tags.sortable === true) { | |
let attributes: PgAttribute[] = | |
pgIntrospectionResultsByKind.attribute; | |
attributes = attributes.filter( | |
(attribute) => attribute.class.id === table.id | |
); | |
attributes.forEach((attribute) => { | |
if (attribute.tags.sortable !== true) { | |
omit('order', attribute.tags); | |
} | |
}); | |
} else { | |
// @omit sorting from the table. | |
omit('order', table.tags); | |
} | |
}); | |
return build; | |
}); | |
}; | |
function omit(valueToOmit: string, tags: { omit?: string | boolean }) { | |
if (typeof tags.omit === 'boolean') { | |
if (!tags.omit) { | |
tags.omit = valueToOmit; | |
} | |
} else if (typeof tags.omit === 'string') { | |
if ( | |
tags.omit !== 'all' && | |
!tags.omit.split(',').some((o) => o === valueToOmit) | |
) { | |
tags.omit += `,${valueToOmit}`; | |
} | |
} else { | |
tags.omit = valueToOmit; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment