@diplodoc/cli 4.28.2 → 4.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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.28.2",
6
+ "version": "4.29.0",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "git@github.com:diplodoc-platform/cli.git"
@@ -7,6 +7,7 @@ import {mkdir} from 'node:fs/promises';
7
7
  import {pick} from 'lodash';
8
8
  import {gray} from 'chalk';
9
9
  import {asyncify, eachLimit} from 'async';
10
+ import liquid from '@diplodoc/transform/lib/liquid';
10
11
  import {BaseProgram} from '~/program/base';
11
12
  import {Command, defined} from '~/config';
12
13
  import {YFM_CONFIG_FILENAME} from '~/constants';
@@ -21,6 +22,7 @@ import {
21
22
  resolveSchemas,
22
23
  resolveSource,
23
24
  resolveTargets,
25
+ resolveVars,
24
26
  } from '../utils';
25
27
 
26
28
  const MAX_CONCURRENCY = 50;
@@ -31,6 +33,7 @@ export type ExtractArgs = ProgramArgs & {
31
33
  target?: string | string[];
32
34
  include?: string[];
33
35
  exclude?: string[];
36
+ vars?: Record<string, any>;
34
37
  };
35
38
 
36
39
  export type ExtractConfig = Pick<ProgramConfig, 'input' | 'strict' | 'quiet'> & {
@@ -40,6 +43,7 @@ export type ExtractConfig = Pick<ProgramConfig, 'input' | 'strict' | 'quiet'> &
40
43
  include: string[];
41
44
  exclude: string[];
42
45
  files: string[];
46
+ vars: Record<string, any>;
43
47
  };
44
48
 
45
49
  class ExtractLogger extends Logger {
@@ -68,6 +72,7 @@ export class Extract
68
72
  options.files,
69
73
  options.include,
70
74
  options.exclude,
75
+ options.vars,
71
76
  options.config(YFM_CONFIG_FILENAME),
72
77
  ];
73
78
 
@@ -96,6 +101,7 @@ export class Extract
96
101
  source.language,
97
102
  ['.md', '.yaml'],
98
103
  );
104
+ const vars = resolveVars(config, args);
99
105
 
100
106
  return Object.assign(config, {
101
107
  input,
@@ -107,12 +113,13 @@ export class Extract
107
113
  files,
108
114
  include,
109
115
  exclude,
116
+ vars,
110
117
  });
111
118
  });
112
119
  }
113
120
 
114
121
  async action() {
115
- const {input, output, files, source, target: targets} = this.config;
122
+ const {input, output, files, source, target: targets, vars} = this.config;
116
123
 
117
124
  this.logger.setup(this.config);
118
125
 
@@ -125,6 +132,7 @@ export class Extract
125
132
  target,
126
133
  input,
127
134
  output,
135
+ vars,
128
136
  });
129
137
 
130
138
  await eachLimit(
@@ -157,10 +165,11 @@ export type PipelineParameters = {
157
165
  output: string;
158
166
  source: ExtractOptions['source'];
159
167
  target: ExtractOptions['target'];
168
+ vars: Record<string, any>;
160
169
  };
161
170
 
162
171
  function pipeline(params: PipelineParameters) {
163
- const {input, output, source, target} = params;
172
+ const {input, output, source, target, vars} = params;
164
173
  const inputRoot = resolve(input);
165
174
  const outputRoot = resolve(output);
166
175
 
@@ -180,7 +189,14 @@ function pipeline(params: PipelineParameters) {
180
189
  return;
181
190
  }
182
191
 
183
- const content = await loadFile(inputPath);
192
+ let content = await loadFile(inputPath);
193
+ if (Object.keys(vars).length && typeof content === 'string') {
194
+ content = liquid(content, vars, inputPath, {
195
+ conditions: 'strict',
196
+ substitutions: false,
197
+ cycles: false,
198
+ });
199
+ }
184
200
 
185
201
  await mkdir(dirname(xliffPath), {recursive: true});
186
202
 
@@ -82,6 +82,19 @@ const exclude = option({
82
82
  parser: toArray,
83
83
  });
84
84
 
85
+ const vars = option({
86
+ flags: '-v, --vars <json>',
87
+ desc: `
88
+ Pass list of variables directly to translation.
89
+ Variables should be passed in JSON format.
90
+ Translation command ignores any presets.yaml.
91
+
92
+ Example:
93
+ {{PROGRAM}} -i ./ -o ./build -v '{"name":"test"}'
94
+ `,
95
+ parser: (value) => JSON.parse(value),
96
+ });
97
+
85
98
  const dryRun = option({
86
99
  flags: '--dry-run',
87
100
  desc: 'Do not execute target translation provider, but only calculate required quota.',
@@ -105,6 +118,7 @@ export const options = {
105
118
  files,
106
119
  include,
107
120
  exclude,
121
+ vars,
108
122
  dryRun,
109
123
  useSource,
110
124
  };
@@ -13,7 +13,7 @@ import {Extract} from './commands/extract';
13
13
  import {Compose} from './commands/compose';
14
14
  import {Extension as YandexTranslation} from './providers/yandex';
15
15
 
16
- import {resolveFiles, resolveSource, resolveTargets} from './utils';
16
+ import {resolveFiles, resolveSource, resolveTargets, resolveVars} from './utils';
17
17
 
18
18
  type Parent = IProgram & {
19
19
  translate: Translate;
@@ -42,6 +42,7 @@ export type TranslateArgs = ProgramArgs & {
42
42
  target?: string | string[];
43
43
  include?: string[];
44
44
  exclude?: string[];
45
+ vars?: Record<string, any>;
45
46
  };
46
47
 
47
48
  export type TranslateConfig = Pick<ProgramConfig, 'input' | 'strict' | 'quiet'> & {
@@ -52,6 +53,7 @@ export type TranslateConfig = Pick<ProgramConfig, 'input' | 'strict' | 'quiet'>
52
53
  include: string[];
53
54
  exclude: string[];
54
55
  files: string[];
56
+ vars: Record<string, any>;
55
57
  dryRun: boolean;
56
58
  };
57
59
 
@@ -101,6 +103,7 @@ export class Translate
101
103
  options.files,
102
104
  options.include,
103
105
  options.exclude,
106
+ options.vars,
104
107
  options.dryRun,
105
108
  options.config(YFM_CONFIG_FILENAME),
106
109
  ];
@@ -141,6 +144,7 @@ export class Translate
141
144
  source.language,
142
145
  ['.md', '.yaml'],
143
146
  );
147
+ const vars = resolveVars(config, args);
144
148
 
145
149
  return Object.assign(config, {
146
150
  input,
@@ -152,6 +156,7 @@ export class Translate
152
156
  files,
153
157
  include,
154
158
  exclude,
159
+ vars,
155
160
  provider: defined('provider', args, config),
156
161
  dryRun: defined('dryRun', args, config) || false,
157
162
  });
@@ -8,6 +8,7 @@ import axios, {AxiosError, AxiosResponse} from 'axios';
8
8
  import {LogLevel, Logger} from '~/logger';
9
9
  import {TranslateError, compose, dumpFile, extract, loadFile, resolveSchemas} from '../../utils';
10
10
  import {AuthError, Defer, LimitExceed, RequestError, bytes} from './utils';
11
+ import liquid from '@diplodoc/transform/lib/liquid';
11
12
 
12
13
  const REQUESTS_LIMIT = 15;
13
14
  const BYTES_LIMIT = 10000;
@@ -27,7 +28,7 @@ export class Provider {
27
28
  }
28
29
 
29
30
  async translate(files: string[], config: TranslateConfig & YandexTranslationConfig) {
30
- const {input, output, auth, folder, source, target: targets, dryRun} = config;
31
+ const {input, output, auth, folder, source, target: targets, vars, dryRun} = config;
31
32
 
32
33
  try {
33
34
  for (const target of targets) {
@@ -39,6 +40,7 @@ export class Provider {
39
40
  targetLanguage: target.language,
40
41
  // yandexCloudTranslateGlossaryPairs,
41
42
  folderId: folder,
43
+ vars,
42
44
  dryRun,
43
45
  };
44
46
 
@@ -90,6 +92,7 @@ type TranslatorParams = {
90
92
  output: string;
91
93
  sourceLanguage: string;
92
94
  targetLanguage: string;
95
+ vars: Record<string, any>;
93
96
  // yandexCloudTranslateGlossaryPairs: YandexCloudTranslateGlossaryPair[];
94
97
  };
95
98
 
@@ -233,7 +236,7 @@ function requester(params: RequesterParams, cache: Cache) {
233
236
  }
234
237
 
235
238
  function translator(params: TranslatorParams, split: Split) {
236
- const {input, output, sourceLanguage, targetLanguage} = params;
239
+ const {input, output, sourceLanguage, targetLanguage, vars} = params;
237
240
  const inputRoot = resolve(input);
238
241
  const outputRoot = resolve(output);
239
242
 
@@ -245,7 +248,15 @@ function translator(params: TranslatorParams, split: Split) {
245
248
 
246
249
  const inputPath = join(inputRoot, path);
247
250
  const outputPath = join(outputRoot, path.replace(sourceLanguage, targetLanguage));
248
- const content = await loadFile(inputPath);
251
+
252
+ let content = await loadFile(inputPath);
253
+ if (Object.keys(vars).length && typeof content === 'string') {
254
+ content = liquid(content, vars, inputPath, {
255
+ conditions: 'strict',
256
+ substitutions: false,
257
+ cycles: false,
258
+ });
259
+ }
249
260
 
250
261
  await mkdir(dirname(outputPath), {recursive: true});
251
262
 
@@ -2,6 +2,7 @@ import {ok} from 'node:assert';
2
2
  import {dirname, isAbsolute, relative, resolve} from 'node:path';
3
3
  import {readFileSync} from 'node:fs';
4
4
  import glob from 'glob';
5
+ import {merge} from 'lodash';
5
6
  import {filter} from 'minimatch';
6
7
  import {defined} from '~/config';
7
8
 
@@ -145,3 +146,10 @@ export function resolveFiles(
145
146
 
146
147
  return result;
147
148
  }
149
+
150
+ export function resolveVars(
151
+ config: {vars?: Record<string, any>},
152
+ args: {vars?: Record<string, any>},
153
+ ) {
154
+ return merge(config.vars || {}, args.vars);
155
+ }
@@ -1,5 +1,5 @@
1
1
  export type {Locale} from './config';
2
2
  export {dumpFile, loadFile, resolveSchemas} from './fs';
3
3
  export {extract, compose} from './translate';
4
- export {resolveSource, resolveTargets, resolveFiles} from './config';
4
+ export {resolveSource, resolveTargets, resolveFiles, resolveVars} from './config';
5
5
  export {TranslateError, ExtractError, ComposeError} from './errors';