{"version":3,"file":"drizzle-config.cjs","names":["getD1BindingInfo","confirmSync"],"sources":["../src/drizzle-config.ts"],"sourcesContent":["import { execFileSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport type { Config } from 'drizzle-kit';\nimport { confirmSync, getD1BindingInfo } from './utils';\n\n/**\n * Options for configuring a Drizzle Kit setup targeting a Cloudflare D1 database.\n */\nexport interface DrizzleD1Options {\n  /** Path to the Wrangler configuration file (`wrangler.toml` or `wrangler.json`). */\n  configPath?: string;\n  /** Directory where the local D1 SQLite database file is persisted. */\n  persistTo?: string;\n  /** Wrangler environment name (e.g. `\"staging\"`, `\"production\"`). */\n  environment?: string;\n  /** Name of the D1 binding as declared in the Wrangler config.\n   *\n   * Defaults to the first D1 binding found.\n   */\n  binding?: string;\n  /**\n   * When `true`, connects to the remote Cloudflare D1 database via the HTTP API\n   * instead of a local SQLite file.\n   *\n   * Requires `accountId` and `apiToken`.\n   *\n   * Defaults to the `remote` flag on the resolved D1 binding if set, otherwise `false`.\n   */\n  remote?: boolean;\n  /** When `true`, targets the D1 preview database instead of the production one. */\n  preview?: boolean;\n  /**\n   * Cloudflare account ID.\n   *\n   * Required when using remote database.\n   */\n  accountId?: string;\n  /**\n   * Cloudflare API token with D1 read/write permissions.\n   *\n   * Required when using remote database.\n   */\n  apiToken?: string;\n}\n\n/**\n * A Drizzle Kit `Config` object with the dialect, driver, and database\n * credential fields omitted — those are injected automatically by {@link drizzleD1Config}.\n */\nexport type DrizzleKitConfig = Omit<Config, 'dialect' | 'driver' | 'dbCredentials'>;\n\n/**\n * Builds a complete Drizzle Kit {@link Config} object pre-configured for a\n * Cloudflare D1 database.\n *\n * Behaviour:\n * - **Local mode** (default): resolves the SQLite file path from the Wrangler\n *   config and points `dbCredentials.url` at it. If the file does not yet exist\n *   the user is prompted to run `wrangler d1 execute --local` to create it.\n * - **Remote mode** (`options.remote = true`): switches the driver to `d1-http`\n *   and forwards `accountId` / `apiToken` as HTTP credentials. Both options are\n *   required in this mode.\n * - **Preview mode** (`options.preview = true`): targets the `preview_database_id`\n *   declared in the Wrangler config rather than the production `database_id`.\n *\n * @param config  Base Drizzle Kit configuration (schemas, migrations directory, etc.)\n *                — everything except dialect, driver, and credentials.\n * @param options D1-specific options that control which binding, environment,\n *                and mode (local / remote / preview) to use.\n * @returns       A complete Drizzle Kit `Config` ready to be exported from\n *                `drizzle.config.ts`.\n *\n * @throws {Error} If required remote options (`accountId`, `apiToken`) are missing\n *                 when `remote` is `true`.\n * @throws {Error} If the resolved `database_id` / `preview_database_id` is not set\n *                 for the target binding.\n * @throws {Error} If the local SQLite file cannot be found or created.\n *\n * @example\n * // drizzle.config.ts — local mode\n * import { drizzleD1Config } from '@deox/drizzle-d1-utils';\n *\n * export default drizzleD1Config(\n *   { schema: './src/schema.ts', out: './drizzle' },\n *   { binding: 'DB' },\n * );\n *\n * @example\n * // drizzle.config.ts — remote mode\n * import { drizzleD1Config } from '@deox/drizzle-d1-utils';\n *\n * export default drizzleD1Config(\n *   { schema: './src/schema.ts', out: './drizzle' },\n *   {\n *     binding: 'DB',\n *     remote: true,\n *     accountId: process.env.CF_ACCOUNT_ID,\n *     apiToken: process.env.CF_API_TOKEN,\n *   },\n * );\n */\nexport function drizzleD1Config(config: DrizzleKitConfig, options: DrizzleD1Options = {}): Config {\n  const binding = getD1BindingInfo({\n    binding: options.binding,\n    environment: options.environment,\n    configPath: options.configPath,\n    persistTo: options.persistTo,\n  });\n\n  const useRemote = options.remote ?? binding.remote ?? false;\n  const usePreview = options.preview ?? false;\n\n  if (useRemote) {\n    const requiredOptions: (keyof DrizzleD1Options)[] = ['accountId', 'apiToken'];\n    const missingOptions = requiredOptions.filter((name) => !options[name]);\n    if (missingOptions.length > 0) {\n      throw new Error(`Options ${requiredOptions.join(', ')} are required when using remote database. Missing: ${missingOptions.join(', ')}`);\n    }\n  }\n\n  const database = usePreview ? binding.previewDatabase : binding.database;\n\n  if (!database) {\n    throw new Error(`'${usePreview ? 'preview_database_id' : 'database_id'} is not set for D1 binding '${binding.binding}'`);\n  }\n\n  if (!useRemote && !database.exists) {\n    if (binding.databaseName) {\n      let bin: string | undefined;\n      try {\n        bin = createRequire(import.meta.url).resolve('wrangler/bin/wrangler');\n      } catch (_) {}\n\n      if (bin) {\n        const args: string[] = ['d1', 'execute', binding.databaseName, \"--command='SELECT 1'\", '--local'];\n        if (options.environment) {\n          args.push(`--env=${options.environment}`);\n        }\n        if (options.configPath) {\n          args.push(`--config=${options.configPath}`);\n        }\n        if (options.persistTo) {\n          args.push(`--persist-to=${options.persistTo}`);\n        }\n\n        const command = ['wrangler', ...args].join(' ');\n        console.log(`[!] SQLite file for D1 binding '${binding.binding}' does not exist.`);\n        console.log('[!] The file can be created by executing the following command:');\n        console.log(`    ${command}`);\n\n        const confirmed = confirmSync('[!] Run this command to create it?');\n        if (!confirmed) {\n          throw new Error('Aborted by user.');\n        }\n\n        console.log('[!] Command is being executed. Please wait...');\n\n        try {\n          execFileSync(bin, args, {\n            stdio: 'ignore',\n          });\n        } catch (_) {}\n\n        if (existsSync(database.filename)) {\n          database.exists = true;\n\n          console.log('[✓] Command success! SQLite file has been successfully created.');\n        } else {\n          console.log('[×] Command failed! Unable to create SQLite file.');\n          process.exit(1);\n        }\n      }\n    }\n    if (!database.exists) {\n      throw new Error(`Could not find SQLite file for D1 binding '${binding.binding}'`);\n    }\n  }\n\n  console.log('----------------------------------------------------------');\n  console.log('  Using following D1 Database:');\n  console.log('----------------------------------------------------------');\n  console.log(`  Binding        : ${binding.binding}`);\n  console.log(`  Database name  : ${binding.databaseName ?? '(not set)'}`);\n  console.log(`  Database Id    : ${database.id}`);\n  if (useRemote) {\n    console.log('  Mode           : REMOTE');\n    console.log('                   (using remote Cloudflare D1 database)');\n  } else {\n    console.log('  Mode           : LOCAL');\n    console.log('                   (using local SQLite database)');\n    console.log(`  SQLite file    : ${database.filename}`);\n  }\n  console.log('----------------------------------------------------------');\n\n  process.on('exit', () => {\n    console.log('');\n  });\n\n  return {\n    ...config,\n    dialect: 'sqlite',\n    ...(useRemote\n      ? {\n          driver: 'd1-http',\n          dbCredentials: {\n            databaseId: database.id,\n            accountId: options.accountId,\n            token: options.apiToken,\n          },\n        }\n      : {\n          dbCredentials: {\n            url: `file:${database.filename}`,\n          },\n        }),\n  };\n}\n"],"mappings":"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"}