millas 0.2.27 → 0.2.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/millas.js +12 -2
- package/package.json +2 -1
- package/src/cli.js +117 -20
- package/src/commands/call.js +1 -1
- package/src/commands/createsuperuser.js +137 -182
- package/src/commands/key.js +61 -83
- package/src/commands/lang.js +423 -515
- package/src/commands/make.js +88 -62
- package/src/commands/migrate.js +200 -279
- package/src/commands/new.js +55 -50
- package/src/commands/route.js +78 -80
- package/src/commands/schedule.js +52 -150
- package/src/commands/serve.js +158 -191
- package/src/console/AppCommand.js +106 -0
- package/src/console/BaseCommand.js +726 -0
- package/src/console/CommandContext.js +66 -0
- package/src/console/CommandRegistry.js +88 -0
- package/src/console/Style.js +123 -0
- package/src/console/index.js +12 -3
- package/src/container/AppInitializer.js +10 -0
- package/src/container/Application.js +2 -0
- package/src/facades/DB.js +195 -0
- package/src/index.js +2 -1
- package/src/scaffold/maker.js +102 -42
- package/src/schematics/Collection.js +28 -0
- package/src/schematics/SchematicEngine.js +122 -0
- package/src/schematics/Template.js +99 -0
- package/src/schematics/index.js +7 -0
- package/src/templates/command/default.template.js +14 -0
- package/src/templates/command/schema.json +19 -0
- package/src/templates/controller/default.template.js +10 -0
- package/src/templates/controller/resource.template.js +59 -0
- package/src/templates/controller/schema.json +30 -0
- package/src/templates/job/default.template.js +11 -0
- package/src/templates/job/schema.json +19 -0
- package/src/templates/middleware/default.template.js +11 -0
- package/src/templates/middleware/schema.json +19 -0
- package/src/templates/migration/default.template.js +14 -0
- package/src/templates/migration/schema.json +19 -0
- package/src/templates/model/default.template.js +14 -0
- package/src/templates/model/migration.template.js +17 -0
- package/src/templates/model/schema.json +30 -0
- package/src/templates/service/default.template.js +12 -0
- package/src/templates/service/schema.json +19 -0
- package/src/templates/shape/default.template.js +11 -0
- package/src/templates/shape/schema.json +19 -0
- package/src/validation/BaseValidator.js +3 -0
- package/src/validation/types.js +3 -3
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Command Context
|
|
5
|
+
* Encapsulates all dependencies and configuration for CLI commands
|
|
6
|
+
*/
|
|
7
|
+
class CommandContext {
|
|
8
|
+
constructor(options = {}) {
|
|
9
|
+
this.program = options.program;
|
|
10
|
+
this.container = options.container || null;
|
|
11
|
+
this.config = options.config || {};
|
|
12
|
+
this.logger = options.logger || console;
|
|
13
|
+
this.cwd = options.cwd || process.cwd();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Set the DI container (lazy loaded after app bootstrap)
|
|
18
|
+
*/
|
|
19
|
+
setContainer(container) {
|
|
20
|
+
this.container = container;
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Set configuration
|
|
26
|
+
*/
|
|
27
|
+
setConfig(config) {
|
|
28
|
+
this.config = config;
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get a service from the container
|
|
34
|
+
*/
|
|
35
|
+
resolve(serviceName) {
|
|
36
|
+
if (!this.container) {
|
|
37
|
+
throw new Error('Container not initialized. Cannot resolve services.');
|
|
38
|
+
}
|
|
39
|
+
return this.container.resolve(serviceName);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Check if running inside a Millas project
|
|
44
|
+
*/
|
|
45
|
+
isMillasProject() {
|
|
46
|
+
const fs = require('fs');
|
|
47
|
+
const path = require('path');
|
|
48
|
+
|
|
49
|
+
const pkgPath = path.join(this.cwd, 'package.json');
|
|
50
|
+
if (!fs.existsSync(pkgPath)) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
56
|
+
// Check for millas marker in package.json
|
|
57
|
+
return pkg.millas === true ||
|
|
58
|
+
(pkg.dependencies && 'millas' in pkg.dependencies) ||
|
|
59
|
+
(pkg.devDependencies && 'millas' in pkg.devDependencies);
|
|
60
|
+
} catch {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = CommandContext;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const chalk = require('chalk');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Command Registry
|
|
9
|
+
* Auto-discovers and registers all commands
|
|
10
|
+
*/
|
|
11
|
+
class CommandRegistry {
|
|
12
|
+
constructor(context) {
|
|
13
|
+
this.context = context;
|
|
14
|
+
this.commands = new Map();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Discover and load all commands from a directory
|
|
19
|
+
*/
|
|
20
|
+
async discoverCommands(commandsDir) {
|
|
21
|
+
if (!require('fs').existsSync(commandsDir)) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const fs = require('fs').promises;
|
|
26
|
+
const files = (await fs.readdir(commandsDir))
|
|
27
|
+
.filter(file => file.endsWith('.js') && file !== 'index.js');
|
|
28
|
+
|
|
29
|
+
for (const file of files) {
|
|
30
|
+
const commandPath = path.join(commandsDir, file);
|
|
31
|
+
try {
|
|
32
|
+
await this.loadCommand(commandPath);
|
|
33
|
+
} catch (err) {
|
|
34
|
+
console.log(err)
|
|
35
|
+
console.error(chalk.yellow(` ⚠ Failed to load command: ${file}`));
|
|
36
|
+
if (process.env.APP_DEBUG) {
|
|
37
|
+
console.error(err);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Load a single command file
|
|
45
|
+
*/
|
|
46
|
+
async loadCommand(commandPath) {
|
|
47
|
+
const CommandClass = require(commandPath);
|
|
48
|
+
const BaseCommand = require('./BaseCommand');
|
|
49
|
+
|
|
50
|
+
// Support both class-based and function-based commands
|
|
51
|
+
if (typeof CommandClass === 'function') {
|
|
52
|
+
// Check if it's a class extending BaseCommand
|
|
53
|
+
if (CommandClass.prototype instanceof BaseCommand) {
|
|
54
|
+
const commandInstance = new CommandClass(this.context);
|
|
55
|
+
await commandInstance.register(); // Now async
|
|
56
|
+
this.commands.set(commandPath, commandInstance);
|
|
57
|
+
}
|
|
58
|
+
// Legacy function-based command (backward compatibility)
|
|
59
|
+
// else if (CommandClass.length === 1) { // expects (program) argument
|
|
60
|
+
// CommandClass(this.context.program);
|
|
61
|
+
// this.commands.set(commandPath, CommandClass);
|
|
62
|
+
// }
|
|
63
|
+
// Invalid command export
|
|
64
|
+
// else {
|
|
65
|
+
// throw new Error(`Invalid command export in ${commandPath}. Must extend BaseCommand or export function(program).`);
|
|
66
|
+
// }
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Register commands from app/commands/ (user-defined commands)
|
|
72
|
+
*/
|
|
73
|
+
async discoverUserCommands() {
|
|
74
|
+
const userCommandsDir = path.join(this.context.cwd, 'app', 'commands');
|
|
75
|
+
if (require('fs').existsSync(userCommandsDir)) {
|
|
76
|
+
await this.discoverCommands(userCommandsDir);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get all registered commands
|
|
82
|
+
*/
|
|
83
|
+
getCommands() {
|
|
84
|
+
return Array.from(this.commands.values());
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = CommandRegistry;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Bootstrap-inspired styling system for CLI output
|
|
7
|
+
* Provides consistent theming across all commands
|
|
8
|
+
*/
|
|
9
|
+
class Style {
|
|
10
|
+
// Bootstrap-style variants
|
|
11
|
+
success(text) {
|
|
12
|
+
return chalk.green(text);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
danger(text) {
|
|
16
|
+
return chalk.red(text);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
warning(text) {
|
|
20
|
+
return chalk.yellow(text);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
info(text) {
|
|
24
|
+
return chalk.cyan(text);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
primary(text) {
|
|
28
|
+
return chalk.blue(text);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
secondary(text) {
|
|
32
|
+
return chalk.gray(text);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
muted(text) {
|
|
36
|
+
return chalk.dim(text);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
light(text) {
|
|
40
|
+
return chalk.white(text);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
dark(text) {
|
|
44
|
+
return chalk.black(text);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Text styles
|
|
48
|
+
bold(text) {
|
|
49
|
+
return chalk.bold(text);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
italic(text) {
|
|
53
|
+
return chalk.italic(text);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
underline(text) {
|
|
57
|
+
return chalk.underline(text);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// HTTP method colors
|
|
61
|
+
method(verb) {
|
|
62
|
+
const colors = {
|
|
63
|
+
GET: chalk.green,
|
|
64
|
+
POST: chalk.blue,
|
|
65
|
+
PUT: chalk.yellow,
|
|
66
|
+
PATCH: chalk.magenta,
|
|
67
|
+
DELETE: chalk.red,
|
|
68
|
+
};
|
|
69
|
+
return colors[verb] || chalk.white;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Status indicators
|
|
73
|
+
checkmark(text = '') {
|
|
74
|
+
return chalk.green(`✔ ${text}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
cross(text = '') {
|
|
78
|
+
return chalk.red(`✖ ${text}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
bullet(text = '') {
|
|
82
|
+
return chalk.cyan(`• ${text}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
arrow(text = '') {
|
|
86
|
+
return chalk.cyan(`→ ${text}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Borders and separators
|
|
90
|
+
line(length = 80, char = '─') {
|
|
91
|
+
return chalk.gray(char.repeat(length));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Badges
|
|
95
|
+
badge(text, variant = 'primary') {
|
|
96
|
+
const styles = {
|
|
97
|
+
success: chalk.bgGreen.black,
|
|
98
|
+
danger: chalk.bgRed.white,
|
|
99
|
+
warning: chalk.bgYellow.black,
|
|
100
|
+
info: chalk.bgCyan.black,
|
|
101
|
+
primary: chalk.bgBlue.white,
|
|
102
|
+
secondary: chalk.bgGray.white,
|
|
103
|
+
};
|
|
104
|
+
const style = styles[variant] || styles.primary;
|
|
105
|
+
return style(` ${text} `);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Code/path highlighting
|
|
109
|
+
code(text) {
|
|
110
|
+
return chalk.cyan(text);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
path(text) {
|
|
114
|
+
return chalk.cyan(text);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Key-value pairs
|
|
118
|
+
kv(key, value) {
|
|
119
|
+
return `${chalk.dim(key)}: ${chalk.white(value)}`;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
module.exports = Style;
|
package/src/console/index.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const Command
|
|
4
|
-
const CommandLoader
|
|
3
|
+
const Command = require('./Command');
|
|
4
|
+
const CommandLoader = require('./CommandLoader');
|
|
5
|
+
const BaseCommand = require('./BaseCommand');
|
|
6
|
+
const CommandContext = require('./CommandContext');
|
|
7
|
+
const CommandRegistry = require('./CommandRegistry');
|
|
5
8
|
|
|
6
|
-
module.exports = {
|
|
9
|
+
module.exports = {
|
|
10
|
+
Command,
|
|
11
|
+
CommandLoader,
|
|
12
|
+
BaseCommand,
|
|
13
|
+
CommandContext,
|
|
14
|
+
CommandRegistry
|
|
15
|
+
};
|
|
@@ -72,6 +72,16 @@ class AppInitializer {
|
|
|
72
72
|
* @returns {Application} the booted kernel
|
|
73
73
|
*/
|
|
74
74
|
async bootKernel() {
|
|
75
|
+
// Load .env if not running via CLI (CLI loads it in src/cli.js)
|
|
76
|
+
if (!process.env.MILLAS_CLI_MODE) {
|
|
77
|
+
const path = require('path');
|
|
78
|
+
const fs = require('fs');
|
|
79
|
+
const envPath = path.resolve(process.cwd(), '.env');
|
|
80
|
+
if (fs.existsSync(envPath)) {
|
|
81
|
+
require('dotenv').config({ path: envPath, override: false });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
75
85
|
const cfg = this._config;
|
|
76
86
|
const basePath = cfg.basePath || process.cwd();
|
|
77
87
|
|
|
@@ -176,7 +176,9 @@ class Application {
|
|
|
176
176
|
|| 3000;
|
|
177
177
|
const _host = host || 'localhost';
|
|
178
178
|
|
|
179
|
+
|
|
179
180
|
await this._adapter.listen(_port, _host);
|
|
181
|
+
console.log(_host,_port)
|
|
180
182
|
|
|
181
183
|
if (process.env.APP_ENV === "development" && process.env.MILLAS_START_UP && !process.env.MILLERS_NODE_ENV) {
|
|
182
184
|
this._printStartupLog(_host, _port);
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* DB Facade - Django-style database access
|
|
8
|
+
*
|
|
9
|
+
* Auto-configures on first use by loading config/database.js
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* const DB = require('millas/src/facades/DB');
|
|
13
|
+
*
|
|
14
|
+
* // Query builder
|
|
15
|
+
* const users = await DB.table('users').where('active', true).get();
|
|
16
|
+
*
|
|
17
|
+
* // Raw queries
|
|
18
|
+
* const result = await DB.select('SELECT * FROM users WHERE id = ?', [1]);
|
|
19
|
+
*
|
|
20
|
+
* // Transactions
|
|
21
|
+
* await DB.transaction(async (trx) => {
|
|
22
|
+
* await trx('users').insert({ name: 'John' });
|
|
23
|
+
* await trx('posts').insert({ title: 'Hello' });
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // Direct connection
|
|
27
|
+
* const db = DB.connection();
|
|
28
|
+
* await db('users').select('*');
|
|
29
|
+
*/
|
|
30
|
+
class DBFacade {
|
|
31
|
+
constructor() {
|
|
32
|
+
this._manager = null;
|
|
33
|
+
this._configured = false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Get the DatabaseManager instance (auto-configures if needed)
|
|
38
|
+
*/
|
|
39
|
+
_getManager() {
|
|
40
|
+
if (!this._configured) {
|
|
41
|
+
this._configure();
|
|
42
|
+
}
|
|
43
|
+
return this._manager;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Auto-configure by loading config/database.js
|
|
48
|
+
*/
|
|
49
|
+
_configure() {
|
|
50
|
+
if (this._configured) return;
|
|
51
|
+
|
|
52
|
+
// Try to find config/database.js from current working directory
|
|
53
|
+
const configPath = path.resolve(process.cwd(), 'config/database.js');
|
|
54
|
+
|
|
55
|
+
if (!fs.existsSync(configPath)) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
'config/database.js not found. Make sure you are in a Millas project directory.'
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const config = require(configPath);
|
|
62
|
+
this._manager = require('../orm/drivers/DatabaseManager');
|
|
63
|
+
this._manager.configure(config);
|
|
64
|
+
this._configured = true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get a database connection
|
|
69
|
+
* @param {string} name - Connection name (optional, uses default if not provided)
|
|
70
|
+
*/
|
|
71
|
+
connection(name) {
|
|
72
|
+
return this._getManager().connection(name);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Get the default connection
|
|
77
|
+
*/
|
|
78
|
+
get db() {
|
|
79
|
+
return this._getManager().db;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Query builder for a table (Laravel: DB::table('users'))
|
|
84
|
+
* @param {string} tableName
|
|
85
|
+
*/
|
|
86
|
+
table(tableName) {
|
|
87
|
+
return this._getManager().table(tableName);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Execute raw SQL SELECT
|
|
92
|
+
* @param {string} sql
|
|
93
|
+
* @param {Array} bindings
|
|
94
|
+
*/
|
|
95
|
+
async select(sql, bindings = []) {
|
|
96
|
+
return this._getManager().select(sql, bindings);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Execute INSERT
|
|
101
|
+
* @param {string} sql
|
|
102
|
+
* @param {Array} bindings
|
|
103
|
+
*/
|
|
104
|
+
async insert(sql, bindings = []) {
|
|
105
|
+
return this._getManager().insert(sql, bindings);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Execute UPDATE
|
|
110
|
+
* @param {string} sql
|
|
111
|
+
* @param {Array} bindings
|
|
112
|
+
*/
|
|
113
|
+
async update(sql, bindings = []) {
|
|
114
|
+
return this._getManager().update(sql, bindings);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Execute DELETE
|
|
119
|
+
* @param {string} sql
|
|
120
|
+
* @param {Array} bindings
|
|
121
|
+
*/
|
|
122
|
+
async delete(sql, bindings = []) {
|
|
123
|
+
return this._getManager().delete(sql, bindings);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Execute raw SQL
|
|
128
|
+
* @param {string} sql
|
|
129
|
+
* @param {Array} bindings
|
|
130
|
+
*/
|
|
131
|
+
async raw(sql, bindings = []) {
|
|
132
|
+
return this._getManager().raw(sql, bindings);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Run queries in a transaction
|
|
137
|
+
* @param {Function} callback
|
|
138
|
+
*/
|
|
139
|
+
async transaction(callback) {
|
|
140
|
+
return this._getManager().transaction(callback);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Begin a transaction manually
|
|
145
|
+
*/
|
|
146
|
+
async beginTransaction() {
|
|
147
|
+
return this._getManager().beginTransaction();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Execute a statement
|
|
152
|
+
* @param {string} sql
|
|
153
|
+
* @param {Array} bindings
|
|
154
|
+
*/
|
|
155
|
+
async statement(sql, bindings = []) {
|
|
156
|
+
return this._getManager().statement(sql, bindings);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Execute unprepared statement
|
|
161
|
+
* @param {string} sql
|
|
162
|
+
*/
|
|
163
|
+
async unprepared(sql) {
|
|
164
|
+
return this._getManager().unprepared(sql);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Get schema builder
|
|
169
|
+
*/
|
|
170
|
+
get schema() {
|
|
171
|
+
return this._getManager().schema;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Close all database connections
|
|
176
|
+
*/
|
|
177
|
+
async closeAll() {
|
|
178
|
+
if (this._manager) {
|
|
179
|
+
await this._manager.closeAll();
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Close a specific connection
|
|
185
|
+
* @param {string} name
|
|
186
|
+
*/
|
|
187
|
+
async close(name) {
|
|
188
|
+
if (this._manager) {
|
|
189
|
+
await this._manager.close(name);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Export singleton instance
|
|
195
|
+
module.exports = new DBFacade();
|