librechat-data-provider 0.7.86 → 0.7.87

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,6 +16,10 @@ export enum PermissionTypes {
16
16
  * Type for Agent Permissions
17
17
  */
18
18
  AGENTS = 'AGENTS',
19
+ /**
20
+ * Type for Memory Permissions
21
+ */
22
+ MEMORIES = 'MEMORIES',
19
23
  /**
20
24
  * Type for Multi-Conversation Permissions
21
25
  */
@@ -45,6 +49,8 @@ export enum Permissions {
45
49
  READ = 'READ',
46
50
  READ_AUTHOR = 'READ_AUTHOR',
47
51
  SHARE = 'SHARE',
52
+ /** Can disable if desired */
53
+ OPT_OUT = 'OPT_OUT',
48
54
  }
49
55
 
50
56
  export const promptPermissionsSchema = z.object({
@@ -60,6 +66,15 @@ export const bookmarkPermissionsSchema = z.object({
60
66
  });
61
67
  export type TBookmarkPermissions = z.infer<typeof bookmarkPermissionsSchema>;
62
68
 
69
+ export const memoryPermissionsSchema = z.object({
70
+ [Permissions.USE]: z.boolean().default(true),
71
+ [Permissions.CREATE]: z.boolean().default(true),
72
+ [Permissions.UPDATE]: z.boolean().default(true),
73
+ [Permissions.READ]: z.boolean().default(true),
74
+ [Permissions.OPT_OUT]: z.boolean().default(true),
75
+ });
76
+ export type TMemoryPermissions = z.infer<typeof memoryPermissionsSchema>;
77
+
63
78
  export const agentPermissionsSchema = z.object({
64
79
  [Permissions.SHARED_GLOBAL]: z.boolean().default(false),
65
80
  [Permissions.USE]: z.boolean().default(true),
@@ -92,6 +107,7 @@ export type TWebSearchPermissions = z.infer<typeof webSearchPermissionsSchema>;
92
107
  export const permissionsSchema = z.object({
93
108
  [PermissionTypes.PROMPTS]: promptPermissionsSchema,
94
109
  [PermissionTypes.BOOKMARKS]: bookmarkPermissionsSchema,
110
+ [PermissionTypes.MEMORIES]: memoryPermissionsSchema,
95
111
  [PermissionTypes.AGENTS]: agentPermissionsSchema,
96
112
  [PermissionTypes.MULTI_CONVO]: multiConvoPermissionsSchema,
97
113
  [PermissionTypes.TEMPORARY_CHAT]: temporaryChatPermissionsSchema,
@@ -347,3 +347,19 @@ export const useGetCustomConfigSpeechQuery = (
347
347
  },
348
348
  );
349
349
  };
350
+
351
+ export const useUpdateFeedbackMutation = (
352
+ conversationId: string,
353
+ messageId: string,
354
+ ): UseMutationResult<t.TUpdateFeedbackResponse, Error, t.TUpdateFeedbackRequest> => {
355
+ const queryClient = useQueryClient();
356
+ return useMutation(
357
+ (payload: t.TUpdateFeedbackRequest) =>
358
+ dataService.updateFeedback(conversationId, messageId, payload),
359
+ {
360
+ onSuccess: () => {
361
+ queryClient.invalidateQueries([QueryKeys.messages, messageId]);
362
+ },
363
+ },
364
+ );
365
+ };
package/src/roles.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  permissionsSchema,
6
6
  agentPermissionsSchema,
7
7
  promptPermissionsSchema,
8
+ memoryPermissionsSchema,
8
9
  runCodePermissionsSchema,
9
10
  webSearchPermissionsSchema,
10
11
  bookmarkPermissionsSchema,
@@ -48,6 +49,13 @@ const defaultRolesSchema = z.object({
48
49
  [PermissionTypes.BOOKMARKS]: bookmarkPermissionsSchema.extend({
49
50
  [Permissions.USE]: z.boolean().default(true),
50
51
  }),
52
+ [PermissionTypes.MEMORIES]: memoryPermissionsSchema.extend({
53
+ [Permissions.USE]: z.boolean().default(true),
54
+ [Permissions.CREATE]: z.boolean().default(true),
55
+ [Permissions.UPDATE]: z.boolean().default(true),
56
+ [Permissions.READ]: z.boolean().default(true),
57
+ [Permissions.OPT_OUT]: z.boolean().default(true),
58
+ }),
51
59
  [PermissionTypes.AGENTS]: agentPermissionsSchema.extend({
52
60
  [Permissions.SHARED_GLOBAL]: z.boolean().default(true),
53
61
  [Permissions.USE]: z.boolean().default(true),
@@ -86,6 +94,13 @@ export const roleDefaults = defaultRolesSchema.parse({
86
94
  [PermissionTypes.BOOKMARKS]: {
87
95
  [Permissions.USE]: true,
88
96
  },
97
+ [PermissionTypes.MEMORIES]: {
98
+ [Permissions.USE]: true,
99
+ [Permissions.CREATE]: true,
100
+ [Permissions.UPDATE]: true,
101
+ [Permissions.READ]: true,
102
+ [Permissions.OPT_OUT]: true,
103
+ },
89
104
  [PermissionTypes.AGENTS]: {
90
105
  [Permissions.SHARED_GLOBAL]: true,
91
106
  [Permissions.USE]: true,
@@ -110,6 +125,7 @@ export const roleDefaults = defaultRolesSchema.parse({
110
125
  permissions: {
111
126
  [PermissionTypes.PROMPTS]: {},
112
127
  [PermissionTypes.BOOKMARKS]: {},
128
+ [PermissionTypes.MEMORIES]: {},
113
129
  [PermissionTypes.AGENTS]: {},
114
130
  [PermissionTypes.MULTI_CONVO]: {},
115
131
  [PermissionTypes.TEMPORARY_CHAT]: {},
package/src/schemas.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { Tools } from './types/assistants';
3
3
  import type { TMessageContentParts, FunctionTool, FunctionToolCall } from './types/assistants';
4
+ import { TFeedback, feedbackSchema } from './feedback';
4
5
  import type { SearchResultData } from './types/web';
5
6
  import type { TEphemeralAgent } from './types';
6
7
  import type { TFile } from './types/files';
@@ -518,13 +519,22 @@ export const tMessageSchema = z.object({
518
519
  thread_id: z.string().optional(),
519
520
  /* frontend components */
520
521
  iconURL: z.string().nullable().optional(),
522
+ feedback: feedbackSchema.optional(),
521
523
  });
522
524
 
525
+ export type MemoryArtifact = {
526
+ key: string;
527
+ value?: string;
528
+ tokenCount?: number;
529
+ type: 'update' | 'delete';
530
+ };
531
+
523
532
  export type TAttachmentMetadata = {
524
533
  type?: Tools;
525
534
  messageId: string;
526
535
  toolCallId: string;
527
536
  [Tools.web_search]?: SearchResultData;
537
+ [Tools.memory]?: MemoryArtifact;
528
538
  };
529
539
 
530
540
  export type TAttachment =
@@ -543,6 +553,7 @@ export type TMessage = z.input<typeof tMessageSchema> & {
543
553
  siblingIndex?: number;
544
554
  attachments?: TAttachment[];
545
555
  clientTimestamp?: string;
556
+ feedback?: TFeedback;
546
557
  };
547
558
 
548
559
  export const coerceNumber = z.union([z.number(), z.string()]).transform((val) => {
@@ -22,6 +22,7 @@ export enum Tools {
22
22
  web_search = 'web_search',
23
23
  retrieval = 'retrieval',
24
24
  function = 'function',
25
+ memory = 'memory',
25
26
  }
26
27
 
27
28
  export enum EToolResources {
@@ -278,7 +278,7 @@ export type UpdatePermVars<T> = {
278
278
  };
279
279
 
280
280
  export type UpdatePromptPermVars = UpdatePermVars<p.TPromptPermissions>;
281
-
281
+ export type UpdateMemoryPermVars = UpdatePermVars<p.TMemoryPermissions>;
282
282
  export type UpdateAgentPermVars = UpdatePermVars<p.TAgentPermissions>;
283
283
 
284
284
  export type UpdatePermResponse = r.TRole;
@@ -290,6 +290,13 @@ export type UpdatePromptPermOptions = MutationOptions<
290
290
  types.TError | null | undefined
291
291
  >;
292
292
 
293
+ export type UpdateMemoryPermOptions = MutationOptions<
294
+ UpdatePermResponse,
295
+ UpdateMemoryPermVars,
296
+ unknown,
297
+ types.TError | null | undefined
298
+ >;
299
+
293
300
  export type UpdateAgentPermOptions = MutationOptions<
294
301
  UpdatePermResponse,
295
302
  UpdateAgentPermVars,
@@ -109,3 +109,18 @@ export type VerifyToolAuthResponse = {
109
109
 
110
110
  export type GetToolCallParams = { conversationId: string };
111
111
  export type ToolCallResults = a.ToolCallResult[];
112
+
113
+ /* Memories */
114
+ export type TUserMemory = {
115
+ key: string;
116
+ value: string;
117
+ updated_at: string;
118
+ tokenCount?: number;
119
+ };
120
+
121
+ export type MemoriesResponse = {
122
+ memories: TUserMemory[];
123
+ totalTokens: number;
124
+ tokenLimit: number | null;
125
+ usagePercentage: number | null;
126
+ };
package/src/types.ts CHANGED
@@ -1,16 +1,19 @@
1
1
  import type OpenAI from 'openai';
2
2
  import type { InfiniteData } from '@tanstack/react-query';
3
3
  import type {
4
+ TBanner,
4
5
  TMessage,
5
6
  TResPlugin,
6
- ImageDetail,
7
7
  TSharedLink,
8
8
  TConversation,
9
9
  EModelEndpoint,
10
10
  TConversationTag,
11
- TBanner,
11
+ TAttachment,
12
12
  } from './schemas';
13
- import { SettingDefinition } from './generate';
13
+ import type { SettingDefinition } from './generate';
14
+ import type { TMinimalFeedback } from './feedback';
15
+ import type { Agent } from './types/assistants';
16
+
14
17
  export type TOpenAIMessage = OpenAI.Chat.ChatCompletionMessageParam;
15
18
 
16
19
  export * from './schemas';
@@ -18,28 +21,78 @@ export * from './schemas';
18
21
  export type TMessages = TMessage[];
19
22
 
20
23
  /* TODO: Cleanup EndpointOption types */
21
- export type TEndpointOption = {
22
- spec?: string | null;
23
- iconURL?: string | null;
24
- endpoint: EModelEndpoint;
25
- endpointType?: EModelEndpoint;
24
+ export type TEndpointOption = Pick<
25
+ TConversation,
26
+ // Core conversation fields
27
+ | 'endpoint'
28
+ | 'endpointType'
29
+ | 'model'
30
+ | 'modelLabel'
31
+ | 'chatGptLabel'
32
+ | 'promptPrefix'
33
+ | 'temperature'
34
+ | 'topP'
35
+ | 'topK'
36
+ | 'top_p'
37
+ | 'frequency_penalty'
38
+ | 'presence_penalty'
39
+ | 'maxOutputTokens'
40
+ | 'maxContextTokens'
41
+ | 'max_tokens'
42
+ | 'maxTokens'
43
+ | 'resendFiles'
44
+ | 'imageDetail'
45
+ | 'reasoning_effort'
46
+ | 'instructions'
47
+ | 'additional_instructions'
48
+ | 'append_current_datetime'
49
+ | 'tools'
50
+ | 'stop'
51
+ | 'region'
52
+ | 'additionalModelRequestFields'
53
+ // Anthropic-specific
54
+ | 'promptCache'
55
+ | 'thinking'
56
+ | 'thinkingBudget'
57
+ // Assistant/Agent fields
58
+ | 'assistant_id'
59
+ | 'agent_id'
60
+ // UI/Display fields
61
+ | 'iconURL'
62
+ | 'greeting'
63
+ | 'spec'
64
+ // Artifacts
65
+ | 'artifacts'
66
+ // Files
67
+ | 'file_ids'
68
+ // System field
69
+ | 'system'
70
+ // Google examples
71
+ | 'examples'
72
+ // Context
73
+ | 'context'
74
+ > & {
75
+ // Fields specific to endpoint options that don't exist on TConversation
26
76
  modelDisplayLabel?: string;
27
- resendFiles?: boolean;
28
- promptCache?: boolean;
29
- maxContextTokens?: number;
30
- imageDetail?: ImageDetail;
31
- model?: string | null;
32
- promptPrefix?: string;
33
- temperature?: number;
34
- chatGptLabel?: string | null;
35
- modelLabel?: string | null;
36
- jailbreak?: boolean;
37
77
  key?: string | null;
38
- /* assistant */
78
+ /** @deprecated Assistants API */
39
79
  thread_id?: string;
40
- /* multi-response stream */
80
+ // Conversation identifiers for multi-response streams
41
81
  overrideConvoId?: string;
42
82
  overrideUserMessageId?: string;
83
+ // Model parameters (used by different endpoints)
84
+ modelOptions?: Record<string, unknown>;
85
+ model_parameters?: Record<string, unknown>;
86
+ // Configuration data (added by middleware)
87
+ modelsConfig?: TModelsConfig;
88
+ // File attachments (processed by middleware)
89
+ attachments?: TAttachment[];
90
+ // Generated prompts
91
+ artifactsPrompt?: string;
92
+ // Agent-specific fields
93
+ agent?: Promise<Agent>;
94
+ // Client-specific options
95
+ clientOptions?: Record<string, unknown>;
43
96
  };
44
97
 
45
98
  export type TEphemeralAgent = {
@@ -128,6 +181,9 @@ export type TUser = {
128
181
  plugins?: string[];
129
182
  twoFactorEnabled?: boolean;
130
183
  backupCodes?: TBackupCode[];
184
+ personalization?: {
185
+ memories?: boolean;
186
+ };
131
187
  createdAt: string;
132
188
  updatedAt: string;
133
189
  };
@@ -546,3 +602,23 @@ export type TAcceptTermsResponse = {
546
602
  };
547
603
 
548
604
  export type TBannerResponse = TBanner | null;
605
+
606
+ export type TUpdateFeedbackRequest = {
607
+ feedback?: TMinimalFeedback;
608
+ };
609
+
610
+ export type TUpdateFeedbackResponse = {
611
+ messageId: string;
612
+ conversationId: string;
613
+ feedback?: TMinimalFeedback;
614
+ };
615
+
616
+ export type TBalanceResponse = {
617
+ tokenCredits: number;
618
+ // Automatic refill settings
619
+ autoRefillEnabled: boolean;
620
+ refillIntervalValue?: number;
621
+ refillIntervalUnit?: 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'months';
622
+ lastRefill?: Date;
623
+ refillAmount?: number;
624
+ };
package/src/web.ts CHANGED
@@ -5,8 +5,8 @@ import type {
5
5
  SearchProviders,
6
6
  TWebSearchConfig,
7
7
  } from './config';
8
- import { extractVariableName } from './utils';
9
8
  import { SearchCategories, SafeSearchTypes } from './config';
9
+ import { extractVariableName } from './utils';
10
10
  import { AuthType } from './schemas';
11
11
 
12
12
  export function loadWebSearchConfig(
@@ -64,23 +64,29 @@ export const webSearchAuth = {
64
64
  /**
65
65
  * Extracts all API keys from the webSearchAuth configuration object
66
66
  */
67
- export const webSearchKeys: TWebSearchKeys[] = [];
67
+ export function getWebSearchKeys(): TWebSearchKeys[] {
68
+ const keys: TWebSearchKeys[] = [];
68
69
 
69
- // Iterate through each category (providers, scrapers, rerankers)
70
- for (const category of Object.keys(webSearchAuth)) {
71
- const categoryObj = webSearchAuth[category as TWebSearchCategories];
70
+ // Iterate through each category (providers, scrapers, rerankers)
71
+ for (const category of Object.keys(webSearchAuth)) {
72
+ const categoryObj = webSearchAuth[category as TWebSearchCategories];
72
73
 
73
- // Iterate through each service within the category
74
- for (const service of Object.keys(categoryObj)) {
75
- const serviceObj = categoryObj[service as keyof typeof categoryObj];
74
+ // Iterate through each service within the category
75
+ for (const service of Object.keys(categoryObj)) {
76
+ const serviceObj = categoryObj[service as keyof typeof categoryObj];
76
77
 
77
- // Extract the API keys from the service
78
- for (const key of Object.keys(serviceObj)) {
79
- webSearchKeys.push(key as TWebSearchKeys);
78
+ // Extract the API keys from the service
79
+ for (const key of Object.keys(serviceObj)) {
80
+ keys.push(key as TWebSearchKeys);
81
+ }
80
82
  }
81
83
  }
84
+
85
+ return keys;
82
86
  }
83
87
 
88
+ export const webSearchKeys: TWebSearchKeys[] = getWebSearchKeys();
89
+
84
90
  export function extractWebSearchEnvVars({
85
91
  keys,
86
92
  config,
package/src/zod.spec.ts CHANGED
@@ -264,19 +264,19 @@ describe('convertJsonSchemaToZod', () => {
264
264
  properties: {
265
265
  name: {
266
266
  type: 'string',
267
- description: 'The user\'s name',
267
+ description: "The user's name",
268
268
  },
269
269
  age: {
270
270
  type: 'number',
271
- description: 'The user\'s age',
271
+ description: "The user's age",
272
272
  },
273
273
  },
274
274
  };
275
275
  const zodSchema = convertJsonSchemaToZod(schema);
276
276
 
277
277
  const shape = (zodSchema as z.ZodObject<any>).shape;
278
- expect(shape.name.description).toBe('The user\'s name');
279
- expect(shape.age.description).toBe('The user\'s age');
278
+ expect(shape.name.description).toBe("The user's name");
279
+ expect(shape.age.description).toBe("The user's age");
280
280
  });
281
281
 
282
282
  it('should preserve descriptions in nested objects', () => {
@@ -290,7 +290,7 @@ describe('convertJsonSchemaToZod', () => {
290
290
  properties: {
291
291
  name: {
292
292
  type: 'string',
293
- description: 'The user\'s name',
293
+ description: "The user's name",
294
294
  },
295
295
  settings: {
296
296
  type: 'object',
@@ -318,7 +318,7 @@ describe('convertJsonSchemaToZod', () => {
318
318
 
319
319
  const userShape = shape.user instanceof z.ZodObject ? shape.user.shape : {};
320
320
  if ('name' in userShape && 'settings' in userShape) {
321
- expect(userShape.name.description).toBe('The user\'s name');
321
+ expect(userShape.name.description).toBe("The user's name");
322
322
  expect(userShape.settings.description).toBe('User preferences');
323
323
 
324
324
  const settingsShape =
@@ -682,10 +682,7 @@ describe('convertJsonSchemaToZod', () => {
682
682
  name: { type: 'string' },
683
683
  age: { type: 'number' },
684
684
  },
685
- anyOf: [
686
- { required: ['name'] },
687
- { required: ['age'] },
688
- ],
685
+ anyOf: [{ required: ['name'] }, { required: ['age'] }],
689
686
  oneOf: [
690
687
  { properties: { role: { type: 'string', enum: ['admin'] } } },
691
688
  { properties: { role: { type: 'string', enum: ['user'] } } },
@@ -708,7 +705,7 @@ describe('convertJsonSchemaToZod', () => {
708
705
  it('should drop fields from nested schemas', () => {
709
706
  // Create a schema with nested fields that should be dropped
710
707
  const schema: JsonSchemaType & {
711
- properties?: Record<string, JsonSchemaType & { anyOf?: any; oneOf?: any }>
708
+ properties?: Record<string, JsonSchemaType & { anyOf?: any; oneOf?: any }>;
712
709
  } = {
713
710
  type: 'object',
714
711
  properties: {
@@ -718,10 +715,7 @@ describe('convertJsonSchemaToZod', () => {
718
715
  name: { type: 'string' },
719
716
  role: { type: 'string' },
720
717
  },
721
- anyOf: [
722
- { required: ['name'] },
723
- { required: ['role'] },
724
- ],
718
+ anyOf: [{ required: ['name'] }, { required: ['role'] }],
725
719
  },
726
720
  settings: {
727
721
  type: 'object',
@@ -742,20 +736,24 @@ describe('convertJsonSchemaToZod', () => {
742
736
  });
743
737
 
744
738
  // The schema should still validate normal properties
745
- expect(zodSchema?.parse({
746
- user: { name: 'John', role: 'admin' },
747
- settings: { theme: 'custom' }, // This would fail if oneOf was still present
748
- })).toEqual({
739
+ expect(
740
+ zodSchema?.parse({
741
+ user: { name: 'John', role: 'admin' },
742
+ settings: { theme: 'custom' }, // This would fail if oneOf was still present
743
+ }),
744
+ ).toEqual({
749
745
  user: { name: 'John', role: 'admin' },
750
746
  settings: { theme: 'custom' },
751
747
  });
752
748
 
753
749
  // But the anyOf constraint should be gone from user
754
750
  // (If it was present, this would fail because neither name nor role is required)
755
- expect(zodSchema?.parse({
756
- user: {},
757
- settings: { theme: 'light' },
758
- })).toEqual({
751
+ expect(
752
+ zodSchema?.parse({
753
+ user: {},
754
+ settings: { theme: 'light' },
755
+ }),
756
+ ).toEqual({
759
757
  user: {},
760
758
  settings: { theme: 'light' },
761
759
  });
@@ -803,10 +801,7 @@ describe('convertJsonSchemaToZod', () => {
803
801
  anyOf: [{ minItems: 1 }],
804
802
  },
805
803
  },
806
- oneOf: [
807
- { required: ['name', 'permissions'] },
808
- { required: ['name'] },
809
- ],
804
+ oneOf: [{ required: ['name', 'permissions'] }, { required: ['name'] }],
810
805
  },
811
806
  },
812
807
  },
@@ -871,10 +866,7 @@ describe('convertJsonSchemaToZod', () => {
871
866
  const schema = {
872
867
  type: 'object', // Add a type to satisfy JsonSchemaType
873
868
  properties: {}, // Empty properties
874
- oneOf: [
875
- { type: 'string' },
876
- { type: 'number' },
877
- ],
869
+ oneOf: [{ type: 'string' }, { type: 'number' }],
878
870
  } as JsonSchemaType & { oneOf?: any };
879
871
 
880
872
  // Convert with transformOneOfAnyOf option
@@ -893,10 +885,7 @@ describe('convertJsonSchemaToZod', () => {
893
885
  const schema = {
894
886
  type: 'object', // Add a type to satisfy JsonSchemaType
895
887
  properties: {}, // Empty properties
896
- anyOf: [
897
- { type: 'string' },
898
- { type: 'number' },
899
- ],
888
+ anyOf: [{ type: 'string' }, { type: 'number' }],
900
889
  } as JsonSchemaType & { anyOf?: any };
901
890
 
902
891
  // Convert with transformOneOfAnyOf option
@@ -956,10 +945,7 @@ describe('convertJsonSchemaToZod', () => {
956
945
  properties: {
957
946
  value: { type: 'string' },
958
947
  },
959
- oneOf: [
960
- { required: ['value'] },
961
- { properties: { optional: { type: 'boolean' } } },
962
- ],
948
+ oneOf: [{ required: ['value'] }, { properties: { optional: { type: 'boolean' } } }],
963
949
  } as JsonSchemaType & { oneOf?: any };
964
950
 
965
951
  // Convert with transformOneOfAnyOf option
@@ -1013,9 +999,12 @@ describe('convertJsonSchemaToZod', () => {
1013
999
  },
1014
1000
  },
1015
1001
  } as JsonSchemaType & {
1016
- properties?: Record<string, JsonSchemaType & {
1017
- properties?: Record<string, JsonSchemaType & { oneOf?: any }>
1018
- }>
1002
+ properties?: Record<
1003
+ string,
1004
+ JsonSchemaType & {
1005
+ properties?: Record<string, JsonSchemaType & { oneOf?: any }>;
1006
+ }
1007
+ >;
1019
1008
  };
1020
1009
 
1021
1010
  // Convert with transformOneOfAnyOf option
@@ -1024,14 +1013,16 @@ describe('convertJsonSchemaToZod', () => {
1024
1013
  });
1025
1014
 
1026
1015
  // The schema should validate nested unions
1027
- expect(zodSchema?.parse({
1028
- user: {
1029
- contact: {
1030
- type: 'email',
1031
- email: 'test@example.com',
1016
+ expect(
1017
+ zodSchema?.parse({
1018
+ user: {
1019
+ contact: {
1020
+ type: 'email',
1021
+ email: 'test@example.com',
1022
+ },
1032
1023
  },
1033
- },
1034
- })).toEqual({
1024
+ }),
1025
+ ).toEqual({
1035
1026
  user: {
1036
1027
  contact: {
1037
1028
  type: 'email',
@@ -1040,14 +1031,16 @@ describe('convertJsonSchemaToZod', () => {
1040
1031
  },
1041
1032
  });
1042
1033
 
1043
- expect(zodSchema?.parse({
1044
- user: {
1045
- contact: {
1046
- type: 'phone',
1047
- phone: '123-456-7890',
1034
+ expect(
1035
+ zodSchema?.parse({
1036
+ user: {
1037
+ contact: {
1038
+ type: 'phone',
1039
+ phone: '123-456-7890',
1040
+ },
1048
1041
  },
1049
- },
1050
- })).toEqual({
1042
+ }),
1043
+ ).toEqual({
1051
1044
  user: {
1052
1045
  contact: {
1053
1046
  type: 'phone',
@@ -1057,14 +1050,16 @@ describe('convertJsonSchemaToZod', () => {
1057
1050
  });
1058
1051
 
1059
1052
  // Should reject invalid contact types
1060
- expect(() => zodSchema?.parse({
1061
- user: {
1062
- contact: {
1063
- type: 'email',
1064
- phone: '123-456-7890', // Missing email, has phone instead
1053
+ expect(() =>
1054
+ zodSchema?.parse({
1055
+ user: {
1056
+ contact: {
1057
+ type: 'email',
1058
+ phone: '123-456-7890', // Missing email, has phone instead
1059
+ },
1065
1060
  },
1066
- },
1067
- })).toThrow();
1061
+ }),
1062
+ ).toThrow();
1068
1063
  });
1069
1064
 
1070
1065
  it('should work with dropFields option', () => {
@@ -1072,10 +1067,7 @@ describe('convertJsonSchemaToZod', () => {
1072
1067
  const schema = {
1073
1068
  type: 'object', // Add a type to satisfy JsonSchemaType
1074
1069
  properties: {}, // Empty properties
1075
- oneOf: [
1076
- { type: 'string' },
1077
- { type: 'number' },
1078
- ],
1070
+ oneOf: [{ type: 'string' }, { type: 'number' }],
1079
1071
  deprecated: true, // Field to drop
1080
1072
  } as JsonSchemaType & { oneOf?: any; deprecated?: boolean };
1081
1073