@friggframework/admin-scripts 2.0.0--canary.522.cbd3d5a.0 → 2.0.0--canary.517.21b69ac.0
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/PR_517_REVIEW_TRACKER.md +56 -0
- package/index.js +12 -3
- package/package.json +6 -9
- package/src/application/__tests__/admin-frigg-commands.test.js +19 -19
- package/src/application/__tests__/admin-script-base.test.js +100 -84
- package/src/application/__tests__/script-runner.test.js +146 -16
- package/src/application/admin-frigg-commands.js +20 -32
- package/src/application/admin-script-base.js +20 -99
- package/src/application/script-runner.js +131 -135
- package/src/application/use-cases/__tests__/delete-schedule-use-case.test.js +168 -0
- package/src/application/use-cases/__tests__/get-effective-schedule-use-case.test.js +114 -0
- package/src/application/use-cases/__tests__/upsert-schedule-use-case.test.js +201 -0
- package/src/application/use-cases/delete-schedule-use-case.js +108 -0
- package/src/application/use-cases/get-effective-schedule-use-case.js +78 -0
- package/src/application/use-cases/index.js +18 -0
- package/src/application/use-cases/upsert-schedule-use-case.js +127 -0
- package/src/builtins/__tests__/integration-health-check.test.js +67 -60
- package/src/builtins/__tests__/oauth-token-refresh.test.js +45 -37
- package/src/builtins/integration-health-check.js +23 -24
- package/src/builtins/oauth-token-refresh.js +19 -20
- package/src/infrastructure/__tests__/admin-auth-middleware.test.js +32 -95
- package/src/infrastructure/__tests__/admin-script-router.test.js +46 -47
- package/src/infrastructure/admin-auth-middleware.js +5 -43
- package/src/infrastructure/admin-script-router.js +38 -32
- package/src/infrastructure/script-executor-handler.js +2 -2
- package/src/application/__tests__/dry-run-http-interceptor.test.js +0 -313
- package/src/application/__tests__/dry-run-repository-wrapper.test.js +0 -257
- package/src/application/__tests__/schedule-management-use-case.test.js +0 -276
- package/src/application/dry-run-http-interceptor.js +0 -296
- package/src/application/dry-run-repository-wrapper.js +0 -261
- package/src/application/schedule-management-use-case.js +0 -230
|
@@ -23,7 +23,7 @@ describe('ScriptRunner', () => {
|
|
|
23
23
|
config: {
|
|
24
24
|
timeout: 300000,
|
|
25
25
|
maxRetries: 0,
|
|
26
|
-
|
|
26
|
+
requireIntegrationInstance: false,
|
|
27
27
|
},
|
|
28
28
|
};
|
|
29
29
|
|
|
@@ -36,9 +36,9 @@ describe('ScriptRunner', () => {
|
|
|
36
36
|
scriptFactory = new ScriptFactory([TestScript]);
|
|
37
37
|
|
|
38
38
|
mockCommands = {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
createAdminProcess: jest.fn(),
|
|
40
|
+
updateAdminProcessState: jest.fn(),
|
|
41
|
+
completeAdminProcess: jest.fn(),
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
mockFrigg = {
|
|
@@ -49,11 +49,11 @@ describe('ScriptRunner', () => {
|
|
|
49
49
|
createAdminScriptCommands.mockReturnValue(mockCommands);
|
|
50
50
|
createAdminFriggCommands.mockReturnValue(mockFrigg);
|
|
51
51
|
|
|
52
|
-
mockCommands.
|
|
52
|
+
mockCommands.createAdminProcess.mockResolvedValue({
|
|
53
53
|
id: 'exec-123',
|
|
54
54
|
});
|
|
55
|
-
mockCommands.
|
|
56
|
-
mockCommands.
|
|
55
|
+
mockCommands.updateAdminProcessState.mockResolvedValue({});
|
|
56
|
+
mockCommands.completeAdminProcess.mockResolvedValue({ success: true });
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
afterEach(() => {
|
|
@@ -76,7 +76,7 @@ describe('ScriptRunner', () => {
|
|
|
76
76
|
expect(result.executionId).toBe('exec-123');
|
|
77
77
|
expect(result.metrics.durationMs).toBeGreaterThanOrEqual(0);
|
|
78
78
|
|
|
79
|
-
expect(mockCommands.
|
|
79
|
+
expect(mockCommands.createAdminProcess).toHaveBeenCalledWith({
|
|
80
80
|
scriptName: 'test-script',
|
|
81
81
|
scriptVersion: '1.0.0',
|
|
82
82
|
trigger: 'MANUAL',
|
|
@@ -85,15 +85,15 @@ describe('ScriptRunner', () => {
|
|
|
85
85
|
audit: { apiKeyName: 'test-key' },
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
-
expect(mockCommands.
|
|
88
|
+
expect(mockCommands.updateAdminProcessState).toHaveBeenCalledWith(
|
|
89
89
|
'exec-123',
|
|
90
90
|
'RUNNING'
|
|
91
91
|
);
|
|
92
92
|
|
|
93
|
-
expect(mockCommands.
|
|
93
|
+
expect(mockCommands.completeAdminProcess).toHaveBeenCalledWith(
|
|
94
94
|
'exec-123',
|
|
95
95
|
expect.objectContaining({
|
|
96
|
-
|
|
96
|
+
state: 'COMPLETED',
|
|
97
97
|
output: { success: true, params: { foo: 'bar' } },
|
|
98
98
|
metrics: expect.objectContaining({
|
|
99
99
|
durationMs: expect.any(Number),
|
|
@@ -128,10 +128,10 @@ describe('ScriptRunner', () => {
|
|
|
128
128
|
expect(result.scriptName).toBe('failing-script');
|
|
129
129
|
expect(result.error.message).toBe('Script failed');
|
|
130
130
|
|
|
131
|
-
expect(mockCommands.
|
|
131
|
+
expect(mockCommands.completeAdminProcess).toHaveBeenCalledWith(
|
|
132
132
|
'exec-123',
|
|
133
133
|
expect.objectContaining({
|
|
134
|
-
|
|
134
|
+
state: 'FAILED',
|
|
135
135
|
error: expect.objectContaining({
|
|
136
136
|
message: 'Script failed',
|
|
137
137
|
}),
|
|
@@ -146,7 +146,7 @@ describe('ScriptRunner', () => {
|
|
|
146
146
|
version: '1.0.0',
|
|
147
147
|
description: 'Integration script',
|
|
148
148
|
config: {
|
|
149
|
-
|
|
149
|
+
requireIntegrationInstance: true,
|
|
150
150
|
},
|
|
151
151
|
};
|
|
152
152
|
|
|
@@ -178,14 +178,144 @@ describe('ScriptRunner', () => {
|
|
|
178
178
|
});
|
|
179
179
|
|
|
180
180
|
expect(result.executionId).toBe('existing-exec-456');
|
|
181
|
-
expect(mockCommands.
|
|
182
|
-
expect(mockCommands.
|
|
181
|
+
expect(mockCommands.createAdminProcess).not.toHaveBeenCalled();
|
|
182
|
+
expect(mockCommands.updateAdminProcessState).toHaveBeenCalledWith(
|
|
183
183
|
'existing-exec-456',
|
|
184
184
|
'RUNNING'
|
|
185
185
|
);
|
|
186
186
|
});
|
|
187
187
|
});
|
|
188
188
|
|
|
189
|
+
describe('dry-run mode', () => {
|
|
190
|
+
it('should return preview without executing script', async () => {
|
|
191
|
+
const runner = new ScriptRunner({ scriptFactory, commands: mockCommands });
|
|
192
|
+
|
|
193
|
+
const result = await runner.execute('test-script', { foo: 'bar' }, {
|
|
194
|
+
trigger: 'MANUAL',
|
|
195
|
+
dryRun: true,
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
expect(result.dryRun).toBe(true);
|
|
199
|
+
expect(result.status).toBe('DRY_RUN_VALID');
|
|
200
|
+
expect(result.scriptName).toBe('test-script');
|
|
201
|
+
expect(result.preview.script.name).toBe('test-script');
|
|
202
|
+
expect(result.preview.script.version).toBe('1.0.0');
|
|
203
|
+
expect(result.preview.input).toEqual({ foo: 'bar' });
|
|
204
|
+
expect(result.message).toContain('validation passed');
|
|
205
|
+
|
|
206
|
+
// Should NOT create execution record or call commands
|
|
207
|
+
expect(mockCommands.createAdminProcess).not.toHaveBeenCalled();
|
|
208
|
+
expect(mockCommands.updateAdminProcessState).not.toHaveBeenCalled();
|
|
209
|
+
expect(mockCommands.completeAdminProcess).not.toHaveBeenCalled();
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it('should validate required parameters in dry-run', async () => {
|
|
213
|
+
class SchemaScript extends AdminScriptBase {
|
|
214
|
+
static Definition = {
|
|
215
|
+
name: 'schema-script',
|
|
216
|
+
version: '1.0.0',
|
|
217
|
+
description: 'Script with schema',
|
|
218
|
+
inputSchema: {
|
|
219
|
+
type: 'object',
|
|
220
|
+
required: ['requiredParam'],
|
|
221
|
+
properties: {
|
|
222
|
+
requiredParam: { type: 'string' },
|
|
223
|
+
optionalParam: { type: 'number' },
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
async execute() {
|
|
229
|
+
return {};
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
scriptFactory.register(SchemaScript);
|
|
234
|
+
const runner = new ScriptRunner({ scriptFactory, commands: mockCommands });
|
|
235
|
+
|
|
236
|
+
// Missing required parameter
|
|
237
|
+
const result = await runner.execute('schema-script', {}, {
|
|
238
|
+
dryRun: true,
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
expect(result.status).toBe('DRY_RUN_INVALID');
|
|
242
|
+
expect(result.preview.validation.valid).toBe(false);
|
|
243
|
+
expect(result.preview.validation.errors).toContain('Missing required parameter: requiredParam');
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('should validate parameter types in dry-run', async () => {
|
|
247
|
+
class TypedScript extends AdminScriptBase {
|
|
248
|
+
static Definition = {
|
|
249
|
+
name: 'typed-script',
|
|
250
|
+
version: '1.0.0',
|
|
251
|
+
description: 'Script with typed params',
|
|
252
|
+
inputSchema: {
|
|
253
|
+
type: 'object',
|
|
254
|
+
properties: {
|
|
255
|
+
count: { type: 'integer' },
|
|
256
|
+
name: { type: 'string' },
|
|
257
|
+
enabled: { type: 'boolean' },
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
async execute() {
|
|
263
|
+
return {};
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
scriptFactory.register(TypedScript);
|
|
268
|
+
const runner = new ScriptRunner({ scriptFactory, commands: mockCommands });
|
|
269
|
+
|
|
270
|
+
const result = await runner.execute('typed-script', {
|
|
271
|
+
count: 'not-a-number',
|
|
272
|
+
name: 123,
|
|
273
|
+
enabled: 'true',
|
|
274
|
+
}, {
|
|
275
|
+
dryRun: true,
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
expect(result.status).toBe('DRY_RUN_INVALID');
|
|
279
|
+
expect(result.preview.validation.errors).toHaveLength(3);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it('should pass validation with correct parameters', async () => {
|
|
283
|
+
class ValidScript extends AdminScriptBase {
|
|
284
|
+
static Definition = {
|
|
285
|
+
name: 'valid-script',
|
|
286
|
+
version: '1.0.0',
|
|
287
|
+
description: 'Script for validation',
|
|
288
|
+
inputSchema: {
|
|
289
|
+
type: 'object',
|
|
290
|
+
required: ['name'],
|
|
291
|
+
properties: {
|
|
292
|
+
name: { type: 'string' },
|
|
293
|
+
count: { type: 'integer' },
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
async execute() {
|
|
299
|
+
return {};
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
scriptFactory.register(ValidScript);
|
|
304
|
+
const runner = new ScriptRunner({ scriptFactory, commands: mockCommands });
|
|
305
|
+
|
|
306
|
+
const result = await runner.execute('valid-script', {
|
|
307
|
+
name: 'test',
|
|
308
|
+
count: 42,
|
|
309
|
+
}, {
|
|
310
|
+
dryRun: true,
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
expect(result.status).toBe('DRY_RUN_VALID');
|
|
314
|
+
expect(result.preview.validation.valid).toBe(true);
|
|
315
|
+
expect(result.preview.validation.errors).toHaveLength(0);
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
|
|
189
319
|
describe('createScriptRunner()', () => {
|
|
190
320
|
it('should create runner with default factory', () => {
|
|
191
321
|
const runner = createScriptRunner();
|
|
@@ -1,18 +1,6 @@
|
|
|
1
1
|
const { QueuerUtil } = require('@friggframework/core/queues');
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
* AdminFriggCommands
|
|
5
|
-
*
|
|
6
|
-
* Helper API for admin scripts. Provides:
|
|
7
|
-
* - Database access via repositories
|
|
8
|
-
* - Integration instantiation (optional)
|
|
9
|
-
* - Logging utilities
|
|
10
|
-
* - Queue operations for self-queuing pattern
|
|
11
|
-
*
|
|
12
|
-
* Follows lazy-loading pattern for repositories to avoid circular dependencies
|
|
13
|
-
* and unnecessary initialization.
|
|
14
|
-
*/
|
|
15
|
-
class AdminFriggCommands {
|
|
3
|
+
class AdminScriptContext {
|
|
16
4
|
constructor(params = {}) {
|
|
17
5
|
this.executionId = params.executionId || null;
|
|
18
6
|
this.logs = [];
|
|
@@ -25,7 +13,7 @@ class AdminFriggCommands {
|
|
|
25
13
|
this._userRepository = null;
|
|
26
14
|
this._moduleRepository = null;
|
|
27
15
|
this._credentialRepository = null;
|
|
28
|
-
this.
|
|
16
|
+
this._adminProcessRepository = null;
|
|
29
17
|
}
|
|
30
18
|
|
|
31
19
|
// ==================== LAZY-LOADED REPOSITORIES ====================
|
|
@@ -62,12 +50,12 @@ class AdminFriggCommands {
|
|
|
62
50
|
return this._credentialRepository;
|
|
63
51
|
}
|
|
64
52
|
|
|
65
|
-
get
|
|
66
|
-
if (!this.
|
|
67
|
-
const {
|
|
68
|
-
this.
|
|
53
|
+
get adminProcessRepository() {
|
|
54
|
+
if (!this._adminProcessRepository) {
|
|
55
|
+
const { createAdminProcessRepository } = require('@friggframework/core/admin-scripts/repositories/admin-process-repository-factory');
|
|
56
|
+
this._adminProcessRepository = createAdminProcessRepository();
|
|
69
57
|
}
|
|
70
|
-
return this.
|
|
58
|
+
return this._adminProcessRepository;
|
|
71
59
|
}
|
|
72
60
|
|
|
73
61
|
// ==================== INTEGRATION QUERIES ====================
|
|
@@ -142,7 +130,7 @@ class AdminFriggCommands {
|
|
|
142
130
|
if (!this.integrationFactory) {
|
|
143
131
|
throw new Error(
|
|
144
132
|
'instantiate() requires integrationFactory. ' +
|
|
145
|
-
'Set Definition.config.
|
|
133
|
+
'Set Definition.config.requireIntegrationInstance = true'
|
|
146
134
|
);
|
|
147
135
|
}
|
|
148
136
|
return this.integrationFactory.getInstanceFromIntegrationId({
|
|
@@ -151,12 +139,8 @@ class AdminFriggCommands {
|
|
|
151
139
|
});
|
|
152
140
|
}
|
|
153
141
|
|
|
154
|
-
// ==================== QUEUE OPERATIONS
|
|
142
|
+
// ==================== QUEUE OPERATIONS ====================
|
|
155
143
|
|
|
156
|
-
/**
|
|
157
|
-
* Queue a script for execution
|
|
158
|
-
* Used for self-queuing pattern with long-running scripts
|
|
159
|
-
*/
|
|
160
144
|
async queueScript(scriptName, params = {}) {
|
|
161
145
|
const queueUrl = process.env.ADMIN_SCRIPT_QUEUE_URL;
|
|
162
146
|
if (!queueUrl) {
|
|
@@ -176,9 +160,6 @@ class AdminFriggCommands {
|
|
|
176
160
|
this.log('info', `Queued continuation for ${scriptName}`, { params });
|
|
177
161
|
}
|
|
178
162
|
|
|
179
|
-
/**
|
|
180
|
-
* Queue multiple scripts in a batch
|
|
181
|
-
*/
|
|
182
163
|
async queueScriptBatch(entries) {
|
|
183
164
|
const queueUrl = process.env.ADMIN_SCRIPT_QUEUE_URL;
|
|
184
165
|
if (!queueUrl) {
|
|
@@ -209,7 +190,7 @@ class AdminFriggCommands {
|
|
|
209
190
|
|
|
210
191
|
// Persist to execution record if we have an executionId
|
|
211
192
|
if (this.executionId) {
|
|
212
|
-
this.
|
|
193
|
+
this.adminProcessRepository.appendProcessLog(this.executionId, entry)
|
|
213
194
|
.catch(err => console.error('Failed to persist log:', err));
|
|
214
195
|
}
|
|
215
196
|
|
|
@@ -230,13 +211,20 @@ class AdminFriggCommands {
|
|
|
230
211
|
}
|
|
231
212
|
|
|
232
213
|
/**
|
|
233
|
-
* Create
|
|
214
|
+
* Create AdminScriptContext instance
|
|
234
215
|
*/
|
|
235
|
-
function
|
|
236
|
-
return new
|
|
216
|
+
function createAdminScriptContext(params = {}) {
|
|
217
|
+
return new AdminScriptContext(params);
|
|
237
218
|
}
|
|
238
219
|
|
|
220
|
+
// Legacy aliases for backwards compatibility
|
|
221
|
+
const AdminFriggCommands = AdminScriptContext;
|
|
222
|
+
const createAdminFriggCommands = createAdminScriptContext;
|
|
223
|
+
|
|
239
224
|
module.exports = {
|
|
225
|
+
AdminScriptContext,
|
|
226
|
+
createAdminScriptContext,
|
|
227
|
+
// Legacy exports (deprecated)
|
|
240
228
|
AdminFriggCommands,
|
|
241
229
|
createAdminFriggCommands,
|
|
242
230
|
};
|
|
@@ -1,64 +1,27 @@
|
|
|
1
|
-
const { createScriptExecutionRepository } = require('@friggframework/core/admin-scripts/repositories/script-execution-repository-factory');
|
|
2
|
-
const { createAdminApiKeyRepository } = require('@friggframework/core/admin-scripts/repositories/admin-api-key-repository-factory');
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Admin Script Base Class
|
|
6
|
-
*
|
|
7
|
-
* Base class for all admin scripts. Provides:
|
|
8
|
-
* - Standard script definition pattern
|
|
9
|
-
* - Repository access
|
|
10
|
-
* - Logging helpers
|
|
11
|
-
* - Integration factory support (optional)
|
|
12
|
-
*
|
|
13
|
-
* Usage:
|
|
14
|
-
* ```javascript
|
|
15
|
-
* class MyScript extends AdminScriptBase {
|
|
16
|
-
* static Definition = {
|
|
17
|
-
* name: 'my-script',
|
|
18
|
-
* version: '1.0.0',
|
|
19
|
-
* description: 'Does something useful',
|
|
20
|
-
* ...
|
|
21
|
-
* };
|
|
22
|
-
*
|
|
23
|
-
* async execute(frigg, params) {
|
|
24
|
-
* // Your script logic here
|
|
25
|
-
* }
|
|
26
|
-
* }
|
|
27
|
-
* ```
|
|
28
|
-
*/
|
|
29
1
|
class AdminScriptBase {
|
|
30
|
-
/**
|
|
31
|
-
* CHILDREN SHOULD SPECIFY A DEFINITION FOR THE SCRIPT
|
|
32
|
-
* Pattern matches IntegrationBase.Definition
|
|
33
|
-
*/
|
|
34
2
|
static Definition = {
|
|
35
|
-
name: 'Script Name',
|
|
36
|
-
version: '0.0.0',
|
|
37
|
-
description: 'What this script does',
|
|
38
|
-
|
|
39
|
-
// Script-specific properties
|
|
3
|
+
name: 'Script Name',
|
|
4
|
+
version: '0.0.0',
|
|
5
|
+
description: 'What this script does',
|
|
40
6
|
source: 'USER_DEFINED', // 'BUILTIN' | 'USER_DEFINED'
|
|
41
7
|
|
|
42
|
-
inputSchema: null,
|
|
43
|
-
outputSchema: null,
|
|
8
|
+
inputSchema: null,
|
|
9
|
+
outputSchema: null,
|
|
44
10
|
|
|
45
11
|
schedule: {
|
|
46
|
-
// Optional: Phase 2
|
|
47
12
|
enabled: false,
|
|
48
|
-
cronExpression: null,
|
|
13
|
+
cronExpression: null,
|
|
49
14
|
},
|
|
50
15
|
|
|
51
16
|
config: {
|
|
52
|
-
timeout: 300000,
|
|
17
|
+
timeout: 300000,
|
|
53
18
|
maxRetries: 0,
|
|
54
|
-
|
|
19
|
+
requireIntegrationInstance: false,
|
|
55
20
|
},
|
|
56
21
|
|
|
57
22
|
display: {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
description: '',
|
|
61
|
-
category: 'maintenance', // 'maintenance' | 'healing' | 'sync' | 'custom'
|
|
23
|
+
category: 'maintenance',
|
|
24
|
+
icon: null,
|
|
62
25
|
},
|
|
63
26
|
};
|
|
64
27
|
|
|
@@ -74,64 +37,22 @@ class AdminScriptBase {
|
|
|
74
37
|
return this.Definition;
|
|
75
38
|
}
|
|
76
39
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
* Pattern matches IntegrationBase constructor
|
|
80
|
-
*/
|
|
81
|
-
constructor(params = {}) {
|
|
82
|
-
this.executionId = params.executionId || null;
|
|
83
|
-
this.logs = [];
|
|
84
|
-
this._startTime = null;
|
|
85
|
-
|
|
86
|
-
// OPTIONAL: Integration factory for scripts that need it
|
|
87
|
-
this.integrationFactory = params.integrationFactory || null;
|
|
88
|
-
|
|
89
|
-
// OPTIONAL: Injected repositories (for testing or custom implementations)
|
|
90
|
-
this.scriptExecutionRepository = params.scriptExecutionRepository || null;
|
|
91
|
-
this.adminApiKeyRepository = params.adminApiKeyRepository || null;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* CHILDREN MUST IMPLEMENT THIS METHOD
|
|
96
|
-
* @param {AdminFriggCommands} frigg - Helper commands object
|
|
97
|
-
* @param {Object} params - Script parameters (validated against inputSchema)
|
|
98
|
-
* @returns {Promise<Object>} - Script results (validated against outputSchema)
|
|
99
|
-
*/
|
|
100
|
-
async execute(frigg, params) {
|
|
101
|
-
throw new Error('AdminScriptBase.execute() must be implemented by subclass');
|
|
40
|
+
static getDisplayLabel() {
|
|
41
|
+
return this.Definition.display?.label || this.Definition.name;
|
|
102
42
|
}
|
|
103
43
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
* @param {string} level - Log level (info, warn, error, debug)
|
|
107
|
-
* @param {string} message - Log message
|
|
108
|
-
* @param {Object} data - Additional data
|
|
109
|
-
* @returns {Object} Log entry
|
|
110
|
-
*/
|
|
111
|
-
log(level, message, data = {}) {
|
|
112
|
-
const entry = {
|
|
113
|
-
level,
|
|
114
|
-
message,
|
|
115
|
-
data,
|
|
116
|
-
timestamp: new Date().toISOString(),
|
|
117
|
-
};
|
|
118
|
-
this.logs.push(entry);
|
|
119
|
-
return entry;
|
|
44
|
+
static getDisplayDescription() {
|
|
45
|
+
return this.Definition.display?.description || this.Definition.description;
|
|
120
46
|
}
|
|
121
47
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
getLogs() {
|
|
127
|
-
return this.logs;
|
|
48
|
+
constructor(params = {}) {
|
|
49
|
+
this.context = params.context || null;
|
|
50
|
+
this.executionId = params.executionId || null;
|
|
51
|
+
this.integrationFactory = params.integrationFactory || null;
|
|
128
52
|
}
|
|
129
53
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
*/
|
|
133
|
-
clearLogs() {
|
|
134
|
-
this.logs = [];
|
|
54
|
+
async execute(params) {
|
|
55
|
+
throw new Error('AdminScriptBase.execute() must be implemented by subclass');
|
|
135
56
|
}
|
|
136
57
|
}
|
|
137
58
|
|