single snapshot test

This commit is contained in:
Thea Kindinger
2026-04-08 18:42:05 -04:00
commit a272d6709f
1502 changed files with 601058 additions and 0 deletions

98
dist/bootstrap.js vendored Normal file
View File

@@ -0,0 +1,98 @@
export function runtimeBootstrapScript(basePath = "") {
return `(() => {
const runtime = {
basePath: ${JSON.stringify(basePath)},
hooks: {},
mounts: {},
registerMount(pluginId, hookName, mountId, mountFn) {
const key = pluginId + ':' + hookName + ':' + mountId;
this.mounts[key] = mountFn;
},
async loadScript(url) {
if (document.querySelector('script[data-runtime-src="' + url + '"]')) return;
await new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = url;
script.async = true;
script.dataset.runtimeSrc = url;
script.onload = () => resolve();
script.onerror = reject;
document.head.appendChild(script);
});
},
ensureCss(url) {
if (!url || document.querySelector('link[data-runtime-css="' + url + '"]')) return;
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
link.dataset.runtimeCss = url;
document.head.appendChild(link);
},
async fetchHooks() {
const res = await fetch(this.basePath + '/api/runtime/hooks', { credentials: 'include' });
if (!res.ok) throw new Error('hook fetch failed: ' + res.status);
const data = await res.json();
this.hooks = data.hooks || {};
return data;
},
toolbarAnchor() {
return document.querySelector('[data-mailcow-plugin-hook="mail.compose.toolbar"]')
|| document.querySelector('.compose-toolbar')
|| document.querySelector('[role="toolbar"]')
|| document.body;
},
attachmentsAnchor() {
return document.querySelector('[data-mailcow-plugin-hook="mail.compose.attachments"]')
|| document.querySelector('.compose-attachments')
|| document.querySelector('[data-attachments]')
|| document.body;
},
async mountContribution(contribution) {
if (contribution.cssUrl) this.ensureCss(contribution.cssUrl);
if (contribution.mountUrl) await this.loadScript(contribution.mountUrl);
const key = contribution.pluginId + ':' + contribution.hook + ':' + contribution.id;
const mountFn = this.mounts[key];
if (!mountFn) return;
const parent = contribution.hook === 'mail.compose.attachments' ? this.attachmentsAnchor() : this.toolbarAnchor();
let target = parent.querySelector('[data-plugin-target="' + key + '"]');
if (!target) {
target = document.createElement('div');
target.dataset.pluginTarget = key;
target.className = 'mailcow-plugin-target';
parent.appendChild(target);
}
const context = {
basePath: this.basePath,
contribution,
hooks: this.hooks,
apiBase: contribution.apiBase,
uiBase: contribution.uiBase,
user: window.MAILCOW_USER || null,
};
await mountFn(target, context);
},
async renderHook(hookName) {
const list = this.hooks[hookName] || [];
for (const contribution of list) {
try {
await this.mountContribution(contribution);
} catch (error) {
console.error('Failed to mount contribution', contribution, error);
}
}
},
async init() {
window.MAILCOW_PLUGIN_RUNTIME = this;
await this.fetchHooks();
await this.renderHook('mail.compose.toolbar');
await this.renderHook('mail.compose.attachments');
}
};
const start = () => runtime.init().catch((err) => console.error('Mailcow plugin runtime bootstrap failed', err));
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', start, { once: true });
} else {
start();
}
})();`;
}