Benjamin Cabanes 848436bca5
docs(nxdev): master docs is latest (#6975)
* docs(nxdev): master docs is latest

* docs(nxdev): update latest documentation

* docs(nxdev): removing NX ROOT
2021-09-13 13:55:18 +00:00

146 lines
3.6 KiB
TypeScript

import { readFileSync } from 'fs';
import { join, relative } from 'path';
import matter from 'gray-matter';
import { extractTitle } from './documents.utils';
import {
DocumentData,
DocumentMetadata,
VersionMetadata,
} from './documents.models';
export interface StaticDocumentPaths {
params: { segments: string[] };
}
export const flavorList: {
label: string;
value: string;
default?: boolean;
}[] = [
{ label: 'Angular', value: 'angular' },
{ label: 'React', value: 'react', default: true },
{ label: 'Node', value: 'node' },
];
export class DocumentsApi {
constructor(
private readonly options: {
publicDocsRoot: string;
versions: VersionMetadata[];
documentsMap: Map<string, DocumentMetadata[]>;
}
) {
if (!options.publicDocsRoot) {
throw new Error('public docs root cannot be undefined');
}
}
getDefaultVersion(): VersionMetadata {
const found = this.options.versions.find((v) => v.default);
if (found) return found;
throw new Error('Cannot find default version');
}
getVersions(): VersionMetadata[] {
return this.options.versions;
}
getDocument(
versionId: string,
flavorId: string,
path: string[]
): DocumentData {
const docPath = this.getFilePath(versionId, flavorId, path);
const originalContent = readFileSync(docPath, 'utf8');
const file = matter(originalContent);
// Set default title if not provided in front-matter section.
if (!file.data.title) {
file.data.title = extractTitle(originalContent) ?? path[path.length - 1];
}
return {
filePath: join(this.options.publicDocsRoot, docPath),
data: file.data,
content: file.content,
excerpt: file.excerpt,
};
}
getDocuments(version: string) {
const docs = this.options.documentsMap.get(version);
if (docs) {
return docs;
} else {
throw new Error(`Cannot find documents for ${version}`);
}
}
getStaticDocumentPaths(version: string): StaticDocumentPaths[] {
const paths: StaticDocumentPaths[] = [];
const defaultVersion = this.getDefaultVersion();
function recur(curr, acc) {
if (curr.itemList) {
curr.itemList.forEach((ii) => {
recur(ii, [...acc, curr.id]);
});
} else {
paths.push({
params: {
segments: [version, ...acc, curr.id],
},
});
// For generic paths such as `/getting-started/intro`, use the default version and react flavor.
if (version === defaultVersion.id && acc[0] === 'react') {
paths.push({
params: {
segments: [...acc.slice(1), curr.id],
},
});
}
}
}
this.getDocuments(version).forEach((item) => {
recur(item, []);
});
return paths;
}
getDocumentsRoot(version: string): string {
const versionPath = this.options.versions.find(
(x) => x.id === version
)?.path;
if (versionPath) {
return join(this.options.publicDocsRoot, versionPath);
}
throw new Error(`Cannot find root for ${version}`);
}
private getFilePath(versionId, flavorId, path): string {
let items = this.getDocuments(versionId).find(
(item) => item.id === flavorId
)?.itemList;
if (!items) {
throw new Error(`Document not found`);
}
let found;
for (const part of path) {
found = items?.find((item) => item.id === part);
if (found) {
items = found.itemList;
} else {
throw new Error(`Document not found`);
}
}
const file = found.file ?? [flavorId, ...path].join('/');
return join(this.getDocumentsRoot(versionId), `${file}.md`);
}
}