Skip to content

Commit

Permalink
Merge pull request #639 from diplodoc-platform/meta-support
Browse files Browse the repository at this point in the history
feat: support meta
  • Loading branch information
v8tenko committed Jan 30, 2024
2 parents 22957d8 + 5073b66 commit 7be29c1
Show file tree
Hide file tree
Showing 27 changed files with 548 additions and 136 deletions.
6 changes: 0 additions & 6 deletions .eslintrc

This file was deleted.

11 changes: 11 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = {
"extends": ["@diplodoc/eslint-config"],
"root": true,
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
},
"env": {
"node": true
}
}
14 changes: 11 additions & 3 deletions src/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ import {ChangelogItem} from '@diplodoc/transform/lib/plugins/changelog/types';

export type VarsPreset = 'internal' | 'external';

export type YfmPreset = Record<string, string>;
export type VarsMetadata = {
[field: string]: string;
}[];

export type YfmPreset = Record<string, string> & {
__metadata?: VarsMetadata;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type Metadata = Record<string, any>;

Expand Down Expand Up @@ -66,10 +72,12 @@ export interface YfmArgv extends YfmConfig {
staticContent: boolean;
}

export interface DocPreset {
export type DocPreset = {
default: YfmPreset;
[varsPreset: string]: YfmPreset;
}
} & {
__metadata: Record<string, string>[];
};

export interface YfmToc extends Filter {
name: string;
Expand Down
16 changes: 11 additions & 5 deletions src/resolvers/md2html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
transformToc,
} from '../utils';
import {Lang, PROCESSING_FINISHED} from '../constants';
import {getAssetsPublicPath, getUpdatedMetadata} from '../services/metadata';
import {getAssetsPublicPath, getVCSMetadata} from '../services/metadata';
import {MarkdownItPluginCb} from '@diplodoc/transform/lib/plugins/typings';

export interface FileTransformOptions {
Expand All @@ -42,6 +42,7 @@ export async function resolveMd2HTML(options: ResolverOptions): Promise<ResolveM
const pathToFileDir: string =
pathToDir === tocBase ? '' : pathToDir.replace(`${tocBase}${sep}`, '');
const relativePathToIndex = relative(pathToDir, `${tocBase}${sep}`);
const vars = getVarsPerFile(inputPath);

const {input, lang, allowCustomResources} = ArgvService.getConfig();
const resolvedPath: string = resolve(input, inputPath);
Expand All @@ -50,13 +51,18 @@ export async function resolveMd2HTML(options: ResolverOptions): Promise<ResolveM
const transformFn: Function = FileTransformer[fileExtension];
const {result} = transformFn(content, {path: inputPath});

const updatedMetadata =
metadata && metadata.isContributorsEnabled
? await getUpdatedMetadata(metadata, content, result?.meta)
: result.meta;
const updatedMetadata = metadata?.isContributorsEnabled
? await getVCSMetadata(metadata, content, result?.meta)
: result.meta;

const fileMeta = fileExtension === '.yaml' ? result.data.meta ?? {} : updatedMetadata;

if (Array.isArray(fileMeta?.metadata)) {
fileMeta.metadata.push(...(vars.__metadata || []));
} else {
fileMeta.metadata = vars.__metadata || [];
}

if (allowCustomResources) {
const {script, style} = metadata?.resources || {};
fileMeta.style = (fileMeta.style || []).concat(style || []).map(fixRelativePath(inputPath));
Expand Down
1 change: 1 addition & 0 deletions src/resolvers/md2md.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export async function resolveMd2Md(options: ResolveMd2MdOptions): Promise<void>
readFileSync(resolvedInputPath, 'utf8'),
metadata,
vars.__system,
vars.__metadata,
);

const {result, changelogs} = transformMd2Md(content, {
Expand Down
40 changes: 34 additions & 6 deletions src/services/metadata.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {dump} from 'js-yaml';
import {dump, load} from 'js-yaml';

import {VCSConnector} from '../vcs-connector/connector-models';
import {MetaDataOptions, Metadata, Resources} from '../models';
import {MetaDataOptions, Metadata, Resources, VarsMetadata} from '../models';
import {
getAuthorDetails,
updateAuthorMetadataStringByAuthorLogin,
Expand All @@ -22,6 +22,7 @@ async function getContentWithUpdatedMetadata(
fileContent: string,
options?: MetaDataOptions,
systemVars?: unknown,
metadataVars?: VarsMetadata,
): Promise<string> {
let result;

Expand All @@ -32,7 +33,9 @@ async function getContentWithUpdatedMetadata(
addSourcePath: options?.addSourcePath,
resources: options?.resources,
systemVars,
metadataVars,
});

result = await getContentWithUpdatedDynamicMetadata(result, options);

return result;
Expand All @@ -45,17 +48,24 @@ function getContentWithUpdatedStaticMetadata({
addSourcePath,
resources,
systemVars,
metadataVars = [],
}: {
fileContent: string;
sourcePath?: string;
addSystemMeta?: boolean;
addSourcePath?: boolean;
resources?: Resources;
systemVars?: unknown;
metadataVars?: VarsMetadata;
}): string {
const newMetadatas: string[] = [];

if ((!addSystemMeta || !systemVars) && !addSourcePath && !resources) {
if (
(!addSystemMeta || !systemVars) &&
!addSourcePath &&
!resources &&
metadataVars.length === 0
) {
return fileContent;
}

Expand All @@ -77,7 +87,25 @@ function getContentWithUpdatedStaticMetadata({
if (matches && matches.length > 0) {
const [, fileMetadata, , fileMainContent] = matches;

return `${getUpdatedMetadataString(newMetadatas, fileMetadata)}${fileMainContent}`;
if (!metadataVars.length) {
return `${getUpdatedMetadataString(newMetadatas, fileMetadata)}${fileMainContent}`;
}

const parsed = load(fileMetadata) as Record<string, any>;

if (!Array.isArray(parsed.metadata)) {
parsed.metadata = [parsed.metadata];
}

parsed.metadata = parsed.metadata.concat(metadataVars);

const patchedMetada = dump(parsed);

return `${getUpdatedMetadataString(newMetadatas, patchedMetada)}${fileMainContent}`;
}

if (metadataVars.length) {
newMetadatas.push(dump({metadata: metadataVars}));
}

return `${getUpdatedMetadataString(newMetadatas)}${fileContent}`;
Expand Down Expand Up @@ -239,7 +267,7 @@ function getUpdatedMetadataString(newMetadatas: string[], defaultMetadata = ''):
}`;
}

async function getUpdatedMetadata(
async function getVCSMetadata(
options: MetaDataOptions,
fileContent: string,
meta?: Metadata,
Expand Down Expand Up @@ -309,6 +337,6 @@ function getAssetsPublicPath(filePath: string) {
export {
getContentWithUpdatedMetadata,
getContentWithUpdatedStaticMetadata,
getUpdatedMetadata,
getVCSMetadata,
getAssetsPublicPath,
};
5 changes: 3 additions & 2 deletions src/services/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ export type PresetStorage = Map<string, YfmPreset>;
let presetStorage: PresetStorage = new Map();

function add(parsedPreset: DocPreset, path: string, varsPreset: string) {
const combinedValues: YfmPreset = {
const combinedValues = {
...(parsedPreset.default || {}),
...(parsedPreset[varsPreset] || {}),
};
__metadata: parsedPreset.__metadata,
} as YfmPreset;

const key = dirname(normalize(path));
presetStorage.set(key, combinedValues);
Expand Down
57 changes: 37 additions & 20 deletions src/utils/markup.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,42 @@
import {join} from 'path';
import {platform} from 'process';

import {CUSTOM_STYLE, Platforms, ResourceType} from '../constants';
import {Resources, SinglePageResult} from '../models';
import {CUSTOM_STYLE, Platforms} from '../constants';
import {LeadingPage, Resources, SinglePageResult, TextItems, VarsMetadata} from '../models';
import {ArgvService, PluginService} from '../services';
import {preprocessPageHtmlForSinglePage} from './singlePage';

import {DocInnerProps, DocPageData, render} from '@diplodoc/client/ssr';
import manifest from '@diplodoc/client/manifest';

import {escape} from 'html-escaper';

const dst = (bundlePath: string) => (target: string) => join(bundlePath, target);
export const сarriage = platform === Platforms.WINDOWS ? '\r\n' : '\n';

export interface TitleMeta {
title?: string;
}
export type Meta = TitleMeta & Resources;

export type Meta = TitleMeta &
Resources & {
metadata: VarsMetadata;
};

export function generateStaticMarkup(
props: DocInnerProps<DocPageData>,
pathToBundle: string,
): string {
const {title: metaTitle, style, script} = (props.data.meta as Meta) || {};
const {style, script, metadata, ...restYamlConfigMeta} = (props.data.meta as Meta) || {};
const {title: tocTitle} = props.data.toc;
const {title: pageTitle} = props.data;

const title = getTitle({
metaTitle,
metaTitle: props.data.meta.title,
tocTitle: tocTitle as string,
pageTitle,
});

const resources = getResources({style, script});

const {staticContent} = ArgvService.getConfig();
Expand All @@ -40,7 +48,7 @@ export function generateStaticMarkup(
<html lang="${props.lang}">
<head>
<meta charset="utf-8">
${getMetadata(props.data.meta as Record<string, string>)}
${getMetadata(metadata, restYamlConfigMeta)}
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${title}</title>
<style type="text/css">
Expand Down Expand Up @@ -93,21 +101,32 @@ function getTitle({tocTitle, metaTitle, pageTitle}: GetTitleOptions) {
return resultPageTitle && tocTitle ? `${resultPageTitle} | ${tocTitle}` : '';
}

function getMetadata(metadata: Record<string, string>): string {
if (!metadata) {
return '';
function getMetadata(metadata: VarsMetadata | undefined, restMeta: LeadingPage['meta']): string {
let result = '';

const addMetaTagsFromObject = (value: Record<string, string | boolean | TextItems>) => {
const args = Object.entries(value).reduce((acc, [name, content]) => {
return acc + `${escape(name)}="${escape(content.toString())}" `;
}, '');

if (args.length) {
result += `<meta ${args} />` + сarriage;
}
};

if (metadata) {
metadata.forEach(addMetaTagsFromObject);
}

// Exclude resources from meta, proceed them separately
const metaEntries = Object.entries(metadata).filter(
([key]) => !Object.keys(ResourceType).includes(key),
);
if (restMeta) {
Object.entries(restMeta)
.map(([name, value]) => {
return {name, content: value};
})
.forEach(addMetaTagsFromObject);
}

return metaEntries
.map(([name, content]) => {
return `<meta name="${name}" content="${content}">`;
})
.join('\n');
return result;
}

function getResources({style, script}: Resources) {
Expand All @@ -130,8 +149,6 @@ function getResources({style, script}: Resources) {
return resourcesTags.join('\n');
}

export const сarriage = platform === Platforms.WINDOWS ? '\r\n' : '\n';

export function joinSinglePageResults(
singlePageResults: SinglePageResult[],
root: string,
Expand Down
7 changes: 5 additions & 2 deletions src/utils/presets.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import {dirname, relative, resolve} from 'path';

import {ArgvService, PresetService} from '../services';
import {YfmPreset} from '../models';

export function getVarsPerFile(filePath: string): Record<string, string> {
export function getVarsPerFile(filePath: string): YfmPreset {
const {vars: argVars} = ArgvService.getConfig();

return {
const result = {
...PresetService.get(dirname(filePath)),
...argVars,
};

return result;
}

export function getVarsPerRelativeFile(filePath: string): Record<string, string> {
Expand Down
Loading

0 comments on commit 7be29c1

Please sign in to comment.