refactor(utils): remove duplicated function (#9972)

Co-authored-by: sebastien <lorber.sebastien@gmail.com>
This commit is contained in:
ozaki 2024-03-29 14:45:30 +01:00 committed by GitHub
parent efbe474e9c
commit 821247142e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 160 additions and 141 deletions

View file

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import {removeTrailingSlash} from '@docusaurus/utils'; import {removeTrailingSlash} from '@docusaurus/utils-common';
import {normalizePluginOptions} from '@docusaurus/utils-validation'; import {normalizePluginOptions} from '@docusaurus/utils-validation';
import collectRedirects from '../collectRedirects'; import collectRedirects from '../collectRedirects';
import {validateOptions} from '../options'; import {validateOptions} from '../options';

View file

@ -7,8 +7,11 @@
import _ from 'lodash'; import _ from 'lodash';
import logger from '@docusaurus/logger'; import logger from '@docusaurus/logger';
import {addTrailingSlash, removeTrailingSlash} from '@docusaurus/utils'; import {
import {applyTrailingSlash} from '@docusaurus/utils-common'; applyTrailingSlash,
addTrailingSlash,
removeTrailingSlash,
} from '@docusaurus/utils-common';
import { import {
createFromExtensionsRedirects, createFromExtensionsRedirects,
createToExtensionsRedirects, createToExtensionsRedirects,

View file

@ -9,7 +9,7 @@ import {
addTrailingSlash, addTrailingSlash,
removeSuffix, removeSuffix,
removeTrailingSlash, removeTrailingSlash,
} from '@docusaurus/utils'; } from '@docusaurus/utils-common';
import type {RedirectItem} from './types'; import type {RedirectItem} from './types';
const ExtensionAdditionalMessage = const ExtensionAdditionalMessage =

View file

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import {removePrefix, addLeadingSlash} from '@docusaurus/utils'; import {addLeadingSlash, removePrefix} from '@docusaurus/utils-common';
import collectRedirects from './collectRedirects'; import collectRedirects from './collectRedirects';
import writeRedirectFiles, { import writeRedirectFiles, {
toRedirectFiles, toRedirectFiles,

View file

@ -41,6 +41,7 @@
"@docusaurus/module-type-aliases": "3.0.0", "@docusaurus/module-type-aliases": "3.0.0",
"@docusaurus/types": "3.0.0", "@docusaurus/types": "3.0.0",
"@docusaurus/utils": "3.0.0", "@docusaurus/utils": "3.0.0",
"@docusaurus/utils-common": "3.0.0",
"@docusaurus/utils-validation": "3.0.0", "@docusaurus/utils-validation": "3.0.0",
"@types/react-router-config": "^5.0.7", "@types/react-router-config": "^5.0.7",
"combine-promises": "^1.1.0", "combine-promises": "^1.1.0",

View file

@ -8,7 +8,7 @@
import path from 'path'; import path from 'path';
import _ from 'lodash'; import _ from 'lodash';
import logger from '@docusaurus/logger'; import logger from '@docusaurus/logger';
import {addTrailingSlash} from '@docusaurus/utils'; import {addTrailingSlash} from '@docusaurus/utils-common';
import {createDocsByIdIndex, toCategoryIndexMatcherParam} from '../docs'; import {createDocsByIdIndex, toCategoryIndexMatcherParam} from '../docs';
import type { import type {
SidebarItemDoc, SidebarItemDoc,

View file

@ -5,12 +5,8 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import { import {isValidPathname, resolvePathname} from '@docusaurus/utils';
addLeadingSlash, import {addLeadingSlash, addTrailingSlash} from '@docusaurus/utils-common';
addTrailingSlash,
isValidPathname,
resolvePathname,
} from '@docusaurus/utils';
import { import {
DefaultNumberPrefixParser, DefaultNumberPrefixParser,
stripPathNumberPrefixes, stripPathNumberPrefixes,

View file

@ -6,7 +6,10 @@
*/ */
import applyTrailingSlash, { import applyTrailingSlash, {
addTrailingSlash,
type ApplyTrailingSlashParams, type ApplyTrailingSlashParams,
addLeadingSlash,
removeTrailingSlash,
} from '../applyTrailingSlash'; } from '../applyTrailingSlash';
function params( function params(
@ -176,3 +179,30 @@ describe('applyTrailingSlash', () => {
).toBe('https://xyz.com/abc/?search#anchor'); ).toBe('https://xyz.com/abc/?search#anchor');
}); });
}); });
describe('addTrailingSlash', () => {
it('is no-op for path with trailing slash', () => {
expect(addTrailingSlash('/abcd/')).toBe('/abcd/');
});
it('adds / for path without trailing slash', () => {
expect(addTrailingSlash('/abcd')).toBe('/abcd/');
});
});
describe('addLeadingSlash', () => {
it('is no-op for path with leading slash', () => {
expect(addLeadingSlash('/abc')).toBe('/abc');
});
it('adds / for path without leading slash', () => {
expect(addLeadingSlash('abc')).toBe('/abc');
});
});
describe('removeTrailingSlash', () => {
it('is no-op for path without trailing slash', () => {
expect(removeTrailingSlash('/abcd')).toBe('/abcd');
});
it('removes / for path with trailing slash', () => {
expect(removeTrailingSlash('/abcd/')).toBe('/abcd');
});
});

View file

@ -0,0 +1,55 @@
/**
* 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 {addPrefix, addSuffix, removePrefix, removeSuffix} from '../stringUtils';
describe('removePrefix', () => {
it("is no-op when prefix doesn't exist", () => {
expect(removePrefix('abcdef', 'ijk')).toBe('abcdef');
expect(removePrefix('abcdef', 'def')).toBe('abcdef');
expect(removePrefix('abcdef', '')).toBe('abcdef');
});
it('removes prefix', () => {
expect(removePrefix('prefix', 'pre')).toBe('fix');
});
});
describe('removeSuffix', () => {
it("is no-op when suffix doesn't exist", () => {
expect(removeSuffix('abcdef', 'ijk')).toBe('abcdef');
expect(removeSuffix('abcdef', 'abc')).toBe('abcdef');
expect(removeSuffix('abcdef', '')).toBe('abcdef');
});
it('removes suffix', () => {
expect(removeSuffix('abcdef', 'ef')).toBe('abcd');
});
it('removes empty suffix', () => {
expect(removeSuffix('abcdef', '')).toBe('abcdef');
});
});
describe('addPrefix', () => {
it('is no-op when prefix already exists', () => {
expect(addPrefix('abcdef', 'abc')).toBe('abcdef');
expect(addPrefix('abc', '')).toBe('abc');
expect(addPrefix('', '')).toBe('');
});
it('adds prefix', () => {
expect(addPrefix('def', 'abc')).toBe('abcdef');
});
});
describe('addSuffix', () => {
it('is no-op when suffix already exists', () => {
expect(addSuffix('abcdef', 'def')).toBe('abcdef');
expect(addSuffix('abc', '')).toBe('abc');
expect(addSuffix('', '')).toBe('');
});
it('adds suffix', () => {
expect(addSuffix('abc', 'def')).toBe('abcdef');
});
});

View file

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import {addPrefix, removeSuffix} from './stringUtils';
import type {DocusaurusConfig} from '@docusaurus/types'; import type {DocusaurusConfig} from '@docusaurus/types';
export type ApplyTrailingSlashParams = Pick< export type ApplyTrailingSlashParams = Pick<
@ -12,6 +13,10 @@ export type ApplyTrailingSlashParams = Pick<
'trailingSlash' | 'baseUrl' 'trailingSlash' | 'baseUrl'
>; >;
export function addTrailingSlash(str: string): string {
return str.endsWith('/') ? str : `${str}/`;
}
// Trailing slash handling depends in some site configuration options // Trailing slash handling depends in some site configuration options
export default function applyTrailingSlash( export default function applyTrailingSlash(
path: string, path: string,
@ -24,13 +29,6 @@ export default function applyTrailingSlash(
return path; return path;
} }
// TODO deduplicate: also present in @docusaurus/utils
function addTrailingSlash(str: string): string {
return str.endsWith('/') ? str : `${str}/`;
}
function removeTrailingSlash(str: string): string {
return str.endsWith('/') ? str.slice(0, -1) : str;
}
function handleTrailingSlash(str: string, trailing: boolean): string { function handleTrailingSlash(str: string, trailing: boolean): string {
return trailing ? addTrailingSlash(str) : removeTrailingSlash(str); return trailing ? addTrailingSlash(str) : removeTrailingSlash(str);
} }
@ -55,3 +53,13 @@ export default function applyTrailingSlash(
return path.replace(pathname, newPathname); return path.replace(pathname, newPathname);
} }
/** Appends a leading slash to `str`, if one doesn't exist. */
export function addLeadingSlash(str: string): string {
return addPrefix(str, '/');
}
/** Removes the trailing slash from `str`. */
export function removeTrailingSlash(str: string): string {
return removeSuffix(str, '/');
}

View file

@ -11,6 +11,10 @@ export const blogPostContainerID = '__blog-post-container';
export { export {
default as applyTrailingSlash, default as applyTrailingSlash,
addTrailingSlash,
addLeadingSlash,
removeTrailingSlash,
type ApplyTrailingSlashParams, type ApplyTrailingSlashParams,
} from './applyTrailingSlash'; } from './applyTrailingSlash';
export {addPrefix, removeSuffix, addSuffix, removePrefix} from './stringUtils';
export {getErrorCausalChain} from './errorUtils'; export {getErrorCausalChain} from './errorUtils';

View file

@ -0,0 +1,30 @@
/**
* 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.
*/
/** Adds a given string prefix to `str`. */
export function addPrefix(str: string, prefix: string): string {
return str.startsWith(prefix) ? str : `${prefix}${str}`;
}
/** Removes a given string suffix from `str`. */
export function removeSuffix(str: string, suffix: string): string {
if (suffix === '') {
// str.slice(0, 0) is ""
return str;
}
return str.endsWith(suffix) ? str.slice(0, -suffix.length) : str;
}
/** Adds a given string suffix to `str`. */
export function addSuffix(str: string, suffix: string): string {
return str.endsWith(suffix) ? str : `${str}${suffix}`;
}
/** Removes a given string prefix from `str`. */
export function removePrefix(str: string, prefix: string): string {
return str.startsWith(prefix) ? str.slice(prefix.length) : str;
}

View file

@ -20,6 +20,7 @@
"dependencies": { "dependencies": {
"@docusaurus/logger": "3.0.0", "@docusaurus/logger": "3.0.0",
"@docusaurus/utils": "3.0.0", "@docusaurus/utils": "3.0.0",
"@docusaurus/utils-common": "3.0.0",
"joi": "^17.9.2", "joi": "^17.9.2",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"tslib": "^2.6.0" "tslib": "^2.6.0"

View file

@ -5,12 +5,8 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import { import {isValidPathname, DEFAULT_PLUGIN_ID, type Tag} from '@docusaurus/utils';
isValidPathname, import {addLeadingSlash} from '@docusaurus/utils-common';
DEFAULT_PLUGIN_ID,
type Tag,
addLeadingSlash,
} from '@docusaurus/utils';
import Joi from './Joi'; import Joi from './Joi';
import {JoiFrontMatter} from './JoiFrontMatter'; import {JoiFrontMatter} from './JoiFrontMatter';

View file

@ -19,6 +19,7 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@docusaurus/logger": "3.0.0", "@docusaurus/logger": "3.0.0",
"@docusaurus/utils-common": "3.0.0",
"@svgr/webpack": "^6.5.1", "@svgr/webpack": "^6.5.1",
"escape-string-regexp": "^4.0.0", "escape-string-regexp": "^4.0.0",
"file-loader": "^6.2.0", "file-loader": "^6.2.0",

View file

@ -7,34 +7,7 @@
import {jest} from '@jest/globals'; import {jest} from '@jest/globals';
import _ from 'lodash'; import _ from 'lodash';
import { import {mapAsyncSequential, findAsyncSequential} from '../jsUtils';
removeSuffix,
removePrefix,
mapAsyncSequential,
findAsyncSequential,
} from '../jsUtils';
describe('removeSuffix', () => {
it("is no-op when suffix doesn't exist", () => {
expect(removeSuffix('abcdef', 'ijk')).toBe('abcdef');
expect(removeSuffix('abcdef', 'abc')).toBe('abcdef');
expect(removeSuffix('abcdef', '')).toBe('abcdef');
});
it('removes suffix', () => {
expect(removeSuffix('abcdef', 'ef')).toBe('abcd');
});
});
describe('removePrefix', () => {
it("is no-op when prefix doesn't exist", () => {
expect(removePrefix('abcdef', 'ijk')).toBe('abcdef');
expect(removePrefix('abcdef', 'def')).toBe('abcdef');
expect(removePrefix('abcdef', '')).toBe('abcdef');
});
it('removes prefix', () => {
expect(removePrefix('prefix', 'pre')).toBe('fix');
});
});
describe('mapAsyncSequential', () => { describe('mapAsyncSequential', () => {
function sleep(timeout: number): Promise<void> { function sleep(timeout: number): Promise<void> {

View file

@ -10,9 +10,6 @@ import {
getEditUrl, getEditUrl,
fileToPath, fileToPath,
isValidPathname, isValidPathname,
addTrailingSlash,
addLeadingSlash,
removeTrailingSlash,
resolvePathname, resolvePathname,
encodePath, encodePath,
buildSshUrl, buildSshUrl,
@ -207,33 +204,6 @@ describe('isValidPathname', () => {
}); });
}); });
describe('addTrailingSlash', () => {
it('is no-op for path with trailing slash', () => {
expect(addTrailingSlash('/abcd/')).toBe('/abcd/');
});
it('adds / for path without trailing slash', () => {
expect(addTrailingSlash('/abcd')).toBe('/abcd/');
});
});
describe('addLeadingSlash', () => {
it('is no-op for path with leading slash', () => {
expect(addLeadingSlash('/abc')).toBe('/abc');
});
it('adds / for path without leading slash', () => {
expect(addLeadingSlash('abc')).toBe('/abc');
});
});
describe('removeTrailingSlash', () => {
it('is no-op for path without trailing slash', () => {
expect(removeTrailingSlash('/abcd')).toBe('/abcd');
});
it('removes / for path with trailing slash', () => {
expect(removeTrailingSlash('/abcd/')).toBe('/abcd');
});
});
describe('parseURLPath', () => { describe('parseURLPath', () => {
it('parse and resolve pathname', () => { it('parse and resolve pathname', () => {
expect(parseURLPath('')).toEqual({ expect(parseURLPath('')).toEqual({

View file

@ -9,8 +9,7 @@
import path from 'path'; import path from 'path';
import Micromatch from 'micromatch'; // Note: Micromatch is used by Globby import Micromatch from 'micromatch'; // Note: Micromatch is used by Globby
import {addSuffix} from './jsUtils'; import {addSuffix} from '@docusaurus/utils-common';
/** A re-export of the globby instance. */ /** A re-export of the globby instance. */
export {default as Globby} from 'globby'; export {default as Globby} from 'globby';

View file

@ -35,12 +35,7 @@ export {
getPluginI18nPath, getPluginI18nPath,
localizePath, localizePath,
} from './i18nUtils'; } from './i18nUtils';
export { export {mapAsyncSequential, findAsyncSequential} from './jsUtils';
removeSuffix,
removePrefix,
mapAsyncSequential,
findAsyncSequential,
} from './jsUtils';
export { export {
normalizeUrl, normalizeUrl,
getEditUrl, getEditUrl,
@ -50,9 +45,6 @@ export {
resolvePathname, resolvePathname,
parseURLPath, parseURLPath,
serializeURLPath, serializeURLPath,
addLeadingSlash,
addTrailingSlash,
removeTrailingSlash,
hasSSHProtocol, hasSSHProtocol,
buildHttpsUrl, buildHttpsUrl,
buildSshUrl, buildSshUrl,

View file

@ -5,30 +5,6 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
/** Adds a given string prefix to `str`. */
export function addPrefix(str: string, prefix: string): string {
return str.startsWith(prefix) ? str : `${prefix}${str}`;
}
/** Adds a given string suffix to `str`. */
export function addSuffix(str: string, suffix: string): string {
return str.endsWith(suffix) ? str : `${str}${suffix}`;
}
/** Removes a given string suffix from `str`. */
export function removeSuffix(str: string, suffix: string): string {
if (suffix === '') {
// str.slice(0, 0) is ""
return str;
}
return str.endsWith(suffix) ? str.slice(0, -suffix.length) : str;
}
/** Removes a given string prefix from `str`. */
export function removePrefix(str: string, prefix: string): string {
return str.startsWith(prefix) ? str.slice(prefix.length) : str;
}
/** /**
* `Array#map` for async operations where order matters. * `Array#map` for async operations where order matters.
* @param array The array to traverse. * @param array The array to traverse.

View file

@ -6,7 +6,6 @@
*/ */
import resolvePathnameUnsafe from 'resolve-pathname'; import resolvePathnameUnsafe from 'resolve-pathname';
import {addPrefix, addSuffix, removeSuffix} from './jsUtils';
/** /**
* Much like `path.join`, but much better. Takes an array of URL segments, and * Much like `path.join`, but much better. Takes an array of URL segments, and
@ -232,22 +231,6 @@ export function resolvePathname(to: string, from?: string): string {
return resolvePathnameUnsafe(to, from); return resolvePathnameUnsafe(to, from);
} }
/** Appends a leading slash to `str`, if one doesn't exist. */
export function addLeadingSlash(str: string): string {
return addPrefix(str, '/');
}
// TODO deduplicate: also present in @docusaurus/utils-common
/** Appends a trailing slash to `str`, if one doesn't exist. */
export function addTrailingSlash(str: string): string {
return addSuffix(str, '/');
}
/** Removes the trailing slash from `str`. */
export function removeTrailingSlash(str: string): string {
return removeSuffix(str, '/');
}
/** Constructs an SSH URL that can be used to push to GitHub. */ /** Constructs an SSH URL that can be used to push to GitHub. */
export function buildSshUrl( export function buildSshUrl(
githubHost: string, githubHost: string,

View file

@ -69,8 +69,8 @@
"del": "^6.1.1", "del": "^6.1.1",
"detect-port": "^1.5.1", "detect-port": "^1.5.1",
"escape-html": "^1.0.3", "escape-html": "^1.0.3",
"eval": "^0.1.8",
"eta": "^2.2.0", "eta": "^2.2.0",
"eval": "^0.1.8",
"file-loader": "^6.2.0", "file-loader": "^6.2.0",
"fs-extra": "^11.1.1", "fs-extra": "^11.1.1",
"html-minifier-terser": "^7.2.0", "html-minifier-terser": "^7.2.0",

View file

@ -9,13 +9,12 @@ import _ from 'lodash';
import logger from '@docusaurus/logger'; import logger from '@docusaurus/logger';
import {matchRoutes as reactRouterMatchRoutes} from 'react-router-config'; import {matchRoutes as reactRouterMatchRoutes} from 'react-router-config';
import { import {
addTrailingSlash,
parseURLPath, parseURLPath,
removeTrailingSlash,
serializeURLPath, serializeURLPath,
flattenRoutes, flattenRoutes,
type URLPath, type URLPath,
} from '@docusaurus/utils'; } from '@docusaurus/utils';
import {addTrailingSlash, removeTrailingSlash} from '@docusaurus/utils-common';
import type {RouteConfig, ReportingSeverity} from '@docusaurus/types'; import type {RouteConfig, ReportingSeverity} from '@docusaurus/types';
function matchRoutes(routeConfig: RouteConfig[], pathname: string) { function matchRoutes(routeConfig: RouteConfig[], pathname: string) {

View file

@ -9,11 +9,13 @@ import {
DEFAULT_PARSE_FRONT_MATTER, DEFAULT_PARSE_FRONT_MATTER,
DEFAULT_STATIC_DIR_NAME, DEFAULT_STATIC_DIR_NAME,
DEFAULT_I18N_DIR_NAME, DEFAULT_I18N_DIR_NAME,
addLeadingSlash,
addTrailingSlash,
removeTrailingSlash,
} from '@docusaurus/utils'; } from '@docusaurus/utils';
import {Joi, printWarning} from '@docusaurus/utils-validation'; import {Joi, printWarning} from '@docusaurus/utils-validation';
import {
addTrailingSlash,
addLeadingSlash,
removeTrailingSlash,
} from '@docusaurus/utils-common';
import type { import type {
DocusaurusConfig, DocusaurusConfig,
I18nConfig, I18nConfig,