@cyklang/cli 0.3.1 → 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.
@@ -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 AssetUpload('upload', 'upload assets from sources'));
46
- this.addCommand(new AssetUpload('u', '(u)pload assets'));
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', { fields: 'asset_id,asset_route,asset_auth,asset_access,asset_mimetype,asset_last_update', sort: options.sort || '1' });
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
- class AssetUpload extends Cmd_1.Cmd {
75
+ /**
76
+ * class AssetU
77
+ */
78
+ class AssetU extends Cmd_1.Cmd {
71
79
  constructor(name, description) {
72
80
  super(name);
73
81
  //----------------------------------------------------------------------------------------------
@@ -75,13 +83,15 @@ class AssetUpload extends Cmd_1.Cmd {
75
83
  //----------------------------------------------------------------------------------------------
76
84
  this.ignorePatterns = ['.git', 'node_modules'];
77
85
  this.description(description)
78
- .option('-a --auth <auth_schema>', 'authentication schema : basic | token | any, default is no authentication')
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')
79
89
  .option('-d --dest <destination>', 'destination path, directory name')
80
90
  .option('-c --clean', 'clean destination path before uploading')
81
91
  .option('-y --yes', 'upload list is automatically confirmed')
82
92
  .argument('[sources...]', 'local files or directories to upload as assets to the server')
83
93
  .action(async (sources, options) => {
84
- await this.commandUpload(sources, options);
94
+ await this.commandU(sources, options);
85
95
  });
86
96
  }
87
97
  mimetypeLookup(filename) {
@@ -94,6 +104,48 @@ class AssetUpload extends Cmd_1.Cmd {
94
104
  }
95
105
  return result;
96
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
+ */
97
149
  async commandUpload(sources, options) {
98
150
  try {
99
151
  await this.prologue(options);
@@ -101,8 +153,8 @@ class AssetUpload extends Cmd_1.Cmd {
101
153
  throw 'dbManager undefined';
102
154
  if (sources.length === 0)
103
155
  throw 'no source to upload';
104
- if (options.auth && ' basic | token | any '.indexOf(options.auth) === -1) {
105
- throw 'valid authentication schemas are : basic | token | any';
156
+ if (options.auth && ' basic | token | cookie | any | none'.indexOf(options.auth) === -1) {
157
+ throw 'valid authentication schemas are : basic | token | cookie | any | none';
106
158
  }
107
159
  logger.debug('options : ', options);
108
160
  logger.debug('auth : ' + options.auth);
@@ -299,6 +351,8 @@ class AssetUpload extends Cmd_1.Cmd {
299
351
  dbAsset.mimetype = mimetype;
300
352
  dbAsset.route = route;
301
353
  dbAsset.auth = auth;
354
+ if (dbAsset.auth === 'none')
355
+ dbAsset.auth = undefined;
302
356
  // const fstat = fs.statSync(fileName)
303
357
  dbAsset.last_update = upload.mtime;
304
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;
@@ -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) {
@@ -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 ModuleUpload('upload', `Upload local module file(s) to the database.
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 ModuleUpload('u', 'shortcut for (u)pload'));
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
- class ModuleUpload extends Cmd_1.Cmd {
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('-i --id <id>', 'module ID to upload')
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.commandUpload(files, options);
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);
@@ -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');
@@ -22,6 +22,7 @@ class UserCommand extends commander_1.Command {
22
22
  this.addCommand(new UserUpdateCmd('u', 'shortcut for (u)pdate'));
23
23
  this.addCommand(new UserDeleteCmd('delete', 'delete user by id and name. Both options are mandatory to avoid typing error'));
24
24
  this.addCommand(new UserPasswdCmd('passwd', 'change user password'));
25
+ this.addCommand(new UserPasswdCmd('p', 'shortcut for (p)asswd'));
25
26
  this.addCommand(new UserListCmd('list', 'list users'));
26
27
  this.addCommand(new UserListCmd('l', 'shortcut for (l)ist'));
27
28
  }
@@ -33,7 +34,7 @@ class UserAddCmd extends Cmd_1.Cmd {
33
34
  this.description(description)
34
35
  .requiredOption('-n --name <name>', 'user name')
35
36
  .option('-e --email <email>', 'user email address')
36
- .option('-p --passwd <password>', 'initial password')
37
+ .option('-p --password <password>', 'initial password')
37
38
  .option('-a --access <acl>', 'access control list')
38
39
  .option('-m --module <module_name>', 'module to launch by default')
39
40
  .option('-d --disable', 'user not abled to connect')
@@ -56,7 +57,11 @@ class UserAddCmd extends Cmd_1.Cmd {
56
57
  if (this.dbManager === undefined)
57
58
  throw 'dbManager undefined';
58
59
  const result = await this.dbManager.dbUserInsert(dbUser);
59
- 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
+ }
60
65
  }
61
66
  catch (err) {
62
67
  logger.error(err);
@@ -173,7 +178,7 @@ class UserDeleteCmd extends Cmd_1.Cmd {
173
178
  }
174
179
  class UserPasswdCmd extends Cmd_1.Cmd {
175
180
  constructor(name, description) {
176
- super('passwd');
181
+ super(name);
177
182
  this.description(description)
178
183
  .requiredOption('-i --id <id>', 'user ID')
179
184
  .requiredOption('-n --name <name>', 'user name')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyklang/cli",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "cyklang CLI",
5
5
  "main": "build/index.js",
6
6
  "scripts": {
@@ -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 AssetUpload('upload', 'upload assets from sources'))
23
- this.addCommand(new AssetUpload('u', '(u)pload assets'))
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
- { fields: 'asset_id,asset_route,asset_auth,asset_access,asset_mimetype,asset_last_update', sort: options.sort || '1' }
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,27 +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
- class AssetUpload extends Cmd {
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)
64
- .option('-a --auth <auth_schema>', 'authentication schema : basic | token | any, default is no authentication')
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')
65
72
  .option('-d --dest <destination>', 'destination path, directory name')
66
73
  .option('-c --clean', 'clean destination path before uploading')
67
74
  .option('-y --yes', 'upload list is automatically confirmed')
68
75
  .argument('[sources...]', 'local files or directories to upload as assets to the server')
69
76
  .action(async (sources: any, options: any) => {
70
- await this.commandUpload(sources, options)
77
+ await this.commandU(sources, options)
71
78
  })
72
79
  }
73
80
 
@@ -82,6 +89,51 @@ class AssetUpload extends Cmd {
82
89
  return result
83
90
  }
84
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
+ */
85
137
  async commandUpload(sources: string[], options: any) {
86
138
 
87
139
  try {
@@ -90,8 +142,8 @@ class AssetUpload extends Cmd {
90
142
 
91
143
  if (sources.length === 0) throw 'no source to upload'
92
144
 
93
- if ( options.auth && ' basic | token | any '.indexOf(options.auth) === -1 ) {
94
- throw 'valid authentication schemas are : basic | token | any'
145
+ if (options.auth && ' basic | token | cookie | any | none'.indexOf(options.auth) === -1) {
146
+ throw 'valid authentication schemas are : basic | token | cookie | any | none'
95
147
  }
96
148
  logger.debug('options : ', options)
97
149
  logger.debug('auth : ' + options.auth)
@@ -131,7 +183,7 @@ class AssetUpload extends Cmd {
131
183
  async cleanDestination(dest: string) {
132
184
 
133
185
  const remoteList = await this.scanAssets()
134
- for(let ind = 0; ind < remoteList.length; ind++) {
186
+ for (let ind = 0; ind < remoteList.length; ind++) {
135
187
  const fd = remoteList[ind]
136
188
  if (fd.path.startsWith(dest)) {
137
189
  const url = '/api/admin/assets/' + fd.id
@@ -314,7 +366,8 @@ class AssetUpload extends Cmd {
314
366
  dbAsset.mimetype = mimetype
315
367
  dbAsset.route = route
316
368
  dbAsset.auth = auth
317
-
369
+ if (dbAsset.auth === 'none') dbAsset.auth = undefined
370
+
318
371
  // const fstat = fs.statSync(fileName)
319
372
  dbAsset.last_update = upload.mtime
320
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
  }
@@ -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 ModuleUpload('upload', `Upload local module file(s) to the database.
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 ModuleUpload('u', 'shortcut for (u)pload'))
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
- class ModuleUpload extends Cmd {
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('-i --id <id>', 'module ID to upload')
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.commandUpload(files, options)
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)
@@ -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
 
@@ -17,6 +17,7 @@ export class UserCommand extends Command {
17
17
  this.addCommand(new UserUpdateCmd('u', 'shortcut for (u)pdate'))
18
18
  this.addCommand(new UserDeleteCmd('delete', 'delete user by id and name. Both options are mandatory to avoid typing error'))
19
19
  this.addCommand(new UserPasswdCmd('passwd', 'change user password'))
20
+ this.addCommand(new UserPasswdCmd('p', 'shortcut for (p)asswd'))
20
21
  this.addCommand(new UserListCmd('list', 'list users'))
21
22
  this.addCommand(new UserListCmd('l', 'shortcut for (l)ist'))
22
23
  }
@@ -41,7 +42,7 @@ class UserAddCmd extends Cmd {
41
42
  this.description(description)
42
43
  .requiredOption('-n --name <name>', 'user name')
43
44
  .option('-e --email <email>', 'user email address')
44
- .option('-p --passwd <password>', 'initial password')
45
+ .option('-p --password <password>', 'initial password')
45
46
  .option('-a --access <acl>', 'access control list')
46
47
  .option('-m --module <module_name>', 'module to launch by default')
47
48
  .option('-d --disable', 'user not abled to connect')
@@ -63,7 +64,11 @@ class UserAddCmd extends Cmd {
63
64
  await this.prologue(options)
64
65
  if (this.dbManager === undefined) throw 'dbManager undefined'
65
66
  const result = await this.dbManager.dbUserInsert(dbUser)
66
- 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
+ }
67
72
  }
68
73
  catch (err) {
69
74
  logger.error(err)
@@ -174,7 +179,7 @@ class UserDeleteCmd extends Cmd {
174
179
 
175
180
  class UserPasswdCmd extends Cmd {
176
181
  constructor(name: string, description: string) {
177
- super('passwd')
182
+ super(name)
178
183
 
179
184
  this.description(description)
180
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>