yamchart 0.8.0 → 0.8.2

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.
Files changed (74) hide show
  1. package/CLAUDE.md +1 -1
  2. package/dist/{advisor-57BOMUUF.js → advisor-3V6WKALO.js} +10 -10
  3. package/dist/{chunk-JYQKDWLG.js → chunk-77CBXDCO.js} +1 -1
  4. package/dist/{chunk-JYQKDWLG.js.map → chunk-77CBXDCO.js.map} +1 -1
  5. package/dist/{chunk-OTAUP5RC.js → chunk-GX2PNKES.js} +5 -5
  6. package/dist/chunk-GX2PNKES.js.map +1 -0
  7. package/dist/chunk-HRF7QVK5.js +362 -0
  8. package/dist/chunk-HRF7QVK5.js.map +1 -0
  9. package/dist/{chunk-X6LQGWUX.js → chunk-KP4CYPBL.js} +9 -2
  10. package/dist/chunk-KP4CYPBL.js.map +1 -0
  11. package/dist/{chunk-E2UZXDF6.js → chunk-T76DI6OA.js} +4 -4
  12. package/dist/{chunk-F6QAWPYU.js → chunk-TZKNU5TD.js} +2 -2
  13. package/dist/chunk-TZKNU5TD.js.map +1 -0
  14. package/dist/compare-ZN6RUOOQ.js +87 -0
  15. package/dist/compare-ZN6RUOOQ.js.map +1 -0
  16. package/dist/{connection-utils-FTSZU2VF.js → connection-utils-MI7RM5BP.js} +4 -4
  17. package/dist/describe-46XBIND7.js +29 -0
  18. package/dist/describe-46XBIND7.js.map +1 -0
  19. package/dist/{dev-MRZ76V74.js → dev-IMKOBPDZ.js} +6 -6
  20. package/dist/dev-IMKOBPDZ.js.map +1 -0
  21. package/dist/{dist-WDTDQDTX.js → dist-25RTZO4E.js} +2 -2
  22. package/dist/{dist-PVHFUYP2.js → dist-ONU5AKOH.js} +2 -2
  23. package/dist/index.js +316 -34
  24. package/dist/index.js.map +1 -1
  25. package/dist/{lineage-XSITWW2O.js → lineage-T5NRHHZN.js} +32 -5
  26. package/dist/{lineage-XSITWW2O.js.map → lineage-T5NRHHZN.js.map} +1 -1
  27. package/dist/public/assets/{EventManagement-BlxJ2TFw.js → EventManagement-DSew47oL.js} +1 -1
  28. package/dist/public/assets/{LoginPage-BT8ikmPn.js → LoginPage-BwFMXS0X.js} +1 -1
  29. package/dist/public/assets/{PublicViewer-B4uFxgbt.js → PublicViewer-70ErTigq.js} +1 -1
  30. package/dist/public/assets/{SetupWizard-njrOhCzw.js → SetupWizard-CR7XCMkq.js} +1 -1
  31. package/dist/public/assets/{ShareManagement-Bg16oJhW.js → ShareManagement-B2ZU0Fdy.js} +1 -1
  32. package/dist/public/assets/{UserManagement-tiCIT4UY.js → UserManagement-CHRB-6uy.js} +1 -1
  33. package/dist/public/assets/{index-BZ25r23j.css → index-B_fusLA_.css} +1 -1
  34. package/dist/public/assets/index-DcNtdUoV.js +187 -0
  35. package/dist/public/assets/{index.es-BuktD_R2.js → index.es-BC82iFuu.js} +1 -1
  36. package/dist/public/assets/{jspdf.es.min-DFRl2hZQ.js → jspdf.es.min-DojRcwGj.js} +3 -3
  37. package/dist/public/index.html +3 -3
  38. package/dist/{query-JRMMNXX6.js → query-Q3B4TQTZ.js} +4 -4
  39. package/dist/{sample-VGIY4U4J.js → sample-PEHRM3TN.js} +4 -4
  40. package/dist/search-NBJHS4TZ.js +28 -0
  41. package/dist/search-NBJHS4TZ.js.map +1 -0
  42. package/dist/source-resolver-2DIK3MK4.js +18 -0
  43. package/dist/source-resolver-2DIK3MK4.js.map +1 -0
  44. package/dist/{sync-warehouse-XHTBZH25.js → sync-warehouse-UGTZCZ7J.js} +4 -4
  45. package/dist/tables-ZERITKTS.js +30 -0
  46. package/dist/tables-ZERITKTS.js.map +1 -0
  47. package/dist/templates/default/CLAUDE.md +1 -1
  48. package/dist/templates/default/docs/yamchart-reference.md +5 -0
  49. package/dist/templates/default/yamchart.yaml +1 -1
  50. package/dist/templates/empty/yamchart.yaml +1 -1
  51. package/dist/{test-TXRZWNXK.js → test-ME2Q6CSR.js} +4 -4
  52. package/dist/{update-UKMEWCSO.js → update-WMATDZTO.js} +2 -2
  53. package/package.json +8 -8
  54. package/dist/chunk-F6QAWPYU.js.map +0 -1
  55. package/dist/chunk-OTAUP5RC.js.map +0 -1
  56. package/dist/chunk-X6LQGWUX.js.map +0 -1
  57. package/dist/describe-TGIOBNJB.js +0 -44
  58. package/dist/describe-TGIOBNJB.js.map +0 -1
  59. package/dist/dev-MRZ76V74.js.map +0 -1
  60. package/dist/public/assets/index-B41yj3io.js +0 -187
  61. package/dist/search-QSYNG4SR.js +0 -39
  62. package/dist/search-QSYNG4SR.js.map +0 -1
  63. package/dist/tables-UOO342TA.js +0 -40
  64. package/dist/tables-UOO342TA.js.map +0 -1
  65. /package/dist/{advisor-57BOMUUF.js.map → advisor-3V6WKALO.js.map} +0 -0
  66. /package/dist/{chunk-E2UZXDF6.js.map → chunk-T76DI6OA.js.map} +0 -0
  67. /package/dist/{connection-utils-FTSZU2VF.js.map → connection-utils-MI7RM5BP.js.map} +0 -0
  68. /package/dist/{dist-WDTDQDTX.js.map → dist-25RTZO4E.js.map} +0 -0
  69. /package/dist/{dist-PVHFUYP2.js.map → dist-ONU5AKOH.js.map} +0 -0
  70. /package/dist/{query-JRMMNXX6.js.map → query-Q3B4TQTZ.js.map} +0 -0
  71. /package/dist/{sample-VGIY4U4J.js.map → sample-PEHRM3TN.js.map} +0 -0
  72. /package/dist/{sync-warehouse-XHTBZH25.js.map → sync-warehouse-UGTZCZ7J.js.map} +0 -0
  73. /package/dist/{test-TXRZWNXK.js.map → test-ME2Q6CSR.js.map} +0 -0
  74. /package/dist/{update-UKMEWCSO.js.map → update-WMATDZTO.js.map} +0 -0
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { resolve, basename, dirname, join } from 'path';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { validateProject } from './commands/validate.js';\nimport { findProjectRoot, loadEnvFile } from './utils/config.js';\nimport pc from 'picocolors';\nimport * as output from './utils/output.js';\nimport { checkForUpdate } from './utils/update-check.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\nconst program = new Command();\n\nprogram\n .name('yamchart')\n .description('Git-native business intelligence dashboards')\n .version(pkg.version);\n\nprogram\n .command('validate')\n .description('Validate configuration files')\n .argument('[path]', 'Path to yamchart project', '.')\n .option('--dry-run', 'Connect to database and test queries with EXPLAIN')\n .option('-c, --connection <name>', 'Connection to use for dry-run')\n .option('--json', 'Output as JSON')\n .action(async (path: string, options: { dryRun?: boolean; connection?: string; json?: boolean }) => {\n const startPath = resolve(path);\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: 'yamchart.yaml not found' }));\n } else {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n }\n process.exit(2);\n }\n\n // Load .env file\n loadEnvFile(projectDir);\n\n if (!options.json) {\n output.header('Validating yamchart project...');\n }\n\n const result = await validateProject(projectDir, {\n dryRun: options.dryRun ?? false,\n connection: options.connection,\n });\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n // Print results\n for (const error of result.errors) {\n output.error(error.file);\n output.detail(error.message);\n if (error.suggestion) {\n output.detail(error.suggestion);\n }\n }\n\n for (const warning of result.warnings) {\n output.warning(warning.file);\n output.detail(warning.message);\n }\n\n output.newline();\n\n if (result.success) {\n output.success(`Schema: ${result.stats.passed} passed`);\n } else {\n output.error(`Schema: ${result.stats.passed} passed, ${result.stats.failed} failed`);\n }\n\n if (result.dryRunStats) {\n output.newline();\n if (result.dryRunStats.failed === 0) {\n output.success(`Queries: ${result.dryRunStats.passed} passed (EXPLAIN OK)`);\n } else {\n output.error(`Queries: ${result.dryRunStats.passed} passed, ${result.dryRunStats.failed} failed`);\n }\n }\n\n output.newline();\n\n if (result.success) {\n output.success('Validation passed');\n } else {\n output.error(`Validation failed with ${result.errors.length} error(s)`);\n }\n }\n\n process.exit(result.success ? 0 : 1);\n });\n\nprogram\n .command('dev')\n .description('Start development server with hot reload')\n .argument('[path]', 'Path to yamchart project', '.')\n .option('-p, --port <number>', 'Port to listen on', '3001')\n .option('--api-only', 'Only serve API, no web UI')\n .option('--no-open', 'Do not open browser automatically')\n .action(async (path: string, options: { port: string; apiOnly?: boolean; open: boolean }) => {\n const startPath = resolve(path);\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n const { runDevServer } = await import('./commands/dev.js');\n\n await runDevServer(projectDir, {\n port: parseInt(options.port, 10),\n apiOnly: options.apiOnly ?? false,\n open: options.open,\n });\n });\n\nprogram\n .command('init')\n .description('Create a new yamchart project')\n .argument('[directory]', 'Target directory', '.')\n .option('--example', 'Create full example project with sample database')\n .option('--empty', 'Create only yamchart.yaml (no connections, models, or charts)')\n .option('--force', 'Overwrite existing files')\n .action(async (directory: string, options: { example?: boolean; empty?: boolean; force?: boolean }) => {\n const { initProject } = await import('./commands/init.js');\n const targetDir = resolve(directory);\n\n const result = await initProject(targetDir, options);\n\n if (!result.success) {\n output.error(result.error || 'Failed to create project');\n process.exit(1);\n }\n\n output.newline();\n output.success(`Created ${directory === '.' ? basename(targetDir) : directory}/`);\n for (const file of result.files.slice(0, 10)) {\n output.detail(file);\n }\n if (result.files.length > 10) {\n output.detail(`... and ${result.files.length - 10} more files`);\n }\n output.newline();\n output.info(`Run \\`cd ${directory === '.' ? basename(targetDir) : directory} && yamchart dev\\` to start.`);\n });\n\nprogram\n .command('sync-dbt')\n .description('Sync dbt project metadata into AI-readable catalog')\n .option('-s, --source <type>', 'Source type: local, github, dbt-cloud', 'local')\n .option('-p, --path <dir>', 'Path to dbt project (for local source)')\n .option('--repo <repo>', 'GitHub repository (for github source)')\n .option('--branch <branch>', 'Git branch (for github source)', 'main')\n .option('-i, --include <patterns...>', 'Include glob patterns')\n .option('-e, --exclude <patterns...>', 'Exclude glob patterns')\n .option('-t, --tag <tags...>', 'Filter by dbt tags')\n .option('--refresh', 'Re-sync using saved configuration')\n .option('--target-database <database>', 'Override database in ref() paths (e.g. switch from dev to prod)')\n .action(async (options: {\n source: 'local' | 'github' | 'dbt-cloud';\n path?: string;\n repo?: string;\n branch?: string;\n include?: string[];\n exclude?: string[];\n tag?: string[];\n refresh?: boolean;\n targetDatabase?: string;\n }) => {\n const { syncDbt, loadSyncConfig } = await import('./commands/sync-dbt.js');\n\n // Find project root\n const projectDir = await findProjectRoot(process.cwd());\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n // Handle refresh mode\n if (options.refresh) {\n const savedConfig = await loadSyncConfig(projectDir);\n if (!savedConfig) {\n output.error('No saved sync config found');\n output.detail('Run sync-dbt without --refresh first');\n process.exit(1);\n }\n output.info(`Re-syncing from ${savedConfig.source}:${savedConfig.path || savedConfig.repo}`);\n }\n\n const spin = output.spinner('Syncing dbt metadata...');\n\n const result = await syncDbt(projectDir, {\n source: options.source,\n path: options.path,\n repo: options.repo,\n branch: options.branch,\n include: options.include || [],\n exclude: options.exclude || [],\n tags: options.tag || [],\n refresh: options.refresh,\n targetDatabase: options.targetDatabase,\n });\n\n spin.stop();\n\n if (!result.success) {\n output.error(result.error || 'Sync failed');\n process.exit(1);\n }\n\n output.success(`Synced ${result.modelsIncluded} models to .yamchart/catalog.md`);\n if (result.modelsExcluded > 0) {\n output.detail(`${result.modelsExcluded} models filtered out`);\n }\n\n // Show lineage warnings\n if (result.warnings) {\n for (const w of result.warnings) {\n output.warning(w);\n }\n }\n\n // Check for database mismatch (skip if --target-database was used)\n if (!options.targetDatabase) {\n try {\n const { readFile } = await import('fs/promises');\n const { resolveConnection } = await import('./commands/connection-utils.js');\n const { detectDatabaseMismatch } = await import('./dbt/rewrite-database.js');\n const catalogJsonStr = await readFile(join(projectDir, '.yamchart', 'catalog.json'), 'utf-8');\n const catalogData = JSON.parse(catalogJsonStr);\n const connection = await resolveConnection(projectDir);\n // Extract database from connection config (varies by type)\n const connDb = (connection as Record<string, any>).config?.database as string | undefined;\n const mismatch = detectDatabaseMismatch(catalogData.models, connDb);\n if (mismatch.mismatch) {\n output.warning(\n `Catalog tables reference database \"${mismatch.catalogDatabase}\" but your default ` +\n `connection uses \"${mismatch.connectionDatabase}\". Models using ref() may query the wrong database.`\n );\n output.detail(\n `To fix: yamchart sync-dbt --refresh --target-database ${mismatch.connectionDatabase}`\n );\n }\n } catch {\n // Connection not configured or unreadable — skip silently\n }\n }\n });\n\nprogram\n .command('generate')\n .description('Generate SQL model stubs from dbt catalog')\n .argument('[model]', 'Specific model to generate (optional)')\n .option('--yolo', 'Skip all prompts, use defaults for everything')\n .action(async (model: string | undefined, options: { yolo?: boolean }) => {\n const { generate } = await import('./commands/generate.js');\n\n const projectDir = await findProjectRoot(process.cwd());\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n const result = await generate(projectDir, {\n model,\n yolo: options.yolo,\n });\n\n if (!result.success) {\n output.error(result.error || 'Generate failed');\n process.exit(1);\n }\n\n output.success(`Generated ${result.filesCreated} model stubs`);\n if (result.filesSkipped > 0) {\n output.detail(`${result.filesSkipped} files skipped`);\n }\n });\n\nprogram\n .command('test')\n .description('Run model tests (@returns schema checks and @tests data assertions)')\n .argument('[model]', 'Specific model to test (optional, tests all if omitted)')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('--json', 'Output as JSON')\n .action(async (model: string | undefined, options: { connection?: string; json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: 'yamchart.yaml not found' }));\n } else {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n }\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { testProject, formatTestOutput } = await import('./commands/test.js');\n const result = await testProject(projectDir, model, {\n connection: options.connection,\n json: options.json,\n });\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n formatTestOutput(result, result.connectionName);\n }\n\n process.exit(result.success ? 0 : 1);\n } catch (err) {\n if (options.json) {\n console.log(\n JSON.stringify({ success: false, error: err instanceof Error ? err.message : String(err) }),\n );\n } else {\n output.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(2);\n }\n });\n\nprogram\n .command('update')\n .description('Check for yamchart updates')\n .action(async () => {\n const { runUpdate } = await import('./commands/update.js');\n await runUpdate(pkg.version);\n });\n\nprogram\n .command('reset-password')\n .description('Reset a user password (requires auth to be enabled)')\n .requiredOption('-e, --email <email>', 'Email address of the user')\n .action(async (options: { email: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n const { resetPassword } = await import('./commands/reset-password.js');\n await resetPassword(projectDir, options.email);\n });\n\nprogram\n .command('tables')\n .description('List tables and views in the connected database')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('-s, --schema <name>', 'Filter to schema')\n .option('-d, --database <name>', 'Filter to database (Snowflake/Databricks)')\n .option('--json', 'Output as JSON')\n .action(async (options: { connection?: string; schema?: string; database?: string; json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { listTables } = await import('./commands/tables.js');\n const result = await listTables(projectDir, options);\n\n if (options.json) {\n console.log(JSON.stringify(result.tables, null, 2));\n } else {\n output.header(`Tables in ${result.connectionName} (${result.connectionType})`);\n if (result.tables.length === 0) {\n output.info('No tables found');\n } else {\n for (const table of result.tables) {\n const schema = table.schema ? `${table.schema}.` : '';\n const typeLabel = table.type === 'VIEW' ? pc.dim(' (view)') : '';\n console.log(` ${schema}${table.name}${typeLabel}`);\n }\n output.newline();\n output.info(`${result.tables.length} table(s) found (${result.durationMs.toFixed(0)}ms)`);\n }\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('describe')\n .description('Show columns and types for a table')\n .argument('<table>', 'Table name (can be fully qualified, e.g. schema.table)')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('--json', 'Output as JSON')\n .action(async (table: string, options: { connection?: string; json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { describeTable } = await import('./commands/describe.js');\n const result = await describeTable(projectDir, table, options);\n\n if (options.json) {\n console.log(JSON.stringify(result.columns, null, 2));\n } else {\n if (result.resolvedFrom) {\n output.detail(`Resolved \"${result.resolvedFrom}\" → ${result.table}`);\n }\n output.header(`${result.table} (${result.connectionName})`);\n\n const nameWidth = Math.max(4, ...result.columns.map((c) => c.name.length));\n const typeWidth = Math.max(4, ...result.columns.map((c) => c.type.length));\n\n console.log(` ${'name'.padEnd(nameWidth)} ${'type'.padEnd(typeWidth)} nullable`);\n console.log(` ${'─'.repeat(nameWidth)} ${'─'.repeat(typeWidth)} ${'─'.repeat(8)}`);\n\n for (const col of result.columns) {\n const nullable = col.nullable === 'YES' ? pc.dim('yes') : 'no';\n console.log(` ${col.name.padEnd(nameWidth)} ${pc.dim(col.type.padEnd(typeWidth))} ${nullable}`);\n }\n\n output.newline();\n output.info(`${result.columns.length} column(s) (${result.durationMs.toFixed(0)}ms)`);\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('query')\n .description('Execute SQL against a connection')\n .argument('<sql>', 'SQL query to execute')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('--json', 'Output as JSON')\n .option('-l, --limit <number>', 'Max rows to return (default: 100)')\n .action(async (sql: string, options: { connection?: string; json?: boolean; limit?: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { executeQuery } = await import('./commands/query.js');\n const { formatTable, formatJSON } = await import('./commands/connection-utils.js');\n\n const limit = options.limit ? parseInt(options.limit, 10) : undefined;\n const result = await executeQuery(projectDir, sql, {\n connection: options.connection,\n json: options.json,\n limit,\n });\n\n if (options.json) {\n console.log(formatJSON(result));\n } else {\n console.log(formatTable(result));\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('sample')\n .description('Show sample rows from a table or dbt model')\n .argument('<table>', 'Table name or dbt model name')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('-l, --limit <number>', 'Rows to show (default: 5)')\n .option('--json', 'Output as JSON')\n .action(async (table: string, options: { connection?: string; json?: boolean; limit?: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { sampleTable } = await import('./commands/sample.js');\n const { formatTable, formatJSON } = await import('./commands/connection-utils.js');\n\n const limit = options.limit ? parseInt(options.limit, 10) : undefined;\n const result = await sampleTable(projectDir, table, {\n connection: options.connection,\n json: options.json,\n limit,\n });\n\n if (options.json) {\n console.log(formatJSON(result));\n } else {\n if (result.resolvedFrom) {\n output.detail(`Resolved \"${result.resolvedFrom}\" → ${result.table}`);\n }\n console.log(formatTable(result));\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('search')\n .description('Search for tables and columns by keyword')\n .argument('<keyword>', 'Keyword to search for')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('--json', 'Output as JSON')\n .action(async (keyword: string, options: { connection?: string; json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { searchDatabase } = await import('./commands/search.js');\n const result = await searchDatabase(projectDir, keyword, options);\n\n if (options.json) {\n console.log(JSON.stringify(result.results, null, 2));\n } else {\n output.header(`Search results for \"${result.keyword}\" in ${result.connectionName} (${result.connectionType})`);\n\n const tables = result.results.filter((r) => r.type === 'table');\n const columns = result.results.filter((r) => r.type === 'column');\n\n if (tables.length > 0) {\n output.newline();\n console.log(' Tables:');\n for (const t of tables) {\n const qualified = t.schema ? `${t.schema}.${t.table}` : t.table;\n console.log(` ${qualified}`);\n }\n }\n\n if (columns.length > 0) {\n output.newline();\n console.log(' Columns:');\n const nameWidth = Math.max(...columns.map((c) => {\n const qualified = c.schema ? `${c.schema}.${c.table}.${c.column}` : `${c.table}.${c.column}`;\n return qualified.length;\n }));\n for (const c of columns) {\n const qualified = c.schema ? `${c.schema}.${c.table}.${c.column}` : `${c.table}.${c.column}`;\n const colType = c.columnType ? pc.dim(c.columnType) : '';\n console.log(` ${qualified.padEnd(nameWidth + 2)}${colType}`);\n }\n }\n\n if (result.results.length === 0) {\n output.detail('No matches found');\n }\n\n output.newline();\n output.info(`${result.results.length} result(s) (${result.durationMs.toFixed(0)}ms)`);\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('sync-warehouse')\n .description('Sync warehouse table metadata into the catalog')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('-s, --schema <schemas>', 'Comma-separated schemas to sync')\n .option('-d, --database <name>', 'Database to sync (Snowflake/Databricks)')\n .option('--skip-samples', 'Skip sample row collection')\n .option('--refresh', 'Re-run with saved connection/schema config')\n .option('--full', 'Force full re-sync (ignore incremental state)')\n .option('--json', 'Output sync summary as JSON')\n .action(async (options) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { runSyncWarehouse } = await import('./commands/sync-warehouse.js');\n await runSyncWarehouse(projectDir, options);\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('lineage')\n .description('Show upstream dependencies for a model')\n .argument('<model>', 'Model name to trace lineage for')\n .option('--depth <n>', 'Maximum depth to trace (default: unlimited)')\n .option('--json', 'Output as JSON')\n .action(async (model: string, options: { depth?: string; json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n try {\n const { getLineage } = await import('./commands/lineage.js');\n const depth = options.depth ? parseInt(options.depth, 10) : undefined;\n const result = await getLineage(projectDir, model, { depth, json: options.json });\n\n if (options.json) {\n console.log(JSON.stringify(result.tree, null, 2));\n } else {\n console.log(result.rendered);\n }\n } catch (err) {\n if (err instanceof Error && err.message.includes('ENOENT')) {\n output.error('No catalog found. Run `yamchart sync-dbt` first.');\n } else {\n output.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(1);\n }\n });\n\nprogram\n .command('advisor')\n .description('AI-powered dbt model advisor — suggests improvements informed by your BI layer')\n .argument('[question]', 'Question to ask, or \"audit\" for comprehensive analysis')\n .option('--top <n>', 'Limit audit suggestions (default: 5)')\n .option('--json', 'Output as JSON')\n .option('--dbt-path <path>', 'Override the synced dbt project path')\n .option('-c, --connection <name>', 'Connection to use for warehouse introspection')\n .action(async (question: string | undefined, options: { top?: string; json?: boolean; dbtPath?: string; connection?: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: 'yamchart.yaml not found' }));\n } else {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n }\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n const { runAdvisor } = await import('./commands/advisor.js');\n await runAdvisor(projectDir, question, {\n top: options.top ? parseInt(options.top, 10) : 5,\n json: options.json,\n dbtPath: options.dbtPath,\n connection: options.connection,\n });\n });\n\nconst semanticCmd = program\n .command('semantic')\n .description('Explore the semantic layer — auto-generated measures and dimensions from your catalog')\n .option('--json', 'Output as JSON')\n .action(async (options: { json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { readFile } = await import('fs/promises');\n const catalogPath = join(projectDir, '.yamchart', 'catalog.json');\n const catalogJson = JSON.parse(await readFile(catalogPath, 'utf-8'));\n\n const { listSemanticEntities } = await import('./commands/semantic.js');\n const result = listSemanticEntities(catalogJson);\n\n if (options.json) {\n console.log(JSON.stringify(result.entities, null, 2));\n return;\n }\n\n if (result.entities.length === 0) {\n output.info('No semantic entities found.');\n output.detail('Run `yamchart sync-dbt` or `yamchart sync-warehouse` to populate the catalog.');\n return;\n }\n\n output.header(`Semantic Layer — ${result.entities.length} entities`);\n\n for (const entity of result.entities) {\n console.log(` ${pc.bold(entity.name)}`);\n console.log(` ${pc.dim(entity.source_table)}`);\n if (entity.description) {\n console.log(` ${entity.description}`);\n }\n if (entity.measures.length > 0) {\n console.log(` Measures: ${entity.measures.map((m) => `${m.name} (${pc.dim(m.type)})`).join(', ')}`);\n }\n if (entity.dimensions.length > 0) {\n console.log(` Dimensions: ${entity.dimensions.map((d) => `${d.name} (${pc.dim(d.type)})`).join(', ')}`);\n }\n console.log();\n }\n } catch (err) {\n if (err instanceof Error && err.message.includes('ENOENT')) {\n output.error('No catalog found. Run `yamchart sync-dbt` or `yamchart sync-warehouse` first.');\n } else {\n output.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(1);\n }\n });\n\nsemanticCmd\n .command('query')\n .description('Run a structured query against the semantic layer')\n .requiredOption('-e, --entity <name>', 'Entity name (e.g. fct_revenue)')\n .requiredOption('-m, --measures <measures>', 'Comma-separated measure names')\n .option('-d, --dimensions <dimensions>', 'Comma-separated dimension names')\n .option('-f, --filter <filter...>', 'Filters in format dimension=value')\n .option('--order <field>', 'Order by field')\n .option('--desc', 'Order descending (default: ascending)')\n .option('-l, --limit <n>', 'Row limit (default: 100)')\n .option('-c, --connection <name>', 'Connection to use')\n .option('--json', 'Output as JSON')\n .option('--sql', 'Print compiled SQL only (do not execute)')\n .action(async (options: {\n entity: string;\n measures: string;\n dimensions?: string;\n filter?: string[];\n order?: string;\n desc?: boolean;\n limit?: string;\n connection?: string;\n json?: boolean;\n sql?: boolean;\n }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { readFile } = await import('fs/promises');\n const catalogPath = join(projectDir, '.yamchart', 'catalog.json');\n const catalogJson = JSON.parse(await readFile(catalogPath, 'utf-8'));\n\n const { querySemanticEntity } = await import('./commands/semantic.js');\n\n // Parse filters: \"region=US\" → { dimension: 'region', operator: 'equals', value: 'US' }\n const filters = (options.filter || []).map((f) => {\n const eqIdx = f.indexOf('=');\n if (eqIdx === -1) throw new Error(`Invalid filter format: \"${f}\". Use dimension=value`);\n return {\n dimension: f.slice(0, eqIdx),\n operator: 'equals' as const,\n value: f.slice(eqIdx + 1),\n };\n });\n\n const result = querySemanticEntity(catalogJson, {\n entity: options.entity,\n measures: options.measures.split(',').map((s) => s.trim()),\n dimensions: options.dimensions ? options.dimensions.split(',').map((s) => s.trim()) : [],\n filters,\n order_by: options.order ? { field: options.order, direction: options.desc ? 'desc' : 'asc' } : undefined,\n limit: options.limit ? parseInt(options.limit, 10) : 100,\n });\n\n // --sql: just print the SQL\n if (options.sql) {\n console.log(result.sql);\n return;\n }\n\n // Execute the query\n const { resolveConnection, createConnector, formatTable, formatJSON } = await import('./commands/connection-utils.js');\n const connection = await resolveConnection(projectDir, options.connection);\n const connector = createConnector(connection, projectDir);\n\n const start = performance.now();\n await connector.connect();\n const queryResult = await connector.execute(result.sql);\n await connector.disconnect();\n const durationMs = Math.round((performance.now() - start) * 100) / 100;\n\n if (options.json) {\n console.log(formatJSON({\n columns: queryResult.columns,\n rows: queryResult.rows,\n rowCount: queryResult.rows.length,\n durationMs,\n }));\n } else {\n output.detail(`Entity: ${result.entityName}`);\n output.detail(`SQL: ${result.sql.replace(/\\n/g, ' ').slice(0, 120)}...`);\n output.newline();\n console.log(formatTable({\n columns: queryResult.columns,\n rows: queryResult.rows,\n rowCount: queryResult.rows.length,\n durationMs,\n }));\n }\n } catch (err) {\n if (err instanceof Error && err.message.includes('ENOENT')) {\n output.error('No catalog found. Run `yamchart sync-dbt` or `yamchart sync-warehouse` first.');\n } else {\n output.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(1);\n }\n });\n\nprogram.parse();\n\n// Passive update check — runs in background, prints on exit if outdated\nlet updateNotification: string | null = null;\n\ncheckForUpdate(pkg.version).then((update) => {\n if (update) {\n updateNotification = `\\n Update available: ${update.current} → ${update.latest}\\n Run: yamchart update to see what's new\\n`;\n }\n});\n\nprocess.on('exit', () => {\n if (updateNotification) {\n // Use dim styling so it doesn't compete with command output\n console.error(`\\n${pc.dim(updateNotification)}`);\n }\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AACA,SAAS,eAAe;AACxB,SAAS,SAAS,UAAU,SAAS,YAAY;AACjD,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAG9B,OAAO,QAAQ;AAIf,IAAM,YAAY,QAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,IAAM,MAAM,KAAK,MAAM,aAAa,KAAK,WAAW,iBAAiB,GAAG,OAAO,CAAC;AAEhF,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,UAAU,EACf,YAAY,6CAA6C,EACzD,QAAQ,IAAI,OAAO;AAEtB,QACG,QAAQ,UAAU,EAClB,YAAY,8BAA8B,EAC1C,SAAS,UAAU,4BAA4B,GAAG,EAClD,OAAO,aAAa,mDAAmD,EACvE,OAAO,2BAA2B,+BAA+B,EACjE,OAAO,UAAU,gBAAgB,EACjC,OAAO,OAAO,MAAc,YAAuE;AAClG,QAAM,YAAY,QAAQ,IAAI;AAC9B,QAAM,aAAa,MAAM,gBAAgB,SAAS;AAElD,MAAI,CAAC,YAAY;AACf,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,OAAO,OAAO,0BAA0B,CAAC,CAAC;AAAA,IAClF,OAAO;AACL,MAAO,MAAM,yBAAyB;AACtC,MAAO,OAAO,oDAAoD;AAAA,IACpE;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,cAAY,UAAU;AAEtB,MAAI,CAAC,QAAQ,MAAM;AACjB,IAAO,OAAO,gCAAgC;AAAA,EAChD;AAEA,QAAM,SAAS,MAAM,gBAAgB,YAAY;AAAA,IAC/C,QAAQ,QAAQ,UAAU;AAAA,IAC1B,YAAY,QAAQ;AAAA,EACtB,CAAC;AAED,MAAI,QAAQ,MAAM;AAChB,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,OAAO;AAEL,eAAWA,UAAS,OAAO,QAAQ;AACjC,MAAO,MAAMA,OAAM,IAAI;AACvB,MAAO,OAAOA,OAAM,OAAO;AAC3B,UAAIA,OAAM,YAAY;AACpB,QAAO,OAAOA,OAAM,UAAU;AAAA,MAChC;AAAA,IACF;AAEA,eAAWC,YAAW,OAAO,UAAU;AACrC,MAAO,QAAQA,SAAQ,IAAI;AAC3B,MAAO,OAAOA,SAAQ,OAAO;AAAA,IAC/B;AAEA,IAAO,QAAQ;AAEf,QAAI,OAAO,SAAS;AAClB,MAAO,QAAQ,WAAW,OAAO,MAAM,MAAM,SAAS;AAAA,IACxD,OAAO;AACL,MAAO,MAAM,WAAW,OAAO,MAAM,MAAM,YAAY,OAAO,MAAM,MAAM,SAAS;AAAA,IACrF;AAEA,QAAI,OAAO,aAAa;AACtB,MAAO,QAAQ;AACf,UAAI,OAAO,YAAY,WAAW,GAAG;AACnC,QAAO,QAAQ,YAAY,OAAO,YAAY,MAAM,sBAAsB;AAAA,MAC5E,OAAO;AACL,QAAO,MAAM,YAAY,OAAO,YAAY,MAAM,YAAY,OAAO,YAAY,MAAM,SAAS;AAAA,MAClG;AAAA,IACF;AAEA,IAAO,QAAQ;AAEf,QAAI,OAAO,SAAS;AAClB,MAAO,QAAQ,mBAAmB;AAAA,IACpC,OAAO;AACL,MAAO,MAAM,0BAA0B,OAAO,OAAO,MAAM,WAAW;AAAA,IACxE;AAAA,EACF;AAEA,UAAQ,KAAK,OAAO,UAAU,IAAI,CAAC;AACrC,CAAC;AAEH,QACG,QAAQ,KAAK,EACb,YAAY,0CAA0C,EACtD,SAAS,UAAU,4BAA4B,GAAG,EAClD,OAAO,uBAAuB,qBAAqB,MAAM,EACzD,OAAO,cAAc,2BAA2B,EAChD,OAAO,aAAa,mCAAmC,EACvD,OAAO,OAAO,MAAc,YAAgE;AAC3F,QAAM,YAAY,QAAQ,IAAI;AAC9B,QAAM,aAAa,MAAM,gBAAgB,SAAS;AAElD,MAAI,CAAC,YAAY;AACf,IAAO,MAAM,yBAAyB;AACtC,IAAO,OAAO,oDAAoD;AAClE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,EAAE,aAAa,IAAI,MAAM,OAAO,mBAAmB;AAEzD,QAAM,aAAa,YAAY;AAAA,IAC7B,MAAM,SAAS,QAAQ,MAAM,EAAE;AAAA,IAC/B,SAAS,QAAQ,WAAW;AAAA,IAC5B,MAAM,QAAQ;AAAA,EAChB,CAAC;AACH,CAAC;AAEH,QACG,QAAQ,MAAM,EACd,YAAY,+BAA+B,EAC3C,SAAS,eAAe,oBAAoB,GAAG,EAC/C,OAAO,aAAa,kDAAkD,EACtE,OAAO,WAAW,+DAA+D,EACjF,OAAO,WAAW,0BAA0B,EAC5C,OAAO,OAAO,WAAmB,YAAqE;AACrG,QAAM,EAAE,YAAY,IAAI,MAAM,OAAO,oBAAoB;AACzD,QAAM,YAAY,QAAQ,SAAS;AAEnC,QAAM,SAAS,MAAM,YAAY,WAAW,OAAO;AAEnD,MAAI,CAAC,OAAO,SAAS;AACnB,IAAO,MAAM,OAAO,SAAS,0BAA0B;AACvD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,EAAO,QAAQ;AACf,EAAO,QAAQ,WAAW,cAAc,MAAM,SAAS,SAAS,IAAI,SAAS,GAAG;AAChF,aAAW,QAAQ,OAAO,MAAM,MAAM,GAAG,EAAE,GAAG;AAC5C,IAAO,OAAO,IAAI;AAAA,EACpB;AACA,MAAI,OAAO,MAAM,SAAS,IAAI;AAC5B,IAAO,OAAO,WAAW,OAAO,MAAM,SAAS,EAAE,aAAa;AAAA,EAChE;AACA,EAAO,QAAQ;AACf,EAAO,KAAK,YAAY,cAAc,MAAM,SAAS,SAAS,IAAI,SAAS,8BAA8B;AAC3G,CAAC;AAEH,QACG,QAAQ,UAAU,EAClB,YAAY,oDAAoD,EAChE,OAAO,uBAAuB,yCAAyC,OAAO,EAC9E,OAAO,oBAAoB,wCAAwC,EACnE,OAAO,iBAAiB,uCAAuC,EAC/D,OAAO,qBAAqB,kCAAkC,MAAM,EACpE,OAAO,+BAA+B,uBAAuB,EAC7D,OAAO,+BAA+B,uBAAuB,EAC7D,OAAO,uBAAuB,oBAAoB,EAClD,OAAO,aAAa,mCAAmC,EACvD,OAAO,gCAAgC,iEAAiE,EACxG,OAAO,OAAO,YAUT;AACJ,QAAM,EAAE,SAAS,eAAe,IAAI,MAAM,OAAO,wBAAwB;AAGzE,QAAM,aAAa,MAAM,gBAAgB,QAAQ,IAAI,CAAC;AAEtD,MAAI,CAAC,YAAY;AACf,IAAO,MAAM,yBAAyB;AACtC,IAAO,OAAO,oDAAoD;AAClE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,MAAI,QAAQ,SAAS;AACnB,UAAM,cAAc,MAAM,eAAe,UAAU;AACnD,QAAI,CAAC,aAAa;AAChB,MAAO,MAAM,4BAA4B;AACzC,MAAO,OAAO,sCAAsC;AACpD,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,IAAO,KAAK,mBAAmB,YAAY,MAAM,IAAI,YAAY,QAAQ,YAAY,IAAI,EAAE;AAAA,EAC7F;AAEA,QAAM,OAAc,QAAQ,yBAAyB;AAErD,QAAM,SAAS,MAAM,QAAQ,YAAY;AAAA,IACvC,QAAQ,QAAQ;AAAA,IAChB,MAAM,QAAQ;AAAA,IACd,MAAM,QAAQ;AAAA,IACd,QAAQ,QAAQ;AAAA,IAChB,SAAS,QAAQ,WAAW,CAAC;AAAA,IAC7B,SAAS,QAAQ,WAAW,CAAC;AAAA,IAC7B,MAAM,QAAQ,OAAO,CAAC;AAAA,IACtB,SAAS,QAAQ;AAAA,IACjB,gBAAgB,QAAQ;AAAA,EAC1B,CAAC;AAED,OAAK,KAAK;AAEV,MAAI,CAAC,OAAO,SAAS;AACnB,IAAO,MAAM,OAAO,SAAS,aAAa;AAC1C,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,EAAO,QAAQ,UAAU,OAAO,cAAc,iCAAiC;AAC/E,MAAI,OAAO,iBAAiB,GAAG;AAC7B,IAAO,OAAO,GAAG,OAAO,cAAc,sBAAsB;AAAA,EAC9D;AAGA,MAAI,OAAO,UAAU;AACnB,eAAW,KAAK,OAAO,UAAU;AAC/B,MAAO,QAAQ,CAAC;AAAA,IAClB;AAAA,EACF;AAGA,MAAI,CAAC,QAAQ,gBAAgB;AAC3B,QAAI;AACF,YAAM,EAAE,SAAS,IAAI,MAAM,OAAO,aAAa;AAC/C,YAAM,EAAE,kBAAkB,IAAI,MAAM,OAAO,gCAAgC;AAC3E,YAAM,EAAE,uBAAuB,IAAI,MAAM,OAAO,gCAA2B;AAC3E,YAAM,iBAAiB,MAAM,SAAS,KAAK,YAAY,aAAa,cAAc,GAAG,OAAO;AAC5F,YAAM,cAAc,KAAK,MAAM,cAAc;AAC7C,YAAM,aAAa,MAAM,kBAAkB,UAAU;AAErD,YAAM,SAAU,WAAmC,QAAQ;AAC3D,YAAM,WAAW,uBAAuB,YAAY,QAAQ,MAAM;AAClE,UAAI,SAAS,UAAU;AACrB,QAAO;AAAA,UACL,sCAAsC,SAAS,eAAe,uCAC1C,SAAS,kBAAkB;AAAA,QACjD;AACA,QAAO;AAAA,UACL,yDAAyD,SAAS,kBAAkB;AAAA,QACtF;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACF,CAAC;AAEH,QACG,QAAQ,UAAU,EAClB,YAAY,2CAA2C,EACvD,SAAS,WAAW,uCAAuC,EAC3D,OAAO,UAAU,+CAA+C,EAChE,OAAO,OAAO,OAA2B,YAAgC;AACxE,QAAM,EAAE,SAAS,IAAI,MAAM,OAAO,wBAAwB;AAE1D,QAAM,aAAa,MAAM,gBAAgB,QAAQ,IAAI,CAAC;AAEtD,MAAI,CAAC,YAAY;AACf,IAAO,MAAM,yBAAyB;AACtC,IAAO,OAAO,oDAAoD;AAClE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,MAAM,SAAS,YAAY;AAAA,IACxC;AAAA,IACA,MAAM,QAAQ;AAAA,EAChB,CAAC;AAED,MAAI,CAAC,OAAO,SAAS;AACnB,IAAO,MAAM,OAAO,SAAS,iBAAiB;AAC9C,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,EAAO,QAAQ,aAAa,OAAO,YAAY,cAAc;AAC7D,MAAI,OAAO,eAAe,GAAG;AAC3B,IAAO,OAAO,GAAG,OAAO,YAAY,gBAAgB;AAAA,EACtD;AACF,CAAC;AAEH,QACG,QAAQ,MAAM,EACd,YAAY,qEAAqE,EACjF,SAAS,WAAW,yDAAyD,EAC7E,OAAO,2BAA2B,uCAAuC,EACzE,OAAO,UAAU,gBAAgB,EACjC,OAAO,OAAO,OAA2B,YAAqD;AAC7F,QAAM,YAAY,QAAQ,GAAG;AAC7B,QAAM,aAAa,MAAM,gBAAgB,SAAS;AAElD,MAAI,CAAC,YAAY;AACf,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,OAAO,OAAO,0BAA0B,CAAC,CAAC;AAAA,IAClF,OAAO;AACL,MAAO,MAAM,yBAAyB;AACtC,MAAO,OAAO,oDAAoD;AAAA,IACpE;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,cAAY,UAAU;AAEtB,MAAI;AACF,UAAM,EAAE,aAAa,iBAAiB,IAAI,MAAM,OAAO,oBAAoB;AAC3E,UAAM,SAAS,MAAM,YAAY,YAAY,OAAO;AAAA,MAClD,YAAY,QAAQ;AAAA,MACpB,MAAM,QAAQ;AAAA,IAChB,CAAC;AAED,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,IAC7C,OAAO;AACL,uBAAiB,QAAQ,OAAO,cAAc;AAAA,IAChD;AAEA,YAAQ,KAAK,OAAO,UAAU,IAAI,CAAC;AAAA,EACrC,SAAS,KAAK;AACZ,QAAI,QAAQ,MAAM;AAChB,cAAQ;AAAA,QACN,KAAK,UAAU,EAAE,SAAS,OAAO,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE,CAAC;AAAA,MAC5F;AAAA,IACF,OAAO;AACL,MAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IAC/D;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,4BAA4B,EACxC,OAAO,YAAY;AAClB,QAAM,EAAE,UAAU,IAAI,MAAM,OAAO,sBAAsB;AACzD,QAAM,UAAU,IAAI,OAAO;AAC7B,CAAC;AAEH,QACG,QAAQ,gBAAgB,EACxB,YAAY,qDAAqD,EACjE,eAAe,uBAAuB,2BAA2B,EACjE,OAAO,OAAO,YAA+B;AAC5C,QAAM,YAAY,QAAQ,GAAG;AAC7B,QAAM,aAAa,MAAM,gBAAgB,SAAS;AAElD,MAAI,CAAC,YAAY;AACf,IAAO,MAAM,yBAAyB;AACtC,IAAO,OAAO,oDAAoD;AAClE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,cAAY,UAAU;AAEtB,QAAM,EAAE,cAAc,IAAI,MAAM,OAAO,8BAA8B;AACrE,QAAM,cAAc,YAAY,QAAQ,KAAK;AAC/C,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,iDAAiD,EAC7D,OAAO,2BAA2B,uCAAuC,EACzE,OAAO,uBAAuB,kBAAkB,EAChD,OAAO,yBAAyB,2CAA2C,EAC3E,OAAO,UAAU,gBAAgB,EACjC,OAAO,OAAO,YAAyF;AACtG,QAAM,YAAY,QAAQ,GAAG;AAC7B,QAAM,aAAa,MAAM,gBAAgB,SAAS;AAElD,MAAI,CAAC,YAAY;AACf,IAAO,MAAM,yBAAyB;AACtC,IAAO,OAAO,oDAAoD;AAClE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,cAAY,UAAU;AAEtB,MAAI;AACF,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,sBAAsB;AAC1D,UAAM,SAAS,MAAM,WAAW,YAAY,OAAO;AAEnD,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,KAAK,UAAU,OAAO,QAAQ,MAAM,CAAC,CAAC;AAAA,IACpD,OAAO;AACL,MAAO,OAAO,aAAa,OAAO,cAAc,KAAK,OAAO,cAAc,GAAG;AAC7E,UAAI,OAAO,OAAO,WAAW,GAAG;AAC9B,QAAO,KAAK,iBAAiB;AAAA,MAC/B,OAAO;AACL,mBAAW,SAAS,OAAO,QAAQ;AACjC,gBAAM,SAAS,MAAM,SAAS,GAAG,MAAM,MAAM,MAAM;AACnD,gBAAM,YAAY,MAAM,SAAS,SAAS,GAAG,IAAI,SAAS,IAAI;AAC9D,kBAAQ,IAAI,KAAK,MAAM,GAAG,MAAM,IAAI,GAAG,SAAS,EAAE;AAAA,QACpD;AACA,QAAO,QAAQ;AACf,QAAO,KAAK,GAAG,OAAO,OAAO,MAAM,oBAAoB,OAAO,WAAW,QAAQ,CAAC,CAAC,KAAK;AAAA,MAC1F;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,IAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAC7D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,UAAU,EAClB,YAAY,oCAAoC,EAChD,SAAS,WAAW,wDAAwD,EAC5E,OAAO,2BAA2B,uCAAuC,EACzE,OAAO,UAAU,gBAAgB,EACjC,OAAO,OAAO,OAAe,YAAqD;AACjF,QAAM,YAAY,QAAQ,GAAG;AAC7B,QAAM,aAAa,MAAM,gBAAgB,SAAS;AAElD,MAAI,CAAC,YAAY;AACf,IAAO,MAAM,yBAAyB;AACtC,IAAO,OAAO,oDAAoD;AAClE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,cAAY,UAAU;AAEtB,MAAI;AACF,UAAM,EAAE,cAAc,IAAI,MAAM,OAAO,wBAAwB;AAC/D,UAAM,SAAS,MAAM,cAAc,YAAY,OAAO,OAAO;AAE7D,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,KAAK,UAAU,OAAO,SAAS,MAAM,CAAC,CAAC;AAAA,IACrD,OAAO;AACL,UAAI,OAAO,cAAc;AACvB,QAAO,OAAO,aAAa,OAAO,YAAY,YAAO,OAAO,KAAK,EAAE;AAAA,MACrE;AACA,MAAO,OAAO,GAAG,OAAO,KAAK,KAAK,OAAO,cAAc,GAAG;AAE1D,YAAM,YAAY,KAAK,IAAI,GAAG,GAAG,OAAO,QAAQ,IAAI,CAAC,MAAM,EAAE,KAAK,MAAM,CAAC;AACzE,YAAM,YAAY,KAAK,IAAI,GAAG,GAAG,OAAO,QAAQ,IAAI,CAAC,MAAM,EAAE,KAAK,MAAM,CAAC;AAEzE,cAAQ,IAAI,KAAK,OAAO,OAAO,SAAS,CAAC,KAAK,OAAO,OAAO,SAAS,CAAC,YAAY;AAClF,cAAQ,IAAI,KAAK,SAAI,OAAO,SAAS,CAAC,KAAK,SAAI,OAAO,SAAS,CAAC,KAAK,SAAI,OAAO,CAAC,CAAC,EAAE;AAEpF,iBAAW,OAAO,OAAO,SAAS;AAChC,cAAM,WAAW,IAAI,aAAa,QAAQ,GAAG,IAAI,KAAK,IAAI;AAC1D,gBAAQ,IAAI,KAAK,IAAI,KAAK,OAAO,SAAS,CAAC,KAAK,GAAG,IAAI,IAAI,KAAK,OAAO,SAAS,CAAC,CAAC,KAAK,QAAQ,EAAE;AAAA,MACnG;AAEA,MAAO,QAAQ;AACf,MAAO,KAAK,GAAG,OAAO,QAAQ,MAAM,eAAe,OAAO,WAAW,QAAQ,CAAC,CAAC,KAAK;AAAA,IACtF;AAAA,EACF,SAAS,KAAK;AACZ,IAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAC7D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,OAAO,EACf,YAAY,kCAAkC,EAC9C,SAAS,SAAS,sBAAsB,EACxC,OAAO,2BAA2B,uCAAuC,EACzE,OAAO,UAAU,gBAAgB,EACjC,OAAO,wBAAwB,mCAAmC,EAClE,OAAO,OAAO,KAAa,YAAqE;AAC/F,QAAM,YAAY,QAAQ,GAAG;AAC7B,QAAM,aAAa,MAAM,gBAAgB,SAAS;AAElD,MAAI,CAAC,YAAY;AACf,IAAO,MAAM,yBAAyB;AACtC,IAAO,OAAO,oDAAoD;AAClE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,cAAY,UAAU;AAEtB,MAAI;AACF,UAAM,EAAE,aAAa,IAAI,MAAM,OAAO,qBAAqB;AAC3D,UAAM,EAAE,aAAa,WAAW,IAAI,MAAM,OAAO,gCAAgC;AAEjF,UAAM,QAAQ,QAAQ,QAAQ,SAAS,QAAQ,OAAO,EAAE,IAAI;AAC5D,UAAM,SAAS,MAAM,aAAa,YAAY,KAAK;AAAA,MACjD,YAAY,QAAQ;AAAA,MACpB,MAAM,QAAQ;AAAA,MACd;AAAA,IACF,CAAC;AAED,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,WAAW,MAAM,CAAC;AAAA,IAChC,OAAO;AACL,cAAQ,IAAI,YAAY,MAAM,CAAC;AAAA,IACjC;AAAA,EACF,SAAS,KAAK;AACZ,IAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAC7D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,4CAA4C,EACxD,SAAS,WAAW,8BAA8B,EAClD,OAAO,2BAA2B,uCAAuC,EACzE,OAAO,wBAAwB,2BAA2B,EAC1D,OAAO,UAAU,gBAAgB,EACjC,OAAO,OAAO,OAAe,YAAqE;AACjG,QAAM,YAAY,QAAQ,GAAG;AAC7B,QAAM,aAAa,MAAM,gBAAgB,SAAS;AAElD,MAAI,CAAC,YAAY;AACf,IAAO,MAAM,yBAAyB;AACtC,IAAO,OAAO,oDAAoD;AAClE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,cAAY,UAAU;AAEtB,MAAI;AACF,UAAM,EAAE,YAAY,IAAI,MAAM,OAAO,sBAAsB;AAC3D,UAAM,EAAE,aAAa,WAAW,IAAI,MAAM,OAAO,gCAAgC;AAEjF,UAAM,QAAQ,QAAQ,QAAQ,SAAS,QAAQ,OAAO,EAAE,IAAI;AAC5D,UAAM,SAAS,MAAM,YAAY,YAAY,OAAO;AAAA,MAClD,YAAY,QAAQ;AAAA,MACpB,MAAM,QAAQ;AAAA,MACd;AAAA,IACF,CAAC;AAED,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,WAAW,MAAM,CAAC;AAAA,IAChC,OAAO;AACL,UAAI,OAAO,cAAc;AACvB,QAAO,OAAO,aAAa,OAAO,YAAY,YAAO,OAAO,KAAK,EAAE;AAAA,MACrE;AACA,cAAQ,IAAI,YAAY,MAAM,CAAC;AAAA,IACjC;AAAA,EACF,SAAS,KAAK;AACZ,IAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAC7D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,0CAA0C,EACtD,SAAS,aAAa,uBAAuB,EAC7C,OAAO,2BAA2B,uCAAuC,EACzE,OAAO,UAAU,gBAAgB,EACjC,OAAO,OAAO,SAAiB,YAAqD;AACnF,QAAM,YAAY,QAAQ,GAAG;AAC7B,QAAM,aAAa,MAAM,gBAAgB,SAAS;AAElD,MAAI,CAAC,YAAY;AACf,IAAO,MAAM,yBAAyB;AACtC,IAAO,OAAO,oDAAoD;AAClE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,cAAY,UAAU;AAEtB,MAAI;AACF,UAAM,EAAE,eAAe,IAAI,MAAM,OAAO,sBAAsB;AAC9D,UAAM,SAAS,MAAM,eAAe,YAAY,SAAS,OAAO;AAEhE,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,KAAK,UAAU,OAAO,SAAS,MAAM,CAAC,CAAC;AAAA,IACrD,OAAO;AACL,MAAO,OAAO,uBAAuB,OAAO,OAAO,QAAQ,OAAO,cAAc,KAAK,OAAO,cAAc,GAAG;AAE7G,YAAM,SAAS,OAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO;AAC9D,YAAM,UAAU,OAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,QAAQ;AAEhE,UAAI,OAAO,SAAS,GAAG;AACrB,QAAO,QAAQ;AACf,gBAAQ,IAAI,WAAW;AACvB,mBAAW,KAAK,QAAQ;AACtB,gBAAM,YAAY,EAAE,SAAS,GAAG,EAAE,MAAM,IAAI,EAAE,KAAK,KAAK,EAAE;AAC1D,kBAAQ,IAAI,OAAO,SAAS,EAAE;AAAA,QAChC;AAAA,MACF;AAEA,UAAI,QAAQ,SAAS,GAAG;AACtB,QAAO,QAAQ;AACf,gBAAQ,IAAI,YAAY;AACxB,cAAM,YAAY,KAAK,IAAI,GAAG,QAAQ,IAAI,CAAC,MAAM;AAC/C,gBAAM,YAAY,EAAE,SAAS,GAAG,EAAE,MAAM,IAAI,EAAE,KAAK,IAAI,EAAE,MAAM,KAAK,GAAG,EAAE,KAAK,IAAI,EAAE,MAAM;AAC1F,iBAAO,UAAU;AAAA,QACnB,CAAC,CAAC;AACF,mBAAW,KAAK,SAAS;AACvB,gBAAM,YAAY,EAAE,SAAS,GAAG,EAAE,MAAM,IAAI,EAAE,KAAK,IAAI,EAAE,MAAM,KAAK,GAAG,EAAE,KAAK,IAAI,EAAE,MAAM;AAC1F,gBAAM,UAAU,EAAE,aAAa,GAAG,IAAI,EAAE,UAAU,IAAI;AACtD,kBAAQ,IAAI,OAAO,UAAU,OAAO,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE;AAAA,QAChE;AAAA,MACF;AAEA,UAAI,OAAO,QAAQ,WAAW,GAAG;AAC/B,QAAO,OAAO,kBAAkB;AAAA,MAClC;AAEA,MAAO,QAAQ;AACf,MAAO,KAAK,GAAG,OAAO,QAAQ,MAAM,eAAe,OAAO,WAAW,QAAQ,CAAC,CAAC,KAAK;AAAA,IACtF;AAAA,EACF,SAAS,KAAK;AACZ,IAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAC7D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,gBAAgB,EACxB,YAAY,gDAAgD,EAC5D,OAAO,2BAA2B,uCAAuC,EACzE,OAAO,0BAA0B,iCAAiC,EAClE,OAAO,yBAAyB,yCAAyC,EACzE,OAAO,kBAAkB,4BAA4B,EACrD,OAAO,aAAa,4CAA4C,EAChE,OAAO,UAAU,+CAA+C,EAChE,OAAO,UAAU,6BAA6B,EAC9C,OAAO,OAAO,YAAY;AACzB,QAAM,YAAY,QAAQ,GAAG;AAC7B,QAAM,aAAa,MAAM,gBAAgB,SAAS;AAElD,MAAI,CAAC,YAAY;AACf,IAAO,MAAM,yBAAyB;AACtC,IAAO,OAAO,oDAAoD;AAClE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,cAAY,UAAU;AAEtB,MAAI;AACF,UAAM,EAAE,iBAAiB,IAAI,MAAM,OAAO,8BAA8B;AACxE,UAAM,iBAAiB,YAAY,OAAO;AAAA,EAC5C,SAAS,KAAK;AACZ,IAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAC7D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,SAAS,EACjB,YAAY,wCAAwC,EACpD,SAAS,WAAW,iCAAiC,EACrD,OAAO,eAAe,6CAA6C,EACnE,OAAO,UAAU,gBAAgB,EACjC,OAAO,OAAO,OAAe,YAAgD;AAC5E,QAAM,YAAY,QAAQ,GAAG;AAC7B,QAAM,aAAa,MAAM,gBAAgB,SAAS;AAElD,MAAI,CAAC,YAAY;AACf,IAAO,MAAM,yBAAyB;AACtC,IAAO,OAAO,oDAAoD;AAClE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI;AACF,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,uBAAuB;AAC3D,UAAM,QAAQ,QAAQ,QAAQ,SAAS,QAAQ,OAAO,EAAE,IAAI;AAC5D,UAAM,SAAS,MAAM,WAAW,YAAY,OAAO,EAAE,OAAO,MAAM,QAAQ,KAAK,CAAC;AAEhF,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,KAAK,UAAU,OAAO,MAAM,MAAM,CAAC,CAAC;AAAA,IAClD,OAAO;AACL,cAAQ,IAAI,OAAO,QAAQ;AAAA,IAC7B;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,eAAe,SAAS,IAAI,QAAQ,SAAS,QAAQ,GAAG;AAC1D,MAAO,MAAM,kDAAkD;AAAA,IACjE,OAAO;AACL,MAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IAC/D;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,SAAS,EACjB,YAAY,qFAAgF,EAC5F,SAAS,cAAc,wDAAwD,EAC/E,OAAO,aAAa,sCAAsC,EAC1D,OAAO,UAAU,gBAAgB,EACjC,OAAO,qBAAqB,sCAAsC,EAClE,OAAO,2BAA2B,+CAA+C,EACjF,OAAO,OAAO,UAA8B,YAAqF;AAChI,QAAM,YAAY,QAAQ,GAAG;AAC7B,QAAM,aAAa,MAAM,gBAAgB,SAAS;AAElD,MAAI,CAAC,YAAY;AACf,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,OAAO,OAAO,0BAA0B,CAAC,CAAC;AAAA,IAClF,OAAO;AACL,MAAO,MAAM,yBAAyB;AACtC,MAAO,OAAO,oDAAoD;AAAA,IACpE;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,cAAY,UAAU;AAEtB,QAAM,EAAE,WAAW,IAAI,MAAM,OAAO,uBAAuB;AAC3D,QAAM,WAAW,YAAY,UAAU;AAAA,IACrC,KAAK,QAAQ,MAAM,SAAS,QAAQ,KAAK,EAAE,IAAI;AAAA,IAC/C,MAAM,QAAQ;AAAA,IACd,SAAS,QAAQ;AAAA,IACjB,YAAY,QAAQ;AAAA,EACtB,CAAC;AACH,CAAC;AAEH,IAAM,cAAc,QACjB,QAAQ,UAAU,EAClB,YAAY,4FAAuF,EACnG,OAAO,UAAU,gBAAgB,EACjC,OAAO,OAAO,YAAgC;AAC7C,QAAM,YAAY,QAAQ,GAAG;AAC7B,QAAM,aAAa,MAAM,gBAAgB,SAAS;AAElD,MAAI,CAAC,YAAY;AACf,IAAO,MAAM,yBAAyB;AACtC,IAAO,OAAO,oDAAoD;AAClE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,cAAY,UAAU;AAEtB,MAAI;AACF,UAAM,EAAE,SAAS,IAAI,MAAM,OAAO,aAAa;AAC/C,UAAM,cAAc,KAAK,YAAY,aAAa,cAAc;AAChE,UAAM,cAAc,KAAK,MAAM,MAAM,SAAS,aAAa,OAAO,CAAC;AAEnE,UAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,wBAAwB;AACtE,UAAM,SAAS,qBAAqB,WAAW;AAE/C,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,KAAK,UAAU,OAAO,UAAU,MAAM,CAAC,CAAC;AACpD;AAAA,IACF;AAEA,QAAI,OAAO,SAAS,WAAW,GAAG;AAChC,MAAO,KAAK,6BAA6B;AACzC,MAAO,OAAO,+EAA+E;AAC7F;AAAA,IACF;AAEA,IAAO,OAAO,yBAAoB,OAAO,SAAS,MAAM,WAAW;AAEnE,eAAW,UAAU,OAAO,UAAU;AACpC,cAAQ,IAAI,KAAK,GAAG,KAAK,OAAO,IAAI,CAAC,EAAE;AACvC,cAAQ,IAAI,KAAK,GAAG,IAAI,OAAO,YAAY,CAAC,EAAE;AAC9C,UAAI,OAAO,aAAa;AACtB,gBAAQ,IAAI,KAAK,OAAO,WAAW,EAAE;AAAA,MACvC;AACA,UAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,gBAAQ,IAAI,eAAe,OAAO,SAAS,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,KAAK,GAAG,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,MACrG;AACA,UAAI,OAAO,WAAW,SAAS,GAAG;AAChC,gBAAQ,IAAI,iBAAiB,OAAO,WAAW,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,KAAK,GAAG,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,MACzG;AACA,cAAQ,IAAI;AAAA,IACd;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,eAAe,SAAS,IAAI,QAAQ,SAAS,QAAQ,GAAG;AAC1D,MAAO,MAAM,+EAA+E;AAAA,IAC9F,OAAO;AACL,MAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IAC/D;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,YACG,QAAQ,OAAO,EACf,YAAY,mDAAmD,EAC/D,eAAe,uBAAuB,gCAAgC,EACtE,eAAe,6BAA6B,+BAA+B,EAC3E,OAAO,iCAAiC,iCAAiC,EACzE,OAAO,4BAA4B,mCAAmC,EACtE,OAAO,mBAAmB,gBAAgB,EAC1C,OAAO,UAAU,uCAAuC,EACxD,OAAO,mBAAmB,0BAA0B,EACpD,OAAO,2BAA2B,mBAAmB,EACrD,OAAO,UAAU,gBAAgB,EACjC,OAAO,SAAS,0CAA0C,EAC1D,OAAO,OAAO,YAWT;AACJ,QAAM,YAAY,QAAQ,GAAG;AAC7B,QAAM,aAAa,MAAM,gBAAgB,SAAS;AAElD,MAAI,CAAC,YAAY;AACf,IAAO,MAAM,yBAAyB;AACtC,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,cAAY,UAAU;AAEtB,MAAI;AACF,UAAM,EAAE,SAAS,IAAI,MAAM,OAAO,aAAa;AAC/C,UAAM,cAAc,KAAK,YAAY,aAAa,cAAc;AAChE,UAAM,cAAc,KAAK,MAAM,MAAM,SAAS,aAAa,OAAO,CAAC;AAEnE,UAAM,EAAE,oBAAoB,IAAI,MAAM,OAAO,wBAAwB;AAGrE,UAAM,WAAW,QAAQ,UAAU,CAAC,GAAG,IAAI,CAAC,MAAM;AAChD,YAAM,QAAQ,EAAE,QAAQ,GAAG;AAC3B,UAAI,UAAU,GAAI,OAAM,IAAI,MAAM,2BAA2B,CAAC,wBAAwB;AACtF,aAAO;AAAA,QACL,WAAW,EAAE,MAAM,GAAG,KAAK;AAAA,QAC3B,UAAU;AAAA,QACV,OAAO,EAAE,MAAM,QAAQ,CAAC;AAAA,MAC1B;AAAA,IACF,CAAC;AAED,UAAM,SAAS,oBAAoB,aAAa;AAAA,MAC9C,QAAQ,QAAQ;AAAA,MAChB,UAAU,QAAQ,SAAS,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAAA,MACzD,YAAY,QAAQ,aAAa,QAAQ,WAAW,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC;AAAA,MACvF;AAAA,MACA,UAAU,QAAQ,QAAQ,EAAE,OAAO,QAAQ,OAAO,WAAW,QAAQ,OAAO,SAAS,MAAM,IAAI;AAAA,MAC/F,OAAO,QAAQ,QAAQ,SAAS,QAAQ,OAAO,EAAE,IAAI;AAAA,IACvD,CAAC;AAGD,QAAI,QAAQ,KAAK;AACf,cAAQ,IAAI,OAAO,GAAG;AACtB;AAAA,IACF;AAGA,UAAM,EAAE,mBAAmB,iBAAiB,aAAa,WAAW,IAAI,MAAM,OAAO,gCAAgC;AACrH,UAAM,aAAa,MAAM,kBAAkB,YAAY,QAAQ,UAAU;AACzE,UAAM,YAAY,gBAAgB,YAAY,UAAU;AAExD,UAAM,QAAQ,YAAY,IAAI;AAC9B,UAAM,UAAU,QAAQ;AACxB,UAAM,cAAc,MAAM,UAAU,QAAQ,OAAO,GAAG;AACtD,UAAM,UAAU,WAAW;AAC3B,UAAM,aAAa,KAAK,OAAO,YAAY,IAAI,IAAI,SAAS,GAAG,IAAI;AAEnE,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,WAAW;AAAA,QACrB,SAAS,YAAY;AAAA,QACrB,MAAM,YAAY;AAAA,QAClB,UAAU,YAAY,KAAK;AAAA,QAC3B;AAAA,MACF,CAAC,CAAC;AAAA,IACJ,OAAO;AACL,MAAO,OAAO,WAAW,OAAO,UAAU,EAAE;AAC5C,MAAO,OAAO,QAAQ,OAAO,IAAI,QAAQ,OAAO,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,KAAK;AACvE,MAAO,QAAQ;AACf,cAAQ,IAAI,YAAY;AAAA,QACtB,SAAS,YAAY;AAAA,QACrB,MAAM,YAAY;AAAA,QAClB,UAAU,YAAY,KAAK;AAAA,QAC3B;AAAA,MACF,CAAC,CAAC;AAAA,IACJ;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,eAAe,SAAS,IAAI,QAAQ,SAAS,QAAQ,GAAG;AAC1D,MAAO,MAAM,+EAA+E;AAAA,IAC9F,OAAO;AACL,MAAO,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IAC/D;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QAAQ,MAAM;AAGd,IAAI,qBAAoC;AAExC,eAAe,IAAI,OAAO,EAAE,KAAK,CAAC,WAAW;AAC3C,MAAI,QAAQ;AACV,yBAAqB;AAAA,sBAAyB,OAAO,OAAO,WAAM,OAAO,MAAM;AAAA;AAAA;AAAA,EACjF;AACF,CAAC;AAED,QAAQ,GAAG,QAAQ,MAAM;AACvB,MAAI,oBAAoB;AAEtB,YAAQ,MAAM;AAAA,EAAK,GAAG,IAAI,kBAAkB,CAAC,EAAE;AAAA,EACjD;AACF,CAAC;","names":["error","warning"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { resolve, basename, dirname, join } from 'path';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { validateProject } from './commands/validate.js';\nimport { findProjectRoot, loadEnvFile } from './utils/config.js';\nimport pc from 'picocolors';\nimport * as output from './utils/output.js';\nimport { checkForUpdate } from './utils/update-check.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));\n\nconst program = new Command();\n\nprogram\n .name('yamchart')\n .description('Git-native business intelligence dashboards')\n .version(pkg.version);\n\nprogram\n .command('validate')\n .description('Validate configuration files')\n .argument('[path]', 'Path to yamchart project', '.')\n .option('--dry-run', 'Connect to database and test queries with EXPLAIN')\n .option('-c, --connection <name>', 'Connection to use for dry-run')\n .option('--json', 'Output as JSON')\n .action(async (path: string, options: { dryRun?: boolean; connection?: string; json?: boolean }) => {\n const startPath = resolve(path);\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: 'yamchart.yaml not found' }));\n } else {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n }\n process.exit(2);\n }\n\n // Load .env file\n loadEnvFile(projectDir);\n\n if (!options.json) {\n output.header('Validating yamchart project...');\n }\n\n const result = await validateProject(projectDir, {\n dryRun: options.dryRun ?? false,\n connection: options.connection,\n });\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n // Print results\n for (const error of result.errors) {\n output.error(error.file);\n output.detail(error.message);\n if (error.suggestion) {\n output.detail(error.suggestion);\n }\n }\n\n for (const warning of result.warnings) {\n output.warning(warning.file);\n output.detail(warning.message);\n }\n\n output.newline();\n\n if (result.success) {\n output.success(`Schema: ${result.stats.passed} passed`);\n } else {\n output.error(`Schema: ${result.stats.passed} passed, ${result.stats.failed} failed`);\n }\n\n if (result.dryRunStats) {\n output.newline();\n if (result.dryRunStats.failed === 0) {\n output.success(`Queries: ${result.dryRunStats.passed} passed (EXPLAIN OK)`);\n } else {\n output.error(`Queries: ${result.dryRunStats.passed} passed, ${result.dryRunStats.failed} failed`);\n }\n }\n\n output.newline();\n\n if (result.success) {\n output.success('Validation passed');\n } else {\n output.error(`Validation failed with ${result.errors.length} error(s)`);\n }\n }\n\n process.exit(result.success ? 0 : 1);\n });\n\nprogram\n .command('dev')\n .description('Start development server with hot reload')\n .argument('[path]', 'Path to yamchart project', '.')\n .option('-p, --port <number>', 'Port to listen on', '3001')\n .option('--api-only', 'Only serve API, no web UI')\n .option('--no-open', 'Do not open browser automatically')\n .action(async (path: string, options: { port: string; apiOnly?: boolean; open: boolean }) => {\n const startPath = resolve(path);\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n const { runDevServer } = await import('./commands/dev.js');\n\n await runDevServer(projectDir, {\n port: parseInt(options.port, 10),\n apiOnly: options.apiOnly ?? false,\n open: options.open,\n version: pkg.version,\n });\n });\n\nprogram\n .command('init')\n .description('Create a new yamchart project')\n .argument('[directory]', 'Target directory', '.')\n .option('--example', 'Create full example project with sample database')\n .option('--empty', 'Create only yamchart.yaml (no connections, models, or charts)')\n .option('--force', 'Overwrite existing files')\n .action(async (directory: string, options: { example?: boolean; empty?: boolean; force?: boolean }) => {\n const { initProject } = await import('./commands/init.js');\n const targetDir = resolve(directory);\n\n const result = await initProject(targetDir, options);\n\n if (!result.success) {\n output.error(result.error || 'Failed to create project');\n process.exit(1);\n }\n\n output.newline();\n output.success(`Created ${directory === '.' ? basename(targetDir) : directory}/`);\n for (const file of result.files.slice(0, 10)) {\n output.detail(file);\n }\n if (result.files.length > 10) {\n output.detail(`... and ${result.files.length - 10} more files`);\n }\n output.newline();\n output.info(`Run \\`cd ${directory === '.' ? basename(targetDir) : directory} && yamchart dev\\` to start.`);\n });\n\nprogram\n .command('sync-dbt')\n .description('Sync dbt project metadata into AI-readable catalog')\n .option('-s, --source <type>', 'Source type: local, github, dbt-cloud', 'local')\n .option('-p, --path <dir>', 'Path to dbt project (for local source)')\n .option('--repo <repo>', 'GitHub repository (for github source)')\n .option('--branch <branch>', 'Git branch (for github source)', 'main')\n .option('-i, --include <patterns...>', 'Include glob patterns')\n .option('-e, --exclude <patterns...>', 'Exclude glob patterns')\n .option('-t, --tag <tags...>', 'Filter by dbt tags')\n .option('--refresh', 'Re-sync using saved configuration')\n .option('--target-database <database>', 'Override database in ref() paths (e.g. switch from dev to prod)')\n .action(async (options: {\n source: 'local' | 'github' | 'dbt-cloud';\n path?: string;\n repo?: string;\n branch?: string;\n include?: string[];\n exclude?: string[];\n tag?: string[];\n refresh?: boolean;\n targetDatabase?: string;\n }) => {\n const { syncDbt, loadSyncConfig } = await import('./commands/sync-dbt.js');\n\n // Find project root\n const projectDir = await findProjectRoot(process.cwd());\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n // Handle refresh mode\n if (options.refresh) {\n const savedConfig = await loadSyncConfig(projectDir);\n if (!savedConfig) {\n output.error('No saved sync config found');\n output.detail('Run sync-dbt without --refresh first');\n process.exit(1);\n }\n output.info(`Re-syncing from ${savedConfig.source}:${savedConfig.path || savedConfig.repo}`);\n }\n\n const spin = output.spinner('Syncing dbt metadata...');\n\n const result = await syncDbt(projectDir, {\n source: options.source,\n path: options.path,\n repo: options.repo,\n branch: options.branch,\n include: options.include || [],\n exclude: options.exclude || [],\n tags: options.tag || [],\n refresh: options.refresh,\n targetDatabase: options.targetDatabase,\n });\n\n spin.stop();\n\n if (!result.success) {\n output.error(result.error || 'Sync failed');\n process.exit(1);\n }\n\n output.success(`Synced ${result.modelsIncluded} models to .yamchart/catalog.md`);\n if (result.modelsExcluded > 0) {\n output.detail(`${result.modelsExcluded} models filtered out`);\n }\n\n // Show lineage warnings\n if (result.warnings) {\n for (const w of result.warnings) {\n output.warning(w);\n }\n }\n\n // Check for database mismatch (skip if --target-database was used)\n if (!options.targetDatabase) {\n try {\n const { readFile } = await import('fs/promises');\n const { resolveConnection } = await import('./commands/connection-utils.js');\n const { detectDatabaseMismatch } = await import('./dbt/rewrite-database.js');\n const catalogJsonStr = await readFile(join(projectDir, '.yamchart', 'catalog.json'), 'utf-8');\n const catalogData = JSON.parse(catalogJsonStr);\n const connection = await resolveConnection(projectDir);\n // Extract database from connection config (varies by type)\n const connDb = (connection as Record<string, any>).config?.database as string | undefined;\n const mismatch = detectDatabaseMismatch(catalogData.models, connDb);\n if (mismatch.mismatch) {\n output.warning(\n `Catalog tables reference database \"${mismatch.catalogDatabase}\" but your default ` +\n `connection uses \"${mismatch.connectionDatabase}\". Models using ref() may query the wrong database.`\n );\n output.detail(\n `To fix: yamchart sync-dbt --refresh --target-database ${mismatch.connectionDatabase}`\n );\n }\n } catch {\n // Connection not configured or unreadable — skip silently\n }\n }\n });\n\nprogram\n .command('generate')\n .description('Generate SQL model stubs from dbt catalog')\n .argument('[model]', 'Specific model to generate (optional)')\n .option('--yolo', 'Skip all prompts, use defaults for everything')\n .action(async (model: string | undefined, options: { yolo?: boolean }) => {\n const { generate } = await import('./commands/generate.js');\n\n const projectDir = await findProjectRoot(process.cwd());\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n const result = await generate(projectDir, {\n model,\n yolo: options.yolo,\n });\n\n if (!result.success) {\n output.error(result.error || 'Generate failed');\n process.exit(1);\n }\n\n output.success(`Generated ${result.filesCreated} model stubs`);\n if (result.filesSkipped > 0) {\n output.detail(`${result.filesSkipped} files skipped`);\n }\n });\n\nprogram\n .command('test')\n .description('Run model tests (@returns schema checks and @tests data assertions)')\n .argument('[model]', 'Specific model to test (optional, tests all if omitted)')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('--json', 'Output as JSON')\n .action(async (model: string | undefined, options: { connection?: string; json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: 'yamchart.yaml not found' }));\n } else {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n }\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { testProject, formatTestOutput } = await import('./commands/test.js');\n const result = await testProject(projectDir, model, {\n connection: options.connection,\n json: options.json,\n });\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n formatTestOutput(result, result.connectionName);\n }\n\n process.exit(result.success ? 0 : 1);\n } catch (err) {\n if (options.json) {\n console.log(\n JSON.stringify({ success: false, error: err instanceof Error ? err.message : String(err) }),\n );\n } else {\n output.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(2);\n }\n });\n\nprogram\n .command('update')\n .description('Check for yamchart updates')\n .action(async () => {\n const { runUpdate } = await import('./commands/update.js');\n await runUpdate(pkg.version);\n });\n\nprogram\n .command('reset-password')\n .description('Reset a user password (requires auth to be enabled)')\n .requiredOption('-e, --email <email>', 'Email address of the user')\n .action(async (options: { email: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n const { resetPassword } = await import('./commands/reset-password.js');\n await resetPassword(projectDir, options.email);\n });\n\nprogram\n .command('tables')\n .description('List tables and views in the connected database')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('-s, --schema <name>', 'Filter to schema')\n .option('-d, --database <name>', 'Filter to database (Snowflake/Databricks)')\n .option('--json', 'Output as JSON')\n .option('--source <type>', 'Data source: auto, catalog, model, or db (default: auto)')\n .option('--compare', 'Compare local metadata against live database')\n .action(async (options: { connection?: string; schema?: string; database?: string; json?: boolean; source?: string; compare?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n if (options.compare) {\n const { resolveTablesSource } = await import('./commands/source-resolver.js');\n const { compareTables, formatCompareTables } = await import('./commands/compare.js');\n\n let localResult;\n try {\n localResult = await resolveTablesSource(projectDir, 'catalog', options.connection, {\n schema: options.schema,\n database: options.database,\n });\n } catch {\n try {\n localResult = await resolveTablesSource(projectDir, 'model', options.connection, {\n schema: options.schema,\n database: options.database,\n });\n } catch {\n output.error('Cannot compare — no local metadata found. Run `yamchart sync-dbt` or `yamchart sync-warehouse` first.');\n process.exit(1);\n }\n }\n\n const dbResult = await resolveTablesSource(projectDir, 'db', options.connection, {\n schema: options.schema,\n database: options.database,\n });\n const diffs = compareTables(localResult.tables, dbResult.tables);\n\n if (options.json) {\n console.log(JSON.stringify(diffs, null, 2));\n } else {\n console.log(formatCompareTables(localResult.source, diffs));\n }\n return;\n }\n\n const { listTables } = await import('./commands/tables.js');\n const result = await listTables(projectDir, {\n ...options,\n source: (options.source as any) || 'auto',\n });\n\n if (options.json) {\n console.log(JSON.stringify(result.tables, null, 2));\n } else {\n const sourceLabel = result.source === 'db'\n ? `${result.connectionName} (${result.connectionType})`\n : `Source: ${result.source}`;\n output.header(`Tables in ${sourceLabel}`);\n if (result.tables.length === 0) {\n output.info('No tables found');\n } else {\n for (const table of result.tables) {\n const schema = table.schema ? `${table.schema}.` : '';\n const typeLabel = table.type === 'VIEW' ? pc.dim(' (view)') : '';\n console.log(` ${schema}${table.name}${typeLabel}`);\n }\n output.newline();\n output.info(`${result.tables.length} table(s) found${result.durationMs > 0 ? ` (${result.durationMs.toFixed(0)}ms)` : ''}`);\n }\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('describe')\n .description('Show columns and types for a table')\n .argument('<table>', 'Table name (can be fully qualified, e.g. schema.table)')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('--json', 'Output as JSON')\n .option('--source <type>', 'Data source: auto, catalog, model, or db (default: auto)')\n .option('--compare', 'Compare local metadata against live database')\n .action(async (table: string, options: { connection?: string; json?: boolean; source?: string; compare?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n if (options.compare) {\n const { resolveDescribeSource } = await import('./commands/source-resolver.js');\n const { compareColumns, formatCompareColumns } = await import('./commands/compare.js');\n\n let localResult;\n try {\n localResult = await resolveDescribeSource(projectDir, table, 'catalog', options.connection);\n } catch {\n try {\n localResult = await resolveDescribeSource(projectDir, table, 'model', options.connection);\n } catch {\n output.error('Cannot compare — no local metadata found. Run `yamchart sync-dbt` or `yamchart sync-warehouse` first.');\n process.exit(1);\n }\n }\n\n const dbResult = await resolveDescribeSource(projectDir, table, 'db', options.connection);\n const diffs = compareColumns(localResult.columns, dbResult.columns);\n\n if (options.json) {\n console.log(JSON.stringify(diffs, null, 2));\n } else {\n console.log(formatCompareColumns(localResult.table, localResult.source, diffs));\n }\n return;\n }\n\n const { describeTable } = await import('./commands/describe.js');\n const result = await describeTable(projectDir, table, {\n ...options,\n source: (options.source as any) || 'auto',\n });\n\n if (options.json) {\n console.log(JSON.stringify(result.columns, null, 2));\n } else {\n if (result.resolvedFrom) {\n output.detail(`Resolved \"${result.resolvedFrom}\" → ${result.table}`);\n }\n const sourceLabel = result.source === 'db'\n ? `${result.connectionName} (${result.connectionType})`\n : `Source: ${result.source}`;\n output.header(`${result.table} (${sourceLabel})`);\n\n const nameWidth = Math.max(4, ...result.columns.map((c) => c.name.length));\n const typeWidth = Math.max(4, ...result.columns.map((c) => c.type.length));\n\n console.log(` ${'name'.padEnd(nameWidth)} ${'type'.padEnd(typeWidth)} nullable`);\n console.log(` ${'─'.repeat(nameWidth)} ${'─'.repeat(typeWidth)} ${'─'.repeat(8)}`);\n\n for (const col of result.columns) {\n const nullable = col.nullable === 'YES' ? pc.dim('yes') : 'no';\n console.log(` ${col.name.padEnd(nameWidth)} ${pc.dim(col.type.padEnd(typeWidth))} ${nullable}`);\n }\n\n output.newline();\n output.info(`${result.columns.length} column(s)${result.durationMs > 0 ? ` (${result.durationMs.toFixed(0)}ms)` : ''}`);\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('query')\n .description('Execute SQL against a connection')\n .argument('<sql>', 'SQL query to execute')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('--json', 'Output as JSON')\n .option('-l, --limit <number>', 'Max rows to return (default: 100)')\n .action(async (sql: string, options: { connection?: string; json?: boolean; limit?: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { executeQuery } = await import('./commands/query.js');\n const { formatTable, formatJSON } = await import('./commands/connection-utils.js');\n\n const limit = options.limit ? parseInt(options.limit, 10) : undefined;\n const result = await executeQuery(projectDir, sql, {\n connection: options.connection,\n json: options.json,\n limit,\n });\n\n if (options.json) {\n console.log(formatJSON(result));\n } else {\n console.log(formatTable(result));\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('sample')\n .description('Show sample rows from a table or dbt model')\n .argument('<table>', 'Table name or dbt model name')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('-l, --limit <number>', 'Rows to show (default: 5)')\n .option('--json', 'Output as JSON')\n .action(async (table: string, options: { connection?: string; json?: boolean; limit?: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { sampleTable } = await import('./commands/sample.js');\n const { formatTable, formatJSON } = await import('./commands/connection-utils.js');\n\n const limit = options.limit ? parseInt(options.limit, 10) : undefined;\n const result = await sampleTable(projectDir, table, {\n connection: options.connection,\n json: options.json,\n limit,\n });\n\n if (options.json) {\n console.log(formatJSON(result));\n } else {\n if (result.resolvedFrom) {\n output.detail(`Resolved \"${result.resolvedFrom}\" → ${result.table}`);\n }\n console.log(formatTable(result));\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('search')\n .description('Search for tables and columns by keyword')\n .argument('<keyword>', 'Keyword to search for')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('--json', 'Output as JSON')\n .option('--source <type>', 'Data source: auto, catalog, model, or db (default: auto)')\n .action(async (keyword: string, options: { connection?: string; json?: boolean; source?: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { searchDatabase } = await import('./commands/search.js');\n const result = await searchDatabase(projectDir, keyword, {\n ...options,\n source: (options.source as any) || 'auto',\n });\n\n if (options.json) {\n console.log(JSON.stringify(result.results, null, 2));\n } else {\n const sourceLabel = result.source === 'db'\n ? `${result.connectionName} (${result.connectionType})`\n : `Source: ${result.source}`;\n output.header(`Search results for \"${result.keyword}\" in ${sourceLabel}`);\n\n const tables = result.results.filter((r) => r.type === 'table');\n const columns = result.results.filter((r) => r.type === 'column');\n\n if (tables.length > 0) {\n output.newline();\n console.log(' Tables:');\n for (const t of tables) {\n const qualified = t.schema ? `${t.schema}.${t.table}` : t.table;\n console.log(` ${qualified}`);\n }\n }\n\n if (columns.length > 0) {\n output.newline();\n console.log(' Columns:');\n const nameWidth = Math.max(...columns.map((c) => {\n const qualified = c.schema ? `${c.schema}.${c.table}.${c.column}` : `${c.table}.${c.column}`;\n return qualified.length;\n }));\n for (const c of columns) {\n const qualified = c.schema ? `${c.schema}.${c.table}.${c.column}` : `${c.table}.${c.column}`;\n const colType = c.columnType ? pc.dim(c.columnType) : '';\n console.log(` ${qualified.padEnd(nameWidth + 2)}${colType}`);\n }\n }\n\n if (result.results.length === 0) {\n output.detail('No matches found');\n }\n\n output.newline();\n output.info(`${result.results.length} result(s)${result.durationMs > 0 ? ` (${result.durationMs.toFixed(0)}ms)` : ''}`);\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nconst catalogCmd = program\n .command('catalog')\n .description('Explore cached local metadata (no database connection needed)');\n\ncatalogCmd\n .command('tables')\n .description('List tables from cached catalog')\n .option('-s, --schema <name>', 'Filter to schema')\n .option('--json', 'Output as JSON')\n .action(async (options: { schema?: string; json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n try {\n const { listTables } = await import('./commands/tables.js');\n const result = await listTables(projectDir, {\n source: 'catalog',\n schema: options.schema,\n });\n\n if (options.json) {\n console.log(JSON.stringify(result.tables, null, 2));\n } else {\n output.header('Tables (from catalog)');\n if (result.tables.length === 0) {\n output.info('No tables found in catalog');\n output.detail('Run `yamchart sync-warehouse` or `yamchart sync-dbt` to populate');\n } else {\n const filtered = options.schema\n ? result.tables.filter((t) => t.schema.toLowerCase().includes(options.schema!.toLowerCase()))\n : result.tables;\n for (const table of filtered) {\n const schema = table.schema ? `${table.schema}.` : '';\n const typeLabel = table.type === 'VIEW' ? pc.dim(' (view)') : table.type === 'SOURCE' ? pc.dim(' (source)') : '';\n console.log(` ${schema}${table.name}${typeLabel}`);\n }\n output.newline();\n output.info(`${filtered.length} table(s) from catalog`);\n }\n }\n } catch (err) {\n if (err instanceof Error && err.message.includes('No catalog found')) {\n output.error('No catalog found');\n output.detail('Run `yamchart sync-warehouse` or `yamchart sync-dbt` to populate');\n } else {\n output.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(1);\n }\n });\n\ncatalogCmd\n .command('describe')\n .description('Show cached columns and types for a table')\n .argument('<table>', 'Table name or model name')\n .option('--json', 'Output as JSON')\n .action(async (table: string, options: { json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n try {\n const { describeTable } = await import('./commands/describe.js');\n const result = await describeTable(projectDir, table, { source: 'catalog' });\n\n if (options.json) {\n console.log(JSON.stringify(result.columns, null, 2));\n } else {\n if (result.resolvedFrom) {\n output.detail(`Resolved \"${result.resolvedFrom}\" → ${result.table}`);\n }\n output.header(`${result.table} (from catalog)`);\n\n const nameWidth = Math.max(4, ...result.columns.map((c) => c.name.length));\n const typeWidth = Math.max(4, ...result.columns.map((c) => c.type.length));\n\n console.log(` ${'name'.padEnd(nameWidth)} ${'type'.padEnd(typeWidth)} nullable`);\n console.log(` ${'─'.repeat(nameWidth)} ${'─'.repeat(typeWidth)} ${'─'.repeat(8)}`);\n\n for (const col of result.columns) {\n const nullable = col.nullable === 'YES' ? pc.dim('yes') : 'no';\n console.log(` ${col.name.padEnd(nameWidth)} ${pc.dim(col.type.padEnd(typeWidth))} ${nullable}`);\n }\n\n output.newline();\n output.info(`${result.columns.length} column(s)`);\n }\n } catch (err) {\n if (err instanceof Error && err.message.includes('No catalog found')) {\n output.error('No catalog found');\n output.detail('Run `yamchart sync-warehouse` or `yamchart sync-dbt` to populate');\n } else if (err instanceof Error && err.message.includes('not found in catalog')) {\n output.error(err.message);\n output.detail('Try `yamchart catalog search` to find available tables');\n } else {\n output.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(1);\n }\n });\n\ncatalogCmd\n .command('search')\n .description('Search cached metadata for tables and columns')\n .argument('<keyword>', 'Keyword to search for')\n .option('--json', 'Output as JSON')\n .action(async (keyword: string, options: { json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n try {\n const { searchDatabase } = await import('./commands/search.js');\n const result = await searchDatabase(projectDir, keyword, { source: 'catalog' });\n\n if (options.json) {\n console.log(JSON.stringify(result.results, null, 2));\n } else {\n output.header(`Search results for \"${keyword}\" (from catalog)`);\n\n const tables = result.results.filter((r) => r.type === 'table');\n const columns = result.results.filter((r) => r.type === 'column');\n\n if (tables.length > 0) {\n output.newline();\n console.log(' Tables:');\n for (const t of tables) {\n const qualified = t.schema ? `${t.schema}.${t.table}` : t.table;\n console.log(` ${qualified}`);\n }\n }\n\n if (columns.length > 0) {\n output.newline();\n console.log(' Columns:');\n const nameWidth = Math.max(...columns.map((c) => {\n const qualified = c.schema ? `${c.schema}.${c.table}.${c.column}` : `${c.table}.${c.column}`;\n return qualified.length;\n }));\n for (const c of columns) {\n const qualified = c.schema ? `${c.schema}.${c.table}.${c.column}` : `${c.table}.${c.column}`;\n const colType = c.columnType ? pc.dim(c.columnType) : '';\n console.log(` ${qualified.padEnd(nameWidth + 2)}${colType}`);\n }\n }\n\n if (result.results.length === 0) {\n output.detail('No matches found in catalog');\n output.detail('Try `yamchart search <keyword>` to search the live database');\n }\n\n output.newline();\n output.info(`${result.results.length} result(s) from catalog`);\n }\n } catch (err) {\n if (err instanceof Error && err.message.includes('No catalog found')) {\n output.error('No catalog found');\n output.detail('Run `yamchart sync-warehouse` or `yamchart sync-dbt` to populate');\n } else {\n output.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(1);\n }\n });\n\ncatalogCmd\n .command('status')\n .description('Show catalog sync status')\n .option('--json', 'Output as JSON')\n .action(async (options: { json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n try {\n const { readFile } = await import('fs/promises');\n const catalogPath = join(projectDir, '.yamchart', 'catalog.json');\n\n let catalogData: { syncedAt?: string; source?: { type: string }; models?: Array<{ source?: string; columns?: unknown[] }> };\n try {\n catalogData = JSON.parse(await readFile(catalogPath, 'utf-8'));\n } catch {\n if (options.json) {\n console.log(JSON.stringify({ exists: false }));\n } else {\n output.error('No catalog found');\n output.detail('Run `yamchart sync-warehouse` or `yamchart sync-dbt` to populate');\n }\n process.exit(1);\n return;\n }\n\n const models = catalogData.models || [];\n const dbtModels = models.filter((m) => m.source === 'dbt');\n const warehouseModels = models.filter((m) => m.source === 'warehouse');\n const sourceModels = models.filter((m) => m.source === 'dbt-source');\n const totalColumns = models.reduce((sum, m) => sum + (m.columns?.length || 0), 0);\n\n // Try to load warehouse sync state\n let syncState: { syncedAt?: string; connection?: string; schemas?: string[] } | null = null;\n try {\n const syncPath = join(projectDir, '.yamchart', 'warehouse-sync.json');\n syncState = JSON.parse(await readFile(syncPath, 'utf-8'));\n } catch {\n // No sync state\n }\n\n if (options.json) {\n console.log(JSON.stringify({\n exists: true,\n syncedAt: catalogData.syncedAt,\n source: catalogData.source,\n models: models.length,\n dbtModels: dbtModels.length,\n warehouseModels: warehouseModels.length,\n sourceModels: sourceModels.length,\n totalColumns,\n warehouseSync: syncState ? {\n syncedAt: syncState.syncedAt,\n connection: syncState.connection,\n schemas: syncState.schemas,\n } : null,\n }, null, 2));\n } else {\n output.header('Catalog Status');\n console.log(` Last synced: ${catalogData.syncedAt || 'unknown'}`);\n console.log(` Models: ${models.length} total (${dbtModels.length} dbt, ${warehouseModels.length} warehouse, ${sourceModels.length} sources)`);\n console.log(` Columns: ${totalColumns}`);\n\n if (syncState) {\n output.newline();\n console.log(` Warehouse sync:`);\n console.log(` Connection: ${syncState.connection || 'default'}`);\n console.log(` Schemas: ${syncState.schemas?.join(', ') || 'all'}`);\n console.log(` Last sync: ${syncState.syncedAt || 'unknown'}`);\n }\n }\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('sync-warehouse')\n .description('Sync warehouse table metadata into the catalog')\n .option('-c, --connection <name>', 'Connection to use (overrides default)')\n .option('-s, --schema <schemas>', 'Comma-separated schemas to sync')\n .option('-d, --database <name>', 'Database to sync (Snowflake/Databricks)')\n .option('--skip-samples', 'Skip sample row collection')\n .option('--refresh', 'Re-run with saved connection/schema config')\n .option('--full', 'Force full re-sync (ignore incremental state)')\n .option('--json', 'Output sync summary as JSON')\n .action(async (options) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { runSyncWarehouse } = await import('./commands/sync-warehouse.js');\n await runSyncWarehouse(projectDir, options);\n } catch (err) {\n output.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nprogram\n .command('lineage')\n .description('Show upstream dependencies for a model')\n .argument('<model>', 'Model name to trace lineage for')\n .option('--depth <n>', 'Maximum depth to trace (default: unlimited)')\n .option('--json', 'Output as JSON')\n .option('--source <type>', 'Data source: auto, catalog, model, or db (default: auto)')\n .action(async (model: string, options: { depth?: string; json?: boolean; source?: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { getLineage } = await import('./commands/lineage.js');\n const depth = options.depth ? parseInt(options.depth, 10) : undefined;\n const result = await getLineage(projectDir, model, {\n depth,\n json: options.json,\n source: (options.source as any) || 'auto',\n });\n\n if (options.json) {\n console.log(JSON.stringify(result.tree, null, 2));\n } else {\n console.log(result.rendered);\n }\n } catch (err) {\n if (err instanceof Error && err.message.includes('ENOENT')) {\n output.error('No catalog found. Run `yamchart sync-dbt` first.');\n } else {\n output.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(1);\n }\n });\n\nprogram\n .command('advisor')\n .description('AI-powered dbt model advisor — suggests improvements informed by your BI layer')\n .argument('[question]', 'Question to ask, or \"audit\" for comprehensive analysis')\n .option('--top <n>', 'Limit audit suggestions (default: 5)')\n .option('--json', 'Output as JSON')\n .option('--dbt-path <path>', 'Override the synced dbt project path')\n .option('-c, --connection <name>', 'Connection to use for warehouse introspection')\n .action(async (question: string | undefined, options: { top?: string; json?: boolean; dbtPath?: string; connection?: string }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: 'yamchart.yaml not found' }));\n } else {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n }\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n const { runAdvisor } = await import('./commands/advisor.js');\n await runAdvisor(projectDir, question, {\n top: options.top ? parseInt(options.top, 10) : 5,\n json: options.json,\n dbtPath: options.dbtPath,\n connection: options.connection,\n });\n });\n\nconst semanticCmd = program\n .command('semantic')\n .description('Explore the semantic layer — auto-generated measures and dimensions from your catalog')\n .option('--json', 'Output as JSON')\n .action(async (options: { json?: boolean }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n output.detail('Run this command from a yamchart project directory');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { readFile } = await import('fs/promises');\n const catalogPath = join(projectDir, '.yamchart', 'catalog.json');\n const catalogJson = JSON.parse(await readFile(catalogPath, 'utf-8'));\n\n const { listSemanticEntities } = await import('./commands/semantic.js');\n const result = listSemanticEntities(catalogJson);\n\n if (options.json) {\n console.log(JSON.stringify(result.entities, null, 2));\n return;\n }\n\n if (result.entities.length === 0) {\n output.info('No semantic entities found.');\n output.detail('Run `yamchart sync-dbt` or `yamchart sync-warehouse` to populate the catalog.');\n return;\n }\n\n output.header(`Semantic Layer — ${result.entities.length} entities`);\n\n for (const entity of result.entities) {\n console.log(` ${pc.bold(entity.name)}`);\n console.log(` ${pc.dim(entity.source_table)}`);\n if (entity.description) {\n console.log(` ${entity.description}`);\n }\n if (entity.measures.length > 0) {\n console.log(` Measures: ${entity.measures.map((m) => `${m.name} (${pc.dim(m.type)})`).join(', ')}`);\n }\n if (entity.dimensions.length > 0) {\n console.log(` Dimensions: ${entity.dimensions.map((d) => `${d.name} (${pc.dim(d.type)})`).join(', ')}`);\n }\n console.log();\n }\n } catch (err) {\n if (err instanceof Error && err.message.includes('ENOENT')) {\n output.error('No catalog found. Run `yamchart sync-dbt` or `yamchart sync-warehouse` first.');\n } else {\n output.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(1);\n }\n });\n\nsemanticCmd\n .command('query')\n .description('Run a structured query against the semantic layer')\n .requiredOption('-e, --entity <name>', 'Entity name (e.g. fct_revenue)')\n .requiredOption('-m, --measures <measures>', 'Comma-separated measure names')\n .option('-d, --dimensions <dimensions>', 'Comma-separated dimension names')\n .option('-f, --filter <filter...>', 'Filters in format dimension=value')\n .option('--order <field>', 'Order by field')\n .option('--desc', 'Order descending (default: ascending)')\n .option('-l, --limit <n>', 'Row limit (default: 100)')\n .option('-c, --connection <name>', 'Connection to use')\n .option('--json', 'Output as JSON')\n .option('--sql', 'Print compiled SQL only (do not execute)')\n .action(async (options: {\n entity: string;\n measures: string;\n dimensions?: string;\n filter?: string[];\n order?: string;\n desc?: boolean;\n limit?: string;\n connection?: string;\n json?: boolean;\n sql?: boolean;\n }) => {\n const startPath = resolve('.');\n const projectDir = await findProjectRoot(startPath);\n\n if (!projectDir) {\n output.error('yamchart.yaml not found');\n process.exit(2);\n }\n\n loadEnvFile(projectDir);\n\n try {\n const { readFile } = await import('fs/promises');\n const catalogPath = join(projectDir, '.yamchart', 'catalog.json');\n const catalogJson = JSON.parse(await readFile(catalogPath, 'utf-8'));\n\n const { querySemanticEntity } = await import('./commands/semantic.js');\n\n // Parse filters: \"region=US\" → { dimension: 'region', operator: 'equals', value: 'US' }\n const filters = (options.filter || []).map((f) => {\n const eqIdx = f.indexOf('=');\n if (eqIdx === -1) throw new Error(`Invalid filter format: \"${f}\". Use dimension=value`);\n return {\n dimension: f.slice(0, eqIdx),\n operator: 'equals' as const,\n value: f.slice(eqIdx + 1),\n };\n });\n\n const result = querySemanticEntity(catalogJson, {\n entity: options.entity,\n measures: options.measures.split(',').map((s) => s.trim()),\n dimensions: options.dimensions ? options.dimensions.split(',').map((s) => s.trim()) : [],\n filters,\n order_by: options.order ? { field: options.order, direction: options.desc ? 'desc' : 'asc' } : undefined,\n limit: options.limit ? parseInt(options.limit, 10) : 100,\n });\n\n // --sql: just print the SQL\n if (options.sql) {\n console.log(result.sql);\n return;\n }\n\n // Execute the query\n const { resolveConnection, createConnector, formatTable, formatJSON } = await import('./commands/connection-utils.js');\n const connection = await resolveConnection(projectDir, options.connection);\n const connector = createConnector(connection, projectDir);\n\n const start = performance.now();\n await connector.connect();\n const queryResult = await connector.execute(result.sql);\n await connector.disconnect();\n const durationMs = Math.round((performance.now() - start) * 100) / 100;\n\n if (options.json) {\n console.log(formatJSON({\n columns: queryResult.columns,\n rows: queryResult.rows,\n rowCount: queryResult.rows.length,\n durationMs,\n }));\n } else {\n output.detail(`Entity: ${result.entityName}`);\n output.detail(`SQL: ${result.sql.replace(/\\n/g, ' ').slice(0, 120)}...`);\n output.newline();\n console.log(formatTable({\n columns: queryResult.columns,\n rows: queryResult.rows,\n rowCount: queryResult.rows.length,\n durationMs,\n }));\n }\n } catch (err) {\n if (err instanceof Error && err.message.includes('ENOENT')) {\n output.error('No catalog found. Run `yamchart sync-dbt` or `yamchart sync-warehouse` first.');\n } else {\n output.error(err instanceof Error ? err.message : String(err));\n }\n process.exit(1);\n }\n });\n\nprogram.parse();\n\n// Passive update check — runs in background, prints on exit if outdated\nlet updateNotification: string | null = null;\n\ncheckForUpdate(pkg.version).then((update) => {\n if (update) {\n updateNotification = `\\n Update available: ${update.current} → ${update.latest}\\n Run: yamchart update to see what's new\\n`;\n }\n});\n\nprocess.on('exit', () => {\n if (updateNotification) {\n // Use dim styling so it doesn't compete with command output\n console.error(`\\n${pc.dim(updateNotification)}`);\n }\n});\n"],"mappings":"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","names":["error","warning"]}
@@ -162,17 +162,44 @@ async function scanYamchartModelDeps(projectDir, catalogModels) {
162
162
  return entries;
163
163
  }
164
164
  async function getLineage(projectDir, modelName, options) {
165
+ const source = options?.source || "auto";
166
+ if (source === "db") {
167
+ throw new Error(
168
+ "Database lineage is not supported. Lineage is derived from catalog metadata. Run `yamchart sync-dbt` or `yamchart sync-warehouse` to populate the catalog."
169
+ );
170
+ }
171
+ if (source === "model") {
172
+ const yamchartEntries2 = await scanYamchartModelDeps(projectDir, []);
173
+ const tree2 = buildLineageTree(modelName, yamchartEntries2, {
174
+ maxDepth: options?.depth
175
+ });
176
+ const rendered2 = renderLineageTree(tree2);
177
+ return { tree: tree2, rendered: rendered2, source: "model" };
178
+ }
165
179
  const catalogPath = join(projectDir, ".yamchart", "catalog.json");
166
- const content = await readFile(catalogPath, "utf-8");
167
- const catalog = JSON.parse(content);
168
- const models = catalog.models || [];
180
+ let models = [];
181
+ try {
182
+ const content = await readFile(catalogPath, "utf-8");
183
+ const catalog = JSON.parse(content);
184
+ models = catalog.models || [];
185
+ } catch {
186
+ if (source === "catalog") {
187
+ throw new Error("No catalog found. Run `yamchart sync-dbt` or `yamchart sync-warehouse` to populate it.");
188
+ }
189
+ const yamchartEntries2 = await scanYamchartModelDeps(projectDir, []);
190
+ const tree2 = buildLineageTree(modelName, yamchartEntries2, {
191
+ maxDepth: options?.depth
192
+ });
193
+ const rendered2 = renderLineageTree(tree2);
194
+ return { tree: tree2, rendered: rendered2, source: "model" };
195
+ }
169
196
  const yamchartEntries = await scanYamchartModelDeps(projectDir, models);
170
197
  const allModels = [...models, ...yamchartEntries];
171
198
  const tree = buildLineageTree(modelName, allModels, {
172
199
  maxDepth: options?.depth
173
200
  });
174
201
  const rendered = renderLineageTree(tree);
175
- return { tree, rendered };
202
+ return { tree, rendered, source: "catalog" };
176
203
  }
177
204
  export {
178
205
  buildLineageTree,
@@ -181,4 +208,4 @@ export {
181
208
  renderLineageTree,
182
209
  resolveDependencies
183
210
  };
184
- //# sourceMappingURL=lineage-XSITWW2O.js.map
211
+ //# sourceMappingURL=lineage-T5NRHHZN.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/lineage.ts"],"sourcesContent":["import { readFile, readdir, access } from 'fs/promises';\nimport { join, extname } from 'path';\n\nexport interface LineageNode {\n name: string;\n isSource?: boolean;\n children: LineageNode[];\n}\n\nexport interface CatalogEntry {\n name: string;\n table?: string;\n source?: string;\n dependsOn?: string[];\n}\n\n/**\n * Convert a dbt node key to a model name.\n *\n * Examples:\n * model.project.stg_orders → stg_orders\n * source.project.raw.orders → raw.orders\n */\nfunction resolveNodeKey(key: string): string {\n const parts = key.split('.');\n if (parts[0] === 'source' && parts.length >= 4) {\n // source.project.schema.table → schema.table\n return parts.slice(2).join('.');\n }\n // model.project.name → name\n return parts[parts.length - 1];\n}\n\n/**\n * Extract all dependencies from yamchart model SQL.\n * Finds ref() calls, @source annotations, and FROM/JOIN table references.\n */\nexport function extractSqlDependencies(sql: string): {\n refs: string[];\n sources: string[];\n tables: string[];\n} {\n const refs: string[] = [];\n const sources: string[] = [];\n const tables: string[] = [];\n\n // Extract {{ ref('name') }} calls\n const refRegex = /\\{\\{\\s*ref\\(['\"]([^'\"]+)['\"]\\)\\s*\\}\\}/g;\n let match;\n while ((match = refRegex.exec(sql)) !== null) {\n if (match[1]) refs.push(match[1]);\n }\n\n // Extract all @source: annotations\n const sourceRegex = /--\\s*@source:\\s*(.+)/g;\n while ((match = sourceRegex.exec(sql)) !== null) {\n if (match[1]) sources.push(match[1].trim());\n }\n\n // Remove comments and Jinja for table extraction\n const cleaned = sql\n .replace(/--.*$/gm, '')\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n .replace(/\\{\\{[\\s\\S]*?\\}\\}/g, '')\n .replace(/\\{%[\\s\\S]*?%\\}/g, '');\n\n // Extract FROM and JOIN table references\n const tableRegex = /\\b(?:FROM|JOIN)\\s+([\\w]+(?:\\.[\\w]+){1,2})/gi;\n while ((match = tableRegex.exec(cleaned)) !== null) {\n if (match[1]) tables.push(match[1]);\n }\n\n return { refs, sources, tables };\n}\n\n/**\n * Resolve extracted SQL dependencies against catalog entries.\n * Returns an array of catalog model names that were matched.\n */\nexport function resolveDependencies(\n deps: { refs: string[]; sources: string[]; tables: string[] },\n catalogModels: CatalogEntry[],\n): string[] {\n const resolved = new Set<string>();\n\n // Build lookup maps\n const byName = new Map<string, string>();\n const byTable = new Map<string, string>();\n\n for (const model of catalogModels) {\n byName.set(model.name.toLowerCase(), model.name);\n if (model.table) {\n byTable.set(model.table.toUpperCase(), model.name);\n }\n }\n\n // Resolve ref() calls by name\n for (const ref of deps.refs) {\n const nameMatch = byName.get(ref.toLowerCase());\n if (nameMatch) resolved.add(nameMatch);\n }\n\n // Resolve @source by name\n for (const source of deps.sources) {\n const nameMatch = byName.get(source.toLowerCase());\n if (nameMatch) resolved.add(nameMatch);\n }\n\n // Resolve FROM/JOIN tables\n for (const table of deps.tables) {\n // Try exact match on table path (case-insensitive)\n const upper = table.toUpperCase();\n const exactMatch = byTable.get(upper);\n if (exactMatch) {\n resolved.add(exactMatch);\n continue;\n }\n\n // Try matching by name (last segment)\n const parts = table.split('.');\n const lastPart = parts[parts.length - 1]!;\n const nameMatch = byName.get(lastPart.toLowerCase());\n if (nameMatch) {\n resolved.add(nameMatch);\n continue;\n }\n\n // Try suffix match on table paths (for partial qualification like SCHEMA.TABLE)\n for (const [tablePath, modelName] of byTable) {\n if (tablePath.endsWith('.' + upper)) {\n resolved.add(modelName);\n break;\n }\n }\n }\n\n return Array.from(resolved);\n}\n\n/**\n * Build a tree of upstream dependencies from catalog data.\n * Walks `dependsOn` recursively with cycle detection.\n */\nexport function buildLineageTree(\n modelName: string,\n models: CatalogEntry[],\n options?: { maxDepth?: number },\n): LineageNode {\n const modelMap = new Map<string, CatalogEntry>();\n for (const model of models) {\n modelMap.set(model.name, model);\n }\n\n function walk(name: string, visited: Set<string>, depth: number): LineageNode | null {\n // Cycle detection: if already on the current path, skip entirely\n if (visited.has(name)) {\n return null;\n }\n\n const entry = modelMap.get(name);\n const node: LineageNode = {\n name,\n children: [],\n };\n\n if (entry?.source === 'dbt-source') {\n node.isSource = true;\n }\n\n // Unknown model or depth limit reached: return node with no children\n if (!entry) {\n return node;\n }\n\n if (options?.maxDepth !== undefined && depth >= options.maxDepth) {\n return node;\n }\n\n visited.add(name);\n\n if (entry.dependsOn) {\n for (const dep of entry.dependsOn) {\n const resolvedName = resolveNodeKey(dep);\n const child = walk(resolvedName, visited, depth + 1);\n if (child) {\n node.children.push(child);\n }\n }\n }\n\n // Remove from visited so the same node can appear in other branches\n // (cycle detection is path-based, not global)\n visited.delete(name);\n\n return node;\n }\n\n // Root call never returns null (visited set is empty)\n return walk(modelName, new Set<string>(), 0)!;\n}\n\n/**\n * Render a lineage tree as indented text for terminal output.\n *\n * Format:\n * fct_revenue\n * ← stg_orders\n * ← source: raw.orders\n * ← stg_payments\n * ← source: raw.payments\n */\nexport function renderLineageTree(node: LineageNode, indent: number = 0): string {\n const lines: string[] = [];\n\n if (indent === 0) {\n // Root node: just the name\n lines.push(node.name);\n } else {\n const padding = ' '.repeat(indent);\n const label = node.isSource ? `source: ${node.name}` : node.name;\n lines.push(`${padding}\\u2190 ${label}`);\n }\n\n for (const child of node.children) {\n lines.push(renderLineageTree(child, indent + 1));\n }\n\n return lines.join('\\n');\n}\n\ninterface CatalogFile {\n models?: CatalogEntry[];\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 yamchart model .sql files and build catalog entries with resolved dependencies.\n * Only creates entries for models not already in the catalog.\n */\nasync function scanYamchartModelDeps(\n projectDir: string,\n catalogModels: CatalogEntry[],\n): Promise<CatalogEntry[]> {\n const modelsDir = join(projectDir, 'models');\n const entries: CatalogEntry[] = [];\n const existingNames = new Set(catalogModels.map(m => m.name));\n\n try {\n await access(modelsDir);\n } catch {\n return [];\n }\n\n const sqlFiles = await findSqlFiles(modelsDir);\n\n for (const filePath of sqlFiles) {\n const sql = await readFile(filePath, 'utf-8');\n\n // Extract model name from @name annotation\n const nameMatch = sql.match(/--\\s*@name:\\s*(.+)/);\n if (!nameMatch?.[1]) continue;\n\n const name = nameMatch[1].trim();\n\n // Skip if already in catalog (dbt/warehouse entry takes precedence)\n if (existingNames.has(name)) continue;\n\n // Extract and resolve dependencies\n const deps = extractSqlDependencies(sql);\n const resolved = resolveDependencies(deps, catalogModels);\n\n entries.push({\n name,\n ...(resolved.length > 0 ? { dependsOn: resolved } : {}),\n });\n }\n\n return entries;\n}\n\n/**\n * Load catalog.json and run lineage for a model.\n * Scans yamchart model SQL files to resolve dependencies not in the catalog.\n */\nexport async function getLineage(\n projectDir: string,\n modelName: string,\n options?: { depth?: number; json?: boolean },\n): Promise<{ tree: LineageNode; rendered: string }> {\n const catalogPath = join(projectDir, '.yamchart', 'catalog.json');\n const content = await readFile(catalogPath, 'utf-8');\n const catalog: CatalogFile = JSON.parse(content);\n const models = catalog.models || [];\n\n // Scan yamchart model SQL files for dependencies not in the catalog\n const yamchartEntries = await scanYamchartModelDeps(projectDir, models);\n const allModels = [...models, ...yamchartEntries];\n\n const tree = buildLineageTree(modelName, allModels, {\n maxDepth: options?.depth,\n });\n\n const rendered = renderLineageTree(tree);\n\n return { tree, rendered };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/commands/lineage.ts"],"sourcesContent":["import { readFile, readdir, access } from 'fs/promises';\nimport { join, extname } from 'path';\n\nexport interface LineageNode {\n name: string;\n isSource?: boolean;\n children: LineageNode[];\n}\n\nexport interface CatalogEntry {\n name: string;\n table?: string;\n source?: string;\n dependsOn?: string[];\n}\n\n/**\n * Convert a dbt node key to a model name.\n *\n * Examples:\n * model.project.stg_orders → stg_orders\n * source.project.raw.orders → raw.orders\n */\nfunction resolveNodeKey(key: string): string {\n const parts = key.split('.');\n if (parts[0] === 'source' && parts.length >= 4) {\n // source.project.schema.table → schema.table\n return parts.slice(2).join('.');\n }\n // model.project.name → name\n return parts[parts.length - 1];\n}\n\n/**\n * Extract all dependencies from yamchart model SQL.\n * Finds ref() calls, @source annotations, and FROM/JOIN table references.\n */\nexport function extractSqlDependencies(sql: string): {\n refs: string[];\n sources: string[];\n tables: string[];\n} {\n const refs: string[] = [];\n const sources: string[] = [];\n const tables: string[] = [];\n\n // Extract {{ ref('name') }} calls\n const refRegex = /\\{\\{\\s*ref\\(['\"]([^'\"]+)['\"]\\)\\s*\\}\\}/g;\n let match;\n while ((match = refRegex.exec(sql)) !== null) {\n if (match[1]) refs.push(match[1]);\n }\n\n // Extract all @source: annotations\n const sourceRegex = /--\\s*@source:\\s*(.+)/g;\n while ((match = sourceRegex.exec(sql)) !== null) {\n if (match[1]) sources.push(match[1].trim());\n }\n\n // Remove comments and Jinja for table extraction\n const cleaned = sql\n .replace(/--.*$/gm, '')\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n .replace(/\\{\\{[\\s\\S]*?\\}\\}/g, '')\n .replace(/\\{%[\\s\\S]*?%\\}/g, '');\n\n // Extract FROM and JOIN table references\n const tableRegex = /\\b(?:FROM|JOIN)\\s+([\\w]+(?:\\.[\\w]+){1,2})/gi;\n while ((match = tableRegex.exec(cleaned)) !== null) {\n if (match[1]) tables.push(match[1]);\n }\n\n return { refs, sources, tables };\n}\n\n/**\n * Resolve extracted SQL dependencies against catalog entries.\n * Returns an array of catalog model names that were matched.\n */\nexport function resolveDependencies(\n deps: { refs: string[]; sources: string[]; tables: string[] },\n catalogModels: CatalogEntry[],\n): string[] {\n const resolved = new Set<string>();\n\n // Build lookup maps\n const byName = new Map<string, string>();\n const byTable = new Map<string, string>();\n\n for (const model of catalogModels) {\n byName.set(model.name.toLowerCase(), model.name);\n if (model.table) {\n byTable.set(model.table.toUpperCase(), model.name);\n }\n }\n\n // Resolve ref() calls by name\n for (const ref of deps.refs) {\n const nameMatch = byName.get(ref.toLowerCase());\n if (nameMatch) resolved.add(nameMatch);\n }\n\n // Resolve @source by name\n for (const source of deps.sources) {\n const nameMatch = byName.get(source.toLowerCase());\n if (nameMatch) resolved.add(nameMatch);\n }\n\n // Resolve FROM/JOIN tables\n for (const table of deps.tables) {\n // Try exact match on table path (case-insensitive)\n const upper = table.toUpperCase();\n const exactMatch = byTable.get(upper);\n if (exactMatch) {\n resolved.add(exactMatch);\n continue;\n }\n\n // Try matching by name (last segment)\n const parts = table.split('.');\n const lastPart = parts[parts.length - 1]!;\n const nameMatch = byName.get(lastPart.toLowerCase());\n if (nameMatch) {\n resolved.add(nameMatch);\n continue;\n }\n\n // Try suffix match on table paths (for partial qualification like SCHEMA.TABLE)\n for (const [tablePath, modelName] of byTable) {\n if (tablePath.endsWith('.' + upper)) {\n resolved.add(modelName);\n break;\n }\n }\n }\n\n return Array.from(resolved);\n}\n\n/**\n * Build a tree of upstream dependencies from catalog data.\n * Walks `dependsOn` recursively with cycle detection.\n */\nexport function buildLineageTree(\n modelName: string,\n models: CatalogEntry[],\n options?: { maxDepth?: number },\n): LineageNode {\n const modelMap = new Map<string, CatalogEntry>();\n for (const model of models) {\n modelMap.set(model.name, model);\n }\n\n function walk(name: string, visited: Set<string>, depth: number): LineageNode | null {\n // Cycle detection: if already on the current path, skip entirely\n if (visited.has(name)) {\n return null;\n }\n\n const entry = modelMap.get(name);\n const node: LineageNode = {\n name,\n children: [],\n };\n\n if (entry?.source === 'dbt-source') {\n node.isSource = true;\n }\n\n // Unknown model or depth limit reached: return node with no children\n if (!entry) {\n return node;\n }\n\n if (options?.maxDepth !== undefined && depth >= options.maxDepth) {\n return node;\n }\n\n visited.add(name);\n\n if (entry.dependsOn) {\n for (const dep of entry.dependsOn) {\n const resolvedName = resolveNodeKey(dep);\n const child = walk(resolvedName, visited, depth + 1);\n if (child) {\n node.children.push(child);\n }\n }\n }\n\n // Remove from visited so the same node can appear in other branches\n // (cycle detection is path-based, not global)\n visited.delete(name);\n\n return node;\n }\n\n // Root call never returns null (visited set is empty)\n return walk(modelName, new Set<string>(), 0)!;\n}\n\n/**\n * Render a lineage tree as indented text for terminal output.\n *\n * Format:\n * fct_revenue\n * ← stg_orders\n * ← source: raw.orders\n * ← stg_payments\n * ← source: raw.payments\n */\nexport function renderLineageTree(node: LineageNode, indent: number = 0): string {\n const lines: string[] = [];\n\n if (indent === 0) {\n // Root node: just the name\n lines.push(node.name);\n } else {\n const padding = ' '.repeat(indent);\n const label = node.isSource ? `source: ${node.name}` : node.name;\n lines.push(`${padding}\\u2190 ${label}`);\n }\n\n for (const child of node.children) {\n lines.push(renderLineageTree(child, indent + 1));\n }\n\n return lines.join('\\n');\n}\n\ninterface CatalogFile {\n models?: CatalogEntry[];\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 yamchart model .sql files and build catalog entries with resolved dependencies.\n * Only creates entries for models not already in the catalog.\n */\nasync function scanYamchartModelDeps(\n projectDir: string,\n catalogModels: CatalogEntry[],\n): Promise<CatalogEntry[]> {\n const modelsDir = join(projectDir, 'models');\n const entries: CatalogEntry[] = [];\n const existingNames = new Set(catalogModels.map(m => m.name));\n\n try {\n await access(modelsDir);\n } catch {\n return [];\n }\n\n const sqlFiles = await findSqlFiles(modelsDir);\n\n for (const filePath of sqlFiles) {\n const sql = await readFile(filePath, 'utf-8');\n\n // Extract model name from @name annotation\n const nameMatch = sql.match(/--\\s*@name:\\s*(.+)/);\n if (!nameMatch?.[1]) continue;\n\n const name = nameMatch[1].trim();\n\n // Skip if already in catalog (dbt/warehouse entry takes precedence)\n if (existingNames.has(name)) continue;\n\n // Extract and resolve dependencies\n const deps = extractSqlDependencies(sql);\n const resolved = resolveDependencies(deps, catalogModels);\n\n entries.push({\n name,\n ...(resolved.length > 0 ? { dependsOn: resolved } : {}),\n });\n }\n\n return entries;\n}\n\n/**\n * Load catalog.json and run lineage for a model.\n * Scans yamchart model SQL files to resolve dependencies not in the catalog.\n */\nexport async function getLineage(\n projectDir: string,\n modelName: string,\n options?: { depth?: number; json?: boolean; source?: 'auto' | 'catalog' | 'model' | 'db' },\n): Promise<{ tree: LineageNode; rendered: string; source: 'catalog' | 'model' }> {\n const source = options?.source || 'auto';\n\n if (source === 'db') {\n throw new Error(\n 'Database lineage is not supported. Lineage is derived from catalog metadata. Run `yamchart sync-dbt` or `yamchart sync-warehouse` to populate the catalog.',\n );\n }\n\n // For source: 'model', only scan SQL model files (skip catalog)\n if (source === 'model') {\n const yamchartEntries = await scanYamchartModelDeps(projectDir, []);\n const tree = buildLineageTree(modelName, yamchartEntries, {\n maxDepth: options?.depth,\n });\n const rendered = renderLineageTree(tree);\n return { tree, rendered, source: 'model' };\n }\n\n // For source: 'auto' or 'catalog', read catalog and merge with model deps\n const catalogPath = join(projectDir, '.yamchart', 'catalog.json');\n let models: CatalogEntry[] = [];\n\n try {\n const content = await readFile(catalogPath, 'utf-8');\n const catalog: CatalogFile = JSON.parse(content);\n models = catalog.models || [];\n } catch {\n if (source === 'catalog') {\n throw new Error('No catalog found. Run `yamchart sync-dbt` or `yamchart sync-warehouse` to populate it.');\n }\n // In auto mode, fall back to model-only lineage\n const yamchartEntries = await scanYamchartModelDeps(projectDir, []);\n const tree = buildLineageTree(modelName, yamchartEntries, {\n maxDepth: options?.depth,\n });\n const rendered = renderLineageTree(tree);\n return { tree, rendered, source: 'model' };\n }\n\n // Scan yamchart model SQL files for dependencies not in the catalog\n const yamchartEntries = await scanYamchartModelDeps(projectDir, models);\n const allModels = [...models, ...yamchartEntries];\n\n const tree = buildLineageTree(modelName, allModels, {\n maxDepth: options?.depth,\n });\n\n const rendered = renderLineageTree(tree);\n\n return { tree, rendered, source: 'catalog' };\n}\n"],"mappings":"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","names":["yamchartEntries","tree","rendered"]}
@@ -1,4 +1,4 @@
1
- import{p as xe,u as he,q as me,e as be,r as $,j as t,s as E,E as ce,M as fe,t as ve,v as je,w as Ce,a as S}from"./index-B41yj3io.js";import{a as s}from"./echarts-DtOYsfLX.js";const ge=`
1
+ import{p as xe,u as he,q as me,e as be,r as $,j as t,s as E,E as ce,M as fe,t as ve,v as je,w as Ce,a as S}from"./index-DcNtdUoV.js";import{a as s}from"./echarts-DtOYsfLX.js";const ge=`
2
2
  .rdp-root {
3
3
  --rdp-accent-color: var(--yc-color-primary, #2563eb);
4
4
  --rdp-accent-background-color: color-mix(in srgb, var(--yc-color-primary, #2563eb) 15%, transparent);
@@ -1 +1 @@
1
- import{u,j as e,A as p}from"./index-B41yj3io.js";import{a as r}from"./echarts-DtOYsfLX.js";const f="",g={google:"Google",microsoft:"Microsoft",oidc:"SSO"};function j(){const m=u(o=>o.login),l=u(o=>o.providers),[a,x]=r.useState(""),[t,b]=r.useState(""),[c,s]=r.useState(""),[n,d]=r.useState(!1);r.useEffect(()=>{window.location.hash.includes("error=account_conflict")&&(s("An account with this email already exists. Please sign in with your password."),window.location.hash="#/")},[]);const y=async o=>{o.preventDefault(),s(""),d(!0);try{await m(a,t)}catch(i){i instanceof p?s(i.message):s("An unexpected error occurred")}finally{d(!1)}},h=o=>{window.location.href=`${f}/api/auth/sso/${o}`};return e.jsx("div",{className:"min-h-screen flex items-center justify-center",style:{backgroundColor:"var(--yc-color-background)"},children:e.jsxs("div",{className:"rounded-lg shadow-sm p-8 w-full max-w-md",style:{backgroundColor:"var(--yc-color-surface)",border:"1px solid var(--yc-color-border)"},children:[e.jsx("h1",{className:"text-2xl font-semibold mb-2",style:{color:"var(--yc-color-text)"},children:"Sign in to Yamchart"}),e.jsx("p",{className:"text-sm mb-6",style:{color:"var(--yc-color-text-secondary)"},children:"Enter your credentials to access dashboards."}),c&&e.jsx("div",{className:"text-sm rounded-md px-4 py-3 mb-4",style:{backgroundColor:"color-mix(in srgb, var(--yc-color-danger) 10%, transparent)",border:"1px solid color-mix(in srgb, var(--yc-color-danger) 30%, transparent)",color:"var(--yc-color-danger)"},children:c}),l.length>0&&e.jsxs("div",{className:"space-y-2 mb-6",children:[l.map(o=>e.jsxs("button",{onClick:()=>h(o),className:"w-full py-2 px-4 text-sm font-medium rounded-md hover:bg-black/5",style:{border:"1px solid var(--yc-color-border)",color:"var(--yc-color-text-secondary)"},children:["Sign in with ",g[o]??o]},o)),e.jsxs("div",{className:"relative my-4",children:[e.jsx("div",{className:"absolute inset-0 flex items-center",children:e.jsx("div",{className:"w-full border-t",style:{borderColor:"var(--yc-color-border)"}})}),e.jsx("div",{className:"relative flex justify-center text-xs",style:{color:"var(--yc-color-text-muted)"},children:e.jsx("span",{className:"px-2",style:{backgroundColor:"var(--yc-color-surface)"},children:"or"})})]})]}),e.jsxs("form",{onSubmit:y,className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:"email",className:"block text-sm font-medium mb-1",style:{color:"var(--yc-color-text-secondary)"},children:"Email"}),e.jsx("input",{id:"email",type:"email",value:a,onChange:o=>x(o.target.value),required:!0,className:"w-full px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",style:{backgroundColor:"var(--yc-color-input-bg)",color:"var(--yc-color-text)",borderColor:"var(--yc-color-border)"},placeholder:"you@example.com"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"password",className:"block text-sm font-medium mb-1",style:{color:"var(--yc-color-text-secondary)"},children:"Password"}),e.jsx("input",{id:"password",type:"password",value:t,onChange:o=>b(o.target.value),required:!0,className:"w-full px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",style:{backgroundColor:"var(--yc-color-input-bg)",color:"var(--yc-color-text)",borderColor:"var(--yc-color-border)"},placeholder:"Password"})]}),e.jsx("button",{type:"submit",disabled:n,className:"w-full py-2 px-4 bg-blue-600 text-white text-sm font-medium rounded-md hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed",children:n?"Signing in...":"Sign in"})]})]})})}export{j as LoginPage};
1
+ import{u,j as e,A as p}from"./index-DcNtdUoV.js";import{a as r}from"./echarts-DtOYsfLX.js";const f="",g={google:"Google",microsoft:"Microsoft",oidc:"SSO"};function j(){const m=u(o=>o.login),l=u(o=>o.providers),[a,x]=r.useState(""),[t,b]=r.useState(""),[c,s]=r.useState(""),[n,d]=r.useState(!1);r.useEffect(()=>{window.location.hash.includes("error=account_conflict")&&(s("An account with this email already exists. Please sign in with your password."),window.location.hash="#/")},[]);const y=async o=>{o.preventDefault(),s(""),d(!0);try{await m(a,t)}catch(i){i instanceof p?s(i.message):s("An unexpected error occurred")}finally{d(!1)}},h=o=>{window.location.href=`${f}/api/auth/sso/${o}`};return e.jsx("div",{className:"min-h-screen flex items-center justify-center",style:{backgroundColor:"var(--yc-color-background)"},children:e.jsxs("div",{className:"rounded-lg shadow-sm p-8 w-full max-w-md",style:{backgroundColor:"var(--yc-color-surface)",border:"1px solid var(--yc-color-border)"},children:[e.jsx("h1",{className:"text-2xl font-semibold mb-2",style:{color:"var(--yc-color-text)"},children:"Sign in to Yamchart"}),e.jsx("p",{className:"text-sm mb-6",style:{color:"var(--yc-color-text-secondary)"},children:"Enter your credentials to access dashboards."}),c&&e.jsx("div",{className:"text-sm rounded-md px-4 py-3 mb-4",style:{backgroundColor:"color-mix(in srgb, var(--yc-color-danger) 10%, transparent)",border:"1px solid color-mix(in srgb, var(--yc-color-danger) 30%, transparent)",color:"var(--yc-color-danger)"},children:c}),l.length>0&&e.jsxs("div",{className:"space-y-2 mb-6",children:[l.map(o=>e.jsxs("button",{onClick:()=>h(o),className:"w-full py-2 px-4 text-sm font-medium rounded-md hover:bg-black/5",style:{border:"1px solid var(--yc-color-border)",color:"var(--yc-color-text-secondary)"},children:["Sign in with ",g[o]??o]},o)),e.jsxs("div",{className:"relative my-4",children:[e.jsx("div",{className:"absolute inset-0 flex items-center",children:e.jsx("div",{className:"w-full border-t",style:{borderColor:"var(--yc-color-border)"}})}),e.jsx("div",{className:"relative flex justify-center text-xs",style:{color:"var(--yc-color-text-muted)"},children:e.jsx("span",{className:"px-2",style:{backgroundColor:"var(--yc-color-surface)"},children:"or"})})]})]}),e.jsxs("form",{onSubmit:y,className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:"email",className:"block text-sm font-medium mb-1",style:{color:"var(--yc-color-text-secondary)"},children:"Email"}),e.jsx("input",{id:"email",type:"email",value:a,onChange:o=>x(o.target.value),required:!0,className:"w-full px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",style:{backgroundColor:"var(--yc-color-input-bg)",color:"var(--yc-color-text)",borderColor:"var(--yc-color-border)"},placeholder:"you@example.com"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"password",className:"block text-sm font-medium mb-1",style:{color:"var(--yc-color-text-secondary)"},children:"Password"}),e.jsx("input",{id:"password",type:"password",value:t,onChange:o=>b(o.target.value),required:!0,className:"w-full px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",style:{backgroundColor:"var(--yc-color-input-bg)",color:"var(--yc-color-text)",borderColor:"var(--yc-color-border)"},placeholder:"Password"})]}),e.jsx("button",{type:"submit",disabled:n,className:"w-full py-2 px-4 bg-blue-600 text-white text-sm font-medium rounded-md hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed",children:n?"Signing in...":"Sign in"})]})]})})}export{j as LoginPage};
@@ -1 +1 @@
1
- import{j as e,c as U,b as G,d as I,e as Y,f as q,g as _,F as z,S as K,C as X,D as Q,h as J,T as Z,G as ee,W as re,i as te,H as se,k as ae,l as le,m as ce,P as oe,n as ne,B as ie,L as de,a as he,o as xe}from"./index-B41yj3io.js";import{a as f}from"./echarts-DtOYsfLX.js";function me({title:a,description:l,loading:r=!1,error:i=null,cached:t,durationMs:c,hasDrillDown:b,onRefresh:s,children:u}){return e.jsxs("div",{className:"chart-container",children:[e.jsxs("div",{className:"flex items-start justify-between p-4 border-b",style:{borderColor:"var(--yc-color-border)"},children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h2",{className:"text-lg font-semibold",style:{color:"var(--yc-color-text)"},children:a}),b&&e.jsxs("svg",{className:"w-4 h-4 flex-shrink-0",style:{color:"var(--yc-color-text-muted)"},viewBox:"0 0 20 20",fill:"currentColor","aria-hidden":"true",children:[e.jsx("title",{children:"Right-click to drill down"}),e.jsx("path",{fillRule:"evenodd",d:"M5.22 14.78a.75.75 0 001.06 0l7.22-7.22v5.69a.75.75 0 001.5 0v-7.5a.75.75 0 00-.75-.75h-7.5a.75.75 0 000 1.5h5.69l-7.22 7.22a.75.75 0 000 1.06z",clipRule:"evenodd"})]})]}),l&&e.jsx("p",{className:"text-sm mt-1",style:{color:"var(--yc-color-text-secondary)"},children:l})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[t!==void 0&&e.jsx("span",{className:"text-xs px-2 py-1 rounded",style:t?{backgroundColor:"color-mix(in srgb, var(--yc-color-success) 15%, transparent)",color:"var(--yc-color-success)"}:{backgroundColor:"color-mix(in srgb, var(--yc-color-primary) 15%, transparent)",color:"var(--yc-color-primary)"},children:t?"Cached":"Fresh"}),c!==void 0&&e.jsxs("span",{className:"text-xs",style:{color:"var(--yc-color-text-muted)"},children:[c,"ms"]}),s&&e.jsx("button",{onClick:s,disabled:r,className:"p-1.5 hover:bg-black/5 rounded transition-colors disabled:opacity-50",style:{color:"var(--yc-color-text-muted)"},title:"Refresh",children:e.jsx("svg",{className:U("w-4 h-4",r&&"animate-spin"),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})})})]})]}),e.jsx("div",{className:"p-4",children:i?e.jsx("div",{className:"flex items-center justify-center h-64",style:{color:"var(--yc-color-danger)"},children:e.jsxs("div",{className:"text-center",children:[e.jsx("p",{className:"font-medium",children:"Failed to load chart"}),e.jsx("p",{className:"text-sm mt-1",children:i.message})]})}):u})]})}const ue={day:{label:"Date",format:"%b %d, %Y"},week:{label:"Week Starting",format:"%b %d"},month:{label:"Month",format:"%b '%y"},quarter:{label:"Quarter",format:"quarter"},year:{label:"Year",format:"%Y"}};function ye({chartName:a}){const[l,r]=f.useState(!1),i=async()=>{const t=`{{${a}}}`;try{await navigator.clipboard.writeText(t),r(!0),setTimeout(()=>r(!1),2e3)}catch(c){console.error("Failed to copy:",c)}};return e.jsx("button",{onClick:i,className:"text-sm flex items-center gap-1.5 px-2 py-1 rounded hover:bg-black/5 transition-colors",style:{color:"var(--yc-color-text-secondary)"},title:`Copy {{${a}}} for use in markdown widgets`,children:l?e.jsxs(e.Fragment,{children:[e.jsx("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",style:{color:"var(--yc-color-success)"},children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})}),e.jsx("span",{style:{color:"var(--yc-color-success)"},children:"Copied!"})]}):e.jsxs(e.Fragment,{children:[e.jsx("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"})}),e.jsx("span",{children:"Copy Reference"})]})})}function F(a,l){if(!l)return a.toLocaleString();const r=l.decimals??0;switch(l.type){case"currency":return new Intl.NumberFormat("en-US",{style:"currency",currency:l.currency||"USD",minimumFractionDigits:r,maximumFractionDigits:r}).format(a);case"percent":return new Intl.NumberFormat("en-US",{style:"percent",minimumFractionDigits:r,maximumFractionDigits:r}).format(a/100);default:return a.toLocaleString(void 0,{minimumFractionDigits:r,maximumFractionDigits:r})}}function fe(a,l){const r=a>=0?"+":"";return l==="percent_change"?`${r}${a.toFixed(1)}%`:`${r}${a.toLocaleString()}`}function ve({data:a,config:l,title:r,comparison:i}){var p,n,j;if(!(a!=null&&a[0])||!((p=l.value)!=null&&p.field))return e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-muted)"},children:"No data available"});const t=a[0],c=t[l.value.field],b=F(c,l.format);let s=null,u="percent_change",C,w,v;if(i)s=i.change,u=i.changeType,C=i.currentPeriodLabel,w=i.previousPeriodLabel,v=F(i.previousValue,l.format);else if((n=l.comparison)!=null&&n.enabled&&l.comparison.field){const x=t[l.comparison.field];u=l.comparison.type,x&&x!==0&&(u==="percent_change"?s=(c-x)/x*100:s=c-x,v=F(x,l.format))}const h=l.goal,g=h&&h.value!==0?Math.max(0,Math.min(c/h.value*100,100)):null,N=h?c>=h.value?"var(--yc-color-success)":"var(--yc-color-danger)":void 0;return e.jsxs("div",{className:"h-80 flex flex-col items-center justify-center p-8",children:[e.jsxs("div",{className:"text-6xl font-bold tabular-nums",style:{color:"var(--yc-color-text)"},children:[b,l.unit&&e.jsx("span",{className:"text-3xl font-normal ml-2",style:{color:"var(--yc-color-text-muted)"},children:l.unit})]}),C&&e.jsx("div",{className:"text-sm mt-2",style:{color:"var(--yc-color-text-muted)"},children:C}),r&&e.jsx("div",{className:"text-lg mt-3",style:{color:"var(--yc-color-text-secondary)"},children:r}),s!==null&&e.jsxs("div",{className:"mt-4 flex flex-col items-center gap-1",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"text-lg font-medium px-3 py-1 rounded",style:s>=0?{backgroundColor:"color-mix(in srgb, var(--yc-color-success) 15%, transparent)",color:"var(--yc-color-success)"}:{backgroundColor:"color-mix(in srgb, var(--yc-color-danger) 15%, transparent)",color:"var(--yc-color-danger)"},children:fe(s,u)}),v&&e.jsxs("span",{className:"text-sm",style:{color:"var(--yc-color-text-muted)"},children:["vs ",v]}),!v&&((j=l.comparison)==null?void 0:j.label)&&e.jsx("span",{className:"text-sm",style:{color:"var(--yc-color-text-muted)"},children:l.comparison.label})]}),w&&e.jsx("div",{className:"text-xs",style:{color:"var(--yc-color-text-muted)"},children:w})]}),h&&g!==null&&e.jsxs("div",{className:"mt-4 w-full max-w-[280px]",children:[h.show_progress&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex justify-between text-sm mb-1",style:{color:"var(--yc-color-text-muted)"},children:[e.jsxs("span",{children:[F(c,l.format)," / ",F(h.value,l.format)]}),e.jsxs("span",{children:[g.toFixed(0),"%"]})]}),e.jsx("div",{className:"w-full h-2 rounded-full",style:{backgroundColor:"var(--yc-color-surface-hover)"},children:e.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${g}%`,backgroundColor:N}})})]}),h.label&&e.jsx("div",{className:"text-sm mt-1 text-center",style:{color:"var(--yc-color-text-muted)"},children:h.label})]})]})}function ge({chartName:a,drillParams:l}){var S,$,T,V,R,B;const{data:r,isLoading:i}=G(a),{data:t,isLoading:c,error:b}=I(a),{data:s}=Y(),u=q(),C=_(o=>o.getEffectiveFilters),w=_(o=>o.setChartFilter),v=i||c,h=l==null?void 0:l._from,g=l?Object.fromEntries(Object.entries(l).filter(([o])=>!o.startsWith("_"))):{},N=Object.keys(g).length>0,p=Object.entries(g).map(([o,d])=>`${o}: ${d}`).join(", ");f.useEffect(()=>{if(N)for(const[o,d]of Object.entries(g))w(a,o,d)},[a,N]);const[n,j]=f.useState(null),x=f.useCallback((o,d,y)=>{j({x:y.x,y:y.y,field:o,value:d})},[]),E=f.useCallback(()=>{var k,D;if(!n||!((k=r==null?void 0:r.drillDown)!=null&&k.model))return;const o=r.drillDown,d=o.fields?typeof o.fields=="string"?o.fields:o.fields[0]:o.field??((D=r.chart.x)==null?void 0:D.field)??n.field,y=new URLSearchParams;if(n.allFields)for(const[P,H]of Object.entries(n.allFields))y.set(P,H);else y.set(d,n.value);y.set("_from",a),window.location.hash=`/charts/${a}/detail?${y.toString()}`,j(null)},[n,r,a]),W=f.useCallback(()=>{var k,D;if(!n||!((k=r==null?void 0:r.drillDown)!=null&&k.chart))return;const o=r.drillDown,d=o.fields?typeof o.fields=="string"?o.fields:o.fields[0]:o.field??((D=r.chart.x)==null?void 0:D.field)??n.field,y=new URLSearchParams({[d]:n.value,_from:a});window.location.hash=`/charts/${r.drillDown.chart}?${y.toString()}`,j(null)},[n,r,a]),M=C(a).granularity,m=M?ue[M]:void 0,L=m==null?void 0:m.label,A=m==null?void 0:m.format;if(i)return e.jsxs("div",{className:"chart-container animate-pulse",children:[e.jsx("div",{className:"p-4 border-b",style:{borderColor:"var(--yc-color-border)"},children:e.jsx("div",{className:"h-6 rounded w-48",style:{backgroundColor:"var(--yc-color-surface-hover)"}})}),e.jsx("div",{className:"p-4",children:e.jsx("div",{className:"h-80 rounded",style:{backgroundColor:"var(--yc-color-surface-hover)"}})})]});if(!r)return e.jsxs("div",{className:"chart-container p-8 text-center",style:{color:"var(--yc-color-text-secondary)"},children:["Chart not found: ",a]});const O=()=>{if(!t)return e.jsx("div",{className:"h-80 rounded animate-pulse",style:{backgroundColor:"var(--yc-color-surface-hover)"}});const o=r.chart.type;switch(o){case"line":if(!r.chart.x||!r.chart.y&&!r.chart.series)return e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-secondary)"},children:"Missing axis configuration"});{const d=m?{...r.chart.x,label:L,format:A}:r.chart.x;return e.jsx(de,{data:t.rows,columns:t.columns,xAxis:d,yAxis:r.chart.y,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c,onChartClick:x,goalData:t.goalData})}case"bar":if(!r.chart.x||!r.chart.y&&!r.chart.series)return e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-secondary)"},children:"Missing axis configuration"});{const d=m?{...r.chart.x,label:L,format:A}:r.chart.x;return e.jsx(ie,{data:t.rows,xAxis:d,yAxis:r.chart.y,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c,onChartClick:x,goalData:t.goalData})}case"area":if(!r.chart.x||!r.chart.y&&!r.chart.series)return e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-secondary)"},children:"Missing axis configuration"});{const d=m?{...r.chart.x,label:L,format:A}:r.chart.x;return e.jsx(ne,{data:t.rows,xAxis:d,yAxis:r.chart.y,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c,onChartClick:x,goalData:t.goalData})}case"pie":return!r.chart.x||!r.chart.y?e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-secondary)"},children:"Missing pie chart configuration"}):e.jsx(oe,{data:t.rows,xAxis:r.chart.x,yAxis:r.chart.y,theme:s==null?void 0:s.theme,loading:c,onChartClick:x});case"donut":return!r.chart.x||!r.chart.y?e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-secondary)"},children:"Missing donut chart configuration"}):e.jsx(ce,{data:t.rows,xAxis:r.chart.x,yAxis:r.chart.y,centerValue:r.chart.centerValue,theme:s==null?void 0:s.theme,loading:c,onChartClick:x});case"scatter":return!r.chart.x||!r.chart.y?e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-secondary)"},children:"Missing axis configuration"}):e.jsx(le,{data:t.rows,xAxis:r.chart.x,yAxis:r.chart.y,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c});case"combo":if(!r.chart.x)return e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-secondary)"},children:"Missing axis configuration"});{const d=m?{...r.chart.x,label:L,format:A}:r.chart.x;return e.jsx(ae,{data:t.rows,xAxis:d,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c,onChartClick:x,goalData:t.goalData})}case"kpi":return e.jsx(ve,{data:t.rows,config:r.chart,title:r.title,comparison:t.comparison});case"heatmap":return!r.chart.x||!r.chart.y?e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-secondary)"},children:"Missing axis configuration"}):e.jsx(se,{data:t.rows,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c});case"funnel":return e.jsx(te,{data:t.rows,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c});case"waterfall":return e.jsx(re,{data:t.rows,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c});case"gauge":return e.jsx(ee,{data:t.rows,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c});case"table":return e.jsx(Z,{data:t.rows,columns:t.columns,chartConfig:r.chart,height:"100%",loading:c});default:return e.jsxs("div",{className:"h-80 flex items-center justify-center text-gray-500",children:['Chart type "',o,'" not yet implemented']})}};return e.jsxs("div",{className:"space-y-4",children:[h&&e.jsxs("div",{className:"flex items-center gap-2 text-sm",style:{color:"var(--yc-color-text-secondary)"},children:[e.jsx("button",{onClick:()=>{window.location.hash=`/charts/${h}`},className:"transition-colors hover:opacity-80",style:{color:"var(--yc-color-primary)"},children:h}),e.jsx("span",{children:"/"}),e.jsx("span",{className:"font-medium",style:{color:"var(--yc-color-text)"},children:r.title}),p&&e.jsxs("span",{style:{color:"var(--yc-color-text-muted)"},children:["(",p,")"]})]}),e.jsxs("div",{className:"flex flex-wrap items-end justify-between gap-4",children:[r.parameters.length>0?e.jsx(z,{parameters:r.parameters,chartName:a}):e.jsx("div",{}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ye,{chartName:a}),e.jsx(K,{resourceType:"chart",resourceName:a})]})]}),e.jsx(me,{title:r.title,description:r.description,loading:v,cached:t==null?void 0:t.meta.cached,durationMs:t==null?void 0:t.meta.durationMs,hasDrillDown:!!((S=r.drillDown)!=null&&S.chart),onRefresh:()=>u(a),children:e.jsx(X,{isLoading:c,error:b,data:t==null?void 0:t.rows,onRetry:()=>u(a),children:O()})}),N&&t&&e.jsx(Q,{data:t.rows,columns:t.columns,drillDownColumns:($=r.drillDown)==null?void 0:$.columns,filterDisplay:p,chartName:a}),n&&e.jsx(J,{x:n.x,y:n.y,field:n.field,value:n.value,allFields:n.allFields,onViewDetails:(T=r.drillDown)!=null&&T.model?E:void 0,onGoToChart:(V=r.drillDown)!=null&&V.chart?W:void 0,detailModel:(R=r.drillDown)==null?void 0:R.model,targetChart:(B=r.drillDown)==null?void 0:B.chart,onClose:()=>j(null)})]})}function Ce({parsed:a}){const l=a.params.token,[r,i]=f.useState(null),[t,c]=f.useState(!1);return f.useEffect(()=>{if(!l){i("No share token provided");return}he.getPublicConfig(l).then(()=>c(!0)).catch(()=>i("This link has expired or been revoked"))},[l]),r?e.jsx("div",{className:"min-h-screen bg-gray-50 flex items-center justify-center",children:e.jsx("div",{className:"text-center",children:e.jsx("div",{className:"text-gray-400 text-lg",children:r})})}):t?e.jsxs("div",{className:"min-h-screen bg-gray-50",children:[e.jsx("div",{className:"max-w-7xl mx-auto py-6 px-4",children:a.type==="public_chart"?e.jsx(ge,{chartName:a.name}):e.jsx(xe,{dashboardId:a.name,initialTab:a.params.tab})}),e.jsx("div",{className:"text-center py-4 text-xs text-gray-400",children:"Shared via yamchart"})]}):e.jsx("div",{className:"min-h-screen bg-gray-50 flex items-center justify-center",children:e.jsx("div",{className:"text-gray-500",children:"Loading..."})})}export{Ce as PublicViewer};
1
+ import{j as e,c as U,b as G,d as I,e as Y,f as q,g as _,F as z,S as K,C as X,D as Q,h as J,T as Z,G as ee,W as re,i as te,H as se,k as ae,l as le,m as ce,P as oe,n as ne,B as ie,L as de,a as he,o as xe}from"./index-DcNtdUoV.js";import{a as f}from"./echarts-DtOYsfLX.js";function me({title:a,description:l,loading:r=!1,error:i=null,cached:t,durationMs:c,hasDrillDown:b,onRefresh:s,children:u}){return e.jsxs("div",{className:"chart-container",children:[e.jsxs("div",{className:"flex items-start justify-between p-4 border-b",style:{borderColor:"var(--yc-color-border)"},children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h2",{className:"text-lg font-semibold",style:{color:"var(--yc-color-text)"},children:a}),b&&e.jsxs("svg",{className:"w-4 h-4 flex-shrink-0",style:{color:"var(--yc-color-text-muted)"},viewBox:"0 0 20 20",fill:"currentColor","aria-hidden":"true",children:[e.jsx("title",{children:"Right-click to drill down"}),e.jsx("path",{fillRule:"evenodd",d:"M5.22 14.78a.75.75 0 001.06 0l7.22-7.22v5.69a.75.75 0 001.5 0v-7.5a.75.75 0 00-.75-.75h-7.5a.75.75 0 000 1.5h5.69l-7.22 7.22a.75.75 0 000 1.06z",clipRule:"evenodd"})]})]}),l&&e.jsx("p",{className:"text-sm mt-1",style:{color:"var(--yc-color-text-secondary)"},children:l})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[t!==void 0&&e.jsx("span",{className:"text-xs px-2 py-1 rounded",style:t?{backgroundColor:"color-mix(in srgb, var(--yc-color-success) 15%, transparent)",color:"var(--yc-color-success)"}:{backgroundColor:"color-mix(in srgb, var(--yc-color-primary) 15%, transparent)",color:"var(--yc-color-primary)"},children:t?"Cached":"Fresh"}),c!==void 0&&e.jsxs("span",{className:"text-xs",style:{color:"var(--yc-color-text-muted)"},children:[c,"ms"]}),s&&e.jsx("button",{onClick:s,disabled:r,className:"p-1.5 hover:bg-black/5 rounded transition-colors disabled:opacity-50",style:{color:"var(--yc-color-text-muted)"},title:"Refresh",children:e.jsx("svg",{className:U("w-4 h-4",r&&"animate-spin"),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})})})]})]}),e.jsx("div",{className:"p-4",children:i?e.jsx("div",{className:"flex items-center justify-center h-64",style:{color:"var(--yc-color-danger)"},children:e.jsxs("div",{className:"text-center",children:[e.jsx("p",{className:"font-medium",children:"Failed to load chart"}),e.jsx("p",{className:"text-sm mt-1",children:i.message})]})}):u})]})}const ue={day:{label:"Date",format:"%b %d, %Y"},week:{label:"Week Starting",format:"%b %d"},month:{label:"Month",format:"%b '%y"},quarter:{label:"Quarter",format:"quarter"},year:{label:"Year",format:"%Y"}};function ye({chartName:a}){const[l,r]=f.useState(!1),i=async()=>{const t=`{{${a}}}`;try{await navigator.clipboard.writeText(t),r(!0),setTimeout(()=>r(!1),2e3)}catch(c){console.error("Failed to copy:",c)}};return e.jsx("button",{onClick:i,className:"text-sm flex items-center gap-1.5 px-2 py-1 rounded hover:bg-black/5 transition-colors",style:{color:"var(--yc-color-text-secondary)"},title:`Copy {{${a}}} for use in markdown widgets`,children:l?e.jsxs(e.Fragment,{children:[e.jsx("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",style:{color:"var(--yc-color-success)"},children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})}),e.jsx("span",{style:{color:"var(--yc-color-success)"},children:"Copied!"})]}):e.jsxs(e.Fragment,{children:[e.jsx("svg",{className:"w-4 h-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"})}),e.jsx("span",{children:"Copy Reference"})]})})}function F(a,l){if(!l)return a.toLocaleString();const r=l.decimals??0;switch(l.type){case"currency":return new Intl.NumberFormat("en-US",{style:"currency",currency:l.currency||"USD",minimumFractionDigits:r,maximumFractionDigits:r}).format(a);case"percent":return new Intl.NumberFormat("en-US",{style:"percent",minimumFractionDigits:r,maximumFractionDigits:r}).format(a/100);default:return a.toLocaleString(void 0,{minimumFractionDigits:r,maximumFractionDigits:r})}}function fe(a,l){const r=a>=0?"+":"";return l==="percent_change"?`${r}${a.toFixed(1)}%`:`${r}${a.toLocaleString()}`}function ve({data:a,config:l,title:r,comparison:i}){var p,n,j;if(!(a!=null&&a[0])||!((p=l.value)!=null&&p.field))return e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-muted)"},children:"No data available"});const t=a[0],c=t[l.value.field],b=F(c,l.format);let s=null,u="percent_change",C,w,v;if(i)s=i.change,u=i.changeType,C=i.currentPeriodLabel,w=i.previousPeriodLabel,v=F(i.previousValue,l.format);else if((n=l.comparison)!=null&&n.enabled&&l.comparison.field){const x=t[l.comparison.field];u=l.comparison.type,x&&x!==0&&(u==="percent_change"?s=(c-x)/x*100:s=c-x,v=F(x,l.format))}const h=l.goal,g=h&&h.value!==0?Math.max(0,Math.min(c/h.value*100,100)):null,N=h?c>=h.value?"var(--yc-color-success)":"var(--yc-color-danger)":void 0;return e.jsxs("div",{className:"h-80 flex flex-col items-center justify-center p-8",children:[e.jsxs("div",{className:"text-6xl font-bold tabular-nums",style:{color:"var(--yc-color-text)"},children:[b,l.unit&&e.jsx("span",{className:"text-3xl font-normal ml-2",style:{color:"var(--yc-color-text-muted)"},children:l.unit})]}),C&&e.jsx("div",{className:"text-sm mt-2",style:{color:"var(--yc-color-text-muted)"},children:C}),r&&e.jsx("div",{className:"text-lg mt-3",style:{color:"var(--yc-color-text-secondary)"},children:r}),s!==null&&e.jsxs("div",{className:"mt-4 flex flex-col items-center gap-1",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:"text-lg font-medium px-3 py-1 rounded",style:s>=0?{backgroundColor:"color-mix(in srgb, var(--yc-color-success) 15%, transparent)",color:"var(--yc-color-success)"}:{backgroundColor:"color-mix(in srgb, var(--yc-color-danger) 15%, transparent)",color:"var(--yc-color-danger)"},children:fe(s,u)}),v&&e.jsxs("span",{className:"text-sm",style:{color:"var(--yc-color-text-muted)"},children:["vs ",v]}),!v&&((j=l.comparison)==null?void 0:j.label)&&e.jsx("span",{className:"text-sm",style:{color:"var(--yc-color-text-muted)"},children:l.comparison.label})]}),w&&e.jsx("div",{className:"text-xs",style:{color:"var(--yc-color-text-muted)"},children:w})]}),h&&g!==null&&e.jsxs("div",{className:"mt-4 w-full max-w-[280px]",children:[h.show_progress&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex justify-between text-sm mb-1",style:{color:"var(--yc-color-text-muted)"},children:[e.jsxs("span",{children:[F(c,l.format)," / ",F(h.value,l.format)]}),e.jsxs("span",{children:[g.toFixed(0),"%"]})]}),e.jsx("div",{className:"w-full h-2 rounded-full",style:{backgroundColor:"var(--yc-color-surface-hover)"},children:e.jsx("div",{className:"h-full rounded-full transition-all duration-500",style:{width:`${g}%`,backgroundColor:N}})})]}),h.label&&e.jsx("div",{className:"text-sm mt-1 text-center",style:{color:"var(--yc-color-text-muted)"},children:h.label})]})]})}function ge({chartName:a,drillParams:l}){var S,$,T,V,R,B;const{data:r,isLoading:i}=G(a),{data:t,isLoading:c,error:b}=I(a),{data:s}=Y(),u=q(),C=_(o=>o.getEffectiveFilters),w=_(o=>o.setChartFilter),v=i||c,h=l==null?void 0:l._from,g=l?Object.fromEntries(Object.entries(l).filter(([o])=>!o.startsWith("_"))):{},N=Object.keys(g).length>0,p=Object.entries(g).map(([o,d])=>`${o}: ${d}`).join(", ");f.useEffect(()=>{if(N)for(const[o,d]of Object.entries(g))w(a,o,d)},[a,N]);const[n,j]=f.useState(null),x=f.useCallback((o,d,y)=>{j({x:y.x,y:y.y,field:o,value:d})},[]),E=f.useCallback(()=>{var k,D;if(!n||!((k=r==null?void 0:r.drillDown)!=null&&k.model))return;const o=r.drillDown,d=o.fields?typeof o.fields=="string"?o.fields:o.fields[0]:o.field??((D=r.chart.x)==null?void 0:D.field)??n.field,y=new URLSearchParams;if(n.allFields)for(const[P,H]of Object.entries(n.allFields))y.set(P,H);else y.set(d,n.value);y.set("_from",a),window.location.hash=`/charts/${a}/detail?${y.toString()}`,j(null)},[n,r,a]),W=f.useCallback(()=>{var k,D;if(!n||!((k=r==null?void 0:r.drillDown)!=null&&k.chart))return;const o=r.drillDown,d=o.fields?typeof o.fields=="string"?o.fields:o.fields[0]:o.field??((D=r.chart.x)==null?void 0:D.field)??n.field,y=new URLSearchParams({[d]:n.value,_from:a});window.location.hash=`/charts/${r.drillDown.chart}?${y.toString()}`,j(null)},[n,r,a]),M=C(a).granularity,m=M?ue[M]:void 0,L=m==null?void 0:m.label,A=m==null?void 0:m.format;if(i)return e.jsxs("div",{className:"chart-container animate-pulse",children:[e.jsx("div",{className:"p-4 border-b",style:{borderColor:"var(--yc-color-border)"},children:e.jsx("div",{className:"h-6 rounded w-48",style:{backgroundColor:"var(--yc-color-surface-hover)"}})}),e.jsx("div",{className:"p-4",children:e.jsx("div",{className:"h-80 rounded",style:{backgroundColor:"var(--yc-color-surface-hover)"}})})]});if(!r)return e.jsxs("div",{className:"chart-container p-8 text-center",style:{color:"var(--yc-color-text-secondary)"},children:["Chart not found: ",a]});const O=()=>{if(!t)return e.jsx("div",{className:"h-80 rounded animate-pulse",style:{backgroundColor:"var(--yc-color-surface-hover)"}});const o=r.chart.type;switch(o){case"line":if(!r.chart.x||!r.chart.y&&!r.chart.series)return e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-secondary)"},children:"Missing axis configuration"});{const d=m?{...r.chart.x,label:L,format:A}:r.chart.x;return e.jsx(de,{data:t.rows,columns:t.columns,xAxis:d,yAxis:r.chart.y,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c,onChartClick:x,goalData:t.goalData})}case"bar":if(!r.chart.x||!r.chart.y&&!r.chart.series)return e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-secondary)"},children:"Missing axis configuration"});{const d=m?{...r.chart.x,label:L,format:A}:r.chart.x;return e.jsx(ie,{data:t.rows,xAxis:d,yAxis:r.chart.y,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c,onChartClick:x,goalData:t.goalData})}case"area":if(!r.chart.x||!r.chart.y&&!r.chart.series)return e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-secondary)"},children:"Missing axis configuration"});{const d=m?{...r.chart.x,label:L,format:A}:r.chart.x;return e.jsx(ne,{data:t.rows,xAxis:d,yAxis:r.chart.y,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c,onChartClick:x,goalData:t.goalData})}case"pie":return!r.chart.x||!r.chart.y?e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-secondary)"},children:"Missing pie chart configuration"}):e.jsx(oe,{data:t.rows,xAxis:r.chart.x,yAxis:r.chart.y,theme:s==null?void 0:s.theme,loading:c,onChartClick:x});case"donut":return!r.chart.x||!r.chart.y?e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-secondary)"},children:"Missing donut chart configuration"}):e.jsx(ce,{data:t.rows,xAxis:r.chart.x,yAxis:r.chart.y,centerValue:r.chart.centerValue,theme:s==null?void 0:s.theme,loading:c,onChartClick:x});case"scatter":return!r.chart.x||!r.chart.y?e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-secondary)"},children:"Missing axis configuration"}):e.jsx(le,{data:t.rows,xAxis:r.chart.x,yAxis:r.chart.y,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c});case"combo":if(!r.chart.x)return e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-secondary)"},children:"Missing axis configuration"});{const d=m?{...r.chart.x,label:L,format:A}:r.chart.x;return e.jsx(ae,{data:t.rows,xAxis:d,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c,onChartClick:x,goalData:t.goalData})}case"kpi":return e.jsx(ve,{data:t.rows,config:r.chart,title:r.title,comparison:t.comparison});case"heatmap":return!r.chart.x||!r.chart.y?e.jsx("div",{className:"h-80 flex items-center justify-center",style:{color:"var(--yc-color-text-secondary)"},children:"Missing axis configuration"}):e.jsx(se,{data:t.rows,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c});case"funnel":return e.jsx(te,{data:t.rows,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c});case"waterfall":return e.jsx(re,{data:t.rows,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c});case"gauge":return e.jsx(ee,{data:t.rows,chartConfig:r.chart,theme:s==null?void 0:s.theme,loading:c});case"table":return e.jsx(Z,{data:t.rows,columns:t.columns,chartConfig:r.chart,height:"100%",loading:c});default:return e.jsxs("div",{className:"h-80 flex items-center justify-center text-gray-500",children:['Chart type "',o,'" not yet implemented']})}};return e.jsxs("div",{className:"space-y-4",children:[h&&e.jsxs("div",{className:"flex items-center gap-2 text-sm",style:{color:"var(--yc-color-text-secondary)"},children:[e.jsx("button",{onClick:()=>{window.location.hash=`/charts/${h}`},className:"transition-colors hover:opacity-80",style:{color:"var(--yc-color-primary)"},children:h}),e.jsx("span",{children:"/"}),e.jsx("span",{className:"font-medium",style:{color:"var(--yc-color-text)"},children:r.title}),p&&e.jsxs("span",{style:{color:"var(--yc-color-text-muted)"},children:["(",p,")"]})]}),e.jsxs("div",{className:"flex flex-wrap items-end justify-between gap-4",children:[r.parameters.length>0?e.jsx(z,{parameters:r.parameters,chartName:a}):e.jsx("div",{}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(ye,{chartName:a}),e.jsx(K,{resourceType:"chart",resourceName:a})]})]}),e.jsx(me,{title:r.title,description:r.description,loading:v,cached:t==null?void 0:t.meta.cached,durationMs:t==null?void 0:t.meta.durationMs,hasDrillDown:!!((S=r.drillDown)!=null&&S.chart),onRefresh:()=>u(a),children:e.jsx(X,{isLoading:c,error:b,data:t==null?void 0:t.rows,onRetry:()=>u(a),children:O()})}),N&&t&&e.jsx(Q,{data:t.rows,columns:t.columns,drillDownColumns:($=r.drillDown)==null?void 0:$.columns,filterDisplay:p,chartName:a}),n&&e.jsx(J,{x:n.x,y:n.y,field:n.field,value:n.value,allFields:n.allFields,onViewDetails:(T=r.drillDown)!=null&&T.model?E:void 0,onGoToChart:(V=r.drillDown)!=null&&V.chart?W:void 0,detailModel:(R=r.drillDown)==null?void 0:R.model,targetChart:(B=r.drillDown)==null?void 0:B.chart,onClose:()=>j(null)})]})}function Ce({parsed:a}){const l=a.params.token,[r,i]=f.useState(null),[t,c]=f.useState(!1);return f.useEffect(()=>{if(!l){i("No share token provided");return}he.getPublicConfig(l).then(()=>c(!0)).catch(()=>i("This link has expired or been revoked"))},[l]),r?e.jsx("div",{className:"min-h-screen bg-gray-50 flex items-center justify-center",children:e.jsx("div",{className:"text-center",children:e.jsx("div",{className:"text-gray-400 text-lg",children:r})})}):t?e.jsxs("div",{className:"min-h-screen bg-gray-50",children:[e.jsx("div",{className:"max-w-7xl mx-auto py-6 px-4",children:a.type==="public_chart"?e.jsx(ge,{chartName:a.name}):e.jsx(xe,{dashboardId:a.name,initialTab:a.params.tab})}),e.jsx("div",{className:"text-center py-4 text-xs text-gray-400",children:"Shared via yamchart"})]}):e.jsx("div",{className:"min-h-screen bg-gray-50 flex items-center justify-center",children:e.jsx("div",{className:"text-gray-500",children:"Loading..."})})}export{Ce as PublicViewer};
@@ -1 +1 @@
1
- import{u as g,j as e,A as h}from"./index-B41yj3io.js";import{a as o}from"./echarts-DtOYsfLX.js";function j(){const m=g(r=>r.setup),[a,b]=o.useState(""),[l,x]=o.useState(""),[t,p]=o.useState(""),[c,y]=o.useState(""),[n,s]=o.useState(""),[d,u]=o.useState(!1),f=async r=>{if(r.preventDefault(),s(""),t!==c){s("Passwords do not match");return}if(t.length<8){s("Password must be at least 8 characters");return}u(!0);try{await m(a,l,t)}catch(i){i instanceof h?s(i.message):s("An unexpected error occurred")}finally{u(!1)}};return e.jsx("div",{className:"min-h-screen flex items-center justify-center",style:{backgroundColor:"var(--yc-color-background)"},children:e.jsxs("div",{className:"rounded-lg shadow-sm p-8 w-full max-w-md",style:{backgroundColor:"var(--yc-color-surface)",border:"1px solid var(--yc-color-border)"},children:[e.jsx("h1",{className:"text-2xl font-semibold mb-2",style:{color:"var(--yc-color-text)"},children:"Welcome to Yamchart"}),e.jsx("p",{className:"text-sm mb-6",style:{color:"var(--yc-color-text-secondary)"},children:"Create your admin account to get started."}),n&&e.jsx("div",{className:"text-sm rounded-md px-4 py-3 mb-4",style:{backgroundColor:"color-mix(in srgb, var(--yc-color-danger) 10%, transparent)",border:"1px solid color-mix(in srgb, var(--yc-color-danger) 30%, transparent)",color:"var(--yc-color-danger)"},children:n}),e.jsxs("form",{onSubmit:f,className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:"name",className:"block text-sm font-medium mb-1",style:{color:"var(--yc-color-text-secondary)"},children:"Name"}),e.jsx("input",{id:"name",type:"text",value:l,onChange:r=>x(r.target.value),required:!0,className:"w-full px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",style:{backgroundColor:"var(--yc-color-input-bg)",color:"var(--yc-color-text)",borderColor:"var(--yc-color-border)"},placeholder:"Your Name"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"setup-email",className:"block text-sm font-medium mb-1",style:{color:"var(--yc-color-text-secondary)"},children:"Email"}),e.jsx("input",{id:"setup-email",type:"email",value:a,onChange:r=>b(r.target.value),required:!0,className:"w-full px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",style:{backgroundColor:"var(--yc-color-input-bg)",color:"var(--yc-color-text)",borderColor:"var(--yc-color-border)"},placeholder:"admin@example.com"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"setup-password",className:"block text-sm font-medium mb-1",style:{color:"var(--yc-color-text-secondary)"},children:"Password"}),e.jsx("input",{id:"setup-password",type:"password",value:t,onChange:r=>p(r.target.value),required:!0,minLength:8,className:"w-full px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",style:{backgroundColor:"var(--yc-color-input-bg)",color:"var(--yc-color-text)",borderColor:"var(--yc-color-border)"},placeholder:"At least 8 characters"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"confirm-password",className:"block text-sm font-medium mb-1",style:{color:"var(--yc-color-text-secondary)"},children:"Confirm Password"}),e.jsx("input",{id:"confirm-password",type:"password",value:c,onChange:r=>y(r.target.value),required:!0,className:"w-full px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",style:{backgroundColor:"var(--yc-color-input-bg)",color:"var(--yc-color-text)",borderColor:"var(--yc-color-border)"},placeholder:"Confirm password"})]}),e.jsx("button",{type:"submit",disabled:d,className:"w-full py-2 px-4 bg-blue-600 text-white text-sm font-medium rounded-md hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed",children:d?"Creating account...":"Create Admin Account"})]})]})})}export{j as SetupWizard};
1
+ import{u as g,j as e,A as h}from"./index-DcNtdUoV.js";import{a as o}from"./echarts-DtOYsfLX.js";function j(){const m=g(r=>r.setup),[a,b]=o.useState(""),[l,x]=o.useState(""),[t,p]=o.useState(""),[c,y]=o.useState(""),[n,s]=o.useState(""),[d,u]=o.useState(!1),f=async r=>{if(r.preventDefault(),s(""),t!==c){s("Passwords do not match");return}if(t.length<8){s("Password must be at least 8 characters");return}u(!0);try{await m(a,l,t)}catch(i){i instanceof h?s(i.message):s("An unexpected error occurred")}finally{u(!1)}};return e.jsx("div",{className:"min-h-screen flex items-center justify-center",style:{backgroundColor:"var(--yc-color-background)"},children:e.jsxs("div",{className:"rounded-lg shadow-sm p-8 w-full max-w-md",style:{backgroundColor:"var(--yc-color-surface)",border:"1px solid var(--yc-color-border)"},children:[e.jsx("h1",{className:"text-2xl font-semibold mb-2",style:{color:"var(--yc-color-text)"},children:"Welcome to Yamchart"}),e.jsx("p",{className:"text-sm mb-6",style:{color:"var(--yc-color-text-secondary)"},children:"Create your admin account to get started."}),n&&e.jsx("div",{className:"text-sm rounded-md px-4 py-3 mb-4",style:{backgroundColor:"color-mix(in srgb, var(--yc-color-danger) 10%, transparent)",border:"1px solid color-mix(in srgb, var(--yc-color-danger) 30%, transparent)",color:"var(--yc-color-danger)"},children:n}),e.jsxs("form",{onSubmit:f,className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{htmlFor:"name",className:"block text-sm font-medium mb-1",style:{color:"var(--yc-color-text-secondary)"},children:"Name"}),e.jsx("input",{id:"name",type:"text",value:l,onChange:r=>x(r.target.value),required:!0,className:"w-full px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",style:{backgroundColor:"var(--yc-color-input-bg)",color:"var(--yc-color-text)",borderColor:"var(--yc-color-border)"},placeholder:"Your Name"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"setup-email",className:"block text-sm font-medium mb-1",style:{color:"var(--yc-color-text-secondary)"},children:"Email"}),e.jsx("input",{id:"setup-email",type:"email",value:a,onChange:r=>b(r.target.value),required:!0,className:"w-full px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",style:{backgroundColor:"var(--yc-color-input-bg)",color:"var(--yc-color-text)",borderColor:"var(--yc-color-border)"},placeholder:"admin@example.com"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"setup-password",className:"block text-sm font-medium mb-1",style:{color:"var(--yc-color-text-secondary)"},children:"Password"}),e.jsx("input",{id:"setup-password",type:"password",value:t,onChange:r=>p(r.target.value),required:!0,minLength:8,className:"w-full px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",style:{backgroundColor:"var(--yc-color-input-bg)",color:"var(--yc-color-text)",borderColor:"var(--yc-color-border)"},placeholder:"At least 8 characters"})]}),e.jsxs("div",{children:[e.jsx("label",{htmlFor:"confirm-password",className:"block text-sm font-medium mb-1",style:{color:"var(--yc-color-text-secondary)"},children:"Confirm Password"}),e.jsx("input",{id:"confirm-password",type:"password",value:c,onChange:r=>y(r.target.value),required:!0,className:"w-full px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",style:{backgroundColor:"var(--yc-color-input-bg)",color:"var(--yc-color-text)",borderColor:"var(--yc-color-border)"},placeholder:"Confirm password"})]}),e.jsx("button",{type:"submit",disabled:d,className:"w-full py-2 px-4 bg-blue-600 text-white text-sm font-medium rounded-md hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed",children:d?"Creating account...":"Create Admin Account"})]})]})})}export{j as SetupWizard};