@bhsd/common 0.11.0 → 0.13.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/README.md +4 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +22 -7
- package/dist/index.mjs +22 -7
- package/dist/test.d.ts +38 -0
- package/dist/test.js +172 -0
- package/package.json +9 -10
- package/bin/dev.cjs +0 -15
package/README.md
ADDED
package/dist/index.d.ts
CHANGED
|
@@ -47,6 +47,16 @@ export declare const setObject: (key: string, value: unknown) => void;
|
|
|
47
47
|
* @param baseVersion 基础版本号
|
|
48
48
|
*/
|
|
49
49
|
export declare const compareVersion: (version: string, baseVersion: string) => boolean;
|
|
50
|
+
/**
|
|
51
|
+
* 加载 I18N
|
|
52
|
+
* @param url 下载地址
|
|
53
|
+
* @param cur 当前版本号
|
|
54
|
+
* @param languages 语言代码列表
|
|
55
|
+
* @param key 存储的键名
|
|
56
|
+
* @param i18n 已存储的I18N对象
|
|
57
|
+
* @throws `Error` 无法获取语言包
|
|
58
|
+
*/
|
|
59
|
+
export declare const setI18N: (url: string, cur: string, languages: string[] | string, key: string, i18n?: Record<string, string>) => Promise<Record<string, string>>;
|
|
50
60
|
/**
|
|
51
61
|
* 加载 wikiparse
|
|
52
62
|
* @param getConfig 获取解析配置的函数
|
package/dist/index.js
CHANGED
|
@@ -32,6 +32,7 @@ __export(index_exports, {
|
|
|
32
32
|
rawurldecode: () => rawurldecode,
|
|
33
33
|
refreshStdout: () => refreshStdout,
|
|
34
34
|
sanitizeInlineStyle: () => sanitizeInlineStyle,
|
|
35
|
+
setI18N: () => setI18N,
|
|
35
36
|
setObject: () => setObject,
|
|
36
37
|
splitColors: () => splitColors
|
|
37
38
|
});
|
|
@@ -114,6 +115,22 @@ const compareVersion = (version, baseVersion) => {
|
|
|
114
115
|
const [major, minor] = parseVersion(version), [baseMajor, baseMinor] = parseVersion(baseVersion);
|
|
115
116
|
return major > baseMajor || major === baseMajor && minor >= baseMinor;
|
|
116
117
|
};
|
|
118
|
+
const setI18N = async (url, cur, languages, key, i18n = getObject(key) ?? {}) => {
|
|
119
|
+
const { version, lang } = i18n, langs = Array.isArray(languages) ? languages : [languages];
|
|
120
|
+
if (version === cur && langs.includes(lang)) {
|
|
121
|
+
return i18n;
|
|
122
|
+
}
|
|
123
|
+
for (const language of langs) {
|
|
124
|
+
try {
|
|
125
|
+
const res = await fetch(`${url}/${language.toLowerCase()}.json`);
|
|
126
|
+
Object.assign(i18n, await res.json(), { version: cur, lang: language });
|
|
127
|
+
setObject(key, i18n);
|
|
128
|
+
return i18n;
|
|
129
|
+
} catch {
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
throw new Error(`Failed to fetch the localization for ${langs[0]}.`);
|
|
133
|
+
};
|
|
117
134
|
let configLoaded = false, i18nLoaded = false;
|
|
118
135
|
const getWikiparse = async (getConfig, langs) => {
|
|
119
136
|
const dir = "extensions/dist";
|
|
@@ -128,13 +145,11 @@ const getWikiparse = async (getConfig, langs) => {
|
|
|
128
145
|
}
|
|
129
146
|
if (!i18nLoaded && langs) {
|
|
130
147
|
i18nLoaded = true;
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
} catch {
|
|
137
|
-
}
|
|
148
|
+
const key = "wikiparse-i18n", { version } = wikiparse;
|
|
149
|
+
try {
|
|
150
|
+
wikiparse.setI18N(await setI18N(`${wikiparse.CDN}/i18n`, version, langs, key));
|
|
151
|
+
} catch {
|
|
152
|
+
setObject(key, { version, lang: "en" });
|
|
138
153
|
}
|
|
139
154
|
}
|
|
140
155
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -76,6 +76,22 @@ const compareVersion = (version, baseVersion) => {
|
|
|
76
76
|
const [major, minor] = parseVersion(version), [baseMajor, baseMinor] = parseVersion(baseVersion);
|
|
77
77
|
return major > baseMajor || major === baseMajor && minor >= baseMinor;
|
|
78
78
|
};
|
|
79
|
+
const setI18N = async (url, cur, languages, key, i18n = getObject(key) ?? {}) => {
|
|
80
|
+
const { version, lang } = i18n, langs = Array.isArray(languages) ? languages : [languages];
|
|
81
|
+
if (version === cur && langs.includes(lang)) {
|
|
82
|
+
return i18n;
|
|
83
|
+
}
|
|
84
|
+
for (const language of langs) {
|
|
85
|
+
try {
|
|
86
|
+
const res = await fetch(`${url}/${language.toLowerCase()}.json`);
|
|
87
|
+
Object.assign(i18n, await res.json(), { version: cur, lang: language });
|
|
88
|
+
setObject(key, i18n);
|
|
89
|
+
return i18n;
|
|
90
|
+
} catch {
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
throw new Error(`Failed to fetch the localization for ${langs[0]}.`);
|
|
94
|
+
};
|
|
79
95
|
let configLoaded = false, i18nLoaded = false;
|
|
80
96
|
const getWikiparse = async (getConfig, langs) => {
|
|
81
97
|
const dir = "extensions/dist";
|
|
@@ -90,13 +106,11 @@ const getWikiparse = async (getConfig, langs) => {
|
|
|
90
106
|
}
|
|
91
107
|
if (!i18nLoaded && langs) {
|
|
92
108
|
i18nLoaded = true;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
} catch {
|
|
99
|
-
}
|
|
109
|
+
const key = "wikiparse-i18n", { version } = wikiparse;
|
|
110
|
+
try {
|
|
111
|
+
wikiparse.setI18N(await setI18N(`${wikiparse.CDN}/i18n`, version, langs, key));
|
|
112
|
+
} catch {
|
|
113
|
+
setObject(key, { version, lang: "en" });
|
|
100
114
|
}
|
|
101
115
|
}
|
|
102
116
|
};
|
|
@@ -143,6 +157,7 @@ export {
|
|
|
143
157
|
rawurldecode,
|
|
144
158
|
refreshStdout,
|
|
145
159
|
sanitizeInlineStyle,
|
|
160
|
+
setI18N,
|
|
146
161
|
setObject,
|
|
147
162
|
splitColors
|
|
148
163
|
};
|
package/dist/test.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
declare interface MediaWikiPage {
|
|
2
|
+
readonly pageid: number;
|
|
3
|
+
readonly title: string;
|
|
4
|
+
readonly ns: number;
|
|
5
|
+
readonly revisions?: {
|
|
6
|
+
readonly content: string;
|
|
7
|
+
readonly contentmodel: string;
|
|
8
|
+
}[];
|
|
9
|
+
}
|
|
10
|
+
export interface SimplePage extends Pick<MediaWikiPage, 'pageid' | 'title' | 'ns'> {
|
|
11
|
+
readonly content: string;
|
|
12
|
+
}
|
|
13
|
+
export interface Test {
|
|
14
|
+
desc: string;
|
|
15
|
+
wikitext?: string;
|
|
16
|
+
parsed?: string;
|
|
17
|
+
html?: string;
|
|
18
|
+
print?: string;
|
|
19
|
+
render?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 获取最近更改的页面源代码
|
|
23
|
+
* @param url api.php网址
|
|
24
|
+
* @param site 站点名称
|
|
25
|
+
* @param grclimit 页面数上限
|
|
26
|
+
*/
|
|
27
|
+
export declare const getPages: (url: string, site?: string, grclimit?: string) => Promise<SimplePage[]>;
|
|
28
|
+
/** 重置请求 */
|
|
29
|
+
export declare const reset: () => void;
|
|
30
|
+
/**
|
|
31
|
+
* 执行解析测试
|
|
32
|
+
* @param parse 解析函数
|
|
33
|
+
* @param retry 重试次数
|
|
34
|
+
* @param grclimit 页面数上限
|
|
35
|
+
*/
|
|
36
|
+
export declare const execute: (parse: (wikitext: string) => unknown, retry?: number, grclimit?: string) => Promise<void>;
|
|
37
|
+
export declare const mochaTest: (results: unknown, parse: (wikitext: string) => string, beforeFn?: Mocha.Func | Mocha.AsyncFunc) => void;
|
|
38
|
+
export {};
|
package/dist/test.js
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// test/test.ts
|
|
31
|
+
var test_exports = {};
|
|
32
|
+
__export(test_exports, {
|
|
33
|
+
execute: () => execute,
|
|
34
|
+
getPages: () => getPages,
|
|
35
|
+
mochaTest: () => mochaTest,
|
|
36
|
+
reset: () => reset
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(test_exports);
|
|
39
|
+
var import_fs = __toESM(require("fs"));
|
|
40
|
+
var import_assert = __toESM(require("assert"));
|
|
41
|
+
var import_perf_hooks = require("perf_hooks");
|
|
42
|
+
|
|
43
|
+
// src/index.ts
|
|
44
|
+
var refreshStdout = (str) => {
|
|
45
|
+
process.stdout.write(`\x1B[K\x1B[?7l${str}\x1B[?7h\r`);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// test/test.ts
|
|
49
|
+
var apis = [
|
|
50
|
+
["维基百科", "https://zh.wikipedia.org/w"],
|
|
51
|
+
["Wikipedia", "https://en.wikipedia.org/w"],
|
|
52
|
+
["ウィキペディア", "https://ja.wikipedia.org/w"]
|
|
53
|
+
];
|
|
54
|
+
var c;
|
|
55
|
+
var getPages = async (url, site, grclimit = "max") => {
|
|
56
|
+
const qs = {
|
|
57
|
+
action: "query",
|
|
58
|
+
format: "json",
|
|
59
|
+
formatversion: "2",
|
|
60
|
+
errorformat: "plaintext",
|
|
61
|
+
generator: "recentchanges",
|
|
62
|
+
grcnamespace: site === "MediaWiki" ? "0|10|12|100|102|104|106" : "0|10",
|
|
63
|
+
grclimit,
|
|
64
|
+
grctype: "edit|new",
|
|
65
|
+
grctoponly: "1",
|
|
66
|
+
prop: "revisions",
|
|
67
|
+
rvprop: "contentmodel|content",
|
|
68
|
+
...c
|
|
69
|
+
}, response = await (await fetch(`${url}?${String(new URLSearchParams(qs))}`)).json();
|
|
70
|
+
c = response.continue;
|
|
71
|
+
return response.query.pages.map(({ pageid, title, ns, revisions }) => ({
|
|
72
|
+
pageid,
|
|
73
|
+
title,
|
|
74
|
+
ns,
|
|
75
|
+
content: revisions?.[0]?.contentmodel === "wikitext" && revisions[0].content
|
|
76
|
+
})).filter((page) => page.content !== false);
|
|
77
|
+
};
|
|
78
|
+
var reset = () => {
|
|
79
|
+
c = void 0;
|
|
80
|
+
};
|
|
81
|
+
var execute = async (parse, retry = 10, grclimit) => {
|
|
82
|
+
const failures = /* @__PURE__ */ new Map();
|
|
83
|
+
for (const [site, url] of apis) {
|
|
84
|
+
console.log(`开始检查${site}:`);
|
|
85
|
+
let worst;
|
|
86
|
+
reset();
|
|
87
|
+
try {
|
|
88
|
+
let failed = 0, i = 0;
|
|
89
|
+
for (let j = 0; j < retry; j++) {
|
|
90
|
+
for (const { content, title } of await getPages(`${url}/api.php`, site, grclimit)) {
|
|
91
|
+
refreshStdout(`${i++} ${title}`);
|
|
92
|
+
try {
|
|
93
|
+
const start = import_perf_hooks.performance.now();
|
|
94
|
+
parse(content);
|
|
95
|
+
const duration = import_perf_hooks.performance.now() - start;
|
|
96
|
+
if (!worst || duration > worst.duration) {
|
|
97
|
+
worst = { title, duration };
|
|
98
|
+
}
|
|
99
|
+
} catch (e) {
|
|
100
|
+
console.error(`
|
|
101
|
+
解析 ${title} 页面时出错!`, e);
|
|
102
|
+
failed++;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (failed) {
|
|
107
|
+
failures.set(site, failed);
|
|
108
|
+
}
|
|
109
|
+
console.log(`
|
|
110
|
+
最耗时页面:${worst.title} (${worst.duration.toFixed(3)}ms)`);
|
|
111
|
+
} catch (e) {
|
|
112
|
+
console.error(`访问${site}的API端口时出错!`, e);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (failures.size > 0) {
|
|
116
|
+
let total = 0;
|
|
117
|
+
for (const [site, failed] of failures) {
|
|
118
|
+
console.error(`${site}:${failed} 个页面解析失败!`);
|
|
119
|
+
total += failed;
|
|
120
|
+
}
|
|
121
|
+
throw new Error(`共有 ${total} 个页面解析失败!`);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
var tests = require("wikiparser-node/test/parserTests.json");
|
|
125
|
+
var split = (test) => test?.parsed?.split(/(?<=<\/>)(?!$)|(?<!^)(?=<\w)/u);
|
|
126
|
+
var mochaTest = (results, parse, beforeFn) => {
|
|
127
|
+
describe("Parser tests", () => {
|
|
128
|
+
for (let i = tests.length - 1; i >= 0; i--) {
|
|
129
|
+
const test = tests[i], { wikitext, desc } = test;
|
|
130
|
+
if (wikitext) {
|
|
131
|
+
it(desc, () => {
|
|
132
|
+
try {
|
|
133
|
+
delete test.html;
|
|
134
|
+
delete test.print;
|
|
135
|
+
delete test.render;
|
|
136
|
+
test.parsed = parse(wikitext);
|
|
137
|
+
import_assert.default.deepStrictEqual(
|
|
138
|
+
split(test),
|
|
139
|
+
split(results.find(({ desc: d }) => d === desc))
|
|
140
|
+
);
|
|
141
|
+
} catch (e) {
|
|
142
|
+
if (!(e instanceof import_assert.default.AssertionError)) {
|
|
143
|
+
tests.splice(i, 1);
|
|
144
|
+
}
|
|
145
|
+
if (e instanceof Error) {
|
|
146
|
+
Object.assign(e, { cause: { message: `
|
|
147
|
+
${wikitext}` } });
|
|
148
|
+
}
|
|
149
|
+
throw e;
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (beforeFn) {
|
|
155
|
+
before(beforeFn);
|
|
156
|
+
}
|
|
157
|
+
after(() => {
|
|
158
|
+
import_fs.default.writeFileSync(
|
|
159
|
+
"test/parserTests.json",
|
|
160
|
+
`${JSON.stringify(tests, null, " ")}
|
|
161
|
+
`
|
|
162
|
+
);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
};
|
|
166
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
167
|
+
0 && (module.exports = {
|
|
168
|
+
execute,
|
|
169
|
+
getPages,
|
|
170
|
+
mochaTest,
|
|
171
|
+
reset
|
|
172
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bhsd/common",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Bhsd",
|
|
6
6
|
"files": [
|
|
@@ -24,17 +24,19 @@
|
|
|
24
24
|
"import": "./dist/cm.mjs",
|
|
25
25
|
"require": "./dist/cm.js"
|
|
26
26
|
},
|
|
27
|
+
"./dist/test": {
|
|
28
|
+
"types": "./dist/test.d.ts",
|
|
29
|
+
"import": "./dist/test.js",
|
|
30
|
+
"require": "./dist/test.js"
|
|
31
|
+
},
|
|
27
32
|
"./*.cjs": "./*.cjs",
|
|
28
33
|
"./package.json": "./package.json"
|
|
29
34
|
},
|
|
30
35
|
"types": "./dist/index.d.ts",
|
|
31
36
|
"sideEffects": false,
|
|
32
|
-
"bin": {
|
|
33
|
-
"copy-dev": "bin/dev.cjs"
|
|
34
|
-
},
|
|
35
37
|
"scripts": {
|
|
36
38
|
"prepublishOnly": "npm run build",
|
|
37
|
-
"build": "tsc --
|
|
39
|
+
"build": "tsc && esbuild src/* --charset=utf8 --target=es2024 --format=cjs --outdir=dist && esbuild test/* --charset=utf8 --target=es2024 --format=cjs --outdir=dist --bundle --platform=node --external:wikiparser-node && esbuild src/* --charset=utf8 --target=es2024 --format=esm --outdir=dist --out-extension:.js=.mjs && mv dist/*/*.d.ts dist/ && rm dist/global.*",
|
|
38
40
|
"lint:ts": "tsc --noEmit && eslint --cache .",
|
|
39
41
|
"lint": "npm run lint:ts"
|
|
40
42
|
},
|
|
@@ -54,15 +56,12 @@
|
|
|
54
56
|
"eslint-plugin-eslint-comments": "^3.2.0",
|
|
55
57
|
"eslint-plugin-jsdoc": "^50.6.3",
|
|
56
58
|
"eslint-plugin-json-es": "^1.6.0",
|
|
57
|
-
"eslint-plugin-markdown": "4.0.1",
|
|
58
59
|
"eslint-plugin-n": "^17.15.1",
|
|
59
60
|
"eslint-plugin-promise": "^7.2.1",
|
|
60
61
|
"eslint-plugin-regexp": "^2.7.0",
|
|
61
62
|
"eslint-plugin-unicorn": "^56.0.1",
|
|
62
|
-
"
|
|
63
|
-
"mocha": "^11.1.0",
|
|
64
|
-
"stylelint": "^16.19.1",
|
|
63
|
+
"stylelint": "^16.20.0",
|
|
65
64
|
"typescript": "^5.8.2",
|
|
66
|
-
"wikiparser-node": "^1.
|
|
65
|
+
"wikiparser-node": "^1.21.2"
|
|
67
66
|
}
|
|
68
67
|
}
|
package/bin/dev.cjs
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const fs = require('fs'),
|
|
5
|
-
{devDependencies, version} = require('@bhsd/common/package.json'),
|
|
6
|
-
json = require(`${process.cwd()}/package.json`);
|
|
7
|
-
const {name: n, dependencies, optionalDependencies} = json,
|
|
8
|
-
others = {[n]: '', ...dependencies, ...optionalDependencies},
|
|
9
|
-
dev = Object.fromEntries(
|
|
10
|
-
Object.entries({...json.devDependencies, ...devDependencies}).filter(([k]) => !(k in others))
|
|
11
|
-
.sort(([a], [b]) => a.localeCompare(b)),
|
|
12
|
-
);
|
|
13
|
-
(dependencies && '@bhsd/common' in dependencies ? dependencies : dev)['@bhsd/common'] = `^${version}`;
|
|
14
|
-
json.devDependencies = dev;
|
|
15
|
-
fs.writeFileSync('package.json', `${JSON.stringify(json, null, '\t')}\n`);
|