slicejs-cli 1.0.0

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.
Files changed (24) hide show
  1. package/PROJECT_TEMPLATES/Basic/Components/Service/FetchManager/FetchManager.js +62 -0
  2. package/PROJECT_TEMPLATES/Basic/Components/Service/IndexedDbManager/IndexedDbManager.js +138 -0
  3. package/PROJECT_TEMPLATES/Basic/Components/Service/LocalStorageManager/LocalStorageManager.js +45 -0
  4. package/PROJECT_TEMPLATES/Basic/Components/Service/Translator/Translator.js +59 -0
  5. package/PROJECT_TEMPLATES/Basic/Components/Structural/Controller/Controller.js +108 -0
  6. package/PROJECT_TEMPLATES/Basic/Components/Structural/Debugger/Debugger.css +58 -0
  7. package/PROJECT_TEMPLATES/Basic/Components/Structural/Debugger/Debugger.html +6 -0
  8. package/PROJECT_TEMPLATES/Basic/Components/Structural/Debugger/Debugger.js +177 -0
  9. package/PROJECT_TEMPLATES/Basic/Components/Structural/Logger/Log.js +10 -0
  10. package/PROJECT_TEMPLATES/Basic/Components/Structural/Logger/Logger.js +112 -0
  11. package/PROJECT_TEMPLATES/Basic/Components/Structural/StylesManager/CustomStylesManager/CustomStylesManager.js +52 -0
  12. package/PROJECT_TEMPLATES/Basic/Components/Structural/StylesManager/StylesManager.js +38 -0
  13. package/PROJECT_TEMPLATES/Basic/Components/Structural/StylesManager/ThemeManager/ThemeManager.js +25 -0
  14. package/PROJECT_TEMPLATES/Basic/Slice.js +172 -0
  15. package/PROJECT_TEMPLATES/Basic/sliceConfig.json +24 -0
  16. package/client.js +54 -0
  17. package/commands/createComponent/componentTemplate.js +30 -0
  18. package/commands/createComponent/createComponent.js +84 -0
  19. package/commands/init/init.js +34 -0
  20. package/commands/listComponents/listComponents.js +41 -0
  21. package/commands/modifyComponent/modifyComponent copy.js +111 -0
  22. package/commands/modifyComponent/modifyComponent.js +158 -0
  23. package/package.json +23 -0
  24. package/postInstall.js +27 -0
@@ -0,0 +1,62 @@
1
+ export default class FetchManager {
2
+ constructor(baseUrl, timeout) {
3
+ if(baseUrl != undefined){
4
+ this.url = baseUrl;
5
+ }
6
+ this.methods = ["GET", "POST", "PUT", "DELETE"];
7
+
8
+ if(timeout != undefined){
9
+ this.timeout = timeout;
10
+ } else {this.timeout=5000}
11
+ }
12
+
13
+ async request(method, data, endpoint) {
14
+
15
+ if (!this.methods.includes(method)) throw new Error("Invalid method");
16
+ if(data && typeof data !== "object") throw new Error("Invalid data, not json");
17
+ const controller = new AbortController()
18
+
19
+ let options;
20
+ if(method !="GET"){
21
+ options = {
22
+ method: method,
23
+ headers: {
24
+ "Content-Type": "application/json"
25
+ },
26
+ signal: controller.signal,
27
+ }
28
+ }else{
29
+ options = {
30
+ method: method,
31
+ signal: controller.signal,
32
+ }
33
+ }
34
+
35
+
36
+ if(data!=null){
37
+ options.body = JSON.stringify(data);
38
+ }
39
+
40
+ if(slice.controller.components.has("myLoading")){
41
+ slice.controller.components.delete("myLoading")
42
+ }
43
+
44
+ let loading = await slice.getInstance("Loading", {id:"myLoading"});
45
+ loading.start();
46
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout || 10000)
47
+
48
+ let response;
49
+ if(this.baseUrl != undefined){
50
+ response = await fetch(this.url + endpoint, options);
51
+ }else{
52
+ response = await fetch(endpoint, options);
53
+ }
54
+
55
+ let output = await response.json();
56
+ loading.stop();
57
+
58
+ return output;
59
+ }
60
+
61
+ }
62
+
@@ -0,0 +1,138 @@
1
+ export default class IndexedDbManager {
2
+ constructor(databaseName, storeName) {
3
+ this.databaseName = databaseName;
4
+ this.storeName = storeName;
5
+ this.db = null;
6
+ }
7
+
8
+ async openDatabase() {
9
+ return new Promise((resolve, reject) => {
10
+ const request = indexedDB.open(this.databaseName);
11
+
12
+ request.onupgradeneeded = (event) => {
13
+ const db = event.target.result;
14
+ if (!db.objectStoreNames.contains(this.storeName)) {
15
+ db.createObjectStore(this.storeName, { keyPath: 'id', autoIncrement: true });
16
+ }
17
+ };
18
+
19
+ request.onsuccess = (event) => {
20
+ this.db = event.target.result;
21
+ resolve(this.db);
22
+ };
23
+
24
+ request.onerror = (event) => {
25
+ reject(new Error(`Error opening IndexedDB: ${event.target.error}`));
26
+ };
27
+ });
28
+ }
29
+
30
+ closeDatabase() {
31
+ if (this.db) {
32
+ this.db.close();
33
+ this.db = null;
34
+ }
35
+ }
36
+
37
+ async addItem(item) {
38
+ const db = await this.openDatabase();
39
+ return new Promise((resolve, reject) => {
40
+ const transaction = db.transaction([this.storeName], 'readwrite');
41
+ const store = transaction.objectStore(this.storeName);
42
+ const request = store.add(item);
43
+
44
+ request.onsuccess = () => {
45
+ resolve(request.result);
46
+ };
47
+
48
+ request.onerror = (event) => {
49
+ reject(new Error(`Error adding item to IndexedDB: ${event.target.error}`));
50
+ };
51
+ });
52
+ }
53
+
54
+ async updateItem(item) {
55
+ const db = await this.openDatabase();
56
+ return new Promise((resolve, reject) => {
57
+ const transaction = db.transaction([this.storeName], 'readwrite');
58
+ const store = transaction.objectStore(this.storeName);
59
+ const request = store.put(item);
60
+
61
+ request.onsuccess = () => {
62
+ resolve(request.result);
63
+ };
64
+
65
+ request.onerror = (event) => {
66
+ reject(new Error(`Error updating item in IndexedDB: ${event.target.error}`));
67
+ };
68
+ });
69
+ }
70
+
71
+ async getItem(id) {
72
+ const db = await this.openDatabase();
73
+ return new Promise((resolve, reject) => {
74
+ const transaction = db.transaction([this.storeName], 'readonly');
75
+ const store = transaction.objectStore(this.storeName);
76
+ const request = store.get(id);
77
+
78
+ request.onsuccess = () => {
79
+ resolve(request.result);
80
+ };
81
+
82
+ request.onerror = (event) => {
83
+ reject(new Error(`Error getting item from IndexedDB: ${event.target.error}`));
84
+ };
85
+ });
86
+ }
87
+
88
+ async deleteItem(id) {
89
+ const db = await this.openDatabase();
90
+ return new Promise((resolve, reject) => {
91
+ const transaction = db.transaction([this.storeName], 'readwrite');
92
+ const store = transaction.objectStore(this.storeName);
93
+ const request = store.delete(id);
94
+
95
+ request.onsuccess = () => {
96
+ resolve();
97
+ };
98
+
99
+ request.onerror = (event) => {
100
+ reject(new Error(`Error deleting item from IndexedDB: ${event.target.error}`));
101
+ };
102
+ });
103
+ }
104
+
105
+ async getAllItems() {
106
+ const db = await this.openDatabase();
107
+ return new Promise((resolve, reject) => {
108
+ const transaction = db.transaction([this.storeName], 'readonly');
109
+ const store = transaction.objectStore(this.storeName);
110
+ const request = store.getAll();
111
+
112
+ request.onsuccess = () => {
113
+ resolve(request.result);
114
+ };
115
+
116
+ request.onerror = (event) => {
117
+ reject(new Error(`Error getting items from IndexedDB: ${event.target.error}`));
118
+ };
119
+ });
120
+ }
121
+
122
+ async clearItems() {
123
+ const db = await this.openDatabase();
124
+ return new Promise((resolve, reject) => {
125
+ const transaction = db.transaction([this.storeName], 'readwrite');
126
+ const store = transaction.objectStore(this.storeName);
127
+ const request = store.clear();
128
+
129
+ request.onsuccess = () => {
130
+ resolve();
131
+ };
132
+
133
+ request.onerror = (event) => {
134
+ reject(new Error(`Error clearing items in IndexedDB: ${event.target.error}`));
135
+ };
136
+ });
137
+ }
138
+ }
@@ -0,0 +1,45 @@
1
+ export default class LocalStorageManager {
2
+ constructor() {
3
+ // No se necesitan propiedades en este caso
4
+ }
5
+
6
+ getItem(key) {
7
+ try {
8
+ const item = localStorage.getItem(key);
9
+ return item ? JSON.parse(item) : null;
10
+ } catch (error) {
11
+ console.error(`Error getting item from localStorage: ${error.message}`);
12
+ return null;
13
+ }
14
+ }
15
+
16
+ setItem(key, value) {
17
+ try {
18
+ localStorage.setItem(key, JSON.stringify(value));
19
+ return true;
20
+ } catch (error) {
21
+ console.error(`Error setting item in localStorage: ${error.message}`);
22
+ return false;
23
+ }
24
+ }
25
+
26
+ removeItem(key) {
27
+ try {
28
+ localStorage.removeItem(key);
29
+ return true;
30
+ } catch (error) {
31
+ console.error(`Error removing item from localStorage: ${error.message}`);
32
+ return false;
33
+ }
34
+ }
35
+
36
+ clear() {
37
+ try {
38
+ localStorage.clear();
39
+ return true;
40
+ } catch (error) {
41
+ console.error(`Error clearing localStorage: ${error.message}`);
42
+ return false;
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,59 @@
1
+ export default class Translator {
2
+
3
+ constructor() {
4
+ this.messages={
5
+ "en":{
6
+
7
+ "myInput":{
8
+ "placeholder":"Type here"
9
+ }
10
+
11
+ },
12
+ "es":{
13
+
14
+ "myInput":{
15
+ "placeholder":"Escribe aquí"
16
+ }
17
+ }
18
+ }
19
+ this.currentLanguage = 'en';
20
+ }
21
+
22
+
23
+ changeLanguage(newLanguage) {
24
+ this.currentLanguage = newLanguage;
25
+ return this.setPropertiesForComponents();
26
+ }
27
+
28
+
29
+
30
+ setPropertiesForComponents() {
31
+ try {
32
+ const currentLanguageMessages = this.messages[this.currentLanguage];
33
+
34
+ for (const componentName in currentLanguageMessages) {
35
+ const component = slice.controller.activeComponents.get(componentName);
36
+ const translations = currentLanguageMessages[componentName];
37
+ if (component) {
38
+ for (const prop in translations) {
39
+ component[prop] = translations[prop];
40
+ }
41
+ }else {
42
+ console.error(`Component ${componentName} not found`);
43
+ }
44
+
45
+ }
46
+
47
+ return true
48
+ } catch (error) {
49
+ console.log(error)
50
+ }
51
+
52
+ }
53
+
54
+ }
55
+
56
+
57
+
58
+
59
+
@@ -0,0 +1,108 @@
1
+ import components from "../../components.js";
2
+
3
+ export default class Controller {
4
+ constructor() {
5
+ this.componentCategories = new Map(Object.entries(components));
6
+ this.templates = new Map();
7
+ this.classes = new Map();
8
+ this.requestedStyles = new Set();
9
+ this.activeComponents = new Map();
10
+ this.idCounter = 0;
11
+
12
+ }
13
+
14
+ registerComponent(component) {
15
+ const htmlId = component.id;
16
+
17
+ if (htmlId && htmlId.trim() !== ""){
18
+ if (this.activeComponents.has(htmlId)) {
19
+ slice.logger.logError("Controller", `A component with the same html id attribute is already registered: ${htmlId}`);
20
+ return null;
21
+ }
22
+ }
23
+
24
+ let sliceId = component.sliceId;
25
+
26
+ if (sliceId && sliceId.trim() !== ""){
27
+ if (this.activeComponents.has(sliceId)) {
28
+ slice.logger.logError("Controller", `A component with the same slice id attribute is already registered: ${sliceId}`);
29
+ return null;
30
+ }
31
+ }else {
32
+ sliceId = `slice-${this.idCounter}`;
33
+ component.sliceId = sliceId;
34
+ this.idCounter++;
35
+ }
36
+
37
+ this.activeComponents.set(sliceId, component);
38
+ return true;
39
+
40
+ }
41
+
42
+ getComponent(id) {
43
+ return this.activeComponents.get(id);
44
+ }
45
+
46
+ //Attach template to component
47
+ loadTemplateToComponent(component) {
48
+ const className = component.constructor.name;
49
+ const template = this.templates.get(className);
50
+
51
+ if (!template) {
52
+ console.error(`Template not found for component: ${className}`);
53
+ return;
54
+ }
55
+
56
+ component.innerHTML = template.innerHTML;
57
+ return component;
58
+ }
59
+
60
+
61
+ getComponentCategory(componentSliceId){
62
+ return this.componentCategories.get(componentSliceId);
63
+ }
64
+
65
+ async fetchText(componentName, fileType){
66
+
67
+ const componentCategory = this.getComponentCategory(componentName);
68
+
69
+ let path;
70
+
71
+ if(fileType === "css"){
72
+ path = `Slice/${slice.paths.components}/${componentCategory}/${componentName}/${componentName}.css`;
73
+ }
74
+
75
+ if(fileType === "html"){
76
+ path = `Slice/${slice.paths.components}/${componentCategory}/${componentName}/${componentName}.html`;
77
+ }
78
+
79
+ if(fileType === "theme"){
80
+ path = `Slice/${slice.paths.themes}/${componentName}.css`;
81
+ }
82
+
83
+ const response = await fetch(path);
84
+ const html = await response.text();
85
+ return html;
86
+
87
+ }
88
+
89
+ setComponentProps(component, props) {
90
+ for (const prop in props) {
91
+ component[`_${prop}`] = null;
92
+ component[prop] = props[prop];
93
+ }
94
+ }
95
+
96
+ removeVisualPropsFromComponent(component, props){
97
+ const filteredProps = props.filter(prop => !component.visualProps.includes(prop));
98
+ component.visualProps = filteredProps;
99
+ }
100
+
101
+ destroyComponent(component){
102
+ const sliceId = component.sliceId;
103
+ this.activeComponents.delete(sliceId);
104
+ component.remove();
105
+ }
106
+
107
+
108
+ }
@@ -0,0 +1,58 @@
1
+ #debugger-container {
2
+ display: none;
3
+ position: fixed;
4
+ top: 20px;
5
+ left: 20px;
6
+ padding: 15px;
7
+ border: 1px solid var(--primary-color);
8
+ background-color: var(--primary-background-color);
9
+ z-index: 1000;
10
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
11
+ border-radius: 8px;
12
+ }
13
+
14
+ #debugger-container.active {
15
+ display: block;
16
+ }
17
+
18
+ #close-debugger {
19
+ cursor: pointer;
20
+ position: absolute;
21
+ top: 10px;
22
+ right: 10px;
23
+ font-size: 14px;
24
+ color: var(--danger-color);
25
+ }
26
+
27
+ h3 {
28
+ color: var(--primary-color);
29
+ margin-bottom: 10px;
30
+ }
31
+
32
+ #component-details table {
33
+ width: 100%;
34
+ border-collapse: collapse;
35
+ margin-top: 10px;
36
+ }
37
+
38
+ #component-details th,
39
+ #component-details td {
40
+ border: 1px solid #2b2a4c;
41
+ padding: 12px;
42
+ text-align: left;
43
+ }
44
+
45
+ #component-details th {
46
+ background-color: #ede2de;
47
+ color: #2b2a4c;
48
+ }
49
+
50
+ #component-details td {
51
+ background-color: #fff;
52
+ color: #555;
53
+ }
54
+
55
+ /* Estilo para las filas impares, solo para mejorar la legibilidad */
56
+ #component-details tr:nth-child(odd) {
57
+ background-color: #f9f9f9;
58
+ }
@@ -0,0 +1,6 @@
1
+ <div id="debugger-container">
2
+ <div id="close-debugger">[Close]</div>
3
+ <h3>Component Details</h3>
4
+ <ul id="component-details"></ul>
5
+ </div>
6
+
@@ -0,0 +1,177 @@
1
+ import sliceConfig from "../../../sliceConfig.json" assert { type: "json" };
2
+
3
+ export default class Debugger extends HTMLElement {
4
+ constructor(slice) {
5
+ super();
6
+ this.enabled = sliceConfig.debugger.enabled;
7
+ this.toggleClick = sliceConfig.debugger.click;
8
+ this.toggle = "click";
9
+ }
10
+
11
+ async enableDebugMode() {
12
+ const html = await slice.controller.fetchText("Debugger", "html");
13
+ this.innerHTML = html;
14
+ const css = await slice.controller.fetchText("Debugger", "css");
15
+ slice.stylesManager.registerComponentStyles("Debugger", css);
16
+
17
+ this.debuggerContainer = this.querySelector("#debugger-container");
18
+ this.closeDebugger = this.querySelector("#close-debugger");
19
+ this.componentDetailsList = this.querySelector("#component-details");
20
+
21
+ this.closeDebugger.addEventListener("click", () => this.hideDebugger());
22
+
23
+ // Arrastrar y soltar
24
+ this.makeDraggable();
25
+
26
+ slice.logger.logInfo("Logger", "Debug mode enabled");
27
+ return true;
28
+ }
29
+
30
+ attachDebugMode(component) {
31
+ if (this.toggleClick === "right") {
32
+ this.toggle = "contextmenu";
33
+ } else {
34
+ this.toggle = "click";
35
+ }
36
+ component.addEventListener(this.toggle, (event) =>
37
+ this.handleDebugClick(event, component)
38
+ );
39
+ }
40
+
41
+ // VISUAL
42
+
43
+ makeDraggable() {
44
+ let offsetX, offsetY;
45
+ let isDragging = false;
46
+
47
+ this.debuggerContainer.addEventListener("mousedown", (event) => {
48
+ isDragging = true;
49
+ offsetX =
50
+ event.clientX - this.debuggerContainer.getBoundingClientRect().left;
51
+ offsetY =
52
+ event.clientY - this.debuggerContainer.getBoundingClientRect().top;
53
+ });
54
+
55
+ document.addEventListener("mousemove", (event) => {
56
+ if (isDragging) {
57
+ const x = event.clientX - offsetX;
58
+ const y = event.clientY - offsetY;
59
+
60
+ this.debuggerContainer.style.left = `${x}px`;
61
+ this.debuggerContainer.style.top = `${y}px`;
62
+ }
63
+ });
64
+
65
+ document.addEventListener("mouseup", () => {
66
+ isDragging = false;
67
+ });
68
+ }
69
+
70
+ handleDebugClick(event, component) {
71
+ event.preventDefault();
72
+ const sliceId = component.sliceId;
73
+
74
+ const componentDetails = {
75
+ SliceId: sliceId,
76
+ ClassName: component.constructor.name,
77
+ ObservedAttributes: {},
78
+ };
79
+
80
+ const realComponentProps = component.debuggerProps;
81
+
82
+ realComponentProps.forEach((attr) => {
83
+ //verify if the attr doesnt exist in the component, assign the value of _attr
84
+ if (component[attr] === undefined) {
85
+ componentDetails.ObservedAttributes[attr] = component[`_${attr}`];
86
+ } else {
87
+ componentDetails.ObservedAttributes[attr] = component[attr];
88
+ }
89
+ });
90
+
91
+ // Mostrar observedAttributes y sus valores
92
+ this.showComponentDetails(componentDetails);
93
+ }
94
+
95
+ showComponentDetails(details) {
96
+ this.componentDetailsList.innerHTML = "";
97
+
98
+ // Mostrar información general
99
+ Object.entries(details).forEach(([key, value]) => {
100
+ const listItem = document.createElement("li");
101
+ listItem.textContent = `${key}: ${value}`;
102
+ this.componentDetailsList.appendChild(listItem);
103
+ });
104
+
105
+ // Mostrar observedAttributes y sus valores
106
+ const observedAttributesWithValues = this.getAttributesWithValues(
107
+ details.ObservedAttributes
108
+ );
109
+ const observedAttributesWithoutValues = this.getAttributesWithoutValues(
110
+ details.ObservedAttributes
111
+ );
112
+
113
+ if (observedAttributesWithValues.length > 0) {
114
+ this.createTable(
115
+ "Attributes with Values",
116
+ observedAttributesWithValues,
117
+ details
118
+ );
119
+ }
120
+
121
+ if (observedAttributesWithoutValues.length > 0) {
122
+ this.createTable(
123
+ "Attributes without Values",
124
+ observedAttributesWithoutValues,
125
+ details
126
+ );
127
+ }
128
+
129
+ this.debuggerContainer.classList.add("active");
130
+ }
131
+
132
+ createTable(title, attributes, details) {
133
+ const tableContainer = document.createElement("div");
134
+ tableContainer.classList.add("table-container");
135
+
136
+ const titleElement = document.createElement("h4");
137
+ titleElement.textContent = title;
138
+ tableContainer.appendChild(titleElement);
139
+
140
+ const table = document.createElement("table");
141
+ const thead = table.createTHead();
142
+ const tbody = table.createTBody();
143
+
144
+ const headerRow = thead.insertRow();
145
+ const headerCell1 = headerRow.insertCell(0);
146
+ const headerCell2 = headerRow.insertCell(1);
147
+
148
+ headerCell1.textContent = "Attribute";
149
+ headerCell2.textContent = "Value";
150
+
151
+ attributes.forEach((attr) => {
152
+ const row = tbody.insertRow();
153
+ const cell1 = row.insertCell(0);
154
+ const cell2 = row.insertCell(1);
155
+
156
+ cell1.textContent = attr;
157
+ cell2.textContent = details.ObservedAttributes[attr];
158
+ });
159
+
160
+ tableContainer.appendChild(table);
161
+ this.componentDetailsList.appendChild(tableContainer);
162
+ }
163
+
164
+ getAttributesWithValues(attributes) {
165
+ return Object.keys(attributes).filter((attr) => attributes[attr] !== null);
166
+ }
167
+
168
+ getAttributesWithoutValues(attributes) {
169
+ return Object.keys(attributes).filter((attr) => attributes[attr] === null);
170
+ }
171
+
172
+ hideDebugger() {
173
+ this.debuggerContainer.classList.remove("active");
174
+ }
175
+ }
176
+
177
+ customElements.define("slice-debugger", Debugger);
@@ -0,0 +1,10 @@
1
+ export default class Log {
2
+ constructor(logType, componentCategory, componentSliceId, message, error = null) {
3
+ this.logType = logType;
4
+ this.componentCategory = componentCategory;
5
+ this.componentSliceId = componentSliceId;
6
+ this.message = message;
7
+ this.error = error;
8
+ this.timestamp = new Date();
9
+ }
10
+ }