Repository: facebook/docusaurus
File: packages/docusaurus-theme-classic/src/options.ts (TypeScript)

Code before:
    },
  ],
  otherwise: Joi.forbidden().messages({
    'any.unknown': 'Bad navbar item type {.type}',
  }),
});

const DropdownNavbarItemSchema = NavbarItemBaseSchema.append({
  items: Joi.array().items(DropdownSubitemSchema).required(),
});

const DocsVersionDropdownNavbarItemSchema = NavbarItemBaseSchema.append({
  type: Joi.string().equal('docsVersionDropdown').required(),
  docsPluginId: Joi.string(),
  dropdownActiveClassDisabled: Joi.boolean(),
  dropdownItemsBefore: Joi.array().items(DropdownSubitemSchema).default([]),
  dropdownItemsAfter: Joi.array().items(DropdownSubitemSchema).default([]),
  versions: Joi.alternatives().try(
    Joi.array().items(Joi.string().min(1)),
    Joi.object<PropVersionItems>().pattern(
      Joi.string().min(1),
      Joi.object<PropVersionItem>({
        label: Joi.string().min(1),
      }),
    ),
  ),
});

const LocaleDropdownNavbarItemSchema = NavbarItemBaseSchema.append({
  type: Joi.string().equal('localeDropdown').required(),
  dropdownItemsBefore: Joi.array().items(DropdownSubitemSchema).default([]),
  dropdownItemsAfter: Joi.array().items(DropdownSubitemSchema).default([]),
  queryString: Joi.string(),
});

const SearchItemSchema = Joi.object({
  type: Joi.string().equal('search').required(),
  className: Joi.string(),
});

const NavbarItemSchema = Joi.object({
  position: NavbarItemPosition,
}).when('.', {
  switch: [
    {
      is: itemWithType('docsVersion'),
      then: DocsVersionNavbarItemSchema,
    },
    {
      is: itemWithType('dropdown'),
      then: DropdownNavbarItemSchema,

Review comment (suggestion):
can you add some basic tests in `packages/docusaurus-theme-classic/src/__tests__/options.test.ts` ?

We are not covering everything properly but adding tests for Joi schema is good. Joi often has surprisingly weird behaviors.

Code after:
    },
  ],
  otherwise: Joi.forbidden().messages({
    'any.unknown': 'Bad navbar item type {.type}',
  }),
});

const DropdownNavbarItemSchema = NavbarItemBaseSchema.append({
  items: Joi.array().items(DropdownSubitemSchema).required(),
});

const DocsVersionDropdownNavbarItemSchema = NavbarItemBaseSchema.append({
  type: Joi.string().equal('docsVersionDropdown').required(),
  docsPluginId: Joi.string(),
  dropdownActiveClassDisabled: Joi.boolean(),
  dropdownItemsBefore: Joi.array().items(DropdownSubitemSchema).default([]),
  dropdownItemsAfter: Joi.array().items(DropdownSubitemSchema).default([]),
  versions: Joi.alternatives().try(
    Joi.array().items(Joi.string().min(1)).min(1),
    Joi.object<PropVersionItems>()
      .pattern(
        Joi.string().min(1),
        Joi.object<PropVersionItem>({
          label: Joi.string().min(1),
        }),
      )
      .min(1),
  ),
});

const LocaleDropdownNavbarItemSchema = NavbarItemBaseSchema.append({
  type: Joi.string().equal('localeDropdown').required(),
  dropdownItemsBefore: Joi.array().items(DropdownSubitemSchema).default([]),
  dropdownItemsAfter: Joi.array().items(DropdownSubitemSchema).default([]),
  queryString: Joi.string(),
});

const SearchItemSchema = Joi.object({
  type: Joi.string().equal('search').required(),
  className: Joi.string(),
});

const NavbarItemSchema = Joi.object({
  position: NavbarItemPosition,
}).when('.', {
  switch: [
    {
      is: itemWithType('docsVersion'),
      then: DocsVersionNavbarItemSchema,
    },
    {