yamchart 0.9.2 → 0.9.4
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.
- package/dist/{advisor-SK2EPAAY.js → advisor-SC64RTZO.js} +11 -11
- package/dist/agent-TZZHNDPK.js +8 -0
- package/dist/{chunk-4P5UHWYK.js → chunk-7CD6UQAV.js} +102 -2
- package/dist/chunk-7CD6UQAV.js.map +1 -0
- package/dist/chunk-7D4SUZUM.js +38 -0
- package/dist/{chunk-EHM6AMMA.js → chunk-EAQXUGP6.js} +65 -2
- package/dist/chunk-EAQXUGP6.js.map +1 -0
- package/dist/{chunk-UDKODFOE.js → chunk-H4L3FNLS.js} +16 -6
- package/dist/chunk-H4L3FNLS.js.map +1 -0
- package/dist/{chunk-OI3EGXVE.js → chunk-NXQ6ZO3V.js} +19 -4
- package/dist/chunk-NXQ6ZO3V.js.map +1 -0
- package/dist/{chunk-65G5DBRO.js → chunk-RM6MNDVF.js} +35 -5
- package/dist/chunk-RM6MNDVF.js.map +1 -0
- package/dist/{chunk-EHYYYKRW.js → chunk-RMIDEBHD.js} +4 -4
- package/dist/{chunk-CWAWATL4.js → chunk-S7YQXEKM.js} +159 -2
- package/dist/chunk-S7YQXEKM.js.map +1 -0
- package/dist/{chunk-ZA6AOQVZ.js → chunk-ZMJPRNOA.js} +2 -2
- package/dist/{compare-ZN6RUOOQ.js → compare-RQFCEZIK.js} +2 -2
- package/dist/{connection-utils-MCJBJEDQ.js → connection-utils-C4FQGBW6.js} +5 -5
- package/dist/{describe-XJ5GXYUE.js → describe-X75C2VDU.js} +7 -7
- package/dist/{dev-PLBVJXT4.js → dev-7YLRQ6SA.js} +27994 -13330
- package/dist/dev-7YLRQ6SA.js.map +1 -0
- package/dist/{dist-VNX77VV5.js → dist-JMLAZUL7.js} +9 -3
- package/dist/{dist-7CRX2GIR.js → dist-MNXSMGV6.js} +3 -3
- package/dist/{dist-OCECEAXB.js → dist-MX5K2ABB.js} +3 -3
- package/dist/{dist-JH7OL7U4.js → dist-NGQG7Z4G.js} +7 -3
- package/dist/{generate-KNER36CB.js → generate-B7FAWVIQ.js} +2 -2
- package/dist/index.js +33 -33
- package/dist/{init-GVBYCLJT.js → init-SECXKD5G.js} +2 -2
- package/dist/{lineage-T5NRHHZN.js → lineage-HYO4RKZT.js} +2 -2
- package/dist/{query-2RB75CRI.js → query-QNRDS74I.js} +5 -5
- package/dist/{reset-password-IZQTDTU7.js → reset-password-HDCLH7PZ.js} +3 -3
- package/dist/{rewrite-database-FDJIXKZ2.js → rewrite-database-BOA4QPUR.js} +2 -2
- package/dist/{sample-3UAL7MVU.js → sample-SKLHBZBU.js} +5 -5
- package/dist/{search-ODC4S575.js → search-4KMETZVX.js} +7 -7
- package/dist/{semantic-RAP3S5PQ.js → semantic-6WKELH5V.js} +2 -2
- package/dist/source-resolver-R7WBIL7M.js +18 -0
- package/dist/{sync-dbt-22QQKT3A.js → sync-dbt-72GVO75P.js} +2 -2
- package/dist/{sync-warehouse-QMCT5B4G.js → sync-warehouse-UWRNUXE7.js} +41 -15
- package/dist/sync-warehouse-UWRNUXE7.js.map +1 -0
- package/dist/{tables-QWHUCBRH.js → tables-V65QUGHK.js} +7 -7
- package/dist/templates/default/docs/yamchart-reference.md +74 -9
- package/dist/{test-KX2GETNF.js → test-UE5OWG3E.js} +5 -5
- package/dist/{update-WMATDZTO.js → update-HWCJNQRP.js} +2 -2
- package/package.json +9 -3
- package/dist/agent-KWKPAYT2.js +0 -8
- package/dist/chunk-4P5UHWYK.js.map +0 -1
- package/dist/chunk-65G5DBRO.js.map +0 -1
- package/dist/chunk-CWAWATL4.js.map +0 -1
- package/dist/chunk-DGUM43GV.js +0 -11
- package/dist/chunk-EHM6AMMA.js.map +0 -1
- package/dist/chunk-OI3EGXVE.js.map +0 -1
- package/dist/chunk-UDKODFOE.js.map +0 -1
- package/dist/dev-PLBVJXT4.js.map +0 -1
- package/dist/source-resolver-6QBBNW3P.js +0 -18
- package/dist/sync-warehouse-QMCT5B4G.js.map +0 -1
- /package/dist/{advisor-SK2EPAAY.js.map → advisor-SC64RTZO.js.map} +0 -0
- /package/dist/{agent-KWKPAYT2.js.map → agent-TZZHNDPK.js.map} +0 -0
- /package/dist/{chunk-DGUM43GV.js.map → chunk-7D4SUZUM.js.map} +0 -0
- /package/dist/{chunk-EHYYYKRW.js.map → chunk-RMIDEBHD.js.map} +0 -0
- /package/dist/{chunk-ZA6AOQVZ.js.map → chunk-ZMJPRNOA.js.map} +0 -0
- /package/dist/{compare-ZN6RUOOQ.js.map → compare-RQFCEZIK.js.map} +0 -0
- /package/dist/{connection-utils-MCJBJEDQ.js.map → connection-utils-C4FQGBW6.js.map} +0 -0
- /package/dist/{describe-XJ5GXYUE.js.map → describe-X75C2VDU.js.map} +0 -0
- /package/dist/{dist-JH7OL7U4.js.map → dist-JMLAZUL7.js.map} +0 -0
- /package/dist/{dist-7CRX2GIR.js.map → dist-MNXSMGV6.js.map} +0 -0
- /package/dist/{dist-OCECEAXB.js.map → dist-MX5K2ABB.js.map} +0 -0
- /package/dist/{dist-VNX77VV5.js.map → dist-NGQG7Z4G.js.map} +0 -0
- /package/dist/{generate-KNER36CB.js.map → generate-B7FAWVIQ.js.map} +0 -0
- /package/dist/{init-GVBYCLJT.js.map → init-SECXKD5G.js.map} +0 -0
- /package/dist/{lineage-T5NRHHZN.js.map → lineage-HYO4RKZT.js.map} +0 -0
- /package/dist/{query-2RB75CRI.js.map → query-QNRDS74I.js.map} +0 -0
- /package/dist/{reset-password-IZQTDTU7.js.map → reset-password-HDCLH7PZ.js.map} +0 -0
- /package/dist/{rewrite-database-FDJIXKZ2.js.map → rewrite-database-BOA4QPUR.js.map} +0 -0
- /package/dist/{sample-3UAL7MVU.js.map → sample-SKLHBZBU.js.map} +0 -0
- /package/dist/{search-ODC4S575.js.map → search-4KMETZVX.js.map} +0 -0
- /package/dist/{semantic-RAP3S5PQ.js.map → semantic-6WKELH5V.js.map} +0 -0
- /package/dist/{source-resolver-6QBBNW3P.js.map → source-resolver-R7WBIL7M.js.map} +0 -0
- /package/dist/{sync-dbt-22QQKT3A.js.map → sync-dbt-72GVO75P.js.map} +0 -0
- /package/dist/{tables-QWHUCBRH.js.map → tables-V65QUGHK.js.map} +0 -0
- /package/dist/{test-KX2GETNF.js.map → test-UE5OWG3E.js.map} +0 -0
- /package/dist/{update-WMATDZTO.js.map → update-HWCJNQRP.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../packages/query/src/parser.ts","../../../packages/query/src/presets.ts","../../../packages/query/src/template.ts","../../../packages/query/src/compiler.ts","../../../packages/query/src/connectors/duckdb.ts","../../../packages/query/src/connectors/postgres.ts","../../../packages/query/src/connectors/mysql.ts","../../../packages/query/src/connectors/sqlite.ts","../../../packages/query/src/connectors/snowflake.ts","../../../packages/query/src/connectors/auth.ts","../../../packages/query/src/connectors/reconnecting.ts","../../../packages/query/src/connectors/index.ts","../../../packages/query/src/test-runner.ts","../../../packages/query/src/index.ts"],"sourcesContent":["import type { ModelMetadata, ModelParam, ReturnColumn } from '@yamchart/schema';\n\nexport interface ParsedModel {\n metadata: ModelMetadata;\n sql: string;\n}\n\ninterface ParseResult extends ModelMetadata {\n sql: string;\n}\n\n/**\n * Parse model metadata from SQL comments.\n *\n * Supports:\n * - @name: model_name\n * - @description: text\n * - @owner: team-name\n * - @tags: [tag1, tag2]\n * - @param name: type = default {option1, option2}\n * - @returns: (multiline)\n * - @tests: (multiline)\n */\nexport function parseModelMetadata(sql: string): ParseResult {\n const lines = sql.split('\\n');\n const metadataLines: string[] = [];\n const sqlLines: string[] = [];\n\n let inMetadata = true;\n let inMultiline: 'returns' | 'tests' | null = null;\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Check if this is a metadata comment\n if (trimmed.startsWith('-- @') || (inMultiline && trimmed.startsWith('--'))) {\n metadataLines.push(trimmed);\n inMetadata = true;\n } else if (trimmed.startsWith('--') && inMetadata && metadataLines.length > 0) {\n // Continuation of metadata block\n metadataLines.push(trimmed);\n } else if (trimmed === '' && inMetadata) {\n // Empty line in metadata section, keep going\n continue;\n } else {\n // SQL content\n inMetadata = false;\n sqlLines.push(line);\n }\n }\n\n // Parse metadata\n const metadata = parseMetadataLines(metadataLines);\n\n if (!metadata.name) {\n throw new Error('Model must have a @name');\n }\n\n return {\n ...metadata,\n name: metadata.name,\n sql: sqlLines.join('\\n').trim(),\n };\n}\n\nfunction parseMetadataLines(lines: string[]): Partial<ModelMetadata> & { sql?: string } {\n const result: Partial<ModelMetadata> = {};\n const params: ModelParam[] = [];\n const returns: ReturnColumn[] = [];\n const tests: string[] = [];\n\n let currentMultiline: 'returns' | 'tests' | null = null;\n\n for (const line of lines) {\n const content = line.replace(/^--\\s*/, '').trim();\n\n // Check for multiline content (indented with -)\n if (currentMultiline && content.startsWith('- ')) {\n const itemContent = content.slice(2).trim();\n\n if (currentMultiline === 'returns') {\n const returnCol = parseReturnColumn(itemContent);\n if (returnCol) returns.push(returnCol);\n } else if (currentMultiline === 'tests') {\n tests.push(itemContent);\n }\n continue;\n }\n\n // Check for new directive\n if (content.startsWith('@')) {\n currentMultiline = null;\n\n if (content.startsWith('@name:')) {\n result.name = content.slice(6).trim();\n } else if (content.startsWith('@description:')) {\n result.description = content.slice(13).trim();\n } else if (content.startsWith('@owner:')) {\n result.owner = content.slice(7).trim();\n } else if (content.startsWith('@tags:')) {\n result.tags = parseTags(content.slice(6).trim());\n } else if (content.startsWith('@param')) {\n const param = parseParam(content.slice(6).trim());\n if (param) params.push(param);\n } else if (content.startsWith('@returns:')) {\n currentMultiline = 'returns';\n } else if (content.startsWith('@tests:')) {\n currentMultiline = 'tests';\n }\n }\n }\n\n if (params.length > 0) result.params = params;\n if (returns.length > 0) result.returns = returns;\n if (tests.length > 0) result.tests = tests;\n\n return result;\n}\n\nfunction parseTags(input: string): string[] {\n // Parse [tag1, tag2, tag3]\n const match = input.match(/\\[(.*)\\]/);\n if (!match?.[1]) return [];\n return match[1].split(',').map(t => t.trim());\n}\n\nfunction parseParam(input: string): ModelParam | null {\n // Parse: name: type = default {option1, option2}\n // Or: name: type = default\n // Or: name: type\n\n const match = input.match(/^(\\w+):\\s*(\\w+(?:\\[\\])?)\\s*(?:=\\s*([^{]+))?\\s*(?:\\{([^}]+)\\})?/);\n if (!match) return null;\n\n const [, name, type, defaultValue, options] = match;\n if (!name || !type) return null;\n\n const param: ModelParam = {\n name: name.trim(),\n type: type.trim() as ModelParam['type'],\n };\n\n if (defaultValue) {\n param.default = defaultValue.trim();\n }\n\n if (options) {\n param.options = options.split(',').map(o => o.trim());\n }\n\n return param;\n}\n\nfunction parseReturnColumn(input: string): ReturnColumn | null {\n // Parse: name: type -- description\n // Or: name: type\n\n const match = input.match(/^(\\w+):\\s*(\\w+)\\s*(?:--\\s*(.+))?/);\n if (!match) return null;\n\n const [, name, type, description] = match;\n if (!name || !type) return null;\n\n const col: ReturnColumn = {\n name: name.trim(),\n type: type.trim(),\n };\n\n if (description) {\n col.description = description.trim();\n }\n\n return col;\n}\n","import {\n subDays,\n subWeeks,\n subMonths,\n subYears,\n subQuarters,\n addDays,\n addWeeks,\n addMonths,\n addYears,\n addQuarters,\n startOfDay,\n startOfWeek,\n startOfYear,\n startOfMonth,\n startOfQuarter,\n endOfDay,\n endOfWeek,\n endOfMonth,\n endOfQuarter,\n endOfYear,\n differenceInDays,\n parseISO,\n format,\n} from 'date-fns';\n\nexport interface DateRange {\n start_date: string;\n end_date: string;\n}\n\nexport interface CustomDateRange {\n type: 'custom';\n start: string;\n end: string;\n}\n\n/**\n * Check if a value is a custom date range object.\n */\nexport function isCustomDateRange(value: unknown): value is CustomDateRange {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as CustomDateRange).type === 'custom' &&\n 'start' in value &&\n 'end' in value\n );\n}\n\n/**\n * Expand a custom date range into start_date and end_date.\n */\nexport function expandCustomDateRange(range: CustomDateRange): DateRange {\n return {\n start_date: range.start,\n end_date: range.end,\n };\n}\n\nexport const DATE_PRESETS = [\n 'today',\n 'yesterday',\n 'last_7_days',\n 'last_30_days',\n 'last_90_days',\n 'last_12_months',\n 'year_to_date',\n 'month_to_date',\n 'quarter_to_date',\n 'previous_month',\n 'previous_quarter',\n 'previous_year',\n] as const;\n\nexport type DatePreset = (typeof DATE_PRESETS)[number];\n\nconst DATE_FORMAT = 'yyyy-MM-dd';\n\nfunction formatDate(date: Date): string {\n return format(date, DATE_FORMAT);\n}\n\n/**\n * Expand a date preset into start_date and end_date.\n * Returns null if preset is not recognized.\n */\nexport function expandDatePreset(preset: string): DateRange | null {\n const now = new Date();\n const today = formatDate(now);\n\n switch (preset) {\n case 'today':\n return {\n start_date: today,\n end_date: today,\n };\n\n case 'yesterday': {\n const yesterday = formatDate(subDays(now, 1));\n return {\n start_date: yesterday,\n end_date: yesterday,\n };\n }\n\n case 'last_7_days': {\n const yesterday = formatDate(subDays(now, 1));\n return {\n start_date: formatDate(subDays(now, 7)),\n end_date: yesterday,\n };\n }\n\n case 'last_30_days': {\n const yesterday = formatDate(subDays(now, 1));\n return {\n start_date: formatDate(subDays(now, 30)),\n end_date: yesterday,\n };\n }\n\n case 'last_90_days': {\n const yesterday = formatDate(subDays(now, 1));\n return {\n start_date: formatDate(subDays(now, 90)),\n end_date: yesterday,\n };\n }\n\n case 'last_12_months': {\n const yesterday = formatDate(subDays(now, 1));\n return {\n start_date: formatDate(subMonths(now, 12)),\n end_date: yesterday,\n };\n }\n\n case 'year_to_date':\n return {\n start_date: formatDate(startOfYear(now)),\n end_date: today,\n };\n\n case 'month_to_date':\n return {\n start_date: formatDate(startOfMonth(now)),\n end_date: today,\n };\n\n case 'quarter_to_date':\n return {\n start_date: formatDate(startOfQuarter(now)),\n end_date: today,\n };\n\n case 'previous_month': {\n const lastMonth = subMonths(now, 1);\n return {\n start_date: formatDate(startOfMonth(lastMonth)),\n end_date: formatDate(endOfMonth(lastMonth)),\n };\n }\n\n case 'previous_quarter': {\n const lastQuarter = subMonths(now, 3);\n return {\n start_date: formatDate(startOfQuarter(lastQuarter)),\n end_date: formatDate(endOfQuarter(lastQuarter)),\n };\n }\n\n case 'previous_year': {\n const lastYear = subYears(now, 1);\n return {\n start_date: formatDate(startOfYear(lastYear)),\n end_date: formatDate(endOfYear(lastYear)),\n };\n }\n\n default:\n return null;\n }\n}\n\n/**\n * Compute the equivalent previous period for a given date range.\n * Uses semantic shifting for named presets, day-length shifting for custom ranges.\n */\nexport function computePreviousPeriod(\n startDate: string,\n endDate: string,\n presetName?: string\n): DateRange {\n const start = parseISO(startDate);\n const end = parseISO(endDate);\n\n switch (presetName) {\n case 'today':\n case 'yesterday': {\n return {\n start_date: formatDate(subDays(start, 1)),\n end_date: formatDate(subDays(end, 1)),\n };\n }\n case 'last_7_days': {\n return {\n start_date: formatDate(subDays(start, 7)),\n end_date: formatDate(subDays(end, 7)),\n };\n }\n case 'last_30_days': {\n return {\n start_date: formatDate(subDays(start, 30)),\n end_date: formatDate(subDays(end, 30)),\n };\n }\n case 'last_90_days': {\n return {\n start_date: formatDate(subDays(start, 90)),\n end_date: formatDate(subDays(end, 90)),\n };\n }\n case 'last_12_months':\n case 'last_365_days': {\n return {\n start_date: formatDate(subMonths(start, 12)),\n end_date: formatDate(subMonths(end, 12)),\n };\n }\n case 'year_to_date': {\n return {\n start_date: formatDate(subYears(start, 1)),\n end_date: formatDate(subYears(end, 1)),\n };\n }\n case 'month_to_date': {\n return {\n start_date: formatDate(subMonths(start, 1)),\n end_date: formatDate(subMonths(end, 1)),\n };\n }\n case 'quarter_to_date': {\n return {\n start_date: formatDate(subQuarters(start, 1)),\n end_date: formatDate(subQuarters(end, 1)),\n };\n }\n case 'previous_month': {\n const shifted = subMonths(start, 1);\n return {\n start_date: formatDate(startOfMonth(shifted)),\n end_date: formatDate(endOfMonth(shifted)),\n };\n }\n case 'previous_quarter': {\n const shifted = subQuarters(start, 1);\n return {\n start_date: formatDate(startOfQuarter(shifted)),\n end_date: formatDate(endOfQuarter(shifted)),\n };\n }\n case 'previous_year': {\n const shifted = subYears(start, 1);\n return {\n start_date: formatDate(startOfYear(shifted)),\n end_date: formatDate(endOfYear(shifted)),\n };\n }\n default: {\n // Custom range: shift back by the range length in days\n const days = differenceInDays(end, start);\n return {\n start_date: formatDate(subDays(start, days)),\n end_date: formatDate(subDays(end, days)),\n };\n }\n }\n}\n\n/**\n * Format a date range as a human-readable label.\n * Same year: \"Jan 17 – Feb 16\"\n * Cross year: \"Dec 18, 2025 – Jan 17, 2026\"\n * Single day: \"Feb 16\"\n */\nexport function formatPeriodLabel(startDate: string, endDate: string): string {\n const start = parseISO(startDate);\n const end = parseISO(endDate);\n\n if (startDate === endDate) {\n return format(start, 'MMM d');\n }\n\n const startYear = start.getFullYear();\n const endYear = end.getFullYear();\n\n if (startYear === endYear) {\n return `${format(start, 'MMM d')} – ${format(end, 'MMM d')}`;\n }\n\n return `${format(start, 'MMM d, yyyy')} – ${format(end, 'MMM d, yyyy')}`;\n}\n\n/**\n * Check if a string is a known date preset.\n */\nexport function isDatePreset(value: string): value is DatePreset {\n return DATE_PRESETS.includes(value as DatePreset);\n}\n\n// --- Relative date range support ---\n\nexport interface RelativeDateRange {\n type: 'relative';\n direction: 'previous' | 'current' | 'next';\n value?: number;\n unit: 'day' | 'week' | 'month' | 'quarter' | 'year';\n includeToday?: boolean;\n}\n\n/**\n * Check if a value is a relative date range object.\n */\nexport function isRelativeDateRange(value: unknown): value is RelativeDateRange {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n (value as RelativeDateRange).type === 'relative'\n );\n}\n\n/**\n * Expand a relative date range into start_date and end_date.\n */\nexport function expandRelativeDateRange(rel: RelativeDateRange): DateRange {\n const now = new Date();\n const today = startOfDay(now);\n\n if (rel.direction === 'current') {\n switch (rel.unit) {\n case 'day':\n return { start_date: formatDate(today), end_date: formatDate(today) };\n case 'week':\n return {\n start_date: formatDate(startOfWeek(today, { weekStartsOn: 1 })),\n end_date: formatDate(endOfWeek(today, { weekStartsOn: 1 })),\n };\n case 'month':\n return { start_date: formatDate(startOfMonth(today)), end_date: formatDate(endOfMonth(today)) };\n case 'quarter':\n return { start_date: formatDate(startOfQuarter(today)), end_date: formatDate(endOfQuarter(today)) };\n case 'year':\n return { start_date: formatDate(startOfYear(today)), end_date: formatDate(endOfYear(today)) };\n }\n }\n\n const n = rel.value ?? 1;\n\n if (rel.direction === 'previous') {\n const end = rel.includeToday ? today : subDays(today, 1);\n const shiftFns = { day: subDays, week: subWeeks, month: subMonths, quarter: subQuarters, year: subYears };\n const start = shiftFns[rel.unit](rel.includeToday ? today : today, n);\n return {\n start_date: formatDate(start < end ? start : end),\n end_date: formatDate(start < end ? end : start),\n };\n }\n\n // next\n const start = rel.includeToday ? today : addDays(today, 1);\n const shiftFns = { day: addDays, week: addWeeks, month: addMonths, quarter: addQuarters, year: addYears };\n const end = shiftFns[rel.unit](start, n);\n return {\n start_date: formatDate(start < end ? start : end),\n end_date: formatDate(start < end ? end : start),\n };\n}\n","import nunjucks from 'nunjucks';\n\n// Configure Nunjucks environment\nconst env = new nunjucks.Environment(null, {\n autoescape: false, // SQL doesn't need HTML escaping\n throwOnUndefined: false, // user.x may be undefined for RLS\n});\n\n/**\n * Array subclass that renders as SQL-safe quoted, comma-separated values.\n * Used for multi_select parameters so {{ param }} produces 'val1', 'val2'.\n * Remains iterable for {% for item in param %} loops.\n */\nexport class SqlList extends Array<string> {\n override toString(): string {\n return this.map(v => `'${String(v).replace(/'/g, \"''\")}'`).join(', ');\n }\n}\n\nexport interface TemplateContext {\n [key: string]: unknown;\n ref: (name: string) => string;\n}\n\nexport interface ModelRefs {\n [modelName: string]: string; // model name -> table/subquery\n}\n\n/**\n * Create a template context with parameters and ref() function.\n * Array values are wrapped in SqlList so {{ param }} auto-quotes for SQL IN clauses.\n */\nexport function createTemplateContext(\n params: Record<string, unknown>,\n refs: ModelRefs = {},\n userContext?: Record<string, unknown>\n): TemplateContext {\n const processed: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(params)) {\n if (Array.isArray(value)) {\n const list = new SqlList(...value);\n processed[key] = list;\n } else {\n processed[key] = value;\n }\n }\n\n return {\n ...processed,\n user: userContext ?? {},\n ref: (name: string): string => {\n const resolved = refs[name];\n if (resolved === undefined) {\n throw new Error(`Unknown model reference: ${name}`);\n }\n return resolved;\n },\n };\n}\n\n/**\n * Render a SQL template with the given context.\n */\nexport function renderTemplate(\n template: string,\n context: Record<string, unknown>\n): string {\n const rendered = env.renderString(template, context);\n // Clean up extra whitespace from conditionals\n return rendered\n .split('\\n')\n .map(line => line.trimEnd())\n .filter((line, i, arr) => {\n // Remove consecutive blank lines\n if (line === '' && arr[i - 1] === '') return false;\n return true;\n })\n .join('\\n')\n .trim();\n}\n\n/**\n * Check if a template contains a specific variable reference.\n */\nexport function templateHasVariable(template: string, varName: string): boolean {\n // Match {{ varName }} or {{ varName | filter }}\n const regex = new RegExp(`\\\\{\\\\{\\\\s*${varName}(?:\\\\s*\\\\|[^}]+)?\\\\s*\\\\}\\\\}`, 'g');\n return regex.test(template);\n}\n\n/**\n * Extract all variable names from a template.\n */\nexport function extractTemplateVariables(template: string): string[] {\n const variables = new Set<string>();\n\n // Match {{ variable }} or {{ variable | filter }}\n const regex = /\\{\\{\\s*(\\w+)(?:\\s*\\|[^}]+)?\\s*\\}\\}/g;\n let match;\n\n while ((match = regex.exec(template)) !== null) {\n const varName = match[1];\n // Exclude built-in functions\n if (varName && varName !== 'ref' && varName !== 'loop') {\n variables.add(varName);\n }\n }\n\n return Array.from(variables);\n}\n","import type { Chart, ModelMetadata } from '@yamchart/schema';\nimport { renderTemplate, createTemplateContext, type ModelRefs } from './template.js';\nimport { expandDatePreset, isDatePreset, isCustomDateRange, expandCustomDateRange, isRelativeDateRange, expandRelativeDateRange } from './presets.js';\nimport { createHash } from 'node:crypto';\nimport {\n format,\n subDays,\n addDays,\n startOfYear,\n startOfMonth,\n startOfQuarter,\n endOfYear,\n endOfMonth,\n endOfQuarter,\n} from 'date-fns';\n\n/**\n * Resolve dynamic default values like current_date(), today, today - 30d to actual dates.\n *\n * Supported expressions:\n * - current_date, current_date(), now() → today's date\n * - today → today's date\n * - today - 30, today - 30d → 30 days ago\n * - today + 7, today + 7d → 7 days from now\n * - start_of_year, start_of_month, start_of_quarter → period boundaries\n * - end_of_year, end_of_month, end_of_quarter → period boundaries\n */\nexport function resolveDynamicDefault(value: unknown): unknown {\n if (typeof value !== 'string') return value;\n\n const trimmed = value.trim().toLowerCase();\n\n // Exact matches: current_date, now(), today\n if (\n trimmed === 'current_date()' ||\n trimmed === 'current_date' ||\n trimmed === 'now()' ||\n trimmed === 'today'\n ) {\n return format(new Date(), 'yyyy-MM-dd');\n }\n\n // Period boundary functions\n const now = new Date();\n switch (trimmed) {\n case 'start_of_year':\n return format(startOfYear(now), 'yyyy-MM-dd');\n case 'start_of_month':\n return format(startOfMonth(now), 'yyyy-MM-dd');\n case 'start_of_quarter':\n return format(startOfQuarter(now), 'yyyy-MM-dd');\n case 'end_of_year':\n return format(endOfYear(now), 'yyyy-MM-dd');\n case 'end_of_month':\n return format(endOfMonth(now), 'yyyy-MM-dd');\n case 'end_of_quarter':\n return format(endOfQuarter(now), 'yyyy-MM-dd');\n }\n\n // Date arithmetic: today - 30, today - 30d, today + 7, today + 7d\n // Also: current_date - 30, current_date() - 30\n const arithMatch = trimmed.match(\n /^(?:today|current_date(?:\\(\\))?)\\s*([+-])\\s*(\\d+)\\s*d?$/\n );\n if (arithMatch) {\n const [, op, numStr] = arithMatch;\n const days = parseInt(numStr!, 10);\n const result = op === '-' ? subDays(now, days) : addDays(now, days);\n return format(result, 'yyyy-MM-dd');\n }\n\n return value;\n}\n\nexport interface CompiledQuery {\n sql: string;\n params: Record<string, unknown>;\n cacheKey: string;\n chartName: string;\n}\n\nexport interface CompilerConfig {\n models: Record<string, { metadata: ModelMetadata; sql: string }>;\n refs: ModelRefs;\n}\n\nexport class QueryCompiler {\n private models: Map<string, { metadata: ModelMetadata; sql: string }>;\n private refs: ModelRefs;\n\n constructor(config: CompilerConfig) {\n this.models = new Map(Object.entries(config.models));\n this.refs = config.refs;\n }\n\n /**\n * Compile a chart definition into an executable SQL query.\n */\n compile(\n chart: Chart,\n inputParams: Record<string, unknown>,\n userContext?: Record<string, unknown>\n ): CompiledQuery {\n // Get SQL template\n const { sql, modelParams } = this.getSQL(chart);\n\n // Merge parameters: model defaults < chart defaults < input params\n const params = this.resolveParams(chart, modelParams, inputParams);\n\n // Expand date presets (pass inputParams to avoid overwriting explicit start_date/end_date)\n const expandedParams = this.expandPresets(params, inputParams);\n\n // Create template context with params, refs, and user context\n const context = createTemplateContext(expandedParams, this.refs, userContext);\n\n // Render template\n const renderedSQL = renderTemplate(sql, context);\n\n // Generate cache key (includes user context hash for RLS)\n const cacheKey = this.generateCacheKey(chart.name, renderedSQL, expandedParams, userContext);\n\n return {\n sql: renderedSQL,\n params: expandedParams,\n cacheKey,\n chartName: chart.name,\n };\n }\n\n private getSQL(chart: Chart): { sql: string; modelParams: ModelMetadata['params'] } {\n if (chart.source.sql) {\n return { sql: chart.source.sql, modelParams: undefined };\n }\n\n if (chart.source.model) {\n const model = this.models.get(chart.source.model);\n if (!model) {\n throw new Error(`Unknown model: ${chart.source.model}`);\n }\n return { sql: model.sql, modelParams: model.metadata.params };\n }\n\n throw new Error('Chart source must specify either model or sql');\n }\n\n private resolveParams(\n chart: Chart,\n modelParams: ModelMetadata['params'],\n inputParams: Record<string, unknown>\n ): Record<string, unknown> {\n const params: Record<string, unknown> = {};\n\n // Apply model parameter defaults (resolve dynamic values like current_date())\n if (modelParams) {\n for (const param of modelParams) {\n if (param.default !== undefined) {\n params[param.name] = resolveDynamicDefault(param.default);\n }\n }\n }\n\n // Apply chart parameter defaults (resolve dynamic values)\n if (chart.parameters) {\n for (const param of chart.parameters) {\n if (param.default !== undefined) {\n params[param.name] = resolveDynamicDefault(param.default);\n }\n }\n }\n\n // Apply input params (overrides defaults)\n Object.assign(params, inputParams);\n\n return params;\n }\n\n private expandPresets(params: Record<string, unknown>, inputParams: Record<string, unknown>): Record<string, unknown> {\n const expanded: Record<string, unknown> = { ...params };\n\n // If input explicitly provided start_date and end_date, don't overwrite from date_range.\n // This prevents previous-period comparison queries from having their dates\n // clobbered by a default date_range parameter re-expanding to the current period.\n if (inputParams.start_date && inputParams.end_date) {\n return expanded;\n }\n\n // Check for date_range and expand it (preset string, custom range, or relative range)\n if (isRelativeDateRange(params.date_range)) {\n const dateRange = expandRelativeDateRange(params.date_range);\n expanded.start_date = dateRange.start_date;\n expanded.end_date = dateRange.end_date;\n } else if (isCustomDateRange(params.date_range)) {\n const dateRange = expandCustomDateRange(params.date_range);\n expanded.start_date = dateRange.start_date;\n expanded.end_date = dateRange.end_date;\n } else if (typeof params.date_range === 'string' && isDatePreset(params.date_range)) {\n const dateRange = expandDatePreset(params.date_range);\n if (dateRange) {\n expanded.start_date = dateRange.start_date;\n expanded.end_date = dateRange.end_date;\n }\n }\n\n return expanded;\n }\n\n private generateCacheKey(\n chartName: string,\n sql: string,\n params: Record<string, unknown>,\n userContext?: Record<string, unknown>\n ): string {\n const sqlHash = createHash('sha256').update(sql).digest('hex').slice(0, 8);\n const paramsHash = createHash('sha256')\n .update(JSON.stringify(params, Object.keys(params).sort()))\n .digest('hex')\n .slice(0, 8);\n\n let key = `${chartName}:${sqlHash}:${paramsHash}`;\n\n if (userContext && Object.keys(userContext).length > 0) {\n const userHash = createHash('sha256')\n .update(JSON.stringify(userContext, Object.keys(userContext).sort()))\n .digest('hex')\n .slice(0, 8);\n key += `:${userHash}`;\n }\n\n return key;\n }\n\n /**\n * Add or update a model in the compiler.\n */\n addModel(name: string, metadata: ModelMetadata, sql: string): void {\n this.models.set(name, { metadata, sql });\n }\n\n /**\n * Add or update a ref mapping.\n */\n addRef(name: string, target: string): void {\n this.refs[name] = target;\n }\n}\n","import duckdb from 'duckdb';\nimport { performance } from 'node:perf_hooks';\nimport { serializeDateValue, type Connector, type QueryResult } from './index.js';\n\nexport interface DuckDBConfig {\n path: string; // file path or ':memory:'\n}\n\nexport class DuckDBConnector implements Connector {\n private config: DuckDBConfig;\n private db: duckdb.Database | null = null;\n private connection: duckdb.Connection | null = null;\n\n constructor(config: DuckDBConfig) {\n this.config = config;\n }\n\n async connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n this.db = new duckdb.Database(this.config.path, (err) => {\n if (err) {\n reject(err);\n return;\n }\n this.connection = this.db!.connect();\n resolve();\n });\n });\n }\n\n async disconnect(): Promise<void> {\n return new Promise((resolve) => {\n if (this.connection) {\n this.connection.close(() => {\n this.connection = null;\n });\n }\n if (this.db) {\n this.db.close(() => {\n this.db = null;\n resolve();\n });\n } else {\n resolve();\n }\n });\n }\n\n async execute(sql: string): Promise<QueryResult> {\n if (!this.connection) {\n throw new Error('Not connected to database');\n }\n\n const startTime = performance.now();\n\n return new Promise((resolve, reject) => {\n const stmt = this.connection!.prepare(sql, (prepErr) => {\n if (prepErr) {\n reject(prepErr);\n return;\n }\n\n // Extract column metadata from the prepared statement\n const columnInfo = stmt.columns();\n\n stmt.all((err, rows) => {\n const durationMs = performance.now() - startTime;\n\n if (err) {\n reject(err);\n return;\n }\n\n const typedRows = rows as Array<Record<string, unknown>>;\n // Convert BigInt values to numbers for JSON serialization\n const serializedRows = typedRows.map((row) => this.serializeRow(row));\n\n const columns = columnInfo.map((col) => ({\n name: col.name,\n type: col.type.sql_type,\n }));\n\n stmt.finalize();\n\n resolve({\n columns,\n rows: serializedRows,\n rowCount: serializedRows.length,\n durationMs,\n });\n });\n });\n });\n }\n\n isConnected(): boolean {\n return this.connection !== null;\n }\n\n async explain(sql: string): Promise<{ valid: boolean; error?: string }> {\n if (!this.connection) {\n throw new Error('Not connected to database');\n }\n\n return new Promise((resolve) => {\n this.connection!.all(`EXPLAIN ${sql}`, (err) => {\n if (err) {\n resolve({ valid: false, error: err.message });\n } else {\n resolve({ valid: true });\n }\n });\n });\n }\n\n private serializeRow(row: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(row)) {\n if (typeof value === 'bigint') {\n // Convert BigInt to number for JSON serialization\n result[key] = Number(value);\n } else if (value instanceof Date) {\n result[key] = serializeDateValue(value);\n } else {\n result[key] = value;\n }\n }\n return result;\n }\n}\n","import { performance } from 'node:perf_hooks';\nimport { serializeDateValue, type Connector, type QueryResult } from './index.js';\n\nexport interface PostgresConfig {\n host: string;\n port: number;\n database: string;\n user: string;\n password: string;\n schema?: string;\n ssl?: boolean | object;\n // Pool settings\n min?: number;\n max?: number;\n idleTimeoutMillis?: number;\n connectTimeoutMillis?: number;\n // Query settings\n statementTimeout?: number;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet sdk: any = null;\nlet typeParserConfigured = false;\n\nasync function loadSDK() {\n if (!sdk) {\n try {\n sdk = await import('pg');\n } catch {\n throw new Error(\n 'pg is not installed. Install it with: npm install pg'\n );\n }\n\n // Configure pg to return int8 (bigint) as JavaScript BigInt instead of string\n // OID 20 = int8 in PostgreSQL\n if (!typeParserConfigured) {\n sdk.types.setTypeParser(20, (val: string) => {\n if (val === null) return null;\n return BigInt(val);\n });\n typeParserConfigured = true;\n }\n }\n return sdk;\n}\n\n// Safe identifier escaping for schema names\nfunction escapeIdentifier(identifier: string): string {\n // Only allow alphanumeric and underscores for safety\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(identifier)) {\n throw new Error(`Invalid identifier: ${identifier}`);\n }\n return `\"${identifier}\"`;\n}\n\nexport class PostgresConnector implements Connector {\n private config: PostgresConfig;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private pool: any = null;\n\n constructor(config: PostgresConfig) {\n this.config = config;\n }\n\n async connect(): Promise<void> {\n const pg = await loadSDK();\n\n const poolConfig = {\n host: this.config.host,\n port: this.config.port,\n database: this.config.database,\n user: this.config.user,\n password: this.config.password,\n ssl: this.config.ssl,\n min: this.config.min ?? 2,\n max: this.config.max ?? 10,\n idleTimeoutMillis: this.config.idleTimeoutMillis ?? 30000,\n connectionTimeoutMillis: this.config.connectTimeoutMillis ?? 10000,\n statement_timeout: this.config.statementTimeout,\n };\n\n this.pool = new pg.Pool(poolConfig);\n\n // Handle pool errors (idle client errors)\n this.pool.on('error', (err: Error) => {\n console.error('Unexpected postgres pool error:', err.message);\n });\n\n // Set search_path on each new client from the pool\n if (this.config.schema) {\n const schema = escapeIdentifier(this.config.schema);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.pool.on('connect', (client: any) => {\n client.query(`SET search_path TO ${schema}`).catch((err: Error) => {\n console.error('Failed to set search_path:', err.message);\n });\n });\n }\n\n // Verify connection works\n const client = await this.pool.connect();\n client.release();\n }\n\n async disconnect(): Promise<void> {\n if (this.pool) {\n await this.pool.end();\n this.pool = null;\n }\n }\n\n isConnected(): boolean {\n return this.pool !== null;\n }\n\n async execute(sql: string): Promise<QueryResult> {\n if (!this.pool) {\n throw new Error('Not connected to database');\n }\n\n const start = performance.now();\n const result = await this.pool.query(sql);\n const durationMs = performance.now() - start;\n\n return {\n columns: this.extractColumns(result),\n rows: result.rows.map((row: Record<string, unknown>) => this.serializeRow(row)),\n rowCount: result.rowCount ?? result.rows.length,\n durationMs,\n };\n }\n\n async explain(sql: string): Promise<{ valid: boolean; error?: string }> {\n if (!this.pool) {\n throw new Error('Not connected to database');\n }\n\n try {\n await this.pool.query(`EXPLAIN ${sql}`);\n return { valid: true };\n } catch (err) {\n return {\n valid: false,\n error: err instanceof Error ? err.message : String(err)\n };\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private extractColumns(result: any): Array<{ name: string; type: string }> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return result.fields.map((field: any) => ({\n name: field.name,\n type: this.pgTypeToString(field.dataTypeID),\n }));\n }\n\n private pgTypeToString(oid: number): string {\n // Common Postgres type OIDs\n const typeMap: Record<number, string> = {\n 16: 'boolean', // bool\n 20: 'integer', // int8\n 21: 'integer', // int2\n 23: 'integer', // int4\n 700: 'number', // float4\n 701: 'number', // float8\n 1700: 'number', // numeric\n 25: 'string', // text\n 1043: 'string', // varchar\n 1082: 'date', // date\n 1114: 'date', // timestamp\n 1184: 'date', // timestamptz\n 114: 'unknown', // json\n 3802: 'unknown', // jsonb\n };\n return typeMap[oid] ?? 'unknown';\n }\n\n private serializeRow(row: Record<string, unknown>): Record<string, unknown> {\n const serialized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(row)) {\n serialized[key] = this.serializeValue(value);\n }\n return serialized;\n }\n\n private serializeValue(value: unknown): unknown {\n if (value === null || value === undefined) {\n return null;\n }\n if (typeof value === 'bigint') {\n // Return as string if value exceeds safe integer range to preserve precision\n if (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER) {\n return value.toString();\n }\n return Number(value);\n }\n if (value instanceof Date) {\n return serializeDateValue(value);\n }\n return value;\n }\n}\n","import { performance } from 'node:perf_hooks';\nimport { serializeDateValue, type Connector, type QueryResult } from './index.js';\n\nexport interface MySQLConfig {\n host: string;\n port: number;\n database: string;\n user: string;\n password: string;\n ssl?: boolean | object;\n // Pool settings\n min?: number;\n max?: number;\n idleTimeoutMillis?: number;\n connectTimeoutMillis?: number;\n // Query settings\n statementTimeout?: number;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet sdk: any = null;\n\nasync function loadSDK() {\n if (!sdk) {\n try {\n sdk = await import('mysql2/promise');\n } catch {\n throw new Error(\n 'mysql2 is not installed. Install it with: npm install mysql2'\n );\n }\n }\n return sdk;\n}\n\nexport class MySQLConnector implements Connector {\n private config: MySQLConfig;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private pool: any = null;\n\n constructor(config: MySQLConfig) {\n this.config = config;\n }\n\n async connect(): Promise<void> {\n const mysql = await loadSDK();\n\n const poolConfig = {\n host: this.config.host,\n port: this.config.port,\n database: this.config.database,\n user: this.config.user,\n password: this.config.password,\n ssl: this.config.ssl ? {} : undefined,\n waitForConnections: true,\n connectionLimit: this.config.max ?? 10,\n queueLimit: 0,\n connectTimeout: this.config.connectTimeoutMillis ?? 10000,\n };\n\n this.pool = mysql.createPool(poolConfig);\n\n // Verify connection works\n const connection = await this.pool.getConnection();\n connection.release();\n }\n\n async disconnect(): Promise<void> {\n if (this.pool) {\n await this.pool.end();\n this.pool = null;\n }\n }\n\n isConnected(): boolean {\n return this.pool !== null;\n }\n\n async execute(sql: string): Promise<QueryResult> {\n if (!this.pool) {\n throw new Error('Not connected to database');\n }\n\n const start = performance.now();\n const [rows, fields] = await this.pool.query(sql);\n const durationMs = performance.now() - start;\n\n return {\n columns: this.extractColumns(fields),\n rows: rows.map((row: Record<string, unknown>) => this.serializeRow(row)),\n rowCount: rows.length,\n durationMs,\n };\n }\n\n async explain(sql: string): Promise<{ valid: boolean; error?: string }> {\n if (!this.pool) {\n throw new Error('Not connected to database');\n }\n\n try {\n await this.pool.query(`EXPLAIN ${sql}`);\n return { valid: true };\n } catch (err) {\n return {\n valid: false,\n error: err instanceof Error ? err.message : String(err)\n };\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private extractColumns(fields: any[]): Array<{ name: string; type: string }> {\n return fields.map(field => ({\n name: field.name,\n type: this.mysqlTypeToString(field.type),\n }));\n }\n\n private mysqlTypeToString(type: number | undefined): string {\n // MySQL field type constants\n const typeMap: Record<number, string> = {\n 0: 'number', // DECIMAL\n 1: 'integer', // TINY\n 2: 'integer', // SHORT\n 3: 'integer', // LONG\n 4: 'number', // FLOAT\n 5: 'number', // DOUBLE\n 7: 'date', // TIMESTAMP\n 8: 'integer', // LONGLONG\n 9: 'integer', // INT24\n 10: 'date', // DATE\n 11: 'string', // TIME\n 12: 'date', // DATETIME\n 13: 'integer', // YEAR\n 15: 'string', // VARCHAR\n 245: 'unknown', // JSON\n 246: 'number', // NEWDECIMAL\n 252: 'string', // BLOB\n 253: 'string', // VAR_STRING\n 254: 'string', // STRING\n };\n return typeMap[type ?? 0] ?? 'unknown';\n }\n\n private serializeRow(row: Record<string, unknown>): Record<string, unknown> {\n const serialized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(row)) {\n serialized[key] = this.serializeValue(value);\n }\n return serialized;\n }\n\n private serializeValue(value: unknown): unknown {\n if (value === null || value === undefined) {\n return null;\n }\n if (typeof value === 'bigint') {\n if (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER) {\n return value.toString();\n }\n return Number(value);\n }\n if (value instanceof Date) {\n return serializeDateValue(value);\n }\n if (Buffer.isBuffer(value)) {\n return value.toString('utf-8');\n }\n return value;\n }\n}\n","import Database, { type Database as DatabaseType } from 'better-sqlite3';\nimport { performance } from 'node:perf_hooks';\nimport type { Connector, QueryResult } from './index.js';\n\nexport interface SQLiteConfig {\n path: string; // file path or :memory:\n readonly?: boolean;\n}\n\nexport class SQLiteConnector implements Connector {\n private config: SQLiteConfig;\n private db: DatabaseType | null = null;\n\n constructor(config: SQLiteConfig) {\n this.config = config;\n }\n\n async connect(): Promise<void> {\n this.db = new Database(this.config.path, {\n readonly: this.config.readonly ?? false,\n });\n\n // Enable foreign keys and WAL mode for better performance\n this.db.pragma('journal_mode = WAL');\n this.db.pragma('foreign_keys = ON');\n }\n\n async disconnect(): Promise<void> {\n if (this.db) {\n this.db.close();\n this.db = null;\n }\n }\n\n isConnected(): boolean {\n return this.db !== null;\n }\n\n async execute(sql: string): Promise<QueryResult> {\n if (!this.db) {\n throw new Error('Not connected to database');\n }\n\n const start = performance.now();\n const stmt = this.db.prepare(sql);\n const rows = stmt.all() as Record<string, unknown>[];\n const durationMs = performance.now() - start;\n\n // Extract column info from the statement\n const columns = stmt.columns().map(col => ({\n name: col.name,\n type: this.sqliteTypeToString(col.type),\n }));\n\n return {\n columns,\n rows: rows.map(row => this.serializeRow(row)),\n rowCount: rows.length,\n durationMs,\n };\n }\n\n async explain(sql: string): Promise<{ valid: boolean; error?: string }> {\n if (!this.db) {\n throw new Error('Not connected to database');\n }\n\n try {\n this.db.prepare(`EXPLAIN ${sql}`);\n return { valid: true };\n } catch (err) {\n return {\n valid: false,\n error: err instanceof Error ? err.message : String(err)\n };\n }\n }\n\n private sqliteTypeToString(type: string | null): string {\n if (!type) return 'unknown';\n\n const upperType = type.toUpperCase();\n\n if (upperType.includes('INT')) return 'integer';\n if (upperType.includes('CHAR') || upperType.includes('TEXT') || upperType.includes('CLOB')) return 'string';\n if (upperType.includes('BLOB')) return 'unknown';\n if (upperType.includes('REAL') || upperType.includes('FLOA') || upperType.includes('DOUB')) return 'number';\n if (upperType.includes('NUMERIC') || upperType.includes('DECIMAL')) return 'number';\n if (upperType.includes('DATE') || upperType.includes('TIME')) return 'date';\n if (upperType.includes('BOOL')) return 'boolean';\n\n return 'unknown';\n }\n\n private serializeRow(row: Record<string, unknown>): Record<string, unknown> {\n const serialized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(row)) {\n serialized[key] = this.serializeValue(value);\n }\n return serialized;\n }\n\n private serializeValue(value: unknown): unknown {\n if (value === null || value === undefined) {\n return null;\n }\n if (typeof value === 'bigint') {\n if (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER) {\n return value.toString();\n }\n return Number(value);\n }\n if (Buffer.isBuffer(value)) {\n return value.toString('base64');\n }\n return value;\n }\n}\n","import { performance } from 'node:perf_hooks';\nimport { serializeDateValue, type Connector, type QueryResult } from './index.js';\n\nexport interface SnowflakeConfig {\n account: string;\n username: string;\n password?: string;\n privateKey?: string;\n authenticator?: string;\n clientStoreTemporaryCredential?: boolean;\n warehouse: string;\n database: string;\n schema?: string;\n role?: string;\n // Connection settings\n connectTimeoutMillis?: number;\n // Query settings\n statementTimeout?: number;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet sdk: any = null;\n\nasync function loadSDK() {\n if (!sdk) {\n try {\n sdk = (await import('snowflake-sdk')).default;\n } catch {\n throw new Error(\n 'snowflake-sdk is not installed. Snowflake support requires a separate install:\\n' +\n ' npm install -g snowflake-sdk\\n' +\n 'This package is optional and not bundled with yamchart to keep the default install lightweight.'\n );\n }\n }\n return sdk;\n}\n\nexport class SnowflakeConnector implements Connector {\n private config: SnowflakeConfig;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private connection: any = null;\n\n constructor(config: SnowflakeConfig) {\n this.config = config;\n }\n\n async connect(): Promise<void> {\n const snowflake = await loadSDK();\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const connectionOptions: Record<string, any> = {\n account: this.config.account,\n username: this.config.username,\n password: this.config.password,\n privateKey: this.config.privateKey,\n warehouse: this.config.warehouse,\n database: this.config.database,\n schema: this.config.schema,\n role: this.config.role,\n timeout: this.config.connectTimeoutMillis ?? 60000,\n };\n\n if (this.config.authenticator) {\n connectionOptions.authenticator = this.config.authenticator;\n }\n if (this.config.clientStoreTemporaryCredential !== undefined) {\n connectionOptions.clientStoreTemporaryCredential = this.config.clientStoreTemporaryCredential;\n }\n\n this.connection = snowflake.createConnection(connectionOptions);\n\n if (this.config.authenticator === 'EXTERNALBROWSER') {\n // connectAsync handles browser-based SSO flow\n await this.connection!.connectAsync();\n } else {\n return new Promise((resolve, reject) => {\n this.connection!.connect((err: Error | undefined) => {\n if (err) {\n this.connection = null;\n reject(err);\n } else {\n resolve();\n }\n });\n });\n }\n }\n\n async disconnect(): Promise<void> {\n if (this.connection) {\n return new Promise((resolve, reject) => {\n this.connection!.destroy((err: Error | undefined) => {\n this.connection = null;\n if (err) {\n reject(err);\n } else {\n resolve();\n }\n });\n });\n }\n }\n\n isConnected(): boolean {\n return this.connection !== null && this.connection.isUp();\n }\n\n async execute(sql: string): Promise<QueryResult> {\n if (!this.connection) {\n throw new Error('Not connected to database');\n }\n\n const start = performance.now();\n\n return new Promise((resolve, reject) => {\n this.connection!.execute({\n sqlText: sql,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n complete: (err: Error | undefined, stmt: any, rows: any[]) => {\n const durationMs = performance.now() - start;\n\n if (err) {\n reject(err);\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const columns = stmt ? stmt.getColumns().map((col: any) => ({\n name: col.getName().toLowerCase(),\n type: this.snowflakeTypeToString(col.getType()),\n })) : [];\n\n resolve({\n columns,\n rows: (rows || []).map(row => this.serializeRow(this.lowercaseKeys(row as Record<string, unknown>))),\n rowCount: rows?.length ?? 0,\n durationMs,\n });\n },\n });\n });\n }\n\n async explain(sql: string): Promise<{ valid: boolean; error?: string }> {\n if (!this.connection) {\n throw new Error('Not connected to database');\n }\n\n try {\n await this.execute(`EXPLAIN ${sql}`);\n return { valid: true };\n } catch (err) {\n return {\n valid: false,\n error: err instanceof Error ? err.message : String(err)\n };\n }\n }\n\n private snowflakeTypeToString(type: string): string {\n const typeMap: Record<string, string> = {\n 'NUMBER': 'number',\n 'DECIMAL': 'number',\n 'NUMERIC': 'number',\n 'INT': 'integer',\n 'INTEGER': 'integer',\n 'BIGINT': 'integer',\n 'SMALLINT': 'integer',\n 'TINYINT': 'integer',\n 'BYTEINT': 'integer',\n 'FLOAT': 'number',\n 'FLOAT4': 'number',\n 'FLOAT8': 'number',\n 'DOUBLE': 'number',\n 'DOUBLE PRECISION': 'number',\n 'REAL': 'number',\n 'VARCHAR': 'string',\n 'CHAR': 'string',\n 'CHARACTER': 'string',\n 'STRING': 'string',\n 'TEXT': 'string',\n 'BINARY': 'unknown',\n 'VARBINARY': 'unknown',\n 'BOOLEAN': 'boolean',\n 'DATE': 'date',\n 'DATETIME': 'date',\n 'TIME': 'string',\n 'TIMESTAMP': 'date',\n 'TIMESTAMP_LTZ': 'date',\n 'TIMESTAMP_NTZ': 'date',\n 'TIMESTAMP_TZ': 'date',\n 'VARIANT': 'unknown',\n 'OBJECT': 'unknown',\n 'ARRAY': 'unknown',\n };\n\n const upperType = type.toUpperCase();\n return typeMap[upperType] ?? 'unknown';\n }\n\n private lowercaseKeys(row: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(row)) {\n result[key.toLowerCase()] = value;\n }\n return result;\n }\n\n private serializeRow(row: Record<string, unknown>): Record<string, unknown> {\n const serialized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(row)) {\n serialized[key] = this.serializeValue(value);\n }\n return serialized;\n }\n\n private serializeValue(value: unknown): unknown {\n if (value === null || value === undefined) {\n return null;\n }\n if (typeof value === 'bigint') {\n if (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER) {\n return value.toString();\n }\n return Number(value);\n }\n if (value instanceof Date) {\n return serializeDateValue(value);\n }\n return value;\n }\n}\n","import type { PostgresConnection, MySQLConnection, SnowflakeConnection } from '@yamchart/schema';\n\nexport interface ResolvedCredentials {\n user: string;\n password: string;\n}\n\nexport interface ResolvedSnowflakeCredentials {\n username: string;\n password?: string;\n privateKey?: string;\n authenticator?: string;\n clientStoreTemporaryCredential?: boolean;\n}\n\nexport function resolvePostgresAuth(connection: PostgresConnection): ResolvedCredentials {\n const auth = connection.auth;\n\n // Auth is optional for Postgres (local dev with trust auth)\n if (!auth) {\n return {\n user: process.env.PGUSER ?? 'postgres',\n password: process.env.PGPASSWORD ?? '',\n };\n }\n\n if (auth.type === 'env') {\n const user = process.env[auth.user_var];\n const password = process.env[auth.password_var];\n\n if (!user) {\n throw new Error(`Missing environment variable: ${auth.user_var}`);\n }\n\n return { user, password: password ?? '' };\n }\n\n // key_pair and secret_manager deferred to post-MVP\n throw new Error(`Auth type \"${auth.type}\" not yet implemented`);\n}\n\nexport function resolveMySQLAuth(connection: MySQLConnection): ResolvedCredentials {\n const auth = connection.auth;\n\n // Auth is optional for MySQL (local dev)\n if (!auth) {\n return {\n user: process.env.MYSQL_USER ?? 'root',\n password: process.env.MYSQL_PASSWORD ?? '',\n };\n }\n\n if (auth.type === 'env') {\n const user = process.env[auth.user_var];\n const password = process.env[auth.password_var];\n\n if (!user) {\n throw new Error(`Missing environment variable: ${auth.user_var}`);\n }\n\n return { user, password: password ?? '' };\n }\n\n throw new Error(`Auth type \"${auth.type}\" not yet implemented`);\n}\n\nexport function resolveSnowflakeAuth(connection: SnowflakeConnection): ResolvedSnowflakeCredentials {\n const auth = connection.auth;\n\n if (auth.type === 'env') {\n const username = process.env[auth.user_var];\n const password = process.env[auth.password_var];\n\n if (!username) {\n throw new Error(`Missing environment variable: ${auth.user_var}`);\n }\n\n return { username, password: password ?? undefined };\n }\n\n if (auth.type === 'key_pair') {\n const username = process.env[auth.user_var];\n\n if (!username) {\n throw new Error(`Missing environment variable: ${auth.user_var}`);\n }\n\n // Read private key from file path\n const fs = require('fs');\n const privateKey = fs.readFileSync(auth.private_key_path, 'utf-8');\n\n return { username, privateKey };\n }\n\n if (auth.type === 'externalbrowser') {\n const username = process.env[auth.user_var];\n\n if (!username) {\n throw new Error(`Missing environment variable: ${auth.user_var}`);\n }\n\n return {\n username,\n authenticator: 'EXTERNALBROWSER',\n clientStoreTemporaryCredential: auth.cache_token ?? false,\n };\n }\n\n throw new Error(`Auth type \"${auth.type}\" not yet implemented for Snowflake`);\n}\n","import type { Connector, QueryResult } from './index.js';\n\n/**\n * Error patterns that indicate a stale/terminated connection rather than\n * a query-level error. When these are encountered, the connector will\n * automatically reconnect and retry the operation once.\n */\nconst CONNECTION_ERROR_PATTERNS = [\n 'terminated connection',\n 'socket hang up',\n 'connection reset',\n 'ECONNRESET',\n 'ECONNREFUSED',\n 'ETIMEDOUT',\n 'connection lost',\n 'gone away', // MySQL: \"server has gone away\"\n 'not connected',\n];\n\nfunction isConnectionError(error: unknown): boolean {\n const message = error instanceof Error ? error.message : String(error);\n const lower = message.toLowerCase();\n return CONNECTION_ERROR_PATTERNS.some((pattern) => lower.includes(pattern.toLowerCase()));\n}\n\n/**\n * Wraps a Connector with automatic reconnection logic.\n * When a query fails due to a connection error (e.g. terminated connection\n * after process suspend/resume), the wrapper disconnects, reconnects, and\n * retries the operation once.\n */\nexport class ReconnectingConnector implements Connector {\n private inner: Connector;\n\n constructor(inner: Connector) {\n this.inner = inner;\n }\n\n async connect(): Promise<void> {\n return this.inner.connect();\n }\n\n async disconnect(): Promise<void> {\n return this.inner.disconnect();\n }\n\n isConnected(): boolean {\n return this.inner.isConnected();\n }\n\n async execute(sql: string): Promise<QueryResult> {\n await this.ensureConnected();\n\n try {\n return await this.inner.execute(sql);\n } catch (err) {\n if (isConnectionError(err)) {\n await this.reconnect();\n return this.inner.execute(sql);\n }\n throw err;\n }\n }\n\n async explain(sql: string): Promise<{ valid: boolean; error?: string }> {\n await this.ensureConnected();\n\n try {\n return await this.inner.explain(sql);\n } catch (err) {\n if (isConnectionError(err)) {\n await this.reconnect();\n return this.inner.explain(sql);\n }\n throw err;\n }\n }\n\n private async ensureConnected(): Promise<void> {\n if (!this.inner.isConnected()) {\n await this.reconnect();\n }\n }\n\n private async reconnect(): Promise<void> {\n try { await this.inner.disconnect(); } catch { /* may already be disconnected */ }\n await this.inner.connect();\n }\n}\n","export interface QueryResult {\n columns: Array<{\n name: string;\n type: string;\n }>;\n rows: Array<Record<string, unknown>>;\n rowCount: number;\n durationMs: number;\n}\n\nexport interface Connector {\n connect(): Promise<void>;\n disconnect(): Promise<void>;\n execute(sql: string): Promise<QueryResult>;\n explain(sql: string): Promise<{ valid: boolean; error?: string }>;\n isConnected(): boolean;\n}\n\n/**\n * Serialize a Date value for JSON responses. Dates at midnight UTC are\n * formatted as date-only strings (\"2026-02-19\") to avoid timezone-shift\n * issues on the client. Database DATE columns and day-level aggregations\n * (e.g. date_trunc('day', ...)) produce midnight UTC timestamps that would\n * otherwise display as the previous day in timezones west of UTC.\n */\nexport function serializeDateValue(value: Date): string {\n if (\n value.getUTCHours() === 0 &&\n value.getUTCMinutes() === 0 &&\n value.getUTCSeconds() === 0 &&\n value.getUTCMilliseconds() === 0\n ) {\n const y = value.getUTCFullYear();\n const m = String(value.getUTCMonth() + 1).padStart(2, '0');\n const d = String(value.getUTCDate()).padStart(2, '0');\n return `${y}-${m}-${d}`;\n }\n return value.toISOString();\n}\n\nexport * from './duckdb.js';\nexport * from './postgres.js';\nexport * from './mysql.js';\nexport * from './sqlite.js';\nexport * from './snowflake.js';\nexport * from './auth.js';\nexport * from './reconnecting.js';\n","import type { ModelMetadata, ReturnColumn } from '@yamchart/schema';\nimport type { Connector, QueryResult } from './connectors/index.js';\n\nexport interface AssertionResult {\n sql: string;\n passed: boolean;\n violationCount?: number;\n sampleViolations?: Array<Record<string, unknown>>;\n error?: string;\n warning?: string;\n}\n\nexport interface SchemaCheckResult {\n passed: boolean;\n expectedColumns: string[];\n actualColumns: string[];\n missingColumns: string[];\n extraColumns: string[];\n typeMismatches: Array<{ column: string; expected: string; actual: string }>;\n}\n\nexport interface ModelTestResult {\n modelName: string;\n schemaCheck?: SchemaCheckResult;\n assertions: AssertionResult[];\n durationMs: number;\n error?: string;\n}\n\nexport interface TestSuiteResult {\n models: ModelTestResult[];\n passed: number;\n failed: number;\n skipped: number;\n durationMs: number;\n}\n\nexport interface TestModelInput {\n compiledSql: string;\n metadata: ModelMetadata;\n}\n\nconst TYPE_MAP: Record<string, string[]> = {\n date: ['date', 'timestamp', 'datetime', 'timestamptz', 'timestamp with time zone'],\n number: ['integer', 'int', 'bigint', 'float', 'double', 'decimal', 'numeric', 'real', 'smallint', 'tinyint', 'hugeint', 'int4', 'int8', 'float4', 'float8'],\n integer: ['integer', 'int', 'bigint', 'smallint', 'tinyint', 'hugeint', 'int4', 'int8'],\n string: ['varchar', 'text', 'char', 'string', 'character varying', 'nvarchar'],\n boolean: ['boolean', 'bool'],\n};\n\nfunction typesMatch(expectedType: string, actualType: string): boolean {\n const expected = expectedType.toLowerCase();\n const actual = actualType.toLowerCase();\n if (expected === actual) return true;\n const acceptedTypes = TYPE_MAP[expected];\n if (acceptedTypes) return acceptedTypes.includes(actual);\n return false;\n}\n\n/**\n * Replace {{this}} (with optional whitespace) with compiled model SQL.\n */\nexport function expandThis(assertionSql: string, compiledSql: string): string {\n return assertionSql.replace(/\\{\\{\\s*this\\s*\\}\\}/g, compiledSql);\n}\n\nconst MAX_SAMPLE_VIOLATIONS = 5;\n\nexport async function runAssertion(\n compiledSql: string,\n assertionSql: string,\n connector: Connector,\n): Promise<AssertionResult> {\n const warning = !/\\{\\{\\s*this\\s*\\}\\}/.test(assertionSql)\n ? 'Test assertion does not reference {{this}} — did you mean to include it?'\n : undefined;\n\n const expandedSql = expandThis(assertionSql, compiledSql);\n\n try {\n const result = await connector.execute(expandedSql);\n\n return {\n sql: assertionSql,\n passed: result.rowCount === 0,\n violationCount: result.rowCount,\n sampleViolations: result.rows.slice(0, MAX_SAMPLE_VIOLATIONS),\n warning,\n };\n } catch (err) {\n return {\n sql: assertionSql,\n passed: false,\n error: err instanceof Error ? err.message : String(err),\n warning,\n };\n }\n}\n\nexport async function runModel(\n compiledSql: string,\n metadata: ModelMetadata,\n connector: Connector,\n): Promise<ModelTestResult> {\n const start = performance.now();\n const hasReturns = metadata.returns && metadata.returns.length > 0;\n const hasTests = metadata.tests && metadata.tests.length > 0;\n\n // Nothing to test\n if (!hasReturns && !hasTests) {\n return {\n modelName: metadata.name,\n assertions: [],\n durationMs: performance.now() - start,\n };\n }\n\n // Schema check\n let schemaCheckResult: SchemaCheckResult | undefined;\n if (hasReturns) {\n try {\n schemaCheckResult = await checkSchema(compiledSql, connector, metadata.returns!);\n } catch (err) {\n return {\n modelName: metadata.name,\n assertions: [],\n durationMs: performance.now() - start,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n // Data assertions\n const assertions: AssertionResult[] = [];\n if (hasTests) {\n for (const testSql of metadata.tests!) {\n const result = await runAssertion(compiledSql, testSql, connector);\n assertions.push(result);\n }\n }\n\n return {\n modelName: metadata.name,\n schemaCheck: schemaCheckResult,\n assertions,\n durationMs: performance.now() - start,\n };\n}\n\nexport async function runAll(\n models: TestModelInput[],\n connector: Connector,\n): Promise<TestSuiteResult> {\n const start = performance.now();\n const results: ModelTestResult[] = [];\n let passed = 0;\n let failed = 0;\n let skipped = 0;\n\n for (const model of models) {\n const result = await runModel(model.compiledSql, model.metadata, connector);\n results.push(result);\n\n const hasAnyCheck = result.schemaCheck || result.assertions.length > 0;\n if (!hasAnyCheck && !result.error) {\n skipped++;\n continue;\n }\n\n if (result.error) {\n failed++;\n continue;\n }\n\n // Count individual checks\n if (result.schemaCheck) {\n if (result.schemaCheck.passed) passed++;\n else failed++;\n }\n for (const assertion of result.assertions) {\n if (assertion.passed) passed++;\n else failed++;\n }\n }\n\n return {\n models: results,\n passed,\n failed,\n skipped,\n durationMs: performance.now() - start,\n };\n}\n\nexport async function checkSchema(\n compiledSql: string,\n connector: Connector,\n expectedReturns: ReturnColumn[],\n): Promise<SchemaCheckResult> {\n const wrappedSql = `SELECT * FROM (${compiledSql}) AS _model LIMIT 0`;\n const result = await connector.execute(wrappedSql);\n\n const actualColumns = result.columns.map((c) => c.name);\n const expectedColumns = expectedReturns.map((c) => c.name);\n\n const missingColumns = expectedColumns.filter((name) => !actualColumns.includes(name));\n const extraColumns = actualColumns.filter((name) => !expectedColumns.includes(name));\n\n const typeMismatches: SchemaCheckResult['typeMismatches'] = [];\n for (const expected of expectedReturns) {\n const actual = result.columns.find((c) => c.name === expected.name);\n if (actual && !typesMatch(expected.type, actual.type)) {\n typeMismatches.push({\n column: expected.name,\n expected: expected.type,\n actual: actual.type,\n });\n }\n }\n\n return {\n passed: missingColumns.length === 0 && typeMismatches.length === 0,\n expectedColumns,\n actualColumns,\n missingColumns,\n extraColumns,\n typeMismatches,\n };\n}\n","// Yamchart Query Engine\nexport const VERSION = '0.1.0';\n\nexport * from './parser.js';\nexport * from './presets.js';\nexport * from './template.js';\nexport * from './compiler.js';\nexport * from './connectors/index.js';\nexport * from './test-runner.js';\nexport * from './semantic/index.js';\n"],"mappings":";;;;;AAuBM,SAAU,mBAAmB,KAAW;AAC5C,QAAM,QAAQ,IAAI,MAAM,IAAI;AAC5B,QAAM,gBAA0B,CAAA;AAChC,QAAM,WAAqB,CAAA;AAE3B,MAAI,aAAa;AACjB,MAAI,cAA0C;AAE9C,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,KAAK,KAAI;AAGzB,QAAI,QAAQ,WAAW,MAAM,KAAM,eAAe,QAAQ,WAAW,IAAI,GAAI;AAC3E,oBAAc,KAAK,OAAO;AAC1B,mBAAa;IACf,WAAW,QAAQ,WAAW,IAAI,KAAK,cAAc,cAAc,SAAS,GAAG;AAE7E,oBAAc,KAAK,OAAO;IAC5B,WAAW,YAAY,MAAM,YAAY;AAEvC;IACF,OAAO;AAEL,mBAAa;AACb,eAAS,KAAK,IAAI;IACpB;EACF;AAGA,QAAM,WAAW,mBAAmB,aAAa;AAEjD,MAAI,CAAC,SAAS,MAAM;AAClB,UAAM,IAAI,MAAM,yBAAyB;EAC3C;AAEA,SAAO;IACL,GAAG;IACH,MAAM,SAAS;IACf,KAAK,SAAS,KAAK,IAAI,EAAE,KAAI;;AAEjC;AAEA,SAAS,mBAAmB,OAAe;AACzC,QAAM,SAAiC,CAAA;AACvC,QAAM,SAAuB,CAAA;AAC7B,QAAM,UAA0B,CAAA;AAChC,QAAM,QAAkB,CAAA;AAExB,MAAI,mBAA+C;AAEnD,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,KAAK,QAAQ,UAAU,EAAE,EAAE,KAAI;AAG/C,QAAI,oBAAoB,QAAQ,WAAW,IAAI,GAAG;AAChD,YAAM,cAAc,QAAQ,MAAM,CAAC,EAAE,KAAI;AAEzC,UAAI,qBAAqB,WAAW;AAClC,cAAM,YAAY,kBAAkB,WAAW;AAC/C,YAAI;AAAW,kBAAQ,KAAK,SAAS;MACvC,WAAW,qBAAqB,SAAS;AACvC,cAAM,KAAK,WAAW;MACxB;AACA;IACF;AAGA,QAAI,QAAQ,WAAW,GAAG,GAAG;AAC3B,yBAAmB;AAEnB,UAAI,QAAQ,WAAW,QAAQ,GAAG;AAChC,eAAO,OAAO,QAAQ,MAAM,CAAC,EAAE,KAAI;MACrC,WAAW,QAAQ,WAAW,eAAe,GAAG;AAC9C,eAAO,cAAc,QAAQ,MAAM,EAAE,EAAE,KAAI;MAC7C,WAAW,QAAQ,WAAW,SAAS,GAAG;AACxC,eAAO,QAAQ,QAAQ,MAAM,CAAC,EAAE,KAAI;MACtC,WAAW,QAAQ,WAAW,QAAQ,GAAG;AACvC,eAAO,OAAO,UAAU,QAAQ,MAAM,CAAC,EAAE,KAAI,CAAE;MACjD,WAAW,QAAQ,WAAW,QAAQ,GAAG;AACvC,cAAM,QAAQ,WAAW,QAAQ,MAAM,CAAC,EAAE,KAAI,CAAE;AAChD,YAAI;AAAO,iBAAO,KAAK,KAAK;MAC9B,WAAW,QAAQ,WAAW,WAAW,GAAG;AAC1C,2BAAmB;MACrB,WAAW,QAAQ,WAAW,SAAS,GAAG;AACxC,2BAAmB;MACrB;IACF;EACF;AAEA,MAAI,OAAO,SAAS;AAAG,WAAO,SAAS;AACvC,MAAI,QAAQ,SAAS;AAAG,WAAO,UAAU;AACzC,MAAI,MAAM,SAAS;AAAG,WAAO,QAAQ;AAErC,SAAO;AACT;AAEA,SAAS,UAAU,OAAa;AAE9B,QAAM,QAAQ,MAAM,MAAM,UAAU;AACpC,MAAI,CAAC,QAAQ,CAAC;AAAG,WAAO,CAAA;AACxB,SAAO,MAAM,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAI,CAAE;AAC9C;AAEA,SAAS,WAAW,OAAa;AAK/B,QAAM,QAAQ,MAAM,MAAM,gEAAgE;AAC1F,MAAI,CAAC;AAAO,WAAO;AAEnB,QAAM,CAAC,EAAE,MAAM,MAAM,cAAc,OAAO,IAAI;AAC9C,MAAI,CAAC,QAAQ,CAAC;AAAM,WAAO;AAE3B,QAAM,QAAoB;IACxB,MAAM,KAAK,KAAI;IACf,MAAM,KAAK,KAAI;;AAGjB,MAAI,cAAc;AAChB,UAAM,UAAU,aAAa,KAAI;EACnC;AAEA,MAAI,SAAS;AACX,UAAM,UAAU,QAAQ,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,KAAI,CAAE;EACtD;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,OAAa;AAItC,QAAM,QAAQ,MAAM,MAAM,kCAAkC;AAC5D,MAAI,CAAC;AAAO,WAAO;AAEnB,QAAM,CAAC,EAAE,MAAM,MAAM,WAAW,IAAI;AACpC,MAAI,CAAC,QAAQ,CAAC;AAAM,WAAO;AAE3B,QAAM,MAAoB;IACxB,MAAM,KAAK,KAAI;IACf,MAAM,KAAK,KAAI;;AAGjB,MAAI,aAAa;AACf,QAAI,cAAc,YAAY,KAAI;EACpC;AAEA,SAAO;AACT;;;AC7KA,SACE,SACA,UACA,WACA,UACA,aACA,SACA,UACA,WACA,UACA,aACA,YACA,aACA,aACA,cACA,gBAEA,WACA,YACA,cACA,WACA,kBACA,UACA,cACK;AAgBD,SAAU,kBAAkB,OAAc;AAC9C,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACT,MAA0B,SAAS,YACpC,WAAW,SACX,SAAS;AAEb;AAKM,SAAU,sBAAsB,OAAsB;AAC1D,SAAO;IACL,YAAY,MAAM;IAClB,UAAU,MAAM;;AAEpB;AAEO,IAAM,eAAe;EAC1B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAKF,IAAM,cAAc;AAEpB,SAAS,WAAW,MAAU;AAC5B,SAAO,OAAO,MAAM,WAAW;AACjC;AAMM,SAAU,iBAAiB,QAAc;AAC7C,QAAM,MAAM,oBAAI,KAAI;AACpB,QAAM,QAAQ,WAAW,GAAG;AAE5B,UAAQ,QAAQ;IACd,KAAK;AACH,aAAO;QACL,YAAY;QACZ,UAAU;;IAGd,KAAK,aAAa;AAChB,YAAM,YAAY,WAAW,QAAQ,KAAK,CAAC,CAAC;AAC5C,aAAO;QACL,YAAY;QACZ,UAAU;;IAEd;IAEA,KAAK,eAAe;AAClB,YAAM,YAAY,WAAW,QAAQ,KAAK,CAAC,CAAC;AAC5C,aAAO;QACL,YAAY,WAAW,QAAQ,KAAK,CAAC,CAAC;QACtC,UAAU;;IAEd;IAEA,KAAK,gBAAgB;AACnB,YAAM,YAAY,WAAW,QAAQ,KAAK,CAAC,CAAC;AAC5C,aAAO;QACL,YAAY,WAAW,QAAQ,KAAK,EAAE,CAAC;QACvC,UAAU;;IAEd;IAEA,KAAK,gBAAgB;AACnB,YAAM,YAAY,WAAW,QAAQ,KAAK,CAAC,CAAC;AAC5C,aAAO;QACL,YAAY,WAAW,QAAQ,KAAK,EAAE,CAAC;QACvC,UAAU;;IAEd;IAEA,KAAK,kBAAkB;AACrB,YAAM,YAAY,WAAW,QAAQ,KAAK,CAAC,CAAC;AAC5C,aAAO;QACL,YAAY,WAAW,UAAU,KAAK,EAAE,CAAC;QACzC,UAAU;;IAEd;IAEA,KAAK;AACH,aAAO;QACL,YAAY,WAAW,YAAY,GAAG,CAAC;QACvC,UAAU;;IAGd,KAAK;AACH,aAAO;QACL,YAAY,WAAW,aAAa,GAAG,CAAC;QACxC,UAAU;;IAGd,KAAK;AACH,aAAO;QACL,YAAY,WAAW,eAAe,GAAG,CAAC;QAC1C,UAAU;;IAGd,KAAK,kBAAkB;AACrB,YAAM,YAAY,UAAU,KAAK,CAAC;AAClC,aAAO;QACL,YAAY,WAAW,aAAa,SAAS,CAAC;QAC9C,UAAU,WAAW,WAAW,SAAS,CAAC;;IAE9C;IAEA,KAAK,oBAAoB;AACvB,YAAM,cAAc,UAAU,KAAK,CAAC;AACpC,aAAO;QACL,YAAY,WAAW,eAAe,WAAW,CAAC;QAClD,UAAU,WAAW,aAAa,WAAW,CAAC;;IAElD;IAEA,KAAK,iBAAiB;AACpB,YAAM,WAAW,SAAS,KAAK,CAAC;AAChC,aAAO;QACL,YAAY,WAAW,YAAY,QAAQ,CAAC;QAC5C,UAAU,WAAW,UAAU,QAAQ,CAAC;;IAE5C;IAEA;AACE,aAAO;EACX;AACF;AAMM,SAAU,sBACd,WACA,SACA,YAAmB;AAEnB,QAAM,QAAQ,SAAS,SAAS;AAChC,QAAM,MAAM,SAAS,OAAO;AAE5B,UAAQ,YAAY;IAClB,KAAK;IACL,KAAK,aAAa;AAChB,aAAO;QACL,YAAY,WAAW,QAAQ,OAAO,CAAC,CAAC;QACxC,UAAU,WAAW,QAAQ,KAAK,CAAC,CAAC;;IAExC;IACA,KAAK,eAAe;AAClB,aAAO;QACL,YAAY,WAAW,QAAQ,OAAO,CAAC,CAAC;QACxC,UAAU,WAAW,QAAQ,KAAK,CAAC,CAAC;;IAExC;IACA,KAAK,gBAAgB;AACnB,aAAO;QACL,YAAY,WAAW,QAAQ,OAAO,EAAE,CAAC;QACzC,UAAU,WAAW,QAAQ,KAAK,EAAE,CAAC;;IAEzC;IACA,KAAK,gBAAgB;AACnB,aAAO;QACL,YAAY,WAAW,QAAQ,OAAO,EAAE,CAAC;QACzC,UAAU,WAAW,QAAQ,KAAK,EAAE,CAAC;;IAEzC;IACA,KAAK;IACL,KAAK,iBAAiB;AACpB,aAAO;QACL,YAAY,WAAW,UAAU,OAAO,EAAE,CAAC;QAC3C,UAAU,WAAW,UAAU,KAAK,EAAE,CAAC;;IAE3C;IACA,KAAK,gBAAgB;AACnB,aAAO;QACL,YAAY,WAAW,SAAS,OAAO,CAAC,CAAC;QACzC,UAAU,WAAW,SAAS,KAAK,CAAC,CAAC;;IAEzC;IACA,KAAK,iBAAiB;AACpB,aAAO;QACL,YAAY,WAAW,UAAU,OAAO,CAAC,CAAC;QAC1C,UAAU,WAAW,UAAU,KAAK,CAAC,CAAC;;IAE1C;IACA,KAAK,mBAAmB;AACtB,aAAO;QACL,YAAY,WAAW,YAAY,OAAO,CAAC,CAAC;QAC5C,UAAU,WAAW,YAAY,KAAK,CAAC,CAAC;;IAE5C;IACA,KAAK,kBAAkB;AACrB,YAAM,UAAU,UAAU,OAAO,CAAC;AAClC,aAAO;QACL,YAAY,WAAW,aAAa,OAAO,CAAC;QAC5C,UAAU,WAAW,WAAW,OAAO,CAAC;;IAE5C;IACA,KAAK,oBAAoB;AACvB,YAAM,UAAU,YAAY,OAAO,CAAC;AACpC,aAAO;QACL,YAAY,WAAW,eAAe,OAAO,CAAC;QAC9C,UAAU,WAAW,aAAa,OAAO,CAAC;;IAE9C;IACA,KAAK,iBAAiB;AACpB,YAAM,UAAU,SAAS,OAAO,CAAC;AACjC,aAAO;QACL,YAAY,WAAW,YAAY,OAAO,CAAC;QAC3C,UAAU,WAAW,UAAU,OAAO,CAAC;;IAE3C;IACA,SAAS;AAEP,YAAM,OAAO,iBAAiB,KAAK,KAAK;AACxC,aAAO;QACL,YAAY,WAAW,QAAQ,OAAO,IAAI,CAAC;QAC3C,UAAU,WAAW,QAAQ,KAAK,IAAI,CAAC;;IAE3C;EACF;AACF;AAQM,SAAU,kBAAkB,WAAmB,SAAe;AAClE,QAAM,QAAQ,SAAS,SAAS;AAChC,QAAM,MAAM,SAAS,OAAO;AAE5B,MAAI,cAAc,SAAS;AACzB,WAAO,OAAO,OAAO,OAAO;EAC9B;AAEA,QAAM,YAAY,MAAM,YAAW;AACnC,QAAM,UAAU,IAAI,YAAW;AAE/B,MAAI,cAAc,SAAS;AACzB,WAAO,GAAG,OAAO,OAAO,OAAO,CAAC,WAAM,OAAO,KAAK,OAAO,CAAC;EAC5D;AAEA,SAAO,GAAG,OAAO,OAAO,aAAa,CAAC,WAAM,OAAO,KAAK,aAAa,CAAC;AACxE;AAKM,SAAU,aAAa,OAAa;AACxC,SAAO,aAAa,SAAS,KAAmB;AAClD;AAeM,SAAU,oBAAoB,OAAc;AAChD,SACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACT,MAA4B,SAAS;AAE1C;AAKM,SAAU,wBAAwB,KAAsB;AAC5D,QAAM,MAAM,oBAAI,KAAI;AACpB,QAAM,QAAQ,WAAW,GAAG;AAE5B,MAAI,IAAI,cAAc,WAAW;AAC/B,YAAQ,IAAI,MAAM;MAChB,KAAK;AACH,eAAO,EAAE,YAAY,WAAW,KAAK,GAAG,UAAU,WAAW,KAAK,EAAC;MACrE,KAAK;AACH,eAAO;UACL,YAAY,WAAW,YAAY,OAAO,EAAE,cAAc,EAAC,CAAE,CAAC;UAC9D,UAAU,WAAW,UAAU,OAAO,EAAE,cAAc,EAAC,CAAE,CAAC;;MAE9D,KAAK;AACH,eAAO,EAAE,YAAY,WAAW,aAAa,KAAK,CAAC,GAAG,UAAU,WAAW,WAAW,KAAK,CAAC,EAAC;MAC/F,KAAK;AACH,eAAO,EAAE,YAAY,WAAW,eAAe,KAAK,CAAC,GAAG,UAAU,WAAW,aAAa,KAAK,CAAC,EAAC;MACnG,KAAK;AACH,eAAO,EAAE,YAAY,WAAW,YAAY,KAAK,CAAC,GAAG,UAAU,WAAW,UAAU,KAAK,CAAC,EAAC;IAC/F;EACF;AAEA,QAAM,IAAI,IAAI,SAAS;AAEvB,MAAI,IAAI,cAAc,YAAY;AAChC,UAAMA,OAAM,IAAI,eAAe,QAAQ,QAAQ,OAAO,CAAC;AACvD,UAAMC,YAAW,EAAE,KAAK,SAAS,MAAM,UAAU,OAAO,WAAW,SAAS,aAAa,MAAM,SAAQ;AACvG,UAAMC,SAAQD,UAAS,IAAI,IAAI,EAAE,IAAI,eAAe,QAAQ,OAAO,CAAC;AACpE,WAAO;MACL,YAAY,WAAWC,SAAQF,OAAME,SAAQF,IAAG;MAChD,UAAU,WAAWE,SAAQF,OAAMA,OAAME,MAAK;;EAElD;AAGA,QAAM,QAAQ,IAAI,eAAe,QAAQ,QAAQ,OAAO,CAAC;AACzD,QAAM,WAAW,EAAE,KAAK,SAAS,MAAM,UAAU,OAAO,WAAW,SAAS,aAAa,MAAM,SAAQ;AACvG,QAAM,MAAM,SAAS,IAAI,IAAI,EAAE,OAAO,CAAC;AACvC,SAAO;IACL,YAAY,WAAW,QAAQ,MAAM,QAAQ,GAAG;IAChD,UAAU,WAAW,QAAQ,MAAM,MAAM,KAAK;;AAElD;;;AC3XA,OAAO,cAAc;AAGrB,IAAM,MAAM,IAAI,SAAS,YAAY,MAAM;EACzC,YAAY;;EACZ,kBAAkB;;CACnB;AAOK,IAAO,UAAP,cAAuB,MAAa;EAC/B,WAAQ;AACf,WAAO,KAAK,IAAI,OAAK,IAAI,OAAO,CAAC,EAAE,QAAQ,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI;EACtE;;AAgBI,SAAU,sBACd,QACA,OAAkB,CAAA,GAClB,aAAqC;AAErC,QAAM,YAAqC,CAAA;AAC3C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,YAAM,OAAO,IAAI,QAAQ,GAAG,KAAK;AACjC,gBAAU,GAAG,IAAI;IACnB,OAAO;AACL,gBAAU,GAAG,IAAI;IACnB;EACF;AAEA,SAAO;IACL,GAAG;IACH,MAAM,eAAe,CAAA;IACrB,KAAK,CAAC,SAAwB;AAC5B,YAAM,WAAW,KAAK,IAAI;AAC1B,UAAI,aAAa,QAAW;AAC1B,cAAM,IAAI,MAAM,4BAA4B,IAAI,EAAE;MACpD;AACA,aAAO;IACT;;AAEJ;AAKM,SAAU,eACd,UACA,SAAgC;AAEhC,QAAM,WAAW,IAAI,aAAa,UAAU,OAAO;AAEnD,SAAO,SACJ,MAAM,IAAI,EACV,IAAI,UAAQ,KAAK,QAAO,CAAE,EAC1B,OAAO,CAAC,MAAM,GAAG,QAAO;AAEvB,QAAI,SAAS,MAAM,IAAI,IAAI,CAAC,MAAM;AAAI,aAAO;AAC7C,WAAO;EACT,CAAC,EACA,KAAK,IAAI,EACT,KAAI;AACT;AAKM,SAAU,oBAAoB,UAAkB,SAAe;AAEnE,QAAM,QAAQ,IAAI,OAAO,aAAa,OAAO,+BAA+B,GAAG;AAC/E,SAAO,MAAM,KAAK,QAAQ;AAC5B;AAKM,SAAU,yBAAyB,UAAgB;AACvD,QAAM,YAAY,oBAAI,IAAG;AAGzB,QAAM,QAAQ;AACd,MAAI;AAEJ,UAAQ,QAAQ,MAAM,KAAK,QAAQ,OAAO,MAAM;AAC9C,UAAM,UAAU,MAAM,CAAC;AAEvB,QAAI,WAAW,YAAY,SAAS,YAAY,QAAQ;AACtD,gBAAU,IAAI,OAAO;IACvB;EACF;AAEA,SAAO,MAAM,KAAK,SAAS;AAC7B;;;AC1GA,SAAS,kBAAkB;AAC3B,SACE,UAAAC,SACA,WAAAC,UACA,WAAAC,UACA,eAAAC,cACA,gBAAAC,eACA,kBAAAC,iBACA,aAAAC,YACA,cAAAC,aACA,gBAAAC,qBACK;AAaD,SAAU,sBAAsB,OAAc;AAClD,MAAI,OAAO,UAAU;AAAU,WAAO;AAEtC,QAAM,UAAU,MAAM,KAAI,EAAG,YAAW;AAGxC,MACE,YAAY,oBACZ,YAAY,kBACZ,YAAY,WACZ,YAAY,SACZ;AACA,WAAOR,QAAO,oBAAI,KAAI,GAAI,YAAY;EACxC;AAGA,QAAM,MAAM,oBAAI,KAAI;AACpB,UAAQ,SAAS;IACf,KAAK;AACH,aAAOA,QAAOG,aAAY,GAAG,GAAG,YAAY;IAC9C,KAAK;AACH,aAAOH,QAAOI,cAAa,GAAG,GAAG,YAAY;IAC/C,KAAK;AACH,aAAOJ,QAAOK,gBAAe,GAAG,GAAG,YAAY;IACjD,KAAK;AACH,aAAOL,QAAOM,WAAU,GAAG,GAAG,YAAY;IAC5C,KAAK;AACH,aAAON,QAAOO,YAAW,GAAG,GAAG,YAAY;IAC7C,KAAK;AACH,aAAOP,QAAOQ,cAAa,GAAG,GAAG,YAAY;EACjD;AAIA,QAAM,aAAa,QAAQ,MACzB,yDAAyD;AAE3D,MAAI,YAAY;AACd,UAAM,CAAC,EAAE,IAAI,MAAM,IAAI;AACvB,UAAM,OAAO,SAAS,QAAS,EAAE;AACjC,UAAM,SAAS,OAAO,MAAMP,SAAQ,KAAK,IAAI,IAAIC,SAAQ,KAAK,IAAI;AAClE,WAAOF,QAAO,QAAQ,YAAY;EACpC;AAEA,SAAO;AACT;AAcM,IAAO,gBAAP,MAAoB;EAChB;EACA;EAER,YAAY,QAAsB;AAChC,SAAK,SAAS,IAAI,IAAI,OAAO,QAAQ,OAAO,MAAM,CAAC;AACnD,SAAK,OAAO,OAAO;EACrB;;;;EAKA,QACE,OACA,aACA,aAAqC;AAGrC,UAAM,EAAE,KAAK,YAAW,IAAK,KAAK,OAAO,KAAK;AAG9C,UAAM,SAAS,KAAK,cAAc,OAAO,aAAa,WAAW;AAGjE,UAAM,iBAAiB,KAAK,cAAc,QAAQ,WAAW;AAG7D,UAAM,UAAU,sBAAsB,gBAAgB,KAAK,MAAM,WAAW;AAG5E,UAAM,cAAc,eAAe,KAAK,OAAO;AAG/C,UAAM,WAAW,KAAK,iBAAiB,MAAM,MAAM,aAAa,gBAAgB,WAAW;AAE3F,WAAO;MACL,KAAK;MACL,QAAQ;MACR;MACA,WAAW,MAAM;;EAErB;EAEQ,OAAO,OAAY;AACzB,QAAI,MAAM,OAAO,KAAK;AACpB,aAAO,EAAE,KAAK,MAAM,OAAO,KAAK,aAAa,OAAS;IACxD;AAEA,QAAI,MAAM,OAAO,OAAO;AACtB,YAAM,QAAQ,KAAK,OAAO,IAAI,MAAM,OAAO,KAAK;AAChD,UAAI,CAAC,OAAO;AACV,cAAM,IAAI,MAAM,kBAAkB,MAAM,OAAO,KAAK,EAAE;MACxD;AACA,aAAO,EAAE,KAAK,MAAM,KAAK,aAAa,MAAM,SAAS,OAAM;IAC7D;AAEA,UAAM,IAAI,MAAM,+CAA+C;EACjE;EAEQ,cACN,OACA,aACA,aAAoC;AAEpC,UAAM,SAAkC,CAAA;AAGxC,QAAI,aAAa;AACf,iBAAW,SAAS,aAAa;AAC/B,YAAI,MAAM,YAAY,QAAW;AAC/B,iBAAO,MAAM,IAAI,IAAI,sBAAsB,MAAM,OAAO;QAC1D;MACF;IACF;AAGA,QAAI,MAAM,YAAY;AACpB,iBAAW,SAAS,MAAM,YAAY;AACpC,YAAI,MAAM,YAAY,QAAW;AAC/B,iBAAO,MAAM,IAAI,IAAI,sBAAsB,MAAM,OAAO;QAC1D;MACF;IACF;AAGA,WAAO,OAAO,QAAQ,WAAW;AAEjC,WAAO;EACT;EAEQ,cAAc,QAAiC,aAAoC;AACzF,UAAM,WAAoC,EAAE,GAAG,OAAM;AAKrD,QAAI,YAAY,cAAc,YAAY,UAAU;AAClD,aAAO;IACT;AAGA,QAAI,oBAAoB,OAAO,UAAU,GAAG;AAC1C,YAAM,YAAY,wBAAwB,OAAO,UAAU;AAC3D,eAAS,aAAa,UAAU;AAChC,eAAS,WAAW,UAAU;IAChC,WAAW,kBAAkB,OAAO,UAAU,GAAG;AAC/C,YAAM,YAAY,sBAAsB,OAAO,UAAU;AACzD,eAAS,aAAa,UAAU;AAChC,eAAS,WAAW,UAAU;IAChC,WAAW,OAAO,OAAO,eAAe,YAAY,aAAa,OAAO,UAAU,GAAG;AACnF,YAAM,YAAY,iBAAiB,OAAO,UAAU;AACpD,UAAI,WAAW;AACb,iBAAS,aAAa,UAAU;AAChC,iBAAS,WAAW,UAAU;MAChC;IACF;AAEA,WAAO;EACT;EAEQ,iBACN,WACA,KACA,QACA,aAAqC;AAErC,UAAM,UAAU,WAAW,QAAQ,EAAE,OAAO,GAAG,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,CAAC;AACzE,UAAM,aAAa,WAAW,QAAQ,EACnC,OAAO,KAAK,UAAU,QAAQ,OAAO,KAAK,MAAM,EAAE,KAAI,CAAE,CAAC,EACzD,OAAO,KAAK,EACZ,MAAM,GAAG,CAAC;AAEb,QAAI,MAAM,GAAG,SAAS,IAAI,OAAO,IAAI,UAAU;AAE/C,QAAI,eAAe,OAAO,KAAK,WAAW,EAAE,SAAS,GAAG;AACtD,YAAM,WAAW,WAAW,QAAQ,EACjC,OAAO,KAAK,UAAU,aAAa,OAAO,KAAK,WAAW,EAAE,KAAI,CAAE,CAAC,EACnE,OAAO,KAAK,EACZ,MAAM,GAAG,CAAC;AACb,aAAO,IAAI,QAAQ;IACrB;AAEA,WAAO;EACT;;;;EAKA,SAAS,MAAc,UAAyB,KAAW;AACzD,SAAK,OAAO,IAAI,MAAM,EAAE,UAAU,IAAG,CAAE;EACzC;;;;EAKA,OAAO,MAAc,QAAc;AACjC,SAAK,KAAK,IAAI,IAAI;EACpB;;;;ACnPF,OAAO,YAAY;AACnB,SAAS,eAAAS,oBAAmB;AAOtB,IAAO,kBAAP,MAAsB;EAClB;EACA,KAA6B;EAC7B,aAAuC;EAE/C,YAAY,QAAoB;AAC9B,SAAK,SAAS;EAChB;EAEA,MAAM,UAAO;AACX,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAU;AACrC,WAAK,KAAK,IAAI,OAAO,SAAS,KAAK,OAAO,MAAM,CAAC,QAAO;AACtD,YAAI,KAAK;AACP,iBAAO,GAAG;AACV;QACF;AACA,aAAK,aAAa,KAAK,GAAI,QAAO;AAClC,gBAAO;MACT,CAAC;IACH,CAAC;EACH;EAEA,MAAM,aAAU;AACd,WAAO,IAAI,QAAQ,CAAC,YAAW;AAC7B,UAAI,KAAK,YAAY;AACnB,aAAK,WAAW,MAAM,MAAK;AACzB,eAAK,aAAa;QACpB,CAAC;MACH;AACA,UAAI,KAAK,IAAI;AACX,aAAK,GAAG,MAAM,MAAK;AACjB,eAAK,KAAK;AACV,kBAAO;QACT,CAAC;MACH,OAAO;AACL,gBAAO;MACT;IACF,CAAC;EACH;EAEA,MAAM,QAAQ,KAAW;AACvB,QAAI,CAAC,KAAK,YAAY;AACpB,YAAM,IAAI,MAAM,2BAA2B;IAC7C;AAEA,UAAM,YAAYC,aAAY,IAAG;AAEjC,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAU;AACrC,YAAM,OAAO,KAAK,WAAY,QAAQ,KAAK,CAAC,YAAW;AACrD,YAAI,SAAS;AACX,iBAAO,OAAO;AACd;QACF;AAGA,cAAM,aAAa,KAAK,QAAO;AAE/B,aAAK,IAAI,CAAC,KAAK,SAAQ;AACrB,gBAAM,aAAaA,aAAY,IAAG,IAAK;AAEvC,cAAI,KAAK;AACP,mBAAO,GAAG;AACV;UACF;AAEA,gBAAM,YAAY;AAElB,gBAAM,iBAAiB,UAAU,IAAI,CAAC,QAAQ,KAAK,aAAa,GAAG,CAAC;AAEpE,gBAAM,UAAU,WAAW,IAAI,CAAC,SAAS;YACvC,MAAM,IAAI;YACV,MAAM,IAAI,KAAK;YACf;AAEF,eAAK,SAAQ;AAEb,kBAAQ;YACN;YACA,MAAM;YACN,UAAU,eAAe;YACzB;WACD;QACH,CAAC;MACH,CAAC;IACH,CAAC;EACH;EAEA,cAAW;AACT,WAAO,KAAK,eAAe;EAC7B;EAEA,MAAM,QAAQ,KAAW;AACvB,QAAI,CAAC,KAAK,YAAY;AACpB,YAAM,IAAI,MAAM,2BAA2B;IAC7C;AAEA,WAAO,IAAI,QAAQ,CAAC,YAAW;AAC7B,WAAK,WAAY,IAAI,WAAW,GAAG,IAAI,CAAC,QAAO;AAC7C,YAAI,KAAK;AACP,kBAAQ,EAAE,OAAO,OAAO,OAAO,IAAI,QAAO,CAAE;QAC9C,OAAO;AACL,kBAAQ,EAAE,OAAO,KAAI,CAAE;QACzB;MACF,CAAC;IACH,CAAC;EACH;EAEQ,aAAa,KAA4B;AAC/C,UAAM,SAAkC,CAAA;AACxC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC9C,UAAI,OAAO,UAAU,UAAU;AAE7B,eAAO,GAAG,IAAI,OAAO,KAAK;MAC5B,WAAW,iBAAiB,MAAM;AAChC,eAAO,GAAG,IAAI,mBAAmB,KAAK;MACxC,OAAO;AACL,eAAO,GAAG,IAAI;MAChB;IACF;AACA,WAAO;EACT;;;;AChIF,SAAS,eAAAC,oBAAmB;AAqB5B,IAAI,MAAW;AACf,IAAI,uBAAuB;AAE3B,eAAe,UAAO;AACpB,MAAI,CAAC,KAAK;AACR,QAAI;AACF,YAAM,MAAM,OAAO,IAAI;IACzB,QAAQ;AACN,YAAM,IAAI,MACR,sDAAsD;IAE1D;AAIA,QAAI,CAAC,sBAAsB;AACzB,UAAI,MAAM,cAAc,IAAI,CAAC,QAAe;AAC1C,YAAI,QAAQ;AAAM,iBAAO;AACzB,eAAO,OAAO,GAAG;MACnB,CAAC;AACD,6BAAuB;IACzB;EACF;AACA,SAAO;AACT;AAGA,SAAS,iBAAiB,YAAkB;AAE1C,MAAI,CAAC,2BAA2B,KAAK,UAAU,GAAG;AAChD,UAAM,IAAI,MAAM,uBAAuB,UAAU,EAAE;EACrD;AACA,SAAO,IAAI,UAAU;AACvB;AAEM,IAAO,oBAAP,MAAwB;EACpB;;EAEA,OAAY;EAEpB,YAAY,QAAsB;AAChC,SAAK,SAAS;EAChB;EAEA,MAAM,UAAO;AACX,UAAM,KAAK,MAAM,QAAO;AAExB,UAAM,aAAa;MACjB,MAAM,KAAK,OAAO;MAClB,MAAM,KAAK,OAAO;MAClB,UAAU,KAAK,OAAO;MACtB,MAAM,KAAK,OAAO;MAClB,UAAU,KAAK,OAAO;MACtB,KAAK,KAAK,OAAO;MACjB,KAAK,KAAK,OAAO,OAAO;MACxB,KAAK,KAAK,OAAO,OAAO;MACxB,mBAAmB,KAAK,OAAO,qBAAqB;MACpD,yBAAyB,KAAK,OAAO,wBAAwB;MAC7D,mBAAmB,KAAK,OAAO;;AAGjC,SAAK,OAAO,IAAI,GAAG,KAAK,UAAU;AAGlC,SAAK,KAAK,GAAG,SAAS,CAAC,QAAc;AACnC,cAAQ,MAAM,mCAAmC,IAAI,OAAO;IAC9D,CAAC;AAGD,QAAI,KAAK,OAAO,QAAQ;AACtB,YAAM,SAAS,iBAAiB,KAAK,OAAO,MAAM;AAElD,WAAK,KAAK,GAAG,WAAW,CAACC,YAAe;AACtC,QAAAA,QAAO,MAAM,sBAAsB,MAAM,EAAE,EAAE,MAAM,CAAC,QAAc;AAChE,kBAAQ,MAAM,8BAA8B,IAAI,OAAO;QACzD,CAAC;MACH,CAAC;IACH;AAGA,UAAM,SAAS,MAAM,KAAK,KAAK,QAAO;AACtC,WAAO,QAAO;EAChB;EAEA,MAAM,aAAU;AACd,QAAI,KAAK,MAAM;AACb,YAAM,KAAK,KAAK,IAAG;AACnB,WAAK,OAAO;IACd;EACF;EAEA,cAAW;AACT,WAAO,KAAK,SAAS;EACvB;EAEA,MAAM,QAAQ,KAAW;AACvB,QAAI,CAAC,KAAK,MAAM;AACd,YAAM,IAAI,MAAM,2BAA2B;IAC7C;AAEA,UAAM,QAAQC,aAAY,IAAG;AAC7B,UAAM,SAAS,MAAM,KAAK,KAAK,MAAM,GAAG;AACxC,UAAM,aAAaA,aAAY,IAAG,IAAK;AAEvC,WAAO;MACL,SAAS,KAAK,eAAe,MAAM;MACnC,MAAM,OAAO,KAAK,IAAI,CAAC,QAAiC,KAAK,aAAa,GAAG,CAAC;MAC9E,UAAU,OAAO,YAAY,OAAO,KAAK;MACzC;;EAEJ;EAEA,MAAM,QAAQ,KAAW;AACvB,QAAI,CAAC,KAAK,MAAM;AACd,YAAM,IAAI,MAAM,2BAA2B;IAC7C;AAEA,QAAI;AACF,YAAM,KAAK,KAAK,MAAM,WAAW,GAAG,EAAE;AACtC,aAAO,EAAE,OAAO,KAAI;IACtB,SAAS,KAAK;AACZ,aAAO;QACL,OAAO;QACP,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;;IAE1D;EACF;;EAGQ,eAAe,QAAW;AAEhC,WAAO,OAAO,OAAO,IAAI,CAAC,WAAgB;MACxC,MAAM,MAAM;MACZ,MAAM,KAAK,eAAe,MAAM,UAAU;MAC1C;EACJ;EAEQ,eAAe,KAAW;AAEhC,UAAM,UAAkC;MACtC,IAAI;;MACJ,IAAI;;MACJ,IAAI;;MACJ,IAAI;;MACJ,KAAK;;MACL,KAAK;;MACL,MAAM;;MACN,IAAI;;MACJ,MAAM;;MACN,MAAM;;MACN,MAAM;;MACN,MAAM;;MACN,KAAK;;MACL,MAAM;;;AAER,WAAO,QAAQ,GAAG,KAAK;EACzB;EAEQ,aAAa,KAA4B;AAC/C,UAAM,aAAsC,CAAA;AAC5C,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC9C,iBAAW,GAAG,IAAI,KAAK,eAAe,KAAK;IAC7C;AACA,WAAO;EACT;EAEQ,eAAe,OAAc;AACnC,QAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,aAAO;IACT;AACA,QAAI,OAAO,UAAU,UAAU;AAE7B,UAAI,QAAQ,OAAO,oBAAoB,QAAQ,OAAO,kBAAkB;AACtE,eAAO,MAAM,SAAQ;MACvB;AACA,aAAO,OAAO,KAAK;IACrB;AACA,QAAI,iBAAiB,MAAM;AACzB,aAAO,mBAAmB,KAAK;IACjC;AACA,WAAO;EACT;;;;AC1MF,SAAS,eAAAC,oBAAmB;AAoB5B,IAAIC,OAAW;AAEf,eAAeC,WAAO;AACpB,MAAI,CAACD,MAAK;AACR,QAAI;AACF,MAAAA,OAAM,MAAM,OAAO,gBAAgB;IACrC,QAAQ;AACN,YAAM,IAAI,MACR,8DAA8D;IAElE;EACF;AACA,SAAOA;AACT;AAEM,IAAO,iBAAP,MAAqB;EACjB;;EAEA,OAAY;EAEpB,YAAY,QAAmB;AAC7B,SAAK,SAAS;EAChB;EAEA,MAAM,UAAO;AACX,UAAM,QAAQ,MAAMC,SAAO;AAE3B,UAAM,aAAa;MACjB,MAAM,KAAK,OAAO;MAClB,MAAM,KAAK,OAAO;MAClB,UAAU,KAAK,OAAO;MACtB,MAAM,KAAK,OAAO;MAClB,UAAU,KAAK,OAAO;MACtB,KAAK,KAAK,OAAO,MAAM,CAAA,IAAK;MAC5B,oBAAoB;MACpB,iBAAiB,KAAK,OAAO,OAAO;MACpC,YAAY;MACZ,gBAAgB,KAAK,OAAO,wBAAwB;;AAGtD,SAAK,OAAO,MAAM,WAAW,UAAU;AAGvC,UAAM,aAAa,MAAM,KAAK,KAAK,cAAa;AAChD,eAAW,QAAO;EACpB;EAEA,MAAM,aAAU;AACd,QAAI,KAAK,MAAM;AACb,YAAM,KAAK,KAAK,IAAG;AACnB,WAAK,OAAO;IACd;EACF;EAEA,cAAW;AACT,WAAO,KAAK,SAAS;EACvB;EAEA,MAAM,QAAQ,KAAW;AACvB,QAAI,CAAC,KAAK,MAAM;AACd,YAAM,IAAI,MAAM,2BAA2B;IAC7C;AAEA,UAAM,QAAQC,aAAY,IAAG;AAC7B,UAAM,CAAC,MAAM,MAAM,IAAI,MAAM,KAAK,KAAK,MAAM,GAAG;AAChD,UAAM,aAAaA,aAAY,IAAG,IAAK;AAEvC,WAAO;MACL,SAAS,KAAK,eAAe,MAAM;MACnC,MAAM,KAAK,IAAI,CAAC,QAAiC,KAAK,aAAa,GAAG,CAAC;MACvE,UAAU,KAAK;MACf;;EAEJ;EAEA,MAAM,QAAQ,KAAW;AACvB,QAAI,CAAC,KAAK,MAAM;AACd,YAAM,IAAI,MAAM,2BAA2B;IAC7C;AAEA,QAAI;AACF,YAAM,KAAK,KAAK,MAAM,WAAW,GAAG,EAAE;AACtC,aAAO,EAAE,OAAO,KAAI;IACtB,SAAS,KAAK;AACZ,aAAO;QACL,OAAO;QACP,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;;IAE1D;EACF;;EAGQ,eAAe,QAAa;AAClC,WAAO,OAAO,IAAI,YAAU;MAC1B,MAAM,MAAM;MACZ,MAAM,KAAK,kBAAkB,MAAM,IAAI;MACvC;EACJ;EAEQ,kBAAkB,MAAwB;AAEhD,UAAM,UAAkC;MACtC,GAAG;;MACH,GAAG;;MACH,GAAG;;MACH,GAAG;;MACH,GAAG;;MACH,GAAG;;MACH,GAAG;;MACH,GAAG;;MACH,GAAG;;MACH,IAAI;;MACJ,IAAI;;MACJ,IAAI;;MACJ,IAAI;;MACJ,IAAI;;MACJ,KAAK;;MACL,KAAK;;MACL,KAAK;;MACL,KAAK;;MACL,KAAK;;;AAEP,WAAO,QAAQ,QAAQ,CAAC,KAAK;EAC/B;EAEQ,aAAa,KAA4B;AAC/C,UAAM,aAAsC,CAAA;AAC5C,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC9C,iBAAW,GAAG,IAAI,KAAK,eAAe,KAAK;IAC7C;AACA,WAAO;EACT;EAEQ,eAAe,OAAc;AACnC,QAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,aAAO;IACT;AACA,QAAI,OAAO,UAAU,UAAU;AAC7B,UAAI,QAAQ,OAAO,oBAAoB,QAAQ,OAAO,kBAAkB;AACtE,eAAO,MAAM,SAAQ;MACvB;AACA,aAAO,OAAO,KAAK;IACrB;AACA,QAAI,iBAAiB,MAAM;AACzB,aAAO,mBAAmB,KAAK;IACjC;AACA,QAAI,OAAO,SAAS,KAAK,GAAG;AAC1B,aAAO,MAAM,SAAS,OAAO;IAC/B;AACA,WAAO;EACT;;;;AC1KF,OAAO,cAAiD;AACxD,SAAS,eAAAC,oBAAmB;AAQtB,IAAO,kBAAP,MAAsB;EAClB;EACA,KAA0B;EAElC,YAAY,QAAoB;AAC9B,SAAK,SAAS;EAChB;EAEA,MAAM,UAAO;AACX,SAAK,KAAK,IAAI,SAAS,KAAK,OAAO,MAAM;MACvC,UAAU,KAAK,OAAO,YAAY;KACnC;AAGD,SAAK,GAAG,OAAO,oBAAoB;AACnC,SAAK,GAAG,OAAO,mBAAmB;EACpC;EAEA,MAAM,aAAU;AACd,QAAI,KAAK,IAAI;AACX,WAAK,GAAG,MAAK;AACb,WAAK,KAAK;IACZ;EACF;EAEA,cAAW;AACT,WAAO,KAAK,OAAO;EACrB;EAEA,MAAM,QAAQ,KAAW;AACvB,QAAI,CAAC,KAAK,IAAI;AACZ,YAAM,IAAI,MAAM,2BAA2B;IAC7C;AAEA,UAAM,QAAQA,aAAY,IAAG;AAC7B,UAAM,OAAO,KAAK,GAAG,QAAQ,GAAG;AAChC,UAAM,OAAO,KAAK,IAAG;AACrB,UAAM,aAAaA,aAAY,IAAG,IAAK;AAGvC,UAAM,UAAU,KAAK,QAAO,EAAG,IAAI,UAAQ;MACzC,MAAM,IAAI;MACV,MAAM,KAAK,mBAAmB,IAAI,IAAI;MACtC;AAEF,WAAO;MACL;MACA,MAAM,KAAK,IAAI,SAAO,KAAK,aAAa,GAAG,CAAC;MAC5C,UAAU,KAAK;MACf;;EAEJ;EAEA,MAAM,QAAQ,KAAW;AACvB,QAAI,CAAC,KAAK,IAAI;AACZ,YAAM,IAAI,MAAM,2BAA2B;IAC7C;AAEA,QAAI;AACF,WAAK,GAAG,QAAQ,WAAW,GAAG,EAAE;AAChC,aAAO,EAAE,OAAO,KAAI;IACtB,SAAS,KAAK;AACZ,aAAO;QACL,OAAO;QACP,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;;IAE1D;EACF;EAEQ,mBAAmB,MAAmB;AAC5C,QAAI,CAAC;AAAM,aAAO;AAElB,UAAM,YAAY,KAAK,YAAW;AAElC,QAAI,UAAU,SAAS,KAAK;AAAG,aAAO;AACtC,QAAI,UAAU,SAAS,MAAM,KAAK,UAAU,SAAS,MAAM,KAAK,UAAU,SAAS,MAAM;AAAG,aAAO;AACnG,QAAI,UAAU,SAAS,MAAM;AAAG,aAAO;AACvC,QAAI,UAAU,SAAS,MAAM,KAAK,UAAU,SAAS,MAAM,KAAK,UAAU,SAAS,MAAM;AAAG,aAAO;AACnG,QAAI,UAAU,SAAS,SAAS,KAAK,UAAU,SAAS,SAAS;AAAG,aAAO;AAC3E,QAAI,UAAU,SAAS,MAAM,KAAK,UAAU,SAAS,MAAM;AAAG,aAAO;AACrE,QAAI,UAAU,SAAS,MAAM;AAAG,aAAO;AAEvC,WAAO;EACT;EAEQ,aAAa,KAA4B;AAC/C,UAAM,aAAsC,CAAA;AAC5C,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC9C,iBAAW,GAAG,IAAI,KAAK,eAAe,KAAK;IAC7C;AACA,WAAO;EACT;EAEQ,eAAe,OAAc;AACnC,QAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,aAAO;IACT;AACA,QAAI,OAAO,UAAU,UAAU;AAC7B,UAAI,QAAQ,OAAO,oBAAoB,QAAQ,OAAO,kBAAkB;AACtE,eAAO,MAAM,SAAQ;MACvB;AACA,aAAO,OAAO,KAAK;IACrB;AACA,QAAI,OAAO,SAAS,KAAK,GAAG;AAC1B,aAAO,MAAM,SAAS,QAAQ;IAChC;AACA,WAAO;EACT;;;;ACpHF,SAAS,eAAAC,oBAAmB;AAqB5B,IAAIC,OAAW;AAEf,eAAeC,WAAO;AACpB,MAAI,CAACD,MAAK;AACR,QAAI;AACF,MAAAA,QAAO,MAAM,OAAO,eAAe,GAAG;IACxC,QAAQ;AACN,YAAM,IAAI,MACR,iNAEiG;IAErG;EACF;AACA,SAAOA;AACT;AAEM,IAAO,qBAAP,MAAyB;EACrB;;EAEA,aAAkB;EAE1B,YAAY,QAAuB;AACjC,SAAK,SAAS;EAChB;EAEA,MAAM,UAAO;AACX,UAAM,YAAY,MAAMC,SAAO;AAG/B,UAAM,oBAAyC;MAC7C,SAAS,KAAK,OAAO;MACrB,UAAU,KAAK,OAAO;MACtB,UAAU,KAAK,OAAO;MACtB,YAAY,KAAK,OAAO;MACxB,WAAW,KAAK,OAAO;MACvB,UAAU,KAAK,OAAO;MACtB,QAAQ,KAAK,OAAO;MACpB,MAAM,KAAK,OAAO;MAClB,SAAS,KAAK,OAAO,wBAAwB;;AAG/C,QAAI,KAAK,OAAO,eAAe;AAC7B,wBAAkB,gBAAgB,KAAK,OAAO;IAChD;AACA,QAAI,KAAK,OAAO,mCAAmC,QAAW;AAC5D,wBAAkB,iCAAiC,KAAK,OAAO;IACjE;AAEA,SAAK,aAAa,UAAU,iBAAiB,iBAAiB;AAE9D,QAAI,KAAK,OAAO,kBAAkB,mBAAmB;AAEnD,YAAM,KAAK,WAAY,aAAY;IACrC,OAAO;AACL,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAU;AACrC,aAAK,WAAY,QAAQ,CAAC,QAA0B;AAClD,cAAI,KAAK;AACP,iBAAK,aAAa;AAClB,mBAAO,GAAG;UACZ,OAAO;AACL,oBAAO;UACT;QACF,CAAC;MACH,CAAC;IACH;EACF;EAEA,MAAM,aAAU;AACd,QAAI,KAAK,YAAY;AACnB,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAU;AACrC,aAAK,WAAY,QAAQ,CAAC,QAA0B;AAClD,eAAK,aAAa;AAClB,cAAI,KAAK;AACP,mBAAO,GAAG;UACZ,OAAO;AACL,oBAAO;UACT;QACF,CAAC;MACH,CAAC;IACH;EACF;EAEA,cAAW;AACT,WAAO,KAAK,eAAe,QAAQ,KAAK,WAAW,KAAI;EACzD;EAEA,MAAM,QAAQ,KAAW;AACvB,QAAI,CAAC,KAAK,YAAY;AACpB,YAAM,IAAI,MAAM,2BAA2B;IAC7C;AAEA,UAAM,QAAQC,aAAY,IAAG;AAE7B,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAU;AACrC,WAAK,WAAY,QAAQ;QACvB,SAAS;;QAET,UAAU,CAAC,KAAwB,MAAW,SAAe;AAC3D,gBAAM,aAAaA,aAAY,IAAG,IAAK;AAEvC,cAAI,KAAK;AACP,mBAAO,GAAG;AACV;UACF;AAGA,gBAAM,UAAU,OAAO,KAAK,WAAU,EAAG,IAAI,CAAC,SAAc;YAC1D,MAAM,IAAI,QAAO,EAAG,YAAW;YAC/B,MAAM,KAAK,sBAAsB,IAAI,QAAO,CAAE;YAC9C,IAAI,CAAA;AAEN,kBAAQ;YACN;YACA,OAAO,QAAQ,CAAA,GAAI,IAAI,SAAO,KAAK,aAAa,KAAK,cAAc,GAA8B,CAAC,CAAC;YACnG,UAAU,MAAM,UAAU;YAC1B;WACD;QACH;OACD;IACH,CAAC;EACH;EAEA,MAAM,QAAQ,KAAW;AACvB,QAAI,CAAC,KAAK,YAAY;AACpB,YAAM,IAAI,MAAM,2BAA2B;IAC7C;AAEA,QAAI;AACF,YAAM,KAAK,QAAQ,WAAW,GAAG,EAAE;AACnC,aAAO,EAAE,OAAO,KAAI;IACtB,SAAS,KAAK;AACZ,aAAO;QACL,OAAO;QACP,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;;IAE1D;EACF;EAEQ,sBAAsB,MAAY;AACxC,UAAM,UAAkC;MACtC,UAAU;MACV,WAAW;MACX,WAAW;MACX,OAAO;MACP,WAAW;MACX,UAAU;MACV,YAAY;MACZ,WAAW;MACX,WAAW;MACX,SAAS;MACT,UAAU;MACV,UAAU;MACV,UAAU;MACV,oBAAoB;MACpB,QAAQ;MACR,WAAW;MACX,QAAQ;MACR,aAAa;MACb,UAAU;MACV,QAAQ;MACR,UAAU;MACV,aAAa;MACb,WAAW;MACX,QAAQ;MACR,YAAY;MACZ,QAAQ;MACR,aAAa;MACb,iBAAiB;MACjB,iBAAiB;MACjB,gBAAgB;MAChB,WAAW;MACX,UAAU;MACV,SAAS;;AAGX,UAAM,YAAY,KAAK,YAAW;AAClC,WAAO,QAAQ,SAAS,KAAK;EAC/B;EAEQ,cAAc,KAA4B;AAChD,UAAM,SAAkC,CAAA;AACxC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC9C,aAAO,IAAI,YAAW,CAAE,IAAI;IAC9B;AACA,WAAO;EACT;EAEQ,aAAa,KAA4B;AAC/C,UAAM,aAAsC,CAAA;AAC5C,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC9C,iBAAW,GAAG,IAAI,KAAK,eAAe,KAAK;IAC7C;AACA,WAAO;EACT;EAEQ,eAAe,OAAc;AACnC,QAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,aAAO;IACT;AACA,QAAI,OAAO,UAAU,UAAU;AAC7B,UAAI,QAAQ,OAAO,oBAAoB,QAAQ,OAAO,kBAAkB;AACtE,eAAO,MAAM,SAAQ;MACvB;AACA,aAAO,OAAO,KAAK;IACrB;AACA,QAAI,iBAAiB,MAAM;AACzB,aAAO,mBAAmB,KAAK;IACjC;AACA,WAAO;EACT;;;;ACxNI,SAAU,oBAAoB,YAA8B;AAChE,QAAM,OAAO,WAAW;AAGxB,MAAI,CAAC,MAAM;AACT,WAAO;MACL,MAAM,QAAQ,IAAI,UAAU;MAC5B,UAAU,QAAQ,IAAI,cAAc;;EAExC;AAEA,MAAI,KAAK,SAAS,OAAO;AACvB,UAAM,OAAO,QAAQ,IAAI,KAAK,QAAQ;AACtC,UAAM,WAAW,QAAQ,IAAI,KAAK,YAAY;AAE9C,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,iCAAiC,KAAK,QAAQ,EAAE;IAClE;AAEA,WAAO,EAAE,MAAM,UAAU,YAAY,GAAE;EACzC;AAGA,QAAM,IAAI,MAAM,cAAc,KAAK,IAAI,uBAAuB;AAChE;AAEM,SAAU,iBAAiB,YAA2B;AAC1D,QAAM,OAAO,WAAW;AAGxB,MAAI,CAAC,MAAM;AACT,WAAO;MACL,MAAM,QAAQ,IAAI,cAAc;MAChC,UAAU,QAAQ,IAAI,kBAAkB;;EAE5C;AAEA,MAAI,KAAK,SAAS,OAAO;AACvB,UAAM,OAAO,QAAQ,IAAI,KAAK,QAAQ;AACtC,UAAM,WAAW,QAAQ,IAAI,KAAK,YAAY;AAE9C,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,iCAAiC,KAAK,QAAQ,EAAE;IAClE;AAEA,WAAO,EAAE,MAAM,UAAU,YAAY,GAAE;EACzC;AAEA,QAAM,IAAI,MAAM,cAAc,KAAK,IAAI,uBAAuB;AAChE;AAEM,SAAU,qBAAqB,YAA+B;AAClE,QAAM,OAAO,WAAW;AAExB,MAAI,KAAK,SAAS,OAAO;AACvB,UAAM,WAAW,QAAQ,IAAI,KAAK,QAAQ;AAC1C,UAAM,WAAW,QAAQ,IAAI,KAAK,YAAY;AAE9C,QAAI,CAAC,UAAU;AACb,YAAM,IAAI,MAAM,iCAAiC,KAAK,QAAQ,EAAE;IAClE;AAEA,WAAO,EAAE,UAAU,UAAU,YAAY,OAAS;EACpD;AAEA,MAAI,KAAK,SAAS,YAAY;AAC5B,UAAM,WAAW,QAAQ,IAAI,KAAK,QAAQ;AAE1C,QAAI,CAAC,UAAU;AACb,YAAM,IAAI,MAAM,iCAAiC,KAAK,QAAQ,EAAE;IAClE;AAGA,UAAM,KAAK,UAAQ,IAAI;AACvB,UAAM,aAAa,GAAG,aAAa,KAAK,kBAAkB,OAAO;AAEjE,WAAO,EAAE,UAAU,WAAU;EAC/B;AAEA,MAAI,KAAK,SAAS,mBAAmB;AACnC,UAAM,WAAW,QAAQ,IAAI,KAAK,QAAQ;AAE1C,QAAI,CAAC,UAAU;AACb,YAAM,IAAI,MAAM,iCAAiC,KAAK,QAAQ,EAAE;IAClE;AAEA,WAAO;MACL;MACA,eAAe;MACf,gCAAgC,KAAK,eAAe;;EAExD;AAEA,QAAM,IAAI,MAAM,cAAc,KAAK,IAAI,qCAAqC;AAC9E;;;ACtGA,IAAM,4BAA4B;EAChC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EACA;;AAGF,SAAS,kBAAkB,OAAc;AACvC,QAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,QAAM,QAAQ,QAAQ,YAAW;AACjC,SAAO,0BAA0B,KAAK,CAAC,YAAY,MAAM,SAAS,QAAQ,YAAW,CAAE,CAAC;AAC1F;AAQM,IAAO,wBAAP,MAA4B;EACxB;EAER,YAAY,OAAgB;AAC1B,SAAK,QAAQ;EACf;EAEA,MAAM,UAAO;AACX,WAAO,KAAK,MAAM,QAAO;EAC3B;EAEA,MAAM,aAAU;AACd,WAAO,KAAK,MAAM,WAAU;EAC9B;EAEA,cAAW;AACT,WAAO,KAAK,MAAM,YAAW;EAC/B;EAEA,MAAM,QAAQ,KAAW;AACvB,UAAM,KAAK,gBAAe;AAE1B,QAAI;AACF,aAAO,MAAM,KAAK,MAAM,QAAQ,GAAG;IACrC,SAAS,KAAK;AACZ,UAAI,kBAAkB,GAAG,GAAG;AAC1B,cAAM,KAAK,UAAS;AACpB,eAAO,KAAK,MAAM,QAAQ,GAAG;MAC/B;AACA,YAAM;IACR;EACF;EAEA,MAAM,QAAQ,KAAW;AACvB,UAAM,KAAK,gBAAe;AAE1B,QAAI;AACF,aAAO,MAAM,KAAK,MAAM,QAAQ,GAAG;IACrC,SAAS,KAAK;AACZ,UAAI,kBAAkB,GAAG,GAAG;AAC1B,cAAM,KAAK,UAAS;AACpB,eAAO,KAAK,MAAM,QAAQ,GAAG;MAC/B;AACA,YAAM;IACR;EACF;EAEQ,MAAM,kBAAe;AAC3B,QAAI,CAAC,KAAK,MAAM,YAAW,GAAI;AAC7B,YAAM,KAAK,UAAS;IACtB;EACF;EAEQ,MAAM,YAAS;AACrB,QAAI;AAAE,YAAM,KAAK,MAAM,WAAU;IAAI,QAAQ;IAAoC;AACjF,UAAM,KAAK,MAAM,QAAO;EAC1B;;;;AC9DI,SAAU,mBAAmB,OAAW;AAC5C,MACE,MAAM,YAAW,MAAO,KACxB,MAAM,cAAa,MAAO,KAC1B,MAAM,cAAa,MAAO,KAC1B,MAAM,mBAAkB,MAAO,GAC/B;AACA,UAAM,IAAI,MAAM,eAAc;AAC9B,UAAM,IAAI,OAAO,MAAM,YAAW,IAAK,CAAC,EAAE,SAAS,GAAG,GAAG;AACzD,UAAM,IAAI,OAAO,MAAM,WAAU,CAAE,EAAE,SAAS,GAAG,GAAG;AACpD,WAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;EACvB;AACA,SAAO,MAAM,YAAW;AAC1B;;;ACIA,IAAM,WAAqC;EACzC,MAAM,CAAC,QAAQ,aAAa,YAAY,eAAe,0BAA0B;EACjF,QAAQ,CAAC,WAAW,OAAO,UAAU,SAAS,UAAU,WAAW,WAAW,QAAQ,YAAY,WAAW,WAAW,QAAQ,QAAQ,UAAU,QAAQ;EAC1J,SAAS,CAAC,WAAW,OAAO,UAAU,YAAY,WAAW,WAAW,QAAQ,MAAM;EACtF,QAAQ,CAAC,WAAW,QAAQ,QAAQ,UAAU,qBAAqB,UAAU;EAC7E,SAAS,CAAC,WAAW,MAAM;;AAG7B,SAAS,WAAW,cAAsB,YAAkB;AAC1D,QAAM,WAAW,aAAa,YAAW;AACzC,QAAM,SAAS,WAAW,YAAW;AACrC,MAAI,aAAa;AAAQ,WAAO;AAChC,QAAM,gBAAgB,SAAS,QAAQ;AACvC,MAAI;AAAe,WAAO,cAAc,SAAS,MAAM;AACvD,SAAO;AACT;AAKM,SAAU,WAAW,cAAsB,aAAmB;AAClE,SAAO,aAAa,QAAQ,uBAAuB,WAAW;AAChE;AAEA,IAAM,wBAAwB;AAE9B,eAAsB,aACpB,aACA,cACA,WAAoB;AAEpB,QAAM,UAAU,CAAC,qBAAqB,KAAK,YAAY,IACnD,kFACA;AAEJ,QAAM,cAAc,WAAW,cAAc,WAAW;AAExD,MAAI;AACF,UAAM,SAAS,MAAM,UAAU,QAAQ,WAAW;AAElD,WAAO;MACL,KAAK;MACL,QAAQ,OAAO,aAAa;MAC5B,gBAAgB,OAAO;MACvB,kBAAkB,OAAO,KAAK,MAAM,GAAG,qBAAqB;MAC5D;;EAEJ,SAAS,KAAK;AACZ,WAAO;MACL,KAAK;MACL,QAAQ;MACR,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;MACtD;;EAEJ;AACF;AAEA,eAAsB,SACpB,aACA,UACA,WAAoB;AAEpB,QAAM,QAAQ,YAAY,IAAG;AAC7B,QAAM,aAAa,SAAS,WAAW,SAAS,QAAQ,SAAS;AACjE,QAAM,WAAW,SAAS,SAAS,SAAS,MAAM,SAAS;AAG3D,MAAI,CAAC,cAAc,CAAC,UAAU;AAC5B,WAAO;MACL,WAAW,SAAS;MACpB,YAAY,CAAA;MACZ,YAAY,YAAY,IAAG,IAAK;;EAEpC;AAGA,MAAI;AACJ,MAAI,YAAY;AACd,QAAI;AACF,0BAAoB,MAAM,YAAY,aAAa,WAAW,SAAS,OAAQ;IACjF,SAAS,KAAK;AACZ,aAAO;QACL,WAAW,SAAS;QACpB,YAAY,CAAA;QACZ,YAAY,YAAY,IAAG,IAAK;QAChC,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;;IAE1D;EACF;AAGA,QAAM,aAAgC,CAAA;AACtC,MAAI,UAAU;AACZ,eAAW,WAAW,SAAS,OAAQ;AACrC,YAAM,SAAS,MAAM,aAAa,aAAa,SAAS,SAAS;AACjE,iBAAW,KAAK,MAAM;IACxB;EACF;AAEA,SAAO;IACL,WAAW,SAAS;IACpB,aAAa;IACb;IACA,YAAY,YAAY,IAAG,IAAK;;AAEpC;AAEA,eAAsB,OACpB,QACA,WAAoB;AAEpB,QAAM,QAAQ,YAAY,IAAG;AAC7B,QAAM,UAA6B,CAAA;AACnC,MAAI,SAAS;AACb,MAAI,SAAS;AACb,MAAI,UAAU;AAEd,aAAW,SAAS,QAAQ;AAC1B,UAAM,SAAS,MAAM,SAAS,MAAM,aAAa,MAAM,UAAU,SAAS;AAC1E,YAAQ,KAAK,MAAM;AAEnB,UAAM,cAAc,OAAO,eAAe,OAAO,WAAW,SAAS;AACrE,QAAI,CAAC,eAAe,CAAC,OAAO,OAAO;AACjC;AACA;IACF;AAEA,QAAI,OAAO,OAAO;AAChB;AACA;IACF;AAGA,QAAI,OAAO,aAAa;AACtB,UAAI,OAAO,YAAY;AAAQ;;AAC1B;IACP;AACA,eAAW,aAAa,OAAO,YAAY;AACzC,UAAI,UAAU;AAAQ;;AACjB;IACP;EACF;AAEA,SAAO;IACL,QAAQ;IACR;IACA;IACA;IACA,YAAY,YAAY,IAAG,IAAK;;AAEpC;AAEA,eAAsB,YACpB,aACA,WACA,iBAA+B;AAE/B,QAAM,aAAa,kBAAkB,WAAW;AAChD,QAAM,SAAS,MAAM,UAAU,QAAQ,UAAU;AAEjD,QAAM,gBAAgB,OAAO,QAAQ,IAAI,CAAC,MAAM,EAAE,IAAI;AACtD,QAAM,kBAAkB,gBAAgB,IAAI,CAAC,MAAM,EAAE,IAAI;AAEzD,QAAM,iBAAiB,gBAAgB,OAAO,CAAC,SAAS,CAAC,cAAc,SAAS,IAAI,CAAC;AACrF,QAAM,eAAe,cAAc,OAAO,CAAC,SAAS,CAAC,gBAAgB,SAAS,IAAI,CAAC;AAEnF,QAAM,iBAAsD,CAAA;AAC5D,aAAW,YAAY,iBAAiB;AACtC,UAAM,SAAS,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,SAAS,IAAI;AAClE,QAAI,UAAU,CAAC,WAAW,SAAS,MAAM,OAAO,IAAI,GAAG;AACrD,qBAAe,KAAK;QAClB,QAAQ,SAAS;QACjB,UAAU,SAAS;QACnB,QAAQ,OAAO;OAChB;IACH;EACF;AAEA,SAAO;IACL,QAAQ,eAAe,WAAW,KAAK,eAAe,WAAW;IACjE;IACA;IACA;IACA;IACA;;AAEJ;;;ACnOO,IAAM,UAAU;","names":["end","shiftFns","start","format","subDays","addDays","startOfYear","startOfMonth","startOfQuarter","endOfYear","endOfMonth","endOfQuarter","performance","performance","performance","client","performance","performance","sdk","loadSDK","performance","performance","performance","sdk","loadSDK","performance"]}
|
package/dist/chunk-DGUM43GV.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
-
}) : x)(function(x) {
|
|
4
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
export {
|
|
9
|
-
__require
|
|
10
|
-
};
|
|
11
|
-
//# sourceMappingURL=chunk-DGUM43GV.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/introspection.ts"],"sourcesContent":["/**\n * Per-engine SQL generation and result normalization for database introspection.\n *\n * Pure logic — no I/O, no connectors. Generates SQL strings and provides\n * normalize functions to transform raw query results into consistent shapes.\n */\n\nexport interface NormalizedTable {\n schema: string;\n name: string;\n type: string;\n}\n\nexport interface NormalizedColumn {\n name: string;\n type: string;\n nullable: string;\n}\n\nexport interface SearchResult {\n type: 'table' | 'column';\n schema: string;\n table: string;\n column?: string;\n columnType?: string;\n}\n\nexport interface TablesQuery {\n sql: string;\n normalize: (rows: Record<string, unknown>[]) => NormalizedTable[];\n}\n\nexport interface DescribeQuery {\n sql: string;\n normalize: (rows: Record<string, unknown>[]) => NormalizedColumn[];\n}\n\nexport interface SearchQuery {\n sql: string;\n normalize: (rows: Record<string, unknown>[]) => SearchResult[];\n}\n\nexport interface NormalizedColumnWithTable {\n schema: string;\n table: string;\n name: string;\n type: string;\n nullable: string;\n}\n\nexport interface ColumnsQuery {\n sql: string;\n normalize: (rows: Record<string, unknown>[]) => NormalizedColumnWithTable[];\n}\n\n/**\n * Escape a SQL string literal value by doubling single quotes.\n */\nfunction escapeSqlValue(value: string): string {\n return value.replace(/'/g, \"''\");\n}\n\n/**\n * Normalize table_type values: 'BASE TABLE' -> 'TABLE', everything else uppercased.\n */\nfunction normalizeTableType(tableType: string): string {\n const upper = tableType.toUpperCase();\n if (upper === 'BASE TABLE') return 'TABLE';\n return upper;\n}\n\n/**\n * Helper to read a property from a row, trying lowercase first then uppercase.\n * MySQL drivers may return column names in either case.\n */\nfunction getField(row: Record<string, unknown>, lowercase: string, uppercase: string): unknown {\n if (lowercase in row) return row[lowercase];\n if (uppercase in row) return row[uppercase];\n return undefined;\n}\n\n/**\n * Generate a SQL query to list tables/views and a normalizer for the results.\n *\n * Supported types: duckdb, postgres, mysql, snowflake, sqlite.\n */\nexport function getTablesQuery(\n type: string,\n options?: { schema?: string; database?: string },\n): TablesQuery {\n switch (type) {\n case 'duckdb':\n case 'postgres': {\n const conditions = [\n \"table_schema NOT IN ('information_schema', 'pg_catalog')\",\n ];\n if (options?.schema) {\n conditions.push(`table_schema = '${escapeSqlValue(options.schema)}'`);\n }\n const sql = `SELECT table_schema, table_name, table_type FROM information_schema.tables WHERE ${conditions.join(' AND ')}`;\n return {\n sql,\n normalize: (rows) =>\n rows.map((row) => ({\n schema: String(row.table_schema),\n name: String(row.table_name),\n type: normalizeTableType(String(row.table_type)),\n })),\n };\n }\n\n case 'mysql': {\n let sql = 'SELECT table_schema, table_name, table_type FROM information_schema.tables';\n if (options?.schema) {\n sql += ` WHERE table_schema = '${escapeSqlValue(options.schema)}'`;\n }\n return {\n sql,\n normalize: (rows) =>\n rows.map((row) => ({\n schema: String(getField(row, 'table_schema', 'TABLE_SCHEMA')),\n name: String(getField(row, 'table_name', 'TABLE_NAME')),\n type: normalizeTableType(String(getField(row, 'table_type', 'TABLE_TYPE'))),\n })),\n };\n }\n\n case 'snowflake': {\n const conditions: string[] = [];\n if (options?.schema) {\n conditions.push(`TABLE_SCHEMA = '${escapeSqlValue(options.schema)}'`);\n }\n if (options?.database) {\n conditions.push(`TABLE_CATALOG = '${escapeSqlValue(options.database)}'`);\n }\n let sql = 'SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE FROM INFORMATION_SCHEMA.TABLES';\n if (conditions.length > 0) {\n sql += ` WHERE ${conditions.join(' AND ')}`;\n }\n return {\n sql,\n normalize: (rows) =>\n rows.map((row) => ({\n schema: String(row.TABLE_SCHEMA),\n name: String(row.TABLE_NAME),\n type: normalizeTableType(String(row.TABLE_TYPE)),\n })),\n };\n }\n\n case 'sqlite': {\n const sql = \"SELECT name, type FROM sqlite_master WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%'\";\n return {\n sql,\n normalize: (rows) =>\n rows.map((row) => ({\n schema: '',\n name: String(row.name),\n type: String(row.type).toUpperCase(),\n })),\n };\n }\n\n default:\n throw new Error(`Unsupported database type: ${type}`);\n }\n}\n\n/**\n * Generate a SQL query to describe a table's columns and a normalizer for the results.\n *\n * Supported types: duckdb, postgres, mysql, snowflake, sqlite.\n * Accepts schema-qualified names (e.g. 'public.orders', 'ANALYTICS.PUBLIC.ORDERS').\n */\nexport function getDescribeQuery(type: string, table: string): DescribeQuery {\n switch (type) {\n case 'duckdb': {\n return {\n sql: `DESCRIBE ${table}`,\n normalize: (rows) =>\n rows.map((row) => ({\n name: String(row.column_name),\n type: String(row.column_type),\n nullable: String(row.null),\n })),\n };\n }\n\n case 'postgres': {\n const parts = table.split('.');\n const tableName = parts.length > 1 ? parts[parts.length - 1]! : table;\n const schemaName = parts.length > 1 ? parts[0]! : null;\n\n const conditions = [`table_name = '${escapeSqlValue(tableName)}'`];\n if (schemaName) {\n conditions.push(`table_schema = '${escapeSqlValue(schemaName)}'`);\n }\n\n const sql = `SELECT column_name, data_type, is_nullable FROM information_schema.columns WHERE ${conditions.join(' AND ')} ORDER BY ordinal_position`;\n return {\n sql,\n normalize: (rows) =>\n rows.map((row) => ({\n name: String(row.column_name),\n type: String(row.data_type),\n nullable: String(row.is_nullable),\n })),\n };\n }\n\n case 'mysql': {\n const parts = table.split('.');\n const tableName = parts.length > 1 ? parts[parts.length - 1]! : table;\n const schemaName = parts.length > 1 ? parts[0]! : null;\n\n const conditions = [`table_name = '${escapeSqlValue(tableName)}'`];\n if (schemaName) {\n conditions.push(`table_schema = '${escapeSqlValue(schemaName)}'`);\n }\n\n const sql = `SELECT column_name, column_type, is_nullable FROM information_schema.columns WHERE ${conditions.join(' AND ')} ORDER BY ordinal_position`;\n return {\n sql,\n normalize: (rows) =>\n rows.map((row) => ({\n name: String(getField(row, 'column_name', 'COLUMN_NAME')),\n type: String(getField(row, 'column_type', 'COLUMN_TYPE')),\n nullable: String(getField(row, 'is_nullable', 'IS_NULLABLE')),\n })),\n };\n }\n\n case 'snowflake': {\n return {\n sql: `DESCRIBE TABLE ${table}`,\n normalize: (rows) =>\n rows.map((row) => ({\n name: String(row.name),\n type: String(row.type),\n nullable: String(row['null?']) === 'Y' ? 'YES' : 'NO',\n })),\n };\n }\n\n case 'sqlite': {\n return {\n sql: `PRAGMA table_info(${table})`,\n normalize: (rows) =>\n rows.map((row) => ({\n name: String(row.name),\n type: String(row.type),\n nullable: Number(row.notnull) === 1 ? 'NO' : 'YES',\n })),\n };\n }\n\n default:\n throw new Error(`Unsupported database type: ${type}`);\n }\n}\n\n/**\n * Generate a SQL query to search for tables and columns matching a keyword.\n *\n * Supported types: duckdb, postgres, mysql, snowflake, sqlite.\n */\nexport function getSearchQuery(type: string, keyword: string): SearchQuery {\n const escaped = escapeSqlValue(keyword);\n\n switch (type) {\n case 'duckdb':\n case 'postgres': {\n const sql = [\n `SELECT 'table' AS match_type, table_schema, table_name, NULL AS column_name, NULL AS data_type`,\n `FROM information_schema.tables`,\n `WHERE table_schema NOT IN ('information_schema', 'pg_catalog')`,\n `AND table_name ILIKE '%${escaped}%'`,\n `UNION ALL`,\n `SELECT 'column' AS match_type, table_schema, table_name, column_name, data_type`,\n `FROM information_schema.columns`,\n `WHERE table_schema NOT IN ('information_schema', 'pg_catalog')`,\n `AND column_name ILIKE '%${escaped}%'`,\n `ORDER BY match_type, table_schema, table_name`,\n ].join(' ');\n\n return {\n sql,\n normalize: (rows) =>\n rows.map((row) => ({\n type: String(row.match_type) as 'table' | 'column',\n schema: String(row.table_schema),\n table: String(row.table_name),\n ...(row.column_name ? { column: String(row.column_name) } : {}),\n ...(row.data_type ? { columnType: String(row.data_type) } : {}),\n })),\n };\n }\n\n case 'mysql': {\n const sql = [\n `SELECT 'table' AS match_type, table_schema, table_name, NULL AS column_name, NULL AS data_type`,\n `FROM information_schema.tables`,\n `WHERE table_name LIKE '%${escaped}%'`,\n `UNION ALL`,\n `SELECT 'column' AS match_type, table_schema, table_name, column_name, data_type`,\n `FROM information_schema.columns`,\n `WHERE column_name LIKE '%${escaped}%'`,\n `ORDER BY match_type, table_schema, table_name`,\n ].join(' ');\n\n return {\n sql,\n normalize: (rows) =>\n rows.map((row) => ({\n type: String(getField(row, 'match_type', 'MATCH_TYPE')) as 'table' | 'column',\n schema: String(getField(row, 'table_schema', 'TABLE_SCHEMA')),\n table: String(getField(row, 'table_name', 'TABLE_NAME')),\n ...(getField(row, 'column_name', 'COLUMN_NAME')\n ? { column: String(getField(row, 'column_name', 'COLUMN_NAME')) }\n : {}),\n ...(getField(row, 'data_type', 'DATA_TYPE')\n ? { columnType: String(getField(row, 'data_type', 'DATA_TYPE')) }\n : {}),\n })),\n };\n }\n\n case 'snowflake': {\n const sql = [\n `SELECT 'table' AS MATCH_TYPE, TABLE_SCHEMA, TABLE_NAME, NULL AS COLUMN_NAME, NULL AS DATA_TYPE`,\n `FROM INFORMATION_SCHEMA.TABLES`,\n `WHERE TABLE_NAME ILIKE '%${escaped}%'`,\n `UNION ALL`,\n `SELECT 'column' AS MATCH_TYPE, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE`,\n `FROM INFORMATION_SCHEMA.COLUMNS`,\n `WHERE COLUMN_NAME ILIKE '%${escaped}%'`,\n `ORDER BY MATCH_TYPE, TABLE_SCHEMA, TABLE_NAME`,\n ].join(' ');\n\n return {\n sql,\n normalize: (rows) =>\n rows.map((row) => ({\n type: String(row.MATCH_TYPE) as 'table' | 'column',\n schema: String(row.TABLE_SCHEMA),\n table: String(row.TABLE_NAME),\n ...(row.COLUMN_NAME ? { column: String(row.COLUMN_NAME) } : {}),\n ...(row.DATA_TYPE ? { columnType: String(row.DATA_TYPE) } : {}),\n })),\n };\n }\n\n case 'sqlite': {\n const sql = `SELECT name FROM sqlite_master WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%' AND name LIKE '%${escaped}%'`;\n\n return {\n sql,\n normalize: (rows) =>\n rows.map((row) => ({\n type: 'table' as const,\n schema: '',\n table: String(row.name),\n })),\n };\n }\n\n default:\n throw new Error(`Unsupported database type: ${type}`);\n }\n}\n\n/**\n * Generate a SQL query to fetch ALL columns across all tables in a single bulk query,\n * and a normalizer for the results.\n *\n * Supported types: duckdb, postgres, mysql, snowflake.\n * SQLite is not supported (no information_schema); use getDescribeQuery per table.\n */\nexport function getColumnsQuery(\n type: string,\n options?: { schema?: string; database?: string },\n): ColumnsQuery {\n switch (type) {\n case 'duckdb':\n case 'postgres': {\n const conditions = [\n \"table_schema NOT IN ('information_schema', 'pg_catalog')\",\n ];\n if (options?.schema) {\n conditions.push(`table_schema = '${escapeSqlValue(options.schema)}'`);\n }\n const sql = `SELECT table_schema, table_name, column_name, data_type, is_nullable FROM information_schema.columns WHERE ${conditions.join(' AND ')} ORDER BY table_schema, table_name, ordinal_position`;\n return {\n sql,\n normalize: (rows) =>\n rows.map((row) => ({\n schema: String(row.table_schema),\n table: String(row.table_name),\n name: String(row.column_name),\n type: String(row.data_type),\n nullable: String(row.is_nullable),\n })),\n };\n }\n\n case 'mysql': {\n const conditions: string[] = [];\n if (options?.schema) {\n conditions.push(`table_schema = '${escapeSqlValue(options.schema)}'`);\n }\n let sql = 'SELECT table_schema, table_name, column_name, column_type, is_nullable FROM information_schema.columns';\n if (conditions.length > 0) {\n sql += ` WHERE ${conditions.join(' AND ')}`;\n }\n sql += ' ORDER BY table_schema, table_name, ordinal_position';\n return {\n sql,\n normalize: (rows) =>\n rows.map((row) => ({\n schema: String(getField(row, 'table_schema', 'TABLE_SCHEMA')),\n table: String(getField(row, 'table_name', 'TABLE_NAME')),\n name: String(getField(row, 'column_name', 'COLUMN_NAME')),\n type: String(getField(row, 'column_type', 'COLUMN_TYPE')),\n nullable: String(getField(row, 'is_nullable', 'IS_NULLABLE')),\n })),\n };\n }\n\n case 'snowflake': {\n const conditions: string[] = [];\n if (options?.schema) {\n conditions.push(`TABLE_SCHEMA = '${escapeSqlValue(options.schema)}'`);\n }\n if (options?.database) {\n conditions.push(`TABLE_CATALOG = '${escapeSqlValue(options.database)}'`);\n }\n let sql = 'SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE, IS_NULLABLE FROM INFORMATION_SCHEMA.COLUMNS';\n if (conditions.length > 0) {\n sql += ` WHERE ${conditions.join(' AND ')}`;\n }\n sql += ' ORDER BY TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION';\n return {\n sql,\n normalize: (rows) =>\n rows.map((row) => ({\n schema: String(row.TABLE_SCHEMA),\n table: String(row.TABLE_NAME),\n name: String(row.COLUMN_NAME),\n type: String(row.DATA_TYPE),\n nullable: String(row.IS_NULLABLE),\n })),\n };\n }\n\n case 'sqlite':\n throw new Error(\n 'SQLite does not support bulk column queries. Use getDescribeQuery per table.',\n );\n\n default:\n throw new Error(`Unsupported database type: ${type}`);\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/connection-utils.ts"],"sourcesContent":["import { readFile, access } from 'fs/promises';\nimport { join } from 'path';\nimport { parse as parseYaml } from 'yaml';\nimport {\n DuckDBConnector,\n PostgresConnector,\n MySQLConnector,\n SQLiteConnector,\n SnowflakeConnector,\n resolvePostgresAuth,\n resolveMySQLAuth,\n resolveSnowflakeAuth,\n type Connector,\n type QueryResult,\n} from '@yamchart/query';\nimport {\n ConnectionSchema,\n type Connection,\n type DuckDBConnection,\n type PostgresConnection,\n type MySQLConnection,\n type SQLiteConnection,\n type SnowflakeConnection,\n} from '@yamchart/schema';\n\nexport interface ProjectConfig {\n name: string;\n version?: string;\n default_connection?: string;\n defaults?: {\n connection?: string;\n };\n}\n\n/**\n * Read and parse yamchart.yaml from a project directory.\n * Resolves environment overrides and merges yamchart.local.yaml if present.\n */\nexport async function loadProjectConfig(\n projectDir: string,\n env?: string,\n): Promise<ProjectConfig> {\n const configPath = join(projectDir, 'yamchart.yaml');\n const content = await readFile(configPath, 'utf-8');\n const raw = parseYaml(content) as Record<string, unknown>;\n\n const { resolveProjectConfig, deepMerge } = await import('@yamchart/schema');\n const resolvedEnv = env || process.env.YAMCHART_ENV || undefined;\n let merged = resolveProjectConfig(raw, resolvedEnv);\n\n // Merge yamchart.local.yaml if it exists\n const localPath = join(projectDir, 'yamchart.local.yaml');\n try {\n await access(localPath);\n const localContent = await readFile(localPath, 'utf-8');\n const localOverrides = parseYaml(localContent) as Record<string, unknown>;\n if (localOverrides && typeof localOverrides === 'object') {\n merged = deepMerge(merged, localOverrides);\n }\n } catch {\n // No local overrides file\n }\n\n return merged as ProjectConfig;\n}\n\n/**\n * Load and validate a connection YAML file.\n * Tries .yaml then .yml extensions.\n * If no overrideName, falls back to defaults.connection from project config.\n */\nexport async function resolveConnection(\n projectDir: string,\n overrideName?: string,\n env?: string,\n): Promise<Connection> {\n const config = await loadProjectConfig(projectDir, env);\n const connName = overrideName || config.defaults?.connection || config.default_connection;\n\n if (!connName) {\n throw new Error(\n 'No connection specified. Use --connection or set defaults.connection in yamchart.yaml.',\n );\n }\n\n const yamlPath = join(projectDir, 'connections', `${connName}.yaml`);\n const ymlPath = join(projectDir, 'connections', `${connName}.yml`);\n\n let connPath = yamlPath;\n try {\n await access(yamlPath);\n } catch {\n try {\n await access(ymlPath);\n connPath = ymlPath;\n } catch {\n throw new Error(`Connection \"${connName}\" not found at connections/${connName}.yaml`);\n }\n }\n\n const content = await readFile(connPath, 'utf-8');\n const raw = parseYaml(content);\n const parsed = ConnectionSchema.parse(raw);\n return parsed;\n}\n\n/**\n * Instantiate the right connector class based on connection.type.\n * Resolves auth and relative paths. Does NOT call connect().\n */\nexport function createConnector(connection: Connection, projectDir: string): Connector {\n switch (connection.type) {\n case 'duckdb': {\n const duckdbConn = connection as DuckDBConnection;\n const dbPath = duckdbConn.config.path.startsWith('/')\n ? duckdbConn.config.path\n : duckdbConn.config.path === ':memory:'\n ? ':memory:'\n : join(projectDir, duckdbConn.config.path);\n return new DuckDBConnector({ path: dbPath });\n }\n\n case 'postgres': {\n const pgConn = connection as PostgresConnection;\n const credentials = resolvePostgresAuth(pgConn);\n return new PostgresConnector({\n host: pgConn.config.host,\n port: pgConn.config.port,\n database: pgConn.config.database,\n schema: pgConn.config.schema,\n ssl: pgConn.config.ssl,\n user: credentials.user,\n password: credentials.password,\n min: pgConn.pool?.min_connections,\n max: pgConn.pool?.max_connections,\n idleTimeoutMillis: pgConn.pool?.idle_timeout,\n statementTimeout: pgConn.query?.timeout,\n });\n }\n\n case 'mysql': {\n const mysqlConn = connection as MySQLConnection;\n const credentials = resolveMySQLAuth(mysqlConn);\n return new MySQLConnector({\n host: mysqlConn.config.host,\n port: mysqlConn.config.port,\n database: mysqlConn.config.database,\n ssl: mysqlConn.config.ssl,\n user: credentials.user,\n password: credentials.password,\n min: mysqlConn.pool?.min_connections,\n max: mysqlConn.pool?.max_connections,\n idleTimeoutMillis: mysqlConn.pool?.idle_timeout,\n statementTimeout: mysqlConn.query?.timeout,\n });\n }\n\n case 'sqlite': {\n const sqliteConn = connection as SQLiteConnection;\n const dbPath = sqliteConn.config.path.startsWith('/')\n ? sqliteConn.config.path\n : sqliteConn.config.path === ':memory:'\n ? ':memory:'\n : join(projectDir, sqliteConn.config.path);\n return new SQLiteConnector({ path: dbPath });\n }\n\n case 'snowflake': {\n const sfConn = connection as SnowflakeConnection;\n const credentials = resolveSnowflakeAuth(sfConn);\n return new SnowflakeConnector({\n account: sfConn.config.account,\n username: credentials.username,\n password: credentials.password,\n privateKey: credentials.privateKey,\n authenticator: credentials.authenticator,\n clientStoreTemporaryCredential: credentials.clientStoreTemporaryCredential,\n warehouse: sfConn.config.warehouse,\n database: sfConn.config.database,\n schema: sfConn.config.schema,\n role: sfConn.config.role,\n statementTimeout: sfConn.query?.timeout,\n });\n }\n\n default:\n throw new Error(`Unsupported connection type: ${(connection as Connection).type}`);\n }\n}\n\n/**\n * Format a query result as an aligned terminal table.\n * Truncates values longer than 40 characters.\n */\nexport function formatTable(result: QueryResult): string {\n const { columns, rows, rowCount, durationMs } = result;\n const maxWidth = 40;\n\n const truncate = (val: unknown): string => {\n if (val === null || val === undefined) return 'NULL';\n const str = String(val);\n if (str.length > maxWidth) return str.slice(0, maxWidth - 3) + '...';\n return str;\n };\n\n // Calculate column widths\n const headers = columns.map((c) => c.name);\n const formattedRows = rows.map((row) =>\n columns.map((c) => truncate(row[c.name])),\n );\n\n const colWidths = headers.map((h, i) => {\n const dataMax = formattedRows.reduce(\n (max, row) => Math.max(max, row[i]!.length),\n 0,\n );\n return Math.max(h.length, dataMax);\n });\n\n // Build lines\n const lines: string[] = [];\n\n // Header\n const headerLine = headers.map((h, i) => h.padEnd(colWidths[i]!)).join(' ');\n lines.push(headerLine);\n\n // Separator\n const separator = colWidths.map((w) => '-'.repeat(w)).join(' ');\n lines.push(separator);\n\n // Data rows\n for (const row of formattedRows) {\n const line = row.map((val, i) => val.padEnd(colWidths[i]!)).join(' ');\n lines.push(line);\n }\n\n // Footer\n lines.push('');\n lines.push(`${rowCount} row(s) (${Math.round(durationMs)}ms)`);\n\n return lines.join('\\n');\n}\n\n/**\n * Format a query result as a JSON string.\n */\nexport function formatJSON(result: QueryResult): string {\n return JSON.stringify(\n {\n columns: result.columns,\n rows: result.rows,\n rowCount: result.rowCount,\n durationMs: result.durationMs,\n },\n null,\n 2,\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/source-resolver.ts","../src/commands/model-parser.ts"],"sourcesContent":["import { readFile, access } from 'fs/promises';\nimport { join } from 'path';\nimport { performance } from 'node:perf_hooks';\nimport type { NormalizedColumn, NormalizedTable, SearchResult } from './introspection.js';\nimport { getDescribeQuery, getTablesQuery, getSearchQuery } from './introspection.js';\nimport { resolveConnection, createConnector } from './connection-utils.js';\nimport { scanModels } from './model-parser.js';\nimport { resolveTableName } from './model-resolver.js';\n\nexport type SourceType = 'auto' | 'catalog' | 'model' | 'db';\n\ninterface CatalogColumn {\n name: string;\n data_type: string;\n description?: string;\n}\n\ninterface CatalogModel {\n name: string;\n table?: string;\n columns?: CatalogColumn[];\n source?: string;\n dependsOn?: string[];\n}\n\ninterface CatalogFile {\n models?: CatalogModel[];\n}\n\nexport interface DescribeSourceResult {\n source: 'catalog' | 'model' | 'db';\n table: string;\n columns: NormalizedColumn[];\n connectionName?: string;\n connectionType?: string;\n durationMs: number;\n resolvedFrom?: string;\n}\n\nexport interface TablesSourceResult {\n source: 'catalog' | 'model' | 'db';\n tables: NormalizedTable[];\n connectionName?: string;\n connectionType?: string;\n durationMs: number;\n}\n\nexport interface SearchSourceResult {\n source: 'catalog' | 'model' | 'db';\n keyword: string;\n results: SearchResult[];\n connectionName?: string;\n connectionType?: string;\n durationMs: number;\n}\n\nasync function loadCatalog(projectDir: string): Promise<CatalogFile | null> {\n try {\n const catalogPath = join(projectDir, '.yamchart', 'catalog.json');\n await access(catalogPath);\n const content = await readFile(catalogPath, 'utf-8');\n return JSON.parse(content) as CatalogFile;\n } catch {\n return null;\n }\n}\n\nfunction findCatalogModel(catalog: CatalogFile, tableName: string): CatalogModel | undefined {\n return catalog.models?.find(\n (m) => m.name.toLowerCase() === tableName.toLowerCase(),\n );\n}\n\nfunction catalogColumnsToNormalized(columns: CatalogColumn[]): NormalizedColumn[] {\n return columns.map((c) => ({\n name: c.name,\n type: c.data_type,\n nullable: 'YES',\n }));\n}\n\n// --- DESCRIBE ---\n\nasync function describeFromCatalog(\n projectDir: string,\n table: string,\n): Promise<DescribeSourceResult | null> {\n const catalog = await loadCatalog(projectDir);\n if (!catalog) return null;\n\n const model = findCatalogModel(catalog, table);\n if (!model?.columns?.length) return null;\n\n return {\n source: 'catalog',\n table: model.table || table,\n columns: catalogColumnsToNormalized(model.columns),\n durationMs: 0,\n ...(model.table ? { resolvedFrom: table } : {}),\n };\n}\n\nasync function describeFromModel(\n projectDir: string,\n table: string,\n): Promise<DescribeSourceResult | null> {\n const models = await scanModels(projectDir);\n const match = models.find(\n (m) => m.name.toLowerCase() === table.toLowerCase(),\n );\n if (!match || match.columns.length === 0) return null;\n\n return {\n source: 'model',\n table: match.name,\n columns: match.columns,\n durationMs: 0,\n };\n}\n\nasync function describeFromDb(\n projectDir: string,\n table: string,\n connectionName?: string,\n): Promise<DescribeSourceResult> {\n const resolved = await resolveTableName(projectDir, table);\n const connection = await resolveConnection(projectDir, connectionName);\n const connector = createConnector(connection, projectDir);\n\n try {\n await connector.connect();\n const query = getDescribeQuery(connection.type, resolved.tableName);\n const startTime = performance.now();\n const result = await connector.execute(query.sql);\n const durationMs = performance.now() - startTime;\n const columns = query.normalize(result.rows as Record<string, unknown>[]);\n\n return {\n source: 'db',\n table: resolved.tableName,\n columns,\n connectionName: connection.name,\n connectionType: connection.type,\n durationMs,\n ...(resolved.source === 'catalog' ? { resolvedFrom: table } : {}),\n };\n } finally {\n await connector.disconnect();\n }\n}\n\nexport async function resolveDescribeSource(\n projectDir: string,\n table: string,\n source: SourceType,\n connectionName?: string,\n): Promise<DescribeSourceResult> {\n switch (source) {\n case 'catalog': {\n const catalog = await loadCatalog(projectDir);\n if (!catalog) throw new Error('No catalog found. Run `yamchart sync-dbt` or `yamchart sync-warehouse` to populate it.');\n const model = findCatalogModel(catalog, table);\n if (!model) throw new Error(`Table \"${table}\" not found in catalog.`);\n if (!model.columns?.length) throw new Error(`Catalog has no column metadata for \"${table}\". Run sync to populate.`);\n return {\n source: 'catalog',\n table: model.table || table,\n columns: catalogColumnsToNormalized(model.columns),\n durationMs: 0,\n ...(model.table ? { resolvedFrom: table } : {}),\n };\n }\n\n case 'model': {\n const models = await scanModels(projectDir);\n const match = models.find((m) => m.name.toLowerCase() === table.toLowerCase());\n if (!match) throw new Error(`No model found matching \"${table}\". Check your models/ directory.`);\n return {\n source: 'model',\n table: match.name,\n columns: match.columns,\n durationMs: 0,\n };\n }\n\n case 'db':\n return describeFromDb(projectDir, table, connectionName);\n\n case 'auto': {\n const catalogResult = await describeFromCatalog(projectDir, table);\n if (catalogResult) return catalogResult;\n\n const modelResult = await describeFromModel(projectDir, table);\n if (modelResult) return modelResult;\n\n return describeFromDb(projectDir, table, connectionName);\n }\n }\n}\n\n// --- TABLES ---\n\nasync function tablesFromCatalog(projectDir: string): Promise<TablesSourceResult | null> {\n const catalog = await loadCatalog(projectDir);\n if (!catalog?.models?.length) return null;\n\n const tables: NormalizedTable[] = catalog.models.map((m) => {\n const parts = (m.table || m.name).split('.');\n return {\n schema: parts.length > 1 ? parts.slice(0, -1).join('.') : '',\n name: parts[parts.length - 1],\n type: m.source === 'dbt-source' ? 'SOURCE' : 'TABLE',\n };\n });\n\n return { source: 'catalog', tables, durationMs: 0 };\n}\n\nasync function tablesFromModel(projectDir: string): Promise<TablesSourceResult | null> {\n const models = await scanModels(projectDir);\n if (models.length === 0) return null;\n\n const tables: NormalizedTable[] = models.map((m) => ({\n schema: '',\n name: m.name,\n type: 'MODEL',\n }));\n\n return { source: 'model', tables, durationMs: 0 };\n}\n\nasync function tablesFromDb(\n projectDir: string,\n connectionName?: string,\n options?: { schema?: string; database?: string },\n): Promise<TablesSourceResult> {\n const connection = await resolveConnection(projectDir, connectionName);\n const connector = createConnector(connection, projectDir);\n\n try {\n await connector.connect();\n const query = getTablesQuery(connection.type, options);\n const start = performance.now();\n const result = await connector.execute(query.sql);\n const tables = query.normalize(result.rows);\n const durationMs = Math.round((performance.now() - start) * 100) / 100;\n\n return {\n source: 'db',\n tables,\n connectionName: connection.name,\n connectionType: connection.type,\n durationMs,\n };\n } finally {\n await connector.disconnect();\n }\n}\n\nexport async function resolveTablesSource(\n projectDir: string,\n source: SourceType,\n connectionName?: string,\n options?: { schema?: string; database?: string },\n): Promise<TablesSourceResult> {\n switch (source) {\n case 'catalog': {\n const catalog = await loadCatalog(projectDir);\n if (!catalog) throw new Error('No catalog found. Run `yamchart sync-dbt` or `yamchart sync-warehouse` to populate it.');\n const result = await tablesFromCatalog(projectDir);\n return result || { source: 'catalog', tables: [], durationMs: 0 };\n }\n\n case 'model': {\n const result = await tablesFromModel(projectDir);\n return result || { source: 'model', tables: [], durationMs: 0 };\n }\n\n case 'db':\n return tablesFromDb(projectDir, connectionName, options);\n\n case 'auto': {\n const catalogResult = await tablesFromCatalog(projectDir);\n if (catalogResult) return catalogResult;\n\n const modelResult = await tablesFromModel(projectDir);\n if (modelResult) return modelResult;\n\n return tablesFromDb(projectDir, connectionName, options);\n }\n }\n}\n\n// --- SEARCH ---\n\nfunction searchCatalog(catalog: CatalogFile, keyword: string): SearchResult[] {\n const results: SearchResult[] = [];\n const lower = keyword.toLowerCase();\n\n for (const model of catalog.models || []) {\n const tableParts = (model.table || model.name).split('.');\n const schema = tableParts.length > 1 ? tableParts.slice(0, -1).join('.') : '';\n const tableName = tableParts[tableParts.length - 1];\n\n if (model.name.toLowerCase().includes(lower) || tableName.toLowerCase().includes(lower)) {\n results.push({ type: 'table', schema, table: model.name });\n }\n\n for (const col of model.columns || []) {\n if (col.name.toLowerCase().includes(lower)) {\n results.push({\n type: 'column',\n schema,\n table: model.name,\n column: col.name,\n columnType: col.data_type,\n });\n }\n }\n }\n\n return results;\n}\n\nasync function searchFromDb(\n projectDir: string,\n keyword: string,\n connectionName?: string,\n): Promise<SearchSourceResult> {\n const connection = await resolveConnection(projectDir, connectionName);\n const connector = createConnector(connection, projectDir);\n\n try {\n await connector.connect();\n const query = getSearchQuery(connection.type, keyword);\n const startTime = performance.now();\n const result = await connector.execute(query.sql);\n const durationMs = performance.now() - startTime;\n const results = query.normalize(result.rows as Record<string, unknown>[]);\n\n return {\n source: 'db',\n keyword,\n results,\n connectionName: connection.name,\n connectionType: connection.type,\n durationMs,\n };\n } finally {\n await connector.disconnect();\n }\n}\n\nexport async function resolveSearchSource(\n projectDir: string,\n keyword: string,\n source: SourceType,\n connectionName?: string,\n): Promise<SearchSourceResult> {\n switch (source) {\n case 'catalog': {\n const catalog = await loadCatalog(projectDir);\n if (!catalog) throw new Error('No catalog found. Run `yamchart sync-dbt` or `yamchart sync-warehouse` to populate it.');\n return { source: 'catalog', keyword, results: searchCatalog(catalog, keyword), durationMs: 0 };\n }\n\n case 'model': {\n const models = await scanModels(projectDir);\n const lower = keyword.toLowerCase();\n const results: SearchResult[] = [];\n\n for (const model of models) {\n if (model.name.toLowerCase().includes(lower)) {\n results.push({ type: 'table', schema: '', table: model.name });\n }\n for (const col of model.columns) {\n if (col.name.toLowerCase().includes(lower)) {\n results.push({ type: 'column', schema: '', table: model.name, column: col.name, columnType: col.type });\n }\n }\n }\n\n return { source: 'model', keyword, results, durationMs: 0 };\n }\n\n case 'db':\n return searchFromDb(projectDir, keyword, connectionName);\n\n case 'auto': {\n const catalog = await loadCatalog(projectDir);\n if (catalog?.models?.length) {\n const results = searchCatalog(catalog, keyword);\n if (results.length > 0) {\n return { source: 'catalog', keyword, results, durationMs: 0 };\n }\n }\n\n const models = await scanModels(projectDir);\n if (models.length > 0) {\n const lower = keyword.toLowerCase();\n const results: SearchResult[] = [];\n for (const model of models) {\n if (model.name.toLowerCase().includes(lower)) {\n results.push({ type: 'table', schema: '', table: model.name });\n }\n for (const col of model.columns) {\n if (col.name.toLowerCase().includes(lower)) {\n results.push({ type: 'column', schema: '', table: model.name, column: col.name, columnType: col.type });\n }\n }\n }\n if (results.length > 0) {\n return { source: 'model', keyword, results, durationMs: 0 };\n }\n }\n\n return searchFromDb(projectDir, keyword, connectionName);\n }\n }\n}\n","import { readFile, readdir, access } from 'fs/promises';\nimport { join, extname } from 'path';\nimport type { NormalizedColumn } from './introspection.js';\n\nexport interface ParsedModel {\n name: string;\n description?: string;\n columns: NormalizedColumn[];\n}\n\n/**\n * Parse @name, @description, and @returns from a SQL model file's content.\n * Returns null if no @name annotation is found.\n */\nexport function parseModelReturns(sql: string): ParsedModel | null {\n const nameMatch = sql.match(/--\\s*@name:\\s*(.+)/);\n if (!nameMatch?.[1]) return null;\n\n const name = nameMatch[1].trim();\n\n const descMatch = sql.match(/--\\s*@description:\\s*(.+)/);\n const description = descMatch?.[1]?.trim();\n\n const columns: NormalizedColumn[] = [];\n\n // Find @returns: block and parse each -- - name: type line\n const returnsMatch = sql.match(/--\\s*@returns:\\s*\\n((?:\\s*--\\s+-\\s+.+\\n?)*)/);\n if (returnsMatch?.[1]) {\n const lines = returnsMatch[1].split('\\n');\n for (const line of lines) {\n const colMatch = line.match(/--\\s+-\\s+(\\w+)(?:\\s*:\\s*(\\w+))?/);\n if (colMatch?.[1]) {\n columns.push({\n name: colMatch[1],\n type: colMatch[2] || 'unknown',\n nullable: 'YES',\n });\n }\n }\n }\n\n return { name, description, columns };\n}\n\n/**\n * Recursively find all .sql files in a directory.\n */\nasync function findSqlFiles(dir: string): Promise<string[]> {\n const files: string[] = [];\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n files.push(...await findSqlFiles(fullPath));\n } else if (extname(entry.name) === '.sql') {\n files.push(fullPath);\n }\n }\n\n return files;\n}\n\n/**\n * Scan models/ directory for SQL files, parse @name and @returns annotations.\n * Returns array of ParsedModel for files that have @name.\n */\nexport async function scanModels(projectDir: string): Promise<ParsedModel[]> {\n const modelsDir = join(projectDir, 'models');\n\n try {\n await access(modelsDir);\n } catch {\n return [];\n }\n\n const sqlFiles = await findSqlFiles(modelsDir);\n const models: ParsedModel[] = [];\n\n for (const filePath of sqlFiles) {\n const content = await readFile(filePath, 'utf-8');\n const parsed = parseModelReturns(content);\n if (parsed) {\n models.push(parsed);\n }\n }\n\n return models;\n}\n"],"mappings":"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","names":["readFile","access","join","join","access","readFile"]}
|