@diplodoc/cli 4.11.0 → 4.12.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/src/models.ts CHANGED
@@ -7,7 +7,13 @@ import {ChangelogItem} from '@diplodoc/transform/lib/plugins/changelog/types';
7
7
 
8
8
  export type VarsPreset = 'internal' | 'external';
9
9
 
10
- export type YfmPreset = Record<string, string>;
10
+ export type VarsMetadata = {
11
+ [field: string]: string;
12
+ }[];
13
+
14
+ export type YfmPreset = Record<string, string> & {
15
+ __metadata?: VarsMetadata;
16
+ };
11
17
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
18
  export type Metadata = Record<string, any>;
13
19
 
@@ -43,6 +49,7 @@ interface YfmConfig {
43
49
  resources?: Resources;
44
50
  yandexCloudTranslateFolderId: string;
45
51
  yandexCloudTranslateGlossaryPairs: YandexCloudTranslateGlossaryPair[];
52
+ needToSanitizeHtml: boolean;
46
53
  }
47
54
 
48
55
  export interface YfmArgv extends YfmConfig {
@@ -65,10 +72,12 @@ export interface YfmArgv extends YfmConfig {
65
72
  staticContent: boolean;
66
73
  }
67
74
 
68
- export interface DocPreset {
75
+ export type DocPreset = {
69
76
  default: YfmPreset;
70
77
  [varsPreset: string]: YfmPreset;
71
- }
78
+ } & {
79
+ __metadata: Record<string, string>[];
80
+ };
72
81
 
73
82
  export interface YfmToc extends Filter {
74
83
  name: string;
@@ -16,7 +16,7 @@ import {
16
16
  transformToc,
17
17
  } from '../utils';
18
18
  import {Lang, PROCESSING_FINISHED} from '../constants';
19
- import {getAssetsPublicPath, getUpdatedMetadata} from '../services/metadata';
19
+ import {getAssetsPublicPath, getVCSMetadata} from '../services/metadata';
20
20
  import {MarkdownItPluginCb} from '@diplodoc/transform/lib/plugins/typings';
21
21
 
22
22
  export interface FileTransformOptions {
@@ -42,6 +42,7 @@ export async function resolveMd2HTML(options: ResolverOptions): Promise<ResolveM
42
42
  const pathToFileDir: string =
43
43
  pathToDir === tocBase ? '' : pathToDir.replace(`${tocBase}${sep}`, '');
44
44
  const relativePathToIndex = relative(pathToDir, `${tocBase}${sep}`);
45
+ const vars = getVarsPerFile(inputPath);
45
46
 
46
47
  const {input, lang, allowCustomResources} = ArgvService.getConfig();
47
48
  const resolvedPath: string = resolve(input, inputPath);
@@ -50,13 +51,18 @@ export async function resolveMd2HTML(options: ResolverOptions): Promise<ResolveM
50
51
  const transformFn: Function = FileTransformer[fileExtension];
51
52
  const {result} = transformFn(content, {path: inputPath});
52
53
 
53
- const updatedMetadata =
54
- metadata && metadata.isContributorsEnabled
55
- ? await getUpdatedMetadata(metadata, content, result?.meta)
56
- : result.meta;
54
+ const updatedMetadata = metadata?.isContributorsEnabled
55
+ ? await getVCSMetadata(metadata, content, result?.meta)
56
+ : result.meta;
57
57
 
58
58
  const fileMeta = fileExtension === '.yaml' ? result.data.meta ?? {} : updatedMetadata;
59
59
 
60
+ if (Array.isArray(fileMeta?.metadata)) {
61
+ fileMeta.metadata.push(...(vars.__metadata || []));
62
+ } else {
63
+ fileMeta.metadata = vars.__metadata || [];
64
+ }
65
+
60
66
  if (allowCustomResources) {
61
67
  const {script, style} = metadata?.resources || {};
62
68
  fileMeta.style = (fileMeta.style || []).concat(style || []).map(fixRelativePath(inputPath));
@@ -21,6 +21,7 @@ export async function resolveMd2Md(options: ResolveMd2MdOptions): Promise<void>
21
21
  readFileSync(resolvedInputPath, 'utf8'),
22
22
  metadata,
23
23
  vars.__system,
24
+ vars.__metadata,
24
25
  );
25
26
 
26
27
  const {result, changelogs} = transformMd2Md(content, {
@@ -1,7 +1,7 @@
1
- import {dump} from 'js-yaml';
1
+ import {dump, load} from 'js-yaml';
2
2
 
3
3
  import {VCSConnector} from '../vcs-connector/connector-models';
4
- import {MetaDataOptions, Metadata, Resources} from '../models';
4
+ import {MetaDataOptions, Metadata, Resources, VarsMetadata} from '../models';
5
5
  import {
6
6
  getAuthorDetails,
7
7
  updateAuthorMetadataStringByAuthorLogin,
@@ -22,6 +22,7 @@ async function getContentWithUpdatedMetadata(
22
22
  fileContent: string,
23
23
  options?: MetaDataOptions,
24
24
  systemVars?: unknown,
25
+ metadataVars?: VarsMetadata,
25
26
  ): Promise<string> {
26
27
  let result;
27
28
 
@@ -32,7 +33,9 @@ async function getContentWithUpdatedMetadata(
32
33
  addSourcePath: options?.addSourcePath,
33
34
  resources: options?.resources,
34
35
  systemVars,
36
+ metadataVars,
35
37
  });
38
+
36
39
  result = await getContentWithUpdatedDynamicMetadata(result, options);
37
40
 
38
41
  return result;
@@ -45,6 +48,7 @@ function getContentWithUpdatedStaticMetadata({
45
48
  addSourcePath,
46
49
  resources,
47
50
  systemVars,
51
+ metadataVars = [],
48
52
  }: {
49
53
  fileContent: string;
50
54
  sourcePath?: string;
@@ -52,10 +56,16 @@ function getContentWithUpdatedStaticMetadata({
52
56
  addSourcePath?: boolean;
53
57
  resources?: Resources;
54
58
  systemVars?: unknown;
59
+ metadataVars?: VarsMetadata;
55
60
  }): string {
56
61
  const newMetadatas: string[] = [];
57
62
 
58
- if ((!addSystemMeta || !systemVars) && !addSourcePath && !resources) {
63
+ if (
64
+ (!addSystemMeta || !systemVars) &&
65
+ !addSourcePath &&
66
+ !resources &&
67
+ metadataVars.length === 0
68
+ ) {
59
69
  return fileContent;
60
70
  }
61
71
 
@@ -77,7 +87,25 @@ function getContentWithUpdatedStaticMetadata({
77
87
  if (matches && matches.length > 0) {
78
88
  const [, fileMetadata, , fileMainContent] = matches;
79
89
 
80
- return `${getUpdatedMetadataString(newMetadatas, fileMetadata)}${fileMainContent}`;
90
+ if (!metadataVars.length) {
91
+ return `${getUpdatedMetadataString(newMetadatas, fileMetadata)}${fileMainContent}`;
92
+ }
93
+
94
+ const parsed = load(fileMetadata) as Record<string, any>;
95
+
96
+ if (!Array.isArray(parsed.metadata)) {
97
+ parsed.metadata = [parsed.metadata];
98
+ }
99
+
100
+ parsed.metadata = parsed.metadata.concat(metadataVars);
101
+
102
+ const patchedMetada = dump(parsed);
103
+
104
+ return `${getUpdatedMetadataString(newMetadatas, patchedMetada)}${fileMainContent}`;
105
+ }
106
+
107
+ if (metadataVars.length) {
108
+ newMetadatas.push(dump({metadata: metadataVars}));
81
109
  }
82
110
 
83
111
  return `${getUpdatedMetadataString(newMetadatas)}${fileContent}`;
@@ -239,7 +267,7 @@ function getUpdatedMetadataString(newMetadatas: string[], defaultMetadata = ''):
239
267
  }`;
240
268
  }
241
269
 
242
- async function getUpdatedMetadata(
270
+ async function getVCSMetadata(
243
271
  options: MetaDataOptions,
244
272
  fileContent: string,
245
273
  meta?: Metadata,
@@ -309,6 +337,6 @@ function getAssetsPublicPath(filePath: string) {
309
337
  export {
310
338
  getContentWithUpdatedMetadata,
311
339
  getContentWithUpdatedStaticMetadata,
312
- getUpdatedMetadata,
340
+ getVCSMetadata,
313
341
  getAssetsPublicPath,
314
342
  };
@@ -7,10 +7,11 @@ export type PresetStorage = Map<string, YfmPreset>;
7
7
  let presetStorage: PresetStorage = new Map();
8
8
 
9
9
  function add(parsedPreset: DocPreset, path: string, varsPreset: string) {
10
- const combinedValues: YfmPreset = {
10
+ const combinedValues = {
11
11
  ...(parsedPreset.default || {}),
12
12
  ...(parsedPreset[varsPreset] || {}),
13
- };
13
+ __metadata: parsedPreset.__metadata,
14
+ } as YfmPreset;
14
15
 
15
16
  const key = dirname(normalize(path));
16
17
  presetStorage.set(key, combinedValues);
@@ -1,34 +1,42 @@
1
1
  import {join} from 'path';
2
2
  import {platform} from 'process';
3
3
 
4
- import {CUSTOM_STYLE, Platforms, ResourceType} from '../constants';
5
- import {Resources, SinglePageResult} from '../models';
4
+ import {CUSTOM_STYLE, Platforms} from '../constants';
5
+ import {LeadingPage, Resources, SinglePageResult, TextItems, VarsMetadata} from '../models';
6
6
  import {ArgvService, PluginService} from '../services';
7
7
  import {preprocessPageHtmlForSinglePage} from './singlePage';
8
8
 
9
9
  import {DocInnerProps, DocPageData, render} from '@diplodoc/client/ssr';
10
10
  import manifest from '@diplodoc/client/manifest';
11
11
 
12
+ import {escape} from 'html-escaper';
13
+
12
14
  const dst = (bundlePath: string) => (target: string) => join(bundlePath, target);
15
+ export const сarriage = platform === Platforms.WINDOWS ? '\r\n' : '\n';
13
16
 
14
17
  export interface TitleMeta {
15
18
  title?: string;
16
19
  }
17
- export type Meta = TitleMeta & Resources;
20
+
21
+ export type Meta = TitleMeta &
22
+ Resources & {
23
+ metadata: VarsMetadata;
24
+ };
18
25
 
19
26
  export function generateStaticMarkup(
20
27
  props: DocInnerProps<DocPageData>,
21
28
  pathToBundle: string,
22
29
  ): string {
23
- const {title: metaTitle, style, script} = (props.data.meta as Meta) || {};
30
+ const {style, script, metadata, ...restYamlConfigMeta} = (props.data.meta as Meta) || {};
24
31
  const {title: tocTitle} = props.data.toc;
25
32
  const {title: pageTitle} = props.data;
26
33
 
27
34
  const title = getTitle({
28
- metaTitle,
35
+ metaTitle: props.data.meta.title,
29
36
  tocTitle: tocTitle as string,
30
37
  pageTitle,
31
38
  });
39
+
32
40
  const resources = getResources({style, script});
33
41
 
34
42
  const {staticContent} = ArgvService.getConfig();
@@ -40,7 +48,7 @@ export function generateStaticMarkup(
40
48
  <html lang="${props.lang}">
41
49
  <head>
42
50
  <meta charset="utf-8">
43
- ${getMetadata(props.data.meta as Record<string, string>)}
51
+ ${getMetadata(metadata, restYamlConfigMeta)}
44
52
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
45
53
  <title>${title}</title>
46
54
  <style type="text/css">
@@ -93,21 +101,32 @@ function getTitle({tocTitle, metaTitle, pageTitle}: GetTitleOptions) {
93
101
  return resultPageTitle && tocTitle ? `${resultPageTitle} | ${tocTitle}` : '';
94
102
  }
95
103
 
96
- function getMetadata(metadata: Record<string, string>): string {
97
- if (!metadata) {
98
- return '';
104
+ function getMetadata(metadata: VarsMetadata | undefined, restMeta: LeadingPage['meta']): string {
105
+ let result = '';
106
+
107
+ const addMetaTagsFromObject = (value: Record<string, string | boolean | TextItems>) => {
108
+ const args = Object.entries(value).reduce((acc, [name, content]) => {
109
+ return acc + `${escape(name)}="${escape(content.toString())}" `;
110
+ }, '');
111
+
112
+ if (args.length) {
113
+ result += `<meta ${args} />` + сarriage;
114
+ }
115
+ };
116
+
117
+ if (metadata) {
118
+ metadata.forEach(addMetaTagsFromObject);
99
119
  }
100
120
 
101
- // Exclude resources from meta, proceed them separately
102
- const metaEntries = Object.entries(metadata).filter(
103
- ([key]) => !Object.keys(ResourceType).includes(key),
104
- );
121
+ if (restMeta) {
122
+ Object.entries(restMeta)
123
+ .map(([name, value]) => {
124
+ return {name, content: value};
125
+ })
126
+ .forEach(addMetaTagsFromObject);
127
+ }
105
128
 
106
- return metaEntries
107
- .map(([name, content]) => {
108
- return `<meta name="${name}" content="${content}">`;
109
- })
110
- .join('\n');
129
+ return result;
111
130
  }
112
131
 
113
132
  function getResources({style, script}: Resources) {
@@ -130,8 +149,6 @@ function getResources({style, script}: Resources) {
130
149
  return resourcesTags.join('\n');
131
150
  }
132
151
 
133
- export const сarriage = platform === Platforms.WINDOWS ? '\r\n' : '\n';
134
-
135
152
  export function joinSinglePageResults(
136
153
  singlePageResults: SinglePageResult[],
137
154
  root: string,
@@ -1,14 +1,17 @@
1
1
  import {dirname, relative, resolve} from 'path';
2
2
 
3
3
  import {ArgvService, PresetService} from '../services';
4
+ import {YfmPreset} from '../models';
4
5
 
5
- export function getVarsPerFile(filePath: string): Record<string, string> {
6
+ export function getVarsPerFile(filePath: string): YfmPreset {
6
7
  const {vars: argVars} = ArgvService.getConfig();
7
8
 
8
- return {
9
+ const result = {
9
10
  ...PresetService.get(dirname(filePath)),
10
11
  ...argVars,
11
12
  };
13
+
14
+ return result;
12
15
  }
13
16
 
14
17
  export function getVarsPerRelativeFile(filePath: string): Record<string, string> {