Skip to content

Commit 0d9b3d6

Browse files
P-5672: Support for getting customer groups as part of customer (#97)
* Support for getting customer groups as part of customer * Updated test
1 parent 0f64a0b commit 0d9b3d6

File tree

9 files changed

+129
-47
lines changed

9 files changed

+129
-47
lines changed

.changeset/sixty-timers-perform.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@team-plain/typescript-sdk': minor
3+
---
4+
5+
Updates the customer fragment so that it also fetches customer groups

src/client.ts

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,32 @@ import {
5858
import { request } from './request';
5959
import type { Result } from './result';
6060

61-
type SDKResult<T> = Promise<Result<T, PlainSDKError>>;
61+
type SDKResult<T> = Promise<Result<Transform<T>, PlainSDKError>>;
62+
63+
// Transform takes a GraphQL Fragment and transforms it into a type in which
64+
// all of its connection-like fields (e.g. fields which have an `edges`) property
65+
// are flattened into an array. For example:
66+
//
67+
// Given the type:
68+
//
69+
// type Fragment = {
70+
// customerGroupMemberships: {
71+
// edges: Array<{ node: CustomerGroupMembershipPartsFragment }>
72+
// }
73+
// }
74+
//
75+
// When we apply Transform to it, we get:
76+
//
77+
// type Transform<Fragment> = {
78+
// {
79+
// customerGroupMemberships: Array<CustomerGroupMembershipPartsFragment>
80+
// }
81+
//
82+
type Transform<T> = T extends { edges: Array<{ node: infer E }> }
83+
? Array<Transform<E>>
84+
: T extends object
85+
? { [K in keyof T]: Transform<T[K]> }
86+
: T;
6287

6388
function nonNullable<T>(x: T | null | undefined): T {
6489
if (x === null || x === undefined) {
@@ -159,7 +184,10 @@ export class PlainClient {
159184

160185
return unwrapData(res, (q) => ({
161186
pageInfo: q.customers.pageInfo,
162-
customers: q.customers.edges.map((edge) => edge.node),
187+
customers: q.customers.edges.map((edge) => ({
188+
...edge.node,
189+
customerGroupMemberships: edge.node.customerGroupMemberships.edges.map((e) => e.node),
190+
})),
163191
totalCount: q.customers.totalCount,
164192
}));
165193
}
@@ -175,7 +203,15 @@ export class PlainClient {
175203
variables,
176204
});
177205

178-
return unwrapData(res, (q) => q.customer);
206+
return unwrapData(res, (q) => {
207+
if (!q.customer) {
208+
return null;
209+
}
210+
return {
211+
...q.customer,
212+
customerGroupMemberships: q.customer.customerGroupMemberships.edges.map((e) => e.node),
213+
};
214+
});
179215
}
180216

181217
/**
@@ -189,7 +225,18 @@ export class PlainClient {
189225
variables,
190226
});
191227

192-
return unwrapData(res, (q) => q.customerByEmail);
228+
return unwrapData(res, (q) => {
229+
if (!q.customerByEmail) {
230+
return null;
231+
}
232+
233+
return {
234+
...q.customerByEmail,
235+
customerGroupMemberships: q.customerByEmail.customerGroupMemberships.edges.map(
236+
(e) => e.node
237+
),
238+
};
239+
});
193240
}
194241

195242
/**
@@ -207,9 +254,13 @@ export class PlainClient {
207254
});
208255

209256
return unwrapData(res, (q) => {
257+
const customer = nonNullable(q.upsertCustomer.customer);
210258
return {
211259
result: nonNullable(q.upsertCustomer.result),
212-
customer: nonNullable(q.upsertCustomer.customer),
260+
customer: {
261+
...customer,
262+
customerGroupMemberships: customer.customerGroupMemberships.edges.map((e) => e.node),
263+
},
213264
};
214265
});
215266
}

src/graphql/fragments/customerCardConfigParts.gql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
fragment CustomerCardConfigParts on CustomerCardConfig {
2+
__typename
23
id
34
title
45
key

src/graphql/fragments/customerEventParts.gql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
fragment CustomerEventParts on CustomerEvent {
2+
__typename
23
id
34
customerId
45
title

src/graphql/fragments/customerGroupMembershipParts.gql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
fragment CustomerGroupMembershipParts on CustomerGroupMembership {
2+
__typename
23
customerId
34
createdAt {
45
...DateTimeParts

src/graphql/fragments/customerGroupParts.gql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
fragment CustomerGroupParts on CustomerGroup {
2+
__typename
23
id
34
name
45
key

src/graphql/fragments/customerParts.gql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,11 @@ fragment CustomerParts on Customer {
2323
markedAsSpamAt {
2424
...DateTimeParts
2525
}
26+
customerGroupMemberships {
27+
edges {
28+
node {
29+
...CustomerGroupMembershipParts
30+
}
31+
}
32+
}
2633
}

src/graphql/types.ts

Lines changed: 33 additions & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/tests/query.test.ts

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ import { describe, expect, test } from 'vitest';
33

44
import { PlainClient } from '..';
55
import type { PlainSDKError } from '../error';
6-
import { CustomerByIdDocument } from '../graphql/types';
6+
import { CustomerByIdDocument, type CustomerPartsFragment } from '../graphql/types';
77
import { PlainGraphQLError } from '../graphql-utlities';
88
import { testHelpers } from './test-helpers';
99

1010
describe('query test - customer by id', () => {
1111
test('should return a valid customer', async () => {
1212
const customerId = 'c_123';
1313

14-
const response = {
14+
const response: { data: { customer: CustomerPartsFragment } } = {
1515
data: {
1616
customer: {
1717
__typename: 'Customer',
@@ -22,17 +22,27 @@ describe('query test - customer by id', () => {
2222
email: {
2323
email: 'test@gmail.com',
2424
isVerified: true,
25-
verifiedAt: { __typename: 'DateTime', iso8601: '2023-03-20T13:06:37.918Z' },
25+
verifiedAt: {
26+
__typename: 'DateTime',
27+
iso8601: '2023-03-20T13:06:37.918Z',
28+
unixTimestamp: '1699890305',
29+
},
30+
},
31+
updatedAt: {
32+
__typename: 'DateTime',
33+
iso8601: '2023-05-01T09:54:51.715Z',
34+
unixTimestamp: '1699890305',
35+
},
36+
createdAt: {
37+
__typename: 'DateTime',
38+
iso8601: '2023-03-20T13:06:37.961Z',
39+
unixTimestamp: '1699890305',
2640
},
27-
status: 'ACTIVE',
28-
statusChangedAt: { __typename: 'DateTime', iso8601: '2023-05-01T09:54:51.715Z' },
29-
assignedToUser: { __typename: 'UserActor', userId: 'u_123' },
30-
assignedAt: { __typename: 'DateTime', iso8601: '2023-04-10T15:01:54.499Z' },
31-
updatedAt: { __typename: 'DateTime', iso8601: '2023-05-01T09:54:51.715Z' },
32-
lastIdleAt: { __typename: 'DateTime', iso8601: '2023-03-20T13:06:47.492Z' },
33-
createdAt: { __typename: 'DateTime', iso8601: '2023-03-20T13:06:37.961Z' },
3441
createdBy: {},
3542
markedAsSpamAt: null,
43+
customerGroupMemberships: {
44+
edges: [],
45+
},
3646
},
3747
},
3848
};
@@ -56,7 +66,10 @@ describe('query test - customer by id', () => {
5666
});
5767

5868
expect(result.error).toBeUndefined();
59-
expect(result.data).toEqual(response.data.customer);
69+
expect(result.data).toEqual({
70+
...response.data.customer,
71+
customerGroupMemberships: [],
72+
});
6073
});
6174

6275
test('should accept a null customer when not found', async () => {

0 commit comments

Comments
 (0)