@cicctencent/tars2node-cli 0.0.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/README.md +74 -0
- package/bin/tars.js +81 -0
- package/jce.pegjs +359 -0
- package/lib/generator/finder.js +122 -0
- package/lib/generator/printer.js +116 -0
- package/lib/generator/ts/def/base.js +55 -0
- package/lib/generator/ts/def/const.js +108 -0
- package/lib/generator/ts/def/enum.js +144 -0
- package/lib/generator/ts/def/interf.js +508 -0
- package/lib/generator/ts/def/proxy.js +483 -0
- package/lib/generator/ts/def/struct.js +383 -0
- package/lib/generator/ts/generator.js +645 -0
- package/lib/generator/ts/printer.js +66 -0
- package/lib/generator/ts/typing.js +193 -0
- package/lib/generator/ts/util.js +21 -0
- package/lib/generator/typing.js +351 -0
- package/lib/parser/parser.js +383 -0
- package/main.d.ts +29 -0
- package/main.js +35 -0
- package/package.json +44 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const peg = require('pegjs');
|
|
6
|
+
const assert = require('assert');
|
|
7
|
+
const globby = require('globby');
|
|
8
|
+
const util = require('util');
|
|
9
|
+
|
|
10
|
+
const PEG_SOURCE = './../../jce.pegjs';
|
|
11
|
+
const parser = buildParser();
|
|
12
|
+
|
|
13
|
+
class AST {
|
|
14
|
+
/**
|
|
15
|
+
* constructor
|
|
16
|
+
* @param {string} pathname
|
|
17
|
+
*/
|
|
18
|
+
constructor(pathname) {
|
|
19
|
+
assert(pathname.length > 0, 'Need at least one entry file to parse.');
|
|
20
|
+
|
|
21
|
+
this.pathname = pathname;
|
|
22
|
+
/** @type {Object.<string, *>} */
|
|
23
|
+
this.parsed = {};
|
|
24
|
+
this.parser = parser;
|
|
25
|
+
/** @type {Object.<string, *>} */
|
|
26
|
+
this.refMap = {};
|
|
27
|
+
/** @type {Object.<string, *>} */
|
|
28
|
+
this.fileRefMap = {};
|
|
29
|
+
// 倒排索引
|
|
30
|
+
this.invertedMap = {};
|
|
31
|
+
/** @type {string[]} */
|
|
32
|
+
this.entry = [];
|
|
33
|
+
/** 入口文件路径 */
|
|
34
|
+
this.entryFilepath = '';
|
|
35
|
+
/** 记录文件是否已经被加载 */
|
|
36
|
+
this.refFilePath = new Map();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 原始编译方式
|
|
40
|
+
buildAST() {
|
|
41
|
+
const result = this.parseTars();
|
|
42
|
+
|
|
43
|
+
this.setRefMap(result.modules, result.pathname, true);
|
|
44
|
+
this.handleRefRecursively(result.refs, this.pathname);
|
|
45
|
+
return this.refMap;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 按文件模块解析AST
|
|
49
|
+
buildFileAST() {
|
|
50
|
+
const result = this.parseTars();
|
|
51
|
+
this.setFileRefMap(result.modules, result.pathname);
|
|
52
|
+
this.handleFileRefRecursively(result.refs, this.pathname);
|
|
53
|
+
// fs.writeFileSync('fileRefMap.json', JSON.stringify(this.fileRefMap, null, 2),{encoding: 'utf8'});
|
|
54
|
+
// fs.writeFileSync('invertedMap.json', JSON.stringify(this.invertedMap, null, 2),{encoding: 'utf8'});
|
|
55
|
+
this.changeModuleName()
|
|
56
|
+
// fs.writeFileSync('refMap.json', JSON.stringify(this.refMap, null, 2),{encoding: 'utf8'});
|
|
57
|
+
return this.refMap;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 解决递归问题,合并依赖文件。
|
|
61
|
+
buildASTRecursiveMerge() {
|
|
62
|
+
const result = this.parseTars();
|
|
63
|
+
this.setRefMapRecuriveMerge(result.modules, result.pathname, true);
|
|
64
|
+
this.handleRefRecursivelyMerge(result.refs, this.pathname, true);
|
|
65
|
+
// TODO:: 归一化 this.changeModuleName()
|
|
66
|
+
this.changeModuleNameOrigin();
|
|
67
|
+
// 合并文件,并去除依赖
|
|
68
|
+
this.mergeModuleFile();
|
|
69
|
+
return this.refMap;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// 合并 include 文件
|
|
73
|
+
mergeModuleFile() {
|
|
74
|
+
const entryModelName = path.basename(this.pathname, '.tars');
|
|
75
|
+
Object.keys(this.refMap).forEach(key => {
|
|
76
|
+
const moduleName = path.basename(this.refMap[key].pathname, '.tars');
|
|
77
|
+
// 入口文件作为合并基准
|
|
78
|
+
if (moduleName == entryModelName) {
|
|
79
|
+
} else {
|
|
80
|
+
this.refMap[entryModelName].value = this.refMap[entryModelName].value.concat(this.refMap[key].value);
|
|
81
|
+
delete this.refMap[key];
|
|
82
|
+
}
|
|
83
|
+
// this.refMap[entryModelName].value.map(m => {
|
|
84
|
+
// if (m.type === 'interface') {
|
|
85
|
+
// // TODO:: 处理方法
|
|
86
|
+
// // m.methods.forEach(({ params, output }) => {
|
|
87
|
+
// // this._checkIsTypeNeedImport(output, moduleName);
|
|
88
|
+
// // params && params.forEach(({ type }) => { // 测试函数允许没有参数
|
|
89
|
+
// // this._checkIsTypeNeedImport(type, moduleName);
|
|
90
|
+
// // });
|
|
91
|
+
// // });
|
|
92
|
+
// } else if (m.type === 'struct') {
|
|
93
|
+
// // 处理结构体
|
|
94
|
+
// m.members.forEach(({ type }) => {
|
|
95
|
+
// this.renameImport(type, entryModelName);
|
|
96
|
+
// });
|
|
97
|
+
// }
|
|
98
|
+
// })
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 修改 module name
|
|
103
|
+
* */
|
|
104
|
+
changeModuleNameOrigin() {
|
|
105
|
+
// 记录映射关系
|
|
106
|
+
let moduleMap = new Map();
|
|
107
|
+
Object.keys(this.refMap).forEach(key => {
|
|
108
|
+
const moduleName = path.basename(this.refMap[key].pathname, '.tars');
|
|
109
|
+
moduleMap.set(key, moduleName);
|
|
110
|
+
this.refMap[moduleName] = this.refMap[key];
|
|
111
|
+
// 去除改变之前的多余的module
|
|
112
|
+
delete this.refMap[key];
|
|
113
|
+
});
|
|
114
|
+
// 改变包的引用名称
|
|
115
|
+
Object.keys(this.refMap).forEach(key => {
|
|
116
|
+
this.refMap[key].value &&
|
|
117
|
+
this.refMap[key].value.forEach(item => {
|
|
118
|
+
item.members &&
|
|
119
|
+
item.members.forEach(member => {
|
|
120
|
+
// 需要改变引用包名称
|
|
121
|
+
if (util.isObject(member.type) && member.type.nested && member.type.nested.length > 0) {
|
|
122
|
+
member.type.nested = member.type.nested.map(module => {
|
|
123
|
+
return moduleMap.get(module);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @param {*[]} modules
|
|
133
|
+
* @param {string} pathname
|
|
134
|
+
*/
|
|
135
|
+
setFileRefMap(modules, pathname) {
|
|
136
|
+
const fileRefMap = this.fileRefMap[pathname] = {};
|
|
137
|
+
modules.forEach(({ id, type, value }) => {
|
|
138
|
+
assert(type === 'module', `File ${id} is not a tars module.`);
|
|
139
|
+
(value || []).forEach(item => {
|
|
140
|
+
// 这里不考虑从哪里引用了,因为法确定
|
|
141
|
+
this.invertedMap[item.id] = {
|
|
142
|
+
pathname,
|
|
143
|
+
moduleId: id
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
fileRefMap[id] = value;
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** 递归处理引用
|
|
151
|
+
* @param {{type: string, target: string}[]} refList
|
|
152
|
+
* @param {string} pathname
|
|
153
|
+
*/
|
|
154
|
+
handleFileRefRecursively(refList, pathname) {
|
|
155
|
+
const parsedRefs = this.parseRefs(refList, pathname);
|
|
156
|
+
|
|
157
|
+
parsedRefs.forEach(({ refs, pathname: _pathname, modules }) => {
|
|
158
|
+
this.setFileRefMap(modules, _pathname);
|
|
159
|
+
this.handleFileRefRecursively(refs, _pathname);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** 递归处理引用
|
|
164
|
+
* @param {{type: string, target: string}[]} refList
|
|
165
|
+
* @param {string} pathname
|
|
166
|
+
*/
|
|
167
|
+
handleRefRecursively(refList, pathname) {
|
|
168
|
+
const parsedRefs = this.parseRefs(refList, pathname);
|
|
169
|
+
|
|
170
|
+
parsedRefs.forEach(({ refs, pathname: _pathname, modules }) => {
|
|
171
|
+
this.setRefMap(modules, _pathname);
|
|
172
|
+
this.handleFileRefRecursively(refs, _pathname);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* 修改 module name
|
|
178
|
+
* */
|
|
179
|
+
changeModuleName() {
|
|
180
|
+
// 记录映射关系
|
|
181
|
+
let moduleMap = {};
|
|
182
|
+
Object.keys(this.fileRefMap).forEach(key => {
|
|
183
|
+
const moduleName = path.basename(key).replace(/\.\w+$/, '');
|
|
184
|
+
const module = this.fileRefMap[key];
|
|
185
|
+
// path到name
|
|
186
|
+
moduleMap[key] = moduleName;
|
|
187
|
+
// todo: 目前一个文件只允许导出1个module
|
|
188
|
+
this.refMap[moduleName] = {
|
|
189
|
+
pathname: key,
|
|
190
|
+
value: module[Object.keys(module)[0]],
|
|
191
|
+
};
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
const changeNest = type => {
|
|
195
|
+
if (typeof type !== 'object') {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (typeof type.key === 'object') {
|
|
199
|
+
changeNest(type.key);
|
|
200
|
+
}
|
|
201
|
+
if (typeof type.value === 'object') {
|
|
202
|
+
changeNest(type.value);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (typeof type.target === 'object') {
|
|
206
|
+
changeNest(type.target);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (typeof type.target !== 'string') {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const conf = this.invertedMap[type.target];
|
|
213
|
+
// 需要改变引用包名称
|
|
214
|
+
if (conf) {
|
|
215
|
+
const moduleName = moduleMap[conf.pathname];
|
|
216
|
+
if (moduleName) {
|
|
217
|
+
type.nested = [moduleName];
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
// 改变包的引用名称
|
|
223
|
+
Object.keys(this.refMap).forEach(key => {
|
|
224
|
+
const refObj = this.refMap[key];
|
|
225
|
+
refObj.value.forEach(item => {
|
|
226
|
+
(item.members || []).forEach(member => {
|
|
227
|
+
changeNest(member.type);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* @param {*[]} modules
|
|
235
|
+
* @param {string} pathname
|
|
236
|
+
* @param {boolean} [isEntry = false]
|
|
237
|
+
*/
|
|
238
|
+
setRefMap(modules, pathname, isEntry = false) {
|
|
239
|
+
modules.forEach(({
|
|
240
|
+
id,
|
|
241
|
+
type,
|
|
242
|
+
value,
|
|
243
|
+
}) => {
|
|
244
|
+
assert(type === 'module', `File ${id} is not a tars module.`);
|
|
245
|
+
if (!this.refMap[id]) {
|
|
246
|
+
if (isEntry) {
|
|
247
|
+
this.entry.push(id);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
this.refMap[id] = {};
|
|
251
|
+
this.refMap[id].pathname = pathname;
|
|
252
|
+
this.refMap[id].value = value;
|
|
253
|
+
} else {
|
|
254
|
+
this.refMap[id].value = this.refMap[id].value.concat(value);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* @param {*[]} modules
|
|
262
|
+
* @param {string} pathname
|
|
263
|
+
* @param {boolean} [isEntry = false]
|
|
264
|
+
*/
|
|
265
|
+
setRefMapRecuriveMerge(modules, pathname, isEntry = false) {
|
|
266
|
+
return modules.map(({ id, type, value }) => {
|
|
267
|
+
assert(type === 'module', `File ${id} is not a tars module.`);
|
|
268
|
+
if (!this.refMap[id]) {
|
|
269
|
+
if (isEntry) {
|
|
270
|
+
this.entry.push(id);
|
|
271
|
+
this.entryFilepath = pathname;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
this.refMap[id] = {};
|
|
275
|
+
this.refMap[id].pathname = pathname;
|
|
276
|
+
this.refMap[id].value = value;
|
|
277
|
+
} else {
|
|
278
|
+
// 判断文件路径是否已经被使用。由于用户定义的协议的 module name 不跟随文件名
|
|
279
|
+
if (this.refFilePath.get(`${pathname}${id}`)) {
|
|
280
|
+
// console.error('文件已被加载>>>', this.refFilePath.get(`${pathname}${id}`), pathname);
|
|
281
|
+
// Object.keys(this.refMap).forEach(key => {
|
|
282
|
+
// console.error(`key>>>> ${key}`, this.refMap[key].value.length, pathname);
|
|
283
|
+
// })
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
this.refMap[id].value = this.refMap[id].value.concat(value);
|
|
287
|
+
}
|
|
288
|
+
// 记录加载的文件
|
|
289
|
+
this.refFilePath.set(`${pathname}${id}`, id);
|
|
290
|
+
return true;
|
|
291
|
+
}).filter(item => item).length > 0
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* @param {string} [pathname]
|
|
296
|
+
*/
|
|
297
|
+
parseTars(pathname) {
|
|
298
|
+
pathname = pathname || this.pathname;
|
|
299
|
+
assert(pathname.length > 0, 'Need at least one .tars file to parse.');
|
|
300
|
+
let result;
|
|
301
|
+
try {
|
|
302
|
+
result = parser.parse(fs.readFileSync(pathname, 'utf8'));
|
|
303
|
+
} catch (e) {
|
|
304
|
+
console.error('\x1b[31m', `💥 Parse ${pathname} fail.`);
|
|
305
|
+
if (e.location && e.location.start && e.location.end) {
|
|
306
|
+
console.error('\x1b[31m', `💥 Error line: start at ${e.location.start.line} end at ${e.location.end.line}`);
|
|
307
|
+
console.error('\x1b[31m', `💥 Error column: start at ${e.location.start.column} end at ${e.location.end.column}`);
|
|
308
|
+
}
|
|
309
|
+
console.error('\x1b[31m', `💥 ${e.stack}`);
|
|
310
|
+
throw new Error('An error occured, compiling stoped');
|
|
311
|
+
}
|
|
312
|
+
const refs = /** @type {{type: string, target: string}[]} */ (result).filter(({ type }) => type === 'ref');
|
|
313
|
+
const modules = /** @type {{type: string, target: string}[]} */ (result).filter(({ type }) => type === 'module');
|
|
314
|
+
assert(modules.length > 0, 'A file must include at least one module.');
|
|
315
|
+
|
|
316
|
+
const parsed = {
|
|
317
|
+
refs,
|
|
318
|
+
modules,
|
|
319
|
+
pathname,
|
|
320
|
+
};
|
|
321
|
+
this.parsed[pathname] = parsed;
|
|
322
|
+
return parsed;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* @param {{type: string, target: string}[]} refs
|
|
327
|
+
* @param {string} pathname
|
|
328
|
+
*/
|
|
329
|
+
parseRefs(refs, pathname) {
|
|
330
|
+
pathname = pathname || this.pathname;
|
|
331
|
+
const { dir } = path.parse(pathname);
|
|
332
|
+
return refs.map(ref => {
|
|
333
|
+
let targetPath = path.resolve(dir, ref.target);
|
|
334
|
+
let result = this.parsed[targetPath];
|
|
335
|
+
if (!result) {
|
|
336
|
+
if (!fs.existsSync(targetPath)) {
|
|
337
|
+
const { base } = path.parse(targetPath);
|
|
338
|
+
const cwd = path.resolve(dir, '../../'); // 从上2级目录开始找
|
|
339
|
+
const filePaths = globby.sync(`**/${base}`, {
|
|
340
|
+
cwd,
|
|
341
|
+
});
|
|
342
|
+
if (filePaths.length) {
|
|
343
|
+
targetPath = path.resolve(cwd, filePaths[0]);
|
|
344
|
+
} else {
|
|
345
|
+
throw new Error(`找不到${pathname}依赖的${base}文件!`);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
result = this.parseTars(targetPath);
|
|
349
|
+
}
|
|
350
|
+
return result;
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* 递归处理引用
|
|
356
|
+
* @param {{type: string, target: string}[]} refList
|
|
357
|
+
* @param {string} pathname
|
|
358
|
+
*/
|
|
359
|
+
handleRefRecursivelyMerge(refList, pathname, init = false) {
|
|
360
|
+
// 入口文件只需要执行一次。不需要重复导入
|
|
361
|
+
if (this.entryFilepath == pathname && !init) {
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
const parsedRefs = this.parseRefs(refList, pathname);
|
|
365
|
+
parsedRefs.forEach(({ refs, pathname: _pathname, modules }) => {
|
|
366
|
+
const hasNew = this.setRefMapRecuriveMerge(modules, _pathname);
|
|
367
|
+
// 判断是否有新增文件,有新增文件,需要递归查找引用文件
|
|
368
|
+
if (!hasNew) {
|
|
369
|
+
// console.error("Recursively >>> error", _pathname);
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
this.handleRefRecursivelyMerge(refs, _pathname);
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function buildParser() {
|
|
378
|
+
const content = fs.readFileSync(path.resolve(__dirname, PEG_SOURCE), 'utf8');
|
|
379
|
+
const source = content.toString();
|
|
380
|
+
return peg.generate(source);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
module.exports = AST;
|
package/main.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface Config {
|
|
2
|
+
withReturn?: boolean;
|
|
3
|
+
interface?: boolean;
|
|
4
|
+
gather?: boolean;
|
|
5
|
+
long?: 'string'|'number'|'bigint';
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export declare function run(
|
|
9
|
+
entry: string,
|
|
10
|
+
type: 'ts' | 'es5',
|
|
11
|
+
dir?: string,
|
|
12
|
+
mode?: 'service' | 'client' | 'all',
|
|
13
|
+
config?: Config
|
|
14
|
+
): Promise<Array<void>>;
|
|
15
|
+
|
|
16
|
+
export declare function process(
|
|
17
|
+
entry: string,
|
|
18
|
+
type: 'ts' | 'es5',
|
|
19
|
+
dir?: string,
|
|
20
|
+
mode?: 'service' | 'client' | 'all',
|
|
21
|
+
config?: Config
|
|
22
|
+
): Promise<object>;
|
|
23
|
+
|
|
24
|
+
export interface AST {
|
|
25
|
+
entry: string[];
|
|
26
|
+
buildAST(): object;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export declare function ast(entry: string): AST;
|
package/main.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
const Generator = require('./lib/generator/ts/generator');
|
|
6
|
+
const TsParser = require('./lib/parser/parser');
|
|
7
|
+
|
|
8
|
+
function runner(entry, type, dir, mode = 'service', config = {}) {
|
|
9
|
+
dir = dir || path.parse(entry).dir;
|
|
10
|
+
|
|
11
|
+
const parser = new TsParser(entry);
|
|
12
|
+
let ast
|
|
13
|
+
if (config.useModuleName === false) {
|
|
14
|
+
ast = parser.buildAST()
|
|
15
|
+
} else if (config.fixRecurAndMerge) {
|
|
16
|
+
ast = parser.buildASTRecursiveMerge()
|
|
17
|
+
} else {
|
|
18
|
+
ast = parser.buildFileAST()
|
|
19
|
+
}
|
|
20
|
+
return new Generator(ast, entry, {
|
|
21
|
+
mode,
|
|
22
|
+
type,
|
|
23
|
+
output: dir,
|
|
24
|
+
long: 'string',
|
|
25
|
+
...config,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports.ast = entry => new TsParser(entry).buildAST();
|
|
30
|
+
module.exports.memo = (...args) => runner(...args).memo();
|
|
31
|
+
module.exports.run = (...args) => runner(...args).build();
|
|
32
|
+
module.exports.process = (...args) => {
|
|
33
|
+
const generator = runner(...args);
|
|
34
|
+
return generator.build().then(() => generator.getTree());
|
|
35
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cicctencent/tars2node-cli",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "main.js",
|
|
6
|
+
"types": "main.d.ts",
|
|
7
|
+
"access": "public",
|
|
8
|
+
"files": [
|
|
9
|
+
"lib",
|
|
10
|
+
"bin",
|
|
11
|
+
"main.d.ts",
|
|
12
|
+
"jce.pegjs"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"test": "mocha --recursive \"./test/**/*.test.js\" -w --watch-extensions js",
|
|
16
|
+
"test:lint": "eslint main.js bin/ lib/"
|
|
17
|
+
},
|
|
18
|
+
"author": "liquidliang",
|
|
19
|
+
"original_author": "kealxiao",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"bin": {
|
|
22
|
+
"tars": "./bin/tars.js"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"chokidar": "^2.1.8",
|
|
26
|
+
"commander": "^2.20.3",
|
|
27
|
+
"fs-extra": "^8.1.0",
|
|
28
|
+
"globby": "^11.1.0",
|
|
29
|
+
"pegjs": "^0.10.0",
|
|
30
|
+
"typescript": "^3.9.10"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@tars/rpc": "latest",
|
|
34
|
+
"@tars/stream": "latest",
|
|
35
|
+
"@types/fs-extra": "^8.1.5",
|
|
36
|
+
"@types/node": "^10.17.60",
|
|
37
|
+
"@types/pegjs": "^0.10.6",
|
|
38
|
+
"chai": "^4.5.0",
|
|
39
|
+
"eslint": "^5.16.0",
|
|
40
|
+
"eslint-config-airbnb-base": "^13.2.0",
|
|
41
|
+
"eslint-plugin-import": "^2.32.0",
|
|
42
|
+
"mocha": "^5.2.0"
|
|
43
|
+
}
|
|
44
|
+
}
|