yamchart 0.3.6 → 0.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-7HKIUUVE.js → chunk-ENOTMVPI.js} +27 -4
- package/dist/{chunk-7HKIUUVE.js.map → chunk-ENOTMVPI.js.map} +1 -1
- package/dist/{dev-PWY7UVIO.js → dev-CPZ3M5EE.js} +134 -70
- package/dist/dev-CPZ3M5EE.js.map +1 -0
- package/dist/index.js +2 -2
- package/dist/public/assets/{index-DY3hJB9N.js → index-D9hfHuVH.js} +99 -99
- package/dist/public/assets/{index-ogBV05Wr.css → index-xXsNnf9d.css} +1 -1
- package/dist/public/assets/{index.es-DTRIdI7C.js → index.es-B4AYqvku.js} +1 -1
- package/dist/public/index.html +2 -2
- package/package.json +4 -4
- package/dist/dev-PWY7UVIO.js.map +0 -1
|
@@ -523,15 +523,38 @@ var LayoutSchema = z5.object({
|
|
|
523
523
|
gap: z5.number().min(0).default(16),
|
|
524
524
|
rows: z5.array(RowSchema).min(1)
|
|
525
525
|
});
|
|
526
|
+
var TabSchema = z5.object({
|
|
527
|
+
name: z5.string().min(1),
|
|
528
|
+
label: z5.string().min(1),
|
|
529
|
+
filters: z5.array(ParameterSchema).optional(),
|
|
530
|
+
layout: LayoutSchema
|
|
531
|
+
});
|
|
526
532
|
var DashboardSchema = z5.object({
|
|
527
533
|
// Identity
|
|
528
534
|
name: z5.string().min(1),
|
|
529
535
|
title: z5.string().min(1),
|
|
530
536
|
description: z5.string().optional(),
|
|
531
|
-
// Filters inherited by all widgets
|
|
537
|
+
// Filters inherited by all widgets (shared across tabs)
|
|
532
538
|
filters: z5.array(ParameterSchema).optional(),
|
|
533
|
-
// Layout definition
|
|
534
|
-
layout: LayoutSchema
|
|
539
|
+
// Layout definition (mutually exclusive with tabs)
|
|
540
|
+
layout: LayoutSchema.optional(),
|
|
541
|
+
// Tabbed layout
|
|
542
|
+
tabs: z5.array(TabSchema).min(1).optional()
|
|
543
|
+
}).superRefine((data, ctx) => {
|
|
544
|
+
if (data.layout && data.tabs) {
|
|
545
|
+
ctx.addIssue({
|
|
546
|
+
code: z5.ZodIssueCode.custom,
|
|
547
|
+
message: 'Dashboard must have either "layout" or "tabs", not both',
|
|
548
|
+
path: ["tabs"]
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
if (!data.layout && !data.tabs) {
|
|
552
|
+
ctx.addIssue({
|
|
553
|
+
code: z5.ZodIssueCode.custom,
|
|
554
|
+
message: 'Dashboard must have either "layout" or "tabs"',
|
|
555
|
+
path: []
|
|
556
|
+
});
|
|
557
|
+
}
|
|
535
558
|
});
|
|
536
559
|
|
|
537
560
|
// ../../packages/schema/dist/schedule.js
|
|
@@ -936,4 +959,4 @@ export {
|
|
|
936
959
|
findProjectRoot,
|
|
937
960
|
loadEnvFile
|
|
938
961
|
};
|
|
939
|
-
//# sourceMappingURL=chunk-
|
|
962
|
+
//# sourceMappingURL=chunk-ENOTMVPI.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/commands/validate.ts","../../../packages/schema/src/connection.ts","../../../packages/schema/src/chart.ts","../../../packages/schema/src/project.ts","../../../packages/schema/src/model.ts","../../../packages/schema/src/dashboard.ts","../../../packages/schema/src/schedule.ts","../src/utils/config.ts"],"sourcesContent":["import { readFile, readdir, access } from 'fs/promises';\nimport { join, extname, relative } from 'path';\nimport { parse as parseYaml } from 'yaml';\nimport {\n ProjectSchema,\n ConnectionSchema,\n ChartSchema,\n DashboardSchema,\n ScheduleSchema,\n type Schedule,\n} from '@yamchart/schema';\nimport type { ZodError } from 'zod';\nimport { parseModelMetadata } from '@yamchart/query';\n\nfunction formatZodErrors(error: ZodError): string[] {\n return error.errors.map((e) => {\n const path = e.path.length > 0 ? e.path.join('.') : '(root)';\n return `${path}: ${e.message}`;\n });\n}\n\nexport interface ValidationError {\n file: string;\n line?: number;\n message: string;\n suggestion?: string;\n}\n\nexport interface ValidationResult {\n success: boolean;\n errors: ValidationError[];\n warnings: ValidationError[];\n stats: {\n files: number;\n passed: number;\n failed: number;\n };\n dryRunStats?: {\n passed: number;\n failed: number;\n };\n}\n\nexport interface ValidateOptions {\n dryRun: boolean;\n connection?: string;\n}\n\ninterface LoadedConfig {\n project: { name: string; version: string; defaults?: { connection?: string } } | null;\n connections: Map<string, { name: string; type: string }>;\n models: Map<string, { name: string; sql: string }>;\n charts: Map<string, { name: string; source: { model?: string; sql?: string } }>;\n dashboards: Map<string, { name: string; layout: unknown }>;\n schedules: Map<string, Schedule>;\n}\n\nexport async function validateProject(\n projectDir: string,\n options: ValidateOptions\n): Promise<ValidationResult> {\n const errors: ValidationError[] = [];\n const warnings: ValidationError[] = [];\n let filesChecked = 0;\n let filesPassed = 0;\n\n const config: LoadedConfig = {\n project: null,\n connections: new Map(),\n models: new Map(),\n charts: new Map(),\n dashboards: new Map(),\n schedules: new Map(),\n };\n\n // Phase 1: Schema validation\n\n // Validate yamchart.yaml\n const projectPath = join(projectDir, 'yamchart.yaml');\n try {\n await access(projectPath);\n filesChecked++;\n const content = await readFile(projectPath, 'utf-8');\n const parsed = parseYaml(content);\n const result = ProjectSchema.safeParse(parsed);\n\n if (result.success) {\n config.project = result.data;\n filesPassed++;\n } else {\n errors.push({\n file: 'yamchart.yaml',\n message: `Invalid schema:\\n${formatZodErrors(result.error).map(e => ` - ${e}`).join('\\n')}`,\n });\n }\n } catch {\n errors.push({\n file: 'yamchart.yaml',\n message: 'yamchart.yaml not found',\n });\n return {\n success: false,\n errors,\n warnings,\n stats: { files: filesChecked, passed: filesPassed, failed: filesChecked - filesPassed },\n };\n }\n\n // Validate connections\n const connectionsDir = join(projectDir, 'connections');\n try {\n await access(connectionsDir);\n const files = await readdir(connectionsDir);\n\n for (const file of files) {\n if (extname(file) !== '.yaml' && extname(file) !== '.yml') continue;\n filesChecked++;\n\n const filePath = join(connectionsDir, file);\n const content = await readFile(filePath, 'utf-8');\n const parsed = parseYaml(content);\n const result = ConnectionSchema.safeParse(parsed);\n\n if (result.success) {\n config.connections.set(result.data.name, result.data);\n filesPassed++;\n } else {\n errors.push({\n file: `connections/${file}`,\n message: `Invalid schema:\\n${formatZodErrors(result.error).map(e => ` - ${e}`).join('\\n')}`,\n });\n }\n }\n } catch {\n // No connections directory is ok\n }\n\n // Validate models\n const modelsDir = join(projectDir, 'models');\n const modelStats = { filesChecked: 0, filesPassed: 0 };\n try {\n await access(modelsDir);\n await validateModelsDir(modelsDir, projectDir, config, errors, modelStats);\n filesChecked += modelStats.filesChecked;\n filesPassed += modelStats.filesPassed;\n } catch {\n // No models directory is ok\n }\n\n // Validate charts\n const chartsDir = join(projectDir, 'charts');\n try {\n await access(chartsDir);\n const files = await readdir(chartsDir);\n\n for (const file of files) {\n if (extname(file) !== '.yaml' && extname(file) !== '.yml') continue;\n filesChecked++;\n\n const filePath = join(chartsDir, file);\n const content = await readFile(filePath, 'utf-8');\n const parsed = parseYaml(content);\n const result = ChartSchema.safeParse(parsed);\n\n if (result.success) {\n config.charts.set(result.data.name, result.data);\n filesPassed++;\n } else {\n errors.push({\n file: `charts/${file}`,\n message: `Invalid schema:\\n${formatZodErrors(result.error).map(e => ` - ${e}`).join('\\n')}`,\n });\n }\n }\n } catch {\n // No charts directory is ok\n }\n\n // Validate dashboards\n const dashboardsDir = join(projectDir, 'dashboards');\n try {\n await access(dashboardsDir);\n const files = await readdir(dashboardsDir);\n\n for (const file of files) {\n if (extname(file) !== '.yaml' && extname(file) !== '.yml') continue;\n filesChecked++;\n\n const filePath = join(dashboardsDir, file);\n const content = await readFile(filePath, 'utf-8');\n const parsed = parseYaml(content);\n const result = DashboardSchema.safeParse(parsed);\n\n if (result.success) {\n config.dashboards.set(result.data.name, result.data);\n filesPassed++;\n } else {\n errors.push({\n file: `dashboards/${file}`,\n message: `Invalid schema:\\n${formatZodErrors(result.error).map(e => ` - ${e}`).join('\\n')}`,\n });\n }\n }\n } catch {\n // No dashboards directory is ok\n }\n\n // Validate schedules\n const schedulesDir = join(projectDir, 'schedules');\n try {\n await access(schedulesDir);\n const files = await readdir(schedulesDir);\n\n for (const file of files) {\n if (extname(file) !== '.yaml' && extname(file) !== '.yml') continue;\n filesChecked++;\n\n const filePath = join(schedulesDir, file);\n const content = await readFile(filePath, 'utf-8');\n const parsed = parseYaml(content);\n const result = ScheduleSchema.safeParse(parsed);\n\n if (result.success) {\n config.schedules.set(result.data.name, result.data);\n filesPassed++;\n } else {\n errors.push({\n file: `schedules/${file}`,\n message: `Invalid schema:\\n${formatZodErrors(result.error).map(e => ` - ${e}`).join('\\n')}`,\n });\n }\n }\n } catch {\n // No schedules directory is ok\n }\n\n // Phase 2: Cross-reference validation\n crossReferenceValidation(config, errors, warnings);\n\n // Phase 3: Dry-run query validation (if enabled)\n let dryRunStats: { passed: number; failed: number } | undefined;\n if (options.dryRun) {\n dryRunStats = await dryRunValidation(projectDir, config, options.connection, errors);\n }\n\n return {\n success: errors.length === 0,\n errors,\n warnings,\n stats: {\n files: filesChecked,\n passed: filesPassed,\n failed: filesChecked - filesPassed,\n },\n dryRunStats,\n };\n}\n\nasync function validateModelsDir(\n dir: string,\n projectDir: string,\n config: LoadedConfig,\n errors: ValidationError[],\n stats: { filesChecked: number; filesPassed: number }\n): Promise<void> {\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n await validateModelsDir(fullPath, projectDir, config, errors, stats);\n } else if (extname(entry.name) === '.sql') {\n stats.filesChecked++;\n const relPath = relative(projectDir, fullPath);\n const content = await readFile(fullPath, 'utf-8');\n\n try {\n const parsed = parseModelMetadata(content);\n config.models.set(parsed.name, { name: parsed.name, sql: parsed.sql });\n stats.filesPassed++;\n } catch (err) {\n errors.push({\n file: relPath,\n message: err instanceof Error ? err.message : 'Failed to parse model',\n });\n }\n }\n }\n}\n\nfunction crossReferenceValidation(\n config: LoadedConfig,\n errors: ValidationError[],\n warnings: ValidationError[]\n): void {\n // Check that charts reference existing models\n for (const [chartName, chart] of config.charts) {\n if (chart.source.model && !config.models.has(chart.source.model)) {\n const suggestion = findSimilar(chart.source.model, Array.from(config.models.keys()));\n errors.push({\n file: `charts/${chartName}.yaml`,\n message: `Unknown model reference \"${chart.source.model}\"`,\n suggestion: suggestion ? `Did you mean \"${suggestion}\"?` : undefined,\n });\n }\n }\n\n // Check that schedules reference existing charts\n for (const [scheduleName, schedule] of config.schedules) {\n const chartNames = schedule.type === 'report' ? schedule.charts : [schedule.chart];\n for (const chartName of chartNames) {\n if (!config.charts.has(chartName)) {\n const suggestion = findSimilar(chartName, Array.from(config.charts.keys()));\n warnings.push({\n file: `schedules/${scheduleName}.yaml`,\n message: `Unknown chart reference \"${chartName}\"`,\n suggestion: suggestion ? `Did you mean \"${suggestion}\"?` : undefined,\n });\n }\n }\n\n // Validate cron expression (basic: 5 or 6 space-separated fields)\n const cronFields = schedule.schedule.trim().split(/\\s+/);\n if (cronFields.length < 5 || cronFields.length > 6) {\n errors.push({\n file: `schedules/${scheduleName}.yaml`,\n message: `Invalid cron expression \"${schedule.schedule}\" (expected 5-6 fields)`,\n });\n }\n }\n\n // Check that default connection exists\n if (config.project?.defaults?.connection) {\n const connName = config.project.defaults.connection;\n if (!config.connections.has(connName)) {\n const suggestion = findSimilar(connName, Array.from(config.connections.keys()));\n errors.push({\n file: 'yamchart.yaml',\n message: `Default connection \"${connName}\" not found`,\n suggestion: suggestion ? `Did you mean \"${suggestion}\"?` : undefined,\n });\n }\n }\n}\n\nfunction findSimilar(target: string, candidates: string[]): string | null {\n const threshold = 3; // Levenshtein distance threshold\n\n for (const candidate of candidates) {\n if (levenshtein(target.toLowerCase(), candidate.toLowerCase()) <= threshold) {\n return candidate;\n }\n }\n return null;\n}\n\nfunction levenshtein(a: string, b: string): number {\n const matrix: number[][] = [];\n\n for (let i = 0; i <= b.length; i++) {\n matrix[i] = [i];\n }\n for (let j = 0; j <= a.length; j++) {\n matrix[0]![j] = j;\n }\n\n for (let i = 1; i <= b.length; i++) {\n for (let j = 1; j <= a.length; j++) {\n if (b.charAt(i - 1) === a.charAt(j - 1)) {\n matrix[i]![j] = matrix[i - 1]![j - 1]!;\n } else {\n matrix[i]![j] = Math.min(\n matrix[i - 1]![j - 1]! + 1,\n matrix[i]![j - 1]! + 1,\n matrix[i - 1]![j]! + 1\n );\n }\n }\n }\n\n return matrix[b.length]![a.length]!;\n}\n\nasync function dryRunValidation(\n projectDir: string,\n config: LoadedConfig,\n connectionName: string | undefined,\n errors: ValidationError[]\n): Promise<{ passed: number; failed: number }> {\n const { DuckDBConnector } = await import('@yamchart/query');\n\n let passed = 0;\n let failed = 0;\n\n // Determine which connection to use\n const connName = connectionName || config.project?.defaults?.connection;\n if (!connName) {\n errors.push({\n file: 'yamchart.yaml',\n message: 'No connection specified for dry-run (use --connection or set defaults.connection)',\n });\n return { passed, failed: 1 };\n }\n\n const connection = config.connections.get(connName);\n if (!connection) {\n errors.push({\n file: 'yamchart.yaml',\n message: `Connection \"${connName}\" not found`,\n });\n return { passed, failed: 1 };\n }\n\n // Only DuckDB supported for now\n if (connection.type !== 'duckdb') {\n errors.push({\n file: `connections/${connName}.yaml`,\n message: `Dry-run not yet supported for connection type \"${connection.type}\"`,\n });\n return { passed, failed: 1 };\n }\n\n // Load full connection config to get path\n const connPath = join(projectDir, 'connections', `${connName}.yaml`);\n const connContent = await readFile(connPath, 'utf-8');\n const connConfig = parseYaml(connContent) as { config: { path: string } };\n\n // Resolve path relative to project\n const dbPath = connConfig.config.path.startsWith('/')\n ? connConfig.config.path\n : join(projectDir, connConfig.config.path);\n\n const connector = new DuckDBConnector({ path: dbPath });\n\n try {\n await connector.connect();\n\n for (const [modelName, model] of config.models) {\n const result = await connector.explain(model.sql);\n\n if (result.valid) {\n passed++;\n } else {\n failed++;\n errors.push({\n file: `models/${modelName}.sql`,\n message: result.error || 'Query validation failed',\n });\n }\n }\n } finally {\n await connector.disconnect();\n }\n\n return { passed, failed };\n}\n","import { z } from 'zod';\n\n// Auth configuration for connections\nconst EnvAuthSchema = z.object({\n type: z.literal('env'),\n user_var: z.string(),\n password_var: z.string(),\n});\n\nconst KeyPairAuthSchema = z.object({\n type: z.literal('key_pair'),\n user_var: z.string(),\n private_key_path: z.string(),\n});\n\nconst SecretManagerAuthSchema = z.object({\n type: z.literal('secret_manager'),\n provider: z.enum(['aws_secrets_manager', 'gcp_secret_manager', 'vault']),\n secret_id: z.string(),\n});\n\nconst ExternalBrowserAuthSchema = z.object({\n type: z.literal('externalbrowser'),\n user_var: z.string(),\n cache_token: z.boolean().optional(),\n});\n\nconst AuthSchema = z.discriminatedUnion('type', [\n EnvAuthSchema,\n KeyPairAuthSchema,\n SecretManagerAuthSchema,\n ExternalBrowserAuthSchema,\n]);\n\n// Connection pool configuration\nconst PoolConfigSchema = z.object({\n min_connections: z.number().int().positive().optional(),\n max_connections: z.number().int().positive().optional(),\n idle_timeout: z.number().int().positive().optional(),\n});\n\n// Query settings\nconst QueryConfigSchema = z.object({\n timeout: z.number().int().positive().optional(),\n max_rows: z.number().int().positive().optional(),\n});\n\n// DuckDB-specific config\nconst DuckDBConfigSchema = z.object({\n path: z.string(), // file path or :memory:\n});\n\n// Postgres-specific config\nconst PostgresConfigSchema = z.object({\n host: z.string(),\n port: z.number().int().positive().default(5432),\n database: z.string(),\n schema: z.string().optional(),\n ssl: z.boolean().optional(),\n});\n\n// Snowflake-specific config\nconst SnowflakeConfigSchema = z.object({\n account: z.string(),\n warehouse: z.string(),\n database: z.string(),\n schema: z.string().optional(),\n role: z.string().optional(),\n});\n\n// MySQL-specific config\nconst MySQLConfigSchema = z.object({\n host: z.string(),\n port: z.number().int().positive().default(3306),\n database: z.string(),\n ssl: z.boolean().optional(),\n});\n\n// SQLite-specific config\nconst SQLiteConfigSchema = z.object({\n path: z.string(), // file path or :memory:\n});\n\n// Base connection schema\nconst BaseConnectionSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n pool: PoolConfigSchema.optional(),\n query: QueryConfigSchema.optional(),\n});\n\n// Type-specific connection schemas\nconst DuckDBConnectionSchema = BaseConnectionSchema.extend({\n type: z.literal('duckdb'),\n config: DuckDBConfigSchema,\n auth: z.undefined().optional(),\n});\n\nconst PostgresConnectionSchema = BaseConnectionSchema.extend({\n type: z.literal('postgres'),\n config: PostgresConfigSchema,\n auth: AuthSchema.optional(),\n});\n\nconst SnowflakeConnectionSchema = BaseConnectionSchema.extend({\n type: z.literal('snowflake'),\n config: SnowflakeConfigSchema,\n auth: AuthSchema,\n});\n\nconst MySQLConnectionSchema = BaseConnectionSchema.extend({\n type: z.literal('mysql'),\n config: MySQLConfigSchema,\n auth: AuthSchema.optional(),\n});\n\nconst SQLiteConnectionSchema = BaseConnectionSchema.extend({\n type: z.literal('sqlite'),\n config: SQLiteConfigSchema,\n auth: z.undefined().optional(),\n});\n\n// Union of all connection types\nexport const ConnectionSchema = z.discriminatedUnion('type', [\n DuckDBConnectionSchema,\n PostgresConnectionSchema,\n SnowflakeConnectionSchema,\n MySQLConnectionSchema,\n SQLiteConnectionSchema,\n]);\n\nexport type Connection = z.infer<typeof ConnectionSchema>;\nexport type DuckDBConnection = z.infer<typeof DuckDBConnectionSchema>;\nexport type PostgresConnection = z.infer<typeof PostgresConnectionSchema>;\nexport type SnowflakeConnection = z.infer<typeof SnowflakeConnectionSchema>;\nexport type MySQLConnection = z.infer<typeof MySQLConnectionSchema>;\nexport type SQLiteConnection = z.infer<typeof SQLiteConnectionSchema>;\n","import { z } from 'zod';\n\n// Axis types\nconst AxisTypeSchema = z.enum(['temporal', 'quantitative', 'ordinal', 'nominal']);\n\n// Axis configuration\nconst AxisSchema = z.object({\n field: z.string().min(1),\n type: AxisTypeSchema,\n format: z.string().optional(),\n label: z.string().optional(),\n});\n\n// Chart types supported (scatter has its own dedicated schema)\nconst ChartTypeSchema = z.enum([\n 'line',\n 'bar',\n 'area',\n 'pie',\n 'donut',\n 'table',\n 'metric',\n 'map',\n 'heatmap',\n 'funnel',\n 'sankey',\n 'treemap',\n 'waterfall',\n 'gauge',\n]);\n\n// Gradient configuration - boolean shorthand or explicit from/to\nconst GradientSchema = z.union([\n z.boolean(),\n z.object({\n from: z.string(),\n to: z.string(),\n }),\n]);\n\n// Long format series: group by a field in the data (one row per series value)\nconst LongFormatSeriesSchema = z.object({\n field: z.string().min(1),\n colors: z.record(z.string(), z.string()).optional(),\n});\n\n// Wide format column: each column becomes a separate series\nconst WideFormatColumnSchema = z.object({\n field: z.string().min(1),\n name: z.string().optional(),\n type: z.enum(['line', 'bar', 'area']).optional(),\n axis: z.enum(['left', 'right']).optional(),\n color: z.string().optional(),\n style: z.enum(['solid', 'dashed', 'dotted']).optional(),\n opacity: z.number().min(0).max(1).optional(),\n gradient: GradientSchema.optional(),\n});\n\n// Wide format series: explicit list of columns\nconst WideFormatSeriesSchema = z.object({\n columns: z.array(WideFormatColumnSchema).min(1),\n});\n\n// Series config is either long format (group by field) or wide format (explicit columns)\nconst SeriesConfigSchema = z.union([\n LongFormatSeriesSchema,\n WideFormatSeriesSchema,\n]);\n\n// Color condition for conditional coloring\nconst ColorConditionSchema = z.object({\n when: z.string(),\n color: z.string(),\n});\n\n// Conditional color configuration\nconst ConditionalColorSchema = z.object({\n conditions: z.array(ColorConditionSchema).min(1),\n default: z.string().optional(),\n});\n\n// Color - either a simple string or conditional config\nconst ColorSchema = z.union([\n z.string(),\n ConditionalColorSchema,\n]);\n\n// Legend configuration\nconst LegendSchema = z.object({\n show: z.boolean().optional(),\n position: z.enum(['top', 'bottom', 'left', 'right']).optional(),\n});\n\n// Annotation configuration\nconst LineAnnotationSchema = z.object({\n type: z.literal('line'),\n value: z.number(),\n label: z.string().optional(),\n color: z.string().optional(),\n style: z.enum(['solid', 'dashed', 'dotted']).optional(),\n});\n\nconst BandAnnotationSchema = z.object({\n type: z.literal('band'),\n from: z.number(),\n to: z.number(),\n label: z.string().optional(),\n color: z.string().optional(),\n});\n\nconst AnnotationSchema = z.discriminatedUnion('type', [\n LineAnnotationSchema,\n BandAnnotationSchema,\n]);\n\n// Interactivity options\nconst InteractionsSchema = z.object({\n tooltip: z.boolean().default(true),\n zoom: z.boolean().default(false),\n brush: z.boolean().default(false),\n});\n\n// KPI format types\nconst KpiFormatSchema = z.object({\n type: z.enum(['number', 'currency', 'percent']),\n currency: z.string().optional(), // e.g., 'USD', 'EUR'\n decimals: z.number().optional(),\n});\n\n// KPI comparison configuration\nconst KpiComparisonSchema = z.object({\n enabled: z.boolean(),\n field: z.string().min(1),\n label: z.string().optional(),\n type: z.enum(['percent_change', 'absolute']),\n});\n\n// KPI value configuration\nconst KpiValueSchema = z.object({\n field: z.string().min(1),\n});\n\n// KPI-specific config\nconst KpiConfigSchema = z.object({\n type: z.literal('kpi'),\n value: KpiValueSchema,\n format: KpiFormatSchema,\n comparison: KpiComparisonSchema.optional(),\n});\n\n// Center value for donut charts\nconst CenterValueSchema = z.object({\n field: z.string().optional(), // 'total' for sum, or specific field\n label: z.string().optional(),\n format: z.string().optional(),\n});\n\n// Standard chart config (existing)\nconst StandardChartConfigSchema = z.object({\n type: ChartTypeSchema,\n x: AxisSchema,\n y: AxisSchema.optional(),\n series: SeriesConfigSchema.optional(),\n stacking: z.enum(['stacked', 'percent']).optional(),\n color: ColorSchema.optional(),\n gradient: GradientSchema.optional(),\n legend: LegendSchema.optional(),\n annotations: z.array(AnnotationSchema).optional(),\n interactions: InteractionsSchema.optional(),\n centerValue: CenterValueSchema.optional(), // For donut charts\n});\n\n// Dual axes for combo charts\nconst DualAxesSchema = z.object({\n left: AxisSchema.optional(),\n right: AxisSchema.optional(),\n});\n\n// Combo chart config - requires dual axes\nconst ComboChartConfigSchema = z.object({\n type: z.literal('combo'),\n x: AxisSchema,\n series: WideFormatSeriesSchema,\n axes: DualAxesSchema,\n legend: LegendSchema.optional(),\n interactions: InteractionsSchema.optional(),\n gradient: GradientSchema.optional(),\n});\n\n// Scatter chart size encoding\nconst ScatterSizeSchema = z.object({\n field: z.string().min(1),\n min: z.number().optional(),\n max: z.number().optional(),\n label: z.string().optional(),\n});\n\n// Scatter chart grouping\nconst ScatterGroupSchema = z.object({\n field: z.string().min(1),\n});\n\n// Regression line configuration\nconst RegressionSchema = z.object({\n type: z.literal('linear'),\n show_equation: z.boolean().optional(),\n show_r_squared: z.boolean().optional(),\n});\n\n// Scatter/bubble chart config\nconst ScatterChartConfigSchema = z.object({\n type: z.literal('scatter'),\n x: AxisSchema,\n y: AxisSchema,\n size: ScatterSizeSchema.optional(),\n group: ScatterGroupSchema.optional(),\n regression: RegressionSchema.optional(),\n color: ColorSchema.optional(),\n legend: LegendSchema.optional(),\n interactions: InteractionsSchema.optional(),\n});\n\n// Heatmap chart config\nconst HeatmapChartConfigSchema = z.object({\n type: z.literal('heatmap'),\n x: AxisSchema,\n y: AxisSchema,\n value: z.object({\n field: z.string().min(1),\n label: z.string().optional(),\n }),\n color_range: z.object({\n min: z.string().optional(),\n max: z.string().optional(),\n }).optional(),\n show_values: z.boolean().optional(),\n});\n\n// Funnel chart config\nconst FunnelChartConfigSchema = z.object({\n type: z.literal('funnel'),\n stage: z.object({ field: z.string().min(1) }),\n value: z.object({ field: z.string().min(1) }),\n show_conversion: z.boolean().optional(),\n color: ColorSchema.optional(),\n});\n\n// Waterfall chart config\nconst WaterfallChartConfigSchema = z.object({\n type: z.literal('waterfall'),\n category: z.object({ field: z.string().min(1) }),\n value: z.object({ field: z.string().min(1) }),\n total_field: z.string().optional(),\n colors: z.object({\n increase: z.string().optional(),\n decrease: z.string().optional(),\n total: z.string().optional(),\n }).optional(),\n});\n\n// Gauge chart config\nconst GaugeThresholdSchema = z.object({\n value: z.number(),\n color: z.string(),\n});\n\nconst GaugeChartConfigSchema = z.object({\n type: z.literal('gauge'),\n value: z.object({ field: z.string().min(1) }),\n min: z.number().optional(),\n max: z.number().optional(),\n thresholds: z.array(GaugeThresholdSchema).optional(),\n format: z.string().optional(),\n});\n\n// Chart visualization config - standard, KPI, combo, scatter, heatmap, funnel, waterfall, or gauge\nconst ChartConfigSchema = z.union([\n ScatterChartConfigSchema,\n ComboChartConfigSchema,\n HeatmapChartConfigSchema,\n FunnelChartConfigSchema,\n WaterfallChartConfigSchema,\n GaugeChartConfigSchema,\n StandardChartConfigSchema,\n KpiConfigSchema,\n]);\n\n// Parameter types\nconst ParameterTypeSchema = z.enum([\n 'date_range',\n 'select',\n 'multi_select',\n 'dynamic_select',\n 'text',\n 'number',\n]);\n\n// Parameter option\nconst ParameterOptionSchema = z.union([\n z.string(),\n z.object({\n value: z.string(),\n label: z.string(),\n }),\n]);\n\n// Parameter source (for dynamic options)\nconst ParameterSourceSchema = z.object({\n model: z.string(),\n value_field: z.string(),\n label_field: z.string(),\n});\n\n// Parameter definition\nconst ParameterSchema = z.object({\n name: z.string().min(1),\n type: ParameterTypeSchema,\n label: z.string().optional(),\n default: z.union([z.string(), z.number(), z.array(z.string())]).optional(),\n options: z.array(ParameterOptionSchema).optional(),\n source: ParameterSourceSchema.optional(),\n});\n\n// Data source - either model reference or inline SQL\nconst SourceSchema = z.object({\n model: z.string().optional(),\n sql: z.string().optional(),\n}).refine(\n (data) => data.model !== undefined || data.sql !== undefined,\n { message: 'Source must specify either model or sql' }\n).refine(\n (data) => !(data.model !== undefined && data.sql !== undefined),\n { message: 'Source cannot specify both model and sql' }\n);\n\n// Refresh/cache configuration\nconst RefreshSchema = z.object({\n schedule: z.string().optional(), // cron expression\n timezone: z.string().optional(),\n cache_ttl: z.string().optional(), // e.g., \"1h\", \"30m\"\n});\n\n// Drill-down column config for data table display\nconst DrillDownColumnSchema = z.object({\n field: z.string().min(1),\n label: z.string().optional(),\n format: z.string().optional(),\n});\n\n// Drill-down configuration\nconst DrillDownConfigSchema = z.object({\n chart: z.string().optional(), // target chart name (source side)\n field: z.string().optional(), // field to pass as filter, defaults to x-axis field\n columns: z.array(DrillDownColumnSchema).optional(), // data table columns (target side)\n});\n\n// Main chart schema\nexport const ChartSchema = z.object({\n // Identity\n name: z.string().min(1),\n title: z.string().min(1),\n description: z.string().optional(),\n\n // Metadata\n owner: z.string().optional(),\n tags: z.array(z.string()).optional(),\n created: z.string().optional(),\n updated: z.string().optional(),\n\n // Data\n source: SourceSchema,\n parameters: z.array(ParameterSchema).optional(),\n\n // Visualization\n chart: ChartConfigSchema,\n\n // Caching\n refresh: RefreshSchema.optional(),\n\n // Drill-down navigation\n drillDown: DrillDownConfigSchema.optional(),\n});\n\nexport type Chart = z.infer<typeof ChartSchema>;\nexport type ChartConfig = z.infer<typeof ChartConfigSchema>;\nexport type ChartType = z.infer<typeof ChartTypeSchema>;\nexport type Parameter = z.infer<typeof ParameterSchema>;\nexport type Axis = z.infer<typeof AxisSchema>;\nexport type SeriesConfig = z.infer<typeof SeriesConfigSchema>;\nexport type LongFormatSeries = z.infer<typeof LongFormatSeriesSchema>;\nexport type WideFormatSeries = z.infer<typeof WideFormatSeriesSchema>;\nexport type WideFormatColumn = z.infer<typeof WideFormatColumnSchema>;\nexport type ColorConfig = z.infer<typeof ColorSchema>;\nexport type ConditionalColor = z.infer<typeof ConditionalColorSchema>;\nexport type ColorCondition = z.infer<typeof ColorConditionSchema>;\nexport type GradientConfig = z.infer<typeof GradientSchema>;\nexport type LegendConfig = z.infer<typeof LegendSchema>;\nexport type ComboChartConfig = z.infer<typeof ComboChartConfigSchema>;\nexport type DualAxes = z.infer<typeof DualAxesSchema>;\nexport type ScatterChartConfig = z.infer<typeof ScatterChartConfigSchema>;\nexport type ScatterSize = z.infer<typeof ScatterSizeSchema>;\nexport type ScatterGroup = z.infer<typeof ScatterGroupSchema>;\nexport type RegressionConfig = z.infer<typeof RegressionSchema>;\nexport type DrillDownConfig = z.infer<typeof DrillDownConfigSchema>;\nexport type DrillDownColumn = z.infer<typeof DrillDownColumnSchema>;\nexport type HeatmapChartConfig = z.infer<typeof HeatmapChartConfigSchema>;\nexport type FunnelChartConfig = z.infer<typeof FunnelChartConfigSchema>;\nexport type WaterfallChartConfig = z.infer<typeof WaterfallChartConfigSchema>;\nexport type GaugeChartConfig = z.infer<typeof GaugeChartConfigSchema>;\n\nexport { ParameterSchema };\n","import { z } from 'zod';\n\n// Default settings\nconst DefaultsSchema = z.object({\n connection: z.string().optional(),\n theme: z.string().optional(),\n timezone: z.string().optional(),\n cache_ttl: z.string().optional(),\n base_url: z.string().url().optional(),\n});\n\n// Environment-specific settings\nconst EnvironmentSchema = z.object({\n connection: z.string().optional(),\n base_url: z.string().url().optional(),\n});\n\n// Git integration settings\nconst GitSchema = z.object({\n provider: z.enum(['github', 'gitlab', 'bitbucket']).optional(),\n repo: z.string().optional(),\n branch: z.string().optional(),\n preview_branches: z.boolean().optional(),\n});\n\n// SSO provider configuration\nconst SSOProviderSchema = z.object({\n client_id: z.string(),\n client_secret: z.string(),\n tenant: z.string().optional(),\n issuer: z.string().optional(),\n display_name: z.string().optional(),\n});\n\n// Authentication settings (built-in local auth)\nconst AuthSchema = z.object({\n enabled: z.boolean(),\n db_path: z.string().optional(),\n session_ttl: z.string().optional(),\n providers: z.object({\n google: SSOProviderSchema.optional(),\n microsoft: SSOProviderSchema.optional(),\n oidc: SSOProviderSchema.optional(),\n }).optional(),\n});\n\n// Feature flags\nconst FeaturesSchema = z.object({\n enable_sql_editor: z.boolean().optional(),\n enable_csv_export: z.boolean().optional(),\n enable_scheduling: z.boolean().optional(),\n});\n\n// Theme configuration\nconst ThemeSchema = z.object({\n palette: z.array(z.string()).optional(),\n gradient: z.boolean().default(false),\n opacity: z.number().min(0).max(1).default(1.0),\n});\n\n// Main project schema\nexport const ProjectSchema = z.object({\n version: z.string().min(1),\n name: z.string().min(1),\n description: z.string().optional(),\n\n defaults: DefaultsSchema.optional(),\n\n environments: z.record(z.string(), EnvironmentSchema).optional(),\n\n git: GitSchema.optional(),\n auth: AuthSchema.optional(),\n features: FeaturesSchema.optional(),\n theme: ThemeSchema.optional(),\n});\n\nexport type Project = z.infer<typeof ProjectSchema>;\nexport type Auth = z.infer<typeof AuthSchema>;\nexport type Defaults = z.infer<typeof DefaultsSchema>;\nexport type Environment = z.infer<typeof EnvironmentSchema>;\nexport type Theme = z.infer<typeof ThemeSchema>;\n","import { z } from 'zod';\n\n// Parameter type\nconst ParamTypeSchema = z.enum(['string', 'number', 'date', 'boolean', 'string[]', 'number[]']);\n\n// Model parameter\nconst ModelParamSchema = z.object({\n name: z.string().min(1),\n type: ParamTypeSchema,\n default: z.string().optional(),\n options: z.array(z.string()).optional(), // For enum-like params\n description: z.string().optional(),\n});\n\n// Return column definition\nconst ReturnColumnSchema = z.object({\n name: z.string().min(1),\n type: z.string(),\n description: z.string().optional(),\n});\n\n// Model metadata (extracted from SQL comments)\nexport const ModelMetadataSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n owner: z.string().optional(),\n tags: z.array(z.string()).optional(),\n\n params: z.array(ModelParamSchema).optional(),\n returns: z.array(ReturnColumnSchema).optional(),\n tests: z.array(z.string()).optional(), // SQL assertions\n});\n\n// Full model (metadata + SQL)\nexport const ModelSchema = z.object({\n metadata: ModelMetadataSchema,\n sql: z.string().min(1),\n filePath: z.string().optional(),\n});\n\nexport type ModelMetadata = z.infer<typeof ModelMetadataSchema>;\nexport type ModelParam = z.infer<typeof ModelParamSchema>;\nexport type ReturnColumn = z.infer<typeof ReturnColumnSchema>;\nexport type Model = z.infer<typeof ModelSchema>;\n","import { z } from 'zod';\nimport { ParameterSchema } from './chart.js';\n\n// Widget types\nconst ChartWidgetSchema = z.object({\n type: z.literal('chart'),\n ref: z.string().min(1),\n cols: z.number().min(1).max(12),\n});\n\nconst TextWidgetSchema = z.object({\n type: z.literal('text'),\n content: z.string().min(1),\n cols: z.number().min(1).max(12),\n});\n\nconst WidgetSchema = z.discriminatedUnion('type', [\n ChartWidgetSchema,\n TextWidgetSchema,\n]);\n\n// Row configuration\nconst RowSchema = z.object({\n height: z.number().min(50),\n widgets: z.array(WidgetSchema).min(1),\n});\n\n// Layout configuration\nconst LayoutSchema = z.object({\n gap: z.number().min(0).default(16),\n rows: z.array(RowSchema).min(1),\n});\n\n// Main dashboard schema\nexport const DashboardSchema = z.object({\n // Identity\n name: z.string().min(1),\n title: z.string().min(1),\n description: z.string().optional(),\n\n // Filters inherited by all widgets\n filters: z.array(ParameterSchema).optional(),\n\n // Layout definition\n layout: LayoutSchema,\n});\n\nexport type Dashboard = z.infer<typeof DashboardSchema>;\nexport type DashboardLayout = z.infer<typeof LayoutSchema>;\nexport type DashboardRow = z.infer<typeof RowSchema>;\nexport type DashboardWidget = z.infer<typeof WidgetSchema>;\nexport type ChartWidget = z.infer<typeof ChartWidgetSchema>;\nexport type TextWidget = z.infer<typeof TextWidgetSchema>;\n","import { z } from 'zod';\n\nconst SlackChannelSchema = z.object({\n webhook_url: z.string().min(1),\n channel: z.string().optional(),\n});\n\nconst ChannelSchema = z.object({\n slack: SlackChannelSchema,\n});\n\nconst ConditionOperatorSchema = z.enum(['lt', 'gt', 'lte', 'gte', 'eq']);\n\nconst ConditionSchema = z.object({\n field: z.string().min(1),\n operator: ConditionOperatorSchema,\n value: z.number(),\n});\n\nconst ReportScheduleSchema = z.object({\n name: z.string().min(1),\n type: z.literal('report'),\n schedule: z.string().min(1),\n timezone: z.string().optional(),\n channel: ChannelSchema,\n charts: z.array(z.string().min(1)).min(1),\n params: z.record(z.unknown()).optional(),\n message: z.string().optional(),\n notify_on_error: z.boolean().optional(),\n});\n\nconst AlertScheduleSchema = z.object({\n name: z.string().min(1),\n type: z.literal('alert'),\n schedule: z.string().min(1),\n timezone: z.string().optional(),\n channel: ChannelSchema,\n chart: z.string().min(1),\n params: z.record(z.unknown()).optional(),\n condition: ConditionSchema,\n cooldown: z.string().optional(),\n message: z.string().optional(),\n notify_on_error: z.boolean().optional(),\n});\n\nexport const ScheduleSchema = z.discriminatedUnion('type', [\n ReportScheduleSchema,\n AlertScheduleSchema,\n]);\n\nexport type Schedule = z.infer<typeof ScheduleSchema>;\nexport type ReportSchedule = z.infer<typeof ReportScheduleSchema>;\nexport type AlertSchedule = z.infer<typeof AlertScheduleSchema>;\nexport type Condition = z.infer<typeof ConditionSchema>;\nexport type ConditionOperator = z.infer<typeof ConditionOperatorSchema>;\n","import { access } from 'fs/promises';\nimport { join, dirname, resolve } from 'path';\nimport { config as loadDotenv } from 'dotenv';\n\n/**\n * Find the project root by looking for yamchart.yaml.\n * Searches current directory and parent directories.\n */\nexport async function findProjectRoot(startDir: string): Promise<string | null> {\n let currentDir = resolve(startDir);\n const root = dirname(currentDir);\n\n while (currentDir !== root) {\n const configPath = join(currentDir, 'yamchart.yaml');\n try {\n await access(configPath);\n return currentDir;\n } catch {\n currentDir = dirname(currentDir);\n }\n }\n\n // Check root directory too\n try {\n await access(join(root, 'yamchart.yaml'));\n return root;\n } catch {\n return null;\n }\n}\n\n/**\n * Load .env file from project directory.\n */\nexport function loadEnvFile(projectDir: string): void {\n loadDotenv({ path: join(projectDir, '.env') });\n}\n\n/**\n * Resolve ${VAR} syntax in a string from environment variables.\n */\nexport function resolveEnvVars(value: string): string {\n return value.replace(/\\$\\{([^}]+)\\}/g, (match, varName) => {\n const envValue = process.env[varName];\n if (envValue === undefined) {\n throw new Error(`Environment variable not found: ${varName}`);\n }\n return envValue;\n });\n}\n\n/**\n * Recursively resolve env vars in an object.\n */\nexport function resolveEnvVarsInObject<T>(obj: T): T {\n if (typeof obj === 'string') {\n return resolveEnvVars(obj) as T;\n }\n if (Array.isArray(obj)) {\n return obj.map(resolveEnvVarsInObject) as T;\n }\n if (obj !== null && typeof obj === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[key] = resolveEnvVarsInObject(value);\n }\n return result as T;\n }\n return obj;\n}\n"],"mappings":"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","names":["z","z","AuthSchema","z","z","z","z","access","join"]}
|
|
1
|
+
{"version":3,"sources":["../src/commands/validate.ts","../../../packages/schema/src/connection.ts","../../../packages/schema/src/chart.ts","../../../packages/schema/src/project.ts","../../../packages/schema/src/model.ts","../../../packages/schema/src/dashboard.ts","../../../packages/schema/src/schedule.ts","../src/utils/config.ts"],"sourcesContent":["import { readFile, readdir, access } from 'fs/promises';\nimport { join, extname, relative } from 'path';\nimport { parse as parseYaml } from 'yaml';\nimport {\n ProjectSchema,\n ConnectionSchema,\n ChartSchema,\n DashboardSchema,\n ScheduleSchema,\n type Schedule,\n} from '@yamchart/schema';\nimport type { ZodError } from 'zod';\nimport { parseModelMetadata } from '@yamchart/query';\n\nfunction formatZodErrors(error: ZodError): string[] {\n return error.errors.map((e) => {\n const path = e.path.length > 0 ? e.path.join('.') : '(root)';\n return `${path}: ${e.message}`;\n });\n}\n\nexport interface ValidationError {\n file: string;\n line?: number;\n message: string;\n suggestion?: string;\n}\n\nexport interface ValidationResult {\n success: boolean;\n errors: ValidationError[];\n warnings: ValidationError[];\n stats: {\n files: number;\n passed: number;\n failed: number;\n };\n dryRunStats?: {\n passed: number;\n failed: number;\n };\n}\n\nexport interface ValidateOptions {\n dryRun: boolean;\n connection?: string;\n}\n\ninterface LoadedConfig {\n project: { name: string; version: string; defaults?: { connection?: string } } | null;\n connections: Map<string, { name: string; type: string }>;\n models: Map<string, { name: string; sql: string }>;\n charts: Map<string, { name: string; source: { model?: string; sql?: string } }>;\n dashboards: Map<string, { name: string; layout: unknown }>;\n schedules: Map<string, Schedule>;\n}\n\nexport async function validateProject(\n projectDir: string,\n options: ValidateOptions\n): Promise<ValidationResult> {\n const errors: ValidationError[] = [];\n const warnings: ValidationError[] = [];\n let filesChecked = 0;\n let filesPassed = 0;\n\n const config: LoadedConfig = {\n project: null,\n connections: new Map(),\n models: new Map(),\n charts: new Map(),\n dashboards: new Map(),\n schedules: new Map(),\n };\n\n // Phase 1: Schema validation\n\n // Validate yamchart.yaml\n const projectPath = join(projectDir, 'yamchart.yaml');\n try {\n await access(projectPath);\n filesChecked++;\n const content = await readFile(projectPath, 'utf-8');\n const parsed = parseYaml(content);\n const result = ProjectSchema.safeParse(parsed);\n\n if (result.success) {\n config.project = result.data;\n filesPassed++;\n } else {\n errors.push({\n file: 'yamchart.yaml',\n message: `Invalid schema:\\n${formatZodErrors(result.error).map(e => ` - ${e}`).join('\\n')}`,\n });\n }\n } catch {\n errors.push({\n file: 'yamchart.yaml',\n message: 'yamchart.yaml not found',\n });\n return {\n success: false,\n errors,\n warnings,\n stats: { files: filesChecked, passed: filesPassed, failed: filesChecked - filesPassed },\n };\n }\n\n // Validate connections\n const connectionsDir = join(projectDir, 'connections');\n try {\n await access(connectionsDir);\n const files = await readdir(connectionsDir);\n\n for (const file of files) {\n if (extname(file) !== '.yaml' && extname(file) !== '.yml') continue;\n filesChecked++;\n\n const filePath = join(connectionsDir, file);\n const content = await readFile(filePath, 'utf-8');\n const parsed = parseYaml(content);\n const result = ConnectionSchema.safeParse(parsed);\n\n if (result.success) {\n config.connections.set(result.data.name, result.data);\n filesPassed++;\n } else {\n errors.push({\n file: `connections/${file}`,\n message: `Invalid schema:\\n${formatZodErrors(result.error).map(e => ` - ${e}`).join('\\n')}`,\n });\n }\n }\n } catch {\n // No connections directory is ok\n }\n\n // Validate models\n const modelsDir = join(projectDir, 'models');\n const modelStats = { filesChecked: 0, filesPassed: 0 };\n try {\n await access(modelsDir);\n await validateModelsDir(modelsDir, projectDir, config, errors, modelStats);\n filesChecked += modelStats.filesChecked;\n filesPassed += modelStats.filesPassed;\n } catch {\n // No models directory is ok\n }\n\n // Validate charts\n const chartsDir = join(projectDir, 'charts');\n try {\n await access(chartsDir);\n const files = await readdir(chartsDir);\n\n for (const file of files) {\n if (extname(file) !== '.yaml' && extname(file) !== '.yml') continue;\n filesChecked++;\n\n const filePath = join(chartsDir, file);\n const content = await readFile(filePath, 'utf-8');\n const parsed = parseYaml(content);\n const result = ChartSchema.safeParse(parsed);\n\n if (result.success) {\n config.charts.set(result.data.name, result.data);\n filesPassed++;\n } else {\n errors.push({\n file: `charts/${file}`,\n message: `Invalid schema:\\n${formatZodErrors(result.error).map(e => ` - ${e}`).join('\\n')}`,\n });\n }\n }\n } catch {\n // No charts directory is ok\n }\n\n // Validate dashboards\n const dashboardsDir = join(projectDir, 'dashboards');\n try {\n await access(dashboardsDir);\n const files = await readdir(dashboardsDir);\n\n for (const file of files) {\n if (extname(file) !== '.yaml' && extname(file) !== '.yml') continue;\n filesChecked++;\n\n const filePath = join(dashboardsDir, file);\n const content = await readFile(filePath, 'utf-8');\n const parsed = parseYaml(content);\n const result = DashboardSchema.safeParse(parsed);\n\n if (result.success) {\n config.dashboards.set(result.data.name, result.data);\n filesPassed++;\n } else {\n errors.push({\n file: `dashboards/${file}`,\n message: `Invalid schema:\\n${formatZodErrors(result.error).map(e => ` - ${e}`).join('\\n')}`,\n });\n }\n }\n } catch {\n // No dashboards directory is ok\n }\n\n // Validate schedules\n const schedulesDir = join(projectDir, 'schedules');\n try {\n await access(schedulesDir);\n const files = await readdir(schedulesDir);\n\n for (const file of files) {\n if (extname(file) !== '.yaml' && extname(file) !== '.yml') continue;\n filesChecked++;\n\n const filePath = join(schedulesDir, file);\n const content = await readFile(filePath, 'utf-8');\n const parsed = parseYaml(content);\n const result = ScheduleSchema.safeParse(parsed);\n\n if (result.success) {\n config.schedules.set(result.data.name, result.data);\n filesPassed++;\n } else {\n errors.push({\n file: `schedules/${file}`,\n message: `Invalid schema:\\n${formatZodErrors(result.error).map(e => ` - ${e}`).join('\\n')}`,\n });\n }\n }\n } catch {\n // No schedules directory is ok\n }\n\n // Phase 2: Cross-reference validation\n crossReferenceValidation(config, errors, warnings);\n\n // Phase 3: Dry-run query validation (if enabled)\n let dryRunStats: { passed: number; failed: number } | undefined;\n if (options.dryRun) {\n dryRunStats = await dryRunValidation(projectDir, config, options.connection, errors);\n }\n\n return {\n success: errors.length === 0,\n errors,\n warnings,\n stats: {\n files: filesChecked,\n passed: filesPassed,\n failed: filesChecked - filesPassed,\n },\n dryRunStats,\n };\n}\n\nasync function validateModelsDir(\n dir: string,\n projectDir: string,\n config: LoadedConfig,\n errors: ValidationError[],\n stats: { filesChecked: number; filesPassed: number }\n): Promise<void> {\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n await validateModelsDir(fullPath, projectDir, config, errors, stats);\n } else if (extname(entry.name) === '.sql') {\n stats.filesChecked++;\n const relPath = relative(projectDir, fullPath);\n const content = await readFile(fullPath, 'utf-8');\n\n try {\n const parsed = parseModelMetadata(content);\n config.models.set(parsed.name, { name: parsed.name, sql: parsed.sql });\n stats.filesPassed++;\n } catch (err) {\n errors.push({\n file: relPath,\n message: err instanceof Error ? err.message : 'Failed to parse model',\n });\n }\n }\n }\n}\n\nfunction crossReferenceValidation(\n config: LoadedConfig,\n errors: ValidationError[],\n warnings: ValidationError[]\n): void {\n // Check that charts reference existing models\n for (const [chartName, chart] of config.charts) {\n if (chart.source.model && !config.models.has(chart.source.model)) {\n const suggestion = findSimilar(chart.source.model, Array.from(config.models.keys()));\n errors.push({\n file: `charts/${chartName}.yaml`,\n message: `Unknown model reference \"${chart.source.model}\"`,\n suggestion: suggestion ? `Did you mean \"${suggestion}\"?` : undefined,\n });\n }\n }\n\n // Check that schedules reference existing charts\n for (const [scheduleName, schedule] of config.schedules) {\n const chartNames = schedule.type === 'report' ? schedule.charts : [schedule.chart];\n for (const chartName of chartNames) {\n if (!config.charts.has(chartName)) {\n const suggestion = findSimilar(chartName, Array.from(config.charts.keys()));\n warnings.push({\n file: `schedules/${scheduleName}.yaml`,\n message: `Unknown chart reference \"${chartName}\"`,\n suggestion: suggestion ? `Did you mean \"${suggestion}\"?` : undefined,\n });\n }\n }\n\n // Validate cron expression (basic: 5 or 6 space-separated fields)\n const cronFields = schedule.schedule.trim().split(/\\s+/);\n if (cronFields.length < 5 || cronFields.length > 6) {\n errors.push({\n file: `schedules/${scheduleName}.yaml`,\n message: `Invalid cron expression \"${schedule.schedule}\" (expected 5-6 fields)`,\n });\n }\n }\n\n // Check that default connection exists\n if (config.project?.defaults?.connection) {\n const connName = config.project.defaults.connection;\n if (!config.connections.has(connName)) {\n const suggestion = findSimilar(connName, Array.from(config.connections.keys()));\n errors.push({\n file: 'yamchart.yaml',\n message: `Default connection \"${connName}\" not found`,\n suggestion: suggestion ? `Did you mean \"${suggestion}\"?` : undefined,\n });\n }\n }\n}\n\nfunction findSimilar(target: string, candidates: string[]): string | null {\n const threshold = 3; // Levenshtein distance threshold\n\n for (const candidate of candidates) {\n if (levenshtein(target.toLowerCase(), candidate.toLowerCase()) <= threshold) {\n return candidate;\n }\n }\n return null;\n}\n\nfunction levenshtein(a: string, b: string): number {\n const matrix: number[][] = [];\n\n for (let i = 0; i <= b.length; i++) {\n matrix[i] = [i];\n }\n for (let j = 0; j <= a.length; j++) {\n matrix[0]![j] = j;\n }\n\n for (let i = 1; i <= b.length; i++) {\n for (let j = 1; j <= a.length; j++) {\n if (b.charAt(i - 1) === a.charAt(j - 1)) {\n matrix[i]![j] = matrix[i - 1]![j - 1]!;\n } else {\n matrix[i]![j] = Math.min(\n matrix[i - 1]![j - 1]! + 1,\n matrix[i]![j - 1]! + 1,\n matrix[i - 1]![j]! + 1\n );\n }\n }\n }\n\n return matrix[b.length]![a.length]!;\n}\n\nasync function dryRunValidation(\n projectDir: string,\n config: LoadedConfig,\n connectionName: string | undefined,\n errors: ValidationError[]\n): Promise<{ passed: number; failed: number }> {\n const { DuckDBConnector } = await import('@yamchart/query');\n\n let passed = 0;\n let failed = 0;\n\n // Determine which connection to use\n const connName = connectionName || config.project?.defaults?.connection;\n if (!connName) {\n errors.push({\n file: 'yamchart.yaml',\n message: 'No connection specified for dry-run (use --connection or set defaults.connection)',\n });\n return { passed, failed: 1 };\n }\n\n const connection = config.connections.get(connName);\n if (!connection) {\n errors.push({\n file: 'yamchart.yaml',\n message: `Connection \"${connName}\" not found`,\n });\n return { passed, failed: 1 };\n }\n\n // Only DuckDB supported for now\n if (connection.type !== 'duckdb') {\n errors.push({\n file: `connections/${connName}.yaml`,\n message: `Dry-run not yet supported for connection type \"${connection.type}\"`,\n });\n return { passed, failed: 1 };\n }\n\n // Load full connection config to get path\n const connPath = join(projectDir, 'connections', `${connName}.yaml`);\n const connContent = await readFile(connPath, 'utf-8');\n const connConfig = parseYaml(connContent) as { config: { path: string } };\n\n // Resolve path relative to project\n const dbPath = connConfig.config.path.startsWith('/')\n ? connConfig.config.path\n : join(projectDir, connConfig.config.path);\n\n const connector = new DuckDBConnector({ path: dbPath });\n\n try {\n await connector.connect();\n\n for (const [modelName, model] of config.models) {\n const result = await connector.explain(model.sql);\n\n if (result.valid) {\n passed++;\n } else {\n failed++;\n errors.push({\n file: `models/${modelName}.sql`,\n message: result.error || 'Query validation failed',\n });\n }\n }\n } finally {\n await connector.disconnect();\n }\n\n return { passed, failed };\n}\n","import { z } from 'zod';\n\n// Auth configuration for connections\nconst EnvAuthSchema = z.object({\n type: z.literal('env'),\n user_var: z.string(),\n password_var: z.string(),\n});\n\nconst KeyPairAuthSchema = z.object({\n type: z.literal('key_pair'),\n user_var: z.string(),\n private_key_path: z.string(),\n});\n\nconst SecretManagerAuthSchema = z.object({\n type: z.literal('secret_manager'),\n provider: z.enum(['aws_secrets_manager', 'gcp_secret_manager', 'vault']),\n secret_id: z.string(),\n});\n\nconst ExternalBrowserAuthSchema = z.object({\n type: z.literal('externalbrowser'),\n user_var: z.string(),\n cache_token: z.boolean().optional(),\n});\n\nconst AuthSchema = z.discriminatedUnion('type', [\n EnvAuthSchema,\n KeyPairAuthSchema,\n SecretManagerAuthSchema,\n ExternalBrowserAuthSchema,\n]);\n\n// Connection pool configuration\nconst PoolConfigSchema = z.object({\n min_connections: z.number().int().positive().optional(),\n max_connections: z.number().int().positive().optional(),\n idle_timeout: z.number().int().positive().optional(),\n});\n\n// Query settings\nconst QueryConfigSchema = z.object({\n timeout: z.number().int().positive().optional(),\n max_rows: z.number().int().positive().optional(),\n});\n\n// DuckDB-specific config\nconst DuckDBConfigSchema = z.object({\n path: z.string(), // file path or :memory:\n});\n\n// Postgres-specific config\nconst PostgresConfigSchema = z.object({\n host: z.string(),\n port: z.number().int().positive().default(5432),\n database: z.string(),\n schema: z.string().optional(),\n ssl: z.boolean().optional(),\n});\n\n// Snowflake-specific config\nconst SnowflakeConfigSchema = z.object({\n account: z.string(),\n warehouse: z.string(),\n database: z.string(),\n schema: z.string().optional(),\n role: z.string().optional(),\n});\n\n// MySQL-specific config\nconst MySQLConfigSchema = z.object({\n host: z.string(),\n port: z.number().int().positive().default(3306),\n database: z.string(),\n ssl: z.boolean().optional(),\n});\n\n// SQLite-specific config\nconst SQLiteConfigSchema = z.object({\n path: z.string(), // file path or :memory:\n});\n\n// Base connection schema\nconst BaseConnectionSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n pool: PoolConfigSchema.optional(),\n query: QueryConfigSchema.optional(),\n});\n\n// Type-specific connection schemas\nconst DuckDBConnectionSchema = BaseConnectionSchema.extend({\n type: z.literal('duckdb'),\n config: DuckDBConfigSchema,\n auth: z.undefined().optional(),\n});\n\nconst PostgresConnectionSchema = BaseConnectionSchema.extend({\n type: z.literal('postgres'),\n config: PostgresConfigSchema,\n auth: AuthSchema.optional(),\n});\n\nconst SnowflakeConnectionSchema = BaseConnectionSchema.extend({\n type: z.literal('snowflake'),\n config: SnowflakeConfigSchema,\n auth: AuthSchema,\n});\n\nconst MySQLConnectionSchema = BaseConnectionSchema.extend({\n type: z.literal('mysql'),\n config: MySQLConfigSchema,\n auth: AuthSchema.optional(),\n});\n\nconst SQLiteConnectionSchema = BaseConnectionSchema.extend({\n type: z.literal('sqlite'),\n config: SQLiteConfigSchema,\n auth: z.undefined().optional(),\n});\n\n// Union of all connection types\nexport const ConnectionSchema = z.discriminatedUnion('type', [\n DuckDBConnectionSchema,\n PostgresConnectionSchema,\n SnowflakeConnectionSchema,\n MySQLConnectionSchema,\n SQLiteConnectionSchema,\n]);\n\nexport type Connection = z.infer<typeof ConnectionSchema>;\nexport type DuckDBConnection = z.infer<typeof DuckDBConnectionSchema>;\nexport type PostgresConnection = z.infer<typeof PostgresConnectionSchema>;\nexport type SnowflakeConnection = z.infer<typeof SnowflakeConnectionSchema>;\nexport type MySQLConnection = z.infer<typeof MySQLConnectionSchema>;\nexport type SQLiteConnection = z.infer<typeof SQLiteConnectionSchema>;\n","import { z } from 'zod';\n\n// Axis types\nconst AxisTypeSchema = z.enum(['temporal', 'quantitative', 'ordinal', 'nominal']);\n\n// Axis configuration\nconst AxisSchema = z.object({\n field: z.string().min(1),\n type: AxisTypeSchema,\n format: z.string().optional(),\n label: z.string().optional(),\n});\n\n// Chart types supported (scatter has its own dedicated schema)\nconst ChartTypeSchema = z.enum([\n 'line',\n 'bar',\n 'area',\n 'pie',\n 'donut',\n 'table',\n 'metric',\n 'map',\n 'heatmap',\n 'funnel',\n 'sankey',\n 'treemap',\n 'waterfall',\n 'gauge',\n]);\n\n// Gradient configuration - boolean shorthand or explicit from/to\nconst GradientSchema = z.union([\n z.boolean(),\n z.object({\n from: z.string(),\n to: z.string(),\n }),\n]);\n\n// Long format series: group by a field in the data (one row per series value)\nconst LongFormatSeriesSchema = z.object({\n field: z.string().min(1),\n colors: z.record(z.string(), z.string()).optional(),\n});\n\n// Wide format column: each column becomes a separate series\nconst WideFormatColumnSchema = z.object({\n field: z.string().min(1),\n name: z.string().optional(),\n type: z.enum(['line', 'bar', 'area']).optional(),\n axis: z.enum(['left', 'right']).optional(),\n color: z.string().optional(),\n style: z.enum(['solid', 'dashed', 'dotted']).optional(),\n opacity: z.number().min(0).max(1).optional(),\n gradient: GradientSchema.optional(),\n});\n\n// Wide format series: explicit list of columns\nconst WideFormatSeriesSchema = z.object({\n columns: z.array(WideFormatColumnSchema).min(1),\n});\n\n// Series config is either long format (group by field) or wide format (explicit columns)\nconst SeriesConfigSchema = z.union([\n LongFormatSeriesSchema,\n WideFormatSeriesSchema,\n]);\n\n// Color condition for conditional coloring\nconst ColorConditionSchema = z.object({\n when: z.string(),\n color: z.string(),\n});\n\n// Conditional color configuration\nconst ConditionalColorSchema = z.object({\n conditions: z.array(ColorConditionSchema).min(1),\n default: z.string().optional(),\n});\n\n// Color - either a simple string or conditional config\nconst ColorSchema = z.union([\n z.string(),\n ConditionalColorSchema,\n]);\n\n// Legend configuration\nconst LegendSchema = z.object({\n show: z.boolean().optional(),\n position: z.enum(['top', 'bottom', 'left', 'right']).optional(),\n});\n\n// Annotation configuration\nconst LineAnnotationSchema = z.object({\n type: z.literal('line'),\n value: z.number(),\n label: z.string().optional(),\n color: z.string().optional(),\n style: z.enum(['solid', 'dashed', 'dotted']).optional(),\n});\n\nconst BandAnnotationSchema = z.object({\n type: z.literal('band'),\n from: z.number(),\n to: z.number(),\n label: z.string().optional(),\n color: z.string().optional(),\n});\n\nconst AnnotationSchema = z.discriminatedUnion('type', [\n LineAnnotationSchema,\n BandAnnotationSchema,\n]);\n\n// Interactivity options\nconst InteractionsSchema = z.object({\n tooltip: z.boolean().default(true),\n zoom: z.boolean().default(false),\n brush: z.boolean().default(false),\n});\n\n// KPI format types\nconst KpiFormatSchema = z.object({\n type: z.enum(['number', 'currency', 'percent']),\n currency: z.string().optional(), // e.g., 'USD', 'EUR'\n decimals: z.number().optional(),\n});\n\n// KPI comparison configuration\nconst KpiComparisonSchema = z.object({\n enabled: z.boolean(),\n field: z.string().min(1),\n label: z.string().optional(),\n type: z.enum(['percent_change', 'absolute']),\n});\n\n// KPI value configuration\nconst KpiValueSchema = z.object({\n field: z.string().min(1),\n});\n\n// KPI-specific config\nconst KpiConfigSchema = z.object({\n type: z.literal('kpi'),\n value: KpiValueSchema,\n format: KpiFormatSchema,\n comparison: KpiComparisonSchema.optional(),\n});\n\n// Center value for donut charts\nconst CenterValueSchema = z.object({\n field: z.string().optional(), // 'total' for sum, or specific field\n label: z.string().optional(),\n format: z.string().optional(),\n});\n\n// Standard chart config (existing)\nconst StandardChartConfigSchema = z.object({\n type: ChartTypeSchema,\n x: AxisSchema,\n y: AxisSchema.optional(),\n series: SeriesConfigSchema.optional(),\n stacking: z.enum(['stacked', 'percent']).optional(),\n color: ColorSchema.optional(),\n gradient: GradientSchema.optional(),\n legend: LegendSchema.optional(),\n annotations: z.array(AnnotationSchema).optional(),\n interactions: InteractionsSchema.optional(),\n centerValue: CenterValueSchema.optional(), // For donut charts\n});\n\n// Dual axes for combo charts\nconst DualAxesSchema = z.object({\n left: AxisSchema.optional(),\n right: AxisSchema.optional(),\n});\n\n// Combo chart config - requires dual axes\nconst ComboChartConfigSchema = z.object({\n type: z.literal('combo'),\n x: AxisSchema,\n series: WideFormatSeriesSchema,\n axes: DualAxesSchema,\n legend: LegendSchema.optional(),\n interactions: InteractionsSchema.optional(),\n gradient: GradientSchema.optional(),\n});\n\n// Scatter chart size encoding\nconst ScatterSizeSchema = z.object({\n field: z.string().min(1),\n min: z.number().optional(),\n max: z.number().optional(),\n label: z.string().optional(),\n});\n\n// Scatter chart grouping\nconst ScatterGroupSchema = z.object({\n field: z.string().min(1),\n});\n\n// Regression line configuration\nconst RegressionSchema = z.object({\n type: z.literal('linear'),\n show_equation: z.boolean().optional(),\n show_r_squared: z.boolean().optional(),\n});\n\n// Scatter/bubble chart config\nconst ScatterChartConfigSchema = z.object({\n type: z.literal('scatter'),\n x: AxisSchema,\n y: AxisSchema,\n size: ScatterSizeSchema.optional(),\n group: ScatterGroupSchema.optional(),\n regression: RegressionSchema.optional(),\n color: ColorSchema.optional(),\n legend: LegendSchema.optional(),\n interactions: InteractionsSchema.optional(),\n});\n\n// Heatmap chart config\nconst HeatmapChartConfigSchema = z.object({\n type: z.literal('heatmap'),\n x: AxisSchema,\n y: AxisSchema,\n value: z.object({\n field: z.string().min(1),\n label: z.string().optional(),\n }),\n color_range: z.object({\n min: z.string().optional(),\n max: z.string().optional(),\n }).optional(),\n show_values: z.boolean().optional(),\n});\n\n// Funnel chart config\nconst FunnelChartConfigSchema = z.object({\n type: z.literal('funnel'),\n stage: z.object({ field: z.string().min(1) }),\n value: z.object({ field: z.string().min(1) }),\n show_conversion: z.boolean().optional(),\n color: ColorSchema.optional(),\n});\n\n// Waterfall chart config\nconst WaterfallChartConfigSchema = z.object({\n type: z.literal('waterfall'),\n category: z.object({ field: z.string().min(1) }),\n value: z.object({ field: z.string().min(1) }),\n total_field: z.string().optional(),\n colors: z.object({\n increase: z.string().optional(),\n decrease: z.string().optional(),\n total: z.string().optional(),\n }).optional(),\n});\n\n// Gauge chart config\nconst GaugeThresholdSchema = z.object({\n value: z.number(),\n color: z.string(),\n});\n\nconst GaugeChartConfigSchema = z.object({\n type: z.literal('gauge'),\n value: z.object({ field: z.string().min(1) }),\n min: z.number().optional(),\n max: z.number().optional(),\n thresholds: z.array(GaugeThresholdSchema).optional(),\n format: z.string().optional(),\n});\n\n// Chart visualization config - standard, KPI, combo, scatter, heatmap, funnel, waterfall, or gauge\nconst ChartConfigSchema = z.union([\n ScatterChartConfigSchema,\n ComboChartConfigSchema,\n HeatmapChartConfigSchema,\n FunnelChartConfigSchema,\n WaterfallChartConfigSchema,\n GaugeChartConfigSchema,\n StandardChartConfigSchema,\n KpiConfigSchema,\n]);\n\n// Parameter types\nconst ParameterTypeSchema = z.enum([\n 'date_range',\n 'select',\n 'multi_select',\n 'dynamic_select',\n 'text',\n 'number',\n]);\n\n// Parameter option\nconst ParameterOptionSchema = z.union([\n z.string(),\n z.object({\n value: z.string(),\n label: z.string(),\n }),\n]);\n\n// Parameter source (for dynamic options)\nconst ParameterSourceSchema = z.object({\n model: z.string(),\n value_field: z.string(),\n label_field: z.string(),\n});\n\n// Parameter definition\nconst ParameterSchema = z.object({\n name: z.string().min(1),\n type: ParameterTypeSchema,\n label: z.string().optional(),\n default: z.union([z.string(), z.number(), z.array(z.string())]).optional(),\n options: z.array(ParameterOptionSchema).optional(),\n source: ParameterSourceSchema.optional(),\n});\n\n// Data source - either model reference or inline SQL\nconst SourceSchema = z.object({\n model: z.string().optional(),\n sql: z.string().optional(),\n}).refine(\n (data) => data.model !== undefined || data.sql !== undefined,\n { message: 'Source must specify either model or sql' }\n).refine(\n (data) => !(data.model !== undefined && data.sql !== undefined),\n { message: 'Source cannot specify both model and sql' }\n);\n\n// Refresh/cache configuration\nconst RefreshSchema = z.object({\n schedule: z.string().optional(), // cron expression\n timezone: z.string().optional(),\n cache_ttl: z.string().optional(), // e.g., \"1h\", \"30m\"\n});\n\n// Drill-down column config for data table display\nconst DrillDownColumnSchema = z.object({\n field: z.string().min(1),\n label: z.string().optional(),\n format: z.string().optional(),\n});\n\n// Drill-down configuration\nconst DrillDownConfigSchema = z.object({\n chart: z.string().optional(), // target chart name (source side)\n field: z.string().optional(), // field to pass as filter, defaults to x-axis field\n columns: z.array(DrillDownColumnSchema).optional(), // data table columns (target side)\n});\n\n// Main chart schema\nexport const ChartSchema = z.object({\n // Identity\n name: z.string().min(1),\n title: z.string().min(1),\n description: z.string().optional(),\n\n // Metadata\n owner: z.string().optional(),\n tags: z.array(z.string()).optional(),\n created: z.string().optional(),\n updated: z.string().optional(),\n\n // Data\n source: SourceSchema,\n parameters: z.array(ParameterSchema).optional(),\n\n // Visualization\n chart: ChartConfigSchema,\n\n // Caching\n refresh: RefreshSchema.optional(),\n\n // Drill-down navigation\n drillDown: DrillDownConfigSchema.optional(),\n});\n\nexport type Chart = z.infer<typeof ChartSchema>;\nexport type ChartConfig = z.infer<typeof ChartConfigSchema>;\nexport type ChartType = z.infer<typeof ChartTypeSchema>;\nexport type Parameter = z.infer<typeof ParameterSchema>;\nexport type Axis = z.infer<typeof AxisSchema>;\nexport type SeriesConfig = z.infer<typeof SeriesConfigSchema>;\nexport type LongFormatSeries = z.infer<typeof LongFormatSeriesSchema>;\nexport type WideFormatSeries = z.infer<typeof WideFormatSeriesSchema>;\nexport type WideFormatColumn = z.infer<typeof WideFormatColumnSchema>;\nexport type ColorConfig = z.infer<typeof ColorSchema>;\nexport type ConditionalColor = z.infer<typeof ConditionalColorSchema>;\nexport type ColorCondition = z.infer<typeof ColorConditionSchema>;\nexport type GradientConfig = z.infer<typeof GradientSchema>;\nexport type LegendConfig = z.infer<typeof LegendSchema>;\nexport type ComboChartConfig = z.infer<typeof ComboChartConfigSchema>;\nexport type DualAxes = z.infer<typeof DualAxesSchema>;\nexport type ScatterChartConfig = z.infer<typeof ScatterChartConfigSchema>;\nexport type ScatterSize = z.infer<typeof ScatterSizeSchema>;\nexport type ScatterGroup = z.infer<typeof ScatterGroupSchema>;\nexport type RegressionConfig = z.infer<typeof RegressionSchema>;\nexport type DrillDownConfig = z.infer<typeof DrillDownConfigSchema>;\nexport type DrillDownColumn = z.infer<typeof DrillDownColumnSchema>;\nexport type HeatmapChartConfig = z.infer<typeof HeatmapChartConfigSchema>;\nexport type FunnelChartConfig = z.infer<typeof FunnelChartConfigSchema>;\nexport type WaterfallChartConfig = z.infer<typeof WaterfallChartConfigSchema>;\nexport type GaugeChartConfig = z.infer<typeof GaugeChartConfigSchema>;\n\nexport { ParameterSchema };\n","import { z } from 'zod';\n\n// Default settings\nconst DefaultsSchema = z.object({\n connection: z.string().optional(),\n theme: z.string().optional(),\n timezone: z.string().optional(),\n cache_ttl: z.string().optional(),\n base_url: z.string().url().optional(),\n});\n\n// Environment-specific settings\nconst EnvironmentSchema = z.object({\n connection: z.string().optional(),\n base_url: z.string().url().optional(),\n});\n\n// Git integration settings\nconst GitSchema = z.object({\n provider: z.enum(['github', 'gitlab', 'bitbucket']).optional(),\n repo: z.string().optional(),\n branch: z.string().optional(),\n preview_branches: z.boolean().optional(),\n});\n\n// SSO provider configuration\nconst SSOProviderSchema = z.object({\n client_id: z.string(),\n client_secret: z.string(),\n tenant: z.string().optional(),\n issuer: z.string().optional(),\n display_name: z.string().optional(),\n});\n\n// Authentication settings (built-in local auth)\nconst AuthSchema = z.object({\n enabled: z.boolean(),\n db_path: z.string().optional(),\n session_ttl: z.string().optional(),\n providers: z.object({\n google: SSOProviderSchema.optional(),\n microsoft: SSOProviderSchema.optional(),\n oidc: SSOProviderSchema.optional(),\n }).optional(),\n});\n\n// Feature flags\nconst FeaturesSchema = z.object({\n enable_sql_editor: z.boolean().optional(),\n enable_csv_export: z.boolean().optional(),\n enable_scheduling: z.boolean().optional(),\n});\n\n// Theme configuration\nconst ThemeSchema = z.object({\n palette: z.array(z.string()).optional(),\n gradient: z.boolean().default(false),\n opacity: z.number().min(0).max(1).default(1.0),\n});\n\n// Main project schema\nexport const ProjectSchema = z.object({\n version: z.string().min(1),\n name: z.string().min(1),\n description: z.string().optional(),\n\n defaults: DefaultsSchema.optional(),\n\n environments: z.record(z.string(), EnvironmentSchema).optional(),\n\n git: GitSchema.optional(),\n auth: AuthSchema.optional(),\n features: FeaturesSchema.optional(),\n theme: ThemeSchema.optional(),\n});\n\nexport type Project = z.infer<typeof ProjectSchema>;\nexport type Auth = z.infer<typeof AuthSchema>;\nexport type Defaults = z.infer<typeof DefaultsSchema>;\nexport type Environment = z.infer<typeof EnvironmentSchema>;\nexport type Theme = z.infer<typeof ThemeSchema>;\n","import { z } from 'zod';\n\n// Parameter type\nconst ParamTypeSchema = z.enum(['string', 'number', 'date', 'boolean', 'string[]', 'number[]']);\n\n// Model parameter\nconst ModelParamSchema = z.object({\n name: z.string().min(1),\n type: ParamTypeSchema,\n default: z.string().optional(),\n options: z.array(z.string()).optional(), // For enum-like params\n description: z.string().optional(),\n});\n\n// Return column definition\nconst ReturnColumnSchema = z.object({\n name: z.string().min(1),\n type: z.string(),\n description: z.string().optional(),\n});\n\n// Model metadata (extracted from SQL comments)\nexport const ModelMetadataSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n owner: z.string().optional(),\n tags: z.array(z.string()).optional(),\n\n params: z.array(ModelParamSchema).optional(),\n returns: z.array(ReturnColumnSchema).optional(),\n tests: z.array(z.string()).optional(), // SQL assertions\n});\n\n// Full model (metadata + SQL)\nexport const ModelSchema = z.object({\n metadata: ModelMetadataSchema,\n sql: z.string().min(1),\n filePath: z.string().optional(),\n});\n\nexport type ModelMetadata = z.infer<typeof ModelMetadataSchema>;\nexport type ModelParam = z.infer<typeof ModelParamSchema>;\nexport type ReturnColumn = z.infer<typeof ReturnColumnSchema>;\nexport type Model = z.infer<typeof ModelSchema>;\n","import { z } from 'zod';\nimport { ParameterSchema } from './chart.js';\n\n// Widget types\nconst ChartWidgetSchema = z.object({\n type: z.literal('chart'),\n ref: z.string().min(1),\n cols: z.number().min(1).max(12),\n});\n\nconst TextWidgetSchema = z.object({\n type: z.literal('text'),\n content: z.string().min(1),\n cols: z.number().min(1).max(12),\n});\n\nconst WidgetSchema = z.discriminatedUnion('type', [\n ChartWidgetSchema,\n TextWidgetSchema,\n]);\n\n// Row configuration\nconst RowSchema = z.object({\n height: z.number().min(50),\n widgets: z.array(WidgetSchema).min(1),\n});\n\n// Layout configuration\nconst LayoutSchema = z.object({\n gap: z.number().min(0).default(16),\n rows: z.array(RowSchema).min(1),\n});\n\n// Tab configuration\nconst TabSchema = z.object({\n name: z.string().min(1),\n label: z.string().min(1),\n filters: z.array(ParameterSchema).optional(),\n layout: LayoutSchema,\n});\n\n// Main dashboard schema\nexport const DashboardSchema = z.object({\n // Identity\n name: z.string().min(1),\n title: z.string().min(1),\n description: z.string().optional(),\n\n // Filters inherited by all widgets (shared across tabs)\n filters: z.array(ParameterSchema).optional(),\n\n // Layout definition (mutually exclusive with tabs)\n layout: LayoutSchema.optional(),\n\n // Tabbed layout\n tabs: z.array(TabSchema).min(1).optional(),\n}).superRefine((data, ctx) => {\n if (data.layout && data.tabs) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Dashboard must have either \"layout\" or \"tabs\", not both',\n path: ['tabs'],\n });\n }\n if (!data.layout && !data.tabs) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Dashboard must have either \"layout\" or \"tabs\"',\n path: [],\n });\n }\n});\n\nexport type Dashboard = z.infer<typeof DashboardSchema>;\nexport type DashboardTab = z.infer<typeof TabSchema>;\nexport type DashboardLayout = z.infer<typeof LayoutSchema>;\nexport type DashboardRow = z.infer<typeof RowSchema>;\nexport type DashboardWidget = z.infer<typeof WidgetSchema>;\nexport type ChartWidget = z.infer<typeof ChartWidgetSchema>;\nexport type TextWidget = z.infer<typeof TextWidgetSchema>;\n","import { z } from 'zod';\n\nconst SlackChannelSchema = z.object({\n webhook_url: z.string().min(1),\n channel: z.string().optional(),\n});\n\nconst ChannelSchema = z.object({\n slack: SlackChannelSchema,\n});\n\nconst ConditionOperatorSchema = z.enum(['lt', 'gt', 'lte', 'gte', 'eq']);\n\nconst ConditionSchema = z.object({\n field: z.string().min(1),\n operator: ConditionOperatorSchema,\n value: z.number(),\n});\n\nconst ReportScheduleSchema = z.object({\n name: z.string().min(1),\n type: z.literal('report'),\n schedule: z.string().min(1),\n timezone: z.string().optional(),\n channel: ChannelSchema,\n charts: z.array(z.string().min(1)).min(1),\n params: z.record(z.unknown()).optional(),\n message: z.string().optional(),\n notify_on_error: z.boolean().optional(),\n});\n\nconst AlertScheduleSchema = z.object({\n name: z.string().min(1),\n type: z.literal('alert'),\n schedule: z.string().min(1),\n timezone: z.string().optional(),\n channel: ChannelSchema,\n chart: z.string().min(1),\n params: z.record(z.unknown()).optional(),\n condition: ConditionSchema,\n cooldown: z.string().optional(),\n message: z.string().optional(),\n notify_on_error: z.boolean().optional(),\n});\n\nexport const ScheduleSchema = z.discriminatedUnion('type', [\n ReportScheduleSchema,\n AlertScheduleSchema,\n]);\n\nexport type Schedule = z.infer<typeof ScheduleSchema>;\nexport type ReportSchedule = z.infer<typeof ReportScheduleSchema>;\nexport type AlertSchedule = z.infer<typeof AlertScheduleSchema>;\nexport type Condition = z.infer<typeof ConditionSchema>;\nexport type ConditionOperator = z.infer<typeof ConditionOperatorSchema>;\n","import { access } from 'fs/promises';\nimport { join, dirname, resolve } from 'path';\nimport { config as loadDotenv } from 'dotenv';\n\n/**\n * Find the project root by looking for yamchart.yaml.\n * Searches current directory and parent directories.\n */\nexport async function findProjectRoot(startDir: string): Promise<string | null> {\n let currentDir = resolve(startDir);\n const root = dirname(currentDir);\n\n while (currentDir !== root) {\n const configPath = join(currentDir, 'yamchart.yaml');\n try {\n await access(configPath);\n return currentDir;\n } catch {\n currentDir = dirname(currentDir);\n }\n }\n\n // Check root directory too\n try {\n await access(join(root, 'yamchart.yaml'));\n return root;\n } catch {\n return null;\n }\n}\n\n/**\n * Load .env file from project directory.\n */\nexport function loadEnvFile(projectDir: string): void {\n loadDotenv({ path: join(projectDir, '.env') });\n}\n\n/**\n * Resolve ${VAR} syntax in a string from environment variables.\n */\nexport function resolveEnvVars(value: string): string {\n return value.replace(/\\$\\{([^}]+)\\}/g, (match, varName) => {\n const envValue = process.env[varName];\n if (envValue === undefined) {\n throw new Error(`Environment variable not found: ${varName}`);\n }\n return envValue;\n });\n}\n\n/**\n * Recursively resolve env vars in an object.\n */\nexport function resolveEnvVarsInObject<T>(obj: T): T {\n if (typeof obj === 'string') {\n return resolveEnvVars(obj) as T;\n }\n if (Array.isArray(obj)) {\n return obj.map(resolveEnvVarsInObject) as T;\n }\n if (obj !== null && typeof obj === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[key] = resolveEnvVarsInObject(value);\n }\n return result as T;\n }\n return obj;\n}\n"],"mappings":"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","names":["z","z","AuthSchema","z","z","z","z","access","join"]}
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
ScheduleSchema,
|
|
7
7
|
loadEnvFile,
|
|
8
8
|
validateProject
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ENOTMVPI.js";
|
|
10
10
|
import {
|
|
11
11
|
AuthDatabase,
|
|
12
12
|
generateSessionToken,
|
|
@@ -289,6 +289,10 @@ var ConfigLoader = class {
|
|
|
289
289
|
return this.models.get(name);
|
|
290
290
|
}
|
|
291
291
|
getDefaultConnection() {
|
|
292
|
+
const envConnection = process.env.YAMCHART_CONNECTION;
|
|
293
|
+
if (envConnection) {
|
|
294
|
+
return this.connections.get(envConnection);
|
|
295
|
+
}
|
|
292
296
|
const defaultName = this.project?.defaults?.connection;
|
|
293
297
|
if (defaultName) {
|
|
294
298
|
return this.connections.get(defaultName);
|
|
@@ -529,6 +533,49 @@ function createConnectorFromConfig(connection, options) {
|
|
|
529
533
|
throw new Error(`Unsupported connection type: ${connection.type}`);
|
|
530
534
|
}
|
|
531
535
|
}
|
|
536
|
+
function buildConnectionInfo(connection) {
|
|
537
|
+
const info2 = {
|
|
538
|
+
name: connection.name,
|
|
539
|
+
type: connection.type
|
|
540
|
+
};
|
|
541
|
+
switch (connection.type) {
|
|
542
|
+
case "duckdb": {
|
|
543
|
+
const c = connection;
|
|
544
|
+
info2.path = c.config.path;
|
|
545
|
+
break;
|
|
546
|
+
}
|
|
547
|
+
case "postgres": {
|
|
548
|
+
const c = connection;
|
|
549
|
+
info2.host = c.config.host;
|
|
550
|
+
info2.port = c.config.port;
|
|
551
|
+
info2.database = c.config.database;
|
|
552
|
+
info2.schema = c.config.schema;
|
|
553
|
+
break;
|
|
554
|
+
}
|
|
555
|
+
case "mysql": {
|
|
556
|
+
const c = connection;
|
|
557
|
+
info2.host = c.config.host;
|
|
558
|
+
info2.port = c.config.port;
|
|
559
|
+
info2.database = c.config.database;
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
562
|
+
case "sqlite": {
|
|
563
|
+
const c = connection;
|
|
564
|
+
info2.path = c.config.path;
|
|
565
|
+
break;
|
|
566
|
+
}
|
|
567
|
+
case "snowflake": {
|
|
568
|
+
const c = connection;
|
|
569
|
+
info2.account = c.config.account;
|
|
570
|
+
info2.warehouse = c.config.warehouse;
|
|
571
|
+
info2.database = c.config.database;
|
|
572
|
+
info2.schema = c.config.schema;
|
|
573
|
+
info2.role = c.config.role;
|
|
574
|
+
break;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
return info2;
|
|
578
|
+
}
|
|
532
579
|
async function testConnection(connection, options) {
|
|
533
580
|
const start = performance.now();
|
|
534
581
|
let connector = null;
|
|
@@ -799,12 +846,30 @@ async function dashboardRoutes(fastify, options) {
|
|
|
799
846
|
});
|
|
800
847
|
fastify.post("/api/dashboards/:id", async (request, reply) => {
|
|
801
848
|
const { id } = request.params;
|
|
802
|
-
const { layout, message } = request.body;
|
|
849
|
+
const { layout, tab, tabLayout, message } = request.body;
|
|
803
850
|
const dashboard = configLoader.getDashboardByName(id);
|
|
804
851
|
if (!dashboard) {
|
|
805
852
|
return reply.status(404).send({ error: `Dashboard not found: ${id}` });
|
|
806
853
|
}
|
|
807
|
-
|
|
854
|
+
let updated;
|
|
855
|
+
if (dashboard.tabs) {
|
|
856
|
+
if (!tab || !tabLayout) {
|
|
857
|
+
return reply.status(400).send({ error: 'Tabbed dashboard requires "tab" and "tabLayout" fields' });
|
|
858
|
+
}
|
|
859
|
+
const tabIndex = dashboard.tabs.findIndex((t) => t.name === tab);
|
|
860
|
+
if (tabIndex === -1) {
|
|
861
|
+
return reply.status(400).send({ error: `Tab not found: ${tab}` });
|
|
862
|
+
}
|
|
863
|
+
const existingTab = dashboard.tabs[tabIndex];
|
|
864
|
+
const newTabs = [...dashboard.tabs];
|
|
865
|
+
newTabs[tabIndex] = { ...existingTab, layout: tabLayout };
|
|
866
|
+
updated = { ...dashboard, tabs: newTabs };
|
|
867
|
+
} else {
|
|
868
|
+
if (!layout) {
|
|
869
|
+
return reply.status(400).send({ error: 'Non-tabbed dashboard requires "layout" field' });
|
|
870
|
+
}
|
|
871
|
+
updated = { ...dashboard, layout };
|
|
872
|
+
}
|
|
808
873
|
const filePath = join3(projectDir, "dashboards", `${id}.yaml`);
|
|
809
874
|
await writeFile(filePath, stringifyYaml(updated));
|
|
810
875
|
await configLoader.load();
|
|
@@ -818,7 +883,7 @@ async function dashboardRoutes(fastify, options) {
|
|
|
818
883
|
});
|
|
819
884
|
fastify.post("/api/dashboards/:id/warm-cache", async (request, reply) => {
|
|
820
885
|
const { id } = request.params;
|
|
821
|
-
const { params = {} } = request.body;
|
|
886
|
+
const { params = {}, tab } = request.body;
|
|
822
887
|
const dashboard = configLoader.getDashboardByName(id);
|
|
823
888
|
if (!dashboard) {
|
|
824
889
|
return reply.status(404).send({ error: `Dashboard not found: ${id}` });
|
|
@@ -827,12 +892,28 @@ async function dashboardRoutes(fastify, options) {
|
|
|
827
892
|
return reply.status(500).send({ error: "Query service not available" });
|
|
828
893
|
}
|
|
829
894
|
const chartRefs = [];
|
|
830
|
-
|
|
831
|
-
for (const
|
|
832
|
-
|
|
833
|
-
|
|
895
|
+
const extractFromLayout = (layout) => {
|
|
896
|
+
for (const row of layout.rows) {
|
|
897
|
+
for (const widget of row.widgets) {
|
|
898
|
+
if (widget.type === "chart" && widget.ref) {
|
|
899
|
+
chartRefs.push(widget.ref);
|
|
900
|
+
}
|
|
834
901
|
}
|
|
835
902
|
}
|
|
903
|
+
};
|
|
904
|
+
if (dashboard.tabs) {
|
|
905
|
+
if (tab) {
|
|
906
|
+
const matchingTab = dashboard.tabs.find((t) => t.name === tab);
|
|
907
|
+
if (matchingTab) {
|
|
908
|
+
extractFromLayout(matchingTab.layout);
|
|
909
|
+
}
|
|
910
|
+
} else {
|
|
911
|
+
for (const t of dashboard.tabs) {
|
|
912
|
+
extractFromLayout(t.layout);
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
} else if (dashboard.layout) {
|
|
916
|
+
extractFromLayout(dashboard.layout);
|
|
836
917
|
}
|
|
837
918
|
const results = await Promise.all(chartRefs.map(async (chartRef) => {
|
|
838
919
|
const chart = configLoader.getChartByName(chartRef);
|
|
@@ -13326,32 +13407,8 @@ async function createServer(options) {
|
|
|
13326
13407
|
if (!defaultConnection) {
|
|
13327
13408
|
throw new Error("No connection configured");
|
|
13328
13409
|
}
|
|
13329
|
-
|
|
13330
|
-
|
|
13331
|
-
const duckdbConfig = defaultConnection;
|
|
13332
|
-
const dbPath = duckdbConfig.config.path.startsWith("/") ? duckdbConfig.config.path : join4(projectDir, duckdbConfig.config.path);
|
|
13333
|
-
connector = new DuckDBConnector({ path: dbPath });
|
|
13334
|
-
await connector.connect();
|
|
13335
|
-
} else if (defaultConnection.type === "postgres") {
|
|
13336
|
-
const pgConnection = defaultConnection;
|
|
13337
|
-
const credentials = resolvePostgresAuth(pgConnection);
|
|
13338
|
-
connector = new PostgresConnector({
|
|
13339
|
-
host: pgConnection.config.host,
|
|
13340
|
-
port: pgConnection.config.port,
|
|
13341
|
-
database: pgConnection.config.database,
|
|
13342
|
-
schema: pgConnection.config.schema,
|
|
13343
|
-
ssl: pgConnection.config.ssl,
|
|
13344
|
-
user: credentials.user,
|
|
13345
|
-
password: credentials.password,
|
|
13346
|
-
min: pgConnection.pool?.min_connections,
|
|
13347
|
-
max: pgConnection.pool?.max_connections,
|
|
13348
|
-
idleTimeoutMillis: pgConnection.pool?.idle_timeout,
|
|
13349
|
-
statementTimeout: pgConnection.query?.timeout
|
|
13350
|
-
});
|
|
13351
|
-
await connector.connect();
|
|
13352
|
-
} else {
|
|
13353
|
-
throw new Error(`Unsupported connection type: ${defaultConnection.type}`);
|
|
13354
|
-
}
|
|
13410
|
+
const connector = createConnectorFromConfig(defaultConnection, { projectDir });
|
|
13411
|
+
await connector.connect();
|
|
13355
13412
|
const project = configLoader.getProject();
|
|
13356
13413
|
const cacheTtl = project.defaults?.cache_ttl ? parseTtl2(project.defaults.cache_ttl) : 5 * 60 * 1e3;
|
|
13357
13414
|
const cache = new MemoryCache({
|
|
@@ -13383,26 +13440,16 @@ async function createServer(options) {
|
|
|
13383
13440
|
if (schedules.length > 0) {
|
|
13384
13441
|
schedulerService.start(schedules);
|
|
13385
13442
|
}
|
|
13386
|
-
|
|
13387
|
-
|
|
13388
|
-
|
|
13389
|
-
|
|
13390
|
-
|
|
13391
|
-
|
|
13392
|
-
|
|
13393
|
-
|
|
13394
|
-
|
|
13395
|
-
|
|
13396
|
-
schema: defaultConnection.config.schema
|
|
13397
|
-
}
|
|
13398
|
-
};
|
|
13399
|
-
fastify.get("/api/health", async () => ({
|
|
13400
|
-
status: "ok",
|
|
13401
|
-
version: VERSION,
|
|
13402
|
-
project: project.name,
|
|
13403
|
-
environment: process.env.NODE_ENV || "development",
|
|
13404
|
-
connection: connectionInfo
|
|
13405
|
-
}));
|
|
13443
|
+
fastify.get("/api/health", async () => {
|
|
13444
|
+
const currentConnection = configLoader.getDefaultConnection();
|
|
13445
|
+
return {
|
|
13446
|
+
status: "ok",
|
|
13447
|
+
version: VERSION,
|
|
13448
|
+
project: configLoader.getProject().name,
|
|
13449
|
+
environment: process.env.NODE_ENV || "development",
|
|
13450
|
+
connection: currentConnection ? buildConnectionInfo(currentConnection) : void 0
|
|
13451
|
+
};
|
|
13452
|
+
});
|
|
13406
13453
|
if (authDb) {
|
|
13407
13454
|
const secureCookies = process.env.NODE_ENV === "production";
|
|
13408
13455
|
const sessionTtlMs = options.localAuth.sessionTtlMs;
|
|
@@ -13554,24 +13601,41 @@ async function runDevServer(projectDir, options) {
|
|
|
13554
13601
|
}
|
|
13555
13602
|
success(`Validation passed (${validation.stats.passed} files)`);
|
|
13556
13603
|
newline();
|
|
13557
|
-
|
|
13558
|
-
let
|
|
13604
|
+
let usesBrowserAuth = false;
|
|
13605
|
+
let localAuth;
|
|
13559
13606
|
try {
|
|
13560
|
-
|
|
13561
|
-
|
|
13562
|
-
|
|
13563
|
-
|
|
13564
|
-
|
|
13565
|
-
|
|
13566
|
-
|
|
13567
|
-
|
|
13568
|
-
|
|
13569
|
-
|
|
13570
|
-
|
|
13571
|
-
|
|
13607
|
+
const { readFileSync } = await import("fs");
|
|
13608
|
+
const { parse } = await import("yaml");
|
|
13609
|
+
const raw = readFileSync(resolve(projectDir, "yamchart.yaml"), "utf-8");
|
|
13610
|
+
const projectConfig = parse(raw);
|
|
13611
|
+
if (projectConfig?.auth?.enabled) {
|
|
13612
|
+
localAuth = {
|
|
13613
|
+
enabled: true,
|
|
13614
|
+
dbPath: projectConfig.auth.db_path ? resolve(projectConfig.auth.db_path.replace(/^~/, homedir())) : resolve(homedir(), ".yamchart", "auth.db"),
|
|
13615
|
+
sessionTtlMs: projectConfig.auth.session_ttl ? parseTtl(projectConfig.auth.session_ttl) : 30 * 24 * 60 * 60 * 1e3
|
|
13616
|
+
};
|
|
13617
|
+
}
|
|
13618
|
+
const connectionDir = resolve(projectDir, "connections");
|
|
13619
|
+
const targetConn = process.env.YAMCHART_CONNECTION || projectConfig?.defaults?.connection;
|
|
13620
|
+
if (targetConn) {
|
|
13621
|
+
try {
|
|
13622
|
+
const connRaw = readFileSync(resolve(connectionDir, `${targetConn}.yaml`), "utf-8");
|
|
13623
|
+
const connConfig = parse(connRaw);
|
|
13624
|
+
if (connConfig?.auth?.type === "externalbrowser") {
|
|
13625
|
+
usesBrowserAuth = true;
|
|
13626
|
+
}
|
|
13627
|
+
} catch {
|
|
13572
13628
|
}
|
|
13573
|
-
} catch {
|
|
13574
13629
|
}
|
|
13630
|
+
} catch {
|
|
13631
|
+
}
|
|
13632
|
+
if (usesBrowserAuth) {
|
|
13633
|
+
info("Snowflake SSO \u2014 opening browser for authentication...");
|
|
13634
|
+
newline();
|
|
13635
|
+
}
|
|
13636
|
+
const spinner2 = spinner("Starting server...");
|
|
13637
|
+
let server;
|
|
13638
|
+
try {
|
|
13575
13639
|
server = await createServer({
|
|
13576
13640
|
projectDir,
|
|
13577
13641
|
port: options.port,
|
|
@@ -13621,4 +13685,4 @@ async function runDevServer(projectDir, options) {
|
|
|
13621
13685
|
export {
|
|
13622
13686
|
runDevServer
|
|
13623
13687
|
};
|
|
13624
|
-
//# sourceMappingURL=dev-
|
|
13688
|
+
//# sourceMappingURL=dev-CPZ3M5EE.js.map
|