Skip to content

Commit 4e1eac8

Browse files
authored
Merge pull request #1235 from Quramy/allow_to_transform_callexpression
fix: Allow to transform CallExpression
2 parents e6ced8d + 951dd5b commit 4e1eac8

File tree

5 files changed

+146
-20
lines changed

5 files changed

+146
-20
lines changed

src/transformer/__snapshots__/transformer.test.ts.snap

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ exports[`transformer GraphQL document transformation should ignore TemplateExpre
1515
"
1616
`;
1717

18+
exports[`transformer GraphQL document transformation should ignore arguments which are not template literal in CallExpression node even if the node matches tag name 1`] = `
19+
"const query = hoge('abc', 100);
20+
"
21+
`;
22+
23+
exports[`transformer GraphQL document transformation should ignore template argument in CallExpression when the node does not matche tag name 1`] = `
24+
"const query = hoge(\`abc\`);
25+
"
26+
`;
27+
1828
exports[`transformer GraphQL document transformation should transform NoSubstitutionTemplateLiteral 1`] = `
1929
"const query = {
2030
kind: "Document",
@@ -115,6 +125,56 @@ exports[`transformer GraphQL document transformation should transform TemplateEx
115125
"
116126
`;
117127

128+
exports[`transformer GraphQL document transformation should transform first template argument in CallExpression when the node matches tag name 1`] = `
129+
"const query = {
130+
kind: "Document",
131+
definitions: [{
132+
kind: "OperationDefinition",
133+
operation: "query",
134+
variableDefinitions: [],
135+
directives: [],
136+
selectionSet: {
137+
kind: "SelectionSet",
138+
selections: [{
139+
kind: "Field",
140+
name: {
141+
kind: "Name",
142+
value: "hello"
143+
},
144+
arguments: [],
145+
directives: []
146+
}]
147+
}
148+
}]
149+
};
150+
"
151+
`;
152+
153+
exports[`transformer GraphQL document transformation should transform first template expression argument in CallExpression when the node matches tag name 1`] = `
154+
"const query = {
155+
kind: "Document",
156+
definitions: [{
157+
kind: "OperationDefinition",
158+
operation: "query",
159+
variableDefinitions: [],
160+
directives: [],
161+
selectionSet: {
162+
kind: "SelectionSet",
163+
selections: [{
164+
kind: "Field",
165+
name: {
166+
kind: "Name",
167+
value: "hello"
168+
},
169+
arguments: [],
170+
directives: []
171+
}]
172+
}
173+
}]
174+
};
175+
"
176+
`;
177+
118178
exports[`transformer GraphQL document transformation should transform inner document with documentTransformers 1`] = `
119179
"const query = {
120180
kind: "Document",

src/transformer/transformer.test.ts

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import ts from 'typescript';
22
import { DocumentNode, parse, visit } from 'graphql';
33

4-
import { parseTagConfig } from '../ts-ast-util';
4+
import { parseTagConfig, type TagConfig } from '../ts-ast-util';
55
import { getTransformer } from './transformer';
66

77
function transformAndPrint({
@@ -13,7 +13,7 @@ function transformAndPrint({
1313
documentTransformers = [],
1414
enabled = true,
1515
}: {
16-
tag?: string;
16+
tag?: TagConfig;
1717
target: 'text' | 'object';
1818
docContent: string;
1919
tsContent: string;
@@ -153,6 +153,74 @@ describe('transformer', () => {
153153
).toMatchSnapshot();
154154
});
155155

156+
it('should transform first template argument in CallExpression when the node matches tag name', () => {
157+
expect(
158+
transformAndPrint({
159+
tsContent: `
160+
const query = hoge(\`abc\`);
161+
`,
162+
tag: { name: 'hoge', ignoreFunctionCallExpression: false },
163+
docContent: `
164+
query {
165+
hello
166+
}
167+
`,
168+
target: 'object',
169+
}),
170+
).toMatchSnapshot();
171+
});
172+
173+
it('should transform first template expression argument in CallExpression when the node matches tag name', () => {
174+
expect(
175+
transformAndPrint({
176+
tsContent: `
177+
const query = hoge(\`abc\${def}\`);
178+
`,
179+
tag: { name: 'hoge', ignoreFunctionCallExpression: false },
180+
docContent: `
181+
query {
182+
hello
183+
}
184+
`,
185+
target: 'object',
186+
}),
187+
).toMatchSnapshot();
188+
});
189+
190+
it('should ignore template argument in CallExpression when the node does not matche tag name', () => {
191+
expect(
192+
transformAndPrint({
193+
tsContent: `
194+
const query = hoge(\`abc\`);
195+
`,
196+
tag: { name: 'foo', ignoreFunctionCallExpression: false },
197+
docContent: `
198+
query {
199+
hello
200+
}
201+
`,
202+
target: 'object',
203+
}),
204+
).toMatchSnapshot();
205+
});
206+
207+
it('should ignore arguments which are not template literal in CallExpression node even if the node matches tag name', () => {
208+
expect(
209+
transformAndPrint({
210+
tsContent: `
211+
const query = hoge('abc', 100);
212+
`,
213+
tag: { name: 'hoge', ignoreFunctionCallExpression: false },
214+
docContent: `
215+
query {
216+
hello
217+
}
218+
`,
219+
target: 'object',
220+
}),
221+
).toMatchSnapshot();
222+
});
223+
156224
it('should transform to 0 literal when removeFragmentDefinitions: true and document has only fragments', () => {
157225
expect(
158226
transformAndPrint({

src/transformer/transformer.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,16 @@ export function getTransformer({
4444
return (ctx: ts.TransformationContext) => {
4545
const visit = (node: ts.Node): ts.Node | undefined => {
4646
if (!getEnabled()) return node;
47-
if (tag.names.length > 1) return node;
4847
let templateNode: ts.NoSubstitutionTemplateLiteral | ts.TemplateExpression | undefined = undefined;
4948

50-
if (ts.isImportDeclaration(node) && tag.names[0]) {
51-
return removeAliasFromImportDeclaration(node, tag.names[0]);
49+
if (ts.isImportDeclaration(node) && tag.names.length > 0) {
50+
return removeAliasFromImportDeclaration(node, tag.names);
5251
}
5352

54-
if (
55-
ts.isTaggedTemplateExpression(node) &&
56-
(!tag.names.length || !!getTemplateNodeUnder(node, { ...tag, allowFunctionCallExpression: false }))
57-
) {
53+
if (ts.isTaggedTemplateExpression(node) && (!tag.names.length || !!getTemplateNodeUnder(node, tag))) {
5854
templateNode = node.template;
55+
} else if (ts.isCallExpression(node) && !!getTemplateNodeUnder(node, tag)) {
56+
templateNode = node.arguments[0] as ts.TemplateLiteral;
5957
} else if (tag.allowNotTaggedTemplate && ts.isNoSubstitutionTemplateLiteral(node)) {
6058
templateNode = node;
6159
} else if (tag.allowNotTaggedTemplate && ts.isTemplateExpression(node)) {

src/ts-ast-util/utilily-functions.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,9 @@ describe(removeAliasFromImportDeclaration, () => {
309309
function remove(text: string, name: string) {
310310
const inputSource = ts.createSourceFile('input.ts', text, ts.ScriptTarget.Latest);
311311
const statements = inputSource.statements as ts.NodeArray<ts.ImportDeclaration>;
312-
const out = removeAliasFromImportDeclaration(statements[0], name);
312+
const out = removeAliasFromImportDeclaration(statements[0], [name]);
313313
if (!out) return undefined;
314-
return printNode(removeAliasFromImportDeclaration(statements[0], name)).trim();
314+
return printNode(removeAliasFromImportDeclaration(statements[0], [name])).trim();
315315
}
316316

317317
it('should return base statement when name does not match', () => {

src/ts-ast-util/utilily-functions.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ function mergeNamedBinding(base: ts.NamedImportBindings | undefined, head: ts.Na
1010
return astf.updateNamedImports(base, [...base.elements, ...head.elements]);
1111
}
1212

13-
function removeFromNamedBinding(base: ts.NamedImportBindings | undefined, name: string) {
13+
function removeFromNamedBinding(base: ts.NamedImportBindings | undefined, names: string[]) {
1414
if (!base) return undefined;
1515
// treat namedImports only
1616
if (ts.isNamespaceImport(base)) return base;
17-
const elements = base.elements.filter(elm => elm.name.text !== name);
17+
const elements = base.elements.filter(elm => !names.includes(elm.name.text));
1818
if (elements.length === 0) return undefined;
1919
return astf.updateNamedImports(base, elements);
2020
}
@@ -29,12 +29,12 @@ function mergeImportClause(base: ts.ImportClause | undefined, head: ts.ImportCla
2929
return astf.updateImportClause(base, isTypeOnly, name, namedBindings);
3030
}
3131

32-
function removeFromImportClause(base: ts.ImportClause | undefined, name: string) {
32+
function removeFromImportClause(base: ts.ImportClause | undefined, names: string[]) {
3333
if (!base) return undefined;
34-
const namedBindings = removeFromNamedBinding(base.namedBindings, name);
35-
const nameId = base.name?.text !== name ? base.name : undefined;
36-
if (!nameId && !namedBindings) return undefined;
37-
return astf.updateImportClause(base, base.isTypeOnly, nameId, namedBindings);
34+
const namedBindings = removeFromNamedBinding(base.namedBindings, names);
35+
const nameIdentifier = base.name && names.includes(base.name.text) ? undefined : base.name;
36+
if (!nameIdentifier && !namedBindings) return undefined;
37+
return astf.updateImportClause(base, base.isTypeOnly, nameIdentifier, namedBindings);
3838
}
3939

4040
export function findNode(sourceFile: ts.SourceFile, position: number): ts.Node | undefined {
@@ -121,9 +121,9 @@ export function mergeImportDeclarationsWithSameModules(base: ts.ImportDeclaratio
121121
return astf.updateImportDeclaration(base, modifiers, importClause, base.moduleSpecifier, undefined);
122122
}
123123

124-
export function removeAliasFromImportDeclaration(base: ts.ImportDeclaration, name: string) {
124+
export function removeAliasFromImportDeclaration(base: ts.ImportDeclaration, names: string[]) {
125125
const modifiers = base.modifiers;
126-
const importClause = removeFromImportClause(base.importClause, name);
126+
const importClause = removeFromImportClause(base.importClause, names);
127127
if (!importClause) return undefined;
128128
return astf.updateImportDeclaration(base, modifiers, importClause, base.moduleSpecifier, undefined);
129129
}

0 commit comments

Comments
 (0)