UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

155 lines (154 loc) • 6.61 kB
import { D as normalizeOptionalString, j as isRecord } from "./runtime-doctor-migrations-KsHvG31D.js"; import "./src-BRYbjtIr.js"; //#region packages/normalization-core/src/expect.ts /** Returns the value or throws with the named context; use for genuine invariants only. */ function expectDefined(value, context) { if (value === null || value === void 0) throw new Error("expected " + context + " to be defined"); return value; } //#endregion //#region src/secrets/ref-contract.ts /** Shared SecretRef grammar and validation helpers for config, schema, SDK, and gateway parity. */ /** Provider alias used when a SecretRef omits a source-specific provider. */ const DEFAULT_SECRET_PROVIDER_ALIAS = "default"; const ENV_SECRET_REF_ID_RE = /^[A-Z][A-Z0-9_]{0,127}$/; function isSecretRef(value) { if (!isRecord(value)) return false; if (Object.keys(value).length !== 3) return false; return (value.source === "env" || value.source === "file" || value.source === "exec" || value.source === "store") && typeof value.provider === "string" && value.provider.trim().length > 0 && typeof value.id === "string" && value.id.trim().length > 0; } /** * Runtime secret-reference grammar shared by config parsing, plugin SDK schemas, * gateway parity checks, and resolver planning. */ const FILE_SECRET_REF_SEGMENT_PATTERN = /^(?:[^~]|~0|~1)*$/; /** Shared alias grammar for env/file/exec/store secret provider names. */ const SECRET_PROVIDER_ALIAS_PATTERN = /^[a-z][a-z0-9_-]{0,63}$/; const EXEC_SECRET_REF_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:/#-]{0,255}$/; function secretRefKey(ref) { return `${ref.source}:${ref.provider}:${ref.id}`; } /** Validates file secret ref ids against the shared JSON-pointer-style contract. */ function isValidFileSecretRefId(value) { if (value === "value") return true; if (!value.startsWith("/")) return false; return value.slice(1).split("/").every((segment) => FILE_SECRET_REF_SEGMENT_PATTERN.test(segment)); } function validateExecSecretRefId(value) { if (!EXEC_SECRET_REF_ID_PATTERN.test(value)) return { ok: false, reason: "pattern" }; for (const segment of value.split("/")) if (segment === "." || segment === "..") return { ok: false, reason: "traversal-segment" }; return { ok: true }; } function isValidExecSecretRefId(value) { return validateExecSecretRefId(value).ok; } function formatExecSecretRefIdValidationMessage() { return [ "Exec secret reference id must match /^[A-Za-z0-9][A-Za-z0-9._:/#-]{0,255}$/", "and must not include \".\" or \"..\" path segments", "(example: \"vault/openai/api-key\" or \"aws/secret#json_key\")." ].join(" "); } //#endregion //#region src/config/types.secrets.ts const ENV_SECRET_TEMPLATE_RE = /^\$\{([A-Z][A-Z0-9_]{0,127})\}$/; const ENV_SECRET_SHORTHAND_RE = /^\$([A-Z][A-Z0-9_]{0,127})$/; function isLegacySecretRefWithoutProvider(value) { if (!isRecord(value)) return false; return (value.source === "env" || value.source === "file" || value.source === "exec" || value.source === "store") && typeof value.id === "string" && value.id.trim().length > 0 && value.provider === void 0; } /** Parse `$NAME` and `${NAME}` env-secret shorthand strings into env SecretRefs. */ function parseEnvTemplateSecretRef(value, provider = DEFAULT_SECRET_PROVIDER_ALIAS) { if (typeof value !== "string") return null; const trimmed = value.trim(); const match = ENV_SECRET_TEMPLATE_RE.exec(trimmed) ?? ENV_SECRET_SHORTHAND_RE.exec(trimmed); if (!match) return null; return { source: "env", provider: provider.trim() || "default", id: expectDefined(match[1], "types.secrets regex capture 1") }; } /** Parse current structured refs and supported env shorthand without legacy normalization. */ function parseSecretRef(value, defaults) { return isSecretRef(value) ? value : parseEnvTemplateSecretRef(value, defaults?.env); } /** Public SDK input adapter; persisted config and state are normalized by Doctor. */ function coerceSecretRef(value, defaults) { if (isLegacySecretRefWithoutProvider(value)) { const provider = defaults?.[value.source] ?? "default"; return { source: value.source, provider, id: value.id }; } return parseSecretRef(value, defaults); } /** Return whether a value contains either a literal secret string or resolvable SecretRef shape. */ function hasConfiguredSecretInput(value, defaults) { if (normalizeSecretInputString(value)) return true; return coerceSecretRef(value, defaults) !== null; } /** Trim a literal secret input string while leaving non-string inputs unresolved. */ function normalizeSecretInputString(value) { return normalizeOptionalString(value); } /** Error thrown when strict secret reads encounter a configured but unresolved SecretRef. */ var UnresolvedSecretInputError = class extends Error { constructor(params) { super(`${params.path}: unresolved SecretRef "${secretRefKey(params.ref)}". Resolve this command against an active gateway runtime snapshot before reading it.`); this.name = "UnresolvedSecretInputError"; this.path = params.path; this.ref = params.ref; } }; /** Resolve a secret field to either a literal value, a configured-unavailable ref, or missing. */ function resolveSecretInputString(params) { const { explicitRef, ref } = resolveSecretInputRef(params); const normalized = normalizeSecretInputString(params.value); if (normalized && !explicitRef) return { status: "available", value: normalized, ref: null }; if (!ref) return { status: "missing", value: void 0, ref: null }; if ((params.mode ?? "strict") === "strict") throw new UnresolvedSecretInputError({ path: params.path, ref }); return { status: "configured_unavailable", value: void 0, ref }; } /** Return a strict literal secret value, throwing if the field still points at a SecretRef. */ function normalizeResolvedSecretInputString(params) { return resolveSecretInputString({ ...params, mode: "strict" }).value; } /** Resolve explicit `refValue` before inline secret references embedded in `value`. */ function resolveSecretInputRef(params) { const explicitRef = coerceSecretRef(params.refValue, params.defaults); const inlineRef = explicitRef ? null : coerceSecretRef(params.value, params.defaults); return { explicitRef, inlineRef, ref: explicitRef ?? inlineRef }; } //#endregion export { ENV_SECRET_REF_ID_RE as a, isValidExecSecretRefId as c, parseEnvTemplateSecretRef as i, isValidFileSecretRefId as l, normalizeResolvedSecretInputString as n, SECRET_PROVIDER_ALIAS_PATTERN as o, normalizeSecretInputString as r, formatExecSecretRefIdValidationMessage as s, hasConfiguredSecretInput as t, expectDefined as u };