src/services/projects/create/options.ts
import type { Language } from '../../../utils/languages';
import type { CommandOptions } from '../../../utils/option-parser';
import languages from '../../../utils/languages';
import { validateAppHostname, validateDbName, validatePort } from '../../../utils/validators';
export type ProjectCreateOptions = {
applicationName: string;
applicationHost: string;
applicationPort: string;
databaseConnectionURL?: string;
databaseName?: string;
databaseHost?: string;
databasePort?: string;
databaseUser?: string;
databasePassword?: string;
databaseSSL?: boolean;
databaseSslMode?: 'preferred' | 'disabled' | 'required' | 'verify';
databaseDialect?: 'mariadb' | 'mssql' | 'mysql' | 'postgres' | 'mongodb';
databaseSchema?: string;
mongoDBSRV?: boolean;
language?: Language;
};
type Option = CommandOptions<ProjectCreateOptions>[string];
export function getDialect(options: ProjectCreateOptions): ProjectCreateOptions['databaseDialect'] {
const { databaseDialect: dialect, databaseConnectionURL: url } = options;
if (dialect) return dialect;
if (url?.startsWith('postgres://')) return 'postgres';
if (url?.startsWith('mssql://')) return 'mssql';
if (url?.startsWith('mongodb')) return 'mongodb';
if (url?.startsWith('mysql://') || url?.startsWith('mariadb://')) return 'mysql';
return null;
}
export const applicationHost: Option = {
default: 'http://localhost',
validate: validateAppHostname,
oclif: { char: 'H', description: 'Hostname of your admin backend application.' },
prompter: { question: "What's the IP/hostname on which your application will be running?" },
};
export const applicationPort: Option = {
default: '3310',
validate: validatePort,
oclif: { char: 'P', description: 'Port of your admin backend application.' },
prompter: { question: `What's the port on which your application will be running?` },
};
export const databaseConnectionURL: Option = {
oclif: { char: 'c', description: 'Enter the database credentials with a connection URL.' },
prompter: null,
};
export const databaseName: Option = {
exclusive: ['databaseConnectionURL'],
validate: validateDbName,
oclif: { char: 'n', description: 'Enter your database name.' },
prompter: { question: "What's the database name?" },
};
export const databaseHost: Option = {
exclusive: ['databaseConnectionURL'],
default: 'localhost',
oclif: { char: 'h', description: 'Enter your database host.' },
prompter: { question: "What's the database hostname?" },
};
export const databasePort: Option = {
exclusive: ['databaseConnectionURL'],
default: args => {
const dialect = getDialect(args);
if (dialect === 'postgres') return '5432';
if (dialect === 'mysql' || dialect === 'mariadb') return '3306';
if (dialect === 'mssql') return '1433';
if (dialect === 'mongodb') return '27017';
return undefined;
},
validate: validatePort,
oclif: { char: 'p', description: 'Enter your database port.' },
prompter: { question: "What's the database port?" },
};
export const databaseUser: Option = {
exclusive: ['databaseConnectionURL'],
default: args => (getDialect(args) === 'mongodb' ? undefined : 'root'),
oclif: { char: 'u', description: 'Enter your database user.' },
prompter: { question: "What's the database user?" },
};
export const databasePassword: Option = {
exclusive: ['databaseConnectionURL'],
oclif: { description: 'Enter your database password.' },
prompter: { question: "What's the database password? [optional]" },
};
export const databaseSSL: Option = {
exclusive: ['databaseSslMode'],
when: args => args.databaseSslMode === undefined,
type: 'boolean',
default: false,
oclif: { description: 'Use SSL for database connection.' },
prompter: { question: 'Does your database require a SSL connection?' },
};
export const databaseSslMode: Option = {
exclusive: ['databaseSSL'],
when: args => args.databaseSSL === undefined,
choices: ['preferred', 'verify', 'required', 'disabled'].map(value => ({ name: value, value })),
default: 'preferred',
oclif: { description: 'SSL mode.' },
prompter: { question: 'Which SSL mode do you want to use?' },
};
export const language: Option = {
choices: Object.values(languages).map(l => ({ name: l.name, value: l })),
default: Object.values(languages)[0],
oclif: { char: 'l', description: 'Choose the language you want to use for your project.' },
prompter: { question: 'In which language would you like to generate your sources?' },
};
export const databaseDialectV1: Option = {
choices: [
{ name: 'mongodb', value: 'mongodb' },
{ name: 'mssql', value: 'mssql' },
{ name: 'mysql / mariadb', value: 'mysql' },
{ name: 'postgres', value: 'postgres' },
],
exclusive: ['databaseConnectionURL'],
oclif: { char: 'd', description: 'Enter your database dialect.' },
prompter: { question: "What's the database type?" },
};
export const databaseDialectSqlV2: Option = {
choices: [
{ name: 'mssql', value: 'mssql' },
{ name: 'mysql / mariadb', value: 'mysql' },
{ name: 'postgres', value: 'postgres' },
],
exclusive: ['databaseConnectionURL'],
oclif: { char: 'd', description: 'Enter your database dialect.' },
prompter: { question: "What's the database type?" },
};
export const databaseSchema: Option = {
when: args => ['postgres', 'mssql'].includes(getDialect(args)),
default: args => (getDialect(args) === 'postgres' ? 'public' : ''),
oclif: { char: 's', description: 'Enter your database schema.' },
prompter: {
question: "What's the database schema? [optional]",
description: 'Leave blank by default',
},
};
export const mongoDBSRV: Option = {
type: 'boolean',
exclusive: ['databaseConnectionURL'],
when: args => getDialect(args) === 'mongodb',
default: false,
oclif: { description: 'Use SRV DNS record for mongoDB connection.' },
prompter: { question: 'Use a SRV connection string?' },
};