@agile-team/mach-report 2.13.0 → 2.15.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 +20 -7
- package/THIRD_PARTY_NOTICES.md +3 -1
- package/dist/ExcelBindingWizard-BKH1nGNS.js +1485 -0
- package/dist/ExcelBindingWizard-Bs43BGNp.cjs +1 -0
- package/dist/ParamEditor-Da4akw6V.cjs +1 -0
- package/dist/ParamEditor-DoAhzJsm.js +594 -0
- package/dist/{ReportBatchPanel-CW2HV9I8.js → ReportBatchPanel-BMf6boMA.js} +39 -39
- package/dist/ReportBatchPanel-wP9m9Pj1.cjs +1 -0
- package/dist/ReportPreview-ChV19HBp.js +4619 -0
- package/dist/ReportPreview-DbLvvOUT.cjs +6 -0
- package/dist/{ReportTemplateLibrary-BZB-XWjj.js → ReportTemplateLibrary-C9wutIiT.js} +1 -1
- package/dist/ReportTemplateLibrary-Sxr3eD0J.cjs +1 -0
- package/dist/RuleEditor-C_Clasvd.js +2037 -0
- package/dist/RuleEditor-XhGHK8DE.cjs +1 -0
- package/dist/TemplateOutlinePanel-D6Bkny59.js +96 -0
- package/dist/TemplateOutlinePanel-JTSR53vJ.cjs +1 -0
- package/dist/TemplateReusePanel-Kx35S0Ql.cjs +1 -0
- package/dist/TemplateReusePanel-rVuK1kTz.js +388 -0
- package/dist/TemplateReviewPanel-B0ar9_zf.js +592 -0
- package/dist/TemplateReviewPanel-Dn6X9UmY.cjs +1 -0
- package/dist/analytics.cjs +1 -1
- package/dist/analytics.d.cts +3 -1
- package/dist/analytics.d.ts +3 -1
- package/dist/analytics.js +154 -60
- package/dist/artifact-integrity.json +135 -0
- package/dist/assets-B9ImAi6_.cjs +1 -0
- package/dist/assets-DEaz4qsp.js +124 -0
- package/dist/batch-BaP6pWDE.cjs +1 -0
- package/dist/batch-BfZHN1do.js +220 -0
- package/dist/batch-CGyt-b2W.js +273 -0
- package/dist/batch-CLpELXBl.cjs +1 -0
- package/dist/capabilities-CAh2Nrue.cjs +1 -0
- package/dist/capabilities-DskCHs3V.js +69 -0
- package/dist/codes.d.cts +2 -0
- package/dist/codes.d.ts +2 -0
- package/dist/{computed-Bvk0W15F.js → computed-C-4C2S5h.js} +3 -3
- package/dist/config-BVsJXSqS.js +842 -0
- package/dist/config-D10us76d.cjs +1 -0
- package/dist/data-explanation-B8MZRYVS.js +16 -0
- package/dist/data-explanation-DE55G30w.cjs +1 -0
- package/dist/designer-2bDlcNXQ.js +5136 -0
- package/dist/designer-BT7XCdbW.cjs +2 -0
- package/dist/designer.cjs +1 -2
- package/dist/designer.d.cts +432 -17
- package/dist/designer.d.ts +432 -17
- package/dist/designer.js +21 -4312
- package/dist/drill-ByJviLXS.js +145 -0
- package/dist/drill-DYTxuL3A.cjs +1 -0
- package/dist/font-loader-B_UkxpzC.cjs +1 -0
- package/dist/font-loader-Q3bQjmrI.js +297 -0
- package/dist/index.cjs +8 -8
- package/dist/index.d.cts +239 -5
- package/dist/index.d.ts +239 -5
- package/dist/index.js +939 -893
- package/dist/json-snapshot-DFb2eWkf.js +1416 -0
- package/dist/json-snapshot-WWSGlaHG.cjs +2 -0
- package/dist/licenses/_bwip-js_generic-4.11.4.txt +24 -0
- package/dist/licenses/_fast-csv_format-4.3.5.txt +22 -0
- package/dist/licenses/_fast-csv_parse-4.3.6.txt +22 -0
- package/dist/licenses/_pdf-lib_fontkit-1.1.1.txt +326 -0
- package/dist/licenses/_pdf-lib_standard-fonts-1.0.0.txt +22 -0
- package/dist/licenses/_pdf-lib_upng-1.0.1.txt +22 -0
- package/dist/licenses/_types_node-14.18.63.txt +22 -0
- package/dist/licenses/_types_pako-2.0.3.txt +22 -0
- package/dist/licenses/_types_pegjs-0.10.6.txt +22 -0
- package/dist/licenses/archiver-5.3.2.txt +23 -0
- package/dist/licenses/archiver-utils-2.1.0.txt +23 -0
- package/dist/licenses/archiver-utils-3.0.4.txt +23 -0
- package/dist/licenses/async-3.2.6.txt +20 -0
- package/dist/licenses/balanced-match-1.0.2.txt +22 -0
- package/dist/licenses/base64-js-1.5.1.txt +22 -0
- package/dist/licenses/big-integer-1.6.52.txt +25 -0
- package/dist/licenses/binary-0.3.0.txt +178 -0
- package/dist/licenses/bl-4.1.0.txt +14 -0
- package/dist/licenses/bluebird-3.4.7.txt +22 -0
- package/dist/licenses/brace-expansion-1.1.21.txt +22 -0
- package/dist/licenses/brace-expansion-2.1.7.txt +22 -0
- package/dist/licenses/buffer-5.7.1.txt +22 -0
- package/dist/licenses/buffer-crc32-0.2.13.txt +20 -0
- package/dist/licenses/buffer-indexof-polyfill-1.0.2.txt +23 -0
- package/dist/licenses/buffers-0.1.1.txt +140 -0
- package/dist/licenses/chainsaw-0.1.0.txt +184 -0
- package/dist/licenses/compress-commons-4.1.2.txt +23 -0
- package/dist/licenses/concat-map-0.0.1.txt +19 -0
- package/dist/licenses/core-util-is-1.0.3.txt +20 -0
- package/dist/licenses/crc-32-1.2.2.txt +202 -0
- package/dist/licenses/crc32-stream-4.0.3.txt +23 -0
- package/dist/licenses/dayjs-1.11.23.txt +22 -0
- package/dist/licenses/duplexer2-0.1.4.txt +27 -0
- package/dist/licenses/end-of-stream-1.4.5.txt +22 -0
- package/dist/licenses/exceljs-4.4.0.txt +23 -0
- package/dist/licenses/fast-csv-4.3.6.txt +22 -0
- package/dist/licenses/fast-png-6.4.0.txt +22 -0
- package/dist/licenses/fs-constants-1.0.0.txt +22 -0
- package/dist/licenses/fs.realpath-1.0.0.txt +44 -0
- package/dist/licenses/fstream-1.0.12.txt +16 -0
- package/dist/licenses/glob-7.2.3.txt +22 -0
- package/dist/licenses/graceful-fs-4.2.11.txt +16 -0
- package/dist/licenses/ieee754-1.2.1.txt +12 -0
- package/dist/licenses/immediate-3.0.6.txt +21 -0
- package/dist/licenses/inflight-1.0.6.txt +16 -0
- package/dist/licenses/inherits-2.0.4.txt +17 -0
- package/dist/licenses/iobuffer-5.4.0.txt +23 -0
- package/dist/licenses/isarray-1.0.0.txt +61 -0
- package/dist/licenses/jszip-3.10.2.txt +652 -0
- package/dist/licenses/lazystream-1.0.1.txt +24 -0
- package/dist/licenses/lie-3.3.0.txt +8 -0
- package/dist/licenses/listenercount-1.0.1.txt +6 -0
- package/dist/licenses/lodash.defaults-4.2.0.txt +48 -0
- package/dist/licenses/lodash.difference-4.5.0.txt +48 -0
- package/dist/licenses/lodash.escaperegexp-4.1.2.txt +48 -0
- package/dist/licenses/lodash.flatten-4.4.0.txt +48 -0
- package/dist/licenses/lodash.groupby-4.6.0.txt +48 -0
- package/dist/licenses/lodash.isboolean-3.0.3.txt +23 -0
- package/dist/licenses/lodash.isequal-4.5.0.txt +48 -0
- package/dist/licenses/lodash.isfunction-3.0.9.txt +48 -0
- package/dist/licenses/lodash.isnil-4.0.0.txt +23 -0
- package/dist/licenses/lodash.isplainobject-4.0.6.txt +48 -0
- package/dist/licenses/lodash.isundefined-3.0.1.txt +23 -0
- package/dist/licenses/lodash.union-4.6.0.txt +48 -0
- package/dist/licenses/lodash.uniq-4.5.0.txt +48 -0
- package/dist/licenses/minimatch-3.1.5.txt +16 -0
- package/dist/licenses/minimatch-5.1.9.txt +16 -0
- package/dist/licenses/minimist-1.2.8.txt +19 -0
- package/dist/licenses/mkdirp-0.5.6.txt +22 -0
- package/dist/licenses/node-sql-parser-5.4.0.txt +202 -0
- package/dist/licenses/normalize-path-3.0.0.txt +22 -0
- package/dist/licenses/once-1.4.0.txt +16 -0
- package/dist/licenses/pako-1.0.11.txt +22 -0
- package/dist/licenses/pako-2.2.0.txt +22 -0
- package/dist/licenses/path-is-absolute-1.0.1.txt +22 -0
- package/dist/licenses/pdf-lib-1.17.1.txt +22 -0
- package/dist/licenses/process-nextick-args-2.0.1.txt +20 -0
- package/dist/licenses/readable-stream-2.3.8.txt +48 -0
- package/dist/licenses/readable-stream-3.6.2.txt +48 -0
- package/dist/licenses/readdir-glob-1.1.3.txt +202 -0
- package/dist/licenses/rimraf-2.7.1.txt +16 -0
- package/dist/licenses/safe-buffer-5.1.2.txt +22 -0
- package/dist/licenses/safe-buffer-5.2.1.txt +22 -0
- package/dist/licenses/saxes-5.0.1.txt +397 -0
- package/dist/licenses/setimmediate-1.0.5.txt +21 -0
- package/dist/licenses/string_decoder-1.1.1.txt +49 -0
- package/dist/licenses/string_decoder-1.3.0.txt +49 -0
- package/dist/licenses/tar-stream-2.2.0.txt +22 -0
- package/dist/licenses/tmp-0.2.7.txt +22 -0
- package/dist/licenses/traverse-0.3.9.txt +25 -0
- package/dist/licenses/tslib-1.14.1.txt +13 -0
- package/dist/licenses/unzipper-0.10.14.txt +26 -0
- package/dist/licenses/util-deprecate-1.0.2.txt +25 -0
- package/dist/licenses/uuid-11.1.1.txt +10 -0
- package/dist/licenses/wrappy-1.0.2.txt +16 -0
- package/dist/licenses/xmlchars-2.2.0.txt +19 -0
- package/dist/licenses/zip-stream-4.1.1.txt +23 -0
- package/dist/matrix-CGRGkn5s.js +112 -0
- package/dist/matrix-gEO7ZM_u.cjs +1 -0
- package/dist/media-B7vnpD8k.cjs +1 -0
- package/dist/media-Y90dHK9z.js +70 -0
- package/dist/param-validation-C3HlcLLO.cjs +1 -0
- package/dist/param-validation-Do7Eg8Zv.js +181 -0
- package/dist/pdf-BwNyeGpt.js +36352 -0
- package/dist/pdf-CvvrjPQg.cjs +103 -0
- package/dist/pdf.cjs +1 -101
- package/dist/pdf.d.cts +18 -3
- package/dist/pdf.d.ts +18 -3
- package/dist/pdf.js +9 -36579
- package/dist/plugin-Ca_XZG3l.js +22 -0
- package/dist/{plugin-DzS6pxTA.cjs → plugin-DHO7X8z2.cjs} +1 -1
- package/dist/prepared-CFy9B75C.cjs +1 -0
- package/dist/prepared-ajM-H-9B.js +69 -0
- package/dist/progress-B0ctFpKf.cjs +1 -0
- package/dist/progress-D-OTpEav.js +52 -0
- package/dist/{record-bindings-D-5jQlTj.js → record-bindings-Do_b3h4V.js} +1 -1
- package/dist/{region-binding-workflow-CcUq8W2Q.js → region-binding-workflow-BMhK_TjP.js} +1 -1
- package/dist/{region-binding-workflow-BzfbxRiR.cjs → region-binding-workflow-DIYJdCUr.cjs} +1 -1
- package/dist/{report-params-B44imUd4.js → report-params-B1RzkhJj.js} +1 -1
- package/dist/{report-params-SJfhKgaX.cjs → report-params-WDGrA4oP.cjs} +1 -1
- package/dist/sbom.cdx.json +3982 -0
- package/dist/server/node.d.cts +66 -12
- package/dist/server/node.d.ts +66 -12
- package/dist/server-node.cjs +1 -1
- package/dist/server-node.js +405 -381
- package/dist/server.cjs +1 -1
- package/dist/server.d.cts +878 -15
- package/dist/server.d.ts +878 -15
- package/dist/server.js +1034 -534
- package/dist/sha256-ArEYjaTI.cjs +1 -0
- package/dist/sha256-DPEuJ3nh.js +155 -0
- package/dist/style.css +1 -1
- package/dist/template-bindings-C2SpvsMU.js +58 -0
- package/dist/template-bindings-CEtWyiLX.cjs +1 -0
- package/dist/template-catalog-FJE_c9Qe.cjs +1 -0
- package/dist/template-catalog-j2B1MJlL.js +414 -0
- package/dist/template-fragments-BGbQLGlV.js +187 -0
- package/dist/template-fragments-DcKeiylI.cjs +1 -0
- package/dist/template-outline-BwRV_eRo.cjs +1 -0
- package/dist/template-outline-cnWfT_LK.js +88 -0
- package/dist/{template-registry-BjE1VS6g.js → template-registry-BtaKPELV.js} +364 -201
- package/dist/template-registry-Co1zPq5e.cjs +1 -0
- package/dist/textwrap-CWHyzkBH.cjs +4 -0
- package/dist/textwrap-DE1kgcJB.js +110 -0
- package/dist/{tree-CqcQ99NM.js → tree-CjVZLRw7.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/vue/async.d.cts +190 -15
- package/dist/vue/async.d.ts +190 -15
- package/dist/vue/index.d.cts +274 -24
- package/dist/vue/index.d.ts +274 -24
- package/dist/vue-async.cjs +1 -1
- package/dist/vue-async.js +5 -5
- package/dist/vue.cjs +1 -1
- package/dist/vue.js +90 -81
- package/dist/{workbook-session-DNa2RHNG.cjs → workbook-session-Bjv1YCRK.cjs} +18 -18
- package/dist/{workbook-session-BPb3TMnT.js → workbook-session-BvToI-Fd.js} +5440 -5288
- package/dist/worker.cjs +1 -1
- package/dist/worker.d.cts +66 -12
- package/dist/worker.d.ts +66 -12
- package/dist/worker.js +61 -56
- package/dist/xlsx-node.cjs +34 -34
- package/dist/xlsx-node.js +878 -870
- package/dist/xlsx.cjs +3 -4
- package/dist/xlsx.d.cts +22 -10
- package/dist/xlsx.d.ts +22 -10
- package/dist/xlsx.js +261 -253
- package/package.json +2 -2
- package/dist/ExcelBindingWizard-CeAf4QSE.js +0 -1465
- package/dist/ExcelBindingWizard-y0mT-AHR.cjs +0 -1
- package/dist/ParamEditor-BLaE5q5W.js +0 -522
- package/dist/ParamEditor-MBBC7lUE.cjs +0 -1
- package/dist/ReportBatchPanel-Fp1ePFag.cjs +0 -1
- package/dist/ReportPreview-BN6fk7Wz.cjs +0 -6
- package/dist/ReportPreview-D2Jkyh1U.js +0 -4243
- 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/assets-C2U-e-Sz.cjs +0 -4
- package/dist/assets-Q0wUwNrV.js +0 -217
- package/dist/batch-Bt3Fd27Z.cjs +0 -1
- package/dist/batch-mRqhhhjt.js +0 -364
- package/dist/capabilities-CK_7hizc.js +0 -63
- package/dist/capabilities-CsZ-pNHR.cjs +0 -1
- package/dist/config-Bb7RiIO5.cjs +0 -1
- package/dist/config-XVwG87IA.js +0 -529
- package/dist/matrix-DVyWiYsd.cjs +0 -1
- package/dist/matrix-yZsGnldA.js +0 -227
- package/dist/page-window-index-CIuT4BAv.js +0 -43
- package/dist/page-window-index-DEjnM6IB.cjs +0 -1
- package/dist/param-validation-BlHHXs6u.js +0 -153
- package/dist/param-validation-DCK039V1.cjs +0 -1
- package/dist/plugin-D4wizDXB.js +0 -22
- package/dist/progress-7OSZbFok.js +0 -39
- package/dist/progress-BnLiS5eH.cjs +0 -1
- package/dist/task-events-DQ276fn2.cjs +0 -1
- package/dist/task-events-Dpsvf_t2.js +0 -47
- package/dist/template-registry-D3SjENi6.cjs +0 -1
- package/dist/template-review-DGwWOoCv.cjs +0 -2
- package/dist/template-review-PgEe_Wr9.js +0 -1742
- package/dist/validate-BJ5HIWY8.cjs +0 -1
- package/dist/validate-DbgEM1Hh.js +0 -163
package/dist/server/node.d.cts
CHANGED
|
@@ -194,6 +194,13 @@ declare interface PreparedReport {
|
|
|
194
194
|
revision?: string;
|
|
195
195
|
sourceToken?: string;
|
|
196
196
|
}>;
|
|
197
|
+
/** Ordered occurrences; legacy revisions remains last-value-by-ID for compatibility. */
|
|
198
|
+
sources?: ReportRuntimeSource[];
|
|
199
|
+
/** Captured metrics identity; absence on old saved instances remains supported with diagnostics. */
|
|
200
|
+
layout?: {
|
|
201
|
+
textMetrics: "heuristic" | "provided" | "font-bytes";
|
|
202
|
+
fontFingerprint?: string;
|
|
203
|
+
};
|
|
197
204
|
}
|
|
198
205
|
|
|
199
206
|
declare interface RenderPlan {
|
|
@@ -208,6 +215,8 @@ export declare function reportArtifactSha256(bytes: Uint8Array): string;
|
|
|
208
215
|
|
|
209
216
|
/** 可持久化的业务身份与计划坐标独立;权限及并发校验仍由业务服务器执行。 */
|
|
210
217
|
declare interface ReportCellSource {
|
|
218
|
+
/** Source identity across report occurrences; sharing must be explicitly declared. */
|
|
219
|
+
sourceScope?: string;
|
|
211
220
|
datasetId: string;
|
|
212
221
|
rowKey: string | number;
|
|
213
222
|
field: string;
|
|
@@ -215,6 +224,16 @@ declare interface ReportCellSource {
|
|
|
215
224
|
sourceToken?: string;
|
|
216
225
|
}
|
|
217
226
|
|
|
227
|
+
declare interface ReportDataTarget {
|
|
228
|
+
datasetId: string;
|
|
229
|
+
field: string;
|
|
230
|
+
rowKey?: string | number;
|
|
231
|
+
/** Use table identity when the same dataset appears in several tables. */
|
|
232
|
+
tableId?: string;
|
|
233
|
+
/** Assigned by the source/runtime when several reports share dataset names. */
|
|
234
|
+
reportScope?: string;
|
|
235
|
+
}
|
|
236
|
+
|
|
218
237
|
declare interface ReportDescription {
|
|
219
238
|
id: string;
|
|
220
239
|
params: ReportParamDef[];
|
|
@@ -233,6 +252,9 @@ declare interface ReportDiagnostic {
|
|
|
233
252
|
message: string;
|
|
234
253
|
path?: string;
|
|
235
254
|
severity: "warning" | "error" | "info";
|
|
255
|
+
/** Optional explanation supplied by the business source, not inferred from blank cells. */
|
|
256
|
+
valueState?: ReportValueState;
|
|
257
|
+
target?: ReportDataTarget;
|
|
236
258
|
}
|
|
237
259
|
|
|
238
260
|
declare type ReportJobJson = null | boolean | number | string | ReportJobJson[] | {
|
|
@@ -328,6 +350,10 @@ declare interface ReportParamDef {
|
|
|
328
350
|
label: string;
|
|
329
351
|
value: string;
|
|
330
352
|
}>;
|
|
353
|
+
/** Opaque host-resolved source key. No URL, credentials or executable code is stored. */
|
|
354
|
+
optionsSource?: string;
|
|
355
|
+
/** Select dependencies must be declared parameters; changing a parent clears descendants. */
|
|
356
|
+
dependsOn?: string[];
|
|
331
357
|
defaultValue?: string;
|
|
332
358
|
required?: boolean;
|
|
333
359
|
placeholder?: string;
|
|
@@ -345,7 +371,7 @@ declare interface ReportParamIssue {
|
|
|
345
371
|
message: string;
|
|
346
372
|
}
|
|
347
373
|
|
|
348
|
-
declare type ReportParamIssueCode = "definition" | "required" | "type" | "option" | "minimum" | "maximum" | "minLength" | "maxLength";
|
|
374
|
+
declare type ReportParamIssueCode = "definition" | "required" | "type" | "option" | "dependency" | "minimum" | "maximum" | "minLength" | "maxLength";
|
|
349
375
|
|
|
350
376
|
declare interface ReportParamValidation {
|
|
351
377
|
ok: boolean;
|
|
@@ -356,15 +382,30 @@ declare interface ReportParamValidation {
|
|
|
356
382
|
issues: ReportParamIssue[];
|
|
357
383
|
}
|
|
358
384
|
|
|
385
|
+
/** Licensed local font bytes; never downloaded implicitly by the runtime. */
|
|
386
|
+
declare interface ReportPdfFontOptions {
|
|
387
|
+
customFontBytes?: Uint8Array | ArrayBuffer;
|
|
388
|
+
customFontName?: string;
|
|
389
|
+
customFontFaces?: {
|
|
390
|
+
regular: Uint8Array | ArrayBuffer;
|
|
391
|
+
bold?: Uint8Array | ArrayBuffer;
|
|
392
|
+
italic?: Uint8Array | ArrayBuffer;
|
|
393
|
+
boldItalic?: Uint8Array | ArrayBuffer;
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
|
|
359
397
|
declare interface ReportRuntime {
|
|
360
398
|
describe(reportIds?: string[]): ReportDescription[];
|
|
361
399
|
validate(input: Omit<ReportRuntimeInput, "signal">): ReportParamValidation;
|
|
362
400
|
prepare(input: ReportRuntimeInput): Promise<PreparedReport>;
|
|
363
401
|
export(input: ReportRuntimeExportInput): Promise<ReportRuntimeExportResult>;
|
|
402
|
+
exportPrepared(input: ReportRuntimePreparedExportInput): Promise<ReportRuntimeExportResult>;
|
|
364
403
|
}
|
|
365
404
|
|
|
366
405
|
/** 可用 worker_threads/进程/RPC 实现;接收可序列化请求,signal 由桥接层映射为取消消息。 */
|
|
367
406
|
declare interface ReportRuntimeExecutor {
|
|
407
|
+
/** Old custom executors may omit this; the runtime explicitly rejects unsupported prepared output. */
|
|
408
|
+
exportPrepared?(input: Omit<ReportRuntimePreparedExportInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<ReportRuntimeExportResult>;
|
|
368
409
|
prepare(input: Omit<ReportRuntimeInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<PreparedReport>;
|
|
369
410
|
export(input: Omit<ReportRuntimeExportInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<ReportRuntimeExportResult>;
|
|
370
411
|
}
|
|
@@ -373,17 +414,6 @@ declare interface ReportRuntimeExportInput extends ReportRuntimeInput {
|
|
|
373
414
|
format: "pdf" | "xlsx";
|
|
374
415
|
/** strict 在编码前拒绝已识别的输出降级;默认保留诊断并继续。 */
|
|
375
416
|
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
417
|
xlsx?: {
|
|
388
418
|
sheetMode?: "auto" | "pages" | "continuous";
|
|
389
419
|
valueMode?: "text" | "raw";
|
|
@@ -401,6 +431,27 @@ declare interface ReportRuntimeInput extends ReportTaskMonitoring {
|
|
|
401
431
|
reportIds: string[];
|
|
402
432
|
params?: Record<string, string>;
|
|
403
433
|
signal?: AbortSignal;
|
|
434
|
+
/** Prepare using the same licensed font bytes later supplied to PDF output. */
|
|
435
|
+
pdf?: ReportPdfFontOptions;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/** Encode an existing plan without querying providers or repaginating. */
|
|
439
|
+
declare interface ReportRuntimePreparedExportInput extends ReportTaskMonitoring {
|
|
440
|
+
prepared: PreparedReport;
|
|
441
|
+
format: ReportRuntimeExportInput["format"];
|
|
442
|
+
fidelity?: ReportRuntimeExportInput["fidelity"];
|
|
443
|
+
pdf?: ReportPdfFontOptions;
|
|
444
|
+
xlsx?: ReportRuntimeExportInput["xlsx"];
|
|
445
|
+
signal?: AbortSignal;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/** One query occurrence; repeated report IDs retain independent provenance. */
|
|
449
|
+
declare interface ReportRuntimeSource {
|
|
450
|
+
reportId: string;
|
|
451
|
+
reportIndex: number;
|
|
452
|
+
reportScope: string;
|
|
453
|
+
revision?: string;
|
|
454
|
+
sourceToken?: string;
|
|
404
455
|
}
|
|
405
456
|
|
|
406
457
|
declare interface ReportRuntimeStats {
|
|
@@ -430,6 +481,9 @@ declare interface ReportTaskMonitoring {
|
|
|
430
481
|
|
|
431
482
|
declare type ReportTaskObserver = (event: ReportTaskEvent) => void;
|
|
432
483
|
|
|
484
|
+
/** Optional business explanations never replace raw data or schema validation. */
|
|
485
|
+
declare type ReportValueState = "missing-source" | "not-applicable" | "not-calculable";
|
|
486
|
+
|
|
433
487
|
export declare class ReportWorkerError extends Error {
|
|
434
488
|
readonly code?: string;
|
|
435
489
|
readonly path?: string;
|
package/dist/server/node.d.ts
CHANGED
|
@@ -194,6 +194,13 @@ declare interface PreparedReport {
|
|
|
194
194
|
revision?: string;
|
|
195
195
|
sourceToken?: string;
|
|
196
196
|
}>;
|
|
197
|
+
/** Ordered occurrences; legacy revisions remains last-value-by-ID for compatibility. */
|
|
198
|
+
sources?: ReportRuntimeSource[];
|
|
199
|
+
/** Captured metrics identity; absence on old saved instances remains supported with diagnostics. */
|
|
200
|
+
layout?: {
|
|
201
|
+
textMetrics: "heuristic" | "provided" | "font-bytes";
|
|
202
|
+
fontFingerprint?: string;
|
|
203
|
+
};
|
|
197
204
|
}
|
|
198
205
|
|
|
199
206
|
declare interface RenderPlan {
|
|
@@ -208,6 +215,8 @@ export declare function reportArtifactSha256(bytes: Uint8Array): string;
|
|
|
208
215
|
|
|
209
216
|
/** 可持久化的业务身份与计划坐标独立;权限及并发校验仍由业务服务器执行。 */
|
|
210
217
|
declare interface ReportCellSource {
|
|
218
|
+
/** Source identity across report occurrences; sharing must be explicitly declared. */
|
|
219
|
+
sourceScope?: string;
|
|
211
220
|
datasetId: string;
|
|
212
221
|
rowKey: string | number;
|
|
213
222
|
field: string;
|
|
@@ -215,6 +224,16 @@ declare interface ReportCellSource {
|
|
|
215
224
|
sourceToken?: string;
|
|
216
225
|
}
|
|
217
226
|
|
|
227
|
+
declare interface ReportDataTarget {
|
|
228
|
+
datasetId: string;
|
|
229
|
+
field: string;
|
|
230
|
+
rowKey?: string | number;
|
|
231
|
+
/** Use table identity when the same dataset appears in several tables. */
|
|
232
|
+
tableId?: string;
|
|
233
|
+
/** Assigned by the source/runtime when several reports share dataset names. */
|
|
234
|
+
reportScope?: string;
|
|
235
|
+
}
|
|
236
|
+
|
|
218
237
|
declare interface ReportDescription {
|
|
219
238
|
id: string;
|
|
220
239
|
params: ReportParamDef[];
|
|
@@ -233,6 +252,9 @@ declare interface ReportDiagnostic {
|
|
|
233
252
|
message: string;
|
|
234
253
|
path?: string;
|
|
235
254
|
severity: "warning" | "error" | "info";
|
|
255
|
+
/** Optional explanation supplied by the business source, not inferred from blank cells. */
|
|
256
|
+
valueState?: ReportValueState;
|
|
257
|
+
target?: ReportDataTarget;
|
|
236
258
|
}
|
|
237
259
|
|
|
238
260
|
declare type ReportJobJson = null | boolean | number | string | ReportJobJson[] | {
|
|
@@ -328,6 +350,10 @@ declare interface ReportParamDef {
|
|
|
328
350
|
label: string;
|
|
329
351
|
value: string;
|
|
330
352
|
}>;
|
|
353
|
+
/** Opaque host-resolved source key. No URL, credentials or executable code is stored. */
|
|
354
|
+
optionsSource?: string;
|
|
355
|
+
/** Select dependencies must be declared parameters; changing a parent clears descendants. */
|
|
356
|
+
dependsOn?: string[];
|
|
331
357
|
defaultValue?: string;
|
|
332
358
|
required?: boolean;
|
|
333
359
|
placeholder?: string;
|
|
@@ -345,7 +371,7 @@ declare interface ReportParamIssue {
|
|
|
345
371
|
message: string;
|
|
346
372
|
}
|
|
347
373
|
|
|
348
|
-
declare type ReportParamIssueCode = "definition" | "required" | "type" | "option" | "minimum" | "maximum" | "minLength" | "maxLength";
|
|
374
|
+
declare type ReportParamIssueCode = "definition" | "required" | "type" | "option" | "dependency" | "minimum" | "maximum" | "minLength" | "maxLength";
|
|
349
375
|
|
|
350
376
|
declare interface ReportParamValidation {
|
|
351
377
|
ok: boolean;
|
|
@@ -356,15 +382,30 @@ declare interface ReportParamValidation {
|
|
|
356
382
|
issues: ReportParamIssue[];
|
|
357
383
|
}
|
|
358
384
|
|
|
385
|
+
/** Licensed local font bytes; never downloaded implicitly by the runtime. */
|
|
386
|
+
declare interface ReportPdfFontOptions {
|
|
387
|
+
customFontBytes?: Uint8Array | ArrayBuffer;
|
|
388
|
+
customFontName?: string;
|
|
389
|
+
customFontFaces?: {
|
|
390
|
+
regular: Uint8Array | ArrayBuffer;
|
|
391
|
+
bold?: Uint8Array | ArrayBuffer;
|
|
392
|
+
italic?: Uint8Array | ArrayBuffer;
|
|
393
|
+
boldItalic?: Uint8Array | ArrayBuffer;
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
|
|
359
397
|
declare interface ReportRuntime {
|
|
360
398
|
describe(reportIds?: string[]): ReportDescription[];
|
|
361
399
|
validate(input: Omit<ReportRuntimeInput, "signal">): ReportParamValidation;
|
|
362
400
|
prepare(input: ReportRuntimeInput): Promise<PreparedReport>;
|
|
363
401
|
export(input: ReportRuntimeExportInput): Promise<ReportRuntimeExportResult>;
|
|
402
|
+
exportPrepared(input: ReportRuntimePreparedExportInput): Promise<ReportRuntimeExportResult>;
|
|
364
403
|
}
|
|
365
404
|
|
|
366
405
|
/** 可用 worker_threads/进程/RPC 实现;接收可序列化请求,signal 由桥接层映射为取消消息。 */
|
|
367
406
|
declare interface ReportRuntimeExecutor {
|
|
407
|
+
/** Old custom executors may omit this; the runtime explicitly rejects unsupported prepared output. */
|
|
408
|
+
exportPrepared?(input: Omit<ReportRuntimePreparedExportInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<ReportRuntimeExportResult>;
|
|
368
409
|
prepare(input: Omit<ReportRuntimeInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<PreparedReport>;
|
|
369
410
|
export(input: Omit<ReportRuntimeExportInput, "signal" | "onEvent">, signal?: AbortSignal, onEvent?: ReportTaskObserver): Promise<ReportRuntimeExportResult>;
|
|
370
411
|
}
|
|
@@ -373,17 +414,6 @@ declare interface ReportRuntimeExportInput extends ReportRuntimeInput {
|
|
|
373
414
|
format: "pdf" | "xlsx";
|
|
374
415
|
/** strict 在编码前拒绝已识别的输出降级;默认保留诊断并继续。 */
|
|
375
416
|
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
417
|
xlsx?: {
|
|
388
418
|
sheetMode?: "auto" | "pages" | "continuous";
|
|
389
419
|
valueMode?: "text" | "raw";
|
|
@@ -401,6 +431,27 @@ declare interface ReportRuntimeInput extends ReportTaskMonitoring {
|
|
|
401
431
|
reportIds: string[];
|
|
402
432
|
params?: Record<string, string>;
|
|
403
433
|
signal?: AbortSignal;
|
|
434
|
+
/** Prepare using the same licensed font bytes later supplied to PDF output. */
|
|
435
|
+
pdf?: ReportPdfFontOptions;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/** Encode an existing plan without querying providers or repaginating. */
|
|
439
|
+
declare interface ReportRuntimePreparedExportInput extends ReportTaskMonitoring {
|
|
440
|
+
prepared: PreparedReport;
|
|
441
|
+
format: ReportRuntimeExportInput["format"];
|
|
442
|
+
fidelity?: ReportRuntimeExportInput["fidelity"];
|
|
443
|
+
pdf?: ReportPdfFontOptions;
|
|
444
|
+
xlsx?: ReportRuntimeExportInput["xlsx"];
|
|
445
|
+
signal?: AbortSignal;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/** One query occurrence; repeated report IDs retain independent provenance. */
|
|
449
|
+
declare interface ReportRuntimeSource {
|
|
450
|
+
reportId: string;
|
|
451
|
+
reportIndex: number;
|
|
452
|
+
reportScope: string;
|
|
453
|
+
revision?: string;
|
|
454
|
+
sourceToken?: string;
|
|
404
455
|
}
|
|
405
456
|
|
|
406
457
|
declare interface ReportRuntimeStats {
|
|
@@ -430,6 +481,9 @@ declare interface ReportTaskMonitoring {
|
|
|
430
481
|
|
|
431
482
|
declare type ReportTaskObserver = (event: ReportTaskEvent) => void;
|
|
432
483
|
|
|
484
|
+
/** Optional business explanations never replace raw data or schema validation. */
|
|
485
|
+
declare type ReportValueState = "missing-source" | "not-applicable" | "not-calculable";
|
|
486
|
+
|
|
433
487
|
export declare class ReportWorkerError extends Error {
|
|
434
488
|
readonly code?: string;
|
|
435
489
|
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"),v=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)||t.reportScope!==void 0&&(typeof t.reportScope!="string"||!t.reportScope.trim()||t.reportScope.length>4096)?!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!==void 0&&(typeof e!="string"||!e.trim()||e.length>4096)&&r.push({path:t,message:"来源范围应为不超过 4096 字符的非空字符串"})}function G(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 X(e,t,r){G(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;V(n.sourceScope,`${t}.sourceScope`,r);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 Y(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 ee(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 te(e,t){if(typeof e!="object"||e===null||Array.isArray(e))return[{path:"",message:"code must be an object."}];const r=e,o=[...Y(r),...ee(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 re=new Set(["text","image","barcode","qrcode","chart","line","rect","ellipse"]);function A(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function ne(e,t,r,o){const n=e[t];(typeof n!="number"||!Number.isFinite(n))&&o.push({path:`${r}.${t}`,message:`应为有限数字,实际 ${JSON.stringify(n)}`})}function oe(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 se(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}X(d,u,r),Array.isArray(d.children)&&d.children.forEach((b,$)=>{U(b,`${t}.grid.cells.${i}.${y}.children.${$}`,r,o)})})})}}function ie(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 字符串"}):re.has(n)||o.push({path:`${t}.kind`,message:`未知组件类型 ${JSON.stringify(n)},将以兜底方式渲染`});for(const s of["leftMm","topMm","widthMm","heightMm"])ne(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:"组件尺寸不能为负数"});oe(e.table,t,r),ae(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"}),se(e.grid,t,r,o),ie(e.richParagraphs,t,r)}function ae(e,t,r,o){if(e!==void 0)for(const n of te(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 ce(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 fe(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)=>ce(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 ue=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]),S=(e,t)=>e>>>t|e<<32-t;function pe(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(s,7)^S(s,18)^s>>>3,y=S(i,17)^S(i,19)^i>>>10;r[n]=r[n-16]+d+r[n-7]+y}}function de(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 $=S(i,6)^S(i,11)^S(i,25),p=i&d^~i&y,f=u+$+p+ue[b]+t[b]>>>0,c=S(r,2)^S(r,13)^S(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 me(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 ye=()=>new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),le=e=>Array.from(e,t=>t.toString(16).padStart(8,"0")).join("");async function he(e){const t=me(e),r=ye(),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)),pe(t,n,o),de(r,o);return le(r)}function ge(e){if(e===void 0)return!0;if(!Array.isArray(e))return!1;const t=new Set;return e.every(r=>!r||typeof r!="object"||Array.isArray(r)||typeof r.reportId!="string"||!r.reportId.trim()||!Number.isSafeInteger(r.reportIndex)||r.reportIndex<0||t.has(r.reportIndex)||typeof r.reportScope!="string"||!r.reportScope.trim()||r.reportScope.length>4096||r.revision!==void 0&&typeof r.revision!="string"||r.sourceToken!==void 0&&typeof r.sourceToken!="string"?!1:(t.add(r.reportIndex),!0))}const I="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 we(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 be(e){return Array.isArray(e)&&e.every(t=>R(t)&&typeof t.code=="string"&&typeof t.message=="string"&&["info","warning","error"].includes(t.severity)&&Q(t))}function Ae(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 xe(e){return e===void 0?!0:R(e)&&["heuristic","provided","font-bytes"].includes(e.textMetrics)&&(e.fontFingerprint===void 0||typeof e.fontFingerprint=="string"&&/^[a-f0-9]{64}$/.test(e.fontFingerprint))}function Se(e,t){if(!R(e)||!we(e.stats)||!be(e.diagnostics)||!Ae(e.revisions)||!xe(e.layout)||!ge(e.sources))return!1;if(t==="prepare")return fe(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 $e(e){const t=C(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 ke(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($e)}:{}}}function Ne(e){if(!e||typeof e!="object")return!1;const t=e;return t.protocol===I&&typeof t.id=="string"&&(t.operation==="prepare"||t.operation==="export"||t.operation==="exportPrepared")&&!!t.input&&typeof t.input=="object"}async function ve(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:I,id:t.id,result:o}}catch(o){return{protocol:I,id:t.id,error:ke(o)}}}function Re(e){const t=e.result;return!t||!("bytes"in t)||!(t.bytes.buffer instanceof ArrayBuffer)?[]:[t.bytes.buffer]}function Ie(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"||!("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 Me=0;function B(e){const t=new Error("报表 Worker 任务已取消");return t.name="AbortError",Object.defineProperty(t,"cause",{value:e}),t}function Ee(e,t){if(!e||typeof e!="object")return;const r=e;return r.protocol===I&&r.id===t?r:void 0}function Oe(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(B(i.reason)):new Promise((y,u)=>{let b;try{b=e()}catch(l){u(l);return}const $=`mach-report-${Date.now()}-${++Me}`;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),k=>u(l??k)))},g=()=>m(B(i?.reason)),x=l=>{const w=Ee(l,$);if(!(!w||p)){if("type"in w&&w.type==="event"){const k="event"in w?w.event:void 0;Ie(k,s)?z(d,k,i):m(new Error("报表 Worker 返回无效阶段事件"));return}w.error&&typeof w.error.name=="string"&&typeof w.error.message=="string"?m(new J(w.error)):Se(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,...k}=s;b.postMessage({protocol:I,id:$,operation:n,input:k})}}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)}}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 Te(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 je(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 N(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 $=Array.isArray(u),p=Te(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(je(u,c),b+1)}return i.delete(u),$?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","任务类型无效");N(e.request.payload,{maxNodes:19e3,maxCharacters:75e4}),N(e)}function qe(e,t){if(e&&(e.createdAt!==t.createdAt||N(e.request)!==N(t.request)))throw new a("input","任务创建时间与请求不可变更,请使用新任务ID")}function Je(e,t){return e.status==="queued"||e.status==="running"&&(e.lease?.expiresAt??0)<=t}function Pe(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 M(e){return new TextEncoder().encode(N(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:M(e.result);if(n>t.maxResultBytes)throw new a("capacity","任务结果超过独立预算,请保存文件引用");return Math.max(M(r)+t.controlReserveBytes,M(o))+n}function L(e){return e.status!=="queued"&&e.status!=="running"}function Be(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 We(e){const t=new TextEncoder().encode(N(e)),r=globalThis.crypto?.subtle;if(!r)return he(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 Fe(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 We(e.request),expiresAt:t}}function Ue(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 E(e,t){return j.createHash("sha256").update(JSON.stringify([e,t])).digest("hex")+".json"}async function P(e){try{return await h.promises.readFile(e,"utf8")}catch(t){if(O(t)==="ENOENT")return;throw t}}async function De(e,t){const r=await P(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 Ce(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 De(e,!0),await h.promises.open(e,"wx",384)}finally{await o.close(),await h.promises.unlink(r)}}async function _e(e,t){const r=v.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 Ce(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 Ke(e,t,r,o){if("tombstone"in r){const n=r.tombstone;if(Ue(n),T(n.scope,n.id),E(n.scope,n.id)!==t)throw new a("input","持久任务摘要身份不匹配");const s=M(n);e.tombstoneBytes+=s,e.tombstones.set(t,{value:n,bytes:s})}else{if(_(r,r.scope,r.id,r.revision-1),E(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 Le(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(v.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=v.join(e,s);if((await h.promises.stat(i)).size>4e6)throw new a("capacity","持久任务文件超过单文件预算");Ke(n,s,JSON.parse(await h.promises.readFile(i,"utf8")),t)}return n}async function ze(e,t,r){const o=v.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,v.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 He(e){const t=v.resolve(e.directory),r=Pe(e);await h.promises.mkdir(t,{recursive:!0,mode:448});const o=await _e(t,e.recoverDeadOwner??!1);let n;try{n=await Le(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 ze(t,p,f)}catch(m){throw await P(v.join(t,p))===f&&c(),m}c()};return{read:async(p,f)=>{d(),T(p,f),await i;const c=n.records.get(E(p,f));return c?q(c.record):void 0},readTombstone:async(p,f)=>{d(),T(p,f),await i;const c=n.tombstones.get(E(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(N(m));return _(g,p,f,c),y(async()=>{const x=E(p,f),l=n.records.get(x);if((l?.record.revision??null)!==c||n.tombstones.has(x))return!1;qe(l?.record,g);const w=K(g,r),k=n.bytes-(l?.bytes??0)+w;if(k>r.maxBytes||!l&&n.records.size>=r.maxRecords)throw new a("capacity","持久任务容量已满,请清理终态任务或扩大显式预算");return await u(x,N(g),()=>{n.records.set(x,{record:g,bytes:w}),n.bytes=k}),!0})},prune:async p=>{const f=Be(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(v.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 Fe(g.record,f.now+f.tombstoneRetentionMs),l=M(x);if(n.tombstones.size>=r.maxTombstones||n.tombstoneBytes+l>r.maxTombstoneBytes)break;await u(m,N({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 P(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 Oe(()=>{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 Qe(e){const t=W.parentPort;if(!t)throw new Error("serveNodeReportWorker 只能在 worker_threads 中调用");const r=o=>{Ne(o)&&ve(e,o,n=>t.postMessage({protocol:I,id:o.id,type:"event",event:n})).then(n=>t.postMessage(n,Re(n)))};return t.on("message",r),()=>t.off("message",r)}function Ve(e){return j.createHash("sha256").update(e).digest("hex")}exports.ReportWorkerError=J;exports.createNodeReportExecutor=Ze;exports.openFileReportJobStore=He;exports.reportArtifactSha256=Ve;exports.serveNodeReportWorker=Qe;
|