@esmx/core 3.0.0-rc.59 → 3.0.0-rc.60
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/core.mjs +4 -4
- package/dist/index.d.ts +3 -3
- package/dist/index.mjs +0 -6
- package/dist/manifest-json.d.ts +8 -21
- package/dist/module-config.d.ts +39 -144
- package/dist/module-config.mjs +145 -57
- package/dist/module-config.test.mjs +620 -509
- package/dist/pack-config.d.ts +2 -2
- package/dist/utils/import-map.d.ts +9 -5
- package/dist/utils/import-map.mjs +36 -23
- package/dist/utils/import-map.test.mjs +1139 -103
- package/package.json +3 -3
- package/src/core.ts +5 -4
- package/src/index.ts +14 -9
- package/src/manifest-json.ts +8 -22
- package/src/module-config.test.ts +636 -637
- package/src/module-config.ts +242 -257
- package/src/pack-config.ts +2 -2
- package/src/utils/import-map.test.ts +1207 -110
- package/src/utils/import-map.ts +63 -29
|
@@ -1,608 +1,719 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { describe, expect, it
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
3
|
import {
|
|
4
|
-
|
|
4
|
+
addPackageExportsToScopes,
|
|
5
|
+
createDefaultExports,
|
|
6
|
+
getEnvironmentExports,
|
|
7
|
+
getEnvironmentImports,
|
|
8
|
+
getEnvironmentScopes,
|
|
9
|
+
getEnvironments,
|
|
10
|
+
getLinks,
|
|
11
|
+
parseModuleConfig,
|
|
12
|
+
parsedExportValue,
|
|
13
|
+
processExportArray,
|
|
14
|
+
processObjectExport,
|
|
15
|
+
processStringExport,
|
|
16
|
+
resolveExportFile
|
|
5
17
|
} from "./module-config.mjs";
|
|
6
|
-
describe("
|
|
7
|
-
const testModuleName = "test-module";
|
|
8
|
-
const testRoot = "/test/root";
|
|
18
|
+
describe("Module Config Parser", () => {
|
|
9
19
|
describe("parseModuleConfig", () => {
|
|
10
|
-
it("should parse
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
expect(result.
|
|
14
|
-
expect(result.
|
|
15
|
-
expect(result.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
it("should parse basic module config with name and root", () => {
|
|
21
|
+
const result = parseModuleConfig("test-module", "/test/root");
|
|
22
|
+
expect(result.name).toBe("test-module");
|
|
23
|
+
expect(result.root).toBe("/test/root");
|
|
24
|
+
expect(result.links).toBeDefined();
|
|
25
|
+
expect(result.environments).toBeDefined();
|
|
26
|
+
});
|
|
27
|
+
it("should handle empty config object", () => {
|
|
28
|
+
const result = parseModuleConfig("test-module", "/test/root", {});
|
|
29
|
+
expect(result.name).toBe("test-module");
|
|
30
|
+
expect(result.root).toBe("/test/root");
|
|
31
|
+
});
|
|
32
|
+
it("should handle undefined config parameter", () => {
|
|
33
|
+
const result = parseModuleConfig(
|
|
34
|
+
"test-module",
|
|
35
|
+
"/test/root",
|
|
36
|
+
void 0
|
|
37
|
+
);
|
|
38
|
+
expect(result.name).toBe("test-module");
|
|
39
|
+
expect(result.root).toBe("/test/root");
|
|
40
|
+
});
|
|
41
|
+
it("should process links configuration", () => {
|
|
27
42
|
const config = {
|
|
28
43
|
links: {
|
|
29
|
-
"
|
|
30
|
-
"api-utils": "/absolute/path/api-utils/dist"
|
|
31
|
-
},
|
|
32
|
-
imports: {
|
|
33
|
-
axios: "shared-lib/axios",
|
|
34
|
-
lodash: "shared-lib/lodash"
|
|
35
|
-
},
|
|
36
|
-
exports: {
|
|
37
|
-
axios: "axios",
|
|
38
|
-
"src/utils/format": "./src/utils/format.ts",
|
|
39
|
-
"custom-api": "./src/api/custom.ts"
|
|
44
|
+
"custom-link": "/custom/path"
|
|
40
45
|
}
|
|
41
46
|
};
|
|
42
|
-
const result = parseModuleConfig(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
expect(result.links).toHaveProperty("shared-lib");
|
|
47
|
-
expect(result.links).toHaveProperty("api-utils");
|
|
48
|
-
expect(result.exports).toHaveProperty("axios");
|
|
49
|
-
expect(result.exports).toHaveProperty("src/utils/format");
|
|
50
|
-
expect(result.exports).toHaveProperty("custom-api");
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
describe("links processing", () => {
|
|
54
|
-
it("should create self-link with default dist path", () => {
|
|
55
|
-
const config = {};
|
|
56
|
-
const result = parseModuleConfig(testModuleName, testRoot, config);
|
|
57
|
-
const selfLink = result.links[testModuleName];
|
|
58
|
-
expect(selfLink).toBeDefined();
|
|
59
|
-
expect(selfLink.name).toBe(testModuleName);
|
|
60
|
-
expect(selfLink.root).toBe(path.resolve(testRoot, "dist"));
|
|
61
|
-
expect(selfLink.client).toBe(path.resolve(testRoot, "dist/client"));
|
|
62
|
-
expect(selfLink.server).toBe(path.resolve(testRoot, "dist/server"));
|
|
63
|
-
expect(selfLink.clientManifestJson).toBe(
|
|
64
|
-
path.resolve(testRoot, "dist/client/manifest.json")
|
|
65
|
-
);
|
|
66
|
-
expect(selfLink.serverManifestJson).toBe(
|
|
67
|
-
path.resolve(testRoot, "dist/server/manifest.json")
|
|
47
|
+
const result = parseModuleConfig(
|
|
48
|
+
"test-module",
|
|
49
|
+
"/test/root",
|
|
50
|
+
config
|
|
68
51
|
);
|
|
52
|
+
expect(result.links["custom-link"]).toBeDefined();
|
|
53
|
+
});
|
|
54
|
+
it("should generate client and server environments", () => {
|
|
55
|
+
const result = parseModuleConfig("test-module", "/test/root");
|
|
56
|
+
expect(result.environments.client).toBeDefined();
|
|
57
|
+
expect(result.environments.server).toBeDefined();
|
|
69
58
|
});
|
|
70
|
-
it("should
|
|
59
|
+
it("should handle absolute and relative paths in links", () => {
|
|
71
60
|
const config = {
|
|
72
61
|
links: {
|
|
73
|
-
|
|
62
|
+
absolute: "/absolute/path",
|
|
63
|
+
relative: "relative/path"
|
|
74
64
|
}
|
|
75
65
|
};
|
|
76
|
-
const result = parseModuleConfig(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
expect(sharedLibLink.client).toBe(
|
|
81
|
-
path.resolve(testRoot, "../shared-lib/dist/client")
|
|
82
|
-
);
|
|
83
|
-
expect(sharedLibLink.server).toBe(
|
|
84
|
-
path.resolve(testRoot, "../shared-lib/dist/server")
|
|
66
|
+
const result = parseModuleConfig(
|
|
67
|
+
"test-module",
|
|
68
|
+
"/test/root",
|
|
69
|
+
config
|
|
85
70
|
);
|
|
71
|
+
expect(result.links.absolute.root).toBe("/absolute/path");
|
|
72
|
+
expect(result.links.relative.root).toBe("relative/path");
|
|
73
|
+
});
|
|
74
|
+
it("should maintain type safety across transformations", () => {
|
|
75
|
+
const result = parseModuleConfig("test-module", "/test/root");
|
|
76
|
+
expect(typeof result.name).toBe("string");
|
|
77
|
+
expect(typeof result.root).toBe("string");
|
|
78
|
+
expect(typeof result.links).toBe("object");
|
|
79
|
+
expect(typeof result.environments).toBe("object");
|
|
86
80
|
});
|
|
87
|
-
|
|
88
|
-
|
|
81
|
+
});
|
|
82
|
+
describe("getLinks", () => {
|
|
83
|
+
it("should create default link for module name", () => {
|
|
84
|
+
const result = getLinks("test-module", "/test/root", {});
|
|
85
|
+
expect(result["test-module"]).toBeDefined();
|
|
86
|
+
expect(result["test-module"].name).toBe("test-module");
|
|
87
|
+
});
|
|
88
|
+
it("should process custom links configuration", () => {
|
|
89
89
|
const config = {
|
|
90
90
|
links: {
|
|
91
|
-
"
|
|
91
|
+
"custom-link": "/custom/path"
|
|
92
92
|
}
|
|
93
93
|
};
|
|
94
|
-
const result =
|
|
95
|
-
|
|
96
|
-
expect(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
);
|
|
101
|
-
expect(
|
|
102
|
-
|
|
103
|
-
|
|
94
|
+
const result = getLinks("test-module", "/test/root", config);
|
|
95
|
+
expect(result["custom-link"]).toBeDefined();
|
|
96
|
+
expect(result["custom-link"].name).toBe("custom-link");
|
|
97
|
+
});
|
|
98
|
+
it("should handle empty links object", () => {
|
|
99
|
+
const result = getLinks("test-module", "/test/root", {});
|
|
100
|
+
expect(Object.keys(result)).toHaveLength(1);
|
|
101
|
+
expect(result["test-module"]).toBeDefined();
|
|
102
|
+
});
|
|
103
|
+
it("should resolve absolute paths correctly", () => {
|
|
104
|
+
const config = {
|
|
105
|
+
links: {
|
|
106
|
+
absolute: "/absolute/path"
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
const result = getLinks("test-module", "/test/root", config);
|
|
110
|
+
expect(result.absolute.root).toBe("/absolute/path");
|
|
104
111
|
});
|
|
105
|
-
it("should
|
|
112
|
+
it("should resolve relative paths from root", () => {
|
|
106
113
|
const config = {
|
|
107
114
|
links: {
|
|
108
|
-
|
|
109
|
-
lib2: "/absolute/lib2/dist",
|
|
110
|
-
lib3: "./relative/lib3/dist"
|
|
115
|
+
relative: "relative/path"
|
|
111
116
|
}
|
|
112
117
|
};
|
|
113
|
-
const result =
|
|
114
|
-
expect(
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
118
|
+
const result = getLinks("test-module", "/test/root", config);
|
|
119
|
+
expect(result.relative.root).toBe("relative/path");
|
|
120
|
+
});
|
|
121
|
+
it("should generate client and server manifest paths", () => {
|
|
122
|
+
const result = getLinks("test-module", "/test/root", {});
|
|
123
|
+
const link = result["test-module"];
|
|
124
|
+
const expectedRoot = path.resolve("/test/root", "dist");
|
|
125
|
+
expect(link.client).toBe(path.resolve(expectedRoot, "client"));
|
|
126
|
+
expect(link.clientManifestJson).toBe(
|
|
127
|
+
path.resolve(expectedRoot, "client/manifest.json")
|
|
128
|
+
);
|
|
129
|
+
expect(link.server).toBe(path.resolve(expectedRoot, "server"));
|
|
130
|
+
expect(link.serverManifestJson).toBe(
|
|
131
|
+
path.resolve(expectedRoot, "server/manifest.json")
|
|
132
|
+
);
|
|
133
|
+
});
|
|
134
|
+
it("should handle Windows path separators", () => {
|
|
135
|
+
const result = getLinks("test-module", "C:\\test\\root", {});
|
|
136
|
+
const link = result["test-module"];
|
|
137
|
+
expect(link.client).toMatch(/[/\\]/);
|
|
138
|
+
expect(link.server).toMatch(/[/\\]/);
|
|
139
|
+
});
|
|
140
|
+
it("should handle Unix path separators", () => {
|
|
141
|
+
const result = getLinks("test-module", "/test/root", {});
|
|
142
|
+
const link = result["test-module"];
|
|
143
|
+
const expectedRoot = path.resolve("/test/root", "dist");
|
|
144
|
+
expect(link.client).toBe(path.resolve(expectedRoot, "client"));
|
|
145
|
+
expect(link.server).toBe(path.resolve(expectedRoot, "server"));
|
|
146
|
+
});
|
|
147
|
+
it("should handle paths with special characters", () => {
|
|
148
|
+
const result = getLinks("test-module", "/test/root@1.0.0", {});
|
|
149
|
+
const link = result["test-module"];
|
|
150
|
+
expect(link.root).toBe(path.resolve("/test/root@1.0.0", "dist"));
|
|
151
|
+
});
|
|
152
|
+
it("should handle paths with spaces", () => {
|
|
153
|
+
const result = getLinks(
|
|
154
|
+
"test-module",
|
|
155
|
+
"/test/root with spaces",
|
|
156
|
+
{}
|
|
157
|
+
);
|
|
158
|
+
const link = result["test-module"];
|
|
159
|
+
expect(link.root).toBe(
|
|
160
|
+
path.resolve("/test/root with spaces", "dist")
|
|
161
|
+
);
|
|
119
162
|
});
|
|
120
163
|
});
|
|
121
|
-
describe("
|
|
122
|
-
describe("
|
|
123
|
-
it("should
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
);
|
|
130
|
-
expect(result.exports["src/entry.client"]).toEqual({
|
|
131
|
-
name: "src/entry.client",
|
|
132
|
-
rewrite: true,
|
|
133
|
-
entryPoints: {
|
|
134
|
-
client: "./src/entry.client",
|
|
135
|
-
server: false
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
expect(result.exports["src/entry.server"]).toEqual({
|
|
139
|
-
name: "src/entry.server",
|
|
140
|
-
rewrite: true,
|
|
141
|
-
entryPoints: {
|
|
142
|
-
client: false,
|
|
143
|
-
server: "./src/entry.server"
|
|
164
|
+
describe("Environment Import Functions", () => {
|
|
165
|
+
describe("getEnvironmentImports", () => {
|
|
166
|
+
it("should filter imports by environment", () => {
|
|
167
|
+
const imports = {
|
|
168
|
+
react: "react",
|
|
169
|
+
vue: {
|
|
170
|
+
client: "vue",
|
|
171
|
+
server: "vue/server"
|
|
144
172
|
}
|
|
145
|
-
}
|
|
173
|
+
};
|
|
174
|
+
const clientResult = getEnvironmentImports("client", imports);
|
|
175
|
+
const serverResult = getEnvironmentImports("server", imports);
|
|
176
|
+
expect(clientResult.react).toBe("react");
|
|
177
|
+
expect(clientResult.vue).toBe("vue");
|
|
178
|
+
expect(serverResult.vue).toBe("vue/server");
|
|
146
179
|
});
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const config = {
|
|
151
|
-
exports: ["npm:axios", "npm:lodash"]
|
|
180
|
+
it("should handle string import values", () => {
|
|
181
|
+
const imports = {
|
|
182
|
+
react: "react"
|
|
152
183
|
};
|
|
153
|
-
const result =
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
entryPoints: {
|
|
162
|
-
client: "axios",
|
|
163
|
-
server: "axios"
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
expect(result.exports.lodash).toEqual({
|
|
167
|
-
name: "lodash",
|
|
168
|
-
rewrite: false,
|
|
169
|
-
entryPoints: {
|
|
170
|
-
client: "lodash",
|
|
171
|
-
server: "lodash"
|
|
184
|
+
const result = getEnvironmentImports("client", imports);
|
|
185
|
+
expect(result.react).toBe("react");
|
|
186
|
+
});
|
|
187
|
+
it("should handle object import values with matching environment", () => {
|
|
188
|
+
const imports = {
|
|
189
|
+
vue: {
|
|
190
|
+
client: "vue",
|
|
191
|
+
server: "vue/server"
|
|
172
192
|
}
|
|
173
|
-
}
|
|
193
|
+
};
|
|
194
|
+
const result = getEnvironmentImports("client", imports);
|
|
195
|
+
expect(result.vue).toBe("vue");
|
|
174
196
|
});
|
|
175
|
-
it("should
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
"
|
|
180
|
-
|
|
181
|
-
]
|
|
197
|
+
it("should skip imports when environment value is undefined", () => {
|
|
198
|
+
const imports = {
|
|
199
|
+
vue: {
|
|
200
|
+
client: "vue",
|
|
201
|
+
server: "vue/server"
|
|
202
|
+
}
|
|
182
203
|
};
|
|
183
|
-
const result =
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
);
|
|
188
|
-
expect(result
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
204
|
+
const result = getEnvironmentImports("server", imports);
|
|
205
|
+
expect(result.vue).toBe("vue/server");
|
|
206
|
+
});
|
|
207
|
+
it("should handle empty imports object", () => {
|
|
208
|
+
const result = getEnvironmentImports("client", {});
|
|
209
|
+
expect(Object.keys(result)).toHaveLength(0);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
describe("getEnvironmentScopes", () => {
|
|
213
|
+
it("should process scoped imports per environment", () => {
|
|
214
|
+
const scopes = {
|
|
215
|
+
utils: {
|
|
216
|
+
lodash: "lodash",
|
|
217
|
+
moment: {
|
|
218
|
+
client: "moment",
|
|
219
|
+
server: "moment/server"
|
|
220
|
+
}
|
|
194
221
|
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
222
|
+
};
|
|
223
|
+
const result = getEnvironmentScopes("client", scopes);
|
|
224
|
+
expect(result.utils.lodash).toBe("lodash");
|
|
225
|
+
expect(result.utils.moment).toBe("moment");
|
|
226
|
+
});
|
|
227
|
+
it("should handle empty scopes object", () => {
|
|
228
|
+
const result = getEnvironmentScopes("client", {});
|
|
229
|
+
expect(Object.keys(result)).toHaveLength(0);
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
describe("getEnvironments", () => {
|
|
233
|
+
it("should combine imports, exports and scopes", () => {
|
|
234
|
+
const config = {
|
|
235
|
+
imports: {
|
|
236
|
+
react: "react"
|
|
237
|
+
},
|
|
238
|
+
scopes: {
|
|
239
|
+
utils: {
|
|
240
|
+
lodash: "lodash"
|
|
241
|
+
}
|
|
202
242
|
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
243
|
+
};
|
|
244
|
+
const result = getEnvironments(config, "client", "test-module");
|
|
245
|
+
expect(result.imports.react).toBe("react");
|
|
246
|
+
expect(result.scopes.utils.lodash).toBe("lodash");
|
|
247
|
+
expect(result.exports).toBeDefined();
|
|
248
|
+
});
|
|
249
|
+
it("should preserve import mapping types", () => {
|
|
250
|
+
const config = {
|
|
251
|
+
imports: {
|
|
252
|
+
react: "react"
|
|
210
253
|
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
"jsx",
|
|
219
|
-
"mjsx",
|
|
220
|
-
"cjsx",
|
|
221
|
-
"ts",
|
|
222
|
-
"mts",
|
|
223
|
-
"cts",
|
|
224
|
-
"tsx",
|
|
225
|
-
"mtsx",
|
|
226
|
-
"ctsx"
|
|
227
|
-
];
|
|
254
|
+
};
|
|
255
|
+
const result = getEnvironments(config, "client", "test-module");
|
|
256
|
+
expect(typeof result.imports).toBe("object");
|
|
257
|
+
expect(typeof result.exports).toBe("object");
|
|
258
|
+
expect(typeof result.scopes).toBe("object");
|
|
259
|
+
});
|
|
260
|
+
it("should add pkg exports to scopes with empty string key", () => {
|
|
228
261
|
const config = {
|
|
229
|
-
exports:
|
|
262
|
+
exports: ["pkg:lodash", "pkg:react", "./src/component"]
|
|
230
263
|
};
|
|
231
|
-
const result =
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
);
|
|
236
|
-
|
|
237
|
-
expect(result.exports["src/test"]).toBeDefined();
|
|
238
|
-
});
|
|
264
|
+
const result = getEnvironments(config, "client", "test-module");
|
|
265
|
+
const emptyScope = result.scopes[""];
|
|
266
|
+
expect(emptyScope).toBeDefined();
|
|
267
|
+
expect(emptyScope.lodash).toBe("test-module/lodash");
|
|
268
|
+
expect(emptyScope.react).toBe("test-module/react");
|
|
269
|
+
expect(emptyScope["./src/component"]).toBeUndefined();
|
|
239
270
|
});
|
|
240
|
-
it("should
|
|
271
|
+
it("should not override existing empty string scope", () => {
|
|
241
272
|
const config = {
|
|
242
|
-
exports: [
|
|
243
|
-
|
|
244
|
-
{
|
|
245
|
-
|
|
246
|
-
utils: {
|
|
247
|
-
input: "./src/utils/index.ts",
|
|
248
|
-
rewrite: true
|
|
249
|
-
}
|
|
273
|
+
exports: ["pkg:lodash"],
|
|
274
|
+
scopes: {
|
|
275
|
+
"": {
|
|
276
|
+
existing: "existing-value"
|
|
250
277
|
}
|
|
251
|
-
]
|
|
252
|
-
};
|
|
253
|
-
const result = parseModuleConfig(
|
|
254
|
-
testModuleName,
|
|
255
|
-
testRoot,
|
|
256
|
-
config
|
|
257
|
-
);
|
|
258
|
-
expect(result.exports["custom-api"]).toEqual({
|
|
259
|
-
name: "custom-api",
|
|
260
|
-
rewrite: true,
|
|
261
|
-
entryPoints: {
|
|
262
|
-
client: "./src/api/custom.ts",
|
|
263
|
-
server: "./src/api/custom.ts"
|
|
264
278
|
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
279
|
+
};
|
|
280
|
+
const result = getEnvironments(config, "client", "test-module");
|
|
281
|
+
const emptyScope = result.scopes[""];
|
|
282
|
+
expect(emptyScope).toBeDefined();
|
|
283
|
+
expect(emptyScope.existing).toBe("existing-value");
|
|
284
|
+
expect(emptyScope.lodash).toBe("test-module/lodash");
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
describe("addPackageExportsToScopes", () => {
|
|
288
|
+
it("should create scopes for pkg exports", () => {
|
|
289
|
+
const exports = {
|
|
290
|
+
lodash: { name: "lodash", file: "lodash", pkg: true },
|
|
291
|
+
react: { name: "react", file: "react", pkg: true },
|
|
292
|
+
"./src/component": {
|
|
293
|
+
name: "./src/component",
|
|
294
|
+
file: "./src/component",
|
|
295
|
+
pkg: false
|
|
272
296
|
}
|
|
273
|
-
}
|
|
297
|
+
};
|
|
298
|
+
const scopes = {};
|
|
299
|
+
const result = addPackageExportsToScopes(
|
|
300
|
+
exports,
|
|
301
|
+
scopes,
|
|
302
|
+
"test-module"
|
|
303
|
+
);
|
|
304
|
+
const emptyScope = result[""];
|
|
305
|
+
expect(emptyScope).toBeDefined();
|
|
306
|
+
expect(emptyScope.lodash).toBe("test-module/lodash");
|
|
307
|
+
expect(emptyScope.react).toBe("test-module/react");
|
|
308
|
+
expect(emptyScope["./src/component"]).toBeUndefined();
|
|
274
309
|
});
|
|
275
|
-
it("should
|
|
276
|
-
const
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
310
|
+
it("should not override existing empty string scope", () => {
|
|
311
|
+
const exports = {
|
|
312
|
+
lodash: { name: "lodash", file: "lodash", pkg: true }
|
|
313
|
+
};
|
|
314
|
+
const scopes = {
|
|
315
|
+
"": {
|
|
316
|
+
existing: "existing-value"
|
|
317
|
+
}
|
|
280
318
|
};
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
319
|
+
const result = addPackageExportsToScopes(
|
|
320
|
+
exports,
|
|
321
|
+
scopes,
|
|
322
|
+
"test-module"
|
|
284
323
|
);
|
|
285
|
-
|
|
286
|
-
|
|
324
|
+
const emptyScope = result[""];
|
|
325
|
+
expect(emptyScope.existing).toBe("existing-value");
|
|
326
|
+
expect(emptyScope.lodash).toBe("test-module/lodash");
|
|
327
|
+
});
|
|
328
|
+
it("should handle empty exports", () => {
|
|
329
|
+
const exports = {};
|
|
330
|
+
const scopes = {};
|
|
331
|
+
const result = addPackageExportsToScopes(
|
|
332
|
+
exports,
|
|
333
|
+
scopes,
|
|
334
|
+
"test-module"
|
|
287
335
|
);
|
|
288
|
-
|
|
336
|
+
expect(Object.keys(result)).toHaveLength(0);
|
|
289
337
|
});
|
|
290
338
|
});
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
339
|
+
});
|
|
340
|
+
describe("Export Processing Functions", () => {
|
|
341
|
+
describe("createDefaultExports", () => {
|
|
342
|
+
it("should generate client default exports", () => {
|
|
343
|
+
const result = createDefaultExports("client");
|
|
344
|
+
expect(result["src/entry.client"].file).toBe(
|
|
345
|
+
"./src/entry.client"
|
|
346
|
+
);
|
|
347
|
+
expect(result["src/entry.server"].file).toBe("");
|
|
348
|
+
});
|
|
349
|
+
it("should generate server default exports", () => {
|
|
350
|
+
const result = createDefaultExports("server");
|
|
351
|
+
expect(result["src/entry.client"].file).toBe("");
|
|
352
|
+
expect(result["src/entry.server"].file).toBe(
|
|
353
|
+
"./src/entry.server"
|
|
354
|
+
);
|
|
355
|
+
});
|
|
356
|
+
it("should handle client environment switch case", () => {
|
|
357
|
+
const result = createDefaultExports("client");
|
|
358
|
+
expect(result["src/entry.client"].file).toBe(
|
|
359
|
+
"./src/entry.client"
|
|
360
|
+
);
|
|
361
|
+
expect(result["src/entry.server"].file).toBe("");
|
|
362
|
+
});
|
|
363
|
+
it("should handle server environment switch case", () => {
|
|
364
|
+
const result = createDefaultExports("server");
|
|
365
|
+
expect(result["src/entry.client"].file).toBe("");
|
|
366
|
+
expect(result["src/entry.server"].file).toBe(
|
|
367
|
+
"./src/entry.server"
|
|
368
|
+
);
|
|
369
|
+
});
|
|
370
|
+
});
|
|
371
|
+
describe("processStringExport", () => {
|
|
372
|
+
it("should parse simple string export", () => {
|
|
373
|
+
const result = processStringExport("./src/component");
|
|
374
|
+
expect(result["./src/component"]).toBeDefined();
|
|
375
|
+
expect(result["./src/component"].file).toBe("./src/component");
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
describe("processObjectExport", () => {
|
|
379
|
+
it("should handle environment-specific exports", () => {
|
|
380
|
+
const exportObject = {
|
|
381
|
+
"./src/component": {
|
|
382
|
+
client: "./src/component.client",
|
|
383
|
+
server: "./src/component.server"
|
|
297
384
|
}
|
|
298
385
|
};
|
|
299
|
-
const result =
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
config
|
|
386
|
+
const result = processObjectExport(exportObject, "client");
|
|
387
|
+
expect(result["./src/component"].file).toBe(
|
|
388
|
+
"./src/component.client"
|
|
303
389
|
);
|
|
304
|
-
expect(result.exports.axios).toEqual({
|
|
305
|
-
name: "axios",
|
|
306
|
-
rewrite: true,
|
|
307
|
-
entryPoints: {
|
|
308
|
-
client: "axios",
|
|
309
|
-
server: "axios"
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
expect(result.exports.utils).toEqual({
|
|
313
|
-
name: "utils",
|
|
314
|
-
rewrite: true,
|
|
315
|
-
entryPoints: {
|
|
316
|
-
client: "./src/utils/index.ts",
|
|
317
|
-
server: "./src/utils/index.ts"
|
|
318
|
-
}
|
|
319
|
-
});
|
|
320
390
|
});
|
|
321
|
-
it("should process
|
|
322
|
-
const
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
server: "./src/storage/filesystem.ts"
|
|
328
|
-
},
|
|
329
|
-
rewrite: true
|
|
330
|
-
},
|
|
331
|
-
"npm-package": {
|
|
332
|
-
input: "some-package",
|
|
333
|
-
rewrite: false
|
|
334
|
-
}
|
|
391
|
+
it("should process mixed string and object exports", () => {
|
|
392
|
+
const exportObject = {
|
|
393
|
+
"./src/utils": "./src/utils",
|
|
394
|
+
"./src/component": {
|
|
395
|
+
client: "./src/component.client",
|
|
396
|
+
server: "./src/component.server"
|
|
335
397
|
}
|
|
336
398
|
};
|
|
337
|
-
const result =
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
399
|
+
const result = processObjectExport(exportObject, "client");
|
|
400
|
+
expect(result["./src/utils"].file).toBe("./src/utils");
|
|
401
|
+
expect(result["./src/component"].file).toBe(
|
|
402
|
+
"./src/component.client"
|
|
341
403
|
);
|
|
342
|
-
expect(result.exports.storage).toEqual({
|
|
343
|
-
name: "storage",
|
|
344
|
-
rewrite: true,
|
|
345
|
-
entryPoints: {
|
|
346
|
-
client: "./src/storage/indexedDB.ts",
|
|
347
|
-
server: "./src/storage/filesystem.ts"
|
|
348
|
-
}
|
|
349
|
-
});
|
|
350
|
-
expect(result.exports["npm-package"]).toEqual({
|
|
351
|
-
name: "npm-package",
|
|
352
|
-
rewrite: false,
|
|
353
|
-
entryPoints: {
|
|
354
|
-
client: "some-package",
|
|
355
|
-
server: "some-package"
|
|
356
|
-
}
|
|
357
|
-
});
|
|
358
404
|
});
|
|
359
|
-
it("should handle
|
|
360
|
-
const
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
server: "./src/server-feature.ts"
|
|
372
|
-
}
|
|
373
|
-
}
|
|
405
|
+
it("should handle string config values in export object", () => {
|
|
406
|
+
const exportObject = {
|
|
407
|
+
"./src/utils": "./src/utils"
|
|
408
|
+
};
|
|
409
|
+
const result = processObjectExport(exportObject, "client");
|
|
410
|
+
expect(result["./src/utils"].file).toBe("./src/utils");
|
|
411
|
+
});
|
|
412
|
+
it("should handle object config values in export object", () => {
|
|
413
|
+
const exportObject = {
|
|
414
|
+
"./src/component": {
|
|
415
|
+
client: "./src/component.client",
|
|
416
|
+
server: "./src/component.server"
|
|
374
417
|
}
|
|
375
418
|
};
|
|
376
|
-
const result =
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
config
|
|
419
|
+
const result = processObjectExport(exportObject, "client");
|
|
420
|
+
expect(result["./src/component"].file).toBe(
|
|
421
|
+
"./src/component.client"
|
|
380
422
|
);
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
client: "./src/client-feature.ts",
|
|
386
|
-
server: false
|
|
387
|
-
}
|
|
388
|
-
});
|
|
389
|
-
expect(result.exports["server-only"]).toEqual({
|
|
390
|
-
name: "server-only",
|
|
391
|
-
rewrite: true,
|
|
392
|
-
entryPoints: {
|
|
393
|
-
client: false,
|
|
394
|
-
server: "./src/server-feature.ts"
|
|
395
|
-
}
|
|
396
|
-
});
|
|
423
|
+
});
|
|
424
|
+
it("should handle empty export object", () => {
|
|
425
|
+
const result = processObjectExport({}, "client");
|
|
426
|
+
expect(Object.keys(result)).toHaveLength(0);
|
|
397
427
|
});
|
|
398
428
|
});
|
|
399
|
-
describe("
|
|
400
|
-
it("should handle
|
|
429
|
+
describe("resolveExportFile", () => {
|
|
430
|
+
it("should handle string config", () => {
|
|
431
|
+
const result = resolveExportFile(
|
|
432
|
+
"./src/component",
|
|
433
|
+
"client",
|
|
434
|
+
"component"
|
|
435
|
+
);
|
|
436
|
+
expect(result).toBe("./src/component");
|
|
437
|
+
});
|
|
438
|
+
it("should return string config directly", () => {
|
|
439
|
+
const result = resolveExportFile(
|
|
440
|
+
"./src/component",
|
|
441
|
+
"client",
|
|
442
|
+
"component"
|
|
443
|
+
);
|
|
444
|
+
expect(result).toBe("./src/component");
|
|
445
|
+
});
|
|
446
|
+
it("should resolve environment-specific paths", () => {
|
|
401
447
|
const config = {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
},
|
|
413
|
-
// Object with just input
|
|
414
|
-
"with-input": {
|
|
415
|
-
input: "./src/with-input.ts"
|
|
416
|
-
},
|
|
417
|
-
// Object with just rewrite
|
|
418
|
-
"with-rewrite": {
|
|
419
|
-
rewrite: false
|
|
420
|
-
}
|
|
421
|
-
}
|
|
448
|
+
client: "./src/component.client",
|
|
449
|
+
server: "./src/component.server"
|
|
450
|
+
};
|
|
451
|
+
const result = resolveExportFile(config, "client", "component");
|
|
452
|
+
expect(result).toBe("./src/component.client");
|
|
453
|
+
});
|
|
454
|
+
it("should return empty string when value is false", () => {
|
|
455
|
+
const config = {
|
|
456
|
+
client: false,
|
|
457
|
+
server: "./src/component.server"
|
|
422
458
|
};
|
|
423
|
-
const result =
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
459
|
+
const result = resolveExportFile(config, "client", "component");
|
|
460
|
+
expect(result).toBe("");
|
|
461
|
+
});
|
|
462
|
+
it("should return name when value is empty string", () => {
|
|
463
|
+
const config = {
|
|
464
|
+
client: "",
|
|
465
|
+
server: "./src/component.server"
|
|
466
|
+
};
|
|
467
|
+
const result = resolveExportFile(config, "client", "component");
|
|
468
|
+
expect(result).toBe("component");
|
|
469
|
+
});
|
|
470
|
+
it("should return environment value when it's a string", () => {
|
|
471
|
+
const config = {
|
|
472
|
+
client: "./src/component.client",
|
|
473
|
+
server: "./src/component.server"
|
|
474
|
+
};
|
|
475
|
+
const result = resolveExportFile(config, "client", "component");
|
|
476
|
+
expect(result).toBe("./src/component.client");
|
|
477
|
+
});
|
|
478
|
+
it("should return name when environment value is undefined", () => {
|
|
479
|
+
const config = {
|
|
480
|
+
client: "./src/component.client"
|
|
481
|
+
};
|
|
482
|
+
const result = resolveExportFile(config, "server", "component");
|
|
483
|
+
expect(result).toBe("component");
|
|
484
|
+
});
|
|
485
|
+
it("should handle invalid config types gracefully", () => {
|
|
486
|
+
const result = resolveExportFile(
|
|
487
|
+
{},
|
|
488
|
+
"client",
|
|
489
|
+
"component"
|
|
427
490
|
);
|
|
428
|
-
expect(result
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
expect(result
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
entryPoints: {
|
|
448
|
-
client: "./src/with-input.ts",
|
|
449
|
-
server: "./src/with-input.ts"
|
|
450
|
-
}
|
|
451
|
-
});
|
|
452
|
-
expect(result.exports["with-rewrite"]).toEqual({
|
|
453
|
-
name: "with-rewrite",
|
|
454
|
-
rewrite: false,
|
|
455
|
-
entryPoints: {
|
|
456
|
-
client: "with-rewrite",
|
|
457
|
-
server: "with-rewrite"
|
|
491
|
+
expect(result).toBe("component");
|
|
492
|
+
});
|
|
493
|
+
});
|
|
494
|
+
describe("processExportArray", () => {
|
|
495
|
+
it("should combine multiple export configurations", () => {
|
|
496
|
+
const exportArray = ["./src/component1", "./src/component2"];
|
|
497
|
+
const result = processExportArray(exportArray, "client");
|
|
498
|
+
expect(result["./src/component1"]).toBeDefined();
|
|
499
|
+
expect(result["./src/component2"]).toBeDefined();
|
|
500
|
+
});
|
|
501
|
+
it("should handle string items in export array", () => {
|
|
502
|
+
const exportArray = ["./src/component"];
|
|
503
|
+
const result = processExportArray(exportArray, "client");
|
|
504
|
+
expect(result["./src/component"]).toBeDefined();
|
|
505
|
+
});
|
|
506
|
+
it("should handle object items in export array", () => {
|
|
507
|
+
const exportArray = [
|
|
508
|
+
{
|
|
509
|
+
"./src/component": "./src/component"
|
|
458
510
|
}
|
|
459
|
-
|
|
511
|
+
];
|
|
512
|
+
const result = processExportArray(exportArray, "client");
|
|
513
|
+
expect(result["./src/component"]).toBeDefined();
|
|
514
|
+
});
|
|
515
|
+
it("should handle empty export array", () => {
|
|
516
|
+
const result = processExportArray([], "client");
|
|
517
|
+
expect(Object.keys(result)).toHaveLength(0);
|
|
460
518
|
});
|
|
461
519
|
});
|
|
462
|
-
describe("
|
|
463
|
-
it("should
|
|
520
|
+
describe("getEnvironmentExports", () => {
|
|
521
|
+
it("should merge default and user exports", () => {
|
|
464
522
|
const config = {
|
|
465
|
-
exports:
|
|
466
|
-
"test-export": {
|
|
467
|
-
input: "./src/test.ts"
|
|
468
|
-
// rewrite not specified, should default to true
|
|
469
|
-
}
|
|
470
|
-
}
|
|
523
|
+
exports: ["./src/custom"]
|
|
471
524
|
};
|
|
472
|
-
const result =
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
525
|
+
const result = getEnvironmentExports(config, "client");
|
|
526
|
+
expect(result["src/entry.client"]).toBeDefined();
|
|
527
|
+
expect(result["./src/custom"]).toBeDefined();
|
|
528
|
+
});
|
|
529
|
+
it("should handle config without exports property", () => {
|
|
530
|
+
const result = getEnvironmentExports({}, "client");
|
|
531
|
+
expect(result["src/entry.client"]).toBeDefined();
|
|
478
532
|
});
|
|
479
|
-
it("should
|
|
533
|
+
it("should handle config with exports property", () => {
|
|
480
534
|
const config = {
|
|
481
|
-
exports:
|
|
482
|
-
"fallback-test": {
|
|
483
|
-
// No input or entryPoints specified
|
|
484
|
-
rewrite: false
|
|
485
|
-
}
|
|
486
|
-
}
|
|
535
|
+
exports: ["./src/custom"]
|
|
487
536
|
};
|
|
488
|
-
const result =
|
|
489
|
-
|
|
490
|
-
testRoot,
|
|
491
|
-
config
|
|
492
|
-
);
|
|
493
|
-
expect(result.exports["fallback-test"].entryPoints).toEqual({
|
|
494
|
-
client: "fallback-test",
|
|
495
|
-
server: "fallback-test"
|
|
496
|
-
});
|
|
537
|
+
const result = getEnvironmentExports(config, "client");
|
|
538
|
+
expect(result["./src/custom"]).toBeDefined();
|
|
497
539
|
});
|
|
498
540
|
});
|
|
499
541
|
});
|
|
500
|
-
describe("
|
|
501
|
-
it("should
|
|
502
|
-
const
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
};
|
|
507
|
-
const config = { imports };
|
|
508
|
-
const result = parseModuleConfig(testModuleName, testRoot, config);
|
|
509
|
-
expect(result.imports).toEqual(imports);
|
|
542
|
+
describe("parsedExportValue", () => {
|
|
543
|
+
it("should handle pkg: prefixed exports", () => {
|
|
544
|
+
const result = parsedExportValue("pkg:lodash");
|
|
545
|
+
expect(result.name).toBe("lodash");
|
|
546
|
+
expect(result.pkg).toBe(true);
|
|
547
|
+
expect(result.file).toBe("lodash");
|
|
510
548
|
});
|
|
511
|
-
it("should handle
|
|
512
|
-
const
|
|
513
|
-
|
|
514
|
-
expect(result.
|
|
549
|
+
it("should handle root: prefixed exports", () => {
|
|
550
|
+
const result = parsedExportValue("root:src/component.tsx");
|
|
551
|
+
expect(result.name).toBe("src/component");
|
|
552
|
+
expect(result.pkg).toBe(false);
|
|
553
|
+
expect(result.file).toBe("./src/component.tsx");
|
|
515
554
|
});
|
|
516
|
-
it("should
|
|
517
|
-
const
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
};
|
|
522
|
-
const result = parseModuleConfig(testModuleName, testRoot, config);
|
|
523
|
-
expect(result.imports).toEqual({});
|
|
555
|
+
it("should process regular file exports", () => {
|
|
556
|
+
const result = parsedExportValue("./src/component");
|
|
557
|
+
expect(result.name).toBe("./src/component");
|
|
558
|
+
expect(result.pkg).toBe(false);
|
|
559
|
+
expect(result.file).toBe("./src/component");
|
|
524
560
|
});
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
};
|
|
531
|
-
const result = parseModuleConfig(testModuleName, testRoot, config);
|
|
532
|
-
expect(result.exports).toHaveProperty("src/entry.client");
|
|
533
|
-
expect(result.exports).toHaveProperty("src/entry.server");
|
|
534
|
-
expect(Object.keys(result.exports)).toHaveLength(2);
|
|
561
|
+
it("should handle pkg: prefixed values correctly", () => {
|
|
562
|
+
const result = parsedExportValue("pkg:@scope/package");
|
|
563
|
+
expect(result.name).toBe("@scope/package");
|
|
564
|
+
expect(result.pkg).toBe(true);
|
|
565
|
+
expect(result.file).toBe("@scope/package");
|
|
535
566
|
});
|
|
536
|
-
it("should handle
|
|
537
|
-
const
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
expect(result.exports).toHaveProperty("src/entry.client");
|
|
542
|
-
expect(result.exports).toHaveProperty("src/entry.server");
|
|
543
|
-
expect(Object.keys(result.exports)).toHaveLength(2);
|
|
567
|
+
it("should handle root: prefixed values with extension removal", () => {
|
|
568
|
+
const result = parsedExportValue("root:src/component.tsx");
|
|
569
|
+
expect(result.name).toBe("src/component");
|
|
570
|
+
expect(result.pkg).toBe(false);
|
|
571
|
+
expect(result.file).toBe("./src/component.tsx");
|
|
544
572
|
});
|
|
545
|
-
it("should handle
|
|
546
|
-
const
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
expect(result.
|
|
554
|
-
expect(result.
|
|
555
|
-
expect(result.
|
|
556
|
-
});
|
|
557
|
-
it("should
|
|
558
|
-
const
|
|
573
|
+
it("should handle root: prefixed values without extensions", () => {
|
|
574
|
+
const result = parsedExportValue("root:src/utils");
|
|
575
|
+
expect(result.name).toBe("src/utils");
|
|
576
|
+
expect(result.pkg).toBe(false);
|
|
577
|
+
expect(result.file).toBe("./src/utils");
|
|
578
|
+
});
|
|
579
|
+
it("should handle regular values without prefixes", () => {
|
|
580
|
+
const result = parsedExportValue("./src/component.tsx");
|
|
581
|
+
expect(result.name).toBe("./src/component.tsx");
|
|
582
|
+
expect(result.pkg).toBe(false);
|
|
583
|
+
expect(result.file).toBe("./src/component.tsx");
|
|
584
|
+
});
|
|
585
|
+
it("should preserve file extensions for non-root exports", () => {
|
|
586
|
+
const result = parsedExportValue("./src/component.tsx");
|
|
587
|
+
expect(result.file).toBe("./src/component.tsx");
|
|
588
|
+
});
|
|
589
|
+
it("should handle malformed pkg: values", () => {
|
|
590
|
+
const result = parsedExportValue("pkg:");
|
|
591
|
+
expect(result.name).toBe("");
|
|
592
|
+
expect(result.pkg).toBe(true);
|
|
593
|
+
expect(result.file).toBe("");
|
|
594
|
+
});
|
|
595
|
+
it("should handle malformed root: values", () => {
|
|
596
|
+
const result = parsedExportValue("root:");
|
|
597
|
+
expect(result.name).toBe("");
|
|
598
|
+
expect(result.pkg).toBe(false);
|
|
599
|
+
expect(result.file).toBe("./");
|
|
600
|
+
});
|
|
601
|
+
it("should handle file extensions correctly in root: prefix", () => {
|
|
602
|
+
const result = parsedExportValue("root:src/component.tsx");
|
|
603
|
+
expect(result.name).toBe("src/component");
|
|
604
|
+
expect(result.file).toBe("./src/component.tsx");
|
|
605
|
+
});
|
|
606
|
+
it("should handle nested paths in pkg: prefix", () => {
|
|
607
|
+
const result = parsedExportValue("pkg:@scope/package/subpath");
|
|
608
|
+
expect(result.name).toBe("@scope/package/subpath");
|
|
609
|
+
expect(result.pkg).toBe(true);
|
|
610
|
+
expect(result.file).toBe("@scope/package/subpath");
|
|
611
|
+
});
|
|
612
|
+
});
|
|
613
|
+
describe("Integration Tests", () => {
|
|
614
|
+
it("should work end-to-end with complex configuration", () => {
|
|
559
615
|
const config = {
|
|
560
616
|
links: {
|
|
561
|
-
|
|
617
|
+
shared: "/shared/modules"
|
|
562
618
|
},
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
619
|
+
imports: {
|
|
620
|
+
react: "react",
|
|
621
|
+
vue: {
|
|
622
|
+
client: "vue",
|
|
623
|
+
server: "vue/server"
|
|
624
|
+
}
|
|
625
|
+
},
|
|
626
|
+
scopes: {
|
|
627
|
+
utils: {
|
|
628
|
+
lodash: "lodash"
|
|
629
|
+
}
|
|
630
|
+
},
|
|
631
|
+
exports: [
|
|
632
|
+
"./src/component",
|
|
633
|
+
{
|
|
634
|
+
"./src/utils": {
|
|
635
|
+
client: "./src/utils.client",
|
|
636
|
+
server: "./src/utils.server"
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
]
|
|
566
640
|
};
|
|
567
641
|
const result = parseModuleConfig(
|
|
568
|
-
|
|
569
|
-
|
|
642
|
+
"test-module",
|
|
643
|
+
"/test/root",
|
|
570
644
|
config
|
|
571
645
|
);
|
|
572
|
-
expect(result.name).toBe(
|
|
573
|
-
expect(result.links).
|
|
574
|
-
expect(result.
|
|
646
|
+
expect(result.name).toBe("test-module");
|
|
647
|
+
expect(result.links.shared).toBeDefined();
|
|
648
|
+
expect(result.environments.client.imports.react).toBe("react");
|
|
649
|
+
expect(result.environments.client.imports.vue).toBe("vue");
|
|
650
|
+
expect(result.environments.server.imports.vue).toBe("vue/server");
|
|
575
651
|
});
|
|
576
|
-
|
|
577
|
-
describe("type safety", () => {
|
|
578
|
-
it("should maintain type safety for ParsedModuleConfig", () => {
|
|
652
|
+
it("should correctly filter environment-specific exports", () => {
|
|
579
653
|
const config = {
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
654
|
+
exports: [
|
|
655
|
+
{
|
|
656
|
+
"./src/component": {
|
|
657
|
+
client: "./src/component.client",
|
|
658
|
+
server: "./src/component.server"
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
]
|
|
583
662
|
};
|
|
584
|
-
const
|
|
585
|
-
|
|
586
|
-
|
|
663
|
+
const clientResult = parseModuleConfig(
|
|
664
|
+
"test-module",
|
|
665
|
+
"/test/root",
|
|
587
666
|
config
|
|
588
667
|
);
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
668
|
+
const serverResult = parseModuleConfig(
|
|
669
|
+
"test-module",
|
|
670
|
+
"/test/root",
|
|
671
|
+
config
|
|
672
|
+
);
|
|
673
|
+
expect(
|
|
674
|
+
clientResult.environments.client.exports["./src/component"].file
|
|
675
|
+
).toBe("./src/component.client");
|
|
676
|
+
expect(
|
|
677
|
+
serverResult.environments.server.exports["./src/component"].file
|
|
678
|
+
).toBe("./src/component.server");
|
|
679
|
+
});
|
|
680
|
+
it("should maintain cross-environment consistency", () => {
|
|
681
|
+
const result = parseModuleConfig("test-module", "/test/root");
|
|
682
|
+
expect(
|
|
683
|
+
result.environments.client.exports["src/entry.client"].file
|
|
684
|
+
).toBe("./src/entry.client");
|
|
685
|
+
expect(
|
|
686
|
+
result.environments.server.exports["src/entry.server"].file
|
|
687
|
+
).toBe("./src/entry.server");
|
|
594
688
|
});
|
|
595
|
-
it("should
|
|
689
|
+
it("should work with path resolution across different environments", () => {
|
|
596
690
|
const config = {
|
|
597
|
-
|
|
691
|
+
links: {
|
|
692
|
+
relative: "relative/path"
|
|
693
|
+
}
|
|
598
694
|
};
|
|
599
|
-
const result = parseModuleConfig(
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
expect(
|
|
605
|
-
|
|
695
|
+
const result = parseModuleConfig(
|
|
696
|
+
"test-module",
|
|
697
|
+
"/test/root",
|
|
698
|
+
config
|
|
699
|
+
);
|
|
700
|
+
expect(result.links.relative.root).toBe("relative/path");
|
|
701
|
+
});
|
|
702
|
+
});
|
|
703
|
+
describe("Error Handling", () => {
|
|
704
|
+
it("should handle invalid config types gracefully in resolveExportFile", () => {
|
|
705
|
+
const result = resolveExportFile({}, "client", "component");
|
|
706
|
+
expect(result).toBe("component");
|
|
707
|
+
});
|
|
708
|
+
it("should handle malformed pkg: values in parsedExportValue", () => {
|
|
709
|
+
const result = parsedExportValue("pkg:");
|
|
710
|
+
expect(result.name).toBe("");
|
|
711
|
+
expect(result.pkg).toBe(true);
|
|
712
|
+
});
|
|
713
|
+
it("should handle malformed root: values in parsedExportValue", () => {
|
|
714
|
+
const result = parsedExportValue("root:");
|
|
715
|
+
expect(result.name).toBe("");
|
|
716
|
+
expect(result.pkg).toBe(false);
|
|
606
717
|
});
|
|
607
718
|
});
|
|
608
719
|
});
|