UNPKG

formiojs

Version:

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

116 lines (109 loc) • 190 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});\n\nvar _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; /* globals OktaAuth */\n\n// Intentionally use native-promise-only here... Other promise libraries (es6-promise)\n// duck-punch the global Promise definition which messes up Angular 2 since it\n// also duck-punches the global Promise definition. For now, keep native-promise-only.\n\n\nvar _nativePromiseOnly = __webpack_require__(/*! native-promise-only */ \"./node_modules/native-promise-only/lib/npo.src.js\");\n\nvar _nativePromiseOnly2 = _interopRequireDefault(_nativePromiseOnly);\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 = __webpack_require__(/*! browser-cookies */ \"./node_modules/browser-cookies/src/browser-cookies.js\");\n\nvar _browserCookies2 = _interopRequireDefault(_browserCookies);\n\nvar _shallowCopy = __webpack_require__(/*! shallow-copy */ \"./node_modules/shallow-copy/index.js\");\n\nvar _shallowCopy2 = _interopRequireDefault(_shallowCopy);\n\nvar _providers = __webpack_require__(/*! ./providers */ \"./lib/providers/index.js\");\n\nvar _providers2 = _interopRequireDefault(_providers);\n\nvar _get2 = __webpack_require__(/*! lodash/get */ \"./node_modules/lodash/get.js\");\n\nvar _get3 = _interopRequireDefault(_get2);\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\nvar isBoolean = function isBoolean(val) {\n return (typeof val === 'undefined' ? 'undefined' : _typeof(val)) === _typeof(true);\n};\nvar isNil = function isNil(val) {\n return val === null || val === undefined;\n};\nvar isObject = function isObject(val) {\n return val && (typeof val === 'undefined' ? 'undefined' : _typeof(val)) === 'object';\n};\n\n/**\n * The Formio interface class.\n *\n * let formio = new Formio('https://examples.form.io/example');\n */\n\nvar Formio = function () {\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 }\n\n // Initialize our variables.\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 = '';\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 = this.base + '/project';\n this.projectsUrl = 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;\n\n // 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 if (project && this.base === project && !isProjectUrl) {\n this.noProject = true;\n this.projectUrl = this.base;\n }\n\n // Normalize to an absolute path.\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 if (queryparts.length > 1) {\n path = queryparts[0];\n this.query = '?' + queryparts[1];\n }\n\n // Register a specific path.\n var registerPath = function registerPath(name, base) {\n _this[name + 'sUrl'] = base + '/' + name;\n var regex = new RegExp('/' + name + '/([^/]+)');\n if (path.search(regex) !== -1) {\n parts = path.match(regex);\n _this[name + 'Url'] = parts ? base + parts[0] : '';\n _this[name + 'Id'] = parts.length > 1 ? parts[1] : '';\n base += parts[0];\n }\n return base;\n };\n\n // Register an array of items.\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 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 this.projectId = pathParts.shift();\n path = '/' + pathParts.join('/');\n this.projectUrl = hostName + '/' + this.projectId;\n }\n } else {\n // Get project id from subdomain.\n if (hostparts.length > 2 && (hostparts[2].split('.').length > 2 || hostName.indexOf('localhost') !== -1)) {\n this.projectUrl = hostName;\n this.projectId = hostparts[2].split('.')[0];\n }\n }\n this.projectsUrl = this.projectsUrl || this.base + '/project';\n }\n\n // Configure Form urls and form ids.\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 = this.projectUrl + '/form';\n this.formUrl = path ? this.projectUrl + path : '';\n this.formId = path.replace(/^\\/+|\\/+$/g, '');\n var items = ['submission', 'action', 'v'];\n for (var i in items) {\n if (items.hasOwnProperty(i)) {\n var item = items[i];\n this[item + 'sUrl'] = this.projectUrl + path + '/' + item;\n if (this.pathType === item && subs.length > 2 && subs[2]) {\n this[item + 'Id'] = subs[2].replace(/^\\/+|\\/+$/g, '');\n this[item + 'Url'] = this.projectUrl + path + subs[0];\n }\n }\n }\n }\n\n // Set the app url if it is not set.\n if (!Formio.projectUrlSet) {\n Formio.projectUrl = this.projectUrl;\n }\n }\n /* eslint-enable max-statements */\n\n _createClass(Formio, [{\n key: 'delete',\n value: function _delete(type, opts) {\n var _id = type + 'Id';\n var _url = type + 'Url';\n if (!this[_id]) {\n _nativePromiseOnly2.default.reject('Nothing to delete');\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 = type + 'Url';\n query = query || '';\n if (query && isObject(query)) {\n query = '?' + Formio.serialize(query.params);\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 = type + 'Id';\n var _url = type + 'Url';\n var method = this[_id] || data._id ? 'put' : 'post';\n var reqUrl = this[_id] ? this[_url] : this[type + 'sUrl'];\n if (!this[_id] && data._id && method === 'put' && !(reqUrl.indexOf(data._id) !== -1)) {\n reqUrl += '/' + data._id;\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 = type + 'Id';\n var _url = type + 'Url';\n if (query && isObject(query)) {\n query = Formio.serialize(query.params);\n }\n if (query) {\n query = this.query ? this.query + '&' + query : '?' + query;\n } else {\n query = this.query;\n }\n if (!this[_id]) {\n return _nativePromiseOnly2.default.reject('Missing ' + _id);\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 = 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 }\n // If a submission already exists but form is marked to load current version of form.\n if (currentForm.revisions === 'current' && _this2.submissionId) {\n return currentForm;\n }\n // If they specified a revision form, load the revised form components.\n if (query && isObject(query)) {\n query = Formio.serialize(query.params);\n }\n if (query) {\n query = _this2.query ? _this2.query + '&' + query : '?' + query;\n } else {\n query = _this2.query;\n }\n return _this2.makeRequest('form', _this2.vUrl + query, 'get', null, opts).then(function (revisionForm) {\n currentForm.components = revisionForm.components;\n // Using object.assign so we don't cross polinate multiple form loads.\n return Object.assign({}, currentForm);\n })\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 = _this3.formUrl + '/v/' + _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 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', this.formUrl + '/actions');\n }\n }, {\n key: 'actionInfo',\n value: function actionInfo(name) {\n return this.makeRequest('actionInfo', this.formUrl + '/actions/' + 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 _nativePromiseOnly2.default.resolve('');\n }\n if (this.isObjectId(this.projectId)) {\n return _nativePromiseOnly2.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 _nativePromiseOnly2.default.resolve('');\n }\n if (this.isObjectId(this.formId)) {\n return _nativePromiseOnly2.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 /**\n * Returns the JWT token for this instance.\n *\n * @return {*}\n */\n\n }, {\n key: 'getToken',\n value: function getToken() {\n return Formio.getToken();\n }\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) {\n var token = Formio.getToken();\n if (!token) {\n return _nativePromiseOnly2.default.reject('You must be authenticated to generate a temporary auth token.');\n }\n return this.makeRequest('tempToken', 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 /**\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 _nativePromiseOnly2.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 return _this4.getDownloadUrl(_form);\n });\n }\n\n var apiUrl = '/project/' + form.project;\n apiUrl += '/form/' + form._id;\n apiUrl += '/submission/' + this.submissionId;\n apiUrl += '/download';\n\n var download = this.base + apiUrl;\n return new _nativePromiseOnly2.default(function (resolve, reject) {\n _this4.getTempToken(3600, 'GET:' + apiUrl).then(function (tempToken) {\n download += '?token=' + 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 return result || { 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\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 return result || { url: '' };\n });\n });\n\n return Formio.pluginAlter('wrapFileRequestPromise', request, requestArgs);\n }\n\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 _nativePromiseOnly2.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();\n\n // Get the anonymous and admin roles.\n var anonRole = {};\n var adminRole = {};\n for (var roleName in access.roles) {\n if (access.roles.hasOwnProperty(roleName)) {\n var role = access.roles[roleName];\n if (role.default) {\n anonRole = role;\n }\n if (role.admin) {\n adminRole = role;\n }\n }\n }\n\n var canSubmit = false;\n var canSubmitAnonymously = false;\n\n // If the user is an admin, then they can submit this form.\n if (user && user.roles.indexOf(adminRole._id) !== -1) {\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 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 }\n // Check if the logged in user has the appropriate role.\n if (user && user.roles.indexOf(subRole.roles[j]) !== -1) {\n canSubmit = true;\n break;\n }\n }\n }\n if (canSubmit) {\n break;\n }\n }\n }\n }\n // If their user cannot submit, but anonymous can, then delete token and allow submission.\n if (!canSubmit && canSubmitAnonymously) {\n canSubmit = true;\n Formio.setUser(null);\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 if (isObject(query)) {\n query = '?' + Formio.serialize(query.params);\n }\n return Formio.makeStaticRequest(Formio.baseUrl + '/project' + 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 if (base && url.indexOf(base) === 0) {\n regex += '(' + base.replace(/^http[s]?:\\/\\//, '') + ')';\n } else {\n regex += '([^/]+)';\n }\n regex += '($|\\\\/.*)';\n return url.match(new RegExp(regex));\n }\n }, {\n key: 'serialize',\n value: function serialize(obj) {\n var str = [];\n for (var p in obj) {\n if (obj.hasOwnProperty(p)) {\n str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));\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 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 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 return result;\n });\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 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 return result;\n });\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 _nativePromiseOnly2.default.reject('No url provided');\n }\n method = (method || 'GET').toUpperCase();\n\n // For reverse compatibility, if they provided the ignoreCache parameter,\n // then change it back to the options format where that is a parameter.\n if (isBoolean(opts)) {\n opts = { ignoreCache: opts };\n }\n if (!opts || !isObject(opts)) {\n opts = {};\n }\n\n // Generate a cachekey.\n var cacheKey = btoa(url);\n\n // Get the cached promise to save multiple loads.\n if (!opts.ignoreCache && method === 'GET' && Formio.cache.hasOwnProperty(cacheKey)) {\n return _nativePromiseOnly2.default.resolve(Formio.cache[cacheKey]);\n }\n\n // Set up and fetch request\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();\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 if (data) {\n options.body = JSON.stringify(data);\n }\n\n // Allow plugins to alter the options.\n options = Formio.pluginAlter('requestOptions', options, url);\n\n var requestToken = options.headers.get('x-jwt-token');\n return 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);\n Formio.events.emit('formio.sessionExpired', response.body);\n } else if (response.status === 401) {\n Formio.events.emit('formio.unauthorized', response.body);\n }\n // Parse and return the error as a rejected promise to reject this promise\n return (response.headers.get('content-type').indexOf('application/json') !== -1 ? response.json() : response.text()).then(function (error) {\n return _nativePromiseOnly2.default.reject(error);\n });\n }\n\n // Handle fetch results\n var token = response.headers.get('x-jwt-token');\n\n // 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 var tokenIntroduced = false;\n if (method === 'GET' && !requestToken && token && !opts.external && !(url.indexOf('token=') !== -1) && !(url.indexOf('x-jwt-token=') !== -1)) {\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);\n }\n // 204 is no content. Don't try to .json() it.\n if (response.status === 204) {\n return {};\n }\n\n var getResult = response.headers.get('content-type').indexOf('application/json') !== -1 ? 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 if (range && isObject(result)) {\n range = range.split('/');\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 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 });\n\n // Return the result with the headers.\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 = {};\n\n // Shallow copy result so modifications don't end up in cache\n if (Array.isArray(result)) {\n resultCopy = result.map(_shallowCopy2.default);\n resultCopy.skip = result.skip;\n resultCopy.limit = result.limit;\n resultCopy.serverCount = result.serverCount;\n } else {\n resultCopy = (0, _shallowCopy2.default)(result);\n }\n\n // Cache the response.\n if (method === 'GET') {\n Formio.cache[cacheKey] = resultCopy;\n }\n\n return resultCopy;\n }).catch(function (err) {\n if (err === 'Bad Token') {\n Formio.setToken(null);\n Formio.events.emit('formio.badToken', err);\n }\n if (err.message) {\n err.message = 'Could not connect to API server (' + err.message + ')';\n err.networkError = true;\n }\n return _nativePromiseOnly2.default.reject(err);\n });\n }\n }, {\n key: 'setToken',\n value: function setToken(token) {\n token = token || '';\n if (token === this.token) {\n return;\n }\n this.token = token;\n if (!token) {\n Formio.setUser(null);\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 try {\n return localStorage.removeItem('formioToken');\n } catch (err) {\n return _browserCookies2.default.erase('formioToken', { 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 try {\n localStorage.setItem('formioToken', token);\n } catch (err) {\n _browserCookies2.default.set('formioToken', token, { path: '/' });\n }\n return Formio.currentUser(); // Run this so user is updated if null\n }\n }, {\n key: 'getToken',\n value: function getToken() {\n if (this.token) {\n return this.token;\n }\n try {\n this.token = localStorage.getItem('formioToken') || '';\n return this.token;\n } catch (e) {\n this.token = _browserCookies2.default.get('formioToken');\n return this.token;\n }\n }\n }, {\n key: 'setUser',\n value: function setUser(user) {\n if (!user) {\n this.setToken(null);\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 try {\n return localStorage.removeItem('formioUser');\n } catch (err) {\n return _browserCookies2.default.erase('formioUser', { 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 try {\n localStorage.setItem('formioUser', JSON.stringify(user));\n } catch (err) {\n _browserCookies2.default.set('formioUser', JSON.stringify(user), { path: '/' });\n }\n }\n }, {\n key: 'getUser',\n value: function getUser() {\n try {\n return JSON.parse(localStorage.getItem('formioUser') || null);\n } catch (e) {\n return JSON.parse(_browserCookies2.default.get('formioUser'));\n }\n }\n }, {\n key: 'setBaseUrl',\n value: function setBaseUrl(url) {\n Formio.baseUrl = url;\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) {\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 = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n args[_key2 - 1] = arguments[_key2];\n }\n\n return _nativePromiseOnly2.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 = 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 _nativePromiseOnly2.default.resolve(null);\n }\n\n return _nativePromiseOnly2.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 return callPlugin(0);\n }\n }, {\n key: 'pluginAlter',\n value: function pluginAlter(pluginFn, value) {\n for (var _len4 = arguments.length, args = 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(undefined, [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', 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 = this.getUser();\n if (user) {\n return Formio.pluginAlter('wrapStaticRequestPromise', _nativePromiseOnly2.default.resolve(user), {\n url: projectUrl,\n method: 'GET',\n options: options\n });\n }\n if ((!options || !options.external) && !Formio.getToken()) {\n return Formio.pluginAlter('wrapStaticRequestPromise', _nativePromiseOnly2.default.resolve(null), {\n url: projectUrl,\n method: 'GET',\n options: options\n });\n }\n return Formio.makeRequest(formio, 'currentUser', projectUrl, 'GET', null, options).then(function (response) {\n Formio.setUser(response);\n return response;\n });\n }\n }, {\n key: 'logout',\n value: function logout(formio) {\n Formio.setToken(null);\n Formio.setUser(null);\n Formio.clearCache();\n var projectUrl = formio ? formio.projectUrl : Formio.baseUrl;\n return Formio.makeRequest(formio, 'logout', 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 ' + token\n }\n });\n }\n }, {\n key: 'oktaInit',\n value: function oktaInit(options) {\n options = options || {};\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 _nativePromiseOnly2.default.reject(errorMessage);\n }\n return new _nativePromiseOnly2.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 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 default:\n console.warn('Unknown SSO type');\n return _nativePromiseOnly2.default.reject('Unknown SSO type');\n }\n }\n }, {\n key: 'requireLibrary',\n value: function requireLibrary(name, property, src, polling) {\n if (!Formio.libraries.hasOwnProperty(name)) {\n Formio.libraries[name] = {};\n Formio.libraries[name].ready = new _nativePromiseOnly2.default(function (resolve, reject) {\n Formio.libraries[name].resolve = resolve;\n Formio.libraries[name].reject = reject;\n });\n\n var callbackName = name + 'Callback';\n\n if (!polling && !window[callbackName]) {\n window[callbackName] = function () {\n return Formio.libraries[name].resolve();\n };\n }\n\n // See if the plugin already exists.\n var plugin = (0, _get3.default)(window, property);\n if (plugin) {\n Formio.libraries[name].resolve(plugin);\n } else {\n src = Array.isArray(src) ? src : [src];\n src.forEach(function (lib) {\n var attrs = {};\n var elementType = '';\n if (typeof lib === 'string') {\n lib = {\n type: 'script',\n src: lib\n };\n }\n switch (lib.type) {\n case 'script':\n elementType = 'script';\n attrs = {\n src: lib.src,\n type: 'text/javascript',\n defer: true,\n async: true\n };\n break;\n case 'styles':\n elementType = 'link';\n attrs = {\n href: lib.src,\n rel: 'stylesheet'\n };\n break;\n }\n\n // Add the script to the top page.\n var script = document.createElement(elementType);\n for (var attr in attrs) {\n script.setAttribute(attr, attrs[attr]);\n }\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n\n // if no callback is provided, then check periodically for the script.\n if (polling) {\n var interval = setInterval(function () {\n var plugin = (0, _get3.default)(window, property);\n if (plugin) {\n clearInterval(interval);\n Formio.libraries[name].resolve(plugin);\n }\n }, 200);\n }\n }\n }\n return Formio.libraries[name].ready;\n }\n }, {\n key: 'libraryReady',\n value: function libraryReady(name) {\n if (Formio.libraries.hasOwnProperty(name) && Formio.libraries[name].ready) {\n return Formio.libraries[name].ready;\n }\n\n return _nativePromiseOnly2.default.reject(name + ' library was not required.');\n }\n }]);\n\n return Formio;\n}();\n\n// Define all the static properties.\n\n\nexports.default = Formio;\nFormio.libraries = {};\nFormio.Headers = Headers;\nFormio.baseUrl = 'https://api.form.io';\nFormio.projectUrl = Formio.baseUrl;\nFormio.projectUrlSet = false;\nFormio.plugins = [];\nFormio.cache = {};\nFormio.providers = _providers2.default;\nFormio.events = new _eventemitter.EventEmitter2({\n wildcard: false,\n maxListeners: 0\n});\n\nif ((typeof global === 'undefined' ? 'undefined' : _typeof(global)) === 'object' && !global.Formio) {\n global.Formio = Formio;\n}\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../node_modules/webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n//# sourceURL=webpack:///./lib/Formio.js?"); /***/ }), /***/ "./lib/providers/index.js": /*!********************************!*\ !*** ./lib/providers/index.js ***! \********************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _storage = __webpack_require__(/*! ./storage */ \"./lib/providers/storage/index.js\");\n\nvar _storage2 = _interopRequireDefault(_storage);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nexports.default = {\n storage: _storage2.default\n};\n\n//# sourceURL=webpack:///./lib/providers/index.js?"); /***/ }), /***/ "./lib/providers/storage/base64.js": /*!*****************************************!*\ !*** ./lib/providers/storage/base64.js ***! \**************************************