"use strict";
/**
 * 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.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConfigSchema = exports.DEFAULT_CONFIG = exports.DEFAULT_MARKDOWN_CONFIG = exports.DEFAULT_MARKDOWN_MDX1COMPAT = exports.DEFAULT_MARKDOWN_HOOKS = exports.DEFAULT_FUTURE_CONFIG = exports.DEFAULT_FUTURE_V4_CONFIG_TRUE = exports.DEFAULT_FUTURE_V4_CONFIG = exports.DEFAULT_FASTER_CONFIG_TRUE = exports.DEFAULT_FASTER_CONFIG = exports.DEFAULT_STORAGE_CONFIG = exports.DEFAULT_I18N_CONFIG = void 0;
exports.validateConfig = validateConfig;
const tslib_1 = require("tslib");
const utils_1 = require("@docusaurus/utils");
const utils_validation_1 = require("@docusaurus/utils-validation");
const utils_common_1 = require("@docusaurus/utils-common");
const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
const DEFAULT_I18N_LOCALE = 'en';
const SiteUrlSchema = utils_validation_1.Joi.string()
    .custom((value, helpers) => {
    try {
        const { pathname } = new URL(value);
        if (pathname !== '/') {
            return helpers.error('docusaurus.subPathError', { pathname });
        }
    }
    catch {
        return helpers.error('any.invalid');
    }
    return (0, utils_common_1.removeTrailingSlash)(value);
})
    .messages({
    'any.invalid': '"{#value}" does not look like a valid URL. Make sure it has a protocol; for example, "https://example.com".',
    'docusaurus.subPathError': 'The url is not supposed to contain a sub-path like "{#pathname}". Please use the baseUrl field for sub-paths.',
});
const BaseUrlSchema = utils_validation_1.Joi
    // Weird Joi trick needed, otherwise value '' is not normalized...
    .alternatives()
    .try(utils_validation_1.Joi.string().required().allow(''))
    .custom((value) => (0, utils_common_1.addLeadingSlash)((0, utils_common_1.addTrailingSlash)(value)));
exports.DEFAULT_I18N_CONFIG = {
    defaultLocale: DEFAULT_I18N_LOCALE,
    path: utils_1.DEFAULT_I18N_DIR_NAME,
    locales: [DEFAULT_I18N_LOCALE],
    localeConfigs: {},
};
exports.DEFAULT_STORAGE_CONFIG = {
    type: 'localStorage',
    namespace: false,
};
exports.DEFAULT_FASTER_CONFIG = {
    swcJsLoader: false,
    swcJsMinimizer: false,
    swcHtmlMinimizer: false,
    lightningCssMinimizer: false,
    mdxCrossCompilerCache: false,
    rspackBundler: false,
    rspackPersistentCache: false,
    ssgWorkerThreads: false,
    gitEagerVcs: false,
};
// When using the "faster: true" shortcut
exports.DEFAULT_FASTER_CONFIG_TRUE = {
    swcJsLoader: true,
    swcJsMinimizer: true,
    swcHtmlMinimizer: true,
    lightningCssMinimizer: true,
    mdxCrossCompilerCache: true,
    rspackBundler: true,
    rspackPersistentCache: true,
    ssgWorkerThreads: true,
    gitEagerVcs: true,
};
exports.DEFAULT_FUTURE_V4_CONFIG = {
    removeLegacyPostBuildHeadAttribute: false,
    useCssCascadeLayers: false,
    siteStorageNamespacing: false,
    fasterByDefault: false,
    mdx1CompatDisabledByDefault: false,
};
// When using the "v4: true" shortcut
exports.DEFAULT_FUTURE_V4_CONFIG_TRUE = {
    removeLegacyPostBuildHeadAttribute: true,
    useCssCascadeLayers: true,
    siteStorageNamespacing: true,
    fasterByDefault: true,
    mdx1CompatDisabledByDefault: true,
};
exports.DEFAULT_FUTURE_CONFIG = {
    v4: exports.DEFAULT_FUTURE_V4_CONFIG,
    faster: exports.DEFAULT_FASTER_CONFIG,
    experimental_vcs: (0, utils_1.getVcsPreset)('default-v1'),
    experimental_router: 'browser',
};
exports.DEFAULT_MARKDOWN_HOOKS = {
    onBrokenMarkdownLinks: 'warn',
    onBrokenMarkdownImages: 'throw',
};
exports.DEFAULT_MARKDOWN_MDX1COMPAT = {
    comments: true,
    admonitions: true,
    headingIds: true,
};
exports.DEFAULT_MARKDOWN_CONFIG = {
    // TODO Docusaurus v5: change this to "detect"?
    //  we probably need stable CommonMark support first
    //  see https://github.com/facebook/docusaurus/issues/9092
    format: 'mdx',
    mermaid: false,
    emoji: true,
    preprocessor: undefined,
    parseFrontMatter: utils_1.DEFAULT_PARSE_FRONT_MATTER,
    mdx1Compat: exports.DEFAULT_MARKDOWN_MDX1COMPAT,
    anchors: {
        maintainCase: false,
    },
    remarkRehypeOptions: undefined,
    hooks: exports.DEFAULT_MARKDOWN_HOOKS,
};
exports.DEFAULT_CONFIG = {
    i18n: exports.DEFAULT_I18N_CONFIG,
    storage: exports.DEFAULT_STORAGE_CONFIG,
    future: exports.DEFAULT_FUTURE_CONFIG,
    onBrokenLinks: 'throw',
    onBrokenAnchors: 'warn', // TODO Docusaurus v4: change to throw
    onBrokenMarkdownLinks: undefined,
    onDuplicateRoutes: 'warn',
    plugins: [],
    themes: [],
    presets: [],
    headTags: [],
    stylesheets: [],
    scripts: [],
    clientModules: [],
    customFields: {},
    themeConfig: {},
    titleDelimiter: '|',
    noIndex: false,
    tagline: '',
    baseUrlIssueBanner: true,
    staticDirectories: [utils_1.DEFAULT_STATIC_DIR_NAME],
    markdown: exports.DEFAULT_MARKDOWN_CONFIG,
};
function createPluginSchema(theme) {
    return utils_validation_1.Joi.alternatives()
        .try(utils_validation_1.Joi.function(), utils_validation_1.Joi.array()
        .ordered(utils_validation_1.Joi.function().required(), utils_validation_1.Joi.object().required())
        .length(2), utils_validation_1.Joi.string(), utils_validation_1.Joi.array()
        .ordered(utils_validation_1.Joi.string().required(), utils_validation_1.Joi.object().required())
        .length(2), utils_validation_1.Joi.any().valid(false, null))
        .error((errors) => {
        errors.forEach((error) => {
            const validConfigExample = theme
                ? `Example valid theme config:
{
  themes: [
    ["@docusaurus/theme-classic",options],
    "./myTheme",
    ["./myTheme",{someOption: 42}],
    function myTheme() { },
    [function myTheme() { },options]
  ],
};`
                : `Example valid plugin config:
{
  plugins: [
    ["@docusaurus/plugin-content-docs",options],
    "./myPlugin",
    ["./myPlugin",{someOption: 42}],
    function myPlugin() { },
    [function myPlugin() { },options]
  ],
};`;
            error.message = ` => Bad Docusaurus ${theme ? 'theme' : 'plugin'} value ${error.path.reduce((acc, cur) => typeof cur === 'string' ? `${acc}.${cur}` : `${acc}[${cur}]`)}.
${validConfigExample}
`;
        });
        return errors;
    });
}
const PluginSchema = createPluginSchema(false);
const ThemeSchema = createPluginSchema(true);
const PresetSchema = utils_validation_1.Joi.alternatives()
    .try(utils_validation_1.Joi.string(), utils_validation_1.Joi.array()
    .items(utils_validation_1.Joi.string().required(), utils_validation_1.Joi.object().required())
    .length(2), utils_validation_1.Joi.any().valid(false, null))
    .messages({
    'alternatives.types': `{#label} does not look like a valid preset config. A preset config entry should be one of:
- A tuple of [presetName, options], like \`["classic", \\{ blog: false \\}]\`, or
- A simple string, like \`"classic"\``,
});
const LocaleConfigSchema = utils_validation_1.Joi.object({
    label: utils_validation_1.Joi.string(),
    htmlLang: utils_validation_1.Joi.string(),
    direction: utils_validation_1.Joi.string().equal('ltr', 'rtl'),
    calendar: utils_validation_1.Joi.string(),
    path: utils_validation_1.Joi.string(),
    translate: utils_validation_1.Joi.boolean(),
    url: SiteUrlSchema,
    baseUrl: BaseUrlSchema,
});
const I18N_CONFIG_SCHEMA = utils_validation_1.Joi.object({
    defaultLocale: utils_validation_1.Joi.string().required(),
    path: utils_validation_1.Joi.string().default(exports.DEFAULT_I18N_CONFIG.path),
    locales: utils_validation_1.Joi.array().items().min(1).items(utils_validation_1.Joi.string().required()).required(),
    localeConfigs: utils_validation_1.Joi.object()
        .pattern(/.*/, LocaleConfigSchema)
        .default(exports.DEFAULT_I18N_CONFIG.localeConfigs),
})
    .optional()
    .default(exports.DEFAULT_I18N_CONFIG);
// Individual boolean defaults are not set here on purpose
// They are resolved in postProcessDocusaurusConfig based on
// the future.v4.fasterByDefault flag
const FASTER_CONFIG_SCHEMA = utils_validation_1.Joi.alternatives()
    .try(utils_validation_1.Joi.object({
    swcJsLoader: utils_validation_1.Joi.boolean(),
    swcJsMinimizer: utils_validation_1.Joi.boolean(),
    swcHtmlMinimizer: utils_validation_1.Joi.boolean(),
    lightningCssMinimizer: utils_validation_1.Joi.boolean(),
    mdxCrossCompilerCache: utils_validation_1.Joi.boolean(),
    rspackBundler: utils_validation_1.Joi.boolean(),
    rspackPersistentCache: utils_validation_1.Joi.boolean(),
    ssgWorkerThreads: utils_validation_1.Joi.boolean(),
    gitEagerVcs: utils_validation_1.Joi.boolean(),
}), utils_validation_1.Joi.boolean()
    .required()
    .custom((bool) => bool ? exports.DEFAULT_FASTER_CONFIG_TRUE : exports.DEFAULT_FASTER_CONFIG))
    .optional();
const FUTURE_V4_SCHEMA = utils_validation_1.Joi.alternatives()
    .try(utils_validation_1.Joi.object({
    removeLegacyPostBuildHeadAttribute: utils_validation_1.Joi.boolean().default(exports.DEFAULT_FUTURE_V4_CONFIG.removeLegacyPostBuildHeadAttribute),
    useCssCascadeLayers: utils_validation_1.Joi.boolean().default(exports.DEFAULT_FUTURE_V4_CONFIG.useCssCascadeLayers),
    siteStorageNamespacing: utils_validation_1.Joi.boolean().default(exports.DEFAULT_FUTURE_V4_CONFIG.siteStorageNamespacing),
    fasterByDefault: utils_validation_1.Joi.boolean().default(exports.DEFAULT_FUTURE_V4_CONFIG.fasterByDefault),
    mdx1CompatDisabledByDefault: utils_validation_1.Joi.boolean().default(exports.DEFAULT_FUTURE_V4_CONFIG.mdx1CompatDisabledByDefault),
}), utils_validation_1.Joi.boolean()
    .required()
    .custom((bool) => bool ? exports.DEFAULT_FUTURE_V4_CONFIG_TRUE : exports.DEFAULT_FUTURE_V4_CONFIG))
    .optional()
    .default(exports.DEFAULT_FUTURE_V4_CONFIG);
const STORAGE_CONFIG_SCHEMA = utils_validation_1.Joi.object({
    type: utils_validation_1.Joi.string()
        .equal('localStorage', 'sessionStorage')
        .default(exports.DEFAULT_STORAGE_CONFIG.type),
    // namespace default is not set here on purpose
    // It is resolved in postProcessDocusaurusConfig based on
    // the future.v4.siteStorageNamespacing flag
    namespace: utils_validation_1.Joi.alternatives().try(utils_validation_1.Joi.string(), utils_validation_1.Joi.boolean()),
})
    .optional()
    .default({ type: exports.DEFAULT_STORAGE_CONFIG.type });
const VCS_CONFIG_OBJECT_SCHEMA = utils_validation_1.Joi.object({
    // All the fields are required on purpose
    // You either provide a full VCS config or nothing
    initialize: utils_validation_1.Joi.function().maxArity(1).required(),
    getFileCreationInfo: utils_validation_1.Joi.function().arity(1).required(),
    getFileLastUpdateInfo: utils_validation_1.Joi.function().arity(1).required(),
});
const VCS_CONFIG_SCHEMA = utils_validation_1.Joi.custom((input) => {
    if (typeof input === 'string') {
        const presetName = input;
        if (!utils_1.VcsPresetNames.includes(presetName)) {
            throw new Error(`VCS config preset name '${input}' is not valid.`);
        }
        return (0, utils_1.getVcsPreset)(presetName);
    }
    if (typeof input === 'boolean') {
        // We return the boolean on purpose
        // We'll normalize it to a real VcsConfig later
        // This is annoying, but we have to read the future flag to switch to the
        // new "default-v2" config (not easy to do it here)
        return input;
    }
    const { error, value } = VCS_CONFIG_OBJECT_SCHEMA.validate(input);
    if (error) {
        throw error;
    }
    return value;
}).default(true);
const FUTURE_CONFIG_SCHEMA = utils_validation_1.Joi.object({
    v4: FUTURE_V4_SCHEMA,
    faster: FASTER_CONFIG_SCHEMA,
    experimental_vcs: VCS_CONFIG_SCHEMA,
    experimental_router: utils_validation_1.Joi.string()
        .equal('browser', 'hash')
        .default(exports.DEFAULT_FUTURE_CONFIG.experimental_router),
    experimental_storage: utils_validation_1.Joi.any()
        .forbidden()
        .messages({
        'any.unknown': `The Docusaurus config ${logger_1.default.code('future.experimental_storage')} has been promoted to a stable top-level ${logger_1.default.code('storage')} config attribute. Please move your storage config to the top level.`,
    }),
    experimental_faster: utils_validation_1.Joi.any()
        .forbidden()
        .messages({
        'any.unknown': `The Docusaurus config ${logger_1.default.code('future.experimental_faster')} has been renamed to ${logger_1.default.code('future.faster')}. Please update your Docusaurus config.`,
    }),
})
    .optional()
    .default(exports.DEFAULT_FUTURE_CONFIG);
// TODO move to @docusaurus/utils-validation
exports.ConfigSchema = utils_validation_1.Joi.object({
    url: SiteUrlSchema.required(),
    baseUrl: BaseUrlSchema.required(),
    baseUrlIssueBanner: utils_validation_1.Joi.boolean().default(exports.DEFAULT_CONFIG.baseUrlIssueBanner),
    favicon: utils_validation_1.Joi.string().optional(),
    title: utils_validation_1.Joi.string().required(),
    trailingSlash: utils_validation_1.Joi.boolean(), // No default value! undefined = retrocompatible legacy behavior!
    i18n: I18N_CONFIG_SCHEMA,
    storage: STORAGE_CONFIG_SCHEMA,
    future: FUTURE_CONFIG_SCHEMA,
    onBrokenLinks: utils_validation_1.Joi.string()
        .equal('ignore', 'log', 'warn', 'throw')
        .default(exports.DEFAULT_CONFIG.onBrokenLinks),
    onBrokenAnchors: utils_validation_1.Joi.string()
        .equal('ignore', 'log', 'warn', 'throw')
        .default(exports.DEFAULT_CONFIG.onBrokenAnchors),
    onBrokenMarkdownLinks: utils_validation_1.Joi.string()
        .equal('ignore', 'log', 'warn', 'throw')
        .default(() => exports.DEFAULT_CONFIG.onBrokenMarkdownLinks),
    onDuplicateRoutes: utils_validation_1.Joi.string()
        .equal('ignore', 'log', 'warn', 'throw')
        .default(exports.DEFAULT_CONFIG.onDuplicateRoutes),
    organizationName: utils_validation_1.Joi.string().allow(''),
    staticDirectories: utils_validation_1.Joi.array()
        .items(utils_validation_1.Joi.string())
        .default(exports.DEFAULT_CONFIG.staticDirectories),
    projectName: utils_validation_1.Joi.string().allow(''),
    deploymentBranch: utils_validation_1.Joi.string().optional(),
    customFields: utils_validation_1.Joi.object().unknown().default(exports.DEFAULT_CONFIG.customFields),
    githubHost: utils_validation_1.Joi.string(),
    githubPort: utils_validation_1.Joi.string(),
    plugins: utils_validation_1.Joi.array().items(PluginSchema).default(exports.DEFAULT_CONFIG.plugins),
    themes: utils_validation_1.Joi.array().items(ThemeSchema).default(exports.DEFAULT_CONFIG.themes),
    presets: utils_validation_1.Joi.array().items(PresetSchema).default(exports.DEFAULT_CONFIG.presets),
    themeConfig: utils_validation_1.Joi.object().unknown().default(exports.DEFAULT_CONFIG.themeConfig),
    scripts: utils_validation_1.Joi.array()
        .items(utils_validation_1.Joi.string(), utils_validation_1.Joi.object({
        src: utils_validation_1.Joi.string().required(),
        async: utils_validation_1.Joi.bool(),
        defer: utils_validation_1.Joi.bool(),
    })
        // See https://github.com/facebook/docusaurus/issues/3378
        .unknown())
        .messages({
        'array.includes': '{#label} is invalid. A script must be a plain string (the src), or an object with at least a "src" property.',
    })
        .default(exports.DEFAULT_CONFIG.scripts),
    ssrTemplate: utils_validation_1.Joi.string(),
    headTags: utils_validation_1.Joi.array()
        .items(utils_validation_1.Joi.object({
        tagName: utils_validation_1.Joi.string().required(),
        attributes: utils_validation_1.Joi.object().when('customElement', {
            is: utils_validation_1.Joi.valid(true),
            then: utils_validation_1.Joi.optional(),
            otherwise: utils_validation_1.Joi.object()
                .pattern(/[\w-]+/, utils_validation_1.Joi.string())
                .required(),
        }),
        customElement: utils_validation_1.Joi.bool().default(false),
    }).unknown())
        .messages({
        'array.includes': '{#label} is invalid. A headTag must be an object with at least a "tagName" and an "attributes" property.',
    })
        .default(exports.DEFAULT_CONFIG.headTags),
    stylesheets: utils_validation_1.Joi.array()
        .items(utils_validation_1.Joi.string(), utils_validation_1.Joi.object({
        href: utils_validation_1.Joi.string().required(),
        type: utils_validation_1.Joi.string(),
    }).unknown())
        .messages({
        'array.includes': '{#label} is invalid. A stylesheet must be a plain string (the href), or an object with at least a "href" property.',
    })
        .default(exports.DEFAULT_CONFIG.stylesheets),
    clientModules: utils_validation_1.Joi.array()
        .items(utils_validation_1.Joi.string())
        .default(exports.DEFAULT_CONFIG.clientModules),
    tagline: utils_validation_1.Joi.string().allow('').default(exports.DEFAULT_CONFIG.tagline),
    titleDelimiter: utils_validation_1.Joi.string().default(exports.DEFAULT_CONFIG.titleDelimiter),
    noIndex: utils_validation_1.Joi.bool().default(exports.DEFAULT_CONFIG.noIndex),
    webpack: utils_validation_1.Joi.object({
        jsLoader: utils_validation_1.Joi.alternatives()
            .try(utils_validation_1.Joi.string().equal('babel'), utils_validation_1.Joi.function())
            .optional(),
    }).optional(),
    markdown: utils_validation_1.Joi.object({
        format: utils_validation_1.Joi.string()
            .equal('mdx', 'md', 'detect')
            .default(exports.DEFAULT_CONFIG.markdown.format),
        parseFrontMatter: utils_validation_1.Joi.function().default(() => exports.DEFAULT_CONFIG.markdown.parseFrontMatter),
        mermaid: utils_validation_1.Joi.boolean().default(exports.DEFAULT_CONFIG.markdown.mermaid),
        emoji: utils_validation_1.Joi.boolean().default(exports.DEFAULT_CONFIG.markdown.emoji),
        preprocessor: utils_validation_1.Joi.function()
            .arity(1)
            .optional()
            .default(() => exports.DEFAULT_CONFIG.markdown.preprocessor),
        // Individual boolean defaults are not set here on purpose
        // They are resolved in postProcessDocusaurusConfig based on
        // the future.v4.mdx1CompatDisabledByDefault flag
        mdx1Compat: utils_validation_1.Joi.object({
            comments: utils_validation_1.Joi.boolean(),
            admonitions: utils_validation_1.Joi.boolean(),
            headingIds: utils_validation_1.Joi.boolean(),
        }).default({}),
        remarkRehypeOptions: 
        // add proper external options validation?
        // Not sure if it's a good idea, validation is likely to become stale
        // See https://github.com/remarkjs/remark-rehype#options
        utils_validation_1.Joi.object().unknown(),
        anchors: utils_validation_1.Joi.object({
            maintainCase: utils_validation_1.Joi.boolean().default(exports.DEFAULT_CONFIG.markdown.anchors.maintainCase),
        }).default(exports.DEFAULT_CONFIG.markdown.anchors),
        hooks: utils_validation_1.Joi.object({
            onBrokenMarkdownLinks: utils_validation_1.Joi.alternatives()
                .try(utils_validation_1.Joi.string().equal('ignore', 'log', 'warn', 'throw'), utils_validation_1.Joi.function())
                .default(exports.DEFAULT_CONFIG.markdown.hooks.onBrokenMarkdownLinks),
            onBrokenMarkdownImages: utils_validation_1.Joi.alternatives()
                .try(utils_validation_1.Joi.string().equal('ignore', 'log', 'warn', 'throw'), utils_validation_1.Joi.function())
                .default(exports.DEFAULT_CONFIG.markdown.hooks.onBrokenMarkdownImages),
        }).default(exports.DEFAULT_CONFIG.markdown.hooks),
    }).default({
        ...exports.DEFAULT_CONFIG.markdown,
        mdx1Compat: {
        // erased on purpose, filled using postprocessing
        },
    }),
}).messages({
    'docusaurus.configValidationWarning': 'Docusaurus config validation warning. Field {#label}: {#warningMessage}',
});
// Expressing this kind of logic in Joi is a pain
// We also want to decouple logic from Joi: easier to remove it later!
function postProcessDocusaurusConfig(config) {
    var _a;
    // Resolve storage.namespace based on the v4 future flag
    // undefined means "not explicitly set by user"
    if (config.storage.namespace === undefined) {
        config.storage.namespace = config.future.v4.siteStorageNamespacing;
    }
    // Resolve faster config based on the v4.fasterByDefault flag
    // undefined means "not explicitly set by user"
    if (config.future.faster === undefined) {
        config.future.faster = {};
    }
    const fasterDefault = config.future.v4.fasterByDefault;
    const fasterKeys = Object.keys(exports.DEFAULT_FASTER_CONFIG);
    for (const key of fasterKeys) {
        if (config.future.faster[key] === undefined) {
            config.future.faster[key] = fasterDefault;
        }
    }
    // Resolve mdx1Compat config based on the v4.mdx1CompatDisabledByDefault flag
    // undefined means "not explicitly set by user"
    const mdx1CompatDefault = !config.future.v4.mdx1CompatDisabledByDefault;
    const mdx1CompatKeys = Object.keys(exports.DEFAULT_MARKDOWN_MDX1COMPAT);
    for (const key of mdx1CompatKeys) {
        (_a = config.markdown.mdx1Compat)[key] ?? (_a[key] = mdx1CompatDefault);
    }
    if (config.onBrokenMarkdownLinks) {
        logger_1.default.warn `The code=${'siteConfig.onBrokenMarkdownLinks'} config option is deprecated and will be removed in Docusaurus v4.
Please migrate and move this option to code=${'siteConfig.markdown.hooks.onBrokenMarkdownLinks'} instead.`;
        // For v3 retro compatibility we use the old attribute over the new one
        config.markdown.hooks.onBrokenMarkdownLinks = config.onBrokenMarkdownLinks;
        // We erase the former one to ensure we don't use it anywhere
        config.onBrokenMarkdownLinks = undefined;
    }
    // We normalize the VCS config when using a boolean value
    if (typeof config.future.experimental_vcs === 'boolean') {
        const vcsConfig = config.future.experimental_vcs
            ? config.future.faster.gitEagerVcs
                ? (0, utils_1.getVcsPreset)('default-v2')
                : (0, utils_1.getVcsPreset)('default-v1')
            : (0, utils_1.getVcsPreset)('disabled');
        config.future.experimental_vcs = vcsConfig;
    }
    if (config.future.faster.ssgWorkerThreads &&
        !config.future.v4.removeLegacyPostBuildHeadAttribute) {
        throw new Error(`Docusaurus config ${logger_1.default.code('future.faster.ssgWorkerThreads')} requires the future flag ${logger_1.default.code('future.v4.removeLegacyPostBuildHeadAttribute')} to be turned on.
If you use Docusaurus Faster, we recommend that you also activate Docusaurus v4 future flags: ${logger_1.default.code('{future: {v4: true}}')}
All the v4 future flags are documented here: https://docusaurus.io/docs/api/docusaurus-config#future`);
    }
    if (config.future.faster.rspackPersistentCache &&
        !config.future.faster.rspackBundler) {
        throw new Error(`Docusaurus config flag ${logger_1.default.code('future.faster.rspackPersistentCache')} requires the flag ${logger_1.default.code('future.faster.rspackBundler')} to be turned on.`);
    }
}
// TODO move to @docusaurus/utils-validation
function validateConfig(config, siteConfigPath) {
    const { error, warning, value } = exports.ConfigSchema.validate(config, {
        abortEarly: false,
    });
    (0, utils_validation_1.printWarning)(warning);
    if (error) {
        const unknownFields = error.details.reduce((formattedError, err) => {
            if (err.type === 'object.unknown') {
                return `${formattedError}"${err.path.reduce((acc, cur) => typeof cur === 'string' ? `${acc}.${cur}` : `${acc}[${cur}]`)}",`;
            }
            return formattedError;
        }, '');
        let formattedError = error.details.reduce((accumulatedErr, err) => err.type !== 'object.unknown'
            ? `${accumulatedErr}${err.message}\n`
            : accumulatedErr, '');
        formattedError = unknownFields
            ? `${formattedError}These field(s) (${unknownFields}) are not recognized in ${siteConfigPath}.\nIf you still want these fields to be in your configuration, put them in the "customFields" field.\nSee https://docusaurus.io/docs/api/docusaurus-config/#customfields`
            : formattedError;
        throw new Error(formattedError);
    }
    postProcessDocusaurusConfig(value);
    return value;
}
