@jayfong/x-utils 1.0.0-202407012223

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.
Files changed (77) hide show
  1. package/_cjs/ai.js +80 -0
  2. package/_cjs/cli.js +51 -0
  3. package/_cjs/clipboard.js +65 -0
  4. package/_cjs/cmd.js +42 -0
  5. package/_cjs/crawler.js +341 -0
  6. package/_cjs/csv.js +97 -0
  7. package/_cjs/data_set.js +115 -0
  8. package/_cjs/env.js +63 -0
  9. package/_cjs/fs.js +35 -0
  10. package/_cjs/html.js +62 -0
  11. package/_cjs/http_server.js +56 -0
  12. package/_cjs/json.js +49 -0
  13. package/_cjs/ksb.js +217 -0
  14. package/_cjs/number.js +39 -0
  15. package/_cjs/ocr.js +74 -0
  16. package/_cjs/path.js +35 -0
  17. package/_cjs/pinyin.js +32 -0
  18. package/_cjs/puppeteer.js +271 -0
  19. package/_cjs/runner.js +88 -0
  20. package/_cjs/task.js +41 -0
  21. package/_cjs/text.js +136 -0
  22. package/_cjs/unicode/lib_unicode.js +58643 -0
  23. package/_cjs/unicode/unicode.js +441 -0
  24. package/_cjs/upload.js +100 -0
  25. package/_cjs/yaml.js +52 -0
  26. package/ai.d.ts +26 -0
  27. package/ai.js +60 -0
  28. package/cli.d.ts +14 -0
  29. package/cli.js +21 -0
  30. package/clipboard.d.ts +6 -0
  31. package/clipboard.js +35 -0
  32. package/cmd.d.ts +5 -0
  33. package/cmd.js +22 -0
  34. package/crawler.d.ts +162 -0
  35. package/crawler.js +332 -0
  36. package/csv.d.ts +14 -0
  37. package/csv.js +67 -0
  38. package/data_set.d.ts +22 -0
  39. package/data_set.js +85 -0
  40. package/env.d.ts +4 -0
  41. package/env.js +32 -0
  42. package/fs.d.ts +2 -0
  43. package/fs.js +5 -0
  44. package/html.d.ts +7 -0
  45. package/html.js +45 -0
  46. package/http_server.d.ts +10 -0
  47. package/http_server.js +26 -0
  48. package/json.d.ts +6 -0
  49. package/json.js +19 -0
  50. package/ksb.d.ts +32 -0
  51. package/ksb.js +197 -0
  52. package/number.d.ts +3 -0
  53. package/number.js +9 -0
  54. package/ocr.d.ts +10 -0
  55. package/ocr.js +54 -0
  56. package/ofd.d.ts +1 -0
  57. package/package.json +158 -0
  58. package/path.d.ts +2 -0
  59. package/path.js +5 -0
  60. package/pinyin.d.ts +3 -0
  61. package/pinyin.js +12 -0
  62. package/puppeteer.d.ts +38 -0
  63. package/puppeteer.js +241 -0
  64. package/runner.d.ts +13 -0
  65. package/runner.js +58 -0
  66. package/task.d.ts +6 -0
  67. package/task.js +21 -0
  68. package/text.d.ts +63 -0
  69. package/text.js +119 -0
  70. package/unicode/lib_unicode.d.ts +4 -0
  71. package/unicode/lib_unicode.js +58623 -0
  72. package/unicode/unicode.d.ts +347 -0
  73. package/unicode/unicode.js +426 -0
  74. package/upload.d.ts +22 -0
  75. package/upload.js +70 -0
  76. package/yaml.d.ts +6 -0
  77. package/yaml.js +22 -0
package/data_set.js ADDED
@@ -0,0 +1,85 @@
1
+ import { asyncExitHook } from "exit-hook";
2
+ import fs from "fs-extra";
3
+ import * as path from "node:path";
4
+ import { keyBy, keysStrict, pickStrict } from "vtils";
5
+ import { v } from "vtils/vae";
6
+ import { XCsv } from "./csv.js";
7
+ import { XJson } from "./json.js";
8
+ import { XYaml } from "./yaml.js";
9
+ class XDataSet {
10
+ constructor(options) {
11
+ this.options = options;
12
+ this.storeType = options.storeFile.endsWith(".csv") ? "csv" : options.storeFile.endsWith(".yaml") || options.storeFile.endsWith(".yml") ? "yaml" : "json";
13
+ this.dataShapeSchema = options.dataSchema(v);
14
+ this.dataSchema = v.object(this.dataShapeSchema);
15
+ this.csvOptions = {
16
+ arrayDelimiter: options.csvArrayDelimiter,
17
+ arrayFieldNames: keysStrict(this.dataShapeSchema).filter(
18
+ (key) => this.dataShapeSchema[key].options.type === "array"
19
+ ),
20
+ objectFieldNames: keysStrict(this.dataShapeSchema).filter(
21
+ (key) => this.dataShapeSchema[key].options.type === "object"
22
+ ),
23
+ booleanFieldNames: keysStrict(this.dataShapeSchema).filter(
24
+ (key) => this.dataShapeSchema[key].options.type === "boolean"
25
+ ),
26
+ dateFieldNames: keysStrict(this.dataShapeSchema).filter(
27
+ (key) => this.dataShapeSchema[key].options.type === "date"
28
+ )
29
+ };
30
+ if (!options.noAutoWrite) {
31
+ const timer = setInterval(() => {
32
+ this.write();
33
+ }, options.autoWriteInterval || 5e3);
34
+ asyncExitHook(
35
+ async () => {
36
+ clearInterval(timer);
37
+ await this.write();
38
+ },
39
+ {
40
+ wait: 1e4
41
+ }
42
+ );
43
+ }
44
+ }
45
+ storeType;
46
+ dataShapeSchema;
47
+ dataSchema;
48
+ csvOptions;
49
+ currentMap;
50
+ get current() {
51
+ const orderedDataFieldNames = keysStrict(this.dataShapeSchema);
52
+ const dataSet = keysStrict(this.currentMap).map((dataKeyValue) => {
53
+ const data = {
54
+ ...this.currentMap[dataKeyValue],
55
+ [this.options.dataKey]: dataKeyValue
56
+ };
57
+ return this.dataSchema.cast(
58
+ pickStrict(data, orderedDataFieldNames)
59
+ );
60
+ });
61
+ return dataSet;
62
+ }
63
+ async read() {
64
+ let dataSet = [];
65
+ try {
66
+ dataSet = await (this.storeType === "csv" ? XCsv.read(this.options.storeFile, this.csvOptions) : this.storeType === "yaml" ? XYaml.read(this.options.storeFile) : XJson.read(this.options.storeFile));
67
+ } catch {
68
+ }
69
+ dataSet = dataSet.map((data) => this.dataSchema.cast(data));
70
+ this.currentMap = keyBy(
71
+ dataSet,
72
+ (data) => data[this.options.dataKey]
73
+ );
74
+ return dataSet;
75
+ }
76
+ async write(dataSet = this.current) {
77
+ console.log(`\u{1F4A5} \u5199\u5165 ${this.options.storeFile}`);
78
+ await fs.ensureDir(path.dirname(this.options.storeFile));
79
+ await (this.storeType === "csv" ? XCsv.write(this.options.storeFile, dataSet, this.csvOptions) : this.storeType === "yaml" ? XYaml.write(this.options.storeFile, dataSet) : XJson.write(this.options.storeFile, dataSet));
80
+ console.log(`\u2705 \u5199\u5165 ${this.options.storeFile}`);
81
+ }
82
+ }
83
+ export {
84
+ XDataSet
85
+ };
package/env.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export declare class XEnv {
2
+ private static getEnvVarsFromFile;
3
+ static getEnvVar<T>(name: string): Promise<T | undefined>;
4
+ }
package/env.js ADDED
@@ -0,0 +1,32 @@
1
+ import dotenv from "dotenv";
2
+ import { isPlainObject, memoize } from "vtils";
3
+ import { XFs } from "./fs.js";
4
+ import { XPath } from "./path.js";
5
+ import { XYaml } from "./yaml.js";
6
+ class XEnv {
7
+ static getEnvVarsFromFile = memoize(async () => {
8
+ const envYmlFile = XPath.join(import.meta.dirname, ".env.yml");
9
+ if (await XFs.pathExists(envYmlFile)) {
10
+ return XYaml.read(envYmlFile);
11
+ }
12
+ const envYamlFile = XPath.join(import.meta.dirname, ".env.yaml");
13
+ if (await XFs.pathExists(envYamlFile)) {
14
+ return XYaml.read(envYamlFile);
15
+ }
16
+ const dotenvFile = XPath.join(import.meta.dirname, ".env");
17
+ if (await XFs.pathExists(dotenvFile)) {
18
+ const dotenvContent = await XFs.readFile(dotenvFile, "utf-8");
19
+ return dotenv.parse(dotenvContent);
20
+ }
21
+ });
22
+ static async getEnvVar(name) {
23
+ if (process.env[name] != null) {
24
+ return process.env[name];
25
+ }
26
+ const envVars = await XEnv.getEnvVarsFromFile();
27
+ return isPlainObject(envVars) ? envVars[name] ?? void 0 : void 0;
28
+ }
29
+ }
30
+ export {
31
+ XEnv
32
+ };
package/fs.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import fs from 'fs-extra';
2
+ export declare const XFs: typeof fs;
package/fs.js ADDED
@@ -0,0 +1,5 @@
1
+ import fs from "fs-extra";
2
+ const XFs = fs;
3
+ export {
4
+ XFs
5
+ };
package/html.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ /// <reference types="node" />
2
+ import { ParagraphChild } from 'docx';
3
+ export { HTMLElement as XHtmlElement, NodeType as XHtmlNodeType, } from 'node-html-parser';
4
+ export declare class XHtml {
5
+ static parse(html: string): import("node-html-parser").HTMLElement;
6
+ static toDocxParagraphChildren(html: string, fetchImage: (url: string) => Promise<Buffer>): Promise<ParagraphChild[]>;
7
+ }
package/html.js ADDED
@@ -0,0 +1,45 @@
1
+ import { ImageRun, TextRun } from "docx";
2
+ import { imageDimensionsFromData } from "image-dimensions";
3
+ import { parse } from "node-html-parser";
4
+ import { parser } from "posthtml-parser";
5
+ import { flattenDeep, ii } from "vtils";
6
+ import {
7
+ HTMLElement,
8
+ NodeType
9
+ } from "node-html-parser";
10
+ class XHtml {
11
+ static parse(html) {
12
+ return parse(html);
13
+ }
14
+ static async toDocxParagraphChildren(html, fetchImage) {
15
+ const nodes = parser(html, {
16
+ decodeEntities: true
17
+ }).map(function process(node) {
18
+ return typeof node === "object" && node.content && Array.isArray(node.content) ? flattenDeep(node.content).map(process).flat() : [node];
19
+ }).flat();
20
+ return await Promise.all(
21
+ nodes.map(async (node) => {
22
+ return typeof node === "string" || typeof node === "number" ? new TextRun({
23
+ text: String(node)
24
+ }) : node.tag === "img" && typeof node.attrs?.src === "string" ? await ii(async () => {
25
+ const imageBuffer = await fetchImage(node.attrs.src);
26
+ const size = imageDimensionsFromData(imageBuffer);
27
+ return new ImageRun({
28
+ data: imageBuffer,
29
+ transformation: {
30
+ width: size?.width || 0,
31
+ height: size?.height || 0
32
+ }
33
+ });
34
+ }) : new TextRun({
35
+ text: ""
36
+ });
37
+ })
38
+ );
39
+ }
40
+ }
41
+ export {
42
+ XHtml,
43
+ HTMLElement as XHtmlElement,
44
+ NodeType as XHtmlNodeType
45
+ };
@@ -0,0 +1,10 @@
1
+ export type XHttpServerOptions = {
2
+ port: number;
3
+ handlers: Record<string, (data: any) => any>;
4
+ };
5
+ export declare class XHttpServer {
6
+ private options;
7
+ constructor(options: XHttpServerOptions);
8
+ start(): Promise<void>;
9
+ static start(options: XHttpServerOptions): Promise<void>;
10
+ }
package/http_server.js ADDED
@@ -0,0 +1,26 @@
1
+ import cors from "@fastify/cors";
2
+ import Fastify from "fastify";
3
+ class XHttpServer {
4
+ constructor(options) {
5
+ this.options = options;
6
+ }
7
+ async start() {
8
+ const fastify = Fastify({
9
+ logger: true
10
+ });
11
+ await fastify.register(cors);
12
+ Object.keys(this.options.handlers).forEach((name) => {
13
+ fastify.post(`/${name}`, (req) => this.options.handlers[name](req.body));
14
+ });
15
+ await fastify.listen({
16
+ host: "0.0.0.0",
17
+ port: this.options.port
18
+ });
19
+ }
20
+ static async start(options) {
21
+ await new XHttpServer(options).start();
22
+ }
23
+ }
24
+ export {
25
+ XHttpServer
26
+ };
package/json.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export declare class XJson {
2
+ static parse<T>(value: string): T;
3
+ static stringify(value: any, compact?: boolean): string;
4
+ static read<T>(file: string): Promise<T>;
5
+ static write(file: string, value: any, compact?: boolean): Promise<void>;
6
+ }
package/json.js ADDED
@@ -0,0 +1,19 @@
1
+ import * as fs from "node:fs";
2
+ class XJson {
3
+ static parse(value) {
4
+ return JSON.parse(value);
5
+ }
6
+ static stringify(value, compact = false) {
7
+ return JSON.stringify(value, null, compact ? void 0 : 2);
8
+ }
9
+ static async read(file) {
10
+ const value = await fs.promises.readFile(file, "utf8");
11
+ return XJson.parse(value);
12
+ }
13
+ static async write(file, value, compact = false) {
14
+ await fs.promises.writeFile(file, XJson.stringify(value, compact));
15
+ }
16
+ }
17
+ export {
18
+ XJson
19
+ };
package/ksb.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ /// <reference types="lodash" />
2
+ export declare class XKsb {
3
+ static request<T>(url: string, data?: any): Promise<T>;
4
+ static desensitize(text: string): string;
5
+ static getPaperId(payload: {
6
+ paperName: string;
7
+ }): Promise<string | undefined>;
8
+ static getPaperIdMemo: ((payload: {
9
+ paperName: string;
10
+ }) => Promise<string | undefined>) & import("lodash").MemoizedFunction;
11
+ static deletePaper(payload: {
12
+ paperName: string;
13
+ }): Promise<void>;
14
+ static addPaper(payload: {
15
+ paperName: string;
16
+ }): Promise<void>;
17
+ static ensurePaperExistsAndEmpty(payload: {
18
+ paperName: string;
19
+ }): Promise<void>;
20
+ static addQuestion(payload: {
21
+ paperName: string;
22
+ question: {
23
+ type: '单选' | '判断' | '填空' | '问答';
24
+ question: string;
25
+ options: Array<{
26
+ key: string;
27
+ value: string;
28
+ }>;
29
+ answer: string | boolean | string[];
30
+ };
31
+ }): Promise<void>;
32
+ }
package/ksb.js ADDED
@@ -0,0 +1,197 @@
1
+ import { xr } from "@jayfong/x-request";
2
+ import { castArray, md5, memoize } from "vtils";
3
+ class XKsb {
4
+ static request(url, data) {
5
+ const token = "%22ZpWKMcjeUIsZMwZIMUdkhEfAq93e3dPsQyWxAtkRNbc=%22";
6
+ const key = "12b6bb84e093532fb72b4d65fec3f00b";
7
+ const clientId = "ca37dd67-f885-4678-91a7-6531bb153ef2";
8
+ const ts = (/* @__PURE__ */ new Date()).getTime();
9
+ const sign = md5(`${key}${clientId}${url}${ts}${key}`);
10
+ return xr.postJson({
11
+ url: `https://www.kaoshibao.com/api${url}`,
12
+ data,
13
+ autoReferer: true,
14
+ // proxyUrl: 'http://127.0.0.1:8888',
15
+ headers: {
16
+ Timestamp: ts,
17
+ Version: "2.2.2",
18
+ Platform: "web",
19
+ Authorization: token,
20
+ "Client-Identifier": clientId,
21
+ Sign: sign
22
+ }
23
+ }).then((res) => res.data);
24
+ }
25
+ static desensitize(text) {
26
+ return text.replace(/台湾|澳门|香港|西藏|新疆|习近平/g, (word) => {
27
+ return word.split("").join(String.fromCharCode(8290));
28
+ });
29
+ }
30
+ static async getPaperId(payload) {
31
+ const res = await XKsb.request("/user/paper/list", {
32
+ keyword: payload.paperName,
33
+ page: 1,
34
+ size: 10,
35
+ parentid: "",
36
+ column: "0",
37
+ direction: ""
38
+ });
39
+ return res.data.rows?.[0]?.paperid;
40
+ }
41
+ static getPaperIdMemo = memoize(
42
+ (payload) => XKsb.getPaperId(payload),
43
+ (payload) => payload.paperName
44
+ );
45
+ static async deletePaper(payload) {
46
+ const paperId = await XKsb.getPaperId(payload);
47
+ if (paperId) {
48
+ await XKsb.request("/user/paper/delete", {
49
+ id: paperId
50
+ });
51
+ XKsb.getPaperIdMemo.cache.delete(payload.paperName);
52
+ }
53
+ }
54
+ static async addPaper(payload) {
55
+ await XKsb.request("/user/paper/add", {
56
+ name: payload.paperName,
57
+ type: "4"
58
+ });
59
+ XKsb.getPaperIdMemo.cache.delete(payload.paperName);
60
+ }
61
+ static async ensurePaperExistsAndEmpty(payload) {
62
+ await XKsb.deletePaper(payload);
63
+ await XKsb.addPaper(payload);
64
+ }
65
+ static async addQuestion(payload) {
66
+ payload.question.question = XKsb.desensitize(payload.question.question);
67
+ payload.question.options.forEach((opt) => {
68
+ opt.value = XKsb.desensitize(opt.value);
69
+ });
70
+ if (typeof payload.question.answer === "string") {
71
+ payload.question.answer = XKsb.desensitize(payload.question.answer);
72
+ } else if (Array.isArray(payload.question.answer)) {
73
+ payload.question.answer.forEach((v, i) => {
74
+ if (typeof v === "string") {
75
+ payload.question.answer[i] = XKsb.desensitize(v);
76
+ }
77
+ });
78
+ }
79
+ const paperId = await XKsb.getPaperIdMemo(payload);
80
+ await XKsb.request(
81
+ "/user/question/add",
82
+ // 单选
83
+ payload.question.type === "\u5355\u9009" ? {
84
+ id: "",
85
+ qtype: "1",
86
+ paperid: paperId,
87
+ options: JSON.stringify(
88
+ payload.question.options.map((opt) => ({
89
+ Key: opt.key,
90
+ Value: opt.value,
91
+ checked: false,
92
+ extend: ""
93
+ }))
94
+ ),
95
+ judgeOptions: [
96
+ { Key: "A", Value: "\u6B63\u786E" },
97
+ { Key: "B", Value: "\u9519\u8BEF" }
98
+ ],
99
+ question: payload.question.question,
100
+ answer: payload.question.answer,
101
+ extra: '{"ordered":"0","case_sensitive":"0"}',
102
+ paixuAnswer: "",
103
+ analysis: "",
104
+ parentid: 0,
105
+ chapter: "",
106
+ difficulty: "",
107
+ blanks: [{ Value: "" }],
108
+ optionData: [],
109
+ optionTipic: [],
110
+ optionDataTipic: {
111
+ options: [
112
+ { Key: "A", Value: "", checked: false },
113
+ { Key: "B", Value: "", checked: false },
114
+ { Key: "C", Value: "", checked: false },
115
+ { Key: "D", Value: "", checked: false }
116
+ ],
117
+ answer: ""
118
+ },
119
+ fileList: []
120
+ } : payload.question.type === "\u5224\u65AD" ? {
121
+ id: "",
122
+ qtype: "3",
123
+ paperid: paperId,
124
+ options: '[{"Key":"A","Value":"","checked":false},{"Key":"B","Value":"","checked":false},{"Key":"C","Value":"","checked":false},{"Key":"D","Value":"","checked":false}]',
125
+ judgeOptions: [
126
+ { Key: "A", Value: "\u6B63\u786E" },
127
+ { Key: "B", Value: "\u9519\u8BEF" }
128
+ ],
129
+ question: payload.question.question,
130
+ answer: payload.question.answer ? "A" : "B",
131
+ parentid: 0,
132
+ chapter: "",
133
+ difficulty: "",
134
+ extra: '{"ordered":"0","case_sensitive":"0"}',
135
+ analysis: "",
136
+ paixuAnswer: "",
137
+ blanks: [{ Value: "" }],
138
+ optionData: [],
139
+ optionTipic: [],
140
+ optionDataTipic: ""
141
+ } : payload.question.type === "\u586B\u7A7A" ? {
142
+ id: "",
143
+ qtype: "4",
144
+ paperid: paperId,
145
+ options: '[{"Key":"A","Value":"","checked":false},{"Key":"B","Value":"","checked":false},{"Key":"C","Value":"","checked":false},{"Key":"D","Value":"","checked":false}]',
146
+ judgeOptions: [
147
+ { Key: "A", Value: "\u6B63\u786E" },
148
+ { Key: "B", Value: "\u9519\u8BEF" }
149
+ ],
150
+ question: payload.question.question,
151
+ answer: castArray(payload.question.answer).join("|"),
152
+ parentid: 0,
153
+ chapter: "",
154
+ difficulty: "",
155
+ extra: '{"ordered":"0","case_sensitive":"0"}',
156
+ analysis: "",
157
+ paixuAnswer: "",
158
+ blanks: castArray(payload.question.answer).map((v) => ({
159
+ Value: v
160
+ })),
161
+ optionData: [],
162
+ optionTipic: [],
163
+ optionDataTipic: ""
164
+ } : payload.question.type === "\u95EE\u7B54" ? {
165
+ id: "",
166
+ qtype: "11",
167
+ paperid: paperId,
168
+ options: '[{"Key":"A","Value":"","checked":false},{"Key":"B","Value":"","checked":false},{"Key":"C","Value":"","checked":false},{"Key":"D","Value":"","checked":false}]',
169
+ judgeOptions: [
170
+ { Key: "A", Value: "\u6B63\u786E" },
171
+ { Key: "B", Value: "\u9519\u8BEF" }
172
+ ],
173
+ question: payload.question.question,
174
+ answer: payload.question.answer,
175
+ parentid: 0,
176
+ chapter: "",
177
+ difficulty: "",
178
+ extra: '{"ordered":"0","case_sensitive":"0"}',
179
+ analysis: "",
180
+ paixuAnswer: "",
181
+ blanks: [{ Value: "" }],
182
+ optionData: [],
183
+ optionTipic: [],
184
+ optionDataTipic: ""
185
+ } : {}
186
+ // 判断
187
+ // {"id":"","qtype":"3","paperid":"15844653","options":"[{\"Key\":\"A\",\"Value\":\"\",\"checked\":false},{\"Key\":\"B\",\"Value\":\"\",\"checked\":false},{\"Key\":\"C\",\"Value\":\"\",\"checked\":false},{\"Key\":\"D\",\"Value\":\"\",\"checked\":false}]","judgeOptions":[{"Key":"A","Value":"正确"},{"Key":"B","Value":"错误"}],"question":"<p>顶顶顶顶</p>","answer":"A","parentid":0,"chapter":"","difficulty":"","extra":"{\"ordered\":\"0\",\"case_sensitive\":\"0\"}","analysis":"","paixuAnswer":"","blanks":[{"Value":""}],"optionData":[],"optionTipic":[],"optionDataTipic":""}
188
+ // 填空
189
+ // {"id":"","qtype":"4","paperid":"15844653","options":"[{\"Key\":\"A\",\"Value\":\"\",\"checked\":false},{\"Key\":\"B\",\"Value\":\"\",\"checked\":false},{\"Key\":\"C\",\"Value\":\"\",\"checked\":false},{\"Key\":\"D\",\"Value\":\"\",\"checked\":false}]","judgeOptions":[{"Key":"A","Value":"正确"},{"Key":"B","Value":"错误"}],"question":"<p>99999999</p>","answer":"999|888","parentid":0,"chapter":"","difficulty":"","extra":"{\"ordered\":\"0\",\"case_sensitive\":\"0\"}","analysis":"","paixuAnswer":"","blanks":[{"Value":"999"},{"Value":"888"}],"optionData":[],"optionTipic":[],"optionDataTipic":""}
190
+ // 问答
191
+ // {"id":"","qtype":"11","paperid":"15844653","options":"[{\"Key\":\"A\",\"Value\":\"\",\"checked\":false},{\"Key\":\"B\",\"Value\":\"\",\"checked\":false},{\"Key\":\"C\",\"Value\":\"\",\"checked\":false},{\"Key\":\"D\",\"Value\":\"\",\"checked\":false}]","judgeOptions":[{"Key":"A","Value":"正确"},{"Key":"B","Value":"错误"}],"question":"<p>666666</p>","answer":"<p>67777777</p>","parentid":0,"chapter":"","difficulty":"","extra":"{\"ordered\":\"0\",\"case_sensitive\":\"0\"}","analysis":"","paixuAnswer":"","blanks":[{"Value":""}],"optionData":[],"optionTipic":[],"optionDataTipic":""}
192
+ );
193
+ }
194
+ }
195
+ export {
196
+ XKsb
197
+ };
package/number.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export declare class XNumber {
2
+ static toChinese(value: number): string;
3
+ }
package/number.js ADDED
@@ -0,0 +1,9 @@
1
+ import nzh from "nzh";
2
+ class XNumber {
3
+ static toChinese(value) {
4
+ return nzh.cn.encodeS(value);
5
+ }
6
+ }
7
+ export {
8
+ XNumber
9
+ };
package/ocr.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ /// <reference types="node" />
2
+ export declare class XOcr {
3
+ static recognize(url: string, { serverUrl, }?: {
4
+ serverUrl?: string;
5
+ }): Promise<string>;
6
+ static recognizeCaptcha(buffer: Buffer, { serverUrl, serverToken, }?: {
7
+ serverUrl?: string;
8
+ serverToken?: string;
9
+ }): Promise<string>;
10
+ }
package/ocr.js ADDED
@@ -0,0 +1,54 @@
1
+ import { xr } from "@jayfong/x-request";
2
+ import { XEnv } from "./env.js";
3
+ class XOcr {
4
+ static async recognize(url, {
5
+ serverUrl
6
+ } = {}) {
7
+ if (serverUrl == null) {
8
+ serverUrl = await XEnv.getEnvVar("X_OCR_RECOGNIZE_SERVER_URL");
9
+ }
10
+ const { data: buffer } = await xr.get({
11
+ url,
12
+ autoReferer: true
13
+ });
14
+ const base64 = buffer.toString("base64");
15
+ const { data: res } = await xr.postJson({
16
+ url: serverUrl,
17
+ data: {
18
+ base64,
19
+ options: {}
20
+ }
21
+ });
22
+ if (res.code !== 100) {
23
+ if (res.data.includes("No text found in image")) {
24
+ return "";
25
+ }
26
+ throw new Error(res.data);
27
+ }
28
+ return res.data.map((item) => item.text).join(" ");
29
+ }
30
+ static async recognizeCaptcha(buffer, {
31
+ serverUrl,
32
+ serverToken
33
+ } = {}) {
34
+ if (serverUrl == null) {
35
+ serverUrl = await XEnv.getEnvVar("X_OCR_RECOGNIZE_CAPTCHA_SERVER_URL");
36
+ }
37
+ if (serverToken == null) {
38
+ serverToken = await XEnv.getEnvVar(
39
+ "X_OCR_RECOGNIZE_CAPTCHA_SERVER_TOKEN"
40
+ );
41
+ }
42
+ const res = await xr.postJson({
43
+ url: serverUrl,
44
+ data: xr.formData({
45
+ token: serverToken,
46
+ file: xr.formFile(buffer, { name: "xx.png" })
47
+ })
48
+ });
49
+ return res.data.text;
50
+ }
51
+ }
52
+ export {
53
+ XOcr
54
+ };
package/ofd.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};