@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.
Files changed (51) hide show
  1. package/README.md +1 -0
  2. package/aws-ecs.env +38 -0
  3. package/build/Cmd.d.ts +7 -0
  4. package/build/Cmd.js +35 -0
  5. package/build/DBClient.d.ts +10 -0
  6. package/build/DBClient.js +205 -0
  7. package/build/InitCommand.d.ts +9 -0
  8. package/build/InitCommand.js +122 -0
  9. package/build/ModuleCommand.d.ts +5 -0
  10. package/build/ModuleCommand.js +202 -0
  11. package/build/NodeCrypto.d.ts +5 -0
  12. package/build/NodeCrypto.js +49 -0
  13. package/build/QueryCommand.d.ts +5 -0
  14. package/build/QueryCommand.js +62 -0
  15. package/build/RunCommand.d.ts +5 -0
  16. package/build/RunCommand.js +112 -0
  17. package/build/TableCommand.d.ts +5 -0
  18. package/build/TableCommand.js +140 -0
  19. package/build/TestCommand copy.d.ts +5 -0
  20. package/build/TestCommand copy.js +111 -0
  21. package/build/TestCommand.d.ts +5 -0
  22. package/build/TestCommand.js +111 -0
  23. package/build/UserCommand.d.ts +5 -0
  24. package/build/UserCommand.js +202 -0
  25. package/build/console.d.ts +13 -0
  26. package/build/console.js +109 -0
  27. package/build/cykquery.d.ts +2 -0
  28. package/build/cykquery.js +145 -0
  29. package/build/cyktable.d.ts +2 -0
  30. package/build/cyktable.js +133 -0
  31. package/build/index.d.ts +2 -0
  32. package/build/index.js +32 -0
  33. package/build/module.d.ts +2 -0
  34. package/build/module.js +290 -0
  35. package/docker-compose.ecs.yml +44 -0
  36. package/docker-compose.yml +43 -0
  37. package/docker.env +38 -0
  38. package/package.json +38 -0
  39. package/src/Cmd.ts +33 -0
  40. package/src/DBClient.ts +220 -0
  41. package/src/InitCommand.ts +107 -0
  42. package/src/ModuleCommand.ts +192 -0
  43. package/src/NodeCrypto.ts +60 -0
  44. package/src/QueryCommand.ts +62 -0
  45. package/src/RunCommand.ts +98 -0
  46. package/src/TableCommand.ts +127 -0
  47. package/src/TestCommand.ts +98 -0
  48. package/src/UserCommand.ts +203 -0
  49. package/src/console.ts +97 -0
  50. package/src/index.ts +30 -0
  51. package/tsconfig.json +12 -0
@@ -0,0 +1,98 @@
1
+ import { Structure, Script, XmlError, DBRemote, DBManager, ModuleInstruction, parseXML } from "@cyklang/core"
2
+ import * as fs from "fs"
3
+ import { errorconsole, PrintInstructionType } from "./console"
4
+ import loglevel from 'loglevel'
5
+ import { NodeCrypto } from "./NodeCrypto"
6
+ import { Cmd } from "./Cmd"
7
+ loglevel.setLevel('debug')
8
+ const logger = loglevel.getLogger('RunCommand.ts');
9
+
10
+ export class RunCommand extends Cmd {
11
+ constructor() {
12
+ super('run')
13
+ this.description('run module').version('0.2')
14
+ .argument('<files...>', 'local module file(s) to run')
15
+ .action(async(files: any, options: any) => {
16
+ await this.runFiles(files, options)
17
+ })
18
+ }
19
+ async runFiles(files: string[], options: any) {
20
+ try {
21
+ await this.prologue(options)
22
+ for (let ind=0; ind < files.length; ind++) {
23
+ const result = await runFile(files[ind])
24
+ // if (result === false) {
25
+ // logger.debug('*********** FAILURE ' + process.argv[ind] + ' ***************')
26
+ // }
27
+ }
28
+ }
29
+ catch (err) {
30
+ logger.error(err)
31
+ }
32
+ }
33
+ }
34
+
35
+
36
+ async function runFile(filename: string): Promise<void> {
37
+ let result: boolean
38
+
39
+ if (filename.indexOf(".") !== -1) {
40
+ filename = filename.substring(0, filename.indexOf("."))
41
+ }
42
+
43
+ let xmlfilename = filename + ".xml"
44
+ // let logfilename = filename + ".log"
45
+ // let outfilename = filename + ".output"
46
+
47
+ let xml = fs.readFileSync(xmlfilename)
48
+
49
+ // fs.writeFileSync(logfilename, "")
50
+
51
+ try {
52
+ if (process.env.DBREMOTE_URL === undefined) throw 'DBREMOTE_URL undefined'
53
+ logger.trace('DBREMOTE_URL '+process.env.DBREMOTE_URL)
54
+ const structure = new Structure()
55
+ const nodeCrypto = new NodeCrypto()
56
+ const dbRemote = new DBRemote(structure.scope, process.env.DBREMOTE_URL, nodeCrypto)
57
+ const login = await dbRemote.signin(process.env.USER_NAME, undefined, process.env.USER_PASSWORD)
58
+ const dbManager = new DBManager(structure.scope, dbRemote)
59
+ await dbManager.initialize()
60
+ const tag = parseXML(xmlfilename, xml.toString())
61
+ const moduleInstruction = new ModuleInstruction(tag, dbManager)
62
+ await moduleInstruction.parse(structure.scope)
63
+ await moduleInstruction.execute(structure.scope)
64
+
65
+ // structure.scope.addInstructionType(new PrintInstructionType(logfilename))
66
+ // let script = new Script(structure.scope, xmlfilename, xml.toString())
67
+ // await script.parseInstructions()
68
+ // await script.execute()
69
+ }
70
+ catch (err) {
71
+
72
+ if (err instanceof XmlError) {
73
+ let xmlError = <XmlError>err
74
+ errorconsole(xmlError)
75
+ }
76
+ console.log(err)
77
+ }
78
+
79
+ // let log = fs.readFileSync(logfilename)
80
+ // if (fs.existsSync(outfilename) === true ) {
81
+ // let out = fs.readFileSync(outfilename)
82
+
83
+ // if (log.toString() === out.toString()) {
84
+ // console.log("test " + xmlfilename + " SUCCESS")
85
+ // result = true
86
+ // }
87
+ // else {
88
+ // console.log("test " + xmlfilename + " FAILURE")
89
+ // result = false
90
+ // }
91
+ // }
92
+ // else {
93
+ // console.log("test " + xmlfilename + " output file not found ")
94
+ // result = false
95
+ // }
96
+
97
+ // return result
98
+ }
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env ts-node
2
+ import { DBManager } from "@cyklang/core"
3
+ import * as fs from "fs"
4
+ import loglevel from 'loglevel'
5
+ import { Command } from "commander"
6
+ import { spawn } from "child_process"
7
+ import { Cmd } from "./Cmd"
8
+ const logger = loglevel.getLogger("TableCommand.ts")
9
+ logger.setLevel("debug")
10
+
11
+ export class TableCommand extends Command {
12
+ constructor(name: string) {
13
+ super(name)
14
+ this.description('import/export table rows').version('0.1')
15
+ this.addCommand(new TableExportCmd())
16
+ }
17
+ }
18
+
19
+ class TableExportCmd extends Cmd {
20
+ constructor() {
21
+ super('export')
22
+ this.description('export to CSV file(s)')
23
+ .argument('<tables...>', 'table(s) to export')
24
+ .option('-f --file <file>', 'name of the file to create, defaults to <table_name>.csv')
25
+ .option('-d --dir <directory>', 'name of the directory where to create exported files')
26
+ .action(async (tables, options) => this.commandExport( tables, options))
27
+ }
28
+ async commandExport(tables: string[], options: Options) {
29
+ await this.prologue(options)
30
+ if (this.dbManager === undefined) throw 'dbManager undefined'
31
+ await commandImportExport(this.dbManager, 'to', tables, options)
32
+ }
33
+ }
34
+
35
+ class TableImportCmd extends Cmd {
36
+ constructor() {
37
+ super('import')
38
+ this.description('import from CSV file(s)')
39
+ .option('-f --file <file>', 'name of the file to import, defaults to <table_name>.csv')
40
+ .option('-d --dir <directory>', 'name of the directory where to find files to import')
41
+ .action(async (tables, options) => this.commandImport(tables, options))
42
+ }
43
+ async commandImport(tables: string[], options: Options) {
44
+ await this.prologue(options)
45
+ if (this.dbManager === undefined) throw 'dbManager undefined'
46
+ await commandImportExport(this.dbManager, 'from', tables, options)
47
+ }
48
+ }
49
+
50
+ interface Options {
51
+ env: string | undefined
52
+ file: string | undefined
53
+ dir: string | undefined
54
+ }
55
+
56
+ const commandImportExport = async (dbManager: DBManager, direction: 'from' | 'to', tables: string[], options: Options) => {
57
+ logger.debug('tables : ', tables, 'options : ', options)
58
+ try {
59
+
60
+ if (options.file === undefined && options.dir === undefined) throw '--file or --dir mandatory'
61
+ if (options.file !== undefined && options.dir !== undefined) throw '--file and --dir are mutually exclusive'
62
+ if (tables.length === 0) throw 'at least one table name is mandatory'
63
+ if (tables.length > 1 && options.dir === undefined) throw 'for multiple tables, --dir is mandatory'
64
+
65
+ for (let indi = 0; indi < tables.length; indi++) {
66
+ const tableName = tables[indi]
67
+ const dbTable = await dbManager.dbTableExist(tableName)
68
+ if (dbTable === undefined) {
69
+ logger.info('table ' + tableName + ' not found')
70
+ continue
71
+ }
72
+ let lcols: string | undefined
73
+ for (let indj = 0; indj < dbTable.columns.length; indj++) {
74
+ const dbColumn = dbTable.columns[indj]
75
+ if (lcols === undefined) {
76
+ lcols = "("
77
+ }
78
+ else {
79
+ lcols += ","
80
+ }
81
+ lcols += dbColumn.name
82
+ }
83
+ lcols += ")"
84
+
85
+ let psql_cmd = "psql -c"
86
+ if (process.env.HEROKU_CLI !== undefined) {
87
+ psql_cmd = process.env.HEROKU_CLI + ' -c '
88
+ }
89
+
90
+ let filename
91
+ if (options.file !== undefined) {
92
+ if (fs.existsSync(options.file) && fs.lstatSync(options.file).isDirectory())
93
+ throw '--file ' + options.file + ' is a directory'
94
+ filename = options.file
95
+ }
96
+ else if (options.dir === undefined)
97
+ throw '--file and --dir unspecified'
98
+ else if (fs.existsSync(options.dir) === false)
99
+ throw 'directory ' + options.dir + ' does not exist'
100
+ else if (fs.lstatSync(options.dir).isFile()) {
101
+ logger.debug("--dir " + options.dir + " is a file ")
102
+ }
103
+ else {
104
+ let directory = options.dir.trim()
105
+ if (directory[directory.length - 1] !== '/') {
106
+ directory += '/'
107
+ }
108
+ filename = directory + tableName + '.csv'
109
+ }
110
+
111
+ let copy_cmd = "\\copy " + tableName + lcols + direction + " '" + filename + "' csv header"
112
+ const shell_cmd = psql_cmd + '"' + copy_cmd + '"'
113
+ logger.debug(shell_cmd)
114
+ const child = spawn(shell_cmd.trim(), { stdio: 'inherit', shell: true })
115
+ // exec(shell_cmd.trim(), (error, stdout, stderr) => {
116
+ // if (error) throw error
117
+ // logger.debug(stdout, stderr)
118
+ // })
119
+ }
120
+ }
121
+ catch (err) {
122
+ logger.error(err)
123
+ }
124
+
125
+
126
+ }
127
+
@@ -0,0 +1,98 @@
1
+ import { Structure, Script, XmlError, DBRemote, DBManager } from "@cyklang/core"
2
+ import * as fs from "fs"
3
+ import { errorconsole, PrintInstructionType } from "./console"
4
+ import loglevel from 'loglevel'
5
+ import { NodeCrypto } from "./NodeCrypto"
6
+ import { Cmd } from "./Cmd"
7
+ loglevel.setLevel('debug')
8
+ const logger = loglevel.getLogger('TestCommand.ts');
9
+
10
+ export class TestCommand extends Cmd {
11
+ constructor() {
12
+ super('test')
13
+ this.description('test script').version('0.1')
14
+ .argument('<files...>', 'local module file(s) to test run')
15
+ .action(async(files: any, options: any) => {
16
+ await this.testRun(files, options)
17
+ })
18
+ }
19
+ async testRun(files: string[], options: any) {
20
+ try {
21
+ await this.prologue(options)
22
+ for (let ind=0; ind < files.length; ind++) {
23
+ const result = await testfile(files[ind])
24
+ if (result === false) {
25
+ logger.debug('*********** FAILURE ' + process.argv[ind] + ' ***************')
26
+ }
27
+ }
28
+ }
29
+ catch (err) {
30
+ logger.error(err)
31
+ }
32
+
33
+ }
34
+ }
35
+
36
+
37
+ async function testfile(filename: string): Promise<boolean> {
38
+ let result: boolean
39
+
40
+ if (filename.indexOf(".") !== -1) {
41
+ filename = filename.substring(0, filename.indexOf("."))
42
+ }
43
+
44
+ let xmlfilename = filename + ".xml"
45
+ let logfilename = filename + ".log"
46
+ let outfilename = filename + ".output"
47
+
48
+ let xml = fs.readFileSync(xmlfilename)
49
+
50
+
51
+ fs.writeFileSync(logfilename, "")
52
+ //console.log(xml.toString())
53
+ try {
54
+ if (process.env.DBREMOTE_URL === undefined) throw 'DBREMOTE_URL undefined'
55
+ logger.trace('DBREMOTE_URL '+process.env.DBREMOTE_URL)
56
+ const structure = new Structure()
57
+ const nodeCrypto = new NodeCrypto()
58
+ const dbRemote = new DBRemote(structure.scope, process.env.DBREMOTE_URL, nodeCrypto)
59
+ const login = await dbRemote.signin(process.env.USER_NAME, undefined, process.env.USER_PASSWORD)
60
+ //const dbRemote = new DBRemote(structure, 'https://cyk-postgres.herokuapp.com')
61
+ const dbManager = new DBManager(structure.scope, dbRemote)
62
+ await dbManager.initialize()
63
+ structure.scope.addInstructionType(new PrintInstructionType(logfilename))
64
+ let script = new Script(structure.scope, xmlfilename, xml.toString())
65
+ await script.parseInstructions()
66
+ await script.execute()
67
+ // console.log(JSON.stringify(script.block.toString()))
68
+ }
69
+ catch (err) {
70
+
71
+ if (err instanceof XmlError) {
72
+ let xmlError = <XmlError>err
73
+ errorconsole(xmlError)
74
+ }
75
+ console.log(err)
76
+ }
77
+
78
+ let log = fs.readFileSync(logfilename)
79
+ if (fs.existsSync(outfilename) === true ) {
80
+ let out = fs.readFileSync(outfilename)
81
+
82
+ if (log.toString() === out.toString()) {
83
+ console.log("test " + xmlfilename + " SUCCESS")
84
+ result = true
85
+ }
86
+ else {
87
+ console.log("test " + xmlfilename + " FAILURE")
88
+ result = false
89
+ }
90
+ }
91
+ else {
92
+ console.log("test " + xmlfilename + " output file not found ")
93
+ result = false
94
+ }
95
+
96
+
97
+ return result
98
+ }
@@ -0,0 +1,203 @@
1
+ #!/usr/bin/env ts-node
2
+ import loglevel from 'loglevel'
3
+ import { Command } from 'commander'
4
+ import { DBUser } from '@cyklang/core'
5
+ import { Cmd } from './Cmd'
6
+ import { DBClient } from './DBClient'
7
+ const logger = loglevel.getLogger('UserCommand.ts')
8
+ logger.setLevel('debug')
9
+
10
+ export class UserCommand extends Command {
11
+ constructor(name: string) {
12
+ super(name)
13
+ this.description('manage users in cyk_user table').version('0.1')
14
+ this.addCommand(new UserAddCmd())
15
+ this.addCommand(new UserUpdateCmd('update', 'update user by id all fields except password'))
16
+ this.addCommand(new UserUpdateCmd('u', 'shortcut for (u)pdate'))
17
+ this.addCommand(new UserDeleteCmd('delete', 'delete user by id and name. Both options are mandatory to avoid typing error'))
18
+ this.addCommand(new UserPasswdCmd('passwd', 'change user password'))
19
+ this.addCommand(new UserListCmd('list', 'list users'))
20
+ this.addCommand(new UserListCmd('l', 'shortcut for (l)ist'))
21
+ }
22
+ }
23
+
24
+ interface Options {
25
+ id: string | undefined
26
+ name: string | undefined
27
+ email: string | undefined
28
+ access: string | undefined
29
+ module: string | undefined
30
+ password: string | undefined
31
+ disable: boolean | undefined
32
+ env: string | undefined
33
+ sort: string | undefined
34
+ }
35
+
36
+ class UserAddCmd extends Cmd {
37
+ constructor() {
38
+ super('add')
39
+ this.description('add a new user')
40
+ .requiredOption('-n --name <name>', 'user name')
41
+ .option('-e --email <email>', 'user email address')
42
+ .option('-p --passwd <password>', 'initial password')
43
+ .option('-a --access <acl>', 'access control list')
44
+ .option('-m --module <module_name>', 'module to launch by default')
45
+ .option('-d --disable', 'user not abled to connect')
46
+ .action(async (options: Options) => {
47
+ const dbUser = new DBUser()
48
+ dbUser.name = options.name
49
+ dbUser.email = options.email
50
+ dbUser.password = options.password
51
+ dbUser.access = options.access
52
+ dbUser.appli = options.module
53
+ dbUser.disable = options.disable || false
54
+ await this.commandAdd(dbUser, options)
55
+ })
56
+ }
57
+ async commandAdd(dbUser: DBUser, options: Options) {
58
+ try {
59
+ await this.prologue(options)
60
+ if (this.dbManager === undefined) throw 'dbManager undefined'
61
+ const result = await this.dbManager.dbUserInsert(dbUser)
62
+ logger.debug(result)
63
+ }
64
+ catch (err) {
65
+ logger.error(err)
66
+ }
67
+ }
68
+ }
69
+
70
+ class UserListCmd extends Cmd {
71
+ constructor(name: string, description: string) {
72
+ super(name)
73
+ this.description(description)
74
+ .option('-s --sort <columns>', 'sort list by column numbers (begins by 0) separated by comma')
75
+ .action(async (options: Options) => {
76
+ await this.commandList(options)
77
+ })
78
+ }
79
+ async commandList(options: Options) {
80
+ try {
81
+ await this.prologue(options)
82
+ if (this.dbManager === undefined) throw 'dbManager undefined'
83
+
84
+ const dbClient = new DBClient(this.dbManager)
85
+ dbClient.selectFromTable('List of users', 'cyk_user',
86
+ { fields: 'user_id,user_name,user_email,user_access,user_appli,user_disable', sort: options.sort || '1' })
87
+
88
+ }
89
+ catch (err) {
90
+ logger.error(err)
91
+ }
92
+ }
93
+
94
+ }
95
+
96
+ class UserUpdateCmd extends Cmd {
97
+ constructor(name: string, description: string) {
98
+ super(name)
99
+ this.description(description)
100
+ .requiredOption('-i --id <id>', 'user ID')
101
+ .option('-n --name <name>', 'user name')
102
+ .option('-e --email <email>', 'user email address')
103
+ .option('-a --access <acl>', 'access control list')
104
+ .option('-m --module <module_name>', 'module to launch by default')
105
+ .option('-d --disable', 'user not able to connect')
106
+ .action(async (options: Options) => {
107
+ const dbUser = new DBUser()
108
+ dbUser.id = options.id
109
+ dbUser.name = options.name
110
+ dbUser.email = options.email
111
+ dbUser.access = options.access
112
+ dbUser.appli = options.module
113
+ dbUser.disable = options.disable
114
+ await this.commandUpdate(dbUser, options)
115
+ })
116
+ }
117
+ async commandUpdate(dbUser2: DBUser, options: Options) {
118
+ try {
119
+ await this.prologue(options)
120
+ if (this.dbManager === undefined) throw 'dbManager undefined'
121
+ if (dbUser2.id === undefined) throw 'id is missing'
122
+ const dbUser1 = await this.dbManager.getUser(dbUser2.id)
123
+ if (dbUser1 === undefined) throw 'user with id ' + dbUser2.id + ' not found'
124
+ // 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 }
125
+ if (dbUser2.name !== undefined) dbUser1.name = dbUser2.name
126
+ if (dbUser2.email !== undefined) dbUser1.email = dbUser2.email
127
+ if (dbUser2.access !== undefined) dbUser1.access = dbUser2.access
128
+ if (dbUser2.appli !== undefined) dbUser1.appli = dbUser2.appli
129
+ if (dbUser2.disable !== undefined) dbUser1.disable = dbUser2.disable
130
+ // logger.debug('dbUser1 before dbUserUpdate : ', dbUser1)
131
+ await this.dbManager.dbUserUpdate(dbUser1)
132
+ }
133
+ catch (err) {
134
+ logger.error(err)
135
+ }
136
+ }
137
+ }
138
+
139
+ class UserDeleteCmd extends Cmd {
140
+ constructor(name: string, description: string) {
141
+ super(name)
142
+ this.description(description)
143
+ .requiredOption('-i --id <id>', 'user ID')
144
+ .requiredOption('-n --name <name>', 'user name')
145
+ .action(async (options: Options) => {
146
+ const dbUser = new DBUser()
147
+ dbUser.id = options.id
148
+ dbUser.name = options.name
149
+ await this.commandDelete(dbUser, options)
150
+ })
151
+ }
152
+ async commandDelete(dbUser: DBUser, options: Options) {
153
+ try {
154
+ await this.prologue(options)
155
+ if (this.dbManager === undefined) throw 'dbManager undefined'
156
+ if (dbUser.id === undefined || dbUser.name === undefined) throw 'id or name missing'
157
+ const userExist = await this.dbManager.getUser(dbUser.id)
158
+ if (userExist === undefined) throw 'user with id ' + dbUser.id + ' not found'
159
+ if (dbUser.name !== userExist.name) 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
+
168
+ class UserPasswdCmd extends Cmd {
169
+ constructor(name: string, description: string) {
170
+ super('passwd')
171
+
172
+ this.description(description)
173
+ .requiredOption('-i --id <id>', 'user ID')
174
+ .requiredOption('-n --name <name>', 'user name')
175
+ .requiredOption('-p --password <password>', 'new password')
176
+ .action(async (options: Options) => {
177
+ const dbUser = new DBUser()
178
+ dbUser.id = options.id
179
+ dbUser.name = options.name
180
+ dbUser.password = options.password
181
+ await this.commandPasswd(dbUser, options)
182
+ })
183
+ }
184
+ async commandPasswd(dbUser: DBUser, options: Options) {
185
+ try {
186
+ await this.prologue(options)
187
+ if (this.dbManager === undefined) throw 'dbManager undefined'
188
+ // logger.debug(dbUser)
189
+ if (dbUser.id === undefined || dbUser.name === undefined || dbUser.password === undefined) throw 'id or name or password missing'
190
+ const userExist = await this.dbManager.getUser(dbUser.id)
191
+ if (userExist === undefined) throw 'user with id ' + dbUser.id + ' not found'
192
+ if (dbUser.name !== userExist.name) throw 'name ' + dbUser.name + ' different from ' + userExist.name
193
+ await this.dbManager.dbUserPasswd(dbUser.id, dbUser.password)
194
+ logger.info('password changed for user ' + dbUser.name)
195
+ }
196
+ catch (err) {
197
+ logger.error(err)
198
+ }
199
+ }
200
+ }
201
+
202
+
203
+
package/src/console.ts ADDED
@@ -0,0 +1,97 @@
1
+ import { XmlError } from '@cyklang/core'
2
+ import * as fs from "fs"
3
+ import { Instruction, InstructionType, Tag } from '@cyklang/core'
4
+ import { Data, Scope } from '@cyklang/core'
5
+ import { Expression } from '@cyklang/core'
6
+ import * as loglevel from "loglevel"
7
+ const logger = loglevel.getLogger('console.ts')
8
+ logger.setLevel('info')
9
+
10
+ export function errorconsole(xmlError: XmlError) {
11
+ if (xmlError.tag !== undefined) {
12
+ let msg = "\n=============== XmlError at (" + xmlError.tag.filename
13
+ if (xmlError.tag.line !== undefined) {
14
+ msg += ":" + (xmlError.tag.line + 1)
15
+ }
16
+ if (xmlError.tag.column !== undefined) {
17
+ msg += ":" + (xmlError.tag.column + 1)
18
+ }
19
+ msg += ") ===============\n"
20
+ console.log(msg)
21
+ }
22
+ }
23
+
24
+ export class InputInstructionType extends InstructionType {
25
+ constructor() {
26
+ super("input")
27
+ }
28
+ async parseInstruction(tag: Tag, scope: Scope): Promise<Instruction> {
29
+ let result = new InputInstruction(tag)
30
+
31
+ return result
32
+ }
33
+ }
34
+
35
+ class InputInstruction extends Instruction {
36
+ constructor(tag: Tag) {
37
+ super(tag)
38
+ }
39
+
40
+ async execute() {
41
+ throw new Error("Method not implemented.")
42
+ }
43
+ dump(): void {
44
+ throw new Error("Method not implemented.")
45
+ }
46
+
47
+ }
48
+
49
+ export class PrintInstructionType extends InstructionType {
50
+ logfilename: string
51
+ constructor(logfilename: string) {
52
+ super("print")
53
+ this.logfilename = logfilename
54
+ }
55
+ async parseInstruction(tag: Tag, scope: Scope): Promise<Instruction> {
56
+ let result = new PrintInstruction(tag, this.logfilename)
57
+ return result
58
+ }
59
+ }
60
+
61
+ class PrintInstruction extends Instruction {
62
+ exprValue: string | undefined
63
+ logfilename: string
64
+ constructor(tag: Tag, logfilename: string) {
65
+ super(tag)
66
+ this.logfilename = logfilename
67
+ this.parse(tag)
68
+ }
69
+ parse(tag: Tag): void {
70
+ this.exprValue = tag.getText()
71
+ }
72
+ async execute(scope: Scope) {
73
+ if (this.exprValue !== undefined) {
74
+ let express = new Expression(scope)
75
+ let value: Data | undefined | null
76
+ try {
77
+ value = await express.evaluate(this.exprValue)
78
+ }
79
+ catch (err) {
80
+ console.log(err)
81
+ throw (new XmlError("Expression : " + this.exprValue, this.tag))
82
+ }
83
+ // logger.debug("print expr " + this.exprValue + " -> " + value?.toString())
84
+ if (value !== undefined && value !== null) {
85
+ // console.log("testprint : " + value.toString())
86
+ fs.appendFileSync(this.logfilename, value.toString() + "\n")
87
+ }
88
+ else {
89
+ console.log(value)
90
+ //throw (new XmlError("<print> undefined : " + this.exprValue, this.tag))
91
+ }
92
+ }
93
+ }
94
+ dump() {
95
+
96
+ }
97
+ }
package/src/index.ts ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ts-node
2
+ import loglevel from 'loglevel'
3
+ import { Command } from 'commander'
4
+ import { ModuleCommand } from "./ModuleCommand"
5
+ import { UserCommand } from './UserCommand'
6
+ import { QueryCommand } from './QueryCommand'
7
+ import { TableCommand } from './TableCommand'
8
+ import { TestCommand } from './TestCommand'
9
+ import { RunCommand } from './RunCommand'
10
+ import { InitCommand } from './InitCommand'
11
+ const logger = loglevel.getLogger("index.ts")
12
+ logger.setLevel("debug")
13
+
14
+ const program = new Command()
15
+ program.name('cyk').description('cyklang CLI')
16
+ .version('0.2')
17
+
18
+ program.addCommand(new InitCommand('init'))
19
+ program.addCommand(new ModuleCommand('module'))
20
+ program.addCommand(new ModuleCommand('m'))
21
+ program.addCommand(new UserCommand('user'))
22
+ program.addCommand(new UserCommand('u'))
23
+ program.addCommand(new QueryCommand('query'))
24
+ program.addCommand(new QueryCommand('q'))
25
+ program.addCommand(new TableCommand('table'))
26
+ program.addCommand(new TableCommand('t'))
27
+ program.addCommand(new TestCommand())
28
+ program.addCommand(new RunCommand())
29
+
30
+ program.parse()
package/tsconfig.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2020",
4
+ "module": "commonjs",
5
+ "declaration": true,
6
+ "outDir": "./build",
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ },
10
+ "include": [ "src"]
11
+ }
12
+