@diplodoc/cli 4.0.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.
Files changed (74) hide show
  1. package/CHANGELOG.md +785 -0
  2. package/LICENSE +21 -0
  3. package/README.md +62 -0
  4. package/README.ru.md +63 -0
  5. package/build/app.client.css +47 -0
  6. package/build/app.client.js +3 -0
  7. package/build/index.js +3993 -0
  8. package/build/index.js.map +7 -0
  9. package/build/lib.js +3374 -0
  10. package/build/lib.js.map +7 -0
  11. package/build/linter.js +1265 -0
  12. package/build/linter.js.map +7 -0
  13. package/package.json +126 -0
  14. package/src/cmd/build/index.ts +304 -0
  15. package/src/cmd/index.ts +4 -0
  16. package/src/cmd/publish/index.ts +92 -0
  17. package/src/cmd/publish/upload.ts +61 -0
  18. package/src/cmd/translate/index.ts +261 -0
  19. package/src/cmd/xliff/compose.ts +222 -0
  20. package/src/cmd/xliff/extract.ts +237 -0
  21. package/src/cmd/xliff/index.ts +27 -0
  22. package/src/constants.ts +122 -0
  23. package/src/globals.d.ts +1 -0
  24. package/src/index.ts +54 -0
  25. package/src/models.ts +249 -0
  26. package/src/packages/credentials/index.ts +1 -0
  27. package/src/packages/credentials/yandex-oauth.ts +42 -0
  28. package/src/resolvers/index.ts +3 -0
  29. package/src/resolvers/lintPage.ts +119 -0
  30. package/src/resolvers/md2html.ts +142 -0
  31. package/src/resolvers/md2md.ts +147 -0
  32. package/src/services/argv.ts +38 -0
  33. package/src/services/authors.ts +64 -0
  34. package/src/services/contributors.ts +104 -0
  35. package/src/services/includers/batteries/common.ts +34 -0
  36. package/src/services/includers/batteries/generic.ts +130 -0
  37. package/src/services/includers/batteries/index.ts +3 -0
  38. package/src/services/includers/batteries/sourcedocs.ts +33 -0
  39. package/src/services/includers/batteries/unarchive.ts +97 -0
  40. package/src/services/includers/index.ts +157 -0
  41. package/src/services/index.ts +6 -0
  42. package/src/services/leading.ts +88 -0
  43. package/src/services/metadata.ts +249 -0
  44. package/src/services/plugins.ts +76 -0
  45. package/src/services/preset.ts +55 -0
  46. package/src/services/tocs.ts +401 -0
  47. package/src/services/utils.ts +151 -0
  48. package/src/steps/index.ts +6 -0
  49. package/src/steps/processAssets.ts +36 -0
  50. package/src/steps/processExcludedFiles.ts +47 -0
  51. package/src/steps/processLinter.ts +100 -0
  52. package/src/steps/processLogs.ts +18 -0
  53. package/src/steps/processMapFile.ts +35 -0
  54. package/src/steps/processPages.ts +312 -0
  55. package/src/steps/processServiceFiles.ts +95 -0
  56. package/src/steps/publishFilesToS3.ts +47 -0
  57. package/src/utils/file.ts +17 -0
  58. package/src/utils/glob.ts +14 -0
  59. package/src/utils/index.ts +8 -0
  60. package/src/utils/logger.ts +42 -0
  61. package/src/utils/markup.ts +125 -0
  62. package/src/utils/path.ts +24 -0
  63. package/src/utils/presets.ts +20 -0
  64. package/src/utils/singlePage.ts +228 -0
  65. package/src/utils/toc.ts +87 -0
  66. package/src/utils/url.ts +3 -0
  67. package/src/utils/worker.ts +10 -0
  68. package/src/validator.ts +150 -0
  69. package/src/vcs-connector/client/github.ts +52 -0
  70. package/src/vcs-connector/connector-models.ts +76 -0
  71. package/src/vcs-connector/connector-validator.ts +114 -0
  72. package/src/vcs-connector/github.ts +333 -0
  73. package/src/vcs-connector/index.ts +15 -0
  74. package/src/workers/linter/index.ts +62 -0
@@ -0,0 +1,55 @@
1
+ import {dirname, normalize} from 'path';
2
+
3
+ import {DocPreset, YfmPreset} from '../models';
4
+
5
+ export type PresetStorage = Map<string, YfmPreset>;
6
+
7
+ let presetStorage: PresetStorage = new Map();
8
+
9
+ function add(parsedPreset: DocPreset, path: string, varsPreset: string) {
10
+ const combinedValues: YfmPreset = {
11
+ ...parsedPreset.default || {},
12
+ ...parsedPreset[varsPreset] || {},
13
+ };
14
+
15
+ const key = dirname(normalize(path));
16
+ presetStorage.set(key, combinedValues);
17
+ }
18
+
19
+ function get(path: string): YfmPreset {
20
+ let combinedValues: YfmPreset = {};
21
+ let localPath = normalize(path);
22
+
23
+ while (localPath !== '.') {
24
+ const presetValues: YfmPreset = presetStorage.get(localPath) || {};
25
+ localPath = dirname(localPath);
26
+
27
+ combinedValues = {
28
+ ...presetValues,
29
+ ...combinedValues,
30
+ };
31
+ }
32
+
33
+ // Add root' presets
34
+ combinedValues = {
35
+ ...presetStorage.get('.'),
36
+ ...combinedValues,
37
+ };
38
+
39
+ return combinedValues;
40
+ }
41
+
42
+ function getPresetStorage(): Map<string, YfmPreset> {
43
+ return presetStorage;
44
+ }
45
+
46
+ function setPresetStorage(preset: Map<string, YfmPreset>): void {
47
+ presetStorage = preset;
48
+ }
49
+
50
+ export default {
51
+ add,
52
+ get,
53
+ getPresetStorage,
54
+ setPresetStorage,
55
+ };
@@ -0,0 +1,401 @@
1
+ import {dirname, extname, join, parse, resolve, relative, normalize, sep} from 'path';
2
+ import {copyFileSync, readFileSync, writeFileSync, existsSync} from 'fs';
3
+ import {load, dump} from 'js-yaml';
4
+ import shell from 'shelljs';
5
+ import walkSync from 'walk-sync';
6
+ import liquid from '@doc-tools/transform/lib/liquid';
7
+ import log from '@doc-tools/transform/lib/log';
8
+ import {bold} from 'chalk';
9
+
10
+ import {ArgvService, PresetService} from './index';
11
+ import {getContentWithUpdatedStaticMetadata} from './metadata';
12
+ import {YfmToc} from '../models';
13
+ import {Stage, IncludeMode} from '../constants';
14
+ import {isExternalHref, logger} from '../utils';
15
+ import {filterFiles, firstFilterTextItems, liquidField} from './utils';
16
+ import {applyIncluders, IncludersError} from './includers';
17
+
18
+ export interface TocServiceData {
19
+ storage: Map<string, YfmToc>;
20
+ navigationPaths: string[];
21
+ includedTocPaths: Set<string>;
22
+ }
23
+
24
+ const storage: TocServiceData['storage'] = new Map();
25
+ let navigationPaths: TocServiceData['navigationPaths'] = [];
26
+ const includedTocPaths: TocServiceData['includedTocPaths'] = new Set();
27
+
28
+ async function add(path: string) {
29
+ const {
30
+ input: inputFolderPath,
31
+ output: outputFolderPath,
32
+ outputFormat,
33
+ ignoreStage,
34
+ vars,
35
+ } = ArgvService.getConfig();
36
+
37
+ const pathToDir = dirname(path);
38
+ const content = readFileSync(resolve(inputFolderPath, path), 'utf8');
39
+ const parsedToc = load(content) as YfmToc;
40
+
41
+ // Should ignore toc with specified stage.
42
+ if (parsedToc.stage === ignoreStage) {
43
+ return;
44
+ }
45
+
46
+ const combinedVars = {
47
+ ...PresetService.get(pathToDir),
48
+ ...vars,
49
+ };
50
+
51
+ if (parsedToc.title) {
52
+ parsedToc.title = firstFilterTextItems(
53
+ parsedToc.title,
54
+ combinedVars,
55
+ {resolveConditions: true},
56
+ );
57
+ }
58
+
59
+ if (typeof parsedToc.title === 'string') {
60
+ parsedToc.title = liquidField(parsedToc.title, combinedVars, path);
61
+ }
62
+
63
+ parsedToc.items = await processTocItems(
64
+ path,
65
+ parsedToc.items,
66
+ join(inputFolderPath, pathToDir),
67
+ resolve(inputFolderPath),
68
+ combinedVars,
69
+ );
70
+
71
+ /* Store parsed toc for .md output format */
72
+ storage.set(path, parsedToc);
73
+
74
+ /* Store path to toc file to handle relative paths in navigation */
75
+ parsedToc.base = pathToDir;
76
+
77
+ if (outputFormat === 'md') {
78
+ /* Should copy resolved and filtered toc to output folder */
79
+ const outputPath = resolve(outputFolderPath, path);
80
+ const outputToc = dump(parsedToc);
81
+ shell.mkdir('-p', dirname(outputPath));
82
+ writeFileSync(outputPath, outputToc);
83
+ }
84
+
85
+ prepareNavigationPaths(parsedToc, pathToDir);
86
+ }
87
+
88
+ async function processTocItems(
89
+ path: string,
90
+ items: YfmToc[],
91
+ tocDir: string,
92
+ sourcesDir: string,
93
+ vars: Record<string, string>,
94
+ ) {
95
+ const {
96
+ resolveConditions,
97
+ removeHiddenTocItems,
98
+ } = ArgvService.getConfig();
99
+
100
+ let preparedItems = items;
101
+
102
+ /* Should remove all links with false expressions */
103
+ if (resolveConditions || removeHiddenTocItems) {
104
+ try {
105
+ preparedItems = filterFiles(items, 'items', vars, {
106
+ resolveConditions,
107
+ removeHiddenTocItems,
108
+ });
109
+ } catch (error) {
110
+ log.error(`Error while filtering toc file: ${path}. Error message: ${error}`);
111
+ }
112
+ }
113
+
114
+ /* Should resolve all includes */
115
+ return _replaceIncludes(path, preparedItems, tocDir, sourcesDir, vars);
116
+ }
117
+
118
+ function getForPath(path: string): YfmToc|undefined {
119
+ return storage.get(path);
120
+ }
121
+
122
+ function getNavigationPaths(): string[] {
123
+ return [...navigationPaths];
124
+ }
125
+
126
+ function getIncludedTocPaths(): string[] {
127
+ return [...includedTocPaths];
128
+ }
129
+
130
+ function prepareNavigationPaths(parsedToc: YfmToc, dirPath: string) {
131
+ function processItems(items: YfmToc[], pathToDir: string) {
132
+ items.forEach((item) => {
133
+ if (!parsedToc.singlePage && item.items) {
134
+ const preparedSubItems = item.items.map(((yfmToc: YfmToc, index: number) => {
135
+ // Generate personal id for each navigation item
136
+ yfmToc.id = `${yfmToc.name}-${index}-${Math.random()}`;
137
+ return yfmToc;
138
+ }));
139
+ processItems(preparedSubItems, pathToDir);
140
+ }
141
+
142
+ if (item.href && !isExternalHref(item.href)) {
143
+ const href = join(pathToDir, item.href);
144
+ storage.set(href, parsedToc);
145
+
146
+ const navigationPath = _normalizeHref(href);
147
+ navigationPaths.push(navigationPath);
148
+ }
149
+ });
150
+ }
151
+
152
+ processItems([parsedToc], dirPath);
153
+ }
154
+
155
+ /**
156
+ * Should normalize hrefs. MD and YAML files will be ignored.
157
+ * @param href
158
+ * @return {string}
159
+ * @example instance-groups/create-with-coi/ -> instance-groups/create-with-coi/index.yaml
160
+ * @example instance-groups/create-with-coi -> instance-groups/create-with-coi.md
161
+ * @private
162
+ */
163
+ function _normalizeHref(href: string): string {
164
+ const preparedHref = normalize(href);
165
+
166
+ if (preparedHref.endsWith('.md') || preparedHref.endsWith('.yaml')) {
167
+ return preparedHref;
168
+ }
169
+
170
+ if (preparedHref.endsWith(sep)) {
171
+ return `${preparedHref}index.yaml`;
172
+ }
173
+
174
+ return `${preparedHref}.md`;
175
+ }
176
+
177
+ /**
178
+ * Copies all files of include toc to original dir.
179
+ * @param tocPath
180
+ * @param destDir
181
+ * @return
182
+ * @private
183
+ */
184
+ function _copyTocDir(tocPath: string, destDir: string) {
185
+ const {input: inputFolderPath} = ArgvService.getConfig();
186
+
187
+ const {dir: tocDir} = parse(tocPath);
188
+ const files: string[] = walkSync(tocDir, {
189
+ globs: ['**/*.*'],
190
+ ignore: ['**/toc.yaml'],
191
+ directories: false,
192
+ });
193
+
194
+ files.forEach((relPath) => {
195
+ const from = resolve(tocDir, relPath);
196
+ const to = resolve(destDir, relPath);
197
+ const fileExtension = extname(relPath);
198
+ const isMdFile = fileExtension === '.md';
199
+
200
+ shell.mkdir('-p', parse(to).dir);
201
+
202
+ if (isMdFile) {
203
+ const fileContent = readFileSync(from, 'utf8');
204
+ const sourcePath = relative(inputFolderPath, from);
205
+ const updatedFileContent = getContentWithUpdatedStaticMetadata({
206
+ fileContent,
207
+ sourcePath,
208
+ addSourcePath: true,
209
+ });
210
+
211
+ writeFileSync(to, updatedFileContent);
212
+ } else {
213
+ copyFileSync(from, to);
214
+ }
215
+ });
216
+ }
217
+
218
+ /**
219
+ * Make hrefs relative to the main toc in the included toc.
220
+ * @param items
221
+ * @param includeTocDir
222
+ * @param tocDir
223
+ * @return
224
+ * @private
225
+ */
226
+ function _replaceIncludesHrefs(items: YfmToc[], includeTocDir: string, tocDir: string): YfmToc[] {
227
+ return items.reduce((acc, tocItem) => {
228
+ if (tocItem.href) {
229
+ tocItem.href = relative(tocDir, resolve(includeTocDir, tocItem.href));
230
+ }
231
+
232
+ if (tocItem.items) {
233
+ tocItem.items = _replaceIncludesHrefs(tocItem.items, includeTocDir, tocDir);
234
+ }
235
+
236
+ if (tocItem.include) {
237
+ const {path} = tocItem.include;
238
+ tocItem.include.path = relative(tocDir, resolve(includeTocDir, path));
239
+ }
240
+
241
+ return acc.concat(tocItem);
242
+ }, [] as YfmToc[]);
243
+ }
244
+
245
+ /**
246
+ * Liquid substitutions in toc file.
247
+ * @param input
248
+ * @param vars
249
+ * @param path
250
+ * @return {string}
251
+ * @private
252
+ */
253
+ function _liquidSubstitutions(input: string, vars: Record<string, string>, path: string) {
254
+ const {outputFormat, applyPresets} = ArgvService.getConfig();
255
+ if (outputFormat === 'md' && !applyPresets) {
256
+ return input;
257
+ }
258
+
259
+ return liquid(input, vars, path, {
260
+ conditions: false,
261
+ substitutions: true,
262
+ });
263
+ }
264
+
265
+ function addIncludeTocPath(includeTocPath: string) {
266
+ includedTocPaths.add(includeTocPath);
267
+ }
268
+
269
+ /**
270
+ * Replaces include fields in toc file by resolved toc.
271
+ * @param path
272
+ * @param items
273
+ * @param tocDir
274
+ * @param sourcesDir
275
+ * @param vars
276
+ * @return
277
+ * @private
278
+ */
279
+ async function _replaceIncludes(
280
+ path: string,
281
+ items: YfmToc[],
282
+ tocDir: string,
283
+ sourcesDir: string,
284
+ vars: Record<string, string>,
285
+ ): Promise<YfmToc[]> {
286
+ const result: YfmToc[] = [];
287
+
288
+ for (const item of items) {
289
+ let includedInlineItems: YfmToc[] | null = null;
290
+
291
+ if (item.name) {
292
+ const tocPath = join(tocDir, 'toc.yaml');
293
+
294
+ item.name = _liquidSubstitutions(item.name, vars, tocPath);
295
+ }
296
+
297
+ try {
298
+ await applyIncluders(path, item, vars);
299
+ } catch (err) {
300
+ if (err instanceof Error || err instanceof IncludersError) {
301
+ const message = err.toString();
302
+
303
+ const file = err instanceof IncludersError ? err.path : path;
304
+
305
+ logger.error(file, message);
306
+ }
307
+ }
308
+
309
+ if (item.include) {
310
+ const {mode = IncludeMode.ROOT_MERGE} = item.include;
311
+ const includeTocPath = mode === IncludeMode.ROOT_MERGE
312
+ ? resolve(sourcesDir, item.include.path)
313
+ : resolve(tocDir, item.include.path);
314
+ const includeTocDir = dirname(includeTocPath);
315
+
316
+ try {
317
+ const includeToc = load(readFileSync(includeTocPath, 'utf8')) as YfmToc;
318
+
319
+ // Should ignore included toc with tech-preview stage.
320
+ if (includeToc.stage === Stage.TECH_PREVIEW) {
321
+ continue;
322
+ }
323
+
324
+ if (mode === IncludeMode.MERGE || mode === IncludeMode.ROOT_MERGE) {
325
+ _copyTocDir(includeTocPath, tocDir);
326
+ }
327
+
328
+ /* Save the path to exclude toc from the output directory in the next step */
329
+ addIncludeTocPath(includeTocPath);
330
+
331
+ let includedTocItems = (item.items || []).concat(includeToc.items);
332
+
333
+ /* Resolve nested toc inclusions */
334
+ const baseTocDir = mode === IncludeMode.LINK ? includeTocDir : tocDir;
335
+ includedTocItems = await processTocItems(path, includedTocItems, baseTocDir, sourcesDir, vars);
336
+
337
+ /* Make hrefs relative to the main toc */
338
+ if (mode === IncludeMode.LINK) {
339
+ includedTocItems = _replaceIncludesHrefs(includedTocItems, includeTocDir, tocDir);
340
+ }
341
+
342
+ if (item.name) {
343
+ item.items = includedTocItems;
344
+ } else {
345
+ includedInlineItems = includedTocItems;
346
+ }
347
+ } catch (err) {
348
+ const message = (
349
+ `Error while including toc: ${bold(includeTocPath)} to ${bold(join(tocDir, 'toc.yaml'))}`
350
+ );
351
+
352
+ log.error(message);
353
+
354
+ continue;
355
+ } finally {
356
+ delete item.include;
357
+ }
358
+ } else if (item.items) {
359
+ item.items = await processTocItems(path, item.items, tocDir, sourcesDir, vars);
360
+ }
361
+
362
+ if (includedInlineItems) {
363
+ result.push(...includedInlineItems);
364
+ } else {
365
+ result.push(item);
366
+ }
367
+ }
368
+
369
+ return result;
370
+ }
371
+
372
+ function getTocDir(pagePath: string): string {
373
+ const {input: inputFolderPath} = ArgvService.getConfig();
374
+
375
+ const tocDir = dirname(pagePath);
376
+ const tocPath = resolve(tocDir, 'toc.yaml');
377
+
378
+
379
+ if (!tocDir.includes(inputFolderPath)) {
380
+ throw new Error('Error while finding toc dir');
381
+ }
382
+
383
+ if (existsSync(tocPath)) {
384
+ return tocDir;
385
+ }
386
+
387
+ return getTocDir(tocDir);
388
+ }
389
+
390
+ function setNavigationPaths(paths: TocServiceData['navigationPaths']) {
391
+ navigationPaths = paths;
392
+ }
393
+
394
+ export default {
395
+ add,
396
+ getForPath,
397
+ getNavigationPaths,
398
+ getTocDir,
399
+ getIncludedTocPaths,
400
+ setNavigationPaths,
401
+ };
@@ -0,0 +1,151 @@
1
+ import evalExp from '@doc-tools/transform/lib/liquid/evaluation';
2
+ import {Filter, TextItems} from '../models';
3
+ import liquid from '@doc-tools/transform/lib/liquid';
4
+ import {ArgvService} from './index';
5
+
6
+ export interface FilterFilesOptions {
7
+ resolveConditions?: boolean;
8
+ removeHiddenTocItems?: boolean;
9
+ }
10
+
11
+ /**
12
+ * Filters file by expression and removes empty file's items.
13
+ * @param items
14
+ * @param itemsKey
15
+ * @param vars
16
+ * @param options
17
+ * @return {T[]}
18
+ */
19
+ export function filterFiles<T extends Filter>(
20
+ items: T[],
21
+ itemsKey: string,
22
+ vars: Record<string, string>,
23
+ options?: FilterFilesOptions,
24
+ ): T[] {
25
+ if (!Array.isArray(items)) {
26
+ return [];
27
+ }
28
+
29
+ const reducer = (results: T[], item: T) => {
30
+ if (shouldProcessItem(item, vars, options)) {
31
+ const prop = item[itemsKey] as T[];
32
+
33
+ if (prop) {
34
+ const filteredProperty = filterFiles(prop, itemsKey, vars, options);
35
+
36
+ if (filteredProperty.length) {
37
+ results.push({
38
+ ...item,
39
+ [itemsKey]: filteredProperty,
40
+ });
41
+ }
42
+ } else {
43
+ results.push(item);
44
+ }
45
+ }
46
+
47
+ return results;
48
+ };
49
+
50
+ return items.reduce(reducer, []);
51
+ }
52
+
53
+ export function filterTextItems(
54
+ items: undefined | TextItems,
55
+ vars: Record<string, string>,
56
+ options?: FilterFilesOptions,
57
+ ) {
58
+ if (!Array.isArray(items)) {
59
+ return items;
60
+ }
61
+
62
+ return items.reduce((result: string[], item) => {
63
+ if (!isObject(item)) {
64
+ result.push(item);
65
+ return result;
66
+ }
67
+
68
+ const useItem = shouldProcessItem(item, vars, options);
69
+
70
+ if (useItem) {
71
+ if (Array.isArray(item.text)) {
72
+ result.push(...item.text);
73
+ } else {
74
+ result.push(item.text);
75
+ }
76
+ }
77
+
78
+ return result;
79
+ }, []);
80
+ }
81
+
82
+ export function firstFilterTextItems(
83
+ items: TextItems,
84
+ vars: Record<string, string>,
85
+ options?: FilterFilesOptions,
86
+ ) {
87
+ const filteredItems = filterTextItems(items, vars, options);
88
+
89
+ if (!Array.isArray(filteredItems)) {
90
+ return filteredItems || '';
91
+ }
92
+
93
+ return filteredItems[0] || '';
94
+ }
95
+
96
+ function shouldProcessItem<T extends Filter>(item: T, vars: Record<string, string>, options?: FilterFilesOptions) {
97
+ const {resolveConditions, removeHiddenTocItems} = options || {};
98
+ let useItem = true;
99
+
100
+ if (resolveConditions) {
101
+ const {when} = item;
102
+ useItem =
103
+ when === true || when === undefined || (typeof when === 'string' && evalExp(when, vars));
104
+
105
+ delete item.when;
106
+ }
107
+
108
+ if (useItem && removeHiddenTocItems) {
109
+ useItem = !item.hidden;
110
+
111
+ delete item.hidden;
112
+ }
113
+
114
+ return useItem;
115
+ }
116
+
117
+ export function liquidFields(fields: undefined | string | string[], vars: Record<string, unknown>, path: string) {
118
+ if (typeof fields === 'string') {
119
+ return liquidField(fields, vars, path);
120
+ }
121
+
122
+ if (!Array.isArray(fields)) {
123
+ return fields;
124
+ }
125
+
126
+ return fields.map((item) => {
127
+ if (typeof item === 'string') {
128
+ return liquidField(item, vars, path);
129
+ }
130
+ return item;
131
+ });
132
+ }
133
+
134
+ export function liquidField(input: string, vars: Record<string, unknown>, path: string) {
135
+ const {applyPresets, resolveConditions} = ArgvService.getConfig();
136
+
137
+ if (!applyPresets && !resolveConditions) {
138
+ return input;
139
+ }
140
+
141
+ return liquid(input, vars, path, {
142
+ substitutions: applyPresets,
143
+ conditions: resolveConditions,
144
+ keepNotVar: true,
145
+ withSourceMap: false,
146
+ });
147
+ }
148
+
149
+ export function isObject(o: unknown): o is object {
150
+ return typeof o === 'object' && o !== null;
151
+ }
@@ -0,0 +1,6 @@
1
+ export * from './processAssets';
2
+ export * from './processExcludedFiles';
3
+ export * from './processLogs';
4
+ export * from './processPages';
5
+ export * from './processLinter';
6
+ export * from './processServiceFiles';
@@ -0,0 +1,36 @@
1
+ import walkSync from 'walk-sync';
2
+ import shell from 'shelljs';
3
+
4
+ import client from '../../scripts/client';
5
+ import {ArgvService} from '../services';
6
+ import {copyFiles} from '../utils';
7
+
8
+ /**
9
+ * Processes assets files (everything except .yaml and .md files)
10
+ * @param {string} outputBundlePath
11
+ * @return {void}
12
+ */
13
+ export function processAssets(outputBundlePath: string) {
14
+ const {
15
+ input: inputFolderPath,
16
+ output: outputFolderPath,
17
+ } = ArgvService.getConfig();
18
+
19
+ const assetFilePath: string[] = walkSync(inputFolderPath, {
20
+ directories: false,
21
+ includeBasePath: false,
22
+ ignore: [
23
+ '**/*.yaml',
24
+ '**/*.md',
25
+ ],
26
+ });
27
+
28
+ copyFiles(inputFolderPath, outputFolderPath, assetFilePath);
29
+
30
+ /* Copy js bundle to user' output folder */
31
+ shell.mkdir('-p', outputBundlePath);
32
+
33
+ for (const path of Object.values(client.dst)) {
34
+ shell.cp(path, outputBundlePath);
35
+ }
36
+ }
@@ -0,0 +1,47 @@
1
+ import {resolve, relative} from 'path';
2
+ import walkSync from 'walk-sync';
3
+ import shell from 'shelljs';
4
+
5
+ import {ArgvService, TocService} from '../services';
6
+ import {convertBackSlashToSlash} from '../utils';
7
+
8
+ /**
9
+ * Removes all content files that unspecified in toc files or ignored.
10
+ * @return {void}
11
+ */
12
+ export function processExcludedFiles() {
13
+ const {
14
+ input: inputFolderPath,
15
+ output: outputFolderPath,
16
+ ignore,
17
+ } = ArgvService.getConfig();
18
+
19
+ const allContentFiles: string[] = walkSync(inputFolderPath, {
20
+ directories: false,
21
+ includeBasePath: true,
22
+ globs: [
23
+ '**/*.md',
24
+ '**/index.yaml',
25
+ ...ignore,
26
+ ],
27
+ // Ignores service directories like "_includes", "_templates" and etc.
28
+ ignore: ['**/_*/**/*'],
29
+ });
30
+ const navigationPaths = TocService.getNavigationPaths()
31
+ .map((filePath) => convertBackSlashToSlash(resolve(inputFolderPath, filePath)));
32
+ const tocSpecifiedFiles = new Set(navigationPaths);
33
+ const excludedFiles = allContentFiles
34
+ .filter((filePath) => !tocSpecifiedFiles.has(filePath));
35
+
36
+ shell.rm('-f', excludedFiles);
37
+
38
+ const includedTocPaths = TocService.getIncludedTocPaths()
39
+ .map((filePath) => {
40
+ const relativeTocPath = relative(inputFolderPath, filePath);
41
+ const destTocPath = resolve(outputFolderPath, relativeTocPath);
42
+
43
+ return convertBackSlashToSlash(destTocPath);
44
+ });
45
+
46
+ shell.rm('-rf', includedTocPaths);
47
+ }