@usertour/helpers 0.0.15 → 0.0.17
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/dist/__tests__/attribute.test.cjs +1036 -0
- package/dist/__tests__/attribute.test.d.cts +2 -0
- package/dist/__tests__/attribute.test.d.ts +2 -0
- package/dist/__tests__/attribute.test.js +802 -0
- package/dist/__tests__/time.test.cjs +73 -0
- package/dist/__tests__/time.test.d.cts +2 -0
- package/dist/__tests__/time.test.d.ts +2 -0
- package/dist/__tests__/time.test.js +48 -0
- package/dist/__tests__/url.test.cjs +259 -0
- package/dist/__tests__/url.test.d.cts +2 -0
- package/dist/__tests__/url.test.d.ts +2 -0
- package/dist/__tests__/url.test.js +197 -0
- package/dist/{chunk-B4DTY6GN.js → chunk-4LLDSAHJ.js} +0 -12
- package/dist/chunk-7CC4WXB3.js +60 -0
- package/dist/chunk-7ODE2AIC.js +0 -0
- package/dist/{chunk-IZFZYGPU.js → chunk-BC7KXBMF.js} +5 -56
- package/dist/chunk-CEK3SCQO.js +31 -0
- package/dist/chunk-PBZSPV5R.js +239 -0
- package/dist/conditions/attribute.cjs +264 -0
- package/dist/conditions/attribute.d.cts +28 -0
- package/dist/conditions/attribute.d.ts +28 -0
- package/dist/conditions/attribute.js +9 -0
- package/dist/conditions/condition.cjs +95 -0
- package/dist/{conditions.d.ts → conditions/condition.d.cts} +1 -2
- package/dist/{conditions.d.cts → conditions/condition.d.ts} +1 -2
- package/dist/conditions/condition.js +9 -0
- package/dist/conditions/index.cjs +379 -0
- package/dist/conditions/index.d.cts +6 -0
- package/dist/conditions/index.d.ts +6 -0
- package/dist/conditions/index.js +24 -0
- package/dist/conditions/time.cjs +55 -0
- package/dist/conditions/time.d.cts +10 -0
- package/dist/conditions/time.d.ts +10 -0
- package/dist/conditions/time.js +7 -0
- package/dist/{conditions.cjs → conditions/url.cjs} +9 -71
- package/dist/conditions/url.d.cts +6 -0
- package/dist/conditions/url.d.ts +6 -0
- package/dist/conditions/url.js +9 -0
- package/dist/content.cjs +0 -13
- package/dist/content.d.cts +1 -2
- package/dist/content.d.ts +1 -2
- package/dist/content.js +1 -3
- package/dist/index.cjs +261 -54
- package/dist/index.d.cts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +19 -8
- package/package.json +15 -9
- package/dist/conditions.js +0 -11
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
// src/conditions.ts
|
|
2
|
-
import isEqual from "fast-deep-equal";
|
|
1
|
+
// src/conditions/url.ts
|
|
3
2
|
var parseUrl = (url) => {
|
|
4
3
|
const urlPatterns = url.match(/^(([a-z\d]+):\/\/)?([^/?#]+)?(\/[^?#]*)?(\?([^#]*))?(#.*)?$/i);
|
|
5
4
|
if (!urlPatterns) {
|
|
@@ -60,62 +59,12 @@ var isMatchUrlPattern = (_url, includes, excludes) => {
|
|
|
60
59
|
}) : false;
|
|
61
60
|
return isMatchIncludesConditions && !isMatchExcludesConditions;
|
|
62
61
|
};
|
|
63
|
-
var
|
|
64
|
-
const {
|
|
65
|
-
|
|
66
|
-
if (!isEqual(others2, others1)) {
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
for (const key in data) {
|
|
70
|
-
if (!isEqual(data[key], data2[key])) {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return true;
|
|
75
|
-
};
|
|
76
|
-
var conditionsIsSame = (rr1, rr2) => {
|
|
77
|
-
const r1 = [...rr1];
|
|
78
|
-
const r2 = [...rr2];
|
|
79
|
-
if (r1.length === 0 && r2.length === 0) {
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
if (r1.length !== r2.length) {
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
const group1 = r1.filter((item) => item.type === "group");
|
|
86
|
-
const group2 = r2.filter((item) => item.type === "group");
|
|
87
|
-
if (group1.length !== group2.length) {
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
|
-
for (let index = 0; index < r1.length; index++) {
|
|
91
|
-
const item1 = r1[index];
|
|
92
|
-
const item2 = r2[index];
|
|
93
|
-
if (!item1 || !item2) {
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
if (item1.type === "group") {
|
|
97
|
-
if (!item2.conditions) {
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
const c1 = item1.conditions;
|
|
101
|
-
const c2 = item2.conditions;
|
|
102
|
-
if (item1.operators !== item2.operators) {
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
if (!conditionsIsSame(c1, c2)) {
|
|
106
|
-
return false;
|
|
107
|
-
}
|
|
108
|
-
} else {
|
|
109
|
-
if (!compareConditionsItem(item1, item2)) {
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return true;
|
|
62
|
+
var evaluateUrlCondition = (rules, url) => {
|
|
63
|
+
const { excludes, includes } = rules.data;
|
|
64
|
+
return isMatchUrlPattern(url, includes, excludes);
|
|
115
65
|
};
|
|
116
66
|
|
|
117
67
|
export {
|
|
118
|
-
isEqual,
|
|
119
68
|
isMatchUrlPattern,
|
|
120
|
-
|
|
69
|
+
evaluateUrlCondition
|
|
121
70
|
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// src/conditions/time.ts
|
|
2
|
+
import { isAfter, isBefore, isValid, parseISO } from "date-fns";
|
|
3
|
+
var evaluateTimeCondition = (rules) => {
|
|
4
|
+
try {
|
|
5
|
+
const { endDate, endDateHour, endDateMinute, startDate, startDateHour, startDateMinute } = rules.data || {};
|
|
6
|
+
if (!startDate || !startDateHour || !startDateMinute) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
const startTimeString = `${startDate}T${startDateHour.padStart(2, "0")}:${startDateMinute.padStart(2, "0")}:00`;
|
|
10
|
+
const startTime = parseISO(startTimeString);
|
|
11
|
+
if (!isValid(startTime)) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
const now = /* @__PURE__ */ new Date();
|
|
15
|
+
if (!endDate || !endDateHour || !endDateMinute) {
|
|
16
|
+
return isAfter(now, startTime);
|
|
17
|
+
}
|
|
18
|
+
const endTimeString = `${endDate}T${endDateHour.padStart(2, "0")}:${endDateMinute.padStart(2, "0")}:00`;
|
|
19
|
+
const endTime = parseISO(endTimeString);
|
|
20
|
+
if (!isValid(endTime)) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return isAfter(now, startTime) && isBefore(now, endTime);
|
|
24
|
+
} catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export {
|
|
30
|
+
evaluateTimeCondition
|
|
31
|
+
};
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
// src/conditions/attribute.ts
|
|
2
|
+
import { BizAttributeTypes } from "@usertour/types";
|
|
3
|
+
import { subDays, startOfDay, endOfDay } from "date-fns";
|
|
4
|
+
function evaluateFilterConditions(conditions, attributes, userAttributes) {
|
|
5
|
+
if (!conditions || !conditions.length) {
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
const result = evaluateAttributeConditionsGroup(conditions, attributes, userAttributes);
|
|
9
|
+
return evaluateFilterResult(result);
|
|
10
|
+
}
|
|
11
|
+
function evaluateAttributeConditionsGroup(conditions, attributes, userAttributes) {
|
|
12
|
+
if (!conditions || !conditions.length) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
const AND = [];
|
|
16
|
+
const OR = [];
|
|
17
|
+
for (const condition of conditions) {
|
|
18
|
+
const { operators } = condition;
|
|
19
|
+
const item = condition.type !== "group" ? evaluateAttributeCondition(condition, attributes, userAttributes) : evaluateAttributeConditionsGroup(condition.conditions || [], attributes, userAttributes);
|
|
20
|
+
if (!item) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (operators === "and") {
|
|
24
|
+
AND.push(item);
|
|
25
|
+
} else {
|
|
26
|
+
OR.push(item);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const filter = {};
|
|
30
|
+
if (AND.length > 0) {
|
|
31
|
+
filter.AND = AND;
|
|
32
|
+
}
|
|
33
|
+
if (OR.length > 0) {
|
|
34
|
+
filter.OR = OR;
|
|
35
|
+
}
|
|
36
|
+
if (AND.length === 0 && OR.length === 0) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
return filter;
|
|
40
|
+
}
|
|
41
|
+
function evaluateAttributeCondition(condition, attributes, userAttributes) {
|
|
42
|
+
const { data } = condition;
|
|
43
|
+
if (!data) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
const { logic, value, attrId, value2, listValues = [] } = data;
|
|
47
|
+
if (!attrId) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
const attr = attributes.find((attr2) => attr2.id === attrId);
|
|
51
|
+
if (!attr) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
const actualValue = getAttributeValue(attr.codeName, userAttributes);
|
|
55
|
+
if (attr.dataType === BizAttributeTypes.String) {
|
|
56
|
+
return evaluateStringCondition(logic, actualValue, value);
|
|
57
|
+
}
|
|
58
|
+
if (attr.dataType === BizAttributeTypes.Number) {
|
|
59
|
+
return evaluateNumberCondition(logic, actualValue, value, value2);
|
|
60
|
+
}
|
|
61
|
+
if (attr.dataType === BizAttributeTypes.Boolean) {
|
|
62
|
+
return evaluateBooleanCondition(logic, actualValue);
|
|
63
|
+
}
|
|
64
|
+
if (attr.dataType === BizAttributeTypes.List) {
|
|
65
|
+
return evaluateListCondition(logic, actualValue, listValues);
|
|
66
|
+
}
|
|
67
|
+
if (attr.dataType === BizAttributeTypes.DateTime) {
|
|
68
|
+
return evaluateDateTimeCondition(logic, actualValue, value);
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
function getAttributeValue(codeName, userAttributes) {
|
|
73
|
+
return userAttributes == null ? void 0 : userAttributes[codeName];
|
|
74
|
+
}
|
|
75
|
+
function evaluateStringCondition(logic, actualValue, expectedValue) {
|
|
76
|
+
const stringValue = actualValue === null || actualValue === void 0 ? "" : String(actualValue);
|
|
77
|
+
switch (logic) {
|
|
78
|
+
case "is":
|
|
79
|
+
return stringValue === expectedValue;
|
|
80
|
+
case "not":
|
|
81
|
+
return stringValue !== expectedValue;
|
|
82
|
+
case "contains":
|
|
83
|
+
return stringValue.includes(expectedValue);
|
|
84
|
+
case "notContain":
|
|
85
|
+
return !stringValue.includes(expectedValue);
|
|
86
|
+
case "startsWith":
|
|
87
|
+
return stringValue.startsWith(expectedValue);
|
|
88
|
+
case "endsWith":
|
|
89
|
+
return stringValue.endsWith(expectedValue);
|
|
90
|
+
case "empty": {
|
|
91
|
+
const isEmpty = !stringValue || stringValue === "";
|
|
92
|
+
return isEmpty;
|
|
93
|
+
}
|
|
94
|
+
case "any":
|
|
95
|
+
return Boolean(stringValue && stringValue !== "");
|
|
96
|
+
default:
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function evaluateNumberCondition(logic, actualValue, expectedValue, expectedValue2) {
|
|
101
|
+
const numValue = Number(actualValue);
|
|
102
|
+
const numValue2 = Number(expectedValue2);
|
|
103
|
+
if (Number.isNaN(numValue)) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
switch (logic) {
|
|
107
|
+
case "is":
|
|
108
|
+
return numValue === expectedValue;
|
|
109
|
+
case "not":
|
|
110
|
+
return numValue !== expectedValue;
|
|
111
|
+
case "isLessThan":
|
|
112
|
+
return numValue < expectedValue;
|
|
113
|
+
case "isLessThanOrEqualTo":
|
|
114
|
+
return numValue <= expectedValue;
|
|
115
|
+
case "isGreaterThan":
|
|
116
|
+
return numValue > expectedValue;
|
|
117
|
+
case "isGreaterThanOrEqualTo":
|
|
118
|
+
return numValue >= expectedValue;
|
|
119
|
+
case "between":
|
|
120
|
+
return numValue >= expectedValue && numValue <= numValue2;
|
|
121
|
+
case "empty":
|
|
122
|
+
return actualValue === null || actualValue === void 0 || actualValue === "";
|
|
123
|
+
case "any":
|
|
124
|
+
return actualValue !== null && actualValue !== void 0 && actualValue !== "";
|
|
125
|
+
default:
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function evaluateBooleanCondition(logic, actualValue) {
|
|
130
|
+
switch (logic) {
|
|
131
|
+
case "true":
|
|
132
|
+
return actualValue === true;
|
|
133
|
+
case "false":
|
|
134
|
+
return actualValue === false;
|
|
135
|
+
case "empty":
|
|
136
|
+
return actualValue === null || actualValue === void 0 || actualValue === "";
|
|
137
|
+
case "any":
|
|
138
|
+
return actualValue !== null && actualValue !== void 0 && actualValue !== "";
|
|
139
|
+
default:
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function evaluateListCondition(logic, actualValue, expectedValues) {
|
|
144
|
+
const arrayValue = Array.isArray(actualValue) ? actualValue : [];
|
|
145
|
+
if (logic === "empty" || logic === "any") {
|
|
146
|
+
switch (logic) {
|
|
147
|
+
case "empty":
|
|
148
|
+
return !arrayValue || arrayValue.length === 0;
|
|
149
|
+
case "any":
|
|
150
|
+
return arrayValue && arrayValue.length > 0;
|
|
151
|
+
default:
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const filteredValues = expectedValues.filter(
|
|
156
|
+
(value) => value !== null && value !== void 0 && value !== ""
|
|
157
|
+
);
|
|
158
|
+
if (!filteredValues.length) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
switch (logic) {
|
|
162
|
+
case "includesAtLeastOne":
|
|
163
|
+
return filteredValues.some((value) => arrayValue.includes(value));
|
|
164
|
+
case "includesAll":
|
|
165
|
+
return filteredValues.every((value) => arrayValue.includes(value));
|
|
166
|
+
case "notIncludesAtLeastOne":
|
|
167
|
+
return !filteredValues.some((value) => arrayValue.includes(value));
|
|
168
|
+
case "notIncludesAll":
|
|
169
|
+
return !filteredValues.every((value) => arrayValue.includes(value));
|
|
170
|
+
default:
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function evaluateDateTimeCondition(logic, actualValue, expectedValue) {
|
|
175
|
+
const actualDate = actualValue ? new Date(actualValue) : null;
|
|
176
|
+
const now = /* @__PURE__ */ new Date();
|
|
177
|
+
if (!actualDate || Number.isNaN(actualDate.getTime())) {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
switch (logic) {
|
|
181
|
+
case "lessThan": {
|
|
182
|
+
const targetDate = subDays(now, Number(expectedValue));
|
|
183
|
+
return actualDate >= targetDate;
|
|
184
|
+
}
|
|
185
|
+
case "exactly": {
|
|
186
|
+
const targetDate = subDays(now, Number(expectedValue));
|
|
187
|
+
const start = startOfDay(targetDate);
|
|
188
|
+
const end = endOfDay(targetDate);
|
|
189
|
+
return actualDate >= start && actualDate <= end;
|
|
190
|
+
}
|
|
191
|
+
case "moreThan": {
|
|
192
|
+
const targetDate = subDays(now, Number(expectedValue));
|
|
193
|
+
return actualDate <= targetDate;
|
|
194
|
+
}
|
|
195
|
+
case "before": {
|
|
196
|
+
const expectedDate = new Date(expectedValue);
|
|
197
|
+
return actualDate <= expectedDate;
|
|
198
|
+
}
|
|
199
|
+
case "on": {
|
|
200
|
+
const expectedDateOn = new Date(expectedValue);
|
|
201
|
+
const start = startOfDay(expectedDateOn);
|
|
202
|
+
const end = endOfDay(expectedDateOn);
|
|
203
|
+
return actualDate >= start && actualDate <= end;
|
|
204
|
+
}
|
|
205
|
+
case "after": {
|
|
206
|
+
const expectedDateAfter = new Date(expectedValue);
|
|
207
|
+
return actualDate >= expectedDateAfter;
|
|
208
|
+
}
|
|
209
|
+
case "empty":
|
|
210
|
+
return !actualValue || actualValue === "";
|
|
211
|
+
case "any":
|
|
212
|
+
return actualValue && actualValue !== "";
|
|
213
|
+
default:
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function evaluateFilterResult(filter) {
|
|
218
|
+
if (!filter) {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
if (filter.AND) {
|
|
222
|
+
return filter.AND.every((item) => evaluateFilterResult(item));
|
|
223
|
+
}
|
|
224
|
+
if (filter.OR) {
|
|
225
|
+
return filter.OR.some((item) => evaluateFilterResult(item));
|
|
226
|
+
}
|
|
227
|
+
if (typeof filter === "boolean") {
|
|
228
|
+
return filter;
|
|
229
|
+
}
|
|
230
|
+
if (typeof filter === "object") {
|
|
231
|
+
return true;
|
|
232
|
+
}
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export {
|
|
237
|
+
evaluateFilterConditions,
|
|
238
|
+
evaluateAttributeCondition
|
|
239
|
+
};
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/conditions/attribute.ts
|
|
21
|
+
var attribute_exports = {};
|
|
22
|
+
__export(attribute_exports, {
|
|
23
|
+
evaluateAttributeCondition: () => evaluateAttributeCondition,
|
|
24
|
+
evaluateFilterConditions: () => evaluateFilterConditions
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(attribute_exports);
|
|
27
|
+
var import_types = require("@usertour/types");
|
|
28
|
+
var import_date_fns = require("date-fns");
|
|
29
|
+
function evaluateFilterConditions(conditions, attributes, userAttributes) {
|
|
30
|
+
if (!conditions || !conditions.length) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
const result = evaluateAttributeConditionsGroup(conditions, attributes, userAttributes);
|
|
34
|
+
return evaluateFilterResult(result);
|
|
35
|
+
}
|
|
36
|
+
function evaluateAttributeConditionsGroup(conditions, attributes, userAttributes) {
|
|
37
|
+
if (!conditions || !conditions.length) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
const AND = [];
|
|
41
|
+
const OR = [];
|
|
42
|
+
for (const condition of conditions) {
|
|
43
|
+
const { operators } = condition;
|
|
44
|
+
const item = condition.type !== "group" ? evaluateAttributeCondition(condition, attributes, userAttributes) : evaluateAttributeConditionsGroup(condition.conditions || [], attributes, userAttributes);
|
|
45
|
+
if (!item) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (operators === "and") {
|
|
49
|
+
AND.push(item);
|
|
50
|
+
} else {
|
|
51
|
+
OR.push(item);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const filter = {};
|
|
55
|
+
if (AND.length > 0) {
|
|
56
|
+
filter.AND = AND;
|
|
57
|
+
}
|
|
58
|
+
if (OR.length > 0) {
|
|
59
|
+
filter.OR = OR;
|
|
60
|
+
}
|
|
61
|
+
if (AND.length === 0 && OR.length === 0) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
return filter;
|
|
65
|
+
}
|
|
66
|
+
function evaluateAttributeCondition(condition, attributes, userAttributes) {
|
|
67
|
+
const { data } = condition;
|
|
68
|
+
if (!data) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
const { logic, value, attrId, value2, listValues = [] } = data;
|
|
72
|
+
if (!attrId) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
const attr = attributes.find((attr2) => attr2.id === attrId);
|
|
76
|
+
if (!attr) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
const actualValue = getAttributeValue(attr.codeName, userAttributes);
|
|
80
|
+
if (attr.dataType === import_types.BizAttributeTypes.String) {
|
|
81
|
+
return evaluateStringCondition(logic, actualValue, value);
|
|
82
|
+
}
|
|
83
|
+
if (attr.dataType === import_types.BizAttributeTypes.Number) {
|
|
84
|
+
return evaluateNumberCondition(logic, actualValue, value, value2);
|
|
85
|
+
}
|
|
86
|
+
if (attr.dataType === import_types.BizAttributeTypes.Boolean) {
|
|
87
|
+
return evaluateBooleanCondition(logic, actualValue);
|
|
88
|
+
}
|
|
89
|
+
if (attr.dataType === import_types.BizAttributeTypes.List) {
|
|
90
|
+
return evaluateListCondition(logic, actualValue, listValues);
|
|
91
|
+
}
|
|
92
|
+
if (attr.dataType === import_types.BizAttributeTypes.DateTime) {
|
|
93
|
+
return evaluateDateTimeCondition(logic, actualValue, value);
|
|
94
|
+
}
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
function getAttributeValue(codeName, userAttributes) {
|
|
98
|
+
return userAttributes == null ? void 0 : userAttributes[codeName];
|
|
99
|
+
}
|
|
100
|
+
function evaluateStringCondition(logic, actualValue, expectedValue) {
|
|
101
|
+
const stringValue = actualValue === null || actualValue === void 0 ? "" : String(actualValue);
|
|
102
|
+
switch (logic) {
|
|
103
|
+
case "is":
|
|
104
|
+
return stringValue === expectedValue;
|
|
105
|
+
case "not":
|
|
106
|
+
return stringValue !== expectedValue;
|
|
107
|
+
case "contains":
|
|
108
|
+
return stringValue.includes(expectedValue);
|
|
109
|
+
case "notContain":
|
|
110
|
+
return !stringValue.includes(expectedValue);
|
|
111
|
+
case "startsWith":
|
|
112
|
+
return stringValue.startsWith(expectedValue);
|
|
113
|
+
case "endsWith":
|
|
114
|
+
return stringValue.endsWith(expectedValue);
|
|
115
|
+
case "empty": {
|
|
116
|
+
const isEmpty = !stringValue || stringValue === "";
|
|
117
|
+
return isEmpty;
|
|
118
|
+
}
|
|
119
|
+
case "any":
|
|
120
|
+
return Boolean(stringValue && stringValue !== "");
|
|
121
|
+
default:
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function evaluateNumberCondition(logic, actualValue, expectedValue, expectedValue2) {
|
|
126
|
+
const numValue = Number(actualValue);
|
|
127
|
+
const numValue2 = Number(expectedValue2);
|
|
128
|
+
if (Number.isNaN(numValue)) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
switch (logic) {
|
|
132
|
+
case "is":
|
|
133
|
+
return numValue === expectedValue;
|
|
134
|
+
case "not":
|
|
135
|
+
return numValue !== expectedValue;
|
|
136
|
+
case "isLessThan":
|
|
137
|
+
return numValue < expectedValue;
|
|
138
|
+
case "isLessThanOrEqualTo":
|
|
139
|
+
return numValue <= expectedValue;
|
|
140
|
+
case "isGreaterThan":
|
|
141
|
+
return numValue > expectedValue;
|
|
142
|
+
case "isGreaterThanOrEqualTo":
|
|
143
|
+
return numValue >= expectedValue;
|
|
144
|
+
case "between":
|
|
145
|
+
return numValue >= expectedValue && numValue <= numValue2;
|
|
146
|
+
case "empty":
|
|
147
|
+
return actualValue === null || actualValue === void 0 || actualValue === "";
|
|
148
|
+
case "any":
|
|
149
|
+
return actualValue !== null && actualValue !== void 0 && actualValue !== "";
|
|
150
|
+
default:
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function evaluateBooleanCondition(logic, actualValue) {
|
|
155
|
+
switch (logic) {
|
|
156
|
+
case "true":
|
|
157
|
+
return actualValue === true;
|
|
158
|
+
case "false":
|
|
159
|
+
return actualValue === false;
|
|
160
|
+
case "empty":
|
|
161
|
+
return actualValue === null || actualValue === void 0 || actualValue === "";
|
|
162
|
+
case "any":
|
|
163
|
+
return actualValue !== null && actualValue !== void 0 && actualValue !== "";
|
|
164
|
+
default:
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function evaluateListCondition(logic, actualValue, expectedValues) {
|
|
169
|
+
const arrayValue = Array.isArray(actualValue) ? actualValue : [];
|
|
170
|
+
if (logic === "empty" || logic === "any") {
|
|
171
|
+
switch (logic) {
|
|
172
|
+
case "empty":
|
|
173
|
+
return !arrayValue || arrayValue.length === 0;
|
|
174
|
+
case "any":
|
|
175
|
+
return arrayValue && arrayValue.length > 0;
|
|
176
|
+
default:
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const filteredValues = expectedValues.filter(
|
|
181
|
+
(value) => value !== null && value !== void 0 && value !== ""
|
|
182
|
+
);
|
|
183
|
+
if (!filteredValues.length) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
switch (logic) {
|
|
187
|
+
case "includesAtLeastOne":
|
|
188
|
+
return filteredValues.some((value) => arrayValue.includes(value));
|
|
189
|
+
case "includesAll":
|
|
190
|
+
return filteredValues.every((value) => arrayValue.includes(value));
|
|
191
|
+
case "notIncludesAtLeastOne":
|
|
192
|
+
return !filteredValues.some((value) => arrayValue.includes(value));
|
|
193
|
+
case "notIncludesAll":
|
|
194
|
+
return !filteredValues.every((value) => arrayValue.includes(value));
|
|
195
|
+
default:
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function evaluateDateTimeCondition(logic, actualValue, expectedValue) {
|
|
200
|
+
const actualDate = actualValue ? new Date(actualValue) : null;
|
|
201
|
+
const now = /* @__PURE__ */ new Date();
|
|
202
|
+
if (!actualDate || Number.isNaN(actualDate.getTime())) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
switch (logic) {
|
|
206
|
+
case "lessThan": {
|
|
207
|
+
const targetDate = (0, import_date_fns.subDays)(now, Number(expectedValue));
|
|
208
|
+
return actualDate >= targetDate;
|
|
209
|
+
}
|
|
210
|
+
case "exactly": {
|
|
211
|
+
const targetDate = (0, import_date_fns.subDays)(now, Number(expectedValue));
|
|
212
|
+
const start = (0, import_date_fns.startOfDay)(targetDate);
|
|
213
|
+
const end = (0, import_date_fns.endOfDay)(targetDate);
|
|
214
|
+
return actualDate >= start && actualDate <= end;
|
|
215
|
+
}
|
|
216
|
+
case "moreThan": {
|
|
217
|
+
const targetDate = (0, import_date_fns.subDays)(now, Number(expectedValue));
|
|
218
|
+
return actualDate <= targetDate;
|
|
219
|
+
}
|
|
220
|
+
case "before": {
|
|
221
|
+
const expectedDate = new Date(expectedValue);
|
|
222
|
+
return actualDate <= expectedDate;
|
|
223
|
+
}
|
|
224
|
+
case "on": {
|
|
225
|
+
const expectedDateOn = new Date(expectedValue);
|
|
226
|
+
const start = (0, import_date_fns.startOfDay)(expectedDateOn);
|
|
227
|
+
const end = (0, import_date_fns.endOfDay)(expectedDateOn);
|
|
228
|
+
return actualDate >= start && actualDate <= end;
|
|
229
|
+
}
|
|
230
|
+
case "after": {
|
|
231
|
+
const expectedDateAfter = new Date(expectedValue);
|
|
232
|
+
return actualDate >= expectedDateAfter;
|
|
233
|
+
}
|
|
234
|
+
case "empty":
|
|
235
|
+
return !actualValue || actualValue === "";
|
|
236
|
+
case "any":
|
|
237
|
+
return actualValue && actualValue !== "";
|
|
238
|
+
default:
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
function evaluateFilterResult(filter) {
|
|
243
|
+
if (!filter) {
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
if (filter.AND) {
|
|
247
|
+
return filter.AND.every((item) => evaluateFilterResult(item));
|
|
248
|
+
}
|
|
249
|
+
if (filter.OR) {
|
|
250
|
+
return filter.OR.some((item) => evaluateFilterResult(item));
|
|
251
|
+
}
|
|
252
|
+
if (typeof filter === "boolean") {
|
|
253
|
+
return filter;
|
|
254
|
+
}
|
|
255
|
+
if (typeof filter === "object") {
|
|
256
|
+
return true;
|
|
257
|
+
}
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
261
|
+
0 && (module.exports = {
|
|
262
|
+
evaluateAttributeCondition,
|
|
263
|
+
evaluateFilterConditions
|
|
264
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { RulesCondition, UserTourTypes } from '@usertour/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Simplified attribute type with only required fields
|
|
5
|
+
*/
|
|
6
|
+
interface SimpleAttribute {
|
|
7
|
+
id: string;
|
|
8
|
+
codeName: string;
|
|
9
|
+
dataType: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Evaluate filter conditions and return boolean result
|
|
13
|
+
* @param conditions - Filter conditions to evaluate
|
|
14
|
+
* @param attributes - Available attributes
|
|
15
|
+
* @param context - Filter context with user attributes
|
|
16
|
+
* @returns boolean indicating if conditions are met
|
|
17
|
+
*/
|
|
18
|
+
declare function evaluateFilterConditions(conditions: RulesCondition[], attributes: SimpleAttribute[], userAttributes: UserTourTypes.Attributes): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Evaluate a single attribute condition
|
|
21
|
+
* @param condition - Single attribute filter condition
|
|
22
|
+
* @param attributes - Available attributes
|
|
23
|
+
* @param context - Filter context with user attributes
|
|
24
|
+
* @returns Evaluation result (boolean or complex structure)
|
|
25
|
+
*/
|
|
26
|
+
declare function evaluateAttributeCondition(condition: RulesCondition, attributes: SimpleAttribute[], userAttributes: UserTourTypes.Attributes): any;
|
|
27
|
+
|
|
28
|
+
export { type SimpleAttribute, evaluateAttributeCondition, evaluateFilterConditions };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { RulesCondition, UserTourTypes } from '@usertour/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Simplified attribute type with only required fields
|
|
5
|
+
*/
|
|
6
|
+
interface SimpleAttribute {
|
|
7
|
+
id: string;
|
|
8
|
+
codeName: string;
|
|
9
|
+
dataType: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Evaluate filter conditions and return boolean result
|
|
13
|
+
* @param conditions - Filter conditions to evaluate
|
|
14
|
+
* @param attributes - Available attributes
|
|
15
|
+
* @param context - Filter context with user attributes
|
|
16
|
+
* @returns boolean indicating if conditions are met
|
|
17
|
+
*/
|
|
18
|
+
declare function evaluateFilterConditions(conditions: RulesCondition[], attributes: SimpleAttribute[], userAttributes: UserTourTypes.Attributes): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Evaluate a single attribute condition
|
|
21
|
+
* @param condition - Single attribute filter condition
|
|
22
|
+
* @param attributes - Available attributes
|
|
23
|
+
* @param context - Filter context with user attributes
|
|
24
|
+
* @returns Evaluation result (boolean or complex structure)
|
|
25
|
+
*/
|
|
26
|
+
declare function evaluateAttributeCondition(condition: RulesCondition, attributes: SimpleAttribute[], userAttributes: UserTourTypes.Attributes): any;
|
|
27
|
+
|
|
28
|
+
export { type SimpleAttribute, evaluateAttributeCondition, evaluateFilterConditions };
|