@pnp/odata
Version:
pnp - provides shared odata functionality and base classes
214 lines • 9.39 kB
JavaScript
import { __decorate } from "tslib";
import { assign, isFunc, hOP } from "@pnp/common";
import { Logger } from "@pnp/logging";
import { CachingOptions, CachingParserWrapper } from "./caching.js";
/**
* Resolves the context's result value
*
* @param context The current context
*/
function returnResult(context) {
Logger.log({
data: Logger.activeLogLevel === 0 /* Verbose */ ? context.result : {},
level: 1 /* Info */,
message: "[" + context.requestId + "] (" + (new Date()).getTime() + ") Returning result from pipeline. Set logging to verbose to see data.",
});
return Promise.resolve(context.result);
}
/**
* Sets the result on the context
*/
export function setResult(context, value) {
return new Promise(function (resolve) {
context.result = value;
context.hasResult = true;
resolve(context);
});
}
/**
* Invokes the next method in the provided context's pipeline
*
* @param c The current request context
*/
function next(c) {
return c.pipes.length > 0 ? c.pipes.shift()(c) : Promise.resolve(c);
}
/**
* Executes the current request context's pipeline
*
* @param context Current context
*/
export function pipe(context) {
if (context.pipes.length < 1) {
Logger.write("[" + context.requestId + "] (" + (new Date()).getTime() + ") Request pipeline contains no methods!", 3 /* Error */);
throw Error("Request pipeline contains no methods!");
}
var promise = next(context).then(function (ctx) { return returnResult(ctx); }).catch(function (e) {
Logger.error(e);
throw e;
});
if (context.isBatched) {
// this will block the batch's execute method from returning until the child requests have been resolved
context.batch.addResolveBatchDependency(promise);
}
return promise;
}
/**
* decorator factory applied to methods in the pipeline to control behavior
*/
export function requestPipelineMethod(alwaysRun) {
if (alwaysRun === void 0) { alwaysRun = false; }
return function (target, propertyKey, descriptor) {
var method = descriptor.value;
descriptor.value = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
// if we have a result already in the pipeline, pass it along and don't call the tagged method
if (!alwaysRun && args.length > 0 && hOP(args[0], "hasResult") && args[0].hasResult) {
Logger.write("[" + args[0].requestId + "] (" + (new Date()).getTime() + ") Skipping request pipeline method " + propertyKey + ", existing result in pipeline.", 0 /* Verbose */);
return Promise.resolve(args[0]);
}
// apply the tagged method
Logger.write("[" + args[0].requestId + "] (" + (new Date()).getTime() + ") Calling request pipeline method " + propertyKey + ".", 0 /* Verbose */);
// then chain the next method in the context's pipeline - allows for dynamic pipeline
return method.apply(target, args).then(function (ctx) { return next(ctx); });
};
};
}
/**
* Contains the methods used within the request pipeline
*/
var PipelineMethods = /** @class */ (function () {
function PipelineMethods() {
}
/**
* Logs the start of the request
*/
PipelineMethods.logStart = function (context) {
return new Promise(function (resolve) {
Logger.log({
data: Logger.activeLogLevel === 1 /* Info */ ? {} : context,
level: 1 /* Info */,
message: "[" + context.requestId + "] (" + (new Date()).getTime() + ") Beginning " + context.method + " request (" + context.url + ")",
});
resolve(context);
});
};
/**
* Handles caching of the request
*/
PipelineMethods.caching = function (context) {
return new Promise(function (resolve) {
// handle caching, if applicable
if (context.useCaching) {
Logger.write("[" + context.requestId + "] (" + (new Date()).getTime() + ") Caching is enabled for request, checking cache...", 1 /* Info */);
var cacheOptions = new CachingOptions(context.url.toLowerCase());
if (context.cachingOptions !== undefined) {
cacheOptions = assign(cacheOptions, context.cachingOptions);
}
// we may not have a valid store
if (cacheOptions.store !== null) {
// check if we have the data in cache and if so resolve the promise and return
var data = cacheOptions.store.get(cacheOptions.key);
if (data !== null) {
Logger.log({
data: Logger.activeLogLevel === 1 /* Info */ ? {} : data,
level: 1 /* Info */,
message: "[" + context.requestId + "] (" + (new Date()).getTime() + ") Value returned from cache.",
});
// ensure we clear any held batch dependency we are resolving from the cache
if (isFunc(context.batchDependency)) {
context.batchDependency();
}
// handle the case where a parser needs to take special actions with a cached result
if (hOP(context.parser, "hydrate")) {
data = context.parser.hydrate(data);
}
return setResult(context, data).then(function (ctx) { return resolve(ctx); });
}
}
Logger.write("[" + context.requestId + "] (" + (new Date()).getTime() + ") Value not found in cache.", 1 /* Info */);
// if we don't then wrap the supplied parser in the caching parser wrapper
// and send things on their way
context.parser = new CachingParserWrapper(context.parser, cacheOptions);
}
return resolve(context);
});
};
/**
* Sends the request
*/
PipelineMethods.send = function (context) {
return new Promise(function (resolve, reject) {
// send or batch the request
if (context.isBatched) {
var p = context.batch.add(context);
// we release the dependency here to ensure the batch does not execute until the request is added to the batch
if (isFunc(context.batchDependency)) {
context.batchDependency();
}
Logger.write("[" + context.requestId + "] (" + (new Date()).getTime() + ") Batching request in batch " + context.batch.batchId + ".", 1 /* Info */);
// we set the result as the promise which will be resolved by the batch's execution
resolve(setResult(context, p));
}
else {
Logger.write("[" + context.requestId + "] (" + (new Date()).getTime() + ") Sending request.", 1 /* Info */);
// we are not part of a batch, so proceed as normal
var client = context.clientFactory();
var opts = assign(context.options || {}, { method: context.method });
client.fetch(context.url, opts)
.then(function (response) { return context.parser.parse(response); })
.then(function (result) { return setResult(context, result); })
.then(function (ctx) { return resolve(ctx); })
.catch(function (e) { return reject(e); });
}
});
};
/**
* Logs the end of the request
*/
PipelineMethods.logEnd = function (context) {
return new Promise(function (resolve) {
if (context.isBatched) {
Logger.log({
data: Logger.activeLogLevel === 1 /* Info */ ? {} : context,
level: 1 /* Info */,
message: "[" + context.requestId + "] (" + (new Date()).getTime() + ") " + context.method + " request will complete in batch " + context.batch.batchId + ".",
});
}
else {
Logger.log({
data: Logger.activeLogLevel === 1 /* Info */ ? {} : context,
level: 1 /* Info */,
message: "[" + context.requestId + "] (" + (new Date()).getTime() + ") Completing " + context.method + " request.",
});
}
resolve(context);
});
};
__decorate([
requestPipelineMethod(true)
], PipelineMethods, "logStart", null);
__decorate([
requestPipelineMethod()
], PipelineMethods, "caching", null);
__decorate([
requestPipelineMethod()
], PipelineMethods, "send", null);
__decorate([
requestPipelineMethod(true)
], PipelineMethods, "logEnd", null);
return PipelineMethods;
}());
export { PipelineMethods };
export function getDefaultPipeline() {
return [
PipelineMethods.logStart,
PipelineMethods.caching,
PipelineMethods.send,
PipelineMethods.logEnd,
].slice(0);
}
//# sourceMappingURL=pipeline.js.map