@transact-open-ux/core
Version:
Provides utility methods to integrate with the Transact Platform
889 lines (877 loc) • 36.5 kB
JavaScript
/**
* Copyright (c) 2019 Avoka Technologies Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { j2xParser, parse } from 'fast-xml-parser';
import pako from 'pako';
import axios from 'axios';
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
function __awaiter(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 ENCODE_MAP = {
'"': """,
"&": "&",
"'": "'",
"<": "<",
">": ">"
};
const DECODE_MAP = {
"&": "&",
"'": "'",
">": ">",
"<": "<",
""": '"'
};
/**
* Encodes special XML chars
* @param value
* @private
*/
const encode = (value) => {
if (value === null || value === undefined) {
return "";
}
return value.toString().replace(/([&"'<>])/g, (str, item) => {
return ENCODE_MAP[item];
});
};
/**
* Decodes special XML chars
* @param value
* @private
*/
const decode = (value) => {
if (value === null || value === undefined) {
return "";
}
return value.replace(/("|&|'|<|>)/g, (str, item) => {
return DECODE_MAP[item];
});
};
/**
* Serialize a JS object to an XML string
* @param object
* @param prettify
* @returns {*}
* @private
*/
const jsonToXml = (object, prettify = false) => {
const parser = new j2xParser({
format: prettify,
ignoreAttributes: true,
indentBy: " ",
supressEmptyNode: true,
tagValueProcessor: value => encode(value)
});
return parser.parse(object);
};
const xmlToJsonOptions = {
decodeHTMLchar: true,
tagValueProcessor: value => decode(value)
};
/**
* Parse an XML string to a JS object
* @param xmlData
*/
const xmlToJson = (xmlData) => {
const rootObj = parse(xmlData, xmlToJsonOptions);
return rootObj.hasOwnProperty("AvokaSmartForm")
? rootObj.AvokaSmartForm
: rootObj;
};
/**
* @private
* @param buf
* @returns {String|string|*}
*/
const bufferToBinaryString = buf => {
const binstr = Array.prototype.map
.call(buf, ch => String.fromCharCode(ch))
.join("");
return binstr;
};
/**
* @private
* @param binstr
* @returns {*}
*/
const binaryStringToBuffer = (binstr) => {
const buf = new Uint8Array(binstr.length);
Array.prototype.forEach.call(binstr, (ch, i) => {
buf[i] = ch.charCodeAt(0);
});
return buf;
};
/**
* functions below are from unibabel v2.1.3 (Nov 18, 2015)
* Base64, TypedArrays, and UTF-8 / Unicode conversions in Browser
* https://github.com/coolaj86/unibabel-js
* @private
*/
const utf8ToBinaryString = str => {
const escstr = encodeURIComponent(str);
// replaces any uri escape sequence, such as %0A,
// with binary escape, such as 0x0A
const binstr = escstr.replace(/%([0-9A-F]{2})/g, (match, p1) => String.fromCharCode(parseInt(p1, 16)));
return binstr;
};
/**
* @private
* @param str
*/
const utf8ToBuffer = str => {
const binstr = utf8ToBinaryString(str);
const buf = binaryStringToBuffer(binstr);
return buf;
};
/**
* @private
* @param binstr
* @returns {string}
*/
const binaryStringToUtf8 = binstr => {
const escstr = binstr.replace(/(.)/g, (m, p) => {
let code = p
.charCodeAt(0)
.toString(16)
.toUpperCase();
if (code.length < 2) {
code = `0${code}`;
}
return `%${code}`;
});
return decodeURIComponent(escstr);
};
/**
* @private
* @param buf
* @returns {string}
*/
const bufferToUtf8 = buf => {
const binstr = bufferToBinaryString(buf);
return binaryStringToUtf8(binstr);
};
/**
* @private
* @param arr
* @returns {*}
*/
const bufferToBase64 = arr => {
const binstr = bufferToBinaryString(arr);
return btoa(binstr);
};
/**
* @private
* @param base64
* @returns {*}
*/
const base64ToBuffer = base64 => {
const binstr = atob(base64);
const buf = binaryStringToBuffer(binstr);
return buf;
};
// Can we get/set cookies on document.cookie?
/**
* @private
*/
const hasDocumentCookie = () => typeof document === "object" && typeof document.cookie === "string";
/**
* @private
*/
const HAS_DOCUMENT_COOKIE = hasDocumentCookie();
/**
* @private
* @param key
*/
const getCookie = key => {
if (!HAS_DOCUMENT_COOKIE) {
return null;
}
return (decodeURIComponent(document.cookie.replace(new RegExp(`(?:(?:^|.*;)\\s*${encodeURIComponent(key).replace(/[-.+*]/g, "\\$&")}\\s*\\=\\s*([^;]*).*$)|^.*$`), "$1")) || undefined);
};
/**
* Gets the value from a data object via the part parameter.
*
* #### Example
*
* ```js
* import { getDataFromPath } from "transact-open-ux/core";
*
* const formState = {
* Applicant: {
* FirstName: "David"
* }
* };
*
* // FirstName === "David
* const FirstName = getDataFromPath("Applicant.FirstName", formState);
* ```
* @param path The path to get the data from
* @param data The object to lookup the path
* @returns Returns the value found at the path location within the data object.
*/
const getDataFromPath = (path = "", data) => {
const parts = path && path.split(".");
let value = data;
let part;
while (parts && parts.length) {
part = parts.shift();
value = value[part];
if (typeof value === "undefined") {
return value;
}
}
return value;
};
/**
* Sets the data path to the value.
* #### Example
*
* ```js
* import { setDataFromPath } from "transact-open-ux/core";
*
* const formState = {
* Applicant: {
* FirstName: "David"
* }
* };
*
* // formState.Applicant.FirstName === "Joe"
* ```
* setDataFromPath("Applicant.FirstName", formState, "Joe");
* @param path The path to set the data
* @param data The object to find and set the data path in
* @param value The value to set the data to
* @returns The modified object.
*/
const setDataFromPath = (path = "", data, value) => {
const parts = path.split(".");
let node = data;
let part = parts.shift();
while (part) {
if (typeof node === "undefined") {
return data;
}
if (parts.length === 0) {
node[part] = value;
}
else {
if (!Object.prototype.hasOwnProperty.call(node, part)) {
node[part] = {};
}
node = node[part];
}
part = parts.shift();
}
return data;
};
/**
* Redirects the app to another target url
* @param redirectTarget The url to redirect to.
*/
const redirect = (redirectTarget) => {
if (typeof redirectTarget === "string") {
window.onbeforeunload = null;
window.location.replace(redirectTarget);
}
};
/**
* Returns an object of the current URL parameters. The keys are the parameter names
* @returns An object of the current URL parameters. The keys are the parameter names.
*/
const getUrlQueryParams = () => {
const a = {};
if (window && window.location) {
window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, (b, c, d) => {
a[c] = d;
return d;
});
}
return a;
};
/**
* Returns the value of the URL parameter. Or null if it does not exist.
* @param key The URL Parameter name.
* @returns The value of the URL parameter. Or null if it does not exist.
*/
const getUrlQueryParam = (key) => getUrlQueryParams()[key] || null;
/**
* returns a json string from an object, stripping out any keys that start with a dollar sign
* @param object The object to transform to a JSON string
* @param prettify A boolean value indicating whether to prettify the output
* @returns A JSON string representation of an object, stripping out any keys that start with a dollar sign.
*/
const jsonify = (object, prettify) => JSON.stringify(object,
// @ts-ignore
(key, val) => {
if (key.match(/^\$/)) {
return undefined;
} // strip dollar keys out
return val;
}, prettify ? "\t" : false);
/**
* @private
* Removes null and undefined properties from the object
* @param object
*/
const cleanObjProps = (object = {}) => {
Object.keys(object).forEach(key => {
if (object[key] === undefined || object[key] === null) {
delete object[key];
}
});
};
const isWebCrypto = window.crypto && (window.crypto.subtle || window.crypto.webkitSubtle);
// for IE11 specific web crypto support
const isMsCrypto = window.msCrypto && window.msCrypto.subtle;
const cryptoSubtle = isWebCrypto || isMsCrypto;
const failMsg = "Browser does not support data encryption!";
/**
* Takes in the crypto object and handles the success and fail handlers dependant on browser type
* @private
* @param obj
* @param handler1
* @param handler2
*/
const addHandler = (obj, handler1, handler2) => {
const handlerObj = obj;
if (isMsCrypto) {
handlerObj.onerror = handler2;
handlerObj.oncomplete = e => {
const data = e.target.result;
handler1(data);
};
}
else if (isWebCrypto) {
handlerObj
.then(data => {
handler1(data);
})
.catch(handler2);
}
};
/**
* TM Form Data Encryption
* Please note the data encryption/decryption only works in:
* - Modern browsers (Chrome v44+, Firefox, Edge v20+)
* - IE 11
* TM will make sure data is not encrypted in other browsers, hence these methods
* will not be called in this case
* You should also avoid calling the following three methods explicitly if browser is
* not listed above
* @param data
* @param requestKey
* @returns {promise}
* @private
*/
const tmEncryptData = (data, requestKey) => {
if (!requestKey) {
return Promise.reject(new Error("requestKey not found."));
}
if (!cryptoSubtle) {
return data; // ignore and send back data is encryption doesn't exist. Security handled in back-end
}
return new Promise((resolve, reject) => {
try {
// create AES key
const genOp = cryptoSubtle.generateKey({
length: 128,
name: "AES-CBC"
}, true, // whether the key is extractable (i.e. can be used in exportKey)
["encrypt", "decrypt"] // must be ["encrypt", "decrypt"] or ["wrapKey", "unwrapKey"]
);
addHandler(genOp, key => {
// export key
const exportOp = cryptoSubtle.exportKey("raw", // can be "jwk" or "raw"
key // extractable must be true
);
addHandler(exportOp, keyData => {
// compress and encrypt original data
const dataBytes = utf8ToBuffer(data);
const compressedData = pako.deflate(dataBytes);
const iv = utf8ToBuffer(requestKey.substring(16));
const encryptOp = cryptoSubtle.encrypt(
// encrypt data
{
iv,
name: "AES-CBC"
}, key, // from generated key above
compressedData);
addHandler(encryptOp, encryptedAESData => {
// generate TM specific encrypted Data
const requestKeyBuffer = utf8ToBuffer(requestKey);
// Request Key (32 bytes) + AES key (16 bytes) + encrypted Data
const combinedData = new Uint8Array(
// @ts-ignore
requestKeyBuffer.byteLength +
keyData.byteLength +
encryptedAESData.byteLength);
combinedData.set(new Uint8Array(requestKeyBuffer), 0);
combinedData.set(new Uint8Array(keyData), requestKeyBuffer.byteLength);
combinedData.set(new Uint8Array(encryptedAESData), requestKeyBuffer.byteLength + keyData.byteLength);
const tmEncryptedData = bufferToBase64(combinedData);
resolve(tmEncryptedData);
}, reject);
}, reject);
}, reject);
}
catch (err) {
reject(err);
}
});
};
/**
* TM Form Data Decryption
* @param encryptedDataBase64
* @returns {promise}
* @private
*/
const tmDecryptData = encryptedDataBase64 => {
if (!cryptoSubtle) {
throw new Error(failMsg);
}
return new Promise((resolve, reject) => {
try {
const encryptedData = base64ToBuffer(encryptedDataBase64);
const iv = encryptedData.subarray(16, 32);
const aesKey = encryptedData.subarray(32, 48);
const data = encryptedData.subarray(48);
const importOp = cryptoSubtle.importKey("raw", aesKey, "AES-CBC", false, [
"decrypt"
]);
addHandler(importOp, key => {
// decrypt data
const decryptOp = cryptoSubtle.decrypt({
iv,
name: "AES-CBC"
}, key, data);
addHandler(decryptOp, decrypted => {
// uncompress data
const decBuffer = new Uint8Array(decrypted);
const uncompressedData = pako.inflate(decBuffer);
const originalData = bufferToUtf8(uncompressedData);
resolve(originalData);
}, reject);
}, reject);
}
catch (err) {
reject(err);
}
});
};
function sendMultipart(method, url, data) {
return __awaiter(this, void 0, void 0, function* () {
const formData = new FormData();
const dataObj = typeof data === "string" ? JSON.parse(data) : data;
Object.keys(dataObj).forEach(key => {
formData.append(key, dataObj[key]);
});
try {
const response = yield axios({
data: formData,
method,
url
});
return response.data;
}
catch (e) {
const errorData = e.response.data;
return Promise.reject(errorData);
}
});
}
// @private
const isDev = process.env.NODE_ENV === "development";
// @private
const config = window.openUxConfig || {};
// @private
let { endpoint = "http://localhost:9999/app", // location of mock server
requestKey = getCookie("requestKey") } = config;
/**
* A boolean variable that indicates whether the app is being opened in receipt mode
* @returns boolean true or false depending on whether the app is being opened in receipt mode.
*/
const isReceipt = !!config.isReceipt;
let shouldEncryptCmd = !isDev;
let shouldEncryptData;
/**
* Returns a string that contains an XML representation of the data
* @param data The application data object to serialize to XML.
* @param prettify A boolean value indicating whether to prettify the output.
* @returns A string that contains an XML representation of the data.
*/
const getDataXml = (data, prettify) => jsonToXml({ AvokaSmartForm: JSON.parse(jsonify(data)) }, prettify);
/**
* @private
* @param data
*/
function transformFormData(data) {
return __awaiter(this, void 0, void 0, function* () {
const doDecrypt = typeof data === "string" &&
data.indexOf("<") === -1 &&
data.indexOf("%") === -1;
const decryptedData = doDecrypt ? yield tmDecryptData(data) : data;
// turn off command encryption if encryption not required
if (shouldEncryptCmd && !doDecrypt) {
shouldEncryptCmd = false;
}
if (typeof shouldEncryptData !== "boolean" && doDecrypt) {
shouldEncryptData = true;
}
return xmlToJson(decryptedData.trim());
});
}
/**
* Returns true if Save Challenge is required.
* User should perform a formLoad with options to resume the form.
* @returns A boolean true if Save Challenge is required, otherwise false.
*/
const isSaveChallengeRequired = () => !!getUrlQueryParam("trackingCode");
/**
* @private
* @param type
* @param options
* @param parameters
* @param fileData
* @param currentFormData
*/
function transactCall(type, options, parameters, fileData, currentFormData) {
return __awaiter(this, void 0, void 0, function* () {
// remove null or undefined properties from options and params
if (options) {
cleanObjProps(options);
}
if (parameters) {
cleanObjProps(parameters);
}
const command = {
options,
parameters,
requestKey,
type
};
const cmdJson = JSON.stringify(command);
const dataObj = {};
if (fileData) {
dataObj.fileAttachment = fileData;
}
try {
// Set formData if required
if (typeof currentFormData === "object") {
dataObj.formData = shouldEncryptData
? yield tmEncryptData(getDataXml(currentFormData), requestKey)
: getDataXml(currentFormData);
}
// Set command
dataObj.command = shouldEncryptCmd
? yield tmEncryptData(cmdJson, requestKey)
: cmdJson;
const response = yield sendMultipart("post", endpoint, dataObj);
const { formData, revisionNumber, redirectUrl } = response;
if (formData) {
response.formData = yield transformFormData(formData);
}
if (redirectUrl) {
redirect(redirectUrl);
}
if (typeof revisionNumber !== "undefined") {
setDataFromPath("SFMData.SystemProfile.RevisionNumber", response.formData || currentFormData, revisionNumber);
}
return response;
}
catch (e) {
return Promise.reject(e);
}
});
}
/**
* Make a call that performs a user initiated save operation.
* It is recommended that the app displays a save confirmation page after this operation.
* @param {object} formData An object tree of the form data, e.g. passed in via a Redux selector
* @param {boolean} sendEmailSavedForm Specify whether to send an "Form Saved" email message to the specified user emailAddress parameter
* @param {boolean} sendEmailShareForm Specify whether to send a "Form Shared" email message to the user specified by the emailAddress parameter
* @param {string} emailAddress The email address of the user to send the
* @param {string} milestone A transaction milestone event to record with the transaction, maximum length should be 100 characters (optional)
* @returns A Promise containing the response object. <br>
* For more information visit the <a target="_blank" href="https://docs.avoka.com/sdk/">SDK documentation.</a>
*/
const userSave = (formData, sendEmailSavedForm, sendEmailShareForm, emailAddress, milestone) => transactCall("userSave", {
emailAddress,
milestone,
sendEmailSavedForm,
sendEmailShareForm
}, undefined, undefined, formData);
/**
* Make a call that performs a user initiated submit operation.
* The app should display a submission confirmation page after this operation.
* @param {object} formData An object tree of the form data, e.g. passed in via a Redux selector
* @param {boolean} sendEmailFormReceipt Specify whether to send an "Form Receipt" email message to the specified user emailAddress parameter
* @param {string} emailAddress The email address of the user to send the
* @param {string} milestone A transaction milestone event to record with the transaction, maximum length should be 100 characters (optional)
* @returns A Promise containing the response object. <br>
* For more information visit the <a target="_blank" href="https://docs.avoka.com/sdk/">SDK documentation.</a>
*/
const userSubmit = (formData, sendEmailFormReceipt, emailAddress, milestone) => transactCall("userSubmit", {
emailAddress,
milestone,
sendEmailFormReceipt
}, undefined, undefined, formData);
/**
* Make a call that performs a user initiated cancel abandonment operation.
* The app should display a cancel confirmation page after this operation.
* @param {object} formData An object tree of the form data, e.g. passed in via a Redux selector
* @param {string} milestone A transaction milestone event to record with the transaction, maximum length should be 100 characters (optional)
* @returns A Promise containing the response object. <br>
* For more information visit the <a target="_blank" href="https://docs.avoka.com/sdk/">SDK documentation.</a>
*/
const userCancel = (formData, milestone) => transactCall("userCancel", {
milestone
}, undefined, undefined, formData);
/**
* Call the formInit command.
*
* This command type specifies that the form application is fully initialized and ready for user interaction.
* The role of this command to provide analytics around the performance of forms and understand how long they take to open,
* and what the impact is on conversion rate and form starts.
*
* This information will be recorded in the TM Request Log table as a millisecond value between the TM HTML document
* data streamed completed time and the time the formInit event was received
* @returns A Promise containing the response object. <br>
* For more information visit the <a target="_blank" href="https://docs.avoka.com/sdk/">SDK documentation.</a>
*/
const formInit = () => transactCall("formInit");
/**
* Make a call to the form load operation to load the application prefill data at load time.
* You can also load a saved application via a combination of parameters, see examples below.
* After the data has been retrieved a form initiated operation will be called.
* @param saveChallengeAnswer {string} specify the save challenge answer
* @param trackingCode {string} specify the tracking code or reference number. This value should be used when presenting a user with a dialog to open another previously saved form.
* @param parameters {object} specify custom parameters, For example a mobile SMS PIN token
* @returns A Promise containing the response object. <br>
* For more information visit the <a target="_blank" href="https://docs.avoka.com/sdk/">SDK documentation.</a> <br>
* *Note: the formData property will be an object instead of XML when returned via the core library.*
*/
function formLoad(saveChallengeAnswer, trackingCode, parameters) {
return __awaiter(this, void 0, void 0, function* () {
try {
const response = yield transactCall("formLoad", {
saveChallengeAnswer,
trackingCode
}, parameters);
const { error, validationErrors } = response;
if (!validationErrors && !error) {
// PhantomJS Support
if (typeof window.callPhantom === "function") {
setTimeout(() => {
window.callPhantom({ completed: true });
}, 4000);
}
if (!isReceipt) {
formInit().catch(err => err);
} // perform formInit
// remove trackingCode from URL
if (trackingCode &&
isSaveChallengeRequired() &&
typeof window.history.replaceState === "function") {
const newUrl = window.location.href.split("?trackingCode")[0];
window.history.replaceState("", "", newUrl);
}
}
return response;
}
catch (e) {
return e;
}
});
}
/**
* The formNew command creates a new form transaction or opens an existing transaction.
* This call should be followed by the formLoad command.
* <br>
* This command is provided to support the use case where Transact is not rendering the HTML Open UX application,
* but instead it is being rendered separately by another system such as a Content Management System (CSM) or another application.
*
* @param requestUrl {string} specify the endpoint which will be used for this call and all subsequent Open UX calls
* @param formCode {string} specify the globally unique application form code to create a new transaction for
* @param formVersion {string} specify the application form version number to use, if not specified then the current form version will be used for the transaction
* @param trackingCode {string} specify the tracking code or reference number. This value should be used when opening an previously saved form application.
* @returns A Promise containing the response object. <br>
* For more information visit the <a target="_blank" href="https://docs.avoka.com/sdk/">SDK documentation.</a>
*/
function formNew(requestUrl, formCode, formVersion, trackingCode) {
return __awaiter(this, void 0, void 0, function* () {
if (!requestUrl) {
throw new Error("The requestUrl is required, i.e. https://apps.mybank.com/web-plugin/app/");
}
if (!formCode && !trackingCode) {
throw new Error("You must supply a formCode OR a trackingCode");
}
try {
// set endpoint
endpoint = requestUrl;
// reset requestKey if it already exists
if (requestKey) {
requestKey = undefined;
}
const response = yield transactCall("formNew", {
formCode,
formVersion,
trackingCode
}, undefined, undefined, undefined);
// set requestKey
requestKey = response.requestKey;
return response;
}
catch (e) {
return Promise.reject(e);
}
});
}
/**
* Make a call to the form start operation specifying that the user has started interacting with the form.
* @param {object} formData An object tree of the form data, e.g. passed in via a Redux selector
* @param {string} milestone A transaction milestone event to record with the transaction, maximum length should be 100 characters (optional)
* @returns A Promise containing the response object. <br>
* For more information visit the <a target="_blank" href="https://docs.avoka.com/sdk/">SDK documentation.</a>
*/
const formStart = (formData, milestone) => transactCall("formStart", {
milestone
}, undefined, undefined, formData);
/**
* This command type enables recording information about an unexpected JavaScript error in the application and
* storing this information in the TM Error Log for operational support
* @param {string} stacktrace the JavaScript stacktrace, with \n character new line delimiters
* @param {string} context application state / context information to help understand the context of the error.
* @returns A Promise containing the response object. <br>
* For more information visit the <a target="_blank" href="https://docs.avoka.com/sdk/">SDK documentation.</a>
*/
const formError = (stacktrace, context) => transactCall("formError", {
context,
stacktrace
}, undefined, undefined);
/**
* Make a call to the form update operation, this performs an app initiated background save.
* Reasons to call this command include: page change save, timer based save, milestone based save, add attachment,
* specify attachment to be added manually and remove attachment.
*
* The parameters addAttachmentManually, removeAttachment and addAttachmentFile can be specified with appropriate metadata
* using the associated helper methods, detailed separately in the parameter descriptions below. It is expected that only one
* of these parameters (or none of them) would be provided for any one call,
* the others can be either left off (if they appear after any other necessary parameters) or provided with a null or undefined value.
* @param {object} formData An object tree of the form data, e.g. passed in via a Redux selector
* @param {boolean} userSaved Specify whether to set submission.user_saved_flag so that submission automatic abandonment will not occur
* @param {boolean} sendEmailSavedForm Specify whether to send an "Form Saved" email message to the specified user emailAddress parameter
* @param {string} emailAddress The email address of the user to send the
* @param {string} milestone A transaction milestone event to record with the transaction, maximum length should be 100 characters (optional)
* @param {object} addAttachmentManually The add submit manually file attachment - use the method makeAddAttachmentManually to obtain this
* @param {object} removeAttachment The remove file attachment metadata - use the method makeRemoveAttachment to obtain this
* @param {object} addAttachmentFile The add file attachment metadata - use the method makeAddAttachmentFile to obtain this
* @param fileContent The DOM File object with content as per: https://developer.mozilla.org/en-US/docs/Web/API/File
* @returns A Promise containing the response object. <br>
* For more information visit the <a target="_blank" href="https://docs.avoka.com/sdk/">SDK documentation.</a> <br>
* *Note: the formData property will be an object instead of XML when returned via the core library.*
*/
const formUpdate = (formData, userSaved, sendEmailSavedForm, emailAddress, milestone, addAttachmentManually, removeAttachment, addAttachmentFile, fileContent) => transactCall("formUpdate", {
addAttachmentFile,
addAttachmentManually,
emailAddress,
milestone,
removeAttachment,
sendEmailSavedForm,
userSaved
}, undefined, fileContent, formData);
/**
* Make a call to execute a named Fluent Function service hosted on Transact Manager.
* @param {string} serviceName The form action service definition name (required)
* @param {string} serviceVersion The form action service definition version number (required)
* @param {string} milestone A transaction milestone event to record with the transaction, maximum length should be 100 characters (optional)
* @param {object} params The parameters to the specified form function. This takes the form of an object, where each key is a parameter name. The object value for that key is delivered as the value for that parameter.
* @returns A Promise containing the response object. <br>
* For more information visit the <a target="_blank" href="https://docs.avoka.com/sdk/">SDK documentation.</a>
*/
const formFunction = (serviceName, serviceVersion, milestone, params) => transactCall("formFunction", {
milestone,
serviceName,
serviceVersion
}, params);
/**
* Make a call to the form ineligible operation.
* The app should display a custom page after this operation preventing the user from performing further work.
* @param {object} formData An object tree of the form data, e.g. passed in via a Redux selector
* @param {string} milestone A transaction milestone event to record with the transaction, maximum length should be 100 characters (optional)
* @returns A Promise containing the response object. <br>
* For more information visit the <a target="_blank" href="https://docs.avoka.com/sdk/">SDK documentation.</a>
*/
const formIneligible = (formData, milestone) => transactCall("formIneligible", {
milestone
}, undefined, undefined, formData);
/**
* Return an object suitable for passing to the addAttachmentManually parameter of the formUpdate method.
* @param {string} path Should specify the XPath to the Attachment Field.
* The path value would be used when returning validation errors to the client if the addAttachmentFile operation fail
* @param {string} attachmentKey provides a GUID of the file attachment, this value will be used to store the new file attachment in TM
* @param {string} attachmentName The name attribute for the meta data
* @returns An object suitable for passing to the addAttachmentManually parameter of the formUpdate method.
*/
const makeAddAttachmentManually = (path, attachmentKey, attachmentName) => ({
attachmentKey,
attachmentName,
path
});
/**
* Return an object suitable for passing to the addAttachmentFile parameter of the formUpdate method.
* @param {string} path Should specify the XPath to the Attachment Field.
* The path value would be used when returning validation errors to the client if the addAttachmentFile operation fail
* @param {string} attachmentKey provides a GUID of the file attachment, this value will be used to store the new file attachment in TM
* @param {string} attachmentName The name attribute for the meta data
* @param {string} description The description attribute for the meta data
* @param {number} maxSize Specifies the max file size allowed for the attachment, this is a server side check.
* @param {string} fileTypes Specifies the file types allowed
* @returns an object suitable for passing to the addAttachmentFile parameter of the formUpdate method.
*/
const makeAddAttachmentFile = (path, attachmentKey, attachmentName, description, maxSize, fileTypes) => ({
attachmentKey,
attachmentName,
description,
fileTypes,
maxSize,
path
});
/**
* Return an object suitable for passing to the removeAttachment parameter of the formUpdate method.
* @param {string} attachmentKey The attachmentKey string
* @returns an object suitable for passing to the removeAttachment parameter of the formUpdate method.
*/
const makeRemoveAttachment = (attachmentKey) => ({
attachmentKey
});
export { formError, formFunction, formIneligible, formInit, formLoad, formNew, formStart, formUpdate, getDataFromPath, getDataXml, getUrlQueryParam, getUrlQueryParams, isReceipt, isSaveChallengeRequired, jsonify, makeAddAttachmentFile, makeAddAttachmentManually, makeRemoveAttachment, redirect, setDataFromPath, userCancel, userSave, userSubmit };
//# sourceMappingURL=open-ux-core.es.js.map