nexabase-report 0.28.1 → 0.28.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/NEXAREPORT.md +3 -3
- package/README.md +23 -0
- package/bin/nexabase-report-ai.mjs +47 -0
- package/dist/{generated-BjsMhDVX.js → generated-BnErILTW.js} +30 -0
- package/dist/{html2pdf-B3mAxkNT.js → html2pdf-jHo6I3W3.js} +2 -2
- package/dist/{index-n-ggfS1p.js → index-Dc1HlUG3.js} +8 -8
- package/dist/{index.es-5IFpweNE.js → index.es-CKZ1d9_J.js} +2 -2
- package/dist/{jspdf.es.min-C6M8fb8R.js → jspdf.es.min-Ce1kkozr.js} +1 -1
- package/dist/nexabase-report.es.js +1 -1
- package/dist/nexabase-report.umd.js +25 -2
- package/dist/{pptxgen.es-KpBnHDuC.js → pptxgen.es-DRuTW2iV.js} +1 -1
- package/package.json +5 -1
package/NEXAREPORT.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- nexabase-report@0.28.
|
|
1
|
+
<!-- nexabase-report@0.28.3 — generado por scripts/gen-ai-context.mjs, no editar a mano -->
|
|
2
2
|
# NexaReport — referencia para agentes de IA
|
|
3
3
|
|
|
4
4
|
> Este archivo se genera desde los tipos TypeScript reales del paquete (`src/lib/types/report.ts`
|
|
@@ -281,10 +281,10 @@ El schema formal completo (todas las interfaces, no solo bandas/elementos) está
|
|
|
281
281
|
`nexabase-report/schema`, así que es accesible sin instalar nada vía:
|
|
282
282
|
|
|
283
283
|
```
|
|
284
|
-
https://unpkg.com/nexabase-report@0.28.
|
|
284
|
+
https://unpkg.com/nexabase-report@0.28.3/schema/nexareport.schema.json
|
|
285
285
|
```
|
|
286
286
|
|
|
287
|
-
(cambia `@0.28.
|
|
287
|
+
(cambia `@0.28.3` por `@latest` para la versión más reciente). Valida el JSON generado
|
|
288
288
|
contra ese schema antes de darlo por bueno — evita que un campo inventado llegue al usuario.
|
|
289
289
|
|
|
290
290
|
Más ejemplos reales (subreportes, crosstab, master-detail, códigos de barras) en `examples/*.json`
|
package/README.md
CHANGED
|
@@ -241,6 +241,29 @@ Reports use a banded structure:
|
|
|
241
241
|
|
|
242
242
|
`Text`, `Image`, `Barcode`, `QRCode`, `Rectangle`, `Ellipse`, `Line`, `Arrow`, `Table`, `Chart`, `Crosstab`, `SubReport`, `DrillDown`
|
|
243
243
|
|
|
244
|
+
## AI-Assisted Report Generation
|
|
245
|
+
|
|
246
|
+
Let your AI coding assistant (Claude Code, Gemini CLI, OpenCode, Cursor...) build report JSON for
|
|
247
|
+
you — one command, run once per project:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
npx nexabase-report-ai
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
This detects your project's AI instructions file (`CLAUDE.md`, `AGENTS.md`, `GEMINI.md`,
|
|
254
|
+
`.cursorrules`) — or creates `AGENTS.md` if none exists — and adds a pointer to the always-current
|
|
255
|
+
report reference and JSON Schema (served straight from the published package, so it's never
|
|
256
|
+
stale):
|
|
257
|
+
|
|
258
|
+
- `https://unpkg.com/nexabase-report@latest/NEXAREPORT.md` — band/element types, binding syntax,
|
|
259
|
+
worked examples
|
|
260
|
+
- `https://unpkg.com/nexabase-report@latest/schema/nexareport.schema.json` — the formal schema, to
|
|
261
|
+
validate generated JSON before trusting it
|
|
262
|
+
|
|
263
|
+
From then on, any assistant that reads your project's instructions file already knows the current
|
|
264
|
+
report format — no manual copy-pasting, and it can't drift out of date since both files are
|
|
265
|
+
regenerated from the real TypeScript types on every published version.
|
|
266
|
+
|
|
244
267
|
## Expression Engine
|
|
245
268
|
|
|
246
269
|
Safe evaluation without `eval`. Supports:
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// npx nexabase-report-ai -> agrega, UNA vez, el puntero a NEXAREPORT.md/schema en el archivo
|
|
3
|
+
// de instrucciones de IA que ya tenga el proyecto (CLAUDE.md/AGENTS.md/GEMINI.md/.cursorrules).
|
|
4
|
+
// Idempotente: si ya está, no duplica nada.
|
|
5
|
+
import { readFile, writeFile, appendFile } from 'node:fs/promises';
|
|
6
|
+
import { existsSync } from 'node:fs';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
|
|
9
|
+
const cwd = process.cwd();
|
|
10
|
+
const MARKER = '<!-- nexabase-report:ai-context -->';
|
|
11
|
+
|
|
12
|
+
const BLOCK = `
|
|
13
|
+
${MARKER}
|
|
14
|
+
## NexaReport
|
|
15
|
+
|
|
16
|
+
Antes de crear o modificar un reporte de NexaReport (JSON \`NexaReportDefinition\`), lee
|
|
17
|
+
https://unpkg.com/nexabase-report@latest/NEXAREPORT.md y valida el JSON generado contra
|
|
18
|
+
https://unpkg.com/nexabase-report@latest/schema/nexareport.schema.json antes de entregarlo.
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
const candidates = ['CLAUDE.md', 'AGENTS.md', 'GEMINI.md', '.cursorrules'];
|
|
22
|
+
const found = candidates.filter(f => existsSync(join(cwd, f)));
|
|
23
|
+
|
|
24
|
+
async function addTo(file) {
|
|
25
|
+
const path = join(cwd, file);
|
|
26
|
+
const current = existsSync(path) ? await readFile(path, 'utf-8') : '';
|
|
27
|
+
if (current.includes(MARKER)) {
|
|
28
|
+
console.log(` = ${file} ya tiene la sección de NexaReport, sin cambios`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (current) {
|
|
32
|
+
await appendFile(path, '\n' + BLOCK);
|
|
33
|
+
} else {
|
|
34
|
+
await writeFile(path, BLOCK.trimStart() + '\n');
|
|
35
|
+
}
|
|
36
|
+
console.log(` + ${file} actualizado`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (found.length > 0) {
|
|
40
|
+
for (const f of found) await addTo(f);
|
|
41
|
+
} else {
|
|
42
|
+
// Ningún archivo de instrucciones detectado: crea AGENTS.md, la convención más genérica
|
|
43
|
+
// (la leen Claude Code, Gemini CLI, OpenCode, Cursor y otros).
|
|
44
|
+
await addTo('AGENTS.md');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
console.log('\nListo. Cualquier IA que lea ese archivo ya sabe consultar el formato actual de NexaReport.');
|
|
@@ -859,6 +859,36 @@ promedio…). No dependen de la banda en la que estén, porque no hay bandas.</l
|
|
|
859
859
|
<p>Los formatos pensados para documentos —Word, PPTX— y los de datos —Excel, CSV— están orientados a
|
|
860
860
|
reportes paginados. Si necesitas repartir cifras periódicamente por correo o en un archivo, el
|
|
861
861
|
formato adecuado es un <strong>reporte</strong>, no un dashboard.</p>
|
|
862
|
+
`
|
|
863
|
+
},
|
|
864
|
+
{
|
|
865
|
+
id: "ia-generacion",
|
|
866
|
+
title: "Generar reportes con IA",
|
|
867
|
+
search: "ia, ai, claude, gemini, copilot, cursor, prompt, generar, automatizar, npx generar reportes con ia si integras nexareport en tu app, no necesitas armar el json del reporte a mano ni empezar desde cero en el diseñador: un asistente de ia puede generarlo por ti. configuración (un comando, una sola vez) desde la carpeta de tu proyecto: npx nexabase report ai ese comando detecta el archivo de instrucciones que tu asistente ya lee solo ( claude.md , agents.md , gemini.md , .cursorrules ) —o crea agents.md si no encuentra ninguno— y le agrega el puntero al formato actual de nexareport. no hay nada que copiar ni pegar a mano, y si lo corres de nuevo no duplica nada. de ahí en adelante, cualquier desarrollador del equipo , en cualquier sesión , con cualquier reporte que pida, la ia ya sabe consultar sola el formato actual — sin volver a tocar nada. por qué siempre está al día el comando apunta a nexabase report@latest en npm, no a una copia local: el documento de referencia y el schema formal se regeneran automáticamente en cada versión publicada, directo desde el código. nunca vas a recibir un json con un campo que ya no existe, o le falte uno nuevo (como staticpage , para reportes de páginas fijas). después de generarlo pega el json resultante en el diseñador ( importar json ) para revisarlo visualmente y ajustar posiciones, colores o binding fino — la ia arma la estructura, el diseñador es donde lo dejas exacto.",
|
|
868
|
+
element: "",
|
|
869
|
+
html: `<h1>Generar reportes con IA</h1>
|
|
870
|
+
<p>Si integras NexaReport en tu app, no necesitas armar el JSON del reporte a mano ni empezar desde
|
|
871
|
+
cero en el diseñador: un asistente de IA puede generarlo por ti.</p>
|
|
872
|
+
<h2>Configuración (un comando, una sola vez)</h2>
|
|
873
|
+
<p>Desde la carpeta de tu proyecto:</p>
|
|
874
|
+
<pre><code>npx nexabase-report-ai
|
|
875
|
+
</code></pre>
|
|
876
|
+
<p>Ese comando detecta el archivo de instrucciones que tu asistente ya lee solo (<code>CLAUDE.md</code>,
|
|
877
|
+
<code>AGENTS.md</code>, <code>GEMINI.md</code>, <code>.cursorrules</code>) —o crea <code>AGENTS.md</code> si no encuentra ninguno— y le agrega
|
|
878
|
+
el puntero al formato actual de NexaReport. No hay nada que copiar ni pegar a mano, y si lo
|
|
879
|
+
corres de nuevo no duplica nada.</p>
|
|
880
|
+
<p>De ahí en adelante, <strong>cualquier desarrollador del equipo</strong>, en <strong>cualquier sesión</strong>, con
|
|
881
|
+
<strong>cualquier reporte</strong> que pida, la IA ya sabe consultar sola el formato actual — sin volver a
|
|
882
|
+
tocar nada.</p>
|
|
883
|
+
<h2>Por qué siempre está al día</h2>
|
|
884
|
+
<p>El comando apunta a <code>nexabase-report@latest</code> en npm, no a una copia local: el documento de
|
|
885
|
+
referencia y el schema formal se regeneran automáticamente en cada versión publicada, directo
|
|
886
|
+
desde el código. Nunca vas a recibir un JSON con un campo que ya no existe, o le falte uno nuevo
|
|
887
|
+
(como <code>StaticPage</code>, para reportes de páginas fijas).</p>
|
|
888
|
+
<h2>Después de generarlo</h2>
|
|
889
|
+
<p>Pega el JSON resultante en el diseñador (<strong>Importar JSON</strong>) para revisarlo visualmente y ajustar
|
|
890
|
+
posiciones, colores o binding fino — la IA arma la estructura, el diseñador es donde lo dejas
|
|
891
|
+
exacto.</p>
|
|
862
892
|
`
|
|
863
893
|
}
|
|
864
894
|
];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { g as Nl, c as ut, d as Vl } from "./index-
|
|
2
|
-
import { j as Xl } from "./jspdf.es.min-
|
|
1
|
+
import { g as Nl, c as ut, d as Vl } from "./index-Dc1HlUG3.js";
|
|
2
|
+
import { j as Xl } from "./jspdf.es.min-Ce1kkozr.js";
|
|
3
3
|
function Jl(Pe, br) {
|
|
4
4
|
for (var fe = 0; fe < br.length; fe++) {
|
|
5
5
|
const HA = br[fe];
|
|
@@ -93562,7 +93562,7 @@ function RWe(t) {
|
|
|
93562
93562
|
let A = null, p = null;
|
|
93563
93563
|
try {
|
|
93564
93564
|
await new Promise((H) => setTimeout(H, 50)), typeof document < "u" && ((g = document.fonts) != null && g.ready) && await document.fonts.ready, A = await L5(t.reportPaperRef.value, t.apiBaseUrl), p = await H5(t.reportPaperRef.value);
|
|
93565
|
-
const { default: y } = await import("./html2pdf-
|
|
93565
|
+
const { default: y } = await import("./html2pdf-jHo6I3W3.js").then((H) => H.h), E = t.reportDef.value, B = E.layout.page, x = (((v = E.metadata) == null ? void 0 : v.name) || "reporte") + ".pdf", I = t.reportPaperRef.value.querySelector(".report-page"), S = (I == null ? void 0 : I.offsetWidth) || t.reportPaperRef.value.offsetWidth || void 0, M = (I == null ? void 0 : I.offsetHeight) || void 0, C = Math.min(3, Math.max(2, (typeof window < "u" ? window.devicePixelRatio : 2) || 2)), Q = (I == null ? void 0 : I.offsetWidth) || 794, T = (I == null ? void 0 : I.offsetHeight) || 1123, F = Math.max(1, t.pagination.value.totalPages), U = await y().set({
|
|
93566
93566
|
filename: x,
|
|
93567
93567
|
margin: 0,
|
|
93568
93568
|
image: { type: "jpeg", quality: 0.98 },
|
|
@@ -93593,7 +93593,7 @@ function RWe(t) {
|
|
|
93593
93593
|
}
|
|
93594
93594
|
async function a() {
|
|
93595
93595
|
var G;
|
|
93596
|
-
const h = t.reportDef.value, { jsPDF: A } = await import("./jspdf.es.min-
|
|
93596
|
+
const h = t.reportDef.value, { jsPDF: A } = await import("./jspdf.es.min-Ce1kkozr.js").then((k) => k.j), p = h.layout.page, g = p.orientation === "landscape";
|
|
93597
93597
|
let v = 210, m = 297;
|
|
93598
93598
|
if (p.format === "Letter" ? (v = 215.9, m = 279.4) : p.format === "Ticket" && (v = 80, m = 200), g) {
|
|
93599
93599
|
const k = v;
|
|
@@ -93950,7 +93950,7 @@ function RWe(t) {
|
|
|
93950
93950
|
t.isExportingPdf.value = !0;
|
|
93951
93951
|
try {
|
|
93952
93952
|
await new Promise((U) => setTimeout(U, 50)), typeof document < "u" && ((A = document.fonts) != null && A.ready) && await document.fonts.ready;
|
|
93953
|
-
const v = await L5(t.reportPaperRef.value, t.apiBaseUrl), m = await H5(t.reportPaperRef.value), { default: y } = await import("./html2pdf-
|
|
93953
|
+
const v = await L5(t.reportPaperRef.value, t.apiBaseUrl), m = await H5(t.reportPaperRef.value), { default: y } = await import("./html2pdf-jHo6I3W3.js").then((U) => U.h), B = t.reportDef.value.layout.page, x = t.reportPaperRef.value.querySelector(".report-page"), I = (x == null ? void 0 : x.offsetWidth) || t.reportPaperRef.value.offsetWidth || void 0, S = (x == null ? void 0 : x.offsetHeight) || void 0, M = Math.min(3, Math.max(2, (typeof window < "u" ? window.devicePixelRatio : 2) || 2)), C = (x == null ? void 0 : x.offsetWidth) || 794, Q = (x == null ? void 0 : x.offsetHeight) || 1123, T = Math.max(1, t.pagination.value.totalPages), b = await y().set({
|
|
93954
93954
|
filename: "report.pdf",
|
|
93955
93955
|
margin: 0,
|
|
93956
93956
|
image: { type: "jpeg", quality: 0.98 },
|
|
@@ -94134,7 +94134,7 @@ ${E.outerHTML}
|
|
|
94134
94134
|
t.isExportingPdf.value = !0;
|
|
94135
94135
|
try {
|
|
94136
94136
|
await new Promise((T) => setTimeout(T, 50)), typeof document < "u" && ((g = document.fonts) != null && g.ready) && await document.fonts.ready;
|
|
94137
|
-
const m = await L5(A, t.apiBaseUrl), y = await H5(A), { default: E } = await import("./html2pdf-
|
|
94137
|
+
const m = await L5(A, t.apiBaseUrl), y = await H5(A), { default: E } = await import("./html2pdf-jHo6I3W3.js").then((T) => T.h), { default: B } = await import("./pptxgen.es-DRuTW2iV.js"), x = Array.from(A.querySelectorAll(".report-page"));
|
|
94138
94138
|
if (x.length === 0) {
|
|
94139
94139
|
Si("PPTX export — no rendered pages were found", null);
|
|
94140
94140
|
return;
|
|
@@ -94484,7 +94484,7 @@ const UWe = {
|
|
|
94484
94484
|
}
|
|
94485
94485
|
return !!de;
|
|
94486
94486
|
}
|
|
94487
|
-
const o = it(() => a(n.minimal)), s = it(() => a(n.fluid)), l = it(() => !o.value || a(n.showThumbs)), c = it(() => !o.value || a(n.showToolbar)), u = We(!1), f = it(() => "0.28.
|
|
94487
|
+
const o = it(() => a(n.minimal)), s = it(() => a(n.fluid)), l = it(() => !o.value || a(n.showThumbs)), c = it(() => !o.value || a(n.showToolbar)), u = We(!1), f = it(() => "0.28.3"), d = it(() => "2026-08-28T03:08:50.080Z"), h = it(() => A.value), A = We(n.locale || "es"), p = We(!a(n.minimal)), g = We("pages"), v = We(""), m = We(!1), y = it(() => {
|
|
94488
94488
|
const de = v.value.toLowerCase().trim();
|
|
94489
94489
|
return de ? ge.value.filter((ve) => ve.title.toLowerCase().includes(de)) : ge.value;
|
|
94490
94490
|
});
|
|
@@ -94546,7 +94546,7 @@ const UWe = {
|
|
|
94546
94546
|
let Ae = null;
|
|
94547
94547
|
async function Qe() {
|
|
94548
94548
|
if (Ae) return Ae;
|
|
94549
|
-
const de = await import("./html2pdf-
|
|
94549
|
+
const de = await import("./html2pdf-jHo6I3W3.js").then((ve) => ve.h);
|
|
94550
94550
|
return Ae = (de == null ? void 0 : de.default) || de, Ae;
|
|
94551
94551
|
}
|
|
94552
94552
|
async function _e(de) {
|
|
@@ -111973,7 +111973,7 @@ const nit = { class: "nd-help-panel" }, iit = { class: "nd-help-head" }, ait = {
|
|
|
111973
111973
|
if (!(i.value.length || a.value)) {
|
|
111974
111974
|
a.value = !0;
|
|
111975
111975
|
try {
|
|
111976
|
-
const h = await import("./generated-
|
|
111976
|
+
const h = await import("./generated-BnErILTW.js");
|
|
111977
111977
|
i.value = h.helpTopics, o.value || c(r.contextElement);
|
|
111978
111978
|
} finally {
|
|
111979
111979
|
a.value = !1;
|
|
@@ -126144,7 +126144,7 @@ const upt = { class: "nd-rt-toolbar" }, dpt = ["title"], fpt = ["title"], hpt =
|
|
|
126144
126144
|
function Ah(ne, _) {
|
|
126145
126145
|
fl(ne, _, W, V);
|
|
126146
126146
|
}
|
|
126147
|
-
const gu = We(!1), po = We(!1), k0 = We(!1), Zn = We("home"), Ua = We(null), go = We(""), vu = it(() => "0.28.
|
|
126147
|
+
const gu = We(!1), po = We(!1), k0 = We(!1), Zn = We("home"), Ua = We(null), go = We(""), vu = it(() => "0.28.3"), vo = it(() => "2026-08-28T03:08:50.080Z"), mu = it(() => ({
|
|
126148
126148
|
home: d("tab_file"),
|
|
126149
126149
|
new: d("new"),
|
|
126150
126150
|
open: d("open"),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as Va, d as il } from "./index-
|
|
2
|
-
import { _ as La } from "./jspdf.es.min-
|
|
1
|
+
import { c as Va, d as il } from "./index-Dc1HlUG3.js";
|
|
2
|
+
import { _ as La } from "./jspdf.es.min-Ce1kkozr.js";
|
|
3
3
|
var fn = {}, cn = {}, cr, vn;
|
|
4
4
|
function Q() {
|
|
5
5
|
if (vn) return cr;
|
|
@@ -7303,7 +7303,7 @@ function wu(n) {
|
|
|
7303
7303
|
*/
|
|
7304
7304
|
(function(n) {
|
|
7305
7305
|
function e() {
|
|
7306
|
-
return (Ht.canvg ? Promise.resolve(Ht.canvg) : import("./index.es-
|
|
7306
|
+
return (Ht.canvg ? Promise.resolve(Ht.canvg) : import("./index.es-CKZ1d9_J.js")).catch((function(r) {
|
|
7307
7307
|
return Promise.reject(new Error("Could not load canvg: " + r));
|
|
7308
7308
|
})).then((function(r) {
|
|
7309
7309
|
return r.default ? r.default : r;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as s, N as r, a as t, S as E, b as m, i, r as l, e as o, t as p } from "./index-
|
|
1
|
+
import { D as s, N as r, a as t, S as E, b as m, i, r as l, e as o, t as p } from "./index-Dc1HlUG3.js";
|
|
2
2
|
export {
|
|
3
3
|
s as DEFAULT_THEME,
|
|
4
4
|
r as NexaDesignerElement,
|