coralite 0.40.2 → 0.41.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.map +1 -1
- package/dist/lib/coralite-element.js +36 -2
- 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/index.js +172 -57
- package/dist/lib/index.js.map +2 -2
- package/dist/lib/renderer.d.ts.map +1 -1
- package/dist/lib/utils/client/runtime.d.ts.map +1 -1
- package/dist/lib/utils/server/render.d.ts +2 -1
- package/dist/lib/utils/server/render.d.ts.map +1 -1
- package/dist/plugins/testing.d.ts.map +1 -1
- package/dist/types/core.d.ts +21 -3
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/plugin.d.ts +5 -1
- package/dist/types/plugin.d.ts.map +1 -1
- package/llms.txt +76 -7
- package/package.json +5 -3
package/dist/lib/index.js
CHANGED
|
@@ -3460,59 +3460,106 @@ var staticAssetPlugin = (assets = []) => {
|
|
|
3460
3460
|
};
|
|
3461
3461
|
|
|
3462
3462
|
// plugins/testing.js
|
|
3463
|
-
function traverseAndAddTestId(children) {
|
|
3463
|
+
function traverseAndAddTestId(children, instanceId, { autoTestId = false, counters = {} } = {}) {
|
|
3464
3464
|
if (!Array.isArray(children)) {
|
|
3465
3465
|
return;
|
|
3466
3466
|
}
|
|
3467
3467
|
for (let i = 0; i < children.length; i++) {
|
|
3468
3468
|
const node = children[i];
|
|
3469
|
-
if (node.type === "tag"
|
|
3470
|
-
if (
|
|
3471
|
-
node.attribs["data-testid"]
|
|
3469
|
+
if (node.type === "tag") {
|
|
3470
|
+
if (node.attribs?.ref) {
|
|
3471
|
+
if (!node.attribs["data-testid"]) {
|
|
3472
|
+
const refValue = node.attribs.ref;
|
|
3473
|
+
const prefix = instanceId ? `${instanceId}__` : "";
|
|
3474
|
+
if (instanceId === "page" && refValue.includes("__")) {
|
|
3475
|
+
node.attribs["data-testid"] = refValue;
|
|
3476
|
+
} else {
|
|
3477
|
+
node.attribs["data-testid"] = `${prefix}${refValue}`;
|
|
3478
|
+
}
|
|
3479
|
+
}
|
|
3480
|
+
} else if (autoTestId && instanceId) {
|
|
3481
|
+
const tagName = node.name.toLowerCase();
|
|
3482
|
+
const isInteractive = [
|
|
3483
|
+
"button",
|
|
3484
|
+
"a",
|
|
3485
|
+
"input",
|
|
3486
|
+
"form",
|
|
3487
|
+
"select",
|
|
3488
|
+
"textarea"
|
|
3489
|
+
].includes(tagName) || node.attribs && (node.attribs.tabindex !== void 0 || node.attribs.role && ["button", "link", "checkbox"].includes(node.attribs.role)) || node.slots;
|
|
3490
|
+
if (isInteractive) {
|
|
3491
|
+
if (!counters[tagName]) {
|
|
3492
|
+
counters[tagName] = 0;
|
|
3493
|
+
}
|
|
3494
|
+
const index = counters[tagName]++;
|
|
3495
|
+
if (!node.attribs) {
|
|
3496
|
+
node.attribs = {};
|
|
3497
|
+
}
|
|
3498
|
+
if (!node.attribs["data-testid"]) {
|
|
3499
|
+
node.attribs["data-testid"] = `${instanceId}__${tagName}-${index}`;
|
|
3500
|
+
}
|
|
3501
|
+
}
|
|
3472
3502
|
}
|
|
3473
3503
|
}
|
|
3474
3504
|
if (node.children?.length > 0) {
|
|
3475
|
-
traverseAndAddTestId(node.children
|
|
3505
|
+
traverseAndAddTestId(node.children, instanceId, {
|
|
3506
|
+
autoTestId,
|
|
3507
|
+
counters
|
|
3508
|
+
});
|
|
3476
3509
|
}
|
|
3477
3510
|
}
|
|
3478
3511
|
}
|
|
3479
3512
|
var testingPlugin = definePlugin({
|
|
3480
3513
|
name: "testing",
|
|
3481
3514
|
server: {
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
const uniqueRefValue = `${instanceId}__${ref.name}`;
|
|
3486
|
-
if (ref.element.attribs) {
|
|
3487
|
-
const currentTestId = ref.element.attribs["data-testid"];
|
|
3488
|
-
if (!currentTestId || currentTestId === ref.name) {
|
|
3489
|
-
ref.element.attribs["data-testid"] = uniqueRefValue;
|
|
3490
|
-
}
|
|
3491
|
-
}
|
|
3515
|
+
onBeforeBuild: ({ app }) => {
|
|
3516
|
+
if (app.options.mode !== "testing") {
|
|
3517
|
+
return;
|
|
3492
3518
|
}
|
|
3519
|
+
app.options.externalStyles = app.options.externalStyles || [];
|
|
3520
|
+
const velocityStyle = `
|
|
3521
|
+
*, *::before, *::after {
|
|
3522
|
+
transition: none !important;
|
|
3523
|
+
animation: none !important;
|
|
3524
|
+
scroll-behavior: auto !important;
|
|
3525
|
+
}
|
|
3526
|
+
`.trim();
|
|
3527
|
+
app.options.externalStyles.push(`data:text/css;base64,${Buffer.from(velocityStyle).toString("base64")}`);
|
|
3493
3528
|
},
|
|
3494
|
-
|
|
3495
|
-
const
|
|
3496
|
-
|
|
3497
|
-
|
|
3529
|
+
onBeforeComponentRender: ({ instanceId, template, app }) => {
|
|
3530
|
+
const isTesting = app.options.mode === "testing";
|
|
3531
|
+
const counters = {};
|
|
3532
|
+
const templateNode = template;
|
|
3533
|
+
if (templateNode && templateNode.children) {
|
|
3534
|
+
traverseAndAddTestId(templateNode.children, instanceId, {
|
|
3535
|
+
autoTestId: isTesting,
|
|
3536
|
+
counters
|
|
3537
|
+
});
|
|
3498
3538
|
}
|
|
3499
3539
|
},
|
|
3500
|
-
onPageSet: ({ elements }) => {
|
|
3501
|
-
const
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3540
|
+
onPageSet: ({ elements, app }) => {
|
|
3541
|
+
const isTesting = app.options.mode === "testing";
|
|
3542
|
+
const counters = {};
|
|
3543
|
+
traverseAndAddTestId(elements?.root?.children, "page", {
|
|
3544
|
+
autoTestId: isTesting,
|
|
3545
|
+
counters
|
|
3546
|
+
});
|
|
3505
3547
|
}
|
|
3506
3548
|
},
|
|
3507
3549
|
client: {
|
|
3508
3550
|
onBeforeComponentRender: ({ instanceId, refs }) => {
|
|
3509
3551
|
for (let i = 0; i < refs.length; i++) {
|
|
3510
3552
|
const ref = refs[i];
|
|
3511
|
-
const
|
|
3553
|
+
const prefix = `${instanceId}__`;
|
|
3554
|
+
const uniqueRefValue = ref.element && ref.element.getAttribute("ref");
|
|
3512
3555
|
if (ref.element && ref.element.setAttribute) {
|
|
3513
3556
|
const currentTestId = ref.element.getAttribute("data-testid");
|
|
3514
3557
|
if (!currentTestId || currentTestId === ref.name) {
|
|
3515
|
-
|
|
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
|
+
}
|
|
3516
3563
|
}
|
|
3517
3564
|
}
|
|
3518
3565
|
}
|
|
@@ -4190,8 +4237,15 @@ function createComponentDefinition({ app }) {
|
|
|
4190
4237
|
}
|
|
4191
4238
|
}
|
|
4192
4239
|
}
|
|
4193
|
-
|
|
4194
|
-
|
|
4240
|
+
let serverToExecute = server;
|
|
4241
|
+
if (app.options.mode === "testing" && app.options.testing?.mocks) {
|
|
4242
|
+
const mock = app.options.testing.mocks[module.id];
|
|
4243
|
+
if (mock && typeof mock.server === "function") {
|
|
4244
|
+
serverToExecute = mock.server;
|
|
4245
|
+
}
|
|
4246
|
+
}
|
|
4247
|
+
if (typeof serverToExecute === "function") {
|
|
4248
|
+
const serverResult = await serverToExecute({
|
|
4195
4249
|
...context2,
|
|
4196
4250
|
...initialState
|
|
4197
4251
|
});
|
|
@@ -4609,8 +4663,8 @@ function createPageHandlers({
|
|
|
4609
4663
|
data,
|
|
4610
4664
|
app
|
|
4611
4665
|
});
|
|
4612
|
-
const
|
|
4613
|
-
if (
|
|
4666
|
+
const isStatic = app.options.mode === "production" || app.options.mode === "testing";
|
|
4667
|
+
if (isStatic && !data.virtual) {
|
|
4614
4668
|
delete data.content;
|
|
4615
4669
|
}
|
|
4616
4670
|
return {
|
|
@@ -4619,16 +4673,16 @@ function createPageHandlers({
|
|
|
4619
4673
|
state: mappedContext.state,
|
|
4620
4674
|
page: mappedContext.page,
|
|
4621
4675
|
path: mappedContext.data.path,
|
|
4622
|
-
root:
|
|
4623
|
-
customElements:
|
|
4624
|
-
tempElements:
|
|
4625
|
-
skipRenderElements:
|
|
4676
|
+
root: isStatic ? null : mappedContext.elements.root,
|
|
4677
|
+
customElements: isStatic ? null : mappedContext.elements.customElements,
|
|
4678
|
+
tempElements: isStatic ? null : mappedContext.elements.tempElements,
|
|
4679
|
+
skipRenderElements: isStatic ? null : mappedContext.elements.skipRenderElements
|
|
4626
4680
|
},
|
|
4627
4681
|
state: mappedContext.state
|
|
4628
4682
|
};
|
|
4629
4683
|
};
|
|
4630
4684
|
const onPageUpdateLocal = async (newValue, oldValue) => {
|
|
4631
|
-
if (app.options.mode === "production") {
|
|
4685
|
+
if (app.options.mode === "production" || app.options.mode === "testing") {
|
|
4632
4686
|
if (!newValue.result) {
|
|
4633
4687
|
await onFileSetLocal(newValue);
|
|
4634
4688
|
}
|
|
@@ -4869,7 +4923,7 @@ ${css}
|
|
|
4869
4923
|
root.children.unshift(styleElement);
|
|
4870
4924
|
}
|
|
4871
4925
|
}
|
|
4872
|
-
function injectReadinessScript(root, head, hasScripts) {
|
|
4926
|
+
function injectReadinessScript(root, head, hasScripts, mode) {
|
|
4873
4927
|
const readinessScriptElement = createCoraliteElement({
|
|
4874
4928
|
type: "tag",
|
|
4875
4929
|
name: "script",
|
|
@@ -4878,6 +4932,9 @@ function injectReadinessScript(root, head, hasScripts) {
|
|
|
4878
4932
|
children: []
|
|
4879
4933
|
});
|
|
4880
4934
|
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() };";
|
|
4935
|
+
if (mode === "testing") {
|
|
4936
|
+
data += " window.__coralite__.components = {}; window.__coralite__.events = [];";
|
|
4937
|
+
}
|
|
4881
4938
|
if (!hasScripts) {
|
|
4882
4939
|
data += " window.__coralite__.lifecycle._start(0, 0);";
|
|
4883
4940
|
}
|
|
@@ -4984,8 +5041,32 @@ import { getClientContext, createCoraliteClass, globalClientHooks } from '${base
|
|
|
4984
5041
|
(async () => {
|
|
4985
5042
|
const hydrationData = ${hydrationData};
|
|
4986
5043
|
const declarativeTags = ${JSON.stringify(declarativeTags)};
|
|
4987
|
-
|
|
4988
|
-
|
|
5044
|
+
|
|
5045
|
+
const initialElements = Array.from(document.querySelectorAll('[data-cid]'))
|
|
5046
|
+
.filter(el => {
|
|
5047
|
+
const tagName = el.tagName.toLowerCase();
|
|
5048
|
+
const isDeclarative = declarativeTags.includes(tagName);
|
|
5049
|
+
const isInitial = el.hasAttribute('data-coralite-initial');
|
|
5050
|
+
|
|
5051
|
+
if (window['__coralite__'] && window['__coralite__'].components && isInitial) {
|
|
5052
|
+
const cid = el.getAttribute('data-cid');
|
|
5053
|
+
if (cid && !hydrationData[cid]) {
|
|
5054
|
+
const error = new Error('Coralite Hydration Mismatch: Component with data-cid "' + cid + '" (' + tagName + ') has no matching server hydration data.');
|
|
5055
|
+
if (typeof window['showCoraliteError'] === 'function') {
|
|
5056
|
+
window['showCoraliteError'](error);
|
|
5057
|
+
} else {
|
|
5058
|
+
console.error(error);
|
|
5059
|
+
const overlay = document.createElement('div');
|
|
5060
|
+
overlay.style = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(255,0,0,0.9);color:white;padding:20px;z-index:10000;font-family:monospace;white-space:pre-wrap;overflow:auto;';
|
|
5061
|
+
overlay.innerHTML = '<h1>Coralite Hydration Mismatch</h1><p>' + error.message + '</p>';
|
|
5062
|
+
document.body.appendChild(overlay);
|
|
5063
|
+
}
|
|
5064
|
+
throw error;
|
|
5065
|
+
}
|
|
5066
|
+
}
|
|
5067
|
+
|
|
5068
|
+
return isDeclarative && isInitial;
|
|
5069
|
+
});
|
|
4989
5070
|
if (window.__coralite__ && window.__coralite__.lifecycle) {
|
|
4990
5071
|
window.__coralite__.lifecycle._start(initialElements.length, declarativeTags.length);
|
|
4991
5072
|
}
|
|
@@ -5424,20 +5505,11 @@ function createRenderer({
|
|
|
5424
5505
|
componentState = cleanKeys(componentState);
|
|
5425
5506
|
}
|
|
5426
5507
|
const module = cloneModuleInstance(moduleComponent.result);
|
|
5427
|
-
if (module.values && module.values.refs) {
|
|
5428
|
-
for (let i = 0; i < module.values.refs.length; i++) {
|
|
5429
|
-
const ref = module.values.refs[i];
|
|
5430
|
-
const uniqueRefValue = `${instanceId}__${ref.name}`;
|
|
5431
|
-
if (ref.element && ref.element.attribs) {
|
|
5432
|
-
ref.element.attribs.ref = uniqueRefValue;
|
|
5433
|
-
}
|
|
5434
|
-
componentState[`ref_${ref.name}`] = uniqueRefValue;
|
|
5435
|
-
}
|
|
5436
|
-
}
|
|
5437
5508
|
const mappedComponentContext = await hooks.trigger("onBeforeComponentRender", {
|
|
5438
5509
|
state: componentState,
|
|
5439
5510
|
componentId: module.id,
|
|
5440
5511
|
instanceId,
|
|
5512
|
+
template: module.template,
|
|
5441
5513
|
refs: module.values.refs,
|
|
5442
5514
|
textNodes: module.values.textNodes,
|
|
5443
5515
|
attributes: module.values.attributes,
|
|
@@ -5447,6 +5519,16 @@ function createRenderer({
|
|
|
5447
5519
|
app
|
|
5448
5520
|
});
|
|
5449
5521
|
componentState = mappedComponentContext.state;
|
|
5522
|
+
if (module.values && module.values.refs) {
|
|
5523
|
+
for (let i = 0; i < module.values.refs.length; i++) {
|
|
5524
|
+
const ref = module.values.refs[i];
|
|
5525
|
+
const uniqueRefValue = `${instanceId}__${ref.name}`;
|
|
5526
|
+
if (ref.element && ref.element.attribs) {
|
|
5527
|
+
ref.element.attribs.ref = uniqueRefValue;
|
|
5528
|
+
}
|
|
5529
|
+
componentState[`ref_${ref.name}`] = uniqueRefValue;
|
|
5530
|
+
}
|
|
5531
|
+
}
|
|
5450
5532
|
const result = module.template;
|
|
5451
5533
|
if (module.styles.length) {
|
|
5452
5534
|
const selector = module.id;
|
|
@@ -6024,7 +6106,7 @@ function createRenderer({
|
|
|
6024
6106
|
chunkManifest[tag] = scriptResult.manifest[tag];
|
|
6025
6107
|
}
|
|
6026
6108
|
}
|
|
6027
|
-
injectReadinessScript(mappedComponent.root, headElement, true);
|
|
6109
|
+
injectReadinessScript(mappedComponent.root, headElement, true, normalizedOptions.mode);
|
|
6028
6110
|
injectImportMap(mappedComponent.root, headElement, scriptResult.importMap);
|
|
6029
6111
|
const base = normalizedOptions.baseURL.endsWith("/") ? normalizedOptions.baseURL : normalizedOptions.baseURL + "/";
|
|
6030
6112
|
const hydrationData = {};
|
|
@@ -6057,7 +6139,7 @@ function createRenderer({
|
|
|
6057
6139
|
}
|
|
6058
6140
|
removeElements(mappedComponent.skipRenderElements, true);
|
|
6059
6141
|
if (!mappedSessionObject.scripts.content[mappedComponent.path.pathname]) {
|
|
6060
|
-
injectReadinessScript(mappedComponent.root, headElement, false);
|
|
6142
|
+
injectReadinessScript(mappedComponent.root, headElement, false, normalizedOptions.mode);
|
|
6061
6143
|
}
|
|
6062
6144
|
const rawHTML = transformNode(mappedComponent.root);
|
|
6063
6145
|
const result = {
|
|
@@ -6158,7 +6240,7 @@ function createRenderer({
|
|
|
6158
6240
|
if (!buildOptions) {
|
|
6159
6241
|
buildOptions = {};
|
|
6160
6242
|
}
|
|
6161
|
-
if (normalizedOptions.mode === "production") {
|
|
6243
|
+
if (normalizedOptions.mode === "production" || normalizedOptions.mode === "testing") {
|
|
6162
6244
|
const allComponentIds = app.components.list.map((c) => c.result.id);
|
|
6163
6245
|
globalScriptResult = await scriptManager.compileAllInstances(allComponentIds, normalizedOptions.mode);
|
|
6164
6246
|
Object.assign(outputFiles, globalScriptResult.outputFiles);
|
|
@@ -6249,12 +6331,16 @@ function createRenderer({
|
|
|
6249
6331
|
});
|
|
6250
6332
|
}
|
|
6251
6333
|
}
|
|
6334
|
+
const mocksStr = app.options.testing?.mocks ? serialize2(app.options.testing.mocks) : "";
|
|
6335
|
+
const mocksHash = hash(mocksStr);
|
|
6336
|
+
const mocksChanged = manifest.testingMocksHash !== mocksHash;
|
|
6252
6337
|
const pagesToRender = [];
|
|
6253
6338
|
const skippedPages = [];
|
|
6254
6339
|
const newManifest = {
|
|
6255
6340
|
physical: {},
|
|
6256
6341
|
virtual: {},
|
|
6257
|
-
dependencies: {}
|
|
6342
|
+
dependencies: {},
|
|
6343
|
+
testingMocksHash: mocksHash
|
|
6258
6344
|
};
|
|
6259
6345
|
const componentChanges = /* @__PURE__ */ new Map();
|
|
6260
6346
|
const allComponents = app.components.list;
|
|
@@ -6277,7 +6363,7 @@ function createRenderer({
|
|
|
6277
6363
|
};
|
|
6278
6364
|
for (const pageItem of queue) {
|
|
6279
6365
|
let shouldRebuild = false;
|
|
6280
|
-
if (normalizedOptions.output && normalizedOptions.mode === "production") {
|
|
6366
|
+
if (normalizedOptions.output && (normalizedOptions.mode === "production" || normalizedOptions.mode === "testing")) {
|
|
6281
6367
|
const relativeDir = relative3(normalizedOptions.path.pages, pageItem.path.dirname);
|
|
6282
6368
|
const outFile = join4(normalizedOptions.output, relativeDir, pageItem.path.filename);
|
|
6283
6369
|
try {
|
|
@@ -6296,6 +6382,9 @@ function createRenderer({
|
|
|
6296
6382
|
if (componentIds.some((id) => componentChanges.get(id))) {
|
|
6297
6383
|
shouldRebuild = true;
|
|
6298
6384
|
}
|
|
6385
|
+
if (mocksChanged) {
|
|
6386
|
+
shouldRebuild = true;
|
|
6387
|
+
}
|
|
6299
6388
|
if (pageItem.virtual) {
|
|
6300
6389
|
if (shouldRebuild || pageItem.volatile || !manifest.virtual || !manifest.virtual[pageItem.path.pathname] || String(manifest.virtual[pageItem.path.pathname].cacheKey) !== String(pageItem.cacheKey) || normalizedOptions.mode === "development") {
|
|
6301
6390
|
shouldRebuild = true;
|
|
@@ -6494,7 +6583,8 @@ async function createCoralite({
|
|
|
6494
6583
|
skipRenderByAttribute,
|
|
6495
6584
|
onError,
|
|
6496
6585
|
mode = "production",
|
|
6497
|
-
output
|
|
6586
|
+
output,
|
|
6587
|
+
testing
|
|
6498
6588
|
}) {
|
|
6499
6589
|
if (!components || typeof components !== "string") {
|
|
6500
6590
|
handleError({
|
|
@@ -6530,7 +6620,8 @@ async function createCoralite({
|
|
|
6530
6620
|
skipRenderByAttribute,
|
|
6531
6621
|
mode,
|
|
6532
6622
|
path: path2,
|
|
6533
|
-
output: output ? normalize(output) : void 0
|
|
6623
|
+
output: output ? normalize(output) : void 0,
|
|
6624
|
+
testing
|
|
6534
6625
|
};
|
|
6535
6626
|
const trackedOutputFiles = /* @__PURE__ */ new Set();
|
|
6536
6627
|
const app = {
|
|
@@ -6781,7 +6872,7 @@ async function createCoralite({
|
|
|
6781
6872
|
return results;
|
|
6782
6873
|
}
|
|
6783
6874
|
});
|
|
6784
|
-
if (app.options.mode === "
|
|
6875
|
+
if (app.options.mode === "testing") {
|
|
6785
6876
|
app.options.plugins.unshift(testingPlugin);
|
|
6786
6877
|
}
|
|
6787
6878
|
app.options.plugins.unshift(metadataPlugin);
|
|
@@ -6839,7 +6930,7 @@ async function createCoralite({
|
|
|
6839
6930
|
onUpdate: handlers.onPageUpdate,
|
|
6840
6931
|
onDelete: handlers.onPageDelete
|
|
6841
6932
|
});
|
|
6842
|
-
if (app.options.mode === "production") {
|
|
6933
|
+
if (app.options.mode === "production" || app.options.mode === "testing") {
|
|
6843
6934
|
for await (const file of discoverHtmlFiles({
|
|
6844
6935
|
path: app.options.pages,
|
|
6845
6936
|
recursive: true,
|
|
@@ -6880,6 +6971,30 @@ function defineConfig(options) {
|
|
|
6880
6971
|
throw new CoraliteError(`Config property "${prop}" cannot be empty`);
|
|
6881
6972
|
}
|
|
6882
6973
|
}
|
|
6974
|
+
if (options.mode !== void 0) {
|
|
6975
|
+
const validModes = ["production", "development", "testing"];
|
|
6976
|
+
if (!validModes.includes(options.mode)) {
|
|
6977
|
+
throw new CoraliteError(`Invalid mode: "${options.mode}". Valid modes are: ${validModes.join(", ")}`);
|
|
6978
|
+
}
|
|
6979
|
+
}
|
|
6980
|
+
if (options.testing !== void 0) {
|
|
6981
|
+
if (typeof options.testing !== "object" || options.testing === null) {
|
|
6982
|
+
throw new CoraliteError('Config property "testing" must be an object');
|
|
6983
|
+
}
|
|
6984
|
+
if (options.testing.mocks !== void 0) {
|
|
6985
|
+
if (typeof options.testing.mocks !== "object" || options.testing.mocks === null) {
|
|
6986
|
+
throw new CoraliteError('Config property "testing.mocks" must be an object');
|
|
6987
|
+
}
|
|
6988
|
+
for (const [key, mock] of Object.entries(options.testing.mocks)) {
|
|
6989
|
+
if (typeof mock !== "object" || mock === null) {
|
|
6990
|
+
throw new CoraliteError(`Mock for component "${key}" must be an object`);
|
|
6991
|
+
}
|
|
6992
|
+
if (mock.server !== void 0 && typeof mock.server !== "function") {
|
|
6993
|
+
throw new CoraliteError(`Mock server for component "${key}" must be a function`);
|
|
6994
|
+
}
|
|
6995
|
+
}
|
|
6996
|
+
}
|
|
6997
|
+
}
|
|
6883
6998
|
if ("plugins" in options && options.plugins !== void 0) {
|
|
6884
6999
|
if (!Array.isArray(options.plugins)) {
|
|
6885
7000
|
throw new CoraliteError(
|