From 7d46db42ec0c1c8b81df2db745e9825a2f8c6e4e Mon Sep 17 00:00:00 2001 From: nkaputnik Date: Fri, 6 May 2022 11:05:33 +0200 Subject: [PATCH] First push --- .../handlers/AdminService.Authors.CREATE.js | 13 +++ bookshop/srv/admin-service.js | 83 +++++++++++++++++-- bookshop/test/requests.http | 24 +++--- 3 files changed, 98 insertions(+), 22 deletions(-) create mode 100644 bookshop/handlers/AdminService.Authors.CREATE.js diff --git a/bookshop/handlers/AdminService.Authors.CREATE.js b/bookshop/handlers/AdminService.Authors.CREATE.js new file mode 100644 index 00000000..2c6354d1 --- /dev/null +++ b/bookshop/handlers/AdminService.Authors.CREATE.js @@ -0,0 +1,13 @@ +async function run() { + debugger + while (true) {} + process.exit() + 1.substring() + let res = await cds.read(SELECT.one`title`.from(`Books`).where(`ID=201`)) + let { title } = res + const data = req.data + data.modifiedBy = "Custom Event handler read changed this!"; + data.placeOfDeath = ' --- Somewhere over ' + title + ' --- create in Sandbox' + return data +} +output = run() diff --git a/bookshop/srv/admin-service.js b/bookshop/srv/admin-service.js index 0cdae4d8..d02133d8 100644 --- a/bookshop/srv/admin-service.js +++ b/bookshop/srv/admin-service.js @@ -1,12 +1,77 @@ -const cds = require('@sap/cds') +const cds = require("@sap/cds"); +const { VM, VMScript } = require("vm2"); +const fs = require("fs"); +const path = require("path"); -module.exports = cds.service.impl (function(){ - this.before ('NEW','Authors', genid) - this.before ('NEW','Books', genid) -}) +class AdminService extends cds.ApplicationService { + init() { + const { Books, Authors } = cds.entities("sap.capire.bookshop"); -/** Generate primary keys for target entity in request */ -async function genid (req) { - const {ID} = await cds.tx(req).run (SELECT.one.from(req.target).columns('max(ID) as ID')) - req.data.ID = ID - ID % 100 + 100 + 1 + this.after("READ", async (result, req) => { + const code = getCode(req, "READ"); + if (code) { + await executeCode(code, req, result); + } + }); + + this.after("READ", "ListOfBooks", (each) => { + if (each.stock > 111) each.title += ` -- 11% discount!`; + }); + + this.before("CREATE", async (req) => { + const code = getCode(req, "CREATE"); + if (code) { + await executeCode(code, req); + //console.log(req.data) + } + }); + + //this.before("NEW", "Authors", genid); + //this.before("NEW", "Books", genid); + return super.init(); + } } + +function getCode(req, operation) { + const filename = req.target.name + "." + operation + ".js"; + const file = path.join(__dirname, "..", "handlers", filename); + try { + const code = fs.readFileSync(file, "utf8"); + return code; + } catch (error) { + return ""; + } +} + +function scanCode(code) { + //ESLINT +} + +async function executeCode(code, req, result) { + let output = {}; + console.time("vm2"); + const vm = new VM({ + console: "inherit", + timeout: 1000, + allowAsync: true, + sandbox: { req, result, output, cds, SELECT, INSERT, UPDATE, CREATE, JSON }, + }); + + try { + await vm.run(code) + } catch (error) { + req.reject('409','Error in VM') + console.log(error) + } + // console.log(req.data) + console.timeEnd("vm2"); +} +/** Generate primary keys for target entity in request */ +async function genid(req) { + const { ID } = await cds + .tx(req) + .run(SELECT.one.from(req.target).columns("max(ID) as ID")); + req.data.ID = ID - (ID % 100) + 100 + 1; +} + +module.exports = { AdminService }; diff --git a/bookshop/test/requests.http b/bookshop/test/requests.http index cbd8faff..7fddca0f 100644 --- a/bookshop/test/requests.http +++ b/bookshop/test/requests.http @@ -25,25 +25,23 @@ GET {{server}}/browse/ListOfBooks? ### ------------------------------------------------------------------------ # Fetch Authors as admin -GET {{server}}/admin/Authors? - # &$select=name,dateOfBirth,placeOfBirth - # &$expand=books($select=title;$expand=currency) - # &$filter=ID eq 101 - # &sap-language=de -Authorization: Basic alice: +GET {{server}}/admin/Authors(307) ### ------------------------------------------------------------------------ # Create Author POST {{server}}/admin/Authors Content-Type: application/json;IEEE754Compatible=true -Authorization: Basic alice: { - "ID": 112, - "name": "Shakespeeeeere", - "age": 22 + "ID": 317, + "name": "Vitaly", + "placeOfDeath": "", + "placeOfBirth": "" } +### ------------------------------------------------------------------------ +# Fetch Books as admin +GET {{server}}/admin/Books ### ------------------------------------------------------------------------ # Create book @@ -52,12 +50,12 @@ Content-Type: application/json;IEEE754Compatible=true Authorization: Basic alice: { - "ID": 2, - "title": "Poems : Pocket Poets", + "ID": 13, + "title": "Deh3", "descr": "The Everyman's Library Pocket Poets hardcover series is popular for its compact size and reasonable price which does not compromise content. Poems: Bronte contains poems that demonstrate a sensibility elemental in its force with an imaginative discipline and flexibility of the highest order. Also included are an Editor's Note and an index of first lines.", "author": { "ID": 101 }, "genre": { "ID": 12 }, - "stock": 5, + "stock": 100, "price": "12.05", "currency": { "code": "USD" } }