mirror of
https://github.com/facebook/docusaurus.git
synced 2025-12-26 01:33:02 +00:00
Refactor VCS preset + config validation
This commit is contained in:
parent
ab790703b2
commit
acf5f383ea
|
|
@ -129,5 +129,6 @@
|
|||
"stylelint-config-standard": "^29.0.0",
|
||||
"typescript": "~5.8.2"
|
||||
},
|
||||
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
||||
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
|
||||
"dependencies": {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,11 @@ export type VcsConfig = {
|
|||
getFileLastUpdateInfo: (filePath: string) => Promise<VcsChangeInfo | null>;
|
||||
};
|
||||
|
||||
/**
|
||||
* List of pre-built VcsConfig that Docusaurus provides.
|
||||
*/
|
||||
export type VcsPreset = 'git-ad-hoc' | 'git-eager' | 'hardcoded';
|
||||
|
||||
export type FutureConfig = {
|
||||
/**
|
||||
* Turns v4 future flags on
|
||||
|
|
@ -86,7 +91,7 @@ export type FutureConfig = {
|
|||
|
||||
experimental_storage: StorageConfig;
|
||||
|
||||
experimental_vcs: VcsConfig;
|
||||
experimental_vcs: VcsPreset | VcsConfig;
|
||||
|
||||
/**
|
||||
* Docusaurus can work with 2 router types.
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ export {
|
|||
FasterConfig,
|
||||
StorageConfig,
|
||||
VcsConfig,
|
||||
VcsPreset,
|
||||
VcsChangeInfo,
|
||||
VscInitializeParams,
|
||||
Config,
|
||||
|
|
|
|||
|
|
@ -131,6 +131,11 @@ export {
|
|||
type FrontMatterLastUpdate,
|
||||
} from './lastUpdateUtils';
|
||||
|
||||
export {DEFAULT_VCS_CONFIG, DEFAULT_TEST_VCS_CONFIG} from './vcs/vcs';
|
||||
export {
|
||||
VcsPresetNames,
|
||||
getVcsPreset,
|
||||
getDefaultVcsConfig,
|
||||
DEFAULT_TEST_VCS_CONFIG,
|
||||
} from './vcs/vcs';
|
||||
|
||||
export {normalizeTags, reportInlineTags} from './tags';
|
||||
|
|
|
|||
|
|
@ -8,31 +8,59 @@
|
|||
import {VcsHardcoded} from './vcsHardcoded';
|
||||
import {VcsGitAdHoc} from './vcsGitAdHoc';
|
||||
import {VscGitEager} from './vcsGitEager';
|
||||
import type {VcsConfig} from '@docusaurus/types';
|
||||
import type {VcsConfig, VcsPreset} from '@docusaurus/types';
|
||||
|
||||
const VcsPresets = {
|
||||
const VcsPresets: Record<VcsPreset, VcsConfig> = {
|
||||
'git-ad-hoc': VcsGitAdHoc,
|
||||
'git-eager': VscGitEager,
|
||||
hardcoded: VcsHardcoded,
|
||||
} as const satisfies Record<string, VcsConfig>;
|
||||
};
|
||||
|
||||
type VscPresetName = keyof typeof VcsPresets;
|
||||
export const VcsPresetNames = Object.keys(VcsPresets) as VcsPreset[];
|
||||
|
||||
function getVcsPreset(presetName: VscPresetName): VcsConfig {
|
||||
return VcsPresets[presetName];
|
||||
export function findVcsPreset(presetName: string): VcsConfig | undefined {
|
||||
return VcsPresets[presetName as VcsPreset];
|
||||
}
|
||||
|
||||
function getDefaultVcsConfig(): VcsConfig {
|
||||
export function getVcsPreset(presetName: VcsPreset): VcsConfig {
|
||||
const vcs = findVcsPreset(presetName);
|
||||
if (vcs) {
|
||||
return vcs;
|
||||
} else {
|
||||
throw new Error(
|
||||
`Unknown Docusaurus VCS preset name: ${process.env.DOCUSAURUS_VCS}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function getDefaultVcsPreset(): VcsPreset {
|
||||
// Escape hatch to override the default VCS preset we use
|
||||
if (process.env.DOCUSAURUS_VCS) {
|
||||
const vcs = getVcsPreset(process.env.DOCUSAURUS_VCS as VscPresetName);
|
||||
if (vcs) {
|
||||
return vcs;
|
||||
} else {
|
||||
throw new Error(
|
||||
`Unknown DOCUSAURUS_VCS preset name: ${process.env.DOCUSAURUS_VCS}`,
|
||||
);
|
||||
}
|
||||
return process.env.DOCUSAURUS_VCS as VcsPreset;
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
// TODO add feature flag switch for git-eager / git-ad-hoc strategies
|
||||
// return getVcsPreset('git-ad-hoc');
|
||||
return 'git-eager';
|
||||
}
|
||||
// Return hardcoded values in dev to improve DX
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
return 'hardcoded';
|
||||
}
|
||||
|
||||
// Return hardcoded values in test to make tests simpler and faster
|
||||
if (process.env.NODE_ENV === 'test') {
|
||||
return 'hardcoded';
|
||||
}
|
||||
|
||||
return 'git-eager';
|
||||
}
|
||||
|
||||
export function getDefaultVcsConfig(): VcsConfig {
|
||||
// Escape hatch to override the default VCS preset we use
|
||||
if (process.env.DOCUSAURUS_VCS) {
|
||||
return getVcsPreset(process.env.DOCUSAURUS_VCS as VcsPreset);
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
|
|
@ -40,7 +68,6 @@ function getDefaultVcsConfig(): VcsConfig {
|
|||
// return getVcsPreset('git-ad-hoc');
|
||||
return getVcsPreset('git-eager');
|
||||
}
|
||||
|
||||
// Return hardcoded values in dev to improve DX
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
return getVcsPreset('hardcoded');
|
||||
|
|
@ -55,5 +82,3 @@ function getDefaultVcsConfig(): VcsConfig {
|
|||
}
|
||||
|
||||
export const DEFAULT_TEST_VCS_CONFIG: VcsConfig = VcsHardcoded;
|
||||
|
||||
export const DEFAULT_VCS_CONFIG: VcsConfig = getDefaultVcsConfig();
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ function createGitVcsConfig(): VcsConfig {
|
|||
|
||||
return {
|
||||
initialize: ({siteDir}) => {
|
||||
console.log('git eager init');
|
||||
// Only pre-init for production builds
|
||||
getGitFileInfo(siteDir).catch((error) => {
|
||||
console.error(
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import {jest} from '@jest/globals';
|
||||
import {DEFAULT_VCS_CONFIG} from '@docusaurus/utils';
|
||||
import {DEFAULT_TEST_VCS_CONFIG, getVcsPreset} from '@docusaurus/utils';
|
||||
import {
|
||||
ConfigSchema,
|
||||
DEFAULT_CONFIG,
|
||||
|
|
@ -31,6 +31,7 @@ import type {
|
|||
I18nConfig,
|
||||
I18nLocaleConfig,
|
||||
VcsConfig,
|
||||
VcsPreset,
|
||||
} from '@docusaurus/types';
|
||||
import type {DeepPartial} from 'utility-types';
|
||||
|
||||
|
|
@ -1413,128 +1414,25 @@ describe('future', () => {
|
|||
});
|
||||
}
|
||||
|
||||
it('accepts vcs - undefined', () => {
|
||||
expect(
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: undefined,
|
||||
},
|
||||
}),
|
||||
).toEqual(futureContaining(DEFAULT_FUTURE_CONFIG));
|
||||
});
|
||||
|
||||
it('accepts vcs - empty', () => {
|
||||
expect(
|
||||
normalizeConfig({
|
||||
future: {experimental_vcs: {}},
|
||||
}),
|
||||
).toEqual(futureContaining(DEFAULT_FUTURE_CONFIG));
|
||||
});
|
||||
|
||||
it('accepts vcs - full', () => {
|
||||
const vcs: VcsConfig = {
|
||||
initialize: (_params) => {},
|
||||
getFileCreationInfo: (_filePath) => null,
|
||||
getFileLastUpdateInfo: (_filePath) => null,
|
||||
};
|
||||
expect(
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: vcs,
|
||||
},
|
||||
}),
|
||||
).toEqual(vcsContaining(vcs));
|
||||
});
|
||||
|
||||
it('rejects vcs - boolean', () => {
|
||||
// @ts-expect-error: invalid
|
||||
const vcs: Partial<VcsConfig> = true;
|
||||
expect(() =>
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: vcs,
|
||||
},
|
||||
}),
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
""future.experimental_vcs" must be of type object
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('rejects vcs - number', () => {
|
||||
// @ts-expect-error: invalid
|
||||
const vcs: Partial<VcsConfig> = 42;
|
||||
expect(() =>
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: vcs,
|
||||
},
|
||||
}),
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
""future.experimental_vcs" must be of type object
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
describe('initialize', () => {
|
||||
it('accepts fn(params)', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
initialize: (_params) => null,
|
||||
};
|
||||
describe('base', () => {
|
||||
it('accepts vcs - undefined', () => {
|
||||
expect(
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: vcs,
|
||||
experimental_vcs: undefined,
|
||||
},
|
||||
}),
|
||||
).toEqual(
|
||||
vcsContaining({
|
||||
...DEFAULT_VCS_CONFIG,
|
||||
...vcs,
|
||||
futureContaining({
|
||||
...DEFAULT_FUTURE_CONFIG,
|
||||
experimental_vcs: DEFAULT_TEST_VCS_CONFIG,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('accepts fn()', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
initialize: () => null,
|
||||
};
|
||||
expect(
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: vcs,
|
||||
},
|
||||
}),
|
||||
).toEqual(
|
||||
vcsContaining({
|
||||
...DEFAULT_VCS_CONFIG,
|
||||
...vcs,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('accepts undefined', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
initialize: undefined,
|
||||
};
|
||||
expect(
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: vcs,
|
||||
},
|
||||
}),
|
||||
).toEqual(
|
||||
vcsContaining({
|
||||
...DEFAULT_VCS_CONFIG,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('rejects null', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
// @ts-expect-error: invalid
|
||||
initialize: null,
|
||||
};
|
||||
it('rejects vcs - boolean', () => {
|
||||
// @ts-expect-error: invalid
|
||||
const vcs: Partial<VcsConfig> = true;
|
||||
expect(() =>
|
||||
normalizeConfig({
|
||||
future: {
|
||||
|
|
@ -1542,16 +1440,14 @@ describe('future', () => {
|
|||
},
|
||||
}),
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
""future.experimental_vcs.initialize" must be of type function
|
||||
""future.experimental_vcs" failed custom validation because "value" must be of type object
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('rejects number', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
// @ts-expect-error: invalid
|
||||
initialize: 42,
|
||||
};
|
||||
it('rejects vcs - number', () => {
|
||||
// @ts-expect-error: invalid
|
||||
const vcs: Partial<VcsConfig> = 42;
|
||||
expect(() =>
|
||||
normalizeConfig({
|
||||
future: {
|
||||
|
|
@ -1559,136 +1455,67 @@ describe('future', () => {
|
|||
},
|
||||
}),
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
""future.experimental_vcs.initialize" must be of type function
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('rejects fn(params, anotherArg)', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
// @ts-expect-error: invalid
|
||||
initialize: (_params, _anotherArg) => null,
|
||||
};
|
||||
expect(() =>
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: vcs,
|
||||
},
|
||||
}),
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
""future.experimental_vcs.initialize" must have an arity lesser or equal to 1
|
||||
""future.experimental_vcs" failed custom validation because "value" must be of type object
|
||||
"
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getFileCreationInfo', () => {
|
||||
it('accepts fn(filePath)', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
describe('presets', () => {
|
||||
it('accepts git-ad-hoc', () => {
|
||||
const presetName: VcsPreset = 'git-ad-hoc';
|
||||
expect(
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: presetName,
|
||||
},
|
||||
}),
|
||||
).toEqual(vcsContaining(getVcsPreset(presetName)));
|
||||
});
|
||||
|
||||
it('accepts git-eager', () => {
|
||||
const presetName: VcsPreset = 'git-eager';
|
||||
expect(
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: presetName,
|
||||
},
|
||||
}),
|
||||
).toEqual(vcsContaining(getVcsPreset(presetName)));
|
||||
});
|
||||
|
||||
it('accepts hardcoded', () => {
|
||||
const presetName: VcsPreset = 'hardcoded';
|
||||
expect(
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: presetName,
|
||||
},
|
||||
}),
|
||||
).toEqual(vcsContaining(getVcsPreset(presetName)));
|
||||
});
|
||||
|
||||
it('rejects unknown preset name', () => {
|
||||
// @ts-expect-error: invalid on purpose
|
||||
const presetName: VcsPreset = 'unknown-preset-name';
|
||||
expect(() =>
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: presetName,
|
||||
},
|
||||
}),
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
""future.experimental_vcs" failed custom validation because VCS config preset name 'unknown-preset-name' is not valid.
|
||||
"
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('object config', () => {
|
||||
it('accepts vcs - full', () => {
|
||||
const vcs: VcsConfig = {
|
||||
initialize: (_params) => {},
|
||||
getFileCreationInfo: (_filePath) => null,
|
||||
};
|
||||
expect(
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: vcs,
|
||||
},
|
||||
}),
|
||||
).toEqual(
|
||||
vcsContaining({
|
||||
...DEFAULT_VCS_CONFIG,
|
||||
...vcs,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('accepts undefined', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
getFileCreationInfo: undefined,
|
||||
};
|
||||
expect(
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: vcs,
|
||||
},
|
||||
}),
|
||||
).toEqual(
|
||||
vcsContaining({
|
||||
...DEFAULT_VCS_CONFIG,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('rejects null', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
// @ts-expect-error: invalid
|
||||
getFileCreationInfo: null,
|
||||
};
|
||||
expect(() =>
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: vcs,
|
||||
},
|
||||
}),
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
""future.experimental_vcs.getFileCreationInfo" must be of type function
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('rejects number', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
// @ts-expect-error: invalid
|
||||
getFileCreationInfo: 42,
|
||||
};
|
||||
expect(() =>
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: vcs,
|
||||
},
|
||||
}),
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
""future.experimental_vcs.getFileCreationInfo" must be of type function
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('rejects fn()', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
getFileCreationInfo: () => null,
|
||||
};
|
||||
expect(() =>
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: vcs,
|
||||
},
|
||||
}),
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
""future.experimental_vcs.getFileCreationInfo" must have an arity of 1
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('rejects fn(filePath, anotherArg)', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
// @ts-expect-error: invalid
|
||||
getFileCreationInfo: (_filePath, _anotherArg) => null,
|
||||
};
|
||||
expect(() =>
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: vcs,
|
||||
},
|
||||
}),
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
""future.experimental_vcs.getFileCreationInfo" must have an arity of 1
|
||||
"
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getFileLastUpdateInfo', () => {
|
||||
it('accepts fn(filePath)', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
getFileLastUpdateInfo: (_filePath) => null,
|
||||
};
|
||||
expect(
|
||||
|
|
@ -1697,52 +1524,26 @@ describe('future', () => {
|
|||
experimental_vcs: vcs,
|
||||
},
|
||||
}),
|
||||
).toEqual(
|
||||
vcsContaining({
|
||||
...DEFAULT_VCS_CONFIG,
|
||||
...vcs,
|
||||
}),
|
||||
);
|
||||
).toEqual(vcsContaining(vcs));
|
||||
});
|
||||
|
||||
it('accepts undefined', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
getFileLastUpdateInfo: undefined,
|
||||
};
|
||||
expect(
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: vcs,
|
||||
},
|
||||
}),
|
||||
).toEqual(
|
||||
vcsContaining({
|
||||
...DEFAULT_VCS_CONFIG,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('rejects null', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
// @ts-expect-error: invalid
|
||||
getFileLastUpdateInfo: null,
|
||||
};
|
||||
it('rejects vcs - empty', () => {
|
||||
expect(() =>
|
||||
normalizeConfig({
|
||||
future: {
|
||||
experimental_vcs: vcs,
|
||||
},
|
||||
future: {experimental_vcs: {}},
|
||||
}),
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
""future.experimental_vcs.getFileLastUpdateInfo" must be of type function
|
||||
""future.experimental_vcs" failed custom validation because "initialize" is required
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('rejects number', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
// @ts-expect-error: invalid
|
||||
getFileLastUpdateInfo: 42,
|
||||
it('accepts vcs - bad initialize() arity', () => {
|
||||
const vcs: VcsConfig = {
|
||||
// @ts-expect-error: invalid arity
|
||||
initialize: (_params, _extraParam) => {},
|
||||
getFileCreationInfo: (_filePath) => null,
|
||||
getFileLastUpdateInfo: (_filePath) => null,
|
||||
};
|
||||
expect(() =>
|
||||
normalizeConfig({
|
||||
|
|
@ -1751,14 +1552,17 @@ describe('future', () => {
|
|||
},
|
||||
}),
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
""future.experimental_vcs.getFileLastUpdateInfo" must be of type function
|
||||
""future.experimental_vcs" failed custom validation because "initialize" must have an arity lesser or equal to 1
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('rejects fn()', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
getFileLastUpdateInfo: () => null,
|
||||
it('accepts vcs - bad getFileCreationInfo() arity', () => {
|
||||
const vcs: VcsConfig = {
|
||||
initialize: (_params) => {},
|
||||
// @ts-expect-error: invalid arity
|
||||
getFileCreationInfo: (_filePath, _extraParam) => null,
|
||||
getFileLastUpdateInfo: (_filePath) => null,
|
||||
};
|
||||
expect(() =>
|
||||
normalizeConfig({
|
||||
|
|
@ -1767,15 +1571,17 @@ describe('future', () => {
|
|||
},
|
||||
}),
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
""future.experimental_vcs.getFileLastUpdateInfo" must have an arity of 1
|
||||
""future.experimental_vcs" failed custom validation because "getFileCreationInfo" must have an arity of 1
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('rejects fn(filePath, anotherArg)', () => {
|
||||
const vcs: Partial<VcsConfig> = {
|
||||
// @ts-expect-error: invalid
|
||||
getFileLastUpdateInfo: (_filePath, _anotherArg) => null,
|
||||
it('accepts vcs - bad getFileLastUpdateInfo() arity', () => {
|
||||
const vcs: VcsConfig = {
|
||||
initialize: (_params) => {},
|
||||
getFileCreationInfo: (_filePath) => null,
|
||||
// @ts-expect-error: invalid arity
|
||||
getFileLastUpdateInfo: (_filePath, _extraParam) => null,
|
||||
};
|
||||
expect(() =>
|
||||
normalizeConfig({
|
||||
|
|
@ -1784,7 +1590,7 @@ describe('future', () => {
|
|||
},
|
||||
}),
|
||||
).toThrowErrorMatchingInlineSnapshot(`
|
||||
""future.experimental_vcs.getFileLastUpdateInfo" must have an arity of 1
|
||||
""future.experimental_vcs" failed custom validation because "getFileLastUpdateInfo" must have an arity of 1
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ import {
|
|||
DEFAULT_PARSE_FRONT_MATTER,
|
||||
DEFAULT_STATIC_DIR_NAME,
|
||||
DEFAULT_I18N_DIR_NAME,
|
||||
DEFAULT_VCS_CONFIG,
|
||||
getDefaultVcsConfig,
|
||||
VcsPresetNames,
|
||||
getVcsPreset,
|
||||
} from '@docusaurus/utils';
|
||||
import {Joi, printWarning} from '@docusaurus/utils-validation';
|
||||
import {
|
||||
|
|
@ -29,6 +31,7 @@ import type {
|
|||
MarkdownHooks,
|
||||
I18nLocaleConfig,
|
||||
VcsConfig,
|
||||
VcsPreset,
|
||||
} from '@docusaurus/types';
|
||||
|
||||
const DEFAULT_I18N_LOCALE = 'en';
|
||||
|
|
@ -108,7 +111,9 @@ export const DEFAULT_FUTURE_CONFIG: FutureConfig = {
|
|||
v4: DEFAULT_FUTURE_V4_CONFIG,
|
||||
experimental_faster: DEFAULT_FASTER_CONFIG,
|
||||
experimental_storage: DEFAULT_STORAGE_CONFIG,
|
||||
experimental_vcs: DEFAULT_VCS_CONFIG,
|
||||
|
||||
// Not good, need to be loaded lazily
|
||||
experimental_vcs: getDefaultVcsConfig(),
|
||||
experimental_router: 'browser',
|
||||
};
|
||||
|
||||
|
|
@ -334,22 +339,28 @@ const STORAGE_CONFIG_SCHEMA = Joi.object({
|
|||
.optional()
|
||||
.default(DEFAULT_STORAGE_CONFIG);
|
||||
|
||||
const VCS_CONFIG_SCHEMA = Joi.object<VcsConfig>({
|
||||
initialize: Joi.function()
|
||||
.maxArity(1)
|
||||
.optional()
|
||||
.default(() => DEFAULT_VCS_CONFIG.initialize),
|
||||
getFileCreationInfo: Joi.function()
|
||||
.arity(1)
|
||||
.optional()
|
||||
.default(() => DEFAULT_VCS_CONFIG.getFileCreationInfo),
|
||||
getFileLastUpdateInfo: Joi.function()
|
||||
.arity(1)
|
||||
.optional()
|
||||
.default(() => DEFAULT_VCS_CONFIG.getFileLastUpdateInfo),
|
||||
})
|
||||
.optional()
|
||||
.default(DEFAULT_VCS_CONFIG);
|
||||
const VCS_CONFIG_OBJECT_SCHEMA = Joi.object<VcsConfig>({
|
||||
// All the fields are required on purpose
|
||||
// You either provide a full VCS config or nothing
|
||||
initialize: Joi.function().maxArity(1).required(),
|
||||
getFileCreationInfo: Joi.function().arity(1).required(),
|
||||
getFileLastUpdateInfo: Joi.function().arity(1).required(),
|
||||
});
|
||||
|
||||
const VCS_CONFIG_SCHEMA = Joi.custom((input) => {
|
||||
if (typeof input === 'string') {
|
||||
const presetName = input as VcsPreset;
|
||||
if (!VcsPresetNames.includes(presetName)) {
|
||||
throw new Error(`VCS config preset name '${input}' is not valid.`);
|
||||
}
|
||||
return getVcsPreset(presetName);
|
||||
}
|
||||
const {error, value} = VCS_CONFIG_OBJECT_SCHEMA.validate(input);
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
return value;
|
||||
}).default(() => getDefaultVcsConfig());
|
||||
|
||||
const FUTURE_CONFIG_SCHEMA = Joi.object<FutureConfig>({
|
||||
v4: FUTURE_V4_SCHEMA,
|
||||
|
|
|
|||
|
|
@ -6088,9 +6088,9 @@ caniuse-api@^3.0.0:
|
|||
lodash.uniq "^4.5.0"
|
||||
|
||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001718:
|
||||
version "1.0.30001721"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001721.tgz#36b90cd96901f8c98dd6698bf5c8af7d4c6872d7"
|
||||
integrity sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==
|
||||
version "1.0.30001754"
|
||||
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz"
|
||||
integrity sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==
|
||||
|
||||
ccount@^2.0.0:
|
||||
version "2.0.1"
|
||||
|
|
|
|||
Loading…
Reference in New Issue