@arsedizioni/ars-utils 22.6.85 → 22.6.88
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/fesm2022/arsedizioni-ars-utils-clipper.common.mjs +3158 -3344
- package/fesm2022/arsedizioni-ars-utils-clipper.common.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-clipper.ui.mjs +7616 -4772
- package/fesm2022/arsedizioni-ars-utils-clipper.ui.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-core.date.mjs +321 -702
- package/fesm2022/arsedizioni-ars-utils-core.date.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-core.markdown.mjs +445 -590
- package/fesm2022/arsedizioni-ars-utils-core.markdown.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-core.mjs +1735 -2370
- package/fesm2022/arsedizioni-ars-utils-core.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-core.validators.mjs +1280 -1470
- package/fesm2022/arsedizioni-ars-utils-core.validators.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-evolution.common.mjs +1097 -1528
- package/fesm2022/arsedizioni-ars-utils-evolution.common.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-support.common.mjs +198 -294
- package/fesm2022/arsedizioni-ars-utils-support.common.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.controls.date.mjs +115 -117
- package/fesm2022/arsedizioni-ars-utils-ui.controls.date.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.controls.mjs +1607 -613
- package/fesm2022/arsedizioni-ars-utils-ui.controls.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.controls.tree.mjs +840 -367
- package/fesm2022/arsedizioni-ars-utils-ui.controls.tree.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.auth.mjs +1634 -651
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.auth.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.mjs +1255 -792
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.prompt.mjs +1410 -357
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.prompt.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.select.mjs +2401 -944
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.select.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.files.mjs +1553 -741
- package/fesm2022/arsedizioni-ars-utils-ui.files.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.filters.mjs +901 -430
- package/fesm2022/arsedizioni-ars-utils-ui.filters.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.help.mjs +737 -530
- package/fesm2022/arsedizioni-ars-utils-ui.help.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.mjs +6638 -1755
- package/fesm2022/arsedizioni-ars-utils-ui.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.navigation.mjs +1479 -1207
- package/fesm2022/arsedizioni-ars-utils-ui.navigation.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.notifications.mjs +1003 -270
- package/fesm2022/arsedizioni-ars-utils-ui.notifications.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.oauth.mjs +497 -278
- package/fesm2022/arsedizioni-ars-utils-ui.oauth.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.paginator.mjs +48 -52
- package/fesm2022/arsedizioni-ars-utils-ui.paginator.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.shell.mjs +464 -704
- package/fesm2022/arsedizioni-ars-utils-ui.shell.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.tinymce.mjs +724 -657
- package/fesm2022/arsedizioni-ars-utils-ui.tinymce.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils.mjs +3 -19
- package/fesm2022/arsedizioni-ars-utils.mjs.map +1 -1
- package/package.json +1 -1
- package/types/arsedizioni-ars-utils-clipper.common.d.ts +1151 -1163
- package/types/arsedizioni-ars-utils-clipper.ui.d.ts +1588 -1426
- package/types/arsedizioni-ars-utils-core.d.ts +1169 -1172
- package/types/arsedizioni-ars-utils-core.date.d.ts +204 -208
- package/types/arsedizioni-ars-utils-core.markdown.d.ts +128 -126
- package/types/arsedizioni-ars-utils-core.validators.d.ts +270 -236
- package/types/arsedizioni-ars-utils-evolution.common.d.ts +1054 -1067
- package/types/arsedizioni-ars-utils-support.common.d.ts +225 -234
- package/types/arsedizioni-ars-utils-ui.controls.d.ts +440 -278
- package/types/arsedizioni-ars-utils-ui.controls.date.d.ts +24 -28
- package/types/arsedizioni-ars-utils-ui.controls.tree.d.ts +172 -136
- package/types/arsedizioni-ars-utils-ui.d.ts +2035 -821
- package/types/arsedizioni-ars-utils-ui.dialogs.auth.d.ts +327 -322
- package/types/arsedizioni-ars-utils-ui.dialogs.d.ts +343 -347
- package/types/arsedizioni-ars-utils-ui.dialogs.prompt.d.ts +167 -167
- package/types/arsedizioni-ars-utils-ui.dialogs.select.d.ts +373 -367
- package/types/arsedizioni-ars-utils-ui.files.d.ts +335 -283
- package/types/arsedizioni-ars-utils-ui.filters.d.ts +232 -160
- package/types/arsedizioni-ars-utils-ui.help.d.ts +204 -211
- package/types/arsedizioni-ars-utils-ui.navigation.d.ts +811 -646
- package/types/arsedizioni-ars-utils-ui.notifications.d.ts +74 -78
- package/types/arsedizioni-ars-utils-ui.oauth.d.ts +102 -62
- package/types/arsedizioni-ars-utils-ui.paginator.d.ts +19 -22
- package/types/arsedizioni-ars-utils-ui.shell.d.ts +376 -382
- package/types/arsedizioni-ars-utils-ui.tinymce.d.ts +244 -231
- package/types/arsedizioni-ars-utils.d.ts +1 -3
|
@@ -1,738 +1,357 @@
|
|
|
1
|
-
import * as i0 from
|
|
2
|
-
import {
|
|
3
|
-
import { DateAdapter,
|
|
4
|
-
import { TZDate } from
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { map } from
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Creates an array of the given length, filling each slot with the result of `valueFunction`.
|
|
11
|
-
* @param length - Number of elements to create.
|
|
12
|
-
* @param valueFunction - Factory called with each index to produce the element value.
|
|
13
|
-
* @returns Typed array of `length` elements.
|
|
14
|
-
*/
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { Injectable, InjectionToken, inject, makeEnvironmentProviders } from "@angular/core";
|
|
3
|
+
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from "@angular/material/core";
|
|
4
|
+
import { TZDate } from "@date-fns/tz";
|
|
5
|
+
import { addDays, addMonths, addSeconds, addYears, format, getDate, getDay, getDaysInMonth, getMonth, getYear, isDate, isValid, parse, parseISO } from "date-fns";
|
|
6
|
+
import { HTTP_INTERCEPTORS, HttpResponse } from "@angular/common/http";
|
|
7
|
+
import { map } from "rxjs";
|
|
15
8
|
function range(length, valueFunction) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
return valuesArray;
|
|
9
|
+
const valuesArray = Array(length);
|
|
10
|
+
for (let i = 0; i < length; i++) valuesArray[i] = valueFunction(i);
|
|
11
|
+
return valuesArray;
|
|
21
12
|
}
|
|
22
|
-
// date-fns doesn't have a way to read/print month names or days of the week directly,
|
|
23
|
-
// so we get them by formatting a date with a format that produces the desired month/day.
|
|
24
13
|
const MONTH_FORMATS = {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
14
|
+
long: "LLLL",
|
|
15
|
+
short: "LLL",
|
|
16
|
+
narrow: "LLLLL"
|
|
28
17
|
};
|
|
29
18
|
const DAY_OF_WEEK_FORMATS = {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
19
|
+
long: "EEEE",
|
|
20
|
+
short: "EEE",
|
|
21
|
+
narrow: "EEEEE"
|
|
33
22
|
};
|
|
34
23
|
const MAT_DATE_FNS_FORMATS = {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
24
|
+
parse: {
|
|
25
|
+
dateInput: "P",
|
|
26
|
+
timeInput: [
|
|
27
|
+
"p",
|
|
28
|
+
"HH:mm",
|
|
29
|
+
"H:mm"
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
display: {
|
|
33
|
+
dateInput: "P",
|
|
34
|
+
monthYearLabel: "LLL uuuu",
|
|
35
|
+
dateA11yLabel: "PP",
|
|
36
|
+
monthYearA11yLabel: "LLLL uuuu",
|
|
37
|
+
timeInput: "p",
|
|
38
|
+
timeOptionLabel: "p"
|
|
39
|
+
}
|
|
47
40
|
};
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
return this.invalid();
|
|
236
|
-
}
|
|
237
|
-
else if (typeof value === 'number') {
|
|
238
|
-
return DateFnsAdapter.toLocal(value);
|
|
239
|
-
}
|
|
240
|
-
else if (value instanceof Date) {
|
|
241
|
-
return this.clone(value);
|
|
242
|
-
}
|
|
243
|
-
return null;
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* Formats a `Date` using the given date-fns display format string.
|
|
247
|
-
* Throws an `Error` when `date` is not valid.
|
|
248
|
-
* @param date - The date to format.
|
|
249
|
-
* @param displayFormat - A date-fns format string (e.g. `'P'`, `'LLL uuuu'`).
|
|
250
|
-
*/
|
|
251
|
-
format(date, displayFormat) {
|
|
252
|
-
if (!this.isValid(date)) {
|
|
253
|
-
throw Error('DateFnsAdapter: Cannot format invalid date.');
|
|
254
|
-
}
|
|
255
|
-
return format(date, displayFormat, { locale: this.locale });
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Adds the given number of whole years to a date.
|
|
259
|
-
* @param date - The base date.
|
|
260
|
-
* @param years - Number of years to add (can be negative).
|
|
261
|
-
*/
|
|
262
|
-
addCalendarYears(date, years) {
|
|
263
|
-
return DateFnsAdapter.toLocal(addYears(date, years));
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Adds the given number of whole months to a date.
|
|
267
|
-
* @param date - The base date.
|
|
268
|
-
* @param months - Number of months to add (can be negative).
|
|
269
|
-
*/
|
|
270
|
-
addCalendarMonths(date, months) {
|
|
271
|
-
return DateFnsAdapter.toLocal(addMonths(date, months));
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
* Adds the given number of whole days to a date.
|
|
275
|
-
* @param date - The base date.
|
|
276
|
-
* @param days - Number of days to add (can be negative).
|
|
277
|
-
*/
|
|
278
|
-
addCalendarDays(date, days) {
|
|
279
|
-
return DateFnsAdapter.toLocal(addDays(date, days));
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* Serialises a date to an ISO 8601 date-only string (`yyyy-MM-dd`) using its Europe/Rome calendar day,
|
|
283
|
-
* independent of the browser timezone.
|
|
284
|
-
* @param date - The date to serialise.
|
|
285
|
-
* @returns the yyyy-MM-dd string for the date in Europe/Rome.
|
|
286
|
-
*/
|
|
287
|
-
toIso8601(date) {
|
|
288
|
-
return format(new TZDate(date, 'Europe/Rome'), 'yyyy-MM-dd');
|
|
289
|
-
}
|
|
290
|
-
/**
|
|
291
|
-
* Returns the given value when it is a valid `Date`, or `null` for an empty string.
|
|
292
|
-
* Deserialises valid ISO 8601 strings into `Date` instances.
|
|
293
|
-
* Delegates all other values to the base-class implementation.
|
|
294
|
-
* @param value - The raw value to deserialise.
|
|
295
|
-
*/
|
|
296
|
-
deserialize(value) {
|
|
297
|
-
if (value === null || value === undefined) {
|
|
298
|
-
return null;
|
|
299
|
-
}
|
|
300
|
-
if (typeof value === 'string') {
|
|
301
|
-
const trimmedValue = value.trim();
|
|
302
|
-
if (trimmedValue.length === 0) {
|
|
303
|
-
return null;
|
|
304
|
-
}
|
|
305
|
-
const date = parseISO(trimmedValue);
|
|
306
|
-
if (this.isValid(date)) {
|
|
307
|
-
return DateFnsAdapter.toLocal(date);
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
return super.deserialize(value);
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* Returns `true` when `obj` is an instance of `Date`.
|
|
314
|
-
* @param obj - The object to test.
|
|
315
|
-
*/
|
|
316
|
-
isDateInstance(obj) {
|
|
317
|
-
return isDate(obj);
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* Returns `true` when `date` represents a valid point in time.
|
|
321
|
-
* @param date - The date to validate.
|
|
322
|
-
*/
|
|
323
|
-
isValid(date) {
|
|
324
|
-
return isValid(date);
|
|
325
|
-
}
|
|
326
|
-
/**
|
|
327
|
-
* Returns a sentinel `Date` that represents an invalid date (`new Date(NaN)`).
|
|
328
|
-
*/
|
|
329
|
-
invalid() {
|
|
330
|
-
return new Date(NaN);
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* Returns the hours component (0-23) of the given date.
|
|
334
|
-
* @param date - The source date.
|
|
335
|
-
*/
|
|
336
|
-
getHours(date) {
|
|
337
|
-
return date.getHours();
|
|
338
|
-
}
|
|
339
|
-
/**
|
|
340
|
-
* Returns the minutes component (0-59) of the given date.
|
|
341
|
-
* @param date - The source date.
|
|
342
|
-
*/
|
|
343
|
-
getMinutes(date) {
|
|
344
|
-
return date.getMinutes();
|
|
345
|
-
}
|
|
346
|
-
/**
|
|
347
|
-
* Returns the seconds component (0-59) of the given date.
|
|
348
|
-
* @param date - The source date.
|
|
349
|
-
*/
|
|
350
|
-
getSeconds(date) {
|
|
351
|
-
return date.getSeconds();
|
|
352
|
-
}
|
|
353
|
-
/**
|
|
354
|
-
* Returns a clone of `target` with its time-of-day set to the given hours/minutes/seconds,
|
|
355
|
-
* keeping the date part unchanged.
|
|
356
|
-
* @param target - The date whose time should be set.
|
|
357
|
-
* @param hours - New hours (0-23).
|
|
358
|
-
* @param minutes - New minutes (0-59).
|
|
359
|
-
* @param seconds - New seconds (0-59).
|
|
360
|
-
*/
|
|
361
|
-
setTime(target, hours, minutes, seconds) {
|
|
362
|
-
const clone = this.clone(target);
|
|
363
|
-
clone.setHours(hours, minutes, seconds, 0);
|
|
364
|
-
return clone;
|
|
365
|
-
}
|
|
366
|
-
/**
|
|
367
|
-
* Adds the given number of seconds to a date.
|
|
368
|
-
* @param date - The base date.
|
|
369
|
-
* @param amount - Number of seconds to add (can be negative).
|
|
370
|
-
*/
|
|
371
|
-
addSeconds(date, amount) {
|
|
372
|
-
return DateFnsAdapter.toLocal(addSeconds(date, amount));
|
|
373
|
-
}
|
|
374
|
-
/**
|
|
375
|
-
* Parses a time-only value into a `Date` (today's date, in `Europe/Rome`, with the parsed
|
|
376
|
-
* time-of-day set). The wall-clock time is preserved exactly as entered.
|
|
377
|
-
* @param value - The value to parse (a string, or an existing `Date`).
|
|
378
|
-
* @param parseFormat - A format string or an array of format strings (date-fns tokens).
|
|
379
|
-
* @returns the parsed Date, an invalid sentinel, or null for unrecognised input.
|
|
380
|
-
*/
|
|
381
|
-
parseTime(value, parseFormat) {
|
|
382
|
-
if (typeof value === 'string' && value.length > 0) {
|
|
383
|
-
const formats = Array.isArray(parseFormat) ? parseFormat : [parseFormat];
|
|
384
|
-
if (!formats.length) {
|
|
385
|
-
throw Error('Formats array must not be empty.');
|
|
386
|
-
}
|
|
387
|
-
const referenceDate = new TZDate(new Date(), 'Europe/Rome');
|
|
388
|
-
for (const currentFormat of formats) {
|
|
389
|
-
const fromFormat = parse(value, currentFormat, referenceDate, { locale: this.locale });
|
|
390
|
-
if (this.isValid(fromFormat)) {
|
|
391
|
-
return DateFnsAdapter.toLocal(fromFormat);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
return this.invalid();
|
|
395
|
-
}
|
|
396
|
-
else if (value instanceof Date) {
|
|
397
|
-
return this.clone(value);
|
|
398
|
-
}
|
|
399
|
-
return null;
|
|
400
|
-
}
|
|
401
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: DateFnsAdapter, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
402
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: DateFnsAdapter }); }
|
|
403
|
-
}
|
|
404
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: DateFnsAdapter, decorators: [{
|
|
405
|
-
type: Injectable
|
|
406
|
-
}], ctorParameters: () => [] });
|
|
407
|
-
/**
|
|
408
|
-
* Standalone providers for the ARS date-fns adapter.
|
|
409
|
-
*
|
|
410
|
-
* Configures Angular Material to use {@link DateFnsAdapter} (Europe/Rome timezone)
|
|
411
|
-
* and the matching {@link MAT_DATE_FNS_FORMATS}. Also supports `mat-timepicker` since
|
|
412
|
-
* {@link DateFnsAdapter} implements the time-related `DateAdapter` methods.
|
|
413
|
-
*
|
|
414
|
-
* @example
|
|
415
|
-
* bootstrapApplication(AppComponent, {
|
|
416
|
-
* providers: [provideArsDateFns()]
|
|
417
|
-
* });
|
|
418
|
-
*/
|
|
41
|
+
var DateFnsAdapter = class DateFnsAdapter extends DateAdapter {
|
|
42
|
+
constructor() {
|
|
43
|
+
super();
|
|
44
|
+
const matDateLocale = inject(MAT_DATE_LOCALE, { optional: true });
|
|
45
|
+
if (matDateLocale && typeof matDateLocale === "object") this.setLocale(matDateLocale);
|
|
46
|
+
}
|
|
47
|
+
static toLocal(value) {
|
|
48
|
+
const ms = typeof value === "number" ? value : value.getTime();
|
|
49
|
+
const t = new TZDate(ms, "Europe/Rome");
|
|
50
|
+
Object.defineProperty(t, "toJSON", {
|
|
51
|
+
value: () => format(t, "yyyy-MM-dd'T'HH:mm:ss"),
|
|
52
|
+
enumerable: false,
|
|
53
|
+
configurable: true,
|
|
54
|
+
writable: true
|
|
55
|
+
});
|
|
56
|
+
return t;
|
|
57
|
+
}
|
|
58
|
+
getYear(date) {
|
|
59
|
+
return getYear(date);
|
|
60
|
+
}
|
|
61
|
+
getMonth(date) {
|
|
62
|
+
return getMonth(date);
|
|
63
|
+
}
|
|
64
|
+
getDate(date) {
|
|
65
|
+
return getDate(date);
|
|
66
|
+
}
|
|
67
|
+
getDayOfWeek(date) {
|
|
68
|
+
return getDay(date);
|
|
69
|
+
}
|
|
70
|
+
getMonthNames(style) {
|
|
71
|
+
const pattern = MONTH_FORMATS[style];
|
|
72
|
+
return range(12, (i) => this.format(new Date(2017, i, 1), pattern));
|
|
73
|
+
}
|
|
74
|
+
getDateNames() {
|
|
75
|
+
const dtf = typeof Intl !== "undefined" ? new Intl.DateTimeFormat(this.locale?.code, {
|
|
76
|
+
day: "numeric",
|
|
77
|
+
timeZone: "utc"
|
|
78
|
+
}) : null;
|
|
79
|
+
return range(31, (i) => {
|
|
80
|
+
if (dtf) {
|
|
81
|
+
const date = /* @__PURE__ */ new Date();
|
|
82
|
+
date.setUTCFullYear(2017, 0, i + 1);
|
|
83
|
+
date.setUTCHours(0, 0, 0, 0);
|
|
84
|
+
return dtf.format(date).replace(/[\u200e\u200f]/g, "");
|
|
85
|
+
}
|
|
86
|
+
return String(i + 1);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
getDayOfWeekNames(style) {
|
|
90
|
+
const pattern = DAY_OF_WEEK_FORMATS[style];
|
|
91
|
+
return range(7, (i) => this.format(new Date(2017, 0, i + 1), pattern));
|
|
92
|
+
}
|
|
93
|
+
getYearName(date) {
|
|
94
|
+
return this.format(date, "y");
|
|
95
|
+
}
|
|
96
|
+
getFirstDayOfWeek() {
|
|
97
|
+
return this.locale?.options?.weekStartsOn ?? 0;
|
|
98
|
+
}
|
|
99
|
+
getNumDaysInMonth(date) {
|
|
100
|
+
return getDaysInMonth(date);
|
|
101
|
+
}
|
|
102
|
+
clone(date) {
|
|
103
|
+
return DateFnsAdapter.toLocal(date.getTime());
|
|
104
|
+
}
|
|
105
|
+
createDate(year, month, date) {
|
|
106
|
+
if (month < 0 || month > 11) throw Error(`Invalid month index "${month}". Month index has to be between 0 and 11.`);
|
|
107
|
+
if (date < 1) throw Error(`Invalid date "${date}". Date has to be greater than 0.`);
|
|
108
|
+
if (month < 0 || month > 11) throw Error(`Invalid month index "${month}". Month index has to be between 0 and 11.`);
|
|
109
|
+
const result = new TZDate(year, month, date, 0, 0, 0, 0, "Europe/Rome");
|
|
110
|
+
if (result.getMonth() !== month) throw Error(`Invalid date "${date}" for month with index "${month}".`);
|
|
111
|
+
return DateFnsAdapter.toLocal(result);
|
|
112
|
+
}
|
|
113
|
+
today() {
|
|
114
|
+
return DateFnsAdapter.toLocal(/* @__PURE__ */ new Date());
|
|
115
|
+
}
|
|
116
|
+
parse(value, parseFormat) {
|
|
117
|
+
if (value === null || value === void 0) return null;
|
|
118
|
+
if (typeof value === "string") {
|
|
119
|
+
const trimmedValue = value.trim();
|
|
120
|
+
if (trimmedValue.length === 0) return null;
|
|
121
|
+
const iso8601Date = parseISO(trimmedValue);
|
|
122
|
+
if (this.isValid(iso8601Date)) return DateFnsAdapter.toLocal(iso8601Date);
|
|
123
|
+
const formats = Array.isArray(parseFormat) ? parseFormat : [parseFormat];
|
|
124
|
+
if (!formats.length) throw Error("Formats array must not be empty.");
|
|
125
|
+
for (const currentFormat of formats) {
|
|
126
|
+
const fromFormat = parse(trimmedValue, currentFormat, new TZDate(/* @__PURE__ */ new Date(), "Europe/Rome"), { locale: this.locale });
|
|
127
|
+
if (this.isValid(fromFormat)) return DateFnsAdapter.toLocal(fromFormat);
|
|
128
|
+
}
|
|
129
|
+
return this.invalid();
|
|
130
|
+
} else if (typeof value === "number") return DateFnsAdapter.toLocal(value);
|
|
131
|
+
else if (value instanceof Date) return this.clone(value);
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
format(date, displayFormat) {
|
|
135
|
+
if (!this.isValid(date)) throw Error("DateFnsAdapter: Cannot format invalid date.");
|
|
136
|
+
return format(date, displayFormat, { locale: this.locale });
|
|
137
|
+
}
|
|
138
|
+
addCalendarYears(date, years) {
|
|
139
|
+
return DateFnsAdapter.toLocal(addYears(date, years));
|
|
140
|
+
}
|
|
141
|
+
addCalendarMonths(date, months) {
|
|
142
|
+
return DateFnsAdapter.toLocal(addMonths(date, months));
|
|
143
|
+
}
|
|
144
|
+
addCalendarDays(date, days) {
|
|
145
|
+
return DateFnsAdapter.toLocal(addDays(date, days));
|
|
146
|
+
}
|
|
147
|
+
toIso8601(date) {
|
|
148
|
+
return format(new TZDate(date, "Europe/Rome"), "yyyy-MM-dd");
|
|
149
|
+
}
|
|
150
|
+
deserialize(value) {
|
|
151
|
+
if (value === null || value === void 0) return null;
|
|
152
|
+
if (typeof value === "string") {
|
|
153
|
+
const trimmedValue = value.trim();
|
|
154
|
+
if (trimmedValue.length === 0) return null;
|
|
155
|
+
const date = parseISO(trimmedValue);
|
|
156
|
+
if (this.isValid(date)) return DateFnsAdapter.toLocal(date);
|
|
157
|
+
}
|
|
158
|
+
return super.deserialize(value);
|
|
159
|
+
}
|
|
160
|
+
isDateInstance(obj) {
|
|
161
|
+
return isDate(obj);
|
|
162
|
+
}
|
|
163
|
+
isValid(date) {
|
|
164
|
+
return isValid(date);
|
|
165
|
+
}
|
|
166
|
+
invalid() {
|
|
167
|
+
return /* @__PURE__ */ new Date(NaN);
|
|
168
|
+
}
|
|
169
|
+
getHours(date) {
|
|
170
|
+
return date.getHours();
|
|
171
|
+
}
|
|
172
|
+
getMinutes(date) {
|
|
173
|
+
return date.getMinutes();
|
|
174
|
+
}
|
|
175
|
+
getSeconds(date) {
|
|
176
|
+
return date.getSeconds();
|
|
177
|
+
}
|
|
178
|
+
setTime(target, hours, minutes, seconds) {
|
|
179
|
+
const clone = this.clone(target);
|
|
180
|
+
clone.setHours(hours, minutes, seconds, 0);
|
|
181
|
+
return clone;
|
|
182
|
+
}
|
|
183
|
+
addSeconds(date, amount) {
|
|
184
|
+
return DateFnsAdapter.toLocal(addSeconds(date, amount));
|
|
185
|
+
}
|
|
186
|
+
parseTime(value, parseFormat) {
|
|
187
|
+
if (typeof value === "string" && value.length > 0) {
|
|
188
|
+
const formats = Array.isArray(parseFormat) ? parseFormat : [parseFormat];
|
|
189
|
+
if (!formats.length) throw Error("Formats array must not be empty.");
|
|
190
|
+
const referenceDate = new TZDate(/* @__PURE__ */ new Date(), "Europe/Rome");
|
|
191
|
+
for (const currentFormat of formats) {
|
|
192
|
+
const fromFormat = parse(value, currentFormat, referenceDate, { locale: this.locale });
|
|
193
|
+
if (this.isValid(fromFormat)) return DateFnsAdapter.toLocal(fromFormat);
|
|
194
|
+
}
|
|
195
|
+
return this.invalid();
|
|
196
|
+
} else if (value instanceof Date) return this.clone(value);
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
static {
|
|
200
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
201
|
+
minVersion: "12.0.0",
|
|
202
|
+
version: "22.2.1",
|
|
203
|
+
ngImport: i0,
|
|
204
|
+
type: DateFnsAdapter,
|
|
205
|
+
deps: [],
|
|
206
|
+
target: i0.ɵɵFactoryTarget.Injectable
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
static {
|
|
210
|
+
this.ɵprov = i0.ɵɵngDeclareInjectable({
|
|
211
|
+
minVersion: "12.0.0",
|
|
212
|
+
version: "22.2.1",
|
|
213
|
+
ngImport: i0,
|
|
214
|
+
type: DateFnsAdapter
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
219
|
+
minVersion: "12.0.0",
|
|
220
|
+
version: "22.2.1",
|
|
221
|
+
ngImport: i0,
|
|
222
|
+
type: DateFnsAdapter,
|
|
223
|
+
decorators: [{ type: Injectable }],
|
|
224
|
+
ctorParameters: () => []
|
|
225
|
+
});
|
|
419
226
|
function provideArsDateFns() {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
227
|
+
return makeEnvironmentProviders([{
|
|
228
|
+
provide: DateAdapter,
|
|
229
|
+
useClass: DateFnsAdapter
|
|
230
|
+
}, {
|
|
231
|
+
provide: MAT_DATE_FORMATS,
|
|
232
|
+
useValue: MAT_DATE_FNS_FORMATS
|
|
233
|
+
}]);
|
|
427
234
|
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
* IANA timezone used to serialise dates towards the backend.
|
|
433
|
-
* Override it in the application providers to run the same code in another zone:
|
|
434
|
-
* `{ provide: ARS_TIME_ZONE, useValue: 'Europe/Zurich' }`.
|
|
435
|
-
*/
|
|
436
|
-
const ARS_TIME_ZONE = new InjectionToken('ARS_TIME_ZONE', {
|
|
437
|
-
providedIn: 'root',
|
|
438
|
-
factory: () => DEFAULT_TIME_ZONE,
|
|
235
|
+
const DEFAULT_TIME_ZONE = "Europe/Rome";
|
|
236
|
+
const ARS_TIME_ZONE = new InjectionToken("ARS_TIME_ZONE", {
|
|
237
|
+
providedIn: "root",
|
|
238
|
+
factory: () => DEFAULT_TIME_ZONE
|
|
439
239
|
});
|
|
440
|
-
/** Naive local datetime pattern (no timezone designator): the server reads it as DateTimeKind.Unspecified. */
|
|
441
240
|
const NAIVE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss";
|
|
442
|
-
/**
|
|
443
|
-
* What a string has to look like to be read back as a date: an ISO 8601 calendar date, optionally
|
|
444
|
-
* followed by a time and by `Z` or an offset. Anchored at both ends, so a string that merely
|
|
445
|
-
* *contains* a date ("Circolare del 2026-09-07") is left alone.
|
|
446
|
-
*/
|
|
447
241
|
const ISO_DATE_PATTERN = /^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,7}))?)?(Z|[+-]\d{2}:?\d{2})?)?$/;
|
|
448
|
-
/** Shortest string that can be a date (`2026-09-07`), and the longest one worth testing. */
|
|
449
242
|
const MIN_ISO_LENGTH = 10;
|
|
450
243
|
const MAX_ISO_LENGTH = 33;
|
|
451
|
-
/**
|
|
452
|
-
* Returns `true` for payloads that must be forwarded untouched
|
|
453
|
-
* (binary or already-encoded bodies).
|
|
454
|
-
* @param body - The request body to test.
|
|
455
|
-
*/
|
|
456
244
|
function isOpaqueBody(body) {
|
|
457
|
-
|
|
458
|
-
body instanceof Blob ||
|
|
459
|
-
body instanceof ArrayBuffer ||
|
|
460
|
-
ArrayBuffer.isView(body) ||
|
|
461
|
-
body instanceof URLSearchParams ||
|
|
462
|
-
typeof body === 'string');
|
|
245
|
+
return body instanceof FormData || body instanceof Blob || body instanceof ArrayBuffer || ArrayBuffer.isView(body) || body instanceof URLSearchParams || typeof body === "string";
|
|
463
246
|
}
|
|
464
|
-
/**
|
|
465
|
-
* Recursively replaces every `Date` found in `value` with its naive local
|
|
466
|
-
* datetime string, returning a NEW structure: the original object graph — and
|
|
467
|
-
* therefore any bound form model — is never mutated.
|
|
468
|
-
*
|
|
469
|
-
* @param value - The value to normalise (object, array, Date or primitive).
|
|
470
|
-
* @param timeZone - IANA timezone used to compute the wall-clock value.
|
|
471
|
-
* @param seen - Guard against circular references.
|
|
472
|
-
* @returns The normalised value, safe to hand over to `JSON.stringify`.
|
|
473
|
-
*/
|
|
474
247
|
function normalizeDates(value, timeZone, seen) {
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
seen.add(value);
|
|
489
|
-
if (Array.isArray(value)) {
|
|
490
|
-
return value.map(item => normalizeDates(item, timeZone, seen));
|
|
491
|
-
}
|
|
492
|
-
const source = value;
|
|
493
|
-
const result = {};
|
|
494
|
-
for (const key of Object.keys(source)) {
|
|
495
|
-
result[key] = normalizeDates(source[key], timeZone, seen);
|
|
496
|
-
}
|
|
497
|
-
return result;
|
|
248
|
+
if (value instanceof Date) {
|
|
249
|
+
if (isNaN(value.getTime())) return null;
|
|
250
|
+
return format(new TZDate(value.getTime(), timeZone), NAIVE_PATTERN);
|
|
251
|
+
}
|
|
252
|
+
if (value === null || typeof value !== "object") return value;
|
|
253
|
+
if (isOpaqueBody(value)) return value;
|
|
254
|
+
if (seen.has(value)) return value;
|
|
255
|
+
seen.add(value);
|
|
256
|
+
if (Array.isArray(value)) return value.map((item) => normalizeDates(item, timeZone, seen));
|
|
257
|
+
const source = value;
|
|
258
|
+
const result = {};
|
|
259
|
+
for (const key of Object.keys(source)) result[key] = normalizeDates(source[key], timeZone, seen);
|
|
260
|
+
return result;
|
|
498
261
|
}
|
|
499
|
-
/**
|
|
500
|
-
* Rewrites the request body, if any, replacing Dates with naive local strings.
|
|
501
|
-
* Shared by the functional and the class-based interceptor.
|
|
502
|
-
* @param req - The outgoing request.
|
|
503
|
-
* @param timeZone - IANA timezone used to compute the wall-clock value.
|
|
504
|
-
* @returns The original request when there is nothing to convert, a clone otherwise.
|
|
505
|
-
*/
|
|
506
262
|
function localizeRequest(req, timeZone) {
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
return req.clone({ body: normalizeDates(body, timeZone, new WeakSet()) });
|
|
263
|
+
const body = req.body;
|
|
264
|
+
if (body === null || body === void 0 || isOpaqueBody(body)) return req;
|
|
265
|
+
return req.clone({ body: normalizeDates(body, timeZone, /* @__PURE__ */ new WeakSet()) });
|
|
511
266
|
}
|
|
512
|
-
/**
|
|
513
|
-
* Reads an ISO string back into a `Date`, or returns `undefined` when it is not one.
|
|
514
|
-
*
|
|
515
|
-
* The mirror image of {@link normalizeDates}. A value that carries `Z` or an offset names an
|
|
516
|
-
* instant and is parsed as it stands; a naive one is a wall-clock value in `timeZone` — that is
|
|
517
|
-
* what the request side wrote, and what `System.Text.Json` emits for a `DateTime` with
|
|
518
|
-
* `Kind = Unspecified` — so it is rebuilt component by component through {@link TZDate}.
|
|
519
|
-
*
|
|
520
|
-
* Reading a naive value with `new Date(s)` instead would be right for a datetime and wrong for a
|
|
521
|
-
* bare date: the ECMAScript spec reads `2026-09-07` as UTC midnight and `2026-09-07T00:00:00` as
|
|
522
|
-
* local midnight. That difference is the off-by-one-day this file exists to prevent, arriving from
|
|
523
|
-
* the other direction.
|
|
524
|
-
*
|
|
525
|
-
* @param value - The string to read.
|
|
526
|
-
* @param timeZone - IANA timezone the naive values are expressed in.
|
|
527
|
-
* @returns The date, or `undefined` when the string is not an ISO date.
|
|
528
|
-
*/
|
|
529
267
|
function parseLocalDate(value, timeZone) {
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
// date to begin with, and the original string says more than a wrong Date would.
|
|
541
|
-
if (!zone) {
|
|
542
|
-
const check = new TZDate(date.getTime(), timeZone);
|
|
543
|
-
if (check.getFullYear() !== +year || check.getMonth() !== +month - 1 || check.getDate() !== +day) {
|
|
544
|
-
return undefined;
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
return date;
|
|
268
|
+
const m = ISO_DATE_PATTERN.exec(value);
|
|
269
|
+
if (!m) return void 0;
|
|
270
|
+
const [, year, month, day, hours, minutes, seconds, fraction, zone] = m;
|
|
271
|
+
const date = zone ? new Date(value) : new Date(new TZDate(+year, +month - 1, +day, hours ? +hours : 0, minutes ? +minutes : 0, seconds ? +seconds : 0, fraction ? +fraction.slice(0, 3).padEnd(3, "0") : 0, timeZone).getTime());
|
|
272
|
+
if (isNaN(date.getTime())) return void 0;
|
|
273
|
+
if (!zone) {
|
|
274
|
+
const check = new TZDate(date.getTime(), timeZone);
|
|
275
|
+
if (check.getFullYear() !== +year || check.getMonth() !== +month - 1 || check.getDate() !== +day) return;
|
|
276
|
+
}
|
|
277
|
+
return date;
|
|
548
278
|
}
|
|
549
|
-
/**
|
|
550
|
-
* Recursively replaces every ISO date string found in `value` with a `Date`, returning a NEW
|
|
551
|
-
* structure, exactly as {@link normalizeDates} does on the way out.
|
|
552
|
-
*
|
|
553
|
-
* Only whole strings are considered, and only inside an object or an array: a top-level string
|
|
554
|
-
* body — a rendered document, a plain-text answer — is never touched.
|
|
555
|
-
*
|
|
556
|
-
* @param value - The value to revive (object, array or primitive).
|
|
557
|
-
* @param timeZone - IANA timezone the naive values are expressed in.
|
|
558
|
-
* @param seen - Guard against circular references.
|
|
559
|
-
* @returns The revived value.
|
|
560
|
-
*/
|
|
561
279
|
function reviveDates(value, timeZone, seen) {
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
if (Array.isArray(value)) {
|
|
576
|
-
return value.map(item => reviveDates(item, timeZone, seen));
|
|
577
|
-
}
|
|
578
|
-
const source = value;
|
|
579
|
-
const result = {};
|
|
580
|
-
for (const key of Object.keys(source)) {
|
|
581
|
-
result[key] = reviveDates(source[key], timeZone, seen);
|
|
582
|
-
}
|
|
583
|
-
return result;
|
|
280
|
+
if (typeof value === "string") {
|
|
281
|
+
if (value.length < MIN_ISO_LENGTH || value.length > MAX_ISO_LENGTH) return value;
|
|
282
|
+
return parseLocalDate(value, timeZone) ?? value;
|
|
283
|
+
}
|
|
284
|
+
if (value === null || typeof value !== "object") return value;
|
|
285
|
+
if (value instanceof Date || isOpaqueBody(value)) return value;
|
|
286
|
+
if (seen.has(value)) return value;
|
|
287
|
+
seen.add(value);
|
|
288
|
+
if (Array.isArray(value)) return value.map((item) => reviveDates(item, timeZone, seen));
|
|
289
|
+
const source = value;
|
|
290
|
+
const result = {};
|
|
291
|
+
for (const key of Object.keys(source)) result[key] = reviveDates(source[key], timeZone, seen);
|
|
292
|
+
return result;
|
|
584
293
|
}
|
|
585
|
-
/**
|
|
586
|
-
* Rewrites a response body, if any, replacing ISO date strings with Dates.
|
|
587
|
-
* Shared by the functional and the class-based interceptor.
|
|
588
|
-
* @param event - The event coming back from the chain.
|
|
589
|
-
* @param timeZone - IANA timezone the naive values are expressed in.
|
|
590
|
-
* @returns The original event when there is nothing to convert, a clone otherwise.
|
|
591
|
-
*/
|
|
592
294
|
function localizeResponse(event, timeZone) {
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
return event;
|
|
598
|
-
return event.clone({ body: reviveDates(body, timeZone, new WeakSet()) });
|
|
295
|
+
if (!(event instanceof HttpResponse)) return event;
|
|
296
|
+
const body = event.body;
|
|
297
|
+
if (body === null || typeof body !== "object" || isOpaqueBody(body)) return event;
|
|
298
|
+
return event.clone({ body: reviveDates(body, timeZone, /* @__PURE__ */ new WeakSet()) });
|
|
599
299
|
}
|
|
600
|
-
/**
|
|
601
|
-
* Functional interceptor that closes the date serialisation boundary of the application, in both
|
|
602
|
-
* directions: it writes the dates of every request and reads back those of every response.
|
|
603
|
-
*
|
|
604
|
-
* ON THE WAY OUT every `Date` of the request body is serialised as a naive local datetime string
|
|
605
|
-
* (`yyyy-MM-ddTHH:mm:ss`: no `Z`, no offset). `JSON.stringify` would otherwise call
|
|
606
|
-
* `Date.prototype.toJSON`, which emits a UTC instant: a date picked as 29/07/2026 00:00 in Rome
|
|
607
|
-
* (UTC+2) becomes `2026-07-28T22:00:00.000Z`, so the server stores the 28th — the classic
|
|
608
|
-
* "off by one day". Sending the wall-clock value instead makes System.Text.Json produce a
|
|
609
|
-
* `DateTime` with `Kind = Unspecified` and the exact day/time the user selected.
|
|
610
|
-
*
|
|
611
|
-
* ON THE WAY BACK every ISO date string of the response body is read into a `Date`. Models declare
|
|
612
|
-
* `Date`, but `HttpClient` only runs `JSON.parse`, which has no notion of dates, so without this
|
|
613
|
-
* every one of those properties holds a `string` at runtime and the declared type is a promise
|
|
614
|
-
* nobody keeps. It goes unnoticed for a long time — the `date` pipe accepts strings and
|
|
615
|
-
* {@link DateFnsAdapter.deserialize} parses them for the datepickers — until somebody calls a
|
|
616
|
-
* method of `Date` on one and gets a `TypeError`, or writes `x.someDate = new Date(x.someDate)` to
|
|
617
|
-
* work around it one call site at a time.
|
|
618
|
-
*
|
|
619
|
-
* With both halves here no call site has to convert anything, in either direction, and dates that
|
|
620
|
-
* lost a per-instance `toJSON` along the way (after a `structuredClone`, say) are covered too.
|
|
621
|
-
*
|
|
622
|
-
* Both halves are idempotent — a body already normalised holds no `Date`, a body already revived
|
|
623
|
-
* holds no ISO string — so registering this twice, or over a chain that has already converted,
|
|
624
|
-
* changes nothing.
|
|
625
|
-
*
|
|
626
|
-
* REGISTER IT FIRST in `withInterceptors([...])`. The first interceptor of the array is the first
|
|
627
|
-
* to see the request and the LAST to see the response, which is what this one wants in both
|
|
628
|
-
* directions: every other interceptor keeps seeing the body exactly as the server sent it.
|
|
629
|
-
*
|
|
630
|
-
* If you would rather have the library register it for you, use {@link provideArsLocalDates}.
|
|
631
|
-
*
|
|
632
|
-
* @example
|
|
633
|
-
* provideHttpClient(withInterceptors([
|
|
634
|
-
* arsLocalDateInterceptor,
|
|
635
|
-
* evolutionAuthInterceptor(...),
|
|
636
|
-
* ]));
|
|
637
|
-
*/
|
|
638
300
|
const arsLocalDateInterceptor = (req, next) => {
|
|
639
|
-
|
|
640
|
-
|
|
301
|
+
const timeZone = inject(ARS_TIME_ZONE);
|
|
302
|
+
return next(localizeRequest(req, timeZone)).pipe(map((event) => localizeResponse(event, timeZone)));
|
|
641
303
|
};
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
/**
|
|
676
|
-
* Standalone providers for date conversion towards and from the backend.
|
|
677
|
-
*
|
|
678
|
-
* Registers {@link ArsLocalDateInterceptor}, so that every `Date` of a request body travels as a
|
|
679
|
-
* naive local datetime string instead of a UTC instant, and every ISO date string of a response
|
|
680
|
-
* body comes back as the `Date` the model declares.
|
|
681
|
-
*
|
|
682
|
-
* IMPORTANT: the application MUST call `withInterceptorsFromDi()`, otherwise
|
|
683
|
-
* these providers have no effect at all (no error is raised).
|
|
684
|
-
*
|
|
685
|
-
* @param timeZone - IANA timezone name (default: `Europe/Rome`).
|
|
686
|
-
* @returns The environment providers to add to the application configuration.
|
|
687
|
-
*
|
|
688
|
-
* @example
|
|
689
|
-
* providers: [
|
|
690
|
-
* provideArsLocalDates(),
|
|
691
|
-
* provideHttpClient(withInterceptors([evolutionAuthInterceptor(...)]), withInterceptorsFromDi()),
|
|
692
|
-
* ]
|
|
693
|
-
*/
|
|
304
|
+
var ArsLocalDateInterceptor = class ArsLocalDateInterceptor {
|
|
305
|
+
constructor() {
|
|
306
|
+
this.timeZone = inject(ARS_TIME_ZONE);
|
|
307
|
+
}
|
|
308
|
+
intercept(req, next) {
|
|
309
|
+
return next.handle(localizeRequest(req, this.timeZone)).pipe(map((event) => localizeResponse(event, this.timeZone)));
|
|
310
|
+
}
|
|
311
|
+
static {
|
|
312
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
313
|
+
minVersion: "12.0.0",
|
|
314
|
+
version: "22.2.1",
|
|
315
|
+
ngImport: i0,
|
|
316
|
+
type: ArsLocalDateInterceptor,
|
|
317
|
+
deps: [],
|
|
318
|
+
target: i0.ɵɵFactoryTarget.Injectable
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
static {
|
|
322
|
+
this.ɵprov = i0.ɵɵngDeclareInjectable({
|
|
323
|
+
minVersion: "12.0.0",
|
|
324
|
+
version: "22.2.1",
|
|
325
|
+
ngImport: i0,
|
|
326
|
+
type: ArsLocalDateInterceptor
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
331
|
+
minVersion: "12.0.0",
|
|
332
|
+
version: "22.2.1",
|
|
333
|
+
ngImport: i0,
|
|
334
|
+
type: ArsLocalDateInterceptor,
|
|
335
|
+
decorators: [{ type: Injectable }]
|
|
336
|
+
});
|
|
694
337
|
function provideArsLocalDates(timeZone = DEFAULT_TIME_ZONE) {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
338
|
+
return makeEnvironmentProviders([{
|
|
339
|
+
provide: ARS_TIME_ZONE,
|
|
340
|
+
useValue: timeZone
|
|
341
|
+
}, {
|
|
342
|
+
provide: HTTP_INTERCEPTORS,
|
|
343
|
+
useClass: ArsLocalDateInterceptor,
|
|
344
|
+
multi: true
|
|
345
|
+
}]);
|
|
699
346
|
}
|
|
700
|
-
/**
|
|
701
|
-
* Formats a date as a date-only ISO string (`yyyy-MM-dd`) using its wall-clock
|
|
702
|
-
* calendar day in the given timezone. Use it for query-string parameters and for
|
|
703
|
-
* DTO fields mapped to a .NET `DateOnly`, which the interceptor cannot detect.
|
|
704
|
-
*
|
|
705
|
-
* @param value - The date to serialise.
|
|
706
|
-
* @param timeZone - IANA timezone name (default: `Europe/Rome`).
|
|
707
|
-
* @returns The `yyyy-MM-dd` string, or `undefined` for empty/invalid input.
|
|
708
|
-
*/
|
|
709
347
|
function toLocalDateOnlyString(value, timeZone = DEFAULT_TIME_ZONE) {
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
return format(new TZDate(value.getTime(), timeZone), 'yyyy-MM-dd');
|
|
348
|
+
if (!value || isNaN(value.getTime())) return void 0;
|
|
349
|
+
return format(new TZDate(value.getTime(), timeZone), "yyyy-MM-dd");
|
|
713
350
|
}
|
|
714
|
-
/**
|
|
715
|
-
* Formats a date as a naive local datetime string (`yyyy-MM-ddTHH:mm:ss`), the
|
|
716
|
-
* same representation produced by the interceptor. Useful for query-string
|
|
717
|
-
* parameters, which never pass through the request body.
|
|
718
|
-
*
|
|
719
|
-
* @param value - The date to serialise.
|
|
720
|
-
* @param timeZone - IANA timezone name (default: `Europe/Rome`).
|
|
721
|
-
* @returns The naive datetime string, or `undefined` for empty/invalid input.
|
|
722
|
-
*/
|
|
723
351
|
function toLocalDateTimeString(value, timeZone = DEFAULT_TIME_ZONE) {
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
return format(new TZDate(value.getTime(), timeZone), NAIVE_PATTERN);
|
|
352
|
+
if (!value || isNaN(value.getTime())) return void 0;
|
|
353
|
+
return format(new TZDate(value.getTime(), timeZone), NAIVE_PATTERN);
|
|
727
354
|
}
|
|
728
|
-
|
|
729
|
-
/*
|
|
730
|
-
* Public API Surface of @arsedizioni/ars-utils/core.date
|
|
731
|
-
*/
|
|
732
|
-
|
|
733
|
-
/**
|
|
734
|
-
* Generated bundle index. Do not edit.
|
|
735
|
-
*/
|
|
736
|
-
|
|
737
355
|
export { ARS_TIME_ZONE, ArsLocalDateInterceptor, DEFAULT_TIME_ZONE, DateFnsAdapter, MAT_DATE_FNS_FORMATS, arsLocalDateInterceptor, provideArsDateFns, provideArsLocalDates, toLocalDateOnlyString, toLocalDateTimeString };
|
|
738
|
-
|
|
356
|
+
|
|
357
|
+
//# sourceMappingURL=arsedizioni-ars-utils-core.date.mjs.map
|