@wisemen/wise-date 0.0.1

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.
Files changed (44) hide show
  1. package/README.md +302 -0
  2. package/dist/future-infinity-date.d.ts +31 -0
  3. package/dist/future-infinity-date.js +87 -0
  4. package/dist/future-infinity-date.js.map +1 -0
  5. package/dist/index.d.ts +9 -0
  6. package/dist/index.js +12 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/init-dayjs.d.ts +1 -0
  9. package/dist/init-dayjs.js +24 -0
  10. package/dist/init-dayjs.js.map +1 -0
  11. package/dist/invalid-date.d.ts +5 -0
  12. package/dist/invalid-date.js +8 -0
  13. package/dist/invalid-date.js.map +1 -0
  14. package/dist/month.d.ts +15 -0
  15. package/dist/month.js +21 -0
  16. package/dist/month.js.map +1 -0
  17. package/dist/past-infinity-date.d.ts +31 -0
  18. package/dist/past-infinity-date.js +87 -0
  19. package/dist/past-infinity-date.js.map +1 -0
  20. package/dist/plain-date-object.d.ts +6 -0
  21. package/dist/plain-date-object.js +2 -0
  22. package/dist/plain-date-object.js.map +1 -0
  23. package/dist/tests/wise-date.constructor.unit.test.d.ts +1 -0
  24. package/dist/tests/wise-date.constructor.unit.test.js +31 -0
  25. package/dist/tests/wise-date.constructor.unit.test.js.map +1 -0
  26. package/dist/tests/wise-date.manipulation.unit.test.d.ts +1 -0
  27. package/dist/tests/wise-date.manipulation.unit.test.js +92 -0
  28. package/dist/tests/wise-date.manipulation.unit.test.js.map +1 -0
  29. package/dist/tests/wise-date.ordering.unit.test.d.ts +1 -0
  30. package/dist/tests/wise-date.ordering.unit.test.js +174 -0
  31. package/dist/tests/wise-date.ordering.unit.test.js.map +1 -0
  32. package/dist/units.d.ts +4 -0
  33. package/dist/units.js +2 -0
  34. package/dist/units.js.map +1 -0
  35. package/dist/wise-date.column.d.ts +3 -0
  36. package/dist/wise-date.column.js +31 -0
  37. package/dist/wise-date.column.js.map +1 -0
  38. package/dist/wise-date.d.ts +52 -0
  39. package/dist/wise-date.factory.d.ts +4 -0
  40. package/dist/wise-date.factory.js +14 -0
  41. package/dist/wise-date.factory.js.map +1 -0
  42. package/dist/wise-date.js +156 -0
  43. package/dist/wise-date.js.map +1 -0
  44. package/package.json +40 -0
package/README.md ADDED
@@ -0,0 +1,302 @@
1
+ # Wisemen Monetary Package for TypeScript
2
+
3
+ ## Features
4
+
5
+ ✔ Accurate Financial Calculations – `Monetary` provides the tools to accurately perform moneraty operations \
6
+ ✔ Persistence Support – Seamlessly store and retrieve monetary values with extenstions for `TypeORM`. \
7
+ ✔ DTO Validation – Ensure data integrity with built-in validation for monetary objects. \
8
+ ✔ Immutability – Monetary is fully immutable, meaning no state bugs. \
9
+ ✔ TypeScript Support – Fully typed for a smooth developer experience.
10
+
11
+
12
+ ## Philosophy
13
+
14
+ Wisemen Monetary places the responsibility of accurately dealing with monetary values with the developer, but helps where needed by providing the necessary tools.
15
+
16
+ ## Example
17
+
18
+ ```typescript
19
+ // 10 euros with precision 4
20
+ import { Monetary } from './monetary'
21
+
22
+ const price = new Monetary({
23
+ amount: 10_0000,
24
+ currency: Currency.EUR,
25
+ precision: 4
26
+ })
27
+
28
+ // 2 euros discount with precision 0
29
+ const flatDiscount = new Monetary({
30
+ amount: 2,
31
+ currency: Currency.EUR,
32
+ precision: 0
33
+ })
34
+
35
+ const bonusDiscountRate = 0.90 // 90 percent of discounted price
36
+
37
+ const discountedPrice = price
38
+ .subtract(flatDiscount) // subtract 2 euros
39
+ .multiply(bonusDiscountRate) // take 90 percent of price
40
+ .toPrecision(2) // only store up to cents
41
+ .floor()
42
+
43
+ discountedPrice.toString() // -> "7,20 euros"
44
+ ```
45
+
46
+
47
+ ## Deep Dive
48
+
49
+ ### Monetary operations
50
+
51
+ #### Rounding
52
+
53
+ Monetary stores the current amount internally as a regular javascript `number` which means it can be both an `integer` or a `float`. Monetary objects will never perform any type of rounding on the internal value automatically. The point at which rounding of the monetary value takes place and the specific rounding operation is determined by the developer. Rounding always respects the set precision.
54
+
55
+ Monetary supports 3 rounding operations:
56
+ - `round()`: rounds half up to the nearest integer
57
+ - `ceil()`: rounds up to the nearest integer
58
+ - `floor()`: rounds down to the nearest integer
59
+
60
+ ```typescript
61
+ // 10 euros with precsion 2
62
+ const price = new Monetary({
63
+ amount: 1000,
64
+ currency: Currency.EUR,
65
+ precision: 2
66
+ })
67
+
68
+ price.isRounded() // -> true
69
+
70
+ const discountedPrice = price.multiply(.9999) // -> 9.999 euros
71
+ discountedPrice.isRounded() // -> false
72
+
73
+ discountedPrice.round() // -> 10 euros
74
+ discountedPrice.floor() // -> 9.99 euros
75
+ discountedPrice.ceil() // -> 10 euros
76
+ ```
77
+
78
+ #### Adding and subtracting
79
+
80
+ Monetary only allows values with the same currency to be added or subtracted from each other.
81
+
82
+ ```typescript
83
+ // 10 euros with precsion 2
84
+ const euros = new Monetary({
85
+ amount: 1000,
86
+ currency: Currency.EUR,
87
+ precision: 2
88
+ })
89
+
90
+ // 10 USD with precsion 2
91
+ const dollars = new Monetary({
92
+ amount: 1000,
93
+ currency: Currency.USD,
94
+ precision: 2
95
+ })
96
+
97
+ euros.add(dollars) // -> throws IllegalMonetaryOperationError
98
+ euros.subtract(dollars) // -> throws IllegalMonetaryOperationError
99
+ ```
100
+
101
+ Adding or subtracting values with different precisions will use the highest precision of the two in the resulting value. The amount of the value with the lowest precision is increased to the higher precision before the operation is performed.
102
+
103
+ ```typescript
104
+ // 10 euros with precsion 2
105
+ const euros = new Monetary({
106
+ amount: 1000,
107
+ currency: Currency.EUR,
108
+ precision: 2
109
+ })
110
+
111
+ // 10 euros with precsion 4
112
+ const morePreciseEuros = new Monetary({
113
+ amount: 1000000,
114
+ currency: Currency.EUR,
115
+ precision: 4
116
+ })
117
+
118
+ euros.add(morePreciseEuros) // -> 20 euros with precision 4
119
+ euros.subtract(morePreciseEuros) // -> 0 euros with precision 4
120
+ ```
121
+
122
+ #### Changing precision
123
+
124
+ Changing the precision of a monetary value adjusts the internal amount. The value is multiplied by 10<sup>(newPrecision - oldPrecision)</sup>. A decrease in precision can result in an unrounded value.
125
+
126
+ ```typescript
127
+ // 9,50 euros with precsion 2
128
+ const euros = new Monetary({
129
+ amount: 950,
130
+ currency: Currency.EUR,
131
+ precision: 2
132
+ })
133
+
134
+ euros.toPrecision(4) // -> amount of 95000
135
+ euros.toPrecision(0) // -> amount of 9,50 (unrounded)
136
+ ```
137
+
138
+ ### Persistence
139
+
140
+ Storing arbitrary precision is not possible in Monetary. Monetary storing mechanisms require a set precision. All stored values will have the set precision. Values with a lower precision are normalized to the set precision. Values with a higher precision will trigger an error when stored.
141
+
142
+ ```typescript
143
+ class Entity {
144
+ @MonetaryColumn({defaultPrecision: 4})
145
+ amount: Monetary
146
+ }
147
+
148
+ // 9,50 euros with precsion 2
149
+ const euros = new Monetary({
150
+ amount: 950,
151
+ currency: Currency.EUR,
152
+ precision: 2
153
+ })
154
+
155
+ // 9,50 euros with precsion 5
156
+ const highPrecisionEuros = new Monetary({
157
+ amount: 950000,
158
+ currency: Currency.EUR,
159
+ precision: 5
160
+ })
161
+
162
+ await entityRepository.insert({amount: euros}) // -> stored as 95000
163
+ await entityRepository.insert({amount: highPrecisionEuros}) // -> throws PrecisionLossError
164
+ ```
165
+
166
+ Monetary provides 2 storing mechanisms for `TypeORM`.
167
+
168
+ #### Storing only the amount
169
+
170
+ When the currency of a monetary value is static (i.e. only EUR is supported) monetary values can be stored as just the amount. The amount is stored as an `int4` column.
171
+
172
+ ```typescript
173
+ class Entity {
174
+ @MonetaryAmountColumn({
175
+ monetaryPrecision: 4,
176
+ currency: Currency.EUR // the static currency
177
+ })
178
+ amount: Monetary
179
+ }
180
+
181
+ // 9,50 dollars with precision 2
182
+ const dollars = new Monetary({
183
+ amount: 950,
184
+ currency: Currency.USD,
185
+ precision: 2
186
+ })
187
+
188
+ await entityRepository.insert({amount: dollars}) // -> throws UnsupportedCurrencyError
189
+ ```
190
+
191
+ #### Storing the amount and currency
192
+
193
+ Storing multiple currencies in a single field will store the monetary values as `jsonb`. It's possible to define a precision per currency. If a precision is not set for a currency, the default precision is used.
194
+
195
+ ```typescript
196
+ class Entity {
197
+ @MonetaryColumn({
198
+ defaultPrecision: 2,
199
+ currencyPrecisions: {
200
+ [Currency.EUR]: 4
201
+ }
202
+ })
203
+ amount: Monetary
204
+ }
205
+
206
+ // 9,50 dollars with precsion 2
207
+ const dollars = new Monetary({
208
+ amount: 950,
209
+ currency: Currency.USD,
210
+ precision: 2
211
+ })
212
+
213
+ // 9,50 euros with precsion 2
214
+ const euros = new Monetary({
215
+ amount: 950,
216
+ currency: Currency.EUR,
217
+ precision: 2
218
+ })
219
+
220
+
221
+ await entityRepository.insert({amount: dollars}) // -> stored with precision 2 as 950
222
+ await entityRepository.insert({amount: euros}) // -> stored with precision 4 as 95000
223
+ ```
224
+
225
+ ### DTO
226
+
227
+ Monetary provides a DTO `MonetaryDto` which defines `ApiProperty`s for open api documentation in `Nestjs` and validation for `class-validator`.
228
+
229
+ ```json
230
+ {
231
+ "amount": 950,
232
+ "currency": "EUR",
233
+ "precision": 2
234
+ }
235
+ ```
236
+
237
+ #### Validation
238
+
239
+ The DTO validates it's internal properties. When you need to validate the DTO as a nested property you can use `IsMonetary`. This validator applies `IsObject`, `ValidateNested` and `Type` internally. You can optionally define allowed currencies and a maximum precision.
240
+
241
+ ```typescript
242
+ class EntityDto {
243
+ @IsMonetary({
244
+ maxPrecision: 4, // optional max precision
245
+ allowedCurrencies: new Set([Currency.EUR]) // optional allowed currencies
246
+ })
247
+ amount: MonetaryDto
248
+ }
249
+ ```
250
+
251
+ #### Creating DTOs
252
+
253
+ A Monetary DTO can be made through a static method:
254
+
255
+ ```typescript
256
+ const euros = new Monetary({
257
+ amount: 950,
258
+ currency: Currency.EUR,
259
+ precision: 2
260
+ })
261
+
262
+ const dto = MonetaryDto.from(euros)
263
+ ```
264
+
265
+ Or with a builder which allows invalid values for testing:
266
+ ```typescript
267
+ const dto = new MonetaryDtoBuilder()
268
+ .withAmount(950)
269
+ .withCurrency(Currency.EUR)
270
+ .withPrecision(2)
271
+ .build()
272
+ ```
273
+
274
+ #### Parsing DTOs
275
+
276
+ A Monetary DTO can be parsed by passing it to the constructor:
277
+
278
+ ```typescript
279
+ const dto = new MonetaryDtoBuilder()
280
+ .withAmount(950)
281
+ .withCurrency(Currency.EUR)
282
+ .withPrecision(2)
283
+ .build()
284
+
285
+ const amount = new Monetary(dto)
286
+ ```
287
+
288
+ or with a convenience method on the dto:
289
+
290
+ ```typescript
291
+ const dto = new MonetaryDtoBuilder()
292
+ .withAmount(950)
293
+ .withCurrency(Currency.EUR)
294
+ .withPrecision(2)
295
+ .build()
296
+
297
+ const amount = dto.parse()
298
+ ```
299
+
300
+
301
+
302
+
@@ -0,0 +1,31 @@
1
+ import { WiseDate } from './wise-date.js';
2
+ import { DateUnit, DiffDateUnit, ReachableDateUnit } from './units.js';
3
+ import { PlainDateObject } from './plain-date-object.js';
4
+ export declare class FutureInfinityDate extends WiseDate {
5
+ constructor();
6
+ isSame(otherDate: WiseDate, _unit?: DateUnit): boolean;
7
+ isAfter(_otherDate: WiseDate, _unit?: DateUnit): boolean;
8
+ isSameOrAfter(_otherDate: WiseDate, _unit?: DateUnit): boolean;
9
+ isBefore(_otherDate: WiseDate, _unit?: DateUnit): boolean;
10
+ isSameOrBefore(otherDate: WiseDate, unit?: DateUnit): boolean;
11
+ startOf(_unit: ReachableDateUnit): WiseDate;
12
+ endOf(_unit: ReachableDateUnit): WiseDate;
13
+ get year(): number;
14
+ get month(): number;
15
+ get dayOfMonth(): number;
16
+ get weekOfYear(): number;
17
+ get dayOfYear(): number;
18
+ isToday(): boolean;
19
+ isTomorrow(): boolean;
20
+ isYesterday(): boolean;
21
+ add(_amount: number, _unit: DateUnit): WiseDate;
22
+ subtract(_amount: number, _unit: DateUnit): WiseDate;
23
+ diff(_withOther: WiseDate, _unit: DiffDateUnit, _precise?: boolean): number;
24
+ format(_template: string): string;
25
+ clone(): WiseDate;
26
+ toPlainObject(): PlainDateObject;
27
+ toString(): string;
28
+ isFutureInfinity(): boolean;
29
+ isPastInfinity(): boolean;
30
+ isInfinity(): boolean;
31
+ }
@@ -0,0 +1,87 @@
1
+ import dayjs from 'dayjs';
2
+ import { WiseDate } from './wise-date.js';
3
+ export class FutureInfinityDate extends WiseDate {
4
+ constructor() {
5
+ super(dayjs(8.64e15));
6
+ }
7
+ isSame(otherDate, _unit) {
8
+ return otherDate instanceof FutureInfinityDate;
9
+ }
10
+ isAfter(_otherDate, _unit) {
11
+ return true;
12
+ }
13
+ isSameOrAfter(_otherDate, _unit) {
14
+ return true;
15
+ }
16
+ isBefore(_otherDate, _unit) {
17
+ return false;
18
+ }
19
+ isSameOrBefore(otherDate, unit) {
20
+ return this.isSame(otherDate, unit);
21
+ }
22
+ startOf(_unit) {
23
+ return this;
24
+ }
25
+ endOf(_unit) {
26
+ return this;
27
+ }
28
+ get year() {
29
+ return Infinity;
30
+ }
31
+ get month() {
32
+ return Infinity;
33
+ }
34
+ get dayOfMonth() {
35
+ return Infinity;
36
+ }
37
+ get weekOfYear() {
38
+ return Infinity;
39
+ }
40
+ get dayOfYear() {
41
+ return Infinity;
42
+ }
43
+ isToday() {
44
+ return false;
45
+ }
46
+ isTomorrow() {
47
+ return false;
48
+ }
49
+ isYesterday() {
50
+ return false;
51
+ }
52
+ add(_amount, _unit) {
53
+ return this;
54
+ }
55
+ subtract(_amount, _unit) {
56
+ return this;
57
+ }
58
+ diff(_withOther, _unit, _precise = false) {
59
+ return Infinity;
60
+ }
61
+ format(_template) {
62
+ return 'future infinity';
63
+ }
64
+ clone() {
65
+ return this;
66
+ }
67
+ toPlainObject() {
68
+ return {
69
+ year: Infinity,
70
+ month: Infinity,
71
+ day: Infinity
72
+ };
73
+ }
74
+ toString() {
75
+ return 'infinity';
76
+ }
77
+ isFutureInfinity() {
78
+ return true;
79
+ }
80
+ isPastInfinity() {
81
+ return false;
82
+ }
83
+ isInfinity() {
84
+ return true;
85
+ }
86
+ }
87
+ //# sourceMappingURL=future-infinity-date.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"future-infinity-date.js","sourceRoot":"","sources":["../lib/future-infinity-date.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAIzC,MAAM,OAAO,kBAAmB,SAAQ,QAAQ;IAC9C;QACE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA;IACvB,CAAC;IAED,MAAM,CAAE,SAAmB,EAAE,KAAgB;QAC3C,OAAO,SAAS,YAAY,kBAAkB,CAAA;IAChD,CAAC;IAED,OAAO,CAAE,UAAoB,EAAE,KAAgB;QAC7C,OAAO,IAAI,CAAA;IACb,CAAC;IAED,aAAa,CAAE,UAAoB,EAAE,KAAgB;QACnD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,QAAQ,CAAE,UAAoB,EAAE,KAAgB;QAC9C,OAAO,KAAK,CAAA;IACd,CAAC;IAED,cAAc,CAAE,SAAmB,EAAE,IAAe;QAClD,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;IACrC,CAAC;IAED,OAAO,CAAE,KAAwB;QAC/B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK,CAAE,KAAwB;QAC7B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,IAAI;QACN,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,IAAI,KAAK;QACP,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,IAAI,SAAS;QACX,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,OAAO;QACL,OAAO,KAAK,CAAA;IACd,CAAC;IAED,UAAU;QACR,OAAO,KAAK,CAAA;IACd,CAAC;IAED,WAAW;QACT,OAAO,KAAK,CAAA;IACd,CAAC;IAEM,GAAG,CAAE,OAAe,EAAE,KAAe;QAC1C,OAAO,IAAI,CAAA;IACb,CAAC;IAEM,QAAQ,CAAE,OAAe,EAAE,KAAe;QAC/C,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,CAAE,UAAoB,EAAE,KAAmB,EAAE,QAAQ,GAAG,KAAK;QAC/D,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,MAAM,CAAE,SAAiB;QACvB,OAAO,iBAAiB,CAAA;IAC1B,CAAC;IAED,KAAK;QACH,OAAO,IAAI,CAAA;IACb,CAAC;IAED,aAAa;QACX,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,QAAQ;YACf,GAAG,EAAE,QAAQ;SACd,CAAA;IACH,CAAC;IAED,QAAQ;QACN,OAAO,UAAU,CAAA;IACnB,CAAC;IAED,gBAAgB;QACd,OAAO,IAAI,CAAA;IACb,CAAC;IAED,cAAc;QACZ,OAAO,KAAK,CAAA;IACd,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAA;IACb,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ export * from './wise-date.js';
2
+ export * from './month.js';
3
+ export * from './invalid-date.js';
4
+ export * from './units.js';
5
+ export * from './plain-date-object.js';
6
+ export * from './future-infinity-date.js';
7
+ export * from './past-infinity-date.js';
8
+ export * from './wise-date.factory.js';
9
+ export * from './wise-date.column.js';
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ import { initDayjs } from './init-dayjs.js';
2
+ initDayjs();
3
+ export * from './wise-date.js';
4
+ export * from './month.js';
5
+ export * from './invalid-date.js';
6
+ export * from './units.js';
7
+ export * from './plain-date-object.js';
8
+ export * from './future-infinity-date.js';
9
+ export * from './past-infinity-date.js';
10
+ export * from './wise-date.factory.js';
11
+ export * from './wise-date.column.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,SAAS,EAAE,CAAA;AAEX,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA;AAC1B,cAAc,mBAAmB,CAAA;AACjC,cAAc,YAAY,CAAA;AAC1B,cAAc,wBAAwB,CAAA;AACtC,cAAc,2BAA2B,CAAA;AACzC,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA"}
@@ -0,0 +1 @@
1
+ export declare function initDayjs(): void;
@@ -0,0 +1,24 @@
1
+ import dayjs from 'dayjs';
2
+ import customParseFormat from 'dayjs/plugin/customParseFormat.js';
3
+ import isoWeek from 'dayjs/plugin/isoWeek.js';
4
+ import MinMax from 'dayjs/plugin/minMax.js';
5
+ import Utc from 'dayjs/plugin/utc.js';
6
+ import TimeZone from 'dayjs/plugin/timezone.js';
7
+ import weekOfYear from 'dayjs/plugin/weekOfYear.js';
8
+ import dayOfYear from 'dayjs/plugin/dayOfYear.js';
9
+ import isToday from 'dayjs/plugin/isToday.js';
10
+ import isTomorrow from 'dayjs/plugin/isTomorrow.js';
11
+ import isYesterday from 'dayjs/plugin/isYesterday.js';
12
+ export function initDayjs() {
13
+ dayjs.extend(customParseFormat);
14
+ dayjs.extend(isoWeek);
15
+ dayjs.extend(MinMax);
16
+ dayjs.extend(Utc);
17
+ dayjs.extend(TimeZone);
18
+ dayjs.extend(weekOfYear);
19
+ dayjs.extend(dayOfYear);
20
+ dayjs.extend(isToday);
21
+ dayjs.extend(isTomorrow);
22
+ dayjs.extend(isYesterday);
23
+ }
24
+ //# sourceMappingURL=init-dayjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-dayjs.js","sourceRoot":"","sources":["../lib/init-dayjs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,iBAAiB,MAAM,mCAAmC,CAAA;AACjE,OAAO,OAAO,MAAM,yBAAyB,CAAA;AAC7C,OAAO,MAAM,MAAM,wBAAwB,CAAA;AAC3C,OAAO,GAAG,MAAM,qBAAqB,CAAA;AACrC,OAAO,QAAQ,MAAM,0BAA0B,CAAA;AAC/C,OAAO,UAAU,MAAM,4BAA4B,CAAA;AACnD,OAAO,SAAS,MAAM,2BAA2B,CAAA;AACjD,OAAO,OAAO,MAAM,yBAAyB,CAAA;AAC7C,OAAO,UAAU,MAAM,4BAA4B,CAAA;AACnD,OAAO,WAAW,MAAM,6BAA6B,CAAA;AAErD,MAAM,UAAU,SAAS;IACvB,KAAK,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAA;IAC/B,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACrB,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACpB,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACjB,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IACtB,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IACxB,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IACvB,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACrB,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IACxB,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;AAC3B,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { WiseDate } from './wise-date.js';
2
+ export declare class InvalidDate extends Error {
3
+ readonly date: WiseDate;
4
+ constructor(date: WiseDate);
5
+ }
@@ -0,0 +1,8 @@
1
+ export class InvalidDate extends Error {
2
+ date;
3
+ constructor(date) {
4
+ super(`Invalid date: ${date.format('YYYY-MM-DD')}`);
5
+ this.date = date;
6
+ }
7
+ }
8
+ //# sourceMappingURL=invalid-date.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invalid-date.js","sourceRoot":"","sources":["../lib/invalid-date.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,WAAY,SAAQ,KAAK;IAElB;IADlB,YACkB,IAAc;QAE9B,KAAK,CAAC,iBAAiB,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAA;QAFnC,SAAI,GAAJ,IAAI,CAAU;IAGhC,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ export declare enum Month {
2
+ JANUARY = 1,
3
+ FEBRUARY = 2,
4
+ MARCH = 3,
5
+ APRIL = 4,
6
+ MAY = 5,
7
+ JUNE = 6,
8
+ JULY = 7,
9
+ AUGUST = 8,
10
+ SEPTEMBER = 9,
11
+ OCTOBER = 10,
12
+ NOVEMBER = 11,
13
+ DECEMBER = 12
14
+ }
15
+ export declare function month(value: number): Month;
package/dist/month.js ADDED
@@ -0,0 +1,21 @@
1
+ export var Month;
2
+ (function (Month) {
3
+ Month[Month["JANUARY"] = 1] = "JANUARY";
4
+ Month[Month["FEBRUARY"] = 2] = "FEBRUARY";
5
+ Month[Month["MARCH"] = 3] = "MARCH";
6
+ Month[Month["APRIL"] = 4] = "APRIL";
7
+ Month[Month["MAY"] = 5] = "MAY";
8
+ Month[Month["JUNE"] = 6] = "JUNE";
9
+ Month[Month["JULY"] = 7] = "JULY";
10
+ Month[Month["AUGUST"] = 8] = "AUGUST";
11
+ Month[Month["SEPTEMBER"] = 9] = "SEPTEMBER";
12
+ Month[Month["OCTOBER"] = 10] = "OCTOBER";
13
+ Month[Month["NOVEMBER"] = 11] = "NOVEMBER";
14
+ Month[Month["DECEMBER"] = 12] = "DECEMBER";
15
+ })(Month || (Month = {}));
16
+ export function month(value) {
17
+ if (1 <= value && value <= 12)
18
+ return value;
19
+ throw new Error('Month must be a value between 1 and 12');
20
+ }
21
+ //# sourceMappingURL=month.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"month.js","sourceRoot":"","sources":["../lib/month.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,KAaX;AAbD,WAAY,KAAK;IACf,uCAAW,CAAA;IACX,yCAAY,CAAA;IACZ,mCAAS,CAAA;IACT,mCAAS,CAAA;IACT,+BAAO,CAAA;IACP,iCAAQ,CAAA;IACR,iCAAQ,CAAA;IACR,qCAAU,CAAA;IACV,2CAAa,CAAA;IACb,wCAAY,CAAA;IACZ,0CAAa,CAAA;IACb,0CAAa,CAAA;AACf,CAAC,EAbW,KAAK,KAAL,KAAK,QAahB;AAED,MAAM,UAAU,KAAK,CAAE,KAAa;IAClC,IAAI,CAAC,IAAI,KAAK,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,KAAc,CAAA;IACpD,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;AAC3D,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { WiseDate } from './wise-date.js';
2
+ import { DateUnit, DiffDateUnit, ReachableDateUnit } from './units.js';
3
+ import { PlainDateObject } from './plain-date-object.js';
4
+ export declare class PastInfinityDate extends WiseDate {
5
+ constructor();
6
+ isSame(otherDate: WiseDate, _unit?: DateUnit): boolean;
7
+ isAfter(_otherDate: WiseDate, _unit?: DateUnit): boolean;
8
+ isSameOrAfter(_otherDate: WiseDate, _unit?: DateUnit): boolean;
9
+ isBefore(_otherDate: WiseDate, _unit?: DateUnit): boolean;
10
+ isSameOrBefore(_otherDate: WiseDate, _unit?: DateUnit): boolean;
11
+ startOf(_unit: ReachableDateUnit): WiseDate;
12
+ endOf(_unit: ReachableDateUnit): WiseDate;
13
+ get year(): number;
14
+ get month(): number;
15
+ get dayOfMonth(): number;
16
+ get weekOfYear(): number;
17
+ get dayOfYear(): number;
18
+ isToday(): boolean;
19
+ isTomorrow(): boolean;
20
+ isYesterday(): boolean;
21
+ add(_amount: number, _unit: DateUnit): WiseDate;
22
+ subtract(_amount: number, _unit: DateUnit): WiseDate;
23
+ diff(_withOther: WiseDate, _unit: DiffDateUnit, _precise?: boolean): number;
24
+ format(_template: string): string;
25
+ clone(): WiseDate;
26
+ toPlainObject(): PlainDateObject;
27
+ toString(): string;
28
+ isFutureInfinity(): boolean;
29
+ isPastInfinity(): boolean;
30
+ isInfinity(): boolean;
31
+ }
@@ -0,0 +1,87 @@
1
+ import dayjs from 'dayjs';
2
+ import { WiseDate } from './wise-date.js';
3
+ export class PastInfinityDate extends WiseDate {
4
+ constructor() {
5
+ super(dayjs(-8.64e14));
6
+ }
7
+ isSame(otherDate, _unit) {
8
+ return otherDate instanceof PastInfinityDate;
9
+ }
10
+ isAfter(_otherDate, _unit) {
11
+ return false;
12
+ }
13
+ isSameOrAfter(_otherDate, _unit) {
14
+ return this.isSame(_otherDate, _unit);
15
+ }
16
+ isBefore(_otherDate, _unit) {
17
+ return true;
18
+ }
19
+ isSameOrBefore(_otherDate, _unit) {
20
+ return true;
21
+ }
22
+ startOf(_unit) {
23
+ return this;
24
+ }
25
+ endOf(_unit) {
26
+ return this;
27
+ }
28
+ get year() {
29
+ return -Infinity;
30
+ }
31
+ get month() {
32
+ return -Infinity;
33
+ }
34
+ get dayOfMonth() {
35
+ return -Infinity;
36
+ }
37
+ get weekOfYear() {
38
+ return -Infinity;
39
+ }
40
+ get dayOfYear() {
41
+ return -Infinity;
42
+ }
43
+ isToday() {
44
+ return false;
45
+ }
46
+ isTomorrow() {
47
+ return false;
48
+ }
49
+ isYesterday() {
50
+ return false;
51
+ }
52
+ add(_amount, _unit) {
53
+ return this;
54
+ }
55
+ subtract(_amount, _unit) {
56
+ return this;
57
+ }
58
+ diff(_withOther, _unit, _precise = false) {
59
+ return Infinity;
60
+ }
61
+ format(_template) {
62
+ return '-infinity';
63
+ }
64
+ clone() {
65
+ return this;
66
+ }
67
+ toPlainObject() {
68
+ return {
69
+ year: -Infinity,
70
+ month: -Infinity,
71
+ day: -Infinity
72
+ };
73
+ }
74
+ toString() {
75
+ return '-infinity';
76
+ }
77
+ isFutureInfinity() {
78
+ return false;
79
+ }
80
+ isPastInfinity() {
81
+ return true;
82
+ }
83
+ isInfinity() {
84
+ return true;
85
+ }
86
+ }
87
+ //# sourceMappingURL=past-infinity-date.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"past-infinity-date.js","sourceRoot":"","sources":["../lib/past-infinity-date.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAIzC,MAAM,OAAO,gBAAiB,SAAQ,QAAQ;IAC5C;QACE,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAA;IACxB,CAAC;IAED,MAAM,CAAE,SAAmB,EAAE,KAAgB;QAC3C,OAAO,SAAS,YAAY,gBAAgB,CAAA;IAC9C,CAAC;IAED,OAAO,CAAE,UAAoB,EAAE,KAAgB;QAC7C,OAAO,KAAK,CAAA;IACd,CAAC;IAED,aAAa,CAAE,UAAoB,EAAE,KAAgB;QACnD,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,CAAA;IACvC,CAAC;IAED,QAAQ,CAAE,UAAoB,EAAE,KAAgB;QAC9C,OAAO,IAAI,CAAA;IACb,CAAC;IAED,cAAc,CAAE,UAAoB,EAAE,KAAgB;QACpD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,CAAE,KAAwB;QAC/B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,KAAK,CAAE,KAAwB;QAC7B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,IAAI;QACN,OAAO,CAAC,QAAQ,CAAA;IAClB,CAAC;IAED,IAAI,KAAK;QACP,OAAO,CAAC,QAAQ,CAAA;IAClB,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,CAAC,QAAQ,CAAA;IAClB,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,CAAC,QAAQ,CAAA;IAClB,CAAC;IAED,IAAI,SAAS;QACX,OAAO,CAAC,QAAQ,CAAA;IAClB,CAAC;IAED,OAAO;QACL,OAAO,KAAK,CAAA;IACd,CAAC;IAED,UAAU;QACR,OAAO,KAAK,CAAA;IACd,CAAC;IAED,WAAW;QACT,OAAO,KAAK,CAAA;IACd,CAAC;IAEM,GAAG,CAAE,OAAe,EAAE,KAAe;QAC1C,OAAO,IAAI,CAAA;IACb,CAAC;IAEM,QAAQ,CAAE,OAAe,EAAE,KAAe;QAC/C,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,CAAE,UAAoB,EAAE,KAAmB,EAAE,QAAQ,GAAG,KAAK;QAC/D,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,MAAM,CAAE,SAAiB;QACvB,OAAO,WAAW,CAAA;IACpB,CAAC;IAED,KAAK;QACH,OAAO,IAAI,CAAA;IACb,CAAC;IAED,aAAa;QACX,OAAO;YACL,IAAI,EAAE,CAAC,QAAQ;YACf,KAAK,EAAE,CAAC,QAAQ;YAChB,GAAG,EAAE,CAAC,QAAQ;SACf,CAAA;IACH,CAAC;IAED,QAAQ;QACN,OAAO,WAAW,CAAA;IACpB,CAAC;IAED,gBAAgB;QACd,OAAO,KAAK,CAAA;IACd,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAA;IACb,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAA;IACb,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ import { Month } from './month.js';
2
+ export interface PlainDateObject {
3
+ year: number;
4
+ month: Month;
5
+ day: number;
6
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=plain-date-object.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plain-date-object.js","sourceRoot":"","sources":["../lib/plain-date-object.ts"],"names":[],"mappings":""}