@usertour/helpers 0.0.34 → 0.0.36

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 (36) hide show
  1. package/dist/__tests__/attribute.test.cjs +10 -1
  2. package/dist/__tests__/attribute.test.js +2 -1
  3. package/dist/__tests__/condition.test.cjs +1008 -21
  4. package/dist/__tests__/condition.test.js +902 -4
  5. package/dist/__tests__/get-attribute-type.test.cjs +195 -0
  6. package/dist/__tests__/get-attribute-type.test.d.cts +2 -0
  7. package/dist/__tests__/get-attribute-type.test.d.ts +2 -0
  8. package/dist/__tests__/get-attribute-type.test.js +133 -0
  9. package/dist/__tests__/time.test.cjs +482 -42
  10. package/dist/__tests__/time.test.js +349 -28
  11. package/dist/attribute.cjs +111 -0
  12. package/dist/attribute.d.cts +5 -0
  13. package/dist/attribute.d.ts +5 -0
  14. package/dist/attribute.js +12 -0
  15. package/dist/{chunk-A4KMGXB3.js → chunk-3UOSPZEP.js} +4 -4
  16. package/dist/chunk-EEYZG4JJ.js +78 -0
  17. package/dist/chunk-JQWKLXW6.js +147 -0
  18. package/dist/{chunk-7JXEY4A2.js → chunk-KYDXF7SU.js} +5 -1
  19. package/dist/conditions/attribute.cjs +10 -1
  20. package/dist/conditions/attribute.js +2 -1
  21. package/dist/conditions/condition.cjs +110 -20
  22. package/dist/conditions/condition.js +4 -3
  23. package/dist/conditions/index.cjs +152 -19
  24. package/dist/conditions/index.d.cts +1 -1
  25. package/dist/conditions/index.d.ts +1 -1
  26. package/dist/conditions/index.js +14 -5
  27. package/dist/conditions/time.cjs +150 -18
  28. package/dist/conditions/time.d.cts +29 -2
  29. package/dist/conditions/time.d.ts +29 -2
  30. package/dist/conditions/time.js +12 -3
  31. package/dist/index.cjs +209 -19
  32. package/dist/index.d.cts +2 -1
  33. package/dist/index.d.ts +2 -1
  34. package/dist/index.js +20 -4
  35. package/package.json +2 -2
  36. package/dist/chunk-CEK3SCQO.js +0 -31
@@ -20,36 +20,168 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/conditions/time.ts
21
21
  var time_exports = {};
22
22
  __export(time_exports, {
23
- evaluateTimeCondition: () => evaluateTimeCondition
23
+ convertTimeConditionLegacyToV2: () => convertTimeConditionLegacyToV2,
24
+ evaluateTimeCondition: () => evaluateTimeCondition,
25
+ isTimeConditionDataLegacy: () => isTimeConditionDataLegacy,
26
+ isTimeConditionDataV2: () => isTimeConditionDataV2,
27
+ normalizeTimeConditionData: () => normalizeTimeConditionData
24
28
  });
25
29
  module.exports = __toCommonJS(time_exports);
26
30
  var import_date_fns = require("date-fns");
27
- var evaluateTimeCondition = (rules) => {
31
+
32
+ // src/type-utils.ts
33
+ var nativeIsArray = Array.isArray;
34
+ var ObjProto = Object.prototype;
35
+ var objToString = ObjProto.toString;
36
+ var objHasOwn = ObjProto.hasOwnProperty;
37
+ var isUndefined = (x) => x === void 0;
38
+ var isString = (x) => {
39
+ return objToString.call(x) === "[object String]";
40
+ };
41
+ var isEmptyString = (x) => isString(x) && x.trim().length === 0;
42
+ var isNull = (x) => {
43
+ return x === null;
44
+ };
45
+ var isNullish = (x) => isUndefined(x) || isNull(x);
46
+
47
+ // src/conditions/time.ts
48
+ function isEmpty(value) {
49
+ return isNullish(value) || isEmptyString(value);
50
+ }
51
+ function hasRequiredFields(data, type) {
52
+ if (type === "start") {
53
+ return !isEmpty(data.startDate) && !isEmpty(data.startDateHour) && !isEmpty(data.startDateMinute);
54
+ }
55
+ return !isEmpty(data.endDate) && !isEmpty(data.endDateHour) && !isEmpty(data.endDateMinute);
56
+ }
57
+ function parseLegacyDate(dateStr) {
58
+ const [month, day, year] = dateStr.split("/");
59
+ if (!month || !day || !year) {
60
+ return null;
61
+ }
62
+ return {
63
+ month: Number.parseInt(month),
64
+ day: Number.parseInt(day),
65
+ year: Number.parseInt(year)
66
+ };
67
+ }
68
+ function createLegacyDateTime(data, type) {
69
+ const dateStr = type === "start" ? data.startDate : data.endDate;
70
+ const hourStr = type === "start" ? data.startDateHour : data.endDateHour;
71
+ const minuteStr = type === "start" ? data.startDateMinute : data.endDateMinute;
72
+ if (!dateStr || !hourStr || !minuteStr) {
73
+ return null;
74
+ }
75
+ const dateParts = parseLegacyDate(dateStr);
76
+ if (!dateParts) {
77
+ return null;
78
+ }
79
+ const dateTime = new Date(
80
+ dateParts.year,
81
+ dateParts.month - 1,
82
+ dateParts.day,
83
+ Number.parseInt(hourStr),
84
+ Number.parseInt(minuteStr),
85
+ 0
86
+ );
87
+ return (0, import_date_fns.isValid)(dateTime) ? dateTime : null;
88
+ }
89
+ function isTimeConditionDataV2(data) {
90
+ return data && ("startTime" in data || "endTime" in data);
91
+ }
92
+ function isTimeConditionDataLegacy(data) {
93
+ return data && ("startDate" in data || "startDateHour" in data);
94
+ }
95
+ function convertTimeConditionLegacyToV2(legacyData) {
28
96
  try {
29
- const { endDate, endDateHour, endDateMinute, startDate, startDateHour, startDateMinute } = rules.data || {};
30
- if (!startDate || !startDateHour || !startDateMinute) {
31
- return false;
97
+ if (!hasRequiredFields(legacyData, "start")) {
98
+ return null;
32
99
  }
33
- const startTimeString = `${startDate}T${startDateHour.padStart(2, "0")}:${startDateMinute.padStart(2, "0")}:00`;
34
- const startTime = (0, import_date_fns.parseISO)(startTimeString);
35
- if (!(0, import_date_fns.isValid)(startTime)) {
36
- return false;
100
+ const startDateTime = createLegacyDateTime(legacyData, "start");
101
+ if (!startDateTime) {
102
+ return null;
37
103
  }
38
- const now = /* @__PURE__ */ new Date();
39
- if (!endDate || !endDateHour || !endDateMinute) {
40
- return (0, import_date_fns.isAfter)(now, startTime);
104
+ const result = {
105
+ startTime: startDateTime.toISOString()
106
+ };
107
+ if (hasRequiredFields(legacyData, "end")) {
108
+ const endDateTime = createLegacyDateTime(legacyData, "end");
109
+ if (endDateTime) {
110
+ result.endTime = endDateTime.toISOString();
111
+ }
41
112
  }
42
- const endTimeString = `${endDate}T${endDateHour.padStart(2, "0")}:${endDateMinute.padStart(2, "0")}:00`;
43
- const endTime = (0, import_date_fns.parseISO)(endTimeString);
44
- if (!(0, import_date_fns.isValid)(endTime)) {
45
- return false;
113
+ return result;
114
+ } catch {
115
+ return null;
116
+ }
117
+ }
118
+ function normalizeTimeConditionData(data) {
119
+ if (!data) {
120
+ return null;
121
+ }
122
+ if (isTimeConditionDataV2(data)) {
123
+ return data;
124
+ }
125
+ if (isTimeConditionDataLegacy(data)) {
126
+ return convertTimeConditionLegacyToV2(data);
127
+ }
128
+ return null;
129
+ }
130
+ function evaluateTimeConditionV2(data) {
131
+ if (!data.startTime) {
132
+ return false;
133
+ }
134
+ const startTime = (0, import_date_fns.parseISO)(data.startTime);
135
+ if (!(0, import_date_fns.isValid)(startTime)) {
136
+ return false;
137
+ }
138
+ const now = /* @__PURE__ */ new Date();
139
+ if (!data.endTime) {
140
+ return (0, import_date_fns.isAfter)(now, startTime);
141
+ }
142
+ const endTime = (0, import_date_fns.parseISO)(data.endTime);
143
+ if (!(0, import_date_fns.isValid)(endTime)) {
144
+ return false;
145
+ }
146
+ return (0, import_date_fns.isAfter)(now, startTime) && (0, import_date_fns.isBefore)(now, endTime);
147
+ }
148
+ function evaluateTimeConditionLegacy(data) {
149
+ if (!hasRequiredFields(data, "start")) {
150
+ return false;
151
+ }
152
+ const startDateTime = createLegacyDateTime(data, "start");
153
+ if (!startDateTime) {
154
+ return false;
155
+ }
156
+ const now = /* @__PURE__ */ new Date();
157
+ if (!hasRequiredFields(data, "end")) {
158
+ return (0, import_date_fns.isAfter)(now, startDateTime);
159
+ }
160
+ const endDateTime = createLegacyDateTime(data, "end");
161
+ if (!endDateTime) {
162
+ return false;
163
+ }
164
+ return (0, import_date_fns.isAfter)(now, startDateTime) && (0, import_date_fns.isBefore)(now, endDateTime);
165
+ }
166
+ var evaluateTimeCondition = (rules) => {
167
+ try {
168
+ const data = rules.data || {};
169
+ if (isTimeConditionDataV2(data)) {
170
+ return evaluateTimeConditionV2(data);
46
171
  }
47
- return (0, import_date_fns.isAfter)(now, startTime) && (0, import_date_fns.isBefore)(now, endTime);
172
+ if (isTimeConditionDataLegacy(data)) {
173
+ return evaluateTimeConditionLegacy(data);
174
+ }
175
+ return false;
48
176
  } catch {
49
177
  return false;
50
178
  }
51
179
  };
52
180
  // Annotate the CommonJS export names for ESM import in node:
53
181
  0 && (module.exports = {
54
- evaluateTimeCondition
182
+ convertTimeConditionLegacyToV2,
183
+ evaluateTimeCondition,
184
+ isTimeConditionDataLegacy,
185
+ isTimeConditionDataV2,
186
+ normalizeTimeConditionData
55
187
  });
@@ -1,10 +1,37 @@
1
- import { RulesCondition } from '@usertour/types';
1
+ import { TimeConditionDataV2, TimeConditionDataLegacy, TimeConditionData, RulesCondition } from '@usertour/types';
2
2
 
3
+ /**
4
+ * Type guard to check if data is in new format (TimeConditionDataV2)
5
+ * @param data - The data to check
6
+ * @returns true if data has startTime or endTime fields
7
+ */
8
+ declare function isTimeConditionDataV2(data: any): data is TimeConditionDataV2;
9
+ /**
10
+ * Type guard to check if data is in legacy format (TimeConditionDataLegacy)
11
+ * @param data - The data to check
12
+ * @returns true if data has startDate or startDateHour fields
13
+ */
14
+ declare function isTimeConditionDataLegacy(data: any): data is TimeConditionDataLegacy;
15
+ /**
16
+ * Convert legacy format to new format (ISO 8601)
17
+ * @param legacyData - Legacy time condition data
18
+ * @returns New format time condition data, or null if conversion fails
19
+ */
20
+ declare function convertTimeConditionLegacyToV2(legacyData: TimeConditionDataLegacy): TimeConditionDataV2 | null;
21
+ /**
22
+ * Normalize time condition data to new format
23
+ * If data is already in new format, returns it as-is
24
+ * If data is in legacy format, converts it to new format
25
+ * @param data - Time condition data (either format)
26
+ * @returns New format time condition data, or null if conversion fails
27
+ */
28
+ declare function normalizeTimeConditionData(data: TimeConditionData | null | undefined): TimeConditionDataV2 | null;
3
29
  /**
4
30
  * Evaluate time condition based on start and end time rules
31
+ * Supports both new ISO 8601 format and legacy format for backward compatibility
5
32
  * @param rules - Time condition rules
6
33
  * @returns boolean indicating if current time matches the condition
7
34
  */
8
35
  declare const evaluateTimeCondition: (rules: RulesCondition) => boolean;
9
36
 
10
- export { evaluateTimeCondition };
37
+ export { convertTimeConditionLegacyToV2, evaluateTimeCondition, isTimeConditionDataLegacy, isTimeConditionDataV2, normalizeTimeConditionData };
@@ -1,10 +1,37 @@
1
- import { RulesCondition } from '@usertour/types';
1
+ import { TimeConditionDataV2, TimeConditionDataLegacy, TimeConditionData, RulesCondition } from '@usertour/types';
2
2
 
3
+ /**
4
+ * Type guard to check if data is in new format (TimeConditionDataV2)
5
+ * @param data - The data to check
6
+ * @returns true if data has startTime or endTime fields
7
+ */
8
+ declare function isTimeConditionDataV2(data: any): data is TimeConditionDataV2;
9
+ /**
10
+ * Type guard to check if data is in legacy format (TimeConditionDataLegacy)
11
+ * @param data - The data to check
12
+ * @returns true if data has startDate or startDateHour fields
13
+ */
14
+ declare function isTimeConditionDataLegacy(data: any): data is TimeConditionDataLegacy;
15
+ /**
16
+ * Convert legacy format to new format (ISO 8601)
17
+ * @param legacyData - Legacy time condition data
18
+ * @returns New format time condition data, or null if conversion fails
19
+ */
20
+ declare function convertTimeConditionLegacyToV2(legacyData: TimeConditionDataLegacy): TimeConditionDataV2 | null;
21
+ /**
22
+ * Normalize time condition data to new format
23
+ * If data is already in new format, returns it as-is
24
+ * If data is in legacy format, converts it to new format
25
+ * @param data - Time condition data (either format)
26
+ * @returns New format time condition data, or null if conversion fails
27
+ */
28
+ declare function normalizeTimeConditionData(data: TimeConditionData | null | undefined): TimeConditionDataV2 | null;
3
29
  /**
4
30
  * Evaluate time condition based on start and end time rules
31
+ * Supports both new ISO 8601 format and legacy format for backward compatibility
5
32
  * @param rules - Time condition rules
6
33
  * @returns boolean indicating if current time matches the condition
7
34
  */
8
35
  declare const evaluateTimeCondition: (rules: RulesCondition) => boolean;
9
36
 
10
- export { evaluateTimeCondition };
37
+ export { convertTimeConditionLegacyToV2, evaluateTimeCondition, isTimeConditionDataLegacy, isTimeConditionDataV2, normalizeTimeConditionData };
@@ -1,7 +1,16 @@
1
1
  import {
2
- evaluateTimeCondition
3
- } from "../chunk-CEK3SCQO.js";
2
+ convertTimeConditionLegacyToV2,
3
+ evaluateTimeCondition,
4
+ isTimeConditionDataLegacy,
5
+ isTimeConditionDataV2,
6
+ normalizeTimeConditionData
7
+ } from "../chunk-JQWKLXW6.js";
8
+ import "../chunk-GFH3VWOC.js";
4
9
  import "../chunk-XEO3YXBM.js";
5
10
  export {
6
- evaluateTimeCondition
11
+ convertTimeConditionLegacyToV2,
12
+ evaluateTimeCondition,
13
+ isTimeConditionDataLegacy,
14
+ isTimeConditionDataV2,
15
+ normalizeTimeConditionData
7
16
  };
package/dist/index.cjs CHANGED
@@ -43,9 +43,11 @@ __export(src_exports, {
43
43
  assignConditionIds: () => assignConditionIds,
44
44
  assignableWindow: () => assignableWindow,
45
45
  buildConfig: () => buildConfig,
46
+ capitalizeFirstLetter: () => capitalizeFirstLetter,
46
47
  cn: () => cn,
47
48
  conditionsIsSame: () => conditionsIsSame,
48
49
  convertSettings: () => convertSettings,
50
+ convertTimeConditionLegacyToV2: () => convertTimeConditionLegacyToV2,
49
51
  convertToCssVars: () => convertToCssVars,
50
52
  cuid: () => cuid,
51
53
  deepClone: () => deepClone,
@@ -60,8 +62,10 @@ __export(src_exports, {
60
62
  evaluateUrlCondition: () => evaluateUrlCondition,
61
63
  fetch: () => fetch,
62
64
  filterConditionsByType: () => filterConditionsByType,
65
+ filterNullAttributes: () => filterNullAttributes,
63
66
  formatDate: () => formatDate,
64
67
  generateAutoStateColors: () => generateAutoStateColors,
68
+ getAttributeType: () => getAttributeType,
65
69
  getAuthToken: () => getAuthToken,
66
70
  getCodeError: () => getCodeError,
67
71
  getContentError: () => getContentError,
@@ -102,6 +106,8 @@ __export(src_exports, {
102
106
  isPublishedAtLeastOneEnvironment: () => isPublishedAtLeastOneEnvironment,
103
107
  isPublishedInAllEnvironments: () => isPublishedInAllEnvironments,
104
108
  isString: () => isString,
109
+ isTimeConditionDataLegacy: () => isTimeConditionDataLegacy,
110
+ isTimeConditionDataV2: () => isTimeConditionDataV2,
105
111
  isUint8Array: () => isUint8Array,
106
112
  isUndefined: () => isUndefined,
107
113
  isUrl: () => isUrl,
@@ -111,6 +117,7 @@ __export(src_exports, {
111
117
  nativeForEach: () => nativeForEach,
112
118
  nativeIndexOf: () => nativeIndexOf,
113
119
  navigator: () => navigator,
120
+ normalizeTimeConditionData: () => normalizeTimeConditionData,
114
121
  parseUrlParams: () => parseUrlParams,
115
122
  regenerateConditionIds: () => regenerateConditionIds,
116
123
  removeAuthToken: () => removeAuthToken,
@@ -1100,27 +1107,134 @@ var evaluateUrlCondition = (rules, url) => {
1100
1107
 
1101
1108
  // src/conditions/time.ts
1102
1109
  var import_date_fns = require("date-fns");
1103
- var evaluateTimeCondition = (rules) => {
1110
+ function isEmpty(value) {
1111
+ return isNullish(value) || isEmptyString(value);
1112
+ }
1113
+ function hasRequiredFields(data, type) {
1114
+ if (type === "start") {
1115
+ return !isEmpty(data.startDate) && !isEmpty(data.startDateHour) && !isEmpty(data.startDateMinute);
1116
+ }
1117
+ return !isEmpty(data.endDate) && !isEmpty(data.endDateHour) && !isEmpty(data.endDateMinute);
1118
+ }
1119
+ function parseLegacyDate(dateStr) {
1120
+ const [month, day, year] = dateStr.split("/");
1121
+ if (!month || !day || !year) {
1122
+ return null;
1123
+ }
1124
+ return {
1125
+ month: Number.parseInt(month),
1126
+ day: Number.parseInt(day),
1127
+ year: Number.parseInt(year)
1128
+ };
1129
+ }
1130
+ function createLegacyDateTime(data, type) {
1131
+ const dateStr = type === "start" ? data.startDate : data.endDate;
1132
+ const hourStr = type === "start" ? data.startDateHour : data.endDateHour;
1133
+ const minuteStr = type === "start" ? data.startDateMinute : data.endDateMinute;
1134
+ if (!dateStr || !hourStr || !minuteStr) {
1135
+ return null;
1136
+ }
1137
+ const dateParts = parseLegacyDate(dateStr);
1138
+ if (!dateParts) {
1139
+ return null;
1140
+ }
1141
+ const dateTime = new Date(
1142
+ dateParts.year,
1143
+ dateParts.month - 1,
1144
+ dateParts.day,
1145
+ Number.parseInt(hourStr),
1146
+ Number.parseInt(minuteStr),
1147
+ 0
1148
+ );
1149
+ return (0, import_date_fns.isValid)(dateTime) ? dateTime : null;
1150
+ }
1151
+ function isTimeConditionDataV2(data) {
1152
+ return data && ("startTime" in data || "endTime" in data);
1153
+ }
1154
+ function isTimeConditionDataLegacy(data) {
1155
+ return data && ("startDate" in data || "startDateHour" in data);
1156
+ }
1157
+ function convertTimeConditionLegacyToV2(legacyData) {
1104
1158
  try {
1105
- const { endDate, endDateHour, endDateMinute, startDate, startDateHour, startDateMinute } = rules.data || {};
1106
- if (!startDate || !startDateHour || !startDateMinute) {
1107
- return false;
1159
+ if (!hasRequiredFields(legacyData, "start")) {
1160
+ return null;
1108
1161
  }
1109
- const startTimeString = `${startDate}T${startDateHour.padStart(2, "0")}:${startDateMinute.padStart(2, "0")}:00`;
1110
- const startTime = (0, import_date_fns.parseISO)(startTimeString);
1111
- if (!(0, import_date_fns.isValid)(startTime)) {
1112
- return false;
1162
+ const startDateTime = createLegacyDateTime(legacyData, "start");
1163
+ if (!startDateTime) {
1164
+ return null;
1113
1165
  }
1114
- const now = /* @__PURE__ */ new Date();
1115
- if (!endDate || !endDateHour || !endDateMinute) {
1116
- return (0, import_date_fns.isAfter)(now, startTime);
1166
+ const result = {
1167
+ startTime: startDateTime.toISOString()
1168
+ };
1169
+ if (hasRequiredFields(legacyData, "end")) {
1170
+ const endDateTime = createLegacyDateTime(legacyData, "end");
1171
+ if (endDateTime) {
1172
+ result.endTime = endDateTime.toISOString();
1173
+ }
1117
1174
  }
1118
- const endTimeString = `${endDate}T${endDateHour.padStart(2, "0")}:${endDateMinute.padStart(2, "0")}:00`;
1119
- const endTime = (0, import_date_fns.parseISO)(endTimeString);
1120
- if (!(0, import_date_fns.isValid)(endTime)) {
1121
- return false;
1175
+ return result;
1176
+ } catch {
1177
+ return null;
1178
+ }
1179
+ }
1180
+ function normalizeTimeConditionData(data) {
1181
+ if (!data) {
1182
+ return null;
1183
+ }
1184
+ if (isTimeConditionDataV2(data)) {
1185
+ return data;
1186
+ }
1187
+ if (isTimeConditionDataLegacy(data)) {
1188
+ return convertTimeConditionLegacyToV2(data);
1189
+ }
1190
+ return null;
1191
+ }
1192
+ function evaluateTimeConditionV2(data) {
1193
+ if (!data.startTime) {
1194
+ return false;
1195
+ }
1196
+ const startTime = (0, import_date_fns.parseISO)(data.startTime);
1197
+ if (!(0, import_date_fns.isValid)(startTime)) {
1198
+ return false;
1199
+ }
1200
+ const now = /* @__PURE__ */ new Date();
1201
+ if (!data.endTime) {
1202
+ return (0, import_date_fns.isAfter)(now, startTime);
1203
+ }
1204
+ const endTime = (0, import_date_fns.parseISO)(data.endTime);
1205
+ if (!(0, import_date_fns.isValid)(endTime)) {
1206
+ return false;
1207
+ }
1208
+ return (0, import_date_fns.isAfter)(now, startTime) && (0, import_date_fns.isBefore)(now, endTime);
1209
+ }
1210
+ function evaluateTimeConditionLegacy(data) {
1211
+ if (!hasRequiredFields(data, "start")) {
1212
+ return false;
1213
+ }
1214
+ const startDateTime = createLegacyDateTime(data, "start");
1215
+ if (!startDateTime) {
1216
+ return false;
1217
+ }
1218
+ const now = /* @__PURE__ */ new Date();
1219
+ if (!hasRequiredFields(data, "end")) {
1220
+ return (0, import_date_fns.isAfter)(now, startDateTime);
1221
+ }
1222
+ const endDateTime = createLegacyDateTime(data, "end");
1223
+ if (!endDateTime) {
1224
+ return false;
1225
+ }
1226
+ return (0, import_date_fns.isAfter)(now, startDateTime) && (0, import_date_fns.isBefore)(now, endDateTime);
1227
+ }
1228
+ var evaluateTimeCondition = (rules) => {
1229
+ try {
1230
+ const data = rules.data || {};
1231
+ if (isTimeConditionDataV2(data)) {
1232
+ return evaluateTimeConditionV2(data);
1233
+ }
1234
+ if (isTimeConditionDataLegacy(data)) {
1235
+ return evaluateTimeConditionLegacy(data);
1122
1236
  }
1123
- return (0, import_date_fns.isAfter)(now, startTime) && (0, import_date_fns.isBefore)(now, endTime);
1237
+ return false;
1124
1238
  } catch {
1125
1239
  return false;
1126
1240
  }
@@ -1186,8 +1300,8 @@ function evaluateStringCondition(logic, actualValue, expectedValue) {
1186
1300
  case "endsWith":
1187
1301
  return stringValue.endsWith(expectedValue);
1188
1302
  case "empty": {
1189
- const isEmpty = !stringValue || stringValue === "";
1190
- return isEmpty;
1303
+ const isEmpty2 = !stringValue || stringValue === "";
1304
+ return isEmpty2;
1191
1305
  }
1192
1306
  case "any":
1193
1307
  return Boolean(stringValue && stringValue !== "");
@@ -1240,7 +1354,7 @@ function evaluateBooleanCondition(logic, actualValue) {
1240
1354
  }
1241
1355
  }
1242
1356
  function evaluateListCondition(logic, actualValue, expectedValues) {
1243
- const arrayValue = Array.isArray(actualValue) ? actualValue : [];
1357
+ const arrayValue = isArray(actualValue) ? actualValue : [];
1244
1358
  if (logic === "empty" || logic === "any") {
1245
1359
  switch (logic) {
1246
1360
  case "empty":
@@ -1424,6 +1538,75 @@ var allConditionsHaveIds = (conditions) => {
1424
1538
  }
1425
1539
  return true;
1426
1540
  };
1541
+
1542
+ // src/attribute.ts
1543
+ var import_types6 = require("@usertour/types");
1544
+ var import_date_fns3 = require("date-fns");
1545
+ var isValidYear = (date) => {
1546
+ const year = date.getFullYear();
1547
+ return year >= 1900 && year <= 2100;
1548
+ };
1549
+ var tryParseDate = (parser) => {
1550
+ try {
1551
+ const date = parser();
1552
+ return (0, import_date_fns3.isValid)(date) && isValidYear(date);
1553
+ } catch {
1554
+ return false;
1555
+ }
1556
+ };
1557
+ function isDateString(dateStr) {
1558
+ if (!Number.isNaN(Number(dateStr)) || dateStr.length < 10) {
1559
+ return false;
1560
+ }
1561
+ const dateFormats = [
1562
+ "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
1563
+ "yyyy-MM-dd'T'HH:mm:ss'Z'",
1564
+ "yyyy-MM-dd'T'HH:mm:ss.SSS",
1565
+ "yyyy-MM-dd'T'HH:mm:ss",
1566
+ "yyyy-MM-dd",
1567
+ "MM/dd/yyyy",
1568
+ "dd/MM/yyyy",
1569
+ "yyyy/MM/dd",
1570
+ "MM-dd-yyyy",
1571
+ "dd-MM-yyyy"
1572
+ ];
1573
+ if (tryParseDate(() => (0, import_date_fns3.parseISO)(dateStr))) {
1574
+ return true;
1575
+ }
1576
+ return dateFormats.some((format) => tryParseDate(() => (0, import_date_fns3.parse)(dateStr, format, /* @__PURE__ */ new Date())));
1577
+ }
1578
+ var getAttributeType = (attribute) => {
1579
+ const t = typeof attribute;
1580
+ if (t === "number") {
1581
+ return import_types6.BizAttributeTypes.Number;
1582
+ }
1583
+ if (t === "string") {
1584
+ if (isDateString(attribute)) {
1585
+ return import_types6.BizAttributeTypes.DateTime;
1586
+ }
1587
+ return import_types6.BizAttributeTypes.String;
1588
+ }
1589
+ if (t === "boolean") {
1590
+ return import_types6.BizAttributeTypes.Boolean;
1591
+ }
1592
+ if (t === "object" && Array.isArray(attribute)) {
1593
+ return import_types6.BizAttributeTypes.List;
1594
+ }
1595
+ return import_types6.BizAttributeTypes.Nil;
1596
+ };
1597
+ var capitalizeFirstLetter = (string) => {
1598
+ return string.charAt(0).toUpperCase() + string.slice(1);
1599
+ };
1600
+ var filterNullAttributes = (attributes) => {
1601
+ const attrs = {};
1602
+ for (const key in attributes) {
1603
+ const v = attributes[key];
1604
+ if (!isNull(v)) {
1605
+ attrs[key] = v;
1606
+ }
1607
+ }
1608
+ return attrs;
1609
+ };
1427
1610
  // Annotate the CommonJS export names for ESM import in node:
1428
1611
  0 && (module.exports = {
1429
1612
  AbortController,
@@ -1434,9 +1617,11 @@ var allConditionsHaveIds = (conditions) => {
1434
1617
  assignConditionIds,
1435
1618
  assignableWindow,
1436
1619
  buildConfig,
1620
+ capitalizeFirstLetter,
1437
1621
  cn,
1438
1622
  conditionsIsSame,
1439
1623
  convertSettings,
1624
+ convertTimeConditionLegacyToV2,
1440
1625
  convertToCssVars,
1441
1626
  cuid,
1442
1627
  deepClone,
@@ -1451,8 +1636,10 @@ var allConditionsHaveIds = (conditions) => {
1451
1636
  evaluateUrlCondition,
1452
1637
  fetch,
1453
1638
  filterConditionsByType,
1639
+ filterNullAttributes,
1454
1640
  formatDate,
1455
1641
  generateAutoStateColors,
1642
+ getAttributeType,
1456
1643
  getAuthToken,
1457
1644
  getCodeError,
1458
1645
  getContentError,
@@ -1493,6 +1680,8 @@ var allConditionsHaveIds = (conditions) => {
1493
1680
  isPublishedAtLeastOneEnvironment,
1494
1681
  isPublishedInAllEnvironments,
1495
1682
  isString,
1683
+ isTimeConditionDataLegacy,
1684
+ isTimeConditionDataV2,
1496
1685
  isUint8Array,
1497
1686
  isUndefined,
1498
1687
  isUrl,
@@ -1502,6 +1691,7 @@ var allConditionsHaveIds = (conditions) => {
1502
1691
  nativeForEach,
1503
1692
  nativeIndexOf,
1504
1693
  navigator,
1694
+ normalizeTimeConditionData,
1505
1695
  parseUrlParams,
1506
1696
  regenerateConditionIds,
1507
1697
  removeAuthToken,
package/dist/index.d.cts CHANGED
@@ -11,8 +11,9 @@ export { generateAutoStateColors, hexToHSLString, hexToRGBStr } from './color.cj
11
11
  export { absoluteUrl, cn, cuid, evalCode, formatDate, getRandomColor, hexToRgb, isDark, uuidV4 } from './helper.cjs';
12
12
  export { allConditionsHaveIds, assignConditionIds, conditionsIsSame, evaluateRule, evaluateRulesConditions, filterConditionsByType, isConditionsActived, regenerateConditionIds } from './conditions/condition.cjs';
13
13
  export { evaluateUrlCondition, isMatchUrlPattern } from './conditions/url.cjs';
14
- export { evaluateTimeCondition } from './conditions/time.cjs';
14
+ export { convertTimeConditionLegacyToV2, evaluateTimeCondition, isTimeConditionDataLegacy, isTimeConditionDataV2, normalizeTimeConditionData } from './conditions/time.cjs';
15
15
  export { evaluateAttributeCondition } from './conditions/attribute.cjs';
16
+ export { capitalizeFirstLetter, filterNullAttributes, getAttributeType } from './attribute.cjs';
16
17
  export { default as isEqual } from 'fast-deep-equal';
17
18
  import '@usertour/types';
18
19
  import './storage.cjs';
package/dist/index.d.ts CHANGED
@@ -11,8 +11,9 @@ export { generateAutoStateColors, hexToHSLString, hexToRGBStr } from './color.js
11
11
  export { absoluteUrl, cn, cuid, evalCode, formatDate, getRandomColor, hexToRgb, isDark, uuidV4 } from './helper.js';
12
12
  export { allConditionsHaveIds, assignConditionIds, conditionsIsSame, evaluateRule, evaluateRulesConditions, filterConditionsByType, isConditionsActived, regenerateConditionIds } from './conditions/condition.js';
13
13
  export { evaluateUrlCondition, isMatchUrlPattern } from './conditions/url.js';
14
- export { evaluateTimeCondition } from './conditions/time.js';
14
+ export { convertTimeConditionLegacyToV2, evaluateTimeCondition, isTimeConditionDataLegacy, isTimeConditionDataV2, normalizeTimeConditionData } from './conditions/time.js';
15
15
  export { evaluateAttributeCondition } from './conditions/attribute.js';
16
+ export { capitalizeFirstLetter, filterNullAttributes, getAttributeType } from './attribute.js';
16
17
  export { default as isEqual } from 'fast-deep-equal';
17
18
  import '@usertour/types';
18
19
  import './storage.js';