@nocobase/utils 1.9.0-beta.8 → 2.0.0-alpha.10
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.
- package/lib/client.d.ts +2 -0
- package/lib/client.js +5 -1
- package/lib/common.d.ts +3 -0
- package/lib/common.js +29 -1
- package/lib/date.js +1 -1
- package/lib/index.d.ts +9 -7
- package/lib/index.js +15 -11
- package/lib/parse-bigint.d.ts +9 -0
- package/lib/parse-bigint.js +47 -0
- package/lib/transformFilter.d.ts +154 -0
- package/lib/transformFilter.js +128 -0
- package/lib/variable-usage.d.ts +23 -0
- package/lib/variable-usage.js +138 -0
- package/package.json +2 -2
package/lib/client.d.ts
CHANGED
|
@@ -29,4 +29,6 @@ export * from './parseHTML';
|
|
|
29
29
|
export * from './uid';
|
|
30
30
|
export * from './url';
|
|
31
31
|
export * from './transformMultiColumnToSingleColumn';
|
|
32
|
+
export * from './transformFilter';
|
|
33
|
+
export * from './variable-usage';
|
|
32
34
|
export { dayjs, lodash, getDayRangeByParams, getOffsetRangeByParams };
|
package/lib/client.js
CHANGED
|
@@ -66,6 +66,8 @@ __reExport(client_exports, require("./parseHTML"), module.exports);
|
|
|
66
66
|
__reExport(client_exports, require("./uid"), module.exports);
|
|
67
67
|
__reExport(client_exports, require("./url"), module.exports);
|
|
68
68
|
__reExport(client_exports, require("./transformMultiColumnToSingleColumn"), module.exports);
|
|
69
|
+
__reExport(client_exports, require("./transformFilter"), module.exports);
|
|
70
|
+
__reExport(client_exports, require("./variable-usage"), module.exports);
|
|
69
71
|
// Annotate the CommonJS export names for ESM import in node:
|
|
70
72
|
0 && (module.exports = {
|
|
71
73
|
dayjs,
|
|
@@ -91,5 +93,7 @@ __reExport(client_exports, require("./transformMultiColumnToSingleColumn"), modu
|
|
|
91
93
|
...require("./parseHTML"),
|
|
92
94
|
...require("./uid"),
|
|
93
95
|
...require("./url"),
|
|
94
|
-
...require("./transformMultiColumnToSingleColumn")
|
|
96
|
+
...require("./transformMultiColumnToSingleColumn"),
|
|
97
|
+
...require("./transformFilter"),
|
|
98
|
+
...require("./variable-usage")
|
|
95
99
|
});
|
package/lib/common.d.ts
CHANGED
|
@@ -33,3 +33,6 @@ export declare function treeFind<T = any>(tree: T | T[], callback: (node: T) =>
|
|
|
33
33
|
*/
|
|
34
34
|
export declare function sortTree(tree: any[], sortBy: string | Function, childrenKey?: string, isAsc?: boolean): any;
|
|
35
35
|
export declare function sleep(ms: number): Promise<void>;
|
|
36
|
+
export declare function isEmptyFilter(obj: any): boolean;
|
|
37
|
+
export declare const removeNullCondition: (filter: any, customFlat?: any) => any;
|
|
38
|
+
export * from './transformFilter';
|
package/lib/common.js
CHANGED
|
@@ -26,6 +26,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
26
26
|
}
|
|
27
27
|
return to;
|
|
28
28
|
};
|
|
29
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
29
30
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
30
31
|
// If the importer is in node compatibility mode or this is not an ESM
|
|
31
32
|
// file that has been converted to a CommonJS file using a Babel-
|
|
@@ -40,15 +41,19 @@ __export(common_exports, {
|
|
|
40
41
|
hasEmptyValue: () => hasEmptyValue,
|
|
41
42
|
isArray: () => isArray,
|
|
42
43
|
isEmpty: () => isEmpty,
|
|
44
|
+
isEmptyFilter: () => isEmptyFilter,
|
|
43
45
|
isPlainObject: () => isPlainObject,
|
|
44
46
|
isString: () => isString,
|
|
45
47
|
nextTick: () => nextTick,
|
|
48
|
+
removeNullCondition: () => removeNullCondition,
|
|
46
49
|
sleep: () => sleep,
|
|
47
50
|
sortTree: () => sortTree,
|
|
48
51
|
treeFind: () => treeFind
|
|
49
52
|
});
|
|
50
53
|
module.exports = __toCommonJS(common_exports);
|
|
51
54
|
var import_lodash = __toESM(require("lodash"));
|
|
55
|
+
var import_flat = __toESM(require("flat"));
|
|
56
|
+
__reExport(common_exports, require("./transformFilter"), module.exports);
|
|
52
57
|
const isString = /* @__PURE__ */ __name((value) => {
|
|
53
58
|
return typeof value === "string";
|
|
54
59
|
}, "isString");
|
|
@@ -131,15 +136,38 @@ function sleep(ms) {
|
|
|
131
136
|
});
|
|
132
137
|
}
|
|
133
138
|
__name(sleep, "sleep");
|
|
139
|
+
function isEmptyFilter(obj) {
|
|
140
|
+
if (!obj) return true;
|
|
141
|
+
if ("$and" in obj && import_lodash.default.isEmpty(obj.$and) || "$or" in obj && import_lodash.default.isEmpty(obj.$or)) {
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
__name(isEmptyFilter, "isEmptyFilter");
|
|
147
|
+
const removeNullCondition = /* @__PURE__ */ __name((filter, customFlat = import_flat.default) => {
|
|
148
|
+
const items = customFlat(filter || {});
|
|
149
|
+
const values = {};
|
|
150
|
+
for (const key in items) {
|
|
151
|
+
const value = items[key];
|
|
152
|
+
if (value != null && !isEmpty(value) && value !== "") {
|
|
153
|
+
values[key] = value;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const result = customFlat.unflatten(values);
|
|
157
|
+
return import_lodash.default.isEmpty(result) ? void 0 : result;
|
|
158
|
+
}, "removeNullCondition");
|
|
134
159
|
// Annotate the CommonJS export names for ESM import in node:
|
|
135
160
|
0 && (module.exports = {
|
|
136
161
|
hasEmptyValue,
|
|
137
162
|
isArray,
|
|
138
163
|
isEmpty,
|
|
164
|
+
isEmptyFilter,
|
|
139
165
|
isPlainObject,
|
|
140
166
|
isString,
|
|
141
167
|
nextTick,
|
|
168
|
+
removeNullCondition,
|
|
142
169
|
sleep,
|
|
143
170
|
sortTree,
|
|
144
|
-
treeFind
|
|
171
|
+
treeFind,
|
|
172
|
+
...require("./transformFilter")
|
|
145
173
|
});
|
package/lib/date.js
CHANGED
|
@@ -111,7 +111,7 @@ const toMoment = /* @__PURE__ */ __name((val, options) => {
|
|
|
111
111
|
return import_dayjs.dayjs.utc(dateString, "YYYY-MM-DD");
|
|
112
112
|
}
|
|
113
113
|
if (!utc) {
|
|
114
|
-
return import_dayjs.dayjs
|
|
114
|
+
return (0, import_dayjs.dayjs)(val);
|
|
115
115
|
}
|
|
116
116
|
if (import_dayjs.dayjs.isDayjs(val)) {
|
|
117
117
|
return offset ? val.utcOffset(offsetFromString(offset)) : val;
|
package/lib/index.d.ts
CHANGED
|
@@ -7,17 +7,19 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
import lodash from 'lodash';
|
|
10
|
-
export {
|
|
11
|
-
export { dayjs } from './dayjs';
|
|
10
|
+
export { Schema } from '@formily/json-schema';
|
|
12
11
|
export * from './assign';
|
|
13
12
|
export * from './collections-graph';
|
|
14
13
|
export * from './common';
|
|
15
14
|
export * from './crypto';
|
|
16
15
|
export * from './date';
|
|
16
|
+
export * from './dateRangeUtils';
|
|
17
17
|
export * from './dayjs';
|
|
18
|
+
export { dayjs } from './dayjs';
|
|
18
19
|
export * from './forEach';
|
|
19
20
|
export * from './fs-exists';
|
|
20
21
|
export * from './handlebars';
|
|
22
|
+
export * from './i18n';
|
|
21
23
|
export * from './isValidFilter';
|
|
22
24
|
export * from './json-templates';
|
|
23
25
|
export * from './koa-multer';
|
|
@@ -26,17 +28,17 @@ export * from './merge';
|
|
|
26
28
|
export * from './mixin';
|
|
27
29
|
export * from './mixin/AsyncEmitter';
|
|
28
30
|
export * from './number';
|
|
31
|
+
export * from './object-to-cli-args';
|
|
32
|
+
export * from './parse-bigint';
|
|
29
33
|
export * from './parse-date';
|
|
30
34
|
export * from './parse-filter';
|
|
35
|
+
export * from './parsedValue';
|
|
31
36
|
export * from './perf-hooks';
|
|
32
37
|
export * from './registry';
|
|
33
38
|
export * from './requireModule';
|
|
34
39
|
export * from './toposort';
|
|
35
40
|
export * from './uid';
|
|
36
41
|
export * from './url';
|
|
37
|
-
export * from './
|
|
42
|
+
export * from './variable-usage';
|
|
38
43
|
export * from './wrap-middleware';
|
|
39
|
-
export
|
|
40
|
-
export * from './parsedValue';
|
|
41
|
-
export * from './dateRangeUtils';
|
|
42
|
-
export { Schema } from '@formily/json-schema';
|
|
44
|
+
export { lodash };
|
package/lib/index.js
CHANGED
|
@@ -43,16 +43,19 @@ __export(src_exports, {
|
|
|
43
43
|
});
|
|
44
44
|
module.exports = __toCommonJS(src_exports);
|
|
45
45
|
var import_lodash = __toESM(require("lodash"));
|
|
46
|
-
var
|
|
46
|
+
var import_json_schema = require("@formily/json-schema");
|
|
47
47
|
__reExport(src_exports, require("./assign"), module.exports);
|
|
48
48
|
__reExport(src_exports, require("./collections-graph"), module.exports);
|
|
49
49
|
__reExport(src_exports, require("./common"), module.exports);
|
|
50
50
|
__reExport(src_exports, require("./crypto"), module.exports);
|
|
51
51
|
__reExport(src_exports, require("./date"), module.exports);
|
|
52
|
+
__reExport(src_exports, require("./dateRangeUtils"), module.exports);
|
|
52
53
|
__reExport(src_exports, require("./dayjs"), module.exports);
|
|
54
|
+
var import_dayjs = require("./dayjs");
|
|
53
55
|
__reExport(src_exports, require("./forEach"), module.exports);
|
|
54
56
|
__reExport(src_exports, require("./fs-exists"), module.exports);
|
|
55
57
|
__reExport(src_exports, require("./handlebars"), module.exports);
|
|
58
|
+
__reExport(src_exports, require("./i18n"), module.exports);
|
|
56
59
|
__reExport(src_exports, require("./isValidFilter"), module.exports);
|
|
57
60
|
__reExport(src_exports, require("./json-templates"), module.exports);
|
|
58
61
|
__reExport(src_exports, require("./koa-multer"), module.exports);
|
|
@@ -61,20 +64,19 @@ __reExport(src_exports, require("./merge"), module.exports);
|
|
|
61
64
|
__reExport(src_exports, require("./mixin"), module.exports);
|
|
62
65
|
__reExport(src_exports, require("./mixin/AsyncEmitter"), module.exports);
|
|
63
66
|
__reExport(src_exports, require("./number"), module.exports);
|
|
67
|
+
__reExport(src_exports, require("./object-to-cli-args"), module.exports);
|
|
68
|
+
__reExport(src_exports, require("./parse-bigint"), module.exports);
|
|
64
69
|
__reExport(src_exports, require("./parse-date"), module.exports);
|
|
65
70
|
__reExport(src_exports, require("./parse-filter"), module.exports);
|
|
71
|
+
__reExport(src_exports, require("./parsedValue"), module.exports);
|
|
66
72
|
__reExport(src_exports, require("./perf-hooks"), module.exports);
|
|
67
73
|
__reExport(src_exports, require("./registry"), module.exports);
|
|
68
74
|
__reExport(src_exports, require("./requireModule"), module.exports);
|
|
69
75
|
__reExport(src_exports, require("./toposort"), module.exports);
|
|
70
76
|
__reExport(src_exports, require("./uid"), module.exports);
|
|
71
77
|
__reExport(src_exports, require("./url"), module.exports);
|
|
72
|
-
__reExport(src_exports, require("./
|
|
78
|
+
__reExport(src_exports, require("./variable-usage"), module.exports);
|
|
73
79
|
__reExport(src_exports, require("./wrap-middleware"), module.exports);
|
|
74
|
-
__reExport(src_exports, require("./object-to-cli-args"), module.exports);
|
|
75
|
-
__reExport(src_exports, require("./parsedValue"), module.exports);
|
|
76
|
-
__reExport(src_exports, require("./dateRangeUtils"), module.exports);
|
|
77
|
-
var import_json_schema = require("@formily/json-schema");
|
|
78
80
|
// Annotate the CommonJS export names for ESM import in node:
|
|
79
81
|
0 && (module.exports = {
|
|
80
82
|
Schema,
|
|
@@ -85,10 +87,12 @@ var import_json_schema = require("@formily/json-schema");
|
|
|
85
87
|
...require("./common"),
|
|
86
88
|
...require("./crypto"),
|
|
87
89
|
...require("./date"),
|
|
90
|
+
...require("./dateRangeUtils"),
|
|
88
91
|
...require("./dayjs"),
|
|
89
92
|
...require("./forEach"),
|
|
90
93
|
...require("./fs-exists"),
|
|
91
94
|
...require("./handlebars"),
|
|
95
|
+
...require("./i18n"),
|
|
92
96
|
...require("./isValidFilter"),
|
|
93
97
|
...require("./json-templates"),
|
|
94
98
|
...require("./koa-multer"),
|
|
@@ -97,17 +101,17 @@ var import_json_schema = require("@formily/json-schema");
|
|
|
97
101
|
...require("./mixin"),
|
|
98
102
|
...require("./mixin/AsyncEmitter"),
|
|
99
103
|
...require("./number"),
|
|
104
|
+
...require("./object-to-cli-args"),
|
|
105
|
+
...require("./parse-bigint"),
|
|
100
106
|
...require("./parse-date"),
|
|
101
107
|
...require("./parse-filter"),
|
|
108
|
+
...require("./parsedValue"),
|
|
102
109
|
...require("./perf-hooks"),
|
|
103
110
|
...require("./registry"),
|
|
104
111
|
...require("./requireModule"),
|
|
105
112
|
...require("./toposort"),
|
|
106
113
|
...require("./uid"),
|
|
107
114
|
...require("./url"),
|
|
108
|
-
...require("./
|
|
109
|
-
...require("./wrap-middleware")
|
|
110
|
-
...require("./object-to-cli-args"),
|
|
111
|
-
...require("./parsedValue"),
|
|
112
|
-
...require("./dateRangeUtils")
|
|
115
|
+
...require("./variable-usage"),
|
|
116
|
+
...require("./wrap-middleware")
|
|
113
117
|
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
export declare const parseBigIntValue: (val: string | number) => string | number;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
15
|
+
var __export = (target, all) => {
|
|
16
|
+
for (var name in all)
|
|
17
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
18
|
+
};
|
|
19
|
+
var __copyProps = (to, from, except, desc) => {
|
|
20
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
21
|
+
for (let key of __getOwnPropNames(from))
|
|
22
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
23
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
24
|
+
}
|
|
25
|
+
return to;
|
|
26
|
+
};
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var parse_bigint_exports = {};
|
|
29
|
+
__export(parse_bigint_exports, {
|
|
30
|
+
parseBigIntValue: () => parseBigIntValue
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(parse_bigint_exports);
|
|
33
|
+
const parseBigIntValue = /* @__PURE__ */ __name((val) => {
|
|
34
|
+
if (val === null || val === void 0) {
|
|
35
|
+
return val;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const big = BigInt(val);
|
|
39
|
+
return big <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(big) : val;
|
|
40
|
+
} catch {
|
|
41
|
+
return val;
|
|
42
|
+
}
|
|
43
|
+
}, "parseBigIntValue");
|
|
44
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
45
|
+
0 && (module.exports = {
|
|
46
|
+
parseBigIntValue
|
|
47
|
+
});
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* 过滤器条件项接口
|
|
11
|
+
*/
|
|
12
|
+
export interface FilterCondition {
|
|
13
|
+
/** 字段名 */
|
|
14
|
+
path: string;
|
|
15
|
+
/** 值 */
|
|
16
|
+
value: any;
|
|
17
|
+
/** 操作符 */
|
|
18
|
+
operator: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 过滤器分组接口
|
|
22
|
+
*/
|
|
23
|
+
export interface FilterGroupType {
|
|
24
|
+
/** 逻辑操作符 */
|
|
25
|
+
logic: '$and' | '$or';
|
|
26
|
+
/** 条件项数组 */
|
|
27
|
+
items: (FilterCondition | FilterGroupType)[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 查询条件对象类型
|
|
31
|
+
*/
|
|
32
|
+
export type QueryCondition = {
|
|
33
|
+
[field: string]: {
|
|
34
|
+
[operator: string]: any;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* 查询对象类型
|
|
39
|
+
*/
|
|
40
|
+
export type QueryObject = {
|
|
41
|
+
[logic: string]: (QueryCondition | QueryObject)[];
|
|
42
|
+
} | QueryCondition;
|
|
43
|
+
/**
|
|
44
|
+
* 转换过滤器数据结构
|
|
45
|
+
*
|
|
46
|
+
* 将结构化的过滤器配置转换为查询对象格式
|
|
47
|
+
*
|
|
48
|
+
* @param filter - 过滤器配置对象
|
|
49
|
+
* @returns 转换后的查询对象
|
|
50
|
+
*
|
|
51
|
+
* @throws {Error} 当过滤器格式无效时抛出错误
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* // 简单条件
|
|
56
|
+
* const simpleFilter = {
|
|
57
|
+
* "logic": "$and",
|
|
58
|
+
* "items": [
|
|
59
|
+
* {
|
|
60
|
+
* "path": "name",
|
|
61
|
+
* "operator": "$eq",
|
|
62
|
+
* "value": "test"
|
|
63
|
+
* }
|
|
64
|
+
* ]
|
|
65
|
+
* };
|
|
66
|
+
*
|
|
67
|
+
* const result = transformFilter(simpleFilter);
|
|
68
|
+
* // 输出: {"$and":[{"name":{"$eq":"test"}}]}
|
|
69
|
+
*
|
|
70
|
+
* // 嵌套条件
|
|
71
|
+
* const nestedFilter = {
|
|
72
|
+
* "logic": "$or",
|
|
73
|
+
* "items": [
|
|
74
|
+
* {
|
|
75
|
+
* "path": "isAdmin",
|
|
76
|
+
* "operator": "$eq",
|
|
77
|
+
* "value": true
|
|
78
|
+
* },
|
|
79
|
+
* {
|
|
80
|
+
* "logic": "$and",
|
|
81
|
+
* "items": [
|
|
82
|
+
* {
|
|
83
|
+
* "path": "name",
|
|
84
|
+
* "operator": "$includes",
|
|
85
|
+
* "value": "NocoBase"
|
|
86
|
+
* },
|
|
87
|
+
* {
|
|
88
|
+
* "path": "age",
|
|
89
|
+
* "operator": "$gt",
|
|
90
|
+
* "value": 18
|
|
91
|
+
* }
|
|
92
|
+
* ]
|
|
93
|
+
* }
|
|
94
|
+
* ]
|
|
95
|
+
* };
|
|
96
|
+
*
|
|
97
|
+
* const nestedResult = transformFilter(nestedFilter);
|
|
98
|
+
* // 输出: {"$or":[{"isAdmin":{"$eq":true}},{"$and":[{"name":{"$includes":"NocoBase"}},{"age":{"$gt":18}}]}]}
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export declare function transformFilter(filter: FilterGroupType): QueryObject;
|
|
102
|
+
/**
|
|
103
|
+
* 条件评估器函数类型
|
|
104
|
+
*
|
|
105
|
+
* @param path - 左值(字段名)
|
|
106
|
+
* @param operator - 操作符
|
|
107
|
+
* @param value - 右值
|
|
108
|
+
* @returns 条件评估结果
|
|
109
|
+
*/
|
|
110
|
+
export type ConditionEvaluator = (path: string, operator: string, value: any) => boolean;
|
|
111
|
+
/**
|
|
112
|
+
* 评估过滤器条件
|
|
113
|
+
*
|
|
114
|
+
* 解析 FilterGroupType 类型的条件,根据提供的评估器函数计算每个条件的值,
|
|
115
|
+
* 然后按照逻辑操作符组合得出最终的布尔值结果。
|
|
116
|
+
*
|
|
117
|
+
* @param conditions - 过滤器条件配置对象
|
|
118
|
+
* @param evaluator - 条件评估器函数,用于计算 path、operator、value 的结果
|
|
119
|
+
* @returns 最终的布尔值结果
|
|
120
|
+
*
|
|
121
|
+
* @throws {Error} 当条件格式无效时抛出错误
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```typescript
|
|
125
|
+
* // 定义条件评估器
|
|
126
|
+
* const evaluator: ConditionEvaluator = (path, operator, value) => {
|
|
127
|
+
* // 这里实现具体的条件计算逻辑
|
|
128
|
+
* // 例如从上下文中获取字段值并与 value 比较
|
|
129
|
+
* const fieldValue = getFieldValue(path);
|
|
130
|
+
* return compareValues(fieldValue, operator, value);
|
|
131
|
+
* };
|
|
132
|
+
*
|
|
133
|
+
* // 评估条件
|
|
134
|
+
* const conditions = {
|
|
135
|
+
* logic: '$and',
|
|
136
|
+
* items: [
|
|
137
|
+
* {
|
|
138
|
+
* path: 'name',
|
|
139
|
+
* operator: '$eq',
|
|
140
|
+
* value: 'test'
|
|
141
|
+
* },
|
|
142
|
+
* {
|
|
143
|
+
* path: 'age',
|
|
144
|
+
* operator: '$gt',
|
|
145
|
+
* value: 18
|
|
146
|
+
* }
|
|
147
|
+
* ]
|
|
148
|
+
* };
|
|
149
|
+
*
|
|
150
|
+
* const result = evaluateConditions(conditions, evaluator);
|
|
151
|
+
* // 返回: boolean (根据评估器的具体实现)
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
export declare function evaluateConditions(conditions: FilterGroupType, evaluator: ConditionEvaluator): boolean;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
15
|
+
var __export = (target, all) => {
|
|
16
|
+
for (var name in all)
|
|
17
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
18
|
+
};
|
|
19
|
+
var __copyProps = (to, from, except, desc) => {
|
|
20
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
21
|
+
for (let key of __getOwnPropNames(from))
|
|
22
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
23
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
24
|
+
}
|
|
25
|
+
return to;
|
|
26
|
+
};
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var transformFilter_exports = {};
|
|
29
|
+
__export(transformFilter_exports, {
|
|
30
|
+
evaluateConditions: () => evaluateConditions,
|
|
31
|
+
transformFilter: () => transformFilter
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(transformFilter_exports);
|
|
34
|
+
function isFilterCondition(item) {
|
|
35
|
+
return "path" in item && "operator" in item && "value" in item;
|
|
36
|
+
}
|
|
37
|
+
__name(isFilterCondition, "isFilterCondition");
|
|
38
|
+
function isFilterGroup(item) {
|
|
39
|
+
return "logic" in item && "items" in item;
|
|
40
|
+
}
|
|
41
|
+
__name(isFilterGroup, "isFilterGroup");
|
|
42
|
+
function transformCondition(condition) {
|
|
43
|
+
const { path, operator, value } = condition;
|
|
44
|
+
return {
|
|
45
|
+
[path]: {
|
|
46
|
+
[operator]: value
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
__name(transformCondition, "transformCondition");
|
|
51
|
+
function transformGroup(group) {
|
|
52
|
+
const { logic, items } = group;
|
|
53
|
+
const transformedItems = items.map((item) => {
|
|
54
|
+
if (isFilterCondition(item)) {
|
|
55
|
+
return transformCondition(item);
|
|
56
|
+
} else if (isFilterGroup(item)) {
|
|
57
|
+
return transformGroup(item);
|
|
58
|
+
} else {
|
|
59
|
+
throw new Error("Invalid filter item type");
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
return {
|
|
63
|
+
[logic]: transformedItems
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
__name(transformGroup, "transformGroup");
|
|
67
|
+
function transformFilter(filter) {
|
|
68
|
+
if (!filter || typeof filter !== "object") {
|
|
69
|
+
throw new Error("Invalid filter: filter must be an object");
|
|
70
|
+
}
|
|
71
|
+
if (!isFilterGroup(filter)) {
|
|
72
|
+
throw new Error("Invalid filter: filter must have logic and items properties");
|
|
73
|
+
}
|
|
74
|
+
if (!Array.isArray(filter.items)) {
|
|
75
|
+
throw new Error("Invalid filter: items must be an array");
|
|
76
|
+
}
|
|
77
|
+
return transformGroup(filter);
|
|
78
|
+
}
|
|
79
|
+
__name(transformFilter, "transformFilter");
|
|
80
|
+
function evaluateCondition(condition, evaluator) {
|
|
81
|
+
const { path, operator, value } = condition;
|
|
82
|
+
return evaluator(path, operator, value);
|
|
83
|
+
}
|
|
84
|
+
__name(evaluateCondition, "evaluateCondition");
|
|
85
|
+
function evaluateGroup(group, evaluator) {
|
|
86
|
+
const { logic, items } = group;
|
|
87
|
+
if (!items || items.length === 0) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
const results = items.map((item) => {
|
|
91
|
+
if (isFilterCondition(item)) {
|
|
92
|
+
return evaluateCondition(item, evaluator);
|
|
93
|
+
} else if (isFilterGroup(item)) {
|
|
94
|
+
return evaluateGroup(item, evaluator);
|
|
95
|
+
} else {
|
|
96
|
+
throw new Error("Invalid filter item type");
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
if (logic === "$and") {
|
|
100
|
+
return results.every((result) => result === true);
|
|
101
|
+
} else if (logic === "$or") {
|
|
102
|
+
return results.some((result) => result === true);
|
|
103
|
+
} else {
|
|
104
|
+
throw new Error(`Unsupported logic operator: ${logic}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
__name(evaluateGroup, "evaluateGroup");
|
|
108
|
+
function evaluateConditions(conditions, evaluator) {
|
|
109
|
+
if (!conditions || typeof conditions !== "object") {
|
|
110
|
+
throw new Error("Invalid conditions: conditions must be an object");
|
|
111
|
+
}
|
|
112
|
+
if (!isFilterGroup(conditions)) {
|
|
113
|
+
throw new Error("Invalid conditions: conditions must have logic and items properties");
|
|
114
|
+
}
|
|
115
|
+
if (!Array.isArray(conditions.items)) {
|
|
116
|
+
throw new Error("Invalid conditions: items must be an array");
|
|
117
|
+
}
|
|
118
|
+
if (typeof evaluator !== "function") {
|
|
119
|
+
throw new Error("Invalid evaluator: evaluator must be a function");
|
|
120
|
+
}
|
|
121
|
+
return evaluateGroup(conditions, evaluator);
|
|
122
|
+
}
|
|
123
|
+
__name(evaluateConditions, "evaluateConditions");
|
|
124
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
125
|
+
0 && (module.exports = {
|
|
126
|
+
evaluateConditions,
|
|
127
|
+
transformFilter
|
|
128
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
export type JSONValue = string | {
|
|
10
|
+
[key: string]: JSONValue;
|
|
11
|
+
} | JSONValue[];
|
|
12
|
+
/**
|
|
13
|
+
* 提取模板中使用到的 ctx 顶层变量名集合。
|
|
14
|
+
* - 支持点语法与顶层括号变量:ctx.user / ctx["user"]
|
|
15
|
+
*/
|
|
16
|
+
export declare function extractUsedVariableNames(template: JSONValue): Set<string>;
|
|
17
|
+
/**
|
|
18
|
+
* 提取模板中使用到的 ctx 顶层变量与对应的子路径数组。
|
|
19
|
+
* - 返回 Map 形如:{ user: ['id', 'roles[0].name'], view: ['record.id'] }
|
|
20
|
+
* - 兼容:顶层括号变量(ctx["user"])、首段括号键与数字索引(如 ["roles"][0].name -> roles[0].name)
|
|
21
|
+
* - 方法调用:记录空字符串以触发服务端 attach(例如 ctx.twice(21) => { twice: [''] })
|
|
22
|
+
*/
|
|
23
|
+
export declare function extractUsedVariablePaths(template: JSONValue): Record<string, string[]>;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
15
|
+
var __export = (target, all) => {
|
|
16
|
+
for (var name in all)
|
|
17
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
18
|
+
};
|
|
19
|
+
var __copyProps = (to, from, except, desc) => {
|
|
20
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
21
|
+
for (let key of __getOwnPropNames(from))
|
|
22
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
23
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
24
|
+
}
|
|
25
|
+
return to;
|
|
26
|
+
};
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var variable_usage_exports = {};
|
|
29
|
+
__export(variable_usage_exports, {
|
|
30
|
+
extractUsedVariableNames: () => extractUsedVariableNames,
|
|
31
|
+
extractUsedVariablePaths: () => extractUsedVariablePaths
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(variable_usage_exports);
|
|
34
|
+
function extractUsedVariableNames(template) {
|
|
35
|
+
const result = /* @__PURE__ */ new Set();
|
|
36
|
+
const visit = /* @__PURE__ */ __name((src) => {
|
|
37
|
+
if (typeof src === "string") {
|
|
38
|
+
const regex = /\{\{\s*([^}]+?)\s*\}\}/g;
|
|
39
|
+
let m;
|
|
40
|
+
while ((m = regex.exec(src)) !== null) {
|
|
41
|
+
const expr = m[1];
|
|
42
|
+
const pathRegex = /ctx\.([a-zA-Z_$][a-zA-Z0-9_$]*)/g;
|
|
43
|
+
let pm;
|
|
44
|
+
while ((pm = pathRegex.exec(expr)) !== null) {
|
|
45
|
+
result.add(pm[1]);
|
|
46
|
+
}
|
|
47
|
+
const bracketVarRegex = /ctx\[\s*(["'])\s*([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\1\s*\]/g;
|
|
48
|
+
let bm;
|
|
49
|
+
while ((bm = bracketVarRegex.exec(expr)) !== null) {
|
|
50
|
+
result.add(bm[2]);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
} else if (Array.isArray(src)) {
|
|
54
|
+
src.forEach(visit);
|
|
55
|
+
} else if (src && typeof src === "object") {
|
|
56
|
+
Object.values(src).forEach(visit);
|
|
57
|
+
}
|
|
58
|
+
}, "visit");
|
|
59
|
+
visit(template);
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
__name(extractUsedVariableNames, "extractUsedVariableNames");
|
|
63
|
+
function extractUsedVariablePaths(template) {
|
|
64
|
+
const usage = {};
|
|
65
|
+
const visit = /* @__PURE__ */ __name((src) => {
|
|
66
|
+
if (typeof src === "string") {
|
|
67
|
+
const regex = /\{\{\s*([^}]+?)\s*\}\}/g;
|
|
68
|
+
let m;
|
|
69
|
+
while ((m = regex.exec(src)) !== null) {
|
|
70
|
+
const expr = m[1];
|
|
71
|
+
const pathRegex = /ctx\.([a-zA-Z_$][a-zA-Z0-9_$]*)([^\s)]*)/g;
|
|
72
|
+
let pm;
|
|
73
|
+
while ((pm = pathRegex.exec(expr)) !== null) {
|
|
74
|
+
const varName = pm[1];
|
|
75
|
+
const after = pm[2] || "";
|
|
76
|
+
usage[varName] = usage[varName] || [];
|
|
77
|
+
if (after.startsWith(".")) {
|
|
78
|
+
usage[varName].push(after.slice(1));
|
|
79
|
+
} else if (after.startsWith("[")) {
|
|
80
|
+
const mm = after.match(/^\[\s*(["'])\s*([^'"\]]+)\s*\1\s*\](.*)$/);
|
|
81
|
+
if (mm) {
|
|
82
|
+
const first = mm[2];
|
|
83
|
+
const rest = mm[3] || "";
|
|
84
|
+
usage[varName].push(`${first}${rest}`);
|
|
85
|
+
} else {
|
|
86
|
+
const mn = after.match(/^\[(\d+)\](.*)$/);
|
|
87
|
+
if (mn) {
|
|
88
|
+
const idx = mn[1];
|
|
89
|
+
const rest = mn[2] || "";
|
|
90
|
+
usage[varName].push(`[${idx}]${rest}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
} else if (after.startsWith("(")) {
|
|
94
|
+
if (!usage[varName].length) usage[varName].push("");
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const bracketVarRegex = /ctx\[\s*(["'])\s*([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\1\s*\]([^\s)]*)/g;
|
|
98
|
+
let bm;
|
|
99
|
+
while ((bm = bracketVarRegex.exec(expr)) !== null) {
|
|
100
|
+
const varName = bm[2];
|
|
101
|
+
const after = bm[3] || "";
|
|
102
|
+
usage[varName] = usage[varName] || [];
|
|
103
|
+
if (after.startsWith(".")) {
|
|
104
|
+
usage[varName].push(after.slice(1));
|
|
105
|
+
} else if (after.startsWith("[")) {
|
|
106
|
+
const mm = after.match(/^\[\s*(["'])\s*([^'"\]]+)\s*\1\s*\](.*)$/);
|
|
107
|
+
if (mm) {
|
|
108
|
+
const first = mm[2];
|
|
109
|
+
const rest = mm[3] || "";
|
|
110
|
+
usage[varName].push(`${first}${rest}`);
|
|
111
|
+
} else {
|
|
112
|
+
const mn = after.match(/^\[(\d+)\](.*)$/);
|
|
113
|
+
if (mn) {
|
|
114
|
+
const idx = mn[1];
|
|
115
|
+
const rest = mn[2] || "";
|
|
116
|
+
usage[varName].push(`[${idx}]${rest}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
} else if (after.startsWith("(")) {
|
|
120
|
+
if (!usage[varName].length) usage[varName].push("");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
} else if (Array.isArray(src)) {
|
|
125
|
+
src.forEach(visit);
|
|
126
|
+
} else if (src && typeof src === "object") {
|
|
127
|
+
Object.values(src).forEach(visit);
|
|
128
|
+
}
|
|
129
|
+
}, "visit");
|
|
130
|
+
visit(template);
|
|
131
|
+
return usage;
|
|
132
|
+
}
|
|
133
|
+
__name(extractUsedVariablePaths, "extractUsedVariablePaths");
|
|
134
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
135
|
+
0 && (module.exports = {
|
|
136
|
+
extractUsedVariableNames,
|
|
137
|
+
extractUsedVariablePaths
|
|
138
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/utils",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-alpha.10",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "./lib/index.d.ts",
|
|
6
6
|
"license": "AGPL-3.0",
|
|
@@ -16,5 +16,5 @@
|
|
|
16
16
|
"multer": "^1.4.5-lts.2",
|
|
17
17
|
"object-path": "^0.11.8"
|
|
18
18
|
},
|
|
19
|
-
"gitHead": "
|
|
19
|
+
"gitHead": "6422cfb6fa6c8450de2efa3294fd29a28b228990"
|
|
20
20
|
}
|