vscode-apollo 1.19.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.changeset/README.md +8 -0
- package/.changeset/config.json +14 -0
- package/.circleci/config.yml +91 -0
- package/.eslintrc.js +10 -0
- package/.git-blame-ignore-revs +2 -0
- package/.gitattributes +1 -0
- package/.github/workflows/release.yml +95 -0
- package/.gitleaks.toml +26 -0
- package/.nvmrc +1 -0
- package/.prettierrc +5 -0
- package/.vscode/launch.json +66 -0
- package/.vscode/settings.json +16 -0
- package/.vscode/tasks.json +60 -0
- package/.vscodeignore +28 -1
- package/CHANGELOG.md +250 -1
- package/CODEOWNERS +4 -0
- package/LICENSE +2 -2
- package/README.md +104 -55
- package/codegen.yml +12 -0
- package/graphql.configuration.json +5 -1
- package/images/IconRun.svg +8 -0
- package/images/marketplace/apollo-wordmark.png +0 -0
- package/jest.config.ts +21 -0
- package/jest.e2e.config.js +17 -0
- package/package.json +102 -23
- package/renovate.json +30 -0
- package/sampleWorkspace/clientSchema/apollo.config.cjs +10 -0
- package/sampleWorkspace/clientSchema/src/clientSchema.js +16 -0
- package/sampleWorkspace/clientSchema/src/test.js +18 -0
- package/sampleWorkspace/fixtures/starwarsSchema.graphql +299 -0
- package/sampleWorkspace/httpSchema/apollo.config.ts +8 -0
- package/sampleWorkspace/httpSchema/src/test.js +9 -0
- package/sampleWorkspace/localSchema/apollo.config.js +8 -0
- package/sampleWorkspace/localSchema/src/test.js +8 -0
- package/sampleWorkspace/localSchemaArray/apollo.config.js +12 -0
- package/sampleWorkspace/localSchemaArray/planets.graphql +20 -0
- package/sampleWorkspace/localSchemaArray/src/test.js +12 -0
- package/sampleWorkspace/sampleWorkspace.code-workspace +20 -0
- package/sampleWorkspace/spotifyGraph/apollo.config.mjs +5 -0
- package/sampleWorkspace/spotifyGraph/src/test.js +11 -0
- package/src/__e2e__/mockServer.js +117 -0
- package/src/__e2e__/mocks.js +13094 -0
- package/src/__e2e__/run.js +23 -0
- package/src/__e2e__/runTests.js +44 -0
- package/src/__e2e__/setup.js +1 -0
- package/src/__e2e__/vscode-environment.js +16 -0
- package/src/__e2e__/vscode.js +1 -0
- package/src/__mocks__/fs.js +3 -0
- package/src/__tests__/statusBar.test.ts +8 -7
- package/src/build.js +57 -0
- package/src/debug.ts +2 -5
- package/src/env/index.ts +1 -0
- package/src/env/typescript-utility-types.ts +2 -0
- package/src/extension.ts +265 -170
- package/src/language-server/__e2e__/clientSchema.e2e.ts +147 -0
- package/src/language-server/__e2e__/httpSchema.e2e.ts +21 -0
- package/src/language-server/__e2e__/localSchema.e2e.ts +25 -0
- package/src/language-server/__e2e__/localSchemaArray.e2e.ts +31 -0
- package/src/language-server/__e2e__/studioGraph.e2e.ts +65 -0
- package/src/language-server/__e2e__/utils.ts +151 -0
- package/src/language-server/__tests__/diagnostics.test.ts +86 -0
- package/src/language-server/__tests__/document.test.ts +187 -0
- package/src/language-server/__tests__/fileSet.test.ts +46 -0
- package/src/language-server/__tests__/fixtures/starwarsSchema.ts +1917 -0
- package/src/language-server/config/__tests__/config.ts +54 -0
- package/src/language-server/config/__tests__/loadConfig.ts +384 -0
- package/src/language-server/config/__tests__/utils.ts +99 -0
- package/src/language-server/config/config.ts +284 -0
- package/src/language-server/config/index.ts +3 -0
- package/src/language-server/config/loadConfig.ts +101 -0
- package/src/language-server/config/utils.ts +45 -0
- package/src/language-server/diagnostics.ts +118 -0
- package/src/language-server/document.ts +277 -0
- package/src/language-server/engine/index.ts +123 -0
- package/src/language-server/engine/operations/frontendUrlRoot.ts +15 -0
- package/src/language-server/engine/operations/schemaTagsAndFieldStats.ts +32 -0
- package/src/language-server/errors/__tests__/NoMissingClientDirectives.test.ts +225 -0
- package/src/language-server/errors/logger.ts +58 -0
- package/src/language-server/errors/validation.ts +274 -0
- package/src/language-server/fileSet.ts +63 -0
- package/src/language-server/format.ts +48 -0
- package/src/language-server/graphqlTypes.ts +16741 -0
- package/src/language-server/index.ts +28 -0
- package/src/language-server/languageProvider.ts +795 -0
- package/src/language-server/loadingHandler.ts +47 -0
- package/src/language-server/project/base.ts +406 -0
- package/src/language-server/project/client.ts +568 -0
- package/src/language-server/project/defaultClientSchema.ts +70 -0
- package/src/language-server/providers/schema/__tests__/file.ts +191 -0
- package/src/language-server/providers/schema/base.ts +15 -0
- package/src/language-server/providers/schema/endpoint.ts +138 -0
- package/src/language-server/providers/schema/engine.ts +204 -0
- package/src/language-server/providers/schema/file.ts +176 -0
- package/src/language-server/providers/schema/index.ts +59 -0
- package/src/language-server/server.ts +274 -0
- package/src/language-server/typings/graphql.d.ts +27 -0
- package/src/language-server/utilities/__tests__/graphql.test.ts +399 -0
- package/src/language-server/utilities/__tests__/uri.ts +55 -0
- package/src/language-server/utilities/debouncer.ts +8 -0
- package/src/language-server/utilities/debug.ts +90 -0
- package/src/language-server/utilities/graphql.ts +433 -0
- package/src/language-server/utilities/index.ts +3 -0
- package/src/language-server/utilities/source.ts +182 -0
- package/src/language-server/utilities/uri.ts +19 -0
- package/src/language-server/workspace.ts +254 -0
- package/src/languageServerClient.ts +22 -15
- package/src/messages.ts +75 -0
- package/src/statusBar.ts +5 -5
- package/src/tools/__tests__/buildServiceDefinition.test.ts +491 -0
- package/src/tools/__tests__/snapshotSerializers/astSerializer.ts +19 -0
- package/src/tools/__tests__/snapshotSerializers/graphQLTypeSerializer.ts +14 -0
- package/src/tools/buildServiceDefinition.ts +241 -0
- package/src/tools/index.ts +6 -0
- package/src/tools/schema/index.ts +2 -0
- package/src/tools/schema/resolveObject.ts +18 -0
- package/src/tools/schema/resolverMap.ts +23 -0
- package/src/tools/utilities/graphql.ts +22 -0
- package/src/tools/utilities/index.ts +3 -0
- package/src/tools/utilities/invariant.ts +5 -0
- package/src/tools/utilities/predicates.ts +5 -0
- package/src/utils.ts +7 -21
- package/syntaxes/graphql.dart.json +2 -4
- package/syntaxes/graphql.ex.json +1 -4
- package/syntaxes/graphql.js.json +3 -3
- package/syntaxes/graphql.json +13 -9
- package/syntaxes/graphql.lua.json +51 -0
- package/syntaxes/graphql.rb.json +1 -1
- package/tsconfig.build.json +11 -0
- package/tsconfig.json +22 -7
- package/create-server-symlink.js +0 -8
- package/lib/debug.d.ts +0 -11
- package/lib/debug.d.ts.map +0 -1
- package/lib/debug.js +0 -48
- package/lib/debug.js.map +0 -1
- package/lib/extension.d.ts +0 -4
- package/lib/extension.d.ts.map +0 -1
- package/lib/extension.js +0 -187
- package/lib/extension.js.map +0 -1
- package/lib/languageServerClient.d.ts +0 -4
- package/lib/languageServerClient.d.ts.map +0 -1
- package/lib/languageServerClient.js +0 -57
- package/lib/languageServerClient.js.map +0 -1
- package/lib/statusBar.d.ts +0 -24
- package/lib/statusBar.d.ts.map +0 -1
- package/lib/statusBar.js +0 -46
- package/lib/statusBar.js.map +0 -1
- package/lib/testRunner/index.d.ts +0 -3
- package/lib/testRunner/index.d.ts.map +0 -1
- package/lib/testRunner/index.js +0 -49
- package/lib/testRunner/index.js.map +0 -1
- package/lib/testRunner/jest-config.d.ts +0 -14
- package/lib/testRunner/jest-config.d.ts.map +0 -1
- package/lib/testRunner/jest-config.js +0 -18
- package/lib/testRunner/jest-config.js.map +0 -1
- package/lib/testRunner/jest-vscode-environment.d.ts +0 -2
- package/lib/testRunner/jest-vscode-environment.d.ts.map +0 -1
- package/lib/testRunner/jest-vscode-environment.js +0 -19
- package/lib/testRunner/jest-vscode-environment.js.map +0 -1
- package/lib/testRunner/jest-vscode-framework-setup.d.ts +0 -1
- package/lib/testRunner/jest-vscode-framework-setup.d.ts.map +0 -1
- package/lib/testRunner/jest-vscode-framework-setup.js +0 -3
- package/lib/testRunner/jest-vscode-framework-setup.js.map +0 -1
- package/lib/testRunner/vscode-test-script.d.ts +0 -2
- package/lib/testRunner/vscode-test-script.d.ts.map +0 -1
- package/lib/testRunner/vscode-test-script.js +0 -23
- package/lib/testRunner/vscode-test-script.js.map +0 -1
- package/lib/utils.d.ts +0 -18
- package/lib/utils.d.ts.map +0 -1
- package/lib/utils.js +0 -52
- package/lib/utils.js.map +0 -1
- package/src/testRunner/README.md +0 -23
- package/src/testRunner/index.ts +0 -72
- package/src/testRunner/jest-config.ts +0 -17
- package/src/testRunner/jest-vscode-environment.ts +0 -25
- package/src/testRunner/jest-vscode-framework-setup.ts +0 -10
- package/src/testRunner/jest.d.ts +0 -37
- package/src/testRunner/vscode-test-script.ts +0 -38
- package/tsconfig.test.json +0 -4
- package/tsconfig.tsbuildinfo +0 -2486
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ClientConfig, parseApolloConfig } from "../";
|
|
2
|
+
import { URI } from "vscode-uri";
|
|
3
|
+
|
|
4
|
+
describe("ApolloConfig", () => {
|
|
5
|
+
describe("confifDirURI", () => {
|
|
6
|
+
it("properly parses dir paths for configDirURI", () => {
|
|
7
|
+
const uri = URI.parse("/test/dir/name");
|
|
8
|
+
const config = parseApolloConfig({ client: { service: "hai" } }, uri);
|
|
9
|
+
// can be either /test/dir/name or \\test\\dir\\name depending on platform
|
|
10
|
+
// this difference is fine :)
|
|
11
|
+
expect(config?.configDirURI?.fsPath).toMatch(
|
|
12
|
+
/\/test\/dir\/name|\\test\\dir\\name/,
|
|
13
|
+
);
|
|
14
|
+
});
|
|
15
|
+
it("properly parses filepaths for configDirURI", () => {
|
|
16
|
+
const uri = URI.parse("/test/dir/name/apollo.config.js");
|
|
17
|
+
const config = parseApolloConfig(
|
|
18
|
+
{
|
|
19
|
+
client: { service: "hai" },
|
|
20
|
+
},
|
|
21
|
+
uri,
|
|
22
|
+
);
|
|
23
|
+
// can be either /test/dir/name or \\test\\dir\\name depending on platform
|
|
24
|
+
// this difference is fine :)
|
|
25
|
+
expect(config?.configDirURI?.fsPath).toMatch(
|
|
26
|
+
/\/test\/dir\/name|\\test\\dir\\name/,
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe("variant", () => {
|
|
32
|
+
it("gets default variant when none is set", () => {
|
|
33
|
+
const config = parseApolloConfig({
|
|
34
|
+
client: { service: "hai" },
|
|
35
|
+
});
|
|
36
|
+
expect(config?.variant).toEqual("current");
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("gets variant from service specifier", () => {
|
|
40
|
+
const config = parseApolloConfig({
|
|
41
|
+
client: { service: "hai@master" },
|
|
42
|
+
});
|
|
43
|
+
expect(config?.variant).toEqual("master");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("can set and override variants", () => {
|
|
47
|
+
const config = parseApolloConfig({
|
|
48
|
+
client: { service: "hai@master" },
|
|
49
|
+
});
|
|
50
|
+
config!.variant = "new";
|
|
51
|
+
expect(config?.variant).toEqual("new");
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
let { loadConfig } = require("../");
|
|
2
|
+
let { ClientConfig, RoverConfig } = require("../config");
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import * as fs from "fs";
|
|
5
|
+
|
|
6
|
+
async function withFeatureFlags(flags: string, fn: () => void) {
|
|
7
|
+
const FF = process.env.APOLLO_FEATURE_FLAGS;
|
|
8
|
+
try {
|
|
9
|
+
process.env.APOLLO_FEATURE_FLAGS = flags;
|
|
10
|
+
jest.resetModules();
|
|
11
|
+
({ loadConfig } = require("../"));
|
|
12
|
+
({ ClientConfig, RoverConfig } = require("../config"));
|
|
13
|
+
return await fn();
|
|
14
|
+
} finally {
|
|
15
|
+
process.env.APOLLO_FEATURE_FLAGS = FF;
|
|
16
|
+
jest.resetModules();
|
|
17
|
+
({ loadConfig } = require("../"));
|
|
18
|
+
({ ClientConfig, RoverConfig } = require("../config"));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const makeNestedDir = (dir: string) => {
|
|
23
|
+
if (fs.existsSync(dir)) return;
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
fs.mkdirSync(dir);
|
|
27
|
+
} catch (err: any) {
|
|
28
|
+
if (err.code == "ENOENT") {
|
|
29
|
+
makeNestedDir(path.dirname(dir)); //create parent dir
|
|
30
|
+
makeNestedDir(dir); //create dir
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const deleteFolderRecursive = (path: string) => {
|
|
36
|
+
// don't delete files on windows -- will get a resource locked error
|
|
37
|
+
if (require("os").type().includes("Windows")) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (fs.existsSync(path)) {
|
|
42
|
+
fs.readdirSync(path).forEach(function (file, index) {
|
|
43
|
+
var curPath = path + "/" + file;
|
|
44
|
+
if (fs.lstatSync(curPath).isDirectory()) {
|
|
45
|
+
// recurse
|
|
46
|
+
deleteFolderRecursive(curPath);
|
|
47
|
+
} else {
|
|
48
|
+
// delete file
|
|
49
|
+
fs.unlinkSync(curPath);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
fs.rmdirSync(path);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const writeFilesToDir = (dir: string, files: Record<string, string>) => {
|
|
57
|
+
Object.keys(files).forEach((key) => {
|
|
58
|
+
if (key.includes("/")) makeNestedDir(path.dirname(key));
|
|
59
|
+
fs.writeFileSync(`${dir}/${key}`, files[key]);
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
describe("loadConfig", () => {
|
|
64
|
+
let dir: string;
|
|
65
|
+
let dirPath: string;
|
|
66
|
+
|
|
67
|
+
// set up a temp dir
|
|
68
|
+
beforeEach(() => {
|
|
69
|
+
dir = fs.mkdtempSync("__tmp__");
|
|
70
|
+
dirPath = `${process.cwd()}/${dir}`;
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// clean up our temp dir
|
|
74
|
+
afterEach(() => {
|
|
75
|
+
if (dir) {
|
|
76
|
+
deleteFolderRecursive(dir);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
describe("finding files", () => {
|
|
81
|
+
it("loads with client defaults from different dir", async () => {
|
|
82
|
+
writeFilesToDir(dir, {
|
|
83
|
+
"apollo.config.js": `
|
|
84
|
+
module.exports = {
|
|
85
|
+
client: {
|
|
86
|
+
service: 'hello'
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
`,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const config = await loadConfig({
|
|
93
|
+
configPath: dirPath,
|
|
94
|
+
});
|
|
95
|
+
expect(config?.rawConfig).toMatchInlineSnapshot(`
|
|
96
|
+
Object {
|
|
97
|
+
"client": Object {
|
|
98
|
+
"excludes": Array [
|
|
99
|
+
"**/node_modules",
|
|
100
|
+
"**/__tests__",
|
|
101
|
+
],
|
|
102
|
+
"includes": Array [
|
|
103
|
+
"src/**/*.{ts,tsx,js,jsx,graphql,gql}",
|
|
104
|
+
],
|
|
105
|
+
"service": "hello",
|
|
106
|
+
"tagName": "gql",
|
|
107
|
+
},
|
|
108
|
+
"engine": Object {
|
|
109
|
+
"endpoint": "https://graphql.api.apollographql.com/api/graphql",
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
`);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("loads with rover defaults from different dir", () =>
|
|
116
|
+
withFeatureFlags("rover", async () => {
|
|
117
|
+
writeFilesToDir(dir, {
|
|
118
|
+
"apollo.config.js": `
|
|
119
|
+
module.exports = {
|
|
120
|
+
rover: {
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
`,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const config = await loadConfig({
|
|
127
|
+
configPath: dirPath,
|
|
128
|
+
});
|
|
129
|
+
expect(config?.rawConfig).toMatchInlineSnapshot(`
|
|
130
|
+
Object {
|
|
131
|
+
"engine": Object {
|
|
132
|
+
"endpoint": "https://graphql.api.apollographql.com/api/graphql",
|
|
133
|
+
},
|
|
134
|
+
"rover": Object {},
|
|
135
|
+
}
|
|
136
|
+
`);
|
|
137
|
+
}));
|
|
138
|
+
|
|
139
|
+
it("[deprecated] loads config from package.json", async () => {
|
|
140
|
+
writeFilesToDir(dir, {
|
|
141
|
+
"package.json": `{"apollo":{"client": {"service": "hello"}} }`,
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// silence the warning
|
|
145
|
+
const spy = jest.spyOn(console, "warn");
|
|
146
|
+
spy.mockImplementationOnce(() => {});
|
|
147
|
+
|
|
148
|
+
const config = await loadConfig({ configPath: dirPath });
|
|
149
|
+
|
|
150
|
+
spy.mockRestore();
|
|
151
|
+
expect(config?.client?.service).toEqual("hello");
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it("loads config from a ts file", async () => {
|
|
155
|
+
writeFilesToDir(dir, {
|
|
156
|
+
"apollo.config.ts": `export default {"client": {"service": "hello"} }`,
|
|
157
|
+
});
|
|
158
|
+
const config = await loadConfig({ configPath: dirPath });
|
|
159
|
+
expect(config?.client?.service).toEqual("hello");
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
describe("errors", () => {
|
|
164
|
+
it("throws when config file is empty", async () => {
|
|
165
|
+
writeFilesToDir(dir, { "apollo.config.js": `` });
|
|
166
|
+
|
|
167
|
+
const spy = jest.spyOn(console, "error");
|
|
168
|
+
// use this to keep the log quiet
|
|
169
|
+
spy.mockImplementation();
|
|
170
|
+
|
|
171
|
+
await loadConfig({
|
|
172
|
+
configPath: dirPath,
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
expect(spy).toHaveBeenCalledWith(
|
|
176
|
+
expect.stringMatching(/config file failed to load/i),
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
spy.mockRestore();
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it("throws when explorer.search fails", async () => {
|
|
183
|
+
writeFilesToDir(dir, { "apollo.config.js": `* 98375^%*&^ its lit` });
|
|
184
|
+
|
|
185
|
+
const error = await loadConfig({
|
|
186
|
+
configPath: dirPath,
|
|
187
|
+
}).catch((e: any) => e);
|
|
188
|
+
|
|
189
|
+
expect(error.message).toMatch(/config file failed to load/i);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it("issues a deprecation warning when loading config from package.json", async () => {
|
|
193
|
+
const spy = jest.spyOn(console, "warn");
|
|
194
|
+
spy.mockImplementation();
|
|
195
|
+
|
|
196
|
+
writeFilesToDir(dir, {
|
|
197
|
+
"package.json": `{"apollo":{"client": {"service": "hello"}} }`,
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
await loadConfig({
|
|
201
|
+
configPath: dirPath,
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
expect(spy).toHaveBeenCalledWith(
|
|
205
|
+
expect.stringMatching(/The "apollo" package.json configuration/i),
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
spy.mockRestore();
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it("throws if a config file was expected but not found", async () => {
|
|
212
|
+
const spy = jest.spyOn(console, "error");
|
|
213
|
+
spy.mockImplementation();
|
|
214
|
+
|
|
215
|
+
writeFilesToDir(dir, { "foo.config.js": `module.exports = {}` });
|
|
216
|
+
|
|
217
|
+
await loadConfig({
|
|
218
|
+
configPath: dirPath,
|
|
219
|
+
requireConfig: true, // this is what we're testing
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
expect(spy).toHaveBeenCalledWith(
|
|
223
|
+
expect.stringMatching(/no apollo config/i),
|
|
224
|
+
);
|
|
225
|
+
spy.mockRestore();
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it("throws if project type cant be resolved", async () => {
|
|
229
|
+
writeFilesToDir(dir, {
|
|
230
|
+
"apollo.config.js": `module.exports = {}`,
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
const error = await loadConfig({
|
|
234
|
+
configPath: dirPath,
|
|
235
|
+
}).catch((e: any) => e);
|
|
236
|
+
|
|
237
|
+
expect(error.message).toMatch(
|
|
238
|
+
/Config needs to contain a 'client' field./i,
|
|
239
|
+
);
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
describe("env loading", () => {
|
|
244
|
+
it("finds .env in config path & parses for key", async () => {
|
|
245
|
+
writeFilesToDir(dir, {
|
|
246
|
+
"apollo.config.js": `module.exports = { client: { name: 'hello' } }`,
|
|
247
|
+
".env": `APOLLO_KEY=service:harambe:54378950jn`,
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
const config = await loadConfig({
|
|
251
|
+
configPath: dirPath,
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
expect(config?.client?.service).toEqual("harambe");
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it("finds .env.local in config path & parses for key", async () => {
|
|
258
|
+
writeFilesToDir(dir, {
|
|
259
|
+
"apollo.config.js": `module.exports = { client: { name: 'hello' } }`,
|
|
260
|
+
".env.local": `APOLLO_KEY=service:harambe:54378950jn`,
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
const config = await loadConfig({
|
|
264
|
+
configPath: dirPath,
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
expect(config?.client?.service).toEqual("harambe");
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it("finds .env and .env.local in config path & parses for key, preferring .env.local", async () => {
|
|
271
|
+
writeFilesToDir(dir, {
|
|
272
|
+
"apollo.config.js": `module.exports = { client: { name: 'hello' } }`,
|
|
273
|
+
".env": `APOLLO_KEY=service:hamato:54378950jn`,
|
|
274
|
+
".env.local": `APOLLO_KEY=service:yoshi:65489061ko`,
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
const config = await loadConfig({
|
|
278
|
+
configPath: dirPath,
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
expect(config?.client?.service).toEqual("yoshi");
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
// this doesn't work right now :)
|
|
285
|
+
it.skip("finds .env in cwd & parses for key", async () => {
|
|
286
|
+
writeFilesToDir(dir, {
|
|
287
|
+
"dir/apollo.config.js": `module.exports = { client: { name: 'hello' } }`,
|
|
288
|
+
".env": `APOLLO_KEY=service:harambe:54378950jn`,
|
|
289
|
+
});
|
|
290
|
+
process.chdir(dir);
|
|
291
|
+
const config = await loadConfig({
|
|
292
|
+
configPath: "dir/",
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
process.chdir("../");
|
|
296
|
+
expect(config?.client?.service).toEqual("harambe");
|
|
297
|
+
});
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
describe("project type", () => {
|
|
301
|
+
it("infers client projects from config", async () => {
|
|
302
|
+
writeFilesToDir(dir, {
|
|
303
|
+
"apollo.config.js": `module.exports = { client: { service: 'hello' } }`,
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
const config = await loadConfig({
|
|
307
|
+
configPath: dirPath,
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
expect(config).toBeInstanceOf(ClientConfig);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it("infers rover projects from config", () =>
|
|
314
|
+
withFeatureFlags("rover", async () => {
|
|
315
|
+
writeFilesToDir(dir, {
|
|
316
|
+
"apollo.config.js": `module.exports = { rover: {} }`,
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
const config = await loadConfig({
|
|
320
|
+
configPath: dirPath,
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
expect(config).toBeInstanceOf(RoverConfig);
|
|
324
|
+
}));
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
describe("service name", () => {
|
|
328
|
+
it("lets config service name take precedence for client project", async () => {
|
|
329
|
+
writeFilesToDir(dir, {
|
|
330
|
+
"apollo.config.js": `module.exports = { client: { service: 'hello' } }`,
|
|
331
|
+
".env": `APOLLO_KEY=service:harambe:54378950jn`,
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
const config = await loadConfig({
|
|
335
|
+
configPath: dirPath,
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
expect(config?.client?.service).toEqual("hello");
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
it("uses env var to determine service name when no other options", async () => {
|
|
342
|
+
writeFilesToDir(dir, {
|
|
343
|
+
"apollo.config.js": `module.exports = { client: { } }`,
|
|
344
|
+
".env": `APOLLO_KEY=service:harambe:54378950jn`,
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
const config = await loadConfig({
|
|
348
|
+
configPath: dirPath,
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
expect(config?.client?.service).toEqual("harambe");
|
|
352
|
+
});
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
describe("default merging", () => {
|
|
356
|
+
it("merges service name and default config for client projects", async () => {
|
|
357
|
+
writeFilesToDir(dir, {
|
|
358
|
+
"apollo.config.js": `module.exports = { client: { service: 'hello' } }`,
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
const config = await loadConfig({
|
|
362
|
+
configPath: dirPath,
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
expect((config?.rawConfig as any).client.includes).toEqual([
|
|
366
|
+
"src/**/*.{ts,tsx,js,jsx,graphql,gql}",
|
|
367
|
+
]);
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
it("merges engine config defaults", async () => {
|
|
371
|
+
writeFilesToDir(dir, {
|
|
372
|
+
"apollo.config.js": `module.exports = { client: { service: 'wow' } }`,
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
const config = await loadConfig({
|
|
376
|
+
configPath: dirPath,
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
expect(config?.rawConfig?.engine?.endpoint).toEqual(
|
|
380
|
+
"https://graphql.api.apollographql.com/api/graphql",
|
|
381
|
+
);
|
|
382
|
+
});
|
|
383
|
+
});
|
|
384
|
+
});
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getServiceFromKey,
|
|
3
|
+
getGraphIdFromConfig,
|
|
4
|
+
isClientConfig,
|
|
5
|
+
isLocalServiceConfig,
|
|
6
|
+
parseServiceSpecifier,
|
|
7
|
+
parseApolloConfig,
|
|
8
|
+
configSchema,
|
|
9
|
+
} from "../";
|
|
10
|
+
|
|
11
|
+
describe("getServiceFromKey", () => {
|
|
12
|
+
it("returns undefined with no provided key", () => {
|
|
13
|
+
expect(getServiceFromKey()).toBeUndefined();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("returns service name from service api key", () => {
|
|
17
|
+
const key = "service:bob-123:489fhseo4";
|
|
18
|
+
expect(getServiceFromKey(key)).toEqual("bob-123");
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("returns nothing if key is not a service key", () => {
|
|
22
|
+
const key = "not-a-service:bob-123:489fhseo4";
|
|
23
|
+
expect(getServiceFromKey(key)).toBeUndefined();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("returns nothing if key is malformed", () => {
|
|
27
|
+
const key = "service/bob-123:489fhseo4";
|
|
28
|
+
expect(getServiceFromKey(key)).toBeUndefined();
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe("getServiceName", () => {
|
|
33
|
+
describe("client config", () => {
|
|
34
|
+
it("finds service name when client.service is a string", () => {
|
|
35
|
+
const rawConfig = configSchema.parse({
|
|
36
|
+
client: { service: "my-service" },
|
|
37
|
+
});
|
|
38
|
+
expect(getGraphIdFromConfig(rawConfig)).toEqual("my-service");
|
|
39
|
+
|
|
40
|
+
const rawConfigWithTag = configSchema.parse({
|
|
41
|
+
client: { service: "my-service@master" },
|
|
42
|
+
});
|
|
43
|
+
expect(getGraphIdFromConfig(rawConfigWithTag)).toEqual("my-service");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("finds service name when client.service is an object", () => {
|
|
47
|
+
const rawConfig = configSchema.parse({
|
|
48
|
+
client: {
|
|
49
|
+
service: { name: "my-service", localSchemaFile: "./someFile" },
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
expect(getGraphIdFromConfig(rawConfig)).toEqual("my-service");
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
describe("service config", () => {
|
|
56
|
+
it("finds service name from raw service config", () => {
|
|
57
|
+
const rawConfig = configSchema.parse({
|
|
58
|
+
client: {
|
|
59
|
+
service: {
|
|
60
|
+
name: "my-service",
|
|
61
|
+
localSchemaFile: "./someFile",
|
|
62
|
+
},
|
|
63
|
+
includes: [],
|
|
64
|
+
excludes: [],
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
expect(getGraphIdFromConfig(rawConfig)).toEqual("my-service");
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe("isClientConfig", () => {
|
|
73
|
+
it("identifies client config properly", () => {
|
|
74
|
+
const config = parseApolloConfig({
|
|
75
|
+
client: { service: "hello" },
|
|
76
|
+
});
|
|
77
|
+
expect(isClientConfig(config!)).toBeTruthy();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe("isLocalServiceConfig", () => {
|
|
82
|
+
it("properly identifies a client config that uses localSchemaFiles", () => {
|
|
83
|
+
const clientServiceConfig = { name: "my-service", localSchemaFile: "okay" };
|
|
84
|
+
expect(isLocalServiceConfig(clientServiceConfig)).toBeTruthy();
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
describe("parseServiceSpecifier", () => {
|
|
89
|
+
it("parses service identifier for service id and tag properly", () => {
|
|
90
|
+
const [id, tag] = parseServiceSpecifier("my-service@master");
|
|
91
|
+
expect(id).toEqual("my-service");
|
|
92
|
+
expect(tag).toEqual("master");
|
|
93
|
+
|
|
94
|
+
const [idFromSimpleName, tagFromSimpleName] =
|
|
95
|
+
parseServiceSpecifier("my-service");
|
|
96
|
+
expect(idFromSimpleName).toEqual("my-service");
|
|
97
|
+
expect(tagFromSimpleName).toBeUndefined();
|
|
98
|
+
});
|
|
99
|
+
});
|