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,228 @@
1
+ const {
2
+ clear_line,
3
+ clear_line_end,
4
+ OPTION_PAGE_SIZE,
5
+ shareData,
6
+ LINE_EXPRESSION
7
+ } = require("../commands/share_data");
8
+ const {
9
+ whisper,
10
+ warn,
11
+ info,
12
+ log,
13
+ omit,
14
+ omit_offset,
15
+ write
16
+ } = require("./log_tool");
17
+ const {
18
+ alignStr,
19
+ alignNumber,
20
+ Alignment
21
+ } = require("./transform_tool");
22
+
23
+ function moveCursorLineUp(n) {
24
+ write(`\x1B[${n}A\r`);
25
+ }
26
+
27
+ function clearLine() {
28
+ if (shareData.FULL_AUTOMATIC) {
29
+ return;
30
+ }
31
+ // write(clear_line);
32
+ process.stdout.clearLine(0);
33
+ }
34
+
35
+ function toggleRawMode(flag) {
36
+ if (shareData.FULL_AUTOMATIC) {
37
+ return;
38
+ }
39
+ if (typeof process.stdin.setRawMode == 'function') {
40
+ process.stdin.setRawMode(flag);
41
+ } else {
42
+ if (typeof tty == "object") {
43
+ tty.setRawMode(flag);
44
+ }
45
+ }
46
+ }
47
+
48
+ /**
49
+ *
50
+ * @param {*} prompt
51
+ * @param {number} countdown 自动倒计时(秒数)
52
+ */
53
+ async function pause(prompt = "", countdown) {
54
+ if (shareData.FULL_AUTOMATIC) {
55
+ return;
56
+ }
57
+ let needCountDown = countdown > 0;
58
+ let leftTime = countdown;
59
+ log("");
60
+ if (needCountDown) {
61
+ warn(`${prompt} ... [回车键继续 ${leftTime}s] `);
62
+ } else {
63
+ warn(`${prompt} ... [回车键继续] `);
64
+ }
65
+ await new Promise(resolve => {
66
+ process.stdin.on('keypress', onKeyPress);
67
+ toggleRawMode(true);
68
+ process.stdin.resume();
69
+ function onKeyPress(ch, key) {
70
+ let isKey = false;
71
+ let inputsChg = false;
72
+ if (key) {
73
+ if (key.name == "return") {
74
+ moveCursorLineUp(1);
75
+ willResolve();
76
+ } else if (key.ctrl && key.name == "c") {
77
+ throw "用户中止";
78
+ return;
79
+ } else {
80
+ clearInterval(timeout);
81
+ moveCursorLineUp(1);
82
+ warn(`${prompt} ... [回车键继续] ${clear_line_end}`);
83
+ }
84
+ }
85
+ };
86
+ let timeout = 0;
87
+ if (needCountDown) {
88
+ timeout = setInterval(() => {
89
+ leftTime -= 1;
90
+ moveCursorLineUp(1);
91
+ warn(`${prompt} ... [回车键继续 ${leftTime}s] `);
92
+ if (leftTime <= 0) {
93
+ willResolve();
94
+ }
95
+ }, 1000);
96
+ }
97
+
98
+ function willResolve() {
99
+ clearInterval(timeout);
100
+ process.stdin.off("keypress", onKeyPress);
101
+ process.stdin.pause();
102
+ resolve();
103
+ }
104
+ });
105
+ }
106
+
107
+
108
+ /** 记录上一个显示的选项 */
109
+ let prevViewOptions = null;
110
+ let prevBegIndex = 0;
111
+ let prevFocusIndex = 0;
112
+ let firstTime = true;
113
+
114
+ function resetOptions() {
115
+ prevViewOptions = null;
116
+ prevBegIndex = 0;
117
+ prevFocusIndex = 0;
118
+ firstTime = true;
119
+ }
120
+
121
+ /**
122
+ *
123
+ * @param {{key: string, value: any}[]} viewOptions
124
+ * @param {{key: string, value: any}[]} filteredViewOptions
125
+ * @param {*} selectedIndices
126
+ * @param {number} focusedIndex
127
+ * @param {number} numPerPage
128
+ */
129
+ function showOptions(viewOptions, filteredViewOptions, selectedIndices, focusedIndex = -1, numPerPage = OPTION_PAGE_SIZE, indicator_char = ">", searchChars = "") {
130
+ const selectColor = "green"; // 选中颜色
131
+ const focusColor = "gray"; // 焦点颜色
132
+ const filterColor = "reset"; // 筛选颜色
133
+ const defaultColor = "gray"; // 默认颜色
134
+ let begIndex = 0;
135
+ let numShow = Math.min(filteredViewOptions.length, numPerPage > 0 ? numPerPage : filteredViewOptions.length);
136
+ // 转换成filterdView
137
+ focusedIndex = filteredViewOptions.indexOf(viewOptions[focusedIndex]);
138
+ if (typeof selectedIndices === "number") {
139
+ selectedIndices = filteredViewOptions.indexOf(viewOptions[selectedIndices]);
140
+ } else {
141
+ selectedIndices = selectedIndices.concat().map(v => filteredViewOptions.indexOf(viewOptions[v]));
142
+ }
143
+ if (prevViewOptions && prevViewOptions.every((v, i) => v == filteredViewOptions[i])) {
144
+ prevViewOptions = filteredViewOptions;
145
+ begIndex = prevBegIndex = 0;
146
+ prevFocusIndex = 0;
147
+ } else {
148
+ let focusOffset = focusedIndex - prevFocusIndex;
149
+ let isPageDown = focusOffset >= numPerPage;
150
+ let isPageUp = focusOffset <= -numPerPage;
151
+ if (isPageDown) {
152
+ begIndex = Math.min(focusedIndex, filteredViewOptions.length - numShow);
153
+ } else if (isPageUp) {
154
+ begIndex = Math.max(0, focusedIndex - numPerPage);
155
+ } else {
156
+ begIndex = prevBegIndex;
157
+ }
158
+ if (firstTime) {
159
+ firstTime = false;
160
+ } else {
161
+ moveCursorLineUp(numPerPage + 4);
162
+ }
163
+ }
164
+ // 需要对begIndex进行限制
165
+ if (focusedIndex != -1) {
166
+ // 超出单页显示,要修正
167
+ if (focusedIndex < begIndex) {
168
+ begIndex = focusedIndex;
169
+ } else if (focusedIndex >= begIndex + numShow) {
170
+ begIndex = Math.min(filteredViewOptions.length - numShow, focusedIndex - numShow + 1);
171
+ }
172
+ }
173
+ prevBegIndex = begIndex;
174
+ prevFocusIndex = focusedIndex;
175
+ let alignment = Alignment.RIGHT;
176
+ let maxKeyLength = filteredViewOptions.reduce((prev, current) => {
177
+ if (alignment == Alignment.RIGHT && Number.isNaN(parseInt(current.key))) {
178
+ alignment = Alignment.LEFT;
179
+ }
180
+ return Math.max(prev, current.key.toString().length);
181
+ }, 0);
182
+ clearLine();
183
+ info(`当前选择: ${typeof selectedIndices === "number" ? (selectedIndices == -1 ? 0 : 1) : selectedIndices.length} / ${filteredViewOptions.length}`);
184
+ write(`${begIndex == 0 ? "" : "▲"['magenta'] }${clear_line_end}\n`);
185
+ for (let i = 0; i < numPerPage; ++i) {
186
+ // for (let index = begIndex; index < begIndex + numShow; index++) {
187
+ let index = begIndex + i;
188
+ let viewOption = filteredViewOptions[index];
189
+ if (viewOption == undefined) {
190
+ write(clear_line_end + "\n");
191
+ continue;
192
+ }
193
+ let viewOptionStr = `${alignStr(viewOption.key, maxKeyLength, {alignment: alignment})} - ${viewOption.value?.toString().replace(new RegExp(LINE_EXPRESSION, "g"), "")}`;
194
+ let indicator;
195
+ let optionColor;
196
+ let selected = selectedIndices === index || selectedIndices instanceof Array && selectedIndices.includes(index);
197
+ let focused = focusedIndex === index;
198
+ let filtered = filteredViewOptions && filteredViewOptions.length != filteredViewOptions.length && filteredViewOptions.includes(viewOption);
199
+ indicator = focused ? `${indicator_char} ` [selectColor] : " ";
200
+ if (selected) {
201
+ optionColor = selectColor;
202
+ } else if (filtered) {
203
+ optionColor = filterColor;
204
+ } else if (focused) {
205
+ optionColor = focusColor;
206
+ } else {
207
+ optionColor = defaultColor;
208
+ }
209
+ // 清空本行
210
+ clearLine();
211
+ let preview = omit_offset(viewOptionStr, 2);
212
+ if (searchChars) {
213
+ preview = preview.replaceAll(searchChars, searchChars["red"]);
214
+ }
215
+ write(`${indicator}${preview[optionColor]}`);
216
+ write('\n');
217
+ }
218
+ write(`${begIndex + numShow >= filteredViewOptions.length ? "" : "▼"['magenta'] }${clear_line_end}\n`);
219
+ }
220
+
221
+ module.exports = {
222
+ moveCursorLineUp,
223
+ toggleRawMode,
224
+ pause,
225
+ showOptions,
226
+ resetOptions,
227
+ clearLine,
228
+ };
@@ -0,0 +1,190 @@
1
+ const { stdout_columns } = require("../commands/share_data");
2
+ const { json_compacted, formatTimestampMillisec } = require('./transform_tool');
3
+
4
+ const colors = [
5
+ "gray",
6
+ "reset",
7
+ "cyan",
8
+ "green",
9
+ "yellow",
10
+ "red",
11
+ "red",
12
+ "magenta",
13
+ ];
14
+
15
+ const LogLevel = {
16
+ NONE: -1,
17
+ WHISPER: 0,
18
+ DEBUG: 1,
19
+ INFO: 2,
20
+ SUCCESS: 3,
21
+ WARNING: 4,
22
+ ERROR: 5,
23
+ VITAL: 6,
24
+ SYSTEM: 7,
25
+ STDOUT: 99,
26
+ };
27
+
28
+ function log(msg, end = "\n", level = -1, force = true, with_date = false) {
29
+ if (!checkStdOut(level)) {
30
+ return;
31
+ }
32
+ if (logLevel > level && !force) {
33
+ return;
34
+ }
35
+ if (typeof msg === "object" && !msg) {
36
+ msg = "<空>";
37
+ level = LogLevel.SYSTEM;
38
+ }
39
+ if (with_date) {
40
+ msg = `[${formatTimestampMillisec(Date.now())}] ` + msg;
41
+ }
42
+ // clearLine();
43
+ let color = colors[level];
44
+ if (color) {
45
+ process.stdout.write(msg.toString()[color] + end);
46
+ } else {
47
+ process.stdout.write(msg.toString() + end);
48
+ }
49
+ }
50
+
51
+ function log2(msg, end = "\n", level = -1, with_date = false) {
52
+ if (typeof msg === "object" && !msg) {
53
+ msg = "<空>";
54
+ level = LogLevel.SYSTEM;
55
+ }
56
+ if (with_date) {
57
+ msg = `[${formatTimestampMillisec(Date.now())}] ` + msg;
58
+ }
59
+ // clearLine();
60
+ let color = colors[level];
61
+ if (color) {
62
+ process.stdout.write(msg.toString()[color] + end);
63
+ } else {
64
+ process.stdout.write(msg.toString() + end);
65
+ }
66
+ }
67
+
68
+ function write(msg) {
69
+ log(msg.toString(), "", -1, true);
70
+ }
71
+
72
+ function debug(msg, end = "\n", force = false, with_date = false) {
73
+ log(msg.toString(), end, LogLevel.DEBUG, force, with_date);
74
+ }
75
+
76
+ function info(msg, end = "\n", force = false, with_date = false) {
77
+ log(msg.toString(), end, LogLevel.INFO, force, with_date);
78
+ }
79
+
80
+ function success(msg, end = "\n", force = false, with_date = false) {
81
+ log(msg.toString(), end, LogLevel.SUCCESS, force, with_date);
82
+ }
83
+
84
+ function warn(msg, end = "\n", force = false, with_date = false) {
85
+ log(msg.toString(), end, LogLevel.WARNING, force, with_date);
86
+ }
87
+
88
+ function error(msg, end = "\n", force = false) {
89
+ log(msg.toString(), end, LogLevel.ERROR, force);
90
+ }
91
+
92
+ function error2(msg, end = "\n") {
93
+ log2(msg.toString(), end, LogLevel.ERROR);
94
+ }
95
+
96
+ function whisper(msg, end = "\n", force = false, with_date = false) {
97
+ log(msg.toString(), end, LogLevel.WHISPER, force, with_date);
98
+ }
99
+
100
+ function stdout(msg) {
101
+ process.stdout.write(msg.toString());
102
+ }
103
+
104
+ function omit(msg, max_num = stdout_columns - 5, prefix_num = stdout_columns - 5, suffix_num = 0, omit_chars = " ... ") {
105
+ if (msg && msg.length > max_num) {
106
+ return `${msg.substr(0, prefix_num)}${omit_chars}${msg.substr(msg.length - suffix_num)}`;
107
+ } else {
108
+ return msg;
109
+ }
110
+ }
111
+
112
+ function omit_offset(msg, offset) {
113
+ return omit(msg, stdout_columns - offset - 5, stdout_columns - offset - 5, 0, " ... ");
114
+ }
115
+
116
+ function getPrint(value, no_omit = false) {
117
+ if (value instanceof Array) {
118
+ return `Array[${value.length}]` + (!no_omit ? omit(json_compacted(value, 2)) : json_compacted(value, 2));
119
+ } else {
120
+ value = typeof value == "string" ? `"${value}"` : json_compacted(value, 2);
121
+ return !no_omit ? omit(value) : value;
122
+ }
123
+ }
124
+
125
+
126
+ let lastError = null;
127
+ let lastErrorCode = 0;
128
+
129
+ let logLevel = 0;
130
+
131
+ function getLastError() {
132
+ return lastError;
133
+ }
134
+
135
+ function getLastErrorCode() {
136
+ return lastErrorCode;
137
+ }
138
+
139
+ function setLastError(err, code) {
140
+ lastError = err;
141
+ lastErrorCode = code;
142
+ }
143
+
144
+ function resetError(extraError) {
145
+ if (lastError) {
146
+ if (typeof extraError == "string") {
147
+ error(`${lastError} [${extraError}]`);
148
+ } else {
149
+ error(`${lastError}`);
150
+ }
151
+ }
152
+ lastError = null;
153
+ lastErrorCode = null;
154
+ }
155
+
156
+ function setLogLevel(level) {
157
+ logLevel = level;
158
+ }
159
+
160
+ function isStdOut() {
161
+ return logLevel == LogLevel.STDOUT;
162
+ }
163
+
164
+ function checkStdOut(level) {
165
+ return logLevel != LogLevel.STDOUT || logLevel == level;
166
+ }
167
+
168
+ module.exports = {
169
+ getLastError,
170
+ getLastErrorCode,
171
+ setLastError,
172
+ resetError,
173
+ omit,
174
+ log,
175
+ debug,
176
+ info,
177
+ warn,
178
+ error,
179
+ error2,
180
+ whisper,
181
+ stdout,
182
+ getPrint,
183
+ success,
184
+ isStdOut,
185
+ checkStdOut,
186
+ write,
187
+ omit_offset,
188
+ setLogLevel,
189
+ LogLevel,
190
+ };
@@ -0,0 +1,194 @@
1
+ /**
2
+ *
3
+ * @param {*} str
4
+ * @returns {Array<{
5
+ * name: string,
6
+ * args: Array<{
7
+ * value: string | number,
8
+ * dynamic: boolean,
9
+ * }>,
10
+ * }>}}
11
+ */
12
+ function parseDirective(str) {
13
+
14
+ function curr() {
15
+ return str.charCodeAt(index);
16
+ }
17
+
18
+ function next() {
19
+ return str.charCodeAt(++index);
20
+ }
21
+
22
+ function eof() {
23
+ return index >= len;
24
+ }
25
+
26
+
27
+ function eatSpace() {
28
+ while (curr() === spaceChar) {
29
+ next();
30
+ }
31
+ }
32
+
33
+ function parseString() {
34
+ var stringQuote = curr();
35
+ var chr;
36
+ while (!eof()) {
37
+ chr = next();
38
+ // escape char
39
+ if (chr === escapeChr) {
40
+ next();
41
+ } else if (chr === stringQuote) {
42
+ break;
43
+ }
44
+ }
45
+ next();
46
+ }
47
+
48
+
49
+ var reservedArgRE = /^in$|^-?\d+/;
50
+ /**
51
+ * Check and convert possible numeric strings to numbers
52
+ * before setting back to data
53
+ *
54
+ * @param {*} value
55
+ * @return {*|Number}
56
+ */
57
+
58
+ function toNumber(value) {
59
+ if (typeof value !== 'string') {
60
+ return value;
61
+ } else {
62
+ var parsed = Number(value);
63
+ return isNaN(parsed) ? value : parsed;
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Strip quotes from a string
69
+ *
70
+ * @param {String} str
71
+ * @return {String | false}
72
+ */
73
+
74
+ function stripQuotes(str) {
75
+ var a = str.charCodeAt(0);
76
+ var b = str.charCodeAt(str.length - 1);
77
+ return a === b && (a === 0x22 || a === 0x27) ? str.slice(1, -1) : str;
78
+ }
79
+ /**
80
+ * Check if an argument is dynamic and strip quotes.
81
+ *
82
+ * @param {String} arg
83
+ * @return {Object}
84
+ */
85
+
86
+ function processFilterArg(arg) {
87
+ if (reservedArgRE.test(arg)) {
88
+ return {
89
+ value: toNumber(arg),
90
+ dynamic: false
91
+ };
92
+ } else {
93
+ var stripped = stripQuotes(arg);
94
+ var dynamic = stripped === arg;
95
+ value = unescapeString(stripped);
96
+ return {
97
+ value: value,
98
+ dynamic: dynamic
99
+ };
100
+ }
101
+ }
102
+
103
+
104
+ function unescapeString(str) {
105
+ return str
106
+ .replace(/\\\\/g, '\\')
107
+ .replace(/\\\"/g, '"')
108
+ ;
109
+ };
110
+
111
+ function pushFilterArg() {
112
+ filters[filters.length - 1].args.push(processFilterArg(str.substring(start, index)));
113
+ }
114
+
115
+ function pushFilterName() {
116
+ filters.push({
117
+ name: str.substring(start, index),
118
+ args: [],
119
+ });
120
+ }
121
+
122
+
123
+ let index = 0, len = str.length;
124
+ let spaceChar = " ".charCodeAt(0);
125
+ let pipeChar = "|".charCodeAt(0);
126
+ let doubleQuoteChar = '"'.charCodeAt(0);
127
+ let singleQuoteChar = "'".charCodeAt(0);
128
+ var escapeChr = 0x5C;
129
+ let commaChar = ",".charCodeAt(0);
130
+ let parenthesisBeg = "(".charCodeAt(0);
131
+ let parenthesisEnd = ")".charCodeAt(0);
132
+ let filters = [];
133
+ const FILTER_NAME = 1;
134
+ const FILTER_ARGS = 2;
135
+ let state = FILTER_NAME;
136
+ var start = 0;
137
+ while (!eof()) {
138
+ let char = curr();
139
+ if (state === FILTER_NAME) {
140
+ if (char === pipeChar || char === spaceChar) {
141
+ if (start !== index) {
142
+ pushFilterName();
143
+ }
144
+ next();
145
+ eatSpace();
146
+ start = index;
147
+ } else if (char === parenthesisBeg) {
148
+ if (start !== index) {
149
+ pushFilterName();
150
+ }
151
+ next();
152
+ eatSpace();
153
+ start = index;
154
+ state = FILTER_ARGS;
155
+ } else {
156
+ next();
157
+ }
158
+ } else if (state === FILTER_ARGS) {
159
+ if (char === pipeChar || char === spaceChar || char === commaChar) {
160
+ if (start !== index) {
161
+ pushFilterArg();
162
+ }
163
+ next();
164
+ eatSpace();
165
+ start = index;
166
+ } else if (char === doubleQuoteChar || char === singleQuoteChar) {
167
+ parseString();
168
+ pushFilterArg();
169
+ eatSpace();
170
+ start = index;
171
+ } else if (char === parenthesisEnd) {
172
+ if (start !== index) {
173
+ pushFilterArg();
174
+ }
175
+ next();
176
+ eatSpace();
177
+ start = index;
178
+ state = FILTER_NAME;
179
+ } else {
180
+ next();
181
+ }
182
+ } else {
183
+ next();
184
+ }
185
+ }
186
+ if (start !== index) {
187
+ pushFilterName();
188
+ }
189
+ return filters;
190
+ }
191
+
192
+ module.exports = {
193
+ parseDirective,
194
+ };