@bereasoftware/time-guard 2.5.0 → 2.5.2

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,4 +1,4 @@
1
- import { Temporal } from '../../../node_modules/@js-temporal/polyfill/dist/index.cjs';
1
+ import { Temporal } from '@js-temporal/polyfill';
2
2
  type TemporalPlainDateTime = Temporal.PlainDateTime;
3
3
  type TemporalZonedDateTime = Temporal.ZonedDateTime;
4
4
  /**
@@ -1,5 +1,5 @@
1
1
  import { IDateFormatter, FormatPreset } from '../types';
2
- import { Temporal } from '../../../node_modules/@js-temporal/polyfill/dist/index.cjs';
2
+ import { Temporal } from '@js-temporal/polyfill';
3
3
  /**
4
4
  * Date Formatter implementation
5
5
  */
@@ -7,38 +7,6 @@ export declare class AdvancedFormatPlugin implements ITimeGuardPlugin {
7
7
  * Install plugin into TimeGuard
8
8
  */
9
9
  install(TimeGuardClass: typeof TimeGuard): void;
10
- /**
11
- * Get ordinal suffix (1st, 2nd, 3rd, etc.)
12
- */
13
- private getOrdinal;
14
- /**
15
- * Pad number with leading zeros
16
- */
17
- private padNumber;
18
- /**
19
- * Get ISO week number
20
- */
21
- private getISOWeek;
22
- /**
23
- * Get week of year (locale-based)
24
- */
25
- private getWeekOfYear;
26
- /**
27
- * Get ISO week year
28
- */
29
- private getISOWeekYear;
30
- /**
31
- * Get week year
32
- */
33
- private getWeekYear;
34
- /**
35
- * Get timezone offset short form
36
- */
37
- private getTimezoneOffset;
38
- /**
39
- * Get timezone offset long form
40
- */
41
- private getTimezoneOffsetLong;
42
10
  }
43
11
  /**
44
12
  * Create and export default instance
@@ -1,14 +1,12 @@
1
- import { ITimeGuard, ITimeGuardConfig, Unit, FormatPreset, IRoundOptions, IDurationOptions, IDiffResult, IDiffOptions, DurationParts, IDurationExplanation } from './types';
1
+ import { ITimeGuard, ITimeGuardConfig, Unit, FormatPreset, IRoundOptions, IDurationOptions, IDiffResult, IDiffOptions, DurationParts, IDurationExplanation, IFormattableDuration } from './types';
2
2
  /**
3
3
  * Diff result object that allows chaining with .as()
4
- * Example: tg1.diff(tg2).as('month')
5
- * Also acts as a number value for backward compatibility
6
4
  *
7
5
  * Supports two modes:
8
- * - 'exact': Returns precise time differences (e.g., 65 days)
9
- * - 'calendar': Returns calendar-aware breakdown (e.g., 2 months 5 days)
6
+ * - 'exact': Returns precise time differences
7
+ * - 'calendar': Returns calendar-aware breakdown
10
8
  */
11
- declare class DiffResult implements IDiffResult {
9
+ declare class DiffResult implements IDiffResult, IFormattableDuration {
12
10
  private _value;
13
11
  private _tg1;
14
12
  private _tg2;
@@ -16,46 +14,19 @@ declare class DiffResult implements IDiffResult {
16
14
  private _breakdownData;
17
15
  private _locale;
18
16
  constructor(value: number, tg1: TimeGuard, tg2: TimeGuard, mode?: 'calendar' | 'exact', breakdownData?: DurationParts, locale?: string);
19
- /**
20
- * Convert the diff to a different unit
21
- * Example: diff.as('month') returns the difference in months
22
- */
23
17
  as(unit: Unit): number;
24
- /**
25
- * Get breakdown in calendar mode (months, days, etc.)
26
- * Returns null for 'exact' mode
27
- */
28
18
  breakdown(): DurationParts | null;
29
- /**
30
- * Format as human-readable string
31
- * Example: "2 months and 5 days"
32
- */
33
19
  format(locale?: string): string;
34
- /**
35
- * Get the calculation mode used for this diff
36
- */
37
20
  getMode(): 'calendar' | 'exact';
38
- /**
39
- * Allow implicit numeric conversion for backward compatibility
40
- */
41
21
  valueOf(): number;
42
- /**
43
- * String representation
44
- */
45
22
  toString(): string;
46
- /**
47
- * JSON representation
48
- */
49
23
  toJSON(): number;
50
24
  }
51
25
  /**
52
26
  * DurationResult class - Represents a duration breakdown with humanize support
53
- * Example: start.until(end).humanize() → "2 months and 5 days"
54
- *
55
- * Public class available for type checking and extending
56
27
  * Returned by until(), since(), and between() methods
57
28
  */
58
- export declare class DurationResult implements DurationParts {
29
+ export declare class DurationResult implements DurationParts, IFormattableDuration {
59
30
  years: number;
60
31
  months: number;
61
32
  weeks: number;
@@ -83,78 +54,16 @@ export declare class DurationResult implements DurationParts {
83
54
  }>;
84
55
  calculationTimeMs?: number;
85
56
  });
86
- /**
87
- * Convert duration to human-readable string
88
- * Supports multiple humanization styles using Intl API
89
- * @example
90
- * duration.humanize() // "2 months" (Intl.RelativeTimeFormat style)
91
- * duration.humanize({ fullBreakdown: true, locale: 'es' }) // "2 meses y 5 días"
92
- */
93
57
  humanize(options?: {
94
58
  locale?: string;
95
59
  fullBreakdown?: boolean;
96
60
  numeric?: 'always' | 'auto';
97
61
  }): string;
98
- /**
99
- * Get total duration in specified unit (date-fns style)
100
- * Useful for business logic: payments, metrics, analytics
101
- *
102
- * Conversion factors:
103
- * - 1 year = 365.25 days (accounting for leap years)
104
- * - 1 month = 365.25/12 days = 30.4375 days
105
- * - 1 week = 7 days
106
- *
107
- * @example
108
- * duration.total('days') // 65
109
- * duration.total('months') // 2.166... (65 / 30.4375)
110
- * duration.total('hours') // 1560 (65 * 24)
111
- * duration.total('seconds') // 5616000 (65 * 24 * 60 * 60)
112
- */
113
62
  total(unit: Unit): number;
114
- /**
115
- * String representation
116
- * Returns humanized format by default, or numeric if in exact mode
117
- */
118
63
  toString(): string;
119
- /**
120
- * JSON representation
121
- * Returns the breakdown as object for serialization
122
- */
123
64
  toJSON(): Record<string, number>;
124
- /**
125
- * Explain the calculation - killer feature for debugging and education
126
- * Returns detailed breakdown of how the duration was calculated
127
- *
128
- * Perfect for:
129
- * - Debugging complex date calculations
130
- * - Educational purposes (showing date math)
131
- * - Auditing time-based business logic
132
- * - Verification of calculation methodology
133
- *
134
- * @example
135
- * start.until(end).explain()
136
- * // {
137
- * // input: ['2024-01-15', '2024-03-20'],
138
- * // steps: [
139
- * // 'Parsed dates: 2024-01-15 to 2024-03-20',
140
- * // '2024 is a leap year (366 days)',
141
- * // 'February 2024 has 29 days',
142
- * // 'Total calculated: 65 days'
143
- * // ],
144
- * // breakdown: { years: 0, months: 2, weeks: 0, days: 5, ... },
145
- * // mode: 'exact',
146
- * // explanation: 'Calculated 2024-01-15 to 2024-03-20...'
147
- * // }
148
- */
149
65
  explain(): IDurationExplanation;
150
- /**
151
- * Generate explanation steps for the calculation
152
- * Used when steps weren't provided during construction
153
- */
154
66
  private generateExplanationSteps;
155
- /**
156
- * Pluralize a unit name (deprecated - use utility function)
157
- */
158
67
  private pluralizeUnit;
159
68
  }
160
69
  /**
@@ -162,58 +71,23 @@ export declare class DurationResult implements DurationParts {
162
71
  */
163
72
  /**
164
73
  * TimeRange - Fluent API for date range operations
165
- * Semantic naming that eliminates confusion about date order
166
74
  *
167
75
  * @example
168
76
  * TimeGuard.range('2024-01-15', '2024-03-20')
169
- * .toDuration() // Returns DurationResult
170
- * .humanize() // "2 months and 5 days"
171
- *
172
- * TimeGuard.range('2024-01-15', '2024-03-20')
173
- * .inMonths() // 2.1355 (precise decimal)
174
- *
175
- * These methods work regardless of date order
77
+ * .toDuration().humanize() // "2 months and 5 days"
78
+ * .inMonths() // 2.1355 (precise decimal)
176
79
  */
177
80
  export declare class TimeRange {
178
81
  private _start;
179
82
  private _end;
180
83
  constructor(start: TimeGuard, end: TimeGuard);
181
- /**
182
- * Get the duration between the two dates
183
- * @returns DurationResult with all duration properties and methods
184
- * @example
185
- * const duration = TimeGuard.range(start, end).toDuration();
186
- * duration.humanize(); // "2 months and 5 days"
187
- * duration.total('day'); // 65.875
188
- */
189
84
  toDuration(): DurationResult;
190
- /**
191
- * Get the range expressed in months (as decimal)
192
- * Accounts for leap years and average month lengths
193
- * @returns Number of months (can be decimal like 2.1355)
194
- * @example
195
- * TimeGuard.range('2024-01-15', '2024-03-20').inMonths(); // ~2.1355
196
- */
197
85
  inMonths(): number;
198
- /**
199
- * Get human-readable representation of the range
200
- * Semantic naming that emphasizes what the range represents
201
- * @returns String like "2 months and 5 days"
202
- * @example
203
- * TimeGuard.range(start, end).humanize(); // "2 months and 5 days"
204
- * TimeGuard.range(start, end).humanize({ locale: 'es' }); // "2 meses y 5 días"
205
- */
206
86
  humanize(options?: {
207
87
  locale?: string;
208
88
  fullBreakdown?: boolean;
209
89
  numeric?: 'always' | 'auto';
210
90
  }): string;
211
- /**
212
- * Get duration in specific unit
213
- * Chainable with other TimeRange methods
214
- * @example
215
- * TimeGuard.range(start, end).in('day'); // 65.875
216
- */
217
91
  in(unit: Unit): number;
218
92
  }
219
93
  export declare class TimeGuard implements ITimeGuard {
@@ -224,48 +98,23 @@ export declare class TimeGuard implements ITimeGuard {
224
98
  private static isLeapYearValue;
225
99
  private static toDurationParts;
226
100
  constructor(input?: unknown, config?: ITimeGuardConfig);
227
- /**
228
- * Static factory methods
229
- */
230
101
  static now(config?: ITimeGuardConfig): TimeGuard;
231
102
  static from(input: unknown, config?: ITimeGuardConfig): TimeGuard;
232
103
  static fromTemporal(temporal: any, // Temporal.PlainDateTime | Temporal.ZonedDateTime
233
104
  config?: ITimeGuardConfig): TimeGuard;
234
105
  /**
235
- * Calculate duration between two dates - semantic API eliminating until/since confusion
236
- *
237
- * Always returns positive duration regardless of date order.
238
- * Use .humanize() for user-friendly output.
106
+ * Calculate duration between two dates - always returns positive duration
239
107
  *
240
108
  * @example
241
- * const start = TimeGuard.from("2024-01-15");
242
- * const end = TimeGuard.from("2024-03-20");
243
- *
244
- * TimeGuard.between(start, end).humanize();
245
- * // "2 months and 5 days"
246
- *
247
- * // Order doesn't matter - semantic clarity!
248
- * TimeGuard.between(end, start).humanize();
249
- * // "2 months and 5 days" (still positive)
250
- *
251
- * // Has all DurationParts properties
252
- * TimeGuard.between(start, end).months; // 2
253
- * TimeGuard.between(start, end).days; // 5
109
+ * TimeGuard.between(start, end).humanize() // "2 months and 5 days"
110
+ * TimeGuard.between(end, start).humanize() // "2 months and 5 days" (still positive)
254
111
  */
255
112
  static between(date1: TimeGuard, date2: TimeGuard): DurationResult;
256
113
  /**
257
114
  * Create a TimeRange for fluent duration calculations
258
- * Marketing-friendly naming that emphasizes range semantics
259
115
  *
260
116
  * @example
261
- * TimeGuard.range("2024-01-15", "2024-03-20")
262
- * .humanize() // "2 months and 5 days"
263
- *
264
- * TimeGuard.range("2024-01-15", "2024-03-20")
265
- * .inMonths() // 2.1355
266
- *
267
- * TimeGuard.range("2024-01-15", "2024-03-20")
268
- * .toDuration() // DurationResult object
117
+ * TimeGuard.range("2024-01-15", "2024-03-20").humanize() // "2 months and 5 days"
269
118
  */
270
119
  static range(start: unknown, end: unknown): TimeRange;
271
120
  toTemporal(): any;
@@ -293,14 +142,9 @@ export declare class TimeGuard implements ITimeGuard {
293
142
  *
294
143
  * @example
295
144
  * // Exact mode (default)
296
- * tg1.diff(tg2).as('day') // Get as number: 65
297
- *
298
- * // Calendar mode - shows normalized breakdown
299
- * tg1.diff(tg2, { mode: 'calendar' }).format('en')
300
- * // Output: "2 months and 5 days"
301
- *
302
- * // With custom unit
303
- * tg1.diff(tg2, { unit: 'hour' }).as('hour') // 1560
145
+ * tg1.diff(tg2).as('day') // 65
146
+ * // Calendar mode
147
+ * tg1.diff(tg2, { mode: 'calendar' }).format('en') // "2 months and 5 days"
304
148
  */
305
149
  diff(other: TimeGuard): DiffResult;
306
150
  diff(other: TimeGuard, unit: Unit): number;
@@ -101,6 +101,14 @@ export interface DurationParts {
101
101
  seconds: number;
102
102
  milliseconds: number;
103
103
  }
104
+ /**
105
+ * Base interface for formattable duration-like objects
106
+ * Common functionality shared by DiffResult and DurationResult
107
+ */
108
+ export interface IFormattableDuration {
109
+ toString(): string;
110
+ toJSON(): Record<string, number> | number;
111
+ }
104
112
  /**
105
113
  * Options for humanize() method
106
114
  */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bereasoftware/time-guard",
3
3
  "private": false,
4
- "version": "2.5.0",
4
+ "version": "2.5.2",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "main": "./dist/time-guard.cjs",
@@ -120,7 +120,6 @@
120
120
  "@js-temporal/polyfill": "^0.5.1"
121
121
  },
122
122
  "devDependencies": {
123
- "@js-temporal/polyfill": "^0.5.1",
124
123
  "@semantic-release/changelog": "^6.0.3",
125
124
  "@semantic-release/git": "^10.0.1",
126
125
  "@semantic-release/github": "^12.0.6",
@@ -1,17 +0,0 @@
1
- import { ILocale } from '../types';
2
- /**
3
- * Locale data record for all supported languages
4
- */
5
- export declare const LOCALES_DATA: Record<string, ILocale>;
6
- /**
7
- * Dynamically register all locales
8
- */
9
- export declare function registerAllLocales(localeMap: Map<string, ILocale> | Record<string, ILocale>): void;
10
- /**
11
- * Get all available locales
12
- */
13
- export declare function getAvailableLocales(): string[];
14
- /**
15
- * Total locales count
16
- */
17
- export declare const LOCALES_COUNT: number;
@@ -1,6 +0,0 @@
1
- /**
2
- * Polyfill Loader - Automatically loads Temporal API polyfill if needed
3
- * No user installation required - polyfill is included in time-guard
4
- * Compatible with both ESM and CJS environments (SSR / Nest / Nuxt / Node.js)
5
- */
6
- export {};