graphile / graphile/crystal

Customize codec for base64JSON throws runtime error

Open
#1,822 3 comments 0 reactions 0 assignees View on GitHub
📄 add-to-docs
Dominant language
TypeScript
Stars
12.9k
Forks
625
Avg merge
5h 23m
Merged PRs (30d)
24

Description

### Summary

The `id: ID!` values produced by the `NodePlugin` and the `NodeIdCodecBase64JSONPlugin` plugin are not URL-safe. This means, if I wanted to use these ID's as part of a URL, I'd have to do additional client-side logic to make them URL safe. I'd instead like to customize/override the codec to use a url-safe base64 encoding. I'm finding not able to do so successfully.

### Steps to reproduce

When creating a plugin like this:

```typescript
import "graphile-config";
import { NodePlugin } from "graphile-build";

function base64JSONEncode(value: any): string | null {
return Buffer.from(JSON.stringify(value), "utf8").toString("base64url");
}
base64JSONEncode.isSyncAndSafe = true; // Optimization
function base64JSONDecode(value: string): any {
return JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
}
base64JSONDecode.isSyncAndSafe = true; // Optimization

export const NodeIdCodecBase64URLJSONPlugin: GraphileConfig.Plugin = {
name: "NodeIdCodecBase64URLJSONPlugin",
version: "1.0.0",
description: `Adds a URL-safe 'base64JSON' codec for NodeIDs`,
after: [
NodePlugin.name,
],
schema: {
hooks: {
init(_, build) {
if (!build.registerNodeIdCodec) {
return _;
}
build.registerNodeIdCodec({
name: "base64JSON",
encode: base64JSONEncode,
decode: base64JSONDecode,
});
return _;
},
},
},
};
```

...configured with a `plugins` and `presets` configuration that ignores the stock codec:
```typescript
{
extends: [
PostGraphileAmberPreset,
PostGraphileRelayPreset,
],
plugins: [
NodeIdCodecBase64URLJSONPlugin,
],
disablePlugins: [
// disable existing plugins
NodeIdCodecBase64JSONPlugin.name,
],

}
```

### Expected results

I'd expect code that currently relies on this codec to work successfully.

### Actual results

I get a runtime error thrown from inside the `PgTableNodePlugin`:

```
Error occurred during watch schema generation: Error: Could not find Node ID codec 'base64JSON'
at Object.getNodeIdCodec (/workdir/node_modules/.pnpm/graphile-build@5.0.0-beta.9_grafast@0.0.1-beta.8_graphile-config@0.0.1-beta.3_graphql@16.8.1/node_modules/graphile-build/dist/plugins/NodePlugin.js:58:35)
at init (/workdir/node_modules/.pnpm/graphile-build-pg@5.0.0-beta.10_@dataplan+pg@0.0.1-beta.8_grafast@0.0.1-beta.8_graphile-build_u4y5pffkmjvd272uyyrjurxzfq/node_modules/graphile-build-pg/dist/plugins/PgTableNodePlugin.js:100:38)
at SchemaBuilder.applyHooks (/workdir/node_modules/.pnpm/graphile-build@5.0.0-beta.9_grafast@0.0.1-beta.8_graphile-config@0.0.1-beta.3_graphql@16.8.1/node_modules/graphile-build/dist/SchemaBuilder.js:98:30)
at SchemaBuilder.createBuild (/workdir/node_modules/.pnpm/graphile-build@5.0.0-beta.9_grafast@0.0.1-beta.8_graphile-config@0.0.1-beta.3_graphql@16.8.1/node_modules/graphile-build/dist/SchemaBuilder.js:148:14)
at SchemaBuilder.buildSchema (/workdir/node_modules/.pnpm/graphile-build@5.0.0-beta.9_grafast@0.0.1-beta.8_graphile-config@0.0.1-beta.3_graphql@16.8.1/node_modules/graphile-build/dist/SchemaBuilder.js:157:28)
at buildSchema (/workdir/node_modules/.pnpm/graphile-build@5.0.0-beta.9_grafast@0.0.1-beta.8_graphile-config@0.0.1-beta.3_graphql@16.8.1/node_modules/graphile-build/dist/index.js:322:28)
at /workdir/node_modules/.pnpm/graphile-build@5.0.0-beta.9_grafast@0.0.1-beta.8_graphile-config@0.0.1-beta.3_graphql@16.8.1/node_modules/graphile-build/dist/index.js:467:56
at watch (/workdir/node_modules/.pnpm/graphile-build@5.0.0-beta.9_grafast@0.0.1-beta.8_graphile-config@0.0.1-beta.3_graphql@16.8.1/node_modules/graphile-build/dist/index.js:246:13)
```

### Possible Solution

I'd be equally happy to propose a change to the stock `NodeIdCodecBase64JSONPlugin` implementation to use the `base64url` buffer encoding as I'm doing above — but I'm unsure the extent to which this would be an undesirable or breaking change.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.