xonecode 0.1.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 (187) hide show
  1. package/README.md +167 -0
  2. package/dist/agent/authEnDisco.js +56 -0
  3. package/dist/agent/authEnDisco.js.map +1 -0
  4. package/dist/agent/configEnDisco.js +109 -0
  5. package/dist/agent/configEnDisco.js.map +1 -0
  6. package/dist/agent/crearProyecto.js +34 -0
  7. package/dist/agent/crearProyecto.js.map +1 -0
  8. package/dist/agent/entorno.js +124 -0
  9. package/dist/agent/entorno.js.map +1 -0
  10. package/dist/agent/guionizado.js +53 -0
  11. package/dist/agent/guionizado.js.map +1 -0
  12. package/dist/agent/instantanea.js +129 -0
  13. package/dist/agent/instantanea.js.map +1 -0
  14. package/dist/agent/interrupts.js +83 -0
  15. package/dist/agent/interrupts.js.map +1 -0
  16. package/dist/agent/mensajes.js +24 -0
  17. package/dist/agent/mensajes.js.map +1 -0
  18. package/dist/agent/modelos.js +42 -0
  19. package/dist/agent/modelos.js.map +1 -0
  20. package/dist/agent/normalizar.js +20 -0
  21. package/dist/agent/normalizar.js.map +1 -0
  22. package/dist/agent/perfiles.js +103 -0
  23. package/dist/agent/perfiles.js.map +1 -0
  24. package/dist/agent/proyecto.js +107 -0
  25. package/dist/agent/proyecto.js.map +1 -0
  26. package/dist/agent/puente.js +142 -0
  27. package/dist/agent/puente.js.map +1 -0
  28. package/dist/agent/resumenDeTool.js +48 -0
  29. package/dist/agent/resumenDeTool.js.map +1 -0
  30. package/dist/agent/skills.js +65 -0
  31. package/dist/agent/skills.js.map +1 -0
  32. package/dist/agent/textoDeTool.js +113 -0
  33. package/dist/agent/textoDeTool.js.map +1 -0
  34. package/dist/agent/turnoReal.js +173 -0
  35. package/dist/agent/turnoReal.js.map +1 -0
  36. package/dist/agent/verificador.js +65 -0
  37. package/dist/agent/verificador.js.map +1 -0
  38. package/dist/agent/xoneAgent.js +106 -0
  39. package/dist/agent/xoneAgent.js.map +1 -0
  40. package/dist/bin.js +9 -0
  41. package/dist/bin.js.map +1 -0
  42. package/dist/cli/aprobar.js +82 -0
  43. package/dist/cli/aprobar.js.map +1 -0
  44. package/dist/cli/config.js +133 -0
  45. package/dist/cli/config.js.map +1 -0
  46. package/dist/cli/consola.js +346 -0
  47. package/dist/cli/consola.js.map +1 -0
  48. package/dist/cli/describe.js +53 -0
  49. package/dist/cli/describe.js.map +1 -0
  50. package/dist/cli/doctor.js +45 -0
  51. package/dist/cli/doctor.js.map +1 -0
  52. package/dist/cli/main.js +520 -0
  53. package/dist/cli/main.js.map +1 -0
  54. package/dist/cli/markdown.js +90 -0
  55. package/dist/cli/markdown.js.map +1 -0
  56. package/dist/cli/run.js +164 -0
  57. package/dist/cli/run.js.map +1 -0
  58. package/dist/cli/spinner.js +89 -0
  59. package/dist/cli/spinner.js.map +1 -0
  60. package/dist/cli/stdio.js +193 -0
  61. package/dist/cli/stdio.js.map +1 -0
  62. package/dist/cli/tema.js +40 -0
  63. package/dist/cli/tema.js.map +1 -0
  64. package/dist/cli/verify.js +62 -0
  65. package/dist/cli/verify.js.map +1 -0
  66. package/dist/core/bitacora.js +30 -0
  67. package/dist/core/bitacora.js.map +1 -0
  68. package/dist/core/config.js +236 -0
  69. package/dist/core/config.js.map +1 -0
  70. package/dist/core/contextos.js +56 -0
  71. package/dist/core/contextos.js.map +1 -0
  72. package/dist/core/deps.js +51 -0
  73. package/dist/core/deps.js.map +1 -0
  74. package/dist/core/diff.js +79 -0
  75. package/dist/core/diff.js.map +1 -0
  76. package/dist/core/esqueleto.js +366 -0
  77. package/dist/core/esqueleto.js.map +1 -0
  78. package/dist/core/events.js +2 -0
  79. package/dist/core/events.js.map +1 -0
  80. package/dist/core/modelos.js +85 -0
  81. package/dist/core/modelos.js.map +1 -0
  82. package/dist/core/notify.js +106 -0
  83. package/dist/core/notify.js.map +1 -0
  84. package/dist/core/ports.js +114 -0
  85. package/dist/core/ports.js.map +1 -0
  86. package/dist/core/turno.js +127 -0
  87. package/dist/core/turno.js.map +1 -0
  88. package/dist/vendor/hitl.js +103 -0
  89. package/dist/vendor/hitl.js.map +1 -0
  90. package/dist/vendor/skillLoaders/catalog.js +74 -0
  91. package/dist/vendor/skillLoaders/catalog.js.map +1 -0
  92. package/dist/vendor/tokenTracking.js +58 -0
  93. package/dist/vendor/tokenTracking.js.map +1 -0
  94. package/package.json +41 -0
  95. package/skills/xone-debugging/SKILL.md +52 -0
  96. package/skills/xone-debugging/references/faq.md +561 -0
  97. package/skills/xone-debugging/references/troubleshooting-y-glosario.md +429 -0
  98. package/skills/xone-development/SKILL.md +105 -0
  99. package/skills/xone-development/references/anti-patrones.md +94 -0
  100. package/skills/xone-development/references/css/atributos-por-categoria.md +509 -0
  101. package/skills/xone-development/references/css/buenas-practicas-y-parser.md +419 -0
  102. package/skills/xone-development/references/css/dinamicos-cascada-y-componentes.md +550 -0
  103. package/skills/xone-development/references/css/patrones-material-y-temas.md +1140 -0
  104. package/skills/xone-development/references/css/propiedades-y-herencia.md +885 -0
  105. package/skills/xone-development/references/css/selectores-unidades-colores.md +840 -0
  106. package/skills/xone-development/references/datos/appdata-referencia-ampliada.md +457 -0
  107. package/skills/xone-development/references/datos/appdata.md +611 -0
  108. package/skills/xone-development/references/datos/http-sqlmanager-y-crypto.md +720 -0
  109. package/skills/xone-development/references/datos/http.md +366 -0
  110. package/skills/xone-development/references/datos/oauth2-y-replica.md +156 -0
  111. package/skills/xone-development/references/device/biometria-imagedrawing-y-otros.md +544 -0
  112. package/skills/xone-development/references/device/objetos-de-dispositivo.md +583 -0
  113. package/skills/xone-development/references/device/systemsettings-referencia-ampliada.md +396 -0
  114. package/skills/xone-development/references/device/systemsettings-y-permisos.md +342 -0
  115. package/skills/xone-development/references/fundamentos/conceptos-clave.md +695 -0
  116. package/skills/xone-development/references/fundamentos/configuracion-app-xml-ini-mappings.md +668 -0
  117. package/skills/xone-development/references/fundamentos/errores-comunes.md +312 -0
  118. package/skills/xone-development/references/fundamentos/navegacion-convenciones-y-primer-proyecto.md +576 -0
  119. package/skills/xone-development/references/fundamentos/plataforma-y-anatomia-de-proyecto.md +387 -0
  120. package/skills/xone-development/references/indice-completo.md +77 -0
  121. package/skills/xone-development/references/javascript/coleccion-error-y-usuario.md +260 -0
  122. package/skills/xone-development/references/javascript/debugging-y-best-practices.md +245 -0
  123. package/skills/xone-development/references/javascript/metodos-de-los-controles.md +556 -0
  124. package/skills/xone-development/references/javascript/metodos-nativos-de-la-vista.md +114 -0
  125. package/skills/xone-development/references/javascript/motor-js-y-contexto-de-ejecucion.md +319 -0
  126. package/skills/xone-development/references/javascript/objeto-ai-llm-en-dispositivo.md +358 -0
  127. package/skills/xone-development/references/javascript/objetos-creables-a-m.md +527 -0
  128. package/skills/xone-development/references/javascript/objetos-creables-n-z.md +385 -0
  129. package/skills/xone-development/references/javascript/patrones-criticos-seguridad-y-rendimiento.md +595 -0
  130. package/skills/xone-development/references/javascript/patrones-de-navegacion-datos-y-codigo.md +751 -0
  131. package/skills/xone-development/references/javascript/patrones-de-ui-voz-integracion-y-seguridad.md +701 -0
  132. package/skills/xone-development/references/javascript/plantillas-y-funciones-utilitarias.md +647 -0
  133. package/skills/xone-development/references/javascript/self-y-dataobject.md +449 -0
  134. package/skills/xone-development/references/javascript/singletons-globales.md +361 -0
  135. package/skills/xone-development/references/javascript/ui-catalogo-de-metodos.md +464 -0
  136. package/skills/xone-development/references/javascript/ui-gps-camara-y-multimedia.md +506 -0
  137. package/skills/xone-development/references/javascript/ui-navegacion-mensajes-y-vista.md +422 -0
  138. package/skills/xone-development/references/resumen-js-datos-dispositivo.md +80 -0
  139. package/skills/xone-development/references/resumen-xml-y-css.md +74 -0
  140. package/skills/xone-development/references/tipos-de-prop.md +28 -0
  141. package/skills/xone-development/references/xml-ui/asfilter-visibilidad-eventos-y-macros.md +576 -0
  142. package/skills/xone-development/references/xml-ui/atributos-coll-group-frame.md +235 -0
  143. package/skills/xone-development/references/xml-ui/atributos-method-macro-script-event-app.md +244 -0
  144. package/skills/xone-development/references/xml-ui/atributos-prop.md +439 -0
  145. package/skills/xone-development/references/xml-ui/contents-y-macros.md +392 -0
  146. package/skills/xone-development/references/xml-ui/errores-comunes-xml.md +245 -0
  147. package/skills/xone-development/references/xml-ui/estructura-y-nodo-coll.md +326 -0
  148. package/skills/xone-development/references/xml-ui/eventos-ciclo-de-vida-e-interaccion.md +704 -0
  149. package/skills/xone-development/references/xml-ui/eventos-sistema-login-y-personalizados.md +944 -0
  150. package/skills/xone-development/references/xml-ui/layouts-herencia-y-buenas-practicas.md +618 -0
  151. package/skills/xone-development/references/xml-ui/mapas.md +685 -0
  152. package/skills/xone-development/references/xml-ui/mappings-y-colecciones-separadas.md +148 -0
  153. package/skills/xone-development/references/xml-ui/nodos-group-y-frame.md +666 -0
  154. package/skills/xone-development/references/xml-ui/patrones-de-pantalla.md +643 -0
  155. package/skills/xone-development/references/xml-ui/prop-atributos-y-condiciones.md +298 -0
  156. package/skills/xone-development/references/xml-ui/prop-tipos-basicos.md +493 -0
  157. package/skills/xone-development/references/xml-ui/prop-tipos-combos-y-controles.md +664 -0
  158. package/skills/xone-development/references/xml-ui/prop-tipos-listas-y-mapas.md +412 -0
  159. package/skills/xone-plan-builder/SKILL.md +183 -0
  160. package/skills/xone-plan-builder/agents/openai.yaml +5 -0
  161. package/skills/xone-plan-builder/references/TASKS-FORMAT.md +132 -0
  162. package/skills/xone-project-generator/SKILL.md +111 -0
  163. package/skills/xone-project-generator/references/canonical-sizes.md +292 -0
  164. package/skills/xone-project-generator/references/colecciones-base.md +16 -0
  165. package/skills/xone-project-generator/references/convenciones-de-nombres.md +16 -0
  166. package/skills/xone-project-generator/references/ejemplos-por-sector-y-prohibiciones.md +140 -0
  167. package/skills/xone-project-generator/references/fase-3-estilos-css.md +597 -0
  168. package/skills/xone-project-generator/references/fase-6-colecciones.md +762 -0
  169. package/skills/xone-project-generator/references/fase-7-asfilter-e-integraciones.md +142 -0
  170. package/skills/xone-project-generator/references/fase-7-entidades-y-estructura-de-pantalla.md +494 -0
  171. package/skills/xone-project-generator/references/fase-7-plantilla-consola.md +477 -0
  172. package/skills/xone-project-generator/references/fase-7-plantillas-de-pantalla.md +302 -0
  173. package/skills/xone-project-generator/references/fase-7-viewmodes-graficos-y-listas.md +681 -0
  174. package/skills/xone-project-generator/references/fase-7-viewmodes-mapa-y-calendario.md +479 -0
  175. package/skills/xone-project-generator/references/fases-0-2-analisis-y-modelo-de-datos.md +350 -0
  176. package/skills/xone-project-generator/references/fases-10-12-readmes-y-validacion.md +194 -0
  177. package/skills/xone-project-generator/references/fases-4-5-estructura-y-configuracion.md +587 -0
  178. package/skills/xone-project-generator/references/fases-8-9-eventos-y-javascript.md +861 -0
  179. package/skills/xone-project-generator/references/flujo-de-generacion.md +67 -0
  180. package/skills/xone-project-generator/references/plantillas-estandar.md +98 -0
  181. package/skills/xone-project-generator/references/tamanos-canonicos.md +49 -0
  182. package/skills/xone-review/SKILL.md +189 -0
  183. package/skills/xone-spec-builder/SKILL.md +235 -0
  184. package/skills/xone-spec-builder/agents/openai.yaml +5 -0
  185. package/skills/xone-spec-builder/references/ADR-FORMAT.md +55 -0
  186. package/skills/xone-spec-builder/references/CONTEXT-FORMAT.md +42 -0
  187. package/skills/xone-spec-builder/references/PLAN-FORMAT.md +120 -0
@@ -0,0 +1,260 @@
1
+ # XOne JavaScript — selfDataColl, err y user
2
+
3
+ > Fuente: `xone/v2/xone-help-docs/topics/06-javascript-runtime-objects.md` §1–§4. Referencia de la skill; el índice está en [../../SKILL.md](../../SKILL.md).
4
+
5
+ Contenido: §1 objetos globales y sus alias · §2 API completa de la colección actual (información, acceso, crear/añadir/borrar, browse, filtros y orden, búsqueda full-text, macros y variables, metadatos, SQL directo y JSON) · §3 objeto de error global y excepciones del framework · §4 usuario logueado
6
+
7
+ ---
8
+
9
+ ## 1. Objetos Globales — Resumen
10
+
11
+ Los siguientes objetos se inyectan automáticamente en cada script de XOne:
12
+
13
+ | Nombre global | Alias | Que representa |
14
+ |---|---|---|
15
+ | `self` | `dataobject` | El objeto/registro actual sobre el que se ejecuta el script. API completa en tópico 03 sección 2. |
16
+ | `selfDataColl` | `datacollection` | La coleccion actual. API completa en §2 de este tópico. |
17
+ | `appData` | `appdata` | La aplicación (raiz). API en tópico 03 sección 4. |
18
+ | `user` | — | El usuario logueado. Hereda toda la API de `self`. Ver §4. |
19
+ | `err` | `error` | El último error producido por el framework. Ver §3. |
20
+ | `ui` | — | La interfaz de usuario y servicios del dispositivo. API en tópico 03 sección 3. |
21
+
22
+ > **Regla de nomenclatura:** Los alias (`dataobject`, `datacollection`, `appdata`, `error`) son equivalentes a los nombres principales. En JavaScript se recomienda usar los nombres principales (`self`, `selfDataColl`, `appData`, `err`).
23
+
24
+ ---
25
+
26
+ ## 2. selfDataColl / datacollection — Coleccion Actual
27
+
28
+ `selfDataColl` representa la coleccion sobre la que se ejecuta el script actual. Es el equivalente al concepto de "tabla" o "resultado de consulta" en memoria.
29
+
30
+ ### 2.1 Información básica
31
+
32
+ | Método | Descripción |
33
+ |---|---|
34
+ | `getName()` / `name()` → `String` | Nombre de la coleccion (el atributo `name` del `<coll>`). |
35
+ | `getOwnerApp()` → `appData` | App propietaria. |
36
+ | `getOwnerObject()` / `ownerObject()` → `dataobject` | Objeto contenedor (en colecciones anidadas / contents). |
37
+ | `getCount()` / `count()` → `int` | Total de objetos cargados en memoria. |
38
+ | `isEmpty()` → `boolean` | Atajo equivalente a `getCount() == 0`. |
39
+ | `browseLength()` → `long` | Cantidad de filas del recorrido browse. **Solo devuelve un valor útil tras `startBrowse(true)`**; con `startBrowse()` por defecto devuelve `-1`. |
40
+ | `stringKey()` → `boolean` | `true` si la PK es de tipo texto. |
41
+ | `getMultipleKey()` → `boolean` | `true` si la PK es múltiple (varios campos clave). |
42
+ | `getCurrentItem()` → `dataobject` | Objeto actual del cursor browse. **El objeto devuelto es efímero**: su contenido se reemplaza con cada `moveNext()`. No guardar la referencia para usarla después; leer o copiar los campos dentro de la iteración. |
43
+ | `getIdFieldName()` → `String` | Nombre del campo PK de la coleccion. |
44
+ | `isFull()` → `boolean` | `true` si todos los registros están cargados en memoria. |
45
+ | `isLocked()` → `boolean` | `true` si la coleccion esta bloqueada (`lock()`). |
46
+ | `isBrowsing()` → `boolean` | `true` si hay un cursor browse activo. |
47
+ | `getXmlNode()` → `XmlNode` | Nodo XML que define la coleccion (acceso a metadatos del modelo). |
48
+ | `getConnection()` / `getDataConnector()` → `Connection` | Conexión de base de datos usada. |
49
+ | `getAccessString()` → `String` | SQL/objeto de acceso declarado en la coll. |
50
+ | `getDevelopedAccessString()` → `String` | SQL con macros expandidas. |
51
+ | `getDevelopedFilter()` → `String` | Filtro activo con macros expandidas. |
52
+ | `getDevelopedLinkFilter()` → `String` | Linkfilter con macros expandidas. |
53
+
54
+ ### 2.2 Acceso a objetos
55
+
56
+ | Método | Descripción |
57
+ |---|---|
58
+ | `get(index)` / `getObject(index)` / `getItem(index)` → `dataobject` | Obtiene el objeto por índice (base 0). |
59
+ | `get(key)` / `getObject(key)` / `getItem(key)` → `dataobject` | Obtiene el objeto por valor de PK (clave). |
60
+ | `getItem(field, value)` → `dataobject` | Busca por par campo/valor (primero en memoria, luego en BD). Equivalente a `getObject(field, value)`. |
61
+ | `findObject(criteria)` → `dataobject` | Busca el primer objeto que cumple una cláusula WHERE SQL (p.ej. `"LOGIN='admin'"` o `"ID=5 AND ACTIVO=1"`). Lanza la búsqueda contra BD. |
62
+ | `findAllObjects(criteria)` → `Object[]` | Igual que `findObject` pero devuelve todas las coincidencias. |
63
+ | `getObjectIndex(item)` → `int` | Índice del objeto dentro de la coleccion. |
64
+ | `swapItems(a, b)` | Intercambia dos objetos de posición. Cada argumento puede ser índice, clave PK o `dataobject`. Si alguno no se encuentra en la coll, no hace nada. |
65
+
66
+ ### 2.3 Crear, anadir, borrar
67
+
68
+ | Método | Descripción |
69
+ |---|---|
70
+ | `createObject(...)` → `dataobject` | Crea un nuevo objeto (no guardado en BD) (legacy; el patrón preferido es `new NombreColeccion({...})`). |
71
+ | `createClone()` → `datacollection` | Clona la coleccion (útil para filtrar sin afectar la original). |
72
+ | `addItem(item)` / `addItem(index, item)` → `boolean` | Anade un objeto a la lista en memoria. Con 2 params, el **índice va primero** y el item segundo. Si `index == -1` se añade al final. |
73
+ | `removeItem(idx \| key \| dataobject)` → `boolean` | Elimina un objeto **solo de la lista en memoria**. **NO** lo borra en BD. |
74
+ | `deleteItem(idx \| key \| dataobject)` → `boolean` | Elimina un objeto de la lista **Y de la base de datos**. |
75
+ | `clear()` → `boolean` | Vacia la coleccion en memoria. Si la coll está bloqueada con `lock()`, no hace nada. |
76
+ | `deleteAll()` → `boolean` | Borra todos los objetos en BD. |
77
+ | `browseDeleteAll()` → `boolean` | Borra todos recorriendo (lanza eventos por objeto). |
78
+ | `browseDeleteWithNoRules()` → `boolean` | Borra todos sin lanzar eventos. |
79
+ | `loadAll()` → `boolean` | Carga todos los registros en memoria. Usar con precaucion en datasets grandes. |
80
+ | `saveAll()` → `boolean` | Guarda todos los objetos modificados. |
81
+
82
+ ### 2.4 Browse (cursor de navegación)
83
+
84
+ El browse es el patron correcto para recorrer grandes colecciones sin cargarlas todas en memoria.
85
+
86
+ | Método | Descripción |
87
+ |---|---|
88
+ | `startBrowse(...)` → `boolean` | Inicia el cursor browse. |
89
+ | `endBrowse()` → `boolean` | Finaliza el cursor. **Siempre en bloque `finally`**. |
90
+ | `moveFirst()` → `boolean` | Mueve al primer item. |
91
+ | `moveLast()` → `boolean` | Mueve al último item. |
92
+ | `moveNext()` → `boolean` | Avanza al siguiente item. Devuelve `false` al llegar al final. |
93
+ | `movePrevious()` → `boolean` | Retrocede al item anterior. |
94
+ | `lock()` / `unlock()` | Bloquea/desbloquea la coll. La coll nace **desbloqueada**. Estando bloqueada, `clear()` y `loadAll()` no hacen nada — útil para "congelar" el contenido de la coll mientras se opera sobre ella. `isLocked()` devuelve el estado actual. |
95
+
96
+ ```js
97
+ // Patron correcto: startBrowse posiciona en el primer item; iterar con getCurrentItem+moveNext;
98
+ // siempre endBrowse() en finally.
99
+ var coll = appData.getCollection("Pedidos");
100
+ coll.setFilter("estado = 'pendiente'");
101
+ coll.startBrowse();
102
+ try {
103
+ var item = coll.getCurrentItem();
104
+ while (item != null) {
105
+ item.setValue("revisado", 1);
106
+ item.save();
107
+ if (!coll.moveNext()) break;
108
+ item = coll.getCurrentItem();
109
+ }
110
+ } finally {
111
+ coll.endBrowse();
112
+ }
113
+ ```
114
+
115
+ ### 2.5 Filtros y orden
116
+
117
+ | Método | Descripción |
118
+ |---|---|
119
+ | `getFilter()` → `String` | Filtro SQL activo. |
120
+ | `setFilter(value)` | Cambia el filtro SQL. |
121
+ | `getLinkFilter()` → `String` | Linkfilter activo. |
122
+ | `setLinkFilter(value)` | Cambia el linkfilter. |
123
+ | `getSort()` → `String` | Orden activo. |
124
+ | `setSort(value)` | Cambia el orden. |
125
+ | `doSort(expr?)` | Reordena los objetos **en memoria**. Acepta una expresión SQL-like (`"CAMPO asc, CAMPO2 desc"`); sin argumento usa el sort actual de la coll. |
126
+ | `reload(xmlNode, [forced])` → `boolean` | **NO recarga datos.** Recarga la **definición XML** de la coll en runtime. Requiere un nodo XML obligatorio; sin él falla. Para recargar los datos con el filtro actual usar `clear()`+`loadAll()` o un nuevo `startBrowse()`. |
127
+ | `rebuildLayout(...)` | Reconstruye el layout de propiedades visibles. |
128
+
129
+ ### 2.6 Busqueda full-text
130
+
131
+ | Método | Descripción |
132
+ |---|---|
133
+ | `createSearchIndex(field/fields[]/table+fields[])` | Crea índice FTS para busqueda rápida. |
134
+ | `createPersistData(fields.../table+fields...)` | Crea tabla persistente de busqueda. |
135
+ | `doSearch(criteria)` / `doSearch(table, criteria)` | Ejecuta la busqueda full-text. |
136
+ | `generateRowId()` → `String` | Genera un nuevo ROWID (GUID) valido para un nuevo objeto. |
137
+
138
+ ### 2.7 Macros y variables de coleccion
139
+
140
+ | Método | Descripción |
141
+ |---|---|
142
+ | `getMacro(name)` / `getMacro(index)` → `String` | Lee el valor de una macro. Acepta nombre (`"##X##"`) o índice numérico. |
143
+ | `setMacro(name, value)` / `setMacro(index, value)` | Asigna una macro. Igual: por nombre o por índice. |
144
+ | `getMacroCount()` → `int` | Número de macros declaradas. |
145
+ | `getAllMacros()` → `Map<String,Object>` | Todas las macros como mapa. |
146
+ | `getVariable(name)` → `Object` | Lee variable de scope (en memoria, no se persiste). |
147
+ | `setVariable(name, value)` | Asigna variable de scope. |
148
+ | `getVariables(name)` / `setVariables(name, value)` | **Obsoletos.** Alias de `getVariable`/`setVariable`; usar las formas en singular. |
149
+ | `getAllVariables()` → `Map<String,Object>` | Todas las variables. |
150
+
151
+ > **Importante:** Para usar `setMacro` hay que declarar previamente el nodo `<macro name="##X##" value="" default="true" />` como hijo directo de `<coll>`.
152
+
153
+ ### 2.8 Metadatos y propiedades
154
+
155
+ | Método | Descripción |
156
+ |---|---|
157
+ | `getCollPropertyValue(attr)` → `String` | Lee un atributo XML del nodo `<coll>` (p.ej. `"sql"`, `"loadall"`). |
158
+ | `getGroupCount()` → `int` | Número de grupos. |
159
+ | `getGroup(index)` → `String` | Nombre del grupo por índice. |
160
+ | `getPropertyCount()` → `int` | Número de propiedades. |
161
+ | `getPropertyName(index)` / `propertyName(index)` → `String` | Nombre del campo por índice. |
162
+ | `getPropType(name)` / `propType(name)` → `String` | Tipo del campo (`T`, `TL`, `N`, `NC`, `Z`, `D`, etc.). |
163
+ | `getPropertyTitle(name)` → `String` | Título visible del campo. |
164
+ | `getPropertyGroup(name)` → `String` | Nombre del grupo al que pertenece el campo. |
165
+ | `getPropVisibility(name)` / `propVisibility(name)` → `String` | Visibilidad bitmask del campo. |
166
+ | `bind(...)` / `unbind(...)` | Vincula/desvincula eventos. |
167
+ | `clearCaches()` | Propaga `clearCaches()` a todos los objetos cargados en memoria (vacía la caché de atributos resueltos de cada uno). |
168
+
169
+ ### 2.9 SQL directo y JSON
170
+
171
+ | Método | Descripción |
172
+ |---|---|
173
+ | `executeSqlString(sql)` → `Object` | Ejecuta SQL contra la conexión de la coll. **Las macros (`##X##`) se sustituyen automáticamente** en el SQL antes de ejecutarlo. |
174
+ | `toJson()` → `Object[]` | Serializa todos los objetos en memoria a un array. |
175
+ | `loadFromJson(jsonArray, [{strictMode: true}])` → `datacollection` | Hidrata la coleccion desde un array. **Vacía la coll antes de cargar.** Acepta un array JSON o un string parseable como JSON. Con `strictMode: true` ignora campos no declarados en el mapping. |
176
+
177
+ ```js
178
+ // Ejemplo: clonar coleccion para filtrar sin afectar la original
179
+ var colOriginal = appData.getCollection("Articulos");
180
+ var colFiltrada = colOriginal.createClone();
181
+ colFiltrada.setFilter("activo = 1");
182
+ colFiltrada.reload();
183
+ appData.writeConsoleString("Articulos activos: " + colFiltrada.getCount());
184
+ ```
185
+
186
+ ---
187
+
188
+ ## 3. err / error — Objeto de Error Global
189
+
190
+ `err` (alias `error`) es el objeto de error global del framework. Se actualiza automáticamente cuando se produce un error en operaciones de BD, guardado, etc.
191
+
192
+ | Método | Descripción |
193
+ |---|---|
194
+ | `getNumber()` → `int` | Código de error. `0` significa sin error. |
195
+ | `setNumber(value)` | Asigna un código de error personalizado. |
196
+ | `getDescription()` → `String` | Descripción/mensaje del error. |
197
+ | `setDescription(value)` | Asigna un mensaje de error personalizado. |
198
+ | `getFailedSql()` → `String` | La sentencia SQL que provoco el error (si aplica). |
199
+ | `clear()` | Limpia el estado de error (pone número a 0 y descripción a ""). |
200
+ | `toString()` → `String` | Serialización legible: `"[código] descripción"`. |
201
+
202
+ ```js
203
+ // Patron de verificación de errores tras operación
204
+ self.save();
205
+ if (err.getNumber() != 0) {
206
+ appData.writeConsoleString("Error " + err.getNumber() + ": " + err.getDescription());
207
+ if (err.getFailedSql()) {
208
+ appData.writeConsoleString("SQL: " + err.getFailedSql());
209
+ }
210
+ err.clear();
211
+ }
212
+ ```
213
+
214
+ ```js
215
+ // Usar failWithMessage para lanzar un error controlado
216
+ // (detiene la ejecución del flujo y propaga el código y mensaje)
217
+ if (!self.getValue("DNI")) {
218
+ appData.failWithMessage(101, "El DNI es obligatorio");
219
+ }
220
+ ```
221
+
222
+ ### 3.1 Excepciones del framework
223
+
224
+ | Excepción | Causa típica |
225
+ |---|---|
226
+ | `XoneGenericException` | Error generico del framework. |
227
+ | `XoneFailWithMessageException` | Lanzada por `appData.failWithMessage(code, msg)`. |
228
+ | `XOneJavascriptException` | Error en el motor JS (sintaxis, variable no definida, etc.). |
229
+ | `FormulaParseException` | Error al parsear una formula de atributo XML. |
230
+ | `LocationNotFoundException` | No hay fix GPS disponible. |
231
+ | `PluginNotInstalledException` | Plugin requerido no esta instalado. |
232
+
233
+ ```js
234
+ try {
235
+ self.save();
236
+ } catch (e) {
237
+ appData.writeConsoleString("Excepcion: " + e);
238
+ err.setNumber(-1);
239
+ err.setDescription(e.toString());
240
+ }
241
+ ```
242
+
243
+ ---
244
+
245
+ ## 4. user — Usuario Logueado
246
+
247
+ `user` representa la fila del usuario que ha iniciado sesión. Hereda **toda la API de `self` / `dataobject`**: `getValue`, `setValue`, `save`, `executeNode`, `getOwnerCollection`, etc.
248
+
249
+ ```js
250
+ var nombre = user.getValue("NOMBRE");
251
+ var rol = user.getValue("ROL");
252
+ var empresa = user.getValue("IDEMPRESA");
253
+
254
+ // user tiene las mismas propiedades que cualquier dataobject
255
+ user.setValue("ULTIMO_ACCESO", new Date().toISOString());
256
+ user.save();
257
+ ```
258
+
259
+ > **Nota:** Si el mapping no tiene coleccion de login configurada, `user` sera `null`. Verificar antes de usar en pantallas de acceso publico.
260
+
@@ -0,0 +1,245 @@
1
+ # XOne JavaScript — Debugging y top 20 de buenas prácticas
2
+
3
+ > Fuente: `xone/v2/xone-help-docs/topics/03e-js-patrones-buenas-practicas.md` §14–§15. Referencia de la skill; el índice está en [../../SKILL.md](../../SKILL.md).
4
+
5
+ Contenido: §14 debugging y troubleshooting de JavaScript · §15 top 20 de buenas prácticas
6
+
7
+ ---
8
+
9
+ ## 14. Debugging y Troubleshooting
10
+
11
+ ### 14.1 console.* (API WHATWG completa)
12
+
13
+ ```javascript
14
+ // Métodos disponibles: log, info, debug, warn, error, trace, assert,
15
+ // group, groupCollapsed, groupEnd, time, timeLog, timeEnd,
16
+ // count, countReset, dir, dirxml, clear, table
17
+ console.log("Valor de campo: " + self.MAP_NOMBRE);
18
+ console.warn("Aviso: parámetro fuera de rango");
19
+ console.error("Error al guardar:", err); // varargs soportados
20
+ console.info("Carga completada");
21
+ console.debug("Estado interno:", { id: 42, ok: true });
22
+
23
+ // Formato con placeholders %s/%d/%i/%f/%o/%O/%j/%%
24
+ console.log("Usuario %s tiene %d puntos", nombre, puntos);
25
+
26
+ // Agrupar logs
27
+ console.group("Procesando pedido");
28
+ console.log("ID:", pedido.ID);
29
+ console.log("Líneas:", pedido.LINEAS.length);
30
+ console.groupEnd();
31
+
32
+ // Medir tiempos
33
+ console.time("consulta");
34
+ let res = $http.get(url, req, ok, err);
35
+ console.timeEnd("consulta"); // "consulta: 142ms"
36
+
37
+ // Log condicional
38
+ function logDebug(mensaje) {
39
+ if (appData.getCurrentEnterprise().getVariable("Debug") === true) {
40
+ console.debug("DEBUG: " + mensaje);
41
+ }
42
+ }
43
+
44
+ // Alternativa: consola del framework (XOne-specific)
45
+ appData.writeConsoleString("Debug: proceso iniciado");
46
+ ```
47
+
48
+ ### 14.2 ui.showToast() para Debug Rápido
49
+
50
+ ```javascript
51
+ function debugToast(variable, nombre) {
52
+ ui.showToast(nombre + " = " + cstr(variable));
53
+ }
54
+
55
+ // Ejemplos
56
+ debugToast(self.MAP_ESTADO, "Estado");
57
+ debugToast(typeof self.MAP_PRECIO, "Tipo precio");
58
+ debugToast(self.getOwnerCollection().getName(), "Coleccion");
59
+
60
+ function debugMsgBox(variable, nombre) {
61
+ ui.msgBox(nombre + " = " + cstr(variable) + "\nTipo: " + typeof variable, "Debug", 0);
62
+ }
63
+ ```
64
+
65
+ ### 14.3 try/catch
66
+
67
+ ```javascript
68
+ function operacionSegura() {
69
+ try {
70
+ let resultado = operacionRiesgosa();
71
+ if (!resultado) throw "No se pudo completar la operación";
72
+ return resultado;
73
+ } catch(ex) {
74
+ console.log("Error en operacionSegura: " + ex);
75
+ appData.writeConsoleString("Error: " + ex);
76
+ ui.showToast("Error: " + ex);
77
+ return null;
78
+ } finally {
79
+ ui.hideWaitDialog();
80
+ }
81
+ }
82
+
83
+ // Verificar errores del framework
84
+ function verificarErrores() {
85
+ let error = appData.error();
86
+ if (error.getNumber() != 0) {
87
+ console.log("Código: " + error.getNumber());
88
+ console.log("Descripción: " + error.getDescription());
89
+ console.log("SQL fallido: " + error.getFailedSql());
90
+ error.clear();
91
+ return true;
92
+ }
93
+ return false;
94
+ }
95
+ ```
96
+
97
+ ### 14.4 Errores Comunes y Soluciones
98
+
99
+ | Error | Causa | Solución |
100
+ |-------|-------|----------|
101
+ | `self es null` | Se accede a `self` fuera de contexto | Guardar referencia antes de callbacks asíncronos |
102
+ | `coleccion bloqueada` | Se intenta addItem sin unlock | Usar patron `coll.unlock(); try {...} finally { coll.lock(); }` |
103
+ | `NaN en calculos` | Valor null/undefined en operación matematica | Usar `cnum()` para conversiones numéricas seguras |
104
+ | `campo no encontrado` | Nombre de propiedad incorrecto | Verificar nombre exacto en el XML (sensible a mayusculas) |
105
+ | `cursor no cerrado` | Fuga de recursos SQL | SIEMPRE cerrar cursor en bloque `finally` |
106
+ | `WaitDialog no desaparece` | Error antes de `hideWaitDialog()` | Usar `try/finally` para garantizar que se oculte |
107
+ | `GPS STATUS != 1` | GPS no activado o sin cobertura | Verificar `ui.checkGpsStatus()` y pedir permiso |
108
+ | `Error en JSON.parse` | Respuesta del servidor no es JSON valido | Envolver en try/catch y verificar la respuesta |
109
+ | `window es null` | Pantalla cerrada mientras se ejecuta callback | Verificar `window != null` antes de acceder a controles |
110
+ | `refresh no actualiza` | Nombre de campo incorrecto en refresh | Usar el nombre exacto de la propiedad (MAP_CAMPO) |
111
+
112
+ ---
113
+
114
+ ## 15. Best Practices - Top 20
115
+
116
+ ### 1. Guardar referencia de `self` antes de callbacks asíncronos
117
+
118
+ ```javascript
119
+ let miObjeto = self;
120
+ $http.get(url, request, function(sData) {
121
+ miObjeto.MAP_DATO = sData; // CORRECTO
122
+ // self.MAP_DATO = sData; // INCORRECTO
123
+ }, errorCb);
124
+ ```
125
+
126
+ ### 2. Siempre usar lock/unlock al modificar colecciones
127
+
128
+ ```javascript
129
+ coll.unlock();
130
+ try {
131
+ let obj = coll.createObject();
132
+ coll.addItem(obj);
133
+ } finally {
134
+ coll.lock();
135
+ }
136
+ ```
137
+
138
+ ### 3. Usar `isEmpty()`, `cstr()`, `cnum()` para conversiones seguras
139
+
140
+ Nunca acceder a valores sin verificar que no sean null/undefined.
141
+
142
+ ### 4. Refrescar solo los campos necesarios
143
+
144
+ ```javascript
145
+ ui.refresh("MAP_NOMBRE,MAP_ESTADO"); // CORRECTO
146
+ ui.refresh(); // INCORRECTO - refresca todo
147
+ ```
148
+
149
+ ### 5. Usar consultas parametrizadas para prevenir SQL injection
150
+
151
+ ```javascript
152
+ sqlManager.doRawQuery("SELECT * FROM tabla WHERE campo=?", valor);
153
+ ```
154
+
155
+ ### 6. Cerrar cursores y conexiones SQL en bloques `finally`
156
+
157
+ ```javascript
158
+ try { cursor = sqlManager.doRawQuery(...);
159
+ try { /* usar cursor */ } finally { cursor.close(); }
160
+ } finally { sqlManager.close(); }
161
+ ```
162
+
163
+ ### 7. Ocultar WaitDialog en bloque `finally`
164
+
165
+ ```javascript
166
+ ui.showWaitDialog("Cargando...");
167
+ try { /* operacion */ }
168
+ catch(ex) { ui.showToast("Error: " + ex); }
169
+ finally { ui.hideWaitDialog(); }
170
+ ```
171
+
172
+ ### 8. Verificar existencia de objetos antes de usarlos
173
+
174
+ ```javascript
175
+ let usuario = coll.findObject("ID = 1");
176
+ if (!usuario) { ui.showToast("No encontrado"); return; }
177
+ ```
178
+
179
+ ### 9. No usar APIs web que no existen en XOne
180
+
181
+ No `document`, `window`, `localStorage`, `XMLHttpRequest`, `navigator`. **Sí** existen, con implementación custom y semántica compatible: `Promise` (full ES2024 incluyendo `all`/`allSettled`/`race`/`any`/`withResolvers`), `fetch`, `setTimeout`/`setInterval`, `URL`, `Headers`, `AbortController`, `TextEncoder`/`TextDecoder`, `console.{log,warn,error,...}`, `performance.now()`, `atob`/`btoa`.
182
+
183
+ ### 10. `getControl(name, [dataObject])` es NATIVO — no redeclararlo
184
+
185
+ Es una función global del motor (Rhino y V8). Firma:
186
+ - `getControl(name)` → control en la última ventana visible.
187
+ - `getControl(name, dataObject)` → control en la ventana asociada a ese DataObject.
188
+
189
+ Semántica estricta: lanza error si el nombre está vacío, el control no existe en la ventana destino, no hay ventana, o el dataObject no es válido. No hace falta verificar null.
190
+
191
+ Proyectos antiguos con su propio `function getControl(...){...}` siguen funcionando: la declaración del script sombrea a la nativa en el scope local del script.
192
+
193
+ ### 11. Usar `ui.executeActionAfterDelay()` en lugar de `ui.sleep()`
194
+
195
+ `sleep()` bloquea toda la interfaz. `executeActionAfterDelay()` no.
196
+
197
+ ### 12. Nunca hardcodear credenciales en el código
198
+
199
+ Usar macros globales o almacenamiento encriptado.
200
+
201
+ ### 13. Validar datos antes de guardar (patron validarFormulario)
202
+
203
+ Verificar campos obligatorios, rangos y formatos antes de `save()`.
204
+
205
+ ### 14. Organizar functions.js en secciones claras
206
+
207
+ Constantes, utilidades, navegación, mensajes, datos, validaciones, inicialización.
208
+
209
+ ### 15. Usar `try/catch` en operaciones que pueden fallar
210
+
211
+ Especialmente: operaciones de red, acceso a BD, GPS, camara, archivos.
212
+
213
+ ### 16. Liberar colecciones con `clear()` después de usarlas
214
+
215
+ Previene acumulacion de objetos en memoria.
216
+
217
+ ### 17. Usar `saveAll()` al final en lugar de `save()` individual en bucles
218
+
219
+ Una sola escritura a BD en lugar de N.
220
+
221
+ ### 18. Documentar funciones con proposito, parámetros y retorno
222
+
223
+ ```javascript
224
+ /**
225
+ * Calcula el precio con descuento
226
+ * @param {number} precio - Precio original
227
+ * @param {number} descuento - Porcentaje de descuento (0-100)
228
+ * @returns {number} - Precio con descuento aplicado
229
+ */
230
+ function calcularDescuento(precio, descuento) { ... }
231
+ ```
232
+
233
+ ### 19. Usar constantes para valores magicos
234
+
235
+ ```javascript
236
+ var ESTADOS = { ACTIVO: "ACTIVO", INACTIVO: "INACTIVO" };
237
+ if (estado == ESTADOS.ACTIVO) ...
238
+ ```
239
+
240
+ ### 20. Separar lógica de negocio de la lógica de UI
241
+
242
+ Funciones que calculan o procesan datos NO deben contener `ui.showToast()`. Las funciones de UI llaman a las de negocio y muestran los resultados.
243
+
244
+ > **Referencia cruzada:** Para la estructura de carpetas del proyecto y como se integran los archivos JS, consultar el tópico 01 - Fundamentos (cubre también la guía de creación de proyectos nuevos).
245
+