@cyklang/cli 0.1.0
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/README.md +1 -0
- package/aws-ecs.env +38 -0
- package/build/Cmd.d.ts +7 -0
- package/build/Cmd.js +35 -0
- package/build/DBClient.d.ts +10 -0
- package/build/DBClient.js +205 -0
- package/build/InitCommand.d.ts +9 -0
- package/build/InitCommand.js +122 -0
- package/build/ModuleCommand.d.ts +5 -0
- package/build/ModuleCommand.js +202 -0
- package/build/NodeCrypto.d.ts +5 -0
- package/build/NodeCrypto.js +49 -0
- package/build/QueryCommand.d.ts +5 -0
- package/build/QueryCommand.js +62 -0
- package/build/RunCommand.d.ts +5 -0
- package/build/RunCommand.js +112 -0
- package/build/TableCommand.d.ts +5 -0
- package/build/TableCommand.js +140 -0
- package/build/TestCommand copy.d.ts +5 -0
- package/build/TestCommand copy.js +111 -0
- package/build/TestCommand.d.ts +5 -0
- package/build/TestCommand.js +111 -0
- package/build/UserCommand.d.ts +5 -0
- package/build/UserCommand.js +202 -0
- package/build/console.d.ts +13 -0
- package/build/console.js +109 -0
- package/build/cykquery.d.ts +2 -0
- package/build/cykquery.js +145 -0
- package/build/cyktable.d.ts +2 -0
- package/build/cyktable.js +133 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +32 -0
- package/build/module.d.ts +2 -0
- package/build/module.js +290 -0
- package/docker-compose.ecs.yml +44 -0
- package/docker-compose.yml +43 -0
- package/docker.env +38 -0
- package/package.json +38 -0
- package/src/Cmd.ts +33 -0
- package/src/DBClient.ts +220 -0
- package/src/InitCommand.ts +107 -0
- package/src/ModuleCommand.ts +192 -0
- package/src/NodeCrypto.ts +60 -0
- package/src/QueryCommand.ts +62 -0
- package/src/RunCommand.ts +98 -0
- package/src/TableCommand.ts +127 -0
- package/src/TestCommand.ts +98 -0
- package/src/UserCommand.ts +203 -0
- package/src/console.ts +97 -0
- package/src/index.ts +30 -0
- package/tsconfig.json +12 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# cyk-cli
|
package/aws-ecs.env
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# PostgreSql connection
|
|
2
|
+
# used by psql command line utility
|
|
3
|
+
PGHOST="localhost"
|
|
4
|
+
PGPORT="5432"
|
|
5
|
+
PGUSER="postgres"
|
|
6
|
+
PGPASSWORD="postgres"
|
|
7
|
+
|
|
8
|
+
# at postgresql database initialization
|
|
9
|
+
|
|
10
|
+
# POSTGRES_USER="postgres"
|
|
11
|
+
POSTGRES_PASSWORD="postgres"
|
|
12
|
+
|
|
13
|
+
# admin user
|
|
14
|
+
# created at database initialization
|
|
15
|
+
ADMIN_NAME=cyk
|
|
16
|
+
ADMIN_PASSWORD=cyk
|
|
17
|
+
ADMIN_EMAIL=my-email@my-domain
|
|
18
|
+
|
|
19
|
+
# JWT token generation
|
|
20
|
+
# https://www.allkeysgenerator.com
|
|
21
|
+
# 128 bits Hex
|
|
22
|
+
|
|
23
|
+
SECRET_TOKEN="423F4428472B4B6250655368566D5971"
|
|
24
|
+
SECRET_RTOKEN="743777217A25432A46294A404E635266"
|
|
25
|
+
|
|
26
|
+
# Login Page Config
|
|
27
|
+
LOGIN_IMAGE="https://media.smartbox.com/pim/1000001967971201770883.jpg?thumbor=800x0/filters:quality(90)"
|
|
28
|
+
LOGIN_TITLE="CYK Framework"
|
|
29
|
+
LOGIN_SUBTITLE="Une application pilote du framework CYK"
|
|
30
|
+
LOGIN_APPLI="accounting"
|
|
31
|
+
|
|
32
|
+
# credential used by cyk CLI
|
|
33
|
+
|
|
34
|
+
USER_NAME=cyk
|
|
35
|
+
USER_PASSWORD=cyk
|
|
36
|
+
CYK_PORT="3000"
|
|
37
|
+
DBREMOTE_URL="http://localhost:3000"
|
|
38
|
+
|
package/build/Cmd.d.ts
ADDED
package/build/Cmd.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Cmd = void 0;
|
|
7
|
+
const core_1 = require("@cyklang/core");
|
|
8
|
+
const commander_1 = require("commander");
|
|
9
|
+
const dotenv_1 = __importDefault(require("dotenv"));
|
|
10
|
+
const loglevel_1 = __importDefault(require("loglevel"));
|
|
11
|
+
const NodeCrypto_1 = require("./NodeCrypto");
|
|
12
|
+
const logger = loglevel_1.default.getLogger('Cmd.ts');
|
|
13
|
+
logger.setLevel('debug');
|
|
14
|
+
class Cmd extends commander_1.Command {
|
|
15
|
+
constructor(name) {
|
|
16
|
+
super(name);
|
|
17
|
+
this.option('--env <env>', 'path to the environment variables file');
|
|
18
|
+
}
|
|
19
|
+
async prologue(options) {
|
|
20
|
+
const dotenvOutput = dotenv_1.default.config({ path: options.env });
|
|
21
|
+
if (dotenvOutput.error !== undefined)
|
|
22
|
+
throw dotenvOutput.error;
|
|
23
|
+
const structure = new core_1.Structure();
|
|
24
|
+
if (process.env.DBREMOTE_URL === undefined)
|
|
25
|
+
throw 'DBREMOTE_URL undefined';
|
|
26
|
+
logger.debug('DBREMOTE_URL ' + process.env.DBREMOTE_URL);
|
|
27
|
+
const nodeCrypto = new NodeCrypto_1.NodeCrypto();
|
|
28
|
+
const dbRemote = new core_1.DBRemote(structure.scope, process.env.DBREMOTE_URL, nodeCrypto);
|
|
29
|
+
const login = await dbRemote.signin(process.env.USER_NAME, undefined, process.env.USER_PASSWORD);
|
|
30
|
+
// logger.debug(login)
|
|
31
|
+
this.dbManager = new core_1.DBManager(structure.scope, dbRemote);
|
|
32
|
+
await this.dbManager.initialize();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.Cmd = Cmd;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DBManager } from "@cyklang/core";
|
|
2
|
+
export declare class DBClient {
|
|
3
|
+
dbManager: DBManager;
|
|
4
|
+
constructor(dbManager: DBManager);
|
|
5
|
+
selectFromTable(title: string, tableName: string, options: {
|
|
6
|
+
fields: string;
|
|
7
|
+
sort?: string | undefined;
|
|
8
|
+
where?: string | undefined;
|
|
9
|
+
}): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DBClient = void 0;
|
|
7
|
+
const core_1 = require("@cyklang/core");
|
|
8
|
+
const loglevel_1 = __importDefault(require("loglevel"));
|
|
9
|
+
const logger = loglevel_1.default.getLogger('DBClient.ts');
|
|
10
|
+
logger.setLevel('debug');
|
|
11
|
+
// DBManager wrapper class
|
|
12
|
+
class DBClient {
|
|
13
|
+
constructor(dbManager) {
|
|
14
|
+
this.dbManager = dbManager;
|
|
15
|
+
}
|
|
16
|
+
async selectFromTable(title, tableName, options) {
|
|
17
|
+
try {
|
|
18
|
+
const objectDataType = this.dbManager.scope.structure.objectDataType;
|
|
19
|
+
const stringDataType = this.dbManager.scope.structure.stringDataType;
|
|
20
|
+
const request = new core_1.DBExecuteRequest();
|
|
21
|
+
request.selectFromTable = tableName;
|
|
22
|
+
request.parameters.addVariable('fields', stringDataType).data = new core_1.PrimitiveData(stringDataType, options.fields);
|
|
23
|
+
request.parameters.addVariable('where', stringDataType).data = new core_1.PrimitiveData(stringDataType, options.where);
|
|
24
|
+
if (options.sort !== undefined) {
|
|
25
|
+
const colnames = options.fields.split(',');
|
|
26
|
+
const sortcols = options.sort.split(',');
|
|
27
|
+
let order_by = '';
|
|
28
|
+
for (let ind = 0; ind < sortcols.length; ind++) {
|
|
29
|
+
const coli = sortcols[ind];
|
|
30
|
+
const colname = colnames[Number(coli)];
|
|
31
|
+
if (order_by !== '')
|
|
32
|
+
order_by += ',';
|
|
33
|
+
order_by += colname;
|
|
34
|
+
}
|
|
35
|
+
logger.debug('order_by ' + order_by);
|
|
36
|
+
request.parameters.addVariable('order_by', stringDataType).data = new core_1.PrimitiveData(stringDataType, order_by);
|
|
37
|
+
}
|
|
38
|
+
// if (options !== undefined) {
|
|
39
|
+
// Object.entries(options).forEach(([key, value]) => {
|
|
40
|
+
// const data = new PrimitiveData(stringDataType, value)
|
|
41
|
+
// request.parameters.addVariable(key, stringDataType).data = data
|
|
42
|
+
// })
|
|
43
|
+
// }
|
|
44
|
+
const xmlResult = await this.dbManager.dbExecute(request);
|
|
45
|
+
if (xmlResult === undefined)
|
|
46
|
+
throw 'xmlResult undefined';
|
|
47
|
+
const tagXmlResult = (0, core_1.parseXML)('xmlResult', xmlResult);
|
|
48
|
+
const objXmlResult = (await objectDataType.parseData(tagXmlResult, this.dbManager.scope));
|
|
49
|
+
const objectMeta = (objXmlResult.variables.getData('meta'));
|
|
50
|
+
if (objectMeta === undefined)
|
|
51
|
+
throw 'objectMeta not found';
|
|
52
|
+
const xmlMeta = objectMeta.variables.getString(tableName);
|
|
53
|
+
if (xmlMeta === undefined)
|
|
54
|
+
throw 'meta does not have ' + tableName + ' description';
|
|
55
|
+
const tagDBTable = (0, core_1.parseXML)('dbTable', xmlMeta);
|
|
56
|
+
const dbTable = new core_1.DBTable(tagDBTable);
|
|
57
|
+
const fields = options.fields.split(',');
|
|
58
|
+
const list = new List();
|
|
59
|
+
for (let ind = 0; ind < fields.length; ind++) {
|
|
60
|
+
const field = fields[ind];
|
|
61
|
+
const dbColumn = dbTable.columns.filter((dbColumn) => dbColumn.name === field)[0];
|
|
62
|
+
if (dbColumn === undefined)
|
|
63
|
+
throw 'field ' + field + ' not found';
|
|
64
|
+
list.addDBColumn(dbColumn);
|
|
65
|
+
}
|
|
66
|
+
const objDataset = objXmlResult.variables.getData(tableName);
|
|
67
|
+
for (let ind = 0; ind < objDataset.variables.length(); ind++) {
|
|
68
|
+
const record = objDataset.variables.at(ind)?.data;
|
|
69
|
+
list.addObjectData(record);
|
|
70
|
+
}
|
|
71
|
+
logger.info(list.renderList(title));
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
logger.error(err);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.DBClient = DBClient;
|
|
79
|
+
class List {
|
|
80
|
+
constructor() {
|
|
81
|
+
this.columns = [];
|
|
82
|
+
this.rows = [];
|
|
83
|
+
this.lines = [];
|
|
84
|
+
this.currentLine = '';
|
|
85
|
+
}
|
|
86
|
+
addDBColumn(dbColumn) {
|
|
87
|
+
const col = new Column(dbColumn.name);
|
|
88
|
+
col.label = dbColumn.label || dbColumn.name;
|
|
89
|
+
col.dbColumn = dbColumn;
|
|
90
|
+
this.columns.push(col);
|
|
91
|
+
}
|
|
92
|
+
addObjectData(objectData) {
|
|
93
|
+
const cells = [];
|
|
94
|
+
this.columns.forEach((column) => {
|
|
95
|
+
let cell = undefined;
|
|
96
|
+
const data = objectData.variables.getData(column.name);
|
|
97
|
+
if (data !== undefined && data !== null) {
|
|
98
|
+
cell = data.value;
|
|
99
|
+
}
|
|
100
|
+
cells.push(cell);
|
|
101
|
+
});
|
|
102
|
+
this.rows.push(new Row(cells));
|
|
103
|
+
}
|
|
104
|
+
renderList(title) {
|
|
105
|
+
// calculate column.width
|
|
106
|
+
let total_width = 0;
|
|
107
|
+
for (let indi = 0; indi < this.columns.length; indi++) {
|
|
108
|
+
const column = this.columns[indi];
|
|
109
|
+
column.width = column.label.length;
|
|
110
|
+
this.rows.forEach((row) => {
|
|
111
|
+
const cell = row.cells[indi];
|
|
112
|
+
const renderedCell = this.renderCell(cell);
|
|
113
|
+
if (renderedCell.length > column.width) {
|
|
114
|
+
column.width = renderedCell.length;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
if (total_width > 0)
|
|
118
|
+
total_width += 3;
|
|
119
|
+
total_width += column.width;
|
|
120
|
+
}
|
|
121
|
+
// title
|
|
122
|
+
this.lines.push(this.renderCell(title, total_width, 'center'));
|
|
123
|
+
// header
|
|
124
|
+
this.lines.push(this.renderHeaderRow());
|
|
125
|
+
this.lines.push(this.renderSeparator());
|
|
126
|
+
// rows
|
|
127
|
+
for (let indj = 0; indj < this.rows.length; indj++) {
|
|
128
|
+
const row = this.rows[indj];
|
|
129
|
+
this.lines.push(this.renderRow(row));
|
|
130
|
+
}
|
|
131
|
+
return this.lines.join('\n');
|
|
132
|
+
}
|
|
133
|
+
renderHeaderRow() {
|
|
134
|
+
let result = '';
|
|
135
|
+
for (let indi = 0; indi < this.columns.length; indi++) {
|
|
136
|
+
const column = this.columns[indi];
|
|
137
|
+
if (result !== '')
|
|
138
|
+
result += ' | ';
|
|
139
|
+
result += this.renderCell(column.label, column.width, 'center');
|
|
140
|
+
}
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
143
|
+
renderRow(row) {
|
|
144
|
+
let result = '';
|
|
145
|
+
for (let indi = 0; indi < this.columns.length; indi++) {
|
|
146
|
+
const column = this.columns[indi];
|
|
147
|
+
let justify = 'left';
|
|
148
|
+
if (column.dbColumn?.dataTypeName === 'number' || column?.type === 'number') {
|
|
149
|
+
justify = 'right';
|
|
150
|
+
}
|
|
151
|
+
if (result !== '')
|
|
152
|
+
result += ' | ';
|
|
153
|
+
result += this.renderCell(row.cells[indi], column.width, justify);
|
|
154
|
+
}
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
renderSeparator() {
|
|
158
|
+
let result = '';
|
|
159
|
+
for (let indi = 0; indi < this.columns.length; indi++) {
|
|
160
|
+
const column = this.columns[indi];
|
|
161
|
+
if (result !== '')
|
|
162
|
+
result += '-+-';
|
|
163
|
+
result += '-'.repeat(column.width);
|
|
164
|
+
}
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
renderCell(value, width, justify) {
|
|
168
|
+
let result;
|
|
169
|
+
if (value === undefined) {
|
|
170
|
+
result = '';
|
|
171
|
+
}
|
|
172
|
+
else if (value === null) {
|
|
173
|
+
result = 'null';
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
result = value.toString();
|
|
177
|
+
}
|
|
178
|
+
if (width !== undefined && result.length < width) {
|
|
179
|
+
if (justify === undefined || justify === 'left') {
|
|
180
|
+
result += ' '.repeat(width - result.length);
|
|
181
|
+
}
|
|
182
|
+
else if (justify === 'right') {
|
|
183
|
+
result = ' '.repeat(width - result.length) + result;
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
// justify === center
|
|
187
|
+
const before = Math.floor((width - result.length) / 2);
|
|
188
|
+
result = ' '.repeat(before) + result + ' '.repeat(width - result.length - before);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
class Column {
|
|
195
|
+
constructor(name) {
|
|
196
|
+
this.label = '';
|
|
197
|
+
this.width = 0;
|
|
198
|
+
this.name = name;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
class Row {
|
|
202
|
+
constructor(cells) {
|
|
203
|
+
this.cells = cells;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
export declare class InitCommand extends Command {
|
|
3
|
+
constructor(name: string);
|
|
4
|
+
commandInit(options: any): Promise<void>;
|
|
5
|
+
getRandomInt(min: number, max: number): number;
|
|
6
|
+
generateToken(): string;
|
|
7
|
+
writeEnvFile(): Promise<void>;
|
|
8
|
+
writeDockerComposeFile(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.InitCommand = void 0;
|
|
23
|
+
const commander_1 = require("commander");
|
|
24
|
+
const fs = __importStar(require("fs"));
|
|
25
|
+
const loglevel_1 = require("loglevel");
|
|
26
|
+
const logger = (0, loglevel_1.getLogger)('InitCommand.ts');
|
|
27
|
+
logger.setLevel('debug');
|
|
28
|
+
class InitCommand extends commander_1.Command {
|
|
29
|
+
constructor(name) {
|
|
30
|
+
super(name);
|
|
31
|
+
this.description('initialize a folder with files necessary for a cyklang project')
|
|
32
|
+
.action(async (options) => {
|
|
33
|
+
await this.commandInit(options);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
async commandInit(options) {
|
|
37
|
+
try {
|
|
38
|
+
await this.writeEnvFile();
|
|
39
|
+
await this.writeDockerComposeFile();
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
logger.error(err);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// developer.mozilla.org Math.random()
|
|
46
|
+
// On renvoie un entier aléatoire entre une valeur min (incluse)
|
|
47
|
+
// et une valeur max (exclue).
|
|
48
|
+
// Attention : si on utilisait Math.round(), on aurait une distribution
|
|
49
|
+
// non uniforme !
|
|
50
|
+
getRandomInt(min, max) {
|
|
51
|
+
min = Math.ceil(min);
|
|
52
|
+
max = Math.floor(max);
|
|
53
|
+
return Math.floor(Math.random() * (max - min)) + min;
|
|
54
|
+
}
|
|
55
|
+
generateToken() {
|
|
56
|
+
let result = '';
|
|
57
|
+
for (let ind = 0; ind < 32; ind++) {
|
|
58
|
+
result += this.getRandomInt(0, 15).toString(16);
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
async writeEnvFile() {
|
|
63
|
+
const envFilename = '.env';
|
|
64
|
+
if (fs.existsSync(envFilename) === true) {
|
|
65
|
+
logger.info(envFilename + ' file already exists. Remove it before launching init command');
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
Math.random();
|
|
69
|
+
const content = `# PostgreSql connection
|
|
70
|
+
# used by psql command line utility
|
|
71
|
+
PGHOST="localhost"
|
|
72
|
+
PGPORT="4321"
|
|
73
|
+
PGUSER="postgres"
|
|
74
|
+
PGPASSWORD="postgres"
|
|
75
|
+
|
|
76
|
+
# at postgresql database initialization
|
|
77
|
+
|
|
78
|
+
# POSTGRES_USER="postgres"
|
|
79
|
+
POSTGRES_PASSWORD="postgres"
|
|
80
|
+
|
|
81
|
+
# admin user
|
|
82
|
+
# created at database initialization
|
|
83
|
+
ADMIN_NAME=cyk
|
|
84
|
+
ADMIN_PASSWORD=cyk
|
|
85
|
+
ADMIN_EMAIL=my-email@my-domain
|
|
86
|
+
|
|
87
|
+
# JWT token generation
|
|
88
|
+
# e.g. https://www.allkeysgenerator.com
|
|
89
|
+
# 128 bits Hex
|
|
90
|
+
|
|
91
|
+
SECRET_TOKEN="${this.generateToken()}"
|
|
92
|
+
SECRET_RTOKEN="${this.generateToken()}"
|
|
93
|
+
|
|
94
|
+
# Login Page Config
|
|
95
|
+
LOGIN_IMAGE="https://media.smartbox.com/pim/1000001967971201770883.jpg?thumbor=800x0/filters:quality(90)"
|
|
96
|
+
LOGIN_TITLE="CYK Framework"
|
|
97
|
+
LOGIN_SUBTITLE="Une application pilote du framework CYK"
|
|
98
|
+
LOGIN_APPLI="accounting"
|
|
99
|
+
|
|
100
|
+
# credential used by cyk CLI
|
|
101
|
+
|
|
102
|
+
USER_NAME=cyk
|
|
103
|
+
USER_PASSWORD=cyk
|
|
104
|
+
CYK_PORT="3000"
|
|
105
|
+
DBREMOTE_URL="http://localhost:3000"
|
|
106
|
+
`;
|
|
107
|
+
fs.writeFileSync(envFilename, content);
|
|
108
|
+
logger.debug('created ' + envFilename);
|
|
109
|
+
}
|
|
110
|
+
async writeDockerComposeFile() {
|
|
111
|
+
const dockerComposeFilename = 'docker-compose.yml';
|
|
112
|
+
if (fs.existsSync(dockerComposeFilename) === true) {
|
|
113
|
+
logger.info(dockerComposeFilename + ' already exists. Remove it before launching init command');
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const modelFilename = __dirname + '/../' + dockerComposeFilename;
|
|
117
|
+
const content = fs.readFileSync(modelFilename);
|
|
118
|
+
fs.writeFileSync(dockerComposeFilename, content);
|
|
119
|
+
logger.debug('created ' + dockerComposeFilename);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.InitCommand = InitCommand;
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
#!/usr/bin/env ts-node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
6
|
+
}) : (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
o[k2] = m[k];
|
|
9
|
+
}));
|
|
10
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
11
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
12
|
+
}) : function(o, v) {
|
|
13
|
+
o["default"] = v;
|
|
14
|
+
});
|
|
15
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
16
|
+
if (mod && mod.__esModule) return mod;
|
|
17
|
+
var result = {};
|
|
18
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
19
|
+
__setModuleDefault(result, mod);
|
|
20
|
+
return result;
|
|
21
|
+
};
|
|
22
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.ModuleCommand = void 0;
|
|
27
|
+
const core_1 = require("@cyklang/core");
|
|
28
|
+
const fs = __importStar(require("fs"));
|
|
29
|
+
const loglevel_1 = __importDefault(require("loglevel"));
|
|
30
|
+
const path_1 = __importDefault(require("path"));
|
|
31
|
+
const commander_1 = require("commander");
|
|
32
|
+
const Cmd_1 = require("./Cmd");
|
|
33
|
+
const DBClient_1 = require("./DBClient");
|
|
34
|
+
const logger = loglevel_1.default.getLogger("ModuleCommand.ts");
|
|
35
|
+
logger.setLevel("debug");
|
|
36
|
+
class ModuleCommand extends commander_1.Command {
|
|
37
|
+
constructor(name) {
|
|
38
|
+
super(name);
|
|
39
|
+
this.description('manage modules');
|
|
40
|
+
// upload
|
|
41
|
+
this.addCommand(new ModuleUpload('upload', `Upload local module file(s) to the database.
|
|
42
|
+
Module name is the base name of the file. If a module with the same name already exists, it will be updated.
|
|
43
|
+
Otherwise, a new module is inserted in the database. To rename a module, use option --id to indicate the module you want to rename`));
|
|
44
|
+
this.addCommand(new ModuleUpload('u', 'shortcut for (u)pload'));
|
|
45
|
+
// download
|
|
46
|
+
this.addCommand(new ModuleDownload('download', 'download module files to the current directory'));
|
|
47
|
+
this.addCommand(new ModuleDownload('d', 'shortcut for (d)ownload'));
|
|
48
|
+
// list
|
|
49
|
+
this.addCommand(new ModuleList('list', 'List modules'));
|
|
50
|
+
this.addCommand(new ModuleList('l', 'shortcut for (l)ist'));
|
|
51
|
+
// rename
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.ModuleCommand = ModuleCommand;
|
|
55
|
+
function getModuleDBName(filePath) {
|
|
56
|
+
let result;
|
|
57
|
+
if (filePath.endsWith('.xml') === false)
|
|
58
|
+
throw filePath + ' does not have .xml extension';
|
|
59
|
+
result = path_1.default.basename(filePath, '.xml');
|
|
60
|
+
const identifierRegex = /^[_a-zA-Z][_a-zA-Z0-9]*$/;
|
|
61
|
+
if (result.match(identifierRegex) === null)
|
|
62
|
+
throw 'filename ' + result + ' does not match identifier syntax';
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
class ModuleUpload extends Cmd_1.Cmd {
|
|
66
|
+
constructor(name, description) {
|
|
67
|
+
super(name);
|
|
68
|
+
this.description(description)
|
|
69
|
+
.option('-i --id <id>', 'module ID to download')
|
|
70
|
+
.argument('[files...]', 'local module file(s) to upload to the server')
|
|
71
|
+
.action(async (files, options) => {
|
|
72
|
+
await this.commandUpload(files, options);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
async commandUpload(files, options) {
|
|
76
|
+
try {
|
|
77
|
+
await this.prologue(options);
|
|
78
|
+
if (this.dbManager === undefined)
|
|
79
|
+
throw 'dbManager undefined';
|
|
80
|
+
if (files.length === 0)
|
|
81
|
+
throw 'file(s) argument is missing';
|
|
82
|
+
if (options.id !== undefined) {
|
|
83
|
+
if (files.length > 1)
|
|
84
|
+
throw 'with --id option you can only specify 1 local file';
|
|
85
|
+
const dbModule = await this.dbManager.getModule(options.id);
|
|
86
|
+
dbModule.source = fs.readFileSync(files[0]).toString();
|
|
87
|
+
dbModule.dbname = getModuleDBName(files[0]);
|
|
88
|
+
const tag = (0, core_1.parseXML)(dbModule.dbname, dbModule.source);
|
|
89
|
+
dbModule.access = tag.attributes.ACCESS;
|
|
90
|
+
dbModule.description = tag.attributes.DESCRIPTION;
|
|
91
|
+
await this.dbManager.dbModuleUpdate(dbModule);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
for (let ind = 0; ind < files.length; ind++) {
|
|
95
|
+
const file = files[ind];
|
|
96
|
+
const dbname = getModuleDBName(file);
|
|
97
|
+
const source = fs.readFileSync(file).toString();
|
|
98
|
+
const tag = (0, core_1.parseXML)(dbname, source);
|
|
99
|
+
const dbModuleExist = await this.dbManager.dbModuleExist(dbname);
|
|
100
|
+
if (dbModuleExist === undefined) {
|
|
101
|
+
// insert
|
|
102
|
+
const dbModule = new core_1.DBModule();
|
|
103
|
+
dbModule.source = source;
|
|
104
|
+
dbModule.dbname = dbname;
|
|
105
|
+
dbModule.access = tag.attributes.ACCESS;
|
|
106
|
+
dbModule.description = tag.attributes.DESCRIPTION;
|
|
107
|
+
logger.debug('module insert ' + dbname + ' access ' + dbModule.access + ' description ' + dbModule.description);
|
|
108
|
+
const id = await this.dbManager.dbModuleInsert(dbModule);
|
|
109
|
+
logger.info('module ' + dbname + ' added with ID ' + id);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
// update
|
|
113
|
+
dbModuleExist.access = tag.attributes.ACCESS;
|
|
114
|
+
dbModuleExist.description = tag.attributes.DESCRIPTION;
|
|
115
|
+
logger.debug('module update ' + dbname + ' access ' + dbModuleExist.access + ' description ' + dbModuleExist.description);
|
|
116
|
+
await this.dbManager.dbModuleUpdate(dbModuleExist);
|
|
117
|
+
logger.info('module ' + dbname + ' updated');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
logger.error(err);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
class ModuleDownload extends Cmd_1.Cmd {
|
|
128
|
+
constructor(name, description) {
|
|
129
|
+
super(name);
|
|
130
|
+
this.description(description)
|
|
131
|
+
.option('-i --id <id>', 'module ID')
|
|
132
|
+
.option('-a --all', 'download all the modules')
|
|
133
|
+
.argument('[files...]', 'module(s) name(s) are derived as the basename(s) of the file(s) path')
|
|
134
|
+
.action(async (files, options) => {
|
|
135
|
+
await this.commandDownload(files, options);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
async commandDownload(files, options) {
|
|
139
|
+
try {
|
|
140
|
+
await this.prologue(options);
|
|
141
|
+
if (this.dbManager === undefined)
|
|
142
|
+
throw 'dbManager undefined';
|
|
143
|
+
if (options.id !== undefined) {
|
|
144
|
+
const dbModule = await this.dbManager.getModule(options.id);
|
|
145
|
+
await this.downloadModule(dbModule.dbname || '', dbModule);
|
|
146
|
+
}
|
|
147
|
+
else if (options.all !== undefined) {
|
|
148
|
+
const modules = await this.dbManager.getModules(undefined);
|
|
149
|
+
for (let ind = 0; ind < modules.length; ind++) {
|
|
150
|
+
const dbModule = modules[ind];
|
|
151
|
+
await this.downloadModule(dbModule.dbname || '', dbModule);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
for (let ind = 0; ind < files.length; ind++) {
|
|
156
|
+
await this.downloadModule(getModuleDBName(files[ind]));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
logger.error(err);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
async downloadModule(dbname, dbModule) {
|
|
165
|
+
logger.debug('downloadModule ' + dbname);
|
|
166
|
+
if (dbModule === undefined) {
|
|
167
|
+
dbModule = await this.dbManager?.dbModuleExist(dbname);
|
|
168
|
+
if (dbModule === undefined)
|
|
169
|
+
throw 'module not found : ' + dbname;
|
|
170
|
+
}
|
|
171
|
+
const filePath = dbname + '.xml';
|
|
172
|
+
if (fs.existsSync(filePath) === true) {
|
|
173
|
+
logger.info('file ' + filePath + ' already exists and will not be overwritten ');
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
fs.writeFileSync(filePath, dbModule.source || '');
|
|
177
|
+
logger.info('module ' + dbname + ' has been downloaded and file ' + filePath + ' has been created');
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
class ModuleList extends Cmd_1.Cmd {
|
|
182
|
+
constructor(name, description) {
|
|
183
|
+
super(name);
|
|
184
|
+
this.description(description)
|
|
185
|
+
.option('-s --sort <columns>', 'sort list by column numbers (begins by 0) separated by comma')
|
|
186
|
+
.action(async (options) => {
|
|
187
|
+
await this.commandList(options);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
async commandList(options) {
|
|
191
|
+
try {
|
|
192
|
+
await this.prologue(options);
|
|
193
|
+
if (this.dbManager === undefined)
|
|
194
|
+
throw 'dbManager undefined';
|
|
195
|
+
const dbClient = new DBClient_1.DBClient(this.dbManager);
|
|
196
|
+
dbClient.selectFromTable('List of Modules', 'cyk_module', { fields: 'module_id,module_dbname,module_access,module_description', sort: options.sort || '1' });
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
logger.error(err);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|