@nano-app/frontend 0.3.1 → 0.3.3
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/bin/generate-stores.mjs +128 -0
- package/dist/auto-register.d.ts +6 -0
- package/dist/auto-register.js +9 -0
- package/dist/auto-register.mjs +310 -0
- package/dist/auto-register.ts +336 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +12 -2
- package/dist/state/RenderManager.d.ts +47 -0
- package/dist/state/RenderManager.js +78 -0
- package/dist/store/{ApiClient.d.ts → ApiStore.d.ts} +4 -3
- package/dist/store/{ApiClient.js → ApiStore.js} +10 -10
- package/dist/store/AppStore.d.ts +25 -0
- package/dist/store/AppStore.js +59 -0
- package/dist/store/RenderManager.d.ts +47 -0
- package/dist/store/RenderManager.js +78 -0
- package/dist/store/StateManager.d.ts +4 -0
- package/dist/store/StateManager.js +10 -0
- package/dist/store/StoreManager.d.ts +8 -9
- package/dist/store/StoreManager.js +14 -28
- package/dist/store/stores.d.ts +6 -0
- package/dist/store/stores.js +9 -0
- package/dist/ui/Controller.d.ts +13 -14
- package/dist/ui/Controller.js +41 -8
- package/dist/ui/createComponent.d.ts +17 -4
- package/dist/ui/createComponent.js +25 -18
- package/dist/utils/pathUtils.d.ts +14 -0
- package/dist/utils/pathUtils.js +43 -0
- package/package.json +8 -6
- package/dist/api/ApiClient.d.ts +0 -16
- package/dist/api/ApiClient.js +0 -69
- package/dist/api/QueryBuilder.d.ts +0 -8
- package/dist/api/QueryBuilder.js +0 -51
- package/dist/components/Controller.d.ts +0 -16
- package/dist/components/Controller.js +0 -29
- package/dist/config/index.d.ts +0 -21
- package/dist/config/index.js +0 -10
- package/dist/hooks/useComponent.d.ts +0 -8
- package/dist/hooks/useComponent.js +0 -10
- package/dist/plugin/index.d.ts +0 -11
- package/dist/plugin/index.js +0 -134
- package/dist/store/StoreClient.d.ts +0 -11
- package/dist/store/StoreClient.js +0 -40
- package/dist/store/bootstrapApp.d.ts +0 -19
- package/dist/store/bootstrapApp.js +0 -25
- package/dist/store/setStores.d.ts +0 -8
- package/dist/store/setStores.js +0 -23
- package/dist/types/api.d.ts +0 -7
- package/dist/types/api.js +0 -2
- package/dist/ui/Component.d.ts +0 -4
- package/dist/ui/Component.js +0 -49
- package/dist/ui/StoreProvider.d.ts +0 -18
- package/dist/ui/StoreProvider.js +0 -62
- package/dist/ui/defineController.d.ts +0 -23
- package/dist/ui/defineController.js +0 -14
- package/dist/ui/defineView.d.ts +0 -3
- package/dist/ui/defineView.js +0 -44
- package/dist/ui/definers.d.ts +0 -1
- package/dist/ui/definers.js +0 -59
- package/dist/ui/useComponent.d.ts +0 -2
- package/dist/ui/useComponent.js +0 -9
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { createRequire } from "module";
|
|
4
|
+
import { readdirSync, mkdirSync, writeFileSync, existsSync } from "fs";
|
|
5
|
+
import { resolve, join } from "path";
|
|
6
|
+
|
|
7
|
+
const cwd = process.cwd();
|
|
8
|
+
const srcDir = join(cwd, "src");
|
|
9
|
+
const outDir = join(cwd, "node_modules", "@nano-app", "frontend", "dist");
|
|
10
|
+
const outFile = join(outDir, "auto-register.mjs");
|
|
11
|
+
|
|
12
|
+
// Busca recursivamente archivos *.store.ts
|
|
13
|
+
function findStoreFiles(dir) {
|
|
14
|
+
const results = [];
|
|
15
|
+
if (!existsSync(dir)) return results;
|
|
16
|
+
|
|
17
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
18
|
+
const fullPath = join(dir, entry.name);
|
|
19
|
+
if (entry.isDirectory()) {
|
|
20
|
+
results.push(...findStoreFiles(fullPath));
|
|
21
|
+
} else if (entry.isFile() && entry.name.endsWith(".store.ts")) {
|
|
22
|
+
results.push(fullPath);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return results;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Importa un archivo .ts usando jiti (transpilador de Next.js)
|
|
29
|
+
function loadStoreFile(filePath) {
|
|
30
|
+
try {
|
|
31
|
+
const jitiPath = resolve(cwd, "node_modules", "jiti", "lib", "jiti.cjs");
|
|
32
|
+
const require = createRequire(import.meta.url);
|
|
33
|
+
const jiti = require(jitiPath);
|
|
34
|
+
const load = jiti(filePath, { interopDefault: true });
|
|
35
|
+
const mod = load(filePath);
|
|
36
|
+
return mod?.default ?? mod;
|
|
37
|
+
} catch (err) {
|
|
38
|
+
console.error(` [ERROR] No se pudo cargar ${filePath}: ${err.message}`);
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Valida que el objeto tenga la forma correcta
|
|
44
|
+
function validateEntry(entry, filePath) {
|
|
45
|
+
if (!entry || typeof entry !== "object") {
|
|
46
|
+
console.warn(` [WARN] ${filePath}: el export default no es un objeto, se ignora.`);
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
if (entry.type !== "app" && entry.type !== "api") {
|
|
50
|
+
console.warn(` [WARN] ${filePath}: type debe ser "app" o "api", se ignora.`);
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
if (entry.type === "api" && !entry.path) {
|
|
54
|
+
console.warn(` [WARN] ${filePath}: type "api" requiere un campo "path", se ignora.`);
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Serializa el objeto de datos a string JS (soporta funciones)
|
|
61
|
+
function serialize(value, indent = 0) {
|
|
62
|
+
const pad = " ".repeat(indent);
|
|
63
|
+
const padInner = " ".repeat(indent + 1);
|
|
64
|
+
|
|
65
|
+
if (value === null) return "null";
|
|
66
|
+
if (value === undefined) return "undefined";
|
|
67
|
+
if (typeof value === "function") return value.toString();
|
|
68
|
+
if (typeof value === "string") return JSON.stringify(value);
|
|
69
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
70
|
+
|
|
71
|
+
if (Array.isArray(value)) {
|
|
72
|
+
if (value.length === 0) return "[]";
|
|
73
|
+
const items = value.map((v) => `${padInner}${serialize(v, indent + 1)}`).join(",\n");
|
|
74
|
+
return `[\n${items}\n${pad}]`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (typeof value === "object") {
|
|
78
|
+
const entries = Object.entries(value);
|
|
79
|
+
if (entries.length === 0) return "{}";
|
|
80
|
+
const lines = entries
|
|
81
|
+
.map(([k, v]) => `${padInner}${JSON.stringify(k)}: ${serialize(v, indent + 1)}`)
|
|
82
|
+
.join(",\n");
|
|
83
|
+
return `{\n${lines}\n${pad}}`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return String(value);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ─── Main ────────────────────────────────────────────────────────────────────
|
|
90
|
+
|
|
91
|
+
const storeFiles = findStoreFiles(srcDir);
|
|
92
|
+
console.log(`\n[nano-app] Buscando archivos *.store.ts en ${srcDir}`);
|
|
93
|
+
console.log(`[nano-app] Encontrados: ${storeFiles.length}\n`);
|
|
94
|
+
|
|
95
|
+
const entries = [];
|
|
96
|
+
|
|
97
|
+
for (const filePath of storeFiles) {
|
|
98
|
+
console.log(` Procesando: ${filePath.replace(cwd, ".")}`);
|
|
99
|
+
const mod = loadStoreFile(filePath);
|
|
100
|
+
if (mod && validateEntry(mod, filePath)) {
|
|
101
|
+
const name = filePath
|
|
102
|
+
.replace(srcDir, "")
|
|
103
|
+
.replace(/\\/g, "/")
|
|
104
|
+
.replace(/^\//, "")
|
|
105
|
+
.replace(/\.store\.ts$/, "")
|
|
106
|
+
.split("/")
|
|
107
|
+
.pop();
|
|
108
|
+
|
|
109
|
+
entries.push({ name, ...mod });
|
|
110
|
+
console.log(` ✓ Store "${name}" (${mod.type})`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Genera el archivo de salida
|
|
115
|
+
mkdirSync(outDir, { recursive: true });
|
|
116
|
+
|
|
117
|
+
const serializedEntries = entries
|
|
118
|
+
.map((entry) => ` ${serialize(entry, 1)}`)
|
|
119
|
+
.join(",\n");
|
|
120
|
+
|
|
121
|
+
const output = `// Auto-generado por @nano-app
|
|
122
|
+
// No editar manualmente.
|
|
123
|
+
export default [\n${serializedEntries}\n];\n`;
|
|
124
|
+
|
|
125
|
+
writeFileSync(outFile, output, "utf-8");
|
|
126
|
+
|
|
127
|
+
console.log(`\n[nano-app] Archivo generado: ${outFile.replace(cwd, ".")}`);
|
|
128
|
+
console.log(`[nano-app] Stores registrados: ${entries.map((e) => `"${e.name}"`).join(", ") || "(ninguno — se usará store app vacío)"}\n`);
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
// Auto-generado por @nano-app
|
|
2
|
+
// No editar manualmente.
|
|
3
|
+
export default [
|
|
4
|
+
{
|
|
5
|
+
"name": "api",
|
|
6
|
+
"type": "api",
|
|
7
|
+
"path": "/api",
|
|
8
|
+
"data": {
|
|
9
|
+
"busy": true,
|
|
10
|
+
"DefaultItems": [],
|
|
11
|
+
"UserStatusItems": [
|
|
12
|
+
{
|
|
13
|
+
"key": "SUSPENDED",
|
|
14
|
+
"text": "Suspendido"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"key": "PENDING",
|
|
18
|
+
"text": "Pendiente"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"key": "ACTIVE",
|
|
22
|
+
"text": "Activo"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "app",
|
|
29
|
+
"type": "app",
|
|
30
|
+
"data": {
|
|
31
|
+
"isRegister": false,
|
|
32
|
+
"navbar": {
|
|
33
|
+
"tabs": [],
|
|
34
|
+
"selectedTabKey": "home",
|
|
35
|
+
"selectedTab": {},
|
|
36
|
+
"isMenuOpen": false
|
|
37
|
+
},
|
|
38
|
+
"form": {
|
|
39
|
+
"data": {},
|
|
40
|
+
"validate": []
|
|
41
|
+
},
|
|
42
|
+
"drawer": {
|
|
43
|
+
"isOpen": false,
|
|
44
|
+
"formType": "",
|
|
45
|
+
"title": ""
|
|
46
|
+
},
|
|
47
|
+
"totales": {},
|
|
48
|
+
"config": {
|
|
49
|
+
"theme": "dark"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"name": "const",
|
|
55
|
+
"type": "app",
|
|
56
|
+
"data": {
|
|
57
|
+
"alias": "42974117.prex",
|
|
58
|
+
"stepSkipTop": 20,
|
|
59
|
+
"tabs": (rolId = 0) => [
|
|
60
|
+
{ key: "home", href: "/", label: "Home", minRole: -1 },
|
|
61
|
+
{ key: "resumen", href: "/resumen", label: "Resumen", minRole: -1 },
|
|
62
|
+
{ key: "admin", href: "/admin", label: "Administración", minRole: -1 },
|
|
63
|
+
{ key: "uli", href: "/", label: "Uli :v", minRole: -1 },
|
|
64
|
+
{ key: "luka", href: "/", label: "Lucas :v", minRole: -1 }].
|
|
65
|
+
filter((tab) => tab.minRole >= rolId),
|
|
66
|
+
"initialForms": {
|
|
67
|
+
"User": {
|
|
68
|
+
"rolId": 1,
|
|
69
|
+
"status": "PENDING"
|
|
70
|
+
},
|
|
71
|
+
"Collection": {
|
|
72
|
+
"total_months": 1,
|
|
73
|
+
"start_date": "2026-03-01T00:00:00.000Z"
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"tableColumns": {
|
|
77
|
+
"Users": [
|
|
78
|
+
"name",
|
|
79
|
+
"phone",
|
|
80
|
+
"mail",
|
|
81
|
+
"pending",
|
|
82
|
+
"favor",
|
|
83
|
+
"rol.name",
|
|
84
|
+
"status"
|
|
85
|
+
],
|
|
86
|
+
"Collections": [
|
|
87
|
+
"user.name",
|
|
88
|
+
"price",
|
|
89
|
+
"description",
|
|
90
|
+
"start_date",
|
|
91
|
+
"total_months",
|
|
92
|
+
"subscription.description"
|
|
93
|
+
],
|
|
94
|
+
"Subscriptions": [
|
|
95
|
+
"description",
|
|
96
|
+
"price"
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
"formField": {
|
|
100
|
+
"pay": [
|
|
101
|
+
{
|
|
102
|
+
"fieldName": "total",
|
|
103
|
+
"valueType": "price",
|
|
104
|
+
"isRequired": true
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
"login": [
|
|
108
|
+
{
|
|
109
|
+
"fieldName": "mail",
|
|
110
|
+
"inputType": "email",
|
|
111
|
+
"isRequired": true
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"fieldName": "password",
|
|
115
|
+
"inputType": "password",
|
|
116
|
+
"isRequired": true
|
|
117
|
+
}
|
|
118
|
+
],
|
|
119
|
+
"register": [
|
|
120
|
+
{
|
|
121
|
+
"fieldName": "name",
|
|
122
|
+
"isRequired": true
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"fieldName": "phone",
|
|
126
|
+
"isRequired": true
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"fieldName": "mail",
|
|
130
|
+
"inputType": "email",
|
|
131
|
+
"isRequired": true
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"fieldName": "password",
|
|
135
|
+
"inputType": "password",
|
|
136
|
+
"isRequired": true
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"fieldName": "confirmPassword",
|
|
140
|
+
"inputType": "password",
|
|
141
|
+
"isRequired": true
|
|
142
|
+
}
|
|
143
|
+
],
|
|
144
|
+
"Users": [
|
|
145
|
+
{
|
|
146
|
+
"fieldName": "name",
|
|
147
|
+
"isRequired": true
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"fieldName": "mail",
|
|
151
|
+
"inputType": "email",
|
|
152
|
+
"isRequired": true
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"fieldName": "rolId",
|
|
156
|
+
"valueType": "number",
|
|
157
|
+
"isRequired": true,
|
|
158
|
+
"inputType": "select",
|
|
159
|
+
"select": {
|
|
160
|
+
"items": "/Roles",
|
|
161
|
+
"itemKey": "id",
|
|
162
|
+
"showValues": [
|
|
163
|
+
"name"
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"fieldName": "status",
|
|
169
|
+
"inputType": "select",
|
|
170
|
+
"isRequired": true,
|
|
171
|
+
"select": {
|
|
172
|
+
"items": "/UserStatusItems",
|
|
173
|
+
"itemKey": "key",
|
|
174
|
+
"showValues": [
|
|
175
|
+
"text"
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"fieldName": "pending",
|
|
181
|
+
"valueType": "price"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"fieldName": "favor",
|
|
185
|
+
"valueType": "price"
|
|
186
|
+
}
|
|
187
|
+
],
|
|
188
|
+
"Collections": [
|
|
189
|
+
{
|
|
190
|
+
"fieldName": "userId",
|
|
191
|
+
"valueType": "number",
|
|
192
|
+
"inputType": "select",
|
|
193
|
+
"isRequired": true,
|
|
194
|
+
"select": {
|
|
195
|
+
"items": "Users",
|
|
196
|
+
"itemKey": "id",
|
|
197
|
+
"showValues": [
|
|
198
|
+
"name"
|
|
199
|
+
]
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"fieldName": "price",
|
|
204
|
+
"valueType": "price",
|
|
205
|
+
"isRequired": true
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"fieldName": "description",
|
|
209
|
+
"isRequired": true
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"fieldName": "total_months",
|
|
213
|
+
"valueType": "number",
|
|
214
|
+
"isRequired": true
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"fieldName": "start_date",
|
|
218
|
+
"valueType": "date",
|
|
219
|
+
"inputType": "date",
|
|
220
|
+
"isRequired": true
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
"fieldName": "subscriptionId",
|
|
224
|
+
"valueType": "number",
|
|
225
|
+
"inputType": "select",
|
|
226
|
+
"select": {
|
|
227
|
+
"items": "Subscriptions",
|
|
228
|
+
"itemKey": "id",
|
|
229
|
+
"showValues": [
|
|
230
|
+
"description"
|
|
231
|
+
]
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
],
|
|
235
|
+
"Subscriptions": [
|
|
236
|
+
{
|
|
237
|
+
"fieldName": "description",
|
|
238
|
+
"isRequired": true
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
"fieldName": "price",
|
|
242
|
+
"valueType": "price",
|
|
243
|
+
"isRequired": true
|
|
244
|
+
}
|
|
245
|
+
]
|
|
246
|
+
},
|
|
247
|
+
"expandFields": {
|
|
248
|
+
"Users": "rol",
|
|
249
|
+
"Collections": "user,subscription"
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
"name": "i18n",
|
|
255
|
+
"type": "app",
|
|
256
|
+
"data": {
|
|
257
|
+
"login": {
|
|
258
|
+
"header": (isRegister) => isRegister ? "REGISTRARSE" : "INICIAR SESIÓN",
|
|
259
|
+
"footer": (isRegister) => isRegister ? "o iniciar sesión" : "o registrarse",
|
|
260
|
+
"buttonText": (isRegister) => isRegister ? "Crear" : "Ingresar"
|
|
261
|
+
},
|
|
262
|
+
"create": (entity) => `Crear ${entity}`,
|
|
263
|
+
"edit": (entity) => `Editar ${entity}`,
|
|
264
|
+
"mapping": {
|
|
265
|
+
"name": "Nombre",
|
|
266
|
+
"phone": "Teléfono",
|
|
267
|
+
"mail": "Mail",
|
|
268
|
+
"pending": "Pendiente",
|
|
269
|
+
"favor": "A favor",
|
|
270
|
+
"rolId": "Rol",
|
|
271
|
+
"rol.name": "Rol",
|
|
272
|
+
"status": "Estado",
|
|
273
|
+
"password": "Contraseña",
|
|
274
|
+
"confirmPassword": "Repetir contraseña",
|
|
275
|
+
"user.name": "Usuario",
|
|
276
|
+
"userId": "Usuario",
|
|
277
|
+
"price": "Precio",
|
|
278
|
+
"description": "Descripción",
|
|
279
|
+
"start_date": "Fecha de inicio",
|
|
280
|
+
"total_months": "Meses totales",
|
|
281
|
+
"subscription.description": "Subscripción",
|
|
282
|
+
"subscriptionId": "Subscripción",
|
|
283
|
+
"last_pay": "Último pago",
|
|
284
|
+
"first_month": "Mes de inicio",
|
|
285
|
+
"current_month": "Último mes pagado",
|
|
286
|
+
"payed_months": "Meses pagados",
|
|
287
|
+
"actions": "Acciones",
|
|
288
|
+
"created_at": "Creado",
|
|
289
|
+
"Users": "Usuarios",
|
|
290
|
+
"Collections": "Cuotas",
|
|
291
|
+
"Subscriptions": "Subscripciones",
|
|
292
|
+
"total": "TOTAL"
|
|
293
|
+
},
|
|
294
|
+
"months": {
|
|
295
|
+
"1": "Enero",
|
|
296
|
+
"2": "Febrero",
|
|
297
|
+
"3": "Marzo",
|
|
298
|
+
"4": "Abril",
|
|
299
|
+
"5": "Mayo",
|
|
300
|
+
"6": "Junio",
|
|
301
|
+
"7": "Julio",
|
|
302
|
+
"8": "Agosto",
|
|
303
|
+
"9": "Septiembre",
|
|
304
|
+
"10": "Octubre",
|
|
305
|
+
"11": "Noviembre",
|
|
306
|
+
"12": "Diciembre"
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
];
|