feat: plugins v1.7

This commit is contained in:
2026-04-29 15:24:56 +02:00
parent eabbc08896
commit d261bac0ed
45 changed files with 5621 additions and 867 deletions

122
electron/api/docs-html.ts Normal file
View File

@@ -0,0 +1,122 @@
import { promises as fs } from 'fs';
import * as path from 'path';
function getScalarBundleCandidates(): string[] {
const processWithResources = process as NodeJS.Process & { resourcesPath?: string };
const candidates: string[] = [];
if (processWithResources.resourcesPath) {
candidates.push(path.join(processWithResources.resourcesPath, 'scalar', 'api-reference.js'));
}
candidates.push(path.join(process.cwd(), 'node_modules', '@scalar', 'api-reference', 'dist', 'browser', 'standalone.js'));
try {
candidates.push(path.join(path.dirname(require.resolve('@scalar/api-reference')), 'browser', 'standalone.js'));
} catch {
// ignore; the packaged app path above is the production path
}
return candidates;
}
export async function getScalarApiReferenceBundlePath(): Promise<string | null> {
for (const candidate of getScalarBundleCandidates()) {
try {
await fs.access(candidate);
return candidate;
} catch {
// try the next candidate
}
}
return null;
}
export function getDocsHtml(specUrl: string): string {
const scalarConfig = {
url: specUrl,
theme: 'default',
layout: 'modern',
proxyUrl: '',
telemetry: false,
persistAuth: false,
showDeveloperTools: 'never',
hideDownloadButton: false,
hideTestRequestButton: false,
hideClientButton: false,
externalUrls: {
dashboardUrl: '',
registryUrl: '',
proxyUrl: '',
apiBaseUrl: ''
},
agent: {
disabled: true,
hideAddApi: true
},
mcp: {
disabled: true
}
};
return `<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
http-equiv="Content-Security-Policy"
content="default-src 'none'; script-src 'self' 'nonce-metoyou-local-api-docs'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'"
/>
<title>MetoYou Local API</title>
<style>
:root { color-scheme: light dark; }
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: #0b0d11;
color: #e6e9ee;
}
.placeholder {
max-width: 720px;
margin: 8vh auto;
padding: 2rem;
background: #14181f;
border: 1px solid #232a35;
border-radius: 12px;
}
h1 { margin-top: 0; }
a { color: #7aa2f7; }
code { background: #1f262f; padding: 0.1rem 0.4rem; border-radius: 4px; }
#api-reference { min-height: 100vh; }
</style>
</head>
<body>
<div id="api-reference"></div>
<noscript>
<div class="placeholder">
<h1>API Documentation</h1>
<p>JavaScript is required to render Scalar. The OpenAPI specification is available directly:</p>
<p><a href="${specUrl}">${specUrl}</a></p>
</div>
</noscript>
<script nonce="metoyou-local-api-docs" src="/scalar/api-reference.js"></script>
<script nonce="metoyou-local-api-docs">
(function () {
var config = ${JSON.stringify(scalarConfig)};
if (!window.Scalar || typeof window.Scalar.createApiReference !== 'function') {
var root = document.getElementById('api-reference');
root.innerHTML = '<div class="placeholder"><h1>API Documentation</h1>'
+ '<p>The bundled Scalar UI could not be loaded.</p>'
+ '<p>Spec: <a href="' + config.url + '">' + config.url + '</a></p></div>';
return;
}
window.Scalar.createApiReference('#api-reference', config);
})();
</script>
</body>
</html>`;
}