hola-server 1.0.11 → 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/skills/msg.md ADDED
@@ -0,0 +1,30 @@
1
+ # Message Utilities Skill
2
+
3
+ ## Overview
4
+
5
+ The `hola-server/core/msg.js` module wraps the `wxmnode` library to provide a simplified interface for sending messages (e.g., WeChat Work or similar enterprise messengers).
6
+
7
+ ## Importing
8
+
9
+ ```javascript
10
+ const { init_wxm, send_msg } = require("hola-server/core/msg");
11
+ ```
12
+
13
+ ## API Reference
14
+
15
+ ### `init_wxm(name, password)`
16
+ Initializes the underlying messaging client with credentials.
17
+ - **param**: `name` (string) - Account/Service name.
18
+ - **param**: `password` (string) - Credentials.
19
+
20
+ ### `send_msg(content, type, detail)`
21
+ Sends a message asynchronously.
22
+ - **param**: `content` (string) - Main message body.
23
+ - **param**: `type` (string) - Message type identifier.
24
+ - **param**: `detail` (Object) - Additional metadata or payload options.
25
+ - **returns**: `Promise<Object>` - Result from the messaging service.
26
+
27
+ ```javascript
28
+ await init_wxm("bot_account", "secret_token");
29
+ await send_msg("System Alert: Disk Full", "text", { priority: "high" });
30
+ ```
@@ -0,0 +1,88 @@
1
+ # Number Utilities Skill
2
+
3
+ ## Overview
4
+
5
+ The `hola-server/core/number.js` module provides extensive numerical utilities including parsing, rounding, range generation, sampling, and space definitions for search algorithms.
6
+
7
+ ## Importing
8
+
9
+ ```javascript
10
+ const {
11
+ parse_num, extract_number,
12
+ to_fixed2, round_to_fixed2,
13
+ range, scale,
14
+ space, is_space, contains_space,
15
+ is_integer, random_number, random_sample, lhs_samples
16
+ } = require("hola-server/core/number");
17
+ ```
18
+
19
+ ## API Reference
20
+
21
+ ### 1. Parsing & Formatting
22
+
23
+ #### `parse_num(str)`
24
+ Parses string to float, defaults to 0 if invalid.
25
+ - **returns**: `number`
26
+
27
+ #### `to_fixed2(str)`
28
+ Parses string/number and rounds/formats to 2 decimal places.
29
+ - **returns**: `number`
30
+
31
+ #### `round_to_fixed2(num)`
32
+ Math utility to round a number to 2 decimal places.
33
+ - **returns**: `number`
34
+
35
+ #### `extract_number(value)`
36
+ Extracts the first valid numeric sequence from a string.
37
+ - **param**: `value` (string) - e.g., "Price$12.50each".
38
+ - **returns**: `number` - e.g., 12.50.
39
+
40
+ ### 2. Ranges & Spaces
41
+
42
+ #### `range(start, end, step)`
43
+ Generates an arithmetic sequence.
44
+ - `range(3)` → `[0, 1, 2]`
45
+ - `range(1, 5)` → `[1, 2, 3, 4, 5]`
46
+ - `range(0, 10, 2)` → `[0, 2, 4, 6, 8, 10]`
47
+
48
+ #### `scale(start, end, ratio)`
49
+ Generates a geometric sequence.
50
+ - `scale(2, 16, 2)` → `[2, 4, 8, 16]`
51
+
52
+ #### `space(min, max)`
53
+ Creates a "space" object `{min, max}` representing a continuous range.
54
+ - **returns**: `{min: number, max: number}`
55
+
56
+ #### `is_space(value)`
57
+ Checks if an object is a valid space (has min/max).
58
+ - **returns**: `boolean`
59
+
60
+ #### `contains_space(obj)`
61
+ Checks if any property of an object is a space.
62
+ - **returns**: `boolean`
63
+
64
+ ### 3. Random & Sampling
65
+
66
+ #### `random_number(min, max)`
67
+ Generates a random number between min and max. Returns integer if bounds are integers, otherwise float with 2 decimals.
68
+ - **returns**: `number`
69
+
70
+ #### `lhs_samples(min, max, n)`
71
+ Generates `n` ranges using Latin Hypercube Sampling logic.
72
+ - **returns**: `Array<{min, max}>`
73
+
74
+ #### `random_sample(obj)`
75
+ Takes a configuration object where values can be fixed, arrays (options), or spaces (range), and returns a single sampled object.
76
+ - **Array values**: Randomly picks one element.
77
+ - **Space values**: Randomly picks number within range.
78
+ - **Other**: Kept as-is.
79
+
80
+ ```javascript
81
+ const config = {
82
+ color: ['red', 'blue'], // Pick one
83
+ size: space(10, 20), // Pick number 10-20
84
+ type: 'shirt' // Fixed
85
+ };
86
+ const sample = random_sample(config);
87
+ // { color: 'red', size: 14.5, type: 'shirt' }
88
+ ```
package/skills/obj.md ADDED
@@ -0,0 +1,36 @@
1
+ # Object Utilities Skill
2
+
3
+ ## Overview
4
+
5
+ The `hola-server/core/obj.js` module provides simple object manipulation helpers.
6
+
7
+ ## Importing
8
+
9
+ ```javascript
10
+ const { copy_obj, is_object } = require("hola-server/core/obj");
11
+ ```
12
+
13
+ ## API Reference
14
+
15
+ ### `copy_obj(obj, attrs)`
16
+ Creates a shallow copy of an object containing only the specified attributes (whitelisting).
17
+ - **param**: `obj` (Object) - Source object.
18
+ - **param**: `attrs` (string[]) - Keys to copy.
19
+ - **returns**: `Object`
20
+
21
+ ```javascript
22
+ const src = { a: 1, b: 2, c: 3 };
23
+ const dest = copy_obj(src, ['a', 'c']);
24
+ // dest is { a: 1, c: 3 }
25
+ ```
26
+
27
+ ### `is_object(obj)`
28
+ Checks if a value is a plain non-null object (excludes arrays and null).
29
+ - **param**: `obj` (*) - Value to check.
30
+ - **returns**: `boolean`
31
+
32
+ ```javascript
33
+ is_object({}); // true
34
+ is_object([]); // false
35
+ is_object(null); // false
36
+ ```
@@ -0,0 +1,206 @@
1
+ # HTTP Parameter Utilities Skill
2
+
3
+ ## Overview
4
+
5
+ The `hola-server/http/params.js` module provides utilities for extracting and validating parameters from Express request objects (query strings and body).
6
+
7
+ ## Importing
8
+
9
+ ```javascript
10
+ const {
11
+ get_params, post_params, post_update_params,
12
+ required_get_params, required_post_params, required_params
13
+ } = require("hola-server/http/params");
14
+ ```
15
+
16
+ ## API Reference
17
+
18
+ ### 1. Extract Query Parameters
19
+
20
+ #### `get_params(req, params)`
21
+ Extracts specified parameters from `req.query` (only values that are present).
22
+
23
+ **Parameters:**
24
+ - `req` (Object): Express request object
25
+ - `params` (string[]): Parameter names to extract
26
+
27
+ **Returns:** `Object` - Extracted parameters
28
+
29
+ ```javascript
30
+ // URL: /api/products?name=iPhone&price=999&stock=50
31
+
32
+ const params = get_params(req, ["name", "price", "category"]);
33
+ // Returns: { name: "iPhone", price: "999" }
34
+ // Note: "category" is omitted (not present in query)
35
+ ```
36
+
37
+ ### 2. Extract Body Parameters
38
+
39
+ #### `post_params(req, params)`
40
+ Extracts specified parameters from `req.body` (only non-empty values).
41
+
42
+ ```javascript
43
+ const params = post_params(req, ["name", "email", "age"]);
44
+ // Returns only fields that have values
45
+ ```
46
+
47
+ #### `post_update_params(req, params)`
48
+ Extracts update parameters, **including `null` and empty strings** (but excluding `undefined`).
49
+
50
+ **Use Case:** Partial updates where empty string means "clear field" and undefined means "no change".
51
+
52
+ ```javascript
53
+ // Body: { name: "John", email: "", age: undefined }
54
+
55
+ const params = post_update_params(req, ["name", "email", "age"]);
56
+ // Returns: { name: "John", email: "" }
57
+ // Note: "age" is omitted (undefined), "email" is included (empty string is valid)
58
+ ```
59
+
60
+ ### 3. Required Parameters
61
+
62
+ #### `required_get_params(req, params)`
63
+ Extracts required query parameters. Returns `null` if any are missing.
64
+
65
+ ```javascript
66
+ const { NO_PARAMS } = require("hola-server/http/code");
67
+
68
+ const params = required_get_params(req, ["page", "limit"]);
69
+ if (!params) {
70
+ return res.json({ code: NO_PARAMS, err: ["page", "limit"] });
71
+ }
72
+ // params contains both page and limit, or null
73
+ ```
74
+
75
+ #### `required_post_params(req, params)`
76
+ Extracts required body parameters. Returns `null` if any are missing.
77
+
78
+ ```javascript
79
+ const { NO_PARAMS } = require("hola-server/http/code");
80
+
81
+ const params = required_post_params(req, ["username", "password"]);
82
+ if (!params) {
83
+ return res.json({ code: NO_PARAMS, err: ["username", "password"] });
84
+ }
85
+ ```
86
+
87
+ #### `required_params(input, params)`
88
+ General-purpose required parameter extraction from any object.
89
+
90
+ ```javascript
91
+ const params = required_params(req.body, ["name", "email"]);
92
+ if (!params) {
93
+ return res.json({ code: NO_PARAMS, err: ["name", "email"] });
94
+ }
95
+ ```
96
+
97
+ ## Usage Patterns
98
+
99
+ ### Pattern 1: Optional Query Parameters
100
+
101
+ ```javascript
102
+ router.get("/search", async (req, res) => {
103
+ const search = get_params(req, ["name", "category", "min_price", "max_price"]);
104
+
105
+ const results = await entity.list_entity(
106
+ { attr_names: "name,price,category", page: 1, limit: 20, sort_by: "price", desc: "false" },
107
+ {},
108
+ search, // Only includes parameters that were provided
109
+ "*"
110
+ );
111
+
112
+ return res.json(results);
113
+ });
114
+ ```
115
+
116
+ ### Pattern 2: Required Body Parameters
117
+
118
+ ```javascript
119
+ const { NO_PARAMS, SUCCESS } = require("hola-server/http/code");
120
+
121
+ router.post("/login", async (req, res) => {
122
+ const credentials = required_post_params(req, ["username", "password"]);
123
+
124
+ if (!credentials) {
125
+ return res.json({ code: NO_PARAMS, err: ["username", "password"] });
126
+ }
127
+
128
+ // Proceed with authentication
129
+ const user = await authenticate(credentials.username, credentials.password);
130
+ return res.json({ code: SUCCESS, user });
131
+ });
132
+ ```
133
+
134
+ ### Pattern 3: Partial Updates
135
+
136
+ ```javascript
137
+ router.put("/:id", async (req, res) => {
138
+ // Use post_update_params to allow clearing fields with empty strings
139
+ const updates = post_update_params(req, ["name", "description", "email", "phone"]);
140
+
141
+ const result = await entity.update_entity(req.params.id, updates, "*");
142
+ return res.json(result);
143
+ });
144
+ ```
145
+
146
+ ### Pattern 4: Pagination Parameters
147
+
148
+ ```javascript
149
+ router.get("/list", async (req, res) => {
150
+ const query_params = get_params(req, ["page", "limit", "sort_by", "desc"]);
151
+
152
+ // Provide defaults
153
+ query_params.page = query_params.page || 1;
154
+ query_params.limit = query_params.limit || 20;
155
+ query_params.sort_by = query_params.sort_by || "created_at";
156
+ query_params.desc = query_params.desc || "true";
157
+ query_params.attr_names = "name,price,created_at";
158
+
159
+ const result = await entity.list_entity(query_params, {}, {}, "*");
160
+ return res.json(result);
161
+ });
162
+ ```
163
+
164
+ ### Pattern 5: Combining Query and Body
165
+
166
+ ```javascript
167
+ const { NO_PARAMS } = require("hola-server/http/code");
168
+
169
+ router.post("/filter", async (req, res) => {
170
+ // Extract pagination from query
171
+ const pagination = required_get_params(req, ["page", "limit"]);
172
+ if (!pagination) {
173
+ return res.json({ code: NO_PARAMS, err: ["page", "limit"] });
174
+ }
175
+
176
+ // Extract filter from body
177
+ const filters = post_params(req, ["category", "min_price", "max_price", "brand"]);
178
+
179
+ const results = await entity.list_entity(
180
+ { ...pagination, attr_names: "name,price", sort_by: "price", desc: "false" },
181
+ {},
182
+ filters,
183
+ "*"
184
+ );
185
+
186
+ return res.json(results);
187
+ });
188
+ ```
189
+
190
+ ## Best Practices
191
+
192
+ 1. **Use `required_*` functions for validation**: They return `null` if parameters are missing, making validation simple.
193
+
194
+ 2. **Use `post_update_params` for PATCH/PUT**: Distinguishes between "clear field" (empty string) and "no change" (undefined).
195
+
196
+ 3. **Provide defaults for optional params**: After extracting with `get_params` or `post_params`, apply defaults as needed.
197
+
198
+ 4. **Whitelist parameters**: Always specify exact parameter names to avoid exposing internal fields.
199
+
200
+ ```javascript
201
+ // Good: explicit whitelist
202
+ const params = post_params(req, ["name", "email", "age"]);
203
+
204
+ // Avoid: accepting all body params
205
+ const params = req.body; // Could include malicious/internal fields
206
+ ```
@@ -0,0 +1,22 @@
1
+ # Random Utilities Skill
2
+
3
+ ## Overview
4
+
5
+ The `hola-server/core/random.js` module provides simple random generation utilities.
6
+
7
+ ## Importing
8
+
9
+ ```javascript
10
+ const { random_code } = require("hola-server/core/random");
11
+ ```
12
+
13
+ ## API Reference
14
+
15
+ ### `random_code()`
16
+ Generates a random 6-digit integer code (0 to 999999).
17
+ - **returns**: `number`
18
+
19
+ ```javascript
20
+ const code = random_code();
21
+ // e.g., 123456
22
+ ```
package/skills/role.md ADDED
@@ -0,0 +1,59 @@
1
+ # Role & Permission Utilities Skill
2
+
3
+ ## Overview
4
+
5
+ The `hola-server/core/role.js` module provides utilities for checking user roles and permissions against entity meta definitions and system settings.
6
+
7
+ ## Importing
8
+
9
+ ```javascript
10
+ const {
11
+ is_root_role, is_root_user,
12
+ validate_meta_role, check_user_role,
13
+ get_user_role_right, get_session_user
14
+ } = require("hola-server/core/role");
15
+ ```
16
+
17
+ ## API Reference
18
+
19
+ ### 1. Role Validation
20
+
21
+ #### `validate_meta_role(role_name)`
22
+ Checks if a role name exists in the system settings.
23
+ - **param**: `role_name` (string)
24
+ - **returns**: `boolean`
25
+
26
+ #### `is_root_role(role_name)`
27
+ Checks if a specific role has root privileges (based on settings).
28
+ - **returns**: `boolean`
29
+
30
+ ### 2. User & Session Checks
31
+
32
+ #### `get_session_user(req)`
33
+ Extracts user object from request session.
34
+ - **param**: `req` (Object) - Express request object.
35
+ - **returns**: `Object|null`
36
+
37
+ #### `is_root_user(req)`
38
+ Checks if the current session user has root privileges.
39
+ - **returns**: `boolean`
40
+
41
+ ### 3. Permission Checking
42
+
43
+ #### `get_user_role_right(req, meta)`
44
+ Resolves the current user's permissions for a specific entity based on their role.
45
+ - **param**: `req` (Object) - HTTP request.
46
+ - **param**: `meta` (Object) - Entity meta definition.
47
+ - **returns**: `[mode, view]` - Tuple of allowed modes (e.g., "crud") and view ID.
48
+
49
+ #### `check_user_role(req, meta, mode, view)`
50
+ Verifies if the current user has specific access rights.
51
+ - **param**: `mode` (string) - Required operation mode (c/r/u/d).
52
+ - **param**: `view` (string) - Required view access.
53
+ - **returns**: `boolean` - True if permitted.
54
+
55
+ ```javascript
56
+ if (check_user_role(req, productMeta, 'c', '*')) {
57
+ // User can create products
58
+ }
59
+ ```