react-semaphor 0.1.346 → 0.1.347

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("../chunks/validators-8R9pr2K9.js"),t=require("../chunks/catalog-field-grounding-Du6mKDcF.js");function d(e,a={}){const i=o(e),s={connectionId:a.connectionId,connectionType:e,path:["database","schema","table"],labels:{database:"Database",schema:"Schema",table:"Table"},prefixLevels:["database","schema","table"],dialect:"postgres",supportsFilterClause:!0};return i.includes("postgres")?{...s,prefixLevels:["schema","table"],dialect:"postgres"}:i.includes("mysql")?{...s,prefixLevels:["database","table"],dialect:"mysql",supportsFilterClause:!1}:i.includes("mssql")||i.includes("sqlserver")?{...s,dialect:"mssql",supportsFilterClause:!1}:i.includes("redshift")?{...s,prefixLevels:["schema","table"],dialect:"redshift"}:i.includes("snowflake")?{...s,dialect:"snowflake"}:i.includes("clickhouse")?{connectionId:a.connectionId,connectionType:e,path:["database","table"],labels:{database:"Database",table:"Table"},prefixLevels:["database","table"],dialect:"clickhouse",supportsFilterClause:!1}:i==="s3"||i==="api"?{connectionId:a.connectionId,connectionType:e,path:["table"],labels:{table:i==="api"?"API Table":"File Table"},prefixLevels:["table"],dialect:"duckdb",supportsFilterClause:!0}:i==="googlesheets"||i==="fileupload"?{connectionId:a.connectionId,connectionType:e,path:["table"],labels:{table:"Table"},prefixLevels:["table"],dialect:"postgres",supportsFilterClause:!0}:i==="s3tables"?{...s,labels:{database:"Database",schema:"Namespace",table:"Table"},dialect:"duckdb"}:i==="bigquery"?{...s,labels:{database:"Project",schema:"Dataset",table:"Table"},prefixLevels:["schema","table"],dialect:"bigquery",supportsFilterClause:!1}:s}function c(e){const a=o(e);switch(a){case"mysql":case"bigquery":case"redshift":case"snowflake":case"clickhouse":case"duckdb":case"sqlite":return a;case"mssql":case"sqlserver":return"mssql";case"postgres":case"postgresql":return"postgres";default:return"unknown"}}function u(e){return e.capabilities.prefixLevels.every(a=>!!l(e.source,a))}function m(e){const a=e.quoteIdentifier??p;return e.capabilities.prefixLevels.map(i=>l(e.source,i)).filter(i=>!!i).map(i=>a(i,e.capabilities.dialect)).join(".")}function l(e,a){return a==="database"?e.databaseName:a==="schema"?e.schemaName:e.tableName}function p(e,a){return a==="mysql"||a==="bigquery"||a==="clickhouse"||a==="duckdb"?`\`${e.replace(/`/g,"``")}\``:a==="mssql"?`[${e.replace(/]/g,"]]")}]`:`"${e.replace(/"/g,'""')}"`}function o(e){if(typeof e!="string")return"";const a=[];for(const i of e.trim().toLowerCase())b(i)&&a.push(i);return a.join("")}function b(e){const a=e.charCodeAt(0);return a>=48&&a<=57||a>=97&&a<=122}const n={kind:"semantic",domainId:"domain_sales",datasetName:"orders",connectionId:"conn_sales",label:"Orders"},f={revenueKpi:{version:1,kind:"metric",id:"revenue-kpi",label:"Revenue",source:n,metrics:[{name:"revenue",role:"measure"}],primaryMetric:{name:"revenue",role:"measure"},comparison:{kind:"previous_period"},limit:1},revenueTrend:{version:1,kind:"records",id:"revenue-trend",label:"Revenue trend",source:n,fields:[{name:"order_date",role:"date",dataType:"date",label:"Order Date"},{name:"revenue",role:"measure",dataType:"number"}],dateField:{name:"order_date",role:"date",dataType:"date"},timeGrain:"month",limit:100},topCustomersRecords:{version:1,kind:"records",id:"top-customers",label:"Top customers",source:n,fields:[{name:"customer_name",role:"dimension",dataType:"string"},{name:"segment",role:"dimension",dataType:"string"},{name:"revenue",role:"measure",dataType:"number"}],orderBy:{field:{name:"revenue",role:"measure"},direction:"desc"},limit:20},regionInputOptions:{version:1,kind:"inputOptions",id:"region-options",label:"Region options",source:n,field:{name:"region",role:"dimension",dataType:"string"},limit:100},previousPeriodRevenueComparison:{version:1,kind:"metric",id:"revenue-previous-period",label:"Revenue previous period comparison",source:n,metrics:[{name:"revenue",role:"measure"}],primaryMetric:{name:"revenue",role:"measure"},dateField:{name:"order_date",role:"date",dataType:"date"},timeGrain:"week",comparison:{kind:"previous_period"},limit:100},inboundSupplierConcentration:{version:1,kind:"metric",id:"inbound-supplier-concentration",label:"Inbound supplier concentration",source:n,metrics:[{name:"net_tons",role:"measure"},{name:"ticket_value",role:"measure"}],primaryMetric:{name:"net_tons",role:"measure"},dateField:{name:"ticket_date",role:"date",dataType:"date"},timeWindow:{unit:"month",value:6,anchor:"latest_available"},dimensions:[{name:"supplier_id",role:"dimension",dataType:"number"}],filters:[{field:{name:"direction",role:"dimension",dataType:"string"},operator:"=",values:["Inbound"]}],limit:15},boundedSqlRanking:{version:1,kind:"sql",id:"top-customer-ranking-sql",label:"Top customer ranking SQL",source:{kind:"sql",connectionId:"conn_sales",dialect:"postgres"},sql:"SELECT customer_name, SUM(revenue) AS revenue FROM public.orders GROUP BY customer_name ORDER BY revenue DESC LIMIT 20",limit:20,rationale:"Ranking is SQL-natural because it requires ordering grouped aggregate rows.",fields:[{name:"customer_name",role:"dimension",dataType:"string"},{name:"revenue",role:"measure",dataType:"number"}]}};exports.preferSemaphorFieldRefMetadata=r.preferSemaphorFieldRefMetadata;exports.preferSemaphorSourceMetadata=r.preferSemaphorSourceMetadata;exports.semaphorFieldRefsMatch=r.semaphorFieldRefsMatch;exports.semaphorSourceIdentityKey=r.semaphorSourceIdentityKey;exports.semaphorSourcesReferToSameDataset=r.semaphorSourcesReferToSameDataset;exports.validateSemaphorAnalyticsIntent=r.validateSemaphorAnalyticsIntent;exports.validateSemaphorAnalyticsRecoveryPlan=r.validateSemaphorAnalyticsRecoveryPlan;exports.validateSemaphorDashboardIntent=r.validateSemaphorDashboardIntent;exports.validateSemaphorOperationIntent=r.validateSemaphorOperationIntent;exports.buildAnalyticsCatalogFieldSummary=t.buildAnalyticsCatalogFieldSummary;exports.getAnalyticsCatalogFieldCandidates=t.getAnalyticsCatalogFieldCandidates;exports.getAnalyticsCatalogFieldName=t.getAnalyticsCatalogFieldName;exports.isAnalyticsCatalogDateField=t.isAnalyticsCatalogDateField;exports.isAnalyticsCatalogDimensionField=t.isAnalyticsCatalogDimensionField;exports.isAnalyticsCatalogMetricField=t.isAnalyticsCatalogMetricField;exports.isAnalyticsDateLikeDataType=t.isAnalyticsDateLikeDataType;exports.isAnalyticsMetricIdentifierField=t.isAnalyticsMetricIdentifierField;exports.isAnalyticsTechnicalIdentifierField=t.isAnalyticsTechnicalIdentifierField;exports.normalizeAnalyticsCatalogDataType=t.normalizeAnalyticsCatalogDataType;exports.normalizeAnalyticsCatalogName=t.normalizeAnalyticsCatalogName;exports.SEMAPHOR_ANALYTICS_INTENT_FIXTURES=f;exports.buildSemaphorQualifiedSourcePath=m;exports.getSemaphorConnectionCapabilities=d;exports.normalizeSemaphorDialect=c;exports.semaphorSourceHasRequiredCoordinates=u;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("../chunks/validators-Bu5tOTYW.js"),t=require("../chunks/catalog-field-grounding-Du6mKDcF.js");function d(e,a={}){const i=o(e),s={connectionId:a.connectionId,connectionType:e,path:["database","schema","table"],labels:{database:"Database",schema:"Schema",table:"Table"},prefixLevels:["database","schema","table"],dialect:"postgres",supportsFilterClause:!0};return i.includes("postgres")?{...s,prefixLevels:["schema","table"],dialect:"postgres"}:i.includes("mysql")?{...s,prefixLevels:["database","table"],dialect:"mysql",supportsFilterClause:!1}:i.includes("mssql")||i.includes("sqlserver")?{...s,dialect:"mssql",supportsFilterClause:!1}:i.includes("redshift")?{...s,prefixLevels:["schema","table"],dialect:"redshift"}:i.includes("snowflake")?{...s,dialect:"snowflake"}:i.includes("clickhouse")?{connectionId:a.connectionId,connectionType:e,path:["database","table"],labels:{database:"Database",table:"Table"},prefixLevels:["database","table"],dialect:"clickhouse",supportsFilterClause:!1}:i==="s3"||i==="api"?{connectionId:a.connectionId,connectionType:e,path:["table"],labels:{table:i==="api"?"API Table":"File Table"},prefixLevels:["table"],dialect:"duckdb",supportsFilterClause:!0}:i==="googlesheets"||i==="fileupload"?{connectionId:a.connectionId,connectionType:e,path:["table"],labels:{table:"Table"},prefixLevels:["table"],dialect:"postgres",supportsFilterClause:!0}:i==="s3tables"?{...s,labels:{database:"Database",schema:"Namespace",table:"Table"},dialect:"duckdb"}:i==="bigquery"?{...s,labels:{database:"Project",schema:"Dataset",table:"Table"},prefixLevels:["schema","table"],dialect:"bigquery",supportsFilterClause:!1}:s}function c(e){const a=o(e);switch(a){case"mysql":case"bigquery":case"redshift":case"snowflake":case"clickhouse":case"duckdb":case"sqlite":return a;case"mssql":case"sqlserver":return"mssql";case"postgres":case"postgresql":return"postgres";default:return"unknown"}}function u(e){return e.capabilities.prefixLevels.every(a=>!!l(e.source,a))}function m(e){const a=e.quoteIdentifier??p;return e.capabilities.prefixLevels.map(i=>l(e.source,i)).filter(i=>!!i).map(i=>a(i,e.capabilities.dialect)).join(".")}function l(e,a){return a==="database"?e.databaseName:a==="schema"?e.schemaName:e.tableName}function p(e,a){return a==="mysql"||a==="bigquery"||a==="clickhouse"||a==="duckdb"?`\`${e.replace(/`/g,"``")}\``:a==="mssql"?`[${e.replace(/]/g,"]]")}]`:`"${e.replace(/"/g,'""')}"`}function o(e){if(typeof e!="string")return"";const a=[];for(const i of e.trim().toLowerCase())b(i)&&a.push(i);return a.join("")}function b(e){const a=e.charCodeAt(0);return a>=48&&a<=57||a>=97&&a<=122}const n={kind:"semantic",domainId:"domain_sales",datasetName:"orders",connectionId:"conn_sales",label:"Orders"},f={revenueKpi:{version:1,kind:"metric",id:"revenue-kpi",label:"Revenue",source:n,metrics:[{name:"revenue",role:"measure"}],primaryMetric:{name:"revenue",role:"measure"},comparison:{kind:"previous_period"},limit:1},revenueTrend:{version:1,kind:"records",id:"revenue-trend",label:"Revenue trend",source:n,fields:[{name:"order_date",role:"date",dataType:"date",label:"Order Date"},{name:"revenue",role:"measure",dataType:"number"}],dateField:{name:"order_date",role:"date",dataType:"date"},timeGrain:"month",limit:100},topCustomersRecords:{version:1,kind:"records",id:"top-customers",label:"Top customers",source:n,fields:[{name:"customer_name",role:"dimension",dataType:"string"},{name:"segment",role:"dimension",dataType:"string"},{name:"revenue",role:"measure",dataType:"number"}],orderBy:{field:{name:"revenue",role:"measure"},direction:"desc"},limit:20},regionInputOptions:{version:1,kind:"inputOptions",id:"region-options",label:"Region options",source:n,field:{name:"region",role:"dimension",dataType:"string"},limit:100},previousPeriodRevenueComparison:{version:1,kind:"metric",id:"revenue-previous-period",label:"Revenue previous period comparison",source:n,metrics:[{name:"revenue",role:"measure"}],primaryMetric:{name:"revenue",role:"measure"},dateField:{name:"order_date",role:"date",dataType:"date"},timeGrain:"week",comparison:{kind:"previous_period"},limit:100},inboundSupplierConcentration:{version:1,kind:"metric",id:"inbound-supplier-concentration",label:"Inbound supplier concentration",source:n,metrics:[{name:"net_tons",role:"measure"},{name:"ticket_value",role:"measure"}],primaryMetric:{name:"net_tons",role:"measure"},dateField:{name:"ticket_date",role:"date",dataType:"date"},timeWindow:{unit:"month",value:6,anchor:"latest_available"},dimensions:[{name:"supplier_id",role:"dimension",dataType:"number"}],filters:[{field:{name:"direction",role:"dimension",dataType:"string"},operator:"=",values:["Inbound"]}],limit:15},boundedSqlRanking:{version:1,kind:"sql",id:"top-customer-ranking-sql",label:"Top customer ranking SQL",source:{kind:"sql",connectionId:"conn_sales",dialect:"postgres"},sql:"SELECT customer_name, SUM(revenue) AS revenue FROM public.orders GROUP BY customer_name ORDER BY revenue DESC LIMIT 20",limit:20,rationale:"Ranking is SQL-natural because it requires ordering grouped aggregate rows.",fields:[{name:"customer_name",role:"dimension",dataType:"string"},{name:"revenue",role:"measure",dataType:"number"}]}};exports.preferSemaphorFieldRefMetadata=r.preferSemaphorFieldRefMetadata;exports.preferSemaphorSourceMetadata=r.preferSemaphorSourceMetadata;exports.semaphorFieldRefsMatch=r.semaphorFieldRefsMatch;exports.semaphorSourceIdentityKey=r.semaphorSourceIdentityKey;exports.semaphorSourcesReferToSameDataset=r.semaphorSourcesReferToSameDataset;exports.validateSemaphorAnalyticsIntent=r.validateSemaphorAnalyticsIntent;exports.validateSemaphorAnalyticsRecoveryPlan=r.validateSemaphorAnalyticsRecoveryPlan;exports.validateSemaphorDashboardIntent=r.validateSemaphorDashboardIntent;exports.validateSemaphorOperationIntent=r.validateSemaphorOperationIntent;exports.buildAnalyticsCatalogFieldSummary=t.buildAnalyticsCatalogFieldSummary;exports.getAnalyticsCatalogFieldCandidates=t.getAnalyticsCatalogFieldCandidates;exports.getAnalyticsCatalogFieldName=t.getAnalyticsCatalogFieldName;exports.isAnalyticsCatalogDateField=t.isAnalyticsCatalogDateField;exports.isAnalyticsCatalogDimensionField=t.isAnalyticsCatalogDimensionField;exports.isAnalyticsCatalogMetricField=t.isAnalyticsCatalogMetricField;exports.isAnalyticsDateLikeDataType=t.isAnalyticsDateLikeDataType;exports.isAnalyticsMetricIdentifierField=t.isAnalyticsMetricIdentifierField;exports.isAnalyticsTechnicalIdentifierField=t.isAnalyticsTechnicalIdentifierField;exports.normalizeAnalyticsCatalogDataType=t.normalizeAnalyticsCatalogDataType;exports.normalizeAnalyticsCatalogName=t.normalizeAnalyticsCatalogName;exports.SEMAPHOR_ANALYTICS_INTENT_FIXTURES=f;exports.buildSemaphorQualifiedSourcePath=m;exports.getSemaphorConnectionCapabilities=d;exports.normalizeSemaphorDialect=c;exports.semaphorSourceHasRequiredCoordinates=u;
@@ -1,4 +1,4 @@
1
- import { f as v, p as h, e as g, s as y, d as k, v as C, b as I, c as S, a as T } from "../chunks/validators-yMB7Tm4j.js";
1
+ import { f as v, p as h, e as g, s as y, d as k, v as C, b as I, c as S, a as T } from "../chunks/validators-ZeP5TVCl.js";
2
2
  import { j as F, a as _, g as A, c as R, h as L, f as D, i as x, e as M, d as N, b as w, n as O } from "../chunks/catalog-field-grounding-DoEBOXQd.js";
3
3
  function d(e, a = {}) {
4
4
  const r = n(e), t = {
@@ -0,0 +1 @@
1
+ "use strict";function _(e){return e?e.kind==="semantic"?[e.kind,e.domainId,e.datasetId||"",e.datasetName].join(":"):e.kind==="physical"?[e.kind,e.connectionId,e.databaseName||"",e.schemaName||"",e.tableName].join(":"):[e.kind,e.connectionId,e.dialect||"",e.label||""].join(":"):""}function b(e,i){return!e||!i?e===i:e.kind!==i.kind?!1:e.kind==="semantic"&&i.kind==="semantic"?e.domainId!==i.domainId?!1:e.datasetId&&i.datasetId?e.datasetId===i.datasetId:e.datasetName===i.datasetName:_(e)===_(i)}function A(e,i){return e.kind!=="semantic"||i.kind!=="semantic"?e:{...e,datasetId:e.datasetId||i.datasetId,label:e.label||i.label,connectionId:e.connectionId||i.connectionId}}function w(e,i){return e.name===i.name&&b(e.source,i.source)}function F(e,i){return{...e,label:e.label||i.label,role:e.role||i.role,dataType:e.dataType||i.dataType,source:e.source&&i.source?A(e.source,i.source):e.source||i.source}}function a(e,i,n){return n?{code:e,message:i,path:n}:{code:e,message:i}}function j(e){for(let i=0;i<e.length;i+=1){const n=e[i];if(e.some((o,r)=>r!==i&&I(o,n)))return!1}return!0}function S(e,i){return w(e,i)}function I(e,i){return S(e,i)&&y(e)===y(i)}function x(e){return`Metric intent has duplicate metric "${e.name}" with the same aggregate (${y(e)}). Use different aggregates to request both, or remove one entry.`}function T(e,i){return h(e,i).length===1}function D(e,i){return h(e,i).length===1}function h(e,i){return i.filter(o=>q(e,o))}function q(e,i){return C(e,i)?e.source?S(i,e):!0:!1}function C(e,i){return!(i.name!==e.name||e.role!==void 0&&i.role!==void 0&&i.role!==e.role||E(e,i)&&y(i)!==y(e))}function E(e,i){return e.role==="measure"||i.role==="measure"||e.aggregate!==void 0||i.aggregate!==void 0}function y(e){return(e.aggregate||"SUM").toUpperCase()}function d(e){return typeof e=="string"&&e.trim().length>0}function c(e){return!!(e&&typeof e=="object"&&!Array.isArray(e))}function g(e){const i=new Set;for(const n of e){if(i.has(n))return n;i.add(n)}return null}const P=new Set(["SUM","COUNT","AVG","MIN","MAX","MEDIAN","DISTINCT"]);function M(e,i,n){if(!e||typeof e!="object"){n.push(a("missing_source","Analytics intent needs a source.",i));return}if(e.kind==="semantic"){d(e.domainId)||n.push(a("missing_semantic_domain","Semantic source needs a domainId.",`${i}.domainId`)),d(e.datasetName)||n.push(a("missing_dataset_name","Semantic source needs a datasetName.",`${i}.datasetName`));return}if(e.kind==="physical"){d(e.connectionId)||n.push(a("missing_connection_id","Physical source needs a connectionId.",`${i}.connectionId`)),d(e.tableName)||n.push(a("missing_table_name","Physical source needs a tableName.",`${i}.tableName`));return}if(e.kind==="sql"){d(e.connectionId)||n.push(a("missing_connection_id","SQL source needs a connectionId.",`${i}.connectionId`));return}n.push(a("invalid_source_kind","Source kind is not supported.",i))}function f(e,i,n,o={}){if(!e||!c(e)){o.required&&n.push(a("missing_field_ref","Field reference needs a name.",i));return}d(e.name)||n.push(a("missing_field_ref","Field reference needs a name.",`${i}.name`)),e.source!==void 0&&M(e.source,`${i}.source`,n),O(e.aggregate,`${i}.aggregate`,n)}function O(e,i,n){e!==void 0&&(typeof e!="string"||!P.has(e))&&n.push(a("invalid_aggregate","Field aggregate must be SUM, COUNT, AVG, MIN, MAX, MEDIAN, or DISTINCT.",i))}function U(e,i){if(e.analysis===void 0)return;if(!c(e.analysis)){i.push(a("invalid_metric_analysis","Metric analysis must be a structured object.","analysis"));return}if(e.analysis.kind!=="period_change"){i.push(a("invalid_metric_analysis","Metric analysis kind is not supported.","analysis.kind"));return}e.dateField||i.push(a("missing_analysis_date_field","Period-change analysis needs a dateField.","dateField")),e.timeGrain||i.push(a("missing_analysis_time_grain","Period-change analysis needs a timeGrain.","timeGrain")),e.analysis.orderBy!==void 0&&e.analysis.orderBy!=="absolute_change"&&e.analysis.orderBy!=="positive_change"&&e.analysis.orderBy!=="negative_change"&&e.analysis.orderBy!=="period"&&i.push(a("invalid_metric_analysis","Period-change analysis orderBy must be absolute_change, positive_change, negative_change, or period.","analysis.orderBy"));const{timeWindow:n}=e.analysis;n!==void 0&&k(n,"analysis.timeWindow",i)}function k(e,i,n){if(!c(e)){n.push(a("invalid_time_window","Time window must be a structured object.",i));return}e.unit!=="second"&&e.unit!=="minute"&&e.unit!=="hour"&&e.unit!=="day"&&e.unit!=="week"&&e.unit!=="month"&&e.unit!=="quarter"&&e.unit!=="year"&&n.push(a("invalid_time_window","Time window unit must be second, minute, hour, day, week, month, quarter, or year.",`${i}.unit`)),(typeof e.value!="number"||!Number.isFinite(e.value)||e.value<=0)&&n.push(a("invalid_time_window","Time window value must be a positive number.",`${i}.value`)),e.anchor!==void 0&&e.anchor!=="now"&&e.anchor!=="latest_available"&&n.push(a("invalid_time_window","Time window anchor must be now or latest_available.",`${i}.anchor`)),e.completeness!==void 0&&e.completeness!=="include_partial"&&e.completeness!=="complete_periods"&&n.push(a("invalid_time_window","Time window completeness must be include_partial or complete_periods.",`${i}.completeness`))}function H(e,i,n){if(e!==void 0){if(!Array.isArray(e)){n.push(a("invalid_analytics_filters","Analytics filters must be an array.",i));return}e.forEach((o,r)=>{const t=`${i}.${r}`;if(!c(o)){n.push(a("invalid_analytics_filter","Analytics filter must be a structured object.",t));return}const s=o;f(s.field,`${t}.field`,n,{required:!0});const m=s.operator==="is_null"||s.operator==="is_not_null";if(s.operator!==void 0&&s.operator!=="="&&s.operator!=="!="&&s.operator!=="in"&&s.operator!=="not_in"&&s.operator!=="contains"&&s.operator!=="not_contains"&&s.operator!=="between"&&s.operator!=="not_between"&&s.operator!==">"&&s.operator!==">="&&s.operator!=="<"&&s.operator!=="<="&&s.operator!=="is_null"&&s.operator!=="is_not_null"&&n.push(a("invalid_analytics_filter_operator","Analytics filter operator is not supported.",`${t}.operator`)),s.values===void 0&&!m&&n.push(a("missing_analytics_filter_value","Analytics filter needs values unless it is a null check.",t)),m&&s.values!==void 0){n.push(a("invalid_analytics_filter_values","Null-check analytics filters must not include values.",`${t}.values`));return}if(s.values!==void 0&&!Array.isArray(s.values)){n.push(a("invalid_analytics_filter_values","Analytics filter values must be an array when provided.",`${t}.values`));return}if(s.values!==void 0){const u=s.values.length;if(s.operator==="between"||s.operator==="not_between"){u!==2&&n.push(a("invalid_analytics_filter_values","Between analytics filters must include exactly two values.",`${t}.values`));return}(s.operator==="contains"||s.operator==="not_contains"||s.operator==="="||s.operator==="!="||s.operator===">"||s.operator===">="||s.operator==="<"||s.operator==="<="||s.operator===void 0)&&u!==1&&n.push(a("invalid_analytics_filter_values","Scalar analytics filters must include exactly one value. Use in/not_in for multiple values.",`${t}.values`))}})}}function v(e){var o;const i=[],n=[];if(!e||typeof e!="object")return{ok:!1,errors:[a("invalid_analytics_intent","Analytics intent must be a structured object.")],warnings:n,repairHints:[{code:"invalid_analytics_intent",recommendedNextStep:"Send one structured analytics intent object with kind, source, and required fields."}]};if(e.version!==void 0&&e.version!==1&&i.push(a("invalid_version","Analytics intent version must be 1.","version")),M(e.source,"source",i),e.kind==="metric"){const r=Array.isArray(e.metrics)?e.metrics.filter(t=>c(t)&&d(t.name)):[];if(!Array.isArray(e.metrics)||e.metrics.length===0?i.push(a("missing_metric","Metric intent needs at least one metric.","metrics")):e.metrics.some(t=>!c(t)||!d(t.name))&&i.push(a("invalid_metric_list","Metric intent metrics must be an array of field references with names.","metrics")),r.forEach((t,s)=>{f(t,`metrics.${s}`,i,{required:!0})}),r.length>0&&!j(r)){const t=r.find((s,m)=>r.some((u,l)=>l!==m&&I(u,s)));t&&i.push(a("duplicate_metric",x(t),"metrics"))}if(c(e.primaryMetric)&&d(e.primaryMetric.name)&&h(e.primaryMetric,r).length>1&&i.push(a("ambiguous_primary_metric","Metric intent primaryMetric must identify exactly one selected metric.","primaryMetric")),e.primaryMetric!==void 0&&(f(e.primaryMetric,"primaryMetric",i,{required:!0}),c(e.primaryMetric)&&d(e.primaryMetric.name)&&r.length>0&&!T(e.primaryMetric,r)&&i.push(a("invalid_primary_metric","Metric intent primaryMetric must match one metric field reference.","primaryMetric"))),e.dimensions!==void 0&&!Array.isArray(e.dimensions)?i.push(a("invalid_metric_dimensions","Metric intent dimensions must be an array of field references.","dimensions")):Array.isArray(e.dimensions)&&e.dimensions.some(t=>!c(t)||!d(t.name))&&i.push(a("invalid_metric_dimensions","Metric intent dimensions must be an array of field references with names.","dimensions")),e.dateField!==void 0&&f(e.dateField,"dateField",i),e.timeWindow!==void 0&&(k(e.timeWindow,"timeWindow",i),e.dateField||i.push(a("missing_time_window_date_field","Metric timeWindow needs a dateField.","dateField"))),H(e.filters,"filters",i),Array.isArray(e.dimensions)&&e.dimensions.forEach((t,s)=>{f(t,`dimensions.${s}`,i)}),e.orderBy!==void 0){if(!c(e.orderBy))i.push(a("invalid_metric_order_by","Metric intent orderBy must be a structured object.","orderBy"));else if(f(e.orderBy.field,"orderBy.field",i,{required:!0}),e.orderBy.direction!=="asc"&&e.orderBy.direction!=="desc"&&i.push(a("invalid_metric_order_direction","Metric intent orderBy direction must be asc or desc.","orderBy.direction")),c(e.orderBy.field)&&d(e.orderBy.field.name)){const t=[...r,...e.timeGrain&&e.dateField&&c(e.dateField)?[e.dateField]:[],...Array.isArray(e.dimensions)?e.dimensions.filter(s=>c(s)&&d(s.name)):[]];t.length>0&&!D(e.orderBy.field,t)&&i.push(a("invalid_metric_order_by","Metric intent orderBy.field must match one selected metric, grouped dateField, or dimension.","orderBy.field"))}}U(e,i)}else e.kind==="records"?(!Array.isArray(e.fields)||e.fields.length===0?i.push(a("missing_record_fields","Records intent needs at least one field.","fields")):e.fields.some(r=>!c(r)||!d(r.name))&&i.push(a("invalid_record_fields","Records intent fields must be field references with names.","fields")),Array.isArray(e.fields)&&e.fields.forEach((r,t)=>{f(r,`fields.${t}`,i)}),e.dateField!==void 0&&f(e.dateField,"dateField",i),e.orderBy!==void 0&&(c(e.orderBy)?(f(e.orderBy.field,"orderBy.field",i,{required:!0}),e.orderBy.direction!=="asc"&&e.orderBy.direction!=="desc"&&i.push(a("invalid_record_order_direction","Records intent orderBy direction must be asc or desc.","orderBy.direction"))):i.push(a("invalid_record_order_by","Records intent orderBy must be a structured object.","orderBy")))):e.kind==="inputOptions"?((!e.field||!d(e.field.name))&&i.push(a("missing_input_options_field","Input options intent needs a field.","field")),f(e.field,"field",i,{required:!0})):e.kind==="sql"?(((o=e.source)==null?void 0:o.kind)!=="sql"&&i.push(a("invalid_sql_source","SQL analytics intent must use a SQL execution source.","source")),d(e.sql)||i.push(a("missing_sql","SQL analytics intent needs SQL text.","sql")),Array.isArray(e.fields)&&e.fields.forEach((r,t)=>{f(r,`fields.${t}`,i)})):i.push(a("invalid_analytics_kind","Analytics kind is not supported.","kind"));return{ok:i.length===0,errors:i,warnings:n,repairHints:L(i)}}function $(e){const i=[],n=[];if(!e||typeof e!="object")return{ok:!1,errors:[a("invalid_operation_intent","Operation intent must be a structured object.")],warnings:n,repairHints:[{code:"invalid_operation_intent",recommendedNextStep:"Send one typed operation intent with version, kind, and required operation fields."}]};if(e.version!==1&&i.push(a("invalid_version","Operation intent version must be 1.","version")),e.kind==="answer_obligations")!Array.isArray(e.obligations)||e.obligations.length===0?i.push(a("missing_obligations","Answer-obligations operation intent needs at least one obligation.","obligations")):e.obligations.forEach((o,r)=>{d(o.id)||i.push(a("missing_obligation_id","Each analytics obligation needs an id.",`obligations.${r}.id`)),d(o.prompt)||i.push(a("missing_obligation_prompt","Each analytics obligation needs a prompt.",`obligations.${r}.prompt`))});else if(e.kind==="dashboard_change"||e.kind==="data_app_change"){if(d(e.instruction)||i.push(a("missing_instruction","Change operation intent needs an instruction.","instruction")),e.analyticsIntent){const o=v(e.analyticsIntent);i.push(...o.errors),n.push(...o.warnings)}}else i.push(a("invalid_operation_kind","Operation intent kind is not supported.","kind"));return{ok:i.length===0,errors:i,warnings:n,repairHints:N(i)}}function G(e){const i=[],n=[];if(!e||typeof e!="object")return{ok:!1,errors:[a("invalid_recovery_plan","Analytics recovery plan must be a structured object.")],warnings:n,repairHints:[{code:"invalid_recovery_plan",recommendedNextStep:"Return a typed recovery plan with operationIntent and plannedToolCalls."}]};e.version!==1&&i.push(a("invalid_version","Recovery plan version must be 1.","version")),e.kind!=="analytics_recovery_plan"&&i.push(a("invalid_recovery_plan_kind","Recovery plan kind must be analytics_recovery_plan.","kind"));const o=$(e.operationIntent);return i.push(...o.errors),n.push(...o.warnings),Array.isArray(e.plannedToolCalls)||i.push(a("invalid_planned_tool_calls","Recovery plan plannedToolCalls must be an array.","plannedToolCalls")),{ok:i.length===0,errors:i,warnings:n,repairHints:N(i)}}function N(e){return e.map(i=>({code:i.code,recommendedNextStep:i.code==="missing_obligations"?"Normalize the user request into one or more typed analytics obligations before recovery planning.":"Correct the operation/recovery contract shape before planning execution."}))}function L(e){return e.map(i=>{switch(i.code){case"missing_source":return{code:i.code,fieldRole:"source",recommendedNextStep:"Provide a semantic, physical, or SQL source before executing analytics."};case"missing_metric":return{code:i.code,fieldRole:"metric",recommendedNextStep:"Choose one exact metric from the grounded schema candidates."};case"missing_record_fields":return{code:i.code,fieldRole:"dimension",recommendedNextStep:"Provide at least one field for the records intent."};case"missing_input_options_field":return{code:i.code,fieldRole:"input",recommendedNextStep:"Provide the exact field whose option values should be listed."};case"missing_sql":return{code:i.code,fieldRole:"sql",recommendedNextStep:"Provide bounded read-only SQL with an explicit outer LIMIT."};case"conflicting_sql":return{code:i.code,fieldRole:"sql",recommendedNextStep:"Use one canonical SQL text location for the intent; prefer top-level sql."};case"missing_semantic_domain":case"missing_dataset_name":case"missing_connection_id":case"missing_table_name":return{code:i.code,fieldRole:"source",recommendedNextStep:"Use grounded catalog metadata to fill the missing source reference."};default:return}}).filter(i=>!!i)}function Q(e,i,n,o){if(!e||typeof e!="object"){n.push(a("invalid_view","Dashboard view must be an object.",i));return}if(d(e.title)||n.push(a("missing_view_title","Dashboard view needs a title.",i)),!e.presentation||typeof e.presentation!="object"){n.push(a("missing_presentation","Dashboard view needs a presentation.",`${i}.presentation`));return}if(e.presentation.kind==="text"){d(e.text)||o.push(a("missing_text_content","Text views should include text content.",`${i}.text`));return}if(!e.analytics){n.push(a("missing_view_analytics","Non-text dashboard views need analytics intent.",`${i}.analytics`));return}const r=v(e.analytics);for(const t of r.errors)n.push(a(t.code,t.message,`${i}.analytics${t.path?`.${t.path}`:""}`));for(const t of r.warnings)o.push(a(t.code,t.message,`${i}.analytics${t.path?`.${t.path}`:""}`))}function V(e){const i=[],n=[];if(!e||typeof e!="object")return{ok:!1,errors:[a("invalid_dashboard_intent","Dashboard intent must be a structured object.")],warnings:n};e.version!==1&&i.push(a("invalid_version","Dashboard intent version must be 1.")),e.kind!=="dashboard"&&i.push(a("invalid_kind","Experience intent kind must be dashboard.")),d(e.title)||i.push(a("missing_title","Dashboard intent needs a title.","title"));const o=Array.isArray(e.inputs)?e.inputs:[],r=g(o.filter(c).map(u=>u.id).filter(u=>typeof u=="string"));r&&i.push(a("duplicate_input_id",`Duplicate input id: ${r}.`,"inputs"));for(const[u,l]of o.entries()){const p=`inputs.${u}`;if(!c(l)){i.push(a("invalid_input","Dashboard input must be an object.",p));continue}d(l.id)||i.push(a("missing_input_id","Input needs an id.",`${p}.id`)),d(l.label)||i.push(a("missing_input_label","Input needs a label.",`${p}.label`)),!l.field||!d(l.field.name)?i.push(a("missing_input_field","Input needs a field.",`${p}.field`)):f(l.field,`${p}.field`,i)}const t=Array.isArray(e.sections)?e.sections:[];t.length===0&&i.push(a("missing_sections","Dashboard intent needs at least one section.","sections"));const s=t.flatMap(u=>u&&typeof u=="object"&&Array.isArray(u.views)?u.views.filter(c).map(l=>l.id).filter(l=>!!l):[]),m=g(s);m&&i.push(a("duplicate_view_id",`Duplicate dashboard view id: ${m}.`,"sections"));for(const[u,l]of t.entries()){const p=`sections.${u}`;if(!l||typeof l!="object"){i.push(a("invalid_section","Dashboard section must be an object.",p));continue}if(d(l.title)||i.push(a("missing_section_title","Dashboard section needs a title.",p)),!Array.isArray(l.views)||l.views.length===0){i.push(a("missing_section_views","Dashboard section needs at least one view.",`${p}.views`));continue}for(const[B,R]of l.views.entries())Q(R,`${p}.views.${B}`,i,n)}return{ok:i.length===0,errors:i,warnings:n}}exports.preferSemaphorFieldRefMetadata=F;exports.preferSemaphorSourceMetadata=A;exports.semaphorFieldRefsMatch=w;exports.semaphorSourceIdentityKey=_;exports.semaphorSourcesReferToSameDataset=b;exports.validateSemaphorAnalyticsIntent=v;exports.validateSemaphorAnalyticsRecoveryPlan=G;exports.validateSemaphorDashboardIntent=V;exports.validateSemaphorOperationIntent=$;
@@ -40,14 +40,14 @@ function L(e, i) {
40
40
  source: e.source && i.source ? N(e.source, i.source) : e.source || i.source
41
41
  };
42
42
  }
43
- function a(e, i, s) {
44
- return s ? { code: e, message: i, path: s } : { code: e, message: i };
43
+ function a(e, i, n) {
44
+ return n ? { code: e, message: i, path: n } : { code: e, message: i };
45
45
  }
46
46
  function R(e) {
47
47
  for (let i = 0; i < e.length; i += 1) {
48
- const s = e[i];
48
+ const n = e[i];
49
49
  if (e.some(
50
- (o, r) => r !== i && b(o, s)
50
+ (o, r) => r !== i && b(o, n)
51
51
  ))
52
52
  return !1;
53
53
  }
@@ -93,10 +93,10 @@ function c(e) {
93
93
  }
94
94
  function v(e) {
95
95
  const i = /* @__PURE__ */ new Set();
96
- for (const s of e) {
97
- if (i.has(s))
98
- return s;
99
- i.add(s);
96
+ for (const n of e) {
97
+ if (i.has(n))
98
+ return n;
99
+ i.add(n);
100
100
  }
101
101
  return null;
102
102
  }
@@ -109,19 +109,19 @@ const C = /* @__PURE__ */ new Set([
109
109
  "MEDIAN",
110
110
  "DISTINCT"
111
111
  ]);
112
- function A(e, i, s) {
112
+ function A(e, i, n) {
113
113
  if (!e || typeof e != "object") {
114
- s.push(a("missing_source", "Analytics intent needs a source.", i));
114
+ n.push(a("missing_source", "Analytics intent needs a source.", i));
115
115
  return;
116
116
  }
117
117
  if (e.kind === "semantic") {
118
- d(e.domainId) || s.push(
118
+ d(e.domainId) || n.push(
119
119
  a(
120
120
  "missing_semantic_domain",
121
121
  "Semantic source needs a domainId.",
122
122
  `${i}.domainId`
123
123
  )
124
- ), d(e.datasetName) || s.push(
124
+ ), d(e.datasetName) || n.push(
125
125
  a(
126
126
  "missing_dataset_name",
127
127
  "Semantic source needs a datasetName.",
@@ -131,13 +131,13 @@ function A(e, i, s) {
131
131
  return;
132
132
  }
133
133
  if (e.kind === "physical") {
134
- d(e.connectionId) || s.push(
134
+ d(e.connectionId) || n.push(
135
135
  a(
136
136
  "missing_connection_id",
137
137
  "Physical source needs a connectionId.",
138
138
  `${i}.connectionId`
139
139
  )
140
- ), d(e.tableName) || s.push(
140
+ ), d(e.tableName) || n.push(
141
141
  a(
142
142
  "missing_table_name",
143
143
  "Physical source needs a tableName.",
@@ -147,7 +147,7 @@ function A(e, i, s) {
147
147
  return;
148
148
  }
149
149
  if (e.kind === "sql") {
150
- d(e.connectionId) || s.push(
150
+ d(e.connectionId) || n.push(
151
151
  a(
152
152
  "missing_connection_id",
153
153
  "SQL source needs a connectionId.",
@@ -156,21 +156,21 @@ function A(e, i, s) {
156
156
  );
157
157
  return;
158
158
  }
159
- s.push(a("invalid_source_kind", "Source kind is not supported.", i));
159
+ n.push(a("invalid_source_kind", "Source kind is not supported.", i));
160
160
  }
161
- function f(e, i, s, o = {}) {
161
+ function f(e, i, n, o = {}) {
162
162
  if (!e || !c(e)) {
163
- o.required && s.push(
163
+ o.required && n.push(
164
164
  a("missing_field_ref", "Field reference needs a name.", i)
165
165
  );
166
166
  return;
167
167
  }
168
- d(e.name) || s.push(
168
+ d(e.name) || n.push(
169
169
  a("missing_field_ref", "Field reference needs a name.", `${i}.name`)
170
- ), e.source !== void 0 && A(e.source, `${i}.source`, s), E(e.aggregate, `${i}.aggregate`, s);
170
+ ), e.source !== void 0 && A(e.source, `${i}.source`, n), E(e.aggregate, `${i}.aggregate`, n);
171
171
  }
172
- function E(e, i, s) {
173
- e !== void 0 && (typeof e != "string" || !C.has(e)) && s.push(
172
+ function E(e, i, n) {
173
+ e !== void 0 && (typeof e != "string" || !C.has(e)) && n.push(
174
174
  a(
175
175
  "invalid_aggregate",
176
176
  "Field aggregate must be SUM, COUNT, AVG, MIN, MAX, MEDIAN, or DISTINCT.",
@@ -220,12 +220,12 @@ function P(e, i) {
220
220
  "analysis.orderBy"
221
221
  )
222
222
  );
223
- const { timeWindow: s } = e.analysis;
224
- s !== void 0 && k(s, "analysis.timeWindow", i);
223
+ const { timeWindow: n } = e.analysis;
224
+ n !== void 0 && w(n, "analysis.timeWindow", i);
225
225
  }
226
- function k(e, i, s) {
226
+ function w(e, i, n) {
227
227
  if (!c(e)) {
228
- s.push(
228
+ n.push(
229
229
  a(
230
230
  "invalid_time_window",
231
231
  "Time window must be a structured object.",
@@ -234,25 +234,25 @@ function k(e, i, s) {
234
234
  );
235
235
  return;
236
236
  }
237
- e.unit !== "second" && e.unit !== "minute" && e.unit !== "hour" && e.unit !== "day" && e.unit !== "week" && e.unit !== "month" && e.unit !== "quarter" && e.unit !== "year" && s.push(
237
+ e.unit !== "second" && e.unit !== "minute" && e.unit !== "hour" && e.unit !== "day" && e.unit !== "week" && e.unit !== "month" && e.unit !== "quarter" && e.unit !== "year" && n.push(
238
238
  a(
239
239
  "invalid_time_window",
240
240
  "Time window unit must be second, minute, hour, day, week, month, quarter, or year.",
241
241
  `${i}.unit`
242
242
  )
243
- ), (typeof e.value != "number" || !Number.isFinite(e.value) || e.value <= 0) && s.push(
243
+ ), (typeof e.value != "number" || !Number.isFinite(e.value) || e.value <= 0) && n.push(
244
244
  a(
245
245
  "invalid_time_window",
246
246
  "Time window value must be a positive number.",
247
247
  `${i}.value`
248
248
  )
249
- ), e.anchor !== void 0 && e.anchor !== "now" && e.anchor !== "latest_available" && s.push(
249
+ ), e.anchor !== void 0 && e.anchor !== "now" && e.anchor !== "latest_available" && n.push(
250
250
  a(
251
251
  "invalid_time_window",
252
252
  "Time window anchor must be now or latest_available.",
253
253
  `${i}.anchor`
254
254
  )
255
- ), e.completeness !== void 0 && e.completeness !== "include_partial" && e.completeness !== "complete_periods" && s.push(
255
+ ), e.completeness !== void 0 && e.completeness !== "include_partial" && e.completeness !== "complete_periods" && n.push(
256
256
  a(
257
257
  "invalid_time_window",
258
258
  "Time window completeness must be include_partial or complete_periods.",
@@ -260,10 +260,10 @@ function k(e, i, s) {
260
260
  )
261
261
  );
262
262
  }
263
- function O(e, i, s) {
263
+ function O(e, i, n) {
264
264
  if (e !== void 0) {
265
265
  if (!Array.isArray(e)) {
266
- s.push(
266
+ n.push(
267
267
  a(
268
268
  "invalid_analytics_filters",
269
269
  "Analytics filters must be an array.",
@@ -273,57 +273,80 @@ function O(e, i, s) {
273
273
  return;
274
274
  }
275
275
  e.forEach((o, r) => {
276
- const n = `${i}.${r}`;
276
+ const t = `${i}.${r}`;
277
277
  if (!c(o)) {
278
- s.push(
278
+ n.push(
279
279
  a(
280
280
  "invalid_analytics_filter",
281
281
  "Analytics filter must be a structured object.",
282
- n
282
+ t
283
283
  )
284
284
  );
285
285
  return;
286
286
  }
287
- const t = o;
288
- f(t.field, `${n}.field`, s, {
287
+ const s = o;
288
+ f(s.field, `${t}.field`, n, {
289
289
  required: !0
290
290
  });
291
- const p = t.operator === "is_null" || t.operator === "is_not_null";
292
- if (t.operator !== void 0 && t.operator !== "=" && t.operator !== "!=" && t.operator !== "in" && t.operator !== "not_in" && t.operator !== "contains" && t.operator !== "not_contains" && t.operator !== "between" && t.operator !== "not_between" && t.operator !== ">" && t.operator !== ">=" && t.operator !== "<" && t.operator !== "<=" && t.operator !== "is_null" && t.operator !== "is_not_null" && s.push(
291
+ const m = s.operator === "is_null" || s.operator === "is_not_null";
292
+ if (s.operator !== void 0 && s.operator !== "=" && s.operator !== "!=" && s.operator !== "in" && s.operator !== "not_in" && s.operator !== "contains" && s.operator !== "not_contains" && s.operator !== "between" && s.operator !== "not_between" && s.operator !== ">" && s.operator !== ">=" && s.operator !== "<" && s.operator !== "<=" && s.operator !== "is_null" && s.operator !== "is_not_null" && n.push(
293
293
  a(
294
294
  "invalid_analytics_filter_operator",
295
295
  "Analytics filter operator is not supported.",
296
- `${n}.operator`
296
+ `${t}.operator`
297
297
  )
298
- ), t.values === void 0 && !p && s.push(
298
+ ), s.values === void 0 && !m && n.push(
299
299
  a(
300
300
  "missing_analytics_filter_value",
301
301
  "Analytics filter needs values unless it is a null check.",
302
- n
302
+ t
303
303
  )
304
- ), p && t.values !== void 0) {
305
- s.push(
304
+ ), m && s.values !== void 0) {
305
+ n.push(
306
306
  a(
307
307
  "invalid_analytics_filter_values",
308
308
  "Null-check analytics filters must not include values.",
309
- `${n}.values`
309
+ `${t}.values`
310
310
  )
311
311
  );
312
312
  return;
313
313
  }
314
- t.values !== void 0 && !Array.isArray(t.values) && s.push(
315
- a(
316
- "invalid_analytics_filter_values",
317
- "Analytics filter values must be an array when provided.",
318
- `${n}.values`
319
- )
320
- );
314
+ if (s.values !== void 0 && !Array.isArray(s.values)) {
315
+ n.push(
316
+ a(
317
+ "invalid_analytics_filter_values",
318
+ "Analytics filter values must be an array when provided.",
319
+ `${t}.values`
320
+ )
321
+ );
322
+ return;
323
+ }
324
+ if (s.values !== void 0) {
325
+ const u = s.values.length;
326
+ if (s.operator === "between" || s.operator === "not_between") {
327
+ u !== 2 && n.push(
328
+ a(
329
+ "invalid_analytics_filter_values",
330
+ "Between analytics filters must include exactly two values.",
331
+ `${t}.values`
332
+ )
333
+ );
334
+ return;
335
+ }
336
+ (s.operator === "contains" || s.operator === "not_contains" || s.operator === "=" || s.operator === "!=" || s.operator === ">" || s.operator === ">=" || s.operator === "<" || s.operator === "<=" || s.operator === void 0) && u !== 1 && n.push(
337
+ a(
338
+ "invalid_analytics_filter_values",
339
+ "Scalar analytics filters must include exactly one value. Use in/not_in for multiple values.",
340
+ `${t}.values`
341
+ )
342
+ );
343
+ }
321
344
  });
322
345
  }
323
346
  }
324
- function w(e) {
347
+ function k(e) {
325
348
  var o;
326
- const i = [], s = [];
349
+ const i = [], n = [];
327
350
  if (!e || typeof e != "object")
328
351
  return {
329
352
  ok: !1,
@@ -333,7 +356,7 @@ function w(e) {
333
356
  "Analytics intent must be a structured object."
334
357
  )
335
358
  ],
336
- warnings: s,
359
+ warnings: n,
337
360
  repairHints: [
338
361
  {
339
362
  code: "invalid_analytics_intent",
@@ -345,32 +368,32 @@ function w(e) {
345
368
  a("invalid_version", "Analytics intent version must be 1.", "version")
346
369
  ), A(e.source, "source", i), e.kind === "metric") {
347
370
  const r = Array.isArray(e.metrics) ? e.metrics.filter(
348
- (n) => c(n) && d(n.name)
371
+ (t) => c(t) && d(t.name)
349
372
  ) : [];
350
373
  if (!Array.isArray(e.metrics) || e.metrics.length === 0 ? i.push(
351
374
  a("missing_metric", "Metric intent needs at least one metric.", "metrics")
352
375
  ) : e.metrics.some(
353
- (n) => !c(n) || !d(n.name)
376
+ (t) => !c(t) || !d(t.name)
354
377
  ) && i.push(
355
378
  a(
356
379
  "invalid_metric_list",
357
380
  "Metric intent metrics must be an array of field references with names.",
358
381
  "metrics"
359
382
  )
360
- ), r.forEach((n, t) => {
361
- f(n, `metrics.${t}`, i, {
383
+ ), r.forEach((t, s) => {
384
+ f(t, `metrics.${s}`, i, {
362
385
  required: !0
363
386
  });
364
387
  }), r.length > 0 && !R(r)) {
365
- const n = r.find(
366
- (t, p) => r.some(
367
- (u, l) => l !== p && b(u, t)
388
+ const t = r.find(
389
+ (s, m) => r.some(
390
+ (u, l) => l !== m && b(u, s)
368
391
  )
369
392
  );
370
- n && i.push(
393
+ t && i.push(
371
394
  a(
372
395
  "duplicate_metric",
373
- F(n),
396
+ F(t),
374
397
  "metrics"
375
398
  )
376
399
  );
@@ -402,21 +425,21 @@ function w(e) {
402
425
  "dimensions"
403
426
  )
404
427
  ) : Array.isArray(e.dimensions) && e.dimensions.some(
405
- (n) => !c(n) || !d(n.name)
428
+ (t) => !c(t) || !d(t.name)
406
429
  ) && i.push(
407
430
  a(
408
431
  "invalid_metric_dimensions",
409
432
  "Metric intent dimensions must be an array of field references with names.",
410
433
  "dimensions"
411
434
  )
412
- ), e.dateField !== void 0 && f(e.dateField, "dateField", i), e.timeWindow !== void 0 && (k(e.timeWindow, "timeWindow", i), e.dateField || i.push(
435
+ ), e.dateField !== void 0 && f(e.dateField, "dateField", i), e.timeWindow !== void 0 && (w(e.timeWindow, "timeWindow", i), e.dateField || i.push(
413
436
  a(
414
437
  "missing_time_window_date_field",
415
438
  "Metric timeWindow needs a dateField.",
416
439
  "dateField"
417
440
  )
418
- )), O(e.filters, "filters", i), Array.isArray(e.dimensions) && e.dimensions.forEach((n, t) => {
419
- f(n, `dimensions.${t}`, i);
441
+ )), O(e.filters, "filters", i), Array.isArray(e.dimensions) && e.dimensions.forEach((t, s) => {
442
+ f(t, `dimensions.${s}`, i);
420
443
  }), e.orderBy !== void 0) {
421
444
  if (!c(e.orderBy))
422
445
  i.push(
@@ -435,16 +458,16 @@ function w(e) {
435
458
  "orderBy.direction"
436
459
  )
437
460
  ), c(e.orderBy.field) && d(e.orderBy.field.name)) {
438
- const n = [
461
+ const t = [
439
462
  ...r,
440
463
  ...e.timeGrain && e.dateField && c(e.dateField) ? [e.dateField] : [],
441
464
  ...Array.isArray(e.dimensions) ? e.dimensions.filter(
442
- (t) => c(t) && d(t.name)
465
+ (s) => c(s) && d(s.name)
443
466
  ) : []
444
467
  ];
445
- n.length > 0 && !x(
468
+ t.length > 0 && !x(
446
469
  e.orderBy.field,
447
- n
470
+ t
448
471
  ) && i.push(
449
472
  a(
450
473
  "invalid_metric_order_by",
@@ -469,8 +492,8 @@ function w(e) {
469
492
  "Records intent fields must be field references with names.",
470
493
  "fields"
471
494
  )
472
- ), Array.isArray(e.fields) && e.fields.forEach((r, n) => {
473
- f(r, `fields.${n}`, i);
495
+ ), Array.isArray(e.fields) && e.fields.forEach((r, t) => {
496
+ f(r, `fields.${t}`, i);
474
497
  }), e.dateField !== void 0 && f(e.dateField, "dateField", i), e.orderBy !== void 0 && (c(e.orderBy) ? (f(e.orderBy.field, "orderBy.field", i, {
475
498
  required: !0
476
499
  }), e.orderBy.direction !== "asc" && e.orderBy.direction !== "desc" && i.push(
@@ -497,20 +520,20 @@ function w(e) {
497
520
  "SQL analytics intent must use a SQL execution source.",
498
521
  "source"
499
522
  )
500
- ), d(e.sql) || i.push(a("missing_sql", "SQL analytics intent needs SQL text.", "sql")), Array.isArray(e.fields) && e.fields.forEach((r, n) => {
501
- f(r, `fields.${n}`, i);
523
+ ), d(e.sql) || i.push(a("missing_sql", "SQL analytics intent needs SQL text.", "sql")), Array.isArray(e.fields) && e.fields.forEach((r, t) => {
524
+ f(r, `fields.${t}`, i);
502
525
  })) : i.push(
503
526
  a("invalid_analytics_kind", "Analytics kind is not supported.", "kind")
504
527
  );
505
528
  return {
506
529
  ok: i.length === 0,
507
530
  errors: i,
508
- warnings: s,
509
- repairHints: U(i)
531
+ warnings: n,
532
+ repairHints: H(i)
510
533
  };
511
534
  }
512
- function H(e) {
513
- const i = [], s = [];
535
+ function U(e) {
536
+ const i = [], n = [];
514
537
  if (!e || typeof e != "object")
515
538
  return {
516
539
  ok: !1,
@@ -520,7 +543,7 @@ function H(e) {
520
543
  "Operation intent must be a structured object."
521
544
  )
522
545
  ],
523
- warnings: s,
546
+ warnings: n,
524
547
  repairHints: [
525
548
  {
526
549
  code: "invalid_operation_intent",
@@ -560,10 +583,10 @@ function H(e) {
560
583
  "instruction"
561
584
  )
562
585
  ), e.analyticsIntent) {
563
- const o = w(
586
+ const o = k(
564
587
  e.analyticsIntent
565
588
  );
566
- i.push(...o.errors), s.push(...o.warnings);
589
+ i.push(...o.errors), n.push(...o.warnings);
567
590
  }
568
591
  } else
569
592
  i.push(
@@ -576,12 +599,12 @@ function H(e) {
576
599
  return {
577
600
  ok: i.length === 0,
578
601
  errors: i,
579
- warnings: s,
602
+ warnings: n,
580
603
  repairHints: I(i)
581
604
  };
582
605
  }
583
606
  function Q(e) {
584
- const i = [], s = [];
607
+ const i = [], n = [];
585
608
  if (!e || typeof e != "object")
586
609
  return {
587
610
  ok: !1,
@@ -591,7 +614,7 @@ function Q(e) {
591
614
  "Analytics recovery plan must be a structured object."
592
615
  )
593
616
  ],
594
- warnings: s,
617
+ warnings: n,
595
618
  repairHints: [
596
619
  {
597
620
  code: "invalid_recovery_plan",
@@ -608,8 +631,8 @@ function Q(e) {
608
631
  "kind"
609
632
  )
610
633
  );
611
- const o = H(e.operationIntent);
612
- return i.push(...o.errors), s.push(...o.warnings), Array.isArray(e.plannedToolCalls) || i.push(
634
+ const o = U(e.operationIntent);
635
+ return i.push(...o.errors), n.push(...o.warnings), Array.isArray(e.plannedToolCalls) || i.push(
613
636
  a(
614
637
  "invalid_planned_tool_calls",
615
638
  "Recovery plan plannedToolCalls must be an array.",
@@ -618,7 +641,7 @@ function Q(e) {
618
641
  ), {
619
642
  ok: i.length === 0,
620
643
  errors: i,
621
- warnings: s,
644
+ warnings: n,
622
645
  repairHints: I(i)
623
646
  };
624
647
  }
@@ -628,7 +651,7 @@ function I(e) {
628
651
  recommendedNextStep: i.code === "missing_obligations" ? "Normalize the user request into one or more typed analytics obligations before recovery planning." : "Correct the operation/recovery contract shape before planning execution."
629
652
  }));
630
653
  }
631
- function U(e) {
654
+ function H(e) {
632
655
  return e.map((i) => {
633
656
  switch (i.code) {
634
657
  case "missing_source":
@@ -681,13 +704,13 @@ function U(e) {
681
704
  }
682
705
  }).filter((i) => !!i);
683
706
  }
684
- function G(e, i, s, o) {
707
+ function G(e, i, n, o) {
685
708
  if (!e || typeof e != "object") {
686
- s.push(a("invalid_view", "Dashboard view must be an object.", i));
709
+ n.push(a("invalid_view", "Dashboard view must be an object.", i));
687
710
  return;
688
711
  }
689
- if (d(e.title) || s.push(a("missing_view_title", "Dashboard view needs a title.", i)), !e.presentation || typeof e.presentation != "object") {
690
- s.push(
712
+ if (d(e.title) || n.push(a("missing_view_title", "Dashboard view needs a title.", i)), !e.presentation || typeof e.presentation != "object") {
713
+ n.push(
691
714
  a(
692
715
  "missing_presentation",
693
716
  "Dashboard view needs a presentation.",
@@ -707,7 +730,7 @@ function G(e, i, s, o) {
707
730
  return;
708
731
  }
709
732
  if (!e.analytics) {
710
- s.push(
733
+ n.push(
711
734
  a(
712
735
  "missing_view_analytics",
713
736
  "Non-text dashboard views need analytics intent.",
@@ -716,22 +739,22 @@ function G(e, i, s, o) {
716
739
  );
717
740
  return;
718
741
  }
719
- const r = w(e.analytics);
720
- for (const n of r.errors)
721
- s.push(
722
- a(n.code, n.message, `${i}.analytics${n.path ? `.${n.path}` : ""}`)
742
+ const r = k(e.analytics);
743
+ for (const t of r.errors)
744
+ n.push(
745
+ a(t.code, t.message, `${i}.analytics${t.path ? `.${t.path}` : ""}`)
723
746
  );
724
- for (const n of r.warnings)
747
+ for (const t of r.warnings)
725
748
  o.push(
726
749
  a(
727
- n.code,
728
- n.message,
729
- `${i}.analytics${n.path ? `.${n.path}` : ""}`
750
+ t.code,
751
+ t.message,
752
+ `${i}.analytics${t.path ? `.${t.path}` : ""}`
730
753
  )
731
754
  );
732
755
  }
733
756
  function V(e) {
734
- const i = [], s = [];
757
+ const i = [], n = [];
735
758
  if (!e || typeof e != "object")
736
759
  return {
737
760
  ok: !1,
@@ -741,7 +764,7 @@ function V(e) {
741
764
  "Dashboard intent must be a structured object."
742
765
  )
743
766
  ],
744
- warnings: s
767
+ warnings: n
745
768
  };
746
769
  e.version !== 1 && i.push(a("invalid_version", "Dashboard intent version must be 1.")), e.kind !== "dashboard" && i.push(a("invalid_kind", "Experience intent kind must be dashboard.")), d(e.title) || i.push(a("missing_title", "Dashboard intent needs a title.", "title"));
747
770
  const o = Array.isArray(e.inputs) ? e.inputs : [], r = v(
@@ -755,51 +778,51 @@ function V(e) {
755
778
  )
756
779
  );
757
780
  for (const [u, l] of o.entries()) {
758
- const m = `inputs.${u}`;
781
+ const p = `inputs.${u}`;
759
782
  if (!c(l)) {
760
- i.push(a("invalid_input", "Dashboard input must be an object.", m));
783
+ i.push(a("invalid_input", "Dashboard input must be an object.", p));
761
784
  continue;
762
785
  }
763
- d(l.id) || i.push(a("missing_input_id", "Input needs an id.", `${m}.id`)), d(l.label) || i.push(
764
- a("missing_input_label", "Input needs a label.", `${m}.label`)
786
+ d(l.id) || i.push(a("missing_input_id", "Input needs an id.", `${p}.id`)), d(l.label) || i.push(
787
+ a("missing_input_label", "Input needs a label.", `${p}.label`)
765
788
  ), !l.field || !d(l.field.name) ? i.push(
766
- a("missing_input_field", "Input needs a field.", `${m}.field`)
767
- ) : f(l.field, `${m}.field`, i);
789
+ a("missing_input_field", "Input needs a field.", `${p}.field`)
790
+ ) : f(l.field, `${p}.field`, i);
768
791
  }
769
- const n = Array.isArray(e.sections) ? e.sections : [];
770
- n.length === 0 && i.push(
792
+ const t = Array.isArray(e.sections) ? e.sections : [];
793
+ t.length === 0 && i.push(
771
794
  a(
772
795
  "missing_sections",
773
796
  "Dashboard intent needs at least one section.",
774
797
  "sections"
775
798
  )
776
799
  );
777
- const t = n.flatMap(
800
+ const s = t.flatMap(
778
801
  (u) => u && typeof u == "object" && Array.isArray(u.views) ? u.views.filter(c).map((l) => l.id).filter((l) => !!l) : []
779
- ), p = v(t);
780
- p && i.push(
802
+ ), m = v(s);
803
+ m && i.push(
781
804
  a(
782
805
  "duplicate_view_id",
783
- `Duplicate dashboard view id: ${p}.`,
806
+ `Duplicate dashboard view id: ${m}.`,
784
807
  "sections"
785
808
  )
786
809
  );
787
- for (const [u, l] of n.entries()) {
788
- const m = `sections.${u}`;
810
+ for (const [u, l] of t.entries()) {
811
+ const p = `sections.${u}`;
789
812
  if (!l || typeof l != "object") {
790
813
  i.push(
791
- a("invalid_section", "Dashboard section must be an object.", m)
814
+ a("invalid_section", "Dashboard section must be an object.", p)
792
815
  );
793
816
  continue;
794
817
  }
795
818
  if (d(l.title) || i.push(
796
- a("missing_section_title", "Dashboard section needs a title.", m)
819
+ a("missing_section_title", "Dashboard section needs a title.", p)
797
820
  ), !Array.isArray(l.views) || l.views.length === 0) {
798
821
  i.push(
799
822
  a(
800
823
  "missing_section_views",
801
824
  "Dashboard section needs at least one view.",
802
- `${m}.views`
825
+ `${p}.views`
803
826
  )
804
827
  );
805
828
  continue;
@@ -807,15 +830,15 @@ function V(e) {
807
830
  for (const [M, S] of l.views.entries())
808
831
  G(
809
832
  S,
810
- `${m}.views.${M}`,
833
+ `${p}.views.${M}`,
811
834
  i,
812
- s
835
+ n
813
836
  );
814
837
  }
815
- return { ok: i.length === 0, errors: i, warnings: s };
838
+ return { ok: i.length === 0, errors: i, warnings: n };
816
839
  }
817
840
  export {
818
- H as a,
841
+ U as a,
819
842
  Q as b,
820
843
  V as c,
821
844
  $ as d,
@@ -823,5 +846,5 @@ export {
823
846
  L as f,
824
847
  N as p,
825
848
  h as s,
826
- w as v
849
+ k as v
827
850
  };
@@ -1,3 +1,3 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v=require("../chunks/validators-8R9pr2K9.js"),Se=require("../chunks/catalog-field-grounding-Du6mKDcF.js"),re=["lg","md","sm","xs","xxs"],$=10;function _(e){return e&&typeof e=="object"?e:null}function D(e){return typeof e=="string"?e:null}function ae(e){var t,n,r;return!!(e&&typeof e=="object")&&(((t=_(e))==null?void 0:t.kind)==="semantic"||((n=_(e))==null?void 0:n.kind)==="physical"||((r=_(e))==null?void 0:r.kind)==="sql")}function N(e){return ae(e)?e.kind==="semantic"?!!(e.domainId&&e.datasetName):e.kind==="physical"?!!(e.connectionId&&e.tableName):!1:!1}function we(e){return v.semaphorSourceIdentityKey(e)}function G(e,t){return v.semaphorSourcesReferToSameDataset(e,t)}function ie(e,t){return v.preferSemaphorSourceMetadata(e,t)}function M(e){const t=[];for(const n of e){const r=t.findIndex(a=>G(a,n));r===-1?t.push(n):t[r]=ie(t[r],n)}return t}function ve(e){return M(e)[0]}function H(e,t){return e.kind!=="semantic"||e.connectionId||(t==null?void 0:t.kind)!=="semantic"||!v.semaphorSourcesReferToSameDataset(e,t)||!t.connectionId?e:{...e,connectionId:t.connectionId}}function W(e){return N(e)?e:void 0}function ne(e,t){if(!(e.kind!=="semantic"||e.connectionId))return t.find(n=>(n==null?void 0:n.kind)==="semantic"&&v.semaphorSourcesReferToSameDataset(e,n)&&!!n.connectionId)}function w(e,t){const n=W(e==null?void 0:e.source);return n?H(n,t):void 0}function oe({explicitSource:e,field:t,defaultSource:n,fallbackSources:r}){const a=[n,...r||[]],i=W(e),o=i?H(i,ne(i,a)):void 0;if(o)return o;if(e!==void 0)return;const d=w(t,n),s=d?H(d,ne(d,a)):void 0;if(s)return s;if((t==null?void 0:t.source)===void 0)return W(n)}function De(e,t){if(!(e!=null&&e.name)||!(t!=null&&t.name)||e.name!==t.name)return!1;const n=w(e),r=w(t);return!n||!r?!0:G(n,r)}function C(e){var t;return D((t=_(e))==null?void 0:t.kind)}function se(e){var t,n;return C(e)!=="semantic"?null:((n=D((t=_(e))==null?void 0:t.domainId))==null?void 0:n.trim())||null}function Ae(e){var t;return C(e)!=="semantic"?null:D((t=_(e))==null?void 0:t.datasetName)}function Ce(e){var t;return C(e)!=="semantic"?null:D((t=_(e))==null?void 0:t.datasetId)}function ke(e){var t;return C(e)!=="physical"?null:D((t=_(e))==null?void 0:t.connectionId)}function xe(e){var t;return C(e)!=="physical"?null:D((t=_(e))==null?void 0:t.tableName)}function Fe(e){var t;return C(e)!=="physical"?"":D((t=_(e))==null?void 0:t.databaseName)||""}function Te(e){var t;return C(e)!=="physical"?"":D((t=_(e))==null?void 0:t.schemaName)||""}function de(e){if(e.analyticsIntent&&typeof e.analyticsIntent=="object"&&"source"in e.analyticsIntent)return e.analyticsIntent.source}function ce({datasets:e,requireAtLeastOne:t}){if(t&&e.length<1)return{ok:!1,issue:"invalid_dataset_count"};if(e.length<=1)return{ok:!0};const n=e.map(se),r=new Set(n.filter(Boolean));return n.some(a=>!a)||r.size!==1?{ok:!1,issue:"invalid_multi_dataset_scope"}:{ok:!0}}function z(e,t){if(!t)return!1;if(t.kind==="semantic"){const n=Ce(e);return se(e)===t.domainId?n&&t.datasetId?n===t.datasetId:Ae(e)===t.datasetName:!1}return t.kind==="physical"?ke(e)===t.connectionId&&xe(e)===t.tableName&&Fe(e)===(t.databaseName||"")&&Te(e)===(t.schemaName||""):!1}function $e(e,t){return e.find(n=>z(n,t))}function f(e,t,n){return n?{code:e,message:t,cardId:n}:{code:e,message:t}}function B(e){const t=new Set;for(const n of e){if(t.has(n))return n;t.add(n)}return null}function le({card:e,datasets:t,errors:n}){if(e.type==="text")return;const r=de(e);if(!r){if(t.length<=1)return;n.push(f("missing_card_analytics_source","Multi-dataset dashboard cards must include analytics intent with a source so the materializer can choose the correct dataset.",e.id));return}t.some(a=>z(a,r))||n.push(f("invalid_card_analytics_source","Dashboard cards with an explicit analytics source must use one of the selected datasets.",e.id))}function V(e){return e.map(t=>t==null?void 0:t.source).filter(t=>!!t)}function L(e){return Array.isArray(e)?e.filter(t=>!!(t&&typeof t=="object")):[]}function Me(e){return Array.isArray(e)?e.filter(t=>!!(t&&typeof t=="object")):[]}function Ne(e){var n;if(!e)return[];const t=[e.source];return e.kind==="metric"?t.push(...V([...L(e.metrics),e.primaryMetric,e.dateField,...L(e.dimensions),...Me(e.filters).map(r=>r.field)])):e.kind==="records"?t.push(...V([...L(e.fields),e.dateField,(n=e.orderBy)==null?void 0:n.field])):e.kind==="inputOptions"?t.push(...V([e.field])):e.kind==="sql"&&t.push(...V(e.fields||[])),t}function ue({card:e,datasets:t,errors:n}){if(e.type!=="text"){for(const r of Ne(e.analyticsIntent))if(r&&!t.some(a=>z(a,r))){n.push(f("invalid_card_query_source","Dashboard card query field references must use one of the selected datasets.",e.id));return}}}function fe({card:e,errors:t}){if(e.type==="text"||!e.analyticsIntent)return;const n=v.validateSemaphorAnalyticsIntent(e.analyticsIntent);if(!n.ok)for(const r of n.errors)t.push(f(r.code,r.path?`${r.path}: ${r.message}`:r.message,e.id))}function pe({datasets:e,errors:t,requireAtLeastOne:n}){const r=ce({datasets:e,requireAtLeastOne:n});if(!r.ok){if(r.issue==="invalid_dataset_count"){t.push(f("invalid_dataset_count","Dashboard authoring requires at least one selected dataset."));return}t.push(f("invalid_multi_dataset_scope","Multi-dataset dashboard authoring is limited to semantic datasets from one domain."))}}function he(e){var p,S;const t=[];if(!e||typeof e!="object")return{ok:!1,errors:[f("invalid_plan","Dashboard plan must be a structured object.")],warnings:[]};const n=e,r=[...n.warnings||[]];n.version!==1&&t.push(f("invalid_version","Dashboard plan version must be 1.")),(p=n.title)!=null&&p.trim()||t.push(f("missing_title","Dashboard plan needs a title."));const a=Array.isArray(n.datasets)?n.datasets:[],i=Array.isArray(n.sheets)?n.sheets:[];pe({datasets:a,errors:t,requireAtLeastOne:!0}),i.length!==1&&t.push(f("invalid_sheet_count","MVP dashboard authoring creates exactly one dashboard sheet."));const o=i[0];o&&o.kind!=="dashboard"&&t.push(f("invalid_sheet_kind",'Generated sheet must use kind "dashboard".'));const d=(o==null?void 0:o.cards)||[];d.length>$&&t.push(f("too_many_cards",`Generated dashboards can contain at most ${$} cards.`));const s=B(d.map(l=>l.id));s&&t.push(f("duplicate_card_id",`Duplicate generated card id: ${s}.`));const u=B(d.map(l=>l.frameId));u&&t.push(f("duplicate_frame_id",`Duplicate generated frame id: ${u}.`));for(const l of d)(S=l.title)!=null&&S.trim()||t.push(f("missing_card_title","Card title is required.",l.id)),l.type==="custom"&&t.push(f("custom_visual_out_of_scope","Whole-dashboard authoring supports built-in visual types only.",l.id)),l.type!=="text"&&!l.analyticsIntent&&r.push(f("missing_analytics_intent","Non-text card has no analytics intent and may be skipped by the app layer.",l.id)),le({card:l,datasets:a,errors:t}),fe({card:l,errors:t}),ue({card:l,datasets:a,errors:t});const h=Array.isArray(n.filterInputs)?n.filterInputs:[],b=h.map(l=>l.id),y=B(b);y&&t.push(f("duplicate_input_id",`Duplicate dashboard input id: ${y}.`));const c=h.map(l=>l.variableName).filter(Boolean)||[],g=B(c);g&&t.push(f("duplicate_input_variable",`Duplicate dashboard input variable name: ${g}.`));const A=Array.isArray(n.calculatedFields)?n.calculatedFields:[];for(const l of A)l.scope==="domain"&&l.reuseOnly!==!0&&t.push(f("domain_calculated_field_create_out_of_scope",`Creating domain calculated field "${l.name}" is outside MVP.`));return{ok:t.length===0,errors:t,warnings:r}}function me(e){var o;const t=[];if(!e||typeof e!="object")return{ok:!1,errors:[f("invalid_change_plan","Dashboard change plan must be a structured object.")],warnings:[]};const n=e,r=[...n.warnings||[]];n.version!==1&&t.push(f("invalid_version","Dashboard change plan version must be 1.")),(o=n.dashboardId)!=null&&o.trim()||t.push(f("missing_dashboard_id","Dashboard change plan needs a dashboard id."));const a=Array.isArray(n.datasets)?n.datasets:[],i=Array.isArray(n.operations)?n.operations:[];pe({datasets:a,errors:t,requireAtLeastOne:!1});for(const d of i){if(d.kind==="unsupported"){r.push(f("unsupported_operation",d.reason||d.requestedAction));continue}d.kind==="addCard"&&d.card.type==="custom"&&t.push(f("custom_visual_out_of_scope","Whole-dashboard authoring supports built-in visual types only.",d.card.id)),d.kind==="addCard"&&(le({card:d.card,datasets:a,errors:t}),fe({card:d.card,errors:t}),ue({card:d.card,datasets:a,errors:t})),d.kind==="addCalculatedField"&&d.field.scope==="domain"&&d.field.reuseOnly!==!0&&t.push(f("domain_calculated_field_create_out_of_scope",`Creating domain calculated field "${d.field.name}" is outside MVP.`))}return{ok:t.length===0,errors:t,warnings:r}}const Pe={lg:48,md:36,sm:24,xs:12,xxs:6};function Re(e,t){let n=0,r=0,a=0;return e.map(i=>{const o=Math.min(i.w,t);n>0&&n+o>t&&(n=0,r+=a,a=0);const d={i:i.frameId,x:n,y:r,w:o,h:i.h,minW:Math.min(i.minW,t),minH:i.minH,static:!1};return n+=o,a=Math.max(a,i.h),d})}function Be(e){const t=[...e].sort((s,u)=>s.priority-u.priority),n=t.filter(s=>s.role==="kpi"),r=t.filter(s=>s.role==="chart"),a=t.filter(s=>s.role==="table"),i=t.filter(s=>s.role==="text"),o=i.slice(0,1),d=i.slice(o.length);return{kpis:n,introText:o,charts:r,tables:a,supportingText:d}}function Ve(e,t,n){return t==="xxs"||t==="xs"?n:t==="sm"?Math.min(12,n):t==="md"?e<=1||e===2?18:12:e<=1||e===2?24:e===3?16:12}function ze(e,t,n,r){return n==="xxs"||n==="xs"||n==="sm"||n==="md"||t===1||t%2===1&&e===0?r:r/2}function Oe(e){const{item:t,band:n,index:r,bandCount:a,breakpoint:i,columns:o}=e;return n==="kpi"?{...t,band:n,w:Ve(a,i,o),h:15,minW:Math.min(6,o),minH:12}:n==="table"?{...t,band:n,w:o,h:i==="xxs"||i==="xs"?34:38,minW:Math.min(12,o),minH:18}:n==="introText"?{...t,band:n,w:o,h:i==="xxs"||i==="xs"?12:10,minW:Math.min(12,o),minH:8}:n==="supportingText"?{...t,band:n,w:i==="lg"?o/2:o,h:i==="xxs"||i==="xs"?12:10,minW:Math.min(12,o),minH:8}:{...t,band:n,w:ze(r,a,i,o),h:i==="xxs"||i==="xs"?28:30,minW:Math.min(12,o),minH:16}}function x(e,t,n,r){return e.map((a,i)=>Oe({item:a,band:t,index:i,bandCount:e.length,breakpoint:n,columns:r}))}function O(e){const t=Be(e);return Object.fromEntries(re.map(n=>{const r=Pe[n],a=[...x(t.introText,"introText",n,r),...x(t.kpis,"kpi",n,r),...x(t.charts,"chart",n,r),...x(t.tables,"table",n,r),...x(t.supportingText,"supportingText",n,r)];return[n,Re(a,r)]}))}function qe(e){const t=Se.normalizeAnalyticsCatalogDataType(e);return t==="datetime"?"date":t==="unknown"?"string":t}function Le(e){return!!(e&&typeof e=="object"&&!Array.isArray(e))}function je(e){return Le(e)&&typeof e.filterId=="string"&&typeof e.operation=="string"&&Array.isArray(e.values)}function Ee(e){return e.filter(t=>typeof t=="string"||typeof t=="number")}function He(e){return e.filter(t=>t instanceof Date||typeof t=="string")}function K(e,t){if(t===void 0)return;const n=qe(e.dataType),r=e.operation||"in";if(je(t))return{...t,filterId:e.id,name:t.name||e.column,valueType:n,dataType:e.dataType,fieldMeta:e.fieldMeta,semanticContext:e.semanticContext};if(r==="is null"||r==="is not null")return{filterId:e.id,name:e.column,operation:r,valueType:n,values:[],dataType:e.dataType,fieldMeta:e.fieldMeta,semanticContext:e.semanticContext};const a=Array.isArray(t)?t:[t],i=n==="date"?He(a):Ee(a);if(i.length!==0&&!((r==="between"||r==="not between")&&i.length<2))return{filterId:e.id,name:e.column,operation:r,valueType:n,values:i,dataType:e.dataType,fieldMeta:e.fieldMeta,semanticContext:e.semanticContext}}function We(e,t,n){return n?{code:e,message:t,cardId:n}:{code:e,message:t}}function Ge(e,t,n){const r=(t||[]).filter(a=>a.scope==="card"&&a.targetCardId===n).map(a=>a.field).filter(Boolean);return r.length===0?e:{...e,calculatedFields:[...e.calculatedFields||[],...r]}}function Ke(e){const t={};return{inputs:(e.filterInputs||[]).map((r,a)=>{const i=K(r.filter,r.defaultValue);return i&&(t.shared??(t.shared={}),t.shared[r.id]={status:"set",value:{kind:"filter",filterValue:i}}),{id:r.id,kind:"filter",label:r.label,variableName:r.variableName,scope:r.scope||{kind:"allSheets",sheetKinds:["dashboard"]},runtimeScope:"shared",presentation:{placement:"toolbar",order:a},exports:["label","value","start","end","range"],filter:r.filter}}),defaultInputValues:t.shared&&Object.keys(t.shared).length>0?t:void 0}}function Ue(e){var b,y;const t=he(e.plan);if(!t.ok)throw new Error(t.errors.map(c=>c.message).join(`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v=require("../chunks/validators-Bu5tOTYW.js"),Se=require("../chunks/catalog-field-grounding-Du6mKDcF.js"),re=["lg","md","sm","xs","xxs"],$=10;function _(e){return e&&typeof e=="object"?e:null}function D(e){return typeof e=="string"?e:null}function ae(e){var t,n,r;return!!(e&&typeof e=="object")&&(((t=_(e))==null?void 0:t.kind)==="semantic"||((n=_(e))==null?void 0:n.kind)==="physical"||((r=_(e))==null?void 0:r.kind)==="sql")}function N(e){return ae(e)?e.kind==="semantic"?!!(e.domainId&&e.datasetName):e.kind==="physical"?!!(e.connectionId&&e.tableName):!1:!1}function we(e){return v.semaphorSourceIdentityKey(e)}function G(e,t){return v.semaphorSourcesReferToSameDataset(e,t)}function ie(e,t){return v.preferSemaphorSourceMetadata(e,t)}function M(e){const t=[];for(const n of e){const r=t.findIndex(a=>G(a,n));r===-1?t.push(n):t[r]=ie(t[r],n)}return t}function ve(e){return M(e)[0]}function H(e,t){return e.kind!=="semantic"||e.connectionId||(t==null?void 0:t.kind)!=="semantic"||!v.semaphorSourcesReferToSameDataset(e,t)||!t.connectionId?e:{...e,connectionId:t.connectionId}}function W(e){return N(e)?e:void 0}function ne(e,t){if(!(e.kind!=="semantic"||e.connectionId))return t.find(n=>(n==null?void 0:n.kind)==="semantic"&&v.semaphorSourcesReferToSameDataset(e,n)&&!!n.connectionId)}function w(e,t){const n=W(e==null?void 0:e.source);return n?H(n,t):void 0}function oe({explicitSource:e,field:t,defaultSource:n,fallbackSources:r}){const a=[n,...r||[]],i=W(e),o=i?H(i,ne(i,a)):void 0;if(o)return o;if(e!==void 0)return;const d=w(t,n),s=d?H(d,ne(d,a)):void 0;if(s)return s;if((t==null?void 0:t.source)===void 0)return W(n)}function De(e,t){if(!(e!=null&&e.name)||!(t!=null&&t.name)||e.name!==t.name)return!1;const n=w(e),r=w(t);return!n||!r?!0:G(n,r)}function C(e){var t;return D((t=_(e))==null?void 0:t.kind)}function se(e){var t,n;return C(e)!=="semantic"?null:((n=D((t=_(e))==null?void 0:t.domainId))==null?void 0:n.trim())||null}function Ae(e){var t;return C(e)!=="semantic"?null:D((t=_(e))==null?void 0:t.datasetName)}function Ce(e){var t;return C(e)!=="semantic"?null:D((t=_(e))==null?void 0:t.datasetId)}function ke(e){var t;return C(e)!=="physical"?null:D((t=_(e))==null?void 0:t.connectionId)}function xe(e){var t;return C(e)!=="physical"?null:D((t=_(e))==null?void 0:t.tableName)}function Fe(e){var t;return C(e)!=="physical"?"":D((t=_(e))==null?void 0:t.databaseName)||""}function Te(e){var t;return C(e)!=="physical"?"":D((t=_(e))==null?void 0:t.schemaName)||""}function de(e){if(e.analyticsIntent&&typeof e.analyticsIntent=="object"&&"source"in e.analyticsIntent)return e.analyticsIntent.source}function ce({datasets:e,requireAtLeastOne:t}){if(t&&e.length<1)return{ok:!1,issue:"invalid_dataset_count"};if(e.length<=1)return{ok:!0};const n=e.map(se),r=new Set(n.filter(Boolean));return n.some(a=>!a)||r.size!==1?{ok:!1,issue:"invalid_multi_dataset_scope"}:{ok:!0}}function z(e,t){if(!t)return!1;if(t.kind==="semantic"){const n=Ce(e);return se(e)===t.domainId?n&&t.datasetId?n===t.datasetId:Ae(e)===t.datasetName:!1}return t.kind==="physical"?ke(e)===t.connectionId&&xe(e)===t.tableName&&Fe(e)===(t.databaseName||"")&&Te(e)===(t.schemaName||""):!1}function $e(e,t){return e.find(n=>z(n,t))}function f(e,t,n){return n?{code:e,message:t,cardId:n}:{code:e,message:t}}function B(e){const t=new Set;for(const n of e){if(t.has(n))return n;t.add(n)}return null}function le({card:e,datasets:t,errors:n}){if(e.type==="text")return;const r=de(e);if(!r){if(t.length<=1)return;n.push(f("missing_card_analytics_source","Multi-dataset dashboard cards must include analytics intent with a source so the materializer can choose the correct dataset.",e.id));return}t.some(a=>z(a,r))||n.push(f("invalid_card_analytics_source","Dashboard cards with an explicit analytics source must use one of the selected datasets.",e.id))}function V(e){return e.map(t=>t==null?void 0:t.source).filter(t=>!!t)}function L(e){return Array.isArray(e)?e.filter(t=>!!(t&&typeof t=="object")):[]}function Me(e){return Array.isArray(e)?e.filter(t=>!!(t&&typeof t=="object")):[]}function Ne(e){var n;if(!e)return[];const t=[e.source];return e.kind==="metric"?t.push(...V([...L(e.metrics),e.primaryMetric,e.dateField,...L(e.dimensions),...Me(e.filters).map(r=>r.field)])):e.kind==="records"?t.push(...V([...L(e.fields),e.dateField,(n=e.orderBy)==null?void 0:n.field])):e.kind==="inputOptions"?t.push(...V([e.field])):e.kind==="sql"&&t.push(...V(e.fields||[])),t}function ue({card:e,datasets:t,errors:n}){if(e.type!=="text"){for(const r of Ne(e.analyticsIntent))if(r&&!t.some(a=>z(a,r))){n.push(f("invalid_card_query_source","Dashboard card query field references must use one of the selected datasets.",e.id));return}}}function fe({card:e,errors:t}){if(e.type==="text"||!e.analyticsIntent)return;const n=v.validateSemaphorAnalyticsIntent(e.analyticsIntent);if(!n.ok)for(const r of n.errors)t.push(f(r.code,r.path?`${r.path}: ${r.message}`:r.message,e.id))}function pe({datasets:e,errors:t,requireAtLeastOne:n}){const r=ce({datasets:e,requireAtLeastOne:n});if(!r.ok){if(r.issue==="invalid_dataset_count"){t.push(f("invalid_dataset_count","Dashboard authoring requires at least one selected dataset."));return}t.push(f("invalid_multi_dataset_scope","Multi-dataset dashboard authoring is limited to semantic datasets from one domain."))}}function he(e){var p,S;const t=[];if(!e||typeof e!="object")return{ok:!1,errors:[f("invalid_plan","Dashboard plan must be a structured object.")],warnings:[]};const n=e,r=[...n.warnings||[]];n.version!==1&&t.push(f("invalid_version","Dashboard plan version must be 1.")),(p=n.title)!=null&&p.trim()||t.push(f("missing_title","Dashboard plan needs a title."));const a=Array.isArray(n.datasets)?n.datasets:[],i=Array.isArray(n.sheets)?n.sheets:[];pe({datasets:a,errors:t,requireAtLeastOne:!0}),i.length!==1&&t.push(f("invalid_sheet_count","MVP dashboard authoring creates exactly one dashboard sheet."));const o=i[0];o&&o.kind!=="dashboard"&&t.push(f("invalid_sheet_kind",'Generated sheet must use kind "dashboard".'));const d=(o==null?void 0:o.cards)||[];d.length>$&&t.push(f("too_many_cards",`Generated dashboards can contain at most ${$} cards.`));const s=B(d.map(l=>l.id));s&&t.push(f("duplicate_card_id",`Duplicate generated card id: ${s}.`));const u=B(d.map(l=>l.frameId));u&&t.push(f("duplicate_frame_id",`Duplicate generated frame id: ${u}.`));for(const l of d)(S=l.title)!=null&&S.trim()||t.push(f("missing_card_title","Card title is required.",l.id)),l.type==="custom"&&t.push(f("custom_visual_out_of_scope","Whole-dashboard authoring supports built-in visual types only.",l.id)),l.type!=="text"&&!l.analyticsIntent&&r.push(f("missing_analytics_intent","Non-text card has no analytics intent and may be skipped by the app layer.",l.id)),le({card:l,datasets:a,errors:t}),fe({card:l,errors:t}),ue({card:l,datasets:a,errors:t});const h=Array.isArray(n.filterInputs)?n.filterInputs:[],b=h.map(l=>l.id),y=B(b);y&&t.push(f("duplicate_input_id",`Duplicate dashboard input id: ${y}.`));const c=h.map(l=>l.variableName).filter(Boolean)||[],g=B(c);g&&t.push(f("duplicate_input_variable",`Duplicate dashboard input variable name: ${g}.`));const A=Array.isArray(n.calculatedFields)?n.calculatedFields:[];for(const l of A)l.scope==="domain"&&l.reuseOnly!==!0&&t.push(f("domain_calculated_field_create_out_of_scope",`Creating domain calculated field "${l.name}" is outside MVP.`));return{ok:t.length===0,errors:t,warnings:r}}function me(e){var o;const t=[];if(!e||typeof e!="object")return{ok:!1,errors:[f("invalid_change_plan","Dashboard change plan must be a structured object.")],warnings:[]};const n=e,r=[...n.warnings||[]];n.version!==1&&t.push(f("invalid_version","Dashboard change plan version must be 1.")),(o=n.dashboardId)!=null&&o.trim()||t.push(f("missing_dashboard_id","Dashboard change plan needs a dashboard id."));const a=Array.isArray(n.datasets)?n.datasets:[],i=Array.isArray(n.operations)?n.operations:[];pe({datasets:a,errors:t,requireAtLeastOne:!1});for(const d of i){if(d.kind==="unsupported"){r.push(f("unsupported_operation",d.reason||d.requestedAction));continue}d.kind==="addCard"&&d.card.type==="custom"&&t.push(f("custom_visual_out_of_scope","Whole-dashboard authoring supports built-in visual types only.",d.card.id)),d.kind==="addCard"&&(le({card:d.card,datasets:a,errors:t}),fe({card:d.card,errors:t}),ue({card:d.card,datasets:a,errors:t})),d.kind==="addCalculatedField"&&d.field.scope==="domain"&&d.field.reuseOnly!==!0&&t.push(f("domain_calculated_field_create_out_of_scope",`Creating domain calculated field "${d.field.name}" is outside MVP.`))}return{ok:t.length===0,errors:t,warnings:r}}const Pe={lg:48,md:36,sm:24,xs:12,xxs:6};function Re(e,t){let n=0,r=0,a=0;return e.map(i=>{const o=Math.min(i.w,t);n>0&&n+o>t&&(n=0,r+=a,a=0);const d={i:i.frameId,x:n,y:r,w:o,h:i.h,minW:Math.min(i.minW,t),minH:i.minH,static:!1};return n+=o,a=Math.max(a,i.h),d})}function Be(e){const t=[...e].sort((s,u)=>s.priority-u.priority),n=t.filter(s=>s.role==="kpi"),r=t.filter(s=>s.role==="chart"),a=t.filter(s=>s.role==="table"),i=t.filter(s=>s.role==="text"),o=i.slice(0,1),d=i.slice(o.length);return{kpis:n,introText:o,charts:r,tables:a,supportingText:d}}function Ve(e,t,n){return t==="xxs"||t==="xs"?n:t==="sm"?Math.min(12,n):t==="md"?e<=1||e===2?18:12:e<=1||e===2?24:e===3?16:12}function ze(e,t,n,r){return n==="xxs"||n==="xs"||n==="sm"||n==="md"||t===1||t%2===1&&e===0?r:r/2}function Oe(e){const{item:t,band:n,index:r,bandCount:a,breakpoint:i,columns:o}=e;return n==="kpi"?{...t,band:n,w:Ve(a,i,o),h:15,minW:Math.min(6,o),minH:12}:n==="table"?{...t,band:n,w:o,h:i==="xxs"||i==="xs"?34:38,minW:Math.min(12,o),minH:18}:n==="introText"?{...t,band:n,w:o,h:i==="xxs"||i==="xs"?12:10,minW:Math.min(12,o),minH:8}:n==="supportingText"?{...t,band:n,w:i==="lg"?o/2:o,h:i==="xxs"||i==="xs"?12:10,minW:Math.min(12,o),minH:8}:{...t,band:n,w:ze(r,a,i,o),h:i==="xxs"||i==="xs"?28:30,minW:Math.min(12,o),minH:16}}function x(e,t,n,r){return e.map((a,i)=>Oe({item:a,band:t,index:i,bandCount:e.length,breakpoint:n,columns:r}))}function O(e){const t=Be(e);return Object.fromEntries(re.map(n=>{const r=Pe[n],a=[...x(t.introText,"introText",n,r),...x(t.kpis,"kpi",n,r),...x(t.charts,"chart",n,r),...x(t.tables,"table",n,r),...x(t.supportingText,"supportingText",n,r)];return[n,Re(a,r)]}))}function qe(e){const t=Se.normalizeAnalyticsCatalogDataType(e);return t==="datetime"?"date":t==="unknown"?"string":t}function Le(e){return!!(e&&typeof e=="object"&&!Array.isArray(e))}function je(e){return Le(e)&&typeof e.filterId=="string"&&typeof e.operation=="string"&&Array.isArray(e.values)}function Ee(e){return e.filter(t=>typeof t=="string"||typeof t=="number")}function He(e){return e.filter(t=>t instanceof Date||typeof t=="string")}function K(e,t){if(t===void 0)return;const n=qe(e.dataType),r=e.operation||"in";if(je(t))return{...t,filterId:e.id,name:t.name||e.column,valueType:n,dataType:e.dataType,fieldMeta:e.fieldMeta,semanticContext:e.semanticContext};if(r==="is null"||r==="is not null")return{filterId:e.id,name:e.column,operation:r,valueType:n,values:[],dataType:e.dataType,fieldMeta:e.fieldMeta,semanticContext:e.semanticContext};const a=Array.isArray(t)?t:[t],i=n==="date"?He(a):Ee(a);if(i.length!==0&&!((r==="between"||r==="not between")&&i.length<2))return{filterId:e.id,name:e.column,operation:r,valueType:n,values:i,dataType:e.dataType,fieldMeta:e.fieldMeta,semanticContext:e.semanticContext}}function We(e,t,n){return n?{code:e,message:t,cardId:n}:{code:e,message:t}}function Ge(e,t,n){const r=(t||[]).filter(a=>a.scope==="card"&&a.targetCardId===n).map(a=>a.field).filter(Boolean);return r.length===0?e:{...e,calculatedFields:[...e.calculatedFields||[],...r]}}function Ke(e){const t={};return{inputs:(e.filterInputs||[]).map((r,a)=>{const i=K(r.filter,r.defaultValue);return i&&(t.shared??(t.shared={}),t.shared[r.id]={status:"set",value:{kind:"filter",filterValue:i}}),{id:r.id,kind:"filter",label:r.label,variableName:r.variableName,scope:r.scope||{kind:"allSheets",sheetKinds:["dashboard"]},runtimeScope:"shared",presentation:{placement:"toolbar",order:a},exports:["label","value","start","end","range"],filter:r.filter}}),defaultInputValues:t.shared&&Object.keys(t.shared).length>0?t:void 0}}function Ue(e){var b,y;const t=he(e.plan);if(!t.ok)throw new Error(t.errors.map(c=>c.message).join(`
2
2
  `)||"Dashboard plan is invalid.");const n=e.plan.sheets[0],r=[...t.warnings],a=[],i=new Map(e.cardArtifacts.map(c=>[c.planCardId,c])),o=[];for(const c of n.cards){const g=i.get(c.id);if(!g){const p=We("missing_card_artifact",`Card "${c.title}" was skipped because no generated artifact was supplied.`,c.id);a.push(p);continue}r.push(...g.warnings||[]);const A=Ge(g.card,e.plan.calculatedFields,c.id);o.push({id:c.frameId,cards:[A],activeCardId:A.id})}if(o.length===0)throw new Error("Dashboard plan did not produce any persistable cards.");const{inputs:d,defaultInputValues:s}=Ke(e.plan),u=O(n.cards.filter(c=>o.some(g=>g.id===c.frameId)).map(c=>({frameId:c.frameId,priority:c.priority,role:c.role})));return{dashboard:{id:e.dashboardId,title:e.plan.title,description:e.plan.description||"",sheets:[{id:n.id,kind:"dashboard",title:n.title,description:n.description,frames:o,layouts:u,calculatedFields:(b=e.plan.calculatedFields)==null?void 0:b.filter(c=>c.scope==="sheet"&&c.field).map(c=>c.field)}],calculatedFields:(y=e.plan.calculatedFields)==null?void 0:y.filter(c=>c.scope==="dashboard"&&c.field).map(c=>c.field),inputs:d,...s?{defaultInputValues:s}:{}},warnings:r,skippedOperations:a}}function k(e,t,n){return n?{code:e,message:t,cardId:n}:{code:e,message:t}}function Xe(e){return JSON.parse(JSON.stringify(e))}function Je(e){var t;return(t=e.sheets)==null?void 0:t.find(n=>(n.kind||"dashboard")==="dashboard")}function j(e,t){var n;for(const r of e.sheets||[])for(const a of r.frames||[]){const i=(n=a.cards)==null?void 0:n.find(o=>o.id===t);if(i)return{sheet:r,frame:a,card:i}}return null}function ge(e){var n,r;const t=(r=(n=e.cards)==null?void 0:n[0])==null?void 0:r.type;return t==="kpi"?"kpi":t==="table"||t==="detailTable"||t==="pivotTable"?"table":t==="text"?"text":"chart"}function Qe(e){var t;return new Map((((t=e.layouts)==null?void 0:t.lg)||[]).map((n,r)=>[n.i,r]))}function be(e,t=new Map){const n=Qe(e),r=Math.max(n.size,t.size),a=(e.frames||[]).map((i,o)=>({frameId:i.id,role:ge(i),priority:t.get(i.id)??n.get(i.id)??r+o}));e.layouts=O(a)}function Ye(e){return Object.values(e.layouts||{}).some(t=>t.length>0)}function Ze(e,t){if(!Ye(e)){be(e);return}const n=O([{frameId:t.id,role:ge(t),priority:0}]);e.layouts??(e.layouts={});for(const[r,a]of Object.entries(n)){const i=e.layouts[r]||[];if(i.some(s=>s.i===t.id))continue;const o=a[0];if(!o)continue;const d=i.reduce((s,u)=>Math.max(s,u.y+u.h),0);e.layouts[r]=[...i,{...o,y:d}]}}function et(e,t){var r;const n=K(t.filter,t.defaultValue);n&&(e.defaultInputValues??(e.defaultInputValues={}),(r=e.defaultInputValues).shared??(r.shared={}),e.defaultInputValues.shared[t.id]={status:"set",value:{kind:"filter",filterValue:n}})}function tt(e){var d;const t=me(e.changePlan);if(!t.ok)throw new Error(t.errors.map(s=>s.message).join(`
3
3
  `)||"Dashboard change plan is invalid.");const n=Xe(e.dashboard),r=[...t.warnings],a=[],i=new Map(e.cardArtifacts.map(s=>[s.planCardId,s])),o=Je(n);if(!o)throw new Error("Dashboard has no editable dashboard sheet.");o.frames??(o.frames=[]);for(const s of e.changePlan.operations)switch(s.kind){case"addCard":{if((o.frames||[]).reduce((y,c)=>{var g;return y+(((g=c.cards)==null?void 0:g.length)||0)},0)>=$){a.push(k("generated_card_limit_reached",`MVP AI refinement is capped at ${$} cards.`,s.card.id));break}const h=i.get(s.card.id);if(!h){a.push(k("missing_card_artifact",`Card "${s.card.title}" was skipped because no generated artifact was supplied.`,s.card.id));break}const b={id:s.card.frameId,cards:[h.card],activeCardId:h.card.id};o.frames.push(b),Ze(o,b);break}case"addFilterInput":{n.inputs??(n.inputs=[]);const u={id:s.input.id,kind:"filter",label:s.input.label,variableName:s.input.variableName,scope:s.input.scope||{kind:"allSheets",sheetKinds:["dashboard"]},runtimeScope:"shared",presentation:{placement:"toolbar",order:n.inputs.length},exports:["label","value","start","end","range"],filter:s.input.filter};n.inputs.push(u),et(n,s.input);break}case"addCalculatedField":{if(s.field.scope==="dashboard"&&s.field.field)n.calculatedFields??(n.calculatedFields=[]),n.calculatedFields.push(s.field.field);else if(s.field.scope==="sheet"&&s.field.field)o.calculatedFields??(o.calculatedFields=[]),o.calculatedFields.push(s.field.field);else if(s.field.scope==="card"&&s.field.field){const u=s.field.targetCardId?j(n,s.field.targetCardId):null;u?((d=u.card).calculatedFields??(d.calculatedFields=[]),u.card.calculatedFields.push(s.field.field)):a.push(k("missing_calculated_field_target",`Calculated field "${s.field.name}" needs a valid target card.`))}break}case"renameCard":{const u=j(n,s.cardId);if(!u){a.push(k("card_not_found",`Card "${s.cardId}" could not be renamed because it was not found.`,s.cardId));break}u.card.title=s.title,s.description!==void 0&&(u.card.description=s.description);break}case"reorderCards":{const u=new Map;for(let h=0;h<s.cardIds.length;h+=1){const b=s.cardIds[h],y=j(n,b);y&&u.set(y.frame.id,h)}be(o,u);break}case"reuseCalculatedField":r.push(k("reused_calculated_field",`Calculated field "${s.fieldId}" is reused by reference.`));break;case"unsupported":a.push(k("unsupported_operation",s.reason||s.requestedAction));break}return{dashboard:n,warnings:r,skippedOperations:a}}function I(e,t,n){return n?{code:e,message:t,cardId:n}:{code:e,message:t}}function T(e,t){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||t}function Ie(e,t){if(!t.has(e))return t.add(e),e;let n=2,r=`${e}-${n}`;for(;t.has(r);)n+=1,r=`${e}-${n}`;return t.add(r),r}function P(e){return!!(e&&typeof e=="object")}function ye(e){return Array.isArray(e.inputs)?e.inputs.filter(t=>P(t)&&typeof t.id=="string"):[]}function U(e){return Array.isArray(e.sections)?e.sections.filter(t=>P(t)):[]}function X(e){return Array.isArray(e.views)?e.views.filter(t=>P(t)):[]}function F(e){if(!Array.isArray(e))return[];const t=[];for(const n of e){const r=w(n);r&&t.push(r)}return t}function nt(e){var r;if(!e)return[];const t=[];if(N(e.source)&&t.push(e.source),e.kind==="metric"){t.push(...F(e.metrics));const a=w(e.dateField);a&&t.push(a),t.push(...F(e.dimensions)),t.push(...F((r=e.filters)==null?void 0:r.map(i=>i.field)))}else if(e.kind==="records"){const a=w(e.dateField);a&&t.push(a),t.push(...F(e.fields))}else if(e.kind==="inputOptions"){const a=w(e.field);a&&t.push(a)}else e.kind==="sql"&&t.push(...F(e.fields));const n="inputs"in e&&Array.isArray(e.inputs)?e.inputs:[];for(const a of n){const i=w(a.field);i&&t.push(i)}return t}function rt(e){const t=[];for(const n of ye(e)){const r=w(n.field);r&&t.push(r)}for(const n of U(e))for(const r of X(n))t.push(...nt(r.analytics));return t}function at(e){var n;const t=[];for(const r of U(e))for(const a of X(r))N((n=a.analytics)==null?void 0:n.source)&&t.push(a.analytics.source);return t}function it(e,t){const n=M(e).filter(N);if(n.length===0)return t.push(I("missing_materializable_dataset","No semantic or physical source could be converted into the current dashboard authoring dataset reference.")),[];const r=n.every(i=>i.kind==="semantic"),a=Array.from(new Set(n.filter(i=>i.kind==="semantic").map(i=>i.domainId)));return n.length>1&&(!r||a.length!==1)?(t.push(I("multiple_datasets_out_of_scope","The dashboard authoring compiler supports multiple datasets only within one semantic domain; using the first source and deferring the rest.")),[n[0]]):n}function ot(e,t){const n=U(e),r=ye(e),a=M(rt(e)),i=M(at(e));return{sections:n,inputs:r,sources:a,primarySources:i,defaultSource:i.length===1?i[0]:void 0,datasets:it(a,t)}}function st(e){return e&&v.validateSemaphorAnalyticsIntent(e).ok?e:void 0}function dt(e){var t;switch((t=e.presentation)==null?void 0:t.kind){case"kpi":return"kpi";case"lineChart":return"line";case"barChart":return"bar";case"areaChart":return"area";case"table":return"table";case"text":return"text";default:return null}}function ct(e){var t,n,r;return((t=e.presentation)==null?void 0:t.kind)==="kpi"?"kpi":((n=e.presentation)==null?void 0:n.kind)==="table"?"table":((r=e.presentation)==null?void 0:r.kind)==="text"?"text":"chart"}function lt(e){switch(e){case"not_in":return"not in";case"not_between":return"not between";case"contains":return"like";default:return e||"in"}}function ut(e){return P(e.field)?e.field.dataType==="datetime"?"date":e.field.dataType||"string":"string"}function ft(e){if(!(!e||e.kind!=="physical"))return[e.databaseName,e.schemaName,e.tableName].filter(Boolean).join(".")}function pt(e,t,n,r,a,i){if(e.kind!=="filter")return i.push(I("control_inputs_deferred",`Control input "${e.label}" is represented in the protocol but not yet materialized by the dashboard authoring adapter.`)),null;if(!P(e.field)||typeof e.field.name!="string")return i.push(I("filter_requires_field",`Filter "${e.label||e.id}" needs a field before the dashboard compiler can materialize it.`)),null;const o=oe({explicitSource:void 0,field:e.field,defaultSource:t,fallbackSources:n}),d=(o==null?void 0:o.kind)==="semantic"||(o==null?void 0:o.kind)==="physical"?o.connectionId:void 0;if(!d)return i.push(I("filter_requires_connection_id",`Filter "${e.label}" needs a source connectionId before the dashboard compiler can materialize it.`)),null;const h={id:`filter-${Ie(T(e.id,e.field.name),a)}`,variableName:e.id,connectionId:d,title:e.label,column:e.field.name,dataType:ut(e),qualifiedTableName:ft(o),sql:"",operation:lt(e.operator),type:e.multi===!1?"single":"multiple",location:"dashboard",displayMode:"toolbar",fieldMeta:(o==null?void 0:o.kind)==="semantic"?{name:e.field.name,qualifiedFieldName:e.field.name,dataType:e.field.dataType,role:e.field.role==="measure"?"metric":"groupby"}:void 0,semanticContext:(o==null?void 0:o.kind)==="semantic"?{semanticDomainId:o.domainId,connectionId:o.connectionId}:void 0};return{id:e.id,label:e.label,variableName:e.id,scope:r,filter:h,defaultValue:K(h,e.defaultValue)}}function E(e){const t=[],n=[];for(const r of e.viewIds){const a=e.viewIdToCardId.get(r);a?t.push(a):n.push(r)}return n.length>0&&e.warnings.push(I("input_scope_view_not_found",`Filter "${e.inputLabel}" referenced unknown view ids: ${n.join(", ")}.`)),Array.from(new Set(t))}function ht(e){var r,a;if(!e.protocolScope){const i=Array.from(new Set(e.boundCardIds));return i.length>0&&i.length<e.allCardIds.length?{kind:"cards",cardIds:i}:void 0}if(e.protocolScope.level==="dashboard"){if(!((r=e.protocolScope.excludeViewIds)!=null&&r.length))return;const i=new Set(E({inputLabel:e.inputLabel,viewIds:e.protocolScope.excludeViewIds,viewIdToCardId:e.viewIdToCardId,warnings:e.warnings}));return{kind:"cards",cardIds:e.allCardIds.filter(o=>!i.has(o))}}if(e.protocolScope.level==="view"){const i=E({inputLabel:e.inputLabel,viewIds:e.protocolScope.viewIds,viewIdToCardId:e.viewIdToCardId,warnings:e.warnings});return i.length===0?(e.warnings.push(I("input_scope_has_no_materialized_cards",`Filter "${e.inputLabel}" was deferred because its view scope does not match any materialized cards.`)),null):{kind:"cards",cardIds:i}}const t=e.sectionIdToCardIds.get(e.protocolScope.sectionId)||[];if(t.length===0)return e.warnings.push(I("input_scope_section_not_found",`Filter "${e.inputLabel}" was deferred because section "${e.protocolScope.sectionId}" does not match any materialized cards.`)),null;if(!((a=e.protocolScope.excludeViewIds)!=null&&a.length))return{kind:"cards",cardIds:t};const n=new Set(E({inputLabel:e.inputLabel,viewIds:e.protocolScope.excludeViewIds,viewIdToCardId:e.viewIdToCardId,warnings:e.warnings}));return{kind:"cards",cardIds:t.filter(i=>!n.has(i))}}function mt(e){var c,g,A;const t=[],n=v.validateSemaphorDashboardIntent(e);for(const p of n.warnings)t.push(I(p.code,p.message));for(const p of n.errors)t.push(I(p.code,p.message));const r=ot(e,t),a=[],i=new Map,o=new Map,d=new Map,s=new Set,u=new Set;let h=0;for(const[p,S]of r.sections.entries()){const l=typeof S.title=="string"?S.title:`Section ${p+1}`,J=S.id||T(l,`section-${p+1}`);o.set(J,[]);for(const[Q,m]of X(S).entries()){const Y=dt(m),q=T(m.id||`${l}-${m.title||`View ${Q+1}`}`,`card-${p+1}-${Q+1}`);if(!Y){t.push(I("unsupported_presentation",`Dashboard presentation "${((c=m.presentation)==null?void 0:c.kind)||"unknown"}" is not supported by the dashboard authoring adapter.`,`card-${q}`));continue}if(((g=m.analytics)==null?void 0:g.kind)==="sql"){t.push(I("sql_intent_deferred","SQL analytics intent is valid protocol, but the current dashboard authoring adapter only materializes semantic and physical config-card intents.",`card-${q}`));continue}const Z=Ie(q,s),R=`card-${Z}`;m.id&&i.set(m.id,R),(A=o.get(J))==null||A.push(R);const _e=m.analytics&&"inputs"in m.analytics?m.analytics.inputs:void 0;for(const ee of _e||[]){const te=d.get(ee.inputId)||[];te.push(R),d.set(ee.inputId,te)}a.push({id:R,frameId:`frame-${Z}`,title:m.title,description:m.description,type:Y,role:ct(m),priority:h,section:l,analyticsIntent:st(m.analytics),text:m.text}),h+=1}}const b=r.inputs.map(p=>{const S=ht({protocolScope:p.scope,inputLabel:p.label,allCardIds:a.map(l=>l.id),boundCardIds:d.get(p.id)||[],viewIdToCardId:i,sectionIdToCardIds:o,warnings:t});return S===null?null:pt(p,r.defaultSource,r.sources,S,u,t)}).filter(p=>!!p);return{plan:{version:1,id:`plan-${T(e.title,"dashboard")}`,title:e.title,description:e.description,datasets:r.datasets,sheets:[{id:`sheet-${T(e.title,"dashboard")}`,title:e.title,description:e.description,kind:"dashboard",cards:a}],filterInputs:b.length?b:void 0,warnings:t.length?t:void 0,unresolvedRequests:n.ok?void 0:n.errors.map(p=>p.message)},warnings:t}}exports.DASHBOARD_AUTHORING_BREAKPOINTS=re;exports.DASHBOARD_AUTHORING_MAX_GENERATED_CARDS=$;exports.applyDashboardChangePlan=tt;exports.compileDashboardFromPlan=Ue;exports.compileResponsiveDashboardLayouts=O;exports.dashboardAuthoringDatasetMatchesSource=z;exports.dashboardAuthoringFieldsReferToSameTarget=De;exports.dashboardAuthoringSourceFromField=w;exports.dashboardAuthoringSourceKey=we;exports.dashboardAuthoringSourcesReferToSameDataset=G;exports.dashboardPlanFromSemaphorDashboardIntent=mt;exports.findDashboardAuthoringDatasetForSource=$e;exports.getDashboardAuthoringCardSource=de;exports.isMaterializableDashboardAuthoringSource=N;exports.isSemaphorSourceRef=ae;exports.mergeDashboardAuthoringSources=M;exports.preferDashboardAuthoringSourceMetadata=ie;exports.preferredDashboardAuthoringSource=ve;exports.resolveDashboardAuthoringSource=oe;exports.validateDashboardAuthoringDatasetScope=ce;exports.validateDashboardChangePlan=me;exports.validateDashboardPlan=he;
@@ -1,4 +1,4 @@
1
- import { s as he, d as W, p as me, v as ne, c as ge } from "../chunks/validators-yMB7Tm4j.js";
1
+ import { s as he, d as W, p as me, v as ne, c as ge } from "../chunks/validators-ZeP5TVCl.js";
2
2
  import { b as be } from "../chunks/catalog-field-grounding-DoEBOXQd.js";
3
3
  const Ie = [
4
4
  "lg",
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const S=require("../chunks/validators-8R9pr2K9.js"),K=require("../chunks/index-BxM99sFL.js"),a=require("react"),F=require("react/jsx-runtime");function E(e){var r;const t=V(e);return{version:1,kind:"metric",id:e.id,label:e.label,source:k(e),metrics:t,primaryMetric:z(e,t),dateField:e.dateField?l(e.dateField,"date"):void 0,timeGrain:e.timeGrain,dimensions:(r=e.dimensions)==null?void 0:r.map(n=>l(n,"dimension")),comparison:X(e.comparison),orderBy:e.orderBy?{field:l(e.orderBy.field),direction:e.orderBy.direction}:void 0,inputs:R(e.inputs),limit:e.limit}}function z(e,t){if(!e.primaryMetric)return t[0]||{name:"",role:"measure"};const r=l(e.primaryMetric,"measure"),n=L(r,t),o=n.length===1?n[0]:void 0;return o?B(r,o):r}function V(e){const t=[];for(const r of e.metrics.map(n=>l(n,"measure"))){if(!r.name)continue;const n=t.findIndex(o=>j(o,r));if(n===-1){t.push(r);continue}t[n]=B(t[n],r)}return t}function j(e,t){return S.semaphorFieldRefsMatch(e,t)&&g(e)===g(t)}function N(e,t){return g(t)===g(e)}function Q(e,t){return t.name!==e.name||e.source&&!S.semaphorFieldRefsMatch(t,e)?!1:N(e,t)}function L(e,t){const r=t.filter(n=>Q(e,n));return e.aggregate!==void 0,r}function g(e){return(e.aggregate||"SUM").toUpperCase()}function B(e,t){if(e.aggregate&&t.aggregate&&e.aggregate!==t.aggregate)throw new Error(`Metric "${e.name}" was requested with conflicting aggregate semantics: ${e.aggregate} and ${t.aggregate}.`);return{...S.preferSemaphorFieldRefMetadata(e,t),aggregate:e.aggregate||t.aggregate}}function w(e){if("sort"in e)throw new Error("useSemaphorRecords supports orderBy for a single deterministic sort. Multiple sort clauses are not supported by the analytics protocol yet.");if(!W(e))throw new Error("useSemaphorRecords needs at least one field.");const t=G(e.fields);return{version:1,kind:"records",id:e.id,label:e.label,source:k(e),fields:t,dateField:e.dateField?l(e.dateField,"date"):void 0,timeGrain:e.timeGrain,orderBy:e.orderBy?{field:l(e.orderBy.field),direction:e.orderBy.direction}:void 0,inputs:R(e.inputs),limit:e.limit}}function G(e){return e.map(t=>{const r=l(t);if(!r.role)throw new Error(`useSemaphorRecords field "${r.name}" needs an explicit role.`);return r})}function O(e){return{version:1,kind:"inputOptions",id:e.id,label:e.label,source:k(e),field:l(e.field,"dimension"),search:e.search,limit:e.limit}}function $(e){if("toAnalyticsInput"in e){const t=e.toAnalyticsInput();return{inputId:t.inputId,...t.field?{field:t.field}:{}}}return{inputId:e.inputId,...e.field?{field:e.field}:{}}}function J(e){const t=R(e);return t.length>0?t:void 0}function q(e){return(e||[]).map(H)}function M(e){return q(e).filter(t=>t.isActive)}function C(e){return e.kind==="filter"?{inputId:e.id,kind:e.kind,label:e.label,field:l(e.field,"dimension"),operator:e.operator||"in"}:{inputId:e.id,kind:e.kind,label:e.label}}function T(e=[]){return e.map(t=>typeof t=="object"?t:{label:String(t),value:t})}function y(e){return e==null?!1:Array.isArray(e)?e.length>0:typeof e=="string"?e.trim().length>0:!0}function H(e){return"toAnalyticsInput"in e?e.toAnalyticsInput():"kind"in e&&"isActive"in e?e:{...e,kind:"filter",isActive:y(e.value),value:e.value}}function k(e){return e.source}function W(e){var t;return!!((t=e.fields)!=null&&t.length)}function l(e,t){return{...e,role:e.role||t}}function R(e){return(e||[]).map($)}function X(e){if(e)return e}function P(){return{executeMetric:(e,t)=>v(e,t),executeRecords:(e,t)=>v(e,t),executeInputOptions:(e,t)=>v(e,t)}}async function v(e,t){if(!t.token)throw new Error("SemaphorDataAppProvider needs a token to execute queries.");const r=await fetch(ee(t),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t.token}`},body:JSON.stringify({intent:e,activeInputs:t.activeInputs,resultShape:e.kind})}),n=await Y(r);if(!r.ok||n.error)throw new Error(n.error||`Semaphor Data App execution failed with status ${r.status}.`);return n}async function Y(e){const t=await e.text().catch(()=>"");if(!t.trim())return e.ok?{error:"Semaphor Data App execution returned an empty response."}:{};try{return JSON.parse(t)}catch{return e.ok?{error:"Semaphor Data App execution returned invalid JSON.",details:t}:{error:Z(e,t),details:t}}}function Z(e,t){const r=e.statusText?` ${e.statusText}`:"",n=t.replace(/\s+/g," ").trim();return n?`Semaphor Data App execution failed with status ${e.status}${r}: ${n.slice(0,240)}`:`Semaphor Data App execution failed with status ${e.status}${r}.`}function ee(e){const t=te(e).replace(/\/+$/,"");return t?t.endsWith("/api")?`${t}/v1/data-app/execute`:`${t}/api/v1/data-app/execute`:"/api/v1/data-app/execute"}function te(e){if(e.apiBaseUrl)return e.apiBaseUrl;if(!e.token)return"";try{return K.jwtDecode(e.token).apiServiceUrl||""}catch{return""}}const D=a.createContext({});function U(){if(!(typeof window>"u"))return window.__SEMAPHOR_DATA_APP_RUNTIME__}function _(){return a.useContext(D)}function re({token:e,apiBaseUrl:t,executor:r,children:n}){var d;const o=U(),u=((d=o==null?void 0:o.authToken)==null?void 0:d.accessToken)||e,i=(o==null?void 0:o.dataApiBaseUrl)||(o==null?void 0:o.apiBaseUrl)||t,m=a.useMemo(()=>P(),[]),s=r||m,f=a.useMemo(()=>({token:u,apiBaseUrl:i,executor:s}),[i,s,u]);return F.jsx(D.Provider,{value:f,children:n})}const I={value:null},ne={records:[]},A={options:[]};function oe(e){const t=M(e.inputs);try{const r=E(e),n=b(r);return n?{error:n,activeInputs:t,queryKey:c(void 0,t,n),idleData:I}:{intent:r,error:null,activeInputs:t,queryKey:c(r,t),idleData:I}}catch(r){const n=h(r);return{error:n,activeInputs:t,queryKey:c(void 0,t,n),idleData:I}}}function ie(e){const t=M(e.inputs),r=ne;try{const n=w(e),o=b(n);return o?{error:o,activeInputs:t,queryKey:c(void 0,t,o),idleData:r}:{intent:n,error:null,activeInputs:t,queryKey:c(n,t),idleData:r}}catch(n){const o=h(n);return{error:o,activeInputs:t,queryKey:c(void 0,t,o),idleData:r}}}function ae(e){try{const t=O(e),r=b(t);return r?{error:r,queryKey:c(void 0,void 0,r),idleData:A}:{intent:t,error:null,queryKey:c(t),idleData:A}}catch(t){const r=h(t);return{error:r,queryKey:c(void 0,void 0,r),idleData:A}}}function h(e){return e instanceof Error?e:new Error(String(e))}function b(e){const t=S.validateSemaphorAnalyticsIntent(e);if(t.ok)return null;const r=t.errors.map(n=>n.path?`${n.code} at ${n.path}: ${n.message}`:`${n.code}: ${n.message}`).join("; ");return new Error(`Invalid Semaphor analytics intent. ${r}`)}function c(e,t,r){return JSON.stringify({intent:e,activeInputs:t,error:r==null?void 0:r.message})}function ue(e){const[t,r]=a.useState(e.defaultValue),n=Object.prototype.hasOwnProperty.call(e,"value"),o=n?e.value:t,u=a.useMemo(()=>T(e.options),[e.options]),i=a.useCallback(s=>{var d;const f=s;(d=e.onValueChange)==null||d.call(e,f),n||r(f)},[n,e]),m=a.useCallback(()=>i(void 0),[i]);return a.useMemo(()=>{const s=C(e);return{id:e.id,kind:e.kind,label:e.label,field:s.field,operator:s.operator,controlRole:e.kind==="control"?e.role:void 0,value:o,options:u,isActive:y(o),setValue:i,clear:m,toAnalyticsInput:()=>({inputId:s.inputId,field:s.field,kind:e.kind,label:e.label,value:o,isActive:y(o),operator:s.operator,controlRole:e.kind==="control"?e.role:void 0})}},[m,u,i,e,o])}function se(e){const t=a.useMemo(()=>oe(e),[e]),r=a.useCallback(u=>{var i;return t.intent?(i=u.executor)==null?void 0:i.executeMetric(t.intent,u):void 0},[t.intent]),n=x(t.queryKey,r,t.idleData,t.activeInputs),o=t.error?t.idleData:n.data;return{id:e.id,intent:t.intent,value:(o==null?void 0:o.value)??null,metrics:o==null?void 0:o.metrics,comparisonValue:o==null?void 0:o.comparisonValue,delta:o==null?void 0:o.delta,deltaPercent:o==null?void 0:o.deltaPercent,records:o==null?void 0:o.records,status:t.error?"error":n.status,isLoading:!t.error&&n.status==="loading",error:t.error||n.error}}function le(e){const t=a.useMemo(()=>ie(e),[e]),r=a.useCallback(u=>{var i;return t.intent?(i=u.executor)==null?void 0:i.executeRecords(t.intent,u):void 0},[t.intent]),n=x(t.queryKey,r,t.idleData,t.activeInputs),o=t.error?t.idleData:n.data;return{id:e.id,intent:t.intent,records:(o==null?void 0:o.records)||[],columns:o==null?void 0:o.columns,rowCount:o==null?void 0:o.rowCount,status:t.error?"error":n.status,isLoading:!t.error&&n.status==="loading",error:t.error||n.error}}function de(e){const t=a.useMemo(()=>ae(e),[e]),r=a.useCallback(u=>{var i;return t.intent?(i=u.executor)==null?void 0:i.executeInputOptions(t.intent,u):void 0},[t.intent]),n=x(t.queryKey,r,t.idleData),o=t.error?t.idleData:n.data;return{id:e.id,intent:t.intent,options:(o==null?void 0:o.options)||[],status:t.error?"error":n.status,isLoading:!t.error&&n.status==="loading",error:t.error||n.error}}function x(e,t,r,n){const o=_(),u=a.useRef(t),i=a.useRef(n),[m,s]=a.useState({status:"idle",data:r,error:null});return u.current=t,i.current=n,a.useEffect(()=>{let f;try{f=u.current({...o,activeInputs:i.current})}catch(p){s({status:"error",data:r,error:h(p)});return}if(!f){s({status:"idle",data:r,error:null});return}let d=!1;return s(p=>({status:"loading",data:p.data,error:null})),f.then(p=>{d||s({status:"success",data:p,error:null})}).catch(p=>{d||s({status:"error",data:r,error:h(p)})}),()=>{d=!0}},[r,e,o]),m}exports.SemaphorDataAppContext=D;exports.SemaphorDataAppProvider=re;exports.createSemaphorQueryExecutor=P;exports.hasSemaphorInputValue=y;exports.normalizeSemaphorInputOptions=T;exports.readWindowRuntime=U;exports.toSemaphorActiveInputSnapshots=M;exports.toSemaphorInputBinding=$;exports.toSemaphorInputBindings=J;exports.toSemaphorInputOptionsIntent=O;exports.toSemaphorInputSnapshots=q;exports.toSemaphorInputSpec=C;exports.toSemaphorMetricIntent=E;exports.toSemaphorRecordsIntent=w;exports.useSemaphorDataAppRuntime=_;exports.useSemaphorInput=ue;exports.useSemaphorInputOptions=de;exports.useSemaphorMetric=se;exports.useSemaphorRecords=le;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const S=require("../chunks/validators-Bu5tOTYW.js"),K=require("../chunks/index-BxM99sFL.js"),a=require("react"),F=require("react/jsx-runtime");function E(e){var r;const t=V(e);return{version:1,kind:"metric",id:e.id,label:e.label,source:k(e),metrics:t,primaryMetric:z(e,t),dateField:e.dateField?l(e.dateField,"date"):void 0,timeGrain:e.timeGrain,dimensions:(r=e.dimensions)==null?void 0:r.map(n=>l(n,"dimension")),comparison:X(e.comparison),orderBy:e.orderBy?{field:l(e.orderBy.field),direction:e.orderBy.direction}:void 0,inputs:R(e.inputs),limit:e.limit}}function z(e,t){if(!e.primaryMetric)return t[0]||{name:"",role:"measure"};const r=l(e.primaryMetric,"measure"),n=L(r,t),o=n.length===1?n[0]:void 0;return o?B(r,o):r}function V(e){const t=[];for(const r of e.metrics.map(n=>l(n,"measure"))){if(!r.name)continue;const n=t.findIndex(o=>j(o,r));if(n===-1){t.push(r);continue}t[n]=B(t[n],r)}return t}function j(e,t){return S.semaphorFieldRefsMatch(e,t)&&g(e)===g(t)}function N(e,t){return g(t)===g(e)}function Q(e,t){return t.name!==e.name||e.source&&!S.semaphorFieldRefsMatch(t,e)?!1:N(e,t)}function L(e,t){const r=t.filter(n=>Q(e,n));return e.aggregate!==void 0,r}function g(e){return(e.aggregate||"SUM").toUpperCase()}function B(e,t){if(e.aggregate&&t.aggregate&&e.aggregate!==t.aggregate)throw new Error(`Metric "${e.name}" was requested with conflicting aggregate semantics: ${e.aggregate} and ${t.aggregate}.`);return{...S.preferSemaphorFieldRefMetadata(e,t),aggregate:e.aggregate||t.aggregate}}function w(e){if("sort"in e)throw new Error("useSemaphorRecords supports orderBy for a single deterministic sort. Multiple sort clauses are not supported by the analytics protocol yet.");if(!W(e))throw new Error("useSemaphorRecords needs at least one field.");const t=G(e.fields);return{version:1,kind:"records",id:e.id,label:e.label,source:k(e),fields:t,dateField:e.dateField?l(e.dateField,"date"):void 0,timeGrain:e.timeGrain,orderBy:e.orderBy?{field:l(e.orderBy.field),direction:e.orderBy.direction}:void 0,inputs:R(e.inputs),limit:e.limit}}function G(e){return e.map(t=>{const r=l(t);if(!r.role)throw new Error(`useSemaphorRecords field "${r.name}" needs an explicit role.`);return r})}function O(e){return{version:1,kind:"inputOptions",id:e.id,label:e.label,source:k(e),field:l(e.field,"dimension"),search:e.search,limit:e.limit}}function $(e){if("toAnalyticsInput"in e){const t=e.toAnalyticsInput();return{inputId:t.inputId,...t.field?{field:t.field}:{}}}return{inputId:e.inputId,...e.field?{field:e.field}:{}}}function J(e){const t=R(e);return t.length>0?t:void 0}function q(e){return(e||[]).map(H)}function M(e){return q(e).filter(t=>t.isActive)}function C(e){return e.kind==="filter"?{inputId:e.id,kind:e.kind,label:e.label,field:l(e.field,"dimension"),operator:e.operator||"in"}:{inputId:e.id,kind:e.kind,label:e.label}}function T(e=[]){return e.map(t=>typeof t=="object"?t:{label:String(t),value:t})}function y(e){return e==null?!1:Array.isArray(e)?e.length>0:typeof e=="string"?e.trim().length>0:!0}function H(e){return"toAnalyticsInput"in e?e.toAnalyticsInput():"kind"in e&&"isActive"in e?e:{...e,kind:"filter",isActive:y(e.value),value:e.value}}function k(e){return e.source}function W(e){var t;return!!((t=e.fields)!=null&&t.length)}function l(e,t){return{...e,role:e.role||t}}function R(e){return(e||[]).map($)}function X(e){if(e)return e}function P(){return{executeMetric:(e,t)=>v(e,t),executeRecords:(e,t)=>v(e,t),executeInputOptions:(e,t)=>v(e,t)}}async function v(e,t){if(!t.token)throw new Error("SemaphorDataAppProvider needs a token to execute queries.");const r=await fetch(ee(t),{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t.token}`},body:JSON.stringify({intent:e,activeInputs:t.activeInputs,resultShape:e.kind})}),n=await Y(r);if(!r.ok||n.error)throw new Error(n.error||`Semaphor Data App execution failed with status ${r.status}.`);return n}async function Y(e){const t=await e.text().catch(()=>"");if(!t.trim())return e.ok?{error:"Semaphor Data App execution returned an empty response."}:{};try{return JSON.parse(t)}catch{return e.ok?{error:"Semaphor Data App execution returned invalid JSON.",details:t}:{error:Z(e,t),details:t}}}function Z(e,t){const r=e.statusText?` ${e.statusText}`:"",n=t.replace(/\s+/g," ").trim();return n?`Semaphor Data App execution failed with status ${e.status}${r}: ${n.slice(0,240)}`:`Semaphor Data App execution failed with status ${e.status}${r}.`}function ee(e){const t=te(e).replace(/\/+$/,"");return t?t.endsWith("/api")?`${t}/v1/data-app/execute`:`${t}/api/v1/data-app/execute`:"/api/v1/data-app/execute"}function te(e){if(e.apiBaseUrl)return e.apiBaseUrl;if(!e.token)return"";try{return K.jwtDecode(e.token).apiServiceUrl||""}catch{return""}}const D=a.createContext({});function U(){if(!(typeof window>"u"))return window.__SEMAPHOR_DATA_APP_RUNTIME__}function _(){return a.useContext(D)}function re({token:e,apiBaseUrl:t,executor:r,children:n}){var d;const o=U(),u=((d=o==null?void 0:o.authToken)==null?void 0:d.accessToken)||e,i=(o==null?void 0:o.dataApiBaseUrl)||(o==null?void 0:o.apiBaseUrl)||t,m=a.useMemo(()=>P(),[]),s=r||m,f=a.useMemo(()=>({token:u,apiBaseUrl:i,executor:s}),[i,s,u]);return F.jsx(D.Provider,{value:f,children:n})}const I={value:null},ne={records:[]},A={options:[]};function oe(e){const t=M(e.inputs);try{const r=E(e),n=b(r);return n?{error:n,activeInputs:t,queryKey:c(void 0,t,n),idleData:I}:{intent:r,error:null,activeInputs:t,queryKey:c(r,t),idleData:I}}catch(r){const n=h(r);return{error:n,activeInputs:t,queryKey:c(void 0,t,n),idleData:I}}}function ie(e){const t=M(e.inputs),r=ne;try{const n=w(e),o=b(n);return o?{error:o,activeInputs:t,queryKey:c(void 0,t,o),idleData:r}:{intent:n,error:null,activeInputs:t,queryKey:c(n,t),idleData:r}}catch(n){const o=h(n);return{error:o,activeInputs:t,queryKey:c(void 0,t,o),idleData:r}}}function ae(e){try{const t=O(e),r=b(t);return r?{error:r,queryKey:c(void 0,void 0,r),idleData:A}:{intent:t,error:null,queryKey:c(t),idleData:A}}catch(t){const r=h(t);return{error:r,queryKey:c(void 0,void 0,r),idleData:A}}}function h(e){return e instanceof Error?e:new Error(String(e))}function b(e){const t=S.validateSemaphorAnalyticsIntent(e);if(t.ok)return null;const r=t.errors.map(n=>n.path?`${n.code} at ${n.path}: ${n.message}`:`${n.code}: ${n.message}`).join("; ");return new Error(`Invalid Semaphor analytics intent. ${r}`)}function c(e,t,r){return JSON.stringify({intent:e,activeInputs:t,error:r==null?void 0:r.message})}function ue(e){const[t,r]=a.useState(e.defaultValue),n=Object.prototype.hasOwnProperty.call(e,"value"),o=n?e.value:t,u=a.useMemo(()=>T(e.options),[e.options]),i=a.useCallback(s=>{var d;const f=s;(d=e.onValueChange)==null||d.call(e,f),n||r(f)},[n,e]),m=a.useCallback(()=>i(void 0),[i]);return a.useMemo(()=>{const s=C(e);return{id:e.id,kind:e.kind,label:e.label,field:s.field,operator:s.operator,controlRole:e.kind==="control"?e.role:void 0,value:o,options:u,isActive:y(o),setValue:i,clear:m,toAnalyticsInput:()=>({inputId:s.inputId,field:s.field,kind:e.kind,label:e.label,value:o,isActive:y(o),operator:s.operator,controlRole:e.kind==="control"?e.role:void 0})}},[m,u,i,e,o])}function se(e){const t=a.useMemo(()=>oe(e),[e]),r=a.useCallback(u=>{var i;return t.intent?(i=u.executor)==null?void 0:i.executeMetric(t.intent,u):void 0},[t.intent]),n=x(t.queryKey,r,t.idleData,t.activeInputs),o=t.error?t.idleData:n.data;return{id:e.id,intent:t.intent,value:(o==null?void 0:o.value)??null,metrics:o==null?void 0:o.metrics,comparisonValue:o==null?void 0:o.comparisonValue,delta:o==null?void 0:o.delta,deltaPercent:o==null?void 0:o.deltaPercent,records:o==null?void 0:o.records,status:t.error?"error":n.status,isLoading:!t.error&&n.status==="loading",error:t.error||n.error}}function le(e){const t=a.useMemo(()=>ie(e),[e]),r=a.useCallback(u=>{var i;return t.intent?(i=u.executor)==null?void 0:i.executeRecords(t.intent,u):void 0},[t.intent]),n=x(t.queryKey,r,t.idleData,t.activeInputs),o=t.error?t.idleData:n.data;return{id:e.id,intent:t.intent,records:(o==null?void 0:o.records)||[],columns:o==null?void 0:o.columns,rowCount:o==null?void 0:o.rowCount,status:t.error?"error":n.status,isLoading:!t.error&&n.status==="loading",error:t.error||n.error}}function de(e){const t=a.useMemo(()=>ae(e),[e]),r=a.useCallback(u=>{var i;return t.intent?(i=u.executor)==null?void 0:i.executeInputOptions(t.intent,u):void 0},[t.intent]),n=x(t.queryKey,r,t.idleData),o=t.error?t.idleData:n.data;return{id:e.id,intent:t.intent,options:(o==null?void 0:o.options)||[],status:t.error?"error":n.status,isLoading:!t.error&&n.status==="loading",error:t.error||n.error}}function x(e,t,r,n){const o=_(),u=a.useRef(t),i=a.useRef(n),[m,s]=a.useState({status:"idle",data:r,error:null});return u.current=t,i.current=n,a.useEffect(()=>{let f;try{f=u.current({...o,activeInputs:i.current})}catch(p){s({status:"error",data:r,error:h(p)});return}if(!f){s({status:"idle",data:r,error:null});return}let d=!1;return s(p=>({status:"loading",data:p.data,error:null})),f.then(p=>{d||s({status:"success",data:p,error:null})}).catch(p=>{d||s({status:"error",data:r,error:h(p)})}),()=>{d=!0}},[r,e,o]),m}exports.SemaphorDataAppContext=D;exports.SemaphorDataAppProvider=re;exports.createSemaphorQueryExecutor=P;exports.hasSemaphorInputValue=y;exports.normalizeSemaphorInputOptions=T;exports.readWindowRuntime=U;exports.toSemaphorActiveInputSnapshots=M;exports.toSemaphorInputBinding=$;exports.toSemaphorInputBindings=J;exports.toSemaphorInputOptionsIntent=O;exports.toSemaphorInputSnapshots=q;exports.toSemaphorInputSpec=C;exports.toSemaphorMetricIntent=E;exports.toSemaphorRecordsIntent=w;exports.useSemaphorDataAppRuntime=_;exports.useSemaphorInput=ue;exports.useSemaphorInputOptions=de;exports.useSemaphorMetric=se;exports.useSemaphorRecords=le;
@@ -1,4 +1,4 @@
1
- import { e as x, f as O, v as q } from "../chunks/validators-yMB7Tm4j.js";
1
+ import { e as x, f as O, v as q } from "../chunks/validators-ZeP5TVCl.js";
2
2
  import { j as T } from "../chunks/index-CuHybtft.js";
3
3
  import { createContext as U, useContext as _, useMemo as m, useState as b, useCallback as h, useRef as R, useEffect as C } from "react";
4
4
  import { jsx as K } from "react/jsx-runtime";
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "email": "support@semaphor.cloud"
6
6
  },
7
7
  "license": "MIT",
8
- "version": "0.1.346",
8
+ "version": "0.1.347",
9
9
  "description": "Fully interactive and customizable dashboards for your apps.",
10
10
  "keywords": [
11
11
  "react",
@@ -1 +0,0 @@
1
- "use strict";function _(e){return e?e.kind==="semantic"?[e.kind,e.domainId,e.datasetId||"",e.datasetName].join(":"):e.kind==="physical"?[e.kind,e.connectionId,e.databaseName||"",e.schemaName||"",e.tableName].join(":"):[e.kind,e.connectionId,e.dialect||"",e.label||""].join(":"):""}function b(e,i){return!e||!i?e===i:e.kind!==i.kind?!1:e.kind==="semantic"&&i.kind==="semantic"?e.domainId!==i.domainId?!1:e.datasetId&&i.datasetId?e.datasetId===i.datasetId:e.datasetName===i.datasetName:_(e)===_(i)}function A(e,i){return e.kind!=="semantic"||i.kind!=="semantic"?e:{...e,datasetId:e.datasetId||i.datasetId,label:e.label||i.label,connectionId:e.connectionId||i.connectionId}}function I(e,i){return e.name===i.name&&b(e.source,i.source)}function F(e,i){return{...e,label:e.label||i.label,role:e.role||i.role,dataType:e.dataType||i.dataType,source:e.source&&i.source?A(e.source,i.source):e.source||i.source}}function a(e,i,n){return n?{code:e,message:i,path:n}:{code:e,message:i}}function j(e){for(let i=0;i<e.length;i+=1){const n=e[i];if(e.some((o,r)=>r!==i&&M(o,n)))return!1}return!0}function S(e,i){return I(e,i)}function M(e,i){return S(e,i)&&y(e)===y(i)}function T(e){return`Metric intent has duplicate metric "${e.name}" with the same aggregate (${y(e)}). Use different aggregates to request both, or remove one entry.`}function D(e,i){return h(e,i).length===1}function x(e,i){return h(e,i).length===1}function h(e,i){return i.filter(o=>q(e,o))}function q(e,i){return C(e,i)?e.source?S(i,e):!0:!1}function C(e,i){return!(i.name!==e.name||e.role!==void 0&&i.role!==void 0&&i.role!==e.role||E(e,i)&&y(i)!==y(e))}function E(e,i){return e.role==="measure"||i.role==="measure"||e.aggregate!==void 0||i.aggregate!==void 0}function y(e){return(e.aggregate||"SUM").toUpperCase()}function d(e){return typeof e=="string"&&e.trim().length>0}function c(e){return!!(e&&typeof e=="object"&&!Array.isArray(e))}function g(e){const i=new Set;for(const n of e){if(i.has(n))return n;i.add(n)}return null}const P=new Set(["SUM","COUNT","AVG","MIN","MAX","MEDIAN","DISTINCT"]);function k(e,i,n){if(!e||typeof e!="object"){n.push(a("missing_source","Analytics intent needs a source.",i));return}if(e.kind==="semantic"){d(e.domainId)||n.push(a("missing_semantic_domain","Semantic source needs a domainId.",`${i}.domainId`)),d(e.datasetName)||n.push(a("missing_dataset_name","Semantic source needs a datasetName.",`${i}.datasetName`));return}if(e.kind==="physical"){d(e.connectionId)||n.push(a("missing_connection_id","Physical source needs a connectionId.",`${i}.connectionId`)),d(e.tableName)||n.push(a("missing_table_name","Physical source needs a tableName.",`${i}.tableName`));return}if(e.kind==="sql"){d(e.connectionId)||n.push(a("missing_connection_id","SQL source needs a connectionId.",`${i}.connectionId`));return}n.push(a("invalid_source_kind","Source kind is not supported.",i))}function f(e,i,n,o={}){if(!e||!c(e)){o.required&&n.push(a("missing_field_ref","Field reference needs a name.",i));return}d(e.name)||n.push(a("missing_field_ref","Field reference needs a name.",`${i}.name`)),e.source!==void 0&&k(e.source,`${i}.source`,n),O(e.aggregate,`${i}.aggregate`,n)}function O(e,i,n){e!==void 0&&(typeof e!="string"||!P.has(e))&&n.push(a("invalid_aggregate","Field aggregate must be SUM, COUNT, AVG, MIN, MAX, MEDIAN, or DISTINCT.",i))}function H(e,i){if(e.analysis===void 0)return;if(!c(e.analysis)){i.push(a("invalid_metric_analysis","Metric analysis must be a structured object.","analysis"));return}if(e.analysis.kind!=="period_change"){i.push(a("invalid_metric_analysis","Metric analysis kind is not supported.","analysis.kind"));return}e.dateField||i.push(a("missing_analysis_date_field","Period-change analysis needs a dateField.","dateField")),e.timeGrain||i.push(a("missing_analysis_time_grain","Period-change analysis needs a timeGrain.","timeGrain")),e.analysis.orderBy!==void 0&&e.analysis.orderBy!=="absolute_change"&&e.analysis.orderBy!=="positive_change"&&e.analysis.orderBy!=="negative_change"&&e.analysis.orderBy!=="period"&&i.push(a("invalid_metric_analysis","Period-change analysis orderBy must be absolute_change, positive_change, negative_change, or period.","analysis.orderBy"));const{timeWindow:n}=e.analysis;n!==void 0&&w(n,"analysis.timeWindow",i)}function w(e,i,n){if(!c(e)){n.push(a("invalid_time_window","Time window must be a structured object.",i));return}e.unit!=="second"&&e.unit!=="minute"&&e.unit!=="hour"&&e.unit!=="day"&&e.unit!=="week"&&e.unit!=="month"&&e.unit!=="quarter"&&e.unit!=="year"&&n.push(a("invalid_time_window","Time window unit must be second, minute, hour, day, week, month, quarter, or year.",`${i}.unit`)),(typeof e.value!="number"||!Number.isFinite(e.value)||e.value<=0)&&n.push(a("invalid_time_window","Time window value must be a positive number.",`${i}.value`)),e.anchor!==void 0&&e.anchor!=="now"&&e.anchor!=="latest_available"&&n.push(a("invalid_time_window","Time window anchor must be now or latest_available.",`${i}.anchor`)),e.completeness!==void 0&&e.completeness!=="include_partial"&&e.completeness!=="complete_periods"&&n.push(a("invalid_time_window","Time window completeness must be include_partial or complete_periods.",`${i}.completeness`))}function U(e,i,n){if(e!==void 0){if(!Array.isArray(e)){n.push(a("invalid_analytics_filters","Analytics filters must be an array.",i));return}e.forEach((o,r)=>{const s=`${i}.${r}`;if(!c(o)){n.push(a("invalid_analytics_filter","Analytics filter must be a structured object.",s));return}const t=o;f(t.field,`${s}.field`,n,{required:!0});const p=t.operator==="is_null"||t.operator==="is_not_null";if(t.operator!==void 0&&t.operator!=="="&&t.operator!=="!="&&t.operator!=="in"&&t.operator!=="not_in"&&t.operator!=="contains"&&t.operator!=="not_contains"&&t.operator!=="between"&&t.operator!=="not_between"&&t.operator!==">"&&t.operator!==">="&&t.operator!=="<"&&t.operator!=="<="&&t.operator!=="is_null"&&t.operator!=="is_not_null"&&n.push(a("invalid_analytics_filter_operator","Analytics filter operator is not supported.",`${s}.operator`)),t.values===void 0&&!p&&n.push(a("missing_analytics_filter_value","Analytics filter needs values unless it is a null check.",s)),p&&t.values!==void 0){n.push(a("invalid_analytics_filter_values","Null-check analytics filters must not include values.",`${s}.values`));return}t.values!==void 0&&!Array.isArray(t.values)&&n.push(a("invalid_analytics_filter_values","Analytics filter values must be an array when provided.",`${s}.values`))})}}function v(e){var o;const i=[],n=[];if(!e||typeof e!="object")return{ok:!1,errors:[a("invalid_analytics_intent","Analytics intent must be a structured object.")],warnings:n,repairHints:[{code:"invalid_analytics_intent",recommendedNextStep:"Send one structured analytics intent object with kind, source, and required fields."}]};if(e.version!==void 0&&e.version!==1&&i.push(a("invalid_version","Analytics intent version must be 1.","version")),k(e.source,"source",i),e.kind==="metric"){const r=Array.isArray(e.metrics)?e.metrics.filter(s=>c(s)&&d(s.name)):[];if(!Array.isArray(e.metrics)||e.metrics.length===0?i.push(a("missing_metric","Metric intent needs at least one metric.","metrics")):e.metrics.some(s=>!c(s)||!d(s.name))&&i.push(a("invalid_metric_list","Metric intent metrics must be an array of field references with names.","metrics")),r.forEach((s,t)=>{f(s,`metrics.${t}`,i,{required:!0})}),r.length>0&&!j(r)){const s=r.find((t,p)=>r.some((u,l)=>l!==p&&M(u,t)));s&&i.push(a("duplicate_metric",T(s),"metrics"))}if(c(e.primaryMetric)&&d(e.primaryMetric.name)&&h(e.primaryMetric,r).length>1&&i.push(a("ambiguous_primary_metric","Metric intent primaryMetric must identify exactly one selected metric.","primaryMetric")),e.primaryMetric!==void 0&&(f(e.primaryMetric,"primaryMetric",i,{required:!0}),c(e.primaryMetric)&&d(e.primaryMetric.name)&&r.length>0&&!D(e.primaryMetric,r)&&i.push(a("invalid_primary_metric","Metric intent primaryMetric must match one metric field reference.","primaryMetric"))),e.dimensions!==void 0&&!Array.isArray(e.dimensions)?i.push(a("invalid_metric_dimensions","Metric intent dimensions must be an array of field references.","dimensions")):Array.isArray(e.dimensions)&&e.dimensions.some(s=>!c(s)||!d(s.name))&&i.push(a("invalid_metric_dimensions","Metric intent dimensions must be an array of field references with names.","dimensions")),e.dateField!==void 0&&f(e.dateField,"dateField",i),e.timeWindow!==void 0&&(w(e.timeWindow,"timeWindow",i),e.dateField||i.push(a("missing_time_window_date_field","Metric timeWindow needs a dateField.","dateField"))),U(e.filters,"filters",i),Array.isArray(e.dimensions)&&e.dimensions.forEach((s,t)=>{f(s,`dimensions.${t}`,i)}),e.orderBy!==void 0){if(!c(e.orderBy))i.push(a("invalid_metric_order_by","Metric intent orderBy must be a structured object.","orderBy"));else if(f(e.orderBy.field,"orderBy.field",i,{required:!0}),e.orderBy.direction!=="asc"&&e.orderBy.direction!=="desc"&&i.push(a("invalid_metric_order_direction","Metric intent orderBy direction must be asc or desc.","orderBy.direction")),c(e.orderBy.field)&&d(e.orderBy.field.name)){const s=[...r,...e.timeGrain&&e.dateField&&c(e.dateField)?[e.dateField]:[],...Array.isArray(e.dimensions)?e.dimensions.filter(t=>c(t)&&d(t.name)):[]];s.length>0&&!x(e.orderBy.field,s)&&i.push(a("invalid_metric_order_by","Metric intent orderBy.field must match one selected metric, grouped dateField, or dimension.","orderBy.field"))}}H(e,i)}else e.kind==="records"?(!Array.isArray(e.fields)||e.fields.length===0?i.push(a("missing_record_fields","Records intent needs at least one field.","fields")):e.fields.some(r=>!c(r)||!d(r.name))&&i.push(a("invalid_record_fields","Records intent fields must be field references with names.","fields")),Array.isArray(e.fields)&&e.fields.forEach((r,s)=>{f(r,`fields.${s}`,i)}),e.dateField!==void 0&&f(e.dateField,"dateField",i),e.orderBy!==void 0&&(c(e.orderBy)?(f(e.orderBy.field,"orderBy.field",i,{required:!0}),e.orderBy.direction!=="asc"&&e.orderBy.direction!=="desc"&&i.push(a("invalid_record_order_direction","Records intent orderBy direction must be asc or desc.","orderBy.direction"))):i.push(a("invalid_record_order_by","Records intent orderBy must be a structured object.","orderBy")))):e.kind==="inputOptions"?((!e.field||!d(e.field.name))&&i.push(a("missing_input_options_field","Input options intent needs a field.","field")),f(e.field,"field",i,{required:!0})):e.kind==="sql"?(((o=e.source)==null?void 0:o.kind)!=="sql"&&i.push(a("invalid_sql_source","SQL analytics intent must use a SQL execution source.","source")),d(e.sql)||i.push(a("missing_sql","SQL analytics intent needs SQL text.","sql")),Array.isArray(e.fields)&&e.fields.forEach((r,s)=>{f(r,`fields.${s}`,i)})):i.push(a("invalid_analytics_kind","Analytics kind is not supported.","kind"));return{ok:i.length===0,errors:i,warnings:n,repairHints:L(i)}}function $(e){const i=[],n=[];if(!e||typeof e!="object")return{ok:!1,errors:[a("invalid_operation_intent","Operation intent must be a structured object.")],warnings:n,repairHints:[{code:"invalid_operation_intent",recommendedNextStep:"Send one typed operation intent with version, kind, and required operation fields."}]};if(e.version!==1&&i.push(a("invalid_version","Operation intent version must be 1.","version")),e.kind==="answer_obligations")!Array.isArray(e.obligations)||e.obligations.length===0?i.push(a("missing_obligations","Answer-obligations operation intent needs at least one obligation.","obligations")):e.obligations.forEach((o,r)=>{d(o.id)||i.push(a("missing_obligation_id","Each analytics obligation needs an id.",`obligations.${r}.id`)),d(o.prompt)||i.push(a("missing_obligation_prompt","Each analytics obligation needs a prompt.",`obligations.${r}.prompt`))});else if(e.kind==="dashboard_change"||e.kind==="data_app_change"){if(d(e.instruction)||i.push(a("missing_instruction","Change operation intent needs an instruction.","instruction")),e.analyticsIntent){const o=v(e.analyticsIntent);i.push(...o.errors),n.push(...o.warnings)}}else i.push(a("invalid_operation_kind","Operation intent kind is not supported.","kind"));return{ok:i.length===0,errors:i,warnings:n,repairHints:N(i)}}function G(e){const i=[],n=[];if(!e||typeof e!="object")return{ok:!1,errors:[a("invalid_recovery_plan","Analytics recovery plan must be a structured object.")],warnings:n,repairHints:[{code:"invalid_recovery_plan",recommendedNextStep:"Return a typed recovery plan with operationIntent and plannedToolCalls."}]};e.version!==1&&i.push(a("invalid_version","Recovery plan version must be 1.","version")),e.kind!=="analytics_recovery_plan"&&i.push(a("invalid_recovery_plan_kind","Recovery plan kind must be analytics_recovery_plan.","kind"));const o=$(e.operationIntent);return i.push(...o.errors),n.push(...o.warnings),Array.isArray(e.plannedToolCalls)||i.push(a("invalid_planned_tool_calls","Recovery plan plannedToolCalls must be an array.","plannedToolCalls")),{ok:i.length===0,errors:i,warnings:n,repairHints:N(i)}}function N(e){return e.map(i=>({code:i.code,recommendedNextStep:i.code==="missing_obligations"?"Normalize the user request into one or more typed analytics obligations before recovery planning.":"Correct the operation/recovery contract shape before planning execution."}))}function L(e){return e.map(i=>{switch(i.code){case"missing_source":return{code:i.code,fieldRole:"source",recommendedNextStep:"Provide a semantic, physical, or SQL source before executing analytics."};case"missing_metric":return{code:i.code,fieldRole:"metric",recommendedNextStep:"Choose one exact metric from the grounded schema candidates."};case"missing_record_fields":return{code:i.code,fieldRole:"dimension",recommendedNextStep:"Provide at least one field for the records intent."};case"missing_input_options_field":return{code:i.code,fieldRole:"input",recommendedNextStep:"Provide the exact field whose option values should be listed."};case"missing_sql":return{code:i.code,fieldRole:"sql",recommendedNextStep:"Provide bounded read-only SQL with an explicit outer LIMIT."};case"conflicting_sql":return{code:i.code,fieldRole:"sql",recommendedNextStep:"Use one canonical SQL text location for the intent; prefer top-level sql."};case"missing_semantic_domain":case"missing_dataset_name":case"missing_connection_id":case"missing_table_name":return{code:i.code,fieldRole:"source",recommendedNextStep:"Use grounded catalog metadata to fill the missing source reference."};default:return}}).filter(i=>!!i)}function Q(e,i,n,o){if(!e||typeof e!="object"){n.push(a("invalid_view","Dashboard view must be an object.",i));return}if(d(e.title)||n.push(a("missing_view_title","Dashboard view needs a title.",i)),!e.presentation||typeof e.presentation!="object"){n.push(a("missing_presentation","Dashboard view needs a presentation.",`${i}.presentation`));return}if(e.presentation.kind==="text"){d(e.text)||o.push(a("missing_text_content","Text views should include text content.",`${i}.text`));return}if(!e.analytics){n.push(a("missing_view_analytics","Non-text dashboard views need analytics intent.",`${i}.analytics`));return}const r=v(e.analytics);for(const s of r.errors)n.push(a(s.code,s.message,`${i}.analytics${s.path?`.${s.path}`:""}`));for(const s of r.warnings)o.push(a(s.code,s.message,`${i}.analytics${s.path?`.${s.path}`:""}`))}function V(e){const i=[],n=[];if(!e||typeof e!="object")return{ok:!1,errors:[a("invalid_dashboard_intent","Dashboard intent must be a structured object.")],warnings:n};e.version!==1&&i.push(a("invalid_version","Dashboard intent version must be 1.")),e.kind!=="dashboard"&&i.push(a("invalid_kind","Experience intent kind must be dashboard.")),d(e.title)||i.push(a("missing_title","Dashboard intent needs a title.","title"));const o=Array.isArray(e.inputs)?e.inputs:[],r=g(o.filter(c).map(u=>u.id).filter(u=>typeof u=="string"));r&&i.push(a("duplicate_input_id",`Duplicate input id: ${r}.`,"inputs"));for(const[u,l]of o.entries()){const m=`inputs.${u}`;if(!c(l)){i.push(a("invalid_input","Dashboard input must be an object.",m));continue}d(l.id)||i.push(a("missing_input_id","Input needs an id.",`${m}.id`)),d(l.label)||i.push(a("missing_input_label","Input needs a label.",`${m}.label`)),!l.field||!d(l.field.name)?i.push(a("missing_input_field","Input needs a field.",`${m}.field`)):f(l.field,`${m}.field`,i)}const s=Array.isArray(e.sections)?e.sections:[];s.length===0&&i.push(a("missing_sections","Dashboard intent needs at least one section.","sections"));const t=s.flatMap(u=>u&&typeof u=="object"&&Array.isArray(u.views)?u.views.filter(c).map(l=>l.id).filter(l=>!!l):[]),p=g(t);p&&i.push(a("duplicate_view_id",`Duplicate dashboard view id: ${p}.`,"sections"));for(const[u,l]of s.entries()){const m=`sections.${u}`;if(!l||typeof l!="object"){i.push(a("invalid_section","Dashboard section must be an object.",m));continue}if(d(l.title)||i.push(a("missing_section_title","Dashboard section needs a title.",m)),!Array.isArray(l.views)||l.views.length===0){i.push(a("missing_section_views","Dashboard section needs at least one view.",`${m}.views`));continue}for(const[R,B]of l.views.entries())Q(B,`${m}.views.${R}`,i,n)}return{ok:i.length===0,errors:i,warnings:n}}exports.preferSemaphorFieldRefMetadata=F;exports.preferSemaphorSourceMetadata=A;exports.semaphorFieldRefsMatch=I;exports.semaphorSourceIdentityKey=_;exports.semaphorSourcesReferToSameDataset=b;exports.validateSemaphorAnalyticsIntent=v;exports.validateSemaphorAnalyticsRecoveryPlan=G;exports.validateSemaphorDashboardIntent=V;exports.validateSemaphorOperationIntent=$;