Skip to content

Commit

Permalink
Merge pull request hayes#806 from hayes/tgriesser/bug/parseIdType
Browse files Browse the repository at this point in the history
Tgriesser/bug/parse id type
  • Loading branch information
hayes authored Feb 23, 2023
2 parents 592ffd3 + d2b02b7 commit 9bbbefa
Show file tree
Hide file tree
Showing 13 changed files with 135 additions and 24 deletions.
6 changes: 6 additions & 0 deletions .changeset/eight-ligers-develop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@pothos/plugin-relay': patch
'@pothos/deno': patch
---

Fix a few issues with globalID parsing
4 changes: 2 additions & 2 deletions packages/deno/packages/plugin-relay/field-builder.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions packages/deno/packages/plugin-relay/index.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions packages/deno/packages/plugin-relay/input-field-builder.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 12 additions & 2 deletions packages/deno/packages/plugin-relay/schema-builder.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions packages/plugin-relay/src/field-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ fieldBuilderProto.node = function node({ id, ...options }) {
typeof rawID === 'string'
? internalDecodeGlobalID(this.builder, rawID, context, info, true)
: rawID && {
id: String(rawID.id),
id: rawID.id,
typename: this.builder.configStore.getTypeConfig(rawID.type).name,
};

Expand Down Expand Up @@ -165,7 +165,7 @@ fieldBuilderProto.nodeList = function nodeList({ ids, ...options }) {
typeof id === 'string'
? internalDecodeGlobalID(this.builder, id, context, info, true)
: id && {
id: String(id.id),
id: id.id,
typename: this.builder.configStore.getTypeConfig(id.type).name,
},
);
Expand Down
14 changes: 4 additions & 10 deletions packages/plugin-relay/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ export class PothosRelayPlugin<Types extends SchemaTypes> extends BasePlugin<Typ
): GraphQLFieldResolver<unknown, Types['Context'], object> {
const argMappings = mapInputFields(fieldConfig.args, this.buildCache, (inputField) => {
if (inputField.extensions?.isRelayGlobalID) {
return (inputField.extensions?.relayGlobalIDFor ?? true) as
| true
| { typename: string; parseId: (id: string, ctx: object) => unknown }[];
return (inputField.extensions?.relayGlobalIDFor ??
inputField.extensions?.relayGlobalIDAlwaysParse ??
false) as boolean | { typename: string; parseId: (id: string, ctx: object) => unknown }[];
}

return null;
Expand All @@ -42,13 +42,7 @@ export class PothosRelayPlugin<Types extends SchemaTypes> extends BasePlugin<Typ
const argMapper = createInputValueMapper(
argMappings,
(globalID, mappings, ctx: Types['Context'], info: GraphQLResolveInfo) =>
internalDecodeGlobalID(
this.builder,
String(globalID),
ctx,
info,
Array.isArray(mappings.value) ? mappings.value : false,
),
internalDecodeGlobalID(this.builder, String(globalID), ctx, info, mappings.value ?? false),
);

return (parent, args, context, info) =>
Expand Down
4 changes: 2 additions & 2 deletions packages/plugin-relay/src/input-field-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ inputFieldBuilder.globalIDList = function globalIDList<Req extends FieldRequired
(Array.isArray(forTypes) ? forTypes : [forTypes])) as ObjectRef<SchemaTypes>[]
)?.map((type: ObjectRef<SchemaTypes>) => ({
typename: this.builder.configStore.getTypeConfig(type).name,
parse: type instanceof NodeRef ? type.parseId : undefined,
parseId: type instanceof NodeRef ? type.parseId : undefined,
})) ?? null,
},
}) as never;
Expand All @@ -60,7 +60,7 @@ inputFieldBuilder.globalID = function globalID<Req extends boolean>(
(Array.isArray(forTypes) ? forTypes : [forTypes])) as ObjectRef<SchemaTypes>[]
)?.map((type: ObjectRef<SchemaTypes>) => ({
typename: this.builder.configStore.getTypeConfig(type).name,
parse: type instanceof NodeRef ? type.parseId : undefined,
parseId: type instanceof NodeRef ? type.parseId : undefined,
})) ?? null,
},
}) as unknown as InputFieldRef<
Expand Down
14 changes: 12 additions & 2 deletions packages/plugin-relay/src/schema-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,12 @@ schemaBuilderProto.nodeInterfaceRef = function nodeInterfaceRef() {
...this.options.relayOptions.nodeQueryOptions,
type: ref as InterfaceRef<unknown>,
args: {
id: t.arg.globalID({ required: true }),
id: t.arg.globalID({
required: true,
extensions: {
relayGlobalIDAlwaysParse: true,
},
}),
},
resolve: resolveNodeFn
? (root, args, context, info) =>
Expand Down Expand Up @@ -198,7 +203,12 @@ schemaBuilderProto.nodeInterfaceRef = function nodeInterfaceRef() {
...this.options.relayOptions.nodesQueryOptions,
type: [ref],
args: {
ids: t.arg.globalIDList({ required: true }),
ids: t.arg.globalIDList({
required: true,
extensions: {
relayGlobalIDAlwaysParse: true,
},
}),
},
resolve: resolveNodesFn
? (root, args, context, info) =>
Expand Down
8 changes: 8 additions & 0 deletions packages/plugin-relay/tests/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ input GlobalIDInput {
otherList: [OtherInput!] = [{someField: \\"abc\\"}]
}
type IDResult {
arg: String!
id: String!
idType: String!
typename: String!
}
type IDWithColon implements Node {
id: ID!
idString: String!
Expand Down Expand Up @@ -133,6 +140,7 @@ type PollAnswersUsingOffsetConnectionEdge {
type Query {
batchNumbers(after: ID, before: ID, first: Int, last: Int): QueryBatchNumbersConnection!
cursorConnection(after: ID, before: ID, first: Int, last: Int): QueryCursorConnection!
echoIDs(genericNumberThingID: ID!, globalID: ID!, numberThingID: ID!): [IDResult!]!
extraNode: Node
idWithColon(id: ID!): IDWithColon!
idsWithColon(ids: [ID!]!): [IDWithColon!]!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ class NumberThing {
id: number;

constructor(n: number) {
if (typeof n !== 'number') {
throw new TypeError(`Expected NumberThing to receive number, saw ${typeof n} ${n}`);
}
this.id = n;
}
}
Expand All @@ -13,6 +16,11 @@ class BatchLoadableNumberThing {
id: number;

constructor(n: number) {
if (typeof n !== 'number') {
throw new TypeError(
`Expected BatchLoadableNumberThing to receive number, saw ${typeof n} ${n}`,
);
}
this.id = n;
}
}
Expand Down
43 changes: 43 additions & 0 deletions packages/plugin-relay/tests/examples/relay/schema/numbers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class NumberThing {
id: number;

constructor(n: number) {
if (typeof n !== 'number') {
throw new TypeError(`Expected NumberThing to receive number, saw ${typeof n} ${n}`);
}
this.id = n;
}
}
Expand All @@ -24,6 +27,11 @@ class BatchLoadableNumberThing {
id: number;

constructor(n: number) {
if (typeof n !== 'number') {
throw new TypeError(
`Expected BatchLoadableNumberThing to receive number, saw ${typeof n} ${n}`,
);
}
this.id = n;
}
}
Expand Down Expand Up @@ -269,3 +277,38 @@ builder.queryField('numberThingsByIDs', (t) =>
resolve: (root, args) => args.ids.map(({ id }) => new NumberThing(id)),
}),
);

const IDResult = builder
.objectRef<{
id: unknown;
typename: string;
arg: string;
}>('IDResult')
.implement({
fields: (t) => ({
id: t.string({
resolve: (n) => String(n.id),
}),
typename: t.exposeString('typename', {}),
arg: t.exposeString('arg', {}),
idType: t.string({
resolve: (n) => typeof n.id,
}),
}),
});

builder.queryField('echoIDs', (t) =>
t.field({
type: [IDResult],
args: {
globalID: t.arg.globalID({ required: true }),
numberThingID: t.arg.globalID({ required: true, for: [NumberThingRef] }),
genericNumberThingID: t.arg.globalID({ required: true, for: [NumberThing] }),
},
resolve: (_, args) => [
{ ...args.globalID, arg: 'globalID' },
{ ...args.numberThingID, arg: 'numberThingID' },
{ ...args.genericNumberThingID, arg: 'genericNumberThingID' },
],
}),
);
30 changes: 30 additions & 0 deletions packages/plugin-relay/tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,16 @@ describe('relay example schema', () => {
id
number
}
echoIDs(
globalID: "TnVtYmVyOjE="
numberThingID: "TnVtYmVyOjE="
genericNumberThingID: "TnVtYmVyOjE="
) {
id
typename
arg
idType
}
}
`;

Expand All @@ -549,6 +559,26 @@ describe('relay example schema', () => {
expect(result).toMatchInlineSnapshot(`
{
"data": {
"echoIDs": [
{
"arg": "globalID",
"id": "1",
"idType": "string",
"typename": "Number",
},
{
"arg": "numberThingID",
"id": "1",
"idType": "number",
"typename": "Number",
},
{
"arg": "genericNumberThingID",
"id": "1",
"idType": "string",
"typename": "Number",
},
],
"idWithColon": {
"id": "SURXaXRoQ29sb246MTp0ZXN0",
"idString": "1:test",
Expand Down

0 comments on commit 9bbbefa

Please sign in to comment.