@apollo/client-ai-apps 0.3.2 → 0.4.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/.github/workflows/pr.yaml +52 -3
- package/.github/workflows/prep-release.yml +38 -0
- package/.github/workflows/release.yaml +8 -4
- package/.github/workflows/verify-changeset.yml +58 -0
- package/CHANGELOG.md +88 -0
- package/dist/core/ApolloClient.d.ts +3 -2
- package/dist/core/ApolloClient.d.ts.map +1 -0
- package/dist/core/ApolloClient.js +65 -0
- package/dist/core/ApolloClient.js.map +1 -0
- package/dist/index.d.ts +18 -18
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -279
- package/dist/index.js.map +1 -0
- package/dist/link/ToolCallLink.d.ts +1 -0
- package/dist/link/ToolCallLink.d.ts.map +1 -0
- package/dist/link/ToolCallLink.js +39 -0
- package/dist/link/ToolCallLink.js.map +1 -0
- package/dist/react/ApolloProvider.d.ts +4 -3
- package/dist/react/ApolloProvider.d.ts.map +1 -0
- package/dist/react/ApolloProvider.js +30 -0
- package/dist/react/ApolloProvider.js.map +1 -0
- package/dist/react/context/ToolUseContext.d.ts +4 -3
- package/dist/react/context/ToolUseContext.d.ts.map +1 -0
- package/dist/react/context/ToolUseContext.js +11 -0
- package/dist/react/context/ToolUseContext.js.map +1 -0
- package/dist/react/hooks/useCallTool.d.ts +4 -0
- package/dist/react/hooks/useCallTool.d.ts.map +1 -0
- package/dist/react/hooks/useCallTool.js +5 -0
- package/dist/react/hooks/useCallTool.js.map +1 -0
- package/dist/react/hooks/useOpenAiGlobal.d.ts +2 -1
- package/dist/react/hooks/useOpenAiGlobal.d.ts.map +1 -0
- package/dist/react/hooks/useOpenAiGlobal.js +20 -0
- package/dist/react/hooks/useOpenAiGlobal.js.map +1 -0
- package/dist/react/hooks/useOpenExternal.d.ts +1 -0
- package/dist/react/hooks/useOpenExternal.d.ts.map +1 -0
- package/dist/react/hooks/useOpenExternal.js +5 -0
- package/dist/react/hooks/useOpenExternal.js.map +1 -0
- package/dist/react/hooks/useRequestDisplayMode.d.ts +2 -1
- package/dist/react/hooks/useRequestDisplayMode.d.ts.map +1 -0
- package/dist/react/hooks/useRequestDisplayMode.js +6 -0
- package/dist/react/hooks/useRequestDisplayMode.js.map +1 -0
- package/dist/react/hooks/useSendFollowUpMessage.d.ts +1 -0
- package/dist/react/hooks/useSendFollowUpMessage.d.ts.map +1 -0
- package/dist/react/hooks/useSendFollowUpMessage.js +8 -0
- package/dist/react/hooks/useSendFollowUpMessage.js.map +1 -0
- package/dist/react/hooks/useToolEffect.d.ts +1 -0
- package/dist/react/hooks/useToolEffect.d.ts.map +1 -0
- package/dist/react/hooks/useToolEffect.js +28 -0
- package/dist/react/hooks/useToolEffect.js.map +1 -0
- package/dist/react/hooks/useToolInput.d.ts +1 -0
- package/dist/react/hooks/useToolInput.d.ts.map +1 -0
- package/dist/react/hooks/useToolInput.js +6 -0
- package/dist/react/hooks/useToolInput.js.map +1 -0
- package/dist/react/hooks/useToolName.d.ts +1 -0
- package/dist/react/hooks/useToolName.d.ts.map +1 -0
- package/dist/react/hooks/useToolName.js +6 -0
- package/dist/react/hooks/useToolName.js.map +1 -0
- package/dist/react/hooks/useToolOutput.d.ts +2 -1
- package/dist/react/hooks/useToolOutput.d.ts.map +1 -0
- package/dist/react/hooks/useToolOutput.js +5 -0
- package/dist/react/hooks/useToolOutput.js.map +1 -0
- package/dist/react/hooks/useToolResponseMetadata.d.ts +2 -1
- package/dist/react/hooks/useToolResponseMetadata.d.ts.map +1 -0
- package/dist/react/hooks/useToolResponseMetadata.js +5 -0
- package/dist/react/hooks/useToolResponseMetadata.js.map +1 -0
- package/dist/react/hooks/useWidgetState.d.ts +3 -2
- package/dist/react/hooks/useWidgetState.d.ts.map +1 -0
- package/dist/react/hooks/useWidgetState.js +27 -0
- package/dist/react/hooks/useWidgetState.js.map +1 -0
- package/dist/types/application-manifest.d.ts +15 -0
- package/dist/types/application-manifest.d.ts.map +1 -0
- package/dist/types/application-manifest.js +2 -0
- package/dist/types/application-manifest.js.map +1 -0
- package/dist/types/openai.d.ts +1 -0
- package/dist/types/openai.d.ts.map +1 -0
- package/dist/types/openai.js +6 -0
- package/dist/types/openai.js.map +1 -0
- package/dist/vite/absolute_asset_imports_plugin.d.ts +1 -0
- package/dist/vite/absolute_asset_imports_plugin.d.ts.map +1 -0
- package/dist/vite/absolute_asset_imports_plugin.js +17 -0
- package/dist/vite/absolute_asset_imports_plugin.js.map +1 -0
- package/dist/vite/application_manifest_plugin.d.ts +2 -1
- package/dist/vite/application_manifest_plugin.d.ts.map +1 -0
- package/dist/vite/application_manifest_plugin.js +317 -0
- package/dist/vite/application_manifest_plugin.js.map +1 -0
- package/dist/vite/index.d.ts +3 -2
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +3 -307
- package/dist/vite/index.js.map +1 -0
- package/knope.toml +63 -0
- package/package.json +19 -11
- package/src/core/ApolloClient.ts +10 -5
- package/src/core/__tests__/ApolloClient.test.ts +33 -10
- package/src/index.ts +19 -18
- package/src/react/ApolloProvider.tsx +4 -3
- package/src/react/__tests__/ApolloProvider.test.tsx +3 -3
- package/src/react/context/ToolUseContext.tsx +2 -1
- package/src/react/hooks/__tests__/useCallTool.test.ts +1 -1
- package/src/react/hooks/__tests__/useOpenAiGlobal.test.ts +6 -6
- package/src/react/hooks/__tests__/useOpenExternal.test.tsx +2 -2
- package/src/react/hooks/__tests__/useRequestDisplayMode.test.ts +2 -2
- package/src/react/hooks/__tests__/useSendFollowUpMessage.test.ts +1 -1
- package/src/react/hooks/__tests__/useToolEffect.test.tsx +2 -2
- package/src/react/hooks/__tests__/useToolInput.test.ts +1 -1
- package/src/react/hooks/__tests__/useToolName.test.ts +1 -1
- package/src/react/hooks/__tests__/useToolOutput.test.tsx +2 -2
- package/src/react/hooks/__tests__/useToolResponseMetadata.test.tsx +2 -2
- package/src/react/hooks/__tests__/useWidgetState.test.tsx +2 -2
- package/src/react/hooks/useOpenAiGlobal.ts +2 -5
- package/src/react/hooks/useOpenExternal.ts +1 -1
- package/src/react/hooks/useRequestDisplayMode.ts +1 -1
- package/src/react/hooks/useToolEffect.tsx +3 -3
- package/src/react/hooks/useToolInput.ts +1 -1
- package/src/react/hooks/useToolName.ts +1 -1
- package/src/react/hooks/useToolOutput.ts +1 -1
- package/src/react/hooks/useToolResponseMetadata.ts +1 -1
- package/src/react/hooks/useWidgetState.ts +4 -3
- package/src/testing/internal/index.ts +2 -2
- package/src/testing/internal/matchers/index.ts +1 -1
- package/src/testing/internal/matchers/toRerender.ts +2 -2
- package/src/testing/internal/matchers/{index.d.ts → types.ts} +1 -1
- package/src/testing/internal/openai/dispatchStateChange.ts +1 -1
- package/src/testing/internal/openai/stubOpenAiGlobals.ts +6 -2
- package/src/types/application-manifest.ts +16 -0
- package/src/vite/__tests__/absolute_asset_imports_plugin.test.ts +2 -2
- package/src/vite/__tests__/application_manifest_plugin.test.ts +460 -240
- package/src/vite/application_manifest_plugin.ts +253 -93
- package/src/vite/index.ts +2 -2
- package/tsconfig.base.build.json +13 -0
- package/tsconfig.base.json +21 -0
- package/tsconfig.config.json +9 -0
- package/tsconfig.json +10 -0
- package/tsconfig.src.build.json +14 -0
- package/tsconfig.src.json +17 -0
- package/tsconfig.test.json +20 -0
- package/tsconfig.vite.build.json +6 -0
- package/tsconfig.vite.json +16 -0
- package/scripts/build-vite.mjs +0 -18
- package/scripts/build.mjs +0 -7
- package/scripts/shared.mjs +0 -9
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { Mock } from "vitest";
|
|
2
|
+
import { expect, test, vi, describe, beforeEach } from "vitest";
|
|
3
|
+
import { ApplicationManifestPlugin } from "../application_manifest_plugin.js";
|
|
3
4
|
import fs from "fs";
|
|
4
5
|
import * as glob from "glob";
|
|
5
6
|
import path from "path";
|
|
7
|
+
import type { ManifestWidgetSettings } from "../../types/application-manifest.js";
|
|
6
8
|
|
|
7
9
|
const root = process.cwd();
|
|
8
10
|
|
|
@@ -31,12 +33,7 @@ vi.mock(import("path"), async (importOriginal) => {
|
|
|
31
33
|
};
|
|
32
34
|
});
|
|
33
35
|
|
|
34
|
-
vi.mock(import("glob")
|
|
35
|
-
const actual = await importOriginal();
|
|
36
|
-
return {
|
|
37
|
-
glob: vi.fn(),
|
|
38
|
-
};
|
|
39
|
-
});
|
|
36
|
+
vi.mock(import("glob"));
|
|
40
37
|
|
|
41
38
|
beforeEach(() => {
|
|
42
39
|
vi.clearAllMocks();
|
|
@@ -44,19 +41,39 @@ beforeEach(() => {
|
|
|
44
41
|
|
|
45
42
|
describe("buildStart", () => {
|
|
46
43
|
test("Should write to dev application manifest file when using a serve command", async () => {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
44
|
+
mockReadFile({
|
|
45
|
+
"package.json": JSON.stringify({
|
|
46
|
+
labels: {
|
|
47
|
+
toolInvocation: {
|
|
48
|
+
invoking: "Testing global...",
|
|
49
|
+
invoked: "Tested global!",
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
widgetSettings: {
|
|
53
|
+
description: "Test",
|
|
54
|
+
domain: "https://example.com",
|
|
55
|
+
prefersBorder: true,
|
|
56
|
+
} satisfies ManifestWidgetSettings,
|
|
57
|
+
}),
|
|
58
|
+
[`${root}/my-component.tsx`]: `
|
|
59
|
+
const MY_QUERY = gql\`query HelloWorldQuery($name: string!) @tool(
|
|
60
|
+
name: "hello-world",
|
|
61
|
+
description: "This is an awesome tool!",
|
|
62
|
+
extraInputs: [{
|
|
63
|
+
name: "doStuff",
|
|
64
|
+
type: "boolean",
|
|
65
|
+
description: "Should we do stuff?"
|
|
66
|
+
}],
|
|
67
|
+
labels: {
|
|
68
|
+
toolInvocation: {
|
|
69
|
+
invoking: "Testing tool...",
|
|
70
|
+
invoked: "Tested tool!"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
) { helloWorld(name: $name) }\`;
|
|
74
|
+
`,
|
|
59
75
|
});
|
|
76
|
+
|
|
60
77
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
61
78
|
Promise.resolve(["my-component.tsx"])
|
|
62
79
|
);
|
|
@@ -81,10 +98,16 @@ describe("buildStart", () => {
|
|
|
81
98
|
{
|
|
82
99
|
"csp": {
|
|
83
100
|
"connectDomains": [],
|
|
101
|
+
"frameDomains": [],
|
|
102
|
+
"redirectDomains": [],
|
|
84
103
|
"resourceDomains": [],
|
|
85
104
|
},
|
|
86
105
|
"format": "apollo-ai-app-manifest",
|
|
87
106
|
"hash": "abc",
|
|
107
|
+
"labels": {
|
|
108
|
+
"toolInvocation/invoked": "Tested global!",
|
|
109
|
+
"toolInvocation/invoking": "Testing global...",
|
|
110
|
+
},
|
|
88
111
|
"operations": [
|
|
89
112
|
{
|
|
90
113
|
"body": "query HelloWorldQuery($name: string!) {
|
|
@@ -103,6 +126,10 @@ describe("buildStart", () => {
|
|
|
103
126
|
"type": "boolean",
|
|
104
127
|
},
|
|
105
128
|
],
|
|
129
|
+
"labels": {
|
|
130
|
+
"toolInvocation/invoked": "Tested tool!",
|
|
131
|
+
"toolInvocation/invoking": "Testing tool...",
|
|
132
|
+
},
|
|
106
133
|
"name": "hello-world",
|
|
107
134
|
},
|
|
108
135
|
],
|
|
@@ -114,19 +141,21 @@ describe("buildStart", () => {
|
|
|
114
141
|
],
|
|
115
142
|
"resource": "http://localhost:undefined",
|
|
116
143
|
"version": "1",
|
|
144
|
+
"widgetSettings": {
|
|
145
|
+
"description": "Test",
|
|
146
|
+
"domain": "https://example.com",
|
|
147
|
+
"prefersBorder": true,
|
|
148
|
+
},
|
|
117
149
|
}
|
|
118
150
|
`);
|
|
119
151
|
});
|
|
120
152
|
|
|
121
153
|
test("Should NOT write to dev application manifest file when using a build command", async () => {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
128
|
-
`;
|
|
129
|
-
}
|
|
154
|
+
mockReadFile({
|
|
155
|
+
"package.json": JSON.stringify({}),
|
|
156
|
+
"my-component.tsx": `
|
|
157
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
158
|
+
`,
|
|
130
159
|
});
|
|
131
160
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
132
161
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -142,14 +171,11 @@ describe("buildStart", () => {
|
|
|
142
171
|
});
|
|
143
172
|
|
|
144
173
|
test("Should not process files that do not contain gql tags", async () => {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const MY_QUERY = \`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
151
|
-
`;
|
|
152
|
-
}
|
|
174
|
+
mockReadFile({
|
|
175
|
+
"package.json": JSON.stringify({}),
|
|
176
|
+
[`${root}/my-component.tsx`]: `
|
|
177
|
+
const MY_QUERY = \`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
178
|
+
`,
|
|
153
179
|
});
|
|
154
180
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
155
181
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -175,6 +201,8 @@ describe("buildStart", () => {
|
|
|
175
201
|
{
|
|
176
202
|
"csp": {
|
|
177
203
|
"connectDomains": [],
|
|
204
|
+
"frameDomains": [],
|
|
205
|
+
"redirectDomains": [],
|
|
178
206
|
"resourceDomains": [],
|
|
179
207
|
},
|
|
180
208
|
"format": "apollo-ai-app-manifest",
|
|
@@ -187,14 +215,11 @@ describe("buildStart", () => {
|
|
|
187
215
|
});
|
|
188
216
|
|
|
189
217
|
test("Should capture queries when writing to manifest file", async () => {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
const MY_QUERY = gql\`query HelloWorldQuery { helloWorld }\`;
|
|
196
|
-
`;
|
|
197
|
-
}
|
|
218
|
+
mockReadFile({
|
|
219
|
+
"package.json": JSON.stringify({}),
|
|
220
|
+
[`${root}/my-component.tsx`]: `
|
|
221
|
+
const MY_QUERY = gql\`query HelloWorldQuery { helloWorld }\`;
|
|
222
|
+
`,
|
|
198
223
|
});
|
|
199
224
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
200
225
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -220,6 +245,8 @@ describe("buildStart", () => {
|
|
|
220
245
|
{
|
|
221
246
|
"csp": {
|
|
222
247
|
"connectDomains": [],
|
|
248
|
+
"frameDomains": [],
|
|
249
|
+
"redirectDomains": [],
|
|
223
250
|
"resourceDomains": [],
|
|
224
251
|
},
|
|
225
252
|
"format": "apollo-ai-app-manifest",
|
|
@@ -244,14 +271,11 @@ describe("buildStart", () => {
|
|
|
244
271
|
});
|
|
245
272
|
|
|
246
273
|
test("Should capture queries as prefetch when query is marked with @prefetch directive", async () => {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
const MY_QUERY = gql\`query HelloWorldQuery @prefetch { helloWorld }\`;
|
|
253
|
-
`;
|
|
254
|
-
}
|
|
274
|
+
mockReadFile({
|
|
275
|
+
"package.json": JSON.stringify({}),
|
|
276
|
+
[`${root}/my-component.tsx`]: `
|
|
277
|
+
const MY_QUERY = gql\`query HelloWorldQuery @prefetch { helloWorld }\`;
|
|
278
|
+
`,
|
|
255
279
|
});
|
|
256
280
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
257
281
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -277,6 +301,8 @@ describe("buildStart", () => {
|
|
|
277
301
|
{
|
|
278
302
|
"csp": {
|
|
279
303
|
"connectDomains": [],
|
|
304
|
+
"frameDomains": [],
|
|
305
|
+
"redirectDomains": [],
|
|
280
306
|
"resourceDomains": [],
|
|
281
307
|
},
|
|
282
308
|
"format": "apollo-ai-app-manifest",
|
|
@@ -302,15 +328,12 @@ describe("buildStart", () => {
|
|
|
302
328
|
});
|
|
303
329
|
|
|
304
330
|
test("Should error when multiple operations are marked with @prefetch", async () => {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
const MY_QUERY2 = gql\`query HelloWorldQuery2 @prefetch { helloWorld }\`;
|
|
312
|
-
`;
|
|
313
|
-
}
|
|
331
|
+
mockReadFile({
|
|
332
|
+
"package.json": JSON.stringify({}),
|
|
333
|
+
"my-component.tsx": `
|
|
334
|
+
const MY_QUERY = gql\`query HelloWorldQuery @prefetch { helloWorld }\`;
|
|
335
|
+
const MY_QUERY2 = gql\`query HelloWorldQuery2 @prefetch { helloWorld }\`;
|
|
336
|
+
`,
|
|
314
337
|
});
|
|
315
338
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
316
339
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -328,14 +351,11 @@ describe("buildStart", () => {
|
|
|
328
351
|
});
|
|
329
352
|
|
|
330
353
|
test("Should capture mutations when writing to manifest file", async () => {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
const MY_QUERY = gql\`mutation HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
337
|
-
`;
|
|
338
|
-
}
|
|
354
|
+
mockReadFile({
|
|
355
|
+
"package.json": JSON.stringify({}),
|
|
356
|
+
[`${root}/my-component.tsx`]: `
|
|
357
|
+
const MY_QUERY = gql\`mutation HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
358
|
+
`,
|
|
339
359
|
});
|
|
340
360
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
341
361
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -361,6 +381,8 @@ describe("buildStart", () => {
|
|
|
361
381
|
{
|
|
362
382
|
"csp": {
|
|
363
383
|
"connectDomains": [],
|
|
384
|
+
"frameDomains": [],
|
|
385
|
+
"redirectDomains": [],
|
|
364
386
|
"resourceDomains": [],
|
|
365
387
|
},
|
|
366
388
|
"format": "apollo-ai-app-manifest",
|
|
@@ -390,14 +412,11 @@ describe("buildStart", () => {
|
|
|
390
412
|
});
|
|
391
413
|
|
|
392
414
|
test("Should throw error when a subscription operation type is discovered", async () => {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
const MY_QUERY = gql\`subscription HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
399
|
-
`;
|
|
400
|
-
}
|
|
415
|
+
mockReadFile({
|
|
416
|
+
"package.json": JSON.stringify({}),
|
|
417
|
+
"my-component.tsx": `
|
|
418
|
+
const MY_QUERY = gql\`subscription HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
419
|
+
`,
|
|
401
420
|
});
|
|
402
421
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
403
422
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -416,18 +435,15 @@ describe("buildStart", () => {
|
|
|
416
435
|
});
|
|
417
436
|
|
|
418
437
|
test("Should use custom entry point when in serve mode and provided in package.json", async () => {
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
429
|
-
`;
|
|
430
|
-
}
|
|
438
|
+
mockReadFile({
|
|
439
|
+
"package.json": JSON.stringify({
|
|
440
|
+
entry: {
|
|
441
|
+
staging: "http://staging.awesome.com",
|
|
442
|
+
},
|
|
443
|
+
}),
|
|
444
|
+
"my-component.tsx": `
|
|
445
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
446
|
+
`,
|
|
431
447
|
});
|
|
432
448
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
433
449
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -444,21 +460,18 @@ describe("buildStart", () => {
|
|
|
444
460
|
});
|
|
445
461
|
await plugin.buildStart();
|
|
446
462
|
|
|
447
|
-
let [
|
|
463
|
+
let [, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
448
464
|
let contentObj = JSON.parse(content);
|
|
449
465
|
|
|
450
466
|
expect(contentObj.resource).toBe("http://staging.awesome.com");
|
|
451
467
|
});
|
|
452
468
|
|
|
453
469
|
test("Should use https when enabled in server config", async () => {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
460
|
-
`;
|
|
461
|
-
}
|
|
470
|
+
mockReadFile({
|
|
471
|
+
"package.json": JSON.stringify({}),
|
|
472
|
+
"my-component.tsx": `
|
|
473
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
474
|
+
`,
|
|
462
475
|
});
|
|
463
476
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
464
477
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -474,21 +487,18 @@ describe("buildStart", () => {
|
|
|
474
487
|
});
|
|
475
488
|
await plugin.buildStart();
|
|
476
489
|
|
|
477
|
-
let [
|
|
490
|
+
let [, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
478
491
|
let contentObj = JSON.parse(content);
|
|
479
492
|
|
|
480
493
|
expect(contentObj.resource).toBe("https://localhost:5678");
|
|
481
494
|
});
|
|
482
495
|
|
|
483
496
|
test("Should use custom host when specified in server config", async () => {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
490
|
-
`;
|
|
491
|
-
}
|
|
497
|
+
mockReadFile({
|
|
498
|
+
"package.json": JSON.stringify({}),
|
|
499
|
+
"my-component.tsx": `
|
|
500
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
501
|
+
`,
|
|
492
502
|
});
|
|
493
503
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
494
504
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -504,21 +514,18 @@ describe("buildStart", () => {
|
|
|
504
514
|
});
|
|
505
515
|
await plugin.buildStart();
|
|
506
516
|
|
|
507
|
-
let [
|
|
517
|
+
let [, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
508
518
|
let contentObj = JSON.parse(content);
|
|
509
519
|
|
|
510
520
|
expect(contentObj.resource).toBe("http://awesome.com:5678");
|
|
511
521
|
});
|
|
512
522
|
|
|
513
523
|
test("Should error when tool name is not provided", async () => {
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool { helloWorld }\`;
|
|
520
|
-
`;
|
|
521
|
-
}
|
|
524
|
+
mockReadFile({
|
|
525
|
+
"package.json": JSON.stringify({}),
|
|
526
|
+
"my-component.tsx": `
|
|
527
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool { helloWorld }\`;
|
|
528
|
+
`,
|
|
522
529
|
});
|
|
523
530
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
524
531
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -537,14 +544,11 @@ describe("buildStart", () => {
|
|
|
537
544
|
});
|
|
538
545
|
|
|
539
546
|
test("Should error when tool description is not provided", async () => {
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world") { helloWorld }\`;
|
|
546
|
-
`;
|
|
547
|
-
}
|
|
547
|
+
mockReadFile({
|
|
548
|
+
"package.json": JSON.stringify({}),
|
|
549
|
+
"my-component.tsx": `
|
|
550
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world") { helloWorld }\`;
|
|
551
|
+
`,
|
|
548
552
|
});
|
|
549
553
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
550
554
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -563,14 +567,11 @@ describe("buildStart", () => {
|
|
|
563
567
|
});
|
|
564
568
|
|
|
565
569
|
test("Should error when tool name contains spaces", async () => {
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello world", description: "A tool") { helloWorld }\`;
|
|
572
|
-
`;
|
|
573
|
-
}
|
|
570
|
+
mockReadFile({
|
|
571
|
+
"package.json": JSON.stringify({}),
|
|
572
|
+
"my-component.tsx": `
|
|
573
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello world", description: "A tool") { helloWorld }\`;
|
|
574
|
+
`,
|
|
574
575
|
});
|
|
575
576
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
576
577
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -589,14 +590,11 @@ describe("buildStart", () => {
|
|
|
589
590
|
});
|
|
590
591
|
|
|
591
592
|
test("Should error when tool name is not a string", async () => {
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: true) { helloWorld }\`;
|
|
598
|
-
`;
|
|
599
|
-
}
|
|
593
|
+
mockReadFile({
|
|
594
|
+
"package.json": JSON.stringify({}),
|
|
595
|
+
"my-component.tsx": `
|
|
596
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: true) { helloWorld }\`;
|
|
597
|
+
`,
|
|
600
598
|
});
|
|
601
599
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
602
600
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -615,14 +613,11 @@ describe("buildStart", () => {
|
|
|
615
613
|
});
|
|
616
614
|
|
|
617
615
|
test("Should error when tool description is not a string", async () => {
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: false) { helloWorld }\`;
|
|
624
|
-
`;
|
|
625
|
-
}
|
|
616
|
+
mockReadFile({
|
|
617
|
+
"package.json": JSON.stringify({}),
|
|
618
|
+
"my-component.tsx": `
|
|
619
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: false) { helloWorld }\`;
|
|
620
|
+
`,
|
|
626
621
|
});
|
|
627
622
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
628
623
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -641,14 +636,11 @@ describe("buildStart", () => {
|
|
|
641
636
|
});
|
|
642
637
|
|
|
643
638
|
test("Should error when extraInputs is not an array", async () => {
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "hello", extraInputs: false ) { helloWorld }\`;
|
|
650
|
-
`;
|
|
651
|
-
}
|
|
639
|
+
mockReadFile({
|
|
640
|
+
"package.json": JSON.stringify({}),
|
|
641
|
+
"my-component.tsx": `
|
|
642
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "hello", extraInputs: false ) { helloWorld }\`;
|
|
643
|
+
`,
|
|
652
644
|
});
|
|
653
645
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
654
646
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -666,17 +658,241 @@ describe("buildStart", () => {
|
|
|
666
658
|
);
|
|
667
659
|
});
|
|
668
660
|
|
|
661
|
+
test("Should error when widgetSettings.prefersBorder is not a boolean", async () => {
|
|
662
|
+
mockReadFile({
|
|
663
|
+
"package.json": JSON.stringify({
|
|
664
|
+
widgetSettings: {
|
|
665
|
+
prefersBorder: "test",
|
|
666
|
+
},
|
|
667
|
+
}),
|
|
668
|
+
"my-component.tsx": `
|
|
669
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "test", description: "Test") { helloWorld }\`;
|
|
670
|
+
`,
|
|
671
|
+
});
|
|
672
|
+
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
673
|
+
Promise.resolve(["my-component.tsx"])
|
|
674
|
+
);
|
|
675
|
+
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
676
|
+
vi.spyOn(fs, "writeFileSync");
|
|
677
|
+
|
|
678
|
+
const plugin = ApplicationManifestPlugin();
|
|
679
|
+
plugin.configResolved({ command: "serve", server: {} });
|
|
680
|
+
|
|
681
|
+
await expect(
|
|
682
|
+
async () => await plugin.buildStart()
|
|
683
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
684
|
+
`[Error: Expected 'widgetSettings.prefersBorder' to be of type 'boolean' but found 'string' instead.]`
|
|
685
|
+
);
|
|
686
|
+
});
|
|
687
|
+
|
|
688
|
+
test("Should error when widgetSettings.description is not a string", async () => {
|
|
689
|
+
mockReadFile({
|
|
690
|
+
"package.json": JSON.stringify({
|
|
691
|
+
widgetSettings: {
|
|
692
|
+
description: true,
|
|
693
|
+
},
|
|
694
|
+
}),
|
|
695
|
+
"my-component.tsx": `
|
|
696
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "test", description: "Test") { helloWorld }\`;
|
|
697
|
+
`,
|
|
698
|
+
});
|
|
699
|
+
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
700
|
+
Promise.resolve(["my-component.tsx"])
|
|
701
|
+
);
|
|
702
|
+
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
703
|
+
vi.spyOn(fs, "writeFileSync");
|
|
704
|
+
|
|
705
|
+
const plugin = ApplicationManifestPlugin();
|
|
706
|
+
plugin.configResolved({ command: "serve", server: {} });
|
|
707
|
+
|
|
708
|
+
await expect(
|
|
709
|
+
async () => await plugin.buildStart()
|
|
710
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
711
|
+
`[Error: Expected 'widgetSettings.description' to be of type 'string' but found 'boolean' instead.]`
|
|
712
|
+
);
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
test("Should error when widgetSettings.domain is not a string", async () => {
|
|
716
|
+
mockReadFile({
|
|
717
|
+
"package.json": JSON.stringify({
|
|
718
|
+
widgetSettings: {
|
|
719
|
+
domain: true,
|
|
720
|
+
},
|
|
721
|
+
}),
|
|
722
|
+
"my-component.tsx": `
|
|
723
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "test", description: "Test") { helloWorld }\`;
|
|
724
|
+
`,
|
|
725
|
+
});
|
|
726
|
+
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
727
|
+
Promise.resolve(["my-component.tsx"])
|
|
728
|
+
);
|
|
729
|
+
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
730
|
+
vi.spyOn(fs, "writeFileSync");
|
|
731
|
+
|
|
732
|
+
const plugin = ApplicationManifestPlugin();
|
|
733
|
+
plugin.configResolved({ command: "serve", server: {} });
|
|
734
|
+
|
|
735
|
+
await expect(
|
|
736
|
+
async () => await plugin.buildStart()
|
|
737
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
738
|
+
`[Error: Expected 'widgetSettings.domain' to be of type 'string' but found 'boolean' instead.]`
|
|
739
|
+
);
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
test("Should allow empty widgetSettings value", async () => {
|
|
743
|
+
mockReadFile({
|
|
744
|
+
"package.json": JSON.stringify({
|
|
745
|
+
widgetSettings: {},
|
|
746
|
+
}),
|
|
747
|
+
"my-component.tsx": `
|
|
748
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "test", description: "Test") { helloWorld }\`;
|
|
749
|
+
`,
|
|
750
|
+
});
|
|
751
|
+
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
752
|
+
Promise.resolve(["my-component.tsx"])
|
|
753
|
+
);
|
|
754
|
+
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
755
|
+
vi.spyOn(fs, "writeFileSync");
|
|
756
|
+
|
|
757
|
+
const plugin = ApplicationManifestPlugin();
|
|
758
|
+
plugin.configResolved({ command: "serve", server: {}, build: {} });
|
|
759
|
+
|
|
760
|
+
await expect(plugin.buildStart()).resolves.toBeUndefined();
|
|
761
|
+
});
|
|
762
|
+
|
|
763
|
+
test("Should error when labels.toolInvocation.invoking in package.json is not a string", async () => {
|
|
764
|
+
mockReadFile({
|
|
765
|
+
"package.json": JSON.stringify({
|
|
766
|
+
labels: {
|
|
767
|
+
toolInvocation: {
|
|
768
|
+
invoking: true,
|
|
769
|
+
},
|
|
770
|
+
},
|
|
771
|
+
}),
|
|
772
|
+
"my-component.tsx": `
|
|
773
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "test", description: "Test") { helloWorld }\`;
|
|
774
|
+
`,
|
|
775
|
+
});
|
|
776
|
+
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
777
|
+
Promise.resolve(["my-component.tsx"])
|
|
778
|
+
);
|
|
779
|
+
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
780
|
+
vi.spyOn(fs, "writeFileSync");
|
|
781
|
+
|
|
782
|
+
const plugin = ApplicationManifestPlugin();
|
|
783
|
+
plugin.configResolved({ command: "serve", server: {} });
|
|
784
|
+
|
|
785
|
+
await expect(
|
|
786
|
+
async () => await plugin.buildStart()
|
|
787
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
788
|
+
`[Error: Expected 'labels.toolInvocation.invoking' to be of type 'string' but found 'boolean' instead.]`
|
|
789
|
+
);
|
|
790
|
+
});
|
|
791
|
+
|
|
792
|
+
test("Should error when labels.toolInvocation.invoking in @tool is not a string", async () => {
|
|
793
|
+
mockReadFile({
|
|
794
|
+
"package.json": JSON.stringify({}),
|
|
795
|
+
"my-component.tsx": `
|
|
796
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "test", description: "Test", labels: { toolInvocation: { invoking: true } }) { helloWorld }\`;
|
|
797
|
+
`,
|
|
798
|
+
});
|
|
799
|
+
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
800
|
+
Promise.resolve(["my-component.tsx"])
|
|
801
|
+
);
|
|
802
|
+
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
803
|
+
vi.spyOn(fs, "writeFileSync");
|
|
804
|
+
|
|
805
|
+
const plugin = ApplicationManifestPlugin();
|
|
806
|
+
plugin.configResolved({ command: "serve", server: {} });
|
|
807
|
+
|
|
808
|
+
await expect(
|
|
809
|
+
async () => await plugin.buildStart()
|
|
810
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
811
|
+
`[Error: Expected 'labels.toolInvocation.invoking' to be of type 'string' but found 'boolean' instead.]`
|
|
812
|
+
);
|
|
813
|
+
});
|
|
814
|
+
|
|
815
|
+
test("Should error when labels.toolInvocation.invoked in package.json is not a string", async () => {
|
|
816
|
+
mockReadFile({
|
|
817
|
+
"package.json": JSON.stringify({
|
|
818
|
+
labels: {
|
|
819
|
+
toolInvocation: {
|
|
820
|
+
invoked: true,
|
|
821
|
+
},
|
|
822
|
+
},
|
|
823
|
+
}),
|
|
824
|
+
"my-component.tsx": `
|
|
825
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "test", description: "Test") { helloWorld }\`;
|
|
826
|
+
`,
|
|
827
|
+
});
|
|
828
|
+
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
829
|
+
Promise.resolve(["my-component.tsx"])
|
|
830
|
+
);
|
|
831
|
+
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
832
|
+
vi.spyOn(fs, "writeFileSync");
|
|
833
|
+
|
|
834
|
+
const plugin = ApplicationManifestPlugin();
|
|
835
|
+
plugin.configResolved({ command: "serve", server: {} });
|
|
836
|
+
|
|
837
|
+
await expect(
|
|
838
|
+
async () => await plugin.buildStart()
|
|
839
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
840
|
+
`[Error: Expected 'labels.toolInvocation.invoked' to be of type 'string' but found 'boolean' instead.]`
|
|
841
|
+
);
|
|
842
|
+
});
|
|
843
|
+
|
|
844
|
+
test("Should error when labels.toolInvocation.invoked in @tool is not a string", async () => {
|
|
845
|
+
mockReadFile({
|
|
846
|
+
"package.json": JSON.stringify({}),
|
|
847
|
+
"my-component.tsx": `
|
|
848
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "test", description: "Test", labels: { toolInvocation: { invoked: true } }) { helloWorld }\`;
|
|
849
|
+
`,
|
|
850
|
+
});
|
|
851
|
+
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
852
|
+
Promise.resolve(["my-component.tsx"])
|
|
853
|
+
);
|
|
854
|
+
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
855
|
+
vi.spyOn(fs, "writeFileSync");
|
|
856
|
+
|
|
857
|
+
const plugin = ApplicationManifestPlugin();
|
|
858
|
+
plugin.configResolved({ command: "serve", server: {} });
|
|
859
|
+
|
|
860
|
+
await expect(
|
|
861
|
+
async () => await plugin.buildStart()
|
|
862
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
863
|
+
`[Error: Expected 'labels.toolInvocation.invoked' to be of type 'string' but found 'boolean' instead.]`
|
|
864
|
+
);
|
|
865
|
+
});
|
|
866
|
+
|
|
867
|
+
test("Should allow empty labels value", async () => {
|
|
868
|
+
mockReadFile({
|
|
869
|
+
"package.json": JSON.stringify({
|
|
870
|
+
labels: {},
|
|
871
|
+
}),
|
|
872
|
+
"my-component.tsx": `
|
|
873
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "test", description: "Test", labels: {}) { helloWorld }\`;
|
|
874
|
+
`,
|
|
875
|
+
});
|
|
876
|
+
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
877
|
+
Promise.resolve(["my-component.tsx"])
|
|
878
|
+
);
|
|
879
|
+
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
880
|
+
vi.spyOn(fs, "writeFileSync");
|
|
881
|
+
|
|
882
|
+
const plugin = ApplicationManifestPlugin();
|
|
883
|
+
plugin.configResolved({ command: "serve", server: {}, build: {} });
|
|
884
|
+
|
|
885
|
+
await expect(plugin.buildStart()).resolves.toBeUndefined();
|
|
886
|
+
});
|
|
887
|
+
|
|
669
888
|
test("Should error when an unknown type is discovered", async () => {
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
}] ) { helloWorld }\`;
|
|
678
|
-
`;
|
|
679
|
-
}
|
|
889
|
+
mockReadFile({
|
|
890
|
+
"package.json": JSON.stringify({}),
|
|
891
|
+
"my-component.tsx": `
|
|
892
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "hello", extraInputs: [{
|
|
893
|
+
name: 3.1
|
|
894
|
+
}] ) { helloWorld }\`;
|
|
895
|
+
`,
|
|
680
896
|
});
|
|
681
897
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
682
898
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -695,25 +911,22 @@ describe("buildStart", () => {
|
|
|
695
911
|
});
|
|
696
912
|
|
|
697
913
|
test("Should order operations and fragments when generating normalized operation", async () => {
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
}\`;
|
|
715
|
-
`;
|
|
716
|
-
}
|
|
914
|
+
mockReadFile({
|
|
915
|
+
"package.json": JSON.stringify({}),
|
|
916
|
+
[`${root}/my-component.tsx`]: `
|
|
917
|
+
const MY_QUERY = gql\`
|
|
918
|
+
fragment A on User { firstName }
|
|
919
|
+
fragment B on User { lastName }
|
|
920
|
+
query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") {
|
|
921
|
+
helloWorld {
|
|
922
|
+
...B
|
|
923
|
+
...A
|
|
924
|
+
...C
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
fragment C on User { middleName }
|
|
928
|
+
}\`;
|
|
929
|
+
`,
|
|
717
930
|
});
|
|
718
931
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
719
932
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -739,6 +952,8 @@ describe("buildStart", () => {
|
|
|
739
952
|
{
|
|
740
953
|
"csp": {
|
|
741
954
|
"connectDomains": [],
|
|
955
|
+
"frameDomains": [],
|
|
956
|
+
"redirectDomains": [],
|
|
742
957
|
"resourceDomains": [],
|
|
743
958
|
},
|
|
744
959
|
"format": "apollo-ai-app-manifest",
|
|
@@ -792,18 +1007,15 @@ describe("buildStart", () => {
|
|
|
792
1007
|
|
|
793
1008
|
describe("writeBundle", () => {
|
|
794
1009
|
test("Should use custom entry point when in build mode and provided in package.json", async () => {
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
805
|
-
`;
|
|
806
|
-
}
|
|
1010
|
+
mockReadFile({
|
|
1011
|
+
"package.json": JSON.stringify({
|
|
1012
|
+
entry: {
|
|
1013
|
+
staging: "http://staging.awesome.com",
|
|
1014
|
+
},
|
|
1015
|
+
}),
|
|
1016
|
+
"my-component.tsx": `
|
|
1017
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
1018
|
+
`,
|
|
807
1019
|
});
|
|
808
1020
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
809
1021
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -822,21 +1034,18 @@ describe("writeBundle", () => {
|
|
|
822
1034
|
await plugin.buildStart();
|
|
823
1035
|
await plugin.writeBundle();
|
|
824
1036
|
|
|
825
|
-
let [
|
|
1037
|
+
let [, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
826
1038
|
let contentObj = JSON.parse(content);
|
|
827
1039
|
|
|
828
1040
|
expect(contentObj.resource).toBe("http://staging.awesome.com");
|
|
829
1041
|
});
|
|
830
1042
|
|
|
831
1043
|
test("Should use index.html when in build production and not provided in package.json", async () => {
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
838
|
-
`;
|
|
839
|
-
}
|
|
1044
|
+
mockReadFile({
|
|
1045
|
+
"package.json": JSON.stringify({}),
|
|
1046
|
+
"my-component.tsx": `
|
|
1047
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
1048
|
+
`,
|
|
840
1049
|
});
|
|
841
1050
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
842
1051
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -855,21 +1064,18 @@ describe("writeBundle", () => {
|
|
|
855
1064
|
await plugin.buildStart();
|
|
856
1065
|
await plugin.writeBundle();
|
|
857
1066
|
|
|
858
|
-
let [
|
|
1067
|
+
let [, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
859
1068
|
let contentObj = JSON.parse(content);
|
|
860
1069
|
|
|
861
1070
|
expect(contentObj.resource).toBe("index.html");
|
|
862
1071
|
});
|
|
863
1072
|
|
|
864
1073
|
test("Should throw an error when in build mode and using a mode that is not production and not provided in package.json", async () => {
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
871
|
-
`;
|
|
872
|
-
}
|
|
1074
|
+
mockReadFile({
|
|
1075
|
+
"package.json": JSON.stringify({}),
|
|
1076
|
+
"my-component.tsx": `
|
|
1077
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
1078
|
+
`,
|
|
873
1079
|
});
|
|
874
1080
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
875
1081
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -895,14 +1101,11 @@ describe("writeBundle", () => {
|
|
|
895
1101
|
});
|
|
896
1102
|
|
|
897
1103
|
test("Should always write to both locations when running in build mode", async () => {
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
904
|
-
`;
|
|
905
|
-
}
|
|
1104
|
+
mockReadFile({
|
|
1105
|
+
"package.json": JSON.stringify({}),
|
|
1106
|
+
"my-component.tsx": `
|
|
1107
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
1108
|
+
`,
|
|
906
1109
|
});
|
|
907
1110
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
908
1111
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -927,18 +1130,15 @@ describe("writeBundle", () => {
|
|
|
927
1130
|
|
|
928
1131
|
describe("configureServer", () => {
|
|
929
1132
|
test("Should write to manifest file when package.json or file is updated", async () => {
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
}]) { helloWorld(name: $name) }\`;
|
|
940
|
-
`;
|
|
941
|
-
}
|
|
1133
|
+
mockReadFile({
|
|
1134
|
+
"package.json": JSON.stringify({}),
|
|
1135
|
+
"my-component.tsx": `
|
|
1136
|
+
const MY_QUERY = gql\`query HelloWorldQuery($name: string!) @tool(name: "hello-world", description: "This is an awesome tool!", extraInputs: [{
|
|
1137
|
+
name: "doStuff",
|
|
1138
|
+
type: "boolean",
|
|
1139
|
+
description: "Should we do stuff?"
|
|
1140
|
+
}]) { helloWorld(name: $name) }\`;
|
|
1141
|
+
`,
|
|
942
1142
|
});
|
|
943
1143
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
944
1144
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -946,16 +1146,18 @@ describe("configureServer", () => {
|
|
|
946
1146
|
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
947
1147
|
vi.spyOn(fs, "writeFileSync");
|
|
948
1148
|
|
|
1149
|
+
let _callbacks: Function[] = [];
|
|
1150
|
+
|
|
949
1151
|
const server = {
|
|
950
1152
|
watcher: {
|
|
951
1153
|
init: () => {
|
|
952
|
-
|
|
1154
|
+
_callbacks = [];
|
|
953
1155
|
},
|
|
954
1156
|
on: (_event: string, callback: Function) => {
|
|
955
|
-
|
|
1157
|
+
_callbacks.push(callback);
|
|
956
1158
|
},
|
|
957
|
-
trigger: async (file) => {
|
|
958
|
-
for (const callback of
|
|
1159
|
+
trigger: async (file: string) => {
|
|
1160
|
+
for (const callback of _callbacks) {
|
|
959
1161
|
await callback(file);
|
|
960
1162
|
}
|
|
961
1163
|
},
|
|
@@ -970,10 +1172,28 @@ describe("configureServer", () => {
|
|
|
970
1172
|
build: { outDir: "/dist" },
|
|
971
1173
|
});
|
|
972
1174
|
await plugin.buildStart();
|
|
973
|
-
|
|
1175
|
+
plugin.configureServer(server);
|
|
974
1176
|
await server.watcher.trigger("package.json");
|
|
975
1177
|
await server.watcher.trigger("my-component.tsx");
|
|
976
1178
|
|
|
977
1179
|
expect(fs.writeFileSync).toBeCalledTimes(6);
|
|
978
1180
|
});
|
|
979
1181
|
});
|
|
1182
|
+
|
|
1183
|
+
type FilePath = string;
|
|
1184
|
+
|
|
1185
|
+
function mockReadFile(mocks: Record<FilePath, string | (() => string)>) {
|
|
1186
|
+
vi.spyOn(fs, "readFileSync").mockImplementation((path) => {
|
|
1187
|
+
const mock = mocks[path.toString()];
|
|
1188
|
+
|
|
1189
|
+
if (!mock) {
|
|
1190
|
+
throw new Error(`No matched mock for path '${path}'`);
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
if (typeof mock === "function") {
|
|
1194
|
+
return mock();
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
return mock;
|
|
1198
|
+
});
|
|
1199
|
+
}
|