dfp-lib
Version:
This project hosts the Node.JS client library for the SOAP-based DFP API at Google.
215 lines (214 loc) • 7.64 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const xml2js = require("xml2js");
const xmlElement_1 = require("../soap/xmlElement");
class SoapClient {
constructor(wsdl, xmlns, user, classmap) {
this.user = user;
this.endpoint = wsdl;
this.soapHeaders = {};
this.httpHeaders = {};
this.lastRequest = {};
this.lastResponse = {};
this.namespace = xmlns;
this.lastElapsedTime = 0;
this.classmap = classmap || {};
this.xmlBuilder = new xml2js.Builder();
}
__soapCall(functionName, args, soapRequestHeader, httpHeaders = {}) {
return __awaiter(this, void 0, void 0, function* () {
const body = {};
body[functionName] = args;
let xml = this.xmlBuilder.buildObject({
'soapenv:Envelope': {
$: {
'xmlns:soapenv': 'http://schemas.xmlsoap.org/soap/envelope/',
'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
'xmlns': this.namespace
},
'soapenv:Header': {
RequestHeader: soapRequestHeader
},
'soapenv:Body': this.__prepareSoapBody(body)
}
});
return yield this.__makeRequest(xml, httpHeaders);
});
}
postRequest(options) {
return __awaiter(this, void 0, void 0, function* () {
const requestHandler = this.user.getRequestHandler();
return new Promise(function (resolve, reject) {
requestHandler.post(options, function (err, response) {
const out = {
error: err,
response: response
};
(err) ? reject(out) : resolve(out);
});
});
});
}
parseXML(xml) {
return __awaiter(this, void 0, void 0, function* () {
const options = {
explicitArray: false,
ignoreAttrs: !this.classmap,
tagNameProcessors: [
xml2js.processors.stripPrefix
],
valueProcessors: [
xml2js.processors.parseNumbers
]
};
return new Promise(function (resolve, reject) {
xml2js.parseString(xml, options, function (err, result) {
if (err) {
reject(err);
}
else {
resolve(result);
}
});
});
});
}
__makeRequest(xml, httpHeaders = {}) {
return __awaiter(this, void 0, void 0, function* () {
const options = {
url: this.endpoint,
qs: {
wsdl: ''
},
body: xml,
time: true,
gzip: true,
headers: Object.assign({
'Content-Type': 'text/xml; charset=utf-8'
}, httpHeaders)
};
let out = null;
try {
out = yield this.postRequest(options);
}
catch (_out) {
out = _out;
}
const response = out.response;
this.lastRequest = response.request;
this.lastResponse = response;
this.lastElapsedTime = response.elapsedTime;
response.body = this.__parseSoapBody(yield this.parseXML(response.body));
if (out.error) {
this.lastError = out.error;
throw out.error;
}
return response.body;
});
}
__prepareSoapBody(obj) {
if (!(obj instanceof Object)) {
return obj;
}
const root = (obj instanceof Array) ? new Array(obj.length) : { $: {} };
for (let head = { obj: obj, soap: root, next: null }, tail = head; head; head = head.next) {
if (head.obj instanceof xmlElement_1.XMLElement) {
const xsiType = head.obj.constructor.XSI_TYPE;
if (xsiType) {
head.soap.$['xsi:type'] = xsiType;
}
}
for (let key in head.obj) {
if (head.obj.hasOwnProperty(key)) {
const child = head.obj[key];
if ((child instanceof Object) && !(child instanceof Function)) {
tail = tail.next = {
obj: child,
soap: head.soap[key] = (child instanceof Array) ? new Array(child.length) : { $: {} }
};
}
else if (child != null) {
head.soap[key] = child;
}
}
}
}
return root;
}
__getLocation() {
return this.endpoint;
}
__setLocation(endpoint) {
this.endpoint = endpoint;
}
__getHeader(key) {
return this.soapHeaders[key];
}
__setHeader(key, value) {
this.soapHeaders[key] = value;
}
__clearHeaders() {
this.soapHeaders = {};
}
__clearHttpHeaders() {
this.httpHeaders = {};
}
__getHttpHeader(key) {
return this.httpHeaders[key];
}
__setHttpHeader(key, value) {
this.httpHeaders[key] = value;
}
__getLastResponse() {
return this.lastResponse;
}
__getLastResponseHeaders() {
return this.lastResponse.headers;
}
__getLastRequestHeaders() {
return this.lastRequest.headers;
}
__parseSoapBody(body) {
if (!this.classmap || !(body instanceof Object)) {
return body;
}
const root = { body: body };
let head = { obj: body, parent: root, key: 'body', next: null };
do {
const node = head;
head = head.next;
const parent = node.obj;
for (let key in parent) {
const child = parent[key];
if (parent.hasOwnProperty(key) && (child instanceof Object) && !(child instanceof Function)) {
head = {
obj: child,
parent: parent,
key: key,
next: head
};
}
}
if (parent.$) {
const xsiClass = this.classmap[parent.$['xsi:type']];
if (xsiClass) {
const obj = node.parent[node.key] = new xsiClass();
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
obj[key] = parent[key];
}
}
}
}
} while (head);
return root.body;
}
}
exports.SoapClient = SoapClient;