@cyklang/cli 0.3.0 → 0.4.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/build/AssetCommand.js +72 -11
- package/build/Cmd.d.ts +8 -0
- package/build/Cmd.js +50 -0
- package/build/DBClient.d.ts +10 -0
- package/build/DBClient.js +32 -0
- package/build/ModuleCommand.js +41 -5
- package/build/TableCommand.js +38 -0
- package/build/UserCommand.js +13 -7
- package/package.json +1 -1
- package/src/AssetCommand.ts +78 -17
- package/src/Cmd.ts +59 -0
- package/src/DBClient.ts +35 -1
- package/src/ModuleCommand.ts +46 -5
- package/src/TableCommand.ts +41 -0
- package/src/UserCommand.ts +13 -7
- package/test/t26.output +7 -0
- package/test/t26.xml +37 -0
package/build/AssetCommand.js
CHANGED
|
@@ -42,8 +42,9 @@ class AssetCommand extends commander_1.Command {
|
|
|
42
42
|
this.description(description);
|
|
43
43
|
this.addCommand(new AssetList('list', 'list assets'));
|
|
44
44
|
this.addCommand(new AssetList('l', '(l)ist assets'));
|
|
45
|
-
this.addCommand(new
|
|
46
|
-
this.addCommand(new
|
|
45
|
+
this.addCommand(new AssetU('upload', 'upload asset content from source files to a <destination> path'));
|
|
46
|
+
this.addCommand(new AssetU('update', 'update properties of asset identified by its <id>'));
|
|
47
|
+
this.addCommand(new AssetU('u', '(u)pload assets content from sources or (u)pdate asset properties'));
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
exports.AssetCommand = AssetCommand;
|
|
@@ -51,6 +52,7 @@ class AssetList extends Cmd_1.Cmd {
|
|
|
51
52
|
constructor(name, description) {
|
|
52
53
|
super(name);
|
|
53
54
|
this.description(description)
|
|
55
|
+
.option('-d --dest <destination>', 'filter assets whose pathname begins with destination')
|
|
54
56
|
.option('-s --sort <columns>', 'sort list by column numbers (begins by 0) separated by comma')
|
|
55
57
|
.action(async (options) => { await this.commandList(options); });
|
|
56
58
|
}
|
|
@@ -60,14 +62,20 @@ class AssetList extends Cmd_1.Cmd {
|
|
|
60
62
|
if (this.dbManager === undefined)
|
|
61
63
|
throw 'dbManager undefined';
|
|
62
64
|
const dbClient = new DBClient_1.DBClient(this.dbManager);
|
|
63
|
-
dbClient.selectFromTable('List of Assets', 'cyk_asset', {
|
|
65
|
+
dbClient.selectFromTable('List of Assets', 'cyk_asset', {
|
|
66
|
+
fields: 'asset_id,asset_route,asset_auth,asset_access,asset_mimetype,asset_last_update', sort: options.sort || '1',
|
|
67
|
+
where: (options.dest ? "asset_route like '" + options.dest + "%'" : undefined)
|
|
68
|
+
});
|
|
64
69
|
}
|
|
65
70
|
catch (err) {
|
|
66
71
|
logger.error(err);
|
|
67
72
|
}
|
|
68
73
|
}
|
|
69
74
|
}
|
|
70
|
-
|
|
75
|
+
/**
|
|
76
|
+
* class AssetU
|
|
77
|
+
*/
|
|
78
|
+
class AssetU extends Cmd_1.Cmd {
|
|
71
79
|
constructor(name, description) {
|
|
72
80
|
super(name);
|
|
73
81
|
//----------------------------------------------------------------------------------------------
|
|
@@ -75,12 +83,15 @@ class AssetUpload extends Cmd_1.Cmd {
|
|
|
75
83
|
//----------------------------------------------------------------------------------------------
|
|
76
84
|
this.ignorePatterns = ['.git', 'node_modules'];
|
|
77
85
|
this.description(description)
|
|
86
|
+
.option('-i --id <id>', 'asset id to update properties')
|
|
87
|
+
.option('--auth <auth_schema>', 'authentication schema : basic | token | cookie | any | none, default is none')
|
|
88
|
+
.option('--access <access>', 'access rights required')
|
|
78
89
|
.option('-d --dest <destination>', 'destination path, directory name')
|
|
79
90
|
.option('-c --clean', 'clean destination path before uploading')
|
|
80
91
|
.option('-y --yes', 'upload list is automatically confirmed')
|
|
81
92
|
.argument('[sources...]', 'local files or directories to upload as assets to the server')
|
|
82
93
|
.action(async (sources, options) => {
|
|
83
|
-
await this.
|
|
94
|
+
await this.commandU(sources, options);
|
|
84
95
|
});
|
|
85
96
|
}
|
|
86
97
|
mimetypeLookup(filename) {
|
|
@@ -93,6 +104,48 @@ class AssetUpload extends Cmd_1.Cmd {
|
|
|
93
104
|
}
|
|
94
105
|
return result;
|
|
95
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* method commandU
|
|
109
|
+
* @param sources
|
|
110
|
+
* @param options
|
|
111
|
+
*/
|
|
112
|
+
async commandU(sources, options) {
|
|
113
|
+
if (sources.length > 0) {
|
|
114
|
+
// upload
|
|
115
|
+
logger.debug('upload sources :', sources);
|
|
116
|
+
await this.commandUpload(sources, options);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// update
|
|
120
|
+
logger.debug('update', options);
|
|
121
|
+
await this.commandUpdate(options);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* method commandUpdate
|
|
126
|
+
* @param options
|
|
127
|
+
*/
|
|
128
|
+
async commandUpdate(options) {
|
|
129
|
+
try {
|
|
130
|
+
await this.prologue(options);
|
|
131
|
+
if (this.dbManager === undefined)
|
|
132
|
+
throw 'dbManager undefined';
|
|
133
|
+
if (options.id === undefined)
|
|
134
|
+
throw '<id_or_route> of asset to update is missing';
|
|
135
|
+
const dbAsset = await this.dbManager.dbAssetExist(options.id);
|
|
136
|
+
if (dbAsset === undefined)
|
|
137
|
+
throw 'Asset ' + options.id + ' not found';
|
|
138
|
+
await this.updateAuthAccess('cyk_asset', 'assert', dbAsset.id || '', options);
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
logger.error(err);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* method commandUpload
|
|
146
|
+
* @param sources
|
|
147
|
+
* @param options
|
|
148
|
+
*/
|
|
96
149
|
async commandUpload(sources, options) {
|
|
97
150
|
try {
|
|
98
151
|
await this.prologue(options);
|
|
@@ -100,6 +153,11 @@ class AssetUpload extends Cmd_1.Cmd {
|
|
|
100
153
|
throw 'dbManager undefined';
|
|
101
154
|
if (sources.length === 0)
|
|
102
155
|
throw 'no source to upload';
|
|
156
|
+
if (options.auth && ' basic | token | cookie | any | none'.indexOf(options.auth) === -1) {
|
|
157
|
+
throw 'valid authentication schemas are : basic | token | cookie | any | none';
|
|
158
|
+
}
|
|
159
|
+
logger.debug('options : ', options);
|
|
160
|
+
logger.debug('auth : ' + options.auth);
|
|
103
161
|
let dest = "/";
|
|
104
162
|
if (options.dest !== undefined)
|
|
105
163
|
dest = options.dest;
|
|
@@ -121,7 +179,7 @@ class AssetUpload extends Cmd_1.Cmd {
|
|
|
121
179
|
else if (filestat.isFile() === true) {
|
|
122
180
|
const base = path_1.default.parse(source).base;
|
|
123
181
|
logger.debug('upload file ' + source + ' to ' + dest + base);
|
|
124
|
-
await this.uploadAsset({ path: source, mtime: filestat.mtime }, dest + base);
|
|
182
|
+
await this.uploadAsset({ path: source, mtime: filestat.mtime }, dest + base, options.auth);
|
|
125
183
|
}
|
|
126
184
|
}
|
|
127
185
|
}
|
|
@@ -169,7 +227,7 @@ class AssetUpload extends Cmd_1.Cmd {
|
|
|
169
227
|
uploadConfirmed = true;
|
|
170
228
|
}
|
|
171
229
|
if (uploadConfirmed === true) {
|
|
172
|
-
await this.uploadFiles(dirName, uploadList, dest);
|
|
230
|
+
await this.uploadFiles(dirName, uploadList, dest, options.auth);
|
|
173
231
|
}
|
|
174
232
|
// const rl = readline.createInterface(process.stdin, process.stdout)
|
|
175
233
|
// rl.question('Do you want to upload this(these) ' + uploadList.length + ' file(s) (Y/N/y/n) ?', async (reply) => {
|
|
@@ -269,19 +327,19 @@ class AssetUpload extends Cmd_1.Cmd {
|
|
|
269
327
|
//----------------------------------------------------------------------------------------------
|
|
270
328
|
// uploadFiles
|
|
271
329
|
//----------------------------------------------------------------------------------------------
|
|
272
|
-
async uploadFiles(dirName, uploadList, dest) {
|
|
330
|
+
async uploadFiles(dirName, uploadList, dest, auth) {
|
|
273
331
|
for (let ind = 0; ind < uploadList.length; ind++) {
|
|
274
332
|
const upload = uploadList[ind];
|
|
275
333
|
const route = dest + upload.path.substring(dirName.length);
|
|
276
334
|
logger.debug('upload ' + upload.path + ' to ' + route);
|
|
277
|
-
await this.uploadAsset(upload, route);
|
|
335
|
+
await this.uploadAsset(upload, route, auth);
|
|
278
336
|
}
|
|
279
337
|
}
|
|
280
338
|
//----------------------------------------------------------------------------------------------
|
|
281
339
|
// uploadAsset
|
|
282
340
|
//----------------------------------------------------------------------------------------------
|
|
283
|
-
async uploadAsset(upload, route) {
|
|
284
|
-
logger.debug('uploadAsset ' + upload.path + ' to route ' + route + ' with mimetype ' + this.mimetypeLookup(upload.path));
|
|
341
|
+
async uploadAsset(upload, route, auth) {
|
|
342
|
+
logger.debug('uploadAsset ' + upload.path + ' to route ' + route + ' with mimetype ' + this.mimetypeLookup(upload.path) + ', auth : ' + auth);
|
|
285
343
|
try {
|
|
286
344
|
let dbAsset = await this.dbManager?.dbAssetExist(route);
|
|
287
345
|
if (dbAsset === undefined) {
|
|
@@ -292,6 +350,9 @@ class AssetUpload extends Cmd_1.Cmd {
|
|
|
292
350
|
throw 'mimetype false for ' + upload;
|
|
293
351
|
dbAsset.mimetype = mimetype;
|
|
294
352
|
dbAsset.route = route;
|
|
353
|
+
dbAsset.auth = auth;
|
|
354
|
+
if (dbAsset.auth === 'none')
|
|
355
|
+
dbAsset.auth = undefined;
|
|
295
356
|
// const fstat = fs.statSync(fileName)
|
|
296
357
|
dbAsset.last_update = upload.mtime;
|
|
297
358
|
// const contentBuffer = fs.readFileSync(fileName)
|
package/build/Cmd.d.ts
CHANGED
|
@@ -5,4 +5,12 @@ export declare class Cmd extends Command {
|
|
|
5
5
|
dbRemote: DBRemote | undefined;
|
|
6
6
|
constructor(name: string);
|
|
7
7
|
prologue(options: any): Promise<SigninResponse>;
|
|
8
|
+
/**
|
|
9
|
+
* method updateAuthAccess
|
|
10
|
+
* @param tableName
|
|
11
|
+
* @param prefix
|
|
12
|
+
* @param id
|
|
13
|
+
* @param options
|
|
14
|
+
*/
|
|
15
|
+
updateAuthAccess(tableName: string, prefix: string, id: string, options: any): Promise<void>;
|
|
8
16
|
}
|
package/build/Cmd.js
CHANGED
|
@@ -9,6 +9,7 @@ const commander_1 = require("commander");
|
|
|
9
9
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
10
10
|
const loglevel_1 = __importDefault(require("loglevel"));
|
|
11
11
|
const NodeCrypto_1 = require("./NodeCrypto");
|
|
12
|
+
const DBClient_1 = require("./DBClient");
|
|
12
13
|
const logger = loglevel_1.default.getLogger('Cmd.ts');
|
|
13
14
|
logger.setLevel('debug');
|
|
14
15
|
class Cmd extends commander_1.Command {
|
|
@@ -32,5 +33,54 @@ class Cmd extends commander_1.Command {
|
|
|
32
33
|
await this.dbManager.initialize();
|
|
33
34
|
return login;
|
|
34
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* method updateAuthAccess
|
|
38
|
+
* @param tableName
|
|
39
|
+
* @param prefix
|
|
40
|
+
* @param id
|
|
41
|
+
* @param options
|
|
42
|
+
*/
|
|
43
|
+
async updateAuthAccess(tableName, prefix, id, options) {
|
|
44
|
+
try {
|
|
45
|
+
let dclAuth;
|
|
46
|
+
if (options.auth) {
|
|
47
|
+
if (' basic | token | cookie | any | none | null '.indexOf(' ' + options.auth + ' ') === -1) {
|
|
48
|
+
throw 'valid authentication schemas are : basic | token | cookie | any | null';
|
|
49
|
+
}
|
|
50
|
+
dclAuth = `<string name='${prefix}_auth'>`;
|
|
51
|
+
if (' none | null '.indexOf(' ' + options.auth + ' ') === -1)
|
|
52
|
+
dclAuth += ` "${options.auth}" `;
|
|
53
|
+
else
|
|
54
|
+
dclAuth += ' null ';
|
|
55
|
+
dclAuth += "</string>";
|
|
56
|
+
}
|
|
57
|
+
let dclAccess;
|
|
58
|
+
if (options.access) {
|
|
59
|
+
dclAccess = `<string name='${prefix}_access'> `;
|
|
60
|
+
if (' null | none '.indexOf(' ' + options.access + ' ') === -1)
|
|
61
|
+
dclAccess += `"${options.access}"`;
|
|
62
|
+
else
|
|
63
|
+
dclAccess += ' null ';
|
|
64
|
+
dclAccess += "</string>";
|
|
65
|
+
}
|
|
66
|
+
const inst = `
|
|
67
|
+
<db.update table='${tableName}'>
|
|
68
|
+
<object>
|
|
69
|
+
<number name='${prefix}_id'>${id}</number>
|
|
70
|
+
${dclAuth}
|
|
71
|
+
${dclAccess ? dclAccess : ''}
|
|
72
|
+
</object>
|
|
73
|
+
</db.update>
|
|
74
|
+
`;
|
|
75
|
+
if (!this.dbManager)
|
|
76
|
+
throw 'prologue() has not been called before';
|
|
77
|
+
const dbClient = new DBClient_1.DBClient(this.dbManager);
|
|
78
|
+
dbClient.execInstructions(inst);
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
logger.error(err);
|
|
82
|
+
throw err;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
35
85
|
}
|
|
36
86
|
exports.Cmd = Cmd;
|
package/build/DBClient.d.ts
CHANGED
|
@@ -2,6 +2,16 @@ import { DBManager } from "@cyklang/core";
|
|
|
2
2
|
export declare class DBClient {
|
|
3
3
|
dbManager: DBManager;
|
|
4
4
|
constructor(dbManager: DBManager);
|
|
5
|
+
/**
|
|
6
|
+
* method execInstructions
|
|
7
|
+
* @param source
|
|
8
|
+
*/
|
|
9
|
+
execInstructions(source: string): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* method execScript
|
|
12
|
+
* @param source
|
|
13
|
+
*/
|
|
14
|
+
execScript(source: string): Promise<void>;
|
|
5
15
|
runQuery(): Promise<void>;
|
|
6
16
|
selectFromTable(title: string, tableName: string, options: {
|
|
7
17
|
fields: string;
|
package/build/DBClient.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.DBClient = void 0;
|
|
7
7
|
const core_1 = require("@cyklang/core");
|
|
8
8
|
const loglevel_1 = __importDefault(require("loglevel"));
|
|
9
|
+
const console_1 = require("./console");
|
|
9
10
|
const logger = loglevel_1.default.getLogger('DBClient.ts');
|
|
10
11
|
logger.setLevel('debug');
|
|
11
12
|
// DBManager wrapper class
|
|
@@ -13,6 +14,37 @@ class DBClient {
|
|
|
13
14
|
constructor(dbManager) {
|
|
14
15
|
this.dbManager = dbManager;
|
|
15
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* method execInstructions
|
|
19
|
+
* @param source
|
|
20
|
+
*/
|
|
21
|
+
async execInstructions(source) {
|
|
22
|
+
const script = `<?xml-model href="https://www.cyklang.net/schema/cyklang.xsd" type="application/xml" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
|
23
|
+
<module>
|
|
24
|
+
` + source + `
|
|
25
|
+
</module>`;
|
|
26
|
+
await this.execScript(script);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* method execScript
|
|
30
|
+
* @param source
|
|
31
|
+
*/
|
|
32
|
+
async execScript(source) {
|
|
33
|
+
try {
|
|
34
|
+
const script = new core_1.Script(this.dbManager.scope, '', source);
|
|
35
|
+
await script.parseInstructions();
|
|
36
|
+
await script.execute();
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
console.log(source);
|
|
40
|
+
console.log();
|
|
41
|
+
if (err instanceof core_1.XmlError) {
|
|
42
|
+
let xmlError = err;
|
|
43
|
+
(0, console_1.errorconsole)(xmlError);
|
|
44
|
+
}
|
|
45
|
+
console.log(err);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
16
48
|
async runQuery() {
|
|
17
49
|
}
|
|
18
50
|
async selectFromTable(title, tableName, options) {
|
package/build/ModuleCommand.js
CHANGED
|
@@ -38,10 +38,10 @@ class ModuleCommand extends commander_1.Command {
|
|
|
38
38
|
super(name);
|
|
39
39
|
this.description('manage modules');
|
|
40
40
|
// upload
|
|
41
|
-
this.addCommand(new
|
|
41
|
+
this.addCommand(new ModuleU('upload', `Upload local module file(s) to the database.
|
|
42
42
|
Module name is the base name of the file. If a module with the same name already exists, it will be updated.
|
|
43
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
|
|
44
|
+
this.addCommand(new ModuleU('u', 'shortcut for (u)pload'));
|
|
45
45
|
// download
|
|
46
46
|
this.addCommand(new ModuleDownload('download', 'download module files to the current directory'));
|
|
47
47
|
this.addCommand(new ModuleDownload('d', 'shortcut for (d)ownload'));
|
|
@@ -64,16 +64,52 @@ function getModuleDBName(filePath) {
|
|
|
64
64
|
throw 'filename ' + result + ' does not match identifier syntax';
|
|
65
65
|
return result;
|
|
66
66
|
}
|
|
67
|
-
|
|
67
|
+
/**
|
|
68
|
+
* class ModuleU
|
|
69
|
+
*/
|
|
70
|
+
class ModuleU extends Cmd_1.Cmd {
|
|
68
71
|
constructor(name, description) {
|
|
69
72
|
super(name);
|
|
70
73
|
this.description(description)
|
|
71
|
-
.option('
|
|
74
|
+
.option('--auth <auth_schema>', 'authentication schema : basic | token | cookie | any | none, default is none')
|
|
75
|
+
.option('--access <access_right>', 'access rights required')
|
|
76
|
+
.option('-i --id <id>', 'module ID to upload or update')
|
|
72
77
|
.argument('[files...]', 'local module file(s) to upload to the server')
|
|
73
78
|
.action(async (files, options) => {
|
|
74
|
-
await this.
|
|
79
|
+
await this.commandU(files, options);
|
|
75
80
|
});
|
|
76
81
|
}
|
|
82
|
+
async commandU(files, options) {
|
|
83
|
+
if (files.length > 0) {
|
|
84
|
+
await this.commandUpload(files, options);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
await this.commandUpdate(options);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* method commandUpdate
|
|
92
|
+
* @param options
|
|
93
|
+
*/
|
|
94
|
+
async commandUpdate(options) {
|
|
95
|
+
try {
|
|
96
|
+
await this.prologue(options);
|
|
97
|
+
if (this.dbManager === undefined)
|
|
98
|
+
throw 'dbManager undefined';
|
|
99
|
+
if (options.id === undefined)
|
|
100
|
+
throw '<id_or_route> of module to update is missing';
|
|
101
|
+
const dbModule = await this.dbManager.getModule(options.id);
|
|
102
|
+
await this.updateAuthAccess('cyk_module', 'module', dbModule.id || '', options);
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
logger.error(err);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* method commandUpload
|
|
110
|
+
* @param files
|
|
111
|
+
* @param options
|
|
112
|
+
*/
|
|
77
113
|
async commandUpload(files, options) {
|
|
78
114
|
try {
|
|
79
115
|
await this.prologue(options);
|
package/build/TableCommand.js
CHANGED
|
@@ -43,9 +43,47 @@ class TableCommand extends commander_1.Command {
|
|
|
43
43
|
this.addCommand(new TableList('l', '(l)ist database tables'));
|
|
44
44
|
this.addCommand(new TableData('data', 'table (d)ata'));
|
|
45
45
|
this.addCommand(new TableData('d', 'table (d)ata'));
|
|
46
|
+
this.addCommand(new TableUpdate('update', 'update table properties'));
|
|
47
|
+
this.addCommand(new TableUpdate('u', 'shortcut for (u)pdate table properties'));
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
50
|
exports.TableCommand = TableCommand;
|
|
51
|
+
/**
|
|
52
|
+
* class TableUpdate
|
|
53
|
+
*/
|
|
54
|
+
class TableUpdate extends Cmd_1.Cmd {
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
* @param name
|
|
58
|
+
* @param description
|
|
59
|
+
*/
|
|
60
|
+
constructor(name, description) {
|
|
61
|
+
super(name);
|
|
62
|
+
this.description(description)
|
|
63
|
+
.option('-n --name <table_name>', 'name of the table whose properties are to be changed')
|
|
64
|
+
.option('--auth <auth_schema>', 'authentication schema : basic | token | cookie | any | none, default is none')
|
|
65
|
+
.option('--access <access>', 'access rights required')
|
|
66
|
+
.action(async (options) => {
|
|
67
|
+
await this.commandUpdate(options);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
async commandUpdate(options) {
|
|
71
|
+
try {
|
|
72
|
+
await this.prologue(options);
|
|
73
|
+
if (this.dbManager === undefined)
|
|
74
|
+
throw 'dbManager undefined';
|
|
75
|
+
if (!options.name)
|
|
76
|
+
throw '<table_name> is missing';
|
|
77
|
+
const dbTable = await this.dbManager.dbTableExist(options.name);
|
|
78
|
+
if (!dbTable)
|
|
79
|
+
throw 'Table ' + options.name + ' not found';
|
|
80
|
+
await this.updateAuthAccess('cyk_table', 'table', dbTable.id || '', options);
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
logger.error(err);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
49
87
|
class TableExportCmd extends Cmd_1.Cmd {
|
|
50
88
|
constructor() {
|
|
51
89
|
super('export');
|
package/build/UserCommand.js
CHANGED
|
@@ -16,23 +16,25 @@ class UserCommand extends commander_1.Command {
|
|
|
16
16
|
constructor(name) {
|
|
17
17
|
super(name);
|
|
18
18
|
this.description('manage users in cyk_user table').version('0.1');
|
|
19
|
-
this.addCommand(new UserAddCmd());
|
|
19
|
+
this.addCommand(new UserAddCmd('add', 'add a new user'));
|
|
20
|
+
this.addCommand(new UserAddCmd('a', 'add a new user'));
|
|
20
21
|
this.addCommand(new UserUpdateCmd('update', 'update user by id all fields except password'));
|
|
21
22
|
this.addCommand(new UserUpdateCmd('u', 'shortcut for (u)pdate'));
|
|
22
23
|
this.addCommand(new UserDeleteCmd('delete', 'delete user by id and name. Both options are mandatory to avoid typing error'));
|
|
23
24
|
this.addCommand(new UserPasswdCmd('passwd', 'change user password'));
|
|
25
|
+
this.addCommand(new UserPasswdCmd('p', 'shortcut for (p)asswd'));
|
|
24
26
|
this.addCommand(new UserListCmd('list', 'list users'));
|
|
25
27
|
this.addCommand(new UserListCmd('l', 'shortcut for (l)ist'));
|
|
26
28
|
}
|
|
27
29
|
}
|
|
28
30
|
exports.UserCommand = UserCommand;
|
|
29
31
|
class UserAddCmd extends Cmd_1.Cmd {
|
|
30
|
-
constructor() {
|
|
31
|
-
super(
|
|
32
|
-
this.description(
|
|
32
|
+
constructor(name, description) {
|
|
33
|
+
super(name);
|
|
34
|
+
this.description(description)
|
|
33
35
|
.requiredOption('-n --name <name>', 'user name')
|
|
34
36
|
.option('-e --email <email>', 'user email address')
|
|
35
|
-
.option('-p --
|
|
37
|
+
.option('-p --password <password>', 'initial password')
|
|
36
38
|
.option('-a --access <acl>', 'access control list')
|
|
37
39
|
.option('-m --module <module_name>', 'module to launch by default')
|
|
38
40
|
.option('-d --disable', 'user not abled to connect')
|
|
@@ -55,7 +57,11 @@ class UserAddCmd extends Cmd_1.Cmd {
|
|
|
55
57
|
if (this.dbManager === undefined)
|
|
56
58
|
throw 'dbManager undefined';
|
|
57
59
|
const result = await this.dbManager.dbUserInsert(dbUser);
|
|
58
|
-
logger.debug(result);
|
|
60
|
+
logger.debug('ID', result);
|
|
61
|
+
if (dbUser.password) {
|
|
62
|
+
await this.dbManager.dbUserPasswd(result, dbUser.password);
|
|
63
|
+
logger.info('password changed for user ' + dbUser.name);
|
|
64
|
+
}
|
|
59
65
|
}
|
|
60
66
|
catch (err) {
|
|
61
67
|
logger.error(err);
|
|
@@ -172,7 +178,7 @@ class UserDeleteCmd extends Cmd_1.Cmd {
|
|
|
172
178
|
}
|
|
173
179
|
class UserPasswdCmd extends Cmd_1.Cmd {
|
|
174
180
|
constructor(name, description) {
|
|
175
|
-
super(
|
|
181
|
+
super(name);
|
|
176
182
|
this.description(description)
|
|
177
183
|
.requiredOption('-i --id <id>', 'user ID')
|
|
178
184
|
.requiredOption('-n --name <name>', 'user name')
|
package/package.json
CHANGED
package/src/AssetCommand.ts
CHANGED
|
@@ -19,8 +19,9 @@ export class AssetCommand extends Command {
|
|
|
19
19
|
this.description(description)
|
|
20
20
|
this.addCommand(new AssetList('list', 'list assets'))
|
|
21
21
|
this.addCommand(new AssetList('l', '(l)ist assets'))
|
|
22
|
-
this.addCommand(new
|
|
23
|
-
this.addCommand(new
|
|
22
|
+
this.addCommand(new AssetU('upload', 'upload asset content from source files to a <destination> path'))
|
|
23
|
+
this.addCommand(new AssetU('update', 'update properties of asset identified by its <id>'))
|
|
24
|
+
this.addCommand(new AssetU('u', '(u)pload assets content from sources or (u)pdate asset properties'))
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -28,6 +29,7 @@ class AssetList extends Cmd {
|
|
|
28
29
|
constructor(name: string, description: string) {
|
|
29
30
|
super(name)
|
|
30
31
|
this.description(description)
|
|
32
|
+
.option('-d --dest <destination>', 'filter assets whose pathname begins with destination')
|
|
31
33
|
.option('-s --sort <columns>', 'sort list by column numbers (begins by 0) separated by comma')
|
|
32
34
|
.action(async (options: any) => { await this.commandList(options) })
|
|
33
35
|
}
|
|
@@ -38,7 +40,11 @@ class AssetList extends Cmd {
|
|
|
38
40
|
|
|
39
41
|
const dbClient = new DBClient(this.dbManager)
|
|
40
42
|
dbClient.selectFromTable('List of Assets', 'cyk_asset',
|
|
41
|
-
{
|
|
43
|
+
{
|
|
44
|
+
fields: 'asset_id,asset_route,asset_auth,asset_access,asset_mimetype,asset_last_update', sort: options.sort || '1',
|
|
45
|
+
where: (options.dest ? "asset_route like '" + options.dest + "%'" : undefined)
|
|
46
|
+
}
|
|
47
|
+
|
|
42
48
|
)
|
|
43
49
|
}
|
|
44
50
|
catch (err) {
|
|
@@ -47,26 +53,28 @@ class AssetList extends Cmd {
|
|
|
47
53
|
}
|
|
48
54
|
}
|
|
49
55
|
|
|
50
|
-
//----------------------------------------------------------------------------------------------
|
|
51
|
-
// class AssetUpload
|
|
52
|
-
//----------------------------------------------------------------------------------------------
|
|
53
|
-
|
|
54
56
|
interface FileDescriptor {
|
|
55
57
|
path: string
|
|
56
58
|
mtime: Date
|
|
57
59
|
id?: number
|
|
58
60
|
}
|
|
59
|
-
|
|
61
|
+
/**
|
|
62
|
+
* class AssetU
|
|
63
|
+
*/
|
|
64
|
+
class AssetU extends Cmd {
|
|
60
65
|
|
|
61
66
|
constructor(name: string, description: string) {
|
|
62
67
|
super(name)
|
|
63
68
|
this.description(description)
|
|
69
|
+
.option('-i --id <id>', 'asset id to update properties')
|
|
70
|
+
.option('--auth <auth_schema>', 'authentication schema : basic | token | cookie | any | none, default is none')
|
|
71
|
+
.option('--access <access>', 'access rights required')
|
|
64
72
|
.option('-d --dest <destination>', 'destination path, directory name')
|
|
65
73
|
.option('-c --clean', 'clean destination path before uploading')
|
|
66
74
|
.option('-y --yes', 'upload list is automatically confirmed')
|
|
67
75
|
.argument('[sources...]', 'local files or directories to upload as assets to the server')
|
|
68
76
|
.action(async (sources: any, options: any) => {
|
|
69
|
-
await this.
|
|
77
|
+
await this.commandU(sources, options)
|
|
70
78
|
})
|
|
71
79
|
}
|
|
72
80
|
|
|
@@ -81,6 +89,51 @@ class AssetUpload extends Cmd {
|
|
|
81
89
|
return result
|
|
82
90
|
}
|
|
83
91
|
|
|
92
|
+
/**
|
|
93
|
+
* method commandU
|
|
94
|
+
* @param sources
|
|
95
|
+
* @param options
|
|
96
|
+
*/
|
|
97
|
+
async commandU(sources: string[], options: any) {
|
|
98
|
+
if (sources.length > 0) {
|
|
99
|
+
// upload
|
|
100
|
+
logger.debug('upload sources :', sources)
|
|
101
|
+
await this.commandUpload(sources, options)
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
// update
|
|
105
|
+
logger.debug('update', options)
|
|
106
|
+
await this.commandUpdate(options)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* method commandUpdate
|
|
112
|
+
* @param options
|
|
113
|
+
*/
|
|
114
|
+
async commandUpdate(options: any) {
|
|
115
|
+
try {
|
|
116
|
+
await this.prologue(options)
|
|
117
|
+
if (this.dbManager === undefined) throw 'dbManager undefined'
|
|
118
|
+
|
|
119
|
+
if (options.id === undefined) throw '<id_or_route> of asset to update is missing'
|
|
120
|
+
|
|
121
|
+
const dbAsset = await this.dbManager.dbAssetExist(options.id)
|
|
122
|
+
if (dbAsset === undefined) throw 'Asset ' + options.id + ' not found'
|
|
123
|
+
|
|
124
|
+
await this.updateAuthAccess('cyk_asset', 'assert', dbAsset.id || '', options)
|
|
125
|
+
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
logger.error(err)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* method commandUpload
|
|
134
|
+
* @param sources
|
|
135
|
+
* @param options
|
|
136
|
+
*/
|
|
84
137
|
async commandUpload(sources: string[], options: any) {
|
|
85
138
|
|
|
86
139
|
try {
|
|
@@ -89,6 +142,12 @@ class AssetUpload extends Cmd {
|
|
|
89
142
|
|
|
90
143
|
if (sources.length === 0) throw 'no source to upload'
|
|
91
144
|
|
|
145
|
+
if (options.auth && ' basic | token | cookie | any | none'.indexOf(options.auth) === -1) {
|
|
146
|
+
throw 'valid authentication schemas are : basic | token | cookie | any | none'
|
|
147
|
+
}
|
|
148
|
+
logger.debug('options : ', options)
|
|
149
|
+
logger.debug('auth : ' + options.auth)
|
|
150
|
+
|
|
92
151
|
let dest = "/"
|
|
93
152
|
if (options.dest !== undefined) dest = options.dest
|
|
94
153
|
if (dest.substring(0, 1) !== '/') dest = '/' + dest
|
|
@@ -108,7 +167,7 @@ class AssetUpload extends Cmd {
|
|
|
108
167
|
else if (filestat.isFile() === true) {
|
|
109
168
|
const base = path.parse(source).base
|
|
110
169
|
logger.debug('upload file ' + source + ' to ' + dest + base)
|
|
111
|
-
await this.uploadAsset({ path: source, mtime: filestat.mtime }, dest + base)
|
|
170
|
+
await this.uploadAsset({ path: source, mtime: filestat.mtime }, dest + base, options.auth)
|
|
112
171
|
}
|
|
113
172
|
}
|
|
114
173
|
}
|
|
@@ -124,7 +183,7 @@ class AssetUpload extends Cmd {
|
|
|
124
183
|
async cleanDestination(dest: string) {
|
|
125
184
|
|
|
126
185
|
const remoteList = await this.scanAssets()
|
|
127
|
-
for(let ind = 0; ind < remoteList.length; ind++) {
|
|
186
|
+
for (let ind = 0; ind < remoteList.length; ind++) {
|
|
128
187
|
const fd = remoteList[ind]
|
|
129
188
|
if (fd.path.startsWith(dest)) {
|
|
130
189
|
const url = '/api/admin/assets/' + fd.id
|
|
@@ -168,7 +227,7 @@ class AssetUpload extends Cmd {
|
|
|
168
227
|
}
|
|
169
228
|
|
|
170
229
|
if (uploadConfirmed === true) {
|
|
171
|
-
await this.uploadFiles(dirName, uploadList, dest)
|
|
230
|
+
await this.uploadFiles(dirName, uploadList, dest, options.auth)
|
|
172
231
|
}
|
|
173
232
|
|
|
174
233
|
// const rl = readline.createInterface(process.stdin, process.stdout)
|
|
@@ -281,12 +340,12 @@ class AssetUpload extends Cmd {
|
|
|
281
340
|
// uploadFiles
|
|
282
341
|
//----------------------------------------------------------------------------------------------
|
|
283
342
|
|
|
284
|
-
async uploadFiles(dirName: string, uploadList: FileDescriptor[], dest: string) {
|
|
343
|
+
async uploadFiles(dirName: string, uploadList: FileDescriptor[], dest: string, auth: string | undefined) {
|
|
285
344
|
for (let ind = 0; ind < uploadList.length; ind++) {
|
|
286
345
|
const upload = uploadList[ind]
|
|
287
346
|
const route = dest + upload.path.substring(dirName.length)
|
|
288
347
|
logger.debug('upload ' + upload.path + ' to ' + route)
|
|
289
|
-
await this.uploadAsset(upload, route)
|
|
348
|
+
await this.uploadAsset(upload, route, auth)
|
|
290
349
|
}
|
|
291
350
|
}
|
|
292
351
|
|
|
@@ -294,8 +353,8 @@ class AssetUpload extends Cmd {
|
|
|
294
353
|
// uploadAsset
|
|
295
354
|
//----------------------------------------------------------------------------------------------
|
|
296
355
|
|
|
297
|
-
async uploadAsset(upload: FileDescriptor, route: string) {
|
|
298
|
-
logger.debug('uploadAsset ' + upload.path + ' to route ' + route + ' with mimetype ' + this.mimetypeLookup(upload.path))
|
|
356
|
+
async uploadAsset(upload: FileDescriptor, route: string, auth?: string) {
|
|
357
|
+
logger.debug('uploadAsset ' + upload.path + ' to route ' + route + ' with mimetype ' + this.mimetypeLookup(upload.path) + ', auth : ' + auth)
|
|
299
358
|
|
|
300
359
|
try {
|
|
301
360
|
let dbAsset: DBAsset | undefined = await this.dbManager?.dbAssetExist(route)
|
|
@@ -306,7 +365,9 @@ class AssetUpload extends Cmd {
|
|
|
306
365
|
if (mimetype === false) throw 'mimetype false for ' + upload
|
|
307
366
|
dbAsset.mimetype = mimetype
|
|
308
367
|
dbAsset.route = route
|
|
309
|
-
|
|
368
|
+
dbAsset.auth = auth
|
|
369
|
+
if (dbAsset.auth === 'none') dbAsset.auth = undefined
|
|
370
|
+
|
|
310
371
|
// const fstat = fs.statSync(fileName)
|
|
311
372
|
dbAsset.last_update = upload.mtime
|
|
312
373
|
|
package/src/Cmd.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Command } from "commander";
|
|
|
3
3
|
import dotenv from 'dotenv'
|
|
4
4
|
import loglevel from 'loglevel'
|
|
5
5
|
import { NodeCrypto } from "./NodeCrypto";
|
|
6
|
+
import { DBClient } from "./DBClient";
|
|
6
7
|
const logger = loglevel.getLogger('Cmd.ts')
|
|
7
8
|
logger.setLevel('debug')
|
|
8
9
|
|
|
@@ -35,4 +36,62 @@ export class Cmd extends Command {
|
|
|
35
36
|
|
|
36
37
|
|
|
37
38
|
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* method updateAuthAccess
|
|
42
|
+
* @param tableName
|
|
43
|
+
* @param prefix
|
|
44
|
+
* @param id
|
|
45
|
+
* @param options
|
|
46
|
+
*/
|
|
47
|
+
async updateAuthAccess(tableName: string, prefix: string, id: string, options: any) {
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
|
|
51
|
+
let dclAuth: string | undefined
|
|
52
|
+
|
|
53
|
+
if (options.auth) {
|
|
54
|
+
if (' basic | token | cookie | any | none | null '.indexOf(' ' + options.auth + ' ') === -1) {
|
|
55
|
+
throw 'valid authentication schemas are : basic | token | cookie | any | null'
|
|
56
|
+
}
|
|
57
|
+
dclAuth = `<string name='${prefix}_auth'>`
|
|
58
|
+
if (' none | null '.indexOf(' ' + options.auth + ' ') === -1)
|
|
59
|
+
dclAuth += ` "${options.auth}" `
|
|
60
|
+
else
|
|
61
|
+
dclAuth += ' null '
|
|
62
|
+
dclAuth += "</string>"
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let dclAccess: string | undefined
|
|
66
|
+
|
|
67
|
+
if (options.access) {
|
|
68
|
+
|
|
69
|
+
dclAccess = `<string name='${prefix}_access'> `
|
|
70
|
+
if (' null | none '.indexOf(' ' + options.access + ' ') === -1)
|
|
71
|
+
dclAccess += `"${options.access}"`
|
|
72
|
+
else
|
|
73
|
+
dclAccess += ' null '
|
|
74
|
+
dclAccess += "</string>"
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const inst = `
|
|
78
|
+
<db.update table='${tableName}'>
|
|
79
|
+
<object>
|
|
80
|
+
<number name='${prefix}_id'>${id}</number>
|
|
81
|
+
${dclAuth}
|
|
82
|
+
${dclAccess ? dclAccess : ''}
|
|
83
|
+
</object>
|
|
84
|
+
</db.update>
|
|
85
|
+
`
|
|
86
|
+
|
|
87
|
+
if (! this.dbManager) throw 'prologue() has not been called before'
|
|
88
|
+
|
|
89
|
+
const dbClient = new DBClient(this.dbManager)
|
|
90
|
+
dbClient.execInstructions(inst)
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
logger.error(err)
|
|
94
|
+
throw err
|
|
95
|
+
}
|
|
96
|
+
}
|
|
38
97
|
}
|
package/src/DBClient.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { BasicType, DBColumn, DBExecuteRequest, DBManager, DBTable, ObjectData, parseXML, PrimitiveData } from "@cyklang/core";
|
|
1
|
+
import { BasicType, DBColumn, DBExecuteRequest, DBManager, DBTable, ObjectData, parseXML, PrimitiveData, Script, XmlError } from "@cyklang/core";
|
|
2
2
|
import loglevel from "loglevel";
|
|
3
|
+
import { errorconsole } from "./console";
|
|
3
4
|
const logger = loglevel.getLogger('DBClient.ts')
|
|
4
5
|
logger.setLevel('debug')
|
|
5
6
|
// DBManager wrapper class
|
|
@@ -10,6 +11,39 @@ export class DBClient {
|
|
|
10
11
|
this.dbManager = dbManager
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
* method execInstructions
|
|
16
|
+
* @param source
|
|
17
|
+
*/
|
|
18
|
+
async execInstructions(source: string) {
|
|
19
|
+
const script = `<?xml-model href="https://www.cyklang.net/schema/cyklang.xsd" type="application/xml" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
|
20
|
+
<module>
|
|
21
|
+
` + source + `
|
|
22
|
+
</module>`
|
|
23
|
+
await this.execScript(script)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* method execScript
|
|
28
|
+
* @param source
|
|
29
|
+
*/
|
|
30
|
+
async execScript(source: string) {
|
|
31
|
+
try {
|
|
32
|
+
const script = new Script(this.dbManager.scope, '', source)
|
|
33
|
+
await script.parseInstructions()
|
|
34
|
+
await script.execute()
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
console.log(source)
|
|
38
|
+
console.log()
|
|
39
|
+
if (err instanceof XmlError) {
|
|
40
|
+
let xmlError = <XmlError>err
|
|
41
|
+
errorconsole(xmlError)
|
|
42
|
+
}
|
|
43
|
+
console.log(err)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
13
47
|
async runQuery() {
|
|
14
48
|
|
|
15
49
|
}
|
package/src/ModuleCommand.ts
CHANGED
|
@@ -14,11 +14,11 @@ export class ModuleCommand extends Command {
|
|
|
14
14
|
super(name)
|
|
15
15
|
this.description('manage modules')
|
|
16
16
|
// upload
|
|
17
|
-
this.addCommand(new
|
|
17
|
+
this.addCommand(new ModuleU('upload', `Upload local module file(s) to the database.
|
|
18
18
|
Module name is the base name of the file. If a module with the same name already exists, it will be updated.
|
|
19
19
|
Otherwise, a new module is inserted in the database. To rename a module, use option --id to indicate the module you want to rename`)
|
|
20
20
|
)
|
|
21
|
-
this.addCommand(new
|
|
21
|
+
this.addCommand(new ModuleU('u', 'shortcut for (u)pload'))
|
|
22
22
|
// download
|
|
23
23
|
this.addCommand(new ModuleDownload('download', 'download module files to the current directory'))
|
|
24
24
|
this.addCommand(new ModuleDownload('d', 'shortcut for (d)ownload'))
|
|
@@ -45,16 +45,57 @@ interface UploadOptions {
|
|
|
45
45
|
id: string | undefined
|
|
46
46
|
env: string | undefined
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* class ModuleU
|
|
51
|
+
*/
|
|
52
|
+
class ModuleU extends Cmd {
|
|
49
53
|
constructor(name: string, description: string) {
|
|
50
54
|
super(name)
|
|
51
55
|
this.description(description)
|
|
52
|
-
.option('
|
|
56
|
+
.option('--auth <auth_schema>', 'authentication schema : basic | token | cookie | any | none, default is none')
|
|
57
|
+
.option('--access <access_right>', 'access rights required')
|
|
58
|
+
.option('-i --id <id>', 'module ID to upload or update')
|
|
53
59
|
.argument('[files...]', 'local module file(s) to upload to the server')
|
|
54
60
|
.action(async (files: any, options: any) => {
|
|
55
|
-
await this.
|
|
61
|
+
await this.commandU(files, options)
|
|
56
62
|
})
|
|
57
63
|
}
|
|
64
|
+
|
|
65
|
+
async commandU(files: string[], options: any) {
|
|
66
|
+
if (files.length > 0) {
|
|
67
|
+
await this.commandUpload(files, options)
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
await this.commandUpdate(options)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* method commandUpdate
|
|
76
|
+
* @param options
|
|
77
|
+
*/
|
|
78
|
+
async commandUpdate(options: any) {
|
|
79
|
+
try {
|
|
80
|
+
await this.prologue(options)
|
|
81
|
+
if (this.dbManager === undefined) throw 'dbManager undefined'
|
|
82
|
+
|
|
83
|
+
if (options.id === undefined) throw '<id_or_route> of module to update is missing'
|
|
84
|
+
|
|
85
|
+
const dbModule = await this.dbManager.getModule(options.id)
|
|
86
|
+
|
|
87
|
+
await this.updateAuthAccess('cyk_module', 'module', dbModule.id || '', options)
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
logger.error(err)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* method commandUpload
|
|
96
|
+
* @param files
|
|
97
|
+
* @param options
|
|
98
|
+
*/
|
|
58
99
|
async commandUpload(files: string[], options: UploadOptions) {
|
|
59
100
|
try {
|
|
60
101
|
await this.prologue(options)
|
package/src/TableCommand.ts
CHANGED
|
@@ -22,6 +22,47 @@ export class TableCommand extends Command {
|
|
|
22
22
|
this.addCommand(new TableList('l', '(l)ist database tables'))
|
|
23
23
|
this.addCommand(new TableData('data', 'table (d)ata'))
|
|
24
24
|
this.addCommand(new TableData('d', 'table (d)ata'))
|
|
25
|
+
this.addCommand(new TableUpdate('update', 'update table properties'))
|
|
26
|
+
this.addCommand(new TableUpdate('u', 'shortcut for (u)pdate table properties'))
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* class TableUpdate
|
|
32
|
+
*/
|
|
33
|
+
class TableUpdate extends Cmd {
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
*
|
|
37
|
+
* @param name
|
|
38
|
+
* @param description
|
|
39
|
+
*/
|
|
40
|
+
constructor(name: string, description: string) {
|
|
41
|
+
super(name)
|
|
42
|
+
this.description(description)
|
|
43
|
+
.option('-n --name <table_name>', 'name of the table whose properties are to be changed')
|
|
44
|
+
.option('--auth <auth_schema>', 'authentication schema : basic | token | cookie | any | none, default is none')
|
|
45
|
+
.option('--access <access>', 'access rights required')
|
|
46
|
+
.action(async (options: any) => {
|
|
47
|
+
await this.commandUpdate(options)
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async commandUpdate(options: any) {
|
|
52
|
+
try {
|
|
53
|
+
await this.prologue(options)
|
|
54
|
+
if (this.dbManager === undefined) throw 'dbManager undefined'
|
|
55
|
+
|
|
56
|
+
if ( ! options.name ) throw '<table_name> is missing'
|
|
57
|
+
|
|
58
|
+
const dbTable = await this.dbManager.dbTableExist(options.name)
|
|
59
|
+
if ( ! dbTable ) throw 'Table ' + options.name + ' not found'
|
|
60
|
+
|
|
61
|
+
await this.updateAuthAccess('cyk_table', 'table', dbTable.id || '', options)
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
logger.error(err)
|
|
65
|
+
}
|
|
25
66
|
}
|
|
26
67
|
}
|
|
27
68
|
|
package/src/UserCommand.ts
CHANGED
|
@@ -11,11 +11,13 @@ export class UserCommand extends Command {
|
|
|
11
11
|
constructor(name: string) {
|
|
12
12
|
super(name)
|
|
13
13
|
this.description('manage users in cyk_user table').version('0.1')
|
|
14
|
-
this.addCommand(new UserAddCmd())
|
|
14
|
+
this.addCommand(new UserAddCmd('add', 'add a new user'))
|
|
15
|
+
this.addCommand(new UserAddCmd('a', 'add a new user'))
|
|
15
16
|
this.addCommand(new UserUpdateCmd('update', 'update user by id all fields except password'))
|
|
16
17
|
this.addCommand(new UserUpdateCmd('u', 'shortcut for (u)pdate'))
|
|
17
18
|
this.addCommand(new UserDeleteCmd('delete', 'delete user by id and name. Both options are mandatory to avoid typing error'))
|
|
18
19
|
this.addCommand(new UserPasswdCmd('passwd', 'change user password'))
|
|
20
|
+
this.addCommand(new UserPasswdCmd('p', 'shortcut for (p)asswd'))
|
|
19
21
|
this.addCommand(new UserListCmd('list', 'list users'))
|
|
20
22
|
this.addCommand(new UserListCmd('l', 'shortcut for (l)ist'))
|
|
21
23
|
}
|
|
@@ -35,12 +37,12 @@ interface Options {
|
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
class UserAddCmd extends Cmd {
|
|
38
|
-
constructor() {
|
|
39
|
-
super(
|
|
40
|
-
this.description(
|
|
40
|
+
constructor(name: string, description: string) {
|
|
41
|
+
super(name)
|
|
42
|
+
this.description(description)
|
|
41
43
|
.requiredOption('-n --name <name>', 'user name')
|
|
42
44
|
.option('-e --email <email>', 'user email address')
|
|
43
|
-
.option('-p --
|
|
45
|
+
.option('-p --password <password>', 'initial password')
|
|
44
46
|
.option('-a --access <acl>', 'access control list')
|
|
45
47
|
.option('-m --module <module_name>', 'module to launch by default')
|
|
46
48
|
.option('-d --disable', 'user not abled to connect')
|
|
@@ -62,7 +64,11 @@ class UserAddCmd extends Cmd {
|
|
|
62
64
|
await this.prologue(options)
|
|
63
65
|
if (this.dbManager === undefined) throw 'dbManager undefined'
|
|
64
66
|
const result = await this.dbManager.dbUserInsert(dbUser)
|
|
65
|
-
logger.debug(result)
|
|
67
|
+
logger.debug('ID', result)
|
|
68
|
+
if (dbUser.password) {
|
|
69
|
+
await this.dbManager.dbUserPasswd(result, dbUser.password)
|
|
70
|
+
logger.info('password changed for user ' + dbUser.name)
|
|
71
|
+
}
|
|
66
72
|
}
|
|
67
73
|
catch (err) {
|
|
68
74
|
logger.error(err)
|
|
@@ -173,7 +179,7 @@ class UserDeleteCmd extends Cmd {
|
|
|
173
179
|
|
|
174
180
|
class UserPasswdCmd extends Cmd {
|
|
175
181
|
constructor(name: string, description: string) {
|
|
176
|
-
super(
|
|
182
|
+
super(name)
|
|
177
183
|
|
|
178
184
|
this.description(description)
|
|
179
185
|
.requiredOption('-i --id <id>', 'user ID')
|
package/test/t26.output
CHANGED
|
@@ -3,3 +3,10 @@ date : <b>Gras</b> <i>Italic </i>
|
|
|
3
3
|
format 1 : Format sans paramètre
|
|
4
4
|
format 2 : Nom : CYK Final
|
|
5
5
|
format 3 : Nom : { CYK Prénom Philippe }
|
|
6
|
+
{"name":"CYK","surname":"Philippe","adresses":[{"town":"Saint-Denis","department":"Reunion"},{"town":"Paris","department":"Paris"}]}
|
|
7
|
+
var1 = undefined
|
|
8
|
+
var2 = undefined
|
|
9
|
+
var1 == var2
|
|
10
|
+
after set var2 from var1
|
|
11
|
+
var1 == var2
|
|
12
|
+
var1 == var3
|
package/test/t26.xml
CHANGED
|
@@ -31,5 +31,42 @@
|
|
|
31
31
|
</object>
|
|
32
32
|
|
|
33
33
|
<print>json(person)</print>
|
|
34
|
+
|
|
35
|
+
<string name="var1"/>
|
|
36
|
+
<string name="var2"/>
|
|
37
|
+
<print>"var1 = " + var1</print>
|
|
38
|
+
<print>"var2 = " + var2</print>
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
<if>
|
|
42
|
+
<condition>var1 == var2</condition>
|
|
43
|
+
<then>
|
|
44
|
+
<print>"var1 == var2"</print>
|
|
45
|
+
</then>
|
|
46
|
+
</if>
|
|
47
|
+
|
|
48
|
+
<set name="var2">var1</set>
|
|
49
|
+
<print>"after set var2 from var1"</print>
|
|
50
|
+
|
|
51
|
+
<if>
|
|
52
|
+
<condition>var1 == var2</condition>
|
|
53
|
+
<then>
|
|
54
|
+
<print>"var1 == var2"</print>
|
|
55
|
+
</then>
|
|
56
|
+
</if>
|
|
57
|
+
|
|
58
|
+
<string name="var3">var1</string>
|
|
59
|
+
|
|
60
|
+
<if>
|
|
61
|
+
<condition>var1 == var3</condition>
|
|
62
|
+
<then>
|
|
63
|
+
<print>"var1 == var3"</print>
|
|
64
|
+
</then>
|
|
65
|
+
<else>
|
|
66
|
+
<print>"var1 !== var3"</print>
|
|
67
|
+
</else>
|
|
68
|
+
</if>
|
|
69
|
+
|
|
70
|
+
|
|
34
71
|
|
|
35
72
|
</module>
|