@optimizely-opal/opal-tool-ocp-sdk 1.1.0-beta.1 → 1.1.0-beta.2

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.
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable max-classes-per-file */
2
- import { AuthRequirement, IslandResponse, Parameter } from '../types/Models';
2
+ import { AuthRequirement, IslandResponse, OAuthAuthData, OptiIdAuthData, Parameter } from '../types/Models';
3
3
  import { ToolError } from '../types/ToolError';
4
4
  import * as App from '@zaiusinc/app-sdk';
5
5
  import { logger, getAppContext } from '@zaiusinc/app-sdk';
@@ -53,14 +53,14 @@ export class InteractionResult {
53
53
  /**
54
54
  * Interaction definition for an Opal interaction
55
55
  */
56
- export class Interaction<TAuthData> {
56
+ export class Interaction {
57
57
  public constructor(
58
58
  public name: string,
59
59
  public endpoint: string,
60
60
  public handler: (
61
61
  functionContext: ToolFunction | GlobalToolFunction,
62
62
  data: unknown,
63
- authData?: TAuthData
63
+ authData: OptiIdAuthData | OAuthAuthData
64
64
  ) => Promise<InteractionResult>
65
65
  ) {}
66
66
  }
@@ -68,7 +68,7 @@ export class Interaction<TAuthData> {
68
68
  /**
69
69
  * Tool definition for an Opal tool
70
70
  */
71
- export class Tool<TAuthData> {
71
+ export class Tool {
72
72
  /**
73
73
  * HTTP method for the endpoint (default: POST)
74
74
  */
@@ -91,7 +91,7 @@ export class Tool<TAuthData> {
91
91
  public handler: (
92
92
  functionContext: ToolFunction | GlobalToolFunction,
93
93
  params: unknown,
94
- authData?: TAuthData
94
+ authData: OptiIdAuthData | OAuthAuthData
95
95
  ) => Promise<unknown>,
96
96
  public authRequirements: AuthRequirement[] = [DEFAULT_OPTIID_AUTH]
97
97
  ) {}
@@ -114,8 +114,8 @@ export class Tool<TAuthData> {
114
114
  }
115
115
 
116
116
  export class ToolsService {
117
- private functions: Map<string, Tool<any>> = new Map();
118
- private interactions: Map<string, Interaction<any>> = new Map();
117
+ private functions: Map<string, Tool> = new Map();
118
+ private interactions: Map<string, Interaction> = new Map();
119
119
 
120
120
  /**
121
121
  * Generate KV store key for tool overrides
@@ -144,7 +144,7 @@ export class ToolsService {
144
144
  * @param overrides Override data
145
145
  * @returns Tools with overrides applied
146
146
  */
147
- private applyOverrides(tools: Array<Tool<any>>, overrides: StoredOverrides): Array<Tool<any>> {
147
+ private applyOverrides(tools: Tool[], overrides: StoredOverrides): Tool[] {
148
148
  return tools.map((tool) => {
149
149
  const override = overrides[tool.name];
150
150
  if (!override) {
@@ -207,7 +207,7 @@ export class ToolsService {
207
207
  * @param functionName Function name
208
208
  * @returns Tool definitions with overrides applied
209
209
  */
210
- public async getToolsWithOverrides(appVersionId: string, functionName: string): Promise<Array<Tool<any>>> {
210
+ public async getToolsWithOverrides(appVersionId: string, functionName: string): Promise<Tool[]> {
211
211
  const tools = Array.from(this.functions.values());
212
212
  const overrides = await this.getOverrides(appVersionId, functionName);
213
213
 
@@ -259,20 +259,20 @@ export class ToolsService {
259
259
  * @param endpoint API endpoint for the tool
260
260
  * @param authRequirements Authentication requirements (optional - defaults to OptiID if not specified)
261
261
  */
262
- public registerTool<TAuthData>(
262
+ public registerTool(
263
263
  name: string,
264
264
  description: string,
265
265
  handler: (
266
266
  functionContext: ToolFunction | GlobalToolFunction,
267
267
  params: unknown,
268
- authData?: TAuthData
268
+ authData: OptiIdAuthData | OAuthAuthData
269
269
  ) => Promise<unknown>,
270
270
  parameters: Parameter[],
271
271
  endpoint: string,
272
272
  authRequirements?: AuthRequirement[]
273
273
  ): void {
274
274
  const resolvedAuthRequirements = this.withDefaultAuthRequirements(authRequirements);
275
- const func = new Tool<TAuthData>(
275
+ const func = new Tool(
276
276
  name,
277
277
  description,
278
278
  parameters,
@@ -289,16 +289,16 @@ export class ToolsService {
289
289
  * @param handler Function implementing the tool
290
290
  * @param endpoint API endpoint for the tool
291
291
  */
292
- public registerInteraction<TAuthData>(
292
+ public registerInteraction(
293
293
  name: string,
294
294
  handler: (
295
295
  functionContext: ToolFunction | GlobalToolFunction,
296
296
  data: unknown,
297
- authData?: TAuthData
297
+ authData: OptiIdAuthData | OAuthAuthData
298
298
  ) => Promise<InteractionResult>,
299
299
  endpoint: string
300
300
  ): void {
301
- const func = new Interaction<TAuthData>(name, endpoint, handler);
301
+ const func = new Interaction(name, endpoint, handler);
302
302
  this.interactions.set(endpoint, func);
303
303
  }
304
304
 
@@ -330,12 +330,17 @@ export class ToolsService {
330
330
 
331
331
  // Extract auth data from body JSON
332
332
  const authData = req.bodyJSON?.auth;
333
+
334
+ // Validate auth data is present if tool has auth requirements
335
+ if (func.authRequirements.length > 0 && !authData) {
336
+ throw new ToolError('Authentication data is required', 403);
337
+ }
338
+
333
339
  const result = await func.handler(functionContext, params, authData);
334
340
  return new App.Response(200, result);
335
341
  }
336
342
 
337
343
  // Handle interactions
338
- // Auth is already validated by the function layer
339
344
  const interaction = this.interactions.get(req.path);
340
345
  if (interaction) {
341
346
  const params = req.bodyJSON?.data ?? req.bodyJSON;
@@ -343,6 +348,11 @@ export class ToolsService {
343
348
  // Extract auth data from body JSON
344
349
  const authData = req.bodyJSON?.auth;
345
350
 
351
+ // Interactions always require auth
352
+ if (!authData) {
353
+ throw new ToolError('Authentication data is required', 403);
354
+ }
355
+
346
356
  const result = await interaction.handler(functionContext, params, authData);
347
357
  return new App.Response(200, result);
348
358
  }
@@ -43,29 +43,38 @@ export class Parameter {
43
43
  }
44
44
 
45
45
  /**
46
- * Credentials structure
46
+ * Credentials structure ofr OptiID provider
47
47
  */
48
- export class OptiIdAuthDataCredentials {
48
+ export interface OptiIdAuthDataCredentials {
49
+ customer_id: string;
50
+ instance_id: string;
51
+ access_token: string;
52
+ product_sku: string;
53
+ }
49
54
 
50
- public constructor(
51
- public customer_id: string,
52
- public instance_id: string,
53
- public access_token: string,
54
- public product_sku: string
55
- ) {}
55
+ /**
56
+ * Credentials structure for OAuth providers
57
+ */
58
+ export interface OAuthProviderAuthDataCredentials {
59
+ access_token: string;
60
+ token_type: string;
61
+ expires_at: string;
56
62
  }
57
63
 
64
+ export interface OptiIdAuthData {
65
+ provider: 'OptiID';
66
+ credentials: OptiIdAuthDataCredentials;
67
+ }
68
+
69
+ export interface OAuthAuthData {
70
+ provider: string;
71
+ credentials: OAuthProviderAuthDataCredentials;
72
+ }
58
73
 
59
74
  /**
60
75
  * Auth data structure
61
76
  */
62
- export class OptiIdAuthData {
63
-
64
- public constructor(
65
- public provider: string,
66
- public credentials: OptiIdAuthDataCredentials
67
- ) {}
68
- }
77
+ export type AuthData = OptiIdAuthData | OAuthAuthData;
69
78
 
70
79
  /**
71
80
  * Authentication requirements for an Opal tool