@friggframework/admin-scripts 2.0.0--canary.517.7e78259.0 → 2.0.0--canary.517.2239974.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/package.json +6 -6
- package/src/application/__tests__/admin-frigg-commands.test.js +81 -295
- package/src/application/__tests__/admin-script-base.test.js +0 -91
- package/src/application/__tests__/script-runner.test.js +0 -133
- package/src/application/__tests__/validate-script-input.test.js +196 -0
- package/src/application/admin-frigg-commands.js +15 -78
- package/src/application/admin-script-base.js +0 -20
- package/src/application/script-runner.js +1 -111
- package/src/application/validate-script-input.js +116 -0
- package/src/builtins/__tests__/integration-health-check.test.js +27 -25
- package/src/builtins/__tests__/oauth-token-refresh.test.js +17 -15
- package/src/builtins/integration-health-check.js +3 -3
- package/src/builtins/oauth-token-refresh.js +2 -2
- package/src/infrastructure/__tests__/admin-script-router.test.js +2 -2
- package/src/infrastructure/admin-script-router.js +28 -14
- package/src/infrastructure/script-executor-handler.js +18 -35
|
@@ -3,6 +3,7 @@ const serverless = require('serverless-http');
|
|
|
3
3
|
const { validateAdminApiKey } = require('./admin-auth-middleware');
|
|
4
4
|
const { getScriptFactory } = require('../application/script-factory');
|
|
5
5
|
const { createScriptRunner } = require('../application/script-runner');
|
|
6
|
+
const { validateScriptInput } = require('../application/validate-script-input');
|
|
6
7
|
const { createAdminScriptCommands } = require('@friggframework/core/application/commands/admin-script-commands');
|
|
7
8
|
const { QueuerUtil } = require('@friggframework/core/queues');
|
|
8
9
|
const { createSchedulerAdapter } = require('../adapters/scheduler-adapter-factory');
|
|
@@ -95,13 +96,13 @@ router.get('/scripts/:scriptName', async (req, res) => {
|
|
|
95
96
|
});
|
|
96
97
|
|
|
97
98
|
/**
|
|
98
|
-
* POST /admin/scripts/:scriptName
|
|
99
|
-
*
|
|
99
|
+
* POST /admin/scripts/:scriptName/validate
|
|
100
|
+
* Validate script inputs without executing (dry-run)
|
|
100
101
|
*/
|
|
101
|
-
router.post('/scripts/:scriptName', async (req, res) => {
|
|
102
|
+
router.post('/scripts/:scriptName/validate', async (req, res) => {
|
|
102
103
|
try {
|
|
103
104
|
const { scriptName } = req.params;
|
|
104
|
-
const { params = {}
|
|
105
|
+
const { params = {} } = req.body;
|
|
105
106
|
const factory = getScriptFactory();
|
|
106
107
|
|
|
107
108
|
if (!factory.has(scriptName)) {
|
|
@@ -111,19 +112,32 @@ router.post('/scripts/:scriptName', async (req, res) => {
|
|
|
111
112
|
});
|
|
112
113
|
}
|
|
113
114
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
115
|
+
const result = validateScriptInput(factory, scriptName, params);
|
|
116
|
+
res.json(result);
|
|
117
|
+
} catch (error) {
|
|
118
|
+
console.error('Error validating script:', error);
|
|
119
|
+
res.status(500).json({ error: 'Failed to validate script' });
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* POST /admin/scripts/:scriptName
|
|
125
|
+
* Execute a script (sync or async)
|
|
126
|
+
*/
|
|
127
|
+
router.post('/scripts/:scriptName', async (req, res) => {
|
|
128
|
+
try {
|
|
129
|
+
const { scriptName } = req.params;
|
|
130
|
+
const { params = {}, mode = 'async' } = req.body;
|
|
131
|
+
const factory = getScriptFactory();
|
|
132
|
+
|
|
133
|
+
if (!factory.has(scriptName)) {
|
|
134
|
+
return res.status(404).json({
|
|
135
|
+
error: `Script "${scriptName}" not found`,
|
|
136
|
+
code: 'SCRIPT_NOT_FOUND',
|
|
121
137
|
});
|
|
122
|
-
return res.json(result);
|
|
123
138
|
}
|
|
124
139
|
|
|
125
140
|
if (mode === 'sync') {
|
|
126
|
-
// Synchronous execution - wait for result
|
|
127
141
|
const runner = createScriptRunner();
|
|
128
142
|
const result = await runner.execute(scriptName, params, {
|
|
129
143
|
trigger: 'MANUAL',
|
|
@@ -155,7 +169,7 @@ router.post('/scripts/:scriptName', async (req, res) => {
|
|
|
155
169
|
|
|
156
170
|
res.status(202).json({
|
|
157
171
|
executionId: execution.id,
|
|
158
|
-
status: '
|
|
172
|
+
status: 'QUEUED',
|
|
159
173
|
scriptName,
|
|
160
174
|
message: 'Script queued for execution',
|
|
161
175
|
});
|
|
@@ -1,65 +1,48 @@
|
|
|
1
1
|
const { createScriptRunner } = require('../application/script-runner');
|
|
2
|
-
const { createAdminScriptCommands } = require('@friggframework/core/application/commands/admin-script-commands');
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* SQS Queue Worker Lambda Handler
|
|
6
5
|
*
|
|
7
|
-
* Processes script execution messages from AdminScriptQueue
|
|
6
|
+
* Processes script execution messages from AdminScriptQueue.
|
|
7
|
+
* Thin adapter: parses SQS messages and delegates to ScriptRunner.
|
|
8
|
+
* ScriptRunner handles execution tracking, error recording, and status updates.
|
|
8
9
|
*/
|
|
9
10
|
async function handler(event) {
|
|
10
11
|
const results = [];
|
|
11
12
|
|
|
12
13
|
for (const record of event.Records) {
|
|
13
|
-
|
|
14
|
-
const { scriptName, executionId, trigger, params } = message;
|
|
15
|
-
|
|
16
|
-
console.log(`Processing script: ${scriptName}, executionId: ${executionId}`);
|
|
14
|
+
let scriptName;
|
|
17
15
|
|
|
18
16
|
try {
|
|
19
|
-
const
|
|
20
|
-
|
|
17
|
+
const message = JSON.parse(record.body);
|
|
18
|
+
({ scriptName } = message);
|
|
19
|
+
const { executionId, trigger, params } = message;
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
await commands.updateAdminProcessState(executionId, 'RUNNING');
|
|
21
|
+
if (!scriptName || !executionId) {
|
|
22
|
+
throw new Error(`Invalid SQS message: missing scriptName or executionId`);
|
|
25
23
|
}
|
|
26
24
|
|
|
25
|
+
console.log(`Processing script: ${scriptName}, executionId: ${executionId}`);
|
|
26
|
+
|
|
27
|
+
const runner = createScriptRunner();
|
|
27
28
|
const result = await runner.execute(scriptName, params, {
|
|
28
29
|
trigger: trigger || 'QUEUE',
|
|
29
30
|
mode: 'async',
|
|
30
|
-
executionId,
|
|
31
|
+
executionId,
|
|
31
32
|
});
|
|
32
33
|
|
|
33
|
-
console.log(
|
|
34
|
-
`Script completed: ${scriptName}, status: ${result.status}`
|
|
35
|
-
);
|
|
34
|
+
console.log(`Script completed: ${scriptName}, status: ${result.status}`);
|
|
36
35
|
results.push({
|
|
37
36
|
scriptName,
|
|
38
37
|
status: result.status,
|
|
39
38
|
executionId: result.executionId,
|
|
40
39
|
});
|
|
41
40
|
} catch (error) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (executionId) {
|
|
46
|
-
const commands = createAdminScriptCommands();
|
|
47
|
-
await commands
|
|
48
|
-
.completeAdminProcess(executionId, {
|
|
49
|
-
state: 'FAILED',
|
|
50
|
-
error: {
|
|
51
|
-
name: error.name,
|
|
52
|
-
message: error.message,
|
|
53
|
-
stack: error.stack,
|
|
54
|
-
},
|
|
55
|
-
})
|
|
56
|
-
.catch((e) =>
|
|
57
|
-
console.error('Failed to update execution:', e)
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
|
|
41
|
+
// Only reaches here for unexpected failures (message parse errors, runner construction).
|
|
42
|
+
// Script execution errors are handled by ScriptRunner and returned as { status: 'FAILED' }.
|
|
43
|
+
console.error(`Unexpected error processing record:`, error);
|
|
61
44
|
results.push({
|
|
62
|
-
scriptName,
|
|
45
|
+
scriptName: scriptName || 'unknown',
|
|
63
46
|
status: 'FAILED',
|
|
64
47
|
error: error.message,
|
|
65
48
|
});
|