@apollo/client-ai-apps 0.2.3 → 0.2.4
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/dist/vite/absolute_asset_imports_plugin.d.ts +4 -0
- package/dist/vite/index.d.ts +1 -0
- package/dist/vite/index.js +17 -5
- package/package.json +1 -1
- package/src/vite/absolute_asset_imports_plugin.test.ts +100 -0
- package/src/vite/absolute_asset_imports_plugin.ts +20 -0
- package/src/vite/application_manifest_plugin.test.ts +36 -36
- package/src/vite/application_manifest_plugin.ts +5 -5
- package/src/vite/index.ts +1 -0
package/dist/vite/index.d.ts
CHANGED
package/dist/vite/index.js
CHANGED
|
@@ -157,11 +157,9 @@ var ApplicationManifestPlugin = () => {
|
|
|
157
157
|
resourceDomains: packageJson.csp?.resourceDomains ?? []
|
|
158
158
|
}
|
|
159
159
|
};
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
writeFileSync(dest, JSON.stringify(manifest));
|
|
164
|
-
}
|
|
160
|
+
const dest = path.resolve(root, config.build.outDir, ".application-manifest.json");
|
|
161
|
+
mkdirSync(path.dirname(dest), { recursive: true });
|
|
162
|
+
writeFileSync(dest, JSON.stringify(manifest));
|
|
165
163
|
writeFileSync(".application-manifest.json", JSON.stringify(manifest));
|
|
166
164
|
};
|
|
167
165
|
return {
|
|
@@ -231,7 +229,21 @@ function removeClientDirective(doc) {
|
|
|
231
229
|
}
|
|
232
230
|
});
|
|
233
231
|
}
|
|
232
|
+
|
|
233
|
+
// src/vite/absolute_asset_imports_plugin.ts
|
|
234
|
+
var AbsoluteAssetImportsPlugin = () => {
|
|
235
|
+
return {
|
|
236
|
+
name: "absolute-asset-imports",
|
|
237
|
+
transformIndexHtml(html, ctx) {
|
|
238
|
+
if (!ctx.server) return html;
|
|
239
|
+
let baseUrl = (ctx.server.config?.server?.origin ?? ctx.server.resolvedUrls?.local[0]).replace(/\/$/, "");
|
|
240
|
+
baseUrl = baseUrl.replace(/\/$/, "");
|
|
241
|
+
return html.replace(/(from\s+["'])\/([^"']+)/g, `$1${baseUrl}/$2`).replace(/(src=["'])\/([^"']+)/gi, `$1${baseUrl}/$2`);
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
};
|
|
234
245
|
export {
|
|
246
|
+
AbsoluteAssetImportsPlugin,
|
|
235
247
|
ApplicationManifestPlugin,
|
|
236
248
|
sortTopLevelDefinitions
|
|
237
249
|
};
|
package/package.json
CHANGED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { expect, test, vi, describe, beforeEach, Mock } from "vitest";
|
|
2
|
+
import { AbsoluteAssetImportsPlugin } from "./absolute_asset_imports_plugin";
|
|
3
|
+
|
|
4
|
+
test("Should replace root relative scripts with full url when origin is provided", () => {
|
|
5
|
+
const ctx = {
|
|
6
|
+
server: {
|
|
7
|
+
config: {
|
|
8
|
+
server: {
|
|
9
|
+
origin: "http://localhost:3000/",
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
const html = `<html><head><script type="module" src="/@vite/client"></script></head><body><script module src="/assets/main.ts?t=12345"></script></body></html>`;
|
|
15
|
+
const plugin = AbsoluteAssetImportsPlugin();
|
|
16
|
+
|
|
17
|
+
let result = plugin.transformIndexHtml(html, ctx);
|
|
18
|
+
|
|
19
|
+
expect(result).toMatchInlineSnapshot(
|
|
20
|
+
`"<html><head><script type="module" src="http://localhost:3000/@vite/client"></script></head><body><script module src="http://localhost:3000/assets/main.ts?t=12345"></script></body></html>"`
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test("Should replace root relative scripts with full url when origin is not provided", () => {
|
|
25
|
+
const ctx = {
|
|
26
|
+
server: {
|
|
27
|
+
resolvedUrls: {
|
|
28
|
+
local: ["http://localhost:3000/"],
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
const html = `<html><head> <script type="module">import { injectIntoGlobalHook } from "/@react-refresh";
|
|
33
|
+
injectIntoGlobalHook(window);
|
|
34
|
+
window.$RefreshReg$ = () => {};
|
|
35
|
+
window.$RefreshSig$ = () => (type) => type;</script></head></html>`;
|
|
36
|
+
const plugin = AbsoluteAssetImportsPlugin();
|
|
37
|
+
|
|
38
|
+
let result = plugin.transformIndexHtml(html, ctx);
|
|
39
|
+
|
|
40
|
+
expect(result).toMatchInlineSnapshot(`
|
|
41
|
+
"<html><head> <script type="module">import { injectIntoGlobalHook } from "http://localhost:3000/@react-refresh";
|
|
42
|
+
injectIntoGlobalHook(window);
|
|
43
|
+
window.$RefreshReg$ = () => {};
|
|
44
|
+
window.$RefreshSig$ = () => (type) => type;</script></head></html>"
|
|
45
|
+
`);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("Should replace root relative imports with full url when origin is provided", () => {
|
|
49
|
+
const ctx = {
|
|
50
|
+
server: {
|
|
51
|
+
config: {
|
|
52
|
+
server: {
|
|
53
|
+
origin: "http://localhost:3000/",
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
const html = `<html><head> <script type="module">import { injectIntoGlobalHook } from "/@react-refresh";
|
|
59
|
+
injectIntoGlobalHook(window);
|
|
60
|
+
window.$RefreshReg$ = () => {};
|
|
61
|
+
window.$RefreshSig$ = () => (type) => type;</script></head></html>`;
|
|
62
|
+
const plugin = AbsoluteAssetImportsPlugin();
|
|
63
|
+
|
|
64
|
+
let result = plugin.transformIndexHtml(html, ctx);
|
|
65
|
+
|
|
66
|
+
expect(result).toMatchInlineSnapshot(`
|
|
67
|
+
"<html><head> <script type="module">import { injectIntoGlobalHook } from "http://localhost:3000/@react-refresh";
|
|
68
|
+
injectIntoGlobalHook(window);
|
|
69
|
+
window.$RefreshReg$ = () => {};
|
|
70
|
+
window.$RefreshSig$ = () => (type) => type;</script></head></html>"
|
|
71
|
+
`);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test("Should replace root relative imports with full url when origin is not provided", () => {
|
|
75
|
+
const ctx = {
|
|
76
|
+
server: {
|
|
77
|
+
resolvedUrls: {
|
|
78
|
+
local: ["http://localhost:3000/"],
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
const html = `<html><body><script module src="/assets/main.ts?t=12345"></script></body></html>`;
|
|
83
|
+
const plugin = AbsoluteAssetImportsPlugin();
|
|
84
|
+
|
|
85
|
+
let result = plugin.transformIndexHtml(html, ctx);
|
|
86
|
+
|
|
87
|
+
expect(result).toMatchInlineSnapshot(
|
|
88
|
+
`"<html><body><script module src="http://localhost:3000/assets/main.ts?t=12345"></script></body></html>"`
|
|
89
|
+
);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test("Should not modify html when not running a local server", () => {
|
|
93
|
+
const ctx = {};
|
|
94
|
+
const html = `<html><head><script type="module" src="/@vite/client"></script></head><body><script module src="/assets/main.ts?t=12345"></script></body></html>`;
|
|
95
|
+
const plugin = AbsoluteAssetImportsPlugin();
|
|
96
|
+
|
|
97
|
+
let result = plugin.transformIndexHtml(html, ctx);
|
|
98
|
+
|
|
99
|
+
expect(result).toMatchInlineSnapshot(`"<html><head><script type="module" src="/@vite/client"></script></head><body><script module src="/assets/main.ts?t=12345"></script></body></html>"`);
|
|
100
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const AbsoluteAssetImportsPlugin = () => {
|
|
2
|
+
return {
|
|
3
|
+
name: "absolute-asset-imports",
|
|
4
|
+
|
|
5
|
+
transformIndexHtml(html: string, ctx: any) {
|
|
6
|
+
if (!ctx.server) return html;
|
|
7
|
+
|
|
8
|
+
let baseUrl = (ctx.server.config?.server?.origin ?? ctx.server.resolvedUrls?.local[0]).replace(/\/$/, "");
|
|
9
|
+
baseUrl = baseUrl.replace(/\/$/, "");
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
html
|
|
13
|
+
// import "/@vite/..." or "/@react-refresh"
|
|
14
|
+
.replace(/(from\s+["'])\/([^"']+)/g, `$1${baseUrl}/$2`)
|
|
15
|
+
// src="/src/..."
|
|
16
|
+
.replace(/(src=["'])\/([^"']+)/gi, `$1${baseUrl}/$2`)
|
|
17
|
+
);
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
};
|
|
@@ -4,6 +4,8 @@ import fs from "fs";
|
|
|
4
4
|
import * as glob from "glob";
|
|
5
5
|
import path from "path";
|
|
6
6
|
|
|
7
|
+
const root = process.cwd();
|
|
8
|
+
|
|
7
9
|
vi.mock(import("fs"), async (importOriginal) => {
|
|
8
10
|
const actual = await importOriginal();
|
|
9
11
|
return {
|
|
@@ -21,7 +23,7 @@ vi.mock(import("path"), async (importOriginal) => {
|
|
|
21
23
|
return {
|
|
22
24
|
default: {
|
|
23
25
|
...actual.default,
|
|
24
|
-
resolve: vi.fn(),
|
|
26
|
+
resolve: vi.fn((...args) => args.map((a, i) => (i === 0 ? a : a.replace(/^\//, ""))).join("/")),
|
|
25
27
|
dirname: vi.fn(),
|
|
26
28
|
},
|
|
27
29
|
};
|
|
@@ -43,7 +45,7 @@ describe("buildStart", () => {
|
|
|
43
45
|
vi.spyOn(fs, "readFileSync").mockImplementation((path) => {
|
|
44
46
|
if (path === "package.json") {
|
|
45
47
|
return JSON.stringify({});
|
|
46
|
-
} else if (path === "my-component.tsx") {
|
|
48
|
+
} else if (path === root + "/my-component.tsx") {
|
|
47
49
|
return `
|
|
48
50
|
const MY_QUERY = gql\`query HelloWorldQuery($name: string!) @tool(name: "hello-world", description: "This is an awesome tool!", extraInputs: [{
|
|
49
51
|
name: "doStuff",
|
|
@@ -54,11 +56,10 @@ describe("buildStart", () => {
|
|
|
54
56
|
}
|
|
55
57
|
});
|
|
56
58
|
vi.spyOn(glob, "glob").mockImplementation(() => Promise.resolve(["my-component.tsx"]));
|
|
57
|
-
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
58
59
|
vi.spyOn(fs, "writeFileSync");
|
|
59
60
|
|
|
60
61
|
const plugin = ApplicationManifestPlugin();
|
|
61
|
-
plugin.configResolved({ command: "serve", server: {} });
|
|
62
|
+
plugin.configResolved({ command: "serve", server: {}, build: { outDir: "/dist" } });
|
|
62
63
|
await plugin.buildStart();
|
|
63
64
|
let [file, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
64
65
|
|
|
@@ -66,8 +67,8 @@ describe("buildStart", () => {
|
|
|
66
67
|
let contentObj = JSON.parse(content);
|
|
67
68
|
contentObj.hash = "abc";
|
|
68
69
|
|
|
69
|
-
expect(fs.writeFileSync).
|
|
70
|
-
expect(file).toBe("
|
|
70
|
+
expect(fs.writeFileSync).toHaveBeenCalledTimes(2);
|
|
71
|
+
expect(file).toBe(root + "/dist/.application-manifest.json");
|
|
71
72
|
expect(contentObj).toMatchInlineSnapshot(`
|
|
72
73
|
{
|
|
73
74
|
"csp": {
|
|
@@ -134,18 +135,17 @@ describe("buildStart", () => {
|
|
|
134
135
|
vi.spyOn(fs, "readFileSync").mockImplementation((path) => {
|
|
135
136
|
if (path === "package.json") {
|
|
136
137
|
return JSON.stringify({});
|
|
137
|
-
} else if (path === "my-component.tsx") {
|
|
138
|
+
} else if (path === root + "/my-component.tsx") {
|
|
138
139
|
return `
|
|
139
140
|
const MY_QUERY = \`query HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
140
141
|
`;
|
|
141
142
|
}
|
|
142
143
|
});
|
|
143
144
|
vi.spyOn(glob, "glob").mockImplementation(() => Promise.resolve(["my-component.tsx"]));
|
|
144
|
-
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
145
145
|
vi.spyOn(fs, "writeFileSync");
|
|
146
146
|
|
|
147
147
|
const plugin = ApplicationManifestPlugin();
|
|
148
|
-
plugin.configResolved({ command: "serve", server: {} });
|
|
148
|
+
plugin.configResolved({ command: "serve", server: {}, build: { outDir: "/dist" } });
|
|
149
149
|
await plugin.buildStart();
|
|
150
150
|
let [file, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
151
151
|
|
|
@@ -153,8 +153,8 @@ describe("buildStart", () => {
|
|
|
153
153
|
let contentObj = JSON.parse(content);
|
|
154
154
|
contentObj.hash = "abc";
|
|
155
155
|
|
|
156
|
-
expect(fs.writeFileSync).
|
|
157
|
-
expect(file).toBe("
|
|
156
|
+
expect(fs.writeFileSync).toHaveBeenCalledTimes(2);
|
|
157
|
+
expect(file).toBe(root + "/dist/.application-manifest.json");
|
|
158
158
|
expect(contentObj).toMatchInlineSnapshot(`
|
|
159
159
|
{
|
|
160
160
|
"csp": {
|
|
@@ -174,18 +174,17 @@ describe("buildStart", () => {
|
|
|
174
174
|
vi.spyOn(fs, "readFileSync").mockImplementation((path) => {
|
|
175
175
|
if (path === "package.json") {
|
|
176
176
|
return JSON.stringify({});
|
|
177
|
-
} else if (path === "my-component.tsx") {
|
|
177
|
+
} else if (path === root + "/my-component.tsx") {
|
|
178
178
|
return `
|
|
179
179
|
const MY_QUERY = gql\`query HelloWorldQuery { helloWorld }\`;
|
|
180
180
|
`;
|
|
181
181
|
}
|
|
182
182
|
});
|
|
183
183
|
vi.spyOn(glob, "glob").mockImplementation(() => Promise.resolve(["my-component.tsx"]));
|
|
184
|
-
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
185
184
|
vi.spyOn(fs, "writeFileSync");
|
|
186
185
|
|
|
187
186
|
const plugin = ApplicationManifestPlugin();
|
|
188
|
-
plugin.configResolved({ command: "serve", server: {} });
|
|
187
|
+
plugin.configResolved({ command: "serve", server: {}, build: { outDir: "/dist" } });
|
|
189
188
|
await plugin.buildStart();
|
|
190
189
|
let [file, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
191
190
|
|
|
@@ -193,8 +192,8 @@ describe("buildStart", () => {
|
|
|
193
192
|
let contentObj = JSON.parse(content);
|
|
194
193
|
contentObj.hash = "abc";
|
|
195
194
|
|
|
196
|
-
expect(fs.writeFileSync).
|
|
197
|
-
expect(file).toBe("
|
|
195
|
+
expect(fs.writeFileSync).toHaveBeenCalledTimes(2);
|
|
196
|
+
expect(file).toBe(root + "/dist/.application-manifest.json");
|
|
198
197
|
expect(contentObj).toMatchInlineSnapshot(`
|
|
199
198
|
{
|
|
200
199
|
"csp": {
|
|
@@ -226,18 +225,17 @@ describe("buildStart", () => {
|
|
|
226
225
|
vi.spyOn(fs, "readFileSync").mockImplementation((path) => {
|
|
227
226
|
if (path === "package.json") {
|
|
228
227
|
return JSON.stringify({});
|
|
229
|
-
} else if (path === "my-component.tsx") {
|
|
228
|
+
} else if (path === root + "/my-component.tsx") {
|
|
230
229
|
return `
|
|
231
230
|
const MY_QUERY = gql\`query HelloWorldQuery @prefetch { helloWorld }\`;
|
|
232
231
|
`;
|
|
233
232
|
}
|
|
234
233
|
});
|
|
235
234
|
vi.spyOn(glob, "glob").mockImplementation(() => Promise.resolve(["my-component.tsx"]));
|
|
236
|
-
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
237
235
|
vi.spyOn(fs, "writeFileSync");
|
|
238
236
|
|
|
239
237
|
const plugin = ApplicationManifestPlugin();
|
|
240
|
-
plugin.configResolved({ command: "serve", server: {} });
|
|
238
|
+
plugin.configResolved({ command: "serve", server: {}, build: { outDir: "/dist" } });
|
|
241
239
|
await plugin.buildStart();
|
|
242
240
|
let [file, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
243
241
|
|
|
@@ -245,8 +243,8 @@ describe("buildStart", () => {
|
|
|
245
243
|
let contentObj = JSON.parse(content);
|
|
246
244
|
contentObj.hash = "abc";
|
|
247
245
|
|
|
248
|
-
expect(fs.writeFileSync).
|
|
249
|
-
expect(file).toBe("
|
|
246
|
+
expect(fs.writeFileSync).toHaveBeenCalledTimes(2);
|
|
247
|
+
expect(file).toBe(root + "/dist/.application-manifest.json");
|
|
250
248
|
expect(contentObj).toMatchInlineSnapshot(`
|
|
251
249
|
{
|
|
252
250
|
"csp": {
|
|
@@ -301,18 +299,17 @@ describe("buildStart", () => {
|
|
|
301
299
|
vi.spyOn(fs, "readFileSync").mockImplementation((path) => {
|
|
302
300
|
if (path === "package.json") {
|
|
303
301
|
return JSON.stringify({});
|
|
304
|
-
} else if (path === "my-component.tsx") {
|
|
302
|
+
} else if (path === root + "/my-component.tsx") {
|
|
305
303
|
return `
|
|
306
304
|
const MY_QUERY = gql\`mutation HelloWorldQuery @tool(name: "hello-world", description: "This is an awesome tool!") { helloWorld }\`;
|
|
307
305
|
`;
|
|
308
306
|
}
|
|
309
307
|
});
|
|
310
308
|
vi.spyOn(glob, "glob").mockImplementation(() => Promise.resolve(["my-component.tsx"]));
|
|
311
|
-
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
312
309
|
vi.spyOn(fs, "writeFileSync");
|
|
313
310
|
|
|
314
311
|
const plugin = ApplicationManifestPlugin();
|
|
315
|
-
plugin.configResolved({ command: "serve", server: {} });
|
|
312
|
+
plugin.configResolved({ command: "serve", server: {}, build: { outDir: "/dist" } });
|
|
316
313
|
await plugin.buildStart();
|
|
317
314
|
let [file, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
318
315
|
|
|
@@ -320,8 +317,8 @@ describe("buildStart", () => {
|
|
|
320
317
|
let contentObj = JSON.parse(content);
|
|
321
318
|
contentObj.hash = "abc";
|
|
322
319
|
|
|
323
|
-
expect(fs.writeFileSync).
|
|
324
|
-
expect(file).toBe("
|
|
320
|
+
expect(fs.writeFileSync).toHaveBeenCalledTimes(2);
|
|
321
|
+
expect(file).toBe(root + "/dist/.application-manifest.json");
|
|
325
322
|
expect(contentObj).toMatchInlineSnapshot(`
|
|
326
323
|
{
|
|
327
324
|
"csp": {
|
|
@@ -395,7 +392,7 @@ describe("buildStart", () => {
|
|
|
395
392
|
vi.spyOn(fs, "writeFileSync");
|
|
396
393
|
|
|
397
394
|
const plugin = ApplicationManifestPlugin();
|
|
398
|
-
plugin.configResolved({ command: "serve", mode: "staging", server: {} });
|
|
395
|
+
plugin.configResolved({ command: "serve", mode: "staging", server: {}, build: { outDir: "/dist" } });
|
|
399
396
|
await plugin.buildStart();
|
|
400
397
|
|
|
401
398
|
let [file, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
@@ -419,7 +416,7 @@ describe("buildStart", () => {
|
|
|
419
416
|
vi.spyOn(fs, "writeFileSync");
|
|
420
417
|
|
|
421
418
|
const plugin = ApplicationManifestPlugin();
|
|
422
|
-
plugin.configResolved({ command: "serve", server: { https: {}, port: "5678" } });
|
|
419
|
+
plugin.configResolved({ command: "serve", server: { https: {}, port: "5678" }, build: { outDir: "/dist" } });
|
|
423
420
|
await plugin.buildStart();
|
|
424
421
|
|
|
425
422
|
let [file, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
@@ -443,7 +440,11 @@ describe("buildStart", () => {
|
|
|
443
440
|
vi.spyOn(fs, "writeFileSync");
|
|
444
441
|
|
|
445
442
|
const plugin = ApplicationManifestPlugin();
|
|
446
|
-
plugin.configResolved({
|
|
443
|
+
plugin.configResolved({
|
|
444
|
+
command: "serve",
|
|
445
|
+
server: { port: "5678", host: "awesome.com" },
|
|
446
|
+
build: { outDir: "/dist" },
|
|
447
|
+
});
|
|
447
448
|
await plugin.buildStart();
|
|
448
449
|
|
|
449
450
|
let [file, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
@@ -590,7 +591,7 @@ describe("buildStart", () => {
|
|
|
590
591
|
vi.spyOn(fs, "readFileSync").mockImplementation((path) => {
|
|
591
592
|
if (path === "package.json") {
|
|
592
593
|
return JSON.stringify({});
|
|
593
|
-
} else if (path === "my-component.tsx") {
|
|
594
|
+
} else if (path === root + "/my-component.tsx") {
|
|
594
595
|
return `
|
|
595
596
|
const MY_QUERY = gql\`
|
|
596
597
|
fragment A on User { firstName }
|
|
@@ -608,11 +609,10 @@ describe("buildStart", () => {
|
|
|
608
609
|
}
|
|
609
610
|
});
|
|
610
611
|
vi.spyOn(glob, "glob").mockImplementation(() => Promise.resolve(["my-component.tsx"]));
|
|
611
|
-
vi.spyOn(path, "resolve").mockImplementation((_, file) => file);
|
|
612
612
|
vi.spyOn(fs, "writeFileSync");
|
|
613
613
|
|
|
614
614
|
const plugin = ApplicationManifestPlugin();
|
|
615
|
-
plugin.configResolved({ command: "serve", server: {} });
|
|
615
|
+
plugin.configResolved({ command: "serve", server: {}, build: { outDir: "/dist" } });
|
|
616
616
|
await plugin.buildStart();
|
|
617
617
|
let [file, content] = (fs.writeFileSync as unknown as Mock).mock.calls[0];
|
|
618
618
|
|
|
@@ -620,8 +620,8 @@ describe("buildStart", () => {
|
|
|
620
620
|
let contentObj = JSON.parse(content);
|
|
621
621
|
contentObj.hash = "abc";
|
|
622
622
|
|
|
623
|
-
expect(fs.writeFileSync).
|
|
624
|
-
expect(file).toBe(
|
|
623
|
+
expect(fs.writeFileSync).toHaveBeenCalledTimes(2);
|
|
624
|
+
expect(file).toBe(`${root}/dist/.application-manifest.json`);
|
|
625
625
|
expect(contentObj).toMatchInlineSnapshot(`
|
|
626
626
|
{
|
|
627
627
|
"csp": {
|
|
@@ -819,12 +819,12 @@ describe("configureServer", () => {
|
|
|
819
819
|
server.watcher.init();
|
|
820
820
|
|
|
821
821
|
const plugin = ApplicationManifestPlugin();
|
|
822
|
-
plugin.configResolved({ command: "serve", server: {} });
|
|
822
|
+
plugin.configResolved({ command: "serve", server: {}, build: { outDir: "/dist" } });
|
|
823
823
|
await plugin.buildStart();
|
|
824
824
|
await plugin.configureServer(server);
|
|
825
825
|
await server.watcher.trigger("package.json");
|
|
826
826
|
await server.watcher.trigger("my-component.tsx");
|
|
827
827
|
|
|
828
|
-
expect(fs.writeFileSync).toBeCalledTimes(
|
|
828
|
+
expect(fs.writeFileSync).toBeCalledTimes(6);
|
|
829
829
|
});
|
|
830
830
|
});
|
|
@@ -207,11 +207,11 @@ export const ApplicationManifestPlugin = () => {
|
|
|
207
207
|
},
|
|
208
208
|
};
|
|
209
209
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
210
|
+
// Always write to build directory so the MCP server picks it up
|
|
211
|
+
const dest = path.resolve(root, config.build.outDir, ".application-manifest.json");
|
|
212
|
+
mkdirSync(path.dirname(dest), { recursive: true });
|
|
213
|
+
writeFileSync(dest, JSON.stringify(manifest));
|
|
214
|
+
|
|
215
215
|
// Always write to the dev location so that the app can bundle the manifest content
|
|
216
216
|
writeFileSync(".application-manifest.json", JSON.stringify(manifest));
|
|
217
217
|
};
|
package/src/vite/index.ts
CHANGED