Merge pull request #11 from amhsirak/develop
feat: record & workflow routes
This commit is contained in:
9
server/src/routes/index.ts
Normal file
9
server/src/routes/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { router as record } from './record';
|
||||
import { router as workflow } from './workflow';
|
||||
import { router as storage } from './storage';
|
||||
|
||||
export {
|
||||
record,
|
||||
workflow,
|
||||
storage,
|
||||
};
|
||||
113
server/src/routes/record.ts
Normal file
113
server/src/routes/record.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* RESTful API endpoints handling remote browser recording sessions.
|
||||
*/
|
||||
import { Router } from 'express';
|
||||
|
||||
import {
|
||||
initializeRemoteBrowserForRecording,
|
||||
destroyRemoteBrowser,
|
||||
getActiveBrowserId,
|
||||
interpretWholeWorkflow,
|
||||
stopRunningInterpretation,
|
||||
getRemoteBrowserCurrentUrl, getRemoteBrowserCurrentTabs,
|
||||
} from '../browser-management/controller'
|
||||
import { chromium } from "playwright";
|
||||
import logger from "../logger";
|
||||
|
||||
export const router = Router();
|
||||
|
||||
/**
|
||||
* Logs information about remote browser recording session.
|
||||
*/
|
||||
router.all('/', (req, res, next) => {
|
||||
logger.log('debug', `The record API was invoked: ${req.url}`)
|
||||
next() // pass control to the next handler
|
||||
})
|
||||
|
||||
/**
|
||||
* GET endpoint for starting the remote browser recording session.
|
||||
* returns session's id
|
||||
*/
|
||||
router.get('/start', (req, res) => {
|
||||
const id = initializeRemoteBrowserForRecording({
|
||||
browser: chromium,
|
||||
launchOptions: {
|
||||
headless: true,
|
||||
}
|
||||
});
|
||||
return res.send(id);
|
||||
});
|
||||
|
||||
/**
|
||||
* POST endpoint for starting the remote browser recording session accepting browser launch options.
|
||||
* returns session's id
|
||||
*/
|
||||
router.post('/start', (req, res) => {
|
||||
const id = initializeRemoteBrowserForRecording({
|
||||
browser: chromium,
|
||||
launchOptions: req.body,
|
||||
});
|
||||
return res.send(id);
|
||||
});
|
||||
|
||||
/**
|
||||
* GET endpoint for terminating the remote browser recording session.
|
||||
* returns whether the termination was successful
|
||||
*/
|
||||
router.get('/stop/:browserId', async (req, res) => {
|
||||
const success = await destroyRemoteBrowser(req.params.browserId);
|
||||
return res.send(success);
|
||||
});
|
||||
|
||||
/**
|
||||
* GET endpoint for getting the id of the active remote browser.
|
||||
*/
|
||||
router.get('/active', (req, res) => {
|
||||
const id = getActiveBrowserId();
|
||||
return res.send(id);
|
||||
});
|
||||
|
||||
/**
|
||||
* GET endpoint for getting the current url of the active remote browser.
|
||||
*/
|
||||
router.get('/active/url', (req, res) => {
|
||||
const id = getActiveBrowserId();
|
||||
if (id) {
|
||||
const url = getRemoteBrowserCurrentUrl(id);
|
||||
return res.send(url);
|
||||
}
|
||||
return res.send(null);
|
||||
});
|
||||
|
||||
/**
|
||||
* GET endpoint for getting the current tabs of the active remote browser.
|
||||
*/
|
||||
router.get('/active/tabs', (req, res) => {
|
||||
const id = getActiveBrowserId();
|
||||
if (id) {
|
||||
const hosts = getRemoteBrowserCurrentTabs(id);
|
||||
return res.send(hosts);
|
||||
}
|
||||
return res.send([]);
|
||||
});
|
||||
|
||||
/**
|
||||
* GET endpoint for starting an interpretation of the currently generated workflow.
|
||||
*/
|
||||
router.get('/interpret', async (req, res) => {
|
||||
try {
|
||||
await interpretWholeWorkflow();
|
||||
return res.send('interpretation done');
|
||||
} catch (e) {
|
||||
return res.send('interpretation done');
|
||||
return res.status(400);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* GET endpoint for stopping an ongoing interpretation of the currently generated workflow.
|
||||
*/
|
||||
router.get('/interpret/stop', async (req, res) => {
|
||||
await stopRunningInterpretation();
|
||||
return res.send('interpretation stopped');
|
||||
});
|
||||
123
server/src/routes/workflow.ts
Normal file
123
server/src/routes/workflow.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* RESTful API endpoints handling currently generated workflow management.
|
||||
*/
|
||||
|
||||
import { Router } from 'express';
|
||||
import logger from "../logger";
|
||||
import { browserPool } from "../server";
|
||||
import { readFile } from "../workflow-management/storage";
|
||||
|
||||
export const router = Router();
|
||||
|
||||
/**
|
||||
* Logs information about workflow API.
|
||||
*/
|
||||
router.all('/', (req, res, next) => {
|
||||
logger.log('debug', `The workflow API was invoked: ${req.url}`)
|
||||
next() // pass control to the next handler
|
||||
})
|
||||
|
||||
/**
|
||||
* GET endpoint for a recording linked to a remote browser instance.
|
||||
* returns session's id
|
||||
*/
|
||||
router.get('/:browserId', (req, res) => {
|
||||
const activeBrowser = browserPool.getRemoteBrowser(req.params.browserId);
|
||||
let workflowFile = null;
|
||||
if (activeBrowser && activeBrowser.generator) {
|
||||
workflowFile = activeBrowser.generator.getWorkflowFile();
|
||||
}
|
||||
return res.send(workflowFile);
|
||||
});
|
||||
|
||||
/**
|
||||
* Get endpoint returning the parameter array of the recording associated with the browserId browser instance.
|
||||
*/
|
||||
router.get('/params/:browserId', (req, res) => {
|
||||
const activeBrowser = browserPool.getRemoteBrowser(req.params.browserId);
|
||||
let params = null;
|
||||
if (activeBrowser && activeBrowser.generator) {
|
||||
params = activeBrowser.generator.getParams();
|
||||
}
|
||||
return res.send(params);
|
||||
});
|
||||
|
||||
/**
|
||||
* DELETE endpoint for deleting a pair from the generated workflow.
|
||||
*/
|
||||
router.delete('/pair/:index', (req, res) => {
|
||||
const id = browserPool.getActiveBrowserId();
|
||||
if (id) {
|
||||
const browser = browserPool.getRemoteBrowser(id);
|
||||
if (browser) {
|
||||
browser.generator?.removePairFromWorkflow(parseInt(req.params.index));
|
||||
const workflowFile = browser.generator?.getWorkflowFile();
|
||||
return res.send(workflowFile);
|
||||
}
|
||||
}
|
||||
return res.send(null);
|
||||
});
|
||||
|
||||
/**
|
||||
* POST endpoint for adding a pair to the generated workflow.
|
||||
*/
|
||||
router.post('/pair/:index', (req, res) => {
|
||||
const id = browserPool.getActiveBrowserId();
|
||||
if (id) {
|
||||
const browser = browserPool.getRemoteBrowser(id);
|
||||
logger.log('debug', `Adding pair to workflow`);
|
||||
if (browser) {
|
||||
logger.log('debug', `Adding pair to workflow: ${JSON.stringify(req.body)}`);
|
||||
if (req.body.pair) {
|
||||
browser.generator?.addPairToWorkflow(parseInt(req.params.index), req.body.pair);
|
||||
const workflowFile = browser.generator?.getWorkflowFile();
|
||||
return res.send(workflowFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res.send(null);
|
||||
});
|
||||
|
||||
/**
|
||||
* PUT endpoint for updating a pair in the generated workflow.
|
||||
*/
|
||||
router.put('/pair/:index', (req, res) => {
|
||||
const id = browserPool.getActiveBrowserId();
|
||||
if (id) {
|
||||
const browser = browserPool.getRemoteBrowser(id);
|
||||
logger.log('debug', `Updating pair in workflow`);
|
||||
if (browser) {
|
||||
logger.log('debug', `New value: ${JSON.stringify(req.body)}`);
|
||||
if (req.body.pair) {
|
||||
browser.generator?.updatePairInWorkflow(parseInt(req.params.index), req.body.pair);
|
||||
const workflowFile = browser.generator?.getWorkflowFile();
|
||||
return res.send(workflowFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res.send(null);
|
||||
});
|
||||
|
||||
/**
|
||||
* PUT endpoint for updating the currently generated workflow file from the one in the storage.
|
||||
*/
|
||||
router.put('/:browserId/:fileName', async (req, res) => {
|
||||
try {
|
||||
const browser = browserPool.getRemoteBrowser(req.params.browserId);
|
||||
logger.log('debug', `Updating workflow file`);
|
||||
if (browser && browser.generator) {
|
||||
const recording = await readFile(`./../storage/recordings/${req.params.fileName}.waw.json`)
|
||||
const parsedRecording = JSON.parse(recording);
|
||||
if (parsedRecording.recording) {
|
||||
browser.generator?.updateWorkflowFile(parsedRecording.recording, parsedRecording.recording_meta);
|
||||
const workflowFile = browser.generator?.getWorkflowFile();
|
||||
return res.send(workflowFile);
|
||||
}
|
||||
}
|
||||
return res.send(null);
|
||||
} catch (e) {
|
||||
const { message } = e as Error;
|
||||
logger.log('info', `Error while reading a recording with name: ${req.params.fileName}.waw.json`);
|
||||
return res.send(null);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user