hola-server 2.0.1 → 3.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 (242) hide show
  1. package/README.md +318 -132
  2. package/dist/config/index.d.ts +46 -0
  3. package/dist/config/index.d.ts.map +1 -0
  4. package/dist/config/index.js +55 -0
  5. package/dist/config/index.js.map +1 -0
  6. package/dist/core/array.d.ts +27 -0
  7. package/dist/core/array.d.ts.map +1 -0
  8. package/dist/core/array.js +66 -0
  9. package/dist/core/array.js.map +1 -0
  10. package/dist/core/bash.d.ts +51 -0
  11. package/dist/core/bash.d.ts.map +1 -0
  12. package/dist/core/bash.js +161 -0
  13. package/dist/core/bash.js.map +1 -0
  14. package/dist/core/chart.d.ts +11 -0
  15. package/dist/core/chart.d.ts.map +1 -0
  16. package/dist/core/chart.js +35 -0
  17. package/dist/core/chart.js.map +1 -0
  18. package/dist/core/date.d.ts +11 -0
  19. package/dist/core/date.d.ts.map +1 -0
  20. package/dist/core/date.js +18 -0
  21. package/dist/core/date.js.map +1 -0
  22. package/dist/core/encrypt.d.ts +18 -0
  23. package/dist/core/encrypt.d.ts.map +1 -0
  24. package/dist/core/encrypt.js +50 -0
  25. package/dist/core/encrypt.js.map +1 -0
  26. package/dist/core/file.d.ts +22 -0
  27. package/dist/core/file.d.ts.map +1 -0
  28. package/dist/core/file.js +21 -0
  29. package/dist/core/file.js.map +1 -0
  30. package/dist/core/lhs.d.ts +17 -0
  31. package/dist/core/lhs.d.ts.map +1 -0
  32. package/dist/core/lhs.js +30 -0
  33. package/dist/core/lhs.js.map +1 -0
  34. package/dist/core/meta.d.ts +200 -0
  35. package/dist/core/meta.d.ts.map +1 -0
  36. package/dist/core/meta.js +336 -0
  37. package/dist/core/meta.js.map +1 -0
  38. package/dist/core/number.d.ts +37 -0
  39. package/dist/core/number.d.ts.map +1 -0
  40. package/dist/core/number.js +99 -0
  41. package/dist/core/number.js.map +1 -0
  42. package/dist/core/obj.d.ts +9 -0
  43. package/dist/core/obj.d.ts.map +1 -0
  44. package/dist/core/obj.js +15 -0
  45. package/dist/core/obj.js.map +1 -0
  46. package/dist/core/random.d.ts +7 -0
  47. package/dist/core/random.d.ts.map +1 -0
  48. package/dist/core/random.js +7 -0
  49. package/dist/core/random.js.map +1 -0
  50. package/dist/core/role.d.ts +42 -0
  51. package/dist/core/role.d.ts.map +1 -0
  52. package/dist/core/role.js +81 -0
  53. package/dist/core/role.js.map +1 -0
  54. package/dist/core/thread.d.ts +7 -0
  55. package/dist/core/thread.d.ts.map +1 -0
  56. package/dist/core/thread.js +7 -0
  57. package/dist/core/thread.js.map +1 -0
  58. package/dist/core/type.d.ts +46 -0
  59. package/dist/core/type.d.ts.map +1 -0
  60. package/dist/core/type.js +281 -0
  61. package/dist/core/type.js.map +1 -0
  62. package/dist/core/url.d.ts +20 -0
  63. package/dist/core/url.d.ts.map +1 -0
  64. package/dist/core/url.js +24 -0
  65. package/dist/core/url.js.map +1 -0
  66. package/dist/core/validate.d.ts +11 -0
  67. package/dist/core/validate.d.ts.map +1 -0
  68. package/dist/core/validate.js +19 -0
  69. package/dist/core/validate.js.map +1 -0
  70. package/dist/db/db.d.ts +72 -0
  71. package/dist/db/db.d.ts.map +1 -0
  72. package/dist/db/db.js +225 -0
  73. package/dist/db/db.js.map +1 -0
  74. package/dist/db/entity.d.ts +77 -0
  75. package/dist/db/entity.d.ts.map +1 -0
  76. package/dist/db/entity.js +671 -0
  77. package/dist/db/entity.js.map +1 -0
  78. package/dist/db/gridfs.d.ts +29 -0
  79. package/dist/db/gridfs.d.ts.map +1 -0
  80. package/dist/db/gridfs.js +125 -0
  81. package/dist/db/gridfs.js.map +1 -0
  82. package/dist/db/index.d.ts +8 -0
  83. package/dist/db/index.d.ts.map +1 -0
  84. package/dist/db/index.js +8 -0
  85. package/dist/db/index.js.map +1 -0
  86. package/dist/errors/auth.d.ts +15 -0
  87. package/dist/errors/auth.d.ts.map +1 -0
  88. package/dist/errors/auth.js +21 -0
  89. package/dist/errors/auth.js.map +1 -0
  90. package/dist/errors/http.d.ts +15 -0
  91. package/dist/errors/http.d.ts.map +1 -0
  92. package/dist/errors/http.js +21 -0
  93. package/dist/errors/http.js.map +1 -0
  94. package/dist/errors/index.d.ts +18 -0
  95. package/dist/errors/index.d.ts.map +1 -0
  96. package/dist/errors/index.js +18 -0
  97. package/dist/errors/index.js.map +1 -0
  98. package/dist/errors/validation.d.ts +11 -0
  99. package/dist/errors/validation.d.ts.map +1 -0
  100. package/dist/errors/validation.js +15 -0
  101. package/dist/errors/validation.js.map +1 -0
  102. package/dist/http/code.d.ts +21 -0
  103. package/dist/http/code.d.ts.map +1 -0
  104. package/dist/http/code.js +27 -0
  105. package/dist/http/code.js.map +1 -0
  106. package/dist/index.d.ts +57 -0
  107. package/dist/index.d.ts.map +1 -0
  108. package/dist/index.js +61 -0
  109. package/dist/index.js.map +1 -0
  110. package/dist/meta/index.d.ts +9 -0
  111. package/dist/meta/index.d.ts.map +1 -0
  112. package/dist/meta/index.js +11 -0
  113. package/dist/meta/index.js.map +1 -0
  114. package/dist/meta/router.d.ts +26 -0
  115. package/dist/meta/router.d.ts.map +1 -0
  116. package/dist/meta/router.js +258 -0
  117. package/dist/meta/router.js.map +1 -0
  118. package/dist/meta/schema.d.ts +41 -0
  119. package/dist/meta/schema.d.ts.map +1 -0
  120. package/dist/meta/schema.js +69 -0
  121. package/dist/meta/schema.js.map +1 -0
  122. package/dist/plugins/auth.d.ts +248 -0
  123. package/dist/plugins/auth.d.ts.map +1 -0
  124. package/dist/plugins/auth.js +121 -0
  125. package/dist/plugins/auth.js.map +1 -0
  126. package/dist/plugins/body.d.ts +47 -0
  127. package/dist/plugins/body.d.ts.map +1 -0
  128. package/dist/plugins/body.js +36 -0
  129. package/dist/plugins/body.js.map +1 -0
  130. package/dist/plugins/cors.d.ts +62 -0
  131. package/dist/plugins/cors.d.ts.map +1 -0
  132. package/dist/plugins/cors.js +17 -0
  133. package/dist/plugins/cors.js.map +1 -0
  134. package/dist/plugins/error.d.ts +51 -0
  135. package/dist/plugins/error.d.ts.map +1 -0
  136. package/dist/plugins/error.js +51 -0
  137. package/dist/plugins/error.js.map +1 -0
  138. package/dist/plugins/index.d.ts +9 -0
  139. package/dist/plugins/index.d.ts.map +1 -0
  140. package/dist/plugins/index.js +9 -0
  141. package/dist/plugins/index.js.map +1 -0
  142. package/dist/setting.d.ts +66 -0
  143. package/dist/setting.d.ts.map +1 -0
  144. package/dist/setting.js +27 -0
  145. package/dist/setting.js.map +1 -0
  146. package/dist/tool/gen_i18n.d.ts +10 -0
  147. package/dist/tool/gen_i18n.d.ts.map +1 -0
  148. package/{tool → dist/tool}/gen_i18n.js +9 -22
  149. package/dist/tool/gen_i18n.js.map +1 -0
  150. package/dist/tool/vector_store.d.ts +72 -0
  151. package/dist/tool/vector_store.d.ts.map +1 -0
  152. package/dist/tool/vector_store.js +203 -0
  153. package/dist/tool/vector_store.js.map +1 -0
  154. package/package.json +37 -22
  155. package/core/array.js +0 -124
  156. package/core/bash.js +0 -294
  157. package/core/chart.js +0 -46
  158. package/core/cron.js +0 -21
  159. package/core/date.js +0 -26
  160. package/core/encrypt.js +0 -26
  161. package/core/file.js +0 -51
  162. package/core/lhs.js +0 -53
  163. package/core/meta.js +0 -283
  164. package/core/msg.js +0 -24
  165. package/core/number.js +0 -181
  166. package/core/obj.js +0 -25
  167. package/core/random.js +0 -12
  168. package/core/role.js +0 -108
  169. package/core/thread.js +0 -13
  170. package/core/type.js +0 -368
  171. package/core/url.js +0 -30
  172. package/core/validate.js +0 -35
  173. package/db/db.js +0 -446
  174. package/db/entity.js +0 -920
  175. package/db/gridfs.js +0 -175
  176. package/design/add_default_field_attr.md +0 -56
  177. package/http/code.js +0 -18
  178. package/http/context.js +0 -31
  179. package/http/cors.js +0 -32
  180. package/http/error.js +0 -39
  181. package/http/express.js +0 -104
  182. package/http/params.js +0 -85
  183. package/http/router.js +0 -83
  184. package/http/session.js +0 -73
  185. package/index.js +0 -112
  186. package/router/clone.js +0 -65
  187. package/router/create.js +0 -54
  188. package/router/delete.js +0 -49
  189. package/router/read.js +0 -191
  190. package/router/update.js +0 -89
  191. package/setting.js +0 -67
  192. package/skills/array.md +0 -155
  193. package/skills/bash.md +0 -91
  194. package/skills/chart.md +0 -54
  195. package/skills/code.md +0 -422
  196. package/skills/context.md +0 -177
  197. package/skills/date.md +0 -58
  198. package/skills/express.md +0 -255
  199. package/skills/file.md +0 -60
  200. package/skills/lhs.md +0 -54
  201. package/skills/meta.md +0 -1023
  202. package/skills/msg.md +0 -30
  203. package/skills/number.md +0 -88
  204. package/skills/obj.md +0 -36
  205. package/skills/params.md +0 -206
  206. package/skills/random.md +0 -22
  207. package/skills/role.md +0 -59
  208. package/skills/session.md +0 -281
  209. package/skills/storage.md +0 -743
  210. package/skills/thread.md +0 -22
  211. package/skills/type.md +0 -547
  212. package/skills/url.md +0 -34
  213. package/skills/validate.md +0 -48
  214. package/test/cleanup/close-db.js +0 -5
  215. package/test/core/array.js +0 -226
  216. package/test/core/chart.js +0 -51
  217. package/test/core/date.js +0 -37
  218. package/test/core/encrypt.js +0 -14
  219. package/test/core/file.js +0 -59
  220. package/test/core/lhs.js +0 -44
  221. package/test/core/meta.js +0 -594
  222. package/test/core/number.js +0 -172
  223. package/test/core/obj.js +0 -47
  224. package/test/core/random.js +0 -24
  225. package/test/core/thread.js +0 -20
  226. package/test/core/type.js +0 -216
  227. package/test/core/validate.js +0 -67
  228. package/test/db/db-ops.js +0 -99
  229. package/test/db/db.js +0 -72
  230. package/test/db/pipe_test.txt +0 -0
  231. package/test/db/test_case_design.md +0 -528
  232. package/test/db/test_db_class.js +0 -613
  233. package/test/db/test_entity_class.js +0 -414
  234. package/test/db/test_gridfs_class.js +0 -234
  235. package/test/entity/create.js +0 -442
  236. package/test/entity/delete-mixed.js +0 -156
  237. package/test/entity/delete.js +0 -480
  238. package/test/entity/read.js +0 -285
  239. package/test/entity/ref-filter.js +0 -63
  240. package/test/entity/update.js +0 -252
  241. package/test/router/role.js +0 -15
  242. package/tool/test.json +0 -25
package/core/array.js DELETED
@@ -1,124 +0,0 @@
1
- /**
2
- * @fileoverview Array manipulation utility functions.
3
- * @module core/array
4
- */
5
-
6
- const { round_to_fixed2 } = require('./number');
7
-
8
- /**
9
- * Shuffle array elements randomly in place.
10
- * @param {Array} arr - Array to shuffle.
11
- */
12
- const shuffle = (arr) => {
13
- for (let i = arr.length; i; i--) {
14
- const j = Math.floor(Math.random() * i);
15
- [arr[i - 1], arr[j]] = [arr[j], arr[i - 1]];
16
- }
17
- };
18
-
19
- /**
20
- * Remove elements from array by matching field value.
21
- * @param {Object[]} array - Array of objects to modify.
22
- * @param {string} field - Field name to match.
23
- * @param {*} value - Value to match for removal.
24
- */
25
- const remove_element = (array, field, value) => {
26
- for (let i = array.length - 1; i >= 0; --i) {
27
- if (array[i][field] == value) array.splice(i, 1);
28
- }
29
- };
30
-
31
- /**
32
- * Extract n elements from array using specified method.
33
- * @param {Array} array - Source array.
34
- * @param {number} n - Number of elements to extract.
35
- * @param {string} method - 'pop' or 'shift'.
36
- * @returns {Array|undefined} Array of extracted elements or undefined if empty.
37
- */
38
- const extract_n = (array, n, method) => {
39
- const result = [];
40
- while (result.length < n) {
41
- const ele = array[method]();
42
- if (ele) result.push(ele);
43
- else break;
44
- }
45
- return result.length > 0 ? result : undefined;
46
- };
47
-
48
- const pop_n = (array, n) => extract_n(array, n, 'pop');
49
- const shift_n = (array, n) => extract_n(array, n, 'shift');
50
-
51
- /**
52
- * Calculate sum of number array.
53
- * @param {number[]} arr - Array of numbers.
54
- * @returns {number} Sum rounded to 2 decimal places.
55
- */
56
- const sum = (arr) => round_to_fixed2(arr.reduce((pre, cur) => pre + cur, 0));
57
-
58
- /**
59
- * Calculate average of number array.
60
- * @param {number[]} arr - Array of numbers.
61
- * @returns {number} Average rounded to 2 decimal places.
62
- */
63
- const avg = (arr) => arr.length === 0 ? 0 : round_to_fixed2(sum(arr) / arr.length);
64
-
65
- /**
66
- * Convert array of objects to key-value object.
67
- * @param {Object[]} arr - Array of objects.
68
- * @param {string} key_attr - Attribute to use as key.
69
- * @param {string} value_attr - Attribute to use as value.
70
- * @returns {Object} Mapped object.
71
- */
72
- const map_array_to_obj = (arr, key_attr, value_attr) => {
73
- return arr.reduce((obj, el) => ({ ...obj, [el[key_attr]]: el[value_attr] }), {});
74
- };
75
-
76
- /**
77
- * Sort array of objects by attribute.
78
- * @param {Object[]} arr - Array to sort.
79
- * @param {string} attr - Attribute name to sort by.
80
- * @param {boolean} [desc=false] - Sort descending if true.
81
- * @returns {Object[]} Sorted array.
82
- */
83
- const sort_by_attr = (arr, attr, desc = false) => {
84
- arr.sort((a, b) => desc ? b[attr] - a[attr] : a[attr] - b[attr]);
85
- return arr;
86
- };
87
-
88
- const sort_desc = (arr, attr) => sort_by_attr(arr, attr, true);
89
- const sort_asc = (arr, attr) => sort_by_attr(arr, attr, false);
90
-
91
- /**
92
- * Sort array by predefined key sequence.
93
- * @param {Object[]} arr - Array to sort.
94
- * @param {string} attr - Attribute name to sort by.
95
- * @param {Array} keys - Ordered array of key values.
96
- * @returns {Object[]} Sorted array.
97
- */
98
- const sort_by_key_seq = (arr, attr, keys) => {
99
- arr.sort((a, b) => keys.indexOf(a[attr]) - keys.indexOf(b[attr]));
100
- return arr;
101
- };
102
-
103
- /**
104
- * Create cartesian product of two object arrays.
105
- * @param {Object[]} arr1 - First array.
106
- * @param {Object[]} arr2 - Second array.
107
- * @returns {Object[]} Combined array with length arr1.length * arr2.length.
108
- */
109
- const combine = (arr1, arr2) => arr1.flatMap(obj1 => arr2.map(obj2 => ({ ...obj1, ...obj2 })));
110
-
111
- /**
112
- * Remove duplicate elements from array.
113
- * @param {Array} array - Array to deduplicate.
114
- * @returns {Array} Array with unique elements.
115
- */
116
- const unique = (array) => {
117
- const seen = new Map();
118
- return array.filter(value => {
119
- const key = JSON.stringify(value);
120
- return seen.has(key) ? false : (seen.set(key, true), true);
121
- });
122
- };
123
-
124
- module.exports = { shuffle, remove_element, pop_n, shift_n, sum, avg, combine, sort_desc, sort_asc, sort_by_key_seq, unique, map_array_to_obj };
package/core/bash.js DELETED
@@ -1,294 +0,0 @@
1
- /**
2
- * @fileoverview Bash command execution and SSH utility functions.
3
- * @module core/bash
4
- */
5
-
6
- const fs = require('fs');
7
- const { exec } = require("child_process");
8
- const { random_code } = require('./random');
9
- const { is_log_debug, is_log_error, log_debug, log_error } = require('../db/db');
10
-
11
- const LOG_BASH = "bash";
12
- const SSH_OPTIONS = "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no";
13
-
14
- /**
15
- * Execute command with unified logging and error handling.
16
- * @param {string} cmd - Command to execute.
17
- * @param {Object} options - Exec options.
18
- * @param {string} error_msg - Error message prefix.
19
- * @param {string} success_msg - Success message prefix.
20
- * @param {Object} [log_extra] - Additional logging context.
21
- * @returns {Promise<{stdout: string, err?: string}>} Command result.
22
- */
23
- const exec_with_logging = (cmd, options, error_msg, success_msg, log_extra) => {
24
- return new Promise((resolve) => {
25
- exec(cmd, options, (error, stdout) => {
26
- if (error) {
27
- if (is_log_error()) log_error(LOG_BASH, `${error_msg}, error:${error}`, log_extra);
28
- resolve({ stdout, err: `${error_msg}, error:${error}` });
29
- } else {
30
- if (is_log_debug()) log_debug(LOG_BASH, `${success_msg}, stdout:${stdout}`, log_extra);
31
- resolve({ stdout });
32
- }
33
- });
34
- });
35
- };
36
-
37
- /**
38
- * Get temporary log file path.
39
- * @returns {Promise<string>} Path to temporary log file.
40
- */
41
- const get_log_file = async () => {
42
- const home = await run_simple_local_cmd("echo ~");
43
- const log_dir = `${home}/.hola/ssh`;
44
- await run_local_cmd(`mkdir -p ${log_dir}`);
45
- return `${log_dir}/l_${random_code()}.log`;
46
- };
47
-
48
- /**
49
- * Build SSH command prefix.
50
- * @param {Object} host - Host configuration.
51
- * @returns {string} SSH command prefix.
52
- */
53
- const build_ssh_prefix = (host) => `ssh ${host.auth} ${SSH_OPTIONS} -p ${host.port} ${host.user}@${host.ip}`;
54
-
55
- /**
56
- * Build SCP command.
57
- * @param {Object} host - Host configuration.
58
- * @param {string} src - Source path.
59
- * @param {string} dest - Destination path.
60
- * @param {boolean} to_remote - True if copying to remote.
61
- * @returns {string} SCP command.
62
- */
63
- const build_scp_cmd = (host, src, dest, to_remote) => {
64
- const remote_path = `${host.user}@${host.ip}:${to_remote ? dest : src}`;
65
- const local_path = to_remote ? src : dest;
66
- const [first, second] = to_remote ? [local_path, remote_path] : [remote_path, local_path];
67
- return `scp ${host.auth} ${SSH_OPTIONS} -P ${host.port} -q ${first} ${second}`;
68
- };
69
-
70
- /**
71
- * Run script on remote host via SSH.
72
- * @param {Object} host - Host info with user, ip, port, auth, name.
73
- * @param {string} script - Commands to run.
74
- * @param {Object} [log_extra] - Additional logging context.
75
- * @returns {Promise<{stdout: string, err?: string}>} Command result.
76
- */
77
- const run_script = (host, script, log_extra) => {
78
- const cmd = `${build_ssh_prefix(host)} /bin/bash <<'EOT'\n ${script} \nEOT\n`;
79
- return exec_with_logging(cmd, { maxBuffer: 1024 * 150000 },
80
- `error running on host:${host.name} script:${script}`,
81
- `executing on host:${host.name}, script:${script}`, log_extra);
82
- };
83
-
84
- /**
85
- * Run script on remote host with file redirect to avoid progress bar issues.
86
- * @param {Object} host - Host info with user, ip, port, auth, name.
87
- * @param {string} script - Commands to run.
88
- * @param {Object} [log_extra] - Additional logging context.
89
- * @returns {Promise<{stdout: string, err?: string}>} Command result.
90
- */
91
- const run_script_extra = async (host, script, log_extra) => {
92
- const log_file = await get_log_file();
93
- const cmd = `${build_ssh_prefix(host)} /bin/bash <<'EOT' > ${log_file} \n ${script} \nEOT\n`;
94
-
95
- return new Promise((resolve) => {
96
- exec(cmd, { maxBuffer: 1024 * 150000 }, (error, stdout) => {
97
- if (error) {
98
- if (is_log_error()) log_error(LOG_BASH, `error running on host:${host.name} script:${script}, error:${error}`, log_extra);
99
- resolve({ stdout, err: `error running script:${script}, error:${error}` });
100
- } else {
101
- const output = fs.readFileSync(log_file, { encoding: 'utf8', flag: 'r' });
102
- if (is_log_debug()) log_debug(LOG_BASH, `executing on host:${host.name}, script:${script}, stdout:${output}`, log_extra);
103
- fs.unlinkSync(log_file);
104
- resolve({ stdout: output });
105
- }
106
- });
107
- });
108
- };
109
-
110
- /**
111
- * Run script file on remote host.
112
- * @param {Object} host - Host info.
113
- * @param {string} script_file - Path to local script file.
114
- * @param {Object} [log_extra] - Additional logging context.
115
- * @returns {Promise<{stdout: string, err?: string}>} Command result.
116
- */
117
- const run_script_file = (host, script_file, log_extra) => {
118
- const cmd = `${build_ssh_prefix(host)} /bin/bash < ${script_file}`;
119
- return exec_with_logging(cmd, {},
120
- `error running on host:${host.name} script_file:${script_file}`,
121
- `executing on host:${host.name}, script_file:${script_file}`, log_extra);
122
- };
123
-
124
- /**
125
- * Run command on local host.
126
- * @param {string} cmd - Command to execute.
127
- * @param {Object} [log_extra] - Additional logging context.
128
- * @returns {Promise<{stdout: string, err?: string}>} Command result.
129
- */
130
- const run_local_cmd = (cmd, log_extra) => {
131
- return exec_with_logging(cmd, { maxBuffer: 1024 * 15000000 },
132
- `error running on local host cmd:${cmd}`,
133
- `executing on local host cmd:${cmd}`, log_extra);
134
- };
135
-
136
- /**
137
- * SCP remote file to local.
138
- * @param {Object} host - Remote host info.
139
- * @param {string} remote_file - Remote file path.
140
- * @param {string} local_file - Local file path.
141
- * @param {Object} [log_extra] - Additional logging context.
142
- * @returns {Promise<{stdout: string, err?: string}>} Command result.
143
- */
144
- const scp = (host, remote_file, local_file, log_extra) => {
145
- const cmd = build_scp_cmd(host, remote_file, local_file, false);
146
- return exec_with_logging(cmd, {},
147
- `error scp on host:${host.name} remote:${remote_file}, local:${local_file}`,
148
- `executing scp on host:${host.name}, remote:${remote_file}, local:${local_file}`, log_extra);
149
- };
150
-
151
- /**
152
- * SCP local file to remote.
153
- * @param {Object} host - Remote host info.
154
- * @param {string} local_file - Local file path.
155
- * @param {string} remote_file - Remote file path.
156
- * @param {Object} [log_extra] - Additional logging context.
157
- * @returns {Promise<{stdout: string, err?: string}>} Command result.
158
- */
159
- const scpr = (host, local_file, remote_file, log_extra) => {
160
- const cmd = build_scp_cmd(host, local_file, remote_file, true);
161
- return exec_with_logging(cmd, {},
162
- `error scpr on host:${host.name} remote:${remote_file}, local:${local_file}`,
163
- `executing scpr on host:${host.name}, remote:${remote_file}, local:${local_file}`, log_extra);
164
- };
165
-
166
- /**
167
- * Run simple command on remote host and get trimmed result.
168
- * @param {Object} host - Host info.
169
- * @param {string} cmd - Command to run.
170
- * @param {Object} [log_extra] - Additional logging context.
171
- * @returns {Promise<string|null>} Trimmed output or null on error.
172
- */
173
- const run_simple_cmd = async (host, cmd, log_extra) => {
174
- const { err, stdout } = await run_script(host, cmd, log_extra);
175
- return err ? null : stdout.trim();
176
- };
177
-
178
- /**
179
- * Run simple command locally and get trimmed result.
180
- * @param {string} cmd - Command to run.
181
- * @param {Object} [log_extra] - Additional logging context.
182
- * @returns {Promise<string|null>} Trimmed output or null on error.
183
- */
184
- const run_simple_local_cmd = async (cmd, log_extra) => {
185
- const { err, stdout } = await run_local_cmd(cmd, log_extra);
186
- return err ? null : stdout.trim();
187
- };
188
-
189
- /**
190
- * Extract info from stdout using regex pattern matching.
191
- * @param {string} stdout - Command output.
192
- * @param {string} key - Key to search for.
193
- * @param {Object} [log_extra] - Additional logging context.
194
- * @returns {string[]} Array of matched values.
195
- */
196
- const get_info = (stdout, key, log_extra) => {
197
- const word_key = key.split(" ").join("\\s+");
198
- const regex = new RegExp(`\n\\s?${word_key}\\s?:(.*)\\s`, 'g');
199
- if (is_log_debug()) log_debug(LOG_BASH, `get_info regex:${JSON.stringify(regex)}`, log_extra);
200
-
201
- const matched = [...stdout.matchAll(regex)].map(result => result[1].trim());
202
- if (is_log_debug()) log_debug(LOG_BASH, `get_info matched:${JSON.stringify(matched)}`, log_extra);
203
- return matched;
204
- };
205
-
206
- /**
207
- * Read key-value pairs from stdout.
208
- * @param {string} stdout - Command output.
209
- * @param {string} [delimiter=":"] - Key-value delimiter.
210
- * @param {number[]} [lines] - Specific lines to read.
211
- * @param {Object} [config] - Filter config for keys.
212
- * @param {boolean} [exclude_mode] - If true, exclude keys in config.
213
- * @returns {Object} Parsed key-value object.
214
- */
215
- const read_key_value_line = (stdout, delimiter = ":", lines, config, exclude_mode) => {
216
- if (!stdout) return {};
217
-
218
- const contents = stdout.toString().split(/(?:\r\n|\r|\n)/g);
219
- const line_texts = lines ? lines.map(i => contents[i]) : contents;
220
-
221
- return line_texts.reduce((obj, content) => {
222
- const key_value = content.split(delimiter);
223
- if (key_value.length !== 2) return obj;
224
-
225
- const key = key_value[0].trim();
226
- const should_include = !config ||
227
- (exclude_mode !== true && config[key]) ||
228
- (exclude_mode === true && !config[`!${key}`]);
229
-
230
- if (key && should_include) obj[key] = key_value[1].trim();
231
- return obj;
232
- }, {});
233
- };
234
-
235
- /**
236
- * Read structured lines into array of objects.
237
- * @param {string} stdout - Command output.
238
- * @param {string[]} keys - Attribute keys for columns.
239
- * @param {number} [ignore=1] - Lines to skip at start.
240
- * @param {string} [delimiter=" "] - Column delimiter.
241
- * @returns {Object[]} Array of parsed objects.
242
- */
243
- const read_obj_line = (stdout, keys, ignore = 1, delimiter = " ") => {
244
- if (!stdout) return [];
245
-
246
- return stdout.toString().split(/(?:\r\n|\r|\n)/g)
247
- .slice(ignore)
248
- .filter(content => content.trim().length > 0)
249
- .map(content => {
250
- const attrs = content.split(delimiter).filter(f => f.trim().length > 0);
251
- return keys.reduce((obj, key, i) => {
252
- if (attrs[i]) obj[key] = attrs[i].trim();
253
- return obj;
254
- }, {});
255
- });
256
- };
257
-
258
- /**
259
- * Get multiple system attributes from remote host.
260
- * @param {Object} host - Host info.
261
- * @param {Array<{name: string, cmd: string}>} attrs - Attributes to fetch.
262
- * @param {Object} [log_extra] - Additional logging context.
263
- * @returns {Promise<Object>} Object with attribute values.
264
- */
265
- const get_system_attributes = async (host, attrs, log_extra) => {
266
- const results = await Promise.all(attrs.map(attr => run_simple_cmd(host, attr.cmd, log_extra)));
267
- return attrs.reduce((obj, attr, i) => {
268
- if (results[i]) obj[attr.name] = results[i];
269
- return obj;
270
- }, {});
271
- };
272
-
273
- /**
274
- * Stop process on remote host if running.
275
- * @param {Object} host - Host info.
276
- * @param {string} process_name - Process name to stop.
277
- * @param {string} stop_cmd - Command to stop the process.
278
- * @param {boolean} [using_full] - Use pgrep -f for full command match.
279
- * @param {Object} [log_extra] - Additional logging context.
280
- * @returns {Promise<boolean>} True if process was running and stopped.
281
- */
282
- const stop_process = async (host, process_name, stop_cmd, using_full, log_extra) => {
283
- const grep_cmd = using_full ? `pgrep -f "${process_name}" | wc -l` : `pgrep ${process_name} | wc -l`;
284
- const { stdout } = await run_script(host, grep_cmd, log_extra);
285
- const has_process = stdout && parseInt(stdout) > 0;
286
- if (has_process) await run_script(host, stop_cmd, log_extra);
287
- return has_process;
288
- };
289
-
290
- module.exports = {
291
- stop_process, scp, scpr, run_script, run_script_extra, run_script_file,
292
- run_simple_cmd, run_local_cmd, run_simple_local_cmd, get_info,
293
- get_system_attributes, read_key_value_line, read_obj_line
294
- };
package/core/chart.js DELETED
@@ -1,46 +0,0 @@
1
- /**
2
- * @fileoverview Chart data processing utility functions.
3
- * @module core/chart
4
- */
5
-
6
- const { has_value } = require("./validate");
7
-
8
- /**
9
- * Set chart header prefix for all columns except the first.
10
- * @param {Array[]} arr - 2D array with headers in first row.
11
- * @param {string} prefix - Prefix to add to header names.
12
- */
13
- const set_chart_header = (arr, prefix) => {
14
- if (!arr || arr.length < 1) return;
15
- const headers = arr[0];
16
- if (!headers || headers.length < 1) return;
17
- for (let i = 1; i < headers.length; i++) {
18
- headers[i] = `${prefix}${headers[i]}`;
19
- }
20
- };
21
-
22
- /**
23
- * Merge two chart data arrays by combining columns.
24
- * @param {Array[]} arr1 - First 2D data array (will be modified).
25
- * @param {Array[]} arr2 - Second 2D data array to merge.
26
- */
27
- const merge_chart_data = (arr1, arr2) => {
28
- if (!arr1 || arr1.length < 2 || !arr2 || arr2.length < 2) return;
29
-
30
- const max = Math.max(arr1.length, arr2.length);
31
- const arr1_cols = arr1[0].length;
32
- const arr2_cols = arr2[0].length;
33
-
34
- for (let i = 0; i < max; i++) {
35
- if (!has_value(arr1[i])) {
36
- arr1[i] = [...new Array(arr1_cols)].map(() => "");
37
- arr1[i][0] = arr2[i][0];
38
- }
39
- if (!has_value(arr2[i])) {
40
- arr2[i] = [...new Array(arr2_cols)].map(() => "");
41
- }
42
- arr1[i] = [...arr1[i], ...arr2[i].splice(1)];
43
- }
44
- };
45
-
46
- module.exports = { set_chart_header, merge_chart_data };
package/core/cron.js DELETED
@@ -1,21 +0,0 @@
1
- /**
2
- * @fileoverview Cron job scheduling utility functions.
3
- * @module core/cron
4
- */
5
-
6
- const node_cron = require('node-cron');
7
-
8
- /**
9
- * Initialize and start cron jobs.
10
- * @param {string[]} crons - Array of cron expressions.
11
- * @param {Function[]} tasks - Array of task functions to execute.
12
- * @param {string} [timezone="Asia/Shanghai"] - Timezone for scheduling.
13
- */
14
- const init_cron = async (crons, tasks, timezone = "Asia/Shanghai") => {
15
- crons.forEach((cron, index) => {
16
- const schedule = node_cron.schedule(cron, () => tasks[index](), { scheduled: true, timezone });
17
- schedule.start();
18
- });
19
- };
20
-
21
- module.exports = { init_cron };
package/core/date.js DELETED
@@ -1,26 +0,0 @@
1
- /**
2
- * @fileoverview Date formatting and parsing utility functions.
3
- * @module core/date
4
- */
5
-
6
- const date_format = require("dateformat");
7
-
8
- const format_time = (date) => date_format(date, "HH:MM");
9
- const simple_date = (date) => date_format(date, "mm/dd");
10
- const format_date = (date) => date_format(date, "yyyymmdd");
11
- const format_date_time = (date) => date_format(date, "yyyymmdd HH:MM:ss");
12
-
13
- /**
14
- * Parse yyyymmdd formatted string to Date object.
15
- * @param {string} date - Date string in yyyymmdd format.
16
- * @returns {Date} Parsed Date object with time set to 00:00:00.
17
- */
18
- const parse_date = (date) => {
19
- const [year, month, day] = [date.slice(0, 4), date.slice(4, 6), date.slice(6, 8)].map(Number);
20
- const date_obj = new Date();
21
- date_obj.setFullYear(year, month - 1, day);
22
- date_obj.setHours(0, 0, 0, 0);
23
- return date_obj;
24
- };
25
-
26
- module.exports = { simple_date, format_date, format_time, format_date_time, parse_date };
package/core/encrypt.js DELETED
@@ -1,26 +0,0 @@
1
- /**
2
- * @fileoverview Encryption and hashing utility functions.
3
- * @module core/encrypt
4
- */
5
-
6
- const crypto = require('crypto');
7
- const { get_settings } = require('../setting');
8
-
9
- /**
10
- * Generate MD5 hash of content.
11
- * @param {string} content - Content to hash.
12
- * @returns {string} MD5 hash in hex format.
13
- */
14
- const md5 = (content) => crypto.createHash('md5').update(content).digest('hex');
15
-
16
- /**
17
- * Encrypt password using MD5 with salt.
18
- * @param {string} password - Plain text password.
19
- * @returns {string} Encrypted password hash.
20
- */
21
- const encrypt_pwd = (password) => {
22
- const crypto_key = get_settings().encrypt.key;
23
- return md5(`BGT*&+${password}&76w${crypto_key}`);
24
- };
25
-
26
- module.exports = { md5, encrypt_pwd };
package/core/file.js DELETED
@@ -1,51 +0,0 @@
1
- /**
2
- * @fileoverview File system utility functions.
3
- * @module core/file
4
- */
5
-
6
- const fs = require('fs');
7
- const unzipper = require('unzipper');
8
-
9
- /**
10
- * Get file extension from filename.
11
- * @param {string} file_name - Name of the file.
12
- * @returns {string} File extension without dot.
13
- */
14
- const file_extension = (file_name) => file_name ? file_name.split('.').pop() : "";
15
-
16
- /**
17
- * Get file name without extension.
18
- * @param {string} file_name - Name of the file.
19
- * @returns {string} File name prefix.
20
- */
21
- const file_prefix = (file_name) => file_name ? file_name.split('.')[0] : "";
22
-
23
- /**
24
- * Read files from zip archive with filter.
25
- * @param {string} path - Path to zip file.
26
- * @param {Function} predicate - Filter function for files.
27
- * @returns {Promise<Object[]>} Array of matching file entries.
28
- */
29
- const read_from_zip = async (path, predicate) => {
30
- const directory = await unzipper.Open.file(path);
31
- return directory.files.filter(predicate);
32
- };
33
-
34
- const read_from_zip_by_extension = (path, extension) => read_from_zip(path, file => file_extension(file.path) === extension);
35
- const read_from_zip_by_prefix = (path, prefix) => read_from_zip(path, file => file_prefix(file.path) === prefix);
36
-
37
- /**
38
- * Check if file exists at path.
39
- * @param {string} path - File path to check.
40
- * @returns {boolean} True if file exists, false otherwise.
41
- */
42
- const is_file_exist = (path) => fs.existsSync(path);
43
-
44
- /**
45
- * Get file size in bytes.
46
- * @param {string} path - File path.
47
- * @returns {Promise<number>} File size in bytes.
48
- */
49
- const get_file_size = async (path) => (await fs.promises.stat(path)).size;
50
-
51
- module.exports = { file_extension, file_prefix, read_from_zip_by_extension, read_from_zip_by_prefix, is_file_exist, get_file_size };
package/core/lhs.js DELETED
@@ -1,53 +0,0 @@
1
- /**
2
- * @fileoverview Template execution utilities using Node.js VM.
3
- * @module core/lhs
4
- */
5
-
6
- const vm = require('node:vm');
7
- const { range, scale, space } = require("./number");
8
-
9
- /**
10
- * Get default context with number utilities.
11
- * @returns {Object} Context object with range, scale, and space functions.
12
- */
13
- const get_context = () => ({ range, scale, space });
14
-
15
- /**
16
- * Run code in VM context.
17
- * @param {string} code - JavaScript code to execute.
18
- * @param {Object} ctx - Context object for VM.
19
- * @returns {Object} Context object after execution.
20
- */
21
- const run_in_context = (code, ctx) => {
22
- vm.createContext(ctx);
23
- vm.runInContext(code, ctx);
24
- return ctx;
25
- };
26
-
27
- /**
28
- * Verify template string is valid JavaScript.
29
- * @param {string} template - Template string to verify.
30
- * @param {Object} knob - Variable bindings for template.
31
- * @returns {string|null} Error message if invalid, null if valid.
32
- */
33
- const verify_template = (template, knob) => {
34
- try {
35
- run_in_context("__output__=`" + template + "`;", knob);
36
- return null;
37
- } catch (err) {
38
- return err.message;
39
- }
40
- };
41
-
42
- /**
43
- * Execute template string and return result.
44
- * @param {string} template - Template string to execute.
45
- * @param {Object} knob - Variable bindings for template.
46
- * @returns {string} Executed template output.
47
- */
48
- const execute_template = (template, knob) => {
49
- const ctx = run_in_context("__output__=`" + template + "`;", knob);
50
- return ctx["__output__"];
51
- };
52
-
53
- module.exports = { get_context, run_in_context, verify_template, execute_template };