@friggframework/admin-scripts 2.0.0--canary.545.b4ca16d.0 → 2.0.0--canary.517.8eaf5df.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/README.md +277 -0
- package/index.js +23 -6
- package/package.json +6 -6
- package/src/adapters/__tests__/aws-scheduler-adapter.test.js +106 -45
- package/src/adapters/__tests__/local-scheduler-adapter.test.js +24 -10
- package/src/adapters/__tests__/scheduler-adapter-factory.test.js +30 -9
- package/src/adapters/__tests__/scheduler-adapter.test.js +6 -2
- package/src/adapters/aws-scheduler-adapter.js +55 -28
- package/src/adapters/local-scheduler-adapter.js +2 -2
- package/src/adapters/scheduler-adapter-factory.js +3 -1
- package/src/adapters/scheduler-adapter.js +9 -3
- package/src/application/__tests__/admin-frigg-commands.test.js +73 -30
- package/src/application/__tests__/admin-script-base.test.js +23 -6
- package/src/application/__tests__/script-factory.test.js +30 -6
- package/src/application/__tests__/script-runner.test.js +113 -24
- package/src/application/__tests__/validate-script-input.test.js +54 -15
- package/src/application/admin-frigg-commands.js +21 -9
- package/src/application/admin-script-base.js +3 -2
- package/src/application/script-factory.js +3 -1
- package/src/application/script-runner.js +90 -48
- package/src/application/use-cases/__tests__/delete-schedule-use-case.test.js +16 -7
- package/src/application/use-cases/__tests__/get-effective-schedule-use-case.test.js +9 -4
- package/src/application/use-cases/__tests__/upsert-schedule-use-case.test.js +21 -10
- package/src/application/use-cases/delete-schedule-use-case.js +6 -4
- package/src/application/use-cases/get-effective-schedule-use-case.js +3 -1
- package/src/application/use-cases/index.js +3 -1
- package/src/application/use-cases/upsert-schedule-use-case.js +30 -11
- package/src/application/validate-script-input.js +10 -3
- package/src/builtins/__tests__/integration-health-check.test.js +232 -127
- package/src/builtins/__tests__/oauth-token-refresh.test.js +128 -75
- package/src/builtins/index.js +1 -4
- package/src/builtins/integration-health-check.js +63 -30
- package/src/builtins/oauth-token-refresh.js +64 -29
- package/src/infrastructure/__tests__/admin-auth-middleware.test.js +9 -3
- package/src/infrastructure/__tests__/admin-script-router.test.js +125 -52
- package/src/infrastructure/admin-auth-middleware.js +3 -1
- package/src/infrastructure/admin-script-router.js +129 -14
- package/src/infrastructure/bootstrap.js +87 -0
- package/src/infrastructure/script-executor-handler.js +119 -52
- 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
|
@@ -162,11 +162,19 @@ describe('ScriptFactory', () => {
|
|
|
162
162
|
describe('getNames()', () => {
|
|
163
163
|
it('should return array of all registered script names', () => {
|
|
164
164
|
class Script1 extends AdminScriptBase {
|
|
165
|
-
static Definition = {
|
|
165
|
+
static Definition = {
|
|
166
|
+
name: 'script-1',
|
|
167
|
+
version: '1.0.0',
|
|
168
|
+
description: 'One',
|
|
169
|
+
};
|
|
166
170
|
}
|
|
167
171
|
|
|
168
172
|
class Script2 extends AdminScriptBase {
|
|
169
|
-
static Definition = {
|
|
173
|
+
static Definition = {
|
|
174
|
+
name: 'script-2',
|
|
175
|
+
version: '1.0.0',
|
|
176
|
+
description: 'Two',
|
|
177
|
+
};
|
|
170
178
|
}
|
|
171
179
|
|
|
172
180
|
factory.registerAll([Script1, Script2]);
|
|
@@ -272,11 +280,19 @@ describe('ScriptFactory', () => {
|
|
|
272
280
|
describe('clear()', () => {
|
|
273
281
|
it('should remove all registered scripts', () => {
|
|
274
282
|
class Script1 extends AdminScriptBase {
|
|
275
|
-
static Definition = {
|
|
283
|
+
static Definition = {
|
|
284
|
+
name: 'script-1',
|
|
285
|
+
version: '1.0.0',
|
|
286
|
+
description: 'One',
|
|
287
|
+
};
|
|
276
288
|
}
|
|
277
289
|
|
|
278
290
|
class Script2 extends AdminScriptBase {
|
|
279
|
-
static Definition = {
|
|
291
|
+
static Definition = {
|
|
292
|
+
name: 'script-2',
|
|
293
|
+
version: '1.0.0',
|
|
294
|
+
description: 'Two',
|
|
295
|
+
};
|
|
280
296
|
}
|
|
281
297
|
|
|
282
298
|
factory.registerAll([Script1, Script2]);
|
|
@@ -295,14 +311,22 @@ describe('ScriptFactory', () => {
|
|
|
295
311
|
expect(factory.size).toBe(0);
|
|
296
312
|
|
|
297
313
|
class Script1 extends AdminScriptBase {
|
|
298
|
-
static Definition = {
|
|
314
|
+
static Definition = {
|
|
315
|
+
name: 'script-1',
|
|
316
|
+
version: '1.0.0',
|
|
317
|
+
description: 'One',
|
|
318
|
+
};
|
|
299
319
|
}
|
|
300
320
|
|
|
301
321
|
factory.register(Script1);
|
|
302
322
|
expect(factory.size).toBe(1);
|
|
303
323
|
|
|
304
324
|
class Script2 extends AdminScriptBase {
|
|
305
|
-
static Definition = {
|
|
325
|
+
static Definition = {
|
|
326
|
+
name: 'script-2',
|
|
327
|
+
version: '1.0.0',
|
|
328
|
+
description: 'Two',
|
|
329
|
+
};
|
|
306
330
|
}
|
|
307
331
|
|
|
308
332
|
factory.register(Script2);
|
|
@@ -6,13 +6,15 @@ const { AdminScriptBase } = require('../admin-script-base');
|
|
|
6
6
|
jest.mock('../admin-frigg-commands');
|
|
7
7
|
jest.mock('@friggframework/core/application/commands/admin-script-commands');
|
|
8
8
|
|
|
9
|
-
const {
|
|
10
|
-
const {
|
|
9
|
+
const { createAdminScriptContext } = require('../admin-frigg-commands');
|
|
10
|
+
const {
|
|
11
|
+
createAdminScriptCommands,
|
|
12
|
+
} = require('@friggframework/core/application/commands/admin-script-commands');
|
|
11
13
|
|
|
12
14
|
describe('ScriptRunner', () => {
|
|
13
15
|
let scriptFactory;
|
|
14
16
|
let mockCommands;
|
|
15
|
-
let
|
|
17
|
+
let mockContext;
|
|
16
18
|
let testScript;
|
|
17
19
|
|
|
18
20
|
class TestScript extends AdminScriptBase {
|
|
@@ -41,13 +43,14 @@ describe('ScriptRunner', () => {
|
|
|
41
43
|
completeAdminProcess: jest.fn(),
|
|
42
44
|
};
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
mockContext = {
|
|
45
47
|
log: jest.fn(),
|
|
46
48
|
getExecutionId: jest.fn(),
|
|
49
|
+
getLogs: jest.fn(() => []),
|
|
47
50
|
};
|
|
48
51
|
|
|
49
52
|
createAdminScriptCommands.mockReturnValue(mockCommands);
|
|
50
|
-
|
|
53
|
+
createAdminScriptContext.mockReturnValue(mockContext);
|
|
51
54
|
|
|
52
55
|
mockCommands.createAdminProcess.mockResolvedValue({
|
|
53
56
|
id: 'exec-123',
|
|
@@ -62,17 +65,27 @@ describe('ScriptRunner', () => {
|
|
|
62
65
|
|
|
63
66
|
describe('execute()', () => {
|
|
64
67
|
it('should execute script successfully', async () => {
|
|
65
|
-
const runner = new ScriptRunner({
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
trigger: 'MANUAL',
|
|
69
|
-
mode: 'async',
|
|
70
|
-
audit: { apiKeyName: 'test-key' },
|
|
68
|
+
const runner = new ScriptRunner({
|
|
69
|
+
scriptFactory,
|
|
70
|
+
commands: mockCommands,
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
+
const result = await runner.execute(
|
|
74
|
+
'test-script',
|
|
75
|
+
{ foo: 'bar' },
|
|
76
|
+
{
|
|
77
|
+
trigger: 'MANUAL',
|
|
78
|
+
mode: 'async',
|
|
79
|
+
audit: { apiKeyName: 'test-key' },
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
|
|
73
83
|
expect(result.status).toBe('COMPLETED');
|
|
74
84
|
expect(result.scriptName).toBe('test-script');
|
|
75
|
-
expect(result.output).toEqual({
|
|
85
|
+
expect(result.output).toEqual({
|
|
86
|
+
success: true,
|
|
87
|
+
params: { foo: 'bar' },
|
|
88
|
+
});
|
|
76
89
|
expect(result.executionId).toBe('exec-123');
|
|
77
90
|
expect(result.metrics.durationMs).toBeGreaterThanOrEqual(0);
|
|
78
91
|
|
|
@@ -103,7 +116,10 @@ describe('ScriptRunner', () => {
|
|
|
103
116
|
});
|
|
104
117
|
|
|
105
118
|
it('should throw error if trigger is not provided', async () => {
|
|
106
|
-
const runner = new ScriptRunner({
|
|
119
|
+
const runner = new ScriptRunner({
|
|
120
|
+
scriptFactory,
|
|
121
|
+
commands: mockCommands,
|
|
122
|
+
});
|
|
107
123
|
|
|
108
124
|
await expect(
|
|
109
125
|
runner.execute('test-script', { foo: 'bar' }, {})
|
|
@@ -111,7 +127,10 @@ describe('ScriptRunner', () => {
|
|
|
111
127
|
});
|
|
112
128
|
|
|
113
129
|
it('should throw error if options are omitted entirely', async () => {
|
|
114
|
-
const runner = new ScriptRunner({
|
|
130
|
+
const runner = new ScriptRunner({
|
|
131
|
+
scriptFactory,
|
|
132
|
+
commands: mockCommands,
|
|
133
|
+
});
|
|
115
134
|
|
|
116
135
|
await expect(
|
|
117
136
|
runner.execute('test-script', { foo: 'bar' })
|
|
@@ -133,13 +152,20 @@ describe('ScriptRunner', () => {
|
|
|
133
152
|
}
|
|
134
153
|
|
|
135
154
|
scriptFactory.register(FailingScript);
|
|
136
|
-
const runner = new ScriptRunner({
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
trigger: 'MANUAL',
|
|
140
|
-
mode: 'sync',
|
|
155
|
+
const runner = new ScriptRunner({
|
|
156
|
+
scriptFactory,
|
|
157
|
+
commands: mockCommands,
|
|
141
158
|
});
|
|
142
159
|
|
|
160
|
+
const result = await runner.execute(
|
|
161
|
+
'failing-script',
|
|
162
|
+
{},
|
|
163
|
+
{
|
|
164
|
+
trigger: 'MANUAL',
|
|
165
|
+
mode: 'sync',
|
|
166
|
+
}
|
|
167
|
+
);
|
|
168
|
+
|
|
143
169
|
expect(result.status).toBe('FAILED');
|
|
144
170
|
expect(result.scriptName).toBe('failing-script');
|
|
145
171
|
expect(result.error.message).toBe('Script failed');
|
|
@@ -186,13 +212,20 @@ describe('ScriptRunner', () => {
|
|
|
186
212
|
});
|
|
187
213
|
|
|
188
214
|
it('should reuse existing execution ID when provided', async () => {
|
|
189
|
-
const runner = new ScriptRunner({
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
trigger: 'QUEUE',
|
|
193
|
-
executionId: 'existing-exec-456',
|
|
215
|
+
const runner = new ScriptRunner({
|
|
216
|
+
scriptFactory,
|
|
217
|
+
commands: mockCommands,
|
|
194
218
|
});
|
|
195
219
|
|
|
220
|
+
const result = await runner.execute(
|
|
221
|
+
'test-script',
|
|
222
|
+
{ foo: 'bar' },
|
|
223
|
+
{
|
|
224
|
+
trigger: 'QUEUE',
|
|
225
|
+
executionId: 'existing-exec-456',
|
|
226
|
+
}
|
|
227
|
+
);
|
|
228
|
+
|
|
196
229
|
expect(result.executionId).toBe('existing-exec-456');
|
|
197
230
|
expect(mockCommands.createAdminProcess).not.toHaveBeenCalled();
|
|
198
231
|
expect(mockCommands.updateAdminProcessState).toHaveBeenCalledWith(
|
|
@@ -200,6 +233,62 @@ describe('ScriptRunner', () => {
|
|
|
200
233
|
'RUNNING'
|
|
201
234
|
);
|
|
202
235
|
});
|
|
236
|
+
|
|
237
|
+
it('reports COMPLETED even when persisting completion fails', async () => {
|
|
238
|
+
// Commands return an error object (never throw). A successful script
|
|
239
|
+
// must not be misreported as FAILED if the completion write fails.
|
|
240
|
+
mockCommands.completeAdminProcess.mockResolvedValue({
|
|
241
|
+
error: 500,
|
|
242
|
+
reason: 'DB write failed',
|
|
243
|
+
});
|
|
244
|
+
const runner = new ScriptRunner({
|
|
245
|
+
scriptFactory,
|
|
246
|
+
commands: mockCommands,
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
const result = await runner.execute(
|
|
250
|
+
'test-script',
|
|
251
|
+
{},
|
|
252
|
+
{ trigger: 'MANUAL' }
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
expect(result.status).toBe('COMPLETED');
|
|
256
|
+
expect(result.stateUpdateFailed).toBe(true);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it('throws when the execution record cannot be created', async () => {
|
|
260
|
+
mockCommands.createAdminProcess.mockResolvedValue({
|
|
261
|
+
error: 500,
|
|
262
|
+
reason: 'DB down',
|
|
263
|
+
});
|
|
264
|
+
const runner = new ScriptRunner({
|
|
265
|
+
scriptFactory,
|
|
266
|
+
commands: mockCommands,
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
await expect(
|
|
270
|
+
runner.execute('test-script', {}, { trigger: 'MANUAL' })
|
|
271
|
+
).rejects.toThrow('DB down');
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
it('persists collected logs on completion', async () => {
|
|
275
|
+
mockContext.getLogs.mockReturnValue([
|
|
276
|
+
{ level: 'info', message: 'hi' },
|
|
277
|
+
]);
|
|
278
|
+
const runner = new ScriptRunner({
|
|
279
|
+
scriptFactory,
|
|
280
|
+
commands: mockCommands,
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
await runner.execute('test-script', {}, { trigger: 'MANUAL' });
|
|
284
|
+
|
|
285
|
+
expect(mockCommands.completeAdminProcess).toHaveBeenCalledWith(
|
|
286
|
+
'exec-123',
|
|
287
|
+
expect.objectContaining({
|
|
288
|
+
logs: [{ level: 'info', message: 'hi' }],
|
|
289
|
+
})
|
|
290
|
+
);
|
|
291
|
+
});
|
|
203
292
|
});
|
|
204
293
|
|
|
205
294
|
describe('createScriptRunner()', () => {
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const {
|
|
2
|
+
validateScriptInput,
|
|
3
|
+
validateParams,
|
|
4
|
+
validateType,
|
|
5
|
+
} = require('../validate-script-input');
|
|
2
6
|
const { ScriptFactory } = require('../script-factory');
|
|
3
7
|
const { AdminScriptBase } = require('../admin-script-base');
|
|
4
8
|
|
|
@@ -61,12 +65,18 @@ describe('validateScriptInput', () => {
|
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
beforeEach(() => {
|
|
64
|
-
scriptFactory = new ScriptFactory([
|
|
68
|
+
scriptFactory = new ScriptFactory([
|
|
69
|
+
TestScript,
|
|
70
|
+
SchemaScript,
|
|
71
|
+
TypedScript,
|
|
72
|
+
]);
|
|
65
73
|
});
|
|
66
74
|
|
|
67
75
|
describe('validateScriptInput()', () => {
|
|
68
76
|
it('should return VALID for script without schema', () => {
|
|
69
|
-
const result = validateScriptInput(scriptFactory, 'test-script', {
|
|
77
|
+
const result = validateScriptInput(scriptFactory, 'test-script', {
|
|
78
|
+
foo: 'bar',
|
|
79
|
+
});
|
|
70
80
|
|
|
71
81
|
expect(result.status).toBe('VALID');
|
|
72
82
|
expect(result.scriptName).toBe('test-script');
|
|
@@ -77,11 +87,17 @@ describe('validateScriptInput', () => {
|
|
|
77
87
|
});
|
|
78
88
|
|
|
79
89
|
it('should return INVALID when required parameters are missing', () => {
|
|
80
|
-
const result = validateScriptInput(
|
|
90
|
+
const result = validateScriptInput(
|
|
91
|
+
scriptFactory,
|
|
92
|
+
'schema-script',
|
|
93
|
+
{}
|
|
94
|
+
);
|
|
81
95
|
|
|
82
96
|
expect(result.status).toBe('INVALID');
|
|
83
97
|
expect(result.preview.validation.valid).toBe(false);
|
|
84
|
-
expect(result.preview.validation.errors).toContain(
|
|
98
|
+
expect(result.preview.validation.errors).toContain(
|
|
99
|
+
'Missing required parameter: requiredParam'
|
|
100
|
+
);
|
|
85
101
|
});
|
|
86
102
|
|
|
87
103
|
it('should return INVALID for wrong parameter types', () => {
|
|
@@ -122,7 +138,11 @@ describe('validateScriptInput', () => {
|
|
|
122
138
|
});
|
|
123
139
|
|
|
124
140
|
it('should return null inputSchema when script has no schema', () => {
|
|
125
|
-
const result = validateScriptInput(
|
|
141
|
+
const result = validateScriptInput(
|
|
142
|
+
scriptFactory,
|
|
143
|
+
'test-script',
|
|
144
|
+
{}
|
|
145
|
+
);
|
|
126
146
|
|
|
127
147
|
expect(result.preview.inputSchema).toBeNull();
|
|
128
148
|
});
|
|
@@ -130,7 +150,10 @@ describe('validateScriptInput', () => {
|
|
|
130
150
|
|
|
131
151
|
describe('validateParams()', () => {
|
|
132
152
|
it('should return valid when no schema defined', () => {
|
|
133
|
-
const result = validateParams(
|
|
153
|
+
const result = validateParams(
|
|
154
|
+
{ name: 'test' },
|
|
155
|
+
{ anything: 'goes' }
|
|
156
|
+
);
|
|
134
157
|
|
|
135
158
|
expect(result.valid).toBe(true);
|
|
136
159
|
expect(result.errors).toHaveLength(0);
|
|
@@ -158,35 +181,51 @@ describe('validateScriptInput', () => {
|
|
|
158
181
|
describe('validateType()', () => {
|
|
159
182
|
it('should validate integer type', () => {
|
|
160
183
|
expect(validateType('x', 42, { type: 'integer' })).toBeNull();
|
|
161
|
-
expect(validateType('x', 3.14, { type: 'integer' })).toContain(
|
|
162
|
-
|
|
184
|
+
expect(validateType('x', 3.14, { type: 'integer' })).toContain(
|
|
185
|
+
'must be an integer'
|
|
186
|
+
);
|
|
187
|
+
expect(validateType('x', 'foo', { type: 'integer' })).toContain(
|
|
188
|
+
'must be an integer'
|
|
189
|
+
);
|
|
163
190
|
});
|
|
164
191
|
|
|
165
192
|
it('should validate number type', () => {
|
|
166
193
|
expect(validateType('x', 3.14, { type: 'number' })).toBeNull();
|
|
167
194
|
expect(validateType('x', 42, { type: 'number' })).toBeNull();
|
|
168
|
-
expect(validateType('x', 'foo', { type: 'number' })).toContain(
|
|
195
|
+
expect(validateType('x', 'foo', { type: 'number' })).toContain(
|
|
196
|
+
'must be a number'
|
|
197
|
+
);
|
|
169
198
|
});
|
|
170
199
|
|
|
171
200
|
it('should validate string type', () => {
|
|
172
201
|
expect(validateType('x', 'hello', { type: 'string' })).toBeNull();
|
|
173
|
-
expect(validateType('x', 123, { type: 'string' })).toContain(
|
|
202
|
+
expect(validateType('x', 123, { type: 'string' })).toContain(
|
|
203
|
+
'must be a string'
|
|
204
|
+
);
|
|
174
205
|
});
|
|
175
206
|
|
|
176
207
|
it('should validate boolean type', () => {
|
|
177
208
|
expect(validateType('x', true, { type: 'boolean' })).toBeNull();
|
|
178
|
-
expect(validateType('x', 'true', { type: 'boolean' })).toContain(
|
|
209
|
+
expect(validateType('x', 'true', { type: 'boolean' })).toContain(
|
|
210
|
+
'must be a boolean'
|
|
211
|
+
);
|
|
179
212
|
});
|
|
180
213
|
|
|
181
214
|
it('should validate array type', () => {
|
|
182
215
|
expect(validateType('x', [1, 2], { type: 'array' })).toBeNull();
|
|
183
|
-
expect(validateType('x', 'not-array', { type: 'array' })).toContain(
|
|
216
|
+
expect(validateType('x', 'not-array', { type: 'array' })).toContain(
|
|
217
|
+
'must be an array'
|
|
218
|
+
);
|
|
184
219
|
});
|
|
185
220
|
|
|
186
221
|
it('should validate object type', () => {
|
|
187
222
|
expect(validateType('x', { a: 1 }, { type: 'object' })).toBeNull();
|
|
188
|
-
expect(validateType('x', [1, 2], { type: 'object' })).toContain(
|
|
189
|
-
|
|
223
|
+
expect(validateType('x', [1, 2], { type: 'object' })).toContain(
|
|
224
|
+
'must be an object'
|
|
225
|
+
);
|
|
226
|
+
expect(validateType('x', 'string', { type: 'object' })).toContain(
|
|
227
|
+
'must be an object'
|
|
228
|
+
);
|
|
190
229
|
});
|
|
191
230
|
|
|
192
231
|
it('should return null when no type specified', () => {
|
|
@@ -34,7 +34,9 @@ class AdminScriptContext {
|
|
|
34
34
|
|
|
35
35
|
get integrationRepository() {
|
|
36
36
|
if (!this._integrationRepository) {
|
|
37
|
-
const {
|
|
37
|
+
const {
|
|
38
|
+
createIntegrationRepository,
|
|
39
|
+
} = require('@friggframework/core/integrations/repositories/integration-repository-factory');
|
|
38
40
|
this._integrationRepository = createIntegrationRepository();
|
|
39
41
|
}
|
|
40
42
|
return this._integrationRepository;
|
|
@@ -42,7 +44,9 @@ class AdminScriptContext {
|
|
|
42
44
|
|
|
43
45
|
get userRepository() {
|
|
44
46
|
if (!this._userRepository) {
|
|
45
|
-
const {
|
|
47
|
+
const {
|
|
48
|
+
createUserRepository,
|
|
49
|
+
} = require('@friggframework/core/user/repositories/user-repository-factory');
|
|
46
50
|
this._userRepository = createUserRepository();
|
|
47
51
|
}
|
|
48
52
|
return this._userRepository;
|
|
@@ -50,7 +54,9 @@ class AdminScriptContext {
|
|
|
50
54
|
|
|
51
55
|
get moduleRepository() {
|
|
52
56
|
if (!this._moduleRepository) {
|
|
53
|
-
const {
|
|
57
|
+
const {
|
|
58
|
+
createModuleRepository,
|
|
59
|
+
} = require('@friggframework/core/modules/repositories/module-repository-factory');
|
|
54
60
|
this._moduleRepository = createModuleRepository();
|
|
55
61
|
}
|
|
56
62
|
return this._moduleRepository;
|
|
@@ -58,7 +64,9 @@ class AdminScriptContext {
|
|
|
58
64
|
|
|
59
65
|
get credentialRepository() {
|
|
60
66
|
if (!this._credentialRepository) {
|
|
61
|
-
const {
|
|
67
|
+
const {
|
|
68
|
+
createCredentialRepository,
|
|
69
|
+
} = require('@friggframework/core/credential/repositories/credential-repository-factory');
|
|
62
70
|
this._credentialRepository = createCredentialRepository();
|
|
63
71
|
}
|
|
64
72
|
return this._credentialRepository;
|
|
@@ -74,12 +82,12 @@ class AdminScriptContext {
|
|
|
74
82
|
if (!this.integrationFactory) {
|
|
75
83
|
throw new Error(
|
|
76
84
|
'instantiate() requires integrationFactory. ' +
|
|
77
|
-
|
|
85
|
+
'Set Definition.config.requireIntegrationInstance = true'
|
|
78
86
|
);
|
|
79
87
|
}
|
|
80
88
|
return this.integrationFactory.getInstanceFromIntegrationId({
|
|
81
89
|
integrationId,
|
|
82
|
-
_isAdminContext: true,
|
|
90
|
+
_isAdminContext: true, // Bypass user ownership check
|
|
83
91
|
});
|
|
84
92
|
}
|
|
85
93
|
|
|
@@ -88,7 +96,9 @@ class AdminScriptContext {
|
|
|
88
96
|
async queueScript(scriptName, params = {}) {
|
|
89
97
|
const queueUrl = process.env.ADMIN_SCRIPT_QUEUE_URL;
|
|
90
98
|
if (!queueUrl) {
|
|
91
|
-
throw new Error(
|
|
99
|
+
throw new Error(
|
|
100
|
+
'ADMIN_SCRIPT_QUEUE_URL environment variable not set'
|
|
101
|
+
);
|
|
92
102
|
}
|
|
93
103
|
|
|
94
104
|
await QueuerUtil.send(
|
|
@@ -107,10 +117,12 @@ class AdminScriptContext {
|
|
|
107
117
|
async queueScriptBatch(entries) {
|
|
108
118
|
const queueUrl = process.env.ADMIN_SCRIPT_QUEUE_URL;
|
|
109
119
|
if (!queueUrl) {
|
|
110
|
-
throw new Error(
|
|
120
|
+
throw new Error(
|
|
121
|
+
'ADMIN_SCRIPT_QUEUE_URL environment variable not set'
|
|
122
|
+
);
|
|
111
123
|
}
|
|
112
124
|
|
|
113
|
-
const messages = entries.map(entry => ({
|
|
125
|
+
const messages = entries.map((entry) => ({
|
|
114
126
|
scriptName: entry.scriptName,
|
|
115
127
|
trigger: 'QUEUE',
|
|
116
128
|
params: entry.params || {},
|
|
@@ -15,7 +15,6 @@ class AdminScriptBase {
|
|
|
15
15
|
|
|
16
16
|
config: {
|
|
17
17
|
timeout: 300000,
|
|
18
|
-
maxRetries: 0,
|
|
19
18
|
requireIntegrationInstance: false,
|
|
20
19
|
},
|
|
21
20
|
|
|
@@ -32,7 +31,9 @@ class AdminScriptBase {
|
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
async execute(params) {
|
|
35
|
-
throw new Error(
|
|
34
|
+
throw new Error(
|
|
35
|
+
'AdminScriptBase.execute() must be implemented by subclass'
|
|
36
|
+
);
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
39
|
|
|
@@ -26,7 +26,9 @@ class ScriptFactory {
|
|
|
26
26
|
*/
|
|
27
27
|
register(ScriptClass) {
|
|
28
28
|
if (!ScriptClass || !ScriptClass.Definition) {
|
|
29
|
-
throw new Error(
|
|
29
|
+
throw new Error(
|
|
30
|
+
'Script class must have a static Definition property'
|
|
31
|
+
);
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
const definition = ScriptClass.Definition;
|