@dune2/cli 0.4.13 → 0.5.1
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/auth-777GVVSS.js +8 -0
- package/dist/auth-777GVVSS.js.map +1 -0
- package/dist/chunk-2SEEW5WZ.js +67 -0
- package/dist/chunk-2SEEW5WZ.js.map +1 -0
- package/dist/chunk-6UFZ6KLX.js +124 -0
- package/dist/chunk-6UFZ6KLX.js.map +1 -0
- package/dist/chunk-ADQ6JLT6.js +196 -0
- package/dist/chunk-ADQ6JLT6.js.map +1 -0
- package/dist/chunk-BSWWGPSV.js +60 -0
- package/dist/chunk-BSWWGPSV.js.map +1 -0
- package/dist/chunk-IKJLPHF7.js +117 -0
- package/dist/chunk-IKJLPHF7.js.map +1 -0
- package/dist/chunk-KNC7XY4Z.js +130 -0
- package/dist/chunk-KNC7XY4Z.js.map +1 -0
- package/dist/chunk-Q7UJ456X.js +24 -0
- package/dist/chunk-Q7UJ456X.js.map +1 -0
- package/dist/chunk-SVCF6X5K.js +22 -0
- package/dist/chunk-SVCF6X5K.js.map +1 -0
- package/dist/cli.js +58 -837
- package/dist/cli.js.map +1 -1
- package/dist/download-NS56QNEI.js +49 -0
- package/dist/download-NS56QNEI.js.map +1 -0
- package/dist/downloadFromPlatform-6ZUZTZAX.js +11 -0
- package/dist/downloadFromPlatform-6ZUZTZAX.js.map +1 -0
- package/dist/extract-7YVZJT6N.js +116 -0
- package/dist/extract-7YVZJT6N.js.map +1 -0
- package/dist/generateApi-TMEDGY2V.js +272 -0
- package/dist/generateApi-TMEDGY2V.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +11 -5
- package/dist/initConfig-DHDY6MWT.js +36 -0
- package/dist/initConfig-DHDY6MWT.js.map +1 -0
- package/dist/interactive-HNOHT33A.js +43 -0
- package/dist/interactive-HNOHT33A.js.map +1 -0
- package/dist/namespace-IDUS7AMO.js +137 -0
- package/dist/namespace-IDUS7AMO.js.map +1 -0
- package/dist/upload-WCPUDBKZ.js +92 -0
- package/dist/upload-WCPUDBKZ.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-B2TLAH5N.js +0 -491
- package/dist/chunk-B2TLAH5N.js.map +0 -1
package/dist/chunk-B2TLAH5N.js
DELETED
|
@@ -1,491 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
normalizeConfig
|
|
3
|
-
} from "./chunk-4BXCANQI.js";
|
|
4
|
-
import {
|
|
5
|
-
createLogger,
|
|
6
|
-
homeConfigDir
|
|
7
|
-
} from "./chunk-UGSBKD2I.js";
|
|
8
|
-
|
|
9
|
-
// src/shared/config/index.ts
|
|
10
|
-
import JoyCon from "joycon";
|
|
11
|
-
var joycon = new JoyCon();
|
|
12
|
-
function defineConfig(c) {
|
|
13
|
-
return c;
|
|
14
|
-
}
|
|
15
|
-
var configName = "dune.config.js";
|
|
16
|
-
async function getConfig() {
|
|
17
|
-
const res = await joycon.load([configName]);
|
|
18
|
-
return normalizeConfig(res.data ?? {});
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// src/shared/letters.ts
|
|
22
|
-
function letterToNumber(letters) {
|
|
23
|
-
if (typeof letters === "number" || !Number.isNaN(+letters)) {
|
|
24
|
-
return +letters;
|
|
25
|
-
}
|
|
26
|
-
let n = 0;
|
|
27
|
-
letters = letters.toUpperCase();
|
|
28
|
-
for (let p = 0; p < letters.length; p++) {
|
|
29
|
-
n = letters[p].charCodeAt(0) - 64 + n * 26;
|
|
30
|
-
}
|
|
31
|
-
return Math.max(0, n - 1);
|
|
32
|
-
}
|
|
33
|
-
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
34
|
-
var base = alphabet.length;
|
|
35
|
-
function numberToLetter(n) {
|
|
36
|
-
const digits = [];
|
|
37
|
-
do {
|
|
38
|
-
const v = n % base;
|
|
39
|
-
digits.push(v);
|
|
40
|
-
n = Math.floor(n / base);
|
|
41
|
-
} while (n-- > 0);
|
|
42
|
-
const chars = [];
|
|
43
|
-
while (digits.length) {
|
|
44
|
-
chars.push(alphabet[digits.pop()]);
|
|
45
|
-
}
|
|
46
|
-
return chars.join("");
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// src/shared/google/sheet.ts
|
|
50
|
-
import { google as google2 } from "googleapis";
|
|
51
|
-
|
|
52
|
-
// src/shared/google/auth.ts
|
|
53
|
-
import fs from "fs-extra";
|
|
54
|
-
import { google } from "googleapis";
|
|
55
|
-
|
|
56
|
-
// src/shared/google/shared.ts
|
|
57
|
-
import connect from "connect";
|
|
58
|
-
import open from "open";
|
|
59
|
-
import { URL } from "url";
|
|
60
|
-
var log = createLogger("google:shared");
|
|
61
|
-
function openBrowser(url) {
|
|
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: open.apps.chrome } });
|
|
64
|
-
}
|
|
65
|
-
function openAndWaitReturnQuery(toOpenUrl, port, queryKey) {
|
|
66
|
-
return new Promise((resolve) => {
|
|
67
|
-
openBrowser(toOpenUrl);
|
|
68
|
-
const app = connect();
|
|
69
|
-
app.use((req, res, next) => {
|
|
70
|
-
const parsedUrl = new URL(req.url, `http://localhost:${port}`);
|
|
71
|
-
const target = parsedUrl.searchParams.get(queryKey);
|
|
72
|
-
if (target) {
|
|
73
|
-
res.writeHead(200, {
|
|
74
|
-
"content-type": "text/html;charset=utf8"
|
|
75
|
-
});
|
|
76
|
-
res.end(
|
|
77
|
-
`<div>\u5F53\u524D\u7A97\u53E3\u53EF\u76F4\u63A5\u5173\u95ED</div>
|
|
78
|
-
<script>
|
|
79
|
-
window.open("", "_self", "");
|
|
80
|
-
window.close();
|
|
81
|
-
</script>`
|
|
82
|
-
);
|
|
83
|
-
server.close();
|
|
84
|
-
server.unref();
|
|
85
|
-
resolve(target);
|
|
86
|
-
}
|
|
87
|
-
next();
|
|
88
|
-
});
|
|
89
|
-
const server = app.listen(port);
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// src/shared/google/auth.ts
|
|
94
|
-
var log2 = createLogger("google:auth");
|
|
95
|
-
var GoogleAuth = class {
|
|
96
|
-
constructor(options) {
|
|
97
|
-
this.options = options;
|
|
98
|
-
this.tokens = null;
|
|
99
|
-
this.tokensCachePath = homeConfigDir("chromeAuthToken.json");
|
|
100
|
-
this.oauth2Client = new google.auth.OAuth2(
|
|
101
|
-
this.options.client_id,
|
|
102
|
-
this.options.client_secret,
|
|
103
|
-
"http://localhost:12345"
|
|
104
|
-
);
|
|
105
|
-
this.initCredentialsPromise = null;
|
|
106
|
-
this.options.scope = this.options.scope ?? ["spreadsheets"];
|
|
107
|
-
const scopePrefix = `https://www.googleapis.com/auth/`;
|
|
108
|
-
this.scope = this.options.scope.map((item) => {
|
|
109
|
-
if (item.startsWith(scopePrefix)) {
|
|
110
|
-
return item;
|
|
111
|
-
}
|
|
112
|
-
return `${scopePrefix}${item}`;
|
|
113
|
-
});
|
|
114
|
-
try {
|
|
115
|
-
this.tokens = fs.readJsonSync(this.tokensCachePath);
|
|
116
|
-
} catch (e) {
|
|
117
|
-
log2.info("\u672A\u83B7\u53D6\u5230\u7F13\u5B58\u7684token");
|
|
118
|
-
this.tokens = null;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
async saveTokens(tokens) {
|
|
122
|
-
this.tokens = tokens;
|
|
123
|
-
await fs.writeJSON(this.tokensCachePath, tokens);
|
|
124
|
-
log2.info("\u4FDD\u5B58token\u6210\u529F");
|
|
125
|
-
}
|
|
126
|
-
async getCode() {
|
|
127
|
-
log2.info("\u5C06\u6253\u5F00chrome\u6D4F\u89C8\u5668\u8FDB\u884C\u6388\u6743");
|
|
128
|
-
const authUrl = this.oauth2Client.generateAuthUrl({
|
|
129
|
-
access_type: "offline",
|
|
130
|
-
scope: this.scope
|
|
131
|
-
});
|
|
132
|
-
return await openAndWaitReturnQuery(authUrl, 12345, "code");
|
|
133
|
-
}
|
|
134
|
-
async initCredentialsImpl() {
|
|
135
|
-
if (!this.tokens) {
|
|
136
|
-
const code = await this.getCode();
|
|
137
|
-
const { tokens } = await this.oauth2Client.getToken(code);
|
|
138
|
-
await this.saveTokens(tokens);
|
|
139
|
-
}
|
|
140
|
-
this.oauth2Client.setCredentials(this.tokens);
|
|
141
|
-
}
|
|
142
|
-
async initCredentials() {
|
|
143
|
-
if (!this.initCredentialsPromise) {
|
|
144
|
-
this.initCredentialsPromise = this.initCredentialsImpl();
|
|
145
|
-
}
|
|
146
|
-
return await this.initCredentialsPromise;
|
|
147
|
-
}
|
|
148
|
-
};
|
|
149
|
-
var clientSecret = {
|
|
150
|
-
client_id: "467670582023-3sr5gnfsuebgtde1mk3vp78om43no4kv.apps.googleusercontent.com",
|
|
151
|
-
project_id: "dune-cli-376503",
|
|
152
|
-
auth_uri: "https://accounts.google.com/o/oauth2/auth",
|
|
153
|
-
token_uri: "https://oauth2.googleapis.com/token",
|
|
154
|
-
auth_provider_x509_cert_url: "https://www.googleapis.com/oauth2/v1/certs",
|
|
155
|
-
client_secret: "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",
|
|
156
|
-
redirect_uris: ["http://localhost"],
|
|
157
|
-
javascript_origins: ["http://localhost"]
|
|
158
|
-
};
|
|
159
|
-
var googleAuth = new GoogleAuth(clientSecret);
|
|
160
|
-
|
|
161
|
-
// src/shared/google/sheet.ts
|
|
162
|
-
var log3 = createLogger("google:sheets");
|
|
163
|
-
var GoogleSheet = class {
|
|
164
|
-
constructor() {
|
|
165
|
-
this.initPromise = null;
|
|
166
|
-
this.get = async (options) => {
|
|
167
|
-
await this.init();
|
|
168
|
-
return this.sheets.spreadsheets.values.get(options);
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
async initImpl() {
|
|
172
|
-
if (!this.sheets) {
|
|
173
|
-
await googleAuth.initCredentials();
|
|
174
|
-
this.sheets = google2.sheets({
|
|
175
|
-
version: "v4",
|
|
176
|
-
auth: googleAuth.oauth2Client
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* 调用sheets其他方法的时候需要先初始化
|
|
182
|
-
*/
|
|
183
|
-
async init() {
|
|
184
|
-
if (!this.initPromise) {
|
|
185
|
-
this.initPromise = this.initImpl();
|
|
186
|
-
}
|
|
187
|
-
await this.initPromise;
|
|
188
|
-
}
|
|
189
|
-
async update(spreadsheetId, range, colIndex, rowIndex, values) {
|
|
190
|
-
await this.init();
|
|
191
|
-
const colLetter = numberToLetter(colIndex);
|
|
192
|
-
const sheetNeedRange = `${range}!${colLetter}${rowIndex}`;
|
|
193
|
-
const res = await this.sheets.spreadsheets.values.update({
|
|
194
|
-
spreadsheetId,
|
|
195
|
-
range: sheetNeedRange,
|
|
196
|
-
valueInputOption: "USER_ENTERED",
|
|
197
|
-
requestBody: { values }
|
|
198
|
-
});
|
|
199
|
-
if (res.status === 200) {
|
|
200
|
-
log3.info(`\u66F4\u65B0 ${sheetNeedRange} \u7684\u503C\u6210\u529F`);
|
|
201
|
-
} else {
|
|
202
|
-
log3.error("some thing wrong", res);
|
|
203
|
-
}
|
|
204
|
-
return res;
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* 更新某一个单元格
|
|
208
|
-
*/
|
|
209
|
-
async updateCell(spreadsheetId, range, colIndex, rowIndex, values) {
|
|
210
|
-
return this.update(spreadsheetId, range, colIndex, rowIndex, [[values]]);
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* 更新某一列
|
|
214
|
-
*/
|
|
215
|
-
async updateColumn(spreadsheetId, range, colIndex, rowIndex, values) {
|
|
216
|
-
return this.update(spreadsheetId, range, colIndex, rowIndex, [
|
|
217
|
-
...values.map((v) => [v])
|
|
218
|
-
]);
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* This method is used to get the titles of all the ranges in a Google Spreadsheet.
|
|
222
|
-
*
|
|
223
|
-
* @async
|
|
224
|
-
* @param {string} spreadsheetId - The ID of the Google Spreadsheet.
|
|
225
|
-
* @returns {Promise<string[]>} - A promise that resolves to an array of titles of all the ranges in the Google Spreadsheet.
|
|
226
|
-
* @throws {Error} - Throws an error if the initialization of the Google Sheets API client fails.
|
|
227
|
-
*/
|
|
228
|
-
async getRangeTitles(spreadsheetId) {
|
|
229
|
-
var _a;
|
|
230
|
-
await this.init();
|
|
231
|
-
const res = await this.sheets.spreadsheets.get({
|
|
232
|
-
spreadsheetId
|
|
233
|
-
});
|
|
234
|
-
const titles = (_a = res.data.sheets) == null ? void 0 : _a.map((v) => {
|
|
235
|
-
var _a2;
|
|
236
|
-
return (_a2 = v.properties) == null ? void 0 : _a2.title;
|
|
237
|
-
}).filter((v) => !!v);
|
|
238
|
-
return titles;
|
|
239
|
-
}
|
|
240
|
-
};
|
|
241
|
-
var googleSheet = new GoogleSheet();
|
|
242
|
-
|
|
243
|
-
// src/commands/downloadFromPlatform.ts
|
|
244
|
-
import axios from "axios";
|
|
245
|
-
import pMap2 from "p-map";
|
|
246
|
-
|
|
247
|
-
// src/shared/i18nData.ts
|
|
248
|
-
import Table from "cli-table3";
|
|
249
|
-
import fs2 from "fs-extra";
|
|
250
|
-
import pMap from "p-map";
|
|
251
|
-
import path from "path";
|
|
252
|
-
import pc from "picocolors";
|
|
253
|
-
|
|
254
|
-
// src/shared/sleep.ts
|
|
255
|
-
function sleep(ms) {
|
|
256
|
-
return new Promise((resolve) => {
|
|
257
|
-
setTimeout(resolve, ms);
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
// src/shared/i18nData.ts
|
|
262
|
-
var log4 = createLogger("i18nData");
|
|
263
|
-
var I18nData = class {
|
|
264
|
-
constructor(locale, config, shouldDeleteUnused = false) {
|
|
265
|
-
this.locale = locale;
|
|
266
|
-
this.config = config;
|
|
267
|
-
this.shouldDeleteUnused = shouldDeleteUnused;
|
|
268
|
-
this.data = {};
|
|
269
|
-
// 没有被使用到的翻译key
|
|
270
|
-
this.unUsedKeys = /* @__PURE__ */ new Set();
|
|
271
|
-
this.isDefaultLocale = locale === config.defaultLocale;
|
|
272
|
-
this.filePath = path.join(
|
|
273
|
-
config.cwd,
|
|
274
|
-
config.i18nDir,
|
|
275
|
-
config.i18nFileName.replace("{locale}", locale)
|
|
276
|
-
);
|
|
277
|
-
}
|
|
278
|
-
async loadData() {
|
|
279
|
-
try {
|
|
280
|
-
if (await fs2.pathExists(this.filePath)) {
|
|
281
|
-
this.data = await fs2.readJSON(this.filePath);
|
|
282
|
-
} else {
|
|
283
|
-
log4.info("File '%s' does not exist", pc.dim(this.filePath));
|
|
284
|
-
}
|
|
285
|
-
} catch (e) {
|
|
286
|
-
log4.error(
|
|
287
|
-
"Error loading i18n data for locale '%s' from file '%s'",
|
|
288
|
-
pc.yellow(this.locale),
|
|
289
|
-
pc.yellow(this.filePath)
|
|
290
|
-
);
|
|
291
|
-
log4.error("Error: %s", e.message);
|
|
292
|
-
}
|
|
293
|
-
return this.data;
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* @param {ExtractedMap} extractedData 提取出来的内容
|
|
297
|
-
*/
|
|
298
|
-
async updateByExtractedData(extractedData) {
|
|
299
|
-
const oldData = await this.loadData();
|
|
300
|
-
let newData = {};
|
|
301
|
-
extractedData.forEach((value, key) => {
|
|
302
|
-
let newValue = oldData[key] || "";
|
|
303
|
-
if (this.isDefaultLocale) {
|
|
304
|
-
newValue = newValue || value.messages || key;
|
|
305
|
-
newValue = this.normalizeNamespacedDefaultLocaleData(newValue);
|
|
306
|
-
}
|
|
307
|
-
newData[key] = newValue;
|
|
308
|
-
});
|
|
309
|
-
if (!this.shouldDeleteUnused) {
|
|
310
|
-
newData = { ...oldData, ...newData };
|
|
311
|
-
}
|
|
312
|
-
this.data = newData;
|
|
313
|
-
Object.keys(oldData).forEach((key) => {
|
|
314
|
-
if (!extractedData.has(key)) {
|
|
315
|
-
this.unUsedKeys.add(key);
|
|
316
|
-
}
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* 如果是默认语言,开启了 namespace的话
|
|
321
|
-
* 提取出来的 文案 是 `模块名.文案` 的形式
|
|
322
|
-
* 在这里需要把 `模块名.` 去掉
|
|
323
|
-
*/
|
|
324
|
-
normalizeNamespacedDefaultLocaleData(v) {
|
|
325
|
-
if (!this.namespaceReg && this.config.namespace) {
|
|
326
|
-
const names = Object.keys(this.config.namespace).join("|");
|
|
327
|
-
const separator = this.config.namespaceSeparator;
|
|
328
|
-
this.namespaceReg = new RegExp(`^(${names})\\${separator}`);
|
|
329
|
-
}
|
|
330
|
-
if (this.namespaceReg) {
|
|
331
|
-
return v.replace(this.namespaceReg, "");
|
|
332
|
-
}
|
|
333
|
-
return v;
|
|
334
|
-
}
|
|
335
|
-
async updateFromSheetData(sheetData) {
|
|
336
|
-
await this.loadData();
|
|
337
|
-
this.data = { ...this.data, ...sheetData };
|
|
338
|
-
}
|
|
339
|
-
sortData() {
|
|
340
|
-
this.data = this.config.jsonSorter(this.data);
|
|
341
|
-
}
|
|
342
|
-
async saveToDisk() {
|
|
343
|
-
this.sortData();
|
|
344
|
-
log4.info(
|
|
345
|
-
"Saving i18n data for locale '%s' to file '%s'",
|
|
346
|
-
pc.green(this.locale),
|
|
347
|
-
pc.dim(this.filePath)
|
|
348
|
-
);
|
|
349
|
-
try {
|
|
350
|
-
await fs2.ensureFile(this.filePath);
|
|
351
|
-
await fs2.writeJson(this.filePath, this.data, { spaces: 2 });
|
|
352
|
-
log4.info(
|
|
353
|
-
"Saved i18n data for locale '%s' to file '%s'",
|
|
354
|
-
pc.green(this.locale),
|
|
355
|
-
pc.dim(this.filePath)
|
|
356
|
-
);
|
|
357
|
-
} catch (e) {
|
|
358
|
-
log4.error(
|
|
359
|
-
"Error saving i18n data for locale '%s' to file '%s'",
|
|
360
|
-
pc.green(this.locale),
|
|
361
|
-
pc.dim(this.filePath)
|
|
362
|
-
);
|
|
363
|
-
log4.error("Error: %s", pc.red(e.message));
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
async trySaveToGoogle(sheetData) {
|
|
367
|
-
await pMap(
|
|
368
|
-
Object.entries(this.data),
|
|
369
|
-
async ([key, value]) => {
|
|
370
|
-
var _a;
|
|
371
|
-
if (sheetData.hasI18nItem(this.locale, key)) {
|
|
372
|
-
await ((_a = sheetData.getI18nItem(this.locale, key)) == null ? void 0 : _a.tryUpdate(value));
|
|
373
|
-
await sleep(1e3);
|
|
374
|
-
} else {
|
|
375
|
-
log4.error(
|
|
376
|
-
"%s range %s not found key %s",
|
|
377
|
-
pc.bold(this.config.sheetRange),
|
|
378
|
-
pc.bold(this.locale),
|
|
379
|
-
pc.bold(key)
|
|
380
|
-
);
|
|
381
|
-
}
|
|
382
|
-
},
|
|
383
|
-
{ concurrency: 50 }
|
|
384
|
-
);
|
|
385
|
-
}
|
|
386
|
-
statistic() {
|
|
387
|
-
const total = Object.keys(this.data).length;
|
|
388
|
-
const missing = Object.values(this.data).filter((v) => !v).length;
|
|
389
|
-
return {
|
|
390
|
-
locale: this.locale,
|
|
391
|
-
total,
|
|
392
|
-
missing
|
|
393
|
-
};
|
|
394
|
-
}
|
|
395
|
-
static printStatistic(label, i18nDataArr) {
|
|
396
|
-
const unUsedKeys = i18nDataArr.reduce((keys, item) => {
|
|
397
|
-
return new Set(item.unUsedKeys);
|
|
398
|
-
}, /* @__PURE__ */ new Set());
|
|
399
|
-
if (unUsedKeys.size) {
|
|
400
|
-
console.log(
|
|
401
|
-
pc.bold(
|
|
402
|
-
`\u5171\u6709 ${pc.green(
|
|
403
|
-
unUsedKeys.size
|
|
404
|
-
)} \u4E2A key \u672A\u5728\u4EE3\u7801\u4E2D\u4F7F\u7528\uFF0C\u4EE5\u4E0B\u662F\u5177\u4F53\u7684 key`
|
|
405
|
-
)
|
|
406
|
-
);
|
|
407
|
-
console.log(
|
|
408
|
-
pc.red(
|
|
409
|
-
"\u6CE8\u610F\uFF1A\u8FD9\u4E9Bkey\u53EF\u80FD\u662F\u5DF2\u7ECF\u5220\u9664\u7684\u4EE3\u7801\uFF0C\u4E5F\u53EF\u80FD\u662F\u901A\u8FC7 `t.ignoreExtract` \u8C03\u7528\u5FFD\u7565\u4E86\u63D0\u53D6 \u5E76\u4E0D\u4E00\u5B9A\u662F\u5197\u4F59\u7684 key"
|
|
410
|
-
)
|
|
411
|
-
);
|
|
412
|
-
console.table(unUsedKeys);
|
|
413
|
-
}
|
|
414
|
-
const table = new Table({
|
|
415
|
-
head: ["Language", "Total count", "Missing"],
|
|
416
|
-
colAligns: ["left", "center", "center"],
|
|
417
|
-
style: {
|
|
418
|
-
head: ["green"],
|
|
419
|
-
border: [],
|
|
420
|
-
compact: true
|
|
421
|
-
}
|
|
422
|
-
});
|
|
423
|
-
i18nDataArr.forEach((i18nData) => {
|
|
424
|
-
const statistic = i18nData.statistic();
|
|
425
|
-
table.push([
|
|
426
|
-
statistic.locale,
|
|
427
|
-
statistic.total,
|
|
428
|
-
statistic.missing > 0 ? pc.red(statistic.missing) : statistic.missing
|
|
429
|
-
]);
|
|
430
|
-
});
|
|
431
|
-
console.log(pc.bold(label));
|
|
432
|
-
console.log(table.toString());
|
|
433
|
-
}
|
|
434
|
-
};
|
|
435
|
-
|
|
436
|
-
// src/commands/downloadFromPlatform.ts
|
|
437
|
-
var logger = createLogger("downloadFromPlatform");
|
|
438
|
-
async function downloadFromPlatform() {
|
|
439
|
-
var _a;
|
|
440
|
-
const config = await getConfig();
|
|
441
|
-
const i18nConfig = (_a = config.i18n) == null ? void 0 : _a[0];
|
|
442
|
-
if (!i18nConfig) {
|
|
443
|
-
logger.error("i18n \u914D\u7F6E\u4E3A\u7A7A");
|
|
444
|
-
return;
|
|
445
|
-
}
|
|
446
|
-
const { translatePlatform, locales } = i18nConfig;
|
|
447
|
-
if (!(translatePlatform == null ? void 0 : translatePlatform.enable)) {
|
|
448
|
-
logger.info("translatePlatform.enable \u4E3A false\uFF0C\u4E0D\u4F1A\u4E0B\u8F7D");
|
|
449
|
-
return;
|
|
450
|
-
}
|
|
451
|
-
logger.info("\u5F00\u59CB\u4ECE\u7FFB\u8BD1\u5E73\u53F0\u4E0B\u8F7D\u7FFB\u8BD1\u6587\u4EF6");
|
|
452
|
-
const res = await axios({
|
|
453
|
-
baseURL: translatePlatform.url,
|
|
454
|
-
url: "/v1/dune-i18n/public/findAll",
|
|
455
|
-
params: {
|
|
456
|
-
projectName: translatePlatform.project
|
|
457
|
-
}
|
|
458
|
-
}).catch((err) => {
|
|
459
|
-
throw new TransError(err, "\u8BF7\u6C42\u7FFB\u8BD1\u5E73\u53F0\u5931\u8D25");
|
|
460
|
-
});
|
|
461
|
-
const data = res.data.data;
|
|
462
|
-
if (!data) {
|
|
463
|
-
throw new TransError(res.data, "data \u4E3A\u7A7A");
|
|
464
|
-
}
|
|
465
|
-
await pMap2(locales ?? [], async (locale) => {
|
|
466
|
-
const i18nData = new I18nData(locale, i18nConfig);
|
|
467
|
-
await i18nData.updateFromSheetData((data == null ? void 0 : data[locale]) ?? {});
|
|
468
|
-
await i18nData.saveToDisk();
|
|
469
|
-
return i18nData;
|
|
470
|
-
});
|
|
471
|
-
logger.info("\u4ECE\u7FFB\u8BD1\u5E73\u53F0\u4E0B\u8F7D\u7FFB\u8BD1\u6587\u4EF6\u5B8C\u6210");
|
|
472
|
-
}
|
|
473
|
-
var TransError = class extends Error {
|
|
474
|
-
constructor(data, message = "") {
|
|
475
|
-
super(`\u83B7\u53D6\u7FFB\u8BD1\u5E73\u53F0\u6570\u636E\u5931\u8D25: ${message}`);
|
|
476
|
-
this.data = data;
|
|
477
|
-
}
|
|
478
|
-
};
|
|
479
|
-
|
|
480
|
-
export {
|
|
481
|
-
defineConfig,
|
|
482
|
-
configName,
|
|
483
|
-
getConfig,
|
|
484
|
-
letterToNumber,
|
|
485
|
-
numberToLetter,
|
|
486
|
-
googleSheet,
|
|
487
|
-
sleep,
|
|
488
|
-
I18nData,
|
|
489
|
-
downloadFromPlatform
|
|
490
|
-
};
|
|
491
|
-
//# sourceMappingURL=chunk-B2TLAH5N.js.map
|
|
@@ -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"]}
|