"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getQuickStartConfiguration = getQuickStartConfiguration;
exports.getManualConfiguration = getManualConfiguration;
exports.getCiConfiguration = getCiConfiguration;
const prompts_1 = require("@clack/prompts");
const shared_constants_1 = require("@vendure/common/lib/shared-constants");
const crypto_1 = require("crypto");
const fs_extra_1 = __importDefault(require("fs-extra"));
const handlebars_1 = __importDefault(require("handlebars"));
const path_1 = __importDefault(require("path"));
const helpers_1 = require("./helpers");
/* eslint-disable no-console */
async function getQuickStartConfiguration(root, packageManager, port) {
    // First we want to detect whether Docker is running
    const { result: dockerStatus } = await (0, helpers_1.isDockerAvailable)();
    let usePostgres;
    switch (dockerStatus) {
        case 'running':
            usePostgres = true;
            break;
        case 'not-found':
            usePostgres = false;
            break;
        case 'not-running': {
            let useSqlite = false;
            let dockerIsNowRunning = false;
            do {
                const useSqliteResponse = await (0, prompts_1.select)({
                    message: 'We could not automatically start Docker. How should we proceed?',
                    options: [
                        { label: `Let's use SQLite as the database`, value: true },
                        { label: 'I have manually started Docker', value: false },
                    ],
                    initialValue: true,
                });
                (0, helpers_1.checkCancel)(useSqlite);
                useSqlite = useSqliteResponse;
                if (useSqlite === false) {
                    const { result: dockerStatusManual } = await (0, helpers_1.isDockerAvailable)();
                    dockerIsNowRunning = dockerStatusManual === 'running';
                }
            } while (dockerIsNowRunning !== true && useSqlite === false);
            usePostgres = !useSqlite;
            break;
        }
    }
    const includeStorefront = await (0, prompts_1.select)({
        message: 'Would you like to include the Next.js storefront?',
        options: [
            { label: 'No', value: false },
            {
                label: 'Yes',
                value: true,
                hint: 'Adds a ready-to-use Next.js storefront connected to your Vendure server',
            },
        ],
        initialValue: false,
    });
    (0, helpers_1.checkCancel)(includeStorefront);
    const quickStartAnswers = {
        dbType: usePostgres ? 'postgres' : 'sqlite',
        dbHost: usePostgres ? 'localhost' : '',
        dbPort: usePostgres ? '6543' : '',
        dbName: usePostgres ? 'vendure' : '',
        dbUserName: usePostgres ? 'vendure' : '',
        dbPassword: usePostgres ? (0, crypto_1.randomBytes)(16).toString('base64url') : '',
        dbSchema: usePostgres ? 'public' : '',
        populateProducts: true,
        superadminIdentifier: shared_constants_1.SUPER_ADMIN_USER_IDENTIFIER,
        superadminPassword: shared_constants_1.SUPER_ADMIN_USER_PASSWORD,
        includeStorefront,
    };
    const responses = Object.assign(Object.assign({}, (await generateSources(root, quickStartAnswers, packageManager, port))), { dbType: quickStartAnswers.dbType, populateProducts: quickStartAnswers.populateProducts, superadminIdentifier: quickStartAnswers.superadminIdentifier, superadminPassword: quickStartAnswers.superadminPassword, includeStorefront: includeStorefront });
    return responses;
}
/**
 * Prompts the user to determine how the new Vendure app should be configured.
 */
async function getManualConfiguration(root, packageManager, port) {
    const dbType = (await (0, prompts_1.select)({
        message: 'Which database are you using?',
        options: [
            { label: 'MySQL', value: 'mysql' },
            { label: 'MariaDB', value: 'mariadb' },
            { label: 'Postgres', value: 'postgres' },
            { label: 'SQLite', value: 'sqlite' },
        ],
        initialValue: 'sqlite',
    }));
    (0, helpers_1.checkCancel)(dbType);
    const hasConnection = dbType !== 'sqlite';
    const dbHost = hasConnection
        ? await (0, prompts_1.text)({
            message: "What's the database host address?",
            initialValue: 'localhost',
        })
        : '';
    (0, helpers_1.checkCancel)(dbHost);
    const dbPort = hasConnection
        ? await (0, prompts_1.text)({
            message: 'What port is the database listening on?',
            initialValue: defaultDBPort(dbType).toString(),
        })
        : '';
    (0, helpers_1.checkCancel)(dbPort);
    const dbName = hasConnection
        ? await (0, prompts_1.text)({
            message: "What's the name of the database?",
            initialValue: 'vendure',
        })
        : '';
    (0, helpers_1.checkCancel)(dbName);
    const dbSchema = dbType === 'postgres'
        ? await (0, prompts_1.text)({
            message: "What's the schema name we should use?",
            initialValue: 'public',
        })
        : '';
    (0, helpers_1.checkCancel)(dbSchema);
    const dbSSL = dbType === 'postgres'
        ? await (0, prompts_1.select)({
            message: 'Use SSL to connect to the database? (only enable if your database provider supports SSL)',
            options: [
                { label: 'no', value: false },
                { label: 'yes', value: true },
            ],
            initialValue: false,
        })
        : false;
    (0, helpers_1.checkCancel)(dbSSL);
    const dbUserName = hasConnection
        ? await (0, prompts_1.text)({
            message: "What's the database user name?",
        })
        : '';
    (0, helpers_1.checkCancel)(dbUserName);
    const dbPassword = hasConnection
        ? await (0, prompts_1.text)({
            message: "What's the database password?",
            defaultValue: '',
        })
        : '';
    (0, helpers_1.checkCancel)(dbPassword);
    const superadminIdentifier = await (0, prompts_1.text)({
        message: 'What identifier do you want to use for the superadmin user?',
        initialValue: shared_constants_1.SUPER_ADMIN_USER_IDENTIFIER,
    });
    (0, helpers_1.checkCancel)(superadminIdentifier);
    const superadminPassword = await (0, prompts_1.text)({
        message: 'What password do you want to use for the superadmin user?',
        initialValue: shared_constants_1.SUPER_ADMIN_USER_PASSWORD,
    });
    (0, helpers_1.checkCancel)(superadminPassword);
    const populateProducts = await (0, prompts_1.select)({
        message: 'Populate with some sample product data?',
        options: [
            { label: 'yes', value: true },
            { label: 'no', value: false },
        ],
        initialValue: true,
    });
    (0, helpers_1.checkCancel)(populateProducts);
    const includeStorefront = await (0, prompts_1.select)({
        message: 'Would you like to include the Next.js storefront?',
        options: [
            { label: 'No', value: false },
            {
                label: 'Yes',
                value: true,
                hint: 'Adds a ready-to-use Next.js storefront connected to your Vendure server',
            },
        ],
        initialValue: false,
    });
    (0, helpers_1.checkCancel)(includeStorefront);
    const answers = {
        dbType,
        dbHost,
        dbPort,
        dbName,
        dbSchema,
        dbUserName,
        dbPassword,
        dbSSL,
        superadminIdentifier,
        superadminPassword,
        populateProducts,
        includeStorefront,
    };
    return Object.assign(Object.assign({}, (await generateSources(root, answers, packageManager, port))), { dbType, populateProducts: answers.populateProducts, superadminIdentifier: answers.superadminIdentifier, superadminPassword: answers.superadminPassword, includeStorefront: includeStorefront });
}
/**
 * Returns mock "user response" without prompting, for use in CI
 */
async function getCiConfiguration(root, packageManager, port, includeStorefront = false) {
    const ciAnswers = {
        dbType: 'sqlite',
        dbHost: '',
        dbPort: '',
        dbName: 'vendure',
        dbUserName: '',
        dbPassword: '',
        populateProducts: true,
        superadminIdentifier: shared_constants_1.SUPER_ADMIN_USER_IDENTIFIER,
        superadminPassword: shared_constants_1.SUPER_ADMIN_USER_PASSWORD,
        includeStorefront,
    };
    return Object.assign(Object.assign({}, (await generateSources(root, ciAnswers, packageManager, port))), { dbType: ciAnswers.dbType, populateProducts: ciAnswers.populateProducts, superadminIdentifier: ciAnswers.superadminIdentifier, superadminPassword: ciAnswers.superadminPassword, includeStorefront });
}
/**
 * Create the server index, worker and config source code based on the options specified by the CLI prompts.
 */
async function generateSources(root, answers, packageManager, port) {
    const assetPath = (fileName) => path_1.default.join(__dirname, '../assets', fileName);
    /**
     * Helper to escape single quotes only. Used when generating the config file since e.g. passwords
     * might use special chars (`< > ' "` etc) which Handlebars would be default convert to HTML entities.
     * Instead, we disable escaping and use this custom helper to escape only the single quote character.
     */
    handlebars_1.default.registerHelper('escapeSingle', (aString) => {
        return typeof aString === 'string' ? aString.replace(/'/g, "\\'") : aString;
    });
    const templateContext = Object.assign(Object.assign({}, answers), { dbType: answers.dbType === 'sqlite' ? 'better-sqlite3' : answers.dbType, name: path_1.default.basename(root), isSQLite: answers.dbType === 'sqlite', requiresConnection: answers.dbType !== 'sqlite', cookieSecret: (0, crypto_1.randomBytes)(16).toString('base64url'), port, isMonorepo: answers.includeStorefront });
    async function createSourceFile(filename, noEscape = false) {
        const template = await fs_extra_1.default.readFile(assetPath(filename), 'utf-8');
        return handlebars_1.default.compile(template, { noEscape })(templateContext);
    }
    return {
        indexSource: await createSourceFile('index.hbs'),
        indexWorkerSource: await createSourceFile('index-worker.hbs'),
        configSource: await createSourceFile('vendure-config.hbs', true),
        envSource: await createSourceFile('.env.hbs', true),
        envDtsSource: await createSourceFile('environment.d.hbs', true),
        readmeSource: await createSourceFile('readme.hbs'),
        dockerfileSource: await createSourceFile('Dockerfile.hbs'),
        dockerComposeSource: await createSourceFile('docker-compose.hbs'),
        tsconfigDashboardSource: await createSourceFile('tsconfig.dashboard.hbs'),
        viteConfigSource: await createSourceFile('vite.config.hbs'),
    };
}
function defaultDBPort(dbType) {
    switch (dbType) {
        case 'mysql':
        case 'mariadb':
            return 3306;
        case 'postgres':
            return 5432;
        default:
            return 3306;
    }
}
//# sourceMappingURL=gather-user-responses.js.map