import "./chunk-7D4SUZUM.js";

// src/http-auth/auth-method.ts
import { Schema } from "effect";
var TOKEN_VARIABLE = "token";
var AuthCarrier = Schema.Literals(["header", "query"]);
var AuthPlacement = Schema.Struct({
  carrier: AuthCarrier,
  /** Header name (e.g. `Authorization`) or query-param name (e.g. `token`). */
  name: Schema.String,
  /** Literal prepended to the credential value, e.g. `Bearer `. */
  prefix: Schema.optional(Schema.String),
  /** The credential input this placement renders from. Absent ⇒ `token`. */
  variable: Schema.optional(Schema.String),
  /** Render this exact value instead of a credential. */
  literal: Schema.optional(Schema.String)
});
var ApiKeyAuthMethod = Schema.Struct({
  slug: Schema.String,
  kind: Schema.Literal("apikey"),
  /** Display label; derived from the first placement when absent. */
  label: Schema.optional(Schema.String),
  placements: Schema.Array(AuthPlacement)
});
var NoneAuthMethod = Schema.Struct({
  slug: Schema.String,
  kind: Schema.Literal("none")
});
var renderPlacementValue = (placement, values) => {
  if (placement.literal !== void 0) return placement.literal;
  const value = values[placement.variable ?? TOKEN_VARIABLE];
  if (value == null) return null;
  return placement.prefix ? `${placement.prefix}${value}` : value;
};
var renderAuthPlacements = (placements, values) => {
  const headers = {};
  const queryParams = {};
  for (const placement of placements) {
    const rendered = renderPlacementValue(placement, values);
    if (rendered === null) continue;
    if (placement.carrier === "header") headers[placement.name] = rendered;
    else queryParams[placement.name] = rendered;
  }
  return { headers, queryParams };
};
var requiredPlacementVariables = (placements) => {
  const names = /* @__PURE__ */ new Set();
  for (const placement of placements) {
    if (placement.literal !== void 0) continue;
    names.add(placement.variable ?? TOKEN_VARIABLE);
  }
  return [...names];
};
var oauthBearerPlacement = (header, prefix) => ({
  carrier: "header",
  name: header ?? "Authorization",
  prefix: prefix ?? "Bearer "
});
var normalizeAuthMethodSlugs = (methods, defaultSlugFor) => {
  const taken = /* @__PURE__ */ new Set();
  return methods.map((method) => {
    const requested = method.slug?.trim() || defaultSlugFor(method);
    let slug = requested;
    for (let n = 2; taken.has(slug); n += 1) slug = `${requested}_${n}`;
    taken.add(slug);
    return { ...method, slug };
  });
};
var apiKeyMethodLabel = (method) => {
  if (method.label !== void 0 && method.label.trim().length > 0) return method.label;
  const first = method.placements.find(
    (placement) => placement.name.trim().length > 0
  );
  return first ? `API key (${first.name})` : `API key (${method.slug})`;
};
var describePlacement = (placement) => ({
  carrier: placement.carrier,
  name: placement.name,
  prefix: placement.prefix ?? "",
  ...placement.variable !== void 0 ? { variable: placement.variable } : {},
  ...placement.literal !== void 0 ? { literal: placement.literal } : {}
});
var describeApiKeyAuthMethod = (method) => ({
  id: method.slug,
  label: apiKeyMethodLabel(method),
  kind: "apikey",
  template: method.slug,
  placements: method.placements.map(describePlacement)
});
var describeNoneAuthMethod = (slug) => ({
  id: slug,
  label: "No authentication",
  kind: "none",
  template: slug
});

// src/http-auth/authoring.ts
import { Schema as Schema2 } from "effect";
var variable = (name) => ({ type: "variable", name });
var VariablePart = Schema2.Struct({
  type: Schema2.Literal("variable"),
  name: Schema2.String
});
var isVariablePart = (part) => typeof part !== "string";
var AuthTemplateValue = Schema2.Union([
  Schema2.String,
  Schema2.Array(Schema2.Union([Schema2.String, VariablePart])).check(
    Schema2.makeFilter((parts) => {
      const variableIndexes = parts.flatMap((part, index) => isVariablePart(part) ? [index] : []);
      if (variableIndexes.length > 1 || variableIndexes.length === 1 && variableIndexes[0] !== parts.length - 1) {
        return "a template value renders at most ONE variable, as the FINAL part \u2014 split extra variables/suffixes into separate header or query entries";
      }
      return void 0;
    })
  )
]);
var ApiKeyAuthTemplate = Schema2.Struct({
  slug: Schema2.optional(Schema2.String),
  type: Schema2.Literal("apiKey"),
  label: Schema2.optional(Schema2.String),
  headers: Schema2.optional(Schema2.Record(Schema2.String, AuthTemplateValue)),
  queryParams: Schema2.optional(Schema2.Record(Schema2.String, AuthTemplateValue))
});
var placementFromValue = (carrier, name, value) => {
  if (typeof value === "string") return { carrier, name, literal: value };
  const variablePart = value.find(isVariablePart);
  if (variablePart === void 0) {
    return { carrier, name, literal: value.filter((p) => typeof p === "string").join("") };
  }
  const prefix = value.filter((part) => typeof part === "string").join("");
  return {
    carrier,
    name,
    ...prefix ? { prefix } : {},
    ...variablePart.name !== TOKEN_VARIABLE ? { variable: variablePart.name } : {}
  };
};
var apiKeyMethodFromAuthTemplate = (template) => {
  const placements = [];
  for (const [name, value] of Object.entries(template.headers ?? {})) {
    placements.push(placementFromValue("header", name, value));
  }
  for (const [name, value] of Object.entries(template.queryParams ?? {})) {
    placements.push(placementFromValue("query", name, value));
  }
  return {
    ...template.slug !== void 0 ? { slug: template.slug } : {},
    kind: "apikey",
    ...template.label !== void 0 ? { label: template.label } : {},
    placements
  };
};
var apiKeyAuthTemplateFromMethod = (method) => {
  const headers = {};
  const queryParams = {};
  for (const placement of method.placements) {
    const target = placement.carrier === "header" ? headers : queryParams;
    target[placement.name] = placement.literal !== void 0 ? placement.literal : placement.prefix ? [placement.prefix, variable(placement.variable ?? TOKEN_VARIABLE)] : [variable(placement.variable ?? TOKEN_VARIABLE)];
  }
  return {
    ...method.slug !== void 0 ? { slug: method.slug } : {},
    type: "apiKey",
    ...method.label !== void 0 ? { label: method.label } : {},
    ...Object.keys(headers).length > 0 ? { headers } : {},
    ...Object.keys(queryParams).length > 0 ? { queryParams } : {}
  };
};
var isApiKeyAuthTemplate = (input) => input.type === "apiKey";

// src/http-auth/legacy.ts
import { Schema as Schema3 } from "effect";
var LegacyVariablePart = Schema3.Struct({
  type: Schema3.Literal("variable"),
  name: Schema3.String
});
var LegacyTemplateValue = Schema3.Union([
  Schema3.String,
  Schema3.Array(Schema3.Union([Schema3.String, LegacyVariablePart]))
]);
var LegacyApiKeyTemplate = Schema3.Struct({
  slug: Schema3.String,
  type: Schema3.Literal("apiKey"),
  headers: Schema3.optional(Schema3.Record(Schema3.String, LegacyTemplateValue)),
  queryParams: Schema3.optional(Schema3.Record(Schema3.String, LegacyTemplateValue))
});
var decodeLegacyApiKeyTemplate = Schema3.decodeUnknownOption(LegacyApiKeyTemplate);
var placementFromTemplateValue = (carrier, name, value) => {
  if (typeof value === "string") return { carrier, name, literal: value };
  const literals = [];
  for (const part of value) {
    if (typeof part === "string") {
      literals.push(part);
      continue;
    }
    const prefix = literals.join("");
    return {
      carrier,
      name,
      ...prefix ? { prefix } : {},
      ...part.name !== TOKEN_VARIABLE ? { variable: part.name } : {}
    };
  }
  return { carrier, name, literal: literals.join("") };
};
var apiKeyMethodFromLegacyTemplate = (template) => {
  const placements = [];
  for (const [name, value] of Object.entries(template.headers ?? {})) {
    placements.push(placementFromTemplateValue("header", name, value));
  }
  for (const [name, value] of Object.entries(template.queryParams ?? {})) {
    placements.push(placementFromTemplateValue("query", name, value));
  }
  return { slug: template.slug, kind: "apikey", placements };
};

// src/http-auth/migrate.ts
var planAuthConfigMigration = (rows, transforms) => {
  const updates = [];
  for (const row of rows) {
    const transform = transforms[row.pluginId];
    if (!transform) continue;
    const migrated = transform(row.config);
    if (migrated !== null) updates.push({ rowId: row.rowId, config: migrated });
  }
  return updates;
};
var runSqliteAuthConfigMigration = async (client, transforms) => {
  const exists = await client.execute(
    "SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'integration'"
  );
  if (exists.rows.length === 0) return 0;
  const result = await client.execute("SELECT row_id, plugin_id, config FROM integration");
  const rows = [];
  for (const row of result.rows) {
    if (typeof row.row_id !== "string" || typeof row.plugin_id !== "string") continue;
    if (typeof row.config !== "string") continue;
    let config;
    try {
      config = JSON.parse(row.config);
    } catch {
      continue;
    }
    rows.push({ rowId: row.row_id, pluginId: row.plugin_id, config });
  }
  const updates = planAuthConfigMigration(rows, transforms);
  if (updates.length === 0) return 0;
  await client.execute("BEGIN");
  try {
    for (const update of updates) {
      await client.execute({
        sql: "UPDATE integration SET config = ? WHERE row_id = ?",
        args: [JSON.stringify(update.config), update.rowId]
      });
    }
    await client.execute("COMMIT");
  } catch (cause) {
    await client.execute("ROLLBACK");
    throw cause;
  }
  return updates.length;
};
export {
  ApiKeyAuthMethod,
  ApiKeyAuthTemplate,
  AuthCarrier,
  AuthPlacement,
  AuthTemplateValue,
  LegacyApiKeyTemplate,
  LegacyTemplateValue,
  NoneAuthMethod,
  TOKEN_VARIABLE,
  apiKeyAuthTemplateFromMethod,
  apiKeyMethodFromAuthTemplate,
  apiKeyMethodFromLegacyTemplate,
  apiKeyMethodLabel,
  decodeLegacyApiKeyTemplate,
  describeApiKeyAuthMethod,
  describeNoneAuthMethod,
  isApiKeyAuthTemplate,
  normalizeAuthMethodSlugs,
  oauthBearerPlacement,
  planAuthConfigMigration,
  renderAuthPlacements,
  requiredPlacementVariables,
  runSqliteAuthConfigMigration,
  variable
};
//# sourceMappingURL=http-auth.js.map