@apollo/client-ai-apps 0.3.1 → 0.3.3
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 +25 -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 -17
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -278
- 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 +7 -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 +274 -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 -302
- package/dist/vite/index.js.map +1 -0
- package/knope.toml +63 -0
- package/package.json +15 -8
- package/src/core/ApolloClient.ts +10 -5
- package/src/core/__tests__/ApolloClient.test.ts +12 -9
- package/src/index.ts +17 -17
- 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 +7 -0
- package/src/vite/__tests__/absolute_asset_imports_plugin.test.ts +2 -2
- package/src/vite/__tests__/application_manifest_plugin.test.ts +317 -232
- package/src/vite/application_manifest_plugin.ts +160 -90
- 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,23 @@ 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
|
+
widgetSettings: {
|
|
47
|
+
description: "Test",
|
|
48
|
+
domain: "https://example.com",
|
|
49
|
+
prefersBorder: true,
|
|
50
|
+
} satisfies ManifestWidgetSettings,
|
|
51
|
+
}),
|
|
52
|
+
[`${root}/my-component.tsx`]: `
|
|
53
|
+
const MY_QUERY = gql\`query HelloWorldQuery($name: string!) @tool(name: "hello-world", description: "This is an awesome tool!", extraInputs: [{
|
|
54
|
+
name: "doStuff",
|
|
55
|
+
type: "boolean",
|
|
56
|
+
description: "Should we do stuff?"
|
|
57
|
+
}]) { helloWorld(name: $name) }\`;
|
|
58
|
+
`,
|
|
59
59
|
});
|
|
60
|
+
|
|
60
61
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
61
62
|
Promise.resolve(["my-component.tsx"])
|
|
62
63
|
);
|
|
@@ -114,19 +115,21 @@ describe("buildStart", () => {
|
|
|
114
115
|
],
|
|
115
116
|
"resource": "http://localhost:undefined",
|
|
116
117
|
"version": "1",
|
|
118
|
+
"widgetSettings": {
|
|
119
|
+
"description": "Test",
|
|
120
|
+
"domain": "https://example.com",
|
|
121
|
+
"prefersBorder": true,
|
|
122
|
+
},
|
|
117
123
|
}
|
|
118
124
|
`);
|
|
119
125
|
});
|
|
120
126
|
|
|
121
127
|
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
|
-
}
|
|
128
|
+
mockReadFile({
|
|
129
|
+
"package.json": JSON.stringify({}),
|
|
130
|
+
"my-component.tsx": `
|
|
131
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
132
|
+
`,
|
|
130
133
|
});
|
|
131
134
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
132
135
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -142,14 +145,11 @@ describe("buildStart", () => {
|
|
|
142
145
|
});
|
|
143
146
|
|
|
144
147
|
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
|
-
}
|
|
148
|
+
mockReadFile({
|
|
149
|
+
"package.json": JSON.stringify({}),
|
|
150
|
+
[`${root}/my-component.tsx`]: `
|
|
151
|
+
const MY_QUERY = \`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
152
|
+
`,
|
|
153
153
|
});
|
|
154
154
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
155
155
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -187,14 +187,11 @@ describe("buildStart", () => {
|
|
|
187
187
|
});
|
|
188
188
|
|
|
189
189
|
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
|
-
}
|
|
190
|
+
mockReadFile({
|
|
191
|
+
"package.json": JSON.stringify({}),
|
|
192
|
+
[`${root}/my-component.tsx`]: `
|
|
193
|
+
const MY_QUERY = gql\`query HelloWorldQuery { helloWorld }\`;
|
|
194
|
+
`,
|
|
198
195
|
});
|
|
199
196
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
200
197
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -244,14 +241,11 @@ describe("buildStart", () => {
|
|
|
244
241
|
});
|
|
245
242
|
|
|
246
243
|
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
|
-
}
|
|
244
|
+
mockReadFile({
|
|
245
|
+
"package.json": JSON.stringify({}),
|
|
246
|
+
[`${root}/my-component.tsx`]: `
|
|
247
|
+
const MY_QUERY = gql\`query HelloWorldQuery @prefetch { helloWorld }\`;
|
|
248
|
+
`,
|
|
255
249
|
});
|
|
256
250
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
257
251
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -302,15 +296,12 @@ describe("buildStart", () => {
|
|
|
302
296
|
});
|
|
303
297
|
|
|
304
298
|
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
|
-
}
|
|
299
|
+
mockReadFile({
|
|
300
|
+
"package.json": JSON.stringify({}),
|
|
301
|
+
"my-component.tsx": `
|
|
302
|
+
const MY_QUERY = gql\`query HelloWorldQuery @prefetch { helloWorld }\`;
|
|
303
|
+
const MY_QUERY2 = gql\`query HelloWorldQuery2 @prefetch { helloWorld }\`;
|
|
304
|
+
`,
|
|
314
305
|
});
|
|
315
306
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
316
307
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -328,14 +319,11 @@ describe("buildStart", () => {
|
|
|
328
319
|
});
|
|
329
320
|
|
|
330
321
|
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
|
-
}
|
|
322
|
+
mockReadFile({
|
|
323
|
+
"package.json": JSON.stringify({}),
|
|
324
|
+
[`${root}/my-component.tsx`]: `
|
|
325
|
+
const MY_QUERY = gql\`mutation HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
326
|
+
`,
|
|
339
327
|
});
|
|
340
328
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
341
329
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -390,14 +378,11 @@ describe("buildStart", () => {
|
|
|
390
378
|
});
|
|
391
379
|
|
|
392
380
|
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
|
-
}
|
|
381
|
+
mockReadFile({
|
|
382
|
+
"package.json": JSON.stringify({}),
|
|
383
|
+
"my-component.tsx": `
|
|
384
|
+
const MY_QUERY = gql\`subscription HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
385
|
+
`,
|
|
401
386
|
});
|
|
402
387
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
403
388
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -416,18 +401,15 @@ describe("buildStart", () => {
|
|
|
416
401
|
});
|
|
417
402
|
|
|
418
403
|
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
|
-
}
|
|
404
|
+
mockReadFile({
|
|
405
|
+
"package.json": JSON.stringify({
|
|
406
|
+
entry: {
|
|
407
|
+
staging: "http://staging.awesome.com",
|
|
408
|
+
},
|
|
409
|
+
}),
|
|
410
|
+
"my-component.tsx": `
|
|
411
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
412
|
+
`,
|
|
431
413
|
});
|
|
432
414
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
433
415
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -444,21 +426,18 @@ describe("buildStart", () => {
|
|
|
444
426
|
});
|
|
445
427
|
await plugin.buildStart();
|
|
446
428
|
|
|
447
|
-
let [
|
|
429
|
+
let [, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
448
430
|
let contentObj = JSON.parse(content);
|
|
449
431
|
|
|
450
432
|
expect(contentObj.resource).toBe("http://staging.awesome.com");
|
|
451
433
|
});
|
|
452
434
|
|
|
453
435
|
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
|
-
}
|
|
436
|
+
mockReadFile({
|
|
437
|
+
"package.json": JSON.stringify({}),
|
|
438
|
+
"my-component.tsx": `
|
|
439
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
440
|
+
`,
|
|
462
441
|
});
|
|
463
442
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
464
443
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -474,21 +453,18 @@ describe("buildStart", () => {
|
|
|
474
453
|
});
|
|
475
454
|
await plugin.buildStart();
|
|
476
455
|
|
|
477
|
-
let [
|
|
456
|
+
let [, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
478
457
|
let contentObj = JSON.parse(content);
|
|
479
458
|
|
|
480
459
|
expect(contentObj.resource).toBe("https://localhost:5678");
|
|
481
460
|
});
|
|
482
461
|
|
|
483
462
|
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
|
-
}
|
|
463
|
+
mockReadFile({
|
|
464
|
+
"package.json": JSON.stringify({}),
|
|
465
|
+
"my-component.tsx": `
|
|
466
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
467
|
+
`,
|
|
492
468
|
});
|
|
493
469
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
494
470
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -504,21 +480,18 @@ describe("buildStart", () => {
|
|
|
504
480
|
});
|
|
505
481
|
await plugin.buildStart();
|
|
506
482
|
|
|
507
|
-
let [
|
|
483
|
+
let [, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
508
484
|
let contentObj = JSON.parse(content);
|
|
509
485
|
|
|
510
486
|
expect(contentObj.resource).toBe("http://awesome.com:5678");
|
|
511
487
|
});
|
|
512
488
|
|
|
513
489
|
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
|
-
}
|
|
490
|
+
mockReadFile({
|
|
491
|
+
"package.json": JSON.stringify({}),
|
|
492
|
+
"my-component.tsx": `
|
|
493
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool { helloWorld }\`;
|
|
494
|
+
`,
|
|
522
495
|
});
|
|
523
496
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
524
497
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -537,14 +510,11 @@ describe("buildStart", () => {
|
|
|
537
510
|
});
|
|
538
511
|
|
|
539
512
|
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
|
-
}
|
|
513
|
+
mockReadFile({
|
|
514
|
+
"package.json": JSON.stringify({}),
|
|
515
|
+
"my-component.tsx": `
|
|
516
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world") { helloWorld }\`;
|
|
517
|
+
`,
|
|
548
518
|
});
|
|
549
519
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
550
520
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -562,15 +532,35 @@ describe("buildStart", () => {
|
|
|
562
532
|
);
|
|
563
533
|
});
|
|
564
534
|
|
|
535
|
+
test("Should error when tool name contains spaces", async () => {
|
|
536
|
+
mockReadFile({
|
|
537
|
+
"package.json": JSON.stringify({}),
|
|
538
|
+
"my-component.tsx": `
|
|
539
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello world", description: "A tool") { helloWorld }\`;
|
|
540
|
+
`,
|
|
541
|
+
});
|
|
542
|
+
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
543
|
+
Promise.resolve(["my-component.tsx"])
|
|
544
|
+
);
|
|
545
|
+
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
546
|
+
vi.spyOn(fs, "writeFileSync");
|
|
547
|
+
|
|
548
|
+
const plugin = ApplicationManifestPlugin();
|
|
549
|
+
plugin.configResolved({ command: "serve", server: {} });
|
|
550
|
+
|
|
551
|
+
await expect(
|
|
552
|
+
async () => await plugin.buildStart()
|
|
553
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
554
|
+
`[Error: Tool with name "hello world" contains spaces which is not allowed.]`
|
|
555
|
+
);
|
|
556
|
+
});
|
|
557
|
+
|
|
565
558
|
test("Should error when tool name is not a string", async () => {
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: true) { helloWorld }\`;
|
|
572
|
-
`;
|
|
573
|
-
}
|
|
559
|
+
mockReadFile({
|
|
560
|
+
"package.json": JSON.stringify({}),
|
|
561
|
+
"my-component.tsx": `
|
|
562
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: true) { helloWorld }\`;
|
|
563
|
+
`,
|
|
574
564
|
});
|
|
575
565
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
576
566
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -589,14 +579,11 @@ describe("buildStart", () => {
|
|
|
589
579
|
});
|
|
590
580
|
|
|
591
581
|
test("Should error when tool description is not a string", async () => {
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: false) { helloWorld }\`;
|
|
598
|
-
`;
|
|
599
|
-
}
|
|
582
|
+
mockReadFile({
|
|
583
|
+
"package.json": JSON.stringify({}),
|
|
584
|
+
"my-component.tsx": `
|
|
585
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: false) { helloWorld }\`;
|
|
586
|
+
`,
|
|
600
587
|
});
|
|
601
588
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
602
589
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -615,14 +602,11 @@ describe("buildStart", () => {
|
|
|
615
602
|
});
|
|
616
603
|
|
|
617
604
|
test("Should error when extraInputs is not an array", async () => {
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "hello", extraInputs: false ) { helloWorld }\`;
|
|
624
|
-
`;
|
|
625
|
-
}
|
|
605
|
+
mockReadFile({
|
|
606
|
+
"package.json": JSON.stringify({}),
|
|
607
|
+
"my-component.tsx": `
|
|
608
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "hello", extraInputs: false ) { helloWorld }\`;
|
|
609
|
+
`,
|
|
626
610
|
});
|
|
627
611
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
628
612
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -640,17 +624,116 @@ describe("buildStart", () => {
|
|
|
640
624
|
);
|
|
641
625
|
});
|
|
642
626
|
|
|
627
|
+
test("Should error when widgetSettings.prefersBorder is not a boolean", async () => {
|
|
628
|
+
mockReadFile({
|
|
629
|
+
"package.json": JSON.stringify({
|
|
630
|
+
widgetSettings: {
|
|
631
|
+
prefersBorder: "test",
|
|
632
|
+
},
|
|
633
|
+
}),
|
|
634
|
+
"my-component.tsx": `
|
|
635
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "test", description: "Test") { helloWorld }\`;
|
|
636
|
+
`,
|
|
637
|
+
});
|
|
638
|
+
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
639
|
+
Promise.resolve(["my-component.tsx"])
|
|
640
|
+
);
|
|
641
|
+
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
642
|
+
vi.spyOn(fs, "writeFileSync");
|
|
643
|
+
|
|
644
|
+
const plugin = ApplicationManifestPlugin();
|
|
645
|
+
plugin.configResolved({ command: "serve", server: {} });
|
|
646
|
+
|
|
647
|
+
await expect(
|
|
648
|
+
async () => await plugin.buildStart()
|
|
649
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
650
|
+
`[Error: Expected 'widgetSettings.prefersBorder' to be of type 'boolean' but found 'string' instead.]`
|
|
651
|
+
);
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
test("Should error when widgetSettings.description is not a string", async () => {
|
|
655
|
+
mockReadFile({
|
|
656
|
+
"package.json": JSON.stringify({
|
|
657
|
+
widgetSettings: {
|
|
658
|
+
description: true,
|
|
659
|
+
},
|
|
660
|
+
}),
|
|
661
|
+
"my-component.tsx": `
|
|
662
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "test", description: "Test") { helloWorld }\`;
|
|
663
|
+
`,
|
|
664
|
+
});
|
|
665
|
+
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
666
|
+
Promise.resolve(["my-component.tsx"])
|
|
667
|
+
);
|
|
668
|
+
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
669
|
+
vi.spyOn(fs, "writeFileSync");
|
|
670
|
+
|
|
671
|
+
const plugin = ApplicationManifestPlugin();
|
|
672
|
+
plugin.configResolved({ command: "serve", server: {} });
|
|
673
|
+
|
|
674
|
+
await expect(
|
|
675
|
+
async () => await plugin.buildStart()
|
|
676
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
677
|
+
`[Error: Expected 'widgetSettings.description' to be of type 'string' but found 'boolean' instead.]`
|
|
678
|
+
);
|
|
679
|
+
});
|
|
680
|
+
|
|
681
|
+
test("Should error when widgetSettings.domain is not a string", async () => {
|
|
682
|
+
mockReadFile({
|
|
683
|
+
"package.json": JSON.stringify({
|
|
684
|
+
widgetSettings: {
|
|
685
|
+
domain: true,
|
|
686
|
+
},
|
|
687
|
+
}),
|
|
688
|
+
"my-component.tsx": `
|
|
689
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "test", description: "Test") { helloWorld }\`;
|
|
690
|
+
`,
|
|
691
|
+
});
|
|
692
|
+
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
693
|
+
Promise.resolve(["my-component.tsx"])
|
|
694
|
+
);
|
|
695
|
+
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
696
|
+
vi.spyOn(fs, "writeFileSync");
|
|
697
|
+
|
|
698
|
+
const plugin = ApplicationManifestPlugin();
|
|
699
|
+
plugin.configResolved({ command: "serve", server: {} });
|
|
700
|
+
|
|
701
|
+
await expect(
|
|
702
|
+
async () => await plugin.buildStart()
|
|
703
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
704
|
+
`[Error: Expected 'widgetSettings.domain' to be of type 'string' but found 'boolean' instead.]`
|
|
705
|
+
);
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
test("Should allow empty widgetSettings value", async () => {
|
|
709
|
+
mockReadFile({
|
|
710
|
+
"package.json": JSON.stringify({
|
|
711
|
+
widgetSettings: {},
|
|
712
|
+
}),
|
|
713
|
+
"my-component.tsx": `
|
|
714
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "test", description: "Test") { helloWorld }\`;
|
|
715
|
+
`,
|
|
716
|
+
});
|
|
717
|
+
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
718
|
+
Promise.resolve(["my-component.tsx"])
|
|
719
|
+
);
|
|
720
|
+
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
721
|
+
vi.spyOn(fs, "writeFileSync");
|
|
722
|
+
|
|
723
|
+
const plugin = ApplicationManifestPlugin();
|
|
724
|
+
plugin.configResolved({ command: "serve", server: {}, build: {} });
|
|
725
|
+
|
|
726
|
+
await expect(plugin.buildStart()).resolves.toBeUndefined();
|
|
727
|
+
});
|
|
728
|
+
|
|
643
729
|
test("Should error when an unknown type is discovered", async () => {
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
}] ) { helloWorld }\`;
|
|
652
|
-
`;
|
|
653
|
-
}
|
|
730
|
+
mockReadFile({
|
|
731
|
+
"package.json": JSON.stringify({}),
|
|
732
|
+
"my-component.tsx": `
|
|
733
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "hello", extraInputs: [{
|
|
734
|
+
name: 3.1
|
|
735
|
+
}] ) { helloWorld }\`;
|
|
736
|
+
`,
|
|
654
737
|
});
|
|
655
738
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
656
739
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -669,25 +752,22 @@ describe("buildStart", () => {
|
|
|
669
752
|
});
|
|
670
753
|
|
|
671
754
|
test("Should order operations and fragments when generating normalized operation", async () => {
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
}\`;
|
|
689
|
-
`;
|
|
690
|
-
}
|
|
755
|
+
mockReadFile({
|
|
756
|
+
"package.json": JSON.stringify({}),
|
|
757
|
+
[`${root}/my-component.tsx`]: `
|
|
758
|
+
const MY_QUERY = gql\`
|
|
759
|
+
fragment A on User { firstName }
|
|
760
|
+
fragment B on User { lastName }
|
|
761
|
+
query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") {
|
|
762
|
+
helloWorld {
|
|
763
|
+
...B
|
|
764
|
+
...A
|
|
765
|
+
...C
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
fragment C on User { middleName }
|
|
769
|
+
}\`;
|
|
770
|
+
`,
|
|
691
771
|
});
|
|
692
772
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
693
773
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -766,18 +846,15 @@ describe("buildStart", () => {
|
|
|
766
846
|
|
|
767
847
|
describe("writeBundle", () => {
|
|
768
848
|
test("Should use custom entry point when in build mode and provided in package.json", async () => {
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
779
|
-
`;
|
|
780
|
-
}
|
|
849
|
+
mockReadFile({
|
|
850
|
+
"package.json": JSON.stringify({
|
|
851
|
+
entry: {
|
|
852
|
+
staging: "http://staging.awesome.com",
|
|
853
|
+
},
|
|
854
|
+
}),
|
|
855
|
+
"my-component.tsx": `
|
|
856
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
857
|
+
`,
|
|
781
858
|
});
|
|
782
859
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
783
860
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -796,21 +873,18 @@ describe("writeBundle", () => {
|
|
|
796
873
|
await plugin.buildStart();
|
|
797
874
|
await plugin.writeBundle();
|
|
798
875
|
|
|
799
|
-
let [
|
|
876
|
+
let [, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
800
877
|
let contentObj = JSON.parse(content);
|
|
801
878
|
|
|
802
879
|
expect(contentObj.resource).toBe("http://staging.awesome.com");
|
|
803
880
|
});
|
|
804
881
|
|
|
805
882
|
test("Should use index.html when in build production and not provided in package.json", async () => {
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
812
|
-
`;
|
|
813
|
-
}
|
|
883
|
+
mockReadFile({
|
|
884
|
+
"package.json": JSON.stringify({}),
|
|
885
|
+
"my-component.tsx": `
|
|
886
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
887
|
+
`,
|
|
814
888
|
});
|
|
815
889
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
816
890
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -829,21 +903,18 @@ describe("writeBundle", () => {
|
|
|
829
903
|
await plugin.buildStart();
|
|
830
904
|
await plugin.writeBundle();
|
|
831
905
|
|
|
832
|
-
let [
|
|
906
|
+
let [, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
833
907
|
let contentObj = JSON.parse(content);
|
|
834
908
|
|
|
835
909
|
expect(contentObj.resource).toBe("index.html");
|
|
836
910
|
});
|
|
837
911
|
|
|
838
912
|
test("Should throw an error when in build mode and using a mode that is not production and not provided in package.json", async () => {
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
845
|
-
`;
|
|
846
|
-
}
|
|
913
|
+
mockReadFile({
|
|
914
|
+
"package.json": JSON.stringify({}),
|
|
915
|
+
"my-component.tsx": `
|
|
916
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
917
|
+
`,
|
|
847
918
|
});
|
|
848
919
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
849
920
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -869,14 +940,11 @@ describe("writeBundle", () => {
|
|
|
869
940
|
});
|
|
870
941
|
|
|
871
942
|
test("Should always write to both locations when running in build mode", async () => {
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
878
|
-
`;
|
|
879
|
-
}
|
|
943
|
+
mockReadFile({
|
|
944
|
+
"package.json": JSON.stringify({}),
|
|
945
|
+
"my-component.tsx": `
|
|
946
|
+
const MY_QUERY = gql\`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
947
|
+
`,
|
|
880
948
|
});
|
|
881
949
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
882
950
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -901,18 +969,15 @@ describe("writeBundle", () => {
|
|
|
901
969
|
|
|
902
970
|
describe("configureServer", () => {
|
|
903
971
|
test("Should write to manifest file when package.json or file is updated", async () => {
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
}]) { helloWorld(name: $name) }\`;
|
|
914
|
-
`;
|
|
915
|
-
}
|
|
972
|
+
mockReadFile({
|
|
973
|
+
"package.json": JSON.stringify({}),
|
|
974
|
+
"my-component.tsx": `
|
|
975
|
+
const MY_QUERY = gql\`query HelloWorldQuery($name: string!) @tool(name: "hello-world", description: "This is an awesome tool!", extraInputs: [{
|
|
976
|
+
name: "doStuff",
|
|
977
|
+
type: "boolean",
|
|
978
|
+
description: "Should we do stuff?"
|
|
979
|
+
}]) { helloWorld(name: $name) }\`;
|
|
980
|
+
`,
|
|
916
981
|
});
|
|
917
982
|
vi.spyOn(glob, "glob").mockImplementation(() =>
|
|
918
983
|
Promise.resolve(["my-component.tsx"])
|
|
@@ -920,16 +985,18 @@ describe("configureServer", () => {
|
|
|
920
985
|
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
921
986
|
vi.spyOn(fs, "writeFileSync");
|
|
922
987
|
|
|
988
|
+
let _callbacks: Function[] = [];
|
|
989
|
+
|
|
923
990
|
const server = {
|
|
924
991
|
watcher: {
|
|
925
992
|
init: () => {
|
|
926
|
-
|
|
993
|
+
_callbacks = [];
|
|
927
994
|
},
|
|
928
995
|
on: (_event: string, callback: Function) => {
|
|
929
|
-
|
|
996
|
+
_callbacks.push(callback);
|
|
930
997
|
},
|
|
931
|
-
trigger: async (file) => {
|
|
932
|
-
for (const callback of
|
|
998
|
+
trigger: async (file: string) => {
|
|
999
|
+
for (const callback of _callbacks) {
|
|
933
1000
|
await callback(file);
|
|
934
1001
|
}
|
|
935
1002
|
},
|
|
@@ -944,10 +1011,28 @@ describe("configureServer", () => {
|
|
|
944
1011
|
build: { outDir: "/dist" },
|
|
945
1012
|
});
|
|
946
1013
|
await plugin.buildStart();
|
|
947
|
-
|
|
1014
|
+
plugin.configureServer(server);
|
|
948
1015
|
await server.watcher.trigger("package.json");
|
|
949
1016
|
await server.watcher.trigger("my-component.tsx");
|
|
950
1017
|
|
|
951
1018
|
expect(fs.writeFileSync).toBeCalledTimes(6);
|
|
952
1019
|
});
|
|
953
1020
|
});
|
|
1021
|
+
|
|
1022
|
+
type FilePath = string;
|
|
1023
|
+
|
|
1024
|
+
function mockReadFile(mocks: Record<FilePath, string | (() => string)>) {
|
|
1025
|
+
vi.spyOn(fs, "readFileSync").mockImplementation((path) => {
|
|
1026
|
+
const mock = mocks[path.toString()];
|
|
1027
|
+
|
|
1028
|
+
if (!mock) {
|
|
1029
|
+
throw new Error(`No matched mock for path '${path}'`);
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
if (typeof mock === "function") {
|
|
1033
|
+
return mock();
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
return mock;
|
|
1037
|
+
});
|
|
1038
|
+
}
|