import { n as T, v as x } from "./validators-CVuWOHYv.js";
import { b as S, c as H, a as b } from "./source-identity-Dj3dryN9.js";
function w(e) {
  var t;
  const r = B(e);
  return {
    version: 1,
    kind: "metric",
    id: e.id,
    label: e.label,
    source: h(e),
    metrics: r,
    primaryMetric: z(e, r),
    dateField: e.dateField ? a(e.dateField, "date") : void 0,
    timeGrain: e.timeGrain,
    dimensions: (t = e.dimensions) == null ? void 0 : t.map((o) => a(o, "dimension")),
    comparison: X(e.comparison),
    orderBy: e.orderBy ? {
      field: a(e.orderBy.field),
      direction: e.orderBy.direction
    } : void 0,
    inputs: m(e.inputs),
    limit: e.limit
  };
}
function F(e) {
  var t;
  return {
    ...w(e),
    ...e.timeWindow ? { timeWindow: e.timeWindow } : {},
    ...(t = e.filters) != null && t.length ? { filters: e.filters } : {},
    ...e.analysis ? { analysis: e.analysis } : {}
  };
}
function ge(e) {
  return {
    ...e.chartTitle ? { chartTitle: e.chartTitle } : {},
    ...e.chartType ? { chartType: e.chartType } : {},
    ...e.driverMode ? { driverMode: e.driverMode } : {},
    ...e.includePopulation !== void 0 ? { includePopulation: e.includePopulation } : {},
    ...e.calendarContext ? { calendarContext: e.calendarContext } : {}
  };
}
function z(e, r) {
  if (!e.primaryMetric)
    return r[0] || { name: "", role: "measure" };
  const t = a(e.primaryMetric, "measure"), o = K(t, r), i = o.length === 1 ? o[0] : void 0;
  return i ? A(t, i) : t;
}
function B(e) {
  const r = [];
  for (const t of e.metrics.map(
    (o) => a(o, "measure")
  )) {
    if (!t.name)
      continue;
    const o = r.findIndex(
      (i) => O(i, t)
    );
    if (o === -1) {
      r.push(t);
      continue;
    }
    r[o] = A(
      r[o],
      t
    );
  }
  return r;
}
function O(e, r) {
  return S(e, r) && f(e) === f(r);
}
function D(e, r) {
  return f(r) === f(e);
}
function j(e, r) {
  return r.name !== e.name || e.source && !S(r, e) ? !1 : D(e, r);
}
function K(e, r) {
  const t = r.filter(
    (o) => j(e, o)
  );
  return e.aggregate !== void 0, t;
}
function f(e) {
  return (e.aggregate || "SUM").toUpperCase();
}
function A(e, r) {
  if (e.aggregate && r.aggregate && e.aggregate !== r.aggregate)
    throw new Error(
      `Metric "${e.name}" was requested with conflicting aggregate semantics: ${e.aggregate} and ${r.aggregate}.`
    );
  return {
    ...H(e, r),
    aggregate: e.aggregate || r.aggregate
  };
}
function Q(e) {
  var t;
  if ("sort" in e)
    throw new Error(
      "semaphor.records supports orderBy for a single deterministic sort. Multiple sort clauses are not supported by the analytics protocol yet."
    );
  if (!J(e))
    throw new Error("semaphor.records needs at least one field.");
  const r = E(e.fields);
  return {
    version: 1,
    kind: "records",
    id: e.id,
    label: e.label,
    source: h(e),
    fields: r,
    dateField: e.dateField ? a(e.dateField, "date") : void 0,
    timeGrain: e.timeGrain,
    ...e.timeWindow ? { timeWindow: e.timeWindow } : {},
    ...(t = e.filters) != null && t.length ? { filters: e.filters } : {},
    orderBy: e.orderBy ? {
      field: a(e.orderBy.field),
      direction: e.orderBy.direction
    } : void 0,
    inputs: m(e.inputs),
    limit: e.limit,
    ...e.pagination ? { pagination: e.pagination } : {}
  };
}
function E(e) {
  return e.map((r) => {
    const t = a(r);
    if (!t.role)
      throw new Error(
        `semaphor.records field "${t.name}" needs an explicit role.`
      );
    return t;
  });
}
function N(e) {
  return {
    version: 1,
    kind: "inputOptions",
    id: e.id,
    label: e.label,
    source: h(e),
    field: a(e.field, "dimension"),
    search: e.search,
    limit: e.limit
  };
}
function W(e) {
  var r;
  return {
    version: 1,
    kind: "sql",
    id: e.id,
    label: e.label,
    source: e.source,
    sql: e.sql,
    ...e.defaultParameters ? { defaultParameters: e.defaultParameters } : {},
    ...e.pythonCode ? { pythonCode: e.pythonCode } : {},
    ...(r = e.fields) != null && r.length ? { fields: e.fields.map((t) => a(t)) } : {},
    inputs: m(e.inputs),
    limit: e.limit,
    ...e.pagination ? { pagination: e.pagination } : {},
    rationale: e.rationale
  };
}
function U(e) {
  if ("toAnalyticsInput" in e) {
    const n = e.toAnalyticsInput();
    return {
      inputId: n.inputId,
      kind: n.kind,
      ...n.controlRole ? { controlRole: n.controlRole } : {},
      ...n.operator ? { operator: n.operator } : {},
      ...n.field ? { field: n.field } : {}
    };
  }
  if ("id" in e) {
    const n = M(e);
    return {
      inputId: n.inputId,
      kind: n.kind,
      ...n.controlRole ? { controlRole: n.controlRole } : {},
      ...n.operator ? { operator: n.operator } : {},
      ...n.field ? { field: n.field } : {}
    };
  }
  const r = "kind" in e ? e.kind : void 0, t = "operator" in e ? _(e.operator, e.inputId) : void 0, o = "controlRole" in e ? e.controlRole : "role" in e ? e.role : void 0, i = V(o) ? o : void 0;
  return {
    inputId: e.inputId,
    ...r ? { kind: r } : {},
    ...i ? { controlRole: i } : {},
    ...t ? { operator: t } : {},
    ...e.field ? { field: e.field } : {}
  };
}
function V(e) {
  return e === "grain" || e === "metric" || e === "dimension" || e === "aggregation" || e === "sqlParam";
}
function ve(e) {
  const r = m(e);
  return r.length > 0 ? r : void 0;
}
function G(e) {
  return (e || []).map(L);
}
function qe(e) {
  return G(e).filter((r) => r.isActive);
}
function M(e) {
  if (e.kind === "filter") {
    const r = _(e.operator, e.id);
    return {
      inputId: e.id,
      kind: e.kind,
      label: e.label,
      field: a(e.field, "dimension"),
      operator: r || "in"
    };
  }
  return {
    inputId: e.id,
    kind: e.kind,
    label: e.label,
    controlRole: e.role
  };
}
function Ie(e = []) {
  return e.map(
    (r) => typeof r == "object" ? r : {
      label: String(r),
      value: r
    }
  );
}
function g(e) {
  return e == null ? !1 : Array.isArray(e) ? e.length > 0 : typeof e == "string" ? e.trim().length > 0 : !0;
}
function L(e) {
  if ("toAnalyticsInput" in e)
    return e.toAnalyticsInput();
  if ("kind" in e && "isActive" in e)
    return e;
  if ("id" in e) {
    const r = M(e), t = Object.prototype.hasOwnProperty.call(e, "value") ? e.value : e.defaultValue;
    return {
      inputId: r.inputId,
      kind: r.kind,
      label: r.label,
      ...r.field ? { field: r.field } : {},
      ...r.operator ? { operator: r.operator } : {},
      ...r.controlRole ? { controlRole: r.controlRole } : {},
      value: t,
      isActive: g(t)
    };
  }
  return {
    ...e,
    kind: "filter",
    isActive: g(
      e.value
    ),
    value: e.value
  };
}
function h(e) {
  return e.source;
}
function J(e) {
  var r;
  return !!((r = e.fields) != null && r.length);
}
function a(e, r) {
  return {
    ...e,
    role: e.role || r
  };
}
function m(e) {
  return (e || []).map(U);
}
function X(e) {
  if (e)
    return e;
}
function _(e, r) {
  if (e === void 0)
    return;
  const t = T(e);
  if (!t)
    throw new Error(
      `useSemaphorInput "${r}" uses unsupported filter operator "${e}".`
    );
  return t;
}
function Y(e, r = {}) {
  const t = r.pathPrefix || "analysisOptions";
  if (e === void 0)
    return { ok: !0 };
  if (!e || typeof e != "object" || Array.isArray(e))
    return s(
      t,
      "Data App analysis options must be an object."
    );
  const o = e, i = {};
  if (o.chartTitle !== void 0) {
    if (typeof o.chartTitle != "string")
      return s(
        `${t}.chartTitle`,
        'Data App analysis option "chartTitle" must be a string.'
      );
    i.chartTitle = o.chartTitle;
  }
  if (o.chartType !== void 0) {
    if (typeof o.chartType != "string")
      return s(
        `${t}.chartType`,
        'Data App analysis option "chartType" must be a string.'
      );
    i.chartType = o.chartType;
  }
  if (o.driverMode !== void 0) {
    if (!ee(o.driverMode))
      return s(
        `${t}.driverMode`,
        'Data App analysis option "driverMode" must be absolute_delta, largest_negative, largest_positive, positive_and_negative, or all.'
      );
    i.driverMode = o.driverMode;
  }
  if (o.includePopulation !== void 0) {
    if (typeof o.includePopulation != "boolean")
      return s(
        `${t}.includePopulation`,
        'Data App analysis option "includePopulation" must be a boolean.'
      );
    i.includePopulation = o.includePopulation;
  }
  if (o.calendarContext !== void 0) {
    const n = te(
      o.calendarContext,
      {
        pathPrefix: `${t}.calendarContext`,
        validateTimezone: r.validateTimezone
      }
    );
    if (!n.ok)
      return n;
    i.calendarContext = n.calendarContext;
  }
  return { ok: !0, analysisOptions: i };
}
function ke(e) {
  const r = e.queries.map(
    (i, n) => Z(i, n, {
      fieldCatalogs: e.fieldCatalogs || [],
      requireFieldCatalog: !!e.requireFieldCatalog,
      validateTimezone: e.validateTimezone
    })
  ), t = r.flatMap((i) => i.diagnostics), o = r.map((i) => i.executionResult);
  return {
    ok: t.every((i) => i.severity !== "error"),
    diagnostics: t,
    queries: r,
    intents: r.flatMap(
      (i) => i.intent ? [i.intent] : []
    ),
    executionResults: o
  };
}
function Z(e, r, t) {
  const o = `queries.${r}`;
  try {
    const i = ie(e), n = ye(e, i), d = x(i), l = [
      ...le({
        querySpec: e,
        queryId: n,
        intent: i,
        pathPrefix: o
      }),
      ...d.errors.map(
        (y) => v(y, {
          queryHook: e.queryHook,
          queryId: n,
          pathPrefix: o,
          severity: "error",
          intent: i
        })
      ),
      ...d.warnings.map(
        (y) => v(y, {
          queryHook: e.queryHook,
          queryId: n,
          pathPrefix: o,
          severity: "warning",
          intent: i
        })
      ),
      ...ne({
        querySpec: e,
        queryId: n,
        intent: i,
        pathPrefix: o,
        fieldCatalogs: t.fieldCatalogs,
        requireFieldCatalog: t.requireFieldCatalog
      }),
      ...de({
        querySpec: e,
        queryId: n,
        intent: i,
        pathPrefix: o,
        validateTimezone: t.validateTimezone
      })
    ], u = me(d, l);
    return {
      queryHook: e.queryHook,
      queryId: n,
      intent: i,
      diagnostics: l,
      executionResult: k({
        intent: i,
        validation: u,
        diagnostics: l
      })
    };
  } catch (i) {
    const n = {
      severity: "error",
      code: "invalid_query_spec",
      message: i instanceof Error ? i.message : String(i),
      path: o,
      queryHook: e.queryHook,
      queryId: P(e.spec)
    }, d = R([n]);
    return {
      queryHook: e.queryHook,
      queryId: n.queryId,
      diagnostics: [n],
      executionResult: k({
        validation: d,
        diagnostics: [n]
      })
    };
  }
}
function s(e, r) {
  return {
    ok: !1,
    issues: [
      {
        code: "invalid_analysis_option",
        message: r,
        path: e
      }
    ]
  };
}
function C(e) {
  return !!(e && typeof e == "object" && !Array.isArray(e));
}
function ee(e) {
  return e === "absolute_delta" || e === "largest_negative" || e === "largest_positive" || e === "positive_and_negative" || e === "all";
}
function re(e) {
  return e.trim().length > 0 && !Number.isNaN(Date.parse(e));
}
function te(e, r) {
  var u;
  if (!e || typeof e != "object" || Array.isArray(e))
    return s(
      r.pathPrefix,
      'Data App analysis option "calendarContext" must be an object.'
    );
  const t = e, o = t.tz, i = t.weekStart, n = t.anchor, d = n && typeof n == "object" && !Array.isArray(n) ? n.iso : void 0, l = typeof o == "string" ? ((u = r.validateTimezone) == null ? void 0 : u.call(r, o)) ?? o : null;
  return l ? typeof i != "number" || !Number.isInteger(i) || i < 0 || i > 6 ? s(
    `${r.pathPrefix}.weekStart`,
    'Data App analysis option "calendarContext.weekStart" must be an integer from 0 to 6.'
  ) : n !== "now" && !(typeof d == "string" && re(d)) ? s(
    `${r.pathPrefix}.anchor`,
    'Data App analysis option "calendarContext.anchor" must be "now" or an object with a valid iso string.'
  ) : {
    ok: !0,
    calendarContext: {
      tz: l,
      weekStart: i,
      anchor: n
    }
  } : s(
    `${r.pathPrefix}.tz`,
    'Data App analysis option "calendarContext.tz" must be a valid timezone string.'
  );
}
function ie(e) {
  return oe(e.spec);
}
function oe(e) {
  if (!C(e))
    throw new Error("useSemaphorQuery spec must be an object.");
  if (e.queryKind === "metric")
    return w(e);
  if (e.queryKind === "analysis")
    return F(e);
  if (e.queryKind === "records")
    return Q(e);
  if (e.queryKind === "sql")
    return W(e);
  if (e.queryKind === "inputOptions")
    return N(e);
  throw new Error(
    "useSemaphorQuery spec.queryKind must be metric, analysis, records, inputOptions, or sql."
  );
}
function ne(e) {
  if (e.intent.kind === "sql")
    return [];
  if (e.fieldCatalogs.length === 0 && !e.requireFieldCatalog)
    return [];
  const r = fe(
    e.fieldCatalogs,
    e.intent.source
  );
  return r ? [
    ...ae({
      ...e,
      catalog: r
    }),
    ...se({
      ...e,
      catalog: r
    })
  ] : [
    {
      severity: "error",
      code: "invalid_source_ref",
      message: `Source ref for ${e.querySpec.queryHook} does not match a visible Semaphor source.`,
      path: `${e.pathPrefix}.spec.source`,
      queryHook: e.querySpec.queryHook,
      queryId: e.queryId,
      intentId: e.intent.id,
      source: e.intent.source
    }
  ];
}
function ae(e) {
  return ue(e.intent).flatMap(({ field: r, path: t }) => $(e.catalog, r, e.intent.source) ? [] : [
    {
      severity: "error",
      code: "missing_field",
      message: `Field "${r.name}" is not visible on the selected Semaphor source.`,
      path: `${e.pathPrefix}.${t}`,
      queryHook: e.querySpec.queryHook,
      queryId: e.queryId,
      intentId: e.intent.id,
      source: c(r, e.intent.source),
      field: r
    }
  ]);
}
function se(e) {
  return ("inputs" in e.intent ? e.intent.inputs || [] : []).flatMap((t, o) => {
    if (!t.field)
      return [];
    const i = c(t.field, e.intent.source);
    return b(i, e.intent.source) ? $(e.catalog, t.field, e.intent.source) ? [] : [
      {
        severity: "error",
        code: "missing_field",
        message: `Input "${t.inputId}" references field "${t.field.name}", which is not visible on the selected Semaphor source.`,
        path: `${e.pathPrefix}.spec.inputs.${o}.field`,
        queryHook: e.querySpec.queryHook,
        queryId: e.queryId,
        intentId: e.intent.id,
        source: i,
        field: t.field
      }
    ] : [
      {
        severity: "error",
        code: "unsupported_input_filter_composition",
        message: `Input "${t.inputId}" filters a different Semaphor source than the query. Cross-source Data App inputs are not supported yet.`,
        path: `${e.pathPrefix}.spec.inputs.${o}.field`,
        queryHook: e.querySpec.queryHook,
        queryId: e.queryId,
        intentId: e.intent.id,
        source: i,
        field: t.field
      }
    ];
  });
}
function de(e) {
  if (e.querySpec.spec.queryKind !== "analysis")
    return [];
  const r = Y(
    e.querySpec.spec,
    {
      pathPrefix: `${e.pathPrefix}.spec`,
      validateTimezone: e.validateTimezone
    }
  );
  return r.ok ? [] : r.issues.map((t) => ({
    severity: "error",
    code: t.code,
    message: t.message,
    path: t.path,
    queryHook: e.querySpec.queryHook,
    queryId: e.queryId,
    intentId: e.intent.id,
    source: e.intent.source
  }));
}
function le(e) {
  return e.querySpec.spec.queryKind !== "sql" ? [] : C(e.querySpec.spec) ? Object.prototype.hasOwnProperty.call(e.querySpec.spec, "parameters") ? [
    {
      severity: "error",
      code: "deprecated_sql_parameters",
      message: "semaphor.sql uses defaultParameters for static SQL param(...) fallback values. The legacy parameters field is not supported.",
      path: `${e.pathPrefix}.spec.parameters`,
      queryHook: e.querySpec.queryHook,
      queryId: e.queryId,
      intentId: e.intent.id
    }
  ] : [] : [];
}
function ue(e) {
  return e.kind === "metric" ? [
    ...e.metrics.map((r, t) => ({
      field: r,
      path: `spec.metrics.${t}`
    })),
    ...e.primaryMetric ? [{ field: e.primaryMetric, path: "spec.primaryMetric" }] : [],
    ...e.dateField ? [{ field: e.dateField, path: "spec.dateField" }] : [],
    ...(e.dimensions || []).map((r, t) => ({
      field: r,
      path: `spec.dimensions.${t}`
    })),
    ...e.orderBy ? [{ field: e.orderBy.field, path: "spec.orderBy.field" }] : [],
    ...(e.filters || []).map((r, t) => ({
      field: r.field,
      path: `spec.filters.${t}.field`
    }))
  ] : e.kind === "records" ? [
    ...e.fields.map((r, t) => ({
      field: r,
      path: `spec.fields.${t}`
    })),
    ...e.dateField ? [{ field: e.dateField, path: "spec.dateField" }] : [],
    ...e.orderBy ? [{ field: e.orderBy.field, path: "spec.orderBy.field" }] : [],
    ...(e.filters || []).map((r, t) => ({
      field: r.field,
      path: `spec.filters.${t}.field`
    }))
  ] : e.kind === "inputOptions" ? [{ field: e.field, path: "spec.field" }] : [];
}
function fe(e, r) {
  return e.find((t) => p(t, r));
}
function $(e, r, t) {
  const o = c(r, t);
  if (p(e, o))
    return e.fields.find(
      (i) => ce(i, r) && p(
        e,
        c(i, e.source)
      )
    );
}
function p(e, r) {
  return [e.source, ...e.sourceAliases || []].some(
    (t) => b(t, r)
  );
}
function c(e, r) {
  return e.source || r;
}
function ce(e, r) {
  return !!(e.name && r.name && e.name === r.name);
}
function v(e, r) {
  return {
    severity: r.severity,
    code: e.code || "invalid_analytics_intent",
    message: e.message,
    path: e.path ? `${r.pathPrefix}.spec.${e.path}` : r.pathPrefix,
    queryHook: r.queryHook,
    queryId: r.queryId,
    intentId: r.intent.id,
    source: r.intent.source
  };
}
function me(e, r) {
  const t = R(r);
  return {
    ok: t.ok && e.ok,
    errors: I([
      ...e.errors,
      ...t.errors
    ]),
    warnings: I([
      ...e.warnings,
      ...t.warnings
    ]),
    repairHints: [
      ...e.repairHints,
      ...t.repairHints
    ]
  };
}
function R(e) {
  const r = e.filter((o) => o.severity === "error").map(q), t = e.filter((o) => o.severity === "warning").map(q);
  return {
    ok: r.length === 0,
    errors: r,
    warnings: t,
    repairHints: r.map((o) => {
      var i, n;
      return {
        code: o.code,
        message: o.message,
        fieldRole: o.fieldRole,
        invalidField: (i = o.repairHint) == null ? void 0 : i.invalidField,
        recommendedNextStep: ((n = o.repairHint) == null ? void 0 : n.recommendedNextStep) || "Update the Data App SDK query spec to use visible Semaphor source and field refs."
      };
    })
  };
}
function q(e) {
  var r;
  return {
    code: e.code,
    message: e.message,
    path: e.path,
    fieldRole: e.code === "invalid_source_ref" ? "source" : void 0,
    repairHint: {
      code: e.code,
      message: e.message,
      invalidField: (r = e.field) == null ? void 0 : r.name,
      fieldRole: e.code === "invalid_source_ref" ? "source" : void 0,
      recommendedNextStep: e.code === "unsupported_input_filter_composition" ? "Use an input field from the same Semaphor source as the query, or split the query into separate source-scoped queries." : "Update the query spec to use a visible Semaphor source and field ref."
    }
  };
}
function I(e) {
  const r = /* @__PURE__ */ new Set();
  return e.filter((t) => {
    const o = `${t.code}:${t.path || ""}:${t.message}`;
    return r.has(o) ? !1 : (r.add(o), !0);
  });
}
function k(e) {
  var t, o;
  const r = e.diagnostics.filter(
    (i) => i.severity === "error"
  );
  return {
    intentId: (t = e.intent) == null ? void 0 : t.id,
    status: r.length ? "failed" : "answered",
    resultShape: (o = e.intent) == null ? void 0 : o.kind,
    intent: e.intent,
    validation: e.validation,
    coverage: {
      answeredObligations: r.length ? [] : ["query_spec_validation"],
      missingObligations: r.length ? ["query_spec_validation"] : [],
      warnings: e.validation.warnings
    },
    missingFields: r.filter((i) => i.code === "missing_field").flatMap(
      (i) => {
        var n;
        return (n = i.field) != null && n.name ? [i.field.name] : [];
      }
    ),
    warnings: e.diagnostics.filter((i) => i.severity === "warning").map((i) => i.message),
    metadata: {
      validationKind: "data_app_sdk_query_spec"
    }
  };
}
function ye(e, r) {
  return r.id || P(e.spec);
}
function P(e) {
  if (!e || typeof e != "object" || !("id" in e))
    return;
  const r = e.id;
  return typeof r == "string" && r.trim() ? r : void 0;
}
export {
  W as a,
  N as b,
  Q as c,
  ge as d,
  F as e,
  w as f,
  M as g,
  g as h,
  U as i,
  ve as j,
  G as k,
  Y as l,
  Ie as n,
  qe as t,
  ke as v
};
