@optimizely-opal/opal-tool-ocp-sdk 1.0.0-beta.3 → 1.0.0-beta.5

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.
Files changed (57) hide show
  1. package/README.md +114 -0
  2. package/dist/auth/AuthUtils.d.ts +5 -5
  3. package/dist/auth/AuthUtils.d.ts.map +1 -1
  4. package/dist/auth/AuthUtils.js +53 -25
  5. package/dist/auth/AuthUtils.js.map +1 -1
  6. package/dist/auth/AuthUtils.test.js +62 -117
  7. package/dist/auth/AuthUtils.test.js.map +1 -1
  8. package/dist/function/GlobalToolFunction.d.ts +1 -1
  9. package/dist/function/GlobalToolFunction.d.ts.map +1 -1
  10. package/dist/function/GlobalToolFunction.js +17 -4
  11. package/dist/function/GlobalToolFunction.js.map +1 -1
  12. package/dist/function/GlobalToolFunction.test.js +54 -8
  13. package/dist/function/GlobalToolFunction.test.js.map +1 -1
  14. package/dist/function/ToolFunction.d.ts +1 -1
  15. package/dist/function/ToolFunction.d.ts.map +1 -1
  16. package/dist/function/ToolFunction.js +17 -4
  17. package/dist/function/ToolFunction.js.map +1 -1
  18. package/dist/function/ToolFunction.test.js +54 -8
  19. package/dist/function/ToolFunction.test.js.map +1 -1
  20. package/dist/index.d.ts +1 -0
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +1 -0
  23. package/dist/index.js.map +1 -1
  24. package/dist/service/Service.d.ts +15 -2
  25. package/dist/service/Service.d.ts.map +1 -1
  26. package/dist/service/Service.js +43 -17
  27. package/dist/service/Service.js.map +1 -1
  28. package/dist/service/Service.test.js +84 -2
  29. package/dist/service/Service.test.js.map +1 -1
  30. package/dist/types/ToolError.d.ts +72 -0
  31. package/dist/types/ToolError.d.ts.map +1 -0
  32. package/dist/types/ToolError.js +107 -0
  33. package/dist/types/ToolError.js.map +1 -0
  34. package/dist/types/ToolError.test.d.ts +2 -0
  35. package/dist/types/ToolError.test.d.ts.map +1 -0
  36. package/dist/types/ToolError.test.js +185 -0
  37. package/dist/types/ToolError.test.js.map +1 -0
  38. package/dist/validation/ParameterValidator.d.ts +5 -16
  39. package/dist/validation/ParameterValidator.d.ts.map +1 -1
  40. package/dist/validation/ParameterValidator.js +10 -3
  41. package/dist/validation/ParameterValidator.js.map +1 -1
  42. package/dist/validation/ParameterValidator.test.js +187 -146
  43. package/dist/validation/ParameterValidator.test.js.map +1 -1
  44. package/package.json +1 -1
  45. package/src/auth/AuthUtils.test.ts +62 -157
  46. package/src/auth/AuthUtils.ts +66 -32
  47. package/src/function/GlobalToolFunction.test.ts +54 -8
  48. package/src/function/GlobalToolFunction.ts +26 -6
  49. package/src/function/ToolFunction.test.ts +54 -8
  50. package/src/function/ToolFunction.ts +26 -6
  51. package/src/index.ts +1 -0
  52. package/src/service/Service.test.ts +103 -2
  53. package/src/service/Service.ts +45 -17
  54. package/src/types/ToolError.test.ts +222 -0
  55. package/src/types/ToolError.ts +125 -0
  56. package/src/validation/ParameterValidator.test.ts +188 -158
  57. package/src/validation/ParameterValidator.ts +17 -20
@@ -1,5 +1,6 @@
1
1
  import { ParameterValidator } from './ParameterValidator';
2
2
  import { Parameter, ParameterType } from '../types/Models';
3
+ import { ToolError } from '../types/ToolError';
3
4
 
4
5
  describe('ParameterValidator', () => {
5
6
  describe('validate', () => {
@@ -22,13 +23,12 @@ describe('ParameterValidator', () => {
22
23
  config: { theme: 'dark', language: 'en' }
23
24
  };
24
25
 
25
- const result = ParameterValidator.validate(validParams, paramDefs);
26
-
27
- expect(result.isValid).toBe(true);
28
- expect(result.errors).toHaveLength(0);
26
+ expect(() => {
27
+ ParameterValidator.validate(validParams, paramDefs, '/test-endpoint');
28
+ }).not.toThrow();
29
29
  });
30
30
 
31
- it('should fail validation for missing required parameters', () => {
31
+ it('should throw ToolError for missing required parameters', () => {
32
32
  const paramDefs = [
33
33
  new Parameter('name', ParameterType.String, 'User name', true),
34
34
  new Parameter('email', ParameterType.String, 'User email', true)
@@ -39,17 +39,30 @@ describe('ParameterValidator', () => {
39
39
  // email is missing
40
40
  };
41
41
 
42
- const result = ParameterValidator.validate(params, paramDefs);
43
-
44
- expect(result.isValid).toBe(false);
45
- expect(result.errors).toHaveLength(1);
46
- expect(result.errors[0]).toEqual({
47
- field: 'email',
48
- message: "Required parameter 'email' is missing"
49
- });
42
+ expect(() => {
43
+ ParameterValidator.validate(params, paramDefs, '/test-endpoint');
44
+ }).toThrow(ToolError);
45
+
46
+ try {
47
+ ParameterValidator.validate(params, paramDefs, '/test-endpoint');
48
+ } catch (error) {
49
+ expect(error).toBeInstanceOf(ToolError);
50
+ const toolError = error as ToolError;
51
+ expect(toolError.status).toBe(400);
52
+ expect(toolError.message).toBe(
53
+ "[400] One or more validation errors occurred.: email (Required parameter 'email' is missing)"
54
+ );
55
+ expect(toolError.title).toBe('One or more validation errors occurred.');
56
+ expect(toolError.detail).toBe("See 'errors' field for details.");
57
+ expect(toolError.errors).toHaveLength(1);
58
+ expect(toolError.errors).toEqual([{
59
+ field: 'email',
60
+ message: "Required parameter 'email' is missing"
61
+ }]);
62
+ }
50
63
  });
51
64
 
52
- it('should fail validation for wrong parameter types', () => {
65
+ it('should throw ToolError for wrong parameter types', () => {
53
66
  const paramDefs = [
54
67
  new Parameter('name', ParameterType.String, 'User name', true),
55
68
  new Parameter('age', ParameterType.Integer, 'User age', true),
@@ -66,42 +79,64 @@ describe('ParameterValidator', () => {
66
79
  config: 'invalid' // should be object
67
80
  };
68
81
 
69
- const result = ParameterValidator.validate(invalidParams, paramDefs);
70
-
71
- expect(result.isValid).toBe(false);
72
- expect(result.errors).toHaveLength(5);
82
+ try {
83
+ ParameterValidator.validate(invalidParams, paramDefs, '/test-endpoint');
84
+ fail('Should have thrown ToolError');
85
+ } catch (error) {
86
+ expect(error).toBeInstanceOf(ToolError);
87
+ const toolError = error as ToolError;
88
+ expect(toolError.status).toBe(400);
89
+ expect(toolError.errors).toHaveLength(5);
73
90
 
74
- expect(result.errors[0].field).toBe('name');
75
- expect(result.errors[0].message).toContain('must be a string');
91
+ expect(toolError.errors![0].field).toBe('name');
92
+ expect(toolError.errors![0].message).toContain('must be a string');
76
93
 
77
- expect(result.errors[1].field).toBe('age');
78
- expect(result.errors[1].message).toContain('must be an integer');
94
+ expect(toolError.errors![1].field).toBe('age');
95
+ expect(toolError.errors![1].message).toContain('must be an integer');
79
96
 
80
- expect(result.errors[2].field).toBe('active');
81
- expect(result.errors[2].message).toContain('must be a boolean');
97
+ expect(toolError.errors![2].field).toBe('active');
98
+ expect(toolError.errors![2].message).toContain('must be a boolean');
82
99
 
83
- expect(result.errors[3].field).toBe('tags');
84
- expect(result.errors[3].message).toContain('must be an array');
100
+ expect(toolError.errors![3].field).toBe('tags');
101
+ expect(toolError.errors![3].message).toContain('must be an array');
85
102
 
86
- expect(result.errors[4].field).toBe('config');
87
- expect(result.errors[4].message).toContain('must be an object');
103
+ expect(toolError.errors![4].field).toBe('config');
104
+ expect(toolError.errors![4].message).toContain('must be an object');
105
+ }
88
106
  });
89
107
 
90
- it('should handle null/undefined parameters correctly', () => {
108
+ it('should throw ToolError when params is null with required parameters', () => {
91
109
  const paramDefs = [
92
110
  new Parameter('required', ParameterType.String, 'Required param', true),
93
111
  new Parameter('optional', ParameterType.String, 'Optional param', false)
94
112
  ];
95
113
 
96
- const result1 = ParameterValidator.validate(null, paramDefs);
97
- expect(result1.isValid).toBe(false);
98
- expect(result1.errors).toHaveLength(1);
99
- expect(result1.errors[0].field).toBe('required');
114
+ try {
115
+ ParameterValidator.validate(null, paramDefs, '/test-endpoint');
116
+ fail('Should have thrown ToolError');
117
+ } catch (error) {
118
+ expect(error).toBeInstanceOf(ToolError);
119
+ const toolError = error as ToolError;
120
+ expect(toolError.errors).toHaveLength(1);
121
+ expect(toolError.errors![0].field).toBe('required');
122
+ }
123
+ });
100
124
 
101
- const result2 = ParameterValidator.validate(undefined, paramDefs);
102
- expect(result2.isValid).toBe(false);
103
- expect(result2.errors).toHaveLength(1);
104
- expect(result2.errors[0].field).toBe('required');
125
+ it('should throw ToolError when params is undefined with required parameters', () => {
126
+ const paramDefs = [
127
+ new Parameter('required', ParameterType.String, 'Required param', true),
128
+ new Parameter('optional', ParameterType.String, 'Optional param', false)
129
+ ];
130
+
131
+ try {
132
+ ParameterValidator.validate(undefined, paramDefs, '/test-endpoint');
133
+ fail('Should have thrown ToolError');
134
+ } catch (error) {
135
+ expect(error).toBeInstanceOf(ToolError);
136
+ const toolError = error as ToolError;
137
+ expect(toolError.errors).toHaveLength(1);
138
+ expect(toolError.errors![0].field).toBe('required');
139
+ }
105
140
  });
106
141
 
107
142
  it('should allow optional parameters to be missing', () => {
@@ -115,10 +150,9 @@ describe('ParameterValidator', () => {
115
150
  // age is optional and missing
116
151
  };
117
152
 
118
- const result = ParameterValidator.validate(params, paramDefs);
119
-
120
- expect(result.isValid).toBe(true);
121
- expect(result.errors).toHaveLength(0);
153
+ expect(() => {
154
+ ParameterValidator.validate(params, paramDefs, '/test-endpoint');
155
+ }).not.toThrow();
122
156
  });
123
157
 
124
158
  it('should distinguish between integer and number types', () => {
@@ -132,210 +166,206 @@ describe('ParameterValidator', () => {
132
166
  score: 85.5 // number is fine
133
167
  };
134
168
 
135
- const result1 = ParameterValidator.validate(params1, paramDefs);
136
- expect(result1.isValid).toBe(false);
137
- expect(result1.errors).toHaveLength(1);
138
- expect(result1.errors[0].field).toBe('count');
139
- expect(result1.errors[0].message).toContain('must be an integer');
169
+ try {
170
+ ParameterValidator.validate(params1, paramDefs, '/test-endpoint');
171
+ fail('Should have thrown ToolError');
172
+ } catch (error) {
173
+ expect(error).toBeInstanceOf(ToolError);
174
+ const toolError = error as ToolError;
175
+ expect(toolError.errors).toHaveLength(1);
176
+ expect(toolError.errors![0].field).toBe('count');
177
+ expect(toolError.errors![0].message).toContain('must be an integer');
178
+ }
140
179
 
141
180
  const params2 = {
142
181
  count: 25, // integer is fine
143
182
  score: 85.5 // number is fine
144
183
  };
145
184
 
146
- const result2 = ParameterValidator.validate(params2, paramDefs);
147
- expect(result2.isValid).toBe(true);
148
- expect(result2.errors).toHaveLength(0);
185
+ expect(() => {
186
+ ParameterValidator.validate(params2, paramDefs, '/test-endpoint');
187
+ }).not.toThrow();
149
188
  });
150
189
 
151
190
  it('should handle array vs object distinction', () => {
152
191
  const paramDefs = [
153
- new Parameter('tags', ParameterType.List, 'Tag list', true),
154
- new Parameter('config', ParameterType.Dictionary, 'Config object', true)
192
+ new Parameter('tags', ParameterType.List, 'Tags', true),
193
+ new Parameter('config', ParameterType.Dictionary, 'Config', true)
155
194
  ];
156
195
 
157
196
  const params = {
158
- tags: { 0: 'tag1', 1: 'tag2' }, // object that looks like array
159
- config: ['key1', 'key2'] // array instead of object
197
+ tags: { key: 'value' }, // should be array, not object
198
+ config: ['item1', 'item2'] // should be object, not array
160
199
  };
161
200
 
162
- const result = ParameterValidator.validate(params, paramDefs);
163
- expect(result.isValid).toBe(false);
164
- expect(result.errors).toHaveLength(2);
165
-
166
- expect(result.errors[0].field).toBe('tags');
167
- expect(result.errors[0].message).toContain('must be an array');
168
-
169
- expect(result.errors[1].field).toBe('config');
170
- expect(result.errors[1].message).toContain('must be an object');
201
+ try {
202
+ ParameterValidator.validate(params, paramDefs, '/test-endpoint');
203
+ fail('Should have thrown ToolError');
204
+ } catch (error) {
205
+ expect(error).toBeInstanceOf(ToolError);
206
+ const toolError = error as ToolError;
207
+ expect(toolError.errors).toHaveLength(2);
208
+ }
171
209
  });
172
210
 
173
211
  it('should handle null values for optional parameters', () => {
174
212
  const paramDefs = [
175
213
  new Parameter('name', ParameterType.String, 'User name', true),
176
- new Parameter('age', ParameterType.Integer, 'User age', false)
214
+ new Parameter('nickname', ParameterType.String, 'Nickname', false)
177
215
  ];
178
216
 
179
217
  const params = {
180
218
  name: 'John Doe',
181
- age: null // null for optional parameter should be allowed
219
+ nickname: null // optional param can be null
182
220
  };
183
221
 
184
- const result = ParameterValidator.validate(params, paramDefs);
185
- expect(result.isValid).toBe(true);
186
- expect(result.errors).toHaveLength(0);
222
+ expect(() => {
223
+ ParameterValidator.validate(params, paramDefs, '/test-endpoint');
224
+ }).not.toThrow();
187
225
  });
188
226
 
189
227
  it('should handle edge cases for number validation', () => {
190
228
  const paramDefs = [
191
- new Parameter('score', ParameterType.Number, 'Score value', true)
229
+ new Parameter('value', ParameterType.Number, 'Number value', true)
192
230
  ];
193
231
 
194
- // Test NaN
195
- const params1 = { score: NaN };
196
- const result1 = ParameterValidator.validate(params1, paramDefs);
197
- expect(result1.isValid).toBe(false);
198
- expect(result1.errors[0].message).toContain('must be a number');
199
-
200
- // Test Infinity
201
- const params2 = { score: Infinity };
202
- const result2 = ParameterValidator.validate(params2, paramDefs);
203
- expect(result2.isValid).toBe(true);
204
- expect(result2.errors).toHaveLength(0);
205
-
206
- // Test negative numbers
207
- const params3 = { score: -42.5 };
208
- const result3 = ParameterValidator.validate(params3, paramDefs);
209
- expect(result3.isValid).toBe(true);
210
- expect(result3.errors).toHaveLength(0);
232
+ // NaN should fail
233
+ try {
234
+ ParameterValidator.validate({ value: NaN }, paramDefs, '/test-endpoint');
235
+ fail('Should have thrown ToolError for NaN');
236
+ } catch (error) {
237
+ expect(error).toBeInstanceOf(ToolError);
238
+ }
239
+
240
+ // Infinity should pass (it's a number)
241
+ expect(() => {
242
+ ParameterValidator.validate({ value: Infinity }, paramDefs, '/test-endpoint');
243
+ }).not.toThrow();
244
+
245
+ // Negative numbers should pass
246
+ expect(() => {
247
+ ParameterValidator.validate({ value: -42.5 }, paramDefs, '/test-endpoint');
248
+ }).not.toThrow();
211
249
  });
212
250
 
213
251
  it('should handle edge cases for integer validation', () => {
214
252
  const paramDefs = [
215
- new Parameter('count', ParameterType.Integer, 'Item count', true)
253
+ new Parameter('count', ParameterType.Integer, 'Count', true)
216
254
  ];
217
255
 
218
- // Test negative integers
219
- const params1 = { count: -5 };
220
- const result1 = ParameterValidator.validate(params1, paramDefs);
221
- expect(result1.isValid).toBe(true);
222
- expect(result1.errors).toHaveLength(0);
223
-
224
- // Test zero
225
- const params2 = { count: 0 };
226
- const result2 = ParameterValidator.validate(params2, paramDefs);
227
- expect(result2.isValid).toBe(true);
228
- expect(result2.errors).toHaveLength(0);
229
-
230
- // Test very large integers
231
- const params3 = { count: Number.MAX_SAFE_INTEGER };
232
- const result3 = ParameterValidator.validate(params3, paramDefs);
233
- expect(result3.isValid).toBe(true);
234
- expect(result3.errors).toHaveLength(0);
256
+ // Zero should pass
257
+ expect(() => {
258
+ ParameterValidator.validate({ count: 0 }, paramDefs, '/test-endpoint');
259
+ }).not.toThrow();
260
+
261
+ // Negative integer should pass
262
+ expect(() => {
263
+ ParameterValidator.validate({ count: -10 }, paramDefs, '/test-endpoint');
264
+ }).not.toThrow();
235
265
  });
236
266
 
237
267
  it('should handle empty arrays and objects', () => {
238
268
  const paramDefs = [
239
- new Parameter('tags', ParameterType.List, 'Tag list', true),
240
- new Parameter('config', ParameterType.Dictionary, 'Config object', true)
269
+ new Parameter('tags', ParameterType.List, 'Tags', true),
270
+ new Parameter('config', ParameterType.Dictionary, 'Config', true)
241
271
  ];
242
272
 
243
273
  const params = {
244
- tags: [], // empty array should be valid
245
- config: {} // empty object should be valid
274
+ tags: [],
275
+ config: {}
246
276
  };
247
277
 
248
- const result = ParameterValidator.validate(params, paramDefs);
249
- expect(result.isValid).toBe(true);
250
- expect(result.errors).toHaveLength(0);
278
+ expect(() => {
279
+ ParameterValidator.validate(params, paramDefs, '/test-endpoint');
280
+ }).not.toThrow();
251
281
  });
252
282
 
253
283
  it('should handle special string values', () => {
254
284
  const paramDefs = [
255
- new Parameter('text', ParameterType.String, 'Text value', true)
285
+ new Parameter('value', ParameterType.String, 'String value', true)
256
286
  ];
257
287
 
258
- // Test empty string
259
- const params1 = { text: '' };
260
- const result1 = ParameterValidator.validate(params1, paramDefs);
261
- expect(result1.isValid).toBe(true);
262
- expect(result1.errors).toHaveLength(0);
263
-
264
- // Test string with special characters
265
- const params2 = { text: 'Hello\nWorld\t!' };
266
- const result2 = ParameterValidator.validate(params2, paramDefs);
267
- expect(result2.isValid).toBe(true);
268
- expect(result2.errors).toHaveLength(0);
288
+ // Empty string should pass
289
+ expect(() => {
290
+ ParameterValidator.validate({ value: '' }, paramDefs, '/test-endpoint');
291
+ }).not.toThrow();
292
+
293
+ // String with only whitespace should pass
294
+ expect(() => {
295
+ ParameterValidator.validate({ value: ' ' }, paramDefs, '/test-endpoint');
296
+ }).not.toThrow();
269
297
  });
270
298
 
271
- it('should handle multiple validation errors', () => {
299
+ it('should collect multiple validation errors', () => {
272
300
  const paramDefs = [
273
- new Parameter('name', ParameterType.String, 'User name', true),
274
- new Parameter('age', ParameterType.Integer, 'User age', true),
275
- new Parameter('email', ParameterType.String, 'User email', true)
301
+ new Parameter('name', ParameterType.String, 'Name', true),
302
+ new Parameter('age', ParameterType.Integer, 'Age', true),
303
+ new Parameter('email', ParameterType.String, 'Email', true)
276
304
  ];
277
305
 
278
306
  const params = {
279
- name: 123, // wrong type
280
- age: '25' // wrong type
307
+ // name is missing
308
+ age: 'invalid' // wrong type
281
309
  // email is missing
282
310
  };
283
311
 
284
- const result = ParameterValidator.validate(params, paramDefs);
285
- expect(result.isValid).toBe(false);
286
- expect(result.errors).toHaveLength(3);
287
-
288
- expect(result.errors.some((e) => e.field === 'name')).toBe(true);
289
- expect(result.errors.some((e) => e.field === 'age')).toBe(true);
290
- expect(result.errors.some((e) => e.field === 'email')).toBe(true);
312
+ try {
313
+ ParameterValidator.validate(params, paramDefs, '/test-endpoint');
314
+ fail('Should have thrown ToolError');
315
+ } catch (error) {
316
+ expect(error).toBeInstanceOf(ToolError);
317
+ const toolError = error as ToolError;
318
+ expect(toolError.errors).toHaveLength(3);
319
+
320
+ expect(toolError.errors!.some((e) => e.field === 'name')).toBe(true);
321
+ expect(toolError.errors!.some((e) => e.field === 'age')).toBe(true);
322
+ expect(toolError.errors!.some((e) => e.field === 'email')).toBe(true);
323
+ }
291
324
  });
292
325
 
293
326
  it('should handle tools with no parameter definitions', () => {
294
- const result = ParameterValidator.validate({ someParam: 'value' }, []);
295
- expect(result.isValid).toBe(true);
296
- expect(result.errors).toHaveLength(0);
327
+ expect(() => {
328
+ ParameterValidator.validate({ anyParam: 'value' }, [], '/test-endpoint');
329
+ }).not.toThrow();
297
330
  });
298
331
 
299
332
  it('should handle extra parameters not in definition', () => {
300
333
  const paramDefs = [
301
- new Parameter('name', ParameterType.String, 'User name', true)
334
+ new Parameter('name', ParameterType.String, 'Name', true)
302
335
  ];
303
336
 
304
337
  const params = {
305
- name: 'John Doe',
306
- extraParam: 'should be ignored'
338
+ name: 'John',
339
+ extraParam: 'ignored', // not in definition
340
+ anotherExtra: 123
307
341
  };
308
342
 
309
- const result = ParameterValidator.validate(params, paramDefs);
310
- expect(result.isValid).toBe(true);
311
- expect(result.errors).toHaveLength(0);
343
+ // Extra parameters should be ignored
344
+ expect(() => {
345
+ ParameterValidator.validate(params, paramDefs, '/test-endpoint');
346
+ }).not.toThrow();
312
347
  });
313
348
 
314
349
  it('should handle nested objects and arrays', () => {
315
350
  const paramDefs = [
316
- new Parameter('config', ParameterType.Dictionary, 'Config object', true),
317
- new Parameter('matrix', ParameterType.List, 'Matrix data', true)
351
+ new Parameter('config', ParameterType.Dictionary, 'Config', true),
352
+ new Parameter('items', ParameterType.List, 'Items', true)
318
353
  ];
319
354
 
320
355
  const params = {
321
356
  config: {
322
357
  nested: {
323
- deep: {
324
- value: 'test'
358
+ deeply: {
359
+ nested: 'value'
325
360
  }
326
- },
327
- array: [1, 2, 3]
361
+ }
328
362
  },
329
- matrix: [
330
- [1, 2, 3],
331
- [4, 5, 6],
332
- { nested: 'object in array' }
333
- ]
363
+ items: [1, 2, [3, 4, [5, 6]]]
334
364
  };
335
365
 
336
- const result = ParameterValidator.validate(params, paramDefs);
337
- expect(result.isValid).toBe(true);
338
- expect(result.errors).toHaveLength(0);
366
+ expect(() => {
367
+ ParameterValidator.validate(params, paramDefs, '/test-endpoint');
368
+ }).not.toThrow();
339
369
  });
340
370
  });
341
371
  });
@@ -1,20 +1,5 @@
1
1
  import { Parameter, ParameterType } from '../types/Models';
2
-
3
- /**
4
- * Validation error details
5
- */
6
- export interface ValidationError {
7
- field: string;
8
- message: string;
9
- }
10
-
11
- /**
12
- * Validation result
13
- */
14
- export interface ValidationResult {
15
- isValid: boolean;
16
- errors: ValidationError[];
17
- }
2
+ import { ToolError, ValidationError } from '../types/ToolError';
18
3
 
19
4
  /**
20
5
  * Parameter validator for tool inputs
@@ -22,14 +7,18 @@ export interface ValidationResult {
22
7
  export class ParameterValidator {
23
8
  /**
24
9
  * Validate parameters against their definitions
10
+ * Throws ToolError with status 400 if validation fails
11
+ *
25
12
  * @param params The actual parameters received
26
13
  * @param parameterDefinitions The expected parameter definitions
27
- * @returns Validation result with any errors found
14
+ * @param _endpoint The endpoint being validated (reserved for future use)
15
+ * @throws {ToolError} When validation fails
28
16
  */
29
17
  public static validate(
30
18
  params: any,
31
- parameterDefinitions: Parameter[]
32
- ): ValidationResult {
19
+ parameterDefinitions: Parameter[],
20
+ _endpoint: string
21
+ ): void {
33
22
  const errors: ValidationError[] = [];
34
23
 
35
24
  // Validate each defined parameter
@@ -57,7 +46,15 @@ export class ParameterValidator {
57
46
  }
58
47
  }
59
48
 
60
- return { isValid: errors.length === 0, errors };
49
+ // Throw ToolError if validation failed
50
+ if (errors.length > 0) {
51
+ throw new ToolError(
52
+ 'One or more validation errors occurred.',
53
+ 400,
54
+ "See 'errors' field for details.",
55
+ errors
56
+ );
57
+ }
61
58
  }
62
59
 
63
60
  /**