@arsedizioni/ars-utils 22.0.84 → 22.0.85
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { inject, Injectable, makeEnvironmentProviders, InjectionToken, ElementRef, afterNextRender, Directive, input, DestroyRef, HostListener, output, forwardRef, effect, Pipe, EventEmitter, signal, computed, Service, PLATFORM_ID, RendererFactory2 } from '@angular/core';
|
|
3
3
|
import { DateAdapter, MAT_DATE_LOCALE, MAT_DATE_FORMATS } from '@angular/material/core';
|
|
4
4
|
import { TZDate } from '@date-fns/tz';
|
|
5
5
|
import { format, getYear, getMonth, getDate, getDay, getDaysInMonth, parseISO, parse, addYears, addMonths, addDays, isDate, isValid, addSeconds, endOfDay } from 'date-fns';
|
|
@@ -13,189 +13,6 @@ import { DomSanitizer } from '@angular/platform-browser';
|
|
|
13
13
|
import { SelectionModel } from '@angular/cdk/collections';
|
|
14
14
|
import { isPlatformBrowser } from '@angular/common';
|
|
15
15
|
|
|
16
|
-
/** Default application timezone: all dates are serialised as Europe/Rome wall-clock values. */
|
|
17
|
-
const DEFAULT_TIME_ZONE = 'Europe/Rome';
|
|
18
|
-
/**
|
|
19
|
-
* IANA timezone used to serialise dates towards the backend.
|
|
20
|
-
* Override it in the application providers to run the same code in another zone:
|
|
21
|
-
* `{ provide: ARS_TIME_ZONE, useValue: 'Europe/Zurich' }`.
|
|
22
|
-
*/
|
|
23
|
-
const ARS_TIME_ZONE = new InjectionToken('ARS_TIME_ZONE', {
|
|
24
|
-
providedIn: 'root',
|
|
25
|
-
factory: () => DEFAULT_TIME_ZONE,
|
|
26
|
-
});
|
|
27
|
-
/** Naive local datetime pattern (no timezone designator): the server reads it as DateTimeKind.Unspecified. */
|
|
28
|
-
const NAIVE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss";
|
|
29
|
-
/**
|
|
30
|
-
* Returns `true` for payloads that must be forwarded untouched
|
|
31
|
-
* (binary or already-encoded bodies).
|
|
32
|
-
* @param body - The request body to test.
|
|
33
|
-
*/
|
|
34
|
-
function isOpaqueBody(body) {
|
|
35
|
-
return (body instanceof FormData ||
|
|
36
|
-
body instanceof Blob ||
|
|
37
|
-
body instanceof ArrayBuffer ||
|
|
38
|
-
ArrayBuffer.isView(body) ||
|
|
39
|
-
body instanceof URLSearchParams ||
|
|
40
|
-
typeof body === 'string');
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Recursively replaces every `Date` found in `value` with its naive local
|
|
44
|
-
* datetime string, returning a NEW structure: the original object graph — and
|
|
45
|
-
* therefore any bound form model — is never mutated.
|
|
46
|
-
*
|
|
47
|
-
* @param value - The value to normalise (object, array, Date or primitive).
|
|
48
|
-
* @param timeZone - IANA timezone used to compute the wall-clock value.
|
|
49
|
-
* @param seen - Guard against circular references.
|
|
50
|
-
* @returns The normalised value, safe to hand over to `JSON.stringify`.
|
|
51
|
-
*/
|
|
52
|
-
function normalizeDates(value, timeZone, seen) {
|
|
53
|
-
if (value instanceof Date) {
|
|
54
|
-
// Invalid dates would make format() throw a RangeError: send null instead.
|
|
55
|
-
if (isNaN(value.getTime()))
|
|
56
|
-
return null;
|
|
57
|
-
return format(new TZDate(value.getTime(), timeZone), NAIVE_PATTERN);
|
|
58
|
-
}
|
|
59
|
-
if (value === null || typeof value !== 'object')
|
|
60
|
-
return value;
|
|
61
|
-
if (isOpaqueBody(value))
|
|
62
|
-
return value;
|
|
63
|
-
// Circular reference: leave it as is, JSON.stringify will report it anyway.
|
|
64
|
-
if (seen.has(value))
|
|
65
|
-
return value;
|
|
66
|
-
seen.add(value);
|
|
67
|
-
if (Array.isArray(value)) {
|
|
68
|
-
return value.map(item => normalizeDates(item, timeZone, seen));
|
|
69
|
-
}
|
|
70
|
-
const source = value;
|
|
71
|
-
const result = {};
|
|
72
|
-
for (const key of Object.keys(source)) {
|
|
73
|
-
result[key] = normalizeDates(source[key], timeZone, seen);
|
|
74
|
-
}
|
|
75
|
-
return result;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Rewrites the request body, if any, replacing Dates with naive local strings.
|
|
79
|
-
* Shared by the functional and the class-based interceptor.
|
|
80
|
-
* @param req - The outgoing request.
|
|
81
|
-
* @param timeZone - IANA timezone used to compute the wall-clock value.
|
|
82
|
-
* @returns The original request when there is nothing to convert, a clone otherwise.
|
|
83
|
-
*/
|
|
84
|
-
function localizeRequest(req, timeZone) {
|
|
85
|
-
const body = req.body;
|
|
86
|
-
if (body === null || body === undefined || isOpaqueBody(body))
|
|
87
|
-
return req;
|
|
88
|
-
return req.clone({ body: normalizeDates(body, timeZone, new WeakSet()) });
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Functional interceptor that serialises every `Date` in an outgoing request
|
|
92
|
-
* body as a naive local datetime string (`yyyy-MM-ddTHH:mm:ss`: no `Z`, no offset).
|
|
93
|
-
*
|
|
94
|
-
* WHY: `JSON.stringify` calls `Date.prototype.toJSON`, which emits a UTC instant.
|
|
95
|
-
* A date picked as 29/07/2026 00:00 in Rome (UTC+2) becomes
|
|
96
|
-
* `2026-07-28T22:00:00.000Z`, so the server stores the 28th — the classic
|
|
97
|
-
* "off by one day" bug. Sending the wall-clock value instead makes
|
|
98
|
-
* System.Text.Json produce a `DateTime` with `Kind = Unspecified` and the exact
|
|
99
|
-
* day/time the user selected.
|
|
100
|
-
*
|
|
101
|
-
* This is the single serialisation boundary of the application: no call site has
|
|
102
|
-
* to convert anything, and it also covers dates that lost a per-instance
|
|
103
|
-
* `toJSON` along the way (e.g. after `structuredClone`).
|
|
104
|
-
*
|
|
105
|
-
* Register it explicitly in `provideHttpClient(withInterceptors([...]))`.
|
|
106
|
-
* If you would rather have the library register it for you, use
|
|
107
|
-
* {@link provideArsLocalDates} instead.
|
|
108
|
-
*
|
|
109
|
-
* @example
|
|
110
|
-
* provideHttpClient(withInterceptors([
|
|
111
|
-
* arsLocalDateInterceptor,
|
|
112
|
-
* evolutionAuthInterceptor(...),
|
|
113
|
-
* ]));
|
|
114
|
-
*/
|
|
115
|
-
const arsLocalDateInterceptor = (req, next) => next(localizeRequest(req, inject(ARS_TIME_ZONE)));
|
|
116
|
-
/**
|
|
117
|
-
* Class-based twin of {@link arsLocalDateInterceptor}.
|
|
118
|
-
*
|
|
119
|
-
* Exists because a functional `HttpInterceptorFn` can ONLY be registered inside
|
|
120
|
-
* `provideHttpClient(withInterceptors([...]))`, while a class registered on the
|
|
121
|
-
* `HTTP_INTERCEPTORS` multi-token can be contributed by any `EnvironmentProviders` —
|
|
122
|
-
* which is what lets {@link provideArsLocalDates} (and `provideArsDateFns`) wire it up
|
|
123
|
-
* on their own.
|
|
124
|
-
*
|
|
125
|
-
* REQUIRES `withInterceptorsFromDi()` in the application's `provideHttpClient()`:
|
|
126
|
-
* without it Angular never reads `HTTP_INTERCEPTORS` and this interceptor is
|
|
127
|
-
* silently skipped.
|
|
128
|
-
*/
|
|
129
|
-
class ArsLocalDateInterceptor {
|
|
130
|
-
constructor() {
|
|
131
|
-
this.timeZone = inject(ARS_TIME_ZONE);
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Normalises the request body before handing it to the next handler.
|
|
135
|
-
* @param req - The outgoing request.
|
|
136
|
-
* @param next - The next handler in the chain.
|
|
137
|
-
*/
|
|
138
|
-
intercept(req, next) {
|
|
139
|
-
return next.handle(localizeRequest(req, this.timeZone));
|
|
140
|
-
}
|
|
141
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ArsLocalDateInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
142
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ArsLocalDateInterceptor }); }
|
|
143
|
-
}
|
|
144
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ArsLocalDateInterceptor, decorators: [{
|
|
145
|
-
type: Injectable
|
|
146
|
-
}] });
|
|
147
|
-
/**
|
|
148
|
-
* Standalone providers for date serialisation towards the backend.
|
|
149
|
-
*
|
|
150
|
-
* Registers {@link ArsLocalDateInterceptor} so that every `Date` in a request
|
|
151
|
-
* body travels as a naive local datetime string instead of a UTC instant.
|
|
152
|
-
*
|
|
153
|
-
* IMPORTANT: the application MUST call `withInterceptorsFromDi()`, otherwise
|
|
154
|
-
* these providers have no effect at all (no error is raised).
|
|
155
|
-
*
|
|
156
|
-
* @param timeZone - IANA timezone name (default: `Europe/Rome`).
|
|
157
|
-
*
|
|
158
|
-
* @example
|
|
159
|
-
* providers: [
|
|
160
|
-
* provideArsLocalDates(),
|
|
161
|
-
* provideHttpClient(withInterceptors([evolutionAuthInterceptor(...)]), withInterceptorsFromDi()),
|
|
162
|
-
* ]
|
|
163
|
-
*/
|
|
164
|
-
function provideArsLocalDates(timeZone = DEFAULT_TIME_ZONE) {
|
|
165
|
-
return makeEnvironmentProviders([
|
|
166
|
-
{ provide: ARS_TIME_ZONE, useValue: timeZone },
|
|
167
|
-
{ provide: HTTP_INTERCEPTORS, useClass: ArsLocalDateInterceptor, multi: true },
|
|
168
|
-
]);
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Formats a date as a date-only ISO string (`yyyy-MM-dd`) using its wall-clock
|
|
172
|
-
* calendar day in the given timezone. Use it for query-string parameters and for
|
|
173
|
-
* DTO fields mapped to a .NET `DateOnly`, which the interceptor cannot detect.
|
|
174
|
-
*
|
|
175
|
-
* @param value - The date to serialise.
|
|
176
|
-
* @param timeZone - IANA timezone name (default: `Europe/Rome`).
|
|
177
|
-
* @returns The `yyyy-MM-dd` string, or `undefined` for empty/invalid input.
|
|
178
|
-
*/
|
|
179
|
-
function toLocalDateOnlyString(value, timeZone = DEFAULT_TIME_ZONE) {
|
|
180
|
-
if (!value || isNaN(value.getTime()))
|
|
181
|
-
return undefined;
|
|
182
|
-
return format(new TZDate(value.getTime(), timeZone), 'yyyy-MM-dd');
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Formats a date as a naive local datetime string (`yyyy-MM-ddTHH:mm:ss`), the
|
|
186
|
-
* same representation produced by the interceptor. Useful for query-string
|
|
187
|
-
* parameters, which never pass through the request body.
|
|
188
|
-
*
|
|
189
|
-
* @param value - The date to serialise.
|
|
190
|
-
* @param timeZone - IANA timezone name (default: `Europe/Rome`).
|
|
191
|
-
* @returns The naive datetime string, or `undefined` for empty/invalid input.
|
|
192
|
-
*/
|
|
193
|
-
function toLocalDateTimeString(value, timeZone = DEFAULT_TIME_ZONE) {
|
|
194
|
-
if (!value || isNaN(value.getTime()))
|
|
195
|
-
return undefined;
|
|
196
|
-
return format(new TZDate(value.getTime(), timeZone), NAIVE_PATTERN);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
16
|
/**
|
|
200
17
|
* Creates an array of the given length, filling each slot with the result of `valueFunction`.
|
|
201
18
|
* @param length - Number of elements to create.
|
|
@@ -595,15 +412,199 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
595
412
|
* providers: [provideArsDateFns()]
|
|
596
413
|
* });
|
|
597
414
|
*/
|
|
598
|
-
function provideArsDateFns(
|
|
599
|
-
const { timeZone = 'Europe/Rome', httpSerialization = true } = options;
|
|
415
|
+
function provideArsDateFns() {
|
|
600
416
|
return makeEnvironmentProviders([
|
|
601
|
-
{
|
|
602
|
-
|
|
603
|
-
|
|
417
|
+
{
|
|
418
|
+
provide: DateAdapter,
|
|
419
|
+
useClass: DateFnsAdapter
|
|
420
|
+
},
|
|
421
|
+
{ provide: MAT_DATE_FORMATS, useValue: MAT_DATE_FNS_FORMATS }
|
|
604
422
|
]);
|
|
605
423
|
}
|
|
606
424
|
|
|
425
|
+
/** Default application timezone: all dates are serialised as Europe/Rome wall-clock values. */
|
|
426
|
+
const DEFAULT_TIME_ZONE = 'Europe/Rome';
|
|
427
|
+
/**
|
|
428
|
+
* IANA timezone used to serialise dates towards the backend.
|
|
429
|
+
* Override it in the application providers to run the same code in another zone:
|
|
430
|
+
* `{ provide: ARS_TIME_ZONE, useValue: 'Europe/Zurich' }`.
|
|
431
|
+
*/
|
|
432
|
+
const ARS_TIME_ZONE = new InjectionToken('ARS_TIME_ZONE', {
|
|
433
|
+
providedIn: 'root',
|
|
434
|
+
factory: () => DEFAULT_TIME_ZONE,
|
|
435
|
+
});
|
|
436
|
+
/** Naive local datetime pattern (no timezone designator): the server reads it as DateTimeKind.Unspecified. */
|
|
437
|
+
const NAIVE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss";
|
|
438
|
+
/**
|
|
439
|
+
* Returns `true` for payloads that must be forwarded untouched
|
|
440
|
+
* (binary or already-encoded bodies).
|
|
441
|
+
* @param body - The request body to test.
|
|
442
|
+
*/
|
|
443
|
+
function isOpaqueBody(body) {
|
|
444
|
+
return (body instanceof FormData ||
|
|
445
|
+
body instanceof Blob ||
|
|
446
|
+
body instanceof ArrayBuffer ||
|
|
447
|
+
ArrayBuffer.isView(body) ||
|
|
448
|
+
body instanceof URLSearchParams ||
|
|
449
|
+
typeof body === 'string');
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Recursively replaces every `Date` found in `value` with its naive local
|
|
453
|
+
* datetime string, returning a NEW structure: the original object graph — and
|
|
454
|
+
* therefore any bound form model — is never mutated.
|
|
455
|
+
*
|
|
456
|
+
* @param value - The value to normalise (object, array, Date or primitive).
|
|
457
|
+
* @param timeZone - IANA timezone used to compute the wall-clock value.
|
|
458
|
+
* @param seen - Guard against circular references.
|
|
459
|
+
* @returns The normalised value, safe to hand over to `JSON.stringify`.
|
|
460
|
+
*/
|
|
461
|
+
function normalizeDates(value, timeZone, seen) {
|
|
462
|
+
if (value instanceof Date) {
|
|
463
|
+
// Invalid dates would make format() throw a RangeError: send null instead.
|
|
464
|
+
if (isNaN(value.getTime()))
|
|
465
|
+
return null;
|
|
466
|
+
return format(new TZDate(value.getTime(), timeZone), NAIVE_PATTERN);
|
|
467
|
+
}
|
|
468
|
+
if (value === null || typeof value !== 'object')
|
|
469
|
+
return value;
|
|
470
|
+
if (isOpaqueBody(value))
|
|
471
|
+
return value;
|
|
472
|
+
// Circular reference: leave it as is, JSON.stringify will report it anyway.
|
|
473
|
+
if (seen.has(value))
|
|
474
|
+
return value;
|
|
475
|
+
seen.add(value);
|
|
476
|
+
if (Array.isArray(value)) {
|
|
477
|
+
return value.map(item => normalizeDates(item, timeZone, seen));
|
|
478
|
+
}
|
|
479
|
+
const source = value;
|
|
480
|
+
const result = {};
|
|
481
|
+
for (const key of Object.keys(source)) {
|
|
482
|
+
result[key] = normalizeDates(source[key], timeZone, seen);
|
|
483
|
+
}
|
|
484
|
+
return result;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Rewrites the request body, if any, replacing Dates with naive local strings.
|
|
488
|
+
* Shared by the functional and the class-based interceptor.
|
|
489
|
+
* @param req - The outgoing request.
|
|
490
|
+
* @param timeZone - IANA timezone used to compute the wall-clock value.
|
|
491
|
+
* @returns The original request when there is nothing to convert, a clone otherwise.
|
|
492
|
+
*/
|
|
493
|
+
function localizeRequest(req, timeZone) {
|
|
494
|
+
const body = req.body;
|
|
495
|
+
if (body === null || body === undefined || isOpaqueBody(body))
|
|
496
|
+
return req;
|
|
497
|
+
return req.clone({ body: normalizeDates(body, timeZone, new WeakSet()) });
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Functional interceptor that serialises every `Date` in an outgoing request
|
|
501
|
+
* body as a naive local datetime string (`yyyy-MM-ddTHH:mm:ss`: no `Z`, no offset).
|
|
502
|
+
*
|
|
503
|
+
* WHY: `JSON.stringify` calls `Date.prototype.toJSON`, which emits a UTC instant.
|
|
504
|
+
* A date picked as 29/07/2026 00:00 in Rome (UTC+2) becomes
|
|
505
|
+
* `2026-07-28T22:00:00.000Z`, so the server stores the 28th — the classic
|
|
506
|
+
* "off by one day" bug. Sending the wall-clock value instead makes
|
|
507
|
+
* System.Text.Json produce a `DateTime` with `Kind = Unspecified` and the exact
|
|
508
|
+
* day/time the user selected.
|
|
509
|
+
*
|
|
510
|
+
* This is the single serialisation boundary of the application: no call site has
|
|
511
|
+
* to convert anything, and it also covers dates that lost a per-instance
|
|
512
|
+
* `toJSON` along the way (e.g. after `structuredClone`).
|
|
513
|
+
*
|
|
514
|
+
* Register it explicitly in `provideHttpClient(withInterceptors([...]))`.
|
|
515
|
+
* If you would rather have the library register it for you, use
|
|
516
|
+
* {@link provideArsLocalDates} instead.
|
|
517
|
+
*
|
|
518
|
+
* @example
|
|
519
|
+
* provideHttpClient(withInterceptors([
|
|
520
|
+
* arsLocalDateInterceptor,
|
|
521
|
+
* evolutionAuthInterceptor(...),
|
|
522
|
+
* ]));
|
|
523
|
+
*/
|
|
524
|
+
const arsLocalDateInterceptor = (req, next) => next(localizeRequest(req, inject(ARS_TIME_ZONE)));
|
|
525
|
+
/**
|
|
526
|
+
* Class-based twin of {@link arsLocalDateInterceptor}.
|
|
527
|
+
*
|
|
528
|
+
* Exists because a functional `HttpInterceptorFn` can ONLY be registered inside
|
|
529
|
+
* `provideHttpClient(withInterceptors([...]))`, while a class registered on the
|
|
530
|
+
* `HTTP_INTERCEPTORS` multi-token can be contributed by any `EnvironmentProviders` —
|
|
531
|
+
* which is what lets {@link provideArsLocalDates} (and `provideArsDateFns`) wire it up
|
|
532
|
+
* on their own.
|
|
533
|
+
*
|
|
534
|
+
* REQUIRES `withInterceptorsFromDi()` in the application's `provideHttpClient()`:
|
|
535
|
+
* without it Angular never reads `HTTP_INTERCEPTORS` and this interceptor is
|
|
536
|
+
* silently skipped.
|
|
537
|
+
*/
|
|
538
|
+
class ArsLocalDateInterceptor {
|
|
539
|
+
constructor() {
|
|
540
|
+
this.timeZone = inject(ARS_TIME_ZONE);
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Normalises the request body before handing it to the next handler.
|
|
544
|
+
* @param req - The outgoing request.
|
|
545
|
+
* @param next - The next handler in the chain.
|
|
546
|
+
*/
|
|
547
|
+
intercept(req, next) {
|
|
548
|
+
return next.handle(localizeRequest(req, this.timeZone));
|
|
549
|
+
}
|
|
550
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ArsLocalDateInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
551
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ArsLocalDateInterceptor }); }
|
|
552
|
+
}
|
|
553
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ArsLocalDateInterceptor, decorators: [{
|
|
554
|
+
type: Injectable
|
|
555
|
+
}] });
|
|
556
|
+
/**
|
|
557
|
+
* Standalone providers for date serialisation towards the backend.
|
|
558
|
+
*
|
|
559
|
+
* Registers {@link ArsLocalDateInterceptor} so that every `Date` in a request
|
|
560
|
+
* body travels as a naive local datetime string instead of a UTC instant.
|
|
561
|
+
*
|
|
562
|
+
* IMPORTANT: the application MUST call `withInterceptorsFromDi()`, otherwise
|
|
563
|
+
* these providers have no effect at all (no error is raised).
|
|
564
|
+
*
|
|
565
|
+
* @param timeZone - IANA timezone name (default: `Europe/Rome`).
|
|
566
|
+
*
|
|
567
|
+
* @example
|
|
568
|
+
* providers: [
|
|
569
|
+
* provideArsLocalDates(),
|
|
570
|
+
* provideHttpClient(withInterceptors([evolutionAuthInterceptor(...)]), withInterceptorsFromDi()),
|
|
571
|
+
* ]
|
|
572
|
+
*/
|
|
573
|
+
function provideArsLocalDates(timeZone = DEFAULT_TIME_ZONE) {
|
|
574
|
+
return makeEnvironmentProviders([
|
|
575
|
+
{ provide: ARS_TIME_ZONE, useValue: timeZone },
|
|
576
|
+
{ provide: HTTP_INTERCEPTORS, useClass: ArsLocalDateInterceptor, multi: true },
|
|
577
|
+
]);
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Formats a date as a date-only ISO string (`yyyy-MM-dd`) using its wall-clock
|
|
581
|
+
* calendar day in the given timezone. Use it for query-string parameters and for
|
|
582
|
+
* DTO fields mapped to a .NET `DateOnly`, which the interceptor cannot detect.
|
|
583
|
+
*
|
|
584
|
+
* @param value - The date to serialise.
|
|
585
|
+
* @param timeZone - IANA timezone name (default: `Europe/Rome`).
|
|
586
|
+
* @returns The `yyyy-MM-dd` string, or `undefined` for empty/invalid input.
|
|
587
|
+
*/
|
|
588
|
+
function toLocalDateOnlyString(value, timeZone = DEFAULT_TIME_ZONE) {
|
|
589
|
+
if (!value || isNaN(value.getTime()))
|
|
590
|
+
return undefined;
|
|
591
|
+
return format(new TZDate(value.getTime(), timeZone), 'yyyy-MM-dd');
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Formats a date as a naive local datetime string (`yyyy-MM-ddTHH:mm:ss`), the
|
|
595
|
+
* same representation produced by the interceptor. Useful for query-string
|
|
596
|
+
* parameters, which never pass through the request body.
|
|
597
|
+
*
|
|
598
|
+
* @param value - The date to serialise.
|
|
599
|
+
* @param timeZone - IANA timezone name (default: `Europe/Rome`).
|
|
600
|
+
* @returns The naive datetime string, or `undefined` for empty/invalid input.
|
|
601
|
+
*/
|
|
602
|
+
function toLocalDateTimeString(value, timeZone = DEFAULT_TIME_ZONE) {
|
|
603
|
+
if (!value || isNaN(value.getTime()))
|
|
604
|
+
return undefined;
|
|
605
|
+
return format(new TZDate(value.getTime(), timeZone), NAIVE_PATTERN);
|
|
606
|
+
}
|
|
607
|
+
|
|
607
608
|
/**
|
|
608
609
|
* Directive that moves browser focus to the host element after the first render cycle.
|
|
609
610
|
* Apply `autoFocus` to any focusable element to set focus automatically on initialisation.
|
|
@@ -4102,5 +4103,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
4102
4103
|
* Generated bundle index. Do not edit.
|
|
4103
4104
|
*/
|
|
4104
4105
|
|
|
4105
|
-
export { AutoFocusDirective, BroadcastChannelManager, BroadcastService, CHANNEL_NAME, CopyClipboardDirective, DateFnsAdapter, DateFormat, DateInterval, DateIntervalChangeDirective, DeleteModel, EmailsValidatorDirective, EnvironmentService, EqualsValidatorDirective, FileInfo, FileSizeValidatorDirective, FormatHtmlPipe, FormatMarkdownPipe, FormatPipe, GroupModel, GuidValidatorDirective, IDModel, ImportModel, MAT_DATE_FNS_FORMATS, MaxTermsValidatorDirective, NotEmptyValidatorDirective, NotEqualValidatorDirective, NotFutureValidatorDirective, PasswordValidatorDirective, QueryModel, RelationModel, RemoveFocusDirective, ReplacePipe, SafeHtmlPipe, SafeUrlPipe, ScreenService, SearchCallbackPipe, SearchFilterPipe, SelectableModel, SplashService, SqlDateValidatorDirective, SystemUtils, ThemeService, TimeValidatorDirective, UpdateRelationsModel, UrlValidatorDirective, UtilsMessages, ValidIfDirective, ValidatorDirective, ValueModel, provideArsDateFns };
|
|
4106
|
+
export { ARS_TIME_ZONE, ArsLocalDateInterceptor, AutoFocusDirective, BroadcastChannelManager, BroadcastService, CHANNEL_NAME, CopyClipboardDirective, DEFAULT_TIME_ZONE, DateFnsAdapter, DateFormat, DateInterval, DateIntervalChangeDirective, DeleteModel, EmailsValidatorDirective, EnvironmentService, EqualsValidatorDirective, FileInfo, FileSizeValidatorDirective, FormatHtmlPipe, FormatMarkdownPipe, FormatPipe, GroupModel, GuidValidatorDirective, IDModel, ImportModel, MAT_DATE_FNS_FORMATS, MaxTermsValidatorDirective, NotEmptyValidatorDirective, NotEqualValidatorDirective, NotFutureValidatorDirective, PasswordValidatorDirective, QueryModel, RelationModel, RemoveFocusDirective, ReplacePipe, SafeHtmlPipe, SafeUrlPipe, ScreenService, SearchCallbackPipe, SearchFilterPipe, SelectableModel, SplashService, SqlDateValidatorDirective, SystemUtils, ThemeService, TimeValidatorDirective, UpdateRelationsModel, UrlValidatorDirective, UtilsMessages, ValidIfDirective, ValidatorDirective, ValueModel, arsLocalDateInterceptor, provideArsDateFns, provideArsLocalDates, toLocalDateOnlyString, toLocalDateTimeString };
|
|
4106
4107
|
//# sourceMappingURL=arsedizioni-ars-utils-core.mjs.map
|