@magicfeedback/native 1.1.16-beta.1 → 1.1.16-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,179 +1 @@
1
- /*
2
- * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
3
- * This devtool is neither made for production nor for readable output files.
4
- * It uses "eval()" calls to create a separate source file in the browser devtools.
5
- * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
6
- * or disable the default devtool with "devtool: false".
7
- * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
8
- */
9
- (function webpackUniversalModuleDefinition(root, factory) {
10
- if(typeof exports === 'object' && typeof module === 'object')
11
- module.exports = factory();
12
- else if(typeof define === 'function' && define.amd)
13
- define([], factory);
14
- else if(typeof exports === 'object')
15
- exports["magicfeedback"] = factory();
16
- else
17
- root["magicfeedback"] = factory();
18
- })(self, () => {
19
- return /******/ (() => { // webpackBootstrap
20
- /******/ var __webpack_modules__ = ({
21
-
22
- /***/ "./node_modules/cross-fetch/dist/browser-ponyfill.js":
23
- /*!***********************************************************!*\
24
- !*** ./node_modules/cross-fetch/dist/browser-ponyfill.js ***!
25
- \***********************************************************/
26
- /***/ (function(module, exports) {
27
-
28
- eval("var global = typeof self !== 'undefined' ? self : this;\nvar __self__ = (function () {\nfunction F() {\nthis.fetch = false;\nthis.DOMException = global.DOMException\n}\nF.prototype = global;\nreturn new F();\n})();\n(function(self) {\n\nvar irrelevant = (function (exports) {\n\n var support = {\n searchParams: 'URLSearchParams' in self,\n iterable: 'Symbol' in self && 'iterator' in Symbol,\n blob:\n 'FileReader' in self &&\n 'Blob' in self &&\n (function() {\n try {\n new Blob();\n return true\n } catch (e) {\n return false\n }\n })(),\n formData: 'FormData' in self,\n arrayBuffer: 'ArrayBuffer' in self\n };\n\n function isDataView(obj) {\n return obj && DataView.prototype.isPrototypeOf(obj)\n }\n\n if (support.arrayBuffer) {\n var viewClasses = [\n '[object Int8Array]',\n '[object Uint8Array]',\n '[object Uint8ClampedArray]',\n '[object Int16Array]',\n '[object Uint16Array]',\n '[object Int32Array]',\n '[object Uint32Array]',\n '[object Float32Array]',\n '[object Float64Array]'\n ];\n\n var isArrayBufferView =\n ArrayBuffer.isView ||\n function(obj) {\n return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1\n };\n }\n\n function normalizeName(name) {\n if (typeof name !== 'string') {\n name = String(name);\n }\n if (/[^a-z0-9\\-#$%&'*+.^_`|~]/i.test(name)) {\n throw new TypeError('Invalid character in header field name')\n }\n return name.toLowerCase()\n }\n\n function normalizeValue(value) {\n if (typeof value !== 'string') {\n value = String(value);\n }\n return value\n }\n\n // Build a destructive iterator for the value list\n function iteratorFor(items) {\n var iterator = {\n next: function() {\n var value = items.shift();\n return {done: value === undefined, value: value}\n }\n };\n\n if (support.iterable) {\n iterator[Symbol.iterator] = function() {\n return iterator\n };\n }\n\n return iterator\n }\n\n function Headers(headers) {\n this.map = {};\n\n if (headers instanceof Headers) {\n headers.forEach(function(value, name) {\n this.append(name, value);\n }, this);\n } else if (Array.isArray(headers)) {\n headers.forEach(function(header) {\n this.append(header[0], header[1]);\n }, this);\n } else if (headers) {\n Object.getOwnPropertyNames(headers).forEach(function(name) {\n this.append(name, headers[name]);\n }, this);\n }\n }\n\n Headers.prototype.append = function(name, value) {\n name = normalizeName(name);\n value = normalizeValue(value);\n var oldValue = this.map[name];\n this.map[name] = oldValue ? oldValue + ', ' + value : value;\n };\n\n Headers.prototype['delete'] = function(name) {\n delete this.map[normalizeName(name)];\n };\n\n Headers.prototype.get = function(name) {\n name = normalizeName(name);\n return this.has(name) ? this.map[name] : null\n };\n\n Headers.prototype.has = function(name) {\n return this.map.hasOwnProperty(normalizeName(name))\n };\n\n Headers.prototype.set = function(name, value) {\n this.map[normalizeName(name)] = normalizeValue(value);\n };\n\n Headers.prototype.forEach = function(callback, thisArg) {\n for (var name in this.map) {\n if (this.map.hasOwnProperty(name)) {\n callback.call(thisArg, this.map[name], name, this);\n }\n }\n };\n\n Headers.prototype.keys = function() {\n var items = [];\n this.forEach(function(value, name) {\n items.push(name);\n });\n return iteratorFor(items)\n };\n\n Headers.prototype.values = function() {\n var items = [];\n this.forEach(function(value) {\n items.push(value);\n });\n return iteratorFor(items)\n };\n\n Headers.prototype.entries = function() {\n var items = [];\n this.forEach(function(value, name) {\n items.push([name, value]);\n });\n return iteratorFor(items)\n };\n\n if (support.iterable) {\n Headers.prototype[Symbol.iterator] = Headers.prototype.entries;\n }\n\n function consumed(body) {\n if (body.bodyUsed) {\n return Promise.reject(new TypeError('Already read'))\n }\n body.bodyUsed = true;\n }\n\n function fileReaderReady(reader) {\n return new Promise(function(resolve, reject) {\n reader.onload = function() {\n resolve(reader.result);\n };\n reader.onerror = function() {\n reject(reader.error);\n };\n })\n }\n\n function readBlobAsArrayBuffer(blob) {\n var reader = new FileReader();\n var promise = fileReaderReady(reader);\n reader.readAsArrayBuffer(blob);\n return promise\n }\n\n function readBlobAsText(blob) {\n var reader = new FileReader();\n var promise = fileReaderReady(reader);\n reader.readAsText(blob);\n return promise\n }\n\n function readArrayBufferAsText(buf) {\n var view = new Uint8Array(buf);\n var chars = new Array(view.length);\n\n for (var i = 0; i < view.length; i++) {\n chars[i] = String.fromCharCode(view[i]);\n }\n return chars.join('')\n }\n\n function bufferClone(buf) {\n if (buf.slice) {\n return buf.slice(0)\n } else {\n var view = new Uint8Array(buf.byteLength);\n view.set(new Uint8Array(buf));\n return view.buffer\n }\n }\n\n function Body() {\n this.bodyUsed = false;\n\n this._initBody = function(body) {\n this._bodyInit = body;\n if (!body) {\n this._bodyText = '';\n } else if (typeof body === 'string') {\n this._bodyText = body;\n } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {\n this._bodyBlob = body;\n } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {\n this._bodyFormData = body;\n } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {\n this._bodyText = body.toString();\n } else if (support.arrayBuffer && support.blob && isDataView(body)) {\n this._bodyArrayBuffer = bufferClone(body.buffer);\n // IE 10-11 can't handle a DataView body.\n this._bodyInit = new Blob([this._bodyArrayBuffer]);\n } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {\n this._bodyArrayBuffer = bufferClone(body);\n } else {\n this._bodyText = body = Object.prototype.toString.call(body);\n }\n\n if (!this.headers.get('content-type')) {\n if (typeof body === 'string') {\n this.headers.set('content-type', 'text/plain;charset=UTF-8');\n } else if (this._bodyBlob && this._bodyBlob.type) {\n this.headers.set('content-type', this._bodyBlob.type);\n } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {\n this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');\n }\n }\n };\n\n if (support.blob) {\n this.blob = function() {\n var rejected = consumed(this);\n if (rejected) {\n return rejected\n }\n\n if (this._bodyBlob) {\n return Promise.resolve(this._bodyBlob)\n } else if (this._bodyArrayBuffer) {\n return Promise.resolve(new Blob([this._bodyArrayBuffer]))\n } else if (this._bodyFormData) {\n throw new Error('could not read FormData body as blob')\n } else {\n return Promise.resolve(new Blob([this._bodyText]))\n }\n };\n\n this.arrayBuffer = function() {\n if (this._bodyArrayBuffer) {\n return consumed(this) || Promise.resolve(this._bodyArrayBuffer)\n } else {\n return this.blob().then(readBlobAsArrayBuffer)\n }\n };\n }\n\n this.text = function() {\n var rejected = consumed(this);\n if (rejected) {\n return rejected\n }\n\n if (this._bodyBlob) {\n return readBlobAsText(this._bodyBlob)\n } else if (this._bodyArrayBuffer) {\n return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))\n } else if (this._bodyFormData) {\n throw new Error('could not read FormData body as text')\n } else {\n return Promise.resolve(this._bodyText)\n }\n };\n\n if (support.formData) {\n this.formData = function() {\n return this.text().then(decode)\n };\n }\n\n this.json = function() {\n return this.text().then(JSON.parse)\n };\n\n return this\n }\n\n // HTTP methods whose capitalization should be normalized\n var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'];\n\n function normalizeMethod(method) {\n var upcased = method.toUpperCase();\n return methods.indexOf(upcased) > -1 ? upcased : method\n }\n\n function Request(input, options) {\n options = options || {};\n var body = options.body;\n\n if (input instanceof Request) {\n if (input.bodyUsed) {\n throw new TypeError('Already read')\n }\n this.url = input.url;\n this.credentials = input.credentials;\n if (!options.headers) {\n this.headers = new Headers(input.headers);\n }\n this.method = input.method;\n this.mode = input.mode;\n this.signal = input.signal;\n if (!body && input._bodyInit != null) {\n body = input._bodyInit;\n input.bodyUsed = true;\n }\n } else {\n this.url = String(input);\n }\n\n this.credentials = options.credentials || this.credentials || 'same-origin';\n if (options.headers || !this.headers) {\n this.headers = new Headers(options.headers);\n }\n this.method = normalizeMethod(options.method || this.method || 'GET');\n this.mode = options.mode || this.mode || null;\n this.signal = options.signal || this.signal;\n this.referrer = null;\n\n if ((this.method === 'GET' || this.method === 'HEAD') && body) {\n throw new TypeError('Body not allowed for GET or HEAD requests')\n }\n this._initBody(body);\n }\n\n Request.prototype.clone = function() {\n return new Request(this, {body: this._bodyInit})\n };\n\n function decode(body) {\n var form = new FormData();\n body\n .trim()\n .split('&')\n .forEach(function(bytes) {\n if (bytes) {\n var split = bytes.split('=');\n var name = split.shift().replace(/\\+/g, ' ');\n var value = split.join('=').replace(/\\+/g, ' ');\n form.append(decodeURIComponent(name), decodeURIComponent(value));\n }\n });\n return form\n }\n\n function parseHeaders(rawHeaders) {\n var headers = new Headers();\n // Replace instances of \\r\\n and \\n followed by at least one space or horizontal tab with a space\n // https://tools.ietf.org/html/rfc7230#section-3.2\n var preProcessedHeaders = rawHeaders.replace(/\\r?\\n[\\t ]+/g, ' ');\n preProcessedHeaders.split(/\\r?\\n/).forEach(function(line) {\n var parts = line.split(':');\n var key = parts.shift().trim();\n if (key) {\n var value = parts.join(':').trim();\n headers.append(key, value);\n }\n });\n return headers\n }\n\n Body.call(Request.prototype);\n\n function Response(bodyInit, options) {\n if (!options) {\n options = {};\n }\n\n this.type = 'default';\n this.status = options.status === undefined ? 200 : options.status;\n this.ok = this.status >= 200 && this.status < 300;\n this.statusText = 'statusText' in options ? options.statusText : 'OK';\n this.headers = new Headers(options.headers);\n this.url = options.url || '';\n this._initBody(bodyInit);\n }\n\n Body.call(Response.prototype);\n\n Response.prototype.clone = function() {\n return new Response(this._bodyInit, {\n status: this.status,\n statusText: this.statusText,\n headers: new Headers(this.headers),\n url: this.url\n })\n };\n\n Response.error = function() {\n var response = new Response(null, {status: 0, statusText: ''});\n response.type = 'error';\n return response\n };\n\n var redirectStatuses = [301, 302, 303, 307, 308];\n\n Response.redirect = function(url, status) {\n if (redirectStatuses.indexOf(status) === -1) {\n throw new RangeError('Invalid status code')\n }\n\n return new Response(null, {status: status, headers: {location: url}})\n };\n\n exports.DOMException = self.DOMException;\n try {\n new exports.DOMException();\n } catch (err) {\n exports.DOMException = function(message, name) {\n this.message = message;\n this.name = name;\n var error = Error(message);\n this.stack = error.stack;\n };\n exports.DOMException.prototype = Object.create(Error.prototype);\n exports.DOMException.prototype.constructor = exports.DOMException;\n }\n\n function fetch(input, init) {\n return new Promise(function(resolve, reject) {\n var request = new Request(input, init);\n\n if (request.signal && request.signal.aborted) {\n return reject(new exports.DOMException('Aborted', 'AbortError'))\n }\n\n var xhr = new XMLHttpRequest();\n\n function abortXhr() {\n xhr.abort();\n }\n\n xhr.onload = function() {\n var options = {\n status: xhr.status,\n statusText: xhr.statusText,\n headers: parseHeaders(xhr.getAllResponseHeaders() || '')\n };\n options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL');\n var body = 'response' in xhr ? xhr.response : xhr.responseText;\n resolve(new Response(body, options));\n };\n\n xhr.onerror = function() {\n reject(new TypeError('Network request failed'));\n };\n\n xhr.ontimeout = function() {\n reject(new TypeError('Network request failed'));\n };\n\n xhr.onabort = function() {\n reject(new exports.DOMException('Aborted', 'AbortError'));\n };\n\n xhr.open(request.method, request.url, true);\n\n if (request.credentials === 'include') {\n xhr.withCredentials = true;\n } else if (request.credentials === 'omit') {\n xhr.withCredentials = false;\n }\n\n if ('responseType' in xhr && support.blob) {\n xhr.responseType = 'blob';\n }\n\n request.headers.forEach(function(value, name) {\n xhr.setRequestHeader(name, value);\n });\n\n if (request.signal) {\n request.signal.addEventListener('abort', abortXhr);\n\n xhr.onreadystatechange = function() {\n // DONE (success or failure)\n if (xhr.readyState === 4) {\n request.signal.removeEventListener('abort', abortXhr);\n }\n };\n }\n\n xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit);\n })\n }\n\n fetch.polyfill = true;\n\n if (!self.fetch) {\n self.fetch = fetch;\n self.Headers = Headers;\n self.Request = Request;\n self.Response = Response;\n }\n\n exports.Headers = Headers;\n exports.Request = Request;\n exports.Response = Response;\n exports.fetch = fetch;\n\n Object.defineProperty(exports, '__esModule', { value: true });\n\n return exports;\n\n})({});\n})(__self__);\n__self__.fetch.ponyfill = true;\n// Remove \"polyfill\" property added by whatwg-fetch\ndelete __self__.fetch.polyfill;\n// Choose between native implementation (global) or custom implementation (__self__)\n// var ctx = global.fetch ? global : __self__;\nvar ctx = __self__; // this line disable service worker support temporarily\nexports = ctx.fetch // To enable: import fetch from 'cross-fetch'\nexports[\"default\"] = ctx.fetch // For TypeScript consumers without esModuleInterop.\nexports.fetch = ctx.fetch // To enable: import {fetch} from 'cross-fetch'\nexports.Headers = ctx.Headers\nexports.Request = ctx.Request\nexports.Response = ctx.Response\nmodule.exports = exports\n\n\n//# sourceURL=webpack://magicfeedback/./node_modules/cross-fetch/dist/browser-ponyfill.js?");
29
-
30
- /***/ }),
31
-
32
- /***/ "./src/config-globals.ts":
33
- /*!*******************************!*\
34
- !*** ./src/config-globals.ts ***!
35
- \*******************************/
36
- /***/ ((__unused_webpack_module, exports) => {
37
-
38
- "use strict";
39
- eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.HOST_API_URL_DEV = exports.HOST_API_URL = void 0;\nexports.HOST_API_URL = 'https://api.magicfeedback.io/';\nexports.HOST_API_URL_DEV = 'https://api-dev.magicfeedback.io/';\n\n\n//# sourceURL=webpack://magicfeedback/./src/config-globals.ts?");
40
-
41
- /***/ }),
42
-
43
- /***/ "./src/index.ts":
44
- /*!**********************!*\
45
- !*** ./src/index.ts ***!
46
- \**********************/
47
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
48
-
49
- "use strict";
50
- eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst main_1 = __importDefault(__webpack_require__(/*! ./main */ \"./src/main.ts\"));\nlet instance = null;\nif (!instance) {\n instance = (0, main_1.default)();\n}\nexports[\"default\"] = instance;\n\n\n//# sourceURL=webpack://magicfeedback/./src/index.ts?");
51
-
52
- /***/ }),
53
-
54
- /***/ "./src/main.ts":
55
- /*!*********************!*\
56
- !*** ./src/main.ts ***!
57
- \*********************/
58
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
59
-
60
- "use strict";
61
- eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst form_1 = __webpack_require__(/*! ./models/form */ \"./src/models/form.ts\");\nconst config_1 = __webpack_require__(/*! ./models/config */ \"./src/models/config.ts\");\nconst log_1 = __webpack_require__(/*! ./utils/log */ \"./src/utils/log.ts\");\nconst request_service_1 = __webpack_require__(/*! ./services/request.service */ \"./src/services/request.service.ts\");\nconst config_globals_1 = __webpack_require__(/*! ./config-globals */ \"./src/config-globals.ts\");\n/**\n *\n * @returns\n */\nfunction main() {\n //===============================================\n // Attributes\n //===============================================\n const config = new config_1.Config();\n let log;\n /**\n *\n * @param options\n */\n function init(options) {\n if (options === null || options === void 0 ? void 0 : options.debug)\n config.set(\"debug\", options === null || options === void 0 ? void 0 : options.debug);\n config.set(\"url\", (options === null || options === void 0 ? void 0 : options.env) && (options === null || options === void 0 ? void 0 : options.env) === \"dev\" ? config_globals_1.HOST_API_URL_DEV : config_globals_1.HOST_API_URL);\n log = new log_1.Log(config);\n log.log(\"Initialized Magicfeedback\", config);\n }\n /**\n *\n * @param appId\n * @param publicKey\n * @param feedback\n * @param id\n * @param completed\n * @param privateKey\n * @returns\n */\n function send(appId, publicKey, feedback, completed = true, id, privateKey) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!appId)\n log.err(\"No appID provided\");\n if (!publicKey)\n log.err(\"No publicKey provided\");\n if (!feedback)\n log.err(\"No feedback provided\");\n if (!feedback.answers &&\n !feedback.profile &&\n !feedback.metrics &&\n !feedback.metadata)\n log.err(\"No feedback data provided\");\n const url = config.get(\"url\");\n const body = {\n integration: appId,\n publicKey: publicKey,\n privateKey: privateKey,\n completed: completed,\n id: id,\n feedback: feedback,\n };\n try {\n const res = yield (0, request_service_1.sendFeedback)(url, body, log);\n log.log(`sent native feedback`);\n return res;\n }\n catch (e) {\n log.err(`error native feedback`, e);\n return false;\n }\n });\n }\n /**\n *\n * @param appId\n * @param publicKey\n * @returns\n */\n function form(appId, publicKey) {\n if (!appId)\n log.err(\"No appID provided\");\n if (!publicKey)\n log.err(\"No publicKey provided\");\n return new form_1.Form(config, appId, publicKey);\n }\n //===============================================\n // Return\n //===============================================\n return {\n // lifecycle\n init,\n // requests\n send,\n form,\n };\n}\nexports[\"default\"] = main;\n\n\n//# sourceURL=webpack://magicfeedback/./src/main.ts?");
62
-
63
- /***/ }),
64
-
65
- /***/ "./src/models/config.ts":
66
- /*!******************************!*\
67
- !*** ./src/models/config.ts ***!
68
- \******************************/
69
- /***/ ((__unused_webpack_module, exports) => {
70
-
71
- "use strict";
72
- eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Config = void 0;\nclass Config {\n constructor() {\n this.variables = {};\n this.variables[\"env\"] = 'prod';\n this.variables[\"debug\"] = false;\n }\n get(key) {\n return this.variables[key];\n }\n set(key, value) {\n this.variables[key] = value;\n }\n}\nexports.Config = Config;\n\n\n//# sourceURL=webpack://magicfeedback/./src/models/config.ts?");
73
-
74
- /***/ }),
75
-
76
- /***/ "./src/models/form.ts":
77
- /*!****************************!*\
78
- !*** ./src/models/form.ts ***!
79
- \****************************/
80
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
81
-
82
- "use strict";
83
- eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Form = void 0;\nconst log_1 = __webpack_require__(/*! ../utils/log */ \"./src/utils/log.ts\");\nconst request_service_1 = __webpack_require__(/*! ../services/request.service */ \"./src/services/request.service.ts\");\nconst questions_service_1 = __webpack_require__(/*! ../services/questions.service */ \"./src/services/questions.service.ts\");\nclass Form {\n /**\n *\n * @param config\n * @param appId\n * @param publicKey\n */\n constructor(config, appId, publicKey) {\n // SDK Config\n this.config = config;\n this.log = new log_1.Log(config);\n // Form options\n this.formOptionsConfig = {\n addButton: true,\n sendButtonText: \"Send\",\n backButtonText: \"Back\",\n nextButtonText: \"Next\",\n addSuccessScreen: true,\n getMetaData: true,\n questionFormat: \"standard\",\n };\n this.selector = \"\";\n // Attributes\n this.appId = appId;\n this.publicKey = publicKey;\n this.url = config.get(\"url\");\n // Form completed data\n this.id = \"\";\n this.formData = null;\n this.feedback = {\n text: \"\",\n answers: [],\n profile: [],\n metrics: [],\n metadata: [],\n };\n // Questions and history\n this.questions = [];\n this.elementQuestions = [];\n this.questionInProcess = null;\n this.history = {};\n // Count variables\n this.progress = 0;\n this.total = 0;\n }\n /**\n * Generate\n * TODO: Check if is inside of a <form>\n * @param selector\n * @param options\n */\n generate(selector, options) {\n return __awaiter(this, void 0, void 0, function* () {\n // Check options, and set default values if this is not defined\n try {\n // Set the options\n this.formOptionsConfig = Object.assign(Object.assign({}, this.formOptionsConfig), options);\n this.selector = selector;\n // Check if the form is in the localstorage and the time is less than 1 day\n const localForm = localStorage.getItem(`magicfeedback-${this.appId}`);\n if (localForm && new Date(JSON.parse(localForm).savedAt) < new Date(new Date().getTime() + 60 * 60 * 24 * 1000)) {\n this.formData = JSON.parse(localForm);\n (0, request_service_1.getForm)(this.url, this.appId, this.publicKey, this.log).then((form) => {\n var _a, _b;\n if ((form === null || form === void 0 ? void 0 : form.updatedAt) && ((_a = this.formData) === null || _a === void 0 ? void 0 : _a.savedAt) && (form === null || form === void 0 ? void 0 : form.updatedAt) > ((_b = this.formData) === null || _b === void 0 ? void 0 : _b.savedAt)) {\n console.log(\"Form updated\");\n this.formData = form;\n this.formData.savedAt = new Date();\n if (this.formData.questions) {\n this.questions = this.formData.questions;\n this.total = this.questions.length;\n }\n localStorage.setItem(`magicfeedback-${this.appId}`, JSON.stringify(this.formData));\n // Create the form from the JSON\n this.generateForm();\n }\n });\n }\n else {\n // Send the data to manage loadings and progress\n this.formData = yield (0, request_service_1.getForm)(this.url, this.appId, this.publicKey, this.log);\n }\n if (this.formData === undefined || !this.formData)\n throw new Error(`No form for app ${this.appId}`);\n if (!this.formData.savedAt) {\n // Save formData in the localstorage to use it in the future\n this.formData.savedAt = new Date();\n localStorage.setItem(`magicfeedback-${this.appId}`, JSON.stringify(this.formData));\n }\n this.questions = this.formData.questions;\n if (this.questions === undefined || !this.questions)\n throw new Error(`No questions for app ${this.appId}`);\n this.total = this.questions.length;\n // Send the data to manage loadings and progress\n if (this.formOptionsConfig.onLoadedEvent) {\n yield this.formOptionsConfig.onLoadedEvent({\n loading: false,\n progress: this.progress,\n total: this.total,\n formData: this.formData,\n });\n }\n if (this.formOptionsConfig.getMetaData)\n this.getMetaData();\n // Create the form from the JSON\n this.generateForm();\n }\n catch (e) {\n this.log.err(e);\n if (this.formOptionsConfig.onLoadedEvent) {\n yield this.formOptionsConfig.onLoadedEvent({\n loading: false,\n error: e,\n });\n }\n return;\n }\n });\n }\n /**\n * Create\n *\n * TODO: Add option to generate in <form> or in other <tag>\n */\n generateForm() {\n var _a, _b, _c;\n try {\n // Order questions by position\n this.questions.sort((a, b) => a.position - b.position);\n // Select and prepare the container\n const container = document.getElementById(this.selector);\n if (!container)\n throw new Error(`Element with ID '${this.selector}' not found.`);\n container.classList.add(\"magicfeedback-container\");\n container.id = \"magicfeedback-container-\" + this.appId;\n container.innerHTML = \"\";\n // Create the form\n const form = document.createElement(\"form\");\n form.classList.add(\"magicfeedback-form\");\n form.id = \"magicfeedback-\" + this.appId;\n // Create the questions container\n const questionContainer = document.createElement(\"div\");\n questionContainer.classList.add(\"magicfeedback-questions\");\n questionContainer.id = \"magicfeedback-questions-\" + this.appId;\n // Process questions and create in the form\n this.elementQuestions = (0, questions_service_1.renderQuestions)(this.questions, this.formOptionsConfig.questionFormat, (_a = this.formData) === null || _a === void 0 ? void 0 : _a.lang[0]);\n switch ((_b = this.formData) === null || _b === void 0 ? void 0 : _b.identity) {\n case 'MAGICSURVEY':\n this.elementQuestions.forEach((element, index) => this.history[index] = [{ object: this.questions[index], element }]);\n this.questionInProcess = this.history[0][0].object;\n questionContainer.appendChild(this.history[0][0].element);\n break;\n default:\n this.elementQuestions.forEach((element) => questionContainer.appendChild(element));\n break;\n }\n form.appendChild(questionContainer);\n // Add the form to the specified container\n container.appendChild(form);\n // Submit button\n if (this.formOptionsConfig.addButton) {\n // Create a container for the buttons\n const actionContainer = (0, questions_service_1.renderActions)((_c = this.formData) === null || _c === void 0 ? void 0 : _c.identity, () => this.back(), this.formOptionsConfig.sendButtonText, this.formOptionsConfig.backButtonText, this.formOptionsConfig.nextButtonText);\n form.appendChild(actionContainer);\n }\n // Submit event\n form.addEventListener(\"submit\", (event) => {\n event.preventDefault();\n this.send();\n });\n }\n catch (e) {\n this.log.err(e);\n if (this.formOptionsConfig.onLoadedEvent) {\n this.formOptionsConfig.onLoadedEvent({\n loading: false,\n error: e,\n });\n }\n return;\n }\n }\n /**\n * Get the metadata from the URL, navigators and others\n * @private\n */\n getMetaData() {\n // Add the navigator url and params from the URL to the metadata\n this.feedback.metadata.push({ key: \"navigator-url\", value: [window.location.href] });\n this.feedback.metadata.push({ key: \"navigator-origin\", value: [window.location.origin] });\n this.feedback.metadata.push({ key: \"navigator-pathname\", value: [window.location.pathname] });\n this.feedback.metadata.push({ key: \"navigator-search\", value: [window.location.search] });\n // Add the navigator metadata\n this.feedback.metadata.push({ key: \"navigator-user\", value: [navigator.userAgent] });\n this.feedback.metadata.push({ key: \"navigator-language\", value: [navigator.language] });\n this.feedback.metadata.push({ key: \"navigator-platform\", value: [navigator.platform] });\n this.feedback.metadata.push({ key: \"navigator-appVersion\", value: [navigator.appVersion] });\n this.feedback.metadata.push({ key: \"navigator-appName\", value: [navigator.appName] });\n this.feedback.metadata.push({ key: \"navigator-product\", value: [navigator.product] });\n // Add the size of the screen\n this.feedback.metadata.push({ key: \"screen-width\", value: [window.screen.width.toString()] });\n this.feedback.metadata.push({ key: \"screen-height\", value: [window.screen.height.toString()] });\n }\n /**\n * Send current answer and verify if its necessary continue with a new question\n * @pubilc\n * @param profile\n * @param metrics\n * @param metadata\n */\n send(metadata, metrics, profile) {\n var _a;\n return __awaiter(this, void 0, void 0, function* () {\n const container = document.getElementById(\"magicfeedback-container-\" + this.appId);\n const questionContainer = document.getElementById(\"magicfeedback-questions-\" + this.appId);\n try {\n if (profile)\n this.feedback.profile = [...this.feedback.profile, ...profile];\n if (metrics)\n this.feedback.metrics = [...this.feedback.metrics, ...metrics];\n if (metadata)\n this.feedback.metadata = [...this.feedback.metadata, ...metadata];\n // BEFORE\n if (this.formOptionsConfig.beforeSubmitEvent) {\n yield this.formOptionsConfig.beforeSubmitEvent({\n loading: true,\n progress: this.progress,\n total: this.total\n });\n }\n // SEND\n const response = yield this.pushAnswers(((_a = this.formData) === null || _a === void 0 ? void 0 : _a.identity) !== 'MAGICSURVEY');\n if (response) {\n this.id = response;\n yield this.processNextQuestion(container, questionContainer);\n }\n // AFTER\n if (this.formOptionsConfig.afterSubmitEvent) {\n yield this.formOptionsConfig.afterSubmitEvent({\n response,\n loading: false,\n progress: this.progress,\n total: this.total,\n error: response ? null : new Error(\"No response\")\n });\n }\n }\n catch (error) {\n // Handle error in beforeSubmitEvent, send(), or afterSubmitEvent\n this.log.err(`An error occurred while submitting the form ${this.appId}:`, error);\n if (this.formOptionsConfig.afterSubmitEvent) {\n yield this.formOptionsConfig.afterSubmitEvent({\n loading: false,\n progress: this.progress,\n total: this.total,\n error\n });\n }\n }\n });\n }\n /**\n * Update feedback.answers with the answers of the form in a JSON format\n * @returns\n * TODO: Required\n */\n answer() {\n const form = document.getElementById(\"magicfeedback-\" + this.appId);\n if (!form) {\n this.log.err(`Form \"${form}\" not found.`);\n this.feedback.answers = [];\n return;\n }\n const surveyAnswers = [];\n let hasError = false; // Flag to track if an error has occurred\n const inputs = form.querySelectorAll(\".magicfeedback-input\");\n inputs.forEach((input) => {\n const inputType = input.type;\n const elementTypeClass = input.classList[0];\n const ans = {\n key: input.name,\n value: [],\n };\n const value = elementTypeClass === 'magicfeedback-consent' ?\n input.checked.toString() :\n input.value;\n if (!ans.key || ans.key === \"\") {\n return;\n }\n else {\n switch (inputType) {\n case \"radio\":\n case \"checkbox\":\n if (elementTypeClass === \"magicfeedback-consent\" ||\n input.checked) {\n ans.value.push(value);\n // check if the answer is already in the array and merge the values\n const index = surveyAnswers.findIndex((a) => a.key === ans.key);\n if (index !== -1) {\n surveyAnswers[index].value = [\n ...surveyAnswers[index].value,\n ...ans.value,\n ];\n }\n else {\n surveyAnswers.push(ans);\n }\n }\n break;\n default:\n if (value !== \"\") {\n if (inputType === \"email\") {\n if (!(0, request_service_1.validateEmail)(value)) {\n this.log.err(\"Invalid email\");\n hasError = true;\n break;\n }\n else {\n this.feedback.profile.push({\n key: \"email\",\n value: [value],\n });\n }\n }\n ans.value.push(value);\n // check if the answer is already in the array and merge the values\n const index = surveyAnswers.findIndex((a) => a.key === ans.key);\n console.log(index, surveyAnswers);\n if (index !== -1) {\n surveyAnswers[index].value = [\n ...surveyAnswers[index].value,\n ...ans.value,\n ];\n }\n else {\n surveyAnswers.push(ans);\n }\n }\n }\n }\n });\n if (hasError) {\n this.feedback.answers = []; // Stop the process if there's an error\n return;\n }\n this.feedback.answers = surveyAnswers;\n }\n /**\n * Send\n * @param completed\n * @returns\n */\n pushAnswers(completed = false) {\n var _a, _b;\n return __awaiter(this, void 0, void 0, function* () {\n try {\n // Get the survey answers from the answer() function\n this.answer();\n if (((_a = this.formData) === null || _a === void 0 ? void 0 : _a.identity) === \"MAGICFORM\") {\n if (this.feedback.answers.length === 0)\n throw new Error(\"No answers provided\");\n this.questions.forEach((question) => {\n if (question.require && !this.feedback.answers.find((a) => a.key === question.ref)) {\n throw new Error(`No answer provided for question ${question.title}`);\n }\n });\n }\n else {\n if (!completed &&\n ((_b = this.questionInProcess) === null || _b === void 0 ? void 0 : _b.require) &&\n this.feedback.answers.length === 0)\n throw new Error(\"No answers provided\");\n }\n // Define the URL and request payload\n const url = this.config.get(\"url\");\n const body = {\n integration: this.appId,\n publicKey: this.publicKey,\n feedback: this.feedback,\n completed,\n };\n // Make the AJAX POST request\n return yield (0, request_service_1.sendFeedback)(url, this.id ? Object.assign(Object.assign({}, body), { sessionId: this.id }) : body, this.log);\n }\n catch (error) {\n // Handle network or request error\n this.log.err(`An error occurred while submitting the form ${this.appId}:`, error);\n // You can perform error handling logic here if needed\n return '';\n }\n });\n }\n /**\n * Call follow up question\n * @param question\n * @private\n */\n callFollowUpQuestion(question) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!(question === null || question === void 0 ? void 0 : question.followup))\n return null;\n try {\n if (this.feedback.answers.length === 0)\n throw new Error(\"No answers provided\");\n // Define the URL and request payload\n const url = this.config.get(\"url\");\n const body = {\n answer: this.feedback.answers[0].value[0],\n publicKey: this.publicKey,\n sessionId: this.id,\n question\n };\n return yield (0, request_service_1.getFollowUpQuestion)(url, body, this.log);\n }\n catch (error) {\n // Handle network or request error\n this.log.err(`An error occurred while submitting the form ${this.appId}:`, error);\n // You can perform error handling logic here if needed\n throw error;\n }\n });\n }\n /**\n * Process next question\n * @param container\n * @param form\n * @private\n */\n processNextQuestion(container, form) {\n var _a, _b, _c, _d;\n return __awaiter(this, void 0, void 0, function* () {\n switch ((_a = this.formData) === null || _a === void 0 ? void 0 : _a.identity) {\n case 'MAGICSURVEY':\n if (!((_b = this.questionInProcess) === null || _b === void 0 ? void 0 : _b.followup)) {\n this.renderNextQuestion(form, container);\n }\n else {\n const followUp = yield this.callFollowUpQuestion(this.questionInProcess);\n if (followUp) {\n // Update the question in process\n this.questionInProcess = followUp;\n // Add the follow up question to the history\n const question = (0, questions_service_1.renderQuestions)([followUp], (_c = this.formOptionsConfig) === null || _c === void 0 ? void 0 : _c.questionFormat, (_d = this.formData) === null || _d === void 0 ? void 0 : _d.lang[0])[0];\n this.history[this.progress].push({ object: followUp, element: question });\n form.removeChild(form.childNodes[0]);\n form.appendChild(question);\n }\n else {\n this.renderNextQuestion(form, container);\n }\n }\n break;\n default:\n this.total = this.questions.length;\n this.progress = this.questions.length;\n if (this.formOptionsConfig.addSuccessScreen) {\n // Remove the form\n if (container.childNodes.length > 0)\n container.removeChild(container.childNodes[0]);\n // Show the success message\n const successMessage = (0, questions_service_1.renderSuccess)(this.formOptionsConfig.successMessage ||\n \"Thank you for your feedback!\");\n container.appendChild(successMessage);\n }\n break;\n }\n });\n }\n /**\n * Render next question\n * @param form\n * @param container\n * @private\n */\n renderNextQuestion(form, container) {\n this.progress++;\n if (this.progress < this.total) {\n this.questionInProcess = this.history[this.progress][0].object;\n form.removeChild(form.childNodes[0]);\n form.appendChild(this.history[this.progress][0].element);\n }\n else {\n if (this.formOptionsConfig.addSuccessScreen) {\n // Remove the form\n if (container.childNodes.length > 0)\n container.removeChild(container.childNodes[0]);\n // Show the success message\n const successMessage = (0, questions_service_1.renderSuccess)(this.formOptionsConfig.successMessage ||\n \"Thank you for your feedback!\");\n container.appendChild(successMessage);\n }\n this.pushAnswers(true);\n }\n }\n /**\n * Render back question\n * @private\n */\n back() {\n if (this.progress === 0)\n return;\n const form = document.getElementById(\"magicfeedback-questions-\" + this.appId);\n form.removeChild(form.childNodes[0]);\n if (this.history[this.progress].length > 1) {\n // Delete the last question in the history array and load the previous one\n this.history[this.progress].pop();\n }\n else {\n // Use the previous question in the history array\n this.progress--;\n }\n // Get the last question in the history array\n const question = this.history[this.progress][this.history[this.progress].length - 1];\n // Update the question in process\n this.questionInProcess = question.object;\n form.appendChild(question.element);\n }\n}\nexports.Form = Form;\n\n\n//# sourceURL=webpack://magicfeedback/./src/models/form.ts?");
84
-
85
- /***/ }),
86
-
87
- /***/ "./src/services/paths.ts":
88
- /*!*******************************!*\
89
- !*** ./src/services/paths.ts ***!
90
- \*******************************/
91
- /***/ ((__unused_webpack_module, exports) => {
92
-
93
- "use strict";
94
- eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.endpoints = void 0;\nexports.endpoints = {\n sdk: {\n app: (appId, publicKey) => `sdk/app/${appId}/${publicKey}`,\n app_info: (appId, publicKey) => `sdk/app/${appId}/${publicKey}/info`,\n feedback: 'sdk/feedback',\n followUpQuestion: 'sdk/followUpQuestion',\n }\n};\n\n\n//# sourceURL=webpack://magicfeedback/./src/services/paths.ts?");
95
-
96
- /***/ }),
97
-
98
- /***/ "./src/services/questions.service.ts":
99
- /*!*******************************************!*\
100
- !*** ./src/services/questions.service.ts ***!
101
- \*******************************************/
102
- /***/ ((__unused_webpack_module, exports) => {
103
-
104
- "use strict";
105
- eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.renderSuccess = exports.renderError = exports.renderActions = exports.renderQuestions = void 0;\nfunction renderQuestions(appQuestions, format = \"standard\", language = \"en\") {\n if (!appQuestions)\n throw new Error(\"[MagicFeedback] No questions provided\");\n const questions = [];\n appQuestions.forEach((question) => {\n var _a, _b;\n if (((_b = (_a = question === null || question === void 0 ? void 0 : question.questionType) === null || _a === void 0 ? void 0 : _a.conf) === null || _b === void 0 ? void 0 : _b.length) > 0) {\n let elementContainer = document.createElement(\"div\");\n elementContainer.classList.add(\"magicfeedback-div\");\n question.questionType.conf.forEach((conf) => conf.ref = question.ref);\n const elements = renderQuestions(question.questionType.conf, format, language);\n elements.forEach((element) => {\n elementContainer.appendChild(element);\n });\n questions.push(elementContainer);\n }\n else {\n // Create a container for each question\n const elementContainer = renderContainer(question, format, language);\n questions.push(elementContainer);\n }\n });\n return questions;\n}\nexports.renderQuestions = renderQuestions;\nfunction parseTitle(title, lang) {\n return typeof title === \"object\" ? (title[lang] || title['en']) : title;\n}\n// Make a function to return a array with yes and no in every language\nfunction getBooleanOptions(lang) {\n switch (lang) {\n case \"es\":\n return ['Sí', 'No'];\n case \"fr\":\n return ['Oui', 'Non'];\n case \"de\":\n return ['Ja', 'Nein'];\n case \"it\":\n return ['Sì', 'No'];\n case \"pt\":\n return ['Sim', 'Não'];\n case \"nl\":\n return ['Ja', 'Nee'];\n case \"pl\":\n return ['Tak', 'Nie'];\n case \"ru\":\n return ['Да', 'Нет'];\n case \"ja\":\n return ['はい', 'いいえ'];\n case \"zh\":\n return ['是', '不'];\n case \"ko\":\n return ['예', '아니'];\n case 'da':\n return ['Ja', 'Nej'];\n case 'fi':\n return ['Kyllä', 'Ei'];\n case 'sv':\n return ['Ja', 'Nej'];\n case 'no':\n return ['Ja', 'Nei'];\n default:\n return ['Yes', 'No'];\n }\n}\nfunction renderContainer(question, format, language) {\n const { id, title, type, ref, require, \n //external_id,\n value, defaultValue, \n // questionType,\n assets } = question;\n let element;\n let elementTypeClass;\n let elementContainer = document.createElement(\"div\");\n elementContainer.classList.add(\"magicfeedback-div\");\n switch (type) {\n case \"TEXT\":\n // Create a text input field\n element = document.createElement(\"input\");\n element.type = \"text\";\n element.placeholder = format === 'slim' ? parseTitle(title, language) : \"Write your answer here...\";\n elementTypeClass = \"magicfeedback-text\";\n break;\n case \"LONGTEXT\":\n // Create a textarea element for TEXT and LONGTEXT types\n element = document.createElement(\"textarea\");\n element.rows = 3; // Set the number of rows based on the type\n element.placeholder = format === 'slim' ? parseTitle(title, language) : \"Write your answer here...\";\n elementTypeClass = \"magicfeedback-longtext\";\n break;\n case \"NUMBER\":\n // Create an input element with type \"number\" for NUMBER type\n element = document.createElement(\"input\");\n element.type = \"number\";\n element.placeholder = format === 'slim' ? parseTitle(title, language) : \"Insert a number here\";\n elementTypeClass = \"magicfeedback-number\";\n if (value.length) {\n value.sort((a, b) => Number(a) - Number(b));\n element.max = value[value.length - 1];\n element.min = value[0];\n element.value = value[0];\n }\n break;\n case \"RADIO\":\n case \"MULTIPLECHOICE\":\n element = document.createElement(\"div\");\n elementTypeClass =\n `magicfeedback-${(type === \"MULTIPLECHOICE\" ? \"checkbox\" : \"radio\")}`;\n value.forEach((option, index) => {\n const container = document.createElement(\"div\");\n container.classList.add(`magicfeedback-${type === \"MULTIPLECHOICE\" ? \"checkbox\" : \"radio\"}-container`);\n const label = document.createElement(\"label\");\n const input = document.createElement(\"input\");\n input.id = `rating-${ref}-${index}`;\n input.type = type === \"MULTIPLECHOICE\" ? \"checkbox\" : \"radio\";\n input.name = ref;\n input.value = option;\n input.classList.add(elementTypeClass);\n input.classList.add(\"magicfeedback-input\");\n if (option === defaultValue) {\n input.checked = true;\n }\n label.textContent = option;\n label.htmlFor = `rating-${ref}-${index}`;\n container.appendChild(input);\n container.appendChild(label);\n element.appendChild(container);\n });\n break;\n case \"BOOLEAN\":\n // Create an input element with type \"checkbox\" for BOOLEAN type with option yes or no\n element = document.createElement(\"div\");\n elementTypeClass = 'magicfeedback-radio';\n const booleanContainer = document.createElement('div');\n booleanContainer.classList.add('magicfeedback-boolean-container');\n booleanContainer.style.display = \"flex\";\n booleanContainer.style.flexDirection = \"row\";\n booleanContainer.style.justifyContent = \"space-between\";\n booleanContainer.style.width = \"70%\";\n booleanContainer.style.margin = \"auto\";\n const booleanOptions = assets.addIcon ? ['✓', '✗'] : getBooleanOptions(language);\n // Create a input button element for each value in the question's value array\n booleanOptions.forEach((option, index) => {\n const container = document.createElement(\"label\");\n container.classList.add(\"magicfeedback-boolean-option\");\n container.htmlFor = `rating-${ref}-${index}`;\n container.style.cursor = \"pointer\";\n container.style.border = \"1px solid #000\";\n container.style.display = \"flex\";\n container.style.justifyContent = \"center\";\n container.style.alignItems = \"center\";\n container.style.margin = \"auto\";\n container.style.padding = \"0\";\n container.style.width = \"45%\";\n container.style.height = \"38px\";\n const containerLabel = document.createElement('label');\n containerLabel.htmlFor = `rating-${ref}-${index}`;\n containerLabel.classList.add('magicfeedback-boolean-option-label-container');\n containerLabel.style.margin = \"0\";\n containerLabel.style.padding = \"0\";\n const label = document.createElement(\"label\");\n label.htmlFor = `rating-${ref}-${index}`;\n label.textContent = option;\n label.style.margin = \"0\";\n label.style.padding = \"0\";\n const input = document.createElement(\"input\");\n input.id = `rating-${ref}-${index}`;\n input.type = \"radio\";\n input.name = ref;\n input.value = option;\n input.classList.add(elementTypeClass);\n input.classList.add(\"magicfeedback-input\");\n input.style.position = \"absolute\";\n input.style.opacity = \"0\";\n input.style.width = \"0\";\n input.style.height = \"0\";\n input.style.margin = \"0\";\n containerLabel.appendChild(input);\n containerLabel.appendChild(label);\n container.appendChild(containerLabel);\n booleanContainer.appendChild(container);\n });\n element.appendChild(booleanContainer);\n break;\n case 'RATING_EMOJI':\n element = document.createElement(\"div\");\n elementTypeClass = 'magicfeedback-rating';\n const ratingContainer = document.createElement('div');\n ratingContainer.classList.add('magicfeedback-rating-container');\n const maxRating = value.length ? Number(value[value.length - 1]) : 5;\n const minRating = value.length ? Number(value[0]) : 1;\n for (let i = minRating; i <= maxRating; i++) {\n const ratingOption = document.createElement('div');\n ratingOption.classList.add('magicfeedback-rating-option');\n const containerLabel = document.createElement('label');\n containerLabel.htmlFor = `rating-${ref}-${i}`;\n containerLabel.classList.add('magicfeedback-rating-option-label-container');\n const ratingLabel = document.createElement('label');\n ratingLabel.htmlFor = `rating-${ref}-${i}`;\n ratingLabel.textContent = i.toString();\n const ratingImage = document.createElement('img');\n if (maxRating === 5) {\n switch (i) {\n case 1:\n ratingImage.src = \"https://magicfeedback-c6458-dev.web.app/assets/1.svg\";\n break;\n case 2:\n ratingImage.src = \"https://magicfeedback-c6458-dev.web.app/assets/2.svg\";\n break;\n case 3:\n ratingImage.src = \"https://magicfeedback-c6458-dev.web.app/assets/6.svg\";\n break;\n case 4:\n ratingImage.src = \"https://magicfeedback-c6458-dev.web.app/assets/9.svg\";\n break;\n case 5:\n ratingImage.src = \"https://magicfeedback-c6458-dev.web.app/assets/10.svg\";\n break;\n }\n }\n else {\n ratingImage.src = `https://magicfeedback-c6458-dev.web.app/assets/${i}.svg`;\n }\n ratingImage.alt = `face-${ref}-${i}`;\n // ratingImage is used to set the form value\n // ... add the code to set the value here\n ratingImage.className = `rating-image${i}`;\n const input = document.createElement(\"input\");\n input.id = `rating-${ref}-${i}`;\n input.type = \"radio\";\n input.name = ref;\n input.value = i.toString();\n input.classList.add(elementTypeClass);\n input.classList.add(\"magicfeedback-input\");\n containerLabel.appendChild(input);\n containerLabel.appendChild(ratingImage);\n containerLabel.appendChild(ratingLabel);\n ratingOption.appendChild(containerLabel);\n ratingContainer.appendChild(ratingOption);\n }\n element.appendChild(ratingContainer);\n break;\n case 'RATING_NUMBER':\n element = document.createElement(\"div\");\n elementTypeClass = 'magicfeedback-rating-number';\n const ratingNumberContainer = document.createElement('div');\n ratingNumberContainer.classList.add('magicfeedback-rating-number-container');\n const maxRatingNumber = value.length ? Number(value[value.length - 1]) : 5;\n const minRatingNumber = value.length ? Number(value[0]) : 1;\n for (let i = minRatingNumber; i <= maxRatingNumber; i++) {\n // Create a input button element for each value in the question's value array\n const ratingOption = document.createElement('div');\n ratingOption.classList.add('magicfeedback-rating-number-option');\n const containerLabel = document.createElement('label');\n containerLabel.htmlFor = `rating-${ref}-${i}`;\n containerLabel.classList.add('magicfeedback-rating-number-option-label-container');\n const ratingLabel = document.createElement('label');\n ratingLabel.htmlFor = `rating-${ref}-${i}`;\n ratingLabel.textContent = i.toString();\n const input = document.createElement(\"input\");\n input.id = `rating-${ref}-${i}`;\n input.type = \"radio\";\n input.name = ref;\n input.value = i.toString();\n input.classList.add(elementTypeClass);\n input.classList.add(\"magicfeedback-input\");\n containerLabel.appendChild(input);\n containerLabel.appendChild(ratingLabel);\n ratingOption.appendChild(containerLabel);\n ratingNumberContainer.appendChild(ratingOption);\n }\n element.appendChild(ratingNumberContainer);\n break;\n case 'RATING_STAR':\n element = document.createElement(\"div\");\n elementTypeClass = 'magicfeedback-rating-star';\n const ratingStarContainer = createStarRating(ref);\n element.appendChild(ratingStarContainer);\n break;\n case 'MULTIPLECHOISE_IMAGE':\n element = document.createElement(\"div\");\n elementTypeClass = 'magicfeedback-multiple-choice-image';\n // Display de items inside a flex container if only have one item display it as a single image in the center, if have 2 items display them as a row, if have more than 2 items display them as a grid, if have 4 items display them as a 2x2 grid and if have 6 items display them as a 3x2 grid\n const multipleChoiceImageContainer = document.createElement(\"div\");\n multipleChoiceImageContainer.classList.add(\"magicfeedback-multiple-choice-image-container\");\n multipleChoiceImageContainer.style.display = \"flex\";\n multipleChoiceImageContainer.style.flexDirection = \"row\";\n multipleChoiceImageContainer.style.flexWrap = \"wrap\";\n multipleChoiceImageContainer.style.justifyContent = \"center\";\n const maxItems = value.length;\n let itemsPerRow = 1;\n let itemsPerColumn = 1;\n if (maxItems === 2) {\n itemsPerRow = 2;\n }\n else if (maxItems === 4) {\n itemsPerRow = 2;\n itemsPerColumn = 2;\n }\n else if (maxItems === 6) {\n itemsPerRow = 3;\n itemsPerColumn = 2;\n }\n const useLabel = assets.addTitle === undefined ? false : assets.addTitle;\n // The image is the only input but can have a title\n value.forEach((option) => {\n try {\n const { position, url, value } = JSON.parse(option);\n const container = document.createElement(\"label\");\n container.classList.add(\"magicfeedback-multiple-choice-image-option\");\n container.style.width = `calc( ${100 / itemsPerRow}% - 10px)`;\n container.style.height = `calc( ${100 / itemsPerColumn}% - 10px)`;\n container.style.margin = \"5px\";\n const containerLabel = document.createElement('label');\n containerLabel.htmlFor = `rating-${ref}-${position}`;\n containerLabel.classList.add('magicfeedback-image-option-label-container');\n containerLabel.style.display = \"flex\";\n containerLabel.style.flexDirection = \"column\";\n // Add a effect on hover and on select\n containerLabel.addEventListener(\"mouseover\", () => {\n containerLabel.style.border = \"2px solid #000\";\n });\n containerLabel.addEventListener(\"mouseout\", () => {\n containerLabel.style.border = \"none\";\n });\n containerLabel.addEventListener(\"click\", () => {\n containerLabel.style.border = \"2px solid #000\";\n });\n const label = document.createElement(\"label\");\n label.textContent = value;\n label.classList.add(\"magicfeedback-multiple-choice-image-label\");\n const input = document.createElement(\"input\");\n input.id = `rating-${ref}-${position}`;\n input.type = \"radio\";\n input.name = ref;\n input.value = value;\n input.style.position = \"absolute\";\n input.style.opacity = \"0\";\n input.style.width = \"0\";\n input.style.height = \"0\";\n input.classList.add(\"magicfeedback-input\");\n // Add max size to the image\n const image = document.createElement(\"img\");\n image.classList.add(\"magicfeedback-multiple-choice-image-image\");\n image.src = url;\n image.style.cursor = \"pointer\";\n image.style.backgroundSize = \"cover\";\n image.style.width = \"100%\";\n image.style.height = \"100%\";\n image.style.margin = \"auto\";\n containerLabel.appendChild(input);\n containerLabel.appendChild(image);\n if (useLabel)\n containerLabel.appendChild(label);\n container.appendChild(containerLabel);\n multipleChoiceImageContainer.appendChild(container);\n }\n catch (e) {\n console.error(e);\n }\n });\n element.appendChild(multipleChoiceImageContainer);\n break;\n case \"SELECT\":\n // Create a select element for RADIO and MULTIPLECHOICE types\n element = document.createElement(\"select\");\n elementTypeClass = \"magicfeedback-select\";\n // Create an option <option value=\"\" disabled selected hidden>Please Choose...</option>\n const option = document.createElement(\"option\");\n option.value = \"\";\n option.text = format === 'slim' ? parseTitle(title, language) : (defaultValue || \"Select an option\");\n option.disabled = true;\n option.selected = true;\n element.appendChild(option);\n value.forEach((optionValue) => {\n // Create an option element for each value in the question's value array\n const option = document.createElement(\"option\");\n option.value = optionValue;\n option.text = optionValue;\n element.appendChild(option);\n });\n break;\n case \"DATE\":\n // Create an input element with type \"date\" for DATE type\n element = document.createElement(\"input\");\n element.type = \"date\";\n element.required = require;\n element.placeholder = format === 'slim' ? parseTitle(title, language) : \"Select a date\";\n elementTypeClass = \"magicfeedback-date\";\n break;\n case \"CONSENT\":\n // Create an input element with type \"checkbox\" for BOOLEAN type\n element = document.createElement(\"input\");\n elementTypeClass = \"magicfeedback-consent\";\n element.type = \"checkbox\";\n element.id = `magicfeedback-${id}`;\n element.name = ref;\n element.value = \"true\";\n element.required = require;\n element.classList.add(\"magicfeedback-consent\");\n element.classList.add(\"magicfeedback-input\");\n break;\n case \"EMAIL\":\n // Create an input element with type \"email\" for EMAIL type\n element = document.createElement(\"input\");\n element.type = \"email\";\n element.required = require;\n element.placeholder = format === 'slim' ? parseTitle(title, language) : \"you@example.com\";\n elementTypeClass = \"magicfeedback-email\";\n break;\n case \"PASSWORD\":\n // Create an input element with type \"password\" for PASSWORD type\n element = document.createElement(\"input\");\n element.type = \"password\";\n element.required = require;\n element.placeholder = format === 'slim' ? parseTitle(title, language) : \"Write your password here\";\n elementTypeClass = \"magicfeedback-password\";\n break;\n default:\n return elementContainer;\n }\n element.id = `magicfeedback-${id}`;\n element.setAttribute(\"name\", ref);\n element.classList.add(elementTypeClass);\n if (defaultValue !== undefined) {\n element.value = defaultValue;\n }\n if (![\"RADIO\", \"MULTIPLECHOICE\"].includes(type)) {\n element.classList.add(\"magicfeedback-input\");\n element.required = require;\n }\n // Add the label and input element to the form\n const label = document.createElement(\"label\");\n label.setAttribute(\"for\", `magicfeedback-${id}`);\n label.textContent = parseTitle(title, language);\n label.classList.add(\"magicfeedback-label\");\n if ([\"CONSENT\"].includes(type)) {\n elementContainer.classList.add(\"magicfeedback-consent-container\");\n elementContainer.appendChild(element);\n elementContainer.appendChild(label);\n }\n else {\n if (format !== 'slim') {\n elementContainer.appendChild(label);\n if ((assets === null || assets === void 0 ? void 0 : assets.general) !== undefined && (assets === null || assets === void 0 ? void 0 : assets.general) !== \"\") {\n // Add a image to the form\n const image = document.createElement(\"img\");\n image.src = assets.general;\n image.classList.add(\"magicfeedback-image\");\n // Add a max default width to the image\n image.style.maxWidth = \"auto\";\n image.style.height = \"400px\";\n image.style.margin = \"10px 0\";\n elementContainer.appendChild(image);\n }\n }\n elementContainer.appendChild(element);\n }\n return elementContainer;\n}\nfunction renderActions(identity = '', backAction, sendButtonText = \"Submit\", backButtonText = \"Back\", nextButtonText = \"Next\") {\n const actionContainer = document.createElement(\"div\");\n actionContainer.classList.add(\"magicfeedback-action-container\");\n // Create a submit button if specified in options\n const submitButton = document.createElement(\"button\");\n submitButton.id = \"magicfeedback-submit\";\n submitButton.type = \"submit\";\n submitButton.classList.add(\"magicfeedback-submit\");\n submitButton.textContent = identity === 'MAGICSURVEY' ? (nextButtonText || \"Next\") : (sendButtonText || \"Submit\");\n // Create a back button\n const backButton = document.createElement(\"button\");\n backButton.id = \"magicfeedback-back\";\n backButton.type = \"button\";\n backButton.classList.add(\"magicfeedback-back\");\n backButton.textContent = backButtonText || \"Back\";\n backButton.addEventListener(\"click\", backAction);\n if (identity === 'MAGICSURVEY') {\n actionContainer.appendChild(backButton);\n }\n actionContainer.appendChild(submitButton);\n return actionContainer;\n}\nexports.renderActions = renderActions;\nfunction createStarRating(ref) {\n const size = 40;\n const selectedClass = \"magicfeedback-rating-star-selected\";\n const starFilled = \"★\";\n const ratingContainer = document.createElement(\"div\");\n ratingContainer.classList.add(\"magicfeedback-rating-star-container\");\n for (let i = 1; i <= 5; i++) {\n const ratingOption = document.createElement(\"label\");\n ratingOption.classList.add(\"magicfeedback-rating-star-option\");\n // Create hidden radio input\n const ratingInput = document.createElement(\"input\");\n ratingInput.id = `rating-${ref}-${i}`;\n ratingInput.type = \"radio\";\n ratingInput.name = ref;\n ratingInput.value = i.toString();\n ratingInput.style.position = \"absolute\";\n ratingInput.style.opacity = \"0\";\n ratingInput.style.width = \"0\";\n ratingInput.style.height = \"0\";\n ratingInput.classList.add(\"magicfeedback-input\");\n // Update filled stars on radio input change\n ratingInput.addEventListener(\"change\", () => {\n const allStars = ratingContainer.querySelectorAll(\".rating__star\");\n for (let j = 0; j < allStars.length; j++) {\n // String to number\n if (j + 1 <= Number(ratingInput.value)) {\n if (!allStars[j].classList.contains(selectedClass))\n allStars[j].classList.add(selectedClass);\n }\n else {\n if (allStars[j].classList.contains(selectedClass))\n allStars[j].classList.remove(selectedClass);\n }\n }\n });\n ratingOption.appendChild(ratingInput);\n // Create star element (after for better positioning)\n const starElement = document.createElement(\"label\");\n starElement.htmlFor = `rating-${ref}-${i}`;\n starElement.classList.add(\"rating__star\");\n starElement.textContent = starFilled;\n starElement.style.fontSize = `${size}px`; // Set star size\n starElement.style.color = \"#CCCCCC\"; // Set star color\n starElement.style.cursor = \"pointer\";\n // Add hover effect\n ratingOption.appendChild(starElement);\n ratingContainer.appendChild(ratingOption);\n }\n return ratingContainer;\n}\nfunction renderError(error) {\n const errorElement = document.createElement(\"div\");\n errorElement.classList.add(\"magicfeedback-error\");\n errorElement.textContent = error;\n return errorElement;\n}\nexports.renderError = renderError;\nfunction renderSuccess(success) {\n const successElement = document.createElement(\"div\");\n successElement.classList.add(\"magicfeedback-success\");\n successElement.textContent = success;\n return successElement;\n}\nexports.renderSuccess = renderSuccess;\n\n\n//# sourceURL=webpack://magicfeedback/./src/services/questions.service.ts?");
106
-
107
- /***/ }),
108
-
109
- /***/ "./src/services/request.service.ts":
110
- /*!*****************************************!*\
111
- !*** ./src/services/request.service.ts ***!
112
- \*****************************************/
113
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
114
-
115
- "use strict";
116
- eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.getFollowUpQuestion = exports.sendFeedback = exports.getQuestions = exports.getForm = exports.validateEmail = void 0;\nconst cross_fetch_1 = __importDefault(__webpack_require__(/*! cross-fetch */ \"./node_modules/cross-fetch/dist/browser-ponyfill.js\"));\nconst package_json_1 = __importDefault(__webpack_require__(/*! ../../package.json */ \"./package.json\"));\nconst paths_1 = __webpack_require__(/*! ./paths */ \"./src/services/paths.ts\");\nconst header = {\n Accept: \"application/json\",\n \"Magicfeedback-Sdk-Version\": package_json_1.default.version,\n};\n// @ts-ignore\nconst serializedParams = (params) => Object.entries(params).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`).join(\"&\");\nfunction validateEmail(email) {\n const re = /\\S+@\\S+\\.\\S+/;\n return re.test(email);\n}\nexports.validateEmail = validateEmail;\nfunction getForm(url, appId, publicKey, log) {\n return __awaiter(this, void 0, void 0, function* () {\n try {\n const response = yield (0, cross_fetch_1.default)(url + paths_1.endpoints.sdk.app_info(appId, publicKey), {\n method: \"GET\",\n headers: header\n });\n if (response.ok) {\n // Handle success response\n const json = yield response.json();\n log.log(`Received form for app ${appId}`, json);\n return json;\n }\n else {\n // Handle error response\n log.err(`Failed to get questions for app ${appId}:`, response.status, response.statusText);\n throw new Error(\"[MagicFeedback] Bad response from server\");\n }\n }\n catch (e) {\n log.err(e);\n return null;\n }\n });\n}\nexports.getForm = getForm;\nfunction getQuestions(url, appId, publicKey, log) {\n return __awaiter(this, void 0, void 0, function* () {\n try {\n const response = yield (0, cross_fetch_1.default)(url + paths_1.endpoints.sdk.app(appId, publicKey), {\n method: \"GET\",\n headers: header\n });\n if (response.ok) {\n // Handle success response\n const json = yield response.json();\n log.log(`Received questions for app ${appId}`, json);\n return json;\n }\n else {\n // Handle error response\n log.err(`Failed to get questions for app ${appId}:`, response.status, response.statusText);\n throw new Error(\"[MagicFeedback] Bad response from server\");\n }\n }\n catch (e) {\n log.err(e);\n return [];\n }\n });\n}\nexports.getQuestions = getQuestions;\nfunction sendFeedback(url, body, log) {\n return __awaiter(this, void 0, void 0, function* () {\n try {\n const response = yield (0, cross_fetch_1.default)(url + paths_1.endpoints.sdk.feedback, {\n method: \"POST\",\n headers: Object.assign({ \"Content-Type\": \"application/json\" }, header),\n body: JSON.stringify(body),\n });\n if (response.ok) {\n // Handle success response\n log.log(`Form ${body.integration} submitted successfully!`);\n // You can perform additional actions here if needed\n const responseJson = yield response.json();\n return responseJson.sessionId;\n }\n else {\n // Handle error response\n log.err(`Failed to submit form ${body.integration}:`, response.status, response.statusText);\n throw new Error(response.statusText);\n }\n }\n catch (e) {\n log.err(e);\n return '';\n }\n });\n}\nexports.sendFeedback = sendFeedback;\nfunction getFollowUpQuestion(url, body, log) {\n return __awaiter(this, void 0, void 0, function* () {\n try {\n const response = yield (0, cross_fetch_1.default)(url + paths_1.endpoints.sdk.followUpQuestion, {\n method: \"POST\",\n headers: Object.assign({ \"Content-Type\": \"application/json\" }, header),\n body: JSON.stringify(body),\n });\n if (response.ok) {\n // Handle success response\n log.log(`Received follow up question for form ${body.integration}`);\n // You can perform additional actions here if needed\n const responseJson = yield response.json();\n return responseJson || '';\n }\n else {\n // Handle error response\n log.err(`Failed to get follow up question for form ${body.integration}:`, response.status, response.statusText);\n throw new Error(response.statusText);\n }\n }\n catch (e) {\n log.err(e);\n return '';\n }\n });\n}\nexports.getFollowUpQuestion = getFollowUpQuestion;\n\n\n//# sourceURL=webpack://magicfeedback/./src/services/request.service.ts?");
117
-
118
- /***/ }),
119
-
120
- /***/ "./src/utils/log.ts":
121
- /*!**************************!*\
122
- !*** ./src/utils/log.ts ***!
123
- \**************************/
124
- /***/ ((__unused_webpack_module, exports) => {
125
-
126
- "use strict";
127
- eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Log = void 0;\nclass Log {\n /**\n *\n * @param config\n */\n constructor(config) {\n // Config\n this.config = config;\n }\n /**\n *\n * @param args\n */\n log(...args) {\n if (this.config.get(\"debug\")) {\n console.log(\"[MagicFeedback]:\", ...args);\n }\n }\n /**\n *\n * @param args\n */\n err(...args) {\n console.error(\"[MagicFeedback]:\", ...args);\n }\n}\nexports.Log = Log;\n\n\n//# sourceURL=webpack://magicfeedback/./src/utils/log.ts?");
128
-
129
- /***/ }),
130
-
131
- /***/ "./package.json":
132
- /*!**********************!*\
133
- !*** ./package.json ***!
134
- \**********************/
135
- /***/ ((module) => {
136
-
137
- "use strict";
138
- eval("module.exports = JSON.parse('{\"name\":\"@magicfeedback/native\",\"version\":\"1.1.16-beta.1\",\"main\":\"./dist/magicfeedback-sdk.node.js\",\"browser\":\"./dist/magicfeedback-sdk.browser.js\",\"types\":\"./dist/types/src/index.d.ts\",\"repository\":{\"type\":\"git\",\"url\":\"git+ssh://git@github.com/MagicFeedback/magicfeedback-sdk.git\"},\"author\":\"farias@magicfeedback.io\",\"license\":\"MIT\",\"private\":false,\"scripts\":{\"dev\":\"vite\",\"build\":\"webpack\",\"build:watch\":\"webpack --watch --mode development\",\"publish\":\"npm publish --access public\",\"publish:beta\":\"npm publish --access public --tag beta\",\"test\":\"jest\",\"test:watch\":\"jest --watchAll\",\"coverage\":\"vitest run --coverage\"},\"files\":[\"dist\"],\"devDependencies\":{\"@babel/preset-typescript\":\"^7.22.5\",\"@types/node\":\"^17.0.21\",\"@types/webpack\":\"^5.28.0\",\"@types/webpack-node-externals\":\"^2.5.3\",\"c8\":\"^7.11.0\",\"jest\":\"^29.5.0\",\"jest-environment-jsdom\":\"^29.5.0\",\"jest-fetch-mock\":\"^3.0.3\",\"nock\":\"^13.2.4\",\"ts-jest\":\"^29.1.0\",\"ts-loader\":\"^9.2.7\",\"ts-node\":\"^10.7.0\",\"typescript\":\"^4.6.2\",\"vite\":\"^2.8.0\",\"vite-plugin-dts\":\"^0.9.9\",\"vitest\":\"^0.5.9\",\"webpack\":\"^5.70.0\",\"webpack-cli\":\"^4.9.2\",\"webpack-node-externals\":\"^3.0.0\"},\"dependencies\":{\"cross-fetch\":\"^3.1.5\",\"is-bundling-for-browser-or-node\":\"^1.1.1\"},\"description\":\"MagicFeedbackAI JavaScript Library for [MagicFeedback.io](https://magicfeedback.io/)\",\"bugs\":{\"url\":\"https://github.com/MagicFeedback/magicfeedback-sdk/issues\"},\"homepage\":\"https://github.com/MagicFeedback/magicfeedback-sdk#readme\",\"directories\":{\"example\":\"examples\",\"test\":\"test\"}}');\n\n//# sourceURL=webpack://magicfeedback/./package.json?");
139
-
140
- /***/ })
141
-
142
- /******/ });
143
- /************************************************************************/
144
- /******/ // The module cache
145
- /******/ var __webpack_module_cache__ = {};
146
- /******/
147
- /******/ // The require function
148
- /******/ function __webpack_require__(moduleId) {
149
- /******/ // Check if module is in cache
150
- /******/ var cachedModule = __webpack_module_cache__[moduleId];
151
- /******/ if (cachedModule !== undefined) {
152
- /******/ return cachedModule.exports;
153
- /******/ }
154
- /******/ // Create a new module (and put it into the cache)
155
- /******/ var module = __webpack_module_cache__[moduleId] = {
156
- /******/ // no module.id needed
157
- /******/ // no module.loaded needed
158
- /******/ exports: {}
159
- /******/ };
160
- /******/
161
- /******/ // Execute the module function
162
- /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
163
- /******/
164
- /******/ // Return the exports of the module
165
- /******/ return module.exports;
166
- /******/ }
167
- /******/
168
- /************************************************************************/
169
- /******/
170
- /******/ // startup
171
- /******/ // Load entry module and return exports
172
- /******/ // This entry module is referenced by other modules so it can't be inlined
173
- /******/ var __webpack_exports__ = __webpack_require__("./src/index.ts");
174
- /******/ __webpack_exports__ = __webpack_exports__["default"];
175
- /******/
176
- /******/ return __webpack_exports__;
177
- /******/ })()
178
- ;
179
- });
1
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.magicfeedback=t():e.magicfeedback=t()}(self,(()=>{return e={98:function(e,t){var i="undefined"!=typeof self?self:this,s=function(){function e(){this.fetch=!1,this.DOMException=i.DOMException}return e.prototype=i,new e}();!function(e){!function(t){var i="URLSearchParams"in e,s="Symbol"in e&&"iterator"in Symbol,n="FileReader"in e&&"Blob"in e&&function(){try{return new Blob,!0}catch(e){return!1}}(),o="FormData"in e,a="ArrayBuffer"in e;if(a)var r=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]"],c=ArrayBuffer.isView||function(e){return e&&r.indexOf(Object.prototype.toString.call(e))>-1};function d(e){if("string"!=typeof e&&(e=String(e)),/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(e))throw new TypeError("Invalid character in header field name");return e.toLowerCase()}function l(e){return"string"!=typeof e&&(e=String(e)),e}function u(e){var t={next:function(){var t=e.shift();return{done:void 0===t,value:t}}};return s&&(t[Symbol.iterator]=function(){return t}),t}function h(e){this.map={},e instanceof h?e.forEach((function(e,t){this.append(t,e)}),this):Array.isArray(e)?e.forEach((function(e){this.append(e[0],e[1])}),this):e&&Object.getOwnPropertyNames(e).forEach((function(t){this.append(t,e[t])}),this)}function p(e){if(e.bodyUsed)return Promise.reject(new TypeError("Already read"));e.bodyUsed=!0}function f(e){return new Promise((function(t,i){e.onload=function(){t(e.result)},e.onerror=function(){i(e.error)}}))}function m(e){var t=new FileReader,i=f(t);return t.readAsArrayBuffer(e),i}function g(e){if(e.slice)return e.slice(0);var t=new Uint8Array(e.byteLength);return t.set(new Uint8Array(e)),t.buffer}function b(){return this.bodyUsed=!1,this._initBody=function(e){var t;this._bodyInit=e,e?"string"==typeof e?this._bodyText=e:n&&Blob.prototype.isPrototypeOf(e)?this._bodyBlob=e:o&&FormData.prototype.isPrototypeOf(e)?this._bodyFormData=e:i&&URLSearchParams.prototype.isPrototypeOf(e)?this._bodyText=e.toString():a&&n&&(t=e)&&DataView.prototype.isPrototypeOf(t)?(this._bodyArrayBuffer=g(e.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer])):a&&(ArrayBuffer.prototype.isPrototypeOf(e)||c(e))?this._bodyArrayBuffer=g(e):this._bodyText=e=Object.prototype.toString.call(e):this._bodyText="",this.headers.get("content-type")||("string"==typeof e?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):i&&URLSearchParams.prototype.isPrototypeOf(e)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},n&&(this.blob=function(){var e=p(this);if(e)return e;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))},this.arrayBuffer=function(){return this._bodyArrayBuffer?p(this)||Promise.resolve(this._bodyArrayBuffer):this.blob().then(m)}),this.text=function(){var e,t,i,s=p(this);if(s)return s;if(this._bodyBlob)return e=this._bodyBlob,i=f(t=new FileReader),t.readAsText(e),i;if(this._bodyArrayBuffer)return Promise.resolve(function(e){for(var t=new Uint8Array(e),i=new Array(t.length),s=0;s<t.length;s++)i[s]=String.fromCharCode(t[s]);return i.join("")}(this._bodyArrayBuffer));if(this._bodyFormData)throw new Error("could not read FormData body as text");return Promise.resolve(this._bodyText)},o&&(this.formData=function(){return this.text().then(k)}),this.json=function(){return this.text().then(JSON.parse)},this}h.prototype.append=function(e,t){e=d(e),t=l(t);var i=this.map[e];this.map[e]=i?i+", "+t:t},h.prototype.delete=function(e){delete this.map[d(e)]},h.prototype.get=function(e){return e=d(e),this.has(e)?this.map[e]:null},h.prototype.has=function(e){return this.map.hasOwnProperty(d(e))},h.prototype.set=function(e,t){this.map[d(e)]=l(t)},h.prototype.forEach=function(e,t){for(var i in this.map)this.map.hasOwnProperty(i)&&e.call(t,this.map[i],i,this)},h.prototype.keys=function(){var e=[];return this.forEach((function(t,i){e.push(i)})),u(e)},h.prototype.values=function(){var e=[];return this.forEach((function(t){e.push(t)})),u(e)},h.prototype.entries=function(){var e=[];return this.forEach((function(t,i){e.push([i,t])})),u(e)},s&&(h.prototype[Symbol.iterator]=h.prototype.entries);var y=["DELETE","GET","HEAD","OPTIONS","POST","PUT"];function v(e,t){var i,s,n=(t=t||{}).body;if(e instanceof v){if(e.bodyUsed)throw new TypeError("Already read");this.url=e.url,this.credentials=e.credentials,t.headers||(this.headers=new h(e.headers)),this.method=e.method,this.mode=e.mode,this.signal=e.signal,n||null==e._bodyInit||(n=e._bodyInit,e.bodyUsed=!0)}else this.url=String(e);if(this.credentials=t.credentials||this.credentials||"same-origin",!t.headers&&this.headers||(this.headers=new h(t.headers)),this.method=(s=(i=t.method||this.method||"GET").toUpperCase(),y.indexOf(s)>-1?s:i),this.mode=t.mode||this.mode||null,this.signal=t.signal||this.signal,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&n)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(n)}function k(e){var t=new FormData;return e.trim().split("&").forEach((function(e){if(e){var i=e.split("="),s=i.shift().replace(/\+/g," "),n=i.join("=").replace(/\+/g," ");t.append(decodeURIComponent(s),decodeURIComponent(n))}})),t}function w(e,t){t||(t={}),this.type="default",this.status=void 0===t.status?200:t.status,this.ok=this.status>=200&&this.status<300,this.statusText="statusText"in t?t.statusText:"OK",this.headers=new h(t.headers),this.url=t.url||"",this._initBody(e)}v.prototype.clone=function(){return new v(this,{body:this._bodyInit})},b.call(v.prototype),b.call(w.prototype),w.prototype.clone=function(){return new w(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new h(this.headers),url:this.url})},w.error=function(){var e=new w(null,{status:0,statusText:""});return e.type="error",e};var E=[301,302,303,307,308];w.redirect=function(e,t){if(-1===E.indexOf(t))throw new RangeError("Invalid status code");return new w(null,{status:t,headers:{location:e}})},t.DOMException=e.DOMException;try{new t.DOMException}catch(e){t.DOMException=function(e,t){this.message=e,this.name=t;var i=Error(e);this.stack=i.stack},t.DOMException.prototype=Object.create(Error.prototype),t.DOMException.prototype.constructor=t.DOMException}function C(e,i){return new Promise((function(s,o){var a=new v(e,i);if(a.signal&&a.signal.aborted)return o(new t.DOMException("Aborted","AbortError"));var r=new XMLHttpRequest;function c(){r.abort()}r.onload=function(){var e,t,i={status:r.status,statusText:r.statusText,headers:(e=r.getAllResponseHeaders()||"",t=new h,e.replace(/\r?\n[\t ]+/g," ").split(/\r?\n/).forEach((function(e){var i=e.split(":"),s=i.shift().trim();if(s){var n=i.join(":").trim();t.append(s,n)}})),t)};i.url="responseURL"in r?r.responseURL:i.headers.get("X-Request-URL");var n="response"in r?r.response:r.responseText;s(new w(n,i))},r.onerror=function(){o(new TypeError("Network request failed"))},r.ontimeout=function(){o(new TypeError("Network request failed"))},r.onabort=function(){o(new t.DOMException("Aborted","AbortError"))},r.open(a.method,a.url,!0),"include"===a.credentials?r.withCredentials=!0:"omit"===a.credentials&&(r.withCredentials=!1),"responseType"in r&&n&&(r.responseType="blob"),a.headers.forEach((function(e,t){r.setRequestHeader(t,e)})),a.signal&&(a.signal.addEventListener("abort",c),r.onreadystatechange=function(){4===r.readyState&&a.signal.removeEventListener("abort",c)}),r.send(void 0===a._bodyInit?null:a._bodyInit)}))}C.polyfill=!0,e.fetch||(e.fetch=C,e.Headers=h,e.Request=v,e.Response=w),t.Headers=h,t.Request=v,t.Response=w,t.fetch=C,Object.defineProperty(t,"__esModule",{value:!0})}({})}(s),s.fetch.ponyfill=!0,delete s.fetch.polyfill;var n=s;(t=n.fetch).default=n.fetch,t.fetch=n.fetch,t.Headers=n.Headers,t.Request=n.Request,t.Response=n.Response,e.exports=t},290:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.HOST_API_URL_DEV=t.HOST_API_URL=void 0,t.HOST_API_URL="https://api.magicfeedback.io/",t.HOST_API_URL_DEV="https://api-dev.magicfeedback.io/"},607:function(e,t,i){"use strict";var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const n=s(i(519));let o=null;o||(o=(0,n.default)()),t.default=o},519:function(e,t,i){"use strict";var s=this&&this.__awaiter||function(e,t,i,s){return new(i||(i=Promise))((function(n,o){function a(e){try{c(s.next(e))}catch(e){o(e)}}function r(e){try{c(s.throw(e))}catch(e){o(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(a,r)}c((s=s.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0});const n=i(954),o=i(712),a=i(5),r=i(341),c=i(290);t.default=function(){const e=new o.Config;let t;return{init:function(i){(null==i?void 0:i.debug)&&e.set("debug",null==i?void 0:i.debug),e.set("url",(null==i?void 0:i.env)&&"dev"===(null==i?void 0:i.env)?c.HOST_API_URL_DEV:c.HOST_API_URL),t=new a.Log(e),t.log("Initialized Magicfeedback",e)},send:function(i,n,o,a=!0,c,d){return s(this,void 0,void 0,(function*(){i||t.err("No appID provided"),n||t.err("No publicKey provided"),o||t.err("No feedback provided"),o.answers||o.profile||o.metrics||o.metadata||t.err("No feedback data provided");const s=e.get("url"),l={integration:i,publicKey:n,privateKey:d,completed:a,id:c,feedback:o};try{const e=yield(0,r.sendFeedback)(s,l,t);return t.log("sent native feedback"),e}catch(e){return t.err("error native feedback",e),!1}}))},form:function(i,s){return i||t.err("No appID provided"),s||t.err("No publicKey provided"),new n.Form(e,i,s)}}}},712:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Config=void 0,t.Config=class{constructor(){this.variables={},this.variables.env="prod",this.variables.debug=!1}get(e){return this.variables[e]}set(e,t){this.variables[e]=t}}},954:function(e,t,i){"use strict";var s=this&&this.__awaiter||function(e,t,i,s){return new(i||(i=Promise))((function(n,o){function a(e){try{c(s.next(e))}catch(e){o(e)}}function r(e){try{c(s.throw(e))}catch(e){o(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(a,r)}c((s=s.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0}),t.Form=void 0;const n=i(5),o=i(341),a=i(183);t.Form=class{constructor(e,t,i){this.config=e,this.log=new n.Log(e),this.formOptionsConfig={addButton:!0,sendButtonText:"Send",backButtonText:"Back",nextButtonText:"Next",addSuccessScreen:!0,getMetaData:!0,questionFormat:"standard"},this.selector="",this.appId=t,this.publicKey=i,this.url=e.get("url"),this.id="",this.formData=null,this.feedback={text:"",answers:[],profile:[],metrics:[],metadata:[]},this.questions=[],this.elementQuestions=[],this.questionInProcess=null,this.history={},this.progress=0,this.total=0}generate(e,t){return s(this,void 0,void 0,(function*(){try{this.formOptionsConfig=Object.assign(Object.assign({},this.formOptionsConfig),t),this.selector=e;const i=localStorage.getItem(`magicfeedback-${this.appId}`);if(i&&new Date(JSON.parse(i).savedAt)<new Date((new Date).getTime()+864e5)?(this.formData=JSON.parse(i),(0,o.getForm)(this.url,this.appId,this.publicKey,this.log).then((e=>{var t,i;(null==e?void 0:e.updatedAt)&&(null===(t=this.formData)||void 0===t?void 0:t.savedAt)&&(null==e?void 0:e.updatedAt)>(null===(i=this.formData)||void 0===i?void 0:i.savedAt)&&(console.log("Form updated"),this.formData=e,this.formData.savedAt=new Date,this.formData.questions&&(this.questions=this.formData.questions,this.total=this.questions.length),localStorage.setItem(`magicfeedback-${this.appId}`,JSON.stringify(this.formData)),this.generateForm())}))):this.formData=yield(0,o.getForm)(this.url,this.appId,this.publicKey,this.log),void 0===this.formData||!this.formData)throw new Error(`No form for app ${this.appId}`);if(this.formData.savedAt||(this.formData.savedAt=new Date,localStorage.setItem(`magicfeedback-${this.appId}`,JSON.stringify(this.formData))),this.questions=this.formData.questions,void 0===this.questions||!this.questions)throw new Error(`No questions for app ${this.appId}`);this.total=this.questions.length,this.formOptionsConfig.onLoadedEvent&&(yield this.formOptionsConfig.onLoadedEvent({loading:!1,progress:this.progress,total:this.total,formData:this.formData})),this.formOptionsConfig.getMetaData&&this.getMetaData(),this.generateForm()}catch(e){return this.log.err(e),void(this.formOptionsConfig.onLoadedEvent&&(yield this.formOptionsConfig.onLoadedEvent({loading:!1,error:e})))}}))}generateForm(){var e,t,i;try{this.questions.sort(((e,t)=>e.position-t.position));const s=document.getElementById(this.selector);if(!s)throw new Error(`Element with ID '${this.selector}' not found.`);s.classList.add("magicfeedback-container"),s.id="magicfeedback-container-"+this.appId,s.innerHTML="";const n=document.createElement("form");n.classList.add("magicfeedback-form"),n.id="magicfeedback-"+this.appId;const o=document.createElement("div");if(o.classList.add("magicfeedback-questions"),o.id="magicfeedback-questions-"+this.appId,this.elementQuestions=(0,a.renderQuestions)(this.questions,this.formOptionsConfig.questionFormat,null===(e=this.formData)||void 0===e?void 0:e.lang[0]),"MAGICSURVEY"===(null===(t=this.formData)||void 0===t?void 0:t.identity)?(this.elementQuestions.forEach(((e,t)=>this.history[t]=[{object:this.questions[t],element:e}])),this.questionInProcess=this.history[0][0].object,o.appendChild(this.history[0][0].element)):this.elementQuestions.forEach((e=>o.appendChild(e))),n.appendChild(o),s.appendChild(n),this.formOptionsConfig.addButton){const e=(0,a.renderActions)(null===(i=this.formData)||void 0===i?void 0:i.identity,(()=>this.back()),this.formOptionsConfig.sendButtonText,this.formOptionsConfig.backButtonText,this.formOptionsConfig.nextButtonText);n.appendChild(e)}n.addEventListener("submit",(e=>{e.preventDefault(),this.send()}))}catch(e){return this.log.err(e),void(this.formOptionsConfig.onLoadedEvent&&this.formOptionsConfig.onLoadedEvent({loading:!1,error:e}))}}getMetaData(){this.feedback.metadata.push({key:"navigator-url",value:[window.location.href]}),this.feedback.metadata.push({key:"navigator-origin",value:[window.location.origin]}),this.feedback.metadata.push({key:"navigator-pathname",value:[window.location.pathname]}),this.feedback.metadata.push({key:"navigator-search",value:[window.location.search]}),this.feedback.metadata.push({key:"navigator-user",value:[navigator.userAgent]}),this.feedback.metadata.push({key:"navigator-language",value:[navigator.language]}),this.feedback.metadata.push({key:"navigator-platform",value:[navigator.platform]}),this.feedback.metadata.push({key:"navigator-appVersion",value:[navigator.appVersion]}),this.feedback.metadata.push({key:"navigator-appName",value:[navigator.appName]}),this.feedback.metadata.push({key:"navigator-product",value:[navigator.product]}),this.feedback.metadata.push({key:"screen-width",value:[window.screen.width.toString()]}),this.feedback.metadata.push({key:"screen-height",value:[window.screen.height.toString()]})}send(e,t,i){var n;return s(this,void 0,void 0,(function*(){const s=document.getElementById("magicfeedback-container-"+this.appId),o=document.getElementById("magicfeedback-questions-"+this.appId);try{i&&(this.feedback.profile=[...this.feedback.profile,...i]),t&&(this.feedback.metrics=[...this.feedback.metrics,...t]),e&&(this.feedback.metadata=[...this.feedback.metadata,...e]),this.formOptionsConfig.beforeSubmitEvent&&(yield this.formOptionsConfig.beforeSubmitEvent({loading:!0,progress:this.progress,total:this.total}));const a=yield this.pushAnswers("MAGICSURVEY"!==(null===(n=this.formData)||void 0===n?void 0:n.identity));a&&(this.id=a,yield this.processNextQuestion(s,o)),this.formOptionsConfig.afterSubmitEvent&&(yield this.formOptionsConfig.afterSubmitEvent({response:a,loading:!1,progress:this.progress,total:this.total,error:a?null:new Error("No response")}))}catch(e){this.log.err(`An error occurred while submitting the form ${this.appId}:`,e),this.formOptionsConfig.afterSubmitEvent&&(yield this.formOptionsConfig.afterSubmitEvent({loading:!1,progress:this.progress,total:this.total,error:e}))}}))}answer(){const e=document.getElementById("magicfeedback-"+this.appId);if(!e)return this.log.err(`Form "${e}" not found.`),void(this.feedback.answers=[]);const t=[];let i=!1;e.querySelectorAll(".magicfeedback-input").forEach((e=>{const s=e.type,n=e.classList[0],a={key:e.name,value:[]},r="magicfeedback-consent"===n?e.checked.toString():e.value;if(a.key&&""!==a.key)switch(s){case"radio":case"checkbox":if("magicfeedback-consent"===n||e.checked){a.value.push(r);const e=t.findIndex((e=>e.key===a.key));-1!==e?t[e].value=[...t[e].value,...a.value]:t.push(a)}break;default:if(""!==r){if("email"===s){if(!(0,o.validateEmail)(r)){this.log.err("Invalid email"),i=!0;break}this.feedback.profile.push({key:"email",value:[r]})}a.value.push(r);const e=t.findIndex((e=>e.key===a.key));console.log(e,t),-1!==e?t[e].value=[...t[e].value,...a.value]:t.push(a)}}})),this.feedback.answers=i?[]:t}pushAnswers(e=!1){var t,i;return s(this,void 0,void 0,(function*(){try{if(this.answer(),"MAGICFORM"===(null===(t=this.formData)||void 0===t?void 0:t.identity)){if(0===this.feedback.answers.length)throw new Error("No answers provided");this.questions.forEach((e=>{if(e.require&&!this.feedback.answers.find((t=>t.key===e.ref)))throw new Error(`No answer provided for question ${e.title}`)}))}else if(!e&&(null===(i=this.questionInProcess)||void 0===i?void 0:i.require)&&0===this.feedback.answers.length)throw new Error("No answers provided");const s=this.config.get("url"),n={integration:this.appId,publicKey:this.publicKey,feedback:this.feedback,completed:e};return yield(0,o.sendFeedback)(s,this.id?Object.assign(Object.assign({},n),{sessionId:this.id}):n,this.log)}catch(e){return this.log.err(`An error occurred while submitting the form ${this.appId}:`,e),""}}))}callFollowUpQuestion(e){return s(this,void 0,void 0,(function*(){if(!(null==e?void 0:e.followup))return null;try{if(0===this.feedback.answers.length)throw new Error("No answers provided");const t=this.config.get("url"),i={answer:this.feedback.answers[0].value[0],publicKey:this.publicKey,sessionId:this.id,question:e};return yield(0,o.getFollowUpQuestion)(t,i,this.log)}catch(e){throw this.log.err(`An error occurred while submitting the form ${this.appId}:`,e),e}}))}processNextQuestion(e,t){var i,n,o,r;return s(this,void 0,void 0,(function*(){if("MAGICSURVEY"===(null===(i=this.formData)||void 0===i?void 0:i.identity))if(null===(n=this.questionInProcess)||void 0===n?void 0:n.followup){const i=yield this.callFollowUpQuestion(this.questionInProcess);if(i){this.questionInProcess=i;const e=(0,a.renderQuestions)([i],null===(o=this.formOptionsConfig)||void 0===o?void 0:o.questionFormat,null===(r=this.formData)||void 0===r?void 0:r.lang[0])[0];this.history[this.progress].push({object:i,element:e}),t.removeChild(t.childNodes[0]),t.appendChild(e)}else this.renderNextQuestion(t,e)}else this.renderNextQuestion(t,e);else if(this.total=this.questions.length,this.progress=this.questions.length,this.formOptionsConfig.addSuccessScreen){e.childNodes.length>0&&e.removeChild(e.childNodes[0]);const t=(0,a.renderSuccess)(this.formOptionsConfig.successMessage||"Thank you for your feedback!");e.appendChild(t)}}))}renderNextQuestion(e,t){if(this.progress++,this.progress<this.total)this.questionInProcess=this.history[this.progress][0].object,e.removeChild(e.childNodes[0]),e.appendChild(this.history[this.progress][0].element);else{if(this.formOptionsConfig.addSuccessScreen){t.childNodes.length>0&&t.removeChild(t.childNodes[0]);const e=(0,a.renderSuccess)(this.formOptionsConfig.successMessage||"Thank you for your feedback!");t.appendChild(e)}this.pushAnswers(!0)}}back(){if(0===this.progress)return;const e=document.getElementById("magicfeedback-questions-"+this.appId);e.removeChild(e.childNodes[0]),this.history[this.progress].length>1?this.history[this.progress].pop():this.progress--;const t=this.history[this.progress][this.history[this.progress].length-1];this.questionInProcess=t.object,e.appendChild(t.element)}}},374:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.endpoints=void 0,t.endpoints={sdk:{app:(e,t)=>`sdk/app/${e}/${t}`,app_info:(e,t)=>`sdk/app/${e}/${t}/info`,feedback:"sdk/feedback",followUpQuestion:"sdk/followUpQuestion"}}},183:(e,t)=>{"use strict";function i(e,t){return"object"==typeof e?e[t]||e.en:e}Object.defineProperty(t,"__esModule",{value:!0}),t.renderSuccess=t.renderError=t.renderActions=t.renderQuestions=void 0,t.renderQuestions=function e(t,s="standard",n="en"){if(!t)throw new Error("[MagicFeedback] No questions provided");const o=[];return t.forEach((t=>{var a,r;if((null===(r=null===(a=null==t?void 0:t.questionType)||void 0===a?void 0:a.conf)||void 0===r?void 0:r.length)>0){let i=document.createElement("div");i.classList.add("magicfeedback-div"),t.questionType.conf.forEach((e=>e.ref=t.ref)),e(t.questionType.conf,s,n).forEach((e=>{i.appendChild(e)})),o.push(i)}else{const e=function(e,t,s){const{id:n,title:o,type:a,ref:r,require:c,value:d,defaultValue:l,assets:u}=e;let h,p,f=document.createElement("div");switch(f.classList.add("magicfeedback-div"),a){case"TEXT":h=document.createElement("input"),h.type="text",h.placeholder="slim"===t?i(o,s):"Write your answer here...",p="magicfeedback-text";break;case"LONGTEXT":h=document.createElement("textarea"),h.rows=3,h.placeholder="slim"===t?i(o,s):"Write your answer here...",p="magicfeedback-longtext";break;case"NUMBER":h=document.createElement("input"),h.type="number",h.placeholder="slim"===t?i(o,s):"Insert a number here",p="magicfeedback-number",d.length&&(d.sort(((e,t)=>Number(e)-Number(t))),h.max=d[d.length-1],h.min=d[0],h.value=d[0]);break;case"RADIO":case"MULTIPLECHOICE":h=document.createElement("div"),p="magicfeedback-"+("MULTIPLECHOICE"===a?"checkbox":"radio"),d.forEach(((e,t)=>{const i=document.createElement("div");i.classList.add(`magicfeedback-${"MULTIPLECHOICE"===a?"checkbox":"radio"}-container`);const s=document.createElement("label"),n=document.createElement("input");n.id=`rating-${r}-${t}`,n.type="MULTIPLECHOICE"===a?"checkbox":"radio",n.name=r,n.value=e,n.classList.add(p),n.classList.add("magicfeedback-input"),e===l&&(n.checked=!0),s.textContent=e,s.htmlFor=`rating-${r}-${t}`,i.appendChild(n),i.appendChild(s),h.appendChild(i)}));break;case"BOOLEAN":h=document.createElement("div"),p="magicfeedback-radio";const e=document.createElement("div");e.classList.add("magicfeedback-boolean-container"),e.style.display="flex",e.style.flexDirection="row",e.style.justifyContent="space-between",e.style.width="70%",e.style.margin="auto",(u.addIcon?["✓","✗"]:function(e){switch(e){case"es":return["Sí","No"];case"fr":return["Oui","Non"];case"de":return["Ja","Nein"];case"it":return["Sì","No"];case"pt":return["Sim","Não"];case"nl":return["Ja","Nee"];case"pl":return["Tak","Nie"];case"ru":return["Да","Нет"];case"ja":return["はい","いいえ"];case"zh":return["是","不"];case"ko":return["예","아니"];case"da":case"sv":return["Ja","Nej"];case"fi":return["Kyllä","Ei"];case"no":return["Ja","Nei"];default:return["Yes","No"]}}(s)).forEach(((t,i)=>{const s=document.createElement("label");s.classList.add("magicfeedback-boolean-option"),s.htmlFor=`rating-${r}-${i}`,s.style.cursor="pointer",s.style.border="1px solid #000",s.style.display="flex",s.style.justifyContent="center",s.style.alignItems="center",s.style.margin="auto",s.style.padding="0",s.style.width="45%",s.style.height="38px";const n=document.createElement("label");n.htmlFor=`rating-${r}-${i}`,n.classList.add("magicfeedback-boolean-option-label-container"),n.style.margin="0",n.style.padding="0";const o=document.createElement("label");o.htmlFor=`rating-${r}-${i}`,o.textContent=t,o.style.margin="0",o.style.padding="0";const a=document.createElement("input");a.id=`rating-${r}-${i}`,a.type="radio",a.name=r,a.value=t,a.classList.add(p),a.classList.add("magicfeedback-input"),a.style.position="absolute",a.style.opacity="0",a.style.width="0",a.style.height="0",a.style.margin="0",n.appendChild(a),n.appendChild(o),s.appendChild(n),e.appendChild(s)})),h.appendChild(e);break;case"RATING_EMOJI":h=document.createElement("div"),p="magicfeedback-rating";const m=document.createElement("div");m.classList.add("magicfeedback-rating-container");const g=d.length?Number(d[d.length-1]):5;for(let e=d.length?Number(d[0]):1;e<=g;e++){const t=document.createElement("div");t.classList.add("magicfeedback-rating-option");const i=document.createElement("label");i.htmlFor=`rating-${r}-${e}`,i.classList.add("magicfeedback-rating-option-label-container");const s=document.createElement("label");s.htmlFor=`rating-${r}-${e}`,s.textContent=e.toString();const n=document.createElement("img");if(5===g)switch(e){case 1:n.src="https://magicfeedback-c6458-dev.web.app/assets/1.svg";break;case 2:n.src="https://magicfeedback-c6458-dev.web.app/assets/2.svg";break;case 3:n.src="https://magicfeedback-c6458-dev.web.app/assets/6.svg";break;case 4:n.src="https://magicfeedback-c6458-dev.web.app/assets/9.svg";break;case 5:n.src="https://magicfeedback-c6458-dev.web.app/assets/10.svg"}else n.src=`https://magicfeedback-c6458-dev.web.app/assets/${e}.svg`;n.alt=`face-${r}-${e}`,n.className=`rating-image${e}`;const o=document.createElement("input");o.id=`rating-${r}-${e}`,o.type="radio",o.name=r,o.value=e.toString(),o.classList.add(p),o.classList.add("magicfeedback-input"),i.appendChild(o),i.appendChild(n),i.appendChild(s),t.appendChild(i),m.appendChild(t)}h.appendChild(m);break;case"RATING_NUMBER":h=document.createElement("div"),p="magicfeedback-rating-number";const b=document.createElement("div");b.classList.add("magicfeedback-rating-number-container");const y=d.length?Number(d[d.length-1]):5;for(let e=d.length?Number(d[0]):1;e<=y;e++){const t=document.createElement("div");t.classList.add("magicfeedback-rating-number-option");const i=document.createElement("label");i.htmlFor=`rating-${r}-${e}`,i.classList.add("magicfeedback-rating-number-option-label-container");const s=document.createElement("label");s.htmlFor=`rating-${r}-${e}`,s.textContent=e.toString();const n=document.createElement("input");n.id=`rating-${r}-${e}`,n.type="radio",n.name=r,n.value=e.toString(),n.classList.add(p),n.classList.add("magicfeedback-input"),i.appendChild(n),i.appendChild(s),t.appendChild(i),b.appendChild(t)}h.appendChild(b);break;case"RATING_STAR":h=document.createElement("div"),p="magicfeedback-rating-star";const v=function(e){const t="magicfeedback-rating-star-selected",i=document.createElement("div");i.classList.add("magicfeedback-rating-star-container");for(let s=1;s<=5;s++){const n=document.createElement("label");n.classList.add("magicfeedback-rating-star-option");const o=document.createElement("input");o.id=`rating-${e}-${s}`,o.type="radio",o.name=e,o.value=s.toString(),o.style.position="absolute",o.style.opacity="0",o.style.width="0",o.style.height="0",o.classList.add("magicfeedback-input"),o.addEventListener("change",(()=>{const e=i.querySelectorAll(".rating__star");for(let i=0;i<e.length;i++)i+1<=Number(o.value)?e[i].classList.contains(t)||e[i].classList.add(t):e[i].classList.contains(t)&&e[i].classList.remove(t)})),n.appendChild(o);const a=document.createElement("label");a.htmlFor=`rating-${e}-${s}`,a.classList.add("rating__star"),a.textContent="★",a.style.fontSize="40px",a.style.color="#CCCCCC",a.style.cursor="pointer",n.appendChild(a),i.appendChild(n)}return i}(r);h.appendChild(v);break;case"MULTIPLECHOISE_IMAGE":h=document.createElement("div"),p="magicfeedback-multiple-choice-image";const k=document.createElement("div");k.classList.add("magicfeedback-multiple-choice-image-container"),k.style.display="flex",k.style.flexDirection="row",k.style.flexWrap="wrap",k.style.justifyContent="center";const w=d.length;let E=1,C=1;2===w?E=2:4===w?(E=2,C=2):6===w&&(E=3,C=2);const x=void 0!==u.addTitle&&u.addTitle;d.forEach((e=>{try{const{position:t,url:i,value:s}=JSON.parse(e),n=document.createElement("label");n.classList.add("magicfeedback-multiple-choice-image-option"),n.style.width=`calc( ${100/E}% - 10px)`,n.style.height=`calc( ${100/C}% - 10px)`,n.style.margin="5px";const o=document.createElement("label");o.htmlFor=`rating-${r}-${t}`,o.classList.add("magicfeedback-image-option-label-container"),o.style.display="flex",o.style.flexDirection="column",o.addEventListener("mouseover",(()=>{o.style.border="2px solid #000"})),o.addEventListener("mouseout",(()=>{o.style.border="none"})),o.addEventListener("click",(()=>{o.style.border="2px solid #000"}));const a=document.createElement("label");a.textContent=s,a.classList.add("magicfeedback-multiple-choice-image-label");const c=document.createElement("input");c.id=`rating-${r}-${t}`,c.type="radio",c.name=r,c.value=s,c.style.position="absolute",c.style.opacity="0",c.style.width="0",c.style.height="0",c.classList.add("magicfeedback-input");const d=document.createElement("img");d.classList.add("magicfeedback-multiple-choice-image-image"),d.src=i,d.style.cursor="pointer",d.style.backgroundSize="cover",d.style.width="100%",d.style.height="100%",d.style.margin="auto",o.appendChild(c),o.appendChild(d),x&&o.appendChild(a),n.appendChild(o),k.appendChild(n)}catch(e){console.error(e)}})),h.appendChild(k);break;case"SELECT":h=document.createElement("select"),p="magicfeedback-select";const O=document.createElement("option");O.value="",O.text="slim"===t?i(o,s):l||"Select an option",O.disabled=!0,O.selected=!0,h.appendChild(O),d.forEach((e=>{const t=document.createElement("option");t.value=e,t.text=e,h.appendChild(t)}));break;case"DATE":h=document.createElement("input"),h.type="date",h.required=c,h.placeholder="slim"===t?i(o,s):"Select a date",p="magicfeedback-date";break;case"CONSENT":h=document.createElement("input"),p="magicfeedback-consent",h.type="checkbox",h.id=`magicfeedback-${n}`,h.name=r,h.value="true",h.required=c,h.classList.add("magicfeedback-consent"),h.classList.add("magicfeedback-input");break;case"EMAIL":h=document.createElement("input"),h.type="email",h.required=c,h.placeholder="slim"===t?i(o,s):"you@example.com",p="magicfeedback-email";break;case"PASSWORD":h=document.createElement("input"),h.type="password",h.required=c,h.placeholder="slim"===t?i(o,s):"Write your password here",p="magicfeedback-password";break;default:return f}h.id=`magicfeedback-${n}`,h.setAttribute("name",r),h.classList.add(p),void 0!==l&&(h.value=l),["RADIO","MULTIPLECHOICE"].includes(a)||(h.classList.add("magicfeedback-input"),h.required=c);const m=document.createElement("label");if(m.setAttribute("for",`magicfeedback-${n}`),m.textContent=i(o,s),m.classList.add("magicfeedback-label"),["CONSENT"].includes(a))f.classList.add("magicfeedback-consent-container"),f.appendChild(h),f.appendChild(m);else{if("slim"!==t&&(f.appendChild(m),void 0!==(null==u?void 0:u.general)&&""!==(null==u?void 0:u.general))){const e=document.createElement("img");e.src=u.general,e.classList.add("magicfeedback-image"),e.style.maxWidth="auto",e.style.height="400px",e.style.margin="10px 0",f.appendChild(e)}f.appendChild(h)}return f}(t,s,n);o.push(e)}})),o},t.renderActions=function(e="",t,i="Submit",s="Back",n="Next"){const o=document.createElement("div");o.classList.add("magicfeedback-action-container");const a=document.createElement("button");a.id="magicfeedback-submit",a.type="submit",a.classList.add("magicfeedback-submit"),a.textContent="MAGICSURVEY"===e?n||"Next":i||"Submit";const r=document.createElement("button");return r.id="magicfeedback-back",r.type="button",r.classList.add("magicfeedback-back"),r.textContent=s||"Back",r.addEventListener("click",t),"MAGICSURVEY"===e&&o.appendChild(r),o.appendChild(a),o},t.renderError=function(e){const t=document.createElement("div");return t.classList.add("magicfeedback-error"),t.textContent=e,t},t.renderSuccess=function(e){const t=document.createElement("div");return t.classList.add("magicfeedback-success"),t.textContent=e,t}},341:function(e,t,i){"use strict";var s=this&&this.__awaiter||function(e,t,i,s){return new(i||(i=Promise))((function(n,o){function a(e){try{c(s.next(e))}catch(e){o(e)}}function r(e){try{c(s.throw(e))}catch(e){o(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(a,r)}c((s=s.apply(e,t||[])).next())}))},n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getFollowUpQuestion=t.sendFeedback=t.getQuestions=t.getForm=t.validateEmail=void 0;const o=n(i(98)),a=n(i(147)),r=i(374),c={Accept:"application/json","Magicfeedback-Sdk-Version":a.default.version};t.validateEmail=function(e){return/\S+@\S+\.\S+/.test(e)},t.getForm=function(e,t,i,n){return s(this,void 0,void 0,(function*(){try{const s=yield(0,o.default)(e+r.endpoints.sdk.app_info(t,i),{method:"GET",headers:c});if(s.ok){const e=yield s.json();return n.log(`Received form for app ${t}`,e),e}throw n.err(`Failed to get questions for app ${t}:`,s.status,s.statusText),new Error("[MagicFeedback] Bad response from server")}catch(e){return n.err(e),null}}))},t.getQuestions=function(e,t,i,n){return s(this,void 0,void 0,(function*(){try{const s=yield(0,o.default)(e+r.endpoints.sdk.app(t,i),{method:"GET",headers:c});if(s.ok){const e=yield s.json();return n.log(`Received questions for app ${t}`,e),e}throw n.err(`Failed to get questions for app ${t}:`,s.status,s.statusText),new Error("[MagicFeedback] Bad response from server")}catch(e){return n.err(e),[]}}))},t.sendFeedback=function(e,t,i){return s(this,void 0,void 0,(function*(){try{const s=yield(0,o.default)(e+r.endpoints.sdk.feedback,{method:"POST",headers:Object.assign({"Content-Type":"application/json"},c),body:JSON.stringify(t)});if(s.ok)return i.log(`Form ${t.integration} submitted successfully!`),(yield s.json()).sessionId;throw i.err(`Failed to submit form ${t.integration}:`,s.status,s.statusText),new Error(s.statusText)}catch(e){return i.err(e),""}}))},t.getFollowUpQuestion=function(e,t,i){return s(this,void 0,void 0,(function*(){try{const s=yield(0,o.default)(e+r.endpoints.sdk.followUpQuestion,{method:"POST",headers:Object.assign({"Content-Type":"application/json"},c),body:JSON.stringify(t)});if(s.ok)return i.log(`Received follow up question for form ${t.integration}`),(yield s.json())||"";throw i.err(`Failed to get follow up question for form ${t.integration}:`,s.status,s.statusText),new Error(s.statusText)}catch(e){return i.err(e),""}}))}},5:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Log=void 0,t.Log=class{constructor(e){this.config=e}log(...e){this.config.get("debug")&&console.log("[MagicFeedback]:",...e)}err(...e){console.error("[MagicFeedback]:",...e)}}},147:e=>{"use strict";e.exports=JSON.parse('{"name":"@magicfeedback/native","version":"1.1.16-beta.2","main":"./dist/magicfeedback-sdk.node.js","browser":"./dist/magicfeedback-sdk.browser.js","types":"./dist/types/src/index.d.ts","repository":{"type":"git","url":"git+ssh://git@github.com/MagicFeedback/magicfeedback-sdk.git"},"author":"farias@magicfeedback.io","license":"MIT","private":false,"scripts":{"dev":"vite","build":"webpack","build:watch":"webpack --watch --mode development","publish":"npm publish --access public","publish:beta":"npm publish --access public --tag beta","test":"jest","test:watch":"jest --watchAll","coverage":"vitest run --coverage"},"files":["dist"],"devDependencies":{"@babel/preset-typescript":"^7.22.5","@types/node":"^17.0.21","@types/webpack":"^5.28.0","@types/webpack-node-externals":"^2.5.3","c8":"^7.11.0","jest":"^29.5.0","jest-environment-jsdom":"^29.5.0","jest-fetch-mock":"^3.0.3","nock":"^13.2.4","ts-jest":"^29.1.0","ts-loader":"^9.2.7","ts-node":"^10.7.0","typescript":"^4.6.2","vite":"^2.8.0","vite-plugin-dts":"^0.9.9","vitest":"^0.5.9","webpack":"^5.70.0","webpack-cli":"^4.9.2","webpack-node-externals":"^3.0.0"},"dependencies":{"cross-fetch":"^3.1.5","is-bundling-for-browser-or-node":"^1.1.1"},"description":"MagicFeedbackAI JavaScript Library for [MagicFeedback.io](https://magicfeedback.io/)","bugs":{"url":"https://github.com/MagicFeedback/magicfeedback-sdk/issues"},"homepage":"https://github.com/MagicFeedback/magicfeedback-sdk#readme","directories":{"example":"examples","test":"test"}}')}},t={},function i(s){var n=t[s];if(void 0!==n)return n.exports;var o=t[s]={exports:{}};return e[s].call(o.exports,o,o.exports,i),o.exports}(607).default;var e,t}));
@@ -1,170 +1 @@
1
- /*
2
- * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
3
- * This devtool is neither made for production nor for readable output files.
4
- * It uses "eval()" calls to create a separate source file in the browser devtools.
5
- * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
6
- * or disable the default devtool with "devtool: false".
7
- * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
8
- */
9
- (function webpackUniversalModuleDefinition(root, factory) {
10
- if(typeof exports === 'object' && typeof module === 'object')
11
- module.exports = factory();
12
- else if(typeof define === 'function' && define.amd)
13
- define([], factory);
14
- else if(typeof exports === 'object')
15
- exports["magicfeedback"] = factory();
16
- else
17
- root["magicfeedback"] = factory();
18
- })(global, () => {
19
- return /******/ (() => { // webpackBootstrap
20
- /******/ "use strict";
21
- /******/ var __webpack_modules__ = ({
22
-
23
- /***/ "./src/config-globals.ts":
24
- /*!*******************************!*\
25
- !*** ./src/config-globals.ts ***!
26
- \*******************************/
27
- /***/ ((__unused_webpack_module, exports) => {
28
-
29
- eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.HOST_API_URL_DEV = exports.HOST_API_URL = void 0;\nexports.HOST_API_URL = 'https://api.magicfeedback.io/';\nexports.HOST_API_URL_DEV = 'https://api-dev.magicfeedback.io/';\n\n\n//# sourceURL=webpack://magicfeedback/./src/config-globals.ts?");
30
-
31
- /***/ }),
32
-
33
- /***/ "./src/index.ts":
34
- /*!**********************!*\
35
- !*** ./src/index.ts ***!
36
- \**********************/
37
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
38
-
39
- eval("\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst main_1 = __importDefault(__webpack_require__(/*! ./main */ \"./src/main.ts\"));\nlet instance = null;\nif (!instance) {\n instance = (0, main_1.default)();\n}\nexports[\"default\"] = instance;\n\n\n//# sourceURL=webpack://magicfeedback/./src/index.ts?");
40
-
41
- /***/ }),
42
-
43
- /***/ "./src/main.ts":
44
- /*!*********************!*\
45
- !*** ./src/main.ts ***!
46
- \*********************/
47
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
48
-
49
- eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst form_1 = __webpack_require__(/*! ./models/form */ \"./src/models/form.ts\");\nconst config_1 = __webpack_require__(/*! ./models/config */ \"./src/models/config.ts\");\nconst log_1 = __webpack_require__(/*! ./utils/log */ \"./src/utils/log.ts\");\nconst request_service_1 = __webpack_require__(/*! ./services/request.service */ \"./src/services/request.service.ts\");\nconst config_globals_1 = __webpack_require__(/*! ./config-globals */ \"./src/config-globals.ts\");\n/**\n *\n * @returns\n */\nfunction main() {\n //===============================================\n // Attributes\n //===============================================\n const config = new config_1.Config();\n let log;\n /**\n *\n * @param options\n */\n function init(options) {\n if (options === null || options === void 0 ? void 0 : options.debug)\n config.set(\"debug\", options === null || options === void 0 ? void 0 : options.debug);\n config.set(\"url\", (options === null || options === void 0 ? void 0 : options.env) && (options === null || options === void 0 ? void 0 : options.env) === \"dev\" ? config_globals_1.HOST_API_URL_DEV : config_globals_1.HOST_API_URL);\n log = new log_1.Log(config);\n log.log(\"Initialized Magicfeedback\", config);\n }\n /**\n *\n * @param appId\n * @param publicKey\n * @param feedback\n * @param id\n * @param completed\n * @param privateKey\n * @returns\n */\n function send(appId, publicKey, feedback, completed = true, id, privateKey) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!appId)\n log.err(\"No appID provided\");\n if (!publicKey)\n log.err(\"No publicKey provided\");\n if (!feedback)\n log.err(\"No feedback provided\");\n if (!feedback.answers &&\n !feedback.profile &&\n !feedback.metrics &&\n !feedback.metadata)\n log.err(\"No feedback data provided\");\n const url = config.get(\"url\");\n const body = {\n integration: appId,\n publicKey: publicKey,\n privateKey: privateKey,\n completed: completed,\n id: id,\n feedback: feedback,\n };\n try {\n const res = yield (0, request_service_1.sendFeedback)(url, body, log);\n log.log(`sent native feedback`);\n return res;\n }\n catch (e) {\n log.err(`error native feedback`, e);\n return false;\n }\n });\n }\n /**\n *\n * @param appId\n * @param publicKey\n * @returns\n */\n function form(appId, publicKey) {\n if (!appId)\n log.err(\"No appID provided\");\n if (!publicKey)\n log.err(\"No publicKey provided\");\n return new form_1.Form(config, appId, publicKey);\n }\n //===============================================\n // Return\n //===============================================\n return {\n // lifecycle\n init,\n // requests\n send,\n form,\n };\n}\nexports[\"default\"] = main;\n\n\n//# sourceURL=webpack://magicfeedback/./src/main.ts?");
50
-
51
- /***/ }),
52
-
53
- /***/ "./src/models/config.ts":
54
- /*!******************************!*\
55
- !*** ./src/models/config.ts ***!
56
- \******************************/
57
- /***/ ((__unused_webpack_module, exports) => {
58
-
59
- eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Config = void 0;\nclass Config {\n constructor() {\n this.variables = {};\n this.variables[\"env\"] = 'prod';\n this.variables[\"debug\"] = false;\n }\n get(key) {\n return this.variables[key];\n }\n set(key, value) {\n this.variables[key] = value;\n }\n}\nexports.Config = Config;\n\n\n//# sourceURL=webpack://magicfeedback/./src/models/config.ts?");
60
-
61
- /***/ }),
62
-
63
- /***/ "./src/models/form.ts":
64
- /*!****************************!*\
65
- !*** ./src/models/form.ts ***!
66
- \****************************/
67
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
68
-
69
- eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Form = void 0;\nconst log_1 = __webpack_require__(/*! ../utils/log */ \"./src/utils/log.ts\");\nconst request_service_1 = __webpack_require__(/*! ../services/request.service */ \"./src/services/request.service.ts\");\nconst questions_service_1 = __webpack_require__(/*! ../services/questions.service */ \"./src/services/questions.service.ts\");\nclass Form {\n /**\n *\n * @param config\n * @param appId\n * @param publicKey\n */\n constructor(config, appId, publicKey) {\n // SDK Config\n this.config = config;\n this.log = new log_1.Log(config);\n // Form options\n this.formOptionsConfig = {\n addButton: true,\n sendButtonText: \"Send\",\n backButtonText: \"Back\",\n nextButtonText: \"Next\",\n addSuccessScreen: true,\n getMetaData: true,\n questionFormat: \"standard\",\n };\n this.selector = \"\";\n // Attributes\n this.appId = appId;\n this.publicKey = publicKey;\n this.url = config.get(\"url\");\n // Form completed data\n this.id = \"\";\n this.formData = null;\n this.feedback = {\n text: \"\",\n answers: [],\n profile: [],\n metrics: [],\n metadata: [],\n };\n // Questions and history\n this.questions = [];\n this.elementQuestions = [];\n this.questionInProcess = null;\n this.history = {};\n // Count variables\n this.progress = 0;\n this.total = 0;\n }\n /**\n * Generate\n * TODO: Check if is inside of a <form>\n * @param selector\n * @param options\n */\n generate(selector, options) {\n return __awaiter(this, void 0, void 0, function* () {\n // Check options, and set default values if this is not defined\n try {\n // Set the options\n this.formOptionsConfig = Object.assign(Object.assign({}, this.formOptionsConfig), options);\n this.selector = selector;\n // Check if the form is in the localstorage and the time is less than 1 day\n const localForm = localStorage.getItem(`magicfeedback-${this.appId}`);\n if (localForm && new Date(JSON.parse(localForm).savedAt) < new Date(new Date().getTime() + 60 * 60 * 24 * 1000)) {\n this.formData = JSON.parse(localForm);\n (0, request_service_1.getForm)(this.url, this.appId, this.publicKey, this.log).then((form) => {\n var _a, _b;\n if ((form === null || form === void 0 ? void 0 : form.updatedAt) && ((_a = this.formData) === null || _a === void 0 ? void 0 : _a.savedAt) && (form === null || form === void 0 ? void 0 : form.updatedAt) > ((_b = this.formData) === null || _b === void 0 ? void 0 : _b.savedAt)) {\n console.log(\"Form updated\");\n this.formData = form;\n this.formData.savedAt = new Date();\n if (this.formData.questions) {\n this.questions = this.formData.questions;\n this.total = this.questions.length;\n }\n localStorage.setItem(`magicfeedback-${this.appId}`, JSON.stringify(this.formData));\n // Create the form from the JSON\n this.generateForm();\n }\n });\n }\n else {\n // Send the data to manage loadings and progress\n this.formData = yield (0, request_service_1.getForm)(this.url, this.appId, this.publicKey, this.log);\n }\n if (this.formData === undefined || !this.formData)\n throw new Error(`No form for app ${this.appId}`);\n if (!this.formData.savedAt) {\n // Save formData in the localstorage to use it in the future\n this.formData.savedAt = new Date();\n localStorage.setItem(`magicfeedback-${this.appId}`, JSON.stringify(this.formData));\n }\n this.questions = this.formData.questions;\n if (this.questions === undefined || !this.questions)\n throw new Error(`No questions for app ${this.appId}`);\n this.total = this.questions.length;\n // Send the data to manage loadings and progress\n if (this.formOptionsConfig.onLoadedEvent) {\n yield this.formOptionsConfig.onLoadedEvent({\n loading: false,\n progress: this.progress,\n total: this.total,\n formData: this.formData,\n });\n }\n if (this.formOptionsConfig.getMetaData)\n this.getMetaData();\n // Create the form from the JSON\n this.generateForm();\n }\n catch (e) {\n this.log.err(e);\n if (this.formOptionsConfig.onLoadedEvent) {\n yield this.formOptionsConfig.onLoadedEvent({\n loading: false,\n error: e,\n });\n }\n return;\n }\n });\n }\n /**\n * Create\n *\n * TODO: Add option to generate in <form> or in other <tag>\n */\n generateForm() {\n var _a, _b, _c;\n try {\n // Order questions by position\n this.questions.sort((a, b) => a.position - b.position);\n // Select and prepare the container\n const container = document.getElementById(this.selector);\n if (!container)\n throw new Error(`Element with ID '${this.selector}' not found.`);\n container.classList.add(\"magicfeedback-container\");\n container.id = \"magicfeedback-container-\" + this.appId;\n container.innerHTML = \"\";\n // Create the form\n const form = document.createElement(\"form\");\n form.classList.add(\"magicfeedback-form\");\n form.id = \"magicfeedback-\" + this.appId;\n // Create the questions container\n const questionContainer = document.createElement(\"div\");\n questionContainer.classList.add(\"magicfeedback-questions\");\n questionContainer.id = \"magicfeedback-questions-\" + this.appId;\n // Process questions and create in the form\n this.elementQuestions = (0, questions_service_1.renderQuestions)(this.questions, this.formOptionsConfig.questionFormat, (_a = this.formData) === null || _a === void 0 ? void 0 : _a.lang[0]);\n switch ((_b = this.formData) === null || _b === void 0 ? void 0 : _b.identity) {\n case 'MAGICSURVEY':\n this.elementQuestions.forEach((element, index) => this.history[index] = [{ object: this.questions[index], element }]);\n this.questionInProcess = this.history[0][0].object;\n questionContainer.appendChild(this.history[0][0].element);\n break;\n default:\n this.elementQuestions.forEach((element) => questionContainer.appendChild(element));\n break;\n }\n form.appendChild(questionContainer);\n // Add the form to the specified container\n container.appendChild(form);\n // Submit button\n if (this.formOptionsConfig.addButton) {\n // Create a container for the buttons\n const actionContainer = (0, questions_service_1.renderActions)((_c = this.formData) === null || _c === void 0 ? void 0 : _c.identity, () => this.back(), this.formOptionsConfig.sendButtonText, this.formOptionsConfig.backButtonText, this.formOptionsConfig.nextButtonText);\n form.appendChild(actionContainer);\n }\n // Submit event\n form.addEventListener(\"submit\", (event) => {\n event.preventDefault();\n this.send();\n });\n }\n catch (e) {\n this.log.err(e);\n if (this.formOptionsConfig.onLoadedEvent) {\n this.formOptionsConfig.onLoadedEvent({\n loading: false,\n error: e,\n });\n }\n return;\n }\n }\n /**\n * Get the metadata from the URL, navigators and others\n * @private\n */\n getMetaData() {\n // Add the navigator url and params from the URL to the metadata\n this.feedback.metadata.push({ key: \"navigator-url\", value: [window.location.href] });\n this.feedback.metadata.push({ key: \"navigator-origin\", value: [window.location.origin] });\n this.feedback.metadata.push({ key: \"navigator-pathname\", value: [window.location.pathname] });\n this.feedback.metadata.push({ key: \"navigator-search\", value: [window.location.search] });\n // Add the navigator metadata\n this.feedback.metadata.push({ key: \"navigator-user\", value: [navigator.userAgent] });\n this.feedback.metadata.push({ key: \"navigator-language\", value: [navigator.language] });\n this.feedback.metadata.push({ key: \"navigator-platform\", value: [navigator.platform] });\n this.feedback.metadata.push({ key: \"navigator-appVersion\", value: [navigator.appVersion] });\n this.feedback.metadata.push({ key: \"navigator-appName\", value: [navigator.appName] });\n this.feedback.metadata.push({ key: \"navigator-product\", value: [navigator.product] });\n // Add the size of the screen\n this.feedback.metadata.push({ key: \"screen-width\", value: [window.screen.width.toString()] });\n this.feedback.metadata.push({ key: \"screen-height\", value: [window.screen.height.toString()] });\n }\n /**\n * Send current answer and verify if its necessary continue with a new question\n * @pubilc\n * @param profile\n * @param metrics\n * @param metadata\n */\n send(metadata, metrics, profile) {\n var _a;\n return __awaiter(this, void 0, void 0, function* () {\n const container = document.getElementById(\"magicfeedback-container-\" + this.appId);\n const questionContainer = document.getElementById(\"magicfeedback-questions-\" + this.appId);\n try {\n if (profile)\n this.feedback.profile = [...this.feedback.profile, ...profile];\n if (metrics)\n this.feedback.metrics = [...this.feedback.metrics, ...metrics];\n if (metadata)\n this.feedback.metadata = [...this.feedback.metadata, ...metadata];\n // BEFORE\n if (this.formOptionsConfig.beforeSubmitEvent) {\n yield this.formOptionsConfig.beforeSubmitEvent({\n loading: true,\n progress: this.progress,\n total: this.total\n });\n }\n // SEND\n const response = yield this.pushAnswers(((_a = this.formData) === null || _a === void 0 ? void 0 : _a.identity) !== 'MAGICSURVEY');\n if (response) {\n this.id = response;\n yield this.processNextQuestion(container, questionContainer);\n }\n // AFTER\n if (this.formOptionsConfig.afterSubmitEvent) {\n yield this.formOptionsConfig.afterSubmitEvent({\n response,\n loading: false,\n progress: this.progress,\n total: this.total,\n error: response ? null : new Error(\"No response\")\n });\n }\n }\n catch (error) {\n // Handle error in beforeSubmitEvent, send(), or afterSubmitEvent\n this.log.err(`An error occurred while submitting the form ${this.appId}:`, error);\n if (this.formOptionsConfig.afterSubmitEvent) {\n yield this.formOptionsConfig.afterSubmitEvent({\n loading: false,\n progress: this.progress,\n total: this.total,\n error\n });\n }\n }\n });\n }\n /**\n * Update feedback.answers with the answers of the form in a JSON format\n * @returns\n * TODO: Required\n */\n answer() {\n const form = document.getElementById(\"magicfeedback-\" + this.appId);\n if (!form) {\n this.log.err(`Form \"${form}\" not found.`);\n this.feedback.answers = [];\n return;\n }\n const surveyAnswers = [];\n let hasError = false; // Flag to track if an error has occurred\n const inputs = form.querySelectorAll(\".magicfeedback-input\");\n inputs.forEach((input) => {\n const inputType = input.type;\n const elementTypeClass = input.classList[0];\n const ans = {\n key: input.name,\n value: [],\n };\n const value = elementTypeClass === 'magicfeedback-consent' ?\n input.checked.toString() :\n input.value;\n if (!ans.key || ans.key === \"\") {\n return;\n }\n else {\n switch (inputType) {\n case \"radio\":\n case \"checkbox\":\n if (elementTypeClass === \"magicfeedback-consent\" ||\n input.checked) {\n ans.value.push(value);\n // check if the answer is already in the array and merge the values\n const index = surveyAnswers.findIndex((a) => a.key === ans.key);\n if (index !== -1) {\n surveyAnswers[index].value = [\n ...surveyAnswers[index].value,\n ...ans.value,\n ];\n }\n else {\n surveyAnswers.push(ans);\n }\n }\n break;\n default:\n if (value !== \"\") {\n if (inputType === \"email\") {\n if (!(0, request_service_1.validateEmail)(value)) {\n this.log.err(\"Invalid email\");\n hasError = true;\n break;\n }\n else {\n this.feedback.profile.push({\n key: \"email\",\n value: [value],\n });\n }\n }\n ans.value.push(value);\n // check if the answer is already in the array and merge the values\n const index = surveyAnswers.findIndex((a) => a.key === ans.key);\n console.log(index, surveyAnswers);\n if (index !== -1) {\n surveyAnswers[index].value = [\n ...surveyAnswers[index].value,\n ...ans.value,\n ];\n }\n else {\n surveyAnswers.push(ans);\n }\n }\n }\n }\n });\n if (hasError) {\n this.feedback.answers = []; // Stop the process if there's an error\n return;\n }\n this.feedback.answers = surveyAnswers;\n }\n /**\n * Send\n * @param completed\n * @returns\n */\n pushAnswers(completed = false) {\n var _a, _b;\n return __awaiter(this, void 0, void 0, function* () {\n try {\n // Get the survey answers from the answer() function\n this.answer();\n if (((_a = this.formData) === null || _a === void 0 ? void 0 : _a.identity) === \"MAGICFORM\") {\n if (this.feedback.answers.length === 0)\n throw new Error(\"No answers provided\");\n this.questions.forEach((question) => {\n if (question.require && !this.feedback.answers.find((a) => a.key === question.ref)) {\n throw new Error(`No answer provided for question ${question.title}`);\n }\n });\n }\n else {\n if (!completed &&\n ((_b = this.questionInProcess) === null || _b === void 0 ? void 0 : _b.require) &&\n this.feedback.answers.length === 0)\n throw new Error(\"No answers provided\");\n }\n // Define the URL and request payload\n const url = this.config.get(\"url\");\n const body = {\n integration: this.appId,\n publicKey: this.publicKey,\n feedback: this.feedback,\n completed,\n };\n // Make the AJAX POST request\n return yield (0, request_service_1.sendFeedback)(url, this.id ? Object.assign(Object.assign({}, body), { sessionId: this.id }) : body, this.log);\n }\n catch (error) {\n // Handle network or request error\n this.log.err(`An error occurred while submitting the form ${this.appId}:`, error);\n // You can perform error handling logic here if needed\n return '';\n }\n });\n }\n /**\n * Call follow up question\n * @param question\n * @private\n */\n callFollowUpQuestion(question) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!(question === null || question === void 0 ? void 0 : question.followup))\n return null;\n try {\n if (this.feedback.answers.length === 0)\n throw new Error(\"No answers provided\");\n // Define the URL and request payload\n const url = this.config.get(\"url\");\n const body = {\n answer: this.feedback.answers[0].value[0],\n publicKey: this.publicKey,\n sessionId: this.id,\n question\n };\n return yield (0, request_service_1.getFollowUpQuestion)(url, body, this.log);\n }\n catch (error) {\n // Handle network or request error\n this.log.err(`An error occurred while submitting the form ${this.appId}:`, error);\n // You can perform error handling logic here if needed\n throw error;\n }\n });\n }\n /**\n * Process next question\n * @param container\n * @param form\n * @private\n */\n processNextQuestion(container, form) {\n var _a, _b, _c, _d;\n return __awaiter(this, void 0, void 0, function* () {\n switch ((_a = this.formData) === null || _a === void 0 ? void 0 : _a.identity) {\n case 'MAGICSURVEY':\n if (!((_b = this.questionInProcess) === null || _b === void 0 ? void 0 : _b.followup)) {\n this.renderNextQuestion(form, container);\n }\n else {\n const followUp = yield this.callFollowUpQuestion(this.questionInProcess);\n if (followUp) {\n // Update the question in process\n this.questionInProcess = followUp;\n // Add the follow up question to the history\n const question = (0, questions_service_1.renderQuestions)([followUp], (_c = this.formOptionsConfig) === null || _c === void 0 ? void 0 : _c.questionFormat, (_d = this.formData) === null || _d === void 0 ? void 0 : _d.lang[0])[0];\n this.history[this.progress].push({ object: followUp, element: question });\n form.removeChild(form.childNodes[0]);\n form.appendChild(question);\n }\n else {\n this.renderNextQuestion(form, container);\n }\n }\n break;\n default:\n this.total = this.questions.length;\n this.progress = this.questions.length;\n if (this.formOptionsConfig.addSuccessScreen) {\n // Remove the form\n if (container.childNodes.length > 0)\n container.removeChild(container.childNodes[0]);\n // Show the success message\n const successMessage = (0, questions_service_1.renderSuccess)(this.formOptionsConfig.successMessage ||\n \"Thank you for your feedback!\");\n container.appendChild(successMessage);\n }\n break;\n }\n });\n }\n /**\n * Render next question\n * @param form\n * @param container\n * @private\n */\n renderNextQuestion(form, container) {\n this.progress++;\n if (this.progress < this.total) {\n this.questionInProcess = this.history[this.progress][0].object;\n form.removeChild(form.childNodes[0]);\n form.appendChild(this.history[this.progress][0].element);\n }\n else {\n if (this.formOptionsConfig.addSuccessScreen) {\n // Remove the form\n if (container.childNodes.length > 0)\n container.removeChild(container.childNodes[0]);\n // Show the success message\n const successMessage = (0, questions_service_1.renderSuccess)(this.formOptionsConfig.successMessage ||\n \"Thank you for your feedback!\");\n container.appendChild(successMessage);\n }\n this.pushAnswers(true);\n }\n }\n /**\n * Render back question\n * @private\n */\n back() {\n if (this.progress === 0)\n return;\n const form = document.getElementById(\"magicfeedback-questions-\" + this.appId);\n form.removeChild(form.childNodes[0]);\n if (this.history[this.progress].length > 1) {\n // Delete the last question in the history array and load the previous one\n this.history[this.progress].pop();\n }\n else {\n // Use the previous question in the history array\n this.progress--;\n }\n // Get the last question in the history array\n const question = this.history[this.progress][this.history[this.progress].length - 1];\n // Update the question in process\n this.questionInProcess = question.object;\n form.appendChild(question.element);\n }\n}\nexports.Form = Form;\n\n\n//# sourceURL=webpack://magicfeedback/./src/models/form.ts?");
70
-
71
- /***/ }),
72
-
73
- /***/ "./src/services/paths.ts":
74
- /*!*******************************!*\
75
- !*** ./src/services/paths.ts ***!
76
- \*******************************/
77
- /***/ ((__unused_webpack_module, exports) => {
78
-
79
- eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.endpoints = void 0;\nexports.endpoints = {\n sdk: {\n app: (appId, publicKey) => `sdk/app/${appId}/${publicKey}`,\n app_info: (appId, publicKey) => `sdk/app/${appId}/${publicKey}/info`,\n feedback: 'sdk/feedback',\n followUpQuestion: 'sdk/followUpQuestion',\n }\n};\n\n\n//# sourceURL=webpack://magicfeedback/./src/services/paths.ts?");
80
-
81
- /***/ }),
82
-
83
- /***/ "./src/services/questions.service.ts":
84
- /*!*******************************************!*\
85
- !*** ./src/services/questions.service.ts ***!
86
- \*******************************************/
87
- /***/ ((__unused_webpack_module, exports) => {
88
-
89
- eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.renderSuccess = exports.renderError = exports.renderActions = exports.renderQuestions = void 0;\nfunction renderQuestions(appQuestions, format = \"standard\", language = \"en\") {\n if (!appQuestions)\n throw new Error(\"[MagicFeedback] No questions provided\");\n const questions = [];\n appQuestions.forEach((question) => {\n var _a, _b;\n if (((_b = (_a = question === null || question === void 0 ? void 0 : question.questionType) === null || _a === void 0 ? void 0 : _a.conf) === null || _b === void 0 ? void 0 : _b.length) > 0) {\n let elementContainer = document.createElement(\"div\");\n elementContainer.classList.add(\"magicfeedback-div\");\n question.questionType.conf.forEach((conf) => conf.ref = question.ref);\n const elements = renderQuestions(question.questionType.conf, format, language);\n elements.forEach((element) => {\n elementContainer.appendChild(element);\n });\n questions.push(elementContainer);\n }\n else {\n // Create a container for each question\n const elementContainer = renderContainer(question, format, language);\n questions.push(elementContainer);\n }\n });\n return questions;\n}\nexports.renderQuestions = renderQuestions;\nfunction parseTitle(title, lang) {\n return typeof title === \"object\" ? (title[lang] || title['en']) : title;\n}\n// Make a function to return a array with yes and no in every language\nfunction getBooleanOptions(lang) {\n switch (lang) {\n case \"es\":\n return ['Sí', 'No'];\n case \"fr\":\n return ['Oui', 'Non'];\n case \"de\":\n return ['Ja', 'Nein'];\n case \"it\":\n return ['Sì', 'No'];\n case \"pt\":\n return ['Sim', 'Não'];\n case \"nl\":\n return ['Ja', 'Nee'];\n case \"pl\":\n return ['Tak', 'Nie'];\n case \"ru\":\n return ['Да', 'Нет'];\n case \"ja\":\n return ['はい', 'いいえ'];\n case \"zh\":\n return ['是', '不'];\n case \"ko\":\n return ['예', '아니'];\n case 'da':\n return ['Ja', 'Nej'];\n case 'fi':\n return ['Kyllä', 'Ei'];\n case 'sv':\n return ['Ja', 'Nej'];\n case 'no':\n return ['Ja', 'Nei'];\n default:\n return ['Yes', 'No'];\n }\n}\nfunction renderContainer(question, format, language) {\n const { id, title, type, ref, require, \n //external_id,\n value, defaultValue, \n // questionType,\n assets } = question;\n let element;\n let elementTypeClass;\n let elementContainer = document.createElement(\"div\");\n elementContainer.classList.add(\"magicfeedback-div\");\n switch (type) {\n case \"TEXT\":\n // Create a text input field\n element = document.createElement(\"input\");\n element.type = \"text\";\n element.placeholder = format === 'slim' ? parseTitle(title, language) : \"Write your answer here...\";\n elementTypeClass = \"magicfeedback-text\";\n break;\n case \"LONGTEXT\":\n // Create a textarea element for TEXT and LONGTEXT types\n element = document.createElement(\"textarea\");\n element.rows = 3; // Set the number of rows based on the type\n element.placeholder = format === 'slim' ? parseTitle(title, language) : \"Write your answer here...\";\n elementTypeClass = \"magicfeedback-longtext\";\n break;\n case \"NUMBER\":\n // Create an input element with type \"number\" for NUMBER type\n element = document.createElement(\"input\");\n element.type = \"number\";\n element.placeholder = format === 'slim' ? parseTitle(title, language) : \"Insert a number here\";\n elementTypeClass = \"magicfeedback-number\";\n if (value.length) {\n value.sort((a, b) => Number(a) - Number(b));\n element.max = value[value.length - 1];\n element.min = value[0];\n element.value = value[0];\n }\n break;\n case \"RADIO\":\n case \"MULTIPLECHOICE\":\n element = document.createElement(\"div\");\n elementTypeClass =\n `magicfeedback-${(type === \"MULTIPLECHOICE\" ? \"checkbox\" : \"radio\")}`;\n value.forEach((option, index) => {\n const container = document.createElement(\"div\");\n container.classList.add(`magicfeedback-${type === \"MULTIPLECHOICE\" ? \"checkbox\" : \"radio\"}-container`);\n const label = document.createElement(\"label\");\n const input = document.createElement(\"input\");\n input.id = `rating-${ref}-${index}`;\n input.type = type === \"MULTIPLECHOICE\" ? \"checkbox\" : \"radio\";\n input.name = ref;\n input.value = option;\n input.classList.add(elementTypeClass);\n input.classList.add(\"magicfeedback-input\");\n if (option === defaultValue) {\n input.checked = true;\n }\n label.textContent = option;\n label.htmlFor = `rating-${ref}-${index}`;\n container.appendChild(input);\n container.appendChild(label);\n element.appendChild(container);\n });\n break;\n case \"BOOLEAN\":\n // Create an input element with type \"checkbox\" for BOOLEAN type with option yes or no\n element = document.createElement(\"div\");\n elementTypeClass = 'magicfeedback-radio';\n const booleanContainer = document.createElement('div');\n booleanContainer.classList.add('magicfeedback-boolean-container');\n booleanContainer.style.display = \"flex\";\n booleanContainer.style.flexDirection = \"row\";\n booleanContainer.style.justifyContent = \"space-between\";\n booleanContainer.style.width = \"70%\";\n booleanContainer.style.margin = \"auto\";\n const booleanOptions = assets.addIcon ? ['✓', '✗'] : getBooleanOptions(language);\n // Create a input button element for each value in the question's value array\n booleanOptions.forEach((option, index) => {\n const container = document.createElement(\"label\");\n container.classList.add(\"magicfeedback-boolean-option\");\n container.htmlFor = `rating-${ref}-${index}`;\n container.style.cursor = \"pointer\";\n container.style.border = \"1px solid #000\";\n container.style.display = \"flex\";\n container.style.justifyContent = \"center\";\n container.style.alignItems = \"center\";\n container.style.margin = \"auto\";\n container.style.padding = \"0\";\n container.style.width = \"45%\";\n container.style.height = \"38px\";\n const containerLabel = document.createElement('label');\n containerLabel.htmlFor = `rating-${ref}-${index}`;\n containerLabel.classList.add('magicfeedback-boolean-option-label-container');\n containerLabel.style.margin = \"0\";\n containerLabel.style.padding = \"0\";\n const label = document.createElement(\"label\");\n label.htmlFor = `rating-${ref}-${index}`;\n label.textContent = option;\n label.style.margin = \"0\";\n label.style.padding = \"0\";\n const input = document.createElement(\"input\");\n input.id = `rating-${ref}-${index}`;\n input.type = \"radio\";\n input.name = ref;\n input.value = option;\n input.classList.add(elementTypeClass);\n input.classList.add(\"magicfeedback-input\");\n input.style.position = \"absolute\";\n input.style.opacity = \"0\";\n input.style.width = \"0\";\n input.style.height = \"0\";\n input.style.margin = \"0\";\n containerLabel.appendChild(input);\n containerLabel.appendChild(label);\n container.appendChild(containerLabel);\n booleanContainer.appendChild(container);\n });\n element.appendChild(booleanContainer);\n break;\n case 'RATING_EMOJI':\n element = document.createElement(\"div\");\n elementTypeClass = 'magicfeedback-rating';\n const ratingContainer = document.createElement('div');\n ratingContainer.classList.add('magicfeedback-rating-container');\n const maxRating = value.length ? Number(value[value.length - 1]) : 5;\n const minRating = value.length ? Number(value[0]) : 1;\n for (let i = minRating; i <= maxRating; i++) {\n const ratingOption = document.createElement('div');\n ratingOption.classList.add('magicfeedback-rating-option');\n const containerLabel = document.createElement('label');\n containerLabel.htmlFor = `rating-${ref}-${i}`;\n containerLabel.classList.add('magicfeedback-rating-option-label-container');\n const ratingLabel = document.createElement('label');\n ratingLabel.htmlFor = `rating-${ref}-${i}`;\n ratingLabel.textContent = i.toString();\n const ratingImage = document.createElement('img');\n if (maxRating === 5) {\n switch (i) {\n case 1:\n ratingImage.src = \"https://magicfeedback-c6458-dev.web.app/assets/1.svg\";\n break;\n case 2:\n ratingImage.src = \"https://magicfeedback-c6458-dev.web.app/assets/2.svg\";\n break;\n case 3:\n ratingImage.src = \"https://magicfeedback-c6458-dev.web.app/assets/6.svg\";\n break;\n case 4:\n ratingImage.src = \"https://magicfeedback-c6458-dev.web.app/assets/9.svg\";\n break;\n case 5:\n ratingImage.src = \"https://magicfeedback-c6458-dev.web.app/assets/10.svg\";\n break;\n }\n }\n else {\n ratingImage.src = `https://magicfeedback-c6458-dev.web.app/assets/${i}.svg`;\n }\n ratingImage.alt = `face-${ref}-${i}`;\n // ratingImage is used to set the form value\n // ... add the code to set the value here\n ratingImage.className = `rating-image${i}`;\n const input = document.createElement(\"input\");\n input.id = `rating-${ref}-${i}`;\n input.type = \"radio\";\n input.name = ref;\n input.value = i.toString();\n input.classList.add(elementTypeClass);\n input.classList.add(\"magicfeedback-input\");\n containerLabel.appendChild(input);\n containerLabel.appendChild(ratingImage);\n containerLabel.appendChild(ratingLabel);\n ratingOption.appendChild(containerLabel);\n ratingContainer.appendChild(ratingOption);\n }\n element.appendChild(ratingContainer);\n break;\n case 'RATING_NUMBER':\n element = document.createElement(\"div\");\n elementTypeClass = 'magicfeedback-rating-number';\n const ratingNumberContainer = document.createElement('div');\n ratingNumberContainer.classList.add('magicfeedback-rating-number-container');\n const maxRatingNumber = value.length ? Number(value[value.length - 1]) : 5;\n const minRatingNumber = value.length ? Number(value[0]) : 1;\n for (let i = minRatingNumber; i <= maxRatingNumber; i++) {\n // Create a input button element for each value in the question's value array\n const ratingOption = document.createElement('div');\n ratingOption.classList.add('magicfeedback-rating-number-option');\n const containerLabel = document.createElement('label');\n containerLabel.htmlFor = `rating-${ref}-${i}`;\n containerLabel.classList.add('magicfeedback-rating-number-option-label-container');\n const ratingLabel = document.createElement('label');\n ratingLabel.htmlFor = `rating-${ref}-${i}`;\n ratingLabel.textContent = i.toString();\n const input = document.createElement(\"input\");\n input.id = `rating-${ref}-${i}`;\n input.type = \"radio\";\n input.name = ref;\n input.value = i.toString();\n input.classList.add(elementTypeClass);\n input.classList.add(\"magicfeedback-input\");\n containerLabel.appendChild(input);\n containerLabel.appendChild(ratingLabel);\n ratingOption.appendChild(containerLabel);\n ratingNumberContainer.appendChild(ratingOption);\n }\n element.appendChild(ratingNumberContainer);\n break;\n case 'RATING_STAR':\n element = document.createElement(\"div\");\n elementTypeClass = 'magicfeedback-rating-star';\n const ratingStarContainer = createStarRating(ref);\n element.appendChild(ratingStarContainer);\n break;\n case 'MULTIPLECHOISE_IMAGE':\n element = document.createElement(\"div\");\n elementTypeClass = 'magicfeedback-multiple-choice-image';\n // Display de items inside a flex container if only have one item display it as a single image in the center, if have 2 items display them as a row, if have more than 2 items display them as a grid, if have 4 items display them as a 2x2 grid and if have 6 items display them as a 3x2 grid\n const multipleChoiceImageContainer = document.createElement(\"div\");\n multipleChoiceImageContainer.classList.add(\"magicfeedback-multiple-choice-image-container\");\n multipleChoiceImageContainer.style.display = \"flex\";\n multipleChoiceImageContainer.style.flexDirection = \"row\";\n multipleChoiceImageContainer.style.flexWrap = \"wrap\";\n multipleChoiceImageContainer.style.justifyContent = \"center\";\n const maxItems = value.length;\n let itemsPerRow = 1;\n let itemsPerColumn = 1;\n if (maxItems === 2) {\n itemsPerRow = 2;\n }\n else if (maxItems === 4) {\n itemsPerRow = 2;\n itemsPerColumn = 2;\n }\n else if (maxItems === 6) {\n itemsPerRow = 3;\n itemsPerColumn = 2;\n }\n const useLabel = assets.addTitle === undefined ? false : assets.addTitle;\n // The image is the only input but can have a title\n value.forEach((option) => {\n try {\n const { position, url, value } = JSON.parse(option);\n const container = document.createElement(\"label\");\n container.classList.add(\"magicfeedback-multiple-choice-image-option\");\n container.style.width = `calc( ${100 / itemsPerRow}% - 10px)`;\n container.style.height = `calc( ${100 / itemsPerColumn}% - 10px)`;\n container.style.margin = \"5px\";\n const containerLabel = document.createElement('label');\n containerLabel.htmlFor = `rating-${ref}-${position}`;\n containerLabel.classList.add('magicfeedback-image-option-label-container');\n containerLabel.style.display = \"flex\";\n containerLabel.style.flexDirection = \"column\";\n // Add a effect on hover and on select\n containerLabel.addEventListener(\"mouseover\", () => {\n containerLabel.style.border = \"2px solid #000\";\n });\n containerLabel.addEventListener(\"mouseout\", () => {\n containerLabel.style.border = \"none\";\n });\n containerLabel.addEventListener(\"click\", () => {\n containerLabel.style.border = \"2px solid #000\";\n });\n const label = document.createElement(\"label\");\n label.textContent = value;\n label.classList.add(\"magicfeedback-multiple-choice-image-label\");\n const input = document.createElement(\"input\");\n input.id = `rating-${ref}-${position}`;\n input.type = \"radio\";\n input.name = ref;\n input.value = value;\n input.style.position = \"absolute\";\n input.style.opacity = \"0\";\n input.style.width = \"0\";\n input.style.height = \"0\";\n input.classList.add(\"magicfeedback-input\");\n // Add max size to the image\n const image = document.createElement(\"img\");\n image.classList.add(\"magicfeedback-multiple-choice-image-image\");\n image.src = url;\n image.style.cursor = \"pointer\";\n image.style.backgroundSize = \"cover\";\n image.style.width = \"100%\";\n image.style.height = \"100%\";\n image.style.margin = \"auto\";\n containerLabel.appendChild(input);\n containerLabel.appendChild(image);\n if (useLabel)\n containerLabel.appendChild(label);\n container.appendChild(containerLabel);\n multipleChoiceImageContainer.appendChild(container);\n }\n catch (e) {\n console.error(e);\n }\n });\n element.appendChild(multipleChoiceImageContainer);\n break;\n case \"SELECT\":\n // Create a select element for RADIO and MULTIPLECHOICE types\n element = document.createElement(\"select\");\n elementTypeClass = \"magicfeedback-select\";\n // Create an option <option value=\"\" disabled selected hidden>Please Choose...</option>\n const option = document.createElement(\"option\");\n option.value = \"\";\n option.text = format === 'slim' ? parseTitle(title, language) : (defaultValue || \"Select an option\");\n option.disabled = true;\n option.selected = true;\n element.appendChild(option);\n value.forEach((optionValue) => {\n // Create an option element for each value in the question's value array\n const option = document.createElement(\"option\");\n option.value = optionValue;\n option.text = optionValue;\n element.appendChild(option);\n });\n break;\n case \"DATE\":\n // Create an input element with type \"date\" for DATE type\n element = document.createElement(\"input\");\n element.type = \"date\";\n element.required = require;\n element.placeholder = format === 'slim' ? parseTitle(title, language) : \"Select a date\";\n elementTypeClass = \"magicfeedback-date\";\n break;\n case \"CONSENT\":\n // Create an input element with type \"checkbox\" for BOOLEAN type\n element = document.createElement(\"input\");\n elementTypeClass = \"magicfeedback-consent\";\n element.type = \"checkbox\";\n element.id = `magicfeedback-${id}`;\n element.name = ref;\n element.value = \"true\";\n element.required = require;\n element.classList.add(\"magicfeedback-consent\");\n element.classList.add(\"magicfeedback-input\");\n break;\n case \"EMAIL\":\n // Create an input element with type \"email\" for EMAIL type\n element = document.createElement(\"input\");\n element.type = \"email\";\n element.required = require;\n element.placeholder = format === 'slim' ? parseTitle(title, language) : \"you@example.com\";\n elementTypeClass = \"magicfeedback-email\";\n break;\n case \"PASSWORD\":\n // Create an input element with type \"password\" for PASSWORD type\n element = document.createElement(\"input\");\n element.type = \"password\";\n element.required = require;\n element.placeholder = format === 'slim' ? parseTitle(title, language) : \"Write your password here\";\n elementTypeClass = \"magicfeedback-password\";\n break;\n default:\n return elementContainer;\n }\n element.id = `magicfeedback-${id}`;\n element.setAttribute(\"name\", ref);\n element.classList.add(elementTypeClass);\n if (defaultValue !== undefined) {\n element.value = defaultValue;\n }\n if (![\"RADIO\", \"MULTIPLECHOICE\"].includes(type)) {\n element.classList.add(\"magicfeedback-input\");\n element.required = require;\n }\n // Add the label and input element to the form\n const label = document.createElement(\"label\");\n label.setAttribute(\"for\", `magicfeedback-${id}`);\n label.textContent = parseTitle(title, language);\n label.classList.add(\"magicfeedback-label\");\n if ([\"CONSENT\"].includes(type)) {\n elementContainer.classList.add(\"magicfeedback-consent-container\");\n elementContainer.appendChild(element);\n elementContainer.appendChild(label);\n }\n else {\n if (format !== 'slim') {\n elementContainer.appendChild(label);\n if ((assets === null || assets === void 0 ? void 0 : assets.general) !== undefined && (assets === null || assets === void 0 ? void 0 : assets.general) !== \"\") {\n // Add a image to the form\n const image = document.createElement(\"img\");\n image.src = assets.general;\n image.classList.add(\"magicfeedback-image\");\n // Add a max default width to the image\n image.style.maxWidth = \"auto\";\n image.style.height = \"400px\";\n image.style.margin = \"10px 0\";\n elementContainer.appendChild(image);\n }\n }\n elementContainer.appendChild(element);\n }\n return elementContainer;\n}\nfunction renderActions(identity = '', backAction, sendButtonText = \"Submit\", backButtonText = \"Back\", nextButtonText = \"Next\") {\n const actionContainer = document.createElement(\"div\");\n actionContainer.classList.add(\"magicfeedback-action-container\");\n // Create a submit button if specified in options\n const submitButton = document.createElement(\"button\");\n submitButton.id = \"magicfeedback-submit\";\n submitButton.type = \"submit\";\n submitButton.classList.add(\"magicfeedback-submit\");\n submitButton.textContent = identity === 'MAGICSURVEY' ? (nextButtonText || \"Next\") : (sendButtonText || \"Submit\");\n // Create a back button\n const backButton = document.createElement(\"button\");\n backButton.id = \"magicfeedback-back\";\n backButton.type = \"button\";\n backButton.classList.add(\"magicfeedback-back\");\n backButton.textContent = backButtonText || \"Back\";\n backButton.addEventListener(\"click\", backAction);\n if (identity === 'MAGICSURVEY') {\n actionContainer.appendChild(backButton);\n }\n actionContainer.appendChild(submitButton);\n return actionContainer;\n}\nexports.renderActions = renderActions;\nfunction createStarRating(ref) {\n const size = 40;\n const selectedClass = \"magicfeedback-rating-star-selected\";\n const starFilled = \"★\";\n const ratingContainer = document.createElement(\"div\");\n ratingContainer.classList.add(\"magicfeedback-rating-star-container\");\n for (let i = 1; i <= 5; i++) {\n const ratingOption = document.createElement(\"label\");\n ratingOption.classList.add(\"magicfeedback-rating-star-option\");\n // Create hidden radio input\n const ratingInput = document.createElement(\"input\");\n ratingInput.id = `rating-${ref}-${i}`;\n ratingInput.type = \"radio\";\n ratingInput.name = ref;\n ratingInput.value = i.toString();\n ratingInput.style.position = \"absolute\";\n ratingInput.style.opacity = \"0\";\n ratingInput.style.width = \"0\";\n ratingInput.style.height = \"0\";\n ratingInput.classList.add(\"magicfeedback-input\");\n // Update filled stars on radio input change\n ratingInput.addEventListener(\"change\", () => {\n const allStars = ratingContainer.querySelectorAll(\".rating__star\");\n for (let j = 0; j < allStars.length; j++) {\n // String to number\n if (j + 1 <= Number(ratingInput.value)) {\n if (!allStars[j].classList.contains(selectedClass))\n allStars[j].classList.add(selectedClass);\n }\n else {\n if (allStars[j].classList.contains(selectedClass))\n allStars[j].classList.remove(selectedClass);\n }\n }\n });\n ratingOption.appendChild(ratingInput);\n // Create star element (after for better positioning)\n const starElement = document.createElement(\"label\");\n starElement.htmlFor = `rating-${ref}-${i}`;\n starElement.classList.add(\"rating__star\");\n starElement.textContent = starFilled;\n starElement.style.fontSize = `${size}px`; // Set star size\n starElement.style.color = \"#CCCCCC\"; // Set star color\n starElement.style.cursor = \"pointer\";\n // Add hover effect\n ratingOption.appendChild(starElement);\n ratingContainer.appendChild(ratingOption);\n }\n return ratingContainer;\n}\nfunction renderError(error) {\n const errorElement = document.createElement(\"div\");\n errorElement.classList.add(\"magicfeedback-error\");\n errorElement.textContent = error;\n return errorElement;\n}\nexports.renderError = renderError;\nfunction renderSuccess(success) {\n const successElement = document.createElement(\"div\");\n successElement.classList.add(\"magicfeedback-success\");\n successElement.textContent = success;\n return successElement;\n}\nexports.renderSuccess = renderSuccess;\n\n\n//# sourceURL=webpack://magicfeedback/./src/services/questions.service.ts?");
90
-
91
- /***/ }),
92
-
93
- /***/ "./src/services/request.service.ts":
94
- /*!*****************************************!*\
95
- !*** ./src/services/request.service.ts ***!
96
- \*****************************************/
97
- /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
98
-
99
- eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.getFollowUpQuestion = exports.sendFeedback = exports.getQuestions = exports.getForm = exports.validateEmail = void 0;\nconst cross_fetch_1 = __importDefault(__webpack_require__(/*! cross-fetch */ \"cross-fetch\"));\nconst package_json_1 = __importDefault(__webpack_require__(/*! ../../package.json */ \"./package.json\"));\nconst paths_1 = __webpack_require__(/*! ./paths */ \"./src/services/paths.ts\");\nconst header = {\n Accept: \"application/json\",\n \"Magicfeedback-Sdk-Version\": package_json_1.default.version,\n};\n// @ts-ignore\nconst serializedParams = (params) => Object.entries(params).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`).join(\"&\");\nfunction validateEmail(email) {\n const re = /\\S+@\\S+\\.\\S+/;\n return re.test(email);\n}\nexports.validateEmail = validateEmail;\nfunction getForm(url, appId, publicKey, log) {\n return __awaiter(this, void 0, void 0, function* () {\n try {\n const response = yield (0, cross_fetch_1.default)(url + paths_1.endpoints.sdk.app_info(appId, publicKey), {\n method: \"GET\",\n headers: header\n });\n if (response.ok) {\n // Handle success response\n const json = yield response.json();\n log.log(`Received form for app ${appId}`, json);\n return json;\n }\n else {\n // Handle error response\n log.err(`Failed to get questions for app ${appId}:`, response.status, response.statusText);\n throw new Error(\"[MagicFeedback] Bad response from server\");\n }\n }\n catch (e) {\n log.err(e);\n return null;\n }\n });\n}\nexports.getForm = getForm;\nfunction getQuestions(url, appId, publicKey, log) {\n return __awaiter(this, void 0, void 0, function* () {\n try {\n const response = yield (0, cross_fetch_1.default)(url + paths_1.endpoints.sdk.app(appId, publicKey), {\n method: \"GET\",\n headers: header\n });\n if (response.ok) {\n // Handle success response\n const json = yield response.json();\n log.log(`Received questions for app ${appId}`, json);\n return json;\n }\n else {\n // Handle error response\n log.err(`Failed to get questions for app ${appId}:`, response.status, response.statusText);\n throw new Error(\"[MagicFeedback] Bad response from server\");\n }\n }\n catch (e) {\n log.err(e);\n return [];\n }\n });\n}\nexports.getQuestions = getQuestions;\nfunction sendFeedback(url, body, log) {\n return __awaiter(this, void 0, void 0, function* () {\n try {\n const response = yield (0, cross_fetch_1.default)(url + paths_1.endpoints.sdk.feedback, {\n method: \"POST\",\n headers: Object.assign({ \"Content-Type\": \"application/json\" }, header),\n body: JSON.stringify(body),\n });\n if (response.ok) {\n // Handle success response\n log.log(`Form ${body.integration} submitted successfully!`);\n // You can perform additional actions here if needed\n const responseJson = yield response.json();\n return responseJson.sessionId;\n }\n else {\n // Handle error response\n log.err(`Failed to submit form ${body.integration}:`, response.status, response.statusText);\n throw new Error(response.statusText);\n }\n }\n catch (e) {\n log.err(e);\n return '';\n }\n });\n}\nexports.sendFeedback = sendFeedback;\nfunction getFollowUpQuestion(url, body, log) {\n return __awaiter(this, void 0, void 0, function* () {\n try {\n const response = yield (0, cross_fetch_1.default)(url + paths_1.endpoints.sdk.followUpQuestion, {\n method: \"POST\",\n headers: Object.assign({ \"Content-Type\": \"application/json\" }, header),\n body: JSON.stringify(body),\n });\n if (response.ok) {\n // Handle success response\n log.log(`Received follow up question for form ${body.integration}`);\n // You can perform additional actions here if needed\n const responseJson = yield response.json();\n return responseJson || '';\n }\n else {\n // Handle error response\n log.err(`Failed to get follow up question for form ${body.integration}:`, response.status, response.statusText);\n throw new Error(response.statusText);\n }\n }\n catch (e) {\n log.err(e);\n return '';\n }\n });\n}\nexports.getFollowUpQuestion = getFollowUpQuestion;\n\n\n//# sourceURL=webpack://magicfeedback/./src/services/request.service.ts?");
100
-
101
- /***/ }),
102
-
103
- /***/ "./src/utils/log.ts":
104
- /*!**************************!*\
105
- !*** ./src/utils/log.ts ***!
106
- \**************************/
107
- /***/ ((__unused_webpack_module, exports) => {
108
-
109
- eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Log = void 0;\nclass Log {\n /**\n *\n * @param config\n */\n constructor(config) {\n // Config\n this.config = config;\n }\n /**\n *\n * @param args\n */\n log(...args) {\n if (this.config.get(\"debug\")) {\n console.log(\"[MagicFeedback]:\", ...args);\n }\n }\n /**\n *\n * @param args\n */\n err(...args) {\n console.error(\"[MagicFeedback]:\", ...args);\n }\n}\nexports.Log = Log;\n\n\n//# sourceURL=webpack://magicfeedback/./src/utils/log.ts?");
110
-
111
- /***/ }),
112
-
113
- /***/ "cross-fetch":
114
- /*!******************************!*\
115
- !*** external "cross-fetch" ***!
116
- \******************************/
117
- /***/ ((module) => {
118
-
119
- module.exports = require("cross-fetch");
120
-
121
- /***/ }),
122
-
123
- /***/ "./package.json":
124
- /*!**********************!*\
125
- !*** ./package.json ***!
126
- \**********************/
127
- /***/ ((module) => {
128
-
129
- eval("module.exports = JSON.parse('{\"name\":\"@magicfeedback/native\",\"version\":\"1.1.16-beta.1\",\"main\":\"./dist/magicfeedback-sdk.node.js\",\"browser\":\"./dist/magicfeedback-sdk.browser.js\",\"types\":\"./dist/types/src/index.d.ts\",\"repository\":{\"type\":\"git\",\"url\":\"git+ssh://git@github.com/MagicFeedback/magicfeedback-sdk.git\"},\"author\":\"farias@magicfeedback.io\",\"license\":\"MIT\",\"private\":false,\"scripts\":{\"dev\":\"vite\",\"build\":\"webpack\",\"build:watch\":\"webpack --watch --mode development\",\"publish\":\"npm publish --access public\",\"publish:beta\":\"npm publish --access public --tag beta\",\"test\":\"jest\",\"test:watch\":\"jest --watchAll\",\"coverage\":\"vitest run --coverage\"},\"files\":[\"dist\"],\"devDependencies\":{\"@babel/preset-typescript\":\"^7.22.5\",\"@types/node\":\"^17.0.21\",\"@types/webpack\":\"^5.28.0\",\"@types/webpack-node-externals\":\"^2.5.3\",\"c8\":\"^7.11.0\",\"jest\":\"^29.5.0\",\"jest-environment-jsdom\":\"^29.5.0\",\"jest-fetch-mock\":\"^3.0.3\",\"nock\":\"^13.2.4\",\"ts-jest\":\"^29.1.0\",\"ts-loader\":\"^9.2.7\",\"ts-node\":\"^10.7.0\",\"typescript\":\"^4.6.2\",\"vite\":\"^2.8.0\",\"vite-plugin-dts\":\"^0.9.9\",\"vitest\":\"^0.5.9\",\"webpack\":\"^5.70.0\",\"webpack-cli\":\"^4.9.2\",\"webpack-node-externals\":\"^3.0.0\"},\"dependencies\":{\"cross-fetch\":\"^3.1.5\",\"is-bundling-for-browser-or-node\":\"^1.1.1\"},\"description\":\"MagicFeedbackAI JavaScript Library for [MagicFeedback.io](https://magicfeedback.io/)\",\"bugs\":{\"url\":\"https://github.com/MagicFeedback/magicfeedback-sdk/issues\"},\"homepage\":\"https://github.com/MagicFeedback/magicfeedback-sdk#readme\",\"directories\":{\"example\":\"examples\",\"test\":\"test\"}}');\n\n//# sourceURL=webpack://magicfeedback/./package.json?");
130
-
131
- /***/ })
132
-
133
- /******/ });
134
- /************************************************************************/
135
- /******/ // The module cache
136
- /******/ var __webpack_module_cache__ = {};
137
- /******/
138
- /******/ // The require function
139
- /******/ function __webpack_require__(moduleId) {
140
- /******/ // Check if module is in cache
141
- /******/ var cachedModule = __webpack_module_cache__[moduleId];
142
- /******/ if (cachedModule !== undefined) {
143
- /******/ return cachedModule.exports;
144
- /******/ }
145
- /******/ // Create a new module (and put it into the cache)
146
- /******/ var module = __webpack_module_cache__[moduleId] = {
147
- /******/ // no module.id needed
148
- /******/ // no module.loaded needed
149
- /******/ exports: {}
150
- /******/ };
151
- /******/
152
- /******/ // Execute the module function
153
- /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
154
- /******/
155
- /******/ // Return the exports of the module
156
- /******/ return module.exports;
157
- /******/ }
158
- /******/
159
- /************************************************************************/
160
- /******/
161
- /******/ // startup
162
- /******/ // Load entry module and return exports
163
- /******/ // This entry module is referenced by other modules so it can't be inlined
164
- /******/ var __webpack_exports__ = __webpack_require__("./src/index.ts");
165
- /******/ __webpack_exports__ = __webpack_exports__["default"];
166
- /******/
167
- /******/ return __webpack_exports__;
168
- /******/ })()
169
- ;
170
- });
1
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.magicfeedback=t():e.magicfeedback=t()}(global,(()=>(()=>{"use strict";var e={290:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.HOST_API_URL_DEV=t.HOST_API_URL=void 0,t.HOST_API_URL="https://api.magicfeedback.io/",t.HOST_API_URL_DEV="https://api-dev.magicfeedback.io/"},607:function(e,t,i){var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const a=s(i(519));let n=null;n||(n=(0,a.default)()),t.default=n},519:function(e,t,i){var s=this&&this.__awaiter||function(e,t,i,s){return new(i||(i=Promise))((function(a,n){function o(e){try{c(s.next(e))}catch(e){n(e)}}function r(e){try{c(s.throw(e))}catch(e){n(e)}}function c(e){var t;e.done?a(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(o,r)}c((s=s.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0});const a=i(954),n=i(712),o=i(5),r=i(341),c=i(290);t.default=function(){const e=new n.Config;let t;return{init:function(i){(null==i?void 0:i.debug)&&e.set("debug",null==i?void 0:i.debug),e.set("url",(null==i?void 0:i.env)&&"dev"===(null==i?void 0:i.env)?c.HOST_API_URL_DEV:c.HOST_API_URL),t=new o.Log(e),t.log("Initialized Magicfeedback",e)},send:function(i,a,n,o=!0,c,d){return s(this,void 0,void 0,(function*(){i||t.err("No appID provided"),a||t.err("No publicKey provided"),n||t.err("No feedback provided"),n.answers||n.profile||n.metrics||n.metadata||t.err("No feedback data provided");const s=e.get("url"),l={integration:i,publicKey:a,privateKey:d,completed:o,id:c,feedback:n};try{const e=yield(0,r.sendFeedback)(s,l,t);return t.log("sent native feedback"),e}catch(e){return t.err("error native feedback",e),!1}}))},form:function(i,s){return i||t.err("No appID provided"),s||t.err("No publicKey provided"),new a.Form(e,i,s)}}}},712:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Config=void 0,t.Config=class{constructor(){this.variables={},this.variables.env="prod",this.variables.debug=!1}get(e){return this.variables[e]}set(e,t){this.variables[e]=t}}},954:function(e,t,i){var s=this&&this.__awaiter||function(e,t,i,s){return new(i||(i=Promise))((function(a,n){function o(e){try{c(s.next(e))}catch(e){n(e)}}function r(e){try{c(s.throw(e))}catch(e){n(e)}}function c(e){var t;e.done?a(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(o,r)}c((s=s.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0}),t.Form=void 0;const a=i(5),n=i(341),o=i(183);t.Form=class{constructor(e,t,i){this.config=e,this.log=new a.Log(e),this.formOptionsConfig={addButton:!0,sendButtonText:"Send",backButtonText:"Back",nextButtonText:"Next",addSuccessScreen:!0,getMetaData:!0,questionFormat:"standard"},this.selector="",this.appId=t,this.publicKey=i,this.url=e.get("url"),this.id="",this.formData=null,this.feedback={text:"",answers:[],profile:[],metrics:[],metadata:[]},this.questions=[],this.elementQuestions=[],this.questionInProcess=null,this.history={},this.progress=0,this.total=0}generate(e,t){return s(this,void 0,void 0,(function*(){try{this.formOptionsConfig=Object.assign(Object.assign({},this.formOptionsConfig),t),this.selector=e;const i=localStorage.getItem(`magicfeedback-${this.appId}`);if(i&&new Date(JSON.parse(i).savedAt)<new Date((new Date).getTime()+864e5)?(this.formData=JSON.parse(i),(0,n.getForm)(this.url,this.appId,this.publicKey,this.log).then((e=>{var t,i;(null==e?void 0:e.updatedAt)&&(null===(t=this.formData)||void 0===t?void 0:t.savedAt)&&(null==e?void 0:e.updatedAt)>(null===(i=this.formData)||void 0===i?void 0:i.savedAt)&&(console.log("Form updated"),this.formData=e,this.formData.savedAt=new Date,this.formData.questions&&(this.questions=this.formData.questions,this.total=this.questions.length),localStorage.setItem(`magicfeedback-${this.appId}`,JSON.stringify(this.formData)),this.generateForm())}))):this.formData=yield(0,n.getForm)(this.url,this.appId,this.publicKey,this.log),void 0===this.formData||!this.formData)throw new Error(`No form for app ${this.appId}`);if(this.formData.savedAt||(this.formData.savedAt=new Date,localStorage.setItem(`magicfeedback-${this.appId}`,JSON.stringify(this.formData))),this.questions=this.formData.questions,void 0===this.questions||!this.questions)throw new Error(`No questions for app ${this.appId}`);this.total=this.questions.length,this.formOptionsConfig.onLoadedEvent&&(yield this.formOptionsConfig.onLoadedEvent({loading:!1,progress:this.progress,total:this.total,formData:this.formData})),this.formOptionsConfig.getMetaData&&this.getMetaData(),this.generateForm()}catch(e){return this.log.err(e),void(this.formOptionsConfig.onLoadedEvent&&(yield this.formOptionsConfig.onLoadedEvent({loading:!1,error:e})))}}))}generateForm(){var e,t,i;try{this.questions.sort(((e,t)=>e.position-t.position));const s=document.getElementById(this.selector);if(!s)throw new Error(`Element with ID '${this.selector}' not found.`);s.classList.add("magicfeedback-container"),s.id="magicfeedback-container-"+this.appId,s.innerHTML="";const a=document.createElement("form");a.classList.add("magicfeedback-form"),a.id="magicfeedback-"+this.appId;const n=document.createElement("div");if(n.classList.add("magicfeedback-questions"),n.id="magicfeedback-questions-"+this.appId,this.elementQuestions=(0,o.renderQuestions)(this.questions,this.formOptionsConfig.questionFormat,null===(e=this.formData)||void 0===e?void 0:e.lang[0]),"MAGICSURVEY"===(null===(t=this.formData)||void 0===t?void 0:t.identity)?(this.elementQuestions.forEach(((e,t)=>this.history[t]=[{object:this.questions[t],element:e}])),this.questionInProcess=this.history[0][0].object,n.appendChild(this.history[0][0].element)):this.elementQuestions.forEach((e=>n.appendChild(e))),a.appendChild(n),s.appendChild(a),this.formOptionsConfig.addButton){const e=(0,o.renderActions)(null===(i=this.formData)||void 0===i?void 0:i.identity,(()=>this.back()),this.formOptionsConfig.sendButtonText,this.formOptionsConfig.backButtonText,this.formOptionsConfig.nextButtonText);a.appendChild(e)}a.addEventListener("submit",(e=>{e.preventDefault(),this.send()}))}catch(e){return this.log.err(e),void(this.formOptionsConfig.onLoadedEvent&&this.formOptionsConfig.onLoadedEvent({loading:!1,error:e}))}}getMetaData(){this.feedback.metadata.push({key:"navigator-url",value:[window.location.href]}),this.feedback.metadata.push({key:"navigator-origin",value:[window.location.origin]}),this.feedback.metadata.push({key:"navigator-pathname",value:[window.location.pathname]}),this.feedback.metadata.push({key:"navigator-search",value:[window.location.search]}),this.feedback.metadata.push({key:"navigator-user",value:[navigator.userAgent]}),this.feedback.metadata.push({key:"navigator-language",value:[navigator.language]}),this.feedback.metadata.push({key:"navigator-platform",value:[navigator.platform]}),this.feedback.metadata.push({key:"navigator-appVersion",value:[navigator.appVersion]}),this.feedback.metadata.push({key:"navigator-appName",value:[navigator.appName]}),this.feedback.metadata.push({key:"navigator-product",value:[navigator.product]}),this.feedback.metadata.push({key:"screen-width",value:[window.screen.width.toString()]}),this.feedback.metadata.push({key:"screen-height",value:[window.screen.height.toString()]})}send(e,t,i){var a;return s(this,void 0,void 0,(function*(){const s=document.getElementById("magicfeedback-container-"+this.appId),n=document.getElementById("magicfeedback-questions-"+this.appId);try{i&&(this.feedback.profile=[...this.feedback.profile,...i]),t&&(this.feedback.metrics=[...this.feedback.metrics,...t]),e&&(this.feedback.metadata=[...this.feedback.metadata,...e]),this.formOptionsConfig.beforeSubmitEvent&&(yield this.formOptionsConfig.beforeSubmitEvent({loading:!0,progress:this.progress,total:this.total}));const o=yield this.pushAnswers("MAGICSURVEY"!==(null===(a=this.formData)||void 0===a?void 0:a.identity));o&&(this.id=o,yield this.processNextQuestion(s,n)),this.formOptionsConfig.afterSubmitEvent&&(yield this.formOptionsConfig.afterSubmitEvent({response:o,loading:!1,progress:this.progress,total:this.total,error:o?null:new Error("No response")}))}catch(e){this.log.err(`An error occurred while submitting the form ${this.appId}:`,e),this.formOptionsConfig.afterSubmitEvent&&(yield this.formOptionsConfig.afterSubmitEvent({loading:!1,progress:this.progress,total:this.total,error:e}))}}))}answer(){const e=document.getElementById("magicfeedback-"+this.appId);if(!e)return this.log.err(`Form "${e}" not found.`),void(this.feedback.answers=[]);const t=[];let i=!1;e.querySelectorAll(".magicfeedback-input").forEach((e=>{const s=e.type,a=e.classList[0],o={key:e.name,value:[]},r="magicfeedback-consent"===a?e.checked.toString():e.value;if(o.key&&""!==o.key)switch(s){case"radio":case"checkbox":if("magicfeedback-consent"===a||e.checked){o.value.push(r);const e=t.findIndex((e=>e.key===o.key));-1!==e?t[e].value=[...t[e].value,...o.value]:t.push(o)}break;default:if(""!==r){if("email"===s){if(!(0,n.validateEmail)(r)){this.log.err("Invalid email"),i=!0;break}this.feedback.profile.push({key:"email",value:[r]})}o.value.push(r);const e=t.findIndex((e=>e.key===o.key));console.log(e,t),-1!==e?t[e].value=[...t[e].value,...o.value]:t.push(o)}}})),this.feedback.answers=i?[]:t}pushAnswers(e=!1){var t,i;return s(this,void 0,void 0,(function*(){try{if(this.answer(),"MAGICFORM"===(null===(t=this.formData)||void 0===t?void 0:t.identity)){if(0===this.feedback.answers.length)throw new Error("No answers provided");this.questions.forEach((e=>{if(e.require&&!this.feedback.answers.find((t=>t.key===e.ref)))throw new Error(`No answer provided for question ${e.title}`)}))}else if(!e&&(null===(i=this.questionInProcess)||void 0===i?void 0:i.require)&&0===this.feedback.answers.length)throw new Error("No answers provided");const s=this.config.get("url"),a={integration:this.appId,publicKey:this.publicKey,feedback:this.feedback,completed:e};return yield(0,n.sendFeedback)(s,this.id?Object.assign(Object.assign({},a),{sessionId:this.id}):a,this.log)}catch(e){return this.log.err(`An error occurred while submitting the form ${this.appId}:`,e),""}}))}callFollowUpQuestion(e){return s(this,void 0,void 0,(function*(){if(!(null==e?void 0:e.followup))return null;try{if(0===this.feedback.answers.length)throw new Error("No answers provided");const t=this.config.get("url"),i={answer:this.feedback.answers[0].value[0],publicKey:this.publicKey,sessionId:this.id,question:e};return yield(0,n.getFollowUpQuestion)(t,i,this.log)}catch(e){throw this.log.err(`An error occurred while submitting the form ${this.appId}:`,e),e}}))}processNextQuestion(e,t){var i,a,n,r;return s(this,void 0,void 0,(function*(){if("MAGICSURVEY"===(null===(i=this.formData)||void 0===i?void 0:i.identity))if(null===(a=this.questionInProcess)||void 0===a?void 0:a.followup){const i=yield this.callFollowUpQuestion(this.questionInProcess);if(i){this.questionInProcess=i;const e=(0,o.renderQuestions)([i],null===(n=this.formOptionsConfig)||void 0===n?void 0:n.questionFormat,null===(r=this.formData)||void 0===r?void 0:r.lang[0])[0];this.history[this.progress].push({object:i,element:e}),t.removeChild(t.childNodes[0]),t.appendChild(e)}else this.renderNextQuestion(t,e)}else this.renderNextQuestion(t,e);else if(this.total=this.questions.length,this.progress=this.questions.length,this.formOptionsConfig.addSuccessScreen){e.childNodes.length>0&&e.removeChild(e.childNodes[0]);const t=(0,o.renderSuccess)(this.formOptionsConfig.successMessage||"Thank you for your feedback!");e.appendChild(t)}}))}renderNextQuestion(e,t){if(this.progress++,this.progress<this.total)this.questionInProcess=this.history[this.progress][0].object,e.removeChild(e.childNodes[0]),e.appendChild(this.history[this.progress][0].element);else{if(this.formOptionsConfig.addSuccessScreen){t.childNodes.length>0&&t.removeChild(t.childNodes[0]);const e=(0,o.renderSuccess)(this.formOptionsConfig.successMessage||"Thank you for your feedback!");t.appendChild(e)}this.pushAnswers(!0)}}back(){if(0===this.progress)return;const e=document.getElementById("magicfeedback-questions-"+this.appId);e.removeChild(e.childNodes[0]),this.history[this.progress].length>1?this.history[this.progress].pop():this.progress--;const t=this.history[this.progress][this.history[this.progress].length-1];this.questionInProcess=t.object,e.appendChild(t.element)}}},374:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.endpoints=void 0,t.endpoints={sdk:{app:(e,t)=>`sdk/app/${e}/${t}`,app_info:(e,t)=>`sdk/app/${e}/${t}/info`,feedback:"sdk/feedback",followUpQuestion:"sdk/followUpQuestion"}}},183:(e,t)=>{function i(e,t){return"object"==typeof e?e[t]||e.en:e}Object.defineProperty(t,"__esModule",{value:!0}),t.renderSuccess=t.renderError=t.renderActions=t.renderQuestions=void 0,t.renderQuestions=function e(t,s="standard",a="en"){if(!t)throw new Error("[MagicFeedback] No questions provided");const n=[];return t.forEach((t=>{var o,r;if((null===(r=null===(o=null==t?void 0:t.questionType)||void 0===o?void 0:o.conf)||void 0===r?void 0:r.length)>0){let i=document.createElement("div");i.classList.add("magicfeedback-div"),t.questionType.conf.forEach((e=>e.ref=t.ref)),e(t.questionType.conf,s,a).forEach((e=>{i.appendChild(e)})),n.push(i)}else{const e=function(e,t,s){const{id:a,title:n,type:o,ref:r,require:c,value:d,defaultValue:l,assets:u}=e;let p,h,m=document.createElement("div");switch(m.classList.add("magicfeedback-div"),o){case"TEXT":p=document.createElement("input"),p.type="text",p.placeholder="slim"===t?i(n,s):"Write your answer here...",h="magicfeedback-text";break;case"LONGTEXT":p=document.createElement("textarea"),p.rows=3,p.placeholder="slim"===t?i(n,s):"Write your answer here...",h="magicfeedback-longtext";break;case"NUMBER":p=document.createElement("input"),p.type="number",p.placeholder="slim"===t?i(n,s):"Insert a number here",h="magicfeedback-number",d.length&&(d.sort(((e,t)=>Number(e)-Number(t))),p.max=d[d.length-1],p.min=d[0],p.value=d[0]);break;case"RADIO":case"MULTIPLECHOICE":p=document.createElement("div"),h="magicfeedback-"+("MULTIPLECHOICE"===o?"checkbox":"radio"),d.forEach(((e,t)=>{const i=document.createElement("div");i.classList.add(`magicfeedback-${"MULTIPLECHOICE"===o?"checkbox":"radio"}-container`);const s=document.createElement("label"),a=document.createElement("input");a.id=`rating-${r}-${t}`,a.type="MULTIPLECHOICE"===o?"checkbox":"radio",a.name=r,a.value=e,a.classList.add(h),a.classList.add("magicfeedback-input"),e===l&&(a.checked=!0),s.textContent=e,s.htmlFor=`rating-${r}-${t}`,i.appendChild(a),i.appendChild(s),p.appendChild(i)}));break;case"BOOLEAN":p=document.createElement("div"),h="magicfeedback-radio";const e=document.createElement("div");e.classList.add("magicfeedback-boolean-container"),e.style.display="flex",e.style.flexDirection="row",e.style.justifyContent="space-between",e.style.width="70%",e.style.margin="auto",(u.addIcon?["✓","✗"]:function(e){switch(e){case"es":return["Sí","No"];case"fr":return["Oui","Non"];case"de":return["Ja","Nein"];case"it":return["Sì","No"];case"pt":return["Sim","Não"];case"nl":return["Ja","Nee"];case"pl":return["Tak","Nie"];case"ru":return["Да","Нет"];case"ja":return["はい","いいえ"];case"zh":return["是","不"];case"ko":return["예","아니"];case"da":case"sv":return["Ja","Nej"];case"fi":return["Kyllä","Ei"];case"no":return["Ja","Nei"];default:return["Yes","No"]}}(s)).forEach(((t,i)=>{const s=document.createElement("label");s.classList.add("magicfeedback-boolean-option"),s.htmlFor=`rating-${r}-${i}`,s.style.cursor="pointer",s.style.border="1px solid #000",s.style.display="flex",s.style.justifyContent="center",s.style.alignItems="center",s.style.margin="auto",s.style.padding="0",s.style.width="45%",s.style.height="38px";const a=document.createElement("label");a.htmlFor=`rating-${r}-${i}`,a.classList.add("magicfeedback-boolean-option-label-container"),a.style.margin="0",a.style.padding="0";const n=document.createElement("label");n.htmlFor=`rating-${r}-${i}`,n.textContent=t,n.style.margin="0",n.style.padding="0";const o=document.createElement("input");o.id=`rating-${r}-${i}`,o.type="radio",o.name=r,o.value=t,o.classList.add(h),o.classList.add("magicfeedback-input"),o.style.position="absolute",o.style.opacity="0",o.style.width="0",o.style.height="0",o.style.margin="0",a.appendChild(o),a.appendChild(n),s.appendChild(a),e.appendChild(s)})),p.appendChild(e);break;case"RATING_EMOJI":p=document.createElement("div"),h="magicfeedback-rating";const f=document.createElement("div");f.classList.add("magicfeedback-rating-container");const g=d.length?Number(d[d.length-1]):5;for(let e=d.length?Number(d[0]):1;e<=g;e++){const t=document.createElement("div");t.classList.add("magicfeedback-rating-option");const i=document.createElement("label");i.htmlFor=`rating-${r}-${e}`,i.classList.add("magicfeedback-rating-option-label-container");const s=document.createElement("label");s.htmlFor=`rating-${r}-${e}`,s.textContent=e.toString();const a=document.createElement("img");if(5===g)switch(e){case 1:a.src="https://magicfeedback-c6458-dev.web.app/assets/1.svg";break;case 2:a.src="https://magicfeedback-c6458-dev.web.app/assets/2.svg";break;case 3:a.src="https://magicfeedback-c6458-dev.web.app/assets/6.svg";break;case 4:a.src="https://magicfeedback-c6458-dev.web.app/assets/9.svg";break;case 5:a.src="https://magicfeedback-c6458-dev.web.app/assets/10.svg"}else a.src=`https://magicfeedback-c6458-dev.web.app/assets/${e}.svg`;a.alt=`face-${r}-${e}`,a.className=`rating-image${e}`;const n=document.createElement("input");n.id=`rating-${r}-${e}`,n.type="radio",n.name=r,n.value=e.toString(),n.classList.add(h),n.classList.add("magicfeedback-input"),i.appendChild(n),i.appendChild(a),i.appendChild(s),t.appendChild(i),f.appendChild(t)}p.appendChild(f);break;case"RATING_NUMBER":p=document.createElement("div"),h="magicfeedback-rating-number";const b=document.createElement("div");b.classList.add("magicfeedback-rating-number-container");const v=d.length?Number(d[d.length-1]):5;for(let e=d.length?Number(d[0]):1;e<=v;e++){const t=document.createElement("div");t.classList.add("magicfeedback-rating-number-option");const i=document.createElement("label");i.htmlFor=`rating-${r}-${e}`,i.classList.add("magicfeedback-rating-number-option-label-container");const s=document.createElement("label");s.htmlFor=`rating-${r}-${e}`,s.textContent=e.toString();const a=document.createElement("input");a.id=`rating-${r}-${e}`,a.type="radio",a.name=r,a.value=e.toString(),a.classList.add(h),a.classList.add("magicfeedback-input"),i.appendChild(a),i.appendChild(s),t.appendChild(i),b.appendChild(t)}p.appendChild(b);break;case"RATING_STAR":p=document.createElement("div"),h="magicfeedback-rating-star";const k=function(e){const t="magicfeedback-rating-star-selected",i=document.createElement("div");i.classList.add("magicfeedback-rating-star-container");for(let s=1;s<=5;s++){const a=document.createElement("label");a.classList.add("magicfeedback-rating-star-option");const n=document.createElement("input");n.id=`rating-${e}-${s}`,n.type="radio",n.name=e,n.value=s.toString(),n.style.position="absolute",n.style.opacity="0",n.style.width="0",n.style.height="0",n.classList.add("magicfeedback-input"),n.addEventListener("change",(()=>{const e=i.querySelectorAll(".rating__star");for(let i=0;i<e.length;i++)i+1<=Number(n.value)?e[i].classList.contains(t)||e[i].classList.add(t):e[i].classList.contains(t)&&e[i].classList.remove(t)})),a.appendChild(n);const o=document.createElement("label");o.htmlFor=`rating-${e}-${s}`,o.classList.add("rating__star"),o.textContent="★",o.style.fontSize="40px",o.style.color="#CCCCCC",o.style.cursor="pointer",a.appendChild(o),i.appendChild(a)}return i}(r);p.appendChild(k);break;case"MULTIPLECHOISE_IMAGE":p=document.createElement("div"),h="magicfeedback-multiple-choice-image";const y=document.createElement("div");y.classList.add("magicfeedback-multiple-choice-image-container"),y.style.display="flex",y.style.flexDirection="row",y.style.flexWrap="wrap",y.style.justifyContent="center";const E=d.length;let w=1,C=1;2===E?w=2:4===E?(w=2,C=2):6===E&&(w=3,C=2);const x=void 0!==u.addTitle&&u.addTitle;d.forEach((e=>{try{const{position:t,url:i,value:s}=JSON.parse(e),a=document.createElement("label");a.classList.add("magicfeedback-multiple-choice-image-option"),a.style.width=`calc( ${100/w}% - 10px)`,a.style.height=`calc( ${100/C}% - 10px)`,a.style.margin="5px";const n=document.createElement("label");n.htmlFor=`rating-${r}-${t}`,n.classList.add("magicfeedback-image-option-label-container"),n.style.display="flex",n.style.flexDirection="column",n.addEventListener("mouseover",(()=>{n.style.border="2px solid #000"})),n.addEventListener("mouseout",(()=>{n.style.border="none"})),n.addEventListener("click",(()=>{n.style.border="2px solid #000"}));const o=document.createElement("label");o.textContent=s,o.classList.add("magicfeedback-multiple-choice-image-label");const c=document.createElement("input");c.id=`rating-${r}-${t}`,c.type="radio",c.name=r,c.value=s,c.style.position="absolute",c.style.opacity="0",c.style.width="0",c.style.height="0",c.classList.add("magicfeedback-input");const d=document.createElement("img");d.classList.add("magicfeedback-multiple-choice-image-image"),d.src=i,d.style.cursor="pointer",d.style.backgroundSize="cover",d.style.width="100%",d.style.height="100%",d.style.margin="auto",n.appendChild(c),n.appendChild(d),x&&n.appendChild(o),a.appendChild(n),y.appendChild(a)}catch(e){console.error(e)}})),p.appendChild(y);break;case"SELECT":p=document.createElement("select"),h="magicfeedback-select";const L=document.createElement("option");L.value="",L.text="slim"===t?i(n,s):l||"Select an option",L.disabled=!0,L.selected=!0,p.appendChild(L),d.forEach((e=>{const t=document.createElement("option");t.value=e,t.text=e,p.appendChild(t)}));break;case"DATE":p=document.createElement("input"),p.type="date",p.required=c,p.placeholder="slim"===t?i(n,s):"Select a date",h="magicfeedback-date";break;case"CONSENT":p=document.createElement("input"),h="magicfeedback-consent",p.type="checkbox",p.id=`magicfeedback-${a}`,p.name=r,p.value="true",p.required=c,p.classList.add("magicfeedback-consent"),p.classList.add("magicfeedback-input");break;case"EMAIL":p=document.createElement("input"),p.type="email",p.required=c,p.placeholder="slim"===t?i(n,s):"you@example.com",h="magicfeedback-email";break;case"PASSWORD":p=document.createElement("input"),p.type="password",p.required=c,p.placeholder="slim"===t?i(n,s):"Write your password here",h="magicfeedback-password";break;default:return m}p.id=`magicfeedback-${a}`,p.setAttribute("name",r),p.classList.add(h),void 0!==l&&(p.value=l),["RADIO","MULTIPLECHOICE"].includes(o)||(p.classList.add("magicfeedback-input"),p.required=c);const f=document.createElement("label");if(f.setAttribute("for",`magicfeedback-${a}`),f.textContent=i(n,s),f.classList.add("magicfeedback-label"),["CONSENT"].includes(o))m.classList.add("magicfeedback-consent-container"),m.appendChild(p),m.appendChild(f);else{if("slim"!==t&&(m.appendChild(f),void 0!==(null==u?void 0:u.general)&&""!==(null==u?void 0:u.general))){const e=document.createElement("img");e.src=u.general,e.classList.add("magicfeedback-image"),e.style.maxWidth="auto",e.style.height="400px",e.style.margin="10px 0",m.appendChild(e)}m.appendChild(p)}return m}(t,s,a);n.push(e)}})),n},t.renderActions=function(e="",t,i="Submit",s="Back",a="Next"){const n=document.createElement("div");n.classList.add("magicfeedback-action-container");const o=document.createElement("button");o.id="magicfeedback-submit",o.type="submit",o.classList.add("magicfeedback-submit"),o.textContent="MAGICSURVEY"===e?a||"Next":i||"Submit";const r=document.createElement("button");return r.id="magicfeedback-back",r.type="button",r.classList.add("magicfeedback-back"),r.textContent=s||"Back",r.addEventListener("click",t),"MAGICSURVEY"===e&&n.appendChild(r),n.appendChild(o),n},t.renderError=function(e){const t=document.createElement("div");return t.classList.add("magicfeedback-error"),t.textContent=e,t},t.renderSuccess=function(e){const t=document.createElement("div");return t.classList.add("magicfeedback-success"),t.textContent=e,t}},341:function(e,t,i){var s=this&&this.__awaiter||function(e,t,i,s){return new(i||(i=Promise))((function(a,n){function o(e){try{c(s.next(e))}catch(e){n(e)}}function r(e){try{c(s.throw(e))}catch(e){n(e)}}function c(e){var t;e.done?a(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(o,r)}c((s=s.apply(e,t||[])).next())}))},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getFollowUpQuestion=t.sendFeedback=t.getQuestions=t.getForm=t.validateEmail=void 0;const n=a(i(31)),o=a(i(147)),r=i(374),c={Accept:"application/json","Magicfeedback-Sdk-Version":o.default.version};t.validateEmail=function(e){return/\S+@\S+\.\S+/.test(e)},t.getForm=function(e,t,i,a){return s(this,void 0,void 0,(function*(){try{const s=yield(0,n.default)(e+r.endpoints.sdk.app_info(t,i),{method:"GET",headers:c});if(s.ok){const e=yield s.json();return a.log(`Received form for app ${t}`,e),e}throw a.err(`Failed to get questions for app ${t}:`,s.status,s.statusText),new Error("[MagicFeedback] Bad response from server")}catch(e){return a.err(e),null}}))},t.getQuestions=function(e,t,i,a){return s(this,void 0,void 0,(function*(){try{const s=yield(0,n.default)(e+r.endpoints.sdk.app(t,i),{method:"GET",headers:c});if(s.ok){const e=yield s.json();return a.log(`Received questions for app ${t}`,e),e}throw a.err(`Failed to get questions for app ${t}:`,s.status,s.statusText),new Error("[MagicFeedback] Bad response from server")}catch(e){return a.err(e),[]}}))},t.sendFeedback=function(e,t,i){return s(this,void 0,void 0,(function*(){try{const s=yield(0,n.default)(e+r.endpoints.sdk.feedback,{method:"POST",headers:Object.assign({"Content-Type":"application/json"},c),body:JSON.stringify(t)});if(s.ok)return i.log(`Form ${t.integration} submitted successfully!`),(yield s.json()).sessionId;throw i.err(`Failed to submit form ${t.integration}:`,s.status,s.statusText),new Error(s.statusText)}catch(e){return i.err(e),""}}))},t.getFollowUpQuestion=function(e,t,i){return s(this,void 0,void 0,(function*(){try{const s=yield(0,n.default)(e+r.endpoints.sdk.followUpQuestion,{method:"POST",headers:Object.assign({"Content-Type":"application/json"},c),body:JSON.stringify(t)});if(s.ok)return i.log(`Received follow up question for form ${t.integration}`),(yield s.json())||"";throw i.err(`Failed to get follow up question for form ${t.integration}:`,s.status,s.statusText),new Error(s.statusText)}catch(e){return i.err(e),""}}))}},5:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Log=void 0,t.Log=class{constructor(e){this.config=e}log(...e){this.config.get("debug")&&console.log("[MagicFeedback]:",...e)}err(...e){console.error("[MagicFeedback]:",...e)}}},31:e=>{e.exports=require("cross-fetch")},147:e=>{e.exports=JSON.parse('{"name":"@magicfeedback/native","version":"1.1.16-beta.2","main":"./dist/magicfeedback-sdk.node.js","browser":"./dist/magicfeedback-sdk.browser.js","types":"./dist/types/src/index.d.ts","repository":{"type":"git","url":"git+ssh://git@github.com/MagicFeedback/magicfeedback-sdk.git"},"author":"farias@magicfeedback.io","license":"MIT","private":false,"scripts":{"dev":"vite","build":"webpack","build:watch":"webpack --watch --mode development","publish":"npm publish --access public","publish:beta":"npm publish --access public --tag beta","test":"jest","test:watch":"jest --watchAll","coverage":"vitest run --coverage"},"files":["dist"],"devDependencies":{"@babel/preset-typescript":"^7.22.5","@types/node":"^17.0.21","@types/webpack":"^5.28.0","@types/webpack-node-externals":"^2.5.3","c8":"^7.11.0","jest":"^29.5.0","jest-environment-jsdom":"^29.5.0","jest-fetch-mock":"^3.0.3","nock":"^13.2.4","ts-jest":"^29.1.0","ts-loader":"^9.2.7","ts-node":"^10.7.0","typescript":"^4.6.2","vite":"^2.8.0","vite-plugin-dts":"^0.9.9","vitest":"^0.5.9","webpack":"^5.70.0","webpack-cli":"^4.9.2","webpack-node-externals":"^3.0.0"},"dependencies":{"cross-fetch":"^3.1.5","is-bundling-for-browser-or-node":"^1.1.1"},"description":"MagicFeedbackAI JavaScript Library for [MagicFeedback.io](https://magicfeedback.io/)","bugs":{"url":"https://github.com/MagicFeedback/magicfeedback-sdk/issues"},"homepage":"https://github.com/MagicFeedback/magicfeedback-sdk#readme","directories":{"example":"examples","test":"test"}}')}},t={},i=function i(s){var a=t[s];if(void 0!==a)return a.exports;var n=t[s]={exports:{}};return e[s].call(n.exports,n,n.exports,i),n.exports}(607);return i.default})()));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magicfeedback/native",
3
- "version": "1.1.16-beta.1",
3
+ "version": "1.1.16-beta.2",
4
4
  "main": "./dist/magicfeedback-sdk.node.js",
5
5
  "browser": "./dist/magicfeedback-sdk.browser.js",
6
6
  "types": "./dist/types/src/index.d.ts",