@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.
@@ -14,46 +14,34 @@ var objToString = ObjProto.toString;
14
14
  var objHasOwn = ObjProto.hasOwnProperty;
15
15
 
16
16
  // src/attribute.ts
17
- var isValidYear = (date) => {
18
- const year = date.getFullYear();
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
- function isDateString(dateStr) {
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
- const dateFormats = [
34
- "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
35
- "yyyy-MM-dd'T'HH:mm:ss'Z'",
36
- "yyyy-MM-dd'T'HH:mm:ss.SSS",
37
- "yyyy-MM-dd'T'HH:mm:ss",
38
- "yyyy-MM-dd",
39
- "MM/dd/yyyy",
40
- "dd/MM/yyyy",
41
- "yyyy/MM/dd",
42
- "MM-dd-yyyy",
43
- "dd-MM-yyyy"
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
- return dateFormats.some((format) => tryParseDate(() => (0, import_date_fns.parse)(dateStr, format, /* @__PURE__ */ new Date())));
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 (isDateString(attribute)) {
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 time", () => {
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 without timezone", () => {
111
- expect(getAttributeType("2024-12-11T16:00:00")).toBe(import_types2.BizAttributeTypes.DateTime);
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 DateTime for ISO 8601 date only", () => {
114
- expect(getAttributeType("2024-12-11")).toBe(import_types2.BizAttributeTypes.DateTime);
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 DateTime for MM/DD/YYYY format", () => {
117
- expect(getAttributeType("12/12/2024")).toBe(import_types2.BizAttributeTypes.DateTime);
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 DateTime for YYYY/MM/DD format", () => {
120
- expect(getAttributeType("2024/12/11")).toBe(import_types2.BizAttributeTypes.DateTime);
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 DateTime for MM-DD-YYYY format", () => {
123
- expect(getAttributeType("12-12-2024")).toBe(import_types2.BizAttributeTypes.DateTime);
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 DateTime for DD-MM-YYYY format", () => {
126
- expect(getAttributeType("11-12-2024")).toBe(import_types2.BizAttributeTypes.DateTime);
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 date string", () => {
129
- expect(getAttributeType("2024-13-45")).toBe(import_types2.BizAttributeTypes.String);
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 date string with invalid year (< 1900)", () => {
132
- expect(getAttributeType("1899-12-11")).toBe(import_types2.BizAttributeTypes.String);
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 date string with invalid year (> 2100)", () => {
135
- expect(getAttributeType("2101-12-11")).toBe(import_types2.BizAttributeTypes.String);
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 DateTime for string that is exactly 10 characters and valid date", () => {
186
- expect(getAttributeType("2024-12-11")).toBe(import_types2.BizAttributeTypes.DateTime);
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
- } from "../chunk-EEYZG4JJ.js";
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 time", () => {
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 without timezone", () => {
49
- expect(getAttributeType("2024-12-11T16:00:00")).toBe(BizAttributeTypes.DateTime);
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 date only", () => {
52
- expect(getAttributeType("2024-12-11")).toBe(BizAttributeTypes.DateTime);
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 DateTime for MM/DD/YYYY format", () => {
55
- expect(getAttributeType("12/12/2024")).toBe(BizAttributeTypes.DateTime);
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 DateTime for YYYY/MM/DD format", () => {
58
- expect(getAttributeType("2024/12/11")).toBe(BizAttributeTypes.DateTime);
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 DateTime for MM-DD-YYYY format", () => {
61
- expect(getAttributeType("12-12-2024")).toBe(BizAttributeTypes.DateTime);
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 DateTime for DD-MM-YYYY format", () => {
64
- expect(getAttributeType("11-12-2024")).toBe(BizAttributeTypes.DateTime);
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 invalid date string", () => {
67
- expect(getAttributeType("2024-13-45")).toBe(BizAttributeTypes.String);
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 date string with invalid year (< 1900)", () => {
70
- expect(getAttributeType("1899-12-11")).toBe(BizAttributeTypes.String);
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 date string with invalid year (> 2100)", () => {
73
- expect(getAttributeType("2101-12-11")).toBe(BizAttributeTypes.String);
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 DateTime for string that is exactly 10 characters and valid date", () => {
124
- expect(getAttributeType("2024-12-11")).toBe(BizAttributeTypes.DateTime);
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
+ });
@@ -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 isValidYear = (date) => {
42
- const year = date.getFullYear();
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
- function isDateString(dateStr) {
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
- const dateFormats = [
58
- "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
59
- "yyyy-MM-dd'T'HH:mm:ss'Z'",
60
- "yyyy-MM-dd'T'HH:mm:ss.SSS",
61
- "yyyy-MM-dd'T'HH:mm:ss",
62
- "yyyy-MM-dd",
63
- "MM/dd/yyyy",
64
- "dd/MM/yyyy",
65
- "yyyy/MM/dd",
66
- "MM-dd-yyyy",
67
- "dd-MM-yyyy"
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
- return dateFormats.some((format) => tryParseDate(() => (0, import_date_fns.parse)(dateStr, format, /* @__PURE__ */ new Date())));
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 (isDateString(attribute)) {
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
  });
@@ -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 };
@@ -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
- } from "./chunk-EEYZG4JJ.js";
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
- if (userAttributes && "attrCode" in vc && typeof vc.attrCode === "string") {
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 = userAttributes[v.attrCode] || v.fallback;
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, parse } from "date-fns";
8
- var isValidYear = (date) => {
9
- const year = date.getFullYear();
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
- function isDateString(dateStr) {
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
- const dateFormats = [
25
- "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
26
- "yyyy-MM-dd'T'HH:mm:ss'Z'",
27
- "yyyy-MM-dd'T'HH:mm:ss.SSS",
28
- "yyyy-MM-dd'T'HH:mm:ss",
29
- "yyyy-MM-dd",
30
- "MM/dd/yyyy",
31
- "dd/MM/yyyy",
32
- "yyyy/MM/dd",
33
- "MM-dd-yyyy",
34
- "dd-MM-yyyy"
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
- return dateFormats.some((format) => tryParseDate(() => parse(dateStr, format, /* @__PURE__ */ new Date())));
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 (isDateString(attribute)) {
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
- if (userAttributes && "attrCode" in vc && typeof vc.attrCode === "string") {
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 = userAttributes[v.attrCode] || v.fallback;
125
+ const value = extractUserAttributeValue(v, userAttributes);
124
126
  if (!isUndefined(value)) {
125
127
  v.value = String(value);
126
128
  }
package/dist/content.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  isPublishedAtLeastOneEnvironment,
6
6
  isPublishedInAllEnvironments,
7
7
  replaceUserAttr
8
- } from "./chunk-MU3AHQEC.js";
8
+ } from "./chunk-GK5DM6EN.js";
9
9
  import "./chunk-GFH3VWOC.js";
10
10
  import "./chunk-XEO3YXBM.js";
11
11
  export {
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
- if (userAttributes && "attrCode" in vc && typeof vc.attrCode === "string") {
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 = userAttributes[v.attrCode] || v.fallback;
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 isValidYear = (date) => {
1638
- const year = date.getFullYear();
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
- function isDateString(dateStr) {
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
- const dateFormats = [
1654
- "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
1655
- "yyyy-MM-dd'T'HH:mm:ss'Z'",
1656
- "yyyy-MM-dd'T'HH:mm:ss.SSS",
1657
- "yyyy-MM-dd'T'HH:mm:ss",
1658
- "yyyy-MM-dd",
1659
- "MM/dd/yyyy",
1660
- "dd/MM/yyyy",
1661
- "yyyy/MM/dd",
1662
- "MM-dd-yyyy",
1663
- "dd-MM-yyyy"
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
- return dateFormats.some((format) => tryParseDate(() => (0, import_date_fns3.parse)(dateStr, format, /* @__PURE__ */ new Date())));
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 (isDateString(attribute)) {
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
- } from "./chunk-EEYZG4JJ.js";
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-MU3AHQEC.js";
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.44",
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.31",
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",