@markuplint/types 3.2.0 → 3.4.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.
- package/lib/check-multi-types.d.ts +1 -1
- package/lib/check.d.ts +6 -5
- package/lib/check.spec.js +1 -0
- package/lib/css-syntax.js +24 -10
- package/lib/css-syntax.spec.js +1 -0
- package/lib/defs.js +1 -1
- package/lib/enum.d.ts +2 -1
- package/lib/enum.js +1 -1
- package/lib/get-candidate.d.ts +1 -1
- package/lib/list.d.ts +2 -1
- package/lib/list.spec.js +1 -0
- package/lib/match-result.d.ts +3 -3
- package/lib/number.d.ts +1 -1
- package/lib/primitive/index.spec.js +1 -0
- package/lib/primitive/is-quantity.d.ts +1 -1
- package/lib/primitive/is-uint.d.ts +1 -1
- package/lib/primitive/split-unit.js +2 -2
- package/lib/rfc/is-bcp-47.spec.js +1 -0
- package/lib/token/token-collection.d.ts +13 -11
- package/lib/token/token-collection.js +11 -7
- package/lib/token/token-collection.spec.js +1 -0
- package/lib/token/token.d.ts +10 -9
- package/lib/token/token.js +13 -15
- package/lib/token/types.d.ts +3 -0
- package/lib/token/types.js +2 -0
- package/lib/types.d.ts +44 -44
- package/lib/whatwg/check-autocomplete.js +4 -4
- package/lib/whatwg/check-autocomplete.spec.js +1 -0
- package/lib/whatwg/check-datetime/datetime-tokens.js +2 -1
- package/lib/whatwg/check-datetime/duration-string.js +9 -0
- package/lib/whatwg/check-datetime/local-date-and-time-string.js +4 -0
- package/lib/whatwg/check-datetime/time-zone-offset-string.d.ts +1 -1
- package/lib/whatwg/check-datetime/time-zone-offset-string.js +3 -2
- package/lib/whatwg/check-mime-type.spec.js +1 -0
- package/lib/whatwg/is-abs-url.spec.js +1 -0
- package/package.json +4 -3
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { CustomSyntaxCheck, UnmatchedResult } from './types';
|
|
2
|
-
export declare function checkMultiTypes(value: string, checks: CustomSyntaxCheck[]): import("./types").MatchedResult | UnmatchedResult;
|
|
2
|
+
export declare function checkMultiTypes(value: string, checks: readonly CustomSyntaxCheck[]): import("./types").MatchedResult | UnmatchedResult;
|
package/lib/check.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { Type, Result, List, CustomSyntax, CustomCssSyntax, Enum, KeywordDefinedType, Number } from './types';
|
|
2
|
-
|
|
3
|
-
export declare function
|
|
4
|
-
export declare function
|
|
5
|
-
export declare function
|
|
6
|
-
export declare function
|
|
2
|
+
import type { ReadonlyDeep } from 'type-fest';
|
|
3
|
+
export declare function check(value: string, type: ReadonlyDeep<Type>, ref?: string, cache?: boolean): Result;
|
|
4
|
+
export declare function isKeyword(type: ReadonlyDeep<Type>): type is ReadonlyDeep<KeywordDefinedType>;
|
|
5
|
+
export declare function isList(type: ReadonlyDeep<Type>): type is ReadonlyDeep<List>;
|
|
6
|
+
export declare function isEnum(type: ReadonlyDeep<Type>): type is ReadonlyDeep<Enum>;
|
|
7
|
+
export declare function isNumber(type: ReadonlyDeep<Type>): type is ReadonlyDeep<Number>;
|
|
7
8
|
export declare function isCSSSyntax(type: CustomSyntax | CustomCssSyntax): type is CustomCssSyntax;
|
|
8
9
|
export declare function isCustomSyntax(type: CustomSyntax | CustomCssSyntax): type is CustomSyntax;
|
package/lib/check.spec.js
CHANGED
package/lib/css-syntax.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.cssSyntaxMatch = void 0;
|
|
4
|
-
const
|
|
5
|
-
const css_tree_1 = tslib_1.__importDefault(require("css-tree"));
|
|
4
|
+
const css_tree_1 = require("css-tree");
|
|
6
5
|
const debug_1 = require("./debug");
|
|
7
6
|
const defs_1 = require("./defs");
|
|
8
7
|
const match_result_1 = require("./match-result");
|
|
@@ -39,7 +38,7 @@ function cssSyntaxMatch(value, type) {
|
|
|
39
38
|
if (typeof valueOrChecker === 'string') {
|
|
40
39
|
typesExtended[key] = valueOrChecker;
|
|
41
40
|
}
|
|
42
|
-
else {
|
|
41
|
+
else if (valueOrChecker) {
|
|
43
42
|
typesCheckers[key] = valueOrChecker;
|
|
44
43
|
}
|
|
45
44
|
});
|
|
@@ -53,15 +52,17 @@ function cssSyntaxMatch(value, type) {
|
|
|
53
52
|
ref = type.ref;
|
|
54
53
|
}
|
|
55
54
|
// @ts-ignore
|
|
56
|
-
const lexer = css_tree_1.
|
|
55
|
+
const lexer = (0, css_tree_1.fork)({
|
|
57
56
|
types: typesExtended,
|
|
58
57
|
properties: propsExtended,
|
|
59
58
|
}).lexer;
|
|
60
59
|
Object.keys(typesCheckers).forEach(key => {
|
|
61
60
|
const checker = typesCheckers[key];
|
|
62
|
-
|
|
61
|
+
// @ts-ignore
|
|
62
|
+
lexer.addType_(key, (token, getNextToken) => checker === null || checker === void 0 ? void 0 : checker(token, getNextToken, cssSyntaxMatch));
|
|
63
63
|
});
|
|
64
64
|
const { isProp, name } = detectName(defName);
|
|
65
|
+
// @ts-ignore
|
|
65
66
|
const matcher = isProp ? lexer.properties[name] : lexer.types[name];
|
|
66
67
|
if (!matcher) {
|
|
67
68
|
(0, debug_1.log)('"%s" CSS syntax not found', defName);
|
|
@@ -79,12 +80,12 @@ function cssSyntaxMatch(value, type) {
|
|
|
79
80
|
(0, debug_1.log)('css-tree/result: %O', result);
|
|
80
81
|
// eslint-disable-next-line no-console
|
|
81
82
|
console.warn = _w;
|
|
82
|
-
if (result.
|
|
83
|
-
if (debug_1.log.enabled) {
|
|
84
|
-
(0, debug_1.log)('css-tree/result.matched: %s', JSON.stringify(result.matched, null, 2));
|
|
85
|
-
}
|
|
83
|
+
if (!result.error) {
|
|
86
84
|
return (0, match_result_1.matched)();
|
|
87
85
|
}
|
|
86
|
+
if (!('css' in result.error)) {
|
|
87
|
+
throw result.error;
|
|
88
|
+
}
|
|
88
89
|
const error = result.error;
|
|
89
90
|
if (caseSensitive) {
|
|
90
91
|
const offset = error.mismatchOffset % MIMIC_LENGTH;
|
|
@@ -125,8 +126,21 @@ function detectName(def) {
|
|
|
125
126
|
name,
|
|
126
127
|
};
|
|
127
128
|
}
|
|
128
|
-
|
|
129
|
+
/**
|
|
130
|
+
*
|
|
131
|
+
* @param key
|
|
132
|
+
* @param obj
|
|
133
|
+
* @modifies obj
|
|
134
|
+
* @returns
|
|
135
|
+
*/
|
|
136
|
+
function eachMimicCases(key,
|
|
137
|
+
// Mutable
|
|
138
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
|
|
139
|
+
obj) {
|
|
129
140
|
const value = obj[key];
|
|
141
|
+
if (!value) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
130
144
|
obj[key] = mimicCases(value);
|
|
131
145
|
}
|
|
132
146
|
function mimicCases(value) {
|
package/lib/css-syntax.spec.js
CHANGED
package/lib/defs.js
CHANGED
|
@@ -431,7 +431,7 @@ exports.types = {
|
|
|
431
431
|
if (!height) {
|
|
432
432
|
return sep.unmatched({ reason: 'unexpected-token' });
|
|
433
433
|
}
|
|
434
|
-
if (tail && tail
|
|
434
|
+
if (tail && tail[0]) {
|
|
435
435
|
return tail[0].unmatched({ reason: 'extra-token' });
|
|
436
436
|
}
|
|
437
437
|
if (!(0, primitive_1.isUint)(width.value)) {
|
package/lib/enum.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { Result } from './types';
|
|
2
2
|
import type { Enum } from './types.schema';
|
|
3
|
-
|
|
3
|
+
import type { ReadonlyDeep } from 'type-fest';
|
|
4
|
+
export declare function checkEnum(value: string, type: ReadonlyDeep<Enum>, ref?: string): Result;
|
package/lib/enum.js
CHANGED
|
@@ -9,7 +9,7 @@ function checkEnum(value, type, ref) {
|
|
|
9
9
|
if (!disallowToSurroundBySpaces) {
|
|
10
10
|
value = value.trim();
|
|
11
11
|
}
|
|
12
|
-
let values = type.enum;
|
|
12
|
+
let values = type.enum.slice();
|
|
13
13
|
if (caseInsensitive) {
|
|
14
14
|
value = value.toLowerCase();
|
|
15
15
|
values = type.enum.map(v => v.toLowerCase());
|
package/lib/get-candidate.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
type NullableString = string | null | undefined;
|
|
2
|
-
export declare function getCandidate(value: NullableString, ...candidates: (NullableString | NullableString[])[]): string | undefined;
|
|
2
|
+
export declare function getCandidate(value: NullableString, ...candidates: readonly (NullableString | readonly NullableString[])[]): string | undefined;
|
|
3
3
|
export {};
|
package/lib/list.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { Result } from './types';
|
|
2
2
|
import type { List } from './types.schema';
|
|
3
|
-
|
|
3
|
+
import type { ReadonlyDeep } from 'type-fest';
|
|
4
|
+
export declare function checkList(value: string, type: ReadonlyDeep<List>, ref?: string, cache?: boolean): Result;
|
package/lib/list.spec.js
CHANGED
package/lib/match-result.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { FormattedPrimitiveTypeCheck, MatchedResult, UnmatchedResult, UnmatchedResultOptions, UnmatchedResultReason } from './types';
|
|
2
2
|
export declare function matches(checker: FormattedPrimitiveTypeCheck, options?: UnmatchedResultOptions & {
|
|
3
|
-
ref?: string;
|
|
4
|
-
reason?: UnmatchedResultReason;
|
|
3
|
+
readonly ref?: string;
|
|
4
|
+
readonly reason?: UnmatchedResultReason;
|
|
5
5
|
}): (value: string) => MatchedResult | UnmatchedResult;
|
|
6
6
|
export declare function matched(): MatchedResult;
|
|
7
7
|
export declare function unmatched(value: string, reason?: UnmatchedResultReason, options?: UnmatchedResultOptions & {
|
|
8
|
-
ref?: string;
|
|
8
|
+
readonly ref?: string;
|
|
9
9
|
}): UnmatchedResult;
|
package/lib/number.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { Result } from './types';
|
|
2
2
|
import type { Number } from './types.schema';
|
|
3
|
-
export declare function checkNumber(value: string, type: Number
|
|
3
|
+
export declare function checkNumber(value: string, type: Readonly<Number>, ref?: string): Result;
|
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* @param units
|
|
5
5
|
* @param numberType
|
|
6
6
|
*/
|
|
7
|
-
export declare function isQuantity(value: string, units: string[], numberType?: 'int' | 'uint' | 'float'): boolean;
|
|
7
|
+
export declare function isQuantity(value: string, units: readonly string[], numberType?: 'int' | 'uint' | 'float'): boolean;
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
import type { TokenValue } from './types';
|
|
1
2
|
import type { UnmatchedResult } from '..';
|
|
2
3
|
import type { Expect, Result, List } from '../types';
|
|
4
|
+
import type { ReadonlyDeep } from 'type-fest';
|
|
3
5
|
import { Token } from './token';
|
|
4
6
|
type TokenCollectionOptions = Partial<Omit<List, 'token'> & {
|
|
5
7
|
specificSeparator: string | string[];
|
|
6
8
|
}>;
|
|
7
|
-
export type TokenEachCheck = (head: Token | null, tail: TokenCollection) => Result | void;
|
|
9
|
+
export type TokenEachCheck = (head: Readonly<Token> | null, tail: ReadonlyDeep<TokenCollection>) => Result | void;
|
|
8
10
|
export declare class TokenCollection extends Array<Token> {
|
|
9
|
-
static fromPatterns(value: Token | string, patterns: RegExp[], typeOptions?: Omit<TokenCollectionOptions, 'specificSeparator'> & {
|
|
11
|
+
static fromPatterns(value: Readonly<Token> | string, patterns: readonly Readonly<RegExp>[], typeOptions?: ReadonlyDeep<Omit<TokenCollectionOptions, 'specificSeparator'> & {
|
|
10
12
|
repeat?: boolean;
|
|
11
|
-
}): TokenCollection;
|
|
13
|
+
}>): TokenCollection;
|
|
12
14
|
static get [Symbol.species](): ArrayConstructor;
|
|
13
15
|
readonly allowEmpty: NonNullable<List['allowEmpty']>;
|
|
14
16
|
readonly caseInsensitive: NonNullable<List['caseInsensitive']>;
|
|
@@ -17,7 +19,7 @@ export declare class TokenCollection extends Array<Token> {
|
|
|
17
19
|
readonly ordered: NonNullable<List['ordered']>;
|
|
18
20
|
readonly separator: NonNullable<List['separator']>;
|
|
19
21
|
readonly unique: NonNullable<List['unique']>;
|
|
20
|
-
constructor(value?: string, typeOptions?: TokenCollectionOptions);
|
|
22
|
+
constructor(value?: string, typeOptions?: ReadonlyDeep<TokenCollectionOptions>);
|
|
21
23
|
constructor(value?: number);
|
|
22
24
|
get value(): string;
|
|
23
25
|
check(options?: {
|
|
@@ -26,18 +28,18 @@ export declare class TokenCollection extends Array<Token> {
|
|
|
26
28
|
cache?: boolean;
|
|
27
29
|
}): import("..").MatchedResult | UnmatchedResult;
|
|
28
30
|
chunk(split: number): TokenCollection[];
|
|
29
|
-
compareTokens(callback: (prev: Token
|
|
31
|
+
compareTokens(callback: (prev: Readonly<Token>, current: Readonly<Token>) => Readonly<Token> | null | void): Readonly<Token> | null | undefined;
|
|
30
32
|
divide(position: number): readonly [TokenCollection, TokenCollection];
|
|
31
|
-
eachCheck(...callbacks: TokenEachCheck[]): Result;
|
|
32
|
-
filter(callback:
|
|
33
|
-
getConsecutiveToken(tokenType: number): Token | null;
|
|
33
|
+
eachCheck(...callbacks: readonly TokenEachCheck[]): Result;
|
|
34
|
+
filter(callback: Parameters<Array<Token>['filter']>[0]): TokenCollection;
|
|
35
|
+
getConsecutiveToken(tokenType: number): Readonly<Token> | null;
|
|
34
36
|
getDuplicated(): Token | null;
|
|
35
37
|
getIdentTokens(): TokenCollection;
|
|
36
38
|
/**
|
|
37
39
|
*
|
|
38
40
|
* @param value The token value or the token type or its list
|
|
39
41
|
*/
|
|
40
|
-
has(value:
|
|
42
|
+
has(value: TokenValue): boolean;
|
|
41
43
|
headAndTail(): {
|
|
42
44
|
head: Token | null;
|
|
43
45
|
tail: TokenCollection;
|
|
@@ -46,10 +48,10 @@ export declare class TokenCollection extends Array<Token> {
|
|
|
46
48
|
*
|
|
47
49
|
* @param value The token value or the token type or its list
|
|
48
50
|
*/
|
|
49
|
-
search(value:
|
|
51
|
+
search(value: TokenValue): Token | null;
|
|
50
52
|
takeTurns(tokenNumbers: ReadonlyArray<number>, lastTokenNumber?: number): {
|
|
51
53
|
unexpectedLastToken: boolean;
|
|
52
|
-
expectedTokenNumber: number;
|
|
54
|
+
expectedTokenNumber: number | undefined;
|
|
53
55
|
token: Token;
|
|
54
56
|
} | null;
|
|
55
57
|
toJSON(): {
|
|
@@ -5,12 +5,12 @@ const match_result_1 = require("../match-result");
|
|
|
5
5
|
const token_1 = require("./token");
|
|
6
6
|
class TokenCollection extends Array {
|
|
7
7
|
static fromPatterns(value, patterns, typeOptions) {
|
|
8
|
-
const
|
|
8
|
+
const originalValue = typeof value === 'string' ? value : value.originalValue;
|
|
9
9
|
let strings = typeof value === 'string' ? value : value.value;
|
|
10
10
|
let cumulativeOffset = typeof value === 'string' ? 0 : value.offset;
|
|
11
11
|
const tokens = [];
|
|
12
12
|
function addToken(tokenValue) {
|
|
13
|
-
const token = new token_1.Token(tokenValue, cumulativeOffset,
|
|
13
|
+
const token = new token_1.Token(tokenValue, cumulativeOffset, originalValue);
|
|
14
14
|
tokens.push(token);
|
|
15
15
|
strings = strings.slice(tokenValue.length);
|
|
16
16
|
cumulativeOffset += tokenValue.length;
|
|
@@ -71,11 +71,11 @@ class TokenCollection extends Array {
|
|
|
71
71
|
separators.push(',');
|
|
72
72
|
}
|
|
73
73
|
if (typeOptions === null || typeOptions === void 0 ? void 0 : typeOptions.specificSeparator) {
|
|
74
|
-
if (
|
|
75
|
-
separators.push(
|
|
74
|
+
if (typeof typeOptions.specificSeparator === 'string') {
|
|
75
|
+
separators.push(typeOptions.specificSeparator);
|
|
76
76
|
}
|
|
77
77
|
else {
|
|
78
|
-
separators.push(typeOptions.specificSeparator);
|
|
78
|
+
separators.push(...typeOptions.specificSeparator);
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
const chars = value.split('');
|
|
@@ -88,8 +88,9 @@ class TokenCollection extends Array {
|
|
|
88
88
|
continue;
|
|
89
89
|
}
|
|
90
90
|
const lastChar = last[0];
|
|
91
|
-
if (
|
|
92
|
-
!separators.includes(
|
|
91
|
+
if (lastChar &&
|
|
92
|
+
!separators.includes(char) &&
|
|
93
|
+
!separators.includes(lastChar) &&
|
|
93
94
|
((token_1.Token.whitespace.includes(lastChar) && token_1.Token.whitespace.includes(char)) ||
|
|
94
95
|
(!token_1.Token.whitespace.includes(lastChar) && !token_1.Token.whitespace.includes(char)))) {
|
|
95
96
|
values.push(last + char);
|
|
@@ -353,6 +354,9 @@ class TokenCollection extends Array {
|
|
|
353
354
|
const tokens = this.slice();
|
|
354
355
|
for (let i = 0; i < tokens.length; i++) {
|
|
355
356
|
const token = tokens[i];
|
|
357
|
+
if (!token) {
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
356
360
|
const expectedTokenNumber = tokenNumbers[i % tokenNumbers.length];
|
|
357
361
|
if (token.type !== expectedTokenNumber) {
|
|
358
362
|
return {
|
package/lib/token/token.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { TokenValue } from './types';
|
|
1
2
|
import type { UnmatchedResult, UnmatchedResultOptions, UnmatchedResultReason } from '../types';
|
|
2
3
|
export declare class Token {
|
|
3
|
-
#private;
|
|
4
4
|
/**
|
|
5
5
|
* @see https://github.com/csstree/csstree/blob/master/lib/tokenizer/types.js
|
|
6
6
|
*/
|
|
@@ -20,28 +20,29 @@ export declare class Token {
|
|
|
20
20
|
static readonly whitespace: ReadonlyArray<string>;
|
|
21
21
|
static getCol(value: string, offset: number): number;
|
|
22
22
|
static getLine(value: string, offset: number): number;
|
|
23
|
-
static getType(value: string, separators?: string[]): 1 | 13 | 18;
|
|
24
|
-
static shiftLocation(token: Token
|
|
23
|
+
static getType(value: string, separators?: readonly string[]): 1 | 13 | 18;
|
|
24
|
+
static shiftLocation(token: Readonly<Token>, offset: number): {
|
|
25
25
|
offset: number;
|
|
26
26
|
line: number;
|
|
27
27
|
column: number;
|
|
28
28
|
};
|
|
29
29
|
readonly offset: number;
|
|
30
|
+
readonly originalValue: string;
|
|
30
31
|
readonly type: number;
|
|
31
32
|
readonly value: string;
|
|
32
|
-
constructor(value: string, offset: number, originalValue: string, separators?: string[]);
|
|
33
|
+
constructor(value: string, offset: number, originalValue: string, separators?: readonly string[]);
|
|
33
34
|
get length(): number;
|
|
34
|
-
|
|
35
|
+
clone(): Token;
|
|
35
36
|
/**
|
|
36
37
|
*
|
|
37
38
|
* @param value The token value or the token type or its list
|
|
38
39
|
*/
|
|
39
|
-
includes(value:
|
|
40
|
+
includes(value: TokenValue, caseInsensitive?: boolean): boolean;
|
|
40
41
|
/**
|
|
41
42
|
*
|
|
42
43
|
* @param value The token value or the token type or its list
|
|
43
44
|
*/
|
|
44
|
-
match(value:
|
|
45
|
+
match(value: TokenValue, caseInsensitive?: boolean): boolean;
|
|
45
46
|
toJSON(): {
|
|
46
47
|
type: number;
|
|
47
48
|
value: string;
|
|
@@ -49,7 +50,7 @@ export declare class Token {
|
|
|
49
50
|
};
|
|
50
51
|
toNumber(): number;
|
|
51
52
|
unmatched(options?: UnmatchedResultOptions & {
|
|
52
|
-
ref?: string;
|
|
53
|
-
reason?: UnmatchedResultReason;
|
|
53
|
+
readonly ref?: string;
|
|
54
|
+
readonly reason?: UnmatchedResultReason;
|
|
54
55
|
}): UnmatchedResult;
|
|
55
56
|
}
|
package/lib/token/token.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var _Token_originalValue;
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
exports.Token = void 0;
|
|
5
|
-
const tslib_1 = require("tslib");
|
|
6
4
|
class Token {
|
|
7
5
|
static getCol(value, offset) {
|
|
6
|
+
var _a;
|
|
8
7
|
const lines = value.slice(0, offset).split(/\n/g);
|
|
9
|
-
return lines[lines.length - 1].length + 1;
|
|
8
|
+
return ((_a = lines[lines.length - 1]) !== null && _a !== void 0 ? _a : '').length + 1;
|
|
10
9
|
}
|
|
11
10
|
static getLine(value, offset) {
|
|
12
11
|
return value.slice(0, offset).split(/\n/g).length;
|
|
13
12
|
}
|
|
14
13
|
static getType(value, separators) {
|
|
15
|
-
|
|
14
|
+
var _a, _b;
|
|
15
|
+
if (Token.whitespace.includes((_a = value[0]) !== null && _a !== void 0 ? _a : '')) {
|
|
16
16
|
return Token.WhiteSpace;
|
|
17
17
|
}
|
|
18
|
-
if (separators === null || separators === void 0 ? void 0 : separators.includes(value[0])) {
|
|
18
|
+
if (separators === null || separators === void 0 ? void 0 : separators.includes((_b = value[0]) !== null && _b !== void 0 ? _b : '')) {
|
|
19
19
|
switch (value[0]) {
|
|
20
20
|
case ',':
|
|
21
21
|
return Token.Comma;
|
|
@@ -27,22 +27,21 @@ class Token {
|
|
|
27
27
|
const shifted = token.offset + offset;
|
|
28
28
|
return {
|
|
29
29
|
offset: shifted,
|
|
30
|
-
line: Token.getLine(
|
|
31
|
-
column: Token.getCol(
|
|
30
|
+
line: Token.getLine(token.originalValue, shifted),
|
|
31
|
+
column: Token.getCol(token.originalValue, shifted),
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
constructor(value, offset, originalValue, separators) {
|
|
35
|
-
_Token_originalValue.set(this, void 0);
|
|
36
35
|
this.type = Token.getType(value, separators);
|
|
37
36
|
this.value = value;
|
|
38
37
|
this.offset = offset;
|
|
39
|
-
|
|
38
|
+
this.originalValue = originalValue;
|
|
40
39
|
}
|
|
41
40
|
get length() {
|
|
42
41
|
return this.value.length;
|
|
43
42
|
}
|
|
44
|
-
|
|
45
|
-
return
|
|
43
|
+
clone() {
|
|
44
|
+
return new Token(this.value, this.offset, this.originalValue);
|
|
46
45
|
}
|
|
47
46
|
/**
|
|
48
47
|
*
|
|
@@ -101,14 +100,12 @@ class Token {
|
|
|
101
100
|
raw: this.value,
|
|
102
101
|
offset: this.offset,
|
|
103
102
|
length: this.value.length,
|
|
104
|
-
line: Token.getLine(
|
|
105
|
-
column: Token.getCol(
|
|
103
|
+
line: Token.getLine(this.originalValue, this.offset),
|
|
104
|
+
column: Token.getCol(this.originalValue, this.offset),
|
|
106
105
|
reason: (_a = options === null || options === void 0 ? void 0 : options.reason) !== null && _a !== void 0 ? _a : 'syntax-error',
|
|
107
106
|
};
|
|
108
107
|
}
|
|
109
108
|
}
|
|
110
|
-
exports.Token = Token;
|
|
111
|
-
_Token_originalValue = new WeakMap();
|
|
112
109
|
/**
|
|
113
110
|
* @see https://github.com/csstree/csstree/blob/master/lib/tokenizer/types.js
|
|
114
111
|
*/
|
|
@@ -126,3 +123,4 @@ Token.WhiteSpace = 13;
|
|
|
126
123
|
* @see https://infra.spec.whatwg.org/#ascii-whitespace
|
|
127
124
|
*/
|
|
128
125
|
Token.whitespace = ['\u0009', '\u000A', '\u000C', '\u000D', '\u0020'];
|
|
126
|
+
exports.Token = Token;
|
package/lib/types.d.ts
CHANGED
|
@@ -2,77 +2,77 @@ import type { cssSyntaxMatch } from './css-syntax';
|
|
|
2
2
|
export type { Type, List, Enum, CssSyntax, KeywordDefinedType, Number } from './types.schema';
|
|
3
3
|
export type Result = UnmatchedResult | MatchedResult;
|
|
4
4
|
export type UnmatchedResult = {
|
|
5
|
-
matched: false;
|
|
6
|
-
ref: string | null;
|
|
7
|
-
raw: string;
|
|
8
|
-
length: number;
|
|
9
|
-
offset: number;
|
|
10
|
-
line: number;
|
|
11
|
-
column: number;
|
|
12
|
-
reason: UnmatchedResultReason;
|
|
13
|
-
passCount?: number;
|
|
5
|
+
readonly matched: false;
|
|
6
|
+
readonly ref: string | null;
|
|
7
|
+
readonly raw: string;
|
|
8
|
+
readonly length: number;
|
|
9
|
+
readonly offset: number;
|
|
10
|
+
readonly line: number;
|
|
11
|
+
readonly column: number;
|
|
12
|
+
readonly reason: UnmatchedResultReason;
|
|
13
|
+
readonly passCount?: number;
|
|
14
14
|
} & UnmatchedResultOptions;
|
|
15
15
|
export type UnmatchedResultOptions = {
|
|
16
|
-
partName?: string;
|
|
17
|
-
expects?: Expect[];
|
|
18
|
-
extra?: Expect;
|
|
19
|
-
candidate?: string;
|
|
16
|
+
readonly partName?: string;
|
|
17
|
+
readonly expects?: readonly Expect[];
|
|
18
|
+
readonly extra?: Expect;
|
|
19
|
+
readonly candidate?: string;
|
|
20
20
|
};
|
|
21
21
|
export type UnmatchedResultReason = 'syntax-error' | 'typo' | 'missing-token' | 'missing-comma' | 'unexpected-token' | 'unexpected-space' | 'unexpected-newline' | 'unexpected-comma' | 'empty-token' | 'out-of-range' | 'doesnt-exist-in-enum' | 'duplicated' | 'illegal-combination' | 'illegal-order' | 'extra-token' | 'must-be-percent-encoded' | 'must-be-serialized' | {
|
|
22
|
-
type: 'out-of-range';
|
|
23
|
-
gt?: number;
|
|
24
|
-
gte?: number;
|
|
25
|
-
lt?: number;
|
|
26
|
-
lte?: number;
|
|
22
|
+
readonly type: 'out-of-range';
|
|
23
|
+
readonly gt?: number;
|
|
24
|
+
readonly gte?: number;
|
|
25
|
+
readonly lt?: number;
|
|
26
|
+
readonly lte?: number;
|
|
27
27
|
} | {
|
|
28
|
-
type: 'out-of-range-length-char';
|
|
29
|
-
gte: number;
|
|
30
|
-
lte?: number;
|
|
28
|
+
readonly type: 'out-of-range-length-char';
|
|
29
|
+
readonly gte: number;
|
|
30
|
+
readonly lte?: number;
|
|
31
31
|
} | {
|
|
32
|
-
type: 'out-of-range-length-digit';
|
|
33
|
-
gte: number;
|
|
34
|
-
lte?: number;
|
|
32
|
+
readonly type: 'out-of-range-length-digit';
|
|
33
|
+
readonly gte: number;
|
|
34
|
+
readonly lte?: number;
|
|
35
35
|
};
|
|
36
36
|
export type MatchedResult = {
|
|
37
|
-
matched: true;
|
|
37
|
+
readonly matched: true;
|
|
38
38
|
};
|
|
39
39
|
export type Expect = {
|
|
40
|
-
type: 'const' | 'format' | 'syntax' | 'regexp' | 'common';
|
|
41
|
-
value: string;
|
|
40
|
+
readonly type: 'const' | 'format' | 'syntax' | 'regexp' | 'common';
|
|
41
|
+
readonly value: string;
|
|
42
42
|
};
|
|
43
43
|
export type FormattedPrimitiveTypeCheck = (value: string) => boolean;
|
|
44
44
|
export type FormattedPrimitiveTypeCreator<O = never> = (options?: O) => FormattedPrimitiveTypeCheck;
|
|
45
45
|
export type Defs = Record<string, CustomCssSyntax | CustomSyntax>;
|
|
46
46
|
export type CustomSyntax = {
|
|
47
|
-
ref: string;
|
|
48
|
-
expects?: Expect[];
|
|
49
|
-
is: CustomSyntaxCheck;
|
|
47
|
+
readonly ref: string;
|
|
48
|
+
readonly expects?: readonly Expect[];
|
|
49
|
+
readonly is: CustomSyntaxCheck;
|
|
50
50
|
};
|
|
51
51
|
export type CustomSyntaxCheck = (value: string) => Result;
|
|
52
52
|
export type CustomSyntaxChecker<O = {}> = (options?: O) => CustomSyntaxCheck;
|
|
53
53
|
export type CustomCssSyntax = {
|
|
54
|
-
ref: string;
|
|
55
|
-
caseSensitive?: boolean;
|
|
56
|
-
expects?: Expect[];
|
|
57
|
-
syntax: {
|
|
58
|
-
apply: `<${string}>`;
|
|
59
|
-
def: Record<string, string | CssSyntaxTokenizer
|
|
54
|
+
readonly ref: string;
|
|
55
|
+
readonly caseSensitive?: boolean;
|
|
56
|
+
readonly expects?: readonly Expect[];
|
|
57
|
+
readonly syntax: {
|
|
58
|
+
readonly apply: `<${string}>`;
|
|
59
|
+
readonly def: Readonly<Record<string, string | CssSyntaxTokenizer>>;
|
|
60
60
|
/**
|
|
61
61
|
* @deprecated
|
|
62
62
|
*/
|
|
63
|
-
ebnf?: Record<string, string | string[]
|
|
63
|
+
readonly ebnf?: Readonly<Record<string, string | readonly string[]>>;
|
|
64
64
|
/**
|
|
65
65
|
* @deprecated
|
|
66
66
|
*/
|
|
67
|
-
properties?: Record<string, string
|
|
67
|
+
readonly properties?: Readonly<Record<string, string>>;
|
|
68
68
|
};
|
|
69
69
|
};
|
|
70
70
|
export type CSSSyntaxToken = {
|
|
71
|
-
type: number;
|
|
72
|
-
value: string;
|
|
73
|
-
index: number;
|
|
74
|
-
balance: number;
|
|
75
|
-
node?: any;
|
|
71
|
+
readonly type: number;
|
|
72
|
+
readonly value: string;
|
|
73
|
+
readonly index: number;
|
|
74
|
+
readonly balance: number;
|
|
75
|
+
readonly node?: any;
|
|
76
76
|
};
|
|
77
|
-
export type CssSyntaxTokenizer = (token: CSSSyntaxToken | null, getNextToken: GetNextToken, match: typeof cssSyntaxMatch) => number;
|
|
77
|
+
export type CssSyntaxTokenizer = (token: Readonly<CSSSyntaxToken> | null, getNextToken: GetNextToken, match: typeof cssSyntaxMatch) => number;
|
|
78
78
|
export type GetNextToken = (length: number) => CSSSyntaxToken | null;
|
|
@@ -132,7 +132,7 @@ const checkAutoComplete = () => value => {
|
|
|
132
132
|
// > just autofill detail tokens
|
|
133
133
|
// > (i.e. the "on" and "off" keywords are not allowed).
|
|
134
134
|
if (head.match(['on', 'off'], true)) {
|
|
135
|
-
if (tail
|
|
135
|
+
if (tail[0]) {
|
|
136
136
|
acLog('[Unmatched ("%s")] Unexpected pair with "on" or "off": "%s"', value, tail.value);
|
|
137
137
|
return tail[0].unmatched({
|
|
138
138
|
reason: 'extra-token',
|
|
@@ -209,7 +209,7 @@ const checkAutoComplete = () => value => {
|
|
|
209
209
|
acLog('[Unmatched ("%s")] Unexpected token: "%s"', value, contactableFiledToken.value);
|
|
210
210
|
return contactableFiledToken.unmatched({
|
|
211
211
|
reason: 'unexpected-token',
|
|
212
|
-
expects: contactableFieldNames.
|
|
212
|
+
expects: contactableFieldNames.map(token => ({
|
|
213
213
|
type: 'const',
|
|
214
214
|
value: token,
|
|
215
215
|
})),
|
|
@@ -242,7 +242,7 @@ const checkAutoComplete = () => value => {
|
|
|
242
242
|
return (0, match_result_1.matched)();
|
|
243
243
|
}
|
|
244
244
|
if (head.match([...autofillFieldNames, ...contactableFieldNames], true)) {
|
|
245
|
-
if (tail
|
|
245
|
+
if (tail[0]) {
|
|
246
246
|
if (tail[0].match(webauthnFieldNames)) {
|
|
247
247
|
return (0, match_result_1.matched)();
|
|
248
248
|
}
|
|
@@ -299,7 +299,7 @@ const checkAutoComplete = () => value => {
|
|
|
299
299
|
candidate = (0, get_candidate_1.getCandidate)(head.value, partOfAddress, autofillFieldNames, contactingTokens, contactableFieldNames);
|
|
300
300
|
}
|
|
301
301
|
else if (!hasContactingToken) {
|
|
302
|
-
expects.push(...contactingTokens.
|
|
302
|
+
expects.push(...contactingTokens.map(token => ({
|
|
303
303
|
type: 'const',
|
|
304
304
|
value: token,
|
|
305
305
|
})));
|
|
@@ -95,6 +95,7 @@ exports.datetimeTokenCheck = {
|
|
|
95
95
|
* > then the day can be 29, as if the year was a leap year.
|
|
96
96
|
*/
|
|
97
97
|
date(date) {
|
|
98
|
+
var _a;
|
|
98
99
|
(0, debug_1.log)('Parsing Datetime Date: "%s"', date === null || date === void 0 ? void 0 : date.value);
|
|
99
100
|
if (!date || !date.value) {
|
|
100
101
|
return (0, match_result_1.unmatched)('', 'missing-token', {
|
|
@@ -120,7 +121,7 @@ exports.datetimeTokenCheck = {
|
|
|
120
121
|
const year = this._year || 2000;
|
|
121
122
|
const isLeap = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
|
|
122
123
|
const month = this._month || 1;
|
|
123
|
-
const dayOfMonth = daysOfMonth[month] + (month === 2 && isLeap ? 1 : 0);
|
|
124
|
+
const dayOfMonth = ((_a = daysOfMonth[month]) !== null && _a !== void 0 ? _a : 0) + (month === 2 && isLeap ? 1 : 0);
|
|
124
125
|
const _date = date.toNumber();
|
|
125
126
|
(0, debug_1.log)('Temporary Year and Month: %s, %s', this._year, this._month);
|
|
126
127
|
(0, debug_1.log)('Computed Year, Month, and Day of Month: %s, %s, %s', year, month, dayOfMonth);
|
|
@@ -41,6 +41,9 @@ const checkDurationISO8601LikeString = () => function checkDurationISO8601LikeSt
|
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
43
|
const [num, sign, extra] = token_1.TokenCollection.fromPatterns(d, [/[0-9]+/, /./]);
|
|
44
|
+
if (!num) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
44
47
|
(0, debug_1.log)('Date part: "%s" => %O', d.value, { num, sign });
|
|
45
48
|
if (!num.match(/^[0-9]+$/)) {
|
|
46
49
|
return num.unmatched({
|
|
@@ -121,6 +124,9 @@ const checkDurationISO8601LikeString = () => function checkDurationISO8601LikeSt
|
|
|
121
124
|
});
|
|
122
125
|
}
|
|
123
126
|
const [num, dpfp, sign] = token_1.TokenCollection.fromPatterns(t, [/[0-9]+/, /(\.[0-9]*)?/, /[^0-9]+/]);
|
|
127
|
+
if (!num) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
124
130
|
(0, debug_1.log)('Time part (h|m|s): "%s" => %O', t.value, { num, dpfp, sign });
|
|
125
131
|
if (!num.match(/^[0-9]+$/)) {
|
|
126
132
|
return num.unmatched({
|
|
@@ -131,6 +137,9 @@ const checkDurationISO8601LikeString = () => function checkDurationISO8601LikeSt
|
|
|
131
137
|
}
|
|
132
138
|
if (dpfp && dpfp.value) {
|
|
133
139
|
const [dp, fp] = token_1.TokenCollection.fromPatterns(dpfp, [/\./, /[0-9]+/]);
|
|
140
|
+
if (!dp) {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
134
143
|
(0, debug_1.log)('Second fractional part (h|m|s): "%s" => %O', dpfp.value, { dp, fp });
|
|
135
144
|
if (!dp.match('.')) {
|
|
136
145
|
return dp.unmatched({
|
|
@@ -91,6 +91,10 @@ const checkNormalizedLocalDateAndTimeString = () => function checkNormalizedLoca
|
|
|
91
91
|
* > if the given time is zero seconds past the minute)
|
|
92
92
|
*/
|
|
93
93
|
const [, , , , , , , , , , second, , fp] = tokens;
|
|
94
|
+
if (!second || !fp) {
|
|
95
|
+
(0, debug_1.log)('Failed: %O', res);
|
|
96
|
+
return res;
|
|
97
|
+
}
|
|
94
98
|
const _second = second.toNumber() || 0;
|
|
95
99
|
const _fp = fp.toNumber() || 0;
|
|
96
100
|
(0, debug_1.log)('Omitting the seconds component: "%s.%s" => %d, %d', second === null || second === void 0 ? void 0 : second.value, fp === null || fp === void 0 ? void 0 : fp.value, _second, _fp);
|
|
@@ -4,4 +4,4 @@ import type { CustomSyntaxChecker } from '../../types';
|
|
|
4
4
|
* @see https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#time-zones
|
|
5
5
|
*/
|
|
6
6
|
export declare const checkTimeZoneOffsetString: CustomSyntaxChecker;
|
|
7
|
-
export declare function parseTimeZone(zone: string | Token): import("../../types").Result;
|
|
7
|
+
export declare function parseTimeZone(zone: string | Readonly<Token>): import("../../types").Result;
|
|
@@ -27,6 +27,7 @@ function parseTimeZone(zone) {
|
|
|
27
27
|
]);
|
|
28
28
|
(0, debug_1.log)('Time-zone Part: "%s" => %O', value, zoneTokens);
|
|
29
29
|
const res = zoneTokens.eachCheck((sign, tail) => {
|
|
30
|
+
var _a, _b;
|
|
30
31
|
if (!sign || !sign.value) {
|
|
31
32
|
return (0, match_result_1.unmatched)(value, 'missing-token', {
|
|
32
33
|
expects: [
|
|
@@ -39,9 +40,9 @@ function parseTimeZone(zone) {
|
|
|
39
40
|
}
|
|
40
41
|
if (sign.match('Z')) {
|
|
41
42
|
if (tail.value) {
|
|
42
|
-
return tail[0].unmatched({
|
|
43
|
+
return ((_b = (_a = tail[0]) === null || _a === void 0 ? void 0 : _a.unmatched({
|
|
43
44
|
reason: 'extra-token',
|
|
44
|
-
});
|
|
45
|
+
})) !== null && _b !== void 0 ? _b : (0, match_result_1.unmatched)(tail.value, 'extra-token'));
|
|
45
46
|
}
|
|
46
47
|
return (0, match_result_1.matched)();
|
|
47
48
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/types",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "Type declaration and value checker",
|
|
5
5
|
"repository": "git@github.com:markuplint/markuplint.git",
|
|
6
6
|
"author": "Yusuke Hirao <yusukehirao@me.com>",
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"@types/bcp-47": "1",
|
|
31
31
|
"@types/css-tree": "^2.0.1",
|
|
32
32
|
"@types/debug": "^4.1.7",
|
|
33
|
-
"@types/whatwg-mimetype": "2"
|
|
33
|
+
"@types/whatwg-mimetype": "2",
|
|
34
|
+
"type-fest": "^3.6.1"
|
|
34
35
|
},
|
|
35
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "0c47b2c2722f6823a17f36edbab98486275f8ab4"
|
|
36
37
|
}
|