diff --git a/.gitignore b/.gitignore index 45af121..9d0a596 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ _sql-database/ dist/ node_modules/ ssc.json +ssc-*.json +Web.config diff --git a/README.md b/README.md index e30a435..4991d55 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,10 @@ Configuration options are stored in a `ssc.json` file. }], // ... OR, path to Web.config file with connectionStrings - "connections": "../Web.config", + "connections": "./Web.config", + + // ... OR, path to ssc-connections.json file + "connections": "./ssc-connections.json", // the following options are optional (default values shown) ... diff --git a/src/commands/init.ts b/src/commands/init.ts index 603235f..6498f30 100644 --- a/src/commands/init.ts +++ b/src/commands/init.ts @@ -13,6 +13,15 @@ interface InitOptions { skip?: boolean; } +/** + * Connection path choices. + */ +enum PathChoices { + SscConfig, + ConnsConfig, + WebConfig +} + /** * Create default config file. * @@ -35,56 +44,88 @@ export function init(options: InitOptions): void { if (options.skip) { // skip prompts and create with defaults - util.setConfig({ connections: options.webconfig || [conn] }); + util.setConfig(util.configFile, { connections: options.webconfig || [conn] }); return; } const questions: inquirer.Questions = [ { name: 'path', - message: 'Use connections from Web.config file?', - type: 'confirm', - when: (): boolean => !!webConfigConns - }, { + message: 'Where would you like to store connections?', + type: 'list', + choices: () => { + const choices: object[] = [ + { name: 'Main configuration file.', value: PathChoices.SscConfig }, + { name: 'Separate connections configuration file.', value: PathChoices.ConnsConfig } + ]; + + if (webConfigConns) { + choices.push({ + name: 'Web.config file with connection strings.', + value: PathChoices.WebConfig + }); + } + + return choices; + } + }, + { name: 'server', message: 'Server URL.', default: (conn.server || undefined), - when: (answers): boolean => (!webConfigConns || !answers.path) - }, { + when: answers => (answers.path !== PathChoices.WebConfig) + }, + { name: 'port', message: 'Server port.', default: (conn.port || undefined), - when: (answers): boolean => (!webConfigConns || !answers.path) - }, { + when: answers => (answers.path !== PathChoices.WebConfig) + }, + { name: 'database', message: 'Database name.', default: (conn.database || undefined), - when: (answers): boolean => (!webConfigConns || !answers.path) - }, { + when: answers => (answers.path !== PathChoices.WebConfig) + }, + { name: 'user', message: 'Login username.', default: (conn.user || undefined), - when: (answers): boolean => (!webConfigConns || !answers.path) - }, { + when: answers => (answers.path !== PathChoices.WebConfig) + }, + { name: 'password', message: 'Login password.', + type: 'password', default: (conn.password || undefined), - when: (answers): boolean => (!webConfigConns || !answers.path) - }, { + when: answers => (answers.path !== PathChoices.WebConfig) + }, + { name: 'name', message: 'Connection name.', default: 'dev', - when: (answers): boolean => (!webConfigConns || !answers.path) + when: answers => (answers.path !== PathChoices.WebConfig) } ]; // prompt user for config options inquirer.prompt(questions).then((answers: inquirer.Answers): void => { - if (answers.path) { - // use Web.config path - util.setConfig({ connections: webConfigFile }); + if (answers.path === PathChoices.WebConfig) { + util.setConfig(util.configFile, { connections: webConfigFile }); + } else if (answers.path === PathChoices.ConnsConfig) { + util.setConfig(util.configFile, { connections: './ssc-connections.json' }); + util.setConfig(util.connsFile, { + connections: [new Connection({ + name: answers.name, + server: answers.server, + port: answers.port, + database: answers.database, + user: answers.user, + password: answers.password + })] + }); } else { - util.setConfig({ + util.setConfig(util.configFile, { connections: [new Connection({ name: answers.name, server: answers.server, diff --git a/src/common/utility.ts b/src/common/utility.ts index 2594301..2319b34 100644 --- a/src/common/utility.ts +++ b/src/common/utility.ts @@ -14,6 +14,11 @@ import { Connection } from '../common/connection'; */ export const configFile: string = path.join(process.cwd(), 'ssc.json'); +/** + * Connections file path. + */ +export const connsFile: string = path.join(process.cwd(), 'ssc-connections.json'); + /** * Web config file path. */ @@ -77,13 +82,14 @@ export function getConfig(): Config { /** * Write config file with provided object contents. * + * @param file Configuration file to write to. * @param config Object to save for config file. */ -export function setConfig(config: Config): void { +export function setConfig(file: string, config: Config): void { const content: string = JSON.stringify(config, null, 2); // save file - fs.outputFile(configFile, content, (error: Error) => { + fs.outputFile(file, content, (error: Error) => { if (error) { return console.error(error); } @@ -107,8 +113,13 @@ export function getConns(config: Config): Connection[] { } if (isString(config.connections)) { - // get form web config - return getWebConfigConns(config.connections); + const configExt: RegExp = /\.config$/; + + if (configExt.test(config.connections)) { + return getWebConfigConns(config.connections); + } else { + return getConnsConfigConns(config.connections); + } } else { return config.connections; } @@ -181,6 +192,24 @@ export function getWebConfigConns(file?: string): Connection[] { return (conns.length ? conns : undefined); } +/** + * Safely get connections from `ssc-connections.json` file. + * + * @param file Relative path to connections config file. + */ +export function getConnsConfigConns(file?: string): Connection[] { + let config: Config; + + try { + config = fs.readJsonSync(file); + } catch (error) { + console.error('Could not find or parse connections config file!'); + process.exit(); + } + + return config.connections as Connection[]; +} + /** * Get all SQL files in correct execution order. *