SnowLuma v2.4.2 source snapshot
Dev Build / cleanup (push) Waiting to run
Dev Build / typecheck (push) Waiting to run
Publish MCP to npm / Build, test, and publish MCP (push) Waiting to run
Publish SDK to npm / Build, test, and publish SDK (push) Waiting to run
Sync action catalog to docs / sync (push) Waiting to run
Publish UI to npm / Build and publish UI (push) Waiting to run
Build and Release / preflight (push) Waiting to run
Dev Build / cleanup (push) Waiting to run
Dev Build / typecheck (push) Waiting to run
Publish MCP to npm / Build, test, and publish MCP (push) Waiting to run
Publish SDK to npm / Build, test, and publish SDK (push) Waiting to run
Sync action catalog to docs / sync (push) Waiting to run
Publish UI to npm / Build and publish UI (push) Waiting to run
Build and Release / preflight (push) Waiting to run
This commit is contained in:
commit
fa9c73363d
1367 files changed
+355735
No files matched your search
@@ -0,0 +1,100 @@
|
||||
/** Browser-safe contract shared by startup, the WebUI and embedding hosts.
|
||||
* Targets are deployment choices; they never belong in the saved UI preferences. */
|
||||
export const WEBUI_TARGETS = {
|
||||
maibot: {
|
||||
label: '麦麦 / 一键包',
|
||||
styles: ['millennium'],
|
||||
defaultStyle: 'millennium',
|
||||
},
|
||||
} as const;
|
||||
|
||||
export type WebuiTarget = keyof typeof WEBUI_TARGETS;
|
||||
export type WebuiColorMode = 'light' | 'dark' | 'system';
|
||||
|
||||
export type WebuiPresentation = {
|
||||
[T in WebuiTarget]: {
|
||||
version: 1;
|
||||
target: T;
|
||||
style: (typeof WEBUI_TARGETS)[T]['styles'][number];
|
||||
mode: WebuiColorMode;
|
||||
};
|
||||
}[WebuiTarget];
|
||||
|
||||
/** null releases the override for this document, without changing deployment opt-in. */
|
||||
export type WebuiPresentationUpdate = WebuiPresentation | { version: 1; target: null };
|
||||
export const WEBUI_PRESENTATION_EVENT = 'snowluma:host-appearance';
|
||||
export const WEBUI_TARGET_BOOTSTRAP_ID = 'snowluma-webui-target';
|
||||
|
||||
export function resolveWebuiTarget(raw: string | undefined): WebuiTarget | null {
|
||||
if (raw === undefined || raw.trim() === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const value = raw.trim();
|
||||
|
||||
if (!Object.hasOwn(WEBUI_TARGETS, value)) {
|
||||
throw new Error(
|
||||
`Invalid SNOWLUMA_WEBUI_TARGET: ${JSON.stringify(value)}. Expected ${Object.keys(WEBUI_TARGETS).join(', ')} or an empty value.`,
|
||||
);
|
||||
}
|
||||
|
||||
return value as WebuiTarget;
|
||||
}
|
||||
|
||||
export function defaultWebuiPresentation(target: WebuiTarget): WebuiPresentation {
|
||||
return { version: 1, target, style: WEBUI_TARGETS[target].defaultStyle, mode: 'system' };
|
||||
}
|
||||
|
||||
export function parseWebuiPresentation(value: unknown): WebuiPresentationUpdate {
|
||||
if (
|
||||
!value ||
|
||||
typeof value !== 'object' ||
|
||||
!('version' in value) ||
|
||||
value.version !== 1 ||
|
||||
!('target' in value)
|
||||
) {
|
||||
throw new TypeError('Invalid host appearance: expected a version 1 presentation');
|
||||
}
|
||||
|
||||
if (value.target === null) {
|
||||
return { version: 1, target: null };
|
||||
}
|
||||
|
||||
if (typeof value.target !== 'string' || !Object.hasOwn(WEBUI_TARGETS, value.target)) {
|
||||
throw new TypeError('Invalid host appearance target');
|
||||
}
|
||||
|
||||
const target = value.target as WebuiTarget;
|
||||
const styles: readonly string[] = WEBUI_TARGETS[target].styles;
|
||||
|
||||
if (!('style' in value) || typeof value.style !== 'string' || !styles.includes(value.style)) {
|
||||
throw new TypeError(`Invalid host appearance style for ${target}`);
|
||||
}
|
||||
|
||||
if (
|
||||
!('mode' in value) ||
|
||||
(value.mode !== 'light' && value.mode !== 'dark' && value.mode !== 'system')
|
||||
) {
|
||||
throw new TypeError('Invalid host appearance color mode');
|
||||
}
|
||||
|
||||
// Both discriminants have been checked against the same target registry.
|
||||
return { version: 1, target, style: value.style, mode: value.mode } as WebuiPresentation;
|
||||
}
|
||||
|
||||
/** Inject before the cached pre-paint theme script. Default HTML stays byte-for-byte intact. */
|
||||
export function injectWebuiTarget(html: string, target: WebuiTarget | null): string {
|
||||
if (target === null) {
|
||||
return html;
|
||||
}
|
||||
|
||||
if (!html.includes('<head>')) {
|
||||
throw new Error('WebUI HTML is missing <head>; cannot inject runtime target');
|
||||
}
|
||||
|
||||
const json = JSON.stringify(defaultWebuiPresentation(target)).replaceAll('<', '\\u003c');
|
||||
return html.replace(
|
||||
'<head>',
|
||||
`<head>\n <script id="${WEBUI_TARGET_BOOTSTRAP_ID}" type="application/json">${json}</script>`,
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user