@dune2/cli 0.1.3 → 0.1.4

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/cli.js CHANGED
@@ -750,7 +750,8 @@ async function compileRequestParams(operationObject) {
750
750
  if (schema) {
751
751
  code = await compile(schema, "Req", {
752
752
  bannerComment: "",
753
- ignoreMinAndMaxItems: true
753
+ ignoreMinAndMaxItems: true,
754
+ additionalProperties: false
754
755
  });
755
756
  }
756
757
  return code ? code : "export type Req = any;";
@@ -766,7 +767,8 @@ async function compileResponseParams(operationObject, apiConfig) {
766
767
  markCircularToRef(data);
767
768
  code = await compile(data, "Res", {
768
769
  bannerComment: "",
769
- ignoreMinAndMaxItems: true
770
+ ignoreMinAndMaxItems: true,
771
+ additionalProperties: false
770
772
  });
771
773
  } else {
772
774
  log8.error("responseSchemaTransformer \u8FD4\u56DE\u503C\u4E3A\u7A7A, \u8BF7\u68C0\u67E5");
@@ -888,7 +890,7 @@ async function upload() {
888
890
  }
889
891
 
890
892
  // package.json
891
- var version = "0.1.2";
893
+ var version = "0.1.3";
892
894
 
893
895
  // src/commands/interactive.ts
894
896
  import enquirer2 from "enquirer";
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/extract.ts","../src/shared/index.ts","../src/shared/i18nData.ts","../src/shared/promptConfigEnable.ts","../src/commands/download.ts","../src/shared/google/sheet.ts","../src/shared/letters.ts","../src/shared/google/auth.ts","../src/shared/google/shared.ts","../src/shared/resolveSheetData.ts","../src/commands/generateApi/index.ts","../src/commands/initConfig.ts","../src/commands/upload.ts","../src/commands/interactive.ts","../src/cli.ts"],"sourcesContent":["import fs from \"fs-extra\";\nimport { globby } from \"globby\";\nimport pMap from \"p-map\";\nimport { createLogger } from \"../shared\";\nimport { getConfig } from \"../shared/config\";\nimport { ExtractedMap, I18nData } from \"../shared/i18nData\";\nimport pc from \"picocolors\";\nimport os from \"os\";\nimport { promptI18nConfigEnable } from \"../shared/promptConfigEnable\";\n\nconst log = createLogger(\"extract\");\n\nexport async function extract() {\n const config = await getConfig();\n const { extract } = await import(\"@dune2/wasm\");\n\n let i18nConfigs = await promptI18nConfigEnable(config.i18n);\n\n // 这是使得任务串行,方便看日志\n for (const configItem of i18nConfigs) {\n const files = await globby(\n [\n `**/**.{js,jsx,ts,tsx}`,\n \"!**/node_modules/**\",\n \"!**.d.ts\",\n \"!**/.next/**\",\n \"!**/out/**\",\n ],\n { cwd: configItem.cwd }\n );\n log.info(\"预计共解析 %s 个文件\", pc.green(files.length));\n let errMsgs: string[] = [];\n const extractedI18nDataMap: ExtractedMap = new Map();\n await pMap(\n files,\n async (file) => {\n const content = await fs.readFile(file, \"utf-8\");\n const res: { data: ExtractedMap; errMsg: string } = await extract(\n content,\n file\n );\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 const cur = extractedI18nDataMap.get(key);\n // 优先保留有 messages 的\n if (!cur?.messages) {\n extractedI18nDataMap.set(key, value);\n }\n });\n }\n if (res.errMsg) {\n errMsgs.push(res.errMsg);\n }\n },\n { concurrency: 20 }\n );\n\n const statistics = await pMap(\n configItem.locales ?? [],\n async (locale, index) => {\n const i18nData = new I18nData(locale, configItem);\n await i18nData.updateByExtractedData(extractedI18nDataMap, index === 0);\n await i18nData.saveToDisk();\n return await i18nData.statistic();\n }\n );\n if (errMsgs.length) {\n console.log(pc.bold(\"以下未能成功提取的文案,请手动处理:\"));\n console.log(errMsgs.join(os.EOL));\n }\n I18nData.printStatistic(\"提取结果: \", statistics);\n }\n}\n","import cac from \"cac\";\nimport debug from \"debug\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\n\nexport const cli = cac(\"dune\");\n\nexport const createLogger = (name: string) => {\n const info = debug(`${cli.name}:${name}`);\n return {\n ...info,\n info,\n error: info.extend(\"error\"),\n };\n};\n\ndebug.enable(`${cli.name}:*`);\n\n/**\n * same with chacheDir\n * homeDir();\n * //=> '~/name'\n *\n * homeDir('bar.js')\n * //=> '~/name/bar.js'\n */\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport const homeConfigDir = (() => {\n const isWin = process.platform === \"win32\";\n const USER_HOME_DIR = isWin ? process.env.USERPROFILE : process.env.HOME;\n const configDir = path.join(USER_HOME_DIR!, \".config\", cli.name);\n\n if (!fs.existsSync(configDir)) {\n fs.mkdirSync(configDir);\n }\n return homeConfigDir;\n\n function homeConfigDir(p?: string): string {\n if (!p) {\n return configDir;\n }\n return path.join(configDir, p);\n }\n})();\n","import pMap from \"p-map\";\nimport { I18nConfig } from \"./config\";\nimport { createLogger } from \"./index\";\nimport fs from \"fs-extra\";\nimport pc from \"picocolors\";\nimport path from \"path\";\nimport Table from \"cli-table3\";\nimport { SheetData } from \"./resolveSheetData\";\n\nconst log = createLogger(\"i18nData\");\nexport type ExtractedMap = Map<string, { id: string; messages: string }>;\n\nexport class I18nData {\n data: Record<string, string> = {};\n\n filePath: string;\n\n constructor(public locale: string, public config: I18nConfig) {\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 async updateByExtractedData(\n extractedData: ExtractedMap,\n shouldUseDefault = false\n ) {\n await this.loadData();\n extractedData.forEach((value, key) => {\n this.data[key] = shouldUseDefault\n ? value.messages || key\n : this.data[key] || \"\";\n });\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 const keys = Object.keys(this.data).sort(this.config.keySorter);\n const newData = {};\n keys.forEach((key) => {\n newData[key] = this.data[key];\n });\n this.data = newData;\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 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\n async trySaveToGoogle(sheetData: SheetData) {\n await pMap(Object.entries(this.data), async ([key, value]) => {\n if (sheetData.hasI18nItem(this.locale, key)) {\n // 更新已有的\n await sheetData.getI18nItem(this.locale, key)?.tryUpdate(value);\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 }\n\n static printStatistic(\n label: string,\n statistics: { locale: string; total: number; missing: number }[]\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 statistics.forEach((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","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\nasync 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 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 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 await i18nData.statistic();\n }\n );\n I18nData.printStatistic(`${configItem.sheetRange} 生成结果: `, statistics);\n }\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\nexport const googleSheet = new GoogleSheet();\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 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 \"728508473485-fgl11a3op1ucd0lef9hs49mkliuaipqa.apps.googleusercontent.com\",\n project_id: \"dune-cli\",\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};\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 { 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)]?.trim();\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 _ from \"lodash\";\nimport { OpenAPIV3 } from \"openapi-types\";\nimport pMap from \"p-map\";\nimport { createLogger } from \"../../shared\";\nimport { getConfig, ApiConfig } from \"../../shared/config\";\nimport fs from \"fs-extra\";\nimport * as os from \"os\";\nimport SwaggerParser from \"@apidevtools/swagger-parser\";\nimport { compile } from \"json-schema-to-typescript\";\nimport path from \"path\";\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(\n apiConfig.swaggerJSONPath\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\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 { url, method, operationObject, apiConfig } = options;\n\n const seeUrl = apiConfig.swaggerUiUrl\n ? `${apiConfig.swaggerUiUrl}#/${encodeURIComponent(\n operationObject.tags?.join(\"/\") ?? \"\"\n )}/${operationObject.operationId}`\n : \"not found swagger ui url\";\n\n const requestBuilderName = _.camelCase(`${url}_${method}_api`);\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 * @see ${seeUrl}\n */`,\n ].filter(Boolean);\n\n // builder 代码\n let builderCode = `\\\nexport const ${requestBuilderName} = new RequestBuilder({\n url: '${url}',\n method: '${method}',\n 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 // 请求参数类型\n // 响应参数类型\n const [requestParamsTypeCode, responseParamsTypeCode] = await Promise.all([\n compileRequestParams(operationObject),\n compileResponseParams(operationObject, apiConfig),\n ]);\n\n code.push(`\nexport namespace ${requestBuilderName} {\n ${requestParamsTypeCode}\n \n ${responseParamsTypeCode}\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) {\n let schema;\n if (operationObject.parameters) {\n // FIXME: 这里还需要处理 ref 类型\n const parameters =\n (operationObject.parameters as OpenAPIV3.ParameterObject[]).filter(\n (p) => p.in === \"query\" || p.in === \"path\"\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.map((p) => {\n //TODO: 这里也要处理 ref 类型\n const schema = p.schema as OpenAPIV3.SchemaObject;\n return [\n p.name,\n {\n type: schema.type,\n description: p.description,\n // enum: schema.enum ?? [],\n },\n ];\n })\n );\n schema = {\n required,\n type: \"object\",\n properties,\n };\n } else if (operationObject.requestBody) {\n //TODO: 这里也需要处理其他类型\n schema = (operationObject.requestBody as OpenAPIV3.RequestBodyObject)\n .content[\"application/json\"].schema;\n }\n\n let code = \"\";\n if (schema) {\n code = await compile(schema, \"Req\", {\n bannerComment: \"\",\n ignoreMinAndMaxItems: !!1,\n // format: false,\n });\n }\n\n return code ? code : \"export type Req = any;\";\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 const data = apiConfig.responseSchemaTransformer!(schema);\n if (data) {\n markCircularToRef(data);\n\n code = await compile(data, \"Res\", {\n bannerComment: \"\",\n ignoreMinAndMaxItems: !!1,\n // format: false,\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 \"../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 * @template {import('@dune2/cli').Config} T\n * @param {T} config - A generic parameter that flows through to the return type\n * @constraint {{import('@dune2/cli').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 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 { resolveSheetData } from \"../shared/resolveSheetData\";\nimport { promptI18nConfigEnable } from \"../shared/promptConfigEnable\";\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 = needSyncKeys.sort(config.keySorter);\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}\nfunction sleep(ms: number) {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\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","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","#!/usr/bin/env node\nimport { extract } from \"./commands/extract\";\nimport { download } from \"./commands/download\";\nimport { generateApi } from \"./commands/generateApi\";\nimport { initConfig } from \"./commands/initConfig\";\nimport { upload } from \"./commands/upload\";\nimport { cli } from \"./shared\";\nimport { version } from \"../package.json\";\nimport { interactive } from \"./commands/interactive\";\n//#region 翻译相关\n\ncli\n .command(\"download\", \"生成翻译文件\")\n .example(\"dune download\")\n .action(download);\ncli\n .command(\"extract\", \"提取代码中的文案\")\n .example(\"dune extract\")\n .action(extract);\ncli.command(\"upload\", \"上传翻译文件\").example(\"dune upload\").action(upload);\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":["fs","pMap","homeConfigDir","fs","path","pc","log","extract","pc","pMap","fs","pMap","google","fs","log","log","fs","log","google","log","log","pMap","pMap","fs","os","path","log","fs","pMap","path","schema","fs","path","log","pMap","log","pMap","enquirer","prompt","log","command"]}
1
+ {"version":3,"sources":["../src/commands/extract.ts","../src/shared/index.ts","../src/shared/i18nData.ts","../src/shared/promptConfigEnable.ts","../src/commands/download.ts","../src/shared/google/sheet.ts","../src/shared/letters.ts","../src/shared/google/auth.ts","../src/shared/google/shared.ts","../src/shared/resolveSheetData.ts","../src/commands/generateApi/index.ts","../src/commands/initConfig.ts","../src/commands/upload.ts","../src/commands/interactive.ts","../src/cli.ts"],"sourcesContent":["import fs from \"fs-extra\";\nimport { globby } from \"globby\";\nimport pMap from \"p-map\";\nimport { createLogger } from \"../shared\";\nimport { getConfig } from \"../shared/config\";\nimport { ExtractedMap, I18nData } from \"../shared/i18nData\";\nimport pc from \"picocolors\";\nimport os from \"os\";\nimport { promptI18nConfigEnable } from \"../shared/promptConfigEnable\";\n\nconst log = createLogger(\"extract\");\n\nexport async function extract() {\n const config = await getConfig();\n const { extract } = await import(\"@dune2/wasm\");\n\n let i18nConfigs = await promptI18nConfigEnable(config.i18n);\n\n // 这是使得任务串行,方便看日志\n for (const configItem of i18nConfigs) {\n const files = await globby(\n [\n `**/**.{js,jsx,ts,tsx}`,\n \"!**/node_modules/**\",\n \"!**.d.ts\",\n \"!**/.next/**\",\n \"!**/out/**\",\n ],\n { cwd: configItem.cwd }\n );\n log.info(\"预计共解析 %s 个文件\", pc.green(files.length));\n let errMsgs: string[] = [];\n const extractedI18nDataMap: ExtractedMap = new Map();\n await pMap(\n files,\n async (file) => {\n const content = await fs.readFile(file, \"utf-8\");\n const res: { data: ExtractedMap; errMsg: string } = await extract(\n content,\n file\n );\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 const cur = extractedI18nDataMap.get(key);\n // 优先保留有 messages 的\n if (!cur?.messages) {\n extractedI18nDataMap.set(key, value);\n }\n });\n }\n if (res.errMsg) {\n errMsgs.push(res.errMsg);\n }\n },\n { concurrency: 20 }\n );\n\n const statistics = await pMap(\n configItem.locales ?? [],\n async (locale, index) => {\n const i18nData = new I18nData(locale, configItem);\n await i18nData.updateByExtractedData(extractedI18nDataMap, index === 0);\n await i18nData.saveToDisk();\n return await i18nData.statistic();\n }\n );\n if (errMsgs.length) {\n console.log(pc.bold(\"以下未能成功提取的文案,请手动处理:\"));\n console.log(errMsgs.join(os.EOL));\n }\n I18nData.printStatistic(\"提取结果: \", statistics);\n }\n}\n","import cac from \"cac\";\nimport debug from \"debug\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\n\nexport const cli = cac(\"dune\");\n\nexport const createLogger = (name: string) => {\n const info = debug(`${cli.name}:${name}`);\n return {\n ...info,\n info,\n error: info.extend(\"error\"),\n };\n};\n\ndebug.enable(`${cli.name}:*`);\n\n/**\n * same with chacheDir\n * homeDir();\n * //=> '~/name'\n *\n * homeDir('bar.js')\n * //=> '~/name/bar.js'\n */\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport const homeConfigDir = (() => {\n const isWin = process.platform === \"win32\";\n const USER_HOME_DIR = isWin ? process.env.USERPROFILE : process.env.HOME;\n const configDir = path.join(USER_HOME_DIR!, \".config\", cli.name);\n\n if (!fs.existsSync(configDir)) {\n fs.mkdirSync(configDir);\n }\n return homeConfigDir;\n\n function homeConfigDir(p?: string): string {\n if (!p) {\n return configDir;\n }\n return path.join(configDir, p);\n }\n})();\n","import pMap from \"p-map\";\nimport { I18nConfig } from \"./config\";\nimport { createLogger } from \"./index\";\nimport fs from \"fs-extra\";\nimport pc from \"picocolors\";\nimport path from \"path\";\nimport Table from \"cli-table3\";\nimport { SheetData } from \"./resolveSheetData\";\n\nconst log = createLogger(\"i18nData\");\nexport type ExtractedMap = Map<string, { id: string; messages: string }>;\n\nexport class I18nData {\n data: Record<string, string> = {};\n\n filePath: string;\n\n constructor(public locale: string, public config: I18nConfig) {\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 async updateByExtractedData(\n extractedData: ExtractedMap,\n shouldUseDefault = false\n ) {\n await this.loadData();\n extractedData.forEach((value, key) => {\n this.data[key] = shouldUseDefault\n ? value.messages || key\n : this.data[key] || \"\";\n });\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 const keys = Object.keys(this.data).sort(this.config.keySorter);\n const newData = {};\n keys.forEach((key) => {\n newData[key] = this.data[key];\n });\n this.data = newData;\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 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\n async trySaveToGoogle(sheetData: SheetData) {\n await pMap(Object.entries(this.data), async ([key, value]) => {\n if (sheetData.hasI18nItem(this.locale, key)) {\n // 更新已有的\n await sheetData.getI18nItem(this.locale, key)?.tryUpdate(value);\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 }\n\n static printStatistic(\n label: string,\n statistics: { locale: string; total: number; missing: number }[]\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 statistics.forEach((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","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\nasync 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 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 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 await i18nData.statistic();\n }\n );\n I18nData.printStatistic(`${configItem.sheetRange} 生成结果: `, statistics);\n }\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\nexport const googleSheet = new GoogleSheet();\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 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 \"728508473485-fgl11a3op1ucd0lef9hs49mkliuaipqa.apps.googleusercontent.com\",\n project_id: \"dune-cli\",\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};\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 { 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)]?.trim();\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 _ from \"lodash\";\nimport { OpenAPIV3 } from \"openapi-types\";\nimport pMap from \"p-map\";\nimport { createLogger } from \"../../shared\";\nimport { getConfig, ApiConfig } from \"../../shared/config\";\nimport fs from \"fs-extra\";\nimport * as os from \"os\";\nimport SwaggerParser from \"@apidevtools/swagger-parser\";\nimport { compile } from \"json-schema-to-typescript\";\nimport path from \"path\";\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(\n apiConfig.swaggerJSONPath\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\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 { url, method, operationObject, apiConfig } = options;\n\n const seeUrl = apiConfig.swaggerUiUrl\n ? `${apiConfig.swaggerUiUrl}#/${encodeURIComponent(\n operationObject.tags?.join(\"/\") ?? \"\"\n )}/${operationObject.operationId}`\n : \"not found swagger ui url\";\n\n const requestBuilderName = _.camelCase(`${url}_${method}_api`);\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 * @see ${seeUrl}\n */`,\n ].filter(Boolean);\n\n // builder 代码\n let builderCode = `\\\nexport const ${requestBuilderName} = new RequestBuilder({\n url: '${url}',\n method: '${method}',\n 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 // 请求参数类型\n // 响应参数类型\n const [requestParamsTypeCode, responseParamsTypeCode] = await Promise.all([\n compileRequestParams(operationObject),\n compileResponseParams(operationObject, apiConfig),\n ]);\n\n code.push(`\nexport namespace ${requestBuilderName} {\n ${requestParamsTypeCode}\n \n ${responseParamsTypeCode}\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) {\n let schema;\n if (operationObject.parameters) {\n // FIXME: 这里还需要处理 ref 类型\n const parameters =\n (operationObject.parameters as OpenAPIV3.ParameterObject[]).filter(\n (p) => p.in === \"query\" || p.in === \"path\"\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.map((p) => {\n //TODO: 这里也要处理 ref 类型\n const schema = p.schema as OpenAPIV3.SchemaObject;\n return [\n p.name,\n {\n type: schema.type,\n description: p.description,\n // enum: schema.enum ?? [],\n },\n ];\n })\n );\n schema = {\n required,\n type: \"object\",\n properties,\n };\n } else if (operationObject.requestBody) {\n //TODO: 这里也需要处理其他类型\n schema = (operationObject.requestBody as OpenAPIV3.RequestBodyObject)\n .content[\"application/json\"].schema;\n }\n\n let code = \"\";\n if (schema) {\n code = await compile(schema, \"Req\", {\n bannerComment: \"\",\n ignoreMinAndMaxItems: !!1,\n additionalProperties: false,\n // format: false,\n });\n }\n\n return code ? code : \"export type Req = any;\";\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 const data = apiConfig.responseSchemaTransformer!(schema);\n if (data) {\n markCircularToRef(data);\n\n code = await compile(data, \"Res\", {\n bannerComment: \"\",\n ignoreMinAndMaxItems: !!1,\n additionalProperties: false,\n // format: false,\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 \"../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 * @template {import('@dune2/cli').Config} T\n * @param {T} config - A generic parameter that flows through to the return type\n * @constraint {{import('@dune2/cli').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 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 { resolveSheetData } from \"../shared/resolveSheetData\";\nimport { promptI18nConfigEnable } from \"../shared/promptConfigEnable\";\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 = needSyncKeys.sort(config.keySorter);\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}\nfunction sleep(ms: number) {\n return new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\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","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","#!/usr/bin/env node\nimport { extract } from \"./commands/extract\";\nimport { download } from \"./commands/download\";\nimport { generateApi } from \"./commands/generateApi\";\nimport { initConfig } from \"./commands/initConfig\";\nimport { upload } from \"./commands/upload\";\nimport { cli } from \"./shared\";\nimport { version } from \"../package.json\";\nimport { interactive } from \"./commands/interactive\";\n//#region 翻译相关\n\ncli\n .command(\"download\", \"生成翻译文件\")\n .example(\"dune download\")\n .action(download);\ncli\n .command(\"extract\", \"提取代码中的文案\")\n .example(\"dune extract\")\n .action(extract);\ncli.command(\"upload\", \"上传翻译文件\").example(\"dune upload\").action(upload);\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":["fs","pMap","homeConfigDir","fs","path","pc","log","extract","pc","pMap","fs","pMap","google","fs","log","log","fs","log","google","log","log","pMap","pMap","fs","os","path","log","fs","pMap","path","schema","fs","path","log","pMap","log","pMap","enquirer","prompt","log","command"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dune2/cli",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {