mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-09 15:17:23 +02:00
* Add edit page url in docs * feat(v2): Create EditPage component * feat(v2): Improve component * Add test * çhore(v2): update description * çhore(v2): update url * fix(v2): test * fix(v2): test * feat(v2): change the prop of EditPage component * chore(v2): Remove packages * feat(v2): Update old tests * chore(v2): fix package * fix(v2): fix editUrl * docs(v2): document editUrl * -- * -- Co-authored-by: Yangshun Tay <tay.yang.shun@gmail.com>
146 lines
3.8 KiB
TypeScript
146 lines
3.8 KiB
TypeScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
import fs from 'fs-extra';
|
|
import path from 'path';
|
|
import {
|
|
parse,
|
|
aliasedSitePath,
|
|
normalizeUrl,
|
|
getEditUrl,
|
|
} from '@docusaurus/utils';
|
|
import {LoadContext} from '@docusaurus/types';
|
|
|
|
import lastUpdate from './lastUpdate';
|
|
import {MetadataRaw, LastUpdateData, MetadataOptions, Env} from './types';
|
|
|
|
type Args = {
|
|
source: string;
|
|
refDir: string;
|
|
context: LoadContext;
|
|
options: MetadataOptions;
|
|
env: Env;
|
|
};
|
|
|
|
async function lastUpdated(
|
|
filePath: string,
|
|
options: MetadataOptions,
|
|
): Promise<LastUpdateData> {
|
|
const {showLastUpdateAuthor, showLastUpdateTime} = options;
|
|
if (showLastUpdateAuthor || showLastUpdateTime) {
|
|
// Use fake data in dev for faster development.
|
|
const fileLastUpdateData =
|
|
process.env.NODE_ENV === 'production'
|
|
? await lastUpdate(filePath)
|
|
: {
|
|
author: 'Author',
|
|
timestamp: 1539502055,
|
|
};
|
|
|
|
if (fileLastUpdateData) {
|
|
const {author, timestamp} = fileLastUpdateData;
|
|
return {
|
|
lastUpdatedAt: showLastUpdateTime ? timestamp : undefined,
|
|
lastUpdatedBy: showLastUpdateAuthor ? author : undefined,
|
|
};
|
|
}
|
|
}
|
|
|
|
return {};
|
|
}
|
|
|
|
export default async function processMetadata({
|
|
source,
|
|
refDir,
|
|
context,
|
|
options,
|
|
env,
|
|
}: Args): Promise<MetadataRaw> {
|
|
const {routeBasePath, editUrl} = options;
|
|
const {siteDir, baseUrl} = context;
|
|
const {versioning} = env;
|
|
const filePath = path.join(refDir, source);
|
|
|
|
const fileStringPromise = fs.readFile(filePath, 'utf-8');
|
|
const lastUpdatedPromise = lastUpdated(filePath, options);
|
|
|
|
let version;
|
|
const dirName = path.dirname(source);
|
|
if (versioning.enabled) {
|
|
if (/^version-/.test(dirName)) {
|
|
const inferredVersion = dirName
|
|
.split('/', 1)
|
|
.shift()!
|
|
.replace(/^version-/, '');
|
|
if (inferredVersion && versioning.versions.includes(inferredVersion)) {
|
|
version = inferredVersion;
|
|
}
|
|
} else {
|
|
version = 'next';
|
|
}
|
|
}
|
|
|
|
// The version portion of the url path. Eg: 'next', '1.0.0', and ''.
|
|
const versionPath =
|
|
version && version !== versioning.latestVersion ? version : '';
|
|
|
|
const relativePath = path.relative(siteDir, filePath);
|
|
|
|
const docsEditUrl = getEditUrl(relativePath, editUrl);
|
|
|
|
const {frontMatter = {}, excerpt} = parse(await fileStringPromise);
|
|
const {sidebar_label, custom_edit_url} = frontMatter;
|
|
|
|
// Default base id is the file name.
|
|
const baseID: string =
|
|
frontMatter.id || path.basename(source, path.extname(source));
|
|
|
|
if (baseID.includes('/')) {
|
|
throw new Error('Document id cannot include "/".');
|
|
}
|
|
|
|
// Append subdirectory as part of id.
|
|
const id = dirName !== '.' ? `${dirName}/${baseID}` : baseID;
|
|
|
|
// Default title is the id.
|
|
const title: string = frontMatter.title || baseID;
|
|
|
|
const description: string = frontMatter.description || excerpt;
|
|
|
|
// The last portion of the url path. Eg: 'foo/bar', 'bar'.
|
|
const routePath =
|
|
version && version !== 'next'
|
|
? id.replace(new RegExp(`^version-${version}/`), '')
|
|
: id;
|
|
const permalink = normalizeUrl([
|
|
baseUrl,
|
|
routeBasePath,
|
|
versionPath,
|
|
routePath,
|
|
]);
|
|
|
|
const {lastUpdatedAt, lastUpdatedBy} = await lastUpdatedPromise;
|
|
|
|
// Assign all of object properties during instantiation (if possible) for
|
|
// NodeJS optimization.
|
|
// Adding properties to object after instantiation will cause hidden
|
|
// class transitions.
|
|
const metadata: MetadataRaw = {
|
|
id,
|
|
title,
|
|
description,
|
|
source: aliasedSitePath(filePath, siteDir),
|
|
permalink,
|
|
editUrl: custom_edit_url !== undefined ? custom_edit_url : docsEditUrl,
|
|
version,
|
|
lastUpdatedBy,
|
|
lastUpdatedAt,
|
|
sidebar_label,
|
|
};
|
|
|
|
return metadata;
|
|
}
|