"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/migrations/index.ts
var migrations_exports = {};
__export(migrations_exports, {
  Migrator: () => Migrator,
  createDomainVerificationsTable: () => createDomainVerificationsTable,
  createMigration: () => createMigration,
  createSsoOidcConfigsTable: () => createSsoOidcConfigsTable,
  createSsoSessionsTable: () => createSsoSessionsTable,
  createTenantInvitationsTable: () => createTenantInvitationsTable,
  createTenantMembersTable: () => createTenantMembersTable,
  createTenantUsageTable: () => createTenantUsageTable,
  createTenantsTable: () => createTenantsTable,
  createVerifiedDomainsTable: () => createVerifiedDomainsTable,
  defineMigration: () => defineMigration,
  enterpriseMigrations: () => enterpriseMigrations,
  getEnterpriseMigrations: () => getEnterpriseMigrations,
  sqlMigration: () => sqlMigration
});
module.exports = __toCommonJS(migrations_exports);

// src/migrations/Migrator.ts
var DEFAULT_CONFIG = {
  tableName: "_migrations",
  schema: "public",
  lockTimeout: 60,
  validateChecksums: true,
  migrationsDir: void 0
};
function generateChecksum(content) {
  let hash = 0;
  for (let i = 0; i < content.length; i++) {
    const char = content.charCodeAt(i);
    hash = (hash << 5) - hash + char;
    hash = hash & hash;
  }
  return Math.abs(hash).toString(16).padStart(8, "0");
}
function sortMigrations(migrations) {
  return [...migrations].sort((a, b) => a.version.localeCompare(b.version));
}
var Migrator = class {
  db;
  config;
  migrations = [];
  initialized = false;
  locked = false;
  constructor(db, config = {}) {
    this.db = db;
    this.config = { ...DEFAULT_CONFIG, ...config };
  }
  /**
   * Get the fully qualified migration table name
   */
  get tableName() {
    return `"${this.config.schema}"."${this.config.tableName}"`;
  }
  /**
   * Get the lock table name
   */
  get lockTableName() {
    return `"${this.config.schema}"."${this.config.tableName}_lock"`;
  }
  /**
   * Initialize migration tracking tables
   */
  async initialize() {
    if (this.initialized) return;
    await this.db.raw(`CREATE SCHEMA IF NOT EXISTS "${this.config.schema}"`);
    await this.db.raw(`
      CREATE TABLE IF NOT EXISTS ${this.tableName} (
        version VARCHAR(255) PRIMARY KEY,
        name VARCHAR(255) NOT NULL,
        applied_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
        execution_time INTEGER NOT NULL,
        checksum VARCHAR(64)
      )
    `);
    await this.db.raw(`
      CREATE TABLE IF NOT EXISTS ${this.lockTableName} (
        id INTEGER PRIMARY KEY DEFAULT 1,
        locked_at TIMESTAMP WITH TIME ZONE,
        locked_by VARCHAR(255),
        CONSTRAINT single_row CHECK (id = 1)
      )
    `);
    await this.db.raw(`
      INSERT INTO ${this.lockTableName} (id, locked_at, locked_by)
      VALUES (1, NULL, NULL)
      ON CONFLICT (id) DO NOTHING
    `);
    this.initialized = true;
  }
  /**
   * Acquire migration lock
   */
  async lock() {
    await this.initialize();
    const lockId = `${process.pid}-${Date.now()}`;
    const lockTimeout = new Date(Date.now() - this.config.lockTimeout * 1e3);
    const result = await this.db.raw(
      `
      UPDATE ${this.lockTableName}
      SET locked_at = CURRENT_TIMESTAMP, locked_by = $1
      WHERE id = 1 AND (locked_at IS NULL OR locked_at < $2)
      RETURNING locked_at
    `,
      [lockId, lockTimeout]
    );
    if (result.data.length > 0) {
      this.locked = true;
      return true;
    }
    return false;
  }
  /**
   * Release migration lock
   */
  async unlock() {
    if (!this.locked) return;
    await this.db.raw(
      `
      UPDATE ${this.lockTableName}
      SET locked_at = NULL, locked_by = NULL
      WHERE id = 1
    `
    );
    this.locked = false;
  }
  /**
   * Add migrations to the migrator
   */
  addMigrations(migrations) {
    for (const migration of migrations) {
      if (!migration.checksum) {
        const content = typeof migration.up === "string" ? migration.up : migration.up.toString();
        migration.checksum = generateChecksum(content);
      }
      if (!this.migrations.find((m) => m.version === migration.version)) {
        this.migrations.push(migration);
      }
    }
  }
  /**
   * Load migrations from directory
   * Expects files named: {version}_{name}.ts or {version}_{name}.sql
   */
  async loadMigrations(dir) {
    const { readdir, readFile } = await import("fs/promises");
    const { join } = await import("path");
    const files = await readdir(dir);
    const migrationFiles = files.filter(
      (f) => f.match(/^\d+_.*\.(ts|js|sql)$/)
    );
    for (const file of migrationFiles) {
      const filePath = join(dir, file);
      const [version, ...nameParts] = file.replace(/\.(ts|js|sql)$/, "").split("_");
      const name = nameParts.join("_");
      if (file.endsWith(".sql")) {
        const content = await readFile(filePath, "utf-8");
        const [up, down] = this.parseSqlMigration(content);
        this.addMigrations([
          {
            version,
            name,
            up,
            down
          }
        ]);
      } else {
        const module2 = await import(filePath);
        this.addMigrations([
          {
            version,
            name,
            up: module2.up,
            down: module2.down,
            transactional: module2.transactional
          }
        ]);
      }
    }
  }
  /**
   * Parse SQL migration file with -- UP and -- DOWN sections
   */
  parseSqlMigration(content) {
    const upMatch = content.match(/--\s*UP\s*\n([\s\S]*?)(?=--\s*DOWN|$)/i);
    const downMatch = content.match(/--\s*DOWN\s*\n([\s\S]*?)$/i);
    const up = upMatch?.[1]?.trim() ?? content.trim();
    const down = downMatch?.[1]?.trim() ?? "";
    return [up, down];
  }
  /**
   * Get current migration status
   */
  async status() {
    await this.initialize();
    const result = await this.db.raw(
      `SELECT version, name, applied_at, execution_time, checksum
       FROM ${this.tableName}
       ORDER BY version ASC`
    );
    const applied = result.data.map((row) => ({
      version: row.version,
      name: row.name,
      appliedAt: new Date(row.applied_at),
      executionTime: row.execution_time,
      checksum: row.checksum ?? void 0
    }));
    const appliedVersions = new Set(applied.map((m) => m.version));
    const sortedMigrations = sortMigrations(this.migrations);
    const pending = sortedMigrations.filter(
      (m) => !appliedVersions.has(m.version)
    );
    return {
      applied,
      pending,
      currentVersion: applied.length > 0 ? applied[applied.length - 1].version : null,
      latestVersion: sortedMigrations.length > 0 ? sortedMigrations[sortedMigrations.length - 1].version : null
    };
  }
  /**
   * Run all pending migrations (or up to a specific version)
   */
  async up(options = {}) {
    const { dryRun = false, to } = options;
    const results = [];
    if (!dryRun) {
      const acquired = await this.lock();
      if (!acquired) {
        throw new Error(
          "Could not acquire migration lock. Another migration may be in progress."
        );
      }
    }
    try {
      const status = await this.status();
      let pending = status.pending;
      if (to) {
        const targetIndex = pending.findIndex((m) => m.version === to);
        if (targetIndex === -1) {
          throw new Error(
            `Target version ${to} not found in pending migrations`
          );
        }
        pending = pending.slice(0, targetIndex + 1);
      }
      for (const migration of pending) {
        const result = await this.runMigration(migration, "up", dryRun);
        results.push(result);
        if (!result.success) {
          break;
        }
      }
    } finally {
      if (!dryRun) {
        await this.unlock();
      }
    }
    return results;
  }
  /**
   * Rollback migrations
   */
  async down(options = {}) {
    const { dryRun = false, steps = 1 } = options;
    const results = [];
    if (!dryRun) {
      const acquired = await this.lock();
      if (!acquired) {
        throw new Error(
          "Could not acquire migration lock. Another migration may be in progress."
        );
      }
    }
    try {
      const status = await this.status();
      const toRollback = status.applied.slice(-steps).reverse();
      for (const record of toRollback) {
        const migration = this.migrations.find(
          (m) => m.version === record.version
        );
        if (!migration) {
          throw new Error(
            `Migration ${record.version} was applied but is not registered. Cannot rollback.`
          );
        }
        const result = await this.runMigration(migration, "down", dryRun);
        results.push(result);
        if (!result.success) {
          break;
        }
      }
    } finally {
      if (!dryRun) {
        await this.unlock();
      }
    }
    return results;
  }
  /**
   * Rollback all migrations and re-run them
   */
  async reset(options = {}) {
    const status = await this.status();
    const downResults = await this.down({
      dryRun: options.dryRun,
      steps: status.applied.length
    });
    if (downResults.every((r) => r.success)) {
      const upResults = await this.up({ dryRun: options.dryRun });
      return [...downResults, ...upResults];
    }
    return downResults;
  }
  /**
   * Migrate to a specific version
   */
  async goto(version, options = {}) {
    const status = await this.status();
    const currentVersion = status.currentVersion;
    const results = [];
    if (currentVersion === version) {
      return results;
    }
    const isUp = !currentVersion || version > currentVersion;
    if (isUp) {
      return this.up({ ...options, to: version });
    } else {
      const currentIndex = status.applied.findIndex(
        (m) => m.version === currentVersion
      );
      const targetIndex = status.applied.findIndex(
        (m) => m.version === version
      );
      if (targetIndex === -1) {
        throw new Error(
          `Target version ${version} not found in applied migrations`
        );
      }
      const steps = currentIndex - targetIndex;
      return this.down({ ...options, steps });
    }
  }
  /**
   * Run a single migration
   */
  async runMigration(migration, direction, dryRun) {
    const startTime = Date.now();
    const action = direction === "up" ? migration.up : migration.down;
    try {
      if (dryRun) {
        return {
          migration,
          success: true,
          executionTime: 0,
          dryRun: true
        };
      }
      const transactional = migration.transactional !== false;
      const runAction = async (db) => {
        if (typeof action === "string") {
          const result = await db.raw(action);
          if (result.error) {
            throw result.error;
          }
        } else {
          await action(db);
        }
      };
      if (transactional) {
        await this.db.transaction(async (tx) => {
          await runAction(tx);
        });
      } else {
        await runAction(this.db);
      }
      const executionTime = Date.now() - startTime;
      if (direction === "up") {
        await this.db.raw(
          `INSERT INTO ${this.tableName} (version, name, execution_time, checksum)
           VALUES ($1, $2, $3, $4)`,
          [
            migration.version,
            migration.name,
            executionTime,
            migration.checksum
          ]
        );
      } else {
        await this.db.raw(`DELETE FROM ${this.tableName} WHERE version = $1`, [
          migration.version
        ]);
      }
      return {
        migration,
        success: true,
        executionTime,
        dryRun: false
      };
    } catch (error) {
      return {
        migration,
        success: false,
        executionTime: Date.now() - startTime,
        error: error instanceof Error ? error : new Error(String(error)),
        dryRun: false
      };
    }
  }
  /**
   * Create a new migration file
   */
  async create(name) {
    const { writeFile, mkdir } = await import("fs/promises");
    const { join } = await import("path");
    if (!this.config.migrationsDir) {
      throw new Error("migrationsDir must be configured to create migrations");
    }
    await mkdir(this.config.migrationsDir, { recursive: true });
    const now = /* @__PURE__ */ new Date();
    const version = [
      now.getFullYear(),
      String(now.getMonth() + 1).padStart(2, "0"),
      String(now.getDate()).padStart(2, "0"),
      String(now.getHours()).padStart(2, "0"),
      String(now.getMinutes()).padStart(2, "0"),
      String(now.getSeconds()).padStart(2, "0")
    ].join("");
    const safeName = name.replace(/[^a-zA-Z0-9_]/g, "_").toLowerCase();
    const fileName = `${version}_${safeName}.sql`;
    const filePath = join(this.config.migrationsDir, fileName);
    const template = `-- Migration: ${name}
-- Version: ${version}
-- Created: ${now.toISOString()}

-- UP
-- Add your forward migration SQL here


-- DOWN
-- Add your rollback migration SQL here

`;
    await writeFile(filePath, template, "utf-8");
    return filePath;
  }
  /**
   * Validate migration integrity
   */
  async validate() {
    const errors = [];
    const status = await this.status();
    if (!this.config.validateChecksums) {
      return { valid: true, errors };
    }
    for (const applied of status.applied) {
      const migration = this.migrations.find(
        (m) => m.version === applied.version
      );
      if (!migration) {
        errors.push(
          `Migration ${applied.version} (${applied.name}) was applied but is not registered`
        );
        continue;
      }
      if (applied.checksum && migration.checksum !== applied.checksum) {
        errors.push(
          `Migration ${applied.version} (${applied.name}) has been modified since it was applied`
        );
      }
    }
    return {
      valid: errors.length === 0,
      errors
    };
  }
};

// src/migrations/helpers.ts
function sqlMigration(migration) {
  return {
    version: migration.version,
    name: migration.name,
    up: migration.up,
    down: migration.down,
    transactional: migration.transactional
  };
}
function createMigration(migration) {
  return {
    version: migration.version,
    name: migration.name,
    up: migration.up,
    down: migration.down,
    transactional: migration.transactional
  };
}
function defineMigration(migration) {
  return migration;
}

// src/migrations/enterprise.ts
var createSsoOidcConfigsTable = {
  version: "20241217_001",
  name: "create_sso_oidc_configs_table",
  up: `
    CREATE TABLE IF NOT EXISTS sso_oidc_configs (
      tenant_id VARCHAR(255) PRIMARY KEY,
      issuer_url VARCHAR(500) NOT NULL,
      client_id VARCHAR(255) NOT NULL,
      client_secret VARCHAR(500) NOT NULL,
      authorization_endpoint VARCHAR(500),
      token_endpoint VARCHAR(500),
      userinfo_endpoint VARCHAR(500),
      jwks_uri VARCHAR(500),
      scopes JSONB DEFAULT '["openid", "profile", "email"]',
      claim_mapping JSONB DEFAULT '{}',
      domains JSONB DEFAULT '[]',
      jit_provisioning_enabled BOOLEAN DEFAULT false,
      default_role VARCHAR(50) DEFAULT 'member',
      pkce_method VARCHAR(10) DEFAULT 'S256',
      metadata JSONB DEFAULT '{}',
      created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
      updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
    );

    CREATE INDEX IF NOT EXISTS idx_sso_oidc_domains ON sso_oidc_configs USING GIN (domains);
  `,
  down: "DROP TABLE IF EXISTS sso_oidc_configs CASCADE"
};
var createDomainVerificationsTable = {
  version: "20241217_002",
  name: "create_domain_verifications_table",
  up: `
    CREATE TABLE IF NOT EXISTS domain_verifications (
      id SERIAL PRIMARY KEY,
      tenant_id VARCHAR(255) NOT NULL,
      domain VARCHAR(255) NOT NULL,
      verification_token VARCHAR(255) NOT NULL,
      verification_method VARCHAR(50) DEFAULT 'dns_txt',
      status VARCHAR(50) DEFAULT 'pending',
      created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
      expires_at TIMESTAMP WITH TIME ZONE,
      verified_at TIMESTAMP WITH TIME ZONE,
      UNIQUE(tenant_id, domain)
    );

    CREATE INDEX IF NOT EXISTS idx_domain_verifications_status ON domain_verifications(status);
  `,
  down: "DROP TABLE IF EXISTS domain_verifications CASCADE"
};
var createVerifiedDomainsTable = {
  version: "20241217_003",
  name: "create_verified_domains_table",
  up: `
    CREATE TABLE IF NOT EXISTS verified_domains (
      id SERIAL PRIMARY KEY,
      tenant_id VARCHAR(255) NOT NULL,
      domain VARCHAR(255) NOT NULL,
      verification_token VARCHAR(255),
      verified_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
      UNIQUE(tenant_id, domain)
    );

    CREATE INDEX IF NOT EXISTS idx_verified_domains_domain ON verified_domains(domain);
  `,
  down: "DROP TABLE IF EXISTS verified_domains CASCADE"
};
var createTenantsTable = {
  version: "20241217_004",
  name: "create_tenants_table",
  up: `
    CREATE TABLE IF NOT EXISTS tenants (
      id VARCHAR(255) PRIMARY KEY,
      slug VARCHAR(255) UNIQUE NOT NULL,
      name VARCHAR(255) NOT NULL,
      status VARCHAR(50) NOT NULL DEFAULT 'active',
      plan VARCHAR(100) NOT NULL,
      custom_domain VARCHAR(255),
      settings JSONB NOT NULL DEFAULT '{}',
      features JSONB NOT NULL DEFAULT '{}',
      quotas JSONB NOT NULL DEFAULT '{}',
      metadata JSONB NOT NULL DEFAULT '{}',
      isolation_model VARCHAR(50) NOT NULL DEFAULT 'row_level',
      schema_name VARCHAR(255),
      created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
      updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
      deleted_at TIMESTAMP WITH TIME ZONE
    );

    CREATE INDEX IF NOT EXISTS idx_tenants_slug ON tenants(slug);
    CREATE INDEX IF NOT EXISTS idx_tenants_custom_domain ON tenants(custom_domain);
    CREATE INDEX IF NOT EXISTS idx_tenants_status ON tenants(status);
    CREATE INDEX IF NOT EXISTS idx_tenants_plan ON tenants(plan);
  `,
  down: "DROP TABLE IF EXISTS tenants CASCADE"
};
var createTenantMembersTable = {
  version: "20241217_005",
  name: "create_tenant_members_table",
  up: `
    CREATE TABLE IF NOT EXISTS tenant_members (
      id VARCHAR(255) PRIMARY KEY,
      tenant_id VARCHAR(255) NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
      user_id VARCHAR(255) NOT NULL,
      role VARCHAR(50) NOT NULL DEFAULT 'member',
      permissions JSONB DEFAULT '[]',
      status VARCHAR(50) NOT NULL DEFAULT 'active',
      invited_by VARCHAR(255),
      joined_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
      UNIQUE(tenant_id, user_id)
    );

    CREATE INDEX IF NOT EXISTS idx_tenant_members_user_id ON tenant_members(user_id);
    CREATE INDEX IF NOT EXISTS idx_tenant_members_status ON tenant_members(status);
  `,
  down: "DROP TABLE IF EXISTS tenant_members CASCADE"
};
var createTenantInvitationsTable = {
  version: "20241217_006",
  name: "create_tenant_invitations_table",
  up: `
    CREATE TABLE IF NOT EXISTS tenant_invitations (
      id VARCHAR(255) PRIMARY KEY,
      tenant_id VARCHAR(255) NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
      email VARCHAR(255) NOT NULL,
      role VARCHAR(50) NOT NULL DEFAULT 'member',
      permissions JSONB DEFAULT '[]',
      token VARCHAR(255) UNIQUE NOT NULL,
      invited_by VARCHAR(255) NOT NULL,
      status VARCHAR(50) NOT NULL DEFAULT 'pending',
      message TEXT,
      created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
      expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
      accepted_at TIMESTAMP WITH TIME ZONE
    );

    CREATE INDEX IF NOT EXISTS idx_tenant_invitations_email ON tenant_invitations(email);
    CREATE INDEX IF NOT EXISTS idx_tenant_invitations_token ON tenant_invitations(token);
    CREATE INDEX IF NOT EXISTS idx_tenant_invitations_status ON tenant_invitations(status);
  `,
  down: "DROP TABLE IF EXISTS tenant_invitations CASCADE"
};
var createTenantUsageTable = {
  version: "20241217_007",
  name: "create_tenant_usage_table",
  up: `
    CREATE TABLE IF NOT EXISTS tenant_usage (
      tenant_id VARCHAR(255) PRIMARY KEY REFERENCES tenants(id) ON DELETE CASCADE,
      user_count INTEGER NOT NULL DEFAULT 0,
      storage_used_bytes BIGINT NOT NULL DEFAULT 0,
      api_requests_this_month BIGINT NOT NULL DEFAULT 0,
      project_count INTEGER NOT NULL DEFAULT 0,
      custom JSONB DEFAULT '{}',
      updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
    );
  `,
  down: "DROP TABLE IF EXISTS tenant_usage CASCADE"
};
var createSsoSessionsTable = {
  version: "20241217_008",
  name: "create_sso_sessions_table",
  up: `
    CREATE TABLE IF NOT EXISTS sso_sessions (
      id VARCHAR(255) PRIMARY KEY,
      user_id VARCHAR(255) NOT NULL,
      tenant_id VARCHAR(255) NOT NULL,
      sso_provider VARCHAR(50) NOT NULL,
      idp_session_id VARCHAR(255),
      saml_session_index VARCHAR(255),
      groups JSONB DEFAULT '[]',
      access_token TEXT,
      refresh_token TEXT,
      id_token TEXT,
      expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
      created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
    );

    CREATE INDEX IF NOT EXISTS idx_sso_sessions_user_id ON sso_sessions(user_id);
    CREATE INDEX IF NOT EXISTS idx_sso_sessions_tenant_id ON sso_sessions(tenant_id);
    CREATE INDEX IF NOT EXISTS idx_sso_sessions_expires ON sso_sessions(expires_at);
  `,
  down: "DROP TABLE IF EXISTS sso_sessions CASCADE"
};
var createBetaSettingsTable = {
  version: "20241217_009",
  name: "create_beta_settings_table",
  up: `
    CREATE TABLE IF NOT EXISTS beta_settings (
      key VARCHAR(100) PRIMARY KEY,
      value TEXT NOT NULL,
      description TEXT,
      updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
      updated_by VARCHAR(255)
    );

    INSERT INTO beta_settings (key, value, description) VALUES
      ('beta_mode', 'true', 'Whether the app is in beta mode'),
      ('require_invite_code', 'true', 'Whether an invite code is required to sign up'),
      ('beta_message', 'We''re in beta! Thanks for being an early tester.', 'Message displayed during beta')
    ON CONFLICT (key) DO NOTHING;
  `,
  down: "DROP TABLE IF EXISTS beta_settings CASCADE"
};
var createBetaInvitesTable = {
  version: "20241217_010",
  name: "create_beta_invites_table",
  up: `
    CREATE TABLE IF NOT EXISTS beta_invites (
      id VARCHAR(255) PRIMARY KEY,
      code VARCHAR(100) NOT NULL UNIQUE,
      max_uses INTEGER NOT NULL DEFAULT 1,
      current_uses INTEGER NOT NULL DEFAULT 0,
      expires_at TIMESTAMP WITH TIME ZONE,
      created_by VARCHAR(255) NOT NULL,
      notes TEXT DEFAULT '',
      is_active BOOLEAN NOT NULL DEFAULT true,
      created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
      CONSTRAINT chk_beta_uses CHECK (current_uses <= max_uses)
    );

    CREATE INDEX IF NOT EXISTS idx_beta_invites_code_active
      ON beta_invites(code) WHERE is_active = true;
    CREATE INDEX IF NOT EXISTS idx_beta_invites_active
      ON beta_invites(is_active, created_at DESC);
  `,
  down: "DROP TABLE IF EXISTS beta_invites CASCADE"
};
var createBetaTestersTable = {
  version: "20241217_011",
  name: "create_beta_testers_table",
  up: `
    CREATE TABLE IF NOT EXISTS beta_testers (
      user_id VARCHAR(255) PRIMARY KEY,
      invite_code VARCHAR(100) NOT NULL REFERENCES beta_invites(code) ON DELETE SET NULL,
      is_beta_tester BOOLEAN NOT NULL DEFAULT true,
      beta_joined_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
    );

    CREATE INDEX IF NOT EXISTS idx_beta_testers_active
      ON beta_testers(is_beta_tester, beta_joined_at DESC)
      WHERE is_beta_tester = true;
  `,
  down: "DROP TABLE IF EXISTS beta_testers CASCADE"
};
var enterpriseMigrations = [
  createSsoOidcConfigsTable,
  createDomainVerificationsTable,
  createVerifiedDomainsTable,
  createTenantsTable,
  createTenantMembersTable,
  createTenantInvitationsTable,
  createTenantUsageTable,
  createSsoSessionsTable,
  createBetaSettingsTable,
  createBetaInvitesTable,
  createBetaTestersTable
];
function getEnterpriseMigrations(features) {
  const migrations = [];
  if (features.sso) {
    migrations.push(
      createSsoOidcConfigsTable,
      createDomainVerificationsTable,
      createVerifiedDomainsTable,
      createSsoSessionsTable
    );
  }
  if (features.tenancy) {
    migrations.push(
      createTenantsTable,
      createTenantMembersTable,
      createTenantInvitationsTable,
      createTenantUsageTable
    );
  }
  if (features.beta) {
    migrations.push(
      createBetaSettingsTable,
      createBetaInvitesTable,
      createBetaTestersTable
    );
  }
  return migrations;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  Migrator,
  createDomainVerificationsTable,
  createMigration,
  createSsoOidcConfigsTable,
  createSsoSessionsTable,
  createTenantInvitationsTable,
  createTenantMembersTable,
  createTenantUsageTable,
  createTenantsTable,
  createVerifiedDomainsTable,
  defineMigration,
  enterpriseMigrations,
  getEnterpriseMigrations,
  sqlMigration
});
//# sourceMappingURL=index.js.map