formiojs
Version:
Common js library for client side interaction with <form.io>
1,516 lines (1,276 loc) • 46.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
require("core-js/modules/es6.function.name");
require("core-js/modules/es7.symbol.async-iterator");
require("core-js/modules/es6.symbol");
require("core-js/modules/es6.number.constructor");
require("core-js/modules/web.dom.iterable");
require("core-js/modules/es6.array.iterator");
require("core-js/modules/es6.string.iterator");
require("core-js/modules/es6.object.assign");
require("core-js/modules/es7.array.includes");
require("core-js/modules/es6.string.includes");
require("core-js/modules/es6.regexp.replace");
require("core-js/modules/es6.regexp.constructor");
require("core-js/modules/es6.regexp.split");
require("core-js/modules/es6.regexp.search");
require("core-js/modules/es6.regexp.match");
var _nativePromiseOnly = _interopRequireDefault(require("native-promise-only"));
require("whatwg-fetch");
var _eventemitter = require("eventemitter2");
var _browserCookies = _interopRequireDefault(require("browser-cookies"));
var _shallowCopy = _interopRequireDefault(require("shallow-copy"));
var providers = _interopRequireWildcard(require("./providers"));
var _get2 = _interopRequireDefault(require("lodash/get"));
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
var isBoolean = function isBoolean(val) {
return _typeof(val) === _typeof(true);
};
var isNil = function isNil(val) {
return val === null || val === undefined;
};
var isObject = function isObject(val) {
return val && _typeof(val) === 'object';
};
/**
* The Formio interface class.
*
* let formio = new Formio('https://examples.form.io/example');
*/
var Formio =
/*#__PURE__*/
function () {
/* eslint-disable max-statements */
function Formio(path) {
var _this = this;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, Formio);
// Ensure we have an instance of Formio.
if (!(this instanceof Formio)) {
return new Formio(path);
} // Initialize our variables.
this.base = '';
this.projectsUrl = '';
this.projectUrl = '';
this.projectId = '';
this.formUrl = '';
this.formsUrl = '';
this.formId = '';
this.submissionsUrl = '';
this.submissionUrl = '';
this.submissionId = '';
this.actionsUrl = '';
this.actionId = '';
this.actionUrl = '';
this.vsUrl = '';
this.vId = '';
this.vUrl = '';
this.query = ''; // Store the original path and options.
this.path = path;
this.options = options;
if (options.hasOwnProperty('base')) {
this.base = options.base;
} else if (Formio.baseUrl) {
this.base = Formio.baseUrl;
} else {
this.base = window.location.href.match(/http[s]?:\/\/api./)[0];
}
if (!path) {
// Allow user to create new projects if this was instantiated without
// a url
this.projectUrl = "".concat(this.base, "/project");
this.projectsUrl = "".concat(this.base, "/project");
this.projectId = false;
this.query = '';
return;
}
if (options.hasOwnProperty('project')) {
this.projectUrl = options.project;
}
var project = this.projectUrl || Formio.projectUrl;
var projectRegEx = /(^|\/)(project)($|\/[^/]+)/;
var isProjectUrl = path.search(projectRegEx) !== -1; // The baseURL is the same as the projectUrl, and does not contain "/project/MONGO_ID" in
// its domain. This is almost certainly against the Open Source server.
if (project && this.base === project && !isProjectUrl) {
this.noProject = true;
this.projectUrl = this.base;
} // Normalize to an absolute path.
if (path.indexOf('http') !== 0 && path.indexOf('//') !== 0) {
path = this.base + path;
}
var hostparts = this.getUrlParts(path);
var parts = [];
var hostName = hostparts[1] + hostparts[2];
path = hostparts.length > 3 ? hostparts[3] : '';
var queryparts = path.split('?');
if (queryparts.length > 1) {
path = queryparts[0];
this.query = "?".concat(queryparts[1]);
} // Register a specific path.
var registerPath = function registerPath(name, base) {
_this["".concat(name, "sUrl")] = "".concat(base, "/").concat(name);
var regex = new RegExp("/".concat(name, "/([^/]+)"));
if (path.search(regex) !== -1) {
parts = path.match(regex);
_this["".concat(name, "Url")] = parts ? base + parts[0] : '';
_this["".concat(name, "Id")] = parts.length > 1 ? parts[1] : '';
base += parts[0];
}
return base;
}; // Register an array of items.
var registerItems = function registerItems(items, base, staticBase) {
for (var i in items) {
if (items.hasOwnProperty(i)) {
var item = items[i];
if (Array.isArray(item)) {
registerItems(item, base, true);
} else {
var newBase = registerPath(item, base);
base = staticBase ? base : newBase;
}
}
}
};
if (!this.projectUrl || this.projectUrl === this.base) {
this.projectUrl = hostName;
}
if (!this.noProject) {
// Determine the projectUrl and projectId
if (isProjectUrl) {
// Get project id as project/:projectId.
registerItems(['project'], hostName);
path = path.replace(projectRegEx, '');
} else if (hostName === this.base) {
// Get project id as first part of path (subdirectory).
if (hostparts.length > 3 && path.split('/').length > 1) {
var pathParts = path.split('/');
pathParts.shift(); // Throw away the first /.
this.projectId = pathParts.shift();
path = "/".concat(pathParts.join('/'));
this.projectUrl = "".concat(hostName, "/").concat(this.projectId);
}
} else {
// Get project id from subdomain.
if (hostparts.length > 2 && (hostparts[2].split('.').length > 2 || hostName.includes('localhost'))) {
this.projectUrl = hostName;
this.projectId = hostparts[2].split('.')[0];
}
}
this.projectsUrl = this.projectsUrl || "".concat(this.base, "/project");
} // Configure Form urls and form ids.
if (path.search(/(^|\/)(form)($|\/)/) !== -1) {
registerItems(['form', ['submission', 'action', 'v']], this.projectUrl);
} else {
var subRegEx = new RegExp('/(submission|action|v)($|/.*)');
var subs = path.match(subRegEx);
this.pathType = subs && subs.length > 1 ? subs[1] : '';
path = path.replace(subRegEx, '');
path = path.replace(/\/$/, '');
this.formsUrl = "".concat(this.projectUrl, "/form");
this.formUrl = path ? this.projectUrl + path : '';
this.formId = path.replace(/^\/+|\/+$/g, '');
var items = ['submission', 'action', 'v'];
for (var i in items) {
if (items.hasOwnProperty(i)) {
var item = items[i];
this["".concat(item, "sUrl")] = "".concat(this.projectUrl + path, "/").concat(item);
if (this.pathType === item && subs.length > 2 && subs[2]) {
this["".concat(item, "Id")] = subs[2].replace(/^\/+|\/+$/g, '');
this["".concat(item, "Url")] = this.projectUrl + path + subs[0];
}
}
}
} // Set the app url if it is not set.
if (!Formio.projectUrlSet) {
Formio.projectUrl = this.projectUrl;
}
}
/* eslint-enable max-statements */
_createClass(Formio, [{
key: "delete",
value: function _delete(type, opts) {
var _id = "".concat(type, "Id");
var _url = "".concat(type, "Url");
if (!this[_id]) {
_nativePromiseOnly.default.reject('Nothing to delete');
}
Formio.cache = {};
return this.makeRequest(type, this[_url], 'delete', null, opts);
}
}, {
key: "index",
value: function index(type, query, opts) {
var _url = "".concat(type, "Url");
query = query || '';
if (query && isObject(query)) {
query = "?".concat(Formio.serialize(query.params));
}
return this.makeRequest(type, this[_url] + query, 'get', null, opts);
}
}, {
key: "save",
value: function save(type, data, opts) {
var _id = "".concat(type, "Id");
var _url = "".concat(type, "Url");
var method = this[_id] || data._id ? 'put' : 'post';
var reqUrl = this[_id] ? this[_url] : this["".concat(type, "sUrl")];
if (!this[_id] && data._id && method === 'put' && !reqUrl.includes(data._id)) {
reqUrl += "/".concat(data._id);
}
Formio.cache = {};
return this.makeRequest(type, reqUrl + this.query, method, data, opts);
}
}, {
key: "load",
value: function load(type, query, opts) {
var _id = "".concat(type, "Id");
var _url = "".concat(type, "Url");
if (query && isObject(query)) {
query = Formio.serialize(query.params);
}
if (query) {
query = this.query ? "".concat(this.query, "&").concat(query) : "?".concat(query);
} else {
query = this.query;
}
if (!this[_id]) {
return _nativePromiseOnly.default.reject("Missing ".concat(_id));
}
return this.makeRequest(type, this[_url] + query, 'get', null, opts);
}
}, {
key: "makeRequest",
value: function makeRequest() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return Formio.makeRequest.apply(Formio, [this].concat(args));
}
}, {
key: "loadProject",
value: function loadProject(query, opts) {
return this.load('project', query, opts);
}
}, {
key: "saveProject",
value: function saveProject(data, opts) {
return this.save('project', data, opts);
}
}, {
key: "deleteProject",
value: function deleteProject(opts) {
return this.delete('project', opts);
}
}, {
key: "loadForm",
value: function loadForm(query, opts) {
var _this2 = this;
return this.load('form', query, opts).then(function (currentForm) {
// Check to see if there isn't a number in vId.
if (!currentForm.revisions || isNaN(parseInt(_this2.vId))) {
return currentForm;
} // If a submission already exists but form is marked to load current version of form.
if (currentForm.revisions === 'current' && _this2.submissionId) {
return currentForm;
} // If they specified a revision form, load the revised form components.
if (query && isObject(query)) {
query = Formio.serialize(query.params);
}
if (query) {
query = _this2.query ? "".concat(_this2.query, "&").concat(query) : "?".concat(query);
} else {
query = _this2.query;
}
return _this2.makeRequest('form', _this2.vUrl + query, 'get', null, opts).then(function (revisionForm) {
currentForm.components = revisionForm.components; // Using object.assign so we don't cross polinate multiple form loads.
return Object.assign({}, currentForm);
}) // If we couldn't load the revision, just return the original form.
.catch(function () {
return Object.assign({}, currentForm);
});
});
}
}, {
key: "saveForm",
value: function saveForm(data, opts) {
return this.save('form', data, opts);
}
}, {
key: "deleteForm",
value: function deleteForm(opts) {
return this.delete('form', opts);
}
}, {
key: "loadForms",
value: function loadForms(query, opts) {
return this.index('forms', query, opts);
}
}, {
key: "loadSubmission",
value: function loadSubmission(query, opts) {
var _this3 = this;
return this.load('submission', query, opts).then(function (submission) {
_this3.vId = submission._fvid;
_this3.vUrl = "".concat(_this3.formUrl, "/v/").concat(_this3.vId);
return submission;
});
}
}, {
key: "saveSubmission",
value: function saveSubmission(data, opts) {
if (!isNaN(parseInt(this.vId))) {
data._fvid = this.vId;
}
return this.save('submission', data, opts);
}
}, {
key: "deleteSubmission",
value: function deleteSubmission(opts) {
return this.delete('submission', opts);
}
}, {
key: "loadSubmissions",
value: function loadSubmissions(query, opts) {
return this.index('submissions', query, opts);
}
}, {
key: "loadAction",
value: function loadAction(query, opts) {
return this.load('action', query, opts);
}
}, {
key: "saveAction",
value: function saveAction(data, opts) {
return this.save('action', data, opts);
}
}, {
key: "deleteAction",
value: function deleteAction(opts) {
return this.delete('action', opts);
}
}, {
key: "loadActions",
value: function loadActions(query, opts) {
return this.index('actions', query, opts);
}
}, {
key: "availableActions",
value: function availableActions() {
return this.makeRequest('availableActions', "".concat(this.formUrl, "/actions"));
}
}, {
key: "actionInfo",
value: function actionInfo(name) {
return this.makeRequest('actionInfo', "".concat(this.formUrl, "/actions/").concat(name));
}
}, {
key: "isObjectId",
value: function isObjectId(id) {
var checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
return checkForHexRegExp.test(id);
}
}, {
key: "getProjectId",
value: function getProjectId() {
if (!this.projectId) {
return _nativePromiseOnly.default.resolve('');
}
if (this.isObjectId(this.projectId)) {
return _nativePromiseOnly.default.resolve(this.projectId);
} else {
return this.loadProject().then(function (project) {
return project._id;
});
}
}
}, {
key: "getFormId",
value: function getFormId() {
if (!this.formId) {
return _nativePromiseOnly.default.resolve('');
}
if (this.isObjectId(this.formId)) {
return _nativePromiseOnly.default.resolve(this.formId);
} else {
return this.loadForm().then(function (form) {
return form._id;
});
}
}
}, {
key: "currentUser",
value: function currentUser(options) {
return Formio.currentUser(this, options);
}
}, {
key: "accessInfo",
value: function accessInfo() {
return Formio.accessInfo(this);
}
/**
* Returns the JWT token for this instance.
*
* @return {*}
*/
}, {
key: "getToken",
value: function getToken(options) {
return Formio.getToken(Object.assign({
formio: this
}, this.options, options));
}
/**
* Sets the JWT token for this instance.
*
* @return {*}
*/
}, {
key: "setToken",
value: function setToken(token, options) {
return Formio.setToken(token, Object.assign({
formio: this
}, this.options, options));
}
/**
* Returns a temporary authentication token for single purpose token generation.
*/
}, {
key: "getTempToken",
value: function getTempToken(expire, allowed, options) {
var token = Formio.getToken(options);
if (!token) {
return _nativePromiseOnly.default.reject('You must be authenticated to generate a temporary auth token.');
}
return this.makeRequest('tempToken', "".concat(this.projectUrl, "/token"), 'GET', null, {
ignoreCache: true,
header: new Headers({
'x-expire': expire,
'x-allow': allowed
})
});
}
/**
* Get a download url for a submission PDF of this submission.
*
* @return {*}
*/
}, {
key: "getDownloadUrl",
value: function getDownloadUrl(form) {
var _this4 = this;
if (!this.submissionId) {
return _nativePromiseOnly.default.resolve('');
}
if (!form) {
// Make sure to load the form first.
return this.loadForm().then(function (_form) {
if (!_form) {
return '';
}
return _this4.getDownloadUrl(_form);
});
}
var apiUrl = "/project/".concat(form.project);
apiUrl += "/form/".concat(form._id);
apiUrl += "/submission/".concat(this.submissionId);
apiUrl += '/download';
var download = this.base + apiUrl;
return new _nativePromiseOnly.default(function (resolve, reject) {
_this4.getTempToken(3600, "GET:".concat(apiUrl)).then(function (tempToken) {
download += "?token=".concat(tempToken.key);
resolve(download);
}, function () {
resolve(download);
}).catch(reject);
});
}
}, {
key: "uploadFile",
value: function uploadFile(storage, file, fileName, dir, progressCallback, url) {
var _this5 = this;
var requestArgs = {
provider: storage,
method: 'upload',
file: file,
fileName: fileName,
dir: dir
};
var request = Formio.pluginWait('preRequest', requestArgs).then(function () {
return Formio.pluginGet('fileRequest', requestArgs).then(function (result) {
if (storage && isNil(result)) {
if (Formio.providers.storage.hasOwnProperty(storage)) {
var provider = new Formio.providers.storage[storage](_this5);
return provider.uploadFile(file, fileName, dir, progressCallback, url);
} else {
throw 'Storage provider not found';
}
}
return result || {
url: ''
};
});
});
return Formio.pluginAlter('wrapFileRequestPromise', request, requestArgs);
}
}, {
key: "downloadFile",
value: function downloadFile(file) {
var _this6 = this;
var requestArgs = {
method: 'download',
file: file
};
var request = Formio.pluginWait('preRequest', requestArgs).then(function () {
return Formio.pluginGet('fileRequest', requestArgs).then(function (result) {
if (file.storage && isNil(result)) {
if (Formio.providers.storage.hasOwnProperty(file.storage)) {
var provider = new Formio.providers.storage[file.storage](_this6);
return provider.downloadFile(file);
} else {
throw 'Storage provider not found';
}
}
return result || {
url: ''
};
});
});
return Formio.pluginAlter('wrapFileRequestPromise', request, requestArgs);
} // Determine if the user can submit the form.
}, {
key: "canSubmit",
value: function canSubmit() {
/* eslint-disable max-statements, max-depth */
return _nativePromiseOnly.default.all([this.loadForm(), this.currentUser(), this.accessInfo()]).then(function (results) {
var form = results.shift();
var user = results.shift();
var access = results.shift(); // Get the anonymous and admin roles.
var anonRole = {};
var adminRole = {};
for (var roleName in access.roles) {
if (access.roles.hasOwnProperty(roleName)) {
var role = access.roles[roleName];
if (role.default) {
anonRole = role;
}
if (role.admin) {
adminRole = role;
}
}
}
var canSubmit = false;
var canSubmitAnonymously = false; // If the user is an admin, then they can submit this form.
if (user && user.roles.includes(adminRole._id)) {
return true;
}
for (var i in form.submissionAccess) {
if (form.submissionAccess.hasOwnProperty(i)) {
var subRole = form.submissionAccess[i];
if (subRole.type === 'create_all' || subRole.type === 'create_own') {
for (var j in subRole.roles) {
if (subRole.roles.hasOwnProperty(j)) {
// Check if anonymous is allowed.
if (anonRole._id === subRole.roles[j]) {
canSubmitAnonymously = true;
} // Check if the logged in user has the appropriate role.
if (user && user.roles.includes(subRole.roles[j])) {
canSubmit = true;
break;
}
}
}
if (canSubmit) {
break;
}
}
}
} // If their user cannot submit, but anonymous can, then delete token and allow submission.
if (!canSubmit && canSubmitAnonymously) {
canSubmit = true;
Formio.setUser(null);
}
return canSubmit;
});
/* eslint-enable max-statements, max-depth */
}
}, {
key: "getUrlParts",
value: function getUrlParts(url) {
return Formio.getUrlParts(url, this);
}
}], [{
key: "loadProjects",
value: function loadProjects(query, opts) {
query = query || '';
if (isObject(query)) {
query = "?".concat(Formio.serialize(query.params));
}
return Formio.makeStaticRequest("".concat(Formio.baseUrl, "/project").concat(query), 'GET', null, opts);
}
}, {
key: "getUrlParts",
value: function getUrlParts(url, formio) {
var base = formio && formio.base ? formio.base : Formio.baseUrl;
var regex = '^(http[s]?:\\/\\/)';
if (base && url.indexOf(base) === 0) {
regex += "(".concat(base.replace(/^http[s]?:\/\//, ''), ")");
} else {
regex += '([^/]+)';
}
regex += '($|\\/.*)';
return url.match(new RegExp(regex));
}
}, {
key: "serialize",
value: function serialize(obj) {
var str = [];
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
str.push("".concat(encodeURIComponent(p), "=").concat(encodeURIComponent(obj[p])));
}
}
return str.join('&');
}
}, {
key: "getRequestArgs",
value: function getRequestArgs(formio, type, url, method, data, opts) {
method = (method || 'GET').toUpperCase();
if (!opts || !isObject(opts)) {
opts = {};
}
var requestArgs = {
url: url,
method: method,
data: data || null,
opts: opts
};
if (type) {
requestArgs.type = type;
}
if (formio) {
requestArgs.formio = formio;
}
return requestArgs;
}
}, {
key: "makeStaticRequest",
value: function makeStaticRequest(url, method, data, opts) {
var requestArgs = Formio.getRequestArgs(null, '', url, method, data, opts);
var request = Formio.pluginWait('preRequest', requestArgs).then(function () {
return Formio.pluginGet('staticRequest', requestArgs).then(function (result) {
if (isNil(result)) {
return Formio.request(url, method, requestArgs.data, requestArgs.opts.header, requestArgs.opts);
}
return result;
});
});
return Formio.pluginAlter('wrapStaticRequestPromise', request, requestArgs);
}
}, {
key: "makeRequest",
value: function makeRequest(formio, type, url, method, data, opts) {
if (!formio) {
return Formio.makeStaticRequest(url, method, data, opts);
}
var requestArgs = Formio.getRequestArgs(formio, type, url, method, data, opts);
requestArgs.opts = requestArgs.opts || {};
requestArgs.opts.formio = formio;
var request = Formio.pluginWait('preRequest', requestArgs).then(function () {
return Formio.pluginGet('request', requestArgs).then(function (result) {
if (isNil(result)) {
return Formio.request(url, method, requestArgs.data, requestArgs.opts.header, requestArgs.opts);
}
return result;
});
});
return Formio.pluginAlter('wrapRequestPromise', request, requestArgs);
}
}, {
key: "request",
value: function request(url, method, data, header, opts) {
if (!url) {
return _nativePromiseOnly.default.reject('No url provided');
}
method = (method || 'GET').toUpperCase(); // For reverse compatibility, if they provided the ignoreCache parameter,
// then change it back to the options format where that is a parameter.
if (isBoolean(opts)) {
opts = {
ignoreCache: opts
};
}
if (!opts || !isObject(opts)) {
opts = {};
} // Generate a cachekey.
var cacheKey = btoa(url); // Get the cached promise to save multiple loads.
if (!opts.ignoreCache && method === 'GET' && Formio.cache.hasOwnProperty(cacheKey)) {
return Formio.cache[cacheKey];
} // Set up and fetch request
var headers = header || new Headers(opts.headers || {
'Accept': 'application/json',
'Content-type': 'application/json; charset=UTF-8'
});
var token = Formio.getToken(opts);
if (token && !opts.noToken) {
headers.append('x-jwt-token', token);
}
var options = {
method: method,
headers: headers,
mode: 'cors'
};
if (data) {
options.body = JSON.stringify(data);
} // Allow plugins to alter the options.
options = Formio.pluginAlter('requestOptions', options, url);
if (options.namespace) {
opts.namespace = options.namespace;
}
var requestToken = options.headers.get('x-jwt-token');
var result = fetch(url, options).then(function (response) {
// Allow plugins to respond.
response = Formio.pluginAlter('requestResponse', response, Formio);
if (!response.ok) {
if (response.status === 440) {
Formio.setToken(null, opts);
Formio.events.emit('formio.sessionExpired', response.body);
} else if (response.status === 401) {
Formio.events.emit('formio.unauthorized', response.body);
} // Parse and return the error as a rejected promise to reject this promise
return (response.headers.get('content-type').includes('application/json') ? response.json() : response.text()).then(function (error) {
return _nativePromiseOnly.default.reject(error);
});
} // Handle fetch results
var token = response.headers.get('x-jwt-token'); // In some strange cases, the fetch library will return an x-jwt-token without sending
// one to the server. This has even been debugged on the server to verify that no token
// was introduced with the request, but the response contains a token. This is an Invalid
// case where we do not send an x-jwt-token and get one in return for any GET request.
var tokenIntroduced = false;
if (method === 'GET' && !requestToken && token && !opts.external && !url.includes('token=') && !url.includes('x-jwt-token=')) {
console.warn('Token was introduced in request.');
tokenIntroduced = true;
}
if (response.status >= 200 && response.status < 300 && token && token !== '' && !tokenIntroduced) {
Formio.setToken(token, opts);
} // 204 is no content. Don't try to .json() it.
if (response.status === 204) {
return {};
}
var getResult = response.headers.get('content-type').includes('application/json') ? response.json() : response.text();
return getResult.then(function (result) {
// Add some content-range metadata to the result here
var range = response.headers.get('content-range');
if (range && isObject(result)) {
range = range.split('/');
if (range[0] !== '*') {
var skipLimit = range[0].split('-');
result.skip = Number(skipLimit[0]);
result.limit = skipLimit[1] - skipLimit[0] + 1;
}
result.serverCount = range[1] === '*' ? range[1] : Number(range[1]);
}
if (!opts.getHeaders) {
return result;
}
var headers = {};
response.headers.forEach(function (item, key) {
headers[key] = item;
}); // Return the result with the headers.
return {
result: result,
headers: headers
};
});
}).then(function (result) {
if (opts.getHeaders) {
return result;
}
var resultCopy = {}; // Shallow copy result so modifications don't end up in cache
if (Array.isArray(result)) {
resultCopy = result.map(_shallowCopy.default);
resultCopy.skip = result.skip;
resultCopy.limit = result.limit;
resultCopy.serverCount = result.serverCount;
} else {
resultCopy = (0, _shallowCopy.default)(result);
}
return resultCopy;
}).catch(function (err) {
if (err === 'Bad Token') {
Formio.setToken(null, opts);
Formio.events.emit('formio.badToken', err);
}
if (err.message) {
err.message = "Could not connect to API server (".concat(err.message, ")");
err.networkError = true;
}
if (method === 'GET') {
delete Formio.cache[cacheKey];
}
return _nativePromiseOnly.default.reject(err);
}); // Cache the response.
if (method === 'GET') {
Formio.cache[cacheKey] = result;
}
return result;
} // Needed to maintain reverse compatability...
}, {
key: "setToken",
value: function setToken() {
var token = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var opts = arguments.length > 1 ? arguments[1] : undefined;
opts = typeof opts === 'string' ? {
namespace: opts
} : opts || {};
var tokenName = "".concat(opts.namespace || 'formio', "Token");
if (!Formio.tokens) {
Formio.tokens = {};
}
if (Formio.tokens[tokenName] === token) {
return;
}
Formio.tokens[tokenName] = token;
if (!token) {
Formio.setUser(null, opts); // iOS in private browse mode will throw an error but we can't detect ahead of time that we are in private mode.
try {
return localStorage.removeItem(tokenName);
} catch (err) {
return _browserCookies.default.erase(tokenName, {
path: '/'
});
}
} // iOS in private browse mode will throw an error but we can't detect ahead of time that we are in private mode.
try {
localStorage.setItem(tokenName, token);
} catch (err) {
_browserCookies.default.set(tokenName, token, {
path: '/'
});
}
return Formio.currentUser(opts.formio, opts); // Run this so user is updated if null
}
}, {
key: "getToken",
value: function getToken(options) {
options = typeof options === 'string' ? {
namespace: options
} : options || {};
var tokenName = "".concat(options.namespace || 'formio', "Token");
if (!Formio.tokens) {
Formio.tokens = {};
}
if (Formio.tokens[tokenName]) {
return Formio.tokens[tokenName];
}
try {
Formio.tokens[tokenName] = localStorage.getItem(tokenName) || '';
return Formio.tokens[tokenName];
} catch (e) {
Formio.tokens[tokenName] = _browserCookies.default.get(tokenName);
return Formio.tokens[tokenName];
}
}
}, {
key: "setUser",
value: function setUser(user) {
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var userName = "".concat(opts.namespace || 'formio', "User");
if (!user) {
Formio.setToken(null, opts); // iOS in private browse mode will throw an error but we can't detect ahead of time that we are in private mode.
try {
return localStorage.removeItem(userName);
} catch (err) {
return _browserCookies.default.erase(userName, {
path: '/'
});
}
} // iOS in private browse mode will throw an error but we can't detect ahead of time that we are in private mode.
try {
localStorage.setItem(userName, JSON.stringify(user));
} catch (err) {
_browserCookies.default.set(userName, JSON.stringify(user), {
path: '/'
});
}
}
}, {
key: "getUser",
value: function getUser(options) {
options = options || {};
var userName = "".concat(options.namespace || 'formio', "User");
try {
return JSON.parse(localStorage.getItem(userName) || null);
} catch (e) {
return JSON.parse(_browserCookies.default.get(userName));
}
}
}, {
key: "setBaseUrl",
value: function setBaseUrl(url) {
Formio.baseUrl = url;
if (!Formio.projectUrlSet) {
Formio.projectUrl = url;
}
}
}, {
key: "getBaseUrl",
value: function getBaseUrl() {
return Formio.baseUrl;
}
}, {
key: "setApiUrl",
value: function setApiUrl(url) {
return Formio.setBaseUrl(url);
}
}, {
key: "getApiUrl",
value: function getApiUrl() {
return Formio.getBaseUrl();
}
}, {
key: "setAppUrl",
value: function setAppUrl(url) {
console.warn('Formio.setAppUrl() is deprecated. Use Formio.setProjectUrl instead.');
Formio.projectUrl = url;
Formio.projectUrlSet = true;
}
}, {
key: "setProjectUrl",
value: function setProjectUrl(url) {
Formio.projectUrl = url;
Formio.projectUrlSet = true;
}
}, {
key: "getAppUrl",
value: function getAppUrl() {
console.warn('Formio.getAppUrl() is deprecated. Use Formio.getProjectUrl instead.');
return Formio.projectUrl;
}
}, {
key: "getProjectUrl",
value: function getProjectUrl() {
return Formio.projectUrl;
}
}, {
key: "clearCache",
value: function clearCache() {
Formio.cache = {};
}
}, {
key: "noop",
value: function noop() {}
}, {
key: "identity",
value: function identity(value) {
return value;
}
}, {
key: "deregisterPlugin",
value: function deregisterPlugin(plugin) {
var beforeLength = Formio.plugins.length;
Formio.plugins = Formio.plugins.filter(function (p) {
if (p !== plugin && p.__name !== plugin) {
return true;
}
(p.deregister || Formio.noop).call(plugin, Formio);
return false;
});
return beforeLength !== Formio.plugins.length;
}
}, {
key: "registerPlugin",
value: function registerPlugin(plugin, name) {
Formio.plugins.push(plugin);
Formio.plugins.sort(function (a, b) {
return (b.priority || 0) - (a.priority || 0);
});
plugin.__name = name;
(plugin.init || Formio.noop).call(plugin, Formio);
}
}, {
key: "getPlugin",
value: function getPlugin(name) {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = Formio.plugins[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var plugin = _step.value;
if (plugin.__name === name) {
return plugin;
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return null;
}
}, {
key: "pluginWait",
value: function pluginWait(pluginFn) {
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
return _nativePromiseOnly.default.all(Formio.plugins.map(function (plugin) {
var _ref;
return (_ref = plugin[pluginFn] || Formio.noop).call.apply(_ref, [plugin].concat(args));
}));
}
}, {
key: "pluginGet",
value: function pluginGet(pluginFn) {
for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
args[_key3 - 1] = arguments[_key3];
}
var callPlugin = function callPlugin(index) {
var _ref2;
var plugin = Formio.plugins[index];
if (!plugin) {
return _nativePromiseOnly.default.resolve(null);
}
return _nativePromiseOnly.default.resolve((_ref2 = plugin[pluginFn] || Formio.noop).call.apply(_ref2, [plugin].concat(args))).then(function (result) {
if (!isNil(result)) {
return result;
}
return callPlugin(index + 1);
});
};
return callPlugin(0);
}
}, {
key: "pluginAlter",
value: function pluginAlter(pluginFn, value) {
for (var _len4 = arguments.length, args = new Array(_len4 > 2 ? _len4 - 2 : 0), _key4 = 2; _key4 < _len4; _key4++) {
args[_key4 - 2] = arguments[_key4];
}
return Formio.plugins.reduce(function (value, plugin) {
return (plugin[pluginFn] || Formio.identity).apply(void 0, [value].concat(args));
}, value);
}
}, {
key: "accessInfo",
value: function accessInfo(formio) {
var projectUrl = formio ? formio.projectUrl : Formio.projectUrl;
return Formio.makeRequest(formio, 'accessInfo', "".concat(projectUrl, "/access"));
}
}, {
key: "currentUser",
value: function currentUser(formio, options) {
var projectUrl = formio ? formio.projectUrl : Formio.projectUrl || Formio.baseUrl;
projectUrl += '/current';
var user = Formio.getUser(options);
if (user) {
return Formio.pluginAlter('wrapStaticRequestPromise', _nativePromiseOnly.default.resolve(user), {
url: projectUrl,
method: 'GET',
options: options
});
}
var token = Formio.getToken(options);
if ((!options || !options.external) && !token) {
return Formio.pluginAlter('wrapStaticRequestPromise', _nativePromiseOnly.default.resolve(null), {
url: projectUrl,
method: 'GET',
options: options
});
}
return Formio.makeRequest(formio, 'currentUser', projectUrl, 'GET', null, options).then(function (response) {
Formio.setUser(response, options);
return response;
});
}
}, {
key: "logout",
value: function logout(formio, options) {
options = options || {};
options.formio = formio;
Formio.setToken(null, options);
Formio.setUser(null, options);
Formio.clearCache();
var projectUrl = formio ? formio.projectUrl : Formio.baseUrl;
return Formio.makeRequest(formio, 'logout', "".concat(projectUrl, "/logout"));
}
}, {
key: "oAuthCurrentUser",
value: function oAuthCurrentUser(formio, token) {
return Formio.currentUser(formio, {
external: true,
headers: {
Authorization: "Bearer ".concat(token)
}
});
}
}, {
key: "oktaInit",
value: function oktaInit(options) {
options = options || {};
if ((typeof OktaAuth === "undefined" ? "undefined" : _typeof(OktaAuth)) !== undefined) {
options.OktaAuth = OktaAuth;
}
if (_typeof(options.OktaAuth) === undefined) {
var errorMessage = 'Cannot find OktaAuth. Please include the Okta JavaScript SDK within your application. See https://developer.okta.com/code/javascript/okta_auth_sdk for an example.';
console.warn(errorMessage);
return _nativePromiseOnly.default.reject(errorMessage);
}
return new _nativePromiseOnly.default(function (resolve, reject) {
var Okta = options.OktaAuth;
delete options.OktaAuth;
var authClient = new Okta(options);
var accessToken = authClient.tokenManager.get('accessToken');
if (accessToken) {
resolve(Formio.oAuthCurrentUser(options.formio, accessToken.accessToken));
} else if (location.hash) {
authClient.token.parseFromUrl().then(function (token) {
authClient.tokenManager.add('accessToken', token);
resolve(Formio.oAuthCurrentUser(options.formio, token.accessToken));
}).catch(function (err) {
console.warn(err);
reject(err);
});
} else {
authClient.token.getWithRedirect({
responseType: 'token',
scopes: options.scopes
});
resolve(false);
}
});
}
}, {
key: "ssoInit",
value: function ssoInit(type, options) {
switch (type) {
case 'okta':
return Formio.oktaInit(options);
default:
console.warn('Unknown SSO type');
return _nativePromiseOnly.default.reject('Unknown SSO type');
}
}
}, {
key: "requireLibrary",
value: function requireLibrary(name, property, src, polling) {
if (!Formio.libraries.hasOwnProperty(name)) {
Formio.libraries[name] = {};
Formio.libraries[name].ready = new _nativePromiseOnly.default(function (resolve, reject) {
Formio.libraries[name].resolve = resolve;
Formio.libraries[name].reject = reject;
});
var callbackName = "".concat(name, "Callback");
if (!polling && !window[callbackName]) {
window[callbackName] = function () {
return Formio.libraries[name].resolve();
};
} // See if the plugin already exists.
var plugin = (0, _get2.default)(window, property);
if (plugin) {
Formio.libraries[name].resolve(plugin);
} else {
src = Array.isArray(src) ? src : [src];
src.forEach(function (lib) {
var attrs = {};
var elementType = '';
if (typeof lib === 'string') {
lib = {
type: 'script',
src: lib
};
}
switch (lib.type) {
case 'script':
elementType = 'script';
attrs = {
src: lib.src,
type: 'text/javascript',
defer: true,
async: true
};
break;
case 'styles':
elementType = 'link';
attrs = {
href: lib.src,
rel: 'stylesheet'
};
break;
} // Add the script to the top page.
var script = document.createElement(elementType);
for (var attr in attrs) {
script.setAttribute(attr, attrs[attr]);
}
document.getElementsByTagName('head')[0].appendChild(script);
}); // if no callback is provided, then check periodically for the script.
if (polling) {
var interval = setInterval(function () {
var plugin = (0, _get2.default)(window, property);
if (plugin) {
clearInterval(interval);
Formio.libraries[name].resolve(plugin);
}
}, 200);
}
}
}
return Formio.libraries[name].ready;
}
}, {
key: "libraryReady",
value: function libraryReady(name) {
if (Formio.libraries.hasOwnProperty(name) && Formio.libraries[name].ready) {
return Formio.libraries[name].ready;
}
return _nativePromiseOnly.default.reject("".concat(name, " library was not required."));
}
}, {
key: "token",
get: function get() {
if (!Formio.tokens) {
Formio.tokens = {};
}
return Formio.tokens.formioToken ? Formio.tokens.formioToken : '';
} // Needed to maintain reverse compatability...
,
set: function set(token) {
if (!Formio.tokens) {
Formio.tokens = {};
}
return Formio.tokens.formioToken = token || '';
}
}]);
return Formio;
}(); // Define all the static properties.
exports.default = Formio;
Formio.libraries = {};
Formio.Promise = _nativePromiseOnly.default;
Formio.Headers = Headers;
Formio.baseUrl = 'https://api.form.io';
Formio.projectUrl = Formio.baseUrl;
Formio.projectUrlSet = false;
Formio.plugins = [];
Formio.cache = {};
Formio.providers = providers;
Formio.events = new _eventemitter.EventEmitter2({
wildcard: false,
maxListeners: 0
});
if ((typeof global === "undefined" ? "undefined" : _typeof(global)) === 'object' && !global.Formio) {
global.Formio = Formio;
}