graphile / crystal

🔮 Graphile's Crystal Monorepo; home to Grafast, PostGraphile, pg-introspection, pg-sql2 and much more!
https://graphile.org/
Other
12.58k stars 570 forks source link

Allow for re-set of a Type as long as we are in the init phase #2101

Closed gitrojones closed 3 months ago

gitrojones commented 3 months ago

Description

Currently it's possible to alias a custom scalar type with a primitive type (Int, String, etc..) in the init phase with build.setGraphQLTypeForPgCodec out of the box with an init hook. However, if you want to alias one scalar type over another it's not currently possible because those scalars don't exist until after PgCodecsPlugin runs and once set they cannot be re-set.

It seems reasonable that a hook set to run after PgCodecsPlugin but within the init phase should be able to re-set any of those automatically generated types.

Performance impact

Unknown

Security impact

Unknown

Checklist

changeset-bot[bot] commented 3 months ago

⚠️ No Changeset found

Latest commit: db3aab8dc26c57ada4b4832a7f75b9848e2ff4b3

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

benjie commented 3 months ago

This seems to already be possible by setting the type before PgCodecsPlugin executes.

const makeSetCodecTypePlugin = (
  databaseTypeName: string,
  inputGraphqlTypeName: string,
  outputGraphqlTypeName: string = inputGraphqlTypeName,
): GraphileConfig.Plugin => ({
  name: `SetCodecTypePlugin_${databaseTypeName}_${inputGraphqlTypeName}_${outputGraphqlTypeName}`,
  version: "0.0.0",

  schema: {
    hooks: {
      init: {
        before: ["PgCodecsPlugin"],
        callback(_, build) {
          for (const codec of build.allPgCodecs) {
            console.log(codec.extensions?.pg?.name, databaseTypeName);
            if (codec.extensions?.pg?.name === databaseTypeName) {
              build.setGraphQLTypeForPgCodec(
                codec,
                "input",
                inputGraphqlTypeName,
              );
              build.setGraphQLTypeForPgCodec(
                codec,
                "output",
                outputGraphqlTypeName,
              );
            }
          }
          return _;
        },
      },
    },
  },
});

However, if you want to alias one scalar type over another it's not currently possible because those scalars don't exist until after PgCodecsPlugin runs

You only reference them by name, so this shouldn't matter. That's one of the major reasons that the new system works the way it does: all of the potential types are registered up front, but none are actually created until later.

If this doesn't address your need, please create a reproduction of your issue. I'm not keen to encourage overwriting of things like codecs or GraphQL types; overwriting things makes debugging hard.