@thisisagile/easy 18.11.1 → 18.12.0
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/README.md +1 -1
- package/dist/chunk-EOHHPAAY.mjs +140 -0
- package/dist/chunk-EOHHPAAY.mjs.map +1 -0
- package/dist/{chunk-5VP4WNID.mjs → chunk-TMVZSMUA.mjs} +2 -2
- package/dist/domain/Audit.mjs +2 -2
- package/dist/domain/DateTime.d.ts +5 -7
- package/dist/domain/DateTime.mjs +1 -1
- package/dist/domain/Entity.mjs +2 -2
- package/dist/index.js +38 -165
- package/dist/index.js.map +1 -1
- package/dist/types/ErrorOrigin.d.ts +2 -0
- package/dist/types/ErrorOrigin.mjs +31 -0
- package/dist/types/ErrorOrigin.mjs.map +1 -1
- package/dist/utils/Period.mjs +1 -1
- package/package.json +4 -9
- package/src/domain/DateTime.ts +40 -206
- package/src/types/ErrorOrigin.ts +16 -4
- package/dist/chunk-GRDUTNMZ.mjs +0 -272
- package/dist/chunk-GRDUTNMZ.mjs.map +0 -1
- /package/dist/{chunk-5VP4WNID.mjs.map → chunk-TMVZSMUA.mjs.map} +0 -0
|
@@ -3,4 +3,6 @@ import { Exception } from './Exception';
|
|
|
3
3
|
import { Response } from '../http/Response';
|
|
4
4
|
import { Results } from './Results';
|
|
5
5
|
import { Result } from './Result';
|
|
6
|
+
import { Optional } from './Types';
|
|
6
7
|
export type ErrorOrigin = Text | Error | Exception | Response | Results | Result;
|
|
8
|
+
export declare const errorMessage: (e: unknown) => Optional<string>;
|
|
@@ -1 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isResponse
|
|
3
|
+
} from "../chunk-EZ4FZ3HS.mjs";
|
|
4
|
+
import {
|
|
5
|
+
choose,
|
|
6
|
+
isException,
|
|
7
|
+
isResults
|
|
8
|
+
} from "../chunk-I2VWZJ2K.mjs";
|
|
9
|
+
import "../chunk-SSROJBD5.mjs";
|
|
10
|
+
import "../chunk-EBIF6AMC.mjs";
|
|
11
|
+
import "../chunk-KCY4RPFR.mjs";
|
|
12
|
+
import "../chunk-S3NSPQ7M.mjs";
|
|
13
|
+
import {
|
|
14
|
+
asString
|
|
15
|
+
} from "../chunk-NNA77YYC.mjs";
|
|
16
|
+
import "../chunk-SJGQU3OG.mjs";
|
|
17
|
+
import "../chunk-D5IYAIMK.mjs";
|
|
18
|
+
import "../chunk-PF7HDF6B.mjs";
|
|
19
|
+
import "../chunk-IXK47WKF.mjs";
|
|
20
|
+
import "../chunk-PIRWVOO2.mjs";
|
|
21
|
+
import {
|
|
22
|
+
isError,
|
|
23
|
+
isString
|
|
24
|
+
} from "../chunk-AAND4MKF.mjs";
|
|
25
|
+
import "../chunk-4N72FQFX.mjs";
|
|
26
|
+
|
|
27
|
+
// src/types/ErrorOrigin.ts
|
|
28
|
+
var errorMessage = (e) => choose(e).type(isResponse, (r) => r.body.error?.errors?.[0]?.message ?? r.body.error?.message).type(isException, (ex) => asString(ex.reason) || ex.message).type(isResults, (rs) => rs.results[0]?.message).type(isError, (e2) => e2.message).type(isString, (s) => s).else(() => void 0);
|
|
29
|
+
export {
|
|
30
|
+
errorMessage
|
|
31
|
+
};
|
|
1
32
|
//# sourceMappingURL=ErrorOrigin.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/types/ErrorOrigin.ts"],"sourcesContent":["import { asString, Text } from './Text';\nimport { Exception, isException } from './Exception';\nimport { isResponse, Response } from '../http/Response';\nimport { isResults, Results } from './Results';\nimport { Result } from './Result';\nimport { choose } from './Case';\nimport { isError, isString } from './Is';\nimport { Optional } from './Types';\n\nexport type ErrorOrigin = Text | Error | Exception | Response | Results | Result;\n\nexport const errorMessage = (e: unknown): Optional<string> =>\n choose(e)\n .type(isResponse, r => r.body.error?.errors?.[0]?.message ?? r.body.error?.message)\n .type(isException, ex => asString(ex.reason) || ex.message)\n .type(isResults, rs => rs.results[0]?.message)\n .type(isError, e => e.message)\n .type(isString, s => s)\n .else(() => undefined);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAWO,IAAM,eAAe,CAAC,MAC3B,OAAO,CAAC,EACL,KAAK,YAAY,OAAK,EAAE,KAAK,OAAO,SAAS,CAAC,GAAG,WAAW,EAAE,KAAK,OAAO,OAAO,EACjF,KAAK,aAAa,QAAM,SAAS,GAAG,MAAM,KAAK,GAAG,OAAO,EACzD,KAAK,WAAW,QAAM,GAAG,QAAQ,CAAC,GAAG,OAAO,EAC5C,KAAK,SAAS,CAAAA,OAAKA,GAAE,OAAO,EAC5B,KAAK,UAAU,OAAK,CAAC,EACrB,KAAK,MAAM,MAAS;","names":["e"]}
|
package/dist/utils/Period.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thisisagile/easy",
|
|
3
|
-
"version": "18.
|
|
3
|
+
"version": "18.12.0",
|
|
4
4
|
"description": "Straightforward library for building domain-driven microservice architectures",
|
|
5
5
|
"author": "Sander Hoogendoorn",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,13 +25,7 @@
|
|
|
25
25
|
"test": "yarn g:jest --coverage",
|
|
26
26
|
"prepack": "yarn g:copy-readme"
|
|
27
27
|
},
|
|
28
|
-
"sideEffects":
|
|
29
|
-
"./src/domain/DateTime.ts",
|
|
30
|
-
"./src/types/Meta.ts",
|
|
31
|
-
"./dist/domain/DateTime.*",
|
|
32
|
-
"./dist/types/Meta.*",
|
|
33
|
-
"./dist/index.js"
|
|
34
|
-
],
|
|
28
|
+
"sideEffects": false,
|
|
35
29
|
"files": [
|
|
36
30
|
"dist",
|
|
37
31
|
"src"
|
|
@@ -42,14 +36,15 @@
|
|
|
42
36
|
"devDependencies": {
|
|
43
37
|
"@thisisagile/easy-test": "*",
|
|
44
38
|
"@types/form-urlencoded": "^4.4.2",
|
|
39
|
+
"@types/luxon": "3.4.2",
|
|
45
40
|
"@types/validator": "^13.12.2"
|
|
46
41
|
},
|
|
47
42
|
"dependencies": {
|
|
48
43
|
"@types/uuid": "^9.0.8",
|
|
49
44
|
"axios": "^1.7.9",
|
|
50
|
-
"dayjs": "^1.11.21",
|
|
51
45
|
"form-urlencoded": "^6.1.5",
|
|
52
46
|
"jwt-decode": "^4.0.0",
|
|
47
|
+
"luxon": "^3.5.0",
|
|
53
48
|
"reflect-metadata": "^0.2.2",
|
|
54
49
|
"uuid": "^9.0.1",
|
|
55
50
|
"validator": "^13.12.0"
|
package/src/domain/DateTime.ts
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import advancedFormat from 'dayjs/plugin/advancedFormat';
|
|
3
|
-
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|
4
|
-
import isoWeek from 'dayjs/plugin/isoWeek';
|
|
5
|
-
import localizedFormat from 'dayjs/plugin/localizedFormat';
|
|
6
|
-
import quarterOfYear from 'dayjs/plugin/quarterOfYear';
|
|
7
|
-
import relativeTime from 'dayjs/plugin/relativeTime';
|
|
8
|
-
import timezone from 'dayjs/plugin/timezone';
|
|
9
|
-
import utc from 'dayjs/plugin/utc';
|
|
10
|
-
import 'dayjs/locale/de';
|
|
11
|
-
import 'dayjs/locale/nl';
|
|
1
|
+
import { DateTime as LuxonDateTime, DateTimeUnit as LuxonDateTimeUnit, DurationUnit as LuxonDurationUnit, Settings } from 'luxon';
|
|
12
2
|
import { Value } from '../types/Value';
|
|
13
3
|
import { Optional } from '../types/Types';
|
|
4
|
+
import { choose } from '../types/Case';
|
|
14
5
|
import { isDefined, isNumber, isString } from '../types/Is';
|
|
15
6
|
import { isDate } from '../types/IsDate';
|
|
16
7
|
import { isA } from '../types/IsA';
|
|
@@ -19,30 +10,11 @@ import { JsonValue } from '../types/Json';
|
|
|
19
10
|
import { seconds } from '../utils/Seconds';
|
|
20
11
|
import { tryTo } from '../types/Try';
|
|
21
12
|
import { use } from '../types/Constructor';
|
|
22
|
-
import { choose } from '../types/Case';
|
|
23
13
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
dayjs.extend(relativeTime);
|
|
29
|
-
dayjs.extend(isoWeek);
|
|
30
|
-
dayjs.extend(advancedFormat);
|
|
31
|
-
dayjs.extend(quarterOfYear);
|
|
32
|
-
dayjs.tz.setDefault('UTC');
|
|
33
|
-
|
|
34
|
-
export type DateTimeUnit = 'year' | 'quarter' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second' | 'millisecond';
|
|
35
|
-
export type DurationUnit =
|
|
36
|
-
| DateTimeUnit
|
|
37
|
-
| 'years'
|
|
38
|
-
| 'quarters'
|
|
39
|
-
| 'months'
|
|
40
|
-
| 'weeks'
|
|
41
|
-
| 'days'
|
|
42
|
-
| 'hours'
|
|
43
|
-
| 'minutes'
|
|
44
|
-
| 'seconds'
|
|
45
|
-
| 'milliseconds';
|
|
14
|
+
Settings.defaultZone = 'utc';
|
|
15
|
+
|
|
16
|
+
export type DateTimeUnit = LuxonDateTimeUnit;
|
|
17
|
+
export type DurationUnit = LuxonDurationUnit;
|
|
46
18
|
export type Duration = Partial<Record<DurationUnit, number>>;
|
|
47
19
|
|
|
48
20
|
export type DiffOptions = {
|
|
@@ -51,65 +23,30 @@ export type DiffOptions = {
|
|
|
51
23
|
|
|
52
24
|
export type DatetimeInput = string | number | Date | DateTime | null;
|
|
53
25
|
|
|
54
|
-
type DateTimeConstructorInput = DatetimeInput | Dayjs;
|
|
55
|
-
type ZonedDayjs = Dayjs & { $x?: { $timezone?: string } };
|
|
56
|
-
|
|
57
|
-
const invalidDate = dayjs.utc(Number.NaN);
|
|
58
|
-
const isDayjs = (value: unknown): value is Dayjs => dayjs.isDayjs(value);
|
|
59
|
-
const isoFormats = [
|
|
60
|
-
'YYYY-MM-DD',
|
|
61
|
-
'YYYY-MM-DDTHH:mm',
|
|
62
|
-
'YYYY-MM-DDTHH:mm:ss',
|
|
63
|
-
'YYYY-MM-DDTHH:mm:ss.SSS',
|
|
64
|
-
'YYYY-MM-DDTHH:mm[Z]',
|
|
65
|
-
'YYYY-MM-DDTHH:mm:ss[Z]',
|
|
66
|
-
'YYYY-MM-DDTHH:mm:ss.SSS[Z]',
|
|
67
|
-
'YYYY-MM-DDTHH:mmZ',
|
|
68
|
-
'YYYY-MM-DDTHH:mmZZ',
|
|
69
|
-
'YYYY-MM-DDTHH:mm:ssZ',
|
|
70
|
-
'YYYY-MM-DDTHH:mm:ssZZ',
|
|
71
|
-
'YYYY-MM-DDTHH:mm:ss.SSSZ',
|
|
72
|
-
'YYYY-MM-DDTHH:mm:ss.SSSZZ',
|
|
73
|
-
];
|
|
74
|
-
const fixedUnitMilliseconds: Partial<Record<DurationUnit, number>> = {
|
|
75
|
-
day: 86400000,
|
|
76
|
-
days: 86400000,
|
|
77
|
-
week: 604800000,
|
|
78
|
-
weeks: 604800000,
|
|
79
|
-
};
|
|
80
|
-
const calendarUnitMonths: Partial<Record<DurationUnit, number>> = {
|
|
81
|
-
month: 1,
|
|
82
|
-
months: 1,
|
|
83
|
-
quarter: 3,
|
|
84
|
-
quarters: 3,
|
|
85
|
-
year: 12,
|
|
86
|
-
years: 12,
|
|
87
|
-
};
|
|
88
|
-
|
|
89
26
|
export class DateTime extends Value<Optional<string>> {
|
|
90
|
-
protected readonly
|
|
27
|
+
protected readonly luxon: LuxonDateTime;
|
|
91
28
|
|
|
92
29
|
constructor(value?: DatetimeInput);
|
|
93
30
|
constructor(value?: string, format?: string);
|
|
94
|
-
constructor(value?:
|
|
95
|
-
const
|
|
96
|
-
.type(
|
|
97
|
-
.type(
|
|
98
|
-
.type(
|
|
99
|
-
.type(
|
|
100
|
-
|
|
101
|
-
.else(
|
|
102
|
-
|
|
103
|
-
super(
|
|
104
|
-
this.
|
|
31
|
+
constructor(value?: DatetimeInput, format?: string) {
|
|
32
|
+
const luxon = choose(value)
|
|
33
|
+
.type(isString, v => (format ? LuxonDateTime.fromFormat(v, format, { setZone: true }) : LuxonDateTime.fromISO(v, { setZone: true })))
|
|
34
|
+
.type(isNumber, v => LuxonDateTime.fromMillis(v))
|
|
35
|
+
.type(isDate, v => LuxonDateTime.fromJSDate(v))
|
|
36
|
+
.type(isDateTime, v => v.luxon)
|
|
37
|
+
// Allow constructing with LuxonDateTime without exposing types
|
|
38
|
+
.else(value instanceof LuxonDateTime ? value : LuxonDateTime.fromISO(undefined as any));
|
|
39
|
+
|
|
40
|
+
super(luxon.toISO() ?? undefined);
|
|
41
|
+
this.luxon = luxon;
|
|
105
42
|
}
|
|
106
43
|
|
|
107
44
|
static get now(): DateTime {
|
|
108
|
-
return
|
|
45
|
+
return new DateTime(LuxonDateTime.utc() as any);
|
|
109
46
|
}
|
|
110
47
|
|
|
111
48
|
get isValid(): boolean {
|
|
112
|
-
return isDefined(this.value) && this.
|
|
49
|
+
return isDefined(this.value) && this.utc.isValid;
|
|
113
50
|
}
|
|
114
51
|
|
|
115
52
|
/**
|
|
@@ -135,8 +72,8 @@ export class DateTime extends Value<Optional<string>> {
|
|
|
135
72
|
return this.withZone('Europe/Warsaw');
|
|
136
73
|
}
|
|
137
74
|
|
|
138
|
-
protected get utc():
|
|
139
|
-
return this.
|
|
75
|
+
protected get utc(): LuxonDateTime {
|
|
76
|
+
return this.luxon.setZone('utc');
|
|
140
77
|
}
|
|
141
78
|
|
|
142
79
|
from(locale?: string): string;
|
|
@@ -148,23 +85,23 @@ export class DateTime extends Value<Optional<string>> {
|
|
|
148
85
|
use((isString(dateOrLocale) ? dateOrLocale : maybeLocale) ?? 'en', locale =>
|
|
149
86
|
ifDefined(
|
|
150
87
|
isA<DateTime>(dateOrLocale) ? dateOrLocale : undefined,
|
|
151
|
-
d => this.utc.
|
|
152
|
-
() => this.utc.
|
|
88
|
+
d => this.utc.setLocale(locale).toRelative({ base: d.utc }),
|
|
89
|
+
() => this.utc.setLocale(locale).toRelative()
|
|
153
90
|
)
|
|
154
91
|
) ?? ''
|
|
155
92
|
);
|
|
156
93
|
}
|
|
157
94
|
|
|
158
95
|
isAfter(dt: DateTime): boolean {
|
|
159
|
-
return this.utc
|
|
96
|
+
return this.utc > dt.utc;
|
|
160
97
|
}
|
|
161
98
|
|
|
162
99
|
isBefore(dt: DateTime): boolean {
|
|
163
|
-
return this.utc
|
|
100
|
+
return this.utc < dt.utc;
|
|
164
101
|
}
|
|
165
102
|
|
|
166
103
|
equals(dt: DateTime): boolean {
|
|
167
|
-
return this.utc.
|
|
104
|
+
return this.utc.hasSame(dt.utc, 'millisecond');
|
|
168
105
|
}
|
|
169
106
|
|
|
170
107
|
add(n: number, unit?: DurationUnit): DateTime;
|
|
@@ -172,7 +109,7 @@ export class DateTime extends Value<Optional<string>> {
|
|
|
172
109
|
add(duration: Duration): DateTime;
|
|
173
110
|
|
|
174
111
|
add(n: number | Duration, unit: DurationUnit = 'day'): DateTime {
|
|
175
|
-
return
|
|
112
|
+
return new DateTime(this.luxon.plus(isNumber(n) ? { [unit]: n } : n) as any);
|
|
176
113
|
}
|
|
177
114
|
|
|
178
115
|
subtract(n: number, unit?: DurationUnit): DateTime;
|
|
@@ -180,28 +117,27 @@ export class DateTime extends Value<Optional<string>> {
|
|
|
180
117
|
subtract(duration: Duration): DateTime;
|
|
181
118
|
|
|
182
119
|
subtract(n: number | Duration, unit: DurationUnit = 'day'): DateTime {
|
|
183
|
-
return
|
|
120
|
+
return new DateTime(this.luxon.minus(isNumber(n) ? { [unit]: n } : n) as any);
|
|
184
121
|
}
|
|
185
122
|
|
|
186
123
|
diff(other: DateTime, unit: DateTimeUnit = 'day', opts?: DiffOptions): number {
|
|
187
|
-
return Math[opts?.rounding ?? 'floor'](this.utc.diff(other.utc
|
|
124
|
+
return Math[opts?.rounding ?? 'floor'](this.utc.diff(other.utc).as(unit));
|
|
188
125
|
}
|
|
189
126
|
|
|
190
127
|
startOf(unit: DateTimeUnit = 'day'): DateTime {
|
|
191
|
-
return
|
|
128
|
+
return new DateTime(this.luxon.startOf(unit) as any);
|
|
192
129
|
}
|
|
193
130
|
|
|
194
131
|
endOf(unit: DateTimeUnit = 'day'): DateTime {
|
|
195
|
-
return
|
|
132
|
+
return new DateTime(this.luxon.endOf(unit) as any);
|
|
196
133
|
}
|
|
197
134
|
|
|
198
135
|
isWeekend(): boolean {
|
|
199
|
-
|
|
200
|
-
return day === 0 || day === 6;
|
|
136
|
+
return this.luxon.isWeekend;
|
|
201
137
|
}
|
|
202
138
|
|
|
203
139
|
withZone(zone: string): DateTime {
|
|
204
|
-
return
|
|
140
|
+
return new DateTime(this.luxon.setZone(zone) as any);
|
|
205
141
|
}
|
|
206
142
|
|
|
207
143
|
toString(): string {
|
|
@@ -209,30 +145,15 @@ export class DateTime extends Value<Optional<string>> {
|
|
|
209
145
|
}
|
|
210
146
|
|
|
211
147
|
toJSON(): JsonValue {
|
|
212
|
-
return this.
|
|
148
|
+
return this.utc.toISO();
|
|
213
149
|
}
|
|
214
150
|
|
|
215
151
|
toFormat(format: string): string {
|
|
216
|
-
return this.
|
|
152
|
+
return this.luxon.toFormat(format);
|
|
217
153
|
}
|
|
218
154
|
|
|
219
155
|
toLocale(locale = 'nl-NL', format = 'D'): string {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
if (format === 'D') return formatWithIntl(this.date, locale, { year: 'numeric', month: 'numeric', day: 'numeric' });
|
|
223
|
-
if (format === 'DDD') return formatWithIntl(this.date, locale, { dateStyle: 'long' });
|
|
224
|
-
if (format === 'ffff') {
|
|
225
|
-
return formatWithIntl(this.date, locale, {
|
|
226
|
-
weekday: 'long',
|
|
227
|
-
year: 'numeric',
|
|
228
|
-
month: 'long',
|
|
229
|
-
day: 'numeric',
|
|
230
|
-
hour: 'numeric',
|
|
231
|
-
minute: '2-digit',
|
|
232
|
-
timeZoneName: timezoneOf(this.date) ? 'long' : 'short',
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
return this.date.locale(toDayjsLocale(locale)).format(toDayjsFormat(format));
|
|
156
|
+
return this.luxon.setLocale(locale).toFormat(format);
|
|
236
157
|
}
|
|
237
158
|
|
|
238
159
|
toFull(locale?: string): string {
|
|
@@ -240,11 +161,11 @@ export class DateTime extends Value<Optional<string>> {
|
|
|
240
161
|
}
|
|
241
162
|
|
|
242
163
|
toDate(): Optional<Date> {
|
|
243
|
-
return this.isValid ? this.utc.
|
|
164
|
+
return this.isValid ? this.utc.toJSDate() : undefined;
|
|
244
165
|
}
|
|
245
166
|
|
|
246
167
|
toEpoch(): number {
|
|
247
|
-
return this.
|
|
168
|
+
return this.luxon.toMillis();
|
|
248
169
|
}
|
|
249
170
|
|
|
250
171
|
ago(end: DateTime = DateTime.now): string {
|
|
@@ -253,7 +174,7 @@ export class DateTime extends Value<Optional<string>> {
|
|
|
253
174
|
|
|
254
175
|
withClock(clock: DateTime): DateTime {
|
|
255
176
|
return tryTo(() => [this.toDate() as Date, clock.toDate() as Date])
|
|
256
|
-
.map(([td, cd]) => new Date(
|
|
177
|
+
.map(([td, cd]) => new Date(td.getFullYear(), td.getMonth(), td.getDate(), cd.getHours(), cd.getMinutes(), cd.getSeconds()))
|
|
257
178
|
.map(d => new DateTime(d)).value;
|
|
258
179
|
}
|
|
259
180
|
}
|
|
@@ -261,90 +182,3 @@ export class DateTime extends Value<Optional<string>> {
|
|
|
261
182
|
export const isDateTime = (dt?: unknown): dt is DateTime => isDefined(dt) && dt instanceof DateTime;
|
|
262
183
|
|
|
263
184
|
export const dt = (dt?: DatetimeInput): DateTime => new DateTime(dt);
|
|
264
|
-
|
|
265
|
-
const parseIso = (value: string): Dayjs => {
|
|
266
|
-
const offset = offsetOf(value);
|
|
267
|
-
if (offset) {
|
|
268
|
-
const date = dayjs.utc(value);
|
|
269
|
-
return date.isValid() ? inOffsetZone(date, offset) : invalidDate;
|
|
270
|
-
}
|
|
271
|
-
return dayjs(value, isoFormats, true).isValid() ? dayjs.utc(value) : invalidDate;
|
|
272
|
-
};
|
|
273
|
-
|
|
274
|
-
const parseFormatted = (value: string, format: string): Dayjs => {
|
|
275
|
-
const dayjsFormat = toDayjsFormat(format);
|
|
276
|
-
const offset = offsetOf(value);
|
|
277
|
-
if (format.includes('ZZZ') && offset) {
|
|
278
|
-
const iso = dayjs.utc(value);
|
|
279
|
-
return iso.isValid() ? inOffsetZone(iso, offset) : invalidDate;
|
|
280
|
-
}
|
|
281
|
-
return dayjs.utc(value, dayjsFormat, true);
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
const offsetOf = (value: string): string | undefined => value.match(/([+-]\d{2}:?\d{2})$/)?.[1];
|
|
285
|
-
|
|
286
|
-
const fromDayjs = (date: Dayjs): DateTime => new DateTime(date as unknown as DatetimeInput);
|
|
287
|
-
|
|
288
|
-
const formatDateTime = (date: Dayjs): string => {
|
|
289
|
-
const formatted = date.format('YYYY-MM-DDTHH:mm:ss.SSSZ');
|
|
290
|
-
return timezoneOf(date) ? formatted : formatted.replace('+00:00', 'Z');
|
|
291
|
-
};
|
|
292
|
-
|
|
293
|
-
const change = (date: Dayjs, value: number | Duration, unit: DurationUnit, direction: 'add' | 'subtract'): Dayjs => {
|
|
294
|
-
if (isNumber(value)) return changeUnit(date, value, unit, direction);
|
|
295
|
-
return Object.entries(value).reduce((result, [durationUnit, durationValue]) => changeUnit(result, durationValue ?? 0, durationUnit as DurationUnit, direction), date);
|
|
296
|
-
};
|
|
297
|
-
|
|
298
|
-
const changeUnit = (date: Dayjs, value: number, unit: DurationUnit, direction: 'add' | 'subtract'): Dayjs => {
|
|
299
|
-
const amount = direction === 'add' ? value : -value;
|
|
300
|
-
const milliseconds = fixedUnitMilliseconds[unit];
|
|
301
|
-
const months = calendarUnitMonths[unit];
|
|
302
|
-
|
|
303
|
-
if (months && !Number.isInteger(value)) return addMonths(date, amount * months);
|
|
304
|
-
if (milliseconds && !Number.isInteger(value)) return date.add(amount * milliseconds, 'millisecond');
|
|
305
|
-
return date.add(amount, toDayjsUnit(unit));
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
const addMonths = (date: Dayjs, months: number): Dayjs => {
|
|
309
|
-
const wholeMonths = Math.trunc(months);
|
|
310
|
-
const fraction = months - wholeMonths;
|
|
311
|
-
const shifted = date.add(wholeMonths, 'month');
|
|
312
|
-
if (fraction === 0) return shifted;
|
|
313
|
-
|
|
314
|
-
const next = shifted.add(months > 0 ? 1 : -1, 'month');
|
|
315
|
-
return shifted.add((next.valueOf() - shifted.valueOf()) * Math.abs(fraction), 'millisecond');
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
const inOffsetZone = (date: Dayjs, offset: string): Dayjs => offsetToTimeZone(offset).map(zone => date.tz(zone)).or(date.utcOffset(offset));
|
|
319
|
-
|
|
320
|
-
const offsetToTimeZone = (offset: string) =>
|
|
321
|
-
tryTo(() => {
|
|
322
|
-
const [, sign, hours, minutes] = offset.match(/^([+-])(\d{2}):?(\d{2})$/) ?? [];
|
|
323
|
-
if (minutes !== '00') throw new Error();
|
|
324
|
-
if (hours === '00') return 'UTC';
|
|
325
|
-
return `Etc/GMT${sign === '+' ? '-' : '+'}${Number(hours)}`;
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
const toDayjsUnit = (unit: DurationUnit): ManipulateType => unit.replace(/s$/, '') as ManipulateType;
|
|
329
|
-
|
|
330
|
-
const toDayjsBoundaryUnit = (unit: DateTimeUnit): OpUnitType => {
|
|
331
|
-
const dayjsUnit = toDayjsUnit(unit);
|
|
332
|
-
return (dayjsUnit === 'week' ? 'isoWeek' : dayjsUnit) as OpUnitType;
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
const toDayjsFormat = (format: string): string =>
|
|
336
|
-
format
|
|
337
|
-
.replace(/'([^']+)'/g, '[$1]')
|
|
338
|
-
.replace(/EEE/g, 'ddd')
|
|
339
|
-
.replace(/yyyy/g, 'YYYY')
|
|
340
|
-
.replace(/dd/g, 'DD')
|
|
341
|
-
.replace(/LLL/g, 'MMM')
|
|
342
|
-
.replace(/ZZZ/g, 'ZZ')
|
|
343
|
-
.replace(/hh/g, 'HH');
|
|
344
|
-
|
|
345
|
-
const toDayjsLocale = (locale: string): string => locale.toLowerCase().split('-')[0];
|
|
346
|
-
|
|
347
|
-
const formatWithIntl = (date: Dayjs, locale: string, options: Intl.DateTimeFormatOptions): string =>
|
|
348
|
-
new Intl.DateTimeFormat(locale, { ...options, timeZone: timezoneOf(date) ?? 'UTC' }).format(date.toDate());
|
|
349
|
-
|
|
350
|
-
const timezoneOf = (date: Dayjs): string | undefined => (date as ZonedDayjs).$x?.$timezone;
|
package/src/types/ErrorOrigin.ts
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
|
-
import { Text } from './Text';
|
|
2
|
-
import { Exception } from './Exception';
|
|
3
|
-
import { Response } from '../http/Response';
|
|
4
|
-
import { Results } from './Results';
|
|
1
|
+
import { asString, Text } from './Text';
|
|
2
|
+
import { Exception, isException } from './Exception';
|
|
3
|
+
import { isResponse, Response } from '../http/Response';
|
|
4
|
+
import { isResults, Results } from './Results';
|
|
5
5
|
import { Result } from './Result';
|
|
6
|
+
import { choose } from './Case';
|
|
7
|
+
import { isError, isString } from './Is';
|
|
8
|
+
import { Optional } from './Types';
|
|
6
9
|
|
|
7
10
|
export type ErrorOrigin = Text | Error | Exception | Response | Results | Result;
|
|
11
|
+
|
|
12
|
+
export const errorMessage = (e: unknown): Optional<string> =>
|
|
13
|
+
choose(e)
|
|
14
|
+
.type(isResponse, r => r.body.error?.errors?.[0]?.message ?? r.body.error?.message)
|
|
15
|
+
.type(isException, ex => asString(ex.reason) || ex.message)
|
|
16
|
+
.type(isResults, rs => rs.results[0]?.message)
|
|
17
|
+
.type(isError, e => e.message)
|
|
18
|
+
.type(isString, s => s)
|
|
19
|
+
.else(() => undefined);
|