@optimizely-opal/opal-tools-sdk 0.1.2-dev → 0.1.5-dev

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/README.md CHANGED
@@ -9,6 +9,7 @@ This SDK simplifies the creation of tools services compatible with the Opal Tool
9
9
  - Parameter validation and type checking
10
10
  - Authentication helpers
11
11
  - Express integration
12
+ - Island components for interactive UI responses
12
13
 
13
14
  ## Installation
14
15
 
@@ -19,7 +20,7 @@ npm install @optimizely-opal/opal-tools-sdk
19
20
  ## Usage
20
21
 
21
22
  ```typescript
22
- import { ToolsService, tool } from '@optimizely-opal/opal-tools-sdk';
23
+ import { ToolsService, tool, IslandResponse, IslandConfig } from '@optimizely-opal/opal-tools-sdk';
23
24
  import express from 'express';
24
25
 
25
26
  const app = express();
@@ -121,6 +122,155 @@ async function getEmail(parameters: EmailParameters, authData?: any) {
121
122
  }
122
123
  ```
123
124
 
125
+ ## Authentication
126
+
127
+ The SDK provides authentication support for tools that require user credentials:
128
+
129
+ ```typescript
130
+ import { ToolsService, tool, requiresAuth, AuthData } from '@optimizely-opal/opal-tools-sdk';
131
+ import express from 'express';
132
+
133
+ interface CalendarParameters {
134
+ date: string;
135
+ timezone?: string;
136
+ }
137
+
138
+ const app = express();
139
+ const toolsService = new ToolsService(app);
140
+
141
+ @requiresAuth({ provider: 'google', scopeBundle: 'calendar', required: true })
142
+ @tool({
143
+ name: 'get_calendar_events',
144
+ description: 'Gets calendar events for a date'
145
+ })
146
+ async function getCalendarEvents(parameters: CalendarParameters, authData?: AuthData) {
147
+ // The authData parameter contains authentication information
148
+ if (authData) {
149
+ const token = authData.credentials.access_token;
150
+ // Use the token to make authenticated requests
151
+ }
152
+
153
+ return { events: ['Meeting at 10:00', 'Lunch at 12:00'] };
154
+ }
155
+ ```
156
+
157
+ ## Island Components
158
+
159
+ The SDK includes Island components for creating interactive UI responses:
160
+
161
+ ```typescript
162
+ import {
163
+ ToolsService,
164
+ tool,
165
+ IslandResponse,
166
+ IslandConfig
167
+ } from '@optimizely-opal/opal-tools-sdk';
168
+ import express from 'express';
169
+
170
+ interface WeatherParameters {
171
+ location: string;
172
+ units?: string;
173
+ }
174
+
175
+ const app = express();
176
+ const toolsService = new ToolsService(app);
177
+
178
+ @tool({
179
+ name: 'get_weather',
180
+ description: 'Gets current weather for a location'
181
+ })
182
+ async function getWeather(parameters: WeatherParameters) {
183
+ // Get weather data (implementation details omitted)
184
+ const weatherData = { temperature: 22, condition: 'sunny', humidity: 65 };
185
+
186
+ // Create an interactive island for weather settings
187
+ const island = new IslandConfig(
188
+ [
189
+ new IslandConfig.Field(
190
+ 'location',
191
+ 'Location',
192
+ 'string',
193
+ parameters.location
194
+ ),
195
+ new IslandConfig.Field(
196
+ 'units',
197
+ 'Temperature Units',
198
+ 'string',
199
+ parameters.units || 'metric',
200
+ false,
201
+ ['metric', 'imperial', 'kelvin']
202
+ ),
203
+ new IslandConfig.Field(
204
+ 'current_temp',
205
+ 'Current Temperature',
206
+ 'string',
207
+ `${weatherData.temperature}°${parameters.units === 'metric' ? 'C' : 'F'}`
208
+ )
209
+ ],
210
+ [
211
+ new IslandConfig.Action(
212
+ 'refresh_weather',
213
+ 'Refresh Weather',
214
+ 'button',
215
+ '/tools/get_weather',
216
+ 'update'
217
+ )
218
+ ],
219
+ 'button', // Optional island type
220
+ 'plus' // Optional island icon
221
+ );
222
+
223
+ return IslandResponse.create([island]);
224
+ }
225
+ ```
226
+
227
+ ### Island Components
228
+
229
+ #### IslandConfig.Field
230
+ Fields represent data inputs in the UI:
231
+ - `name`: Programmatic field identifier
232
+ - `label`: Human-readable label
233
+ - `type`: Field type (`'string'`, `'boolean'`, `'json'`)
234
+ - `value`: Current field value (optional)
235
+ - `hidden`: Whether to hide from user (optional, default: false)
236
+ - `options`: Available options for selection (optional)
237
+
238
+ #### IslandConfig.Action
239
+ Actions represent buttons or operations:
240
+ - `name`: Programmatic action identifier
241
+ - `label`: Human-readable button label
242
+ - `type`: UI element type (typically `'button'`)
243
+ - `endpoint`: API endpoint to call
244
+ - `operation`: Operation type (default: `'create'`)
245
+
246
+ #### IslandConfig
247
+ Contains the complete island configuration:
248
+ - `fields`: Array of IslandConfig.Field objects
249
+ - `actions`: Array of IslandConfig.Action objects
250
+ - `type`: Optional island type for custom rendering (optional)
251
+ - `icon`: Optional icon identifier for the island (optional)
252
+
253
+ #### IslandResponse
254
+ The response wrapper for islands:
255
+ - Use `IslandResponse.create([islands])` to create responses
256
+ - Supports multiple islands per response
257
+
258
+ ## Type Definitions
259
+
260
+ The SDK provides comprehensive TypeScript type definitions:
261
+
262
+ ### Authentication Types
263
+ - `AuthData`: Interface containing provider and credentials information
264
+ - `Credentials`: Interface with access_token, org_sso_id, customer_id, instance_id, and product_sku
265
+ - `Environment`: Interface specifying execution mode (`'headless'` or `'interactive'`)
266
+
267
+ ### Parameter Types
268
+ - `ParameterType`: Enum for supported parameter types
269
+ - `Parameter`: Class for tool parameter definitions
270
+ - `Function`: Class for complete tool function definitions
271
+
272
+ These types provide full IDE support and compile-time type checking for better development experience.
273
+
124
274
  ## Documentation
125
275
 
126
276
  See full documentation for more examples and configuration options.
package/dist/models.d.ts CHANGED
@@ -6,7 +6,7 @@ export declare enum ParameterType {
6
6
  Integer = "integer",
7
7
  Number = "number",
8
8
  Boolean = "boolean",
9
- List = "list",
9
+ List = "array",
10
10
  Dictionary = "object"
11
11
  }
12
12
  /**
@@ -85,3 +85,205 @@ export declare class Function {
85
85
  */
86
86
  toJSON(): any;
87
87
  }
88
+ /**
89
+ * Authentication credentials structure
90
+ */
91
+ export type Credentials = {
92
+ access_token: string;
93
+ org_sso_id?: string;
94
+ customer_id: string;
95
+ instance_id: string;
96
+ product_sku: string;
97
+ };
98
+ /**
99
+ * Authentication data for an Opal tool
100
+ */
101
+ export type AuthData = {
102
+ provider: string;
103
+ credentials: Credentials;
104
+ };
105
+ /**
106
+ * Execution environment for an Opal tool
107
+ */
108
+ export type Environment = {
109
+ execution_mode: "headless" | "interactive";
110
+ };
111
+ /**
112
+ * Island field definition for interactive UI components
113
+ */
114
+ export declare class IslandField {
115
+ name: string;
116
+ label: string;
117
+ type: "string" | "boolean" | "json";
118
+ value: string;
119
+ hidden: boolean;
120
+ options: string[];
121
+ /**
122
+ * Create a new island field
123
+ * @param name Programmatic field identifier
124
+ * @param label Human-readable label
125
+ * @param type Field type
126
+ * @param value Current field value
127
+ * @param hidden Whether to hide from user
128
+ * @param options Available options for selection
129
+ */
130
+ constructor(name: string, label: string, type: "string" | "boolean" | "json", value?: string, hidden?: boolean, options?: string[]);
131
+ /**
132
+ * Convert to JSON for the discovery endpoint
133
+ */
134
+ toJSON(): {
135
+ name: string;
136
+ label: string;
137
+ type: "string" | "boolean" | "json";
138
+ value: string;
139
+ hidden: boolean;
140
+ options: string[];
141
+ };
142
+ }
143
+ /**
144
+ * Island action definition for interactive UI components
145
+ */
146
+ export declare class IslandAction {
147
+ name: string;
148
+ label: string;
149
+ type: string;
150
+ endpoint: string;
151
+ operation: string;
152
+ /**
153
+ * Create a new island action
154
+ * @param name Programmatic action identifier
155
+ * @param label Human-readable button label
156
+ * @param type UI element type
157
+ * @param endpoint API endpoint to call
158
+ * @param operation Operation type
159
+ */
160
+ constructor(name: string, label: string, type: string, endpoint: string, operation?: string);
161
+ /**
162
+ * Convert to JSON for the discovery endpoint
163
+ */
164
+ toJSON(): {
165
+ name: string;
166
+ label: string;
167
+ type: string;
168
+ endpoint: string;
169
+ operation: string;
170
+ };
171
+ }
172
+ /**
173
+ * Island configuration for interactive UI components
174
+ */
175
+ export declare class IslandConfig {
176
+ fields: IslandField[];
177
+ actions: IslandAction[];
178
+ type?: string | undefined;
179
+ icon?: string | undefined;
180
+ static Field: typeof IslandField;
181
+ static Action: typeof IslandAction;
182
+ /**
183
+ * Create a new island configuration
184
+ * @param fields List of island fields
185
+ * @param actions List of island actions
186
+ * @param type Optional island type
187
+ * @param icon Optional island icon
188
+ */
189
+ constructor(fields: IslandField[], actions: IslandAction[], type?: string | undefined, icon?: string | undefined);
190
+ /**
191
+ * Convert to JSON for the discovery endpoint
192
+ */
193
+ toJSON(): {
194
+ fields: {
195
+ name: string;
196
+ label: string;
197
+ type: "string" | "boolean" | "json";
198
+ value: string;
199
+ hidden: boolean;
200
+ options: string[];
201
+ }[];
202
+ actions: {
203
+ name: string;
204
+ label: string;
205
+ type: string;
206
+ endpoint: string;
207
+ operation: string;
208
+ }[];
209
+ };
210
+ }
211
+ /**
212
+ * Island response configuration
213
+ */
214
+ export declare class IslandResponseConfig {
215
+ islands: IslandConfig[];
216
+ /**
217
+ * Create a new island response configuration
218
+ * @param islands List of island configurations
219
+ */
220
+ constructor(islands: IslandConfig[]);
221
+ /**
222
+ * Convert to JSON for the discovery endpoint
223
+ */
224
+ toJSON(): {
225
+ islands: {
226
+ fields: {
227
+ name: string;
228
+ label: string;
229
+ type: "string" | "boolean" | "json";
230
+ value: string;
231
+ hidden: boolean;
232
+ options: string[];
233
+ }[];
234
+ actions: {
235
+ name: string;
236
+ label: string;
237
+ type: string;
238
+ endpoint: string;
239
+ operation: string;
240
+ }[];
241
+ }[];
242
+ };
243
+ }
244
+ /**
245
+ * Island response wrapper for interactive UI components
246
+ */
247
+ export declare class IslandResponse {
248
+ config: IslandResponseConfig;
249
+ message?: string | undefined;
250
+ static ResponseConfig: typeof IslandResponseConfig;
251
+ type: "island";
252
+ /**
253
+ * Create a new island response
254
+ * @param config Response configuration
255
+ * @param message Optional message for the island response
256
+ */
257
+ constructor(config: IslandResponseConfig, message?: string | undefined);
258
+ /**
259
+ * Create an island response with a list of islands
260
+ * @param islands List of island configurations
261
+ * @param message Optional message for the island response
262
+ * @returns New IslandResponse instance
263
+ */
264
+ static create(islands: IslandConfig[], message?: string): IslandResponse;
265
+ /**
266
+ * Convert to JSON for the discovery endpoint
267
+ */
268
+ toJSON(): {
269
+ config: {
270
+ islands: {
271
+ fields: {
272
+ name: string;
273
+ label: string;
274
+ type: "string" | "boolean" | "json";
275
+ value: string;
276
+ hidden: boolean;
277
+ options: string[];
278
+ }[];
279
+ actions: {
280
+ name: string;
281
+ label: string;
282
+ type: string;
283
+ endpoint: string;
284
+ operation: string;
285
+ }[];
286
+ }[];
287
+ };
288
+ };
289
+ }
package/dist/models.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Function = exports.AuthRequirement = exports.Parameter = exports.ParameterType = void 0;
3
+ exports.IslandResponse = exports.IslandResponseConfig = exports.IslandConfig = exports.IslandAction = exports.IslandField = exports.Function = exports.AuthRequirement = exports.Parameter = exports.ParameterType = void 0;
4
4
  /**
5
5
  * Types of parameters supported by Opal tools
6
6
  */
@@ -10,7 +10,7 @@ var ParameterType;
10
10
  ParameterType["Integer"] = "integer";
11
11
  ParameterType["Number"] = "number";
12
12
  ParameterType["Boolean"] = "boolean";
13
- ParameterType["List"] = "list";
13
+ ParameterType["List"] = "array";
14
14
  ParameterType["Dictionary"] = "object";
15
15
  })(ParameterType || (exports.ParameterType = ParameterType = {}));
16
16
  /**
@@ -111,3 +111,157 @@ class Function {
111
111
  }
112
112
  }
113
113
  exports.Function = Function;
114
+ /**
115
+ * Island field definition for interactive UI components
116
+ */
117
+ class IslandField {
118
+ /**
119
+ * Create a new island field
120
+ * @param name Programmatic field identifier
121
+ * @param label Human-readable label
122
+ * @param type Field type
123
+ * @param value Current field value
124
+ * @param hidden Whether to hide from user
125
+ * @param options Available options for selection
126
+ */
127
+ constructor(name, label, type, value = "", hidden = false, options = []) {
128
+ this.name = name;
129
+ this.label = label;
130
+ this.type = type;
131
+ this.value = value;
132
+ this.hidden = hidden;
133
+ this.options = options;
134
+ }
135
+ /**
136
+ * Convert to JSON for the discovery endpoint
137
+ */
138
+ toJSON() {
139
+ return {
140
+ name: this.name,
141
+ label: this.label,
142
+ type: this.type,
143
+ value: this.value,
144
+ hidden: this.hidden,
145
+ options: this.options,
146
+ };
147
+ }
148
+ }
149
+ exports.IslandField = IslandField;
150
+ /**
151
+ * Island action definition for interactive UI components
152
+ */
153
+ class IslandAction {
154
+ /**
155
+ * Create a new island action
156
+ * @param name Programmatic action identifier
157
+ * @param label Human-readable button label
158
+ * @param type UI element type
159
+ * @param endpoint API endpoint to call
160
+ * @param operation Operation type
161
+ */
162
+ constructor(name, label, type, endpoint, operation = "create") {
163
+ this.name = name;
164
+ this.label = label;
165
+ this.type = type;
166
+ this.endpoint = endpoint;
167
+ this.operation = operation;
168
+ }
169
+ /**
170
+ * Convert to JSON for the discovery endpoint
171
+ */
172
+ toJSON() {
173
+ return {
174
+ name: this.name,
175
+ label: this.label,
176
+ type: this.type,
177
+ endpoint: this.endpoint,
178
+ operation: this.operation,
179
+ };
180
+ }
181
+ }
182
+ exports.IslandAction = IslandAction;
183
+ /**
184
+ * Island configuration for interactive UI components
185
+ */
186
+ class IslandConfig {
187
+ /**
188
+ * Create a new island configuration
189
+ * @param fields List of island fields
190
+ * @param actions List of island actions
191
+ * @param type Optional island type
192
+ * @param icon Optional island icon
193
+ */
194
+ constructor(fields, actions, type, icon) {
195
+ this.fields = fields;
196
+ this.actions = actions;
197
+ this.type = type;
198
+ this.icon = icon;
199
+ }
200
+ /**
201
+ * Convert to JSON for the discovery endpoint
202
+ */
203
+ toJSON() {
204
+ return {
205
+ fields: this.fields.map((field) => field.toJSON()),
206
+ actions: this.actions.map((action) => action.toJSON()),
207
+ };
208
+ }
209
+ }
210
+ exports.IslandConfig = IslandConfig;
211
+ IslandConfig.Field = IslandField;
212
+ IslandConfig.Action = IslandAction;
213
+ /**
214
+ * Island response configuration
215
+ */
216
+ class IslandResponseConfig {
217
+ /**
218
+ * Create a new island response configuration
219
+ * @param islands List of island configurations
220
+ */
221
+ constructor(islands) {
222
+ this.islands = islands;
223
+ }
224
+ /**
225
+ * Convert to JSON for the discovery endpoint
226
+ */
227
+ toJSON() {
228
+ return {
229
+ islands: this.islands.map((island) => island.toJSON()),
230
+ };
231
+ }
232
+ }
233
+ exports.IslandResponseConfig = IslandResponseConfig;
234
+ /**
235
+ * Island response wrapper for interactive UI components
236
+ */
237
+ class IslandResponse {
238
+ /**
239
+ * Create a new island response
240
+ * @param config Response configuration
241
+ * @param message Optional message for the island response
242
+ */
243
+ constructor(config, message) {
244
+ this.config = config;
245
+ this.message = message;
246
+ this.type = "island";
247
+ }
248
+ /**
249
+ * Create an island response with a list of islands
250
+ * @param islands List of island configurations
251
+ * @param message Optional message for the island response
252
+ * @returns New IslandResponse instance
253
+ */
254
+ static create(islands, message) {
255
+ return new IslandResponse(new IslandResponseConfig(islands), message);
256
+ }
257
+ /**
258
+ * Convert to JSON for the discovery endpoint
259
+ */
260
+ toJSON() {
261
+ return {
262
+ config: this.config.toJSON(),
263
+ };
264
+ }
265
+ }
266
+ exports.IslandResponse = IslandResponse;
267
+ IslandResponse.ResponseConfig = IslandResponseConfig;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optimizely-opal/opal-tools-sdk",
3
- "version": "0.1.2-dev",
3
+ "version": "0.1.5-dev",
4
4
  "description": "SDK for creating Opal-compatible tools services",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -19,19 +19,18 @@
19
19
  "author": "Optimizely",
20
20
  "license": "MIT",
21
21
  "dependencies": {
22
- "express": "^4.18.2",
23
- "axios": "^1.6.0",
24
22
  "reflect-metadata": "^0.1.13"
25
23
  },
26
24
  "devDependencies": {
27
- "@types/express": "^4.17.17",
28
25
  "@types/jest": "^29.5.3",
29
- "@types/node": "^20.4.5",
30
26
  "jest": "^29.6.2",
31
- "ts-jest": "^29.1.1",
32
- "typescript": "^5.1.6"
27
+ "ts-jest": "^29.1.1"
33
28
  },
34
29
  "peerDependencies": {
30
+ "typescript": "^5.1.6",
31
+ "@types/node": "^20.4.5",
32
+ "@types/express": "^4.17.17",
33
+ "axios": "^1.6.0",
35
34
  "express": "^4.18.2"
36
35
  },
37
36
  "repository": {
package/src/decorators.ts CHANGED
@@ -36,7 +36,7 @@ function mapTypeToParameterType(type: any): ParameterType {
36
36
  } else if (type === Object || type.name === 'Object') {
37
37
  return ParameterType.Dictionary;
38
38
  }
39
-
39
+
40
40
  // Default to string
41
41
  return ParameterType.String;
42
42
  }
@@ -47,14 +47,14 @@ function mapTypeToParameterType(type: any): ParameterType {
47
47
  */
48
48
  function extractParameters(paramType: any): Parameter[] {
49
49
  const parameters: Parameter[] = [];
50
-
50
+
51
51
  // This is very basic and doesn't handle complex types
52
52
  // For production use, this would need to be more sophisticated
53
53
  for (const key in paramType) {
54
54
  if (paramType.hasOwnProperty(key)) {
55
55
  const type = typeof paramType[key] === 'undefined' ? String : paramType[key].constructor;
56
56
  const required = true; // In a real implementation, we'd detect optional parameters
57
-
57
+
58
58
  parameters.push(new Parameter(
59
59
  key,
60
60
  mapTypeToParameterType(type),
@@ -63,7 +63,7 @@ function extractParameters(paramType: any): Parameter[] {
63
63
  ));
64
64
  }
65
65
  }
66
-
66
+
67
67
  return parameters;
68
68
  }
69
69
 
@@ -72,10 +72,10 @@ function extractParameters(paramType: any): Parameter[] {
72
72
  * @param options Tool options including:
73
73
  * - name: Name of the tool
74
74
  * - description: Description of the tool
75
- * - authRequirements: (Optional) Authentication requirements
75
+ * - authRequirements: (Optional) Authentication requirements
76
76
  * Format: { provider: "oauth_provider", scopeBundle: "permissions_scope", required: true }
77
77
  * Example: { provider: "google", scopeBundle: "calendar", required: true }
78
- *
78
+ *
79
79
  * Note: If your tool requires authentication, define your handler function with two parameters:
80
80
  * ```
81
81
  * async function myTool(parameters: ParameterInterface, authData?: any): Promise<any> {
@@ -87,10 +87,10 @@ export function tool(options: ToolOptions) {
87
87
  return function(target: any, propertyKey?: string, descriptor?: PropertyDescriptor) {
88
88
  const isMethod = propertyKey && descriptor;
89
89
  const handler = isMethod ? descriptor.value : target;
90
-
90
+
91
91
  // Generate endpoint from name - ensure hyphens instead of underscores
92
92
  const endpoint = `/tools/${options.name.replace(/_/g, '-')}`;
93
-
93
+
94
94
  // Convert parameter definitions to Parameter objects
95
95
  const parameters: Parameter[] = [];
96
96
  if (options.parameters && options.parameters.length > 0) {
@@ -104,7 +104,7 @@ export function tool(options: ToolOptions) {
104
104
  ));
105
105
  }
106
106
  }
107
-
107
+
108
108
  // Create auth requirements if specified
109
109
  let authRequirements: AuthRequirement[] | undefined;
110
110
  if (options.authRequirements) {
@@ -116,7 +116,7 @@ export function tool(options: ToolOptions) {
116
116
  )
117
117
  ];
118
118
  }
119
-
119
+
120
120
  // Register the tool with all services
121
121
  for (const service of registry.services) {
122
122
  service.registerTool(
@@ -128,7 +128,7 @@ export function tool(options: ToolOptions) {
128
128
  authRequirements
129
129
  );
130
130
  }
131
-
131
+
132
132
  return isMethod ? descriptor : target;
133
133
  };
134
134
  }
package/src/models.ts CHANGED
@@ -6,7 +6,7 @@ export enum ParameterType {
6
6
  Integer = 'integer',
7
7
  Number = 'number',
8
8
  Boolean = 'boolean',
9
- List = 'list',
9
+ List = 'array',
10
10
  Dictionary = 'object'
11
11
  }
12
12
 
@@ -113,3 +113,190 @@ export class Function {
113
113
  return result;
114
114
  }
115
115
  }
116
+
117
+ /**
118
+ * Authentication credentials structure
119
+ */
120
+ export type Credentials ={
121
+ access_token: string;
122
+ org_sso_id?: string;
123
+ customer_id: string;
124
+ instance_id: string;
125
+ product_sku: string;
126
+ }
127
+
128
+ /**
129
+ * Authentication data for an Opal tool
130
+ */
131
+ export type AuthData = {
132
+ provider: string;
133
+ credentials: Credentials;
134
+ }
135
+
136
+ /**
137
+ * Execution environment for an Opal tool
138
+ */
139
+ export type Environment = {
140
+ execution_mode: "headless" | "interactive";
141
+ }
142
+
143
+ /**
144
+ * Island field definition for interactive UI components
145
+ */
146
+ export class IslandField {
147
+ /**
148
+ * Create a new island field
149
+ * @param name Programmatic field identifier
150
+ * @param label Human-readable label
151
+ * @param type Field type
152
+ * @param value Current field value
153
+ * @param hidden Whether to hide from user
154
+ * @param options Available options for selection
155
+ */
156
+ constructor(
157
+ public name: string,
158
+ public label: string,
159
+ public type: "string" | "boolean" | "json",
160
+ public value: string = "",
161
+ public hidden: boolean = false,
162
+ public options: string[] = []
163
+ ) {}
164
+
165
+ /**
166
+ * Convert to JSON for the discovery endpoint
167
+ */
168
+ toJSON() {
169
+ return {
170
+ name: this.name,
171
+ label: this.label,
172
+ type: this.type,
173
+ value: this.value,
174
+ hidden: this.hidden,
175
+ options: this.options,
176
+ };
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Island action definition for interactive UI components
182
+ */
183
+ export class IslandAction {
184
+ /**
185
+ * Create a new island action
186
+ * @param name Programmatic action identifier
187
+ * @param label Human-readable button label
188
+ * @param type UI element type
189
+ * @param endpoint API endpoint to call
190
+ * @param operation Operation type
191
+ */
192
+ constructor(
193
+ public name: string,
194
+ public label: string,
195
+ public type: string,
196
+ public endpoint: string,
197
+ public operation: string = "create"
198
+ ) {}
199
+
200
+ /**
201
+ * Convert to JSON for the discovery endpoint
202
+ */
203
+ toJSON() {
204
+ return {
205
+ name: this.name,
206
+ label: this.label,
207
+ type: this.type,
208
+ endpoint: this.endpoint,
209
+ operation: this.operation,
210
+ };
211
+ }
212
+ }
213
+
214
+ /**
215
+ * Island configuration for interactive UI components
216
+ */
217
+ export class IslandConfig {
218
+ static Field = IslandField;
219
+ static Action = IslandAction;
220
+
221
+ /**
222
+ * Create a new island configuration
223
+ * @param fields List of island fields
224
+ * @param actions List of island actions
225
+ * @param type Optional island type
226
+ * @param icon Optional island icon
227
+ */
228
+ constructor(
229
+ public fields: IslandField[],
230
+ public actions: IslandAction[],
231
+ public type?: string,
232
+ public icon?: string
233
+ ) {}
234
+
235
+ /**
236
+ * Convert to JSON for the discovery endpoint
237
+ */
238
+ toJSON() {
239
+ return {
240
+ fields: this.fields.map((field) => field.toJSON()),
241
+ actions: this.actions.map((action) => action.toJSON()),
242
+ };
243
+ }
244
+ }
245
+
246
+ /**
247
+ * Island response configuration
248
+ */
249
+ export class IslandResponseConfig {
250
+ /**
251
+ * Create a new island response configuration
252
+ * @param islands List of island configurations
253
+ */
254
+ constructor(public islands: IslandConfig[]) {}
255
+
256
+ /**
257
+ * Convert to JSON for the discovery endpoint
258
+ */
259
+ toJSON() {
260
+ return {
261
+ islands: this.islands.map((island) => island.toJSON()),
262
+ };
263
+ }
264
+ }
265
+
266
+ /**
267
+ * Island response wrapper for interactive UI components
268
+ */
269
+ export class IslandResponse {
270
+ static ResponseConfig = IslandResponseConfig;
271
+
272
+ public type: "island" = "island";
273
+
274
+ /**
275
+ * Create a new island response
276
+ * @param config Response configuration
277
+ * @param message Optional message for the island response
278
+ */
279
+ constructor(
280
+ public config: IslandResponseConfig,
281
+ public message?: string
282
+ ) {}
283
+
284
+ /**
285
+ * Create an island response with a list of islands
286
+ * @param islands List of island configurations
287
+ * @param message Optional message for the island response
288
+ * @returns New IslandResponse instance
289
+ */
290
+ static create(islands: IslandConfig[], message?: string): IslandResponse {
291
+ return new IslandResponse(new IslandResponseConfig(islands), message);
292
+ }
293
+
294
+ /**
295
+ * Convert to JSON for the discovery endpoint
296
+ */
297
+ toJSON() {
298
+ return {
299
+ config: this.config.toJSON(),
300
+ };
301
+ }
302
+ }