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.
- package/PROJECT_TEMPLATES/Basic/Components/Service/FetchManager/FetchManager.js +62 -0
- package/PROJECT_TEMPLATES/Basic/Components/Service/IndexedDbManager/IndexedDbManager.js +138 -0
- package/PROJECT_TEMPLATES/Basic/Components/Service/LocalStorageManager/LocalStorageManager.js +45 -0
- package/PROJECT_TEMPLATES/Basic/Components/Service/Translator/Translator.js +59 -0
- package/PROJECT_TEMPLATES/Basic/Components/Structural/Controller/Controller.js +108 -0
- package/PROJECT_TEMPLATES/Basic/Components/Structural/Debugger/Debugger.css +58 -0
- package/PROJECT_TEMPLATES/Basic/Components/Structural/Debugger/Debugger.html +6 -0
- package/PROJECT_TEMPLATES/Basic/Components/Structural/Debugger/Debugger.js +177 -0
- package/PROJECT_TEMPLATES/Basic/Components/Structural/Logger/Log.js +10 -0
- package/PROJECT_TEMPLATES/Basic/Components/Structural/Logger/Logger.js +112 -0
- package/PROJECT_TEMPLATES/Basic/Components/Structural/StylesManager/CustomStylesManager/CustomStylesManager.js +52 -0
- package/PROJECT_TEMPLATES/Basic/Components/Structural/StylesManager/StylesManager.js +38 -0
- package/PROJECT_TEMPLATES/Basic/Components/Structural/StylesManager/ThemeManager/ThemeManager.js +25 -0
- package/PROJECT_TEMPLATES/Basic/Slice.js +172 -0
- package/PROJECT_TEMPLATES/Basic/sliceConfig.json +24 -0
- package/client.js +54 -0
- package/commands/createComponent/componentTemplate.js +30 -0
- package/commands/createComponent/createComponent.js +84 -0
- package/commands/init/init.js +34 -0
- package/commands/listComponents/listComponents.js +41 -0
- package/commands/modifyComponent/modifyComponent copy.js +111 -0
- package/commands/modifyComponent/modifyComponent.js +158 -0
- package/package.json +23 -0
- package/postInstall.js +27 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import Log from "./Log.js";
|
|
2
|
+
import sliceConfig from "../../../sliceConfig.json" assert { type: "json" };
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export default class Logger {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.logs = [];
|
|
8
|
+
this.logEnabled = sliceConfig.logger.enabled;
|
|
9
|
+
this.showLogsConfig = sliceConfig.logger.showLogs;
|
|
10
|
+
|
|
11
|
+
this.showLog = function showLog(log) {
|
|
12
|
+
if (!this.showLogsConfig) return;
|
|
13
|
+
|
|
14
|
+
const logType = log.logType;
|
|
15
|
+
|
|
16
|
+
Object.keys(this.showLogsConfig).forEach(logConfig => {
|
|
17
|
+
if (this.showLogsConfig[logConfig][logType] === true) {
|
|
18
|
+
switch (logConfig) {
|
|
19
|
+
case "console":
|
|
20
|
+
switch (logType) {
|
|
21
|
+
case logTypes.ERROR:
|
|
22
|
+
console.error(`\x1b[31mERROR\x1b[0m - ${log.componentCategory} - ${log.componentSliceId} - ${log.message} - ${log.error}`);
|
|
23
|
+
break;
|
|
24
|
+
case logTypes.WARNING:
|
|
25
|
+
console.warn(`\x1b[33m⚠ WARNING\x1b[0m - ${log.componentCategory} - ${log.componentSliceId} - ${log.message}`);
|
|
26
|
+
break;
|
|
27
|
+
case logTypes.INFO:
|
|
28
|
+
console.log(`\x1b[32m✔ INFO\x1b[0m - ${log.componentCategory} - ${log.componentSliceId} - ${log.message}`);
|
|
29
|
+
break;
|
|
30
|
+
default:
|
|
31
|
+
console.log(`\x1b[37mUNKNOWN\x1b[0m - ${log.componentCategory} - ${log.componentSliceId} - ${log.message}`);
|
|
32
|
+
}
|
|
33
|
+
break;
|
|
34
|
+
case "toast":
|
|
35
|
+
// TODO: Implement displaying a ToastAlert with the log message for each log type
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
createLog(logType, componentSliceId, message, error = null) {
|
|
46
|
+
if (!this.logEnabled) return;
|
|
47
|
+
let componentName;
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
componentName = slice.controller.activeComponents.get(componentSliceId).constructor.name
|
|
51
|
+
} catch (error) {
|
|
52
|
+
componentName = componentSliceId;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
let componentCategory = slice.controller.getComponentCategory(componentName);
|
|
57
|
+
if(componentSliceId === "Slice") componentCategory = "Structural"
|
|
58
|
+
const log = new Log(logType, componentCategory, componentSliceId, message, error);
|
|
59
|
+
this.logs.push(log);
|
|
60
|
+
this.showLog(log);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
logError(componentSliceId, message, error) {
|
|
66
|
+
this.createLog(logTypes.ERROR, componentSliceId, message, error);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
logWarning(componentSliceId, message) {
|
|
70
|
+
this.createLog(logTypes.WARNING, componentSliceId, message);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
logInfo(componentSliceId, message) {
|
|
74
|
+
this.createLog(logTypes.INFO, componentSliceId, message);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
getLogs() {
|
|
78
|
+
return this.logs;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
clearLogs() {
|
|
82
|
+
this.logs = [];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
getLogsByType(type) {
|
|
86
|
+
return this.logs.filter(log => log.logType === type);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
getLogsByCategory(componentCategory) {
|
|
90
|
+
return this.logs.filter(log => log.componentCategory === componentCategory);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
getLogsByComponent(componentSliceId) {
|
|
94
|
+
return this.logs.filter(log => log.componentSliceId === componentSliceId);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
// En esta misma idea, se tiene que tomar en cuenta que el componente de ToastAlert será un toastProvider y que solo debe
|
|
104
|
+
// haber un toastProvider en la página, por lo que se debe implementar un Singleton para el ToastProvider
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
const logTypes = {
|
|
109
|
+
ERROR: 'error',
|
|
110
|
+
WARNING: 'warning',
|
|
111
|
+
INFO: 'info'
|
|
112
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export default class CustomStylesComponent {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.styles = document.createElement('style');
|
|
4
|
+
document.head.appendChild(this.styles);
|
|
5
|
+
this.cachedStyles = new Set();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async proccess(instance,props){
|
|
9
|
+
|
|
10
|
+
const { customCSS } = props;
|
|
11
|
+
if(customCSS.url){
|
|
12
|
+
await this.loadStyles(customCSS.url);
|
|
13
|
+
}
|
|
14
|
+
if(customCSS.classNames){
|
|
15
|
+
|
|
16
|
+
this.removeClasses(instance);
|
|
17
|
+
await this.applyStyles(instance, customCSS.classNames);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async loadStyles(url) {
|
|
23
|
+
if (!this.cachedStyles.has(url)) {
|
|
24
|
+
try {
|
|
25
|
+
const response = await fetch(url);
|
|
26
|
+
const cssText = await response.text();
|
|
27
|
+
|
|
28
|
+
// Almacenar en caché el estilo
|
|
29
|
+
this.cachedStyles.add(url);
|
|
30
|
+
|
|
31
|
+
// Agregar los estilos del archivo CSS personalizado a la propiedad "styles"
|
|
32
|
+
this.styles.appendChild(document.createTextNode(cssText));
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error(`Error al cargar el estilo personalizado: ${url}`, error);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async applyStyles(instance, classNames) {
|
|
40
|
+
classNames.forEach(className => {
|
|
41
|
+
instance.classList.add(className);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
removeClasses(instance){
|
|
46
|
+
while (instance.classList.length > 0) {
|
|
47
|
+
instance.classList.remove(instance.classList.item(0));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import CustomStylesManager from "./CustomStylesManager/CustomStylesManager.js"
|
|
2
|
+
import ThemeManager from "./ThemeManager/ThemeManager.js"
|
|
3
|
+
|
|
4
|
+
export default class StylesManager {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.componentStyles = document.createElement("style");
|
|
7
|
+
this.componentStyles.id = "slice-component-styles";
|
|
8
|
+
document.head.appendChild(this.componentStyles);
|
|
9
|
+
|
|
10
|
+
this.customStylesManager = new CustomStylesManager();
|
|
11
|
+
this.themeManager = new ThemeManager();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
handleInstanceStyles(instance, props) {
|
|
15
|
+
if(props.customCSS){
|
|
16
|
+
this.customStylesManager.proccess(instance, props);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
setTheme(themeName){
|
|
21
|
+
this.themeManager.applyTheme(themeName);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
//add a method that will add css as text to the componentStyles element
|
|
25
|
+
appendComponentStyles(cssText) {
|
|
26
|
+
this.componentStyles.appendChild(document.createTextNode(cssText));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
registerComponentStyles(componentName, cssText) {
|
|
30
|
+
slice.controller.requestedStyles.add(componentName);
|
|
31
|
+
this.appendComponentStyles(cssText);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
}
|
|
38
|
+
|
package/PROJECT_TEMPLATES/Basic/Components/Structural/StylesManager/ThemeManager/ThemeManager.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export default class ThemeManager {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.currentThemeLink = null;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
async applyTheme(themeName) {
|
|
7
|
+
// Eliminar el tema actual
|
|
8
|
+
this.removeCurrentTheme();
|
|
9
|
+
|
|
10
|
+
// Crear un nuevo link y agregarlo al head
|
|
11
|
+
const themeLink = document.createElement("link");
|
|
12
|
+
themeLink.setAttribute("rel", "stylesheet");
|
|
13
|
+
themeLink.setAttribute("href", `Slice/${slice.paths.themes}/${themeName}.css`);
|
|
14
|
+
document.head.appendChild(themeLink);
|
|
15
|
+
|
|
16
|
+
// Establecer el nuevo link como el tema actual
|
|
17
|
+
this.currentThemeLink = themeLink;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
removeCurrentTheme() {
|
|
21
|
+
if (this.currentThemeLink) {
|
|
22
|
+
this.currentThemeLink.parentNode.removeChild(this.currentThemeLink);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import Logger from "./Components/Structural/Logger/Logger.js";
|
|
2
|
+
import Controller from "./Components/Structural/Controller/Controller.js";
|
|
3
|
+
import StylesManager from "./Components/Structural/StylesManager/StylesManager.js";
|
|
4
|
+
import Debugger from "./Components/Structural/Debugger/Debugger.js";
|
|
5
|
+
import sliceConfig from "./sliceConfig.json" assert { type: "json" };
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export default class Slice {
|
|
9
|
+
|
|
10
|
+
constructor() {
|
|
11
|
+
this.logger = new Logger();
|
|
12
|
+
this.controller = new Controller();
|
|
13
|
+
this.stylesManager = new StylesManager();
|
|
14
|
+
this.paths = {
|
|
15
|
+
components: "./Components",
|
|
16
|
+
themes:"./Themes"
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
this.getClass = async function getClass(module) {
|
|
21
|
+
try {
|
|
22
|
+
const { default: myClass } = await import(module);
|
|
23
|
+
return await myClass;
|
|
24
|
+
} catch (error) {
|
|
25
|
+
this.logger.logError("Slice", `Error loading class ${module}`, error);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
async build(componentName, props = {}) {
|
|
33
|
+
|
|
34
|
+
if(!componentName) {
|
|
35
|
+
this.logger.logError("Slice", null, `Component name is required to build a component`);
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if(!this.controller.componentCategories.has(componentName)) {
|
|
40
|
+
this.logger.logError("Slice", null, `Component ${componentName} not found in components.js file`);
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let compontentCategory = this.controller.componentCategories.get(componentName);
|
|
45
|
+
|
|
46
|
+
//Pregunta para la posteridad: ¿Deberíamos dejar que el usuario pueda crear componentes de categoría Structural?
|
|
47
|
+
//Por ahora no lo permitimos, pero si en el futuro se decide que sí, se debe cambiar el código de abajo para que funcione
|
|
48
|
+
//con componentes de categoría Structural
|
|
49
|
+
|
|
50
|
+
if(compontentCategory === "Structural") {
|
|
51
|
+
this.logger.logError("Slice", null, `Component ${componentName} is a Structural component and cannot be built`);
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
const isVisual = compontentCategory === "Visual";
|
|
57
|
+
|
|
58
|
+
let modulePath = `${this.paths.components}/${compontentCategory}/${componentName}/${componentName}.js`;
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
// Load template if not loaded previously and component category is Visual
|
|
62
|
+
if (!this.controller.templates.has(componentName) && isVisual ) {
|
|
63
|
+
try {
|
|
64
|
+
const html = await this.controller.fetchText(componentName, "html");
|
|
65
|
+
const template = document.createElement("template");
|
|
66
|
+
template.innerHTML = html;
|
|
67
|
+
this.controller.templates.set(componentName, template);
|
|
68
|
+
this.logger.logInfo("Slice", `Template ${componentName} loaded`)
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.log(error)
|
|
71
|
+
this.logger.logError("Slice", `Error loading template ${componentName}`, error);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
//Load class if not loaded previously
|
|
77
|
+
if (!this.controller.classes.has(componentName)) {
|
|
78
|
+
try {
|
|
79
|
+
const ComponentClass = await this.getClass(modulePath);
|
|
80
|
+
this.controller.classes.set(componentName, ComponentClass);
|
|
81
|
+
this.logger.logInfo("Slice", `Class ${componentName} loaded`)
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.log(error)
|
|
84
|
+
this.logger.logError("Slice", `Error loading class ${modulePath}`, error);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
//Load css if not loaded previously and component category is Visual
|
|
89
|
+
if (!this.controller.requestedStyles.has(componentName) && isVisual) {
|
|
90
|
+
try {
|
|
91
|
+
const css = await this.controller.fetchText(componentName, "css");
|
|
92
|
+
this.stylesManager.registerComponentStyles(componentName, css);
|
|
93
|
+
this.logger.logInfo("Slice", `CSS ${componentName} loaded`)
|
|
94
|
+
} catch (error) {
|
|
95
|
+
console.log(error)
|
|
96
|
+
this.logger.logError("Slice", `Error loading css ${componentName}`, error);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
//Create instance
|
|
102
|
+
try {
|
|
103
|
+
let componentIds = {};
|
|
104
|
+
if(props.id) componentIds.id = props.id;
|
|
105
|
+
if(props.sliceId) componentIds.sliceId = props.sliceId;
|
|
106
|
+
|
|
107
|
+
delete props.id;
|
|
108
|
+
delete props.sliceId;
|
|
109
|
+
|
|
110
|
+
const ComponentClass = this.controller.classes.get(componentName);
|
|
111
|
+
const componentInstance = new ComponentClass(props);
|
|
112
|
+
|
|
113
|
+
if(componentIds.id) componentInstance.id = componentIds.id;
|
|
114
|
+
if(componentIds.sliceId) componentInstance.sliceId = componentIds.sliceId;
|
|
115
|
+
|
|
116
|
+
this.stylesManager.handleInstanceStyles(componentInstance,props);
|
|
117
|
+
|
|
118
|
+
if(!this.controller.registerComponent(componentInstance)) {
|
|
119
|
+
this.logger.logError("Slice", `Error registering instance ${componentName} ${componentInstance.sliceId}`);
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if(this.debugger.enabled && compontentCategory === "Visual"){
|
|
124
|
+
this.debugger.attachDebugMode(componentInstance);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
//if the component has a method called init, call it
|
|
128
|
+
if(componentInstance.init ) await componentInstance.init();
|
|
129
|
+
|
|
130
|
+
this.logger.logInfo("Slice", `Instance ${componentInstance.sliceId} created`)
|
|
131
|
+
return componentInstance;
|
|
132
|
+
|
|
133
|
+
} catch (error) {
|
|
134
|
+
console.log(error)
|
|
135
|
+
this.logger.logError("Slice", `Error creating instance ${componentName}`, error);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
setPaths(paths) {
|
|
142
|
+
this.paths = paths;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
setTheme(themeName) {
|
|
146
|
+
this.stylesManager.setTheme(themeName);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
attachTemplate(componentInstance) {
|
|
150
|
+
this.controller.loadTemplateToComponent(componentInstance);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async function init() {
|
|
160
|
+
window.slice = new Slice();
|
|
161
|
+
window.slice.debugger = new Debugger();
|
|
162
|
+
|
|
163
|
+
if(window.slice.debugger.enabled){
|
|
164
|
+
await window.slice.debugger.enableDebugMode();
|
|
165
|
+
document.body.appendChild(window.slice.debugger);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
await window.slice.stylesManager.setTheme(sliceConfig.stylesManager.defaultTheme);
|
|
169
|
+
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
init();
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"debugger": {
|
|
3
|
+
"enabled": true,
|
|
4
|
+
"click": "right"
|
|
5
|
+
},
|
|
6
|
+
"stylesManager": {
|
|
7
|
+
"defaultTheme": "Slice"
|
|
8
|
+
},
|
|
9
|
+
"logger": {
|
|
10
|
+
"enabled": true,
|
|
11
|
+
"showLogs": {
|
|
12
|
+
"console": {
|
|
13
|
+
"error": true,
|
|
14
|
+
"warning": true,
|
|
15
|
+
"info": true
|
|
16
|
+
},
|
|
17
|
+
"toast": {
|
|
18
|
+
"error": true,
|
|
19
|
+
"warning": true,
|
|
20
|
+
"info": true
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
package/client.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { program } from "commander";
|
|
2
|
+
import initializeProject from "./commands/init/init.js";
|
|
3
|
+
import createComponent from "./commands/createComponent/createComponent.js";
|
|
4
|
+
import modifyComponent from "./commands/modifyComponent/modifyComponent.js";
|
|
5
|
+
import listComponents from "./commands/listComponents/listComponents.js";
|
|
6
|
+
|
|
7
|
+
const sliceClient = program;
|
|
8
|
+
|
|
9
|
+
sliceClient
|
|
10
|
+
.version('1.0.0')
|
|
11
|
+
.description('Client for managing framework components');
|
|
12
|
+
|
|
13
|
+
sliceClient
|
|
14
|
+
.command('init <projectType>')
|
|
15
|
+
.description('Initialize the project')
|
|
16
|
+
.action((projectType) => {
|
|
17
|
+
initializeProject(projectType);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
sliceClient
|
|
21
|
+
.command('create <componentName>')
|
|
22
|
+
.description('Create a new component')
|
|
23
|
+
.option('-category <category>', 'Specify the category of the component')
|
|
24
|
+
.option('-properties <properties>', 'Specify properties for the component (comma-separated)')
|
|
25
|
+
.action((componentName, options) => {
|
|
26
|
+
const { Category, Properties } = options;
|
|
27
|
+
const propertiesList = Properties ? Properties.split(',') : [];
|
|
28
|
+
createComponent(componentName, Category, propertiesList);
|
|
29
|
+
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Comando para modificar un componente
|
|
33
|
+
sliceClient
|
|
34
|
+
.command('modify <componentName>')
|
|
35
|
+
.description('Modify an existing component')
|
|
36
|
+
.option('-category <category>', 'Component category')
|
|
37
|
+
.option('-add <addProperties>', 'Add Properties to the component (comma-separated)')
|
|
38
|
+
.option('-remove <removeProperties>', 'Remove Properties from the component (comma-separated)')
|
|
39
|
+
.action((componentName, options) => {
|
|
40
|
+
const { Add, Remove,Category } = options;
|
|
41
|
+
const addProperties = Add ? Add.split(',') : [];
|
|
42
|
+
const removeProperties = Remove ? Remove.split(',') : [];
|
|
43
|
+
modifyComponent(componentName,Category, addProperties, removeProperties);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Comando para listar todos los componentes
|
|
47
|
+
sliceClient
|
|
48
|
+
.command('list')
|
|
49
|
+
.description('List all components')
|
|
50
|
+
.action(() => {
|
|
51
|
+
listComponents();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
sliceClient.parse(process.argv);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export default function componentTemplate(componentName, props) {
|
|
2
|
+
// Generar la lista de getters y setters para las props
|
|
3
|
+
const propGettersSetters = props.map(prop => `
|
|
4
|
+
get ${prop}() {
|
|
5
|
+
return this._${prop};
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
set ${prop}(value) {
|
|
9
|
+
this._${prop} = value;
|
|
10
|
+
}
|
|
11
|
+
`).join('\n');
|
|
12
|
+
|
|
13
|
+
return `export default class ${componentName} extends HTMLElement {
|
|
14
|
+
constructor(props) {
|
|
15
|
+
super();
|
|
16
|
+
slice.attachTemplate(this);
|
|
17
|
+
|
|
18
|
+
slice.controller.setComponentProps(this, props);
|
|
19
|
+
this.debuggerProps = [${props.map(prop => `"${prop}"`).join(',')}];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
init() {}
|
|
23
|
+
|
|
24
|
+
${propGettersSetters}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
customElements.define("slice-${componentName.toLowerCase()}", ${componentName});
|
|
28
|
+
`;
|
|
29
|
+
}
|
|
30
|
+
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
|
|
2
|
+
import componentTemplate from './componentTemplate.js';
|
|
3
|
+
import fs from 'fs-extra';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
|
|
7
|
+
const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
|
8
|
+
|
|
9
|
+
function createComponent(componentName, category, properties) {
|
|
10
|
+
|
|
11
|
+
if (!componentName) {
|
|
12
|
+
console.error('Component name is required');
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (!isValidComponentName(componentName)) {
|
|
17
|
+
console.error('Invalid component name. Please use only alphanumeric characters and start with a letter.');
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const categoryVariations = {
|
|
22
|
+
'Service': ['service', 'servicio', 'serv'],
|
|
23
|
+
'Visual': ['visual', 'vis'],
|
|
24
|
+
'Provider': ['provider', 'proveedor', 'prov'],
|
|
25
|
+
'Structural': ['structural', 'estructural', 'est']
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
// Verificar si la categoría es válida
|
|
31
|
+
let categoryIsValid = false;
|
|
32
|
+
Object.keys(categoryVariations).forEach(validCategory => {
|
|
33
|
+
if (categoryVariations[validCategory].includes(category.toLowerCase())) {
|
|
34
|
+
category = validCategory
|
|
35
|
+
categoryIsValid = true;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
if (!categoryIsValid) {
|
|
40
|
+
console.error('Invalid category. Please use one of the following categories: Service, Visual, Provider, Structural');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Crear el nombre de la clase y del archivo
|
|
45
|
+
const className = componentName.charAt(0).toUpperCase() + componentName.slice(1);
|
|
46
|
+
const fileName = `${className}.js`;
|
|
47
|
+
const template = componentTemplate(className, properties);
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
// Determinar la ruta del archivo
|
|
52
|
+
|
|
53
|
+
const componentDir = path.join(__dirname, '../../../../Slice/Components', category, className);
|
|
54
|
+
|
|
55
|
+
// Asegurarse de que el directorio del componente exista
|
|
56
|
+
fs.ensureDirSync(componentDir);
|
|
57
|
+
|
|
58
|
+
// Determinar la ruta del archivo
|
|
59
|
+
const componentPath = path.join(componentDir, fileName);
|
|
60
|
+
|
|
61
|
+
console.log(componentPath);
|
|
62
|
+
|
|
63
|
+
// Verificar si el archivo ya existe
|
|
64
|
+
if (fs.existsSync(componentPath)) {
|
|
65
|
+
console.error(`Component '${componentName}' already exists.`);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Escribir el código del componente en el archivo
|
|
70
|
+
fs.writeFileSync(componentPath, template);
|
|
71
|
+
fs.writeFileSync(`${componentDir}/${className}.css`, '');
|
|
72
|
+
fs.writeFileSync(`${componentDir}/${className}.html`, '');
|
|
73
|
+
|
|
74
|
+
console.log(`Component '${componentName}' created successfully.`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function isValidComponentName(componentName) {
|
|
78
|
+
// Expresión regular para verificar si el nombre contiene caracteres especiales
|
|
79
|
+
const regex = /^[a-zA-Z][a-zA-Z0-9]*$/;
|
|
80
|
+
return regex.test(componentName);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export default createComponent;
|
|
84
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
|
|
7
|
+
export default async function initializeProject(projectType) {
|
|
8
|
+
try {
|
|
9
|
+
// Directorio de origen en el paquete
|
|
10
|
+
let sliceDir;
|
|
11
|
+
let basicPosibilities = ["basic", "Basic", "-b", "-B", "b", "B"];
|
|
12
|
+
if (basicPosibilities.includes(projectType)) {
|
|
13
|
+
sliceDir = path.join(__dirname, '../../PROJECT_TEMPLATES/Basic');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Directorio de destino en la raíz del proyecto
|
|
17
|
+
const destinationDir = path.join(__dirname, '../../../../Slice');
|
|
18
|
+
|
|
19
|
+
// Verificar si el directorio de destino ya existe
|
|
20
|
+
if (fs.existsSync(destinationDir)) {
|
|
21
|
+
console.error('El proyecto ya cuenta con un directorio "Slice". No es posible inicializar el proyecto nuevamente');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Copiar el contenido del directorio de origen al directorio de destino
|
|
26
|
+
await fs.copy(sliceDir, destinationDir);
|
|
27
|
+
|
|
28
|
+
console.log('Proyecto inicializado correctamente.');
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.error('Error al inicializar el proyecto:', error);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
|
|
7
|
+
export default function listComponents() {
|
|
8
|
+
|
|
9
|
+
const SlicePath = path.join(__dirname, '../../../../Slice/Components');
|
|
10
|
+
|
|
11
|
+
const visualComponents = fs.readdirSync(`${SlicePath}/Visual`);
|
|
12
|
+
const services = fs.readdirSync(`${SlicePath}/Service`);
|
|
13
|
+
const providers = fs.readdirSync(`${SlicePath}/Provider`);
|
|
14
|
+
const structuralComponents = fs.readdirSync(`${SlicePath}/Structural`)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
const componentMap = new Map();
|
|
18
|
+
|
|
19
|
+
visualComponents.forEach(component => {
|
|
20
|
+
componentMap.set(component, "Visual");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
services.forEach(component => {
|
|
24
|
+
componentMap.set(component, "Service");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
providers.forEach(component => {
|
|
28
|
+
componentMap.set(component, "Provider");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
structuralComponents.forEach(component => {
|
|
32
|
+
componentMap.set(component, "Structural");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
const mapAsArray = Array.from(componentMap.entries());
|
|
37
|
+
const mapObject = Object.fromEntries(mapAsArray);
|
|
38
|
+
|
|
39
|
+
fs.writeFileSync(`${SlicePath}/components.js`, `const components = ${JSON.stringify(mapObject, null, 2)}; export default components;`);
|
|
40
|
+
console.log('Components list updated');
|
|
41
|
+
}
|