@superblocksteam/sdk 2.0.108-next.0 → 2.0.109-next.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/.turbo/turbo-build.log +1 -1
- package/dist/vite-plugin-generate-api-build-manifest.d.mts +3 -9
- package/dist/vite-plugin-generate-api-build-manifest.d.mts.map +1 -1
- package/dist/vite-plugin-generate-api-build-manifest.mjs +37 -38
- package/dist/vite-plugin-generate-api-build-manifest.mjs.map +1 -1
- package/package.json +6 -6
- package/src/vite-plugin-generate-api-build-manifest.mts +57 -66
- package/test/vite-plugin-generate-api-build-manifest.test.mts +264 -0
- package/tsconfig.tsbuildinfo +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -2,15 +2,9 @@ import type { Plugin } from "vite";
|
|
|
2
2
|
/**
|
|
3
3
|
* Vite plugin that generates a build manifest for the application.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* 3. Generate a build manifest for the application
|
|
9
|
-
* 4. Write the build manifest to a file in the build output directory
|
|
10
|
-
*
|
|
11
|
-
* The build manifest is a JSON object with the following properties:
|
|
12
|
-
* - apis: a map of all apis in the application keyed by their file path
|
|
13
|
-
* - apiDependencies: an array where each item represents an api and its dependencies
|
|
5
|
+
* Collects all API metadata in buildStart, then serves the real manifest
|
|
6
|
+
* content via the load hook. This ensures Rollup's content hash reflects
|
|
7
|
+
* the actual manifest data rather than the placeholder stub file.
|
|
14
8
|
*
|
|
15
9
|
* @param root - The root directory of the application
|
|
16
10
|
* @returns A Vite plugin that generates a build manifest for the application
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-plugin-generate-api-build-manifest.d.mts","sourceRoot":"","sources":["../src/vite-plugin-generate-api-build-manifest.mts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"vite-plugin-generate-api-build-manifest.d.mts","sourceRoot":"","sources":["../src/vite-plugin-generate-api-build-manifest.mts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AA+BnC;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,GA0FpD,MAAM,CACZ"}
|
|
@@ -9,18 +9,20 @@ import { resolveLanguageSpecificStepContentFromBlocks } from "@superblocksteam/u
|
|
|
9
9
|
import { getPageName, getScopeIdFromName, } from "@superblocksteam/vite-plugin-file-sync";
|
|
10
10
|
import { collectSdkApisFromRegistry } from "./collect-sdk-apis.mjs";
|
|
11
11
|
import { getLogger } from "./telemetry/logging.js";
|
|
12
|
+
const BUILD_MANIFEST_SUFFIX = path.join("lib", "user-facing", "build-manifest.js");
|
|
13
|
+
// tsdown (library bundler) outputs hashed filenames like build-manifest-BOqMhObV.js
|
|
14
|
+
// in a flattened dist/ directory. Match both the original source path and the
|
|
15
|
+
// hashed dist path so the load hook can replace the placeholder content.
|
|
16
|
+
const BUILD_MANIFEST_HASHED_RE = /[\\/]build-manifest(?:-[A-Za-z0-9]+)?\.js$/;
|
|
17
|
+
function isBuildManifestModule(id) {
|
|
18
|
+
return (id.endsWith(BUILD_MANIFEST_SUFFIX) || BUILD_MANIFEST_HASHED_RE.test(id));
|
|
19
|
+
}
|
|
12
20
|
/**
|
|
13
21
|
* Vite plugin that generates a build manifest for the application.
|
|
14
22
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* 3. Generate a build manifest for the application
|
|
19
|
-
* 4. Write the build manifest to a file in the build output directory
|
|
20
|
-
*
|
|
21
|
-
* The build manifest is a JSON object with the following properties:
|
|
22
|
-
* - apis: a map of all apis in the application keyed by their file path
|
|
23
|
-
* - apiDependencies: an array where each item represents an api and its dependencies
|
|
23
|
+
* Collects all API metadata in buildStart, then serves the real manifest
|
|
24
|
+
* content via the load hook. This ensures Rollup's content hash reflects
|
|
25
|
+
* the actual manifest data rather than the placeholder stub file.
|
|
24
26
|
*
|
|
25
27
|
* @param root - The root directory of the application
|
|
26
28
|
* @returns A Vite plugin that generates a build manifest for the application
|
|
@@ -41,28 +43,26 @@ export function generateApiBuildManifestPlugin(root) {
|
|
|
41
43
|
viteLogger.clearScreen = () => { };
|
|
42
44
|
const sdkApiEnabled = isSdkApiTemplate(process.env.SUPERBLOCKS_APP_TEMPLATE_NAME);
|
|
43
45
|
const apiFiles = {};
|
|
44
|
-
let
|
|
46
|
+
let manifestCode = "export default {};";
|
|
45
47
|
return {
|
|
46
48
|
name: "sb-generate-build-manifest",
|
|
47
49
|
apply: "build",
|
|
48
50
|
enforce: "pre",
|
|
49
51
|
async buildStart() {
|
|
50
|
-
if (sdkApiEnabled)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
52
|
+
if (!sdkApiEnabled) {
|
|
53
|
+
const apiDocuments = await fg(["**/api.yaml", "**/api.yml"], {
|
|
54
|
+
cwd: root,
|
|
55
|
+
});
|
|
56
|
+
for (const apiFilePath of apiDocuments) {
|
|
57
|
+
const absoluteApiFilePath = path.join(root, apiFilePath);
|
|
58
|
+
const document = await fs.readFile(absoluteApiFilePath, "utf-8");
|
|
59
|
+
const apiPb = yaml.parse(document);
|
|
60
|
+
await resolveLanguageSpecificStepContentFromBlocks(path.dirname(absoluteApiFilePath), apiPb.blocks ?? [], {});
|
|
61
|
+
const pageName = getPageName(apiFilePath);
|
|
62
|
+
apiPb.metadata.id = apiPb.metadata.name;
|
|
63
|
+
apiFiles[apiFilePath] = { apiPb, pageName };
|
|
64
|
+
}
|
|
63
65
|
}
|
|
64
|
-
},
|
|
65
|
-
async generateBundle(_options, bundle) {
|
|
66
66
|
const allApis = Object.entries(apiFiles).reduce((acc, [id, api]) => {
|
|
67
67
|
acc[id] = {
|
|
68
68
|
api,
|
|
@@ -76,22 +76,21 @@ export function generateApiBuildManifestPlugin(root) {
|
|
|
76
76
|
readFile: (p, enc) => fs.readFile(p, enc),
|
|
77
77
|
})
|
|
78
78
|
: {};
|
|
79
|
-
|
|
79
|
+
manifestCode = `export default ${JSON.stringify({
|
|
80
80
|
apis: allApis,
|
|
81
81
|
apiDependencies: [],
|
|
82
82
|
sdkApis,
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
83
|
+
})};`;
|
|
84
|
+
},
|
|
85
|
+
load(id) {
|
|
86
|
+
if (isBuildManifestModule(id)) {
|
|
87
|
+
return manifestCode;
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
augmentChunkHash(chunkInfo) {
|
|
91
|
+
const hasBuildManifest = Object.keys(chunkInfo.modules).some(isBuildManifestModule);
|
|
92
|
+
if (hasBuildManifest) {
|
|
93
|
+
return manifestCode;
|
|
95
94
|
}
|
|
96
95
|
},
|
|
97
96
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-plugin-generate-api-build-manifest.mjs","sourceRoot":"","sources":["../src/vite-plugin-generate-api-build-manifest.mts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,MAAM,WAAW,CAAC;AAC3B,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,4CAA4C,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EACL,WAAW,EACX,kBAAkB,GACnB,MAAM,wCAAwC,CAAC;AAEhD,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"vite-plugin-generate-api-build-manifest.mjs","sourceRoot":"","sources":["../src/vite-plugin-generate-api-build-manifest.mts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superblocksteam/sdk",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.109-next.0",
|
|
4
4
|
"description": "Superblocks JS SDK",
|
|
5
5
|
"homepage": "https://www.superblocks.com",
|
|
6
6
|
"license": "Superblocks Community Software License",
|
|
@@ -48,11 +48,11 @@
|
|
|
48
48
|
"vite-tsconfig-paths": "^6.0.4",
|
|
49
49
|
"winston": "^3.17.0",
|
|
50
50
|
"yaml": "^2.7.1",
|
|
51
|
-
"@superblocksteam/library-shared": "2.0.
|
|
52
|
-
"@superblocksteam/shared": "0.9578.
|
|
53
|
-
"@superblocksteam/telemetry": "2.0.
|
|
54
|
-
"@superblocksteam/util": "2.0.
|
|
55
|
-
"@superblocksteam/vite-plugin-file-sync": "2.0.
|
|
51
|
+
"@superblocksteam/library-shared": "2.0.109-next.0",
|
|
52
|
+
"@superblocksteam/shared": "0.9578.12",
|
|
53
|
+
"@superblocksteam/telemetry": "2.0.109-next.0",
|
|
54
|
+
"@superblocksteam/util": "2.0.109-next.0",
|
|
55
|
+
"@superblocksteam/vite-plugin-file-sync": "2.0.109-next.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@eslint/js": "^9.39.2",
|
|
@@ -18,25 +18,29 @@ import {
|
|
|
18
18
|
import { collectSdkApisFromRegistry } from "./collect-sdk-apis.mjs";
|
|
19
19
|
import { getLogger } from "./telemetry/logging.js";
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
const BUILD_MANIFEST_SUFFIX = path.join(
|
|
22
|
+
"lib",
|
|
23
|
+
"user-facing",
|
|
24
|
+
"build-manifest.js",
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
// tsdown (library bundler) outputs hashed filenames like build-manifest-BOqMhObV.js
|
|
28
|
+
// in a flattened dist/ directory. Match both the original source path and the
|
|
29
|
+
// hashed dist path so the load hook can replace the placeholder content.
|
|
30
|
+
const BUILD_MANIFEST_HASHED_RE = /[\\/]build-manifest(?:-[A-Za-z0-9]+)?\.js$/;
|
|
31
|
+
|
|
32
|
+
function isBuildManifestModule(id: string): boolean {
|
|
33
|
+
return (
|
|
34
|
+
id.endsWith(BUILD_MANIFEST_SUFFIX) || BUILD_MANIFEST_HASHED_RE.test(id)
|
|
35
|
+
);
|
|
36
|
+
}
|
|
27
37
|
|
|
28
38
|
/**
|
|
29
39
|
* Vite plugin that generates a build manifest for the application.
|
|
30
40
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* 3. Generate a build manifest for the application
|
|
35
|
-
* 4. Write the build manifest to a file in the build output directory
|
|
36
|
-
*
|
|
37
|
-
* The build manifest is a JSON object with the following properties:
|
|
38
|
-
* - apis: a map of all apis in the application keyed by their file path
|
|
39
|
-
* - apiDependencies: an array where each item represents an api and its dependencies
|
|
41
|
+
* Collects all API metadata in buildStart, then serves the real manifest
|
|
42
|
+
* content via the load hook. This ensures Rollup's content hash reflects
|
|
43
|
+
* the actual manifest data rather than the placeholder stub file.
|
|
40
44
|
*
|
|
41
45
|
* @param root - The root directory of the application
|
|
42
46
|
* @returns A Vite plugin that generates a build manifest for the application
|
|
@@ -61,18 +65,7 @@ export function generateApiBuildManifestPlugin(root: string) {
|
|
|
61
65
|
process.env.SUPERBLOCKS_APP_TEMPLATE_NAME,
|
|
62
66
|
);
|
|
63
67
|
const apiFiles: Record<string, DeleteMeLibraryApi> = {};
|
|
64
|
-
let
|
|
65
|
-
apis: Record<string, { api: DeleteMeLibraryApi; scopeId: string }>;
|
|
66
|
-
apiDependencies: ApiDependency[];
|
|
67
|
-
sdkApis: Record<
|
|
68
|
-
string,
|
|
69
|
-
{
|
|
70
|
-
entryPoint: string;
|
|
71
|
-
exportName?: string;
|
|
72
|
-
integrations?: Array<{ key: string; pluginId: string; id: string }>;
|
|
73
|
-
}
|
|
74
|
-
>;
|
|
75
|
-
} = { apis: {}, apiDependencies: [], sdkApis: {} };
|
|
68
|
+
let manifestCode = "export default {};";
|
|
76
69
|
|
|
77
70
|
return {
|
|
78
71
|
name: "sb-generate-build-manifest",
|
|
@@ -80,31 +73,29 @@ export function generateApiBuildManifestPlugin(root: string) {
|
|
|
80
73
|
enforce: "pre",
|
|
81
74
|
|
|
82
75
|
async buildStart() {
|
|
83
|
-
if (sdkApiEnabled)
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
76
|
+
if (!sdkApiEnabled) {
|
|
77
|
+
const apiDocuments = await fg(["**/api.yaml", "**/api.yml"], {
|
|
78
|
+
cwd: root,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
for (const apiFilePath of apiDocuments) {
|
|
82
|
+
const absoluteApiFilePath = path.join(root, apiFilePath);
|
|
83
|
+
|
|
84
|
+
const document = await fs.readFile(absoluteApiFilePath, "utf-8");
|
|
85
|
+
const apiPb = yaml.parse(document);
|
|
86
|
+
|
|
87
|
+
await resolveLanguageSpecificStepContentFromBlocks(
|
|
88
|
+
path.dirname(absoluteApiFilePath),
|
|
89
|
+
apiPb.blocks ?? [],
|
|
90
|
+
{},
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const pageName = getPageName(apiFilePath);
|
|
94
|
+
apiPb.metadata.id = apiPb.metadata.name;
|
|
95
|
+
apiFiles[apiFilePath] = { apiPb, pageName };
|
|
96
|
+
}
|
|
104
97
|
}
|
|
105
|
-
},
|
|
106
98
|
|
|
107
|
-
async generateBundle(_options: any, bundle: any) {
|
|
108
99
|
const allApis = Object.entries(apiFiles).reduce(
|
|
109
100
|
(acc, [id, api]) => {
|
|
110
101
|
acc[id] = {
|
|
@@ -123,25 +114,25 @@ export function generateApiBuildManifestPlugin(root: string) {
|
|
|
123
114
|
})
|
|
124
115
|
: {};
|
|
125
116
|
|
|
126
|
-
|
|
117
|
+
manifestCode = `export default ${JSON.stringify({
|
|
127
118
|
apis: allApis,
|
|
128
119
|
apiDependencies: [],
|
|
129
120
|
sdkApis,
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
121
|
+
})};`;
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
load(id: string) {
|
|
125
|
+
if (isBuildManifestModule(id)) {
|
|
126
|
+
return manifestCode;
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
augmentChunkHash(chunkInfo: { modules: Record<string, unknown> }) {
|
|
131
|
+
const hasBuildManifest = Object.keys(chunkInfo.modules).some(
|
|
132
|
+
isBuildManifestModule,
|
|
133
|
+
);
|
|
134
|
+
if (hasBuildManifest) {
|
|
135
|
+
return manifestCode;
|
|
145
136
|
}
|
|
146
137
|
},
|
|
147
138
|
} as Plugin;
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
|
|
3
|
+
vi.mock("fs-extra", () => ({
|
|
4
|
+
default: {
|
|
5
|
+
pathExists: vi.fn(),
|
|
6
|
+
readFile: vi.fn(),
|
|
7
|
+
},
|
|
8
|
+
}));
|
|
9
|
+
|
|
10
|
+
vi.mock("fast-glob", () => ({
|
|
11
|
+
default: vi.fn().mockResolvedValue([]),
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
vi.mock("@superblocksteam/shared", () => ({
|
|
15
|
+
isSdkApiTemplate: vi.fn().mockReturnValue(false),
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
vi.mock("@superblocksteam/util", () => ({
|
|
19
|
+
resolveLanguageSpecificStepContentFromBlocks: vi.fn(),
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
vi.mock("@superblocksteam/vite-plugin-file-sync", () => ({
|
|
23
|
+
getPageName: vi.fn().mockReturnValue("App"),
|
|
24
|
+
getScopeIdFromName: vi.fn().mockReturnValue("scope-app"),
|
|
25
|
+
}));
|
|
26
|
+
|
|
27
|
+
vi.mock("../src/collect-sdk-apis.mjs", () => ({
|
|
28
|
+
collectSdkApisFromRegistry: vi.fn().mockResolvedValue({}),
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
vi.mock("../src/telemetry/logging.js", () => ({
|
|
32
|
+
getLogger: () => ({
|
|
33
|
+
info: vi.fn(),
|
|
34
|
+
warn: vi.fn(),
|
|
35
|
+
error: vi.fn(),
|
|
36
|
+
}),
|
|
37
|
+
}));
|
|
38
|
+
|
|
39
|
+
const { generateApiBuildManifestPlugin } =
|
|
40
|
+
await import("../src/vite-plugin-generate-api-build-manifest.mjs");
|
|
41
|
+
const fg = (await import("fast-glob")).default as unknown as ReturnType<
|
|
42
|
+
typeof vi.fn
|
|
43
|
+
>;
|
|
44
|
+
const fs = (await import("fs-extra")).default;
|
|
45
|
+
const { isSdkApiTemplate } = await import("@superblocksteam/shared");
|
|
46
|
+
const { collectSdkApisFromRegistry } =
|
|
47
|
+
await import("../src/collect-sdk-apis.mjs");
|
|
48
|
+
|
|
49
|
+
describe("generateApiBuildManifestPlugin", () => {
|
|
50
|
+
const ROOT = "/app";
|
|
51
|
+
|
|
52
|
+
beforeEach(() => {
|
|
53
|
+
vi.clearAllMocks();
|
|
54
|
+
vi.mocked(isSdkApiTemplate).mockReturnValue(false);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
function getPlugin() {
|
|
58
|
+
return generateApiBuildManifestPlugin(ROOT) as any;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
describe("load hook returns real manifest content so Rollup content-hashes it", () => {
|
|
62
|
+
it("returns manifest JSON for build-manifest.js module IDs", async () => {
|
|
63
|
+
const plugin = getPlugin();
|
|
64
|
+
await plugin.buildStart();
|
|
65
|
+
|
|
66
|
+
const id = "/some/path/lib/user-facing/build-manifest.js";
|
|
67
|
+
const result = plugin.load(id);
|
|
68
|
+
|
|
69
|
+
expect(result).toBeDefined();
|
|
70
|
+
expect(result).toContain("export default ");
|
|
71
|
+
const parsed = JSON.parse(
|
|
72
|
+
result.replace("export default ", "").replace(";", ""),
|
|
73
|
+
);
|
|
74
|
+
expect(parsed).toHaveProperty("apis");
|
|
75
|
+
expect(parsed).toHaveProperty("apiDependencies");
|
|
76
|
+
expect(parsed).toHaveProperty("sdkApis");
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("returns manifest JSON for hashed dist build-manifest module IDs", async () => {
|
|
80
|
+
fg.mockResolvedValue(["pages/App/apis/GetUsers/api.yaml"]);
|
|
81
|
+
vi.mocked(fs.readFile as any).mockResolvedValue(
|
|
82
|
+
"metadata:\n name: GetUsers\nblocks: []\n",
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
const plugin = getPlugin();
|
|
86
|
+
await plugin.buildStart();
|
|
87
|
+
|
|
88
|
+
const id =
|
|
89
|
+
"/node_modules/@superblocksteam/library/dist/build-manifest-BOqMhObV.js";
|
|
90
|
+
const result = plugin.load(id);
|
|
91
|
+
|
|
92
|
+
expect(result).toBeDefined();
|
|
93
|
+
expect(result).toContain("export default ");
|
|
94
|
+
const parsed = JSON.parse(
|
|
95
|
+
result.replace("export default ", "").replace(";", ""),
|
|
96
|
+
);
|
|
97
|
+
expect(parsed).toHaveProperty("apis");
|
|
98
|
+
expect(Object.keys(parsed.apis)).toContain(
|
|
99
|
+
"pages/App/apis/GetUsers/api.yaml",
|
|
100
|
+
);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("does not intercept unrelated module IDs", async () => {
|
|
104
|
+
const plugin = getPlugin();
|
|
105
|
+
await plugin.buildStart();
|
|
106
|
+
|
|
107
|
+
expect(plugin.load("/some/other/module.js")).toBeUndefined();
|
|
108
|
+
expect(plugin.load("/foo/bar/manifest.js")).toBeUndefined();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("includes YAML API data in the manifest when YAML files exist", async () => {
|
|
112
|
+
fg.mockResolvedValue(["pages/App/apis/GetUsers/api.yaml"]);
|
|
113
|
+
vi.mocked(fs.readFile as any).mockResolvedValue(
|
|
114
|
+
"metadata:\n name: GetUsers\nblocks: []\n",
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
const plugin = getPlugin();
|
|
118
|
+
await plugin.buildStart();
|
|
119
|
+
|
|
120
|
+
const result = plugin.load(
|
|
121
|
+
"/node_modules/@superblocksteam/library/src/lib/user-facing/build-manifest.js",
|
|
122
|
+
);
|
|
123
|
+
const parsed = JSON.parse(
|
|
124
|
+
result.replace("export default ", "").replace(";", ""),
|
|
125
|
+
);
|
|
126
|
+
expect(Object.keys(parsed.apis)).toContain(
|
|
127
|
+
"pages/App/apis/GetUsers/api.yaml",
|
|
128
|
+
);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it("includes SDK API data when SDK template is enabled", async () => {
|
|
132
|
+
vi.mocked(isSdkApiTemplate).mockReturnValue(true);
|
|
133
|
+
vi.mocked(collectSdkApisFromRegistry as any).mockResolvedValue({
|
|
134
|
+
GetUsers: {
|
|
135
|
+
entryPoint: "server/apis/GetUsers/api.ts",
|
|
136
|
+
integrations: [{ key: "db", pluginId: "postgres", id: "pg-1" }],
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
const plugin = getPlugin();
|
|
141
|
+
await plugin.buildStart();
|
|
142
|
+
|
|
143
|
+
const result = plugin.load("/lib/user-facing/build-manifest.js");
|
|
144
|
+
const parsed = JSON.parse(
|
|
145
|
+
result.replace("export default ", "").replace(";", ""),
|
|
146
|
+
);
|
|
147
|
+
expect(parsed.sdkApis).toEqual({
|
|
148
|
+
GetUsers: {
|
|
149
|
+
entryPoint: "server/apis/GetUsers/api.ts",
|
|
150
|
+
integrations: [{ key: "db", pluginId: "postgres", id: "pg-1" }],
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
describe("augmentChunkHash feeds manifest into Rollup content hash", () => {
|
|
157
|
+
it("returns manifestCode for chunks containing the hashed dist build-manifest module", async () => {
|
|
158
|
+
fg.mockResolvedValue(["pages/App/apis/GetUsers/api.yaml"]);
|
|
159
|
+
vi.mocked(fs.readFile as any).mockResolvedValue(
|
|
160
|
+
"metadata:\n name: GetUsers\nblocks: []\n",
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
const plugin = getPlugin();
|
|
164
|
+
await plugin.buildStart();
|
|
165
|
+
|
|
166
|
+
const manifestId =
|
|
167
|
+
"/node_modules/@superblocksteam/library/dist/build-manifest-BOqMhObV.js";
|
|
168
|
+
const chunkInfo = {
|
|
169
|
+
modules: { [manifestId]: { renderedLength: 100 } },
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
const result = plugin.augmentChunkHash(chunkInfo);
|
|
173
|
+
expect(result).toBeDefined();
|
|
174
|
+
expect(result).toContain("GetUsers");
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it("returns manifestCode for chunks containing the source build-manifest module", async () => {
|
|
178
|
+
const plugin = getPlugin();
|
|
179
|
+
await plugin.buildStart();
|
|
180
|
+
|
|
181
|
+
const manifestId =
|
|
182
|
+
"/node_modules/@superblocksteam/library/src/lib/user-facing/build-manifest.js";
|
|
183
|
+
const chunkInfo = {
|
|
184
|
+
modules: { [manifestId]: { renderedLength: 50 } },
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const result = plugin.augmentChunkHash(chunkInfo);
|
|
188
|
+
expect(result).toBeDefined();
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it("returns undefined for chunks without build-manifest", async () => {
|
|
192
|
+
const plugin = getPlugin();
|
|
193
|
+
await plugin.buildStart();
|
|
194
|
+
|
|
195
|
+
const chunkInfo = {
|
|
196
|
+
modules: {
|
|
197
|
+
"/some/other/module.js": { renderedLength: 200 },
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
expect(plugin.augmentChunkHash(chunkInfo)).toBeUndefined();
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it("different manifests produce different augmentChunkHash values", async () => {
|
|
205
|
+
fg.mockResolvedValue(["pages/App/apis/GetUsers/api.yaml"]);
|
|
206
|
+
vi.mocked(fs.readFile as any).mockResolvedValue(
|
|
207
|
+
"metadata:\n name: GetUsers\nblocks: []\n",
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
const plugin1 = getPlugin();
|
|
211
|
+
await plugin1.buildStart();
|
|
212
|
+
const hash1 = plugin1.augmentChunkHash({
|
|
213
|
+
modules: {
|
|
214
|
+
"/node_modules/@superblocksteam/library/dist/build-manifest-BOqMhObV.js":
|
|
215
|
+
{ renderedLength: 100 },
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
vi.clearAllMocks();
|
|
220
|
+
vi.mocked(isSdkApiTemplate).mockReturnValue(false);
|
|
221
|
+
fg.mockResolvedValue(["pages/App/apis/ListOrders/api.yaml"]);
|
|
222
|
+
vi.mocked(fs.readFile as any).mockResolvedValue(
|
|
223
|
+
"metadata:\n name: ListOrders\nblocks: []\n",
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
const plugin2 = getPlugin();
|
|
227
|
+
await plugin2.buildStart();
|
|
228
|
+
const hash2 = plugin2.augmentChunkHash({
|
|
229
|
+
modules: {
|
|
230
|
+
"/node_modules/@superblocksteam/library/dist/build-manifest-BOqMhObV.js":
|
|
231
|
+
{ renderedLength: 100 },
|
|
232
|
+
},
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
expect(hash1).not.toEqual(hash2);
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
describe("content changes produce different load output", () => {
|
|
240
|
+
it("different API manifests produce different module content", async () => {
|
|
241
|
+
fg.mockResolvedValue(["pages/App/apis/GetUsers/api.yaml"]);
|
|
242
|
+
vi.mocked(fs.readFile as any).mockResolvedValue(
|
|
243
|
+
"metadata:\n name: GetUsers\nblocks: []\n",
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
const plugin1 = getPlugin();
|
|
247
|
+
await plugin1.buildStart();
|
|
248
|
+
const result1 = plugin1.load("/lib/user-facing/build-manifest.js");
|
|
249
|
+
|
|
250
|
+
vi.clearAllMocks();
|
|
251
|
+
vi.mocked(isSdkApiTemplate).mockReturnValue(false);
|
|
252
|
+
fg.mockResolvedValue(["pages/App/apis/ListOrders/api.yaml"]);
|
|
253
|
+
vi.mocked(fs.readFile as any).mockResolvedValue(
|
|
254
|
+
"metadata:\n name: ListOrders\nblocks: []\n",
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
const plugin2 = getPlugin();
|
|
258
|
+
await plugin2.buildStart();
|
|
259
|
+
const result2 = plugin2.load("/lib/user-facing/build-manifest.js");
|
|
260
|
+
|
|
261
|
+
expect(result1).not.toEqual(result2);
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
});
|