From 383ca0b4897b6bd5465ac3bbcf50c4c11e0b5b76 Mon Sep 17 00:00:00 2001
From: Reil Gingoyon <reil.gingoyon@gmail.com>
Date: Thu, 6 Oct 2022 00:47:22 +0800
Subject: [PATCH 1/2] feat: added db:info command

---
 src/commands/database_info.js | 65 +++++++++++++++++++++++++++++++++++
 src/sequelize.js              |  2 ++
 2 files changed, 67 insertions(+)
 create mode 100644 src/commands/database_info.js

diff --git a/src/commands/database_info.js b/src/commands/database_info.js
new file mode 100644
index 000000000..3f6cd070d
--- /dev/null
+++ b/src/commands/database_info.js
@@ -0,0 +1,65 @@
+import process from 'process';
+import { _baseOptions } from '../core/yargs';
+
+import helpers from '../helpers';
+import { pick } from 'lodash';
+import clc from 'cli-color';
+
+exports.builder = (yargs) => {
+  _baseOptions(yargs)
+    .option('show-password', {
+      describe: 'Will show password as plain text',
+      type: 'boolean',
+      default: false,
+    })
+    .option('raw', {
+      describe: 'Display the raw object',
+      type: 'boolean',
+      default: false,
+    }).argv;
+};
+
+exports.handler = async function (args) {
+  const command = args._[0];
+
+  // legacy, gulp used to do this
+  await helpers.config.init();
+
+  const options = pick(args, ['showPassword', 'raw']);
+
+  switch (command) {
+    case 'db:info':
+      displayConfigObject(options);
+      break;
+  }
+
+  process.exit(0);
+};
+
+function displayConfigObject(options) {
+  let config = null;
+
+  try {
+    config = helpers.config.readConfig();
+  } catch (e) {
+    helpers.view.error(e);
+  }
+
+  if (!options.showPassword) {
+    config.password = '***';
+  }
+
+  helpers.view.log();
+  helpers.view.log(clc.bold('Sequelize configuration:'));
+
+  options.raw
+    ? helpers.view.log(JSON.stringify(config, null, 2))
+    : display(config);
+}
+
+function display(i, p = '') {
+  Object.entries(i).forEach(([k, v]) => {
+    if (typeof v == 'object' && v !== null) display(v, `${p}${k}.`);
+    else helpers.view.log(`${p}${k}:`, v);
+  });
+}
diff --git a/src/sequelize.js b/src/sequelize.js
index 7249135c6..db1766ce1 100644
--- a/src/sequelize.js
+++ b/src/sequelize.js
@@ -14,6 +14,7 @@ import migrationGenerate from './commands/migration_generate';
 import modelGenerate from './commands/model_generate';
 import seedGenerate from './commands/seed_generate';
 import database from './commands/database';
+import databaseInfo from './commands/database_info';
 
 import helpers from './helpers/index';
 
@@ -35,6 +36,7 @@ yargs
   .command('db:seed:undo', 'Deletes data from the database', seedOne)
   .command('db:seed:all', 'Run every seeder', seed)
   .command('db:seed:undo:all', 'Deletes data from the database', seed)
+  .command('db:info', 'Displays the database configuration', databaseInfo)
   .command('db:create', 'Create database specified by configuration', database)
   .command('db:drop', 'Drop database specified by configuration', database)
   .command('init', 'Initializes project', init)

From 3643588d2c0c3444e312055a461adf80c7af6338 Mon Sep 17 00:00:00 2001
From: Reil Gingoyon <reil.gingoyon@gmail.com>
Date: Sat, 18 Mar 2023 18:48:54 +0800
Subject: [PATCH 2/2] feat: wip db info tests

---
 .editorconfig           |  4 +++
 config/config.json      | 36 ++++++++++++++++++++
 makefile                | 30 +++++++++++++++++
 package.json            |  3 +-
 test/db/db-info.test.js | 74 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 146 insertions(+), 1 deletion(-)
 create mode 100644 config/config.json
 create mode 100644 makefile
 create mode 100644 test/db/db-info.test.js

diff --git a/.editorconfig b/.editorconfig
index d2cc08509..017b589e3 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -19,3 +19,7 @@ insert_final_newline = true
 [*.md]
 trim_trailing_whitespace = false
 indent_size = 4
+
+[{Makefile,**.mk}]
+# Use tabs for indentation (Makefiles require tabs)
+indent_style = tab
diff --git a/config/config.json b/config/config.json
new file mode 100644
index 000000000..aa09c8ed0
--- /dev/null
+++ b/config/config.json
@@ -0,0 +1,36 @@
+{
+  "development": {
+    "username": "root",
+    "password": "secret_pass",
+    "database": "database_development",
+    "host": "127.0.0.1",
+    "dialect": "mysql",
+    "pool": {
+      "maxConnections": 1,
+      "some": {
+        "other": {
+          "nested": {
+            "object": "here"
+          }
+        }
+      }
+    }
+  },
+  "env": {
+    "use_env_variable": "postgresql://[user[:password]@][netlocation][:port][/dbname]"
+  },
+  "test": {
+    "username": "root",
+    "password": null,
+    "database": "database_test",
+    "host": "127.0.0.1",
+    "dialect": "mysql"
+  },
+  "production": {
+    "username": "root",
+    "password": null,
+    "database": "database_production",
+    "host": "127.0.0.1",
+    "dialect": "mysql"
+  }
+}
diff --git a/makefile b/makefile
new file mode 100644
index 000000000..ab8c0fdd4
--- /dev/null
+++ b/makefile
@@ -0,0 +1,30 @@
+build:
+	npm run build
+
+info:
+	@echo "INFO" && \
+	lib/sequelize db:info
+
+fail:
+	@echo "FAIL" && \
+	NODE_ENV=nope lib/sequelize db:info
+
+raw:
+	@echo "RAW" && lib/sequelize db:info --raw
+
+show:
+	@echo "PWD" && lib/sequelize db:info --show-password
+
+env:
+	@echo "ENV" && NODE_ENV=env lib/sequelize db:info
+
+env-pass:
+	@echo "ENV" && NODE_ENV=env lib/sequelize db:info --show-password
+
+run: build show
+	@echo "----\n"
+
+loop:
+	while inotifywait -q -e modify src/**; \
+		do clear; make run; done;
+
diff --git a/package.json b/package.json
index 84c743e83..fd6dc7780 100644
--- a/package.json
+++ b/package.json
@@ -59,7 +59,8 @@
     "pretty": "prettier src test --write",
     "prepare": "husky install && npm run build",
     "test-raw": "mocha 'test/**/*.test.js'",
-    "test": "npm run lint && npm run build && npm run test-raw"
+    "test": "npm run lint && npm run build && npm run test-raw",
+    "test-one": "mocha 'test/db/db-info.test.js' --timeout 5000"
   },
   "repository": {
     "type": "git",
diff --git a/test/db/db-info.test.js b/test/db/db-info.test.js
new file mode 100644
index 000000000..618425edf
--- /dev/null
+++ b/test/db/db-info.test.js
@@ -0,0 +1,74 @@
+const expect = require('expect.js');
+const Support = require(__dirname + '/../support');
+const helpers = require(__dirname + '/../support/helpers');
+const gulp = require('gulp');
+const _ = require('lodash');
+
+['db:info'].forEach((flag) => {
+  describe(Support.getTestDialectTeaser(flag), function () {
+    this.timeout(5000);
+
+    if (Support.dialectIsPostgres() || Support.dialectIsMySQL()) {
+      console.log("we're testing");
+      const combineFlags = function (flags) {
+        let result = flag;
+
+        _.forEach(flags || {}, (value, key) => {
+          result = result + ' --' + key;
+        });
+
+        return result;
+      };
+
+      const prepare = function (options, callback) {
+        options = _.assign(
+          {
+            flags: {},
+            cli: { pipeStdout: true },
+          },
+          options || {}
+        );
+
+        console.log('fl', combineFlags(options.flags));
+
+        const configPath = 'config/config.json';
+        const config = _.assign(
+          { password: 'secret_password' },
+          helpers.getTestConfig(),
+          options.config
+        );
+        const configContent = JSON.stringify(config);
+
+        gulp
+          .src(Support.resolveSupportPath('tmp'))
+          .pipe(helpers.clearDirectory())
+          .pipe(helpers.runCli('init'))
+          .pipe(helpers.runCli('db:create'))
+          .pipe(
+            // helpers.overwriteFile(helpers.getTestConfig(), 'config/config.json')
+            helpers.overwriteFile(configContent, configPath)
+          )
+          .pipe(helpers.runCli(flag, { pipeStdout: true }))
+          // .pipe(helpers.runCli(combineFlags(options.flags), options.cli))
+          .pipe(helpers.teardown(callback));
+      };
+
+      describe('show-password', function () {
+        it('hides the password', function (done) {
+          prepare({}, (err, stdout) => {
+            expect(stdout).to.contain('password: ***');
+            done();
+          });
+        });
+
+        it.only('reveals the password', function (done) {
+          prepare({ flags: { 'show-password': true } }, done);
+          // prepare({ flags: { showPassword: true } }, (err, stdout) => {
+          //   expect(stdout).not.to.contain('password: ***');
+          //   done();
+          // });
+        });
+      });
+    }
+  });
+});