@bhsd/common 1.4.0 → 2.1.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/dist/index.d.ts +5 -0
- package/dist/index.js +22 -29
- package/dist/json_parse.js +1 -4
- package/package.json +20 -22
- package/dist/index.mjs +0 -459
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,11 @@ export declare const wmf = "wiktionary|wiki(?:pedia|books|news|quote|source|vers
|
|
|
17
17
|
* @param str 要解码的字符串
|
|
18
18
|
*/
|
|
19
19
|
export declare const rawurldecode: (str: string) => string;
|
|
20
|
+
/**
|
|
21
|
+
* 将0~255之间的整数转换为十六进制
|
|
22
|
+
* @param d 0~255之间的整数
|
|
23
|
+
*/
|
|
24
|
+
export declare const intToHex: (d: number) => string;
|
|
20
25
|
/**
|
|
21
26
|
* 将0~1之间的数字转换为十六进制
|
|
22
27
|
* @param d 0~1之间的数字
|
package/dist/index.js
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.lintJSONC = exports.lintJSON = exports.lintJSONNative = exports.splitLines = exports.getObjRegex = exports.sanitizeInlineStyle = exports.splitColors = exports.numToHex = exports.rawurldecode = exports.wmf = void 0;
|
|
4
|
-
exports.getRegex = getRegex;
|
|
5
|
-
const json_parse_js_1 = require("./json_parse.js");
|
|
6
|
-
exports.wmf = 'wiktionary|wiki(?:pedia|books|news|quote|source|versity|voyage)';
|
|
1
|
+
import { json_parse, jsonc_parse } from './json_parse.js';
|
|
2
|
+
export const wmf = 'wiktionary|wiki(?:pedia|books|news|quote|source|versity|voyage)';
|
|
7
3
|
/**
|
|
8
4
|
* PHP的`rawurldecode`函数的JavaScript实现
|
|
9
5
|
* @param str 要解码的字符串
|
|
10
6
|
*/
|
|
11
|
-
const rawurldecode = (str) => decodeURIComponent(str.replace(/%(?![\da-f]{2})/giu, '%25'));
|
|
12
|
-
|
|
7
|
+
export const rawurldecode = (str) => decodeURIComponent(str.replace(/%(?![\da-f]{2})/giu, '%25'));
|
|
8
|
+
/**
|
|
9
|
+
* 将0~255之间的整数转换为十六进制
|
|
10
|
+
* @param d 0~255之间的整数
|
|
11
|
+
*/
|
|
12
|
+
export const intToHex = (d) => Math.round(d).toString(16).padStart(2, '0');
|
|
13
13
|
/**
|
|
14
14
|
* 将0~1之间的数字转换为十六进制
|
|
15
15
|
* @param d 0~1之间的数字
|
|
16
16
|
*/
|
|
17
|
-
const numToHex = (d) =>
|
|
18
|
-
exports.numToHex = numToHex;
|
|
17
|
+
export const numToHex = (d) => intToHex(d * 255);
|
|
19
18
|
const regex = /* #__PURE__ */ (() => {
|
|
20
19
|
const hexColor = String.raw `#(?:[\da-f]{3,4}|(?:[\da-f]{2}){3,4})(?![\p{L}\p{N}_])`, rgbValue = String.raw `(?:\d*\.)?\d+%?`, hue = String.raw `(?:\d*\.)?\d+(?:deg|grad|rad|turn)?`, rgbColor = String.raw `rgba?\(\s*(?:${String.raw `${new Array(3).fill(rgbValue).join(String.raw `\s+`)}(?:\s*\/\s*${rgbValue})?`}|${String.raw `${new Array(3).fill(rgbValue).join(String.raw `\s*,\s*`)}(?:\s*,\s*${rgbValue})?`})\s*\)`, hslColor = String.raw `hsla?\(\s*(?:${String.raw `${hue}\s+${rgbValue}\s+${rgbValue}(?:\s*\/\s*${rgbValue})?`}|${String.raw `${hue}${String.raw `\s*,\s*(?:\d*\.)?\d+%`.repeat(2)}(?:\s*,\s*${rgbValue})?`})\s*\)`;
|
|
21
20
|
return {
|
|
@@ -28,7 +27,7 @@ const regex = /* #__PURE__ */ (() => {
|
|
|
28
27
|
* @param str 字符串
|
|
29
28
|
* @param hsl 是否包含 HSL
|
|
30
29
|
*/
|
|
31
|
-
const splitColors = (str, hsl = true) => {
|
|
30
|
+
export const splitColors = (str, hsl = true) => {
|
|
32
31
|
const pieces = [], re = regex[hsl ? 'full' : 'rgb'];
|
|
33
32
|
re.lastIndex = 0;
|
|
34
33
|
let mt = re.exec(str), lastIndex = 0;
|
|
@@ -46,15 +45,13 @@ const splitColors = (str, hsl = true) => {
|
|
|
46
45
|
}
|
|
47
46
|
return pieces;
|
|
48
47
|
};
|
|
49
|
-
exports.splitColors = splitColors;
|
|
50
48
|
/**
|
|
51
49
|
* 清理内联样式中的`{`和`}`
|
|
52
50
|
* @param style 内联样式
|
|
53
51
|
*/
|
|
54
|
-
const sanitizeInlineStyle = (style) => style.replace(/[{}]/gu, p => p === '{' ? '{' : '}')
|
|
55
|
-
.replace(/^[\s;]+/u, p => p.
|
|
56
|
-
|
|
57
|
-
function getRegex(f) {
|
|
52
|
+
export const sanitizeInlineStyle = (style) => style.replace(/[{}]/gu, p => p === '{' ? '{' : '}')
|
|
53
|
+
.replace(/^[\s;]+/u, p => p.replaceAll(';', ' '));
|
|
54
|
+
export function getRegex(f) {
|
|
58
55
|
const map = new Map(), weakMap = new WeakMap();
|
|
59
56
|
return s => {
|
|
60
57
|
const regexp = typeof s === 'string' ? map : weakMap;
|
|
@@ -73,12 +70,12 @@ function getRegex(f) {
|
|
|
73
70
|
* @param f 生成正则表达式的函数
|
|
74
71
|
* @deprecated 需要改为使用`getRegex`
|
|
75
72
|
*/
|
|
76
|
-
|
|
73
|
+
export const getObjRegex = getRegex;
|
|
77
74
|
/**
|
|
78
75
|
* 按行分割字符串并记录每行的起止位置
|
|
79
76
|
* @param str 字符串
|
|
80
77
|
*/
|
|
81
|
-
const splitLines = (str) => {
|
|
78
|
+
export const splitLines = (str) => {
|
|
82
79
|
const lines = [];
|
|
83
80
|
let start = 0;
|
|
84
81
|
for (const line of str.split('\n')) {
|
|
@@ -88,12 +85,11 @@ const splitLines = (str) => {
|
|
|
88
85
|
}
|
|
89
86
|
return lines;
|
|
90
87
|
};
|
|
91
|
-
exports.splitLines = splitLines;
|
|
92
88
|
const mt2num = (mt) => mt && Number(mt[1]);
|
|
93
89
|
const formatJsonError = (str, errors) => {
|
|
94
90
|
let lines;
|
|
95
91
|
const offsetToPosition = (offset) => {
|
|
96
|
-
lines ??=
|
|
92
|
+
lines ??= splitLines(str);
|
|
97
93
|
const line = lines.findIndex(([, , end]) => offset <= end) + 1;
|
|
98
94
|
return {
|
|
99
95
|
line,
|
|
@@ -104,7 +100,7 @@ const formatJsonError = (str, errors) => {
|
|
|
104
100
|
const { line, column, from, to } = error;
|
|
105
101
|
if (from === null || from === undefined) {
|
|
106
102
|
if (line) {
|
|
107
|
-
lines ??=
|
|
103
|
+
lines ??= splitLines(str);
|
|
108
104
|
error.column ??= 1;
|
|
109
105
|
error.from = lines[line - 1][1] + (error.column - 1);
|
|
110
106
|
}
|
|
@@ -129,7 +125,7 @@ const formatJsonError = (str, errors) => {
|
|
|
129
125
|
* @param str JSON字符串
|
|
130
126
|
* @param force 是否强制诊断
|
|
131
127
|
*/
|
|
132
|
-
const lintJSONNative = (str, force) => {
|
|
128
|
+
export const lintJSONNative = (str, force) => {
|
|
133
129
|
if (force || str.trim()) {
|
|
134
130
|
try {
|
|
135
131
|
JSON.parse(str);
|
|
@@ -141,7 +137,6 @@ const lintJSONNative = (str, force) => {
|
|
|
141
137
|
}
|
|
142
138
|
return [];
|
|
143
139
|
};
|
|
144
|
-
exports.lintJSONNative = lintJSONNative;
|
|
145
140
|
const lintJSONBase = (str, parse) => {
|
|
146
141
|
try {
|
|
147
142
|
parse(str);
|
|
@@ -161,17 +156,15 @@ const lintJSONBase = (str, parse) => {
|
|
|
161
156
|
* 诊断JSON字符串中的语法错误
|
|
162
157
|
* @param str JSON字符串
|
|
163
158
|
*/
|
|
164
|
-
const lintJSON = (str) => {
|
|
159
|
+
export const lintJSON = (str) => {
|
|
165
160
|
if (!str.trim()) {
|
|
166
161
|
return [];
|
|
167
162
|
}
|
|
168
|
-
const errors = lintJSONBase(str,
|
|
169
|
-
return errors[errors.length - 1]?.severity === 'error' ? errors : [...errors, ...
|
|
163
|
+
const errors = lintJSONBase(str, json_parse);
|
|
164
|
+
return errors[errors.length - 1]?.severity === 'error' ? errors : [...errors, ...lintJSONNative(str)];
|
|
170
165
|
};
|
|
171
|
-
exports.lintJSON = lintJSON;
|
|
172
166
|
/**
|
|
173
167
|
* 诊断JSONC字符串中的语法错误
|
|
174
168
|
* @param str JSONC字符串
|
|
175
169
|
*/
|
|
176
|
-
const lintJSONC = (str) => str.trim() ? lintJSONBase(str,
|
|
177
|
-
exports.lintJSONC = lintJSONC;
|
|
170
|
+
export const lintJSONC = (str) => str.trim() ? lintJSONBase(str, jsonc_parse) : [];
|
package/dist/json_parse.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/*
|
|
3
2
|
json_parse.js
|
|
4
3
|
2016-05-02
|
|
@@ -27,8 +26,6 @@
|
|
|
27
26
|
|
|
28
27
|
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO NOT CONTROL.
|
|
29
28
|
*/
|
|
30
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
-
exports.jsonc_parse = exports.json_parse = void 0;
|
|
32
29
|
const escapee = {
|
|
33
30
|
'"': '"',
|
|
34
31
|
"\\": "\\",
|
|
@@ -395,4 +392,4 @@ const factory = (jsonc) => {
|
|
|
395
392
|
}
|
|
396
393
|
};
|
|
397
394
|
};
|
|
398
|
-
|
|
395
|
+
export const json_parse = /* @__PURE__ */ factory(), jsonc_parse = /* @__PURE__ */ factory(true);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bhsd/common",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"homepage": "https://github.com/bhsd-harry/common#readme",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/bhsd-harry/common/issues"
|
|
@@ -9,44 +9,42 @@
|
|
|
9
9
|
"author": "Bhsd",
|
|
10
10
|
"files": [
|
|
11
11
|
"/dist/*.js",
|
|
12
|
-
"/dist/index.mjs",
|
|
13
12
|
"/dist/index.d.ts"
|
|
14
13
|
],
|
|
15
|
-
"
|
|
16
|
-
".": {
|
|
17
|
-
"types": "./dist/index.d.ts",
|
|
18
|
-
"import": "./dist/index.mjs",
|
|
19
|
-
"require": "./dist/index.js"
|
|
20
|
-
}
|
|
21
|
-
},
|
|
14
|
+
"main": "./dist/index.js",
|
|
22
15
|
"types": "./dist/index.d.ts",
|
|
16
|
+
"type": "module",
|
|
23
17
|
"sideEffects": false,
|
|
24
18
|
"scripts": {
|
|
19
|
+
"ls": "npm i --package-lock-only && npm ls --package-lock-only --all --omit=dev",
|
|
25
20
|
"prepublishOnly": "npm run build",
|
|
26
|
-
"build": "tsc
|
|
21
|
+
"build": "tsc",
|
|
27
22
|
"lint:ts": "tsc --noEmit && eslint --cache .",
|
|
28
23
|
"lint": "npm run lint:ts",
|
|
29
24
|
"test": "mocha"
|
|
30
25
|
},
|
|
31
26
|
"devDependencies": {
|
|
32
|
-
"@bhsd/code-standard": "^2.
|
|
27
|
+
"@bhsd/code-standard": "^2.3.0",
|
|
28
|
+
"@eslint-community/eslint-plugin-eslint-comments": "^4.7.1",
|
|
33
29
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
34
30
|
"@types/mocha": "^10.0.10",
|
|
35
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
36
|
-
"@typescript-eslint/parser": "^8.
|
|
37
|
-
"esbuild": "^0.
|
|
38
|
-
"eslint": "^
|
|
39
|
-
"eslint-plugin-es-x": "^9.
|
|
40
|
-
"eslint-plugin-
|
|
41
|
-
"eslint-plugin-
|
|
42
|
-
"eslint-plugin-jsonc": "^3.1.1",
|
|
31
|
+
"@typescript-eslint/eslint-plugin": "^8.59.0",
|
|
32
|
+
"@typescript-eslint/parser": "^8.59.0",
|
|
33
|
+
"esbuild": "^0.28.0",
|
|
34
|
+
"eslint": "^10.2.1",
|
|
35
|
+
"eslint-plugin-es-x": "^9.6.0",
|
|
36
|
+
"eslint-plugin-jsdoc": "^62.9.0",
|
|
37
|
+
"eslint-plugin-jsonc": "^3.1.2",
|
|
43
38
|
"eslint-plugin-promise": "^7.2.1",
|
|
44
39
|
"eslint-plugin-regexp": "^3.1.0",
|
|
45
|
-
"eslint-plugin-unicorn": "^
|
|
40
|
+
"eslint-plugin-unicorn": "^64.0.0",
|
|
46
41
|
"mocha": "^11.7.5",
|
|
47
|
-
"typescript": "^
|
|
42
|
+
"typescript": "^6.0.3"
|
|
43
|
+
},
|
|
44
|
+
"overrides": {
|
|
45
|
+
"eslint": "^10.2.1"
|
|
48
46
|
},
|
|
49
47
|
"engines": {
|
|
50
|
-
"node": "
|
|
48
|
+
"node": "^20.19.0 || ^22.13.0 || >=24.11.0"
|
|
51
49
|
}
|
|
52
50
|
}
|
package/dist/index.mjs
DELETED
|
@@ -1,459 +0,0 @@
|
|
|
1
|
-
// src/json_parse.ts
|
|
2
|
-
var escapee = {
|
|
3
|
-
'"': '"',
|
|
4
|
-
"\\": "\\",
|
|
5
|
-
"/": "/",
|
|
6
|
-
b: "\b",
|
|
7
|
-
f: "\f",
|
|
8
|
-
n: "\n",
|
|
9
|
-
r: "\r",
|
|
10
|
-
t: " "
|
|
11
|
-
};
|
|
12
|
-
var spaces = /* @__PURE__ */ new Set([" ", " ", "\n", "\r"]);
|
|
13
|
-
var stringify = (c) => {
|
|
14
|
-
if (c === "") {
|
|
15
|
-
return "end of input";
|
|
16
|
-
}
|
|
17
|
-
return c === '"' ? `'"'` : JSON.stringify(c);
|
|
18
|
-
};
|
|
19
|
-
var factory = (jsonc) => {
|
|
20
|
-
let at;
|
|
21
|
-
let ch;
|
|
22
|
-
let text;
|
|
23
|
-
let warnings;
|
|
24
|
-
const prepareError = (e, from, to) => {
|
|
25
|
-
if (from === void 0) {
|
|
26
|
-
e.from = at - 1;
|
|
27
|
-
} else {
|
|
28
|
-
e.from = from;
|
|
29
|
-
e.to = to ?? at - 1;
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
const warn = (message, from, to) => {
|
|
33
|
-
const warning = {
|
|
34
|
-
message,
|
|
35
|
-
severity: "warning"
|
|
36
|
-
};
|
|
37
|
-
prepareError(warning, from, to);
|
|
38
|
-
warnings.push(warning);
|
|
39
|
-
};
|
|
40
|
-
const error = (message, from, to) => {
|
|
41
|
-
const e = {
|
|
42
|
-
warnings,
|
|
43
|
-
message,
|
|
44
|
-
severity: "error"
|
|
45
|
-
};
|
|
46
|
-
prepareError(e, from, to);
|
|
47
|
-
throw e;
|
|
48
|
-
};
|
|
49
|
-
const next = (c) => {
|
|
50
|
-
if (c && c !== ch) {
|
|
51
|
-
error(`Expected ${stringify(c)} instead of ${stringify(ch)}`);
|
|
52
|
-
}
|
|
53
|
-
ch = text.charAt(at);
|
|
54
|
-
at++;
|
|
55
|
-
return ch;
|
|
56
|
-
};
|
|
57
|
-
const number = () => {
|
|
58
|
-
let string2 = "";
|
|
59
|
-
const from = at - 1;
|
|
60
|
-
if (ch === "-") {
|
|
61
|
-
string2 = "-";
|
|
62
|
-
next();
|
|
63
|
-
}
|
|
64
|
-
if (ch === "0") {
|
|
65
|
-
string2 += ch;
|
|
66
|
-
next();
|
|
67
|
-
if (ch >= "0" && ch <= "9") {
|
|
68
|
-
error("Bad number");
|
|
69
|
-
}
|
|
70
|
-
} else if (ch >= "1" && ch <= "9") {
|
|
71
|
-
while (ch >= "0" && ch <= "9") {
|
|
72
|
-
string2 += ch;
|
|
73
|
-
next();
|
|
74
|
-
}
|
|
75
|
-
} else {
|
|
76
|
-
error("No number after minus sign");
|
|
77
|
-
}
|
|
78
|
-
if (ch !== "." && ch !== "e" && ch !== "E") {
|
|
79
|
-
const value3 = Number(string2);
|
|
80
|
-
if (!Number.isSafeInteger(value3)) {
|
|
81
|
-
warn("Not a safe integer", from);
|
|
82
|
-
}
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
if (ch === ".") {
|
|
86
|
-
string2 += ".";
|
|
87
|
-
next();
|
|
88
|
-
if (ch < "0" || ch > "9") {
|
|
89
|
-
error("Unterminated fractional number");
|
|
90
|
-
}
|
|
91
|
-
while (ch >= "0" && ch <= "9") {
|
|
92
|
-
string2 += ch;
|
|
93
|
-
next();
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
if (ch === "e" || ch === "E") {
|
|
97
|
-
string2 += ch;
|
|
98
|
-
next();
|
|
99
|
-
if (ch === "-" || ch === "+") {
|
|
100
|
-
string2 += ch;
|
|
101
|
-
next();
|
|
102
|
-
}
|
|
103
|
-
while (ch >= "0" && ch <= "9") {
|
|
104
|
-
string2 += ch;
|
|
105
|
-
next();
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
const value2 = Number(string2);
|
|
109
|
-
if (!Number.isFinite(value2)) {
|
|
110
|
-
error("Bad number");
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
const string = () => {
|
|
114
|
-
let value2 = "";
|
|
115
|
-
if (ch === '"') {
|
|
116
|
-
while (next()) {
|
|
117
|
-
if (ch === '"') {
|
|
118
|
-
next();
|
|
119
|
-
return value2;
|
|
120
|
-
}
|
|
121
|
-
const from = at - 1;
|
|
122
|
-
if (ch === "\\") {
|
|
123
|
-
next();
|
|
124
|
-
if (ch === "u") {
|
|
125
|
-
let i = 0;
|
|
126
|
-
let uffff = 0;
|
|
127
|
-
for (; i < 4; i++) {
|
|
128
|
-
const hex = parseInt(next(), 16);
|
|
129
|
-
if (!isFinite(hex)) {
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
132
|
-
uffff = uffff * 16 + hex;
|
|
133
|
-
}
|
|
134
|
-
if (i < 4) {
|
|
135
|
-
error("Bad unicode escape", from);
|
|
136
|
-
}
|
|
137
|
-
value2 += String.fromCharCode(uffff);
|
|
138
|
-
} else if (typeof escapee[ch] === "string") {
|
|
139
|
-
value2 += escapee[ch];
|
|
140
|
-
} else {
|
|
141
|
-
error("Bad escaped character", from, at);
|
|
142
|
-
}
|
|
143
|
-
} else if (ch < " ") {
|
|
144
|
-
error("Bad control character", from, at);
|
|
145
|
-
} else {
|
|
146
|
-
value2 += ch;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
} else {
|
|
150
|
-
error(`Expected '"' instead of ${JSON.stringify(ch)}`);
|
|
151
|
-
}
|
|
152
|
-
return error("Unterminated string");
|
|
153
|
-
};
|
|
154
|
-
const white = () => {
|
|
155
|
-
while (ch) {
|
|
156
|
-
while (ch && spaces.has(ch)) {
|
|
157
|
-
next();
|
|
158
|
-
}
|
|
159
|
-
if (jsonc && ch === "/") {
|
|
160
|
-
const peek = text.charAt(at);
|
|
161
|
-
if (peek === "/") {
|
|
162
|
-
next();
|
|
163
|
-
next();
|
|
164
|
-
while (ch && ch !== "\n" && ch !== "\r") {
|
|
165
|
-
next();
|
|
166
|
-
}
|
|
167
|
-
continue;
|
|
168
|
-
} else if (peek === "*") {
|
|
169
|
-
next();
|
|
170
|
-
next();
|
|
171
|
-
while (ch && !(ch === "*" && text.charAt(at) === "/")) {
|
|
172
|
-
next();
|
|
173
|
-
}
|
|
174
|
-
if (ch === "*") {
|
|
175
|
-
next();
|
|
176
|
-
next();
|
|
177
|
-
}
|
|
178
|
-
continue;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
break;
|
|
182
|
-
}
|
|
183
|
-
};
|
|
184
|
-
const word = () => {
|
|
185
|
-
switch (ch) {
|
|
186
|
-
case "t":
|
|
187
|
-
next();
|
|
188
|
-
next("r");
|
|
189
|
-
next("u");
|
|
190
|
-
next("e");
|
|
191
|
-
return;
|
|
192
|
-
case "f":
|
|
193
|
-
next();
|
|
194
|
-
next("a");
|
|
195
|
-
next("l");
|
|
196
|
-
next("s");
|
|
197
|
-
next("e");
|
|
198
|
-
return;
|
|
199
|
-
case "n":
|
|
200
|
-
next();
|
|
201
|
-
next("u");
|
|
202
|
-
next("l");
|
|
203
|
-
next("l");
|
|
204
|
-
return;
|
|
205
|
-
default:
|
|
206
|
-
error(`Unexpected ${JSON.stringify(ch)}`);
|
|
207
|
-
}
|
|
208
|
-
};
|
|
209
|
-
const array = () => {
|
|
210
|
-
next();
|
|
211
|
-
white();
|
|
212
|
-
if (ch === "]") {
|
|
213
|
-
next();
|
|
214
|
-
return;
|
|
215
|
-
} else if (jsonc && ch === ",") {
|
|
216
|
-
next();
|
|
217
|
-
white();
|
|
218
|
-
next("]");
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
let from;
|
|
222
|
-
while (ch) {
|
|
223
|
-
if (ch === "]") {
|
|
224
|
-
if (jsonc) {
|
|
225
|
-
next();
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
error("Trailing comma in array", from, from + 1);
|
|
229
|
-
}
|
|
230
|
-
value();
|
|
231
|
-
white();
|
|
232
|
-
if (ch === "]") {
|
|
233
|
-
next();
|
|
234
|
-
return;
|
|
235
|
-
} else if (ch === ",") {
|
|
236
|
-
from = at - 1;
|
|
237
|
-
next();
|
|
238
|
-
white();
|
|
239
|
-
} else {
|
|
240
|
-
error(`Expected "," or "]" instead of ${stringify(ch)}`);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
error("Unterminated array");
|
|
244
|
-
};
|
|
245
|
-
const object = () => {
|
|
246
|
-
const keys = /* @__PURE__ */ new Set();
|
|
247
|
-
next();
|
|
248
|
-
white();
|
|
249
|
-
if (ch === "}") {
|
|
250
|
-
next();
|
|
251
|
-
return;
|
|
252
|
-
} else if (jsonc && ch === ",") {
|
|
253
|
-
next();
|
|
254
|
-
white();
|
|
255
|
-
next("}");
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
let from;
|
|
259
|
-
while (ch) {
|
|
260
|
-
if (ch === "}") {
|
|
261
|
-
if (jsonc) {
|
|
262
|
-
next();
|
|
263
|
-
return;
|
|
264
|
-
}
|
|
265
|
-
error("Trailing comma in object", from, from + 1);
|
|
266
|
-
}
|
|
267
|
-
from = at;
|
|
268
|
-
const key = string();
|
|
269
|
-
const to = at - 2;
|
|
270
|
-
white();
|
|
271
|
-
next(":");
|
|
272
|
-
if (keys.has(key)) {
|
|
273
|
-
warn(`Duplicate key ${stringify(key)}`, from, to);
|
|
274
|
-
} else {
|
|
275
|
-
keys.add(key);
|
|
276
|
-
}
|
|
277
|
-
value();
|
|
278
|
-
white();
|
|
279
|
-
if (ch === "}") {
|
|
280
|
-
next();
|
|
281
|
-
return;
|
|
282
|
-
} else if (ch === ",") {
|
|
283
|
-
from = at - 1;
|
|
284
|
-
next();
|
|
285
|
-
white();
|
|
286
|
-
} else {
|
|
287
|
-
error(`Expected "," or "}" instead of ${stringify(ch)}`);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
error(`Expected '"'`);
|
|
291
|
-
};
|
|
292
|
-
const value = () => {
|
|
293
|
-
white();
|
|
294
|
-
switch (ch) {
|
|
295
|
-
case "":
|
|
296
|
-
return void 0;
|
|
297
|
-
case "{":
|
|
298
|
-
return object();
|
|
299
|
-
case "[":
|
|
300
|
-
return array();
|
|
301
|
-
case '"':
|
|
302
|
-
return string();
|
|
303
|
-
case "-":
|
|
304
|
-
return number();
|
|
305
|
-
default:
|
|
306
|
-
return ch >= "0" && ch <= "9" ? number() : word();
|
|
307
|
-
}
|
|
308
|
-
};
|
|
309
|
-
return (source) => {
|
|
310
|
-
text = source;
|
|
311
|
-
warnings = [];
|
|
312
|
-
at = 0;
|
|
313
|
-
ch = " ";
|
|
314
|
-
value();
|
|
315
|
-
white();
|
|
316
|
-
if (ch) {
|
|
317
|
-
error("Syntax error");
|
|
318
|
-
} else if (warnings.length > 0) {
|
|
319
|
-
throw { warnings };
|
|
320
|
-
}
|
|
321
|
-
};
|
|
322
|
-
};
|
|
323
|
-
var json_parse = /* @__PURE__ */ factory();
|
|
324
|
-
var jsonc_parse = /* @__PURE__ */ factory(true);
|
|
325
|
-
|
|
326
|
-
// src/index.ts
|
|
327
|
-
var wmf = "wiktionary|wiki(?:pedia|books|news|quote|source|versity|voyage)";
|
|
328
|
-
var rawurldecode = (str) => decodeURIComponent(str.replace(/%(?![\da-f]{2})/giu, "%25"));
|
|
329
|
-
var numToHex = (d) => Math.round(d * 255).toString(16).padStart(2, "0");
|
|
330
|
-
var regex = /* @__PURE__ */ (() => {
|
|
331
|
-
const hexColor = String.raw`#(?:[\da-f]{3,4}|(?:[\da-f]{2}){3,4})(?![\p{L}\p{N}_])`, rgbValue = String.raw`(?:\d*\.)?\d+%?`, hue = String.raw`(?:\d*\.)?\d+(?:deg|grad|rad|turn)?`, rgbColor = String.raw`rgba?\(\s*(?:${String.raw`${new Array(3).fill(rgbValue).join(String.raw`\s+`)}(?:\s*\/\s*${rgbValue})?`}|${String.raw`${new Array(3).fill(rgbValue).join(String.raw`\s*,\s*`)}(?:\s*,\s*${rgbValue})?`})\s*\)`, hslColor = String.raw`hsla?\(\s*(?:${String.raw`${hue}\s+${rgbValue}\s+${rgbValue}(?:\s*\/\s*${rgbValue})?`}|${String.raw`${hue}${String.raw`\s*,\s*(?:\d*\.)?\d+%`.repeat(2)}(?:\s*,\s*${rgbValue})?`})\s*\)`;
|
|
332
|
-
return {
|
|
333
|
-
full: new RegExp(String.raw`(^|[^\p{L}\p{N}_])(${hexColor}|${rgbColor}|${hslColor})`, "giu"),
|
|
334
|
-
rgb: new RegExp(String.raw`(^|[^\p{L}\p{N}_])(${hexColor}|${rgbColor})`, "giu")
|
|
335
|
-
};
|
|
336
|
-
})();
|
|
337
|
-
var splitColors = (str, hsl = true) => {
|
|
338
|
-
const pieces = [], re = regex[hsl ? "full" : "rgb"];
|
|
339
|
-
re.lastIndex = 0;
|
|
340
|
-
let mt = re.exec(str), lastIndex = 0;
|
|
341
|
-
while (mt) {
|
|
342
|
-
const index = mt.index + mt[1].length;
|
|
343
|
-
if (index > lastIndex) {
|
|
344
|
-
pieces.push([str.slice(lastIndex, index), lastIndex, index, false]);
|
|
345
|
-
}
|
|
346
|
-
({ lastIndex } = re);
|
|
347
|
-
pieces.push([mt[2], index, lastIndex, str[index - 1] !== "&" || !/^#\d+$/u.test(mt[2])]);
|
|
348
|
-
mt = re.exec(str);
|
|
349
|
-
}
|
|
350
|
-
if (str.length > lastIndex) {
|
|
351
|
-
pieces.push([str.slice(lastIndex), lastIndex, str.length, false]);
|
|
352
|
-
}
|
|
353
|
-
return pieces;
|
|
354
|
-
};
|
|
355
|
-
var sanitizeInlineStyle = (style) => style.replace(/[{}]/gu, (p) => p === "{" ? "{" : "}").replace(/^[\s;]+/u, (p) => p.replace(/;/gu, " "));
|
|
356
|
-
function getRegex(f) {
|
|
357
|
-
const map = /* @__PURE__ */ new Map(), weakMap = /* @__PURE__ */ new WeakMap();
|
|
358
|
-
return (s) => {
|
|
359
|
-
const regexp = typeof s === "string" ? map : weakMap;
|
|
360
|
-
if (regexp.has(s)) {
|
|
361
|
-
const re2 = regexp.get(s);
|
|
362
|
-
re2.lastIndex = 0;
|
|
363
|
-
return re2;
|
|
364
|
-
}
|
|
365
|
-
const re = f(s);
|
|
366
|
-
regexp.set(s, re);
|
|
367
|
-
return re;
|
|
368
|
-
};
|
|
369
|
-
}
|
|
370
|
-
var getObjRegex = getRegex;
|
|
371
|
-
var splitLines = (str) => {
|
|
372
|
-
const lines = [];
|
|
373
|
-
let start = 0;
|
|
374
|
-
for (const line of str.split("\n")) {
|
|
375
|
-
const end = start + line.length;
|
|
376
|
-
lines.push([line, start, end]);
|
|
377
|
-
start = end + 1;
|
|
378
|
-
}
|
|
379
|
-
return lines;
|
|
380
|
-
};
|
|
381
|
-
var mt2num = (mt) => mt && Number(mt[1]);
|
|
382
|
-
var formatJsonError = (str, errors) => {
|
|
383
|
-
let lines;
|
|
384
|
-
const offsetToPosition = (offset) => {
|
|
385
|
-
lines ??= splitLines(str);
|
|
386
|
-
const line = lines.findIndex(([, , end]) => offset <= end) + 1;
|
|
387
|
-
return {
|
|
388
|
-
line,
|
|
389
|
-
column: offset - lines[line - 1][1] + 1
|
|
390
|
-
};
|
|
391
|
-
};
|
|
392
|
-
for (const error of errors) {
|
|
393
|
-
const { line, column, from, to } = error;
|
|
394
|
-
if (from === null || from === void 0) {
|
|
395
|
-
if (line) {
|
|
396
|
-
lines ??= splitLines(str);
|
|
397
|
-
error.column ??= 1;
|
|
398
|
-
error.from = lines[line - 1][1] + (error.column - 1);
|
|
399
|
-
} else {
|
|
400
|
-
error.from = 0;
|
|
401
|
-
error.line = 1;
|
|
402
|
-
error.column = 1;
|
|
403
|
-
}
|
|
404
|
-
} else if (!line || !column) {
|
|
405
|
-
Object.assign(error, offsetToPosition(from));
|
|
406
|
-
}
|
|
407
|
-
if (to !== void 0) {
|
|
408
|
-
({ line: error.endLine, column: error.endColumn } = offsetToPosition(to));
|
|
409
|
-
}
|
|
410
|
-
error.position = error.from;
|
|
411
|
-
}
|
|
412
|
-
return errors;
|
|
413
|
-
};
|
|
414
|
-
var lintJSONNative = (str, force) => {
|
|
415
|
-
if (force || str.trim()) {
|
|
416
|
-
try {
|
|
417
|
-
JSON.parse(str);
|
|
418
|
-
} catch (e) {
|
|
419
|
-
const { message } = e, line = mt2num(/\bline (\d+)/u.exec(message)), column = mt2num(/\bcolumn (\d+)/u.exec(message)), from = mt2num(/\bposition (\d+)/u.exec(message));
|
|
420
|
-
return formatJsonError(str, [{ message, line, column, from, severity: "error" }]);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
return [];
|
|
424
|
-
};
|
|
425
|
-
var lintJSONBase = (str, parse) => {
|
|
426
|
-
try {
|
|
427
|
-
parse(str);
|
|
428
|
-
} catch (e) {
|
|
429
|
-
if (!(e instanceof Error)) {
|
|
430
|
-
const { warnings, ...error } = e;
|
|
431
|
-
if (error.message) {
|
|
432
|
-
warnings.push(error);
|
|
433
|
-
}
|
|
434
|
-
return formatJsonError(str, warnings);
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
return [];
|
|
438
|
-
};
|
|
439
|
-
var lintJSON = (str) => {
|
|
440
|
-
if (!str.trim()) {
|
|
441
|
-
return [];
|
|
442
|
-
}
|
|
443
|
-
const errors = lintJSONBase(str, json_parse);
|
|
444
|
-
return errors[errors.length - 1]?.severity === "error" ? errors : [...errors, ...lintJSONNative(str)];
|
|
445
|
-
};
|
|
446
|
-
var lintJSONC = (str) => str.trim() ? lintJSONBase(str, jsonc_parse) : [];
|
|
447
|
-
export {
|
|
448
|
-
getObjRegex,
|
|
449
|
-
getRegex,
|
|
450
|
-
lintJSON,
|
|
451
|
-
lintJSONC,
|
|
452
|
-
lintJSONNative,
|
|
453
|
-
numToHex,
|
|
454
|
-
rawurldecode,
|
|
455
|
-
sanitizeInlineStyle,
|
|
456
|
-
splitColors,
|
|
457
|
-
splitLines,
|
|
458
|
-
wmf
|
|
459
|
-
};
|