A NodeJS wrapper for OpenUI5 to leverage tools like MockServer or ODataModel.
- Use npm to install:
npm install node-ui5
(don't forget--save
if part of your project)
require('node-ui5').then(({sap}) => {
// use sap, for instance:
sap.ui.require([
'sap/ui/model/odata/v2/ODataModel'
], async function (ODataModel) {
console.log('Creating ODataModel...')
const model = new ODataModel({
serviceUrl: 'https://services.odata.org/V2/OData/OData.svc'
})
await model.metadataLoaded()
console.log('Loading products...')
model.read('/Products', {
success: data => {
data.results.forEach(product => {
console.log(product.Name.padEnd(20, ' '), product.Description)
})
}
})
})
})
You may use the factory to specify options:
require('node-ui5/factory')({
bootstrapLocation: 'https://openui5.hana.ondemand.com/resources/sap-ui-core.js',
verbose: true
}).then(({sap}) => {
// use sap
})
You may map local directories:
require('node-ui5/factory')({
exposeAsGlobals: true,
resourceroots: {
myApp: __dirname
},
verbose: true
}).then(() => {
sap.ui.require([
"myApp/mock/server"
], function () {
/*...*/
})
})
- bootstrapLocation: provides URL of the
sap-ui-core.js
bootstrap - exposeAsGlobals: set to
true
to makewindow
andsap
be globally available in NodeJS - resourceroots: an optional dictionary for mapping resources to local folders or remote resources
- verbose: set to
true
to see details on HTTP requests and output ui5 traces - fastButIncompleteSimulation: set to
true
to replace jsdom with a faster (but incomplete) browser simulation. Can also be set by adding--fast
on the command line. - verbose: set to
true
to enable traces. Can also be set by adding--verbose
on the command line. - debug: set to
true
to enable all UI5 traces. When set, verbose mode is automatically enabled. Can also be set by adding--debug
on the command line.
The package offers specific modules available through sap.ui.define / sap.ui.require to simplify development:
'node-ui5/authenticate/basic-with-csrf'
provides a basic authentication method with x-csrf-token generation. The method expects an object composed ofurl
,user
andpassword
string values and returns a promise resolved to an object containing parameters expected by the ODataModel constructor'node-ui5/promisify'
converts some callback API onto promise API by generating Async methods:- CRUD operations of ODataModel
const CONNECTION = {
url: 'https://my.odata.system/SERVICE',
user: 'arnaud',
password: '12345'
}
require('node-ui5').then(({sap}) => {
sap.ui.require([
'sap/ui/model/odata/v2/ODataModel',
'node-ui5/authenticate/basic-with-csrf',
'node-ui5/promisify',
], async function (ODataModel, authenticate) {
const model = new ODataModel(await authenticate(CONNECTION))
await model.metadataLoaded()
console.log('Listing entities...')
var data = await model.readAsync('/EntitySet')
data.results.forEach(entity => {
let name = entity.Name
if (name.length > 40) {
name = `${name.substring(0, 37)}...`
}
console.log(name.padEnd(40, ' '), entity.Guid)
})
console.log(`Found ${data.results.length} entities`)
})
})
The package also provides a server module that implements proxy features.
require('node-ui5/serve')({
port: 8080,
mappings: [{
// http/https proxy
match: /^\/proxy\/(https?)\/(.*)/,
url: '$1://$2'
}, {
// default access to index.html
match: /^\/$/,
file: path.join(__dirname, 'index.html')
}, {
// mapping to file access
match: /(.*)/,
file: path.join(__dirname, '$1')
}]
}).on('ready', () => {
console.log('Server started')
})
The options are:
- hostname: (default:
'127.0.0.1'
) hostname the server should listen to - port: (default:
8080
) port the server should listen to - ssl: specify to implement secured http (https), it must contain the path to the private key (member
key
) and to the certificate (membercert
) - window: if you plan to use the mock mapping, the
window
object must be transmitted - verbose: (default:
true
if--verbose
or--debug
is specified on the command line) set totrue
to enable traces - mappings: an array of mapping objects as detailed below. Mappings are evaluated in the given order
A mapping object is composed of at least two members:
- match: a regular expression matching the requested URL, capturing groups can be specified and values reused in the handler using $1, $2...
- One of these handlers:
Example:
[{
// mock server mapping (with a different base URL)
match: /^\/api\/(.*)/,
mock: '/odata/TODO_SRV/$1'
}, {
// UI5 resources
match: /\/resources\/(.*)/,
ui5resources: '$1'
}, {
// http/https proxy
match: /^\/proxy\/(https?)\/(.*)/,
url: '$1://$2'
}, {
// echo service
match: /^\/echo\/(.*)$/,
custom: (request, response, textToEcho) => {
response.writeHead(200, {
'Content-Type': 'text/plain',
'Content-Length': textToEcho.length
})
response.end(textToEcho)
}
}, {
// default access to index.html
match: /^\/$/,
file: path.join(__dirname, 'index.html')
}, {
// mapping to file access
match: /(.*)/,
file: path.join(__dirname, '$1')
}]
OpenUI5 is a browser library.
Thanks to jsdom and some tweaked XHR objects, the library is loaded in a NodeJS environment.
With version 2, a faster but limited simulation of browser is implemented (and available with the fastButIncompleteSimulation option).
NOTES
CORS implementation of jsdom is prevented by the custom XHR overrides.
If you plan to install the module globally (npm install -g node-ui5
), you must define the
environment variable
NODE_PATH
with:
set NODE_PATH=%APPDATA%\npm\node_modules
on Windows environmentexport NODE_PATH=/usr/local/lib/node_modules
on a Unix-like environment
If you plan to connect to an https server with specific certificates,
make sure to declare the certificate authority with the
environment variable
NODE_EXTRA_CA_CERTS
or to ignore certificate errors by
setting the environment variable
NODE_TLS_REJECT_UNAUTHORIZED
to 0
.