Skip to content

Commit b514738

Browse files
adrienharnayJakeDawkins
authored andcommitted
Feat/file extension (#1130)
* feat(apollo typescript): tsFileExtension CLI arg
1 parent cb0b782 commit b514738

7 files changed

Lines changed: 70 additions & 7 deletions

File tree

packages/apollo-codegen-core/src/compiler/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ export interface CompilerOptions {
4242
namespace?: string;
4343
generateOperationIds?: boolean;
4444
operationIdsPath?: string;
45+
// this option is only implemented in the ts codegen, so we name it
46+
// `ts` fileExtension for now.
47+
tsFileExtension?: string;
4548
useReadOnlyTypes?: boolean;
4649
}
4750

packages/apollo-codegen-typescript/src/codeGeneration.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { BasicGeneratedFile } from "apollo-codegen-core/lib/utilities/CodeGenera
2424
import { CompilerOptions } from "apollo-codegen-core/lib/compiler";
2525
import TypescriptGenerator, { ObjectProperty } from "./language";
2626
import Printer from "./printer";
27+
import { DEFAULT_FILE_EXTENSION } from "./helpers";
2728
import { GraphQLType, isListType } from "graphql/type/definition";
2829
import {
2930
GraphQLNonNull,
@@ -82,14 +83,15 @@ function printGlobalImport(
8283
generator: TypescriptAPIGenerator,
8384
typesUsed: GraphQLType[],
8485
outputPath: string,
86+
tsFileExtension: string,
8587
globalSourcePath: string
8688
) {
8789
if (typesUsed.length > 0) {
8890
const relative = path.relative(
8991
path.dirname(outputPath),
9092
path.join(
9193
path.dirname(globalSourcePath),
92-
path.basename(globalSourcePath, ".ts")
94+
path.basename(globalSourcePath, `.${tsFileExtension}`)
9395
)
9496
);
9597

@@ -116,7 +118,8 @@ export function generateSource(context: CompilerContext) {
116118

117119
generatedFiles.push({
118120
sourcePath: operation.filePath,
119-
fileName: `${operation.operationName}.ts`,
121+
fileName: `${operation.operationName}.${context.options.tsFileExtension ||
122+
DEFAULT_FILE_EXTENSION}`,
120123
content: new TypescriptGeneratedFile(output)
121124
});
122125
});
@@ -162,14 +165,16 @@ export function generateLocalSource(
162165

163166
const operations = Object.values(context.operations).map(operation => ({
164167
sourcePath: operation.filePath,
165-
fileName: `${operation.operationName}.ts`,
168+
fileName: `${operation.operationName}.${context.options.tsFileExtension ||
169+
DEFAULT_FILE_EXTENSION}`,
166170
content: (options?: IGeneratedFileOptions) => {
167171
generator.fileHeader();
168172
if (options && options.outputPath && options.globalSourcePath) {
169173
printGlobalImport(
170174
generator,
171175
generator.getGlobalTypesUsedForOperation(operation),
172176
options.outputPath,
177+
context.options.tsFileExtension || DEFAULT_FILE_EXTENSION,
173178
options.globalSourcePath
174179
);
175180
}
@@ -181,14 +186,16 @@ export function generateLocalSource(
181186

182187
const fragments = Object.values(context.fragments).map(fragment => ({
183188
sourcePath: fragment.filePath,
184-
fileName: `${fragment.fragmentName}.ts`,
189+
fileName: `${fragment.fragmentName}.${context.options.tsFileExtension ||
190+
DEFAULT_FILE_EXTENSION}`,
185191
content: (options?: IGeneratedFileOptions) => {
186192
generator.fileHeader();
187193
if (options && options.outputPath && options.globalSourcePath) {
188194
printGlobalImport(
189195
generator,
190196
generator.getGlobalTypesUsedForFragment(fragment),
191197
options.outputPath,
198+
context.options.tsFileExtension || DEFAULT_FILE_EXTENSION,
192199
options.globalSourcePath
193200
);
194201
}

packages/apollo-codegen-typescript/src/helpers.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import * as t from "@babel/types";
1414

1515
import { CompilerOptions } from "apollo-codegen-core/lib/compiler";
1616

17+
const DEFAULT_FILE_EXTENSION = "ts";
18+
1719
const builtInScalarMap = {
1820
[GraphQLString.name]: t.TSStringKeyword(),
1921
[GraphQLInt.name]: t.TSNumberKeyword(),
@@ -79,3 +81,5 @@ export function createTypeFromGraphQLTypeFunction(
7981

8082
return typeFromGraphQLType;
8183
}
84+
85+
export { DEFAULT_FILE_EXTENSION };

packages/apollo/src/commands/client/__tests__/__snapshots__/generate.test.ts.snap

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,21 @@ export interface SimpleQuery {
364364
"
365365
`;
366366

367+
exports[`client:codegen writes types for typescript with a custom extension 1`] = `
368+
"/* tslint:disable */
369+
/* eslint-disable */
370+
// This file was automatically generated and should not be edited.
371+
372+
// ====================================================
373+
// GraphQL query operation: SimpleQuery
374+
// ====================================================
375+
376+
export interface SimpleQuery {
377+
hello: string;
378+
}
379+
"
380+
`;
381+
367382
exports[`client:codegen writes typescript types for query with client-side data when client schema in graphql file 1`] = `
368383
"/* tslint:disable */
369384
/* eslint-disable */

packages/apollo/src/commands/client/__tests__/generate.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,28 @@ describe("client:codegen", () => {
191191
expect(fs.readFileSync("API.ts").toString()).toMatchSnapshot();
192192
});
193193

194+
test
195+
.fs({
196+
"schema.json": fullSchemaJsonString,
197+
"queryOne.graphql": simpleQuery.toString(),
198+
"my.config.js": defaultConfig
199+
})
200+
.command([
201+
"client:codegen",
202+
"--config=my.config.js",
203+
"--target=typescript",
204+
"--tsFileExtension=d.ts",
205+
"--outputFlat",
206+
"outDirectory"
207+
])
208+
.it("writes types for typescript with a custom extension", () => {
209+
const files = fs.readdirSync("./outDirectory");
210+
const filePath = files.find(f => f === "SimpleQuery.d.ts");
211+
expect(filePath).toBeDefined();
212+
const file = fs.readFileSync(`./outDirectory/${filePath}`).toString();
213+
expect(file).toMatchSnapshot();
214+
});
215+
194216
test
195217
.fs({
196218
"schema.json": fullSchemaJsonString,

packages/apollo/src/commands/client/codegen.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,11 @@ export default class Generate extends ClientCommand {
9696
// typescript
9797
globalTypesFile: flags.string({
9898
description:
99-
'By default, TypeScript will put a file named "globalTypes.ts" inside the "output" directory. Set "globalTypesFile" to specify a different path.'
99+
'By default, TypeScript will put a file named "globalTypes.ts" inside the "output" directory. Set "globalTypesFile" to specify a different path. Alternatively, set "fileExtension" to modify the extension of the file, for example "d.ts" will output "globalTypes.d.ts"'
100+
}),
101+
tsFileExtension: flags.string({
102+
description:
103+
'By default, TypeScript will output "ts" files. Set "tsFileExtension" to specify a different file extension, for example "d.ts"'
100104
})
101105
};
102106

@@ -200,7 +204,8 @@ export default class Generate extends ClientCommand {
200204
useFlowExactObjects: flags.useFlowExactObjects,
201205
useReadOnlyTypes:
202206
flags.useReadOnlyTypes || flags.useFlowReadOnlyTypes,
203-
globalTypesFile: flags.globalTypesFile
207+
globalTypesFile: flags.globalTypesFile,
208+
tsFileExtension: flags.tsFileExtension
204209
}
205210
);
206211
};

packages/apollo/src/generate.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { generateSource as generateScalaSource } from "apollo-codegen-scala";
2525

2626
import { FlowCompilerOptions } from "../../apollo-codegen-flow/lib/language";
2727
import { validateQueryDocument } from "apollo-language-server/lib/errors/validation";
28+
import { DEFAULT_FILE_EXTENSION as TYPESCRIPT_DEFAULT_FILE_EXTENSION } from "apollo-codegen-typescript/lib/helpers";
2829

2930
export type TargetType =
3031
| "json"
@@ -38,6 +39,7 @@ export type GenerationOptions = CompilerOptions &
3839
LegacyCompilerOptions &
3940
FlowCompilerOptions & {
4041
globalTypesFile?: string;
42+
tsFileExtension?: string;
4143
rootPath?: string;
4244
};
4345

@@ -154,7 +156,12 @@ export default function generate(
154156
}
155157

156158
const globalSourcePath =
157-
options.globalTypesFile || path.join(outputPath, "globalTypes.ts");
159+
options.globalTypesFile ||
160+
path.join(
161+
outputPath,
162+
`globalTypes.${options.tsFileExtension ||
163+
TYPESCRIPT_DEFAULT_FILE_EXTENSION}`
164+
);
158165
outFiles[globalSourcePath] = {
159166
output: generatedGlobalFile.fileContents
160167
};

0 commit comments

Comments
 (0)