vscode-apollo 1.19.3 → 1.20.1
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 +82 -0
- package/.eslintrc.js +10 -0
- package/.gitattributes +1 -0
- package/.github/workflows/build-prs.yml +57 -0
- package/.github/workflows/release.yml +114 -0
- package/.gitleaks.toml +26 -0
- package/.nvmrc +1 -0
- package/.prettierrc +5 -0
- package/.vscode/launch.json +61 -0
- package/.vscode/settings.json +16 -0
- package/.vscode/tasks.json +18 -0
- package/.vscodeignore +17 -1
- package/CHANGELOG.md +178 -1
- package/LICENSE +2 -2
- package/README.md +9 -9
- package/codegen.yml +12 -0
- package/images/IconRun.svg +8 -0
- package/jest.config.ts +11 -0
- package/package.json +102 -22
- package/renovate.json +23 -0
- package/src/__mocks__/fs.js +3 -0
- package/src/__tests__/statusBar.test.ts +8 -7
- package/src/debug.ts +2 -5
- package/src/env/fetch/fetch.ts +32 -0
- package/src/env/fetch/global.ts +30 -0
- package/src/env/fetch/index.d.ts +2 -0
- package/src/env/fetch/index.ts +2 -0
- package/src/env/fetch/url.ts +9 -0
- package/src/env/index.ts +4 -0
- package/src/env/polyfills/array.ts +17 -0
- package/src/env/polyfills/index.ts +2 -0
- package/src/env/polyfills/object.ts +7 -0
- package/src/env/typescript-utility-types.ts +2 -0
- package/src/extension.ts +106 -37
- 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 +128 -0
- package/src/language-server/config/__tests__/loadConfig.ts +508 -0
- package/src/language-server/config/__tests__/utils.ts +106 -0
- package/src/language-server/config/config.ts +219 -0
- package/src/language-server/config/index.ts +3 -0
- package/src/language-server/config/loadConfig.ts +228 -0
- package/src/language-server/config/utils.ts +56 -0
- package/src/language-server/diagnostics.ts +109 -0
- package/src/language-server/document.ts +277 -0
- package/src/language-server/engine/GraphQLDataSource.ts +124 -0
- package/src/language-server/engine/index.ts +105 -0
- package/src/language-server/engine/operations/frontendUrlRoot.ts +7 -0
- package/src/language-server/engine/operations/schemaTagsAndFieldStats.ts +24 -0
- package/src/language-server/errors/__tests__/NoMissingClientDirectives.test.ts +220 -0
- package/src/language-server/errors/logger.ts +58 -0
- package/src/language-server/errors/validation.ts +277 -0
- package/src/language-server/fileSet.ts +65 -0
- package/src/language-server/format.ts +48 -0
- package/src/language-server/graphqlTypes.ts +7176 -0
- package/src/language-server/index.ts +29 -0
- package/src/language-server/languageProvider.ts +798 -0
- package/src/language-server/loadingHandler.ts +64 -0
- package/src/language-server/project/base.ts +399 -0
- package/src/language-server/project/client.ts +602 -0
- package/src/language-server/project/defaultClientSchema.ts +45 -0
- package/src/language-server/project/service.ts +48 -0
- package/src/language-server/providers/schema/__tests__/file.ts +150 -0
- package/src/language-server/providers/schema/base.ts +15 -0
- package/src/language-server/providers/schema/endpoint.ts +157 -0
- package/src/language-server/providers/schema/engine.ts +197 -0
- package/src/language-server/providers/schema/file.ts +167 -0
- package/src/language-server/providers/schema/index.ts +75 -0
- package/src/language-server/server.ts +252 -0
- package/src/language-server/typings/codemirror.d.ts +4 -0
- package/src/language-server/typings/graphql.d.ts +27 -0
- package/src/language-server/utilities/__tests__/graphql.test.ts +411 -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 +89 -0
- package/src/language-server/utilities/graphql.ts +432 -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 +262 -0
- package/src/languageServerClient.ts +19 -12
- package/src/messages.ts +84 -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 +1 -16
- 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 +4 -0
- package/tsconfig.json +20 -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,128 @@
|
|
|
1
|
+
import { ApolloConfig, ApolloConfigFormat, DefaultConfigBase } 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 = new ApolloConfig(
|
|
9
|
+
{ service: { name: "hai", ...DefaultConfigBase } },
|
|
10
|
+
uri
|
|
11
|
+
);
|
|
12
|
+
// can be either /test/dir/name or \\test\\dir\\name depending on platform
|
|
13
|
+
// this difference is fine :)
|
|
14
|
+
expect(config.configDirURI?.fsPath).toMatch(
|
|
15
|
+
/\/test\/dir\/name|\\test\\dir\\name/
|
|
16
|
+
);
|
|
17
|
+
});
|
|
18
|
+
it("properly parses filepaths for configDirURI", () => {
|
|
19
|
+
const uri = URI.parse("/test/dir/name/apollo.config.js");
|
|
20
|
+
const config = new ApolloConfig(
|
|
21
|
+
{ service: { name: "hai", ...DefaultConfigBase } },
|
|
22
|
+
uri
|
|
23
|
+
);
|
|
24
|
+
// can be either /test/dir/name or \\test\\dir\\name depending on platform
|
|
25
|
+
// this difference is fine :)
|
|
26
|
+
expect(config.configDirURI?.fsPath).toMatch(
|
|
27
|
+
/\/test\/dir\/name|\\test\\dir\\name/
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe("projects", () => {
|
|
33
|
+
it("creates a ClientConfig when client is present", () => {
|
|
34
|
+
const rawConfig: ApolloConfigFormat = {
|
|
35
|
+
client: { service: "my-service", ...DefaultConfigBase },
|
|
36
|
+
};
|
|
37
|
+
const config = new ApolloConfig(rawConfig);
|
|
38
|
+
const projects = config.projects;
|
|
39
|
+
expect(projects).toHaveLength(1);
|
|
40
|
+
expect(projects[0].isClient).toBeTruthy();
|
|
41
|
+
});
|
|
42
|
+
it("creates a ServiceConfig when service is present", () => {
|
|
43
|
+
const rawConfig: ApolloConfigFormat = {
|
|
44
|
+
service: { name: "my-service", ...DefaultConfigBase },
|
|
45
|
+
};
|
|
46
|
+
const config = new ApolloConfig(rawConfig);
|
|
47
|
+
const projects = config.projects;
|
|
48
|
+
|
|
49
|
+
expect(projects).toHaveLength(1);
|
|
50
|
+
expect(projects[0].isService).toBeTruthy();
|
|
51
|
+
});
|
|
52
|
+
it("creates multiple configs when both client and service are present", () => {
|
|
53
|
+
const rawConfig: ApolloConfigFormat = {
|
|
54
|
+
client: { service: "my-service", ...DefaultConfigBase },
|
|
55
|
+
service: { name: "my-service", ...DefaultConfigBase },
|
|
56
|
+
};
|
|
57
|
+
const config = new ApolloConfig(rawConfig);
|
|
58
|
+
const projects = config.projects;
|
|
59
|
+
|
|
60
|
+
expect(projects).toHaveLength(2);
|
|
61
|
+
expect(projects.find((c) => c.isClient)).toBeTruthy();
|
|
62
|
+
expect(projects.find((c) => c.isService)).toBeTruthy();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
describe("variant", () => {
|
|
67
|
+
it("gets default variant when none is set", () => {
|
|
68
|
+
const config = new ApolloConfig({
|
|
69
|
+
client: { service: "hai", ...DefaultConfigBase },
|
|
70
|
+
});
|
|
71
|
+
expect(config.variant).toEqual("current");
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("gets variant from service specifier", () => {
|
|
75
|
+
const config = new ApolloConfig({
|
|
76
|
+
client: { service: "hai@master", ...DefaultConfigBase },
|
|
77
|
+
});
|
|
78
|
+
expect(config.variant).toEqual("master");
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("can set and override variants", () => {
|
|
82
|
+
const config = new ApolloConfig({
|
|
83
|
+
client: { service: "hai@master", ...DefaultConfigBase },
|
|
84
|
+
});
|
|
85
|
+
config.variant = "new";
|
|
86
|
+
expect(config.variant).toEqual("new");
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe("setDefaults", () => {
|
|
91
|
+
it("can override engine defaults", () => {
|
|
92
|
+
const config = new ApolloConfig({ client: { ...DefaultConfigBase } });
|
|
93
|
+
const overrides = {
|
|
94
|
+
engine: {
|
|
95
|
+
endpoint: "https://test.apollographql.com/api/graphql",
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
config.setDefaults(overrides);
|
|
99
|
+
expect(config.engine).toEqual(overrides.engine);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("can override client defaults", () => {
|
|
103
|
+
const config = new ApolloConfig({ client: { ...DefaultConfigBase } });
|
|
104
|
+
const overrides = {
|
|
105
|
+
client: {
|
|
106
|
+
name: "my-client",
|
|
107
|
+
service: "my-service@master",
|
|
108
|
+
...DefaultConfigBase,
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
config.setDefaults(overrides);
|
|
112
|
+
expect(config.client).toEqual(overrides.client);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("can override service defaults", () => {
|
|
116
|
+
const config = new ApolloConfig({ client: { ...DefaultConfigBase } });
|
|
117
|
+
const overrides = {
|
|
118
|
+
service: {
|
|
119
|
+
name: "my-service",
|
|
120
|
+
url: "localhost:9090",
|
|
121
|
+
...DefaultConfigBase,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
config.setDefaults(overrides);
|
|
125
|
+
expect(config.service).toEqual(config.service);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
});
|
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
import { loadConfig } from "../";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import * as fs from "fs";
|
|
4
|
+
import {
|
|
5
|
+
DefaultClientConfig,
|
|
6
|
+
DefaultServiceConfig,
|
|
7
|
+
DefaultEngineConfig,
|
|
8
|
+
} from "../config";
|
|
9
|
+
import { Debug } from "../../utilities";
|
|
10
|
+
|
|
11
|
+
const makeNestedDir = (dir: string) => {
|
|
12
|
+
if (fs.existsSync(dir)) return;
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
fs.mkdirSync(dir);
|
|
16
|
+
} catch (err) {
|
|
17
|
+
if (err.code == "ENOENT") {
|
|
18
|
+
makeNestedDir(path.dirname(dir)); //create parent dir
|
|
19
|
+
makeNestedDir(dir); //create dir
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const deleteFolderRecursive = (path: string) => {
|
|
25
|
+
// don't delete files on windows -- will get a resource locked error
|
|
26
|
+
if (require("os").type().includes("Windows")) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (fs.existsSync(path)) {
|
|
31
|
+
fs.readdirSync(path).forEach(function (file, index) {
|
|
32
|
+
var curPath = path + "/" + file;
|
|
33
|
+
if (fs.lstatSync(curPath).isDirectory()) {
|
|
34
|
+
// recurse
|
|
35
|
+
deleteFolderRecursive(curPath);
|
|
36
|
+
} else {
|
|
37
|
+
// delete file
|
|
38
|
+
fs.unlinkSync(curPath);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
fs.rmdirSync(path);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const writeFilesToDir = (dir: string, files: Record<string, string>) => {
|
|
46
|
+
Object.keys(files).forEach((key) => {
|
|
47
|
+
if (key.includes("/")) makeNestedDir(path.dirname(key));
|
|
48
|
+
fs.writeFileSync(`${dir}/${key}`, files[key]);
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
describe("loadConfig", () => {
|
|
53
|
+
let dir: string;
|
|
54
|
+
let dirPath: string;
|
|
55
|
+
|
|
56
|
+
// set up a temp dir
|
|
57
|
+
beforeEach(() => {
|
|
58
|
+
dir = fs.mkdtempSync("__tmp__");
|
|
59
|
+
dirPath = `${process.cwd()}/${dir}`;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// clean up our temp dir
|
|
63
|
+
afterEach(() => {
|
|
64
|
+
if (dir) {
|
|
65
|
+
deleteFolderRecursive(dir);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
describe("finding files", () => {
|
|
70
|
+
it("loads with client defaults from different dir", async () => {
|
|
71
|
+
writeFilesToDir(dir, {
|
|
72
|
+
"my.config.js": `
|
|
73
|
+
module.exports = {
|
|
74
|
+
client: {
|
|
75
|
+
service: 'hello'
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
`,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const config = await loadConfig({
|
|
82
|
+
configPath: dirPath,
|
|
83
|
+
configFileName: "my.config.js",
|
|
84
|
+
});
|
|
85
|
+
expect(config?.rawConfig).toMatchInlineSnapshot(`
|
|
86
|
+
Object {
|
|
87
|
+
"client": Object {
|
|
88
|
+
"addTypename": true,
|
|
89
|
+
"clientOnlyDirectives": Array [
|
|
90
|
+
"connection",
|
|
91
|
+
"type",
|
|
92
|
+
],
|
|
93
|
+
"clientSchemaDirectives": Array [
|
|
94
|
+
"client",
|
|
95
|
+
"rest",
|
|
96
|
+
],
|
|
97
|
+
"excludes": Array [
|
|
98
|
+
"**/node_modules",
|
|
99
|
+
"**/__tests__",
|
|
100
|
+
],
|
|
101
|
+
"includes": Array [
|
|
102
|
+
"src/**/*.{ts,tsx,js,jsx,graphql,gql}",
|
|
103
|
+
],
|
|
104
|
+
"service": "hello",
|
|
105
|
+
"statsWindow": Object {
|
|
106
|
+
"from": -86400,
|
|
107
|
+
"to": -0,
|
|
108
|
+
},
|
|
109
|
+
"tagName": "gql",
|
|
110
|
+
},
|
|
111
|
+
"engine": Object {
|
|
112
|
+
"endpoint": "https://graphql.api.apollographql.com/api/graphql",
|
|
113
|
+
},
|
|
114
|
+
}
|
|
115
|
+
`);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("loads with service defaults from different dir", async () => {
|
|
119
|
+
writeFilesToDir(dir, {
|
|
120
|
+
"my.config.js": `
|
|
121
|
+
module.exports = {
|
|
122
|
+
service: {
|
|
123
|
+
name: 'hello'
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
`,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
const config = await loadConfig({
|
|
130
|
+
configPath: dirPath,
|
|
131
|
+
configFileName: "my.config.js",
|
|
132
|
+
});
|
|
133
|
+
expect(config?.rawConfig).toMatchInlineSnapshot(`
|
|
134
|
+
Object {
|
|
135
|
+
"engine": Object {
|
|
136
|
+
"endpoint": "https://graphql.api.apollographql.com/api/graphql",
|
|
137
|
+
},
|
|
138
|
+
"service": Object {
|
|
139
|
+
"endpoint": Object {
|
|
140
|
+
"url": "http://localhost:4000/graphql",
|
|
141
|
+
},
|
|
142
|
+
"excludes": Array [
|
|
143
|
+
"**/node_modules",
|
|
144
|
+
"**/__tests__",
|
|
145
|
+
],
|
|
146
|
+
"includes": Array [
|
|
147
|
+
"src/**/*.{ts,tsx,js,jsx,graphql,gql}",
|
|
148
|
+
],
|
|
149
|
+
"name": "hello",
|
|
150
|
+
},
|
|
151
|
+
}
|
|
152
|
+
`);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it("[deprecated] loads config from package.json", async () => {
|
|
156
|
+
writeFilesToDir(dir, {
|
|
157
|
+
"package.json": `{"apollo":{"client": {"service": "hello"}} }`,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// silence the warning
|
|
161
|
+
const spy = jest.spyOn(console, "warn");
|
|
162
|
+
spy.mockImplementationOnce(() => {});
|
|
163
|
+
|
|
164
|
+
const config = await loadConfig({ configPath: dirPath });
|
|
165
|
+
|
|
166
|
+
spy.mockRestore();
|
|
167
|
+
expect(config?.client?.service).toEqual("hello");
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it("loads config from a ts file", async () => {
|
|
171
|
+
writeFilesToDir(dir, {
|
|
172
|
+
"apollo.config.ts": `module.exports = {"client": {"service": "hello"}`,
|
|
173
|
+
});
|
|
174
|
+
const config = await loadConfig({ configPath: dirPath });
|
|
175
|
+
|
|
176
|
+
expect(config?.client?.service).toEqual("hello");
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
describe("errors", () => {
|
|
181
|
+
it("throws when config file is empty", async () => {
|
|
182
|
+
writeFilesToDir(dir, { "my.config.js": `` });
|
|
183
|
+
|
|
184
|
+
const spy = jest.spyOn(console, "error");
|
|
185
|
+
// use this to keep the log quiet
|
|
186
|
+
spy.mockImplementation();
|
|
187
|
+
|
|
188
|
+
await loadConfig({
|
|
189
|
+
configPath: dirPath,
|
|
190
|
+
configFileName: "my.config.js",
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
expect(spy).toHaveBeenCalledWith(
|
|
194
|
+
expect.stringMatching(/config file failed to load/i)
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
spy.mockRestore();
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it("throws when explorer.search fails", async () => {
|
|
201
|
+
writeFilesToDir(dir, { "my.config.js": `* 98375^%*&^ its lit` });
|
|
202
|
+
|
|
203
|
+
const spy = jest.spyOn(console, "error");
|
|
204
|
+
// use this to keep the log quiet
|
|
205
|
+
spy.mockImplementation();
|
|
206
|
+
|
|
207
|
+
await loadConfig({
|
|
208
|
+
configPath: dirPath,
|
|
209
|
+
configFileName: "my.config.js",
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
expect(spy).toHaveBeenCalledWith(
|
|
213
|
+
expect.stringMatching(/config file failed to load/i)
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
spy.mockRestore();
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it("issues a deprecation warning when loading config from package.json", async () => {
|
|
220
|
+
const spy = jest.spyOn(console, "warn");
|
|
221
|
+
spy.mockImplementation();
|
|
222
|
+
|
|
223
|
+
writeFilesToDir(dir, {
|
|
224
|
+
"package.json": `{"apollo":{"client": {"service": "hello"}} }`,
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
await loadConfig({
|
|
228
|
+
configPath: dirPath,
|
|
229
|
+
configFileName: "package.json",
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
expect(spy).toHaveBeenCalledWith(
|
|
233
|
+
expect.stringMatching(/The "apollo" package.json configuration/i)
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
spy.mockRestore();
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it("throws if a config file was expected but not found", async () => {
|
|
240
|
+
const spy = jest.spyOn(console, "error");
|
|
241
|
+
spy.mockImplementation();
|
|
242
|
+
|
|
243
|
+
writeFilesToDir(dir, { "my.config.js": `module.exports = {}` });
|
|
244
|
+
|
|
245
|
+
await loadConfig({
|
|
246
|
+
configFileName: "my.TYPO.js",
|
|
247
|
+
requireConfig: true, // this is what we're testing
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
expect(spy).toHaveBeenCalledWith(
|
|
251
|
+
expect.stringMatching(/no apollo config/i)
|
|
252
|
+
);
|
|
253
|
+
spy.mockRestore();
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
it("throws if project type cant be resolved", async () => {
|
|
257
|
+
const spy = jest.spyOn(console, "error");
|
|
258
|
+
spy.mockImplementation();
|
|
259
|
+
|
|
260
|
+
writeFilesToDir(dir, {
|
|
261
|
+
"my.config.js": `module.exports = {}`,
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
await loadConfig({
|
|
265
|
+
configPath: dirPath,
|
|
266
|
+
configFileName: "my.config.js",
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
expect(spy).toHaveBeenCalledWith(
|
|
270
|
+
expect.stringMatching(/unable to resolve/i)
|
|
271
|
+
);
|
|
272
|
+
spy.mockRestore();
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
describe("env loading", () => {
|
|
277
|
+
it("finds .env in config path & parses for key", async () => {
|
|
278
|
+
writeFilesToDir(dir, {
|
|
279
|
+
"my.config.js": `module.exports = { client: { name: 'hello' } }`,
|
|
280
|
+
".env": `APOLLO_KEY=service:harambe:54378950jn`,
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
const config = await loadConfig({
|
|
284
|
+
configPath: dirPath,
|
|
285
|
+
configFileName: "my.config.js",
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
expect(config?.client?.service).toEqual("harambe");
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it("finds .env.local in config path & parses for key", async () => {
|
|
292
|
+
writeFilesToDir(dir, {
|
|
293
|
+
"my.config.js": `module.exports = { client: { name: 'hello' } }`,
|
|
294
|
+
".env.local": `APOLLO_KEY=service:harambe:54378950jn`,
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
const config = await loadConfig({
|
|
298
|
+
configPath: dirPath,
|
|
299
|
+
configFileName: "my.config.js",
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
expect(config?.client?.service).toEqual("harambe");
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it("finds .env and .env.local in config path & parses for key, preferring .env.local", async () => {
|
|
306
|
+
writeFilesToDir(dir, {
|
|
307
|
+
"my.config.js": `module.exports = { client: { name: 'hello' } }`,
|
|
308
|
+
".env": `APOLLO_KEY=service:hamato:54378950jn`,
|
|
309
|
+
".env.local": `APOLLO_KEY=service:yoshi:65489061ko`,
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
const config = await loadConfig({
|
|
313
|
+
configPath: dirPath,
|
|
314
|
+
configFileName: "my.config.js",
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
expect(config?.client?.service).toEqual("yoshi");
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
it("Allows setting ENGINE_API_KEY with a deprecation warning", async () => {
|
|
321
|
+
writeFilesToDir(dir, {
|
|
322
|
+
"my.config.js": `module.exports = { client: { name: 'hello' } }`,
|
|
323
|
+
".env.local": `ENGINE_API_KEY=service:yoshi:65489061ko`,
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
const spy = jest.spyOn(Debug, "warning");
|
|
327
|
+
|
|
328
|
+
const config = await loadConfig({
|
|
329
|
+
configPath: dirPath,
|
|
330
|
+
configFileName: "my.config.js",
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
expect(config?.client?.service).toEqual("yoshi");
|
|
334
|
+
expect(spy).toHaveBeenCalledWith(
|
|
335
|
+
expect.stringMatching(/Deprecation warning/i)
|
|
336
|
+
);
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
it("Uses new key when .env defined both legacy and new key", async () => {
|
|
340
|
+
writeFilesToDir(dir, {
|
|
341
|
+
"my.config.js": `module.exports = { client: { name: 'hello' } }`,
|
|
342
|
+
".env.local": `ENGINE_API_KEY=service:yoshi:65489061ko\nAPOLLO_KEY=service:yoshi:65489061ko`,
|
|
343
|
+
});
|
|
344
|
+
const spy = jest.spyOn(Debug, "warning");
|
|
345
|
+
|
|
346
|
+
const config = await loadConfig({
|
|
347
|
+
configPath: dirPath,
|
|
348
|
+
configFileName: "my.config.js",
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
expect(config?.engine.apiKey).toEqual("service:yoshi:65489061ko");
|
|
352
|
+
expect(spy).toHaveBeenCalledWith(
|
|
353
|
+
expect.stringMatching(/Both ENGINE_API_KEY and APOLLO_KEY were found/i)
|
|
354
|
+
);
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
// this doesn't work right now :)
|
|
358
|
+
xit("finds .env in cwd & parses for key", async () => {
|
|
359
|
+
writeFilesToDir(dir, {
|
|
360
|
+
"dir/my.config.js": `module.exports = { client: { name: 'hello' } }`,
|
|
361
|
+
".env": `APOLLO_KEY=service:harambe:54378950jn`,
|
|
362
|
+
});
|
|
363
|
+
process.chdir(dir);
|
|
364
|
+
const config = await loadConfig({
|
|
365
|
+
configPath: "dir/",
|
|
366
|
+
configFileName: "my.config.js",
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
process.chdir("../");
|
|
370
|
+
expect(config?.client?.service).toEqual("harambe");
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
describe("project type", () => {
|
|
375
|
+
it("uses passed in type when config doesnt have client/service", async () => {
|
|
376
|
+
writeFilesToDir(dir, {
|
|
377
|
+
"my.config.js": `module.exports = { engine: { endpoint: 'http://a.a' } }`,
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
const config = await loadConfig({
|
|
381
|
+
configPath: dirPath,
|
|
382
|
+
configFileName: "my.config.js",
|
|
383
|
+
type: "client",
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
expect(config?.isClient).toEqual(true);
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
it("infers client projects from config", async () => {
|
|
390
|
+
writeFilesToDir(dir, {
|
|
391
|
+
"my.config.js": `module.exports = { client: { service: 'hello' } }`,
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
const config = await loadConfig({
|
|
395
|
+
configPath: dirPath,
|
|
396
|
+
configFileName: "my.config.js",
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
expect(config?.isClient).toEqual(true);
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
it("infers service projects from config", async () => {
|
|
403
|
+
writeFilesToDir(dir, {
|
|
404
|
+
"my.config.js": `module.exports = { service: 'wow' }`,
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
const config = await loadConfig({
|
|
408
|
+
configPath: dirPath,
|
|
409
|
+
configFileName: "my.config.js",
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
expect(config?.isService).toEqual(true);
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
describe("service name", () => {
|
|
417
|
+
it("lets config service name take precedence for client project", async () => {
|
|
418
|
+
writeFilesToDir(dir, {
|
|
419
|
+
"my.config.js": `module.exports = { client: { service: 'hello' } }`,
|
|
420
|
+
".env": `APOLLO_KEY=service:harambe:54378950jn`,
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
const config = await loadConfig({
|
|
424
|
+
configPath: dirPath,
|
|
425
|
+
configFileName: "my.config.js",
|
|
426
|
+
name: "not-it",
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
expect(config?.client?.service).toEqual("hello");
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
it("lets name passed in take precedence over env var", async () => {
|
|
433
|
+
writeFilesToDir(dir, {
|
|
434
|
+
"my.config.js": `module.exports = { client: { } }`,
|
|
435
|
+
".env": `APOLLO_KEY=service:harambe:54378950jn`,
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
const config = await loadConfig({
|
|
439
|
+
configPath: dirPath,
|
|
440
|
+
configFileName: "my.config.js",
|
|
441
|
+
name: "hello",
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
expect(config?.client?.service).toEqual("hello");
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
it("uses env var to determine service name when no other options", async () => {
|
|
448
|
+
writeFilesToDir(dir, {
|
|
449
|
+
"my.config.js": `module.exports = { client: { } }`,
|
|
450
|
+
".env": `APOLLO_KEY=service:harambe:54378950jn`,
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
const config = await loadConfig({
|
|
454
|
+
configPath: dirPath,
|
|
455
|
+
configFileName: "my.config.js",
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
expect(config?.client?.service).toEqual("harambe");
|
|
459
|
+
});
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
describe("default merging", () => {
|
|
463
|
+
it("merges service name and default config for client projects", async () => {
|
|
464
|
+
writeFilesToDir(dir, {
|
|
465
|
+
"my.config.js": `module.exports = { client: { service: 'hello' } }`,
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
const config = await loadConfig({
|
|
469
|
+
configPath: dirPath,
|
|
470
|
+
configFileName: "my.config.js",
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
expect(config?.rawConfig?.client?.includes).toEqual(
|
|
474
|
+
DefaultClientConfig.includes
|
|
475
|
+
);
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
it("merges service name and default config for service projects", async () => {
|
|
479
|
+
writeFilesToDir(dir, {
|
|
480
|
+
"my.config.js": `module.exports = { service: { name: 'wow' } }`,
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
const config = await loadConfig({
|
|
484
|
+
configPath: dirPath,
|
|
485
|
+
configFileName: "my.config.js",
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
expect(config?.rawConfig?.service?.includes).toEqual(
|
|
489
|
+
DefaultServiceConfig.includes
|
|
490
|
+
);
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
it("merges engine config defaults", async () => {
|
|
494
|
+
writeFilesToDir(dir, {
|
|
495
|
+
"my.config.js": `module.exports = { client: { service: 'wow' } }`,
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
const config = await loadConfig({
|
|
499
|
+
configPath: dirPath,
|
|
500
|
+
configFileName: "my.config.js",
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
expect(config?.rawConfig?.engine?.endpoint).toEqual(
|
|
504
|
+
DefaultEngineConfig.endpoint
|
|
505
|
+
);
|
|
506
|
+
});
|
|
507
|
+
});
|
|
508
|
+
});
|