xshell 0.0.20 → 0.0.24

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/i18n/README.md CHANGED
@@ -169,7 +169,7 @@ function TestTrans () {
169
169
 
170
170
  ## 词条扫描以及更新翻译的方法
171
171
  ### 整体流程
172
- ![i18n-arch.png](https://cos.shenhongfei.com/assets/i18n-arch.png)
172
+ ![xsh-i18n-arch.png](https://cos.shenhongfei.com/assets/xsh-i18n-arch.png)
173
173
 
174
174
  ### 词条标记
175
175
  #### 词条标记文档
@@ -208,21 +208,13 @@ npm i eslint eslint-plugin-i18n --save-dev
208
208
 
209
209
  3. 使用 `npm run scan` 扫描词条,会创建或修改 `./i18n/` 下的:
210
210
  ① `scanneds.json` 代码中扫描到的词条及其翻译 (仅本次 --input 所包含代码中的词条及翻译)
211
- ② `source/zh.json`, `source/en.json`, ... (`scanneds.json` 对应的 tea 词条格式,可提交到翻译仓库交由翻译团队翻译)
212
- ③ `dict.json` 完整的词典文件 (历史所有词条词条及翻译,会被打包到代码中在运行时决定词条翻译)
211
+ ② `dict.json` 完整的词典文件 (历史所有词条词条及翻译,会被打包到代码中在运行时决定词条翻译)
213
212
 
214
- 4. 补齐 `scanneds.json` 中的翻译,可以选择下面两种方法之一补充翻译:
215
- - 【方法一】交由翻译团队翻译:将 `source/zh.json` 等文件提交到翻译仓库 https://git.woa.com/intl-platform/intl-console-translation ,并创建 TAPD 单,待 `en.json`, 等翻译返回后放到 `source/` 中覆盖原来的文件
216
- - 自动化提交翻译词条配置可以参考文档 http://tapd.oa.com/tcp_access/markdown_wikis/show/#1220399462000786583
217
- - 配置完成后先运行 `npm run dict-pull` 拉取仓库中的词条翻译到本地
218
- - 再运行 `npm run scan` 生成待翻译词条
219
- - 最后运行 `npm run dict-push -- --lang en` 上传待翻译词条到仓库,提交 TAPD 单等待翻译团队翻译词条
220
- - 翻译团队完成翻译后再将词条拉取到本地 `npm run dict-pull`
221
- - 【方法二】手动补充词条翻译:手动补全扫描结果 `scanneds.json` 中未翻译的词条
213
+ 4. 补齐 `scanneds.json` 中的翻译
222
214
 
223
- 5. 通过以上 `"4."` 步骤补充翻译后重新运行扫描 `npm run scan`,这次扫描会自动根据 `source/en.json` 以及 `scanneds.json` 更新 `dict.json`。最终构建时 `dict.json` 内的词条会被打包进 js, 通过 i18n.init(<dict.json>) 加载
215
+ 5. 通过以上 `"4."` 步骤补充翻译后重新运行扫描 `npm run scan`,这次扫描会自动根据 `scanneds.json` 更新 `dict.json`。最终构建时 `dict.json` 内的词条会被打包进 js, 通过 `new I18N(<dict.json>)` 或 `i18n.init(<dict.json>)` 加载
224
216
 
225
- ![i18n-scan.png](https://cos.shenhongfei.com/assets/i18n-scan.png)
217
+ ![xsh-i18n-scan.png](https://cos.shenhongfei.com/assets/xsh-i18n-scan.png)
226
218
 
227
219
 
228
220
  ### 词典文件 dict.json 格式
@@ -1 +1 @@
1
- {"version":3,"file":"i18n-scan.js","sourceRoot":"","sources":["i18n-scan.ts"],"names":[],"mappings":";;;;AAEA,+DAAwB;AACxB,yCAAmC;AAEnC,qEAA+B;AAC/B,mCAAqC;AAErC,mBAAO,CAAC,IAAI,CAAC,WAAW,CAAC;KACpB,MAAM,CAAC,yBAAyB,EAAK,eAAe,EAAE,eAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;KACpF,MAAM,CAAC,qBAAqB,EAAS,6EAA6E,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;KACtI,MAAM,CAAC,uBAAuB,EAAO,6BAA6B,CAAC;KACnE,MAAM,CAAC,uBAAuB,EAAO,kHAAkH,EAAE,gBAAgB,CAAC;KAC1K,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AAExB,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,mBAAO,CAAC,IAAI,EAAE,CAAA;AACzD,IAAA,iBAAO,EAAC,OAAO,EAAE;IACb,GAAI,IAAA,mBAAW,EAAE,eAAI,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAE;IAChD,GAAI,KAAK,CAAE,CAAC,CAAE,EAAE,KAAK,EAAE,CAAG,CAAC,CAAE,EAAG;IAChC,GAAI,MAAM,CAAC,CAAC,CAAE,EAAE,MAAM,EAAE,CAAE,CAAC,CAAE,EAAG;CACnC,CAAC,CAAA","sourcesContent":["#!/usr/bin/env node\n\nimport path from 'upath'\nimport { program } from 'commander'\n\nimport scanner from './scanner'\nimport { try_require } from './utils'\n\nprogram.name('i18n-scan')\n .option('-r, --rootdir [rootdir]' , '根目录:默认为当前工作目录', path.normalize(process.cwd()))\n .option('-i, --input [input]' , '扫描 pattern:多个 pattern 用分号分割,采用 glob pattern 匹配,如 `src/**/*.{js,jsx,ts,tsx}`', v => v.split(';'))\n .option('-o, --output [output]' , 'i18n 目录:默认为 <rootdir>/i18n/')\n .option('-c, --config [config]' , '自定义配置文件,默认为 <rootdir>/i18n/config.js ,可参考默认配置 xshell/i18n/index.ts 以及 https://github.com/i18next/i18next-scanner', 'i18n/config.js')\n .parse(process.argv)\n\nconst { rootdir, config, input, output } = program.opts()\nscanner(rootdir, {\n ... try_require( path.resolve(rootdir, config) ),\n ... input ? { input } : { },\n ... output ? { output } : { },\n})\n"]}
1
+ {"version":3,"file":"i18n-scan.js","sourceRoot":"","sources":["i18n-scan.ts"],"names":[],"mappings":";;;;AAEA,+DAAwB;AACxB,yCAAmC;AAEnC,qEAA+B;AAC/B,mCAAqC;AAErC,mBAAO,CAAC,IAAI,CAAC,WAAW,CAAC;KACpB,MAAM,CAAC,yBAAyB,EAAK,eAAe,EAAE,eAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;KACpF,MAAM,CAAC,qBAAqB,EAAS,6EAA6E,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;KACtI,MAAM,CAAC,uBAAuB,EAAO,6BAA6B,CAAC;KACnE,MAAM,CAAC,uBAAuB,EAAO,kHAAkH,EAAE,gBAAgB,CAAC;KAC1K,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AAExB,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,mBAAO,CAAC,IAAI,EAAE,CAAA;AACzD,IAAA,iBAAO,EAAC,OAAO,EAAE;IACb,GAAI,IAAA,mBAAW,EACX,eAAI,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAChC;IACD,GAAI,KAAK,CAAE,CAAC,CAAE,EAAE,KAAK,EAAE,CAAG,CAAC,CAAE,EAAG;IAChC,GAAI,MAAM,CAAC,CAAC,CAAE,EAAE,MAAM,EAAE,CAAE,CAAC,CAAE,EAAG;CACnC,CAAC,CAAA","sourcesContent":["#!/usr/bin/env node\n\nimport path from 'upath'\nimport { program } from 'commander'\n\nimport scanner from './scanner'\nimport { try_require } from './utils'\n\nprogram.name('i18n-scan')\n .option('-r, --rootdir [rootdir]' , '根目录:默认为当前工作目录', path.normalize(process.cwd()))\n .option('-i, --input [input]' , '扫描 pattern:多个 pattern 用分号分割,采用 glob pattern 匹配,如 `src/**/*.{js,jsx,ts,tsx}`', v => v.split(';'))\n .option('-o, --output [output]' , 'i18n 目录:默认为 <rootdir>/i18n/')\n .option('-c, --config [config]' , '自定义配置文件,默认为 <rootdir>/i18n/config.js ,可参考默认配置 xshell/i18n/index.ts 以及 https://github.com/i18next/i18next-scanner', 'i18n/config.js')\n .parse(process.argv)\n\nconst { rootdir, config, input, output } = program.opts()\nscanner(rootdir, {\n ... try_require(\n path.resolve(rootdir, config)\n ),\n ... input ? { input } : { },\n ... output ? { output } : { },\n})\n"]}
package/i18n/index.d.ts CHANGED
@@ -10,7 +10,7 @@ declare global {
10
10
  }
11
11
  /**
12
12
  提供翻译文本功能,在浏览器环境下自动解析当前语言、国际/国内用户
13
- @see https://github.com/ShenHongFei/xshell/i18n/
13
+ @see https://github.com/ShenHongFei/xshell/tree/master/i18n
14
14
  */
15
15
  export declare class I18N {
16
16
  static LANGUAGE_REGEXP: RegExp;
@@ -39,7 +39,7 @@ export declare class I18N {
39
39
  const i18n = new I18N(dict) // 创建实例,传入词典 dict 并自动判断当前语言(浏览器环境),
40
40
  const i18n = new I18N({ }) // 创建实例,传入空词典
41
41
  ```
42
- @see https://github.com/ShenHongFei/xshell/i18n/
42
+ @see https://github.com/ShenHongFei/xshell/tree/master/i18n
43
43
  */
44
44
  constructor(_dict: _Dict, language?: Language);
45
45
  /** 加载词典文件 (需要将这两行单独放一个文件里,以保证在 import 其他文件之前执行)
package/i18n/index.js CHANGED
@@ -9,7 +9,7 @@ const dict_1 = require("./dict");
9
9
  exports.LANGUAGES = ['zh', 'en', 'ja', 'ko'];
10
10
  /**
11
11
  提供翻译文本功能,在浏览器环境下自动解析当前语言、国际/国内用户
12
- @see https://github.com/ShenHongFei/xshell/i18n/
12
+ @see https://github.com/ShenHongFei/xshell/tree/master/i18n
13
13
  */
14
14
  class I18N {
15
15
  /** ```ts
@@ -19,7 +19,7 @@ class I18N {
19
19
  const i18n = new I18N(dict) // 创建实例,传入词典 dict 并自动判断当前语言(浏览器环境),
20
20
  const i18n = new I18N({ }) // 创建实例,传入空词典
21
21
  ```
22
- @see https://github.com/ShenHongFei/xshell/i18n/
22
+ @see https://github.com/ShenHongFei/xshell/tree/master/i18n
23
23
  */
24
24
  constructor(_dict, language) {
25
25
  /** react-i18next <Trans/> 组件 */
@@ -31,7 +31,7 @@ class I18N {
31
31
  const { search = '' } = document.location || {};
32
32
  const queries = qs_1.default.parse(search, { ignoreQueryPrefix: true });
33
33
  if (!language) {
34
- const lquery = (queries.language || queries.lang); // 暂时不考虑是数组的情况
34
+ const lquery = queries.language; // 暂时不考虑是数组的情况
35
35
  const lwindow = window.language;
36
36
  const lbrowser = typeof navigator !== 'undefined' && navigator.language.slice(0, 2);
37
37
  language = (lquery || lwindow || js_cookie_1.default.get('language') || lbrowser || 'en');
package/i18n/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import qs from 'qs'\nimport Cookies from 'js-cookie'\nimport i18next from 'i18next'\nimport type { i18n as I18Next } from 'i18next'\nimport type { Trans } from 'react-i18next'\n\nimport { Dict } from './dict'\nimport type { _Dict, Item } from './dict'\n\n\nexport type Language = 'zh' | 'en' | 'ja' | 'ko'\n\nexport const LANGUAGES = ['zh', 'en', 'ja', 'ko'] as const\n\ndeclare global {\n interface Window {\n language: Language\n }\n}\n\n\n/**\n 提供翻译文本功能,在浏览器环境下自动解析当前语言、国际/国内用户\n @see https://github.com/ShenHongFei/xshell/i18n/\n*/\nexport class I18N {\n static LANGUAGE_REGEXP = /^(zh|en|ja|jp|ko)$/\n \n \n /** (ISO 639-1 标准语言代码) 可能取 zh, en, ja, ko */\n language: Language\n \n /** hostname shortcuts */\n hosts: Hosts\n \n /** url prefix shortcuts */\n roots: Roots\n \n /** 标记静态文本,以便扫描词条,并在运行时根据当前语言获取翻译 */\n t : (text: string, options?: { language?: Language, context?: string, count?: number, [key: string]: any }) => string\n \n /** render: 翻译配置字段 */\n r : (field: Item | undefined | null) => string\n \n i18next: I18Next\n \n /** react-i18next <Trans/> 组件 */\n Trans: typeof Trans = ({ children }) => children as any\n \n \n /** ```ts\n import dict from './dict.json' // { \"添加\": { \"en\": \"Add\", \"ja\": \"追加\", \"ko\": \"추가\" } }\n \n const i18n = new I18N(dict, 'zh') // 创建实例,传入词典 dict 并指定语言(NodeJS 环境),\n const i18n = new I18N(dict) // 创建实例,传入词典 dict 并自动判断当前语言(浏览器环境),\n const i18n = new I18N({ }) // 创建实例,传入空词典\n ```\n @see https://github.com/ShenHongFei/xshell/i18n/\n */\n constructor (_dict: _Dict, language?: Language) {\n const is_browser = typeof document !== 'undefined' && typeof window !== 'undefined'\n \n const dict = new Dict(_dict)\n \n // --- if in bowser then detect language & intl\n if (is_browser) {\n const { search = '' } = document.location || { }\n const queries = qs.parse(search, { ignoreQueryPrefix: true })\n \n if (!language) {\n const lquery = (queries.language || queries.lang) as string // 暂时不考虑是数组的情况\n const lwindow = window.language\n const lbrowser = typeof navigator !== 'undefined' && navigator.language.slice(0, 2)\n \n language = (lquery || lwindow || Cookies.get('language') || lbrowser || 'en') as Language\n }\n \n if (!I18N.LANGUAGE_REGEXP.test(language))\n language = 'en'\n \n // console.log(`language = ${language}`)\n }\n \n language ||= 'en'\n \n this.language = language\n \n this.t = (text, options) => {\n options = options || { }\n \n const language = options.language || this.language\n \n return this.i18next.t(text, { ...options, lng: language, defaultValue: text })\n }\n \n this.r = (field) => \n field ?\n field[this.language] || field.en || field.zh || field as any || ''\n :\n field || ''\n \n // --- init i18next\n this.i18next = i18next.createInstance()\n \n if (is_browser)\n try {\n // 在无 React 的浏览器环境下避免 react-i18next 中执行 React.createContext() 报错\n // const React = require('react') as typeof import('react')\n const { initReactI18next, Trans: I18NextTrans } = require('react-i18next') as typeof import('react-i18next')\n this.i18next.use(initReactI18next)\n const _i18next = this.i18next\n // 绑定 Trans 组件的 i18n 到 this.i18next, 解决多个 i18next 冲突的问题\n // react-i18next/context.js 中 i18n 实例只在模块级别维护,多次 this.i18next.use(initReactI18next) 会覆盖前面的 i18n,导致 Trans 无法翻译\n // https://github.com/i18next/react-i18next/issues/726\n this.Trans = function Trans ({ i18n = _i18next, ...others }) {\n // 简单转发,性能更好\n return I18NextTrans({ i18n, ...others })\n // return React.createElement(I18NextTrans, { i18n, ...others } as any, children)\n // return <I18NextTrans {...{ i18n, ...others } }>{children}</I18NextTrans>\n }\n } catch { }\n \n this.i18next.init({\n lng: this.language,\n // LOCAL\n // debug: true,\n debug: false,\n fallbackLng: {\n en: ['zh'],\n ja: ['en', 'zh'],\n ko: ['en', 'zh'],\n },\n // 禁用 : 和 . 作为 seperator\n keySeparator: false,\n nsSeparator: false,\n resources: dict.to_resources(),\n interpolation: {\n escapeValue: false\n },\n react: {\n transKeepBasicHtmlNodesFor: []\n },\n })\n \n \n if (typeof window !== 'undefined' && window && !('i18n' in window))\n (window as any).i18n = this\n }\n \n \n /** 加载词典文件 (需要将这两行单独放一个文件里,以保证在 import 其他文件之前执行) \n \n @example\n import dict from './dict.json' // { \"添加\": { \"en\": \"Add\", \"ja\": \"追加\", \"ko\": \"추가\" } }\n i18n.init(dict)\n */\n init (dict: _Dict) {\n Object.entries(\n new Dict(dict).to_resources()\n ).forEach(([language, { translation }]) => {\n this.i18next.addResources(language, 'translation', translation)\n })\n }\n \n toJSON () {\n return {\n language: this.language,\n }\n }\n}\n\n\nexport interface Hosts {\n \n}\n\n\nexport interface Roots {\n \n}\n\nexport type { _Dict, Item }\n\nexport interface I18NBasic {\n intl: boolean\n language: Language\n}\n\nexport default I18N\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import qs from 'qs'\nimport Cookies from 'js-cookie'\nimport i18next from 'i18next'\nimport type { i18n as I18Next } from 'i18next'\nimport type { Trans } from 'react-i18next'\n\nimport { Dict } from './dict'\nimport type { _Dict, Item } from './dict'\n\n\nexport type Language = 'zh' | 'en' | 'ja' | 'ko'\n\nexport const LANGUAGES = ['zh', 'en', 'ja', 'ko'] as const\n\ndeclare global {\n interface Window {\n language: Language\n }\n}\n\n\n/**\n 提供翻译文本功能,在浏览器环境下自动解析当前语言、国际/国内用户\n @see https://github.com/ShenHongFei/xshell/tree/master/i18n\n*/\nexport class I18N {\n static LANGUAGE_REGEXP = /^(zh|en|ja|jp|ko)$/\n \n \n /** (ISO 639-1 标准语言代码) 可能取 zh, en, ja, ko */\n language: Language\n \n /** hostname shortcuts */\n hosts: Hosts\n \n /** url prefix shortcuts */\n roots: Roots\n \n /** 标记静态文本,以便扫描词条,并在运行时根据当前语言获取翻译 */\n t : (text: string, options?: { language?: Language, context?: string, count?: number, [key: string]: any }) => string\n \n /** render: 翻译配置字段 */\n r : (field: Item | undefined | null) => string\n \n i18next: I18Next\n \n /** react-i18next <Trans/> 组件 */\n Trans: typeof Trans = ({ children }) => children as any\n \n \n /** ```ts\n import dict from './dict.json' // { \"添加\": { \"en\": \"Add\", \"ja\": \"追加\", \"ko\": \"추가\" } }\n \n const i18n = new I18N(dict, 'zh') // 创建实例,传入词典 dict 并指定语言(NodeJS 环境),\n const i18n = new I18N(dict) // 创建实例,传入词典 dict 并自动判断当前语言(浏览器环境),\n const i18n = new I18N({ }) // 创建实例,传入空词典\n ```\n @see https://github.com/ShenHongFei/xshell/tree/master/i18n\n */\n constructor (_dict: _Dict, language?: Language) {\n const is_browser = typeof document !== 'undefined' && typeof window !== 'undefined'\n \n const dict = new Dict(_dict)\n \n // --- if in bowser then detect language & intl\n if (is_browser) {\n const { search = '' } = document.location || { }\n const queries = qs.parse(search, { ignoreQueryPrefix: true })\n \n if (!language) {\n const lquery = queries.language as string // 暂时不考虑是数组的情况\n const lwindow = window.language\n const lbrowser = typeof navigator !== 'undefined' && navigator.language.slice(0, 2)\n \n language = (lquery || lwindow || Cookies.get('language') || lbrowser || 'en') as Language\n }\n \n if (!I18N.LANGUAGE_REGEXP.test(language))\n language = 'en'\n \n // console.log(`language = ${language}`)\n }\n \n language ||= 'en'\n \n this.language = language\n \n this.t = (text, options) => {\n options = options || { }\n \n const language = options.language || this.language\n \n return this.i18next.t(text, { ...options, lng: language, defaultValue: text })\n }\n \n this.r = (field) => \n field ?\n field[this.language] || field.en || field.zh || field as any || ''\n :\n field || ''\n \n // --- init i18next\n this.i18next = i18next.createInstance()\n \n if (is_browser)\n try {\n // 在无 React 的浏览器环境下避免 react-i18next 中执行 React.createContext() 报错\n // const React = require('react') as typeof import('react')\n const { initReactI18next, Trans: I18NextTrans } = require('react-i18next') as typeof import('react-i18next')\n this.i18next.use(initReactI18next)\n const _i18next = this.i18next\n // 绑定 Trans 组件的 i18n 到 this.i18next, 解决多个 i18next 冲突的问题\n // react-i18next/context.js 中 i18n 实例只在模块级别维护,多次 this.i18next.use(initReactI18next) 会覆盖前面的 i18n,导致 Trans 无法翻译\n // https://github.com/i18next/react-i18next/issues/726\n this.Trans = function Trans ({ i18n = _i18next, ...others }) {\n // 简单转发,性能更好\n return I18NextTrans({ i18n, ...others })\n // return React.createElement(I18NextTrans, { i18n, ...others } as any, children)\n // return <I18NextTrans {...{ i18n, ...others } }>{children}</I18NextTrans>\n }\n } catch { }\n \n this.i18next.init({\n lng: this.language,\n // LOCAL\n // debug: true,\n debug: false,\n fallbackLng: {\n en: ['zh'],\n ja: ['en', 'zh'],\n ko: ['en', 'zh'],\n },\n // 禁用 : 和 . 作为 seperator\n keySeparator: false,\n nsSeparator: false,\n resources: dict.to_resources(),\n interpolation: {\n escapeValue: false\n },\n react: {\n transKeepBasicHtmlNodesFor: []\n },\n })\n \n \n if (typeof window !== 'undefined' && window && !('i18n' in window))\n (window as any).i18n = this\n }\n \n \n /** 加载词典文件 (需要将这两行单独放一个文件里,以保证在 import 其他文件之前执行) \n \n @example\n import dict from './dict.json' // { \"添加\": { \"en\": \"Add\", \"ja\": \"追加\", \"ko\": \"추가\" } }\n i18n.init(dict)\n */\n init (dict: _Dict) {\n Object.entries(\n new Dict(dict).to_resources()\n ).forEach(([language, { translation }]) => {\n this.i18next.addResources(language, 'translation', translation)\n })\n }\n \n toJSON () {\n return {\n language: this.language,\n }\n }\n}\n\n\nexport interface Hosts {\n \n}\n\n\nexport interface Roots {\n \n}\n\nexport type { _Dict, Item }\n\nexport interface I18NBasic {\n intl: boolean\n language: Language\n}\n\nexport default I18N\n"]}
@@ -23,7 +23,9 @@ const DEFAULT_CONFIG = {
23
23
  debug: false,
24
24
  input: [
25
25
  // 'src/**/*.{js,jsx,ts,tsx}',
26
- '!i18n/**', // Use ! to filter out files or directories
26
+ '!i18n/**',
27
+ '!node_modules/**',
28
+ '!**/*.d.ts',
27
29
  ],
28
30
  // 相对于根目录
29
31
  output: 'i18n/',
@@ -103,7 +105,9 @@ const VALID_EXTENTIONS = new Set(['.js', '.jsx', '.ts', '.tsx', '.ejs']);
103
105
  */
104
106
  function scanner(rootdir = upath_1.default.normalize(process.cwd()), config = {}) {
105
107
  const output = upath_1.default.resolve(rootdir, config.output || DEFAULT_CONFIG.output);
106
- const input = (config.input || DEFAULT_CONFIG.input).map(fp => upath_1.default.resolve(rootdir, fp));
108
+ if (!config.input.length)
109
+ throw new Error('运行 i18n-scan 请指定 --input');
110
+ const input = [...config.input, ...DEFAULT_CONFIG.input];
107
111
  config = {
108
112
  ...DEFAULT_CONFIG,
109
113
  ...config,
@@ -302,7 +306,7 @@ function scanner(rootdir = upath_1.default.normalize(process.cwd()), config = {}
302
306
  console.log('通过以上方法补充翻译后重新运行扫描,会根据 scanneds.json 更新 dict.json'.yellow);
303
307
  console.log('最后 dict.json 所包含的词条会被打包进 js, 通过 new I18N(<dict.json>) 或 i18n.init(<dict.json>) 加载'.yellow);
304
308
  console.log();
305
- console.log(`${'详细文档请查看:'.yellow} ${'https://github.com/ShenHongFei/xshell/i18n'.blue.underline}`);
309
+ console.log(`${'详细文档请查看:'.yellow} ${'https://github.com/ShenHongFei/xshell/tree/master/i18n'.blue.underline}`);
306
310
  cb();
307
311
  }))
308
312
  // 写入词条文件
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import i18n_scanner from 'i18next-scanner'\nimport path from 'upath'\nimport ejs from 'ejs'\nimport vfs from 'vinyl-fs'\nimport map from 'map-stream'\nimport sort from 'gulp-sort'\nimport ora from 'ora'\nimport cli_truncate from 'cli-truncate'\nimport Vinyl from 'vinyl'\nimport through2 from 'through2'\nimport CliTable from 'cli-table3'\nimport type { Transform } from 'stream'\n\nimport { LANGUAGES } from '../index'\nimport type { Language } from '../index'\nimport Dict from '../rwdict'\nimport type { _Dict } from '../dict'\nimport { try_require } from '../utils'\n\nimport '../../prototype.js'\n\nimport { mix_parse_trans_from_string_by_babel } from './parser'\n\n\n\n/** 默认 i18next 扫描配置 */\nconst DEFAULT_CONFIG = {\n debug: false,\n \n input: [\n // 'src/**/*.{js,jsx,ts,tsx}',\n '!i18n/**', // Use ! to filter out files or directories\n ],\n \n // 相对于根目录\n output: 'i18n/',\n \n // 若是相对路径,则以 output 为基准进行解析\n dict: ['dict.json', 'scanneds.json'],\n \n lngs: ['zh', 'en', 'ja', 'ko'],\n ns: ['translation'],\n defaultLng: 'zh',\n defaultNs: 'translation',\n\n func: {\n list: [ 'i18next.t', 'i18n.t', 'i18n.__', 't', '__' ],\n extensions: [ ], // 避免在 transform 中执行原生的 parseFuncFromString\n },\n \n trans: {\n extensions: [ ], // 避免在 transform 中执行原生的 parseTransFromString\n fallbackKey: true,\n \n babylon: {\n sourceType: 'module',\n \n allowAwaitOutsideFunction: true,\n \n // https://babeljs.io/docs/en/babel-parser\n plugins: [\n // Language extensions\n 'jsx',\n 'typescript',\n \n // ECMAScript proposals\n 'classProperties',\n 'classPrivateProperties',\n 'classPrivateMethods',\n 'classStaticBlock',\n 'decimal',\n ['decorators', { decoratorsBeforeExport: true }],\n 'doExpressions',\n 'exportDefaultFrom',\n 'functionBind',\n 'importAssertions',\n 'moduleBlocks',\n 'moduleStringNames',\n 'partialApplication',\n ['pipelineOperator', { proposal: 'smart' }],\n 'privateIn',\n ['recordAndTuple', { syntaxType: 'bar' }],\n 'throwExpressions',\n 'topLevelAwait',\n ],\n } as import('@babel/parser').ParserOptions,\n \n // 实际并没有用到 acorn, 用了 babel\n acorn: {\n ecmaVersion: 'latest',\n sourceType: 'module', // defaults to 'module'\n // Check out https://github.com/acornjs/acorn/tree/master/acorn#interface for additional options\n }\n },\n \n // 禁用 : 和 . 作为 seperator\n keySeparator: false, // char to separate keys\n nsSeparator: false, // char to split namespace from key\n \n // Context Form\n context: true, // whether to add context form key\n contextFallback: true, // whether to add a fallback key as well as the context form key\n contextSeparator: '_', // char to split context from key\n\n // Plural\n // whether to add plural form key\n plural (language: string, ns: string, key: string, options: any /** Config */) {\n return language === 'en'\n }, \n pluralFallback: true, // whether to add a fallback key as well as the plural form key\n pluralSeparator: '_', // char to split plural from key\n \n // interpolation options\n interpolation: {\n prefix: '{{', // prefix for interpolation\n suffix: '}}' // suffix for interpolation\n }\n}\n\nconst VALID_EXTENTIONS = new Set(['.js', '.jsx', '.ts', '.tsx', '.ejs'])\n\nexport type Config = Partial<(typeof DEFAULT_CONFIG) & {\n defaultValue?: string\n resource?: { loadPath?: string, savePath?: string, jsonIndent?: number, lineEnding?: '\\n' }\n}>\n\n\n/** 扫描源码中的词条,以及收集未翻译的词条。生成 scanneds.json 和 untranslateds.json\n* rootdir 要扫描根目录 [ process.cwd() ]\n* config 配置信息\n*/\nexport function scanner (rootdir: string = path.normalize(process.cwd()), config: Config = { }) {\n const output = path.resolve(rootdir, config.output || DEFAULT_CONFIG.output)\n const input = (config.input || DEFAULT_CONFIG.input).map( fp => path.resolve(rootdir, fp) )\n \n config = {\n ...DEFAULT_CONFIG,\n ...config,\n input,\n output,\n resource: {\n loadPath: '',\n savePath: path.resolve(output, 'translation/{{lng}}.js'),\n jsonIndent: 4,\n lineEnding: '\\n'\n }\n }\n \n \n let dict = config.dict.reduce( (dict, fp_dict) => \n dict.merge( try_require( path.resolve(output, fp_dict)), { print: false, overwrite: true }),\n new Dict())\n \n let c_files = 0\n let c_scanneds = 0\n let errors = []\n \n // 扫描出的词条及已有的翻译\n let scanneds: _Dict = { }\n \n // 所有语言的扫描统计信息\n let stats = Object.fromEntries(\n LANGUAGES.map( (language) => [language, { translateds: new Set<string>(), untranslateds: new Set<string>() }])\n )\n \n let spinner = ora({ interval: 66 }).start('Scanning...')\n \n \n \n function on_scanned (text: string, { language, key, defaultValue, count, context }: { language?: Language, key?: string, defaultValue?: string, count?: number, context?: string }) {\n // console.log(text, { language, key, defaultValue, count, context })\n \n text = text || defaultValue\n \n if (!key)\n key = context ? `${text}_${context}` : text\n \n if (!language) {\n for (const language of LANGUAGES)\n on_scanned(text, { language, key, count, context })\n return\n }\n \n // console.log(text, { language, key, defaultValue, count, context })\n // debugger\n \n const stat = stats[language]\n \n // 获取已有翻译\n const translation = \n dict.get(key, language) || \n language === 'zh' && text || \n ''\n \n if (language === 'zh' && !context) return\n \n scanneds[key] = {\n ... scanneds[key],\n [language]: translation\n }\n \n if (translation)\n stat.translateds.add(key)\n else\n stat.untranslateds.add(key)\n \n if (language === 'en' && count !== undefined)\n on_scanned(text, { language, key: `${key}_plural`, context })\n }\n \n \n function new_vinyl_file (_path: string, data: string | object) {\n return new Vinyl({\n cwd: rootdir,\n base: rootdir,\n path: path.resolve(config.output, _path),\n contents: Buffer.from(typeof data === 'string' ? data : JSON.stringify(data, null, 4))\n })\n }\n \n \n // ------------ scan by file\n vfs\n .src(config.input, { cwd: rootdir, sync: false })\n \n // 每个文件扫描前,统计文件数量\n .pipe(\n map( (file: Vinyl, cb: Function, count: number) => {\n // 支持 `// @i18n-noscan` 忽略扫描\n if (/\\/\\/\\s*@i18n-noscan\\s/.test(file.contents.toString())) return cb()\n c_files++\n cb(null, file)\n })\n )\n \n // 对文件进行排序,保证词条有一定的顺序\n .pipe( sort() )\n \n // 分析代码提取词条\n .pipe(\n i18n_scanner.createStream( config, function transform (this: { parser: any }, file: Vinyl, encoding: string, callback: Function): void {\n const { parser } = this\n const ext = path.extname(file.path)\n \n // 只扫描源码文件\n if (!VALID_EXTENTIONS.has(ext)) {\n callback()\n return\n }\n \n c_scanneds++\n const percent = Math.round( (100 * c_scanneds) / c_files )\n const text = `Scanning (${percent}%): ${file.path.green}`\n spinner.text = cli_truncate(text, process.stdout.columns - 5, { position: 'middle', })\n \n let code = file.contents.toString()\n \n if (ext === '.ejs')\n code = ejs.compile( code, { filename: file.path, client: true, legacyInclude: true } as any ).toString()\n \n \n // --- 添加代码中扫描到的 i18n.t('key') 中的 key 到 parser\n // parser.parseFuncFromString 使用 esprima 来解析代码,esprima 仍然不支持 optional chaining !!\n parser.parseFuncFromString(code.replace(/\\?\\.\\[/g, '[').replace(/\\?\\.\\(/g, '(').replace(/\\?\\./g, '.'), on_scanned)\n \n // --- 添加代码中扫描到的 Trans 组件中的 key 到 parser\n if (ext === '.jsx' || ext === '.tsx') {\n // parser.parseTransFromString 使用 acorn 解析代码,不支持 TypeScript,添加 parser.parseTransFromStringByBabel\n mix_parse_trans_from_string_by_babel(parser)\n parser.parseTransFromStringByBabel(\n code,\n { filepath: file.path },\n on_scanned,\n (error: Error) => { errors.push(error) }\n )\n }\n \n setTimeout(callback, 0)\n })\n )\n \n // 创建词条文件\n .pipe(\n through2.obj(\n /** i18n-scanner 会把扫描结果以每个语言一个文件的形式提供,这里解析扫描结果\n * file: 翻译 resource 文件,其中 file.contents 包含翻译的扫描结果\n */\n function write (this: Transform, file: Vinyl, encoding: string, cb: Function) { cb() },\n \n /** 生成 stats.json, unmarkeds.md; 打印 untranslated / unmarkeds */\n function flush (this: Transform, cb: Function) {\n // ------------ stats.json\n this.push(new_vinyl_file('stats.json', \n Object.fromEntries(\n Object.entries(stats).map( ([l, { translateds, untranslateds }]) => \n [l, { translateds: Array.from(translateds), untranslateds: Array.from(untranslateds) }])\n )\n ))\n \n \n // ------------ 打印 cli 统计表\n const table = new CliTable({\n head: [\n 'Language',\n 'Untranslated'.red,\n 'Translated'.green,\n ],\n colAligns: ['right', 'right', 'right', 'right'],\n style: { head: [] },\n chars: {\n top: '',\n 'top-mid': '',\n 'top-left': '',\n 'top-right': '',\n bottom: '',\n 'bottom-mid': '',\n 'bottom-left': '',\n 'bottom-right': '',\n left: '',\n 'left-mid': '',\n mid: '',\n 'mid-mid': '',\n right: '',\n 'right-mid': '',\n middle: ' ',\n },\n })\n \n Object.entries(stats).forEach( ([lang, stat]) => {\n table.push([\n lang, \n String(stat.untranslateds.size).red, \n String(stat.translateds.size).green\n ] as any)\n })\n \n \n \n spinner.stop()\n console.log(`Scanned ${c_files} files. Occured ${errors.length} errors.`)\n console.log(table.toString())\n \n \n // ------------ 生成 unmarkeds.md 统计\n /*\n const fp_unmarked = path.resolve(config.output, 'unmarkeds.md')\n \n if (fs.existsSync(fp_unmarked))\n rimraf.sync(fp_unmarked)\n \n if (unmarkeds.length) {\n console.log(colors.yellow(`\\n⚠️ 发现未标记的中文字符 ${unmarkeds.length} 处:\\n`))\n unmarkeds.forEach(({ value, filepath, loc: { start } }, index) => {\n if (index >= 5) return\n console.log( ` ${colors.white(`'${value}'`)}\\t${colors.blue.underline(`${path.relative(rootdir, filepath)}:${start.line}:${start.column + 1}`)}` )\n })\n }\n \n this.push( new_vinyl_file( fp_unmarked, \n unmarkeds.map( ({ value, filepath, loc }) =>\n '- [' + value.trim() + '](' + path.relative( config.output, path.resolve(rootdir, filepath || '') ) + '#L' + loc.start.line + ')'\n ).join('\\n') + '\\n'\n ))\n \n \n if (unmarkeds.length > 5) {\n console.log(' ...')\n console.log(colors.yellow(`\\n 完整未标记词条请查看 ${colors.blue.underline(path.relative(rootdir, fp_unmarked))}`))\n }\n */\n \n const en_untranslateds = stats.en.untranslateds\n if (en_untranslateds.size) {\n console.log('\\n未翻译的英文词条:'.yellow)\n Array.from(en_untranslateds).slice(0, 10).forEach( untranslated => {\n console.log(untranslated)\n })\n if (en_untranslateds.size > 10) {\n console.log('...')\n console.log(`--- 共 ${en_untranslateds.size} 个未翻译的英文词条 ---`)\n }\n } else\n console.log('\\n所有词条都至少含有英文翻译.'.green)\n \n \n // ------------ 生成 scanneds.json\n const fp_scanneds = path.resolve(config.output, 'scanneds.json')\n this.push(\n new_vinyl_file(fp_scanneds, scanneds)\n )\n \n // ------------ 写入 dict.json\n const fp_dict_new = path.resolve(output, 'dict.json')\n this.push( new_vinyl_file( fp_dict_new, dict.to_json(true) + '\\n' ))\n \n console.log(`\\n\\n${'⚠️ 请检查扫描结果'.yellow} ${fp_scanneds.underline.blue} ${'和新生成的词典文件'.yellow} ${fp_dict_new.underline.blue}`)\n console.log('\\n请手动补全扫描结果 scanneds.json 中未翻译的词条'.yellow)\n console.log('\\n')\n console.log('通过以上方法补充翻译后重新运行扫描,会根据 scanneds.json 更新 dict.json'.yellow)\n console.log('最后 dict.json 所包含的词条会被打包进 js, 通过 new I18N(<dict.json>) 或 i18n.init(<dict.json>) 加载'.yellow)\n console.log()\n console.log(`${'详细文档请查看:'.yellow} ${'https://github.com/ShenHongFei/xshell/i18n'.blue.underline}`)\n \n cb()\n }\n )\n )\n \n // 写入词条文件\n .pipe(\n vfs.dest(rootdir)\n )\n \n .on('end', () => {\n errors.forEach( errorHandler => errorHandler() )\n if (!errors.length) return\n console.log(\n 'https://www.i18next.com/translation-function/essentials\\n以上错误可能是由不规范的词条标记导致,标记规范可见:%s',\n ''.blue.underline\n )\n })\n}\n\nexport default scanner\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;;AAAA,mFAA0C;AAC1C,+DAAwB;AACxB,2DAAqB;AACrB,qEAA0B;AAC1B,yEAA4B;AAC5B,uEAA4B;AAC5B,2DAAqB;AACrB,6EAAuC;AACvC,+DAAyB;AACzB,qEAA+B;AAC/B,yEAAiC;AAGjC,oCAAoC;AAEpC,oEAA4B;AAE5B,oCAAsC;AAEtC,8BAA2B;AAE3B,qCAA+D;AAI/D,sBAAsB;AACtB,MAAM,cAAc,GAAG;IACnB,KAAK,EAAE,KAAK;IAEZ,KAAK,EAAE;QACH,8BAA8B;QAC9B,UAAU;QACV,kBAAkB;QAClB,YAAY;KACf;IAED,SAAS;IACT,MAAM,EAAE,OAAO;IAEf,2BAA2B;IAC3B,IAAI,EAAE,CAAC,WAAW,EAAE,eAAe,CAAC;IAEpC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IAC9B,EAAE,EAAE,CAAC,aAAa,CAAC;IACnB,UAAU,EAAE,IAAI;IAChB,SAAS,EAAE,aAAa;IAExB,IAAI,EAAE;QACF,IAAI,EAAE,CAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,CAAE;QACrD,UAAU,EAAE,EAAG,EAAE,2CAA2C;KAC/D;IAED,KAAK,EAAE;QACH,UAAU,EAAE,EAAG;QACf,WAAW,EAAE,IAAI;QAEjB,OAAO,EAAE;YACL,UAAU,EAAE,QAAQ;YAEpB,yBAAyB,EAAE,IAAI;YAE/B,0CAA0C;YAC1C,OAAO,EAAE;gBACL,sBAAsB;gBACtB,KAAK;gBACL,YAAY;gBAEZ,uBAAuB;gBACvB,iBAAiB;gBACjB,wBAAwB;gBACxB,qBAAqB;gBACrB,kBAAkB;gBAClB,SAAS;gBACT,CAAC,YAAY,EAAE,EAAE,sBAAsB,EAAE,IAAI,EAAE,CAAC;gBAChD,eAAe;gBACf,mBAAmB;gBACnB,cAAc;gBACd,kBAAkB;gBAClB,cAAc;gBACd,mBAAmB;gBACnB,oBAAoB;gBACpB,CAAC,kBAAkB,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;gBAC3C,WAAW;gBACX,CAAC,gBAAgB,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;gBACzC,kBAAkB;gBAClB,eAAe;aAClB;SACqC;QAE1C,0BAA0B;QAC1B,KAAK,EAAE;YACH,WAAW,EAAE,QAAQ;YACrB,UAAU,EAAE,QAAQ,EAAE,uBAAuB;YAC7C,gGAAgG;SACnG;KACJ;IAED,wBAAwB;IACxB,YAAY,EAAE,KAAK;IACnB,WAAW,EAAE,KAAK;IAElB,eAAe;IACf,OAAO,EAAE,IAAI;IACb,eAAe,EAAE,IAAI;IACrB,gBAAgB,EAAE,GAAG;IAErB,SAAS;IACT,iCAAiC;IACjC,MAAM,CAAE,QAAgB,EAAE,EAAU,EAAE,GAAW,EAAE,OAAY,CAAC,aAAa;QACzE,OAAO,QAAQ,KAAK,IAAI,CAAA;IAC5B,CAAC;IACD,cAAc,EAAE,IAAI;IACpB,eAAe,EAAE,GAAG;IAEpB,wBAAwB;IACxB,aAAa,EAAE;QACX,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,IAAI,CAAC,2BAA2B;KAC3C;CACJ,CAAA;AAED,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;AAQxE;;;EAGE;AACF,SAAgB,OAAO,CAAE,UAAkB,eAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,SAAiB,EAAG;IAC1F,MAAM,MAAM,GAAG,eAAI,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,IAAI,cAAc,CAAC,MAAM,CAAC,CAAA;IAE5E,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM;QACpB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;IAE/C,MAAM,KAAK,GAAI,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;IAEzD,MAAM,GAAG;QACL,GAAG,cAAc;QACjB,GAAG,MAAM;QACT,KAAK;QACL,MAAM;QACN,QAAQ,EAAE;YACN,QAAQ,EAAE,EAAE;YACZ,QAAQ,EAAE,eAAI,CAAC,OAAO,CAAC,MAAM,EAAE,wBAAwB,CAAC;YACxD,UAAU,EAAE,CAAC;YACb,UAAU,EAAE,IAAI;SACnB;KACJ,CAAA;IAGD,IAAI,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CACzC,IAAI,CAAC,KAAK,CAAE,IAAA,mBAAW,EAAE,eAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAC/F,IAAI,gBAAI,EAAE,CAAC,CAAA;IAEf,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,IAAI,MAAM,GAAG,EAAE,CAAA;IAEf,eAAe;IACf,IAAI,QAAQ,GAAU,EAAG,CAAA;IAEzB,cAAc;IACd,IAAI,KAAK,GAAG,MAAM,CAAC,WAAW,CAC1B,iBAAS,CAAC,GAAG,CAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,IAAI,GAAG,EAAU,EAAE,aAAa,EAAE,IAAI,GAAG,EAAU,EAAE,CAAC,CAAC,CACjH,CAAA;IAED,IAAI,OAAO,GAAG,IAAA,aAAG,EAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;IAIxD,SAAS,UAAU,CAAE,IAAY,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAkG;QAC9K,qEAAqE;QAErE,IAAI,GAAG,IAAI,IAAI,YAAY,CAAA;QAE3B,IAAI,CAAC,GAAG;YACJ,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;QAE/C,IAAI,CAAC,QAAQ,EAAE;YACX,KAAK,MAAM,QAAQ,IAAI,iBAAS;gBAC5B,UAAU,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;YACvD,OAAM;SACT;QAED,qEAAqE;QACrE,WAAW;QAEX,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAA;QAE5B,SAAS;QACT,MAAM,WAAW,GACb,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC;YACvB,QAAQ,KAAK,IAAI,IAAI,IAAI;YACzB,EAAE,CAAA;QAEN,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,OAAO;YAAE,OAAM;QAEzC,QAAQ,CAAC,GAAG,CAAC,GAAG;YACZ,GAAI,QAAQ,CAAC,GAAG,CAAC;YACjB,CAAC,QAAQ,CAAC,EAAE,WAAW;SAC1B,CAAA;QAED,IAAI,WAAW;YACX,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;;YAEzB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAE/B,IAAI,QAAQ,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;YACxC,UAAU,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,GAAG,SAAS,EAAE,OAAO,EAAE,CAAC,CAAA;IACrE,CAAC;IAGD,SAAS,cAAc,CAAE,KAAa,EAAE,IAAqB;QACzD,OAAO,IAAI,eAAK,CAAC;YACb,GAAG,EAAE,OAAO;YACZ,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,eAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;YACxC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;SACzF,CAAC,CAAA;IACN,CAAC;IAGD,4BAA4B;IAC5B,kBAAG;SACE,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QAEjD,iBAAiB;SAChB,IAAI,CACD,IAAA,oBAAG,EAAE,CAAC,IAAW,EAAE,EAAY,EAAE,KAAa,EAAE,EAAE;QAC9C,4BAA4B;QAC5B,IAAI,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;YAAE,OAAO,EAAE,EAAE,CAAA;QACvE,OAAO,EAAE,CAAA;QACT,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IAClB,CAAC,CAAC,CACL;QAED,qBAAqB;SACpB,IAAI,CAAE,IAAA,mBAAI,GAAE,CAAE;QAEf,WAAW;SACV,IAAI,CACD,yBAAY,CAAC,YAAY,CAAE,MAAM,EAAE,SAAS,SAAS,CAAyB,IAAW,EAAE,QAAgB,EAAE,QAAkB;QAC3H,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;QACvB,MAAM,GAAG,GAAG,eAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAEnC,UAAU;QACV,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YAC5B,QAAQ,EAAE,CAAA;YACV,OAAM;SACT;QAED,UAAU,EAAE,CAAA;QACZ,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAE,CAAC,GAAG,GAAG,UAAU,CAAC,GAAG,OAAO,CAAE,CAAA;QAC1D,MAAM,IAAI,GAAG,aAAa,OAAO,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAA;QACzD,OAAO,CAAC,IAAI,GAAG,IAAA,sBAAY,EAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,GAAG,CAAC,CAAA;QAEtF,IAAI,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAA;QAEnC,IAAI,GAAG,KAAK,MAAM;YACd,IAAI,GAAG,aAAG,CAAC,OAAO,CAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAS,CAAE,CAAC,QAAQ,EAAE,CAAA;QAG5G,8CAA8C;QAC9C,iFAAiF;QACjF,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,UAAU,CAAC,CAAA;QAElH,wCAAwC;QACxC,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,MAAM,EAAE;YAClC,iGAAiG;YACjG,IAAA,6CAAoC,EAAC,MAAM,CAAC,CAAA;YAC5C,MAAM,CAAC,2BAA2B,CAC9B,IAAI,EACJ,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,EACvB,UAAU,EACV,CAAC,KAAY,EAAE,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA,CAAC,CAAC,CAC3C,CAAA;SACJ;QAED,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;IAC3B,CAAC,CAAC,CACL;QAED,SAAS;SACR,IAAI,CACD,kBAAQ,CAAC,GAAG;IACR;;MAEE;IACF,SAAS,KAAK,CAAmB,IAAW,EAAE,QAAgB,EAAE,EAAY,IAAI,EAAE,EAAE,CAAA,CAAC,CAAC;IAEtF,+DAA+D;IAC/D,SAAS,KAAK,CAAmB,EAAY;QACzC,0BAA0B;QAC1B,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,YAAY,EACjC,MAAM,CAAC,WAAW,CACd,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAE,CAAC,CAAC,CAAC,EAAE,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC,EAAE,EAAE,CAC/D,CAAC,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAC/F,CACJ,CAAC,CAAA;QAGF,0BAA0B;QAC1B,MAAM,KAAK,GAAG,IAAI,oBAAQ,CAAC;YACvB,IAAI,EAAE;gBACF,UAAU;gBACV,cAAc,CAAC,GAAG;gBAClB,YAAY,CAAC,KAAK;aACrB;YACD,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;YAC/C,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;YACnB,KAAK,EAAE;gBACH,GAAG,EAAE,EAAE;gBACP,SAAS,EAAE,EAAE;gBACb,UAAU,EAAE,EAAE;gBACd,WAAW,EAAE,EAAE;gBACf,MAAM,EAAE,EAAE;gBACV,YAAY,EAAE,EAAE;gBAChB,aAAa,EAAE,EAAE;gBACjB,cAAc,EAAE,EAAE;gBAClB,IAAI,EAAE,EAAE;gBACR,UAAU,EAAE,EAAE;gBACd,GAAG,EAAE,EAAE;gBACP,SAAS,EAAE,EAAE;gBACb,KAAK,EAAE,EAAE;gBACT,WAAW,EAAE,EAAE;gBACf,MAAM,EAAE,GAAG;aACd;SACJ,CAAC,CAAA;QAEF,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;YAC5C,KAAK,CAAC,IAAI,CAAC;gBACP,IAAI;gBACJ,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,GAAG;gBACnC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK;aAC/B,CAAC,CAAA;QACb,CAAC,CAAC,CAAA;QAIF,OAAO,CAAC,IAAI,EAAE,CAAA;QACd,OAAO,CAAC,GAAG,CAAC,WAAW,OAAO,mBAAmB,MAAM,CAAC,MAAM,UAAU,CAAC,CAAA;QACzE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;QAG7B,kCAAkC;QAClC;;;;;;;;;;;;;;;;;;;;;;;;;UAyBE;QAEF,MAAM,gBAAgB,GAAG,KAAK,CAAC,EAAE,CAAC,aAAa,CAAA;QAC/C,IAAI,gBAAgB,CAAC,IAAI,EAAE;YACvB,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;YACjC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAE,YAAY,CAAC,EAAE;gBAC9D,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;YAC7B,CAAC,CAAC,CAAA;YACF,IAAI,gBAAgB,CAAC,IAAI,GAAG,EAAE,EAAE;gBAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;gBAClB,OAAO,CAAC,GAAG,CAAC,SAAS,gBAAgB,CAAC,IAAI,gBAAgB,CAAC,CAAA;aAC9D;SACJ;;YACG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAA;QAGzC,gCAAgC;QAChC,MAAM,WAAW,GAAG,eAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;QAChE,IAAI,CAAC,IAAI,CACL,cAAc,CAAC,WAAW,EAAE,QAAQ,CAAC,CACxC,CAAA;QAED,4BAA4B;QAC5B,MAAM,WAAW,GAAG,eAAI,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;QACrD,IAAI,CAAC,IAAI,CAAE,cAAc,CAAE,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAE,CAAC,CAAA;QAEpE,OAAO,CAAC,GAAG,CAAC,OAAO,YAAY,CAAC,MAAM,IAAI,WAAW,CAAC,SAAS,CAAC,IAAI,IAAI,WAAW,CAAC,MAAM,IAAI,WAAW,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAA;QAC3H,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,MAAM,CAAC,CAAA;QACvD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACjB,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,MAAM,CAAC,CAAA;QACtE,OAAO,CAAC,GAAG,CAAC,mFAAmF,CAAC,MAAM,CAAC,CAAA;QACvG,OAAO,CAAC,GAAG,EAAE,CAAA;QACb,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,MAAM,IAAI,wDAAwD,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAA;QAE9G,EAAE,EAAE,CAAA;IACR,CAAC,CACJ,CACJ;QAED,SAAS;SACR,IAAI,CACD,kBAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CACpB;SAEA,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;QACZ,MAAM,CAAC,OAAO,CAAE,YAAY,CAAC,EAAE,CAAC,YAAY,EAAE,CAAE,CAAA;QAChD,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAM;QAC1B,OAAO,CAAC,GAAG,CACP,uFAAuF,EACvF,EAAE,CAAC,IAAI,CAAC,SAAS,CACpB,CAAA;IACL,CAAC,CAAC,CAAA;AACV,CAAC;AAtSD,0BAsSC;AAED,kBAAe,OAAO,CAAA","sourcesContent":["import i18n_scanner from 'i18next-scanner'\nimport path from 'upath'\nimport ejs from 'ejs'\nimport vfs from 'vinyl-fs'\nimport map from 'map-stream'\nimport sort from 'gulp-sort'\nimport ora from 'ora'\nimport cli_truncate from 'cli-truncate'\nimport Vinyl from 'vinyl'\nimport through2 from 'through2'\nimport CliTable from 'cli-table3'\nimport type { Transform } from 'stream'\n\nimport { LANGUAGES } from '../index'\nimport type { Language } from '../index'\nimport Dict from '../rwdict'\nimport type { _Dict } from '../dict'\nimport { try_require } from '../utils'\n\nimport '../../prototype.js'\n\nimport { mix_parse_trans_from_string_by_babel } from './parser'\n\n\n\n/** 默认 i18next 扫描配置 */\nconst DEFAULT_CONFIG = {\n debug: false,\n \n input: [\n // 'src/**/*.{js,jsx,ts,tsx}',\n '!i18n/**', // Use ! to filter out files or directories\n '!node_modules/**',\n '!**/*.d.ts',\n ],\n \n // 相对于根目录\n output: 'i18n/',\n \n // 若是相对路径,则以 output 为基准进行解析\n dict: ['dict.json', 'scanneds.json'],\n \n lngs: ['zh', 'en', 'ja', 'ko'],\n ns: ['translation'],\n defaultLng: 'zh',\n defaultNs: 'translation',\n\n func: {\n list: [ 'i18next.t', 'i18n.t', 'i18n.__', 't', '__' ],\n extensions: [ ], // 避免在 transform 中执行原生的 parseFuncFromString\n },\n \n trans: {\n extensions: [ ], // 避免在 transform 中执行原生的 parseTransFromString\n fallbackKey: true,\n \n babylon: {\n sourceType: 'module',\n \n allowAwaitOutsideFunction: true,\n \n // https://babeljs.io/docs/en/babel-parser\n plugins: [\n // Language extensions\n 'jsx',\n 'typescript',\n \n // ECMAScript proposals\n 'classProperties',\n 'classPrivateProperties',\n 'classPrivateMethods',\n 'classStaticBlock',\n 'decimal',\n ['decorators', { decoratorsBeforeExport: true }],\n 'doExpressions',\n 'exportDefaultFrom',\n 'functionBind',\n 'importAssertions',\n 'moduleBlocks',\n 'moduleStringNames',\n 'partialApplication',\n ['pipelineOperator', { proposal: 'smart' }],\n 'privateIn',\n ['recordAndTuple', { syntaxType: 'bar' }],\n 'throwExpressions',\n 'topLevelAwait',\n ],\n } as import('@babel/parser').ParserOptions,\n \n // 实际并没有用到 acorn, 用了 babel\n acorn: {\n ecmaVersion: 'latest',\n sourceType: 'module', // defaults to 'module'\n // Check out https://github.com/acornjs/acorn/tree/master/acorn#interface for additional options\n }\n },\n \n // 禁用 : 和 . 作为 seperator\n keySeparator: false, // char to separate keys\n nsSeparator: false, // char to split namespace from key\n \n // Context Form\n context: true, // whether to add context form key\n contextFallback: true, // whether to add a fallback key as well as the context form key\n contextSeparator: '_', // char to split context from key\n\n // Plural\n // whether to add plural form key\n plural (language: string, ns: string, key: string, options: any /** Config */) {\n return language === 'en'\n }, \n pluralFallback: true, // whether to add a fallback key as well as the plural form key\n pluralSeparator: '_', // char to split plural from key\n \n // interpolation options\n interpolation: {\n prefix: '{{', // prefix for interpolation\n suffix: '}}' // suffix for interpolation\n }\n}\n\nconst VALID_EXTENTIONS = new Set(['.js', '.jsx', '.ts', '.tsx', '.ejs'])\n\nexport type Config = Partial<(typeof DEFAULT_CONFIG) & {\n defaultValue?: string\n resource?: { loadPath?: string, savePath?: string, jsonIndent?: number, lineEnding?: '\\n' }\n}>\n\n\n/** 扫描源码中的词条,以及收集未翻译的词条。生成 scanneds.json 和 untranslateds.json\n* rootdir 要扫描根目录 [ process.cwd() ]\n* config 配置信息\n*/\nexport function scanner (rootdir: string = path.normalize(process.cwd()), config: Config = { }) {\n const output = path.resolve(rootdir, config.output || DEFAULT_CONFIG.output)\n \n if (!config.input.length)\n throw new Error('运行 i18n-scan 请指定 --input')\n \n const input = [...config.input, ...DEFAULT_CONFIG.input]\n \n config = {\n ...DEFAULT_CONFIG,\n ...config,\n input,\n output,\n resource: {\n loadPath: '',\n savePath: path.resolve(output, 'translation/{{lng}}.js'),\n jsonIndent: 4,\n lineEnding: '\\n'\n }\n }\n \n \n let dict = config.dict.reduce( (dict, fp_dict) => \n dict.merge( try_require( path.resolve(output, fp_dict)), { print: false, overwrite: true }),\n new Dict())\n \n let c_files = 0\n let c_scanneds = 0\n let errors = []\n \n // 扫描出的词条及已有的翻译\n let scanneds: _Dict = { }\n \n // 所有语言的扫描统计信息\n let stats = Object.fromEntries(\n LANGUAGES.map( (language) => [language, { translateds: new Set<string>(), untranslateds: new Set<string>() }])\n )\n \n let spinner = ora({ interval: 66 }).start('Scanning...')\n \n \n \n function on_scanned (text: string, { language, key, defaultValue, count, context }: { language?: Language, key?: string, defaultValue?: string, count?: number, context?: string }) {\n // console.log(text, { language, key, defaultValue, count, context })\n \n text = text || defaultValue\n \n if (!key)\n key = context ? `${text}_${context}` : text\n \n if (!language) {\n for (const language of LANGUAGES)\n on_scanned(text, { language, key, count, context })\n return\n }\n \n // console.log(text, { language, key, defaultValue, count, context })\n // debugger\n \n const stat = stats[language]\n \n // 获取已有翻译\n const translation = \n dict.get(key, language) || \n language === 'zh' && text || \n ''\n \n if (language === 'zh' && !context) return\n \n scanneds[key] = {\n ... scanneds[key],\n [language]: translation\n }\n \n if (translation)\n stat.translateds.add(key)\n else\n stat.untranslateds.add(key)\n \n if (language === 'en' && count !== undefined)\n on_scanned(text, { language, key: `${key}_plural`, context })\n }\n \n \n function new_vinyl_file (_path: string, data: string | object) {\n return new Vinyl({\n cwd: rootdir,\n base: rootdir,\n path: path.resolve(config.output, _path),\n contents: Buffer.from(typeof data === 'string' ? data : JSON.stringify(data, null, 4))\n })\n }\n \n \n // ------------ scan by file\n vfs\n .src(config.input, { cwd: rootdir, sync: false })\n \n // 每个文件扫描前,统计文件数量\n .pipe(\n map( (file: Vinyl, cb: Function, count: number) => {\n // 支持 `// @i18n-noscan` 忽略扫描\n if (/\\/\\/\\s*@i18n-noscan\\s/.test(file.contents.toString())) return cb()\n c_files++\n cb(null, file)\n })\n )\n \n // 对文件进行排序,保证词条有一定的顺序\n .pipe( sort() )\n \n // 分析代码提取词条\n .pipe(\n i18n_scanner.createStream( config, function transform (this: { parser: any }, file: Vinyl, encoding: string, callback: Function): void {\n const { parser } = this\n const ext = path.extname(file.path)\n \n // 只扫描源码文件\n if (!VALID_EXTENTIONS.has(ext)) {\n callback()\n return\n }\n \n c_scanneds++\n const percent = Math.round( (100 * c_scanneds) / c_files )\n const text = `Scanning (${percent}%): ${file.path.green}`\n spinner.text = cli_truncate(text, process.stdout.columns - 5, { position: 'middle', })\n \n let code = file.contents.toString()\n \n if (ext === '.ejs')\n code = ejs.compile( code, { filename: file.path, client: true, legacyInclude: true } as any ).toString()\n \n \n // --- 添加代码中扫描到的 i18n.t('key') 中的 key 到 parser\n // parser.parseFuncFromString 使用 esprima 来解析代码,esprima 仍然不支持 optional chaining !!\n parser.parseFuncFromString(code.replace(/\\?\\.\\[/g, '[').replace(/\\?\\.\\(/g, '(').replace(/\\?\\./g, '.'), on_scanned)\n \n // --- 添加代码中扫描到的 Trans 组件中的 key 到 parser\n if (ext === '.jsx' || ext === '.tsx') {\n // parser.parseTransFromString 使用 acorn 解析代码,不支持 TypeScript,添加 parser.parseTransFromStringByBabel\n mix_parse_trans_from_string_by_babel(parser)\n parser.parseTransFromStringByBabel(\n code,\n { filepath: file.path },\n on_scanned,\n (error: Error) => { errors.push(error) }\n )\n }\n \n setTimeout(callback, 0)\n })\n )\n \n // 创建词条文件\n .pipe(\n through2.obj(\n /** i18n-scanner 会把扫描结果以每个语言一个文件的形式提供,这里解析扫描结果\n * file: 翻译 resource 文件,其中 file.contents 包含翻译的扫描结果\n */\n function write (this: Transform, file: Vinyl, encoding: string, cb: Function) { cb() },\n \n /** 生成 stats.json, unmarkeds.md; 打印 untranslated / unmarkeds */\n function flush (this: Transform, cb: Function) {\n // ------------ stats.json\n this.push(new_vinyl_file('stats.json', \n Object.fromEntries(\n Object.entries(stats).map( ([l, { translateds, untranslateds }]) => \n [l, { translateds: Array.from(translateds), untranslateds: Array.from(untranslateds) }])\n )\n ))\n \n \n // ------------ 打印 cli 统计表\n const table = new CliTable({\n head: [\n 'Language',\n 'Untranslated'.red,\n 'Translated'.green,\n ],\n colAligns: ['right', 'right', 'right', 'right'],\n style: { head: [] },\n chars: {\n top: '',\n 'top-mid': '',\n 'top-left': '',\n 'top-right': '',\n bottom: '',\n 'bottom-mid': '',\n 'bottom-left': '',\n 'bottom-right': '',\n left: '',\n 'left-mid': '',\n mid: '',\n 'mid-mid': '',\n right: '',\n 'right-mid': '',\n middle: ' ',\n },\n })\n \n Object.entries(stats).forEach( ([lang, stat]) => {\n table.push([\n lang, \n String(stat.untranslateds.size).red, \n String(stat.translateds.size).green\n ] as any)\n })\n \n \n \n spinner.stop()\n console.log(`Scanned ${c_files} files. Occured ${errors.length} errors.`)\n console.log(table.toString())\n \n \n // ------------ 生成 unmarkeds.md 统计\n /*\n const fp_unmarked = path.resolve(config.output, 'unmarkeds.md')\n \n if (fs.existsSync(fp_unmarked))\n rimraf.sync(fp_unmarked)\n \n if (unmarkeds.length) {\n console.log(colors.yellow(`\\n⚠️ 发现未标记的中文字符 ${unmarkeds.length} 处:\\n`))\n unmarkeds.forEach(({ value, filepath, loc: { start } }, index) => {\n if (index >= 5) return\n console.log( ` ${colors.white(`'${value}'`)}\\t${colors.blue.underline(`${path.relative(rootdir, filepath)}:${start.line}:${start.column + 1}`)}` )\n })\n }\n \n this.push( new_vinyl_file( fp_unmarked, \n unmarkeds.map( ({ value, filepath, loc }) =>\n '- [' + value.trim() + '](' + path.relative( config.output, path.resolve(rootdir, filepath || '') ) + '#L' + loc.start.line + ')'\n ).join('\\n') + '\\n'\n ))\n \n \n if (unmarkeds.length > 5) {\n console.log(' ...')\n console.log(colors.yellow(`\\n 完整未标记词条请查看 ${colors.blue.underline(path.relative(rootdir, fp_unmarked))}`))\n }\n */\n \n const en_untranslateds = stats.en.untranslateds\n if (en_untranslateds.size) {\n console.log('\\n未翻译的英文词条:'.yellow)\n Array.from(en_untranslateds).slice(0, 10).forEach( untranslated => {\n console.log(untranslated)\n })\n if (en_untranslateds.size > 10) {\n console.log('...')\n console.log(`--- 共 ${en_untranslateds.size} 个未翻译的英文词条 ---`)\n }\n } else\n console.log('\\n所有词条都至少含有英文翻译.'.green)\n \n \n // ------------ 生成 scanneds.json\n const fp_scanneds = path.resolve(config.output, 'scanneds.json')\n this.push(\n new_vinyl_file(fp_scanneds, scanneds)\n )\n \n // ------------ 写入 dict.json\n const fp_dict_new = path.resolve(output, 'dict.json')\n this.push( new_vinyl_file( fp_dict_new, dict.to_json(true) + '\\n' ))\n \n console.log(`\\n\\n${'⚠️ 请检查扫描结果'.yellow} ${fp_scanneds.underline.blue} ${'和新生成的词典文件'.yellow} ${fp_dict_new.underline.blue}`)\n console.log('\\n请手动补全扫描结果 scanneds.json 中未翻译的词条'.yellow)\n console.log('\\n')\n console.log('通过以上方法补充翻译后重新运行扫描,会根据 scanneds.json 更新 dict.json'.yellow)\n console.log('最后 dict.json 所包含的词条会被打包进 js, 通过 new I18N(<dict.json>) 或 i18n.init(<dict.json>) 加载'.yellow)\n console.log()\n console.log(`${'详细文档请查看:'.yellow} ${'https://github.com/ShenHongFei/xshell/tree/master/i18n'.blue.underline}`)\n \n cb()\n }\n )\n )\n \n // 写入词条文件\n .pipe(\n vfs.dest(rootdir)\n )\n \n .on('end', () => {\n errors.forEach( errorHandler => errorHandler() )\n if (!errors.length) return\n console.log(\n 'https://www.i18next.com/translation-function/essentials\\n以上错误可能是由不规范的词条标记导致,标记规范可见:%s',\n ''.blue.underline\n )\n })\n}\n\nexport default scanner\n"]}
package/myfont.sass CHANGED
@@ -9,3 +9,6 @@
9
9
 
10
10
  html
11
11
  font-family: 'MyFont', sans-serif
12
+
13
+ body
14
+ font-family: 'MyFont', sans-serif
package/net.d.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="cheerio" />
3
- import request_lib from 'request';
4
- import request_promise from 'request-promise-native';
3
+ import { default as request_lib } from 'request';
4
+ import { default as request_promise } from 'request-promise-native';
5
5
  import { Cookie, MemoryCookieStore } from 'tough-cookie';
6
6
  declare module 'tough-cookie' {
7
7
  interface MemoryCookieStore {
8
8
  idx: Record<string, any>;
9
9
  }
10
10
  }
11
- import './prototype';
12
- import type { Encoding } from './file';
11
+ import './prototype.js';
12
+ import type { Encoding } from './file.js';
13
13
  export declare enum MyProxy {
14
14
  socks5 = "http://localhost:10080",
15
15
  whistle = "http://localhost:8899"
package/net.js CHANGED
@@ -3,15 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.rpc_curl = exports.rpc = exports.to_curl = exports.request_page = exports.parse_html = exports.request_json = exports.request = exports.request_retry = exports._request = exports.Cookie = exports.cookies = exports.MyProxy = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const request_promise_native_1 = (0, tslib_1.__importDefault)(require("request-promise-native"));
6
- const errors_1 = require("request-promise-native/errors");
6
+ const errors_js_1 = require("request-promise-native/errors.js");
7
7
  const promise_retry_1 = (0, tslib_1.__importDefault)(require("promise-retry"));
8
8
  const iconv_lite_1 = (0, tslib_1.__importDefault)(require("iconv-lite"));
9
9
  const cheerio_1 = (0, tslib_1.__importDefault)(require("cheerio"));
10
10
  const qs_1 = (0, tslib_1.__importDefault)(require("qs"));
11
11
  const tough_cookie_1 = require("tough-cookie");
12
12
  Object.defineProperty(exports, "Cookie", { enumerable: true, get: function () { return tough_cookie_1.Cookie; } });
13
- require("./prototype");
14
- const utils_1 = require("./utils");
13
+ require("./prototype.js");
14
+ const utils_js_1 = require("./utils.js");
15
15
  var MyProxy;
16
16
  (function (MyProxy) {
17
17
  MyProxy["socks5"] = "http://localhost:10080";
@@ -124,36 +124,36 @@ async function request(url, { queries, body, type = 'application/json', proxy, m
124
124
  else
125
125
  resp = await (0, exports._request)(options);
126
126
  if (!(200 <= resp.statusCode && resp.statusCode <= 299))
127
- throw new errors_1.StatusCodeError(resp.statusCode, resp.body, options, resp);
127
+ throw new errors_js_1.StatusCodeError(resp.statusCode, resp.body, options, resp);
128
128
  }
129
129
  catch (error) {
130
130
  const { name, options: { method, url, uri, qs }, response, } = error;
131
- error[utils_1.inspect.custom] = () => {
132
- let s = '─'.repeat(utils_1.output_width / 2) + '\n' +
131
+ error[utils_js_1.inspect.custom] = () => {
132
+ let s = '─'.repeat(utils_js_1.output_width / 2) + '\n' +
133
133
  `${(method || 'get').toLowerCase().red} ${String(url || uri).blue.underline}\n`;
134
134
  if (qs)
135
135
  s += `\n${'request.query:'.blue}\n` +
136
- (0, utils_1.inspect)(qs) + '\n';
136
+ (0, utils_js_1.inspect)(qs) + '\n';
137
137
  if (_body)
138
138
  s += `\n${'request.body:'.blue}\n` +
139
- (0, utils_1.inspect)(body) + '\n';
139
+ (0, utils_js_1.inspect)(body) + '\n';
140
140
  if (name === 'StatusCodeError')
141
141
  s += `\n${'response.status:'.yellow} ${String(error.statusCode).red}\n`;
142
- else if (error instanceof errors_1.RequestError)
142
+ else if (error instanceof errors_js_1.RequestError)
143
143
  s += `\n${'response.cause:'.yellow}\n` +
144
- `${(0, utils_1.inspect)(error.cause)}\n`;
144
+ `${(0, utils_js_1.inspect)(error.cause)}\n`;
145
145
  else
146
- s += `\n${(0, utils_1.inspect)(error)}\n`;
146
+ s += `\n${(0, utils_js_1.inspect)(error)}\n`;
147
147
  if (response) {
148
148
  s += `\n${'response.headers:'.yellow}\n` +
149
- `${(0, utils_1.inspect)(response.headers)}\n`;
149
+ `${(0, utils_js_1.inspect)(response.headers)}\n`;
150
150
  if (response.body)
151
151
  s += `\n${'response.body:'.yellow}\n` +
152
- `${(0, utils_1.inspect)(response.body.toString())}\n`;
152
+ `${(0, utils_js_1.inspect)(response.body.toString())}\n`;
153
153
  }
154
154
  s += `\n${'stack:'.yellow}\n` +
155
155
  `${new Error().stack}\n` +
156
- '─'.repeat(utils_1.output_width / 2);
156
+ '─'.repeat(utils_js_1.output_width / 2);
157
157
  return s;
158
158
  };
159
159
  throw error;
@@ -188,14 +188,14 @@ exports.request_json = request_json;
188
188
  /** use $.html(cheerio_element) to get outer html */
189
189
  function parse_html(html) {
190
190
  let $ = cheerio_1.default.load(html, { decodeEntities: false });
191
- Object.defineProperty($, utils_1.inspect.custom, {
191
+ Object.defineProperty($, utils_js_1.inspect.custom, {
192
192
  configurable: true,
193
193
  enumerable: false,
194
194
  value() {
195
195
  return this.html();
196
196
  }
197
197
  });
198
- Object.defineProperty($.prototype, utils_1.inspect.custom, {
198
+ Object.defineProperty($.prototype, utils_js_1.inspect.custom, {
199
199
  configurable: true,
200
200
  enumerable: false,
201
201
  value() {
package/net.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"net.js","sourceRoot":"","sources":["net.ts"],"names":[],"mappings":"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","sourcesContent":["import request_lib from 'request'\nimport type { OptionsWithUri, OptionsWithUrl } from 'request'\n\nimport request_promise from 'request-promise-native'\nimport type { FullResponse } from 'request-promise-native'\nimport { RequestError, StatusCodeError } from 'request-promise-native/errors'\n\nimport promise_retry from 'promise-retry'\n\nimport iconv from 'iconv-lite'\nimport cheerio from 'cheerio'\nimport qs from 'qs'\nimport { Cookie, MemoryCookieStore } from 'tough-cookie'\n\ndeclare module 'tough-cookie' {\n interface MemoryCookieStore {\n idx: Record<string, any>\n }\n}\n\n\nimport './prototype'\nimport type { Encoding } from './file'\nimport { inspect, output_width } from './utils'\n\nexport enum MyProxy {\n socks5 = 'http://localhost:10080',\n whistle = 'http://localhost:8899',\n}\n\n\n// ------------------------------------ Fetch, Request\nconst cookie_store = new MemoryCookieStore()\n\nexport const cookies = {\n store: cookie_store,\n \n jar: request_promise.jar(cookie_store),\n \n get (domain_or_url: string, str = false) {\n if (domain_or_url.startsWith('http'))\n if (str)\n return this.jar.getCookieString(domain_or_url)\n else\n return this.jar.getCookies(domain_or_url)\n \n let cookies: Cookie[]\n this.store.findCookies(domain_or_url, null, true, (error, _cookies) => {\n if (error) throw error\n cookies = _cookies\n })\n return cookies\n },\n}\n\nexport { Cookie }\n\n\nexport const _request = request_promise.defaults({\n rejectUnauthorized: false,\n gzip: true,\n /** prevent 302 redirect cause error, which is a boolean to set whether status codes other than 2xx should also reject the promise */\n simple: false,\n \n jar: cookies.jar\n})\n\n\nexport async function request_retry (retries: number, request_options: request_promise.OptionsWithUrl) {\n return promise_retry<FullResponse>({\n retries,\n minTimeout: 1000,\n maxTimeout: Infinity,\n factor: 2\n }, async (retry, count) => {\n try {\n return await _request(request_options)\n } catch (error) {\n if (!['ECONNRESET', 'ETIMEDOUT', 'ESOCKETTIMEDOUT'].includes(error.cause?.code)) throw error\n if (count <= retries)\n console.log(`${`retry (${count}) …`.yellow} ${request_options.url.toString().blue.underline}`)\n return retry(error)\n }\n })\n}\n\n\nexport interface RequestOptions {\n method?: 'get' | 'post' | 'put' | 'head' | 'delete' | 'patch'\n \n queries?: Record<string, any>\n \n headers?: Record<string, string>\n \n body?: string | Record<string, any>\n \n type?: 'application/json' | 'application/x-www-form-urlencoded' | 'multipart/form-data'\n \n \n proxy?: boolean | MyProxy | string\n \n encoding?: Encoding\n \n retries?: true | number\n \n timeout?: number\n \n auth?: {\n username: string\n password: string\n }\n \n gzip?: boolean\n \n cookies?: Record<string, string>\n}\n\nexport interface RequestRawOptions extends RequestOptions {\n raw: true\n}\n\n/** \n - url: must be full url\n - options:\n - raw: `false` 传入后返回整个 response\n - encoding: `(response content-type: charset=gb18030) || 'utf-8'` when 'binary' then return buffer\n - type: `'application/json'` request content-type header (if has body)\n - proxy: `false` proxy === true then use MyProxy.whistle\n - retries: `false` could be true (default 3 times) or retry times\n - timeout: `20 * 1000`\n - gzip: `raw -> false; else -> true`\n*/\nexport async function request (url: string | URL): Promise<string>\nexport async function request (url: string | URL, options: RequestRawOptions): Promise<request_lib.Response>\nexport async function request (url: string | URL, options: RequestOptions & { encoding: 'binary' }): Promise<Buffer>\nexport async function request (url: string | URL, options: RequestOptions): Promise<string>\nexport async function request (url: string | URL, {\n queries,\n \n body,\n \n type = 'application/json',\n \n proxy,\n \n method,\n \n headers,\n \n encoding,\n \n raw = false,\n \n retries,\n \n timeout = 20 * 1000,\n \n auth,\n \n gzip,\n \n cookies,\n \n}: RequestOptions & { raw?: boolean } = { }) {\n url = url.toString()\n \n if (!url.startsWith('http'))\n url = 'http://' + url\n \n const _body = body // for error log\n \n if (body && !method)\n method = 'post'\n \n if (type === 'application/json' && typeof body !== 'undefined' && (typeof body !== 'string' && !Buffer.isBuffer(body)))\n body = JSON.stringify(body)\n \n // --- proxy\n if (proxy) {\n if (proxy === true)\n proxy = MyProxy.whistle\n } else\n proxy = false\n \n // --- gzip\n if (gzip === undefined)\n gzip = !raw\n \n \n const options: request_lib.Options & { resolveWithFullResponse: boolean } = {\n url,\n \n ... method ? { method: method.toUpperCase() } : { },\n \n proxy,\n \n gzip,\n \n encoding: null,\n \n resolveWithFullResponse: true,\n \n headers: {\n 'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,ja-JP;q=0.6,ja;q=0.5',\n 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36',\n ... body ? { 'content-type': type } : { }, \n ... cookies ? {\n cookie: Object.entries(cookies)\n .map(([key, value]) => \n `${encodeURIComponent(key)}=${encodeURIComponent(value)}`\n ).join('; ')\n } : { },\n ... headers\n },\n \n ... queries ? { qs: queries } : { },\n \n // --- body\n ... (() => {\n if (!body) return { }\n if (type === 'application/x-www-form-urlencoded') return { form: body }\n if (type === 'multipart/form-data') return { formData: body as Record<string, any> }\n return { body }\n })(),\n \n ... timeout ? { timeout } : { },\n \n ... auth ? { auth } : { },\n }\n \n let resp: request_lib.Response\n \n try {\n if (retries) {\n if (retries === true)\n retries = 3\n \n resp = await request_retry(retries, options)\n } else\n resp = await _request(options)\n \n if (!(200 <= resp.statusCode && resp.statusCode <= 299))\n throw new StatusCodeError(resp.statusCode, resp.body, options, resp)\n \n } catch (error) {\n const {\n name, \n options: { method, url, uri, qs }, \n response,\n }: {\n options: OptionsWithUri & OptionsWithUrl\n response: FullResponse\n } & Error = error\n \n error[inspect.custom] = () => {\n let s = '─'.repeat(output_width / 2) + '\\n' +\n `${(method || 'get').toLowerCase().red} ${String(url || uri).blue.underline}\\n`\n \n if (qs)\n s += `\\n${'request.query:'.blue}\\n` +\n inspect(qs) + '\\n'\n \n if (_body)\n s += `\\n${'request.body:'.blue}\\n` +\n inspect(body) + '\\n'\n \n if (name === 'StatusCodeError')\n s += `\\n${'response.status:'.yellow} ${String(error.statusCode).red}\\n`\n else if (error instanceof RequestError)\n s += `\\n${'response.cause:'.yellow}\\n` +\n `${inspect(error.cause)}\\n`\n else\n s += `\\n${inspect(error)}\\n`\n \n if (response) {\n s += `\\n${'response.headers:'.yellow}\\n` + \n `${inspect(response.headers)}\\n`\n \n if (response.body)\n s += `\\n${'response.body:'.yellow}\\n` +\n `${inspect(response.body.toString())}\\n`\n }\n \n s += `\\n${'stack:'.yellow}\\n` +\n `${new Error().stack}\\n` +\n '─'.repeat(output_width / 2)\n \n return s\n }\n \n throw error\n }\n \n if (raw)\n return resp\n \n if (!resp.body)\n return resp.body\n \n // --- decode body\n if (encoding === 'binary')\n return resp.body\n \n encoding ||= /charset=(.*)/.exec(resp.headers['content-type'])?.[1] as Encoding || 'utf-8'\n \n if (/utf-?8/i.test(encoding))\n return (resp.body as Buffer).toString('utf-8')\n \n return iconv.decode((resp.body as Buffer), encoding)\n}\n\n\n/** make http request and parse body as json */\nexport async function request_json <T = any> (url: string | URL, options?: RequestOptions): Promise<T> {\n const resp = await request(url, options)\n if (!resp) return\n try {\n return JSON.parse(resp)\n } catch (error) {\n console.log(resp)\n throw error\n }\n}\n\n\n/** use $.html(cheerio_element) to get outer html */\nexport function parse_html (html: string) {\n let $ = cheerio.load(html, { decodeEntities: false })\n \n Object.defineProperty($, inspect.custom, {\n configurable: true,\n enumerable: false,\n value () {\n return this.html()\n }\n })\n \n Object.defineProperty($.prototype, inspect.custom, {\n configurable: true,\n enumerable: false,\n value (this: cheerio.Cheerio) {\n if (this.length > 1)\n return this.map((index, element) => {\n if (typeof element === 'string') return element\n return $.html(element)\n }).get().join_lines()\n \n return this.toString()\n }\n })\n \n return $\n}\n\n\n/** use $.html(cheerio_element) to get outer html */\nexport async function request_page (url: string | URL, options?: RequestOptions) {\n return parse_html(\n await request(url, options)\n )\n}\n\n\nexport function to_curl (url: string | URL, { queries, headers, method, body, proxy, exe = true }: RequestOptions & { exe?: boolean } = { }) {\n if (proxy === true)\n proxy = process.env.http_proxy\n \n url = url.toString()\n \n if (!url.startsWith('http'))\n url = `http://${url}`\n \n return (exe ? 'curl.exe' : 'curl') + \n ' ' + ( url + (queries ? '?' : '') + qs.stringify(queries) ).quote() +\n // ( typeof proxy === 'undefined' ?\n // ''\n // :\n // ( proxy ? ' --proxy ' + proxy.quote() : ' --noproxy ' + '*'.quote())\n // ) +\n ( proxy ? ` --proxy ${proxy.quote()}` : '' ) +\n ( method && method !== 'get' ? ` -X ${method}` : '' ) +\n ( headers ? Object.entries(headers).map( ([key, value]) => ' -H ' + `${key}: ${value}`.quote() ).join('') : '' ) +\n ( body ? ' -H ' + 'content-type: application/json'.quote() : '') +\n ( body ? ' --data ' + JSON.stringify(body).quote() : '')\n}\n\n\n\n\n// ------------------------------------ rpc client\n/** post json to http://localhost:8421/api/rpc\n - func: function name\n - args?: argument array\n - options?:\n - ignore?: `false` wait for execution but do not serialize result to response\n - async?: `false` do not wait for exec\n*/\nexport async function rpc (\n func: string, \n args?: any[], \n { url = 'http://localhost:8421/api/rpc', async: _async = false, ignore = false }: { url?: string, async?: boolean, ignore?: boolean } = { }\n) {\n if (!func) throw new Error('rpc argument error: no func')\n \n return request_json(url, {\n body: {\n func,\n args,\n async: _async,\n ignore,\n }\n })\n}\n\n\nexport function rpc_curl (func: string, args: any[]) {\n const cmd = args.find( arg => typeof arg === 'object') ?\n to_curl('http://localhost:8421/api/rpc', { body: { func, args } })\n :\n to_curl('http://localhost:8421/api/rpc', { queries: { func, args } })\n return cmd\n}\n\n"]}
1
+ {"version":3,"file":"net.js","sourceRoot":"","sources":["net.ts"],"names":[],"mappings":";;;;AAMA,iGAG+B;AAC/B,gEAAgF;AAEhF,+EAAyC;AAEzC,yEAA8B;AAC9B,mEAA6B;AAC7B,yDAAmB;AACnB,+CAAwD;AA2C/C,uFA3CA,qBAAM,OA2CA;AAlCf,0BAAuB;AAEvB,yCAAkD;AAElD,IAAY,OAGX;AAHD,WAAY,OAAO;IACf,4CAAiC,CAAA;IACjC,4CAAiC,CAAA;AACrC,CAAC,EAHW,OAAO,GAAP,eAAO,KAAP,eAAO,QAGlB;AAGD,sDAAsD;AACtD,MAAM,YAAY,GAAG,IAAI,gCAAiB,EAAE,CAAA;AAE/B,QAAA,OAAO,GAAG;IACnB,KAAK,EAAE,YAAY;IAEnB,GAAG,EAAE,gCAAe,CAAC,GAAG,CAAC,YAAY,CAAC;IAEtC,GAAG,CAAE,aAAqB,EAAE,GAAG,GAAG,KAAK;QACnC,IAAI,aAAa,CAAC,UAAU,CAAC,MAAM,CAAC;YAChC,IAAI,GAAG;gBACH,OAAO,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,aAAa,CAAC,CAAA;;gBAE9C,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,CAAA;QAEjD,IAAI,OAAiB,CAAA;QACrB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;YAClE,IAAI,KAAK;gBAAE,MAAM,KAAK,CAAA;YACtB,OAAO,GAAG,QAAQ,CAAA;QACtB,CAAC,CAAC,CAAA;QACF,OAAO,OAAO,CAAA;IAClB,CAAC;CACJ,CAAA;AAKY,QAAA,QAAQ,GAAG,gCAAe,CAAC,QAAQ,CAAC;IAC7C,kBAAkB,EAAE,KAAK;IACzB,IAAI,EAAE,IAAI;IACV,qIAAqI;IACrI,MAAM,EAAE,KAAK;IAEb,GAAG,EAAE,eAAO,CAAC,GAAG;CACnB,CAAC,CAAA;AAGK,KAAK,UAAU,aAAa,CAAE,OAAe,EAAE,eAA+C;IACjG,OAAO,IAAA,uBAAa,EAAe;QAC/B,OAAO;QACP,UAAU,EAAE,IAAI;QAChB,UAAU,EAAE,QAAQ;QACpB,MAAM,EAAE,CAAC;KACZ,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QACtB,IAAI;YACA,OAAO,MAAM,IAAA,gBAAQ,EAAC,eAAe,CAAC,CAAA;SACzC;QAAC,OAAO,KAAK,EAAE;YACZ,IAAI,CAAC,CAAC,YAAY,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC;gBAAE,MAAM,KAAK,CAAA;YAC5F,IAAI,KAAK,IAAI,OAAO;gBAChB,OAAO,CAAC,GAAG,CAAC,GAAG,UAAU,KAAK,KAAK,CAAC,MAAM,IAAI,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAA;YAClG,OAAO,KAAK,CAAC,KAAK,CAAC,CAAA;SACtB;IACL,CAAC,CAAC,CAAA;AACN,CAAC;AAhBD,sCAgBC;AAoDM,KAAK,UAAU,OAAO,CAAE,GAAiB,EAAE,EAC9C,OAAO,EAEP,IAAI,EAEJ,IAAI,GAAG,kBAAkB,EAEzB,KAAK,EAEL,MAAM,EAEN,OAAO,EAEP,QAAQ,EAER,GAAG,GAAG,KAAK,EAEX,OAAO,EAEP,OAAO,GAAG,EAAE,GAAG,IAAI,EAEnB,IAAI,EAEJ,IAAI,EAEJ,OAAO,MAE6B,EAAG;IACvC,GAAG,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAA;IAEpB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;QACvB,GAAG,GAAG,SAAS,GAAG,GAAG,CAAA;IAEzB,MAAM,KAAK,GAAG,IAAI,CAAA,CAAE,gBAAgB;IAEpC,IAAI,IAAI,IAAI,CAAC,MAAM;QACf,MAAM,GAAG,MAAM,CAAA;IAEnB,IAAI,IAAI,KAAK,kBAAkB,IAAI,OAAO,IAAI,KAAK,WAAW,IAAI,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAClH,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IAE/B,YAAY;IACZ,IAAI,KAAK,EAAE;QACP,IAAI,KAAK,KAAK,IAAI;YACd,KAAK,GAAG,OAAO,CAAC,OAAO,CAAA;KAC9B;;QACG,KAAK,GAAG,KAAK,CAAA;IAEjB,WAAW;IACX,IAAI,IAAI,KAAK,SAAS;QAClB,IAAI,GAAG,CAAC,GAAG,CAAA;IAGf,MAAM,OAAO,GAA+D;QACxE,GAAG;QAEH,GAAI,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,EAAG;QAEnD,KAAK;QAEL,IAAI;QAEJ,QAAQ,EAAE,IAAI;QAEd,uBAAuB,EAAE,IAAI;QAE7B,OAAO,EAAE;YACL,iBAAiB,EAAE,0DAA0D;YAC7E,YAAY,EAAE,oHAAoH;YAClI,GAAI,IAAI,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAG;YACzC,GAAI,OAAO,CAAC,CAAC,CAAC;gBACV,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;qBAC1B,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAClB,GAAG,kBAAkB,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAC5D,CAAC,IAAI,CAAC,IAAI,CAAC;aACnB,CAAC,CAAC,CAAC,EAAG;YACP,GAAI,OAAO;SACd;QAED,GAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAG;QAEnC,WAAW;QACX,GAAI,CAAC,GAAG,EAAE;YACN,IAAI,CAAC,IAAI;gBAAE,OAAO,EAAG,CAAA;YACrB,IAAI,IAAI,KAAK,mCAAmC;gBAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;YACvE,IAAI,IAAI,KAAK,qBAAqB;gBAAE,OAAO,EAAE,QAAQ,EAAE,IAA2B,EAAE,CAAA;YACpF,OAAO,EAAE,IAAI,EAAE,CAAA;QACnB,CAAC,CAAC,EAAE;QAEJ,GAAI,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAG;QAE/B,GAAI,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAG;KAC5B,CAAA;IAED,IAAI,IAA0B,CAAA;IAE9B,IAAI;QACA,IAAI,OAAO,EAAE;YACT,IAAI,OAAO,KAAK,IAAI;gBAChB,OAAO,GAAG,CAAC,CAAA;YAEf,IAAI,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;SAC/C;;YACG,IAAI,GAAG,MAAM,IAAA,gBAAQ,EAAC,OAAO,CAAC,CAAA;QAElC,IAAI,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,IAAI,GAAG,CAAC;YACnD,MAAM,IAAI,2BAAe,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;KAE3E;IAAC,OAAO,KAAK,EAAE;QACZ,MAAM,EACF,IAAI,EACJ,OAAO,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EACjC,QAAQ,GACX,GAGW,KAAK,CAAA;QAEjB,KAAK,CAAC,kBAAO,CAAC,MAAM,CAAC,GAAG,GAAG,EAAE;YACzB,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,uBAAY,GAAG,CAAC,CAAC,GAAG,IAAI;gBACvC,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,CAAA;YAEnF,IAAI,EAAE;gBACF,CAAC,IAAI,KAAK,gBAAgB,CAAC,IAAI,IAAI;oBAC/B,IAAA,kBAAO,EAAC,EAAE,CAAC,GAAG,IAAI,CAAA;YAE1B,IAAI,KAAK;gBACL,CAAC,IAAI,KAAK,eAAe,CAAC,IAAI,IAAI;oBAC9B,IAAA,kBAAO,EAAC,IAAI,CAAC,GAAG,IAAI,CAAA;YAE5B,IAAI,IAAI,KAAK,iBAAiB;gBAC1B,CAAC,IAAI,KAAK,kBAAkB,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,IAAI,CAAA;iBACtE,IAAI,KAAK,YAAY,wBAAY;gBAClC,CAAC,IAAI,KAAK,iBAAiB,CAAC,MAAM,IAAI;oBAClC,GAAG,IAAA,kBAAO,EAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAA;;gBAE/B,CAAC,IAAI,KAAK,IAAA,kBAAO,EAAC,KAAK,CAAC,IAAI,CAAA;YAEhC,IAAI,QAAQ,EAAE;gBACV,CAAC,IAAI,KAAK,mBAAmB,CAAC,MAAM,IAAI;oBACpC,GAAG,IAAA,kBAAO,EAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAA;gBAEpC,IAAI,QAAQ,CAAC,IAAI;oBACb,CAAC,IAAI,KAAK,gBAAgB,CAAC,MAAM,IAAI;wBACjC,GAAG,IAAA,kBAAO,EAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAA;aACnD;YAED,CAAC,IAAI,KAAK,QAAQ,CAAC,MAAM,IAAI;gBACzB,GAAG,IAAI,KAAK,EAAE,CAAC,KAAK,IAAI;gBACxB,GAAG,CAAC,MAAM,CAAC,uBAAY,GAAG,CAAC,CAAC,CAAA;YAEhC,OAAO,CAAC,CAAA;QACZ,CAAC,CAAA;QAED,MAAM,KAAK,CAAA;KACd;IAED,IAAI,GAAG;QACH,OAAO,IAAI,CAAA;IAEf,IAAI,CAAC,IAAI,CAAC,IAAI;QACV,OAAO,IAAI,CAAC,IAAI,CAAA;IAEpB,kBAAkB;IAClB,IAAI,QAAQ,KAAK,QAAQ;QACrB,OAAO,IAAI,CAAC,IAAI,CAAA;IAEpB,QAAQ,KAAR,QAAQ,GAAK,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAa,IAAI,OAAO,EAAA;IAE1F,IAAI,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;QACxB,OAAQ,IAAI,CAAC,IAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IAElD,OAAO,oBAAK,CAAC,MAAM,CAAE,IAAI,CAAC,IAAe,EAAE,QAAQ,CAAC,CAAA;AACxD,CAAC;AA7KD,0BA6KC;AAGD,+CAA+C;AACxC,KAAK,UAAU,YAAY,CAAY,GAAiB,EAAE,OAAwB;IACrF,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IACxC,IAAI,CAAC,IAAI;QAAE,OAAM;IACjB,IAAI;QACA,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;KAC1B;IAAC,OAAO,KAAK,EAAE;QACZ,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACjB,MAAM,KAAK,CAAA;KACd;AACL,CAAC;AATD,oCASC;AAGD,oDAAoD;AACpD,SAAgB,UAAU,CAAE,IAAY;IACpC,IAAI,CAAC,GAAG,iBAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAA;IAErD,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,kBAAO,CAAC,MAAM,EAAE;QACrC,YAAY,EAAE,IAAI;QAClB,UAAU,EAAE,KAAK;QACjB,KAAK;YACD,OAAO,IAAI,CAAC,IAAI,EAAE,CAAA;QACtB,CAAC;KACJ,CAAC,CAAA;IAEF,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,EAAE,kBAAO,CAAC,MAAM,EAAE;QAC/C,YAAY,EAAE,IAAI;QAClB,UAAU,EAAE,KAAK;QACjB,KAAK;YACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;gBACf,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;oBAC/B,IAAI,OAAO,OAAO,KAAK,QAAQ;wBAAE,OAAO,OAAO,CAAA;oBAC/C,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBAC1B,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,CAAA;YAEzB,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAA;QAC1B,CAAC;KACJ,CAAC,CAAA;IAEF,OAAO,CAAC,CAAA;AACZ,CAAC;AA1BD,gCA0BC;AAGD,oDAAoD;AAC7C,KAAK,UAAU,YAAY,CAAE,GAAiB,EAAE,OAAwB;IAC3E,OAAO,UAAU,CACb,MAAM,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAC9B,CAAA;AACL,CAAC;AAJD,oCAIC;AAGD,SAAgB,OAAO,CAAE,GAAiB,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,KAAyC,EAAG;IACvI,IAAI,KAAK,KAAK,IAAI;QACd,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAA;IAElC,GAAG,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAA;IAEpB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;QACvB,GAAG,GAAG,UAAU,GAAG,EAAE,CAAA;IAEzB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC;QAC9B,GAAG,GAAG,CAAE,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,YAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAE,CAAC,KAAK,EAAE;QACpE,mCAAmC;QACnC,SAAS;QACT,QAAQ;QACR,+EAA+E;QAC/E,MAAM;QACN,CAAE,KAAK,CAAE,CAAC,CAAE,YAAY,KAAK,CAAC,KAAK,EAAE,EAAE,CAAE,CAAC,CAAE,EAAE,CAAE;QAChD,CAAE,MAAM,IAAI,MAAM,KAAK,KAAK,CAAE,CAAC,CAAE,OAAO,MAAM,EAAE,CAAE,CAAC,CAAE,EAAE,CAAE;QACzD,CAAE,OAAO,CAAE,CAAC,CAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAE,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,MAAM,GAAG,GAAG,GAAG,KAAK,KAAK,EAAE,CAAC,KAAK,EAAE,CAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAE;QAClH,CAAE,IAAI,CAAE,CAAC,CAAE,MAAM,GAAG,gCAAgC,CAAC,KAAK,EAAE,CAAE,CAAC,CAAE,EAAE,CAAC;QACpE,CAAE,IAAI,CAAE,CAAC,CAAE,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAE,CAAC,CAAE,EAAE,CAAC,CAAA;AACpE,CAAC;AArBD,0BAqBC;AAKD,kDAAkD;AAClD;;;;;;EAME;AACK,KAAK,UAAU,GAAG,CACrB,IAAY,EACZ,IAAY,EACZ,EAAE,GAAG,GAAG,+BAA+B,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,MAAM,GAAG,KAAK,KAA0D,EAAG;IAE3I,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAA;IAEzD,OAAO,YAAY,CAAC,GAAG,EAAE;QACrB,IAAI,EAAE;YACF,IAAI;YACJ,IAAI;YACJ,KAAK,EAAE,MAAM;YACb,MAAM;SACT;KACJ,CAAC,CAAA;AACN,CAAC;AAfD,kBAeC;AAGD,SAAgB,QAAQ,CAAE,IAAY,EAAE,IAAW;IAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAE,GAAG,CAAC,EAAE,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC;QAChD,OAAO,CAAC,+BAA+B,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;QACtE,CAAC;YACG,OAAO,CAAC,+BAA+B,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAA;IAC7E,OAAO,GAAG,CAAA;AACd,CAAC;AAND,4BAMC","sourcesContent":["import {\n default as request_lib,\n type OptionsWithUri,\n type OptionsWithUrl\n} from 'request'\n\nimport {\n default as request_promise,\n type FullResponse,\n} from 'request-promise-native'\nimport { RequestError, StatusCodeError } from 'request-promise-native/errors.js'\n\nimport promise_retry from 'promise-retry'\n\nimport iconv from 'iconv-lite'\nimport cheerio from 'cheerio'\nimport qs from 'qs'\nimport { Cookie, MemoryCookieStore } from 'tough-cookie'\n\ndeclare module 'tough-cookie' {\n interface MemoryCookieStore {\n idx: Record<string, any>\n }\n}\n\n\nimport './prototype.js'\nimport type { Encoding } from './file.js'\nimport { inspect, output_width } from './utils.js'\n\nexport enum MyProxy {\n socks5 = 'http://localhost:10080',\n whistle = 'http://localhost:8899',\n}\n\n\n// ------------------------------------ Fetch, Request\nconst cookie_store = new MemoryCookieStore()\n\nexport const cookies = {\n store: cookie_store,\n \n jar: request_promise.jar(cookie_store),\n \n get (domain_or_url: string, str = false) {\n if (domain_or_url.startsWith('http'))\n if (str)\n return this.jar.getCookieString(domain_or_url)\n else\n return this.jar.getCookies(domain_or_url)\n \n let cookies: Cookie[]\n this.store.findCookies(domain_or_url, null, true, (error, _cookies) => {\n if (error) throw error\n cookies = _cookies\n })\n return cookies\n },\n}\n\nexport { Cookie }\n\n\nexport const _request = request_promise.defaults({\n rejectUnauthorized: false,\n gzip: true,\n /** prevent 302 redirect cause error, which is a boolean to set whether status codes other than 2xx should also reject the promise */\n simple: false,\n \n jar: cookies.jar\n})\n\n\nexport async function request_retry (retries: number, request_options: request_promise.OptionsWithUrl) {\n return promise_retry<FullResponse>({\n retries,\n minTimeout: 1000,\n maxTimeout: Infinity,\n factor: 2\n }, async (retry, count) => {\n try {\n return await _request(request_options)\n } catch (error) {\n if (!['ECONNRESET', 'ETIMEDOUT', 'ESOCKETTIMEDOUT'].includes(error.cause?.code)) throw error\n if (count <= retries)\n console.log(`${`retry (${count}) …`.yellow} ${request_options.url.toString().blue.underline}`)\n return retry(error)\n }\n })\n}\n\n\nexport interface RequestOptions {\n method?: 'get' | 'post' | 'put' | 'head' | 'delete' | 'patch'\n \n queries?: Record<string, any>\n \n headers?: Record<string, string>\n \n body?: string | Record<string, any>\n \n type?: 'application/json' | 'application/x-www-form-urlencoded' | 'multipart/form-data'\n \n \n proxy?: boolean | MyProxy | string\n \n encoding?: Encoding\n \n retries?: true | number\n \n timeout?: number\n \n auth?: {\n username: string\n password: string\n }\n \n gzip?: boolean\n \n cookies?: Record<string, string>\n}\n\nexport interface RequestRawOptions extends RequestOptions {\n raw: true\n}\n\n/** \n - url: must be full url\n - options:\n - raw: `false` 传入后返回整个 response\n - encoding: `(response content-type: charset=gb18030) || 'utf-8'` when 'binary' then return buffer\n - type: `'application/json'` request content-type header (if has body)\n - proxy: `false` proxy === true then use MyProxy.whistle\n - retries: `false` could be true (default 3 times) or retry times\n - timeout: `20 * 1000`\n - gzip: `raw -> false; else -> true`\n*/\nexport async function request (url: string | URL): Promise<string>\nexport async function request (url: string | URL, options: RequestRawOptions): Promise<request_lib.Response>\nexport async function request (url: string | URL, options: RequestOptions & { encoding: 'binary' }): Promise<Buffer>\nexport async function request (url: string | URL, options: RequestOptions): Promise<string>\nexport async function request (url: string | URL, {\n queries,\n \n body,\n \n type = 'application/json',\n \n proxy,\n \n method,\n \n headers,\n \n encoding,\n \n raw = false,\n \n retries,\n \n timeout = 20 * 1000,\n \n auth,\n \n gzip,\n \n cookies,\n \n}: RequestOptions & { raw?: boolean } = { }) {\n url = url.toString()\n \n if (!url.startsWith('http'))\n url = 'http://' + url\n \n const _body = body // for error log\n \n if (body && !method)\n method = 'post'\n \n if (type === 'application/json' && typeof body !== 'undefined' && (typeof body !== 'string' && !Buffer.isBuffer(body)))\n body = JSON.stringify(body)\n \n // --- proxy\n if (proxy) {\n if (proxy === true)\n proxy = MyProxy.whistle\n } else\n proxy = false\n \n // --- gzip\n if (gzip === undefined)\n gzip = !raw\n \n \n const options: request_lib.Options & { resolveWithFullResponse: boolean } = {\n url,\n \n ... method ? { method: method.toUpperCase() } : { },\n \n proxy,\n \n gzip,\n \n encoding: null,\n \n resolveWithFullResponse: true,\n \n headers: {\n 'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,ja-JP;q=0.6,ja;q=0.5',\n 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36',\n ... body ? { 'content-type': type } : { }, \n ... cookies ? {\n cookie: Object.entries(cookies)\n .map(([key, value]) => \n `${encodeURIComponent(key)}=${encodeURIComponent(value)}`\n ).join('; ')\n } : { },\n ... headers\n },\n \n ... queries ? { qs: queries } : { },\n \n // --- body\n ... (() => {\n if (!body) return { }\n if (type === 'application/x-www-form-urlencoded') return { form: body }\n if (type === 'multipart/form-data') return { formData: body as Record<string, any> }\n return { body }\n })(),\n \n ... timeout ? { timeout } : { },\n \n ... auth ? { auth } : { },\n }\n \n let resp: request_lib.Response\n \n try {\n if (retries) {\n if (retries === true)\n retries = 3\n \n resp = await request_retry(retries, options)\n } else\n resp = await _request(options)\n \n if (!(200 <= resp.statusCode && resp.statusCode <= 299))\n throw new StatusCodeError(resp.statusCode, resp.body, options, resp)\n \n } catch (error) {\n const {\n name, \n options: { method, url, uri, qs }, \n response,\n }: {\n options: OptionsWithUri & OptionsWithUrl\n response: FullResponse\n } & Error = error\n \n error[inspect.custom] = () => {\n let s = '─'.repeat(output_width / 2) + '\\n' +\n `${(method || 'get').toLowerCase().red} ${String(url || uri).blue.underline}\\n`\n \n if (qs)\n s += `\\n${'request.query:'.blue}\\n` +\n inspect(qs) + '\\n'\n \n if (_body)\n s += `\\n${'request.body:'.blue}\\n` +\n inspect(body) + '\\n'\n \n if (name === 'StatusCodeError')\n s += `\\n${'response.status:'.yellow} ${String(error.statusCode).red}\\n`\n else if (error instanceof RequestError)\n s += `\\n${'response.cause:'.yellow}\\n` +\n `${inspect(error.cause)}\\n`\n else\n s += `\\n${inspect(error)}\\n`\n \n if (response) {\n s += `\\n${'response.headers:'.yellow}\\n` + \n `${inspect(response.headers)}\\n`\n \n if (response.body)\n s += `\\n${'response.body:'.yellow}\\n` +\n `${inspect(response.body.toString())}\\n`\n }\n \n s += `\\n${'stack:'.yellow}\\n` +\n `${new Error().stack}\\n` +\n '─'.repeat(output_width / 2)\n \n return s\n }\n \n throw error\n }\n \n if (raw)\n return resp\n \n if (!resp.body)\n return resp.body\n \n // --- decode body\n if (encoding === 'binary')\n return resp.body\n \n encoding ||= /charset=(.*)/.exec(resp.headers['content-type'])?.[1] as Encoding || 'utf-8'\n \n if (/utf-?8/i.test(encoding))\n return (resp.body as Buffer).toString('utf-8')\n \n return iconv.decode((resp.body as Buffer), encoding)\n}\n\n\n/** make http request and parse body as json */\nexport async function request_json <T = any> (url: string | URL, options?: RequestOptions): Promise<T> {\n const resp = await request(url, options)\n if (!resp) return\n try {\n return JSON.parse(resp)\n } catch (error) {\n console.log(resp)\n throw error\n }\n}\n\n\n/** use $.html(cheerio_element) to get outer html */\nexport function parse_html (html: string) {\n let $ = cheerio.load(html, { decodeEntities: false })\n \n Object.defineProperty($, inspect.custom, {\n configurable: true,\n enumerable: false,\n value () {\n return this.html()\n }\n })\n \n Object.defineProperty($.prototype, inspect.custom, {\n configurable: true,\n enumerable: false,\n value (this: cheerio.Cheerio) {\n if (this.length > 1)\n return this.map((index, element) => {\n if (typeof element === 'string') return element\n return $.html(element)\n }).get().join_lines()\n \n return this.toString()\n }\n })\n \n return $\n}\n\n\n/** use $.html(cheerio_element) to get outer html */\nexport async function request_page (url: string | URL, options?: RequestOptions) {\n return parse_html(\n await request(url, options)\n )\n}\n\n\nexport function to_curl (url: string | URL, { queries, headers, method, body, proxy, exe = true }: RequestOptions & { exe?: boolean } = { }) {\n if (proxy === true)\n proxy = process.env.http_proxy\n \n url = url.toString()\n \n if (!url.startsWith('http'))\n url = `http://${url}`\n \n return (exe ? 'curl.exe' : 'curl') + \n ' ' + ( url + (queries ? '?' : '') + qs.stringify(queries) ).quote() +\n // ( typeof proxy === 'undefined' ?\n // ''\n // :\n // ( proxy ? ' --proxy ' + proxy.quote() : ' --noproxy ' + '*'.quote())\n // ) +\n ( proxy ? ` --proxy ${proxy.quote()}` : '' ) +\n ( method && method !== 'get' ? ` -X ${method}` : '' ) +\n ( headers ? Object.entries(headers).map( ([key, value]) => ' -H ' + `${key}: ${value}`.quote() ).join('') : '' ) +\n ( body ? ' -H ' + 'content-type: application/json'.quote() : '') +\n ( body ? ' --data ' + JSON.stringify(body).quote() : '')\n}\n\n\n\n\n// ------------------------------------ rpc client\n/** post json to http://localhost:8421/api/rpc\n - func: function name\n - args?: argument array\n - options?:\n - ignore?: `false` wait for execution but do not serialize result to response\n - async?: `false` do not wait for exec\n*/\nexport async function rpc (\n func: string, \n args?: any[], \n { url = 'http://localhost:8421/api/rpc', async: _async = false, ignore = false }: { url?: string, async?: boolean, ignore?: boolean } = { }\n) {\n if (!func) throw new Error('rpc argument error: no func')\n \n return request_json(url, {\n body: {\n func,\n args,\n async: _async,\n ignore,\n }\n })\n}\n\n\nexport function rpc_curl (func: string, args: any[]) {\n const cmd = args.find( arg => typeof arg === 'object') ?\n to_curl('http://localhost:8421/api/rpc', { body: { func, args } })\n :\n to_curl('http://localhost:8421/api/rpc', { queries: { func, args } })\n return cmd\n}\n\n"]}