coralite 0.41.0 → 0.43.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/dist/lib/component-setup.d.ts.map +1 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/coralite-element.d.ts +11 -0
- package/dist/lib/coralite-element.d.ts.map +1 -1
- package/dist/lib/coralite-element.js +50 -4
- package/dist/lib/coralite-element.js.map +2 -2
- package/dist/lib/coralite.d.ts +1 -1
- package/dist/lib/coralite.d.ts.map +1 -1
- package/dist/lib/hooks.d.ts +3 -1
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/index.js +430 -168
- package/dist/lib/index.js.map +2 -2
- package/dist/lib/plugin-setup.d.ts.map +1 -1
- package/dist/lib/plugin.js.map +1 -1
- package/dist/lib/renderer.d.ts.map +1 -1
- package/dist/lib/script-manager.d.ts.map +1 -1
- package/dist/lib/utils/client/inject.d.ts +2 -1
- package/dist/lib/utils/client/inject.d.ts.map +1 -1
- package/dist/lib/utils/client/inject.js +2 -2
- package/dist/lib/utils/client/inject.js.map +2 -2
- package/dist/lib/utils/client/runtime.d.ts +4 -4
- package/dist/lib/utils/client/runtime.d.ts.map +1 -1
- package/dist/lib/utils/core.js.map +1 -1
- package/dist/lib/utils/index.js +10 -11
- package/dist/lib/utils/index.js.map +2 -2
- package/dist/lib/utils/server/render.d.ts +1 -1
- package/dist/lib/utils/server/render.d.ts.map +1 -1
- package/dist/lib/utils/server/server.d.ts.map +1 -1
- package/dist/plugins/testing.d.ts.map +1 -1
- package/dist/types/core.d.ts +61 -2
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/script.d.ts +4 -0
- package/dist/types/script.d.ts.map +1 -1
- package/package.json +1 -1
- package/llms.txt +0 -488
package/dist/lib/index.js
CHANGED
|
@@ -53,17 +53,16 @@ function defaultOnError({ level, message, error }) {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
function handleError({ onErrorCallback, data }) {
|
|
56
|
-
const error = data
|
|
57
|
-
if (error && "isCoraliteError" in error && error.isCoraliteError) {
|
|
58
|
-
|
|
59
|
-
data.
|
|
60
|
-
data.
|
|
61
|
-
data.
|
|
62
|
-
data.
|
|
63
|
-
data.
|
|
64
|
-
data.
|
|
65
|
-
data.
|
|
66
|
-
data.stackFile = data.stackFile || coraliteError.stackFile;
|
|
56
|
+
const { error } = data;
|
|
57
|
+
if (error && typeof error === "object" && "isCoraliteError" in error && error.isCoraliteError) {
|
|
58
|
+
data.componentId ??= error.componentId;
|
|
59
|
+
data.filePath ??= error.filePath;
|
|
60
|
+
data.instanceId ??= error.instanceId;
|
|
61
|
+
data.pagePath ??= error.pagePath;
|
|
62
|
+
data.path ??= error.path;
|
|
63
|
+
data.line ??= error.line;
|
|
64
|
+
data.column ??= error.column;
|
|
65
|
+
data.stackFile ??= error.stackFile;
|
|
67
66
|
}
|
|
68
67
|
if (onErrorCallback) {
|
|
69
68
|
onErrorCallback(data);
|
|
@@ -2123,7 +2122,7 @@ function validateSerializable(value, path2 = "root", seen = /* @__PURE__ */ new
|
|
|
2123
2122
|
|
|
2124
2123
|
// lib/utils/server/server.js
|
|
2125
2124
|
import { parse as parseJS } from "acorn";
|
|
2126
|
-
import { simple as walkJS } from "acorn-walk";
|
|
2125
|
+
import { simple as walkJS, ancestor as walkAncestorJS } from "acorn-walk";
|
|
2127
2126
|
import render from "dom-serializer";
|
|
2128
2127
|
import { sanitize } from "isomorphic-dompurify";
|
|
2129
2128
|
|
|
@@ -2189,6 +2188,46 @@ function getAST(code, locations = false) {
|
|
|
2189
2188
|
astCache.set(cacheKey, ast);
|
|
2190
2189
|
return ast;
|
|
2191
2190
|
}
|
|
2191
|
+
function resolveStringValues(node, ancestors) {
|
|
2192
|
+
if (!node) {
|
|
2193
|
+
return [];
|
|
2194
|
+
}
|
|
2195
|
+
if (node.type === "Literal" && typeof node.value === "string") {
|
|
2196
|
+
return [node.value];
|
|
2197
|
+
}
|
|
2198
|
+
if (node.type === "ConditionalExpression") {
|
|
2199
|
+
return [
|
|
2200
|
+
...resolveStringValues(node.consequent, ancestors),
|
|
2201
|
+
...resolveStringValues(node.alternate, ancestors)
|
|
2202
|
+
];
|
|
2203
|
+
}
|
|
2204
|
+
if (node.type === "Identifier" && ancestors && ancestors.length > 0) {
|
|
2205
|
+
const name = node.name;
|
|
2206
|
+
for (let i = ancestors.length - 1; i >= 0; i--) {
|
|
2207
|
+
const ancestor = ancestors[i];
|
|
2208
|
+
let body = null;
|
|
2209
|
+
if (ancestor.type === "BlockStatement" || ancestor.type === "Program") {
|
|
2210
|
+
body = ancestor.body;
|
|
2211
|
+
} else if (ancestor.type === "FunctionExpression" || ancestor.type === "ArrowFunctionExpression" || ancestor.type === "FunctionDeclaration") {
|
|
2212
|
+
if (ancestor.body && ancestor.body.type === "BlockStatement") {
|
|
2213
|
+
body = ancestor.body.body;
|
|
2214
|
+
}
|
|
2215
|
+
}
|
|
2216
|
+
if (body && Array.isArray(body)) {
|
|
2217
|
+
for (const stmt of body) {
|
|
2218
|
+
if (stmt.type === "VariableDeclaration") {
|
|
2219
|
+
for (const decl of stmt.declarations) {
|
|
2220
|
+
if (decl.id.type === "Identifier" && decl.id.name === name && decl.init) {
|
|
2221
|
+
return resolveStringValues(decl.init, []);
|
|
2222
|
+
}
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
2229
|
+
return [];
|
|
2230
|
+
}
|
|
2192
2231
|
function extractFromHTMLString(html, components) {
|
|
2193
2232
|
try {
|
|
2194
2233
|
const matches = html.matchAll(/<([a-zA-Z0-9-]+)/g);
|
|
@@ -2205,7 +2244,7 @@ function findAndExtractScript(code) {
|
|
|
2205
2244
|
const ast = getAST(code, true);
|
|
2206
2245
|
let result = null;
|
|
2207
2246
|
const components = /* @__PURE__ */ new Set();
|
|
2208
|
-
const findHTMLComponents = (node) => {
|
|
2247
|
+
const findHTMLComponents = (node, ancestors = []) => {
|
|
2209
2248
|
if (node.type === "Literal" && typeof node.value === "string") {
|
|
2210
2249
|
extractFromHTMLString(node.value, components);
|
|
2211
2250
|
} else if (node.type === "TemplateLiteral") {
|
|
@@ -2214,32 +2253,50 @@ function findAndExtractScript(code) {
|
|
|
2214
2253
|
extractFromHTMLString(element.value.cooked, components);
|
|
2215
2254
|
}
|
|
2216
2255
|
}
|
|
2256
|
+
} else {
|
|
2257
|
+
const values = resolveStringValues(node, ancestors);
|
|
2258
|
+
for (const val of values) {
|
|
2259
|
+
extractFromHTMLString(val, components);
|
|
2260
|
+
}
|
|
2217
2261
|
}
|
|
2218
2262
|
};
|
|
2219
|
-
|
|
2220
|
-
AssignmentExpression(node) {
|
|
2263
|
+
walkAncestorJS(ast, {
|
|
2264
|
+
AssignmentExpression(node, ancestors) {
|
|
2221
2265
|
if (node.left.type === "MemberExpression" && node.left.property.type === "Identifier" && (node.left.property.name === "innerHTML" || node.left.property.name === "outerHTML")) {
|
|
2222
|
-
findHTMLComponents(node.right);
|
|
2266
|
+
findHTMLComponents(node.right, ancestors);
|
|
2223
2267
|
}
|
|
2224
2268
|
},
|
|
2225
|
-
CallExpression(node) {
|
|
2269
|
+
CallExpression(node, ancestors) {
|
|
2226
2270
|
if (node.callee && node.callee.type === "MemberExpression" && node.callee.object && node.callee.object.type === "Identifier" && node.callee.object.name === "document" && node.callee.property && node.callee.property.type === "Identifier" && node.callee.property.name === "createElement") {
|
|
2227
2271
|
const arg = node.arguments[0];
|
|
2228
|
-
if (arg
|
|
2229
|
-
|
|
2230
|
-
|
|
2272
|
+
if (arg) {
|
|
2273
|
+
const values = resolveStringValues(arg, ancestors);
|
|
2274
|
+
for (const val of values) {
|
|
2275
|
+
if (val.includes("-")) {
|
|
2276
|
+
components.add(val);
|
|
2277
|
+
}
|
|
2231
2278
|
}
|
|
2232
2279
|
}
|
|
2233
2280
|
}
|
|
2234
2281
|
if (node.callee && node.callee.type === "MemberExpression" && node.callee.property && node.callee.property.type === "Identifier" && node.callee.property.name === "insertAdjacentHTML") {
|
|
2235
2282
|
const arg = node.arguments[1];
|
|
2236
2283
|
if (arg) {
|
|
2237
|
-
findHTMLComponents(arg);
|
|
2284
|
+
findHTMLComponents(arg, ancestors);
|
|
2238
2285
|
}
|
|
2239
2286
|
}
|
|
2240
2287
|
if (node.callee && node.callee.type === "Identifier" && node.callee.name === "defineComponent") {
|
|
2241
2288
|
const firstArg = node.arguments[0];
|
|
2242
2289
|
if (firstArg && firstArg.type === "ObjectExpression") {
|
|
2290
|
+
const depsProp = firstArg.properties.find(
|
|
2291
|
+
(prop) => prop.type === "Property" && prop.key && prop.key.type === "Identifier" && prop.key.name === "dependencies"
|
|
2292
|
+
);
|
|
2293
|
+
if (depsProp && depsProp.type === "Property" && depsProp.value.type === "ArrayExpression") {
|
|
2294
|
+
for (const el of depsProp.value.elements) {
|
|
2295
|
+
if (el && el.type === "Literal" && typeof el.value === "string") {
|
|
2296
|
+
components.add(el.value);
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2243
2300
|
const scriptProp = firstArg.properties.find(
|
|
2244
2301
|
(prop) => prop.type === "Property" && prop.key && prop.key.type === "Identifier" && prop.key.name === "client"
|
|
2245
2302
|
);
|
|
@@ -2248,12 +2305,28 @@ function findAndExtractScript(code) {
|
|
|
2248
2305
|
let startLine = value.loc.start.line - 1;
|
|
2249
2306
|
let prefix = "";
|
|
2250
2307
|
let content = "";
|
|
2308
|
+
let instanceIdVar;
|
|
2309
|
+
if (value.params && value.params[0]) {
|
|
2310
|
+
const param = value.params[0];
|
|
2311
|
+
if (param.type === "Identifier") {
|
|
2312
|
+
instanceIdVar = param.name + ".instanceId";
|
|
2313
|
+
} else if (param.type === "ObjectPattern") {
|
|
2314
|
+
const idProp = param.properties.find((p) => p.key?.type === "Identifier" && p.key?.name === "instanceId");
|
|
2315
|
+
if (idProp) {
|
|
2316
|
+
if (idProp.value.type === "Identifier") {
|
|
2317
|
+
instanceIdVar = idProp.value.name;
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2321
|
+
} else if (method) {
|
|
2322
|
+
instanceIdVar = "this._instanceId";
|
|
2323
|
+
}
|
|
2251
2324
|
let source = code.slice(value.start, value.end);
|
|
2252
2325
|
const replacements = [];
|
|
2253
|
-
|
|
2254
|
-
AssignmentExpression(node2) {
|
|
2326
|
+
walkAncestorJS(value, {
|
|
2327
|
+
AssignmentExpression(node2, ancestorsInClient) {
|
|
2255
2328
|
if (node2.left.type === "MemberExpression" && node2.left.property.type === "Identifier" && (node2.left.property.name === "innerHTML" || node2.left.property.name === "outerHTML")) {
|
|
2256
|
-
findHTMLComponents(node2.right);
|
|
2329
|
+
findHTMLComponents(node2.right, [...ancestors, ...ancestorsInClient]);
|
|
2257
2330
|
replacements.push({
|
|
2258
2331
|
start: node2.right.start - value.start,
|
|
2259
2332
|
end: node2.right.start - value.start,
|
|
@@ -2262,28 +2335,36 @@ function findAndExtractScript(code) {
|
|
|
2262
2335
|
replacements.push({
|
|
2263
2336
|
start: node2.right.end - value.start,
|
|
2264
2337
|
end: node2.right.end - value.start,
|
|
2265
|
-
replacement:
|
|
2338
|
+
replacement: `, ${instanceIdVar})`
|
|
2266
2339
|
});
|
|
2267
2340
|
}
|
|
2268
2341
|
},
|
|
2269
|
-
CallExpression(node2) {
|
|
2342
|
+
CallExpression(node2, ancestorsInClient) {
|
|
2343
|
+
const combinedAncestors = [...ancestors, ...ancestorsInClient];
|
|
2270
2344
|
if (node2.callee && node2.callee.type === "MemberExpression" && node2.callee.object && node2.callee.object.type === "Identifier" && node2.callee.object.name === "document" && node2.callee.property && node2.callee.property.type === "Identifier" && node2.callee.property.name === "createElement") {
|
|
2271
2345
|
const arg = node2.arguments[0];
|
|
2272
|
-
if (arg
|
|
2273
|
-
|
|
2274
|
-
|
|
2346
|
+
if (arg) {
|
|
2347
|
+
const values = resolveStringValues(arg, combinedAncestors);
|
|
2348
|
+
let isCustom = false;
|
|
2349
|
+
for (const val of values) {
|
|
2350
|
+
if (val.includes("-")) {
|
|
2351
|
+
components.add(val);
|
|
2352
|
+
isCustom = true;
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2355
|
+
if (isCustom || arg.type === "Literal" && typeof arg.value === "string" && arg.value.includes("-") || arg.type !== "Literal") {
|
|
2356
|
+
replacements.push({
|
|
2357
|
+
start: node2.callee.start - value.start,
|
|
2358
|
+
end: node2.callee.end - value.start,
|
|
2359
|
+
replacement: "createCoraliteElement"
|
|
2360
|
+
});
|
|
2275
2361
|
}
|
|
2276
|
-
replacements.push({
|
|
2277
|
-
start: node2.callee.start - value.start,
|
|
2278
|
-
end: node2.callee.end - value.start,
|
|
2279
|
-
replacement: "createCoraliteElement"
|
|
2280
|
-
});
|
|
2281
2362
|
}
|
|
2282
2363
|
}
|
|
2283
2364
|
if (node2.callee && node2.callee.type === "MemberExpression" && node2.callee.property && node2.callee.property.type === "Identifier" && node2.callee.property.name === "insertAdjacentHTML") {
|
|
2284
2365
|
const arg = node2.arguments[1];
|
|
2285
2366
|
if (arg) {
|
|
2286
|
-
findHTMLComponents(arg);
|
|
2367
|
+
findHTMLComponents(arg, combinedAncestors);
|
|
2287
2368
|
replacements.push({
|
|
2288
2369
|
start: arg.start - value.start,
|
|
2289
2370
|
end: arg.start - value.start,
|
|
@@ -2292,7 +2373,7 @@ function findAndExtractScript(code) {
|
|
|
2292
2373
|
replacements.push({
|
|
2293
2374
|
start: arg.end - value.start,
|
|
2294
2375
|
end: arg.end - value.start,
|
|
2295
|
-
replacement:
|
|
2376
|
+
replacement: `, ${instanceIdVar})`
|
|
2296
2377
|
});
|
|
2297
2378
|
}
|
|
2298
2379
|
}
|
|
@@ -2324,8 +2405,13 @@ function findAndExtractScript(code) {
|
|
|
2324
2405
|
}
|
|
2325
2406
|
} else if (node.callee && node.callee.type === "Identifier" && node.callee.name === "createCoraliteElement") {
|
|
2326
2407
|
const arg = node.arguments[0];
|
|
2327
|
-
if (arg
|
|
2328
|
-
|
|
2408
|
+
if (arg) {
|
|
2409
|
+
const values = resolveStringValues(arg, ancestors);
|
|
2410
|
+
for (const val of values) {
|
|
2411
|
+
if (val.includes("-")) {
|
|
2412
|
+
components.add(val);
|
|
2413
|
+
}
|
|
2414
|
+
}
|
|
2329
2415
|
}
|
|
2330
2416
|
}
|
|
2331
2417
|
}
|
|
@@ -2391,32 +2477,42 @@ function findAndExtractImperativeComponents(code) {
|
|
|
2391
2477
|
try {
|
|
2392
2478
|
const ast = getAST(code);
|
|
2393
2479
|
const components = /* @__PURE__ */ new Set();
|
|
2394
|
-
const findHTMLComponents = (node) => {
|
|
2480
|
+
const findHTMLComponents = (node, ancestors = []) => {
|
|
2395
2481
|
if (node.type === "Literal" && typeof node.value === "string") {
|
|
2396
2482
|
extractFromHTMLString(node.value, components);
|
|
2397
2483
|
} else if (node.type === "TemplateLiteral") {
|
|
2398
2484
|
for (const element of node.quasis) {
|
|
2399
2485
|
extractFromHTMLString(element.value.cooked, components);
|
|
2400
2486
|
}
|
|
2487
|
+
} else {
|
|
2488
|
+
const values = resolveStringValues(node, ancestors);
|
|
2489
|
+
for (const val of values) {
|
|
2490
|
+
extractFromHTMLString(val, components);
|
|
2491
|
+
}
|
|
2401
2492
|
}
|
|
2402
2493
|
};
|
|
2403
|
-
|
|
2404
|
-
AssignmentExpression(node) {
|
|
2494
|
+
walkAncestorJS(ast, {
|
|
2495
|
+
AssignmentExpression(node, ancestors) {
|
|
2405
2496
|
if (node.left.type === "MemberExpression" && node.left.property.type === "Identifier" && (node.left.property.name === "innerHTML" || node.left.property.name === "outerHTML")) {
|
|
2406
|
-
findHTMLComponents(node.right);
|
|
2497
|
+
findHTMLComponents(node.right, ancestors);
|
|
2407
2498
|
}
|
|
2408
2499
|
},
|
|
2409
|
-
CallExpression(node) {
|
|
2500
|
+
CallExpression(node, ancestors) {
|
|
2410
2501
|
if (node.callee && (node.callee.type === "MemberExpression" && node.callee.object && node.callee.object.type === "Identifier" && node.callee.object.name === "document" && node.callee.property && node.callee.property.type === "Identifier" && node.callee.property.name === "createElement" || node.callee.type === "Identifier" && node.callee.name === "createCoraliteElement")) {
|
|
2411
2502
|
const arg = node.arguments[0];
|
|
2412
|
-
if (arg
|
|
2413
|
-
|
|
2503
|
+
if (arg) {
|
|
2504
|
+
const values = resolveStringValues(arg, ancestors);
|
|
2505
|
+
for (const val of values) {
|
|
2506
|
+
if (val.includes("-")) {
|
|
2507
|
+
components.add(val);
|
|
2508
|
+
}
|
|
2509
|
+
}
|
|
2414
2510
|
}
|
|
2415
2511
|
}
|
|
2416
2512
|
if (node.callee && node.callee.type === "MemberExpression" && node.callee.property && node.callee.property.type === "Identifier" && node.callee.property.name === "insertAdjacentHTML") {
|
|
2417
2513
|
const arg = node.arguments[1];
|
|
2418
2514
|
if (arg) {
|
|
2419
|
-
findHTMLComponents(arg);
|
|
2515
|
+
findHTMLComponents(arg, ancestors);
|
|
2420
2516
|
}
|
|
2421
2517
|
}
|
|
2422
2518
|
}
|
|
@@ -2685,9 +2781,19 @@ ScriptManager.prototype.compileAllInstances = async function(instances, mode) {
|
|
|
2685
2781
|
return factories;
|
|
2686
2782
|
})();
|
|
2687
2783
|
`);
|
|
2784
|
+
const clientMocks = {};
|
|
2785
|
+
if (mode === "testing" && this.options.testing?.mocks?.plugins) {
|
|
2786
|
+
for (const [key, mock] of Object.entries(this.options.testing.mocks.plugins)) {
|
|
2787
|
+
if (mock.client) {
|
|
2788
|
+
clientMocks[key] = { client: mock.client };
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2792
|
+
const clientMocksStr = serialize(clientMocks);
|
|
2688
2793
|
entryCodeParts.push(`const getClientContext = async (instanceContext) => {
|
|
2689
2794
|
const factories = await resolvedContextFactoriesPromise;
|
|
2690
2795
|
const cache = new Map();
|
|
2796
|
+
const clientMocks = ${clientMocksStr};
|
|
2691
2797
|
|
|
2692
2798
|
return new Proxy(instanceContext, {
|
|
2693
2799
|
get(target, prop, receiver) {
|
|
@@ -2702,7 +2808,16 @@ ScriptManager.prototype.compileAllInstances = async function(instances, mode) {
|
|
|
2702
2808
|
throw new Error('Coralite Plugin Error: The plugin "' + String(prop) + '" must be a function for the second phase (instance context). Received: ' + typeof factory);
|
|
2703
2809
|
}
|
|
2704
2810
|
|
|
2705
|
-
|
|
2811
|
+
let resolved = factory(receiver);
|
|
2812
|
+
|
|
2813
|
+
if (clientMocks[prop]?.client?.context) {
|
|
2814
|
+
if (typeof resolved === 'object' && resolved !== null) {
|
|
2815
|
+
resolved = Object.assign({}, resolved, clientMocks[prop].client.context);
|
|
2816
|
+
} else {
|
|
2817
|
+
resolved = clientMocks[prop].client.context;
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2706
2821
|
cache.set(prop, resolved);
|
|
2707
2822
|
return resolved;
|
|
2708
2823
|
},
|
|
@@ -3460,24 +3575,37 @@ var staticAssetPlugin = (assets = []) => {
|
|
|
3460
3575
|
};
|
|
3461
3576
|
|
|
3462
3577
|
// plugins/testing.js
|
|
3463
|
-
function traverseAndAddTestId(children, instanceId, { autoTestId = false, counters = {} } = {}) {
|
|
3578
|
+
function traverseAndAddTestId(children, instanceId, { autoTestId = false, counters = {}, mode = "production" } = {}) {
|
|
3464
3579
|
if (!Array.isArray(children)) {
|
|
3465
3580
|
return;
|
|
3466
3581
|
}
|
|
3582
|
+
const isProduction = mode === "production";
|
|
3583
|
+
const isDevOrTest = mode === "development" || mode === "testing";
|
|
3584
|
+
let prefix = "";
|
|
3585
|
+
if (instanceId === "page") {
|
|
3586
|
+
prefix = "page__";
|
|
3587
|
+
} else if (instanceId) {
|
|
3588
|
+
prefix = `${instanceId}__`;
|
|
3589
|
+
}
|
|
3467
3590
|
for (let i = 0; i < children.length; i++) {
|
|
3468
3591
|
const node = children[i];
|
|
3469
3592
|
if (node.type === "tag") {
|
|
3470
|
-
if (node.attribs
|
|
3471
|
-
if (
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3593
|
+
if (node.attribs) {
|
|
3594
|
+
if (node.attribs.test !== void 0) {
|
|
3595
|
+
delete node.attribs.test;
|
|
3596
|
+
}
|
|
3597
|
+
if (node.attribs["data-testid"] !== void 0) {
|
|
3598
|
+
if (isProduction) {
|
|
3599
|
+
delete node.attribs["data-testid"];
|
|
3600
|
+
} else if (isDevOrTest) {
|
|
3601
|
+
const val = node.attribs["data-testid"];
|
|
3602
|
+
if (prefix && !val.startsWith(prefix)) {
|
|
3603
|
+
node.attribs["data-testid"] = `${prefix}${val}`;
|
|
3604
|
+
}
|
|
3478
3605
|
}
|
|
3479
3606
|
}
|
|
3480
|
-
}
|
|
3607
|
+
}
|
|
3608
|
+
if (autoTestId && isDevOrTest) {
|
|
3481
3609
|
const tagName = node.name.toLowerCase();
|
|
3482
3610
|
const isInteractive = [
|
|
3483
3611
|
"button",
|
|
@@ -3496,7 +3624,7 @@ function traverseAndAddTestId(children, instanceId, { autoTestId = false, counte
|
|
|
3496
3624
|
node.attribs = {};
|
|
3497
3625
|
}
|
|
3498
3626
|
if (!node.attribs["data-testid"]) {
|
|
3499
|
-
node.attribs["data-testid"] = `${
|
|
3627
|
+
node.attribs["data-testid"] = `${prefix}${tagName}-${index}`;
|
|
3500
3628
|
}
|
|
3501
3629
|
}
|
|
3502
3630
|
}
|
|
@@ -3504,7 +3632,8 @@ function traverseAndAddTestId(children, instanceId, { autoTestId = false, counte
|
|
|
3504
3632
|
if (node.children?.length > 0) {
|
|
3505
3633
|
traverseAndAddTestId(node.children, instanceId, {
|
|
3506
3634
|
autoTestId,
|
|
3507
|
-
counters
|
|
3635
|
+
counters,
|
|
3636
|
+
mode
|
|
3508
3637
|
});
|
|
3509
3638
|
}
|
|
3510
3639
|
}
|
|
@@ -3527,43 +3656,51 @@ var testingPlugin = definePlugin({
|
|
|
3527
3656
|
app.options.externalStyles.push(`data:text/css;base64,${Buffer.from(velocityStyle).toString("base64")}`);
|
|
3528
3657
|
},
|
|
3529
3658
|
onBeforeComponentRender: ({ instanceId, template, app }) => {
|
|
3530
|
-
const
|
|
3659
|
+
const mode = app.options.mode;
|
|
3660
|
+
const isDevOrTest = mode === "development" || mode === "testing";
|
|
3531
3661
|
const counters = {};
|
|
3532
3662
|
const templateNode = template;
|
|
3533
3663
|
if (templateNode && templateNode.children) {
|
|
3534
3664
|
traverseAndAddTestId(templateNode.children, instanceId, {
|
|
3535
|
-
autoTestId:
|
|
3536
|
-
counters
|
|
3665
|
+
autoTestId: isDevOrTest,
|
|
3666
|
+
counters,
|
|
3667
|
+
mode
|
|
3537
3668
|
});
|
|
3538
3669
|
}
|
|
3539
3670
|
},
|
|
3671
|
+
onAfterComponentRender: ({ result, app }) => {
|
|
3672
|
+
const mode = app.options.mode;
|
|
3673
|
+
if (mode !== "production") {
|
|
3674
|
+
return;
|
|
3675
|
+
}
|
|
3676
|
+
const traverse = (children) => {
|
|
3677
|
+
if (!Array.isArray(children)) {
|
|
3678
|
+
return;
|
|
3679
|
+
}
|
|
3680
|
+
for (const node of children) {
|
|
3681
|
+
if (node.type === "tag" && node.attribs) {
|
|
3682
|
+
delete node.attribs["data-testid"];
|
|
3683
|
+
delete node.attribs.test;
|
|
3684
|
+
}
|
|
3685
|
+
if (node.children) {
|
|
3686
|
+
traverse(node.children);
|
|
3687
|
+
}
|
|
3688
|
+
}
|
|
3689
|
+
};
|
|
3690
|
+
if (result && result.children) {
|
|
3691
|
+
traverse(result.children);
|
|
3692
|
+
}
|
|
3693
|
+
},
|
|
3540
3694
|
onPageSet: ({ elements, app }) => {
|
|
3541
|
-
const
|
|
3695
|
+
const mode = app.options.mode;
|
|
3696
|
+
const isDevOrTest = mode === "development" || mode === "testing";
|
|
3542
3697
|
const counters = {};
|
|
3543
3698
|
traverseAndAddTestId(elements?.root?.children, "page", {
|
|
3544
|
-
autoTestId:
|
|
3545
|
-
counters
|
|
3699
|
+
autoTestId: isDevOrTest,
|
|
3700
|
+
counters,
|
|
3701
|
+
mode
|
|
3546
3702
|
});
|
|
3547
3703
|
}
|
|
3548
|
-
},
|
|
3549
|
-
client: {
|
|
3550
|
-
onBeforeComponentRender: ({ instanceId, refs }) => {
|
|
3551
|
-
for (let i = 0; i < refs.length; i++) {
|
|
3552
|
-
const ref = refs[i];
|
|
3553
|
-
const prefix = `${instanceId}__`;
|
|
3554
|
-
const uniqueRefValue = ref.element && ref.element.getAttribute("ref");
|
|
3555
|
-
if (ref.element && ref.element.setAttribute) {
|
|
3556
|
-
const currentTestId = ref.element.getAttribute("data-testid");
|
|
3557
|
-
if (!currentTestId || currentTestId === ref.name) {
|
|
3558
|
-
if (uniqueRefValue && uniqueRefValue.startsWith(prefix)) {
|
|
3559
|
-
ref.element.setAttribute("data-testid", uniqueRefValue);
|
|
3560
|
-
} else {
|
|
3561
|
-
ref.element.setAttribute("data-testid", `${prefix}${ref.name}`);
|
|
3562
|
-
}
|
|
3563
|
-
}
|
|
3564
|
-
}
|
|
3565
|
-
}
|
|
3566
|
-
}
|
|
3567
3704
|
}
|
|
3568
3705
|
});
|
|
3569
3706
|
|
|
@@ -4062,7 +4199,7 @@ async function triggerPluginHook({ app, hooks, serverGlobalContext, name, initia
|
|
|
4062
4199
|
}
|
|
4063
4200
|
return currentData;
|
|
4064
4201
|
}
|
|
4065
|
-
function bindPlugins({ pluginFactories, instanceContext = {} }) {
|
|
4202
|
+
function bindPlugins({ pluginFactories, instanceContext = {}, app }) {
|
|
4066
4203
|
const cache = /* @__PURE__ */ new Map();
|
|
4067
4204
|
const proxy = new Proxy(instanceContext, {
|
|
4068
4205
|
get(target, prop) {
|
|
@@ -4082,7 +4219,17 @@ function bindPlugins({ pluginFactories, instanceContext = {} }) {
|
|
|
4082
4219
|
if (typeof factory !== "function") {
|
|
4083
4220
|
throw new CoraliteError(`Coralite Plugin Error: The plugin "${String(prop)}" must be a function for the second phase (instance context). Received: ${typeof factory}`);
|
|
4084
4221
|
}
|
|
4085
|
-
|
|
4222
|
+
let resolved = factory(proxy);
|
|
4223
|
+
if (app?.options?.mode === "testing" && app.options.testing?.mocks?.plugins) {
|
|
4224
|
+
const pluginMock = app.options.testing.mocks.plugins[prop];
|
|
4225
|
+
if (pluginMock?.server?.context) {
|
|
4226
|
+
if (typeof resolved === "object" && resolved !== null) {
|
|
4227
|
+
resolved = Object.assign({}, resolved, pluginMock.server.context);
|
|
4228
|
+
} else {
|
|
4229
|
+
resolved = pluginMock.server.context;
|
|
4230
|
+
}
|
|
4231
|
+
}
|
|
4232
|
+
}
|
|
4086
4233
|
cache.set(prop, resolved);
|
|
4087
4234
|
return resolved;
|
|
4088
4235
|
},
|
|
@@ -4238,8 +4385,8 @@ function createComponentDefinition({ app }) {
|
|
|
4238
4385
|
}
|
|
4239
4386
|
}
|
|
4240
4387
|
let serverToExecute = server;
|
|
4241
|
-
if (app.options.mode === "testing" && app.options.testing?.mocks) {
|
|
4242
|
-
const mock = app.options.testing.mocks[module.id];
|
|
4388
|
+
if (app.options.mode === "testing" && app.options.testing?.mocks?.components) {
|
|
4389
|
+
const mock = app.options.testing.mocks.components[module.id];
|
|
4243
4390
|
if (mock && typeof mock.server === "function") {
|
|
4244
4391
|
serverToExecute = mock.server;
|
|
4245
4392
|
}
|
|
@@ -4258,7 +4405,9 @@ function createComponentDefinition({ app }) {
|
|
|
4258
4405
|
}
|
|
4259
4406
|
state.__script__.server = serverResult;
|
|
4260
4407
|
Object.assign(state, serverResult);
|
|
4261
|
-
|
|
4408
|
+
if (state.__script__.defaultValues) {
|
|
4409
|
+
Object.assign(state.__script__.defaultValues, serverResult);
|
|
4410
|
+
}
|
|
4262
4411
|
}
|
|
4263
4412
|
}
|
|
4264
4413
|
if (getters) {
|
|
@@ -4513,6 +4662,15 @@ async function setupPlugins({
|
|
|
4513
4662
|
}) {
|
|
4514
4663
|
const pluginsToInit = app.options.plugins;
|
|
4515
4664
|
const allExportNames = /* @__PURE__ */ new Set();
|
|
4665
|
+
if (app.options.mode === "testing" && app.options.testing?.mocks?.plugins) {
|
|
4666
|
+
const mockKeys = Object.keys(app.options.testing.mocks.plugins);
|
|
4667
|
+
const registeredPluginNames = pluginsToInit.map((p) => p.server?.name || p.name);
|
|
4668
|
+
for (const mockKey of mockKeys) {
|
|
4669
|
+
if (!registeredPluginNames.includes(mockKey)) {
|
|
4670
|
+
console.warn(`[Coralite Warning]: Mock defined for plugin "${mockKey}", but no plugin with that name is registered.`);
|
|
4671
|
+
}
|
|
4672
|
+
}
|
|
4673
|
+
}
|
|
4516
4674
|
for (const plugin of pluginsToInit) {
|
|
4517
4675
|
if (plugin.server) {
|
|
4518
4676
|
const serverName = plugin.server.name || plugin.name;
|
|
@@ -4932,6 +5090,9 @@ function injectReadinessScript(root, head, hasScripts, mode) {
|
|
|
4932
5090
|
children: []
|
|
4933
5091
|
});
|
|
4934
5092
|
let data = "class CoraliteLifecycleManager { constructor() { this.defined = new Promise(r => this._dr = r); this.rendered = new Promise(r => this._rr = r); this.hydrated = new Promise(r => this._hr = r); this._t = 0; this._rc = 0; this._hc = 0; this._ts = 0; this._dt = new Set(); this._ip = new WeakMap(); this._ir = new WeakMap(); this._rs = new WeakSet(); this._hs = new WeakSet(); this._s = false; } _start(t, ts) { this._t = t; this._ts = ts; this._s = true; this._check(); } _check() { if (!this._s) return; if (this._rc >= this._t) this._rr(); if (this._hc >= this._t) this._hr(); if (this._dt.size >= this._ts) this._dr(); } _markDefined(tag) { this._dt.add(tag); this._check(); } _markInstanceRendered(el) { if (el.hasAttribute('data-coralite-initial') && !this._rs.has(el)) { this._rs.add(el); this._rc++; this._check(); } } _markInstanceReady(el) { const r = this._ir.get(el); r && r(); this._ip.set(el, Promise.resolve()); if (el.hasAttribute('data-coralite-initial') && !this._hs.has(el)) { this._hs.add(el); this._hc++; this._check(); } } waitFor(el) { let p = this._ip.get(el); if (!p) { p = new Promise(r => this._ir.set(el, r)); this._ip.set(el, p); } return p; } } window.__coralite__ = { lifecycle: new CoraliteLifecycleManager() };";
|
|
5093
|
+
if (mode) {
|
|
5094
|
+
data += ` window.__coralite__.mode = '${mode}';`;
|
|
5095
|
+
}
|
|
4935
5096
|
if (mode === "testing") {
|
|
4936
5097
|
data += " window.__coralite__.components = {}; window.__coralite__.events = [];";
|
|
4937
5098
|
}
|
|
@@ -4949,8 +5110,12 @@ function injectReadinessScript(root, head, hasScripts, mode) {
|
|
|
4949
5110
|
root.children.unshift(readinessScriptElement);
|
|
4950
5111
|
}
|
|
4951
5112
|
}
|
|
4952
|
-
function injectImportMap(root, head, importMap) {
|
|
4953
|
-
|
|
5113
|
+
function injectImportMap(root, head, importMap, base) {
|
|
5114
|
+
const finalImportMap = { ...importMap };
|
|
5115
|
+
if (base) {
|
|
5116
|
+
finalImportMap["assets/js/manifest.js"] = `${base}assets/js/manifest.js`;
|
|
5117
|
+
}
|
|
5118
|
+
if (Object.keys(finalImportMap).length === 0) {
|
|
4954
5119
|
return;
|
|
4955
5120
|
}
|
|
4956
5121
|
const importMapElement = createCoraliteElement({
|
|
@@ -4964,7 +5129,7 @@ function injectImportMap(root, head, importMap) {
|
|
|
4964
5129
|
});
|
|
4965
5130
|
importMapElement.children.push(createCoraliteTextNode({
|
|
4966
5131
|
type: "text",
|
|
4967
|
-
data: JSON.stringify({ imports:
|
|
5132
|
+
data: JSON.stringify({ imports: finalImportMap }),
|
|
4968
5133
|
parent: importMapElement
|
|
4969
5134
|
}));
|
|
4970
5135
|
if (head) {
|
|
@@ -5031,16 +5196,19 @@ function resolvePageQueue(pagesCollection, path2) {
|
|
|
5031
5196
|
function generateClientRuntime({
|
|
5032
5197
|
base,
|
|
5033
5198
|
sharedChunkPath,
|
|
5034
|
-
chunkManifest,
|
|
5035
5199
|
declarativeTags = [],
|
|
5036
|
-
hydrationData = "{}"
|
|
5200
|
+
hydrationData = "{}",
|
|
5201
|
+
mode = "production"
|
|
5037
5202
|
}) {
|
|
5038
5203
|
return `
|
|
5039
5204
|
import { getClientContext, createCoraliteClass, globalClientHooks } from '${base}assets/js/${sharedChunkPath}';
|
|
5205
|
+
import componentManifest from '${base}assets/js/manifest.js';
|
|
5040
5206
|
|
|
5041
5207
|
(async () => {
|
|
5042
5208
|
const hydrationData = ${hydrationData};
|
|
5043
5209
|
const declarativeTags = ${JSON.stringify(declarativeTags)};
|
|
5210
|
+
window.__coralite__ = window.__coralite__ || {};
|
|
5211
|
+
window.__coralite__.mode = '${mode}';
|
|
5044
5212
|
|
|
5045
5213
|
const initialElements = Array.from(document.querySelectorAll('[data-cid]'))
|
|
5046
5214
|
.filter(el => {
|
|
@@ -5073,7 +5241,6 @@ import { getClientContext, createCoraliteClass, globalClientHooks } from '${base
|
|
|
5073
5241
|
globalThis.executableScripts = [];
|
|
5074
5242
|
globalThis.globalAbortController = new AbortController();
|
|
5075
5243
|
|
|
5076
|
-
const componentManifest = ${JSON.stringify(chunkManifest)};
|
|
5077
5244
|
const loadCache = {};
|
|
5078
5245
|
|
|
5079
5246
|
const loadComponent = (componentId) => {
|
|
@@ -5088,7 +5255,10 @@ import { getClientContext, createCoraliteClass, globalClientHooks } from '${base
|
|
|
5088
5255
|
|
|
5089
5256
|
if (cssPath) {
|
|
5090
5257
|
const fullCssPath = '${base}assets/css/' + cssPath;
|
|
5091
|
-
|
|
5258
|
+
const inlineStyles = document.getElementById('coralite-inline-styles');
|
|
5259
|
+
const hasStyleInInline = inlineStyles && inlineStyles.textContent.includes('[data-style-selector="' + componentId + '"]');
|
|
5260
|
+
|
|
5261
|
+
if (!document.querySelector('link[href="' + fullCssPath + '"]') && !hasStyleInInline) {
|
|
5092
5262
|
const link = document.createElement('link');
|
|
5093
5263
|
link.rel = 'stylesheet';
|
|
5094
5264
|
link.href = fullCssPath;
|
|
@@ -5153,8 +5323,38 @@ import { getClientContext, createCoraliteClass, globalClientHooks } from '${base
|
|
|
5153
5323
|
return element;
|
|
5154
5324
|
};
|
|
5155
5325
|
|
|
5156
|
-
window.processHTML = (html) => {
|
|
5326
|
+
window.processHTML = (html, instanceId) => {
|
|
5157
5327
|
if (typeof html !== 'string') return html;
|
|
5328
|
+
|
|
5329
|
+
const mode = (window.__coralite__ && window.__coralite__.mode) || 'production';
|
|
5330
|
+
const isDevOrTest = mode === 'development' || mode === 'testing';
|
|
5331
|
+
const isProduction = mode === 'production';
|
|
5332
|
+
|
|
5333
|
+
if (isDevOrTest || isProduction) {
|
|
5334
|
+
html = html.replace(/<([a-zA-Z0-9-]+)([^>]*)>/g, (match, tagName, attrs) => {
|
|
5335
|
+
let newAttrs = attrs;
|
|
5336
|
+
|
|
5337
|
+
// Strip deprecated 'test' attribute
|
|
5338
|
+
newAttrs = newAttrs.replace(/\\s+test\\s*=\\s*(['"]).*?\\1/g, '');
|
|
5339
|
+
|
|
5340
|
+
// Handle data-testid
|
|
5341
|
+
const testIdRegex = /\\s+data-testid\\s*=\\s*(['"])(.*?)\\1/g;
|
|
5342
|
+
if (isProduction) {
|
|
5343
|
+
newAttrs = newAttrs.replace(testIdRegex, '');
|
|
5344
|
+
} else if (isDevOrTest) {
|
|
5345
|
+
const prefix = instanceId ? instanceId + '__' : '';
|
|
5346
|
+
if (prefix) {
|
|
5347
|
+
newAttrs = newAttrs.replace(testIdRegex, (attrMatch, quote, testValue) => {
|
|
5348
|
+
if (testValue.startsWith(prefix)) return attrMatch;
|
|
5349
|
+
return ' data-testid="' + prefix + testValue + '"';
|
|
5350
|
+
});
|
|
5351
|
+
}
|
|
5352
|
+
}
|
|
5353
|
+
|
|
5354
|
+
return '<' + tagName + newAttrs + '>';
|
|
5355
|
+
});
|
|
5356
|
+
}
|
|
5357
|
+
|
|
5158
5358
|
const matches = html.matchAll(/<([a-zA-Z0-9-]+)/g);
|
|
5159
5359
|
for (const match of matches) {
|
|
5160
5360
|
const tag = match[1].toLowerCase();
|
|
@@ -6029,27 +6229,7 @@ function createRenderer({
|
|
|
6029
6229
|
injectExternalStyles(mappedComponent.root, headElement, normalizedOptions.externalStyles);
|
|
6030
6230
|
}
|
|
6031
6231
|
if (mappedSessionObject.styles.size > 0) {
|
|
6032
|
-
|
|
6033
|
-
const cssPaths = [];
|
|
6034
|
-
const remainingStyles = /* @__PURE__ */ new Map();
|
|
6035
|
-
for (const [selector, css] of mappedSessionObject.styles) {
|
|
6036
|
-
const entry = globalScriptResult.manifest[selector];
|
|
6037
|
-
if (entry && entry.css) {
|
|
6038
|
-
cssPaths.push(entry.css);
|
|
6039
|
-
} else {
|
|
6040
|
-
remainingStyles.set(selector, css);
|
|
6041
|
-
}
|
|
6042
|
-
}
|
|
6043
|
-
if (cssPaths.length > 0) {
|
|
6044
|
-
const base = normalizedOptions.baseURL.endsWith("/") ? normalizedOptions.baseURL : normalizedOptions.baseURL + "/";
|
|
6045
|
-
injectExternalStyleLinks(mappedComponent.root, headElement, cssPaths, base);
|
|
6046
|
-
}
|
|
6047
|
-
if (remainingStyles.size > 0) {
|
|
6048
|
-
injectStyles(mappedComponent.root, headElement, remainingStyles);
|
|
6049
|
-
}
|
|
6050
|
-
} else {
|
|
6051
|
-
injectStyles(mappedComponent.root, headElement, mappedSessionObject.styles);
|
|
6052
|
-
}
|
|
6232
|
+
injectStyles(mappedComponent.root, headElement, mappedSessionObject.styles);
|
|
6053
6233
|
}
|
|
6054
6234
|
if (componentsToInclude.size > 0) {
|
|
6055
6235
|
const targetElement = headElement || bodyElement || mappedComponent.root;
|
|
@@ -6095,20 +6275,9 @@ function createRenderer({
|
|
|
6095
6275
|
error: new Error(JSON.stringify(scriptResult.manifest))
|
|
6096
6276
|
});
|
|
6097
6277
|
}
|
|
6098
|
-
const chunkManifest = {};
|
|
6099
|
-
for (const tag of componentsToInclude) {
|
|
6100
|
-
if (scriptResult.manifest[tag]) {
|
|
6101
|
-
chunkManifest[tag] = scriptResult.manifest[tag];
|
|
6102
|
-
}
|
|
6103
|
-
}
|
|
6104
|
-
for (const tag in scriptResult.manifest) {
|
|
6105
|
-
if (tag !== "coralite-runtime" && !chunkManifest[tag]) {
|
|
6106
|
-
chunkManifest[tag] = scriptResult.manifest[tag];
|
|
6107
|
-
}
|
|
6108
|
-
}
|
|
6109
6278
|
injectReadinessScript(mappedComponent.root, headElement, true, normalizedOptions.mode);
|
|
6110
|
-
injectImportMap(mappedComponent.root, headElement, scriptResult.importMap);
|
|
6111
6279
|
const base = normalizedOptions.baseURL.endsWith("/") ? normalizedOptions.baseURL : normalizedOptions.baseURL + "/";
|
|
6280
|
+
injectImportMap(mappedComponent.root, headElement, scriptResult.importMap, base);
|
|
6112
6281
|
const hydrationData = {};
|
|
6113
6282
|
for (const [id, instance] of Object.entries(instances)) {
|
|
6114
6283
|
if (instance.state && Object.keys(instance.state).length > 0) {
|
|
@@ -6119,9 +6288,9 @@ function createRenderer({
|
|
|
6119
6288
|
const scriptContent = generateClientRuntime({
|
|
6120
6289
|
base,
|
|
6121
6290
|
sharedChunkPath: scriptResult.manifest["coralite-runtime"],
|
|
6122
|
-
chunkManifest,
|
|
6123
6291
|
declarativeTags: Array.from(declarativeTags),
|
|
6124
|
-
hydrationData: serialize2(hydrationData)
|
|
6292
|
+
hydrationData: serialize2(hydrationData),
|
|
6293
|
+
mode: normalizedOptions.mode
|
|
6125
6294
|
});
|
|
6126
6295
|
const scriptElement = createCoraliteElement({
|
|
6127
6296
|
type: "tag",
|
|
@@ -6240,10 +6409,74 @@ function createRenderer({
|
|
|
6240
6409
|
if (!buildOptions) {
|
|
6241
6410
|
buildOptions = {};
|
|
6242
6411
|
}
|
|
6412
|
+
const projectRoot = app.options.projectRoot || process.cwd();
|
|
6413
|
+
const cacheDir = join4(projectRoot, ".coralite");
|
|
6414
|
+
const manifestPath = join4(cacheDir, "manifest.json");
|
|
6415
|
+
let manifest = {
|
|
6416
|
+
physical: {},
|
|
6417
|
+
virtual: {},
|
|
6418
|
+
dependencies: {},
|
|
6419
|
+
components: {}
|
|
6420
|
+
};
|
|
6421
|
+
try {
|
|
6422
|
+
const content = await readFile3(manifestPath, "utf8");
|
|
6423
|
+
manifest = JSON.parse(content);
|
|
6424
|
+
if (!manifest.components) {
|
|
6425
|
+
manifest.components = {};
|
|
6426
|
+
}
|
|
6427
|
+
} catch (e) {
|
|
6428
|
+
if (e.code !== "ENOENT") {
|
|
6429
|
+
handleError2({
|
|
6430
|
+
level: "WARN",
|
|
6431
|
+
message: `Could not parse manifest at ${manifestPath}: ${e.message}. Starting with fresh manifest.`
|
|
6432
|
+
});
|
|
6433
|
+
}
|
|
6434
|
+
}
|
|
6435
|
+
let componentBuildInfo = {
|
|
6436
|
+
completed: 0,
|
|
6437
|
+
skipped: 0,
|
|
6438
|
+
details: []
|
|
6439
|
+
};
|
|
6243
6440
|
if (normalizedOptions.mode === "production" || normalizedOptions.mode === "testing") {
|
|
6244
6441
|
const allComponentIds = app.components.list.map((c) => c.result.id);
|
|
6245
6442
|
globalScriptResult = await scriptManager.compileAllInstances(allComponentIds, normalizedOptions.mode);
|
|
6246
6443
|
Object.assign(outputFiles, globalScriptResult.outputFiles);
|
|
6444
|
+
if (globalScriptResult.manifest) {
|
|
6445
|
+
const manifestJS = `export default ${JSON.stringify(globalScriptResult.manifest)};`;
|
|
6446
|
+
outputFiles["manifest.js"] = {
|
|
6447
|
+
path: "assets/js/manifest.js",
|
|
6448
|
+
hashedPath: "manifest.js",
|
|
6449
|
+
text: manifestJS
|
|
6450
|
+
};
|
|
6451
|
+
const newComponentManifest = globalScriptResult.manifest;
|
|
6452
|
+
const oldComponentManifest = manifest.components;
|
|
6453
|
+
for (const [id, value] of Object.entries(newComponentManifest)) {
|
|
6454
|
+
if (id === "coralite-runtime") {
|
|
6455
|
+
continue;
|
|
6456
|
+
}
|
|
6457
|
+
const isNew = !oldComponentManifest[id];
|
|
6458
|
+
const hasChanged = !isNew && (value.js !== oldComponentManifest[id].js || value.css !== oldComponentManifest[id].css);
|
|
6459
|
+
if (isNew || hasChanged) {
|
|
6460
|
+
componentBuildInfo.completed++;
|
|
6461
|
+
componentBuildInfo.details.push({
|
|
6462
|
+
id,
|
|
6463
|
+
status: "built",
|
|
6464
|
+
reason: isNew ? "New component" : "Source changed"
|
|
6465
|
+
});
|
|
6466
|
+
} else {
|
|
6467
|
+
componentBuildInfo.skipped++;
|
|
6468
|
+
componentBuildInfo.details.push({
|
|
6469
|
+
id,
|
|
6470
|
+
status: "skipped"
|
|
6471
|
+
});
|
|
6472
|
+
}
|
|
6473
|
+
}
|
|
6474
|
+
if (typeof buildOptions.onComponentBuild === "function") {
|
|
6475
|
+
await buildOptions.onComponentBuild(componentBuildInfo);
|
|
6476
|
+
} else if (typeof normalizedOptions.onComponentBuild === "function") {
|
|
6477
|
+
await normalizedOptions.onComponentBuild(componentBuildInfo);
|
|
6478
|
+
}
|
|
6479
|
+
}
|
|
6247
6480
|
} else if (normalizedOptions.mode === "development") {
|
|
6248
6481
|
if (!siteWideBundlePromise) {
|
|
6249
6482
|
const bundlePromise = (async () => {
|
|
@@ -6255,6 +6488,14 @@ function createRenderer({
|
|
|
6255
6488
|
delete outputFiles[key];
|
|
6256
6489
|
}
|
|
6257
6490
|
Object.assign(outputFiles, result.outputFiles);
|
|
6491
|
+
if (result.manifest) {
|
|
6492
|
+
const manifestJS = `export default ${JSON.stringify(result.manifest)};`;
|
|
6493
|
+
outputFiles["manifest.js"] = {
|
|
6494
|
+
path: "assets/js/manifest.js",
|
|
6495
|
+
hashedPath: "manifest.js",
|
|
6496
|
+
text: manifestJS
|
|
6497
|
+
};
|
|
6498
|
+
}
|
|
6258
6499
|
}
|
|
6259
6500
|
return result;
|
|
6260
6501
|
})();
|
|
@@ -6301,36 +6542,17 @@ function createRenderer({
|
|
|
6301
6542
|
}
|
|
6302
6543
|
}
|
|
6303
6544
|
sealedQueues.add(buildId);
|
|
6304
|
-
const
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
let manifest = {
|
|
6308
|
-
physical: {},
|
|
6309
|
-
virtual: {},
|
|
6310
|
-
dependencies: {}
|
|
6311
|
-
};
|
|
6312
|
-
try {
|
|
6313
|
-
const content = await readFile3(manifestPath, "utf8");
|
|
6314
|
-
manifest = JSON.parse(content);
|
|
6315
|
-
for (const [path2, metadata] of Object.entries(manifest.physical || {})) {
|
|
6316
|
-
if (metadata.dependencies) {
|
|
6317
|
-
app._dependencyGraph.directPageComponents[path2] = metadata.dependencies;
|
|
6318
|
-
}
|
|
6545
|
+
for (const [path2, metadata] of Object.entries(manifest.physical || {})) {
|
|
6546
|
+
if (metadata.dependencies) {
|
|
6547
|
+
app._dependencyGraph.directPageComponents[path2] = metadata.dependencies;
|
|
6319
6548
|
}
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
}
|
|
6325
|
-
app._refreshDependencyGraph();
|
|
6326
|
-
} catch (e) {
|
|
6327
|
-
if (e.code !== "ENOENT") {
|
|
6328
|
-
handleError2({
|
|
6329
|
-
level: "WARN",
|
|
6330
|
-
message: `Could not parse manifest at ${manifestPath}: ${e.message}. Starting with fresh manifest.`
|
|
6331
|
-
});
|
|
6549
|
+
}
|
|
6550
|
+
for (const [path2, metadata] of Object.entries(manifest.virtual || {})) {
|
|
6551
|
+
if (metadata.dependencies) {
|
|
6552
|
+
app._dependencyGraph.directPageComponents[path2] = metadata.dependencies;
|
|
6332
6553
|
}
|
|
6333
6554
|
}
|
|
6555
|
+
app._refreshDependencyGraph();
|
|
6334
6556
|
const mocksStr = app.options.testing?.mocks ? serialize2(app.options.testing.mocks) : "";
|
|
6335
6557
|
const mocksHash = hash(mocksStr);
|
|
6336
6558
|
const mocksChanged = manifest.testingMocksHash !== mocksHash;
|
|
@@ -6340,6 +6562,7 @@ function createRenderer({
|
|
|
6340
6562
|
physical: {},
|
|
6341
6563
|
virtual: {},
|
|
6342
6564
|
dependencies: {},
|
|
6565
|
+
components: {},
|
|
6343
6566
|
testingMocksHash: mocksHash
|
|
6344
6567
|
};
|
|
6345
6568
|
const componentChanges = /* @__PURE__ */ new Map();
|
|
@@ -6516,6 +6739,7 @@ function createRenderer({
|
|
|
6516
6739
|
}
|
|
6517
6740
|
try {
|
|
6518
6741
|
await mkdir2(cacheDir, { recursive: true });
|
|
6742
|
+
newManifest.components = globalScriptResult?.manifest || {};
|
|
6519
6743
|
const tempManifestPath = `${manifestPath}.tmp`;
|
|
6520
6744
|
await writeFile(tempManifestPath, JSON.stringify(newManifest, null, 2));
|
|
6521
6745
|
await rename(tempManifestPath, manifestPath);
|
|
@@ -6582,6 +6806,7 @@ async function createCoralite({
|
|
|
6582
6806
|
ignoreByAttribute,
|
|
6583
6807
|
skipRenderByAttribute,
|
|
6584
6808
|
onError,
|
|
6809
|
+
onComponentBuild,
|
|
6585
6810
|
mode = "production",
|
|
6586
6811
|
output,
|
|
6587
6812
|
testing
|
|
@@ -6621,6 +6846,7 @@ async function createCoralite({
|
|
|
6621
6846
|
mode,
|
|
6622
6847
|
path: path2,
|
|
6623
6848
|
output: output ? normalize(output) : void 0,
|
|
6849
|
+
onComponentBuild,
|
|
6624
6850
|
testing
|
|
6625
6851
|
};
|
|
6626
6852
|
const trackedOutputFiles = /* @__PURE__ */ new Set();
|
|
@@ -6747,7 +6973,8 @@ async function createCoralite({
|
|
|
6747
6973
|
});
|
|
6748
6974
|
const _bindPluginsLocal = (pluginFactories, instanceContext) => bindPlugins({
|
|
6749
6975
|
pluginFactories,
|
|
6750
|
-
instanceContext
|
|
6976
|
+
instanceContext,
|
|
6977
|
+
app
|
|
6751
6978
|
});
|
|
6752
6979
|
const _defineComponent = createComponentDefinition({ app });
|
|
6753
6980
|
const _evaluateLocal = (options) => evaluate({
|
|
@@ -6872,9 +7099,7 @@ async function createCoralite({
|
|
|
6872
7099
|
return results;
|
|
6873
7100
|
}
|
|
6874
7101
|
});
|
|
6875
|
-
|
|
6876
|
-
app.options.plugins.unshift(testingPlugin);
|
|
6877
|
-
}
|
|
7102
|
+
app.options.plugins.unshift(testingPlugin);
|
|
6878
7103
|
app.options.plugins.unshift(metadataPlugin);
|
|
6879
7104
|
if (assets) {
|
|
6880
7105
|
app.options.plugins.unshift(staticAssetPlugin(assets));
|
|
@@ -6985,12 +7210,49 @@ function defineConfig(options) {
|
|
|
6985
7210
|
if (typeof options.testing.mocks !== "object" || options.testing.mocks === null) {
|
|
6986
7211
|
throw new CoraliteError('Config property "testing.mocks" must be an object');
|
|
6987
7212
|
}
|
|
6988
|
-
|
|
6989
|
-
|
|
6990
|
-
|
|
7213
|
+
const validMocksKeys = ["components", "plugins"];
|
|
7214
|
+
for (const key of Object.keys(options.testing.mocks)) {
|
|
7215
|
+
if (!validMocksKeys.includes(key)) {
|
|
7216
|
+
throw new CoraliteError(`Invalid key "${key}" in testing.mocks. Valid keys are: ${validMocksKeys.join(", ")}`);
|
|
7217
|
+
}
|
|
7218
|
+
}
|
|
7219
|
+
if (options.testing.mocks.components !== void 0) {
|
|
7220
|
+
if (typeof options.testing.mocks.components !== "object" || options.testing.mocks.components === null) {
|
|
7221
|
+
throw new CoraliteError('Config property "testing.mocks.components" must be an object');
|
|
6991
7222
|
}
|
|
6992
|
-
|
|
6993
|
-
|
|
7223
|
+
for (const [key, mock] of Object.entries(options.testing.mocks.components)) {
|
|
7224
|
+
if (typeof mock !== "object" || mock === null) {
|
|
7225
|
+
throw new CoraliteError(`Mock for component "${key}" must be an object`);
|
|
7226
|
+
}
|
|
7227
|
+
if (mock.server !== void 0 && typeof mock.server !== "function") {
|
|
7228
|
+
throw new CoraliteError(`Mock server for component "${key}" must be a function`);
|
|
7229
|
+
}
|
|
7230
|
+
}
|
|
7231
|
+
}
|
|
7232
|
+
if (options.testing.mocks.plugins !== void 0) {
|
|
7233
|
+
if (typeof options.testing.mocks.plugins !== "object" || options.testing.mocks.plugins === null) {
|
|
7234
|
+
throw new CoraliteError('Config property "testing.mocks.plugins" must be an object');
|
|
7235
|
+
}
|
|
7236
|
+
for (const [key, mock] of Object.entries(options.testing.mocks.plugins)) {
|
|
7237
|
+
if (typeof mock !== "object" || mock === null) {
|
|
7238
|
+
throw new CoraliteError(`Mock for plugin "${key}" must be an object`);
|
|
7239
|
+
}
|
|
7240
|
+
if (mock.server !== void 0) {
|
|
7241
|
+
if (typeof mock.server !== "object" || mock.server === null) {
|
|
7242
|
+
throw new CoraliteError(`Mock server for plugin "${key}" must be an object`);
|
|
7243
|
+
}
|
|
7244
|
+
if (mock.server.context !== void 0 && (typeof mock.server.context !== "object" || mock.server.context === null)) {
|
|
7245
|
+
throw new CoraliteError(`Mock server context for plugin "${key}" must be an object`);
|
|
7246
|
+
}
|
|
7247
|
+
}
|
|
7248
|
+
if (mock.client !== void 0) {
|
|
7249
|
+
if (typeof mock.client !== "object" || mock.client === null) {
|
|
7250
|
+
throw new CoraliteError(`Mock client for plugin "${key}" must be an object`);
|
|
7251
|
+
}
|
|
7252
|
+
if (mock.client.context !== void 0 && (typeof mock.client.context !== "object" || mock.client.context === null)) {
|
|
7253
|
+
throw new CoraliteError(`Mock client context for plugin "${key}" must be an object`);
|
|
7254
|
+
}
|
|
7255
|
+
}
|
|
6994
7256
|
}
|
|
6995
7257
|
}
|
|
6996
7258
|
}
|