UNPKG

@graphile-contrib/pg-simplify-inflector

Version:

Simplifies the graphile-build-pg inflector to trim the `ByFooIdAndBarId` from relations

220 lines (173 loc) 7.13 kB
# @graphile-contrib/pg-simplify-inflector This plugin simplifies field names in the PostGraphile schema; e.g. `allUsers` becomes simply `users`, `User.postsByAuthorId` becomes simply `User.posts`, and `Post.userByAuthorId` becomes simply `Post.author`. **Adding this plugin to your schema is almost certainly a breaking change, so do it before you ship anything!** This is the primary reason this isn't enabled by default in PostGraphile. _This plugin is recommended for all PostGraphile users._ ## Customising This plugin is implemented as a single JS file that does not need to be compiled at all - you can simply copy it into your project and customise it as you see fit. Alternatively, you can [write your own inflection plugin](https://www.graphile.org/postgraphile/inflection/). ## Changes: Given these tables: ```sql create table companies ( id serial primary key, name text not null ); create table beverages ( id serial primary key, company_id int not null references companies, distributor_id int references companies, name text not null ); ``` - `Query.allCompanies` 👉 `Query.companies` (disable via `pgSimplifyAllRows = false`) - `Query.allBeverages` 👉 `Query.beverages` - `Beverage.companyByCompanyId` 👉 `Beverage.company` - `Beverage.companyByDistributorId` 👉 `Beverage.distributor` - `Company.beveragesByCompanyId` 👉 `Company.beverages` (because the `company_id` column follows the `[table_name]_id` naming convention) - All update mutations now accept `patch` instead of `companyPatch` / `beveragePatch` (disable via `pgSimplifyPatch = false`) - If you are using `pgSimpleCollections = "only"` then you can set `pgOmitListSuffix = true` to omit the `List` suffix - Fields where the singular and plural are the same and a distinct plural is required are force-pluralised ("fishes") to avoid conflicts (e.g. `singularize("fish") === pluralize("fish")`). Note: `Company.beveragesByDistributorId` will remain, because `distributor_id` does not follow the `[table_name]_id` naming convention, but you could rename this yourself with a smart comment: ```sql comment on constraint "beverages_distributor_id_fkey" on "beverages" is E'@foreignFieldName distributedBeverages'; ``` or with a custom inflector: ```js module.exports = makeAddInflectorsPlugin( { getOppositeBaseName(baseName) { return ( { // These are the default opposites parent: "child", child: "parent", author: "authored", editor: "edited", reviewer: "reviewed", // 👇 Add/customise this line: distributor: "distributed", }[baseName] || null ); }, }, true ); ``` ## Installation: ```bash yarn add @graphile-contrib/pg-simplify-inflector ``` or ```bash npm install --save @graphile-contrib/pg-simplify-inflector ``` ## Usage: CLI: ```bash postgraphile --append-plugins @graphile-contrib/pg-simplify-inflector ``` Library: ```js const PgSimplifyInflectorPlugin = require("@graphile-contrib/pg-simplify-inflector"); // ... app.use( postgraphile(process.env.AUTH_DATABASE_URL, "app_public", { appendPlugins: [PgSimplifyInflectorPlugin], // Optional customisation graphileBuildOptions: { /* * Uncomment if you want simple collections to lose the 'List' suffix * (and connections to gain a 'Connection' suffix). */ //pgOmitListSuffix: true, /* * Uncomment if you want 'userPatch' instead of 'patch' in update * mutations. */ //pgSimplifyPatch: false, /* * Uncomment if you want 'allUsers' instead of 'users' at root level. */ //pgSimplifyAllRows: false, /* * Uncomment if you want primary key queries and mutations to have * `ById` (or similar) suffix; and the `nodeId` queries/mutations * to lose their `ByNodeId` suffix. */ // pgShortPk: true, }, // ... other settings ... }) ); ``` ## Naming your foreign key fields By naming your foreign key along the lines of `author_id` or `author_fk`, e.g.: ```sql CREATE TABLE posts ( id serial primary key, author_id int not null references users, ... ); ``` We can automatically extract the field prefix: `author` and call the relation `author` rather than the default: `user`. This allows for a post to have an `author`, `editor`, `reviewer`, etc. all which point to `users`. The reverse, however, is not so easy. On the User type, we can't call the reverse of all these different relations `posts`. The default inflector refers to these as `postsByAuthorId`, `postsByEditorId`, etc. However we'd rather use shorter names, so we introduce a new inflector: `getOppositeBaseName`. This inflector is passed a baseName (the part without the `_id`/`_fk` suffix, e.g. `author`, `editor`, `reviewer` above) and should return the opposite of that base name which will be prepended to the target type to produce, e.g. `authoredPosts`, `editedPosts`, `reviewedPosts`. Failing this, we just fall back to the default (verbose) inflector; it will be up to you to add smart comments or a custom inflector to override these. ## Handling field conflicts: In most cases, the conflict errors will guide you on how to fix these issues using [smart comments](https://www.graphile.org/postgraphile/smart-comments/). ## Smart Tags ### `@foreignSimpleFieldName` `@foreignSimpleFieldName` was added to override the naming of the foreign-side of a one-to-many relationship's simple collections field (if you're using simple collections). By default we'll take the `@foreignFieldName` and add the "list suffix" ("List" by default, but "" if `pgOmitListSuffix` is set), but if you prefer you can override it entirely with `@foreignSimpleFieldName`. If you set `@foreignSimpleFieldName` and you're using `simpleCollections 'both'` then you should also set `@foreignFieldName` explicitly or unexpected things may occur. Applies to: - foreign key constraints ### `@listSuffix` `@listSuffix` allows you to override the default naming on a per-entity basis, overriding `pgOmitListSuffix`. For example, with `pgOmitListSuffix: true`, you can apply `@listSuffix include` to have the `-List` suffix appended to the simple collection generated for that table, and remove the `-Connection` suffix from the Relay connection. When `pgOmitListSuffix` is not `true`, you can use `@listSuffix omit` to selectively omit the `-List` suffix on simple collections and append `-Connection` to the Relay connection instead. If `@listSuffix` is set, the only valid values are `"omit"` and `"include"`. Any other value will cause an error. | | @listSuffix omit | @listSuffix include | | ----------------: | :------------------ | :------------------ | | Relay Connection | companiesConnection | companies | | Simple Collection | companies | companiesList | > NOTE: `@listSuffix` will have no effect when using `@foreignSimpleFieldName`. Applies to: - tables - foreign key constraints - computed column functions returning `SETOF <record type>`