/**
@license
* @pnp/sp-clientsvc v1.2.1 - pnp - Provides core functionality to interact with the legacy client.svc SharePoint endpoint
* MIT (https://github.com/pnp/pnpjs/blob/master/LICENSE)
* Copyright (c) 2018 Microsoft
* docs: https://pnp.github.io/pnpjs/
* source: https:github.com/pnp/pnpjs
* bugs: https://github.com/pnp/pnpjs/issues
*/
import { extend, objectDefinedNotNull, getAttrValueFromString, jsS, hOP, combine, getGUID, mergeHeaders, mergeOptions, getHashCode } from '@pnp/common';
import { __extends } from 'tslib';
import { CachingOptions, Queryable, CachingParserWrapper, ODataBatch } from '@pnp/odata';
import { SPHttpClient, toAbsoluteUrl } from '@pnp/sp';
import { Logger } from '@pnp/logging';
function objectPath() {
return "";
}
function identityQuery() {
return "";
}
function opQuery(selectProperties, childSelectProperties) {
// this is fairly opaque behavior, but is the simplest way to convey the required information.
// if selectProperties.length === 0 or null then select all
// else select indicated properties
if (selectProperties === void 0) { selectProperties = null; }
if (childSelectProperties === void 0) { childSelectProperties = null; }
// if childSelectProperties === null do not include that block
// if childSelectProperties.length === 0 then select all
// else select indicated properties
var builder = [];
builder.push("");
if (selectProperties === null || selectProperties.length < 1) {
builder.push("");
builder.push("");
builder.push("");
}
else {
builder.push("");
builder.push("");
[].push.apply(builder, selectProperties.map(function (p) { return ""; }));
builder.push("");
builder.push("");
}
if (childSelectProperties !== null) {
if (childSelectProperties.length < 1) {
builder.push("");
builder.push("");
builder.push("");
}
else {
builder.push("");
builder.push("");
[].push.apply(builder, childSelectProperties.map(function (p) { return ""; }));
builder.push("");
builder.push("");
}
}
builder.push("");
return builder.join("");
}
function setProperty(name, type, value) {
var builder = [];
builder.push("");
builder.push("" + value + "");
builder.push("");
return builder.join("");
}
function methodAction(name, params) {
var builder = [];
builder.push("");
if (params !== null) {
var arrParams = params.toArray();
if (arrParams.length < 1) {
builder.push("");
}
else {
builder.push("");
[].push.apply(builder, arrParams.map(function (p) { return "" + p.value + ""; }));
builder.push("");
}
}
builder.push("");
return builder.join("");
}
function objectProperties(o) {
return Object.getOwnPropertyNames(o).map(function (name) {
var value = o[name];
if (typeof value === "boolean") {
return setProperty(name, "Boolean", "" + value);
}
else if (typeof value === "number") {
return setProperty(name, "Number", "" + value);
}
else if (typeof value === "string") {
return setProperty(name, "String", "" + value);
}
return "";
}, []);
}
function property(name) {
var actions = [];
for (var _i = 1; _i < arguments.length; _i++) {
actions[_i - 1] = arguments[_i];
}
return new ObjectPath("", actions);
}
function staticMethod(name, typeId) {
var actions = [];
for (var _i = 2; _i < arguments.length; _i++) {
actions[_i - 2] = arguments[_i];
}
return new ObjectPath("", actions);
}
function staticProperty(name, typeId) {
var actions = [];
for (var _i = 2; _i < arguments.length; _i++) {
actions[_i - 2] = arguments[_i];
}
return new ObjectPath("", actions);
}
function objConstructor(typeId) {
var actions = [];
for (var _i = 1; _i < arguments.length; _i++) {
actions[_i - 1] = arguments[_i];
}
return new ObjectPath("", actions);
}
/**
* Used to build parameters when calling methods
*/
var MethodParams = /** @class */ (function () {
function MethodParams(_p) {
if (_p === void 0) { _p = []; }
this._p = _p;
}
MethodParams.build = function (initValues) {
if (initValues === void 0) { initValues = []; }
var params = new MethodParams();
[].push.apply(params._p, initValues);
return params;
};
MethodParams.prototype.string = function (value) {
return this.a("String", value);
};
MethodParams.prototype.number = function (value) {
return this.a("Number", value.toString());
};
MethodParams.prototype.boolean = function (value) {
return this.a("Boolean", value.toString());
};
MethodParams.prototype.objectPath = function (inputIndex) {
return this.a("ObjectPath", inputIndex.toString());
};
MethodParams.prototype.toArray = function () {
return this._p;
};
MethodParams.prototype.a = function (type, value) {
this._p.push({ type: type, value: value });
return this;
};
return MethodParams;
}());
function method(name, params) {
var actions = [];
for (var _i = 2; _i < arguments.length; _i++) {
actions[_i - 2] = arguments[_i];
}
var builder = [];
builder.push("");
if (params !== null) {
var arrParams = params.toArray();
if (arrParams.length < 1) {
builder.push("");
}
else {
builder.push("");
[].push.apply(builder, arrParams.map(function (p) {
if (p.type === "ObjectPath") {
return "";
}
return "" + p.value + "";
}));
builder.push("");
}
}
builder.push("");
return new ObjectPath(builder.join(""), actions);
}
/**
* Transforms an array of object paths into a request xml body. Does not do placeholder substitutions.
*
* @param objectPaths The object paths for which we want to generate a body
*/
function writeObjectPathBody(objectPaths) {
var actions = [];
var paths = [];
objectPaths.forEach(function (op) {
paths.push(op.path);
actions.push.apply(actions, op.actions);
});
// create our xml payload
return [
"",
"",
actions.join(""),
"",
"",
paths.join(""),
"",
"",
].join("");
}
/**
* Represents an ObjectPath used when querying ProcessQuery
*/
var ObjectPath = /** @class */ (function () {
function ObjectPath(path, actions, id, replaceAfter) {
if (actions === void 0) { actions = []; }
if (id === void 0) { id = -1; }
if (replaceAfter === void 0) { replaceAfter = []; }
this.path = path;
this.actions = actions;
this.id = id;
this.replaceAfter = replaceAfter;
}
return ObjectPath;
}());
/**
* Replaces all found instance of the $$ID$$ placeholder in the supplied xml string
*
* @param id New value to be insterted
* @param xml The existing xml fragment in which the replace should occur
*/
function opSetId(id, xml) {
return xml.replace(/\$\$ID\$\$/g, id);
}
/**
* Replaces all found instance of the $$PATH_ID$$ placeholder in the supplied xml string
*
* @param id New value to be insterted
* @param xml The existing xml fragment in which the replace should occur
*/
function opSetPathId(id, xml) {
return xml.replace(/\$\$PATH_ID\$\$/g, id);
}
/**
* Replaces all found instance of the $$PARENT_ID$$ placeholder in the supplied xml string
*
* @param id New value to be insterted
* @param xml The existing xml fragment in which the replace should occur
*/
function opSetParentId(id, xml) {
return xml.replace(/\$\$PARENT_ID\$\$/g, id);
}
/**
* Replaces all found instance of the $$OP_PARAM_ID$$ placeholder in the supplied xml string
*
* @param map A mapping where [index] = replaced_object_path_id
* @param xml The existing xml fragment in which the replace should occur
* @param indexMapper Used when creating batches, not meant for direct use external to this library
*/
function opSetPathParamId(map, xml, indexMapper) {
if (indexMapper === void 0) { indexMapper = function (n) { return n; }; }
// this approach works because input params must come before the things that need them
// meaning the right id will always be in the map
var matches = /\$\$OP_PARAM_ID_(\d+)\$\$/ig.exec(xml);
if (matches !== null) {
for (var i = 1; i < matches.length; i++) {
var index = parseInt(matches[i], 10);
var regex = new RegExp("\\$\\$OP_PARAM_ID_" + index + "\\$\\$", "ig");
xml = xml.replace(regex, map[indexMapper(index)].toString());
}
}
return xml;
}
/**
* Represents a collection of IObjectPaths
*/
var ObjectPathQueue = /** @class */ (function () {
function ObjectPathQueue(_paths, _relationships) {
if (_paths === void 0) { _paths = []; }
if (_relationships === void 0) { _relationships = {}; }
this._paths = _paths;
this._relationships = _relationships;
this._contextIndex = -1;
this._siteIndex = -1;
this._webIndex = -1;
}
/**
* Adds an object path to the queue
*
* @param op The action to add
* @returns The index of the added object path
*/
ObjectPathQueue.prototype.add = function (op) {
this.dirty();
this._paths.push(op);
return this.lastIndex;
};
ObjectPathQueue.prototype.addChildRelationship = function (parentIndex, childIndex) {
if (objectDefinedNotNull(this._relationships["_" + parentIndex])) {
this._relationships["_" + parentIndex].push(childIndex);
}
else {
this._relationships["_" + parentIndex] = [childIndex];
}
};
ObjectPathQueue.prototype.getChildRelationship = function (parentIndex) {
if (objectDefinedNotNull(this._relationships["_" + parentIndex])) {
return this._relationships["_" + parentIndex];
}
else {
return [];
}
};
ObjectPathQueue.prototype.getChildRelationships = function () {
return this._relationships;
};
/**
* Appends an action to the supplied IObjectPath, replacing placeholders
*
* @param op IObjectPath to which the action will be appended
* @param action The action to append
*/
ObjectPathQueue.prototype.appendAction = function (op, action) {
this.dirty();
op.actions.push(action);
return this;
};
/**
* Appends an action to the last IObjectPath in the collection
*
* @param action
*/
ObjectPathQueue.prototype.appendActionToLast = function (action) {
this.dirty();
return this.appendAction(this.last, action);
};
/**
* Creates a copy of this ObjectPathQueue
*/
ObjectPathQueue.prototype.clone = function () {
var clone = new ObjectPathQueue(this.toArray(), extend({}, this._relationships));
clone._contextIndex = this._contextIndex;
clone._siteIndex = this._siteIndex;
clone._webIndex = this._webIndex;
return clone;
};
/**
* Gets a copy of this instance's paths
*/
ObjectPathQueue.prototype.toArray = function () {
return this._paths.slice(0);
};
Object.defineProperty(ObjectPathQueue.prototype, "last", {
/**
* The last IObjectPath instance added to this collection
*/
get: function () {
if (this._paths.length < 1) {
return null;
}
return this._paths[this.lastIndex];
},
enumerable: true,
configurable: true
});
Object.defineProperty(ObjectPathQueue.prototype, "lastIndex", {
/**
* Index of the last IObjectPath added to the queue
*/
get: function () {
return this._paths.length - 1;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ObjectPathQueue.prototype, "siteIndex", {
/**
* Gets the index of the current site in the queue
*/
get: function () {
if (this._siteIndex < 0) {
// this needs to be here in case we create it
var contextIndex = this.contextIndex;
this._siteIndex = this.add(property("Site",
// actions
objectPath()));
this.addChildRelationship(contextIndex, this._siteIndex);
}
return this._siteIndex;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ObjectPathQueue.prototype, "webIndex", {
/**
* Gets the index of the current web in the queue
*/
get: function () {
if (this._webIndex < 0) {
// this needs to be here in case we create it
var contextIndex = this.contextIndex;
this._webIndex = this.add(property("Web",
// actions
objectPath()));
this.addChildRelationship(contextIndex, this._webIndex);
}
return this._webIndex;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ObjectPathQueue.prototype, "contextIndex", {
/**
* Gets the index of the Current context in the queue, can be used to establish parent -> child rels
*/
get: function () {
if (this._contextIndex < 0) {
this._contextIndex = this.add(staticProperty("Current", "{3747adcd-a3c3-41b9-bfab-4a64dd2f1e0a}",
// actions
objectPath()));
}
return this._contextIndex;
},
enumerable: true,
configurable: true
});
ObjectPathQueue.prototype.toBody = function () {
if (objectDefinedNotNull(this._xml)) {
return this._xml;
}
// create our xml payload
this._xml = writeObjectPathBody(this.toIndexedTree());
return this._xml;
};
/**
* Conducts the string replacements for id, parent id, and path id
*
* @returns The tree with all string replacements made
*/
ObjectPathQueue.prototype.toIndexedTree = function () {
var _this = this;
var builderIndex = -1;
var lastOpId = -1;
var idIndexMap = [];
return this.toArray().map(function (op, index, arr) {
var opId = ++builderIndex;
// track the array index => opId relationship
idIndexMap.push(opId);
// do path replacements
op.path = opSetPathParamId(idIndexMap, opSetId(opId.toString(), op.path));
if (lastOpId >= 0) {
// if we have a parent do the replace
op.path = opSetParentId(lastOpId.toString(), op.path);
}
// rewrite actions with placeholders replaced
op.actions = op.actions.map(function (a) {
var actionId = ++builderIndex;
return opSetId(actionId.toString(), opSetPathId(opId.toString(), a));
});
// handle any specific child relationships
_this.getChildRelationship(index).forEach(function (childIndex) {
// set the parent id for our non-immediate children, thus removing the token so it isn't overwritten
arr[childIndex].path = opSetParentId(opId.toString(), arr[childIndex].path);
});
// and remember our last object path id for the parent replace above
lastOpId = opId;
return op;
});
};
/**
* Dirties this queue clearing any cached data
*/
ObjectPathQueue.prototype.dirty = function () {
this._xml = null;
};
return ObjectPathQueue;
}());
/**
* Used within the request pipeline to parse ProcessQuery results
*/
var ProcessQueryParser = /** @class */ (function () {
function ProcessQueryParser(op) {
this.op = op;
}
/**
* Parses the response checking for errors
*
* @param r Response object
*/
ProcessQueryParser.prototype.parse = function (r) {
var _this = this;
return r.text().then(function (t) {
if (!r.ok) {
throw new Error(t);
}
try {
return JSON.parse(t);
}
catch (e) {
// special case in ProcessQuery where we got an error back, but it is not in json format
throw new Error(t);
}
}).then(function (parsed) {
// here we need to check for an error body
if (parsed.length > 0 && hOP(parsed[0], "ErrorInfo") && parsed[0].ErrorInfo !== null) {
throw new Error(jsS(parsed[0].ErrorInfo));
}
return _this.findResult(parsed);
});
};
ProcessQueryParser.prototype.findResult = function (json) {
for (var i = 0; i < this.op.actions.length; i++) {
var a = this.op.actions[i];
// let's see if the result is null based on the ObjectPath action, if it exists
//
if (/^
if (/^ opId relationship
idIndexMap.push(opId);
var path = opSetPathParamId(idIndexMap, opSetId(opId.toString(), op.path), indexMappingFunction);
if (lastOpId >= 0) {
path = opSetParentId(lastOpId.toString(), path);
}
// rewrite actions with placeholders replaced
var opActions = op.actions.map(function (a) {
var actionId = ++_this._builderIndex;
return opSetId(actionId.toString(), opSetPathId(opId.toString(), a));
});
// handle any specific child relationships
// the childIndex is reduced by 1 because we are removing the Session Path
pathQueue.getChildRelationship(index + 1).map(function (i) { return i - 1; }).forEach(function (childIndex) {
// set the parent id for our non-immediate children
arr[childIndex].path = opSetParentId(opId.toString(), arr[childIndex].path);
});
// and remember our last object path id for the parent replace above
lastOpId = opId;
// return our now substituted path and actions as a new object path instance
return new ObjectPath(path, opActions);
}).forEach(function (op) { return _this._objectPaths.add(op); });
// get this once
var obPaths = _this._objectPaths.toArray();
// create a new parser to handle finding the result based on the path
var parser = new ProcessQueryParser(obPaths[obPaths.length - 1]);
if (request.parser instanceof CachingParserWrapper) {
// handle special case of caching
request.parser = new ProcessQueryCachingParserWrapper(parser, request.parser);
}
else {
request.parser = parser;
}
// add the request to our batch requests
_this._requests.push(request);
// remove the temp property
delete request.options.clientsvc_ObjectPaths;
});
};
BatchExecutor.prototype.execute = function () {
var _this = this;
Logger.write("[" + this.batchId + "] (" + (new Date()).getTime() + ") Executing batch with " + this._requests.length + " requests.", 1 /* Info */);
// create our request body from all the merged object paths
var options = {
body: writeObjectPathBody(this._objectPaths.toArray()),
};
Logger.write("[" + this.batchId + "] (" + (new Date()).getTime() + ") Sending batch request.", 1 /* Info */);
// send the batch
return _super.prototype.postCore.call(this, options, new BatchParser()).then(function (rawResponse) {
Logger.write("[" + _this.batchId + "] (" + (new Date()).getTime() + ") Resolving batched requests.", 1 /* Info */);
return _this._requests.reduce(function (chain, request) {
Logger.write("[" + request.id + "] (" + (new Date()).getTime() + ") Resolving request in batch " + _this.batchId + ".", 1 /* Info */);
return chain.then(function (_) { return request.parser.findResult(rawResponse).then(request.resolve).catch(request.reject); });
}, Promise.resolve());
});
};
return BatchExecutor;
}(ClientSvcQueryable));
/**
* Used to return the raw results from parsing the batch
*/
var BatchParser = /** @class */ (function (_super) {
__extends(BatchParser, _super);
function BatchParser() {
return _super.call(this, null) || this;
}
BatchParser.prototype.findResult = function (json) {
// we leave it to the individual request parsers to find their results in the raw json body
return json;
};
return BatchParser;
}(ProcessQueryParser));
/**
* Handles processing batched results that are also cached
*/
var ProcessQueryCachingParserWrapper = /** @class */ (function (_super) {
__extends(ProcessQueryCachingParserWrapper, _super);
function ProcessQueryCachingParserWrapper(parser, wrapper) {
return _super.call(this, parser, wrapper.cacheOptions) || this;
}
ProcessQueryCachingParserWrapper.prototype.findResult = function (json) {
var _this = this;
return this.parser.findResult(json).then(function (d) { return _this.cacheData(d); });
};
return ProcessQueryCachingParserWrapper;
}(CachingParserWrapper));
export { ObjectPathBatch, ClientSvcQueryable, ObjectPath, opSetId, opSetPathId, opSetParentId, opSetPathParamId, ObjectPathQueue, objectPath, identityQuery, opQuery, setProperty, methodAction, objectProperties, property, staticMethod, staticProperty, objConstructor, MethodParams, method, ProcessQueryParser, writeObjectPathBody };
//# sourceMappingURL=sp-clientsvc.es5.js.map