"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.tryGetPackageJson = void 0;
exports.abort = abort;
exports.isInGitRepo = isInGitRepo;
exports.getUncommittedOrUntrackedFiles = getUncommittedOrUntrackedFiles;
exports.isReact19Installed = isReact19Installed;
exports.installPackage = installPackage;
exports.getPackageDotJson = getPackageDotJson;
exports.updatePackageDotJson = updatePackageDotJson;
exports.getPackageManager = getPackageManager;
exports.isUsingTypeScript = isUsingTypeScript;
exports.tryResolveCredentialsForCi = tryResolveCredentialsForCi;
exports.getOrAskForProjectData = getOrAskForProjectData;
exports.createNewConfigFile = createNewConfigFile;
const childProcess = __importStar(require("node:child_process"));
const fs = __importStar(require("node:fs"));
const os = __importStar(require("node:os"));
const node_path_1 = require("node:path");
const chalk_1 = __importDefault(require("chalk"));
const telemetry_1 = require("../telemetry");
const debug_1 = require("./debug");
const package_manager_1 = require("./package-manager");
const package_json_1 = require("./package-json");
const constants_1 = require("../lib/constants");
const analytics_1 = require("./analytics");
const ui_1 = require("../ui");
const oauth_1 = require("./oauth");
const jwt_exp_1 = require("./jwt-exp");
const api_1 = require("../lib/api");
const wizard_session_1 = require("../lib/wizard-session");
const ampli_settings_1 = require("./ampli-settings");
const urls_1 = require("./urls");
const zone_probe_1 = require("./zone-probe");
const semver_1 = require("./semver");
const wizard_abort_1 = require("./wizard-abort");
const storage_paths_1 = require("./storage-paths");
// Re-exported below for backward compatibility — detection cold paths should
// import directly from `./package-json-light` instead.
const package_json_light_1 = require("./package-json-light");
/** @deprecated Use wizardAbort() directly for new code. */
async function abort(message, status) {
    return (0, wizard_abort_1.wizardAbort)({ message, exitCode: status });
}
function isInGitRepo() {
    try {
        childProcess.execSync('git rev-parse --is-inside-work-tree', {
            stdio: 'ignore',
        });
        return true;
    }
    catch {
        return false;
    }
}
function getUncommittedOrUntrackedFiles() {
    try {
        const gitStatus = childProcess
            .execSync('git status --porcelain=v1', {
            // we only care about stdout
            stdio: ['ignore', 'pipe', 'ignore'],
        })
            .toString();
        const files = gitStatus
            .split(os.EOL)
            .map((line) => line.trim())
            .filter(Boolean)
            .map((f) => `- ${f.split(/\s+/)[1]}`);
        return files;
    }
    catch {
        return [];
    }
}
async function isReact19Installed({ installDir, }) {
    try {
        const packageJson = await (0, exports.tryGetPackageJson)({ installDir });
        if (!packageJson)
            return false;
        const reactVersion = (0, package_json_1.getPackageVersion)('react', packageJson);
        if (!reactVersion) {
            return false;
        }
        return (0, semver_1.fulfillsVersionRange)({
            version: reactVersion,
            acceptableVersions: '>=19.0.0',
            canBeLatest: true,
        });
    }
    catch {
        return false;
    }
}
/**
 * Installs or updates a package with the user's package manager.
 *
 * IMPORTANT: This function modifies the `package.json`! Be sure to re-read
 * it if you make additional modifications to it after calling this function!
 */
async function installPackage({ packageName, alreadyInstalled, packageNameDisplayLabel, packageManager, forceInstall = false, integration, installDir, }) {
    return (0, telemetry_1.traceStep)('install-package', async () => {
        const sdkInstallSpinner = (0, ui_1.getUI)().spinner();
        const pkgManager = packageManager || (await getPackageManager({ installDir }));
        const isReact19 = await isReact19Installed({ installDir });
        const legacyPeerDepsFlag = isReact19 && pkgManager.name === 'npm' ? '--legacy-peer-deps' : '';
        sdkInstallSpinner.start(`${alreadyInstalled ? 'Updating' : 'Installing'} ${chalk_1.default.bold.cyan(packageNameDisplayLabel ?? packageName)} with ${chalk_1.default.bold(pkgManager.label)}.`);
        // Captured by the exec callback below; read in the catch arm to surface
        // the path in the user-facing error message. Typed as a wide union so
        // TypeScript doesn't narrow it to the initializer once a static-analysis
        // pass concludes the closure can't mutate it.
        const installErrorState = { logPath: null };
        try {
            // SECURITY: use execFile (no shell). The package name is wizard-derived
            // (not user-supplied) but we still build the argv from a tokenised list
            // so a future regression — e.g. a manifest field that ever lands in
            // `installCommand` — can't introduce shell injection. installCommand is
            // a multi-word string like "bun add" / "yarn add", so split on
            // whitespace to derive [executable, ...subcommandArgs].
            const [installExe, ...installArgs] = pkgManager.installCommand
                .trim()
                .split(/\s+/);
            const flagArgs = pkgManager.flags ? pkgManager.flags.split(/\s+/) : [];
            const forceArgs = forceInstall && pkgManager.forceInstallFlag
                ? pkgManager.forceInstallFlag.split(/\s+/)
                : [];
            const legacyArgs = legacyPeerDepsFlag
                ? legacyPeerDepsFlag.split(/\s+/)
                : [];
            await new Promise((resolve, reject) => {
                childProcess.execFile(installExe, [
                    ...installArgs,
                    packageName,
                    ...flagArgs,
                    ...forceArgs,
                    ...legacyArgs,
                ], { cwd: installDir }, (err, stdout, stderr) => {
                    if (err) {
                        // Land the error log under `~/.amplitude/wizard/runs/<hash>/`
                        // so it (a) doesn't litter the user's project root and (b)
                        // gets picked up by `/diagnostics --bundle`. Falls back to
                        // the installation dir if the cache root mkdir fails.
                        (0, storage_paths_1.ensureDir)((0, storage_paths_1.getRunDir)(installDir));
                        const logPath = (0, storage_paths_1.getInstallationErrorLogFile)(installDir);
                        try {
                            fs.writeFileSync(logPath, JSON.stringify({ stdout, stderr }), {
                                encoding: 'utf8',
                            });
                            installErrorState.logPath = logPath;
                        }
                        catch {
                            // Best-effort — the underlying npm error is what really
                            // matters; logging is supplementary.
                        }
                        reject(err);
                    }
                    else {
                        resolve();
                    }
                });
            });
        }
        catch (e) {
            sdkInstallSpinner.stop('Installation failed.');
            const logHint = installErrorState.logPath
                ? `The wizard has saved the install error to:\n  ${installErrorState.logPath}\n\nIf you think this issue is caused by the Amplitude wizard, create an issue on GitHub and include the log file's content:\n${constants_1.OUTBOUND_URLS.githubIssues}`
                : `If you think this issue is caused by the Amplitude wizard, create an issue on GitHub:\n${constants_1.OUTBOUND_URLS.githubIssues}`;
            (0, ui_1.getUI)().log.error(`${chalk_1.default.red('Encountered the following error during installation:')}\n\n${e}\n\n${chalk_1.default.dim(logHint)}`);
            await abort();
        }
        sdkInstallSpinner.stop(`${alreadyInstalled ? 'Updated' : 'Installed'} ${chalk_1.default.bold.cyan(packageNameDisplayLabel ?? packageName)} with ${chalk_1.default.bold(pkgManager.label)}.`);
        analytics_1.analytics.wizardCapture('package installed', {
            'package name': packageName,
            'package manager': pkgManager.name,
            integration,
        });
        return { packageManager: pkgManager };
    });
}
/**
 * Get package.json or abort the wizard if not found.
 * Only use where package.json is required (e.g., package install, overrides).
 * For detection/version-checks, use tryGetPackageJson() instead.
 */
async function getPackageDotJson({ installDir, }) {
    const packageJsonFileContents = await fs.promises
        .readFile((0, node_path_1.join)(installDir, 'package.json'), 'utf8')
        .catch(() => {
        (0, ui_1.getUI)().log.error('Could not find package.json. Make sure to run the wizard in the root of your app!');
        return abort();
    });
    let packageJson = undefined;
    try {
        // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
        packageJson = JSON.parse(packageJsonFileContents);
    }
    catch {
        (0, ui_1.getUI)().log.error(`Unable to parse your ${chalk_1.default.cyan('package.json')}. Make sure it has a valid format!`);
        await abort();
    }
    return packageJson || {};
}
/**
 * Try to get package.json, returning null if it doesn't exist.
 * Use this for detection purposes where missing package.json is expected (e.g., Python projects).
 *
 * Re-exported from `./package-json-light` so that callers who import this
 * symbol from `setup-utils` keep working, while framework `detect()` paths
 * can import it from the light module to avoid pulling the rest of
 * `setup-utils` (chalk, OAuth, analytics, …) into the cold-start graph.
 */
exports.tryGetPackageJson = package_json_light_1.tryGetPackageJson;
async function updatePackageDotJson(packageDotJson, { installDir }) {
    try {
        await fs.promises.writeFile((0, node_path_1.join)(installDir, 'package.json'), JSON.stringify(packageDotJson, null, 2), {
            encoding: 'utf8',
            flag: 'w',
        });
    }
    catch {
        (0, ui_1.getUI)().log.error(`Unable to update your ${chalk_1.default.cyan('package.json')}.`);
        await abort();
    }
}
/**
 * Detect and return the package manager. Pure — no prompts.
 * Falls back to first detected or npm if ambiguous.
 */
// eslint-disable-next-line @typescript-eslint/require-await
async function getPackageManager(options) {
    const detectedPackageManagers = (0, package_manager_1.detectAllPackageManagers)({
        installDir: options.installDir,
    });
    if (detectedPackageManagers.length >= 1) {
        const selected = detectedPackageManagers[0];
        analytics_1.analytics.setSessionProperty('package manager', selected.name);
        return selected;
    }
    // No package manager detected — default to npm
    analytics_1.analytics.setSessionProperty('package manager', package_manager_1.NPM.name);
    return package_manager_1.NPM;
}
function isUsingTypeScript({ installDir, }) {
    try {
        return fs.existsSync((0, node_path_1.join)(installDir, 'tsconfig.json'));
    }
    catch {
        return false;
    }
}
/**
 * Best-effort credentials for `--ci` when `--api-key` / AMPLITUDE_WIZARD_API_KEY
 * is not set: locally stored key (.env.local / per-user cache), then OAuth id token from
 * ~/.ampli.json plus org/project from ampli.json (same resolution as interactive bootstrap).
 */
async function tryResolveCredentialsForCi(installDir) {
    const { readApiKeyWithSource } = await import('./api-key-store.js');
    const local = readApiKeyWithSource(installDir);
    if (local) {
        return {
            host: constants_1.DEFAULT_HOST_URL,
            projectApiKey: local.key,
            accessToken: local.key,
            cloudRegion: 'us',
        };
    }
    const { getStoredUser, getStoredToken } = await import('./ampli-settings.js');
    const { readAmpliConfig } = await import('../lib/ampli-config.js');
    const { getAPIKey } = await import('./get-api-key.js');
    const { getHostFromRegion } = await import('./urls.js');
    const storedUser = getStoredUser();
    const realUser = storedUser && storedUser.id !== 'pending' ? storedUser : null;
    const projectConfig = readAmpliConfig(installDir);
    const projectZone = projectConfig.ok ? projectConfig.config.Zone : undefined;
    const zone = realUser?.zone ?? projectZone ?? constants_1.DEFAULT_AMPLITUDE_ZONE;
    const storedToken = realUser
        ? getStoredToken(realUser.id, realUser.zone)
        : getStoredToken(undefined, zone);
    if (!storedToken?.idToken) {
        return null;
    }
    const projectId = projectConfig.ok
        ? projectConfig.config.ProjectId
        : undefined;
    const projectApiKey = await getAPIKey({
        installDir,
        idToken: storedToken.idToken,
        zone,
        projectId,
    });
    if (!projectApiKey) {
        return null;
    }
    const cloudRegion = zone === 'eu' ? 'eu' : 'us';
    return {
        host: getHostFromRegion(cloudRegion),
        projectApiKey,
        accessToken: storedToken.accessToken,
        cloudRegion,
    };
}
/**
 * Get project data for the wizard via Amplitude OAuth or CI API key.
 *
 * Pass installDir to enable fresh-auth detection: when no local ampli.json
 * exists, the cached ~/.ampli.json token is bypassed so the user explicitly
 * authenticates and picks the right Amplitude account for this project.
 */
async function getOrAskForProjectData(_options) {
    // If an API key is provided (via --api-key flag, any mode), bypass OAuth entirely.
    if (_options.apiKey) {
        if (_options.ci) {
            (0, ui_1.getUI)().log.info('Using provided API key (CI mode - OAuth bypassed)');
        }
        return {
            host: constants_1.DEFAULT_HOST_URL,
            projectApiKey: _options.apiKey,
            accessToken: _options.apiKey,
            appId: (0, wizard_session_1.toCredentialAppId)(_options.appId),
            cloudRegion: 'us',
        };
    }
    if (_options.ci) {
        const ciInstallDir = _options.installDir;
        if (!ciInstallDir) {
            (0, ui_1.getUI)().log.error(chalk_1.default.red('CI mode requires --install-dir (or AMPLITUDE_WIZARD_INSTALL_DIR).'));
            await (0, wizard_abort_1.wizardAbort)({
                message: 'CI mode requires an install directory.',
            });
        }
        else {
            const resolved = await tryResolveCredentialsForCi(ciInstallDir);
            if (resolved) {
                (0, ui_1.getUI)().log.info(chalk_1.default.dim('Resolved Amplitude API key non-interactively (CI mode).'));
                return {
                    host: resolved.host,
                    projectApiKey: resolved.projectApiKey,
                    accessToken: resolved.accessToken,
                    appId: (0, wizard_session_1.toCredentialAppId)(_options.appId),
                    cloudRegion: resolved.cloudRegion,
                };
            }
            (0, ui_1.getUI)().log.error(chalk_1.default.red('CI mode could not resolve a project API key. Pass --api-key or AMPLITUDE_WIZARD_API_KEY, store a key in the project (.env.local) or run the wizard interactively once to populate the per-user cache, or ensure the wizard OAuth session store (~/.amplitude/wizard/oauth-session.json, or legacy ~/.ampli.json) has a valid session (and project binding includes ProjectId if needed).'));
            await (0, wizard_abort_1.wizardAbort)({
                message: 'CI mode requires a project API key or resolvable Amplitude credentials.',
            });
        }
    }
    // Force fresh OAuth for projects that haven't been set up yet — no local
    // ampli.json means we don't know which Amplitude org this project belongs to.
    let forceFresh = false;
    if (_options.installDir) {
        const { ampliConfigExists } = await import('../lib/ampli-config.js');
        forceFresh = !ampliConfigExists(_options.installDir);
        if (forceFresh) {
            (0, ui_1.getUI)().log.info(chalk_1.default.dim('No ampli.json found — starting fresh Amplitude authentication for this project.'));
        }
    }
    const result = await (0, telemetry_1.traceStep)('login', () => askForWizardLogin({ forceFresh, installDir: _options.installDir }));
    return {
        accessToken: result.accessToken,
        host: constants_1.DEFAULT_HOST_URL,
        projectApiKey: result.projectApiKey,
        appId: result.appId,
        cloudRegion: result.cloudRegion,
    };
}
async function askForWizardLogin(opts = {}) {
    // ── 1. Authenticate via Amplitude OAuth (reuses ampli CLI session) ──
    const auth = await (0, oauth_1.performAmplitudeAuth)({
        zone: constants_1.DEFAULT_AMPLITUDE_ZONE,
        forceFresh: opts.forceFresh,
    });
    // Wipe any cached project API key for this install dir — a stale key
    // from a prior login in a different org would otherwise win over the
    // freshly-resolved env key in step 4 below (`readApiKeyWithSource` in
    // `askForAmplitudeApiKey` returns first).
    if (opts.installDir) {
        const { clearApiKey } = await import('./api-key-store.js');
        clearApiKey(opts.installDir);
    }
    // ── 2. Detect actual cloud region (EU users auth via US endpoint but
    //       their data lives on EU servers — detectRegionFromToken probes both) ──
    let cloudRegion = 'us';
    try {
        cloudRegion = await (0, urls_1.detectRegionFromToken)(auth.accessToken);
    }
    catch {
        // Fall back to 'us' if region detection fails
    }
    // ── 3. Fetch user info from Amplitude Data API ────────────────────
    let userInfo;
    try {
        userInfo = await (0, api_1.fetchAmplitudeUser)(auth.idToken, cloudRegion);
    }
    catch {
        // Could not fetch user info — warn and continue without it
        (0, ui_1.getUI)().log.warn(chalk_1.default.yellow('Could not fetch user info from Amplitude. Continuing without it.'));
    }
    let selectedOrg;
    if (userInfo) {
        // Persist user details back to ~/.ampli.json (replaces the "pending" entry)
        (0, ampli_settings_1.storeToken)({
            id: userInfo.id,
            firstName: userInfo.firstName,
            lastName: userInfo.lastName,
            email: userInfo.email,
            zone: auth.zone,
        }, {
            accessToken: auth.accessToken,
            idToken: auth.idToken,
            refreshToken: auth.refreshToken,
            // Stored `expiresAt` tracks id_token TTL (binding constraint
            // for API calls) — see `src/utils/jwt-exp.ts`.
            expiresAt: new Date((0, jwt_exp_1.resolveStoredExpiryMs)({ idToken: auth.idToken })).toISOString(),
        });
        // ── 4. Org resolution (flowchart: sign-in → determine destination org) ──
        if (userInfo.orgs.length === 0) {
            // Before we surface a dead-end "no orgs" error, probe the OTHER zone.
            // If the user's org is on the opposite data center, the data API on
            // the current zone will return 0 orgs even though the user is signed
            // in fine. Without this branch the wizard would tell the user "your
            // account has no organizations" — factually wrong when they just
            // happen to have picked (or defaulted to) the wrong region.
            //
            // We never silently switch — region is a user-consented setting, not
            // something we should change behind their back. Instead we throw a
            // typed error so the TUI / outro can render an actionable recovery
            // hint with a one-key region switch.
            const probe = await (0, zone_probe_1.probeOtherZoneForOrgs)(cloudRegion);
            const message = (0, zone_probe_1.buildNoOrgsMessage)(cloudRegion, probe);
            (0, ui_1.getUI)().log.error(`${chalk_1.default.red('No Amplitude organization found.')}\n\n` +
                chalk_1.default.dim(message));
            // Wrap the new-style typed error and rethrow so abort() can carry the
            // metadata. Falling through to abort() preserves the existing exit
            // contract (rejected promise, exit code) for callers.
            throw new zone_probe_1.NoOrgsError(message, cloudRegion, probe.otherZone, probe.otherOrgCount);
        }
        else if (userInfo.orgs.length === 1) {
            selectedOrg = userInfo.orgs[0];
        }
        else {
            // Multiple orgs — prompt the user to pick one
            const { select } = await import('@inquirer/prompts');
            selectedOrg = await select({
                message: 'Select an Amplitude organization:',
                choices: userInfo.orgs.map((org) => ({ name: org.name, value: org })),
            });
        }
        (0, ui_1.getUI)().log.success(`Logged in as ${chalk_1.default.bold(userInfo.email)}${selectedOrg ? ` (${selectedOrg.name})` : ''}`);
        analytics_1.analytics.setDistinctId(userInfo.email);
        analytics_1.analytics.identifyUser({
            email: userInfo.email,
            org_id: selectedOrg?.id,
            org_name: selectedOrg?.name,
        });
        analytics_1.analytics.wizardCapture('wizard link opened');
    }
    let selectedProject;
    if (selectedOrg) {
        if (selectedOrg.projects.length === 1) {
            selectedProject = selectedOrg.projects[0];
        }
        else if (selectedOrg.projects.length > 1) {
            const { select } = await import('@inquirer/prompts');
            selectedProject = await select({
                message: `Select a project in ${selectedOrg.name}:`,
                choices: selectedOrg.projects.map((project) => ({
                    name: project.name,
                    value: project,
                })),
            });
        }
        // Write ~/.ampli.json so future runs recognise this project
        if (opts.installDir && selectedProject) {
            const { writeAmpliConfig } = await import('../lib/ampli-config.js');
            writeAmpliConfig(opts.installDir, {
                OrgId: selectedOrg.id,
                ProjectId: selectedProject.id,
                Zone: cloudRegion,
            });
        }
    }
    // ── 5. Get the Amplitude project API key ─────────────────────────
    // The Data API returns apiKey on the Environment → App type, so we
    // can grab it directly from the project data we already fetched.
    // Falls back to manual prompt if not found.
    let projectApiKey;
    let selectedAppId = null;
    if (selectedProject) {
        // Get environments that have an app with an API key, sorted by rank (lowest = primary)
        const envsWithKey = (selectedProject.environments ?? [])
            .filter((env) => env.app?.apiKey)
            .sort((a, b) => a.rank - b.rank);
        if (envsWithKey.length === 1) {
            projectApiKey = envsWithKey[0].app.apiKey;
            selectedAppId = envsWithKey[0].app?.id ?? null;
            (0, ui_1.getUI)().log.success(chalk_1.default.dim(`Retrieved API key for ${chalk_1.default.bold(envsWithKey[0].name)} environment`));
        }
        else if (envsWithKey.length > 1) {
            const { select } = await import('@inquirer/prompts');
            const selectedEnv = await select({
                message: 'Select an environment:',
                choices: envsWithKey.map((env) => ({
                    name: `${env.name} (${env.app.id})`,
                    value: env,
                })),
            });
            projectApiKey = selectedEnv.app.apiKey;
            selectedAppId = selectedEnv.app?.id ?? null;
            (0, ui_1.getUI)().log.success(chalk_1.default.dim(`Retrieved API key for ${chalk_1.default.bold(selectedEnv.name)} environment`));
        }
        // Persist so future runs don't need to fetch again
        if (projectApiKey && opts.installDir) {
            const { persistApiKey } = await import('./api-key-store.js');
            const source = persistApiKey(projectApiKey, opts.installDir);
            (0, ui_1.getUI)().log.success(chalk_1.default.dim(source === 'cache'
                ? 'API key saved'
                : 'API key saved to .env.local (added to .gitignore)'));
        }
    }
    // Fall back to manual prompt if auto-fetch didn't work
    if (!projectApiKey) {
        projectApiKey = await askForAmplitudeApiKey(opts.installDir);
    }
    return {
        accessToken: auth.accessToken,
        projectApiKey,
        host: constants_1.DEFAULT_HOST_URL,
        distinctId: userInfo?.id ?? 'unknown',
        appId: (0, wizard_session_1.toCredentialAppId)(selectedAppId),
        cloudRegion,
    };
}
async function askForAmplitudeApiKey(installDir) {
    const { readApiKeyWithSource, persistApiKey } = await import('./api-key-store.js');
    // Return saved key if available
    if (installDir) {
        const result = readApiKeyWithSource(installDir);
        if (result) {
            (0, ui_1.getUI)().log.success(chalk_1.default.dim(result.source === 'cache'
                ? 'Using saved Amplitude API key'
                : 'Using saved Amplitude API key from .env.local'));
            return result.key;
        }
    }
    const { input } = await import('@inquirer/prompts');
    (0, ui_1.getUI)().log.info(`\nTo finish setup, enter your Amplitude project ${chalk_1.default.bold('API Key')}.\n` +
        chalk_1.default.dim(`Find it at: Amplitude → Settings → Projects → [your project] → API Keys\n`));
    const apiKey = await input({
        message: 'Amplitude API Key:',
        validate: (v) => v.trim().length > 0 || 'API key cannot be empty',
    });
    const trimmed = apiKey.trim();
    // Persist so the user doesn't have to enter it again
    if (installDir) {
        const source = persistApiKey(trimmed, installDir);
        (0, ui_1.getUI)().log.success(chalk_1.default.dim(source === 'cache'
            ? 'API key saved'
            : 'API key saved to .env.local (added to .gitignore)'));
    }
    return trimmed;
}
/**
 * Creates a new config file with the given filepath and codeSnippet.
 */
async function createNewConfigFile(filepath, codeSnippet, { installDir }, moreInformation) {
    if (!(0, node_path_1.isAbsolute)(filepath)) {
        (0, debug_1.debug)(`createNewConfigFile: filepath is not absolute: ${filepath}`);
        return false;
    }
    const prettyFilename = chalk_1.default.cyan((0, node_path_1.relative)(installDir, filepath));
    try {
        await fs.promises.writeFile(filepath, codeSnippet);
        (0, ui_1.getUI)().log.success(`Added new ${prettyFilename} file.`);
        if (moreInformation) {
            (0, ui_1.getUI)().log.info(chalk_1.default.gray(moreInformation));
        }
        return true;
    }
    catch (e) {
        (0, debug_1.debug)(e);
        (0, ui_1.getUI)().log.warn(`Could not create a new ${prettyFilename} file. Please create one manually and follow the instructions below.`);
    }
    return false;
}
