@sap/ams-dev
Version:
NodesJS AMS development environment
81 lines (68 loc) • 2.93 kB
JavaScript
const compressing = require("compressing");
const { addDefaultHeaders, createHTTPSAgent, filterDCLDirectory, InMemoryStream } = require('./util');
const APPNAME_HEADER = "X-Appname";
async function uploadBaseDcl(credentials, dclRoot, uploadParams) {
const bundle = await bundleDcl(dclRoot);
// Todo: Calculate SHA256 of local policies and upload only when it differs from current policies
// For comparison, use the new HEAD request to get current SHA256 from server
const request = createDclUploadRequest(credentials, bundle, uploadParams);
await postDcl(request);
}
/**
* Bundles the DCL files in the given root directory into an InMemoryStream containing a .tgz archive.
* @param {string} dclRoot
* @returns {Promise<InMemoryStream>}
*/
async function bundleDcl(dclRoot) {
const bundle = new InMemoryStream();
await filterDCLDirectory(dclRoot, async () => {
return compressing.tgz.compressDir(dclRoot, bundle, { ignoreBase: true });
});
return bundle;
}
/**
* Creates an abstract DCL upload request object for use with an arbitrary http client
* @param {object} credentials - the Identity Service credentials
* @param {InMemoryStream} bundle - the .tgz archive containing the DCL files
* @param {object} [uploadParams] - optional parameters for the upload request
* @param {string} [uploadParams.deployerAppName] - a descriptive name of this deployer application to trace back the currently deployed DCL bundle on the AMS server to its source when DCL is deployed from more than one source.
* @returns {object} - the request object
*/
function createDclUploadRequest(credentials, bundle, uploadParams) {
const appName = uploadParams.deployerAppName || "@sap/ams-dev:AmsClient";
const request = {
url: `${credentials.url}/sap/ams/v1/ams-instances/${credentials.authorization_instance_id}/dcl-upload`,
method: "POST",
headers: {
"Content-Type": "application/gzip",
[APPNAME_HEADER]: appName
},
body: bundle.getBuffer(),
agent: createHTTPSAgent(credentials)
};
addDefaultHeaders(request.headers, credentials);
return request;
}
let axios;
async function postDcl(request) {
axios ??= require("axios");
const axios_request = {
method: request.method,
url: request.url,
headers: request.headers,
data: request.body,
httpsAgent: request.agent
};
try {
await axios(axios_request);
} catch(e) {
if(e.response) {
throw new Error(`DCL upload rejected by server: ${e.statusCode} ${e.message}`);
} else if (e.request) {
throw new Error(`DCL upload could not be sent: ${e.statusCode} ${e.message}`);
} else {
throw new Error(`Error preparing DCL upload request: ${e.statusCode} ${e.message}`);
}
}
}
module.exports = uploadBaseDcl;