@agile-team/mach-report 2.5.0 → 2.6.1
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/README.md +91 -14
- package/dist/ReportPreview-Dk-28QAi.js +2946 -0
- package/dist/ReportPreview-FSvcBLjH.cjs +6 -0
- package/dist/_plugin-vue_export-helper-BHFhmbuH.cjs +1 -0
- package/dist/_plugin-vue_export-helper-CHgC5LLL.js +9 -0
- package/dist/analytics.cjs +1 -0
- package/dist/analytics.d.cts +276 -0
- package/dist/analytics.d.ts +276 -0
- package/dist/analytics.js +223 -0
- package/dist/assets-66UBlhES.cjs +1 -0
- package/dist/assets-NVA_sftu.js +163 -0
- package/dist/capabilities-CNjIirfo.js +36 -0
- package/dist/capabilities-D4xeVYSR.cjs +1 -0
- package/dist/designer.cjs +1 -0
- package/dist/designer.d.cts +753 -0
- package/dist/designer.d.ts +753 -0
- package/dist/designer.js +372 -0
- package/dist/grid-geometry-BNptEcMm.js +65 -0
- package/dist/grid-geometry-CZ_cYB6O.cjs +1 -0
- package/dist/index.cjs +8 -5
- package/dist/index.d.cts +413 -8
- package/dist/index.d.ts +413 -8
- package/dist/index.js +1016 -1501
- package/dist/param-validation-BWNjLcN0.js +116 -0
- package/dist/param-validation-CiTxFeZ8.cjs +1 -0
- package/dist/pdf.cjs +48 -48
- package/dist/pdf.d.cts +111 -1
- package/dist/pdf.d.ts +111 -1
- package/dist/pdf.js +3931 -3868
- package/dist/{plugin-DMPLDpBY.cjs → plugin-BqBkn_kI.cjs} +1 -1
- package/dist/{plugin-DDLcFWlk.js → plugin-Ds10VnQO.js} +2 -2
- package/dist/render-plan-CckPEQyf.cjs +1 -0
- package/dist/{render-plan-CXBWRog4.js → render-plan-uzZYYSy1.js} +11 -10
- package/dist/report-params-B_VCihAh.js +12 -0
- package/dist/report-params-CjWrjPl6.cjs +1 -0
- package/dist/report-source-B9bENO0F.js +750 -0
- package/dist/report-source-BbNkkBDy.cjs +1 -0
- package/dist/server/node.d.cts +297 -0
- package/dist/server/node.d.ts +297 -0
- package/dist/server-node.cjs +1 -0
- package/dist/server-node.js +270 -0
- package/dist/server.cjs +1 -0
- package/dist/server.d.cts +643 -0
- package/dist/server.d.ts +643 -0
- package/dist/server.js +237 -0
- package/dist/style-CpwiOPyB.cjs +1 -0
- package/dist/style-Dv5o_x6b.js +67 -0
- package/dist/style.css +1 -1
- package/dist/template-registry-DWExx0gU.cjs +1 -0
- package/dist/template-registry-NpOakidD.js +354 -0
- package/dist/textwrap-CnGsEum6.cjs +4 -0
- package/dist/textwrap-DOl04hCQ.js +110 -0
- package/dist/validate-DfHPD8wX.cjs +1 -0
- package/dist/validate-S6CgIm5d.js +148 -0
- package/dist/vue/async.d.cts +602 -57
- package/dist/vue/async.d.ts +602 -57
- package/dist/vue/index.d.cts +1074 -111
- package/dist/vue/index.d.ts +1074 -111
- package/dist/vue-async.cjs +1 -1
- package/dist/vue-async.js +3 -3
- package/dist/vue.cjs +1 -1
- package/dist/vue.js +167 -82
- package/dist/worker.cjs +1 -0
- package/dist/worker.d.cts +302 -0
- package/dist/worker.d.ts +302 -0
- package/dist/worker.js +133 -0
- package/dist/xlsx/node.d.cts +47 -0
- package/dist/xlsx/node.d.ts +47 -0
- package/dist/xlsx-node.cjs +221 -0
- package/dist/xlsx-node.js +36409 -0
- package/dist/xlsx.cjs +20 -20
- package/dist/xlsx.d.cts +78 -1
- package/dist/xlsx.d.ts +78 -1
- package/dist/xlsx.js +5974 -5831
- package/package.json +62 -2
- package/dist/ReportPreview-CBKLI--k.js +0 -2188
- package/dist/ReportPreview-ClM8h0pM.cjs +0 -6
- package/dist/grid-geometry-BNIvw52m.cjs +0 -1
- package/dist/grid-geometry-C8hGoe9o.js +0 -130
- package/dist/render-plan-CCTL4F9v.cjs +0 -1
- package/dist/report-params-B3Fia6JO.js +0 -10
- package/dist/report-params-D1gZ1DME.cjs +0 -1
- package/dist/textwrap-nH0UYU6D.js +0 -108
- package/dist/textwrap-oD-t4b4B.cjs +0 -4
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { parentPort as R, Worker as N } from "node:worker_threads";
|
|
2
|
+
function W(e, t, r) {
|
|
3
|
+
e.editable !== void 0 && typeof e.editable != "boolean" && r.push({ path: `${t}.editable`, message: "编辑控制应为布尔值" }), e.valueType !== void 0 && !["text", "number", "boolean"].includes(e.valueType) && r.push({ path: `${t}.valueType`, message: "编辑类型应为 text、number 或 boolean" });
|
|
4
|
+
}
|
|
5
|
+
function T(e, t, r) {
|
|
6
|
+
W(e, t, r), E(e.source, `${t}.source`, r, !0), e.formula !== void 0 && typeof e.formula != "string" && r.push({ path: `${t}.formula`, message: "单元格公式应为字符串" });
|
|
7
|
+
}
|
|
8
|
+
function E(e, t, r, o = !1) {
|
|
9
|
+
if (e === void 0) return;
|
|
10
|
+
if (!e || typeof e != "object" || Array.isArray(e)) {
|
|
11
|
+
r.push({ path: t, message: "业务来源应为对象" });
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const s = e;
|
|
15
|
+
for (const n of ["datasetId", ...o ? ["field"] : []])
|
|
16
|
+
(typeof s[n] != "string" || !s[n].trim()) && r.push({ path: `${t}.${n}`, message: "业务标识应为非空字符串" });
|
|
17
|
+
for (const n of ["rowKey", "revision"]) {
|
|
18
|
+
const i = s[n];
|
|
19
|
+
i === void 0 && !(o && n === "rowKey") || typeof i != "string" && !(typeof i == "number" && Number.isFinite(i)) && r.push({ path: `${t}.${n}`, message: "业务键及修订号应为字符串或有限数字" });
|
|
20
|
+
}
|
|
21
|
+
s.sourceToken !== void 0 && typeof s.sourceToken != "string" && r.push({ path: `${t}.sourceToken`, message: "来源令牌应为字符串" });
|
|
22
|
+
}
|
|
23
|
+
const O = /* @__PURE__ */ new Set([
|
|
24
|
+
"text",
|
|
25
|
+
"image",
|
|
26
|
+
"barcode",
|
|
27
|
+
"qrcode",
|
|
28
|
+
"chart",
|
|
29
|
+
"line",
|
|
30
|
+
"rect",
|
|
31
|
+
"ellipse"
|
|
32
|
+
]);
|
|
33
|
+
function p(e) {
|
|
34
|
+
return typeof e == "object" && e !== null && !Array.isArray(e);
|
|
35
|
+
}
|
|
36
|
+
function P(e, t, r, o) {
|
|
37
|
+
const s = e[t];
|
|
38
|
+
(typeof s != "number" || !Number.isFinite(s)) && o.push({ path: `${r}.${t}`, message: `应为有限数字,实际 ${JSON.stringify(s)}` });
|
|
39
|
+
}
|
|
40
|
+
function S(e, t, r) {
|
|
41
|
+
if (e !== void 0) {
|
|
42
|
+
const o = `${t}.table`;
|
|
43
|
+
if (!p(e)) r.push({ path: o, message: "逻辑表来源应为对象" });
|
|
44
|
+
else {
|
|
45
|
+
E(e.source, `${o}.source`, r), (typeof e.id != "string" || !e.id.trim()) && r.push({ path: `${o}.id`, message: "逻辑表 ID 应为非空字符串" });
|
|
46
|
+
const s = e.role;
|
|
47
|
+
["header", "body", "group-header", "subtotal", "grand-total"].includes(s) || r.push({ path: `${o}.role`, message: "未知逻辑表行角色" });
|
|
48
|
+
const n = e.rowIndex;
|
|
49
|
+
(typeof n != "number" || !Number.isInteger(n) || (s === "header" ? n !== -1 : n < 0)) && r.push({ path: `${o}.rowIndex`, message: "表头索引应为 -1,内容行索引应为非负整数" }), (!Array.isArray(e.columnKeys) || e.columnKeys.some((i) => typeof i != "string")) && r.push({ path: `${o}.columnKeys`, message: "逻辑列字段应为字符串数组" }), e.layout !== void 0 && e.layout !== "page" && e.layout !== "wide" && r.push({ path: `${o}.layout`, message: "布局应为 page 或 wide" }), e.title !== void 0 && typeof e.title != "string" && r.push({ path: `${o}.title`, message: "逻辑表名称应为字符串" });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function j(e, t, r, o) {
|
|
54
|
+
if (e !== void 0)
|
|
55
|
+
if (!p(e) || !Array.isArray(e.cells))
|
|
56
|
+
r.push({ path: `${t}.grid.cells`, message: "grid.cells 应为二维数组" });
|
|
57
|
+
else {
|
|
58
|
+
const s = e.paddingMm;
|
|
59
|
+
s !== void 0 && (typeof s != "number" || !Number.isFinite(s) || s < 0) && r.push({ path: `${t}.grid.paddingMm`, message: "单元格内距应为有限非负数" }), e.cells.forEach((n, i) => {
|
|
60
|
+
if (!Array.isArray(n)) {
|
|
61
|
+
r.push({ path: `${t}.grid.cells.${i}`, message: "行应为数组" });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
n.forEach((u, c) => {
|
|
65
|
+
if (u == null) return;
|
|
66
|
+
const m = `${t}.grid.cells.${i}.${c}`;
|
|
67
|
+
if (!p(u)) {
|
|
68
|
+
r.push({ path: m, message: "网格单元格应为对象或 null" });
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
T(u, m, r), Array.isArray(u.children) && u.children.forEach((l, g) => {
|
|
72
|
+
M(l, `${t}.grid.cells.${i}.${c}.children.${g}`, r, o);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function I(e, t, r) {
|
|
79
|
+
e !== void 0 && (Array.isArray(e) ? e.forEach((o, s) => {
|
|
80
|
+
(!p(o) || !Array.isArray(o.segments)) && r.push({ path: `${t}.richParagraphs.${s}`, message: "段落缺少 segments 数组" });
|
|
81
|
+
}) : r.push({ path: `${t}.richParagraphs`, message: "richParagraphs 应为数组" }));
|
|
82
|
+
}
|
|
83
|
+
function M(e, t, r, o = []) {
|
|
84
|
+
if (!p(e)) {
|
|
85
|
+
r.push({ path: t, message: "组件应为对象" });
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const s = e.kind;
|
|
89
|
+
typeof s != "string" ? r.push({ path: `${t}.kind`, message: "组件缺少 kind 字符串" }) : O.has(s) || o.push({
|
|
90
|
+
path: `${t}.kind`,
|
|
91
|
+
message: `未知组件类型 ${JSON.stringify(s)},将以兜底方式渲染`
|
|
92
|
+
});
|
|
93
|
+
for (const n of ["leftMm", "topMm", "widthMm", "heightMm"])
|
|
94
|
+
P(e, n, t, r);
|
|
95
|
+
typeof e.leftMm == "number" && e.leftMm < -100 && r.push({ path: `${t}.leftMm`, message: "几何数值异常(leftMm<-100)" });
|
|
96
|
+
for (const n of ["widthMm", "heightMm"])
|
|
97
|
+
typeof e[n] == "number" && e[n] < 0 && r.push({ path: `${t}.${n}`, message: "组件尺寸不能为负数" });
|
|
98
|
+
S(e.table, t, r), e.lineDirection !== void 0 && !["down", "up"].includes(e.lineDirection) && r.push({ path: `${t}.lineDirection`, message: "线段方向应为 down 或 up" }), j(e.grid, t, r, o), I(e.richParagraphs, t, r);
|
|
99
|
+
}
|
|
100
|
+
function K(e, t, r, o = []) {
|
|
101
|
+
if (!p(e)) {
|
|
102
|
+
r.push({ path: t, message: "页应为对象" });
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const s = e.pageWidthMm, n = e.pageHeightMm;
|
|
106
|
+
(typeof s != "number" || !Number.isFinite(s) || s <= 0) && r.push({ path: `${t}.pageWidthMm`, message: `页宽非法: ${JSON.stringify(s)}` }), (typeof n != "number" || !(n > 0 && n < 5e3)) && r.push({ path: `${t}.pageHeightMm`, message: `页高非法: ${JSON.stringify(n)}` }), e.layout !== void 0 && e.layout !== "page" && e.layout !== "wide" && r.push({ path: `${t}.layout`, message: "布局应为 page 或 wide" });
|
|
107
|
+
const i = e.components;
|
|
108
|
+
Array.isArray(i) ? Array.isArray(i) && i.forEach(
|
|
109
|
+
(u, c) => M(u, `${t}.components.${c}`, r, o)
|
|
110
|
+
) : r.push({ path: `${t}.components`, message: "components 应为数组" });
|
|
111
|
+
}
|
|
112
|
+
function D(e) {
|
|
113
|
+
const t = [], r = [], o = p(e) ? e.pages : void 0;
|
|
114
|
+
if (!Array.isArray(o))
|
|
115
|
+
t.push({
|
|
116
|
+
path: "$.pages",
|
|
117
|
+
message: e == null ? "渲染计划为空" : "渲染计划缺少 pages 数组"
|
|
118
|
+
});
|
|
119
|
+
else {
|
|
120
|
+
o.forEach((n, i) => K(n, `$.pages.${i}`, t, r)), o.length > 2e3 && r.push({
|
|
121
|
+
path: "$.pages",
|
|
122
|
+
message: `页数异常大(${o.length} 页),渲染与打印耗时可能显著增加`
|
|
123
|
+
});
|
|
124
|
+
const s = o.reduce(
|
|
125
|
+
(n, i) => n + (p(i) && Array.isArray(i.components) ? i.components.length : 0),
|
|
126
|
+
0
|
|
127
|
+
);
|
|
128
|
+
s > 5e4 && r.push({
|
|
129
|
+
path: "$.pages",
|
|
130
|
+
message: `组件总数异常大(${s} 个),可能触发浏览器性能限制`
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
return { ok: t.length === 0, errors: t, warnings: r };
|
|
134
|
+
}
|
|
135
|
+
const h = "mach-report-worker/1";
|
|
136
|
+
class k extends Error {
|
|
137
|
+
constructor(t) {
|
|
138
|
+
super(t.message), this.name = t.name, this.code = t.code, this.path = t.path, this.issues = t.issues;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function y(e) {
|
|
142
|
+
return !!e && typeof e == "object" && !Array.isArray(e);
|
|
143
|
+
}
|
|
144
|
+
function F(e) {
|
|
145
|
+
return y(e) ? ["rows", "pages", "cells"].every((t) => typeof e[t] == "number" && Number.isSafeInteger(e[t]) && e[t] >= 0) && typeof e.durationMs == "number" && Number.isFinite(e.durationMs) && e.durationMs >= 0 : !1;
|
|
146
|
+
}
|
|
147
|
+
function C(e) {
|
|
148
|
+
return Array.isArray(e) && e.every((t) => y(t) && typeof t.code == "string" && typeof t.message == "string" && ["info", "warning", "error"].includes(t.severity));
|
|
149
|
+
}
|
|
150
|
+
function J(e) {
|
|
151
|
+
return y(e) && Object.values(e).every((t) => y(t) && (t.revision === void 0 || typeof t.revision == "string") && (t.sourceToken === void 0 || typeof t.sourceToken == "string"));
|
|
152
|
+
}
|
|
153
|
+
function L(e, t) {
|
|
154
|
+
if (!y(e) || !F(e.stats) || !C(e.diagnostics) || !J(e.revisions)) return !1;
|
|
155
|
+
if (t === "prepare") return D(e.plan).ok;
|
|
156
|
+
const r = e.format === "pdf" ? "application/pdf" : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
|
157
|
+
return e.bytes instanceof Uint8Array && (e.format === "pdf" || e.format === "xlsx") && e.contentType === r;
|
|
158
|
+
}
|
|
159
|
+
function U(e) {
|
|
160
|
+
if (!e || typeof e != "object") return { message: String(e) };
|
|
161
|
+
const t = {};
|
|
162
|
+
for (const r of ["code", "path", "field", "message"]) {
|
|
163
|
+
const o = e[r];
|
|
164
|
+
typeof o == "string" && (t[r] = o);
|
|
165
|
+
}
|
|
166
|
+
return t;
|
|
167
|
+
}
|
|
168
|
+
function _(e) {
|
|
169
|
+
if (!(e instanceof Error)) return { name: "Error", message: String(e) };
|
|
170
|
+
const t = e;
|
|
171
|
+
return {
|
|
172
|
+
name: e.name,
|
|
173
|
+
message: e.message,
|
|
174
|
+
...typeof t.code == "string" ? { code: t.code } : {},
|
|
175
|
+
...typeof t.path == "string" ? { path: t.path } : {},
|
|
176
|
+
...Array.isArray(t.issues) ? { issues: t.issues.map(U) } : {}
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function z(e) {
|
|
180
|
+
if (!e || typeof e != "object") return !1;
|
|
181
|
+
const t = e;
|
|
182
|
+
return t.protocol === h && typeof t.id == "string" && (t.operation === "prepare" || t.operation === "export") && !!t.input && typeof t.input == "object";
|
|
183
|
+
}
|
|
184
|
+
async function B(e, t) {
|
|
185
|
+
try {
|
|
186
|
+
const r = t.operation === "prepare" ? await e.prepare(t.input) : await e.export(t.input);
|
|
187
|
+
return { protocol: h, id: t.id, result: r };
|
|
188
|
+
} catch (r) {
|
|
189
|
+
return { protocol: h, id: t.id, error: _(r) };
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
function G(e) {
|
|
193
|
+
const t = e.result;
|
|
194
|
+
return !t || !("bytes" in t) || !(t.bytes.buffer instanceof ArrayBuffer) ? [] : [t.bytes.buffer];
|
|
195
|
+
}
|
|
196
|
+
let H = 0;
|
|
197
|
+
function A(e) {
|
|
198
|
+
const t = new Error("报表 Worker 任务已取消");
|
|
199
|
+
return t.name = "AbortError", Object.defineProperty(t, "cause", { value: e }), t;
|
|
200
|
+
}
|
|
201
|
+
function q(e, t) {
|
|
202
|
+
if (!e || typeof e != "object") return;
|
|
203
|
+
const r = e;
|
|
204
|
+
return r.protocol === h && r.id === t ? r : void 0;
|
|
205
|
+
}
|
|
206
|
+
function Q(e, t = {}) {
|
|
207
|
+
const r = t.timeoutMs ?? 12e4;
|
|
208
|
+
if (!Number.isFinite(r) || r <= 0 || r > 2147483647) throw new RangeError("Worker timeoutMs 应为正有限数字,且不能超过 2147483647");
|
|
209
|
+
const o = (s, n, i) => i?.aborted ? Promise.reject(A(i.reason)) : new Promise((u, c) => {
|
|
210
|
+
let m;
|
|
211
|
+
try {
|
|
212
|
+
m = e();
|
|
213
|
+
} catch (a) {
|
|
214
|
+
c(a);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const l = `mach-report-${Date.now()}-${++H}`;
|
|
218
|
+
let g = !1, $ = () => {
|
|
219
|
+
}, b;
|
|
220
|
+
const d = (a, f) => {
|
|
221
|
+
g || (g = !0, b && clearTimeout(b), $(), i?.removeEventListener("abort", w), Promise.resolve().then(() => m.terminate()).then(
|
|
222
|
+
() => a === void 0 ? u(f) : c(a),
|
|
223
|
+
(v) => c(a ?? v)
|
|
224
|
+
));
|
|
225
|
+
}, w = () => d(A(i?.reason)), x = (a) => {
|
|
226
|
+
const f = q(a, l);
|
|
227
|
+
f && (f.error && typeof f.error.name == "string" && typeof f.error.message == "string" ? d(new k(f.error)) : L(f.result, s) && (s !== "export" || "format" in f.result && "format" in n && f.result.format === n.format) ? d(void 0, f.result) : d(new Error("报表 Worker 返回无效响应")));
|
|
228
|
+
};
|
|
229
|
+
try {
|
|
230
|
+
if ($ = m.subscribe(x, (a) => d(a ?? new Error("报表 Worker 执行失败"))), g) {
|
|
231
|
+
$();
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
i?.addEventListener("abort", w, { once: !0 }), b = setTimeout(() => d(new k({ name: "ReportRuntimeError", code: "timeout", message: `报表 Worker 执行超过 ${r}ms` })), r), i?.aborted ? w() : m.postMessage({ protocol: h, id: l, operation: s, input: n });
|
|
235
|
+
} catch (a) {
|
|
236
|
+
d(a);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
return { prepare: (s, n) => o("prepare", s, n), export: (s, n) => o("export", s, n) };
|
|
240
|
+
}
|
|
241
|
+
function X(e) {
|
|
242
|
+
const t = e.filename ?? e.workerUrl;
|
|
243
|
+
if (!t || e.filename && e.workerUrl) throw new TypeError("请且仅请指定 filename 或 workerUrl");
|
|
244
|
+
return Q(() => {
|
|
245
|
+
const r = new N(t, e.workerOptions);
|
|
246
|
+
return {
|
|
247
|
+
postMessage: (o) => r.postMessage(o),
|
|
248
|
+
terminate: () => r.terminate(),
|
|
249
|
+
subscribe: (o, s) => {
|
|
250
|
+
const n = (i) => s(new Error(`报表 Worker 在响应前退出(code ${i})`));
|
|
251
|
+
return r.on("message", o), r.on("error", s), r.on("messageerror", s), r.on("exit", n), () => {
|
|
252
|
+
r.off("message", o), r.off("error", s), r.off("messageerror", s), r.off("exit", n);
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
}, e);
|
|
257
|
+
}
|
|
258
|
+
function Y(e) {
|
|
259
|
+
const t = R;
|
|
260
|
+
if (!t) throw new Error("serveNodeReportWorker 只能在 worker_threads 中调用");
|
|
261
|
+
const r = (o) => {
|
|
262
|
+
z(o) && B(e, o).then((s) => t.postMessage(s, G(s)));
|
|
263
|
+
};
|
|
264
|
+
return t.on("message", r), () => t.off("message", r);
|
|
265
|
+
}
|
|
266
|
+
export {
|
|
267
|
+
k as ReportWorkerError,
|
|
268
|
+
X as createNodeReportExecutor,
|
|
269
|
+
Y as serveNodeReportWorker
|
|
270
|
+
};
|
package/dist/server.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var V=Object.create;var q=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var J=Object.getOwnPropertyNames;var Q=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var W=(t,e,a,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of J(e))!_.call(t,r)&&r!==a&&q(t,r,{get:()=>e[r],enumerable:!(n=z(e,r))||n.enumerable});return t};var L=(t,e,a)=>(a=t!=null?V(Q(t)):{},W(e||!t||!t.__esModule?q(a,"default",{value:t,enumerable:!0}):a,t));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R=require("./report-source-BbNkkBDy.cjs"),I=require("./report-params-CjWrjPl6.cjs"),C=require("./param-validation-CiTxFeZ8.cjs"),G=require("./validate-DfHPD8wX.cjs");class m extends Error{constructor(e,a,n){super(a),this.code=e,this.path=n,this.name="ReportRuntimeError"}}function x(t){if(!t?.aborted)return;if(t.reason instanceof m)throw t.reason;const e=new Error("报表执行已取消");throw e.name="AbortError",Object.defineProperty(e,"cause",{value:t.reason}),e}function b(t,e,a){if(!Number.isFinite(a)||a<0)throw new m("budget",`${e} 的执行统计无效`,`$.budget.${e}`);const n=t[e];if(n!==void 0&&a>n)throw new m("budget",`${e} 超出预算 ${n}(实际 ${a})`,`$.budget.${e}`)}function U(t){for(const[e,a]of Object.entries(t)){if(a!==void 0&&(!Number.isFinite(a)||a<=0))throw new m("budget",`${e} 应为正有限数字`,`$.budget.${e}`);if(e!=="maxDurationMs"&&a!==void 0&&!Number.isSafeInteger(a))throw new m("budget",`${e} 应为正安全整数`,`$.budget.${e}`);if(e==="maxDurationMs"&&a!==void 0&&a>2147483647)throw new m("budget","maxDurationMs 不能超过 2147483647",`$.budget.${e}`)}}async function B(t,e,a){const n=new AbortController,r=()=>n.abort(t?.reason);t?.addEventListener("abort",r,{once:!0}),t?.aborted&&r();const s=Date.now(),u=e===void 0?void 0:setTimeout(()=>n.abort(new m("timeout",`报表执行超过 ${e}ms`)),e);let o;try{x(n.signal);const i=new Promise((w,f)=>{o=()=>{try{x(n.signal)}catch(v){f(v)}},n.signal.addEventListener("abort",o,{once:!0})}),p=await Promise.race([a(n.signal),i]);if(x(n.signal),e!==void 0&&Date.now()-s>e)throw new m("timeout",`报表执行超过 ${e}ms`);return p}finally{u!==void 0&&clearTimeout(u),o&&n.signal.removeEventListener("abort",o),t?.removeEventListener("abort",r)}}function M(t,e){if(e.length===0)throw new R.ReportSourceError("config","缺少报表 ID");return e.map(a=>{if(!Object.prototype.hasOwnProperty.call(t,a))throw new R.ReportSourceError("config",`未注册报表 ${a}`);return t[a]})}function j(t){return t.grid?.cells.reduce((e,a)=>e+a.reduce((n,r)=>n+(r?1+(r.children?.reduce((s,u)=>s+j(u),0)??0):0),0),0)??0}function X(t,e){return t.pages.reduce((a,n)=>a+n.components.reduce((r,s)=>{if(s.kind!=="list")return r+j(s);const u=e[s.dataset]?.length??0;return r+s.columns.length*(u+(s.headerGrid?.cells.length??1))},0),0)}function H(t,e=Object.keys(t)){return M(t,e).map((a,n)=>{const r=e[n],s=I.getReportParamDefs(t,[r]);return{id:r,params:JSON.parse(JSON.stringify(s)),paramsSchema:C.reportParamsJsonSchema(s),datasetsSchema:Object.fromEntries(Object.entries(a.dataSchema??{}).map(([u,o])=>[u,R.datasetJsonSchema(o)])),capabilities:{save:!!a.provider?.save,export:!!a.provider?.export,templates:!!a.provider?.templates}}})}function A(t,e){M(t,e.reportIds);const a=C.validateReportParams(I.getReportParamDefs(t,e.reportIds),e.params),n=e.reportIds.flatMap(s=>C.validateReportParams(I.getReportParamDefs(t,[s]),e.params).issues),r=new Map(n.map(s=>[JSON.stringify(s),s]));return{...a,ok:r.size===0,issues:[...r.values()]}}function K(t,e){const a=G.validateRenderPlan(t.plan);if(!a.ok)throw new R.ReportSourceError("validate",`执行器返回无效计划:${a.errors[0]?.path}`);const n=t.plan.pages.length,r=t.plan.pages.reduce((s,u)=>s+u.components.reduce((o,i)=>o+j(i),0),0);return b(e,"maxRows",t.stats.rows),b(e,"maxPages",n),b(e,"maxCells",r),{...t,stats:{...t.stats,pages:n,cells:r}}}function N(t,e){const a=A(t.reports,e);if(!a.ok)throw new C.ReportParamValidationError(a.issues)}function F(t=[]){return t.map(({code:e,message:a,severity:n,pageIndex:r,componentIndex:s})=>({code:e,message:a,severity:n,path:`$.pages.${r}.components.${s}`}))}function Y(t){const e={maxRows:1e5,maxPages:1e4,maxCells:2e6,maxOutputBytes:1e8,maxDurationMs:12e4,...t.budget};U(e);const a=async(r,s)=>{const u=Date.now();let o=0,i=0;const p=[],w={},f=Object.fromEntries(Object.entries(t.reports).map(([d,g])=>[d,{...g,pagination:{...t.pagination,...g.pagination,...s?{measurer:s}:{}},dataValidation:{...g.dataValidation,maxRows:Math.min(e.maxRows??1e5,g.dataValidation?.maxRows??1/0),maxCells:Math.min(e.maxCells??2e6,g.dataValidation?.maxCells??1/0)}}])),l=await R.createReportSource(f,{maxPages:e.maxPages,onDatasets:(d,g,P)=>{o+=Object.values(g).reduce(($,S)=>$+S.length,0),b(e,"maxRows",o),i+=X(P,g),b(e,"maxCells",i)}})({...r,params:r.params??{},onWarning:d=>p.push({code:"layout",message:d,severity:"warning"}),onQueryResult:(d,g)=>{Object.defineProperty(w,d,{value:{revision:g.revision,sourceToken:g.sourceToken},enumerable:!0,writable:!0}),p.push(...g.diagnostics??[])}}).catch(d=>{throw d instanceof R.ReportSourceError&&d.cause instanceof R.PaginatePageLimitError?new m("budget",d.cause.message,"$.budget.maxPages"):d});x(r.signal);const c=l.pages.reduce((d,g)=>d+g.components.reduce((P,$)=>P+j($),0),0);return b(e,"maxPages",l.pages.length),b(e,"maxCells",c),{plan:l,diagnostics:p,revisions:w,stats:{rows:o,pages:l.pages.length,cells:c,durationMs:Date.now()-u}}},n=async r=>{const s=Date.now();if(r.format!=="pdf"&&r.format!=="xlsx")throw new R.ReportSourceError("config","不支持的报表导出格式");const u=r.format==="pdf"?await import("@agile-team/mach-report/pdf"):void 0;x(r.signal);const o=r.pdf?.customFontFaces??(r.pdf?.customFontBytes?{regular:r.pdf.customFontBytes}:void 0),i=u&&o?u.createFontBytesMeasurer(o):void 0,p=await a(r,i);x(r.signal);let w;if(r.format==="pdf"){x(r.signal);const l=await u.renderPlanToPdf(p.plan,{...r.pdf,...i?{measurer:i}:{}});w=l.bytes,p.diagnostics.push(...F(l.diagnostics)),p.diagnostics.push(...l.fidelityWarnings.map(c=>({code:"pdf-fidelity",message:c,severity:"warning"})),...l.pageErrors.map(c=>({code:"pdf-page",message:c,severity:"error"}))),l.unsupportedTextCount&&p.diagnostics.push({code:"pdf-font",message:`${l.unsupportedTextCount} 段文本包含当前字体不支持的字符`,severity:"warning"})}else{const{renderPlanToXlsx:l}=await import("@agile-team/mach-report/xlsx");x(r.signal);const c=await l(p.plan,r.xlsx);w=new Uint8Array(c.buffer),p.diagnostics.push(...F(c.diagnostics)),p.diagnostics.push(...c.warnings.map(d=>({code:"xlsx-fidelity",message:d,severity:"warning"})))}x(r.signal),b(e,"maxOutputBytes",w.byteLength);const{plan:f,...v}=p;return{...v,bytes:w,format:r.format,contentType:r.format==="pdf"?"application/pdf":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",stats:{...v.stats,durationMs:Date.now()-s,outputBytes:w.byteLength}}};return{describe:r=>H(t.reports,r),validate:r=>A(t.reports,r),prepare:r=>B(r.signal,e.maxDurationMs,async s=>{const{signal:u,...o}=r;N(t,o);const i=t.executor?await t.executor.prepare(o,s):await a({...o,signal:s});return K(i,e)}),export:r=>B(r.signal,e.maxDurationMs,async s=>{const{signal:u,...o}=r;if(N(t,o),o.format!=="pdf"&&o.format!=="xlsx")throw new R.ReportSourceError("config","不支持的报表导出格式");const i=t.executor?await t.executor.export(o,s):await n({...o,signal:s});return b(e,"maxRows",i.stats.rows),b(e,"maxPages",i.stats.pages),b(e,"maxCells",i.stats.cells),b(e,"maxOutputBytes",i.bytes.byteLength),{...i,stats:{...i.stats,outputBytes:i.bytes.byteLength}}})}}function Z(t={}){const e=t.concurrency??1,a=t.maxQueued??20;if(!Number.isSafeInteger(e)||e<1||!Number.isSafeInteger(a)||a<0)throw new m("budget","队列并发应为正整数,排队上限应为非负整数");const n=[],r=new Set,s=new Set;let u=!1,o=0;const i=()=>{for(;!u&&r.size<e&&n.length;)n.shift().start()};return{get active(){return r.size},get pending(){return n.length},enqueue:(w,f={})=>{if(u)throw new m("closed","任务队列已关闭");if(x(f.signal),r.size>=e&&n.length>=a)throw new m("queue-full","报表任务队列已满");const v=f.id??`report-${++o}`;if(s.has(v))throw new m("queue-full","任务 ID 正在执行或排队");const l=new AbortController;let c="queued",d,g,P;const $=new Promise((h,y)=>{g=h,P=y}),S=()=>{f.signal?.removeEventListener("abort",T),s.delete(v)},D=h=>{if(c!=="queued"&&c!=="running")return;const y=c==="queued";c="cancelled",l.abort(h);try{x(l.signal)}catch(O){P(O)}if(y){const O=n.indexOf(E);O>=0&&n.splice(O,1),S(),i()}},T=()=>D(f.signal?.reason),k=(h,y)=>{c==="running"&&(!Number.isFinite(h)||h<0||y!==void 0&&(!Number.isFinite(y)||y<h)||(d={completed:h,...y===void 0?{}:{total:y}}))},E={cancel:D,start:()=>{c==="queued"&&(c="running",r.add(E),Promise.resolve().then(()=>(x(l.signal),w({signal:l.signal,reportProgress:k}))).then(h=>{c==="running"&&(c="completed",g(h))},h=>{c==="running"&&(c="failed",P(h))}).finally(()=>{r.delete(E),S(),i()}))}};return s.add(v),f.signal?.addEventListener("abort",T,{once:!0}),f.signal?.aborted?D(f.signal.reason):r.size<e?E.start():n.push(E),{id:v,get status(){return c},get progress(){return d},result:$,cancel:D}},close:(w={})=>{u=!0;for(const f of[...n])f.cancel(new m("closed","任务队列已关闭"));if(w.cancelRunning)for(const f of r)f.cancel(new m("closed","任务队列已关闭"))}}}exports.ReportRuntimeError=m;exports.createReportRuntime=Y;exports.createReportTaskQueue=Z;
|