@markuplint/types 3.0.0-dev.25 → 3.0.0-dev.40

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 (65) hide show
  1. package/lib/css-syntax.js +6 -6
  2. package/lib/types.schema.d.ts +1 -1
  3. package/package.json +4 -6
  4. package/types.schema.json +16 -67
  5. package/gen/specific-schema.json +0 -98
  6. package/gen/types.ts +0 -66
  7. package/patches/css-tree+2.3.1.patch +0 -23
  8. package/src/check-multi-types.ts +0 -35
  9. package/src/check.spec.ts +0 -83
  10. package/src/check.ts +0 -48
  11. package/src/css-syntax.spec.ts +0 -167
  12. package/src/css-syntax.ts +0 -188
  13. package/src/debug.ts +0 -3
  14. package/src/defs.ts +0 -811
  15. package/src/enum.ts +0 -25
  16. package/src/get-candidate.ts +0 -24
  17. package/src/index.ts +0 -3
  18. package/src/keyword-type.ts +0 -64
  19. package/src/list.spec.ts +0 -133
  20. package/src/list.ts +0 -34
  21. package/src/match-result.ts +0 -49
  22. package/src/number.ts +0 -46
  23. package/src/primitive/index.spec.ts +0 -65
  24. package/src/primitive/index.ts +0 -7
  25. package/src/primitive/is-float.ts +0 -8
  26. package/src/primitive/is-int.ts +0 -8
  27. package/src/primitive/is-non-zero-uint.ts +0 -8
  28. package/src/primitive/is-quantity.ts +0 -38
  29. package/src/primitive/is-uint.ts +0 -15
  30. package/src/primitive/range.ts +0 -14
  31. package/src/primitive/split-unit.ts +0 -20
  32. package/src/rfc/is-bcp-47.spec.ts +0 -23
  33. package/src/rfc/is-bcp-47.ts +0 -13
  34. package/src/token/index.ts +0 -2
  35. package/src/token/token-collection.spec.ts +0 -147
  36. package/src/token/token-collection.ts +0 -444
  37. package/src/token/token.ts +0 -144
  38. package/src/types.schema.ts +0 -1113
  39. package/src/types.ts +0 -118
  40. package/src/w3c/check-serialized-permissions-policy.spec.ts +0 -38
  41. package/src/w3c/check-serialized-permissions-policy.ts +0 -303
  42. package/src/whatwg/check-autocomplete.spec.ts +0 -387
  43. package/src/whatwg/check-autocomplete.ts +0 -380
  44. package/src/whatwg/check-datetime/date-string.ts +0 -44
  45. package/src/whatwg/check-datetime/datetime-tokens.ts +0 -600
  46. package/src/whatwg/check-datetime/duration-string.ts +0 -399
  47. package/src/whatwg/check-datetime/global-date-and-time-string.ts +0 -96
  48. package/src/whatwg/check-datetime/index.spec.ts +0 -333
  49. package/src/whatwg/check-datetime/index.ts +0 -36
  50. package/src/whatwg/check-datetime/local-date-and-time-string.ts +0 -163
  51. package/src/whatwg/check-datetime/month-string.ts +0 -31
  52. package/src/whatwg/check-datetime/time-string.ts +0 -49
  53. package/src/whatwg/check-datetime/time-zone-offset-string.ts +0 -93
  54. package/src/whatwg/check-datetime/week-string.ts +0 -41
  55. package/src/whatwg/check-datetime/year-string.ts +0 -26
  56. package/src/whatwg/check-datetime/yearless-date-string.ts +0 -38
  57. package/src/whatwg/check-mime-type.spec.ts +0 -59
  58. package/src/whatwg/check-mime-type.ts +0 -46
  59. package/src/whatwg/is-abs-url.spec.ts +0 -8
  60. package/src/whatwg/is-abs-url.ts +0 -31
  61. package/src/whatwg/is-browser-context-name.ts +0 -16
  62. package/src/whatwg/is-custom-element-name.ts +0 -76
  63. package/src/whatwg/is-itemprop-name.ts +0 -17
  64. package/tsconfig.test.json +0 -3
  65. package/tsconfig.tsbuildinfo +0 -1
package/src/types.ts DELETED
@@ -1,118 +0,0 @@
1
- import type { cssSyntaxMatch } from './css-syntax';
2
-
3
- export type { Type, List, Enum, CssSyntax, KeywordDefinedType, Number } from './types.schema';
4
-
5
- export type Result = UnmatchedResult | MatchedResult;
6
-
7
- export type UnmatchedResult = {
8
- matched: false;
9
- ref: string | null;
10
- raw: string;
11
- length: number;
12
- offset: number;
13
- line: number;
14
- column: number;
15
- reason: UnmatchedResultReason;
16
- passCount?: number;
17
- } & UnmatchedResultOptions;
18
-
19
- export type UnmatchedResultOptions = {
20
- partName?: string;
21
- expects?: Expect[];
22
- extra?: Expect;
23
- candidate?: string;
24
- };
25
-
26
- export type UnmatchedResultReason =
27
- | 'syntax-error'
28
- | 'typo'
29
- | 'missing-token'
30
- | 'missing-comma'
31
- | 'unexpected-token'
32
- | 'unexpected-space'
33
- | 'unexpected-newline'
34
- | 'unexpected-comma'
35
- | 'empty-token'
36
- | 'out-of-range'
37
- | 'doesnt-exist-in-enum'
38
- | 'duplicated'
39
- | 'illegal-combination'
40
- | 'illegal-order'
41
- | 'extra-token'
42
- | 'must-be-percent-encoded'
43
- | 'must-be-serialized'
44
- | {
45
- type: 'out-of-range';
46
- gt?: number;
47
- gte?: number;
48
- lt?: number;
49
- lte?: number;
50
- }
51
- | {
52
- type: 'out-of-range-length-char';
53
- gte: number;
54
- lte?: number;
55
- }
56
- | {
57
- type: 'out-of-range-length-digit';
58
- gte: number;
59
- lte?: number;
60
- };
61
-
62
- export type MatchedResult = {
63
- matched: true;
64
- };
65
-
66
- export type Expect = {
67
- type: 'const' | 'format' | 'syntax' | 'regexp' | 'common';
68
- value: string;
69
- };
70
-
71
- export type FormattedPrimitiveTypeCheck = (value: string) => boolean;
72
-
73
- export type FormattedPrimitiveTypeCreator<O = never> = (options?: O) => FormattedPrimitiveTypeCheck;
74
-
75
- export type Defs = Record<string, CustomCssSyntax | CustomSyntax>;
76
-
77
- export type CustomSyntax = {
78
- ref: string;
79
- expects?: Expect[];
80
- is: CustomSyntaxCheck;
81
- };
82
-
83
- export type CustomSyntaxCheck = (value: string) => Result;
84
- export type CustomSyntaxChecker<O = {}> = (options?: O) => CustomSyntaxCheck;
85
-
86
- export type CustomCssSyntax = {
87
- ref: string;
88
- caseSensitive?: boolean;
89
- expects?: Expect[];
90
- syntax: {
91
- apply: `<${string}>`;
92
- def: Record<string, string | CssSyntaxTokenizer>;
93
- /**
94
- * @deprecated
95
- */
96
- ebnf?: Record<string, string | string[]>;
97
- /**
98
- * @deprecated
99
- */
100
- properties?: Record<string, string>;
101
- };
102
- };
103
-
104
- export type CSSSyntaxToken = {
105
- type: number;
106
- value: string;
107
- index: number;
108
- balance: number;
109
- node?: any;
110
- };
111
-
112
- export type CssSyntaxTokenizer = (
113
- token: CSSSyntaxToken | null,
114
- getNextToken: GetNextToken,
115
- match: typeof cssSyntaxMatch,
116
- ) => number;
117
-
118
- export type GetNextToken = (length: number) => CSSSyntaxToken | null;
@@ -1,38 +0,0 @@
1
- // @ts-nocheck
2
-
3
- import { checkSerializedPermissionsPolicy } from './check-serialized-permissions-policy';
4
-
5
- const check = checkSerializedPermissionsPolicy();
6
-
7
- test('checkSerializedPermissionsPolicy', () => {
8
- expect(check('').reason).toBe('empty-token');
9
- expect(check(' ').reason).toBe('unexpected-token');
10
- // expect(check('a').reason).toBe('missing-token');
11
- expect(check('a').matched).toBe(true); // Current supported
12
- expect(check('a:').reason).toBe('unexpected-token');
13
- // expect(check('a ').reason).toBe('missing-token'); // Current supported
14
- expect(check('a ').matched).toBe(true);
15
- expect(check('a a').reason).toBe('unexpected-token');
16
- expect(check('a *').matched).toBe(true);
17
- expect(check('a *a').reason).toBe('unexpected-token');
18
- expect(check('a none').reason).toBe('missing-token');
19
- expect(check("a 'none'").matched).toBe(true);
20
- expect(check('a https://markuplint.dev').matched).toBe(true);
21
- expect(check('a https://markuplint.dev/path/to').reason).toBe('extra-token');
22
- expect(check('a https://マルチバイト.abc.xyz').reason).toBe('must-be-serialized');
23
- expect(check('a * https://markuplint.dev').matched).toBe(true);
24
- expect(check("a * https://markuplint.dev 'none'").matched).toBe(true);
25
- // expect(check("a * https://markuplint.dev 'none';b").reason).toBe('missing-token');
26
- expect(check("a * https://markuplint.dev 'none';b").matched).toBe(true); // Current supported
27
- // expect(check("a * https://markuplint.dev 'none';b ").reason).toBe('missing-token');
28
- expect(check("a * https://markuplint.dev 'none';b ").matched).toBe(true); // Current supported
29
- expect(check("a * https://markuplint.dev 'none';b *").matched).toBe(true);
30
- expect(check("a * https://markuplint.dev 'none';b *;c 'none'").matched).toBe(true);
31
- expect(check("a * https://markuplint.dev 'none'; b *; c 'none'").matched).toBe(true);
32
- });
33
-
34
- test('YouTube embed', () => {
35
- expect(
36
- check('accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture').matched,
37
- ).toBe(true);
38
- });
@@ -1,303 +0,0 @@
1
- import type { Token } from '../token';
2
- import type { CustomSyntaxChecker } from '../types';
3
-
4
- import { log } from '../debug';
5
- import { matched, unmatched } from '../match-result';
6
- import { TokenCollection } from '../token';
7
-
8
- /**
9
- * @see https://w3c.github.io/webappsec-permissions-policy/#serialized-permissions-policy
10
- *
11
- * > Policy Directives in HTML attributes are represented as their
12
- * > ASCII serialization, with the following ABNF:
13
- * > ```abnf
14
- * > serialized-permissions-policy = serialized-policy-directive *(";" serialized-policy-directive)
15
- * > serialized-policy-directive = feature-identifier RWS allow-list
16
- * > feature-identifier = 1*( ALPHA / DIGIT / "-")
17
- * > allow-list = allow-list-value *(RWS allow-list-value)
18
- * > allow-list-value = serialized-origin / "*" / "'self'" / "'src'" / "'none'"
19
- * > ```
20
- *
21
- * But change below according to current supported:
22
- *
23
- * ```abnf
24
- * serialized-policy-directive = feature-identifier [RWS allow-list]
25
- * ```
26
- *
27
- * `allow-list` is optional.
28
- */
29
- export const checkSerializedPermissionsPolicy: CustomSyntaxChecker = () => value => {
30
- const res = _checkSerializedPermissionsPolicy(value);
31
-
32
- if (!res.matched) {
33
- log('Failed: %O', res);
34
- }
35
-
36
- return res;
37
- };
38
-
39
- function _checkSerializedPermissionsPolicy(value: string) {
40
- /**
41
- * The list of serialized-policy-directive
42
- *
43
- * > ```abnf
44
- * > serialized-policy-directive *(";" serialized-policy-directive)
45
- * > ```
46
- */
47
- const patterns = [
48
- /**
49
- * serialized-policy-directive
50
- */
51
- /[^;]*/,
52
- /**
53
- * separator
54
- */
55
- /;?/,
56
- ];
57
- const tokens = TokenCollection.fromPatterns(value, patterns, { repeat: true });
58
- const serializedPolicyDirectives = tokens.chunk(patterns.length);
59
-
60
- log('Serialized Permissions Policy: %s => %O', value, serializedPolicyDirectives);
61
-
62
- for (const [serializedPolicyDirective] of serializedPolicyDirectives) {
63
- if (!serializedPolicyDirective || !serializedPolicyDirective.value) {
64
- return unmatched('', 'empty-token');
65
- }
66
-
67
- const [aw, featureIdentifier, rws, allowListValue] = TokenCollection.fromPatterns(serializedPolicyDirective, [
68
- /**
69
- * Any whitespace
70
- */
71
- /\s*/,
72
-
73
- /**
74
- * feature-identifier
75
- *
76
- * > ```abnf
77
- * > feature-identifier = 1*( ALPHA / DIGIT / "-")
78
- * > ```
79
- */
80
- /[^\s]*/,
81
-
82
- /**
83
- * RWS (Required whitespace)
84
- *
85
- * @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.3
86
- */
87
- /\s*/,
88
-
89
- /**
90
- * allow-list-value
91
- */
92
- /.*/,
93
- ]);
94
-
95
- log('Serialized Policy Directive: %s => %O', serializedPolicyDirective.value, {
96
- aw,
97
- featureIdentifier,
98
- rws,
99
- allowListValue,
100
- });
101
-
102
- /**
103
- * > ```abnf
104
- * > feature-identifier = 1*( ALPHA / DIGIT / "-")
105
- * > ```
106
- */
107
- if (!featureIdentifier || !featureIdentifier.match(/^[a-z0-9-]+$/i)) {
108
- return featureIdentifier.unmatched({
109
- reason: 'unexpected-token',
110
- expects: [{ type: 'common', value: 'feature-identifier' }],
111
- partName: 'feature-identifier',
112
- });
113
- }
114
-
115
- if (!rws || !rws.value) {
116
- // return unmatched('', 'missing-token', {
117
- // expects: [{ type: 'common', value: 'whitespace' }],
118
- // partName: 'directive',
119
- // });
120
- continue;
121
- }
122
-
123
- if (!allowListValue || !allowListValue.value) {
124
- // return unmatched('', 'missing-token', {
125
- // expects: [{ type: 'common', value: 'allow-list' }],
126
- // partName: 'allow-list',
127
- // });
128
- continue;
129
- }
130
-
131
- const allowListPatterns = [
132
- // Value
133
- /[^\s]*/,
134
- // Separator
135
- /\s*/,
136
- ];
137
- const allowListTokens = TokenCollection.fromPatterns(allowListValue, allowListPatterns, { repeat: true });
138
- const allowList = allowListTokens.chunk(allowListPatterns.length);
139
-
140
- log('Allow List: %s => %O', allowListTokens.value, allowList);
141
-
142
- for (const [allow] of allowList) {
143
- if (!allow || !allow.value) {
144
- return unmatched('', 'missing-token', {
145
- expects: [
146
- { type: 'const', value: '*' },
147
- { type: 'const', value: "'self'" },
148
- { type: 'const', value: "'src'" },
149
- { type: 'const', value: "'none'" },
150
- { type: 'common', value: 'serialized-origin' },
151
- ],
152
- partName: 'allow-list',
153
- });
154
- }
155
-
156
- const origin = checkSerializedOrigin(allow);
157
-
158
- if (origin.matched) {
159
- continue;
160
- }
161
-
162
- if (origin.reason !== 'syntax-error') {
163
- return origin;
164
- }
165
-
166
- if (allow.match(['*', "'self'", "'src'", "'none'"], true)) {
167
- continue;
168
- }
169
-
170
- if (allow.match(['self', 'src', 'none'], true)) {
171
- return allow.unmatched({
172
- reason: 'missing-token',
173
- expects: [{ type: 'common', value: 'single-quote' }],
174
- partName: 'keyword',
175
- });
176
- }
177
-
178
- return allow.unmatched({
179
- reason: 'unexpected-token',
180
- expects: [
181
- { type: 'const', value: '*' },
182
- { type: 'const', value: "'self'" },
183
- { type: 'const', value: "'src'" },
184
- { type: 'const', value: "'none'" },
185
- { type: 'common', value: 'serialized-origin' },
186
- ],
187
- partName: 'allow-list',
188
- });
189
- }
190
- }
191
-
192
- return matched();
193
- }
194
-
195
- /**
196
- * serialized-origin
197
- *
198
- * > serialized-origin is the serialization of an origin.
199
- * > However, the code points U+0027 ('), U+0021 (*), U+002C (,)
200
- * > and U+003B (;) MUST NOT appear in the serialization.
201
- * > If they are required, they must be percent-encoded
202
- * > as "%27", "%2A", "%2C" or "%3B", respectively.
203
- */
204
- function checkSerializedOrigin(token: Token) {
205
- const url = parseUrl(token.value);
206
-
207
- log('Parse URL: "%s" => %O', token.value, url);
208
-
209
- if (!url) {
210
- return token.unmatched({
211
- expects: [{ type: 'common', value: 'serialized-origin' }],
212
- });
213
- }
214
-
215
- if (url.pathname && url.pathname !== '/') {
216
- return token.unmatched({
217
- reason: 'extra-token',
218
- extra: { type: 'common', value: 'pathname' },
219
- partName: 'serialized-origin',
220
- });
221
- }
222
-
223
- if (url.search) {
224
- return token.unmatched({
225
- reason: 'extra-token',
226
- extra: { type: 'common', value: 'query' },
227
- partName: 'serialized-origin',
228
- });
229
- }
230
-
231
- if (url.hash) {
232
- return token.unmatched({
233
- reason: 'extra-token',
234
- extra: { type: 'common', value: 'hash' },
235
- partName: 'serialized-origin',
236
- });
237
- }
238
-
239
- if (url.username) {
240
- return token.unmatched({
241
- reason: 'extra-token',
242
- extra: { type: 'common', value: 'username' },
243
- partName: 'serialized-origin',
244
- });
245
- }
246
-
247
- if (url.password) {
248
- return token.unmatched({
249
- reason: 'extra-token',
250
- extra: { type: 'common', value: 'password' },
251
- partName: 'serialized-origin',
252
- });
253
- }
254
-
255
- if (!token.value.includes(url.host)) {
256
- return token.unmatched({
257
- reason: 'must-be-serialized',
258
- partName: 'serialized-origin',
259
- });
260
- }
261
-
262
- if (token.includes("'")) {
263
- return token.unmatched({
264
- expects: [{ type: 'const', value: '%27' }],
265
- reason: 'must-be-percent-encoded',
266
- partName: 'serialized-origin',
267
- });
268
- }
269
-
270
- if (token.includes('*')) {
271
- return token.unmatched({
272
- expects: [{ type: 'const', value: '%2A' }],
273
- reason: 'must-be-percent-encoded',
274
- partName: 'serialized-origin',
275
- });
276
- }
277
-
278
- if (token.includes(',')) {
279
- return token.unmatched({
280
- expects: [{ type: 'const', value: '%2C' }],
281
- reason: 'must-be-percent-encoded',
282
- partName: 'serialized-origin',
283
- });
284
- }
285
-
286
- if (token.includes(';')) {
287
- return token.unmatched({
288
- expects: [{ type: 'const', value: '%3B' }],
289
- reason: 'must-be-percent-encoded',
290
- partName: 'serialized-origin',
291
- });
292
- }
293
-
294
- return matched();
295
- }
296
-
297
- function parseUrl(value: string) {
298
- try {
299
- return new URL(value);
300
- } catch {
301
- return null;
302
- }
303
- }