@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
package/README.md CHANGED
@@ -317,6 +317,119 @@ export class MyToolFunction extends ToolFunction {
317
317
  }
318
318
  ```
319
319
 
320
+ ## Error Handling
321
+
322
+ The SDK provides RFC 9457 Problem Details compliant error handling through the `ToolError` class. This allows you to throw errors with custom HTTP status codes and detailed error information.
323
+
324
+ ### ToolError Class
325
+
326
+ ```typescript
327
+ class ToolError extends Error {
328
+ constructor(
329
+ message: string, // Error message (used as "title" in RFC 9457)
330
+ status?: number, // HTTP status code (default: 500)
331
+ detail?: string // Detailed error description (optional)
332
+ )
333
+ }
334
+ ```
335
+
336
+ ### Usage Examples
337
+
338
+ ```typescript
339
+ import { ToolFunction, tool, ToolError, ParameterType } from '@optimizely-opal/opal-tool-ocp-sdk';
340
+
341
+
342
+ // Throw a 404 error
343
+ throw new ToolError(
344
+ 'Task not found',
345
+ 404,
346
+ `No task exists with ID: ${params.taskId}`
347
+ );
348
+
349
+ // Throw a 400 error for invalid input
350
+ throw new ToolError(
351
+ 'Invalid priority',
352
+ 400,
353
+ `Priority must be one of: ${validPriorities.join(', ')}`
354
+ );
355
+ ```
356
+
357
+ ### Error Response Format
358
+
359
+ When a `ToolError` is thrown, the SDK automatically formats it as an RFC 9457 Problem Details response:
360
+
361
+ ```json
362
+ {
363
+ "title": "Task not found",
364
+ "status": 404,
365
+ "detail": "No task exists with ID: task-123",
366
+ "instance": "/get-task"
367
+ }
368
+ ```
369
+
370
+ ### Validation Errors with Multiple Fields
371
+
372
+ You can also throw `ToolError` with an `errors` array for validation scenarios with multiple field errors:
373
+
374
+ ```typescript
375
+ import { ToolError } from '@optimizely-opal/opal-tool-ocp-sdk';
376
+
377
+ // Validate multiple fields
378
+ const validationErrors = [];
379
+
380
+ if (!email.includes('@')) {
381
+ validationErrors.push({
382
+ field: 'email',
383
+ message: 'Invalid email format'
384
+ });
385
+ }
386
+
387
+ if (age < 0) {
388
+ validationErrors.push({
389
+ field: 'age',
390
+ message: 'Age must be a positive number'
391
+ });
392
+ }
393
+
394
+ if (validationErrors.length > 0) {
395
+ throw new ToolError(
396
+ 'Validation failed',
397
+ 400,
398
+ "See 'errors' field for details.",
399
+ validationErrors
400
+ );
401
+ }
402
+ ```
403
+
404
+ This will return:
405
+
406
+ ```json
407
+ {
408
+ "title": "Validation failed",
409
+ "status": 400,
410
+ "detail": "See 'errors' field for details.",
411
+ "instance": "/create-user",
412
+ "errors": [
413
+ {
414
+ "field": "email",
415
+ "message": "Invalid email format"
416
+ },
417
+ {
418
+ "field": "age",
419
+ "message": "Age must be a positive number"
420
+ }
421
+ ]
422
+ }
423
+ ```
424
+
425
+ **Response Headers:**
426
+ - `Content-Type: application/problem+json`
427
+ - HTTP status code matches the `ToolError` status
428
+
429
+ **Note:**
430
+ - If a regular `Error` (not `ToolError`) is thrown, it will be automatically wrapped in a 500 response with RFC 9457 format
431
+ - Parameter validation is automatic and uses this same format when validation fails
432
+
320
433
  ## API Reference
321
434
 
322
435
  ### Handler Function Signatures
@@ -399,6 +512,7 @@ Key model classes with generic type support:
399
512
  - `AuthRequirement` - Defines authentication needs
400
513
  - `InteractionResult` - Response from interactions
401
514
  - `OptiIdAuthData` - OptiID specific authentication data
515
+ - `ToolError` - Custom error class for RFC 9457 Problem Details error responses with configurable HTTP status codes
402
516
 
403
517
  ## Discovery and Ready Endpoints
404
518
 
@@ -3,7 +3,7 @@ import { OptiIdAuthData } from '../types/Models';
3
3
  * Extract and validate basic OptiID authentication data from request
4
4
  *
5
5
  * @param request - The incoming request
6
- * @returns object with authData and accessToken, or null if invalid
6
+ * @returns object with authData and accessToken, or null if auth is missing
7
7
  */
8
8
  export declare function extractAuthData(request: any): {
9
9
  authData: OptiIdAuthData;
@@ -13,14 +13,14 @@ export declare function extractAuthData(request: any): {
13
13
  * Authenticate a request for regular functions (with organization validation)
14
14
  *
15
15
  * @param request - The incoming request
16
- * @returns true if authentication and authorization succeed
16
+ * @throws {ToolError} If authentication or authorization fails
17
17
  */
18
- export declare function authenticateRegularRequest(request: any): Promise<boolean>;
18
+ export declare function authenticateRegularRequest(request: any): Promise<void>;
19
19
  /**
20
20
  * Authenticate a request for global functions (without organization validation)
21
21
  *
22
22
  * @param request - The incoming request
23
- * @returns true if authentication succeeds
23
+ * @throws {ToolError} If authentication fails
24
24
  */
25
- export declare function authenticateGlobalRequest(request: any): Promise<boolean>;
25
+ export declare function authenticateGlobalRequest(request: any): Promise<void>;
26
26
  //# sourceMappingURL=AuthUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AuthUtils.d.ts","sourceRoot":"","sources":["../../src/auth/AuthUtils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAqBjD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,GAAG,GAAG;IAAE,QAAQ,EAAE,cAAc,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAQtG;AA6DD;;;;;GAKG;AACH,wBAAsB,0BAA0B,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAE/E;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAE9E"}
1
+ {"version":3,"file":"AuthUtils.d.ts","sourceRoot":"","sources":["../../src/auth/AuthUtils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AA4BjD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,GAAG,GAAG;IAAE,QAAQ,EAAE,cAAc,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAiBtG;AA+ED;;;;;GAKG;AACH,wBAAsB,0BAA0B,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3E"}
@@ -5,56 +5,89 @@ exports.authenticateRegularRequest = authenticateRegularRequest;
5
5
  exports.authenticateGlobalRequest = authenticateGlobalRequest;
6
6
  const app_sdk_1 = require("@zaiusinc/app-sdk");
7
7
  const TokenVerifier_1 = require("./TokenVerifier");
8
+ const ToolError_1 = require("../types/ToolError");
8
9
  /**
9
10
  * Validate the OptiID access token
10
11
  *
11
12
  * @param accessToken - The access token to validate
12
- * @returns true if the token is valid
13
+ * @throws {ToolError} If token validation fails
13
14
  */
14
15
  async function validateAccessToken(accessToken) {
15
16
  try {
16
17
  if (!accessToken) {
17
- return false;
18
+ throw new ToolError_1.ToolError('Forbidden', 403, 'OptiID access token is required');
18
19
  }
19
20
  const tokenVerifier = await (0, TokenVerifier_1.getTokenVerifier)();
20
- return await tokenVerifier.verify(accessToken);
21
+ const isValid = await tokenVerifier.verify(accessToken);
22
+ if (!isValid) {
23
+ throw new ToolError_1.ToolError('Forbidden', 403, 'Invalid OptiID access token');
24
+ }
21
25
  }
22
26
  catch (error) {
27
+ if (error instanceof ToolError_1.ToolError) {
28
+ throw error;
29
+ }
23
30
  app_sdk_1.logger.error('OptiID token validation failed:', error);
24
- return false;
31
+ throw new ToolError_1.ToolError('Forbidden', 403, 'Token verification failed');
25
32
  }
26
33
  }
27
34
  /**
28
35
  * Extract and validate basic OptiID authentication data from request
29
36
  *
30
37
  * @param request - The incoming request
31
- * @returns object with authData and accessToken, or null if invalid
38
+ * @returns object with authData and accessToken, or null if auth is missing
32
39
  */
33
40
  function extractAuthData(request) {
34
41
  const authData = request?.bodyJSON?.auth;
42
+ if (!authData) {
43
+ return null;
44
+ }
45
+ if (authData?.provider?.toLowerCase() !== 'optiid') {
46
+ return null;
47
+ }
35
48
  const accessToken = authData?.credentials?.access_token;
36
- if (!accessToken || authData?.provider?.toLowerCase() !== 'optiid') {
49
+ if (!accessToken) {
37
50
  return null;
38
51
  }
39
52
  return { authData, accessToken };
40
53
  }
54
+ /**
55
+ * Extract and validate auth data with error throwing for authentication flow
56
+ *
57
+ * @param request - The incoming request
58
+ * @returns object with authData and accessToken
59
+ * @throws {ToolError} If auth data is invalid or missing
60
+ */
61
+ function extractAndValidateAuthData(request) {
62
+ const authData = request?.bodyJSON?.auth;
63
+ if (!authData) {
64
+ throw new ToolError_1.ToolError('Forbidden', 403, 'Authentication data is required');
65
+ }
66
+ if (authData?.provider?.toLowerCase() !== 'optiid') {
67
+ throw new ToolError_1.ToolError('Forbidden', 403, 'Only OptiID authentication provider is supported');
68
+ }
69
+ const accessToken = authData?.credentials?.access_token;
70
+ if (!accessToken) {
71
+ throw new ToolError_1.ToolError('Forbidden', 403, 'OptiID access token is required');
72
+ }
73
+ return { authData, accessToken };
74
+ }
41
75
  /**
42
76
  * Validate organization ID matches the app context
43
77
  *
44
78
  * @param customerId - The customer ID from the auth data
45
- * @returns true if the organization ID is valid
79
+ * @throws {ToolError} If organization ID is invalid or missing
46
80
  */
47
81
  function validateOrganizationId(customerId) {
48
82
  if (!customerId) {
49
83
  app_sdk_1.logger.error('Organisation ID is required but not provided');
50
- return false;
84
+ throw new ToolError_1.ToolError('Forbidden', 403, 'Organization ID is required');
51
85
  }
52
86
  const appOrganisationId = (0, app_sdk_1.getAppContext)()?.account?.organizationId;
53
87
  if (customerId !== appOrganisationId) {
54
88
  app_sdk_1.logger.error(`Invalid organisation ID: expected ${appOrganisationId}, received ${customerId}`);
55
- return false;
89
+ throw new ToolError_1.ToolError('Forbidden', 403, 'Organization ID does not match');
56
90
  }
57
- return true;
58
91
  }
59
92
  /**
60
93
  * Check if a request should skip authentication (discovery/ready endpoints)
@@ -70,40 +103,35 @@ function shouldSkipAuth(request) {
70
103
  *
71
104
  * @param request - The incoming request
72
105
  * @param validateOrg - Whether to validate organization ID
73
- * @returns true if authentication succeeds
106
+ * @throws {ToolError} If authentication fails
74
107
  */
75
108
  async function authenticateRequest(request, validateOrg) {
76
109
  if (shouldSkipAuth(request)) {
77
- return true;
78
- }
79
- const authInfo = extractAuthData(request);
80
- if (!authInfo) {
81
- app_sdk_1.logger.error('OptiID token is required but not provided');
82
- return false;
110
+ return;
83
111
  }
84
- const { authData, accessToken } = authInfo;
112
+ const { authData, accessToken } = extractAndValidateAuthData(request);
85
113
  // Validate organization ID if required
86
- if (validateOrg && !validateOrganizationId(authData.credentials?.customer_id)) {
87
- return false;
114
+ if (validateOrg) {
115
+ validateOrganizationId(authData.credentials?.customer_id);
88
116
  }
89
- return await validateAccessToken(accessToken);
117
+ await validateAccessToken(accessToken);
90
118
  }
91
119
  /**
92
120
  * Authenticate a request for regular functions (with organization validation)
93
121
  *
94
122
  * @param request - The incoming request
95
- * @returns true if authentication and authorization succeed
123
+ * @throws {ToolError} If authentication or authorization fails
96
124
  */
97
125
  async function authenticateRegularRequest(request) {
98
- return await authenticateRequest(request, true);
126
+ await authenticateRequest(request, true);
99
127
  }
100
128
  /**
101
129
  * Authenticate a request for global functions (without organization validation)
102
130
  *
103
131
  * @param request - The incoming request
104
- * @returns true if authentication succeeds
132
+ * @throws {ToolError} If authentication fails
105
133
  */
106
134
  async function authenticateGlobalRequest(request) {
107
- return await authenticateRequest(request, false);
135
+ await authenticateRequest(request, false);
108
136
  }
109
137
  //# sourceMappingURL=AuthUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AuthUtils.js","sourceRoot":"","sources":["../../src/auth/AuthUtils.ts"],"names":[],"mappings":";;AA6BA,0CAQC;AAmED,gEAEC;AAQD,8DAEC;AApHD,+CAA0D;AAC1D,mDAAmD;AAGnD;;;;;GAKG;AACH,KAAK,UAAU,mBAAmB,CAAC,WAA+B;IAChE,IAAI,CAAC;QACH,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,aAAa,GAAG,MAAM,IAAA,gCAAgB,GAAE,CAAC;QAC/C,OAAO,MAAM,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,gBAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;QACvD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAgB,eAAe,CAAC,OAAY;IAC1C,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,EAAE,IAAsB,CAAC;IAC3D,MAAM,WAAW,GAAG,QAAQ,EAAE,WAAW,EAAE,YAAY,CAAC;IACxD,IAAI,CAAC,WAAW,IAAI,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,QAAQ,EAAE,CAAC;QACnE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;AACnC,CAAC;AAED;;;;;GAKG;AACH,SAAS,sBAAsB,CAAC,UAA8B;IAC5D,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,gBAAM,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAC7D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,iBAAiB,GAAG,IAAA,uBAAa,GAAE,EAAE,OAAO,EAAE,cAAc,CAAC;IACnE,IAAI,UAAU,KAAK,iBAAiB,EAAE,CAAC;QACrC,gBAAM,CAAC,KAAK,CAAC,qCAAqC,iBAAiB,cAAc,UAAU,EAAE,CAAC,CAAC;QAC/F,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,SAAS,cAAc,CAAC,OAAY;IAClC,OAAO,OAAO,CAAC,IAAI,KAAK,YAAY,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC;AACpE,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,mBAAmB,CAAC,OAAY,EAAE,WAAoB;IACnE,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IAC1C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,gBAAM,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC1D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,QAAQ,CAAC;IAE3C,uCAAuC;IACvC,IAAI,WAAW,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC;QAC9E,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,MAAM,mBAAmB,CAAC,WAAW,CAAC,CAAC;AAChD,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,0BAA0B,CAAC,OAAY;IAC3D,OAAO,MAAM,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AAClD,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,yBAAyB,CAAC,OAAY;IAC1D,OAAO,MAAM,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AACnD,CAAC"}
1
+ {"version":3,"file":"AuthUtils.js","sourceRoot":"","sources":["../../src/auth/AuthUtils.ts"],"names":[],"mappings":"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"}