@bereasoftware/time-guard 2.5.4 → 2.6.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.
- package/dist/calendars/index.cjs.map +1 -1
- package/dist/calendars/index.es.js +1 -1
- package/dist/calendars/index.es.js.map +1 -1
- package/dist/locales/index.cjs +1 -2
- package/dist/locales/index.es.js +3 -2797
- package/dist/locales-DSBvgSaw.js +2798 -0
- package/dist/locales-DSBvgSaw.js.map +1 -0
- package/dist/locales-ybx7jS8G.cjs +2 -0
- package/dist/locales-ybx7jS8G.cjs.map +1 -0
- package/dist/plugins/advanced-format.cjs.map +1 -1
- package/dist/plugins/advanced-format.es.js +1 -1
- package/dist/plugins/advanced-format.es.js.map +1 -1
- package/dist/plugins/duration.cjs.map +1 -1
- package/dist/plugins/duration.es.js +1 -1
- package/dist/plugins/duration.es.js.map +1 -1
- package/dist/plugins/relative-time.cjs.map +1 -1
- package/dist/plugins/relative-time.es.js +1 -1
- package/dist/plugins/relative-time.es.js.map +1 -1
- package/dist/time-guard.cjs +2 -2
- package/dist/time-guard.cjs.map +1 -1
- package/dist/time-guard.es.js +54 -17
- package/dist/time-guard.es.js.map +1 -1
- package/dist/time-guard.iife.js +2 -2
- package/dist/time-guard.iife.js.map +1 -1
- package/dist/time-guard.umd.js +2 -2
- package/dist/time-guard.umd.js.map +1 -1
- package/dist/types/adapters/temporal.adapter.d.ts +9 -6
- package/dist/types/index.d.ts +10 -10
- package/dist/types/plugins/index.d.ts +5 -5
- package/dist/types/time-guard.d.ts +2 -0
- package/dist/types/types/index.d.ts +67 -12
- package/package.json +20 -6
- package/dist/locales/index.cjs.map +0 -1
- package/dist/locales/index.es.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"duration.cjs","names":[],"sources":["../../src/plugins/duration/index.ts"],"sourcesContent":["/**\r\n * TimeGuard Duration Plugin\r\n * Implements ISO 8601 duration support and time calculations\r\n * Follows SOLID principles and enables advanced duration operations\r\n */\r\n\r\nimport type { ITimeGuardPlugin } from '../../types';\r\nimport type { TimeGuard } from '../../index';\r\nimport type { DurationInput, DurationObject, DurationUnit, IDuration } from './types';\r\n\r\n/**\r\n * Duration class - represents time span following ISO 8601 standard\r\n */\r\nexport class Duration implements IDuration {\r\n private years: number = 0;\r\n private months: number = 0;\r\n private weeks: number = 0;\r\n private days: number = 0;\r\n private hours: number = 0;\r\n private minutes: number = 0;\r\n private seconds: number = 0;\r\n private milliseconds: number = 0;\r\n\r\n constructor(input: DurationInput) {\r\n this.years = input.years || 0;\r\n this.months = input.months || 0;\r\n this.weeks = input.weeks || 0;\r\n this.days = input.days || 0;\r\n this.hours = input.hours || 0;\r\n this.minutes = input.minutes || 0;\r\n this.seconds = input.seconds || 0;\r\n this.milliseconds = input.milliseconds || 0;\r\n }\r\n\r\n /**\r\n * Create Duration from ISO 8601 string\r\n * @example Duration.fromISO(\"P3Y6M4DT12H30M5S\")\r\n */\r\n static fromISO(iso: string): Duration {\r\n const isoRegex = /^(-)?P(?:(\\d+)Y)?(?:(\\d+)M)?(?:(\\d+)W)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:([\\d.]+)S)?)?$/;\r\n const match = iso.match(isoRegex);\r\n\r\n if (!match) {\r\n throw new Error(`Invalid ISO 8601 duration: ${iso}`);\r\n }\r\n\r\n const [, negative, years, months, , days, hours, minutes, seconds] = match;\r\n const multiplier = negative ? -1 : 1;\r\n\r\n return new Duration({\r\n years: parseInt(years || '0', 10) * multiplier,\r\n months: parseInt(months || '0', 10) * multiplier,\r\n days: parseInt(days || '0', 10) * multiplier,\r\n hours: parseInt(hours || '0', 10) * multiplier,\r\n minutes: parseInt(minutes || '0', 10) * multiplier,\r\n seconds: parseFloat(seconds || '0') * multiplier,\r\n });\r\n }\r\n\r\n /**\r\n * Create a Duration between this date and another\r\n */\r\n static between(from: TimeGuard, to: TimeGuard): Duration {\r\n // Calculate (to - from) using since() for proper duration\r\n const fromDT = (from as any).toTemporal();\r\n const toDT = (to as any).toTemporal();\r\n const duration = (toDT as any).since(fromDT);\r\n \r\n return new Duration({\r\n years: duration.years || 0,\r\n months: duration.months || 0,\r\n weeks: 0,\r\n days: duration.days || 0,\r\n hours: duration.hours || 0,\r\n minutes: duration.minutes || 0,\r\n seconds: duration.seconds || 0,\r\n milliseconds: duration.milliseconds || 0,\r\n });\r\n }\r\n\r\n /**\r\n * Create Duration from milliseconds\r\n */\r\n static fromMilliseconds(ms: number): Duration {\r\n const isNegative = ms < 0;\r\n const absMilhs = Math.abs(ms);\r\n\r\n const years = Math.floor(absMilhs / (1000 * 60 * 60 * 24 * 365));\r\n const months = Math.floor((absMilhs % (1000 * 60 * 60 * 24 * 365)) / (1000 * 60 * 60 * 24 * 30));\r\n const days = Math.floor((absMilhs % (1000 * 60 * 60 * 24 * 30)) / (1000 * 60 * 60 * 24));\r\n const hours = Math.floor((absMilhs % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));\r\n const minutes = Math.floor((absMilhs % (1000 * 60 * 60)) / (1000 * 60));\r\n const seconds = Math.floor((absMilhs % (1000 * 60)) / 1000);\r\n const milliseconds = Math.floor(absMilhs % 1000);\r\n\r\n const multiplier = isNegative ? -1 : 1;\r\n\r\n return new Duration({\r\n years: years * multiplier,\r\n months: months * multiplier,\r\n days: days * multiplier,\r\n hours: hours * multiplier,\r\n minutes: minutes * multiplier,\r\n seconds: seconds * multiplier,\r\n milliseconds: milliseconds * multiplier,\r\n });\r\n }\r\n\r\n /**\r\n * Get duration in specific unit\r\n */\r\n as(unit: DurationUnit): number {\r\n const ms = this.asMilliseconds();\r\n\r\n const conversions: Record<DurationUnit, number> = {\r\n milliseconds: 1,\r\n seconds: 1000,\r\n minutes: 1000 * 60,\r\n hours: 1000 * 60 * 60,\r\n days: 1000 * 60 * 60 * 24,\r\n weeks: 1000 * 60 * 60 * 24 * 7,\r\n months: 1000 * 60 * 60 * 24 * 30,\r\n years: 1000 * 60 * 60 * 24 * 365,\r\n };\r\n\r\n return ms / conversions[unit];\r\n }\r\n\r\n /**\r\n * Get duration as milliseconds\r\n */\r\n asMilliseconds(): number {\r\n return (\r\n this.years * 1000 * 60 * 60 * 24 * 365 +\r\n this.months * 1000 * 60 * 60 * 24 * 30 +\r\n this.weeks * 1000 * 60 * 60 * 24 * 7 +\r\n this.days * 1000 * 60 * 60 * 24 +\r\n this.hours * 1000 * 60 * 60 +\r\n this.minutes * 1000 * 60 +\r\n this.seconds * 1000 +\r\n this.milliseconds\r\n );\r\n }\r\n\r\n /**\r\n * Get duration as seconds\r\n */\r\n asSeconds(): number {\r\n return this.asMilliseconds() / 1000;\r\n }\r\n\r\n /**\r\n * Get duration as minutes\r\n */\r\n asMinutes(): number {\r\n return this.asSeconds() / 60;\r\n }\r\n\r\n /**\r\n * Get duration as hours\r\n */\r\n asHours(): number {\r\n return this.asMinutes() / 60;\r\n }\r\n\r\n /**\r\n * Get duration as days\r\n */\r\n asDays(): number {\r\n return this.asHours() / 24;\r\n }\r\n\r\n /**\r\n * Get duration as weeks\r\n */\r\n asWeeks(): number {\r\n return this.asDays() / 7;\r\n }\r\n\r\n /**\r\n * Get duration as months\r\n */\r\n asMonths(): number {\r\n return this.asDays() / 30;\r\n }\r\n\r\n /**\r\n * Get duration as years\r\n */\r\n asYears(): number {\r\n return this.asDays() / 365;\r\n }\r\n\r\n /**\r\n * Get all components\r\n */\r\n toObject(): DurationObject {\r\n return {\r\n years: this.years,\r\n months: this.months,\r\n weeks: this.weeks,\r\n days: this.days,\r\n hours: this.hours,\r\n minutes: this.minutes,\r\n seconds: this.seconds,\r\n milliseconds: this.milliseconds,\r\n };\r\n }\r\n\r\n /**\r\n * Get ISO 8601 string representation\r\n * @example \"P3Y6M4DT12H30M5S\"\r\n */\r\n toISO(): string {\r\n\r\n // Date part\r\n let datePart = '';\r\n if (this.years) datePart += `${this.years}Y`;\r\n if (this.months) datePart += `${this.months}M`;\r\n if (this.weeks || this.days) datePart += `${this.weeks * 7 + this.days}D`;\r\n\r\n // Time part\r\n let timePart = '';\r\n if (this.hours) timePart += `${this.hours}H`;\r\n if (this.minutes) timePart += `${this.minutes}M`;\r\n if (this.seconds || this.milliseconds) {\r\n timePart += `${this.seconds + this.milliseconds / 1000}S`;\r\n }\r\n\r\n const sign = this.isNegative() ? '-' : '';\r\n return `${sign}P${datePart}${timePart ? `T${timePart}` : ''}`;\r\n }\r\n\r\n /**\r\n * Get human-readable string\r\n */\r\n humanize(): string {\r\n const parts: string[] = [];\r\n\r\n if (this.years) parts.push(`${Math.abs(this.years)} year${Math.abs(this.years) !== 1 ? 's' : ''}`);\r\n if (this.months) parts.push(`${Math.abs(this.months)} month${Math.abs(this.months) !== 1 ? 's' : ''}`);\r\n if (this.weeks) parts.push(`${Math.abs(this.weeks)} week${Math.abs(this.weeks) !== 1 ? 's' : ''}`);\r\n if (this.days) parts.push(`${Math.abs(this.days)} day${Math.abs(this.days) !== 1 ? 's' : ''}`);\r\n if (this.hours) parts.push(`${Math.abs(this.hours)} hour${Math.abs(this.hours) !== 1 ? 's' : ''}`);\r\n if (this.minutes) parts.push(`${Math.abs(this.minutes)} minute${Math.abs(this.minutes) !== 1 ? 's' : ''}`);\r\n if (this.seconds) parts.push(`${Math.abs(this.seconds)} second${Math.abs(this.seconds) !== 1 ? 's' : ''}`);\r\n if (this.milliseconds) parts.push(`${Math.abs(this.milliseconds)} ms`);\r\n\r\n if (parts.length === 0) return '0 seconds';\r\n\r\n const text = parts.join(', ');\r\n return this.isNegative() ? `-${text}` : text;\r\n }\r\n\r\n /**\r\n * Check if duration is negative\r\n */\r\n isNegative(): boolean {\r\n return (\r\n this.years < 0 ||\r\n this.months < 0 ||\r\n this.weeks < 0 ||\r\n this.days < 0 ||\r\n this.hours < 0 ||\r\n this.minutes < 0 ||\r\n this.seconds < 0 ||\r\n this.milliseconds < 0\r\n );\r\n }\r\n\r\n /**\r\n * Get absolute duration\r\n */\r\n abs(): Duration {\r\n return new Duration({\r\n years: Math.abs(this.years),\r\n months: Math.abs(this.months),\r\n weeks: Math.abs(this.weeks),\r\n days: Math.abs(this.days),\r\n hours: Math.abs(this.hours),\r\n minutes: Math.abs(this.minutes),\r\n seconds: Math.abs(this.seconds),\r\n milliseconds: Math.abs(this.milliseconds),\r\n });\r\n }\r\n\r\n /**\r\n * String representation\r\n */\r\n toString(): string {\r\n return this.toISO();\r\n }\r\n}\r\n\r\n/**\r\n * Duration Plugin\r\n */\r\nexport class DurationPlugin implements ITimeGuardPlugin {\r\n name = 'duration';\r\n version = '1.0.0';\r\n\r\n /**\r\n * Install plugin into TimeGuard\r\n */\r\n install(TimeGuardClass: typeof TimeGuard): void {\r\n /**\r\n * Create a Duration between this date and another\r\n */\r\n (TimeGuardClass.prototype as any).duration = function (other: TimeGuard): Duration {\r\n return Duration.between(this, other);\r\n };\r\n\r\n /**\r\n * Get Duration class for creating custom durations\r\n */\r\n (TimeGuardClass as any).Duration = Duration;\r\n\r\n /**\r\n * Create Duration from ISO 8601 string\r\n */\r\n (TimeGuardClass as any).duration = {\r\n fromISO: (iso: string): Duration => Duration.fromISO(iso),\r\n between: (from: TimeGuard, to: TimeGuard): Duration => Duration.between(from, to),\r\n fromMilliseconds: (ms: number): Duration => Duration.fromMilliseconds(ms),\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Create and export default instance\r\n */\r\nexport const durationPlugin = new DurationPlugin();\r\n\r\nexport default durationPlugin;\r\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"duration.cjs","names":[],"sources":["../../src/plugins/duration/index.ts"],"sourcesContent":["/**\n * TimeGuard Duration Plugin\n * Implements ISO 8601 duration support and time calculations\n * Follows SOLID principles and enables advanced duration operations\n */\n\nimport type { ITimeGuardPlugin } from '../../types';\nimport type { TimeGuard } from '../../index';\nimport type {\n DurationInput,\n DurationObject,\n DurationUnit,\n IDuration,\n} from './types';\n\n/**\n * Duration class - represents time span following ISO 8601 standard\n */\nexport class Duration implements IDuration {\n private years: number = 0;\n private months: number = 0;\n private weeks: number = 0;\n private days: number = 0;\n private hours: number = 0;\n private minutes: number = 0;\n private seconds: number = 0;\n private milliseconds: number = 0;\n\n constructor(input: DurationInput) {\n this.years = input.years || 0;\n this.months = input.months || 0;\n this.weeks = input.weeks || 0;\n this.days = input.days || 0;\n this.hours = input.hours || 0;\n this.minutes = input.minutes || 0;\n this.seconds = input.seconds || 0;\n this.milliseconds = input.milliseconds || 0;\n }\n\n /**\n * Create Duration from ISO 8601 string\n * @example Duration.fromISO(\"P3Y6M4DT12H30M5S\")\n */\n static fromISO(iso: string): Duration {\n const isoRegex =\n /^(-)?P(?:(\\d+)Y)?(?:(\\d+)M)?(?:(\\d+)W)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:([\\d.]+)S)?)?$/;\n const match = iso.match(isoRegex);\n\n if (!match) {\n throw new Error(`Invalid ISO 8601 duration: ${iso}`);\n }\n\n const [, negative, years, months, , days, hours, minutes, seconds] = match;\n const multiplier = negative ? -1 : 1;\n\n return new Duration({\n years: parseInt(years || '0', 10) * multiplier,\n months: parseInt(months || '0', 10) * multiplier,\n days: parseInt(days || '0', 10) * multiplier,\n hours: parseInt(hours || '0', 10) * multiplier,\n minutes: parseInt(minutes || '0', 10) * multiplier,\n seconds: parseFloat(seconds || '0') * multiplier,\n });\n }\n\n /**\n * Create a Duration between this date and another\n */\n static between(from: TimeGuard, to: TimeGuard): Duration {\n // Calculate (to - from) using since() for proper duration\n const fromDT = (\n from as unknown as { toTemporal(): Temporal.PlainDateTime }\n ).toTemporal();\n const toDT = (\n to as unknown as { toTemporal(): Temporal.PlainDateTime }\n ).toTemporal();\n const duration = (\n toDT as unknown as {\n since(other: Temporal.PlainDateTime): {\n years?: number;\n months?: number;\n days?: number;\n hours?: number;\n minutes?: number;\n seconds?: number;\n milliseconds?: number;\n };\n }\n ).since(fromDT);\n\n return new Duration({\n years: duration.years || 0,\n months: duration.months || 0,\n weeks: 0,\n days: duration.days || 0,\n hours: duration.hours || 0,\n minutes: duration.minutes || 0,\n seconds: duration.seconds || 0,\n milliseconds: duration.milliseconds || 0,\n });\n }\n\n /**\n * Create Duration from milliseconds\n */\n static fromMilliseconds(ms: number): Duration {\n const isNegative = ms < 0;\n const absMilhs = Math.abs(ms);\n\n const years = Math.floor(absMilhs / (1000 * 60 * 60 * 24 * 365));\n const months = Math.floor(\n (absMilhs % (1000 * 60 * 60 * 24 * 365)) / (1000 * 60 * 60 * 24 * 30),\n );\n const days = Math.floor(\n (absMilhs % (1000 * 60 * 60 * 24 * 30)) / (1000 * 60 * 60 * 24),\n );\n const hours = Math.floor(\n (absMilhs % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60),\n );\n const minutes = Math.floor((absMilhs % (1000 * 60 * 60)) / (1000 * 60));\n const seconds = Math.floor((absMilhs % (1000 * 60)) / 1000);\n const milliseconds = Math.floor(absMilhs % 1000);\n\n const multiplier = isNegative ? -1 : 1;\n\n return new Duration({\n years: years * multiplier,\n months: months * multiplier,\n days: days * multiplier,\n hours: hours * multiplier,\n minutes: minutes * multiplier,\n seconds: seconds * multiplier,\n milliseconds: milliseconds * multiplier,\n });\n }\n\n /**\n * Get duration in specific unit\n */\n as(unit: DurationUnit): number {\n const ms = this.asMilliseconds();\n\n const conversions: Record<DurationUnit, number> = {\n milliseconds: 1,\n seconds: 1000,\n minutes: 1000 * 60,\n hours: 1000 * 60 * 60,\n days: 1000 * 60 * 60 * 24,\n weeks: 1000 * 60 * 60 * 24 * 7,\n months: 1000 * 60 * 60 * 24 * 30,\n years: 1000 * 60 * 60 * 24 * 365,\n };\n\n return ms / conversions[unit];\n }\n\n /**\n * Get duration as milliseconds\n */\n asMilliseconds(): number {\n return (\n this.years * 1000 * 60 * 60 * 24 * 365 +\n this.months * 1000 * 60 * 60 * 24 * 30 +\n this.weeks * 1000 * 60 * 60 * 24 * 7 +\n this.days * 1000 * 60 * 60 * 24 +\n this.hours * 1000 * 60 * 60 +\n this.minutes * 1000 * 60 +\n this.seconds * 1000 +\n this.milliseconds\n );\n }\n\n /**\n * Get duration as seconds\n */\n asSeconds(): number {\n return this.asMilliseconds() / 1000;\n }\n\n /**\n * Get duration as minutes\n */\n asMinutes(): number {\n return this.asSeconds() / 60;\n }\n\n /**\n * Get duration as hours\n */\n asHours(): number {\n return this.asMinutes() / 60;\n }\n\n /**\n * Get duration as days\n */\n asDays(): number {\n return this.asHours() / 24;\n }\n\n /**\n * Get duration as weeks\n */\n asWeeks(): number {\n return this.asDays() / 7;\n }\n\n /**\n * Get duration as months\n */\n asMonths(): number {\n return this.asDays() / 30;\n }\n\n /**\n * Get duration as years\n */\n asYears(): number {\n return this.asDays() / 365;\n }\n\n /**\n * Get all components\n */\n toObject(): DurationObject {\n return {\n years: this.years,\n months: this.months,\n weeks: this.weeks,\n days: this.days,\n hours: this.hours,\n minutes: this.minutes,\n seconds: this.seconds,\n milliseconds: this.milliseconds,\n };\n }\n\n /**\n * Get ISO 8601 string representation\n * @example \"P3Y6M4DT12H30M5S\"\n */\n toISO(): string {\n // Date part\n let datePart = '';\n if (this.years) {\n datePart += `${this.years}Y`;\n }\n if (this.months) {\n datePart += `${this.months}M`;\n }\n if (this.weeks || this.days) {\n datePart += `${this.weeks * 7 + this.days}D`;\n }\n\n // Time part\n let timePart = '';\n if (this.hours) {\n timePart += `${this.hours}H`;\n }\n if (this.minutes) {\n timePart += `${this.minutes}M`;\n }\n if (this.seconds || this.milliseconds) {\n timePart += `${this.seconds + this.milliseconds / 1000}S`;\n }\n\n const sign = this.isNegative() ? '-' : '';\n return `${sign}P${datePart}${timePart ? `T${timePart}` : ''}`;\n }\n\n /**\n * Get human-readable string\n */\n humanize(): string {\n const parts: string[] = [];\n\n if (this.years) {\n parts.push(\n `${Math.abs(this.years)} year${Math.abs(this.years) !== 1 ? 's' : ''}`,\n );\n }\n if (this.months) {\n parts.push(\n `${Math.abs(this.months)} month${Math.abs(this.months) !== 1 ? 's' : ''}`,\n );\n }\n if (this.weeks) {\n parts.push(\n `${Math.abs(this.weeks)} week${Math.abs(this.weeks) !== 1 ? 's' : ''}`,\n );\n }\n if (this.days) {\n parts.push(\n `${Math.abs(this.days)} day${Math.abs(this.days) !== 1 ? 's' : ''}`,\n );\n }\n if (this.hours) {\n parts.push(\n `${Math.abs(this.hours)} hour${Math.abs(this.hours) !== 1 ? 's' : ''}`,\n );\n }\n if (this.minutes) {\n parts.push(\n `${Math.abs(this.minutes)} minute${Math.abs(this.minutes) !== 1 ? 's' : ''}`,\n );\n }\n if (this.seconds) {\n parts.push(\n `${Math.abs(this.seconds)} second${Math.abs(this.seconds) !== 1 ? 's' : ''}`,\n );\n }\n if (this.milliseconds) {\n parts.push(`${Math.abs(this.milliseconds)} ms`);\n }\n\n if (parts.length === 0) {\n return '0 seconds';\n }\n\n const text = parts.join(', ');\n return this.isNegative() ? `-${text}` : text;\n }\n\n /**\n * Check if duration is negative\n */\n isNegative(): boolean {\n return (\n this.years < 0 ||\n this.months < 0 ||\n this.weeks < 0 ||\n this.days < 0 ||\n this.hours < 0 ||\n this.minutes < 0 ||\n this.seconds < 0 ||\n this.milliseconds < 0\n );\n }\n\n /**\n * Get absolute duration\n */\n abs(): Duration {\n return new Duration({\n years: Math.abs(this.years),\n months: Math.abs(this.months),\n weeks: Math.abs(this.weeks),\n days: Math.abs(this.days),\n hours: Math.abs(this.hours),\n minutes: Math.abs(this.minutes),\n seconds: Math.abs(this.seconds),\n milliseconds: Math.abs(this.milliseconds),\n });\n }\n\n /**\n * String representation\n */\n toString(): string {\n return this.toISO();\n }\n}\n\n/**\n * Duration Plugin\n */\nexport class DurationPlugin implements ITimeGuardPlugin {\n name = 'duration';\n version = '1.0.0';\n\n /**\n * Install plugin into TimeGuard\n */\n install(TimeGuardClass: typeof TimeGuard): void {\n /**\n * Create a Duration between this date and another\n */\n (\n TimeGuardClass.prototype as unknown as {\n duration: (other: TimeGuard) => Duration;\n }\n ).duration = function (other: TimeGuard): Duration {\n return Duration.between(this as unknown as TimeGuard, other);\n };\n\n (\n TimeGuardClass as unknown as {\n Duration: typeof Duration;\n duration: {\n fromISO: (iso: string) => Duration;\n between: (from: TimeGuard, to: TimeGuard) => Duration;\n fromMilliseconds: (ms: number) => Duration;\n };\n }\n ).Duration = Duration;\n\n (\n TimeGuardClass as unknown as {\n Duration: typeof Duration;\n duration: {\n fromISO: (iso: string) => Duration;\n between: (from: TimeGuard, to: TimeGuard) => Duration;\n fromMilliseconds: (ms: number) => Duration;\n };\n }\n ).duration = {\n fromISO: (iso: string): Duration => Duration.fromISO(iso),\n between: (from: TimeGuard, to: TimeGuard): Duration =>\n Duration.between(from, to),\n fromMilliseconds: (ms: number): Duration => Duration.fromMilliseconds(ms),\n };\n }\n}\n\n/**\n * Create and export default instance\n */\nexport const durationPlugin = new DurationPlugin();\n\nexport default durationPlugin;\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! time-guard v2.
|
|
1
|
+
/*! time-guard v2.6.1 | (c) 2026 Berea-Soft | MIT License | https://github.com/Berea-Soft/time-guard */
|
|
2
2
|
//#region src/plugins/duration/index.ts
|
|
3
3
|
var e = class e {
|
|
4
4
|
years = 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"duration.es.js","names":[],"sources":["../../src/plugins/duration/index.ts"],"sourcesContent":["/**\r\n * TimeGuard Duration Plugin\r\n * Implements ISO 8601 duration support and time calculations\r\n * Follows SOLID principles and enables advanced duration operations\r\n */\r\n\r\nimport type { ITimeGuardPlugin } from '../../types';\r\nimport type { TimeGuard } from '../../index';\r\nimport type { DurationInput, DurationObject, DurationUnit, IDuration } from './types';\r\n\r\n/**\r\n * Duration class - represents time span following ISO 8601 standard\r\n */\r\nexport class Duration implements IDuration {\r\n private years: number = 0;\r\n private months: number = 0;\r\n private weeks: number = 0;\r\n private days: number = 0;\r\n private hours: number = 0;\r\n private minutes: number = 0;\r\n private seconds: number = 0;\r\n private milliseconds: number = 0;\r\n\r\n constructor(input: DurationInput) {\r\n this.years = input.years || 0;\r\n this.months = input.months || 0;\r\n this.weeks = input.weeks || 0;\r\n this.days = input.days || 0;\r\n this.hours = input.hours || 0;\r\n this.minutes = input.minutes || 0;\r\n this.seconds = input.seconds || 0;\r\n this.milliseconds = input.milliseconds || 0;\r\n }\r\n\r\n /**\r\n * Create Duration from ISO 8601 string\r\n * @example Duration.fromISO(\"P3Y6M4DT12H30M5S\")\r\n */\r\n static fromISO(iso: string): Duration {\r\n const isoRegex = /^(-)?P(?:(\\d+)Y)?(?:(\\d+)M)?(?:(\\d+)W)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:([\\d.]+)S)?)?$/;\r\n const match = iso.match(isoRegex);\r\n\r\n if (!match) {\r\n throw new Error(`Invalid ISO 8601 duration: ${iso}`);\r\n }\r\n\r\n const [, negative, years, months, , days, hours, minutes, seconds] = match;\r\n const multiplier = negative ? -1 : 1;\r\n\r\n return new Duration({\r\n years: parseInt(years || '0', 10) * multiplier,\r\n months: parseInt(months || '0', 10) * multiplier,\r\n days: parseInt(days || '0', 10) * multiplier,\r\n hours: parseInt(hours || '0', 10) * multiplier,\r\n minutes: parseInt(minutes || '0', 10) * multiplier,\r\n seconds: parseFloat(seconds || '0') * multiplier,\r\n });\r\n }\r\n\r\n /**\r\n * Create a Duration between this date and another\r\n */\r\n static between(from: TimeGuard, to: TimeGuard): Duration {\r\n // Calculate (to - from) using since() for proper duration\r\n const fromDT = (from as any).toTemporal();\r\n const toDT = (to as any).toTemporal();\r\n const duration = (toDT as any).since(fromDT);\r\n \r\n return new Duration({\r\n years: duration.years || 0,\r\n months: duration.months || 0,\r\n weeks: 0,\r\n days: duration.days || 0,\r\n hours: duration.hours || 0,\r\n minutes: duration.minutes || 0,\r\n seconds: duration.seconds || 0,\r\n milliseconds: duration.milliseconds || 0,\r\n });\r\n }\r\n\r\n /**\r\n * Create Duration from milliseconds\r\n */\r\n static fromMilliseconds(ms: number): Duration {\r\n const isNegative = ms < 0;\r\n const absMilhs = Math.abs(ms);\r\n\r\n const years = Math.floor(absMilhs / (1000 * 60 * 60 * 24 * 365));\r\n const months = Math.floor((absMilhs % (1000 * 60 * 60 * 24 * 365)) / (1000 * 60 * 60 * 24 * 30));\r\n const days = Math.floor((absMilhs % (1000 * 60 * 60 * 24 * 30)) / (1000 * 60 * 60 * 24));\r\n const hours = Math.floor((absMilhs % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));\r\n const minutes = Math.floor((absMilhs % (1000 * 60 * 60)) / (1000 * 60));\r\n const seconds = Math.floor((absMilhs % (1000 * 60)) / 1000);\r\n const milliseconds = Math.floor(absMilhs % 1000);\r\n\r\n const multiplier = isNegative ? -1 : 1;\r\n\r\n return new Duration({\r\n years: years * multiplier,\r\n months: months * multiplier,\r\n days: days * multiplier,\r\n hours: hours * multiplier,\r\n minutes: minutes * multiplier,\r\n seconds: seconds * multiplier,\r\n milliseconds: milliseconds * multiplier,\r\n });\r\n }\r\n\r\n /**\r\n * Get duration in specific unit\r\n */\r\n as(unit: DurationUnit): number {\r\n const ms = this.asMilliseconds();\r\n\r\n const conversions: Record<DurationUnit, number> = {\r\n milliseconds: 1,\r\n seconds: 1000,\r\n minutes: 1000 * 60,\r\n hours: 1000 * 60 * 60,\r\n days: 1000 * 60 * 60 * 24,\r\n weeks: 1000 * 60 * 60 * 24 * 7,\r\n months: 1000 * 60 * 60 * 24 * 30,\r\n years: 1000 * 60 * 60 * 24 * 365,\r\n };\r\n\r\n return ms / conversions[unit];\r\n }\r\n\r\n /**\r\n * Get duration as milliseconds\r\n */\r\n asMilliseconds(): number {\r\n return (\r\n this.years * 1000 * 60 * 60 * 24 * 365 +\r\n this.months * 1000 * 60 * 60 * 24 * 30 +\r\n this.weeks * 1000 * 60 * 60 * 24 * 7 +\r\n this.days * 1000 * 60 * 60 * 24 +\r\n this.hours * 1000 * 60 * 60 +\r\n this.minutes * 1000 * 60 +\r\n this.seconds * 1000 +\r\n this.milliseconds\r\n );\r\n }\r\n\r\n /**\r\n * Get duration as seconds\r\n */\r\n asSeconds(): number {\r\n return this.asMilliseconds() / 1000;\r\n }\r\n\r\n /**\r\n * Get duration as minutes\r\n */\r\n asMinutes(): number {\r\n return this.asSeconds() / 60;\r\n }\r\n\r\n /**\r\n * Get duration as hours\r\n */\r\n asHours(): number {\r\n return this.asMinutes() / 60;\r\n }\r\n\r\n /**\r\n * Get duration as days\r\n */\r\n asDays(): number {\r\n return this.asHours() / 24;\r\n }\r\n\r\n /**\r\n * Get duration as weeks\r\n */\r\n asWeeks(): number {\r\n return this.asDays() / 7;\r\n }\r\n\r\n /**\r\n * Get duration as months\r\n */\r\n asMonths(): number {\r\n return this.asDays() / 30;\r\n }\r\n\r\n /**\r\n * Get duration as years\r\n */\r\n asYears(): number {\r\n return this.asDays() / 365;\r\n }\r\n\r\n /**\r\n * Get all components\r\n */\r\n toObject(): DurationObject {\r\n return {\r\n years: this.years,\r\n months: this.months,\r\n weeks: this.weeks,\r\n days: this.days,\r\n hours: this.hours,\r\n minutes: this.minutes,\r\n seconds: this.seconds,\r\n milliseconds: this.milliseconds,\r\n };\r\n }\r\n\r\n /**\r\n * Get ISO 8601 string representation\r\n * @example \"P3Y6M4DT12H30M5S\"\r\n */\r\n toISO(): string {\r\n\r\n // Date part\r\n let datePart = '';\r\n if (this.years) datePart += `${this.years}Y`;\r\n if (this.months) datePart += `${this.months}M`;\r\n if (this.weeks || this.days) datePart += `${this.weeks * 7 + this.days}D`;\r\n\r\n // Time part\r\n let timePart = '';\r\n if (this.hours) timePart += `${this.hours}H`;\r\n if (this.minutes) timePart += `${this.minutes}M`;\r\n if (this.seconds || this.milliseconds) {\r\n timePart += `${this.seconds + this.milliseconds / 1000}S`;\r\n }\r\n\r\n const sign = this.isNegative() ? '-' : '';\r\n return `${sign}P${datePart}${timePart ? `T${timePart}` : ''}`;\r\n }\r\n\r\n /**\r\n * Get human-readable string\r\n */\r\n humanize(): string {\r\n const parts: string[] = [];\r\n\r\n if (this.years) parts.push(`${Math.abs(this.years)} year${Math.abs(this.years) !== 1 ? 's' : ''}`);\r\n if (this.months) parts.push(`${Math.abs(this.months)} month${Math.abs(this.months) !== 1 ? 's' : ''}`);\r\n if (this.weeks) parts.push(`${Math.abs(this.weeks)} week${Math.abs(this.weeks) !== 1 ? 's' : ''}`);\r\n if (this.days) parts.push(`${Math.abs(this.days)} day${Math.abs(this.days) !== 1 ? 's' : ''}`);\r\n if (this.hours) parts.push(`${Math.abs(this.hours)} hour${Math.abs(this.hours) !== 1 ? 's' : ''}`);\r\n if (this.minutes) parts.push(`${Math.abs(this.minutes)} minute${Math.abs(this.minutes) !== 1 ? 's' : ''}`);\r\n if (this.seconds) parts.push(`${Math.abs(this.seconds)} second${Math.abs(this.seconds) !== 1 ? 's' : ''}`);\r\n if (this.milliseconds) parts.push(`${Math.abs(this.milliseconds)} ms`);\r\n\r\n if (parts.length === 0) return '0 seconds';\r\n\r\n const text = parts.join(', ');\r\n return this.isNegative() ? `-${text}` : text;\r\n }\r\n\r\n /**\r\n * Check if duration is negative\r\n */\r\n isNegative(): boolean {\r\n return (\r\n this.years < 0 ||\r\n this.months < 0 ||\r\n this.weeks < 0 ||\r\n this.days < 0 ||\r\n this.hours < 0 ||\r\n this.minutes < 0 ||\r\n this.seconds < 0 ||\r\n this.milliseconds < 0\r\n );\r\n }\r\n\r\n /**\r\n * Get absolute duration\r\n */\r\n abs(): Duration {\r\n return new Duration({\r\n years: Math.abs(this.years),\r\n months: Math.abs(this.months),\r\n weeks: Math.abs(this.weeks),\r\n days: Math.abs(this.days),\r\n hours: Math.abs(this.hours),\r\n minutes: Math.abs(this.minutes),\r\n seconds: Math.abs(this.seconds),\r\n milliseconds: Math.abs(this.milliseconds),\r\n });\r\n }\r\n\r\n /**\r\n * String representation\r\n */\r\n toString(): string {\r\n return this.toISO();\r\n }\r\n}\r\n\r\n/**\r\n * Duration Plugin\r\n */\r\nexport class DurationPlugin implements ITimeGuardPlugin {\r\n name = 'duration';\r\n version = '1.0.0';\r\n\r\n /**\r\n * Install plugin into TimeGuard\r\n */\r\n install(TimeGuardClass: typeof TimeGuard): void {\r\n /**\r\n * Create a Duration between this date and another\r\n */\r\n (TimeGuardClass.prototype as any).duration = function (other: TimeGuard): Duration {\r\n return Duration.between(this, other);\r\n };\r\n\r\n /**\r\n * Get Duration class for creating custom durations\r\n */\r\n (TimeGuardClass as any).Duration = Duration;\r\n\r\n /**\r\n * Create Duration from ISO 8601 string\r\n */\r\n (TimeGuardClass as any).duration = {\r\n fromISO: (iso: string): Duration => Duration.fromISO(iso),\r\n between: (from: TimeGuard, to: TimeGuard): Duration => Duration.between(from, to),\r\n fromMilliseconds: (ms: number): Duration => Duration.fromMilliseconds(ms),\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Create and export default instance\r\n */\r\nexport const durationPlugin = new DurationPlugin();\r\n\r\nexport default durationPlugin;\r\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"duration.es.js","names":[],"sources":["../../src/plugins/duration/index.ts"],"sourcesContent":["/**\n * TimeGuard Duration Plugin\n * Implements ISO 8601 duration support and time calculations\n * Follows SOLID principles and enables advanced duration operations\n */\n\nimport type { ITimeGuardPlugin } from '../../types';\nimport type { TimeGuard } from '../../index';\nimport type {\n DurationInput,\n DurationObject,\n DurationUnit,\n IDuration,\n} from './types';\n\n/**\n * Duration class - represents time span following ISO 8601 standard\n */\nexport class Duration implements IDuration {\n private years: number = 0;\n private months: number = 0;\n private weeks: number = 0;\n private days: number = 0;\n private hours: number = 0;\n private minutes: number = 0;\n private seconds: number = 0;\n private milliseconds: number = 0;\n\n constructor(input: DurationInput) {\n this.years = input.years || 0;\n this.months = input.months || 0;\n this.weeks = input.weeks || 0;\n this.days = input.days || 0;\n this.hours = input.hours || 0;\n this.minutes = input.minutes || 0;\n this.seconds = input.seconds || 0;\n this.milliseconds = input.milliseconds || 0;\n }\n\n /**\n * Create Duration from ISO 8601 string\n * @example Duration.fromISO(\"P3Y6M4DT12H30M5S\")\n */\n static fromISO(iso: string): Duration {\n const isoRegex =\n /^(-)?P(?:(\\d+)Y)?(?:(\\d+)M)?(?:(\\d+)W)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:([\\d.]+)S)?)?$/;\n const match = iso.match(isoRegex);\n\n if (!match) {\n throw new Error(`Invalid ISO 8601 duration: ${iso}`);\n }\n\n const [, negative, years, months, , days, hours, minutes, seconds] = match;\n const multiplier = negative ? -1 : 1;\n\n return new Duration({\n years: parseInt(years || '0', 10) * multiplier,\n months: parseInt(months || '0', 10) * multiplier,\n days: parseInt(days || '0', 10) * multiplier,\n hours: parseInt(hours || '0', 10) * multiplier,\n minutes: parseInt(minutes || '0', 10) * multiplier,\n seconds: parseFloat(seconds || '0') * multiplier,\n });\n }\n\n /**\n * Create a Duration between this date and another\n */\n static between(from: TimeGuard, to: TimeGuard): Duration {\n // Calculate (to - from) using since() for proper duration\n const fromDT = (\n from as unknown as { toTemporal(): Temporal.PlainDateTime }\n ).toTemporal();\n const toDT = (\n to as unknown as { toTemporal(): Temporal.PlainDateTime }\n ).toTemporal();\n const duration = (\n toDT as unknown as {\n since(other: Temporal.PlainDateTime): {\n years?: number;\n months?: number;\n days?: number;\n hours?: number;\n minutes?: number;\n seconds?: number;\n milliseconds?: number;\n };\n }\n ).since(fromDT);\n\n return new Duration({\n years: duration.years || 0,\n months: duration.months || 0,\n weeks: 0,\n days: duration.days || 0,\n hours: duration.hours || 0,\n minutes: duration.minutes || 0,\n seconds: duration.seconds || 0,\n milliseconds: duration.milliseconds || 0,\n });\n }\n\n /**\n * Create Duration from milliseconds\n */\n static fromMilliseconds(ms: number): Duration {\n const isNegative = ms < 0;\n const absMilhs = Math.abs(ms);\n\n const years = Math.floor(absMilhs / (1000 * 60 * 60 * 24 * 365));\n const months = Math.floor(\n (absMilhs % (1000 * 60 * 60 * 24 * 365)) / (1000 * 60 * 60 * 24 * 30),\n );\n const days = Math.floor(\n (absMilhs % (1000 * 60 * 60 * 24 * 30)) / (1000 * 60 * 60 * 24),\n );\n const hours = Math.floor(\n (absMilhs % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60),\n );\n const minutes = Math.floor((absMilhs % (1000 * 60 * 60)) / (1000 * 60));\n const seconds = Math.floor((absMilhs % (1000 * 60)) / 1000);\n const milliseconds = Math.floor(absMilhs % 1000);\n\n const multiplier = isNegative ? -1 : 1;\n\n return new Duration({\n years: years * multiplier,\n months: months * multiplier,\n days: days * multiplier,\n hours: hours * multiplier,\n minutes: minutes * multiplier,\n seconds: seconds * multiplier,\n milliseconds: milliseconds * multiplier,\n });\n }\n\n /**\n * Get duration in specific unit\n */\n as(unit: DurationUnit): number {\n const ms = this.asMilliseconds();\n\n const conversions: Record<DurationUnit, number> = {\n milliseconds: 1,\n seconds: 1000,\n minutes: 1000 * 60,\n hours: 1000 * 60 * 60,\n days: 1000 * 60 * 60 * 24,\n weeks: 1000 * 60 * 60 * 24 * 7,\n months: 1000 * 60 * 60 * 24 * 30,\n years: 1000 * 60 * 60 * 24 * 365,\n };\n\n return ms / conversions[unit];\n }\n\n /**\n * Get duration as milliseconds\n */\n asMilliseconds(): number {\n return (\n this.years * 1000 * 60 * 60 * 24 * 365 +\n this.months * 1000 * 60 * 60 * 24 * 30 +\n this.weeks * 1000 * 60 * 60 * 24 * 7 +\n this.days * 1000 * 60 * 60 * 24 +\n this.hours * 1000 * 60 * 60 +\n this.minutes * 1000 * 60 +\n this.seconds * 1000 +\n this.milliseconds\n );\n }\n\n /**\n * Get duration as seconds\n */\n asSeconds(): number {\n return this.asMilliseconds() / 1000;\n }\n\n /**\n * Get duration as minutes\n */\n asMinutes(): number {\n return this.asSeconds() / 60;\n }\n\n /**\n * Get duration as hours\n */\n asHours(): number {\n return this.asMinutes() / 60;\n }\n\n /**\n * Get duration as days\n */\n asDays(): number {\n return this.asHours() / 24;\n }\n\n /**\n * Get duration as weeks\n */\n asWeeks(): number {\n return this.asDays() / 7;\n }\n\n /**\n * Get duration as months\n */\n asMonths(): number {\n return this.asDays() / 30;\n }\n\n /**\n * Get duration as years\n */\n asYears(): number {\n return this.asDays() / 365;\n }\n\n /**\n * Get all components\n */\n toObject(): DurationObject {\n return {\n years: this.years,\n months: this.months,\n weeks: this.weeks,\n days: this.days,\n hours: this.hours,\n minutes: this.minutes,\n seconds: this.seconds,\n milliseconds: this.milliseconds,\n };\n }\n\n /**\n * Get ISO 8601 string representation\n * @example \"P3Y6M4DT12H30M5S\"\n */\n toISO(): string {\n // Date part\n let datePart = '';\n if (this.years) {\n datePart += `${this.years}Y`;\n }\n if (this.months) {\n datePart += `${this.months}M`;\n }\n if (this.weeks || this.days) {\n datePart += `${this.weeks * 7 + this.days}D`;\n }\n\n // Time part\n let timePart = '';\n if (this.hours) {\n timePart += `${this.hours}H`;\n }\n if (this.minutes) {\n timePart += `${this.minutes}M`;\n }\n if (this.seconds || this.milliseconds) {\n timePart += `${this.seconds + this.milliseconds / 1000}S`;\n }\n\n const sign = this.isNegative() ? '-' : '';\n return `${sign}P${datePart}${timePart ? `T${timePart}` : ''}`;\n }\n\n /**\n * Get human-readable string\n */\n humanize(): string {\n const parts: string[] = [];\n\n if (this.years) {\n parts.push(\n `${Math.abs(this.years)} year${Math.abs(this.years) !== 1 ? 's' : ''}`,\n );\n }\n if (this.months) {\n parts.push(\n `${Math.abs(this.months)} month${Math.abs(this.months) !== 1 ? 's' : ''}`,\n );\n }\n if (this.weeks) {\n parts.push(\n `${Math.abs(this.weeks)} week${Math.abs(this.weeks) !== 1 ? 's' : ''}`,\n );\n }\n if (this.days) {\n parts.push(\n `${Math.abs(this.days)} day${Math.abs(this.days) !== 1 ? 's' : ''}`,\n );\n }\n if (this.hours) {\n parts.push(\n `${Math.abs(this.hours)} hour${Math.abs(this.hours) !== 1 ? 's' : ''}`,\n );\n }\n if (this.minutes) {\n parts.push(\n `${Math.abs(this.minutes)} minute${Math.abs(this.minutes) !== 1 ? 's' : ''}`,\n );\n }\n if (this.seconds) {\n parts.push(\n `${Math.abs(this.seconds)} second${Math.abs(this.seconds) !== 1 ? 's' : ''}`,\n );\n }\n if (this.milliseconds) {\n parts.push(`${Math.abs(this.milliseconds)} ms`);\n }\n\n if (parts.length === 0) {\n return '0 seconds';\n }\n\n const text = parts.join(', ');\n return this.isNegative() ? `-${text}` : text;\n }\n\n /**\n * Check if duration is negative\n */\n isNegative(): boolean {\n return (\n this.years < 0 ||\n this.months < 0 ||\n this.weeks < 0 ||\n this.days < 0 ||\n this.hours < 0 ||\n this.minutes < 0 ||\n this.seconds < 0 ||\n this.milliseconds < 0\n );\n }\n\n /**\n * Get absolute duration\n */\n abs(): Duration {\n return new Duration({\n years: Math.abs(this.years),\n months: Math.abs(this.months),\n weeks: Math.abs(this.weeks),\n days: Math.abs(this.days),\n hours: Math.abs(this.hours),\n minutes: Math.abs(this.minutes),\n seconds: Math.abs(this.seconds),\n milliseconds: Math.abs(this.milliseconds),\n });\n }\n\n /**\n * String representation\n */\n toString(): string {\n return this.toISO();\n }\n}\n\n/**\n * Duration Plugin\n */\nexport class DurationPlugin implements ITimeGuardPlugin {\n name = 'duration';\n version = '1.0.0';\n\n /**\n * Install plugin into TimeGuard\n */\n install(TimeGuardClass: typeof TimeGuard): void {\n /**\n * Create a Duration between this date and another\n */\n (\n TimeGuardClass.prototype as unknown as {\n duration: (other: TimeGuard) => Duration;\n }\n ).duration = function (other: TimeGuard): Duration {\n return Duration.between(this as unknown as TimeGuard, other);\n };\n\n (\n TimeGuardClass as unknown as {\n Duration: typeof Duration;\n duration: {\n fromISO: (iso: string) => Duration;\n between: (from: TimeGuard, to: TimeGuard) => Duration;\n fromMilliseconds: (ms: number) => Duration;\n };\n }\n ).Duration = Duration;\n\n (\n TimeGuardClass as unknown as {\n Duration: typeof Duration;\n duration: {\n fromISO: (iso: string) => Duration;\n between: (from: TimeGuard, to: TimeGuard) => Duration;\n fromMilliseconds: (ms: number) => Duration;\n };\n }\n ).duration = {\n fromISO: (iso: string): Duration => Duration.fromISO(iso),\n between: (from: TimeGuard, to: TimeGuard): Duration =>\n Duration.between(from, to),\n fromMilliseconds: (ms: number): Duration => Duration.fromMilliseconds(ms),\n };\n }\n}\n\n/**\n * Create and export default instance\n */\nexport const durationPlugin = new DurationPlugin();\n\nexport default durationPlugin;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relative-time.cjs","names":[],"sources":["../../src/plugins/relative-time/index.ts"],"sourcesContent":["/**\
|
|
1
|
+
{"version":3,"file":"relative-time.cjs","names":[],"sources":["../../src/plugins/relative-time/index.ts"],"sourcesContent":["/**\n * TimeGuard Relative Time Plugin\n * Adds human-readable time differences (e.g., \"2 hours ago\", \"in 3 days\")\n * Follows SOLID principles and Temporal API standards\n */\n\nimport type { ITimeGuardPlugin } from '../../types';\nimport type { TimeGuard } from '../../index';\nimport type {\n RelativeTimeConfig,\n RelativeTimeFormats,\n RelativeTimeThreshold,\n} from './types';\n\nconst DEFAULT_THRESHOLDS: RelativeTimeThreshold[] = [\n { l: 's', r: 44, d: 'second' },\n { l: 'm', r: 89 },\n { l: 'mm', r: 44, d: 'minute' },\n { l: 'h', r: 89 },\n { l: 'hh', r: 21, d: 'hour' },\n { l: 'd', r: 35 },\n { l: 'dd', r: 25, d: 'day' },\n { l: 'M', r: 45 },\n { l: 'MM', r: 10, d: 'month' },\n { l: 'y', r: 17 },\n { l: 'yy', d: 'year' },\n];\n\nconst DEFAULT_FORMATS: RelativeTimeFormats = {\n future: 'in %s',\n past: '%s ago',\n s: 'a few seconds',\n m: 'a minute',\n mm: '%d minutes',\n h: 'an hour',\n hh: '%d hours',\n d: 'a day',\n dd: '%d days',\n M: 'a month',\n MM: '%d months',\n y: 'a year',\n yy: '%d years',\n};\n\nexport class RelativeTimePlugin implements ITimeGuardPlugin {\n name = 'relative-time';\n version = '1.0.0';\n\n private config: RelativeTimeConfig;\n private formats: RelativeTimeFormats;\n\n constructor(config?: RelativeTimeConfig) {\n this.config = {\n thresholds: config?.thresholds || DEFAULT_THRESHOLDS,\n rounding: config?.rounding || Math.round,\n };\n this.formats = DEFAULT_FORMATS;\n }\n\n /**\n * Install plugin into TimeGuard\n */\n install(TimeGuardClass: typeof TimeGuard): void {\n const plugin = this;\n\n /**\n * Get relative time string (e.g., \"2 hours ago\")\n */\n (\n TimeGuardClass.prototype as unknown as {\n fromNow: (withoutSuffix?: boolean) => string;\n }\n ).fromNow = function (withoutSuffix?: boolean): string {\n return plugin.formatRelativeTime(\n this as unknown as TimeGuard,\n false,\n withoutSuffix,\n );\n };\n\n (\n TimeGuardClass.prototype as unknown as {\n toNow: (withoutSuffix?: boolean) => string;\n }\n ).toNow = function (withoutSuffix?: boolean): string {\n return plugin.formatRelativeTime(\n this as unknown as TimeGuard,\n true,\n withoutSuffix,\n );\n };\n\n (\n TimeGuardClass.prototype as unknown as {\n humanize: (other?: TimeGuard, withoutSuffix?: boolean) => string;\n }\n ).humanize = function (other?: TimeGuard, withoutSuffix?: boolean): string {\n if (other) {\n return plugin.formatRelativeTime(\n this as unknown as TimeGuard,\n other.isAfter(this as unknown as TimeGuard),\n withoutSuffix,\n );\n }\n return plugin.formatRelativeTime(\n this as unknown as TimeGuard,\n false,\n withoutSuffix,\n );\n };\n }\n\n /**\n * Format relative time\n */\n private formatRelativeTime(\n date: TimeGuard,\n isFuture: boolean,\n withoutSuffix?: boolean,\n ): string {\n const now = (date.constructor as typeof TimeGuard).now();\n const diff = now.diff(date, 'millisecond');\n const absDiff = Math.abs(diff);\n const isFromNow = diff > 0;\n const actualIsFuture = isFuture ?? !isFromNow;\n\n const result = this.getRelativeTimeString(absDiff);\n\n if (withoutSuffix) {\n return result;\n }\n\n const suffix = actualIsFuture ? this.formats.future : this.formats.past;\n return suffix.replace('%s', result);\n }\n\n /**\n * Get relative time string based on milliseconds\n */\n private getRelativeTimeString(milliseconds: number): string {\n const thresholds = this.config.thresholds || DEFAULT_THRESHOLDS;\n const rounding = this.config.rounding || Math.round;\n\n for (let i = 0; i < thresholds.length; i++) {\n const threshold = thresholds[i];\n const nextThreshold =\n i + 1 < thresholds.length ? thresholds[i + 1] : null;\n\n // Skip if we haven't reached this threshold\n if (nextThreshold && threshold.r && milliseconds < threshold.r * 1000) {\n continue;\n }\n\n // Convert to appropriate unit\n let value: number;\n if (threshold.d) {\n const unitMs = this.getUnitMilliseconds(threshold.d);\n value = rounding(milliseconds / unitMs);\n } else {\n value = 1;\n }\n\n const label = threshold.l;\n const format = this.formats[label as keyof typeof this.formats] || label;\n\n if (typeof format === 'string') {\n return format.includes('%d')\n ? format.replace('%d', String(value))\n : format;\n }\n\n return format;\n }\n\n // Fallback\n return `${rounding(milliseconds / 1000)} seconds`;\n }\n\n /**\n * Get milliseconds per unit\n */\n private getUnitMilliseconds(unit: string): number {\n const msMap: Record<string, number> = {\n second: 1000,\n minute: 1000 * 60,\n hour: 1000 * 60 * 60,\n day: 1000 * 60 * 60 * 24,\n month: 1000 * 60 * 60 * 24 * 30,\n year: 1000 * 60 * 60 * 24 * 365,\n };\n return msMap[unit] || 1;\n }\n\n /**\n * Set format strings\n */\n setFormats(formats: Partial<RelativeTimeFormats>): void {\n Object.assign(this.formats, formats);\n }\n\n /**\n * Get current formats\n */\n getFormats(): RelativeTimeFormats {\n return { ...this.formats };\n }\n}\n\n/**\n * Create and export default instance\n */\nexport default new RelativeTimePlugin();\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! time-guard v2.
|
|
1
|
+
/*! time-guard v2.6.1 | (c) 2026 Berea-Soft | MIT License | https://github.com/Berea-Soft/time-guard */
|
|
2
2
|
//#region src/plugins/relative-time/index.ts
|
|
3
3
|
var e = [
|
|
4
4
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relative-time.es.js","names":[],"sources":["../../src/plugins/relative-time/index.ts"],"sourcesContent":["/**\
|
|
1
|
+
{"version":3,"file":"relative-time.es.js","names":[],"sources":["../../src/plugins/relative-time/index.ts"],"sourcesContent":["/**\n * TimeGuard Relative Time Plugin\n * Adds human-readable time differences (e.g., \"2 hours ago\", \"in 3 days\")\n * Follows SOLID principles and Temporal API standards\n */\n\nimport type { ITimeGuardPlugin } from '../../types';\nimport type { TimeGuard } from '../../index';\nimport type {\n RelativeTimeConfig,\n RelativeTimeFormats,\n RelativeTimeThreshold,\n} from './types';\n\nconst DEFAULT_THRESHOLDS: RelativeTimeThreshold[] = [\n { l: 's', r: 44, d: 'second' },\n { l: 'm', r: 89 },\n { l: 'mm', r: 44, d: 'minute' },\n { l: 'h', r: 89 },\n { l: 'hh', r: 21, d: 'hour' },\n { l: 'd', r: 35 },\n { l: 'dd', r: 25, d: 'day' },\n { l: 'M', r: 45 },\n { l: 'MM', r: 10, d: 'month' },\n { l: 'y', r: 17 },\n { l: 'yy', d: 'year' },\n];\n\nconst DEFAULT_FORMATS: RelativeTimeFormats = {\n future: 'in %s',\n past: '%s ago',\n s: 'a few seconds',\n m: 'a minute',\n mm: '%d minutes',\n h: 'an hour',\n hh: '%d hours',\n d: 'a day',\n dd: '%d days',\n M: 'a month',\n MM: '%d months',\n y: 'a year',\n yy: '%d years',\n};\n\nexport class RelativeTimePlugin implements ITimeGuardPlugin {\n name = 'relative-time';\n version = '1.0.0';\n\n private config: RelativeTimeConfig;\n private formats: RelativeTimeFormats;\n\n constructor(config?: RelativeTimeConfig) {\n this.config = {\n thresholds: config?.thresholds || DEFAULT_THRESHOLDS,\n rounding: config?.rounding || Math.round,\n };\n this.formats = DEFAULT_FORMATS;\n }\n\n /**\n * Install plugin into TimeGuard\n */\n install(TimeGuardClass: typeof TimeGuard): void {\n const plugin = this;\n\n /**\n * Get relative time string (e.g., \"2 hours ago\")\n */\n (\n TimeGuardClass.prototype as unknown as {\n fromNow: (withoutSuffix?: boolean) => string;\n }\n ).fromNow = function (withoutSuffix?: boolean): string {\n return plugin.formatRelativeTime(\n this as unknown as TimeGuard,\n false,\n withoutSuffix,\n );\n };\n\n (\n TimeGuardClass.prototype as unknown as {\n toNow: (withoutSuffix?: boolean) => string;\n }\n ).toNow = function (withoutSuffix?: boolean): string {\n return plugin.formatRelativeTime(\n this as unknown as TimeGuard,\n true,\n withoutSuffix,\n );\n };\n\n (\n TimeGuardClass.prototype as unknown as {\n humanize: (other?: TimeGuard, withoutSuffix?: boolean) => string;\n }\n ).humanize = function (other?: TimeGuard, withoutSuffix?: boolean): string {\n if (other) {\n return plugin.formatRelativeTime(\n this as unknown as TimeGuard,\n other.isAfter(this as unknown as TimeGuard),\n withoutSuffix,\n );\n }\n return plugin.formatRelativeTime(\n this as unknown as TimeGuard,\n false,\n withoutSuffix,\n );\n };\n }\n\n /**\n * Format relative time\n */\n private formatRelativeTime(\n date: TimeGuard,\n isFuture: boolean,\n withoutSuffix?: boolean,\n ): string {\n const now = (date.constructor as typeof TimeGuard).now();\n const diff = now.diff(date, 'millisecond');\n const absDiff = Math.abs(diff);\n const isFromNow = diff > 0;\n const actualIsFuture = isFuture ?? !isFromNow;\n\n const result = this.getRelativeTimeString(absDiff);\n\n if (withoutSuffix) {\n return result;\n }\n\n const suffix = actualIsFuture ? this.formats.future : this.formats.past;\n return suffix.replace('%s', result);\n }\n\n /**\n * Get relative time string based on milliseconds\n */\n private getRelativeTimeString(milliseconds: number): string {\n const thresholds = this.config.thresholds || DEFAULT_THRESHOLDS;\n const rounding = this.config.rounding || Math.round;\n\n for (let i = 0; i < thresholds.length; i++) {\n const threshold = thresholds[i];\n const nextThreshold =\n i + 1 < thresholds.length ? thresholds[i + 1] : null;\n\n // Skip if we haven't reached this threshold\n if (nextThreshold && threshold.r && milliseconds < threshold.r * 1000) {\n continue;\n }\n\n // Convert to appropriate unit\n let value: number;\n if (threshold.d) {\n const unitMs = this.getUnitMilliseconds(threshold.d);\n value = rounding(milliseconds / unitMs);\n } else {\n value = 1;\n }\n\n const label = threshold.l;\n const format = this.formats[label as keyof typeof this.formats] || label;\n\n if (typeof format === 'string') {\n return format.includes('%d')\n ? format.replace('%d', String(value))\n : format;\n }\n\n return format;\n }\n\n // Fallback\n return `${rounding(milliseconds / 1000)} seconds`;\n }\n\n /**\n * Get milliseconds per unit\n */\n private getUnitMilliseconds(unit: string): number {\n const msMap: Record<string, number> = {\n second: 1000,\n minute: 1000 * 60,\n hour: 1000 * 60 * 60,\n day: 1000 * 60 * 60 * 24,\n month: 1000 * 60 * 60 * 24 * 30,\n year: 1000 * 60 * 60 * 24 * 365,\n };\n return msMap[unit] || 1;\n }\n\n /**\n * Set format strings\n */\n setFormats(formats: Partial<RelativeTimeFormats>): void {\n Object.assign(this.formats, formats);\n }\n\n /**\n * Get current formats\n */\n getFormats(): RelativeTimeFormats {\n return { ...this.formats };\n }\n}\n\n/**\n * Create and export default instance\n */\nexport default new RelativeTimePlugin();\n"],"mappings":"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"}
|