UNPKG

@sap/cds

Version:

SAP Cloud Application Programming Model - CDS for Node.js

74 lines (58 loc) 2.55 kB
const cds = require('../../../') const { UPDATE, DELETE } = cds.ql const { getPreferReturnHeader } = require('../utils') const { getKeysAndParamsFromPath } = require('../../common/utils/path') /** * @param {import('../ODataAdapter')} adapter * the adapter instance in which this middleware is used */ module.exports = adapter => { const { service } = adapter return function odata_delete(req, res, next) { if (getPreferReturnHeader(req)) { const msg = "The 'return' preference is not allowed in DELETE requests" cds.error({ status: 400, message: msg }) } // REVISIT: better solution for query._propertyAccess const { SELECT: { one, from }, _propertyAccess } = req._query if (!one) { cds.error({ status: 405, message: 'Method DELETE is not allowed for entity collections' }) } const model = cds.context.model ?? service.model // payload & params const { keys, params } = getKeysAndParamsFromPath(from, { model }) const data = keys //> for read and delete, we provide keys in req.data if (_propertyAccess) data[_propertyAccess] = null //> delete of property -> set to null // query const query = _propertyAccess ? UPDATE(from).set({ [_propertyAccess]: null }) : DELETE.from(from) // cdsReq.headers should contain merged headers of envelope and subreq const headers = { ...cds.context.http.req.headers, ...req.headers } // we need a cds.Request for multiple reasons, incl. params, headers, sap-messages, read after write, ... // for UPDATE: data is already provided via query const cdsReq = adapter.request4({ query, data: query.DELETE ? data : undefined, headers, params, req, res }) // NOTES: // - only via srv.run in combination with srv.dispatch inside, // we automatically either use a single auto-managed tx for the req (i.e., insert and read after write in same tx) // or the auto-managed tx opened for the respective atomicity group, if exists // - in the then block of .run(), the transaction is committed (i.e., before sending the response) if a single auto-managed tx is used return service .run(() => { return service.dispatch(cdsReq).then(result => { // nothing to do return result }) }) .then(() => { if (res.headersSent) return adapter.sap_messages4(cdsReq, req, res) res.sendStatus(204) }) .catch(err => { adapter.sap_messages4(cdsReq, req, res) next(err) }) } }