@cyklang/cli 0.2.1 → 0.2.3
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 +36 -15
- package/build/Cmd.js +18 -13
- package/build/DBClient.d.ts +1 -0
- package/build/DBClient.js +12 -0
- package/build/InitCommand.d.ts +6 -0
- package/build/InitCommand.js +36 -8
- package/build/ModuleCommand.js +9 -1
- package/build/TestCommand.js +1 -1
- package/docker.env +2 -2
- package/package.json +4 -2
- package/src/AssetCommand.ts +50 -26
- package/src/Cmd.ts +18 -12
- package/src/DBClient.ts +16 -0
- package/src/InitCommand.ts +39 -8
- package/src/ModuleCommand.ts +15 -9
- package/src/TestCommand.ts +1 -1
- package/test/t09.output +1 -1
- package/test/t09.xml +1 -1
- package/test/t17.output +2 -0
- package/test/t17.xml +3 -1
- package/test/t20.output +0 -0
- package/test/t20.xml +1 -1
- package/test/t21.xml +11 -5
- package/test/t22.output +0 -0
- package/test/t23.output +48 -0
- package/test/t23.xml +3 -3
- package/test/t24.output +1007 -0
- package/test/t24.xml +20 -0
- package/test/t25.output +4 -0
- package/test/t25.xml +23 -0
package/build/AssetCommand.js
CHANGED
|
@@ -30,7 +30,8 @@ const DBClient_1 = require("./DBClient");
|
|
|
30
30
|
const fs = __importStar(require("fs"));
|
|
31
31
|
const path_1 = __importDefault(require("path"));
|
|
32
32
|
const mime_types_1 = __importDefault(require("mime-types"));
|
|
33
|
-
const
|
|
33
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
34
|
+
// import readline from 'readline'
|
|
34
35
|
const core_1 = require("@cyklang/core");
|
|
35
36
|
const form_data_1 = __importDefault(require("form-data"));
|
|
36
37
|
const logger = (0, loglevel_1.getLogger)('AssetCommand.ts');
|
|
@@ -75,11 +76,22 @@ class AssetUpload extends Cmd_1.Cmd {
|
|
|
75
76
|
this.ignorePatterns = ['.git', 'node_modules'];
|
|
76
77
|
this.description(description)
|
|
77
78
|
.option('-d --dest <destination>', 'route of destination')
|
|
79
|
+
.option('-y --yes', 'upload list is automatically confirmed')
|
|
78
80
|
.argument('[sources...]', 'local files or directories to upload as assets to the server')
|
|
79
81
|
.action(async (sources, options) => {
|
|
80
82
|
await this.commandUpload(sources, options);
|
|
81
83
|
});
|
|
82
84
|
}
|
|
85
|
+
mimetypeLookup(filename) {
|
|
86
|
+
let result;
|
|
87
|
+
if (path_1.default.extname(filename) === '.cyk') {
|
|
88
|
+
result = 'application/xml';
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
result = mime_types_1.default.lookup(filename);
|
|
92
|
+
}
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
83
95
|
async commandUpload(sources, options) {
|
|
84
96
|
try {
|
|
85
97
|
await this.prologue(options);
|
|
@@ -100,7 +112,7 @@ class AssetUpload extends Cmd_1.Cmd {
|
|
|
100
112
|
throw 'source ' + source + ' does not exist';
|
|
101
113
|
const filestat = fs.lstatSync(source);
|
|
102
114
|
if (filestat.isDirectory() === true) {
|
|
103
|
-
await this.uploadDirectory(source, dest);
|
|
115
|
+
await this.uploadDirectory(source, dest, options);
|
|
104
116
|
}
|
|
105
117
|
else if (filestat.isFile() === true) {
|
|
106
118
|
const base = path_1.default.parse(source).base;
|
|
@@ -116,7 +128,7 @@ class AssetUpload extends Cmd_1.Cmd {
|
|
|
116
128
|
//----------------------------------------------------------------------------------------------
|
|
117
129
|
// uploadDirectory
|
|
118
130
|
//----------------------------------------------------------------------------------------------
|
|
119
|
-
async uploadDirectory(source, dest) {
|
|
131
|
+
async uploadDirectory(source, dest, options) {
|
|
120
132
|
const localList = [];
|
|
121
133
|
let dirName;
|
|
122
134
|
if (source.substring(source.length - 1) === '/') {
|
|
@@ -126,7 +138,7 @@ class AssetUpload extends Cmd_1.Cmd {
|
|
|
126
138
|
else {
|
|
127
139
|
dirName = source + '/';
|
|
128
140
|
}
|
|
129
|
-
logger.debug('
|
|
141
|
+
logger.debug('options', options);
|
|
130
142
|
this.scanDir(dirName, localList);
|
|
131
143
|
const remoteList = [];
|
|
132
144
|
await this.scanAssets(remoteList);
|
|
@@ -134,15 +146,24 @@ class AssetUpload extends Cmd_1.Cmd {
|
|
|
134
146
|
// logger.info(fileNames.join('\n'))
|
|
135
147
|
if (uploadList.length === 0)
|
|
136
148
|
throw 'None file to upload';
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (reply
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
149
|
+
let uploadConfirmed = (options.yes !== undefined);
|
|
150
|
+
if (uploadConfirmed === false) {
|
|
151
|
+
const reply = await inquirer_1.default.prompt({ type: 'confirm', name: 'confirm', message: 'Do you want to upload this(these) ' + uploadList.length + ' file(s) ?' });
|
|
152
|
+
if (reply.confirm === true)
|
|
153
|
+
uploadConfirmed = true;
|
|
154
|
+
}
|
|
155
|
+
if (uploadConfirmed === true) {
|
|
144
156
|
await this.uploadFiles(dirName, uploadList, dest);
|
|
145
|
-
}
|
|
157
|
+
}
|
|
158
|
+
// const rl = readline.createInterface(process.stdin, process.stdout)
|
|
159
|
+
// rl.question('Do you want to upload this(these) ' + uploadList.length + ' file(s) (Y/N/y/n) ?', async (reply) => {
|
|
160
|
+
// rl.close()
|
|
161
|
+
// if (reply !== 'Y' && reply !== 'y') {
|
|
162
|
+
// logger.info('upload cancelled')
|
|
163
|
+
// return
|
|
164
|
+
// }
|
|
165
|
+
// await this.uploadFiles(dirName, uploadList, dest)
|
|
166
|
+
// })
|
|
146
167
|
}
|
|
147
168
|
//----------------------------------------------------------------------------------------------
|
|
148
169
|
// buildUploadList
|
|
@@ -208,7 +229,7 @@ class AssetUpload extends Cmd_1.Cmd {
|
|
|
208
229
|
this.scanDir(dirName + fileName + '/', result);
|
|
209
230
|
}
|
|
210
231
|
else {
|
|
211
|
-
if (
|
|
232
|
+
if (this.mimetypeLookup(fileName) === false) {
|
|
212
233
|
logger.info(fileName + ' file extension is unknown and will not be uploaded');
|
|
213
234
|
continue;
|
|
214
235
|
}
|
|
@@ -241,13 +262,13 @@ class AssetUpload extends Cmd_1.Cmd {
|
|
|
241
262
|
// uploadAsset
|
|
242
263
|
//----------------------------------------------------------------------------------------------
|
|
243
264
|
async uploadAsset(upload, route) {
|
|
244
|
-
logger.debug('uploadAsset ' + upload.path + ' to route ' + route + ' with mimetype ' +
|
|
265
|
+
logger.debug('uploadAsset ' + upload.path + ' to route ' + route + ' with mimetype ' + this.mimetypeLookup(upload.path));
|
|
245
266
|
try {
|
|
246
267
|
let dbAsset = await this.dbManager?.dbAssetExist(route);
|
|
247
268
|
if (dbAsset === undefined) {
|
|
248
269
|
dbAsset = new core_1.DBAsset();
|
|
249
270
|
}
|
|
250
|
-
const mimetype =
|
|
271
|
+
const mimetype = this.mimetypeLookup(upload.path);
|
|
251
272
|
if (mimetype === false)
|
|
252
273
|
throw 'mimetype false for ' + upload;
|
|
253
274
|
dbAsset.mimetype = mimetype;
|
package/build/Cmd.js
CHANGED
|
@@ -17,19 +17,24 @@ class Cmd extends commander_1.Command {
|
|
|
17
17
|
this.option('--env <env>', 'path to the environment variables file');
|
|
18
18
|
}
|
|
19
19
|
async prologue(options) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
try {
|
|
21
|
+
const dotenvOutput = dotenv_1.default.config({ path: options.env });
|
|
22
|
+
if (dotenvOutput.error !== undefined)
|
|
23
|
+
throw dotenvOutput.error;
|
|
24
|
+
const structure = new core_1.Structure();
|
|
25
|
+
if (process.env.DBREMOTE_URL === undefined)
|
|
26
|
+
throw 'DBREMOTE_URL undefined';
|
|
27
|
+
logger.debug('Cmd.DBREMOTE_URL ' + process.env.DBREMOTE_URL);
|
|
28
|
+
const nodeCrypto = new NodeCrypto_1.NodeCrypto();
|
|
29
|
+
this.dbRemote = new core_1.DBRemote(structure.scope, process.env.DBREMOTE_URL, nodeCrypto);
|
|
30
|
+
const login = await this.dbRemote.signin(process.env.USER_NAME, undefined, process.env.USER_PASSWORD);
|
|
31
|
+
// logger.debug(login)
|
|
32
|
+
this.dbManager = new core_1.DBManager(structure.scope, this.dbRemote);
|
|
33
|
+
await this.dbManager.initialize();
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
logger.error(err);
|
|
37
|
+
}
|
|
33
38
|
}
|
|
34
39
|
}
|
|
35
40
|
exports.Cmd = Cmd;
|
package/build/DBClient.d.ts
CHANGED
package/build/DBClient.js
CHANGED
|
@@ -76,6 +76,18 @@ class DBClient {
|
|
|
76
76
|
logger.error(err);
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
+
async deleteModule(dbname) {
|
|
80
|
+
try {
|
|
81
|
+
const dbModule = await this.dbManager.dbModuleExist(dbname);
|
|
82
|
+
if (dbModule === undefined) {
|
|
83
|
+
throw ('Module ' + dbname + ' not found');
|
|
84
|
+
}
|
|
85
|
+
await this.dbManager.dbModuleDelete(dbModule);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
logger.error(err);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
79
91
|
}
|
|
80
92
|
exports.DBClient = DBClient;
|
|
81
93
|
class List {
|
package/build/InitCommand.d.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
export declare class InitCommand extends Command {
|
|
3
|
+
PGPORT: string;
|
|
4
|
+
USER_NAME: string;
|
|
5
|
+
USER_PASSWORD: string;
|
|
6
|
+
USER_EMAIL: string;
|
|
7
|
+
CYK_PORT: string;
|
|
3
8
|
constructor(name: string);
|
|
4
9
|
commandInit(options: any): Promise<void>;
|
|
10
|
+
promptParameters(): Promise<void>;
|
|
5
11
|
getRandomInt(min: number, max: number): number;
|
|
6
12
|
generateToken(): string;
|
|
7
13
|
writeEnvFile(): Promise<void>;
|
package/build/InitCommand.js
CHANGED
|
@@ -18,16 +18,25 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
18
18
|
__setModuleDefault(result, mod);
|
|
19
19
|
return result;
|
|
20
20
|
};
|
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
|
+
};
|
|
21
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
25
|
exports.InitCommand = void 0;
|
|
23
26
|
const commander_1 = require("commander");
|
|
24
27
|
const fs = __importStar(require("fs"));
|
|
28
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
25
29
|
const loglevel_1 = require("loglevel");
|
|
26
30
|
const logger = (0, loglevel_1.getLogger)('InitCommand.ts');
|
|
27
31
|
logger.setLevel('debug');
|
|
28
32
|
class InitCommand extends commander_1.Command {
|
|
29
33
|
constructor(name) {
|
|
30
34
|
super(name);
|
|
35
|
+
this.PGPORT = "5432";
|
|
36
|
+
this.USER_NAME = "cyk";
|
|
37
|
+
this.USER_PASSWORD = "cyk";
|
|
38
|
+
this.USER_EMAIL = "my-email@my-domain";
|
|
39
|
+
this.CYK_PORT = "3000";
|
|
31
40
|
this.description('initialize a folder with files necessary for a cyklang project')
|
|
32
41
|
.action(async (options) => {
|
|
33
42
|
await this.commandInit(options);
|
|
@@ -35,6 +44,7 @@ class InitCommand extends commander_1.Command {
|
|
|
35
44
|
}
|
|
36
45
|
async commandInit(options) {
|
|
37
46
|
try {
|
|
47
|
+
await this.promptParameters();
|
|
38
48
|
await this.writeEnvFile();
|
|
39
49
|
await this.writeDockerComposeFile();
|
|
40
50
|
}
|
|
@@ -42,6 +52,24 @@ class InitCommand extends commander_1.Command {
|
|
|
42
52
|
logger.error(err);
|
|
43
53
|
}
|
|
44
54
|
}
|
|
55
|
+
async promptParameters() {
|
|
56
|
+
const reply = await inquirer_1.default.prompt([
|
|
57
|
+
{ type: "number", name: 'PGPORT', default: this.PGPORT, message: 'Postgresql Port' },
|
|
58
|
+
{ type: 'number', name: 'CYK_PORT', default: this.CYK_PORT, message: 'NodeJS Port' },
|
|
59
|
+
{ type: 'input', name: 'USER_NAME', default: this.USER_NAME, message: 'Admin User Login' },
|
|
60
|
+
{ type: 'input', name: 'USER_PASSWORD', default: this.USER_PASSWORD, message: 'Admin User Password' },
|
|
61
|
+
{ type: 'input', name: 'USER_EMAIL', default: this.USER_EMAIL, message: 'Admin Use Email' },
|
|
62
|
+
{ type: "confirm", name: 'confirm' }
|
|
63
|
+
]);
|
|
64
|
+
// logger.debug(reply)
|
|
65
|
+
if (reply.confirm === false)
|
|
66
|
+
throw 'Command cancelled';
|
|
67
|
+
this.PGPORT = reply.PGPORT;
|
|
68
|
+
this.CYK_PORT = reply.CYK_PORT;
|
|
69
|
+
this.USER_NAME = reply.USER_NAME;
|
|
70
|
+
this.USER_PASSWORD = reply.USER_PASSWORD;
|
|
71
|
+
this.USER_EMAIL = reply.USER_EMAIL;
|
|
72
|
+
}
|
|
45
73
|
// developer.mozilla.org Math.random()
|
|
46
74
|
// On renvoie un entier aléatoire entre une valeur min (incluse)
|
|
47
75
|
// et une valeur max (exclue).
|
|
@@ -69,7 +97,7 @@ class InitCommand extends commander_1.Command {
|
|
|
69
97
|
const content = `# PostgreSql connection
|
|
70
98
|
# used by psql command line utility
|
|
71
99
|
PGHOST="localhost"
|
|
72
|
-
PGPORT="
|
|
100
|
+
PGPORT="${this.PGPORT}"
|
|
73
101
|
PGUSER="postgres"
|
|
74
102
|
PGPASSWORD="postgres"
|
|
75
103
|
|
|
@@ -80,9 +108,9 @@ POSTGRES_PASSWORD="postgres"
|
|
|
80
108
|
|
|
81
109
|
# admin user
|
|
82
110
|
# created at database initialization
|
|
83
|
-
ADMIN_NAME
|
|
84
|
-
ADMIN_PASSWORD
|
|
85
|
-
ADMIN_EMAIL
|
|
111
|
+
ADMIN_NAME=${this.USER_NAME}
|
|
112
|
+
ADMIN_PASSWORD=${this.USER_PASSWORD}
|
|
113
|
+
ADMIN_EMAIL=${this.USER_EMAIL}
|
|
86
114
|
|
|
87
115
|
# JWT token generation
|
|
88
116
|
# e.g. https://www.allkeysgenerator.com
|
|
@@ -99,10 +127,10 @@ LOGIN_APPLI="index"
|
|
|
99
127
|
|
|
100
128
|
# credential used by cyk CLI
|
|
101
129
|
|
|
102
|
-
USER_NAME
|
|
103
|
-
USER_PASSWORD
|
|
104
|
-
CYK_PORT="
|
|
105
|
-
DBREMOTE_URL="http://localhost
|
|
130
|
+
USER_NAME=${this.USER_NAME}
|
|
131
|
+
USER_PASSWORD=${this.USER_PASSWORD}
|
|
132
|
+
CYK_PORT="${this.CYK_PORT}"
|
|
133
|
+
DBREMOTE_URL="http://localhost:${this.CYK_PORT}"
|
|
106
134
|
`;
|
|
107
135
|
fs.writeFileSync(envFilename, content);
|
|
108
136
|
logger.debug('created ' + envFilename);
|
package/build/ModuleCommand.js
CHANGED
|
@@ -48,7 +48,9 @@ Otherwise, a new module is inserted in the database. To rename a module, use opt
|
|
|
48
48
|
// list
|
|
49
49
|
this.addCommand(new ModuleList('list', 'List modules'));
|
|
50
50
|
this.addCommand(new ModuleList('l', 'shortcut for (l)ist'));
|
|
51
|
-
// rename
|
|
51
|
+
// rename **TODO**
|
|
52
|
+
// delete
|
|
53
|
+
this.addCommand(new ModuleDelete('delete', 'delete module from database'));
|
|
52
54
|
}
|
|
53
55
|
}
|
|
54
56
|
exports.ModuleCommand = ModuleCommand;
|
|
@@ -217,6 +219,12 @@ class ModuleDelete extends Cmd_1.Cmd {
|
|
|
217
219
|
throw 'dbManager undefined';
|
|
218
220
|
if (files.length === 0)
|
|
219
221
|
throw 'no module to delete';
|
|
222
|
+
const dbClient = new DBClient_1.DBClient(this.dbManager);
|
|
223
|
+
for (let ind = 0; ind < files.length; ind++) {
|
|
224
|
+
const dbname = files.at(ind);
|
|
225
|
+
if (dbname !== undefined)
|
|
226
|
+
dbClient.deleteModule(dbname);
|
|
227
|
+
}
|
|
220
228
|
}
|
|
221
229
|
catch (err) {
|
|
222
230
|
logger.error(err);
|
package/build/TestCommand.js
CHANGED
|
@@ -46,7 +46,7 @@ class TestCommand extends Cmd_1.Cmd {
|
|
|
46
46
|
for (let ind = 0; ind < files.length; ind++) {
|
|
47
47
|
const result = await testfile(files[ind]);
|
|
48
48
|
if (result === false) {
|
|
49
|
-
logger.debug('*********** FAILURE ' +
|
|
49
|
+
logger.debug('*********** FAILURE ' + files[ind] + ' ***************');
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
}
|
package/docker.env
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyklang/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "cyklang CLI",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -17,16 +17,18 @@
|
|
|
17
17
|
"author": "",
|
|
18
18
|
"license": "ISC",
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@cyklang/core": "^0.
|
|
20
|
+
"@cyklang/core": "^0.4.2",
|
|
21
21
|
"commander": "^9.4.0",
|
|
22
22
|
"dotenv": "^16.0.1",
|
|
23
23
|
"form-data": "^4.0.0",
|
|
24
|
+
"inquirer": "^8.2.5",
|
|
24
25
|
"loglevel": "^1.8.0",
|
|
25
26
|
"mime-types": "^2.1.35",
|
|
26
27
|
"pako": "^2.0.4",
|
|
27
28
|
"xml": "^1.0.1"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
31
|
+
"@types/inquirer": "^8.2.4",
|
|
30
32
|
"@types/mime-types": "^2.1.1",
|
|
31
33
|
"@types/pako": "^2.0.0",
|
|
32
34
|
"@types/sax": "^1.2.4",
|
package/src/AssetCommand.ts
CHANGED
|
@@ -5,7 +5,8 @@ import { DBClient } from "./DBClient"
|
|
|
5
5
|
import * as fs from "fs"
|
|
6
6
|
import path from "path"
|
|
7
7
|
import mime from 'mime-types'
|
|
8
|
-
import
|
|
8
|
+
import inquirer from 'inquirer'
|
|
9
|
+
// import readline from 'readline'
|
|
9
10
|
import { DBAsset, DBExecuteRequest, ObjectData, parseXML, PrimitiveData } from "@cyklang/core"
|
|
10
11
|
import FormData from 'form-data'
|
|
11
12
|
|
|
@@ -60,12 +61,24 @@ class AssetUpload extends Cmd {
|
|
|
60
61
|
super(name)
|
|
61
62
|
this.description(description)
|
|
62
63
|
.option('-d --dest <destination>', 'route of destination')
|
|
64
|
+
.option('-y --yes', 'upload list is automatically confirmed')
|
|
63
65
|
.argument('[sources...]', 'local files or directories to upload as assets to the server')
|
|
64
66
|
.action(async (sources: any, options: any) => {
|
|
65
67
|
await this.commandUpload(sources, options)
|
|
66
68
|
})
|
|
67
69
|
}
|
|
68
70
|
|
|
71
|
+
mimetypeLookup(filename: string): string | false {
|
|
72
|
+
let result: string | false
|
|
73
|
+
if (path.extname(filename) === '.cyk') {
|
|
74
|
+
result = 'application/xml'
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
result = mime.lookup(filename)
|
|
78
|
+
}
|
|
79
|
+
return result
|
|
80
|
+
}
|
|
81
|
+
|
|
69
82
|
async commandUpload(sources: string[], options: any) {
|
|
70
83
|
|
|
71
84
|
try {
|
|
@@ -84,12 +97,12 @@ class AssetUpload extends Cmd {
|
|
|
84
97
|
if (fs.existsSync(source) === false) throw 'source ' + source + ' does not exist'
|
|
85
98
|
const filestat = fs.lstatSync(source)
|
|
86
99
|
if (filestat.isDirectory() === true) {
|
|
87
|
-
await this.uploadDirectory(source, dest)
|
|
100
|
+
await this.uploadDirectory(source, dest, options)
|
|
88
101
|
}
|
|
89
102
|
else if (filestat.isFile() === true) {
|
|
90
103
|
const base = path.parse(source).base
|
|
91
104
|
logger.debug('upload file ' + source + ' to ' + dest + base)
|
|
92
|
-
await this.uploadAsset({path:source, mtime: filestat.mtime}, dest + base)
|
|
105
|
+
await this.uploadAsset({ path: source, mtime: filestat.mtime }, dest + base)
|
|
93
106
|
}
|
|
94
107
|
}
|
|
95
108
|
}
|
|
@@ -102,7 +115,7 @@ class AssetUpload extends Cmd {
|
|
|
102
115
|
// uploadDirectory
|
|
103
116
|
//----------------------------------------------------------------------------------------------
|
|
104
117
|
|
|
105
|
-
async uploadDirectory(source: string, dest: string) {
|
|
118
|
+
async uploadDirectory(source: string, dest: string, options: any) {
|
|
106
119
|
|
|
107
120
|
const localList: FileDescriptor[] = []
|
|
108
121
|
let dirName: string
|
|
@@ -114,7 +127,7 @@ class AssetUpload extends Cmd {
|
|
|
114
127
|
dirName = source + '/'
|
|
115
128
|
}
|
|
116
129
|
|
|
117
|
-
logger.debug('
|
|
130
|
+
logger.debug('options', options)
|
|
118
131
|
|
|
119
132
|
this.scanDir(dirName, localList)
|
|
120
133
|
|
|
@@ -126,16 +139,27 @@ class AssetUpload extends Cmd {
|
|
|
126
139
|
// logger.info(fileNames.join('\n'))
|
|
127
140
|
if (uploadList.length === 0) throw 'None file to upload'
|
|
128
141
|
|
|
129
|
-
|
|
130
|
-
rl.question('Do you want to upload this(these) ' + uploadList.length + ' file(s) (Y/N/y/n) ?', async (reply) => {
|
|
131
|
-
rl.close()
|
|
132
|
-
if (reply !== 'Y' && reply !== 'y') {
|
|
133
|
-
logger.info('upload cancelled')
|
|
134
|
-
return
|
|
135
|
-
}
|
|
142
|
+
let uploadConfirmed = (options.yes !== undefined)
|
|
136
143
|
|
|
144
|
+
if (uploadConfirmed === false) {
|
|
145
|
+
const reply = await inquirer.prompt({ type: 'confirm', name: 'confirm', message: 'Do you want to upload this(these) ' + uploadList.length + ' file(s) ?' })
|
|
146
|
+
if (reply.confirm === true) uploadConfirmed = true
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (uploadConfirmed === true) {
|
|
137
150
|
await this.uploadFiles(dirName, uploadList, dest)
|
|
138
|
-
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// const rl = readline.createInterface(process.stdin, process.stdout)
|
|
154
|
+
// rl.question('Do you want to upload this(these) ' + uploadList.length + ' file(s) (Y/N/y/n) ?', async (reply) => {
|
|
155
|
+
// rl.close()
|
|
156
|
+
// if (reply !== 'Y' && reply !== 'y') {
|
|
157
|
+
// logger.info('upload cancelled')
|
|
158
|
+
// return
|
|
159
|
+
// }
|
|
160
|
+
|
|
161
|
+
// await this.uploadFiles(dirName, uploadList, dest)
|
|
162
|
+
// })
|
|
139
163
|
}
|
|
140
164
|
|
|
141
165
|
//----------------------------------------------------------------------------------------------
|
|
@@ -145,26 +169,26 @@ class AssetUpload extends Cmd {
|
|
|
145
169
|
buildUploadList(dirName: string, dest: string, localList: FileDescriptor[], remoteList: FileDescriptor[]): FileDescriptor[] {
|
|
146
170
|
const result: FileDescriptor[] = []
|
|
147
171
|
const remoteMap = new Map<string, FileDescriptor>()
|
|
148
|
-
for(let ind = 0; ind < remoteList.length; ind++) {
|
|
172
|
+
for (let ind = 0; ind < remoteList.length; ind++) {
|
|
149
173
|
const remote = remoteList[ind]
|
|
150
174
|
remoteMap.set(remote.path, remote)
|
|
151
175
|
}
|
|
152
|
-
for(let ind = 0; ind < localList.length; ind++
|
|
176
|
+
for (let ind = 0; ind < localList.length; ind++) {
|
|
153
177
|
const localDesc = localList[ind]
|
|
154
178
|
const route = dest + localDesc.path.substring(dirName.length)
|
|
155
179
|
const remoteDesc = remoteMap.get(route)
|
|
156
180
|
|
|
157
181
|
if (remoteDesc === undefined || remoteDesc.mtime.getTime() + 1000 < localDesc.mtime.getTime()) {
|
|
158
182
|
if (remoteDesc === undefined) logger.debug('remoteDesc undefined')
|
|
159
|
-
else logger.debug('remoteDesc.mtime '+ remoteDesc.mtime.getTime(), 'localDesc.mtime ' + localDesc.mtime.getTime())
|
|
183
|
+
else logger.debug('remoteDesc.mtime ' + remoteDesc.mtime.getTime(), 'localDesc.mtime ' + localDesc.mtime.getTime())
|
|
160
184
|
logger.info(localDesc.path)
|
|
161
185
|
result.push(localDesc)
|
|
162
186
|
}
|
|
163
187
|
}
|
|
164
188
|
return result
|
|
165
189
|
}
|
|
166
|
-
|
|
167
|
-
|
|
190
|
+
|
|
191
|
+
|
|
168
192
|
//----------------------------------------------------------------------------------------------
|
|
169
193
|
// scanAssets
|
|
170
194
|
//----------------------------------------------------------------------------------------------
|
|
@@ -181,13 +205,13 @@ class AssetUpload extends Cmd {
|
|
|
181
205
|
const tag = parseXML('scanAssets', xmlResult)
|
|
182
206
|
const objResult = await this.dbManager.scope.structure.objectDataType.parseData(tag, this.dbManager.scope) as ObjectData
|
|
183
207
|
const rows = (objResult.variables.getData('cyk_asset') as ObjectData).variables
|
|
184
|
-
for(let ind = 0; ind < rows.list.length; ind++) {
|
|
185
|
-
const {variable: row} = rows.list[ind]
|
|
208
|
+
for (let ind = 0; ind < rows.list.length; ind++) {
|
|
209
|
+
const { variable: row } = rows.list[ind]
|
|
186
210
|
const record = row.data as ObjectData
|
|
187
211
|
const asset_route = (record.variables.getData('asset_route') as PrimitiveData).value as string
|
|
188
212
|
const asset_last_update = (record.variables.getData('asset_last_update') as PrimitiveData).value as Date
|
|
189
213
|
// logger.debug('asset_route ' + asset_route,'asset_last_update ' + asset_last_update)
|
|
190
|
-
result.push({path: asset_route, mtime: asset_last_update})
|
|
214
|
+
result.push({ path: asset_route, mtime: asset_last_update })
|
|
191
215
|
}
|
|
192
216
|
}
|
|
193
217
|
|
|
@@ -205,12 +229,12 @@ class AssetUpload extends Cmd {
|
|
|
205
229
|
this.scanDir(dirName + fileName + '/', result)
|
|
206
230
|
}
|
|
207
231
|
else {
|
|
208
|
-
if (
|
|
232
|
+
if (this.mimetypeLookup(fileName) === false) {
|
|
209
233
|
logger.info(fileName + ' file extension is unknown and will not be uploaded')
|
|
210
234
|
continue
|
|
211
235
|
}
|
|
212
236
|
//const dbAssetExist = this.dbManager?.dbAssetExist()
|
|
213
|
-
result.push({path: dirName + fileName, mtime: fstat.mtime})
|
|
237
|
+
result.push({ path: dirName + fileName, mtime: fstat.mtime })
|
|
214
238
|
// logger.debug(dirName + '/' + fileName)
|
|
215
239
|
}
|
|
216
240
|
}
|
|
@@ -248,14 +272,14 @@ class AssetUpload extends Cmd {
|
|
|
248
272
|
//----------------------------------------------------------------------------------------------
|
|
249
273
|
|
|
250
274
|
async uploadAsset(upload: FileDescriptor, route: string) {
|
|
251
|
-
logger.debug('uploadAsset ' + upload.path + ' to route ' + route + ' with mimetype ' +
|
|
275
|
+
logger.debug('uploadAsset ' + upload.path + ' to route ' + route + ' with mimetype ' + this.mimetypeLookup(upload.path))
|
|
252
276
|
|
|
253
277
|
try {
|
|
254
278
|
let dbAsset: DBAsset | undefined = await this.dbManager?.dbAssetExist(route)
|
|
255
279
|
if (dbAsset === undefined) {
|
|
256
280
|
dbAsset = new DBAsset()
|
|
257
281
|
}
|
|
258
|
-
const mimetype =
|
|
282
|
+
const mimetype = this.mimetypeLookup(upload.path)
|
|
259
283
|
if (mimetype === false) throw 'mimetype false for ' + upload
|
|
260
284
|
dbAsset.mimetype = mimetype
|
|
261
285
|
dbAsset.route = route
|
|
@@ -296,7 +320,7 @@ class AssetUpload extends Cmd {
|
|
|
296
320
|
|
|
297
321
|
const route = '/upload/cyk_asset/asset_content?asset_id=' + dbAsset.id
|
|
298
322
|
const resp = await this.dbRemote?.apiServer.post(route, form)
|
|
299
|
-
if (
|
|
323
|
+
if (resp.status === 200) {
|
|
300
324
|
logger.info(fileName + ' uploaded')
|
|
301
325
|
}
|
|
302
326
|
}
|
package/src/Cmd.ts
CHANGED
|
@@ -17,18 +17,24 @@ export class Cmd extends Command {
|
|
|
17
17
|
|
|
18
18
|
async prologue(options: any) {
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
try {
|
|
21
|
+
const dotenvOutput = dotenv.config({path: options.env})
|
|
22
|
+
if (dotenvOutput.error !== undefined) throw dotenvOutput.error
|
|
23
|
+
|
|
24
|
+
const structure = new Structure()
|
|
25
|
+
if (process.env.DBREMOTE_URL === undefined) throw 'DBREMOTE_URL undefined'
|
|
26
|
+
logger.debug('Cmd.DBREMOTE_URL ' + process.env.DBREMOTE_URL)
|
|
27
|
+
const nodeCrypto = new NodeCrypto()
|
|
28
|
+
this.dbRemote = new DBRemote(structure.scope, process.env.DBREMOTE_URL, nodeCrypto)
|
|
29
|
+
const login = await this.dbRemote.signin(process.env.USER_NAME, undefined, process.env.USER_PASSWORD)
|
|
30
|
+
// logger.debug(login)
|
|
31
|
+
|
|
32
|
+
this.dbManager = new DBManager(structure.scope, this.dbRemote)
|
|
33
|
+
await this.dbManager.initialize()
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
logger.error(err)
|
|
37
|
+
}
|
|
22
38
|
|
|
23
|
-
const structure = new Structure()
|
|
24
|
-
if (process.env.DBREMOTE_URL === undefined) throw 'DBREMOTE_URL undefined'
|
|
25
|
-
logger.debug('DBREMOTE_URL ' + process.env.DBREMOTE_URL)
|
|
26
|
-
const nodeCrypto = new NodeCrypto()
|
|
27
|
-
this.dbRemote = new DBRemote(structure.scope, process.env.DBREMOTE_URL, nodeCrypto)
|
|
28
|
-
const login = await this.dbRemote.signin(process.env.USER_NAME, undefined, process.env.USER_PASSWORD)
|
|
29
|
-
// logger.debug(login)
|
|
30
|
-
|
|
31
|
-
this.dbManager = new DBManager(structure.scope, this.dbRemote)
|
|
32
|
-
await this.dbManager.initialize()
|
|
33
39
|
}
|
|
34
40
|
}
|
package/src/DBClient.ts
CHANGED
|
@@ -79,6 +79,22 @@ export class DBClient {
|
|
|
79
79
|
logger.error(err)
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
+
|
|
83
|
+
async deleteModule(dbname: string) {
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
const dbModule = await this.dbManager.dbModuleExist(dbname)
|
|
87
|
+
|
|
88
|
+
if (dbModule === undefined) {
|
|
89
|
+
throw ('Module ' + dbname + ' not found')
|
|
90
|
+
}
|
|
91
|
+
await this.dbManager.dbModuleDelete(dbModule)
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
logger.error(err)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
}
|
|
82
98
|
}
|
|
83
99
|
|
|
84
100
|
class List {
|