"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.validateCategoryMetadataFile = exports.validateSidebars = void 0; const utils_validation_1 = require("@docusaurus/utils-validation"); // NOTE: we don't add any default values during validation on purpose! // Config types are exposed to users for typechecking and we use the same type // in normalization const sidebarItemBaseSchema = utils_validation_1.Joi.object({ className: utils_validation_1.Joi.string(), customProps: utils_validation_1.Joi.object().unknown(), }); const sidebarItemAutogeneratedSchema = sidebarItemBaseSchema.append({ type: 'autogenerated', dirName: utils_validation_1.Joi.string() .required() .pattern(/^[^/](?:.*[^/])?$/) .message('"dirName" must be a dir path relative to the docs folder root, and should not start or end with slash'), }); const sidebarItemDocSchema = sidebarItemBaseSchema.append({ type: utils_validation_1.Joi.string().valid('doc', 'ref').required(), id: utils_validation_1.Joi.string().required(), label: utils_validation_1.Joi.string(), translatable: utils_validation_1.Joi.boolean(), }); const sidebarItemHtmlSchema = sidebarItemBaseSchema.append({ type: 'html', value: utils_validation_1.Joi.string().required(), defaultStyle: utils_validation_1.Joi.boolean(), }); const sidebarItemLinkSchema = sidebarItemBaseSchema.append({ type: 'link', href: utils_validation_1.URISchema.required(), autoAddBaseUrl: utils_validation_1.Joi.boolean(), label: utils_validation_1.Joi.string() .required() .messages({ 'any.unknown': '"label" must be a string' }), description: utils_validation_1.Joi.string().optional().messages({ 'any.unknown': '"description" must be a string', }), }); const sidebarItemCategoryLinkSchema = utils_validation_1.Joi.object() .allow(null) .when('.type', { switch: [ { is: 'doc', then: utils_validation_1.Joi.object({ type: 'doc', id: utils_validation_1.Joi.string().required(), }), }, { is: 'generated-index', then: utils_validation_1.Joi.object({ type: 'generated-index', slug: utils_validation_1.Joi.string().optional(), // This one is not in the user config, only in the normalized version // permalink: Joi.string().optional(), title: utils_validation_1.Joi.string().optional(), description: utils_validation_1.Joi.string().optional(), image: utils_validation_1.Joi.string().optional(), keywords: [utils_validation_1.Joi.string(), utils_validation_1.Joi.array().items(utils_validation_1.Joi.string())], }), }, { is: utils_validation_1.Joi.required(), then: utils_validation_1.Joi.forbidden().messages({ 'any.unknown': 'Unknown sidebar category link type "{.type}".', }), }, ], }); const sidebarItemCategorySchema = sidebarItemBaseSchema.append({ type: 'category', label: utils_validation_1.Joi.string() .required() .messages({ 'any.unknown': '"label" must be a string' }), items: utils_validation_1.Joi.array() .required() .messages({ 'any.unknown': '"items" must be an array' }), // TODO: Joi doesn't allow mutual recursion. See https://github.com/sideway/joi/issues/2611 // .items(Joi.link('#sidebarItemSchema')), link: sidebarItemCategoryLinkSchema, collapsed: utils_validation_1.Joi.boolean().messages({ 'any.unknown': '"collapsed" must be a boolean', }), collapsible: utils_validation_1.Joi.boolean().messages({ 'any.unknown': '"collapsible" must be a boolean', }), description: utils_validation_1.Joi.string().optional().messages({ 'any.unknown': '"description" must be a string', }), }); const sidebarItemSchema = utils_validation_1.Joi.object().when('.type', { switch: [ { is: 'link', then: sidebarItemLinkSchema }, { is: utils_validation_1.Joi.string().valid('doc', 'ref').required(), then: sidebarItemDocSchema, }, { is: 'html', then: sidebarItemHtmlSchema }, { is: 'autogenerated', then: sidebarItemAutogeneratedSchema }, { is: 'category', then: sidebarItemCategorySchema }, { is: utils_validation_1.Joi.any().required(), then: utils_validation_1.Joi.forbidden().messages({ 'any.unknown': 'Unknown sidebar item type "{.type}".', }), }, ], }); // .id('sidebarItemSchema'); function validateSidebarItem(item) { // TODO: remove once with proper Joi support // Because we can't use Joi to validate nested items (see above), we do it // manually utils_validation_1.Joi.assert(item, sidebarItemSchema); if (item.type === 'category') { item.items.forEach(validateSidebarItem); } } function validateSidebars(sidebars) { Object.values(sidebars).forEach((sidebar) => { sidebar.forEach(validateSidebarItem); }); } exports.validateSidebars = validateSidebars; const categoryMetadataFileSchema = utils_validation_1.Joi.object({ label: utils_validation_1.Joi.string(), position: utils_validation_1.Joi.number(), collapsed: utils_validation_1.Joi.boolean(), collapsible: utils_validation_1.Joi.boolean(), className: utils_validation_1.Joi.string(), link: sidebarItemCategoryLinkSchema, customProps: utils_validation_1.Joi.object().unknown(), }); function validateCategoryMetadataFile(unsafeContent) { const { error, value } = categoryMetadataFileSchema.validate(unsafeContent); if (error) { throw error; } return value; } exports.validateCategoryMetadataFile = validateCategoryMetadataFile;