Skip to content

Commit aa7b348

Browse files
authored
fix: add support for custom scalar (#19)
We only supported `Date` scalars, but they can be more. As we don't know the type of scalars, the easy way is to represent it as a string. We could improve the support of custom scalar types through a config, but let's see that later
1 parent d44a803 commit aa7b348

File tree

3 files changed

+89
-2
lines changed

3 files changed

+89
-2
lines changed

src/index.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ const getNamedType = (
100100
enumValuesConvention,
101101
foundType.types && foundType.types[0],
102102
);
103+
case 'scalar':
104+
// it's a scalar, let's use a string as a value.
105+
// This could be improved with a custom scalar definition in the config
106+
return `'${casual.word}'`;
103107
default:
104108
throw `foundType is unknown: ${foundType.name}: ${foundType.type}`;
105109
}
@@ -175,7 +179,7 @@ export interface TypescriptMocksPluginConfig {
175179

176180
interface TypeItem {
177181
name: string;
178-
type: string;
182+
type: 'enum' | 'scalar' | 'union';
179183
values?: string[];
180184
types?: readonly NamedTypeNode[];
181185
}
@@ -278,6 +282,15 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
278282
},
279283
};
280284
},
285+
ScalarTypeDefinition: (node) => {
286+
const name = node.name.value;
287+
if (!types.find((enumType) => enumType.name === name)) {
288+
types.push({
289+
name,
290+
type: 'scalar',
291+
});
292+
}
293+
},
281294
};
282295

283296
const result: any = visit(astNode, { leave: visitor });
@@ -286,7 +299,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
286299
const typeImports = definitions
287300
.map(({ typeName }: { typeName: string }) => typeName)
288301
.filter((typeName: string) => !!typeName);
289-
typeImports.push(...types.map(({ name }) => name));
302+
typeImports.push(...types.filter(({ type }) => type !== 'scalar').map(({ name }) => name));
290303
// List of function that will generate the mock.
291304
// We generate it after having visited because we need to distinct types from enums
292305
const mockFns = definitions.map(({ mockFn }: any) => mockFn).filter((mockFn: Function) => !!mockFn);

tests/__snapshots__/typescript-mock-data.spec.ts.snap

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@ export const aUpdateUserInput = (overrides?: Partial<UpdateUserInput>): UpdateUs
2626
export const aUser = (overrides?: Partial<User>): User => {
2727
return {
2828
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
29+
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
2930
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
3031
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
3132
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : Status.Online,
3233
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : AbcStatus.HasXyzStatus,
34+
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
3335
};
3436
};
3537
"
@@ -63,10 +65,49 @@ export const aUpdateUserInput = (overrides?: Partial<UpdateUserInput>): UpdateUs
6365
export const aUser = (overrides?: Partial<User>): User => {
6466
return {
6567
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
68+
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
6669
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
6770
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
6871
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : Status.Online,
6972
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : AbcStatus.HasXyzStatus,
73+
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
74+
};
75+
};
76+
"
77+
`;
78+
79+
exports[`should generate mock data functions with scalars 1`] = `
80+
"
81+
export const anAbcType = (overrides?: Partial<AbcType>): AbcType => {
82+
return {
83+
abc: overrides && overrides.hasOwnProperty('abc') ? overrides.abc! : 'sit',
84+
};
85+
};
86+
87+
export const anAvatar = (overrides?: Partial<Avatar>): Avatar => {
88+
return {
89+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '0550ff93-dd31-49b4-8c38-ff1cb68bdc38',
90+
url: overrides && overrides.hasOwnProperty('url') ? overrides.url! : 'aliquid',
91+
};
92+
};
93+
94+
export const aUpdateUserInput = (overrides?: Partial<UpdateUserInput>): UpdateUserInput => {
95+
return {
96+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '1d6a9360-c92b-4660-8e5f-04155047bddc',
97+
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'qui',
98+
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
99+
};
100+
};
101+
102+
export const aUser = (overrides?: Partial<User>): User => {
103+
return {
104+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
105+
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
106+
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
107+
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
108+
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : Status.Online,
109+
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : AbcStatus.HasXyzStatus,
110+
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
70111
};
71112
};
72113
"
@@ -98,10 +139,12 @@ export const aUpdateUserInput = (overrides?: Partial<UpdateUserInput>): UpdateUs
98139
export const aUser = (overrides?: Partial<User>): User => {
99140
return {
100141
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
142+
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
101143
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
102144
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
103145
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : Status.ONLINE,
104146
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : AbcStatus.hasXYZStatus,
147+
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
105148
};
106149
};
107150
"
@@ -133,10 +176,12 @@ export const aUpdateUserInput = (overrides?: Partial<UpdateUserInput>): UpdateUs
133176
export const aUser = (overrides?: Partial<User>): User => {
134177
return {
135178
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
179+
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
136180
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
137181
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
138182
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : Status.Online,
139183
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : ABCStatus.HasXyzStatus,
184+
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
140185
};
141186
};
142187
"
@@ -168,10 +213,12 @@ export const aUpdateUserInput = (overrides?: Partial<UpdateUserInput>): UpdateUs
168213
export const aUser = (overrides?: Partial<User>): User => {
169214
return {
170215
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
216+
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
171217
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
172218
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
173219
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : Status.Online,
174220
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : AbcStatus.HasXyzStatus,
221+
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
175222
};
176223
};
177224
"
@@ -203,10 +250,12 @@ export const aUpdateUserInput = (overrides?: Partial<UpdateUserInput>): UpdateUs
203250
export const aUser = (overrides?: Partial<User>): User => {
204251
return {
205252
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
253+
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
206254
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
207255
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
208256
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : Status.Online,
209257
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : AbcStatus.HasXyzStatus,
258+
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
210259
};
211260
};
212261
"
@@ -238,10 +287,12 @@ export const aUpdateUserInput = (overrides?: Partial<UpdateUserInput>): UpdateUs
238287
export const aUser = (overrides?: Partial<User>): User => {
239288
return {
240289
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
290+
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
241291
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
242292
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
243293
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : Status.Online,
244294
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : AbcStatus.HasXyzStatus,
295+
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
245296
};
246297
};
247298
"
@@ -273,10 +324,12 @@ export const aUpdateUserInput = (overrides?: Partial<UpdateUserInput>): UpdateUs
273324
export const aUser = (overrides?: Partial<User>): User => {
274325
return {
275326
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
327+
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
276328
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
277329
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
278330
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : Status.Online,
279331
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : AbcStatus.HasXyzStatus,
332+
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
280333
};
281334
};
282335
"
@@ -311,10 +364,12 @@ export const aUser = (overrides?: Partial<User>): User => {
311364
return {
312365
__typename: 'User',
313366
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
367+
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
314368
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
315369
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
316370
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : Status.Online,
317371
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : AbcStatus.HasXyzStatus,
372+
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
318373
};
319374
};
320375
"
@@ -346,10 +401,12 @@ export const aUpdateUserInput = (overrides?: Partial<UpdateUserInput>): UpdateUs
346401
export const aUser = (overrides?: Partial<User>): User => {
347402
return {
348403
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
404+
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
349405
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
350406
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
351407
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : Status.ONLINE,
352408
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : AbcStatus.HASXYZSTATUS,
409+
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
353410
};
354411
};
355412
"
@@ -381,10 +438,12 @@ export const aUPDATEUSERINPUT = (overrides?: Partial<UPDATEUSERINPUT>): UPDATEUS
381438
export const aUSER = (overrides?: Partial<USER>): USER => {
382439
return {
383440
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
441+
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
384442
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
385443
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
386444
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : STATUS.Online,
387445
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : ABCSTATUS.HasXyzStatus,
446+
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
388447
};
389448
};
390449
"

tests/typescript-mock-data.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,22 @@ import { buildSchema } from 'graphql';
44
import { plugin } from '../src';
55

66
const testSchema = buildSchema(/* GraphQL */ `
7+
scalar Date
8+
scalar AnyObject
9+
710
type Avatar {
811
id: ID!
912
url: String!
1013
}
1114
1215
type User {
1316
id: ID!
17+
creationDate: Date!
1418
login: String!
1519
avatar: Avatar
1620
status: Status!
1721
customStatus: ABCStatus
22+
scalarValue: AnyObject!
1823
}
1924
2025
type Query {
@@ -56,6 +61,16 @@ it('should generate mock data functions', async () => {
5661
expect(result).toMatchSnapshot();
5762
});
5863

64+
it('should generate mock data functions with scalars', async () => {
65+
const result = await plugin(testSchema, [], {});
66+
67+
expect(result).toBeDefined();
68+
expect(result).toContain(
69+
"scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',",
70+
);
71+
expect(result).toMatchSnapshot();
72+
});
73+
5974
it('should generate mock data functions with external types file import', async () => {
6075
const result = await plugin(testSchema, [], { typesFile: './types/graphql.ts' });
6176

0 commit comments

Comments
 (0)