@pawells/typescript-common 2.1.5 → 2.1.6

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 (61) hide show
  1. package/README.md +22 -1
  2. package/dist/array/index.d.ts +1 -0
  3. package/dist/array/index.d.ts.map +1 -1
  4. package/dist/array/index.js +1 -0
  5. package/dist/array/iterators.d.ts +40 -0
  6. package/dist/array/iterators.d.ts.map +1 -0
  7. package/dist/array/iterators.js +54 -0
  8. package/dist/asserts/generic.d.ts +1 -1
  9. package/dist/asserts/generic.d.ts.map +1 -1
  10. package/dist/asserts/generic.js +8 -2
  11. package/dist/asserts/utils.d.ts.map +1 -1
  12. package/dist/asserts/utils.js +2 -3
  13. package/dist/enum/index.d.ts +1 -1
  14. package/dist/enum/index.d.ts.map +1 -1
  15. package/dist/enum/index.js +1 -1
  16. package/dist/function/memoize.d.ts +13 -0
  17. package/dist/function/memoize.d.ts.map +1 -1
  18. package/dist/function/memoize.js +13 -0
  19. package/dist/index.d.ts +3 -0
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +3 -0
  22. package/dist/json.sanitization.d.ts +14 -0
  23. package/dist/json.sanitization.d.ts.map +1 -0
  24. package/dist/json.sanitization.js +37 -0
  25. package/dist/object/clone.d.ts +6 -0
  26. package/dist/object/clone.d.ts.map +1 -1
  27. package/dist/object/clone.js +7 -1
  28. package/dist/object/filter-cached.d.ts +0 -18
  29. package/dist/object/filter-cached.d.ts.map +1 -1
  30. package/dist/object/filter-cached.js +0 -18
  31. package/dist/object/filter.d.ts.map +1 -1
  32. package/dist/object/filter.js +10 -1
  33. package/dist/object/hash.js +2 -2
  34. package/dist/object/index.d.ts +1 -1
  35. package/dist/object/index.d.ts.map +1 -1
  36. package/dist/object/object-flatten.js +4 -0
  37. package/dist/object/property-paths.d.ts +2 -0
  38. package/dist/object/property-paths.d.ts.map +1 -1
  39. package/dist/object/property-paths.js +2 -0
  40. package/dist/object/security-utils.d.ts.map +1 -1
  41. package/dist/object/security-utils.js +8 -1
  42. package/dist/object/sort-keys.d.ts +14 -0
  43. package/dist/object/sort-keys.d.ts.map +1 -1
  44. package/dist/object/sort-keys.js +14 -0
  45. package/dist/object/types.d.ts +0 -102
  46. package/dist/object/types.d.ts.map +1 -1
  47. package/dist/string/assert.d.ts +19 -0
  48. package/dist/string/assert.d.ts.map +1 -1
  49. package/dist/string/assert.js +19 -0
  50. package/dist/time/elapsed-time/elapsed-time.d.ts +7 -7
  51. package/dist/time/elapsed-time/elapsed-time.js +25 -25
  52. package/dist/time/index.d.ts +1 -3
  53. package/dist/time/index.d.ts.map +1 -1
  54. package/dist/time/index.js +0 -3
  55. package/dist/time/stopwatch/stopwatch.d.ts +18 -0
  56. package/dist/time/stopwatch/stopwatch.d.ts.map +1 -1
  57. package/dist/time/stopwatch/stopwatch.js +23 -0
  58. package/dist/zod-util.d.ts +145 -0
  59. package/dist/zod-util.d.ts.map +1 -0
  60. package/dist/zod-util.js +126 -0
  61. package/package.json +65 -58
@@ -48,11 +48,18 @@ const /**
48
48
  * anchored to prevent catastrophic backtracking.
49
49
  */
50
50
  const PATH_TRAVERSAL_PATTERNS = [
51
+ /\.\./, // ASCII parent directory (..)
52
+ /\//, // ASCII solidus (forward slash)
51
53
  /%2e%2e/i, // URL encoded ..
54
+ /%2f/i, // URL encoded solidus
52
55
  /%252e%252e/i, // Double URL encoded ..
56
+ /%252f/i, // Double URL encoded solidus
57
+ /../, // Fullwidth parent directory (U+FF0E U+FF0E)
58
+ ///, // Fullwidth solidus (U+FF0F)
59
+ /∕/, // Division slash (U+2215)
53
60
  new RegExp(String.fromCharCode(0)), // Null byte injection
54
61
  /%00/i, // URL encoded null byte
55
- new RegExp('[\\u200b\\ufeff\\ufffe\\uffff]'), // Unicode BOM, reversed BOM, and invalid characters
62
+ new RegExp('[​￾￿]'), // Unicode BOM, reversed BOM, and invalid characters
56
63
  ];
57
64
  /**
58
65
  * Validates if a property key is safe to use (not dangerous for prototype pollution)
@@ -22,5 +22,19 @@
22
22
  * // Result: { active: true, age: 30, email: 'john@example.com', name: 'John' }
23
23
  * ```
24
24
  */
25
+ /**
26
+ * Sorts the enumerable keys of an object in ascending order.
27
+ *
28
+ * @remarks
29
+ * - Sorts only enumerable keys; non-enumerable properties are preserved in-place
30
+ * - Symbol keys are not sorted (enumerable symbols appear in creation order)
31
+ * - Returns a new object with sorted enumerable keys and all non-enumerable properties
32
+ *
33
+ * @param object - The object to sort
34
+ * @returns A new object with sorted enumerable keys
35
+ * @example
36
+ * const obj = { z: 1, a: 2, m: 3 };
37
+ * ObjectSortKeys(obj); // { a: 2, m: 3, z: 1 }
38
+ */
25
39
  export declare function ObjectSortKeys<T extends Record<string, unknown>>(object: T): T;
26
40
  //# sourceMappingURL=sort-keys.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sort-keys.d.ts","sourceRoot":"","sources":["../../src/object/sort-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAuC9E"}
1
+ {"version":3,"file":"sort-keys.d.ts","sourceRoot":"","sources":["../../src/object/sort-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAuC9E"}
@@ -22,6 +22,20 @@
22
22
  * // Result: { active: true, age: 30, email: 'john@example.com', name: 'John' }
23
23
  * ```
24
24
  */
25
+ /**
26
+ * Sorts the enumerable keys of an object in ascending order.
27
+ *
28
+ * @remarks
29
+ * - Sorts only enumerable keys; non-enumerable properties are preserved in-place
30
+ * - Symbol keys are not sorted (enumerable symbols appear in creation order)
31
+ * - Returns a new object with sorted enumerable keys and all non-enumerable properties
32
+ *
33
+ * @param object - The object to sort
34
+ * @returns A new object with sorted enumerable keys
35
+ * @example
36
+ * const obj = { z: 1, a: 2, m: 3 };
37
+ * ObjectSortKeys(obj); // { a: 2, m: 3, z: 1 }
38
+ */
25
39
  export function ObjectSortKeys(object) {
26
40
  if (!object || typeof object !== 'object' || Array.isArray(object)) {
27
41
  return object;
@@ -1,105 +1,3 @@
1
- /**
2
- * Omits properties from B that are not in A.
3
- *
4
- * @template A - Base type.
5
- * @template B - Type to filter.
6
- *
7
- * @remarks
8
- * Currently exported but not used by public API functions. Reserved for future use
9
- * as an extension point for constrained object transformations or validation scenarios.
10
- */
11
- export type TObjectOmitExtraProperties<A, B> = {
12
- [K in keyof B]: K extends A ? B[K] : never;
13
- };
14
- /**
15
- * Extracts the property keys of an object type.
16
- *
17
- * @template O - The object type.
18
- *
19
- * @remarks
20
- * Currently exported but not used by public API functions. Reserved for future use
21
- * as a generic property introspection utility or type constraint.
22
- */
23
- export type TObjectProperties<O extends object> = keyof O;
24
- /**
25
- * Extracts property keys of a specific type from an object.
26
- *
27
- * @template O - Object type.
28
- * @template PropertyType - The type to match.
29
- *
30
- * @remarks
31
- * Currently exported but not used by public API functions. Reserved for future use
32
- * in type-filtered property transformations or validations (e.g., filtering all
33
- * string properties, all optional properties, or all array properties).
34
- */
35
- export type TObjectPropertiesOfType<O extends object, PropertyType> = keyof {
36
- [K in keyof O as O[K] extends PropertyType ? K : never]: unknown;
37
- };
38
- /**
39
- * Omits properties of a specific type from an object.
40
- *
41
- * @template O - Object type.
42
- * @template PropertyType - The type to omit.
43
- *
44
- * @remarks
45
- * Currently exported but not used by public API functions. Reserved for future use
46
- * in scenarios requiring conditional property exclusion based on value type
47
- * (e.g., extracting only non-array properties, or excluding optional properties).
48
- */
49
- export type TObjectOmitPropertiesOfType<O extends object, PropertyType> = {
50
- [K in keyof O as O[K] extends PropertyType ? never : K]: O[K];
51
- };
52
- /**
53
- * Represents the union of all property values in an object.
54
- *
55
- * @template T - Object type.
56
- *
57
- * @remarks
58
- * Currently exported but not used by public API functions. Reserved for future use
59
- * in generic object value introspection or validation scenarios.
60
- */
61
- export type TObjectPropertyType<T extends object> = T[keyof T];
62
- /**
63
- * Extracts properties shared between two object types.
64
- *
65
- * @template A - First object type.
66
- * @template B - Second object type.
67
- *
68
- * @remarks
69
- * Currently exported but not used by public API functions. Reserved for future use
70
- * in scenarios requiring intersection of object types or common property extraction
71
- * for schema validation or type merging operations.
72
- */
73
- export type TObjectSharedProperties<A extends object, B extends object> = {
74
- [K in keyof A & keyof B]: K extends keyof A ? A[K] : never;
75
- };
76
- /**
77
- * Extracts keys of array properties from an object type.
78
- *
79
- * @template T - Object type.
80
- *
81
- * @remarks
82
- * Currently exported but not used by public API functions. Reserved for future use
83
- * in scenarios requiring filtering of array-typed properties, such as validating
84
- * array field schemas or transforming only array properties in an object.
85
- */
86
- export type TObjectArrayProperties<T extends object> = {
87
- [K in keyof T]: T[K] extends Array<unknown> ? K : never;
88
- }[keyof T];
89
- /**
90
- * Generates nested dot-notation keys for an object type.
91
- *
92
- * @template ObjectType - The object type to generate keys for.
93
- *
94
- * @remarks
95
- * Currently exported but not used by public API functions. Reserved for future use
96
- * in scenarios requiring type-safe nested property access, such as advanced path
97
- * navigation utilities or deep property validation frameworks that benefit from
98
- * compile-time validation of dot-notation paths.
99
- */
100
- export type TObjectNestedKeyOf<ObjectType extends object> = {
101
- [Key in keyof ObjectType & (string | number)]: ObjectType[Key] extends object ? `${Key}` | `${Key}.${TObjectNestedKeyOf<ObjectType[Key]>}` : `${Key}`;
102
- }[keyof ObjectType & (string | number)];
103
1
  /**
104
2
  * Options for object filtering behavior.
105
3
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/object/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/object/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,4HAA4H;IAC5H,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACnC,8EAA8E;IAC9E,sBAAsB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7C,iHAAiH;IACjH,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IAC1C,qGAAqG;IACrG,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,4HAA4H;IAC5H,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACnC,8EAA8E;IAC9E,sBAAsB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7C,iHAAiH;IACjH,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACvC,0FAA0F;IAC1F,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,MAAM,2BAA2B,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtI;;;GAGG;AACH,MAAM,MAAM,2BAA2B,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAE7J;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,CAAC;AAE9E;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM,EAAE,OAAO,SAAS,MAAM,GAAG,MAAM,IAAI,CACjG,KAAK,EAAE,MAAM,KACT,OAAO,CAAC;AAEb;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC;AAElF;;;;;;GAMG;AACH,MAAM,MAAM,yBAAyB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC;AAE3F;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CACrF,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KACP,OAAO,CAAC;AAEb;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CACrF,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,KACP,OAAO,CAAC"}
@@ -102,5 +102,24 @@ export declare function AssertStringNotEmpty(value: unknown, exception?: IAssert
102
102
  * AssertStringMatches("user2@example.com", emailPattern); // Uses cached pattern
103
103
  * ```
104
104
  */
105
+ /**
106
+ * Asserts that the provided value matches the specified regular expression pattern.
107
+ *
108
+ * Uses an LRU cache to store compiled RegExp objects for repeated pattern matching,
109
+ * improving performance for long-running processes with dynamic regex patterns.
110
+ *
111
+ * @remarks
112
+ * - Cache size: 100 entries
113
+ * - Cache is LRU-evicted (least recently used entry is removed when size is exceeded)
114
+ * - When to expect cache behavior: dynamic regex patterns with long-running processes
115
+ *
116
+ * @param value - The string to test against the pattern
117
+ * @param regex - The regular expression pattern to match
118
+ * @param exception - Optional exception configuration
119
+ * @throws StringError if the value does not match the pattern
120
+ * @example
121
+ * AssertStringMatches('test@example.com', /^[^@]+@[^@]+\.[^@]+$/); // passes
122
+ * AssertStringMatches('invalid-email', /^[^@]+@[^@]+\.[^@]+$/); // throws
123
+ */
105
124
  export declare function AssertStringMatches(value: string, regex: RegExp, exception?: IAssertException): void;
106
125
  //# sourceMappingURL=assert.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"assert.d.ts","sourceRoot":"","sources":["../../src/string/assert.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AA8CnD;;;;;;;;;;GAUG;AACH,qBAAa,WAAY,SAAQ,WAAW;gBAC/B,OAAO,CAAC,EAAE,MAAM;CAG5B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,GAAE,gBAAqB,GAAG,OAAO,CAAC,KAAK,IAAI,MAAM,CAGtG;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,GAAE,gBAAqB,GAAG,OAAO,CAAC,KAAK,IAAI,MAAM,CAY9G;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,GAAE,gBAAqB,GAAG,IAAI,CAsBxG"}
1
+ {"version":3,"file":"assert.d.ts","sourceRoot":"","sources":["../../src/string/assert.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AA8CnD;;;;;;;;;;GAUG;AACH,qBAAa,WAAY,SAAQ,WAAW;gBAC/B,OAAO,CAAC,EAAE,MAAM;CAG5B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,GAAE,gBAAqB,GAAG,OAAO,CAAC,KAAK,IAAI,MAAM,CAGtG;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,GAAE,gBAAqB,GAAG,OAAO,CAAC,KAAK,IAAI,MAAM,CAY9G;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,GAAE,gBAAqB,GAAG,IAAI,CAsBxG"}
@@ -159,6 +159,25 @@ export function AssertStringNotEmpty(value, exception = {}) {
159
159
  * AssertStringMatches("user2@example.com", emailPattern); // Uses cached pattern
160
160
  * ```
161
161
  */
162
+ /**
163
+ * Asserts that the provided value matches the specified regular expression pattern.
164
+ *
165
+ * Uses an LRU cache to store compiled RegExp objects for repeated pattern matching,
166
+ * improving performance for long-running processes with dynamic regex patterns.
167
+ *
168
+ * @remarks
169
+ * - Cache size: 100 entries
170
+ * - Cache is LRU-evicted (least recently used entry is removed when size is exceeded)
171
+ * - When to expect cache behavior: dynamic regex patterns with long-running processes
172
+ *
173
+ * @param value - The string to test against the pattern
174
+ * @param regex - The regular expression pattern to match
175
+ * @param exception - Optional exception configuration
176
+ * @throws StringError if the value does not match the pattern
177
+ * @example
178
+ * AssertStringMatches('test@example.com', /^[^@]+@[^@]+\.[^@]+$/); // passes
179
+ * AssertStringMatches('invalid-email', /^[^@]+@[^@]+\.[^@]+$/); // throws
180
+ */
162
181
  export function AssertStringMatches(value, regex, exception = {}) {
163
182
  SetExceptionClass(exception, StringError);
164
183
  AssertString(value, exception); // Ensure value is a string before matching
@@ -61,7 +61,7 @@ export declare class ElapsedTime {
61
61
  * console.log(elapsed.TotalHours); // 26
62
62
  * ```
63
63
  */
64
- private _CalculateTimeValues;
64
+ private _calculateTimeValues;
65
65
  /**
66
66
  * Get a cached property value, computing and caching it if necessary.
67
67
  * For stopped/paused instances (where TotalMilliseconds doesn't change),
@@ -313,7 +313,7 @@ export declare class ElapsedTime {
313
313
  * elapsed2.Format('LONG'); // "2 hours 2 minutes 2 seconds" (all plural)
314
314
  * ```
315
315
  */
316
- private _FormatLong;
316
+ private _formatLong;
317
317
  /**
318
318
  * Format the elapsed time using the token-based formatting system.
319
319
  * This is the main formatting engine that handles all predefined formats
@@ -335,7 +335,7 @@ export declare class ElapsedTime {
335
335
  * // Called automatically by Format() method for most format types
336
336
  * ```
337
337
  */
338
- private _FormatUsingTokens;
338
+ private _formatUsingTokens;
339
339
  /**
340
340
  * Format time units for TIME and TIME_WITH_SECONDS formats
341
341
  * These formats use special formatting with colons for displaying time (e.g., "1:30:45")
@@ -344,7 +344,7 @@ export declare class ElapsedTime {
344
344
  * @returns Formatted time string with colons (e.g., "1:30:45")
345
345
  * @private
346
346
  */
347
- private static _FormatTimeUnits;
347
+ private static _formatTimeUnits;
348
348
  /**
349
349
  * Format units for standard (non-time) formats
350
350
  * Handles different formatting styles including CONCISE, SHORT, MEDIUM, LONG, and custom formats
@@ -355,7 +355,7 @@ export declare class ElapsedTime {
355
355
  * @returns Formatted time string according to the specified format style
356
356
  * @private
357
357
  */
358
- private static _FormatStandardUnits;
358
+ private static _formatStandardUnits;
359
359
  /**
360
360
  * Filter and limit time units based on formatting options.
361
361
  * Applies showZeroValues and maxUnits options to determine which
@@ -374,7 +374,7 @@ export declare class ElapsedTime {
374
374
  * // All zero values -> ensures at least "0 seconds" is shown
375
375
  * ```
376
376
  */
377
- private static _FilterAndLimitUnits;
377
+ private static _filterAndLimitUnits;
378
378
  /**
379
379
  * Apply negative value formatting based on user preferences.
380
380
  * Wraps or modifies the formatted time string to indicate negative durations
@@ -394,7 +394,7 @@ export declare class ElapsedTime {
394
394
  * // Empty: "1h 30m" -> "1h 30m" (no change)
395
395
  * ```
396
396
  */
397
- private static _ApplyNegativeFormatting;
397
+ private static _applyNegativeFormatting;
398
398
  }
399
399
  /**
400
400
  * Formats elapsed time using the specified configuration.
@@ -78,7 +78,7 @@ export class ElapsedTime {
78
78
  * console.log(elapsed.TotalHours); // 26
79
79
  * ```
80
80
  */
81
- _CalculateTimeValues() {
81
+ _calculateTimeValues() {
82
82
  if (this._valuesCalculated)
83
83
  return;
84
84
  this._totalSeconds = Math.floor(this._totalMilliseconds / MS_PER_SECOND);
@@ -119,7 +119,7 @@ export class ElapsedTime {
119
119
  */
120
120
  get Weeks() {
121
121
  return this._getCachedProperty('weeks', () => {
122
- this._CalculateTimeValues();
122
+ this._calculateTimeValues();
123
123
  return this._weeks;
124
124
  });
125
125
  }
@@ -128,7 +128,7 @@ export class ElapsedTime {
128
128
  */
129
129
  get Days() {
130
130
  return this._getCachedProperty('days', () => {
131
- this._CalculateTimeValues();
131
+ this._calculateTimeValues();
132
132
  return this._days;
133
133
  });
134
134
  }
@@ -137,7 +137,7 @@ export class ElapsedTime {
137
137
  */
138
138
  get TotalDays() {
139
139
  return this._getCachedProperty('totalDays', () => {
140
- this._CalculateTimeValues();
140
+ this._calculateTimeValues();
141
141
  return this._totalDays;
142
142
  });
143
143
  }
@@ -146,7 +146,7 @@ export class ElapsedTime {
146
146
  */
147
147
  get Hours() {
148
148
  return this._getCachedProperty('hours', () => {
149
- this._CalculateTimeValues();
149
+ this._calculateTimeValues();
150
150
  return this._hours;
151
151
  });
152
152
  }
@@ -166,7 +166,7 @@ export class ElapsedTime {
166
166
  */
167
167
  get TotalHours() {
168
168
  return this._getCachedProperty('totalHours', () => {
169
- this._CalculateTimeValues();
169
+ this._calculateTimeValues();
170
170
  return this._totalHours;
171
171
  });
172
172
  }
@@ -183,7 +183,7 @@ export class ElapsedTime {
183
183
  */
184
184
  get Minutes() {
185
185
  return this._getCachedProperty('minutes', () => {
186
- this._CalculateTimeValues();
186
+ this._calculateTimeValues();
187
187
  return this._minutes;
188
188
  });
189
189
  }
@@ -200,7 +200,7 @@ export class ElapsedTime {
200
200
  */
201
201
  get TotalMinutes() {
202
202
  return this._getCachedProperty('totalMinutes', () => {
203
- this._CalculateTimeValues();
203
+ this._calculateTimeValues();
204
204
  return this._totalMinutes;
205
205
  });
206
206
  }
@@ -217,7 +217,7 @@ export class ElapsedTime {
217
217
  */
218
218
  get Seconds() {
219
219
  return this._getCachedProperty('seconds', () => {
220
- this._CalculateTimeValues();
220
+ this._calculateTimeValues();
221
221
  return this._seconds;
222
222
  });
223
223
  }
@@ -234,7 +234,7 @@ export class ElapsedTime {
234
234
  */
235
235
  get TotalSeconds() {
236
236
  return this._getCachedProperty('totalSeconds', () => {
237
- this._CalculateTimeValues();
237
+ this._calculateTimeValues();
238
238
  return this._totalSeconds;
239
239
  });
240
240
  }
@@ -251,7 +251,7 @@ export class ElapsedTime {
251
251
  */
252
252
  get Milliseconds() {
253
253
  return this._getCachedProperty('milliseconds', () => {
254
- this._CalculateTimeValues();
254
+ this._calculateTimeValues();
255
255
  return this._milliseconds;
256
256
  });
257
257
  }
@@ -417,7 +417,7 @@ export class ElapsedTime {
417
417
  */
418
418
  Format(format = 'concise', options = {}) {
419
419
  // Ensure all time values are calculated
420
- this._CalculateTimeValues();
420
+ this._calculateTimeValues();
421
421
  let resolvedOptions = { ...options };
422
422
  // Handle predefined formats
423
423
  let formatKey = '';
@@ -431,9 +431,9 @@ export class ElapsedTime {
431
431
  const appliedOptions = ApplyDefaultOptions(resolvedOptions);
432
432
  // Special case for LONG format which needs pluralization
433
433
  if (formatKey === 'long') {
434
- return this._FormatLong(appliedOptions);
434
+ return this._formatLong(appliedOptions);
435
435
  }
436
- return this._FormatUsingTokens(appliedOptions, formatKey, options);
436
+ return this._formatUsingTokens(appliedOptions, formatKey, options);
437
437
  }
438
438
  /**
439
439
  * Special formatter for LONG format with proper pluralization.
@@ -454,7 +454,7 @@ export class ElapsedTime {
454
454
  * elapsed2.Format('LONG'); // "2 hours 2 minutes 2 seconds" (all plural)
455
455
  * ```
456
456
  */
457
- _FormatLong(options) {
457
+ _formatLong(options) {
458
458
  const parts = [];
459
459
  // Process each time unit in order of significance
460
460
  if (this._weeks > 0 || options.showZeroValues) {
@@ -486,7 +486,7 @@ export class ElapsedTime {
486
486
  const formatted = parts.join(' ');
487
487
  // Apply negative formatting
488
488
  if (this.IsNegative) {
489
- return ElapsedTime._ApplyNegativeFormatting(formatted, options);
489
+ return ElapsedTime._applyNegativeFormatting(formatted, options);
490
490
  }
491
491
  return formatted;
492
492
  }
@@ -511,7 +511,7 @@ export class ElapsedTime {
511
511
  * // Called automatically by Format() method for most format types
512
512
  * ```
513
513
  */
514
- _FormatUsingTokens(options, formatKey = '', originalOptions = {}) {
514
+ _formatUsingTokens(options, formatKey = '', originalOptions = {}) {
515
515
  // Define all available time units
516
516
  const units = [
517
517
  { unit: 'week', value: this.Weeks },
@@ -522,7 +522,7 @@ export class ElapsedTime {
522
522
  { unit: 'millisecond', value: this.Milliseconds },
523
523
  ];
524
524
  // Filter and limit units based on options
525
- const filteredUnits = ElapsedTime._FilterAndLimitUnits(units, options);
525
+ const filteredUnits = ElapsedTime._filterAndLimitUnits(units, options);
526
526
  const unitLabels = options.unitLabels ?? DEFAULT_UNIT_LABELS.medium;
527
527
  // Determine if custom labels were explicitly provided by the user (not from format defaults)
528
528
  const hasCustomLabels = originalOptions.unitLabels !== undefined;
@@ -532,13 +532,13 @@ export class ElapsedTime {
532
532
  let formatted;
533
533
  const isTimeFormat = formatKey === 'time' || formatKey === 'timeWithSeconds';
534
534
  if (isTimeFormat) {
535
- formatted = ElapsedTime._FormatTimeUnits(filteredUnits, unitLabels);
535
+ formatted = ElapsedTime._formatTimeUnits(filteredUnits, unitLabels);
536
536
  }
537
537
  else {
538
538
  // Handle different format types
539
- formatted = ElapsedTime._FormatStandardUnits(filteredUnits, unitLabels, formatKey, hasCustomLabels);
539
+ formatted = ElapsedTime._formatStandardUnits(filteredUnits, unitLabels, formatKey, hasCustomLabels);
540
540
  }
541
- return this.IsNegative ? ElapsedTime._ApplyNegativeFormatting(formatted, options) : formatted;
541
+ return this.IsNegative ? ElapsedTime._applyNegativeFormatting(formatted, options) : formatted;
542
542
  }
543
543
  /**
544
544
  * Format time units for TIME and TIME_WITH_SECONDS formats
@@ -548,7 +548,7 @@ export class ElapsedTime {
548
548
  * @returns Formatted time string with colons (e.g., "1:30:45")
549
549
  * @private
550
550
  */
551
- static _FormatTimeUnits(units, unitLabels) {
551
+ static _formatTimeUnits(units, unitLabels) {
552
552
  return units.map(({ unit, value: _value }) => {
553
553
  const labelFunc = unitLabels[unit];
554
554
  if (!labelFunc)
@@ -566,7 +566,7 @@ export class ElapsedTime {
566
566
  * @returns Formatted time string according to the specified format style
567
567
  * @private
568
568
  */
569
- static _FormatStandardUnits(units, unitLabels, formatKey = '', hasCustomLabels = false) {
569
+ static _formatStandardUnits(units, unitLabels, formatKey = '', hasCustomLabels = false) {
570
570
  // Function-based labels: invoke each label function with the value (e.g. pluralization)
571
571
  if (Object.values(unitLabels).some((label) => typeof label === 'function')) {
572
572
  return units.map(({ unit, value }) => {
@@ -626,7 +626,7 @@ export class ElapsedTime {
626
626
  * // All zero values -> ensures at least "0 seconds" is shown
627
627
  * ```
628
628
  */
629
- static _FilterAndLimitUnits(units, options) {
629
+ static _filterAndLimitUnits(units, options) {
630
630
  // Filter out zero values if not showing them
631
631
  let filteredUnits = options.showZeroValues ? units : units.filter((item) => item.value > 0);
632
632
  // Handle the case where all values are zero
@@ -659,7 +659,7 @@ export class ElapsedTime {
659
659
  * // Empty: "1h 30m" -> "1h 30m" (no change)
660
660
  * ```
661
661
  */
662
- static _ApplyNegativeFormatting(output, options) {
662
+ static _applyNegativeFormatting(output, options) {
663
663
  switch (options.negativeValueFormat) {
664
664
  case 'NegativeSign':
665
665
  return `-${output}`;
@@ -8,9 +8,7 @@
8
8
  * @module time
9
9
  */
10
10
  export * from './elapsed-time/elapsed-time.js';
11
- export * from './elapsed-time/types.js';
12
- export * from './elapsed-time/constants.js';
13
- export * from './elapsed-time/utils.js';
11
+ export type { ITimeUnitValue, ITimeElapsedFormatOptions, TTimeElapsedFormats, TTimeUnit, IUnitLabelMap, } from './elapsed-time/types.js';
14
12
  export * from './stopwatch/stopwatch.js';
15
13
  export * from './stopwatch/entry.js';
16
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/time/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/time/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,cAAc,gCAAgC,CAAC;AAC/C,YAAY,EACX,cAAc,EACd,yBAAyB,EACzB,mBAAmB,EACnB,SAAS,EACT,aAAa,GACb,MAAM,yBAAyB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC"}
@@ -8,8 +8,5 @@
8
8
  * @module time
9
9
  */
10
10
  export * from './elapsed-time/elapsed-time.js';
11
- export * from './elapsed-time/types.js';
12
- export * from './elapsed-time/constants.js';
13
- export * from './elapsed-time/utils.js';
14
11
  export * from './stopwatch/stopwatch.js';
15
12
  export * from './stopwatch/entry.js';
@@ -1,5 +1,23 @@
1
1
  import { ElapsedTime } from '../elapsed-time/elapsed-time.js';
2
2
  import { StopwatchEntry } from './entry.js';
3
+ import { SimpleError } from '../../asserts/errors.js';
4
+ /**
5
+ * Error thrown by Stopwatch when an invalid operation is attempted.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const sw = new Stopwatch();
10
+ * sw.Start();
11
+ * sw.Stop();
12
+ * sw.Resume(); // Throws StopwatchError
13
+ * ```
14
+ */
15
+ export declare class StopwatchError extends SimpleError {
16
+ /**
17
+ * @param message - Description of the stopwatch state error
18
+ */
19
+ constructor(message: string);
20
+ }
3
21
  /**
4
22
  * Represents a stopwatch for measuring time intervals.
5
23
  *
@@ -1 +1 @@
1
- {"version":3,"file":"stopwatch.d.ts","sourceRoot":"","sources":["../../../src/time/stopwatch/stopwatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,SAAS;IACrB,OAAO,CAAC,MAAM,CAAwB;IAEtC,OAAO,CAAC,SAAS,CAAuB;IAExC,OAAO,CAAC,QAAQ,CAAS;IAEzB;;;;;;;;;;;;OAYG;gBACS,gBAAgB,UAAQ;IAMpC;;;;OAIG;IACH,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED;;;;;OAKG;IACH,IAAW,KAAK,IAAI,cAAc,GAAG,SAAS,CAE7C;IAED;;;;;OAKG;IACH,IAAW,MAAM,IAAI,cAAc,GAAG,SAAS,CAE9C;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,IAAW,OAAO,IAAI,WAAW,CAUhC;IAED;;;;;OAKG;IACH,IAAW,KAAK,IAAI,cAAc,EAAE,CAEnC;IAED;;OAEG;IACH,IAAW,OAAO,IAAI,cAAc,EAAE,CAErC;IAED;;;OAGG;IACH,IAAW,QAAQ,IAAI,MAAM,GAAG,IAAI,CAEnC;IAED;;;;;;;;;;;;;;;;OAgBG;IACI,KAAK,IAAI,cAAc,GAAG,SAAS;IAU1C;;;;;;;;;;;;;;;;;;;;OAoBG;IACI,IAAI,IAAI,cAAc,GAAG,SAAS;IAmBzC;;;;;;;;;;;;;;;;;;;OAmBG;IACI,KAAK,IAAI,cAAc,GAAG,IAAI;IAQrC;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACI,MAAM,IAAI,cAAc,GAAG,IAAI;IAWtC;;;;;;;;;;;;;;;;OAgBG;IACI,KAAK,IAAI,cAAc;IAW9B;;;;;;;;;;;;;;;;;;OAkBG;IACI,GAAG,IAAI,WAAW;IAUzB;;;;;;;;;;;;;;;OAeG;IACI,KAAK,IAAI,IAAI;CAKpB"}
1
+ {"version":3,"file":"stopwatch.d.ts","sourceRoot":"","sources":["../../../src/time/stopwatch/stopwatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,qBAAa,cAAe,SAAQ,WAAW;IAC9C;;OAEG;gBACS,OAAO,EAAE,MAAM;CAG3B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,qBAAa,SAAS;IACrB,OAAO,CAAC,MAAM,CAAwB;IAEtC,OAAO,CAAC,SAAS,CAAuB;IAExC,OAAO,CAAC,QAAQ,CAAS;IAEzB;;;;;;;;;;;;OAYG;gBACS,gBAAgB,UAAQ;IAMpC;;;;OAIG;IACH,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED;;;;;OAKG;IACH,IAAW,KAAK,IAAI,cAAc,GAAG,SAAS,CAE7C;IAED;;;;;OAKG;IACH,IAAW,MAAM,IAAI,cAAc,GAAG,SAAS,CAE9C;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,IAAW,OAAO,IAAI,WAAW,CAUhC;IAED;;;;;OAKG;IACH,IAAW,KAAK,IAAI,cAAc,EAAE,CAEnC;IAED;;OAEG;IACH,IAAW,OAAO,IAAI,cAAc,EAAE,CAErC;IAED;;;OAGG;IACH,IAAW,QAAQ,IAAI,MAAM,GAAG,IAAI,CAEnC;IAED;;;;;;;;;;;;;;;;OAgBG;IACI,KAAK,IAAI,cAAc,GAAG,SAAS;IAU1C;;;;;;;;;;;;;;;;;;;;OAoBG;IACI,IAAI,IAAI,cAAc,GAAG,SAAS;IAmBzC;;;;;;;;;;;;;;;;;;;OAmBG;IACI,KAAK,IAAI,cAAc,GAAG,IAAI;IAQrC;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACI,MAAM,IAAI,cAAc,GAAG,IAAI;IActC;;;;;;;;;;;;;;;;OAgBG;IACI,KAAK,IAAI,cAAc;IAW9B;;;;;;;;;;;;;;;;;;OAkBG;IACI,GAAG,IAAI,WAAW;IAUzB;;;;;;;;;;;;;;;OAeG;IACI,KAAK,IAAI,IAAI;CAKpB"}
@@ -1,5 +1,25 @@
1
1
  import { ElapsedTime } from '../elapsed-time/elapsed-time.js';
2
2
  import { StopwatchEntry } from './entry.js';
3
+ import { SimpleError } from '../../asserts/errors.js';
4
+ /**
5
+ * Error thrown by Stopwatch when an invalid operation is attempted.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const sw = new Stopwatch();
10
+ * sw.Start();
11
+ * sw.Stop();
12
+ * sw.Resume(); // Throws StopwatchError
13
+ * ```
14
+ */
15
+ export class StopwatchError extends SimpleError {
16
+ /**
17
+ * @param message - Description of the stopwatch state error
18
+ */
19
+ constructor(message) {
20
+ super(message);
21
+ }
22
+ }
3
23
  /**
4
24
  * Represents a stopwatch for measuring time intervals.
5
25
  *
@@ -256,6 +276,9 @@ export class Stopwatch {
256
276
  * ```
257
277
  */
258
278
  Resume() {
279
+ if (this._stopped) {
280
+ throw new StopwatchError('Cannot resume after stopwatch has been stopped');
281
+ }
259
282
  if (this._pausedAt === null)
260
283
  return null;
261
284
  const current = Date.now();