Skip to content

Commit 6163c34

Browse files
authored
Revert "fix(deps): update dependency zod to v4 (#67)" (#88)
* Revert "fix(deps): update dependency zod to v4 (#67)" This reverts commit f1dc8f1. * lint * lint * try package.json stuff * Revert "try package.json stuff" This reverts commit 1d1bfab.
1 parent 43cad88 commit 6163c34

File tree

8 files changed

+62
-78
lines changed

8 files changed

+62
-78
lines changed

packages/toolbox-core/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/toolbox-core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,6 @@
6666
"dependencies": {
6767
"axios": "^1.9.0",
6868
"google-auth-library": "^10.0.0",
69-
"zod": "^4.0.0"
69+
"zod": "^3.24.4"
7070
}
7171
}

packages/toolbox-core/src/toolbox_core/protocol.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ function buildZodShapeFromParam(param: ParameterSchema): ZodTypeAny {
146146
export function createZodSchemaFromParams(
147147
params: ParameterSchema[],
148148
): ZodObject<ZodRawShape> {
149-
const shape: {[k: string]: ZodTypeAny} = {};
149+
const shape: ZodRawShape = {};
150150
for (const param of params) {
151151
shape[param.name] = buildZodShapeFromParam(param);
152152
}

packages/toolbox-core/src/toolbox_core/tool.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,9 @@ function ToolboxTool(
8787
}
8888

8989
const toolUrl = `${baseUrl}/api/tool/${name}/invoke`;
90-
91-
// Only omit keys that actually exist in the provided schema.
92-
// This handles cases where `paramSchema` is already partial.
93-
// Could be partial due to bound params being used while loading tools.
9490
const boundKeys = Object.keys(boundParams);
95-
const existingSchemaKeys = Object.keys(paramSchema.shape);
96-
const keysToOmit = boundKeys.filter(key => existingSchemaKeys.includes(key));
9791
const userParamSchema = paramSchema.omit(
98-
Object.fromEntries(keysToOmit.map(k => [k, true])),
92+
Object.fromEntries(boundKeys.map(k => [k, true])),
9993
);
10094

10195
const callable = async function (
@@ -122,7 +116,7 @@ function ToolboxTool(
122116
validatedUserArgs = userParamSchema.parse(callArguments);
123117
} catch (error) {
124118
if (error instanceof ZodError) {
125-
const errorMessages = error.issues.map(
119+
const errorMessages = error.errors.map(
126120
e => `${e.path.join('.') || 'payload'}: ${e.message}`,
127121
);
128122
throw new Error(

packages/toolbox-core/test/e2e/test.e2e.ts

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {ToolboxTool} from '../../src/toolbox_core/tool';
1818
import {AxiosError} from 'axios';
1919
import {CustomGlobal} from './types';
2020
import {authTokenGetter} from './utils';
21+
import {ZodOptional, ZodNullable, ZodTypeAny} from 'zod';
2122

2223
describe('ToolboxClient E2E Tests', () => {
2324
let commonToolboxClient: ToolboxClient;
@@ -45,13 +46,13 @@ describe('ToolboxClient E2E Tests', () => {
4546

4647
it('should invoke the getNRowsTool with missing params', async () => {
4748
await expect(getNRowsTool()).rejects.toThrow(
48-
/num_rows: Invalid input: expected string, received undefined/,
49+
/Argument validation failed for tool "get-n-rows":\s*- num_rows: Required/,
4950
);
5051
});
5152

5253
it('should invoke the getNRowsTool with wrong param type', async () => {
5354
await expect(getNRowsTool({num_rows: 2})).rejects.toThrow(
54-
/num_rows: Invalid input: expected string, received number/,
55+
/Argument validation failed for tool "get-n-rows":\s*- num_rows: Expected string, received number/,
5556
);
5657
});
5758
});
@@ -294,7 +295,7 @@ describe('ToolboxClient E2E Tests', () => {
294295
});
295296

296297
it('should fail when a tool with a param requiring auth is run with insufficient auth claims', async () => {
297-
expect.assertions(3); // An AxiosError is expected.
298+
expect.assertions(3); // Adjusted to account for logApiError's console.error
298299

299300
const tool = await commonToolboxClient.loadTool(
300301
'get-row-by-content-auth',
@@ -326,36 +327,28 @@ describe('ToolboxClient E2E Tests', () => {
326327

327328
it('should correctly identify required and optional parameters in the schema', () => {
328329
const paramSchema = searchRowsTool.getParamSchema();
330+
const {shape} = paramSchema;
329331

330-
// Test the behavior of the required 'email' parameter
331-
expect(paramSchema.safeParse({email: '[email protected]'}).success).toBe(
332-
true,
333-
);
334-
expect(paramSchema.safeParse({}).success).toBe(false); // Fails when missing
335-
expect(paramSchema.safeParse({email: null}).success).toBe(false); // Fails when null
332+
// Required param 'email'
333+
expect(shape.email.isOptional()).toBe(false);
334+
expect(shape.email.isNullable()).toBe(false);
335+
expect(shape.email._def.typeName).toBe('ZodString');
336336

337-
// Test the behavior of the optional 'data' parameter
338-
expect(
339-
paramSchema.safeParse({email: '[email protected]', data: 'some data'})
340-
.success,
341-
).toBe(true);
337+
// Optional param 'data'
338+
expect(shape.data.isOptional()).toBe(true);
339+
expect(shape.data.isNullable()).toBe(true);
342340
expect(
343-
paramSchema.safeParse({email: '[email protected]', data: null}).success,
344-
).toBe(true); // Should succeed with null
345-
expect(paramSchema.safeParse({email: '[email protected]'}).success).toBe(
346-
true,
347-
); // Should succeed when omitted
341+
(shape.data as ZodOptional<ZodNullable<ZodTypeAny>>).unwrap().unwrap()
342+
._def.typeName,
343+
).toBe('ZodString');
348344

349-
// Test the behavior of the optional 'id' parameter
350-
expect(
351-
paramSchema.safeParse({email: '[email protected]', id: 123}).success,
352-
).toBe(true);
345+
// Optional param 'id'
346+
expect(shape.id.isOptional()).toBe(true);
347+
expect(shape.id.isNullable()).toBe(true);
353348
expect(
354-
paramSchema.safeParse({email: '[email protected]', id: null}).success,
355-
).toBe(true); // Should succeed with null
356-
expect(paramSchema.safeParse({email: '[email protected]'}).success).toBe(
357-
true,
358-
); // Should succeed when omitted
349+
(shape.id as ZodOptional<ZodNullable<ZodTypeAny>>).unwrap().unwrap()
350+
._def.typeName,
351+
).toBe('ZodNumber');
359352
});
360353

361354
it('should run tool with optional params omitted', async () => {
@@ -426,14 +419,16 @@ describe('ToolboxClient E2E Tests', () => {
426419

427420
it('should fail when a required param is missing', async () => {
428421
await expect(searchRowsTool({id: 5, data: 'row5'})).rejects.toThrow(
429-
/email: Invalid input: expected string, received undefined/,
422+
/Argument validation failed for tool "search-rows":\s*- email: Required/,
430423
);
431424
});
432425

433426
it('should fail when a required param is null', async () => {
434427
await expect(
435428
searchRowsTool({email: null, id: 5, data: 'row5'}),
436-
).rejects.toThrow(/email: Invalid input: expected string, received null/);
429+
).rejects.toThrow(
430+
/Argument validation failed for tool "search-rows":\s*- email: Expected string, received null/,
431+
);
437432
});
438433

439434
it('should run tool with all default params', async () => {

packages/toolbox-core/test/test.client.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ type CallableToolReturnedByFactory = ReturnType<OriginalToolboxToolType>;
3232

3333
type InferredZodTool = z.infer<typeof ZodToolSchema>;
3434

35-
const createMockZodObject = (shape: ZodRawShape = {}): ZodObject<ZodRawShape> =>
35+
const createMockZodObject = (
36+
shape: ZodRawShape = {},
37+
): ZodObject<ZodRawShape, 'strip', ZodTypeAny> =>
3638
({
3739
parse: jest.fn(args => args),
3840
_def: {
@@ -43,7 +45,7 @@ const createMockZodObject = (shape: ZodRawShape = {}): ZodObject<ZodRawShape> =>
4345
pick: jest.fn().mockReturnThis(),
4446
omit: jest.fn().mockReturnThis(),
4547
extend: jest.fn().mockReturnThis(),
46-
}) as unknown as ZodObject<ZodRawShape>;
48+
}) as unknown as ZodObject<ZodRawShape, 'strip', ZodTypeAny>;
4749

4850
// --- Mocking External Dependencies ---
4951
jest.mock('axios');
@@ -144,29 +146,29 @@ describe('ToolboxClient', () => {
144146
},
145147
overrides: {
146148
manifestData?: Partial<ZodManifest>;
147-
zodParamsSchema?: ZodObject<ZodRawShape>;
149+
zodParamsSchema?: ZodObject<ZodRawShape, 'strip', ZodTypeAny>;
148150
toolInstance?: Partial<CallableToolReturnedByFactory>;
149151
} = {},
150152
) => {
151153
const manifestData: ZodManifest = {
152154
serverVersion: '1.0.0',
153-
tools: {[toolName]: toolDefinition as unknown as InferredZodTool},
155+
tools: {[toolName]: toolDefinition as unknown as InferredZodTool}, // Cast here if ZodManifest expects InferredZodTool
154156
...overrides.manifestData,
155157
} as ZodManifest; // Outer cast to ZodManifest
156158

157159
const zodParamsSchema =
158160
overrides.zodParamsSchema ||
159161
createMockZodObject(
160162
(toolDefinition.parameters as unknown as ParameterSchema[]).reduce(
161-
(shapeAccumulator: {[k: string]: ZodTypeAny}, param) => {
163+
(shapeAccumulator: ZodRawShape, param) => {
162164
if (!param.authSources) {
163165
shapeAccumulator[param.name] = {
164166
_def: {typeName: 'ZodString'},
165167
} as unknown as ZodTypeAny;
166168
}
167169
return shapeAccumulator;
168170
},
169-
{},
171+
{} as ZodRawShape,
170172
),
171173
);
172174

@@ -294,11 +296,11 @@ describe('ToolboxClient', () => {
294296
const mockApiResponseData = {invalid: 'manifest structure'};
295297
const mockZodError = new ZodError([
296298
{
297-
input: undefined,
298299
path: ['tools'],
299300
message: 'Required',
300301
code: 'invalid_type',
301302
expected: 'object',
303+
received: 'undefined',
302304
},
303305
]);
304306

@@ -478,15 +480,18 @@ describe('ToolboxClient', () => {
478480
tools: toolDefinitions,
479481
};
480482

481-
const zodParamsSchemas: Record<string, ZodObject<ZodRawShape>> = {};
483+
const zodParamsSchemas: Record<
484+
string,
485+
ZodObject<ZodRawShape, 'strip', ZodTypeAny>
486+
> = {};
482487
const toolInstances: Record<string, CallableToolReturnedByFactory> = {};
483488
const orderedToolNames = Object.keys(toolDefinitions);
484489

485490
orderedToolNames.forEach(tName => {
486491
const tDef = toolDefinitions[tName];
487492
zodParamsSchemas[tName] = createMockZodObject(
488493
(tDef.parameters as ParameterSchema[]).reduce(
489-
(acc: {[k: string]: ZodTypeAny}, p) => {
494+
(acc: ZodRawShape, p) => {
490495
acc[p.name] = {
491496
_def: {typeName: 'ZodString'},
492497
} as unknown as ZodTypeAny;
@@ -745,7 +750,6 @@ describe('ToolboxClient', () => {
745750
const mockApiResponseData = {invalid: 'toolset structure'};
746751
const mockZodError = new ZodError([
747752
{
748-
input: undefined,
749753
path: ['serverVersion'],
750754
message: 'Zod validation failed on toolset',
751755
code: 'custom',

packages/toolbox-core/test/test.protocol.ts

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {
2424
// HELPER FUNCTIONS
2525

2626
const getErrorMessages = (error: ZodError): string[] => {
27-
return error.issues.map(e => {
27+
return error.errors.map(e => {
2828
if (e.path.length > 0) {
2929
return `${e.path.join('.')}: ${e.message}`;
3030
}
@@ -175,11 +175,7 @@ describe('ZodParameterSchema', () => {
175175
const data = {name: 'testArray', description: 'An array', type: 'array'};
176176
expectParseFailure(ZodParameterSchema, data, errors => {
177177
expect(errors).toEqual(
178-
expect.arrayContaining([
179-
expect.stringMatching(
180-
'items: Invalid input: expected object, received undefined',
181-
),
182-
]),
178+
expect.arrayContaining([expect.stringMatching(/items: Required/i)]),
183179
);
184180
});
185181
});
@@ -200,7 +196,9 @@ describe('ZodParameterSchema', () => {
200196
const data = {name: 'testParam', description: 'A param'}; // type is missing
201197
expectParseFailure(ZodParameterSchema, data, errors => {
202198
expect(errors).toEqual(
203-
expect.arrayContaining([expect.stringMatching('type: Invalid input')]),
199+
expect.arrayContaining([
200+
expect.stringMatching(/Invalid discriminator value/i),
201+
]),
204202
);
205203
});
206204
});
@@ -291,7 +289,7 @@ describe('ZodManifestSchema', () => {
291289
expectParseFailure(ZodManifestSchema, data, errors => {
292290
expect(errors).toEqual(
293291
expect.arrayContaining([
294-
expect.stringMatching('tools.: Invalid key in record'),
292+
expect.stringMatching(/Tool name cannot be empty/i),
295293
]),
296294
);
297295
});
@@ -317,7 +315,9 @@ describe('createZodObjectSchemaFromParameters', () => {
317315

318316
expectParseSuccess(schema, {});
319317
expectParseFailure(schema, {anyKey: 'anyValue'}, errors => {
320-
expect(errors.some(e => /unrecognized key/i.test(e))).toBe(true);
318+
expect(
319+
errors.some(e => /Unrecognized key\(s\) in object: 'anyKey'/.test(e)),
320+
).toBe(true);
321321
});
322322
});
323323

@@ -339,14 +339,10 @@ describe('createZodObjectSchemaFromParameters', () => {
339339
schema,
340340
{username: 'john_doe', age: '30', isActive: true},
341341
errors =>
342-
expect(errors).toContain(
343-
'age: Invalid input: expected number, received string',
344-
),
342+
expect(errors).toContain('age: Expected number, received string'),
345343
);
346344
expectParseFailure(schema, {username: 'john_doe', isActive: true}, errors =>
347-
expect(errors).toContain(
348-
'age: Invalid input: expected number, received undefined',
349-
),
345+
expect(errors).toContain('age: Required'),
350346
);
351347
});
352348

@@ -369,9 +365,7 @@ describe('createZodObjectSchemaFromParameters', () => {
369365
expectParseSuccess(schema, {tags: ['news', 'tech'], id: 1});
370366

371367
expectParseFailure(schema, {tags: ['news', 123], id: 1}, errors => {
372-
expect(errors).toContain(
373-
'tags.1: Invalid input: expected string, received number',
374-
);
368+
expect(errors).toContain('tags.1: Expected string, received number');
375369
});
376370
});
377371

@@ -412,7 +406,7 @@ describe('createZodObjectSchemaFromParameters', () => {
412406
},
413407
errors => {
414408
expect(errors).toContain(
415-
'matrix.0.1: Invalid input: expected number, received string',
409+
'matrix.0.1: Expected number, received string',
416410
);
417411
},
418412
);
@@ -445,9 +439,7 @@ describe('createZodObjectSchemaFromParameters', () => {
445439

446440
it('should fail if a required parameter is missing', () => {
447441
expectParseFailure(schema, {optionalParam: 'value'}, errors => {
448-
expect(errors).toContain(
449-
'requiredParam: Invalid input: expected string, received undefined',
450-
);
442+
expect(errors).toContain('requiredParam: Required');
451443
});
452444
});
453445

packages/toolbox-core/test/test.tool.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,6 @@ describe('ToolboxTool', () => {
222222
it('should throw a generic error if paramSchema.parse throws a non-ZodError', async () => {
223223
const customError = new Error('A non-Zod parsing error occurred!');
224224
const failingSchema = {
225-
shape: {},
226225
parse: jest.fn().mockImplementation(() => {
227226
throw customError;
228227
}),
@@ -276,7 +275,7 @@ describe('ToolboxTool', () => {
276275
basicParamSchema,
277276
);
278277
await expect(currentTool()).rejects.toThrow(
279-
'Argument validation failed for tool "myTestTool":\n - query: Invalid input: expected string, received undefined',
278+
'Argument validation failed for tool "myTestTool":\n - query: Required',
280279
);
281280
expect(mockAxiosPost).not.toHaveBeenCalled();
282281
});

0 commit comments

Comments
 (0)