nd-common
Version:
603 lines (594 loc) • 23.5 kB
JavaScript
import { InjectionToken, Injectable, Inject, NgModule, forwardRef } from '@angular/core';
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import { of, throwError, Observable } from 'rxjs';
import { mergeMap, map, catchError } from 'rxjs/operators';
import { CommonService, APIVersions, NetDocumentsService, HttpMethod, CallParameters, RecentDocumentType } from 'nd-common';
import { CommonModule } from '@angular/common';
import { HttpModule } from '@angular/http';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @record
*/
const ND_TOKEN_CONTROLLER = new InjectionToken('ndTokenController');
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class RestAPIBaseService {
/**
* @param {?} http
* @param {?} _token
*/
constructor(http, _token) {
this.http = http;
this.DEFAULT_REST_VERSION = APIVersions.two;
this.tokenService = _token;
}
/**
* This is the rest API call method. This method puts all the parameters in the correct order,
* get the authorization token, and handle the call. If the initial call fails because of
* 401 then the function makes the same call again after getting a new access token.
*
* Note: In order to actually see the call go out, you will need to observe it. This is done
* by subscribing to it. Search code base for implementation examples.
*
* @template T
* @param {?} p
* @param {?=} stripResponse
* @return {?} Observable<HttpResponse<any>> RxJs observable of type response, this same type should be return to the controllers caller.
*/
call(p, stripResponse = true) {
/* Construct the URL request string */
// Append: baseUrl + api version + path
p.url = this.getUrl(p.path, p.apiVersion);
/* Construct the RequestOptionsArgs object */
// Set the request method (default to GET if not specified)
if (p.method == null) {
p.method = HttpMethod.Get;
}
// If the request is a GET AND queryArgs were provided then..
if (p.method == HttpMethod.Get && p.queryArgs) {
// Flatten the queryArgs object into a string
let /** @type {?} */ queryArgs = this.generateQueryArgs(p.queryArgs);
let /** @type {?} */ appendage = "?";
// If the URL already has ? in it then..
if (p.url.indexOf(appendage) > -1) {
// Change the appendage to &
appendage = "&";
}
// Add the queryArgs to the request URL
p.url += `${appendage}${queryArgs}`;
}
// Create the header object with the authorization token if it doesn't already exist
let /** @type {?} */ httpOptions = {};
httpOptions = {
headers: this.BaseHeaders,
responseType: 'json',
observe: "response",
body: p.body
};
// Make the call
return this.http.request(p.method, p.url, httpOptions).pipe(catchError((err, caught) => {
// If the status is 401 then..
if (err.status == 401) {
// Call RenewRat to get a new access token
return this.tokenService.renew().pipe(mergeMap((token) => {
this.AccessToken = token;
p.init.headers = this.BaseHeaders;
httpOptions["headers"] = this.BaseHeaders;
return this.http.request(p.method, p.url, httpOptions);
}));
}
else if (err.status == 304) {
return of(new HttpResponse({
status: err.status
}));
}
else {
return throwError(err);
}
}), map((response) => {
if (stripResponse) {
return response.body;
}
else {
// Returning response works just fine, but we have to cast it as `any` so the TypeScript doesn't complain.
return /** @type {?} */ (response);
}
}));
}
/**
* Creates a query argument string based off of the object passed in. This uses the objects labels as the argument labels.
* @param {?} obj The object the query arguments will be based off.
* @return {?} The query argument string (without "?")
*/
generateQueryArgs(obj) {
let /** @type {?} */ queryArgs = "";
Object.keys(obj).forEach((key) => {
let /** @type {?} */ appendage = "";
// if the query args have not set any values yet then..
if (queryArgs.length) {
appendage = "&";
}
let /** @type {?} */ value = obj[key];
// If the value inside the object is an array then..
if (Array.isArray(value)) {
// If the value array has objects inside then..
if (typeof value[0] === "object") {
value = value.map((data) => {
return data.ToString();
}).join(",");
}
else {
value = value.join(",");
}
}
queryArgs += appendage + key + "=" + value;
});
return queryArgs;
}
/**
* Getter for the access token
* @return {?} The access token stored in the classes memory. If empty returns an empty string.
*/
get AccessToken() {
return this.tokenService.token;
}
/**
* Setter for the access token. NOTE: This will trim any white space from the param.
* @param {?} newToken The new access token for the RestAPI to use.
* @return {?}
*/
set AccessToken(newToken) {
this.tokenService.token = newToken.trim();
}
/**
* Gets the base url for api request. If the value has not been set, the method calls GenerateBaseUrl(), which will fill in default values.
* @return {?}
*/
get BaseUrl() {
if (!this._baseUrl) {
this._baseUrl = RestAPIBaseService.GenerateBaseUrl(this.tokenService.host, this.tokenService.useHttps);
}
return this._baseUrl;
}
/**
* Generates the host url need to make api calls
* @param {?=} host The service where the request should be made (defaults to vault.netvoyage.com)
* @param {?=} https Indicates if the request should be made via https (defaults to true)
* @param {?=} api Indicates if the request should be made against the api pool (defaults to true)
* @return {?}
*/
static GenerateBaseUrl(host = NetDocumentsService.vault, https = true, api = true) {
return `${https ? "https" : "http"}://${api ? "api." : ""}${host}`;
}
/**
* Construct the URL request string by appending: baseUrl + api version + path
* @param {?} path The controller path provided by the caller. Example: /System/info/...
* @param {?=} version The API version number the caller is directing to. If no number is provided the default verion is assumed.
* @return {?} The url the API controller will call to.
*/
getUrl(path, version) {
let /** @type {?} */ callUrl = this.BaseUrl;
callUrl += version ? version : this.DEFAULT_REST_VERSION;
callUrl += path;
return callUrl;
}
/**
* Getter for the request headers. This will add in the access token as well as the response acceptance type (JSON)
* @return {?} The Http header object.
*/
get BaseHeaders() {
return new HttpHeaders({
"Authorization": "Bearer " + this.AccessToken,
"Accept": "application/json" //,
});
}
/**
* Handle url string encoding. Ensures double encoding when necessary.
* @param {?} attribute The string to be url encoded.
* @return {?}
*/
static urlEncodeString(attribute) {
if (attribute != null) {
// Check if we have a string with special characters that will require us to double encode the component.
if (CommonService.stringContainsAny(attribute, this.ENCODING_SUBSTRINGS)) {
attribute = encodeURIComponent(attribute);
}
attribute = encodeURIComponent(attribute);
}
return attribute;
}
/**
* Prepare an attribute value for the call to the Rest API.
* Enclose in double quote marks an attribute that contains a comma or a double quote.
* Replace double quote marks with pairs of double quote marks.
* See the "Lookup table query" section of the Rest API documentation.
* @param {?} attribute user-supplied workspace attribute needing prep and encoding
* @return {?}
*/
static attributeQueryEncode(attribute) {
if (attribute && attribute.length > 0) {
// See whether the attribute contains a comma or a double quote mark.
if (attribute.indexOf(",") > -1 || attribute.indexOf('"') > -1) {
// Replace double quote marks with pairs of double quote marks.
attribute = attribute.replace(/"/g, '\"\"');
// Provide a leading double quote mark if necessary.
if (!attribute.startsWith('\"', 0)) {
attribute = `\"${attribute}`;
}
// Provide a trailing double quote mark if necessary.
if (!attribute.endsWith('\"', attribute.length)) {
attribute = `${attribute}\"`;
}
}
// Encode the attribute.
attribute = encodeURIComponent(attribute);
}
return attribute;
}
/**
* @param {?} envUrl
* @return {?}
*/
static cleanEnv(envUrl) {
const /** @type {?} */ envNBReg = /\/NB\d/;
if (!envUrl) {
return envUrl;
}
// If the envUrl is a ShareSpace and it is not in the form of /NB12345567890.nev then encode the envUrl
if (getItemType(envUrl) == "NB" && !envNBReg.test(envUrl)) {
if (envUrl.indexOf("|") < 0)
envUrl += "|0";
envUrl = encodeURI(envUrl.split("|")[0]) + "|" + envUrl.split("|")[1];
}
envUrl = envUrl.replace(/\//g, ":");
return envUrl;
}
/**
* @param {?} filter
* @return {?}
*/
static createFilterList(filter) {
let /** @type {?} */ seperator = " extension eq ";
return (seperator + filter.join(seperator)).trim();
}
}
/**
* A well known array of strings that is used to determine if double encoding is needed.
*/
RestAPIBaseService.ENCODING_SUBSTRINGS = ["/", "&", "\\", "+", "?", "%"];
RestAPIBaseService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
RestAPIBaseService.ctorParameters = () => [
{ type: HttpClient },
{ type: undefined, decorators: [{ type: Inject, args: [ND_TOKEN_CONTROLLER,] }] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class DocumentControllerService extends RestAPIBaseService {
/**
* @param {?} h
* @param {?} _token
*/
constructor(h, _token) {
super(h, _token);
this.h = h;
this.controllerUrl = "/document";
}
/**
* Fetches information of the specified document.
*
* Queryable items:
* [select] A comma separated list of strings that define what data should be returned in the request.
* See OptionalAttributes for a complete list of attribute flags that control what is returned.
* These strings can also define the custom attributes to be returned. This is done by specifying
* the custom attribute number (in string form). If any descriptions are required for the
* specified custom attributes, please add a leading \"1\" to the string form of the custom attribute number.
* p [id] the id of the document to fetch information on.
* @param {?} p
* @return {?}
*/
getInfo(p) {
// If the caller did not provide a document id then throw an error.
if (p.id == undefined)
return throwError("id is required.");
const /** @type {?} */ param = new CallParameters();
param.apiVersion = APIVersions.two;
param.method = HttpMethod.Get;
param.path = `${this.controllerUrl}/${p.id}/info`;
// If the caller provided queryArgs then..
if (p.queryArgs !== undefined) {
param.queryArgs = p.queryArgs;
}
return this.call(param);
}
/**
* Fetches information of the specified documents.
*
* Queryable items:
* [select] A comma separated list of strings that define what data should be returned in the request.
* See OptionalAttributes for a complete list of attribute flags that control what is returned.
* These strings can also define the custom attributes to be returned. This is done by specifying
* the custom attribute number (in string form). If any descriptions are required for the
* specified custom attributes, please add a leading \"1\" to the string form of the custom attribute number.
* p - List of documents to retrieve information for. Should be a comma separated list of envelope and/or document ids.
* @param {?} p
* @return {?}
*/
getListOfDocuments(p) {
// If the caller did not provide a document id then throw an error.
if (p.id == undefined)
return throwError("id is required.");
const /** @type {?} */ param = new CallParameters();
param.apiVersion = APIVersions.two;
param.method = HttpMethod.Post;
param.path = `${this.controllerUrl}\/list`;
param.body = `id=${p.id}&select=${p.queryArgs.select}`;
param.headers = this.BaseHeaders;
param.headers.append("Content-Type", "application/x-www-form-urlencoded");
return this.call(param);
}
/**
* Get list of recent documents
* @param {?} p
* @param {?} documentType
* @param {?=} lastModifiedDate
* @return {?}
*/
getRecent(p, documentType, lastModifiedDate = '') {
let /** @type {?} */ param = new CallParameters();
if (documentType === null || documentType === undefined) {
documentType = RecentDocumentType.All;
}
if (p.queryArgs !== undefined) {
param.queryArgs = p.queryArgs;
}
param.headers = !param.headers ? this.BaseHeaders : param.headers;
if (lastModifiedDate) {
param.headers.append("If-Modified-Since", lastModifiedDate);
}
else {
param.headers.append("Cache-Control", 'no-cache');
param.headers.append("Pragma", 'no-cache');
param.headers.append("Expires", 'Sat, 01 Jan 2000 00:00:00 GMT');
}
param.path = `${this.controllerUrl}/recent/${RecentDocumentType[documentType].toLowerCase()}`;
param.method = HttpMethod.Get;
param.apiVersion = APIVersions.two;
return this.call(param, false);
}
/**
* Get GrantAccessRequest appurl and error Text
* @param {?} p
* @return {?}
*/
getGrantAccessRequestInfo(p) {
let /** @type {?} */ param = new CallParameters();
if (p["Id"] == undefined)
throw "id is required.";
else {
param.path = this.controllerUrl + "/" + p["Id"] + "/grant_access_request_info";
}
param.method = HttpMethod.Get;
param.apiVersion = APIVersions.two;
return this.call(param);
}
/**
* Fetches information of the specified document's linked documents.
*
* Queryable items:
* [select] A comma separated list of strings that define what data should be returned in the request.
* See OptionalAttributes (SelectParameters) for a complete list of attribute flags that control what is returned.
* These strings can also define the custom attributes to be returned. This is done by specifying
* the custom attribute number (in string form). If any descriptions are required for the
* specified custom attributes, please add a leading \"1\" to the string form of the custom attribute number.
* p [id] the id of the document to fetch information on it's linked documents.
* @param {?} p
* @return {?}
*/
getLinkedDocuments(p) {
// If the caller did not provide a document id then throw an error.
if (p.id == undefined) {
return throwError("Document getLinkedDocuments id is required.");
}
const /** @type {?} */ param = new CallParameters();
param.apiVersion = APIVersions.two;
param.method = HttpMethod.Get;
param.path = `${this.controllerUrl}\/${p.id}\/linked`;
// If the caller provided queryArgs then..
if (p.queryArgs !== undefined) {
param.queryArgs = p.queryArgs;
}
return this.call(param);
}
/**
* Puts new version of document.
* Uses first rest api.
* p contains document id and IVersion as body
* @param {?} p
* @return {?}
*/
putNewVersion(p) {
// If the caller did not provide a document id then throw an error.
if (p.id == undefined) {
return Observable.throw("Document putNewVersion id is required.");
}
const /** @type {?} */ param = new CallParameters();
param.apiVersion = APIVersions.one;
param.method = HttpMethod.Put;
param.path = `${this.controllerUrl}\/${p.id}\/new`;
if (p.body != null) {
param.path += "?";
if (p.body.Name != undefined) {
param.path += `vername=${p.body.Name}&`;
}
if (p.body.Description != undefined) {
param.path += `version_description=${p.body.Description}&`;
}
if (p.body.Official) {
param.path += `official=Y`;
}
}
return this.call(param);
}
/**
* Check in a document
* p should include:
* { string } id Document id.
* p may include:
* { File } [file] Optional file object to check in.
* { string } [extension] New file extension.Only used in conjunction with file.
* { boolean } [notify] If true, email will be sent to user who checked out the document.
* @param {?} p
* @return {?}
*/
checkIn(p) {
// If the caller did not provide a document id then throw an error.
if (p.id == undefined) {
return Observable.throw("Document checkIn id is required.");
}
var /** @type {?} */ actionName = "checkin";
let /** @type {?} */ param = new CallParameters();
param.apiVersion = APIVersions.one;
param.method = HttpMethod.Post;
param.path = `${this.controllerUrl}`;
param.headers = this.BaseHeaders;
if (p["file"] != undefined) {
let /** @type {?} */ form = new FormData();
form.append("action", actionName);
form.append("id", p.id);
if (p["notify"] !== undefined) {
form.append("notify", p["notify"]);
}
if (p["extension"] !== undefined) {
form.append("extension", p["extension"]);
}
form.append("file", p["file"]);
param.body = form;
}
else {
param.headers.append("Content-Type", "application/x-www-form-urlencoded");
param.body = `id=${p.id}&action=${actionName}`;
if (p["notify"] !== undefined) {
param.body += `¬ify=${p["notify"]}`;
}
}
return this.call(param);
}
/**
* Upload new version contents
* {File} file File to upload
* {string} id Document id
* {string} [extension] New file extension
* {string} [verName] New version name
* @param {?} p
* @return {?}
*/
putNewVersionContents(p) {
// If the caller did not provide a document id then throw an error.
if (p.id == undefined) {
return Observable.throw("Document putFileContents id is required.");
}
if (p["file"] == undefined) {
return Observable.throw("Document putFileContents file is required.");
}
if (p["extension"] == undefined) {
return Observable.throw("Document putFileContents extension is required.");
}
let /** @type {?} */ param = new CallParameters();
param.apiVersion = APIVersions.one;
param.method = HttpMethod.Put;
param.path = `${this.controllerUrl}\/${p.id}\/new?`;
if (p["extension"] != undefined) {
param.path += `extension=${p["extension"]}`;
}
if (p["verName"] != undefined) {
param.path += `&vername=${p["verName"]}`;
}
param.headers = this.BaseHeaders;
let /** @type {?} */ form = new FormData();
form.append("file", p["file"]);
form.append("processData", "false");
form.append("contentType", p["file"].type);
param.body = form;
return this.call(param);
}
/**
* Retrieve document history
* id Document id.
* order Can take two values, either "none" (the default) or "chronological". If another value is used, simply apply "none".
* @param {?} p
* @return {?}
*/
getHistory(p) {
// If the caller did not provide a document id then throw an error.
if (p.id == undefined) {
return throwError("Document getLinkedDocuments id is required.");
}
const /** @type {?} */ param = new CallParameters();
param.apiVersion = APIVersions.one;
param.method = HttpMethod.Get;
param.path = `${this.controllerUrl}\/${p.id}\/history`;
// If the caller provided queryArgs then..
if (p.queryArgs !== undefined) {
param.queryArgs = p.queryArgs;
}
return this.call(param);
}
}
DocumentControllerService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
DocumentControllerService.ctorParameters = () => [
{ type: HttpClient },
{ type: undefined, decorators: [{ type: Inject, args: [ND_TOKEN_CONTROLLER,] }] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class ndApiModule {
/**
* @param {?} tokenControllerClass
* @return {?}
*/
static forRoot(tokenControllerClass) {
return {
ngModule: ndApiModule,
providers: [
{ provide: ND_TOKEN_CONTROLLER, useExisting: forwardRef(() => tokenControllerClass) },
DocumentControllerService
]
};
}
}
ndApiModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule,
HttpModule
]
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* Generated bundle index. Do not edit.
*/
export { ndApiModule, DocumentControllerService, ND_TOKEN_CONTROLLER, RestAPIBaseService as ɵa };
//# sourceMappingURL=nd-common-api.js.map