@dune2/cli 0.4.12 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-B2TLAH5N.js → chunk-COPEAFHL.js} +10 -11
- package/dist/chunk-COPEAFHL.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/normalizeConfig.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunk-B2TLAH5N.js.map +0 -1
- /package/dist/{types-qEzXY222.d.ts → types-DwQTE6Zn.d.ts} +0 -0
|
@@ -55,12 +55,12 @@ import { google } from "googleapis";
|
|
|
55
55
|
|
|
56
56
|
// src/shared/google/shared.ts
|
|
57
57
|
import connect from "connect";
|
|
58
|
-
import open from "open";
|
|
58
|
+
import open, { apps } from "open";
|
|
59
59
|
import { URL } from "url";
|
|
60
60
|
var log = createLogger("google:shared");
|
|
61
61
|
function openBrowser(url) {
|
|
62
62
|
log.info(`\u5982\u672A\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u53EF\u8BBF\u95EE\u4EE5\u4E0B\u5730\u5740\uFF1A${url}`);
|
|
63
|
-
open(url, { app: { name:
|
|
63
|
+
open(url, { app: { name: apps.chrome } });
|
|
64
64
|
}
|
|
65
65
|
function openAndWaitReturnQuery(toOpenUrl, port, queryKey) {
|
|
66
66
|
return new Promise((resolve) => {
|
|
@@ -114,17 +114,17 @@ var GoogleAuth = class {
|
|
|
114
114
|
try {
|
|
115
115
|
this.tokens = fs.readJsonSync(this.tokensCachePath);
|
|
116
116
|
} catch (e) {
|
|
117
|
-
log2.info("\u672A\u83B7\u53D6\u5230\u7F13\u5B58\
|
|
117
|
+
log2.info("\u672A\u83B7\u53D6\u5230\u7F13\u5B58\u7684 token");
|
|
118
118
|
this.tokens = null;
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
async saveTokens(tokens) {
|
|
122
122
|
this.tokens = tokens;
|
|
123
123
|
await fs.writeJSON(this.tokensCachePath, tokens);
|
|
124
|
-
log2.info("\u4FDD\
|
|
124
|
+
log2.info("\u4FDD\u5B58 token \u6210\u529F");
|
|
125
125
|
}
|
|
126
126
|
async getCode() {
|
|
127
|
-
log2.info("\u5C06\u6253\
|
|
127
|
+
log2.info("\u5C06\u6253\u5F00 chrome \u6D4F\u89C8\u5668\u8FDB\u884C\u6388\u6743");
|
|
128
128
|
const authUrl = this.oauth2Client.generateAuthUrl({
|
|
129
129
|
access_type: "offline",
|
|
130
130
|
scope: this.scope
|
|
@@ -147,14 +147,13 @@ var GoogleAuth = class {
|
|
|
147
147
|
}
|
|
148
148
|
};
|
|
149
149
|
var clientSecret = {
|
|
150
|
-
client_id: "
|
|
151
|
-
project_id: "dune-cli-
|
|
150
|
+
client_id: "691639467478-gugsam9ukfg3m3ga70imecktvqgkqljc.apps.googleusercontent.com",
|
|
151
|
+
project_id: "dune-cli-423514",
|
|
152
152
|
auth_uri: "https://accounts.google.com/o/oauth2/auth",
|
|
153
153
|
token_uri: "https://oauth2.googleapis.com/token",
|
|
154
154
|
auth_provider_x509_cert_url: "https://www.googleapis.com/oauth2/v1/certs",
|
|
155
|
-
client_secret: "GOCSPX-
|
|
156
|
-
redirect_uris: ["http://localhost"]
|
|
157
|
-
javascript_origins: ["http://localhost"]
|
|
155
|
+
client_secret: "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",
|
|
156
|
+
redirect_uris: ["http://localhost"]
|
|
158
157
|
};
|
|
159
158
|
var googleAuth = new GoogleAuth(clientSecret);
|
|
160
159
|
|
|
@@ -488,4 +487,4 @@ export {
|
|
|
488
487
|
I18nData,
|
|
489
488
|
downloadFromPlatform
|
|
490
489
|
};
|
|
491
|
-
//# sourceMappingURL=chunk-
|
|
490
|
+
//# sourceMappingURL=chunk-COPEAFHL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shared/config/index.ts","../src/shared/letters.ts","../src/shared/google/sheet.ts","../src/shared/google/auth.ts","../src/shared/google/shared.ts","../src/commands/downloadFromPlatform.ts","../src/shared/i18nData.ts","../src/shared/sleep.ts"],"sourcesContent":["import JoyCon from \"joycon\";\nimport { Config } from \"./types\";\nimport { normalizeConfig } from \"./normalizeConfig\";\n\nexport * from \"./types\";\n\nconst joycon = new JoyCon();\n\nexport function defineConfig<T extends Config = Config>(c: T) {\n return c;\n}\n\nexport const configName = \"dune.config.js\";\n\nexport async function getConfig(): Promise<Config> {\n const res = await joycon.load([configName]);\n return normalizeConfig(res.data ?? {});\n}\n","/**\n *\n * - input : A\n * output : 0\n * - input : Z\n * output : 25\n * - input : AA\n * output : 26\n * - input : a\n * output : 0\n */\nexport function letterToNumber(letters: string | number) {\n if (typeof letters === \"number\" || !Number.isNaN(+letters)) {\n return +letters;\n }\n\n let n = 0;\n letters = letters.toUpperCase();\n for (let p = 0; p < letters.length; p++) {\n n = letters[p].charCodeAt(0) - 64 + n * 26;\n }\n\n return Math.max(0, n - 1);\n}\n\n/**\n * fork from https://github.com/matthewmueller/number-to-letter\n */\nconst alphabet = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\nconst base = alphabet.length;\n/**\n * numberToLetter(0) // A\n * numberToLetter(25) // Z\n * numberToLetter(26) // AA\n * numberToLetter(51) // AZ\n * numberToLetter(52) // BA\n * numberToLetter(676) // ZA\n * numberToLetter(701) // ZZ\n * numberToLetter(702) // AAA\n */\nexport function numberToLetter(n: number) {\n const digits: number[] = [];\n\n do {\n const v = n % base;\n digits.push(v);\n n = Math.floor(n / base);\n } while (n-- > 0);\n\n const chars: string[] = [];\n while (digits.length) {\n chars.push(alphabet[digits.pop()!]);\n }\n\n return chars.join(\"\");\n}\n","import { GaxiosResponse } from \"gaxios\";\nimport type { sheets_v4 } from \"googleapis\";\nimport { google } from \"googleapis\";\nimport { createLogger } from \"../index\";\nimport { numberToLetter } from \"../letters\";\nimport { googleAuth } from \"./auth\";\n\nconst log = createLogger(\"google:sheets\");\n\nclass GoogleSheet {\n private sheets: sheets_v4.Sheets;\n\n private initPromise: Promise<void> | null = null;\n private async initImpl() {\n if (!this.sheets) {\n await googleAuth.initCredentials();\n this.sheets = google.sheets({\n version: \"v4\",\n auth: googleAuth.oauth2Client,\n });\n }\n }\n /**\n * 调用sheets其他方法的时候需要先初始化\n */\n async init() {\n if (!this.initPromise) {\n this.initPromise = this.initImpl();\n }\n await this.initPromise;\n }\n\n get = async (options: sheets_v4.Params$Resource$Spreadsheets$Values$Get) => {\n await this.init();\n return this.sheets.spreadsheets.values.get(options);\n };\n\n private async update(\n spreadsheetId: string,\n range: string,\n colIndex: number,\n rowIndex: number,\n values: string[][]\n ): Promise<GaxiosResponse<sheets_v4.Schema$UpdateValuesResponse>> {\n await this.init();\n\n const colLetter = numberToLetter(colIndex);\n const sheetNeedRange = `${range}!${colLetter}${rowIndex}`;\n\n const res = await this.sheets.spreadsheets.values.update({\n spreadsheetId,\n range: sheetNeedRange,\n valueInputOption: \"USER_ENTERED\",\n requestBody: { values },\n });\n\n if (res.status === 200) {\n log.info(`更新 ${sheetNeedRange} 的值成功`);\n } else {\n log.error(\"some thing wrong\", res);\n }\n return res;\n }\n\n /**\n * 更新某一个单元格\n */\n async updateCell(\n spreadsheetId: string,\n range: string,\n colIndex: number,\n rowIndex: number,\n values: string\n ) {\n return this.update(spreadsheetId, range, colIndex, rowIndex, [[values]]);\n }\n\n /**\n * 更新某一列\n */\n async updateColumn(\n spreadsheetId: string,\n range: string,\n colIndex: number,\n rowIndex: number,\n values: string[]\n ) {\n return this.update(spreadsheetId, range, colIndex, rowIndex, [\n ...values.map((v) => [v]),\n ]);\n }\n /**\n * This method is used to get the titles of all the ranges in a Google Spreadsheet.\n *\n * @async\n * @param {string} spreadsheetId - The ID of the Google Spreadsheet.\n * @returns {Promise<string[]>} - A promise that resolves to an array of titles of all the ranges in the Google Spreadsheet.\n * @throws {Error} - Throws an error if the initialization of the Google Sheets API client fails.\n */\n async getRangeTitles(spreadsheetId: string) {\n // Initialize the Google Sheets API client\n await this.init();\n // Get the details of the Google Spreadsheet\n const res = await this.sheets.spreadsheets.get({\n spreadsheetId,\n });\n // Extract the titles of all the ranges in the Google Spreadsheet\n const titles = res.data.sheets\n ?.map((v) => v.properties?.title)\n .filter((v): v is string => !!v);\n\n return titles;\n }\n}\n\nexport const googleSheet = new GoogleSheet();\n","import fs from \"fs-extra\";\nimport { OAuth2Client } from \"google-auth-library\";\nimport { google } from \"googleapis\";\nimport { createLogger, homeConfigDir } from \"../index\";\nimport { openAndWaitReturnQuery } from \"./shared\";\n\ninterface AuthOptions {\n client_id: string;\n client_secret: string;\n /**\n * @default ['spreadsheets']\n */\n scope?: string[];\n}\n\nconst log = createLogger(\"google:auth\");\n\nclass GoogleAuth {\n private tokens: any = null;\n\n private tokensCachePath = homeConfigDir(\"chromeAuthToken.json\");\n\n private readonly scope: string[];\n\n oauth2Client: OAuth2Client = new google.auth.OAuth2(\n this.options.client_id,\n this.options.client_secret,\n \"http://localhost:12345\",\n );\n\n constructor(private options: AuthOptions) {\n this.options.scope = this.options.scope ?? [\"spreadsheets\"];\n const scopePrefix = `https://www.googleapis.com/auth/`;\n this.scope = this.options.scope.map((item) => {\n if (item.startsWith(scopePrefix)) {\n return item;\n }\n return `${scopePrefix}${item}`;\n });\n\n try {\n this.tokens = fs.readJsonSync(this.tokensCachePath);\n } catch (e) {\n log.info(\"未获取到缓存的 token\");\n this.tokens = null;\n }\n }\n\n private async saveTokens(tokens: any): Promise<void> {\n this.tokens = tokens;\n await fs.writeJSON(this.tokensCachePath, tokens);\n log.info(\"保存 token 成功\");\n }\n\n async getCode(): Promise<string> {\n log.info(\"将打开 chrome 浏览器进行授权\");\n const authUrl = this.oauth2Client.generateAuthUrl({\n access_type: \"offline\",\n scope: this.scope,\n });\n return await openAndWaitReturnQuery(authUrl, 12345, \"code\");\n }\n\n private async initCredentialsImpl(): Promise<void> {\n if (!this.tokens) {\n const code = await this.getCode();\n const { tokens } = await this.oauth2Client.getToken(code);\n await this.saveTokens(tokens);\n }\n this.oauth2Client.setCredentials(this.tokens);\n }\n private initCredentialsPromise: Promise<void> | null = null;\n async initCredentials() {\n if (!this.initCredentialsPromise) {\n this.initCredentialsPromise = this.initCredentialsImpl();\n }\n return await this.initCredentialsPromise;\n }\n}\n\n// see in https://console.cloud.google.com/apis/credentials?organizationId=286245507762&orgonly=true&project=dune-cli&supportedpurview=organizationId\nconst clientSecret = {\n client_id:\n \"691639467478-gugsam9ukfg3m3ga70imecktvqgkqljc.apps.googleusercontent.com\",\n project_id: \"dune-cli-423514\",\n auth_uri: \"https://accounts.google.com/o/oauth2/auth\",\n token_uri: \"https://oauth2.googleapis.com/token\",\n auth_provider_x509_cert_url: \"https://www.googleapis.com/oauth2/v1/certs\",\n client_secret: \"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\",\n redirect_uris: [\"http://localhost\"],\n};\n\nexport const googleAuth = new GoogleAuth(clientSecret);\n","import connect from \"connect\";\nimport open, { apps } from \"open\";\nimport { URL } from \"url\";\nimport { createLogger } from \"../index\";\n\nconst log = createLogger(\"google:shared\");\n\nfunction openBrowser(url: string) {\n log.info(`如未自动打开浏览器,可访问以下地址:${url}`);\n open(url, { app: { name: apps.chrome } });\n}\n\nexport function openAndWaitReturnQuery(\n toOpenUrl: string,\n port: number,\n queryKey: string,\n) {\n return new Promise<string>((resolve) => {\n openBrowser(toOpenUrl);\n\n const app = connect();\n app.use((req, res, next) => {\n const parsedUrl = new URL(req.url, `http://localhost:${port}`);\n const target = parsedUrl.searchParams.get(queryKey);\n if (target) {\n res.writeHead(200, {\n \"content-type\": \"text/html;charset=utf8\",\n });\n res.end(\n `<div>当前窗口可直接关闭</div>\n <script>\n window.open(\"\", \"_self\", \"\");\n window.close();\n </script>`,\n );\n server.close();\n server.unref();\n resolve(target);\n }\n next();\n });\n\n const server = app.listen(port);\n });\n}\n","import axios from \"axios\";\nimport pMap from \"p-map\";\nimport { createLogger } from \"../shared\";\nimport { getConfig } from \"../shared/config\";\nimport { I18nData } from \"../shared/i18nData\";\n\nconst logger = createLogger(\"downloadFromPlatform\");\n\n/**\n * 从 翻译平台下载翻译文件\n */\nexport async function downloadFromPlatform() {\n const config = await getConfig();\n // 只有配置了 translatePlatform 才会下载\n // TODO: 暂时只支持一个,后续支持多个\n const i18nConfig = config.i18n?.[0];\n if (!i18nConfig) {\n logger.error(\"i18n 配置为空\");\n return;\n }\n const { translatePlatform, locales } = i18nConfig;\n if (!translatePlatform?.enable) {\n logger.info(\"translatePlatform.enable 为 false,不会下载\");\n return;\n }\n logger.info(\"开始从翻译平台下载翻译文件\");\n const res = await axios({\n baseURL: translatePlatform.url,\n url: \"/v1/dune-i18n/public/findAll\",\n params: {\n projectName: translatePlatform.project,\n },\n }).catch((err) => {\n throw new TransError(err, \"请求翻译平台失败\");\n });\n\n const data = res.data.data;\n if (!data) {\n throw new TransError(res.data, \"data 为空\");\n }\n\n await pMap(locales ?? [], async (locale) => {\n const i18nData = new I18nData(locale, i18nConfig);\n await i18nData.updateFromSheetData(data?.[locale] ?? {});\n await i18nData.saveToDisk();\n return i18nData;\n });\n logger.info(\"从翻译平台下载翻译文件完成\");\n}\n\nclass TransError extends Error {\n constructor(public data: any, message: string = \"\") {\n super(`获取翻译平台数据失败: ${message}`);\n }\n}\n","import Table from \"cli-table3\";\nimport fs from \"fs-extra\";\nimport pMap from \"p-map\";\nimport path from \"path\";\nimport pc from \"picocolors\";\nimport { I18nConfig } from \"./config\";\nimport { createLogger } from \"./index\";\nimport { SheetData } from \"./resolveSheetData\";\nimport { sleep } from \"./sleep\";\n\nconst log = createLogger(\"i18nData\");\nexport type ExtractedMap = Map<\n string,\n { id: string; messages: string; files: string[] }\n>;\n\nexport class I18nData {\n data: Record<string, string> = {};\n\n filePath: string;\n\n /**\n * 是否是默认语言,默认语言需要使用提出来的文案作为value\n */\n isDefaultLocale: boolean;\n // 没有被使用到的翻译key\n unUsedKeys: Set<string> = new Set();\n constructor(\n public locale: string,\n public config: I18nConfig,\n // 是否需要删除未使用的文案\n public shouldDeleteUnused = false\n ) {\n this.isDefaultLocale = locale === config.defaultLocale;\n this.filePath = path.join(\n config.cwd!,\n config.i18nDir!,\n config.i18nFileName!.replace(\"{locale}\", locale)\n );\n }\n\n async loadData() {\n try {\n if (await fs.pathExists(this.filePath)) {\n this.data = await fs.readJSON(this.filePath);\n } else {\n log.info(\"File '%s' does not exist\", pc.dim(this.filePath));\n }\n } catch (e) {\n log.error(\n \"Error loading i18n data for locale '%s' from file '%s'\",\n pc.yellow(this.locale),\n pc.yellow(this.filePath)\n );\n log.error(\"Error: %s\", e.message);\n }\n return this.data;\n }\n\n /**\n * @param {ExtractedMap} extractedData 提取出来的内容\n */\n async updateByExtractedData(extractedData: ExtractedMap) {\n const oldData = await this.loadData();\n let newData = {};\n extractedData.forEach((value, key) => {\n let newValue = oldData[key] || \"\";\n if (this.isDefaultLocale) {\n // 默认语言需要回退到key作为value\n newValue = newValue || value.messages || key;\n //#region 对namespace的支持\n newValue = this.normalizeNamespacedDefaultLocaleData(newValue);\n //#endregion\n }\n newData[key] = newValue;\n });\n if (!this.shouldDeleteUnused) {\n // 不删除未使用的文案,则需要合并旧数据\n newData = { ...oldData, ...newData };\n }\n this.data = newData;\n\n // 记录下来未被使用的key,后面需要打印出来提示用户\n Object.keys(oldData).forEach((key) => {\n if (!extractedData.has(key)) {\n this.unUsedKeys.add(key);\n }\n });\n }\n\n private namespaceReg: RegExp;\n /**\n * 如果是默认语言,开启了 namespace的话\n * 提取出来的 文案 是 `模块名.文案` 的形式\n * 在这里需要把 `模块名.` 去掉\n */\n private normalizeNamespacedDefaultLocaleData(v: string) {\n if (!this.namespaceReg && this.config.namespace) {\n const names = Object.keys(this.config.namespace).join(\"|\");\n const separator = this.config.namespaceSeparator;\n this.namespaceReg = new RegExp(`^(${names})\\\\${separator}`);\n }\n if (this.namespaceReg) {\n return v.replace(this.namespaceReg, \"\");\n }\n return v;\n }\n\n async updateFromSheetData(sheetData: Record<string, string>) {\n await this.loadData();\n this.data = { ...this.data, ...sheetData };\n }\n\n private sortData() {\n //region 语言key按一定规则排序\n this.data = this.config.jsonSorter!(this.data);\n //endregion\n }\n\n async saveToDisk() {\n this.sortData();\n log.info(\n \"Saving i18n data for locale '%s' to file '%s'\",\n pc.green(this.locale),\n pc.dim(this.filePath)\n );\n try {\n await fs.ensureFile(this.filePath);\n await fs.writeJson(this.filePath, this.data, { spaces: 2 });\n log.info(\n \"Saved i18n data for locale '%s' to file '%s'\",\n pc.green(this.locale),\n pc.dim(this.filePath)\n );\n } catch (e) {\n log.error(\n \"Error saving i18n data for locale '%s' to file '%s'\",\n pc.green(this.locale),\n pc.dim(this.filePath)\n );\n log.error(\"Error: %s\", pc.red(e.message));\n }\n }\n\n async trySaveToGoogle(sheetData: SheetData) {\n await pMap(\n Object.entries(this.data),\n async ([key, value]) => {\n if (sheetData.hasI18nItem(this.locale, key)) {\n // 更新已有的\n await sheetData.getI18nItem(this.locale, key)?.tryUpdate(value);\n // 避免频繁请求,Google sheet api 默认限制\n // • 每秒钟读操作数:100 请求/秒\n // • 每秒钟单元格写操作数:100 请求/秒\n await sleep(1000);\n } else {\n log.error(\n \"%s range %s not found key %s\",\n pc.bold(this.config.sheetRange),\n pc.bold(this.locale),\n pc.bold(key)\n );\n }\n },\n { concurrency: 50 }\n );\n }\n private statistic() {\n const total = Object.keys(this.data).length;\n const missing = Object.values(this.data).filter((v) => !v).length;\n\n return {\n locale: this.locale,\n total,\n missing,\n };\n }\n static printStatistic(label: string, i18nDataArr: I18nData[]) {\n // 首先打印 unUsedKeys\n const unUsedKeys = i18nDataArr.reduce((keys, item) => {\n return new Set(item.unUsedKeys);\n }, new Set<string>());\n if (unUsedKeys.size) {\n console.log(\n pc.bold(\n `共有 ${pc.green(\n unUsedKeys.size\n )} 个 key 未在代码中使用,以下是具体的 key`\n )\n );\n console.log(\n pc.red(\n \"注意:这些key可能是已经删除的代码,也可能是通过 `t.ignoreExtract` 调用忽略了提取 并不一定是冗余的 key\"\n )\n );\n console.table(unUsedKeys);\n }\n // 打印提取出来的翻译文案统计\n const table = new Table({\n head: [\"Language\", \"Total count\", \"Missing\"],\n colAligns: [\"left\", \"center\", \"center\"],\n style: {\n head: [\"green\"],\n border: [],\n compact: true,\n },\n });\n\n i18nDataArr.forEach((i18nData) => {\n const statistic = i18nData.statistic();\n table.push([\n statistic.locale,\n statistic.total,\n statistic.missing > 0 ? pc.red(statistic.missing) : statistic.missing,\n ]);\n });\n console.log(pc.bold(label));\n console.log(table.toString());\n }\n}\n","export function sleep(ms: number) {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n"],"mappings":"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","names":["google","log","log","google","_a","pMap","fs","log","fs","pMap"]}
|
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
googleSheet,
|
|
8
8
|
letterToNumber,
|
|
9
9
|
sleep
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-COPEAFHL.js";
|
|
11
11
|
import "./chunk-4BXCANQI.js";
|
|
12
12
|
import {
|
|
13
13
|
cli,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
} from "./chunk-UGSBKD2I.js";
|
|
16
16
|
|
|
17
17
|
// package.json
|
|
18
|
-
var version = "0.4.
|
|
18
|
+
var version = "0.4.13";
|
|
19
19
|
|
|
20
20
|
// src/commands/download.ts
|
|
21
21
|
import pMap from "p-map";
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/commands/download.ts","../src/shared/resolveSheetData.ts","../src/shared/promptConfigEnable.ts","../src/commands/extract/index.ts","../src/commands/generateApi/index.ts","../src/shared/formatFile.ts","../src/commands/initConfig.ts","../src/commands/interactive.ts","../src/commands/namespace.ts","../src/shared/autoNamespaceByReg.ts","../src/commands/upload.ts","../src/cli.ts"],"sourcesContent":["{\n \"name\": \"@dune2/cli\",\n \"version\": \"0.4.11\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/liaoyinglong/next-tools.git\",\n \"directory\": \"packages/cli\"\n },\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.js\"\n },\n \"./cli\": {\n \"import\": \"./dist/cli.js\"\n },\n \"./normalizeConfig\": {\n \"import\": \"./dist/normalizeConfig.js\"\n },\n \"./prettier\": {\n \"import\": \"./dist/prettier.js\",\n \"require\": \"./dist/prettier.cjs\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"types\": \"dist/index.d.ts\",\n \"bin\": {\n \"dune\": \"./dist/cli.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"shx rm -rf ./dist && tsup --splitting\",\n \"dev\": \"pnpm run build --watch\",\n \"lint\": \"tsc --diagnostics --noEmit\",\n \"test\": \"vitest run\",\n \"test:u\": \"vitest -u\"\n },\n \"dependencies\": {\n \"@apidevtools/swagger-parser\": \"^10.1.0\",\n \"@dune2/wasm\": \"workspace:*\",\n \"axios\": \"^1.6.2\",\n \"cac\": \"^6.7.14\",\n \"cli-table3\": \"^0.6.3\",\n \"connect\": \"^3.7.0\",\n \"debug\": \"^4.3.4\",\n \"enquirer\": \"^2.3.6\",\n \"fs-extra\": \"^11.2.0\",\n \"globby\": \"^14.0.1\",\n \"googleapis\": \"^108.0.0\",\n \"joycon\": \"^3.1.1\",\n \"json-schema-to-typescript\": \"^14.0.4\",\n \"lodash\": \"^4.17.21\",\n \"open\": \"^10.1.0\",\n \"p-map\": \"^7.0.2\",\n \"path-to-regexp\": \"^6.2.1\",\n \"picocolors\": \"^1.0.0\"\n },\n \"devDependencies\": {\n \"@types/debug\": \"^4.1.7\",\n \"@types/lodash\": \"^4.14.186\",\n \"gaxios\": \"*\",\n \"google-auth-library\": \"*\",\n \"openapi-types\": \"^12.0.2\",\n \"prettier\": \"^3\",\n \"tsup\": \"8\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}\n","import pMap from \"p-map\";\nimport { createLogger } from \"../shared\";\nimport { getConfig } from \"../shared/config\";\nimport { I18nData } from \"../shared/i18nData\";\nimport { resolveSheetData } from \"../shared/resolveSheetData\";\nimport { promptI18nConfigEnable } from \"../shared/promptConfigEnable\";\n\nconst log = createLogger(\"generate\");\n\nexport async function download() {\n const config = await getConfig();\n\n let i18nConfigs = await promptI18nConfigEnable(config.i18n);\n\n let i = 0;\n for (const configItem of i18nConfigs) {\n i++;\n if (!configItem.sheetId || !configItem.sheetRange) {\n log.error(`config.${i} sheetId 或 sheetRange 为空,请检查`);\n continue;\n }\n const sheetData = await resolveSheetData(configItem);\n\n const statistics = await pMap(\n configItem.locales ?? [],\n async (locale, index) => {\n const i18nData = new I18nData(locale, configItem);\n await i18nData.updateFromSheetData(sheetData.getLangDataJSON(locale));\n await i18nData.saveToDisk();\n return i18nData;\n }\n );\n I18nData.printStatistic(`${configItem.sheetRange} 生成结果: `, statistics);\n }\n}\n","import { I18nConfig } from \"./config\";\nimport { googleSheet } from \"./google/sheet\";\nimport { createLogger } from \"./index\";\nimport { letterToNumber } from \"./letters\";\n\nconst log = createLogger(\"shared:resolveSheetData\");\n\nclass SheetI18nItem {\n value: string;\n\n colIndex: number;\n\n constructor(\n private spreadsheetId: string,\n private range: string,\n public key: string,\n colIndex: number | string,\n public row: string[],\n private rowIndex: number\n ) {\n this.colIndex = letterToNumber(colIndex);\n // TODO: 待确定 无值的key是否要生成\n // value = undefined 即不会生成\n this.value = this.row[this.colIndex] || \"\";\n }\n\n /**\n * 尝试更新 单元格的值\n * 如果一样则不更新\n */\n async tryUpdate(newValue: string) {\n if (newValue === this.value) {\n // 云端的值跟本地一样 不需要同步\n return;\n }\n\n await googleSheet.updateCell(\n this.spreadsheetId,\n this.range,\n this.colIndex,\n this.rowIndex,\n newValue\n );\n }\n}\n\nexport async function resolveSheetData(config: I18nConfig): Promise<SheetData> {\n const { position } = config;\n const parseStartIndex = config.parseStartIndex ?? 2;\n\n log.info(`读取 ${config.sheetRange} sheet数据`);\n\n const res = await googleSheet.get({\n spreadsheetId: config.sheetId,\n range: config.sheetRange,\n });\n if (!res.data.values) {\n log.error(\n `${config.sheetRange} sheet数据为空,请检查,应该最少有一行头部数据`\n );\n return new SheetData(config, 2);\n }\n\n const sheetData = new SheetData(config, res.data.values.length + 1);\n\n res.data.values.forEach((row: string[], rowIndex) => {\n // excel 的开始索引是1,所以要 +1\n const trulyRowIndex = rowIndex + 1;\n if (parseStartIndex > trulyRowIndex) {\n // 还未到可以开始解析的行数\n return;\n }\n\n const i18nKey = row[letterToNumber(position!.key)];\n\n if (i18nKey) {\n if (sheetData.keySet.has(i18nKey)) {\n log.error(\n `表格 ${config.sheetRange} 发现重复的i18nKey: ${i18nKey}, 将覆盖前面的值`\n );\n } else {\n sheetData.keySet.add(i18nKey);\n }\n\n config.locales?.forEach((lang) => {\n sheetData.setI18nItem(\n lang,\n new SheetI18nItem(\n config.sheetId!,\n config.sheetRange!,\n i18nKey,\n position![lang],\n row,\n trulyRowIndex\n )\n );\n });\n }\n });\n\n return sheetData;\n}\n\nexport class SheetData {\n keySet = new Set<string>();\n\n constructor(\n private config: I18nConfig,\n // 当前有多少行 新增的时候往后面添加\n public nextAppendRowIndex: number\n ) {}\n\n private value = new Map(\n this.config.locales!.map((lang) => {\n return [lang, new Map<string, SheetI18nItem>()];\n })\n );\n\n getI18nItem(lang: string, i18nKey: string) {\n return this.value.get(lang)!.get(i18nKey);\n }\n\n setI18nItem(lang: string, i18nItem: SheetI18nItem) {\n this.value.get(lang)!.set(i18nItem.key, i18nItem);\n }\n\n hasI18nItem(lang: string, i18nKey: string) {\n return this.value.get(lang)!.has(i18nKey);\n }\n\n getLangDataJSON(lang: string) {\n const res = {} as Record<string, string>;\n this.value.get(lang)!.forEach((i18nItem) => {\n res[i18nItem.key] = i18nItem.value;\n });\n return res;\n }\n}\n","import enquirer from \"enquirer\";\nimport { ApiConfig, I18nConfig } from \"./config\";\nconst { prompt } = enquirer;\n\ninterface Opt<T> {\n configArr: (T & { enabled?: boolean })[];\n getChoiceItem: (item: T) => {\n name: string;\n message?: string;\n value?: string;\n hint?: string;\n };\n checkIsEnabled: (enabledArr: string[], item: T) => boolean;\n}\n\nexport async function promptConfigEnable<T>(opt: Opt<T>) {\n const { configArr, getChoiceItem } = opt;\n // 只有一条配置的时候不用选择\n if (configArr.length <= 1) {\n return configArr;\n }\n\n const choices = [\n {\n name: \"全部\",\n message: \"全部\",\n choices: configArr.map((item) => {\n return getChoiceItem(item);\n }),\n },\n ];\n const res = await prompt<{ enabled: string[] }>({\n type: \"multiselect\",\n message: \"选择要生效的配置项\",\n // @ts-ignore\n hint: \"(空格选中,回车确认)\",\n name: \"enabled\",\n validate(value) {\n return value.length === 0 ? `至少选择一项` : true;\n },\n choices,\n });\n\n configArr.forEach((item) => {\n item.enabled = opt.checkIsEnabled(res.enabled, item);\n });\n\n return configArr.filter((c) => c.enabled);\n}\n\nexport function promptI18nConfigEnable(configArr: I18nConfig[] | undefined) {\n return promptConfigEnable({\n configArr: configArr ?? [],\n getChoiceItem: (item) => {\n return {\n name: item.i18nDir!,\n hint: `sheetRange: ${item.sheetRange}`,\n };\n },\n checkIsEnabled: (enabledArr, item) => {\n return enabledArr.includes(item.i18nDir!);\n },\n });\n}\n\nexport function promptApiConfigEnable(configArr: ApiConfig[] | undefined) {\n return promptConfigEnable({\n configArr: configArr ?? [],\n getChoiceItem: (item) => {\n return {\n name: item.output!,\n hint: `swaggerJSONPath: ${item.swaggerJSONPath}`,\n };\n },\n checkIsEnabled: (enabledArr, item) => {\n return enabledArr.includes(item.output!);\n },\n });\n}\n","import fs from \"fs-extra\";\nimport { globby } from \"globby\";\nimport os from \"os\";\nimport pMap from \"p-map\";\nimport path from \"path\";\nimport pc from \"picocolors\";\nimport { createLogger } from \"../../shared\";\nimport { getConfig, I18nConfig } from \"../../shared/config\";\nimport { ExtractedMap, I18nData } from \"../../shared/i18nData\";\nimport { promptI18nConfigEnable } from \"../../shared/promptConfigEnable\";\n\nconst log = createLogger(\"extract\");\n\n/**\n * 提取文案\n */\nexport async function extract(opts?: { deleteUnused: boolean }) {\n const config = await getConfig();\n const { extract } = await import(\"@dune2/wasm\");\n\n let i18nConfigs = await promptI18nConfigEnable(\n config.i18n?.filter((item) => !item.disableExtract)\n );\n\n // 这是使得任务串行,方便看日志\n for (const configItem of i18nConfigs) {\n const files = await globby(\n [\n `./src/**/**.{js,jsx,ts,tsx}`,\n \"!**/node_modules/**\",\n \"!**.d.ts\",\n \"!**/.next/**\",\n \"!**/out/**\",\n ].concat(configItem.include ?? []),\n { cwd: configItem.cwd }\n );\n log.info(\"预计共解析 %s 个文件\", pc.green(files.length));\n let errMsgs: string[] = [];\n const extractedI18nDataMap: ExtractedMap = new Map();\n\n await pMap(\n files,\n async (file) => {\n const content = await fs.readFile(file, \"utf-8\");\n const res = await extract(content, file);\n if (res.data.size) {\n log.info(\n \"从 %s 中提取到 %s 条文案\",\n pc.dim(file),\n pc.green(res.data.size)\n );\n res.data.forEach((value, key) => {\n let cur = extractedI18nDataMap.get(key)!;\n const hasCache = !!cur;\n if (!hasCache) {\n cur = { ...value, files: [] };\n }\n cur.files.push(\n path.resolve(file) + \":\" + value.line + \":\" + value.column\n );\n // 优先使用 提取出来的文案\n cur.messages = value.messages || cur.messages;\n\n if (!hasCache) {\n extractedI18nDataMap.set(key, cur);\n }\n });\n }\n if (res.errMsg) {\n errMsgs.push(res.errMsg);\n }\n },\n { concurrency: 20 }\n );\n\n await saveExtractedMetaData(configItem, extractedI18nDataMap);\n\n const i18nDataArr = await pMap(configItem.locales ?? [], async (locale) => {\n const i18nData = new I18nData(locale, configItem, opts?.deleteUnused);\n await i18nData.updateByExtractedData(extractedI18nDataMap);\n await i18nData.saveToDisk();\n return i18nData;\n });\n if (errMsgs.length) {\n console.log(pc.bold(\"以下未能成功提取的文案,请手动处理:\"));\n console.log(errMsgs.join(os.EOL));\n }\n I18nData.printStatistic(\"提取结果: \", i18nDataArr);\n\n await import(\"./uploadToTranslatePlatform\").then((mod) =>\n mod.uploadToTranslatePlatform(configItem, i18nDataArr)\n );\n }\n}\n\n/**\n * 保存相关的提取信息\n */\nasync function saveExtractedMetaData(\n config: I18nConfig,\n extractedI18nDataMap: ExtractedMap\n) {\n const { i18nDir } = config;\n // case:\n // input: \"./src/i18n\"\n // output: \"src_i18n.extractedLog.json\"\n const prefix = i18nDir!.replace(\"./\", \"\").replace(/\\//g, \"_\");\n const filename = `${prefix}.extractedLog.json`;\n\n const metaDataJsonPath = path.join(i18nDir!, filename);\n\n await fs.ensureFile(metaDataJsonPath);\n\n // extractedI18nDataMap 是个 Map 需要转成换json\n let data = Array.from(extractedI18nDataMap.entries()).map(\n ([key, value]) => value\n );\n // 按照 id 排序\n data = data.sort((a, b) => {\n return a.id.localeCompare(b.id);\n });\n\n await fs.writeJSON(\n metaDataJsonPath,\n\n data,\n {\n spaces: 2,\n }\n );\n}\n","import SwaggerParser from \"@apidevtools/swagger-parser\";\nimport fs from \"fs-extra\";\nimport { compile } from \"json-schema-to-typescript\";\nimport _ from \"lodash\";\nimport { OpenAPIV3 } from \"openapi-types\";\nimport * as os from \"os\";\nimport pMap from \"p-map\";\nimport path from \"path\";\nimport { createLogger } from \"../../shared\";\nimport { ApiConfig, getConfig } from \"../../shared/config\";\nimport { formatFile } from \"../../shared/formatFile\";\nimport { promptApiConfigEnable } from \"../../shared/promptConfigEnable\";\n\nconst log = createLogger(\"generateApi\");\n\nexport async function generateApi() {\n const config = await getConfig();\n const apiConfigs = await promptApiConfigEnable(config.api);\n\n for (const apiConfig of apiConfigs) {\n log.info(`清除旧的api文件: ${apiConfig.output}`);\n await fs.emptydir(apiConfig.output!);\n }\n\n for (const apiConfig of apiConfigs) {\n log.info(\"开始解析 %s\", apiConfig.swaggerJSONPath);\n const parsed = (await SwaggerParser.dereference(apiConfig.swaggerJSONPath, {\n resolve: {\n http: {\n timeout: 30 * 1000,\n },\n },\n })) as OpenAPIV3.Document;\n\n await pMap(Object.entries(parsed.paths), async ([url, pathItemObject]) => {\n log.info(\"开始生成 %s\", url);\n if (pathItemObject) {\n await pMap(\n [\"get\", \"put\", \"post\", \"delete\", \"patch\"],\n async (method) => {\n const operationObject = pathItemObject[method];\n if (operationObject) {\n const code = await generateApiRequestCode({\n url: url,\n method: method,\n operationObject: operationObject,\n apiConfig,\n });\n const outputPath = path\n .join(\n apiConfig.output!,\n url,\n apiConfig.enableTs ? `${method}.ts` : `${method}.js`\n )\n .replace(/:/g, \"_\");\n await fs.ensureFile(outputPath);\n await fs.writeFile(outputPath, code);\n }\n }\n );\n }\n });\n\n if (apiConfig.format) {\n await formatFile(apiConfig.output!);\n }\n }\n\n log.info(\"generateApi Done\");\n}\n\n/**\n * 根据请求方法,生成请求代码\n */\nexport async function generateApiRequestCode(options: {\n url: string;\n method: string;\n operationObject: OpenAPIV3.OperationObject;\n apiConfig: ApiConfig;\n}): Promise<string> {\n const { method, operationObject, apiConfig } = options;\n\n const url = (() => {\n if (typeof apiConfig.urlTransformer === \"string\") {\n return `${apiConfig.urlTransformer}${options.url}`;\n }\n if (typeof apiConfig.urlTransformer === \"function\") {\n return apiConfig.urlTransformer(options.url);\n }\n return options.url;\n })();\n\n const seeUrl = apiConfig.swaggerUiUrl\n ? `${apiConfig.swaggerUiUrl}#/${operationObject.tags?.join(\"/\") ?? \"\"}/${\n operationObject.operationId\n }`\n : \"\";\n\n // 生成的请求构造器的名称,需要使用原始url\n let requestBuilderName = _.camelCase(`${options.url}_${method}_api`);\n\n // 判断是否有效的js变量\n if (!/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(requestBuilderName)) {\n // 不是有效的js变量,使用 _ + 数字\n requestBuilderName = `_${requestBuilderName}`;\n }\n\n //#region url上参数 例如 /api/v1/users/{userId}\n const urlPathParams = getUrlPathParams(\n (operationObject.parameters as never) ?? []\n );\n const urlPathParamsCode = urlPathParams.length\n ? `urlPathParams: ${JSON.stringify(urlPathParams)},`\n : \"\";\n //#endregion\n\n let code: string[] = [\n \"// 这个文件由 @dune2/cli 自动生成,不要手动修改,否则会被覆盖\",\n apiConfig.RequestBuilderImportPath!,\n apiConfig.requestFnImportPath!,\n apiConfig.queryClientImportPath!,\n\n \"/**\",\n ` * ${operationObject.summary}`,\n ` * @tags ${operationObject.tags?.join(\",\")}`,\n seeUrl && ` * @see ${seeUrl}`,\n ` */`,\n ].filter(Boolean);\n\n // builder 代码\n let builderCode = `\\\nexport const ${requestBuilderName} = new RequestBuilder({\n url: '${url}',\n method: '${method}',\n ${apiConfig.requestFnImportPath ? \"requestFn,\" : \"\"}\n ${urlPathParamsCode}\n ${apiConfig.queryClientImportPath ? \"queryClient,\" : \"\"}\n});`\n // 移除空行\n .replace(/,\\n\\s*}/, \",\" + os.EOL + \"}\");\n if (apiConfig.enableTs) {\n builderCode = builderCode.replace(\n \"new RequestBuilder(\",\n `new RequestBuilder<${requestBuilderName}.Req, ${requestBuilderName}.Res>(`\n );\n }\n code.push(builderCode);\n\n if (apiConfig.enableTs) {\n // post和put请求需要生成表单fieldsMap\n const isGenrateFieldsMap = [\"post\", \"put\"].includes(method);\n // 请求参数类型\n // 响应参数类型\n const [requestParamsTypeCode, responseParamsTypeCode] = await Promise.all([\n compileRequestParams(operationObject, isGenrateFieldsMap),\n compileResponseParams(operationObject, apiConfig),\n ]);\n\n code.push(`\nexport namespace ${requestBuilderName} {\n ${requestParamsTypeCode.code}\n \n ${responseParamsTypeCode}\n};`);\n\n if (isGenrateFieldsMap && !_.isEmpty(requestParamsTypeCode.fieldsMap)) {\n // 生成表单fieldsMap\n code.push(`\nexport const ${requestBuilderName}FieldsMap = ${JSON.stringify(\n requestParamsTypeCode.fieldsMap\n )}\n`);\n }\n }\n\n return code.join(os.EOL);\n}\n\nfunction getUrlPathParams(parameters: OpenAPIV3.ParameterObject[]) {\n return parameters\n .filter((item) => item.in === \"path\")\n .map((item) => item.name);\n}\n\n/**\n * 这个方法还不完善,只能处理简单的请求参数\n */\nasync function compileRequestParams(\n operationObject: OpenAPIV3.OperationObject,\n generateFieldsMap = false\n) {\n let schema;\n if (operationObject.requestBody) {\n //TODO: 这里也需要处理其他类型\n schema = (operationObject.requestBody as OpenAPIV3.RequestBodyObject)\n .content[\"application/json\"].schema;\n } else if (operationObject.parameters) {\n const extraProperties = {};\n const parameters: OpenAPIV3.ParameterObject[] = [];\n (operationObject.parameters as OpenAPIV3.ParameterObject[]).forEach(\n (item) => {\n if (![\"query\", \"path\"].includes(item.in)) {\n return;\n }\n if (_.get(item.schema, \"type\") === \"object\") {\n // swagger get 请求上 有些参数是 object 类型 应该拍平\n _.assign(extraProperties, _.get(item.schema, \"properties\", {}));\n } else {\n parameters.push(item);\n }\n }\n );\n\n // 必填参数中忽略 分页相关的参数\n const required = parameters\n .filter(\n (p) => p.required && ![\"pageNum\", \"pageSize\", \"count\"].includes(p.name)\n )\n .map((p) => p.name);\n const properties = Object.fromEntries(\n parameters\n // 后端 swagger 可能出现没有 schema 的情况,这里过滤掉\n .filter((p) => !!p.schema)\n .map((p) => {\n //TODO: 这里也要处理 ref 类型\n const schema = p.schema as OpenAPIV3.SchemaObject;\n return [\n p.name,\n {\n ...schema,\n description: p.description,\n // enum: schema.enum ?? [],\n },\n ];\n })\n );\n schema = {\n required,\n type: \"object\",\n properties: { ...properties, ...extraProperties },\n };\n }\n\n let code = \"\";\n const fieldsMap: Record<string, string> = {};\n if (schema) {\n try {\n code = await compile(schema, \"Req\", {\n bannerComment: \"\",\n ignoreMinAndMaxItems: !!1,\n additionalProperties: false,\n // format: false,\n });\n\n // 判断接口是否是分页请求\n const isPageSearchRequest = (data: any) => {\n // 入参有这些字段就认为是分页查询接口\n const keys = [\"pageNum\", \"pageSize\", \"count\"];\n return (\n _.get(data, \"type\") === \"object\" &&\n _.get(data, \"required\", []).filter((item) => keys.includes(item))\n .length === keys.length\n );\n };\n\n if (generateFieldsMap) {\n // 分页查询接口取params字段\n const params = isPageSearchRequest(schema)\n ? _.get(schema, \"properties.params.properties\", {})\n : schema.properties;\n _.forEach(params, (_, field) => {\n fieldsMap[field] = field;\n });\n }\n } catch (e) {\n log.error(\"生成请求参数类型失败,请检查 %o\", {\n summary: operationObject.summary,\n message: e.message,\n });\n }\n }\n\n return {\n code: code || \"export type Req = any;\",\n fieldsMap,\n };\n}\n\nasync function compileResponseParams(\n operationObject: OpenAPIV3.OperationObject,\n apiConfig: ApiConfig\n) {\n const temp = operationObject.responses[\"200\"] as OpenAPIV3.ResponseObject;\n let code = \"\";\n if (temp?.content) {\n // FIXME: 可能需要处理其他的content类型\n const temp2 = temp.content[\"application/json\"] || temp.content[\"*/*\"];\n const schema = temp2.schema as OpenAPIV3.SchemaObject;\n let data = apiConfig.responseSchemaTransformer!(schema);\n if (data) {\n // 这里需要深度clone的原因是:\n // 解析出来的scheme会尽可能的被复用,导致影响到下次解析\n data = _.cloneDeep(data);\n markCircularToRef(data);\n try {\n code = await compile(data, \"Res\", {\n bannerComment: \"\",\n ignoreMinAndMaxItems: !!1,\n additionalProperties: false,\n // format: false,\n });\n\n // 通过响应数据判断是否是分页查询接口\n const isPageSearchResponse = (data: any) => {\n // 有result字段且为数组,就认为是分页查询接口\n return (\n _.get(data, \"type\") === \"object\" &&\n _.get(data, \"properties.result.type\") === \"array\"\n );\n };\n\n // 新增后端分页查询返回的数据类型\n if (isPageSearchResponse(data)) {\n code += `${os.EOL}export type ResultItem = Res['result'][0]`;\n }\n } catch (e) {\n log.error(\"转换响应参数类型失败, 请检查 %o\", {\n summary: operationObject.summary,\n error: e.message,\n });\n }\n } else {\n log.error(\"responseSchemaTransformer 返回值为空, 请检查\");\n }\n }\n\n return code ? code : \"export type Res = any;\";\n}\n\nexport function markCircularToRef(\n obj,\n parentMark = \"#\",\n map = new Map([[obj, parentMark]]),\n set = new Set([obj])\n) {\n Object.keys(obj).forEach((key) => {\n const value = obj[key];\n if (typeof value === \"object\" && !Array.isArray(value)) {\n if (set.has(value)) {\n obj[key] = { $ref: map.get(value) };\n return;\n }\n const tempMark = parentMark + \"/\" + key;\n set.add(value);\n map.set(value, tempMark);\n markCircularToRef(value, tempMark, map, set);\n }\n });\n return map;\n}\n","import { createLogger } from \".\";\nimport * as child_process from \"child_process\";\n\nconst log = createLogger(\"formatFile\");\n\nexport function formatFile(filename: string) {\n // 格式化代码\n log.info(`尝试格式化代码: %s`, filename);\n child_process.exec(`prettier --write '${filename}'`, (error) => {\n if (error) {\n log.error(`格式化代码失败: ${error}`);\n log.error(`请手动执行: prettier --write ${filename}`);\n log.error(`或者在配置文件中关闭格式化功能`);\n } else {\n log.info(`格式化代码成功: %s`, filename);\n }\n });\n}\n","import { createLogger } from \"../shared\";\nimport { getConfig, configName } from \"../shared/config\";\nimport fs from \"fs-extra\";\nimport path from \"path\";\n\nconst log = createLogger(\"initConfig\");\n\nconst tpl = `\\\n/**\n * @param {import('@dune2/cli').Config} config\n */\nfunction defineConfig(config) {\n return config;\n}\nmodule.exports = defineConfig({ i18n: [], api:[] });\n`;\n\nexport const initConfig = async () => {\n const config = await getConfig();\n const configPath = path.join(config.cwd!, configName);\n log.info(`config file path: ${configPath}`);\n if (await fs.pathExists(configPath)) {\n log.info(`config file already exists, skip`);\n return;\n }\n await fs.writeFile(configPath, tpl);\n log.info(`config file created`);\n};\n","import { cli, createLogger } from \"../shared\";\nimport enquirer from \"enquirer\";\nconst { prompt } = enquirer;\n\nconst log = createLogger(\"interactive\");\n\nexport const interactive = async (args: any) => {\n const commands = cli.commands.filter((command) => {\n if (command.name) {\n return !command.name.startsWith(\"@@\") && command.name !== \"interactive\";\n }\n return false;\n });\n\n const commandMap = new Map<string, typeof commands[number]>();\n const res = await prompt<{ command: string }>({\n type: \"autocomplete\",\n name: \"command\",\n message: \"选择要执行的命令:\",\n choices: commands.map((command) => {\n commandMap.set(command.name, command);\n return {\n name: command.name,\n value: command.name,\n message: command.description,\n hint: `等同命令 ${cli.name} ${command.name}`,\n };\n }),\n });\n const command = commandMap.get(res.command);\n if (!command) {\n log.error(\"未找到命令 %s\", res.command);\n return;\n }\n command.commandAction?.apply(cli, args);\n};\n","import enquirer from \"enquirer\";\nimport fs from \"fs-extra\";\nimport { globby } from \"globby\";\nimport _ from \"lodash\";\nimport pMap from \"p-map\";\nimport pc from \"picocolors\";\nimport { createLogger } from \"../shared\";\nimport { autoNamespaceByReg } from \"../shared/autoNamespaceByReg\";\nimport { getConfig } from \"../shared/config\";\nimport { formatFile } from \"../shared/formatFile\";\n\nconst { prompt } = enquirer;\n\nconst log = createLogger(\"namespace\");\ninterface Params {\n /**\n * 生成模式\n *\n * - swc 指的是用swc 插件来添加 前缀\n *\n * swc 生成的代码更加规范,但是会有一些问题\n *\n * - reg 指的是用正则来添加 前缀\n *\n * reg 目前只能初始 t function 的调用,不能处理 Trans 组件的复杂\n * @default swc\n */\n mode?: \"swc\" | \"reg\";\n}\n\nexport async function namespace(params: Params) {\n const { mode = \"swc\" } = params;\n const config = await getConfig();\n\n // 不允许提取的 配置 不需要选择\n let i18nConfigs = config.i18n?.filter((item) => !item.disableExtract);\n if (!i18nConfigs) {\n log.info(\"没有配置 i18n\");\n return;\n }\n\n // 选择 生效的 i18n 配置\n const { i18nDir } = await prompt<{ i18nDir: string }>({\n type: \"select\",\n name: \"i18nDir\",\n message: \"选择要生效的配置项\",\n choices: i18nConfigs.map((item) => {\n return {\n name: item.i18nDir!,\n hint: `sheetRange: ${item.sheetRange}`,\n };\n }),\n });\n let i18nConfig = i18nConfigs.find((item) => item.i18nDir === i18nDir);\n if (!i18nConfig) {\n log.info(\"没有找到对应的配置\");\n return;\n }\n\n // 选择 生效的 namespace\n const { namespaces } = await prompt<{ namespaces: string[] }>({\n type: \"multiselect\",\n message: \"选择要生效的配置项\",\n //@ts-ignore\n hint: \"(空格选中,回车确认)\",\n name: \"namespaces\",\n validate(value) {\n return value.length === 0 ? `至少选择一项` : true;\n },\n choices: _.map(i18nConfig.namespace, (v, k) => {\n return {\n name: k,\n };\n }),\n });\n\n const autoNamespace = await (() => {\n if (mode === \"swc\") {\n log.info(\"使用 swc 来处理\");\n return import(\"@dune2/wasm\").then((m) => m.autoNamespace);\n }\n log.info(\"使用 reg 来处理\");\n return autoNamespaceByReg;\n })();\n\n for (const namespace of namespaces) {\n const namespaceConfig = i18nConfig.namespace?.[namespace];\n\n const suffix = `**/**.{js,jsx,ts,tsx}`;\n const combined = _.map(_.castArray(namespaceConfig), (v) => {\n v = v.endsWith(\"/\") ? v : v + \"/\";\n return v + suffix;\n });\n log.info(\"正在处理 namespace: %s\", pc.green(namespace));\n log.info(\"预计处理的文件路径: %s\", pc.green(combined.join(\"\\n\")));\n\n const files = await globby(\n [\n \"!**/node_modules/**\",\n \"!**.d.ts\",\n \"!**/.next/**\",\n \"!**/out/**\",\n //\n ].concat(combined),\n { cwd: i18nConfig.cwd }\n );\n\n log.info(\"预计共处理 %s 个文件\", pc.green(files.length));\n\n let transformedFileSet = new Set<string>();\n\n await pMap(files, async (file) => {\n const content = await fs.readFile(file, \"utf-8\");\n\n const newContent = await autoNamespace(\n content,\n namespace,\n i18nConfig!.namespaceSeparator!\n );\n\n if (newContent) {\n await fs.writeFile(file, newContent);\n await formatFile(file);\n transformedFileSet.add(file);\n }\n });\n log.info(\n \"已为 %s 个文件 自动添加 namespace\",\n pc.green(transformedFileSet.size)\n );\n }\n}\n","/**\n * 目前 支持 . 分割的 namespace\n */\nexport function autoNamespaceByReg(code: string, namespace: string) {\n let hasChanged = false;\n\n /**\n * replace case:\n * t`login` => t`Merchants.login`\n * t`hello ${name}` => t`Merchants.hello ${name}`\n */\n code = code.replace(/\\Wt`(.+?)`/gm, (match, p1) => {\n // 如果 当前 有 $b. 则不替换\n if (/\\S\\.\\S/.test(p1)) {\n return match;\n }\n hasChanged = true;\n return match.replace(p1, `${namespace}.${p1}`);\n });\n\n /**\n * replace case:\n * t('login') => t('Merchants.login')\n * t(\"login\") => t('Merchants.login')\n */\n code = code.replace(/\\Wt\\(['\"](.+?)['\"][),]/gm, (match, p1) => {\n // 如果 当前 有 $b. 则不替换\n if (/\\S\\.\\S/.test(p1)) {\n return match;\n }\n hasChanged = true;\n return match.replace(p1, `${namespace}.${p1}`);\n });\n\n /**\n * 第二个方法已经满足这种情况了,先注释掉\n * replace case:\n * t('login',{ id:'1' }) => t('Merchants.login',{ id:'1' })\n * t(\"login\",{ id:'1' }) => t('Merchants.login',{ id:'1' })\n */\n // code = code.replace(/\\Wt\\(([\"'])(.+?)\\1(,|.*\\))/gm, (match, p1, p2, p3) => {\n // // 如果 当前 有 $b. 则不替换\n // if (/\\S\\.\\S/.test(p2)) {\n // return match;\n // }\n // hasChanged = true;\n // return `t('${namespace}.${p2}'${p3}`;\n // });\n\n if (hasChanged) {\n return code;\n }\n return \"\";\n}\n","import _ from \"lodash\";\nimport pMap from \"p-map\";\nimport { createLogger } from \"../shared\";\nimport { getConfig, I18nConfig } from \"../shared/config\";\nimport { googleSheet } from \"../shared/google/sheet\";\nimport { I18nData } from \"../shared/i18nData\";\nimport { letterToNumber } from \"../shared/letters\";\nimport { promptI18nConfigEnable } from \"../shared/promptConfigEnable\";\nimport { resolveSheetData } from \"../shared/resolveSheetData\";\nimport { sleep } from \"../shared/sleep\";\n\nconst log = createLogger(\"upload\");\n\n/**\n * 检测有本地有新增的key 则将新增的key更新到云端\n * 无则跳过\n */\nasync function batchUpdateKeys(config: I18nConfig) {\n let sheetData = await resolveSheetData(config);\n\n const allKeys: string[] = [];\n const i18nDataMap = new Map<string, I18nData>();\n await pMap(config.locales ?? [], async (locale) => {\n const i18nData = new I18nData(locale, config);\n i18nDataMap.set(locale, i18nData);\n const data = await i18nData.loadData();\n allKeys.push(...Object.keys(data));\n });\n\n let needSyncKeys = Array.from(new Set(allKeys)).filter((key) => {\n // 本地有新的key 服务器没有\n return !sheetData.keySet.has(key);\n });\n needSyncKeys = _.sortBy(needSyncKeys);\n\n if (needSyncKeys.length) {\n log.info(`即将同步本地新增加 ${needSyncKeys.length} 个 i18nKey 到云端`);\n await googleSheet.updateColumn(\n config.sheetId!,\n config.sheetRange!,\n letterToNumber(config.position!.key),\n sheetData.nextAppendRowIndex,\n needSyncKeys\n );\n log.info(\"同步新增加i18nKey成功\");\n\n // 批量同步新增的key的values到云端\n for (const lang of config.locales!) {\n const langFile = i18nDataMap.get(lang);\n const needSyncValues: string[] = [];\n needSyncKeys.forEach((k) => {\n if (langFile) {\n needSyncValues.push(langFile.data[k]);\n }\n });\n log.info(\n `即将同步本地 ${lang} 新增加 ${needSyncValues.length} 个值到云端`\n );\n await googleSheet.updateColumn(\n config.sheetId!,\n config.sheetRange!,\n letterToNumber(config.position![lang]),\n sheetData.nextAppendRowIndex,\n needSyncValues\n );\n }\n\n await sleep(1000);\n sheetData = await resolveSheetData(config);\n log.info(`已重新获取 ${config.sheetRange} 的数据`);\n }\n\n return { sheetData, i18nDataMap };\n}\n\nexport async function upload() {\n const config = await getConfig();\n let i18nConfigs = await promptI18nConfigEnable(config.i18n);\n\n for (const configItem of i18nConfigs) {\n const { sheetData, i18nDataMap } = await batchUpdateKeys(configItem);\n await pMap(configItem.locales ?? [], async (locale) => {\n const i18nData = i18nDataMap.get(locale)!;\n await i18nData.trySaveToGoogle(sheetData);\n });\n }\n\n log.info(\"上传成功\");\n}\n","#!/usr/bin/env node\nimport { version } from \"../package.json\";\nimport { download } from \"./commands/download\";\nimport { downloadFromPlatform } from \"./commands/downloadFromPlatform\";\nimport { extract } from \"./commands/extract\";\nimport { generateApi } from \"./commands/generateApi\";\nimport { initConfig } from \"./commands/initConfig\";\nimport { interactive } from \"./commands/interactive\";\nimport { namespace } from \"./commands/namespace\";\nimport { upload } from \"./commands/upload\";\nimport { cli } from \"./shared\";\n//#region 翻译相关\n\ncli\n .command(\"download\", \"生成翻译文件\")\n .example(\"dune download\")\n .action(download);\ncli\n .command(\"extract\", \"提取代码中的文案\")\n .option(\"--deleteUnused\", \"删除未使用的文案\")\n .example(\"dune extract\")\n .action(extract);\n\ncli\n .command(\"namespaceSwc\", \"添加namespace前缀,由swc驱动\")\n .example(\"dune namespaceSwc\")\n .action(() => {\n return namespace({ mode: \"swc\" });\n });\n\ncli\n .command(\"namespaceReg\", \"添加namespace前缀,由正则驱动\")\n .example(\"dune namespaceReg\")\n .action(() => {\n return namespace({ mode: \"reg\" });\n });\n\ncli.command(\"upload\", \"上传翻译文件\").example(\"dune upload\").action(upload);\n\ncli\n .command(\"downloadFromPlatform\", \"从翻译平台下载文件\")\n .example(\"dune downloadFromPlatform\")\n .action(downloadFromPlatform);\n//#endregion\n\n//#region api 相关\ncli\n .command(\"generateApi\", \"生成api文件\")\n .example(\"dune generateApi\")\n .action(generateApi);\n//#endregion\n\ncli.command(\"init\", \"初始化配置文件\").example(\"dune init\").action(initConfig);\n\ncli\n .command(\"interactive\", \"交互式操作\")\n .example(\"dune interactive\")\n .alias(\"i\")\n .action(interactive);\n\n// make default command run interactive\ncli.command(\"\").action(interactive);\n\ncli.version(version);\ncli.help();\n\n(async () => {\n try {\n // Parse CLI args without running the command\n cli.parse(process.argv, { run: false });\n // Run the command yourself\n // You only need `await` when your command action returns a Promise\n await cli.runMatchedCommand();\n } catch (error) {\n // Handle error here..\n // e.g.\n // console.error(error.stack)\n // process.exit(1)\n }\n})();\n"],"mappings":"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","names":["log","pMap","log","extract","pMap","fs","os","pMap","path","log","log","fs","pMap","path","schema","_","data","fs","path","log","enquirer","prompt","log","command","enquirer","fs","globby","_","pMap","pc","namespace","prompt","enquirer","log","_","namespace","pc","globby","pMap","fs","_","pMap","log","pMap","_"]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/commands/download.ts","../src/shared/resolveSheetData.ts","../src/shared/promptConfigEnable.ts","../src/commands/extract/index.ts","../src/commands/generateApi/index.ts","../src/shared/formatFile.ts","../src/commands/initConfig.ts","../src/commands/interactive.ts","../src/commands/namespace.ts","../src/shared/autoNamespaceByReg.ts","../src/commands/upload.ts","../src/cli.ts"],"sourcesContent":["{\n \"name\": \"@dune2/cli\",\n \"version\": \"0.4.13\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/liaoyinglong/next-tools.git\",\n \"directory\": \"packages/cli\"\n },\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.js\"\n },\n \"./cli\": {\n \"import\": \"./dist/cli.js\"\n },\n \"./normalizeConfig\": {\n \"import\": \"./dist/normalizeConfig.js\"\n },\n \"./prettier\": {\n \"import\": \"./dist/prettier.js\",\n \"require\": \"./dist/prettier.cjs\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"types\": \"dist/index.d.ts\",\n \"bin\": {\n \"dune\": \"./dist/cli.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"shx rm -rf ./dist && tsup --splitting\",\n \"dev\": \"pnpm run build --watch\",\n \"lint\": \"tsc --diagnostics --noEmit\",\n \"test\": \"vitest run\",\n \"test:u\": \"vitest -u\"\n },\n \"dependencies\": {\n \"@apidevtools/swagger-parser\": \"^10.1.0\",\n \"@dune2/wasm\": \"workspace:*\",\n \"axios\": \"^1.6.2\",\n \"cac\": \"^6.7.14\",\n \"cli-table3\": \"^0.6.3\",\n \"connect\": \"^3.7.0\",\n \"debug\": \"^4.3.4\",\n \"enquirer\": \"^2.3.6\",\n \"fs-extra\": \"^11.2.0\",\n \"globby\": \"^14.0.1\",\n \"googleapis\": \"^108.0.0\",\n \"joycon\": \"^3.1.1\",\n \"json-schema-to-typescript\": \"^14.0.4\",\n \"lodash\": \"^4.17.21\",\n \"open\": \"^10.1.0\",\n \"p-map\": \"^7.0.2\",\n \"path-to-regexp\": \"^6.2.1\",\n \"picocolors\": \"^1.0.0\"\n },\n \"devDependencies\": {\n \"@types/debug\": \"^4.1.7\",\n \"@types/lodash\": \"^4.14.186\",\n \"gaxios\": \"*\",\n \"google-auth-library\": \"*\",\n \"openapi-types\": \"^12.0.2\",\n \"prettier\": \"^3\",\n \"tsup\": \"8\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}\n","import pMap from \"p-map\";\nimport { createLogger } from \"../shared\";\nimport { getConfig } from \"../shared/config\";\nimport { I18nData } from \"../shared/i18nData\";\nimport { resolveSheetData } from \"../shared/resolveSheetData\";\nimport { promptI18nConfigEnable } from \"../shared/promptConfigEnable\";\n\nconst log = createLogger(\"generate\");\n\nexport async function download() {\n const config = await getConfig();\n\n let i18nConfigs = await promptI18nConfigEnable(config.i18n);\n\n let i = 0;\n for (const configItem of i18nConfigs) {\n i++;\n if (!configItem.sheetId || !configItem.sheetRange) {\n log.error(`config.${i} sheetId 或 sheetRange 为空,请检查`);\n continue;\n }\n const sheetData = await resolveSheetData(configItem);\n\n const statistics = await pMap(\n configItem.locales ?? [],\n async (locale, index) => {\n const i18nData = new I18nData(locale, configItem);\n await i18nData.updateFromSheetData(sheetData.getLangDataJSON(locale));\n await i18nData.saveToDisk();\n return i18nData;\n }\n );\n I18nData.printStatistic(`${configItem.sheetRange} 生成结果: `, statistics);\n }\n}\n","import { I18nConfig } from \"./config\";\nimport { googleSheet } from \"./google/sheet\";\nimport { createLogger } from \"./index\";\nimport { letterToNumber } from \"./letters\";\n\nconst log = createLogger(\"shared:resolveSheetData\");\n\nclass SheetI18nItem {\n value: string;\n\n colIndex: number;\n\n constructor(\n private spreadsheetId: string,\n private range: string,\n public key: string,\n colIndex: number | string,\n public row: string[],\n private rowIndex: number\n ) {\n this.colIndex = letterToNumber(colIndex);\n // TODO: 待确定 无值的key是否要生成\n // value = undefined 即不会生成\n this.value = this.row[this.colIndex] || \"\";\n }\n\n /**\n * 尝试更新 单元格的值\n * 如果一样则不更新\n */\n async tryUpdate(newValue: string) {\n if (newValue === this.value) {\n // 云端的值跟本地一样 不需要同步\n return;\n }\n\n await googleSheet.updateCell(\n this.spreadsheetId,\n this.range,\n this.colIndex,\n this.rowIndex,\n newValue\n );\n }\n}\n\nexport async function resolveSheetData(config: I18nConfig): Promise<SheetData> {\n const { position } = config;\n const parseStartIndex = config.parseStartIndex ?? 2;\n\n log.info(`读取 ${config.sheetRange} sheet数据`);\n\n const res = await googleSheet.get({\n spreadsheetId: config.sheetId,\n range: config.sheetRange,\n });\n if (!res.data.values) {\n log.error(\n `${config.sheetRange} sheet数据为空,请检查,应该最少有一行头部数据`\n );\n return new SheetData(config, 2);\n }\n\n const sheetData = new SheetData(config, res.data.values.length + 1);\n\n res.data.values.forEach((row: string[], rowIndex) => {\n // excel 的开始索引是1,所以要 +1\n const trulyRowIndex = rowIndex + 1;\n if (parseStartIndex > trulyRowIndex) {\n // 还未到可以开始解析的行数\n return;\n }\n\n const i18nKey = row[letterToNumber(position!.key)];\n\n if (i18nKey) {\n if (sheetData.keySet.has(i18nKey)) {\n log.error(\n `表格 ${config.sheetRange} 发现重复的i18nKey: ${i18nKey}, 将覆盖前面的值`\n );\n } else {\n sheetData.keySet.add(i18nKey);\n }\n\n config.locales?.forEach((lang) => {\n sheetData.setI18nItem(\n lang,\n new SheetI18nItem(\n config.sheetId!,\n config.sheetRange!,\n i18nKey,\n position![lang],\n row,\n trulyRowIndex\n )\n );\n });\n }\n });\n\n return sheetData;\n}\n\nexport class SheetData {\n keySet = new Set<string>();\n\n constructor(\n private config: I18nConfig,\n // 当前有多少行 新增的时候往后面添加\n public nextAppendRowIndex: number\n ) {}\n\n private value = new Map(\n this.config.locales!.map((lang) => {\n return [lang, new Map<string, SheetI18nItem>()];\n })\n );\n\n getI18nItem(lang: string, i18nKey: string) {\n return this.value.get(lang)!.get(i18nKey);\n }\n\n setI18nItem(lang: string, i18nItem: SheetI18nItem) {\n this.value.get(lang)!.set(i18nItem.key, i18nItem);\n }\n\n hasI18nItem(lang: string, i18nKey: string) {\n return this.value.get(lang)!.has(i18nKey);\n }\n\n getLangDataJSON(lang: string) {\n const res = {} as Record<string, string>;\n this.value.get(lang)!.forEach((i18nItem) => {\n res[i18nItem.key] = i18nItem.value;\n });\n return res;\n }\n}\n","import enquirer from \"enquirer\";\nimport { ApiConfig, I18nConfig } from \"./config\";\nconst { prompt } = enquirer;\n\ninterface Opt<T> {\n configArr: (T & { enabled?: boolean })[];\n getChoiceItem: (item: T) => {\n name: string;\n message?: string;\n value?: string;\n hint?: string;\n };\n checkIsEnabled: (enabledArr: string[], item: T) => boolean;\n}\n\nexport async function promptConfigEnable<T>(opt: Opt<T>) {\n const { configArr, getChoiceItem } = opt;\n // 只有一条配置的时候不用选择\n if (configArr.length <= 1) {\n return configArr;\n }\n\n const choices = [\n {\n name: \"全部\",\n message: \"全部\",\n choices: configArr.map((item) => {\n return getChoiceItem(item);\n }),\n },\n ];\n const res = await prompt<{ enabled: string[] }>({\n type: \"multiselect\",\n message: \"选择要生效的配置项\",\n // @ts-ignore\n hint: \"(空格选中,回车确认)\",\n name: \"enabled\",\n validate(value) {\n return value.length === 0 ? `至少选择一项` : true;\n },\n choices,\n });\n\n configArr.forEach((item) => {\n item.enabled = opt.checkIsEnabled(res.enabled, item);\n });\n\n return configArr.filter((c) => c.enabled);\n}\n\nexport function promptI18nConfigEnable(configArr: I18nConfig[] | undefined) {\n return promptConfigEnable({\n configArr: configArr ?? [],\n getChoiceItem: (item) => {\n return {\n name: item.i18nDir!,\n hint: `sheetRange: ${item.sheetRange}`,\n };\n },\n checkIsEnabled: (enabledArr, item) => {\n return enabledArr.includes(item.i18nDir!);\n },\n });\n}\n\nexport function promptApiConfigEnable(configArr: ApiConfig[] | undefined) {\n return promptConfigEnable({\n configArr: configArr ?? [],\n getChoiceItem: (item) => {\n return {\n name: item.output!,\n hint: `swaggerJSONPath: ${item.swaggerJSONPath}`,\n };\n },\n checkIsEnabled: (enabledArr, item) => {\n return enabledArr.includes(item.output!);\n },\n });\n}\n","import fs from \"fs-extra\";\nimport { globby } from \"globby\";\nimport os from \"os\";\nimport pMap from \"p-map\";\nimport path from \"path\";\nimport pc from \"picocolors\";\nimport { createLogger } from \"../../shared\";\nimport { getConfig, I18nConfig } from \"../../shared/config\";\nimport { ExtractedMap, I18nData } from \"../../shared/i18nData\";\nimport { promptI18nConfigEnable } from \"../../shared/promptConfigEnable\";\n\nconst log = createLogger(\"extract\");\n\n/**\n * 提取文案\n */\nexport async function extract(opts?: { deleteUnused: boolean }) {\n const config = await getConfig();\n const { extract } = await import(\"@dune2/wasm\");\n\n let i18nConfigs = await promptI18nConfigEnable(\n config.i18n?.filter((item) => !item.disableExtract)\n );\n\n // 这是使得任务串行,方便看日志\n for (const configItem of i18nConfigs) {\n const files = await globby(\n [\n `./src/**/**.{js,jsx,ts,tsx}`,\n \"!**/node_modules/**\",\n \"!**.d.ts\",\n \"!**/.next/**\",\n \"!**/out/**\",\n ].concat(configItem.include ?? []),\n { cwd: configItem.cwd }\n );\n log.info(\"预计共解析 %s 个文件\", pc.green(files.length));\n let errMsgs: string[] = [];\n const extractedI18nDataMap: ExtractedMap = new Map();\n\n await pMap(\n files,\n async (file) => {\n const content = await fs.readFile(file, \"utf-8\");\n const res = await extract(content, file);\n if (res.data.size) {\n log.info(\n \"从 %s 中提取到 %s 条文案\",\n pc.dim(file),\n pc.green(res.data.size)\n );\n res.data.forEach((value, key) => {\n let cur = extractedI18nDataMap.get(key)!;\n const hasCache = !!cur;\n if (!hasCache) {\n cur = { ...value, files: [] };\n }\n cur.files.push(\n path.resolve(file) + \":\" + value.line + \":\" + value.column\n );\n // 优先使用 提取出来的文案\n cur.messages = value.messages || cur.messages;\n\n if (!hasCache) {\n extractedI18nDataMap.set(key, cur);\n }\n });\n }\n if (res.errMsg) {\n errMsgs.push(res.errMsg);\n }\n },\n { concurrency: 20 }\n );\n\n await saveExtractedMetaData(configItem, extractedI18nDataMap);\n\n const i18nDataArr = await pMap(configItem.locales ?? [], async (locale) => {\n const i18nData = new I18nData(locale, configItem, opts?.deleteUnused);\n await i18nData.updateByExtractedData(extractedI18nDataMap);\n await i18nData.saveToDisk();\n return i18nData;\n });\n if (errMsgs.length) {\n console.log(pc.bold(\"以下未能成功提取的文案,请手动处理:\"));\n console.log(errMsgs.join(os.EOL));\n }\n I18nData.printStatistic(\"提取结果: \", i18nDataArr);\n\n await import(\"./uploadToTranslatePlatform\").then((mod) =>\n mod.uploadToTranslatePlatform(configItem, i18nDataArr)\n );\n }\n}\n\n/**\n * 保存相关的提取信息\n */\nasync function saveExtractedMetaData(\n config: I18nConfig,\n extractedI18nDataMap: ExtractedMap\n) {\n const { i18nDir } = config;\n // case:\n // input: \"./src/i18n\"\n // output: \"src_i18n.extractedLog.json\"\n const prefix = i18nDir!.replace(\"./\", \"\").replace(/\\//g, \"_\");\n const filename = `${prefix}.extractedLog.json`;\n\n const metaDataJsonPath = path.join(i18nDir!, filename);\n\n await fs.ensureFile(metaDataJsonPath);\n\n // extractedI18nDataMap 是个 Map 需要转成换json\n let data = Array.from(extractedI18nDataMap.entries()).map(\n ([key, value]) => value\n );\n // 按照 id 排序\n data = data.sort((a, b) => {\n return a.id.localeCompare(b.id);\n });\n\n await fs.writeJSON(\n metaDataJsonPath,\n\n data,\n {\n spaces: 2,\n }\n );\n}\n","import SwaggerParser from \"@apidevtools/swagger-parser\";\nimport fs from \"fs-extra\";\nimport { compile } from \"json-schema-to-typescript\";\nimport _ from \"lodash\";\nimport { OpenAPIV3 } from \"openapi-types\";\nimport * as os from \"os\";\nimport pMap from \"p-map\";\nimport path from \"path\";\nimport { createLogger } from \"../../shared\";\nimport { ApiConfig, getConfig } from \"../../shared/config\";\nimport { formatFile } from \"../../shared/formatFile\";\nimport { promptApiConfigEnable } from \"../../shared/promptConfigEnable\";\n\nconst log = createLogger(\"generateApi\");\n\nexport async function generateApi() {\n const config = await getConfig();\n const apiConfigs = await promptApiConfigEnable(config.api);\n\n for (const apiConfig of apiConfigs) {\n log.info(`清除旧的api文件: ${apiConfig.output}`);\n await fs.emptydir(apiConfig.output!);\n }\n\n for (const apiConfig of apiConfigs) {\n log.info(\"开始解析 %s\", apiConfig.swaggerJSONPath);\n const parsed = (await SwaggerParser.dereference(apiConfig.swaggerJSONPath, {\n resolve: {\n http: {\n timeout: 30 * 1000,\n },\n },\n })) as OpenAPIV3.Document;\n\n await pMap(Object.entries(parsed.paths), async ([url, pathItemObject]) => {\n log.info(\"开始生成 %s\", url);\n if (pathItemObject) {\n await pMap(\n [\"get\", \"put\", \"post\", \"delete\", \"patch\"],\n async (method) => {\n const operationObject = pathItemObject[method];\n if (operationObject) {\n const code = await generateApiRequestCode({\n url: url,\n method: method,\n operationObject: operationObject,\n apiConfig,\n });\n const outputPath = path\n .join(\n apiConfig.output!,\n url,\n apiConfig.enableTs ? `${method}.ts` : `${method}.js`\n )\n .replace(/:/g, \"_\");\n await fs.ensureFile(outputPath);\n await fs.writeFile(outputPath, code);\n }\n }\n );\n }\n });\n\n if (apiConfig.format) {\n await formatFile(apiConfig.output!);\n }\n }\n\n log.info(\"generateApi Done\");\n}\n\n/**\n * 根据请求方法,生成请求代码\n */\nexport async function generateApiRequestCode(options: {\n url: string;\n method: string;\n operationObject: OpenAPIV3.OperationObject;\n apiConfig: ApiConfig;\n}): Promise<string> {\n const { method, operationObject, apiConfig } = options;\n\n const url = (() => {\n if (typeof apiConfig.urlTransformer === \"string\") {\n return `${apiConfig.urlTransformer}${options.url}`;\n }\n if (typeof apiConfig.urlTransformer === \"function\") {\n return apiConfig.urlTransformer(options.url);\n }\n return options.url;\n })();\n\n const seeUrl = apiConfig.swaggerUiUrl\n ? `${apiConfig.swaggerUiUrl}#/${operationObject.tags?.join(\"/\") ?? \"\"}/${\n operationObject.operationId\n }`\n : \"\";\n\n // 生成的请求构造器的名称,需要使用原始url\n let requestBuilderName = _.camelCase(`${options.url}_${method}_api`);\n\n // 判断是否有效的js变量\n if (!/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(requestBuilderName)) {\n // 不是有效的js变量,使用 _ + 数字\n requestBuilderName = `_${requestBuilderName}`;\n }\n\n //#region url上参数 例如 /api/v1/users/{userId}\n const urlPathParams = getUrlPathParams(\n (operationObject.parameters as never) ?? []\n );\n const urlPathParamsCode = urlPathParams.length\n ? `urlPathParams: ${JSON.stringify(urlPathParams)},`\n : \"\";\n //#endregion\n\n let code: string[] = [\n \"// 这个文件由 @dune2/cli 自动生成,不要手动修改,否则会被覆盖\",\n apiConfig.RequestBuilderImportPath!,\n apiConfig.requestFnImportPath!,\n apiConfig.queryClientImportPath!,\n\n \"/**\",\n ` * ${operationObject.summary}`,\n ` * @tags ${operationObject.tags?.join(\",\")}`,\n seeUrl && ` * @see ${seeUrl}`,\n ` */`,\n ].filter(Boolean);\n\n // builder 代码\n let builderCode = `\\\nexport const ${requestBuilderName} = new RequestBuilder({\n url: '${url}',\n method: '${method}',\n ${apiConfig.requestFnImportPath ? \"requestFn,\" : \"\"}\n ${urlPathParamsCode}\n ${apiConfig.queryClientImportPath ? \"queryClient,\" : \"\"}\n});`\n // 移除空行\n .replace(/,\\n\\s*}/, \",\" + os.EOL + \"}\");\n if (apiConfig.enableTs) {\n builderCode = builderCode.replace(\n \"new RequestBuilder(\",\n `new RequestBuilder<${requestBuilderName}.Req, ${requestBuilderName}.Res>(`\n );\n }\n code.push(builderCode);\n\n if (apiConfig.enableTs) {\n // post和put请求需要生成表单fieldsMap\n const isGenrateFieldsMap = [\"post\", \"put\"].includes(method);\n // 请求参数类型\n // 响应参数类型\n const [requestParamsTypeCode, responseParamsTypeCode] = await Promise.all([\n compileRequestParams(operationObject, isGenrateFieldsMap),\n compileResponseParams(operationObject, apiConfig),\n ]);\n\n code.push(`\nexport namespace ${requestBuilderName} {\n ${requestParamsTypeCode.code}\n \n ${responseParamsTypeCode}\n};`);\n\n if (isGenrateFieldsMap && !_.isEmpty(requestParamsTypeCode.fieldsMap)) {\n // 生成表单fieldsMap\n code.push(`\nexport const ${requestBuilderName}FieldsMap = ${JSON.stringify(\n requestParamsTypeCode.fieldsMap\n )}\n`);\n }\n }\n\n return code.join(os.EOL);\n}\n\nfunction getUrlPathParams(parameters: OpenAPIV3.ParameterObject[]) {\n return parameters\n .filter((item) => item.in === \"path\")\n .map((item) => item.name);\n}\n\n/**\n * 这个方法还不完善,只能处理简单的请求参数\n */\nasync function compileRequestParams(\n operationObject: OpenAPIV3.OperationObject,\n generateFieldsMap = false\n) {\n let schema;\n if (operationObject.requestBody) {\n //TODO: 这里也需要处理其他类型\n schema = (operationObject.requestBody as OpenAPIV3.RequestBodyObject)\n .content[\"application/json\"].schema;\n } else if (operationObject.parameters) {\n const extraProperties = {};\n const parameters: OpenAPIV3.ParameterObject[] = [];\n (operationObject.parameters as OpenAPIV3.ParameterObject[]).forEach(\n (item) => {\n if (![\"query\", \"path\"].includes(item.in)) {\n return;\n }\n if (_.get(item.schema, \"type\") === \"object\") {\n // swagger get 请求上 有些参数是 object 类型 应该拍平\n _.assign(extraProperties, _.get(item.schema, \"properties\", {}));\n } else {\n parameters.push(item);\n }\n }\n );\n\n // 必填参数中忽略 分页相关的参数\n const required = parameters\n .filter(\n (p) => p.required && ![\"pageNum\", \"pageSize\", \"count\"].includes(p.name)\n )\n .map((p) => p.name);\n const properties = Object.fromEntries(\n parameters\n // 后端 swagger 可能出现没有 schema 的情况,这里过滤掉\n .filter((p) => !!p.schema)\n .map((p) => {\n //TODO: 这里也要处理 ref 类型\n const schema = p.schema as OpenAPIV3.SchemaObject;\n return [\n p.name,\n {\n ...schema,\n description: p.description,\n // enum: schema.enum ?? [],\n },\n ];\n })\n );\n schema = {\n required,\n type: \"object\",\n properties: { ...properties, ...extraProperties },\n };\n }\n\n let code = \"\";\n const fieldsMap: Record<string, string> = {};\n if (schema) {\n try {\n code = await compile(schema, \"Req\", {\n bannerComment: \"\",\n ignoreMinAndMaxItems: !!1,\n additionalProperties: false,\n // format: false,\n });\n\n // 判断接口是否是分页请求\n const isPageSearchRequest = (data: any) => {\n // 入参有这些字段就认为是分页查询接口\n const keys = [\"pageNum\", \"pageSize\", \"count\"];\n return (\n _.get(data, \"type\") === \"object\" &&\n _.get(data, \"required\", []).filter((item) => keys.includes(item))\n .length === keys.length\n );\n };\n\n if (generateFieldsMap) {\n // 分页查询接口取params字段\n const params = isPageSearchRequest(schema)\n ? _.get(schema, \"properties.params.properties\", {})\n : schema.properties;\n _.forEach(params, (_, field) => {\n fieldsMap[field] = field;\n });\n }\n } catch (e) {\n log.error(\"生成请求参数类型失败,请检查 %o\", {\n summary: operationObject.summary,\n message: e.message,\n });\n }\n }\n\n return {\n code: code || \"export type Req = any;\",\n fieldsMap,\n };\n}\n\nasync function compileResponseParams(\n operationObject: OpenAPIV3.OperationObject,\n apiConfig: ApiConfig\n) {\n const temp = operationObject.responses[\"200\"] as OpenAPIV3.ResponseObject;\n let code = \"\";\n if (temp?.content) {\n // FIXME: 可能需要处理其他的content类型\n const temp2 = temp.content[\"application/json\"] || temp.content[\"*/*\"];\n const schema = temp2.schema as OpenAPIV3.SchemaObject;\n let data = apiConfig.responseSchemaTransformer!(schema);\n if (data) {\n // 这里需要深度clone的原因是:\n // 解析出来的scheme会尽可能的被复用,导致影响到下次解析\n data = _.cloneDeep(data);\n markCircularToRef(data);\n try {\n code = await compile(data, \"Res\", {\n bannerComment: \"\",\n ignoreMinAndMaxItems: !!1,\n additionalProperties: false,\n // format: false,\n });\n\n // 通过响应数据判断是否是分页查询接口\n const isPageSearchResponse = (data: any) => {\n // 有result字段且为数组,就认为是分页查询接口\n return (\n _.get(data, \"type\") === \"object\" &&\n _.get(data, \"properties.result.type\") === \"array\"\n );\n };\n\n // 新增后端分页查询返回的数据类型\n if (isPageSearchResponse(data)) {\n code += `${os.EOL}export type ResultItem = Res['result'][0]`;\n }\n } catch (e) {\n log.error(\"转换响应参数类型失败, 请检查 %o\", {\n summary: operationObject.summary,\n error: e.message,\n });\n }\n } else {\n log.error(\"responseSchemaTransformer 返回值为空, 请检查\");\n }\n }\n\n return code ? code : \"export type Res = any;\";\n}\n\nexport function markCircularToRef(\n obj,\n parentMark = \"#\",\n map = new Map([[obj, parentMark]]),\n set = new Set([obj])\n) {\n Object.keys(obj).forEach((key) => {\n const value = obj[key];\n if (typeof value === \"object\" && !Array.isArray(value)) {\n if (set.has(value)) {\n obj[key] = { $ref: map.get(value) };\n return;\n }\n const tempMark = parentMark + \"/\" + key;\n set.add(value);\n map.set(value, tempMark);\n markCircularToRef(value, tempMark, map, set);\n }\n });\n return map;\n}\n","import { createLogger } from \".\";\nimport * as child_process from \"child_process\";\n\nconst log = createLogger(\"formatFile\");\n\nexport function formatFile(filename: string) {\n // 格式化代码\n log.info(`尝试格式化代码: %s`, filename);\n child_process.exec(`prettier --write '${filename}'`, (error) => {\n if (error) {\n log.error(`格式化代码失败: ${error}`);\n log.error(`请手动执行: prettier --write ${filename}`);\n log.error(`或者在配置文件中关闭格式化功能`);\n } else {\n log.info(`格式化代码成功: %s`, filename);\n }\n });\n}\n","import { createLogger } from \"../shared\";\nimport { getConfig, configName } from \"../shared/config\";\nimport fs from \"fs-extra\";\nimport path from \"path\";\n\nconst log = createLogger(\"initConfig\");\n\nconst tpl = `\\\n/**\n * @param {import('@dune2/cli').Config} config\n */\nfunction defineConfig(config) {\n return config;\n}\nmodule.exports = defineConfig({ i18n: [], api:[] });\n`;\n\nexport const initConfig = async () => {\n const config = await getConfig();\n const configPath = path.join(config.cwd!, configName);\n log.info(`config file path: ${configPath}`);\n if (await fs.pathExists(configPath)) {\n log.info(`config file already exists, skip`);\n return;\n }\n await fs.writeFile(configPath, tpl);\n log.info(`config file created`);\n};\n","import { cli, createLogger } from \"../shared\";\nimport enquirer from \"enquirer\";\nconst { prompt } = enquirer;\n\nconst log = createLogger(\"interactive\");\n\nexport const interactive = async (args: any) => {\n const commands = cli.commands.filter((command) => {\n if (command.name) {\n return !command.name.startsWith(\"@@\") && command.name !== \"interactive\";\n }\n return false;\n });\n\n const commandMap = new Map<string, typeof commands[number]>();\n const res = await prompt<{ command: string }>({\n type: \"autocomplete\",\n name: \"command\",\n message: \"选择要执行的命令:\",\n choices: commands.map((command) => {\n commandMap.set(command.name, command);\n return {\n name: command.name,\n value: command.name,\n message: command.description,\n hint: `等同命令 ${cli.name} ${command.name}`,\n };\n }),\n });\n const command = commandMap.get(res.command);\n if (!command) {\n log.error(\"未找到命令 %s\", res.command);\n return;\n }\n command.commandAction?.apply(cli, args);\n};\n","import enquirer from \"enquirer\";\nimport fs from \"fs-extra\";\nimport { globby } from \"globby\";\nimport _ from \"lodash\";\nimport pMap from \"p-map\";\nimport pc from \"picocolors\";\nimport { createLogger } from \"../shared\";\nimport { autoNamespaceByReg } from \"../shared/autoNamespaceByReg\";\nimport { getConfig } from \"../shared/config\";\nimport { formatFile } from \"../shared/formatFile\";\n\nconst { prompt } = enquirer;\n\nconst log = createLogger(\"namespace\");\ninterface Params {\n /**\n * 生成模式\n *\n * - swc 指的是用swc 插件来添加 前缀\n *\n * swc 生成的代码更加规范,但是会有一些问题\n *\n * - reg 指的是用正则来添加 前缀\n *\n * reg 目前只能初始 t function 的调用,不能处理 Trans 组件的复杂\n * @default swc\n */\n mode?: \"swc\" | \"reg\";\n}\n\nexport async function namespace(params: Params) {\n const { mode = \"swc\" } = params;\n const config = await getConfig();\n\n // 不允许提取的 配置 不需要选择\n let i18nConfigs = config.i18n?.filter((item) => !item.disableExtract);\n if (!i18nConfigs) {\n log.info(\"没有配置 i18n\");\n return;\n }\n\n // 选择 生效的 i18n 配置\n const { i18nDir } = await prompt<{ i18nDir: string }>({\n type: \"select\",\n name: \"i18nDir\",\n message: \"选择要生效的配置项\",\n choices: i18nConfigs.map((item) => {\n return {\n name: item.i18nDir!,\n hint: `sheetRange: ${item.sheetRange}`,\n };\n }),\n });\n let i18nConfig = i18nConfigs.find((item) => item.i18nDir === i18nDir);\n if (!i18nConfig) {\n log.info(\"没有找到对应的配置\");\n return;\n }\n\n // 选择 生效的 namespace\n const { namespaces } = await prompt<{ namespaces: string[] }>({\n type: \"multiselect\",\n message: \"选择要生效的配置项\",\n //@ts-ignore\n hint: \"(空格选中,回车确认)\",\n name: \"namespaces\",\n validate(value) {\n return value.length === 0 ? `至少选择一项` : true;\n },\n choices: _.map(i18nConfig.namespace, (v, k) => {\n return {\n name: k,\n };\n }),\n });\n\n const autoNamespace = await (() => {\n if (mode === \"swc\") {\n log.info(\"使用 swc 来处理\");\n return import(\"@dune2/wasm\").then((m) => m.autoNamespace);\n }\n log.info(\"使用 reg 来处理\");\n return autoNamespaceByReg;\n })();\n\n for (const namespace of namespaces) {\n const namespaceConfig = i18nConfig.namespace?.[namespace];\n\n const suffix = `**/**.{js,jsx,ts,tsx}`;\n const combined = _.map(_.castArray(namespaceConfig), (v) => {\n v = v.endsWith(\"/\") ? v : v + \"/\";\n return v + suffix;\n });\n log.info(\"正在处理 namespace: %s\", pc.green(namespace));\n log.info(\"预计处理的文件路径: %s\", pc.green(combined.join(\"\\n\")));\n\n const files = await globby(\n [\n \"!**/node_modules/**\",\n \"!**.d.ts\",\n \"!**/.next/**\",\n \"!**/out/**\",\n //\n ].concat(combined),\n { cwd: i18nConfig.cwd }\n );\n\n log.info(\"预计共处理 %s 个文件\", pc.green(files.length));\n\n let transformedFileSet = new Set<string>();\n\n await pMap(files, async (file) => {\n const content = await fs.readFile(file, \"utf-8\");\n\n const newContent = await autoNamespace(\n content,\n namespace,\n i18nConfig!.namespaceSeparator!\n );\n\n if (newContent) {\n await fs.writeFile(file, newContent);\n await formatFile(file);\n transformedFileSet.add(file);\n }\n });\n log.info(\n \"已为 %s 个文件 自动添加 namespace\",\n pc.green(transformedFileSet.size)\n );\n }\n}\n","/**\n * 目前 支持 . 分割的 namespace\n */\nexport function autoNamespaceByReg(code: string, namespace: string) {\n let hasChanged = false;\n\n /**\n * replace case:\n * t`login` => t`Merchants.login`\n * t`hello ${name}` => t`Merchants.hello ${name}`\n */\n code = code.replace(/\\Wt`(.+?)`/gm, (match, p1) => {\n // 如果 当前 有 $b. 则不替换\n if (/\\S\\.\\S/.test(p1)) {\n return match;\n }\n hasChanged = true;\n return match.replace(p1, `${namespace}.${p1}`);\n });\n\n /**\n * replace case:\n * t('login') => t('Merchants.login')\n * t(\"login\") => t('Merchants.login')\n */\n code = code.replace(/\\Wt\\(['\"](.+?)['\"][),]/gm, (match, p1) => {\n // 如果 当前 有 $b. 则不替换\n if (/\\S\\.\\S/.test(p1)) {\n return match;\n }\n hasChanged = true;\n return match.replace(p1, `${namespace}.${p1}`);\n });\n\n /**\n * 第二个方法已经满足这种情况了,先注释掉\n * replace case:\n * t('login',{ id:'1' }) => t('Merchants.login',{ id:'1' })\n * t(\"login\",{ id:'1' }) => t('Merchants.login',{ id:'1' })\n */\n // code = code.replace(/\\Wt\\(([\"'])(.+?)\\1(,|.*\\))/gm, (match, p1, p2, p3) => {\n // // 如果 当前 有 $b. 则不替换\n // if (/\\S\\.\\S/.test(p2)) {\n // return match;\n // }\n // hasChanged = true;\n // return `t('${namespace}.${p2}'${p3}`;\n // });\n\n if (hasChanged) {\n return code;\n }\n return \"\";\n}\n","import _ from \"lodash\";\nimport pMap from \"p-map\";\nimport { createLogger } from \"../shared\";\nimport { getConfig, I18nConfig } from \"../shared/config\";\nimport { googleSheet } from \"../shared/google/sheet\";\nimport { I18nData } from \"../shared/i18nData\";\nimport { letterToNumber } from \"../shared/letters\";\nimport { promptI18nConfigEnable } from \"../shared/promptConfigEnable\";\nimport { resolveSheetData } from \"../shared/resolveSheetData\";\nimport { sleep } from \"../shared/sleep\";\n\nconst log = createLogger(\"upload\");\n\n/**\n * 检测有本地有新增的key 则将新增的key更新到云端\n * 无则跳过\n */\nasync function batchUpdateKeys(config: I18nConfig) {\n let sheetData = await resolveSheetData(config);\n\n const allKeys: string[] = [];\n const i18nDataMap = new Map<string, I18nData>();\n await pMap(config.locales ?? [], async (locale) => {\n const i18nData = new I18nData(locale, config);\n i18nDataMap.set(locale, i18nData);\n const data = await i18nData.loadData();\n allKeys.push(...Object.keys(data));\n });\n\n let needSyncKeys = Array.from(new Set(allKeys)).filter((key) => {\n // 本地有新的key 服务器没有\n return !sheetData.keySet.has(key);\n });\n needSyncKeys = _.sortBy(needSyncKeys);\n\n if (needSyncKeys.length) {\n log.info(`即将同步本地新增加 ${needSyncKeys.length} 个 i18nKey 到云端`);\n await googleSheet.updateColumn(\n config.sheetId!,\n config.sheetRange!,\n letterToNumber(config.position!.key),\n sheetData.nextAppendRowIndex,\n needSyncKeys\n );\n log.info(\"同步新增加i18nKey成功\");\n\n // 批量同步新增的key的values到云端\n for (const lang of config.locales!) {\n const langFile = i18nDataMap.get(lang);\n const needSyncValues: string[] = [];\n needSyncKeys.forEach((k) => {\n if (langFile) {\n needSyncValues.push(langFile.data[k]);\n }\n });\n log.info(\n `即将同步本地 ${lang} 新增加 ${needSyncValues.length} 个值到云端`\n );\n await googleSheet.updateColumn(\n config.sheetId!,\n config.sheetRange!,\n letterToNumber(config.position![lang]),\n sheetData.nextAppendRowIndex,\n needSyncValues\n );\n }\n\n await sleep(1000);\n sheetData = await resolveSheetData(config);\n log.info(`已重新获取 ${config.sheetRange} 的数据`);\n }\n\n return { sheetData, i18nDataMap };\n}\n\nexport async function upload() {\n const config = await getConfig();\n let i18nConfigs = await promptI18nConfigEnable(config.i18n);\n\n for (const configItem of i18nConfigs) {\n const { sheetData, i18nDataMap } = await batchUpdateKeys(configItem);\n await pMap(configItem.locales ?? [], async (locale) => {\n const i18nData = i18nDataMap.get(locale)!;\n await i18nData.trySaveToGoogle(sheetData);\n });\n }\n\n log.info(\"上传成功\");\n}\n","#!/usr/bin/env node\nimport { version } from \"../package.json\";\nimport { download } from \"./commands/download\";\nimport { downloadFromPlatform } from \"./commands/downloadFromPlatform\";\nimport { extract } from \"./commands/extract\";\nimport { generateApi } from \"./commands/generateApi\";\nimport { initConfig } from \"./commands/initConfig\";\nimport { interactive } from \"./commands/interactive\";\nimport { namespace } from \"./commands/namespace\";\nimport { upload } from \"./commands/upload\";\nimport { cli } from \"./shared\";\n//#region 翻译相关\n\ncli\n .command(\"download\", \"生成翻译文件\")\n .example(\"dune download\")\n .action(download);\ncli\n .command(\"extract\", \"提取代码中的文案\")\n .option(\"--deleteUnused\", \"删除未使用的文案\")\n .example(\"dune extract\")\n .action(extract);\n\ncli\n .command(\"namespaceSwc\", \"添加namespace前缀,由swc驱动\")\n .example(\"dune namespaceSwc\")\n .action(() => {\n return namespace({ mode: \"swc\" });\n });\n\ncli\n .command(\"namespaceReg\", \"添加namespace前缀,由正则驱动\")\n .example(\"dune namespaceReg\")\n .action(() => {\n return namespace({ mode: \"reg\" });\n });\n\ncli.command(\"upload\", \"上传翻译文件\").example(\"dune upload\").action(upload);\n\ncli\n .command(\"downloadFromPlatform\", \"从翻译平台下载文件\")\n .example(\"dune downloadFromPlatform\")\n .action(downloadFromPlatform);\n//#endregion\n\n//#region api 相关\ncli\n .command(\"generateApi\", \"生成api文件\")\n .example(\"dune generateApi\")\n .action(generateApi);\n//#endregion\n\ncli.command(\"init\", \"初始化配置文件\").example(\"dune init\").action(initConfig);\n\ncli\n .command(\"interactive\", \"交互式操作\")\n .example(\"dune interactive\")\n .alias(\"i\")\n .action(interactive);\n\n// make default command run interactive\ncli.command(\"\").action(interactive);\n\ncli.version(version);\ncli.help();\n\n(async () => {\n try {\n // Parse CLI args without running the command\n cli.parse(process.argv, { run: false });\n // Run the command yourself\n // You only need `await` when your command action returns a Promise\n await cli.runMatchedCommand();\n } catch (error) {\n // Handle error here..\n // e.g.\n // console.error(error.stack)\n // process.exit(1)\n }\n})();\n"],"mappings":";;;;;;;;;;;;;;;;;AAEE,cAAW;;;ACFb,OAAO,UAAU;;;ACKjB,IAAM,MAAM,aAAa,yBAAyB;AAElD,IAAM,gBAAN,MAAoB;AAAA,EAKlB,YACU,eACA,OACD,KACP,UACO,KACC,UACR;AANQ;AACA;AACD;AAEA;AACC;AAER,SAAK,WAAW,eAAe,QAAQ;AAGvC,SAAK,QAAQ,KAAK,IAAI,KAAK,QAAQ,KAAK;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAU,UAAkB;AAChC,QAAI,aAAa,KAAK,OAAO;AAE3B;AAAA,IACF;AAEA,UAAM,YAAY;AAAA,MAChB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAsB,iBAAiB,QAAwC;AAC7E,QAAM,EAAE,SAAS,IAAI;AACrB,QAAM,kBAAkB,OAAO,mBAAmB;AAElD,MAAI,KAAK,gBAAM,OAAO,UAAU,oBAAU;AAE1C,QAAM,MAAM,MAAM,YAAY,IAAI;AAAA,IAChC,eAAe,OAAO;AAAA,IACtB,OAAO,OAAO;AAAA,EAChB,CAAC;AACD,MAAI,CAAC,IAAI,KAAK,QAAQ;AACpB,QAAI;AAAA,MACF,GAAG,OAAO,UAAU;AAAA,IACtB;AACA,WAAO,IAAI,UAAU,QAAQ,CAAC;AAAA,EAChC;AAEA,QAAM,YAAY,IAAI,UAAU,QAAQ,IAAI,KAAK,OAAO,SAAS,CAAC;AAElE,MAAI,KAAK,OAAO,QAAQ,CAAC,KAAe,aAAa;AAjEvD;AAmEI,UAAM,gBAAgB,WAAW;AACjC,QAAI,kBAAkB,eAAe;AAEnC;AAAA,IACF;AAEA,UAAM,UAAU,IAAI,eAAe,SAAU,GAAG,CAAC;AAEjD,QAAI,SAAS;AACX,UAAI,UAAU,OAAO,IAAI,OAAO,GAAG;AACjC,YAAI;AAAA,UACF,gBAAM,OAAO,UAAU,2CAAkB,OAAO;AAAA,QAClD;AAAA,MACF,OAAO;AACL,kBAAU,OAAO,IAAI,OAAO;AAAA,MAC9B;AAEA,mBAAO,YAAP,mBAAgB,QAAQ,CAAC,SAAS;AAChC,kBAAU;AAAA,UACR;AAAA,UACA,IAAI;AAAA,YACF,OAAO;AAAA,YACP,OAAO;AAAA,YACP;AAAA,YACA,SAAU,IAAI;AAAA,YACd;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAEO,IAAM,YAAN,MAAgB;AAAA,EAGrB,YACU,QAED,oBACP;AAHQ;AAED;AALT,kBAAS,oBAAI,IAAY;AAQzB,SAAQ,QAAQ,IAAI;AAAA,MAClB,KAAK,OAAO,QAAS,IAAI,CAAC,SAAS;AACjC,eAAO,CAAC,MAAM,oBAAI,IAA2B,CAAC;AAAA,MAChD,CAAC;AAAA,IACH;AAAA,EANG;AAAA,EAQH,YAAY,MAAc,SAAiB;AACzC,WAAO,KAAK,MAAM,IAAI,IAAI,EAAG,IAAI,OAAO;AAAA,EAC1C;AAAA,EAEA,YAAY,MAAc,UAAyB;AACjD,SAAK,MAAM,IAAI,IAAI,EAAG,IAAI,SAAS,KAAK,QAAQ;AAAA,EAClD;AAAA,EAEA,YAAY,MAAc,SAAiB;AACzC,WAAO,KAAK,MAAM,IAAI,IAAI,EAAG,IAAI,OAAO;AAAA,EAC1C;AAAA,EAEA,gBAAgB,MAAc;AAC5B,UAAM,MAAM,CAAC;AACb,SAAK,MAAM,IAAI,IAAI,EAAG,QAAQ,CAAC,aAAa;AAC1C,UAAI,SAAS,GAAG,IAAI,SAAS;AAAA,IAC/B,CAAC;AACD,WAAO;AAAA,EACT;AACF;;;ACzIA,OAAO,cAAc;AAErB,IAAM,EAAE,OAAO,IAAI;AAanB,eAAsB,mBAAsB,KAAa;AACvD,QAAM,EAAE,WAAW,cAAc,IAAI;AAErC,MAAI,UAAU,UAAU,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,QAAM,UAAU;AAAA,IACd;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS,UAAU,IAAI,CAAC,SAAS;AAC/B,eAAO,cAAc,IAAI;AAAA,MAC3B,CAAC;AAAA,IACH;AAAA,EACF;AACA,QAAM,MAAM,MAAM,OAA8B;AAAA,IAC9C,MAAM;AAAA,IACN,SAAS;AAAA;AAAA,IAET,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS,OAAO;AACd,aAAO,MAAM,WAAW,IAAI,yCAAW;AAAA,IACzC;AAAA,IACA;AAAA,EACF,CAAC;AAED,YAAU,QAAQ,CAAC,SAAS;AAC1B,SAAK,UAAU,IAAI,eAAe,IAAI,SAAS,IAAI;AAAA,EACrD,CAAC;AAED,SAAO,UAAU,OAAO,CAAC,MAAM,EAAE,OAAO;AAC1C;AAEO,SAAS,uBAAuB,WAAqC;AAC1E,SAAO,mBAAmB;AAAA,IACxB,WAAW,aAAa,CAAC;AAAA,IACzB,eAAe,CAAC,SAAS;AACvB,aAAO;AAAA,QACL,MAAM,KAAK;AAAA,QACX,MAAM,eAAe,KAAK,UAAU;AAAA,MACtC;AAAA,IACF;AAAA,IACA,gBAAgB,CAAC,YAAY,SAAS;AACpC,aAAO,WAAW,SAAS,KAAK,OAAQ;AAAA,IAC1C;AAAA,EACF,CAAC;AACH;AAEO,SAAS,sBAAsB,WAAoC;AACxE,SAAO,mBAAmB;AAAA,IACxB,WAAW,aAAa,CAAC;AAAA,IACzB,eAAe,CAAC,SAAS;AACvB,aAAO;AAAA,QACL,MAAM,KAAK;AAAA,QACX,MAAM,oBAAoB,KAAK,eAAe;AAAA,MAChD;AAAA,IACF;AAAA,IACA,gBAAgB,CAAC,YAAY,SAAS;AACpC,aAAO,WAAW,SAAS,KAAK,MAAO;AAAA,IACzC;AAAA,EACF,CAAC;AACH;;;AFvEA,IAAMA,OAAM,aAAa,UAAU;AAEnC,eAAsB,WAAW;AAC/B,QAAM,SAAS,MAAM,UAAU;AAE/B,MAAI,cAAc,MAAM,uBAAuB,OAAO,IAAI;AAE1D,MAAI,IAAI;AACR,aAAW,cAAc,aAAa;AACpC;AACA,QAAI,CAAC,WAAW,WAAW,CAAC,WAAW,YAAY;AACjD,MAAAA,KAAI,MAAM,UAAU,CAAC,iEAA8B;AACnD;AAAA,IACF;AACA,UAAM,YAAY,MAAM,iBAAiB,UAAU;AAEnD,UAAM,aAAa,MAAM;AAAA,MACvB,WAAW,WAAW,CAAC;AAAA,MACvB,OAAO,QAAQ,UAAU;AACvB,cAAM,WAAW,IAAI,SAAS,QAAQ,UAAU;AAChD,cAAM,SAAS,oBAAoB,UAAU,gBAAgB,MAAM,CAAC;AACpE,cAAM,SAAS,WAAW;AAC1B,eAAO;AAAA,MACT;AAAA,IACF;AACA,aAAS,eAAe,GAAG,WAAW,UAAU,+BAAW,UAAU;AAAA,EACvE;AACF;;;AGlCA,OAAO,QAAQ;AACf,SAAS,cAAc;AACvB,OAAO,QAAQ;AACf,OAAOC,WAAU;AACjB,OAAO,UAAU;AACjB,OAAO,QAAQ;AAMf,IAAMC,OAAM,aAAa,SAAS;AAKlC,eAAsB,QAAQ,MAAkC;AAhBhE;AAiBE,QAAM,SAAS,MAAM,UAAU;AAC/B,QAAM,EAAE,SAAAC,SAAQ,IAAI,MAAM,OAAO,aAAa;AAE9C,MAAI,cAAc,MAAM;AAAA,KACtB,YAAO,SAAP,mBAAa,OAAO,CAAC,SAAS,CAAC,KAAK;AAAA,EACtC;AAGA,aAAW,cAAc,aAAa;AACpC,UAAM,QAAQ,MAAM;AAAA,MAClB;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,EAAE,OAAO,WAAW,WAAW,CAAC,CAAC;AAAA,MACjC,EAAE,KAAK,WAAW,IAAI;AAAA,IACxB;AACA,IAAAD,KAAI,KAAK,wDAAgB,GAAG,MAAM,MAAM,MAAM,CAAC;AAC/C,QAAI,UAAoB,CAAC;AACzB,UAAM,uBAAqC,oBAAI,IAAI;AAEnD,UAAME;AAAA,MACJ;AAAA,MACA,OAAO,SAAS;AACd,cAAM,UAAU,MAAM,GAAG,SAAS,MAAM,OAAO;AAC/C,cAAM,MAAM,MAAMD,SAAQ,SAAS,IAAI;AACvC,YAAI,IAAI,KAAK,MAAM;AACjB,UAAAD,KAAI;AAAA,YACF;AAAA,YACA,GAAG,IAAI,IAAI;AAAA,YACX,GAAG,MAAM,IAAI,KAAK,IAAI;AAAA,UACxB;AACA,cAAI,KAAK,QAAQ,CAAC,OAAO,QAAQ;AAC/B,gBAAI,MAAM,qBAAqB,IAAI,GAAG;AACtC,kBAAM,WAAW,CAAC,CAAC;AACnB,gBAAI,CAAC,UAAU;AACb,oBAAM,EAAE,GAAG,OAAO,OAAO,CAAC,EAAE;AAAA,YAC9B;AACA,gBAAI,MAAM;AAAA,cACR,KAAK,QAAQ,IAAI,IAAI,MAAM,MAAM,OAAO,MAAM,MAAM;AAAA,YACtD;AAEA,gBAAI,WAAW,MAAM,YAAY,IAAI;AAErC,gBAAI,CAAC,UAAU;AACb,mCAAqB,IAAI,KAAK,GAAG;AAAA,YACnC;AAAA,UACF,CAAC;AAAA,QACH;AACA,YAAI,IAAI,QAAQ;AACd,kBAAQ,KAAK,IAAI,MAAM;AAAA,QACzB;AAAA,MACF;AAAA,MACA,EAAE,aAAa,GAAG;AAAA,IACpB;AAEA,UAAM,sBAAsB,YAAY,oBAAoB;AAE5D,UAAM,cAAc,MAAME,MAAK,WAAW,WAAW,CAAC,GAAG,OAAO,WAAW;AACzE,YAAM,WAAW,IAAI,SAAS,QAAQ,YAAY,6BAAM,YAAY;AACpE,YAAM,SAAS,sBAAsB,oBAAoB;AACzD,YAAM,SAAS,WAAW;AAC1B,aAAO;AAAA,IACT,CAAC;AACD,QAAI,QAAQ,QAAQ;AAClB,cAAQ,IAAI,GAAG,KAAK,8GAAoB,CAAC;AACzC,cAAQ,IAAI,QAAQ,KAAK,GAAG,GAAG,CAAC;AAAA,IAClC;AACA,aAAS,eAAe,8BAAU,WAAW;AAE7C,UAAM,OAAO,yCAA6B,EAAE;AAAA,MAAK,CAAC,QAChD,IAAI,0BAA0B,YAAY,WAAW;AAAA,IACvD;AAAA,EACF;AACF;AAKA,eAAe,sBACb,QACA,sBACA;AACA,QAAM,EAAE,QAAQ,IAAI;AAIpB,QAAM,SAAS,QAAS,QAAQ,MAAM,EAAE,EAAE,QAAQ,OAAO,GAAG;AAC5D,QAAM,WAAW,GAAG,MAAM;AAE1B,QAAM,mBAAmB,KAAK,KAAK,SAAU,QAAQ;AAErD,QAAM,GAAG,WAAW,gBAAgB;AAGpC,MAAI,OAAO,MAAM,KAAK,qBAAqB,QAAQ,CAAC,EAAE;AAAA,IACpD,CAAC,CAAC,KAAK,KAAK,MAAM;AAAA,EACpB;AAEA,SAAO,KAAK,KAAK,CAAC,GAAG,MAAM;AACzB,WAAO,EAAE,GAAG,cAAc,EAAE,EAAE;AAAA,EAChC,CAAC;AAED,QAAM,GAAG;AAAA,IACP;AAAA,IAEA;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,IACV;AAAA,EACF;AACF;;;AClIA,OAAO,mBAAmB;AAC1B,OAAOC,SAAQ;AACf,SAAS,eAAe;AACxB,OAAO,OAAO;AAEd,YAAYC,SAAQ;AACpB,OAAOC,WAAU;AACjB,OAAOC,WAAU;;;ACNjB,YAAY,mBAAmB;AAE/B,IAAMC,OAAM,aAAa,YAAY;AAE9B,SAAS,WAAW,UAAkB;AAE3C,EAAAA,KAAI,KAAK,kDAAe,QAAQ;AAChC,EAAc,mBAAK,qBAAqB,QAAQ,KAAK,CAAC,UAAU;AAC9D,QAAI,OAAO;AACT,MAAAA,KAAI,MAAM,+CAAY,KAAK,EAAE;AAC7B,MAAAA,KAAI,MAAM,oDAA2B,QAAQ,EAAE;AAC/C,MAAAA,KAAI,MAAM,4FAAiB;AAAA,IAC7B,OAAO;AACL,MAAAA,KAAI,KAAK,kDAAe,QAAQ;AAAA,IAClC;AAAA,EACF,CAAC;AACH;;;ADJA,IAAMC,OAAM,aAAa,aAAa;AAEtC,eAAsB,cAAc;AAClC,QAAM,SAAS,MAAM,UAAU;AAC/B,QAAM,aAAa,MAAM,sBAAsB,OAAO,GAAG;AAEzD,aAAW,aAAa,YAAY;AAClC,IAAAA,KAAI,KAAK,4CAAc,UAAU,MAAM,EAAE;AACzC,UAAMC,IAAG,SAAS,UAAU,MAAO;AAAA,EACrC;AAEA,aAAW,aAAa,YAAY;AAClC,IAAAD,KAAI,KAAK,+BAAW,UAAU,eAAe;AAC7C,UAAM,SAAU,MAAM,cAAc,YAAY,UAAU,iBAAiB;AAAA,MACzE,SAAS;AAAA,QACP,MAAM;AAAA,UACJ,SAAS,KAAK;AAAA,QAChB;AAAA,MACF;AAAA,IACF,CAAC;AAED,UAAME,MAAK,OAAO,QAAQ,OAAO,KAAK,GAAG,OAAO,CAAC,KAAK,cAAc,MAAM;AACxE,MAAAF,KAAI,KAAK,+BAAW,GAAG;AACvB,UAAI,gBAAgB;AAClB,cAAME;AAAA,UACJ,CAAC,OAAO,OAAO,QAAQ,UAAU,OAAO;AAAA,UACxC,OAAO,WAAW;AAChB,kBAAM,kBAAkB,eAAe,MAAM;AAC7C,gBAAI,iBAAiB;AACnB,oBAAM,OAAO,MAAM,uBAAuB;AAAA,gBACxC;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cACF,CAAC;AACD,oBAAM,aAAaC,MAChB;AAAA,gBACC,UAAU;AAAA,gBACV;AAAA,gBACA,UAAU,WAAW,GAAG,MAAM,QAAQ,GAAG,MAAM;AAAA,cACjD,EACC,QAAQ,MAAM,GAAG;AACpB,oBAAMF,IAAG,WAAW,UAAU;AAC9B,oBAAMA,IAAG,UAAU,YAAY,IAAI;AAAA,YACrC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAED,QAAI,UAAU,QAAQ;AACpB,YAAM,WAAW,UAAU,MAAO;AAAA,IACpC;AAAA,EACF;AAEA,EAAAD,KAAI,KAAK,kBAAkB;AAC7B;AAKA,eAAsB,uBAAuB,SAKzB;AA/EpB;AAgFE,QAAM,EAAE,QAAQ,iBAAiB,UAAU,IAAI;AAE/C,QAAM,OAAO,MAAM;AACjB,QAAI,OAAO,UAAU,mBAAmB,UAAU;AAChD,aAAO,GAAG,UAAU,cAAc,GAAG,QAAQ,GAAG;AAAA,IAClD;AACA,QAAI,OAAO,UAAU,mBAAmB,YAAY;AAClD,aAAO,UAAU,eAAe,QAAQ,GAAG;AAAA,IAC7C;AACA,WAAO,QAAQ;AAAA,EACjB,GAAG;AAEH,QAAM,SAAS,UAAU,eACrB,GAAG,UAAU,YAAY,OAAK,qBAAgB,SAAhB,mBAAsB,KAAK,SAAQ,EAAE,IACjE,gBAAgB,WAClB,KACA;AAGJ,MAAI,qBAAqB,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI,MAAM,MAAM;AAGnE,MAAI,CAAC,6BAA6B,KAAK,kBAAkB,GAAG;AAE1D,yBAAqB,IAAI,kBAAkB;AAAA,EAC7C;AAGA,QAAM,gBAAgB;AAAA,IACnB,gBAAgB,cAAwB,CAAC;AAAA,EAC5C;AACA,QAAM,oBAAoB,cAAc,SACpC,kBAAkB,KAAK,UAAU,aAAa,CAAC,MAC/C;AAGJ,MAAI,OAAiB;AAAA,IACnB;AAAA,IACA,UAAU;AAAA,IACV,UAAU;AAAA,IACV,UAAU;AAAA,IAEV;AAAA,IACA,OAAO,gBAAgB,OAAO;AAAA,IAC9B,cAAa,qBAAgB,SAAhB,mBAAsB,KAAK,IAAI;AAAA,IAC5C,UAAU,YAAY,MAAM;AAAA,IAC5B;AAAA,EACF,EAAE,OAAO,OAAO;AAGhB,MAAI,cAAc,gBACL,kBAAkB;AAAA,UACvB,GAAG;AAAA,aACA,MAAM;AAAA,IACf,UAAU,sBAAsB,eAAe,EAAE;AAAA,IACjD,iBAAiB;AAAA,IACjB,UAAU,wBAAwB,iBAAiB,EAAE;AAAA,KAGpD,QAAQ,WAAW,MAAS,UAAM,GAAG;AACxC,MAAI,UAAU,UAAU;AACtB,kBAAc,YAAY;AAAA,MACxB;AAAA,MACA,sBAAsB,kBAAkB,SAAS,kBAAkB;AAAA,IACrE;AAAA,EACF;AACA,OAAK,KAAK,WAAW;AAErB,MAAI,UAAU,UAAU;AAEtB,UAAM,qBAAqB,CAAC,QAAQ,KAAK,EAAE,SAAS,MAAM;AAG1D,UAAM,CAAC,uBAAuB,sBAAsB,IAAI,MAAM,QAAQ,IAAI;AAAA,MACxE,qBAAqB,iBAAiB,kBAAkB;AAAA,MACxD,sBAAsB,iBAAiB,SAAS;AAAA,IAClD,CAAC;AAED,SAAK,KAAK;AAAA,mBACK,kBAAkB;AAAA,GAClC,sBAAsB,IAAI;AAAA;AAAA,GAE1B,sBAAsB;AAAA,GACtB;AAEC,QAAI,sBAAsB,CAAC,EAAE,QAAQ,sBAAsB,SAAS,GAAG;AAErE,WAAK,KAAK;AAAA,eACD,kBAAkB,eAAe,KAAK;AAAA,QAC7C,sBAAsB;AAAA,MACxB,CAAC;AAAA,CACN;AAAA,IACG;AAAA,EACF;AAEA,SAAO,KAAK,KAAQ,OAAG;AACzB;AAEA,SAAS,iBAAiB,YAAyC;AACjE,SAAO,WACJ,OAAO,CAAC,SAAS,KAAK,OAAO,MAAM,EACnC,IAAI,CAAC,SAAS,KAAK,IAAI;AAC5B;AAKA,eAAe,qBACb,iBACA,oBAAoB,OACpB;AACA,MAAI;AACJ,MAAI,gBAAgB,aAAa;AAE/B,aAAU,gBAAgB,YACvB,QAAQ,kBAAkB,EAAE;AAAA,EACjC,WAAW,gBAAgB,YAAY;AACrC,UAAM,kBAAkB,CAAC;AACzB,UAAM,aAA0C,CAAC;AACjD,IAAC,gBAAgB,WAA2C;AAAA,MAC1D,CAAC,SAAS;AACR,YAAI,CAAC,CAAC,SAAS,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG;AACxC;AAAA,QACF;AACA,YAAI,EAAE,IAAI,KAAK,QAAQ,MAAM,MAAM,UAAU;AAE3C,YAAE,OAAO,iBAAiB,EAAE,IAAI,KAAK,QAAQ,cAAc,CAAC,CAAC,CAAC;AAAA,QAChE,OAAO;AACL,qBAAW,KAAK,IAAI;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAGA,UAAM,WAAW,WACd;AAAA,MACC,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,WAAW,YAAY,OAAO,EAAE,SAAS,EAAE,IAAI;AAAA,IACxE,EACC,IAAI,CAAC,MAAM,EAAE,IAAI;AACpB,UAAM,aAAa,OAAO;AAAA,MACxB,WAEG,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,EACxB,IAAI,CAAC,MAAM;AAEV,cAAMI,UAAS,EAAE;AACjB,eAAO;AAAA,UACL,EAAE;AAAA,UACF;AAAA,YACE,GAAGA;AAAA,YACH,aAAa,EAAE;AAAA;AAAA,UAEjB;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACL;AACA,aAAS;AAAA,MACP;AAAA,MACA,MAAM;AAAA,MACN,YAAY,EAAE,GAAG,YAAY,GAAG,gBAAgB;AAAA,IAClD;AAAA,EACF;AAEA,MAAI,OAAO;AACX,QAAM,YAAoC,CAAC;AAC3C,MAAI,QAAQ;AACV,QAAI;AACF,aAAO,MAAM,QAAQ,QAAQ,OAAO;AAAA,QAClC,eAAe;AAAA,QACf,sBAAsB;AAAA,QACtB,sBAAsB;AAAA;AAAA,MAExB,CAAC;AAGD,YAAM,sBAAsB,CAAC,SAAc;AAEzC,cAAM,OAAO,CAAC,WAAW,YAAY,OAAO;AAC5C,eACE,EAAE,IAAI,MAAM,MAAM,MAAM,YACxB,EAAE,IAAI,MAAM,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,EAC7D,WAAW,KAAK;AAAA,MAEvB;AAEA,UAAI,mBAAmB;AAErB,cAAM,SAAS,oBAAoB,MAAM,IACrC,EAAE,IAAI,QAAQ,gCAAgC,CAAC,CAAC,IAChD,OAAO;AACX,UAAE,QAAQ,QAAQ,CAACC,IAAG,UAAU;AAC9B,oBAAU,KAAK,IAAI;AAAA,QACrB,CAAC;AAAA,MACH;AAAA,IACF,SAAS,GAAG;AACV,MAAAL,KAAI,MAAM,2FAAqB;AAAA,QAC7B,SAAS,gBAAgB;AAAA,QACzB,SAAS,EAAE;AAAA,MACb,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM,QAAQ;AAAA,IACd;AAAA,EACF;AACF;AAEA,eAAe,sBACb,iBACA,WACA;AACA,QAAM,OAAO,gBAAgB,UAAU,KAAK;AAC5C,MAAI,OAAO;AACX,MAAI,6BAAM,SAAS;AAEjB,UAAM,QAAQ,KAAK,QAAQ,kBAAkB,KAAK,KAAK,QAAQ,KAAK;AACpE,UAAM,SAAS,MAAM;AACrB,QAAI,OAAO,UAAU,0BAA2B,MAAM;AACtD,QAAI,MAAM;AAGR,aAAO,EAAE,UAAU,IAAI;AACvB,wBAAkB,IAAI;AACtB,UAAI;AACF,eAAO,MAAM,QAAQ,MAAM,OAAO;AAAA,UAChC,eAAe;AAAA,UACf,sBAAsB;AAAA,UACtB,sBAAsB;AAAA;AAAA,QAExB,CAAC;AAGD,cAAM,uBAAuB,CAACM,UAAc;AAE1C,iBACE,EAAE,IAAIA,OAAM,MAAM,MAAM,YACxB,EAAE,IAAIA,OAAM,wBAAwB,MAAM;AAAA,QAE9C;AAGA,YAAI,qBAAqB,IAAI,GAAG;AAC9B,kBAAQ,GAAM,OAAG;AAAA,QACnB;AAAA,MACF,SAAS,GAAG;AACV,QAAAN,KAAI,MAAM,uFAAsB;AAAA,UAC9B,SAAS,gBAAgB;AAAA,UACzB,OAAO,EAAE;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF,OAAO;AACL,MAAAA,KAAI,MAAM,8EAAsC;AAAA,IAClD;AAAA,EACF;AAEA,SAAO,OAAO,OAAO;AACvB;AAEO,SAAS,kBACd,KACA,aAAa,KACb,MAAM,oBAAI,IAAI,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,GACjC,MAAM,oBAAI,IAAI,CAAC,GAAG,CAAC,GACnB;AACA,SAAO,KAAK,GAAG,EAAE,QAAQ,CAAC,QAAQ;AAChC,UAAM,QAAQ,IAAI,GAAG;AACrB,QAAI,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AACtD,UAAI,IAAI,IAAI,KAAK,GAAG;AAClB,YAAI,GAAG,IAAI,EAAE,MAAM,IAAI,IAAI,KAAK,EAAE;AAClC;AAAA,MACF;AACA,YAAM,WAAW,aAAa,MAAM;AACpC,UAAI,IAAI,KAAK;AACb,UAAI,IAAI,OAAO,QAAQ;AACvB,wBAAkB,OAAO,UAAU,KAAK,GAAG;AAAA,IAC7C;AAAA,EACF,CAAC;AACD,SAAO;AACT;;;AErWA,OAAOO,SAAQ;AACf,OAAOC,WAAU;AAEjB,IAAMC,OAAM,aAAa,YAAY;AAErC,IAAM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUL,IAAM,aAAa,YAAY;AACpC,QAAM,SAAS,MAAM,UAAU;AAC/B,QAAM,aAAaD,MAAK,KAAK,OAAO,KAAM,UAAU;AACpD,EAAAC,KAAI,KAAK,qBAAqB,UAAU,EAAE;AAC1C,MAAI,MAAMF,IAAG,WAAW,UAAU,GAAG;AACnC,IAAAE,KAAI,KAAK,kCAAkC;AAC3C;AAAA,EACF;AACA,QAAMF,IAAG,UAAU,YAAY,GAAG;AAClC,EAAAE,KAAI,KAAK,qBAAqB;AAChC;;;AC1BA,OAAOC,eAAc;AACrB,IAAM,EAAE,QAAAC,QAAO,IAAID;AAEnB,IAAME,OAAM,aAAa,aAAa;AAE/B,IAAM,cAAc,OAAO,SAAc;AANhD;AAOE,QAAM,WAAW,IAAI,SAAS,OAAO,CAACC,aAAY;AAChD,QAAIA,SAAQ,MAAM;AAChB,aAAO,CAACA,SAAQ,KAAK,WAAW,IAAI,KAAKA,SAAQ,SAAS;AAAA,IAC5D;AACA,WAAO;AAAA,EACT,CAAC;AAED,QAAM,aAAa,oBAAI,IAAqC;AAC5D,QAAM,MAAM,MAAMF,QAA4B;AAAA,IAC5C,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS,SAAS,IAAI,CAACE,aAAY;AACjC,iBAAW,IAAIA,SAAQ,MAAMA,QAAO;AACpC,aAAO;AAAA,QACL,MAAMA,SAAQ;AAAA,QACd,OAAOA,SAAQ;AAAA,QACf,SAASA,SAAQ;AAAA,QACjB,MAAM,4BAAQ,IAAI,IAAI,IAAIA,SAAQ,IAAI;AAAA,MACxC;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACD,QAAM,UAAU,WAAW,IAAI,IAAI,OAAO;AAC1C,MAAI,CAAC,SAAS;AACZ,IAAAD,KAAI,MAAM,qCAAY,IAAI,OAAO;AACjC;AAAA,EACF;AACA,gBAAQ,kBAAR,mBAAuB,MAAM,KAAK;AACpC;;;ACnCA,OAAOE,eAAc;AACrB,OAAOC,SAAQ;AACf,SAAS,UAAAC,eAAc;AACvB,OAAOC,QAAO;AACd,OAAOC,WAAU;AACjB,OAAOC,SAAQ;;;ACFR,SAAS,mBAAmB,MAAcC,YAAmB;AAClE,MAAI,aAAa;AAOjB,SAAO,KAAK,QAAQ,gBAAgB,CAAC,OAAO,OAAO;AAEjD,QAAI,SAAS,KAAK,EAAE,GAAG;AACrB,aAAO;AAAA,IACT;AACA,iBAAa;AACb,WAAO,MAAM,QAAQ,IAAI,GAAGA,UAAS,IAAI,EAAE,EAAE;AAAA,EAC/C,CAAC;AAOD,SAAO,KAAK,QAAQ,4BAA4B,CAAC,OAAO,OAAO;AAE7D,QAAI,SAAS,KAAK,EAAE,GAAG;AACrB,aAAO;AAAA,IACT;AACA,iBAAa;AACb,WAAO,MAAM,QAAQ,IAAI,GAAGA,UAAS,IAAI,EAAE,EAAE;AAAA,EAC/C,CAAC;AAiBD,MAAI,YAAY;AACd,WAAO;AAAA,EACT;AACA,SAAO;AACT;;;AD1CA,IAAM,EAAE,QAAAC,QAAO,IAAIC;AAEnB,IAAMC,OAAM,aAAa,WAAW;AAiBpC,eAAsB,UAAU,QAAgB;AA9BhD;AA+BE,QAAM,EAAE,OAAO,MAAM,IAAI;AACzB,QAAM,SAAS,MAAM,UAAU;AAG/B,MAAI,eAAc,YAAO,SAAP,mBAAa,OAAO,CAAC,SAAS,CAAC,KAAK;AACtD,MAAI,CAAC,aAAa;AAChB,IAAAA,KAAI,KAAK,+BAAW;AACpB;AAAA,EACF;AAGA,QAAM,EAAE,QAAQ,IAAI,MAAMF,QAA4B;AAAA,IACpD,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS,YAAY,IAAI,CAAC,SAAS;AACjC,aAAO;AAAA,QACL,MAAM,KAAK;AAAA,QACX,MAAM,eAAe,KAAK,UAAU;AAAA,MACtC;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACD,MAAI,aAAa,YAAY,KAAK,CAAC,SAAS,KAAK,YAAY,OAAO;AACpE,MAAI,CAAC,YAAY;AACf,IAAAE,KAAI,KAAK,wDAAW;AACpB;AAAA,EACF;AAGA,QAAM,EAAE,WAAW,IAAI,MAAMF,QAAiC;AAAA,IAC5D,MAAM;AAAA,IACN,SAAS;AAAA;AAAA,IAET,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS,OAAO;AACd,aAAO,MAAM,WAAW,IAAI,yCAAW;AAAA,IACzC;AAAA,IACA,SAASG,GAAE,IAAI,WAAW,WAAW,CAAC,GAAG,MAAM;AAC7C,aAAO;AAAA,QACL,MAAM;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,QAAM,gBAAgB,OAAO,MAAM;AACjC,QAAI,SAAS,OAAO;AAClB,MAAAD,KAAI,KAAK,qCAAY;AACrB,aAAO,OAAO,aAAa,EAAE,KAAK,CAAC,MAAM,EAAE,aAAa;AAAA,IAC1D;AACA,IAAAA,KAAI,KAAK,qCAAY;AACrB,WAAO;AAAA,EACT,GAAG;AAEH,aAAWE,cAAa,YAAY;AAClC,UAAM,mBAAkB,gBAAW,cAAX,mBAAuBA;AAE/C,UAAM,SAAS;AACf,UAAM,WAAWD,GAAE,IAAIA,GAAE,UAAU,eAAe,GAAG,CAAC,MAAM;AAC1D,UAAI,EAAE,SAAS,GAAG,IAAI,IAAI,IAAI;AAC9B,aAAO,IAAI;AAAA,IACb,CAAC;AACD,IAAAD,KAAI,KAAK,0CAAsBG,IAAG,MAAMD,UAAS,CAAC;AAClD,IAAAF,KAAI,KAAK,8DAAiBG,IAAG,MAAM,SAAS,KAAK,IAAI,CAAC,CAAC;AAEvD,UAAM,QAAQ,MAAMC;AAAA,MAClB;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,MAEF,EAAE,OAAO,QAAQ;AAAA,MACjB,EAAE,KAAK,WAAW,IAAI;AAAA,IACxB;AAEA,IAAAJ,KAAI,KAAK,wDAAgBG,IAAG,MAAM,MAAM,MAAM,CAAC;AAE/C,QAAI,qBAAqB,oBAAI,IAAY;AAEzC,UAAME,MAAK,OAAO,OAAO,SAAS;AAChC,YAAM,UAAU,MAAMC,IAAG,SAAS,MAAM,OAAO;AAE/C,YAAM,aAAa,MAAM;AAAA,QACvB;AAAA,QACAJ;AAAA,QACA,WAAY;AAAA,MACd;AAEA,UAAI,YAAY;AACd,cAAMI,IAAG,UAAU,MAAM,UAAU;AACnC,cAAM,WAAW,IAAI;AACrB,2BAAmB,IAAI,IAAI;AAAA,MAC7B;AAAA,IACF,CAAC;AACD,IAAAN,KAAI;AAAA,MACF;AAAA,MACAG,IAAG,MAAM,mBAAmB,IAAI;AAAA,IAClC;AAAA,EACF;AACF;;;AEnIA,OAAOI,QAAO;AACd,OAAOC,WAAU;AAUjB,IAAMC,OAAM,aAAa,QAAQ;AAMjC,eAAe,gBAAgB,QAAoB;AACjD,MAAI,YAAY,MAAM,iBAAiB,MAAM;AAE7C,QAAM,UAAoB,CAAC;AAC3B,QAAM,cAAc,oBAAI,IAAsB;AAC9C,QAAMC,MAAK,OAAO,WAAW,CAAC,GAAG,OAAO,WAAW;AACjD,UAAM,WAAW,IAAI,SAAS,QAAQ,MAAM;AAC5C,gBAAY,IAAI,QAAQ,QAAQ;AAChC,UAAM,OAAO,MAAM,SAAS,SAAS;AACrC,YAAQ,KAAK,GAAG,OAAO,KAAK,IAAI,CAAC;AAAA,EACnC,CAAC;AAED,MAAI,eAAe,MAAM,KAAK,IAAI,IAAI,OAAO,CAAC,EAAE,OAAO,CAAC,QAAQ;AAE9D,WAAO,CAAC,UAAU,OAAO,IAAI,GAAG;AAAA,EAClC,CAAC;AACD,iBAAeC,GAAE,OAAO,YAAY;AAEpC,MAAI,aAAa,QAAQ;AACvB,IAAAF,KAAI,KAAK,0DAAa,aAAa,MAAM,oCAAgB;AACzD,UAAM,YAAY;AAAA,MAChB,OAAO;AAAA,MACP,OAAO;AAAA,MACP,eAAe,OAAO,SAAU,GAAG;AAAA,MACnC,UAAU;AAAA,MACV;AAAA,IACF;AACA,IAAAA,KAAI,KAAK,mDAAgB;AAGzB,eAAW,QAAQ,OAAO,SAAU;AAClC,YAAM,WAAW,YAAY,IAAI,IAAI;AACrC,YAAM,iBAA2B,CAAC;AAClC,mBAAa,QAAQ,CAAC,MAAM;AAC1B,YAAI,UAAU;AACZ,yBAAe,KAAK,SAAS,KAAK,CAAC,CAAC;AAAA,QACtC;AAAA,MACF,CAAC;AACD,MAAAA,KAAI;AAAA,QACF,wCAAU,IAAI,uBAAQ,eAAe,MAAM;AAAA,MAC7C;AACA,YAAM,YAAY;AAAA,QAChB,OAAO;AAAA,QACP,OAAO;AAAA,QACP,eAAe,OAAO,SAAU,IAAI,CAAC;AAAA,QACrC,UAAU;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAEA,UAAM,MAAM,GAAI;AAChB,gBAAY,MAAM,iBAAiB,MAAM;AACzC,IAAAA,KAAI,KAAK,kCAAS,OAAO,UAAU,qBAAM;AAAA,EAC3C;AAEA,SAAO,EAAE,WAAW,YAAY;AAClC;AAEA,eAAsB,SAAS;AAC7B,QAAM,SAAS,MAAM,UAAU;AAC/B,MAAI,cAAc,MAAM,uBAAuB,OAAO,IAAI;AAE1D,aAAW,cAAc,aAAa;AACpC,UAAM,EAAE,WAAW,YAAY,IAAI,MAAM,gBAAgB,UAAU;AACnE,UAAMC,MAAK,WAAW,WAAW,CAAC,GAAG,OAAO,WAAW;AACrD,YAAM,WAAW,YAAY,IAAI,MAAM;AACvC,YAAM,SAAS,gBAAgB,SAAS;AAAA,IAC1C,CAAC;AAAA,EACH;AAEA,EAAAD,KAAI,KAAK,0BAAM;AACjB;;;AC3EA,IACG,QAAQ,YAAY,sCAAQ,EAC5B,QAAQ,eAAe,EACvB,OAAO,QAAQ;AAClB,IACG,QAAQ,WAAW,kDAAU,EAC7B,OAAO,kBAAkB,kDAAU,EACnC,QAAQ,cAAc,EACtB,OAAO,OAAO;AAEjB,IACG,QAAQ,gBAAgB,8DAAsB,EAC9C,QAAQ,mBAAmB,EAC3B,OAAO,MAAM;AACZ,SAAO,UAAU,EAAE,MAAM,MAAM,CAAC;AAClC,CAAC;AAEH,IACG,QAAQ,gBAAgB,uEAAqB,EAC7C,QAAQ,mBAAmB,EAC3B,OAAO,MAAM;AACZ,SAAO,UAAU,EAAE,MAAM,MAAM,CAAC;AAClC,CAAC;AAEH,IAAI,QAAQ,UAAU,sCAAQ,EAAE,QAAQ,aAAa,EAAE,OAAO,MAAM;AAEpE,IACG,QAAQ,wBAAwB,wDAAW,EAC3C,QAAQ,2BAA2B,EACnC,OAAO,oBAAoB;AAI9B,IACG,QAAQ,eAAe,6BAAS,EAChC,QAAQ,kBAAkB,EAC1B,OAAO,WAAW;AAGrB,IAAI,QAAQ,QAAQ,4CAAS,EAAE,QAAQ,WAAW,EAAE,OAAO,UAAU;AAErE,IACG,QAAQ,eAAe,gCAAO,EAC9B,QAAQ,kBAAkB,EAC1B,MAAM,GAAG,EACT,OAAO,WAAW;AAGrB,IAAI,QAAQ,EAAE,EAAE,OAAO,WAAW;AAElC,IAAI,QAAQ,OAAO;AACnB,IAAI,KAAK;AAAA,CAER,YAAY;AACX,MAAI;AAEF,QAAI,MAAM,QAAQ,MAAM,EAAE,KAAK,MAAM,CAAC;AAGtC,UAAM,IAAI,kBAAkB;AAAA,EAC9B,SAAS,OAAO;AAAA,EAKhB;AACF,GAAG;","names":["log","pMap","log","extract","pMap","fs","os","pMap","path","log","log","fs","pMap","path","schema","_","data","fs","path","log","enquirer","prompt","log","command","enquirer","fs","globby","_","pMap","pc","namespace","prompt","enquirer","log","_","namespace","pc","globby","pMap","fs","_","pMap","log","pMap","_"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as Config } from './types-
|
|
2
|
-
export { A as ApiConfig, I as I18nConfig } from './types-
|
|
1
|
+
import { C as Config } from './types-DwQTE6Zn.js';
|
|
2
|
+
export { A as ApiConfig, I as I18nConfig } from './types-DwQTE6Zn.js';
|
|
3
3
|
import { GaxiosResponse } from 'gaxios';
|
|
4
4
|
import { sheets_v4 } from 'googleapis';
|
|
5
5
|
import 'openapi-types';
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/config/index.ts","../src/shared/letters.ts","../src/shared/google/sheet.ts","../src/shared/google/auth.ts","../src/shared/google/shared.ts","../src/commands/downloadFromPlatform.ts","../src/shared/i18nData.ts","../src/shared/sleep.ts"],"sourcesContent":["import JoyCon from \"joycon\";\nimport { Config } from \"./types\";\nimport { normalizeConfig } from \"./normalizeConfig\";\n\nexport * from \"./types\";\n\nconst joycon = new JoyCon();\n\nexport function defineConfig<T extends Config = Config>(c: T) {\n return c;\n}\n\nexport const configName = \"dune.config.js\";\n\nexport async function getConfig(): Promise<Config> {\n const res = await joycon.load([configName]);\n return normalizeConfig(res.data ?? {});\n}\n","/**\n *\n * - input : A\n * output : 0\n * - input : Z\n * output : 25\n * - input : AA\n * output : 26\n * - input : a\n * output : 0\n */\nexport function letterToNumber(letters: string | number) {\n if (typeof letters === \"number\" || !Number.isNaN(+letters)) {\n return +letters;\n }\n\n let n = 0;\n letters = letters.toUpperCase();\n for (let p = 0; p < letters.length; p++) {\n n = letters[p].charCodeAt(0) - 64 + n * 26;\n }\n\n return Math.max(0, n - 1);\n}\n\n/**\n * fork from https://github.com/matthewmueller/number-to-letter\n */\nconst alphabet = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\nconst base = alphabet.length;\n/**\n * numberToLetter(0) // A\n * numberToLetter(25) // Z\n * numberToLetter(26) // AA\n * numberToLetter(51) // AZ\n * numberToLetter(52) // BA\n * numberToLetter(676) // ZA\n * numberToLetter(701) // ZZ\n * numberToLetter(702) // AAA\n */\nexport function numberToLetter(n: number) {\n const digits: number[] = [];\n\n do {\n const v = n % base;\n digits.push(v);\n n = Math.floor(n / base);\n } while (n-- > 0);\n\n const chars: string[] = [];\n while (digits.length) {\n chars.push(alphabet[digits.pop()!]);\n }\n\n return chars.join(\"\");\n}\n","import { GaxiosResponse } from \"gaxios\";\nimport type { sheets_v4 } from \"googleapis\";\nimport { google } from \"googleapis\";\nimport { createLogger } from \"../index\";\nimport { numberToLetter } from \"../letters\";\nimport { googleAuth } from \"./auth\";\n\nconst log = createLogger(\"google:sheets\");\n\nclass GoogleSheet {\n private sheets: sheets_v4.Sheets;\n\n private initPromise: Promise<void> | null = null;\n private async initImpl() {\n if (!this.sheets) {\n await googleAuth.initCredentials();\n this.sheets = google.sheets({\n version: \"v4\",\n auth: googleAuth.oauth2Client,\n });\n }\n }\n /**\n * 调用sheets其他方法的时候需要先初始化\n */\n async init() {\n if (!this.initPromise) {\n this.initPromise = this.initImpl();\n }\n await this.initPromise;\n }\n\n get = async (options: sheets_v4.Params$Resource$Spreadsheets$Values$Get) => {\n await this.init();\n return this.sheets.spreadsheets.values.get(options);\n };\n\n private async update(\n spreadsheetId: string,\n range: string,\n colIndex: number,\n rowIndex: number,\n values: string[][]\n ): Promise<GaxiosResponse<sheets_v4.Schema$UpdateValuesResponse>> {\n await this.init();\n\n const colLetter = numberToLetter(colIndex);\n const sheetNeedRange = `${range}!${colLetter}${rowIndex}`;\n\n const res = await this.sheets.spreadsheets.values.update({\n spreadsheetId,\n range: sheetNeedRange,\n valueInputOption: \"USER_ENTERED\",\n requestBody: { values },\n });\n\n if (res.status === 200) {\n log.info(`更新 ${sheetNeedRange} 的值成功`);\n } else {\n log.error(\"some thing wrong\", res);\n }\n return res;\n }\n\n /**\n * 更新某一个单元格\n */\n async updateCell(\n spreadsheetId: string,\n range: string,\n colIndex: number,\n rowIndex: number,\n values: string\n ) {\n return this.update(spreadsheetId, range, colIndex, rowIndex, [[values]]);\n }\n\n /**\n * 更新某一列\n */\n async updateColumn(\n spreadsheetId: string,\n range: string,\n colIndex: number,\n rowIndex: number,\n values: string[]\n ) {\n return this.update(spreadsheetId, range, colIndex, rowIndex, [\n ...values.map((v) => [v]),\n ]);\n }\n /**\n * This method is used to get the titles of all the ranges in a Google Spreadsheet.\n *\n * @async\n * @param {string} spreadsheetId - The ID of the Google Spreadsheet.\n * @returns {Promise<string[]>} - A promise that resolves to an array of titles of all the ranges in the Google Spreadsheet.\n * @throws {Error} - Throws an error if the initialization of the Google Sheets API client fails.\n */\n async getRangeTitles(spreadsheetId: string) {\n // Initialize the Google Sheets API client\n await this.init();\n // Get the details of the Google Spreadsheet\n const res = await this.sheets.spreadsheets.get({\n spreadsheetId,\n });\n // Extract the titles of all the ranges in the Google Spreadsheet\n const titles = res.data.sheets\n ?.map((v) => v.properties?.title)\n .filter((v): v is string => !!v);\n\n return titles;\n }\n}\n\nexport const googleSheet = new GoogleSheet();\n","import fs from \"fs-extra\";\nimport { OAuth2Client } from \"google-auth-library\";\nimport { google } from \"googleapis\";\nimport { homeConfigDir, createLogger } from \"../index\";\nimport { openAndWaitReturnQuery } from \"./shared\";\n\ninterface AuthOptions {\n client_id: string;\n client_secret: string;\n /**\n * @default ['spreadsheets']\n */\n scope?: string[];\n}\n\nconst log = createLogger(\"google:auth\");\n\nclass GoogleAuth {\n private tokens: any = null;\n\n private tokensCachePath = homeConfigDir(\"chromeAuthToken.json\");\n\n private readonly scope: string[];\n\n oauth2Client: OAuth2Client = new google.auth.OAuth2(\n this.options.client_id,\n this.options.client_secret,\n \"http://localhost:12345\"\n );\n\n constructor(private options: AuthOptions) {\n this.options.scope = this.options.scope ?? [\"spreadsheets\"];\n const scopePrefix = `https://www.googleapis.com/auth/`;\n this.scope = this.options.scope.map((item) => {\n if (item.startsWith(scopePrefix)) {\n return item;\n }\n return `${scopePrefix}${item}`;\n });\n\n try {\n this.tokens = fs.readJsonSync(this.tokensCachePath);\n } catch (e) {\n log.info(\"未获取到缓存的token\");\n this.tokens = null;\n }\n }\n\n private async saveTokens(tokens: any): Promise<void> {\n this.tokens = tokens;\n await fs.writeJSON(this.tokensCachePath, tokens);\n log.info(\"保存token成功\");\n }\n\n async getCode(): Promise<string> {\n log.info(\"将打开chrome浏览器进行授权\");\n const authUrl = this.oauth2Client.generateAuthUrl({\n access_type: \"offline\",\n scope: this.scope,\n });\n return await openAndWaitReturnQuery(authUrl, 12345, \"code\");\n }\n\n private async initCredentialsImpl(): Promise<void> {\n if (!this.tokens) {\n const code = await this.getCode();\n const { tokens } = await this.oauth2Client.getToken(code);\n await this.saveTokens(tokens);\n }\n this.oauth2Client.setCredentials(this.tokens);\n }\n private initCredentialsPromise: Promise<void> | null = null;\n async initCredentials() {\n if (!this.initCredentialsPromise) {\n this.initCredentialsPromise = this.initCredentialsImpl();\n }\n return await this.initCredentialsPromise;\n }\n}\n\n// see in https://console.cloud.google.com/apis/credentials?organizationId=286245507762&orgonly=true&project=dune-cli&supportedpurview=organizationId\nconst clientSecret = {\n client_id:\n \"467670582023-3sr5gnfsuebgtde1mk3vp78om43no4kv.apps.googleusercontent.com\",\n project_id: \"dune-cli-376503\",\n auth_uri: \"https://accounts.google.com/o/oauth2/auth\",\n token_uri: \"https://oauth2.googleapis.com/token\",\n auth_provider_x509_cert_url: \"https://www.googleapis.com/oauth2/v1/certs\",\n client_secret: \"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\",\n redirect_uris: [\"http://localhost\"],\n javascript_origins: [\"http://localhost\"],\n};\nexport const googleAuth = new GoogleAuth(clientSecret);\n","import connect from \"connect\";\nimport open from \"open\";\nimport { URL } from \"url\";\nimport { createLogger } from \"../index\";\n\nconst log = createLogger(\"google:shared\");\n\nfunction openBrowser(url: string) {\n log.info(`如未自动打开浏览器,可访问以下地址:${url}`);\n open(url, { app: { name: open.apps.chrome } });\n}\n\nexport function openAndWaitReturnQuery(\n toOpenUrl: string,\n port: number,\n queryKey: string\n) {\n return new Promise<string>((resolve) => {\n openBrowser(toOpenUrl);\n\n const app = connect();\n app.use((req, res, next) => {\n const parsedUrl = new URL(req.url, `http://localhost:${port}`);\n const target = parsedUrl.searchParams.get(queryKey);\n if (target) {\n res.writeHead(200, {\n \"content-type\": \"text/html;charset=utf8\",\n });\n res.end(\n `<div>当前窗口可直接关闭</div>\n <script>\n window.open(\"\", \"_self\", \"\");\n window.close();\n </script>`\n );\n server.close();\n server.unref();\n resolve(target);\n }\n next();\n });\n\n const server = app.listen(port);\n });\n}\n","import axios from \"axios\";\nimport pMap from \"p-map\";\nimport { createLogger } from \"../shared\";\nimport { getConfig } from \"../shared/config\";\nimport { I18nData } from \"../shared/i18nData\";\n\nconst logger = createLogger(\"downloadFromPlatform\");\n\n/**\n * 从 翻译平台下载翻译文件\n */\nexport async function downloadFromPlatform() {\n const config = await getConfig();\n // 只有配置了 translatePlatform 才会下载\n // TODO: 暂时只支持一个,后续支持多个\n const i18nConfig = config.i18n?.[0];\n if (!i18nConfig) {\n logger.error(\"i18n 配置为空\");\n return;\n }\n const { translatePlatform, locales } = i18nConfig;\n if (!translatePlatform?.enable) {\n logger.info(\"translatePlatform.enable 为 false,不会下载\");\n return;\n }\n logger.info(\"开始从翻译平台下载翻译文件\");\n const res = await axios({\n baseURL: translatePlatform.url,\n url: \"/v1/dune-i18n/public/findAll\",\n params: {\n projectName: translatePlatform.project,\n },\n }).catch((err) => {\n throw new TransError(err, \"请求翻译平台失败\");\n });\n\n const data = res.data.data;\n if (!data) {\n throw new TransError(res.data, \"data 为空\");\n }\n\n await pMap(locales ?? [], async (locale) => {\n const i18nData = new I18nData(locale, i18nConfig);\n await i18nData.updateFromSheetData(data?.[locale] ?? {});\n await i18nData.saveToDisk();\n return i18nData;\n });\n logger.info(\"从翻译平台下载翻译文件完成\");\n}\n\nclass TransError extends Error {\n constructor(public data: any, message: string = \"\") {\n super(`获取翻译平台数据失败: ${message}`);\n }\n}\n","import Table from \"cli-table3\";\nimport fs from \"fs-extra\";\nimport pMap from \"p-map\";\nimport path from \"path\";\nimport pc from \"picocolors\";\nimport { I18nConfig } from \"./config\";\nimport { createLogger } from \"./index\";\nimport { SheetData } from \"./resolveSheetData\";\nimport { sleep } from \"./sleep\";\n\nconst log = createLogger(\"i18nData\");\nexport type ExtractedMap = Map<\n string,\n { id: string; messages: string; files: string[] }\n>;\n\nexport class I18nData {\n data: Record<string, string> = {};\n\n filePath: string;\n\n /**\n * 是否是默认语言,默认语言需要使用提出来的文案作为value\n */\n isDefaultLocale: boolean;\n // 没有被使用到的翻译key\n unUsedKeys: Set<string> = new Set();\n constructor(\n public locale: string,\n public config: I18nConfig,\n // 是否需要删除未使用的文案\n public shouldDeleteUnused = false\n ) {\n this.isDefaultLocale = locale === config.defaultLocale;\n this.filePath = path.join(\n config.cwd!,\n config.i18nDir!,\n config.i18nFileName!.replace(\"{locale}\", locale)\n );\n }\n\n async loadData() {\n try {\n if (await fs.pathExists(this.filePath)) {\n this.data = await fs.readJSON(this.filePath);\n } else {\n log.info(\"File '%s' does not exist\", pc.dim(this.filePath));\n }\n } catch (e) {\n log.error(\n \"Error loading i18n data for locale '%s' from file '%s'\",\n pc.yellow(this.locale),\n pc.yellow(this.filePath)\n );\n log.error(\"Error: %s\", e.message);\n }\n return this.data;\n }\n\n /**\n * @param {ExtractedMap} extractedData 提取出来的内容\n */\n async updateByExtractedData(extractedData: ExtractedMap) {\n const oldData = await this.loadData();\n let newData = {};\n extractedData.forEach((value, key) => {\n let newValue = oldData[key] || \"\";\n if (this.isDefaultLocale) {\n // 默认语言需要回退到key作为value\n newValue = newValue || value.messages || key;\n //#region 对namespace的支持\n newValue = this.normalizeNamespacedDefaultLocaleData(newValue);\n //#endregion\n }\n newData[key] = newValue;\n });\n if (!this.shouldDeleteUnused) {\n // 不删除未使用的文案,则需要合并旧数据\n newData = { ...oldData, ...newData };\n }\n this.data = newData;\n\n // 记录下来未被使用的key,后面需要打印出来提示用户\n Object.keys(oldData).forEach((key) => {\n if (!extractedData.has(key)) {\n this.unUsedKeys.add(key);\n }\n });\n }\n\n private namespaceReg: RegExp;\n /**\n * 如果是默认语言,开启了 namespace的话\n * 提取出来的 文案 是 `模块名.文案` 的形式\n * 在这里需要把 `模块名.` 去掉\n */\n private normalizeNamespacedDefaultLocaleData(v: string) {\n if (!this.namespaceReg && this.config.namespace) {\n const names = Object.keys(this.config.namespace).join(\"|\");\n const separator = this.config.namespaceSeparator;\n this.namespaceReg = new RegExp(`^(${names})\\\\${separator}`);\n }\n if (this.namespaceReg) {\n return v.replace(this.namespaceReg, \"\");\n }\n return v;\n }\n\n async updateFromSheetData(sheetData: Record<string, string>) {\n await this.loadData();\n this.data = { ...this.data, ...sheetData };\n }\n\n private sortData() {\n //region 语言key按一定规则排序\n this.data = this.config.jsonSorter!(this.data);\n //endregion\n }\n\n async saveToDisk() {\n this.sortData();\n log.info(\n \"Saving i18n data for locale '%s' to file '%s'\",\n pc.green(this.locale),\n pc.dim(this.filePath)\n );\n try {\n await fs.ensureFile(this.filePath);\n await fs.writeJson(this.filePath, this.data, { spaces: 2 });\n log.info(\n \"Saved i18n data for locale '%s' to file '%s'\",\n pc.green(this.locale),\n pc.dim(this.filePath)\n );\n } catch (e) {\n log.error(\n \"Error saving i18n data for locale '%s' to file '%s'\",\n pc.green(this.locale),\n pc.dim(this.filePath)\n );\n log.error(\"Error: %s\", pc.red(e.message));\n }\n }\n\n async trySaveToGoogle(sheetData: SheetData) {\n await pMap(\n Object.entries(this.data),\n async ([key, value]) => {\n if (sheetData.hasI18nItem(this.locale, key)) {\n // 更新已有的\n await sheetData.getI18nItem(this.locale, key)?.tryUpdate(value);\n // 避免频繁请求,Google sheet api 默认限制\n // • 每秒钟读操作数:100 请求/秒\n // • 每秒钟单元格写操作数:100 请求/秒\n await sleep(1000);\n } else {\n log.error(\n \"%s range %s not found key %s\",\n pc.bold(this.config.sheetRange),\n pc.bold(this.locale),\n pc.bold(key)\n );\n }\n },\n { concurrency: 50 }\n );\n }\n private statistic() {\n const total = Object.keys(this.data).length;\n const missing = Object.values(this.data).filter((v) => !v).length;\n\n return {\n locale: this.locale,\n total,\n missing,\n };\n }\n static printStatistic(label: string, i18nDataArr: I18nData[]) {\n // 首先打印 unUsedKeys\n const unUsedKeys = i18nDataArr.reduce((keys, item) => {\n return new Set(item.unUsedKeys);\n }, new Set<string>());\n if (unUsedKeys.size) {\n console.log(\n pc.bold(\n `共有 ${pc.green(\n unUsedKeys.size\n )} 个 key 未在代码中使用,以下是具体的 key`\n )\n );\n console.log(\n pc.red(\n \"注意:这些key可能是已经删除的代码,也可能是通过 `t.ignoreExtract` 调用忽略了提取 并不一定是冗余的 key\"\n )\n );\n console.table(unUsedKeys);\n }\n // 打印提取出来的翻译文案统计\n const table = new Table({\n head: [\"Language\", \"Total count\", \"Missing\"],\n colAligns: [\"left\", \"center\", \"center\"],\n style: {\n head: [\"green\"],\n border: [],\n compact: true,\n },\n });\n\n i18nDataArr.forEach((i18nData) => {\n const statistic = i18nData.statistic();\n table.push([\n statistic.locale,\n statistic.total,\n statistic.missing > 0 ? pc.red(statistic.missing) : statistic.missing,\n ]);\n });\n console.log(pc.bold(label));\n console.log(table.toString());\n }\n}\n","export function sleep(ms: number) {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n"],"mappings":"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","names":["google","log","log","google","_a","pMap","fs","log","fs","pMap"]}
|
|
File without changes
|