@markuplint/types 5.0.0-rc.0 → 5.0.0-rc.2
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/CHANGELOG.md +27 -0
- package/README.md +7 -0
- package/docs/type-system.ja.md +90 -23
- package/docs/type-system.md +90 -23
- package/docs/validators.ja.md +12 -0
- package/docs/validators.md +12 -0
- package/lib/check-multi-types.d.ts +1 -1
- package/lib/defs.js +127 -13
- package/lib/match-result.d.ts +1 -1
- package/lib/token/token-collection.d.ts +1 -1
- package/lib/token/token.d.ts +1 -9
- package/lib/token/token.js +0 -13
- package/lib/types.schema.d.ts +9 -6
- package/lib/types.schema.js +1 -0
- package/lib/whatwg/check-email.d.ts +2 -0
- package/lib/whatwg/check-email.js +18 -0
- package/lib/whatwg/check-simple-color.d.ts +10 -0
- package/lib/whatwg/check-simple-color.js +11 -0
- package/lib/whatwg/check-url.d.ts +16 -0
- package/lib/whatwg/check-url.js +89 -0
- package/package.json +13 -11
- package/types.schema.json +125 -22
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { log } from '../debug.js';
|
|
2
|
+
import { matched, unmatched } from '../match-result.js';
|
|
3
|
+
/**
|
|
4
|
+
* Dummy base URL for resolving relative URLs.
|
|
5
|
+
* Used only for syntax validation — the actual base URL is irrelevant.
|
|
6
|
+
* Matches the approach used by nu-html-checker (galimatias).
|
|
7
|
+
*/
|
|
8
|
+
const DUMMY_BASE = 'http://example.org/foo/bar';
|
|
9
|
+
/**
|
|
10
|
+
* Characters that are illegal in URLs per WHATWG URL Standard.
|
|
11
|
+
* Tabs and newlines are stripped during parsing but are validation errors.
|
|
12
|
+
*
|
|
13
|
+
* @see https://url.spec.whatwg.org/#url-code-points
|
|
14
|
+
*/
|
|
15
|
+
// eslint-disable-next-line no-control-regex
|
|
16
|
+
const ILLEGAL_WHITESPACE = /[\t\n\r]/;
|
|
17
|
+
/**
|
|
18
|
+
* Malformed percent-encoding: `%` not followed by exactly two hex digits.
|
|
19
|
+
*/
|
|
20
|
+
const MALFORMED_PERCENT = /%(?![0-9A-F]{2})/i;
|
|
21
|
+
/**
|
|
22
|
+
* C0 control characters (U+0000–U+001F) and DEL (U+007F) are forbidden
|
|
23
|
+
* in URLs. Excludes TAB/LF/CR which are caught by ILLEGAL_WHITESPACE.
|
|
24
|
+
*/
|
|
25
|
+
// eslint-disable-next-line no-control-regex
|
|
26
|
+
const C0_CONTROL = /[\u0000-\u0008\v\u000E-\u001F\u007F]/;
|
|
27
|
+
/**
|
|
28
|
+
* Unencoded space in URL body (after trimming leading/trailing spaces).
|
|
29
|
+
* `new URL()` accepts spaces by percent-encoding them, but the WHATWG spec
|
|
30
|
+
* considers them a validation error. nu-validator rejects them.
|
|
31
|
+
*/
|
|
32
|
+
const UNENCODED_SPACE = / /;
|
|
33
|
+
/**
|
|
34
|
+
* Validates a URL string (potentially surrounded by spaces) per the WHATWG
|
|
35
|
+
* URL Standard. Accepts both absolute and relative URLs.
|
|
36
|
+
*
|
|
37
|
+
* Uses `new URL()` for structural parsing and adds strict checks matching
|
|
38
|
+
* the nu-html-checker's galimatias StrictErrorHandler behavior:
|
|
39
|
+
* - Illegal whitespace (tabs, newlines) in URL
|
|
40
|
+
* - Malformed percent-encoding
|
|
41
|
+
* - C0 control characters
|
|
42
|
+
* - URLs that fail `new URL()` parsing (even with a dummy base)
|
|
43
|
+
*
|
|
44
|
+
* @see https://html.spec.whatwg.org/multipage/urls-and-fetching.html#valid-url-potentially-surrounded-by-spaces
|
|
45
|
+
* @see https://url.spec.whatwg.org/#url-code-points
|
|
46
|
+
*/
|
|
47
|
+
export const checkURL = () => function checkURL(value) {
|
|
48
|
+
log('CHECK: url');
|
|
49
|
+
const trimmed = value.trim();
|
|
50
|
+
// Empty URL is valid for some attributes (e.g., <a href="">)
|
|
51
|
+
// The spec says "valid URL potentially surrounded by spaces"
|
|
52
|
+
// and the empty string resolves to the document's URL.
|
|
53
|
+
if (trimmed === '') {
|
|
54
|
+
return matched();
|
|
55
|
+
}
|
|
56
|
+
// Check for illegal whitespace (tab, newline, CR)
|
|
57
|
+
if (ILLEGAL_WHITESPACE.test(trimmed)) {
|
|
58
|
+
return unmatched(trimmed, 'unexpected-token');
|
|
59
|
+
}
|
|
60
|
+
// Check for C0 control characters
|
|
61
|
+
if (C0_CONTROL.test(trimmed)) {
|
|
62
|
+
return unmatched(trimmed, 'unexpected-token');
|
|
63
|
+
}
|
|
64
|
+
// Check for malformed percent-encoding
|
|
65
|
+
if (MALFORMED_PERCENT.test(trimmed)) {
|
|
66
|
+
return unmatched(trimmed, 'unexpected-token');
|
|
67
|
+
}
|
|
68
|
+
// Check for unencoded spaces
|
|
69
|
+
if (UNENCODED_SPACE.test(trimmed)) {
|
|
70
|
+
return unmatched(trimmed, 'unexpected-token');
|
|
71
|
+
}
|
|
72
|
+
// Try parsing as absolute URL first
|
|
73
|
+
try {
|
|
74
|
+
new URL(trimmed);
|
|
75
|
+
return matched();
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// Not a valid absolute URL — try as relative
|
|
79
|
+
}
|
|
80
|
+
// Try parsing as relative URL with dummy base
|
|
81
|
+
try {
|
|
82
|
+
new URL(trimmed, DUMMY_BASE);
|
|
83
|
+
return matched();
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// Both absolute and relative parsing failed
|
|
87
|
+
return unmatched(trimmed, 'unexpected-token');
|
|
88
|
+
}
|
|
89
|
+
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/types",
|
|
3
|
-
"version": "5.0.0-rc.
|
|
3
|
+
"version": "5.0.0-rc.2",
|
|
4
4
|
"description": "Type declaration and value checker",
|
|
5
|
-
"repository":
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/markuplint/markuplint.git",
|
|
8
|
+
"directory": "packages/@markuplint/types"
|
|
9
|
+
},
|
|
6
10
|
"author": "Yusuke Hirao <yusukehirao@me.com>",
|
|
7
11
|
"license": "MIT",
|
|
8
12
|
"engines": {
|
|
@@ -25,22 +29,20 @@
|
|
|
25
29
|
"build": "tsc --project tsconfig.build.json",
|
|
26
30
|
"dev": "tsc --watch --project tsconfig.build.json",
|
|
27
31
|
"clean": "tsc --build --clean tsconfig.build.json",
|
|
28
|
-
"schema": "run-s schema:types schema:schema
|
|
29
|
-
"schema:types": "tsx \"./gen/types.ts\"",
|
|
30
|
-
"schema:schema": "npx json2ts \"./types.schema.json\" > \"./src/types.schema.ts\""
|
|
31
|
-
"schema:eslint": "npx eslint --fix \"./src/types.schema.ts\"",
|
|
32
|
-
"schema:prettier": "npx prettier --write \"./src/types.schema.ts\" \"./types.schema.json\" --log-level warn"
|
|
32
|
+
"schema": "run-s schema:types schema:schema",
|
|
33
|
+
"schema:types": "npx tsx \"./gen/types.ts\"",
|
|
34
|
+
"schema:schema": "npx json2ts \"./types.schema.json\" > \"./src/types.schema.ts\""
|
|
33
35
|
},
|
|
34
36
|
"dependencies": {
|
|
35
|
-
"@markuplint/shared": "5.0.0-rc.
|
|
37
|
+
"@markuplint/shared": "5.0.0-rc.2",
|
|
36
38
|
"@types/css-tree": "2.3.11",
|
|
37
|
-
"@types/debug": "4.1.
|
|
39
|
+
"@types/debug": "4.1.13",
|
|
38
40
|
"bcp-47": "2.1.0",
|
|
39
41
|
"css-tree": "3.2.1",
|
|
40
42
|
"debug": "4.4.3",
|
|
41
43
|
"leven": "4.1.0",
|
|
42
|
-
"type-fest": "5.
|
|
44
|
+
"type-fest": "5.5.0",
|
|
43
45
|
"whatwg-mimetype": "5.0.0"
|
|
44
46
|
},
|
|
45
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "e43763858d9234c417053becc73dbd088c1e7ea6"
|
|
46
48
|
}
|