-
-
Notifications
You must be signed in to change notification settings - Fork 601
Closed
Description
Summary
What would be the right way to cast/convert binary types like 'bytea' into hexadecimal instead of base64 strings?
I was trying this plugin based on official source code but
- If I try to register again a
Base64EncodedBinary
GQL type I get name collision errors - When I create a new
HexEncodedBinary
GQL type I cannot find a right way to map pg types like bytea to this one.
Also is there a way to properly detect all the types being converted to base64 to apply this conversion to all of them automatically?
import "graphile-config";
import { EXPORTABLE } from "graphile-build";
import {
TYPES,
} from "@dataplan/pg";
// would cause a collision with already registered Base64EncodedBinary
// const useEncoding='base64';
// const inflectionName='Base64EncodedBinary'
const useEncoding = 'hex';
const inflectionName = 'HexEncodedBinary'
export const BinaryCodecPlugin: GraphileConfig.Plugin = {
name: "BinaryCodecPlugin",
version: "0.0.1",
description: `Encodes/decodes binary types as '${useEncoding}' strings`,
after: [
"CommonTypesPlugin",
"PgBasicsPlugin"
],
schema: {
hooks: {
init: {
provides: ["pg-standard-types"],
callback: (_, build) => {
const doConnection = (name: string) => {
build.registerCursorConnection?.({
typeName: build.inflection.builtin(name),
// When dealing with scalars, nulls are allowed in setof
nonNullNode: false,
scope: {
isPgConnectionRelated: true,
},
});
};
build.registerScalarType(
build.inflection.builtin(inflectionName),
{},
() => ({
description: build.wrapDescription(
`Binary data encoded using ${useEncoding}`,
"type",
),
serialize: EXPORTABLE(
() =>
function serialize(data: unknown) {
if (Buffer.isBuffer(data)) {
//console.log(`[BinaryCodecPlugin] serialize:`,data.toString(useEncoding))
return data.toString(useEncoding);
} else {
throw new Error(
`${inflectionName} can only be used with Node.js buffers.`,
);
}
},
[],
),
parseValue: EXPORTABLE(
(GraphQLError) =>
function parseValue(data: unknown) {
if (typeof data === "string") {
return Buffer.from(data, useEncoding);
} else {
throw new GraphQLError(
`${inflectionName} can only parse string values.`,
);
}
},
[build.graphql.GraphQLError],
),
parseLiteral: EXPORTABLE(
(GraphQLError, Kind) =>
function parseLiteral(ast) {
if (ast.kind !== Kind.STRING) {
// TODO: add name to this error
throw new GraphQLError(
`${inflectionName} can only parse string values`,
);
}
return Buffer.from(ast.value, useEncoding);
},
[build.graphql.GraphQLError, build.graphql.Kind],
),
}),
`graphile-build-pg built-in (${inflectionName})`,
);
doConnection(inflectionName);
// tried this and other approaches but seems to do nothing, also feels hacky:
build.setGraphQLTypeForPgCodec(TYPES['bytea'],'bytea',inflectionName);
return _;
}
}
},
},
};
Additional context
"@graphile-contrib/pg-many-to-many": "^2.0.0-beta.9",
"@graphile/pg-aggregates": "^0.2.0-beta.8",
"@graphile/simplify-inflection": "^8.0.0-beta.7",
"graphile-config": "^0.0.1-beta.17",
"pg": "^8.16.3",
"postgraphile": "^5.0.0-beta.43",
"postgraphile-plugin-connection-filter": "^3.0.0-beta.8"
"ts-node": "^10.9.2",
"typescript": "^5.9.2"
Metadata
Metadata
Assignees
Labels
No labels