@gnar-engine/cli 1.0.8 → 1.0.10
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/bootstrap/services/control/src/config.js +2 -1
- package/bootstrap/services/page/src/config.js +5 -0
- package/bootstrap/services/user/src/config.js +1 -0
- package/package.json +1 -1
- package/src/dev/commands.js +1 -1
- package/src/dev/dev.service.js +7 -0
- package/templates/entity/src/services/mysql.{{entityName}}.service.js.hbs +79 -9
- package/templates/service/src/app.js.hbs +3 -7
- package/templates/service/src/mongodb.config.js.hbs +5 -0
- package/templates/service/src/mysql.config.js.hbs +2 -1
- package/templates/service/src/services/mysql.{{serviceName}}.service.js.hbs +78 -13
|
@@ -7,8 +7,9 @@ export const config = {
|
|
|
7
7
|
serviceName: 'controlService',
|
|
8
8
|
|
|
9
9
|
// environment
|
|
10
|
-
environment: process.env.CONTROL_NODE_ENV || '
|
|
10
|
+
environment: process.env.CONTROL_NODE_ENV || 'development',
|
|
11
11
|
runTests: process.env.CONTROL_RUN_TESTS || false,
|
|
12
|
+
resetDatabase: process.env.CONTROL_RESET_DATABASE || false,
|
|
12
13
|
|
|
13
14
|
// microservice | modular-monolith
|
|
14
15
|
architecture: process.env.GLOBAL_ARCHITECTURE || 'microservice',
|
|
@@ -5,6 +5,11 @@ export const config = {
|
|
|
5
5
|
// service name
|
|
6
6
|
serviceName: 'pageService',
|
|
7
7
|
|
|
8
|
+
// environment
|
|
9
|
+
environment: process.env.PAGE_NODE_ENV || 'developnent',
|
|
10
|
+
runTests: process.env.PAGE_RUN_TESTS || false,
|
|
11
|
+
resetDatabase: process.env.PAGE_RESET_DATABASE || false,
|
|
12
|
+
|
|
8
13
|
// microservice | modular-monolith
|
|
9
14
|
architecture: process.env.GLOBAL_ARCHITECTURE || 'microservice',
|
|
10
15
|
|
|
@@ -9,6 +9,7 @@ export const config = {
|
|
|
9
9
|
// environment
|
|
10
10
|
environment: process.env.USER_NODE_ENV || 'dev',
|
|
11
11
|
runTests: process.env.USER_RUN_TESTS || false,
|
|
12
|
+
resetDatabase: process.env.USER_RESET_DATABASE || false,
|
|
12
13
|
|
|
13
14
|
// microservice | modular-monolith
|
|
14
15
|
architecture: process.env.GLOBAL_ARCHITECTURE || 'microservice',
|
package/package.json
CHANGED
package/src/dev/commands.js
CHANGED
|
@@ -15,7 +15,7 @@ export function registerDevCommands(program) {
|
|
|
15
15
|
.option('-a, --attach-all', 'Attach all services including database and message queues for debugging')
|
|
16
16
|
.option('-t --test', 'Run all tests with ephemeral databases *NOT IMPLEMENTED')
|
|
17
17
|
.option('--test-service <service>', 'Run the tests for the specified service with ephemeral databases (e.g. --test-service user)')
|
|
18
|
-
.option('
|
|
18
|
+
.option('--reset-databases, --reset-databases', 'Drop all service databases, re-running all migrations and seeders *NOT IMPLEMENTED')
|
|
19
19
|
.option('--reset-database <service>', 'Drop the specified service database, re-running all migrations and seeders (e.g. --reset-database user)')
|
|
20
20
|
.addOption(new Option('--core-dev').hideHelp())
|
|
21
21
|
.addOption(new Option('--bootstrap-dev').hideHelp())
|
package/src/dev/dev.service.js
CHANGED
|
@@ -430,6 +430,13 @@ async function buildAndUpContainers({
|
|
|
430
430
|
serviceVolumes.push(`${gnarEngineCliConfig.coreDevPath}:${gnarEngineCliConfig.corePath}`);
|
|
431
431
|
}
|
|
432
432
|
|
|
433
|
+
if (svc.extra_binds) {
|
|
434
|
+
svc.extra_binds.forEach((bind, index) => {
|
|
435
|
+
bind = `${gnarHiddenDir}/data/${svc.name}-data/bind-${index}/:${bind}`;
|
|
436
|
+
serviceVolumes.push(bind);
|
|
437
|
+
})
|
|
438
|
+
}
|
|
439
|
+
|
|
433
440
|
// split from "port:port" to { port: port }
|
|
434
441
|
const ports = {};
|
|
435
442
|
for (const portMapping of svc.ports || []) {
|
|
@@ -1,23 +1,93 @@
|
|
|
1
|
-
import { db } from '@gnar-engine/core';
|
|
1
|
+
import { db, utils } from '@gnar-engine/core';
|
|
2
2
|
|
|
3
3
|
export const {{entityName}} = {
|
|
4
4
|
async getById({ id }) {
|
|
5
5
|
const [result] = await db.query('SELECT * FROM {{lowerCasePlural entityName}} WHERE id = ?', [id]);
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
if (!result) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return db.sql.helpers.objectToCamelCase(result);
|
|
7
12
|
},
|
|
8
13
|
|
|
9
|
-
async getAll() {
|
|
10
|
-
|
|
14
|
+
async getAll({ pageSize = 100, pageNum = 1 }) {
|
|
15
|
+
pageSize = Number(pageSize);
|
|
16
|
+
pageNum = Number(pageNum);
|
|
17
|
+
const offset = (pageNum - 1) * pageSize;
|
|
18
|
+
|
|
19
|
+
const [rows] = await db.query(
|
|
20
|
+
'SELECT * FROM {{lowerCasePlural entityName}} LIMIT ? OFFSET ?',
|
|
21
|
+
[pageSize, offset]
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const [[{ total }]] = await db.query(
|
|
25
|
+
'SELECT COUNT(*) AS total FROM {{lowerCasePlural entityName}}'
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
data: rows.map(row => db.sql.helpers.objectToCamelCase(row)),
|
|
30
|
+
pagination: {
|
|
31
|
+
pageSize,
|
|
32
|
+
pageNum,
|
|
33
|
+
total
|
|
34
|
+
}
|
|
35
|
+
}
|
|
11
36
|
},
|
|
12
37
|
|
|
13
38
|
async create(data) {
|
|
14
|
-
const
|
|
15
|
-
|
|
39
|
+
const id = utils.uuid();
|
|
40
|
+
|
|
41
|
+
// map columns and insert
|
|
42
|
+
const columns = ['id', ...Object.keys(data).map(db.sql.helpers.toSnake)];
|
|
43
|
+
const placeholders = columns.map(() => '?');
|
|
44
|
+
const values = [id, ...Object.values(data)];
|
|
45
|
+
|
|
46
|
+
const sql = `
|
|
47
|
+
INSERT INTO {{lowerCasePlural entityName}} (
|
|
48
|
+
${columns.join(', ')},
|
|
49
|
+
created_at,
|
|
50
|
+
updated_at
|
|
51
|
+
)
|
|
52
|
+
VALUES (
|
|
53
|
+
${placeholders.join(', ')},
|
|
54
|
+
CURRENT_TIMESTAMP,
|
|
55
|
+
CURRENT_TIMESTAMP
|
|
56
|
+
)
|
|
57
|
+
`;
|
|
58
|
+
await db.query(sql, [...values, id]);
|
|
59
|
+
|
|
60
|
+
// return result
|
|
61
|
+
const newItem = await this.getById({ id });
|
|
62
|
+
return db.sql.helpers.objectToCamelCase(newItem);
|
|
16
63
|
},
|
|
17
64
|
|
|
18
|
-
async update({ id,
|
|
19
|
-
|
|
20
|
-
|
|
65
|
+
async update({ id, updatedData }) {
|
|
66
|
+
if (!Object.keys(updatedData).length) {
|
|
67
|
+
return this.getById({ id });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Handle many to many relations
|
|
71
|
+
const newOwnerIds = updatedData.ownerIds ? updatedData.ownerIds : null;
|
|
72
|
+
delete updatedData.ownerIds;
|
|
73
|
+
|
|
74
|
+
// map columns and update
|
|
75
|
+
const columns = Object.keys(updatedData).map((key) => db.sql.helpers.toSnake(key));
|
|
76
|
+
const assignments = columns.map(col => `${col} = ?`);
|
|
77
|
+
const values = Object.values(updatedData);
|
|
78
|
+
|
|
79
|
+
const sql = `
|
|
80
|
+
UPDATE {{lowerCasePlural entityName}}
|
|
81
|
+
SET
|
|
82
|
+
${assignments.join(', ')},
|
|
83
|
+
updated_at = CURRENT_TIMESTAMP
|
|
84
|
+
WHERE id = ?
|
|
85
|
+
`;
|
|
86
|
+
await db.query(sql, [...values, id]);
|
|
87
|
+
|
|
88
|
+
// return result
|
|
89
|
+
const newItem = await this.getById({ id });
|
|
90
|
+
return db.sql.helpers.objectToCamelCase(newItem);
|
|
21
91
|
},
|
|
22
92
|
|
|
23
93
|
async delete({ id }) {
|
|
@@ -8,13 +8,9 @@ import { httpController as {{lowerCase serviceName}}PlatformHttpController } fro
|
|
|
8
8
|
*/
|
|
9
9
|
export const initService = async () => {
|
|
10
10
|
|
|
11
|
-
// Run migrations
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Run seeders
|
|
17
|
-
db.seeders.runSeeders({config});
|
|
11
|
+
// Run migrations & seeders
|
|
12
|
+
await db.migrations.runMigrations({config});
|
|
13
|
+
await db.seeders.runSeeders({config});
|
|
18
14
|
|
|
19
15
|
// Import command handlers after the command bus is initialised
|
|
20
16
|
await import('./commands/{{lowerCase serviceName}}.handler.js');
|
|
@@ -5,6 +5,11 @@ export const config = {
|
|
|
5
5
|
// service name
|
|
6
6
|
serviceName: '{{serviceName}}Service',
|
|
7
7
|
|
|
8
|
+
// environment
|
|
9
|
+
environment: process.env.{{upperCase serviceName}}_NODE_ENV || 'development',
|
|
10
|
+
runTests: process.env.{{upperCase serviceName}}_RUN_TESTS || false,
|
|
11
|
+
resetDatabase: process.env.{{upperCase serviceName}}_RESET_DATABASE || false,
|
|
12
|
+
|
|
8
13
|
// microservice | modular-monolith
|
|
9
14
|
architecture: process.env.GLOBAL_ARCHITECTURE || 'microservice',
|
|
10
15
|
|
|
@@ -6,8 +6,9 @@ export const config = {
|
|
|
6
6
|
serviceName: '{{serviceName}}Service',
|
|
7
7
|
|
|
8
8
|
// environment
|
|
9
|
-
environment: process.env.{{upperCase serviceName}}_NODE_ENV || '
|
|
9
|
+
environment: process.env.{{upperCase serviceName}}_NODE_ENV || 'development',
|
|
10
10
|
runTests: process.env.{{upperCase serviceName}}_RUN_TESTS || false,
|
|
11
|
+
resetDatabase: process.env.{{upperCase serviceName}}_RESET_DATABASE || false,
|
|
11
12
|
|
|
12
13
|
// microservice | modular-monolith
|
|
13
14
|
architecture: process.env.GLOBAL_ARCHITECTURE || 'microservice',
|
|
@@ -1,28 +1,93 @@
|
|
|
1
|
-
import { db } from '@gnar-engine/core';
|
|
1
|
+
import { db, utils } from '@gnar-engine/core';
|
|
2
2
|
|
|
3
3
|
export const {{serviceName}} = {
|
|
4
4
|
async getById({ id }) {
|
|
5
5
|
const [result] = await db.query('SELECT * FROM {{lowerCasePlural serviceName}} WHERE id = ?', [id]);
|
|
6
|
-
return result || null;
|
|
7
|
-
},
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
if (!result) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return db.sql.helpers.objectToCamelCase(result);
|
|
12
12
|
},
|
|
13
13
|
|
|
14
|
-
async getAll() {
|
|
15
|
-
|
|
14
|
+
async getAll({ pageSize = 100, pageNum = 1 }) {
|
|
15
|
+
pageSize = Number(pageSize);
|
|
16
|
+
pageNum = Number(pageNum);
|
|
17
|
+
const offset = (pageNum - 1) * pageSize;
|
|
18
|
+
|
|
19
|
+
const [rows] = await db.query(
|
|
20
|
+
'SELECT * FROM {{lowerCasePlural serviceName}} LIMIT ? OFFSET ?',
|
|
21
|
+
[pageSize, offset]
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const [[{ total }]] = await db.query(
|
|
25
|
+
'SELECT COUNT(*) AS total FROM {{lowerCasePlural serviceName}}'
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
data: rows.map(row => db.sql.helpers.objectToCamelCase(row)),
|
|
30
|
+
pagination: {
|
|
31
|
+
pageSize,
|
|
32
|
+
pageNum,
|
|
33
|
+
total
|
|
34
|
+
}
|
|
35
|
+
}
|
|
16
36
|
},
|
|
17
37
|
|
|
18
38
|
async create(data) {
|
|
19
|
-
const
|
|
20
|
-
|
|
39
|
+
const id = utils.uuid();
|
|
40
|
+
|
|
41
|
+
// map columns and insert
|
|
42
|
+
const columns = ['id', ...Object.keys(data).map(db.sql.helpers.toSnake)];
|
|
43
|
+
const placeholders = columns.map(() => '?');
|
|
44
|
+
const values = [id, ...Object.values(data)];
|
|
45
|
+
|
|
46
|
+
const sql = `
|
|
47
|
+
INSERT INTO {{lowerCasePlural serviceName}} (
|
|
48
|
+
${columns.join(', ')},
|
|
49
|
+
created_at,
|
|
50
|
+
updated_at
|
|
51
|
+
)
|
|
52
|
+
VALUES (
|
|
53
|
+
${placeholders.join(', ')},
|
|
54
|
+
CURRENT_TIMESTAMP,
|
|
55
|
+
CURRENT_TIMESTAMP
|
|
56
|
+
)
|
|
57
|
+
`;
|
|
58
|
+
await db.query(sql, [...values, id]);
|
|
59
|
+
|
|
60
|
+
// return result
|
|
61
|
+
const newItem = await this.getById({ id });
|
|
62
|
+
return db.sql.helpers.objectToCamelCase(newItem);
|
|
21
63
|
},
|
|
22
64
|
|
|
23
|
-
async update({ id,
|
|
24
|
-
|
|
25
|
-
|
|
65
|
+
async update({ id, updatedData }) {
|
|
66
|
+
if (!Object.keys(updatedData).length) {
|
|
67
|
+
return this.getById({ id });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Handle many to many relations
|
|
71
|
+
const newOwnerIds = updatedData.ownerIds ? updatedData.ownerIds : null;
|
|
72
|
+
delete updatedData.ownerIds;
|
|
73
|
+
|
|
74
|
+
// map columns and update
|
|
75
|
+
const columns = Object.keys(updatedData).map((key) => db.sql.helpers.toSnake(key));
|
|
76
|
+
const assignments = columns.map(col => `${col} = ?`);
|
|
77
|
+
const values = Object.values(updatedData);
|
|
78
|
+
|
|
79
|
+
const sql = `
|
|
80
|
+
UPDATE {{lowerCasePlural serviceName}}
|
|
81
|
+
SET
|
|
82
|
+
${assignments.join(', ')},
|
|
83
|
+
updated_at = CURRENT_TIMESTAMP
|
|
84
|
+
WHERE id = ?
|
|
85
|
+
`;
|
|
86
|
+
await db.query(sql, [...values, id]);
|
|
87
|
+
|
|
88
|
+
// return result
|
|
89
|
+
const newItem = await this.getById({ id });
|
|
90
|
+
return db.sql.helpers.objectToCamelCase(newItem);
|
|
26
91
|
},
|
|
27
92
|
|
|
28
93
|
async delete({ id }) {
|