UNPKG

formiojs

Version:

Common js library for client side interaction with <form.io>

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