mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-28 17:57:48 +02:00
148 lines
4.4 KiB
TypeScript
Vendored
148 lines
4.4 KiB
TypeScript
Vendored
/**
|
|
* 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.
|
|
*/
|
|
|
|
// Forked from https://github.com/tribou/jest-serializer-path/blob/master/lib/index.js
|
|
// Added some project-specific handlers
|
|
|
|
import os from 'os';
|
|
import path from 'path';
|
|
import fs from 'fs';
|
|
import _ from 'lodash';
|
|
import {escapePath} from '@docusaurus/utils';
|
|
import {version} from '@docusaurus/core/package.json';
|
|
import stripAnsi from 'strip-ansi';
|
|
|
|
export function print(
|
|
val: unknown,
|
|
serialize: (val: unknown) => string,
|
|
): string {
|
|
if (val instanceof Error) {
|
|
const message = normalizePaths(val.message);
|
|
const error = new Error(message);
|
|
const allKeys = [
|
|
...Object.getOwnPropertyNames(error),
|
|
...Object.keys(val),
|
|
] as (keyof Error)[];
|
|
allKeys.forEach((key) => {
|
|
error[key] = normalizePaths(val[key]) as never;
|
|
});
|
|
return serialize(error);
|
|
} else if (val && typeof val === 'object') {
|
|
const normalizedValue = _.cloneDeep(val) as {[key: string]: unknown};
|
|
|
|
Object.keys(normalizedValue).forEach((key) => {
|
|
normalizedValue[key] = normalizePaths(normalizedValue[key]);
|
|
});
|
|
return serialize(normalizedValue);
|
|
}
|
|
return serialize(normalizePaths(val));
|
|
}
|
|
|
|
export function test(val: unknown): boolean {
|
|
return (
|
|
(typeof val === 'object' &&
|
|
val &&
|
|
Object.keys(val).some((key) =>
|
|
shouldUpdate((val as {[key: string]: unknown})[key]),
|
|
)) ||
|
|
// val.message is non-enumerable in an error
|
|
(val instanceof Error && shouldUpdate(val.message)) ||
|
|
shouldUpdate(val)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Normalize paths across platforms.
|
|
* Filters must be ran on all platforms to guard against false positives
|
|
*/
|
|
function normalizePaths<T>(value: T): T {
|
|
if (typeof value !== 'string') {
|
|
return value;
|
|
}
|
|
|
|
const cwd = process.cwd();
|
|
const cwdReal = getRealPath(cwd);
|
|
const tempDir = os.tmpdir();
|
|
const tempDirReal = getRealPath(tempDir);
|
|
const homeDir = os.homedir();
|
|
const homeDirReal = getRealPath(homeDir);
|
|
|
|
const homeRelativeToTemp = path.relative(tempDir, homeDir);
|
|
const homeRelativeToTempReal = path.relative(tempDirReal, homeDir);
|
|
const homeRealRelativeToTempReal = path.relative(tempDirReal, homeDirReal);
|
|
const homeRealRelativeToTemp = path.relative(tempDir, homeDirReal);
|
|
|
|
const runner: ((val: string) => string)[] = [
|
|
(val) => (val.includes('keepAnsi') ? val : stripAnsi(val)),
|
|
// Replace process.cwd with <PROJECT_ROOT>
|
|
(val) => val.split(cwdReal).join('<PROJECT_ROOT>'),
|
|
(val) => val.split(cwd).join('<PROJECT_ROOT>'),
|
|
|
|
// Replace home directory with <TEMP_DIR>
|
|
(val) => val.split(tempDirReal).join('<TEMP_DIR>'),
|
|
(val) => val.split(tempDir).join('<TEMP_DIR>'),
|
|
|
|
// Replace home directory with <HOME_DIR>
|
|
(val) => val.split(homeDirReal).join('<HOME_DIR>'),
|
|
(val) => val.split(homeDir).join('<HOME_DIR>'),
|
|
|
|
// Handle HOME_DIR nested inside TEMP_DIR
|
|
(val) =>
|
|
val
|
|
.split(`<TEMP_DIR>${path.sep + homeRelativeToTemp}`)
|
|
.join('<HOME_DIR>'),
|
|
(val) =>
|
|
val
|
|
.split(`<TEMP_DIR>${path.sep + homeRelativeToTempReal}`)
|
|
.join('<HOME_DIR>'),
|
|
(val) =>
|
|
val
|
|
.split(`<TEMP_DIR>${path.sep + homeRealRelativeToTempReal}`)
|
|
.join('<HOME_DIR>'),
|
|
(val) =>
|
|
val
|
|
.split(`<TEMP_DIR>${path.sep + homeRealRelativeToTemp}`)
|
|
.join('<HOME_DIR>'),
|
|
|
|
// Replace the Docusaurus version with a stub
|
|
(val) => val.split(version).join('<CURRENT_VERSION>'),
|
|
|
|
// In case the CWD is escaped
|
|
(val) => val.split(escapePath(cwd)).join('<PROJECT_ROOT>'),
|
|
|
|
// Remove win32 drive letters, C:\ -> \
|
|
(val) => val.replace(/[a-zA-Z]:\\/g, '\\'),
|
|
|
|
// Remove duplicate backslashes created from escapePath
|
|
(val) => val.replace(/\\\\/g, '\\'),
|
|
|
|
// Convert win32 backslash's to forward slashes, \ -> /;
|
|
// ignore some that look like escape sequences.
|
|
(val) => val.replace(/\\(?!")/g, '/'),
|
|
];
|
|
|
|
let result = value as string;
|
|
runner.forEach((current) => {
|
|
result = current(result);
|
|
});
|
|
|
|
return result as T & string;
|
|
}
|
|
|
|
function shouldUpdate(value: unknown) {
|
|
return typeof value === 'string' && normalizePaths(value) !== value;
|
|
}
|
|
|
|
function getRealPath(pathname: string) {
|
|
try {
|
|
// eslint-disable-next-line no-restricted-properties
|
|
const realPath = fs.realpathSync(pathname);
|
|
return realPath;
|
|
} catch (err) {
|
|
return pathname;
|
|
}
|
|
}
|