@cyklang/cli 0.4.0 → 0.5.1
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 +120 -40
- package/build/Cmd.js +1 -1
- package/build/DBClient.d.ts +1 -1
- package/build/DBClient.js +8 -2
- package/build/InitCommand.js +5 -1
- package/build/InstallCommand.d.ts +10 -0
- package/build/InstallCommand.js +87 -0
- package/build/ModuleCommand.d.ts +7 -0
- package/build/ModuleCommand.js +39 -26
- package/build/OpenCommand.d.ts +5 -0
- package/build/OpenCommand.js +34 -0
- package/build/RunCommand.d.ts +1 -1
- package/build/RunCommand.js +7 -3
- package/build/TableCommand.js +5 -1
- package/build/TestCommand.js +5 -1
- package/build/console.js +5 -1
- package/build/index.js +8 -3
- package/package.json +5 -4
- package/src/AssetCommand.ts +129 -41
- package/src/Cmd.ts +1 -1
- package/src/DBClient.ts +16 -8
- package/src/InstallCommand.ts +71 -0
- package/src/ModuleCommand.ts +34 -25
- package/src/OpenCommand.ts +31 -0
- package/src/RunCommand.ts +2 -2
- package/src/index.ts +8 -3
- package/test/t27.output +2 -0
- package/test/t27.xml +18 -0
- package/tsconfig.json +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyklang/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "cyklang CLI",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -17,13 +17,14 @@
|
|
|
17
17
|
"author": "",
|
|
18
18
|
"license": "ISC",
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@cyklang/core": "^0.5.
|
|
20
|
+
"@cyklang/core": "^0.5.2",
|
|
21
21
|
"commander": "^9.4.0",
|
|
22
22
|
"dotenv": "^16.0.1",
|
|
23
23
|
"form-data": "^4.0.0",
|
|
24
24
|
"inquirer": "^8.2.5",
|
|
25
25
|
"loglevel": "^1.8.0",
|
|
26
26
|
"mime-types": "^2.1.35",
|
|
27
|
+
"open": "^9.1.0",
|
|
27
28
|
"pako": "^2.0.4"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
@@ -32,8 +33,8 @@
|
|
|
32
33
|
"@types/pako": "^2.0.0",
|
|
33
34
|
"@types/sax": "^1.2.4",
|
|
34
35
|
"nodemon": "^2.0.16",
|
|
35
|
-
"ts-node": "^10.
|
|
36
|
-
"typescript": "
|
|
36
|
+
"ts-node": "^10.9.1",
|
|
37
|
+
"typescript": "^5.2.2"
|
|
37
38
|
},
|
|
38
39
|
"bin": {
|
|
39
40
|
"cyk": "build/index.js"
|
package/src/AssetCommand.ts
CHANGED
|
@@ -7,12 +7,44 @@ import path from "path"
|
|
|
7
7
|
import mime from 'mime-types'
|
|
8
8
|
import inquirer from 'inquirer'
|
|
9
9
|
// import readline from 'readline'
|
|
10
|
-
import { DBAsset, DBExecuteRequest, ObjectData, parseXML, PrimitiveData } from "@cyklang/core"
|
|
10
|
+
import { DBAsset, DBExecuteRequest, DBManager, ObjectData, parseXML, PrimitiveData } from "@cyklang/core"
|
|
11
11
|
import FormData from 'form-data'
|
|
12
12
|
|
|
13
13
|
const logger = getLogger('AssetCommand.ts')
|
|
14
14
|
logger.setLevel('debug')
|
|
15
15
|
|
|
16
|
+
|
|
17
|
+
//----------------------------------------------------------------------------------------------
|
|
18
|
+
// scanAssets
|
|
19
|
+
//----------------------------------------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
const scanAssets = async (dbManager: DBManager | undefined, dest?: string): Promise<FileDescriptor[]> => {
|
|
22
|
+
|
|
23
|
+
const result: FileDescriptor[] = []
|
|
24
|
+
if (dbManager === undefined) throw 'dbManager undefined'
|
|
25
|
+
const dbReq = new DBExecuteRequest()
|
|
26
|
+
dbReq.selectFromTable = 'cyk_asset'
|
|
27
|
+
const pFields = dbReq.parameters.addVariable('fields', dbManager.scope.structure.stringDataType)
|
|
28
|
+
pFields.data = new PrimitiveData(dbManager.scope.structure.stringDataType, "asset_id,asset_route,asset_last_update,asset_mimetype")
|
|
29
|
+
const xmlResult = await dbManager.dbExecute(dbReq)
|
|
30
|
+
if (xmlResult === undefined || xmlResult === null) throw 'xmlResult null or undefined'
|
|
31
|
+
const tag = parseXML('scanAssets', xmlResult)
|
|
32
|
+
const objResult = await dbManager.scope.structure.objectDataType.parseData(tag, dbManager.scope) as ObjectData
|
|
33
|
+
const rows = (objResult.variables.getData('cyk_asset') as ObjectData).variables
|
|
34
|
+
for (let ind = 0; ind < rows.list.length; ind++) {
|
|
35
|
+
const { variable: row } = rows.list[ind]
|
|
36
|
+
const record = row.data as ObjectData
|
|
37
|
+
const asset_id = (record.variables.getData('asset_id') as PrimitiveData).value as number
|
|
38
|
+
const asset_route = (record.variables.getData('asset_route') as PrimitiveData).value as string
|
|
39
|
+
const asset_last_update = (record.variables.getData('asset_last_update') as PrimitiveData)?.value as Date
|
|
40
|
+
// logger.debug('asset_route ' + asset_route,'asset_last_update ' + asset_last_update)
|
|
41
|
+
|
|
42
|
+
if (!dest || asset_route.startsWith(dest))
|
|
43
|
+
result.push({ path: asset_route, mtime: asset_last_update, id: asset_id })
|
|
44
|
+
}
|
|
45
|
+
return result
|
|
46
|
+
}
|
|
47
|
+
|
|
16
48
|
export class AssetCommand extends Command {
|
|
17
49
|
constructor(name: string, description: string) {
|
|
18
50
|
super(name)
|
|
@@ -22,9 +54,92 @@ export class AssetCommand extends Command {
|
|
|
22
54
|
this.addCommand(new AssetU('upload', 'upload asset content from source files to a <destination> path'))
|
|
23
55
|
this.addCommand(new AssetU('update', 'update properties of asset identified by its <id>'))
|
|
24
56
|
this.addCommand(new AssetU('u', '(u)pload assets content from sources or (u)pdate asset properties'))
|
|
57
|
+
this.addCommand(new AssetDelete('delete', 'delete an asset'))
|
|
25
58
|
}
|
|
26
59
|
}
|
|
27
60
|
|
|
61
|
+
/**
|
|
62
|
+
* class AssetDelete
|
|
63
|
+
*/
|
|
64
|
+
class AssetDelete extends Cmd {
|
|
65
|
+
constructor(name: string, description: string) {
|
|
66
|
+
super(name)
|
|
67
|
+
this.description(description)
|
|
68
|
+
.option('-i --id <id_pathname>', 'asset id or pathname to delete')
|
|
69
|
+
.option('-d --dest <destination>', 'delete all assets whose pathname begins with dest')
|
|
70
|
+
.action(async (options: any) => {
|
|
71
|
+
if (options.id)
|
|
72
|
+
await this.commandDeleteOne(options)
|
|
73
|
+
else if (options.dest) {
|
|
74
|
+
await this.commandDeletePathname(options)
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
logger.error('one of --id or --dest options is required')
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
*
|
|
84
|
+
* @param options
|
|
85
|
+
*/
|
|
86
|
+
async commandDeleteOne(options: any) {
|
|
87
|
+
try {
|
|
88
|
+
await this.prologue(options)
|
|
89
|
+
if (this.dbManager === undefined) throw 'dbManager undefined'
|
|
90
|
+
|
|
91
|
+
if (options.id === undefined) throw '<id_or_pathname> of asset to delete is missing'
|
|
92
|
+
|
|
93
|
+
if (!options.id.startsWith('/')) throw '-i --id only pathname is supported at the moment'
|
|
94
|
+
|
|
95
|
+
const dbAsset = await this.dbManager.dbAssetExist(options.id)
|
|
96
|
+
if (dbAsset === undefined) throw 'Asset ' + options.id + ' not found'
|
|
97
|
+
|
|
98
|
+
await this.dbManager.dbAssetDelete(dbAsset)
|
|
99
|
+
|
|
100
|
+
logger.info('asset ' + dbAsset.id + ' ' + dbAsset.route + ' deleted')
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
logger.error(err)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
*
|
|
109
|
+
* @param options
|
|
110
|
+
*/
|
|
111
|
+
async commandDeletePathname(options: any) {
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
await this.prologue(options)
|
|
115
|
+
if (! this.dbManager) throw 'dbManager undefined'
|
|
116
|
+
const dbClient = new DBClient(this.dbManager)
|
|
117
|
+
const list = await dbClient.selectFromTable('Assets to delete', 'cyk_asset',
|
|
118
|
+
{
|
|
119
|
+
fields: 'asset_id,asset_route,asset_auth,asset_access,asset_mimetype,asset_last_update', sort: options.sort || '1',
|
|
120
|
+
where: (options.dest ? "asset_route like '" + options.dest + "%'" : undefined)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
);
|
|
124
|
+
const reply = await inquirer.prompt({type: 'confirm', name: 'confirm', message: 'Do you want to delete these ' + list.length + ' file(s)'})
|
|
125
|
+
if (reply.confirm) {
|
|
126
|
+
for(let ind = 0; ind < list.length; ind++) {
|
|
127
|
+
const asset = list[ind]
|
|
128
|
+
logger.info('delete ' + asset.asset_route)
|
|
129
|
+
const url = '/api/admin/assets/' + asset.asset_id
|
|
130
|
+
await this.dbRemote?.apiServer.delete(url)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
logger.error(err)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
}
|
|
142
|
+
|
|
28
143
|
class AssetList extends Cmd {
|
|
29
144
|
constructor(name: string, description: string) {
|
|
30
145
|
super(name)
|
|
@@ -66,7 +181,7 @@ class AssetU extends Cmd {
|
|
|
66
181
|
constructor(name: string, description: string) {
|
|
67
182
|
super(name)
|
|
68
183
|
this.description(description)
|
|
69
|
-
.option('-i --id <id>', 'asset id
|
|
184
|
+
.option('-i --id <id>', 'asset id or pathname whose properties are updated')
|
|
70
185
|
.option('--auth <auth_schema>', 'authentication schema : basic | token | cookie | any | none, default is none')
|
|
71
186
|
.option('--access <access>', 'access rights required')
|
|
72
187
|
.option('-d --dest <destination>', 'destination path, directory name')
|
|
@@ -97,12 +212,12 @@ class AssetU extends Cmd {
|
|
|
97
212
|
async commandU(sources: string[], options: any) {
|
|
98
213
|
if (sources.length > 0) {
|
|
99
214
|
// upload
|
|
100
|
-
logger.debug('upload sources :', sources)
|
|
215
|
+
// logger.debug('upload sources :', sources)
|
|
101
216
|
await this.commandUpload(sources, options)
|
|
102
217
|
}
|
|
103
218
|
else {
|
|
104
219
|
// update
|
|
105
|
-
logger.debug('update', options)
|
|
220
|
+
// logger.debug('update', options)
|
|
106
221
|
await this.commandUpdate(options)
|
|
107
222
|
}
|
|
108
223
|
}
|
|
@@ -116,12 +231,14 @@ class AssetU extends Cmd {
|
|
|
116
231
|
await this.prologue(options)
|
|
117
232
|
if (this.dbManager === undefined) throw 'dbManager undefined'
|
|
118
233
|
|
|
119
|
-
if (options.id === undefined) throw '<
|
|
234
|
+
if (options.id === undefined) throw '<id_or_pathname> of asset to update is missing'
|
|
235
|
+
|
|
236
|
+
if (!options.id.startsWith('/')) throw '-i --id only pathname is supported at the moment'
|
|
120
237
|
|
|
121
238
|
const dbAsset = await this.dbManager.dbAssetExist(options.id)
|
|
122
239
|
if (dbAsset === undefined) throw 'Asset ' + options.id + ' not found'
|
|
123
240
|
|
|
124
|
-
await this.updateAuthAccess('cyk_asset', '
|
|
241
|
+
await this.updateAuthAccess('cyk_asset', 'asset', dbAsset.id || '', options)
|
|
125
242
|
|
|
126
243
|
}
|
|
127
244
|
catch (err) {
|
|
@@ -145,8 +262,8 @@ class AssetU extends Cmd {
|
|
|
145
262
|
if (options.auth && ' basic | token | cookie | any | none'.indexOf(options.auth) === -1) {
|
|
146
263
|
throw 'valid authentication schemas are : basic | token | cookie | any | none'
|
|
147
264
|
}
|
|
148
|
-
logger.debug('options : ', options)
|
|
149
|
-
logger.debug('auth : ' + options.auth)
|
|
265
|
+
// logger.debug('options : ', options)
|
|
266
|
+
// logger.debug('auth : ' + options.auth)
|
|
150
267
|
|
|
151
268
|
let dest = "/"
|
|
152
269
|
if (options.dest !== undefined) dest = options.dest
|
|
@@ -182,7 +299,7 @@ class AssetU extends Cmd {
|
|
|
182
299
|
|
|
183
300
|
async cleanDestination(dest: string) {
|
|
184
301
|
|
|
185
|
-
const remoteList = await this.
|
|
302
|
+
const remoteList = await scanAssets(this.dbManager)
|
|
186
303
|
for (let ind = 0; ind < remoteList.length; ind++) {
|
|
187
304
|
const fd = remoteList[ind]
|
|
188
305
|
if (fd.path.startsWith(dest)) {
|
|
@@ -208,11 +325,11 @@ class AssetU extends Cmd {
|
|
|
208
325
|
dirName = source + '/'
|
|
209
326
|
}
|
|
210
327
|
|
|
211
|
-
logger.debug('options', options)
|
|
328
|
+
// logger.debug('options', options)
|
|
212
329
|
|
|
213
330
|
this.scanDir(dirName, localList)
|
|
214
331
|
|
|
215
|
-
const remoteList = await this.
|
|
332
|
+
const remoteList = await scanAssets(this.dbManager)
|
|
216
333
|
|
|
217
334
|
const uploadList = this.buildUploadList(dirName, dest, localList, remoteList)
|
|
218
335
|
|
|
@@ -268,35 +385,6 @@ class AssetU extends Cmd {
|
|
|
268
385
|
return result
|
|
269
386
|
}
|
|
270
387
|
|
|
271
|
-
|
|
272
|
-
//----------------------------------------------------------------------------------------------
|
|
273
|
-
// scanAssets
|
|
274
|
-
//----------------------------------------------------------------------------------------------
|
|
275
|
-
|
|
276
|
-
async scanAssets() {
|
|
277
|
-
const result: FileDescriptor[] = []
|
|
278
|
-
if (this.dbManager === undefined) throw 'dbManager undefined'
|
|
279
|
-
const dbReq = new DBExecuteRequest()
|
|
280
|
-
dbReq.selectFromTable = 'cyk_asset'
|
|
281
|
-
const pFields = dbReq.parameters.addVariable('fields', this.dbManager.scope.structure.stringDataType)
|
|
282
|
-
pFields.data = new PrimitiveData(this.dbManager.scope.structure.stringDataType, "asset_id,asset_route,asset_last_update,asset_mimetype")
|
|
283
|
-
const xmlResult = await this.dbManager.dbExecute(dbReq)
|
|
284
|
-
if (xmlResult === undefined || xmlResult === null) throw 'xmlResult null or undefined'
|
|
285
|
-
const tag = parseXML('scanAssets', xmlResult)
|
|
286
|
-
const objResult = await this.dbManager.scope.structure.objectDataType.parseData(tag, this.dbManager.scope) as ObjectData
|
|
287
|
-
const rows = (objResult.variables.getData('cyk_asset') as ObjectData).variables
|
|
288
|
-
for (let ind = 0; ind < rows.list.length; ind++) {
|
|
289
|
-
const { variable: row } = rows.list[ind]
|
|
290
|
-
const record = row.data as ObjectData
|
|
291
|
-
const asset_id = (record.variables.getData('asset_id') as PrimitiveData).value as number
|
|
292
|
-
const asset_route = (record.variables.getData('asset_route') as PrimitiveData).value as string
|
|
293
|
-
const asset_last_update = (record.variables.getData('asset_last_update') as PrimitiveData)?.value as Date
|
|
294
|
-
// logger.debug('asset_route ' + asset_route,'asset_last_update ' + asset_last_update)
|
|
295
|
-
result.push({ path: asset_route, mtime: asset_last_update, id: asset_id })
|
|
296
|
-
}
|
|
297
|
-
return result
|
|
298
|
-
}
|
|
299
|
-
|
|
300
388
|
//----------------------------------------------------------------------------------------------
|
|
301
389
|
// scanDir
|
|
302
390
|
//----------------------------------------------------------------------------------------------
|
|
@@ -354,7 +442,7 @@ class AssetU extends Cmd {
|
|
|
354
442
|
//----------------------------------------------------------------------------------------------
|
|
355
443
|
|
|
356
444
|
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)
|
|
445
|
+
// logger.debug('uploadAsset ' + upload.path + ' to route ' + route + ' with mimetype ' + this.mimetypeLookup(upload.path) + ', auth : ' + auth)
|
|
358
446
|
|
|
359
447
|
try {
|
|
360
448
|
let dbAsset: DBAsset | undefined = await this.dbManager?.dbAssetExist(route)
|
package/src/Cmd.ts
CHANGED
|
@@ -23,7 +23,7 @@ export class Cmd extends Command {
|
|
|
23
23
|
|
|
24
24
|
const structure = new Structure()
|
|
25
25
|
if (process.env.DBREMOTE_URL === undefined) throw 'DBREMOTE_URL undefined'
|
|
26
|
-
logger.
|
|
26
|
+
logger.info('Cyk server: ' + process.env.DBREMOTE_URL)
|
|
27
27
|
const nodeCrypto = new NodeCrypto()
|
|
28
28
|
this.dbRemote = new DBRemote(structure.scope, process.env.DBREMOTE_URL, nodeCrypto)
|
|
29
29
|
const login = await this.dbRemote.signin(process.env.USER_NAME, undefined, process.env.USER_PASSWORD)
|
package/src/DBClient.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BasicType, DBColumn, DBExecuteRequest, DBManager, DBTable, ObjectData, parseXML, PrimitiveData, Script, XmlError } from "@cyklang/core";
|
|
1
|
+
import { BasicType, DBColumn, DBExecuteRequest, DBManager, DBTable, ObjectData, parseXML, PrimitiveData, Script, variable2json, XmlError } from "@cyklang/core";
|
|
2
2
|
import loglevel from "loglevel";
|
|
3
3
|
import { errorconsole } from "./console";
|
|
4
4
|
const logger = loglevel.getLogger('DBClient.ts')
|
|
@@ -47,9 +47,11 @@ export class DBClient {
|
|
|
47
47
|
async runQuery() {
|
|
48
48
|
|
|
49
49
|
}
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
async selectFromTable(title: string, tableName: string, options:
|
|
52
|
-
{ fields: string, sort?: string | undefined, where?: string | undefined, width?: string | undefined }) {
|
|
52
|
+
{ fields: string, sort?: string | undefined, where?: string | undefined, width?: string | undefined }): Promise<any[]> {
|
|
53
|
+
|
|
54
|
+
let result: any[] = []
|
|
53
55
|
|
|
54
56
|
try {
|
|
55
57
|
|
|
@@ -107,8 +109,13 @@ export class DBClient {
|
|
|
107
109
|
|
|
108
110
|
const objDataset = objXmlResult.variables.getData(tableName) as ObjectData
|
|
109
111
|
for (let ind = 0; ind < objDataset.variables.length(); ind++) {
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
+
const variable = objDataset.variables.at(ind)
|
|
113
|
+
if (variable) {
|
|
114
|
+
const record = (variable?.data as ObjectData)
|
|
115
|
+
list.addObjectData(record)
|
|
116
|
+
result.push(variable2json(variable))
|
|
117
|
+
}
|
|
118
|
+
|
|
112
119
|
}
|
|
113
120
|
logger.info(list.renderList(title))
|
|
114
121
|
|
|
@@ -116,6 +123,7 @@ export class DBClient {
|
|
|
116
123
|
catch (err) {
|
|
117
124
|
logger.error(err)
|
|
118
125
|
}
|
|
126
|
+
return result
|
|
119
127
|
}
|
|
120
128
|
|
|
121
129
|
async deleteModule(dbname: string) {
|
|
@@ -124,7 +132,7 @@ export class DBClient {
|
|
|
124
132
|
const dbModule = await this.dbManager.dbModuleExist(dbname)
|
|
125
133
|
|
|
126
134
|
if (dbModule === undefined) {
|
|
127
|
-
|
|
135
|
+
throw ('Module ' + dbname + ' not found')
|
|
128
136
|
}
|
|
129
137
|
await this.dbManager.dbModuleDelete(dbModule)
|
|
130
138
|
}
|
|
@@ -217,7 +225,7 @@ class List {
|
|
|
217
225
|
}
|
|
218
226
|
this.lines.push(this.renderSeparator())
|
|
219
227
|
this.lines.push('Number of lines : ' + this.rows.length)
|
|
220
|
-
|
|
228
|
+
|
|
221
229
|
return this.lines.join('\n')
|
|
222
230
|
}
|
|
223
231
|
|
|
@@ -272,7 +280,7 @@ class List {
|
|
|
272
280
|
}
|
|
273
281
|
|
|
274
282
|
// replace \n with a space
|
|
275
|
-
result = result.replace(/\n/, ' ')
|
|
283
|
+
result = result.replace(/\n/, ' ')
|
|
276
284
|
|
|
277
285
|
if (width !== undefined && width !== 0) {
|
|
278
286
|
if (result.length >= width) {
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Cmd } from "./Cmd";
|
|
2
|
+
import * as fs from "fs"
|
|
3
|
+
import * as path from "path"
|
|
4
|
+
|
|
5
|
+
import loglevel from 'loglevel'
|
|
6
|
+
import { uploadModule } from "./ModuleCommand";
|
|
7
|
+
const logger = loglevel.getLogger('InstallCommand.ts')
|
|
8
|
+
logger.setLevel('debug')
|
|
9
|
+
|
|
10
|
+
export class InstallCommand extends Cmd {
|
|
11
|
+
constructor(name: string) {
|
|
12
|
+
super(name)
|
|
13
|
+
this.description('upload Cyk modules to a Cyk server from a Node package downloaded by "npm install" ')
|
|
14
|
+
.argument('<node_package>', 'Node Package installed as dependency')
|
|
15
|
+
.action(async (node_package: any, options: any) => {
|
|
16
|
+
await this.install(node_package, options)
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async install(node_package: string, options: any) {
|
|
21
|
+
try {
|
|
22
|
+
await this.prologue(options)
|
|
23
|
+
if (this.dbManager === undefined) throw 'dbManager undefined'
|
|
24
|
+
await this.verifyPackageJson(node_package)
|
|
25
|
+
|
|
26
|
+
const xmlFolder = path.join('node_modules', node_package, 'xml')
|
|
27
|
+
if (!fs.existsSync(xmlFolder) || !fs.statSync(xmlFolder).isDirectory()) {
|
|
28
|
+
throw 'xml folder not found ( ' + xmlFolder + ' )'
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const files = fs.readdirSync(xmlFolder)
|
|
32
|
+
for (let ind = 0; ind < files.length; ind++) {
|
|
33
|
+
const file = files[ind]
|
|
34
|
+
await uploadModule(path.join(xmlFolder, file), this.dbManager)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
logger.error(err)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* method verifyPackageJson
|
|
44
|
+
* @param node_package
|
|
45
|
+
*/
|
|
46
|
+
async verifyPackageJson(node_package: string) {
|
|
47
|
+
|
|
48
|
+
let packageJson: any
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
// Lecture du contenu du fichier package.json en tant que chaîne de caractères
|
|
52
|
+
const packageJsonContent = fs.readFileSync('package.json', 'utf8');
|
|
53
|
+
|
|
54
|
+
// Analyse du contenu en tant qu'objet JSON
|
|
55
|
+
packageJson = JSON.parse(packageJsonContent);
|
|
56
|
+
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.error('Error loading package.json file :', error);
|
|
59
|
+
throw error
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!packageJson.dependencies || !packageJson.dependencies[node_package]) {
|
|
63
|
+
throw node_package + ' not installed in the current project. Install it first with "npm install"'
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
}
|
package/src/ModuleCommand.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ts-node
|
|
2
|
-
import { DBModule, parseXML } from "@cyklang/core"
|
|
2
|
+
import { DBManager, DBModule, parseXML } from "@cyklang/core"
|
|
3
3
|
import * as fs from "fs"
|
|
4
4
|
import loglevel from 'loglevel'
|
|
5
5
|
import path from "path"
|
|
@@ -115,30 +115,7 @@ class ModuleU extends Cmd {
|
|
|
115
115
|
else {
|
|
116
116
|
for (let ind = 0; ind < files.length; ind++) {
|
|
117
117
|
const file = files[ind]
|
|
118
|
-
|
|
119
|
-
const source = fs.readFileSync(file).toString()
|
|
120
|
-
const tag = parseXML(dbname, source)
|
|
121
|
-
const dbModuleExist = await this.dbManager.dbModuleExist(dbname)
|
|
122
|
-
if (dbModuleExist === undefined) {
|
|
123
|
-
// insert
|
|
124
|
-
const dbModule = new DBModule()
|
|
125
|
-
dbModule.source = source
|
|
126
|
-
dbModule.dbname = dbname
|
|
127
|
-
dbModule.access = tag.attributes.ACCESS
|
|
128
|
-
dbModule.description = tag.attributes.DESCRIPTION
|
|
129
|
-
logger.debug('module insert ' + dbname + ' access ' + dbModule.access + ' description ' + dbModule.description)
|
|
130
|
-
const id = await this.dbManager.dbModuleInsert(dbModule)
|
|
131
|
-
logger.info('module ' + dbname + ' added with ID ' + id)
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
// update
|
|
135
|
-
dbModuleExist.source = source
|
|
136
|
-
dbModuleExist.access = tag.attributes.ACCESS
|
|
137
|
-
dbModuleExist.description = tag.attributes.DESCRIPTION
|
|
138
|
-
logger.debug('module update ' + dbname + ' access ' + dbModuleExist.access + ' description ' + dbModuleExist.description)
|
|
139
|
-
await this.dbManager.dbModuleUpdate(dbModuleExist)
|
|
140
|
-
logger.info('module ' + dbname + ' updated')
|
|
141
|
-
}
|
|
118
|
+
await uploadModule(file, this.dbManager)
|
|
142
119
|
}
|
|
143
120
|
}
|
|
144
121
|
}
|
|
@@ -148,6 +125,38 @@ class ModuleU extends Cmd {
|
|
|
148
125
|
}
|
|
149
126
|
}
|
|
150
127
|
|
|
128
|
+
/**
|
|
129
|
+
*
|
|
130
|
+
* @param file
|
|
131
|
+
* @param dbManager
|
|
132
|
+
*/
|
|
133
|
+
export async function uploadModule(file: string, dbManager: DBManager) {
|
|
134
|
+
const dbname = getModuleDBName(file)
|
|
135
|
+
const source = fs.readFileSync(file).toString()
|
|
136
|
+
const tag = parseXML(dbname, source)
|
|
137
|
+
const dbModuleExist = await dbManager.dbModuleExist(dbname)
|
|
138
|
+
if (dbModuleExist === undefined) {
|
|
139
|
+
// insert
|
|
140
|
+
const dbModule = new DBModule()
|
|
141
|
+
dbModule.source = source
|
|
142
|
+
dbModule.dbname = dbname
|
|
143
|
+
dbModule.access = tag.attributes.ACCESS
|
|
144
|
+
dbModule.description = tag.attributes.DESCRIPTION
|
|
145
|
+
// logger.debug('module insert ' + dbname + ' access ' + dbModule.access + ' description ' + dbModule.description)
|
|
146
|
+
const id = await dbManager.dbModuleInsert(dbModule)
|
|
147
|
+
logger.info('module ' + dbname + ' added with ID ' + id)
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
// update
|
|
151
|
+
dbModuleExist.source = source
|
|
152
|
+
dbModuleExist.access = tag.attributes.ACCESS
|
|
153
|
+
dbModuleExist.description = tag.attributes.DESCRIPTION
|
|
154
|
+
// logger.debug('module update ' + dbname + ' access ' + dbModuleExist.access + ' description ' + dbModuleExist.description)
|
|
155
|
+
await dbManager.dbModuleUpdate(dbModuleExist)
|
|
156
|
+
logger.info('module ' + dbname + ' updated')
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
151
160
|
interface DownloadOptions {
|
|
152
161
|
id: string | undefined
|
|
153
162
|
env: string | undefined
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Cmd } from "./Cmd";
|
|
2
|
+
|
|
3
|
+
import loglevel from 'loglevel'
|
|
4
|
+
const logger = loglevel.getLogger('OpenCommand.ts')
|
|
5
|
+
logger.setLevel('debug')
|
|
6
|
+
|
|
7
|
+
export class OpenCommand extends Cmd {
|
|
8
|
+
constructor(name: string) {
|
|
9
|
+
super(name)
|
|
10
|
+
this.description('open browser').version('0.1')
|
|
11
|
+
.argument('<module>', 'module to execute')
|
|
12
|
+
.action(async (module: any, options: any) => {
|
|
13
|
+
await this.openBrowser(module, options)
|
|
14
|
+
})
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async openBrowser(module: string, options: any) {
|
|
18
|
+
try {
|
|
19
|
+
await this.prologue(options)
|
|
20
|
+
|
|
21
|
+
if (process.env.DBREMOTE_URL === undefined) throw 'DBREMOTE_URL undefined'
|
|
22
|
+
const url = process.env.DBREMOTE_URL + '/cyk/#/run/' + module;
|
|
23
|
+
const open = await import('open');
|
|
24
|
+
open.default(url)
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
logger.error(err)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
}
|
package/src/RunCommand.ts
CHANGED
|
@@ -8,8 +8,8 @@ loglevel.setLevel('debug')
|
|
|
8
8
|
const logger = loglevel.getLogger('RunCommand.ts');
|
|
9
9
|
|
|
10
10
|
export class RunCommand extends Cmd {
|
|
11
|
-
constructor() {
|
|
12
|
-
super(
|
|
11
|
+
constructor(name: string) {
|
|
12
|
+
super(name)
|
|
13
13
|
this.description('run module').version('0.2')
|
|
14
14
|
.argument('<files...>', 'local module file(s) to run')
|
|
15
15
|
.action(async (files: any, options: any) => {
|
package/src/index.ts
CHANGED
|
@@ -7,8 +7,9 @@ import { QueryCommand } from './QueryCommand'
|
|
|
7
7
|
import { TableCommand } from './TableCommand'
|
|
8
8
|
import { TestCommand } from './TestCommand'
|
|
9
9
|
import { RunCommand } from './RunCommand'
|
|
10
|
-
import {
|
|
10
|
+
import { InstallCommand } from './InstallCommand'
|
|
11
11
|
import { AssetCommand } from './AssetCommand'
|
|
12
|
+
import { OpenCommand } from './OpenCommand'
|
|
12
13
|
const logger = loglevel.getLogger("index.ts")
|
|
13
14
|
logger.setLevel("debug")
|
|
14
15
|
|
|
@@ -16,7 +17,8 @@ const program = new Command()
|
|
|
16
17
|
program.name('cyk').description('cyklang CLI')
|
|
17
18
|
.version('0.2')
|
|
18
19
|
|
|
19
|
-
program.addCommand(new
|
|
20
|
+
program.addCommand(new InstallCommand('install'))
|
|
21
|
+
program.addCommand(new InstallCommand('i'))
|
|
20
22
|
program.addCommand(new AssetCommand('asset', 'manage assets'))
|
|
21
23
|
program.addCommand(new AssetCommand('a', 'manage assets'))
|
|
22
24
|
program.addCommand(new ModuleCommand('module'))
|
|
@@ -28,6 +30,9 @@ program.addCommand(new QueryCommand('q'))
|
|
|
28
30
|
program.addCommand(new TableCommand('table'))
|
|
29
31
|
program.addCommand(new TableCommand('t'))
|
|
30
32
|
program.addCommand(new TestCommand())
|
|
31
|
-
program.addCommand(new RunCommand())
|
|
33
|
+
program.addCommand(new RunCommand('run'))
|
|
34
|
+
program.addCommand(new RunCommand('r'))
|
|
35
|
+
program.addCommand(new OpenCommand('open'))
|
|
36
|
+
program.addCommand(new OpenCommand('o'))
|
|
32
37
|
|
|
33
38
|
program.parse()
|
package/test/t27.output
ADDED
package/test/t27.xml
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<?xml-model href="https://www.cyklang.net/schema/cyklang.xsd" type="application/xml" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
|
2
|
+
<module>
|
|
3
|
+
<print>objson('150')</print>
|
|
4
|
+
<string name="chaine" literal=""><![CDATA[
|
|
5
|
+
{
|
|
6
|
+
"user_id": 1,
|
|
7
|
+
"user_name": "cyk",
|
|
8
|
+
"user_email": "cyk@gmail.com",
|
|
9
|
+
"user_password": "$2b$10$Et1b0DodTNKxW/jvUFC8be8JrRXULHWC5RnwOjVhUXmVKv.CyfFW.",
|
|
10
|
+
"user_access": "admin",
|
|
11
|
+
"user_appli": null,
|
|
12
|
+
"user_disable": false,
|
|
13
|
+
"user_lang": null
|
|
14
|
+
}
|
|
15
|
+
]]>
|
|
16
|
+
</string>
|
|
17
|
+
<print>json(objson(chaine))</print>
|
|
18
|
+
</module>
|