diff --git a/plugin/core/config.ts b/plugin/core/config.ts new file mode 100644 index 0000000..1d2e9b0 --- /dev/null +++ b/plugin/core/config.ts @@ -0,0 +1,67 @@ +export interface YonexusClientConfig { + mainHost: string; + identifier: string; + notifyBotToken: string; + adminUserId: string; +} + +export class YonexusClientConfigError extends Error { + readonly issues: string[]; + + constructor(issues: string[]) { + super(`Invalid Yonexus.Client config: ${issues.join("; ")}`); + this.name = "YonexusClientConfigError"; + this.issues = issues; + } +} + +function isNonEmptyString(value: unknown): value is string { + return typeof value === "string" && value.trim().length > 0; +} + +function isValidWsUrl(value: string): boolean { + try { + const url = new URL(value); + return url.protocol === "ws:" || url.protocol === "wss:"; + } catch { + return false; + } +} + +export function validateYonexusClientConfig(raw: unknown): YonexusClientConfig { + const source = raw as Record | null; + const issues: string[] = []; + + const mainHost = source?.mainHost; + if (!isNonEmptyString(mainHost)) { + issues.push("mainHost is required"); + } else if (!isValidWsUrl(mainHost.trim())) { + issues.push("mainHost must be a valid ws:// or wss:// URL"); + } + + const identifier = source?.identifier; + if (!isNonEmptyString(identifier)) { + issues.push("identifier is required"); + } + + const notifyBotToken = source?.notifyBotToken; + if (!isNonEmptyString(notifyBotToken)) { + issues.push("notifyBotToken is required"); + } + + const adminUserId = source?.adminUserId; + if (!isNonEmptyString(adminUserId)) { + issues.push("adminUserId is required"); + } + + if (issues.length > 0) { + throw new YonexusClientConfigError(issues); + } + + return { + mainHost: mainHost.trim(), + identifier: identifier.trim(), + notifyBotToken: notifyBotToken.trim(), + adminUserId: adminUserId.trim() + }; +} diff --git a/plugin/index.ts b/plugin/index.ts index 8a095cd..28b2420 100644 --- a/plugin/index.ts +++ b/plugin/index.ts @@ -1,3 +1,6 @@ +export { validateYonexusClientConfig, YonexusClientConfigError } from "./core/config.js"; +export type { YonexusClientConfig } from "./core/config.js"; + export interface YonexusClientPluginManifest { readonly name: "Yonexus.Client"; readonly version: string;