@querypanel/node-sdk 1.0.28 → 1.0.29

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 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils/clickhouse.ts","../src/adapters/clickhouse.ts","../src/adapters/postgres.ts","../node_modules/jose/dist/webapi/lib/buffer_utils.js","../node_modules/jose/dist/webapi/lib/base64.js","../node_modules/jose/dist/webapi/util/base64url.js","../node_modules/jose/dist/webapi/util/errors.js","../node_modules/jose/dist/webapi/lib/crypto_key.js","../node_modules/jose/dist/webapi/lib/invalid_key_input.js","../node_modules/jose/dist/webapi/lib/is_key_like.js","../node_modules/jose/dist/webapi/lib/is_disjoint.js","../node_modules/jose/dist/webapi/lib/is_object.js","../node_modules/jose/dist/webapi/lib/check_key_length.js","../node_modules/jose/dist/webapi/lib/asn1.js","../node_modules/jose/dist/webapi/lib/jwk_to_key.js","../node_modules/jose/dist/webapi/key/import.js","../node_modules/jose/dist/webapi/lib/validate_crit.js","../node_modules/jose/dist/webapi/lib/is_jwk.js","../node_modules/jose/dist/webapi/lib/normalize_key.js","../node_modules/jose/dist/webapi/lib/check_key_type.js","../node_modules/jose/dist/webapi/lib/subtle_dsa.js","../node_modules/jose/dist/webapi/lib/get_sign_verify_key.js","../node_modules/jose/dist/webapi/lib/jwt_claims_set.js","../node_modules/jose/dist/webapi/lib/sign.js","../node_modules/jose/dist/webapi/jws/flattened/sign.js","../node_modules/jose/dist/webapi/jws/compact/sign.js","../node_modules/jose/dist/webapi/jwt/sign.js","../src/core/client.ts","../src/core/query-engine.ts","../src/routes/charts.ts","../src/routes/active-charts.ts","../src/routes/ingest.ts","../src/routes/query.ts"],"sourcesContent":["import {\n\tClickHouseAdapter,\n\ttype ClickHouseAdapterOptions,\n\ttype ClickHouseClientFn,\n} from \"./adapters/clickhouse\";\nimport {\n\tPostgresAdapter,\n\ttype PostgresAdapterOptions,\n\ttype PostgresClientFn,\n} from \"./adapters/postgres\";\nimport type { DatabaseAdapter, DatabaseDialect } from \"./adapters/types\";\nimport { ApiClient } from \"./core/client\";\nimport { type DatabaseMetadata, QueryEngine } from \"./core/query-engine\";\nimport * as activeChartsRoute from \"./routes/active-charts\";\nimport * as chartsRoute from \"./routes/charts\";\nimport * as ingestRoute from \"./routes/ingest\";\nimport * as queryRoute from \"./routes/query\";\nimport type { SchemaIntrospection } from \"./schema/types\";\n\n// Re-export all public types\nexport { ClickHouseAdapter, PostgresAdapter };\n\nexport type {\n\tClickHouseAdapterOptions,\n\tClickHouseClientFn,\n\tDatabaseAdapter,\n\tDatabaseDialect,\n\tPostgresAdapterOptions,\n\tPostgresClientFn,\n\tSchemaIntrospection,\n};\n\n// Re-export from query-engine\nexport type { ParamRecord, ParamValue } from \"./core/query-engine\";\nexport type {\n\tActiveChartCreateInput,\n\tActiveChartListOptions,\n\tActiveChartUpdateInput,\n\tSdkActiveChart,\n} from \"./routes/active-charts\";\n\nexport type {\n\tChartCreateInput,\n\tChartListOptions,\n\tChartUpdateInput,\n\tPaginatedResponse,\n\tPaginationInfo,\n\tPaginationQuery,\n\tSdkChart,\n} from \"./routes/charts\";\n// Re-export route types\nexport type {\n\tIngestResponse,\n\tSchemaSyncOptions,\n} from \"./routes/ingest\";\nexport type {\n\tAskOptions,\n\tAskResponse,\n\tChartEnvelope,\n\tContextDocument,\n} from \"./routes/query\";\n\n// Re-export anonymizeResults utility\nexport { anonymizeResults } from \"./routes/query\";\n\n/**\n * Main SDK class - Thin orchestrator\n * Delegates to deep modules (ApiClient, QueryEngine, route modules)\n * Following Ousterhout's principle: \"Simple interface hiding complexity\"\n */\nexport class QueryPanelSdkAPI {\n\tprivate readonly client: ApiClient;\n\tprivate readonly queryEngine: QueryEngine;\n\n\tconstructor(\n\t\tbaseUrl: string,\n\t\tprivateKey: string,\n\t\torganizationId: string,\n\t\toptions?: {\n\t\t\tdefaultTenantId?: string;\n\t\t\tadditionalHeaders?: Record<string, string>;\n\t\t\tfetch?: typeof fetch;\n\t\t},\n\t) {\n\t\tthis.client = new ApiClient(baseUrl, privateKey, organizationId, options);\n\t\tthis.queryEngine = new QueryEngine();\n\t}\n\n\t// Database attachment methods\n\n\tattachClickhouse(\n\t\tname: string,\n\t\tclientFn: ClickHouseClientFn,\n\t\toptions?: ClickHouseAdapterOptions & {\n\t\t\tdescription?: string;\n\t\t\ttags?: string[];\n\t\t\ttenantFieldName?: string;\n\t\t\ttenantFieldType?: string;\n\t\t\tenforceTenantIsolation?: boolean;\n\t\t},\n\t): void {\n\t\tconst adapter = new ClickHouseAdapter(clientFn, options);\n\n\t\tconst metadata: DatabaseMetadata = {\n\t\t\tname,\n\t\t\tdialect: \"clickhouse\",\n\t\t\tdescription: options?.description,\n\t\t\ttags: options?.tags,\n\t\t\ttenantFieldName: options?.tenantFieldName,\n\t\t\ttenantFieldType: options?.tenantFieldType ?? \"String\",\n\t\t\tenforceTenantIsolation: options?.tenantFieldName\n\t\t\t\t? (options?.enforceTenantIsolation ?? true)\n\t\t\t\t: undefined,\n\t\t};\n\n\t\tthis.queryEngine.attachDatabase(name, adapter, metadata);\n\t}\n\n\tattachPostgres(\n\t\tname: string,\n\t\tclientFn: PostgresClientFn,\n\t\toptions?: PostgresAdapterOptions & {\n\t\t\tdescription?: string;\n\t\t\ttags?: string[];\n\t\t\ttenantFieldName?: string;\n\t\t\tenforceTenantIsolation?: boolean;\n\t\t},\n\t): void {\n\t\tconst adapter = new PostgresAdapter(clientFn, options);\n\n\t\tconst metadata: DatabaseMetadata = {\n\t\t\tname,\n\t\t\tdialect: \"postgres\",\n\t\t\tdescription: options?.description,\n\t\t\ttags: options?.tags,\n\t\t\ttenantFieldName: options?.tenantFieldName,\n\t\t\tenforceTenantIsolation: options?.tenantFieldName\n\t\t\t\t? (options?.enforceTenantIsolation ?? true)\n\t\t\t\t: undefined,\n\t\t};\n\n\t\tthis.queryEngine.attachDatabase(name, adapter, metadata);\n\t}\n\n\tattachDatabase(name: string, adapter: DatabaseAdapter): void {\n\t\tconst metadata: DatabaseMetadata = {\n\t\t\tname,\n\t\t\tdialect: adapter.getDialect(),\n\t\t};\n\t\tthis.queryEngine.attachDatabase(name, adapter, metadata);\n\t}\n\n\t// Schema introspection and sync\n\n\tasync introspect(\n\t\tdatabaseName: string,\n\t\ttables?: string[],\n\t): Promise<SchemaIntrospection> {\n\t\tconst adapter = this.queryEngine.getDatabase(databaseName);\n\t\treturn await adapter.introspect(tables ? { tables } : undefined);\n\t}\n\n\tasync syncSchema(\n\t\tdatabaseName: string,\n\t\toptions: ingestRoute.SchemaSyncOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<ingestRoute.IngestResponse> {\n\t\treturn await ingestRoute.syncSchema(\n\t\t\tthis.client,\n\t\t\tthis.queryEngine,\n\t\t\tdatabaseName,\n\t\t\toptions,\n\t\t\tsignal,\n\t\t);\n\t}\n\n\t// Natural language query\n\n\tasync ask(\n\t\tquestion: string,\n\t\toptions: queryRoute.AskOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<queryRoute.AskResponse> {\n\t\treturn await queryRoute.ask(\n\t\t\tthis.client,\n\t\t\tthis.queryEngine,\n\t\t\tquestion,\n\t\t\toptions,\n\t\t\tsignal,\n\t\t);\n\t}\n\n\t// Chart CRUD operations\n\n\tasync createChart(\n\t\tbody: chartsRoute.ChartCreateInput,\n\t\toptions?: { tenantId?: string; userId?: string; scopes?: string[] },\n\t\tsignal?: AbortSignal,\n\t): Promise<chartsRoute.SdkChart> {\n\t\treturn await chartsRoute.createChart(this.client, body, options, signal);\n\t}\n\n\tasync listCharts(\n\t\toptions?: chartsRoute.ChartListOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<chartsRoute.PaginatedResponse<chartsRoute.SdkChart>> {\n\t\treturn await chartsRoute.listCharts(\n\t\t\tthis.client,\n\t\t\tthis.queryEngine,\n\t\t\toptions,\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tasync getChart(\n\t\tid: string,\n\t\toptions?: { tenantId?: string; userId?: string; scopes?: string[] },\n\t\tsignal?: AbortSignal,\n\t): Promise<chartsRoute.SdkChart> {\n\t\treturn await chartsRoute.getChart(\n\t\t\tthis.client,\n\t\t\tthis.queryEngine,\n\t\t\tid,\n\t\t\toptions,\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tasync updateChart(\n\t\tid: string,\n\t\tbody: chartsRoute.ChartUpdateInput,\n\t\toptions?: { tenantId?: string; userId?: string; scopes?: string[] },\n\t\tsignal?: AbortSignal,\n\t): Promise<chartsRoute.SdkChart> {\n\t\treturn await chartsRoute.updateChart(\n\t\t\tthis.client,\n\t\t\tid,\n\t\t\tbody,\n\t\t\toptions,\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tasync deleteChart(\n\t\tid: string,\n\t\toptions?: { tenantId?: string; userId?: string; scopes?: string[] },\n\t\tsignal?: AbortSignal,\n\t): Promise<void> {\n\t\tawait chartsRoute.deleteChart(this.client, id, options, signal);\n\t}\n\n\t// Active Chart CRUD operations\n\n\tasync createActiveChart(\n\t\tbody: activeChartsRoute.ActiveChartCreateInput,\n\t\toptions?: { tenantId?: string; userId?: string; scopes?: string[] },\n\t\tsignal?: AbortSignal,\n\t): Promise<activeChartsRoute.SdkActiveChart> {\n\t\treturn await activeChartsRoute.createActiveChart(\n\t\t\tthis.client,\n\t\t\tbody,\n\t\t\toptions,\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tasync listActiveCharts(\n\t\toptions?: activeChartsRoute.ActiveChartListOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<chartsRoute.PaginatedResponse<activeChartsRoute.SdkActiveChart>> {\n\t\treturn await activeChartsRoute.listActiveCharts(\n\t\t\tthis.client,\n\t\t\tthis.queryEngine,\n\t\t\toptions,\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tasync getActiveChart(\n\t\tid: string,\n\t\toptions?: activeChartsRoute.ActiveChartListOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<activeChartsRoute.SdkActiveChart> {\n\t\treturn await activeChartsRoute.getActiveChart(\n\t\t\tthis.client,\n\t\t\tthis.queryEngine,\n\t\t\tid,\n\t\t\toptions,\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tasync updateActiveChart(\n\t\tid: string,\n\t\tbody: activeChartsRoute.ActiveChartUpdateInput,\n\t\toptions?: { tenantId?: string; userId?: string; scopes?: string[] },\n\t\tsignal?: AbortSignal,\n\t): Promise<activeChartsRoute.SdkActiveChart> {\n\t\treturn await activeChartsRoute.updateActiveChart(\n\t\t\tthis.client,\n\t\t\tid,\n\t\t\tbody,\n\t\t\toptions,\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tasync deleteActiveChart(\n\t\tid: string,\n\t\toptions?: { tenantId?: string; userId?: string; scopes?: string[] },\n\t\tsignal?: AbortSignal,\n\t): Promise<void> {\n\t\tawait activeChartsRoute.deleteActiveChart(this.client, id, options, signal);\n\t}\n}\n","const WRAPPER_REGEX =\n /^(Nullable|LowCardinality|SimpleAggregateFunction)\\((.+)\\)$/i;\n\nexport function isNullableType(type: string): boolean {\n return /Nullable\\s*\\(/i.test(type);\n}\n\nexport function unwrapTypeModifiers(type: string): string {\n let current = type.trim();\n let match = WRAPPER_REGEX.exec(current);\n while (match) {\n const inner = match[2];\n if (!inner) {\n break;\n }\n current = inner.trim();\n match = WRAPPER_REGEX.exec(current);\n }\n return current;\n}\n\nexport function extractPrecisionScale(type: string): {\n precision?: number;\n scale?: number;\n} {\n const unwrapped = unwrapTypeModifiers(type);\n const decimalMatch = unwrapped.match(/Decimal(?:\\d+)?\\((\\d+)\\s*,\\s*(\\d+)\\)/i);\n if (!decimalMatch) return {};\n const precision = decimalMatch[1];\n const scale = decimalMatch[2];\n if (!precision || !scale) return {};\n return {\n precision: Number.parseInt(precision, 10),\n scale: Number.parseInt(scale, 10),\n };\n}\n\nexport function extractFixedStringLength(type: string): number | undefined {\n const unwrapped = unwrapTypeModifiers(type);\n const match = unwrapped.match(/^(?:FixedString|StringFixed)\\((\\d+)\\)$/i);\n if (!match) return undefined;\n const length = match[1];\n if (!length) return undefined;\n return Number.parseInt(length, 10);\n}\n\nexport function parseKeyExpression(expression?: string | null): string[] {\n if (!expression) return [];\n let value = expression.trim();\n if (!value) return [];\n if (/^tuple\\s*\\(/i.test(value) && value.endsWith(\")\")) {\n value = value.replace(/^tuple\\s*\\(/i, \"\").replace(/\\)$/, \"\");\n }\n\n const columns: string[] = [];\n let depth = 0;\n let token = \"\";\n for (const ch of value) {\n if (ch === \"(\") {\n depth += 1;\n token += ch;\n continue;\n }\n if (ch === \")\") {\n depth = Math.max(0, depth - 1);\n token += ch;\n continue;\n }\n if (ch === \",\" && depth === 0) {\n const col = token.trim();\n if (col) columns.push(stripWrapper(col));\n token = \"\";\n continue;\n }\n token += ch;\n }\n const last = token.trim();\n if (last) columns.push(stripWrapper(last));\n return columns.filter(Boolean);\n}\n\nfunction stripWrapper(value: string): string {\n const noQuotes = stripQuotes(value);\n const withoutTicks = noQuotes.replace(/`/g, \"\").trim();\n const parts = withoutTicks.split(\".\");\n return parts[parts.length - 1]?.trim() ?? \"\";\n}\n\nfunction stripQuotes(value: string): string {\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n return value.slice(1, -1);\n }\n return value;\n}\n","import type {\n\tClickHouseSettings,\n\tDataFormat,\n\tQueryParams,\n} from \"@clickhouse/client\";\nimport type {\n\tColumnSchema,\n\tIntrospectOptions,\n\tSchemaIntrospection,\n\tTableSchema,\n} from \"../schema/types\";\nimport { parseKeyExpression, unwrapTypeModifiers } from \"../utils/clickhouse\";\nimport type { DatabaseAdapter, DatabaseExecutionResult } from \"./types\";\n\nexport interface ClickHouseAdapterOptions {\n\t/** Optional logical database name used in introspection metadata. */\n\tdatabase?: string;\n\t/** Override the default response format used for query execution. */\n\tdefaultFormat?: DataFormat;\n\t/**\n\t * Optional database kind label. Defaults to \"clickhouse\" but allows\n\t * sub-classing/custom branding if needed.\n\t */\n\tkind?: SchemaIntrospection[\"db\"][\"kind\"];\n\t/**\n\t * Optional allow-list of table names.\n\t * When specified, introspection and queries are restricted to these tables only.\n\t * ClickHouse tables are not schema-qualified, so just provide table names.\n\t */\n\tallowedTables?: string[];\n}\n\nexport type ClickHouseQueryResult = { json: () => Promise<unknown> };\n\nexport type ClickHouseClientFn = (\n\tparams: QueryParams,\n) => Promise<\n\t| ClickHouseQueryResult\n\t| Array<Record<string, unknown>>\n\t| Record<string, unknown>[]\n>;\n\ninterface QueryOptions {\n\tparams?: Record<string, unknown>;\n\tformat?: DataFormat;\n\tsettings?: ClickHouseSettings;\n}\n\ntype TableRow = {\n\tname: string;\n\tengine: string;\n\tcomment: string | null;\n\tprimary_key: string | null;\n};\n\ntype ColumnRow = {\n\ttable: string;\n\tname: string;\n\ttype: string;\n\tposition: number;\n\tcomment: string | null;\n\tis_in_primary_key: string | number | null;\n};\n\n/**\n * Simplified ClickHouse adapter following IngestRequest format\n * Removed: indexes, constraints, statistics\n * Kept only: tables, columns (name, type, isPrimaryKey, comment)\n */\nexport class ClickHouseAdapter implements DatabaseAdapter {\n\tprivate readonly databaseName: string;\n\tprivate readonly defaultFormat: QueryParams[\"format\"];\n\tprivate readonly kind: SchemaIntrospection[\"db\"][\"kind\"];\n\tprivate readonly allowedTables?: string[];\n\n\tconstructor(\n\t\tprivate readonly clientFn: ClickHouseClientFn,\n\t\toptions: ClickHouseAdapterOptions = {},\n\t) {\n\t\tthis.databaseName = options.database ?? \"default\";\n\t\tthis.defaultFormat = options.defaultFormat ?? \"JSONEachRow\";\n\t\tthis.kind = options.kind ?? \"clickhouse\";\n\t\tif (options.allowedTables) {\n\t\t\tthis.allowedTables = normalizeTableFilter(options.allowedTables);\n\t\t}\n\t}\n\n\tasync execute(\n\t\tsql: string,\n\t\tparams?: Record<string, string | number | boolean | string[] | number[]>,\n\t): Promise<DatabaseExecutionResult> {\n\t\t// Validate query against allowed tables if restrictions are in place\n\t\tif (this.allowedTables) {\n\t\t\tthis.validateQueryTables(sql);\n\t\t}\n\n\t\tconst queryOptions: QueryOptions = {\n\t\t\tformat: this.defaultFormat,\n\t\t};\n\t\tif (params) {\n\t\t\tqueryOptions.params = params;\n\t\t}\n\n\t\tconst rows = await this.query<Record<string, unknown>>(sql, queryOptions);\n\t\tconst fields = rows.length > 0 ? Object.keys(rows[0] ?? {}) : [];\n\t\treturn { fields, rows };\n\t}\n\n\tasync validate(\n\t\tsql: string,\n\t\tparams?: Record<string, string | number | boolean | string[] | number[]>,\n\t): Promise<void> {\n\t\tconst queryOptions: QueryOptions = {\n\t\t\tformat: this.defaultFormat,\n\t\t};\n\t\tif (params) {\n\t\t\tqueryOptions.params = params;\n\t\t}\n\n\t\tawait this.query(`EXPLAIN ${sql}`, queryOptions);\n\t}\n\n\tgetDialect() {\n\t\treturn \"clickhouse\" as const;\n\t}\n\n\t/**\n\t * Simplified introspection: only collect table/column metadata for IngestRequest\n\t * No indexes, constraints, or statistics\n\t */\n\tasync introspect(options?: IntrospectOptions): Promise<SchemaIntrospection> {\n\t\t// Use adapter-level allowedTables if no specific tables provided in options\n\t\tconst tablesToIntrospect = options?.tables\n\t\t\t? normalizeTableFilter(options.tables)\n\t\t\t: this.allowedTables;\n\t\tconst allowTables = tablesToIntrospect ?? [];\n\t\tconst hasFilter = allowTables.length > 0;\n\t\tconst queryParams: Record<string, unknown> = {\n\t\t\tdb: this.databaseName,\n\t\t};\n\t\tif (hasFilter) {\n\t\t\tqueryParams.tables = allowTables;\n\t\t}\n\n\t\tconst filterClause = hasFilter ? \" AND name IN {tables:Array(String)}\" : \"\";\n\t\tconst tables = await this.query<TableRow>(\n\t\t\t`SELECT name, engine, comment, primary_key\n FROM system.tables\n WHERE database = {db:String}${filterClause}\n ORDER BY name`,\n\t\t\t{ params: queryParams },\n\t\t);\n\n\t\tconst columnFilterClause = hasFilter\n\t\t\t? \" AND table IN {tables:Array(String)}\"\n\t\t\t: \"\";\n\t\tconst columns = await this.query<ColumnRow>(\n\t\t\t`SELECT table, name, type, position, comment, is_in_primary_key\n FROM system.columns\n WHERE database = {db:String}${columnFilterClause}\n ORDER BY table, position`,\n\t\t\t{ params: queryParams },\n\t\t);\n\n\t\tconst columnsByTable = new Map<string, ColumnSchema[]>();\n\t\tfor (const rawColumn of columns) {\n\t\t\tconst list = columnsByTable.get(rawColumn.table) ?? [];\n\t\t\tlist.push(transformColumnRow(rawColumn));\n\t\t\tcolumnsByTable.set(rawColumn.table, list);\n\t\t}\n\n\t\tconst tableSchemas: TableSchema[] = tables.map((table) => {\n\t\t\tconst tableColumns = columnsByTable.get(table.name) ?? [];\n\t\t\tconst primaryKeyColumns = parseKeyExpression(table.primary_key);\n\n\t\t\t// Mark columns as primary key\n\t\t\tfor (const column of tableColumns) {\n\t\t\t\tcolumn.isPrimaryKey =\n\t\t\t\t\tcolumn.isPrimaryKey || primaryKeyColumns.includes(column.name);\n\t\t\t}\n\n\t\t\tconst base: TableSchema = {\n\t\t\t\tname: table.name,\n\t\t\t\tschema: this.databaseName,\n\t\t\t\ttype: asTableType(table.engine),\n\t\t\t\tcolumns: tableColumns,\n\t\t\t};\n\n\t\t\tconst comment = sanitize(table.comment);\n\t\t\tif (comment !== undefined) {\n\t\t\t\tbase.comment = comment;\n\t\t\t}\n\n\t\t\treturn base;\n\t\t});\n\n\t\treturn {\n\t\t\tdb: {\n\t\t\t\tkind: this.kind,\n\t\t\t\tname: this.databaseName,\n\t\t\t},\n\t\t\ttables: tableSchemas,\n\t\t\tintrospectedAt: new Date().toISOString(),\n\t\t};\n\t}\n\n\tprivate validateQueryTables(sql: string): void {\n\t\tif (!this.allowedTables || this.allowedTables.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst allowedSet = new Set(this.allowedTables);\n\n\t\t// Extract potential table references from SQL\n\t\tconst tablePattern =\n\t\t\t/(?:FROM|JOIN)\\s+(?:FINAL\\s+)?(?:(?:[a-zA-Z_][a-zA-Z0-9_]*)\\.)?([\"'`]?[a-zA-Z_][a-zA-Z0-9_]*[\"'`]?)/gi;\n\t\tconst matches = sql.matchAll(tablePattern);\n\n\t\tfor (const match of matches) {\n\t\t\tconst table = match[1]?.replace(/[\"'`]/g, \"\");\n\t\t\tif (table) {\n\t\t\t\tif (!allowedSet.has(table)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Query references table \"${table}\" which is not in the allowed tables list`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tasync close(): Promise<void> {\n\t\t// No-op: lifecycle of the underlying client is controlled by the caller.\n\t}\n\n\tprivate async query<T>(sql: string, options?: QueryOptions): Promise<T[]> {\n\t\tconst params: QueryParams = {\n\t\t\tquery: sql,\n\t\t};\n\n\t\tconst format = options?.format ?? this.defaultFormat;\n\t\tif (format !== undefined) {\n\t\t\tparams.format = format;\n\t\t}\n\n\t\tif (options?.params) {\n\t\t\tparams.query_params = options.params;\n\t\t}\n\n\t\tif (options?.settings) {\n\t\t\tparams.clickhouse_settings = options.settings;\n\t\t}\n\n\t\tconst result = await this.clientFn(params);\n\t\treturn this.extractRows<T>(result);\n\t}\n\n\tprivate async extractRows<T>(\n\t\tresult:\n\t\t\t| ClickHouseQueryResult\n\t\t\t| Array<Record<string, unknown>>\n\t\t\t| Record<string, unknown>[],\n\t): Promise<T[]> {\n\t\tif (Array.isArray(result)) {\n\t\t\treturn result as T[];\n\t\t}\n\n\t\tif (\n\t\t\tresult &&\n\t\t\ttypeof (result as ClickHouseQueryResult).json === \"function\"\n\t\t) {\n\t\t\tconst payload = await (result as ClickHouseQueryResult).json();\n\t\t\treturn normalizePayload<T>(payload);\n\t\t}\n\n\t\treturn [];\n\t}\n}\n\nfunction normalizePayload<T>(payload: unknown): T[] {\n\tif (Array.isArray(payload)) {\n\t\treturn payload as T[];\n\t}\n\tif (payload && typeof payload === \"object\") {\n\t\tconst maybeData = (payload as { data?: unknown }).data;\n\t\tif (Array.isArray(maybeData)) {\n\t\t\treturn maybeData as T[];\n\t\t}\n\t}\n\treturn [];\n}\n\nfunction normalizeTableFilter(tables?: string[] | null): string[] {\n\tif (!tables?.length) return [];\n\tconst seen = new Set<string>();\n\tconst normalized: string[] = [];\n\tfor (const table of tables) {\n\t\tif (!table) continue;\n\t\tconst trimmed = table.trim();\n\t\tif (!trimmed) continue;\n\t\tconst parts = trimmed.split(\".\");\n\t\tconst tableName = parts[parts.length - 1];\n\t\tif (!tableName || seen.has(tableName)) continue;\n\t\tseen.add(tableName);\n\t\tnormalized.push(tableName);\n\t}\n\treturn normalized;\n}\n\nfunction transformColumnRow(row: ColumnRow): ColumnSchema {\n\tconst unwrappedType = unwrapTypeModifiers(row.type);\n\n\tconst column: ColumnSchema = {\n\t\tname: row.name,\n\t\ttype: unwrappedType,\n\t\trawType: row.type,\n\t\tisPrimaryKey: Boolean(toNumber(row.is_in_primary_key)),\n\t};\n\n\tconst comment = sanitize(row.comment);\n\tif (comment !== undefined) column.comment = comment;\n\n\treturn column;\n}\n\nfunction asTableType(engine: unknown): TableSchema[\"type\"] {\n\tif (typeof engine === \"string\") {\n\t\tconst normalized = engine.toLowerCase();\n\t\t// ClickHouse view engines: View, MaterializedView, LiveView\n\t\tif (normalized.includes(\"view\")) {\n\t\t\treturn \"view\";\n\t\t}\n\t}\n\treturn \"table\";\n}\n\nfunction sanitize(value: unknown): string | undefined {\n\tif (value === null || value === undefined) return undefined;\n\tconst trimmed = String(value).trim();\n\treturn trimmed.length ? trimmed : undefined;\n}\n\nfunction toNumber(value: unknown): number | undefined {\n\tif (value === null || value === undefined) return undefined;\n\tif (typeof value === \"number\") return value;\n\tconst parsed = Number.parseFloat(String(value));\n\treturn Number.isNaN(parsed) ? undefined : parsed;\n}\n","import type {\n\tColumnSchema,\n\tIntrospectOptions,\n\tSchemaIntrospection,\n\tTableSchema,\n} from \"../schema/types\";\nimport type { DatabaseAdapter, DatabaseExecutionResult } from \"./types\";\n\nexport interface PostgresQueryResult {\n\trows: Array<Record<string, unknown>>;\n\tfields: Array<{ name: string }>;\n}\n\nexport type PostgresClientFn = (\n\tsql: string,\n\tparams?: unknown[],\n) => Promise<PostgresQueryResult>;\n\nexport interface PostgresAdapterOptions {\n\t/** Logical database name used in introspection metadata. */\n\tdatabase?: string;\n\t/** Schema to assume when a table is provided without qualification. */\n\tdefaultSchema?: string;\n\t/** Optional database kind label. Defaults to \"postgres\". */\n\tkind?: SchemaIntrospection[\"db\"][\"kind\"];\n\t/**\n\t * Optional allow-list of table names (schema-qualified or bare).\n\t * When specified, introspection and queries are restricted to these tables only.\n\t */\n\tallowedTables?: string[];\n}\n\ntype TableRow = {\n\ttable_name: string;\n\tschema_name: string;\n\ttable_type: string;\n\tcomment: string | null;\n};\n\ntype ColumnRow = {\n\ttable_name: string;\n\ttable_schema: string;\n\tcolumn_name: string;\n\tdata_type: string;\n\tudt_name: string | null;\n\tis_primary_key: boolean;\n\tdescription: string | null;\n};\n\ninterface NormalizedTable {\n\tschema: string;\n\ttable: string;\n}\n\n/**\n * Simplified PostgreSQL adapter following IngestRequest format\n * Removed: indexes, constraints, foreign keys, statistics\n * Kept only: tables, columns (name, type, isPrimaryKey, comment)\n */\nexport class PostgresAdapter implements DatabaseAdapter {\n\tprivate readonly databaseName: string;\n\tprivate readonly defaultSchema: string;\n\tprivate readonly kind: SchemaIntrospection[\"db\"][\"kind\"];\n\tprivate readonly allowedTables?: NormalizedTable[];\n\n\tconstructor(\n\t\tprivate readonly clientFn: PostgresClientFn,\n\t\toptions: PostgresAdapterOptions = {},\n\t) {\n\t\tthis.databaseName = options.database ?? \"postgres\";\n\t\tthis.defaultSchema = options.defaultSchema ?? \"public\";\n\t\tthis.kind = options.kind ?? \"postgres\";\n\t\tif (options.allowedTables) {\n\t\t\tthis.allowedTables = normalizeTableFilter(\n\t\t\t\toptions.allowedTables,\n\t\t\t\tthis.defaultSchema,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync execute(\n\t\tsql: string,\n\t\tparams?: Record<string, string | number | boolean | string[] | number[]>,\n\t): Promise<DatabaseExecutionResult> {\n\t\t// Validate query against allowed tables if restrictions are in place\n\t\tif (this.allowedTables) {\n\t\t\tthis.validateQueryTables(sql);\n\t\t}\n\n\t\t// Convert named params to positional array for PostgreSQL\n\t\tlet paramArray: unknown[] | undefined;\n\t\tif (params) {\n\t\t\tparamArray = this.convertNamedToPositionalParams(params);\n\t\t}\n\n\t\tconst result = await this.clientFn(sql, paramArray);\n\t\tconst fields = result.fields.map((f) => f.name);\n\t\treturn { fields, rows: result.rows };\n\t}\n\n\tprivate validateQueryTables(sql: string): void {\n\t\tif (!this.allowedTables || this.allowedTables.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst allowedSet = new Set(\n\t\t\tthis.allowedTables.map((t) => tableKey(t.schema, t.table)),\n\t\t);\n\n\t\t// Extract potential table references from SQL\n\t\tconst tablePattern =\n\t\t\t/(?:FROM|JOIN)\\s+(?:ONLY\\s+)?(?:([a-zA-Z_][a-zA-Z0-9_]*)\\.)?([\"']?[a-zA-Z_][a-zA-Z0-9_]*[\"']?)/gi;\n\t\tconst matches = sql.matchAll(tablePattern);\n\n\t\tfor (const match of matches) {\n\t\t\tconst schema = match[1] ?? this.defaultSchema;\n\t\t\tconst table = match[2]?.replace(/['\"]/g, \"\");\n\t\t\tif (table) {\n\t\t\t\tconst key = tableKey(schema, table);\n\t\t\t\tif (!allowedSet.has(key)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Query references table \"${schema}.${table}\" which is not in the allowed tables list`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Convert named params to positional array for PostgreSQL\n\t * PostgreSQL expects $1, $2, $3 in SQL and an array of values [val1, val2, val3]\n\t */\n\tprivate convertNamedToPositionalParams(\n\t\tparams: Record<string, string | number | boolean | string[] | number[]>,\n\t): unknown[] {\n\t\t// Separate numeric and named keys\n\t\tconst numericKeys = Object.keys(params)\n\t\t\t.filter((k) => /^\\d+$/.test(k))\n\t\t\t.map((k) => Number.parseInt(k, 10))\n\t\t\t.sort((a, b) => a - b);\n\n\t\tconst namedKeys = Object.keys(params)\n\t\t\t.filter((k) => !/^\\d+$/.test(k))\n\t\t\t.sort(); // Alphabetical order for consistency\n\n\t\t// Build positional array\n\t\tconst positionalParams: unknown[] = [];\n\n\t\t// First, add values from numeric keys (in sorted order)\n\t\tfor (const key of numericKeys) {\n\t\t\tlet val: unknown = params[String(key)];\n\t\t\tif (typeof val === \"string\") {\n\t\t\t\t// Resolve placeholder tokens like `<tenant_id>` to their named values\n\t\t\t\tconst match = val.match(/^<([a-zA-Z0-9_]+)>$/);\n\t\t\t\tconst namedKey = match?.[1];\n\t\t\t\tif (namedKey && namedKey in params) {\n\t\t\t\t\tval = params[namedKey as keyof typeof params];\n\t\t\t\t}\n\t\t\t}\n\t\t\tpositionalParams.push(val);\n\t\t}\n\n\t\t// Then, add values from named keys (in alphabetical order)\n\t\tfor (const key of namedKeys) {\n\t\t\tconst val = params[key];\n\t\t\tpositionalParams.push(val);\n\t\t}\n\n\t\treturn positionalParams;\n\t}\n\n\tasync validate(\n\t\tsql: string,\n\t\tparams?: Record<string, string | number | boolean | string[] | number[]>,\n\t): Promise<void> {\n\t\tlet paramArray: unknown[] | undefined;\n\t\tif (params) {\n\t\t\tparamArray = this.convertNamedToPositionalParams(params);\n\t\t}\n\n\t\tawait this.clientFn(`EXPLAIN ${sql}`, paramArray);\n\t}\n\n\tgetDialect() {\n\t\treturn \"postgres\" as const;\n\t}\n\n\t/**\n\t * Simplified introspection: only collect table/column metadata for IngestRequest\n\t * No indexes, constraints, or statistics\n\t */\n\tasync introspect(options?: IntrospectOptions): Promise<SchemaIntrospection> {\n\t\t// Use adapter-level allowedTables if no specific tables provided in options\n\t\tconst tablesToIntrospect = options?.tables\n\t\t\t? normalizeTableFilter(options.tables, this.defaultSchema)\n\t\t\t: this.allowedTables;\n\t\tconst normalizedTables = tablesToIntrospect ?? [];\n\n\t\tconst tablesResult = await this.clientFn(\n\t\t\tbuildTablesQuery(normalizedTables),\n\t\t);\n\t\tconst tableRows = tablesResult.rows as TableRow[];\n\n\t\tconst columnsResult = await this.clientFn(\n\t\t\tbuildColumnsQuery(normalizedTables),\n\t\t);\n\t\tconst columnRows = columnsResult.rows as ColumnRow[];\n\n\t\tconst tablesByKey = new Map<string, TableSchema>();\n\n\t\t// Build tables\n\t\tfor (const row of tableRows) {\n\t\t\tconst key = tableKey(row.schema_name, row.table_name);\n\t\t\tconst table: TableSchema = {\n\t\t\t\tname: row.table_name,\n\t\t\t\tschema: row.schema_name,\n\t\t\t\ttype: asTableType(row.table_type),\n\t\t\t\tcolumns: [],\n\t\t\t};\n\n\t\t\tconst comment = sanitize(row.comment);\n\t\t\tif (comment !== undefined) {\n\t\t\t\ttable.comment = comment;\n\t\t\t}\n\n\t\t\ttablesByKey.set(key, table);\n\t\t}\n\n\t\t// Build columns\n\t\tfor (const row of columnRows) {\n\t\t\tconst key = tableKey(row.table_schema, row.table_name);\n\t\t\tconst table = tablesByKey.get(key);\n\t\t\tif (!table) continue;\n\n\t\t\tconst column: ColumnSchema = {\n\t\t\t\tname: row.column_name,\n\t\t\t\ttype: row.data_type,\n\t\t\t\tisPrimaryKey: row.is_primary_key,\n\t\t\t};\n\n\t\t\tconst rawType = row.udt_name ?? undefined;\n\t\t\tif (rawType !== undefined) column.rawType = rawType;\n\n\t\t\tconst comment = sanitize(row.description);\n\t\t\tif (comment !== undefined) column.comment = comment;\n\n\t\t\ttable.columns.push(column);\n\t\t}\n\n\t\tconst tables = Array.from(tablesByKey.values()).sort((a, b) => {\n\t\t\tif (a.schema === b.schema) {\n\t\t\t\treturn a.name.localeCompare(b.name);\n\t\t\t}\n\t\t\treturn a.schema.localeCompare(b.schema);\n\t\t});\n\n\t\treturn {\n\t\t\tdb: {\n\t\t\t\tkind: this.kind,\n\t\t\t\tname: this.databaseName,\n\t\t\t},\n\t\t\ttables,\n\t\t\tintrospectedAt: new Date().toISOString(),\n\t\t};\n\t}\n}\n\nfunction normalizeTableFilter(\n\ttables: string[] | undefined,\n\tdefaultSchema: string,\n): NormalizedTable[] {\n\tif (!tables?.length) return [];\n\tconst normalized: NormalizedTable[] = [];\n\tconst seen = new Set<string>();\n\n\tfor (const raw of tables) {\n\t\tif (!raw) continue;\n\t\tconst trimmed = raw.trim();\n\t\tif (!trimmed) continue;\n\t\tconst parts = trimmed.split(\".\");\n\t\tconst table = parts.pop() ?? \"\";\n\t\tconst schema = parts.pop() ?? defaultSchema;\n\t\tif (!isSafeIdentifier(schema) || !isSafeIdentifier(table)) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst key = tableKey(schema, table);\n\t\tif (seen.has(key)) continue;\n\t\tseen.add(key);\n\t\tnormalized.push({ schema, table });\n\t}\n\n\treturn normalized;\n}\n\nfunction buildTablesQuery(tables: NormalizedTable[]): string {\n\tconst filter = buildFilterClause(tables, \"n.nspname\", \"c.relname\");\n\treturn `SELECT\n c.relname AS table_name,\n n.nspname AS schema_name,\n CASE c.relkind\n WHEN 'r' THEN 'table'\n WHEN 'v' THEN 'view'\n WHEN 'm' THEN 'materialized_view'\n ELSE c.relkind::text\n END AS table_type,\n obj_description(c.oid) AS comment\n FROM pg_class c\n JOIN pg_namespace n ON n.oid = c.relnamespace\n WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')\n AND c.relkind IN ('r', 'v', 'm')\n ${filter}\n ORDER BY n.nspname, c.relname;`;\n}\n\nfunction buildColumnsQuery(tables: NormalizedTable[]): string {\n\tconst filter = buildFilterClause(\n\t\ttables,\n\t\t\"cols.table_schema\",\n\t\t\"cols.table_name\",\n\t);\n\treturn `SELECT\n cols.table_name,\n cols.table_schema,\n cols.column_name,\n cols.data_type,\n cols.udt_name,\n pgd.description,\n EXISTS(\n SELECT 1\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n WHERE tc.constraint_type = 'PRIMARY KEY'\n AND tc.table_schema = cols.table_schema\n AND tc.table_name = cols.table_name\n AND kcu.column_name = cols.column_name\n ) AS is_primary_key\n FROM information_schema.columns cols\n LEFT JOIN pg_catalog.pg_class c\n ON c.relname = cols.table_name\n AND c.relkind IN ('r', 'v', 'm')\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n LEFT JOIN pg_catalog.pg_attribute attr\n ON attr.attrelid = c.oid\n AND attr.attname = cols.column_name\n LEFT JOIN pg_catalog.pg_description pgd\n ON pgd.objoid = attr.attrelid AND pgd.objsubid = attr.attnum\n WHERE cols.table_schema NOT IN ('pg_catalog', 'information_schema')\n ${filter}\n ORDER BY cols.table_schema, cols.table_name, cols.ordinal_position;`;\n}\n\nfunction buildFilterClause(\n\ttables: NormalizedTable[],\n\tschemaExpr: string,\n\ttableExpr: string,\n): string {\n\tif (!tables.length) return \"\";\n\tconst clauses = tables.map(({ schema, table }) => {\n\t\treturn `(${schemaExpr} = '${schema}' AND ${tableExpr} = '${table}')`;\n\t});\n\treturn `AND (${clauses.join(\" OR \")})`;\n}\n\nfunction tableKey(schema: string, table: string): string {\n\treturn `${schema}.${table}`;\n}\n\nfunction isSafeIdentifier(value: string): boolean {\n\treturn /^[A-Za-z_][A-Za-z0-9_]*$/.test(value);\n}\n\nfunction asTableType(value: string): TableSchema[\"type\"] {\n\tconst normalized = value.toLowerCase();\n\tif (normalized.includes(\"view\")) {\n\t\treturn normalized.includes(\"materialized\") ? \"materialized_view\" : \"view\";\n\t}\n\treturn \"table\";\n}\n\nfunction sanitize(value: unknown): string | undefined {\n\tif (value === null || value === undefined) return undefined;\n\tconst trimmed = String(value).trim();\n\treturn trimmed.length ? trimmed : undefined;\n}\n","export const encoder = new TextEncoder();\nexport const decoder = new TextDecoder();\nconst MAX_INT32 = 2 ** 32;\nexport function concat(...buffers) {\n const size = buffers.reduce((acc, { length }) => acc + length, 0);\n const buf = new Uint8Array(size);\n let i = 0;\n for (const buffer of buffers) {\n buf.set(buffer, i);\n i += buffer.length;\n }\n return buf;\n}\nfunction writeUInt32BE(buf, value, offset) {\n if (value < 0 || value >= MAX_INT32) {\n throw new RangeError(`value must be >= 0 and <= ${MAX_INT32 - 1}. Received ${value}`);\n }\n buf.set([value >>> 24, value >>> 16, value >>> 8, value & 0xff], offset);\n}\nexport function uint64be(value) {\n const high = Math.floor(value / MAX_INT32);\n const low = value % MAX_INT32;\n const buf = new Uint8Array(8);\n writeUInt32BE(buf, high, 0);\n writeUInt32BE(buf, low, 4);\n return buf;\n}\nexport function uint32be(value) {\n const buf = new Uint8Array(4);\n writeUInt32BE(buf, value);\n return buf;\n}\nexport function encode(string) {\n const bytes = new Uint8Array(string.length);\n for (let i = 0; i < string.length; i++) {\n const code = string.charCodeAt(i);\n if (code > 127) {\n throw new TypeError('non-ASCII string encountered in encode()');\n }\n bytes[i] = code;\n }\n return bytes;\n}\n","export function encodeBase64(input) {\n if (Uint8Array.prototype.toBase64) {\n return input.toBase64();\n }\n const CHUNK_SIZE = 0x8000;\n const arr = [];\n for (let i = 0; i < input.length; i += CHUNK_SIZE) {\n arr.push(String.fromCharCode.apply(null, input.subarray(i, i + CHUNK_SIZE)));\n }\n return btoa(arr.join(''));\n}\nexport function decodeBase64(encoded) {\n if (Uint8Array.fromBase64) {\n return Uint8Array.fromBase64(encoded);\n }\n const binary = atob(encoded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n","import { encoder, decoder } from '../lib/buffer_utils.js';\nimport { encodeBase64, decodeBase64 } from '../lib/base64.js';\nexport function decode(input) {\n if (Uint8Array.fromBase64) {\n return Uint8Array.fromBase64(typeof input === 'string' ? input : decoder.decode(input), {\n alphabet: 'base64url',\n });\n }\n let encoded = input;\n if (encoded instanceof Uint8Array) {\n encoded = decoder.decode(encoded);\n }\n encoded = encoded.replace(/-/g, '+').replace(/_/g, '/');\n try {\n return decodeBase64(encoded);\n }\n catch {\n throw new TypeError('The input to be decoded is not correctly encoded.');\n }\n}\nexport function encode(input) {\n let unencoded = input;\n if (typeof unencoded === 'string') {\n unencoded = encoder.encode(unencoded);\n }\n if (Uint8Array.prototype.toBase64) {\n return unencoded.toBase64({ alphabet: 'base64url', omitPadding: true });\n }\n return encodeBase64(unencoded).replace(/=/g, '').replace(/\\+/g, '-').replace(/\\//g, '_');\n}\n","export class JOSEError extends Error {\n static code = 'ERR_JOSE_GENERIC';\n code = 'ERR_JOSE_GENERIC';\n constructor(message, options) {\n super(message, options);\n this.name = this.constructor.name;\n Error.captureStackTrace?.(this, this.constructor);\n }\n}\nexport class JWTClaimValidationFailed extends JOSEError {\n static code = 'ERR_JWT_CLAIM_VALIDATION_FAILED';\n code = 'ERR_JWT_CLAIM_VALIDATION_FAILED';\n claim;\n reason;\n payload;\n constructor(message, payload, claim = 'unspecified', reason = 'unspecified') {\n super(message, { cause: { claim, reason, payload } });\n this.claim = claim;\n this.reason = reason;\n this.payload = payload;\n }\n}\nexport class JWTExpired extends JOSEError {\n static code = 'ERR_JWT_EXPIRED';\n code = 'ERR_JWT_EXPIRED';\n claim;\n reason;\n payload;\n constructor(message, payload, claim = 'unspecified', reason = 'unspecified') {\n super(message, { cause: { claim, reason, payload } });\n this.claim = claim;\n this.reason = reason;\n this.payload = payload;\n }\n}\nexport class JOSEAlgNotAllowed extends JOSEError {\n static code = 'ERR_JOSE_ALG_NOT_ALLOWED';\n code = 'ERR_JOSE_ALG_NOT_ALLOWED';\n}\nexport class JOSENotSupported extends JOSEError {\n static code = 'ERR_JOSE_NOT_SUPPORTED';\n code = 'ERR_JOSE_NOT_SUPPORTED';\n}\nexport class JWEDecryptionFailed extends JOSEError {\n static code = 'ERR_JWE_DECRYPTION_FAILED';\n code = 'ERR_JWE_DECRYPTION_FAILED';\n constructor(message = 'decryption operation failed', options) {\n super(message, options);\n }\n}\nexport class JWEInvalid extends JOSEError {\n static code = 'ERR_JWE_INVALID';\n code = 'ERR_JWE_INVALID';\n}\nexport class JWSInvalid extends JOSEError {\n static code = 'ERR_JWS_INVALID';\n code = 'ERR_JWS_INVALID';\n}\nexport class JWTInvalid extends JOSEError {\n static code = 'ERR_JWT_INVALID';\n code = 'ERR_JWT_INVALID';\n}\nexport class JWKInvalid extends JOSEError {\n static code = 'ERR_JWK_INVALID';\n code = 'ERR_JWK_INVALID';\n}\nexport class JWKSInvalid extends JOSEError {\n static code = 'ERR_JWKS_INVALID';\n code = 'ERR_JWKS_INVALID';\n}\nexport class JWKSNoMatchingKey extends JOSEError {\n static code = 'ERR_JWKS_NO_MATCHING_KEY';\n code = 'ERR_JWKS_NO_MATCHING_KEY';\n constructor(message = 'no applicable key found in the JSON Web Key Set', options) {\n super(message, options);\n }\n}\nexport class JWKSMultipleMatchingKeys extends JOSEError {\n [Symbol.asyncIterator];\n static code = 'ERR_JWKS_MULTIPLE_MATCHING_KEYS';\n code = 'ERR_JWKS_MULTIPLE_MATCHING_KEYS';\n constructor(message = 'multiple matching keys found in the JSON Web Key Set', options) {\n super(message, options);\n }\n}\nexport class JWKSTimeout extends JOSEError {\n static code = 'ERR_JWKS_TIMEOUT';\n code = 'ERR_JWKS_TIMEOUT';\n constructor(message = 'request timed out', options) {\n super(message, options);\n }\n}\nexport class JWSSignatureVerificationFailed extends JOSEError {\n static code = 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED';\n code = 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED';\n constructor(message = 'signature verification failed', options) {\n super(message, options);\n }\n}\n","const unusable = (name, prop = 'algorithm.name') => new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);\nconst isAlgorithm = (algorithm, name) => algorithm.name === name;\nfunction getHashLength(hash) {\n return parseInt(hash.name.slice(4), 10);\n}\nfunction getNamedCurve(alg) {\n switch (alg) {\n case 'ES256':\n return 'P-256';\n case 'ES384':\n return 'P-384';\n case 'ES512':\n return 'P-521';\n default:\n throw new Error('unreachable');\n }\n}\nfunction checkUsage(key, usage) {\n if (usage && !key.usages.includes(usage)) {\n throw new TypeError(`CryptoKey does not support this operation, its usages must include ${usage}.`);\n }\n}\nexport function checkSigCryptoKey(key, alg, usage) {\n switch (alg) {\n case 'HS256':\n case 'HS384':\n case 'HS512': {\n if (!isAlgorithm(key.algorithm, 'HMAC'))\n throw unusable('HMAC');\n const expected = parseInt(alg.slice(2), 10);\n const actual = getHashLength(key.algorithm.hash);\n if (actual !== expected)\n throw unusable(`SHA-${expected}`, 'algorithm.hash');\n break;\n }\n case 'RS256':\n case 'RS384':\n case 'RS512': {\n if (!isAlgorithm(key.algorithm, 'RSASSA-PKCS1-v1_5'))\n throw unusable('RSASSA-PKCS1-v1_5');\n const expected = parseInt(alg.slice(2), 10);\n const actual = getHashLength(key.algorithm.hash);\n if (actual !== expected)\n throw unusable(`SHA-${expected}`, 'algorithm.hash');\n break;\n }\n case 'PS256':\n case 'PS384':\n case 'PS512': {\n if (!isAlgorithm(key.algorithm, 'RSA-PSS'))\n throw unusable('RSA-PSS');\n const expected = parseInt(alg.slice(2), 10);\n const actual = getHashLength(key.algorithm.hash);\n if (actual !== expected)\n throw unusable(`SHA-${expected}`, 'algorithm.hash');\n break;\n }\n case 'Ed25519':\n case 'EdDSA': {\n if (!isAlgorithm(key.algorithm, 'Ed25519'))\n throw unusable('Ed25519');\n break;\n }\n case 'ML-DSA-44':\n case 'ML-DSA-65':\n case 'ML-DSA-87': {\n if (!isAlgorithm(key.algorithm, alg))\n throw unusable(alg);\n break;\n }\n case 'ES256':\n case 'ES384':\n case 'ES512': {\n if (!isAlgorithm(key.algorithm, 'ECDSA'))\n throw unusable('ECDSA');\n const expected = getNamedCurve(alg);\n const actual = key.algorithm.namedCurve;\n if (actual !== expected)\n throw unusable(expected, 'algorithm.namedCurve');\n break;\n }\n default:\n throw new TypeError('CryptoKey does not support this operation');\n }\n checkUsage(key, usage);\n}\nexport function checkEncCryptoKey(key, alg, usage) {\n switch (alg) {\n case 'A128GCM':\n case 'A192GCM':\n case 'A256GCM': {\n if (!isAlgorithm(key.algorithm, 'AES-GCM'))\n throw unusable('AES-GCM');\n const expected = parseInt(alg.slice(1, 4), 10);\n const actual = key.algorithm.length;\n if (actual !== expected)\n throw unusable(expected, 'algorithm.length');\n break;\n }\n case 'A128KW':\n case 'A192KW':\n case 'A256KW': {\n if (!isAlgorithm(key.algorithm, 'AES-KW'))\n throw unusable('AES-KW');\n const expected = parseInt(alg.slice(1, 4), 10);\n const actual = key.algorithm.length;\n if (actual !== expected)\n throw unusable(expected, 'algorithm.length');\n break;\n }\n case 'ECDH': {\n switch (key.algorithm.name) {\n case 'ECDH':\n case 'X25519':\n break;\n default:\n throw unusable('ECDH or X25519');\n }\n break;\n }\n case 'PBES2-HS256+A128KW':\n case 'PBES2-HS384+A192KW':\n case 'PBES2-HS512+A256KW':\n if (!isAlgorithm(key.algorithm, 'PBKDF2'))\n throw unusable('PBKDF2');\n break;\n case 'RSA-OAEP':\n case 'RSA-OAEP-256':\n case 'RSA-OAEP-384':\n case 'RSA-OAEP-512': {\n if (!isAlgorithm(key.algorithm, 'RSA-OAEP'))\n throw unusable('RSA-OAEP');\n const expected = parseInt(alg.slice(9), 10) || 1;\n const actual = getHashLength(key.algorithm.hash);\n if (actual !== expected)\n throw unusable(`SHA-${expected}`, 'algorithm.hash');\n break;\n }\n default:\n throw new TypeError('CryptoKey does not support this operation');\n }\n checkUsage(key, usage);\n}\n","function message(msg, actual, ...types) {\n types = types.filter(Boolean);\n if (types.length > 2) {\n const last = types.pop();\n msg += `one of type ${types.join(', ')}, or ${last}.`;\n }\n else if (types.length === 2) {\n msg += `one of type ${types[0]} or ${types[1]}.`;\n }\n else {\n msg += `of type ${types[0]}.`;\n }\n if (actual == null) {\n msg += ` Received ${actual}`;\n }\n else if (typeof actual === 'function' && actual.name) {\n msg += ` Received function ${actual.name}`;\n }\n else if (typeof actual === 'object' && actual != null) {\n if (actual.constructor?.name) {\n msg += ` Received an instance of ${actual.constructor.name}`;\n }\n }\n return msg;\n}\nexport const invalidKeyInput = (actual, ...types) => message('Key must be ', actual, ...types);\nexport const withAlg = (alg, actual, ...types) => message(`Key for the ${alg} algorithm must be `, actual, ...types);\n","export function assertCryptoKey(key) {\n if (!isCryptoKey(key)) {\n throw new Error('CryptoKey instance expected');\n }\n}\nexport const isCryptoKey = (key) => {\n if (key?.[Symbol.toStringTag] === 'CryptoKey')\n return true;\n try {\n return key instanceof CryptoKey;\n }\n catch {\n return false;\n }\n};\nexport const isKeyObject = (key) => key?.[Symbol.toStringTag] === 'KeyObject';\nexport const isKeyLike = (key) => isCryptoKey(key) || isKeyObject(key);\n","export function isDisjoint(...headers) {\n const sources = headers.filter(Boolean);\n if (sources.length === 0 || sources.length === 1) {\n return true;\n }\n let acc;\n for (const header of sources) {\n const parameters = Object.keys(header);\n if (!acc || acc.size === 0) {\n acc = new Set(parameters);\n continue;\n }\n for (const parameter of parameters) {\n if (acc.has(parameter)) {\n return false;\n }\n acc.add(parameter);\n }\n }\n return true;\n}\n","const isObjectLike = (value) => typeof value === 'object' && value !== null;\nexport function isObject(input) {\n if (!isObjectLike(input) || Object.prototype.toString.call(input) !== '[object Object]') {\n return false;\n }\n if (Object.getPrototypeOf(input) === null) {\n return true;\n }\n let proto = input;\n while (Object.getPrototypeOf(proto) !== null) {\n proto = Object.getPrototypeOf(proto);\n }\n return Object.getPrototypeOf(input) === proto;\n}\n","export function checkKeyLength(alg, key) {\n if (alg.startsWith('RS') || alg.startsWith('PS')) {\n const { modulusLength } = key.algorithm;\n if (typeof modulusLength !== 'number' || modulusLength < 2048) {\n throw new TypeError(`${alg} requires key modulusLength to be 2048 bits or larger`);\n }\n }\n}\n","import { invalidKeyInput } from './invalid_key_input.js';\nimport { encodeBase64, decodeBase64 } from '../lib/base64.js';\nimport { JOSENotSupported } from '../util/errors.js';\nimport { isCryptoKey, isKeyObject } from './is_key_like.js';\nconst formatPEM = (b64, descriptor) => {\n const newlined = (b64.match(/.{1,64}/g) || []).join('\\n');\n return `-----BEGIN ${descriptor}-----\\n${newlined}\\n-----END ${descriptor}-----`;\n};\nconst genericExport = async (keyType, keyFormat, key) => {\n if (isKeyObject(key)) {\n if (key.type !== keyType) {\n throw new TypeError(`key is not a ${keyType} key`);\n }\n return key.export({ format: 'pem', type: keyFormat });\n }\n if (!isCryptoKey(key)) {\n throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'KeyObject'));\n }\n if (!key.extractable) {\n throw new TypeError('CryptoKey is not extractable');\n }\n if (key.type !== keyType) {\n throw new TypeError(`key is not a ${keyType} key`);\n }\n return formatPEM(encodeBase64(new Uint8Array(await crypto.subtle.exportKey(keyFormat, key))), `${keyType.toUpperCase()} KEY`);\n};\nexport const toSPKI = (key) => genericExport('public', 'spki', key);\nexport const toPKCS8 = (key) => genericExport('private', 'pkcs8', key);\nconst bytesEqual = (a, b) => {\n if (a.byteLength !== b.length)\n return false;\n for (let i = 0; i < a.byteLength; i++) {\n if (a[i] !== b[i])\n return false;\n }\n return true;\n};\nconst createASN1State = (data) => ({ data, pos: 0 });\nconst parseLength = (state) => {\n const first = state.data[state.pos++];\n if (first & 0x80) {\n const lengthOfLen = first & 0x7f;\n let length = 0;\n for (let i = 0; i < lengthOfLen; i++) {\n length = (length << 8) | state.data[state.pos++];\n }\n return length;\n }\n return first;\n};\nconst skipElement = (state, count = 1) => {\n if (count <= 0)\n return;\n state.pos++;\n const length = parseLength(state);\n state.pos += length;\n if (count > 1) {\n skipElement(state, count - 1);\n }\n};\nconst expectTag = (state, expectedTag, errorMessage) => {\n if (state.data[state.pos++] !== expectedTag) {\n throw new Error(errorMessage);\n }\n};\nconst getSubarray = (state, length) => {\n const result = state.data.subarray(state.pos, state.pos + length);\n state.pos += length;\n return result;\n};\nconst parseAlgorithmOID = (state) => {\n expectTag(state, 0x06, 'Expected algorithm OID');\n const oidLen = parseLength(state);\n return getSubarray(state, oidLen);\n};\nfunction parsePKCS8Header(state) {\n expectTag(state, 0x30, 'Invalid PKCS#8 structure');\n parseLength(state);\n expectTag(state, 0x02, 'Expected version field');\n const verLen = parseLength(state);\n state.pos += verLen;\n expectTag(state, 0x30, 'Expected algorithm identifier');\n const algIdLen = parseLength(state);\n const algIdStart = state.pos;\n return { algIdStart, algIdLength: algIdLen };\n}\nfunction parseSPKIHeader(state) {\n expectTag(state, 0x30, 'Invalid SPKI structure');\n parseLength(state);\n expectTag(state, 0x30, 'Expected algorithm identifier');\n const algIdLen = parseLength(state);\n const algIdStart = state.pos;\n return { algIdStart, algIdLength: algIdLen };\n}\nconst parseECAlgorithmIdentifier = (state) => {\n const algOid = parseAlgorithmOID(state);\n if (bytesEqual(algOid, [0x2b, 0x65, 0x6e])) {\n return 'X25519';\n }\n if (!bytesEqual(algOid, [0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01])) {\n throw new Error('Unsupported key algorithm');\n }\n expectTag(state, 0x06, 'Expected curve OID');\n const curveOidLen = parseLength(state);\n const curveOid = getSubarray(state, curveOidLen);\n for (const { name, oid } of [\n { name: 'P-256', oid: [0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07] },\n { name: 'P-384', oid: [0x2b, 0x81, 0x04, 0x00, 0x22] },\n { name: 'P-521', oid: [0x2b, 0x81, 0x04, 0x00, 0x23] },\n ]) {\n if (bytesEqual(curveOid, oid)) {\n return name;\n }\n }\n throw new Error('Unsupported named curve');\n};\nconst genericImport = async (keyFormat, keyData, alg, options) => {\n let algorithm;\n let keyUsages;\n const isPublic = keyFormat === 'spki';\n const getSigUsages = () => (isPublic ? ['verify'] : ['sign']);\n const getEncUsages = () => isPublic ? ['encrypt', 'wrapKey'] : ['decrypt', 'unwrapKey'];\n switch (alg) {\n case 'PS256':\n case 'PS384':\n case 'PS512':\n algorithm = { name: 'RSA-PSS', hash: `SHA-${alg.slice(-3)}` };\n keyUsages = getSigUsages();\n break;\n case 'RS256':\n case 'RS384':\n case 'RS512':\n algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.slice(-3)}` };\n keyUsages = getSigUsages();\n break;\n case 'RSA-OAEP':\n case 'RSA-OAEP-256':\n case 'RSA-OAEP-384':\n case 'RSA-OAEP-512':\n algorithm = {\n name: 'RSA-OAEP',\n hash: `SHA-${parseInt(alg.slice(-3), 10) || 1}`,\n };\n keyUsages = getEncUsages();\n break;\n case 'ES256':\n case 'ES384':\n case 'ES512': {\n const curveMap = { ES256: 'P-256', ES384: 'P-384', ES512: 'P-521' };\n algorithm = { name: 'ECDSA', namedCurve: curveMap[alg] };\n keyUsages = getSigUsages();\n break;\n }\n case 'ECDH-ES':\n case 'ECDH-ES+A128KW':\n case 'ECDH-ES+A192KW':\n case 'ECDH-ES+A256KW': {\n try {\n const namedCurve = options.getNamedCurve(keyData);\n algorithm = namedCurve === 'X25519' ? { name: 'X25519' } : { name: 'ECDH', namedCurve };\n }\n catch (cause) {\n throw new JOSENotSupported('Invalid or unsupported key format');\n }\n keyUsages = isPublic ? [] : ['deriveBits'];\n break;\n }\n case 'Ed25519':\n case 'EdDSA':\n algorithm = { name: 'Ed25519' };\n keyUsages = getSigUsages();\n break;\n case 'ML-DSA-44':\n case 'ML-DSA-65':\n case 'ML-DSA-87':\n algorithm = { name: alg };\n keyUsages = getSigUsages();\n break;\n default:\n throw new JOSENotSupported('Invalid or unsupported \"alg\" (Algorithm) value');\n }\n return crypto.subtle.importKey(keyFormat, keyData, algorithm, options?.extractable ?? (isPublic ? true : false), keyUsages);\n};\nconst processPEMData = (pem, pattern) => {\n return decodeBase64(pem.replace(pattern, ''));\n};\nexport const fromPKCS8 = (pem, alg, options) => {\n const keyData = processPEMData(pem, /(?:-----(?:BEGIN|END) PRIVATE KEY-----|\\s)/g);\n let opts = options;\n if (alg?.startsWith?.('ECDH-ES')) {\n opts ||= {};\n opts.getNamedCurve = (keyData) => {\n const state = createASN1State(keyData);\n parsePKCS8Header(state);\n return parseECAlgorithmIdentifier(state);\n };\n }\n return genericImport('pkcs8', keyData, alg, opts);\n};\nexport const fromSPKI = (pem, alg, options) => {\n const keyData = processPEMData(pem, /(?:-----(?:BEGIN|END) PUBLIC KEY-----|\\s)/g);\n let opts = options;\n if (alg?.startsWith?.('ECDH-ES')) {\n opts ||= {};\n opts.getNamedCurve = (keyData) => {\n const state = createASN1State(keyData);\n parseSPKIHeader(state);\n return parseECAlgorithmIdentifier(state);\n };\n }\n return genericImport('spki', keyData, alg, opts);\n};\nfunction spkiFromX509(buf) {\n const state = createASN1State(buf);\n expectTag(state, 0x30, 'Invalid certificate structure');\n parseLength(state);\n expectTag(state, 0x30, 'Invalid tbsCertificate structure');\n parseLength(state);\n if (buf[state.pos] === 0xa0) {\n skipElement(state, 6);\n }\n else {\n skipElement(state, 5);\n }\n const spkiStart = state.pos;\n expectTag(state, 0x30, 'Invalid SPKI structure');\n const spkiContentLen = parseLength(state);\n return buf.subarray(spkiStart, spkiStart + spkiContentLen + (state.pos - spkiStart));\n}\nfunction extractX509SPKI(x509) {\n const derBytes = processPEMData(x509, /(?:-----(?:BEGIN|END) CERTIFICATE-----|\\s)/g);\n return spkiFromX509(derBytes);\n}\nexport const fromX509 = (pem, alg, options) => {\n let spki;\n try {\n spki = extractX509SPKI(pem);\n }\n catch (cause) {\n throw new TypeError('Failed to parse the X.509 certificate', { cause });\n }\n return fromSPKI(formatPEM(encodeBase64(spki), 'PUBLIC KEY'), alg, options);\n};\n","import { JOSENotSupported } from '../util/errors.js';\nfunction subtleMapping(jwk) {\n let algorithm;\n let keyUsages;\n switch (jwk.kty) {\n case 'AKP': {\n switch (jwk.alg) {\n case 'ML-DSA-44':\n case 'ML-DSA-65':\n case 'ML-DSA-87':\n algorithm = { name: jwk.alg };\n keyUsages = jwk.priv ? ['sign'] : ['verify'];\n break;\n default:\n throw new JOSENotSupported('Invalid or unsupported JWK \"alg\" (Algorithm) Parameter value');\n }\n break;\n }\n case 'RSA': {\n switch (jwk.alg) {\n case 'PS256':\n case 'PS384':\n case 'PS512':\n algorithm = { name: 'RSA-PSS', hash: `SHA-${jwk.alg.slice(-3)}` };\n keyUsages = jwk.d ? ['sign'] : ['verify'];\n break;\n case 'RS256':\n case 'RS384':\n case 'RS512':\n algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${jwk.alg.slice(-3)}` };\n keyUsages = jwk.d ? ['sign'] : ['verify'];\n break;\n case 'RSA-OAEP':\n case 'RSA-OAEP-256':\n case 'RSA-OAEP-384':\n case 'RSA-OAEP-512':\n algorithm = {\n name: 'RSA-OAEP',\n hash: `SHA-${parseInt(jwk.alg.slice(-3), 10) || 1}`,\n };\n keyUsages = jwk.d ? ['decrypt', 'unwrapKey'] : ['encrypt', 'wrapKey'];\n break;\n default:\n throw new JOSENotSupported('Invalid or unsupported JWK \"alg\" (Algorithm) Parameter value');\n }\n break;\n }\n case 'EC': {\n switch (jwk.alg) {\n case 'ES256':\n algorithm = { name: 'ECDSA', namedCurve: 'P-256' };\n keyUsages = jwk.d ? ['sign'] : ['verify'];\n break;\n case 'ES384':\n algorithm = { name: 'ECDSA', namedCurve: 'P-384' };\n keyUsages = jwk.d ? ['sign'] : ['verify'];\n break;\n case 'ES512':\n algorithm = { name: 'ECDSA', namedCurve: 'P-521' };\n keyUsages = jwk.d ? ['sign'] : ['verify'];\n break;\n case 'ECDH-ES':\n case 'ECDH-ES+A128KW':\n case 'ECDH-ES+A192KW':\n case 'ECDH-ES+A256KW':\n algorithm = { name: 'ECDH', namedCurve: jwk.crv };\n keyUsages = jwk.d ? ['deriveBits'] : [];\n break;\n default:\n throw new JOSENotSupported('Invalid or unsupported JWK \"alg\" (Algorithm) Parameter value');\n }\n break;\n }\n case 'OKP': {\n switch (jwk.alg) {\n case 'Ed25519':\n case 'EdDSA':\n algorithm = { name: 'Ed25519' };\n keyUsages = jwk.d ? ['sign'] : ['verify'];\n break;\n case 'ECDH-ES':\n case 'ECDH-ES+A128KW':\n case 'ECDH-ES+A192KW':\n case 'ECDH-ES+A256KW':\n algorithm = { name: jwk.crv };\n keyUsages = jwk.d ? ['deriveBits'] : [];\n break;\n default:\n throw new JOSENotSupported('Invalid or unsupported JWK \"alg\" (Algorithm) Parameter value');\n }\n break;\n }\n default:\n throw new JOSENotSupported('Invalid or unsupported JWK \"kty\" (Key Type) Parameter value');\n }\n return { algorithm, keyUsages };\n}\nexport async function jwkToKey(jwk) {\n if (!jwk.alg) {\n throw new TypeError('\"alg\" argument is required when \"jwk.alg\" is not present');\n }\n const { algorithm, keyUsages } = subtleMapping(jwk);\n const keyData = { ...jwk };\n if (keyData.kty !== 'AKP') {\n delete keyData.alg;\n }\n delete keyData.use;\n return crypto.subtle.importKey('jwk', keyData, algorithm, jwk.ext ?? (jwk.d || jwk.priv ? false : true), jwk.key_ops ?? keyUsages);\n}\n","import { decode as decodeBase64URL } from '../util/base64url.js';\nimport { fromSPKI, fromPKCS8, fromX509 } from '../lib/asn1.js';\nimport { jwkToKey } from '../lib/jwk_to_key.js';\nimport { JOSENotSupported } from '../util/errors.js';\nimport { isObject } from '../lib/is_object.js';\nexport async function importSPKI(spki, alg, options) {\n if (typeof spki !== 'string' || spki.indexOf('-----BEGIN PUBLIC KEY-----') !== 0) {\n throw new TypeError('\"spki\" must be SPKI formatted string');\n }\n return fromSPKI(spki, alg, options);\n}\nexport async function importX509(x509, alg, options) {\n if (typeof x509 !== 'string' || x509.indexOf('-----BEGIN CERTIFICATE-----') !== 0) {\n throw new TypeError('\"x509\" must be X.509 formatted string');\n }\n return fromX509(x509, alg, options);\n}\nexport async function importPKCS8(pkcs8, alg, options) {\n if (typeof pkcs8 !== 'string' || pkcs8.indexOf('-----BEGIN PRIVATE KEY-----') !== 0) {\n throw new TypeError('\"pkcs8\" must be PKCS#8 formatted string');\n }\n return fromPKCS8(pkcs8, alg, options);\n}\nexport async function importJWK(jwk, alg, options) {\n if (!isObject(jwk)) {\n throw new TypeError('JWK must be an object');\n }\n let ext;\n alg ??= jwk.alg;\n ext ??= options?.extractable ?? jwk.ext;\n switch (jwk.kty) {\n case 'oct':\n if (typeof jwk.k !== 'string' || !jwk.k) {\n throw new TypeError('missing \"k\" (Key Value) Parameter value');\n }\n return decodeBase64URL(jwk.k);\n case 'RSA':\n if ('oth' in jwk && jwk.oth !== undefined) {\n throw new JOSENotSupported('RSA JWK \"oth\" (Other Primes Info) Parameter value is not supported');\n }\n return jwkToKey({ ...jwk, alg, ext });\n case 'AKP': {\n if (typeof jwk.alg !== 'string' || !jwk.alg) {\n throw new TypeError('missing \"alg\" (Algorithm) Parameter value');\n }\n if (alg !== undefined && alg !== jwk.alg) {\n throw new TypeError('JWK alg and alg option value mismatch');\n }\n return jwkToKey({ ...jwk, ext });\n }\n case 'EC':\n case 'OKP':\n return jwkToKey({ ...jwk, alg, ext });\n default:\n throw new JOSENotSupported('Unsupported \"kty\" (Key Type) Parameter value');\n }\n}\n","import { JOSENotSupported, JWEInvalid, JWSInvalid } from '../util/errors.js';\nexport function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) {\n if (joseHeader.crit !== undefined && protectedHeader?.crit === undefined) {\n throw new Err('\"crit\" (Critical) Header Parameter MUST be integrity protected');\n }\n if (!protectedHeader || protectedHeader.crit === undefined) {\n return new Set();\n }\n if (!Array.isArray(protectedHeader.crit) ||\n protectedHeader.crit.length === 0 ||\n protectedHeader.crit.some((input) => typeof input !== 'string' || input.length === 0)) {\n throw new Err('\"crit\" (Critical) Header Parameter MUST be an array of non-empty strings when present');\n }\n let recognized;\n if (recognizedOption !== undefined) {\n recognized = new Map([...Object.entries(recognizedOption), ...recognizedDefault.entries()]);\n }\n else {\n recognized = recognizedDefault;\n }\n for (const parameter of protectedHeader.crit) {\n if (!recognized.has(parameter)) {\n throw new JOSENotSupported(`Extension Header Parameter \"${parameter}\" is not recognized`);\n }\n if (joseHeader[parameter] === undefined) {\n throw new Err(`Extension Header Parameter \"${parameter}\" is missing`);\n }\n if (recognized.get(parameter) && protectedHeader[parameter] === undefined) {\n throw new Err(`Extension Header Parameter \"${parameter}\" MUST be integrity protected`);\n }\n }\n return new Set(protectedHeader.crit);\n}\n","import { isObject } from './is_object.js';\nexport const isJWK = (key) => isObject(key) && typeof key.kty === 'string';\nexport const isPrivateJWK = (key) => key.kty !== 'oct' &&\n ((key.kty === 'AKP' && typeof key.priv === 'string') || typeof key.d === 'string');\nexport const isPublicJWK = (key) => key.kty !== 'oct' && key.d === undefined && key.priv === undefined;\nexport const isSecretJWK = (key) => key.kty === 'oct' && typeof key.k === 'string';\n","import { isJWK } from './is_jwk.js';\nimport { decode } from '../util/base64url.js';\nimport { jwkToKey } from './jwk_to_key.js';\nimport { isCryptoKey, isKeyObject } from './is_key_like.js';\nlet cache;\nconst handleJWK = async (key, jwk, alg, freeze = false) => {\n cache ||= new WeakMap();\n let cached = cache.get(key);\n if (cached?.[alg]) {\n return cached[alg];\n }\n const cryptoKey = await jwkToKey({ ...jwk, alg });\n if (freeze)\n Object.freeze(key);\n if (!cached) {\n cache.set(key, { [alg]: cryptoKey });\n }\n else {\n cached[alg] = cryptoKey;\n }\n return cryptoKey;\n};\nconst handleKeyObject = (keyObject, alg) => {\n cache ||= new WeakMap();\n let cached = cache.get(keyObject);\n if (cached?.[alg]) {\n return cached[alg];\n }\n const isPublic = keyObject.type === 'public';\n const extractable = isPublic ? true : false;\n let cryptoKey;\n if (keyObject.asymmetricKeyType === 'x25519') {\n switch (alg) {\n case 'ECDH-ES':\n case 'ECDH-ES+A128KW':\n case 'ECDH-ES+A192KW':\n case 'ECDH-ES+A256KW':\n break;\n default:\n throw new TypeError('given KeyObject instance cannot be used for this algorithm');\n }\n cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, isPublic ? [] : ['deriveBits']);\n }\n if (keyObject.asymmetricKeyType === 'ed25519') {\n if (alg !== 'EdDSA' && alg !== 'Ed25519') {\n throw new TypeError('given KeyObject instance cannot be used for this algorithm');\n }\n cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [\n isPublic ? 'verify' : 'sign',\n ]);\n }\n switch (keyObject.asymmetricKeyType) {\n case 'ml-dsa-44':\n case 'ml-dsa-65':\n case 'ml-dsa-87': {\n if (alg !== keyObject.asymmetricKeyType.toUpperCase()) {\n throw new TypeError('given KeyObject instance cannot be used for this algorithm');\n }\n cryptoKey = keyObject.toCryptoKey(keyObject.asymmetricKeyType, extractable, [\n isPublic ? 'verify' : 'sign',\n ]);\n }\n }\n if (keyObject.asymmetricKeyType === 'rsa') {\n let hash;\n switch (alg) {\n case 'RSA-OAEP':\n hash = 'SHA-1';\n break;\n case 'RS256':\n case 'PS256':\n case 'RSA-OAEP-256':\n hash = 'SHA-256';\n break;\n case 'RS384':\n case 'PS384':\n case 'RSA-OAEP-384':\n hash = 'SHA-384';\n break;\n case 'RS512':\n case 'PS512':\n case 'RSA-OAEP-512':\n hash = 'SHA-512';\n break;\n default:\n throw new TypeError('given KeyObject instance cannot be used for this algorithm');\n }\n if (alg.startsWith('RSA-OAEP')) {\n return keyObject.toCryptoKey({\n name: 'RSA-OAEP',\n hash,\n }, extractable, isPublic ? ['encrypt'] : ['decrypt']);\n }\n cryptoKey = keyObject.toCryptoKey({\n name: alg.startsWith('PS') ? 'RSA-PSS' : 'RSASSA-PKCS1-v1_5',\n hash,\n }, extractable, [isPublic ? 'verify' : 'sign']);\n }\n if (keyObject.asymmetricKeyType === 'ec') {\n const nist = new Map([\n ['prime256v1', 'P-256'],\n ['secp384r1', 'P-384'],\n ['secp521r1', 'P-521'],\n ]);\n const namedCurve = nist.get(keyObject.asymmetricKeyDetails?.namedCurve);\n if (!namedCurve) {\n throw new TypeError('given KeyObject instance cannot be used for this algorithm');\n }\n if (alg === 'ES256' && namedCurve === 'P-256') {\n cryptoKey = keyObject.toCryptoKey({\n name: 'ECDSA',\n namedCurve,\n }, extractable, [isPublic ? 'verify' : 'sign']);\n }\n if (alg === 'ES384' && namedCurve === 'P-384') {\n cryptoKey = keyObject.toCryptoKey({\n name: 'ECDSA',\n namedCurve,\n }, extractable, [isPublic ? 'verify' : 'sign']);\n }\n if (alg === 'ES512' && namedCurve === 'P-521') {\n cryptoKey = keyObject.toCryptoKey({\n name: 'ECDSA',\n namedCurve,\n }, extractable, [isPublic ? 'verify' : 'sign']);\n }\n if (alg.startsWith('ECDH-ES')) {\n cryptoKey = keyObject.toCryptoKey({\n name: 'ECDH',\n namedCurve,\n }, extractable, isPublic ? [] : ['deriveBits']);\n }\n }\n if (!cryptoKey) {\n throw new TypeError('given KeyObject instance cannot be used for this algorithm');\n }\n if (!cached) {\n cache.set(keyObject, { [alg]: cryptoKey });\n }\n else {\n cached[alg] = cryptoKey;\n }\n return cryptoKey;\n};\nexport async function normalizeKey(key, alg) {\n if (key instanceof Uint8Array) {\n return key;\n }\n if (isCryptoKey(key)) {\n return key;\n }\n if (isKeyObject(key)) {\n if (key.type === 'secret') {\n return key.export();\n }\n if ('toCryptoKey' in key && typeof key.toCryptoKey === 'function') {\n try {\n return handleKeyObject(key, alg);\n }\n catch (err) {\n if (err instanceof TypeError) {\n throw err;\n }\n }\n }\n let jwk = key.export({ format: 'jwk' });\n return handleJWK(key, jwk, alg);\n }\n if (isJWK(key)) {\n if (key.k) {\n return decode(key.k);\n }\n return handleJWK(key, key, alg, true);\n }\n throw new Error('unreachable');\n}\n","import { withAlg as invalidKeyInput } from './invalid_key_input.js';\nimport { isKeyLike } from './is_key_like.js';\nimport * as jwk from './is_jwk.js';\nconst tag = (key) => key?.[Symbol.toStringTag];\nconst jwkMatchesOp = (alg, key, usage) => {\n if (key.use !== undefined) {\n let expected;\n switch (usage) {\n case 'sign':\n case 'verify':\n expected = 'sig';\n break;\n case 'encrypt':\n case 'decrypt':\n expected = 'enc';\n break;\n }\n if (key.use !== expected) {\n throw new TypeError(`Invalid key for this operation, its \"use\" must be \"${expected}\" when present`);\n }\n }\n if (key.alg !== undefined && key.alg !== alg) {\n throw new TypeError(`Invalid key for this operation, its \"alg\" must be \"${alg}\" when present`);\n }\n if (Array.isArray(key.key_ops)) {\n let expectedKeyOp;\n switch (true) {\n case usage === 'sign' || usage === 'verify':\n case alg === 'dir':\n case alg.includes('CBC-HS'):\n expectedKeyOp = usage;\n break;\n case alg.startsWith('PBES2'):\n expectedKeyOp = 'deriveBits';\n break;\n case /^A\\d{3}(?:GCM)?(?:KW)?$/.test(alg):\n if (!alg.includes('GCM') && alg.endsWith('KW')) {\n expectedKeyOp = usage === 'encrypt' ? 'wrapKey' : 'unwrapKey';\n }\n else {\n expectedKeyOp = usage;\n }\n break;\n case usage === 'encrypt' && alg.startsWith('RSA'):\n expectedKeyOp = 'wrapKey';\n break;\n case usage === 'decrypt':\n expectedKeyOp = alg.startsWith('RSA') ? 'unwrapKey' : 'deriveBits';\n break;\n }\n if (expectedKeyOp && key.key_ops?.includes?.(expectedKeyOp) === false) {\n throw new TypeError(`Invalid key for this operation, its \"key_ops\" must include \"${expectedKeyOp}\" when present`);\n }\n }\n return true;\n};\nconst symmetricTypeCheck = (alg, key, usage) => {\n if (key instanceof Uint8Array)\n return;\n if (jwk.isJWK(key)) {\n if (jwk.isSecretJWK(key) && jwkMatchesOp(alg, key, usage))\n return;\n throw new TypeError(`JSON Web Key for symmetric algorithms must have JWK \"kty\" (Key Type) equal to \"oct\" and the JWK \"k\" (Key Value) present`);\n }\n if (!isKeyLike(key)) {\n throw new TypeError(invalidKeyInput(alg, key, 'CryptoKey', 'KeyObject', 'JSON Web Key', 'Uint8Array'));\n }\n if (key.type !== 'secret') {\n throw new TypeError(`${tag(key)} instances for symmetric algorithms must be of type \"secret\"`);\n }\n};\nconst asymmetricTypeCheck = (alg, key, usage) => {\n if (jwk.isJWK(key)) {\n switch (usage) {\n case 'decrypt':\n case 'sign':\n if (jwk.isPrivateJWK(key) && jwkMatchesOp(alg, key, usage))\n return;\n throw new TypeError(`JSON Web Key for this operation be a private JWK`);\n case 'encrypt':\n case 'verify':\n if (jwk.isPublicJWK(key) && jwkMatchesOp(alg, key, usage))\n return;\n throw new TypeError(`JSON Web Key for this operation be a public JWK`);\n }\n }\n if (!isKeyLike(key)) {\n throw new TypeError(invalidKeyInput(alg, key, 'CryptoKey', 'KeyObject', 'JSON Web Key'));\n }\n if (key.type === 'secret') {\n throw new TypeError(`${tag(key)} instances for asymmetric algorithms must not be of type \"secret\"`);\n }\n if (key.type === 'public') {\n switch (usage) {\n case 'sign':\n throw new TypeError(`${tag(key)} instances for asymmetric algorithm signing must be of type \"private\"`);\n case 'decrypt':\n throw new TypeError(`${tag(key)} instances for asymmetric algorithm decryption must be of type \"private\"`);\n }\n }\n if (key.type === 'private') {\n switch (usage) {\n case 'verify':\n throw new TypeError(`${tag(key)} instances for asymmetric algorithm verifying must be of type \"public\"`);\n case 'encrypt':\n throw new TypeError(`${tag(key)} instances for asymmetric algorithm encryption must be of type \"public\"`);\n }\n }\n};\nexport function checkKeyType(alg, key, usage) {\n switch (alg.substring(0, 2)) {\n case 'A1':\n case 'A2':\n case 'di':\n case 'HS':\n case 'PB':\n symmetricTypeCheck(alg, key, usage);\n break;\n default:\n asymmetricTypeCheck(alg, key, usage);\n }\n}\n","import { JOSENotSupported } from '../util/errors.js';\nexport function subtleAlgorithm(alg, algorithm) {\n const hash = `SHA-${alg.slice(-3)}`;\n switch (alg) {\n case 'HS256':\n case 'HS384':\n case 'HS512':\n return { hash, name: 'HMAC' };\n case 'PS256':\n case 'PS384':\n case 'PS512':\n return { hash, name: 'RSA-PSS', saltLength: parseInt(alg.slice(-3), 10) >> 3 };\n case 'RS256':\n case 'RS384':\n case 'RS512':\n return { hash, name: 'RSASSA-PKCS1-v1_5' };\n case 'ES256':\n case 'ES384':\n case 'ES512':\n return { hash, name: 'ECDSA', namedCurve: algorithm.namedCurve };\n case 'Ed25519':\n case 'EdDSA':\n return { name: 'Ed25519' };\n case 'ML-DSA-44':\n case 'ML-DSA-65':\n case 'ML-DSA-87':\n return { name: alg };\n default:\n throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);\n }\n}\n","import { checkSigCryptoKey } from './crypto_key.js';\nimport { invalidKeyInput } from './invalid_key_input.js';\nexport async function getSigKey(alg, key, usage) {\n if (key instanceof Uint8Array) {\n if (!alg.startsWith('HS')) {\n throw new TypeError(invalidKeyInput(key, 'CryptoKey', 'KeyObject', 'JSON Web Key'));\n }\n return crypto.subtle.importKey('raw', key, { hash: `SHA-${alg.slice(-3)}`, name: 'HMAC' }, false, [usage]);\n }\n checkSigCryptoKey(key, alg, usage);\n return key;\n}\n","import { JWTClaimValidationFailed, JWTExpired, JWTInvalid } from '../util/errors.js';\nimport { encoder, decoder } from './buffer_utils.js';\nimport { isObject } from './is_object.js';\nconst epoch = (date) => Math.floor(date.getTime() / 1000);\nconst minute = 60;\nconst hour = minute * 60;\nconst day = hour * 24;\nconst week = day * 7;\nconst year = day * 365.25;\nconst REGEX = /^(\\+|\\-)? ?(\\d+|\\d+\\.\\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i;\nexport function secs(str) {\n const matched = REGEX.exec(str);\n if (!matched || (matched[4] && matched[1])) {\n throw new TypeError('Invalid time period format');\n }\n const value = parseFloat(matched[2]);\n const unit = matched[3].toLowerCase();\n let numericDate;\n switch (unit) {\n case 'sec':\n case 'secs':\n case 'second':\n case 'seconds':\n case 's':\n numericDate = Math.round(value);\n break;\n case 'minute':\n case 'minutes':\n case 'min':\n case 'mins':\n case 'm':\n numericDate = Math.round(value * minute);\n break;\n case 'hour':\n case 'hours':\n case 'hr':\n case 'hrs':\n case 'h':\n numericDate = Math.round(value * hour);\n break;\n case 'day':\n case 'days':\n case 'd':\n numericDate = Math.round(value * day);\n break;\n case 'week':\n case 'weeks':\n case 'w':\n numericDate = Math.round(value * week);\n break;\n default:\n numericDate = Math.round(value * year);\n break;\n }\n if (matched[1] === '-' || matched[4] === 'ago') {\n return -numericDate;\n }\n return numericDate;\n}\nfunction validateInput(label, input) {\n if (!Number.isFinite(input)) {\n throw new TypeError(`Invalid ${label} input`);\n }\n return input;\n}\nconst normalizeTyp = (value) => {\n if (value.includes('/')) {\n return value.toLowerCase();\n }\n return `application/${value.toLowerCase()}`;\n};\nconst checkAudiencePresence = (audPayload, audOption) => {\n if (typeof audPayload === 'string') {\n return audOption.includes(audPayload);\n }\n if (Array.isArray(audPayload)) {\n return audOption.some(Set.prototype.has.bind(new Set(audPayload)));\n }\n return false;\n};\nexport function validateClaimsSet(protectedHeader, encodedPayload, options = {}) {\n let payload;\n try {\n payload = JSON.parse(decoder.decode(encodedPayload));\n }\n catch {\n }\n if (!isObject(payload)) {\n throw new JWTInvalid('JWT Claims Set must be a top-level JSON object');\n }\n const { typ } = options;\n if (typ &&\n (typeof protectedHeader.typ !== 'string' ||\n normalizeTyp(protectedHeader.typ) !== normalizeTyp(typ))) {\n throw new JWTClaimValidationFailed('unexpected \"typ\" JWT header value', payload, 'typ', 'check_failed');\n }\n const { requiredClaims = [], issuer, subject, audience, maxTokenAge } = options;\n const presenceCheck = [...requiredClaims];\n if (maxTokenAge !== undefined)\n presenceCheck.push('iat');\n if (audience !== undefined)\n presenceCheck.push('aud');\n if (subject !== undefined)\n presenceCheck.push('sub');\n if (issuer !== undefined)\n presenceCheck.push('iss');\n for (const claim of new Set(presenceCheck.reverse())) {\n if (!(claim in payload)) {\n throw new JWTClaimValidationFailed(`missing required \"${claim}\" claim`, payload, claim, 'missing');\n }\n }\n if (issuer &&\n !(Array.isArray(issuer) ? issuer : [issuer]).includes(payload.iss)) {\n throw new JWTClaimValidationFailed('unexpected \"iss\" claim value', payload, 'iss', 'check_failed');\n }\n if (subject && payload.sub !== subject) {\n throw new JWTClaimValidationFailed('unexpected \"sub\" claim value', payload, 'sub', 'check_failed');\n }\n if (audience &&\n !checkAudiencePresence(payload.aud, typeof audience === 'string' ? [audience] : audience)) {\n throw new JWTClaimValidationFailed('unexpected \"aud\" claim value', payload, 'aud', 'check_failed');\n }\n let tolerance;\n switch (typeof options.clockTolerance) {\n case 'string':\n tolerance = secs(options.clockTolerance);\n break;\n case 'number':\n tolerance = options.clockTolerance;\n break;\n case 'undefined':\n tolerance = 0;\n break;\n default:\n throw new TypeError('Invalid clockTolerance option type');\n }\n const { currentDate } = options;\n const now = epoch(currentDate || new Date());\n if ((payload.iat !== undefined || maxTokenAge) && typeof payload.iat !== 'number') {\n throw new JWTClaimValidationFailed('\"iat\" claim must be a number', payload, 'iat', 'invalid');\n }\n if (payload.nbf !== undefined) {\n if (typeof payload.nbf !== 'number') {\n throw new JWTClaimValidationFailed('\"nbf\" claim must be a number', payload, 'nbf', 'invalid');\n }\n if (payload.nbf > now + tolerance) {\n throw new JWTClaimValidationFailed('\"nbf\" claim timestamp check failed', payload, 'nbf', 'check_failed');\n }\n }\n if (payload.exp !== undefined) {\n if (typeof payload.exp !== 'number') {\n throw new JWTClaimValidationFailed('\"exp\" claim must be a number', payload, 'exp', 'invalid');\n }\n if (payload.exp <= now - tolerance) {\n throw new JWTExpired('\"exp\" claim timestamp check failed', payload, 'exp', 'check_failed');\n }\n }\n if (maxTokenAge) {\n const age = now - payload.iat;\n const max = typeof maxTokenAge === 'number' ? maxTokenAge : secs(maxTokenAge);\n if (age - tolerance > max) {\n throw new JWTExpired('\"iat\" claim timestamp check failed (too far in the past)', payload, 'iat', 'check_failed');\n }\n if (age < 0 - tolerance) {\n throw new JWTClaimValidationFailed('\"iat\" claim timestamp check failed (it should be in the past)', payload, 'iat', 'check_failed');\n }\n }\n return payload;\n}\nexport class JWTClaimsBuilder {\n #payload;\n constructor(payload) {\n if (!isObject(payload)) {\n throw new TypeError('JWT Claims Set MUST be an object');\n }\n this.#payload = structuredClone(payload);\n }\n data() {\n return encoder.encode(JSON.stringify(this.#payload));\n }\n get iss() {\n return this.#payload.iss;\n }\n set iss(value) {\n this.#payload.iss = value;\n }\n get sub() {\n return this.#payload.sub;\n }\n set sub(value) {\n this.#payload.sub = value;\n }\n get aud() {\n return this.#payload.aud;\n }\n set aud(value) {\n this.#payload.aud = value;\n }\n set jti(value) {\n this.#payload.jti = value;\n }\n set nbf(value) {\n if (typeof value === 'number') {\n this.#payload.nbf = validateInput('setNotBefore', value);\n }\n else if (value instanceof Date) {\n this.#payload.nbf = validateInput('setNotBefore', epoch(value));\n }\n else {\n this.#payload.nbf = epoch(new Date()) + secs(value);\n }\n }\n set exp(value) {\n if (typeof value === 'number') {\n this.#payload.exp = validateInput('setExpirationTime', value);\n }\n else if (value instanceof Date) {\n this.#payload.exp = validateInput('setExpirationTime', epoch(value));\n }\n else {\n this.#payload.exp = epoch(new Date()) + secs(value);\n }\n }\n set iat(value) {\n if (value === undefined) {\n this.#payload.iat = epoch(new Date());\n }\n else if (value instanceof Date) {\n this.#payload.iat = validateInput('setIssuedAt', epoch(value));\n }\n else if (typeof value === 'string') {\n this.#payload.iat = validateInput('setIssuedAt', epoch(new Date()) + secs(value));\n }\n else {\n this.#payload.iat = validateInput('setIssuedAt', value);\n }\n }\n}\n","import { subtleAlgorithm } from './subtle_dsa.js';\nimport { checkKeyLength } from './check_key_length.js';\nimport { getSigKey } from './get_sign_verify_key.js';\nexport async function sign(alg, key, data) {\n const cryptoKey = await getSigKey(alg, key, 'sign');\n checkKeyLength(alg, cryptoKey);\n const signature = await crypto.subtle.sign(subtleAlgorithm(alg, cryptoKey.algorithm), cryptoKey, data);\n return new Uint8Array(signature);\n}\n","import { encode as b64u } from '../../util/base64url.js';\nimport { sign } from '../../lib/sign.js';\nimport { isDisjoint } from '../../lib/is_disjoint.js';\nimport { JWSInvalid } from '../../util/errors.js';\nimport { concat, encode } from '../../lib/buffer_utils.js';\nimport { checkKeyType } from '../../lib/check_key_type.js';\nimport { validateCrit } from '../../lib/validate_crit.js';\nimport { normalizeKey } from '../../lib/normalize_key.js';\nexport class FlattenedSign {\n #payload;\n #protectedHeader;\n #unprotectedHeader;\n constructor(payload) {\n if (!(payload instanceof Uint8Array)) {\n throw new TypeError('payload must be an instance of Uint8Array');\n }\n this.#payload = payload;\n }\n setProtectedHeader(protectedHeader) {\n if (this.#protectedHeader) {\n throw new TypeError('setProtectedHeader can only be called once');\n }\n this.#protectedHeader = protectedHeader;\n return this;\n }\n setUnprotectedHeader(unprotectedHeader) {\n if (this.#unprotectedHeader) {\n throw new TypeError('setUnprotectedHeader can only be called once');\n }\n this.#unprotectedHeader = unprotectedHeader;\n return this;\n }\n async sign(key, options) {\n if (!this.#protectedHeader && !this.#unprotectedHeader) {\n throw new JWSInvalid('either setProtectedHeader or setUnprotectedHeader must be called before #sign()');\n }\n if (!isDisjoint(this.#protectedHeader, this.#unprotectedHeader)) {\n throw new JWSInvalid('JWS Protected and JWS Unprotected Header Parameter names must be disjoint');\n }\n const joseHeader = {\n ...this.#protectedHeader,\n ...this.#unprotectedHeader,\n };\n const extensions = validateCrit(JWSInvalid, new Map([['b64', true]]), options?.crit, this.#protectedHeader, joseHeader);\n let b64 = true;\n if (extensions.has('b64')) {\n b64 = this.#protectedHeader.b64;\n if (typeof b64 !== 'boolean') {\n throw new JWSInvalid('The \"b64\" (base64url-encode payload) Header Parameter must be a boolean');\n }\n }\n const { alg } = joseHeader;\n if (typeof alg !== 'string' || !alg) {\n throw new JWSInvalid('JWS \"alg\" (Algorithm) Header Parameter missing or invalid');\n }\n checkKeyType(alg, key, 'sign');\n let payloadS;\n let payloadB;\n if (b64) {\n payloadS = b64u(this.#payload);\n payloadB = encode(payloadS);\n }\n else {\n payloadB = this.#payload;\n payloadS = '';\n }\n let protectedHeaderString;\n let protectedHeaderBytes;\n if (this.#protectedHeader) {\n protectedHeaderString = b64u(JSON.stringify(this.#protectedHeader));\n protectedHeaderBytes = encode(protectedHeaderString);\n }\n else {\n protectedHeaderString = '';\n protectedHeaderBytes = new Uint8Array();\n }\n const data = concat(protectedHeaderBytes, encode('.'), payloadB);\n const k = await normalizeKey(key, alg);\n const signature = await sign(alg, k, data);\n const jws = {\n signature: b64u(signature),\n payload: payloadS,\n };\n if (this.#unprotectedHeader) {\n jws.header = this.#unprotectedHeader;\n }\n if (this.#protectedHeader) {\n jws.protected = protectedHeaderString;\n }\n return jws;\n }\n}\n","import { FlattenedSign } from '../flattened/sign.js';\nexport class CompactSign {\n #flattened;\n constructor(payload) {\n this.#flattened = new FlattenedSign(payload);\n }\n setProtectedHeader(protectedHeader) {\n this.#flattened.setProtectedHeader(protectedHeader);\n return this;\n }\n async sign(key, options) {\n const jws = await this.#flattened.sign(key, options);\n if (jws.payload === undefined) {\n throw new TypeError('use the flattened module for creating JWS with b64: false');\n }\n return `${jws.protected}.${jws.payload}.${jws.signature}`;\n }\n}\n","import { CompactSign } from '../jws/compact/sign.js';\nimport { JWTInvalid } from '../util/errors.js';\nimport { JWTClaimsBuilder } from '../lib/jwt_claims_set.js';\nexport class SignJWT {\n #protectedHeader;\n #jwt;\n constructor(payload = {}) {\n this.#jwt = new JWTClaimsBuilder(payload);\n }\n setIssuer(issuer) {\n this.#jwt.iss = issuer;\n return this;\n }\n setSubject(subject) {\n this.#jwt.sub = subject;\n return this;\n }\n setAudience(audience) {\n this.#jwt.aud = audience;\n return this;\n }\n setJti(jwtId) {\n this.#jwt.jti = jwtId;\n return this;\n }\n setNotBefore(input) {\n this.#jwt.nbf = input;\n return this;\n }\n setExpirationTime(input) {\n this.#jwt.exp = input;\n return this;\n }\n setIssuedAt(input) {\n this.#jwt.iat = input;\n return this;\n }\n setProtectedHeader(protectedHeader) {\n this.#protectedHeader = protectedHeader;\n return this;\n }\n async sign(key, options) {\n const sig = new CompactSign(this.#jwt.data());\n sig.setProtectedHeader(this.#protectedHeader);\n if (Array.isArray(this.#protectedHeader?.crit) &&\n this.#protectedHeader.crit.includes('b64') &&\n this.#protectedHeader.b64 === false) {\n throw new JWTInvalid('JWTs MUST NOT use unencoded payload');\n }\n return sig.sign(key, options);\n }\n}\n","import { importPKCS8, SignJWT } from \"jose\";\n\n/**\n * Deep module: Hides JWT signing and HTTP complexity behind simple interface\n * Following Ousterhout's principle: \"Pull complexity downward\"\n */\nexport class ApiClient {\n\tprivate readonly baseUrl: string;\n\tprivate readonly privateKey: string;\n\tprivate readonly organizationId: string;\n\tprivate readonly defaultTenantId?: string;\n\tprivate readonly additionalHeaders?: Record<string, string>;\n\tprivate readonly fetchImpl: typeof fetch;\n\tprivate cachedPrivateKey?: Awaited<ReturnType<typeof importPKCS8>>;\n\n\tconstructor(\n\t\tbaseUrl: string,\n\t\tprivateKey: string,\n\t\torganizationId: string,\n\t\toptions?: {\n\t\t\tdefaultTenantId?: string;\n\t\t\tadditionalHeaders?: Record<string, string>;\n\t\t\tfetch?: typeof fetch;\n\t\t},\n\t) {\n\t\tif (!baseUrl) {\n\t\t\tthrow new Error(\"Base URL is required\");\n\t\t}\n\t\tif (!privateKey) {\n\t\t\tthrow new Error(\"Private key is required\");\n\t\t}\n\t\tif (!organizationId) {\n\t\t\tthrow new Error(\"Organization ID is required\");\n\t\t}\n\n\t\tthis.baseUrl = baseUrl.replace(/\\/+$/, \"\");\n\t\tthis.privateKey = privateKey;\n\t\tthis.organizationId = organizationId;\n\t\tthis.defaultTenantId = options?.defaultTenantId;\n\t\tthis.additionalHeaders = options?.additionalHeaders;\n\t\tthis.fetchImpl = options?.fetch ?? globalThis.fetch;\n\n\t\tif (!this.fetchImpl) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Fetch implementation not found. Provide options.fetch or use Node 18+.\",\n\t\t\t);\n\t\t}\n\t}\n\n\tgetDefaultTenantId(): string | undefined {\n\t\treturn this.defaultTenantId;\n\t}\n\n\tasync get<T>(\n\t\tpath: string,\n\t\ttenantId: string,\n\t\tuserId?: string,\n\t\tscopes?: string[],\n\t\tsignal?: AbortSignal,\n\t\tsessionId?: string,\n\t): Promise<T> {\n\t\treturn await this.request<T>(path, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: await this.buildHeaders(tenantId, userId, scopes, false, sessionId),\n\t\t\tsignal,\n\t\t});\n\t}\n\n\tasync post<T>(\n\t\tpath: string,\n\t\tbody: unknown,\n\t\ttenantId: string,\n\t\tuserId?: string,\n\t\tscopes?: string[],\n\t\tsignal?: AbortSignal,\n\t\tsessionId?: string,\n\t): Promise<T> {\n\t\treturn await this.request<T>(path, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: await this.buildHeaders(tenantId, userId, scopes, true, sessionId),\n\t\t\tbody: JSON.stringify(body ?? {}),\n\t\t\tsignal,\n\t\t});\n\t}\n\n\tasync put<T>(\n\t\tpath: string,\n\t\tbody: unknown,\n\t\ttenantId: string,\n\t\tuserId?: string,\n\t\tscopes?: string[],\n\t\tsignal?: AbortSignal,\n\t\tsessionId?: string,\n\t): Promise<T> {\n\t\treturn await this.request<T>(path, {\n\t\t\tmethod: \"PUT\",\n\t\t\theaders: await this.buildHeaders(tenantId, userId, scopes, true, sessionId),\n\t\t\tbody: JSON.stringify(body ?? {}),\n\t\t\tsignal,\n\t\t});\n\t}\n\n\tasync delete<T = void>(\n\t\tpath: string,\n\t\ttenantId: string,\n\t\tuserId?: string,\n\t\tscopes?: string[],\n\t\tsignal?: AbortSignal,\n\t\tsessionId?: string,\n\t): Promise<T> {\n\t\treturn await this.request<T>(path, {\n\t\t\tmethod: \"DELETE\",\n\t\t\theaders: await this.buildHeaders(tenantId, userId, scopes, false, sessionId),\n\t\t\tsignal,\n\t\t});\n\t}\n\n\tprivate async request<T>(path: string, init: RequestInit): Promise<T> {\n\t\tconst response = await this.fetchImpl(`${this.baseUrl}${path}`, init);\n\t\tconst text = await response.text();\n\t\tlet json: any;\n\t\ttry {\n\t\t\tjson = text ? JSON.parse(text) : undefined;\n\t\t} catch {\n\t\t\tjson = undefined;\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\tconst error = new Error(\n\t\t\t\tjson?.error || response.statusText || \"Request failed\",\n\t\t\t);\n\t\t\t(error as any).status = response.status;\n\t\t\tif (json?.details) (error as any).details = json.details;\n\t\t\tthrow error;\n\t\t}\n\n\t\treturn json as T;\n\t}\n\n\tprivate async buildHeaders(\n\t\ttenantId: string,\n\t\tuserId?: string,\n\t\tscopes?: string[],\n\t\tincludeJson: boolean = true,\n\t\tsessionId?: string,\n\t): Promise<Record<string, string>> {\n\t\tconst token = await this.generateJWT(tenantId, userId, scopes);\n\t\tconst headers: Record<string, string> = {\n\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\tAccept: \"application/json\",\n\t\t};\n\t\tif (includeJson) {\n\t\t\theaders[\"Content-Type\"] = \"application/json\";\n\t\t}\n\t\tif (sessionId) {\n\t\t\theaders[\"x-session-id\"] = sessionId;\n\t\t}\n\t\tif (this.additionalHeaders) {\n\t\t\tObject.assign(headers, this.additionalHeaders);\n\t\t}\n\t\treturn headers;\n\t}\n\n\tprivate async generateJWT(\n\t\ttenantId: string,\n\t\tuserId?: string,\n\t\tscopes?: string[],\n\t): Promise<string> {\n\t\tif (!this.cachedPrivateKey) {\n\t\t\tthis.cachedPrivateKey = await importPKCS8(this.privateKey, \"RS256\");\n\t\t}\n\n\t\tconst payload: Record<string, unknown> = {\n\t\t\torganizationId: this.organizationId,\n\t\t\ttenantId,\n\t\t};\n\n\t\tif (userId) payload.userId = userId;\n\t\tif (scopes?.length) payload.scopes = scopes;\n\n\t\treturn await new SignJWT(payload)\n\t\t\t.setProtectedHeader({ alg: \"RS256\" })\n\t\t\t.setIssuedAt()\n\t\t\t.setExpirationTime(\"1h\")\n\t\t\t.sign(this.cachedPrivateKey);\n\t}\n}\n","import type { DatabaseAdapter, DatabaseDialect } from \"../adapters/types\";\n\nexport type ParamValue = string | number | boolean | string[] | number[];\nexport type ParamRecord = Record<string, ParamValue>;\n\nexport interface DatabaseMetadata {\n\tname: string;\n\tdialect: DatabaseDialect;\n\tdescription?: string;\n\ttags?: string[];\n\ttenantFieldName?: string;\n\ttenantFieldType?: string;\n\tenforceTenantIsolation?: boolean;\n}\n\nexport interface DatabaseExecutionResult {\n\trows: Array<Record<string, unknown>>;\n\tfields: string[];\n}\n\n/**\n * Deep module: Hides SQL execution complexity and tenant isolation logic\n * Following Ousterhout's principle: \"Information hiding\"\n */\nexport class QueryEngine {\n\tprivate databases = new Map<string, DatabaseAdapter>();\n\tprivate databaseMetadata = new Map<string, DatabaseMetadata>();\n\tprivate defaultDatabase?: string;\n\n\tattachDatabase(name: string, adapter: DatabaseAdapter, metadata: DatabaseMetadata): void {\n\t\tthis.databases.set(name, adapter);\n\t\tthis.databaseMetadata.set(name, metadata);\n\t\tif (!this.defaultDatabase) {\n\t\t\tthis.defaultDatabase = name;\n\t\t}\n\t}\n\n\tgetDatabase(name?: string): DatabaseAdapter {\n\t\tconst dbName = name ?? this.defaultDatabase;\n\t\tif (!dbName) {\n\t\t\tthrow new Error(\"No database attached.\");\n\t\t}\n\t\tconst adapter = this.databases.get(dbName);\n\t\tif (!adapter) {\n\t\t\tthrow new Error(\n\t\t\t\t`Database '${dbName}' not found. Attached: ${Array.from(\n\t\t\t\t\tthis.databases.keys(),\n\t\t\t\t).join(\", \")}`,\n\t\t\t);\n\t\t}\n\t\treturn adapter;\n\t}\n\n\tgetDatabaseMetadata(name?: string): DatabaseMetadata | undefined {\n\t\tconst dbName = name ?? this.defaultDatabase;\n\t\tif (!dbName) return undefined;\n\t\treturn this.databaseMetadata.get(dbName);\n\t}\n\n\tgetDefaultDatabase(): string | undefined {\n\t\treturn this.defaultDatabase;\n\t}\n\n\tasync validateAndExecute(\n\t\tsql: string,\n\t\tparams: ParamRecord,\n\t\tdatabaseName: string,\n\t\ttenantId: string,\n\t): Promise<DatabaseExecutionResult> {\n\t\tconst adapter = this.getDatabase(databaseName);\n\t\tconst metadata = this.getDatabaseMetadata(databaseName);\n\n\t\t// Apply tenant isolation if configured\n\t\tlet finalSql = sql;\n\t\tif (metadata) {\n\t\t\tfinalSql = this.ensureTenantIsolation(sql, params, metadata, tenantId);\n\t\t}\n\n\t\t// Validate SQL\n\t\tawait adapter.validate(finalSql, params);\n\n\t\t// Execute\n\t\tconst result = await adapter.execute(finalSql, params);\n\t\treturn {\n\t\t\trows: result.rows,\n\t\t\tfields: result.fields,\n\t\t};\n\t}\n\n\tasync execute(\n\t\tsql: string,\n\t\tparams: ParamRecord | undefined,\n\t\tdatabaseName?: string,\n\t): Promise<Array<Record<string, unknown>>> {\n\t\ttry {\n\t\t\tconst adapter = this.getDatabase(databaseName);\n\t\t\tconst result = await adapter.execute(sql, params);\n\t\t\treturn result.rows;\n\t\t} catch (error) {\n\t\t\tconsole.warn(\n\t\t\t\t`Failed to execute SQL locally for database '${databaseName}':`,\n\t\t\t\terror,\n\t\t\t);\n\t\t\treturn [];\n\t\t}\n\t}\n\n\tmapGeneratedParams(params: Array<Record<string, unknown>>): ParamRecord {\n\t\tconst record: ParamRecord = {};\n\n\t\tparams.forEach((param, index) => {\n\t\t\tconst value = param.value as ParamValue | undefined;\n\t\t\tif (value === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst nameCandidate =\n\t\t\t\t(typeof param.name === \"string\" && param.name.trim()) ||\n\t\t\t\t(typeof param.placeholder === \"string\" && param.placeholder.trim()) ||\n\t\t\t\t(typeof param.position === \"number\" && String(param.position)) ||\n\t\t\t\tString(index + 1);\n\t\t\tconst key = nameCandidate.replace(/[{}:$]/g, \"\").trim();\n\t\t\trecord[key] = value;\n\t\t});\n\n\t\treturn record;\n\t}\n\n\tprivate ensureTenantIsolation(\n\t\tsql: string,\n\t\tparams: ParamRecord,\n\t\tmetadata: DatabaseMetadata,\n\t\ttenantId: string,\n\t): string {\n\t\tif (\n\t\t\t!metadata.tenantFieldName ||\n\t\t\tmetadata.enforceTenantIsolation === false\n\t\t) {\n\t\t\treturn sql;\n\t\t}\n\n\t\tconst tenantField = metadata.tenantFieldName;\n\t\tconst paramKey = tenantField;\n\t\tparams[paramKey] = tenantId;\n\n\t\tconst normalizedSql = sql.toLowerCase();\n\t\tif (normalizedSql.includes(tenantField.toLowerCase())) {\n\t\t\treturn sql;\n\t\t}\n\n\t\tconst tenantPredicate =\n\t\t\tmetadata.dialect === \"clickhouse\"\n\t\t\t\t? `${tenantField} = {${tenantField}:${metadata.tenantFieldType ?? \"String\"}}`\n\t\t\t\t: `${tenantField} = '${tenantId}'`;\n\n\t\tif (/\\bwhere\\b/i.test(sql)) {\n\t\t\treturn sql.replace(\n\t\t\t\t/\\bwhere\\b/i,\n\t\t\t\t(match) => `${match} ${tenantPredicate} AND `,\n\t\t\t);\n\t\t}\n\n\t\treturn `${sql} WHERE ${tenantPredicate}`;\n\t}\n}\n","import type { ApiClient } from \"../core/client\";\nimport type { ParamRecord, QueryEngine } from \"../core/query-engine\";\n\nexport interface SdkChart {\n\tid: string;\n\ttitle: string;\n\tdescription: string | null;\n\tsql: string;\n\tsql_params: Record<string, unknown> | null;\n\tvega_lite_spec: Record<string, unknown>;\n\tquery_id: string | null;\n\torganization_id: string | null;\n\ttenant_id: string | null;\n\tuser_id: string | null;\n\tcreated_at: string | null;\n\tupdated_at: string | null;\n\tactive?: boolean;\n\ttarget_db?: string | null;\n}\n\nexport interface ChartCreateInput {\n\ttitle: string;\n\tdescription?: string;\n\tsql: string;\n\tsql_params?: Record<string, unknown>;\n\tvega_lite_spec: Record<string, unknown>;\n\tquery_id?: string;\n\ttarget_db?: string;\n}\n\nexport interface ChartUpdateInput {\n\ttitle?: string;\n\tdescription?: string;\n\tsql?: string;\n\tsql_params?: Record<string, unknown>;\n\tvega_lite_spec?: Record<string, unknown>;\n\ttarget_db?: string;\n}\n\nexport interface PaginationQuery {\n\tpage?: number;\n\tlimit?: number;\n}\n\nexport interface PaginationInfo {\n\tpage: number;\n\tlimit: number;\n\ttotal: number;\n\ttotalPages: number;\n\thasNext: boolean;\n\thasPrev: boolean;\n}\n\nexport interface PaginatedResponse<T> {\n\tdata: T[];\n\tpagination: PaginationInfo;\n}\n\nexport interface ChartListOptions {\n\ttenantId?: string;\n\tuserId?: string;\n\tscopes?: string[];\n\tpagination?: PaginationQuery;\n\tsortBy?: \"title\" | \"user_id\" | \"created_at\" | \"updated_at\";\n\tsortDir?: \"asc\" | \"desc\";\n\ttitle?: string;\n\tuserFilter?: string;\n\tcreatedFrom?: string;\n\tcreatedTo?: string;\n\tupdatedFrom?: string;\n\tupdatedTo?: string;\n\tincludeData?: boolean;\n}\n\ninterface RequestOptions {\n\ttenantId?: string;\n\tuserId?: string;\n\tscopes?: string[];\n}\n\n/**\n * Route module for Chart CRUD operations\n * Simple pass-through to backend with optional data hydration\n */\nexport async function createChart(\n\tclient: ApiClient,\n\tbody: ChartCreateInput,\n\toptions?: RequestOptions,\n\tsignal?: AbortSignal,\n): Promise<SdkChart> {\n\tconst tenantId = resolveTenantId(client, options?.tenantId);\n\treturn await client.post<SdkChart>(\n\t\t\"/charts\",\n\t\tbody,\n\t\ttenantId,\n\t\toptions?.userId,\n\t\toptions?.scopes,\n\t\tsignal,\n\t);\n}\n\nexport async function listCharts(\n\tclient: ApiClient,\n\tqueryEngine: QueryEngine,\n\toptions?: ChartListOptions,\n\tsignal?: AbortSignal,\n): Promise<PaginatedResponse<SdkChart>> {\n\tconst tenantId = resolveTenantId(client, options?.tenantId);\n\tconst params = new URLSearchParams();\n\tif (options?.pagination?.page)\n\t\tparams.set(\"page\", `${options.pagination.page}`);\n\tif (options?.pagination?.limit)\n\t\tparams.set(\"limit\", `${options.pagination.limit}`);\n\tif (options?.sortBy) params.set(\"sort_by\", options.sortBy);\n\tif (options?.sortDir) params.set(\"sort_dir\", options.sortDir);\n\tif (options?.title) params.set(\"title\", options.title);\n\tif (options?.userFilter) params.set(\"user_id\", options.userFilter);\n\tif (options?.createdFrom) params.set(\"created_from\", options.createdFrom);\n\tif (options?.createdTo) params.set(\"created_to\", options.createdTo);\n\tif (options?.updatedFrom) params.set(\"updated_from\", options.updatedFrom);\n\tif (options?.updatedTo) params.set(\"updated_to\", options.updatedTo);\n\n\tconst response = await client.get<PaginatedResponse<SdkChart>>(\n\t\t`/charts${params.toString() ? `?${params.toString()}` : \"\"}`,\n\t\ttenantId,\n\t\toptions?.userId,\n\t\toptions?.scopes,\n\t\tsignal,\n\t);\n\n\tif (options?.includeData) {\n\t\tresponse.data = await Promise.all(\n\t\t\tresponse.data.map(async (chart) => ({\n\t\t\t\t...chart,\n\t\t\t\tvega_lite_spec: {\n\t\t\t\t\t...chart.vega_lite_spec,\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tvalues: await queryEngine.execute(\n\t\t\t\t\t\t\tchart.sql,\n\t\t\t\t\t\t\t(chart.sql_params as ParamRecord | null) ?? undefined,\n\t\t\t\t\t\t\tchart.target_db ?? undefined,\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})),\n\t\t);\n\t}\n\n\treturn response;\n}\n\nexport async function getChart(\n\tclient: ApiClient,\n\tqueryEngine: QueryEngine,\n\tid: string,\n\toptions?: RequestOptions,\n\tsignal?: AbortSignal,\n): Promise<SdkChart> {\n\tconst tenantId = resolveTenantId(client, options?.tenantId);\n\tconst chart = await client.get<SdkChart>(\n\t\t`/charts/${encodeURIComponent(id)}`,\n\t\ttenantId,\n\t\toptions?.userId,\n\t\toptions?.scopes,\n\t\tsignal,\n\t);\n\n\treturn {\n\t\t...chart,\n\t\tvega_lite_spec: {\n\t\t\t...chart.vega_lite_spec,\n\t\t\tdata: {\n\t\t\t\tvalues: await queryEngine.execute(\n\t\t\t\t\tchart.sql,\n\t\t\t\t\t(chart.sql_params as ParamRecord | null) ?? undefined,\n\t\t\t\t\tchart.target_db ?? undefined,\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t};\n}\n\nexport async function updateChart(\n\tclient: ApiClient,\n\tid: string,\n\tbody: ChartUpdateInput,\n\toptions?: RequestOptions,\n\tsignal?: AbortSignal,\n): Promise<SdkChart> {\n\tconst tenantId = resolveTenantId(client, options?.tenantId);\n\treturn await client.put<SdkChart>(\n\t\t`/charts/${encodeURIComponent(id)}`,\n\t\tbody,\n\t\ttenantId,\n\t\toptions?.userId,\n\t\toptions?.scopes,\n\t\tsignal,\n\t);\n}\n\nexport async function deleteChart(\n\tclient: ApiClient,\n\tid: string,\n\toptions?: RequestOptions,\n\tsignal?: AbortSignal,\n): Promise<void> {\n\tconst tenantId = resolveTenantId(client, options?.tenantId);\n\tawait client.delete(\n\t\t`/charts/${encodeURIComponent(id)}`,\n\t\ttenantId,\n\t\toptions?.userId,\n\t\toptions?.scopes,\n\t\tsignal,\n\t);\n}\n\nfunction resolveTenantId(client: ApiClient, tenantId?: string): string {\n\tconst resolved = tenantId ?? client.getDefaultTenantId();\n\tif (!resolved) {\n\t\tthrow new Error(\n\t\t\t\"tenantId is required. Provide it per request or via defaultTenantId option.\",\n\t\t);\n\t}\n\treturn resolved;\n}\n","import type { ApiClient } from \"../core/client\";\nimport type { QueryEngine } from \"../core/query-engine\";\nimport * as charts from \"./charts\";\n\nexport interface SdkActiveChart {\n\tid: string;\n\tchart_id: string;\n\torder: number | null;\n\tmeta: Record<string, unknown> | null;\n\torganization_id: string | null;\n\ttenant_id: string | null;\n\tuser_id: string | null;\n\tcreated_at: string | null;\n\tupdated_at: string | null;\n\tchart?: charts.SdkChart | null;\n}\n\nexport interface ActiveChartCreateInput {\n\tchart_id: string;\n\torder?: number;\n\tmeta?: Record<string, unknown>;\n}\n\nexport interface ActiveChartUpdateInput {\n\tchart_id?: string;\n\torder?: number;\n\tmeta?: Record<string, unknown>;\n}\n\nexport interface ActiveChartListOptions extends charts.ChartListOptions {\n\twithData?: boolean;\n}\n\ninterface RequestOptions {\n\ttenantId?: string;\n\tuserId?: string;\n\tscopes?: string[];\n}\n\n/**\n * Route module for Active Chart CRUD operations\n * Simple pass-through to backend with optional chart data hydration\n */\nexport async function createActiveChart(\n\tclient: ApiClient,\n\tbody: ActiveChartCreateInput,\n\toptions?: RequestOptions,\n\tsignal?: AbortSignal,\n): Promise<SdkActiveChart> {\n\tconst tenantId = resolveTenantId(client, options?.tenantId);\n\treturn await client.post<SdkActiveChart>(\n\t\t\"/active-charts\",\n\t\tbody,\n\t\ttenantId,\n\t\toptions?.userId,\n\t\toptions?.scopes,\n\t\tsignal,\n\t);\n}\n\nexport async function listActiveCharts(\n\tclient: ApiClient,\n\tqueryEngine: QueryEngine,\n\toptions?: ActiveChartListOptions,\n\tsignal?: AbortSignal,\n): Promise<charts.PaginatedResponse<SdkActiveChart>> {\n\tconst tenantId = resolveTenantId(client, options?.tenantId);\n\tconst params = new URLSearchParams();\n\tif (options?.pagination?.page)\n\t\tparams.set(\"page\", `${options.pagination.page}`);\n\tif (options?.pagination?.limit)\n\t\tparams.set(\"limit\", `${options.pagination.limit}`);\n\tif (options?.sortBy) params.set(\"sort_by\", options.sortBy);\n\tif (options?.sortDir) params.set(\"sort_dir\", options.sortDir);\n\tif (options?.title) params.set(\"name\", options.title);\n\tif (options?.userFilter) params.set(\"user_id\", options.userFilter);\n\tif (options?.createdFrom) params.set(\"created_from\", options.createdFrom);\n\tif (options?.createdTo) params.set(\"created_to\", options.createdTo);\n\tif (options?.updatedFrom) params.set(\"updated_from\", options.updatedFrom);\n\tif (options?.updatedTo) params.set(\"updated_to\", options.updatedTo);\n\n\tconst response = await client.get<\n\t\tcharts.PaginatedResponse<SdkActiveChart>\n\t>(\n\t\t`/active-charts${params.toString() ? `?${params.toString()}` : \"\"}`,\n\t\ttenantId,\n\t\toptions?.userId,\n\t\toptions?.scopes,\n\t\tsignal,\n\t);\n\n\tif (options?.withData) {\n\t\tresponse.data = await Promise.all(\n\t\t\tresponse.data.map(async (active) => ({\n\t\t\t\t...active,\n\t\t\t\tchart: active.chart\n\t\t\t\t\t? await charts.getChart(\n\t\t\t\t\t\t\tclient,\n\t\t\t\t\t\t\tqueryEngine,\n\t\t\t\t\t\t\tactive.chart_id,\n\t\t\t\t\t\t\toptions,\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t)\n\t\t\t\t\t: null,\n\t\t\t})),\n\t\t);\n\t}\n\n\treturn response;\n}\n\nexport async function getActiveChart(\n\tclient: ApiClient,\n\tqueryEngine: QueryEngine,\n\tid: string,\n\toptions?: ActiveChartListOptions,\n\tsignal?: AbortSignal,\n): Promise<SdkActiveChart> {\n\tconst tenantId = resolveTenantId(client, options?.tenantId);\n\tconst active = await client.get<SdkActiveChart>(\n\t\t`/active-charts/${encodeURIComponent(id)}`,\n\t\ttenantId,\n\t\toptions?.userId,\n\t\toptions?.scopes,\n\t\tsignal,\n\t);\n\n\tif (options?.withData && active.chart_id) {\n\t\treturn {\n\t\t\t...active,\n\t\t\tchart: await charts.getChart(\n\t\t\t\tclient,\n\t\t\t\tqueryEngine,\n\t\t\t\tactive.chart_id,\n\t\t\t\toptions,\n\t\t\t\tsignal,\n\t\t\t),\n\t\t};\n\t}\n\n\treturn active;\n}\n\nexport async function updateActiveChart(\n\tclient: ApiClient,\n\tid: string,\n\tbody: ActiveChartUpdateInput,\n\toptions?: RequestOptions,\n\tsignal?: AbortSignal,\n): Promise<SdkActiveChart> {\n\tconst tenantId = resolveTenantId(client, options?.tenantId);\n\treturn await client.put<SdkActiveChart>(\n\t\t`/active-charts/${encodeURIComponent(id)}`,\n\t\tbody,\n\t\ttenantId,\n\t\toptions?.userId,\n\t\toptions?.scopes,\n\t\tsignal,\n\t);\n}\n\nexport async function deleteActiveChart(\n\tclient: ApiClient,\n\tid: string,\n\toptions?: RequestOptions,\n\tsignal?: AbortSignal,\n): Promise<void> {\n\tconst tenantId = resolveTenantId(client, options?.tenantId);\n\tawait client.delete(\n\t\t`/active-charts/${encodeURIComponent(id)}`,\n\t\ttenantId,\n\t\toptions?.userId,\n\t\toptions?.scopes,\n\t\tsignal,\n\t);\n}\n\nfunction resolveTenantId(client: ApiClient, tenantId?: string): string {\n\tconst resolved = tenantId ?? client.getDefaultTenantId();\n\tif (!resolved) {\n\t\tthrow new Error(\n\t\t\t\"tenantId is required. Provide it per request or via defaultTenantId option.\",\n\t\t);\n\t}\n\treturn resolved;\n}\n","import { randomUUID } from \"node:crypto\";\nimport type { ApiClient } from \"../core/client\";\nimport type { QueryEngine } from \"../core/query-engine\";\nimport type { SchemaIntrospection } from \"../schema/types\";\n\nexport interface IngestResponse {\n\tsuccess: boolean;\n\tmessage: string;\n\tchunks: number;\n\tchunks_with_annotations: number;\n\tschema_id?: string;\n\tschema_hash?: string;\n\tdrift_detected?: boolean;\n\tskipped?: boolean;\n}\n\nexport interface SchemaSyncOptions {\n\ttenantId?: string;\n\tuserId?: string;\n\tscopes?: string[];\n\ttables?: string[];\n}\n\ninterface SchemaIngestColumn {\n\tname: string;\n\tdata_type: string;\n\tis_primary_key: boolean;\n\tdescription: string;\n}\n\ninterface SchemaIngestTable {\n\ttable_name: string;\n\tdescription: string;\n\tcolumns: SchemaIngestColumn[];\n}\n\ninterface SchemaIngestRequest {\n\tdatabase: string;\n\tdialect: string;\n\ttables: SchemaIngestTable[];\n}\n\n/**\n * Route module for schema ingestion\n * Handles introspection and sync to backend\n */\nexport async function syncSchema(\n\tclient: ApiClient,\n\tqueryEngine: QueryEngine,\n\tdatabaseName: string,\n\toptions: SchemaSyncOptions,\n\tsignal?: AbortSignal,\n): Promise<IngestResponse> {\n\tconst tenantId = resolveTenantId(client, options.tenantId);\n\tconst adapter = queryEngine.getDatabase(databaseName);\n\n\tconst introspection = await adapter.introspect(\n\t\toptions.tables ? { tables: options.tables } : undefined,\n\t);\n\n\tconst payload = buildSchemaRequest(databaseName, adapter, introspection);\n\n\t// Generate a session id so backend telemetry can correlate all work for this sync\n\tconst sessionId = randomUUID();\n\n\tconst response = await client.post<IngestResponse>(\n\t\t\"/ingest\",\n\t\tpayload,\n\t\ttenantId,\n\t\toptions.userId,\n\t\toptions.scopes,\n\t\tsignal,\n\t\tsessionId,\n\t);\n\n\treturn response;\n}\n\nfunction resolveTenantId(client: ApiClient, tenantId?: string): string {\n\tconst resolved = tenantId ?? client.getDefaultTenantId();\n\tif (!resolved) {\n\t\tthrow new Error(\n\t\t\t\"tenantId is required. Provide it per request or via defaultTenantId option.\",\n\t\t);\n\t}\n\treturn resolved;\n}\n\nfunction buildSchemaRequest(\n\tdatabaseName: string,\n\tadapter: { getDialect: () => string },\n\tintrospection: SchemaIntrospection,\n): SchemaIngestRequest {\n\tconst dialect = adapter.getDialect();\n\tconst tables: SchemaIngestTable[] = introspection.tables.map((table) => ({\n\t\ttable_name: table.name,\n\t\tdescription: table.comment ?? `Table ${table.name}`,\n\t\tcolumns: table.columns.map((column) => ({\n\t\t\tname: column.name,\n\t\t\tdata_type: column.rawType ?? column.type,\n\t\t\tis_primary_key: Boolean(column.isPrimaryKey),\n\t\t\tdescription: column.comment ?? \"\",\n\t\t})),\n\t}));\n\n\treturn {\n\t\tdatabase: databaseName,\n\t\tdialect,\n\t\ttables,\n\t};\n}\n","import { randomUUID } from \"node:crypto\";\nimport type { ApiClient } from \"../core/client\";\nimport type { ParamRecord, QueryEngine } from \"../core/query-engine\";\n\nexport interface ContextDocument {\n\tsource?: string;\n\tpageContent: string;\n\tmetadata?: Record<string, unknown>;\n\tscore?: number;\n}\n\nexport interface ChartEnvelope {\n\tvegaLiteSpec: Record<string, unknown> | null;\n\tnotes: string | null;\n}\n\nexport interface AskOptions {\n\ttenantId?: string;\n\tuserId?: string;\n\tscopes?: string[];\n\tdatabase?: string;\n\tlastError?: string;\n\tpreviousSql?: string;\n\tmaxRetry?: number;\n\tchartMaxRetries?: number;\n}\n\nexport interface AskResponse {\n\tsql: string;\n\tparams: ParamRecord;\n\tparamMetadata: Array<Record<string, unknown>>;\n\trationale?: string;\n\tdialect: string;\n\tqueryId?: string;\n\trows: Array<Record<string, unknown>>;\n\tfields: string[];\n\tchart: ChartEnvelope;\n\tcontext?: ContextDocument[];\n\tattempts?: number;\n}\n\ninterface ServerQueryResponse {\n\tsuccess: boolean;\n\tsql: string;\n\tparams?: Array<Record<string, unknown>>;\n\tdialect: string;\n\tdatabase?: string;\n\ttable?: string;\n\trationale?: string;\n\tqueryId?: string;\n\tcontext?: ContextDocument[];\n}\n\ninterface ServerChartResponse {\n\tchart: Record<string, unknown> | null;\n\tnotes: string | null;\n}\n\n/**\n * Route module for natural language query generation\n * Simple orchestration following Ousterhout's principle\n */\nexport async function ask(\n\tclient: ApiClient,\n\tqueryEngine: QueryEngine,\n\tquestion: string,\n\toptions: AskOptions,\n\tsignal?: AbortSignal,\n): Promise<AskResponse> {\n\tconst tenantId = resolveTenantId(client, options.tenantId);\n\tconst sessionId = randomUUID();\n\tconst maxRetry = options.maxRetry ?? 0;\n\tlet attempt = 0;\n\tlet lastError: string | undefined = options.lastError;\n\tlet previousSql: string | undefined = options.previousSql;\n\n\twhile (attempt <= maxRetry) {\n\t\t// Step 1: Get SQL from backend\n\t\tconsole.log({ lastError, previousSql });\n\t\tconst queryResponse = await client.post<ServerQueryResponse>(\n\t\t\t\"/query\",\n\t\t\t{\n\t\t\t\tquestion,\n\t\t\t\t...(lastError ? { last_error: lastError } : {}),\n\t\t\t\t...(previousSql ? { previous_sql: previousSql } : {}),\n\t\t\t\t...(options.maxRetry ? { max_retry: options.maxRetry } : {}),\n\t\t\t},\n\t\t\ttenantId,\n\t\t\toptions.userId,\n\t\t\toptions.scopes,\n\t\t\tsignal,\n\t\t\tsessionId,\n\t\t);\n\n\t\tconst databaseName =\n\t\t\tqueryResponse.database ??\n\t\t\toptions.database ??\n\t\t\tqueryEngine.getDefaultDatabase();\n\t\tif (!databaseName) {\n\t\t\tthrow new Error(\n\t\t\t\t\"No database attached. Call attachPostgres/attachClickhouse first.\",\n\t\t\t);\n\t\t}\n\n\t\t// Step 2: Map and validate parameters\n\t\tconst paramMetadata = Array.isArray(queryResponse.params)\n\t\t\t? queryResponse.params\n\t\t\t: [];\n\t\tconst paramValues = queryEngine.mapGeneratedParams(paramMetadata);\n\n\t\t// Step 3: Execute SQL with tenant isolation\n\t\ttry {\n\t\t\tconst execution = await queryEngine.validateAndExecute(\n\t\t\t\tqueryResponse.sql,\n\t\t\t\tparamValues,\n\t\t\t\tdatabaseName,\n\t\t\t\ttenantId,\n\t\t\t);\n\t\t\tconst rows = execution.rows ?? [];\n\n\t\t\t// Step 4: Generate chart if we have data\n\t\t\tlet chart: ChartEnvelope = {\n\t\t\t\tvegaLiteSpec: null,\n\t\t\t\tnotes: rows.length === 0 ? \"Query returned no rows.\" : null,\n\t\t\t};\n\n\t\t\tif (rows.length > 0) {\n\t\t\t\tconst chartResponse = await client.post<ServerChartResponse>(\n\t\t\t\t\t\"/chart\",\n\t\t\t\t\t{\n\t\t\t\t\t\tquestion,\n\t\t\t\t\t\tsql: queryResponse.sql,\n\t\t\t\t\t\trationale: queryResponse.rationale,\n\t\t\t\t\t\tfields: execution.fields,\n\t\t\t\t\t\trows: anonymizeResults(rows),\n\t\t\t\t\t\tmax_retries: options.chartMaxRetries ?? 3,\n\t\t\t\t\t\tquery_id: queryResponse.queryId,\n\t\t\t\t\t},\n\t\t\t\t\ttenantId,\n\t\t\t\t\toptions.userId,\n\t\t\t\t\toptions.scopes,\n\t\t\t\t\tsignal,\n\t\t\t\t\tsessionId,\n\t\t\t\t);\n\n\t\t\t\tchart = {\n\t\t\t\t\tvegaLiteSpec: chartResponse.chart\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t...chartResponse.chart,\n\t\t\t\t\t\t\t\tdata: { values: rows },\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: null,\n\t\t\t\t\tnotes: chartResponse.notes,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsql: queryResponse.sql,\n\t\t\t\tparams: paramValues,\n\t\t\t\tparamMetadata,\n\t\t\t\trationale: queryResponse.rationale,\n\t\t\t\tdialect: queryResponse.dialect,\n\t\t\t\tqueryId: queryResponse.queryId,\n\t\t\t\trows,\n\t\t\t\tfields: execution.fields,\n\t\t\t\tchart,\n\t\t\t\tcontext: queryResponse.context,\n\t\t\t\tattempts: attempt + 1,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tattempt++;\n\n\t\t\t// If we've exhausted all retries, throw the error\n\t\t\tif (attempt > maxRetry) {\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\t// Save error and SQL for next retry\n\t\t\tlastError = error instanceof Error ? error.message : String(error);\n\t\t\tpreviousSql = queryResponse.sql;\n\n\t\t\t// Log retry attempt\n\t\t\tconsole.warn(\n\t\t\t\t`SQL execution failed (attempt ${attempt}/${maxRetry + 1}): ${lastError}. Retrying...`,\n\t\t\t);\n\t\t}\n\t}\n\n\t// This should never be reached, but TypeScript needs it\n\tthrow new Error(\"Unexpected error in ask retry loop\");\n}\n\nfunction resolveTenantId(client: ApiClient, tenantId?: string): string {\n\tconst resolved = tenantId ?? client.getDefaultTenantId();\n\tif (!resolved) {\n\t\tthrow new Error(\n\t\t\t\"tenantId is required. Provide it per request or via defaultTenantId option.\",\n\t\t);\n\t}\n\treturn resolved;\n}\n\nexport function anonymizeResults(\n\trows: Array<Record<string, unknown>>,\n): Array<Record<string, string>> {\n\tif (!rows?.length) return [];\n\treturn rows.map((row) => {\n\t\tconst masked: Record<string, string> = {};\n\t\tObject.entries(row).forEach(([key, value]) => {\n\t\t\tif (value === null) masked[key] = \"null\";\n\t\t\telse if (Array.isArray(value)) masked[key] = \"array\";\n\t\t\telse masked[key] = typeof value;\n\t\t});\n\t\treturn masked;\n\t});\n}\n"],"mappings":"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","names":["normalizeTableFilter","asTableType","sanitize","encode","message","keyData","encode","resolveTenantId","resolveTenantId","import_node_crypto","resolveTenantId"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/clickhouse.ts","../src/adapters/clickhouse.ts","../src/adapters/postgres.ts"],"sourcesContent":["import { createHash, randomUUID } from \"node:crypto\";\nimport { importPKCS8, SignJWT } from \"jose\";\nimport {\n\tClickHouseAdapter,\n\ttype ClickHouseAdapterOptions,\n\ttype ClickHouseClientFn,\n} from \"./adapters/clickhouse\";\nimport {\n\tPostgresAdapter,\n\ttype PostgresAdapterOptions,\n\ttype PostgresClientFn,\n} from \"./adapters/postgres\";\nimport type { DatabaseAdapter, DatabaseDialect } from \"./adapters/types\";\nimport type { SchemaIntrospection } from \"./schema/types\";\n\nexport { ClickHouseAdapter, PostgresAdapter };\n\nexport type {\n\tClickHouseAdapterOptions,\n\tClickHouseClientFn,\n\tDatabaseAdapter,\n\tDatabaseDialect,\n\tPostgresAdapterOptions,\n\tPostgresClientFn,\n\tSchemaIntrospection,\n};\n\nexport type ParamValue = string | number | boolean | string[] | number[];\nexport type ParamRecord = Record<string, ParamValue>;\n\nexport interface ContextDocument {\n\tsource?: string;\n\tpageContent: string;\n\tmetadata?: Record<string, unknown>;\n\tscore?: number;\n}\n\nexport interface ChartEnvelope {\n\tvegaLiteSpec: Record<string, unknown> | null;\n\tnotes: string | null;\n}\n\nexport interface AskOptions {\n\ttenantId?: string;\n\tuserId?: string;\n\tscopes?: string[];\n\tdatabase?: string;\n\tlastError?: string;\n\tpreviousSql?: string;\n\tmaxRetry?: number;\n\tchartMaxRetries?: number;\n\tdisableAutoSync?: boolean;\n}\n\nexport interface AskResponse {\n\tsql: string;\n\tparams: ParamRecord;\n\tparamMetadata: Array<Record<string, unknown>>;\n\trationale?: string;\n\tdialect: string;\n\tqueryId?: string;\n\trows: Array<Record<string, unknown>>;\n\tfields: string[];\n\tchart: ChartEnvelope;\n\tcontext?: ContextDocument[];\n}\n\nexport interface SchemaSyncOptions {\n\ttenantId?: string;\n\tuserId?: string;\n\tscopes?: string[];\n\ttables?: string[];\n\tforce?: boolean;\n}\n\nexport interface KnowledgeBaseAnnotation {\n\tid: string;\n\torganization_id: string;\n\ttarget_identifier: string;\n\tcontent: string;\n\tcreated_by: string;\n\tupdated_by: string;\n\tcreated_at: string;\n\tupdated_at: string;\n}\n\nexport interface KnowledgeBaseAnnotationInput {\n\ttargetIdentifier: string;\n\tcontent: string;\n\tuserId: string;\n\ttenantId?: string;\n}\n\nexport interface KnowledgeBaseChunkTable {\n\ttable_name: string;\n\tgold_sql?: Array<{ sql: string; description?: string; name?: string }>;\n\tglossary?: Array<{ term: string; definition: string }>;\n}\n\nexport interface KnowledgeBaseChunkRequest {\n\tdatabase: string;\n\tdialect: string;\n\ttables: KnowledgeBaseChunkTable[];\n\ttenantId?: string;\n}\n\nexport interface KnowledgeBaseChunksResponse {\n\tsuccess: boolean;\n\tmessage: string;\n\tchunks: {\n\t\ttotal: number;\n\t\tgold_sql: number;\n\t\tglossary: number;\n\t\tchunks_with_annotations: number;\n\t};\n}\n\nexport interface SdkChart {\n\tid: string;\n\ttitle: string;\n\tdescription: string | null;\n\tsql: string;\n\tsql_params: Record<string, unknown> | null;\n\tvega_lite_spec: Record<string, unknown>;\n\tquery_id: string | null;\n\torganization_id: string | null;\n\ttenant_id: string | null;\n\tuser_id: string | null;\n\tcreated_at: string | null;\n\tupdated_at: string | null;\n\tactive?: boolean;\n\tdatabase?: string | null;\n}\n\nexport interface SdkActiveChart {\n\tid: string;\n\tchart_id: string;\n\torder: number | null;\n\tmeta: Record<string, unknown> | null;\n\torganization_id: string | null;\n\ttenant_id: string | null;\n\tuser_id: string | null;\n\tcreated_at: string | null;\n\tupdated_at: string | null;\n\tchart?: SdkChart | null;\n}\n\nexport interface ChartCreateInput {\n\ttitle: string;\n\tdescription?: string;\n\tsql: string;\n\tsql_params?: Record<string, unknown>;\n\tvega_lite_spec: Record<string, unknown>;\n\tquery_id?: string;\n\tdatabase?: string;\n}\n\nexport interface ChartUpdateInput {\n\ttitle?: string;\n\tdescription?: string;\n\tsql?: string;\n\tsql_params?: Record<string, unknown>;\n\tvega_lite_spec?: Record<string, unknown>;\n\tdatabase?: string;\n}\n\nexport interface ActiveChartCreateInput {\n\tchart_id: string;\n\torder?: number;\n\tmeta?: Record<string, unknown>;\n}\n\nexport interface ActiveChartUpdateInput {\n\tchart_id?: string;\n\torder?: number;\n\tmeta?: Record<string, unknown>;\n}\n\nexport interface PaginationQuery {\n\tpage?: number;\n\tlimit?: number;\n}\n\nexport interface PaginationInfo {\n\tpage: number;\n\tlimit: number;\n\ttotal: number;\n\ttotalPages: number;\n\thasNext: boolean;\n\thasPrev: boolean;\n}\n\nexport interface PaginatedResponse<T> {\n\tdata: T[];\n\tpagination: PaginationInfo;\n}\n\nexport interface ChartListOptions {\n\ttenantId?: string;\n\tuserId?: string;\n\tscopes?: string[];\n\tpagination?: PaginationQuery;\n\tsortBy?: \"title\" | \"user_id\" | \"created_at\" | \"updated_at\";\n\tsortDir?: \"asc\" | \"desc\";\n\ttitle?: string;\n\tuserFilter?: string;\n\tcreatedFrom?: string;\n\tcreatedTo?: string;\n\tupdatedFrom?: string;\n\tupdatedTo?: string;\n\tincludeData?: boolean;\n}\n\nexport interface ActiveChartListOptions extends ChartListOptions {\n\twithData?: boolean;\n}\n\nexport interface IngestResponse {\n\tsuccess: boolean;\n\tmessage: string;\n\tchunks: number;\n\tchunks_with_annotations: number;\n\tschema_id?: string;\n\tschema_hash?: string;\n\tdrift_detected?: boolean;\n\tskipped?: boolean;\n}\n\ninterface DatabaseMetadata {\n\tname: string;\n\tdialect: DatabaseDialect;\n\tdescription?: string;\n\ttags?: string[];\n\ttenantFieldName?: string;\n\ttenantFieldType?: string;\n\tenforceTenantIsolation?: boolean;\n}\n\ninterface SchemaIngestColumn {\n\tname: string;\n\tdata_type: string;\n\tis_primary_key: boolean;\n\tdescription: string;\n}\n\ninterface SchemaIngestTable {\n\ttable_name: string;\n\tdescription: string;\n\tcolumns: SchemaIngestColumn[];\n}\n\ninterface SchemaIngestRequest {\n\tdatabase: string;\n\tdialect: string;\n\ttables: SchemaIngestTable[];\n}\n\ninterface ServerQueryResponse {\n\tsuccess: boolean;\n\tsql: string;\n\tparams?: Array<Record<string, unknown>>;\n\tdialect: string;\n\trationale?: string;\n\tqueryId?: string;\n\tcontext?: ContextDocument[];\n}\n\ninterface ServerChartResponse {\n\tchart: Record<string, unknown> | null;\n\tnotes: string | null;\n}\n\ninterface RequestOptions {\n\ttenantId?: string;\n\tuserId?: string;\n\tscopes?: string[];\n}\n\nexport class QueryPanelSdkAPI {\n\tprivate readonly baseUrl: string;\n\tprivate readonly privateKey: string;\n\tprivate readonly organizationId: string;\n\tprivate readonly defaultTenantId?: string;\n\tprivate readonly additionalHeaders?: Record<string, string>;\n\tprivate readonly fetchImpl: typeof fetch;\n\tprivate cachedPrivateKey?: Awaited<ReturnType<typeof importPKCS8>>;\n\n\tprivate databases = new Map<string, DatabaseAdapter>();\n\tprivate databaseMetadata = new Map<string, DatabaseMetadata>();\n\tprivate defaultDatabase?: string;\n\tprivate lastSyncHashes = new Map<string, string>();\n\tprivate syncedDatabases = new Set<string>();\n\n\tconstructor(\n\t\tbaseUrl: string,\n\t\tprivateKey: string,\n\t\torganizationId: string,\n\t\toptions?: {\n\t\t\tdefaultTenantId?: string;\n\t\t\tadditionalHeaders?: Record<string, string>;\n\t\t\tfetch?: typeof fetch;\n\t\t},\n\t) {\n\t\tif (!baseUrl) {\n\t\t\tthrow new Error(\"Base URL is required\");\n\t\t}\n\t\tif (!privateKey) {\n\t\t\tthrow new Error(\"Private key is required\");\n\t\t}\n\t\tif (!organizationId) {\n\t\t\tthrow new Error(\"Organization ID is required\");\n\t\t}\n\n\t\tthis.baseUrl = baseUrl.replace(/\\/+$/, \"\");\n\t\tthis.privateKey = privateKey;\n\t\tthis.organizationId = organizationId;\n\t\tthis.defaultTenantId = options?.defaultTenantId;\n\t\tthis.additionalHeaders = options?.additionalHeaders;\n\t\tthis.fetchImpl = options?.fetch ?? globalThis.fetch;\n\n\t\tif (!this.fetchImpl) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Fetch implementation not found. Provide options.fetch or use Node 18+.\",\n\t\t\t);\n\t\t}\n\t}\n\n\tattachClickhouse(\n\t\tname: string,\n\t\tclientFn: ClickHouseClientFn,\n\t\toptions?: ClickHouseAdapterOptions & {\n\t\t\tdescription?: string;\n\t\t\ttags?: string[];\n\t\t\ttenantFieldName?: string;\n\t\t\ttenantFieldType?: string;\n\t\t\tenforceTenantIsolation?: boolean;\n\t\t},\n\t): void {\n\t\tconst adapter = new ClickHouseAdapter(clientFn, options);\n\t\tthis.attachDatabase(name, adapter);\n\n\t\tconst metadata: DatabaseMetadata = {\n\t\t\tname,\n\t\t\tdialect: \"clickhouse\",\n\t\t\tdescription: options?.description,\n\t\t\ttags: options?.tags,\n\t\t\ttenantFieldName: options?.tenantFieldName,\n\t\t\ttenantFieldType: options?.tenantFieldType ?? \"String\",\n\t\t\tenforceTenantIsolation: options?.tenantFieldName\n\t\t\t\t? (options?.enforceTenantIsolation ?? true)\n\t\t\t\t: undefined,\n\t\t};\n\n\t\tthis.databaseMetadata.set(name, metadata);\n\t}\n\n\tattachPostgres(\n\t\tname: string,\n\t\tclientFn: PostgresClientFn,\n\t\toptions?: PostgresAdapterOptions & {\n\t\t\tdescription?: string;\n\t\t\ttags?: string[];\n\t\t\ttenantFieldName?: string;\n\t\t\tenforceTenantIsolation?: boolean;\n\t\t},\n\t): void {\n\t\tconst adapter = new PostgresAdapter(clientFn, options);\n\t\tthis.attachDatabase(name, adapter);\n\n\t\tconst metadata: DatabaseMetadata = {\n\t\t\tname,\n\t\t\tdialect: \"postgres\",\n\t\t\tdescription: options?.description,\n\t\t\ttags: options?.tags,\n\t\t\ttenantFieldName: options?.tenantFieldName,\n\t\t\tenforceTenantIsolation: options?.tenantFieldName\n\t\t\t\t? (options?.enforceTenantIsolation ?? true)\n\t\t\t\t: undefined,\n\t\t};\n\n\t\tthis.databaseMetadata.set(name, metadata);\n\t}\n\n\tattachDatabase(name: string, adapter: DatabaseAdapter): void {\n\t\tthis.databases.set(name, adapter);\n\t\tif (!this.defaultDatabase) {\n\t\t\tthis.defaultDatabase = name;\n\t\t}\n\t}\n\n\tasync syncSchema(\n\t\tdatabaseName: string,\n\t\toptions: SchemaSyncOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<IngestResponse> {\n\t\tconst tenantId = this.resolveTenantId(options.tenantId);\n\t\tconst adapter = this.getDatabase(databaseName);\n\t\tconst introspection = await adapter.introspect(\n\t\t\toptions.tables ? { tables: options.tables } : undefined,\n\t\t);\n\n\t\tconst payload = this.buildSchemaRequest(\n\t\t\tdatabaseName,\n\t\t\tadapter,\n\t\t\tintrospection,\n\t\t);\n\t\tconst hash = this.hashSchemaRequest(payload);\n\t\tconst previousHash = this.lastSyncHashes.get(databaseName);\n\n\t\tif (!options.force && previousHash === hash) {\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: \"Schema unchanged; skipping ingestion\",\n\t\t\t\tchunks: 0,\n\t\t\t\tchunks_with_annotations: 0,\n\t\t\t\tschema_hash: hash,\n\t\t\t\tskipped: true,\n\t\t\t};\n\t\t}\n\n\t\t// Generate a session id so backend telemetry can correlate all work for this sync\n\t\tconst sessionId = randomUUID();\n\n\t\tconst response = await this.post<IngestResponse>(\n\t\t\t\"/ingest\",\n\t\t\tpayload,\n\t\t\ttenantId,\n\t\t\toptions.userId,\n\t\t\toptions.scopes,\n\t\t\tsignal,\n\t\t\tsessionId,\n\t\t);\n\n\t\tthis.lastSyncHashes.set(databaseName, hash);\n\t\tthis.syncedDatabases.add(databaseName);\n\n\t\treturn response;\n\t}\n\n\tasync ingestKnowledgeBaseChunks(\n\t\tpayload: KnowledgeBaseChunkRequest,\n\t\toptions?: RequestOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<KnowledgeBaseChunksResponse> {\n\t\tconst tenantId = this.resolveTenantId(\n\t\t\tpayload.tenantId ?? options?.tenantId,\n\t\t);\n\t\treturn await this.post<KnowledgeBaseChunksResponse>(\n\t\t\t\"/knowledge-base/chunks\",\n\t\t\t{\n\t\t\t\torganization_id: this.organizationId,\n\t\t\t\ttenant_id: tenantId,\n\t\t\t\tdatabase: payload.database,\n\t\t\t\tdialect: payload.dialect,\n\t\t\t\ttables: payload.tables,\n\t\t\t},\n\t\t\ttenantId,\n\t\t\toptions?.userId,\n\t\t\toptions?.scopes,\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tasync introspect(\n\t\tdatabaseName: string,\n\t\ttables?: string[],\n\t): Promise<SchemaIntrospection> {\n\t\tconst adapter = this.getDatabase(databaseName);\n\t\treturn await adapter.introspect(tables ? { tables } : undefined);\n\t}\n\n\tasync ask(\n\t\tquestion: string,\n\t\toptions: AskOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<AskResponse> {\n\t\tconst tenantId = this.resolveTenantId(options.tenantId);\n\n\t\tawait this.ensureSchemasSynced(\n\t\t\ttenantId,\n\t\t\toptions.userId,\n\t\t\toptions.scopes,\n\t\t\toptions.disableAutoSync,\n\t\t);\n\n\t\tconst sessionId = randomUUID();\n\n\t\tconst queryResponse = await this.post<ServerQueryResponse>(\n\t\t\t\"/query\",\n\t\t\t{\n\t\t\t\tquestion,\n\t\t\t\t...(options.lastError ? { last_error: options.lastError } : {}),\n\t\t\t\t...(options.previousSql ? { previous_sql: options.previousSql } : {}),\n\t\t\t\t...(options.maxRetry ? { max_retry: options.maxRetry } : {}),\n\t\t\t},\n\t\t\ttenantId,\n\t\t\toptions.userId,\n\t\t\toptions.scopes,\n\t\t\tsignal,\n\t\t\tsessionId,\n\t\t);\n\n\t\tconst databaseName = options.database ?? this.defaultDatabase;\n\t\tif (!databaseName) {\n\t\t\tthrow new Error(\n\t\t\t\t\"No database attached. Call attachPostgres/attachClickhouse first.\",\n\t\t\t);\n\t\t}\n\n\t\tconst adapter = this.getDatabase(databaseName);\n\t\tconst paramMetadata = Array.isArray(queryResponse.params)\n\t\t\t? queryResponse.params\n\t\t\t: [];\n\t\tconst paramValues = this.mapGeneratedParams(paramMetadata);\n\n\t\tconst metadata = this.databaseMetadata.get(databaseName);\n\t\tif (metadata) {\n\t\t\tqueryResponse.sql = this.ensureTenantIsolation(\n\t\t\t\tqueryResponse.sql,\n\t\t\t\tparamValues,\n\t\t\t\tmetadata,\n\t\t\t\ttenantId,\n\t\t\t);\n\t\t}\n\n\t\tawait adapter.validate(queryResponse.sql, paramValues);\n\t\tconst execution = await adapter.execute(queryResponse.sql, paramValues);\n\t\tconst rows = execution.rows ?? [];\n\n\t\tlet chart: ChartEnvelope = {\n\t\t\tvegaLiteSpec: null,\n\t\t\tnotes: rows.length === 0 ? \"Query returned no rows.\" : null,\n\t\t};\n\n\t\tif (rows.length > 0) {\n\t\t\tconst chartResponse = await this.post<ServerChartResponse>(\n\t\t\t\t\"/chart\",\n\t\t\t\t{\n\t\t\t\t\tquestion,\n\t\t\t\t\tsql: queryResponse.sql,\n\t\t\t\t\trationale: queryResponse.rationale,\n\t\t\t\t\tfields: execution.fields,\n\t\t\t\t\trows: anonymizeResults(rows),\n\t\t\t\t\tmax_retries: options.chartMaxRetries ?? 3,\n\t\t\t\t\tquery_id: queryResponse.queryId,\n\t\t\t\t},\n\t\t\t\ttenantId,\n\t\t\t\toptions.userId,\n\t\t\t\toptions.scopes,\n\t\t\t\tsignal,\n\t\t\t\tsessionId,\n\t\t\t);\n\n\t\t\tchart = {\n\t\t\t\tvegaLiteSpec: chartResponse.chart\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...chartResponse.chart,\n\t\t\t\t\t\t\tdata: { values: rows },\n\t\t\t\t\t\t}\n\t\t\t\t\t: null,\n\t\t\t\tnotes: chartResponse.notes,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tsql: queryResponse.sql,\n\t\t\tparams: paramValues,\n\t\t\tparamMetadata,\n\t\t\trationale: queryResponse.rationale,\n\t\t\tdialect: queryResponse.dialect,\n\t\t\tqueryId: queryResponse.queryId,\n\t\t\trows,\n\t\t\tfields: execution.fields,\n\t\t\tchart,\n\t\t\tcontext: queryResponse.context,\n\t\t};\n\t}\n\n\tasync upsertAnnotation(\n\t\tinput: KnowledgeBaseAnnotationInput,\n\t\toptions?: RequestOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<KnowledgeBaseAnnotation> {\n\t\tconst tenantId = this.resolveTenantId(input.tenantId ?? options?.tenantId);\n\t\tconst response = await this.post<{\n\t\t\tsuccess: boolean;\n\t\t\tannotation: KnowledgeBaseAnnotation;\n\t\t}>(\n\t\t\t\"/knowledge-base/annotations\",\n\t\t\t{\n\t\t\t\torganization_id: this.organizationId,\n\t\t\t\ttenant_id: tenantId,\n\t\t\t\ttarget_identifier: input.targetIdentifier,\n\t\t\t\tcontent: input.content,\n\t\t\t\tuser_id: input.userId,\n\t\t\t},\n\t\t\ttenantId,\n\t\t\toptions?.userId,\n\t\t\toptions?.scopes,\n\t\t\tsignal,\n\t\t);\n\n\t\treturn response.annotation;\n\t}\n\n\tasync listAnnotations(\n\t\toptions?: RequestOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<KnowledgeBaseAnnotation[]> {\n\t\tconst tenantId = this.resolveTenantId(options?.tenantId);\n\t\tconst response = await this.get<{\n\t\t\tsuccess: boolean;\n\t\t\tannotations: KnowledgeBaseAnnotation[];\n\t\t}>(\n\t\t\t\"/knowledge-base/annotations\",\n\t\t\ttenantId,\n\t\t\toptions?.userId,\n\t\t\toptions?.scopes,\n\t\t\tsignal,\n\t\t);\n\n\t\treturn response.annotations;\n\t}\n\n\tasync getAnnotation(\n\t\ttargetIdentifier: string,\n\t\toptions?: RequestOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<KnowledgeBaseAnnotation | null> {\n\t\tconst tenantId = this.resolveTenantId(options?.tenantId);\n\t\tconst response = await this.get<{\n\t\t\tsuccess: boolean;\n\t\t\tannotation: KnowledgeBaseAnnotation;\n\t\t}>(\n\t\t\t`/knowledge-base/annotations/${encodeURIComponent(targetIdentifier)}`,\n\t\t\ttenantId,\n\t\t\toptions?.userId,\n\t\t\toptions?.scopes,\n\t\t\tsignal,\n\t\t).catch((error: any) => {\n\t\t\tif (error?.status === 404) {\n\t\t\t\treturn { success: false, annotation: null as any };\n\t\t\t}\n\t\t\tthrow error;\n\t\t});\n\n\t\treturn response.annotation ?? null;\n\t}\n\n\tasync deleteAnnotation(\n\t\ttargetIdentifier: string,\n\t\toptions?: RequestOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<void> {\n\t\tconst tenantId = this.resolveTenantId(options?.tenantId);\n\t\tawait this.delete(\n\t\t\t`/knowledge-base/annotations/${encodeURIComponent(targetIdentifier)}`,\n\t\t\ttenantId,\n\t\t\toptions?.userId,\n\t\t\toptions?.scopes,\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tasync createChart(\n\t\tbody: ChartCreateInput,\n\t\toptions?: RequestOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<SdkChart> {\n\t\tconst tenantId = this.resolveTenantId(options?.tenantId);\n\t\treturn await this.post<SdkChart>(\n\t\t\t\"/charts\",\n\t\t\tbody,\n\t\t\ttenantId,\n\t\t\toptions?.userId,\n\t\t\toptions?.scopes,\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tasync listCharts(\n\t\toptions?: ChartListOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<PaginatedResponse<SdkChart>> {\n\t\tconst tenantId = this.resolveTenantId(options?.tenantId);\n\t\tconst params = new URLSearchParams();\n\t\tif (options?.pagination?.page)\n\t\t\tparams.set(\"page\", `${options.pagination.page}`);\n\t\tif (options?.pagination?.limit)\n\t\t\tparams.set(\"limit\", `${options.pagination.limit}`);\n\t\tif (options?.sortBy) params.set(\"sort_by\", options.sortBy);\n\t\tif (options?.sortDir) params.set(\"sort_dir\", options.sortDir);\n\t\tif (options?.title) params.set(\"title\", options.title);\n\t\tif (options?.userFilter) params.set(\"user_id\", options.userFilter);\n\t\tif (options?.createdFrom) params.set(\"created_from\", options.createdFrom);\n\t\tif (options?.createdTo) params.set(\"created_to\", options.createdTo);\n\t\tif (options?.updatedFrom) params.set(\"updated_from\", options.updatedFrom);\n\t\tif (options?.updatedTo) params.set(\"updated_to\", options.updatedTo);\n\n\t\tconst response = await this.get<PaginatedResponse<SdkChart>>(\n\t\t\t`/charts${params.toString() ? `?${params.toString()}` : \"\"}`,\n\t\t\ttenantId,\n\t\t\toptions?.userId,\n\t\t\toptions?.scopes,\n\t\t\tsignal,\n\t\t);\n\n\t\tif (options?.includeData) {\n\t\t\tresponse.data = await Promise.all(\n\t\t\t\tresponse.data.map(async (chart) => ({\n\t\t\t\t\t...chart,\n\t\t\t\t\tvega_lite_spec: {\n\t\t\t\t\t\t...chart.vega_lite_spec,\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tvalues: await this.runSafeQueryOnClient(\n\t\t\t\t\t\t\t\tchart.sql,\n\t\t\t\t\t\t\t\tchart.database ?? undefined,\n\t\t\t\t\t\t\t\t(chart.sql_params as ParamRecord | null) ?? undefined,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t})),\n\t\t\t);\n\t\t}\n\n\t\treturn response;\n\t}\n\n\tasync getChart(\n\t\tid: string,\n\t\toptions?: RequestOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<SdkChart> {\n\t\tconst tenantId = this.resolveTenantId(options?.tenantId);\n\t\tconst chart = await this.get<SdkChart>(\n\t\t\t`/charts/${encodeURIComponent(id)}`,\n\t\t\ttenantId,\n\t\t\toptions?.userId,\n\t\t\toptions?.scopes,\n\t\t\tsignal,\n\t\t);\n\n\t\treturn {\n\t\t\t...chart,\n\t\t\tvega_lite_spec: {\n\t\t\t\t...chart.vega_lite_spec,\n\t\t\t\tdata: {\n\t\t\t\t\tvalues: await this.runSafeQueryOnClient(\n\t\t\t\t\t\tchart.sql,\n\t\t\t\t\t\tchart.database ?? undefined,\n\t\t\t\t\t\t(chart.sql_params as ParamRecord | null) ?? undefined,\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\t}\n\n\tasync updateChart(\n\t\tid: string,\n\t\tbody: ChartUpdateInput,\n\t\toptions?: RequestOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<SdkChart> {\n\t\tconst tenantId = this.resolveTenantId(options?.tenantId);\n\t\treturn await this.put<SdkChart>(\n\t\t\t`/charts/${encodeURIComponent(id)}`,\n\t\t\tbody,\n\t\t\ttenantId,\n\t\t\toptions?.userId,\n\t\t\toptions?.scopes,\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tasync deleteChart(\n\t\tid: string,\n\t\toptions?: RequestOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<void> {\n\t\tconst tenantId = this.resolveTenantId(options?.tenantId);\n\t\tawait this.delete(\n\t\t\t`/charts/${encodeURIComponent(id)}`,\n\t\t\ttenantId,\n\t\t\toptions?.userId,\n\t\t\toptions?.scopes,\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tasync createActiveChart(\n\t\tbody: ActiveChartCreateInput,\n\t\toptions?: RequestOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<SdkActiveChart> {\n\t\tconst tenantId = this.resolveTenantId(options?.tenantId);\n\t\treturn await this.post<SdkActiveChart>(\n\t\t\t\"/active-charts\",\n\t\t\tbody,\n\t\t\ttenantId,\n\t\t\toptions?.userId,\n\t\t\toptions?.scopes,\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tasync listActiveCharts(\n\t\toptions?: ActiveChartListOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<PaginatedResponse<SdkActiveChart>> {\n\t\tconst tenantId = this.resolveTenantId(options?.tenantId);\n\t\tconst params = new URLSearchParams();\n\t\tif (options?.pagination?.page)\n\t\t\tparams.set(\"page\", `${options.pagination.page}`);\n\t\tif (options?.pagination?.limit)\n\t\t\tparams.set(\"limit\", `${options.pagination.limit}`);\n\t\tif (options?.sortBy) params.set(\"sort_by\", options.sortBy);\n\t\tif (options?.sortDir) params.set(\"sort_dir\", options.sortDir);\n\t\tif (options?.title) params.set(\"name\", options.title);\n\t\tif (options?.userFilter) params.set(\"user_id\", options.userFilter);\n\t\tif (options?.createdFrom) params.set(\"created_from\", options.createdFrom);\n\t\tif (options?.createdTo) params.set(\"created_to\", options.createdTo);\n\t\tif (options?.updatedFrom) params.set(\"updated_from\", options.updatedFrom);\n\t\tif (options?.updatedTo) params.set(\"updated_to\", options.updatedTo);\n\n\t\tconst response = await this.get<PaginatedResponse<SdkActiveChart>>(\n\t\t\t`/active-charts${params.toString() ? `?${params.toString()}` : \"\"}`,\n\t\t\ttenantId,\n\t\t\toptions?.userId,\n\t\t\toptions?.scopes,\n\t\t\tsignal,\n\t\t);\n\n\t\tif (options?.withData) {\n\t\t\tresponse.data = await Promise.all(\n\t\t\t\tresponse.data.map(async (active) => ({\n\t\t\t\t\t...active,\n\t\t\t\t\tchart: active.chart\n\t\t\t\t\t\t? await this.getChart(active.chart_id, options, signal)\n\t\t\t\t\t\t: null,\n\t\t\t\t})),\n\t\t\t);\n\t\t}\n\n\t\treturn response;\n\t}\n\n\tasync getActiveChart(\n\t\tid: string,\n\t\toptions?: ActiveChartListOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<SdkActiveChart> {\n\t\tconst tenantId = this.resolveTenantId(options?.tenantId);\n\t\tconst active = await this.get<SdkActiveChart>(\n\t\t\t`/active-charts/${encodeURIComponent(id)}`,\n\t\t\ttenantId,\n\t\t\toptions?.userId,\n\t\t\toptions?.scopes,\n\t\t\tsignal,\n\t\t);\n\n\t\tif (options?.withData && active.chart_id) {\n\t\t\treturn {\n\t\t\t\t...active,\n\t\t\t\tchart: await this.getChart(active.chart_id, options, signal),\n\t\t\t};\n\t\t}\n\n\t\treturn active;\n\t}\n\n\tasync updateActiveChart(\n\t\tid: string,\n\t\tbody: ActiveChartUpdateInput,\n\t\toptions?: RequestOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<SdkActiveChart> {\n\t\tconst tenantId = this.resolveTenantId(options?.tenantId);\n\t\treturn await this.put<SdkActiveChart>(\n\t\t\t`/active-charts/${encodeURIComponent(id)}`,\n\t\t\tbody,\n\t\t\ttenantId,\n\t\t\toptions?.userId,\n\t\t\toptions?.scopes,\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tasync deleteActiveChart(\n\t\tid: string,\n\t\toptions?: RequestOptions,\n\t\tsignal?: AbortSignal,\n\t): Promise<void> {\n\t\tconst tenantId = this.resolveTenantId(options?.tenantId);\n\t\tawait this.delete(\n\t\t\t`/active-charts/${encodeURIComponent(id)}`,\n\t\t\ttenantId,\n\t\t\toptions?.userId,\n\t\t\toptions?.scopes,\n\t\t\tsignal,\n\t\t);\n\t}\n\n\tprivate getDatabase(name?: string): DatabaseAdapter {\n\t\tconst dbName = name ?? this.defaultDatabase;\n\t\tif (!dbName) {\n\t\t\tthrow new Error(\"No database attached.\");\n\t\t}\n\t\tconst adapter = this.databases.get(dbName);\n\t\tif (!adapter) {\n\t\t\tthrow new Error(\n\t\t\t\t`Database '${dbName}' not found. Attached: ${Array.from(\n\t\t\t\t\tthis.databases.keys(),\n\t\t\t\t).join(\", \")}`,\n\t\t\t);\n\t\t}\n\t\treturn adapter;\n\t}\n\n\tprivate async ensureSchemasSynced(\n\t\ttenantId: string,\n\t\tuserId?: string,\n\t\tscopes?: string[],\n\t\tdisableAutoSync?: boolean,\n\t): Promise<void> {\n\t\tif (disableAutoSync) return;\n\t\tconst unsynced = Array.from(this.databases.keys()).filter(\n\t\t\t(name) => !this.syncedDatabases.has(name),\n\t\t);\n\t\tawait Promise.all(\n\t\t\tunsynced.map((name) =>\n\t\t\t\tthis.syncSchema(name, { tenantId, userId, scopes }).catch((error) => {\n\t\t\t\t\tconsole.warn(`Failed to sync schema for ${name}:`, error);\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\t}\n\n\tprivate resolveTenantId(tenantId?: string): string {\n\t\tconst resolved = tenantId ?? this.defaultTenantId;\n\t\tif (!resolved) {\n\t\t\tthrow new Error(\n\t\t\t\t\"tenantId is required. Provide it per request or via defaultTenantId option.\",\n\t\t\t);\n\t\t}\n\t\treturn resolved;\n\t}\n\n\tprivate async headers(\n\t\ttenantId: string,\n\t\tuserId?: string,\n\t\tscopes?: string[],\n\t\tincludeJson: boolean = true,\n\t\tsessionId?: string,\n\t): Promise<Record<string, string>> {\n\t\tconst token = await this.generateJWT(tenantId, userId, scopes);\n\t\tconst headers: Record<string, string> = {\n\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\tAccept: \"application/json\",\n\t\t};\n\t\tif (includeJson) {\n\t\t\theaders[\"Content-Type\"] = \"application/json\";\n\t\t}\n\t\tif (sessionId) {\n\t\t\theaders[\"x-session-id\"] = sessionId;\n\t\t}\n\t\tif (this.additionalHeaders) {\n\t\t\tObject.assign(headers, this.additionalHeaders);\n\t\t}\n\t\treturn headers;\n\t}\n\n\tprivate async request<T>(path: string, init: RequestInit): Promise<T> {\n\t\tconst response = await this.fetchImpl(`${this.baseUrl}${path}`, init);\n\t\tconst text = await response.text();\n\t\tlet json: any;\n\t\ttry {\n\t\t\tjson = text ? JSON.parse(text) : undefined;\n\t\t} catch {\n\t\t\tjson = undefined;\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\tconst error = new Error(\n\t\t\t\tjson?.error || response.statusText || \"Request failed\",\n\t\t\t);\n\t\t\t(error as any).status = response.status;\n\t\t\tif (json?.details) (error as any).details = json.details;\n\t\t\tthrow error;\n\t\t}\n\n\t\treturn json as T;\n\t}\n\n\tprivate async get<T>(\n\t\tpath: string,\n\t\ttenantId: string,\n\t\tuserId?: string,\n\t\tscopes?: string[],\n\t\tsignal?: AbortSignal,\n\t\tsessionId?: string,\n\t): Promise<T> {\n\t\treturn await this.request<T>(path, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: await this.headers(tenantId, userId, scopes, false, sessionId),\n\t\t\tsignal,\n\t\t});\n\t}\n\n\tprivate async post<T>(\n\t\tpath: string,\n\t\tbody: unknown,\n\t\ttenantId: string,\n\t\tuserId?: string,\n\t\tscopes?: string[],\n\t\tsignal?: AbortSignal,\n\t\tsessionId?: string,\n\t): Promise<T> {\n\t\treturn await this.request<T>(path, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: await this.headers(tenantId, userId, scopes, true, sessionId),\n\t\t\tbody: JSON.stringify(body ?? {}),\n\t\t\tsignal,\n\t\t});\n\t}\n\n\tprivate async put<T>(\n\t\tpath: string,\n\t\tbody: unknown,\n\t\ttenantId: string,\n\t\tuserId?: string,\n\t\tscopes?: string[],\n\t\tsignal?: AbortSignal,\n\t\tsessionId?: string,\n\t): Promise<T> {\n\t\treturn await this.request<T>(path, {\n\t\t\tmethod: \"PUT\",\n\t\t\theaders: await this.headers(tenantId, userId, scopes, true, sessionId),\n\t\t\tbody: JSON.stringify(body ?? {}),\n\t\t\tsignal,\n\t\t});\n\t}\n\n\tprivate async delete<T = void>(\n\t\tpath: string,\n\t\ttenantId: string,\n\t\tuserId?: string,\n\t\tscopes?: string[],\n\t\tsignal?: AbortSignal,\n\t\tsessionId?: string,\n\t): Promise<T> {\n\t\treturn await this.request<T>(path, {\n\t\t\tmethod: \"DELETE\",\n\t\t\theaders: await this.headers(tenantId, userId, scopes, false, sessionId),\n\t\t\tsignal,\n\t\t});\n\t}\n\n\tprivate async generateJWT(\n\t\ttenantId: string,\n\t\tuserId?: string,\n\t\tscopes?: string[],\n\t): Promise<string> {\n\t\tif (!this.cachedPrivateKey) {\n\t\t\tthis.cachedPrivateKey = await importPKCS8(this.privateKey, \"RS256\");\n\t\t}\n\n\t\tconst payload: Record<string, unknown> = {\n\t\t\torganizationId: this.organizationId,\n\t\t\ttenantId,\n\t\t};\n\n\t\tif (userId) payload.userId = userId;\n\t\tif (scopes?.length) payload.scopes = scopes;\n\n\t\treturn await new SignJWT(payload)\n\t\t\t.setProtectedHeader({ alg: \"RS256\" })\n\t\t\t.setIssuedAt()\n\t\t\t.setExpirationTime(\"1h\")\n\t\t\t.sign(this.cachedPrivateKey);\n\t}\n\n\tprivate buildSchemaRequest(\n\t\tdatabaseName: string,\n\t\tadapter: DatabaseAdapter,\n\t\tintrospection: SchemaIntrospection,\n\t): SchemaIngestRequest {\n\t\tconst dialect = adapter.getDialect();\n\t\tconst tables: SchemaIngestTable[] = introspection.tables.map((table) => ({\n\t\t\ttable_name: table.name,\n\t\t\tdescription: table.comment ?? `Table ${table.name}`,\n\t\t\tcolumns: table.columns.map((column) => ({\n\t\t\t\tname: column.name,\n\t\t\t\tdata_type: column.rawType ?? column.type,\n\t\t\t\tis_primary_key: Boolean(column.isPrimaryKey),\n\t\t\t\tdescription: column.comment ?? \"\",\n\t\t\t})),\n\t\t}));\n\n\t\treturn {\n\t\t\tdatabase: databaseName,\n\t\t\tdialect,\n\t\t\ttables,\n\t\t};\n\t}\n\n\tprivate hashSchemaRequest(payload: SchemaIngestRequest): string {\n\t\tconst normalized = payload.tables.map((table) => ({\n\t\t\tname: table.table_name,\n\t\t\tcolumns: table.columns.map((column) => ({\n\t\t\t\tname: column.name,\n\t\t\t\ttype: column.data_type,\n\t\t\t\tprimary: column.is_primary_key,\n\t\t\t})),\n\t\t}));\n\t\treturn createHash(\"sha256\")\n\t\t\t.update(JSON.stringify(normalized))\n\t\t\t.digest(\"hex\");\n\t}\n\n\tprivate mapGeneratedParams(\n\t\tparams: Array<Record<string, unknown>>,\n\t): ParamRecord {\n\t\tconst record: ParamRecord = {};\n\n\t\tparams.forEach((param, index) => {\n\t\t\tconst value = param.value as ParamValue | undefined;\n\t\t\tif (value === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst nameCandidate =\n\t\t\t\t(typeof param.name === \"string\" && param.name.trim()) ||\n\t\t\t\t(typeof param.placeholder === \"string\" && param.placeholder.trim()) ||\n\t\t\t\t(typeof param.position === \"number\" && String(param.position)) ||\n\t\t\t\tString(index + 1);\n\t\t\tconst key = nameCandidate.replace(/[{}:$]/g, \"\").trim();\n\t\t\trecord[key] = value;\n\t\t});\n\n\t\treturn record;\n\t}\n\n\tprivate ensureTenantIsolation(\n\t\tsql: string,\n\t\tparams: ParamRecord,\n\t\tmetadata: DatabaseMetadata,\n\t\ttenantId: string,\n\t): string {\n\t\tif (\n\t\t\t!metadata.tenantFieldName ||\n\t\t\tmetadata.enforceTenantIsolation === false\n\t\t) {\n\t\t\treturn sql;\n\t\t}\n\n\t\tconst tenantField = metadata.tenantFieldName;\n\t\tconst paramKey = tenantField;\n\t\tparams[paramKey] = tenantId;\n\n\t\tconst normalizedSql = sql.toLowerCase();\n\t\tif (normalizedSql.includes(tenantField.toLowerCase())) {\n\t\t\treturn sql;\n\t\t}\n\n\t\tconst tenantPredicate =\n\t\t\tmetadata.dialect === \"clickhouse\"\n\t\t\t\t? `${tenantField} = {${tenantField}:${metadata.tenantFieldType ?? \"String\"}}`\n\t\t\t\t: `${tenantField} = '${tenantId}'`;\n\n\t\tif (/\\bwhere\\b/i.test(sql)) {\n\t\t\treturn sql.replace(\n\t\t\t\t/\\bwhere\\b/i,\n\t\t\t\t(match) => `${match} ${tenantPredicate} AND `,\n\t\t\t);\n\t\t}\n\n\t\treturn `${sql} WHERE ${tenantPredicate}`;\n\t}\n\n\tprivate async runSafeQueryOnClient(\n\t\tsql: string,\n\t\tdatabase?: string,\n\t\tparams?: ParamRecord,\n\t): Promise<Array<Record<string, unknown>>> {\n\t\ttry {\n\t\t\tconst adapter = this.getDatabase(database);\n\t\t\tconst result = await adapter.execute(sql, params);\n\t\t\treturn result.rows;\n\t\t} catch (error) {\n\t\t\tconsole.warn(\n\t\t\t\t`Failed to execute SQL locally for database '${database}':`,\n\t\t\t\terror,\n\t\t\t);\n\t\t\treturn [];\n\t\t}\n\t}\n}\n\nexport function anonymizeResults(\n\trows: Array<Record<string, unknown>>,\n): Array<Record<string, string>> {\n\tif (!rows?.length) return [];\n\treturn rows.map((row) => {\n\t\tconst masked: Record<string, string> = {};\n\t\tObject.entries(row).forEach(([key, value]) => {\n\t\t\tif (value === null) masked[key] = \"null\";\n\t\t\telse if (Array.isArray(value)) masked[key] = \"array\";\n\t\t\telse masked[key] = typeof value;\n\t\t});\n\t\treturn masked;\n\t});\n}\n","const WRAPPER_REGEX =\n /^(Nullable|LowCardinality|SimpleAggregateFunction)\\((.+)\\)$/i;\n\nexport function isNullableType(type: string): boolean {\n return /Nullable\\s*\\(/i.test(type);\n}\n\nexport function unwrapTypeModifiers(type: string): string {\n let current = type.trim();\n let match = WRAPPER_REGEX.exec(current);\n while (match) {\n const inner = match[2];\n if (!inner) {\n break;\n }\n current = inner.trim();\n match = WRAPPER_REGEX.exec(current);\n }\n return current;\n}\n\nexport function extractPrecisionScale(type: string): {\n precision?: number;\n scale?: number;\n} {\n const unwrapped = unwrapTypeModifiers(type);\n const decimalMatch = unwrapped.match(/Decimal(?:\\d+)?\\((\\d+)\\s*,\\s*(\\d+)\\)/i);\n if (!decimalMatch) return {};\n const precision = decimalMatch[1];\n const scale = decimalMatch[2];\n if (!precision || !scale) return {};\n return {\n precision: Number.parseInt(precision, 10),\n scale: Number.parseInt(scale, 10),\n };\n}\n\nexport function extractFixedStringLength(type: string): number | undefined {\n const unwrapped = unwrapTypeModifiers(type);\n const match = unwrapped.match(/^(?:FixedString|StringFixed)\\((\\d+)\\)$/i);\n if (!match) return undefined;\n const length = match[1];\n if (!length) return undefined;\n return Number.parseInt(length, 10);\n}\n\nexport function parseKeyExpression(expression?: string | null): string[] {\n if (!expression) return [];\n let value = expression.trim();\n if (!value) return [];\n if (/^tuple\\s*\\(/i.test(value) && value.endsWith(\")\")) {\n value = value.replace(/^tuple\\s*\\(/i, \"\").replace(/\\)$/, \"\");\n }\n\n const columns: string[] = [];\n let depth = 0;\n let token = \"\";\n for (const ch of value) {\n if (ch === \"(\") {\n depth += 1;\n token += ch;\n continue;\n }\n if (ch === \")\") {\n depth = Math.max(0, depth - 1);\n token += ch;\n continue;\n }\n if (ch === \",\" && depth === 0) {\n const col = token.trim();\n if (col) columns.push(stripWrapper(col));\n token = \"\";\n continue;\n }\n token += ch;\n }\n const last = token.trim();\n if (last) columns.push(stripWrapper(last));\n return columns.filter(Boolean);\n}\n\nfunction stripWrapper(value: string): string {\n const noQuotes = stripQuotes(value);\n const withoutTicks = noQuotes.replace(/`/g, \"\").trim();\n const parts = withoutTicks.split(\".\");\n return parts[parts.length - 1]?.trim() ?? \"\";\n}\n\nfunction stripQuotes(value: string): string {\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n return value.slice(1, -1);\n }\n return value;\n}\n","import type {\n ColumnSchema,\n IntrospectOptions,\n SchemaIntrospection,\n TableSchema,\n} from \"../schema/types\";\nimport {\n extractFixedStringLength,\n extractPrecisionScale,\n isNullableType,\n parseKeyExpression,\n unwrapTypeModifiers,\n} from \"../utils/clickhouse\";\nimport type { DatabaseAdapter, DatabaseExecutionResult } from \"./types\";\n\ntype QueryParams = {\n query: string;\n format?: string;\n};\n\ntype ClickHouseSettings = Record<string, unknown>;\ntype Row = Record<string, unknown>;\n\nexport interface ClickHouseAdapterOptions {\n /** Optional logical database name used in introspection metadata. */\n database?: string;\n /** Override the default response format used for query execution. */\n defaultFormat?: QueryParams[\"format\"];\n /**\n * Optional database kind label. Defaults to \"clickhouse\" but allows\n * sub-classing/custom branding if needed.\n */\n kind?: SchemaIntrospection[\"db\"][\"kind\"];\n /**\n * Optional allow-list of table names.\n * When specified, introspection and queries are restricted to these tables only.\n * ClickHouse tables are not schema-qualified, so just provide table names.\n */\n allowedTables?: string[];\n}\n\nexport type ClickHouseQueryResult = { json: () => Promise<unknown> };\n\nexport type ClickHouseClientFn = (\n params: QueryParams & {\n query_params?: Record<string, unknown>;\n clickhouse_settings?: ClickHouseSettings;\n },\n) => Promise<ClickHouseQueryResult | Array<Record<string, unknown>> | Row[]>;\n\ninterface QueryOptions {\n params?: Record<string, unknown>;\n format?: QueryParams[\"format\"];\n settings?: Record<string, unknown>;\n}\n\ntype TableRow = {\n name: string;\n engine: string;\n comment: string | null;\n total_rows: string | number | null;\n total_bytes: string | number | null;\n primary_key: string | null;\n sorting_key?: string | null;\n};\n\ntype ColumnRow = {\n table: string;\n name: string;\n type: string;\n position: number;\n default_kind: string | null;\n default_expression: string | null;\n comment: string | null;\n is_in_primary_key: string | number | null;\n};\n\nexport class ClickHouseAdapter implements DatabaseAdapter {\n private readonly databaseName: string;\n private readonly defaultFormat: QueryParams[\"format\"];\n private readonly kind: SchemaIntrospection[\"db\"][\"kind\"];\n private readonly allowedTables?: string[];\n\n constructor(\n private readonly clientFn: ClickHouseClientFn,\n options: ClickHouseAdapterOptions = {},\n ) {\n this.databaseName = options.database ?? \"default\";\n this.defaultFormat = options.defaultFormat ?? \"JSONEachRow\";\n this.kind = options.kind ?? \"clickhouse\";\n if (options.allowedTables) {\n this.allowedTables = normalizeTableFilter(options.allowedTables);\n }\n }\n\n async execute(\n sql: string,\n params?: Record<string, string | number | boolean | string[] | number[]>,\n ): Promise<DatabaseExecutionResult> {\n // Validate query against allowed tables if restrictions are in place\n if (this.allowedTables) {\n this.validateQueryTables(sql);\n }\n\n const queryOptions: QueryOptions = {\n format: this.defaultFormat,\n };\n if (params) {\n queryOptions.params = params;\n }\n\n const rows = await this.query<Record<string, unknown>>(sql, queryOptions);\n const fields = rows.length > 0 ? Object.keys(rows[0] ?? {}) : [];\n return { fields, rows };\n }\n\n async validate(\n sql: string,\n params?: Record<string, string | number | boolean | string[] | number[]>,\n ): Promise<void> {\n const queryOptions: QueryOptions = {\n format: this.defaultFormat,\n };\n if (params) {\n queryOptions.params = params;\n }\n\n await this.query(`EXPLAIN ${sql}`, queryOptions);\n }\n\n getDialect() {\n return \"clickhouse\" as const;\n }\n\n async introspect(options?: IntrospectOptions): Promise<SchemaIntrospection> {\n // Use adapter-level allowedTables if no specific tables provided in options\n const tablesToIntrospect = options?.tables\n ? normalizeTableFilter(options.tables)\n : this.allowedTables;\n const allowTables = tablesToIntrospect ?? [];\n const hasFilter = allowTables.length > 0;\n const queryParams: Record<string, unknown> = {\n db: this.databaseName,\n };\n if (hasFilter) {\n queryParams.tables = allowTables;\n }\n\n const filterClause = hasFilter ? \" AND name IN {tables:Array(String)}\" : \"\";\n const tables = await this.query<TableRow>(\n `SELECT name, engine, comment, total_rows, total_bytes, primary_key, sorting_key\n FROM system.tables\n WHERE database = {db:String}${filterClause}\n ORDER BY name`,\n { params: queryParams },\n );\n\n const columnFilterClause = hasFilter\n ? \" AND table IN {tables:Array(String)}\"\n : \"\";\n const columns = await this.query<ColumnRow>(\n `SELECT table, name, type, position, default_kind, default_expression, comment, is_in_primary_key\n FROM system.columns\n WHERE database = {db:String}${columnFilterClause}\n ORDER BY table, position`,\n { params: queryParams },\n );\n\n const columnsByTable = new Map<string, ColumnSchema[]>();\n for (const rawColumn of columns) {\n const list = columnsByTable.get(rawColumn.table) ?? [];\n list.push(transformColumnRow(rawColumn));\n columnsByTable.set(rawColumn.table, list);\n }\n\n const tableSchemas: TableSchema[] = tables.map((table) => {\n const tableColumns = columnsByTable.get(table.name) ?? [];\n const primaryKeyColumns = parseKeyExpression(table.primary_key);\n const totalRows = toNumber(table.total_rows);\n const totalBytes = toNumber(table.total_bytes);\n\n for (const column of tableColumns) {\n column.isPrimaryKey =\n column.isPrimaryKey || primaryKeyColumns.includes(column.name);\n }\n\n const indexes = primaryKeyColumns.length\n ? [\n {\n name: \"primary_key\",\n columns: primaryKeyColumns,\n unique: true,\n type: \"PRIMARY KEY\",\n ...(table.primary_key ? { definition: table.primary_key } : {}),\n },\n ]\n : [];\n\n const constraints = primaryKeyColumns.length\n ? [\n {\n name: \"primary_key\",\n type: \"PRIMARY KEY\",\n columns: primaryKeyColumns,\n },\n ]\n : [];\n\n const base: TableSchema = {\n name: table.name,\n schema: this.databaseName,\n type: asTableType(table.engine),\n engine: table.engine,\n columns: tableColumns,\n indexes,\n constraints,\n };\n\n const comment = sanitize(table.comment);\n if (comment !== undefined) {\n base.comment = comment;\n }\n\n const statistics = buildTableStatistics(totalRows, totalBytes);\n if (statistics) {\n base.statistics = statistics;\n }\n\n return base;\n });\n\n return {\n db: {\n kind: this.kind,\n name: this.databaseName,\n },\n tables: tableSchemas,\n introspectedAt: new Date().toISOString(),\n };\n }\n\n /**\n * Validate that the SQL query only references allowed tables.\n * This is a basic validation that extracts table-like patterns from the query.\n */\n private validateQueryTables(sql: string): void {\n if (!this.allowedTables || this.allowedTables.length === 0) {\n return;\n }\n\n const allowedSet = new Set(this.allowedTables);\n\n // Extract potential table references from SQL\n // This regex looks for identifiers after FROM/JOIN keywords\n // ClickHouse may use database.table notation\n const tablePattern =\n /(?:FROM|JOIN)\\s+(?:FINAL\\s+)?(?:(?:[a-zA-Z_][a-zA-Z0-9_]*)\\.)?([\"'`]?[a-zA-Z_][a-zA-Z0-9_]*[\"'`]?)/gi;\n const matches = sql.matchAll(tablePattern);\n\n for (const match of matches) {\n const table = match[1]?.replace(/[\"'`]/g, \"\");\n if (table) {\n if (!allowedSet.has(table)) {\n throw new Error(\n `Query references table \"${table}\" which is not in the allowed tables list`,\n );\n }\n }\n }\n }\n\n async close(): Promise<void> {\n // No-op: lifecycle of the underlying client is controlled by the caller.\n }\n\n private async query<T>(sql: string, options?: QueryOptions): Promise<T[]> {\n const params: QueryParams & {\n query_params?: Record<string, unknown>;\n clickhouse_settings?: ClickHouseSettings;\n } = {\n query: sql,\n };\n\n const format = options?.format ?? this.defaultFormat;\n if (format !== undefined) {\n params.format = format;\n }\n\n if (options?.params) {\n params.query_params = options.params;\n }\n\n if (options?.settings) {\n params.clickhouse_settings = options.settings as ClickHouseSettings;\n }\n\n const result = await this.clientFn(params);\n return this.extractRows<T>(result);\n }\n\n private async extractRows<T>(\n result: ClickHouseQueryResult | Array<Record<string, unknown>> | Row[],\n ): Promise<T[]> {\n if (Array.isArray(result)) {\n return result as T[];\n }\n\n if (\n result &&\n typeof (result as ClickHouseQueryResult).json === \"function\"\n ) {\n const payload = await (result as ClickHouseQueryResult).json();\n return normalizePayload<T>(payload);\n }\n\n return [];\n }\n}\n\nfunction normalizePayload<T>(payload: unknown): T[] {\n if (Array.isArray(payload)) {\n return payload as T[];\n }\n if (payload && typeof payload === \"object\") {\n const maybeData = (payload as { data?: unknown }).data;\n if (Array.isArray(maybeData)) {\n return maybeData as T[];\n }\n }\n return [];\n}\n\nfunction normalizeTableFilter(tables?: string[] | null): string[] {\n if (!tables?.length) return [];\n const seen = new Set<string>();\n const normalized: string[] = [];\n for (const table of tables) {\n if (!table) continue;\n const trimmed = table.trim();\n if (!trimmed) continue;\n const parts = trimmed.split(\".\");\n const tableName = parts[parts.length - 1];\n if (!tableName || seen.has(tableName)) continue;\n seen.add(tableName);\n normalized.push(tableName);\n }\n return normalized;\n}\n\nfunction transformColumnRow(row: ColumnRow): ColumnSchema {\n const nullable = isNullableType(row.type);\n const unwrappedType = unwrapTypeModifiers(row.type);\n const { precision, scale } = extractPrecisionScale(row.type);\n const maxLength = extractFixedStringLength(row.type);\n\n const column: ColumnSchema = {\n name: row.name,\n type: unwrappedType,\n rawType: row.type,\n nullable,\n isPrimaryKey: Boolean(toNumber(row.is_in_primary_key)),\n isForeignKey: false,\n };\n\n const defaultKind = sanitize(row.default_kind);\n if (defaultKind !== undefined) column.defaultKind = defaultKind;\n\n const defaultExpression = sanitize(row.default_expression);\n if (defaultExpression !== undefined) {\n column.defaultExpression = defaultExpression;\n }\n\n const comment = sanitize(row.comment);\n if (comment !== undefined) column.comment = comment;\n\n if (maxLength !== undefined) column.maxLength = maxLength;\n if (precision !== undefined) column.precision = precision;\n if (scale !== undefined) column.scale = scale;\n\n return column;\n}\n\nfunction asTableType(engine: unknown): TableSchema[\"type\"] {\n if (typeof engine === \"string\") {\n const normalized = engine.toLowerCase();\n // ClickHouse view engines: View, MaterializedView, LiveView\n if (normalized.includes(\"view\")) {\n return \"view\";\n }\n }\n return \"table\";\n}\n\nfunction buildTableStatistics(\n totalRows?: number,\n totalBytes?: number,\n): TableSchema[\"statistics\"] | undefined {\n if (totalRows === undefined && totalBytes === undefined) return undefined;\n const stats: NonNullable<TableSchema[\"statistics\"]> = {};\n if (totalRows !== undefined) stats.totalRows = totalRows;\n if (totalBytes !== undefined) stats.totalBytes = totalBytes;\n return stats;\n}\n\nfunction sanitize(value: unknown): string | undefined {\n if (value === null || value === undefined) return undefined;\n const trimmed = String(value).trim();\n return trimmed.length ? trimmed : undefined;\n}\n\nfunction toNumber(value: unknown): number | undefined {\n if (value === null || value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = Number.parseFloat(String(value));\n return Number.isNaN(parsed) ? undefined : parsed;\n}\n","import type {\n\tColumnSchema,\n\tConstraintSchema,\n\tIndexSchema,\n\tIntrospectOptions,\n\tSchemaIntrospection,\n\tTableSchema,\n} from \"../schema/types\";\nimport type { DatabaseAdapter, DatabaseExecutionResult } from \"./types\";\n\nexport interface PostgresQueryResult {\n\trows: Array<Record<string, unknown>>;\n\tfields: Array<{ name: string }>;\n}\n\nexport type PostgresClientFn = (\n\tsql: string,\n\tparams?: unknown[],\n) => Promise<PostgresQueryResult>;\n\nexport interface PostgresAdapterOptions {\n\t/** Logical database name used in introspection metadata. */\n\tdatabase?: string;\n\t/** Schema to assume when a table is provided without qualification. */\n\tdefaultSchema?: string;\n\t/** Optional database kind label. Defaults to \"postgres\". */\n\tkind?: SchemaIntrospection[\"db\"][\"kind\"];\n\t/**\n\t * Optional allow-list of table names (schema-qualified or bare).\n\t * When specified, introspection and queries are restricted to these tables only.\n\t */\n\tallowedTables?: string[];\n}\n\ntype TableRow = {\n\ttable_name: string;\n\tschema_name: string;\n\ttable_type: string;\n\tcomment: string | null;\n\ttotal_rows: number | null;\n\ttotal_bytes: number | null;\n};\n\ntype ColumnRow = {\n\ttable_name: string;\n\ttable_schema: string;\n\tcolumn_name: string;\n\tdata_type: string;\n\tudt_name: string | null;\n\tis_nullable: string;\n\tcolumn_default: string | null;\n\tcharacter_maximum_length: number | null;\n\tnumeric_precision: number | null;\n\tnumeric_scale: number | null;\n\tordinal_position: number;\n\tdescription: string | null;\n};\n\ntype ConstraintRow = {\n\ttable_schema: string;\n\ttable_name: string;\n\tconstraint_name: string;\n\tconstraint_type: string;\n\tcolumn_name: string | null;\n\tforeign_table_schema: string | null;\n\tforeign_table_name: string | null;\n\tforeign_column_name: string | null;\n};\n\ntype IndexRow = {\n\tschema_name: string;\n\ttable_name: string;\n\tindex_name: string;\n\tindisunique: boolean;\n\tcolumn_names: string[] | null;\n\tdefinition: string | null;\n};\n\ninterface NormalizedTable {\n\tschema: string;\n\ttable: string;\n}\n\nexport class PostgresAdapter implements DatabaseAdapter {\n\tprivate readonly databaseName: string;\n\tprivate readonly defaultSchema: string;\n\tprivate readonly kind: SchemaIntrospection[\"db\"][\"kind\"];\n\tprivate readonly allowedTables?: NormalizedTable[];\n\n\tconstructor(\n\t\tprivate readonly clientFn: PostgresClientFn,\n\t\toptions: PostgresAdapterOptions = {},\n\t) {\n\t\tthis.databaseName = options.database ?? \"postgres\";\n\t\tthis.defaultSchema = options.defaultSchema ?? \"public\";\n\t\tthis.kind = options.kind ?? \"postgres\";\n\t\tif (options.allowedTables) {\n\t\t\tthis.allowedTables = normalizeTableFilter(\n\t\t\t\toptions.allowedTables,\n\t\t\t\tthis.defaultSchema,\n\t\t\t);\n\t\t}\n\t}\n\n\tasync execute(\n\t\tsql: string,\n\t\tparams?: Record<string, string | number | boolean | string[] | number[]>,\n\t): Promise<DatabaseExecutionResult> {\n\t\t// Validate query against allowed tables if restrictions are in place\n\t\tif (this.allowedTables) {\n\t\t\tthis.validateQueryTables(sql);\n\t\t}\n\n\t\t// Convert named params to positional array for PostgreSQL\n\t\tlet paramArray: unknown[] | undefined;\n\t\tif (params) {\n\t\t\tparamArray = this.convertNamedToPositionalParams(params);\n\t\t}\n\n\t\tconst result = await this.clientFn(sql, paramArray);\n\t\tconst fields = result.fields.map((f) => f.name);\n\t\treturn { fields, rows: result.rows };\n\t}\n\n\t/**\n\t * Validate that the SQL query only references allowed tables.\n\t * This is a basic validation that extracts table-like patterns from the query.\n\t */\n\tprivate validateQueryTables(sql: string): void {\n\t\tif (!this.allowedTables || this.allowedTables.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst allowedSet = new Set(\n\t\t\tthis.allowedTables.map((t) => tableKey(t.schema, t.table)),\n\t\t);\n\n\t\t// Extract potential table references from SQL\n\t\t// This regex looks for identifiers after FROM/JOIN keywords\n\t\tconst tablePattern =\n\t\t\t/(?:FROM|JOIN)\\s+(?:ONLY\\s+)?(?:([a-zA-Z_][a-zA-Z0-9_]*)\\.)?([\"']?[a-zA-Z_][a-zA-Z0-9_]*[\"']?)/gi;\n\t\tconst matches = sql.matchAll(tablePattern);\n\n\t\tfor (const match of matches) {\n\t\t\tconst schema = match[1] ?? this.defaultSchema;\n\t\t\tconst table = match[2]?.replace(/['\"]/g, \"\");\n\t\t\tif (table) {\n\t\t\t\tconst key = tableKey(schema, table);\n\t\t\t\tif (!allowedSet.has(key)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Query references table \"${schema}.${table}\" which is not in the allowed tables list`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Convert named params to positional array for PostgreSQL\n\t * PostgreSQL expects $1, $2, $3 in SQL and an array of values [val1, val2, val3]\n\t *\n\t * Supports two formats:\n\t * 1. Numeric keys: { '1': 'value1', '2': 'value2' } - maps directly to $1, $2\n\t * 2. Named keys: { 'tenant_id': 'value' } - values extracted in alphabetical order\n\t * 3. Mixed: { '1': 'value1', 'tenant_id': 'value' } - numeric keys first, then named keys\n\t */\n\tprivate convertNamedToPositionalParams(\n\t\tparams: Record<string, string | number | boolean | string[] | number[]>,\n\t): unknown[] {\n\t\t// Separate numeric and named keys\n\t\tconst numericKeys = Object.keys(params)\n\t\t\t.filter((k) => /^\\d+$/.test(k))\n\t\t\t.map((k) => Number.parseInt(k, 10))\n\t\t\t.sort((a, b) => a - b);\n\n\t\tconst namedKeys = Object.keys(params)\n\t\t\t.filter((k) => !/^\\d+$/.test(k))\n\t\t\t.sort(); // Alphabetical order for consistency\n\n\t\t// Build positional array\n\t\tconst positionalParams: unknown[] = [];\n\n\t\t// First, add values from numeric keys (in sorted order)\n\t\tfor (const key of numericKeys) {\n\t\t\tlet val: unknown = params[String(key)];\n\t\t\tif (typeof val === \"string\") {\n\t\t\t\t// Resolve placeholder tokens like `<tenant_id>` to their named values\n\t\t\t\tconst match = val.match(/^<([a-zA-Z0-9_]+)>$/);\n\t\t\t\tconst namedKey = match?.[1];\n\t\t\t\tif (namedKey && namedKey in params) {\n\t\t\t\t\tval = params[namedKey as keyof typeof params];\n\t\t\t\t}\n\t\t\t}\n\t\t\tpositionalParams.push(val);\n\t\t}\n\n\t\t// Then, add values from named keys (in alphabetical order)\n\t\t// This handles cases where tenant isolation adds named params like {'tenant_id': 'value'}\n\t\tfor (const key of namedKeys) {\n\t\t\tconst val = params[key];\n\t\t\tpositionalParams.push(val);\n\t\t}\n\n\t\treturn positionalParams;\n\t}\n\n\tasync validate(\n\t\tsql: string,\n\t\tparams?: Record<string, string | number | boolean | string[] | number[]>,\n\t): Promise<void> {\n\t\t// Convert named params to positional array for PostgreSQL\n\t\tlet paramArray: unknown[] | undefined;\n\t\tif (params) {\n\t\t\tparamArray = this.convertNamedToPositionalParams(params);\n\t\t}\n\n\t\tawait this.clientFn(`EXPLAIN ${sql}`, paramArray);\n\t}\n\n\tgetDialect() {\n\t\treturn \"postgres\" as const;\n\t}\n\n\tasync introspect(options?: IntrospectOptions): Promise<SchemaIntrospection> {\n\t\t// Use adapter-level allowedTables if no specific tables provided in options\n\t\tconst tablesToIntrospect = options?.tables\n\t\t\t? normalizeTableFilter(options.tables, this.defaultSchema)\n\t\t\t: this.allowedTables;\n\t\tconst normalizedTables = tablesToIntrospect ?? [];\n\n\t\tconst tablesResult = await this.clientFn(\n\t\t\tbuildTablesQuery(normalizedTables),\n\t\t);\n\t\tconst tableRows = tablesResult.rows as TableRow[];\n\n\t\tconst columnsResult = await this.clientFn(\n\t\t\tbuildColumnsQuery(normalizedTables),\n\t\t);\n\t\tconst columnRows = columnsResult.rows as ColumnRow[];\n\n\t\tconst constraintsResult = await this.clientFn(\n\t\t\tbuildConstraintsQuery(normalizedTables),\n\t\t);\n\t\tconst constraintRows = constraintsResult.rows as ConstraintRow[];\n\n\t\tconst indexesResult = await this.clientFn(\n\t\t\tbuildIndexesQuery(normalizedTables),\n\t\t);\n\t\tconst indexRows = indexesResult.rows as IndexRow[];\n\n\t\tconst tablesByKey = new Map<string, TableSchema>();\n\t\tconst columnsByKey = new Map<string, Map<string, ColumnSchema>>();\n\n\t\tfor (const row of tableRows) {\n\t\t\tconst key = tableKey(row.schema_name, row.table_name);\n\t\t\tconst statistics = buildTableStatistics(\n\t\t\t\ttoNumber(row.total_rows),\n\t\t\t\ttoNumber(row.total_bytes),\n\t\t\t);\n\n\t\t\tconst table: TableSchema = {\n\t\t\t\tname: row.table_name,\n\t\t\t\tschema: row.schema_name,\n\t\t\t\ttype: asTableType(row.table_type),\n\t\t\t\tcolumns: [],\n\t\t\t\tindexes: [],\n\t\t\t\tconstraints: [],\n\t\t\t};\n\n\t\t\tconst comment = sanitize(row.comment);\n\t\t\tif (comment !== undefined) {\n\t\t\t\ttable.comment = comment;\n\t\t\t}\n\t\t\tif (statistics) {\n\t\t\t\ttable.statistics = statistics;\n\t\t\t}\n\n\t\t\ttablesByKey.set(key, table);\n\t\t\tcolumnsByKey.set(key, new Map());\n\t\t}\n\n\t\tfor (const row of columnRows) {\n\t\t\tconst key = tableKey(row.table_schema, row.table_name);\n\t\t\tconst table = tablesByKey.get(key);\n\t\t\tif (!table) continue;\n\n\t\t\tconst column: ColumnSchema = {\n\t\t\t\tname: row.column_name,\n\t\t\t\ttype: row.data_type,\n\t\t\t\tnullable: row.is_nullable.toUpperCase() === \"YES\",\n\t\t\t\tisPrimaryKey: false,\n\t\t\t\tisForeignKey: false,\n\t\t\t};\n\n\t\t\tconst rawType = row.udt_name ?? undefined;\n\t\t\tif (rawType !== undefined) column.rawType = rawType;\n\n\t\t\tconst defaultExpression = sanitize(row.column_default);\n\t\t\tif (defaultExpression !== undefined)\n\t\t\t\tcolumn.defaultExpression = defaultExpression;\n\n\t\t\tconst comment = sanitize(row.description);\n\t\t\tif (comment !== undefined) column.comment = comment;\n\n\t\t\tconst maxLength = row.character_maximum_length ?? undefined;\n\t\t\tif (maxLength !== undefined) column.maxLength = maxLength;\n\n\t\t\tconst precision = row.numeric_precision ?? undefined;\n\t\t\tif (precision !== undefined) column.precision = precision;\n\n\t\t\tconst scale = row.numeric_scale ?? undefined;\n\t\t\tif (scale !== undefined) column.scale = scale;\n\n\t\t\ttable.columns.push(column);\n\t\t\tcolumnsByKey.get(key)?.set(row.column_name, column);\n\t\t}\n\n\t\tconst constraintGroups = groupConstraints(constraintRows);\n\t\tfor (const group of constraintGroups) {\n\t\t\tconst key = tableKey(group.table_schema, group.table_name);\n\t\t\tconst table = tablesByKey.get(key);\n\t\t\tif (!table) continue;\n\n\t\t\tconst constraint: ConstraintSchema = {\n\t\t\t\tname: group.constraint_name,\n\t\t\t\ttype: group.constraint_type,\n\t\t\t\tcolumns: [...group.columns],\n\t\t\t};\n\n\t\t\tif (group.type === \"FOREIGN KEY\") {\n\t\t\t\tif (group.foreign_table_name) {\n\t\t\t\t\tconst referencedTable = group.foreign_table_schema\n\t\t\t\t\t\t? `${group.foreign_table_schema}.${group.foreign_table_name}`\n\t\t\t\t\t\t: group.foreign_table_name;\n\t\t\t\t\tconstraint.referencedTable = referencedTable;\n\t\t\t\t}\n\t\t\t\tif (group.foreign_columns.length) {\n\t\t\t\t\tconstraint.referencedColumns = [...group.foreign_columns];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttable.constraints.push(constraint);\n\n\t\t\tfor (let index = 0; index < group.columns.length; index += 1) {\n\t\t\t\tconst columnName = group.columns[index];\n\t\t\t\tif (!columnName) continue;\n\t\t\t\tconst column = columnsByKey.get(key)?.get(columnName);\n\t\t\t\tif (!column) continue;\n\t\t\t\tif (group.type === \"PRIMARY KEY\") {\n\t\t\t\t\tcolumn.isPrimaryKey = true;\n\t\t\t\t}\n\t\t\t\tif (group.type === \"FOREIGN KEY\") {\n\t\t\t\t\tcolumn.isForeignKey = true;\n\t\t\t\t\tif (group.foreign_table_name) {\n\t\t\t\t\t\tcolumn.foreignKeyTable = group.foreign_table_schema\n\t\t\t\t\t\t\t? `${group.foreign_table_schema}.${group.foreign_table_name}`\n\t\t\t\t\t\t\t: group.foreign_table_name;\n\t\t\t\t\t}\n\t\t\t\t\tconst referencedColumn = group.foreign_columns[index];\n\t\t\t\t\tif (referencedColumn) {\n\t\t\t\t\t\tcolumn.foreignKeyColumn = referencedColumn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const row of indexRows) {\n\t\t\tconst key = tableKey(row.schema_name, row.table_name);\n\t\t\tconst table = tablesByKey.get(key);\n\t\t\tif (!table) continue;\n\t\t\tconst columns = coerceStringArray(row.column_names)\n\t\t\t\t.map((c) => c.trim())\n\t\t\t\t.filter(Boolean);\n\t\t\tconst index: IndexSchema = {\n\t\t\t\tname: row.index_name,\n\t\t\t\tcolumns,\n\t\t\t\tunique: Boolean(row.indisunique),\n\t\t\t\ttype: columns.length === 1 ? \"INDEX\" : \"COMPOSITE INDEX\",\n\t\t\t};\n\t\t\tconst definition = sanitize(row.definition);\n\t\t\tif (definition !== undefined) index.definition = definition;\n\t\t\ttable.indexes.push(index);\n\t\t}\n\n\t\tconst tables = Array.from(tablesByKey.values()).sort((a, b) => {\n\t\t\tif (a.schema === b.schema) {\n\t\t\t\treturn a.name.localeCompare(b.name);\n\t\t\t}\n\t\t\treturn a.schema.localeCompare(b.schema);\n\t\t});\n\n\t\treturn {\n\t\t\tdb: {\n\t\t\t\tkind: this.kind,\n\t\t\t\tname: this.databaseName,\n\t\t\t},\n\t\t\ttables,\n\t\t\tintrospectedAt: new Date().toISOString(),\n\t\t};\n\t}\n}\n\ninterface ConstraintGroup {\n\ttable_schema: string;\n\ttable_name: string;\n\tconstraint_name: string;\n\tconstraint_type: ConstraintSchema[\"type\"];\n\tcolumns: string[];\n\tforeign_table_schema?: string | null;\n\tforeign_table_name?: string | null;\n\tforeign_columns: string[];\n\ttype: ConstraintSchema[\"type\"];\n}\n\nfunction groupConstraints(rows: ConstraintRow[]): ConstraintGroup[] {\n\tconst groups = new Map<string, ConstraintGroup>();\n\n\tfor (const row of rows) {\n\t\tconst key = `${row.table_schema}.${row.table_name}.${row.constraint_name}`;\n\t\tlet group = groups.get(key);\n\t\tif (!group) {\n\t\t\tgroup = {\n\t\t\t\ttable_schema: row.table_schema,\n\t\t\t\ttable_name: row.table_name,\n\t\t\t\tconstraint_name: row.constraint_name,\n\t\t\t\tconstraint_type: row.constraint_type,\n\t\t\t\tcolumns: [],\n\t\t\t\tforeign_columns: [],\n\t\t\t\ttype: row.constraint_type,\n\t\t\t};\n\t\t\tgroups.set(key, group);\n\t\t}\n\n\t\tif (row.column_name) {\n\t\t\tgroup.columns.push(row.column_name);\n\t\t}\n\n\t\tif (row.constraint_type === \"FOREIGN KEY\") {\n\t\t\tgroup.foreign_table_schema = row.foreign_table_schema;\n\t\t\tgroup.foreign_table_name = row.foreign_table_name;\n\t\t\tif (row.foreign_column_name) {\n\t\t\t\tgroup.foreign_columns.push(row.foreign_column_name);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn Array.from(groups.values());\n}\n\nfunction normalizeTableFilter(\n\ttables: string[] | undefined,\n\tdefaultSchema: string,\n): NormalizedTable[] {\n\tif (!tables?.length) return [];\n\tconst normalized: NormalizedTable[] = [];\n\tconst seen = new Set<string>();\n\n\tfor (const raw of tables) {\n\t\tif (!raw) continue;\n\t\tconst trimmed = raw.trim();\n\t\tif (!trimmed) continue;\n\t\tconst parts = trimmed.split(\".\");\n\t\tconst table = parts.pop() ?? \"\";\n\t\tconst schema = parts.pop() ?? defaultSchema;\n\t\tif (!isSafeIdentifier(schema) || !isSafeIdentifier(table)) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst key = tableKey(schema, table);\n\t\tif (seen.has(key)) continue;\n\t\tseen.add(key);\n\t\tnormalized.push({ schema, table });\n\t}\n\n\treturn normalized;\n}\n\nfunction buildTablesQuery(tables: NormalizedTable[]): string {\n\tconst filter = buildFilterClause(tables, \"n.nspname\", \"c.relname\");\n\treturn `SELECT\n c.relname AS table_name,\n n.nspname AS schema_name,\n CASE c.relkind\n WHEN 'r' THEN 'table'\n WHEN 'v' THEN 'view'\n WHEN 'm' THEN 'materialized_view'\n ELSE c.relkind::text\n END AS table_type,\n obj_description(c.oid) AS comment,\n c.reltuples AS total_rows,\n pg_total_relation_size(c.oid) AS total_bytes\n FROM pg_class c\n JOIN pg_namespace n ON n.oid = c.relnamespace\n WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')\n AND c.relkind IN ('r', 'v', 'm')\n ${filter}\n ORDER BY n.nspname, c.relname;`;\n}\n\nfunction buildColumnsQuery(tables: NormalizedTable[]): string {\n\tconst filter = buildFilterClause(\n\t\ttables,\n\t\t\"cols.table_schema\",\n\t\t\"cols.table_name\",\n\t);\n\treturn `SELECT\n cols.table_name,\n cols.table_schema,\n cols.column_name,\n cols.data_type,\n cols.udt_name,\n cols.is_nullable,\n cols.column_default,\n cols.character_maximum_length,\n cols.numeric_precision,\n cols.numeric_scale,\n cols.ordinal_position,\n pgd.description\n FROM information_schema.columns cols\n LEFT JOIN pg_catalog.pg_class c\n ON c.relname = cols.table_name\n AND c.relkind IN ('r', 'v', 'm')\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n LEFT JOIN pg_catalog.pg_attribute attr\n ON attr.attrelid = c.oid\n AND attr.attname = cols.column_name\n LEFT JOIN pg_catalog.pg_description pgd\n ON pgd.objoid = attr.attrelid AND pgd.objsubid = attr.attnum\n WHERE cols.table_schema NOT IN ('pg_catalog', 'information_schema')\n ${filter}\n ORDER BY cols.table_schema, cols.table_name, cols.ordinal_position;`;\n}\n\nfunction buildConstraintsQuery(tables: NormalizedTable[]): string {\n\tconst filter = buildFilterClause(tables, \"tc.table_schema\", \"tc.table_name\");\n\treturn `SELECT\n tc.table_schema,\n tc.table_name,\n tc.constraint_name,\n tc.constraint_type,\n kcu.column_name,\n ccu.table_schema AS foreign_table_schema,\n ccu.table_name AS foreign_table_name,\n ccu.column_name AS foreign_column_name\n FROM information_schema.table_constraints tc\n LEFT JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n LEFT JOIN information_schema.constraint_column_usage ccu\n ON ccu.constraint_name = tc.constraint_name\n AND ccu.table_schema = tc.table_schema\n WHERE tc.constraint_type IN ('PRIMARY KEY', 'UNIQUE', 'FOREIGN KEY')\n AND tc.table_schema NOT IN ('pg_catalog', 'information_schema')\n ${filter}\n ORDER BY tc.table_schema, tc.table_name, tc.constraint_name, kcu.ordinal_position;`;\n}\n\nfunction buildIndexesQuery(tables: NormalizedTable[]): string {\n\tconst filter = buildFilterClause(tables, \"n.nspname\", \"c.relname\");\n\treturn `SELECT\n n.nspname AS schema_name,\n c.relname AS table_name,\n ci.relname AS index_name,\n idx.indisunique,\n array_remove(\n array_agg(pg_get_indexdef(idx.indexrelid, g.k, true) ORDER BY g.k),\n NULL\n ) AS column_names,\n pg_get_indexdef(idx.indexrelid) AS definition\n FROM pg_class c\n JOIN pg_namespace n ON n.oid = c.relnamespace\n JOIN pg_index idx ON idx.indrelid = c.oid\n JOIN pg_class ci ON ci.oid = idx.indexrelid\n JOIN LATERAL generate_subscripts(idx.indkey, 1) AS g(k) ON true\n WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')\n ${filter}\n GROUP BY n.nspname, c.relname, ci.relname, idx.indisunique, idx.indexrelid;`;\n}\n\nfunction buildFilterClause(\n\ttables: NormalizedTable[],\n\tschemaExpr: string,\n\ttableExpr: string,\n): string {\n\tif (!tables.length) return \"\";\n\tconst clauses = tables.map(({ schema, table }) => {\n\t\treturn `(${schemaExpr} = '${schema}' AND ${tableExpr} = '${table}')`;\n\t});\n\treturn `AND (${clauses.join(\" OR \")})`;\n}\n\nfunction tableKey(schema: string, table: string): string {\n\treturn `${schema}.${table}`;\n}\n\nfunction isSafeIdentifier(value: string): boolean {\n\treturn /^[A-Za-z_][A-Za-z0-9_]*$/.test(value);\n}\n\nfunction asTableType(value: string): TableSchema[\"type\"] {\n\tconst normalized = value.toLowerCase();\n\tif (normalized.includes(\"view\")) {\n\t\treturn normalized.includes(\"materialized\") ? \"materialized_view\" : \"view\";\n\t}\n\treturn \"table\";\n}\n\nfunction buildTableStatistics(\n\ttotalRows?: number,\n\ttotalBytes?: number,\n): TableSchema[\"statistics\"] | undefined {\n\tif (totalRows === undefined && totalBytes === undefined) return undefined;\n\tconst stats: NonNullable<TableSchema[\"statistics\"]> = {};\n\tif (totalRows !== undefined) stats.totalRows = totalRows;\n\tif (totalBytes !== undefined) stats.totalBytes = totalBytes;\n\treturn stats;\n}\n\nfunction sanitize(value: unknown): string | undefined {\n\tif (value === null || value === undefined) return undefined;\n\tconst trimmed = String(value).trim();\n\treturn trimmed.length ? trimmed : undefined;\n}\n\nfunction toNumber(value: unknown): number | undefined {\n\tif (value === null || value === undefined) return undefined;\n\tif (typeof value === \"number\") return value;\n\tconst parsed = Number.parseFloat(String(value));\n\treturn Number.isNaN(parsed) ? undefined : parsed;\n}\n\nfunction coerceStringArray(value: unknown): string[] {\n\tif (!value) return [];\n\tif (Array.isArray(value)) {\n\t\treturn value.map((entry) => String(entry));\n\t}\n\tconst text = String(value).trim();\n\tif (!text) return [];\n\tconst withoutBraces =\n\t\ttext.startsWith(\"{\") && text.endsWith(\"}\") ? text.slice(1, -1) : text;\n\tif (!withoutBraces) return [];\n\treturn withoutBraces\n\t\t.split(\",\")\n\t\t.map((part) => part.trim().replace(/^\"(.+)\"$/, \"$1\"))\n\t\t.filter(Boolean);\n}\n"],"mappings":"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","names":["normalizeTableFilter","buildTableStatistics","toNumber","asTableType","sanitize"]}