@markuplint/types 1.0.0-dev.20211213.0

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 (177) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +117 -0
  3. package/extends.json +12 -0
  4. package/gen/specific-schema.json +98 -0
  5. package/gen/types.ts +66 -0
  6. package/lib/check-multi-types.d.ts +2 -0
  7. package/lib/check-multi-types.js +29 -0
  8. package/lib/check.d.ts +8 -0
  9. package/lib/check.js +49 -0
  10. package/lib/check.spec.d.ts +1 -0
  11. package/lib/check.spec.js +57 -0
  12. package/lib/css-syntax.d.ts +2 -0
  13. package/lib/css-syntax.js +141 -0
  14. package/lib/css-syntax.spec.d.ts +1 -0
  15. package/lib/css-syntax.spec.js +157 -0
  16. package/lib/debug.d.ts +2 -0
  17. package/lib/debug.js +6 -0
  18. package/lib/defs.d.ts +3 -0
  19. package/lib/defs.js +752 -0
  20. package/lib/enum.d.ts +3 -0
  21. package/lib/enum.js +26 -0
  22. package/lib/get-candicate.d.ts +3 -0
  23. package/lib/get-candicate.js +26 -0
  24. package/lib/index.d.ts +3 -0
  25. package/lib/index.js +6 -0
  26. package/lib/keyword-type.d.ts +3 -0
  27. package/lib/keyword-type.js +46 -0
  28. package/lib/list.d.ts +3 -0
  29. package/lib/list.js +29 -0
  30. package/lib/list.spec.d.ts +1 -0
  31. package/lib/list.spec.js +129 -0
  32. package/lib/match-result.d.ts +9 -0
  33. package/lib/match-result.js +33 -0
  34. package/lib/number.d.ts +3 -0
  35. package/lib/number.js +41 -0
  36. package/lib/primitive/index.d.ts +7 -0
  37. package/lib/primitive/index.js +17 -0
  38. package/lib/primitive/index.spec.d.ts +1 -0
  39. package/lib/primitive/index.spec.js +62 -0
  40. package/lib/primitive/is-float.d.ts +6 -0
  41. package/lib/primitive/is-float.js +12 -0
  42. package/lib/primitive/is-int.d.ts +6 -0
  43. package/lib/primitive/is-int.js +12 -0
  44. package/lib/primitive/is-non-zero-uint.d.ts +6 -0
  45. package/lib/primitive/is-non-zero-uint.js +12 -0
  46. package/lib/primitive/is-quantity.d.ts +7 -0
  47. package/lib/primitive/is-quantity.js +41 -0
  48. package/lib/primitive/is-uint.d.ts +8 -0
  49. package/lib/primitive/is-uint.js +19 -0
  50. package/lib/primitive/range.d.ts +8 -0
  51. package/lib/primitive/range.js +18 -0
  52. package/lib/primitive/split-unit.d.ts +9 -0
  53. package/lib/primitive/split-unit.js +24 -0
  54. package/lib/rfc/is-bcp-47.d.ts +5 -0
  55. package/lib/rfc/is-bcp-47.js +14 -0
  56. package/lib/rfc/is-bcp-47.spec.d.ts +1 -0
  57. package/lib/rfc/is-bcp-47.spec.js +19 -0
  58. package/lib/token/index.d.ts +2 -0
  59. package/lib/token/index.js +7 -0
  60. package/lib/token/token-collection.d.ts +62 -0
  61. package/lib/token/token-collection.js +383 -0
  62. package/lib/token/token-collection.spec.d.ts +1 -0
  63. package/lib/token/token-collection.spec.js +144 -0
  64. package/lib/token/token.d.ts +55 -0
  65. package/lib/token/token.js +128 -0
  66. package/lib/types.d.ts +78 -0
  67. package/lib/types.js +2 -0
  68. package/lib/types.schema.d.ts +54 -0
  69. package/lib/types.schema.js +8 -0
  70. package/lib/w3c/check-serialized-permissions-policy.d.ts +15 -0
  71. package/lib/w3c/check-serialized-permissions-policy.js +251 -0
  72. package/lib/w3c/check-serialized-permissions-policy.spec.d.ts +1 -0
  73. package/lib/w3c/check-serialized-permissions-policy.spec.js +26 -0
  74. package/lib/whatwg/check-autocomplete.d.ts +5 -0
  75. package/lib/whatwg/check-autocomplete.js +282 -0
  76. package/lib/whatwg/check-autocomplete.spec.d.ts +1 -0
  77. package/lib/whatwg/check-autocomplete.spec.js +370 -0
  78. package/lib/whatwg/check-datetime/date-string.d.ts +5 -0
  79. package/lib/whatwg/check-datetime/date-string.js +31 -0
  80. package/lib/whatwg/check-datetime/datetime-tokens.d.ts +3 -0
  81. package/lib/whatwg/check-datetime/datetime-tokens.js +509 -0
  82. package/lib/whatwg/check-datetime/duration-string.d.ts +6 -0
  83. package/lib/whatwg/check-datetime/duration-string.js +322 -0
  84. package/lib/whatwg/check-datetime/global-date-and-time-string.d.ts +5 -0
  85. package/lib/whatwg/check-datetime/global-date-and-time-string.js +66 -0
  86. package/lib/whatwg/check-datetime/index.d.ts +5 -0
  87. package/lib/whatwg/check-datetime/index.js +35 -0
  88. package/lib/whatwg/check-datetime/index.spec.d.ts +1 -0
  89. package/lib/whatwg/check-datetime/index.spec.js +318 -0
  90. package/lib/whatwg/check-datetime/local-date-and-time-string.d.ts +9 -0
  91. package/lib/whatwg/check-datetime/local-date-and-time-string.js +116 -0
  92. package/lib/whatwg/check-datetime/month-string.d.ts +5 -0
  93. package/lib/whatwg/check-datetime/month-string.js +20 -0
  94. package/lib/whatwg/check-datetime/time-string.d.ts +5 -0
  95. package/lib/whatwg/check-datetime/time-string.js +35 -0
  96. package/lib/whatwg/check-datetime/time-zone-offset-string.d.ts +7 -0
  97. package/lib/whatwg/check-datetime/time-zone-offset-string.js +75 -0
  98. package/lib/whatwg/check-datetime/week-string.d.ts +5 -0
  99. package/lib/whatwg/check-datetime/week-string.js +29 -0
  100. package/lib/whatwg/check-datetime/year-string.d.ts +5 -0
  101. package/lib/whatwg/check-datetime/year-string.js +20 -0
  102. package/lib/whatwg/check-datetime/yearless-date-string.d.ts +5 -0
  103. package/lib/whatwg/check-datetime/yearless-date-string.js +27 -0
  104. package/lib/whatwg/check-mime-type.d.ts +11 -0
  105. package/lib/whatwg/check-mime-type.js +42 -0
  106. package/lib/whatwg/check-mime-type.spec.d.ts +1 -0
  107. package/lib/whatwg/check-mime-type.spec.js +58 -0
  108. package/lib/whatwg/is-abs-url.d.ts +15 -0
  109. package/lib/whatwg/is-abs-url.js +34 -0
  110. package/lib/whatwg/is-abs-url.spec.d.ts +1 -0
  111. package/lib/whatwg/is-abs-url.spec.js +8 -0
  112. package/lib/whatwg/is-browser-context-name.d.ts +11 -0
  113. package/lib/whatwg/is-browser-context-name.js +18 -0
  114. package/lib/whatwg/is-custom-element-name.d.ts +22 -0
  115. package/lib/whatwg/is-custom-element-name.js +77 -0
  116. package/lib/whatwg/is-itemprop-name.d.ts +12 -0
  117. package/lib/whatwg/is-itemprop-name.js +19 -0
  118. package/package.json +33 -0
  119. package/src/check-multi-types.ts +35 -0
  120. package/src/check.spec.ts +62 -0
  121. package/src/check.ts +48 -0
  122. package/src/css-syntax.spec.ts +167 -0
  123. package/src/css-syntax.ts +177 -0
  124. package/src/debug.ts +3 -0
  125. package/src/defs.ts +810 -0
  126. package/src/enum.ts +25 -0
  127. package/src/get-candicate.ts +24 -0
  128. package/src/index.ts +3 -0
  129. package/src/keyword-type.ts +52 -0
  130. package/src/list.spec.ts +133 -0
  131. package/src/list.ts +34 -0
  132. package/src/match-result.ts +49 -0
  133. package/src/number.ts +46 -0
  134. package/src/primitive/index.spec.ts +65 -0
  135. package/src/primitive/index.ts +7 -0
  136. package/src/primitive/is-float.ts +8 -0
  137. package/src/primitive/is-int.ts +8 -0
  138. package/src/primitive/is-non-zero-uint.ts +8 -0
  139. package/src/primitive/is-quantity.ts +38 -0
  140. package/src/primitive/is-uint.ts +15 -0
  141. package/src/primitive/range.ts +14 -0
  142. package/src/primitive/split-unit.ts +20 -0
  143. package/src/rfc/is-bcp-47.spec.ts +23 -0
  144. package/src/rfc/is-bcp-47.ts +13 -0
  145. package/src/token/index.ts +2 -0
  146. package/src/token/token-collection.spec.ts +147 -0
  147. package/src/token/token-collection.ts +444 -0
  148. package/src/token/token.ts +144 -0
  149. package/src/types.schema.ts +1059 -0
  150. package/src/types.ts +118 -0
  151. package/src/w3c/check-serialized-permissions-policy.spec.ts +27 -0
  152. package/src/w3c/check-serialized-permissions-policy.ts +287 -0
  153. package/src/whatwg/check-autocomplete.spec.ts +378 -0
  154. package/src/whatwg/check-autocomplete.ts +324 -0
  155. package/src/whatwg/check-datetime/date-string.ts +44 -0
  156. package/src/whatwg/check-datetime/datetime-tokens.ts +600 -0
  157. package/src/whatwg/check-datetime/duration-string.ts +399 -0
  158. package/src/whatwg/check-datetime/global-date-and-time-string.ts +96 -0
  159. package/src/whatwg/check-datetime/index.spec.ts +333 -0
  160. package/src/whatwg/check-datetime/index.ts +36 -0
  161. package/src/whatwg/check-datetime/local-date-and-time-string.ts +163 -0
  162. package/src/whatwg/check-datetime/month-string.ts +31 -0
  163. package/src/whatwg/check-datetime/time-string.ts +49 -0
  164. package/src/whatwg/check-datetime/time-zone-offset-string.ts +93 -0
  165. package/src/whatwg/check-datetime/week-string.ts +41 -0
  166. package/src/whatwg/check-datetime/year-string.ts +26 -0
  167. package/src/whatwg/check-datetime/yearless-date-string.ts +38 -0
  168. package/src/whatwg/check-mime-type.spec.ts +59 -0
  169. package/src/whatwg/check-mime-type.ts +46 -0
  170. package/src/whatwg/is-abs-url.spec.ts +8 -0
  171. package/src/whatwg/is-abs-url.ts +31 -0
  172. package/src/whatwg/is-browser-context-name.ts +16 -0
  173. package/src/whatwg/is-custom-element-name.ts +76 -0
  174. package/src/whatwg/is-itemprop-name.ts +17 -0
  175. package/tsconfig.test.json +3 -0
  176. package/tsconfig.tsbuildinfo +1 -0
  177. package/types.schema.json +1092 -0
@@ -0,0 +1,333 @@
1
+ // @ts-nocheck
2
+
3
+ import { checkDateString } from './date-string';
4
+ import { getMaxWeekNum } from './datetime-tokens';
5
+ import { checkDurationISO8601LikeString, checkDurationComponentListString } from './duration-string';
6
+ import { checkGlobalDateAndTimeString } from './global-date-and-time-string';
7
+ import { checkLocalDateAndTimeString, checkNormalizedLocalDateAndTimeString } from './local-date-and-time-string';
8
+ import { checkMonthString } from './month-string';
9
+ import { checkTimeString } from './time-string';
10
+ import { checkTimeZoneOffsetString } from './time-zone-offset-string';
11
+ import { checkWeekString } from './week-string';
12
+ import { checkYearString } from './year-string';
13
+ import { checkYearlessDateString } from './yearless-date-string';
14
+
15
+ import { checkDateTime } from '.';
16
+
17
+ const isMonth = checkMonthString();
18
+ const isDate = checkDateString();
19
+ const isYearlessDate = checkYearlessDateString();
20
+ const isTimeString = checkTimeString();
21
+ const isLocalDateAndTime = checkLocalDateAndTimeString();
22
+ const isNormalizedLocalDateAndTime = checkNormalizedLocalDateAndTimeString();
23
+ const isTimeZoneOffset = checkTimeZoneOffsetString();
24
+ const isGlobalDateAndTime = checkGlobalDateAndTimeString();
25
+ const isWeek = checkWeekString();
26
+ const isYear = checkYearString();
27
+ const isDurationISO8601Like = checkDurationISO8601LikeString();
28
+ const isDurationComponentList = checkDurationComponentListString();
29
+ const isDateTime = checkDateTime();
30
+
31
+ test('max-week', () => {
32
+ expect(getMaxWeekNum(1976)).toBe(53);
33
+ expect(getMaxWeekNum(1977)).toBe(52);
34
+ expect(getMaxWeekNum(1978)).toBe(52);
35
+ expect(getMaxWeekNum(1979)).toBe(52);
36
+ expect(getMaxWeekNum(1981)).toBe(53);
37
+ });
38
+
39
+ test('month-string', () => {
40
+ expect(isMonth('').reason).toBe('empty-token');
41
+ expect(isMonth(' ').reason).toBe('unexpected-token');
42
+ expect(isMonth('a').reason).toBe('unexpected-token');
43
+ expect(isMonth('0').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 4 });
44
+ expect(isMonth('0000').reason).toStrictEqual({ type: 'out-of-range', gt: 0 });
45
+ expect(isMonth('0001').reason).toBe('missing-token');
46
+ expect(isMonth('0001:').reason).toBe('unexpected-token');
47
+ expect(isMonth('0001-').reason).toBe('missing-token');
48
+ expect(isMonth('0001-a').reason).toBe('unexpected-token');
49
+ expect(isMonth('0001-0').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 2, lte: 2 });
50
+ expect(isMonth('0001-001').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 2, lte: 2 });
51
+ expect(isMonth('0001-00').reason).toStrictEqual({ type: 'out-of-range', gte: 1, lte: 12 });
52
+ expect(isMonth('0001-13').reason).toStrictEqual({ type: 'out-of-range', gte: 1, lte: 12 });
53
+ expect(isMonth('0001-01').matched).toBe(true);
54
+ expect(isMonth('0001-12').matched).toBe(true);
55
+ expect(isMonth('10001-01').matched).toBe(true);
56
+ expect(isMonth('0001-01-').reason).toBe('extra-token');
57
+ });
58
+
59
+ test('date-string', () => {
60
+ expect(isDate('').reason).toBe('empty-token');
61
+ expect(isDate(' ').reason).toBe('unexpected-token');
62
+ expect(isDate('a').reason).toBe('unexpected-token');
63
+ expect(isDate('0').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 4 });
64
+ expect(isDate('0000').reason).toStrictEqual({ type: 'out-of-range', gt: 0 });
65
+ expect(isDate('2000').reason).toBe('missing-token');
66
+ expect(isDate('2000:').reason).toBe('unexpected-token');
67
+ expect(isDate('2000-').reason).toBe('missing-token');
68
+ expect(isDate('2000-a').reason).toBe('unexpected-token');
69
+ expect(isDate('2000-0').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 2, lte: 2 });
70
+ expect(isDate('2000-00').reason).toStrictEqual({ type: 'out-of-range', gte: 1, lte: 12 });
71
+ expect(isDate('2000-01').reason).toBe('missing-token');
72
+ expect(isDate('2000-01:').reason).toBe('unexpected-token');
73
+ expect(isDate('2000-01-').reason).toBe('missing-token');
74
+ expect(isDate('2000-01-a').reason).toBe('unexpected-token');
75
+ expect(isDate('2000-01-0').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 2, lte: 2 });
76
+ expect(isDate('2000-01-001').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 2, lte: 2 });
77
+ expect(isDate('2000-01-00').reason).toStrictEqual({ type: 'out-of-range', gte: 1, lte: 31 });
78
+ expect(isDate('2000-01-01').matched).toBe(true);
79
+ expect(isDate('2000-01-31').matched).toBe(true);
80
+ expect(isDate('2000-01-32').reason).toStrictEqual({ type: 'out-of-range', gte: 1, lte: 31 });
81
+ expect(isDate('2000-02-28').matched).toBe(true);
82
+ expect(isDate('2000-02-29').matched).toBe(true);
83
+ expect(isDate('2000-02-30').reason).toStrictEqual({ type: 'out-of-range', gte: 1, lte: 29 });
84
+ expect(isDate('2001-02-28').matched).toBe(true);
85
+ expect(isDate('2001-02-29').reason).toStrictEqual({ type: 'out-of-range', gte: 1, lte: 28 });
86
+ });
87
+
88
+ test('yearless-date-string', () => {
89
+ expect(isYearlessDate('').reason).toBe('empty-token');
90
+ expect(isYearlessDate(' ').reason).toBe('unexpected-token');
91
+ expect(isYearlessDate('a').reason).toBe('unexpected-token');
92
+ expect(isYearlessDate('0').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 2, lte: 2 });
93
+ expect(isYearlessDate('00').reason).toStrictEqual({ type: 'out-of-range', gte: 1, lte: 12 });
94
+ expect(isYearlessDate('01').reason).toBe('missing-token');
95
+ expect(isYearlessDate('01:').reason).toBe('unexpected-token');
96
+ expect(isYearlessDate('01-').reason).toBe('missing-token');
97
+ expect(isYearlessDate('01-a').reason).toBe('unexpected-token');
98
+ expect(isYearlessDate('01-0').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 2, lte: 2 });
99
+ expect(isYearlessDate('01-00').reason).toStrictEqual({ type: 'out-of-range', gte: 1, lte: 31 });
100
+ expect(isYearlessDate('01-01').matched).toBe(true);
101
+ expect(isYearlessDate('01-31').matched).toBe(true);
102
+ expect(isYearlessDate('01-32').reason).toStrictEqual({ type: 'out-of-range', gte: 1, lte: 31 });
103
+ expect(isYearlessDate('02-28').matched).toBe(true);
104
+ expect(isYearlessDate('02-29').matched).toBe(true);
105
+ expect(isYearlessDate('02-30').reason).toStrictEqual({ type: 'out-of-range', gte: 1, lte: 29 });
106
+ });
107
+
108
+ test('time-string', () => {
109
+ expect(isTimeString('').reason).toBe('empty-token');
110
+ expect(isTimeString(' ').reason).toBe('unexpected-token');
111
+ expect(isTimeString('a').reason).toBe('unexpected-token');
112
+ expect(isTimeString('0').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 2, lte: 2 });
113
+ expect(isTimeString('000').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 2, lte: 2 });
114
+ expect(isTimeString('24').reason).toStrictEqual({ type: 'out-of-range', gte: 0, lte: 23 });
115
+ expect(isTimeString('00').reason).toBe('missing-token');
116
+ expect(isTimeString('00-').reason).toBe('unexpected-token');
117
+ expect(isTimeString('00:').reason).toBe('missing-token');
118
+ expect(isTimeString('00:a').reason).toBe('unexpected-token');
119
+ expect(isTimeString('00:0').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 2, lte: 2 });
120
+ expect(isTimeString('00:000').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 2, lte: 2 });
121
+ expect(isTimeString('00:00').matched).toBe(true);
122
+ expect(isTimeString('00:59').matched).toBe(true);
123
+ expect(isTimeString('00:60').reason).toStrictEqual({ type: 'out-of-range', gte: 0, lte: 59 });
124
+ expect(isTimeString('00:00-').reason).toBe('unexpected-token');
125
+ expect(isTimeString('00:00:').reason).toBe('missing-token');
126
+ expect(isTimeString('00:00:a').reason).toBe('unexpected-token');
127
+ expect(isTimeString('00:00:0').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 2, lte: 2 });
128
+ expect(isTimeString('00:00:000').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 2, lte: 2 });
129
+ expect(isTimeString('00:00:00').matched).toBe(true);
130
+ expect(isTimeString('00:00:59').matched).toBe(true);
131
+ expect(isTimeString('00:00:60').reason).toStrictEqual({ type: 'out-of-range', gte: 0, lte: 59 });
132
+ expect(isTimeString('00:00:00:').reason).toBe('unexpected-token');
133
+ expect(isTimeString('00:00:00.').reason).toBe('missing-token');
134
+ expect(isTimeString('00:00:00.a').reason).toBe('unexpected-token');
135
+ expect(isTimeString('00:00:00.0').matched).toBe(true);
136
+ expect(isTimeString('00:00:00.9').matched).toBe(true);
137
+ expect(isTimeString('00:00:00.00').matched).toBe(true);
138
+ expect(isTimeString('00:00:00.99').matched).toBe(true);
139
+ expect(isTimeString('00:00:00.000').matched).toBe(true);
140
+ expect(isTimeString('00:00:00.999').matched).toBe(true);
141
+ expect(isTimeString('00:00:00.0000').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 1, lte: 3 });
142
+ expect(isTimeString('00:00:00.1000').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 1, lte: 3 });
143
+ });
144
+
145
+ test('local-date-and-time-string', () => {
146
+ expect(isLocalDateAndTime('').reason).toBe('empty-token');
147
+ expect(isLocalDateAndTime(' ').reason).toBe('unexpected-token');
148
+ expect(isLocalDateAndTime('2020-12-31').reason).toBe('missing-token');
149
+ expect(isLocalDateAndTime('2020-12-31:').reason).toBe('unexpected-token');
150
+ expect(isLocalDateAndTime('2020-12-31T').reason).toBe('missing-token');
151
+ expect(isLocalDateAndTime('2020-12-31 ').reason).toBe('missing-token');
152
+ expect(isLocalDateAndTime('2020-12-31 ').reason).toBe('unexpected-token');
153
+ expect(isLocalDateAndTime('2020-12-31T00:00:00.000').matched).toBe(true);
154
+ });
155
+
156
+ test('normalized-local-date-and-time-string', () => {
157
+ expect(isNormalizedLocalDateAndTime('').reason).toBe('empty-token');
158
+ expect(isNormalizedLocalDateAndTime(' ').reason).toBe('unexpected-token');
159
+ expect(isNormalizedLocalDateAndTime('2020-12-31').reason).toBe('missing-token');
160
+ expect(isNormalizedLocalDateAndTime('2020-12-31:').reason).toBe('unexpected-token');
161
+ expect(isNormalizedLocalDateAndTime('2020-12-31T').reason).toBe('missing-token');
162
+ expect(isNormalizedLocalDateAndTime('2020-12-31 ').reason).toBe('unexpected-token');
163
+ expect(isNormalizedLocalDateAndTime('2020-12-31T00:00').matched).toBe(true);
164
+ expect(isNormalizedLocalDateAndTime('2020-12-31T00:00:00').reason).toBe('extra-token');
165
+ expect(isNormalizedLocalDateAndTime('2020-12-31T00:00:01').matched).toBe(true);
166
+ expect(isNormalizedLocalDateAndTime('2020-12-31T00:00:00.0').reason).toBe('extra-token');
167
+ expect(isNormalizedLocalDateAndTime('2020-12-31T00:00:00.00').reason).toBe('extra-token');
168
+ expect(isNormalizedLocalDateAndTime('2020-12-31T00:00:00.000').reason).toBe('extra-token');
169
+ expect(isNormalizedLocalDateAndTime('2020-12-31T00:00:00.001').matched).toBe(true);
170
+ });
171
+
172
+ test('time-zone-offset', () => {
173
+ expect(isTimeZoneOffset('').reason).toBe('empty-token');
174
+ expect(isTimeZoneOffset(' ').reason).toBe('unexpected-token');
175
+ expect(isTimeZoneOffset('a').reason).toBe('unexpected-token');
176
+ expect(isTimeZoneOffset('z').reason).toBe('unexpected-token');
177
+ expect(isTimeZoneOffset('Z').matched).toBe(true);
178
+ expect(isTimeZoneOffset('Z:').reason).toBe('extra-token');
179
+ expect(isTimeZoneOffset('ZZ').reason).toBe('extra-token');
180
+ expect(isTimeZoneOffset('+').reason).toBe('missing-token');
181
+ expect(isTimeZoneOffset('-').reason).toBe('missing-token');
182
+ expect(isTimeZoneOffset('+-').reason).toBe('unexpected-token');
183
+ expect(isTimeZoneOffset('+00').reason).toBe('missing-token');
184
+ expect(isTimeZoneOffset('+00:').reason).toBe('missing-token');
185
+ expect(isTimeZoneOffset('+00:00').matched).toBe(true);
186
+ expect(isTimeZoneOffset('+24:00').matched).toBe(false);
187
+ expect(isTimeZoneOffset('+00:60').matched).toBe(false);
188
+ expect(isTimeZoneOffset('+000:00').matched).toBe(false);
189
+ expect(isTimeZoneOffset('+00:000').matched).toBe(false);
190
+ expect(isTimeZoneOffset('+00:00:').reason).toBe('extra-token');
191
+ expect(isTimeZoneOffset('+0000').matched).toBe(true);
192
+ expect(isTimeZoneOffset('+2400').matched).toBe(false);
193
+ expect(isTimeZoneOffset('+0060').matched).toBe(false);
194
+ expect(isTimeZoneOffset('+00000').matched).toBe(false);
195
+ expect(isTimeZoneOffset('+0000:').reason).toBe('extra-token');
196
+ });
197
+
198
+ test('global-date-and-time-string', () => {
199
+ expect(isGlobalDateAndTime('2000-01-01').reason).toBe('missing-token');
200
+ expect(isGlobalDateAndTime('2000-01-01T00:00').reason).toBe('missing-token');
201
+ expect(isGlobalDateAndTime('2000-01-01T00:00').reason).toBe('missing-token');
202
+ expect(isGlobalDateAndTime('2000-01-01T00:00+').reason).toBe('missing-token');
203
+ expect(isGlobalDateAndTime('2000-01-01T00:00Z').matched).toBe(true);
204
+ expect(isGlobalDateAndTime('2000-01-01T00:00+00').reason).toBe('missing-token');
205
+ expect(isGlobalDateAndTime('2000-01-01T00:00+0000').matched).toBe(true);
206
+ expect(isGlobalDateAndTime('2000-01-01T00:00+00:00').matched).toBe(true);
207
+ expect(isGlobalDateAndTime('2000-01-01T00:00-2359').matched).toBe(true);
208
+ expect(isGlobalDateAndTime('2000-01-01T00:00-23:59').matched).toBe(true);
209
+ expect(isGlobalDateAndTime('2000-01-01T00:00:00+0000').matched).toBe(true);
210
+ expect(isGlobalDateAndTime('2000-01-01T00:00:00.000+0000').matched).toBe(true);
211
+ expect(isGlobalDateAndTime('2000-01-01T00:00:00.000+0000a').reason).toBe('extra-token');
212
+ });
213
+
214
+ test('week-string', () => {
215
+ expect(isWeek('').reason).toBe('empty-token');
216
+ expect(isWeek(' ').reason).toBe('unexpected-token');
217
+ expect(isWeek('a').reason).toBe('unexpected-token');
218
+ expect(isWeek('2000').reason).toBe('missing-token');
219
+ expect(isWeek('2000-').reason).toBe('missing-token');
220
+ expect(isWeek('2000-a').reason).toBe('unexpected-token');
221
+ expect(isWeek('2000-W').reason).toBe('missing-token');
222
+ expect(isWeek('2000-Wa').reason).toBe('unexpected-token');
223
+ expect(isWeek('2000-W0').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 2, lte: 2 });
224
+ expect(isWeek('2000-W00').reason).toStrictEqual({ type: 'out-of-range', gte: 1, lte: 52 });
225
+ expect(isWeek('2000-W53').reason).toStrictEqual({ type: 'out-of-range', gte: 1, lte: 52 });
226
+ expect(isWeek('2000-W01').matched).toBe(true);
227
+ expect(isWeek('2000-W52').matched).toBe(true);
228
+ expect(isWeek('2004-W00').reason).toStrictEqual({ type: 'out-of-range', gte: 1, lte: 53 });
229
+ expect(isWeek('2004-W54').reason).toStrictEqual({ type: 'out-of-range', gte: 1, lte: 53 });
230
+ expect(isWeek('2004-W01').matched).toBe(true);
231
+ expect(isWeek('2004-W53').matched).toBe(true);
232
+ expect(isWeek('2000-W01a').reason).toBe('extra-token');
233
+ });
234
+
235
+ test('year-string', () => {
236
+ expect(isYear('').reason).toBe('empty-token');
237
+ expect(isYear(' ').reason).toBe('unexpected-token');
238
+ expect(isYear('a').reason).toBe('unexpected-token');
239
+ expect(isYear('200').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 4 });
240
+ expect(isYear('2000').matched).toBe(true);
241
+ expect(isYear('20000').matched).toBe(true);
242
+ });
243
+
244
+ test('duration-string (IS08601 like)', () => {
245
+ expect(isDurationISO8601Like('').reason).toBe('empty-token');
246
+ expect(isDurationISO8601Like(' ').reason).toBe('unexpected-token');
247
+ expect(isDurationISO8601Like('a').reason).toBe('unexpected-token');
248
+ expect(isDurationISO8601Like('P').reason).toBe('missing-token');
249
+ expect(isDurationISO8601Like('P0').reason).toBe('missing-token');
250
+ expect(isDurationISO8601Like('P0D').reason).toBe('missing-token');
251
+ expect(isDurationISO8601Like('P0H').reason).toBe('unexpected-token');
252
+ expect(isDurationISO8601Like('P0Dt').reason).toBe('unexpected-token');
253
+ expect(isDurationISO8601Like('P0DT').reason).toBe('missing-token');
254
+ expect(isDurationISO8601Like('P0DT0').reason).toBe('missing-token');
255
+ expect(isDurationISO8601Like('P0DT0H').matched).toBe(true);
256
+ expect(isDurationISO8601Like('P0DT0H0').reason).toBe('missing-token');
257
+ expect(isDurationISO8601Like('P0DT0H0M').matched).toBe(true);
258
+ expect(isDurationISO8601Like('P0DT0H0M0').reason).toBe('missing-token');
259
+ expect(isDurationISO8601Like('P0DT0H0M0S').matched).toBe(true);
260
+ expect(isDurationISO8601Like('P0DT0H0M0.').reason).toBe('missing-token');
261
+ expect(isDurationISO8601Like('P0DT0H0M0M').reason).toBe('unexpected-token');
262
+ expect(isDurationISO8601Like('P0DT0H0M0.0').reason).toBe('missing-token');
263
+ expect(isDurationISO8601Like('P0DT0H0M0.0M').reason).toBe('unexpected-token');
264
+ expect(isDurationISO8601Like('P0DT0H0M0.000').reason).toBe('missing-token');
265
+ expect(isDurationISO8601Like('P0DT0H0M0.0000').reason).toStrictEqual({
266
+ gte: 1,
267
+ lte: 3,
268
+ type: 'out-of-range-length-digit',
269
+ });
270
+ expect(isDurationISO8601Like('P0DT0H0M0.000S').matched).toBe(true);
271
+ expect(isDurationISO8601Like('P0DT0H0M0.000S0').reason).toBe('extra-token');
272
+ expect(isDurationISO8601Like('P0DT0H0M0.000S0H').reason).toBe('extra-token');
273
+ expect(isDurationISO8601Like('P0DT0M').matched).toBe(true);
274
+ expect(isDurationISO8601Like('P0DT0S').matched).toBe(true);
275
+ expect(isDurationISO8601Like('P0DT0.0S').matched).toBe(true);
276
+ expect(isDurationISO8601Like('P0DT0M0S').matched).toBe(true);
277
+ expect(isDurationISO8601Like('P0DT0H0S').matched).toBe(true);
278
+ expect(isDurationISO8601Like('P0DT0H0.0S').matched).toBe(true);
279
+ expect(isDurationISO8601Like('P0DT0M0H').reason).toBe('unexpected-token');
280
+ expect(isDurationISO8601Like('P0DT0S0M').reason).toBe('extra-token');
281
+ expect(isDurationISO8601Like('P0DT0.0S0M').reason).toBe('extra-token');
282
+ expect(isDurationISO8601Like('PT4H18M3S').matched).toBe(true);
283
+ });
284
+
285
+ test('duration-string (duration component list)', () => {
286
+ expect(isDurationComponentList('').reason).toBe('empty-token');
287
+ expect(isDurationComponentList(' ').reason).toBe('missing-token');
288
+ expect(isDurationComponentList(' a').reason).toBe('unexpected-token');
289
+ expect(isDurationComponentList(' 0').reason).toBe('missing-token');
290
+ expect(isDurationComponentList(' 0a').reason).toBe('unexpected-token');
291
+ expect(isDurationComponentList(' 0w').matched).toBe(true);
292
+ expect(isDurationComponentList(' 0ww').reason).toBe('unexpected-token');
293
+ expect(isDurationComponentList('0w').matched).toBe(true);
294
+ expect(isDurationComponentList('0w ').matched).toBe(true);
295
+ expect(isDurationComponentList('0w 0').reason).toBe('missing-token');
296
+ expect(isDurationComponentList('0w 0w').reason).toBe('duplicated');
297
+ expect(isDurationComponentList('0w 0d').matched).toBe(true);
298
+ expect(isDurationComponentList('0w 0d').matched).toBe(true);
299
+ expect(isDurationComponentList(' 0w 0d').matched).toBe(true);
300
+ expect(isDurationComponentList(' 0w 0d ').matched).toBe(true);
301
+ expect(isDurationComponentList('0w 0d ').matched).toBe(true);
302
+ expect(isDurationComponentList('\n0w\n0d\n').matched).toBe(true);
303
+ expect(isDurationComponentList('0w 0.').reason).toBe('missing-token');
304
+ expect(isDurationComponentList('0w 0.0').reason).toBe('missing-token');
305
+ expect(isDurationComponentList('0w 0.0s').matched).toBe(true);
306
+ expect(isDurationComponentList('0w 0.0d').reason).toBe('unexpected-token');
307
+ expect(isDurationComponentList('0s 0.').reason).toBe('unexpected-token');
308
+ expect(isDurationComponentList('0s 0.0').reason).toBe('unexpected-token');
309
+ expect(isDurationComponentList('0s 0.0s').reason).toBe('unexpected-token');
310
+ expect(isDurationComponentList('0w 0.00s').matched).toBe(true);
311
+ expect(isDurationComponentList('0w 0.000s').matched).toBe(true);
312
+ expect(isDurationComponentList('0w 0.0000s').reason).toStrictEqual({
313
+ gte: 1,
314
+ lte: 3,
315
+ type: 'out-of-range-length-digit',
316
+ });
317
+ expect(isDurationComponentList('0s 0.000s').reason).toBe('unexpected-token');
318
+ expect(isDurationComponentList('0.000s 0s').reason).toBe('duplicated');
319
+ expect(isDurationComponentList('0w0d0h0m0.000s').matched).toBe(true);
320
+ expect(isDurationComponentList('0w 0d 0h 0m 0.000s').matched).toBe(true);
321
+ expect(isDurationComponentList('0w 0d0h 0m0.000s').matched).toBe(true);
322
+ expect(isDurationComponentList(' 2w 3d6m 3.4s 93xxxxxxx').reason).toBe('unexpected-token');
323
+ });
324
+
325
+ test('date-time', () => {
326
+ expect(isDateTime('200-1-1').reason).toStrictEqual({ type: 'out-of-range-length-digit', gte: 4 });
327
+ expect(isDateTime('2001-02-29').reason).toStrictEqual({ type: 'out-of-range', gte: 1, lte: 28 });
328
+ expect(isDateTime('2001-02-28T').reason).toBe('missing-token');
329
+ expect(isDateTime('2001-02-28T00').reason).toBe('missing-token');
330
+ expect(isDateTime('2001-02-28T00:0').reason).toStrictEqual({ gte: 2, lte: 2, type: 'out-of-range-length-digit' });
331
+ expect(isDateTime('2000-01-01T00:00:00.000+0000a').reason).toBe('extra-token');
332
+ expect(isDateTime('P0DT0M0H').reason).toBe('unexpected-token');
333
+ });
@@ -0,0 +1,36 @@
1
+ import type { CustomSyntaxChecker } from '../../types';
2
+
3
+ import { checkMultiTypes } from '../../check-multi-types';
4
+
5
+ import { checkDateString } from './date-string';
6
+ import { checkDurationComponentListString, checkDurationISO8601LikeString } from './duration-string';
7
+ import { checkGlobalDateAndTimeString } from './global-date-and-time-string';
8
+ import { checkLocalDateAndTimeString, checkNormalizedLocalDateAndTimeString } from './local-date-and-time-string';
9
+ import { checkMonthString } from './month-string';
10
+ import { checkTimeString } from './time-string';
11
+ import { checkTimeZoneOffsetString } from './time-zone-offset-string';
12
+ import { checkWeekString } from './week-string';
13
+ import { checkYearString } from './year-string';
14
+ import { checkYearlessDateString } from './yearless-date-string';
15
+
16
+ const checks = [
17
+ checkDateString(),
18
+ checkTimeString(),
19
+ checkMonthString(),
20
+ checkYearlessDateString(),
21
+ checkLocalDateAndTimeString(),
22
+ checkNormalizedLocalDateAndTimeString(),
23
+ checkTimeZoneOffsetString(),
24
+ checkGlobalDateAndTimeString(),
25
+ checkWeekString(),
26
+ checkYearString(),
27
+ checkDurationISO8601LikeString(),
28
+ checkDurationComponentListString(),
29
+ ];
30
+
31
+ /**
32
+ * @see https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#dates-and-times
33
+ */
34
+ export const checkDateTime: CustomSyntaxChecker = () => value => {
35
+ return checkMultiTypes(value, checks);
36
+ };
@@ -0,0 +1,163 @@
1
+ import type { CustomSyntaxChecker } from '../../types';
2
+
3
+ import { log } from '../../debug';
4
+ import { TokenCollection } from '../../token';
5
+
6
+ import { datetimeTokenCheck } from './datetime-tokens';
7
+
8
+ /**
9
+ * @see https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-local-date-and-time-string
10
+ */
11
+ export const checkLocalDateAndTimeString: CustomSyntaxChecker = () =>
12
+ function checkLocalDateAndTimeString(value) {
13
+ log('CHECK: local-date-and-time-string');
14
+
15
+ const tokens = TokenCollection.fromPatterns(value, [
16
+ // YYYY
17
+ /[^-]*/,
18
+ // -
19
+ /[^0-9]?/,
20
+ // MM
21
+ /[^-]*/,
22
+ // -
23
+ /[^0-9]?/,
24
+ // DD
25
+ /[^T\s]*/,
26
+ // T
27
+ /[^0-9]?/,
28
+ // hh
29
+ /[^:]*/,
30
+ // :
31
+ /[^0-9]?/,
32
+ // mm
33
+ /[^:]*/,
34
+ // :
35
+ /[^0-9]?/,
36
+ // ss
37
+ /[^.]*/,
38
+ // .
39
+ /[^0-9]?/,
40
+ // sss
41
+ /.[0-9]*/,
42
+ ]);
43
+
44
+ log('Local Date and Time: "%s" => %O', tokens.value, tokens);
45
+
46
+ const res = tokens.eachCheck(
47
+ datetimeTokenCheck.year,
48
+ datetimeTokenCheck.hyphen,
49
+ datetimeTokenCheck.month,
50
+ datetimeTokenCheck.hyphen,
51
+ datetimeTokenCheck.date,
52
+ datetimeTokenCheck.localDateTimeSeparator,
53
+ datetimeTokenCheck.hour,
54
+ datetimeTokenCheck.coron,
55
+ datetimeTokenCheck.minute,
56
+ datetimeTokenCheck.coronOrEnd,
57
+ datetimeTokenCheck.second,
58
+ datetimeTokenCheck.decimalPointOrEnd,
59
+ datetimeTokenCheck.secondFractionalPart,
60
+ datetimeTokenCheck.extra,
61
+ );
62
+
63
+ if (!res.matched) {
64
+ log('Failed: %O', res);
65
+ }
66
+
67
+ return res;
68
+ };
69
+
70
+ /**
71
+ * @see https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-normalised-local-date-and-time-string
72
+ */
73
+ export const checkNormalizedLocalDateAndTimeString: CustomSyntaxChecker = () =>
74
+ function checkNormalizedLocalDateAndTimeString(value) {
75
+ log('CHECK: normalized-local-date-and-time-string');
76
+
77
+ const tokens = TokenCollection.fromPatterns(value, [
78
+ // YYYY
79
+ /[^-]*/,
80
+ // -
81
+ /[^0-9]?/,
82
+ // MM
83
+ /[^-]*/,
84
+ // -
85
+ /[^0-9]?/,
86
+ // DD
87
+ /[^T]*/,
88
+ // T
89
+ /[^0-9]?/,
90
+ // hh
91
+ /[^:]*/,
92
+ // :
93
+ /[^0-9]?/,
94
+ // mm
95
+ /[^:]*/,
96
+ // :
97
+ /[^0-9]?/,
98
+ // ss
99
+ /[^.]*/,
100
+ // .
101
+ /[^0-9]?/,
102
+ // sss
103
+ /.[0-9]*/,
104
+ ]);
105
+
106
+ log('Normalized Local Date and Time: "%s" => %O', tokens.value, tokens);
107
+
108
+ const res = tokens.eachCheck(
109
+ datetimeTokenCheck.year,
110
+ datetimeTokenCheck.hyphen,
111
+ datetimeTokenCheck.month,
112
+ datetimeTokenCheck.hyphen,
113
+ datetimeTokenCheck.date,
114
+ datetimeTokenCheck.normalizedlocalDateTimeSeparator,
115
+ datetimeTokenCheck.hour,
116
+ datetimeTokenCheck.coron,
117
+ datetimeTokenCheck.minute,
118
+ datetimeTokenCheck.coronOrEnd,
119
+ datetimeTokenCheck.second,
120
+ datetimeTokenCheck.decimalPointOrEnd,
121
+ datetimeTokenCheck.secondFractionalPart,
122
+ datetimeTokenCheck.extra,
123
+ );
124
+
125
+ if (!res.matched) {
126
+ log('Failed: %O', res);
127
+ return res;
128
+ }
129
+
130
+ /**
131
+ * > A valid time string representing the time,
132
+ * > expressed as the shortest possible string for the given time
133
+ * > (e.g. omitting the seconds component entirely
134
+ * > if the given time is zero seconds past the minute)
135
+ */
136
+ const [, , , , , , , , , , second, , fp] = tokens;
137
+
138
+ const _second = second.toNumber() || 0;
139
+ const _fp = fp.toNumber() || 0;
140
+
141
+ log('Omitting the seconds component: "%s.%s" => %d, %d', second?.value, fp?.value, _second, _fp);
142
+
143
+ if (second.value && _second === 0 && (!fp.value || (fp.value && _fp === 0))) {
144
+ const res = second.unmatched({
145
+ partName: 'second',
146
+ reason: 'extra-token',
147
+ });
148
+ log('Failed: %O', res);
149
+ return res;
150
+ }
151
+
152
+ if (fp.value && _fp === 0) {
153
+ const res = fp.unmatched({
154
+ partName: 'fractional part',
155
+ reason: 'extra-token',
156
+ });
157
+ log('Failed: %O', res);
158
+ return res;
159
+ }
160
+
161
+ log('Failed: %O', res);
162
+ return res;
163
+ };
@@ -0,0 +1,31 @@
1
+ import type { CustomSyntaxChecker } from '../../types';
2
+
3
+ import { log } from '../../debug';
4
+ import { TokenCollection } from '../../token';
5
+
6
+ import { datetimeTokenCheck } from './datetime-tokens';
7
+
8
+ /**
9
+ * @see https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-month-string
10
+ */
11
+ export const checkMonthString: CustomSyntaxChecker = () =>
12
+ function checkMonthString(value) {
13
+ log('CHECK: month-string');
14
+
15
+ const tokens = TokenCollection.fromPatterns(value, [/[^-]*/, /[^0-9]?/, /.[0-9]*/]);
16
+
17
+ log('Month: "%s" => %O', tokens.value, tokens);
18
+
19
+ const res = tokens.eachCheck(
20
+ datetimeTokenCheck.year,
21
+ datetimeTokenCheck.hyphen,
22
+ datetimeTokenCheck.month,
23
+ datetimeTokenCheck.extra,
24
+ );
25
+
26
+ if (!res.matched) {
27
+ log('Failed: %O', res);
28
+ }
29
+
30
+ return res;
31
+ };
@@ -0,0 +1,49 @@
1
+ import type { CustomSyntaxChecker } from '../../types';
2
+
3
+ import { log } from '../../debug';
4
+ import { TokenCollection } from '../../token';
5
+
6
+ import { datetimeTokenCheck } from './datetime-tokens';
7
+
8
+ /**
9
+ * @see https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#times
10
+ */
11
+ export const checkTimeString: CustomSyntaxChecker = () =>
12
+ function checkTimeString(value) {
13
+ log('CHECK: time-string');
14
+
15
+ const tokens = TokenCollection.fromPatterns(value, [
16
+ // hh
17
+ /[^:]*/,
18
+ // :
19
+ /[^0-9]?/,
20
+ // mm
21
+ /[^:]*/,
22
+ // :
23
+ /[^0-9]?/,
24
+ // ss
25
+ /[^.]*/,
26
+ // .
27
+ /[^0-9]?/,
28
+ // sss
29
+ /.[0-9]*/,
30
+ ]);
31
+
32
+ log('Time: "%s" => %O', tokens.value, tokens);
33
+
34
+ const res = tokens.eachCheck(
35
+ datetimeTokenCheck.hour,
36
+ datetimeTokenCheck.coron,
37
+ datetimeTokenCheck.minute,
38
+ datetimeTokenCheck.coronOrEnd,
39
+ datetimeTokenCheck.second,
40
+ datetimeTokenCheck.decimalPointOrEnd,
41
+ datetimeTokenCheck.secondFractionalPart,
42
+ );
43
+
44
+ if (!res.matched) {
45
+ log('Failed: %O', res);
46
+ }
47
+
48
+ return res;
49
+ };