@design-edito/tools 0.5.2 → 0.5.4

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 (152) hide show
  1. package/agnostic/html/deep-select/index.js +5 -3
  2. package/agnostic/html/hyper-json/smart-tags/coalesced/index.d.ts +9 -9
  3. package/agnostic/html/hyper-json/smart-tags/coalesced/index.js +9 -9
  4. package/agnostic/html/hyper-json/smart-tags/isolated/index.d.ts +3 -3
  5. package/agnostic/html/hyper-json/smart-tags/isolated/index.js +3 -3
  6. package/agnostic/html/index.d.ts +1 -1
  7. package/agnostic/html/index.js +1 -1
  8. package/agnostic/index.d.ts +2 -2
  9. package/agnostic/index.js +2 -2
  10. package/agnostic/misc/index.d.ts +3 -3
  11. package/agnostic/misc/index.js +3 -3
  12. package/agnostic/misc/logs/index.d.ts +1 -1
  13. package/agnostic/misc/logs/index.js +1 -1
  14. package/agnostic/numbers/index.d.ts +1 -1
  15. package/agnostic/numbers/index.js +1 -1
  16. package/agnostic/optim/index.d.ts +1 -1
  17. package/agnostic/optim/index.js +1 -1
  18. package/agnostic/strings/index.d.ts +2 -2
  19. package/agnostic/strings/index.js +2 -2
  20. package/agnostic/time/dates/format-date/index.d.ts +4 -2
  21. package/agnostic/time/dates/format-date/index.js +43 -94
  22. package/agnostic/time/dates/format-date/index.test.js +154 -0
  23. package/agnostic/time/dates/format-date/parts.d.ts +28 -0
  24. package/agnostic/time/dates/format-date/parts.js +136 -0
  25. package/agnostic/time/dates/format-date/types.d.ts +84 -0
  26. package/agnostic/time/dates/format-date/types.js +1 -0
  27. package/agnostic/time/duration/format-duration/index.d.ts +42 -0
  28. package/agnostic/time/duration/format-duration/index.js +94 -0
  29. package/agnostic/time/duration/format-duration/index.test.d.ts +1 -0
  30. package/agnostic/time/duration/format-duration/index.test.js +148 -0
  31. package/agnostic/time/duration/format-duration/parts.d.ts +32 -0
  32. package/agnostic/time/duration/format-duration/parts.js +107 -0
  33. package/agnostic/time/duration/format-duration/types.d.ts +93 -0
  34. package/agnostic/time/duration/format-duration/types.js +1 -0
  35. package/agnostic/time/duration/index.d.ts +6 -1
  36. package/agnostic/time/duration/index.js +2 -2
  37. package/agnostic/time/duration/index.test.d.ts +1 -0
  38. package/agnostic/time/duration/index.test.js +168 -0
  39. package/agnostic/time/index.d.ts +1 -1
  40. package/agnostic/time/index.js +1 -1
  41. package/components/BeforeAfter/index.controlled.d.ts +25 -25
  42. package/components/BeforeAfter/index.controlled.js +47 -53
  43. package/components/BeforeAfter/index.d.ts +20 -23
  44. package/components/BeforeAfter/index.js +48 -40
  45. package/components/Button/index.js +1 -1
  46. package/components/Clippable/index.d.ts +17 -26
  47. package/components/Clippable/index.js +21 -23
  48. package/components/Disclaimer/index.d.ts +32 -24
  49. package/components/Disclaimer/index.js +29 -24
  50. package/components/Drawer/index.d.ts +45 -25
  51. package/components/Drawer/index.js +61 -52
  52. package/components/EventListener/index.d.ts +4 -5
  53. package/components/Gallery/index.d.ts +14 -16
  54. package/components/Gallery/index.js +25 -30
  55. package/components/Iframe/index.js +2 -2
  56. package/components/Image/index.d.ts +5 -15
  57. package/components/Image/index.js +9 -34
  58. package/components/Input/index.d.ts +23 -19
  59. package/components/Input/index.js +30 -20
  60. package/components/JsonEditor/index.d.ts +177 -9
  61. package/components/JsonEditor/index.js +133 -77
  62. package/components/JsonEditor/types.d.ts +11 -0
  63. package/components/JsonEditor/types.js +1 -0
  64. package/components/JsonEditor/utils.d.ts +8 -0
  65. package/components/JsonEditor/utils.js +23 -0
  66. package/components/ListLoader/index.controlled.d.ts +5 -5
  67. package/components/ListLoader/index.controlled.js +4 -4
  68. package/components/ListLoader/index.d.ts +11 -11
  69. package/components/ListLoader/index.js +12 -12
  70. package/components/Overlayer/index.d.ts +4 -4
  71. package/components/Overlayer/index.js +6 -6
  72. package/components/Paginator/index.d.ts +7 -12
  73. package/components/Paginator/index.js +7 -11
  74. package/components/ResizeObserver/index.d.ts +14 -3
  75. package/components/ResizeObserver/index.js +49 -24
  76. package/components/Scrllgngn/index.d.ts +17 -13
  77. package/components/Scrllgngn/index.js +25 -84
  78. package/components/Scrllgngn/utils.d.ts +52 -0
  79. package/components/Scrllgngn/utils.js +102 -0
  80. package/components/ScrollListener/index.d.ts +43 -28
  81. package/components/ScrollListener/index.js +59 -79
  82. package/components/ScrollListener/utils.d.ts +37 -16
  83. package/components/ScrollListener/utils.js +141 -28
  84. package/components/Select/index.d.ts +24 -20
  85. package/components/Select/index.js +30 -20
  86. package/components/Sequencer/index.controlled.d.ts +16 -26
  87. package/components/Sequencer/index.controlled.js +15 -12
  88. package/components/Sequencer/index.d.ts +25 -30
  89. package/components/Sequencer/index.js +20 -34
  90. package/components/Subtitles/index.d.ts +29 -5
  91. package/components/Subtitles/index.js +90 -12
  92. package/components/Textarea/index.d.ts +26 -20
  93. package/components/Textarea/index.js +40 -21
  94. package/components/Theatre/index.d.ts +35 -39
  95. package/components/Theatre/index.js +46 -58
  96. package/components/UIModule/index.d.ts +25 -29
  97. package/components/UIModule/index.js +81 -110
  98. package/components/Video/index.controlled.d.ts +51 -51
  99. package/components/Video/index.controlled.js +75 -72
  100. package/components/Video/index.d.ts +12 -14
  101. package/components/Video/index.js +41 -86
  102. package/components/Video/utils.d.ts +35 -3
  103. package/components/Video/utils.js +37 -14
  104. package/components/index.d.ts +6 -6
  105. package/components/index.js +6 -6
  106. package/components/utils/index.d.ts +22 -0
  107. package/components/utils/index.js +31 -0
  108. package/index.d.ts +1 -1
  109. package/index.js +1 -1
  110. package/node/@aws-s3/storage/directory/index.d.ts +2 -2
  111. package/node/@aws-s3/storage/directory/index.js +2 -2
  112. package/node/@aws-s3/storage/file/index.d.ts +1 -1
  113. package/node/@aws-s3/storage/file/index.js +1 -1
  114. package/node/@aws-s3/storage/index.d.ts +1 -1
  115. package/node/@aws-s3/storage/index.js +1 -1
  116. package/node/@google-cloud/storage/directory/index.d.ts +2 -2
  117. package/node/@google-cloud/storage/directory/index.js +2 -2
  118. package/node/@google-cloud/storage/file/index.d.ts +2 -2
  119. package/node/@google-cloud/storage/file/index.js +2 -2
  120. package/node/@google-cloud/storage/index.d.ts +1 -1
  121. package/node/@google-cloud/storage/index.js +1 -1
  122. package/node/cloud-storage/operations/index.d.ts +2 -2
  123. package/node/cloud-storage/operations/index.js +2 -2
  124. package/node/ftps/file/index.d.ts +2 -2
  125. package/node/ftps/file/index.js +2 -2
  126. package/node/images/index.d.ts +1 -1
  127. package/node/images/index.js +1 -1
  128. package/node/images/transform/operations/index.d.ts +2 -2
  129. package/node/images/transform/operations/index.js +2 -2
  130. package/node/index.d.ts +1 -1
  131. package/node/index.js +1 -1
  132. package/node/process/index.d.ts +1 -1
  133. package/node/process/index.js +1 -1
  134. package/node/sftp/file/index.d.ts +2 -2
  135. package/node/sftp/file/index.js +2 -2
  136. package/node/sftp/index.d.ts +1 -1
  137. package/node/sftp/index.js +1 -1
  138. package/package.json +20 -5
  139. package/TODO.md +0 -269
  140. package/components/BeforeAfter/utils.d.ts +0 -4
  141. package/components/BeforeAfter/utils.js +0 -9
  142. package/components/Input/index.controlled.d.ts +0 -42
  143. package/components/Input/index.controlled.js +0 -54
  144. package/components/Select/index.controlled.d.ts +0 -43
  145. package/components/Select/index.controlled.js +0 -54
  146. package/components/Subtitles/types.d.ts +0 -24
  147. package/components/Subtitles/utils.d.ts +0 -32
  148. package/components/Subtitles/utils.js +0 -107
  149. package/components/Textarea/index.controlled.d.ts +0 -50
  150. package/components/Textarea/index.controlled.js +0 -75
  151. /package/{components/Subtitles/types.js → agnostic/time/dates/format-date/index.test.d.ts} +0 -0
  152. /package/components/ResizeObserver/{style.module.css → styles.module.css} +0 -0
@@ -1,10 +1,12 @@
1
1
  import * as Window from '../../misc/crossenv/window/index.js';
2
2
  import { deepGetProperty } from '../../objects/deep-get-property/index.js';
3
+ import { isRecord } from '../../objects/is-record/index.js';
3
4
  const yieldToMain = async (windowLike) => {
4
- const yild = deepGetProperty(windowLike, 'scheduler.yield');
5
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
5
+ const scheduler = deepGetProperty(windowLike, 'scheduler');
6
+ const yild = isRecord(scheduler) ? scheduler.yield : undefined;
7
+ // `scheduler.yield` must run with `scheduler` as its `this` — a detached reference throws "Illegal invocation".
6
8
  if (typeof yild === 'function')
7
- yild();
9
+ await yild.call(scheduler);
8
10
  else
9
11
  await new Promise(resolve => { setTimeout(resolve, 0); });
10
12
  };
@@ -5,19 +5,19 @@ export * as append from './append/index.js'
5
5
  export * as at from './at/index.js'
6
6
  export * as call from './call/index.js'
7
7
  export * as clone from './clone/index.js'
8
- export * as equals from './equals/index.js'
9
8
  export * as deleteproperties from './deleteproperties/index.js'
9
+ export * as equals from './equals/index.js'
10
10
  export * as getattribute from './getattribute/index.js'
11
11
  export * as getproperties from './getproperties/index.js'
12
12
  export * as getproperty from './getproperty/index.js'
13
- export * as hjstringify from './hjstringify/index.js'
14
13
  export * as hjparse from './hjparse/index.js'
14
+ export * as hjstringify from './hjstringify/index.js'
15
15
  export * as if from './if/index.js'
16
16
  export * as initialize from './initialize/index.js'
17
17
  export * as join from './join/index.js'
18
18
  export * as length from './length/index.js'
19
- export * as map from './map/index.js'
20
19
  export * as negate from './negate/index.js'
20
+ export * as map from './map/index.js'
21
21
  export * as notrailing from './notrailing/index.js'
22
22
  export * as or from './or/index.js'
23
23
  export * as pickrandom from './pickrandom/index.js'
@@ -26,27 +26,27 @@ export * as print from './print/index.js'
26
26
  export * as push from './push/index.js'
27
27
  export * as pusheach from './pusheach/index.js'
28
28
  export * as recordtoarray from './recordtoarray/index.js'
29
- export * as removeclass from './removeclass/index.js'
30
29
  export * as removeattribute from './removeattribute/index.js'
30
+ export * as removeclass from './removeclass/index.js'
31
31
  export * as renameproperty from './renameproperty/index.js'
32
32
  export * as replace from './replace/index.js'
33
- export * as set from './set/index.js'
34
33
  export * as select from './select/index.js'
34
+ export * as set from './set/index.js'
35
35
  export * as setattribute from './setattribute/index.js'
36
+ export * as setproperty from './setproperty/index.js'
36
37
  export * as sorton from './sorton/index.js'
37
38
  export * as split from './split/index.js'
38
39
  export * as spread from './spread/index.js'
39
40
  export * as toarray from './toarray/index.js'
41
+ export * as toboolean from './toboolean/index.js'
40
42
  export * as toelement from './toelement/index.js'
41
- export * as setproperty from './setproperty/index.js'
42
43
  export * as toggleclass from './toggleclass/index.js'
43
44
  export * as tonodelist from './tonodelist/index.js'
44
45
  export * as tonull from './tonull/index.js'
45
- export * as toboolean from './toboolean/index.js'
46
- export * as toref from './toref/index.js'
46
+ export * as tonumber from './tonumber/index.js'
47
47
  export * as torecord from './torecord/index.js'
48
+ export * as toref from './toref/index.js'
48
49
  export * as tostring from './tostring/index.js'
49
50
  export * as totext from './totext/index.js'
50
51
  export * as transformselected from './transformselected/index.js'
51
52
  export * as trim from './trim/index.js'
52
- export * as tonumber from './tonumber/index.js'
@@ -5,19 +5,19 @@ export * as append from './append/index.js'
5
5
  export * as at from './at/index.js'
6
6
  export * as call from './call/index.js'
7
7
  export * as clone from './clone/index.js'
8
- export * as equals from './equals/index.js'
9
8
  export * as deleteproperties from './deleteproperties/index.js'
9
+ export * as equals from './equals/index.js'
10
10
  export * as getattribute from './getattribute/index.js'
11
11
  export * as getproperties from './getproperties/index.js'
12
12
  export * as getproperty from './getproperty/index.js'
13
- export * as hjstringify from './hjstringify/index.js'
14
13
  export * as hjparse from './hjparse/index.js'
14
+ export * as hjstringify from './hjstringify/index.js'
15
15
  export * as if from './if/index.js'
16
16
  export * as initialize from './initialize/index.js'
17
17
  export * as join from './join/index.js'
18
18
  export * as length from './length/index.js'
19
- export * as map from './map/index.js'
20
19
  export * as negate from './negate/index.js'
20
+ export * as map from './map/index.js'
21
21
  export * as notrailing from './notrailing/index.js'
22
22
  export * as or from './or/index.js'
23
23
  export * as pickrandom from './pickrandom/index.js'
@@ -26,27 +26,27 @@ export * as print from './print/index.js'
26
26
  export * as push from './push/index.js'
27
27
  export * as pusheach from './pusheach/index.js'
28
28
  export * as recordtoarray from './recordtoarray/index.js'
29
- export * as removeclass from './removeclass/index.js'
30
29
  export * as removeattribute from './removeattribute/index.js'
30
+ export * as removeclass from './removeclass/index.js'
31
31
  export * as renameproperty from './renameproperty/index.js'
32
32
  export * as replace from './replace/index.js'
33
- export * as set from './set/index.js'
34
33
  export * as select from './select/index.js'
34
+ export * as set from './set/index.js'
35
35
  export * as setattribute from './setattribute/index.js'
36
+ export * as setproperty from './setproperty/index.js'
36
37
  export * as sorton from './sorton/index.js'
37
38
  export * as split from './split/index.js'
38
39
  export * as spread from './spread/index.js'
39
40
  export * as toarray from './toarray/index.js'
41
+ export * as toboolean from './toboolean/index.js'
40
42
  export * as toelement from './toelement/index.js'
41
- export * as setproperty from './setproperty/index.js'
42
43
  export * as toggleclass from './toggleclass/index.js'
43
44
  export * as tonodelist from './tonodelist/index.js'
44
45
  export * as tonull from './tonull/index.js'
45
- export * as toboolean from './toboolean/index.js'
46
- export * as toref from './toref/index.js'
46
+ export * as tonumber from './tonumber/index.js'
47
47
  export * as torecord from './torecord/index.js'
48
+ export * as toref from './toref/index.js'
48
49
  export * as tostring from './tostring/index.js'
49
50
  export * as totext from './totext/index.js'
50
51
  export * as transformselected from './transformselected/index.js'
51
52
  export * as trim from './trim/index.js'
52
- export * as tonumber from './tonumber/index.js'
@@ -1,13 +1,13 @@
1
1
  export * as any from './any/index.js'
2
+ export * as array from './array/index.js'
2
3
  export * as boolean from './boolean/index.js'
3
4
  export * as element from './element/index.js'
4
5
  export * as get from './get/index.js'
5
6
  export * as guess from './guess/index.js'
6
- export * as nodelist from './nodelist/index.js'
7
7
  export * as null from './null/index.js'
8
8
  export * as number from './number/index.js'
9
+ export * as nodelist from './nodelist/index.js'
9
10
  export * as record from './record/index.js'
10
11
  export * as ref from './ref/index.js'
11
- export * as text from './text/index.js'
12
12
  export * as string from './string/index.js'
13
- export * as array from './array/index.js'
13
+ export * as text from './text/index.js'
@@ -1,13 +1,13 @@
1
1
  export * as any from './any/index.js'
2
+ export * as array from './array/index.js'
2
3
  export * as boolean from './boolean/index.js'
3
4
  export * as element from './element/index.js'
4
5
  export * as get from './get/index.js'
5
6
  export * as guess from './guess/index.js'
6
- export * as nodelist from './nodelist/index.js'
7
7
  export * as null from './null/index.js'
8
8
  export * as number from './number/index.js'
9
+ export * as nodelist from './nodelist/index.js'
9
10
  export * as record from './record/index.js'
10
11
  export * as ref from './ref/index.js'
11
- export * as text from './text/index.js'
12
12
  export * as string from './string/index.js'
13
- export * as array from './array/index.js'
13
+ export * as text from './text/index.js'
@@ -6,5 +6,5 @@ export * as insertNode from './insert-node/index.js'
6
6
  export * as placeholders from './placeholders/index.js'
7
7
  export * as replaceInElement from './replace-in-element/index.js'
8
8
  export * as selectorToElement from './selector-to-element/index.js'
9
- export * as watchSelection from './watch-selection/index.js'
10
9
  export * as stringToNodes from './string-to-nodes/index.js'
10
+ export * as watchSelection from './watch-selection/index.js'
@@ -6,5 +6,5 @@ export * as insertNode from './insert-node/index.js'
6
6
  export * as placeholders from './placeholders/index.js'
7
7
  export * as replaceInElement from './replace-in-element/index.js'
8
8
  export * as selectorToElement from './selector-to-element/index.js'
9
- export * as watchSelection from './watch-selection/index.js'
10
9
  export * as stringToNodes from './string-to-nodes/index.js'
10
+ export * as watchSelection from './watch-selection/index.js'
@@ -1,7 +1,6 @@
1
1
  export * as arrays from './arrays/index.js'
2
2
  export * as booleans from './booleans/index.js'
3
3
  export * as colors from './colors/index.js'
4
- export * as css from './css/index.js'
5
4
  export * as errors from './errors/index.js'
6
5
  export * as html from './html/index.js'
7
6
  export * as misc from './misc/index.js'
@@ -10,7 +9,8 @@ export * as objects from './objects/index.js'
10
9
  export * as optim from './optim/index.js'
11
10
  export * as random from './random/index.js'
12
11
  export * as regexps from './regexps/index.js'
13
- export * as sanitization from './sanitization/index.js'
14
12
  export * as strings from './strings/index.js'
13
+ export * as sanitization from './sanitization/index.js'
15
14
  export * as time from './time/index.js'
16
15
  export * as typescript from './typescript/index.js'
16
+ export * as css from './css/index.js'
package/agnostic/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  export * as arrays from './arrays/index.js'
2
2
  export * as booleans from './booleans/index.js'
3
3
  export * as colors from './colors/index.js'
4
- export * as css from './css/index.js'
5
4
  export * as errors from './errors/index.js'
6
5
  export * as html from './html/index.js'
7
6
  export * as misc from './misc/index.js'
@@ -10,7 +9,8 @@ export * as objects from './objects/index.js'
10
9
  export * as optim from './optim/index.js'
11
10
  export * as random from './random/index.js'
12
11
  export * as regexps from './regexps/index.js'
13
- export * as sanitization from './sanitization/index.js'
14
12
  export * as strings from './strings/index.js'
13
+ export * as sanitization from './sanitization/index.js'
15
14
  export * as time from './time/index.js'
16
15
  export * as typescript from './typescript/index.js'
16
+ export * as css from './css/index.js'
@@ -1,12 +1,12 @@
1
1
  export * as assert from './assert/index.js'
2
- export * as connection from './connection/index.js'
3
2
  export * as cast from './cast/index.js'
3
+ export * as connection from './connection/index.js'
4
4
  export * as crawler from './crawler/index.js'
5
5
  export * as crossenv from './crossenv/index.js'
6
+ export * as dataSize from './data-size/index.js'
7
+ export * as isConstructorFunction from './is-constructor-function/index.js'
6
8
  export * as isNullish from './is-nullish/index.js'
7
9
  export * as logs from './logs/index.js'
8
10
  export * as loremIpsum from './lorem-ipsum/index.js'
9
11
  export * as normalizeExtension from './normalize-extension/index.js'
10
12
  export * as outcome from './outcome/index.js'
11
- export * as dataSize from './data-size/index.js'
12
- export * as isConstructorFunction from './is-constructor-function/index.js'
@@ -1,12 +1,12 @@
1
1
  export * as assert from './assert/index.js'
2
- export * as connection from './connection/index.js'
3
2
  export * as cast from './cast/index.js'
3
+ export * as connection from './connection/index.js'
4
4
  export * as crawler from './crawler/index.js'
5
5
  export * as crossenv from './crossenv/index.js'
6
+ export * as dataSize from './data-size/index.js'
7
+ export * as isConstructorFunction from './is-constructor-function/index.js'
6
8
  export * as isNullish from './is-nullish/index.js'
7
9
  export * as logs from './logs/index.js'
8
10
  export * as loremIpsum from './lorem-ipsum/index.js'
9
11
  export * as normalizeExtension from './normalize-extension/index.js'
10
12
  export * as outcome from './outcome/index.js'
11
- export * as dataSize from './data-size/index.js'
12
- export * as isConstructorFunction from './is-constructor-function/index.js'
@@ -1,3 +1,3 @@
1
- export * as logger from './logger/index.js'
2
1
  export * as makeTextBlock from './make-text-block/index.js'
3
2
  export * as styles from './styles/index.js'
3
+ export * as logger from './logger/index.js'
@@ -1,3 +1,3 @@
1
- export * as logger from './logger/index.js'
2
1
  export * as makeTextBlock from './make-text-block/index.js'
3
2
  export * as styles from './styles/index.js'
3
+ export * as logger from './logger/index.js'
@@ -1,6 +1,6 @@
1
1
  export * as absoluteModulo from './absolute-modulo/index.js'
2
2
  export * as approximateRational from './approximate-rational/index.js'
3
3
  export * as clamp from './clamp/index.js'
4
+ export * as interpolate from './interpolate/index.js'
4
5
  export * as geometricProgressions from './geometric-progressions/index.js'
5
6
  export * as round from './round/index.js'
6
- export * as interpolate from './interpolate/index.js'
@@ -1,6 +1,6 @@
1
1
  export * as absoluteModulo from './absolute-modulo/index.js'
2
2
  export * as approximateRational from './approximate-rational/index.js'
3
3
  export * as clamp from './clamp/index.js'
4
+ export * as interpolate from './interpolate/index.js'
4
5
  export * as geometricProgressions from './geometric-progressions/index.js'
5
6
  export * as round from './round/index.js'
6
- export * as interpolate from './interpolate/index.js'
@@ -1,2 +1,2 @@
1
- export * as throttleDebounce from './throttle-debounce/index.js'
2
1
  export * as memoize from './memoize/index.js'
2
+ export * as throttleDebounce from './throttle-debounce/index.js'
@@ -1,2 +1,2 @@
1
- export * as throttleDebounce from './throttle-debounce/index.js'
2
1
  export * as memoize from './memoize/index.js'
2
+ export * as throttleDebounce from './throttle-debounce/index.js'
@@ -1,8 +1,8 @@
1
- export * as charCodes from './char-codes/index.js'
2
1
  export * as matches from './matches/index.js'
2
+ export * as charCodes from './char-codes/index.js'
3
3
  export * as normalizeIndent from './normalize-indent/index.js'
4
4
  export * as parseTable from './parse-table/index.js'
5
5
  export * as replaceAll from './replace-all/index.js'
6
- export * as toAlphanum from './to-alphanum/index.js'
7
6
  export * as splitTrim from './split-trim/index.js'
7
+ export * as toAlphanum from './to-alphanum/index.js'
8
8
  export * as trim from './trim/index.js'
@@ -1,8 +1,8 @@
1
- export * as charCodes from './char-codes/index.js'
2
1
  export * as matches from './matches/index.js'
2
+ export * as charCodes from './char-codes/index.js'
3
3
  export * as normalizeIndent from './normalize-indent/index.js'
4
4
  export * as parseTable from './parse-table/index.js'
5
5
  export * as replaceAll from './replace-all/index.js'
6
- export * as toAlphanum from './to-alphanum/index.js'
7
6
  export * as splitTrim from './split-trim/index.js'
7
+ export * as toAlphanum from './to-alphanum/index.js'
8
8
  export * as trim from './trim/index.js'
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Formats a `Date` object into a string according to a custom template and locale.
2
+ * Formats a `Date` into a string according to a custom template and locale.
3
3
  *
4
4
  * Supported tokens (placeholders must be wrapped in `{{...}}`):
5
5
  *
@@ -42,7 +42,9 @@
42
42
  * @param date - The `Date` object to format.
43
43
  * @param format - The template string containing tokens.
44
44
  * @param locale - Optional locale code (default: `'en'`).
45
- * @returns Formatted date string.
45
+ * @returns Formatted date string. An unknown token is left untouched, braces
46
+ * included.
47
+ * @see {@link getDateParts} to reach the same parts as plain values, unpadded.
46
48
  *
47
49
  * @example
48
50
  * formatDate(new Date(2026, 0, 1, 15, 5), '{{YYYY}}-{{MM}}-{{DD}} {{hh}}:{{mm}} {{A}}')
@@ -1,5 +1,42 @@
1
+ import { getDateParts } from './parts.js';
2
+ // Alternation is ordered, and the first branch that fits wins — so the longest
3
+ // tokens come first. `MM` ahead of `MMMM` would only work by backtracking off the
4
+ // closing braces, which is true but not something a reader should have to derive.
5
+ const tokenRegexp = /\{\{(MMMM|YYYY|MMM|DD|dd|MM|YY|HH|hh|mm|ss|th|ms|D|d|M|H|h|m|s|A|a)\}\}/gv;
6
+ function pad(value, length) {
7
+ return `${value}`.padStart(length, '0');
8
+ }
9
+ /**
10
+ * How each token renders the parts it reads. This is where padding and
11
+ * truncation live — {@link getDateParts} hands over plain quantities, and the
12
+ * padded tokens are the same quantity written differently.
13
+ */
14
+ const renderers = {
15
+ 'D': parts => `${parts.D}`,
16
+ 'DD': parts => pad(parts.D, 2),
17
+ 'd': parts => parts.d,
18
+ 'dd': parts => parts.dd,
19
+ 'M': parts => `${parts.M}`,
20
+ 'MM': parts => pad(parts.M, 2),
21
+ 'MMM': parts => parts.MMM,
22
+ 'MMMM': parts => parts.MMMM,
23
+ 'YY': parts => `${parts.YYYY}`.slice(-2),
24
+ 'YYYY': parts => `${parts.YYYY}`,
25
+ 'H': parts => `${parts.H}`,
26
+ 'HH': parts => pad(parts.H, 2),
27
+ 'h': parts => `${parts.h}`,
28
+ 'hh': parts => pad(parts.h, 2),
29
+ 'm': parts => `${parts.m}`,
30
+ 'mm': parts => pad(parts.m, 2),
31
+ 's': parts => `${parts.s}`,
32
+ 'ss': parts => pad(parts.s, 2),
33
+ 'ms': parts => pad(parts.ms, 3),
34
+ 'A': parts => parts.A,
35
+ 'a': parts => parts.a,
36
+ 'th': parts => parts.th
37
+ };
1
38
  /**
2
- * Formats a `Date` object into a string according to a custom template and locale.
39
+ * Formats a `Date` into a string according to a custom template and locale.
3
40
  *
4
41
  * Supported tokens (placeholders must be wrapped in `{{...}}`):
5
42
  *
@@ -42,103 +79,15 @@
42
79
  * @param date - The `Date` object to format.
43
80
  * @param format - The template string containing tokens.
44
81
  * @param locale - Optional locale code (default: `'en'`).
45
- * @returns Formatted date string.
82
+ * @returns Formatted date string. An unknown token is left untouched, braces
83
+ * included.
84
+ * @see {@link getDateParts} to reach the same parts as plain values, unpadded.
46
85
  *
47
86
  * @example
48
87
  * formatDate(new Date(2026, 0, 1, 15, 5), '{{YYYY}}-{{MM}}-{{DD}} {{hh}}:{{mm}} {{A}}')
49
88
  * // => "2026-01-01 03:05 PM"
50
89
  */
51
90
  export function formatDate(date, format, locale = 'en') {
52
- if (Intl
53
- .DateTimeFormat
54
- .supportedLocalesOf(locale).length === 0) {
55
- // eslint-disable-next-line no-param-reassign
56
- locale = 'en';
57
- }
58
- const day = date.getDate();
59
- const dayOfWeek = date.getDay();
60
- const month = date.getMonth();
61
- const year = date.getFullYear();
62
- const hours = date.getHours();
63
- const minutes = date.getMinutes();
64
- const seconds = date.getSeconds();
65
- const isPM = hours >= 12;
66
- const shortDateNames = [...Array(7)].map((_, i) => new Intl.DateTimeFormat(locale, { weekday: 'short' }).format(new Date(2023, 0, i + 1)));
67
- const dateNames = [...Array(7)].map((_, i) => new Intl.DateTimeFormat(locale, { weekday: 'long' }).format(new Date(2023, 0, i + 1)));
68
- const shortMonthNames = [...Array(12)].map((_, i) => new Intl.DateTimeFormat(locale, { month: 'short' }).format(new Date(2023, i, 1)));
69
- const monthNames = [...Array(12)].map((_, i) => new Intl.DateTimeFormat(locale, { month: 'long' }).format(new Date(2023, i, 1)));
70
- const replacements = {
71
- 'DD': () => String(day).padStart(2, '0'),
72
- 'D': () => String(day),
73
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
74
- 'dd': () => dateNames[dayOfWeek],
75
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
76
- 'd': () => shortDateNames[dayOfWeek],
77
- 'MM': () => String(month + 1).padStart(2, '0'),
78
- 'M': () => String(month + 1),
79
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
80
- 'MMMM': () => monthNames[month],
81
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
82
- 'MMM': () => shortMonthNames[month],
83
- 'YYYY': () => String(year),
84
- 'YY': () => String(year).slice(-2),
85
- 'hh': () => String(hours % 12 !== 0 ? hours % 12 : 12).padStart(2, '0'),
86
- 'h': () => String(hours % 12 !== 0 ? hours % 12 : 12),
87
- 'HH': () => String(hours).padStart(2, '0'),
88
- 'H': () => String(hours),
89
- 'mm': () => String(minutes).padStart(2, '0'),
90
- 'm': () => String(minutes),
91
- 'ss': () => String(seconds).padStart(2, '0'),
92
- 's': () => String(seconds),
93
- 'ms': () => String(date.getMilliseconds()).padStart(3, '0'),
94
- 'A': () => (isPM ? 'PM' : 'AM'),
95
- 'a': () => (isPM ? 'pm' : 'am'),
96
- 'th': () => {
97
- if (locale.startsWith('fr') && day === 1)
98
- return 'er';
99
- if (locale.startsWith('en')) {
100
- const mod10 = day % 10;
101
- const mod100 = day % 100;
102
- if (mod10 === 1 && mod100 !== 11)
103
- return 'st';
104
- if (mod10 === 2 && mod100 !== 12)
105
- return 'nd';
106
- if (mod10 === 3 && mod100 !== 13)
107
- return 'rd';
108
- return 'th';
109
- }
110
- return '';
111
- }
112
- };
113
- const regexp = /\{\{(DD|D|dd|d|MM|M|MMMM|MMM|YYYY|YY|HH|H|hh|h|mm|m|ss|s|A|a|th|ms)\}\}/gv;
114
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
115
- return format.replace(regexp, (match, token) => replacements[token]?.() ?? match);
91
+ const parts = getDateParts(date, locale);
92
+ return format.replace(tokenRegexp, (_match, token) => renderers[token](parts));
116
93
  }
117
- // [WIP] this was removed since JavaScript's Date object don't hold timezone data
118
- // those templates would only reflect the curent client's timezone, no matter what the input Date obj was
119
- // 'ZZ': () => {
120
- // const timezoneOffset = date.getTimezoneOffset()
121
- // const offsetHours = Math.floor(Math.abs(timezoneOffset) / 60)
122
- // const offsetMinutes = Math.abs(timezoneOffset) % 60
123
- // const sign = timezoneOffset > 0 ? '-' : '+'
124
- // return `${sign}${String(offsetHours).padStart(2, '0')}:${String(offsetMinutes).padStart(2, '0')}`
125
- // },
126
- // 'Z': () => {
127
- // const timezoneOffset = date.getTimezoneOffset()
128
- // if (timezoneOffset === 0) return 'Z'
129
- // const offsetHours = Math.floor(Math.abs(timezoneOffset) / 60)
130
- // const offsetMinutes = Math.abs(timezoneOffset) % 60
131
- // const sign = timezoneOffset > 0 ? '-' : '+'
132
- // return `${sign}${String(offsetHours).padStart(2, '0')}:${String(offsetMinutes).padStart(2, '0')}`
133
- // },
134
- // 'z': () => {
135
- // return Intl.DateTimeFormat(locale, { timeZoneName: 'short' })
136
- // .formatToParts(date)
137
- // .find(part => part.type === 'timeZoneName')?.value || ''
138
- // },
139
- // 'zz': () => {
140
- // return Intl.DateTimeFormat(locale, { timeZoneName: 'long' })
141
- // .formatToParts(date)
142
- // .find(part => part.type === 'timeZoneName')?.value || ''
143
- // },
144
- // 'tz': () => Intl.DateTimeFormat().resolvedOptions().timeZone || ''
@@ -0,0 +1,154 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { formatDate } from './index.js';
3
+ import { getDateParts } from './parts.js';
4
+ // Thursday, January 1st 2026, 15:05:09.042 — read in the runtime's own timezone,
5
+ // which is also the one the fixture is built in, so the tests hold anywhere.
6
+ const thursdayAfternoon = new Date(2026, 0, 1, 15, 5, 9, 42);
7
+ describe('formatDate', () => {
8
+ describe('template', () => {
9
+ it('fills a template with the parts of the date', () => {
10
+ expect(formatDate(thursdayAfternoon, '{{YYYY}}-{{MM}}-{{DD}} {{hh}}:{{mm}} {{A}}'))
11
+ .toBe('2026-01-01 03:05 PM');
12
+ });
13
+ it('keeps whatever sits outside the placeholders', () => {
14
+ expect(formatDate(thursdayAfternoon, 'le {{D}} {{MMMM}} {{YYYY}}', 'fr'))
15
+ .toBe('le 1 janvier 2026');
16
+ });
17
+ it('does not substitute a bare letter outside a placeholder', () => {
18
+ expect(formatDate(thursdayAfternoon, 'D M Y {{D}}')).toBe('D M Y 1');
19
+ });
20
+ it('substitutes every occurrence of a repeated token', () => {
21
+ expect(formatDate(thursdayAfternoon, '{{D}}/{{D}}')).toBe('1/1');
22
+ });
23
+ it('leaves an unknown token untouched, braces included', () => {
24
+ expect(formatDate(thursdayAfternoon, '{{ZZ}} {{YYYY}}')).toBe('{{ZZ}} 2026');
25
+ });
26
+ });
27
+ describe('padding', () => {
28
+ it('pads the doubled tokens to two digits', () => {
29
+ expect(formatDate(thursdayAfternoon, '{{DD}} {{MM}} {{HH}} {{hh}} {{mm}} {{ss}}'))
30
+ .toBe('01 01 15 03 05 09');
31
+ });
32
+ it('leaves the bare twins unpadded', () => {
33
+ expect(formatDate(thursdayAfternoon, '{{D}} {{M}} {{H}} {{h}} {{m}} {{s}}'))
34
+ .toBe('1 1 15 3 5 9');
35
+ });
36
+ it('pads milliseconds to three digits', () => {
37
+ expect(formatDate(thursdayAfternoon, '{{ms}}')).toBe('042');
38
+ });
39
+ it('truncates YY to the last two digits of the year', () => {
40
+ expect(formatDate(thursdayAfternoon, '{{YY}}')).toBe('26');
41
+ });
42
+ });
43
+ describe('12-hour clock', () => {
44
+ it('writes midnight as 12 AM', () => {
45
+ expect(formatDate(new Date(2026, 0, 1, 0, 30), '{{h}}:{{mm}} {{A}}')).toBe('12:30 AM');
46
+ });
47
+ it('writes noon as 12 PM', () => {
48
+ expect(formatDate(new Date(2026, 0, 1, 12, 30), '{{h}}:{{mm}} {{A}}')).toBe('12:30 PM');
49
+ });
50
+ it('starts the afternoon back at 1', () => {
51
+ expect(formatDate(new Date(2026, 0, 1, 13), '{{h}} {{a}}')).toBe('1 pm');
52
+ });
53
+ });
54
+ describe('locales', () => {
55
+ it('names the weekday and the month in English by default', () => {
56
+ expect(formatDate(thursdayAfternoon, '{{dd}} {{d}} {{MMMM}} {{MMM}}'))
57
+ .toBe('Thursday Thu January Jan');
58
+ });
59
+ it('names them in the requested locale', () => {
60
+ expect(formatDate(thursdayAfternoon, '{{dd}} {{MMMM}}', 'fr')).toBe('jeudi janvier');
61
+ });
62
+ });
63
+ describe('ordinal suffix', () => {
64
+ it('follows the English rule', () => {
65
+ const suffix = (day) => formatDate(new Date(2026, 0, day), '{{D}}{{th}}');
66
+ expect(suffix(1)).toBe('1st');
67
+ expect(suffix(2)).toBe('2nd');
68
+ expect(suffix(3)).toBe('3rd');
69
+ expect(suffix(4)).toBe('4th');
70
+ expect(suffix(21)).toBe('21st');
71
+ expect(suffix(22)).toBe('22nd');
72
+ expect(suffix(23)).toBe('23rd');
73
+ });
74
+ it('keeps the teens on th, where the last digit would say otherwise', () => {
75
+ const suffix = (day) => formatDate(new Date(2026, 0, day), '{{D}}{{th}}');
76
+ expect(suffix(11)).toBe('11th');
77
+ expect(suffix(12)).toBe('12th');
78
+ expect(suffix(13)).toBe('13th');
79
+ });
80
+ it('marks only the 1st in French', () => {
81
+ expect(formatDate(new Date(2026, 0, 1), '{{D}}{{th}}', 'fr')).toBe('1er');
82
+ expect(formatDate(new Date(2026, 0, 2), '{{D}}{{th}}', 'fr')).toBe('2');
83
+ });
84
+ });
85
+ });
86
+ describe('getDateParts', () => {
87
+ describe('quantities', () => {
88
+ it('hands over plain numbers, unpadded', () => {
89
+ expect(getDateParts(thursdayAfternoon)).toMatchObject({
90
+ D: 1,
91
+ M: 1,
92
+ YYYY: 2026,
93
+ H: 15,
94
+ h: 3,
95
+ m: 5,
96
+ s: 9,
97
+ ms: 42
98
+ });
99
+ });
100
+ it('numbers the months from 1, where Date numbers them from 0', () => {
101
+ expect(getDateParts(new Date(2026, 11, 25)).M).toBe(12);
102
+ });
103
+ it('reaches every part under its readable name too', () => {
104
+ const parts = getDateParts(thursdayAfternoon);
105
+ expect(parts).toMatchObject({
106
+ dayOfMonth: parts.D,
107
+ shortWeekdayName: parts.d,
108
+ fullWeekdayName: parts.dd,
109
+ monthNumber: parts.M,
110
+ shortMonthName: parts.MMM,
111
+ fullMonthName: parts.MMMM,
112
+ year: parts.YYYY,
113
+ hours24: parts.H,
114
+ hours12: parts.h,
115
+ minutes: parts.m,
116
+ seconds: parts.s,
117
+ milliseconds: parts.ms,
118
+ upperCaseMeridiem: parts.A,
119
+ lowerCaseMeridiem: parts.a,
120
+ dayOrdinalSuffix: parts.th
121
+ });
122
+ });
123
+ });
124
+ describe('12-hour clock', () => {
125
+ it('reads both midnight and noon as 12', () => {
126
+ expect(getDateParts(new Date(2026, 0, 1, 0)).h).toBe(12);
127
+ expect(getDateParts(new Date(2026, 0, 1, 12)).h).toBe(12);
128
+ });
129
+ it('splits the meridiem at noon', () => {
130
+ expect(getDateParts(new Date(2026, 0, 1, 11, 59))).toMatchObject({ A: 'AM', a: 'am' });
131
+ expect(getDateParts(new Date(2026, 0, 1, 12, 0))).toMatchObject({ A: 'PM', a: 'pm' });
132
+ });
133
+ });
134
+ describe('locales', () => {
135
+ it('localises the weekday and month names', () => {
136
+ expect(getDateParts(thursdayAfternoon, 'fr')).toMatchObject({
137
+ d: 'jeu.',
138
+ dd: 'jeudi',
139
+ MMM: 'janv.',
140
+ MMMM: 'janvier'
141
+ });
142
+ });
143
+ it('falls back to English on a locale the runtime does not support', () => {
144
+ expect(getDateParts(thursdayAfternoon, 'xx')).toMatchObject({
145
+ dd: 'Thursday',
146
+ MMMM: 'January',
147
+ th: 'st'
148
+ });
149
+ });
150
+ it('leaves the ordinal suffix empty for a locale that has no rule here', () => {
151
+ expect(getDateParts(thursdayAfternoon, 'es').th).toBe('');
152
+ });
153
+ });
154
+ });