@agile-team/mach-report 2.12.0 → 2.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -3
- package/dist/ExcelBindingWizard-CLT2p7P3.cjs +1 -0
- package/dist/ExcelBindingWizard-CvsWR8Ga.js +1485 -0
- package/dist/{ParamEditor-BLaE5q5W.js → ParamEditor-CflQV3eQ.js} +191 -187
- package/dist/ParamEditor-vIDzvpPV.cjs +1 -0
- package/dist/ReportBatchPanel-DkxTzBkD.cjs +1 -0
- package/dist/{ReportBatchPanel-B5ClP9tm.js → ReportBatchPanel-LqVgiqp7.js} +3 -3
- package/dist/ReportPreview-CvbqLUzM.cjs +6 -0
- package/dist/ReportPreview-D_ywJ_-H.js +4533 -0
- package/dist/{ReportTemplateLibrary-BZB-XWjj.js → ReportTemplateLibrary-MjWEtc7X.js} +1 -1
- package/dist/ReportTemplateLibrary-cQ1sqNYo.cjs +1 -0
- package/dist/RuleEditor-BaR6xUiI.cjs +1 -0
- package/dist/RuleEditor-ChuXMlei.js +2037 -0
- package/dist/TemplateOutlinePanel-BHKP89Xz.cjs +1 -0
- package/dist/TemplateOutlinePanel-Dci6aRn1.js +96 -0
- package/dist/TemplateReusePanel-B7Gmyc1z.js +388 -0
- package/dist/TemplateReusePanel-CY5eO2Sh.cjs +1 -0
- package/dist/TemplateReviewPanel-DjlX3xpt.js +592 -0
- package/dist/TemplateReviewPanel-JvZe9_4G.cjs +1 -0
- package/dist/{batch-mRqhhhjt.js → batch-DzaTNLWI.js} +23 -16
- package/dist/batch-xMkqYiTr.cjs +1 -0
- package/dist/config-0UIohTS7.cjs +1 -0
- package/dist/{config-B612mw0x.js → config-Dt9NtCPl.js} +227 -186
- package/dist/data-explanation-BktvER5B.cjs +1 -0
- package/dist/data-explanation-C_J6jYNi.js +16 -0
- package/dist/designer-Ci1LizA9.js +5020 -0
- package/dist/designer-rtmVIIdN.cjs +2 -0
- package/dist/designer.cjs +1 -2
- package/dist/designer.d.cts +306 -3
- package/dist/designer.d.ts +306 -3
- package/dist/designer.js +21 -4266
- package/dist/font-loader-DHto6Lra.js +297 -0
- package/dist/font-loader-vhCT8znW.cjs +1 -0
- package/dist/index.cjs +8 -8
- package/dist/index.d.cts +182 -1
- package/dist/index.d.ts +182 -1
- package/dist/index.js +728 -628
- package/dist/{template-review-BzpcI-tR.js → json-snapshot-BeFT3Tso.js} +867 -637
- package/dist/json-snapshot-D1NTP2oI.cjs +2 -0
- package/dist/pdf-8UPQebOE.js +36288 -0
- package/dist/pdf-AyJGb22z.cjs +101 -0
- package/dist/pdf.cjs +1 -101
- package/dist/pdf.js +9 -36579
- package/dist/plugin-BGKf-Tqg.js +22 -0
- package/dist/{plugin-BDTU4D94.cjs → plugin-CktLH_Iy.cjs} +1 -1
- package/dist/{region-binding-workflow-CcUq8W2Q.js → region-binding-workflow-DEJbhpCv.js} +1 -1
- package/dist/server/node.d.cts +46 -11
- package/dist/server/node.d.ts +46 -11
- package/dist/server-node.cjs +1 -1
- package/dist/server-node.js +294 -280
- package/dist/server.cjs +1 -1
- package/dist/server.d.cts +107 -12
- package/dist/server.d.ts +107 -12
- package/dist/server.js +713 -453
- package/dist/style.css +1 -1
- package/dist/template-bindings-BJR4k7qZ.cjs +1 -0
- package/dist/template-bindings-Daui7hLF.js +252 -0
- package/dist/template-fragments-CLkGo6To.js +187 -0
- package/dist/template-fragments-DFUpq5QM.cjs +1 -0
- package/dist/template-outline-B3xVkzSv.cjs +1 -0
- package/dist/template-outline-CFenM1PV.js +88 -0
- package/dist/{template-registry-BjE1VS6g.js → template-registry-COXDEJEM.js} +1 -1
- package/dist/{useLocalDraft-C07SYRnC.js → useLocalDraft-BnhcxXk_.js} +1 -1
- package/dist/{useLocalDraft-Yiw1wFgI.cjs → useLocalDraft-CioIfDb6.cjs} +1 -1
- package/dist/{validate-DbgEM1Hh.js → validate-CkQBWCeg.js} +3 -3
- package/dist/vue/async.d.cts +72 -2
- package/dist/vue/async.d.ts +72 -2
- package/dist/vue/index.d.cts +124 -5
- package/dist/vue/index.d.ts +124 -5
- package/dist/vue-async.cjs +1 -1
- package/dist/vue-async.js +5 -5
- package/dist/vue.cjs +1 -1
- package/dist/vue.js +78 -71
- package/dist/{workbook-session-BPb3TMnT.js → workbook-session-BfK1yHOO.js} +1 -1
- package/dist/worker.cjs +1 -1
- package/dist/worker.d.cts +46 -11
- package/dist/worker.d.ts +46 -11
- package/dist/worker.js +59 -55
- package/dist/xlsx.js +3 -3
- package/package.json +1 -1
- package/dist/ExcelBindingWizard-CeAf4QSE.js +0 -1465
- package/dist/ExcelBindingWizard-y0mT-AHR.cjs +0 -1
- package/dist/ParamEditor-MBBC7lUE.cjs +0 -1
- package/dist/ReportBatchPanel-Dc-SDkYA.cjs +0 -1
- package/dist/ReportPreview-DWXROHBP.cjs +0 -6
- package/dist/ReportPreview-DiNXhQI0.js +0 -4138
- package/dist/ReportTemplateLibrary-5fk5CQBO.cjs +0 -1
- package/dist/RuleEditor-ChRzNQuF.cjs +0 -1
- package/dist/RuleEditor-DzAmW5YH.js +0 -2024
- package/dist/TemplateReviewPanel-BKofGrV9.js +0 -222
- package/dist/TemplateReviewPanel-DwtOcLue.cjs +0 -1
- package/dist/batch-Bt3Fd27Z.cjs +0 -1
- package/dist/config-BRoLo2oj.cjs +0 -1
- package/dist/plugin-Cd5G2QQn.js +0 -22
- package/dist/record-bindings-By_UKZ2g.cjs +0 -1
- package/dist/record-bindings-D-5jQlTj.js +0 -196
- package/dist/template-review-BfCC8Ng9.cjs +0 -2
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { defineAsyncComponent as c, computed as m } from "vue";
|
|
2
|
+
import { b as i, c as l, a as s } from "./injection-keys-e85udZCp.js";
|
|
3
|
+
import { g as d } from "./report-params-B44imUd4.js";
|
|
4
|
+
const p = c(() => import("./ReportPreview-D_ywJ_-H.js").then((r) => r.s)), _ = {
|
|
5
|
+
install(r, e = {}) {
|
|
6
|
+
let t = e.fetcher;
|
|
7
|
+
if (!t && e.reports) {
|
|
8
|
+
const f = e.reports;
|
|
9
|
+
let n;
|
|
10
|
+
t = async (o) => (n ??= import("@agile-team/mach-report").then(({ createReportSource: a }) => a(f)), (await n)(o)), t.getParamDefs = (o) => d(f, o);
|
|
11
|
+
}
|
|
12
|
+
t && r.provide(i, t), e.pdfExporter && r.provide(l, e.pdfExporter), r.provide(s, m(() => {
|
|
13
|
+
if (e.pdfFontUrl === void 0) return e.config ?? null;
|
|
14
|
+
const f = e.config ?? { defaults: {}, presets: {} };
|
|
15
|
+
return { ...f, defaults: { ...f.defaults, pdfFontUrl: e.pdfFontUrl } };
|
|
16
|
+
})), e.globalComponent !== !1 && !r.component("MachReportPreview") && r.component("MachReportPreview", p);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
export {
|
|
20
|
+
p as M,
|
|
21
|
+
_ as m
|
|
22
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var R=Object.create;var f=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,p=Object.prototype.hasOwnProperty;var m=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of P(e))!p.call(r,o)&&o!==t&&f(r,o,{get:()=>e[o],enumerable:!(n=u(e,o))||n.enumerable});return r};var E=(r,e,t)=>(t=r!=null?R(d(r)):{},m(e||!r||!r.__esModule?f(t,"default",{value:r,enumerable:!0}):t,r));const l=require("vue"),i=require("./injection-keys-Db_DyLkm.cjs"),h=require("./report-params-SJfhKgaX.cjs"),s=l.defineAsyncComponent(()=>Promise.resolve().then(()=>require("./ReportPreview-
|
|
1
|
+
"use strict";var R=Object.create;var f=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,p=Object.prototype.hasOwnProperty;var m=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of P(e))!p.call(r,o)&&o!==t&&f(r,o,{get:()=>e[o],enumerable:!(n=u(e,o))||n.enumerable});return r};var E=(r,e,t)=>(t=r!=null?R(d(r)):{},m(e||!r||!r.__esModule?f(t,"default",{value:r,enumerable:!0}):t,r));const l=require("vue"),i=require("./injection-keys-Db_DyLkm.cjs"),h=require("./report-params-SJfhKgaX.cjs"),s=l.defineAsyncComponent(()=>Promise.resolve().then(()=>require("./ReportPreview-CvbqLUzM.cjs")).then(r=>r.ReportPreview$1)),v={install(r,e={}){let t=e.fetcher;if(!t&&e.reports){const n=e.reports;let o;t=async c=>(o??=import("@agile-team/mach-report").then(({createReportSource:a})=>a(n)),(await o)(c)),t.getParamDefs=c=>h.getReportParamDefs(n,c)}t&&r.provide(i.MACH_REPORT_FETCHER_KEY,t),e.pdfExporter&&r.provide(i.MACH_REPORT_PDF_EXPORTER_KEY,e.pdfExporter),r.provide(i.MACH_REPORT_CONFIG_KEY,l.computed(()=>{if(e.pdfFontUrl===void 0)return e.config??null;const n=e.config??{defaults:{},presets:{}};return{...n,defaults:{...n.defaults,pdfFontUrl:e.pdfFontUrl}}})),e.globalComponent!==!1&&!r.component("MachReportPreview")&&r.component("MachReportPreview",s)}};exports.MachReportPreview=s;exports.machReportPlugin=v;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { v as F } from "./dataset-H5pFuQGU.js";
|
|
2
|
-
import { v as D, d as z, p as Z } from "./template-registry-
|
|
2
|
+
import { v as D, d as z, p as Z } from "./template-registry-COXDEJEM.js";
|
|
3
3
|
import { r as N } from "./grid-geometry-BNptEcMm.js";
|
|
4
4
|
function v(t) {
|
|
5
5
|
let e = "";
|
package/dist/server/node.d.cts
CHANGED
|
@@ -194,6 +194,11 @@ declare interface PreparedReport {
|
|
|
194
194
|
revision?: string;
|
|
195
195
|
sourceToken?: string;
|
|
196
196
|
}>;
|
|
197
|
+
/** Captured metrics identity; absence on old saved instances remains supported with diagnostics. */
|
|
198
|
+
layout?: {
|
|
199
|
+
textMetrics: "heuristic" | "provided" | "font-bytes";
|
|
200
|
+
fontFingerprint?: string;
|
|
201
|
+
};
|
|
197
202
|
}
|
|
198
203
|
|
|
199
204
|
declare interface RenderPlan {
|
|
@@ -215,6 +220,14 @@ declare interface ReportCellSource {
|
|
|
215
220
|
sourceToken?: string;
|
|
216
221
|
}
|
|
217
222
|
|
|
223
|
+
declare interface ReportDataTarget {
|
|
224
|
+
datasetId: string;
|
|
225
|
+
field: string;
|
|
226
|
+
rowKey?: string | number;
|
|
227
|
+
/** Use table identity when the same dataset appears in several tables. */
|
|
228
|
+
tableId?: string;
|
|
229
|
+
}
|
|
230
|
+
|
|
218
231
|
declare interface ReportDescription {
|
|
219
232
|
id: string;
|
|
220
233
|
params: ReportParamDef[];
|
|
@@ -233,6 +246,9 @@ declare interface ReportDiagnostic {
|
|
|
233
246
|
message: string;
|
|
234
247
|
path?: string;
|
|
235
248
|
severity: "warning" | "error" | "info";
|
|
249
|
+
/** Optional explanation supplied by the business source, not inferred from blank cells. */
|
|
250
|
+
valueState?: ReportValueState;
|
|
251
|
+
target?: ReportDataTarget;
|
|
236
252
|
}
|
|
237
253
|
|
|
238
254
|
declare type ReportJobJson = null | boolean | number | string | ReportJobJson[] | {
|
|
@@ -356,15 +372,30 @@ declare interface ReportParamValidation {
|
|
|
356
372
|
issues: ReportParamIssue[];
|
|
357
373
|
}
|
|
358
374
|
|
|
375
|
+
/** Licensed local font bytes; never downloaded implicitly by the runtime. */
|
|
376
|
+
declare interface ReportPdfFontOptions {
|
|
377
|
+
customFontBytes?: Uint8Array | ArrayBuffer;
|
|
378
|
+
customFontName?: string;
|
|
379
|
+
customFontFaces?: {
|
|
380
|
+
regular: Uint8Array | ArrayBuffer;
|
|
381
|
+
bold?: Uint8Array | ArrayBuffer;
|
|
382
|
+
italic?: Uint8Array | ArrayBuffer;
|
|
383
|
+
boldItalic?: Uint8Array | ArrayBuffer;
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
|
|
359
387
|
declare interface ReportRuntime {
|
|
360
388
|
describe(reportIds?: string[]): ReportDescription[];
|
|
361
389
|
validate(input: Omit<ReportRuntimeInput, "signal">): ReportParamValidation;
|
|
362
390
|
prepare(input: ReportRuntimeInput): Promise<PreparedReport>;
|
|
363
391
|
export(input: ReportRuntimeExportInput): Promise<ReportRuntimeExportResult>;
|
|
392
|
+
exportPrepared(input: ReportRuntimePreparedExportInput): Promise<ReportRuntimeExportResult>;
|
|
364
393
|
}
|
|
365
394
|
|
|
366
395
|
/** 可用 worker_threads/进程/RPC 实现;接收可序列化请求,signal 由桥接层映射为取消消息。 */
|
|
367
396
|
declare interface ReportRuntimeExecutor {
|
|
397
|
+
/** Old custom executors may omit this; the runtime explicitly rejects unsupported prepared output. */
|
|
398
|
+
exportPrepared?(input: Omit<ReportRuntimePreparedExportInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<ReportRuntimeExportResult>;
|
|
368
399
|
prepare(input: Omit<ReportRuntimeInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<PreparedReport>;
|
|
369
400
|
export(input: Omit<ReportRuntimeExportInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<ReportRuntimeExportResult>;
|
|
370
401
|
}
|
|
@@ -373,17 +404,6 @@ declare interface ReportRuntimeExportInput extends ReportRuntimeInput {
|
|
|
373
404
|
format: "pdf" | "xlsx";
|
|
374
405
|
/** strict 在编码前拒绝已识别的输出降级;默认保留诊断并继续。 */
|
|
375
406
|
fidelity?: "warn" | "strict";
|
|
376
|
-
/** PDF 中文需宿主显式提供有授权的字体;不隐式下载字体或资源。 */
|
|
377
|
-
pdf?: {
|
|
378
|
-
customFontBytes?: Uint8Array | ArrayBuffer;
|
|
379
|
-
customFontName?: string;
|
|
380
|
-
customFontFaces?: {
|
|
381
|
-
regular: Uint8Array | ArrayBuffer;
|
|
382
|
-
bold?: Uint8Array | ArrayBuffer;
|
|
383
|
-
italic?: Uint8Array | ArrayBuffer;
|
|
384
|
-
boldItalic?: Uint8Array | ArrayBuffer;
|
|
385
|
-
};
|
|
386
|
-
};
|
|
387
407
|
xlsx?: {
|
|
388
408
|
sheetMode?: "auto" | "pages" | "continuous";
|
|
389
409
|
valueMode?: "text" | "raw";
|
|
@@ -401,6 +421,18 @@ declare interface ReportRuntimeInput extends ReportTaskMonitoring {
|
|
|
401
421
|
reportIds: string[];
|
|
402
422
|
params?: Record<string, string>;
|
|
403
423
|
signal?: AbortSignal;
|
|
424
|
+
/** Prepare using the same licensed font bytes later supplied to PDF output. */
|
|
425
|
+
pdf?: ReportPdfFontOptions;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/** Encode an existing plan without querying providers or repaginating. */
|
|
429
|
+
declare interface ReportRuntimePreparedExportInput extends ReportTaskMonitoring {
|
|
430
|
+
prepared: PreparedReport;
|
|
431
|
+
format: ReportRuntimeExportInput["format"];
|
|
432
|
+
fidelity?: ReportRuntimeExportInput["fidelity"];
|
|
433
|
+
pdf?: ReportPdfFontOptions;
|
|
434
|
+
xlsx?: ReportRuntimeExportInput["xlsx"];
|
|
435
|
+
signal?: AbortSignal;
|
|
404
436
|
}
|
|
405
437
|
|
|
406
438
|
declare interface ReportRuntimeStats {
|
|
@@ -430,6 +462,9 @@ declare interface ReportTaskMonitoring {
|
|
|
430
462
|
|
|
431
463
|
declare type ReportTaskObserver = (event: ReportTaskEvent) => void;
|
|
432
464
|
|
|
465
|
+
/** Optional business explanations never replace raw data or schema validation. */
|
|
466
|
+
declare type ReportValueState = "missing-source" | "not-applicable" | "not-calculable";
|
|
467
|
+
|
|
433
468
|
export declare class ReportWorkerError extends Error {
|
|
434
469
|
readonly code?: string;
|
|
435
470
|
readonly path?: string;
|
package/dist/server/node.d.ts
CHANGED
|
@@ -194,6 +194,11 @@ declare interface PreparedReport {
|
|
|
194
194
|
revision?: string;
|
|
195
195
|
sourceToken?: string;
|
|
196
196
|
}>;
|
|
197
|
+
/** Captured metrics identity; absence on old saved instances remains supported with diagnostics. */
|
|
198
|
+
layout?: {
|
|
199
|
+
textMetrics: "heuristic" | "provided" | "font-bytes";
|
|
200
|
+
fontFingerprint?: string;
|
|
201
|
+
};
|
|
197
202
|
}
|
|
198
203
|
|
|
199
204
|
declare interface RenderPlan {
|
|
@@ -215,6 +220,14 @@ declare interface ReportCellSource {
|
|
|
215
220
|
sourceToken?: string;
|
|
216
221
|
}
|
|
217
222
|
|
|
223
|
+
declare interface ReportDataTarget {
|
|
224
|
+
datasetId: string;
|
|
225
|
+
field: string;
|
|
226
|
+
rowKey?: string | number;
|
|
227
|
+
/** Use table identity when the same dataset appears in several tables. */
|
|
228
|
+
tableId?: string;
|
|
229
|
+
}
|
|
230
|
+
|
|
218
231
|
declare interface ReportDescription {
|
|
219
232
|
id: string;
|
|
220
233
|
params: ReportParamDef[];
|
|
@@ -233,6 +246,9 @@ declare interface ReportDiagnostic {
|
|
|
233
246
|
message: string;
|
|
234
247
|
path?: string;
|
|
235
248
|
severity: "warning" | "error" | "info";
|
|
249
|
+
/** Optional explanation supplied by the business source, not inferred from blank cells. */
|
|
250
|
+
valueState?: ReportValueState;
|
|
251
|
+
target?: ReportDataTarget;
|
|
236
252
|
}
|
|
237
253
|
|
|
238
254
|
declare type ReportJobJson = null | boolean | number | string | ReportJobJson[] | {
|
|
@@ -356,15 +372,30 @@ declare interface ReportParamValidation {
|
|
|
356
372
|
issues: ReportParamIssue[];
|
|
357
373
|
}
|
|
358
374
|
|
|
375
|
+
/** Licensed local font bytes; never downloaded implicitly by the runtime. */
|
|
376
|
+
declare interface ReportPdfFontOptions {
|
|
377
|
+
customFontBytes?: Uint8Array | ArrayBuffer;
|
|
378
|
+
customFontName?: string;
|
|
379
|
+
customFontFaces?: {
|
|
380
|
+
regular: Uint8Array | ArrayBuffer;
|
|
381
|
+
bold?: Uint8Array | ArrayBuffer;
|
|
382
|
+
italic?: Uint8Array | ArrayBuffer;
|
|
383
|
+
boldItalic?: Uint8Array | ArrayBuffer;
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
|
|
359
387
|
declare interface ReportRuntime {
|
|
360
388
|
describe(reportIds?: string[]): ReportDescription[];
|
|
361
389
|
validate(input: Omit<ReportRuntimeInput, "signal">): ReportParamValidation;
|
|
362
390
|
prepare(input: ReportRuntimeInput): Promise<PreparedReport>;
|
|
363
391
|
export(input: ReportRuntimeExportInput): Promise<ReportRuntimeExportResult>;
|
|
392
|
+
exportPrepared(input: ReportRuntimePreparedExportInput): Promise<ReportRuntimeExportResult>;
|
|
364
393
|
}
|
|
365
394
|
|
|
366
395
|
/** 可用 worker_threads/进程/RPC 实现;接收可序列化请求,signal 由桥接层映射为取消消息。 */
|
|
367
396
|
declare interface ReportRuntimeExecutor {
|
|
397
|
+
/** Old custom executors may omit this; the runtime explicitly rejects unsupported prepared output. */
|
|
398
|
+
exportPrepared?(input: Omit<ReportRuntimePreparedExportInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<ReportRuntimeExportResult>;
|
|
368
399
|
prepare(input: Omit<ReportRuntimeInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<PreparedReport>;
|
|
369
400
|
export(input: Omit<ReportRuntimeExportInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<ReportRuntimeExportResult>;
|
|
370
401
|
}
|
|
@@ -373,17 +404,6 @@ declare interface ReportRuntimeExportInput extends ReportRuntimeInput {
|
|
|
373
404
|
format: "pdf" | "xlsx";
|
|
374
405
|
/** strict 在编码前拒绝已识别的输出降级;默认保留诊断并继续。 */
|
|
375
406
|
fidelity?: "warn" | "strict";
|
|
376
|
-
/** PDF 中文需宿主显式提供有授权的字体;不隐式下载字体或资源。 */
|
|
377
|
-
pdf?: {
|
|
378
|
-
customFontBytes?: Uint8Array | ArrayBuffer;
|
|
379
|
-
customFontName?: string;
|
|
380
|
-
customFontFaces?: {
|
|
381
|
-
regular: Uint8Array | ArrayBuffer;
|
|
382
|
-
bold?: Uint8Array | ArrayBuffer;
|
|
383
|
-
italic?: Uint8Array | ArrayBuffer;
|
|
384
|
-
boldItalic?: Uint8Array | ArrayBuffer;
|
|
385
|
-
};
|
|
386
|
-
};
|
|
387
407
|
xlsx?: {
|
|
388
408
|
sheetMode?: "auto" | "pages" | "continuous";
|
|
389
409
|
valueMode?: "text" | "raw";
|
|
@@ -401,6 +421,18 @@ declare interface ReportRuntimeInput extends ReportTaskMonitoring {
|
|
|
401
421
|
reportIds: string[];
|
|
402
422
|
params?: Record<string, string>;
|
|
403
423
|
signal?: AbortSignal;
|
|
424
|
+
/** Prepare using the same licensed font bytes later supplied to PDF output. */
|
|
425
|
+
pdf?: ReportPdfFontOptions;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/** Encode an existing plan without querying providers or repaginating. */
|
|
429
|
+
declare interface ReportRuntimePreparedExportInput extends ReportTaskMonitoring {
|
|
430
|
+
prepared: PreparedReport;
|
|
431
|
+
format: ReportRuntimeExportInput["format"];
|
|
432
|
+
fidelity?: ReportRuntimeExportInput["fidelity"];
|
|
433
|
+
pdf?: ReportPdfFontOptions;
|
|
434
|
+
xlsx?: ReportRuntimeExportInput["xlsx"];
|
|
435
|
+
signal?: AbortSignal;
|
|
404
436
|
}
|
|
405
437
|
|
|
406
438
|
declare interface ReportRuntimeStats {
|
|
@@ -430,6 +462,9 @@ declare interface ReportTaskMonitoring {
|
|
|
430
462
|
|
|
431
463
|
declare type ReportTaskObserver = (event: ReportTaskEvent) => void;
|
|
432
464
|
|
|
465
|
+
/** Optional business explanations never replace raw data or schema validation. */
|
|
466
|
+
declare type ReportValueState = "missing-source" | "not-applicable" | "not-calculable";
|
|
467
|
+
|
|
433
468
|
export declare class ReportWorkerError extends Error {
|
|
434
469
|
readonly code?: string;
|
|
435
470
|
readonly path?: string;
|
package/dist/server-node.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const W=require("node:worker_threads"),j=require("node:crypto"),h=require("node:fs"),S=require("node:path");function H(e,t,r){if(!r?.aborted)try{const o=e?.({...t});o&&typeof o.then=="function"&&Promise.resolve(o).catch(()=>{})}catch{}}function K(e,t,r){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"})}function Z(e,t,r){K(e,t,r),e.indentMm!==void 0&&(typeof e.indentMm!="number"||!Number.isFinite(e.indentMm)||e.indentMm<0)&&r.push({path:`${t}.indentMm`,message:"单元格缩进应为有限非负数"}),e.derived!==void 0&&typeof e.derived!="boolean"&&r.push({path:`${t}.derived`,message:"派生结果标记应为布尔值"}),U(e.source,`${t}.source`,r,!0),e.formula!==void 0&&typeof e.formula!="string"&&r.push({path:`${t}.formula`,message:"单元格公式应为字符串"})}function U(e,t,r,o=!1){if(e===void 0)return;if(!e||typeof e!="object"||Array.isArray(e)){r.push({path:t,message:"业务来源应为对象"});return}const n=e;for(const s of["datasetId",...o?["field"]:[]])(typeof n[s]!="string"||!n[s].trim())&&r.push({path:`${t}.${s}`,message:"业务标识应为非空字符串"});for(const s of["rowKey","revision"]){const i=n[s];i===void 0&&!(o&&s==="rowKey")||typeof i!="string"&&!(typeof i=="number"&&Number.isFinite(i))&&r.push({path:`${t}.${s}`,message:"业务键及修订号应为字符串或有限数字"})}n.sourceToken!==void 0&&typeof n.sourceToken!="string"&&r.push({path:`${t}.sourceToken`,message:"来源令牌应为字符串"})}function Q(e){const t=[];return e.value!==void 0&&typeof e.value!="string"&&t.push({path:"value",message:"Symbol value must be a string."}),e.symbology!==void 0&&!["code128","code39","ean13","ean8"].includes(e.symbology)&&t.push({path:"symbology",message:"Unsupported barcode symbology."}),e.errorCorrection!==void 0&&!["L","M","Q","H"].includes(e.errorCorrection)&&t.push({path:"errorCorrection",message:"Unsupported QR error correction."}),e.showText!==void 0&&typeof e.showText!="boolean"&&t.push({path:"showText",message:"showText must be a boolean."}),t}function V(e,t){const r=[];return t!=="barcode"&&t!=="qrcode"&&r.push({path:"",message:"code is only supported by barcode and qrcode components."}),t==="qrcode"&&e.symbology!==void 0&&r.push({path:"symbology",message:"QR components do not use a linear symbology."}),t==="qrcode"&&e.showText===!0&&r.push({path:"showText",message:"Use a separate text component below a QR code."}),t==="barcode"&&e.errorCorrection!==void 0&&r.push({path:"errorCorrection",message:"Linear barcodes do not use QR error correction."}),r}function G(e,t){if(typeof e!="object"||e===null||Array.isArray(e))return[{path:"",message:"code must be an object."}];const r=e,o=[...Q(r),...V(r,t)];for(const i of Object.keys(r))["value","symbology","errorCorrection","quietZoneModules","showText"].includes(i)||o.push({path:i,message:"Unknown symbol option."});const n=r.symbology==="ean13"||r.symbology==="ean8",s=t==="qrcode"?4:n?11:10;return r.quietZoneModules!==void 0&&(!Number.isSafeInteger(r.quietZoneModules)||Number(r.quietZoneModules)<s||Number(r.quietZoneModules)>64)&&o.push({path:"quietZoneModules",message:`Quiet zone must contain ${s}–64 whole modules.`}),o}const X=new Set(["text","image","barcode","qrcode","chart","line","rect","ellipse"]);function A(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Y(e,t,r,o){const n=e[t];(typeof n!="number"||!Number.isFinite(n))&&o.push({path:`${r}.${t}`,message:`应为有限数字,实际 ${JSON.stringify(n)}`})}function ee(e,t,r){if(e!==void 0){const o=`${t}.table`;if(!A(e))r.push({path:o,message:"逻辑表来源应为对象"});else{U(e.source,`${o}.source`,r),(typeof e.id!="string"||!e.id.trim())&&r.push({path:`${o}.id`,message:"逻辑表 ID 应为非空字符串"});const n=e.role;["header","body","group-header","subtotal","grand-total"].includes(n)||r.push({path:`${o}.role`,message:"未知逻辑表行角色"});const s=e.rowIndex;(typeof s!="number"||!Number.isInteger(s)||(n==="header"?s!==-1:s<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:"逻辑表名称应为字符串"})}}}function te(e,t,r,o){if(e!==void 0)if(!A(e)||!Array.isArray(e.cells))r.push({path:`${t}.grid.cells`,message:"grid.cells 应为二维数组"});else{const n=e.paddingMm;n!==void 0&&(typeof n!="number"||!Number.isFinite(n)||n<0)&&r.push({path:`${t}.grid.paddingMm`,message:"单元格内距应为有限非负数"}),e.cells.forEach((s,i)=>{if(!Array.isArray(s)){r.push({path:`${t}.grid.cells.${i}`,message:"行应为数组"});return}s.forEach((d,y)=>{if(d==null)return;const u=`${t}.grid.cells.${i}.${y}`;if(!A(d)){r.push({path:u,message:"网格单元格应为对象或 null"});return}Z(d,u,r),Array.isArray(d.children)&&d.children.forEach((b,k)=>{C(b,`${t}.grid.cells.${i}.${y}.children.${k}`,r,o)})})})}}function re(e,t,r){e!==void 0&&(Array.isArray(e)?e.forEach((o,n)=>{(!A(o)||!Array.isArray(o.segments))&&r.push({path:`${t}.richParagraphs.${n}`,message:"段落缺少 segments 数组"})}):r.push({path:`${t}.richParagraphs`,message:"richParagraphs 应为数组"}))}function C(e,t,r,o=[]){if(!A(e)){r.push({path:t,message:"组件应为对象"});return}const n=e.kind;typeof n!="string"?r.push({path:`${t}.kind`,message:"组件缺少 kind 字符串"}):X.has(n)||o.push({path:`${t}.kind`,message:`未知组件类型 ${JSON.stringify(n)},将以兜底方式渲染`});for(const s of["leftMm","topMm","widthMm","heightMm"])Y(e,s,t,r);typeof e.leftMm=="number"&&e.leftMm<-100&&r.push({path:`${t}.leftMm`,message:"几何数值异常(leftMm<-100)"});for(const s of["widthMm","heightMm"])typeof e[s]=="number"&&e[s]<0&&r.push({path:`${t}.${s}`,message:"组件尺寸不能为负数"});ee(e.table,t,r),ne(e.code,n,t,r),e.pageAnchor!==void 0&&!["header","footer"].includes(e.pageAnchor)&&r.push({path:`${t}.pageAnchor`,message:"页面锚点应为 header 或 footer"}),e.lineDirection!==void 0&&!["down","up"].includes(e.lineDirection)&&r.push({path:`${t}.lineDirection`,message:"线段方向应为 down 或 up"}),te(e.grid,t,r,o),re(e.richParagraphs,t,r)}function ne(e,t,r,o){if(e!==void 0)for(const n of G(e,t))o.push({path:`${r}.code${n.path?`.${n.path}`:""}`,message:n.message})}function F(e,t,r){if(!A(e))return;e.binding!==void 0&&r.push({path:`${t}.binding`,message:"渲染计划不允许未解析字段绑定"});const o=e.grid;!A(o)||!Array.isArray(o.cells)||o.cells.forEach((n,s)=>{Array.isArray(n)&&n.forEach((i,d)=>{!A(i)||!Array.isArray(i.children)||i.children.forEach((y,u)=>F(y,`${t}.grid.cells.${s}.${d}.children.${u}`,r))})})}function oe(e,t,r,o=[]){if(!A(e)){r.push({path:t,message:"页应为对象"});return}const n=e.pageWidthMm,s=e.pageHeightMm;(typeof n!="number"||!Number.isFinite(n)||n<=0)&&r.push({path:`${t}.pageWidthMm`,message:`页宽非法: ${JSON.stringify(n)}`}),(typeof s!="number"||!(s>0&&s<5e3))&&r.push({path:`${t}.pageHeightMm`,message:`页高非法: ${JSON.stringify(s)}`}),e.layout!==void 0&&e.layout!=="page"&&e.layout!=="wide"&&r.push({path:`${t}.layout`,message:"布局应为 page 或 wide"});const i=e.components;Array.isArray(i)?Array.isArray(i)&&i.forEach((d,y)=>{C(d,`${t}.components.${y}`,r,o),F(d,`${t}.components.${y}`,r)}):r.push({path:`${t}.components`,message:"components 应为数组"})}function se(e){const t=[],r=[],o=A(e)?e.pages:void 0;if(A(e)&&e.requiresRecalculation!==void 0&&typeof e.requiresRecalculation!="boolean"&&t.push({path:"$.requiresRecalculation",message:"重算能力要求应为布尔值"}),!Array.isArray(o))t.push({path:"$.pages",message:e==null?"渲染计划为空":"渲染计划缺少 pages 数组"});else{o.forEach((s,i)=>oe(s,`$.pages.${i}`,t,r)),o.length>2e3&&r.push({path:"$.pages",message:`页数异常大(${o.length} 页),渲染与打印耗时可能显著增加`});const n=o.reduce((s,i)=>s+(A(i)&&Array.isArray(i.components)?i.components.length:0),0);n>5e4&&r.push({path:"$.pages",message:`组件总数异常大(${n} 个),可能触发浏览器性能限制`})}return{ok:t.length===0,errors:t,warnings:r}}const M="mach-report-worker/1";class J extends Error{constructor(t){super(t.message),this.name=t.name,this.code=t.code,this.path=t.path,this.issues=t.issues,this.diagnostics=t.diagnostics}}function R(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function ie(e){return R(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}function ae(e){return Array.isArray(e)&&e.every(t=>R(t)&&typeof t.code=="string"&&typeof t.message=="string"&&["info","warning","error"].includes(t.severity))}function ce(e){return R(e)&&Object.values(e).every(t=>R(t)&&(t.revision===void 0||typeof t.revision=="string")&&(t.sourceToken===void 0||typeof t.sourceToken=="string"))}function fe(e,t){if(!R(e)||!ie(e.stats)||!ae(e.diagnostics)||!ce(e.revisions))return!1;if(t==="prepare")return se(e.plan).ok;const r=e.format==="pdf"?"application/pdf":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";return e.bytes instanceof Uint8Array&&(e.format==="pdf"||e.format==="xlsx")&&e.contentType===r}function D(e){if(!e||typeof e!="object")return{message:String(e)};const t={};for(const r of["code","path","field","message"]){const o=e[r];typeof o=="string"&&(t[r]=o)}return t}function ue(e){const t=D(e);if(!R(e))return t;for(const r of["format","severity","kind","nid"])typeof e[r]=="string"&&(t[r]=e[r]);for(const r of["pageIndex","componentIndex"])Number.isSafeInteger(e[r])&&e[r]>=0&&(t[r]=e[r]);return Array.isArray(e.componentPath)&&e.componentPath.every(r=>Number.isSafeInteger(r)&&r>=0)&&(t.componentPath=e.componentPath),t}function pe(e){if(!(e instanceof Error))return{name:"Error",message:String(e)};const t=e;return{name:e.name,message:e.message,...typeof t.code=="string"?{code:t.code}:{},...typeof t.path=="string"?{path:t.path}:{},...Array.isArray(t.issues)?{issues:t.issues.map(D)}:{},...Array.isArray(t.diagnostics)?{diagnostics:t.diagnostics.map(ue)}:{}}}function de(e){if(!e||typeof e!="object")return!1;const t=e;return t.protocol===M&&typeof t.id=="string"&&(t.operation==="prepare"||t.operation==="export")&&!!t.input&&typeof t.input=="object"}async function me(e,t,r){try{const o=t.operation==="prepare"?await e.prepare({...t.input,onEvent:r}):await e.export({...t.input,onEvent:r});return{protocol:M,id:t.id,result:o}}catch(o){return{protocol:M,id:t.id,error:pe(o)}}}function ye(e){const t=e.result;return!t||!("bytes"in t)||!(t.bytes.buffer instanceof ArrayBuffer)?[]:[t.bytes.buffer]}function le(e,t){if(!R(e)||typeof e.taskId!="string"||!e.taskId||t.taskId!==void 0&&e.taskId!==t.taskId||e.correlationId!==t.correlationId||e.reportId!==void 0&&(typeof e.reportId!="string"||!t.reportIds.includes(e.reportId))||!["query","validate","layout","assets","encode"].includes(e.stage)||!["started","completed","failed"].includes(e.status))return!1;for(const r of["completed","total"])if(e[r]!==void 0&&(typeof e[r]!="number"||!Number.isFinite(e[r])||e[r]<0))return!1;return e.completed===void 0||e.total===void 0||e.completed<=e.total}let he=0;function P(e){const t=new Error("报表 Worker 任务已取消");return t.name="AbortError",Object.defineProperty(t,"cause",{value:e}),t}function ge(e,t){if(!e||typeof e!="object")return;const r=e;return r.protocol===M&&r.id===t?r:void 0}function we(e,t={}){const r=t.timeoutMs??12e4;if(!Number.isFinite(r)||r<=0||r>2147483647)throw new RangeError("Worker timeoutMs 应为正有限数字,且不能超过 2147483647");const o=(n,s,i,d)=>i?.aborted?Promise.reject(P(i.reason)):new Promise((y,u)=>{let b;try{b=e()}catch(l){u(l);return}const k=`mach-report-${Date.now()}-${++he}`;let p=!1,f=()=>{},c;const m=(l,w)=>{p||(p=!0,c&&clearTimeout(c),f(),i?.removeEventListener("abort",g),Promise.resolve().then(()=>b.terminate()).then(()=>l===void 0?y(w):u(l),N=>u(l??N)))},g=()=>m(P(i?.reason)),x=l=>{const w=ge(l,k);if(!(!w||p)){if("type"in w&&w.type==="event"){const N="event"in w?w.event:void 0;le(N,s)?H(d,N,i):m(new Error("报表 Worker 返回无效阶段事件"));return}w.error&&typeof w.error.name=="string"&&typeof w.error.message=="string"?m(new J(w.error)):fe(w.result,n)&&(n!=="export"||"format"in w.result&&"format"in s&&w.result.format===s.format)?m(void 0,w.result):m(new Error("报表 Worker 返回无效响应"))}};try{if(f=b.subscribe(x,l=>m(l??new Error("报表 Worker 执行失败"))),p){f();return}if(i?.addEventListener("abort",g,{once:!0}),c=setTimeout(()=>m(new J({name:"ReportRuntimeError",code:"timeout",message:`报表 Worker 执行超过 ${r}ms`})),r),i?.aborted)g();else{const{onEvent:l,signal:w,...N}=s;b.postMessage({protocol:M,id:k,operation:n,input:N})}}catch(l){m(l)}});return{prepare:(n,s,i)=>o("prepare",n,s,i),export:(n,s,i)=>o("export",n,s,i)}}const be=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),$=(e,t)=>e>>>t|e<<32-t;function Ae(e,t,r){const o=new DataView(e.buffer,e.byteOffset+t,64);for(let n=0;n<16;n++)r[n]=o.getUint32(n*4);for(let n=16;n<64;n++){const s=r[n-15],i=r[n-2],d=$(s,7)^$(s,18)^s>>>3,y=$(i,17)^$(i,19)^i>>>10;r[n]=r[n-16]+d+r[n-7]+y}}function xe(e,t){let r=e[0],o=e[1],n=e[2],s=e[3],i=e[4],d=e[5],y=e[6],u=e[7];for(let b=0;b<64;b++){const k=$(i,6)^$(i,11)^$(i,25),p=i&d^~i&y,f=u+k+p+be[b]+t[b]>>>0,c=$(r,2)^$(r,13)^$(r,22),m=r&o^r&n^o&n,g=c+m>>>0;u=y,y=d,d=i,i=s+f>>>0,s=n,n=o,o=r,r=f+g>>>0}e[0]=e[0]+r,e[1]=e[1]+o,e[2]=e[2]+n,e[3]=e[3]+s,e[4]=e[4]+i,e[5]=e[5]+d,e[6]=e[6]+y,e[7]=e[7]+u}function $e(e){const t=new Uint8Array(Math.ceil((e.byteLength+9)/64)*64);t.set(e),t[e.byteLength]=128;const r=new DataView(t.buffer);return r.setUint32(t.length-8,Math.floor(e.byteLength/536870912)),r.setUint32(t.length-4,e.byteLength*8>>>0),t}const ke=()=>new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),Ne=e=>Array.from(e,t=>t.toString(16).padStart(8,"0")).join("");async function ve(e){const t=$e(e),r=ke(),o=new Uint32Array(64);for(let n=0;n<t.length;n+=64)n>0&&n%262144===0&&await new Promise(s=>setTimeout(s,0)),Ae(t,n,o),xe(r,o);return Ne(r)}class a extends Error{constructor(t,r){super(r),this.code=t,this.name="ReportJobError"}}function T(e,t){if(typeof e!="string"||!e.trim()||e.length>256||typeof t!="string"||t!==t.trim()||!/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,127}$/.test(t))throw new a("input","任务范围应非空,ID应为1–128位安全标识")}function Se(e){const t=Array.isArray(e),r=Object.getPrototypeOf(e),o=Object.keys(e);if(r!==(t?Array.prototype:Object.prototype)&&!(r===null&&!t))throw new a("input","任务对象应为普通 JSON 对象");if(Object.getOwnPropertySymbols(e).length)throw new a("input","任务不能包含Symbol");if(Object.getOwnPropertyNames(e).filter(s=>!(t&&s==="length")).length!==o.length)throw new a("input","任务不能包含不可枚举属性");if(t&&(o.length!==e.length||o.some(s=>s!==String(Number(s))||!Number.isSafeInteger(Number(s))||Number(s)<0||Number(s)>=e.length)))throw new a("input","任务数组不能稀疏或包含额外属性");return o.sort()}function Re(e,t){const r=Object.getOwnPropertyDescriptor(e,t);if(["__proto__","prototype","constructor"].includes(t)||r.get||r.set)throw new a("input","任务不能包含危险键或访问器");return r.value}function v(e,t={}){const r=t.maxNodes??2e4,o=t.maxCharacters??1e6;if(!Number.isSafeInteger(r)||r<1||r>2e4||!Number.isSafeInteger(o)||o<1||o>1e6)throw new a("input","任务JSON预算无效");let n=0,s=0;const i=new Set;function d(u,b){if(++n>r||b>32)throw new a("input","任务数据超过节点或深度预算");if(typeof u=="string"){if(s+=u.length,s>o)throw new a("input","任务文本超过预算");return u}if(u===null||typeof u=="boolean"||typeof u=="number"&&Number.isFinite(u))return u;if(!u||typeof u!="object"||i.has(u))throw new a("input","任务只允许无循环的有限 JSON 值");const k=Array.isArray(u),p=Se(u);i.add(u);const f=Object.create(null);for(const c of p){if(s+=c.length,s>o)throw new a("input","任务文本超过预算");f[c]=d(Re(u,c),b+1)}return i.delete(u),k?Array.from({length:u.length},(c,m)=>f[String(m)]):f}const y=JSON.stringify(d(e,0));if(y.length>o)throw new a("input","任务序列化数据超过字符预算");return y}function q(e){return JSON.parse(JSON.stringify(e))}function _(e,t,r,o){if(T(t,r),e.scope!==t||e.id!==r||e.revision!==(o??0)+1||!Number.isSafeInteger(e.revision))throw new a("input","任务身份或修订不匹配");if(![e.createdAt,e.updatedAt,e.attempt].every(n=>Number.isSafeInteger(n)&&n>=0)||!["queued","running","completed","failed","cancelled"].includes(e.status))throw new a("input","任务状态无效");if(e.lease&&(!e.lease.owner||!Number.isSafeInteger(e.lease.expiresAt)))throw new a("input","任务租约无效");if(!e.request||typeof e.request.kind!="string"||!e.request.kind.trim()||e.request.kind.length>128)throw new a("input","任务类型无效");v(e.request.payload,{maxNodes:19e3,maxCharacters:75e4}),v(e)}function Me(e,t){if(e&&(e.createdAt!==t.createdAt||v(e.request)!==v(t.request)))throw new a("input","任务创建时间与请求不可变更,请使用新任务ID")}function Ee(e,t){return e.status==="queued"||e.status==="running"&&(e.lease?.expiresAt??0)<=t}function Oe(e={}){const t={maxRecords:e.maxRecords??1e4,maxBytes:e.maxBytes??67108864,maxResultBytes:e.maxResultBytes??262144,controlReserveBytes:e.controlReserveBytes??4096,maxTombstones:e.maxTombstones??1e4,maxTombstoneBytes:e.maxTombstoneBytes??16777216};if(!Object.values(t).every(r=>Number.isSafeInteger(r)&&r>0)||t.controlReserveBytes<4096)throw new a("input","任务容量应为正整数,控制状态预留至少4096字节");return t}function E(e){return new TextEncoder().encode(v(e)).byteLength}function L(e,t){const r={scope:e.scope,id:e.id,revision:1,request:e.request,status:"queued",createdAt:e.createdAt,updatedAt:e.createdAt,attempt:0},o={...e};delete o.result;const n=e.result===void 0?0:E(e.result);if(n>t.maxResultBytes)throw new a("capacity","任务结果超过独立预算,请保存文件引用");return Math.max(E(r)+t.controlReserveBytes,E(o))+n}function z(e){return e.status!=="queued"&&e.status!=="running"}function Ie(e){const t={...e,tombstoneRetentionMs:e.tombstoneRetentionMs??6048e5,limit:e.limit??100};if(![t.now,t.terminalBefore].every(r=>Number.isSafeInteger(r)&&r>=0)||t.terminalBefore>t.now)throw new a("input","终态清理时间应为不超过当前时间的非负整数");if(![t.tombstoneRetentionMs,t.limit].every(r=>Number.isSafeInteger(r)&&r>0)||!Number.isSafeInteger(t.now+t.tombstoneRetentionMs))throw new a("input","幂等保留期与清理批量应为正整数");return t}async function Te(e){const t=new TextEncoder().encode(v(e)),r=globalThis.crypto?.subtle;if(!r)return ve(t);const o=await r.digest("SHA-256",t);return Array.from(new Uint8Array(o),n=>n.toString(16).padStart(2,"0")).join("")}async function je(e,t){if(!z(e))throw new a("input","只能归档终态任务");return{scope:e.scope,id:e.id,revision:e.revision,status:e.status,createdAt:e.createdAt,updatedAt:e.updatedAt,attempt:e.attempt,requestHash:await Te(e.request),expiresAt:t}}function qe(e){if(!e||!["completed","failed","cancelled"].includes(e.status)||!/^[a-f0-9]{64}$/.test(e.requestHash))throw new a("input","任务幂等摘要无效");if(![e.revision,e.createdAt,e.updatedAt,e.attempt,e.expiresAt].every(t=>Number.isSafeInteger(t)&&t>=0)||e.revision<1)throw new a("input","任务幂等摘要时间或修订无效")}function I(e){return e?.code}function O(e,t){return j.createHash("sha256").update(JSON.stringify([e,t])).digest("hex")+".json"}async function B(e){try{return await h.promises.readFile(e,"utf8")}catch(t){if(I(t)==="ENOENT")return;throw t}}async function Je(e,t){const r=await B(e);if(r===void 0)return;let o;try{o=JSON.parse(r)}catch{throw new a("conflict","任务锁尚未完整写入或已损坏,拒绝自动移除")}if(!o||!Number.isSafeInteger(o.pid)||o.pid<1)throw new a("conflict","任务锁身份无效,拒绝自动移除");try{process.kill(o.pid,0)}catch(n){if(I(n)==="ESRCH"){await h.promises.unlink(e);return}throw n}throw new a("conflict","任务目录的写入进程仍在运行")}async function Be(e,t){if(!t)throw new a("conflict","任务目录已有写入进程;多实例请使用数据库CAS适配器");const r=e+".recovery";let o;try{o=await h.promises.open(r,"wx",384)}catch(n){throw I(n)==="EEXIST"?new a("conflict","任务目录恢复正在进行,请稍后重试"):n}try{return await o.writeFile(JSON.stringify({pid:process.pid})),await Je(e,!0),await h.promises.open(e,"wx",384)}finally{await o.close(),await h.promises.unlink(r)}}async function Pe(e,t){const r=S.join(e,".writer-lock"),o=j.randomUUID();let n;try{n=await h.promises.open(r,"wx",384)}catch(s){if(I(s)!=="EEXIST")throw s;n=await Be(r,t)}try{await n.writeFile(JSON.stringify({pid:process.pid,token:o})),await n.sync()}catch(s){throw await n.close(),await h.promises.unlink(r).catch(()=>{}),s}return{file:r,token:o,handle:n}}function We(e,t,r,o){if("tombstone"in r){const n=r.tombstone;if(qe(n),T(n.scope,n.id),O(n.scope,n.id)!==t)throw new a("input","持久任务摘要身份不匹配");const s=E(n);e.tombstoneBytes+=s,e.tombstones.set(t,{value:n,bytes:s})}else{if(_(r,r.scope,r.id,r.revision-1),O(r.scope,r.id)!==t)throw new a("input","持久任务文件身份不匹配");const n=L(r,o);e.bytes+=n,e.records.set(t,{record:r,bytes:n})}if(e.bytes>o.maxBytes||e.records.size>o.maxRecords||e.tombstoneBytes>o.maxTombstoneBytes||e.tombstones.size>o.maxTombstones)throw new a("capacity","持久任务及控制状态预留超过目录预算")}async function Ue(e,t){const r=await h.promises.readdir(e);for(const s of r.filter(i=>/^\.pending-[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(i)))await h.promises.unlink(S.join(e,s));const o=r.filter(s=>/^[a-f0-9]{64}\.json$/.test(s));if(o.length>t.maxRecords+t.maxTombstones)throw new a("capacity","持久任务数量超过目录预算");const n={records:new Map,tombstones:new Map,bytes:0,tombstoneBytes:0};for(const s of o){const i=S.join(e,s);if((await h.promises.stat(i)).size>4e6)throw new a("capacity","持久任务文件超过单文件预算");We(n,s,JSON.parse(await h.promises.readFile(i,"utf8")),t)}return n}async function Ce(e,t,r){const o=S.join(e,`.pending-${j.randomUUID()}`);try{const n=await h.promises.open(o,"wx",384);try{await n.writeFile(r),await n.sync()}finally{await n.close()}await h.promises.rename(o,S.join(e,t));const s=await h.promises.open(e,"r");try{await s.sync()}finally{await s.close()}}finally{await h.promises.unlink(o).catch(n=>{if(I(n)!=="ENOENT")throw n})}}async function Fe(e){const t=S.resolve(e.directory),r=Oe(e);await h.promises.mkdir(t,{recursive:!0,mode:448});const o=await Pe(t,e.recoverDeadOwner??!1);let n;try{n=await Ue(t,r)}catch(p){throw await o.handle.close(),await h.promises.unlink(o.file),p}let s=!1,i=Promise.resolve();const d=()=>{if(s)throw new a("closed","持久任务存储已关闭")},y=p=>{d();const f=i.then(async()=>{if(JSON.parse(await h.promises.readFile(o.file,"utf8")).token!==o.token)throw new a("closed","持久任务存储写入锁已失效");return p()});return i=f.then(()=>{},()=>{}),f},u=async(p,f,c)=>{try{await Ce(t,p,f)}catch(m){throw await B(S.join(t,p))===f&&c(),m}c()};return{read:async(p,f)=>{d(),T(p,f),await i;const c=n.records.get(O(p,f));return c?q(c.record):void 0},readTombstone:async(p,f)=>{d(),T(p,f),await i;const c=n.tombstones.get(O(p,f));return c?q(c.value):void 0},candidates:async(p,f)=>(d(),await i,Array.from(n.records.values(),c=>c.record).filter(c=>Ee(c,p)).sort((c,m)=>c.createdAt-m.createdAt).slice(0,f).map(q)),compareAndSwap:async(p,f,c,m)=>{const g=JSON.parse(v(m));return _(g,p,f,c),y(async()=>{const x=O(p,f),l=n.records.get(x);if((l?.record.revision??null)!==c||n.tombstones.has(x))return!1;Me(l?.record,g);const w=L(g,r),N=n.bytes-(l?.bytes??0)+w;if(N>r.maxBytes||!l&&n.records.size>=r.maxRecords)throw new a("capacity","持久任务容量已满,请清理终态任务或扩大显式预算");return await u(x,v(g),()=>{n.records.set(x,{record:g,bytes:w}),n.bytes=N}),!0})},prune:async p=>{const f=Ie(p);return y(async()=>{const c={archived:0,expired:0};for(const[m,g]of n.tombstones)g.value.expiresAt>f.now||c.expired>=f.limit||(await h.promises.unlink(S.join(t,m)),n.tombstones.delete(m),n.tombstoneBytes-=g.bytes,c.expired++);for(const[m,g]of n.records){if(!z(g.record)||g.record.updatedAt>f.terminalBefore||c.archived+c.expired>=f.limit)continue;const x=await je(g.record,f.now+f.tombstoneRetentionMs),l=E(x);if(n.tombstones.size>=r.maxTombstones||n.tombstoneBytes+l>r.maxTombstoneBytes)break;await u(m,v({tombstone:x}),()=>{n.tombstones.set(m,{value:x,bytes:l}),n.tombstoneBytes+=l,n.records.delete(m),n.bytes-=g.bytes}),c.archived++}if(c.expired){const m=await h.promises.open(t,"r");try{await m.sync()}finally{await m.close()}}return c})},close:async()=>{if(s)return;s=!0,await i,await o.handle.close();const p=await B(o.file);p&&JSON.parse(p).token===o.token&&await h.promises.unlink(o.file)}}}function De(e){const t=e.filename??e.workerUrl;if(!t||e.filename&&e.workerUrl)throw new TypeError("请且仅请指定 filename 或 workerUrl");return we(()=>{const r=new W.Worker(t,e.workerOptions);return{postMessage:o=>r.postMessage(o),terminate:()=>r.terminate(),subscribe:(o,n)=>{const s=i=>n(new Error(`报表 Worker 在响应前退出(code ${i})`));return r.on("message",o),r.on("error",n),r.on("messageerror",n),r.on("exit",s),()=>{r.off("message",o),r.off("error",n),r.off("messageerror",n),r.off("exit",s)}}}},e)}function _e(e){const t=W.parentPort;if(!t)throw new Error("serveNodeReportWorker 只能在 worker_threads 中调用");const r=o=>{de(o)&&me(e,o,n=>t.postMessage({protocol:M,id:o.id,type:"event",event:n})).then(n=>t.postMessage(n,ye(n)))};return t.on("message",r),()=>t.off("message",r)}function Le(e){return j.createHash("sha256").update(e).digest("hex")}exports.ReportWorkerError=J;exports.createNodeReportExecutor=De;exports.openFileReportJobStore=Fe;exports.reportArtifactSha256=Le;exports.serveNodeReportWorker=_e;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const W=require("node:worker_threads"),j=require("node:crypto"),h=require("node:fs"),R=require("node:path");function z(e,t,r){if(!r?.aborted)try{const o=e?.({...t});o&&typeof o.then=="function"&&Promise.resolve(o).catch(()=>{})}catch{}}function H(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;const t=e,r=o=>typeof o=="string"&&o.trim().length>0&&o.length<=256;return!r(t.datasetId)||!r(t.field)||t.tableId!==void 0&&!r(t.tableId)?!1:t.rowKey===void 0?!0:typeof t.rowKey=="string"?t.rowKey.trim().length>0&&t.rowKey.length<=1024:typeof t.rowKey=="number"&&Number.isFinite(t.rowKey)}function Z(e){return e==="missing-source"||e==="not-applicable"||e==="not-calculable"}function Q(e){return e.target!==void 0&&!H(e.target)?!1:e.valueState===void 0||Z(e.valueState)&&e.target!==void 0}function V(e,t,r){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"})}function G(e,t,r){V(e,t,r),e.indentMm!==void 0&&(typeof e.indentMm!="number"||!Number.isFinite(e.indentMm)||e.indentMm<0)&&r.push({path:`${t}.indentMm`,message:"单元格缩进应为有限非负数"}),e.derived!==void 0&&typeof e.derived!="boolean"&&r.push({path:`${t}.derived`,message:"派生结果标记应为布尔值"}),F(e.source,`${t}.source`,r,!0),e.formula!==void 0&&typeof e.formula!="string"&&r.push({path:`${t}.formula`,message:"单元格公式应为字符串"})}function F(e,t,r,o=!1){if(e===void 0)return;if(!e||typeof e!="object"||Array.isArray(e)){r.push({path:t,message:"业务来源应为对象"});return}const n=e;for(const s of["datasetId",...o?["field"]:[]])(typeof n[s]!="string"||!n[s].trim())&&r.push({path:`${t}.${s}`,message:"业务标识应为非空字符串"});for(const s of["rowKey","revision"]){const i=n[s];i===void 0&&!(o&&s==="rowKey")||typeof i!="string"&&!(typeof i=="number"&&Number.isFinite(i))&&r.push({path:`${t}.${s}`,message:"业务键及修订号应为字符串或有限数字"})}n.sourceToken!==void 0&&typeof n.sourceToken!="string"&&r.push({path:`${t}.sourceToken`,message:"来源令牌应为字符串"})}function X(e){const t=[];return e.value!==void 0&&typeof e.value!="string"&&t.push({path:"value",message:"Symbol value must be a string."}),e.symbology!==void 0&&!["code128","code39","ean13","ean8"].includes(e.symbology)&&t.push({path:"symbology",message:"Unsupported barcode symbology."}),e.errorCorrection!==void 0&&!["L","M","Q","H"].includes(e.errorCorrection)&&t.push({path:"errorCorrection",message:"Unsupported QR error correction."}),e.showText!==void 0&&typeof e.showText!="boolean"&&t.push({path:"showText",message:"showText must be a boolean."}),t}function Y(e,t){const r=[];return t!=="barcode"&&t!=="qrcode"&&r.push({path:"",message:"code is only supported by barcode and qrcode components."}),t==="qrcode"&&e.symbology!==void 0&&r.push({path:"symbology",message:"QR components do not use a linear symbology."}),t==="qrcode"&&e.showText===!0&&r.push({path:"showText",message:"Use a separate text component below a QR code."}),t==="barcode"&&e.errorCorrection!==void 0&&r.push({path:"errorCorrection",message:"Linear barcodes do not use QR error correction."}),r}function ee(e,t){if(typeof e!="object"||e===null||Array.isArray(e))return[{path:"",message:"code must be an object."}];const r=e,o=[...X(r),...Y(r,t)];for(const i of Object.keys(r))["value","symbology","errorCorrection","quietZoneModules","showText"].includes(i)||o.push({path:i,message:"Unknown symbol option."});const n=r.symbology==="ean13"||r.symbology==="ean8",s=t==="qrcode"?4:n?11:10;return r.quietZoneModules!==void 0&&(!Number.isSafeInteger(r.quietZoneModules)||Number(r.quietZoneModules)<s||Number(r.quietZoneModules)>64)&&o.push({path:"quietZoneModules",message:`Quiet zone must contain ${s}–64 whole modules.`}),o}const te=new Set(["text","image","barcode","qrcode","chart","line","rect","ellipse"]);function A(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function re(e,t,r,o){const n=e[t];(typeof n!="number"||!Number.isFinite(n))&&o.push({path:`${r}.${t}`,message:`应为有限数字,实际 ${JSON.stringify(n)}`})}function ne(e,t,r){if(e!==void 0){const o=`${t}.table`;if(!A(e))r.push({path:o,message:"逻辑表来源应为对象"});else{F(e.source,`${o}.source`,r),(typeof e.id!="string"||!e.id.trim())&&r.push({path:`${o}.id`,message:"逻辑表 ID 应为非空字符串"});const n=e.role;["header","body","group-header","subtotal","grand-total"].includes(n)||r.push({path:`${o}.role`,message:"未知逻辑表行角色"});const s=e.rowIndex;(typeof s!="number"||!Number.isInteger(s)||(n==="header"?s!==-1:s<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:"逻辑表名称应为字符串"})}}}function oe(e,t,r,o){if(e!==void 0)if(!A(e)||!Array.isArray(e.cells))r.push({path:`${t}.grid.cells`,message:"grid.cells 应为二维数组"});else{const n=e.paddingMm;n!==void 0&&(typeof n!="number"||!Number.isFinite(n)||n<0)&&r.push({path:`${t}.grid.paddingMm`,message:"单元格内距应为有限非负数"}),e.cells.forEach((s,i)=>{if(!Array.isArray(s)){r.push({path:`${t}.grid.cells.${i}`,message:"行应为数组"});return}s.forEach((d,y)=>{if(d==null)return;const u=`${t}.grid.cells.${i}.${y}`;if(!A(d)){r.push({path:u,message:"网格单元格应为对象或 null"});return}G(d,u,r),Array.isArray(d.children)&&d.children.forEach((b,k)=>{U(b,`${t}.grid.cells.${i}.${y}.children.${k}`,r,o)})})})}}function se(e,t,r){e!==void 0&&(Array.isArray(e)?e.forEach((o,n)=>{(!A(o)||!Array.isArray(o.segments))&&r.push({path:`${t}.richParagraphs.${n}`,message:"段落缺少 segments 数组"})}):r.push({path:`${t}.richParagraphs`,message:"richParagraphs 应为数组"}))}function U(e,t,r,o=[]){if(!A(e)){r.push({path:t,message:"组件应为对象"});return}const n=e.kind;typeof n!="string"?r.push({path:`${t}.kind`,message:"组件缺少 kind 字符串"}):te.has(n)||o.push({path:`${t}.kind`,message:`未知组件类型 ${JSON.stringify(n)},将以兜底方式渲染`});for(const s of["leftMm","topMm","widthMm","heightMm"])re(e,s,t,r);typeof e.leftMm=="number"&&e.leftMm<-100&&r.push({path:`${t}.leftMm`,message:"几何数值异常(leftMm<-100)"});for(const s of["widthMm","heightMm"])typeof e[s]=="number"&&e[s]<0&&r.push({path:`${t}.${s}`,message:"组件尺寸不能为负数"});ne(e.table,t,r),ie(e.code,n,t,r),e.pageAnchor!==void 0&&!["header","footer"].includes(e.pageAnchor)&&r.push({path:`${t}.pageAnchor`,message:"页面锚点应为 header 或 footer"}),e.lineDirection!==void 0&&!["down","up"].includes(e.lineDirection)&&r.push({path:`${t}.lineDirection`,message:"线段方向应为 down 或 up"}),oe(e.grid,t,r,o),se(e.richParagraphs,t,r)}function ie(e,t,r,o){if(e!==void 0)for(const n of ee(e,t))o.push({path:`${r}.code${n.path?`.${n.path}`:""}`,message:n.message})}function D(e,t,r){if(!A(e))return;e.binding!==void 0&&r.push({path:`${t}.binding`,message:"渲染计划不允许未解析字段绑定"});const o=e.grid;!A(o)||!Array.isArray(o.cells)||o.cells.forEach((n,s)=>{Array.isArray(n)&&n.forEach((i,d)=>{!A(i)||!Array.isArray(i.children)||i.children.forEach((y,u)=>D(y,`${t}.grid.cells.${s}.${d}.children.${u}`,r))})})}function ae(e,t,r,o=[]){if(!A(e)){r.push({path:t,message:"页应为对象"});return}const n=e.pageWidthMm,s=e.pageHeightMm;(typeof n!="number"||!Number.isFinite(n)||n<=0)&&r.push({path:`${t}.pageWidthMm`,message:`页宽非法: ${JSON.stringify(n)}`}),(typeof s!="number"||!(s>0&&s<5e3))&&r.push({path:`${t}.pageHeightMm`,message:`页高非法: ${JSON.stringify(s)}`}),e.layout!==void 0&&e.layout!=="page"&&e.layout!=="wide"&&r.push({path:`${t}.layout`,message:"布局应为 page 或 wide"});const i=e.components;Array.isArray(i)?Array.isArray(i)&&i.forEach((d,y)=>{U(d,`${t}.components.${y}`,r,o),D(d,`${t}.components.${y}`,r)}):r.push({path:`${t}.components`,message:"components 应为数组"})}function ce(e){const t=[],r=[],o=A(e)?e.pages:void 0;if(A(e)&&e.requiresRecalculation!==void 0&&typeof e.requiresRecalculation!="boolean"&&t.push({path:"$.requiresRecalculation",message:"重算能力要求应为布尔值"}),!Array.isArray(o))t.push({path:"$.pages",message:e==null?"渲染计划为空":"渲染计划缺少 pages 数组"});else{o.forEach((s,i)=>ae(s,`$.pages.${i}`,t,r)),o.length>2e3&&r.push({path:"$.pages",message:`页数异常大(${o.length} 页),渲染与打印耗时可能显著增加`});const n=o.reduce((s,i)=>s+(A(i)&&Array.isArray(i.components)?i.components.length:0),0);n>5e4&&r.push({path:"$.pages",message:`组件总数异常大(${n} 个),可能触发浏览器性能限制`})}return{ok:t.length===0,errors:t,warnings:r}}const M="mach-report-worker/1";class J extends Error{constructor(t){super(t.message),this.name=t.name,this.code=t.code,this.path=t.path,this.issues=t.issues,this.diagnostics=t.diagnostics}}function v(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function fe(e){return v(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}function ue(e){return Array.isArray(e)&&e.every(t=>v(t)&&typeof t.code=="string"&&typeof t.message=="string"&&["info","warning","error"].includes(t.severity)&&Q(t))}function pe(e){return v(e)&&Object.values(e).every(t=>v(t)&&(t.revision===void 0||typeof t.revision=="string")&&(t.sourceToken===void 0||typeof t.sourceToken=="string"))}function de(e){return e===void 0?!0:v(e)&&["heuristic","provided","font-bytes"].includes(e.textMetrics)&&(e.fontFingerprint===void 0||typeof e.fontFingerprint=="string"&&/^[a-f0-9]{64}$/.test(e.fontFingerprint))}function me(e,t){if(!v(e)||!fe(e.stats)||!ue(e.diagnostics)||!pe(e.revisions)||!de(e.layout))return!1;if(t==="prepare")return ce(e.plan).ok;const r=e.format==="pdf"?"application/pdf":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";return e.bytes instanceof Uint8Array&&(e.format==="pdf"||e.format==="xlsx")&&e.contentType===r}function C(e){if(!e||typeof e!="object")return{message:String(e)};const t={};for(const r of["code","path","field","message"]){const o=e[r];typeof o=="string"&&(t[r]=o)}return t}function ye(e){const t=C(e);if(!v(e))return t;for(const r of["format","severity","kind","nid"])typeof e[r]=="string"&&(t[r]=e[r]);for(const r of["pageIndex","componentIndex"])Number.isSafeInteger(e[r])&&e[r]>=0&&(t[r]=e[r]);return Array.isArray(e.componentPath)&&e.componentPath.every(r=>Number.isSafeInteger(r)&&r>=0)&&(t.componentPath=e.componentPath),t}function le(e){if(!(e instanceof Error))return{name:"Error",message:String(e)};const t=e;return{name:e.name,message:e.message,...typeof t.code=="string"?{code:t.code}:{},...typeof t.path=="string"?{path:t.path}:{},...Array.isArray(t.issues)?{issues:t.issues.map(C)}:{},...Array.isArray(t.diagnostics)?{diagnostics:t.diagnostics.map(ye)}:{}}}function he(e){if(!e||typeof e!="object")return!1;const t=e;return t.protocol===M&&typeof t.id=="string"&&(t.operation==="prepare"||t.operation==="export"||t.operation==="exportPrepared")&&!!t.input&&typeof t.input=="object"}async function ge(e,t,r){try{const o=t.operation==="prepare"?await e.prepare({...t.input,onEvent:r}):t.operation==="exportPrepared"?await e.exportPrepared({...t.input,onEvent:r}):await e.export({...t.input,onEvent:r});return{protocol:M,id:t.id,result:o}}catch(o){return{protocol:M,id:t.id,error:le(o)}}}function we(e){const t=e.result;return!t||!("bytes"in t)||!(t.bytes.buffer instanceof ArrayBuffer)?[]:[t.bytes.buffer]}function be(e,t){if(!v(e)||typeof e.taskId!="string"||!e.taskId||t.taskId!==void 0&&e.taskId!==t.taskId||e.correlationId!==t.correlationId||e.reportId!==void 0&&(typeof e.reportId!="string"||!("reportIds"in t&&t.reportIds.includes(e.reportId)))||!["query","validate","layout","assets","encode"].includes(e.stage)||!["started","completed","failed"].includes(e.status))return!1;for(const r of["completed","total"])if(e[r]!==void 0&&(typeof e[r]!="number"||!Number.isFinite(e[r])||e[r]<0))return!1;return e.completed===void 0||e.total===void 0||e.completed<=e.total}let Ae=0;function P(e){const t=new Error("报表 Worker 任务已取消");return t.name="AbortError",Object.defineProperty(t,"cause",{value:e}),t}function xe(e,t){if(!e||typeof e!="object")return;const r=e;return r.protocol===M&&r.id===t?r:void 0}function $e(e,t={}){const r=t.timeoutMs??12e4;if(!Number.isFinite(r)||r<=0||r>2147483647)throw new RangeError("Worker timeoutMs 应为正有限数字,且不能超过 2147483647");const o=(n,s,i,d)=>i?.aborted?Promise.reject(P(i.reason)):new Promise((y,u)=>{let b;try{b=e()}catch(l){u(l);return}const k=`mach-report-${Date.now()}-${++Ae}`;let p=!1,f=()=>{},c;const m=(l,w)=>{p||(p=!0,c&&clearTimeout(c),f(),i?.removeEventListener("abort",g),Promise.resolve().then(()=>b.terminate()).then(()=>l===void 0?y(w):u(l),N=>u(l??N)))},g=()=>m(P(i?.reason)),x=l=>{const w=xe(l,k);if(!(!w||p)){if("type"in w&&w.type==="event"){const N="event"in w?w.event:void 0;be(N,s)?z(d,N,i):m(new Error("报表 Worker 返回无效阶段事件"));return}w.error&&typeof w.error.name=="string"&&typeof w.error.message=="string"?m(new J(w.error)):me(w.result,n)&&(n==="prepare"||"format"in w.result&&"format"in s&&w.result.format===s.format)?m(void 0,w.result):m(new Error("报表 Worker 返回无效响应"))}};try{if(f=b.subscribe(x,l=>m(l??new Error("报表 Worker 执行失败"))),p){f();return}if(i?.addEventListener("abort",g,{once:!0}),c=setTimeout(()=>m(new J({name:"ReportRuntimeError",code:"timeout",message:`报表 Worker 执行超过 ${r}ms`})),r),i?.aborted)g();else{const{onEvent:l,signal:w,...N}=s;b.postMessage({protocol:M,id:k,operation:n,input:N})}}catch(l){m(l)}});return{exportPrepared:(n,s,i)=>o("exportPrepared",n,s,i),prepare:(n,s,i)=>o("prepare",n,s,i),export:(n,s,i)=>o("export",n,s,i)}}const ke=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),$=(e,t)=>e>>>t|e<<32-t;function Ne(e,t,r){const o=new DataView(e.buffer,e.byteOffset+t,64);for(let n=0;n<16;n++)r[n]=o.getUint32(n*4);for(let n=16;n<64;n++){const s=r[n-15],i=r[n-2],d=$(s,7)^$(s,18)^s>>>3,y=$(i,17)^$(i,19)^i>>>10;r[n]=r[n-16]+d+r[n-7]+y}}function Se(e,t){let r=e[0],o=e[1],n=e[2],s=e[3],i=e[4],d=e[5],y=e[6],u=e[7];for(let b=0;b<64;b++){const k=$(i,6)^$(i,11)^$(i,25),p=i&d^~i&y,f=u+k+p+ke[b]+t[b]>>>0,c=$(r,2)^$(r,13)^$(r,22),m=r&o^r&n^o&n,g=c+m>>>0;u=y,y=d,d=i,i=s+f>>>0,s=n,n=o,o=r,r=f+g>>>0}e[0]=e[0]+r,e[1]=e[1]+o,e[2]=e[2]+n,e[3]=e[3]+s,e[4]=e[4]+i,e[5]=e[5]+d,e[6]=e[6]+y,e[7]=e[7]+u}function Re(e){const t=new Uint8Array(Math.ceil((e.byteLength+9)/64)*64);t.set(e),t[e.byteLength]=128;const r=new DataView(t.buffer);return r.setUint32(t.length-8,Math.floor(e.byteLength/536870912)),r.setUint32(t.length-4,e.byteLength*8>>>0),t}const ve=()=>new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),Me=e=>Array.from(e,t=>t.toString(16).padStart(8,"0")).join("");async function Ee(e){const t=Re(e),r=ve(),o=new Uint32Array(64);for(let n=0;n<t.length;n+=64)n>0&&n%262144===0&&await new Promise(s=>setTimeout(s,0)),Ne(t,n,o),Se(r,o);return Me(r)}class a extends Error{constructor(t,r){super(r),this.code=t,this.name="ReportJobError"}}function T(e,t){if(typeof e!="string"||!e.trim()||e.length>256||typeof t!="string"||t!==t.trim()||!/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,127}$/.test(t))throw new a("input","任务范围应非空,ID应为1–128位安全标识")}function Ie(e){const t=Array.isArray(e),r=Object.getPrototypeOf(e),o=Object.keys(e);if(r!==(t?Array.prototype:Object.prototype)&&!(r===null&&!t))throw new a("input","任务对象应为普通 JSON 对象");if(Object.getOwnPropertySymbols(e).length)throw new a("input","任务不能包含Symbol");if(Object.getOwnPropertyNames(e).filter(s=>!(t&&s==="length")).length!==o.length)throw new a("input","任务不能包含不可枚举属性");if(t&&(o.length!==e.length||o.some(s=>s!==String(Number(s))||!Number.isSafeInteger(Number(s))||Number(s)<0||Number(s)>=e.length)))throw new a("input","任务数组不能稀疏或包含额外属性");return o.sort()}function Oe(e,t){const r=Object.getOwnPropertyDescriptor(e,t);if(["__proto__","prototype","constructor"].includes(t)||r.get||r.set)throw new a("input","任务不能包含危险键或访问器");return r.value}function S(e,t={}){const r=t.maxNodes??2e4,o=t.maxCharacters??1e6;if(!Number.isSafeInteger(r)||r<1||r>2e4||!Number.isSafeInteger(o)||o<1||o>1e6)throw new a("input","任务JSON预算无效");let n=0,s=0;const i=new Set;function d(u,b){if(++n>r||b>32)throw new a("input","任务数据超过节点或深度预算");if(typeof u=="string"){if(s+=u.length,s>o)throw new a("input","任务文本超过预算");return u}if(u===null||typeof u=="boolean"||typeof u=="number"&&Number.isFinite(u))return u;if(!u||typeof u!="object"||i.has(u))throw new a("input","任务只允许无循环的有限 JSON 值");const k=Array.isArray(u),p=Ie(u);i.add(u);const f=Object.create(null);for(const c of p){if(s+=c.length,s>o)throw new a("input","任务文本超过预算");f[c]=d(Oe(u,c),b+1)}return i.delete(u),k?Array.from({length:u.length},(c,m)=>f[String(m)]):f}const y=JSON.stringify(d(e,0));if(y.length>o)throw new a("input","任务序列化数据超过字符预算");return y}function q(e){return JSON.parse(JSON.stringify(e))}function _(e,t,r,o){if(T(t,r),e.scope!==t||e.id!==r||e.revision!==(o??0)+1||!Number.isSafeInteger(e.revision))throw new a("input","任务身份或修订不匹配");if(![e.createdAt,e.updatedAt,e.attempt].every(n=>Number.isSafeInteger(n)&&n>=0)||!["queued","running","completed","failed","cancelled"].includes(e.status))throw new a("input","任务状态无效");if(e.lease&&(!e.lease.owner||!Number.isSafeInteger(e.lease.expiresAt)))throw new a("input","任务租约无效");if(!e.request||typeof e.request.kind!="string"||!e.request.kind.trim()||e.request.kind.length>128)throw new a("input","任务类型无效");S(e.request.payload,{maxNodes:19e3,maxCharacters:75e4}),S(e)}function Te(e,t){if(e&&(e.createdAt!==t.createdAt||S(e.request)!==S(t.request)))throw new a("input","任务创建时间与请求不可变更,请使用新任务ID")}function je(e,t){return e.status==="queued"||e.status==="running"&&(e.lease?.expiresAt??0)<=t}function qe(e={}){const t={maxRecords:e.maxRecords??1e4,maxBytes:e.maxBytes??67108864,maxResultBytes:e.maxResultBytes??262144,controlReserveBytes:e.controlReserveBytes??4096,maxTombstones:e.maxTombstones??1e4,maxTombstoneBytes:e.maxTombstoneBytes??16777216};if(!Object.values(t).every(r=>Number.isSafeInteger(r)&&r>0)||t.controlReserveBytes<4096)throw new a("input","任务容量应为正整数,控制状态预留至少4096字节");return t}function E(e){return new TextEncoder().encode(S(e)).byteLength}function K(e,t){const r={scope:e.scope,id:e.id,revision:1,request:e.request,status:"queued",createdAt:e.createdAt,updatedAt:e.createdAt,attempt:0},o={...e};delete o.result;const n=e.result===void 0?0:E(e.result);if(n>t.maxResultBytes)throw new a("capacity","任务结果超过独立预算,请保存文件引用");return Math.max(E(r)+t.controlReserveBytes,E(o))+n}function L(e){return e.status!=="queued"&&e.status!=="running"}function Je(e){const t={...e,tombstoneRetentionMs:e.tombstoneRetentionMs??6048e5,limit:e.limit??100};if(![t.now,t.terminalBefore].every(r=>Number.isSafeInteger(r)&&r>=0)||t.terminalBefore>t.now)throw new a("input","终态清理时间应为不超过当前时间的非负整数");if(![t.tombstoneRetentionMs,t.limit].every(r=>Number.isSafeInteger(r)&&r>0)||!Number.isSafeInteger(t.now+t.tombstoneRetentionMs))throw new a("input","幂等保留期与清理批量应为正整数");return t}async function Be(e){const t=new TextEncoder().encode(S(e)),r=globalThis.crypto?.subtle;if(!r)return Ee(t);const o=await r.digest("SHA-256",t);return Array.from(new Uint8Array(o),n=>n.toString(16).padStart(2,"0")).join("")}async function Pe(e,t){if(!L(e))throw new a("input","只能归档终态任务");return{scope:e.scope,id:e.id,revision:e.revision,status:e.status,createdAt:e.createdAt,updatedAt:e.updatedAt,attempt:e.attempt,requestHash:await Be(e.request),expiresAt:t}}function We(e){if(!e||!["completed","failed","cancelled"].includes(e.status)||!/^[a-f0-9]{64}$/.test(e.requestHash))throw new a("input","任务幂等摘要无效");if(![e.revision,e.createdAt,e.updatedAt,e.attempt,e.expiresAt].every(t=>Number.isSafeInteger(t)&&t>=0)||e.revision<1)throw new a("input","任务幂等摘要时间或修订无效")}function O(e){return e?.code}function I(e,t){return j.createHash("sha256").update(JSON.stringify([e,t])).digest("hex")+".json"}async function B(e){try{return await h.promises.readFile(e,"utf8")}catch(t){if(O(t)==="ENOENT")return;throw t}}async function Fe(e,t){const r=await B(e);if(r===void 0)return;let o;try{o=JSON.parse(r)}catch{throw new a("conflict","任务锁尚未完整写入或已损坏,拒绝自动移除")}if(!o||!Number.isSafeInteger(o.pid)||o.pid<1)throw new a("conflict","任务锁身份无效,拒绝自动移除");try{process.kill(o.pid,0)}catch(n){if(O(n)==="ESRCH"){await h.promises.unlink(e);return}throw n}throw new a("conflict","任务目录的写入进程仍在运行")}async function Ue(e,t){if(!t)throw new a("conflict","任务目录已有写入进程;多实例请使用数据库CAS适配器");const r=e+".recovery";let o;try{o=await h.promises.open(r,"wx",384)}catch(n){throw O(n)==="EEXIST"?new a("conflict","任务目录恢复正在进行,请稍后重试"):n}try{return await o.writeFile(JSON.stringify({pid:process.pid})),await Fe(e,!0),await h.promises.open(e,"wx",384)}finally{await o.close(),await h.promises.unlink(r)}}async function De(e,t){const r=R.join(e,".writer-lock"),o=j.randomUUID();let n;try{n=await h.promises.open(r,"wx",384)}catch(s){if(O(s)!=="EEXIST")throw s;n=await Ue(r,t)}try{await n.writeFile(JSON.stringify({pid:process.pid,token:o})),await n.sync()}catch(s){throw await n.close(),await h.promises.unlink(r).catch(()=>{}),s}return{file:r,token:o,handle:n}}function Ce(e,t,r,o){if("tombstone"in r){const n=r.tombstone;if(We(n),T(n.scope,n.id),I(n.scope,n.id)!==t)throw new a("input","持久任务摘要身份不匹配");const s=E(n);e.tombstoneBytes+=s,e.tombstones.set(t,{value:n,bytes:s})}else{if(_(r,r.scope,r.id,r.revision-1),I(r.scope,r.id)!==t)throw new a("input","持久任务文件身份不匹配");const n=K(r,o);e.bytes+=n,e.records.set(t,{record:r,bytes:n})}if(e.bytes>o.maxBytes||e.records.size>o.maxRecords||e.tombstoneBytes>o.maxTombstoneBytes||e.tombstones.size>o.maxTombstones)throw new a("capacity","持久任务及控制状态预留超过目录预算")}async function _e(e,t){const r=await h.promises.readdir(e);for(const s of r.filter(i=>/^\.pending-[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(i)))await h.promises.unlink(R.join(e,s));const o=r.filter(s=>/^[a-f0-9]{64}\.json$/.test(s));if(o.length>t.maxRecords+t.maxTombstones)throw new a("capacity","持久任务数量超过目录预算");const n={records:new Map,tombstones:new Map,bytes:0,tombstoneBytes:0};for(const s of o){const i=R.join(e,s);if((await h.promises.stat(i)).size>4e6)throw new a("capacity","持久任务文件超过单文件预算");Ce(n,s,JSON.parse(await h.promises.readFile(i,"utf8")),t)}return n}async function Ke(e,t,r){const o=R.join(e,`.pending-${j.randomUUID()}`);try{const n=await h.promises.open(o,"wx",384);try{await n.writeFile(r),await n.sync()}finally{await n.close()}await h.promises.rename(o,R.join(e,t));const s=await h.promises.open(e,"r");try{await s.sync()}finally{await s.close()}}finally{await h.promises.unlink(o).catch(n=>{if(O(n)!=="ENOENT")throw n})}}async function Le(e){const t=R.resolve(e.directory),r=qe(e);await h.promises.mkdir(t,{recursive:!0,mode:448});const o=await De(t,e.recoverDeadOwner??!1);let n;try{n=await _e(t,r)}catch(p){throw await o.handle.close(),await h.promises.unlink(o.file),p}let s=!1,i=Promise.resolve();const d=()=>{if(s)throw new a("closed","持久任务存储已关闭")},y=p=>{d();const f=i.then(async()=>{if(JSON.parse(await h.promises.readFile(o.file,"utf8")).token!==o.token)throw new a("closed","持久任务存储写入锁已失效");return p()});return i=f.then(()=>{},()=>{}),f},u=async(p,f,c)=>{try{await Ke(t,p,f)}catch(m){throw await B(R.join(t,p))===f&&c(),m}c()};return{read:async(p,f)=>{d(),T(p,f),await i;const c=n.records.get(I(p,f));return c?q(c.record):void 0},readTombstone:async(p,f)=>{d(),T(p,f),await i;const c=n.tombstones.get(I(p,f));return c?q(c.value):void 0},candidates:async(p,f)=>(d(),await i,Array.from(n.records.values(),c=>c.record).filter(c=>je(c,p)).sort((c,m)=>c.createdAt-m.createdAt).slice(0,f).map(q)),compareAndSwap:async(p,f,c,m)=>{const g=JSON.parse(S(m));return _(g,p,f,c),y(async()=>{const x=I(p,f),l=n.records.get(x);if((l?.record.revision??null)!==c||n.tombstones.has(x))return!1;Te(l?.record,g);const w=K(g,r),N=n.bytes-(l?.bytes??0)+w;if(N>r.maxBytes||!l&&n.records.size>=r.maxRecords)throw new a("capacity","持久任务容量已满,请清理终态任务或扩大显式预算");return await u(x,S(g),()=>{n.records.set(x,{record:g,bytes:w}),n.bytes=N}),!0})},prune:async p=>{const f=Je(p);return y(async()=>{const c={archived:0,expired:0};for(const[m,g]of n.tombstones)g.value.expiresAt>f.now||c.expired>=f.limit||(await h.promises.unlink(R.join(t,m)),n.tombstones.delete(m),n.tombstoneBytes-=g.bytes,c.expired++);for(const[m,g]of n.records){if(!L(g.record)||g.record.updatedAt>f.terminalBefore||c.archived+c.expired>=f.limit)continue;const x=await Pe(g.record,f.now+f.tombstoneRetentionMs),l=E(x);if(n.tombstones.size>=r.maxTombstones||n.tombstoneBytes+l>r.maxTombstoneBytes)break;await u(m,S({tombstone:x}),()=>{n.tombstones.set(m,{value:x,bytes:l}),n.tombstoneBytes+=l,n.records.delete(m),n.bytes-=g.bytes}),c.archived++}if(c.expired){const m=await h.promises.open(t,"r");try{await m.sync()}finally{await m.close()}}return c})},close:async()=>{if(s)return;s=!0,await i,await o.handle.close();const p=await B(o.file);p&&JSON.parse(p).token===o.token&&await h.promises.unlink(o.file)}}}function ze(e){const t=e.filename??e.workerUrl;if(!t||e.filename&&e.workerUrl)throw new TypeError("请且仅请指定 filename 或 workerUrl");return $e(()=>{const r=new W.Worker(t,e.workerOptions);return{postMessage:o=>r.postMessage(o),terminate:()=>r.terminate(),subscribe:(o,n)=>{const s=i=>n(new Error(`报表 Worker 在响应前退出(code ${i})`));return r.on("message",o),r.on("error",n),r.on("messageerror",n),r.on("exit",s),()=>{r.off("message",o),r.off("error",n),r.off("messageerror",n),r.off("exit",s)}}}},e)}function He(e){const t=W.parentPort;if(!t)throw new Error("serveNodeReportWorker 只能在 worker_threads 中调用");const r=o=>{he(o)&&ge(e,o,n=>t.postMessage({protocol:M,id:o.id,type:"event",event:n})).then(n=>t.postMessage(n,we(n)))};return t.on("message",r),()=>t.off("message",r)}function Ze(e){return j.createHash("sha256").update(e).digest("hex")}exports.ReportWorkerError=J;exports.createNodeReportExecutor=ze;exports.openFileReportJobStore=Le;exports.reportArtifactSha256=Ze;exports.serveNodeReportWorker=He;
|