@bhsd/common 3.0.0 → 4.0.1

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 CHANGED
@@ -11,7 +11,6 @@ declare interface JsonError {
11
11
  position: number;
12
12
  }
13
13
  export type RegexGetter<T = string> = (s: T) => RegExp;
14
- export * from './color.js';
15
14
  export declare const wmf = "wiktionary|wiki(?:pedia|books|news|quote|source|versity|voyage)";
16
15
  /**
17
16
  * PHP的`rawurldecode`函数的JavaScript实现
@@ -79,3 +78,4 @@ export declare const lintJSONC: (str: string) => JsonError[];
79
78
  * @param re 其他正则表达式,默认为匹配非空白字符的正则表达式
80
79
  */
81
80
  export declare const numLeadingSpaces: (str: string, re?: RegExp) => number;
81
+ export {};
package/dist/index.js CHANGED
@@ -1,13 +1,21 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
1
12
  import { json_parse, jsonc_parse } from './json_parse.js';
2
- export * from './color.js';
3
13
  export const wmf = 'wiktionary|wiki(?:pedia|books|news|quote|source|versity|voyage)';
4
14
  /**
5
15
  * PHP的`rawurldecode`函数的JavaScript实现
6
16
  * @param str 要解码的字符串
7
17
  */
8
- export const rawurldecode = (str) =>
9
- // eslint-disable-next-line unicorn/prefer-string-replace-all
10
- decodeURIComponent(str.replace(/%(?![\da-f]{2})/giu, '%25'));
18
+ export const rawurldecode = (str) => decodeURIComponent(str.replace(/%(?![\da-f]{2})/giu, '%25'));
11
19
  /**
12
20
  * 将0~255之间的整数转换为十六进制
13
21
  * @param d 0~255之间的整数
@@ -33,7 +41,7 @@ const regex = /* #__PURE__ */ (() => {
33
41
  */
34
42
  export const splitColors = (str, names) => {
35
43
  const pieces = [], re = Array.isArray(names) && names.length > 0
36
- ? new RegExp(regex.names.replace('$1', names.join('|')), 'giu')
44
+ ? new RegExp(regex.names.replace('$1', () => names.join('|')), 'giu')
37
45
  : regex.full;
38
46
  re.lastIndex = 0;
39
47
  let mt = re.exec(str), lastIndex = 0;
@@ -55,8 +63,8 @@ export const splitColors = (str, names) => {
55
63
  * 清理内联样式中的`{`和`}`
56
64
  * @param style 内联样式
57
65
  */
58
- export const sanitizeInlineStyle = (style) => style.replaceAll(/[{}]/gu, p => p === '{' ? '{' : '}')
59
- .replace(/^[\s;]+/u, p => p.replaceAll(';', ' '));
66
+ export const sanitizeInlineStyle = (style) => style.replace(/[{}]/gu, p => p === '{' ? '{' : '}')
67
+ .replace(/^[\s;]+/u, p => p.replace(/;/gu, ' '));
60
68
  export function getRegex(f) {
61
69
  const map = new Map(), weakMap = new WeakMap();
62
70
  return s => {
@@ -93,9 +101,10 @@ export const splitLines = (str) => {
93
101
  };
94
102
  const mt2num = (mt) => mt && Number(mt[1]);
95
103
  const formatJsonError = (str, errors) => {
104
+ var _a;
96
105
  let lines;
97
106
  const offsetToPosition = (offset) => {
98
- lines ??= splitLines(str);
107
+ lines !== null && lines !== void 0 ? lines : (lines = splitLines(str));
99
108
  const line = lines.findIndex(([, , end]) => offset <= end) + 1;
100
109
  return {
101
110
  line,
@@ -106,8 +115,8 @@ const formatJsonError = (str, errors) => {
106
115
  const { line, column, from, to } = error;
107
116
  if (from === null || from === undefined) {
108
117
  if (line) {
109
- lines ??= splitLines(str);
110
- error.column ??= 1;
118
+ lines !== null && lines !== void 0 ? lines : (lines = splitLines(str));
119
+ (_a = error.column) !== null && _a !== void 0 ? _a : (error.column = 1);
111
120
  error.from = lines[line - 1][1] + (error.column - 1);
112
121
  }
113
122
  else {
@@ -149,7 +158,7 @@ const lintJSONBase = (str, parse) => {
149
158
  }
150
159
  catch (e) {
151
160
  if (!(e instanceof Error)) {
152
- const { warnings, ...error } = e;
161
+ const _a = e, { warnings } = _a, error = __rest(_a, ["warnings"]);
153
162
  if (error.message) {
154
163
  warnings.push(error);
155
164
  }
@@ -163,12 +172,13 @@ const lintJSONBase = (str, parse) => {
163
172
  * @param str JSON字符串
164
173
  */
165
174
  export const lintJSON = (str) => {
175
+ var _a;
166
176
  if (!str.trim()) {
167
177
  return [];
168
178
  }
169
179
  const errors = lintJSONBase(str, json_parse);
170
180
  // eslint-disable-next-line unicorn/prefer-at
171
- return errors[errors.length - 1]?.severity === 'error' ? errors : [...errors, ...lintJSONNative(str)];
181
+ return ((_a = errors[errors.length - 1]) === null || _a === void 0 ? void 0 : _a.severity) === 'error' ? errors : [...errors, ...lintJSONNative(str)];
172
182
  };
173
183
  /**
174
184
  * 诊断JSONC字符串中的语法错误
@@ -1,14 +1,14 @@
1
1
  export interface JsonSyntaxError {
2
2
  warnings: ExtendedJsonSyntaxError[];
3
- severity?: "error" | "warning";
3
+ severity?: 'error' | 'warning';
4
4
  message?: string;
5
5
  from?: number | null;
6
6
  to?: number;
7
7
  /** @deprecated */
8
8
  position?: number;
9
9
  }
10
- export interface ExtendedJsonSyntaxError extends Omit<JsonSyntaxError, "warnings"> {
11
- severity: "error" | "warning";
10
+ export interface ExtendedJsonSyntaxError extends Omit<JsonSyntaxError, 'warnings'> {
11
+ severity: 'error' | 'warning';
12
12
  message: string;
13
13
  line?: number | null;
14
14
  column?: number | null;
@@ -1,3 +1,4 @@
1
+ // eslint-disable-next-line @stylistic/multiline-comment-style
1
2
  /*
2
3
  json_parse.js
3
4
  2016-05-02
@@ -28,18 +29,18 @@
28
29
  */
29
30
  const escapee = {
30
31
  '"': '"',
31
- "\\": "\\",
32
- "/": "/",
33
- b: "\b",
34
- f: "\f",
35
- n: "\n",
36
- r: "\r",
37
- t: "\t",
32
+ '\\': '\\',
33
+ '/': '/',
34
+ b: '\b',
35
+ f: '\f',
36
+ n: '\n',
37
+ r: '\r',
38
+ t: '\t',
38
39
  };
39
- const spaces = new Set([" ", "\t", "\n", "\r"]);
40
+ const spaces = new Set([' ', '\t', '\n', '\r']);
40
41
  const stringify = (c) => {
41
- if (c === "") {
42
- return "end of input";
42
+ if (c === '') {
43
+ return 'end of input';
43
44
  }
44
45
  return c === '"' ? `'"'` : JSON.stringify(c);
45
46
  };
@@ -59,14 +60,14 @@ const factory = (jsonc) => {
59
60
  }
60
61
  else {
61
62
  e.from = from;
62
- e.to = to ?? at - 1;
63
+ e.to = to !== null && to !== void 0 ? to : at - 1;
63
64
  }
64
65
  };
65
66
  const warn = (message, from, to) => {
66
67
  // Log warning when something is wrong.
67
68
  const warning = {
68
69
  message,
69
- severity: "warning",
70
+ severity: 'warning',
70
71
  };
71
72
  prepareError(warning, from, to);
72
73
  warnings.push(warning);
@@ -76,7 +77,7 @@ const factory = (jsonc) => {
76
77
  const e = {
77
78
  warnings,
78
79
  message,
79
- severity: "error",
80
+ severity: 'error',
80
81
  };
81
82
  prepareError(e, from, to);
82
83
  throw e;
@@ -93,67 +94,67 @@ const factory = (jsonc) => {
93
94
  };
94
95
  const number = () => {
95
96
  // Parse a number value.
96
- let string = "";
97
+ let string = '';
97
98
  const from = at - 1;
98
- if (ch === "-") {
99
- string = "-";
99
+ if (ch === '-') {
100
+ string = '-';
100
101
  next();
101
102
  }
102
- if (ch === "0") {
103
+ if (ch === '0') {
103
104
  string += ch;
104
105
  next();
105
- if (ch >= "0" && ch <= "9") {
106
- error("Bad number");
106
+ if (ch >= '0' && ch <= '9') {
107
+ error('Bad number');
107
108
  }
108
109
  }
109
- else if (ch >= "1" && ch <= "9") {
110
- while (ch >= "0" && ch <= "9") {
110
+ else if (ch >= '1' && ch <= '9') {
111
+ while (ch >= '0' && ch <= '9') {
111
112
  string += ch;
112
113
  next();
113
114
  }
114
115
  }
115
116
  else {
116
- error("No number after minus sign");
117
+ error('No number after minus sign');
117
118
  }
118
- if (ch !== "." && ch !== "e" && ch !== "E") {
119
+ if (ch !== '.' && ch !== 'e' && ch !== 'E') {
119
120
  const value = Number(string);
120
121
  if (!Number.isSafeInteger(value)) {
121
- warn("Not a safe integer", from);
122
+ warn('Not a safe integer', from);
122
123
  }
123
124
  return;
124
125
  }
125
- if (ch === ".") {
126
- string += ".";
126
+ if (ch === '.') {
127
+ string += '.';
127
128
  next();
128
- if (ch < "0" || ch > "9") {
129
- error("Unterminated fractional number");
129
+ if (ch < '0' || ch > '9') {
130
+ error('Unterminated fractional number');
130
131
  }
131
- while (ch >= "0" && ch <= "9") {
132
+ while (ch >= '0' && ch <= '9') {
132
133
  string += ch;
133
134
  next();
134
135
  }
135
136
  }
136
- if (ch === "e" || ch === "E") {
137
+ if (ch === 'e' || ch === 'E') { // eslint-disable-line unicorn/prefer-else-if
137
138
  string += ch;
138
139
  next();
139
140
  // @ts-expect-error `ch` modified
140
- if (ch === "-" || ch === "+") {
141
+ if (ch === '-' || ch === '+') {
141
142
  string += ch;
142
143
  next();
143
144
  }
144
- while (ch >= "0" && ch <= "9") {
145
+ while (ch >= '0' && ch <= '9') {
145
146
  string += ch;
146
147
  next();
147
148
  }
148
149
  }
149
150
  const value = Number(string);
150
151
  if (!Number.isFinite(value)) {
151
- error("Bad number");
152
+ error('Bad number');
152
153
  }
153
154
  };
154
155
  const string = () => {
155
156
  // Parse a string value.
156
- let value = "";
157
+ let value = '';
157
158
  // When parsing for string values, we must look for " and \ characters.
158
159
  if (ch === '"') {
159
160
  while (next()) {
@@ -162,9 +163,9 @@ const factory = (jsonc) => {
162
163
  return value;
163
164
  }
164
165
  const from = at - 1;
165
- if (ch === "\\") {
166
+ if (ch === '\\') {
166
167
  next();
167
- if (ch === "u") {
168
+ if (ch === 'u') {
168
169
  let i = 0;
169
170
  let uffff = 0;
170
171
  for (; i < 4; i++) {
@@ -175,19 +176,19 @@ const factory = (jsonc) => {
175
176
  uffff = uffff * 16 + hex;
176
177
  }
177
178
  if (i < 4) {
178
- error("Bad unicode escape", from);
179
+ error('Bad unicode escape', from);
179
180
  }
180
- value += String.fromCharCode(uffff);
181
+ value += String.fromCodePoint(uffff);
181
182
  }
182
- else if (typeof escapee[ch] === "string") {
183
+ else if (typeof escapee[ch] === 'string') {
183
184
  value += escapee[ch];
184
185
  }
185
186
  else {
186
- error("Bad escaped character", from, at);
187
+ error('Bad escaped character', from, at);
187
188
  }
188
189
  }
189
- else if (ch < " ") {
190
- error("Bad control character", from, at);
190
+ else if (ch < ' ') {
191
+ error('Bad control character', from, at);
191
192
  }
192
193
  else {
193
194
  value += ch;
@@ -197,7 +198,7 @@ const factory = (jsonc) => {
197
198
  else {
198
199
  error(`Expected '"' instead of ${JSON.stringify(ch)}`);
199
200
  }
200
- return error("Unterminated string");
201
+ return error('Unterminated string');
201
202
  };
202
203
  const white = () => {
203
204
  // Skip whitespace and comments (JSONC).
@@ -206,27 +207,27 @@ const factory = (jsonc) => {
206
207
  while (ch && spaces.has(ch)) {
207
208
  next();
208
209
  }
209
- if (jsonc && ch === "/") {
210
+ if (jsonc && ch === '/') {
210
211
  const peek = text.charAt(at);
211
- if (peek === "/") {
212
+ if (peek === '/') {
212
213
  // Skip single-line comments.
213
214
  next(); // skip /
214
215
  next(); // skip /
215
216
  // @ts-expect-error `ch` modified
216
- while (ch && ch !== "\n" && ch !== "\r") {
217
+ while (ch && ch !== '\n' && ch !== '\r') {
217
218
  next();
218
219
  }
219
220
  continue;
220
221
  }
221
- else if (peek === "*") {
222
+ else if (peek === '*') {
222
223
  // Skip multi-line comments.
223
224
  next(); // skip /
224
225
  next(); // skip *
225
226
  // @ts-expect-error `ch` modified
226
- while (ch && !(ch === "*" && text.charAt(at) === "/")) {
227
+ while (ch && (ch !== '*' || text.charAt(at) !== '/')) {
227
228
  next();
228
229
  }
229
- if (ch === "*") {
230
+ if (ch === '*') {
230
231
  next(); // skip *
231
232
  next(); // skip /
232
233
  }
@@ -239,24 +240,24 @@ const factory = (jsonc) => {
239
240
  const word = () => {
240
241
  // true, false, or null.
241
242
  switch (ch) {
242
- case "t":
243
+ case 't':
243
244
  next();
244
- next("r");
245
- next("u");
246
- next("e");
245
+ next('r');
246
+ next('u');
247
+ next('e');
247
248
  return;
248
- case "f":
249
+ case 'f':
249
250
  next();
250
- next("a");
251
- next("l");
252
- next("s");
253
- next("e");
251
+ next('a');
252
+ next('l');
253
+ next('s');
254
+ next('e');
254
255
  return;
255
- case "n":
256
+ case 'n':
256
257
  next();
257
- next("u");
258
- next("l");
259
- next("l");
258
+ next('u');
259
+ next('l');
260
+ next('l');
260
261
  return;
261
262
  default:
262
263
  error(`Unexpected ${JSON.stringify(ch)}`);
@@ -266,32 +267,32 @@ const factory = (jsonc) => {
266
267
  // Parse an array value.
267
268
  next();
268
269
  white();
269
- if (ch === "]") {
270
+ if (ch === ']') {
270
271
  next();
271
272
  return; // empty array
272
273
  }
273
- else if (jsonc && ch === ",") {
274
+ else if (jsonc && ch === ',') {
274
275
  next();
275
276
  white();
276
- next("]");
277
+ next(']');
277
278
  return;
278
279
  }
279
280
  let from;
280
281
  while (ch) {
281
- if (ch === "]") {
282
+ if (ch === ']') {
282
283
  if (jsonc) {
283
284
  next();
284
285
  return;
285
286
  }
286
- error("Trailing comma in array", from, from + 1);
287
+ error('Trailing comma in array', from, from + 1);
287
288
  }
288
289
  value();
289
290
  white();
290
- if (ch === "]") {
291
+ if (ch === ']') {
291
292
  next();
292
293
  return;
293
294
  }
294
- else if (ch === ",") {
295
+ else if (ch === ',') {
295
296
  from = at - 1;
296
297
  next();
297
298
  white();
@@ -300,37 +301,37 @@ const factory = (jsonc) => {
300
301
  error(`Expected "," or "]" instead of ${stringify(ch)}`);
301
302
  }
302
303
  }
303
- error("Unterminated array");
304
+ error('Unterminated array');
304
305
  };
305
306
  const object = () => {
306
307
  // Parse an object value.
307
308
  const keys = new Set();
308
309
  next();
309
310
  white();
310
- if (ch === "}") {
311
+ if (ch === '}') {
311
312
  next();
312
313
  return; // empty object
313
314
  }
314
- else if (jsonc && ch === ",") {
315
+ else if (jsonc && ch === ',') {
315
316
  next();
316
317
  white();
317
- next("}");
318
+ next('}');
318
319
  return;
319
320
  }
320
321
  let from;
321
322
  while (ch) {
322
- if (ch === "}") {
323
+ if (ch === '}') {
323
324
  if (jsonc) {
324
325
  next();
325
326
  return;
326
327
  }
327
- error("Trailing comma in object", from, from + 1);
328
+ error('Trailing comma in object', from, from + 1);
328
329
  }
329
330
  from = at;
330
331
  const key = string();
331
332
  const to = at - 2;
332
333
  white();
333
- next(":");
334
+ next(':');
334
335
  if (keys.has(key)) {
335
336
  warn(`Duplicate key ${stringify(key)}`, from, to);
336
337
  }
@@ -339,11 +340,11 @@ const factory = (jsonc) => {
339
340
  }
340
341
  value();
341
342
  white();
342
- if (ch === "}") {
343
+ if (ch === '}') {
343
344
  next();
344
345
  return;
345
346
  }
346
- else if (ch === ",") {
347
+ else if (ch === ',') {
347
348
  from = at - 1;
348
349
  next();
349
350
  white();
@@ -359,21 +360,23 @@ const factory = (jsonc) => {
359
360
  // or a word.
360
361
  white();
361
362
  switch (ch) {
362
- case "":
363
- return undefined;
364
- case "{":
365
- return object();
366
- case "[":
367
- return array();
363
+ case '':
364
+ break;
365
+ case '{':
366
+ object();
367
+ break;
368
+ case '[':
369
+ array();
370
+ break;
368
371
  case '"':
369
372
  return string();
370
- case "-":
371
- return number();
373
+ case '-':
374
+ number();
375
+ break;
372
376
  default:
373
- return ch >= "0" && ch <= "9"
374
- ? number()
375
- : word();
377
+ (ch >= '0' && ch <= '9' ? number : word)();
376
378
  }
379
+ return undefined;
377
380
  };
378
381
  // Return the json_parse function. It will have access to all of the above
379
382
  // functions and variables.
@@ -381,11 +384,11 @@ const factory = (jsonc) => {
381
384
  text = source;
382
385
  warnings = [];
383
386
  at = 0;
384
- ch = " ";
387
+ ch = ' ';
385
388
  value();
386
389
  white();
387
390
  if (ch) {
388
- error("Syntax error");
391
+ error('Syntax error');
389
392
  }
390
393
  else if (warnings.length > 0) {
391
394
  throw { warnings };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bhsd/common",
3
- "version": "3.0.0",
3
+ "version": "4.0.1",
4
4
  "homepage": "https://github.com/bhsd-harry/common#readme",
5
5
  "bugs": {
6
6
  "url": "https://github.com/bhsd-harry/common/issues"
@@ -8,32 +8,39 @@
8
8
  "license": "MIT",
9
9
  "author": "Bhsd",
10
10
  "files": [
11
- "/dist/*"
11
+ "/dist/"
12
12
  ],
13
13
  "main": "./dist/index.js",
14
14
  "types": "./dist/index.d.ts",
15
+ "exports": {
16
+ ".": "./dist/index.js",
17
+ "./color": "./dist/color.js"
18
+ },
15
19
  "type": "module",
16
20
  "sideEffects": false,
17
21
  "scripts": {
18
22
  "ls": "npm i --package-lock-only && npm ls --package-lock-only --all --omit=dev",
19
23
  "prepublishOnly": "npm run build",
20
- "build": "tsc",
24
+ "build": "tsc && eslint --no-inline-config --no-config-lookup -c eslint.dist.js dist/*.js",
21
25
  "lint:ts": "tsc --noEmit && eslint --cache .",
22
26
  "lint": "npm run lint:ts",
23
- "test": "mocha"
27
+ "test": "testUtil test/*.test.js"
28
+ },
29
+ "peerDependencies": {
30
+ "culori": "^4.0.0"
24
31
  },
25
- "dependencies": {
26
- "culori": "^4.0.2"
32
+ "peerDependenciesMeta": {
33
+ "culori": {
34
+ "optional": true
35
+ }
27
36
  },
28
37
  "devDependencies": {
29
- "@bhsd/code-standard": "^2.6.2",
38
+ "@bhsd/code-standard": "^3.3.0",
30
39
  "@bhsd/lezer-json": "^2.1.0",
40
+ "@bhsd/test-util": "^3.1.0",
31
41
  "@types/culori": "^4.0.1",
32
- "@types/mocha": "^10.0.10",
33
- "esbuild": "^0.28.0",
34
- "eslint": "^10.4.1",
35
- "globals": "^17.6.0",
36
- "mocha": "^11.7.6",
42
+ "culori": "^4.0.2",
43
+ "eslint": "^10.7.0",
37
44
  "typescript": "^6.0.3"
38
45
  },
39
46
  "engines": {