@magicfeedback/native 1.0.4 → 1.0.6

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.
package/README.md CHANGED
@@ -4,7 +4,9 @@ MagicFeedback AI JavaScript Library for [MagicFeedback.io](https://magicfeedback
4
4
 
5
5
  ## Install
6
6
 
7
- This library is available as a [package on NPM](https://www.npmjs.com/package/@magicfeedback/native). To install into a project using NPM with a front-end packager such as [Browserify](http://browserify.org/) or [Webpack](https://webpack.github.io/):
7
+ This library is available as a [package on NPM](https://www.npmjs.com/package/@magicfeedback/native). To install into a
8
+ project using NPM with a front-end packager such as [Browserify](http://browserify.org/)
9
+ or [Webpack](https://webpack.github.io/):
8
10
 
9
11
  ```sh
10
12
  npm i @magicfeedback/native
@@ -33,37 +35,54 @@ magicfeedback.init({
33
35
  ```
34
36
 
35
37
  ## How to use
36
- This guide provides instructions for utilizing various features and functionalities of the application. Each section below highlights a specific use case and provides a code snippet to demonstrate its implementation.
38
+
39
+ This guide provides instructions for utilizing various features and functionalities of the application. Each section
40
+ below highlights a specific use case and provides a code snippet to demonstrate its implementation.
37
41
 
38
42
  ### A. Generate feedback forms
39
- The feedback form generation functionality allows you to easily create and display feedback forms on your website. This section provides an overview of how to use this feature and the necessary code snippets.
43
+
44
+ The feedback form generation functionality allows you to easily create and display feedback forms on your website. This
45
+ section provides an overview of how to use this feature and the necessary code snippets.
40
46
 
41
47
  To generate a feedback form, you need to include the following HTML code snippet in your web page:
42
48
 
43
49
  ```html
50
+
44
51
  <div id="demo_form_div"></div>
45
52
  ```
53
+
46
54
  This code snippet creates a placeholder element with the ID "demo_form_div" where the feedback form will be inserted.
47
55
 
48
56
  Next, you need to include the following JavaScript code snippet in your application:
49
57
 
50
58
  ```js
51
- let form = window.magicfeedback.form("$_APP_ID");
52
- form.generate("demo_form_div", {
53
- addButton: true | false // Default false
54
- beforeSubmitEvent: function(), //Function to execute before send the form
55
- afterSubmitEvent: function(response), //Function to execute after send the form with the response
56
- })
59
+ let form = window.magicfeedback.form(
60
+ "$_APP_ID",
61
+ "$_PUBLIC_KEY"
62
+ );
63
+
64
+ form.generate(
65
+ "demo_form_div",
66
+ {
67
+ addButton: true | false // Default false
68
+ beforeSubmitEvent: function (), //Function to execute before send the form
69
+ afterSubmitEvent: function (response), //Function to execute after send the form with the response
70
+ }
71
+ )
57
72
  ```
58
73
 
59
- In this code snippet, you need to replace $_APP_ID with the actual ID of your feedback application. This ID is provided by the magicfeedback service.
60
-
74
+ In this code snippet, you need to replace $_APP_ID with the actual ID of your feedback application. This ID is provided
75
+ by the magicfeedback service.
61
76
 
62
- The **form.generate()** function generates the feedback form inside the specified container element ("demo_form_div" in this example). You can customize the form generation by including the optional parameters:
77
+ The **form.generate()** function generates the feedback form inside the specified container element ("demo_form_div" in
78
+ this example). You can customize the form generation by including the optional parameters:
63
79
 
64
- * **addButton**: This setting determines whether to include a "Submit" button that enables users to submit the form themselves. By default, this value is set to false, indicating that the button will not be displayed.
65
- * **beforeSubmitEvent**: An optional function that you can define to execute some actions or validations before the form is submitted.
66
- * **afterSubmitEvent**: An optional function that you can define to execute actions after the form is submitted. This function receives the server response as a parameter.
80
+ * **addButton**: This setting determines whether to include a "Submit" button that enables users to submit the form
81
+ themselves. By default, this value is set to false, indicating that the button will not be displayed.
82
+ * **beforeSubmitEvent**: An optional function that you can define to execute some actions or validations before the form
83
+ is submitted.
84
+ * **afterSubmitEvent**: An optional function that you can define to execute actions after the form is submitted. This
85
+ function receives the server response as a parameter.
67
86
 
68
87
  Finally, to send the form, you can use the form.send() function.
69
88
 
@@ -75,40 +94,5 @@ This function triggers the submission of the generated feedback form.
75
94
 
76
95
  ![](./public/A_form.png)
77
96
 
78
- By following these steps and including the appropriate HTML and JavaScript code snippets, you can easily generate and display feedback forms on your website using the magicfeedback service.
79
-
80
- ### B. Send feedback directly
81
- The "Send feedback directly" functionality allows you to send user feedback data to the server without generating a feedback form. This section provides an overview of how to use this feature and the necessary code snippets.
82
-
83
- To send feedback directly, you need to include the following JavaScript code snippet in your application:
84
-
85
-
86
- ```js
87
-
88
- // Initialize an empty array to store user feedback answers
89
- const answers = [];
90
-
91
- // Add user feedback answer objects to the 'answers' array
92
- // Each answer object should have a 'id' key (string) and a 'value' key (array of string values)
93
- answers.push({ id: "rating", value: ["Ok"] });
94
- answers.push({ id: "improve", value: ["Maybe the interface is a bit slow on my OSX"] });
95
-
96
- // Create a profile object to store additional information
97
- // You can include any information you want in this object
98
- const profile = { email: "farias@magicfeedback.io" };
99
-
100
- // Send the user feedback data to the server
101
- // Make sure to provide the required App Id as a parameter
102
- magicfeedback.send("$_APP_ID", answers, profile);
103
-
104
- ```
105
-
106
- In this code snippet, you need to replace $_APP_ID with the actual ID of your feedback application. This ID is provided by the magicfeedback service.
107
-
108
- The answers array stores user feedback answer objects. Each answer object should have an id key, which represents the question or feedback category, and a value key, which holds an array of string values representing the user's response(s) to that question or category. You can add as many answer objects as needed to capture the user's feedback.
109
-
110
- Additionally, you can create a profile object to store additional information about the user. This object can include any information you want, such as the user's email, name, or any other relevant details.
111
-
112
- Finally, to send the user feedback data to the server, you can use the magicfeedback.send() function. This function takes three parameters: the App Id, the answers array, and the profile object. The App Id is required and identifies your feedback application within the magicfeedback service.
113
-
114
- By following these steps and including the appropriate JavaScript code snippet, you can send user feedback data directly to the server using the magicfeedback service.
97
+ By following these steps and including the appropriate HTML and JavaScript code snippets, you can easily generate and
98
+ display feedback forms on your website using the magicfeedback service.
@@ -47,7 +47,7 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo
47
47
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
48
48
 
49
49
  "use strict";
50
- 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 request_1 = __webpack_require__(/*! ./request */ \"./src/request.ts\");\nconst log_1 = __webpack_require__(/*! ./log */ \"./src/log.ts\");\nclass Form {\n /**\n *\n * @param config\n * @param appId\n */\n constructor(config, appId) {\n // Config\n this.config = config;\n this.request = new request_1.Request();\n this.log = new log_1.Log(config);\n // Attributes\n this.appId = appId;\n }\n /**\n * Generate\n * TODO: Check if is inside of a <form>\n * @param appId\n */\n generate(selector, options = {}) {\n //TODO: Check if already exist the form\n // Request question from the app\n this.request\n .get(`${this.config.get(\"url\")}/apps/${this.appId}/questions`, {})\n .then((appQuestions) => {\n if (appQuestions === undefined || !appQuestions) {\n this.log.err(`No questions for app ${this.appId}`);\n return;\n }\n // Create the from from the JSON\n this.generateForm(this.appId, appQuestions, selector, options);\n });\n }\n /**\n * Create\n * @param appId\n * @param appQuestions\n * @param selector\n * @param options\n *\n * TODO: Add option to generate in <form> or in other <tag>\n */\n generateForm(appId, appQuestions, selector, options = {}) {\n // Select the container\n const container = document.getElementById(selector);\n if (!container) {\n this.log.err(`Element with ID '${selector}' not found.`);\n return;\n }\n container.classList.add(\"magicfeedback-container\");\n // Create the form\n const form = document.createElement(\"form\");\n form.classList.add(\"magicfeedback-form\");\n form.id = \"magicfeedback-\" + appId;\n // Process questions and create in the form\n appQuestions.forEach((question) => {\n const { id, title, type, ref, require, \n //external_id,\n value, defaultValue, } = 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 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 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 elementTypeClass = \"magicfeedback-number\";\n if (value.length) {\n value.sort((a, b) => {\n let aa = Number(a);\n let bb = Number(b);\n return aa - bb;\n });\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 === \"RADIO\" ? \"radio\" : \"checkbox\");\n value.forEach((option) => {\n const label = document.createElement(\"label\");\n const input = document.createElement(\"input\");\n input.type = type === \"RADIO\" ? \"radio\" : \"checkbox\";\n input.name = ref;\n input.value = option;\n input.required = require;\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 element.appendChild(input);\n element.appendChild(label);\n });\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 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 elementTypeClass = \"magicfeedback-date\";\n break;\n case \"BOOLEAN\":\n // Create an input element with type \"checkbox\" for BOOLEAN type\n element = document.createElement(\"input\");\n element.type = \"checkbox\";\n elementTypeClass = \"magicfeedback-boolean\";\n break;\n default:\n return; // Skip unknown types\n }\n element.id = `magicfeedback-${id}`;\n element.setAttribute(\"name\", ref);\n if (defaultValue !== undefined) {\n element.value = defaultValue;\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 = title;\n label.classList.add(\"magicfeedback-label\");\n elementContainer.appendChild(label);\n element.classList.add(elementTypeClass);\n if (type != \"RADIO\" && type != \"MULTIPLECHOICE\") {\n element.classList.add(\"magicfeedback-input\");\n element.required = require;\n }\n elementContainer.appendChild(element);\n form.appendChild(elementContainer);\n });\n // Submit button\n if (options.addButton) {\n // Create a submit button if specified in options\n const submitButton = document.createElement(\"button\");\n submitButton.type = \"submit\";\n submitButton.textContent = \"Submit\";\n submitButton.classList.add(\"magicfeedback-submit\");\n form.appendChild(submitButton);\n }\n // Add the form to the specified container\n container.appendChild(form);\n // Submit event\n form.addEventListener(\"submit\", (event) => __awaiter(this, void 0, void 0, function* () {\n event.preventDefault();\n try {\n // BEFORE\n if (options.beforeSubmitEvent) {\n yield options.beforeSubmitEvent();\n }\n // SEND\n const response = yield this.send();\n // AFTER\n if (options.afterSubmitEvent) {\n yield options.afterSubmitEvent(response);\n }\n return response;\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 // You can perform error handling logic here if needed\n return error;\n }\n }));\n }\n /**\n * Answer\n * @param appId\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 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 required = (input as HTMLInputElement).required;\n const ans = {\n id: input.name,\n type: inputType,\n value: [],\n };\n const value = input.value;\n if (inputType === \"radio\" || inputType === \"checkbox\") {\n if (input.checked) {\n ans.value.push(value);\n surveyAnswers.push(ans);\n }\n }\n else {\n ans.value.push(value);\n surveyAnswers.push(ans);\n }\n });\n if (hasError) {\n return []; // Stop the process if there's an error\n }\n return surveyAnswers;\n }\n /**\n * Send\n * @returns\n */\n send() {\n return __awaiter(this, void 0, void 0, function* () {\n // Define the URL and request payload\n const url = `${this.config.get(\"url\")}/feedback/apps`;\n try {\n // Get the survey answers from the answer() function\n const surveyAnswers = this.answer();\n if (surveyAnswers.length === 0) {\n throw new Error(\"No answers provided\");\n }\n // Make the AJAX POST request\n const response = yield this.request.post(url, {\n appId: this.appId,\n answers: surveyAnswers,\n });\n if (response.ok) {\n // Handle success response\n this.log.log(`Form ${this.appId} submitted successfully!`);\n // You can perform additional actions here if needed\n }\n else {\n // Handle error response\n this.log.err(`Failed to submit form ${this.appId}:`, response.status, response.statusText);\n throw new Error(response.statusText);\n }\n return response;\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}\nexports.Form = Form;\n\n\n//# sourceURL=webpack://magicfeedback/./src/form.ts?");
50
+ 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 request_1 = __webpack_require__(/*! ./request */ \"./src/request.ts\");\nconst log_1 = __webpack_require__(/*! ./log */ \"./src/log.ts\");\nclass Form {\n /**\n *\n * @param config\n * @param appId\n */\n constructor(config, appId) {\n // Config\n this.config = config;\n this.request = new request_1.Request();\n this.log = new log_1.Log(config);\n // Attributes\n this.appId = appId;\n }\n /**\n * Generate\n * TODO: Check if is inside of a <form>\n * @param appId\n */\n generate(selector, options = {}) {\n //TODO: Check if already exist the form\n // Request question from the app\n this.request\n .get(`${this.config.get(\"url\")}/apps/${this.appId}/questions`, {})\n .then((appQuestions) => {\n if (appQuestions === undefined || !appQuestions) {\n this.log.err(`No questions for app ${this.appId}`);\n return;\n }\n // Create the from from the JSON\n this.generateForm(this.appId, appQuestions, selector, options);\n });\n }\n /**\n * Create\n * @param appId\n * @param appQuestions\n * @param selector\n * @param options\n *\n * TODO: Add option to generate in <form> or in other <tag>\n */\n generateForm(appId, appQuestions, selector, options = {}) {\n // Select the container\n const container = document.getElementById(selector);\n if (!container) {\n this.log.err(`Element with ID '${selector}' not found.`);\n return;\n }\n container.classList.add(\"magicfeedback-container\");\n // Create the form\n const form = document.createElement(\"form\");\n form.classList.add(\"magicfeedback-form\");\n form.id = \"magicfeedback-\" + appId;\n // Process questions and create in the form\n appQuestions.forEach((question) => {\n const { id, title, type, ref, require, \n //external_id,\n value, defaultValue, } = question;\n this.log.log(\"Question\", 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 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 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 elementTypeClass = \"magicfeedback-number\";\n if (value.length) {\n value.sort((a, b) => {\n let aa = Number(a);\n let bb = Number(b);\n return aa - bb;\n });\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 === \"RADIO\" ? \"radio\" : \"checkbox\");\n value.forEach((option) => {\n const label = document.createElement(\"label\");\n const input = document.createElement(\"input\");\n input.type = type === \"RADIO\" ? \"radio\" : \"checkbox\";\n input.name = ref;\n input.value = option;\n input.required =\n require.toLocaleLowerCase() === \"true\" ? true : false;\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 element.appendChild(input);\n element.appendChild(label);\n });\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 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 elementTypeClass = \"magicfeedback-date\";\n break;\n case \"BOOLEAN\":\n // Create an input element with type \"checkbox\" for BOOLEAN type\n element = document.createElement(\"input\");\n element.type = \"checkbox\";\n elementTypeClass = \"magicfeedback-boolean\";\n break;\n default:\n return; // Skip unknown types\n }\n element.id = `magicfeedback-${id}`;\n element.setAttribute(\"name\", ref);\n if (defaultValue !== undefined) {\n element.value = defaultValue;\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 = title;\n label.classList.add(\"magicfeedback-label\");\n elementContainer.appendChild(label);\n element.classList.add(elementTypeClass);\n if (type != \"RADIO\" && type != \"MULTIPLECHOICE\") {\n element.classList.add(\"magicfeedback-input\");\n element.required =\n require.toLocaleLowerCase() === \"true\" ? true : false;\n }\n elementContainer.appendChild(element);\n form.appendChild(elementContainer);\n });\n // Submit button\n if (options.addButton) {\n // Create a submit button if specified in options\n const submitButton = document.createElement(\"button\");\n submitButton.type = \"submit\";\n submitButton.textContent = \"Submit\";\n submitButton.classList.add(\"magicfeedback-submit\");\n form.appendChild(submitButton);\n }\n // Add the form to the specified container\n container.appendChild(form);\n // Submit event\n form.addEventListener(\"submit\", (event) => __awaiter(this, void 0, void 0, function* () {\n event.preventDefault();\n try {\n // BEFORE\n if (options.beforeSubmitEvent) {\n yield options.beforeSubmitEvent();\n }\n // SEND\n const response = yield this.send();\n // AFTER\n if (options.afterSubmitEvent) {\n yield options.afterSubmitEvent(response);\n }\n return response;\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 // You can perform error handling logic here if needed\n return error;\n }\n }));\n }\n /**\n * Answer\n * @param appId\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 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 required = (input as HTMLInputElement).required;\n const ans = {\n id: input.name,\n type: inputType,\n value: [],\n };\n const value = input.value;\n if (inputType === \"radio\" || inputType === \"checkbox\") {\n if (input.checked) {\n ans.value.push(value);\n surveyAnswers.push(ans);\n }\n }\n else {\n ans.value.push(value);\n surveyAnswers.push(ans);\n }\n });\n if (hasError) {\n return []; // Stop the process if there's an error\n }\n return surveyAnswers;\n }\n /**\n * Send\n * @returns\n */\n send() {\n return __awaiter(this, void 0, void 0, function* () {\n // Define the URL and request payload\n const url = `${this.config.get(\"url\")}/feedback/apps`;\n try {\n // Get the survey answers from the answer() function\n const surveyAnswers = this.answer();\n if (surveyAnswers.length === 0) {\n throw new Error(\"No answers provided\");\n }\n // Make the AJAX POST request\n const response = yield this.request.post(url, {\n appId: this.appId,\n answers: surveyAnswers,\n });\n if (response.ok) {\n // Handle success response\n this.log.log(`Form ${this.appId} submitted successfully!`);\n // You can perform additional actions here if needed\n }\n else {\n // Handle error response\n this.log.err(`Failed to submit form ${this.appId}:`, response.status, response.statusText);\n throw new Error(response.statusText);\n }\n return response;\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}\nexports.Form = Form;\n\n\n//# sourceURL=webpack://magicfeedback/./src/form.ts?");
51
51
 
52
52
  /***/ }),
53
53
 
@@ -80,7 +80,7 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo
80
80
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
81
81
 
82
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 }));\nconst request_1 = __webpack_require__(/*! ./request */ \"./src/request.ts\");\nconst form_1 = __webpack_require__(/*! ./form */ \"./src/form.ts\");\nconst config_1 = __webpack_require__(/*! ./config */ \"./src/config.ts\");\nconst log_1 = __webpack_require__(/*! ./log */ \"./src/log.ts\");\n/**\n *\n * @returns\n */\nfunction main() {\n //===============================================\n // Attributes\n //===============================================\n const config = new config_1.Config();\n const request = new request_1.Request();\n let log;\n //===============================================\n // Private\n //===============================================\n //===============================================\n // Public\n //===============================================\n /**\n *\n * @param options\n */\n function init(options) {\n if (options === null || options === void 0 ? void 0 : options.url)\n config.set(\"url\", options === null || options === void 0 ? void 0 : options.url);\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 log = new log_1.Log(config);\n log.log(\"Initialized Magicfeedback\", options);\n }\n /**\n *\n * @param appId\n * @param answers\n * @param profile\n * @returns\n */\n function send(appId, answers, profile) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!appId)\n log.err(\"No appID provided\");\n if (!answers)\n log.err(\"No answers provided\");\n if (answers.length == 0)\n log.err(\"Answers are empty\");\n const payload = {\n appId: appId,\n answers: answers,\n };\n if (profile)\n payload.profile = profile;\n let res = {};\n try {\n res = yield request.post(`${config.get(\"url\")}/feedback/apps`, payload);\n log.log(`sent native feedback`, res);\n }\n catch (e) {\n log.err(`error native feedback`, e);\n }\n return res;\n });\n }\n /**\n *\n * @param appId\n * @returns\n */\n function form(appId) {\n if (!appId)\n log.err(\"No appID provided\");\n return new form_1.Form(config, appId);\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?");
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 }));\nconst request_1 = __webpack_require__(/*! ./request */ \"./src/request.ts\");\nconst form_1 = __webpack_require__(/*! ./form */ \"./src/form.ts\");\nconst config_1 = __webpack_require__(/*! ./config */ \"./src/config.ts\");\nconst log_1 = __webpack_require__(/*! ./log */ \"./src/log.ts\");\n/**\n *\n * @returns\n */\nfunction main() {\n //===============================================\n // Attributes\n //===============================================\n const config = new config_1.Config();\n const request = new request_1.Request();\n let log;\n //===============================================\n // Private\n //===============================================\n //===============================================\n // Public\n //===============================================\n /**\n *\n * @param options\n */\n function init(options) {\n if (options === null || options === void 0 ? void 0 : options.url)\n config.set(\"url\", options === null || options === void 0 ? void 0 : options.url);\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 log = new log_1.Log(config);\n log.log(\"Initialized Magicfeedback\", config);\n }\n /**\n *\n * @param appId\n * @param answers\n * @param profile\n * @returns\n */\n function send(appId, answers, profile) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!appId)\n log.err(\"No appID provided\");\n if (!answers)\n log.err(\"No answers provided\");\n if (answers.length == 0)\n log.err(\"Answers are empty\");\n const payload = {\n appId: appId,\n answers: answers,\n };\n if (profile)\n payload.profile = profile;\n let res = {};\n try {\n res = yield request.post(`${config.get(\"url\")}/feedback/apps`, payload);\n log.log(`sent native feedback`, res);\n }\n catch (e) {\n log.err(`error native feedback`, e);\n }\n return res;\n });\n }\n /**\n *\n * @param appId\n * @returns\n */\n function form(appId) {\n if (!appId)\n log.err(\"No appID provided\");\n return new form_1.Form(config, appId);\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?");
84
84
 
85
85
  /***/ }),
86
86
 
@@ -102,7 +102,7 @@ eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _argument
102
102
  /***/ ((module) => {
103
103
 
104
104
  "use strict";
105
- eval("module.exports = JSON.parse('{\"name\":\"@magicfeedback/native\",\"version\":\"1.0.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\",\"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?");
105
+ eval("module.exports = JSON.parse('{\"name\":\"@magicfeedback/native\",\"version\":\"1.0.5\",\"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\",\"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?");
106
106
 
107
107
  /***/ })
108
108
 
@@ -36,7 +36,7 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo
36
36
  \*********************/
37
37
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
38
38
 
39
- 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 request_1 = __webpack_require__(/*! ./request */ \"./src/request.ts\");\nconst log_1 = __webpack_require__(/*! ./log */ \"./src/log.ts\");\nclass Form {\n /**\n *\n * @param config\n * @param appId\n */\n constructor(config, appId) {\n // Config\n this.config = config;\n this.request = new request_1.Request();\n this.log = new log_1.Log(config);\n // Attributes\n this.appId = appId;\n }\n /**\n * Generate\n * TODO: Check if is inside of a <form>\n * @param appId\n */\n generate(selector, options = {}) {\n //TODO: Check if already exist the form\n // Request question from the app\n this.request\n .get(`${this.config.get(\"url\")}/apps/${this.appId}/questions`, {})\n .then((appQuestions) => {\n if (appQuestions === undefined || !appQuestions) {\n this.log.err(`No questions for app ${this.appId}`);\n return;\n }\n // Create the from from the JSON\n this.generateForm(this.appId, appQuestions, selector, options);\n });\n }\n /**\n * Create\n * @param appId\n * @param appQuestions\n * @param selector\n * @param options\n *\n * TODO: Add option to generate in <form> or in other <tag>\n */\n generateForm(appId, appQuestions, selector, options = {}) {\n // Select the container\n const container = document.getElementById(selector);\n if (!container) {\n this.log.err(`Element with ID '${selector}' not found.`);\n return;\n }\n container.classList.add(\"magicfeedback-container\");\n // Create the form\n const form = document.createElement(\"form\");\n form.classList.add(\"magicfeedback-form\");\n form.id = \"magicfeedback-\" + appId;\n // Process questions and create in the form\n appQuestions.forEach((question) => {\n const { id, title, type, ref, require, \n //external_id,\n value, defaultValue, } = 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 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 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 elementTypeClass = \"magicfeedback-number\";\n if (value.length) {\n value.sort((a, b) => {\n let aa = Number(a);\n let bb = Number(b);\n return aa - bb;\n });\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 === \"RADIO\" ? \"radio\" : \"checkbox\");\n value.forEach((option) => {\n const label = document.createElement(\"label\");\n const input = document.createElement(\"input\");\n input.type = type === \"RADIO\" ? \"radio\" : \"checkbox\";\n input.name = ref;\n input.value = option;\n input.required = require;\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 element.appendChild(input);\n element.appendChild(label);\n });\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 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 elementTypeClass = \"magicfeedback-date\";\n break;\n case \"BOOLEAN\":\n // Create an input element with type \"checkbox\" for BOOLEAN type\n element = document.createElement(\"input\");\n element.type = \"checkbox\";\n elementTypeClass = \"magicfeedback-boolean\";\n break;\n default:\n return; // Skip unknown types\n }\n element.id = `magicfeedback-${id}`;\n element.setAttribute(\"name\", ref);\n if (defaultValue !== undefined) {\n element.value = defaultValue;\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 = title;\n label.classList.add(\"magicfeedback-label\");\n elementContainer.appendChild(label);\n element.classList.add(elementTypeClass);\n if (type != \"RADIO\" && type != \"MULTIPLECHOICE\") {\n element.classList.add(\"magicfeedback-input\");\n element.required = require;\n }\n elementContainer.appendChild(element);\n form.appendChild(elementContainer);\n });\n // Submit button\n if (options.addButton) {\n // Create a submit button if specified in options\n const submitButton = document.createElement(\"button\");\n submitButton.type = \"submit\";\n submitButton.textContent = \"Submit\";\n submitButton.classList.add(\"magicfeedback-submit\");\n form.appendChild(submitButton);\n }\n // Add the form to the specified container\n container.appendChild(form);\n // Submit event\n form.addEventListener(\"submit\", (event) => __awaiter(this, void 0, void 0, function* () {\n event.preventDefault();\n try {\n // BEFORE\n if (options.beforeSubmitEvent) {\n yield options.beforeSubmitEvent();\n }\n // SEND\n const response = yield this.send();\n // AFTER\n if (options.afterSubmitEvent) {\n yield options.afterSubmitEvent(response);\n }\n return response;\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 // You can perform error handling logic here if needed\n return error;\n }\n }));\n }\n /**\n * Answer\n * @param appId\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 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 required = (input as HTMLInputElement).required;\n const ans = {\n id: input.name,\n type: inputType,\n value: [],\n };\n const value = input.value;\n if (inputType === \"radio\" || inputType === \"checkbox\") {\n if (input.checked) {\n ans.value.push(value);\n surveyAnswers.push(ans);\n }\n }\n else {\n ans.value.push(value);\n surveyAnswers.push(ans);\n }\n });\n if (hasError) {\n return []; // Stop the process if there's an error\n }\n return surveyAnswers;\n }\n /**\n * Send\n * @returns\n */\n send() {\n return __awaiter(this, void 0, void 0, function* () {\n // Define the URL and request payload\n const url = `${this.config.get(\"url\")}/feedback/apps`;\n try {\n // Get the survey answers from the answer() function\n const surveyAnswers = this.answer();\n if (surveyAnswers.length === 0) {\n throw new Error(\"No answers provided\");\n }\n // Make the AJAX POST request\n const response = yield this.request.post(url, {\n appId: this.appId,\n answers: surveyAnswers,\n });\n if (response.ok) {\n // Handle success response\n this.log.log(`Form ${this.appId} submitted successfully!`);\n // You can perform additional actions here if needed\n }\n else {\n // Handle error response\n this.log.err(`Failed to submit form ${this.appId}:`, response.status, response.statusText);\n throw new Error(response.statusText);\n }\n return response;\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}\nexports.Form = Form;\n\n\n//# sourceURL=webpack://magicfeedback/./src/form.ts?");
39
+ 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 request_1 = __webpack_require__(/*! ./request */ \"./src/request.ts\");\nconst log_1 = __webpack_require__(/*! ./log */ \"./src/log.ts\");\nclass Form {\n /**\n *\n * @param config\n * @param appId\n */\n constructor(config, appId) {\n // Config\n this.config = config;\n this.request = new request_1.Request();\n this.log = new log_1.Log(config);\n // Attributes\n this.appId = appId;\n }\n /**\n * Generate\n * TODO: Check if is inside of a <form>\n * @param appId\n */\n generate(selector, options = {}) {\n //TODO: Check if already exist the form\n // Request question from the app\n this.request\n .get(`${this.config.get(\"url\")}/apps/${this.appId}/questions`, {})\n .then((appQuestions) => {\n if (appQuestions === undefined || !appQuestions) {\n this.log.err(`No questions for app ${this.appId}`);\n return;\n }\n // Create the from from the JSON\n this.generateForm(this.appId, appQuestions, selector, options);\n });\n }\n /**\n * Create\n * @param appId\n * @param appQuestions\n * @param selector\n * @param options\n *\n * TODO: Add option to generate in <form> or in other <tag>\n */\n generateForm(appId, appQuestions, selector, options = {}) {\n // Select the container\n const container = document.getElementById(selector);\n if (!container) {\n this.log.err(`Element with ID '${selector}' not found.`);\n return;\n }\n container.classList.add(\"magicfeedback-container\");\n // Create the form\n const form = document.createElement(\"form\");\n form.classList.add(\"magicfeedback-form\");\n form.id = \"magicfeedback-\" + appId;\n // Process questions and create in the form\n appQuestions.forEach((question) => {\n const { id, title, type, ref, require, \n //external_id,\n value, defaultValue, } = question;\n this.log.log(\"Question\", 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 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 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 elementTypeClass = \"magicfeedback-number\";\n if (value.length) {\n value.sort((a, b) => {\n let aa = Number(a);\n let bb = Number(b);\n return aa - bb;\n });\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 === \"RADIO\" ? \"radio\" : \"checkbox\");\n value.forEach((option) => {\n const label = document.createElement(\"label\");\n const input = document.createElement(\"input\");\n input.type = type === \"RADIO\" ? \"radio\" : \"checkbox\";\n input.name = ref;\n input.value = option;\n input.required =\n require.toLocaleLowerCase() === \"true\" ? true : false;\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 element.appendChild(input);\n element.appendChild(label);\n });\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 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 elementTypeClass = \"magicfeedback-date\";\n break;\n case \"BOOLEAN\":\n // Create an input element with type \"checkbox\" for BOOLEAN type\n element = document.createElement(\"input\");\n element.type = \"checkbox\";\n elementTypeClass = \"magicfeedback-boolean\";\n break;\n default:\n return; // Skip unknown types\n }\n element.id = `magicfeedback-${id}`;\n element.setAttribute(\"name\", ref);\n if (defaultValue !== undefined) {\n element.value = defaultValue;\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 = title;\n label.classList.add(\"magicfeedback-label\");\n elementContainer.appendChild(label);\n element.classList.add(elementTypeClass);\n if (type != \"RADIO\" && type != \"MULTIPLECHOICE\") {\n element.classList.add(\"magicfeedback-input\");\n element.required =\n require.toLocaleLowerCase() === \"true\" ? true : false;\n }\n elementContainer.appendChild(element);\n form.appendChild(elementContainer);\n });\n // Submit button\n if (options.addButton) {\n // Create a submit button if specified in options\n const submitButton = document.createElement(\"button\");\n submitButton.type = \"submit\";\n submitButton.textContent = \"Submit\";\n submitButton.classList.add(\"magicfeedback-submit\");\n form.appendChild(submitButton);\n }\n // Add the form to the specified container\n container.appendChild(form);\n // Submit event\n form.addEventListener(\"submit\", (event) => __awaiter(this, void 0, void 0, function* () {\n event.preventDefault();\n try {\n // BEFORE\n if (options.beforeSubmitEvent) {\n yield options.beforeSubmitEvent();\n }\n // SEND\n const response = yield this.send();\n // AFTER\n if (options.afterSubmitEvent) {\n yield options.afterSubmitEvent(response);\n }\n return response;\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 // You can perform error handling logic here if needed\n return error;\n }\n }));\n }\n /**\n * Answer\n * @param appId\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 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 required = (input as HTMLInputElement).required;\n const ans = {\n id: input.name,\n type: inputType,\n value: [],\n };\n const value = input.value;\n if (inputType === \"radio\" || inputType === \"checkbox\") {\n if (input.checked) {\n ans.value.push(value);\n surveyAnswers.push(ans);\n }\n }\n else {\n ans.value.push(value);\n surveyAnswers.push(ans);\n }\n });\n if (hasError) {\n return []; // Stop the process if there's an error\n }\n return surveyAnswers;\n }\n /**\n * Send\n * @returns\n */\n send() {\n return __awaiter(this, void 0, void 0, function* () {\n // Define the URL and request payload\n const url = `${this.config.get(\"url\")}/feedback/apps`;\n try {\n // Get the survey answers from the answer() function\n const surveyAnswers = this.answer();\n if (surveyAnswers.length === 0) {\n throw new Error(\"No answers provided\");\n }\n // Make the AJAX POST request\n const response = yield this.request.post(url, {\n appId: this.appId,\n answers: surveyAnswers,\n });\n if (response.ok) {\n // Handle success response\n this.log.log(`Form ${this.appId} submitted successfully!`);\n // You can perform additional actions here if needed\n }\n else {\n // Handle error response\n this.log.err(`Failed to submit form ${this.appId}:`, response.status, response.statusText);\n throw new Error(response.statusText);\n }\n return response;\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}\nexports.Form = Form;\n\n\n//# sourceURL=webpack://magicfeedback/./src/form.ts?");
40
40
 
41
41
  /***/ }),
42
42
 
@@ -66,7 +66,7 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo
66
66
  \*********************/
67
67
  /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
68
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 }));\nconst request_1 = __webpack_require__(/*! ./request */ \"./src/request.ts\");\nconst form_1 = __webpack_require__(/*! ./form */ \"./src/form.ts\");\nconst config_1 = __webpack_require__(/*! ./config */ \"./src/config.ts\");\nconst log_1 = __webpack_require__(/*! ./log */ \"./src/log.ts\");\n/**\n *\n * @returns\n */\nfunction main() {\n //===============================================\n // Attributes\n //===============================================\n const config = new config_1.Config();\n const request = new request_1.Request();\n let log;\n //===============================================\n // Private\n //===============================================\n //===============================================\n // Public\n //===============================================\n /**\n *\n * @param options\n */\n function init(options) {\n if (options === null || options === void 0 ? void 0 : options.url)\n config.set(\"url\", options === null || options === void 0 ? void 0 : options.url);\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 log = new log_1.Log(config);\n log.log(\"Initialized Magicfeedback\", options);\n }\n /**\n *\n * @param appId\n * @param answers\n * @param profile\n * @returns\n */\n function send(appId, answers, profile) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!appId)\n log.err(\"No appID provided\");\n if (!answers)\n log.err(\"No answers provided\");\n if (answers.length == 0)\n log.err(\"Answers are empty\");\n const payload = {\n appId: appId,\n answers: answers,\n };\n if (profile)\n payload.profile = profile;\n let res = {};\n try {\n res = yield request.post(`${config.get(\"url\")}/feedback/apps`, payload);\n log.log(`sent native feedback`, res);\n }\n catch (e) {\n log.err(`error native feedback`, e);\n }\n return res;\n });\n }\n /**\n *\n * @param appId\n * @returns\n */\n function form(appId) {\n if (!appId)\n log.err(\"No appID provided\");\n return new form_1.Form(config, appId);\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?");
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 }));\nconst request_1 = __webpack_require__(/*! ./request */ \"./src/request.ts\");\nconst form_1 = __webpack_require__(/*! ./form */ \"./src/form.ts\");\nconst config_1 = __webpack_require__(/*! ./config */ \"./src/config.ts\");\nconst log_1 = __webpack_require__(/*! ./log */ \"./src/log.ts\");\n/**\n *\n * @returns\n */\nfunction main() {\n //===============================================\n // Attributes\n //===============================================\n const config = new config_1.Config();\n const request = new request_1.Request();\n let log;\n //===============================================\n // Private\n //===============================================\n //===============================================\n // Public\n //===============================================\n /**\n *\n * @param options\n */\n function init(options) {\n if (options === null || options === void 0 ? void 0 : options.url)\n config.set(\"url\", options === null || options === void 0 ? void 0 : options.url);\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 log = new log_1.Log(config);\n log.log(\"Initialized Magicfeedback\", config);\n }\n /**\n *\n * @param appId\n * @param answers\n * @param profile\n * @returns\n */\n function send(appId, answers, profile) {\n return __awaiter(this, void 0, void 0, function* () {\n if (!appId)\n log.err(\"No appID provided\");\n if (!answers)\n log.err(\"No answers provided\");\n if (answers.length == 0)\n log.err(\"Answers are empty\");\n const payload = {\n appId: appId,\n answers: answers,\n };\n if (profile)\n payload.profile = profile;\n let res = {};\n try {\n res = yield request.post(`${config.get(\"url\")}/feedback/apps`, payload);\n log.log(`sent native feedback`, res);\n }\n catch (e) {\n log.err(`error native feedback`, e);\n }\n return res;\n });\n }\n /**\n *\n * @param appId\n * @returns\n */\n function form(appId) {\n if (!appId)\n log.err(\"No appID provided\");\n return new form_1.Form(config, appId);\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?");
70
70
 
71
71
  /***/ }),
72
72
 
@@ -96,7 +96,7 @@ module.exports = require("cross-fetch");
96
96
  \**********************/
97
97
  /***/ ((module) => {
98
98
 
99
- eval("module.exports = JSON.parse('{\"name\":\"@magicfeedback/native\",\"version\":\"1.0.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\",\"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?");
99
+ eval("module.exports = JSON.parse('{\"name\":\"@magicfeedback/native\",\"version\":\"1.0.5\",\"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\",\"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?");
100
100
 
101
101
  /***/ })
102
102
 
@@ -31,7 +31,7 @@ export type NativeQuestion = {
31
31
  title: string;
32
32
  type: FEEDBACKAPPANSWERTYPE;
33
33
  ref: string;
34
- require: boolean;
34
+ require: string;
35
35
  external_id: string;
36
36
  value: string[];
37
37
  defaultValue: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magicfeedback/native",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
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",