fix(theme-search-algolia): Fix Algolia AskAI validation logic (#11468)
Some checks failed
Argos CI / take-screenshots (push) Waiting to run
Build Hash Router / Build Hash Router (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
Continuous Releases / Continuous Releases (push) Waiting to run
Canary Release / Publish Canary (push) Has been cancelled
E2E Tests / E2E — Yarn v1 (20) (push) Has been cancelled
E2E Tests / E2E — Yarn v1 (20.0) (push) Has been cancelled
E2E Tests / E2E — Yarn v1 (22) (push) Has been cancelled
E2E Tests / E2E — Yarn v1 (24) (push) Has been cancelled
E2E Tests / E2E — Yarn v1 Windows (push) Has been cancelled
E2E Tests / E2E — Yarn Berry (node-modules, -s) (push) Has been cancelled
E2E Tests / E2E — Yarn Berry (node-modules, -st) (push) Has been cancelled
E2E Tests / E2E — Yarn Berry (pnp, -s) (push) Has been cancelled
E2E Tests / E2E — Yarn Berry (pnp, -st) (push) Has been cancelled
E2E Tests / E2E — npm (push) Has been cancelled
E2E Tests / E2E — pnpm (push) Has been cancelled

This commit is contained in:
Sébastien Lorber 2025-10-13 18:57:09 +02:00 committed by GitHub
parent 43665c5f08
commit 19ea360fd5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 47 additions and 17 deletions

View File

@ -229,10 +229,33 @@ describe('validateThemeConfig', () => {
...DEFAULT_CONFIG,
...algolia,
askAi: {
indexName: 'index',
apiKey: 'apiKey',
appId: 'BH4D9OD16A',
assistantId: 'my-assistant-id',
indexName: algolia.indexName,
apiKey: algolia.apiKey,
appId: algolia.appId,
},
},
});
});
it('accepts minimal object format', () => {
const algolia: AlgoliaInput = {
appId: 'BH4D9OD16A',
indexName: 'index',
apiKey: 'apiKey',
askAi: {
assistantId: 'my-assistant-id',
},
};
expect(testValidateThemeConfig(algolia)).toEqual({
algolia: {
...DEFAULT_CONFIG,
...algolia,
askAi: {
assistantId: 'my-assistant-id',
indexName: algolia.indexName,
apiKey: algolia.apiKey,
appId: algolia.appId,
},
},
});
@ -273,21 +296,18 @@ describe('validateThemeConfig', () => {
);
});
it('rejects object missing required fields', () => {
it('rejects empty askAi', () => {
const algolia: AlgoliaInput = {
appId: 'BH4D9OD16A',
indexName: 'index',
apiKey: 'apiKey',
// @ts-expect-error: expected type error: missing mandatory fields
askAi: {
assistantId: 'my-assistant-id',
// Missing indexName, apiKey, appId
},
askAi: {},
};
expect(() =>
testValidateThemeConfig(algolia),
).toThrowErrorMatchingInlineSnapshot(
`""algolia.askAi.indexName" is required"`,
`""algolia.askAi.assistantId" is required"`,
);
});

View File

@ -11,7 +11,7 @@ declare module '@docsearch/react/useDocSearchKeyboardEvents';
declare module '@docsearch/react/version';
declare module '@docusaurus/theme-search-algolia' {
import type {DeepPartial, Overwrite} from 'utility-types';
import type {DeepPartial, Overwrite, Optional} from 'utility-types';
import type {DocSearchProps} from '@docsearch/react';
import type {FacetFilters} from 'algoliasearch/lite';
@ -70,7 +70,9 @@ declare module '@docusaurus/theme-search-algolia' {
apiKey: ThemeConfigAlgolia['apiKey'];
indexName: ThemeConfigAlgolia['indexName'];
// askAi also accepts a shorter string form
askAi?: string | AskAiConfig;
askAi?:
| string
| Optional<AskAiConfig, 'indexName' | 'appId' | 'apiKey'>;
}
>;
};

View File

@ -67,10 +67,11 @@ export const Schema = Joi.object<ThemeConfig>({
Joi.string(),
// Full configuration object
Joi.object({
indexName: Joi.string().required(),
apiKey: Joi.string().required(),
appId: Joi.string().required(),
assistantId: Joi.string().required(),
// Optional Ask AI configuration
indexName: Joi.string().optional(),
apiKey: Joi.string().optional(),
appId: Joi.string().optional(),
searchParameters: Joi.object({
facetFilters: FacetFiltersSchema.optional(),
}).optional(),
@ -102,6 +103,10 @@ export const Schema = Joi.object<ThemeConfig>({
} satisfies ThemeConfigAlgolia['askAi'];
}
// Fill in missing fields with the top-level Algolia config
askAiInput.indexName = askAiInput.indexName ?? algolia.indexName;
askAiInput.apiKey = askAiInput.apiKey ?? algolia.apiKey;
askAiInput.appId = askAiInput.appId ?? algolia.appId;
if (
askAiInput.searchParameters?.facetFilters === undefined &&
algoliaFacetFilters
@ -109,6 +114,7 @@ export const Schema = Joi.object<ThemeConfig>({
askAiInput.searchParameters = askAiInput.searchParameters ?? {};
askAiInput.searchParameters.facetFilters = algoliaFacetFilters;
}
return askAiInput;
},
)

View File

@ -662,9 +662,11 @@ export default async function createConfigAsync() {
// eslint-disable-next-line @typescript-eslint/no-var-requires,global-require
...(require('@docsearch/react').version.startsWith('4.')
? {
// cSpell:ignore IMYF
askAi: 'RgIMYFUmTfrN',
// indexName: 'docusaurus-markdown',
askAi: {
// cSpell:ignore IMYF
assistantId: 'RgIMYFUmTfrN',
indexName: 'docusaurus-markdown',
},
}
: {}),