var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { ExternalObjectMetadata } from './externalobjectmetadata';
/**
* External object.
* <br/><span style="color: red;">ou <strong>should never</strong> instantiate this class directly
* but rather call <code>getExternalObject</code></span>.
* @class
*/
class ExternalObject {
/**
* Constructor
* @param {Session} ses Session
* @param {string} name Business object name
*/
constructor(ses, name) {
/**
* Alias to <code>call</code>
* @function
*/
this.invoke = this.call;
this.session = ses;
this.metadata = new ExternalObjectMetadata(name);
this.path = `${this.session.parameters.extpath}/${encodeURIComponent(name)}`;
}
/**
* Get name
* @return {string} Name
* @function
*/
getName() {
return this.metadata.name;
}
/**
* Build URL-encoded parameters
* @param {object} params URL parameters as key/value pairs
* @return {string} URL-encoded parameters
* @function
*/
callParams(params) {
let p = '';
if (!params)
return p;
for (const i of Object.entries(params)) {
const k = i[0];
const v = i[1] || '';
if (v.sort) { // Array ?
for (const vv of v)
p += (p !== '' ? '&' : '') + k + '=' + encodeURIComponent(vv);
}
else {
p += (p !== '' ? '&' : '') + k + '=' + encodeURIComponent(v);
}
}
return p;
}
/**
* Call an external object
* @param {object} [params] Optional URL parameters
* @param {object|string|FormData} [data] Optional body data (for 'POST' and 'PUT' methods only)
* @param {object} [opts] Options
* @param {string} [opts.path] Absolute or relative path (e.g. absolute '/my/mapped/path' or relative 'my/additional/path')
* @param {object} [opts.method] Optional method 'GET', 'POST', 'PUT' or 'DELETE' (defaults to 'GET' if data is not set or 'POST' if data is set)
* @param {function} [opts.contentType] Optional data content type (for 'POST' and 'PUT' methods only)
* @param {function} [opts.accept] Optional accepted response type (e.g. 'application/json")
* @param {function} [opts.error] Error handler function
* @param {string} [opts.businessCase] Business case label
* @return {promise<object>} Promise to the external object content
* @function
*/
call(params, data, opts) {
return __awaiter(this, void 0, void 0, function* () {
const origin = 'ExternalObject.call';
const ses = this.session;
opts = opts || {};
return new Promise((resolve, reject) => {
let p = '';
if (params)
p = this.callParams(params);
if (opts.businessCase)
p += `_bc=${encodeURIComponent(opts.businessCase)}`;
const m = opts.method ? opts.method.toUpperCase() : (data ? 'POST' : 'GET');
const h = {};
if (opts.contentType) {
h['content-type'] = opts.contentType;
}
else if (data && !(data instanceof FormData)) { // Try to guess type...
h['content-type'] = typeof data === 'string' ? 'application/x-www-form-urlencoded' : 'application/json';
} // FormData = multipart/form-data with boundary string => handled by fetch
//if (ses.parameters.compress)
// h['content-encoding'] = 'gzip';
if (opts.accept)
h.accept = opts.accept === 'json' ? 'application/json' : opts.accept;
let b = ses.getBearerTokenHeader();
if (b) {
h[ses.authheader] = b;
}
else {
b = ses.getBasicAuthHeader();
if (b)
h[ses.authheader] = b;
}
const u = ses.parameters.url + (opts.path && opts.path.startsWith('/') ? opts.path : this.path + (opts.path ? '/' + opts.path : '')) + (p !== '' ? '?' + p : '');
const d = data ? (typeof data === 'string' || data instanceof FormData ? data : JSON.stringify(data)) : undefined;
ses.debug('[simplicite.ExternalObject.call] ' + m + ' ' + u + (d ? ' with ' + d : ''));
fetch(u, {
method: m,
headers: h,
//compress: ses.parameters.compress,
signal: AbortSignal.timeout(ses.parameters.timeout),
body: d
}).then((res) => {
const type = res.headers.get('content-type');
ses.debug(`[${origin}] HTTP status = ${res.status}, response content type = ${type}`);
if (type && type.startsWith('application/json')) { // JSON
res.json().then(jsonData => {
resolve.call(this, jsonData, res.status, res.headers);
}).catch((err) => {
err = ses.getError(err, undefined, origin);
if (!(opts.error || ses.error).call(this, err))
reject.call(this, err);
});
}
else if (type && (type.startsWith('text/') || type.startsWith('application/yaml'))) { // Text
res.text().then(textData => {
resolve.call(this, textData, res.status, res.headers);
}).catch((err) => {
err = ses.getError(err, undefined, origin);
if (!(opts.error || ses.error).call(this, err))
reject.call(this, err);
});
}
else { // Binary
res.arrayBuffer().then(binData => {
resolve.call(this, binData, res.status, res.headers);
}).catch((err) => {
err = ses.getError(err, undefined, origin);
if (!(opts.error || ses.error).call(this, err))
reject.call(this, err);
});
}
}).catch((err) => {
err = ses.getError(err, undefined, origin);
if (!(opts.error || ses.error).call(this, err))
reject.call(this, err);
});
});
});
}
}
export { ExternalObject };
//# sourceMappingURL=externalobject.js.map