@usertour/helpers 0.0.44 → 0.0.46
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__/get-attribute-type.test.cjs +147 -52
- package/dist/__tests__/get-attribute-type.test.js +133 -25
- package/dist/attribute.cjs +21 -31
- package/dist/attribute.d.cts +17 -1
- package/dist/attribute.d.ts +17 -1
- package/dist/attribute.js +5 -3
- package/dist/{chunk-MU3AHQEC.js → chunk-GK5DM6EN.js} +10 -8
- package/dist/{chunk-EEYZG4JJ.js → chunk-R4R6MDTW.js} +19 -30
- package/dist/content.cjs +10 -8
- package/dist/content.js +1 -1
- package/dist/index.cjs +29 -37
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -3
- package/package.json +2 -2
|
@@ -14,46 +14,34 @@ var objToString = ObjProto.toString;
|
|
|
14
14
|
var objHasOwn = ObjProto.hasOwnProperty;
|
|
15
15
|
|
|
16
16
|
// src/attribute.ts
|
|
17
|
-
var
|
|
18
|
-
|
|
19
|
-
return year >= 1900 && year <= 2100;
|
|
20
|
-
};
|
|
21
|
-
var tryParseDate = (parser) => {
|
|
22
|
-
try {
|
|
23
|
-
const date = parser();
|
|
24
|
-
return (0, import_date_fns.isValid)(date) && isValidYear(date);
|
|
25
|
-
} catch {
|
|
17
|
+
var isValidISO8601 = (value) => {
|
|
18
|
+
if (typeof value !== "string") {
|
|
26
19
|
return false;
|
|
27
20
|
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (!Number.isNaN(Number(dateStr)) || dateStr.length < 10) {
|
|
21
|
+
const iso8601Pattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/;
|
|
22
|
+
if (!iso8601Pattern.test(value)) {
|
|
31
23
|
return false;
|
|
32
24
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
];
|
|
45
|
-
if (tryParseDate(() => (0, import_date_fns.parseISO)(dateStr))) {
|
|
46
|
-
return true;
|
|
25
|
+
try {
|
|
26
|
+
const date = (0, import_date_fns.parseISO)(value);
|
|
27
|
+
if (!(0, import_date_fns.isValid)(date)) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
const isoString = date.toISOString();
|
|
31
|
+
const normalizedInput = value.replace(/\.\d{3}Z$/, "Z");
|
|
32
|
+
const normalizedIso = isoString.replace(/\.\d{3}Z$/, "Z");
|
|
33
|
+
return normalizedInput === normalizedIso || value === isoString;
|
|
34
|
+
} catch {
|
|
35
|
+
return false;
|
|
47
36
|
}
|
|
48
|
-
|
|
49
|
-
}
|
|
37
|
+
};
|
|
50
38
|
var getAttributeType = (attribute) => {
|
|
51
39
|
const t = typeof attribute;
|
|
52
40
|
if (t === "number") {
|
|
53
41
|
return import_types.BizAttributeTypes.Number;
|
|
54
42
|
}
|
|
55
43
|
if (t === "string") {
|
|
56
|
-
if (
|
|
44
|
+
if (isValidISO8601(attribute)) {
|
|
57
45
|
return import_types.BizAttributeTypes.DateTime;
|
|
58
46
|
}
|
|
59
47
|
return import_types.BizAttributeTypes.String;
|
|
@@ -100,39 +88,45 @@ describe("getAttributeType", () => {
|
|
|
100
88
|
expect(getAttributeType("123abc")).toBe(import_types2.BizAttributeTypes.String);
|
|
101
89
|
});
|
|
102
90
|
});
|
|
103
|
-
describe("DateTime type", () => {
|
|
104
|
-
test("should return DateTime for ISO 8601 format with
|
|
91
|
+
describe("DateTime type - ISO 8601 UTC only", () => {
|
|
92
|
+
test("should return DateTime for ISO 8601 format with milliseconds and Z", () => {
|
|
105
93
|
expect(getAttributeType("2024-12-11T16:00:00.000Z")).toBe(import_types2.BizAttributeTypes.DateTime);
|
|
106
94
|
});
|
|
107
|
-
test("should return DateTime for ISO 8601 format without milliseconds", () => {
|
|
95
|
+
test("should return DateTime for ISO 8601 format without milliseconds but with Z", () => {
|
|
108
96
|
expect(getAttributeType("2024-12-11T16:00:00Z")).toBe(import_types2.BizAttributeTypes.DateTime);
|
|
109
97
|
});
|
|
110
|
-
test("should return DateTime for ISO 8601 format
|
|
111
|
-
expect(getAttributeType("2024-12-
|
|
98
|
+
test("should return DateTime for ISO 8601 format at midnight", () => {
|
|
99
|
+
expect(getAttributeType("2024-12-11T00:00:00.000Z")).toBe(import_types2.BizAttributeTypes.DateTime);
|
|
100
|
+
});
|
|
101
|
+
test("should return DateTime for ISO 8601 format at end of day", () => {
|
|
102
|
+
expect(getAttributeType("2024-12-11T23:59:59.999Z")).toBe(import_types2.BizAttributeTypes.DateTime);
|
|
103
|
+
});
|
|
104
|
+
test("should return String for ISO 8601 format without timezone (no Z)", () => {
|
|
105
|
+
expect(getAttributeType("2024-12-11T16:00:00")).toBe(import_types2.BizAttributeTypes.String);
|
|
112
106
|
});
|
|
113
|
-
test("should return
|
|
114
|
-
expect(getAttributeType("2024-12-11")).toBe(import_types2.BizAttributeTypes.
|
|
107
|
+
test("should return String for ISO 8601 date only (no T and Z)", () => {
|
|
108
|
+
expect(getAttributeType("2024-12-11")).toBe(import_types2.BizAttributeTypes.String);
|
|
115
109
|
});
|
|
116
|
-
test("should return
|
|
117
|
-
expect(getAttributeType("12/12/2024")).toBe(import_types2.BizAttributeTypes.
|
|
110
|
+
test("should return String for MM/DD/YYYY format", () => {
|
|
111
|
+
expect(getAttributeType("12/12/2024")).toBe(import_types2.BizAttributeTypes.String);
|
|
118
112
|
});
|
|
119
|
-
test("should return
|
|
120
|
-
expect(getAttributeType("2024/12/11")).toBe(import_types2.BizAttributeTypes.
|
|
113
|
+
test("should return String for YYYY/MM/DD format", () => {
|
|
114
|
+
expect(getAttributeType("2024/12/11")).toBe(import_types2.BizAttributeTypes.String);
|
|
121
115
|
});
|
|
122
|
-
test("should return
|
|
123
|
-
expect(getAttributeType("12-12-2024")).toBe(import_types2.BizAttributeTypes.
|
|
116
|
+
test("should return String for MM-DD-YYYY format", () => {
|
|
117
|
+
expect(getAttributeType("12-12-2024")).toBe(import_types2.BizAttributeTypes.String);
|
|
124
118
|
});
|
|
125
|
-
test("should return
|
|
126
|
-
expect(getAttributeType("11-12-2024")).toBe(import_types2.BizAttributeTypes.
|
|
119
|
+
test("should return String for DD-MM-YYYY format", () => {
|
|
120
|
+
expect(getAttributeType("11-12-2024")).toBe(import_types2.BizAttributeTypes.String);
|
|
127
121
|
});
|
|
128
|
-
test("should return String for invalid
|
|
129
|
-
expect(getAttributeType("2024-13-
|
|
122
|
+
test("should return String for invalid ISO 8601 format", () => {
|
|
123
|
+
expect(getAttributeType("2024-13-45T00:00:00.000Z")).toBe(import_types2.BizAttributeTypes.String);
|
|
130
124
|
});
|
|
131
|
-
test("should return String for
|
|
132
|
-
expect(getAttributeType("
|
|
125
|
+
test("should return String for ISO 8601 with timezone offset (not UTC)", () => {
|
|
126
|
+
expect(getAttributeType("2024-12-11T16:00:00.000+08:00")).toBe(import_types2.BizAttributeTypes.String);
|
|
133
127
|
});
|
|
134
|
-
test("should return String for
|
|
135
|
-
expect(getAttributeType("
|
|
128
|
+
test("should return String for ISO 8601 with lowercase z", () => {
|
|
129
|
+
expect(getAttributeType("2024-12-11T16:00:00.000z")).toBe(import_types2.BizAttributeTypes.String);
|
|
136
130
|
});
|
|
137
131
|
});
|
|
138
132
|
describe("Boolean type", () => {
|
|
@@ -182,8 +176,8 @@ describe("getAttributeType", () => {
|
|
|
182
176
|
test("should return String for string that is exactly 9 characters", () => {
|
|
183
177
|
expect(getAttributeType("123456789")).toBe(import_types2.BizAttributeTypes.String);
|
|
184
178
|
});
|
|
185
|
-
test("should return
|
|
186
|
-
expect(getAttributeType("2024-12-11")).toBe(import_types2.BizAttributeTypes.
|
|
179
|
+
test("should return String for string that is exactly 10 characters but not ISO 8601 UTC", () => {
|
|
180
|
+
expect(getAttributeType("2024-12-11")).toBe(import_types2.BizAttributeTypes.String);
|
|
187
181
|
});
|
|
188
182
|
test("should return String for string that contains date-like pattern but invalid", () => {
|
|
189
183
|
expect(getAttributeType("2024-99-99")).toBe(import_types2.BizAttributeTypes.String);
|
|
@@ -193,3 +187,104 @@ describe("getAttributeType", () => {
|
|
|
193
187
|
});
|
|
194
188
|
});
|
|
195
189
|
});
|
|
190
|
+
describe("isValidISO8601", () => {
|
|
191
|
+
describe("Valid ISO 8601 UTC formats", () => {
|
|
192
|
+
test("should return true for ISO 8601 with milliseconds and Z", () => {
|
|
193
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000Z")).toBe(true);
|
|
194
|
+
});
|
|
195
|
+
test("should return true for ISO 8601 without milliseconds but with Z", () => {
|
|
196
|
+
expect(isValidISO8601("2024-12-11T16:00:00Z")).toBe(true);
|
|
197
|
+
});
|
|
198
|
+
test("should return true for ISO 8601 at midnight", () => {
|
|
199
|
+
expect(isValidISO8601("2024-12-11T00:00:00.000Z")).toBe(true);
|
|
200
|
+
});
|
|
201
|
+
test("should return true for ISO 8601 at end of day", () => {
|
|
202
|
+
expect(isValidISO8601("2024-12-11T23:59:59.999Z")).toBe(true);
|
|
203
|
+
});
|
|
204
|
+
test("should return true for ISO 8601 with single digit month and day", () => {
|
|
205
|
+
expect(isValidISO8601("2024-01-01T00:00:00.000Z")).toBe(true);
|
|
206
|
+
});
|
|
207
|
+
test("should return true for ISO 8601 in year 1900", () => {
|
|
208
|
+
expect(isValidISO8601("1900-01-01T00:00:00.000Z")).toBe(true);
|
|
209
|
+
});
|
|
210
|
+
test("should return true for ISO 8601 in year 2100", () => {
|
|
211
|
+
expect(isValidISO8601("2100-12-31T23:59:59.999Z")).toBe(true);
|
|
212
|
+
});
|
|
213
|
+
test("should return true for ISO 8601 with year before 1900", () => {
|
|
214
|
+
expect(isValidISO8601("1800-01-01T00:00:00.000Z")).toBe(true);
|
|
215
|
+
});
|
|
216
|
+
test("should return true for ISO 8601 with year after 2100", () => {
|
|
217
|
+
expect(isValidISO8601("2200-01-01T00:00:00.000Z")).toBe(true);
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
describe("Invalid ISO 8601 UTC formats", () => {
|
|
221
|
+
test("should return false for non-string values", () => {
|
|
222
|
+
expect(isValidISO8601(null)).toBe(false);
|
|
223
|
+
expect(isValidISO8601(void 0)).toBe(false);
|
|
224
|
+
expect(isValidISO8601(123)).toBe(false);
|
|
225
|
+
expect(isValidISO8601(/* @__PURE__ */ new Date())).toBe(false);
|
|
226
|
+
expect(isValidISO8601({})).toBe(false);
|
|
227
|
+
});
|
|
228
|
+
test("should return false for ISO 8601 without T separator", () => {
|
|
229
|
+
expect(isValidISO8601("2024-12-11 16:00:00.000Z")).toBe(false);
|
|
230
|
+
expect(isValidISO8601("2024-12-11")).toBe(false);
|
|
231
|
+
});
|
|
232
|
+
test("should return false for ISO 8601 without Z (UTC indicator)", () => {
|
|
233
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000")).toBe(false);
|
|
234
|
+
expect(isValidISO8601("2024-12-11T16:00:00")).toBe(false);
|
|
235
|
+
});
|
|
236
|
+
test("should return false for ISO 8601 with timezone offset (including +00:00)", () => {
|
|
237
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000+08:00")).toBe(false);
|
|
238
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000-05:00")).toBe(false);
|
|
239
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000+01:00")).toBe(false);
|
|
240
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000-01:00")).toBe(false);
|
|
241
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000+00:00")).toBe(false);
|
|
242
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000-00:00")).toBe(false);
|
|
243
|
+
expect(isValidISO8601("2024-12-11T16:00:00+00:00")).toBe(false);
|
|
244
|
+
});
|
|
245
|
+
test("should return false for ISO 8601 with lowercase z", () => {
|
|
246
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000z")).toBe(false);
|
|
247
|
+
});
|
|
248
|
+
test("should return false for invalid date values", () => {
|
|
249
|
+
expect(isValidISO8601("2024-13-45T00:00:00.000Z")).toBe(false);
|
|
250
|
+
expect(isValidISO8601("2024-02-30T00:00:00.000Z")).toBe(false);
|
|
251
|
+
expect(isValidISO8601("2024-00-00T00:00:00.000Z")).toBe(false);
|
|
252
|
+
});
|
|
253
|
+
test("should return false for other date formats", () => {
|
|
254
|
+
expect(isValidISO8601("12/12/2024")).toBe(false);
|
|
255
|
+
expect(isValidISO8601("2024/12/11")).toBe(false);
|
|
256
|
+
expect(isValidISO8601("12-12-2024")).toBe(false);
|
|
257
|
+
expect(isValidISO8601("11-12-2024")).toBe(false);
|
|
258
|
+
});
|
|
259
|
+
test("should return false for malformed ISO 8601 strings", () => {
|
|
260
|
+
expect(isValidISO8601("2024-12-11T")).toBe(false);
|
|
261
|
+
expect(isValidISO8601("T16:00:00.000Z")).toBe(false);
|
|
262
|
+
expect(isValidISO8601("2024-12-11T16:00:00.Z")).toBe(false);
|
|
263
|
+
expect(isValidISO8601("2024-12-11T16:00.000Z")).toBe(false);
|
|
264
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000")).toBe(false);
|
|
265
|
+
});
|
|
266
|
+
test("should return false for empty string", () => {
|
|
267
|
+
expect(isValidISO8601("")).toBe(false);
|
|
268
|
+
});
|
|
269
|
+
test("should return false for string that looks like ISO 8601 but has extra characters", () => {
|
|
270
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000Z extra")).toBe(false);
|
|
271
|
+
expect(isValidISO8601("prefix 2024-12-11T16:00:00.000Z")).toBe(false);
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
describe("Edge cases", () => {
|
|
275
|
+
test("should handle leap year correctly", () => {
|
|
276
|
+
expect(isValidISO8601("2024-02-29T00:00:00.000Z")).toBe(true);
|
|
277
|
+
expect(isValidISO8601("2023-02-29T00:00:00.000Z")).toBe(false);
|
|
278
|
+
});
|
|
279
|
+
test("should handle different time values correctly", () => {
|
|
280
|
+
expect(isValidISO8601("2024-12-11T12:30:45.123Z")).toBe(true);
|
|
281
|
+
expect(isValidISO8601("2024-12-11T00:00:00.000Z")).toBe(true);
|
|
282
|
+
expect(isValidISO8601("2024-12-11T23:59:59.999Z")).toBe(true);
|
|
283
|
+
});
|
|
284
|
+
test("should handle milliseconds correctly", () => {
|
|
285
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000Z")).toBe(true);
|
|
286
|
+
expect(isValidISO8601("2024-12-11T16:00:00.999Z")).toBe(true);
|
|
287
|
+
expect(isValidISO8601("2024-12-11T16:00:00Z")).toBe(true);
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
getAttributeType
|
|
3
|
-
|
|
2
|
+
getAttributeType,
|
|
3
|
+
isValidISO8601
|
|
4
|
+
} from "../chunk-R4R6MDTW.js";
|
|
4
5
|
import "../chunk-GFH3VWOC.js";
|
|
5
6
|
import "../chunk-XEO3YXBM.js";
|
|
6
7
|
|
|
@@ -38,39 +39,45 @@ describe("getAttributeType", () => {
|
|
|
38
39
|
expect(getAttributeType("123abc")).toBe(BizAttributeTypes.String);
|
|
39
40
|
});
|
|
40
41
|
});
|
|
41
|
-
describe("DateTime type", () => {
|
|
42
|
-
test("should return DateTime for ISO 8601 format with
|
|
42
|
+
describe("DateTime type - ISO 8601 UTC only", () => {
|
|
43
|
+
test("should return DateTime for ISO 8601 format with milliseconds and Z", () => {
|
|
43
44
|
expect(getAttributeType("2024-12-11T16:00:00.000Z")).toBe(BizAttributeTypes.DateTime);
|
|
44
45
|
});
|
|
45
|
-
test("should return DateTime for ISO 8601 format without milliseconds", () => {
|
|
46
|
+
test("should return DateTime for ISO 8601 format without milliseconds but with Z", () => {
|
|
46
47
|
expect(getAttributeType("2024-12-11T16:00:00Z")).toBe(BizAttributeTypes.DateTime);
|
|
47
48
|
});
|
|
48
|
-
test("should return DateTime for ISO 8601 format
|
|
49
|
-
expect(getAttributeType("2024-12-
|
|
49
|
+
test("should return DateTime for ISO 8601 format at midnight", () => {
|
|
50
|
+
expect(getAttributeType("2024-12-11T00:00:00.000Z")).toBe(BizAttributeTypes.DateTime);
|
|
50
51
|
});
|
|
51
|
-
test("should return DateTime for ISO 8601
|
|
52
|
-
expect(getAttributeType("2024-12-
|
|
52
|
+
test("should return DateTime for ISO 8601 format at end of day", () => {
|
|
53
|
+
expect(getAttributeType("2024-12-11T23:59:59.999Z")).toBe(BizAttributeTypes.DateTime);
|
|
53
54
|
});
|
|
54
|
-
test("should return
|
|
55
|
-
expect(getAttributeType("12
|
|
55
|
+
test("should return String for ISO 8601 format without timezone (no Z)", () => {
|
|
56
|
+
expect(getAttributeType("2024-12-11T16:00:00")).toBe(BizAttributeTypes.String);
|
|
56
57
|
});
|
|
57
|
-
test("should return
|
|
58
|
-
expect(getAttributeType("2024
|
|
58
|
+
test("should return String for ISO 8601 date only (no T and Z)", () => {
|
|
59
|
+
expect(getAttributeType("2024-12-11")).toBe(BizAttributeTypes.String);
|
|
59
60
|
});
|
|
60
|
-
test("should return
|
|
61
|
-
expect(getAttributeType("12
|
|
61
|
+
test("should return String for MM/DD/YYYY format", () => {
|
|
62
|
+
expect(getAttributeType("12/12/2024")).toBe(BizAttributeTypes.String);
|
|
62
63
|
});
|
|
63
|
-
test("should return
|
|
64
|
-
expect(getAttributeType("11
|
|
64
|
+
test("should return String for YYYY/MM/DD format", () => {
|
|
65
|
+
expect(getAttributeType("2024/12/11")).toBe(BizAttributeTypes.String);
|
|
65
66
|
});
|
|
66
|
-
test("should return String for
|
|
67
|
-
expect(getAttributeType("
|
|
67
|
+
test("should return String for MM-DD-YYYY format", () => {
|
|
68
|
+
expect(getAttributeType("12-12-2024")).toBe(BizAttributeTypes.String);
|
|
68
69
|
});
|
|
69
|
-
test("should return String for
|
|
70
|
-
expect(getAttributeType("
|
|
70
|
+
test("should return String for DD-MM-YYYY format", () => {
|
|
71
|
+
expect(getAttributeType("11-12-2024")).toBe(BizAttributeTypes.String);
|
|
71
72
|
});
|
|
72
|
-
test("should return String for
|
|
73
|
-
expect(getAttributeType("
|
|
73
|
+
test("should return String for invalid ISO 8601 format", () => {
|
|
74
|
+
expect(getAttributeType("2024-13-45T00:00:00.000Z")).toBe(BizAttributeTypes.String);
|
|
75
|
+
});
|
|
76
|
+
test("should return String for ISO 8601 with timezone offset (not UTC)", () => {
|
|
77
|
+
expect(getAttributeType("2024-12-11T16:00:00.000+08:00")).toBe(BizAttributeTypes.String);
|
|
78
|
+
});
|
|
79
|
+
test("should return String for ISO 8601 with lowercase z", () => {
|
|
80
|
+
expect(getAttributeType("2024-12-11T16:00:00.000z")).toBe(BizAttributeTypes.String);
|
|
74
81
|
});
|
|
75
82
|
});
|
|
76
83
|
describe("Boolean type", () => {
|
|
@@ -120,8 +127,8 @@ describe("getAttributeType", () => {
|
|
|
120
127
|
test("should return String for string that is exactly 9 characters", () => {
|
|
121
128
|
expect(getAttributeType("123456789")).toBe(BizAttributeTypes.String);
|
|
122
129
|
});
|
|
123
|
-
test("should return
|
|
124
|
-
expect(getAttributeType("2024-12-11")).toBe(BizAttributeTypes.
|
|
130
|
+
test("should return String for string that is exactly 10 characters but not ISO 8601 UTC", () => {
|
|
131
|
+
expect(getAttributeType("2024-12-11")).toBe(BizAttributeTypes.String);
|
|
125
132
|
});
|
|
126
133
|
test("should return String for string that contains date-like pattern but invalid", () => {
|
|
127
134
|
expect(getAttributeType("2024-99-99")).toBe(BizAttributeTypes.String);
|
|
@@ -131,3 +138,104 @@ describe("getAttributeType", () => {
|
|
|
131
138
|
});
|
|
132
139
|
});
|
|
133
140
|
});
|
|
141
|
+
describe("isValidISO8601", () => {
|
|
142
|
+
describe("Valid ISO 8601 UTC formats", () => {
|
|
143
|
+
test("should return true for ISO 8601 with milliseconds and Z", () => {
|
|
144
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000Z")).toBe(true);
|
|
145
|
+
});
|
|
146
|
+
test("should return true for ISO 8601 without milliseconds but with Z", () => {
|
|
147
|
+
expect(isValidISO8601("2024-12-11T16:00:00Z")).toBe(true);
|
|
148
|
+
});
|
|
149
|
+
test("should return true for ISO 8601 at midnight", () => {
|
|
150
|
+
expect(isValidISO8601("2024-12-11T00:00:00.000Z")).toBe(true);
|
|
151
|
+
});
|
|
152
|
+
test("should return true for ISO 8601 at end of day", () => {
|
|
153
|
+
expect(isValidISO8601("2024-12-11T23:59:59.999Z")).toBe(true);
|
|
154
|
+
});
|
|
155
|
+
test("should return true for ISO 8601 with single digit month and day", () => {
|
|
156
|
+
expect(isValidISO8601("2024-01-01T00:00:00.000Z")).toBe(true);
|
|
157
|
+
});
|
|
158
|
+
test("should return true for ISO 8601 in year 1900", () => {
|
|
159
|
+
expect(isValidISO8601("1900-01-01T00:00:00.000Z")).toBe(true);
|
|
160
|
+
});
|
|
161
|
+
test("should return true for ISO 8601 in year 2100", () => {
|
|
162
|
+
expect(isValidISO8601("2100-12-31T23:59:59.999Z")).toBe(true);
|
|
163
|
+
});
|
|
164
|
+
test("should return true for ISO 8601 with year before 1900", () => {
|
|
165
|
+
expect(isValidISO8601("1800-01-01T00:00:00.000Z")).toBe(true);
|
|
166
|
+
});
|
|
167
|
+
test("should return true for ISO 8601 with year after 2100", () => {
|
|
168
|
+
expect(isValidISO8601("2200-01-01T00:00:00.000Z")).toBe(true);
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
describe("Invalid ISO 8601 UTC formats", () => {
|
|
172
|
+
test("should return false for non-string values", () => {
|
|
173
|
+
expect(isValidISO8601(null)).toBe(false);
|
|
174
|
+
expect(isValidISO8601(void 0)).toBe(false);
|
|
175
|
+
expect(isValidISO8601(123)).toBe(false);
|
|
176
|
+
expect(isValidISO8601(/* @__PURE__ */ new Date())).toBe(false);
|
|
177
|
+
expect(isValidISO8601({})).toBe(false);
|
|
178
|
+
});
|
|
179
|
+
test("should return false for ISO 8601 without T separator", () => {
|
|
180
|
+
expect(isValidISO8601("2024-12-11 16:00:00.000Z")).toBe(false);
|
|
181
|
+
expect(isValidISO8601("2024-12-11")).toBe(false);
|
|
182
|
+
});
|
|
183
|
+
test("should return false for ISO 8601 without Z (UTC indicator)", () => {
|
|
184
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000")).toBe(false);
|
|
185
|
+
expect(isValidISO8601("2024-12-11T16:00:00")).toBe(false);
|
|
186
|
+
});
|
|
187
|
+
test("should return false for ISO 8601 with timezone offset (including +00:00)", () => {
|
|
188
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000+08:00")).toBe(false);
|
|
189
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000-05:00")).toBe(false);
|
|
190
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000+01:00")).toBe(false);
|
|
191
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000-01:00")).toBe(false);
|
|
192
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000+00:00")).toBe(false);
|
|
193
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000-00:00")).toBe(false);
|
|
194
|
+
expect(isValidISO8601("2024-12-11T16:00:00+00:00")).toBe(false);
|
|
195
|
+
});
|
|
196
|
+
test("should return false for ISO 8601 with lowercase z", () => {
|
|
197
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000z")).toBe(false);
|
|
198
|
+
});
|
|
199
|
+
test("should return false for invalid date values", () => {
|
|
200
|
+
expect(isValidISO8601("2024-13-45T00:00:00.000Z")).toBe(false);
|
|
201
|
+
expect(isValidISO8601("2024-02-30T00:00:00.000Z")).toBe(false);
|
|
202
|
+
expect(isValidISO8601("2024-00-00T00:00:00.000Z")).toBe(false);
|
|
203
|
+
});
|
|
204
|
+
test("should return false for other date formats", () => {
|
|
205
|
+
expect(isValidISO8601("12/12/2024")).toBe(false);
|
|
206
|
+
expect(isValidISO8601("2024/12/11")).toBe(false);
|
|
207
|
+
expect(isValidISO8601("12-12-2024")).toBe(false);
|
|
208
|
+
expect(isValidISO8601("11-12-2024")).toBe(false);
|
|
209
|
+
});
|
|
210
|
+
test("should return false for malformed ISO 8601 strings", () => {
|
|
211
|
+
expect(isValidISO8601("2024-12-11T")).toBe(false);
|
|
212
|
+
expect(isValidISO8601("T16:00:00.000Z")).toBe(false);
|
|
213
|
+
expect(isValidISO8601("2024-12-11T16:00:00.Z")).toBe(false);
|
|
214
|
+
expect(isValidISO8601("2024-12-11T16:00.000Z")).toBe(false);
|
|
215
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000")).toBe(false);
|
|
216
|
+
});
|
|
217
|
+
test("should return false for empty string", () => {
|
|
218
|
+
expect(isValidISO8601("")).toBe(false);
|
|
219
|
+
});
|
|
220
|
+
test("should return false for string that looks like ISO 8601 but has extra characters", () => {
|
|
221
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000Z extra")).toBe(false);
|
|
222
|
+
expect(isValidISO8601("prefix 2024-12-11T16:00:00.000Z")).toBe(false);
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
describe("Edge cases", () => {
|
|
226
|
+
test("should handle leap year correctly", () => {
|
|
227
|
+
expect(isValidISO8601("2024-02-29T00:00:00.000Z")).toBe(true);
|
|
228
|
+
expect(isValidISO8601("2023-02-29T00:00:00.000Z")).toBe(false);
|
|
229
|
+
});
|
|
230
|
+
test("should handle different time values correctly", () => {
|
|
231
|
+
expect(isValidISO8601("2024-12-11T12:30:45.123Z")).toBe(true);
|
|
232
|
+
expect(isValidISO8601("2024-12-11T00:00:00.000Z")).toBe(true);
|
|
233
|
+
expect(isValidISO8601("2024-12-11T23:59:59.999Z")).toBe(true);
|
|
234
|
+
});
|
|
235
|
+
test("should handle milliseconds correctly", () => {
|
|
236
|
+
expect(isValidISO8601("2024-12-11T16:00:00.000Z")).toBe(true);
|
|
237
|
+
expect(isValidISO8601("2024-12-11T16:00:00.999Z")).toBe(true);
|
|
238
|
+
expect(isValidISO8601("2024-12-11T16:00:00Z")).toBe(true);
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
});
|
package/dist/attribute.cjs
CHANGED
|
@@ -22,7 +22,8 @@ var attribute_exports = {};
|
|
|
22
22
|
__export(attribute_exports, {
|
|
23
23
|
capitalizeFirstLetter: () => capitalizeFirstLetter,
|
|
24
24
|
filterNullAttributes: () => filterNullAttributes,
|
|
25
|
-
getAttributeType: () => getAttributeType
|
|
25
|
+
getAttributeType: () => getAttributeType,
|
|
26
|
+
isValidISO8601: () => isValidISO8601
|
|
26
27
|
});
|
|
27
28
|
module.exports = __toCommonJS(attribute_exports);
|
|
28
29
|
var import_types = require("@usertour/types");
|
|
@@ -38,46 +39,34 @@ var isNull = (x) => {
|
|
|
38
39
|
};
|
|
39
40
|
|
|
40
41
|
// src/attribute.ts
|
|
41
|
-
var
|
|
42
|
-
|
|
43
|
-
return year >= 1900 && year <= 2100;
|
|
44
|
-
};
|
|
45
|
-
var tryParseDate = (parser) => {
|
|
46
|
-
try {
|
|
47
|
-
const date = parser();
|
|
48
|
-
return (0, import_date_fns.isValid)(date) && isValidYear(date);
|
|
49
|
-
} catch {
|
|
42
|
+
var isValidISO8601 = (value) => {
|
|
43
|
+
if (typeof value !== "string") {
|
|
50
44
|
return false;
|
|
51
45
|
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (!Number.isNaN(Number(dateStr)) || dateStr.length < 10) {
|
|
46
|
+
const iso8601Pattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/;
|
|
47
|
+
if (!iso8601Pattern.test(value)) {
|
|
55
48
|
return false;
|
|
56
49
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
];
|
|
69
|
-
if (tryParseDate(() => (0, import_date_fns.parseISO)(dateStr))) {
|
|
70
|
-
return true;
|
|
50
|
+
try {
|
|
51
|
+
const date = (0, import_date_fns.parseISO)(value);
|
|
52
|
+
if (!(0, import_date_fns.isValid)(date)) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
const isoString = date.toISOString();
|
|
56
|
+
const normalizedInput = value.replace(/\.\d{3}Z$/, "Z");
|
|
57
|
+
const normalizedIso = isoString.replace(/\.\d{3}Z$/, "Z");
|
|
58
|
+
return normalizedInput === normalizedIso || value === isoString;
|
|
59
|
+
} catch {
|
|
60
|
+
return false;
|
|
71
61
|
}
|
|
72
|
-
|
|
73
|
-
}
|
|
62
|
+
};
|
|
74
63
|
var getAttributeType = (attribute) => {
|
|
75
64
|
const t = typeof attribute;
|
|
76
65
|
if (t === "number") {
|
|
77
66
|
return import_types.BizAttributeTypes.Number;
|
|
78
67
|
}
|
|
79
68
|
if (t === "string") {
|
|
80
|
-
if (
|
|
69
|
+
if (isValidISO8601(attribute)) {
|
|
81
70
|
return import_types.BizAttributeTypes.DateTime;
|
|
82
71
|
}
|
|
83
72
|
return import_types.BizAttributeTypes.String;
|
|
@@ -107,5 +96,6 @@ var filterNullAttributes = (attributes) => {
|
|
|
107
96
|
0 && (module.exports = {
|
|
108
97
|
capitalizeFirstLetter,
|
|
109
98
|
filterNullAttributes,
|
|
110
|
-
getAttributeType
|
|
99
|
+
getAttributeType,
|
|
100
|
+
isValidISO8601
|
|
111
101
|
});
|
package/dist/attribute.d.cts
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate if a value is a valid ISO 8601 date string in UTC
|
|
3
|
+
* According to the specification: datetime must be stored as ISO 8601 in UTC
|
|
4
|
+
*
|
|
5
|
+
* Following industry best practices (Stripe, GitHub, AWS, etc.), we only accept
|
|
6
|
+
* the 'Z' format for UTC, not '+00:00' or '-00:00', for consistency and simplicity.
|
|
7
|
+
*
|
|
8
|
+
* Why we need additional validation after parseISO:
|
|
9
|
+
* 1. parseISO is lenient - it may parse invalid dates (e.g., "2024-13-45") and return a valid Date object
|
|
10
|
+
* by auto-correcting (e.g., "2024-13-45" becomes "2025-01-14")
|
|
11
|
+
* 2. We need to ensure the input string exactly matches what would be produced by toISOString()
|
|
12
|
+
* This prevents accepting malformed dates that get "fixed" by the parser
|
|
13
|
+
* 3. The regex pattern ensures strict format compliance (must have T and Z)
|
|
14
|
+
* 4. The comparison ensures no date normalization occurred (e.g., invalid month/day corrections)
|
|
15
|
+
*/
|
|
16
|
+
declare const isValidISO8601: (value: any) => boolean;
|
|
1
17
|
declare const getAttributeType: (attribute: any) => number;
|
|
2
18
|
declare const capitalizeFirstLetter: (string: string) => string;
|
|
3
19
|
declare const filterNullAttributes: (attributes: Record<string, any>) => Record<string, any>;
|
|
4
20
|
|
|
5
|
-
export { capitalizeFirstLetter, filterNullAttributes, getAttributeType };
|
|
21
|
+
export { capitalizeFirstLetter, filterNullAttributes, getAttributeType, isValidISO8601 };
|
package/dist/attribute.d.ts
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate if a value is a valid ISO 8601 date string in UTC
|
|
3
|
+
* According to the specification: datetime must be stored as ISO 8601 in UTC
|
|
4
|
+
*
|
|
5
|
+
* Following industry best practices (Stripe, GitHub, AWS, etc.), we only accept
|
|
6
|
+
* the 'Z' format for UTC, not '+00:00' or '-00:00', for consistency and simplicity.
|
|
7
|
+
*
|
|
8
|
+
* Why we need additional validation after parseISO:
|
|
9
|
+
* 1. parseISO is lenient - it may parse invalid dates (e.g., "2024-13-45") and return a valid Date object
|
|
10
|
+
* by auto-correcting (e.g., "2024-13-45" becomes "2025-01-14")
|
|
11
|
+
* 2. We need to ensure the input string exactly matches what would be produced by toISOString()
|
|
12
|
+
* This prevents accepting malformed dates that get "fixed" by the parser
|
|
13
|
+
* 3. The regex pattern ensures strict format compliance (must have T and Z)
|
|
14
|
+
* 4. The comparison ensures no date normalization occurred (e.g., invalid month/day corrections)
|
|
15
|
+
*/
|
|
16
|
+
declare const isValidISO8601: (value: any) => boolean;
|
|
1
17
|
declare const getAttributeType: (attribute: any) => number;
|
|
2
18
|
declare const capitalizeFirstLetter: (string: string) => string;
|
|
3
19
|
declare const filterNullAttributes: (attributes: Record<string, any>) => Record<string, any>;
|
|
4
20
|
|
|
5
|
-
export { capitalizeFirstLetter, filterNullAttributes, getAttributeType };
|
|
21
|
+
export { capitalizeFirstLetter, filterNullAttributes, getAttributeType, isValidISO8601 };
|
package/dist/attribute.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
capitalizeFirstLetter,
|
|
3
3
|
filterNullAttributes,
|
|
4
|
-
getAttributeType
|
|
5
|
-
|
|
4
|
+
getAttributeType,
|
|
5
|
+
isValidISO8601
|
|
6
|
+
} from "./chunk-R4R6MDTW.js";
|
|
6
7
|
import "./chunk-GFH3VWOC.js";
|
|
7
8
|
import "./chunk-XEO3YXBM.js";
|
|
8
9
|
export {
|
|
9
10
|
capitalizeFirstLetter,
|
|
10
11
|
filterNullAttributes,
|
|
11
|
-
getAttributeType
|
|
12
|
+
getAttributeType,
|
|
13
|
+
isValidISO8601
|
|
12
14
|
};
|
|
@@ -59,6 +59,14 @@ var buildConfig = (config) => {
|
|
|
59
59
|
hideRulesSetting: (config == null ? void 0 : config.hideRulesSetting) || {}
|
|
60
60
|
};
|
|
61
61
|
};
|
|
62
|
+
var extractUserAttributeValue = (element, userAttributes) => {
|
|
63
|
+
if (!userAttributes || !("attrCode" in element) || typeof element.attrCode !== "string") {
|
|
64
|
+
return "fallback" in element && typeof element.fallback === "string" ? element.fallback : "";
|
|
65
|
+
}
|
|
66
|
+
const attrValue = userAttributes[element.attrCode];
|
|
67
|
+
const fallback = "fallback" in element && typeof element.fallback === "string" ? element.fallback : "";
|
|
68
|
+
return attrValue != null ? attrValue : fallback;
|
|
69
|
+
};
|
|
62
70
|
var extractLinkUrl = (value, userAttributes) => {
|
|
63
71
|
let url = "";
|
|
64
72
|
try {
|
|
@@ -66,13 +74,7 @@ var extractLinkUrl = (value, userAttributes) => {
|
|
|
66
74
|
if ("children" in v && Array.isArray(v.children)) {
|
|
67
75
|
for (const vc of v.children) {
|
|
68
76
|
if ("type" in vc && vc.type === "user-attribute") {
|
|
69
|
-
|
|
70
|
-
const attrValue = userAttributes[vc.attrCode];
|
|
71
|
-
const fallback = "fallback" in vc && typeof vc.fallback === "string" ? vc.fallback : "";
|
|
72
|
-
url += attrValue != null ? attrValue : fallback;
|
|
73
|
-
} else if ("fallback" in vc && typeof vc.fallback === "string") {
|
|
74
|
-
url += vc.fallback;
|
|
75
|
-
}
|
|
77
|
+
url += String(extractUserAttributeValue(vc, userAttributes));
|
|
76
78
|
} else if ("text" in vc && typeof vc.text === "string") {
|
|
77
79
|
url += vc.text;
|
|
78
80
|
}
|
|
@@ -89,7 +91,7 @@ var replaceUserAttrForElement = (data, userAttributes) => {
|
|
|
89
91
|
v.children = replaceUserAttrForElement(v.children, userAttributes);
|
|
90
92
|
}
|
|
91
93
|
if (v.type === "user-attribute" && userAttributes) {
|
|
92
|
-
const value =
|
|
94
|
+
const value = extractUserAttributeValue(v, userAttributes);
|
|
93
95
|
if (!isUndefined(value)) {
|
|
94
96
|
v.value = String(value);
|
|
95
97
|
}
|
|
@@ -4,47 +4,35 @@ import {
|
|
|
4
4
|
|
|
5
5
|
// src/attribute.ts
|
|
6
6
|
import { BizAttributeTypes } from "@usertour/types";
|
|
7
|
-
import { isValid, parseISO
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
return year >= 1900 && year <= 2100;
|
|
11
|
-
};
|
|
12
|
-
var tryParseDate = (parser) => {
|
|
13
|
-
try {
|
|
14
|
-
const date = parser();
|
|
15
|
-
return isValid(date) && isValidYear(date);
|
|
16
|
-
} catch {
|
|
7
|
+
import { isValid, parseISO } from "date-fns";
|
|
8
|
+
var isValidISO8601 = (value) => {
|
|
9
|
+
if (typeof value !== "string") {
|
|
17
10
|
return false;
|
|
18
11
|
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (!Number.isNaN(Number(dateStr)) || dateStr.length < 10) {
|
|
12
|
+
const iso8601Pattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/;
|
|
13
|
+
if (!iso8601Pattern.test(value)) {
|
|
22
14
|
return false;
|
|
23
15
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
];
|
|
36
|
-
if (tryParseDate(() => parseISO(dateStr))) {
|
|
37
|
-
return true;
|
|
16
|
+
try {
|
|
17
|
+
const date = parseISO(value);
|
|
18
|
+
if (!isValid(date)) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
const isoString = date.toISOString();
|
|
22
|
+
const normalizedInput = value.replace(/\.\d{3}Z$/, "Z");
|
|
23
|
+
const normalizedIso = isoString.replace(/\.\d{3}Z$/, "Z");
|
|
24
|
+
return normalizedInput === normalizedIso || value === isoString;
|
|
25
|
+
} catch {
|
|
26
|
+
return false;
|
|
38
27
|
}
|
|
39
|
-
|
|
40
|
-
}
|
|
28
|
+
};
|
|
41
29
|
var getAttributeType = (attribute) => {
|
|
42
30
|
const t = typeof attribute;
|
|
43
31
|
if (t === "number") {
|
|
44
32
|
return BizAttributeTypes.Number;
|
|
45
33
|
}
|
|
46
34
|
if (t === "string") {
|
|
47
|
-
if (
|
|
35
|
+
if (isValidISO8601(attribute)) {
|
|
48
36
|
return BizAttributeTypes.DateTime;
|
|
49
37
|
}
|
|
50
38
|
return BizAttributeTypes.String;
|
|
@@ -72,6 +60,7 @@ var filterNullAttributes = (attributes) => {
|
|
|
72
60
|
};
|
|
73
61
|
|
|
74
62
|
export {
|
|
63
|
+
isValidISO8601,
|
|
75
64
|
getAttributeType,
|
|
76
65
|
capitalizeFirstLetter,
|
|
77
66
|
filterNullAttributes
|
package/dist/content.cjs
CHANGED
|
@@ -90,6 +90,14 @@ var buildConfig = (config) => {
|
|
|
90
90
|
hideRulesSetting: (config == null ? void 0 : config.hideRulesSetting) || {}
|
|
91
91
|
};
|
|
92
92
|
};
|
|
93
|
+
var extractUserAttributeValue = (element, userAttributes) => {
|
|
94
|
+
if (!userAttributes || !("attrCode" in element) || typeof element.attrCode !== "string") {
|
|
95
|
+
return "fallback" in element && typeof element.fallback === "string" ? element.fallback : "";
|
|
96
|
+
}
|
|
97
|
+
const attrValue = userAttributes[element.attrCode];
|
|
98
|
+
const fallback = "fallback" in element && typeof element.fallback === "string" ? element.fallback : "";
|
|
99
|
+
return attrValue != null ? attrValue : fallback;
|
|
100
|
+
};
|
|
93
101
|
var extractLinkUrl = (value, userAttributes) => {
|
|
94
102
|
let url = "";
|
|
95
103
|
try {
|
|
@@ -97,13 +105,7 @@ var extractLinkUrl = (value, userAttributes) => {
|
|
|
97
105
|
if ("children" in v && Array.isArray(v.children)) {
|
|
98
106
|
for (const vc of v.children) {
|
|
99
107
|
if ("type" in vc && vc.type === "user-attribute") {
|
|
100
|
-
|
|
101
|
-
const attrValue = userAttributes[vc.attrCode];
|
|
102
|
-
const fallback = "fallback" in vc && typeof vc.fallback === "string" ? vc.fallback : "";
|
|
103
|
-
url += attrValue != null ? attrValue : fallback;
|
|
104
|
-
} else if ("fallback" in vc && typeof vc.fallback === "string") {
|
|
105
|
-
url += vc.fallback;
|
|
106
|
-
}
|
|
108
|
+
url += String(extractUserAttributeValue(vc, userAttributes));
|
|
107
109
|
} else if ("text" in vc && typeof vc.text === "string") {
|
|
108
110
|
url += vc.text;
|
|
109
111
|
}
|
|
@@ -120,7 +122,7 @@ var replaceUserAttrForElement = (data, userAttributes) => {
|
|
|
120
122
|
v.children = replaceUserAttrForElement(v.children, userAttributes);
|
|
121
123
|
}
|
|
122
124
|
if (v.type === "user-attribute" && userAttributes) {
|
|
123
|
-
const value =
|
|
125
|
+
const value = extractUserAttributeValue(v, userAttributes);
|
|
124
126
|
if (!isUndefined(value)) {
|
|
125
127
|
v.value = String(value);
|
|
126
128
|
}
|
package/dist/content.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -112,6 +112,7 @@ __export(src_exports, {
|
|
|
112
112
|
isUint8Array: () => isUint8Array,
|
|
113
113
|
isUndefined: () => isUndefined,
|
|
114
114
|
isUrl: () => isUrl,
|
|
115
|
+
isValidISO8601: () => isValidISO8601,
|
|
115
116
|
isValidSelector: () => isValidSelector,
|
|
116
117
|
location: () => location,
|
|
117
118
|
mergeThemeDefaultSettings: () => mergeThemeDefaultSettings,
|
|
@@ -1052,6 +1053,14 @@ var buildConfig = (config) => {
|
|
|
1052
1053
|
hideRulesSetting: (config == null ? void 0 : config.hideRulesSetting) || {}
|
|
1053
1054
|
};
|
|
1054
1055
|
};
|
|
1056
|
+
var extractUserAttributeValue = (element, userAttributes) => {
|
|
1057
|
+
if (!userAttributes || !("attrCode" in element) || typeof element.attrCode !== "string") {
|
|
1058
|
+
return "fallback" in element && typeof element.fallback === "string" ? element.fallback : "";
|
|
1059
|
+
}
|
|
1060
|
+
const attrValue = userAttributes[element.attrCode];
|
|
1061
|
+
const fallback = "fallback" in element && typeof element.fallback === "string" ? element.fallback : "";
|
|
1062
|
+
return attrValue != null ? attrValue : fallback;
|
|
1063
|
+
};
|
|
1055
1064
|
var extractLinkUrl = (value, userAttributes) => {
|
|
1056
1065
|
let url = "";
|
|
1057
1066
|
try {
|
|
@@ -1059,13 +1068,7 @@ var extractLinkUrl = (value, userAttributes) => {
|
|
|
1059
1068
|
if ("children" in v && Array.isArray(v.children)) {
|
|
1060
1069
|
for (const vc of v.children) {
|
|
1061
1070
|
if ("type" in vc && vc.type === "user-attribute") {
|
|
1062
|
-
|
|
1063
|
-
const attrValue = userAttributes[vc.attrCode];
|
|
1064
|
-
const fallback = "fallback" in vc && typeof vc.fallback === "string" ? vc.fallback : "";
|
|
1065
|
-
url += attrValue != null ? attrValue : fallback;
|
|
1066
|
-
} else if ("fallback" in vc && typeof vc.fallback === "string") {
|
|
1067
|
-
url += vc.fallback;
|
|
1068
|
-
}
|
|
1071
|
+
url += String(extractUserAttributeValue(vc, userAttributes));
|
|
1069
1072
|
} else if ("text" in vc && typeof vc.text === "string") {
|
|
1070
1073
|
url += vc.text;
|
|
1071
1074
|
}
|
|
@@ -1082,7 +1085,7 @@ var replaceUserAttrForElement = (data, userAttributes) => {
|
|
|
1082
1085
|
v.children = replaceUserAttrForElement(v.children, userAttributes);
|
|
1083
1086
|
}
|
|
1084
1087
|
if (v.type === "user-attribute" && userAttributes) {
|
|
1085
|
-
const value =
|
|
1088
|
+
const value = extractUserAttributeValue(v, userAttributes);
|
|
1086
1089
|
if (!isUndefined(value)) {
|
|
1087
1090
|
v.value = String(value);
|
|
1088
1091
|
}
|
|
@@ -1634,46 +1637,34 @@ var allConditionsHaveIds = (conditions) => {
|
|
|
1634
1637
|
// src/attribute.ts
|
|
1635
1638
|
var import_types6 = require("@usertour/types");
|
|
1636
1639
|
var import_date_fns3 = require("date-fns");
|
|
1637
|
-
var
|
|
1638
|
-
|
|
1639
|
-
return year >= 1900 && year <= 2100;
|
|
1640
|
-
};
|
|
1641
|
-
var tryParseDate = (parser) => {
|
|
1642
|
-
try {
|
|
1643
|
-
const date = parser();
|
|
1644
|
-
return (0, import_date_fns3.isValid)(date) && isValidYear(date);
|
|
1645
|
-
} catch {
|
|
1640
|
+
var isValidISO8601 = (value) => {
|
|
1641
|
+
if (typeof value !== "string") {
|
|
1646
1642
|
return false;
|
|
1647
1643
|
}
|
|
1648
|
-
}
|
|
1649
|
-
|
|
1650
|
-
if (!Number.isNaN(Number(dateStr)) || dateStr.length < 10) {
|
|
1644
|
+
const iso8601Pattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/;
|
|
1645
|
+
if (!iso8601Pattern.test(value)) {
|
|
1651
1646
|
return false;
|
|
1652
1647
|
}
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
"
|
|
1660
|
-
"
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
];
|
|
1665
|
-
if (tryParseDate(() => (0, import_date_fns3.parseISO)(dateStr))) {
|
|
1666
|
-
return true;
|
|
1648
|
+
try {
|
|
1649
|
+
const date = (0, import_date_fns3.parseISO)(value);
|
|
1650
|
+
if (!(0, import_date_fns3.isValid)(date)) {
|
|
1651
|
+
return false;
|
|
1652
|
+
}
|
|
1653
|
+
const isoString = date.toISOString();
|
|
1654
|
+
const normalizedInput = value.replace(/\.\d{3}Z$/, "Z");
|
|
1655
|
+
const normalizedIso = isoString.replace(/\.\d{3}Z$/, "Z");
|
|
1656
|
+
return normalizedInput === normalizedIso || value === isoString;
|
|
1657
|
+
} catch {
|
|
1658
|
+
return false;
|
|
1667
1659
|
}
|
|
1668
|
-
|
|
1669
|
-
}
|
|
1660
|
+
};
|
|
1670
1661
|
var getAttributeType = (attribute) => {
|
|
1671
1662
|
const t = typeof attribute;
|
|
1672
1663
|
if (t === "number") {
|
|
1673
1664
|
return import_types6.BizAttributeTypes.Number;
|
|
1674
1665
|
}
|
|
1675
1666
|
if (t === "string") {
|
|
1676
|
-
if (
|
|
1667
|
+
if (isValidISO8601(attribute)) {
|
|
1677
1668
|
return import_types6.BizAttributeTypes.DateTime;
|
|
1678
1669
|
}
|
|
1679
1670
|
return import_types6.BizAttributeTypes.String;
|
|
@@ -1778,6 +1769,7 @@ var filterNullAttributes = (attributes) => {
|
|
|
1778
1769
|
isUint8Array,
|
|
1779
1770
|
isUndefined,
|
|
1780
1771
|
isUrl,
|
|
1772
|
+
isValidISO8601,
|
|
1781
1773
|
isValidSelector,
|
|
1782
1774
|
location,
|
|
1783
1775
|
mergeThemeDefaultSettings,
|
package/dist/index.d.cts
CHANGED
|
@@ -13,7 +13,7 @@ export { allConditionsHaveIds, assignConditionIds, conditionsIsSame, evaluateRul
|
|
|
13
13
|
export { evaluateUrlCondition, isMatchUrlPattern } from './conditions/url.cjs';
|
|
14
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
|
+
export { capitalizeFirstLetter, filterNullAttributes, getAttributeType, isValidISO8601 } from './attribute.cjs';
|
|
17
17
|
export { default as isEqual } from 'fast-deep-equal';
|
|
18
18
|
import '@usertour/types';
|
|
19
19
|
import './storage.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export { allConditionsHaveIds, assignConditionIds, conditionsIsSame, evaluateRul
|
|
|
13
13
|
export { evaluateUrlCondition, isMatchUrlPattern } from './conditions/url.js';
|
|
14
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
|
+
export { capitalizeFirstLetter, filterNullAttributes, getAttributeType, isValidISO8601 } from './attribute.js';
|
|
17
17
|
export { default as isEqual } from 'fast-deep-equal';
|
|
18
18
|
import '@usertour/types';
|
|
19
19
|
import './storage.js';
|
package/dist/index.js
CHANGED
|
@@ -12,8 +12,9 @@ import {
|
|
|
12
12
|
import {
|
|
13
13
|
capitalizeFirstLetter,
|
|
14
14
|
filterNullAttributes,
|
|
15
|
-
getAttributeType
|
|
16
|
-
|
|
15
|
+
getAttributeType,
|
|
16
|
+
isValidISO8601
|
|
17
|
+
} from "./chunk-R4R6MDTW.js";
|
|
17
18
|
import {
|
|
18
19
|
getAuthToken,
|
|
19
20
|
removeAuthToken,
|
|
@@ -59,7 +60,7 @@ import {
|
|
|
59
60
|
isPublishedAtLeastOneEnvironment,
|
|
60
61
|
isPublishedInAllEnvironments,
|
|
61
62
|
replaceUserAttr
|
|
62
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-GK5DM6EN.js";
|
|
63
64
|
import {
|
|
64
65
|
convertSettings,
|
|
65
66
|
convertToCssVars,
|
|
@@ -206,6 +207,7 @@ export {
|
|
|
206
207
|
isUint8Array,
|
|
207
208
|
isUndefined,
|
|
208
209
|
isUrl,
|
|
210
|
+
isValidISO8601,
|
|
209
211
|
isValidSelector,
|
|
210
212
|
location,
|
|
211
213
|
mergeThemeDefaultSettings,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usertour/helpers",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.46",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Utility functions and helpers shared across the UserTour project",
|
|
6
6
|
"homepage": "https://www.usertour.io",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@paralleldrive/cuid2": "^2.2.2",
|
|
32
|
-
"@usertour/types": "^0.0.
|
|
32
|
+
"@usertour/types": "^0.0.33",
|
|
33
33
|
"chroma-js": "^3.1.2",
|
|
34
34
|
"class-variance-authority": "^0.4.0",
|
|
35
35
|
"clsx": "^1.2.1",
|