librechat-data-provider 0.7.69 → 0.7.72

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.
package/src/zod.spec.ts CHANGED
@@ -13,8 +13,8 @@ describe('convertJsonSchemaToZod', () => {
13
13
  };
14
14
  const zodSchema = convertJsonSchemaToZod(schema);
15
15
 
16
- expect(zodSchema.parse('test')).toBe('test');
17
- expect(() => zodSchema.parse(123)).toThrow();
16
+ expect(zodSchema?.parse('test')).toBe('test');
17
+ expect(() => zodSchema?.parse(123)).toThrow();
18
18
  });
19
19
 
20
20
  it('should convert string enum schema', () => {
@@ -24,8 +24,8 @@ describe('convertJsonSchemaToZod', () => {
24
24
  };
25
25
  const zodSchema = convertJsonSchemaToZod(schema);
26
26
 
27
- expect(zodSchema.parse('foo')).toBe('foo');
28
- expect(() => zodSchema.parse('invalid')).toThrow();
27
+ expect(zodSchema?.parse('foo')).toBe('foo');
28
+ expect(() => zodSchema?.parse('invalid')).toThrow();
29
29
  });
30
30
 
31
31
  it('should convert number schema', () => {
@@ -34,8 +34,8 @@ describe('convertJsonSchemaToZod', () => {
34
34
  };
35
35
  const zodSchema = convertJsonSchemaToZod(schema);
36
36
 
37
- expect(zodSchema.parse(123)).toBe(123);
38
- expect(() => zodSchema.parse('123')).toThrow();
37
+ expect(zodSchema?.parse(123)).toBe(123);
38
+ expect(() => zodSchema?.parse('123')).toThrow();
39
39
  });
40
40
 
41
41
  it('should convert boolean schema', () => {
@@ -44,8 +44,8 @@ describe('convertJsonSchemaToZod', () => {
44
44
  };
45
45
  const zodSchema = convertJsonSchemaToZod(schema);
46
46
 
47
- expect(zodSchema.parse(true)).toBe(true);
48
- expect(() => zodSchema.parse('true')).toThrow();
47
+ expect(zodSchema?.parse(true)).toBe(true);
48
+ expect(() => zodSchema?.parse('true')).toThrow();
49
49
  });
50
50
  });
51
51
 
@@ -57,8 +57,8 @@ describe('convertJsonSchemaToZod', () => {
57
57
  };
58
58
  const zodSchema = convertJsonSchemaToZod(schema);
59
59
 
60
- expect(zodSchema.parse(['a', 'b', 'c'])).toEqual(['a', 'b', 'c']);
61
- expect(() => zodSchema.parse(['a', 123, 'c'])).toThrow();
60
+ expect(zodSchema?.parse(['a', 'b', 'c'])).toEqual(['a', 'b', 'c']);
61
+ expect(() => zodSchema?.parse(['a', 123, 'c'])).toThrow();
62
62
  });
63
63
 
64
64
  it('should convert array of numbers schema', () => {
@@ -68,8 +68,8 @@ describe('convertJsonSchemaToZod', () => {
68
68
  };
69
69
  const zodSchema = convertJsonSchemaToZod(schema);
70
70
 
71
- expect(zodSchema.parse([1, 2, 3])).toEqual([1, 2, 3]);
72
- expect(() => zodSchema.parse([1, '2', 3])).toThrow();
71
+ expect(zodSchema?.parse([1, 2, 3])).toEqual([1, 2, 3]);
72
+ expect(() => zodSchema?.parse([1, '2', 3])).toThrow();
73
73
  });
74
74
  });
75
75
 
@@ -84,8 +84,8 @@ describe('convertJsonSchemaToZod', () => {
84
84
  };
85
85
  const zodSchema = convertJsonSchemaToZod(schema);
86
86
 
87
- expect(zodSchema.parse({ name: 'John', age: 30 })).toEqual({ name: 'John', age: 30 });
88
- expect(() => zodSchema.parse({ name: 123, age: 30 })).toThrow();
87
+ expect(zodSchema?.parse({ name: 'John', age: 30 })).toEqual({ name: 'John', age: 30 });
88
+ expect(() => zodSchema?.parse({ name: 123, age: 30 })).toThrow();
89
89
  });
90
90
 
91
91
  it('should handle required fields', () => {
@@ -99,8 +99,8 @@ describe('convertJsonSchemaToZod', () => {
99
99
  };
100
100
  const zodSchema = convertJsonSchemaToZod(schema);
101
101
 
102
- expect(zodSchema.parse({ name: 'John' })).toEqual({ name: 'John' });
103
- expect(() => zodSchema.parse({})).toThrow();
102
+ expect(zodSchema?.parse({ name: 'John' })).toEqual({ name: 'John' });
103
+ expect(() => zodSchema?.parse({})).toThrow();
104
104
  });
105
105
 
106
106
  it('should handle nested objects', () => {
@@ -120,10 +120,10 @@ describe('convertJsonSchemaToZod', () => {
120
120
  };
121
121
  const zodSchema = convertJsonSchemaToZod(schema);
122
122
 
123
- expect(zodSchema.parse({ user: { name: 'John', age: 30 } })).toEqual({
123
+ expect(zodSchema?.parse({ user: { name: 'John', age: 30 } })).toEqual({
124
124
  user: { name: 'John', age: 30 },
125
125
  });
126
- expect(() => zodSchema.parse({ user: { age: 30 } })).toThrow();
126
+ expect(() => zodSchema?.parse({ user: { age: 30 } })).toThrow();
127
127
  });
128
128
 
129
129
  it('should handle objects with arrays', () => {
@@ -138,8 +138,8 @@ describe('convertJsonSchemaToZod', () => {
138
138
  };
139
139
  const zodSchema = convertJsonSchemaToZod(schema);
140
140
 
141
- expect(zodSchema.parse({ names: ['John', 'Jane'] })).toEqual({ names: ['John', 'Jane'] });
142
- expect(() => zodSchema.parse({ names: ['John', 123] })).toThrow();
141
+ expect(zodSchema?.parse({ names: ['John', 'Jane'] })).toEqual({ names: ['John', 'Jane'] });
142
+ expect(() => zodSchema?.parse({ names: ['John', 123] })).toThrow();
143
143
  });
144
144
  });
145
145
 
@@ -151,7 +151,7 @@ describe('convertJsonSchemaToZod', () => {
151
151
  };
152
152
  const zodSchema = convertJsonSchemaToZod(schema);
153
153
 
154
- expect(zodSchema.parse({})).toEqual({});
154
+ expect(zodSchema?.parse({})).toEqual({});
155
155
  });
156
156
 
157
157
  it('should handle unknown types as unknown', () => {
@@ -160,8 +160,8 @@ describe('convertJsonSchemaToZod', () => {
160
160
  } as unknown as JsonSchemaType;
161
161
  const zodSchema = convertJsonSchemaToZod(schema);
162
162
 
163
- expect(zodSchema.parse('anything')).toBe('anything');
164
- expect(zodSchema.parse(123)).toBe(123);
163
+ expect(zodSchema?.parse('anything')).toBe('anything');
164
+ expect(zodSchema?.parse(123)).toBe(123);
165
165
  });
166
166
 
167
167
  it('should handle empty enum arrays as regular strings', () => {
@@ -171,7 +171,7 @@ describe('convertJsonSchemaToZod', () => {
171
171
  };
172
172
  const zodSchema = convertJsonSchemaToZod(schema);
173
173
 
174
- expect(zodSchema.parse('test')).toBe('test');
174
+ expect(zodSchema?.parse('test')).toBe('test');
175
175
  });
176
176
  });
177
177
 
@@ -223,6 +223,9 @@ describe('convertJsonSchemaToZod', () => {
223
223
  ],
224
224
  },
225
225
  };
226
+ if (zodSchema == null) {
227
+ throw new Error('Zod schema is null');
228
+ }
226
229
 
227
230
  expect(zodSchema.parse(validData)).toEqual(validData);
228
231
  expect(() =>
@@ -253,7 +256,7 @@ describe('convertJsonSchemaToZod', () => {
253
256
  },
254
257
  };
255
258
  const zodSchema = convertJsonSchemaToZod(schema);
256
- expect(zodSchema.description).toBe('A test schema description');
259
+ expect(zodSchema?.description).toBe('A test schema description');
257
260
  });
258
261
 
259
262
  it('should preserve field descriptions', () => {
@@ -309,7 +312,7 @@ describe('convertJsonSchemaToZod', () => {
309
312
 
310
313
  // Type assertions for better type safety
311
314
  const shape = zodSchema instanceof z.ZodObject ? zodSchema.shape : {};
312
- expect(zodSchema.description).toBe('User record');
315
+ expect(zodSchema?.description).toBe('User record');
313
316
 
314
317
  if ('user' in shape) {
315
318
  expect(shape.user.description).toBe('User details');
@@ -436,7 +439,7 @@ describe('convertJsonSchemaToZod', () => {
436
439
  const zodSchema = convertJsonSchemaToZod(schema);
437
440
 
438
441
  // Test top-level description
439
- expect(zodSchema.description).toBe('User profile configuration');
442
+ expect(zodSchema?.description).toBe('User profile configuration');
440
443
 
441
444
  const shape = zodSchema instanceof z.ZodObject ? zodSchema.shape : {};
442
445
 
@@ -464,4 +467,60 @@ describe('convertJsonSchemaToZod', () => {
464
467
  }
465
468
  });
466
469
  });
470
+
471
+ describe('empty object handling', () => {
472
+ it('should return undefined for empty object schemas when allowEmptyObject is false', () => {
473
+ const emptyObjectSchemas = [
474
+ { type: 'object' as const },
475
+ { type: 'object' as const, properties: {} },
476
+ ];
477
+
478
+ emptyObjectSchemas.forEach((schema) => {
479
+ expect(convertJsonSchemaToZod(schema, { allowEmptyObject: false })).toBeUndefined();
480
+ });
481
+ });
482
+
483
+ it('should return zod schema for empty object schemas when allowEmptyObject is true', () => {
484
+ const emptyObjectSchemas = [
485
+ { type: 'object' as const },
486
+ { type: 'object' as const, properties: {} },
487
+ ];
488
+
489
+ emptyObjectSchemas.forEach((schema) => {
490
+ const result = convertJsonSchemaToZod(schema, { allowEmptyObject: true });
491
+ expect(result).toBeDefined();
492
+ expect(result instanceof z.ZodObject).toBeTruthy();
493
+ });
494
+ });
495
+
496
+ it('should return zod schema for empty object schemas by default', () => {
497
+ const emptyObjectSchemas = [
498
+ { type: 'object' as const },
499
+ { type: 'object' as const, properties: {} },
500
+ ];
501
+
502
+ emptyObjectSchemas.forEach((schema) => {
503
+ const result = convertJsonSchemaToZod(schema);
504
+ expect(result).toBeDefined();
505
+ expect(result instanceof z.ZodObject).toBeTruthy();
506
+ });
507
+ });
508
+
509
+ it('should still convert non-empty object schemas regardless of allowEmptyObject setting', () => {
510
+ const schema: JsonSchemaType = {
511
+ type: 'object',
512
+ properties: {
513
+ name: { type: 'string' },
514
+ },
515
+ };
516
+
517
+ const resultWithFlag = convertJsonSchemaToZod(schema, { allowEmptyObject: false });
518
+ const resultWithoutFlag = convertJsonSchemaToZod(schema);
519
+
520
+ expect(resultWithFlag).toBeDefined();
521
+ expect(resultWithoutFlag).toBeDefined();
522
+ expect(resultWithFlag instanceof z.ZodObject).toBeTruthy();
523
+ expect(resultWithoutFlag instanceof z.ZodObject).toBeTruthy();
524
+ });
525
+ });
467
526
  });
package/src/zod.ts CHANGED
@@ -9,7 +9,24 @@ export type JsonSchemaType = {
9
9
  description?: string;
10
10
  };
11
11
 
12
- export function convertJsonSchemaToZod(schema: JsonSchemaType): z.ZodType {
12
+ function isEmptyObjectSchema(jsonSchema?: JsonSchemaType): boolean {
13
+ return (
14
+ jsonSchema != null &&
15
+ typeof jsonSchema === 'object' &&
16
+ jsonSchema.type === 'object' &&
17
+ (jsonSchema.properties == null || Object.keys(jsonSchema.properties).length === 0)
18
+ );
19
+ }
20
+
21
+ export function convertJsonSchemaToZod(
22
+ schema: JsonSchemaType,
23
+ options: { allowEmptyObject?: boolean } = {},
24
+ ): z.ZodType | undefined {
25
+ const { allowEmptyObject = true } = options;
26
+ if (!allowEmptyObject && isEmptyObjectSchema(schema)) {
27
+ return undefined;
28
+ }
29
+
13
30
  let zodSchema: z.ZodType;
14
31
 
15
32
  // Handle primitive types
@@ -26,13 +43,16 @@ export function convertJsonSchemaToZod(schema: JsonSchemaType): z.ZodType {
26
43
  zodSchema = z.boolean();
27
44
  } else if (schema.type === 'array' && schema.items !== undefined) {
28
45
  const itemSchema = convertJsonSchemaToZod(schema.items);
29
- zodSchema = z.array(itemSchema);
46
+ zodSchema = z.array(itemSchema as z.ZodType);
30
47
  } else if (schema.type === 'object') {
31
48
  const shape: Record<string, z.ZodType> = {};
32
49
  const properties = schema.properties ?? {};
33
50
 
34
51
  for (const [key, value] of Object.entries(properties)) {
35
52
  let fieldSchema = convertJsonSchemaToZod(value);
53
+ if (!fieldSchema) {
54
+ continue;
55
+ }
36
56
  if (value.description != null && value.description !== '') {
37
57
  fieldSchema = fieldSchema.describe(value.description);
38
58
  }
package/tsconfig.json CHANGED
@@ -18,9 +18,8 @@
18
18
  "isolatedModules": true,
19
19
  "noEmit": true,
20
20
  "sourceMap": true,
21
- "baseUrl": ".", // This should be the root of your package
21
+ "baseUrl": ".",
22
22
  "paths": {
23
- // Add path mappings
24
23
  "librechat-data-provider/react-query": ["./src/react-query/index.ts"]
25
24
  }
26
25
  },
@@ -1,48 +0,0 @@
1
- import { extractEnvVariable } from '../src/parsers';
2
-
3
- describe('extractEnvVariable', () => {
4
- const originalEnv = process.env;
5
-
6
- beforeEach(() => {
7
- jest.resetModules();
8
- process.env = { ...originalEnv };
9
- });
10
-
11
- afterAll(() => {
12
- process.env = originalEnv;
13
- });
14
-
15
- test('should return the value of the environment variable', () => {
16
- process.env.TEST_VAR = 'test_value';
17
- expect(extractEnvVariable('${TEST_VAR}')).toBe('test_value');
18
- });
19
-
20
- test('should return the original string if the envrionment variable is not defined correctly', () => {
21
- process.env.TEST_VAR = 'test_value';
22
- expect(extractEnvVariable('${ TEST_VAR }')).toBe('${ TEST_VAR }');
23
- });
24
-
25
- test('should return the original string if environment variable is not set', () => {
26
- expect(extractEnvVariable('${NON_EXISTENT_VAR}')).toBe('${NON_EXISTENT_VAR}');
27
- });
28
-
29
- test('should return the original string if it does not contain an environment variable', () => {
30
- expect(extractEnvVariable('some_string')).toBe('some_string');
31
- });
32
-
33
- test('should handle empty strings', () => {
34
- expect(extractEnvVariable('')).toBe('');
35
- });
36
-
37
- test('should handle strings without variable format', () => {
38
- expect(extractEnvVariable('no_var_here')).toBe('no_var_here');
39
- });
40
-
41
- test('should not process multiple variable formats', () => {
42
- process.env.FIRST_VAR = 'first';
43
- process.env.SECOND_VAR = 'second';
44
- expect(extractEnvVariable('${FIRST_VAR} and ${SECOND_VAR}')).toBe(
45
- '${FIRST_VAR} and ${SECOND_VAR}',
46
- );
47
- });
48
- });