Files
Skald-Circle/web/components/shared/plugin-common.js
T
dguiducci 4b1affa600
Nightly Build / build (push) Successful in 7m1s
plugins: merge the user Plugins page into per-plugin sidebar pages
The generic per-user #plugins page is gone: a plugin with per-user
settings hosts them in its own web_pages() sidebar page instead
(Telegram's pairing page is new; Honcho's opt-in page already existed).
The admin catalog moves from #plugin-catalog to #plugins (old hash
redirected), and user_config_schema is removed from the Plugin trait,
the API DTOs and both plugins — the my-config endpoint, the
plugin_user_configs store and the update_user_config hook stay, now
driven by each plugin's own page fragment.
2026-07-28 20:48:03 +01:00

45 lines
1.8 KiB
JavaScript

// Shared helpers for the plugin pages (`plugin-catalog`, `plugin-detail`).
// Kept separate from `connector-common.js` on purpose: the plugin model
// (JSON-Schema config blobs, `plugin_access`) is not the connector model
// (env/api_key manifests).
export async function jf(url, opts) {
const res = await fetch(url, opts);
if (!res.ok) throw new Error(await res.text() || `HTTP ${res.status}`);
const ct = res.headers.get('content-type') || '';
return ct.includes('application/json') ? res.json() : null;
}
/// Normalizes a plugin JSON Schema (`{properties, required}`) into flat field
/// descriptors. Only the scalar types a form can render are supported.
export function schemaFields(schema) {
const props = schema?.properties;
if (!props || typeof props !== 'object') return [];
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
return Object.entries(props).map(([key, p]) => ({
key,
label: p.title || key,
description: p.description || '',
type: p.type === 'boolean' ? 'boolean' : (p.type === 'integer' || p.type === 'number') ? 'number' : 'string',
required: required.has(key),
sensitive: !!p.sensitive,
}));
}
export const hasSchema = (schema) => schemaFields(schema).length > 0;
/// Required config keys with no persisted value yet.
export function missingRequired(p) {
return schemaFields(p.config_schema)
.filter(f => f.required && (p.config?.[f.key] === undefined || p.config?.[f.key] === null || p.config?.[f.key] === ''));
}
/// Admin-catalog health of a plugin: 'off' | 'needs_config' | 'not_running' | 'ok'.
/// Green only when enabled, running and every required config key is set.
export function pluginHealth(p) {
if (!p.enabled) return 'off';
if (missingRequired(p).length) return 'needs_config';
if (!p.running) return 'not_running';
return 'ok';
}