@diplodoc/cli 4.6.3 → 4.6.5

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "author": "Yandex Data UI Team <data-ui@yandex-team.ru>",
4
4
  "description": "Make documentation using yfm-docs in Markdown and HTML formats",
5
5
  "license": "MIT",
6
- "version": "4.6.3",
6
+ "version": "4.6.5",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "git@github.com:diplodoc-platform/cli.git"
@@ -29,23 +29,17 @@
29
29
  "npm:": ">=9.*"
30
30
  },
31
31
  "dependencies": {
32
- "@apidevtools/swagger-parser": "^10.1.0",
33
32
  "@aws-sdk/client-s3": "^3.369.0",
34
- "@diplodoc/client": "^1.0.2",
35
- "@diplodoc/markdown-translation": "^1.0.1",
36
- "@diplodoc/mermaid-extension": "^1.1.3",
37
- "@diplodoc/openapi-extension": "^1.4.4",
38
- "@diplodoc/transform": "^4.3.0",
33
+ "@diplodoc/client": "^1.2.0",
34
+ "@diplodoc/markdown-translation": "^1.0.2",
35
+ "@diplodoc/mermaid-extension": "^1.2.1",
36
+ "@diplodoc/openapi-extension": "^1.4.10",
37
+ "@diplodoc/transform": "^4.7.3",
39
38
  "@octokit/core": "4.2.4",
40
- "@types/glob": "^8.0.0",
41
- "@types/json-stringify-safe": "^5.0.0",
42
39
  "@yandex-cloud/nodejs-sdk": "^2.2.2",
43
40
  "ajv": "^8.11.0",
44
41
  "async": "^3.2.4",
45
- "aws-sdk": "^2.1425.0",
46
- "bem-cn-lite": "^4.1.0",
47
42
  "chalk": "4.1.2",
48
- "dotenv": "^16.0.3",
49
43
  "fast-xml-parser": "^4.0.11",
50
44
  "glob": "^8.0.3",
51
45
  "highlight.js": "^11.7.0",
@@ -66,13 +60,15 @@
66
60
  "yargs": "17.7.2"
67
61
  },
68
62
  "devDependencies": {
69
- "@diplodoc/eslint-config": "^1.0.14",
70
- "@diplodoc/prettier-config": "^1.0.0",
63
+ "@diplodoc/eslint-config": "^2.0.0",
64
+ "@diplodoc/prettier-config": "^2.0.0",
71
65
  "@diplodoc/tsconfig": "^1.0.2",
72
66
  "@types/async": "^3.2.15",
73
67
  "@types/chalk": "2.2.0",
68
+ "@types/glob": "^8.1.0",
74
69
  "@types/html-escaper": "^3.0.0",
75
70
  "@types/js-yaml": "4.0.5",
71
+ "@types/json-stringify-safe": "^5.0.3",
76
72
  "@types/lodash": "4.14.195",
77
73
  "@types/mime-types": "2.1.1",
78
74
  "@types/node": "14.*",
@@ -80,21 +76,11 @@
80
76
  "@types/tar-stream": "^2.2.2",
81
77
  "@types/yargs": "17.0.24",
82
78
  "esbuild": "^0.17.17",
83
- "eslint": "^8.0.0",
84
79
  "husky": "8.0.3",
85
80
  "lint-staged": "13.2.2",
86
81
  "lodash": "4.17.21",
87
- "prettier": "^3.0.3",
88
- "ts-jest": "29.1.0",
89
- "ts-node": "^10.9.1",
90
82
  "typescript": "4.9.5"
91
83
  },
92
- "overrides": {
93
- "react-sortable-hoc": {
94
- "react": "^18.2.0",
95
- "react-dom": "^18.2.0"
96
- }
97
- },
98
84
  "husky": {
99
85
  "hooks": {
100
86
  "pre-commit": "lint-staged"
@@ -129,5 +115,8 @@
129
115
  "tool",
130
116
  "tools",
131
117
  "generator"
132
- ]
118
+ ],
119
+ "overrides": {
120
+ "markdown-it": "^13.0.2"
121
+ }
133
122
  }
@@ -34,7 +34,8 @@ const translate = {
34
34
 
35
35
  const MD_GLOB = '**/*.md';
36
36
  const REQUESTS_LIMIT = 20;
37
- const RETRY_LIMIT = 8;
37
+ const BYTES_LIMIT = 10000;
38
+ const RETRY_LIMIT = 3;
38
39
  const MTRANS_LOCALE = 'MTRANS';
39
40
 
40
41
  function builder<T>(argv: Argv<T>) {
@@ -148,6 +149,23 @@ function translator(params: TranslatorParams) {
148
149
 
149
150
  const session = new Session({oauthToken});
150
151
  const client = session.client(TranslationServiceClient);
152
+ const request = (texts: string[]) => () =>
153
+ client
154
+ .translate(
155
+ TranslateRequest.fromPartial({
156
+ texts,
157
+ folderId,
158
+ sourceLanguageCode: sourceLanguage,
159
+ targetLanguageCode: targetLanguage,
160
+ glossaryConfig: {
161
+ glossaryData: {
162
+ glossaryPairs: yandexCloudTranslateGlossaryPairs,
163
+ },
164
+ },
165
+ format: Format.PLAIN_TEXT,
166
+ }),
167
+ )
168
+ .then((results) => results.translations.map(({text}) => text));
151
169
 
152
170
  return async (mdPath: string) => {
153
171
  try {
@@ -171,45 +189,57 @@ function translator(params: TranslatorParams) {
171
189
 
172
190
  const texts = parseSourcesFromXLIFF(xlf);
173
191
 
174
- const machineTranslateParams = TranslateRequest.fromPartial({
175
- texts,
176
- folderId,
177
- sourceLanguageCode: sourceLanguage,
178
- targetLanguageCode: targetLanguage,
179
- glossaryConfig: {
180
- glossaryData: {
181
- glossaryPairs: yandexCloudTranslateGlossaryPairs,
192
+ const parts = await Promise.all(
193
+ texts.reduce(
194
+ (
195
+ {
196
+ promises,
197
+ buffer,
198
+ bufferSize,
199
+ }: {
200
+ promises: Promise<string[]>[];
201
+ buffer: string[];
202
+ bufferSize: number;
203
+ },
204
+ text,
205
+ index,
206
+ ) => {
207
+ if (text.length >= BYTES_LIMIT) {
208
+ logger.warn(
209
+ mdPath,
210
+ 'Skip document part for translation. Part is too big.',
211
+ );
212
+ promises.push(Promise.resolve([text]));
213
+ return {promises, buffer, bufferSize};
214
+ }
215
+
216
+ if (bufferSize + text.length > BYTES_LIMIT || index === texts.length - 1) {
217
+ promises.push(backoff(request(buffer)));
218
+ buffer = [];
219
+ bufferSize = 0;
220
+ }
221
+
222
+ buffer.push(text);
223
+ bufferSize += text.length;
224
+
225
+ return {promises, buffer, bufferSize};
182
226
  },
183
- },
184
- format: Format.PLAIN_TEXT,
185
- });
186
-
187
- const translations = await retry(
188
- {
189
- times: RETRY_LIMIT,
190
- interval: (count: number) => {
191
- // eslint-disable-next-line no-bitwise
192
- return (1 << count) * 1000;
227
+ {
228
+ promises: [],
229
+ buffer: [],
230
+ bufferSize: 0,
193
231
  },
194
- },
195
- asyncify(
196
- async () =>
197
- await client
198
- .translate(machineTranslateParams)
199
- .then((results: {translations: {text: string}[]}) =>
200
- results.translations.map(({text}: {text: string}) => text),
201
- ),
202
- ),
232
+ ).promises,
203
233
  );
204
234
 
205
- const createXLIFFDocumentParams = {
235
+ const translations = ([] as string[]).concat(...parts);
236
+
237
+ const translatedXLIFF = createXLIFFDocument({
206
238
  sourceLanguage: sourceLanguage + '-' + MTRANS_LOCALE,
207
239
  targetLanguage: targetLanguage + '-' + MTRANS_LOCALE,
208
240
  sources: texts,
209
- targets: translations as string[],
210
- };
211
-
212
- const translatedXLIFF = createXLIFFDocument(createXLIFFDocumentParams);
241
+ targets: translations,
242
+ });
213
243
 
214
244
  const composed = await markdownTranslation.compose({
215
245
  xlf: translatedXLIFF,
@@ -230,7 +260,20 @@ function translator(params: TranslatorParams) {
230
260
  };
231
261
  }
232
262
 
233
- function parseSourcesFromXLIFF(xliff: string) {
263
+ function backoff(action: () => Promise<string[]>): Promise<string[]> {
264
+ return retry(
265
+ {
266
+ times: RETRY_LIMIT,
267
+ interval: (count: number) => {
268
+ // eslint-disable-next-line no-bitwise
269
+ return (1 << count) * 1000;
270
+ },
271
+ },
272
+ asyncify(action),
273
+ );
274
+ }
275
+
276
+ function parseSourcesFromXLIFF(xliff: string): string[] {
234
277
  const parser = new XMLParser();
235
278
 
236
279
  const inputs = parser.parse(xliff)?.xliff?.file?.body['trans-unit'] ?? [];
@@ -1,51 +0,0 @@
1
- import {readFileSync} from 'fs';
2
- import walkSync from 'walk-sync';
3
- import {join, resolve} from 'path';
4
- import S3 from 'aws-sdk/clients/s3';
5
- import mime from 'mime-types';
6
-
7
- import {ArgvService} from '../services';
8
- import {convertBackSlashToSlash, logger} from '../utils';
9
-
10
- const DEFAULT_PREFIX = process.env.YFM_STORAGE_PREFIX ?? '';
11
-
12
- export async function publishFilesToS3(): Promise<void> {
13
- const {
14
- output: outputFolderPath,
15
- ignore = [],
16
- storageEndpoint: endpoint,
17
- storageBucket: bucket,
18
- storagePrefix: prefix = DEFAULT_PREFIX,
19
- storageKeyId: accessKeyId,
20
- storageSecretKey: secretAccessKey,
21
- } = ArgvService.getConfig();
22
-
23
- const s3Client = new S3({
24
- endpoint,
25
- accessKeyId,
26
- secretAccessKey,
27
- });
28
-
29
- const filesToPublish: string[] = walkSync(resolve(outputFolderPath), {
30
- directories: false,
31
- includeBasePath: false,
32
- ignore,
33
- });
34
-
35
- await Promise.all(
36
- filesToPublish.map(async (pathToFile) => {
37
- const mimeType = mime.lookup(pathToFile);
38
-
39
- const params: S3.Types.PutObjectRequest = {
40
- ContentType: mimeType ? mimeType : undefined,
41
- Bucket: bucket,
42
- Key: convertBackSlashToSlash(join(prefix, pathToFile)),
43
- Body: readFileSync(resolve(outputFolderPath, pathToFile)),
44
- };
45
-
46
- logger.upload(pathToFile);
47
-
48
- return s3Client.upload(params).promise();
49
- }),
50
- );
51
- }