mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-04-05 23:37:19 +02:00
🧹 chore: Clean Up Config Fields (#12537)
* chore: remove unused `interface.endpointsMenu` config field * chore: address review — restore JSDoc UI-only example, add Zod strip test * chore: remove unused `interface.sidePanel` config field * chore: restrict fileStrategy/fileStrategies schema to valid storage backends * fix: use valid FileStorage value in AppService test * chore: address review — version bump, exhaustiveness guard, JSDoc, configSchema test * chore: remove debug logger.log from MessageIcon render path * fix: rewrite MessageIcon render tests to use render counting instead of logger spying * chore: bump librechat-data-provider to 0.8.407 * chore: sync example YAML version to 1.3.7
This commit is contained in:
parent
b4d97bd888
commit
ea28dbfa89
17 changed files with 211 additions and 190 deletions
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "librechat-data-provider",
|
||||
"version": "0.8.406",
|
||||
"version": "0.8.407",
|
||||
"description": "data services for librechat apps",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.es.js",
|
||||
|
|
|
|||
|
|
@ -4,8 +4,12 @@ import {
|
|||
azureEndpointSchema,
|
||||
endpointSchema,
|
||||
configSchema,
|
||||
interfaceSchema,
|
||||
fileStorageSchema,
|
||||
fileStrategiesSchema,
|
||||
} from '../src/config';
|
||||
import { tModelSpecPresetSchema, EModelEndpoint } from '../src/schemas';
|
||||
import { FileSources } from '../src/types/files';
|
||||
|
||||
describe('paramDefinitionSchema', () => {
|
||||
it('accepts a minimal definition with only key', () => {
|
||||
|
|
@ -421,3 +425,80 @@ describe('azureEndpointSchema', () => {
|
|||
expect(result.success).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fileStorageSchema', () => {
|
||||
const validStrategies = [
|
||||
FileSources.local,
|
||||
FileSources.firebase,
|
||||
FileSources.s3,
|
||||
FileSources.azure_blob,
|
||||
];
|
||||
const invalidStrategies = [
|
||||
FileSources.openai,
|
||||
FileSources.azure,
|
||||
FileSources.vectordb,
|
||||
FileSources.execute_code,
|
||||
FileSources.mistral_ocr,
|
||||
FileSources.azure_mistral_ocr,
|
||||
FileSources.vertexai_mistral_ocr,
|
||||
FileSources.text,
|
||||
FileSources.document_parser,
|
||||
];
|
||||
|
||||
for (const strategy of validStrategies) {
|
||||
it(`accepts storage strategy "${strategy}"`, () => {
|
||||
expect(fileStorageSchema.safeParse(strategy).success).toBe(true);
|
||||
});
|
||||
}
|
||||
|
||||
for (const strategy of invalidStrategies) {
|
||||
it(`rejects processing strategy "${strategy}"`, () => {
|
||||
expect(fileStorageSchema.safeParse(strategy).success).toBe(false);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('fileStrategiesSchema', () => {
|
||||
it('accepts valid storage strategies for all sub-fields', () => {
|
||||
const result = fileStrategiesSchema.safeParse({
|
||||
default: FileSources.s3,
|
||||
avatar: FileSources.local,
|
||||
image: FileSources.firebase,
|
||||
document: FileSources.azure_blob,
|
||||
});
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
it('rejects processing strategies in sub-fields', () => {
|
||||
const result = fileStrategiesSchema.safeParse({
|
||||
default: FileSources.vectordb,
|
||||
});
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('configSchema fileStrategy', () => {
|
||||
it('rejects a processing strategy as fileStrategy', () => {
|
||||
const result = configSchema.safeParse({ version: '1.3.7', fileStrategy: FileSources.vectordb });
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
it('defaults fileStrategy to local when absent', () => {
|
||||
const result = configSchema.safeParse({ version: '1.3.7' });
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.data?.fileStrategy).toBe(FileSources.local);
|
||||
});
|
||||
});
|
||||
|
||||
describe('interfaceSchema', () => {
|
||||
it('silently strips removed legacy fields', () => {
|
||||
const result = interfaceSchema.parse({
|
||||
endpointsMenu: true,
|
||||
sidePanel: true,
|
||||
modelSelect: false,
|
||||
});
|
||||
expect(result).not.toHaveProperty('endpointsMenu');
|
||||
expect(result).not.toHaveProperty('sidePanel');
|
||||
expect(result.modelSelect).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -62,14 +62,27 @@ export enum SettingsViews {
|
|||
advanced = 'advanced',
|
||||
}
|
||||
|
||||
/** Validates any FileSources value — use for file metadata, DB records, and upload routing. */
|
||||
export const fileSourceSchema = z.nativeEnum(FileSources);
|
||||
|
||||
/** Storage backend strategies only — use for config fields that set where files are stored. */
|
||||
const FILE_STORAGE_BACKENDS = [
|
||||
FileSources.local,
|
||||
FileSources.firebase,
|
||||
FileSources.s3,
|
||||
FileSources.azure_blob,
|
||||
] as const satisfies ReadonlyArray<FileSources>;
|
||||
|
||||
export const fileStorageSchema = z.enum(FILE_STORAGE_BACKENDS);
|
||||
|
||||
export type FileStorage = z.infer<typeof fileStorageSchema>;
|
||||
|
||||
export const fileStrategiesSchema = z
|
||||
.object({
|
||||
default: fileSourceSchema.optional(),
|
||||
avatar: fileSourceSchema.optional(),
|
||||
image: fileSourceSchema.optional(),
|
||||
document: fileSourceSchema.optional(),
|
||||
default: fileStorageSchema.optional(),
|
||||
avatar: fileStorageSchema.optional(),
|
||||
image: fileStorageSchema.optional(),
|
||||
document: fileStorageSchema.optional(),
|
||||
})
|
||||
.optional();
|
||||
|
||||
|
|
@ -677,10 +690,8 @@ export const interfaceSchema = z
|
|||
termsOfService: termsOfServiceSchema.optional(),
|
||||
customWelcome: z.string().optional(),
|
||||
mcpServers: mcpServersSchema.optional(),
|
||||
endpointsMenu: z.boolean().optional(),
|
||||
modelSelect: z.boolean().optional(),
|
||||
parameters: z.boolean().optional(),
|
||||
sidePanel: z.boolean().optional(),
|
||||
multiConvo: z.boolean().optional(),
|
||||
bookmarks: z.boolean().optional(),
|
||||
memories: z.boolean().optional(),
|
||||
|
|
@ -735,10 +746,8 @@ export const interfaceSchema = z
|
|||
.optional(),
|
||||
})
|
||||
.default({
|
||||
endpointsMenu: true,
|
||||
modelSelect: true,
|
||||
parameters: true,
|
||||
sidePanel: true,
|
||||
presets: true,
|
||||
multiConvo: true,
|
||||
bookmarks: true,
|
||||
|
|
@ -1059,7 +1068,7 @@ export const configSchema = z.object({
|
|||
.optional(),
|
||||
interface: interfaceSchema,
|
||||
turnstile: turnstileSchema.optional(),
|
||||
fileStrategy: fileSourceSchema.default(FileSources.local),
|
||||
fileStrategy: fileStorageSchema.default(FileSources.local),
|
||||
fileStrategies: fileStrategiesSchema,
|
||||
actions: z
|
||||
.object({
|
||||
|
|
@ -1833,7 +1842,7 @@ export enum Constants {
|
|||
/** Key for the app's version. */
|
||||
VERSION = 'v0.8.4',
|
||||
/** Key for the Custom Config's version (librechat.yaml). */
|
||||
CONFIG_VERSION = '1.3.6',
|
||||
CONFIG_VERSION = '1.3.7',
|
||||
/** Standard value for the first message's `parentMessageId` value, to indicate no parent exists. */
|
||||
NO_PARENT = '00000000-0000-0000-0000-000000000000',
|
||||
/** Standard value to use whatever the submission prelim. `responseMessageId` is */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue