graphile-contrib / postgraphile-plugin-connection-filter

Filtering on PostGraphile connections
MIT License
286 stars 32 forks source link

Allow generated types to be prefixed to avoid conflicts with existing types #203

Closed Brookke closed 10 months ago

Brookke commented 11 months ago

Problem

We are looking at adopting this filter however we already have some types that have the same names e.g. UserFilters.

Proposal

Introducing an optional typePrefix option. This would prefix the generated types with the string provided, ensuring that they do not clash with other existing types

We have tested this works locally by changing the https://github.com/graphile-contrib/postgraphile-plugin-connection-filter/blob/master/src/ConnectionArgFilterPlugin.ts file to prefix the types and found it to work well.

If I were to open a PR that adds a typePrefix option to the plugin, would this be accepted?

Brookke commented 11 months ago

As noted by @benjie here

A custom plugin could be used to add a prefix:

In V4:

import { makeAddInflectorsPlugin } from "graphile-utils";

export const PrefixFilterPlugin = makeAddInflectorsPlugin(
  (inflectors, build, options) => {
    const {
      filterType: oldFilterType,
      filterFieldType: oldFilterFieldType,
      filterFieldListType: oldFilterFieldListType,
    } = inflectors;
    const { connectionFilterTypePrefix = "" } = options;
    return {
      filterType(typeName) {
        return connectionFilterTypePrefix + oldFilterType.call(this, typeName);
      },
      filterFieldType(typeName) {
        return (
          connectionFilterTypePrefix + oldFilterFieldType.call(this, typeName)
        );
      },
      filterFieldListType(typeName) {
        return (
          connectionFilterTypePrefix +
          oldFilterFieldListType.call(this, typeName)
        );
      },
    };
  },
  true,
);

And of course, It's Better In V5™️:

function prefix(prev, preset, typeName) {
  const { schema: { connectionFilterTypePrefix = "" } } = preset;
  return connectionFilterTypePrefix + prev(typeName);
}

export const PrefixFilterPlugin = {
  name: "PrefixFilterPlugin",
  inflection: {
    replace: {
      filterType: prefix,
      filterFieldType: prefix,
      filterFieldListType: prefix,
    },
  },
};

where connectionFilterTypePrefix is defined in your graphileBuildOptions