Skip to content

Commit a29d063

Browse files
committed
feat(astToSchema): add prefix/suffix option
1 parent 499a72e commit a29d063

File tree

4 files changed

+76
-23
lines changed

4 files changed

+76
-23
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"lib"
1212
],
1313
"dependencies": {
14-
"dedent": "^0.7.0"
14+
"dedent": "0.7.0"
1515
},
1616
"peerDependencies": {
1717
"graphql-compose": "^7.6.1"

src/__tests__/astToSchema-test.ts

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { astToSchema, createFields } from '../astToSchema';
33
import { SchemaComposer } from 'graphql-compose';
44
import { printSchema } from 'graphql/utilities';
55
import path from 'path';
6+
import dedent from 'dedent';
67

78
describe('astToSchema()', () => {
89
describe('Schema ./__testSchema__', () => {
@@ -29,8 +30,8 @@ describe('astToSchema()', () => {
2930
createFields(
3031
sc,
3132
getAstForFile(module, path.resolve(__dirname, './__testSchema__/query/field.ts')),
32-
'Query',
33-
sc.Query
33+
sc.Query,
34+
'Query'
3435
);
3536
expect(sc.Query.hasField('field')).toBeTruthy();
3637
expect(sc.Query.getFieldTypeName('field')).toBe('String');
@@ -40,8 +41,8 @@ describe('astToSchema()', () => {
4041
createFields(
4142
sc,
4243
getAstForFile(module, path.resolve(__dirname, './__testSchema__/query/some.nested.ts')),
43-
'Query',
44-
sc.Query
44+
sc.Query,
45+
'Query'
4546
);
4647
expect(sc.Query.hasField('some')).toBeTruthy();
4748
expect(sc.Query.getFieldTypeName('some')).toBe('QuerySome');
@@ -53,8 +54,8 @@ describe('astToSchema()', () => {
5354
createFields(
5455
sc,
5556
getAstForFile(module, path.resolve(__dirname, './__testSchema__/query/some.type.index.ts')),
56-
'Query',
57-
sc.Query
57+
sc.Query,
58+
'Query'
5859
);
5960
expect(sc.Query.hasField('some')).toBeTruthy();
6061
expect(sc.Query.getFieldTypeName('some')).toBe('QuerySome');
@@ -69,8 +70,8 @@ describe('astToSchema()', () => {
6970
createFields(
7071
sc,
7172
getAstForDir(module, path.resolve(__dirname, './__testSchema__/query/me')),
72-
'Query',
73-
sc.Query
73+
sc.Query,
74+
'Query'
7475
);
7576
expect(sc.Query.hasField('me')).toBeTruthy();
7677
expect(sc.Query.getFieldTypeName('me')).toBe('QueryMe');
@@ -105,5 +106,47 @@ describe('astToSchema()', () => {
105106
});
106107
const sc = astToSchema(ast);
107108
expect(sc.Query.getFieldOTC('auth').getFieldTypeName('nested')).toBe('QueryAuthNested');
109+
expect(sc.Query.toSDL({ deep: true })).toBe(dedent`
110+
type Query {
111+
auth: QueryAuth
112+
}
113+
114+
type QueryAuth {
115+
nested: QueryAuthNested
116+
}
117+
118+
type QueryAuthNested {
119+
method: Boolean
120+
}
121+
122+
"""The \`Boolean\` scalar type represents \`true\` or \`false\`."""
123+
scalar Boolean
124+
`);
125+
});
126+
127+
describe('astToSchema()', () => {
128+
it('should properly add prefix for created TypeNames', () => {
129+
const ast = directoryToAst(module, {
130+
relativePath: './__testSchema__',
131+
include: /query\.auth$|query\.auth\/nested/,
132+
});
133+
const sc = astToSchema(ast, { prefix: 'Corp', suffix: 'Old' });
134+
expect(sc.Query.toSDL({ deep: true })).toBe(dedent`
135+
type Query {
136+
auth: CorpQueryAuthOld
137+
}
138+
139+
type CorpQueryAuthOld {
140+
nested: CorpQueryAuthNestedOld
141+
}
142+
143+
type CorpQueryAuthNestedOld {
144+
method: Boolean
145+
}
146+
147+
"""The \`Boolean\` scalar type represents \`true\` or \`false\`."""
148+
scalar Boolean
149+
`);
150+
});
108151
});
109152
});

src/astToSchema.ts

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import { GraphQLObjectType } from 'graphql';
1515

1616
export interface AstOptions {
1717
schemaComposer?: SchemaComposer<any>;
18+
prefix?: string;
19+
suffix?: string;
1820
}
1921

2022
export function astToSchema<TContext = any>(
@@ -36,29 +38,31 @@ export function astToSchema<TContext = any>(
3638
sc = new SchemaComposer();
3739
}
3840

39-
if (ast.query) populateRoot(sc, 'Query', ast.query);
40-
if (ast.mutation) populateRoot(sc, 'Mutation', ast.mutation);
41-
if (ast.subscription) populateRoot(sc, 'Subscription', ast.subscription);
41+
if (ast.query) populateRoot(sc, 'Query', ast.query, opts);
42+
if (ast.mutation) populateRoot(sc, 'Mutation', ast.mutation, opts);
43+
if (ast.subscription) populateRoot(sc, 'Subscription', ast.subscription, opts);
4244

4345
return sc;
4446
}
4547

4648
function populateRoot(
4749
sc: SchemaComposer<any>,
4850
rootName: 'Query' | 'Mutation' | 'Subscription',
49-
astRootNode: AstRootTypeNode
51+
astRootNode: AstRootTypeNode,
52+
opts?: AstOptions
5053
) {
5154
const tc = sc[rootName];
5255
Object.keys(astRootNode.children).forEach((key) => {
53-
createFields(sc, astRootNode.children[key], rootName, tc);
56+
createFields(sc, astRootNode.children[key], tc, rootName, opts || {});
5457
});
5558
}
5659

5760
export function createFields(
5861
sc: SchemaComposer<any>,
5962
ast: AstDirNode | AstFileNode | void,
60-
prefix: string,
61-
parent: ObjectTypeComposer
63+
parent: ObjectTypeComposer,
64+
pathPrefix: string,
65+
opts: AstOptions = {}
6266
): void {
6367
if (!ast) return;
6468

@@ -76,7 +80,7 @@ export function createFields(
7680
if (name.endsWith('.index')) {
7781
const fieldName = name.slice(0, -6); // remove ".index" from field name
7882
parent.addNestedFields({
79-
[fieldName]: prepareNamespaceFieldConfig(sc, ast, `${prefix}${getTypename(ast)}`),
83+
[fieldName]: prepareNamespaceFieldConfig(sc, ast, getTypename(ast, pathPrefix, opts)),
8084
});
8185
} else {
8286
parent.addNestedFields({
@@ -88,7 +92,7 @@ export function createFields(
8892
}
8993

9094
if (ast.kind === 'dir') {
91-
const typename = `${prefix}${getTypename(ast)}`;
95+
const typename = getTypename(ast, pathPrefix, opts);
9296
let fc: ObjectTypeComposerFieldConfig<any, any>;
9397
if (ast.children['index'] && ast.children['index'].kind === 'file') {
9498
fc = prepareNamespaceFieldConfig(sc, ast.children['index'], typename);
@@ -103,15 +107,17 @@ export function createFields(
103107
},
104108
});
105109

110+
const pathPrefixForChild = getTypename(ast, pathPrefix, {});
106111
Object.keys(ast.children).forEach((key) => {
107-
createFields(sc, ast.children[key], typename, fc.type as any);
112+
createFields(sc, ast.children[key], fc.type as any, pathPrefixForChild, opts);
108113
});
109114
}
110115
}
111116

112-
function getTypename(ast: AstDirNode | AstFileNode): string {
117+
function getTypename(ast: AstDirNode | AstFileNode, pathPrefix: string, opts: AstOptions): string {
113118
const name = ast.name;
114119

120+
let typename = pathPrefix;
115121
if (name.indexOf('.') !== -1) {
116122
const namesArray = name.split('.');
117123

@@ -121,12 +127,16 @@ function getTypename(ast: AstDirNode | AstFileNode): string {
121127
);
122128
}
123129

124-
return namesArray.reduce((prev, current) => {
130+
typename += namesArray.reduce((prev, current) => {
125131
return prev + upperFirst(current);
126132
}, '');
127133
} else {
128-
return upperFirst(name);
134+
typename += upperFirst(name);
129135
}
136+
137+
if (opts.prefix) typename = `${opts.prefix}${typename}`;
138+
if (opts.suffix) typename += opts.suffix;
139+
return typename;
130140
}
131141

132142
function prepareNamespaceFieldConfig(

yarn.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2188,7 +2188,7 @@ decode-uri-component@^0.2.0:
21882188
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
21892189
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
21902190

2191-
dedent@^0.7.0:
2191+
21922192
version "0.7.0"
21932193
resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
21942194
integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=

0 commit comments

Comments
 (0)