"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.validateOptions = exports.validateThemeConfig = exports.ThemeConfigSchema = exports.DEFAULT_CONFIG = void 0;
const prism_react_renderer_1 = require("prism-react-renderer");
const utils_validation_1 = require("@docusaurus/utils-validation");
const defaultPrismTheme = prism_react_renderer_1.themes.palenight;
const DEFAULT_DOCS_CONFIG = {
    versionPersistence: 'localStorage',
    sidebar: {
        hideable: false,
        autoCollapseCategories: false,
    },
};
const DocsSchema = utils_validation_1.Joi.object({
    versionPersistence: utils_validation_1.Joi.string()
        .equal('localStorage', 'none')
        .default(DEFAULT_DOCS_CONFIG.versionPersistence),
    sidebar: utils_validation_1.Joi.object({
        hideable: utils_validation_1.Joi.bool().default(DEFAULT_DOCS_CONFIG.sidebar.hideable),
        autoCollapseCategories: utils_validation_1.Joi.bool().default(DEFAULT_DOCS_CONFIG.sidebar.autoCollapseCategories),
    }).default(DEFAULT_DOCS_CONFIG.sidebar),
}).default(DEFAULT_DOCS_CONFIG);
const DEFAULT_COLOR_MODE_CONFIG = {
    defaultMode: 'light',
    disableSwitch: false,
    respectPrefersColorScheme: false,
};
exports.DEFAULT_CONFIG = {
    colorMode: DEFAULT_COLOR_MODE_CONFIG,
    docs: DEFAULT_DOCS_CONFIG,
    metadata: [],
    prism: {
        additionalLanguages: [],
        theme: defaultPrismTheme,
        magicComments: [
            {
                className: 'theme-code-block-highlighted-line',
                line: 'highlight-next-line',
                block: { start: 'highlight-start', end: 'highlight-end' },
            },
        ],
    },
    navbar: {
        hideOnScroll: false,
        items: [],
    },
    tableOfContents: {
        minHeadingLevel: 2,
        maxHeadingLevel: 3,
    },
};
const NavbarItemPosition = utils_validation_1.Joi.string().equal('left', 'right').default('left');
const NavbarItemBaseSchema = utils_validation_1.Joi.object({
    label: utils_validation_1.Joi.string(),
    html: utils_validation_1.Joi.string(),
    className: utils_validation_1.Joi.string(),
})
    .nand('html', 'label')
    // We allow any unknown attributes on the links (users may need additional
    // attributes like target, aria-role, data-customAttribute...)
    .unknown();
const DefaultNavbarItemSchema = NavbarItemBaseSchema.append({
    to: utils_validation_1.Joi.string(),
    href: utils_validation_1.URISchema,
    activeBasePath: utils_validation_1.Joi.string(),
    activeBaseRegex: utils_validation_1.Joi.string(),
    prependBaseUrlToHref: utils_validation_1.Joi.bool(),
    // This is only triggered in case of a nested dropdown
    items: utils_validation_1.Joi.forbidden().messages({
        'any.unknown': 'Nested dropdowns are not allowed',
    }),
})
    .xor('href', 'to')
    .messages({
    'object.xor': 'One and only one between "to" and "href" should be provided',
});
const DocsVersionNavbarItemSchema = NavbarItemBaseSchema.append({
    type: utils_validation_1.Joi.string().equal('docsVersion').required(),
    to: utils_validation_1.Joi.string(),
    docsPluginId: utils_validation_1.Joi.string(),
});
const DocItemSchema = NavbarItemBaseSchema.append({
    type: utils_validation_1.Joi.string().equal('doc').required(),
    docId: utils_validation_1.Joi.string().required(),
    docsPluginId: utils_validation_1.Joi.string(),
});
const DocSidebarItemSchema = NavbarItemBaseSchema.append({
    type: utils_validation_1.Joi.string().equal('docSidebar').required(),
    sidebarId: utils_validation_1.Joi.string().required(),
    docsPluginId: utils_validation_1.Joi.string(),
});
const HtmlNavbarItemSchema = utils_validation_1.Joi.object({
    className: utils_validation_1.Joi.string(),
    type: utils_validation_1.Joi.string().equal('html').required(),
    value: utils_validation_1.Joi.string().required(),
});
// A temporary workaround to allow users to add custom navbar items
// See https://github.com/facebook/docusaurus/issues/7227
const CustomNavbarItemRegexp = /custom-.*/;
const CustomNavbarItemSchema = utils_validation_1.Joi.object({
    type: utils_validation_1.Joi.string().regex(CustomNavbarItemRegexp).required(),
}).unknown();
const itemWithType = (type) => {
    // Because equal(undefined) is not supported :/
    const typeSchema = 
    // eslint-disable-next-line no-nested-ternary
    type instanceof RegExp
        ? utils_validation_1.Joi.string().required().regex(type)
        : type
            ? utils_validation_1.Joi.string().required().equal(type)
            : utils_validation_1.Joi.string().forbidden();
    return utils_validation_1.Joi.object({
        type: typeSchema,
    })
        .unknown()
        .required();
};
const DropdownSubitemSchema = utils_validation_1.Joi.object({
    position: utils_validation_1.Joi.forbidden(),
}).when('.', {
    switch: [
        {
            is: itemWithType('docsVersion'),
            then: DocsVersionNavbarItemSchema,
        },
        {
            is: itemWithType('doc'),
            then: DocItemSchema,
        },
        {
            is: itemWithType('docSidebar'),
            then: DocSidebarItemSchema,
        },
        {
            is: itemWithType(undefined),
            then: DefaultNavbarItemSchema,
        },
        {
            is: itemWithType('html'),
            then: HtmlNavbarItemSchema,
        },
        {
            is: itemWithType(CustomNavbarItemRegexp),
            then: CustomNavbarItemSchema,
        },
        {
            is: utils_validation_1.Joi.alternatives().try(itemWithType('dropdown'), itemWithType('docsVersionDropdown'), itemWithType('localeDropdown'), itemWithType('search')),
            then: utils_validation_1.Joi.forbidden().messages({
                'any.unknown': 'Nested dropdowns are not allowed',
            }),
        },
    ],
    otherwise: utils_validation_1.Joi.forbidden().messages({
        'any.unknown': 'Bad navbar item type {.type}',
    }),
});
const DropdownNavbarItemSchema = NavbarItemBaseSchema.append({
    items: utils_validation_1.Joi.array().items(DropdownSubitemSchema).required(),
});
const DocsVersionDropdownNavbarItemSchema = NavbarItemBaseSchema.append({
    type: utils_validation_1.Joi.string().equal('docsVersionDropdown').required(),
    docsPluginId: utils_validation_1.Joi.string(),
    dropdownActiveClassDisabled: utils_validation_1.Joi.boolean(),
    dropdownItemsBefore: utils_validation_1.Joi.array().items(DropdownSubitemSchema).default([]),
    dropdownItemsAfter: utils_validation_1.Joi.array().items(DropdownSubitemSchema).default([]),
});
const LocaleDropdownNavbarItemSchema = NavbarItemBaseSchema.append({
    type: utils_validation_1.Joi.string().equal('localeDropdown').required(),
    dropdownItemsBefore: utils_validation_1.Joi.array().items(DropdownSubitemSchema).default([]),
    dropdownItemsAfter: utils_validation_1.Joi.array().items(DropdownSubitemSchema).default([]),
    queryString: utils_validation_1.Joi.string(),
});
const SearchItemSchema = utils_validation_1.Joi.object({
    type: utils_validation_1.Joi.string().equal('search').required(),
    className: utils_validation_1.Joi.string(),
});
const NavbarItemSchema = utils_validation_1.Joi.object({
    position: NavbarItemPosition,
}).when('.', {
    switch: [
        {
            is: itemWithType('docsVersion'),
            then: DocsVersionNavbarItemSchema,
        },
        {
            is: itemWithType('dropdown'),
            then: DropdownNavbarItemSchema,
        },
        {
            is: itemWithType('docsVersionDropdown'),
            then: DocsVersionDropdownNavbarItemSchema,
        },
        {
            is: itemWithType('doc'),
            then: DocItemSchema,
        },
        {
            is: itemWithType('docSidebar'),
            then: DocSidebarItemSchema,
        },
        {
            is: itemWithType('localeDropdown'),
            then: LocaleDropdownNavbarItemSchema,
        },
        {
            is: itemWithType('search'),
            then: SearchItemSchema,
        },
        {
            is: itemWithType('html'),
            then: HtmlNavbarItemSchema,
        },
        {
            is: itemWithType(CustomNavbarItemRegexp),
            then: CustomNavbarItemSchema,
        },
        {
            is: itemWithType(undefined),
            then: utils_validation_1.Joi.object().when('.', {
                // Dropdown item can be specified without type field
                is: utils_validation_1.Joi.object({
                    items: utils_validation_1.Joi.array().required(),
                }).unknown(),
                then: DropdownNavbarItemSchema,
                otherwise: DefaultNavbarItemSchema,
            }),
        },
    ],
    otherwise: utils_validation_1.Joi.forbidden().messages({
        'any.unknown': 'Bad navbar item type {.type}',
    }),
});
const ColorModeSchema = utils_validation_1.Joi.object({
    defaultMode: utils_validation_1.Joi.string()
        .equal('dark', 'light')
        .default(DEFAULT_COLOR_MODE_CONFIG.defaultMode),
    disableSwitch: utils_validation_1.Joi.bool().default(DEFAULT_COLOR_MODE_CONFIG.disableSwitch),
    respectPrefersColorScheme: utils_validation_1.Joi.bool().default(DEFAULT_COLOR_MODE_CONFIG.respectPrefersColorScheme),
    switchConfig: utils_validation_1.Joi.any().forbidden().messages({
        'any.unknown': 'colorMode.switchConfig is deprecated. If you want to customize the icons for light and dark mode, swizzle IconLightMode, IconDarkMode, or ColorModeToggle instead.',
    }),
}).default(DEFAULT_COLOR_MODE_CONFIG);
const HtmlMetadataSchema = utils_validation_1.Joi.object({
    id: utils_validation_1.Joi.string(),
    name: utils_validation_1.Joi.string(),
    property: utils_validation_1.Joi.string(),
    content: utils_validation_1.Joi.string(),
    itemprop: utils_validation_1.Joi.string(),
}).unknown();
const FooterLinkItemSchema = utils_validation_1.Joi.object({
    to: utils_validation_1.Joi.string(),
    href: utils_validation_1.URISchema,
    html: utils_validation_1.Joi.string(),
    label: utils_validation_1.Joi.string(),
})
    .xor('to', 'href', 'html')
    .with('to', 'label')
    .with('href', 'label')
    .nand('html', 'label')
    // We allow any unknown attributes on the links (users may need additional
    // attributes like target, aria-role, data-customAttribute...)
    .unknown();
const LogoSchema = utils_validation_1.Joi.object({
    alt: utils_validation_1.Joi.string().allow(''),
    src: utils_validation_1.Joi.string().required(),
    srcDark: utils_validation_1.Joi.string(),
    width: utils_validation_1.Joi.alternatives().try(utils_validation_1.Joi.string(), utils_validation_1.Joi.number()),
    height: utils_validation_1.Joi.alternatives().try(utils_validation_1.Joi.string(), utils_validation_1.Joi.number()),
    href: utils_validation_1.Joi.string(),
    target: utils_validation_1.Joi.string(),
    style: utils_validation_1.Joi.object(),
    className: utils_validation_1.Joi.string(),
});
// Normalize prism language to lowercase
// See https://github.com/facebook/docusaurus/issues/9012
const PrismLanguage = utils_validation_1.Joi.string().custom((val) => val.toLowerCase());
exports.ThemeConfigSchema = utils_validation_1.Joi.object({
    // TODO temporary (@alpha-58)
    // @ts-expect-error: forbidden
    disableDarkMode: utils_validation_1.Joi.any().forbidden().messages({
        'any.unknown': 'disableDarkMode theme config is deprecated. Please use the new colorMode attribute. You likely want: config.themeConfig.colorMode.disableSwitch = true',
    }),
    // TODO temporary (@alpha-58)
    defaultDarkMode: utils_validation_1.Joi.any().forbidden().messages({
        'any.unknown': 'defaultDarkMode theme config is deprecated. Please use the new colorMode attribute. You likely want: config.themeConfig.colorMode.defaultMode = "dark"',
    }),
    colorMode: ColorModeSchema,
    image: utils_validation_1.Joi.string(),
    docs: DocsSchema,
    metadata: utils_validation_1.Joi.array()
        .items(HtmlMetadataSchema)
        .default(exports.DEFAULT_CONFIG.metadata),
    // cSpell:ignore metadatas
    metadatas: utils_validation_1.Joi.any().forbidden().messages({
        'any.unknown': 
        // cSpell:ignore metadatas
        'themeConfig.metadatas has been renamed as themeConfig.metadata. See https://github.com/facebook/docusaurus/pull/5871',
    }),
    announcementBar: utils_validation_1.Joi.object({
        id: utils_validation_1.Joi.string().default('announcement-bar'),
        content: utils_validation_1.Joi.string().required(),
        backgroundColor: utils_validation_1.Joi.string(),
        textColor: utils_validation_1.Joi.string(),
        isCloseable: utils_validation_1.Joi.bool().default(true),
    }).optional(),
    navbar: utils_validation_1.Joi.object({
        style: utils_validation_1.Joi.string().equal('dark', 'primary'),
        hideOnScroll: utils_validation_1.Joi.bool().default(exports.DEFAULT_CONFIG.navbar.hideOnScroll),
        // TODO temporary (@alpha-58)
        links: utils_validation_1.Joi.any().forbidden().messages({
            'any.unknown': 'themeConfig.navbar.links has been renamed as themeConfig.navbar.items',
        }),
        items: utils_validation_1.Joi.array()
            .items(NavbarItemSchema)
            .default(exports.DEFAULT_CONFIG.navbar.items),
        title: utils_validation_1.Joi.string().allow('', null),
        logo: LogoSchema,
    }).default(exports.DEFAULT_CONFIG.navbar),
    footer: utils_validation_1.Joi.object({
        style: utils_validation_1.Joi.string().equal('dark', 'light').default('light'),
        logo: LogoSchema,
        copyright: utils_validation_1.Joi.string(),
        links: utils_validation_1.Joi.alternatives(utils_validation_1.Joi.array().items(utils_validation_1.Joi.object({
            title: utils_validation_1.Joi.string().allow(null).default(null),
            items: utils_validation_1.Joi.array().items(FooterLinkItemSchema).default([]),
        })), utils_validation_1.Joi.array().items(FooterLinkItemSchema))
            .messages({
            'alternatives.match': `The footer must be either simple or multi-column, and not a mix of the two. See: https://docusaurus.io/docs/api/themes/configuration#footer-links`,
        })
            .default([]),
    }).optional(),
    prism: utils_validation_1.Joi.object({
        theme: utils_validation_1.Joi.object({
            plain: utils_validation_1.Joi.alternatives().try(utils_validation_1.Joi.array(), utils_validation_1.Joi.object()).required(),
            styles: utils_validation_1.Joi.alternatives().try(utils_validation_1.Joi.array(), utils_validation_1.Joi.object()).required(),
        }).default(exports.DEFAULT_CONFIG.prism.theme),
        darkTheme: utils_validation_1.Joi.object({
            plain: utils_validation_1.Joi.alternatives().try(utils_validation_1.Joi.array(), utils_validation_1.Joi.object()).required(),
            styles: utils_validation_1.Joi.alternatives().try(utils_validation_1.Joi.array(), utils_validation_1.Joi.object()).required(),
        }),
        defaultLanguage: PrismLanguage,
        additionalLanguages: utils_validation_1.Joi.array()
            .items(PrismLanguage)
            .default(exports.DEFAULT_CONFIG.prism.additionalLanguages),
        magicComments: utils_validation_1.Joi.array()
            .items(utils_validation_1.Joi.object({
            className: utils_validation_1.Joi.string().required(),
            line: utils_validation_1.Joi.string(),
            block: utils_validation_1.Joi.object({
                start: utils_validation_1.Joi.string().required(),
                end: utils_validation_1.Joi.string().required(),
            }),
        }).or('line', 'block'))
            .default(exports.DEFAULT_CONFIG.prism.magicComments),
    })
        .default(exports.DEFAULT_CONFIG.prism)
        .unknown(),
    hideableSidebar: utils_validation_1.Joi.forbidden().messages({
        'any.unknown': 'themeConfig.hideableSidebar has been moved to themeConfig.docs.sidebar.hideable.',
    }),
    autoCollapseSidebarCategories: utils_validation_1.Joi.forbidden().messages({
        'any.unknown': 'themeConfig.autoCollapseSidebarCategories has been moved to themeConfig.docs.sidebar.autoCollapseCategories.',
    }),
    sidebarCollapsible: utils_validation_1.Joi.forbidden().messages({
        'any.unknown': 'The themeConfig.sidebarCollapsible has been moved to docs plugin options. See: https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-docs',
    }),
    tableOfContents: utils_validation_1.Joi.object({
        minHeadingLevel: utils_validation_1.Joi.number()
            .default(exports.DEFAULT_CONFIG.tableOfContents.minHeadingLevel)
            .when('maxHeadingLevel', {
            is: utils_validation_1.Joi.exist(),
            then: utils_validation_1.Joi.number()
                .integer()
                .min(2)
                .max(6)
                .max(utils_validation_1.Joi.ref('maxHeadingLevel')),
            otherwise: utils_validation_1.Joi.number().integer().min(2).max(6),
        }),
        maxHeadingLevel: utils_validation_1.Joi.number()
            .integer()
            .min(2)
            .max(6)
            .default(exports.DEFAULT_CONFIG.tableOfContents.maxHeadingLevel),
    }).default(exports.DEFAULT_CONFIG.tableOfContents),
});
function validateThemeConfig({ validate, themeConfig, }) {
    return validate(exports.ThemeConfigSchema, themeConfig);
}
exports.validateThemeConfig = validateThemeConfig;
const DEFAULT_OPTIONS = {
    customCss: [],
};
const PluginOptionSchema = utils_validation_1.Joi.object({
    customCss: utils_validation_1.Joi.alternatives()
        .try(utils_validation_1.Joi.array().items(utils_validation_1.Joi.string().required()), utils_validation_1.Joi.alternatives().conditional(utils_validation_1.Joi.string().required(), {
        then: utils_validation_1.Joi.custom((val) => [val]),
        otherwise: utils_validation_1.Joi.forbidden().messages({
            'any.unknown': '"customCss" must be a string or an array of strings',
        }),
    }))
        .default(DEFAULT_OPTIONS.customCss),
});
function validateOptions({ validate, options, }) {
    const validatedOptions = validate(PluginOptionSchema, options);
    return validatedOptions;
}
exports.validateOptions = validateOptions;
