@cyklang/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/aws-ecs.env +38 -0
- package/build/Cmd.d.ts +7 -0
- package/build/Cmd.js +35 -0
- package/build/DBClient.d.ts +10 -0
- package/build/DBClient.js +205 -0
- package/build/InitCommand.d.ts +9 -0
- package/build/InitCommand.js +122 -0
- package/build/ModuleCommand.d.ts +5 -0
- package/build/ModuleCommand.js +202 -0
- package/build/NodeCrypto.d.ts +5 -0
- package/build/NodeCrypto.js +49 -0
- package/build/QueryCommand.d.ts +5 -0
- package/build/QueryCommand.js +62 -0
- package/build/RunCommand.d.ts +5 -0
- package/build/RunCommand.js +112 -0
- package/build/TableCommand.d.ts +5 -0
- package/build/TableCommand.js +140 -0
- package/build/TestCommand copy.d.ts +5 -0
- package/build/TestCommand copy.js +111 -0
- package/build/TestCommand.d.ts +5 -0
- package/build/TestCommand.js +111 -0
- package/build/UserCommand.d.ts +5 -0
- package/build/UserCommand.js +202 -0
- package/build/console.d.ts +13 -0
- package/build/console.js +109 -0
- package/build/cykquery.d.ts +2 -0
- package/build/cykquery.js +145 -0
- package/build/cyktable.d.ts +2 -0
- package/build/cyktable.js +133 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +32 -0
- package/build/module.d.ts +2 -0
- package/build/module.js +290 -0
- package/docker-compose.ecs.yml +44 -0
- package/docker-compose.yml +43 -0
- package/docker.env +38 -0
- package/package.json +38 -0
- package/src/Cmd.ts +33 -0
- package/src/DBClient.ts +220 -0
- package/src/InitCommand.ts +107 -0
- package/src/ModuleCommand.ts +192 -0
- package/src/NodeCrypto.ts +60 -0
- package/src/QueryCommand.ts +62 -0
- package/src/RunCommand.ts +98 -0
- package/src/TableCommand.ts +127 -0
- package/src/TestCommand.ts +98 -0
- package/src/UserCommand.ts +203 -0
- package/src/console.ts +97 -0
- package/src/index.ts +30 -0
- package/tsconfig.json +12 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
#!/usr/bin/env ts-node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.UserCommand = void 0;
|
|
8
|
+
const loglevel_1 = __importDefault(require("loglevel"));
|
|
9
|
+
const commander_1 = require("commander");
|
|
10
|
+
const core_1 = require("@cyklang/core");
|
|
11
|
+
const Cmd_1 = require("./Cmd");
|
|
12
|
+
const DBClient_1 = require("./DBClient");
|
|
13
|
+
const logger = loglevel_1.default.getLogger('UserCommand.ts');
|
|
14
|
+
logger.setLevel('debug');
|
|
15
|
+
class UserCommand extends commander_1.Command {
|
|
16
|
+
constructor(name) {
|
|
17
|
+
super(name);
|
|
18
|
+
this.description('manage users in cyk_user table').version('0.1');
|
|
19
|
+
this.addCommand(new UserAddCmd());
|
|
20
|
+
this.addCommand(new UserUpdateCmd('update', 'update user by id all fields except password'));
|
|
21
|
+
this.addCommand(new UserUpdateCmd('u', 'shortcut for (u)pdate'));
|
|
22
|
+
this.addCommand(new UserDeleteCmd('delete', 'delete user by id and name. Both options are mandatory to avoid typing error'));
|
|
23
|
+
this.addCommand(new UserPasswdCmd('passwd', 'change user password'));
|
|
24
|
+
this.addCommand(new UserListCmd('list', 'list users'));
|
|
25
|
+
this.addCommand(new UserListCmd('l', 'shortcut for (l)ist'));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.UserCommand = UserCommand;
|
|
29
|
+
class UserAddCmd extends Cmd_1.Cmd {
|
|
30
|
+
constructor() {
|
|
31
|
+
super('add');
|
|
32
|
+
this.description('add a new user')
|
|
33
|
+
.requiredOption('-n --name <name>', 'user name')
|
|
34
|
+
.option('-e --email <email>', 'user email address')
|
|
35
|
+
.option('-p --passwd <password>', 'initial password')
|
|
36
|
+
.option('-a --access <acl>', 'access control list')
|
|
37
|
+
.option('-m --module <module_name>', 'module to launch by default')
|
|
38
|
+
.option('-d --disable', 'user not abled to connect')
|
|
39
|
+
.action(async (options) => {
|
|
40
|
+
const dbUser = new core_1.DBUser();
|
|
41
|
+
dbUser.name = options.name;
|
|
42
|
+
dbUser.email = options.email;
|
|
43
|
+
dbUser.password = options.password;
|
|
44
|
+
dbUser.access = options.access;
|
|
45
|
+
dbUser.appli = options.module;
|
|
46
|
+
dbUser.disable = options.disable || false;
|
|
47
|
+
await this.commandAdd(dbUser, options);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async commandAdd(dbUser, options) {
|
|
51
|
+
try {
|
|
52
|
+
await this.prologue(options);
|
|
53
|
+
if (this.dbManager === undefined)
|
|
54
|
+
throw 'dbManager undefined';
|
|
55
|
+
const result = await this.dbManager.dbUserInsert(dbUser);
|
|
56
|
+
logger.debug(result);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
logger.error(err);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
class UserListCmd extends Cmd_1.Cmd {
|
|
64
|
+
constructor(name, description) {
|
|
65
|
+
super(name);
|
|
66
|
+
this.description(description)
|
|
67
|
+
.option('-s --sort <columns>', 'sort list by column numbers (begins by 0) separated by comma')
|
|
68
|
+
.action(async (options) => {
|
|
69
|
+
await this.commandList(options);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
async commandList(options) {
|
|
73
|
+
try {
|
|
74
|
+
await this.prologue(options);
|
|
75
|
+
if (this.dbManager === undefined)
|
|
76
|
+
throw 'dbManager undefined';
|
|
77
|
+
const dbClient = new DBClient_1.DBClient(this.dbManager);
|
|
78
|
+
dbClient.selectFromTable('List of users', 'cyk_user', { fields: 'user_id,user_name,user_email,user_access,user_appli,user_disable', sort: options.sort || '1' });
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
logger.error(err);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
class UserUpdateCmd extends Cmd_1.Cmd {
|
|
86
|
+
constructor(name, description) {
|
|
87
|
+
super(name);
|
|
88
|
+
this.description(description)
|
|
89
|
+
.requiredOption('-i --id <id>', 'user ID')
|
|
90
|
+
.option('-n --name <name>', 'user name')
|
|
91
|
+
.option('-e --email <email>', 'user email address')
|
|
92
|
+
.option('-a --access <acl>', 'access control list')
|
|
93
|
+
.option('-m --module <module_name>', 'module to launch by default')
|
|
94
|
+
.option('-d --disable', 'user not able to connect')
|
|
95
|
+
.action(async (options) => {
|
|
96
|
+
const dbUser = new core_1.DBUser();
|
|
97
|
+
dbUser.id = options.id;
|
|
98
|
+
dbUser.name = options.name;
|
|
99
|
+
dbUser.email = options.email;
|
|
100
|
+
dbUser.access = options.access;
|
|
101
|
+
dbUser.appli = options.module;
|
|
102
|
+
dbUser.disable = options.disable;
|
|
103
|
+
await this.commandUpdate(dbUser, options);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
async commandUpdate(dbUser2, options) {
|
|
107
|
+
try {
|
|
108
|
+
await this.prologue(options);
|
|
109
|
+
if (this.dbManager === undefined)
|
|
110
|
+
throw 'dbManager undefined';
|
|
111
|
+
if (dbUser2.id === undefined)
|
|
112
|
+
throw 'id is missing';
|
|
113
|
+
const dbUser1 = await this.dbManager.getUser(dbUser2.id);
|
|
114
|
+
if (dbUser1 === undefined)
|
|
115
|
+
throw 'user with id ' + dbUser2.id + ' not found';
|
|
116
|
+
// const dbUser1: DBUser = { id: user.user_id, name: user.user_name, email: user.user_email, password: user.user_password, access: user.user_access, appli: user.user_appli, disable: user.user_disable }
|
|
117
|
+
if (dbUser2.name !== undefined)
|
|
118
|
+
dbUser1.name = dbUser2.name;
|
|
119
|
+
if (dbUser2.email !== undefined)
|
|
120
|
+
dbUser1.email = dbUser2.email;
|
|
121
|
+
if (dbUser2.access !== undefined)
|
|
122
|
+
dbUser1.access = dbUser2.access;
|
|
123
|
+
if (dbUser2.appli !== undefined)
|
|
124
|
+
dbUser1.appli = dbUser2.appli;
|
|
125
|
+
if (dbUser2.disable !== undefined)
|
|
126
|
+
dbUser1.disable = dbUser2.disable;
|
|
127
|
+
// logger.debug('dbUser1 before dbUserUpdate : ', dbUser1)
|
|
128
|
+
await this.dbManager.dbUserUpdate(dbUser1);
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
logger.error(err);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
class UserDeleteCmd extends Cmd_1.Cmd {
|
|
136
|
+
constructor(name, description) {
|
|
137
|
+
super(name);
|
|
138
|
+
this.description(description)
|
|
139
|
+
.requiredOption('-i --id <id>', 'user ID')
|
|
140
|
+
.requiredOption('-n --name <name>', 'user name')
|
|
141
|
+
.action(async (options) => {
|
|
142
|
+
const dbUser = new core_1.DBUser();
|
|
143
|
+
dbUser.id = options.id;
|
|
144
|
+
dbUser.name = options.name;
|
|
145
|
+
await this.commandDelete(dbUser, options);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
async commandDelete(dbUser, options) {
|
|
149
|
+
try {
|
|
150
|
+
await this.prologue(options);
|
|
151
|
+
if (this.dbManager === undefined)
|
|
152
|
+
throw 'dbManager undefined';
|
|
153
|
+
if (dbUser.id === undefined || dbUser.name === undefined)
|
|
154
|
+
throw 'id or name missing';
|
|
155
|
+
const userExist = await this.dbManager.getUser(dbUser.id);
|
|
156
|
+
if (userExist === undefined)
|
|
157
|
+
throw 'user with id ' + dbUser.id + ' not found';
|
|
158
|
+
if (dbUser.name !== userExist.name)
|
|
159
|
+
throw 'name ' + dbUser.name + ' different from ' + userExist.name;
|
|
160
|
+
await this.dbManager.dbUserDelete(dbUser);
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
logger.error(err);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
class UserPasswdCmd extends Cmd_1.Cmd {
|
|
168
|
+
constructor(name, description) {
|
|
169
|
+
super('passwd');
|
|
170
|
+
this.description(description)
|
|
171
|
+
.requiredOption('-i --id <id>', 'user ID')
|
|
172
|
+
.requiredOption('-n --name <name>', 'user name')
|
|
173
|
+
.requiredOption('-p --password <password>', 'new password')
|
|
174
|
+
.action(async (options) => {
|
|
175
|
+
const dbUser = new core_1.DBUser();
|
|
176
|
+
dbUser.id = options.id;
|
|
177
|
+
dbUser.name = options.name;
|
|
178
|
+
dbUser.password = options.password;
|
|
179
|
+
await this.commandPasswd(dbUser, options);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
async commandPasswd(dbUser, options) {
|
|
183
|
+
try {
|
|
184
|
+
await this.prologue(options);
|
|
185
|
+
if (this.dbManager === undefined)
|
|
186
|
+
throw 'dbManager undefined';
|
|
187
|
+
// logger.debug(dbUser)
|
|
188
|
+
if (dbUser.id === undefined || dbUser.name === undefined || dbUser.password === undefined)
|
|
189
|
+
throw 'id or name or password missing';
|
|
190
|
+
const userExist = await this.dbManager.getUser(dbUser.id);
|
|
191
|
+
if (userExist === undefined)
|
|
192
|
+
throw 'user with id ' + dbUser.id + ' not found';
|
|
193
|
+
if (dbUser.name !== userExist.name)
|
|
194
|
+
throw 'name ' + dbUser.name + ' different from ' + userExist.name;
|
|
195
|
+
await this.dbManager.dbUserPasswd(dbUser.id, dbUser.password);
|
|
196
|
+
logger.info('password changed for user ' + dbUser.name);
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
logger.error(err);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { XmlError } from '@cyklang/core';
|
|
2
|
+
import { Instruction, InstructionType, Tag } from '@cyklang/core';
|
|
3
|
+
import { Scope } from '@cyklang/core';
|
|
4
|
+
export declare function errorconsole(xmlError: XmlError): void;
|
|
5
|
+
export declare class InputInstructionType extends InstructionType {
|
|
6
|
+
constructor();
|
|
7
|
+
parseInstruction(tag: Tag, scope: Scope): Promise<Instruction>;
|
|
8
|
+
}
|
|
9
|
+
export declare class PrintInstructionType extends InstructionType {
|
|
10
|
+
logfilename: string;
|
|
11
|
+
constructor(logfilename: string);
|
|
12
|
+
parseInstruction(tag: Tag, scope: Scope): Promise<Instruction>;
|
|
13
|
+
}
|
package/build/console.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.PrintInstructionType = exports.InputInstructionType = exports.errorconsole = void 0;
|
|
23
|
+
const core_1 = require("@cyklang/core");
|
|
24
|
+
const fs = __importStar(require("fs"));
|
|
25
|
+
const core_2 = require("@cyklang/core");
|
|
26
|
+
const core_3 = require("@cyklang/core");
|
|
27
|
+
const loglevel = __importStar(require("loglevel"));
|
|
28
|
+
const logger = loglevel.getLogger('console.ts');
|
|
29
|
+
logger.setLevel('info');
|
|
30
|
+
function errorconsole(xmlError) {
|
|
31
|
+
if (xmlError.tag !== undefined) {
|
|
32
|
+
let msg = "\n=============== XmlError at (" + xmlError.tag.filename;
|
|
33
|
+
if (xmlError.tag.line !== undefined) {
|
|
34
|
+
msg += ":" + (xmlError.tag.line + 1);
|
|
35
|
+
}
|
|
36
|
+
if (xmlError.tag.column !== undefined) {
|
|
37
|
+
msg += ":" + (xmlError.tag.column + 1);
|
|
38
|
+
}
|
|
39
|
+
msg += ") ===============\n";
|
|
40
|
+
console.log(msg);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.errorconsole = errorconsole;
|
|
44
|
+
class InputInstructionType extends core_2.InstructionType {
|
|
45
|
+
constructor() {
|
|
46
|
+
super("input");
|
|
47
|
+
}
|
|
48
|
+
async parseInstruction(tag, scope) {
|
|
49
|
+
let result = new InputInstruction(tag);
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.InputInstructionType = InputInstructionType;
|
|
54
|
+
class InputInstruction extends core_2.Instruction {
|
|
55
|
+
constructor(tag) {
|
|
56
|
+
super(tag);
|
|
57
|
+
}
|
|
58
|
+
async execute() {
|
|
59
|
+
throw new Error("Method not implemented.");
|
|
60
|
+
}
|
|
61
|
+
dump() {
|
|
62
|
+
throw new Error("Method not implemented.");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
class PrintInstructionType extends core_2.InstructionType {
|
|
66
|
+
constructor(logfilename) {
|
|
67
|
+
super("print");
|
|
68
|
+
this.logfilename = logfilename;
|
|
69
|
+
}
|
|
70
|
+
async parseInstruction(tag, scope) {
|
|
71
|
+
let result = new PrintInstruction(tag, this.logfilename);
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.PrintInstructionType = PrintInstructionType;
|
|
76
|
+
class PrintInstruction extends core_2.Instruction {
|
|
77
|
+
constructor(tag, logfilename) {
|
|
78
|
+
super(tag);
|
|
79
|
+
this.logfilename = logfilename;
|
|
80
|
+
this.parse(tag);
|
|
81
|
+
}
|
|
82
|
+
parse(tag) {
|
|
83
|
+
this.exprValue = tag.getText();
|
|
84
|
+
}
|
|
85
|
+
async execute(scope) {
|
|
86
|
+
if (this.exprValue !== undefined) {
|
|
87
|
+
let express = new core_3.Expression(scope);
|
|
88
|
+
let value;
|
|
89
|
+
try {
|
|
90
|
+
value = await express.evaluate(this.exprValue);
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
console.log(err);
|
|
94
|
+
throw (new core_1.XmlError("Expression : " + this.exprValue, this.tag));
|
|
95
|
+
}
|
|
96
|
+
// logger.debug("print expr " + this.exprValue + " -> " + value?.toString())
|
|
97
|
+
if (value !== undefined && value !== null) {
|
|
98
|
+
// console.log("testprint : " + value.toString())
|
|
99
|
+
fs.appendFileSync(this.logfilename, value.toString() + "\n");
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
console.log(value);
|
|
103
|
+
//throw (new XmlError("<print> undefined : " + this.exprValue, this.tag))
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
dump() {
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/usr/bin/env ts-node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
6
|
+
}) : (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
o[k2] = m[k];
|
|
9
|
+
}));
|
|
10
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
11
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
12
|
+
}) : function(o, v) {
|
|
13
|
+
o["default"] = v;
|
|
14
|
+
});
|
|
15
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
16
|
+
if (mod && mod.__esModule) return mod;
|
|
17
|
+
var result = {};
|
|
18
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
19
|
+
__setModuleDefault(result, mod);
|
|
20
|
+
return result;
|
|
21
|
+
};
|
|
22
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
const cyk_core_1 = require("@cyk-language/cyk-core");
|
|
27
|
+
const fs = __importStar(require("fs"));
|
|
28
|
+
const loglevel_1 = __importDefault(require("loglevel"));
|
|
29
|
+
const path_1 = __importDefault(require("path"));
|
|
30
|
+
const dotenv_1 = __importDefault(require("dotenv"));
|
|
31
|
+
const logger = loglevel_1.default.getLogger("model.ts");
|
|
32
|
+
logger.setLevel("debug");
|
|
33
|
+
dotenv_1.default.config();
|
|
34
|
+
const main = async () => {
|
|
35
|
+
const structure = new cyk_core_1.Structure();
|
|
36
|
+
if (process.env.DBREMOTE_URL === undefined)
|
|
37
|
+
throw 'DBREMOTE_URL undefined';
|
|
38
|
+
logger.debug('DBREMOTE_URL ' + process.env.DBREMOTE_URL);
|
|
39
|
+
const dbRemote = new cyk_core_1.DBRemote(structure.scope, process.env.DBREMOTE_URL);
|
|
40
|
+
const login = await dbRemote.signin(process.env.USER_NAME, undefined, process.env.USER_PASSWORD);
|
|
41
|
+
logger.debug(login);
|
|
42
|
+
const dbManager = new cyk_core_1.DBManager(structure.scope, dbRemote);
|
|
43
|
+
await dbManager.initialize();
|
|
44
|
+
const { command, filepath, basename } = parseCommandLine();
|
|
45
|
+
const xmlSource = fs.readFileSync(filepath).toString();
|
|
46
|
+
let tag = parseXmlFile(filepath, basename, xmlSource);
|
|
47
|
+
if (command === Command.Exec || command === Command.ExecTest) {
|
|
48
|
+
await executeXml(structure, tag, xmlSource);
|
|
49
|
+
}
|
|
50
|
+
if (command === Command.Test || command === Command.ExecTest) {
|
|
51
|
+
await testQuery(structure, tag.attributes.NAME);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
main().then(() => logger.debug('finished'));
|
|
55
|
+
var Command;
|
|
56
|
+
(function (Command) {
|
|
57
|
+
Command["Exec"] = "exec";
|
|
58
|
+
Command["ExecTest"] = "exectest";
|
|
59
|
+
Command["Test"] = "test";
|
|
60
|
+
})(Command || (Command = {}));
|
|
61
|
+
function syntax() {
|
|
62
|
+
console.log(`
|
|
63
|
+
----------------------------------------------------------------------------------
|
|
64
|
+
cykquery executes a <db.query> to the server (DBREMOTE_URL environment variable)
|
|
65
|
+
syntax :
|
|
66
|
+
cykquery [ exec | test | exectest ] filename
|
|
67
|
+
cykquery filename (option exectest by default)
|
|
68
|
+
----------------------------------------------------------------------------------
|
|
69
|
+
`);
|
|
70
|
+
}
|
|
71
|
+
function parseCommandLine() {
|
|
72
|
+
let command;
|
|
73
|
+
let filepath;
|
|
74
|
+
if (process.argv.length < 3 || process.argv.length > 4) {
|
|
75
|
+
syntax();
|
|
76
|
+
throw Error('nb of command line arguments : ' + process.argv.length);
|
|
77
|
+
}
|
|
78
|
+
if (process.argv.length === 3) {
|
|
79
|
+
filepath = process.argv[2];
|
|
80
|
+
command = Command.ExecTest;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const option = process.argv[2].toLowerCase();
|
|
84
|
+
if (option === 'test' || option === 'exec' || option === 'exectest') {
|
|
85
|
+
command = option;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
syntax();
|
|
89
|
+
throw Error('command unknown ' + process.argv[2]);
|
|
90
|
+
}
|
|
91
|
+
filepath = process.argv[3];
|
|
92
|
+
}
|
|
93
|
+
logger.trace('cykquery filepath : ' + filepath);
|
|
94
|
+
const basename = path_1.default.basename(filepath);
|
|
95
|
+
const extname = path_1.default.extname(filepath);
|
|
96
|
+
logger.trace('basename ' + basename + ', extname ' + extname);
|
|
97
|
+
if (extname.toLowerCase() !== '.xml') {
|
|
98
|
+
throw Error('filepath argument ' + filepath + ' should have xml extension');
|
|
99
|
+
}
|
|
100
|
+
return { command, filepath, basename };
|
|
101
|
+
}
|
|
102
|
+
function parseXmlFile(filepath, basename, xmlSource) {
|
|
103
|
+
const tag = (0, cyk_core_1.parseXML)(filepath, xmlSource);
|
|
104
|
+
if (tag.name !== 'DB.QUERY') {
|
|
105
|
+
throw Error('tag ' + tag.name + ', should be <db.query>');
|
|
106
|
+
}
|
|
107
|
+
const name = tag.attributes.NAME;
|
|
108
|
+
if (name === undefined) {
|
|
109
|
+
throw Error('name attribute is missing');
|
|
110
|
+
}
|
|
111
|
+
if (basename !== name + '.xml') {
|
|
112
|
+
throw Error('filename ' + filepath + ' and name ' + name + ' do not correspond');
|
|
113
|
+
}
|
|
114
|
+
return tag;
|
|
115
|
+
}
|
|
116
|
+
async function executeXml(structure, tag, xmlSource) {
|
|
117
|
+
try {
|
|
118
|
+
logger.debug('executeXml ' + tag.attributes.NAME);
|
|
119
|
+
// structure.setInstructionType("print", new PrintInstructionType(logfilename))
|
|
120
|
+
const dbQueryInstructionType = structure.scope.getInstructionType('db.query');
|
|
121
|
+
if (dbQueryInstructionType === undefined) {
|
|
122
|
+
throw Error('dbQueryInstructionType not found');
|
|
123
|
+
}
|
|
124
|
+
const scopeParse = new cyk_core_1.Scope(structure, structure.scope, undefined);
|
|
125
|
+
const dbQueryInst = await dbQueryInstructionType.parseInstruction(tag, scopeParse);
|
|
126
|
+
dbQueryInst.source = xmlSource;
|
|
127
|
+
const scopeExecute = new cyk_core_1.Scope(structure, structure.scope, undefined);
|
|
128
|
+
await dbQueryInst.execute(scopeExecute);
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
logger.error(err);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async function testQuery(structure, queryName) {
|
|
135
|
+
const xmlScript = `
|
|
136
|
+
<block>
|
|
137
|
+
<object name='result'/>
|
|
138
|
+
<db.execute query='${queryName}' result='result' />
|
|
139
|
+
<print>string(result)</print>
|
|
140
|
+
</block>
|
|
141
|
+
`;
|
|
142
|
+
const script = new cyk_core_1.Script(structure.scope, 'test', xmlScript);
|
|
143
|
+
await script.parseInstructions();
|
|
144
|
+
await script.execute();
|
|
145
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env ts-node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
6
|
+
}) : (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
o[k2] = m[k];
|
|
9
|
+
}));
|
|
10
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
11
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
12
|
+
}) : function(o, v) {
|
|
13
|
+
o["default"] = v;
|
|
14
|
+
});
|
|
15
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
16
|
+
if (mod && mod.__esModule) return mod;
|
|
17
|
+
var result = {};
|
|
18
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
19
|
+
__setModuleDefault(result, mod);
|
|
20
|
+
return result;
|
|
21
|
+
};
|
|
22
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
const cyk_core_1 = require("@cyk-language/cyk-core");
|
|
27
|
+
const fs = __importStar(require("fs"));
|
|
28
|
+
const loglevel_1 = __importDefault(require("loglevel"));
|
|
29
|
+
const dotenv_1 = __importDefault(require("dotenv"));
|
|
30
|
+
const commander_1 = require("commander");
|
|
31
|
+
const child_process_1 = require("child_process");
|
|
32
|
+
const logger = loglevel_1.default.getLogger("cyktable.ts");
|
|
33
|
+
logger.setLevel("debug");
|
|
34
|
+
const program = new commander_1.Command();
|
|
35
|
+
program.name('cyktable').description('import/export table rows')
|
|
36
|
+
.version('0.2');
|
|
37
|
+
program.command('export').description('export to CSV file(s)')
|
|
38
|
+
.argument('<tables...>', 'table(s) to export')
|
|
39
|
+
.option('-e --env <env>', 'path to the environment variables file')
|
|
40
|
+
.option('-f --file <file>', 'name of the file to create, defaults to <table_name>.csv')
|
|
41
|
+
.option('-d --dir <directory>', 'name of the directory where to create exported files')
|
|
42
|
+
.action(async (tables, options) => commandImportExport('to', tables, options));
|
|
43
|
+
program.command('import').description('export to CSV file(s)')
|
|
44
|
+
.argument('<tables...>', 'table(s) to export')
|
|
45
|
+
.option('-e --env <env>', 'path to the environment variables file')
|
|
46
|
+
.option('-f --file <file>', 'name of the file to create, defaults to <table_name>.csv')
|
|
47
|
+
.option('-d --dir <directory>', 'name of the directory where to create exported files')
|
|
48
|
+
.action(async (tables, options) => commandImportExport('from', tables, options));
|
|
49
|
+
const getDBManager = async () => {
|
|
50
|
+
const structure = new cyk_core_1.Structure();
|
|
51
|
+
if (process.env.DBREMOTE_URL === undefined)
|
|
52
|
+
throw 'DBREMOTE_URL undefined';
|
|
53
|
+
logger.debug('DBREMOTE_URL ' + process.env.DBREMOTE_URL);
|
|
54
|
+
const dbRemote = new cyk_core_1.DBRemote(structure.scope, process.env.DBREMOTE_URL);
|
|
55
|
+
const login = await dbRemote.signin(process.env.USER_NAME, undefined, process.env.USER_PASSWORD);
|
|
56
|
+
// logger.debug(login)
|
|
57
|
+
const dbManager = new cyk_core_1.DBManager(structure.scope, dbRemote);
|
|
58
|
+
await dbManager.initialize();
|
|
59
|
+
return dbManager;
|
|
60
|
+
};
|
|
61
|
+
const commandImportExport = async (direction, tables, options) => {
|
|
62
|
+
logger.debug('tables : ', tables, 'options : ', options);
|
|
63
|
+
try {
|
|
64
|
+
const dotenvOutput = dotenv_1.default.config({ path: options.env });
|
|
65
|
+
if (dotenvOutput.error !== undefined)
|
|
66
|
+
throw dotenvOutput.error;
|
|
67
|
+
if (options.file === undefined && options.dir === undefined)
|
|
68
|
+
throw '--file or --dir mandatory';
|
|
69
|
+
if (options.file !== undefined && options.dir !== undefined)
|
|
70
|
+
throw '--file and --dir are mutually exclusive';
|
|
71
|
+
if (tables.length === 0)
|
|
72
|
+
throw 'at least one table name is mandatory';
|
|
73
|
+
if (tables.length > 1 && options.dir === undefined)
|
|
74
|
+
throw 'for multiple tables, --dir is mandatory';
|
|
75
|
+
const dbManager = await getDBManager();
|
|
76
|
+
for (let indi = 0; indi < tables.length; indi++) {
|
|
77
|
+
const tableName = tables[indi];
|
|
78
|
+
const dbTable = await dbManager.dbTableExist(tableName);
|
|
79
|
+
if (dbTable === undefined) {
|
|
80
|
+
logger.info('table ' + tableName + ' not found');
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
let lcols;
|
|
84
|
+
for (let indj = 0; indj < dbTable.columns.length; indj++) {
|
|
85
|
+
const dbColumn = dbTable.columns[indj];
|
|
86
|
+
if (lcols === undefined) {
|
|
87
|
+
lcols = "(";
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
lcols += ",";
|
|
91
|
+
}
|
|
92
|
+
lcols += dbColumn.name;
|
|
93
|
+
}
|
|
94
|
+
lcols += ")";
|
|
95
|
+
let psql_cmd = "psql -c";
|
|
96
|
+
if (process.env.HEROKU_CLI !== undefined) {
|
|
97
|
+
psql_cmd = process.env.HEROKU_CLI + ' -c ';
|
|
98
|
+
}
|
|
99
|
+
let filename;
|
|
100
|
+
if (options.file !== undefined) {
|
|
101
|
+
if (fs.existsSync(options.file) && fs.lstatSync(options.file).isDirectory())
|
|
102
|
+
throw '--file ' + options.file + ' is a directory';
|
|
103
|
+
filename = options.file;
|
|
104
|
+
}
|
|
105
|
+
else if (options.dir === undefined)
|
|
106
|
+
throw '--file and --dir unspecified';
|
|
107
|
+
else if (fs.existsSync(options.dir) === false)
|
|
108
|
+
throw 'directory ' + options.dir + ' does not exist';
|
|
109
|
+
else if (fs.lstatSync(options.dir).isFile()) {
|
|
110
|
+
logger.debug("--dir " + options.dir + " is a file ");
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
let directory = options.dir.trim();
|
|
114
|
+
if (directory[directory.length - 1] !== '/') {
|
|
115
|
+
directory += '/';
|
|
116
|
+
}
|
|
117
|
+
filename = directory + tableName + '.csv';
|
|
118
|
+
}
|
|
119
|
+
let copy_cmd = "\\copy " + tableName + lcols + direction + " '" + filename + "' csv header";
|
|
120
|
+
const shell_cmd = psql_cmd + '"' + copy_cmd + '"';
|
|
121
|
+
logger.debug(shell_cmd);
|
|
122
|
+
const child = (0, child_process_1.spawn)(shell_cmd.trim(), { stdio: 'inherit', shell: true });
|
|
123
|
+
// exec(shell_cmd.trim(), (error, stdout, stderr) => {
|
|
124
|
+
// if (error) throw error
|
|
125
|
+
// logger.debug(stdout, stderr)
|
|
126
|
+
// })
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
logger.error(err);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
program.parse();
|
package/build/index.d.ts
ADDED
package/build/index.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env ts-node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const loglevel_1 = __importDefault(require("loglevel"));
|
|
8
|
+
const commander_1 = require("commander");
|
|
9
|
+
const ModuleCommand_1 = require("./ModuleCommand");
|
|
10
|
+
const UserCommand_1 = require("./UserCommand");
|
|
11
|
+
const QueryCommand_1 = require("./QueryCommand");
|
|
12
|
+
const TableCommand_1 = require("./TableCommand");
|
|
13
|
+
const TestCommand_1 = require("./TestCommand");
|
|
14
|
+
const RunCommand_1 = require("./RunCommand");
|
|
15
|
+
const InitCommand_1 = require("./InitCommand");
|
|
16
|
+
const logger = loglevel_1.default.getLogger("index.ts");
|
|
17
|
+
logger.setLevel("debug");
|
|
18
|
+
const program = new commander_1.Command();
|
|
19
|
+
program.name('cyk').description('cyklang CLI')
|
|
20
|
+
.version('0.2');
|
|
21
|
+
program.addCommand(new InitCommand_1.InitCommand('init'));
|
|
22
|
+
program.addCommand(new ModuleCommand_1.ModuleCommand('module'));
|
|
23
|
+
program.addCommand(new ModuleCommand_1.ModuleCommand('m'));
|
|
24
|
+
program.addCommand(new UserCommand_1.UserCommand('user'));
|
|
25
|
+
program.addCommand(new UserCommand_1.UserCommand('u'));
|
|
26
|
+
program.addCommand(new QueryCommand_1.QueryCommand('query'));
|
|
27
|
+
program.addCommand(new QueryCommand_1.QueryCommand('q'));
|
|
28
|
+
program.addCommand(new TableCommand_1.TableCommand('table'));
|
|
29
|
+
program.addCommand(new TableCommand_1.TableCommand('t'));
|
|
30
|
+
program.addCommand(new TestCommand_1.TestCommand());
|
|
31
|
+
program.addCommand(new RunCommand_1.RunCommand());
|
|
32
|
+
program.parse();
|