node-automator 1.0.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 (143) hide show
  1. package/LICENSE +15 -0
  2. package/assets/alert.png +0 -0
  3. package/assets/error.png +0 -0
  4. package/assets/success.png +0 -0
  5. package/commands/abort.js +11 -0
  6. package/commands/alert.js +19 -0
  7. package/commands/assemble.js +56 -0
  8. package/commands/assert.js +18 -0
  9. package/commands/base.js +363 -0
  10. package/commands/break.js +11 -0
  11. package/commands/change_filter.js +34 -0
  12. package/commands/cheerio.js +15 -0
  13. package/commands/clear_screen.js +14 -0
  14. package/commands/commit.js +31 -0
  15. package/commands/compare.js +23 -0
  16. package/commands/confirm.js +16 -0
  17. package/commands/continue.js +11 -0
  18. package/commands/copy.js +14 -0
  19. package/commands/cursor_up.js +12 -0
  20. package/commands/date.js +25 -0
  21. package/commands/debugger.js +11 -0
  22. package/commands/dingtalk.js +110 -0
  23. package/commands/disassemble.js +36 -0
  24. package/commands/divination.js +15 -0
  25. package/commands/download.js +12 -0
  26. package/commands/edit.js +83 -0
  27. package/commands/edit_excel.js +57 -0
  28. package/commands/env_optional.js +57 -0
  29. package/commands/eval.js +27 -0
  30. package/commands/exec_from_file.js +31 -0
  31. package/commands/export_diff_head.js +31 -0
  32. package/commands/file_info.js +41 -0
  33. package/commands/file_size.js +12 -0
  34. package/commands/files.js +14 -0
  35. package/commands/first_exist.js +18 -0
  36. package/commands/flatten.js +18 -0
  37. package/commands/ftp.js +161 -0
  38. package/commands/git_commit.js +31 -0
  39. package/commands/git_export_diff_head.js +13 -0
  40. package/commands/git_is_dirty.js +13 -0
  41. package/commands/hash.js +21 -0
  42. package/commands/http_request.js +12 -0
  43. package/commands/image_crop.js +19 -0
  44. package/commands/input.js +37 -0
  45. package/commands/interval.js +60 -0
  46. package/commands/is_dirty.js +31 -0
  47. package/commands/jwt_decode.js +22 -0
  48. package/commands/list2dict.js +32 -0
  49. package/commands/log.js +72 -0
  50. package/commands/loop.js +115 -0
  51. package/commands/loop_forever.js +66 -0
  52. package/commands/merge_files.js +39 -0
  53. package/commands/mgr.js +476 -0
  54. package/commands/modify.js +44 -0
  55. package/commands/move.js +14 -0
  56. package/commands/move_local.js +14 -0
  57. package/commands/multi_select.js +16 -0
  58. package/commands/mysql_connect.js +29 -0
  59. package/commands/mysql_end.js +13 -0
  60. package/commands/mysql_query.js +19 -0
  61. package/commands/notify.js +13 -0
  62. package/commands/open.js +30 -0
  63. package/commands/parse.js +18 -0
  64. package/commands/pause.js +15 -0
  65. package/commands/print.js +47 -0
  66. package/commands/read_cache.js +12 -0
  67. package/commands/read_cfg.js +13 -0
  68. package/commands/read_clipboard.js +19 -0
  69. package/commands/read_excel.js +17 -0
  70. package/commands/read_only_excel.js +40 -0
  71. package/commands/read_plain.js +14 -0
  72. package/commands/remove.js +14 -0
  73. package/commands/retrieve.js +17 -0
  74. package/commands/reveal.js +33 -0
  75. package/commands/revision_info.js +31 -0
  76. package/commands/schedule.js +80 -0
  77. package/commands/select.js +17 -0
  78. package/commands/send_email.js +25 -0
  79. package/commands/share_data.js +745 -0
  80. package/commands/shell.js +13 -0
  81. package/commands/sleep.js +17 -0
  82. package/commands/store.js +13 -0
  83. package/commands/store_optional.js +33 -0
  84. package/commands/stream.js +16 -0
  85. package/commands/stringify.js +24 -0
  86. package/commands/svn_add.js +26 -0
  87. package/commands/svn_commit.js +49 -0
  88. package/commands/svn_export_diff_head.js +13 -0
  89. package/commands/svn_is_dirty.js +13 -0
  90. package/commands/svn_update.js +27 -0
  91. package/commands/switch.js +18 -0
  92. package/commands/temp.js +12 -0
  93. package/commands/tencent_cos.js +323 -0
  94. package/commands/test.js +14 -0
  95. package/commands/title.js +18 -0
  96. package/commands/tmpdir.js +21 -0
  97. package/commands/translate.js +58 -0
  98. package/commands/traversal.js +38 -0
  99. package/commands/truncate.js +31 -0
  100. package/commands/truncate_all.js +62 -0
  101. package/commands/ts_sort.js +18 -0
  102. package/commands/unzip.js +50 -0
  103. package/commands/updating_revision.js +28 -0
  104. package/commands/valid_required.js +31 -0
  105. package/commands/void.js +10 -0
  106. package/commands/watch_mail.js +94 -0
  107. package/commands/web_socket.js +233 -0
  108. package/commands/which.js +60 -0
  109. package/commands/write_cache.js +16 -0
  110. package/commands/write_cfg.js +18 -0
  111. package/commands/write_clipboard.js +23 -0
  112. package/commands/write_excel.js +17 -0
  113. package/commands/write_plain.js +18 -0
  114. package/commands/zip.js +78 -0
  115. package/commands/zip_data.js +64 -0
  116. package/examples/print_env.yml +3 -0
  117. package/index.js +109 -0
  118. package/package.json +63 -0
  119. package/scratch/.gitkeep +0 -0
  120. package/utils/alert_tool.js +133 -0
  121. package/utils/base64_tool.js +13 -0
  122. package/utils/cache/local_cache.js +79 -0
  123. package/utils/cache/raw_cache.js +47 -0
  124. package/utils/cache/simple_local_cache.js +33 -0
  125. package/utils/cache/simple_sqlite_cache.js +43 -0
  126. package/utils/cache/simple_svn_cache.js +49 -0
  127. package/utils/cache/svn_cache.js +40 -0
  128. package/utils/cache_tool.js +53 -0
  129. package/utils/display_tool.js +85 -0
  130. package/utils/divination_util.js +555 -0
  131. package/utils/file_tool.js +529 -0
  132. package/utils/hash_tool.js +8 -0
  133. package/utils/interaction_tool.js +228 -0
  134. package/utils/log_tool.js +190 -0
  135. package/utils/parse_directive.js +194 -0
  136. package/utils/parse_tool.js +236 -0
  137. package/utils/request_tool.js +156 -0
  138. package/utils/scm_tool.js +108 -0
  139. package/utils/selection_tool.js +593 -0
  140. package/utils/shell_tool.js +162 -0
  141. package/utils/svn_diff/diff_file.js +44 -0
  142. package/utils/svn_diff/diff_parser.js +55 -0
  143. package/utils/transform_tool.js +520 -0
@@ -0,0 +1,745 @@
1
+ const path = require("path");
2
+ const fs = require("fs");
3
+ const os = require("os");
4
+ const {
5
+ argv
6
+ } = require('yargs');
7
+ const {
8
+ flatten,
9
+ removeDuplicate,
10
+ removeDuplicateObject,
11
+ convert,
12
+ formatDate,
13
+ formatTimeInMillisec,
14
+ formatTimestampMillisec,
15
+ format
16
+ } = require("../utils/transform_tool");
17
+ const {
18
+ parse_sync,
19
+ stringify_sync
20
+ } = require("../utils/parse_tool");
21
+ const { parseDirective } = require("../utils/parse_directive");
22
+ const { hash } = require('../utils/hash_tool');
23
+ const now = Date.now();
24
+ const argv0 = process.argv0;
25
+ let projectRoot = path.resolve(__dirname, "../");
26
+ if (path.basename(argv0).startsWith("automator")) {
27
+ projectRoot = path.dirname(argv0);
28
+ }
29
+ const shareData = {
30
+ // 本程序所在目录
31
+ AUTOMATOR_ROOT: path.resolve(projectRoot, "./"),
32
+ AUTOMATOR_SCRATCH: path.resolve(projectRoot, "./scratch"),
33
+ AUTOMATOR_LOG: path.resolve(projectRoot, "./log"),
34
+ AUTOMATOR_CFG: path.resolve(projectRoot, "./cfg"),
35
+ AUTOMATOR_APPDATA: require('persist-path')('TsubasaYeung/Automator'),
36
+ AUTOMATOR_BEGIN_TIME: now,
37
+ AUTOMATOR_BEGIN_FORMATED_TIME: formatTimestampMillisec(now, "YYYYMMDD_hhmmss"),
38
+ AUTOMATOR_ELAPSED_TIME: 0,
39
+ // 运行的工作目录
40
+ CWD: process.cwd(),
41
+ // 环境变量
42
+ ENV: process.env,
43
+ // 命令行参数
44
+ ARGV: argv,
45
+ // 是否步进执行
46
+ STEP_BY_STEP: 0,
47
+ // 是否全自动执行
48
+ FULL_AUTOMATIC: 0,
49
+ QUIET_MODE: 0,
50
+ DEBUG_MODE: 0,
51
+ $COMPRESS_PROGERSS: 0,
52
+ // 指向 shareData 自身
53
+ SHARE_DATA: undefined,
54
+ // 干跑
55
+ DRY_RUN: 0,
56
+ processPipes: processPipes,
57
+ };
58
+ shareData.SHARE_DATA = shareData;
59
+ Object.defineProperty(shareData, 'AUTOMATOR_ELAPSED_TIME', {
60
+ get() {
61
+ return Date.now() - this.AUTOMATOR_BEGIN_TIME;
62
+ }
63
+ });
64
+
65
+ const LINE_EXPRESSION = "\\r\\n|\\n\\r|\\n|\\r";
66
+
67
+ // 使用 argv 更新 shareData
68
+ let rawArgs = {};
69
+ let tmpkey = null;
70
+ for (let i = 2, len = process.argv.length; i < len; ++i) {
71
+ let curarg = process.argv[i];
72
+ if (curarg[0] == '-') {
73
+ tmpkey = curarg.substr(curarg[1] == '-' ? 2 : 1);
74
+ rawArgs[tmpkey] = true;
75
+ } else {
76
+ if (tmpkey != null) {
77
+ rawArgs[tmpkey] = curarg;
78
+ tmpkey = null;
79
+ } else {
80
+
81
+ }
82
+ }
83
+ }
84
+ for (let k in argv) {
85
+ if (k != '_' && k[0] != '$') {
86
+ if (shareData[k] != null) {
87
+ shareData[k] = argv[k];
88
+ } else {
89
+ shareData[k] = rawArgs[k];
90
+ }
91
+ }
92
+ }
93
+
94
+ /**
95
+ *
96
+ * @param {string} data
97
+ */
98
+ function isSingular(data) {
99
+ if (!/^<<.*>>$/.test(data)) {
100
+ return false;
101
+ }
102
+ let reg = /(?:<<)|(?:>>)/g;
103
+ let matched;
104
+ let isRight = false;
105
+ while(matched = reg.exec(data)) {
106
+ if (isRight && matched[0] == "<<") {
107
+ return false;
108
+ }
109
+ if (!isRight && matched[0] == ">>") {
110
+ isRight = true;
111
+ }
112
+ }
113
+ return true;
114
+ }
115
+
116
+ function formatData(data) {
117
+ if (typeof data == "string") {
118
+ let reg;// = /^<<([^\$<>]*?)>>$/g;
119
+ let match; // = reg.exec(data);
120
+ if (isSingular(data)) {
121
+ return getDataByKey(data.substring(2, data.length - 2));
122
+ // let ret = data.substring(2, data.length - 2);
123
+ // return getDataByKey(ret);
124
+ } else {
125
+ // ?: is for non capturing group
126
+ // ?= is for positive look ahead
127
+ // ?! is for negative look ahead
128
+ // ?<= is for positive look behind
129
+ // ?<! is for negative look behind
130
+ reg = /(?<!\$)<<([^\$<>]*?)>>/g;
131
+ // 处理嵌套 字符串
132
+ while (match = data.match(reg)) {
133
+ data = data.replace(reg, (...args) => {
134
+ return getDataByKey(args[1]);
135
+ });
136
+ }
137
+ // 处理嵌套 代码
138
+ reg = /\$<<([^\$]*?)>>/g;
139
+ while (match = data.match(reg)) {
140
+ data = data.replace(reg, (...args) => {
141
+ return `this.${args[1]}`;
142
+ });
143
+ }
144
+ }
145
+ } else if (data instanceof Array) {
146
+ for (let i = 0, len = data.length; i < len; ++i) {
147
+ data[i] = formatData(data[i]);
148
+ }
149
+ } else if (typeof data == "object") {
150
+ for (let key in data) {
151
+ // 循环体内不处理
152
+ if (key == 'commands')
153
+ continue;
154
+ let value = data[key];
155
+ data[key] = formatData(value);
156
+ }
157
+ }
158
+ return data;
159
+ }
160
+
161
+ /**
162
+ * 获取完整真实路径
163
+ * @param {*} src
164
+ */
165
+ function get_full_path(src, createIfNotExist) {
166
+ let dstDir = path.resolve(src.replace(/^~/, os.homedir())).replace(/\\/g, "/");
167
+ let targetDir;
168
+ switch (createIfNotExist) {
169
+ case "FILE": {
170
+ targetDir = path.dirname(dstDir);
171
+ break;
172
+ }
173
+ case "FOLDER": {
174
+ targetDir = dstDir;
175
+ break;
176
+ }
177
+ }
178
+ if (targetDir && (!fs.existsSync(targetDir) || !fs.lstatSync(targetDir).isDirectory())) {
179
+ try {
180
+ fs.mkdirSync(targetDir, {
181
+ recursive: true
182
+ });
183
+ } catch (err) {
184
+ throw (err);
185
+ }
186
+ }
187
+ return dstDir;
188
+ }
189
+
190
+ function call_code(code) {
191
+ return eval(`(${code})`);
192
+ }
193
+
194
+ function eval_code(code) {
195
+ if (code == null) {
196
+ return null;
197
+ }
198
+ return call_code.call(shareData, `(${code})`);
199
+ }
200
+
201
+ /**
202
+ *
203
+ * @param {string} key
204
+ */
205
+ function getDataByKey(key, from = shareData) {
206
+ key = key.toString();
207
+ let first_pipe_index = key.indexOf("|");
208
+ const subkeys = (first_pipe_index == -1 ? key : key.substring(0, first_pipe_index).trim()).split(".");
209
+ let val = from;
210
+ for (const subkey of subkeys) {
211
+ if (subkey == null) {
212
+ continue;
213
+ }
214
+ val = val && val[formatData(subkey)];
215
+ }
216
+ if (first_pipe_index != -1) {
217
+ let rawstr = key.substring(first_pipe_index + 1);
218
+ rawstr = formatData(rawstr);
219
+ val = processPipes(val, rawstr);
220
+ }
221
+ return val;
222
+ }
223
+
224
+ function processPipe(val, pipename, pipeargs) {
225
+ switch (pipename) {
226
+ case "istream": {
227
+ if (pipeargs[0]) {
228
+ val = fs.ReadStream.from(val);
229
+ } else {
230
+ val = fs.createReadStream(val);
231
+ }
232
+ break;
233
+ }
234
+ case "ostream": {
235
+ val = fs.createWriteStream(val);
236
+ break;
237
+ }
238
+ case "splitlines": {
239
+ val = val.split(new RegExp(LINE_EXPRESSION));
240
+ break;
241
+ }
242
+ case "split": {
243
+ val = val.split(pipeargs[0]);
244
+ break;
245
+ }
246
+ case "join": {
247
+ val = val.join(pipeargs[0]);
248
+ break;
249
+ }
250
+ case "flatten": {
251
+ val = flatten(val);
252
+ break;
253
+ }
254
+ case "unique": {
255
+ val = removeDuplicate(val);
256
+ break;
257
+ }
258
+ case "unique_object": {
259
+ val = removeDuplicateObject(val, pipeargs[0]);
260
+ break;
261
+ }
262
+ case "remove_empty": {
263
+ val = val.filter(v => v);
264
+ break;
265
+ }
266
+ case "sort": {
267
+ let sortBy = pipeargs[0];
268
+ let sortFactor = 1;
269
+ let sortProps = pipeargs[1];
270
+ if (sortBy && sortBy[0] == "-") {
271
+ sortBy = sortBy.substring(1);
272
+ sortFactor = -1;
273
+ }
274
+ let compareFn = function(a, b) {
275
+ if (sortProps) {
276
+ a = getDataByKey(sortProps, a);
277
+ b = getDataByKey(sortProps, b);
278
+ }
279
+ let ret = 0;
280
+ if (a > b) ret = 1;
281
+ else if (a < b) ret = -1;
282
+ return ret * sortFactor;
283
+ };
284
+ switch (sortBy) {
285
+ case "birthtime": {
286
+ compareFn = function(a, b) {
287
+ if (sortProps) {
288
+ a = getDataByKey(sortProps, a);
289
+ b = getDataByKey(sortProps, b);
290
+ }
291
+ return sortFactor * (fs.statSync(a).birthtimeMs - fs.statSync(b).birthtimeMs);
292
+ };
293
+ break;
294
+ }
295
+ // atime Access Time 访问时间
296
+ // 最后一次访问文件(读取或执行)的时间
297
+ case "atime": {
298
+ compareFn = function(a, b) {
299
+ if (sortProps) {
300
+ a = getDataByKey(sortProps, a);
301
+ b = getDataByKey(sortProps, b);
302
+ }
303
+ return sortFactor * (fs.statSync(a).atimeMs - fs.statSync(b).atimeMs);
304
+ };
305
+ break;
306
+ }
307
+ // ctime Change Time 变化时间
308
+ // 最后一次改变文件(属性或权限)或者目录(属性或权限)的时间
309
+ case "ctime": {
310
+ compareFn = function(a, b) {
311
+ if (sortProps) {
312
+ a = getDataByKey(sortProps, a);
313
+ b = getDataByKey(sortProps, b);
314
+ }
315
+ return sortFactor * (fs.statSync(a).ctimeMs - fs.statSync(b).ctimeMs);
316
+ };
317
+ break;
318
+ }
319
+ // mtime Modify Time 修改时间
320
+ // 最后一次修改文件(内容)或者目录(内容)的时间
321
+ case "mtime": {
322
+ compareFn = function(a, b) {
323
+ if (sortProps) {
324
+ a = getDataByKey(sortProps, a);
325
+ b = getDataByKey(sortProps, b);
326
+ }
327
+ return sortFactor * (fs.statSync(a).mtimeMs - fs.statSync(b).mtimeMs);
328
+ };
329
+ break;
330
+ }
331
+ case "size": {
332
+ compareFn = function(a, b) {
333
+ if (sortProps) {
334
+ a = getDataByKey(sortProps, a);
335
+ b = getDataByKey(sortProps, b);
336
+ }
337
+ return sortFactor * (fs.statSync(a).size - fs.statSync(b).size);
338
+ };
339
+ break;
340
+ }
341
+ case "length": {
342
+ compareFn = function(a, b) {
343
+ if (sortProps) {
344
+ a = getDataByKey(sortProps, a);
345
+ b = getDataByKey(sortProps, b);
346
+ }
347
+ return sortFactor * (a.length - b.length);
348
+ };
349
+ break;
350
+ }
351
+ }
352
+ val = Array.prototype.sort.call(val, compareFn);
353
+ break;
354
+ }
355
+ case "parse": {
356
+ val = parse_sync(val, pipeargs[0]);
357
+ break;
358
+ }
359
+ case "stringify": {
360
+ val = stringify_sync(val, pipeargs[0]);
361
+ break;
362
+ }
363
+ case "convert": {
364
+ val = convert(val, pipeargs[0]);
365
+ break;
366
+ }
367
+ case "def": {
368
+ val = val == null ? pipeargs[0] : val;
369
+ break;
370
+ }
371
+ case "first": {
372
+ val = val?.[0];
373
+ break;
374
+ }
375
+ case "last": {
376
+ val = val?.[val?.length - 1];
377
+ break;
378
+ }
379
+ case "property": {
380
+ for (let property of pipeargs) {
381
+ val = val?.[property];
382
+ }
383
+ break;
384
+ }
385
+ case "now_date": {
386
+ val = new Date();
387
+ break;
388
+ }
389
+ case "now_timestamp": {
390
+ val = Date.now();
391
+ break;
392
+ }
393
+ case "format": {
394
+ val = formatData(val);
395
+ break;
396
+ }
397
+ case "format_date": {
398
+ val = formatDate(val, pipeargs?.[0]);
399
+ break;
400
+ }
401
+ case "format_timestamp": {
402
+ val = formatTimestampMillisec(val, pipeargs?.[0]);
403
+ break;
404
+ }
405
+ case "format_time": {
406
+ val = formatTimeInMillisec(val, pipeargs?.[0]);
407
+ break;
408
+ }
409
+ case "sequence": {
410
+ switch(pipeargs?.[0]) {
411
+ case "date": {
412
+ let date = new Date(val);
413
+ let dateTime = date.getTime();
414
+ val = [];
415
+ const repeat = pipeargs?.[1] || 1;
416
+ let step = (pipeargs?.[2] || 1);
417
+ let fmt = (pipeargs?.[3] || "YYYY-MM-DD");
418
+ for (let i = 0; i < repeat * step; i += step) {
419
+ date.setTime(dateTime + i * 24 * 3600 * 1000);
420
+ val.push(formatDate(date, fmt));
421
+ }
422
+ break;
423
+ }
424
+ case "number": {
425
+ let beg = val;
426
+ val = [];
427
+ const repeat = pipeargs?.[1] || 1;
428
+ let step = (pipeargs?.[2] || 1);
429
+ for (let i = 0; i < repeat * step; i += step) {
430
+ val.push(beg + i);
431
+ }
432
+ break;
433
+ }
434
+ default: {
435
+ break;
436
+ }
437
+ }
438
+ break;
439
+ }
440
+ case "value2key": {
441
+ let tmp = {};
442
+ for (let k in val) {
443
+ tmp[val[k]] = k;
444
+ }
445
+ val = tmp;
446
+ break;
447
+ }
448
+ case "step": {
449
+ let interval = pipeargs[0];
450
+ let offset = pipeargs[1] || 0;
451
+ val = ((val / interval << 0) + offset) * interval;
452
+ break;
453
+ }
454
+ case "merge": {
455
+ let k_primary = pipeargs[0];
456
+ let k_calculate = pipeargs[1];
457
+ let filter_zero = pipeargs[2];
458
+ let resolved = {};
459
+ let result = [];
460
+ for (let v of val) {
461
+ v[k_calculate] = +v[k_calculate];
462
+ let v_primary = v[k_primary];
463
+ if (resolved[v_primary]) {
464
+ resolved[v_primary][k_calculate] += v[k_calculate];
465
+ } else {
466
+ resolved[v_primary] = { [k_primary]: v_primary, [k_calculate]: v[k_calculate] };
467
+ result.push(resolved[v_primary]);
468
+ }
469
+ }
470
+ if (filter_zero) {
471
+ result = result.filter(v => v[k_calculate]);
472
+ }
473
+ val = result;
474
+ break;
475
+ }
476
+ case "child": {
477
+ val = getDataByKey(pipeargs[0], val);
478
+ break;
479
+ }
480
+ case "retrieve": {
481
+ val = getDataByKey(val);
482
+ break;
483
+ }
484
+ case "common_dirname": {
485
+ let dir = null;
486
+ for (let file of val) {
487
+ const tmp = path.dirname(file);
488
+ if (dir == null || dir.length > tmp.length) {
489
+ dir = tmp;
490
+ }
491
+ }
492
+ val = dir;
493
+ break;
494
+ }
495
+ case "slice": {
496
+ val = val.slice(pipeargs[0], pipeargs[1]);
497
+ break;
498
+ }
499
+ case "reverse": {
500
+ val = val.map((v, i, arr) => arr[arr.length - 1 - i]);
501
+ break;
502
+ }
503
+ case "map": {
504
+ val = val.map(v => v[pipeargs[0]]);
505
+ break;
506
+ }
507
+ case "size": {
508
+ if (!val) {
509
+ val = 0;
510
+ } else {
511
+ if (val instanceof Array || typeof val === "string") {
512
+ val = val.length;
513
+ } else {
514
+ val = Object.getOwnPropertyNames(val).length;
515
+ }
516
+ }
517
+ break;
518
+ }
519
+ default: {
520
+ if (val instanceof Array) {
521
+ val = val.map( v => processPipe(v, pipename, pipeargs));
522
+ } else {
523
+ switch(pipename) {
524
+ case "path": {
525
+ val = get_full_path(val);
526
+ break;
527
+ }
528
+ case 'basename': {
529
+ val = path.basename(val);
530
+ break;
531
+ }
532
+ case 'extname': {
533
+ val = path.extname(val);
534
+ break;
535
+ }
536
+ case 'basename_noext': {
537
+ val = path.basename(val, path.extname(val));
538
+ break;
539
+ }
540
+ case 'dirname': {
541
+ val = path.dirname(val);
542
+ break;
543
+ }
544
+ case 'relative': {
545
+ val = path.relative(pipeargs[0], val);
546
+ break;
547
+ }
548
+ case 'path_style': {
549
+ switch(pipeargs[0]) {
550
+ case "windows": {
551
+ val = val.replace(/\//g, "\\");
552
+ break;
553
+ }
554
+ case "linux":
555
+ default: {
556
+ val = val.replace(/\\/g, "/");
557
+ break;
558
+ }
559
+ }
560
+ break;
561
+ }
562
+ case "eval": {
563
+ val = eval_code(val);
564
+ break;
565
+ }
566
+ case "trim": {
567
+ val = val.trim();
568
+ break;
569
+ }
570
+ case "host": {
571
+ try {
572
+ val = new URL(val).host;
573
+ } catch(err) {
574
+ val = "";
575
+ }
576
+ break;
577
+ }
578
+ case "hostname": {
579
+ try {
580
+ val = new URL(val).hostname;
581
+ } catch(err) {
582
+ val = "";
583
+ }
584
+ break;
585
+ }
586
+ case "protocol": {
587
+ try {
588
+ val = new URL(val).protocol;
589
+ } catch(err) {
590
+ val = "";
591
+ }
592
+ break;
593
+ }
594
+ case "port": {
595
+ try {
596
+ val = new URL(val).port;
597
+ } catch(err) {
598
+ val = "";
599
+ }
600
+ break;
601
+ }
602
+ case "pathname": {
603
+ try {
604
+ val = new URL(val).pathname;
605
+ } catch(err) {
606
+ val = "";
607
+ }
608
+ break;
609
+ }
610
+ case "query": {
611
+ try {
612
+ val = new URL(val).search;
613
+ } catch(err) {
614
+ val = "";
615
+ }
616
+ break;
617
+ }
618
+ case "decolor": {
619
+ val = val.replace(/\[\d+m/g, "");
620
+ break;
621
+ }
622
+ case "mkdir": {
623
+ if (!fs.existsSync(val)) {
624
+ fs.mkdirSync(val, {
625
+ recursive: true
626
+ });
627
+ }
628
+ break;
629
+ }
630
+ case "case": {
631
+ val = require('change-case')[`${pipeargs[0]}Case`](val);
632
+ break;
633
+ }
634
+ case "calc": {
635
+ switch(pipeargs[0]) {
636
+ case "+": {
637
+ val += pipeargs[1];
638
+ break;
639
+ }
640
+ case "-": {
641
+ val -= pipeargs[1];
642
+ break;
643
+ }
644
+ case "*": {
645
+ val *= pipeargs[1];
646
+ break;
647
+ }
648
+ case "/": {
649
+ val /= pipeargs[1];
650
+ break;
651
+ }
652
+ case "%": {
653
+ val %= pipeargs[1];
654
+ break;
655
+ }
656
+ case "**": {
657
+ val **= pipeargs[1];
658
+ break;
659
+ }
660
+ }
661
+ break;
662
+ }
663
+ case "buffer": {
664
+ val = Buffer.from(val);
665
+ break;
666
+ }
667
+ case "btoa": {
668
+ val = btoa(val);
669
+ break;
670
+ }
671
+ case "atob": {
672
+ val = atob(val);
673
+ break;
674
+ }
675
+ case "increase": {
676
+ let offset = pipeargs[0] || 1;
677
+ if (typeof val === "string") {
678
+ let index = pipeargs[1] || 0;
679
+ if (index < 0) {
680
+ let total = (val.match(/\D+/g)?.length || 0) + 1;
681
+ index += total;
682
+ }
683
+ let pos = index + 1;
684
+ let cur = 0;
685
+ val = val.replace(/\d+/g, (substring) => {
686
+ cur++;
687
+ if (cur === pos) {
688
+ return +substring + offset;
689
+ } else {
690
+ return substring;
691
+ }
692
+ });
693
+ } else {
694
+ val = +val + offset;
695
+ }
696
+ break;
697
+ }
698
+ case "hash": {
699
+ val = hash(val, pipeargs[0], pipeargs[1]);
700
+ break;
701
+ }
702
+ default: {
703
+ throw `Unkown pipe "${pipename}"`;
704
+ break;
705
+ }
706
+ break;
707
+ }
708
+ }
709
+ }
710
+ }
711
+ return val;
712
+ }
713
+
714
+ function processPipes(val, exp) {
715
+ const filters = parseDirective(exp);
716
+ for (let i = 0, len = filters.length; i < len; ++i) {
717
+ let filter = filters[i];
718
+ val = processPipe(val, filter.name, filter.args.map(arg => arg.dynamic ? getDynamicVal(arg.value) : arg.value));
719
+ }
720
+ return val;
721
+ }
722
+
723
+ let dynamicMap = {
724
+ "true": true,
725
+ "false": false,
726
+ };
727
+ function getDynamicVal(val) {
728
+ let mapped = dynamicMap[val];
729
+ if (mapped !== undefined) return mapped;
730
+ return getDataByKey(val);
731
+ }
732
+
733
+ module.exports = {
734
+ shareData,
735
+ stdout_columns: process.stdout.columns || 500,
736
+ clear_line: '\x1B[2K',
737
+ clear_line_end: "\x1B[0K",
738
+ clear_screen: "\x1B[2J",
739
+ OPTION_PAGE_SIZE: 5,
740
+ LINE_EXPRESSION,
741
+ formatData,
742
+ getDataByKey,
743
+ get_full_path,
744
+ eval_code,
745
+ };