@markuplint/types 3.0.0-alpha.1 → 3.0.0-alpha.27

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 (75) hide show
  1. package/README.md +12 -8
  2. package/lib/check-multi-types.d.ts +1 -1
  3. package/lib/css-syntax.js +6 -6
  4. package/lib/defs.js +1 -0
  5. package/lib/get-candidate.d.ts +1 -1
  6. package/lib/match-result.d.ts +1 -1
  7. package/lib/token/token-collection.d.ts +3 -3
  8. package/lib/token/token-collection.js +47 -47
  9. package/lib/token/token.d.ts +1 -1
  10. package/lib/token/token.js +7 -7
  11. package/lib/types.d.ts +16 -16
  12. package/lib/types.schema.d.ts +5 -5
  13. package/package.json +7 -5
  14. package/patches/css-tree+2.3.1.patch +23 -0
  15. package/types.schema.json +67 -16
  16. package/gen/specific-schema.json +0 -98
  17. package/gen/types.ts +0 -66
  18. package/src/check-multi-types.ts +0 -35
  19. package/src/check.spec.ts +0 -83
  20. package/src/check.ts +0 -48
  21. package/src/css-syntax.spec.ts +0 -167
  22. package/src/css-syntax.ts +0 -188
  23. package/src/debug.ts +0 -3
  24. package/src/defs.ts +0 -810
  25. package/src/enum.ts +0 -25
  26. package/src/get-candidate.ts +0 -24
  27. package/src/index.ts +0 -3
  28. package/src/keyword-type.ts +0 -64
  29. package/src/list.spec.ts +0 -133
  30. package/src/list.ts +0 -34
  31. package/src/match-result.ts +0 -49
  32. package/src/number.ts +0 -46
  33. package/src/primitive/index.spec.ts +0 -65
  34. package/src/primitive/index.ts +0 -7
  35. package/src/primitive/is-float.ts +0 -8
  36. package/src/primitive/is-int.ts +0 -8
  37. package/src/primitive/is-non-zero-uint.ts +0 -8
  38. package/src/primitive/is-quantity.ts +0 -38
  39. package/src/primitive/is-uint.ts +0 -15
  40. package/src/primitive/range.ts +0 -14
  41. package/src/primitive/split-unit.ts +0 -20
  42. package/src/rfc/is-bcp-47.spec.ts +0 -23
  43. package/src/rfc/is-bcp-47.ts +0 -13
  44. package/src/token/index.ts +0 -2
  45. package/src/token/token-collection.spec.ts +0 -147
  46. package/src/token/token-collection.ts +0 -444
  47. package/src/token/token.ts +0 -144
  48. package/src/types.schema.ts +0 -1062
  49. package/src/types.ts +0 -118
  50. package/src/w3c/check-serialized-permissions-policy.spec.ts +0 -38
  51. package/src/w3c/check-serialized-permissions-policy.ts +0 -303
  52. package/src/whatwg/check-autocomplete.spec.ts +0 -387
  53. package/src/whatwg/check-autocomplete.ts +0 -380
  54. package/src/whatwg/check-datetime/date-string.ts +0 -44
  55. package/src/whatwg/check-datetime/datetime-tokens.ts +0 -600
  56. package/src/whatwg/check-datetime/duration-string.ts +0 -399
  57. package/src/whatwg/check-datetime/global-date-and-time-string.ts +0 -96
  58. package/src/whatwg/check-datetime/index.spec.ts +0 -333
  59. package/src/whatwg/check-datetime/index.ts +0 -36
  60. package/src/whatwg/check-datetime/local-date-and-time-string.ts +0 -163
  61. package/src/whatwg/check-datetime/month-string.ts +0 -31
  62. package/src/whatwg/check-datetime/time-string.ts +0 -49
  63. package/src/whatwg/check-datetime/time-zone-offset-string.ts +0 -93
  64. package/src/whatwg/check-datetime/week-string.ts +0 -41
  65. package/src/whatwg/check-datetime/year-string.ts +0 -26
  66. package/src/whatwg/check-datetime/yearless-date-string.ts +0 -38
  67. package/src/whatwg/check-mime-type.spec.ts +0 -59
  68. package/src/whatwg/check-mime-type.ts +0 -46
  69. package/src/whatwg/is-abs-url.spec.ts +0 -8
  70. package/src/whatwg/is-abs-url.ts +0 -31
  71. package/src/whatwg/is-browser-context-name.ts +0 -16
  72. package/src/whatwg/is-custom-element-name.ts +0 -76
  73. package/src/whatwg/is-itemprop-name.ts +0 -17
  74. package/tsconfig.test.json +0 -3
  75. package/tsconfig.tsbuildinfo +0 -1
package/src/check.ts DELETED
@@ -1,48 +0,0 @@
1
- import type { Type, Result, List, CustomSyntax, CustomCssSyntax, Enum, KeywordDefinedType, Number } from './types';
2
-
3
- import { log } from './debug';
4
- import { checkEnum } from './enum';
5
- import { checkKeywordType } from './keyword-type';
6
- import { checkList } from './list';
7
- import { checkNumber } from './number';
8
-
9
- export function check(value: string, type: Type, ref?: string, cache = true): Result {
10
- if (isKeyword(type)) {
11
- log('Check keyword: %s', type);
12
- return checkKeywordType(value, type, cache);
13
- }
14
- if (isList(type)) {
15
- log('Check list: %O', type);
16
- return checkList(value, type, ref, cache);
17
- }
18
- if (isEnum(type)) {
19
- log('Check enum: %O', type);
20
- return checkEnum(value, type, ref);
21
- }
22
- log('Check number: %O', type);
23
- return checkNumber(value, type, ref);
24
- }
25
-
26
- export function isKeyword(type: Type): type is KeywordDefinedType {
27
- return typeof type === 'string';
28
- }
29
-
30
- export function isList(type: Type): type is List {
31
- return typeof type !== 'string' && 'token' in type;
32
- }
33
-
34
- export function isEnum(type: Type): type is Enum {
35
- return typeof type !== 'string' && 'enum' in type;
36
- }
37
-
38
- export function isNumber(type: Type): type is Number {
39
- return typeof type !== 'string' && 'enum' in type;
40
- }
41
-
42
- export function isCSSSyntax(type: CustomSyntax | CustomCssSyntax): type is CustomCssSyntax {
43
- return typeof type === 'string' || 'syntax' in type;
44
- }
45
-
46
- export function isCustomSyntax(type: CustomSyntax | CustomCssSyntax): type is CustomSyntax {
47
- return !isCSSSyntax(type);
48
- }
@@ -1,167 +0,0 @@
1
- import type { CustomCssSyntax } from './types';
2
-
3
- import { cssSyntaxMatch } from './css-syntax';
4
-
5
- test('CSS Standard', () => {
6
- expect(cssSyntaxMatch('10px', '<length>').matched).toBe(true);
7
- expect(cssSyntaxMatch('one-pixel', '<length>').matched).toBe(false);
8
- expect(cssSyntaxMatch('(prefers-color-scheme: dark)', '<media-query-list>').matched).toBe(true);
9
- });
10
-
11
- test('Extends', () => {
12
- const sourceSizeList: CustomCssSyntax = {
13
- ref: 'https://html.spec.whatwg.org/multipage/images.html#sizes-attributes',
14
- syntax: {
15
- apply: '<source-size-list>',
16
- def: {
17
- 'source-size-list': '[ <source-size># , ]? <source-size-value>',
18
- 'source-size': '<media-condition> <source-size-value>',
19
- 'source-size-value': '<length>',
20
- },
21
- },
22
- };
23
- expect(cssSyntaxMatch('50vw', sourceSizeList).matched).toBe(true);
24
- expect(cssSyntaxMatch('(max-width: 600px) 200px, 50vw', sourceSizeList).matched).toBe(true);
25
- expect(cssSyntaxMatch('print 300vw', sourceSizeList).matched).toBe(false);
26
- expect(cssSyntaxMatch('(max-width: 600px) 200px', sourceSizeList).matched).toBe(false);
27
- expect(
28
- cssSyntaxMatch('(max-width: 600px) 200px', {
29
- ...sourceSizeList,
30
- syntax: {
31
- ...sourceSizeList.syntax,
32
- apply: '<source-size>',
33
- },
34
- }).matched,
35
- ).toBe(true);
36
-
37
- const keyTimes: CustomCssSyntax = {
38
- ref: 'https://svgwg.org/specs/animations/#KeyTimesAttribute',
39
- syntax: {
40
- apply: '<key-times>',
41
- def: {
42
- 'key-times': '<number> [; <number>]* [;]?',
43
- },
44
- },
45
- };
46
- expect(cssSyntaxMatch('20; 20; 30', keyTimes).matched).toBe(true);
47
- expect(cssSyntaxMatch('20; 20; 30;', keyTimes).matched).toBe(true);
48
- expect(cssSyntaxMatch('20; 20; abc;', keyTimes).matched).toBe(false);
49
- expect(cssSyntaxMatch('20; 20; ;', keyTimes).matched).toBe(false);
50
-
51
- const SVGViewBox: CustomCssSyntax = {
52
- ref: 'https://svgwg.org/svg2-draft/coords.html#ViewBoxAttribute',
53
- syntax: {
54
- apply: '<view-box>',
55
- def: {
56
- 'view-box': '<min-x> [,]? <min-y> [,]? <width> [,]? <height>',
57
- 'min-x': '<number>',
58
- 'min-y': '<number>',
59
- width: '<number>',
60
- height: '<number>',
61
- },
62
- },
63
- };
64
- expect(cssSyntaxMatch('0 0 30 10', SVGViewBox).matched).toBe(true);
65
- expect(cssSyntaxMatch('0 0, 30, 10', SVGViewBox).matched).toBe(true);
66
- expect(cssSyntaxMatch('0 0, 30', SVGViewBox).matched).toBe(false);
67
-
68
- const percentageList: CustomCssSyntax = {
69
- ref: 'https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#percentage',
70
- syntax: {
71
- apply: '<percentage-list>',
72
- def: {
73
- 'percentage-list': '[ <number> [,]? ]* <number>',
74
- },
75
- },
76
- };
77
- expect(cssSyntaxMatch('0 0 30 10', percentageList).matched).toBe(true);
78
- expect(cssSyntaxMatch('0, 0, 30 10', percentageList).matched).toBe(true);
79
- expect(cssSyntaxMatch('0', percentageList).matched).toBe(true);
80
- expect(cssSyntaxMatch('', percentageList).matched).toBe(false);
81
-
82
- const custom: CustomCssSyntax = {
83
- ref: 'n/a',
84
- syntax: {
85
- apply: '<custom>',
86
- def: {
87
- custom: '0 | 1 | .',
88
- },
89
- },
90
- };
91
- expect(cssSyntaxMatch('0', custom).matched).toBe(true);
92
- expect(cssSyntaxMatch('1', custom).matched).toBe(true);
93
- expect(cssSyntaxMatch('.', custom).matched).toBe(true);
94
- expect(cssSyntaxMatch('2', custom).matched).toBe(false);
95
- expect(cssSyntaxMatch(':', custom).matched).toBe(false);
96
- });
97
-
98
- test('custom-type-checking', () => {
99
- const custom: CustomCssSyntax = {
100
- ref: 'n/a',
101
- caseSensitive: true,
102
- syntax: {
103
- apply: '<custom>',
104
- def: {
105
- custom: '<custom-type>',
106
- 'custom-type': token => {
107
- if (!token) {
108
- return 0;
109
- }
110
- return token.value === '1' ? 1 : 0;
111
- },
112
- },
113
- },
114
- };
115
- expect(cssSyntaxMatch('1', custom).matched).toBe(true);
116
- expect(cssSyntaxMatch('0', custom).matched).toBe(false);
117
- });
118
-
119
- test('case-sensitive', () => {
120
- const custom: CustomCssSyntax = {
121
- ref: 'n/a',
122
- caseSensitive: true,
123
- syntax: {
124
- apply: '<custom>',
125
- def: {
126
- custom: 'CaSeS [a | B | aBc]',
127
- },
128
- },
129
- };
130
- expect(cssSyntaxMatch('CaSeS a', custom).matched).toBe(true);
131
- expect(cssSyntaxMatch('CaSeS B', custom).matched).toBe(true);
132
- expect(cssSyntaxMatch('CaSeS aBc', custom).matched).toBe(true);
133
- expect(cssSyntaxMatch('CaSeS A', custom)).toStrictEqual({
134
- column: 7,
135
- line: 1,
136
- matched: false,
137
- length: 1,
138
- offset: 6,
139
- partName: 'value',
140
- raw: 'A',
141
- reason: 'syntax-error',
142
- ref: 'n/a',
143
- expects: [
144
- {
145
- type: 'syntax',
146
- value: 'CaSeS [ a | B | aBc ]',
147
- },
148
- ],
149
- });
150
- expect(cssSyntaxMatch('CaSeS abc', custom)).toStrictEqual({
151
- column: 7,
152
- line: 1,
153
- matched: false,
154
- length: 3,
155
- offset: 6,
156
- partName: 'value',
157
- raw: 'abc',
158
- reason: 'syntax-error',
159
- ref: 'n/a',
160
- expects: [
161
- {
162
- type: 'syntax',
163
- value: 'CaSeS [ a | B | aBc ]',
164
- },
165
- ],
166
- });
167
- });
package/src/css-syntax.ts DELETED
@@ -1,188 +0,0 @@
1
- import type { CustomCssSyntax, CssSyntaxTokenizer, CSSSyntaxToken, GetNextToken, Result, CssSyntax } from './types';
2
-
3
- // @ts-ignore
4
- import csstree from 'css-tree';
5
- // @ts-ignore
6
- import { SyntaxMatchError } from 'css-tree/lib/lexer/error.js';
7
- // @ts-ignore
8
- import { matchAsTree } from 'css-tree/lib/lexer/match.js';
9
- // @ts-ignore
10
- import prepareTokens from 'css-tree/lib/lexer/prepare-tokens.js';
11
-
12
- import { log } from './debug';
13
- import { tokenizers } from './defs';
14
- import { matched } from './match-result';
15
-
16
- // eslint-disable-next-line no-redeclare
17
- interface SyntaxMatchError {
18
- message: string;
19
- rawMessage: 'Mismatch';
20
- syntax: string;
21
- css: string;
22
- mismatchOffset: number;
23
- mismatchLength: number;
24
- offset: number;
25
- line: number;
26
- column: number;
27
- loc: {
28
- source: '<unknown>';
29
- start: { offset: number; line: number; column: number };
30
- end: { offset: number; line: number; column: number };
31
- };
32
- }
33
-
34
- export function cssSyntaxMatch(value: string, type: CssSyntax | CustomCssSyntax): Result {
35
- log('Search CSS Syntax: "%s"', type);
36
-
37
- const origin = value;
38
- let defName: `<${string}>`;
39
- const typesExtended: Record<string, string> = {};
40
- const typesCheckers: Record<string, CssSyntaxTokenizer> = {};
41
- let propsExtended: Record<string, string>;
42
- let ref: string | undefined = undefined;
43
- let caseSensitive = false;
44
- let ebnf: Record<string, string | string[]> | null = null;
45
-
46
- if (typeof type === 'string') {
47
- defName = type;
48
- propsExtended = {};
49
- } else {
50
- defName = type.syntax.apply;
51
- ebnf = type.syntax.ebnf || null;
52
-
53
- if (ebnf) {
54
- // Work in progress
55
- return matched();
56
- }
57
-
58
- const types = {
59
- ...tokenizers,
60
- ...type.syntax.def,
61
- };
62
- Object.keys(types).forEach(key => {
63
- const valueOrChecker = types[key];
64
- if (typeof valueOrChecker === 'string') {
65
- typesExtended[key] = valueOrChecker;
66
- } else {
67
- typesCheckers[key] = valueOrChecker;
68
- }
69
- });
70
- propsExtended = { ...type.syntax.properties };
71
- if (type.caseSensitive) {
72
- caseSensitive = true;
73
- Object.keys(typesExtended).forEach(key => eachMimicCases(key, typesExtended));
74
- Object.keys(propsExtended).forEach(key => eachMimicCases(key, propsExtended));
75
- value = mimicCases(value);
76
- }
77
- ref = type.ref;
78
- }
79
-
80
- // @ts-ignore
81
- const lexer = csstree.fork({
82
- types: typesExtended,
83
- properties: propsExtended,
84
- }).lexer;
85
-
86
- Object.keys(typesCheckers).forEach(key => {
87
- const checker = typesCheckers[key];
88
- lexer.addType_(key, (token: CSSSyntaxToken, getNextToken: GetNextToken) =>
89
- checker(token, getNextToken, cssSyntaxMatch),
90
- );
91
- });
92
-
93
- const { isProp, name, matcher } = defToMatcher(lexer, defName);
94
- const refParam = isProp ? 'Property' : 'Type';
95
- ref = ref || `https://csstree.github.io/docs/syntax/#${refParam}:${name}`;
96
-
97
- // eslint-disable-next-line no-console
98
- const _w = console.warn;
99
-
100
- if (log.enabled) {
101
- // eslint-disable-next-line no-console
102
- console.warn = warn => log('WARNING: %s (by %s => %s)', warn, value, type);
103
- }
104
-
105
- const tokens = prepareTokens(value, lexer.syntax);
106
- const result = matchAsTree(tokens, matcher.match, lexer);
107
-
108
- if (caseSensitive) {
109
- if (result.tokens && Array.isArray(result.tokens)) {
110
- let reducer = 0;
111
- result.tokens = result.tokens.map((token: CSSSyntaxToken) => {
112
- const value = token.value;
113
- const originValue = deMimicCases(value || '');
114
- const isMimiced = value !== originValue;
115
- reducer += isMimiced ? 'mimiccases------mimiccases'.length : 0;
116
- token.value = originValue;
117
- token.balance = token.balance - reducer;
118
- return token;
119
- });
120
- }
121
- }
122
-
123
- log('css-tree/result: %O', result);
124
- // eslint-disable-next-line no-console
125
- console.warn = _w;
126
-
127
- if (result.match) {
128
- if (log.enabled) {
129
- log('css-tree/result.match: %s', JSON.stringify(result.match, null, 2));
130
- }
131
- return matched();
132
- }
133
-
134
- const error: SyntaxMatchError = new SyntaxMatchError(result.reason, matcher.syntax, value, result);
135
-
136
- if (caseSensitive) {
137
- error.message = deMimicCases(error.message);
138
- error.syntax = deMimicCases(error.syntax);
139
- }
140
-
141
- log('css-tree/SyntaxMatchError: %O', error);
142
-
143
- return {
144
- matched: false,
145
- ref,
146
- raw: origin.slice(error.mismatchOffset, error.mismatchOffset + error.mismatchLength),
147
- offset: error.mismatchOffset,
148
- length: error.mismatchLength,
149
- line: error.line,
150
- column: error.column,
151
- expects: [
152
- {
153
- type: 'syntax',
154
- value: error.syntax,
155
- },
156
- ],
157
- partName: error.mismatchOffset === 0 ? undefined : 'value',
158
- reason: 'syntax-error',
159
- };
160
- }
161
-
162
- function defToMatcher(lexer: any, def: `<${string}>`) {
163
- const isProp = def.search("<'") === 0;
164
- const name = def.replace(/^<'?|'?>$/g, '');
165
- const matcher = isProp ? lexer.properties[name] : lexer.types[name];
166
- if (!matcher) {
167
- log('"%s" CSS syntax not found', def);
168
- throw new Error('MARKUPLINT_TYPE_NO_EXIST');
169
- }
170
- return {
171
- isProp,
172
- name,
173
- matcher,
174
- };
175
- }
176
-
177
- function eachMimicCases(key: string, obj: Record<string, string>) {
178
- const value = obj[key];
179
- obj[key] = mimicCases(value);
180
- }
181
-
182
- function mimicCases(value: string) {
183
- return value.replace(/[A-Z]/g, $0 => `mimiccases---${$0}---mimiccases`);
184
- }
185
-
186
- function deMimicCases(value: string) {
187
- return value.replace(/mimiccases---([A-Z])---mimiccases/g, (_, $1) => $1);
188
- }
package/src/debug.ts DELETED
@@ -1,3 +0,0 @@
1
- import debug from 'debug';
2
-
3
- export const log = debug('@markuplint/types');