fix: propagate settingsSchema
This commit is contained in:
@@ -187,6 +187,9 @@ export async function POST(request: NextRequest) {
|
|||||||
...(manifest.configSchema && typeof manifest.configSchema === 'object'
|
...(manifest.configSchema && typeof manifest.configSchema === 'object'
|
||||||
? { configSchema: manifest.configSchema as ServerPlugin['configSchema'] }
|
? { configSchema: manifest.configSchema as ServerPlugin['configSchema'] }
|
||||||
: {}),
|
: {}),
|
||||||
|
...(manifest.settingsSchema && typeof manifest.settingsSchema === 'object'
|
||||||
|
? { settingsSchema: manifest.settingsSchema as ServerPlugin['settingsSchema'] }
|
||||||
|
: {}),
|
||||||
...(declaredFrameOrigins.length > 0
|
...(declaredFrameOrigins.length > 0
|
||||||
? { frameOrigins: declaredFrameOrigins }
|
? { frameOrigins: declaredFrameOrigins }
|
||||||
: {}),
|
: {}),
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ export async function GET() {
|
|||||||
dev: p.dev,
|
dev: p.dev,
|
||||||
// Surface so clients can enforce api.http.fetch origin allowlists.
|
// Surface so clients can enforce api.http.fetch origin allowlists.
|
||||||
httpOrigins: p.httpOrigins,
|
httpOrigins: p.httpOrigins,
|
||||||
settingsSchema: undefined, // Will be read from the bundle's manifest
|
// Per-user settings schema, captured from the manifest at upload/load
|
||||||
|
// time so the client can render the settings UI without re-parsing.
|
||||||
|
settingsSchema: p.settingsSchema,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Only serve enabled themes
|
// Only serve enabled themes
|
||||||
|
|||||||
@@ -185,6 +185,9 @@ async function loadDevPlugin(pluginDir: string): Promise<DevPluginEntry | null>
|
|||||||
...(manifest.configSchema && typeof manifest.configSchema === 'object'
|
...(manifest.configSchema && typeof manifest.configSchema === 'object'
|
||||||
? { configSchema: manifest.configSchema as ServerPlugin['configSchema'] }
|
? { configSchema: manifest.configSchema as ServerPlugin['configSchema'] }
|
||||||
: {}),
|
: {}),
|
||||||
|
...(manifest.settingsSchema && typeof manifest.settingsSchema === 'object'
|
||||||
|
? { settingsSchema: manifest.settingsSchema as ServerPlugin['settingsSchema'] }
|
||||||
|
: {}),
|
||||||
...(frameOrigins.length > 0 ? { frameOrigins } : {}),
|
...(frameOrigins.length > 0 ? { frameOrigins } : {}),
|
||||||
...(httpOrigins.length > 0 ? { httpOrigins } : {}),
|
...(httpOrigins.length > 0 ? { httpOrigins } : {}),
|
||||||
installedAt,
|
installedAt,
|
||||||
|
|||||||
@@ -28,6 +28,21 @@ export interface PluginConfigField {
|
|||||||
options?: { label: string; value: string }[];
|
options?: { label: string; value: string }[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Per-user setting field, mirrors the manifest's `settingsSchema` shape
|
||||||
|
* (see lib/plugin-types.ts SettingFieldSchema). The server passes these
|
||||||
|
* through unchanged so the client can render the per-user settings UI.
|
||||||
|
*/
|
||||||
|
export interface PluginSettingsField {
|
||||||
|
type: 'boolean' | 'string' | 'number' | 'select';
|
||||||
|
label: string;
|
||||||
|
description?: string;
|
||||||
|
default: unknown;
|
||||||
|
options?: string[];
|
||||||
|
min?: number;
|
||||||
|
max?: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ServerPlugin {
|
export interface ServerPlugin {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
@@ -40,6 +55,7 @@ export interface ServerPlugin {
|
|||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
forceEnabled?: boolean;
|
forceEnabled?: boolean;
|
||||||
configSchema?: Record<string, PluginConfigField>;
|
configSchema?: Record<string, PluginConfigField>;
|
||||||
|
settingsSchema?: Record<string, PluginSettingsField>;
|
||||||
installedAt: string;
|
installedAt: string;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -313,6 +313,8 @@ interface ServerPluginInfo {
|
|||||||
dev?: boolean;
|
dev?: boolean;
|
||||||
/** Allowlist of origins this plugin may target via api.http.fetch(). */
|
/** Allowlist of origins this plugin may target via api.http.fetch(). */
|
||||||
httpOrigins?: string[];
|
httpOrigins?: string[];
|
||||||
|
/** Per-user settings schema, captured from the manifest server-side. */
|
||||||
|
settingsSchema?: InstalledPlugin['settingsSchema'];
|
||||||
}
|
}
|
||||||
|
|
||||||
const SERVER_MANAGED_KEY = 'server-managed-plugin-ids';
|
const SERVER_MANAGED_KEY = 'server-managed-plugin-ids';
|
||||||
@@ -412,6 +414,7 @@ async function syncServerPlugins(
|
|||||||
forceEnabled: sp.forceEnabled,
|
forceEnabled: sp.forceEnabled,
|
||||||
adminApproved: true, // Server-managed plugins are always approved
|
adminApproved: true, // Server-managed plugins are always approved
|
||||||
settings: {},
|
settings: {},
|
||||||
|
settingsSchema: sp.settingsSchema,
|
||||||
bundleHash: sp.bundleHash,
|
bundleHash: sp.bundleHash,
|
||||||
...(sp.httpOrigins && sp.httpOrigins.length > 0
|
...(sp.httpOrigins && sp.httpOrigins.length > 0
|
||||||
? { httpOrigins: sp.httpOrigins }
|
? { httpOrigins: sp.httpOrigins }
|
||||||
@@ -452,6 +455,7 @@ async function syncServerPlugins(
|
|||||||
forceEnabled: sp.forceEnabled,
|
forceEnabled: sp.forceEnabled,
|
||||||
bundleHash: sp.bundleHash,
|
bundleHash: sp.bundleHash,
|
||||||
httpOrigins: sp.httpOrigins,
|
httpOrigins: sp.httpOrigins,
|
||||||
|
settingsSchema: sp.settingsSchema,
|
||||||
}
|
}
|
||||||
: p
|
: p
|
||||||
),
|
),
|
||||||
@@ -464,10 +468,22 @@ async function syncServerPlugins(
|
|||||||
...p,
|
...p,
|
||||||
managed: true,
|
managed: true,
|
||||||
forceEnabled: sp.forceEnabled,
|
forceEnabled: sp.forceEnabled,
|
||||||
|
settingsSchema: sp.settingsSchema,
|
||||||
}
|
}
|
||||||
: p
|
: p
|
||||||
),
|
),
|
||||||
}));
|
}));
|
||||||
|
} else if (
|
||||||
|
JSON.stringify(local.settingsSchema ?? null) !== JSON.stringify(sp.settingsSchema ?? null)
|
||||||
|
) {
|
||||||
|
// Schema drift: the bundle is current but the persisted plugin record
|
||||||
|
// pre-dates the server passing settingsSchema through, so the per-user
|
||||||
|
// settings UI was rendering empty. Patch the schema in place.
|
||||||
|
set(state => ({
|
||||||
|
plugins: state.plugins.map(p =>
|
||||||
|
p.id === sp.id ? { ...p, settingsSchema: sp.settingsSchema } : p
|
||||||
|
),
|
||||||
|
}));
|
||||||
} else if (sp.forceEnabled && !local.enabled) {
|
} else if (sp.forceEnabled && !local.enabled) {
|
||||||
// Force-enable if the server says so but client has it disabled
|
// Force-enable if the server says so but client has it disabled
|
||||||
set(state => ({
|
set(state => ({
|
||||||
|
|||||||
Reference in New Issue
Block a user