@fayz-ai/core 0.52.0 → 0.54.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { tl } from './chunk-F4TZJHLH.js';
1
+ import { tl } from './chunk-3Q7EFWGY.js';
2
2
 
3
3
  // src/data/errors.ts
4
4
  var RETRYABLE_KINDS = ["offline", "server"];
@@ -142,5 +142,5 @@ function describeError(err, fallback) {
142
142
  }
143
143
 
144
144
  export { DataError, describeError, errorMessage, offlineMessage, toDataError };
145
- //# sourceMappingURL=chunk-KRQ3R2OF.js.map
146
- //# sourceMappingURL=chunk-KRQ3R2OF.js.map
145
+ //# sourceMappingURL=chunk-2YIEIPMV.js.map
146
+ //# sourceMappingURL=chunk-2YIEIPMV.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/data/errors.ts","../src/lib/error-message.ts"],"names":[],"mappings":"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","file":"chunk-KRQ3R2OF.js","sourcesContent":["// ---------------------------------------------------------------------------\n// Data error taxonomy — one normalized shape for everything the data door can\n// fail with, so callers branch on a `kind` instead of grepping a message.\n//\n// The split that matters most is 'forbidden' vs 'missing-object': a PostgREST\n// \"permission denied for table x\" (42501) once surfaced to a user as \"analytics\n// engine missing\", sending everyone to look for a migration that was already\n// applied. They are different failures with different fixes — a grant versus a\n// deploy — and the taxonomy has to keep them apart.\n// ---------------------------------------------------------------------------\n\nexport type DataErrorKind =\n /** No usable network: fetch failed, request aborted, timed out. */\n | 'offline'\n /** No identity: missing/expired JWT. Re-authenticate. */\n | 'unauthorized'\n /** Identity known, access refused: RLS or a missing GRANT. */\n | 'forbidden'\n /** The object exists, the row does not. */\n | 'not-found'\n /** The table/view/function itself is not there — a deploy gap, not a data gap. */\n | 'missing-object'\n /** The write lost a race or duplicates a unique key. */\n | 'conflict'\n /** The request itself is wrong: bad syntax, constraint violated, no tenant. */\n | 'invalid'\n /** Anything the backend blames on itself. */\n | 'server'\n\n/** Only these are worth trying again with the same input. */\nconst RETRYABLE_KINDS: readonly DataErrorKind[] = ['offline', 'server']\n\nexport interface DataErrorOptions {\n /** The original throw, preserved for reporters that want the real object. */\n cause?: unknown\n /** HTTP status when the failure came over the wire. */\n status?: number\n /** PostgREST (`PGRST116`) or Postgres (`42501`) code. */\n code?: string\n details?: string\n /** Postgres often puts the actionable fix here — surface it, do not drop it. */\n hint?: string\n}\n\nexport class DataError extends Error {\n readonly kind: DataErrorKind\n readonly retryable: boolean\n readonly cause?: unknown\n readonly status?: number\n readonly code?: string\n readonly details?: string\n readonly hint?: string\n\n constructor(kind: DataErrorKind, message: string, options: DataErrorOptions = {}) {\n super(message)\n this.name = 'DataError'\n this.kind = kind\n this.retryable = RETRYABLE_KINDS.includes(kind)\n this.cause = options.cause\n this.status = options.status\n this.code = options.code\n this.details = options.details\n this.hint = options.hint\n }\n}\n\n// ---------------------------------------------------------------------------\n// Classification\n// ---------------------------------------------------------------------------\n\n/** Postgres + PostgREST codes are stable; branch on them before any text. */\nconst CODE_KINDS: Record<string, DataErrorKind> = {\n // PostgREST\n PGRST100: 'invalid', // parse error in the query string\n PGRST106: 'missing-object', // schema not exposed\n PGRST116: 'not-found', // zero rows where exactly one was requested\n PGRST202: 'missing-object', // function not found in schema cache\n PGRST204: 'missing-object', // column not found in schema cache\n PGRST205: 'missing-object', // table not found in schema cache\n PGRST301: 'unauthorized', // JWT invalid or expired\n PGRST302: 'unauthorized', // anonymous access disabled\n // Postgres\n '22007': 'invalid', // invalid datetime format\n '22P02': 'invalid', // invalid input syntax\n '23502': 'invalid', // not-null violation\n '23505': 'conflict', // unique violation\n '23514': 'invalid', // check violation\n '42501': 'forbidden', // insufficient privilege / permission denied\n '42883': 'missing-object', // undefined function\n '42P01': 'missing-object', // undefined table\n '53300': 'server', // too many connections\n '57014': 'server', // statement timeout, server side\n}\n\n/** Transport-level codes — the request never reached PostgREST. */\nconst OFFLINE_CODES = new Set(['ECONNREFUSED', 'ECONNRESET', 'ENOTFOUND', 'ETIMEDOUT', 'EAI_AGAIN'])\n\nconst OFFLINE_TEXT = /failed to fetch|fetch failed|network ?error|networkrequestfailed|load failed|connection (refused|reset|closed)|err_internet_disconnected|aborted|signal is aborted|the operation was aborted|timed out|timeout|sem conexão com a internet|no internet connection/i\n\nfunction statusKind(status: number): DataErrorKind {\n if (status === 401) return 'unauthorized'\n if (status === 403) return 'forbidden'\n if (status === 404 || status === 406) return 'not-found'\n if (status === 408) return 'offline'\n if (status === 409) return 'conflict'\n if (status === 400 || status === 422) return 'invalid'\n if (status >= 500) return 'server'\n return 'server'\n}\n\nfunction textKind(message: string): DataErrorKind | undefined {\n const m = message.toLowerCase()\n if (/permission denied|row-level security|row level security|insufficient privilege/.test(m)) return 'forbidden'\n if (/does not exist|undefined table|undefined function|schema cache|could not find the (table|function)/.test(m)) return 'missing-object'\n if (/jwt|not authenticated|invalid token|unauthorized|no api key/.test(m)) return 'unauthorized'\n if (/duplicate key|already exists|conflict/.test(m)) return 'conflict'\n if (/invalid input (syntax|value)|violates (not-null|check) constraint|invalid request/.test(m)) return 'invalid'\n if (/no rows|not found/.test(m)) return 'not-found'\n return undefined\n}\n\nfunction pick(source: Record<string, unknown>, key: string): unknown {\n const value = source[key]\n return value === null ? undefined : value\n}\n\nfunction readStatus(source: Record<string, unknown>): number | undefined {\n for (const key of ['status', 'statusCode', 'httpStatus']) {\n const value = pick(source, key)\n if (typeof value === 'number') return value\n if (typeof value === 'string' && /^\\d{3}$/.test(value)) return Number(value)\n }\n const response = pick(source, 'response')\n if (response && typeof response === 'object') {\n const status = (response as Record<string, unknown>).status\n if (typeof status === 'number') return status\n }\n return undefined\n}\n\nfunction isOffline(name: string, message: string, code: string | undefined, status: number | undefined): boolean {\n if (name === 'AbortError' || name === 'TimeoutError') return true\n if (code && OFFLINE_CODES.has(code)) return true\n if (status !== undefined) return false\n // navigator.onLine is a hint, not a verdict — it only decides errors we could\n // not classify from a code or a status.\n const nav = (globalThis as { navigator?: { onLine?: boolean } }).navigator\n if (nav && nav.onLine === false) return true\n return OFFLINE_TEXT.test(message)\n}\n\n/**\n * Normalizes anything thrown by the data layer into a {@link DataError}.\n * Idempotent — a DataError passes through untouched.\n */\nexport function toDataError(err: unknown): DataError {\n if (err instanceof DataError) return err\n\n const source: Record<string, unknown> =\n err && typeof err === 'object' ? (err as Record<string, unknown>) : {}\n const name = typeof source.name === 'string' ? source.name : ''\n const rawMessage = typeof source.message === 'string' ? source.message : ''\n const message = rawMessage || (typeof err === 'string' ? err : '') || 'data request failed'\n const codeValue = pick(source, 'code')\n const code = typeof codeValue === 'string' ? codeValue : typeof codeValue === 'number' ? String(codeValue) : undefined\n const status = readStatus(source)\n const details = typeof source.details === 'string' ? source.details : undefined\n const hint = typeof source.hint === 'string' ? source.hint : undefined\n\n let kind: DataErrorKind | undefined = code ? CODE_KINDS[code] : undefined\n if (!kind && isOffline(name, message, code, status)) kind = 'offline'\n if (!kind && status !== undefined) kind = statusKind(status)\n if (!kind) kind = textKind(message)\n\n return new DataError(kind ?? 'server', message, { cause: err, status, code, details, hint })\n}\n","import { toDataError } from '../data/errors'\nimport { tl } from '../i18n'\n\n/**\n * A readable message out of anything a data layer throws.\n *\n * Supabase/PostgREST reject with a PLAIN OBJECT ({message, details, hint,\n * code}), not an Error — so the usual `err instanceof Error ? err.message :\n * String(err)` renders the literal text \"[object Object]\" and hides the one\n * piece of information the user needed. The workspace wizard showed exactly\n * that for a 400 whose body named the failing constraint.\n *\n * Lives in core because every layer above it catches from Supabase: ui, admin,\n * storefront and the plugins all had their own copy of the broken ternary.\n * The careful branches below are plugin-shop's, which had already met this on\n * its settings screens and worked out what each case has to answer.\n *\n * `fallback` is a parameter because the last resort is the one string a user\n * actually reads, and it belongs in their language: SDK prose is English, but\n * merchant-facing copy is the carve-out (see fayz-ssr/AGENTS.md). plugin-shop\n * passes 'erro desconhecido'.\n */\nexport function errorMessage(err: unknown, fallback = 'Unknown error'): string {\n // \"TypeError: Failed to fetch\" is the browser's wording, not the user's: say what happened.\n if (err != null && toDataError(err).kind === 'offline') return offlineMessage()\n // An Error is answered by an Error, message or not. Falling through to the\n // object branch would reach `String(err)` and render the useless word\n // \"Error\" — a refusal with no reason is worse than a generic one, because\n // there is nothing to search for and nothing to report.\n if (err instanceof Error) return err.message.trim() || fallback\n if (typeof err === 'string') return err\n if (err && typeof err === 'object') {\n const e = err as { message?: unknown; details?: unknown; hint?: unknown; code?: unknown }\n // `hint` is worth keeping when Postgres offers one: on a permission error\n // it names the GRANT that is missing, which is the difference between a\n // shrug and a fix.\n const parts = [e.message, e.details, e.hint]\n .filter((p): p is string => typeof p === 'string' && p.trim().length > 0)\n if (parts.length > 0) return [...new Set(parts)].join(' — ')\n // Only a code to go on. The bare code alone (\"erro 23514\") reads as noise;\n // pairing it with the fallback keeps the sentence in the reader's language\n // and still carries the one token worth searching for.\n if (typeof e.code === 'string' && e.code) return `${fallback} (${e.code})`\n }\n const text = String(err ?? '').trim()\n // Never hand back the stringification of an object nobody can read.\n return text && text !== '[object Object]' ? text : fallback\n}\n\nexport function offlineMessage(): string {\n return tl('No internet connection.', 'Sem conexão com a internet.')\n}\n\n/**\n * The text to put on screen for a failure: offline is named as such, a PostgREST\n * object yields its message, and nothing renders as \"[object Object]\". The\n * fallback is in the reader's language.\n */\nexport function describeError(err: unknown, fallback?: string): string {\n return errorMessage(err, fallback ?? tl('Something went wrong. Try again.', 'Algo deu errado. Tente de novo.'))\n}\n"]}
1
+ {"version":3,"sources":["../src/data/errors.ts","../src/lib/error-message.ts"],"names":[],"mappings":"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","file":"chunk-2YIEIPMV.js","sourcesContent":["// ---------------------------------------------------------------------------\n// Data error taxonomy — one normalized shape for everything the data door can\n// fail with, so callers branch on a `kind` instead of grepping a message.\n//\n// The split that matters most is 'forbidden' vs 'missing-object': a PostgREST\n// \"permission denied for table x\" (42501) once surfaced to a user as \"analytics\n// engine missing\", sending everyone to look for a migration that was already\n// applied. They are different failures with different fixes — a grant versus a\n// deploy — and the taxonomy has to keep them apart.\n// ---------------------------------------------------------------------------\n\nexport type DataErrorKind =\n /** No usable network: fetch failed, request aborted, timed out. */\n | 'offline'\n /** No identity: missing/expired JWT. Re-authenticate. */\n | 'unauthorized'\n /** Identity known, access refused: RLS or a missing GRANT. */\n | 'forbidden'\n /** The object exists, the row does not. */\n | 'not-found'\n /** The table/view/function itself is not there — a deploy gap, not a data gap. */\n | 'missing-object'\n /** The write lost a race or duplicates a unique key. */\n | 'conflict'\n /** The request itself is wrong: bad syntax, constraint violated, no tenant. */\n | 'invalid'\n /** Anything the backend blames on itself. */\n | 'server'\n\n/** Only these are worth trying again with the same input. */\nconst RETRYABLE_KINDS: readonly DataErrorKind[] = ['offline', 'server']\n\nexport interface DataErrorOptions {\n /** The original throw, preserved for reporters that want the real object. */\n cause?: unknown\n /** HTTP status when the failure came over the wire. */\n status?: number\n /** PostgREST (`PGRST116`) or Postgres (`42501`) code. */\n code?: string\n details?: string\n /** Postgres often puts the actionable fix here — surface it, do not drop it. */\n hint?: string\n}\n\nexport class DataError extends Error {\n readonly kind: DataErrorKind\n readonly retryable: boolean\n readonly cause?: unknown\n readonly status?: number\n readonly code?: string\n readonly details?: string\n readonly hint?: string\n\n constructor(kind: DataErrorKind, message: string, options: DataErrorOptions = {}) {\n super(message)\n this.name = 'DataError'\n this.kind = kind\n this.retryable = RETRYABLE_KINDS.includes(kind)\n this.cause = options.cause\n this.status = options.status\n this.code = options.code\n this.details = options.details\n this.hint = options.hint\n }\n}\n\n// ---------------------------------------------------------------------------\n// Classification\n// ---------------------------------------------------------------------------\n\n/** Postgres + PostgREST codes are stable; branch on them before any text. */\nconst CODE_KINDS: Record<string, DataErrorKind> = {\n // PostgREST\n PGRST100: 'invalid', // parse error in the query string\n PGRST106: 'missing-object', // schema not exposed\n PGRST116: 'not-found', // zero rows where exactly one was requested\n PGRST202: 'missing-object', // function not found in schema cache\n PGRST204: 'missing-object', // column not found in schema cache\n PGRST205: 'missing-object', // table not found in schema cache\n PGRST301: 'unauthorized', // JWT invalid or expired\n PGRST302: 'unauthorized', // anonymous access disabled\n // Postgres\n '22007': 'invalid', // invalid datetime format\n '22P02': 'invalid', // invalid input syntax\n '23502': 'invalid', // not-null violation\n '23505': 'conflict', // unique violation\n '23514': 'invalid', // check violation\n '42501': 'forbidden', // insufficient privilege / permission denied\n '42883': 'missing-object', // undefined function\n '42P01': 'missing-object', // undefined table\n '53300': 'server', // too many connections\n '57014': 'server', // statement timeout, server side\n}\n\n/** Transport-level codes — the request never reached PostgREST. */\nconst OFFLINE_CODES = new Set(['ECONNREFUSED', 'ECONNRESET', 'ENOTFOUND', 'ETIMEDOUT', 'EAI_AGAIN'])\n\nconst OFFLINE_TEXT = /failed to fetch|fetch failed|network ?error|networkrequestfailed|load failed|connection (refused|reset|closed)|err_internet_disconnected|aborted|signal is aborted|the operation was aborted|timed out|timeout|sem conexão com a internet|no internet connection/i\n\nfunction statusKind(status: number): DataErrorKind {\n if (status === 401) return 'unauthorized'\n if (status === 403) return 'forbidden'\n if (status === 404 || status === 406) return 'not-found'\n if (status === 408) return 'offline'\n if (status === 409) return 'conflict'\n if (status === 400 || status === 422) return 'invalid'\n if (status >= 500) return 'server'\n return 'server'\n}\n\nfunction textKind(message: string): DataErrorKind | undefined {\n const m = message.toLowerCase()\n if (/permission denied|row-level security|row level security|insufficient privilege/.test(m)) return 'forbidden'\n if (/does not exist|undefined table|undefined function|schema cache|could not find the (table|function)/.test(m)) return 'missing-object'\n if (/jwt|not authenticated|invalid token|unauthorized|no api key/.test(m)) return 'unauthorized'\n if (/duplicate key|already exists|conflict/.test(m)) return 'conflict'\n if (/invalid input (syntax|value)|violates (not-null|check) constraint|invalid request/.test(m)) return 'invalid'\n if (/no rows|not found/.test(m)) return 'not-found'\n return undefined\n}\n\nfunction pick(source: Record<string, unknown>, key: string): unknown {\n const value = source[key]\n return value === null ? undefined : value\n}\n\nfunction readStatus(source: Record<string, unknown>): number | undefined {\n for (const key of ['status', 'statusCode', 'httpStatus']) {\n const value = pick(source, key)\n if (typeof value === 'number') return value\n if (typeof value === 'string' && /^\\d{3}$/.test(value)) return Number(value)\n }\n const response = pick(source, 'response')\n if (response && typeof response === 'object') {\n const status = (response as Record<string, unknown>).status\n if (typeof status === 'number') return status\n }\n return undefined\n}\n\nfunction isOffline(name: string, message: string, code: string | undefined, status: number | undefined): boolean {\n if (name === 'AbortError' || name === 'TimeoutError') return true\n if (code && OFFLINE_CODES.has(code)) return true\n if (status !== undefined) return false\n // navigator.onLine is a hint, not a verdict — it only decides errors we could\n // not classify from a code or a status.\n const nav = (globalThis as { navigator?: { onLine?: boolean } }).navigator\n if (nav && nav.onLine === false) return true\n return OFFLINE_TEXT.test(message)\n}\n\n/**\n * Normalizes anything thrown by the data layer into a {@link DataError}.\n * Idempotent — a DataError passes through untouched.\n */\nexport function toDataError(err: unknown): DataError {\n if (err instanceof DataError) return err\n\n const source: Record<string, unknown> =\n err && typeof err === 'object' ? (err as Record<string, unknown>) : {}\n const name = typeof source.name === 'string' ? source.name : ''\n const rawMessage = typeof source.message === 'string' ? source.message : ''\n const message = rawMessage || (typeof err === 'string' ? err : '') || 'data request failed'\n const codeValue = pick(source, 'code')\n const code = typeof codeValue === 'string' ? codeValue : typeof codeValue === 'number' ? String(codeValue) : undefined\n const status = readStatus(source)\n const details = typeof source.details === 'string' ? source.details : undefined\n const hint = typeof source.hint === 'string' ? source.hint : undefined\n\n let kind: DataErrorKind | undefined = code ? CODE_KINDS[code] : undefined\n if (!kind && isOffline(name, message, code, status)) kind = 'offline'\n if (!kind && status !== undefined) kind = statusKind(status)\n if (!kind) kind = textKind(message)\n\n return new DataError(kind ?? 'server', message, { cause: err, status, code, details, hint })\n}\n","import { toDataError } from '../data/errors'\nimport { tl } from '../i18n'\n\n/**\n * A readable message out of anything a data layer throws.\n *\n * Supabase/PostgREST reject with a PLAIN OBJECT ({message, details, hint,\n * code}), not an Error — so the usual `err instanceof Error ? err.message :\n * String(err)` renders the literal text \"[object Object]\" and hides the one\n * piece of information the user needed. The workspace wizard showed exactly\n * that for a 400 whose body named the failing constraint.\n *\n * Lives in core because every layer above it catches from Supabase: ui, admin,\n * storefront and the plugins all had their own copy of the broken ternary.\n * The careful branches below are plugin-shop's, which had already met this on\n * its settings screens and worked out what each case has to answer.\n *\n * `fallback` is a parameter because the last resort is the one string a user\n * actually reads, and it belongs in their language: SDK prose is English, but\n * merchant-facing copy is the carve-out (see fayz-ssr/AGENTS.md). plugin-shop\n * passes 'erro desconhecido'.\n */\nexport function errorMessage(err: unknown, fallback = 'Unknown error'): string {\n // \"TypeError: Failed to fetch\" is the browser's wording, not the user's: say what happened.\n if (err != null && toDataError(err).kind === 'offline') return offlineMessage()\n // An Error is answered by an Error, message or not. Falling through to the\n // object branch would reach `String(err)` and render the useless word\n // \"Error\" — a refusal with no reason is worse than a generic one, because\n // there is nothing to search for and nothing to report.\n if (err instanceof Error) return err.message.trim() || fallback\n if (typeof err === 'string') return err\n if (err && typeof err === 'object') {\n const e = err as { message?: unknown; details?: unknown; hint?: unknown; code?: unknown }\n // `hint` is worth keeping when Postgres offers one: on a permission error\n // it names the GRANT that is missing, which is the difference between a\n // shrug and a fix.\n const parts = [e.message, e.details, e.hint]\n .filter((p): p is string => typeof p === 'string' && p.trim().length > 0)\n if (parts.length > 0) return [...new Set(parts)].join(' — ')\n // Only a code to go on. The bare code alone (\"erro 23514\") reads as noise;\n // pairing it with the fallback keeps the sentence in the reader's language\n // and still carries the one token worth searching for.\n if (typeof e.code === 'string' && e.code) return `${fallback} (${e.code})`\n }\n const text = String(err ?? '').trim()\n // Never hand back the stringification of an object nobody can read.\n return text && text !== '[object Object]' ? text : fallback\n}\n\nexport function offlineMessage(): string {\n return tl('No internet connection.', 'Sem conexão com a internet.')\n}\n\n/**\n * The text to put on screen for a failure: offline is named as such, a PostgREST\n * object yields its message, and nothing renders as \"[object Object]\". The\n * fallback is in the reader's language.\n */\nexport function describeError(err: unknown, fallback?: string): string {\n return errorMessage(err, fallback ?? tl('Something went wrong. Try again.', 'Algo deu errado. Tente de novo.'))\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { isConnectorCategory, CONNECTOR_CATEGORIES, requestPlaneSpec, connectorPlanes, invocationPlane, connectorSubscribes, permissionActions, isEventPermission, connectorEntities, connectorSubscribesTo } from './chunk-7IOAKSU2.js';
2
- import { errorMessage } from './chunk-KRQ3R2OF.js';
1
+ import { isConnectorCategory, CONNECTOR_CATEGORIES, requestPlaneSpec, connectorPlanes, invocationPlane, connectorSubscribes, permissionActions, isEventPermission, connectorEntities, connectorSubscribesTo } from './chunk-XXHB7ZRM.js';
2
+ import { errorMessage } from './chunk-2YIEIPMV.js';
3
3
 
4
4
  // src/testing.ts
5
5
  var PluginContractError = class extends Error {
@@ -286,5 +286,5 @@ function assertConnectorContract(connector) {
286
286
  }
287
287
 
288
288
  export { PluginContractError, assertConnectorContract, assertPluginManifestContract, bespokeConnectorTables };
289
- //# sourceMappingURL=chunk-4IOUOZ6N.js.map
290
- //# sourceMappingURL=chunk-4IOUOZ6N.js.map
289
+ //# sourceMappingURL=chunk-37YMNSAI.js.map
290
+ //# sourceMappingURL=chunk-37YMNSAI.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/testing.ts"],"names":[],"mappings":"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","file":"chunk-4IOUOZ6N.js","sourcesContent":["// ---------------------------------------------------------------------------\n// Plugin contract assertions — the integrity half of the deploy gate.\n// ---------------------------------------------------------------------------\n// Framework-agnostic runtime checks (no test-runner dependency) that any\n// plugin's *.test.ts calls to prove its manifest/connector conform to the\n// platform contract BEFORE it can ship. A plugin that fails these would break\n// the host app at mount time (missing route component, duplicate ids, malformed\n// settings tab). Pair with a capability test (does the plugin do its job?) — see\n// docs/plugins/PLUGIN-PATTERNS.md → capability anatomy. These throw on the first violation.\nimport { errorMessage } from './lib/error-message'\nimport type { PluginManifest } from './types/plugins'\nimport type { Connector } from './integrations'\nimport {\n CONNECTOR_CATEGORIES,\n connectorEntities,\n connectorPlanes,\n connectorSubscribes,\n connectorSubscribesTo,\n grants,\n invocationPlane,\n isConnectorCategory,\n isEventPermission,\n permissionActions,\n requestPlaneSpec,\n} from './integrations'\nimport type { ConnectorPermission } from './integrations'\n\nexport class PluginContractError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'PluginContractError'\n }\n}\n\nfunction fail(scope: string, msg: string): never {\n throw new PluginContractError(`[${scope}] ${msg}`)\n}\n\nfunction nonEmptyString(v: unknown): v is string {\n return typeof v === 'string' && v.trim().length > 0\n}\n\n/**\n * Assert a PluginManifest is structurally sound enough to mount safely.\n * Checks identity, navigation/route wiring, settings tabs, declared features,\n * and id uniqueness. Throws PluginContractError on the first problem.\n */\nexport function assertPluginManifestContract(manifest: PluginManifest): void {\n const id = manifest?.id\n const scope = nonEmptyString(id) ? id : '<unknown plugin>'\n\n for (const field of ['id', 'name', 'icon', 'version'] as const) {\n if (!nonEmptyString(manifest?.[field])) fail(scope, `manifest.${field} must be a non-empty string`)\n }\n\n if (!Array.isArray(manifest.navigation)) fail(scope, 'manifest.navigation must be an array (use [] for settings-only plugins)')\n if (!Array.isArray(manifest.routes)) fail(scope, 'manifest.routes must be an array (use [] for settings-only plugins)')\n\n // Every nav entry must point at a route; every route needs a path + component.\n for (const [i, nav] of manifest.navigation.entries()) {\n if (!nonEmptyString((nav as any)?.route)) fail(scope, `navigation[${i}].route must be a non-empty string`)\n }\n const routePaths = new Set<string>()\n for (const [i, route] of manifest.routes.entries()) {\n if (!nonEmptyString((route as any)?.path)) fail(scope, `routes[${i}].path must be a non-empty string`)\n if (typeof (route as any)?.component !== 'function') fail(scope, `routes[${i}].component must be a component`)\n if (routePaths.has((route as any).path)) fail(scope, `duplicate route path \"${(route as any).path}\"`)\n routePaths.add((route as any).path)\n }\n // A nav entry that links to a route the plugin doesn't declare is dead UI.\n for (const [i, nav] of manifest.navigation.entries()) {\n const r = (nav as any).route\n if (routePaths.size > 0 && !routePaths.has(r)) {\n fail(scope, `navigation[${i}].route \"${r}\" has no matching route in manifest.routes`)\n }\n }\n\n // Settings tabs (the only UI surface integrations need) must be renderable.\n const settingIds = new Set<string>()\n for (const [i, tab] of (manifest.settings ?? []).entries()) {\n if (!nonEmptyString((tab as any)?.id)) fail(scope, `settings[${i}].id must be a non-empty string`)\n if (!nonEmptyString((tab as any)?.label)) fail(scope, `settings[${i}].label must be a non-empty string`)\n if (typeof (tab as any)?.component !== 'function') fail(scope, `settings[${i}].component must be a component`)\n if (settingIds.has((tab as any).id)) fail(scope, `duplicate settings tab id \"${(tab as any).id}\"`)\n settingIds.add((tab as any).id)\n }\n\n for (const [i, feat] of (manifest.declaredFeatures ?? []).entries()) {\n if (!nonEmptyString((feat as any)?.id)) fail(scope, `declaredFeatures[${i}].id must be a non-empty string`)\n }\n\n for (const [i, src] of (manifest.emitsFrom ?? []).entries()) {\n if (!nonEmptyString(src?.table)) fail(scope, `emitsFrom[${i}].table must be a non-empty string`)\n if (!nonEmptyString(src?.entityKey)) fail(scope, `emitsFrom[${i}].entityKey must be a non-empty string`)\n for (const action of src.actions ?? []) {\n if (!EVENT_ACTIONS.has(action)) fail(scope, `emitsFrom[${i}] has unknown action \"${action}\"`)\n }\n }\n\n const functionSlugs = new Set<string>()\n for (const [i, fn] of (manifest.functions ?? []).entries()) {\n if (!SLUG.test(fn?.slug ?? '')) fail(scope, `functions[${i}].slug must be kebab-case — it becomes the deployed function name`)\n if (functionSlugs.has(fn.slug)) fail(scope, `duplicate function slug \"${fn.slug}\"`)\n functionSlugs.add(fn.slug)\n if (typeof fn.verifyJwt !== 'boolean') fail(scope, `functions[${i}].verifyJwt must be a boolean`)\n if (!FUNCTION_INGRESS.has(fn.ingress)) fail(scope, `functions[${i}].ingress \"${fn.ingress}\" is not one of ${[...FUNCTION_INGRESS].join(', ')}`)\n // The ingress authenticates by signature, not by a caller JWT it does not have.\n if (fn.ingress === 'fayz' && fn.verifyJwt) fail(scope, `functions[${i}] is reached through the Fayz ingress, so verifyJwt must be false`)\n for (const secret of fn.secrets ?? []) {\n // A name, never a value — this is the shape that keeps a key out of git.\n if (!SECRET_NAME.test(secret)) fail(scope, `functions[${i}].secrets must name secrets (SCREAMING_SNAKE_CASE), never carry their values`)\n }\n }\n\n for (const [i, def] of (manifest.connectors ?? []).entries()) {\n // An unlisted category renders NO badge rather than a wrong one, so the\n // mistake is invisible in a screenshot. Caught here instead.\n if (def.category !== undefined && !isConnectorCategory(def.category)) {\n fail(\n scope,\n `connectors[${i}].category \"${def.category}\" is not a catalogue category — ` +\n `use one of ${CONNECTOR_CATEGORIES.join(', ')}, taken from the catalogue row with this connector's slug.`,\n )\n }\n for (const pattern of def.subscribesTo ?? []) {\n if (!nonEmptyString(pattern)) fail(scope, `connectors[${i}].subscribesTo must hold non-empty patterns`)\n // Only a trailing star is honoured; see eventKeyMatches.\n if (pattern.includes('*') && !pattern.endsWith('*')) {\n fail(scope, `connectors[${i}].subscribesTo \"${pattern}\" — \"*\" is only honoured at the end`)\n }\n }\n\n assertConnectorPermissions(scope, `connectors[${i}]`, def)\n // The request plane's two fields are required THERE and meaningless\n // elsewhere. Checked at the manifest so a connector cannot reach a buyer\n // with an undeclared budget — the failure would otherwise be a spinner.\n if ((def.planes ?? []).includes('request')) {\n try {\n requestPlaneSpec(def)\n } catch (error) {\n fail(scope, `connectors[${i}] ${errorMessage(error)}`)\n }\n } else if (def.latencyBudgetMs !== undefined || def.onFailure !== undefined) {\n fail(\n scope,\n `connectors[${i}] declares latencyBudgetMs/onFailure but is not on the request plane — ` +\n `nothing enforces them, so they read as a guarantee that does not exist.`,\n )\n }\n // Authorization vs configuration. Both declarations end up on the same row,\n // and a key in both is a value with two owners: the connect form would write\n // it and the settings form would overwrite it.\n const fieldKeys = new Set((def.fields ?? []).map((f) => f.key))\n const settingKeys = new Set<string>()\n for (const [j, setting] of (def.settings ?? []).entries()) {\n const at = `connectors[${i}].settings[${j}]`\n if (!nonEmptyString(setting?.key)) fail(scope, `${at}.key must be a non-empty string`)\n if (!nonEmptyString(setting?.label)) fail(scope, `${at}.label must be a non-empty string`)\n if (!SETTING_TYPES.has(setting.type)) {\n fail(scope, `${at}.type \"${setting.type}\" is not one of ${[...SETTING_TYPES].join(', ')}`)\n }\n if (settingKeys.has(setting.key)) fail(scope, `${at} duplicates settings key \"${setting.key}\"`)\n settingKeys.add(setting.key)\n if (fieldKeys.has(setting.key)) {\n fail(\n scope,\n `${at}.key \"${setting.key}\" is also a credential field — a key either authorizes the ` +\n `connection (fields) or configures it (settings), never both.`,\n )\n }\n if (setting.type === 'select' || setting.type === 'multi-select') {\n if (!Array.isArray(setting.options) || setting.options.length === 0) {\n fail(scope, `${at} is a ${setting.type} and must declare options — that is what replaces a free-text box`)\n }\n for (const [k, option] of setting.options.entries()) {\n if (!nonEmptyString(option?.value)) fail(scope, `${at}.options[${k}].value must be a non-empty string`)\n if (!nonEmptyString(option?.label)) fail(scope, `${at}.options[${k}].label must be a non-empty string`)\n }\n }\n if (setting.pattern !== undefined) {\n if (setting.type !== 'text') fail(scope, `${at}.pattern only applies to a text setting`)\n try {\n new RegExp(setting.pattern)\n } catch {\n fail(scope, `${at}.pattern is not a valid regular expression`)\n }\n // A refusal with no sentence is a form that says no and not why.\n if (!nonEmptyString(setting.patternHint)) fail(scope, `${at} declares a pattern, so it must declare patternHint`)\n }\n }\n // Declared settings nobody can read or write are a screen that renders empty.\n if (settingKeys.size > 0) {\n if (typeof def.getSettings !== 'function') fail(scope, `connectors[${i}] declares settings but no getSettings()`)\n if (typeof def.saveSettings !== 'function') fail(scope, `connectors[${i}] declares settings but no saveSettings()`)\n }\n\n // \"Acionado em quais momentos\" — a moment on a plane the connector does not\n // have is a promise the code cannot keep.\n const planes = new Set(connectorPlanes(def))\n const momentKeys = new Set<string>()\n for (const [j, moment] of (def.invokedAt ?? []).entries()) {\n const at = `connectors[${i}].invokedAt[${j}]`\n if (!nonEmptyString(moment?.key)) fail(scope, `${at}.key must be a non-empty string`)\n if (!nonEmptyString(moment?.label)) fail(scope, `${at}.label must be a non-empty string`)\n if (momentKeys.has(moment.key)) fail(scope, `${at} duplicates key \"${moment.key}\"`)\n momentKeys.add(moment.key)\n const plane = invocationPlane(moment)\n if (!planes.has(plane)) {\n fail(scope, `${at} is declared on the ${plane} plane, which connectors[${i}].planes does not include`)\n }\n if (moment.trigger !== undefined) {\n if (plane !== 'sync') fail(scope, `${at}.trigger only applies to a sync moment`)\n if (!TRIGGERS.has(moment.trigger)) fail(scope, `${at} has unknown trigger \"${moment.trigger}\"`)\n }\n // A moment that reaches something the connector never asked for is the\n // screen answering \"quando ele age\" with access nobody consented to.\n const declared = new Set((def.permissions ?? []).map((p) => p.resource))\n for (const resource of moment.touches ?? []) {\n if (!declared.has(resource)) {\n fail(\n scope,\n `${at}.touches names \"${resource}\", which connectors[${i}].permissions does not declare — ` +\n `a call site cannot reach what the consent view never showed.`,\n )\n }\n }\n }\n\n for (const [j, auto] of (def.managedAutomations ?? []).entries()) {\n if (!nonEmptyString(auto?.eventKey)) fail(scope, `connectors[${i}].managedAutomations[${j}].eventKey must be a non-empty string`)\n if (!nonEmptyString(auto?.label)) fail(scope, `connectors[${i}].managedAutomations[${j}].label must be a non-empty string`)\n // The screen would promise a reaction the ingress never delivers.\n if (!connectorSubscribes(def, auto.eventKey)) {\n fail(scope, `connectors[${i}].managedAutomations[${j}] fires on \"${auto.eventKey}\", which no subscribesTo pattern covers`)\n }\n }\n }\n\n // A connector brings a ConnectorDefinition, not a pair of tables.\n for (const [i, mig] of (manifest.migrations ?? []).entries()) {\n for (const table of bespokeConnectorTables(mig?.sql)) {\n fail(\n scope,\n `migrations[${i}] (\"${mig?.id ?? '?'}\") creates public.${table} — a connector's own ` +\n `*_integrations / *_sync_log table. Store the connection in connections / ` +\n `sync_runs via createConnectionStore('<connector-id>'): two accounts are two ` +\n `rows separated by instance_key, and connector-specific counters go in stats.`,\n )\n }\n }\n\n // A plugin that contributes nothing mountable is almost always a mistake.\n // (Connector-only addon plugins contribute via `connectors` instead.)\n if (\n manifest.navigation.length === 0 &&\n manifest.routes.length === 0 &&\n (manifest.settings ?? []).length === 0 &&\n (manifest.connectors ?? []).length === 0\n ) {\n fail(scope, 'plugin contributes no navigation, routes, settings, or connectors — it would mount but do nothing')\n }\n}\n\n/**\n * What a connector says it needs — and the four ways that declaration can\n * contradict the ones that already existed.\n *\n * The feature this guards is a consent view. Its whole value is that the list it\n * shows is the list, so every way of ending up with two lists is refused here:\n *\n * 1. an action that does not exist for the resource kind (`listen` on a\n * record type, `write` on an event) — a word the reader would have to guess at;\n * 2. a `data` permission naming a resource the legacy `entities` never listed,\n * or an entity with no permission — the \"writes to an entity it never\n * listed\" case, in both directions;\n * 3. a `listen` permission the legacy `subscribesTo` does not name, or a\n * `subscribesTo` pattern no permission explains — the connector would be\n * delivered facts the consent view never showed, or shown facts the ingress\n * filters out;\n * 4. two permissions for the same resource — two rows, two reasons, and no\n * answer to which one the tenant agreed to.\n *\n * Rules 2 and 3 only bite when BOTH declarations are present. A connector built\n * against an older core declares only the legacy fields and is unaffected; a\n * connector written today declares only `permissions` and both are derived from\n * it. What is refused is saying both things and saying them differently.\n */\nfunction assertConnectorPermissions(\n scope: string,\n path: string,\n def: { permissions?: ConnectorPermission[]; entities?: string[]; subscribesTo?: string[] },\n): void {\n const permissions = def.permissions\n if (permissions === undefined) return\n if (!Array.isArray(permissions)) fail(scope, `${path}.permissions must be an array`)\n\n const seen = new Set<string>()\n for (const [j, permission] of permissions.entries()) {\n const at = `${path}.permissions[${j}]`\n if (permission?.kind !== 'data' && permission?.kind !== 'event') {\n fail(scope, `${at}.kind must be \"data\" or \"event\"`)\n }\n if (!nonEmptyString(permission.resource)) fail(scope, `${at}.resource must be a non-empty string`)\n // The reason is the only part a tenant can actually judge; a blank one turns\n // the screen back into the schema dump it exists to replace.\n if (!nonEmptyString(permission.reason)) {\n fail(scope, `${at} must declare a reason — the sentence the tenant judges before authorizing`)\n }\n if (!Array.isArray(permission.actions) || permission.actions.length === 0) {\n fail(scope, `${at}.actions must name at least one action — a resource with no access is not a permission`)\n }\n const legal = permissionActions(permission.kind)\n for (const action of permission.actions) {\n if (!legal.includes(action)) {\n fail(scope, `${at} asks for \"${action}\" on the ${permission.kind} resource \"${permission.resource}\", which only admits ${legal.join(', ')}`)\n }\n }\n if (isEventPermission(permission) && permission.resource.includes('*') && !permission.resource.endsWith('*')) {\n fail(scope, `${at}.resource \"${permission.resource}\" — \"*\" is only honoured at the end`)\n }\n const key = `${permission.kind}:${permission.resource}`\n if (seen.has(key)) fail(scope, `${at} repeats \"${key}\" — one resource, one row, one reason`)\n seen.add(key)\n }\n\n // (2) data permissions ↔ the legacy entities list.\n if (def.entities !== undefined) {\n const declared = new Set(connectorEntities({ permissions }))\n const legacy = new Set(def.entities)\n for (const entity of declared) {\n if (!legacy.has(entity)) {\n fail(\n scope,\n `${path}.permissions reaches \"${entity}\", which ${path}.entities does not list — ` +\n `the two describe the same access and must name the same set (drop entities; it is derived).`,\n )\n }\n }\n for (const entity of legacy) {\n if (!declared.has(entity)) {\n fail(\n scope,\n `${path}.entities lists \"${entity}\" with no permission saying what it does with it — ` +\n `a record type on the consent view with no read/write is a name, not a declaration.`,\n )\n }\n }\n }\n\n // (3) listen permissions ↔ the legacy subscribesTo list.\n if (def.subscribesTo !== undefined) {\n const declared = new Set(connectorSubscribesTo({ permissions }))\n const legacy = new Set(def.subscribesTo)\n for (const pattern of declared) {\n if (!legacy.has(pattern)) {\n fail(\n scope,\n `${path}.permissions listens to \"${pattern}\", which ${path}.subscribesTo does not — ` +\n `the ingress filters on that list, so the consent view would promise a fact never delivered.`,\n )\n }\n }\n for (const pattern of legacy) {\n if (!declared.has(pattern)) {\n fail(\n scope,\n `${path}.subscribesTo asks for \"${pattern}\" with no listen permission explaining it — ` +\n `the connector would receive a fact the tenant was never shown.`,\n )\n }\n }\n }\n}\n\n/**\n * `CREATE TABLE [IF NOT EXISTS] [schema.]name` where name ends in `_integrations`\n * or `_sync_log` — the pair four connectors each reinvented before\n * `connections` / `sync_runs` existed (FAY-1376). Neither generic table\n * matches, so a connector that stores its connection in them creates nothing.\n *\n * Deliberately duplicated in scripts/check-connector-tables.mjs, which scans the\n * .sql files themselves: that runs in the `contracts` CI job with no install and\n * no build, so it cannot import this. This half catches SQL declared inline on a\n * manifest, which no .sql walk would see. The two are held in agreement by one\n * case table, asserted from both sides — see\n * packages/core/test/integrations/connector-tables.test.ts.\n */\nconst BESPOKE_CONNECTOR_TABLE =\n /\\bcreate\\s+table\\s+(?:if\\s+not\\s+exists\\s+)?(?:[a-z0-9_]+\\s*\\.\\s*)?([a-z0-9_]*(?:_integrations|_sync_log))\\b/gi\n\n/** Table names a CREATE TABLE in this SQL would bring back. Empty = conformant. */\nexport function bespokeConnectorTables(sql: unknown): string[] {\n const text = typeof sql === 'string' ? sql.replace(/\"/g, '') : ''\n const found = new Set<string>()\n for (const m of text.matchAll(BESPOKE_CONNECTOR_TABLE)) found.add(m[1].toLowerCase())\n return [...found]\n}\n\nconst EVENT_ACTIONS = new Set(['created', 'updated', 'deleted'])\nconst FUNCTION_INGRESS = new Set(['fayz', 'none'])\nconst SLUG = /^[a-z0-9][a-z0-9-]*$/\nconst SECRET_NAME = /^[A-Z][A-Z0-9_]*$/\n\nconst SETTING_TYPES = new Set(['text', 'select', 'multi-select', 'toggle'])\nconst AUTH_KINDS = new Set(['oauth', 'api-key', 'mtls'])\nconst DIRECTIONS = new Set(['inbound', 'outbound', 'bidirectional'])\nconst TRIGGERS = new Set(['on-write', 'scheduled', 'manual', 'webhook'])\n\n/**\n * Assert an integration Connector descriptor is well-formed: identity present,\n * a known auth kind, and at least one capability with a valid direction +\n * trigger set. This is the contract a connector must satisfy BEFORE its\n * data-plane (edge function) exists — the TDD anchor for an integration.\n */\nexport function assertConnectorContract(connector: Connector): void {\n const scope = nonEmptyString(connector?.id) ? `connector:${connector.id}` : '<unknown connector>'\n for (const field of ['id', 'provider', 'pluginId'] as const) {\n if (!nonEmptyString(connector?.[field])) fail(scope, `connector.${field} must be a non-empty string`)\n }\n if (!AUTH_KINDS.has(connector.authKind)) fail(scope, `connector.authKind \"${connector.authKind}\" is not one of ${[...AUTH_KINDS].join(', ')}`)\n if (!Array.isArray(connector.capabilities) || connector.capabilities.length === 0) {\n fail(scope, 'connector.capabilities must list at least one capability')\n }\n for (const [i, cap] of connector.capabilities.entries()) {\n if (!nonEmptyString(cap?.entity)) fail(scope, `capabilities[${i}].entity must be a non-empty string`)\n if (!DIRECTIONS.has(cap.direction)) fail(scope, `capabilities[${i}].direction \"${cap.direction}\" is invalid`)\n if (!Array.isArray(cap.triggers) || cap.triggers.length === 0) fail(scope, `capabilities[${i}].triggers must be non-empty`)\n for (const trig of cap.triggers) {\n if (!TRIGGERS.has(trig)) fail(scope, `capabilities[${i}] has unknown trigger \"${trig}\"`)\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/testing.ts"],"names":[],"mappings":";;;;AA2BO,IAAM,mBAAA,GAAN,cAAkC,KAAA,CAAM;AAAA,EAC7C,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AAAA,EACd;AACF;AAEA,SAAS,IAAA,CAAK,OAAe,GAAA,EAAoB;AAC/C,EAAA,MAAM,IAAI,mBAAA,CAAoB,CAAA,CAAA,EAAI,KAAK,CAAA,EAAA,EAAK,GAAG,CAAA,CAAE,CAAA;AACnD;AAEA,SAAS,eAAe,CAAA,EAAyB;AAC/C,EAAA,OAAO,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,CAAE,IAAA,GAAO,MAAA,GAAS,CAAA;AACpD;AAOO,SAAS,6BAA6B,QAAA,EAAgC;AAC3E,EAAA,MAAM,KAAK,QAAA,EAAU,EAAA;AACrB,EAAA,MAAM,KAAA,GAAQ,cAAA,CAAe,EAAE,CAAA,GAAI,EAAA,GAAK,kBAAA;AAExC,EAAA,KAAA,MAAW,SAAS,CAAC,IAAA,EAAM,MAAA,EAAQ,MAAA,EAAQ,SAAS,CAAA,EAAY;AAC9D,IAAA,IAAI,CAAC,cAAA,CAAe,QAAA,GAAW,KAAK,CAAC,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,SAAA,EAAY,KAAK,CAAA,2BAAA,CAA6B,CAAA;AAAA,EACpG;AAEA,EAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,QAAA,CAAS,UAAU,CAAA,EAAG,IAAA,CAAK,OAAO,yEAAyE,CAAA;AAC9H,EAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,QAAA,CAAS,MAAM,CAAA,EAAG,IAAA,CAAK,OAAO,qEAAqE,CAAA;AAGtH,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,GAAG,KAAK,QAAA,CAAS,UAAA,CAAW,SAAQ,EAAG;AACpD,IAAA,IAAI,CAAC,eAAgB,GAAA,EAAa,KAAK,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,WAAA,EAAc,CAAC,CAAA,kCAAA,CAAoC,CAAA;AAAA,EAC3G;AACA,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAY;AACnC,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,KAAK,KAAK,QAAA,CAAS,MAAA,CAAO,SAAQ,EAAG;AAClD,IAAA,IAAI,CAAC,eAAgB,KAAA,EAAe,IAAI,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,OAAA,EAAU,CAAC,CAAA,iCAAA,CAAmC,CAAA;AACrG,IAAA,IAAI,OAAQ,OAAe,SAAA,KAAc,UAAA,OAAiB,KAAA,EAAO,CAAA,OAAA,EAAU,CAAC,CAAA,+BAAA,CAAiC,CAAA;AAC7G,IAAA,IAAI,UAAA,CAAW,GAAA,CAAK,KAAA,CAAc,IAAI,CAAA,OAAQ,KAAA,EAAO,CAAA,sBAAA,EAA0B,KAAA,CAAc,IAAI,CAAA,CAAA,CAAG,CAAA;AACpG,IAAA,UAAA,CAAW,GAAA,CAAK,MAAc,IAAI,CAAA;AAAA,EACpC;AAEA,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,GAAG,KAAK,QAAA,CAAS,UAAA,CAAW,SAAQ,EAAG;AACpD,IAAA,MAAM,IAAK,GAAA,CAAY,KAAA;AACvB,IAAA,IAAI,WAAW,IAAA,GAAO,CAAA,IAAK,CAAC,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,EAAG;AAC7C,MAAA,IAAA,CAAK,KAAA,EAAO,CAAA,WAAA,EAAc,CAAC,CAAA,SAAA,EAAY,CAAC,CAAA,0CAAA,CAA4C,CAAA;AAAA,IACtF;AAAA,EACF;AAGA,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAY;AACnC,EAAA,KAAA,MAAW,CAAC,GAAG,GAAG,CAAA,IAAA,CAAM,SAAS,QAAA,IAAY,EAAC,EAAG,OAAA,EAAQ,EAAG;AAC1D,IAAA,IAAI,CAAC,eAAgB,GAAA,EAAa,EAAE,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,SAAA,EAAY,CAAC,CAAA,+BAAA,CAAiC,CAAA;AACjG,IAAA,IAAI,CAAC,eAAgB,GAAA,EAAa,KAAK,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,SAAA,EAAY,CAAC,CAAA,kCAAA,CAAoC,CAAA;AACvG,IAAA,IAAI,OAAQ,KAAa,SAAA,KAAc,UAAA,OAAiB,KAAA,EAAO,CAAA,SAAA,EAAY,CAAC,CAAA,+BAAA,CAAiC,CAAA;AAC7G,IAAA,IAAI,UAAA,CAAW,GAAA,CAAK,GAAA,CAAY,EAAE,CAAA,OAAQ,KAAA,EAAO,CAAA,2BAAA,EAA+B,GAAA,CAAY,EAAE,CAAA,CAAA,CAAG,CAAA;AACjG,IAAA,UAAA,CAAW,GAAA,CAAK,IAAY,EAAE,CAAA;AAAA,EAChC;AAEA,EAAA,KAAA,MAAW,CAAC,GAAG,IAAI,CAAA,IAAA,CAAM,SAAS,gBAAA,IAAoB,EAAC,EAAG,OAAA,EAAQ,EAAG;AACnE,IAAA,IAAI,CAAC,eAAgB,IAAA,EAAc,EAAE,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,iBAAA,EAAoB,CAAC,CAAA,+BAAA,CAAiC,CAAA;AAAA,EAC5G;AAEA,EAAA,KAAA,MAAW,CAAC,GAAG,GAAG,CAAA,IAAA,CAAM,SAAS,SAAA,IAAa,EAAC,EAAG,OAAA,EAAQ,EAAG;AAC3D,IAAA,IAAI,CAAC,eAAe,GAAA,EAAK,KAAK,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,UAAA,EAAa,CAAC,CAAA,kCAAA,CAAoC,CAAA;AAC/F,IAAA,IAAI,CAAC,eAAe,GAAA,EAAK,SAAS,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,UAAA,EAAa,CAAC,CAAA,sCAAA,CAAwC,CAAA;AACvG,IAAA,KAAA,MAAW,MAAA,IAAU,GAAA,CAAI,OAAA,IAAW,EAAC,EAAG;AACtC,MAAA,IAAI,CAAC,aAAA,CAAc,GAAA,CAAI,MAAM,CAAA,EAAG,IAAA,CAAK,KAAA,EAAO,CAAA,UAAA,EAAa,CAAC,CAAA,sBAAA,EAAyB,MAAM,CAAA,CAAA,CAAG,CAAA;AAAA,IAC9F;AAAA,EACF;AAEA,EAAA,MAAM,aAAA,uBAAoB,GAAA,EAAY;AACtC,EAAA,KAAA,MAAW,CAAC,GAAG,EAAE,CAAA,IAAA,CAAM,SAAS,SAAA,IAAa,EAAC,EAAG,OAAA,EAAQ,EAAG;AAC1D,IAAA,IAAI,CAAC,IAAA,CAAK,IAAA,CAAK,EAAA,EAAI,IAAA,IAAQ,EAAE,CAAA,EAAG,IAAA,CAAK,KAAA,EAAO,CAAA,UAAA,EAAa,CAAC,CAAA,sEAAA,CAAmE,CAAA;AAC7H,IAAA,IAAI,aAAA,CAAc,GAAA,CAAI,EAAA,CAAG,IAAI,CAAA,OAAQ,KAAA,EAAO,CAAA,yBAAA,EAA4B,EAAA,CAAG,IAAI,CAAA,CAAA,CAAG,CAAA;AAClF,IAAA,aAAA,CAAc,GAAA,CAAI,GAAG,IAAI,CAAA;AACzB,IAAA,IAAI,OAAO,GAAG,SAAA,KAAc,SAAA,OAAgB,KAAA,EAAO,CAAA,UAAA,EAAa,CAAC,CAAA,6BAAA,CAA+B,CAAA;AAChG,IAAA,IAAI,CAAC,iBAAiB,GAAA,CAAI,EAAA,CAAG,OAAO,CAAA,EAAG,IAAA,CAAK,OAAO,CAAA,UAAA,EAAa,CAAC,cAAc,EAAA,CAAG,OAAO,mBAAmB,CAAC,GAAG,gBAAgB,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAE9I,IAAA,IAAI,EAAA,CAAG,YAAY,MAAA,IAAU,EAAA,CAAG,WAAW,IAAA,CAAK,KAAA,EAAO,CAAA,UAAA,EAAa,CAAC,CAAA,iEAAA,CAAmE,CAAA;AACxI,IAAA,KAAA,MAAW,MAAA,IAAU,EAAA,CAAG,OAAA,IAAW,EAAC,EAAG;AAErC,MAAA,IAAI,CAAC,YAAY,IAAA,CAAK,MAAM,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,UAAA,EAAa,CAAC,CAAA,4EAAA,CAA8E,CAAA;AAAA,IACzI;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,CAAC,GAAG,GAAG,CAAA,IAAA,CAAM,SAAS,UAAA,IAAc,EAAC,EAAG,OAAA,EAAQ,EAAG;AAG5D,IAAA,IAAI,IAAI,QAAA,KAAa,MAAA,IAAa,CAAC,mBAAA,CAAoB,GAAA,CAAI,QAAQ,CAAA,EAAG;AACpE,MAAA,IAAA;AAAA,QACE,KAAA;AAAA,QACA,CAAA,WAAA,EAAc,CAAC,CAAA,YAAA,EAAe,GAAA,CAAI,QAAQ,CAAA,gDAAA,EAC1B,oBAAA,CAAqB,IAAA,CAAK,IAAI,CAAC,CAAA,0DAAA;AAAA,OACjD;AAAA,IACF;AACA,IAAA,KAAA,MAAW,OAAA,IAAW,GAAA,CAAI,YAAA,IAAgB,EAAC,EAAG;AAC5C,MAAA,IAAI,CAAC,eAAe,OAAO,CAAA,OAAQ,KAAA,EAAO,CAAA,WAAA,EAAc,CAAC,CAAA,2CAAA,CAA6C,CAAA;AAEtG,MAAA,IAAI,OAAA,CAAQ,SAAS,GAAG,CAAA,IAAK,CAAC,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AACnD,QAAA,IAAA,CAAK,KAAA,EAAO,CAAA,WAAA,EAAc,CAAC,CAAA,gBAAA,EAAmB,OAAO,CAAA,wCAAA,CAAqC,CAAA;AAAA,MAC5F;AAAA,IACF;AAEA,IAAA,0BAAA,CAA2B,KAAA,EAAO,CAAA,WAAA,EAAc,CAAC,CAAA,CAAA,CAAA,EAAK,GAAG,CAAA;AAIzD,IAAA,IAAA,CAAK,IAAI,MAAA,IAAU,EAAC,EAAG,QAAA,CAAS,SAAS,CAAA,EAAG;AAC1C,MAAA,IAAI;AACF,QAAA,gBAAA,CAAiB,GAAG,CAAA;AAAA,MACtB,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,OAAO,CAAA,WAAA,EAAc,CAAC,KAAK,YAAA,CAAa,KAAK,CAAC,CAAA,CAAE,CAAA;AAAA,MACvD;AAAA,IACF,WAAW,GAAA,CAAI,eAAA,KAAoB,MAAA,IAAa,GAAA,CAAI,cAAc,MAAA,EAAW;AAC3E,MAAA,IAAA;AAAA,QACE,KAAA;AAAA,QACA,cAAc,CAAC,CAAA,mJAAA;AAAA,OAEjB;AAAA,IACF;AAIA,IAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAA,CAAK,GAAA,CAAI,MAAA,IAAU,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,GAAG,CAAC,CAAA;AAC9D,IAAA,MAAM,WAAA,uBAAkB,GAAA,EAAY;AACpC,IAAA,KAAA,MAAW,CAAC,GAAG,OAAO,CAAA,IAAA,CAAM,IAAI,QAAA,IAAY,EAAC,EAAG,OAAA,EAAQ,EAAG;AACzD,MAAA,MAAM,EAAA,GAAK,CAAA,WAAA,EAAc,CAAC,CAAA,WAAA,EAAc,CAAC,CAAA,CAAA,CAAA;AACzC,MAAA,IAAI,CAAC,eAAe,OAAA,EAAS,GAAG,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,+BAAA,CAAiC,CAAA;AACrF,MAAA,IAAI,CAAC,eAAe,OAAA,EAAS,KAAK,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,iCAAA,CAAmC,CAAA;AACzF,MAAA,IAAI,CAAC,aAAA,CAAc,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA,EAAG;AACpC,QAAA,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,OAAA,EAAU,QAAQ,IAAI,CAAA,gBAAA,EAAmB,CAAC,GAAG,aAAa,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,MAC3F;AACA,MAAA,IAAI,WAAA,CAAY,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA,EAAG,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,0BAAA,EAA6B,OAAA,CAAQ,GAAG,CAAA,CAAA,CAAG,CAAA;AAC9F,MAAA,WAAA,CAAY,GAAA,CAAI,QAAQ,GAAG,CAAA;AAC3B,MAAA,IAAI,SAAA,CAAU,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC9B,QAAA,IAAA;AAAA,UACE,KAAA;AAAA,UACA,CAAA,EAAG,EAAE,CAAA,MAAA,EAAS,OAAA,CAAQ,GAAG,CAAA,4HAAA;AAAA,SAE3B;AAAA,MACF;AACA,MAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,QAAA,IAAY,OAAA,CAAQ,SAAS,cAAA,EAAgB;AAChE,QAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,OAAA,CAAQ,OAAO,CAAA,IAAK,OAAA,CAAQ,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG;AACnE,UAAA,IAAA,CAAK,OAAO,CAAA,EAAG,EAAE,CAAA,MAAA,EAAS,OAAA,CAAQ,IAAI,CAAA,sEAAA,CAAmE,CAAA;AAAA,QAC3G;AACA,QAAA,KAAA,MAAW,CAAC,CAAA,EAAG,MAAM,KAAK,OAAA,CAAQ,OAAA,CAAQ,SAAQ,EAAG;AACnD,UAAA,IAAI,CAAC,cAAA,CAAe,MAAA,EAAQ,KAAK,CAAA,EAAG,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,SAAA,EAAY,CAAC,CAAA,kCAAA,CAAoC,CAAA;AACtG,UAAA,IAAI,CAAC,cAAA,CAAe,MAAA,EAAQ,KAAK,CAAA,EAAG,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,SAAA,EAAY,CAAC,CAAA,kCAAA,CAAoC,CAAA;AAAA,QACxG;AAAA,MACF;AACA,MAAA,IAAI,OAAA,CAAQ,YAAY,MAAA,EAAW;AACjC,QAAA,IAAI,QAAQ,IAAA,KAAS,MAAA,OAAa,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,uCAAA,CAAyC,CAAA;AACvF,QAAA,IAAI;AACF,UAAA,IAAI,MAAA,CAAO,QAAQ,OAAO,CAAA;AAAA,QAC5B,CAAA,CAAA,MAAQ;AACN,UAAA,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,0CAAA,CAA4C,CAAA;AAAA,QAC/D;AAEA,QAAA,IAAI,CAAC,eAAe,OAAA,CAAQ,WAAW,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,mDAAA,CAAqD,CAAA;AAAA,MAClH;AAAA,IACF;AAEA,IAAA,IAAI,WAAA,CAAY,OAAO,CAAA,EAAG;AACxB,MAAA,IAAI,OAAO,IAAI,WAAA,KAAgB,UAAA,OAAiB,KAAA,EAAO,CAAA,WAAA,EAAc,CAAC,CAAA,wCAAA,CAA0C,CAAA;AAChH,MAAA,IAAI,OAAO,IAAI,YAAA,KAAiB,UAAA,OAAiB,KAAA,EAAO,CAAA,WAAA,EAAc,CAAC,CAAA,yCAAA,CAA2C,CAAA;AAAA,IACpH;AAIA,IAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,eAAA,CAAgB,GAAG,CAAC,CAAA;AAC3C,IAAA,MAAM,UAAA,uBAAiB,GAAA,EAAY;AACnC,IAAA,KAAA,MAAW,CAAC,GAAG,MAAM,CAAA,IAAA,CAAM,IAAI,SAAA,IAAa,EAAC,EAAG,OAAA,EAAQ,EAAG;AACzD,MAAA,MAAM,EAAA,GAAK,CAAA,WAAA,EAAc,CAAC,CAAA,YAAA,EAAe,CAAC,CAAA,CAAA,CAAA;AAC1C,MAAA,IAAI,CAAC,eAAe,MAAA,EAAQ,GAAG,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,+BAAA,CAAiC,CAAA;AACpF,MAAA,IAAI,CAAC,eAAe,MAAA,EAAQ,KAAK,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,iCAAA,CAAmC,CAAA;AACxF,MAAA,IAAI,UAAA,CAAW,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,EAAG,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,iBAAA,EAAoB,MAAA,CAAO,GAAG,CAAA,CAAA,CAAG,CAAA;AAClF,MAAA,UAAA,CAAW,GAAA,CAAI,OAAO,GAAG,CAAA;AACzB,MAAA,MAAM,KAAA,GAAQ,gBAAgB,MAAM,CAAA;AACpC,MAAA,IAAI,CAAC,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA,EAAG;AACtB,QAAA,IAAA,CAAK,OAAO,CAAA,EAAG,EAAE,uBAAuB,KAAK,CAAA,yBAAA,EAA4B,CAAC,CAAA,yBAAA,CAA2B,CAAA;AAAA,MACvG;AACA,MAAA,IAAI,MAAA,CAAO,YAAY,MAAA,EAAW;AAChC,QAAA,IAAI,UAAU,MAAA,EAAQ,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,sCAAA,CAAwC,CAAA;AAC/E,QAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,MAAA,CAAO,OAAO,CAAA,EAAG,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,sBAAA,EAAyB,MAAA,CAAO,OAAO,CAAA,CAAA,CAAG,CAAA;AAAA,MAChG;AAGA,MAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAA,CAAK,GAAA,CAAI,WAAA,IAAe,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,QAAQ,CAAC,CAAA;AACvE,MAAA,KAAA,MAAW,QAAA,IAAY,MAAA,CAAO,OAAA,IAAW,EAAC,EAAG;AAC3C,QAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,QAAQ,CAAA,EAAG;AAC3B,UAAA,IAAA;AAAA,YACE,KAAA;AAAA,YACA,CAAA,EAAG,EAAE,CAAA,gBAAA,EAAmB,QAAQ,uBAAuB,CAAC,CAAA,kGAAA;AAAA,WAE1D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,IAAA,KAAA,MAAW,CAAC,GAAG,IAAI,CAAA,IAAA,CAAM,IAAI,kBAAA,IAAsB,EAAC,EAAG,OAAA,EAAQ,EAAG;AAChE,MAAA,IAAI,CAAC,cAAA,CAAe,IAAA,EAAM,QAAQ,CAAA,EAAG,IAAA,CAAK,KAAA,EAAO,CAAA,WAAA,EAAc,CAAC,CAAA,qBAAA,EAAwB,CAAC,CAAA,qCAAA,CAAuC,CAAA;AAChI,MAAA,IAAI,CAAC,cAAA,CAAe,IAAA,EAAM,KAAK,CAAA,EAAG,IAAA,CAAK,KAAA,EAAO,CAAA,WAAA,EAAc,CAAC,CAAA,qBAAA,EAAwB,CAAC,CAAA,kCAAA,CAAoC,CAAA;AAE1H,MAAA,IAAI,CAAC,mBAAA,CAAoB,GAAA,EAAK,IAAA,CAAK,QAAQ,CAAA,EAAG;AAC5C,QAAA,IAAA,CAAK,KAAA,EAAO,cAAc,CAAC,CAAA,qBAAA,EAAwB,CAAC,CAAA,YAAA,EAAe,IAAA,CAAK,QAAQ,CAAA,uCAAA,CAAyC,CAAA;AAAA,MAC3H;AAAA,IACF;AAAA,EACF;AAGA,EAAA,KAAA,MAAW,CAAC,GAAG,GAAG,CAAA,IAAA,CAAM,SAAS,UAAA,IAAc,EAAC,EAAG,OAAA,EAAQ,EAAG;AAC5D,IAAA,KAAA,MAAW,KAAA,IAAS,sBAAA,CAAuB,GAAA,EAAK,GAAG,CAAA,EAAG;AACpD,MAAA,IAAA;AAAA,QACE,KAAA;AAAA,QACA,cAAc,CAAC,CAAA,IAAA,EAAO,KAAK,EAAA,IAAM,GAAG,qBAAqB,KAAK,CAAA,2PAAA;AAAA,OAIhE;AAAA,IACF;AAAA,EACF;AAIA,EAAA,IACE,SAAS,UAAA,CAAW,MAAA,KAAW,KAC/B,QAAA,CAAS,MAAA,CAAO,WAAW,CAAA,IAAA,CAC1B,QAAA,CAAS,YAAY,EAAC,EAAG,WAAW,CAAA,IAAA,CACpC,QAAA,CAAS,cAAc,EAAC,EAAG,WAAW,CAAA,EACvC;AACA,IAAA,IAAA,CAAK,OAAO,wGAAmG,CAAA;AAAA,EACjH;AACF;AA0BA,SAAS,0BAAA,CACP,KAAA,EACA,IAAA,EACA,GAAA,EACM;AACN,EAAA,MAAM,cAAc,GAAA,CAAI,WAAA;AACxB,EAAA,IAAI,gBAAgB,MAAA,EAAW;AAC/B,EAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,WAAW,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,IAAI,CAAA,6BAAA,CAA+B,CAAA;AAEnF,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,UAAU,CAAA,IAAK,WAAA,CAAY,SAAQ,EAAG;AACnD,IAAA,MAAM,EAAA,GAAK,CAAA,EAAG,IAAI,CAAA,aAAA,EAAgB,CAAC,CAAA,CAAA,CAAA;AACnC,IAAA,IAAI,UAAA,EAAY,IAAA,KAAS,MAAA,IAAU,UAAA,EAAY,SAAS,OAAA,EAAS;AAC/D,MAAA,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,+BAAA,CAAiC,CAAA;AAAA,IACpD;AACA,IAAA,IAAI,CAAC,eAAe,UAAA,CAAW,QAAQ,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,oCAAA,CAAsC,CAAA;AAGjG,IAAA,IAAI,CAAC,cAAA,CAAe,UAAA,CAAW,MAAM,CAAA,EAAG;AACtC,MAAA,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,+EAAA,CAA4E,CAAA;AAAA,IAC/F;AACA,IAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,UAAA,CAAW,OAAO,CAAA,IAAK,UAAA,CAAW,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG;AACzE,MAAA,IAAA,CAAK,KAAA,EAAO,CAAA,EAAG,EAAE,CAAA,2FAAA,CAAwF,CAAA;AAAA,IAC3G;AACA,IAAA,MAAM,KAAA,GAAQ,iBAAA,CAAkB,UAAA,CAAW,IAAI,CAAA;AAC/C,IAAA,KAAA,MAAW,MAAA,IAAU,WAAW,OAAA,EAAS;AACvC,MAAA,IAAI,CAAC,KAAA,CAAM,QAAA,CAAS,MAAM,CAAA,EAAG;AAC3B,QAAA,IAAA,CAAK,OAAO,CAAA,EAAG,EAAE,CAAA,WAAA,EAAc,MAAM,YAAY,UAAA,CAAW,IAAI,CAAA,WAAA,EAAc,UAAA,CAAW,QAAQ,CAAA,qBAAA,EAAwB,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,MAC7I;AAAA,IACF;AACA,IAAA,IAAI,iBAAA,CAAkB,UAAU,CAAA,IAAK,UAAA,CAAW,QAAA,CAAS,QAAA,CAAS,GAAG,CAAA,IAAK,CAAC,UAAA,CAAW,QAAA,CAAS,QAAA,CAAS,GAAG,CAAA,EAAG;AAC5G,MAAA,IAAA,CAAK,OAAO,CAAA,EAAG,EAAE,CAAA,WAAA,EAAc,UAAA,CAAW,QAAQ,CAAA,wCAAA,CAAqC,CAAA;AAAA,IACzF;AACA,IAAA,MAAM,MAAM,CAAA,EAAG,UAAA,CAAW,IAAI,CAAA,CAAA,EAAI,WAAW,QAAQ,CAAA,CAAA;AACrD,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG,IAAA,CAAK,OAAO,CAAA,EAAG,EAAE,CAAA,UAAA,EAAa,GAAG,CAAA,0CAAA,CAAuC,CAAA;AAC3F,IAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AAAA,EACd;AAGA,EAAA,IAAI,GAAA,CAAI,aAAa,MAAA,EAAW;AAC9B,IAAA,MAAM,WAAW,IAAI,GAAA,CAAI,kBAAkB,EAAE,WAAA,EAAa,CAAC,CAAA;AAC3D,IAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,GAAA,CAAI,QAAQ,CAAA;AACnC,IAAA,KAAA,MAAW,UAAU,QAAA,EAAU;AAC7B,MAAA,IAAI,CAAC,MAAA,CAAO,GAAA,CAAI,MAAM,CAAA,EAAG;AACvB,QAAA,IAAA;AAAA,UACE,KAAA;AAAA,UACA,CAAA,EAAG,IAAI,CAAA,sBAAA,EAAyB,MAAM,YAAY,IAAI,CAAA,0HAAA;AAAA,SAExD;AAAA,MACF;AAAA,IACF;AACA,IAAA,KAAA,MAAW,UAAU,MAAA,EAAQ;AAC3B,MAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,MAAM,CAAA,EAAG;AACzB,QAAA,IAAA;AAAA,UACE,KAAA;AAAA,UACA,CAAA,EAAG,IAAI,CAAA,iBAAA,EAAoB,MAAM,CAAA,0IAAA;AAAA,SAEnC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,EAAA,IAAI,GAAA,CAAI,iBAAiB,MAAA,EAAW;AAClC,IAAA,MAAM,WAAW,IAAI,GAAA,CAAI,sBAAsB,EAAE,WAAA,EAAa,CAAC,CAAA;AAC/D,IAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,GAAA,CAAI,YAAY,CAAA;AACvC,IAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,MAAA,IAAI,CAAC,MAAA,CAAO,GAAA,CAAI,OAAO,CAAA,EAAG;AACxB,QAAA,IAAA;AAAA,UACE,KAAA;AAAA,UACA,CAAA,EAAG,IAAI,CAAA,yBAAA,EAA4B,OAAO,YAAY,IAAI,CAAA,yHAAA;AAAA,SAE5D;AAAA,MACF;AAAA,IACF;AACA,IAAA,KAAA,MAAW,WAAW,MAAA,EAAQ;AAC5B,MAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,OAAO,CAAA,EAAG;AAC1B,QAAA,IAAA;AAAA,UACE,KAAA;AAAA,UACA,CAAA,EAAG,IAAI,CAAA,wBAAA,EAA2B,OAAO,CAAA,+GAAA;AAAA,SAE3C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAeA,IAAM,uBAAA,GACJ,gHAAA;AAGK,SAAS,uBAAuB,GAAA,EAAwB;AAC7D,EAAA,MAAM,IAAA,GAAO,OAAO,GAAA,KAAQ,QAAA,GAAW,IAAI,OAAA,CAAQ,IAAA,EAAM,EAAE,CAAA,GAAI,EAAA;AAC/D,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAY;AAC9B,EAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,uBAAuB,CAAA,EAAG,KAAA,CAAM,GAAA,CAAI,CAAA,CAAE,CAAC,CAAA,CAAE,WAAA,EAAa,CAAA;AACpF,EAAA,OAAO,CAAC,GAAG,KAAK,CAAA;AAClB;AAEA,IAAM,gCAAgB,IAAI,GAAA,CAAI,CAAC,SAAA,EAAW,SAAA,EAAW,SAAS,CAAC,CAAA;AAC/D,IAAM,mCAAmB,IAAI,GAAA,CAAI,CAAC,MAAA,EAAQ,MAAM,CAAC,CAAA;AACjD,IAAM,IAAA,GAAO,sBAAA;AACb,IAAM,WAAA,GAAc,mBAAA;AAEpB,IAAM,aAAA,uBAAoB,GAAA,CAAI,CAAC,QAAQ,QAAA,EAAU,cAAA,EAAgB,QAAQ,CAAC,CAAA;AAC1E,IAAM,6BAAa,IAAI,GAAA,CAAI,CAAC,OAAA,EAAS,SAAA,EAAW,MAAM,CAAC,CAAA;AACvD,IAAM,6BAAa,IAAI,GAAA,CAAI,CAAC,SAAA,EAAW,UAAA,EAAY,eAAe,CAAC,CAAA;AACnE,IAAM,QAAA,uBAAe,GAAA,CAAI,CAAC,YAAY,WAAA,EAAa,QAAA,EAAU,SAAS,CAAC,CAAA;AAQhE,SAAS,wBAAwB,SAAA,EAA4B;AAClE,EAAA,MAAM,KAAA,GAAQ,eAAe,SAAA,EAAW,EAAE,IAAI,CAAA,UAAA,EAAa,SAAA,CAAU,EAAE,CAAA,CAAA,GAAK,qBAAA;AAC5E,EAAA,KAAA,MAAW,KAAA,IAAS,CAAC,IAAA,EAAM,UAAA,EAAY,UAAU,CAAA,EAAY;AAC3D,IAAA,IAAI,CAAC,cAAA,CAAe,SAAA,GAAY,KAAK,CAAC,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,UAAA,EAAa,KAAK,CAAA,2BAAA,CAA6B,CAAA;AAAA,EACtG;AACA,EAAA,IAAI,CAAC,UAAA,CAAW,GAAA,CAAI,UAAU,QAAQ,CAAA,OAAQ,KAAA,EAAO,CAAA,oBAAA,EAAuB,UAAU,QAAQ,CAAA,gBAAA,EAAmB,CAAC,GAAG,UAAU,EAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAC7I,EAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,SAAA,CAAU,YAAY,CAAA,IAAK,SAAA,CAAU,YAAA,CAAa,MAAA,KAAW,CAAA,EAAG;AACjF,IAAA,IAAA,CAAK,OAAO,0DAA0D,CAAA;AAAA,EACxE;AACA,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,GAAG,KAAK,SAAA,CAAU,YAAA,CAAa,SAAQ,EAAG;AACvD,IAAA,IAAI,CAAC,eAAe,GAAA,EAAK,MAAM,GAAG,IAAA,CAAK,KAAA,EAAO,CAAA,aAAA,EAAgB,CAAC,CAAA,mCAAA,CAAqC,CAAA;AACpG,IAAA,IAAI,CAAC,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,SAAS,CAAA,EAAG,IAAA,CAAK,KAAA,EAAO,CAAA,aAAA,EAAgB,CAAC,CAAA,aAAA,EAAgB,GAAA,CAAI,SAAS,CAAA,YAAA,CAAc,CAAA;AAC5G,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA,IAAK,GAAA,CAAI,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG,IAAA,CAAK,KAAA,EAAO,CAAA,aAAA,EAAgB,CAAC,CAAA,4BAAA,CAA8B,CAAA;AAC1H,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAI,QAAA,EAAU;AAC/B,MAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA,EAAG,IAAA,CAAK,KAAA,EAAO,CAAA,aAAA,EAAgB,CAAC,CAAA,uBAAA,EAA0B,IAAI,CAAA,CAAA,CAAG,CAAA;AAAA,IACzF;AAAA,EACF;AACF","file":"chunk-37YMNSAI.js","sourcesContent":["// ---------------------------------------------------------------------------\n// Plugin contract assertions — the integrity half of the deploy gate.\n// ---------------------------------------------------------------------------\n// Framework-agnostic runtime checks (no test-runner dependency) that any\n// plugin's *.test.ts calls to prove its manifest/connector conform to the\n// platform contract BEFORE it can ship. A plugin that fails these would break\n// the host app at mount time (missing route component, duplicate ids, malformed\n// settings tab). Pair with a capability test (does the plugin do its job?) — see\n// docs/plugins/PLUGIN-PATTERNS.md → capability anatomy. These throw on the first violation.\nimport { errorMessage } from './lib/error-message'\nimport type { PluginManifest } from './types/plugins'\nimport type { Connector } from './integrations'\nimport {\n CONNECTOR_CATEGORIES,\n connectorEntities,\n connectorPlanes,\n connectorSubscribes,\n connectorSubscribesTo,\n grants,\n invocationPlane,\n isConnectorCategory,\n isEventPermission,\n permissionActions,\n requestPlaneSpec,\n} from './integrations'\nimport type { ConnectorPermission } from './integrations'\n\nexport class PluginContractError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'PluginContractError'\n }\n}\n\nfunction fail(scope: string, msg: string): never {\n throw new PluginContractError(`[${scope}] ${msg}`)\n}\n\nfunction nonEmptyString(v: unknown): v is string {\n return typeof v === 'string' && v.trim().length > 0\n}\n\n/**\n * Assert a PluginManifest is structurally sound enough to mount safely.\n * Checks identity, navigation/route wiring, settings tabs, declared features,\n * and id uniqueness. Throws PluginContractError on the first problem.\n */\nexport function assertPluginManifestContract(manifest: PluginManifest): void {\n const id = manifest?.id\n const scope = nonEmptyString(id) ? id : '<unknown plugin>'\n\n for (const field of ['id', 'name', 'icon', 'version'] as const) {\n if (!nonEmptyString(manifest?.[field])) fail(scope, `manifest.${field} must be a non-empty string`)\n }\n\n if (!Array.isArray(manifest.navigation)) fail(scope, 'manifest.navigation must be an array (use [] for settings-only plugins)')\n if (!Array.isArray(manifest.routes)) fail(scope, 'manifest.routes must be an array (use [] for settings-only plugins)')\n\n // Every nav entry must point at a route; every route needs a path + component.\n for (const [i, nav] of manifest.navigation.entries()) {\n if (!nonEmptyString((nav as any)?.route)) fail(scope, `navigation[${i}].route must be a non-empty string`)\n }\n const routePaths = new Set<string>()\n for (const [i, route] of manifest.routes.entries()) {\n if (!nonEmptyString((route as any)?.path)) fail(scope, `routes[${i}].path must be a non-empty string`)\n if (typeof (route as any)?.component !== 'function') fail(scope, `routes[${i}].component must be a component`)\n if (routePaths.has((route as any).path)) fail(scope, `duplicate route path \"${(route as any).path}\"`)\n routePaths.add((route as any).path)\n }\n // A nav entry that links to a route the plugin doesn't declare is dead UI.\n for (const [i, nav] of manifest.navigation.entries()) {\n const r = (nav as any).route\n if (routePaths.size > 0 && !routePaths.has(r)) {\n fail(scope, `navigation[${i}].route \"${r}\" has no matching route in manifest.routes`)\n }\n }\n\n // Settings tabs (the only UI surface integrations need) must be renderable.\n const settingIds = new Set<string>()\n for (const [i, tab] of (manifest.settings ?? []).entries()) {\n if (!nonEmptyString((tab as any)?.id)) fail(scope, `settings[${i}].id must be a non-empty string`)\n if (!nonEmptyString((tab as any)?.label)) fail(scope, `settings[${i}].label must be a non-empty string`)\n if (typeof (tab as any)?.component !== 'function') fail(scope, `settings[${i}].component must be a component`)\n if (settingIds.has((tab as any).id)) fail(scope, `duplicate settings tab id \"${(tab as any).id}\"`)\n settingIds.add((tab as any).id)\n }\n\n for (const [i, feat] of (manifest.declaredFeatures ?? []).entries()) {\n if (!nonEmptyString((feat as any)?.id)) fail(scope, `declaredFeatures[${i}].id must be a non-empty string`)\n }\n\n for (const [i, src] of (manifest.emitsFrom ?? []).entries()) {\n if (!nonEmptyString(src?.table)) fail(scope, `emitsFrom[${i}].table must be a non-empty string`)\n if (!nonEmptyString(src?.entityKey)) fail(scope, `emitsFrom[${i}].entityKey must be a non-empty string`)\n for (const action of src.actions ?? []) {\n if (!EVENT_ACTIONS.has(action)) fail(scope, `emitsFrom[${i}] has unknown action \"${action}\"`)\n }\n }\n\n const functionSlugs = new Set<string>()\n for (const [i, fn] of (manifest.functions ?? []).entries()) {\n if (!SLUG.test(fn?.slug ?? '')) fail(scope, `functions[${i}].slug must be kebab-case — it becomes the deployed function name`)\n if (functionSlugs.has(fn.slug)) fail(scope, `duplicate function slug \"${fn.slug}\"`)\n functionSlugs.add(fn.slug)\n if (typeof fn.verifyJwt !== 'boolean') fail(scope, `functions[${i}].verifyJwt must be a boolean`)\n if (!FUNCTION_INGRESS.has(fn.ingress)) fail(scope, `functions[${i}].ingress \"${fn.ingress}\" is not one of ${[...FUNCTION_INGRESS].join(', ')}`)\n // The ingress authenticates by signature, not by a caller JWT it does not have.\n if (fn.ingress === 'fayz' && fn.verifyJwt) fail(scope, `functions[${i}] is reached through the Fayz ingress, so verifyJwt must be false`)\n for (const secret of fn.secrets ?? []) {\n // A name, never a value — this is the shape that keeps a key out of git.\n if (!SECRET_NAME.test(secret)) fail(scope, `functions[${i}].secrets must name secrets (SCREAMING_SNAKE_CASE), never carry their values`)\n }\n }\n\n for (const [i, def] of (manifest.connectors ?? []).entries()) {\n // An unlisted category renders NO badge rather than a wrong one, so the\n // mistake is invisible in a screenshot. Caught here instead.\n if (def.category !== undefined && !isConnectorCategory(def.category)) {\n fail(\n scope,\n `connectors[${i}].category \"${def.category}\" is not a catalogue category — ` +\n `use one of ${CONNECTOR_CATEGORIES.join(', ')}, taken from the catalogue row with this connector's slug.`,\n )\n }\n for (const pattern of def.subscribesTo ?? []) {\n if (!nonEmptyString(pattern)) fail(scope, `connectors[${i}].subscribesTo must hold non-empty patterns`)\n // Only a trailing star is honoured; see eventKeyMatches.\n if (pattern.includes('*') && !pattern.endsWith('*')) {\n fail(scope, `connectors[${i}].subscribesTo \"${pattern}\" — \"*\" is only honoured at the end`)\n }\n }\n\n assertConnectorPermissions(scope, `connectors[${i}]`, def)\n // The request plane's two fields are required THERE and meaningless\n // elsewhere. Checked at the manifest so a connector cannot reach a buyer\n // with an undeclared budget — the failure would otherwise be a spinner.\n if ((def.planes ?? []).includes('request')) {\n try {\n requestPlaneSpec(def)\n } catch (error) {\n fail(scope, `connectors[${i}] ${errorMessage(error)}`)\n }\n } else if (def.latencyBudgetMs !== undefined || def.onFailure !== undefined) {\n fail(\n scope,\n `connectors[${i}] declares latencyBudgetMs/onFailure but is not on the request plane — ` +\n `nothing enforces them, so they read as a guarantee that does not exist.`,\n )\n }\n // Authorization vs configuration. Both declarations end up on the same row,\n // and a key in both is a value with two owners: the connect form would write\n // it and the settings form would overwrite it.\n const fieldKeys = new Set((def.fields ?? []).map((f) => f.key))\n const settingKeys = new Set<string>()\n for (const [j, setting] of (def.settings ?? []).entries()) {\n const at = `connectors[${i}].settings[${j}]`\n if (!nonEmptyString(setting?.key)) fail(scope, `${at}.key must be a non-empty string`)\n if (!nonEmptyString(setting?.label)) fail(scope, `${at}.label must be a non-empty string`)\n if (!SETTING_TYPES.has(setting.type)) {\n fail(scope, `${at}.type \"${setting.type}\" is not one of ${[...SETTING_TYPES].join(', ')}`)\n }\n if (settingKeys.has(setting.key)) fail(scope, `${at} duplicates settings key \"${setting.key}\"`)\n settingKeys.add(setting.key)\n if (fieldKeys.has(setting.key)) {\n fail(\n scope,\n `${at}.key \"${setting.key}\" is also a credential field — a key either authorizes the ` +\n `connection (fields) or configures it (settings), never both.`,\n )\n }\n if (setting.type === 'select' || setting.type === 'multi-select') {\n if (!Array.isArray(setting.options) || setting.options.length === 0) {\n fail(scope, `${at} is a ${setting.type} and must declare options — that is what replaces a free-text box`)\n }\n for (const [k, option] of setting.options.entries()) {\n if (!nonEmptyString(option?.value)) fail(scope, `${at}.options[${k}].value must be a non-empty string`)\n if (!nonEmptyString(option?.label)) fail(scope, `${at}.options[${k}].label must be a non-empty string`)\n }\n }\n if (setting.pattern !== undefined) {\n if (setting.type !== 'text') fail(scope, `${at}.pattern only applies to a text setting`)\n try {\n new RegExp(setting.pattern)\n } catch {\n fail(scope, `${at}.pattern is not a valid regular expression`)\n }\n // A refusal with no sentence is a form that says no and not why.\n if (!nonEmptyString(setting.patternHint)) fail(scope, `${at} declares a pattern, so it must declare patternHint`)\n }\n }\n // Declared settings nobody can read or write are a screen that renders empty.\n if (settingKeys.size > 0) {\n if (typeof def.getSettings !== 'function') fail(scope, `connectors[${i}] declares settings but no getSettings()`)\n if (typeof def.saveSettings !== 'function') fail(scope, `connectors[${i}] declares settings but no saveSettings()`)\n }\n\n // \"Acionado em quais momentos\" — a moment on a plane the connector does not\n // have is a promise the code cannot keep.\n const planes = new Set(connectorPlanes(def))\n const momentKeys = new Set<string>()\n for (const [j, moment] of (def.invokedAt ?? []).entries()) {\n const at = `connectors[${i}].invokedAt[${j}]`\n if (!nonEmptyString(moment?.key)) fail(scope, `${at}.key must be a non-empty string`)\n if (!nonEmptyString(moment?.label)) fail(scope, `${at}.label must be a non-empty string`)\n if (momentKeys.has(moment.key)) fail(scope, `${at} duplicates key \"${moment.key}\"`)\n momentKeys.add(moment.key)\n const plane = invocationPlane(moment)\n if (!planes.has(plane)) {\n fail(scope, `${at} is declared on the ${plane} plane, which connectors[${i}].planes does not include`)\n }\n if (moment.trigger !== undefined) {\n if (plane !== 'sync') fail(scope, `${at}.trigger only applies to a sync moment`)\n if (!TRIGGERS.has(moment.trigger)) fail(scope, `${at} has unknown trigger \"${moment.trigger}\"`)\n }\n // A moment that reaches something the connector never asked for is the\n // screen answering \"quando ele age\" with access nobody consented to.\n const declared = new Set((def.permissions ?? []).map((p) => p.resource))\n for (const resource of moment.touches ?? []) {\n if (!declared.has(resource)) {\n fail(\n scope,\n `${at}.touches names \"${resource}\", which connectors[${i}].permissions does not declare — ` +\n `a call site cannot reach what the consent view never showed.`,\n )\n }\n }\n }\n\n for (const [j, auto] of (def.managedAutomations ?? []).entries()) {\n if (!nonEmptyString(auto?.eventKey)) fail(scope, `connectors[${i}].managedAutomations[${j}].eventKey must be a non-empty string`)\n if (!nonEmptyString(auto?.label)) fail(scope, `connectors[${i}].managedAutomations[${j}].label must be a non-empty string`)\n // The screen would promise a reaction the ingress never delivers.\n if (!connectorSubscribes(def, auto.eventKey)) {\n fail(scope, `connectors[${i}].managedAutomations[${j}] fires on \"${auto.eventKey}\", which no subscribesTo pattern covers`)\n }\n }\n }\n\n // A connector brings a ConnectorDefinition, not a pair of tables.\n for (const [i, mig] of (manifest.migrations ?? []).entries()) {\n for (const table of bespokeConnectorTables(mig?.sql)) {\n fail(\n scope,\n `migrations[${i}] (\"${mig?.id ?? '?'}\") creates public.${table} — a connector's own ` +\n `*_integrations / *_sync_log table. Store the connection in connections / ` +\n `sync_runs via createConnectionStore('<connector-id>'): two accounts are two ` +\n `rows separated by instance_key, and connector-specific counters go in stats.`,\n )\n }\n }\n\n // A plugin that contributes nothing mountable is almost always a mistake.\n // (Connector-only addon plugins contribute via `connectors` instead.)\n if (\n manifest.navigation.length === 0 &&\n manifest.routes.length === 0 &&\n (manifest.settings ?? []).length === 0 &&\n (manifest.connectors ?? []).length === 0\n ) {\n fail(scope, 'plugin contributes no navigation, routes, settings, or connectors — it would mount but do nothing')\n }\n}\n\n/**\n * What a connector says it needs — and the four ways that declaration can\n * contradict the ones that already existed.\n *\n * The feature this guards is a consent view. Its whole value is that the list it\n * shows is the list, so every way of ending up with two lists is refused here:\n *\n * 1. an action that does not exist for the resource kind (`listen` on a\n * record type, `write` on an event) — a word the reader would have to guess at;\n * 2. a `data` permission naming a resource the legacy `entities` never listed,\n * or an entity with no permission — the \"writes to an entity it never\n * listed\" case, in both directions;\n * 3. a `listen` permission the legacy `subscribesTo` does not name, or a\n * `subscribesTo` pattern no permission explains — the connector would be\n * delivered facts the consent view never showed, or shown facts the ingress\n * filters out;\n * 4. two permissions for the same resource — two rows, two reasons, and no\n * answer to which one the tenant agreed to.\n *\n * Rules 2 and 3 only bite when BOTH declarations are present. A connector built\n * against an older core declares only the legacy fields and is unaffected; a\n * connector written today declares only `permissions` and both are derived from\n * it. What is refused is saying both things and saying them differently.\n */\nfunction assertConnectorPermissions(\n scope: string,\n path: string,\n def: { permissions?: ConnectorPermission[]; entities?: string[]; subscribesTo?: string[] },\n): void {\n const permissions = def.permissions\n if (permissions === undefined) return\n if (!Array.isArray(permissions)) fail(scope, `${path}.permissions must be an array`)\n\n const seen = new Set<string>()\n for (const [j, permission] of permissions.entries()) {\n const at = `${path}.permissions[${j}]`\n if (permission?.kind !== 'data' && permission?.kind !== 'event') {\n fail(scope, `${at}.kind must be \"data\" or \"event\"`)\n }\n if (!nonEmptyString(permission.resource)) fail(scope, `${at}.resource must be a non-empty string`)\n // The reason is the only part a tenant can actually judge; a blank one turns\n // the screen back into the schema dump it exists to replace.\n if (!nonEmptyString(permission.reason)) {\n fail(scope, `${at} must declare a reason — the sentence the tenant judges before authorizing`)\n }\n if (!Array.isArray(permission.actions) || permission.actions.length === 0) {\n fail(scope, `${at}.actions must name at least one action — a resource with no access is not a permission`)\n }\n const legal = permissionActions(permission.kind)\n for (const action of permission.actions) {\n if (!legal.includes(action)) {\n fail(scope, `${at} asks for \"${action}\" on the ${permission.kind} resource \"${permission.resource}\", which only admits ${legal.join(', ')}`)\n }\n }\n if (isEventPermission(permission) && permission.resource.includes('*') && !permission.resource.endsWith('*')) {\n fail(scope, `${at}.resource \"${permission.resource}\" — \"*\" is only honoured at the end`)\n }\n const key = `${permission.kind}:${permission.resource}`\n if (seen.has(key)) fail(scope, `${at} repeats \"${key}\" — one resource, one row, one reason`)\n seen.add(key)\n }\n\n // (2) data permissions ↔ the legacy entities list.\n if (def.entities !== undefined) {\n const declared = new Set(connectorEntities({ permissions }))\n const legacy = new Set(def.entities)\n for (const entity of declared) {\n if (!legacy.has(entity)) {\n fail(\n scope,\n `${path}.permissions reaches \"${entity}\", which ${path}.entities does not list — ` +\n `the two describe the same access and must name the same set (drop entities; it is derived).`,\n )\n }\n }\n for (const entity of legacy) {\n if (!declared.has(entity)) {\n fail(\n scope,\n `${path}.entities lists \"${entity}\" with no permission saying what it does with it — ` +\n `a record type on the consent view with no read/write is a name, not a declaration.`,\n )\n }\n }\n }\n\n // (3) listen permissions ↔ the legacy subscribesTo list.\n if (def.subscribesTo !== undefined) {\n const declared = new Set(connectorSubscribesTo({ permissions }))\n const legacy = new Set(def.subscribesTo)\n for (const pattern of declared) {\n if (!legacy.has(pattern)) {\n fail(\n scope,\n `${path}.permissions listens to \"${pattern}\", which ${path}.subscribesTo does not — ` +\n `the ingress filters on that list, so the consent view would promise a fact never delivered.`,\n )\n }\n }\n for (const pattern of legacy) {\n if (!declared.has(pattern)) {\n fail(\n scope,\n `${path}.subscribesTo asks for \"${pattern}\" with no listen permission explaining it — ` +\n `the connector would receive a fact the tenant was never shown.`,\n )\n }\n }\n }\n}\n\n/**\n * `CREATE TABLE [IF NOT EXISTS] [schema.]name` where name ends in `_integrations`\n * or `_sync_log` — the pair four connectors each reinvented before\n * `connections` / `sync_runs` existed (FAY-1376). Neither generic table\n * matches, so a connector that stores its connection in them creates nothing.\n *\n * Deliberately duplicated in scripts/check-connector-tables.mjs, which scans the\n * .sql files themselves: that runs in the `contracts` CI job with no install and\n * no build, so it cannot import this. This half catches SQL declared inline on a\n * manifest, which no .sql walk would see. The two are held in agreement by one\n * case table, asserted from both sides — see\n * packages/core/test/integrations/connector-tables.test.ts.\n */\nconst BESPOKE_CONNECTOR_TABLE =\n /\\bcreate\\s+table\\s+(?:if\\s+not\\s+exists\\s+)?(?:[a-z0-9_]+\\s*\\.\\s*)?([a-z0-9_]*(?:_integrations|_sync_log))\\b/gi\n\n/** Table names a CREATE TABLE in this SQL would bring back. Empty = conformant. */\nexport function bespokeConnectorTables(sql: unknown): string[] {\n const text = typeof sql === 'string' ? sql.replace(/\"/g, '') : ''\n const found = new Set<string>()\n for (const m of text.matchAll(BESPOKE_CONNECTOR_TABLE)) found.add(m[1].toLowerCase())\n return [...found]\n}\n\nconst EVENT_ACTIONS = new Set(['created', 'updated', 'deleted'])\nconst FUNCTION_INGRESS = new Set(['fayz', 'none'])\nconst SLUG = /^[a-z0-9][a-z0-9-]*$/\nconst SECRET_NAME = /^[A-Z][A-Z0-9_]*$/\n\nconst SETTING_TYPES = new Set(['text', 'select', 'multi-select', 'toggle'])\nconst AUTH_KINDS = new Set(['oauth', 'api-key', 'mtls'])\nconst DIRECTIONS = new Set(['inbound', 'outbound', 'bidirectional'])\nconst TRIGGERS = new Set(['on-write', 'scheduled', 'manual', 'webhook'])\n\n/**\n * Assert an integration Connector descriptor is well-formed: identity present,\n * a known auth kind, and at least one capability with a valid direction +\n * trigger set. This is the contract a connector must satisfy BEFORE its\n * data-plane (edge function) exists — the TDD anchor for an integration.\n */\nexport function assertConnectorContract(connector: Connector): void {\n const scope = nonEmptyString(connector?.id) ? `connector:${connector.id}` : '<unknown connector>'\n for (const field of ['id', 'provider', 'pluginId'] as const) {\n if (!nonEmptyString(connector?.[field])) fail(scope, `connector.${field} must be a non-empty string`)\n }\n if (!AUTH_KINDS.has(connector.authKind)) fail(scope, `connector.authKind \"${connector.authKind}\" is not one of ${[...AUTH_KINDS].join(', ')}`)\n if (!Array.isArray(connector.capabilities) || connector.capabilities.length === 0) {\n fail(scope, 'connector.capabilities must list at least one capability')\n }\n for (const [i, cap] of connector.capabilities.entries()) {\n if (!nonEmptyString(cap?.entity)) fail(scope, `capabilities[${i}].entity must be a non-empty string`)\n if (!DIRECTIONS.has(cap.direction)) fail(scope, `capabilities[${i}].direction \"${cap.direction}\" is invalid`)\n if (!Array.isArray(cap.triggers) || cap.triggers.length === 0) fail(scope, `capabilities[${i}].triggers must be non-empty`)\n for (const trig of cap.triggers) {\n if (!TRIGGERS.has(trig)) fail(scope, `capabilities[${i}] has unknown trigger \"${trig}\"`)\n }\n }\n}\n"]}
@@ -1630,7 +1630,7 @@ var coreTranslations = {
1630
1630
  "connectors.emptyTitle": "No connectors",
1631
1631
  "connectors.emptyBody": "Connect a provider, or authorize an external assistant, and it shows up here.",
1632
1632
  "connectors.noProject": "Connectors unavailable",
1633
- "connectors.noProjectBody": "This app is not linked to a Fayz project.",
1633
+ "connectors.noProjectBody": "The assistant is not set up in this app.",
1634
1634
  "connectors.noOrg": "No organization",
1635
1635
  "connectors.noOrgBody": "Pick an organization to see its connections.",
1636
1636
  "connectors.credentials.held": "The key goes to Fayz, encrypted. It is never stored in this app\u2019s database.",
@@ -1734,6 +1734,7 @@ var coreTranslations = {
1734
1734
  "settings.security": "Security",
1735
1735
  "settings.sites": "Sites",
1736
1736
  "settings.team": "Team",
1737
+ "settings.connectors": "Connectors",
1737
1738
  "settings.billing": "Billing",
1738
1739
  "settings.locations": "Companies",
1739
1740
  "billing.title": "Plans & Billing",
@@ -1942,7 +1943,7 @@ var coreTranslations = {
1942
1943
  "connectors.emptyTitle": "Nenhum conector",
1943
1944
  "connectors.emptyBody": "Conecte um provedor, ou autorize um assistente externo, e ele aparece aqui.",
1944
1945
  "connectors.noProject": "Conectores indispon\xEDveis",
1945
- "connectors.noProjectBody": "Este app n\xE3o est\xE1 ligado a um projeto Fayz.",
1946
+ "connectors.noProjectBody": "O assistente n\xE3o est\xE1 configurado neste app.",
1946
1947
  "connectors.noOrg": "Sem organiza\xE7\xE3o",
1947
1948
  "connectors.noOrgBody": "Escolha uma organiza\xE7\xE3o para ver as conex\xF5es dela.",
1948
1949
  "connectors.credentials.held": "A chave vai criptografada para o Fayz. Ela nunca fica no banco de dados deste app.",
@@ -2034,6 +2035,7 @@ var coreTranslations = {
2034
2035
  "settings.security": "Seguran\xE7a",
2035
2036
  "settings.sites": "Sites",
2036
2037
  "settings.team": "Equipe",
2038
+ "settings.connectors": "Conectores",
2037
2039
  "settings.billing": "Faturamento",
2038
2040
  "settings.locations": "Empresas",
2039
2041
  "billing.title": "Planos e Faturamento",
@@ -2083,5 +2085,5 @@ function preloadLocale(locale) {
2083
2085
  }
2084
2086
 
2085
2087
  export { I18nProvider, coreTranslations, getCurrentLocale, mergeTranslations, preloadLocale, registerTranslations, resolveLocale, setCurrentLocale, setLocaleStore, tl, useI18nConfig, useTranslation };
2086
- //# sourceMappingURL=chunk-F4TZJHLH.js.map
2087
- //# sourceMappingURL=chunk-F4TZJHLH.js.map
2088
+ //# sourceMappingURL=chunk-3Q7EFWGY.js.map
2089
+ //# sourceMappingURL=chunk-3Q7EFWGY.js.map