hola-server 1.0.10 → 2.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.
Files changed (83) hide show
  1. package/README.md +196 -1
  2. package/core/array.js +79 -142
  3. package/core/bash.js +208 -259
  4. package/core/chart.js +26 -16
  5. package/core/cron.js +14 -3
  6. package/core/date.js +15 -44
  7. package/core/encrypt.js +19 -9
  8. package/core/file.js +42 -29
  9. package/core/lhs.js +32 -6
  10. package/core/meta.js +213 -289
  11. package/core/msg.js +20 -7
  12. package/core/number.js +105 -103
  13. package/core/obj.js +15 -12
  14. package/core/random.js +9 -6
  15. package/core/role.js +69 -77
  16. package/core/thread.js +12 -2
  17. package/core/type.js +300 -261
  18. package/core/url.js +20 -12
  19. package/core/validate.js +29 -26
  20. package/db/db.js +297 -227
  21. package/db/entity.js +631 -963
  22. package/db/gridfs.js +120 -166
  23. package/design/add_default_field_attr.md +56 -0
  24. package/http/context.js +22 -8
  25. package/http/cors.js +25 -8
  26. package/http/error.js +27 -9
  27. package/http/express.js +70 -41
  28. package/http/params.js +70 -42
  29. package/http/router.js +51 -40
  30. package/http/session.js +59 -36
  31. package/index.js +85 -9
  32. package/package.json +2 -2
  33. package/router/clone.js +28 -36
  34. package/router/create.js +21 -26
  35. package/router/delete.js +24 -28
  36. package/router/read.js +137 -123
  37. package/router/update.js +38 -56
  38. package/setting.js +22 -6
  39. package/skills/array.md +155 -0
  40. package/skills/bash.md +91 -0
  41. package/skills/chart.md +54 -0
  42. package/skills/code.md +422 -0
  43. package/skills/context.md +177 -0
  44. package/skills/date.md +58 -0
  45. package/skills/express.md +255 -0
  46. package/skills/file.md +60 -0
  47. package/skills/lhs.md +54 -0
  48. package/skills/meta.md +1023 -0
  49. package/skills/msg.md +30 -0
  50. package/skills/number.md +88 -0
  51. package/skills/obj.md +36 -0
  52. package/skills/params.md +206 -0
  53. package/skills/random.md +22 -0
  54. package/skills/role.md +59 -0
  55. package/skills/session.md +281 -0
  56. package/skills/storage.md +743 -0
  57. package/skills/thread.md +22 -0
  58. package/skills/type.md +547 -0
  59. package/skills/url.md +34 -0
  60. package/skills/validate.md +48 -0
  61. package/test/cleanup/close-db.js +5 -0
  62. package/test/core/array.js +226 -0
  63. package/test/core/chart.js +51 -0
  64. package/test/core/file.js +59 -0
  65. package/test/core/lhs.js +44 -0
  66. package/test/core/number.js +167 -12
  67. package/test/core/obj.js +47 -0
  68. package/test/core/random.js +24 -0
  69. package/test/core/thread.js +20 -0
  70. package/test/core/type.js +216 -0
  71. package/test/core/validate.js +67 -0
  72. package/test/db/db-ops.js +99 -0
  73. package/test/db/pipe_test.txt +0 -0
  74. package/test/db/test_case_design.md +528 -0
  75. package/test/db/test_db_class.js +613 -0
  76. package/test/db/test_entity_class.js +414 -0
  77. package/test/db/test_gridfs_class.js +234 -0
  78. package/test/entity/create.js +1 -1
  79. package/test/entity/delete-mixed.js +156 -0
  80. package/test/entity/ref-filter.js +63 -0
  81. package/tool/gen_i18n.js +55 -21
  82. package/test/crud/router.js +0 -99
  83. package/test/router/user.js +0 -17
package/core/type.js CHANGED
@@ -1,329 +1,368 @@
1
+ /**
2
+ * @fileoverview Type conversion and validation system.
3
+ * @module core/type
4
+ */
5
+
1
6
  const { has_value, is_undefined } = require('./validate');
2
7
  const { encrypt_pwd } = require('./encrypt');
8
+
3
9
  const type_manager = {};
4
10
 
11
+ // ============================================================================
12
+ // Helper Functions
13
+ // ============================================================================
14
+
5
15
  /**
6
- * register your use type
7
- * @param {type object to do validation and type conversion} type
16
+ * Create success result.
17
+ * @param {*} value - Converted value.
18
+ * @returns {{value: *}} Success result.
8
19
  */
9
- const register_type = type => {
10
- type_manager[type.name] = type;
11
- }
12
-
13
- const convert_number = (value, type) => {
14
- const num_value = Number(value);
15
- if (isNaN(num_value)) {
16
- return { err: 'convert error for value:' + value + ",and type:" + type };
17
- } else {
18
- return { value: num_value };
19
- }
20
- }
21
-
22
- const convert_float = (value, type) => {
23
- const float_value = parseFloat(value);
24
- if (isNaN(float_value)) {
25
- return { err: 'convert error for value:' + value + ",and type:" + type };
26
- } else {
27
- return { value: parseFloat(float_value.toFixed(2)) };
28
- }
29
- }
20
+ const ok = (value) => ({ value });
30
21
 
31
22
  /**
32
- * get your user type
33
- * @param {type name} name
34
- * @returns
23
+ * Create error result.
24
+ * @param {string} type - Type name.
25
+ * @param {*} value - Original value.
26
+ * @returns {{err: string}} Error result.
35
27
  */
36
- const get_type = name => {
37
- const type = type_manager[name];
38
- if (type) {
39
- return type;
40
- } else {
41
- throw new Error('no type registered for name [' + name + ']');
28
+ const err = (type, value) => ({ err: `invalid ${type}:${value}` });
29
+
30
+ /**
31
+ * Check if value is an integer.
32
+ * @param {*} value - Value to check.
33
+ * @returns {boolean} True if integer.
34
+ */
35
+ const is_int = (value) => parseInt(value) === parseFloat(value);
36
+
37
+ /**
38
+ * Create a regex validation type.
39
+ * @param {string} name - Type name.
40
+ * @param {RegExp} pattern - Regex pattern.
41
+ * @returns {Object} Type definition.
42
+ */
43
+ const regex_type = (name, pattern) => ({
44
+ name,
45
+ convert: (value) => pattern.test(value) ? ok(value) : err(name, value)
46
+ });
47
+
48
+ /**
49
+ * Create an integer range validation type.
50
+ * @param {string} name - Type name.
51
+ * @param {number[]} valid_values - Array of valid values.
52
+ * @returns {Object} Type definition.
53
+ */
54
+ const int_enum_type = (name, valid_values) => ({
55
+ name,
56
+ convert: (value) => {
57
+ if (!is_int(value)) return err(name, value);
58
+ const int_value = parseInt(value);
59
+ return valid_values.includes(int_value) ? ok(int_value) : err(name, value);
42
60
  }
43
- }
61
+ });
44
62
 
45
- const obj_type = {
46
- name: "obj",
47
- convert: function (value) {
48
- return value;
63
+ /**
64
+ * Create an integer range validation type.
65
+ * @param {string} name - Type name.
66
+ * @param {number} min - Minimum value.
67
+ * @param {number} max - Maximum value.
68
+ * @returns {Object} Type definition.
69
+ */
70
+ const int_range_type = (name, min, max) => ({
71
+ name,
72
+ convert: (value) => {
73
+ if (!is_int(value)) return err(name, value);
74
+ const int_value = parseInt(value);
75
+ return (int_value >= min && int_value <= max) ? ok(int_value) : err(name, value);
49
76
  }
50
- }
77
+ });
51
78
 
52
- register_type(obj_type);
79
+ /**
80
+ * Create a passthrough string type.
81
+ * @param {string} name - Type name.
82
+ * @returns {Object} Type definition.
83
+ */
84
+ const string_type = (name) => ({ name, convert: (value) => ok(value + "") });
85
+
86
+ // ============================================================================
87
+ // Type Registration
88
+ // ============================================================================
89
+
90
+ /**
91
+ * Register a custom type with conversion function.
92
+ * @param {Object} type - Type definition with name and convert function.
93
+ */
94
+ const register_type = (type) => { type_manager[type.name] = type; };
53
95
 
54
- const boolean_type = {
96
+ /**
97
+ * Get registered type by name.
98
+ * @param {string} name - Type name.
99
+ * @returns {Object} Type definition.
100
+ * @throws {Error} If type not registered.
101
+ */
102
+ const get_type = (name) => {
103
+ const type = type_manager[name];
104
+ if (!type) throw new Error(`no type registered for name [${name}]`);
105
+ return type;
106
+ };
107
+
108
+ // ============================================================================
109
+ // Built-in Types: Basic
110
+ // ============================================================================
111
+
112
+ register_type({ name: "obj", convert: ok });
113
+ register_type({ name: "string", convert: (value) => ok(value ? (value + "").trim() : "") });
114
+ register_type({ name: "password", convert: (value) => ok(encrypt_pwd(value)) });
115
+ register_type({ name: "file", convert: ok });
116
+
117
+ // Passthrough string types
118
+ register_type(string_type("lstr"));
119
+ register_type(string_type("text"));
120
+ register_type(string_type("date"));
121
+ register_type(string_type("enum"));
122
+ register_type(string_type("log_category"));
123
+
124
+ // ============================================================================
125
+ // Built-in Types: Boolean
126
+ // ============================================================================
127
+
128
+ register_type({
55
129
  name: "boolean",
56
- convert: function (value) {
57
- if (value === true || value === "true") {
58
- return { value: true };
59
- } else if (value === false || value === "false") {
60
- return { value: false };
61
- } else {
62
- return { err: 'boolean convert error for value:' + value };
63
- }
130
+ convert: (value) => {
131
+ if (value === true || value === "true") return ok(true);
132
+ if (value === false || value === "false") return ok(false);
133
+ return err("boolean", value);
64
134
  }
65
- }
135
+ });
66
136
 
67
- register_type(boolean_type);
137
+ // ============================================================================
138
+ // Built-in Types: Numeric
139
+ // ============================================================================
68
140
 
69
- const is_int = (value) => {
70
- return parseInt(value) == parseFloat(value);
71
- }
72
- const int_type = {
73
- name: "int",
74
- convert: function (value) {
75
- return is_int(value) ? { value: parseInt(value) } : { err: 'int convert error for value:' + value };
141
+ register_type({
142
+ name: "number",
143
+ convert: (value) => {
144
+ const num = Number(value);
145
+ return isNaN(num) ? err("number", value) : ok(num);
76
146
  }
77
- }
147
+ });
78
148
 
79
- register_type(int_type);
149
+ register_type({
150
+ name: "int",
151
+ convert: (value) => is_int(value) ? ok(parseInt(value)) : err("int", value)
152
+ });
80
153
 
81
- const uint_type = {
154
+ register_type({
82
155
  name: "uint",
83
- convert: function (value) {
156
+ convert: (value) => {
84
157
  const int_value = parseInt(value);
85
- return is_int(value) && int_value >= 0 ? { value: int_value } : { err: 'int convert error for value:' + value };
158
+ return (is_int(value) && int_value >= 0) ? ok(int_value) : err("uint", value);
86
159
  }
87
- }
160
+ });
88
161
 
89
- register_type(uint_type);
90
-
91
- const float_type = {
162
+ register_type({
92
163
  name: "float",
93
- convert: function (value) {
94
- return convert_float(value, "float");
164
+ convert: (value) => {
165
+ const num = parseFloat(value);
166
+ return isNaN(num) ? err("float", value) : ok(parseFloat(num.toFixed(2)));
95
167
  }
96
- }
97
-
98
- register_type(float_type);
168
+ });
99
169
 
100
- const ufloat_type = {
170
+ register_type({
101
171
  name: "ufloat",
102
- convert: function (value) {
103
- const float_value = parseFloat(value);
104
- if (isNaN(float_value) || float_value < 0) {
105
- return { err: 'float convert error for value:' + value };
106
- } else {
107
- return { value: parseFloat(float_value.toFixed(2)) };
108
- }
172
+ convert: (value) => {
173
+ const num = parseFloat(value);
174
+ return (isNaN(num) || num < 0) ? err("ufloat", value) : ok(parseFloat(num.toFixed(2)));
109
175
  }
110
- }
111
-
112
- register_type(ufloat_type);
176
+ });
113
177
 
114
- const number_type = {
115
- name: "number",
116
- convert: function (value) {
117
- return convert_number(value, "number");
178
+ register_type({
179
+ name: "decimal",
180
+ convert: (value) => {
181
+ const num = parseFloat(value);
182
+ return isNaN(num) ? err("decimal", value) : ok(num);
118
183
  }
119
- }
184
+ });
120
185
 
121
- register_type(number_type);
122
-
123
- const string_type = {
124
- name: "string",
125
- convert: function (value) {
126
- return { value: value ? (value + "").trim() : "" };
186
+ register_type({
187
+ name: "percentage",
188
+ convert: (value) => {
189
+ const num = parseFloat(value);
190
+ return isNaN(num) ? err("percentage", value) : ok(parseFloat(num.toFixed(2)));
127
191
  }
128
- }
192
+ });
129
193
 
130
- register_type(string_type);
131
-
132
- const password_type = {
133
- name: "password",
134
- convert: function (value) {
135
- return { value: encrypt_pwd(value) };
194
+ register_type({
195
+ name: "currency",
196
+ convert: (value) => {
197
+ const num = Number(value);
198
+ return isNaN(num) ? err("currency", value) : ok(num);
136
199
  }
137
- }
200
+ });
138
201
 
139
- register_type(password_type);
202
+ // ============================================================================
203
+ // Built-in Types: Date/Time
204
+ // ============================================================================
140
205
 
141
- const file_type = {
142
- name: "file",
143
- convert: function (value) {
144
- return { value: value };
206
+ register_type({
207
+ name: "datetime",
208
+ convert: (value) => {
209
+ const date = new Date(value);
210
+ return isNaN(date.getTime()) ? err("datetime", value) : ok(date.toISOString());
145
211
  }
146
- }
147
-
148
- register_type(file_type);
212
+ });
149
213
 
150
- const array_type = {
151
- name: "array",
152
- convert: function (value) {
153
- if (typeof value === "string") {
154
- return { value: value.split(",") }
155
- } else if (Array.isArray(value)) {
156
- return { value: value }
157
- } else {
158
- return { err: "error array type" }
159
- }
160
- }
161
- }
214
+ register_type(regex_type("time", /^([0-1]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/));
162
215
 
163
- register_type(array_type);
216
+ // ============================================================================
217
+ // Built-in Types: Validation
218
+ // ============================================================================
164
219
 
165
- const lstr_type = {
166
- name: "lstr",
167
- convert: function (value) {
168
- return { value: value + "" };
220
+ register_type({
221
+ name: "email",
222
+ convert: (value) => {
223
+ const pattern = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
224
+ return pattern.test(value) ? ok(value) : err("email", value);
169
225
  }
170
- }
171
-
172
- register_type(lstr_type);
226
+ });
173
227
 
174
- const text_type = {
175
- name: "text",
176
- convert: function (value) {
177
- return { value: value + "" };
228
+ register_type({
229
+ name: "url",
230
+ convert: (value) => {
231
+ try { new URL(value); return ok(value); }
232
+ catch { return err("url", value); }
178
233
  }
179
- }
180
-
181
- register_type(text_type);
234
+ });
182
235
 
183
- const date_type = {
184
- name: "date",
185
- convert: function (value) {
186
- return { value: value + "" };
187
- }
188
- }
189
-
190
- register_type(date_type);
191
-
192
- const age_type = {
193
- name: "age",
194
- convert: function (value) {
195
- if (is_int(value)) {
196
- const int_value = parseInt(value);
197
- if (int_value < 0 || int_value > 200) {
198
- return { err: "invalid age value:" + value };
199
- } else {
200
- return { value: int_value };
201
- }
202
- } else {
203
- return { err: "age isn't int type:" + value };
204
- }
236
+ register_type({
237
+ name: "phone",
238
+ convert: (value) => {
239
+ const cleaned = value.replace(/[\s\-\(\)]/g, '');
240
+ return /^\+?[1-9]\d{1,14}$/.test(cleaned) ? ok(cleaned) : err("phone", value);
205
241
  }
206
- }
207
-
208
- register_type(age_type);
209
-
210
- const gender_type = {
211
- name: "gender",
212
- convert: function (value) {
213
- if (is_int(value)) {
214
- const int_value = parseInt(value);
215
- if (int_value == 0 || int_value == 1) {
216
- return { value: int_value };
217
- } else {
218
- return { err: "invalid gender value:" + value }
219
- }
220
- } else {
221
- return { err: "gender isn't int type:" + value };
222
- }
223
- }
224
- }
225
-
226
- register_type(gender_type);
227
-
228
- const log_level_type = {
229
- name: "log_level",
230
- convert: function (value) {
231
- if (is_int(value)) {
232
- const int_value = parseInt(value);
233
- if (int_value == 0 || int_value == 1 || int_value == 2 || int_value == 3) {
234
- return { value: int_value };
235
- } else {
236
- return { err: "invalid level value:" + value }
237
- }
238
- } else {
239
- return { err: "log level isn't int type:" + value };
240
- }
241
- }
242
- }
242
+ });
243
243
 
244
- register_type(log_level_type);
244
+ register_type(regex_type("uuid", /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i));
245
+ register_type(regex_type("color", /^#([0-9A-F]{3}){1,2}$/i));
245
246
 
246
- const log_category_type = {
247
- name: "log_category",
248
- convert: function (value) {
249
- return { value: value + "" };
247
+ register_type({
248
+ name: "ip_address",
249
+ convert: (value) => {
250
+ if (!/^(\d{1,3}\.){3}\d{1,3}$/.test(value)) return err("ip_address", value);
251
+ const valid = value.split('.').every(part => parseInt(part) <= 255);
252
+ return valid ? ok(value) : err("ip_address", value);
250
253
  }
251
- }
254
+ });
252
255
 
253
- register_type(log_category_type);
256
+ // ============================================================================
257
+ // Built-in Types: Data Structures
258
+ // ============================================================================
254
259
 
255
- const percentage_type = {
256
- name: "percentage",
257
- convert: function (value) {
258
- return convert_float(value, "percentage");
260
+ register_type({
261
+ name: "array",
262
+ convert: (value) => {
263
+ if (typeof value === "string") return ok(value.split(","));
264
+ if (Array.isArray(value)) return ok(value);
265
+ return err("array", value);
259
266
  }
260
- }
261
-
262
- register_type(percentage_type);
263
-
264
- const currency_type = {
265
- name: "currency",
266
- convert: function (value) {
267
- return convert_number(value, "currency");
267
+ });
268
+
269
+ register_type({
270
+ name: "json",
271
+ convert: (value) => {
272
+ if (typeof value === 'object') return ok(value);
273
+ try { return ok(JSON.parse(value)); }
274
+ catch { return err("json", value); }
268
275
  }
269
- }
276
+ });
270
277
 
271
- register_type(currency_type);
278
+ // ============================================================================
279
+ // Built-in Types: Transformations
280
+ // ============================================================================
272
281
 
273
- const email_type = {
274
- name: "email",
275
- convert: function (value) {
276
- const pattern = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
277
- if (pattern.test(value)) {
278
- return { value: value };
279
- } else {
280
- return { err: 'err email for value:' + value };
281
- }
282
- }
283
- }
282
+ register_type({
283
+ name: "slug",
284
+ convert: (value) => ok(value.toString().toLowerCase().trim()
285
+ .replace(/\s+/g, '-')
286
+ .replace(/[^\w\-]+/g, '')
287
+ .replace(/\-\-+/g, '-'))
288
+ });
284
289
 
285
- register_type(email_type);
290
+ // ============================================================================
291
+ // Built-in Types: Domain-Specific
292
+ // ============================================================================
286
293
 
287
- const convert_type = function (obj, fields) {
288
- const result = {};
289
- const error_field_names = [];
294
+ register_type(int_range_type("age", 0, 200));
295
+ register_type(int_enum_type("gender", [0, 1]));
296
+ register_type(int_enum_type("log_level", [0, 1, 2, 3]));
290
297
 
291
- fields.forEach(function (field) {
292
- const field_value = obj[field.name];
293
- if (has_value(field_value)) {
294
- const type_name = field.type ? field.type : "string";
295
- const type = get_type(type_name);
296
- const { value, err } = type.convert(field_value);
297
- if (err) {
298
- error_field_names.push(field.name);
299
- } else {
300
- result[field.name] = value;
301
- }
302
- }
303
- });
304
- return { obj: result, error_field_names: error_field_names };
305
- }
298
+ // ============================================================================
299
+ // Conversion Functions
300
+ // ============================================================================
301
+
302
+ /**
303
+ * Convert a single field value.
304
+ * @param {*} field_value - Value to convert.
305
+ * @param {string} type_name - Type name.
306
+ * @returns {{value?: *, err?: string}} Conversion result.
307
+ */
308
+ const convert_field = (field_value, type_name) => {
309
+ const type = get_type(type_name || "string");
310
+ return type.convert(field_value);
311
+ };
306
312
 
307
- const convert_update_type = function (obj, fields) {
313
+ /**
314
+ * Convert object fields to their defined types.
315
+ * @param {Object} obj - Object with values to convert.
316
+ * @param {Array<{name: string, type?: string}>} fields - Field definitions.
317
+ * @param {boolean} preserve_empty - Whether to preserve empty values as "".
318
+ * @returns {{obj: Object, error_field_names: string[]}} Converted object and error fields.
319
+ */
320
+ const convert_fields = (obj, fields, preserve_empty = false) => {
308
321
  const result = {};
309
322
  const error_field_names = [];
310
323
 
311
- fields.forEach(function (field) {
324
+ for (const field of fields) {
312
325
  const field_value = obj[field.name];
326
+
313
327
  if (has_value(field_value)) {
314
- const type_name = field.type ? field.type : "string";
315
- const type = get_type(type_name);
316
- const { value, err } = type.convert(field_value);
317
- if (err) {
318
- error_field_names.push(field.name);
319
- } else {
320
- result[field.name] = value;
321
- }
322
- } else if (!is_undefined(field_value)) {
328
+ const { value, err } = convert_field(field_value, field.type);
329
+ if (err) error_field_names.push(field.name);
330
+ else result[field.name] = value;
331
+ } else if (preserve_empty && !is_undefined(field_value)) {
323
332
  result[field.name] = "";
324
333
  }
325
- });
326
- return { obj: result, error_field_names: error_field_names };
327
- }
334
+ }
335
+
336
+ return { obj: result, error_field_names };
337
+ };
328
338
 
329
- module.exports = { register_type, convert_type, convert_update_type, get_type }
339
+ /**
340
+ * Convert object fields to their defined types.
341
+ * @param {Object} obj - Object with values to convert.
342
+ * @param {Array<{name: string, type?: string}>} fields - Field definitions.
343
+ * @returns {{obj: Object, error_field_names: string[]}} Converted object and error fields.
344
+ */
345
+ const convert_type = (obj, fields) => convert_fields(obj, fields, false);
346
+
347
+ /**
348
+ * Convert object fields for update operation (preserves empty values).
349
+ * @param {Object} obj - Object with values to convert.
350
+ * @param {Array<{name: string, type?: string}>} fields - Field definitions.
351
+ * @returns {{obj: Object, error_field_names: string[]}} Converted object and error fields.
352
+ */
353
+ const convert_update_type = (obj, fields) => convert_fields(obj, fields, true);
354
+
355
+ module.exports = {
356
+ register_type,
357
+ convert_type,
358
+ convert_update_type,
359
+ get_type,
360
+ // Helper functions for custom type creation
361
+ ok,
362
+ err,
363
+ is_int,
364
+ regex_type,
365
+ int_enum_type,
366
+ int_range_type,
367
+ string_type
368
+ };
package/core/url.js CHANGED
@@ -1,22 +1,30 @@
1
+ /**
2
+ * @fileoverview URL and HTTP request utility functions.
3
+ * @module core/url
4
+ */
5
+
1
6
  const axios = require('axios');
2
7
  const { get_settings } = require("../setting");
3
8
 
4
- const url = function (url, method) {
9
+ /**
10
+ * Create HTTP request function with preset URL and method.
11
+ * @param {string} url - Request URL.
12
+ * @param {string} method - HTTP method (GET, POST, etc.).
13
+ * @returns {Function} Function that accepts config and returns axios promise.
14
+ */
15
+ const url = (url, method) => {
5
16
  const settings = get_settings();
6
17
  const axios_config = settings.axios;
7
18
 
8
- return function (config) {
9
- let params = {
10
- url: url,
11
- method: method,
12
- validateStatus: false
19
+ return (config) => {
20
+ const params = {
21
+ url,
22
+ method,
23
+ validateStatus: false,
24
+ ...(axios_config.proxy && { proxy: axios_config.proxy })
13
25
  };
14
- if (axios_config.proxy) {
15
- params.proxy = axios_config.proxy;
16
- }
17
26
  return axios.request({ ...params, ...config });
18
- }
27
+ };
19
28
  };
20
29
 
21
-
22
- module.exports = { url }
30
+ module.exports = { url };