Skip to content

Commit 43c8e51

Browse files
authored
feat: add support for enumsAsTypes (#118)
1 parent d031a50 commit 43c8e51

File tree

8 files changed

+634
-5
lines changed

8 files changed

+634
-5
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ Defines the file path containing all GraphQL types. This file can also be genera
1818

1919
Adds `__typename` property to mock data
2020

21+
### enumsAsTypes (`boolean`, defaultValue: `false`)
22+
23+
Changes enums to TypeScript string union types
24+
2125
### terminateCircularRelationships (`boolean`, defaultValue: `false`)
2226

2327
When enabled, prevents circular relationships from triggering infinite recursion. After the first resolution of a

src/index.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type Options<T = TypeNode> = {
2525
dynamicValues: boolean;
2626
generateLibrary: 'casual' | 'faker';
2727
fieldGeneration?: TypeFieldMap;
28+
enumsAsTypes?: boolean;
2829
};
2930

3031
const convertName = (value: string, fn: (v: string) => string, transformUnderscore: boolean): string => {
@@ -274,10 +275,10 @@ const getNamedType = (opts: Options<NamedTypeNode>): string | number | boolean =
274275
);
275276
const enumConverter = createNameConverter(opts.enumValuesConvention, opts.transformUnderscore);
276277
const value = foundType.values ? foundType.values[0] : '';
277-
return handleValueGeneration(
278-
opts,
279-
undefined,
280-
() => `${typenameConverter(foundType.name, opts.enumsPrefix)}.${enumConverter(value)}`,
278+
return handleValueGeneration(opts, undefined, () =>
279+
opts.enumsAsTypes
280+
? `'${enumConverter(value)}'`
281+
: `${typenameConverter(foundType.name, opts.enumsPrefix)}.${enumConverter(value)}`,
281282
);
282283
}
283284
case 'union':
@@ -394,6 +395,7 @@ const getImportTypes = ({
394395
typesPrefix,
395396
enumsPrefix,
396397
transformUnderscore,
398+
enumsAsTypes,
397399
}: {
398400
typeNamesConvention: NamingConvention;
399401
definitions: any;
@@ -402,6 +404,7 @@ const getImportTypes = ({
402404
typesPrefix: string;
403405
enumsPrefix: string;
404406
transformUnderscore: boolean;
407+
enumsAsTypes: boolean;
405408
}) => {
406409
const typenameConverter = createNameConverter(typeNamesConvention, transformUnderscore);
407410
const typeImports = typesPrefix?.endsWith('.')
@@ -413,7 +416,9 @@ const getImportTypes = ({
413416
? [enumsPrefix.slice(0, -1)]
414417
: types.filter(({ type }) => type === 'enum').map(({ name }) => typenameConverter(name, enumsPrefix));
415418

416-
typeImports.push(...enumTypes);
419+
if (!enumsAsTypes) {
420+
typeImports.push(...enumTypes);
421+
}
417422

418423
function onlyUnique(value, index, self) {
419424
return self.indexOf(value) === index;
@@ -459,6 +464,7 @@ export interface TypescriptMocksPluginConfig {
459464
generateLibrary?: 'casual' | 'faker';
460465
fieldGeneration?: TypeFieldMap;
461466
locale?: string;
467+
enumsAsTypes?: boolean;
462468
}
463469

464470
interface TypeItem {
@@ -504,6 +510,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
504510
const listElementCount = config.listElementCount > 0 ? config.listElementCount : 1;
505511
const dynamicValues = !!config.dynamicValues;
506512
const generateLibrary = config.generateLibrary || 'casual';
513+
const enumsAsTypes = config.enumsAsTypes ?? false;
507514

508515
if (generateLibrary === 'faker' && config.locale) {
509516
faker.setLocale(config.locale);
@@ -555,6 +562,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
555562
dynamicValues,
556563
generateLibrary,
557564
fieldGeneration: config.fieldGeneration,
565+
enumsAsTypes,
558566
});
559567

560568
return ` ${fieldName}: overrides && overrides.hasOwnProperty('${fieldName}') ? overrides.${fieldName}! : ${value},`;
@@ -587,6 +595,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
587595
dynamicValues,
588596
generateLibrary,
589597
fieldGeneration: config.fieldGeneration,
598+
enumsAsTypes,
590599
});
591600

592601
return ` ${field.name.value}: overrides && overrides.hasOwnProperty('${field.name.value}') ? overrides.${field.name.value}! : ${value},`;
@@ -674,6 +683,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
674683
typesPrefix: config.typesPrefix,
675684
enumsPrefix: config.enumsPrefix,
676685
transformUnderscore: transformUnderscore,
686+
enumsAsTypes,
677687
});
678688
// Function that will generate the mocks.
679689
// We generate it after having visited because we need to distinct types from enums

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

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,6 +1731,84 @@ export const aQuery = (overrides?: Partial<Query>): Query => {
17311731
"
17321732
`;
17331733

1734+
exports[`should generate mock data with as-is enum values as string union type if enumsAsTypes is true and enumValues is "keep" 1`] = `
1735+
"
1736+
export const anAvatar = (overrides?: Partial<Avatar>): Avatar => {
1737+
return {
1738+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '0550ff93-dd31-49b4-8c38-ff1cb68bdc38',
1739+
url: overrides && overrides.hasOwnProperty('url') ? overrides.url! : 'aliquid',
1740+
};
1741+
};
1742+
1743+
export const aUser = (overrides?: Partial<User>): User => {
1744+
return {
1745+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
1746+
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
1747+
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
1748+
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
1749+
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : 'ONLINE',
1750+
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : 'hasXYZStatus',
1751+
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
1752+
camelCaseThing: overrides && overrides.hasOwnProperty('camelCaseThing') ? overrides.camelCaseThing! : aCamelCaseThing(),
1753+
unionThing: overrides && overrides.hasOwnProperty('unionThing') ? overrides.unionThing! : anAvatar(),
1754+
prefixedEnum: overrides && overrides.hasOwnProperty('prefixedEnum') ? overrides.prefixedEnum! : 'PREFIXED_VALUE',
1755+
};
1756+
};
1757+
1758+
export const aWithAvatar = (overrides?: Partial<WithAvatar>): WithAvatar => {
1759+
return {
1760+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '89f515e7-31e0-461d-a230-c4c7f4dafc5c',
1761+
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
1762+
};
1763+
};
1764+
1765+
export const aCamelCaseThing = (overrides?: Partial<CamelCaseThing>): CamelCaseThing => {
1766+
return {
1767+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '345b9cf9-00fa-4974-800f-aeee5ee7fd42',
1768+
};
1769+
};
1770+
1771+
export const aPrefixedResponse = (overrides?: Partial<PrefixedResponse>): PrefixedResponse => {
1772+
return {
1773+
ping: overrides && overrides.hasOwnProperty('ping') ? overrides.ping! : 'sunt',
1774+
};
1775+
};
1776+
1777+
export const anAbcType = (overrides?: Partial<AbcType>): AbcType => {
1778+
return {
1779+
abc: overrides && overrides.hasOwnProperty('abc') ? overrides.abc! : 'sit',
1780+
};
1781+
};
1782+
1783+
export const aListType = (overrides?: Partial<ListType>): ListType => {
1784+
return {
1785+
stringList: overrides && overrides.hasOwnProperty('stringList') ? overrides.stringList! : ['voluptatem'],
1786+
};
1787+
};
1788+
1789+
export const anUpdateUserInput = (overrides?: Partial<UpdateUserInput>): UpdateUserInput => {
1790+
return {
1791+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '1d6a9360-c92b-4660-8e5f-04155047bddc',
1792+
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'qui',
1793+
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
1794+
};
1795+
};
1796+
1797+
export const aMutation = (overrides?: Partial<Mutation>): Mutation => {
1798+
return {
1799+
updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(),
1800+
};
1801+
};
1802+
1803+
export const aQuery = (overrides?: Partial<Query>): Query => {
1804+
return {
1805+
user: overrides && overrides.hasOwnProperty('user') ? overrides.user! : aUser(),
1806+
prefixed_query: overrides && overrides.hasOwnProperty('prefixed_query') ? overrides.prefixed_query! : aPrefixedResponse(),
1807+
};
1808+
};
1809+
"
1810+
`;
1811+
17341812
exports[`should generate mock data with as-is enum values if enumValues is "keep" 1`] = `
17351813
"
17361814
export const anAvatar = (overrides?: Partial<Avatar>): Avatar => {
@@ -1887,6 +1965,84 @@ export const aQuery = (overrides?: Partial<Query>): Query => {
18871965
"
18881966
`;
18891967

1968+
exports[`should generate mock data with enum values as string union type if enumsAsTypes is true 1`] = `
1969+
"
1970+
export const anAvatar = (overrides?: Partial<Avatar>): Avatar => {
1971+
return {
1972+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '0550ff93-dd31-49b4-8c38-ff1cb68bdc38',
1973+
url: overrides && overrides.hasOwnProperty('url') ? overrides.url! : 'aliquid',
1974+
};
1975+
};
1976+
1977+
export const aUser = (overrides?: Partial<User>): User => {
1978+
return {
1979+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
1980+
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
1981+
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
1982+
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
1983+
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : 'Online',
1984+
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : 'HasXyzStatus',
1985+
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
1986+
camelCaseThing: overrides && overrides.hasOwnProperty('camelCaseThing') ? overrides.camelCaseThing! : aCamelCaseThing(),
1987+
unionThing: overrides && overrides.hasOwnProperty('unionThing') ? overrides.unionThing! : anAvatar(),
1988+
prefixedEnum: overrides && overrides.hasOwnProperty('prefixedEnum') ? overrides.prefixedEnum! : 'PrefixedValue',
1989+
};
1990+
};
1991+
1992+
export const aWithAvatar = (overrides?: Partial<WithAvatar>): WithAvatar => {
1993+
return {
1994+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '89f515e7-31e0-461d-a230-c4c7f4dafc5c',
1995+
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
1996+
};
1997+
};
1998+
1999+
export const aCamelCaseThing = (overrides?: Partial<CamelCaseThing>): CamelCaseThing => {
2000+
return {
2001+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '345b9cf9-00fa-4974-800f-aeee5ee7fd42',
2002+
};
2003+
};
2004+
2005+
export const aPrefixedResponse = (overrides?: Partial<PrefixedResponse>): PrefixedResponse => {
2006+
return {
2007+
ping: overrides && overrides.hasOwnProperty('ping') ? overrides.ping! : 'sunt',
2008+
};
2009+
};
2010+
2011+
export const anAbcType = (overrides?: Partial<AbcType>): AbcType => {
2012+
return {
2013+
abc: overrides && overrides.hasOwnProperty('abc') ? overrides.abc! : 'sit',
2014+
};
2015+
};
2016+
2017+
export const aListType = (overrides?: Partial<ListType>): ListType => {
2018+
return {
2019+
stringList: overrides && overrides.hasOwnProperty('stringList') ? overrides.stringList! : ['voluptatem'],
2020+
};
2021+
};
2022+
2023+
export const anUpdateUserInput = (overrides?: Partial<UpdateUserInput>): UpdateUserInput => {
2024+
return {
2025+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '1d6a9360-c92b-4660-8e5f-04155047bddc',
2026+
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'qui',
2027+
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
2028+
};
2029+
};
2030+
2031+
export const aMutation = (overrides?: Partial<Mutation>): Mutation => {
2032+
return {
2033+
updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(),
2034+
};
2035+
};
2036+
2037+
export const aQuery = (overrides?: Partial<Query>): Query => {
2038+
return {
2039+
user: overrides && overrides.hasOwnProperty('user') ? overrides.user! : aUser(),
2040+
prefixed_query: overrides && overrides.hasOwnProperty('prefixed_query') ? overrides.prefixed_query! : aPrefixedResponse(),
2041+
};
2042+
};
2043+
"
2044+
`;
2045+
18902046
exports[`should generate mock data with typename if addTypename is true 1`] = `
18912047
"
18922048
export const anAvatar = (overrides?: Partial<Avatar>): { __typename: 'Avatar' } & Avatar => {
@@ -2604,6 +2760,85 @@ export const aQuery = (overrides?: Partial<Query>): Query => {
26042760
"
26052761
`;
26062762

2763+
exports[`should preserve underscores if transformUnderscore is false and enumsAsTypes is true 1`] = `
2764+
"import { Avatar, User, WithAvatar, CamelCaseThing, Prefixed_Response, AbcType, ListType, UpdateUserInput, Mutation, Query } from './types/graphql';
2765+
2766+
export const anAvatar = (overrides?: Partial<Avatar>): Avatar => {
2767+
return {
2768+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '0550ff93-dd31-49b4-8c38-ff1cb68bdc38',
2769+
url: overrides && overrides.hasOwnProperty('url') ? overrides.url! : 'aliquid',
2770+
};
2771+
};
2772+
2773+
export const aUser = (overrides?: Partial<User>): User => {
2774+
return {
2775+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'a5756f00-41a6-422a-8a7d-d13ee6a63750',
2776+
creationDate: overrides && overrides.hasOwnProperty('creationDate') ? overrides.creationDate! : '1970-01-09T16:33:21.532Z',
2777+
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'libero',
2778+
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
2779+
status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : 'Online',
2780+
customStatus: overrides && overrides.hasOwnProperty('customStatus') ? overrides.customStatus! : 'HasXyzStatus',
2781+
scalarValue: overrides && overrides.hasOwnProperty('scalarValue') ? overrides.scalarValue! : 'neque',
2782+
camelCaseThing: overrides && overrides.hasOwnProperty('camelCaseThing') ? overrides.camelCaseThing! : aCamelCaseThing(),
2783+
unionThing: overrides && overrides.hasOwnProperty('unionThing') ? overrides.unionThing! : anAvatar(),
2784+
prefixedEnum: overrides && overrides.hasOwnProperty('prefixedEnum') ? overrides.prefixedEnum! : 'Prefixed_Value',
2785+
};
2786+
};
2787+
2788+
export const aWithAvatar = (overrides?: Partial<WithAvatar>): WithAvatar => {
2789+
return {
2790+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '89f515e7-31e0-461d-a230-c4c7f4dafc5c',
2791+
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
2792+
};
2793+
};
2794+
2795+
export const aCamelCaseThing = (overrides?: Partial<CamelCaseThing>): CamelCaseThing => {
2796+
return {
2797+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '345b9cf9-00fa-4974-800f-aeee5ee7fd42',
2798+
};
2799+
};
2800+
2801+
export const aPrefixed_Response = (overrides?: Partial<Prefixed_Response>): Prefixed_Response => {
2802+
return {
2803+
ping: overrides && overrides.hasOwnProperty('ping') ? overrides.ping! : 'sunt',
2804+
};
2805+
};
2806+
2807+
export const anAbcType = (overrides?: Partial<AbcType>): AbcType => {
2808+
return {
2809+
abc: overrides && overrides.hasOwnProperty('abc') ? overrides.abc! : 'sit',
2810+
};
2811+
};
2812+
2813+
export const aListType = (overrides?: Partial<ListType>): ListType => {
2814+
return {
2815+
stringList: overrides && overrides.hasOwnProperty('stringList') ? overrides.stringList! : ['voluptatem'],
2816+
};
2817+
};
2818+
2819+
export const anUpdateUserInput = (overrides?: Partial<UpdateUserInput>): UpdateUserInput => {
2820+
return {
2821+
id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '1d6a9360-c92b-4660-8e5f-04155047bddc',
2822+
login: overrides && overrides.hasOwnProperty('login') ? overrides.login! : 'qui',
2823+
avatar: overrides && overrides.hasOwnProperty('avatar') ? overrides.avatar! : anAvatar(),
2824+
};
2825+
};
2826+
2827+
export const aMutation = (overrides?: Partial<Mutation>): Mutation => {
2828+
return {
2829+
updateUser: overrides && overrides.hasOwnProperty('updateUser') ? overrides.updateUser! : aUser(),
2830+
};
2831+
};
2832+
2833+
export const aQuery = (overrides?: Partial<Query>): Query => {
2834+
return {
2835+
user: overrides && overrides.hasOwnProperty('user') ? overrides.user! : aUser(),
2836+
prefixed_query: overrides && overrides.hasOwnProperty('prefixed_query') ? overrides.prefixed_query! : aPrefixed_Response(),
2837+
};
2838+
};
2839+
"
2840+
`;
2841+
26072842
exports[`should use relationshipsToOmit argument to terminate circular relationships with terminateCircularRelationships enabled 1`] = `
26082843
"
26092844
export const anAvatar = (overrides?: Partial<Avatar>, _relationshipsToOmit: Set<string> = new Set()): Avatar => {

0 commit comments

Comments
 (0)