@agile-team/mach-report 2.16.0 → 2.17.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 +10 -6
- package/dist/{ExcelBindingWizard-CP6h2x1f.cjs → ExcelBindingWizard-Bq6FYME6.cjs} +1 -1
- package/dist/{ExcelBindingWizard-HhB3hAJE.js → ExcelBindingWizard-Co1svTsw.js} +3 -3
- package/dist/{ParamEditor-CUQLgoxa.cjs → ParamEditor-B5UZRgxv.cjs} +1 -1
- package/dist/{ParamEditor-OKesP_nO.js → ParamEditor-DNNARyeB.js} +1 -1
- package/dist/{ReportBatchPanel-cZCAMAwH.cjs → ReportBatchPanel-Ctvs2t_9.cjs} +1 -1
- package/dist/{ReportBatchPanel-ruxcbfY6.js → ReportBatchPanel-uQh06usx.js} +1 -1
- package/dist/ReportPreview-BdQawRh0.js +4879 -0
- package/dist/ReportPreview-CJC_-j2I.cjs +6 -0
- package/dist/{ReportTemplateLibrary-BDlNT8JN.cjs → ReportTemplateLibrary-CnP7_1pH.cjs} +1 -1
- package/dist/{ReportTemplateLibrary-DcwrH-63.js → ReportTemplateLibrary-TIL_Oj2l.js} +1 -1
- package/dist/RuleEditor-DkRjOLlr.js +2141 -0
- package/dist/RuleEditor-h5anGsDB.cjs +1 -0
- package/dist/{TemplateOutlinePanel-CGrT5DFN.cjs → TemplateOutlinePanel-BlLxRrfu.cjs} +1 -1
- package/dist/{TemplateOutlinePanel-SXCjaPKR.js → TemplateOutlinePanel-BouxsuqQ.js} +1 -1
- package/dist/{TemplateReusePanel-lHLOS9Wn.js → TemplateReusePanel-BEACLPaN.js} +2 -2
- package/dist/{TemplateReusePanel-6Z3wRFz8.cjs → TemplateReusePanel-yxsHSO40.cjs} +1 -1
- package/dist/{TemplateReviewPanel-CJ9PLc48.js → TemplateReviewPanel-B1OGRY2i.js} +1 -1
- package/dist/{TemplateReviewPanel-Dpk7sLcF.cjs → TemplateReviewPanel-D9Cx0m2N.cjs} +1 -1
- package/dist/analytics.cjs +1 -1
- package/dist/analytics.d.cts +63 -1
- package/dist/analytics.d.ts +63 -1
- package/dist/analytics.js +4 -4
- package/dist/artifact-integrity.json +86 -90
- package/dist/assets-BIMVwjQe.js +231 -0
- package/dist/assets-Dfs2ElxI.cjs +1 -0
- package/dist/{auto-YR7a4BtF.js → auto-BIOmtVhk.js} +14 -14
- package/dist/{auto-uVBjX1j5.cjs → auto-DDHflI9v.cjs} +1 -1
- package/dist/computed-BW5a8QFk.js +612 -0
- package/dist/computed-C2GD3XcE.cjs +1 -0
- package/dist/dataset-DL83majE.js +161 -0
- package/dist/dataset-IrlXbUvh.cjs +1 -0
- package/dist/{designer-BfQSahxq.js → designer-D9XAxqSc.js} +1194 -1179
- package/dist/designer-uCDo5XSK.cjs +2 -0
- package/dist/designer.cjs +1 -1
- package/dist/designer.d.cts +125 -3
- package/dist/designer.d.ts +125 -3
- package/dist/designer.js +1 -1
- package/dist/{drill-CsdjgkRM.cjs → drill-ByN8COs_.cjs} +1 -1
- package/dist/{drill-DIGsZfyB.js → drill-CKW3Xtfa.js} +11 -11
- package/dist/{encoding-BYF9ZTl9.cjs → encoding-BFMFIc4r.cjs} +1 -1
- package/dist/{encoding-BOGq4qYL.js → encoding-DP_Eaf0A.js} +2 -2
- package/dist/{font-loader-EKLzOJxf.cjs → font-loader-7FWVlykp.cjs} +1 -1
- package/dist/{font-loader-CzI1GuBc.js → font-loader-CQZowp0I.js} +1 -1
- package/dist/index.cjs +8 -8
- package/dist/index.d.cts +173 -1
- package/dist/index.d.ts +173 -1
- package/dist/index.js +1205 -808
- package/dist/json-snapshot-D7PE1NsU.cjs +2 -0
- package/dist/{json-snapshot-D6ioHth9.js → json-snapshot-DYmEe3sO.js} +769 -692
- package/dist/matrix-JLAXlux-.js +302 -0
- package/dist/matrix-gTHpDTGm.cjs +1 -0
- package/dist/{pdf-ByVCb1i6.cjs → pdf-B8JouyYv.cjs} +47 -47
- package/dist/{pdf-DJ5S6ukC.js → pdf-l3ea86di.js} +13 -15
- package/dist/pdf.cjs +1 -1
- package/dist/pdf.d.cts +12 -0
- package/dist/pdf.d.ts +12 -0
- package/dist/pdf.js +2 -2
- package/dist/{plugin-C2j5_mhx.js → plugin-BBp74CQZ.js} +1 -1
- package/dist/{plugin-Dr39GBRG.cjs → plugin-CtFX9PFG.cjs} +1 -1
- package/dist/{prepared-DqtpvRTn.js → prepared-CARicKYh.js} +1 -1
- package/dist/{prepared-DdrjLC7L.cjs → prepared-Ch1x_Gog.cjs} +1 -1
- package/dist/{protocol-BzwMP4Vw.cjs → protocol-B5A2uom4.cjs} +1 -1
- package/dist/{protocol-kt4Iy6-3.js → protocol-BaiWjq5w.js} +3 -3
- package/dist/{record-bindings-DUX1VMlR.cjs → record-bindings-B86Sur_y.cjs} +1 -1
- package/dist/{record-bindings-CZWBJ1fU.js → record-bindings-D4TuMzHs.js} +1 -1
- package/dist/{region-binding-workflow-CWNvIjkV.js → region-binding-workflow-BNasF5kz.js} +2 -2
- package/dist/{region-binding-workflow-CqSMxQ4p.cjs → region-binding-workflow-O2Cni3mF.cjs} +1 -1
- package/dist/report-encoding-worker.cjs +1 -1
- package/dist/report-encoding-worker.js +1 -1
- package/dist/runtime-DakRXui3.js +170 -0
- package/dist/runtime-dL5ygIfa.cjs +1 -0
- package/dist/sbom.cdx.json +1 -1
- package/dist/server/node.d.cts +46 -0
- package/dist/server/node.d.ts +46 -0
- package/dist/server-node.cjs +4 -4
- package/dist/server-node.js +2540 -1911
- package/dist/server.cjs +1 -1
- package/dist/server.d.cts +174 -1
- package/dist/server.d.ts +174 -1
- package/dist/server.js +787 -544
- package/dist/style.css +1 -1
- package/dist/template-catalog-Dua8h9ZA.cjs +1 -0
- package/dist/{template-catalog-BtR2JmCL.js → template-catalog-wT1fNeAP.js} +4 -4
- package/dist/{template-fragments-BVsbxs4a.cjs → template-fragments-BajTajb4.cjs} +1 -1
- package/dist/{template-fragments-By0aZC1D.js → template-fragments-DmX5XK4N.js} +1 -1
- package/dist/{template-registry-C62vpv4a.cjs → template-registry-CpysHAxy.cjs} +1 -1
- package/dist/{template-registry-Cw3vRTX2.js → template-registry-u11fPd8D.js} +5 -5
- package/dist/{tree-BX380Rr7.cjs → tree-CLpxYbKa.cjs} +1 -1
- package/dist/{tree-CjVZLRw7.js → tree-DNJorJUf.js} +1 -1
- package/dist/vue/async.d.cts +108 -2
- package/dist/vue/async.d.ts +108 -2
- package/dist/vue/index.d.cts +130 -3
- package/dist/vue/index.d.ts +130 -3
- package/dist/vue-async.cjs +1 -1
- package/dist/vue-async.js +3 -3
- package/dist/vue.cjs +1 -1
- package/dist/vue.js +4 -4
- package/dist/{workbook-session-BeSO8PFB.js → workbook-session-B8pNW24X.js} +1 -1
- package/dist/{workbook-session-Cbts-22R.cjs → workbook-session-DN5LSA5C.cjs} +1 -1
- package/dist/worker.cjs +1 -1
- package/dist/worker.js +4 -4
- package/dist/xlsx.cjs +4 -4
- package/dist/xlsx.d.cts +88 -2
- package/dist/xlsx.d.ts +88 -2
- package/dist/xlsx.js +232 -230
- package/package.json +1 -1
- package/dist/ReportPreview-BcDKCLiK.js +0 -4834
- package/dist/ReportPreview-Bk9nLfO9.cjs +0 -6
- package/dist/RuleEditor-BX5S8RSF.cjs +0 -1
- package/dist/RuleEditor-CGl9XY2s.js +0 -2037
- package/dist/assets-CqIbfbTr.js +0 -126
- package/dist/assets-e4YSke8n.cjs +0 -1
- package/dist/capabilities-DDwXr_cA.js +0 -103
- package/dist/capabilities-DNLyZdNw.cjs +0 -1
- package/dist/computed-C-4C2S5h.js +0 -521
- package/dist/computed-CGV2a809.cjs +0 -1
- package/dist/dataset-BkRmwgeJ.cjs +0 -1
- package/dist/dataset-H5pFuQGU.js +0 -121
- package/dist/designer-CPPdeM5_.cjs +0 -2
- package/dist/diagnostic-notification-B9K9We3h.cjs +0 -1
- package/dist/diagnostic-notification-qGAYZdkB.js +0 -7
- package/dist/json-snapshot-DknkjvxP.cjs +0 -2
- package/dist/matrix-CGRGkn5s.js +0 -112
- package/dist/matrix-gEO7ZM_u.cjs +0 -1
- package/dist/runtime-BjKBI530.js +0 -168
- package/dist/runtime-CBFEPKEs.cjs +0 -1
- package/dist/template-catalog-C2NLdrwB.cjs +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const w=require("./json-snapshot-D7PE1NsU.cjs"),j=require("./assets-Dfs2ElxI.cjs"),L=require("./dataset-IrlXbUvh.cjs"),h=require("./template-registry-CpysHAxy.cjs"),E=require("./template-bindings-CEtWyiLX.cjs"),P=require("./param-validation-C3HlcLLO.cjs");function R(e){if(e===void 0)return;const t=typeof e=="string"?e:JSON.stringify(e);return t.length>160?t.slice(0,157)+"…":t}function N(e){return/\.(?:repeat|binding)(?:\.|$)/.test(e)?/\.format(?:\.|$)/.test(e)?"format":"binding":/\.tree\.(?:idField|parentField|childrenField|labelField|input)$/.test(e)?"binding":/\.tree\.parentValues$/.test(e)?"calculation":/\.tree\.indentMm$/.test(e)?"format":/\.(?:computed|computeOptions|groups|groupBy|aggregates|grandTotal)(?:\.|\[|$)/.test(e)?"calculation":/\.(?:dataset|field|rowKey|revisionField|sourceTokenField|foreignKey|parentKey)$/.test(e)?"binding":/\.(?:style|headerStyle|format|rules|align|headerAlign|semanticRole|unit)(?:\.|\[|$)/.test(e)?"format":e.startsWith("$.template")?"structure":"metadata"}function T(e){const t=new Map;for(const r of e){if(!r||typeof r!="object"||!("field"in r)||typeof r.field!="string"||t.has(r.field))return;t.set(r.field,r)}return t}function D(e,t,r){return!e.startsWith("$.template.params")||t==="moved"?!1:/\.(?:type|required|min|max|minLength|maxLength|options|defaultValue)(?:\[|$)/.test(e)?!0:t!=="added"?!1:Array.isArray(r)?r.some(a=>!!a&&typeof a=="object"&&"required"in a&&a.required===!0):!!r&&typeof r=="object"&&"required"in r&&r.required===!0}function A(e,t,r={}){const a=h.parseReportTemplate(e),n=h.parseReportTemplate(t),o=r.maxChanges??500;if(!Number.isSafeInteger(o)||o<1||o>1e4)throw new RangeError("maxChanges must be between 1 and 10000");const s={changes:[],totalChanges:0,breakingChanges:0,truncated:!1};function d(c,l,u,m){const f=N(l),y=c!=="moved"&&(f==="binding"||l==="$.id"||c==="removed"&&f==="structure"||D(l,c,m));s.totalChanges++,y&&s.breakingChanges++,s.changes.length<o&&s.changes.push({kind:c,category:f,path:l,before:R(u),after:R(m),breaking:y})}function p(c,l,u){const m=T(c),f=T(l);if(!m||!f)return!1;const y=new Map(l.map((g,b)=>[g.field,b]));Array.from(m).forEach(([g,b],$)=>{const x=`${u}[${JSON.stringify(g)}]`;f.has(g)?(y.get(g)!==$&&d("moved",x,$,y.get(g)),i(b,f.get(g),x)):d("removed",x,b,void 0)});for(const[g,b]of f)m.has(g)||d("added",`${u}[${JSON.stringify(g)}]`,void 0,b);return!0}function i(c,l,u){if(!(Object.is(c,l)||u==="$.revision")){if(c===void 0||l===void 0){d(c===void 0?"added":"removed",u,c,l);return}if(Array.isArray(c)&&Array.isArray(l)){if((u.endsWith(".columns")||u.endsWith(".params"))&&p(c,l,u))return;for(let m=0;m<Math.max(c.length,l.length);m++)i(c[m],l[m],`${u}[${m}]`)}else if(c&&l&&typeof c=="object"&&typeof l=="object"&&!Array.isArray(c)&&!Array.isArray(l)){const m=c,f=l;for(const y of new Set([...Object.keys(m),...Object.keys(f)]))i(m[y],f[y],`${u}.${y}`)}else d("modified",u,c,l)}}return i(a,n,"$"),s.truncated=s.totalChanges>s.changes.length,s}function M(e,t,r){for(const a of E.collectTemplateDatasetBindings(e)){const n=Object.prototype.hasOwnProperty.call(t,a.dataset)?t[a.dataset]:void 0;if(!n){r.push({code:"dataset",severity:"error",path:`${a.path}.dataset`,message:`未声明数据集 ${a.dataset}`});continue}const o=new Set(n.fields.map(s=>s.field));a.fields.forEach(({field:s,path:d,summary:p})=>{!o.has(s)&&!a.generated.has(s)&&!(p&&a.summaries.has(s))&&r.push({code:"field",severity:"error",path:d,field:s,message:`数据集 ${a.dataset} 缺少字段 ${s}`})})}}function q(e,t,r,a){const n=r.maxSampleRows??1e3;let o;try{o=w.templateValidationDatasets(t,e.datasets,{maxRows:n})}catch(p){return a.push({code:"sample",severity:"error",path:"$.fixtures",fixture:e.name,message:p instanceof Error?p.message:String(p)}),!1}const s=Object.values(o).reduce((p,i)=>p+i.length,0);if(s>n)return a.push({code:"sample",severity:"error",path:"$.fixtures",fixture:e.name,message:`样例 ${s} 行超过预算 ${n},请显式选择验收样例`}),!1;const d=new Set(E.collectTemplateDatasetBindings(t).map(p=>p.dataset));for(const[p,i]of Object.entries(r.dataSchemas??{}).filter(([c])=>d.has(c)))try{const c=L.validateDatasetRows(o[p],i,{path:`$.datasets.${p}`,maxRows:n});if(a.push(...c.issues.map(l=>({...l,code:"sample",severity:"error",fixture:e.name}))),!c.ok)return!1}catch(c){return a.push({code:"dataset",severity:"error",path:`$.dataSchemas.${p}`,message:String(c)}),!1}return!0}function F(e,t){const r=e.pages[t.pageIndex]?.components[t.componentIndex]?.meta?.labelSource;if(r&&typeof r=="object"&&"pageIndex"in r&&"componentIndex"in r&&typeof r.pageIndex=="number"&&typeof r.componentIndex=="number")return{path:`$.template.pages[${r.pageIndex}].components[${r.componentIndex}]`,pageIndex:r.pageIndex,componentIndex:r.componentIndex};const a=e.pages[t.pageIndex]?.meta?.record;if(a&&typeof a=="object"&&"templatePageIndex"in a&&typeof a.templatePageIndex=="number")return{path:`$.template.pages[${a.templatePageIndex}].components[${t.componentIndex}]`,pageIndex:a.templatePageIndex,componentIndex:t.componentIndex}}function B(e,t,r){const a=F(t,r);if(a)return a;const n=t.pages[r.pageIndex]?.components[r.componentIndex],o=/^table:(\d+):(\d+)(?::|$)/.exec(n?.table?.id??"");if(o)return{path:`$.template.pages[${o[1]}].components[${o[2]}]`,pageIndex:Number(o[1]),componentIndex:Number(o[2])};for(const[s,d]of e.pages.entries()){const p=d.components.findIndex(i=>i===n||n?.nid!==void 0&&"nid"in i&&i.nid===n.nid);if(p>=0)return{path:`$.template.pages[${s}].components[${p}]`,pageIndex:s,componentIndex:p}}return{path:"$.template"}}function J(e,t,r,a,n){const o=P.validateReportParams(e.template.params??[],t.params??{});if(n.issues.push(...o.issues.map(s=>({...s,code:"params",severity:"error",fixture:t.name,path:s.path.replace(/^\$\.params/,`$.fixtures[${r}].params`)}))),!!o.ok&&q(t,e.template,a,n.issues))try{const{plan:s,warnings:d}=w.paginateTemplate(e.template,t.datasets,{maxPages:a.maxPages??100,maxCells:a.maxCells??25e4}),p=(a.formats??["pdf","xlsx"]).flatMap(i=>j.inspectOutputCapabilities(s,i));n.issues.push(...d.map(i=>({code:"layout",severity:"warning",path:"$.template",fixture:t.name,message:i}))),n.issues.push(...p.map(i=>({code:"output",severity:a.strictOutputs?"error":"warning",...B(e.template,s,i),fixture:t.name,message:`${i.format}: ${i.message}`,diagnostic:i}))),n.samples.push({name:t.name,pages:s.pages.length,rows:w.templateDatasetRowCount(e.template,t.datasets),diagnostics:p})}catch(s){n.issues.push({code:"layout",severity:"error",path:"$.template",fixture:t.name,message:s instanceof Error?s.message:String(s)})}}function V(e){for(const[r,a]of[["maxPages",e.maxPages],["maxCells",e.maxCells],["maxSampleRows",e.maxSampleRows]])if(a!==void 0&&(!Number.isSafeInteger(a)||a<1))throw new RangeError(`${r} must be a positive safe integer`);if((e.fixtures?.length??0)>20)throw new RangeError("At most 20 review fixtures are allowed");const t=new Set;for(const r of e.fixtures??[]){if(typeof r.name!="string"||!r.name.trim()||r.name.length>120||t.has(r.name))throw new Error("Review fixtures require unique non-empty names of at most 120 characters");t.add(r.name)}}function*C(e,t,r){let a;yield{stage:"template",run:()=>{V(t),a=h.parseReportTemplate(e)}};const n=t.previous;n&&(yield{stage:"baseline",run:()=>{r.changes=A(n,a),r.changes.breakingChanges&&!t.allowBreakingChanges&&r.issues.push({code:"compatibility",severity:"error",path:"$.template",message:`${r.changes.breakingChanges} 项字段或结构变更需要明确确认兼容性`})}}),t.dataSchemas&&(yield{stage:"bindings",run:()=>M(a.template,t.dataSchemas,r.issues)});for(const[o,s]of(t.fixtures??[]).entries())yield{stage:"fixture",fixture:s.name,run:()=>J(a,s,o,t,r)};t.fixtures?.length||r.issues.push({code:"sample",severity:"warning",path:"$.fixtures",message:"未提供验收样例,仅完成结构和字段检查,尚未验证排版与输出"})}function O(e){return e.ok=e.issues.every(t=>t.severity!=="error"),e}function k(e,t){e.issues.push({code:"template",severity:"error",path:"$",message:t instanceof Error?t.message:String(t)})}function W(e,t={}){const r={ok:!1,issues:[],samples:[]};try{for(const a of C(e,t,r))a.run()}catch(a){k(r,a)}return O(r)}function v(e){if(e?.aborted)throw e.reason??new DOMException("Template review was aborted","AbortError")}function K(e){return v(e),new Promise((t,r)=>{const a=()=>{clearTimeout(n),e?.removeEventListener("abort",a),r(e?.reason??new DOMException("Template review was aborted","AbortError"))},n=setTimeout(()=>{e?.removeEventListener("abort",a),t()},0);e?.addEventListener("abort",a,{once:!0}),e?.aborted&&a()})}function I(e,t){try{e.onProgress?.(t)}catch{}}async function _(e,t={}){const r={ok:!1,issues:[],samples:[]},a=t.fixtures?.length??0;let n=0;v(t.signal);try{const o=C(e,t,r),s=o.next();s.done||(s.value.run(),I(t,{completed:n,total:a,stage:s.value.stage})),v(t.signal);for(const d of o)await K(t.signal),v(t.signal),d.run(),d.stage==="fixture"&&n++,I(t,{completed:n,total:a,stage:d.stage,...d.fixture?{fixture:d.fixture}:{}}),v(t.signal)}catch(o){v(t.signal),k(r,o)}return O(r)}function z(e,t){const r=e.publishedRevision??e.published?.revision;for(const a of[e.draftRevision,r])if(a!==void 0&&(typeof a!="string"||!a.trim()))throw new TypeError("模板生命周期修订应为非空字符串");if(e.draftRevision!==void 0&&e.draftRevision!==t.revision)throw new TypeError("可编辑文档应与草稿修订一致");if(e.published&&(e.published.id!==t.id||e.published.revision!==r))throw new TypeError("发布文档身份或修订不一致");if(!e.published&&r!==void 0&&r!==t.revision)throw new TypeError("发布修订需要对应的独立文档");return{...e.draftRevision===void 0?{}:{draftRevision:e.draftRevision},...r===void 0?{}:{publishedRevision:r}}}function G(e,t){const r=h.parseReportTemplate(e);if(t.id===r.id)throw new Error("复制模板应使用新的 ID");const{revision:a,...n}=r;return h.parseReportTemplate({...n,id:t.id,name:t.name})}function H(e){if(!Array.isArray(e)||e.length>1e3)throw new RangeError("本地模板目录最多 1000 项");const t=new Map,r=new Map,a=[];for(const n of e){const o=h.parseReportTemplate(n.document);if(t.has(o.id))throw new Error(`模板 ID 重复:${o.id}`);if(n.category!==void 0&&(typeof n.category!="string"||n.category.length>128)||n.tags!==void 0&&(!Array.isArray(n.tags)||n.tags.length>20||n.tags.some(i=>typeof i!="string"||i.length>128)))throw new TypeError("模板分类和标签无效");const s=z(n,o),{template:d,...p}=o;t.set(o.id,o),n.published?r.set(o.id,h.parseReportTemplate(n.published)):s.publishedRevision&&r.set(o.id,h.parseReportTemplate(o)),a.push({...p,...s,...n.category?{category:n.category}:{},...n.tags?{tags:[...n.tags]}:{}})}return a.sort((n,o)=>n.id<o.id?-1:1),{search:async n=>{S(n.signal);const o=n.limit??30;if(!Number.isSafeInteger(o)||o<1||o>100)throw new RangeError("模板每页数量应为 1–100");const s=n.query?.trim().toLocaleLowerCase()??"",d=a.filter(i=>(!n.category||i.category===n.category)&&(!n.cursor||i.id>n.cursor)&&(!s||[i.id,i.name,i.description,...i.tags??[]].some(c=>c?.toLocaleLowerCase().includes(s)))),p=new Map;for(const i of a)i.category&&p.set(i.category,(p.get(i.category)??0)+1);return JSON.parse(JSON.stringify({items:d.slice(0,o),...d.length>o?{next:d[o-1].id}:{},categories:Array.from(p,([i,c])=>({id:i,label:i,count:c}))}))},get:async(n,o)=>{S(o.signal);const s=o.mode==="published"?r.get(n):t.get(n);return s?h.parseReportTemplate(s):void 0}}}function S(e){if(!e?.aborted)return;const t=new Error("模板目录操作已取消");throw t.name="AbortError",t}exports.cloneReportTemplate=G;exports.createLocalTemplateCatalog=H;exports.diffReportTemplates=A;exports.reviewReportTemplate=W;exports.reviewReportTemplateAsync=_;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { i as P } from "./
|
|
3
|
-
import { v as L } from "./dataset-
|
|
4
|
-
import { p as h } from "./template-registry-
|
|
1
|
+
import { x as O, H as k, G as j } from "./json-snapshot-DYmEe3sO.js";
|
|
2
|
+
import { i as P } from "./assets-BIMVwjQe.js";
|
|
3
|
+
import { v as L } from "./dataset-DL83majE.js";
|
|
4
|
+
import { p as h } from "./template-registry-u11fPd8D.js";
|
|
5
5
|
import { c as S } from "./template-bindings-C2SpvsMU.js";
|
|
6
6
|
import { d as N } from "./param-validation-Do7Eg8Zv.js";
|
|
7
7
|
function $(e) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const f=require("./template-registry-
|
|
1
|
+
"use strict";const f=require("./template-registry-CpysHAxy.cjs"),T=require("./template-bindings-CEtWyiLX.cjs"),g=require("./style-C22Pbv3T.cjs");function p(t){return JSON.parse(JSON.stringify(t))}function u(t){return{...t.repeatDataset?{repeat:{dataset:t.repeatDataset}}:{},pages:[{widthMm:4999,heightMm:4999,components:t.components}]}}function y(t){if(!t.id.trim()||!t.name.trim()||!t.revision.trim())throw new Error("Fragment identity, name and revision are required");if(!t.components.length||t.components.length>200)throw new RangeError("A fragment must contain 1–200 components");f.parseReportTemplate({schemaVersion:"1.0",id:t.id,name:t.name,template:u(t)})}function E(t,n,e,a){const r=f.parseReportTemplate(t).template.pages[n];if(!r||!e.length||e.some(o=>!Number.isSafeInteger(o)||!r.components[o]))throw new Error("Select existing components to capture a fragment");const s=[...new Set(e)].map(o=>r.components[o]),l=Math.min(...s.map(o=>o.leftMm)),i=Math.min(...s.map(o=>o.topMm)),m={...a,...t.template.repeat?{repeatDataset:t.template.repeat.dataset}:{},components:p(s).map(o=>({...o,leftMm:o.leftMm-l,topMm:o.topMm-i}))};return y(m),m}function b(t){y(t);const n=new Map;for(const e of T.collectTemplateDatasetBindings(u(t))){const a=n.get(e.dataset)??new Set;for(const r of e.fields)!e.generated.has(r.field)&&!e.summaries.has(r.field)&&a.add(r.field);n.set(e.dataset,a)}return[...n].map(([e,a])=>({dataset:e,fields:[...a]}))}function S(t,n,e){const a=n.replace(/^\$\.template\./,"").replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const s of a.slice(0,-1))r=r[s];r[a[a.length-1]]=e}function F(t,n,e={}){const a=u({...t,components:n});for(const r of T.collectTemplateDatasetBindings(a)){for(const l of r.fields){const i=e.fields?.[r.dataset]?.[l.field];i!==void 0&&S(a,l.path,i)}const s=e.datasets?.[r.dataset];s!==void 0&&S(a,`${r.path}.dataset`,s)}}function h(t){if(!t||typeof t!="object")return;if(Array.isArray(t)){t.forEach(h);return}const n=t;for(const e of["nid","rkey","table","source"])delete n[e];if(n.kind==="list"&&delete n.id,n.meta&&typeof n.meta=="object")for(const e of["fragment","labelSource","record"])delete n.meta[e];Object.values(n).forEach(h)}function D(t){const n=new Set(t.template.pages.flatMap(a=>a.components.map(r=>r.meta?.fragment?.instance)));let e=1;for(;n.has(`fragment-${e}`);)e++;return`fragment-${e}`}function R(t,n,e){const a=e?t.components.flatMap((s,l)=>s.meta?.fragment?.instance===e?[l]:[]):[];if(e&&!a.length)throw new Error("Fragment instance no longer exists");const r=a.map(s=>t.components[s]);if(r.some(s=>s.meta?.fragment?.id!==n.id))throw new Error("An upgrade must use the same fragment identity");return{replacing:a,left:r.length?Math.min(...r.map(s=>s.leftMm)):t.marginLeftMm??0,top:r.length?Math.min(...r.map(s=>s.topMm)):t.marginTopMm??0}}function x(t,n){if(n.some(e=>e.leftMm<0||e.topMm<0||e.leftMm+e.widthMm>t.widthMm+.001||e.topMm+(e.kind==="list"?e.rowHeightMm??7:e.heightMm)>t.heightMm+.001))throw new Error("Fragment exceeds the target page; choose a larger page or adjust its placement")}function k(t,n,e){y(n);const a=f.parseReportTemplate(t),r=a.template.pages[e.pageIndex];if(!r||r.flow)throw new Error("Choose a fixed page before inserting a fragment");const s=R(r,n,e.replaceInstance),l=s.replacing,i=e.leftMm??s.left,m=e.topMm??s.top,o=p(n.components),M=e.replaceInstance??D(a);if(n.repeatDataset&&a.template.repeat?.dataset!==(e.bindings?.datasets?.[n.repeatDataset]??n.repeatDataset))throw new Error("Bind this label fragment to the current record dataset");F(n,o,e.bindings),o.forEach(h),o.forEach((c,d)=>{c.leftMm+=i,c.topMm+=m,c.meta={...c.meta,fragment:{id:n.id,revision:n.revision,instance:M,slot:d}}}),x(r,o);const w=l[0]??r.components.length;return r.components=r.components.filter((c,d)=>!l.includes(d)),r.components.splice(w,0,...o),{document:f.parseReportTemplate(a),componentIndices:o.map((c,d)=>w+d),instance:M}}function C(t,n,e,a){const r=f.parseReportTemplate(t),s=r.template.pages[n];if(!s)throw new Error("Page no longer exists");for(const l of e){const i=s.components[l];if(!i)throw new Error("Component no longer exists");i.kind==="list"?a.target==="header"?I(i,a.style):i.columns.forEach(m=>{m.style=g.mergeComponentStyles(m.style,p(a.style)),a.style.align&&(m.align=a.style.align)}):i.style=g.mergeComponentStyles(i.style,p(a.style))}return f.parseReportTemplate(r)}function I(t,n){if(t.headerStyle=g.mergeComponentStyles(t.headerStyle,p(n)),t.columns.forEach(e=>{e.headerStyle=g.mergeComponentStyles(e.headerStyle,p(n)),n.align&&(e.headerAlign=n.align)}),t.headerGrid)for(const e of t.headerGrid.cells)for(const a of e)a&&(a.style=g.mergeComponentStyles(a.style,p(n)))}exports.applyReportDocumentStyle=C;exports.captureTemplateFragment=E;exports.insertTemplateFragment=k;exports.inspectTemplateFragmentBindings=b;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const oe=require("./matrix-gEO7ZM_u.cjs"),H=require("./computed-CGV2a809.cjs"),x=require("./component-tree-DkGLEfZC.cjs"),ae=require("./code-options-BUTChiZZ.cjs"),J=require("./param-validation-C3HlcLLO.cjs"),j=require("./tree-BX380Rr7.cjs");function fe(e,i,t){e!==void 0&&(typeof e!="string"||!e.trim()||e.length>4096)&&t.push({path:i,message:"来源范围应为不超过 4096 字符的非空字符串"})}function W(e,i,t){e.editable!==void 0&&typeof e.editable!="boolean"&&t.push({path:`${i}.editable`,message:"编辑控制应为布尔值"}),e.valueType!==void 0&&!["text","number","boolean"].includes(e.valueType)&&t.push({path:`${i}.valueType`,message:"编辑类型应为 text、number 或 boolean"})}function re(e,i,t){W(e,i,t),e.indentMm!==void 0&&(typeof e.indentMm!="number"||!Number.isFinite(e.indentMm)||e.indentMm<0)&&t.push({path:`${i}.indentMm`,message:"单元格缩进应为有限非负数"}),e.derived!==void 0&&typeof e.derived!="boolean"&&t.push({path:`${i}.derived`,message:"派生结果标记应为布尔值"}),G(e.source,`${i}.source`,t,!0),e.formula!==void 0&&typeof e.formula!="string"&&t.push({path:`${i}.formula`,message:"单元格公式应为字符串"})}function G(e,i,t,s=!1){if(e===void 0)return;if(!e||typeof e!="object"||Array.isArray(e)){t.push({path:i,message:"业务来源应为对象"});return}const n=e;fe(n.sourceScope,`${i}.sourceScope`,t);for(const o of["datasetId",...s?["field"]:[]])(typeof n[o]!="string"||!n[o].trim())&&t.push({path:`${i}.${o}`,message:"业务标识应为非空字符串"});for(const o of["rowKey","revision"]){const a=n[o];a===void 0&&!(s&&o==="rowKey")||typeof a!="string"&&!(typeof a=="number"&&Number.isFinite(a))&&t.push({path:`${i}.${o}`,message:"业务键及修订号应为字符串或有限数字"})}n.sourceToken!==void 0&&typeof n.sourceToken!="string"&&t.push({path:`${i}.sourceToken`,message:"来源令牌应为字符串"})}const de=new Set(["text","image","barcode","qrcode","chart","line","rect","ellipse"]);function g(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function k(e){return e===null?"null":typeof e=="string"?JSON.stringify(e.slice(0,120)):["number","boolean","undefined"].includes(typeof e)?String(e):`[${typeof e}]`}function ue(e,i,t,s){const n=e[i];(typeof n!="number"||!Number.isFinite(n))&&s.push({path:`${t}.${i}`,message:`应为有限数字,实际 ${k(n)}`})}function he(e,i,t){if(e!==void 0){const s=`${i}.table`;if(!g(e))t.push({path:s,message:"逻辑表来源应为对象"});else{G(e.source,`${s}.source`,t),(typeof e.id!="string"||!e.id.trim())&&t.push({path:`${s}.id`,message:"逻辑表 ID 应为非空字符串"});const n=e.role;["header","body","group-header","subtotal","grand-total"].includes(n)||t.push({path:`${s}.role`,message:"未知逻辑表行角色"});const o=e.rowIndex;(typeof o!="number"||!Number.isInteger(o)||(n==="header"?o!==-1:o<0))&&t.push({path:`${s}.rowIndex`,message:"表头索引应为 -1,内容行索引应为非负整数"}),(!Array.isArray(e.columnKeys)||e.columnKeys.some(a=>typeof a!="string"))&&t.push({path:`${s}.columnKeys`,message:"逻辑列字段应为字符串数组"}),e.layout!==void 0&&e.layout!=="page"&&e.layout!=="wide"&&t.push({path:`${s}.layout`,message:"布局应为 page 或 wide"}),e.title!==void 0&&typeof e.title!="string"&&t.push({path:`${s}.title`,message:"逻辑表名称应为字符串"})}}}function me(e,i,t,s){if(e!==void 0)if(!g(e)||!Array.isArray(e.cells))t.push({path:`${i}.grid.cells`,message:"grid.cells 应为二维数组"});else{const n=e.paddingMm;n!==void 0&&(typeof n!="number"||!Number.isFinite(n)||n<0)&&t.push({path:`${i}.grid.paddingMm`,message:"单元格内距应为有限非负数"}),e.cells.forEach((o,a)=>{if(!Array.isArray(o)){t.push({path:`${i}.grid.cells.${a}`,message:"行应为数组"});return}o.forEach((f,r)=>{if(f==null)return;const d=`${i}.grid.cells.${a}.${r}`;if(!g(f)){t.push({path:d,message:"网格单元格应为对象或 null"});return}re(f,d,t),U(f.richParagraphs,d,t),Array.isArray(f.children)&&f.children.forEach((u,p)=>{I(u,`${i}.grid.cells.${a}.${r}.children.${p}`,t,s)})})})}}function S(e,i,t,s){e!==void 0&&!i.includes(e)&&s.push({path:t,message:"未知富文本属性值"})}function O(e,i,t,s,n=0){for(const o of i){const a=e[o];a!==void 0&&(typeof a!="number"||!Number.isFinite(a)||a<n)&&s.push({path:`${t}.${o}`,message:"富文本数值应为范围内有限数字"})}}function ce(e,i,t){if(e!==void 0){if(!g(e)){t.push({path:i,message:"富文本样式应为对象"});return}for(const s of["fontFamily","color","backgroundColor","lineColor","borderColor"])e[s]!==void 0&&typeof e[s]!="string"&&t.push({path:`${i}.${s}`,message:"富文本样式应为字符串"});for(const s of["bold","italic","underline","borderTop","borderRight","borderBottom","borderLeft"])e[s]!==void 0&&typeof e[s]!="boolean"&&t.push({path:`${i}.${s}`,message:"富文本样式应为布尔值"});O(e,["fontSize","fontSizePx","lineWidthPt","lineHeight","opacity"],i,t),O(e,["letterSpacing","rotateDeg"],i,t,-1/0),typeof e.opacity=="number"&&e.opacity>1&&t.push({path:`${i}.opacity`,message:"透明度不能大于1"}),S(e.align,["left","center","right","justify"],`${i}.align`,t),S(e.verticalAlign,["top","middle","bottom"],`${i}.verticalAlign`,t)}}function ge(e,i,t){if(!g(e)){t.push({path:i,message:"富文本片段应为对象"});return}S(e.kind,["text","field"],`${i}.kind`,t);for(const s of["text","field"])e[s]!==void 0&&typeof e[s]!="string"&&t.push({path:`${i}.${s}`,message:"富文本内容应为字符串"});ce(e.style,`${i}.style`,t)}function U(e,i,t){if(e!==void 0){if(!Array.isArray(e)){t.push({path:`${i}.richParagraphs`,message:"richParagraphs 应为数组"});return}e.forEach((s,n)=>{const o=`${i}.richParagraphs.${n}`;if(!g(s)||!Array.isArray(s.segments)){t.push({path:o,message:"段落缺少 segments 数组"});return}S(s.align,["left","center","right","justify"],`${o}.align`,t),O(s,["lineHeight","spaceBeforeMm","spaceAfterMm","indentMm"],o,t),s.segments.forEach((a,f)=>ge(a,`${o}.segments.${f}`,t))})}}function F(e,i,t,s=[]){const n=x.componentTreeIssue([e],i);if(n){t.push(n);return}I(e,i,t,s)}function I(e,i,t,s=[]){if(!g(e)){t.push({path:i,message:"组件应为对象"});return}const n=e.kind;typeof n!="string"?t.push({path:`${i}.kind`,message:"组件缺少 kind 字符串"}):de.has(n)||s.push({path:`${i}.kind`,message:`未知组件类型 ${k(n)},将以兜底方式渲染`});for(const o of["leftMm","topMm","widthMm","heightMm"])ue(e,o,i,t);typeof e.leftMm=="number"&&e.leftMm<-100&&t.push({path:`${i}.leftMm`,message:"几何数值异常(leftMm<-100)"});for(const o of["widthMm","heightMm"])typeof e[o]=="number"&&e[o]<0&&t.push({path:`${i}.${o}`,message:"组件尺寸不能为负数"});he(e.table,i,t),pe(e.code,n,i,t),e.pageAnchor!==void 0&&!["header","footer"].includes(e.pageAnchor)&&t.push({path:`${i}.pageAnchor`,message:"页面锚点应为 header 或 footer"}),e.lineDirection!==void 0&&!["down","up"].includes(e.lineDirection)&&t.push({path:`${i}.lineDirection`,message:"线段方向应为 down 或 up"}),me(e.grid,i,t,s),U(e.richParagraphs,i,t)}function pe(e,i,t,s){if(e!==void 0)for(const n of ae.codeOptionIssues(e,i))s.push({path:`${t}.code${n.path?`.${n.path}`:""}`,message:n.message})}function q(e,i,t){if(!g(e))return;e.binding!==void 0&&t.push({path:`${i}.binding`,message:"渲染计划不允许未解析字段绑定"});const s=e.grid;!g(s)||!Array.isArray(s.cells)||s.cells.forEach((n,o)=>{Array.isArray(n)&&n.forEach((a,f)=>{!g(a)||!Array.isArray(a.children)||a.children.forEach((r,d)=>q(r,`${i}.grid.cells.${o}.${f}.children.${d}`,t))})})}function B(e,i,t,s=[]){if(!g(e)){t.push({path:i,message:"页应为对象"});return}const n=e.pageWidthMm,o=e.pageHeightMm;(typeof n!="number"||!Number.isFinite(n)||n<=0)&&t.push({path:`${i}.pageWidthMm`,message:`页宽非法: ${k(n)}`}),(typeof o!="number"||!(o>0&&o<5e3))&&t.push({path:`${i}.pageHeightMm`,message:`页高非法: ${k(o)}`}),e.layout!==void 0&&e.layout!=="page"&&e.layout!=="wide"&&t.push({path:`${i}.layout`,message:"布局应为 page 或 wide"});const a=e.components;if(!Array.isArray(a))t.push({path:`${i}.components`,message:"components 应为数组"});else if(Array.isArray(a)){const f=x.componentTreeIssue(a,`${i}.components`);if(f){t.push(f);return}a.forEach((r,d)=>{I(r,`${i}.components.${d}`,t,s),q(r,`${i}.components.${d}`,t)})}}function z(e){const i=[],t=[],s=g(e)?e.pages:void 0;if(g(e)&&e.requiresRecalculation!==void 0&&typeof e.requiresRecalculation!="boolean"&&i.push({path:"$.requiresRecalculation",message:"重算能力要求应为布尔值"}),!Array.isArray(s))i.push({path:"$.pages",message:e==null?"渲染计划为空":"渲染计划缺少 pages 数组"});else{const n=x.renderTreeIssue(s);if(n)return{ok:!1,errors:[...i,n],warnings:t};s.forEach((a,f)=>B(a,`$.pages.${f}`,i,t)),s.length>2e3&&t.push({path:"$.pages",message:`页数异常大(${s.length} 页),渲染与打印耗时可能显著增加`});const o=s.reduce((a,f)=>a+(g(f)&&Array.isArray(f.components)?f.components.length:0),0);o>5e4&&t.push({path:"$.pages",message:`组件总数异常大(${o} 个),可能触发浏览器性能限制`})}return{ok:i.length===0,errors:i,warnings:t}}function ye(e){const i=z(e);if(!i.ok){const t=i.errors.slice(0,3).map(s=>`${s.path}: ${s.message}`).join("; ");throw new Error(`渲染计划校验失败(${i.errors.length} 处): ${t}`)}return e.pages}function _(e){return e.kind==="list"?e.id:e.nid}function le(e){return e.kind==="list"?!1:e.pageAnchor!==void 0||e.kind==="text"&&typeof e.text=="string"&&/\{(?:page|totalPages)\}/.test(e.text)}function $e(e,i){const t=e.filter(n=>i.componentIds.includes(_(n)??""));if(t.filter(n=>n.kind==="list"&&n.cardinality!=="record").length&&t.length!==1)throw new Error("纵向重复区域必须独占流式分段,不能与静态或单记录区域并排");for(const n of t){const o=n.kind==="list"?n.topMm+(n.rowHeightMm??0):n.topMm+n.heightMm;if(n.topMm<i.topMm-.001||o>i.topMm+i.heightMm+.001)throw new Error("流式分段应完整包含其组件的原始纵向范围")}}function be(e,i){if(!i)return e.map(s=>({components:[s]}));const t=new Map(e.map(s=>[_(s),s]));return i.bands.map(s=>({band:s,components:s.componentIds.map(n=>{const o=t.get(n);if(!o)throw new Error(`流式区域引用不存在的组件:${n}`);return o})}))}function X(e,i){if(!i||!Array.isArray(i.bands)||!i.bands.length||i.bands.length>1e4)throw new Error("流式排版应包含 1–10000 个区域");const t=new Set,s=new Set;for(const n of e){if(le(n))continue;const o=_(n);if(!o||t.has(o))throw new Error("流式排版组件应具有唯一标识");t.add(o)}if(Ae(e,i,t,s),s.size!==t.size)throw new Error("流式排版必须显式包含每个非锚点组件")}function Ae(e,i,t,s){let n=-1/0;for(const o of i.bands){if(!Number.isFinite(o.topMm)||!Number.isFinite(o.heightMm)||o.topMm<0||o.heightMm<=0||o.topMm<n-.001)throw new Error("流式区域应按原始位置排序,尺寸有效且不重叠");if(!Array.isArray(o.componentIds)||!o.componentIds.length)throw new Error("流式区域不能没有组件");for(const a of o.componentIds){if(!t.has(a)||s.has(a))throw new Error(`流式区域组件缺失、重复或包含页锚点:${a}`);s.add(a)}$e(e,o),n=o.topMm+o.heightMm}}const we=new Set(["__proto__","prototype","constructor"]);function l(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function E(e){return typeof e=="string"&&!!e.trim()&&!we.has(e)}function v(e,i,t,s){for(const n of Object.keys(e))i.includes(n)||s.push({path:`${t}.${n}`,message:"存在未知配置字段"})}function Me(e,i,t){if(e!==void 0){if(!l(e)||!["number","percent","date"].includes(String(e.kind))){t.push({path:i,message:"绑定格式应为 number、percent 或 date"});return}v(e,e.kind==="date"?["kind","pattern"]:e.kind==="number"?["kind","digits","thousands"]:["kind","digits"],i,t),e.digits!==void 0&&(!Number.isInteger(e.digits)||Number(e.digits)<0||Number(e.digits)>100)&&t.push({path:`${i}.digits`,message:"精度应为 0..100 整数"}),e.thousands!==void 0&&typeof e.thousands!="boolean"&&t.push({path:`${i}.thousands`,message:"千分位开关应为布尔值"}),e.pattern!==void 0&&typeof e.pattern!="string"&&t.push({path:`${i}.pattern`,message:"日期格式应为字符串"})}}function Ee(e,i,t){const s=e.binding;if(s===void 0)return;const n=`${i}.binding`;if(!l(s)){t.push({path:n,message:"字段绑定应为对象"});return}(!["text","image","barcode","qrcode"].includes(String(e.kind))||e.grid!==void 0)&&t.push({path:n,message:"绑定仅支持独立文本、图片、条码与二维码组件"}),v(s,["field","format","prefix","suffix","emptyText"],n,t),E(s.field)||t.push({path:`${n}.field`,message:"绑定字段应为安全的非空字段名(按字面读取自有字段)"});for(const o of["prefix","suffix","emptyText"])s[o]!==void 0&&typeof s[o]!="string"&&t.push({path:`${n}.${o}`,message:"应为字符串"});Me(s.format,`${n}.format`,t),e.kind==="image"&&["format","prefix","suffix"].some(o=>s[o]!==void 0)&&t.push({path:n,message:"图片绑定直接读取 PNG/JPEG data URL,不支持文本格式或前后缀"})}function Ne(e,i){if(!l(e)){i.push({path:"$.repeat",message:"逐记录配置应为对象"});return}v(e,["dataset","rowKey","copies"],"$.repeat",i),E(e.dataset)||i.push({path:"$.repeat.dataset",message:"数据集应为安全的非空名称"}),e.rowKey!==void 0&&!E(e.rowKey)&&i.push({path:"$.repeat.rowKey",message:"业务主键应为安全的非空字段名"});const t=e.copies;t!==void 0&&(l(t)?(v(t,["field"],"$.repeat.copies",i),E(t.field)||i.push({path:"$.repeat.copies.field",message:"复制数字段应为安全的非空字段名"})):(!Number.isSafeInteger(t)||Number(t)<1||Number(t)>1e3)&&i.push({path:"$.repeat.copies",message:"每条记录复制数应为 1..1000 整数"}))}function Y(e,i,t,s){if(!l(e))return;Ee(e,i,s),e.binding!==void 0&&!t&&s.push({path:`${i}.binding`,message:"字段绑定需要模板 repeat 数据集;普通报表请使用列表字段"}),t&&e.kind==="list"&&s.push({path:i,message:"逐记录标签使用固定组件;动态列表请使用普通报表模板"});const n=e.grid;l(n)&&Array.isArray(n.cells)&&n.cells.forEach((o,a)=>{Array.isArray(o)&&o.forEach((f,r)=>{l(f)&&Array.isArray(f.children)&&f.children.forEach((d,u)=>Y(d,`${i}.grid.cells.${a}.${r}.children.${u}`,t,s))})})}function Q(e,i){const t=e.repeat!==void 0;t&&Ne(e.repeat,i),Array.isArray(e.pages)&&e.pages.forEach((s,n)=>{if(!l(s))return;const o=`$.pages.${n}`;t&&(s.layout==="wide"||s.flow!==void 0)&&i.push({path:o,message:"逐记录标签仅支持固定尺寸页面,不支持宽表或流式分区"}),Array.isArray(s.components)&&s.components.forEach((a,f)=>{const r=`${o}.components.${f}`;if(Y(a,r,t,i),!t||!l(a))return;const{leftMm:d,topMm:u,widthMm:p,heightMm:y}=a;[d,u,p,y,s.widthMm,s.heightMm].every(A=>typeof A=="number"&&Number.isFinite(A))&&(Number(d)<0||Number(u)<0||Number(d)+Number(p)>Number(s.widthMm)+.001||Number(u)+Number(y)>Number(s.heightMm)+.001)&&i.push({path:r,message:"标签组件超出纸张边界,请调整位置或尺寸"})})})}function Z(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function P(e,i,t){if(e!==void 0){if(!Z(e)){t.push({path:i,message:"条件应为对象"});return}(typeof e.field!="string"||!e.field.trim())&&t.push({path:`${i}.field`,message:"条件需要字段"}),e.numeric!==void 0&&e.numeric!=="number"&&e.numeric!=="decimal"&&t.push({path:`${i}.numeric`,message:"未知条件数值模式"}),[">",">=","<","<=","==","!="].includes(e.op)||t.push({path:`${i}.op`,message:"未知条件运算符"}),typeof e.value!="string"&&!(typeof e.value=="number"&&Number.isFinite(e.value))&&t.push({path:`${i}.value`,message:"条件值应为字符串或有限数字"})}}function ee(e,i,t){if(e===void 0)return;if(!Array.isArray(e)||e.length>2048){t.push({path:i,message:"聚合应为数组且最多 2048 项"});return}const s=new Set;e.forEach((n,o)=>{const a=`${i}.${o}`;if(!Z(n)){t.push({path:a,message:"聚合应为对象"});return}const f=n.field;typeof f!="string"||!f.trim()||s.has(f)?t.push({path:`${a}.field`,message:"聚合输出字段应非空且唯一"}):s.add(f),n.numeric!==void 0&&n.numeric!=="number"&&n.numeric!=="decimal"&&t.push({path:`${a}.numeric`,message:"数值模式应为 number 或 decimal"}),n.digits!==void 0&&(!Number.isInteger(n.digits)||Number(n.digits)<0||Number(n.digits)>100)&&t.push({path:`${a}.digits`,message:"小数位应为 0–100 的整数"});try{H.createAggregateAccumulator({...n,field:n.valueField??f})}catch(r){t.push({path:a,message:r instanceof Error?r.message:String(r)})}})}function ke(e,i,t){if(e===void 0)return;const s=H.validateComputedFields(e);for(const n of s.errors)t.push({path:i,message:n})}function Se(e,i,t){if(e!==void 0)try{oe.validateMatrixOptions(e)}catch(s){t.push({path:i,message:s instanceof Error?s.message:String(s)})}}function ve(e,i,t){if(e.tree===void 0)return;const s=`${i}.tree`;try{j.validateTreeOptions(e.tree);const n=e.tree;if(e.matrix||e.detail||e.groupBy||Array.isArray(e.groups)&&e.groups.length||e.rowVisibleWhen)throw new Error("树形布局不能同时配置普通分组、矩阵、主从或行可见条件");if(e.rowKey!==void 0&&e.rowKey!==n.idField)throw new Error("树形 rowKey 应与 idField 一致");if(!Array.isArray(e.columns)||!e.columns.some(o=>o&&o.field===n.labelField&&!o.hidden))throw new Error("树形布局需要可见的标签列");Array.isArray(e.computed)&&j.validateTreeComputed(n,e.computed)}catch(n){t.push({path:s,message:n instanceof Error?n.message:String(n)})}}const L="1.0";class w extends Error{constructor(i){super(`模板校验失败:${i.slice(0,3).map(t=>`${t.path}: ${t.message}`).join("; ")}`),this.errors=i,this.name="ReportTemplateError"}}const Re=new Set(["__proto__","prototype","constructor"]),xe=new Set(["schemaVersion","id","name","revision","description","template"]),Te=new Set(["left","center","right","justify"]),N=2e5,Oe=64,C=1e7;function h(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function Pe(e,i,t){const s=Object.getPrototypeOf(e),n=Array.isArray(e);if(n?s!==Array.prototype:s!==Object.prototype&&s!==null)return t.push({path:i,message:"模板对象必须使用普通 JSON 对象原型"}),!1;if(n){const o=Object.keys(e);if(o.length!==e.length||o.some(a=>!/^(0|[1-9]\d*)$/.test(a)||Number(a)>=e.length))return t.push({path:i,message:"模板数组不能包含空位或额外属性"}),!1}return Object.getOwnPropertySymbols(e).length>0?(t.push({path:i,message:"模板不能包含 Symbol 键"}),!1):!0}function Fe(e,i,t,s){return Re.has(e)?(s.push({path:t,message:"模板不能包含可能污染原型的键"}),!1):i.get||i.set||!i.enumerable?(s.push({path:t,message:"模板不能包含访问器或不可枚举字段"}),!1):!0}function Ie(e){return e===null||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e)}function D(e,i){const t=new Set;let s=0,n=0,o=!1;const a=(f,r,d)=>{if(!o){if(++s>N){s===N+1&&i.push({path:r,message:"模板超过 JSON 节点安全上限"});return}if(d>Oe){i.push({path:r,message:"模板嵌套层级过深"});return}if(typeof f=="string"){n+=f.length,n>C&&(o=!0,i.push({path:r,message:"模板文本超过 1000 万字符的安全上限"}));return}if(!Ie(f)){if(!f||typeof f!="object"){i.push({path:r,message:"模板只允许 JSON 值,不允许函数、undefined 或非有限数字"});return}if(t.has(f)){i.push({path:r,message:"模板不能包含循环引用"});return}if(Pe(f,r,i)){t.add(f);for(const[u,p]of Object.entries(Object.getOwnPropertyDescriptors(f))){if(Array.isArray(f)&&u==="length")continue;const y=`${r}.${u}`;if(Fe(u,p,y,i)&&a(p.value,y,d+1),s>N||o)break}t.delete(f)}}}};a(e,"$",0)}function m(e,i,t,s,n=!1){const o=e[i];o===void 0&&!n||(typeof o!="string"||n&&!o.trim())&&s.push({path:`${t}.${i}`,message:n?"应为非空字符串":"应为字符串"})}function c(e,i,t,s,n=0,o=!1){const a=e[i];a===void 0&&!o||(typeof a!="number"||!Number.isFinite(a)||a<n)&&s.push({path:`${t}.${i}`,message:`应为大于等于 ${n} 的有限数字`})}function b(e,i,t,s){e[i]!==void 0&&typeof e[i]!="boolean"&&s.push({path:`${t}.${i}`,message:"应为布尔值"})}function M(e,i,t,s=!1){e!==void 0&&!Te.has(e)&&!(s&&e==="auto")&&t.push({path:i,message:`未知对齐方式${s?"(支持 auto)":""}`})}function $(e,i,t){if(e!==void 0){if(!h(e)){t.push({path:i,message:"样式应为对象"});return}M(e.align,`${i}.align`,t),e.verticalAlign!==void 0&&!["top","middle","bottom"].includes(e.verticalAlign)&&t.push({path:`${i}.verticalAlign`,message:"未知垂直对齐方式"});for(const s of["fontSize","fontSizePx","lineWidthPt","lineHeight"])c(e,s,i,t);for(const s of["letterSpacing","rotateDeg"])c(e,s,i,t,-1/0);c(e,"opacity",i,t),typeof e.opacity=="number"&&e.opacity>1&&t.push({path:`${i}.opacity`,message:"透明度不能大于 1"});for(const s of["bold","italic","underline","borderTop","borderRight","borderBottom","borderLeft"])b(e,s,i,t);for(const s of["fontFamily","color","backgroundColor","lineColor","borderColor"])m(e,s,i,t)}}function _e(e,i,t){if(e===void 0)return;if(!Array.isArray(e)){t.push({path:i,message:"参数定义应为数组"});return}const s=new Set,n=t.length;e.forEach((o,a)=>{const f=`${i}.${a}`;if(!h(o)){t.push({path:f,message:"参数定义应为对象"});return}m(o,"field",f,t,!0),typeof o.field=="string"&&(s.has(o.field)&&t.push({path:`${f}.field`,message:"参数名重复"}),s.add(o.field)),o.type!==void 0&&!["text","number","date","month","year","dateRange","select"].includes(o.type)&&t.push({path:`${f}.type`,message:"未知参数类型"});for(const r of["label","defaultValue","placeholder"])m(o,r,f,t);b(o,"required",f,t);for(const r of["minLength","maxLength"]){const d=o[r];d!==void 0&&(typeof d!="number"||!Number.isSafeInteger(d)||d<0)&&t.push({path:`${f}.${r}`,message:"长度边界应为非负整数"})}Le(o,f,t),o.options!==void 0&&(Array.isArray(o.options)?o.options.forEach((r,d)=>{const u=`${f}.options.${d}`;if(!h(r))t.push({path:u,message:"选项应为对象"});else for(const p of["label","value"])typeof r[p]!="string"&&t.push({path:`${u}.${p}`,message:"选项标签与值应为字符串(允许空白选项)"})}):t.push({path:`${f}.options`,message:"选项应为数组"}))}),t.length===n&&t.push(...J.validateReportParamDefinitions(e).map(o=>({path:o.path.replace("$.paramDefs",i),message:o.message})))}function Le(e,i,t){for(const o of["min","max"]){const a=e[o];if(a===void 0)continue;J.isReportTemporalBound(e.type,a)||e.type==="number"&&typeof a=="number"&&Number.isFinite(a)||t.push({path:`${i}.${o}`,message:"数字使用有限数字边界,日期/月/年使用对应规范字符串边界"})}const s=typeof e.min=="number"&&typeof e.max=="number"&&e.min>e.max,n=typeof e.min=="string"&&typeof e.max=="string"&&e.min>e.max;(s||n)&&t.push({path:i,message:"最小边界不能大于最大边界"}),typeof e.minLength=="number"&&typeof e.maxLength=="number"&&e.minLength>e.maxLength&&t.push({path:i,message:"最小长度不能大于最大长度"})}function te(e,i,t){if(!Array.isArray(e)||e.length===0){t.push({path:i,message:"列表至少需要一列"});return}e.every(s=>h(s)&&s.hidden===!0)&&t.push({path:i,message:"列表至少需要一列可见列"}),e.forEach((s,n)=>{const o=`${i}.${n}`;if(!h(s)){t.push({path:o,message:"列应为对象"});return}if(W(s,o,t),b(s,"hidden",o,t),P(s.visibleWhen,`${o}.visibleWhen`,t),typeof s.header!="string"&&t.push({path:`${o}.header`,message:"表头应为字符串(允许空白表头)"}),m(s,"field",o,t,!0),c(s,"widthMm",o,t,Number.MIN_VALUE,!0),$(s.style,`${o}.style`,t),$(s.headerStyle,`${o}.headerStyle`,t),M(s.align,`${o}.align`,t,!0),M(s.headerAlign,`${o}.headerAlign`,t),s.semanticRole!==void 0&&!["identifier","dimension","measure","date","text"].includes(s.semanticRole)&&t.push({path:`${o}.semanticRole`,message:"未知列语义"}),s.format!==void 0)if(!h(s.format)||!["number","percent","date"].includes(s.format.kind))t.push({path:`${o}.format`,message:"未知列格式"});else{const a=s.format.digits;a!==void 0&&(typeof a!="number"||!Number.isInteger(a)||a<0||a>100)&&t.push({path:`${o}.format.digits`,message:"小数位应为 0–100 的整数"}),b(s.format,"thousands",`${o}.format`,t),m(s.format,"pattern",`${o}.format`,t)}s.rules!==void 0&&(Array.isArray(s.rules)?s.rules.forEach((a,f)=>{const r=`${o}.rules.${f}`;if(!h(a)||!h(a.when)){t.push({path:r,message:"条件格式缺少 when 对象"});return}P(a.when,`${r}.when`,t),m(a.when,"field",`${r}.when`,t,!0),[">",">=","<","<=","==","!="].includes(a.when.op)||t.push({path:`${r}.when.op`,message:"未知条件运算符"}),typeof a.when.value!="number"&&typeof a.when.value!="string"&&t.push({path:`${r}.when.value`,message:"条件值应为数字或字符串"}),$(a.style,`${r}.style`,t)}):t.push({path:`${o}.rules`,message:"条件格式应为数组"}))})}function ie(e,i,t){if(e!==void 0){if(!h(e)){t.push({path:i,message:"分组应为对象"});return}m(e,"field",i,t,!0);for(const s of["headerTemplate","subtotalLabel"])m(e,s,i,t);for(const s of["headerStyle","subtotalStyle"])$(e[s],`${i}.${s}`,t);b(e,"keepWithNext",i,t),b(e,"repeatHeader",i,t),ee(e.aggregates,`${i}.aggregates`,t),e.subtotal!==void 0&&(!Array.isArray(e.subtotal)||e.subtotal.some(s=>typeof s!="string"))&&t.push({path:`${i}.subtotal`,message:"小计字段应为字符串数组"})}}function Ce(e,i,t){if(!(e===void 0||typeof e=="boolean")){if(!h(e)){t.push({path:i,message:"合计应为布尔值或对象"});return}m(e,"label",i,t),ee(e.aggregates,`${i}.aggregates`,t),$(e.style,`${i}.style`,t),e.fields!==void 0&&(!Array.isArray(e.fields)||e.fields.some(s=>typeof s!="string"))&&t.push({path:`${i}.fields`,message:"合计字段应为字符串数组"})}}function De(e,i,t,s){const n={kind:"rect",leftMm:0,topMm:0,widthMm:1,heightMm:1,grid:e};if(F(n,t,s,[]),V(n,t,s),!h(e)||!Array.isArray(e.cells))return;const o=e.cells,a=Array.isArray(i)?i.length:0;if(o.length*a>N){s.push({path:t,message:"表头逻辑网格超过 20 万格安全上限"});return}e.cells.length||s.push({path:`${t}.cells`,message:"表头至少需要一行"}),Array.isArray(e.colWidthsMm)&&e.colWidthsMm.length!==a&&s.push({path:`${t}.colWidthsMm`,message:"表头列宽数量应与列表列数一致"}),Array.isArray(e.rowHeightsMm)&&e.rowHeightsMm.length!==e.cells.length&&s.push({path:`${t}.rowHeightsMm`,message:"表头行高数量应与行数一致"}),Ve(o,a,t,s)}function Ve(e,i,t,s){const n=new Set;e.forEach((o,a)=>{if(!Array.isArray(o))return;let f=0;o.forEach((r,d)=>{for(;n.has(`${a}:${f}`);)f++;const u=h(r)&&typeof r.colSpan=="number"?r.colSpan:1,p=h(r)&&typeof r.rowSpan=="number"?r.rowSpan:1;(f+u>i||a+p>e.length)&&s.push({path:`${t}.cells.${a}.${d}`,message:"表头合并区域超出表头边界"});for(let y=a;y<Math.min(e.length,a+p);y++)for(let A=f;A<Math.min(i,f+u);A++)n.has(`${y}:${A}`)&&s.push({path:`${t}.cells.${a}.${d}`,message:"表头合并区域重叠"}),n.add(`${y}:${A}`);f+=u})})}function je(e,i,t){if(ve(e,i,t),ke(e.computed,`${i}.computed`,t),Se(e.matrix,`${i}.matrix`,t),e.matrix&&(e.detail||e.groupBy||Array.isArray(e.groups)&&e.groups.length||e.grandTotal)&&t.push({path:`${i}.matrix`,message:"矩阵请使用自身 totals 汇总,不能同时配置普通分组、总计或主从明细"}),P(e.rowVisibleWhen,`${i}.rowVisibleWhen`,t),e.groups!==void 0&&(!Array.isArray(e.groups)||e.groups.length>16?t.push({path:`${i}.groups`,message:"分组应为数组,最多 16 级"}):e.groups.forEach((o,a)=>ie(o,`${i}.groups.${a}`,t))),e.detail===void 0)return;const s=e.detail,n=`${i}.detail`;if(!h(s)){t.push({path:n,message:"主从关联应为对象"});return}for(const o of["dataset","parentKey","foreignKey"])m(s,o,n,t,!0);for(const o of["rowKey","revisionField","sourceTokenField"])m(s,o,n,t,s[o]!==void 0);m(s,"label",n,t),b(s,"header",n,t),c(s,"rowHeightMm",n,t,Number.MIN_VALUE),te(s.columns,`${n}.columns`,t),s.unmatched!==void 0&&s.unmatched!=="error"&&s.unmatched!=="ignore"&&t.push({path:`${n}.unmatched`,message:"未关联明细策略应为 error 或 ignore"})}function Ke(e,i,t){for(const s of["leftMm","topMm"])c(e,s,i,t,-1/0,!0);c(e,"widthMm",i,t,Number.MIN_VALUE,!0),m(e,"dataset",i,t,!0),m(e,"title",i,t);for(const s of["rowKey","revisionField","sourceTokenField"])m(e,s,i,t,e[s]!==void 0);e.headerGrid!==void 0&&De(e.headerGrid,e.columns,`${i}.headerGrid`,t),e.layout!==void 0&&e.layout!=="page"&&e.layout!=="wide"&&t.push({path:`${i}.layout`,message:"布局应为 page 或 wide"}),te(e.columns,`${i}.columns`,t);for(const s of["fontSizePt","rowHeightMm"])c(e,s,i,t,Number.MIN_VALUE);c(e,"paddingMm",i,t);for(const s of["header","headerBold","headerEveryPage","border"])b(e,s,i,t);e.cardinality!==void 0&&e.cardinality!=="record"&&t.push({path:`${i}.cardinality`,message:"单记录区域类型应为 record"}),m(e,"headerBackgroundColor",i,t),M(e.align,`${i}.align`,t,!0),M(e.headerAlign,`${i}.headerAlign`,t),$(e.headerStyle,`${i}.headerStyle`,t),je(e,i,t),ie(e.groupBy,`${i}.groupBy`,t),Ce(e.grandTotal,`${i}.grandTotal`,t)}function K(e,i,t){Array.isArray(e.richParagraphs)&&e.richParagraphs.forEach((s,n)=>{if(!h(s))return;const o=`${i}.richParagraphs.${n}`;M(s.align,`${o}.align`,t);for(const a of["lineHeight","spaceBeforeMm","spaceAfterMm","indentMm"])c(s,a,o,t);Array.isArray(s.segments)&&s.segments.forEach((a,f)=>{const r=`${o}.segments.${f}`;if(!h(a)){t.push({path:r,message:"富文本片段应为对象"});return}a.kind!==void 0&&a.kind!=="text"&&a.kind!=="field"&&t.push({path:`${r}.kind`,message:"未知富文本片段类型"});for(const d of["text","field"])m(a,d,r,t);$(a.style,`${r}.style`,t)})})}function V(e,i,t){$(e.style,`${i}.style`,t);for(const n of["text","rawText","imageData","fallbackText","nid","rkey"])m(e,n,i,t);if(e.lines!==void 0&&(!Array.isArray(e.lines)||e.lines.some(n=>typeof n!="string"))&&t.push({path:`${i}.lines`,message:"文本行应为字符串数组"}),K(e,i,t),!h(e.grid))return;const s=e.grid;c(s,"gapMm",`${i}.grid`,t),c(s,"paddingMm",`${i}.grid`,t);for(const n of["colWidthsMm","rowHeightsMm"]){const o=s[n];o!==void 0&&(!Array.isArray(o)||o.some(a=>typeof a!="number"||!Number.isFinite(a)||a<0))&&t.push({path:`${i}.grid.${n}`,message:"网格尺寸应为有限非负数字数组"})}Array.isArray(s.cells)&&s.cells.forEach((n,o)=>{Array.isArray(n)&&n.forEach((a,f)=>{const r=`${i}.grid.cells.${o}.${f}`;if(a!==null){if(!h(a)){t.push({path:r,message:"网格单元格应为对象或 null"});return}for(const d of["text","rawText","numberFormat"])m(a,d,r,t);for(const d of["colSpan","rowSpan"]){const u=a[d];u!==void 0&&(typeof u!="number"||!Number.isInteger(u)||u<=0)&&t.push({path:`${r}.${d}`,message:"跨度应为正整数"})}a.value!==void 0&&a.value!==null&&!["string","number","boolean"].includes(typeof a.value)&&t.push({path:`${r}.value`,message:"Excel 原始值应为字符串、数字、布尔值或 null"}),$(a.style,`${r}.style`,t),K(a,r,t),a.children!==void 0&&(Array.isArray(a.children)?a.children.forEach((d,u)=>{h(d)&&V(d,`${r}.children.${u}`,t)}):t.push({path:`${r}.children`,message:"嵌套组件应为数组"}))}})})}function He(e,i,t){if(!(e.flow===void 0||!Array.isArray(e.components)))try{X(e.components,e.flow)}catch(s){t.push({path:`${i}.flow`,message:s instanceof Error?s.message:String(s)})}}function se(e){const i=[],t=[];return D(e,i),i.length?{ok:!1,errors:i,warnings:t}:(h(e)?(e.schemaVersion!==void 0&&e.schemaVersion!==x.RENDER_PLAN_SCHEMA_VERSION&&i.push({path:"$.schemaVersion",message:"不支持的模板 schemaVersion"}),_e(e.params,"$.params",i),Q(e,i),!Array.isArray(e.pages)||e.pages.length===0?i.push({path:"$.pages",message:"模板至少需要一页"}):e.pages.forEach((s,n)=>{const o=`$.pages.${n}`;if(!h(s)){i.push({path:o,message:"页应为对象"});return}c(s,"widthMm",o,i,Number.MIN_VALUE,!0),c(s,"heightMm",o,i,Number.MIN_VALUE,!0),s.layout!==void 0&&s.layout!=="page"&&s.layout!=="wide"&&i.push({path:`${o}.layout`,message:"布局应为 page 或 wide"}),typeof s.heightMm=="number"&&s.heightMm>=5e3&&i.push({path:`${o}.heightMm`,message:"页高应小于 5000mm"});for(const a of["marginTopMm","marginBottomMm","marginLeftMm","marginRightMm"])c(s,a,o,i);typeof s.widthMm=="number"&&Number(s.marginLeftMm??0)+Number(s.marginRightMm??0)>=s.widthMm&&i.push({path:o,message:"横向页边距占满页面"}),typeof s.heightMm=="number"&&Number(s.marginTopMm??0)+Number(s.marginBottomMm??0)>=s.heightMm&&i.push({path:o,message:"纵向页边距占满页面"}),Array.isArray(s.components)?s.components.forEach((a,f)=>{const r=`${o}.components.${f}`;h(a)&&a.kind==="list"?Ke(a,r,i):(F(a,r,i,t),h(a)&&V(a,r,i))}):i.push({path:`${o}.components`,message:"组件应为数组"}),He(s,o,i)})):i.push({path:"$",message:"模板应为对象"}),{ok:i.length===0,errors:i,warnings:t})}function ne(e){const i=[],t=[];if(D(e,i),i.length)return{ok:!1,errors:i,warnings:t};if(!h(e))i.push({path:"$",message:"模板文档应为对象"});else{for(const n of Object.keys(e))xe.has(n)||i.push({path:`$.${n}`,message:"模板文档存在未知字段;只保存模板与描述,不保存取数或业务数据"});e.schemaVersion!==L&&i.push({path:"$.schemaVersion",message:"不支持的模板文档版本"});for(const n of["id","name"])m(e,n,"$",i,!0);for(const n of["revision","description"])m(e,n,"$",i);const s=se(e.template);i.push(...s.errors.map(n=>({...n,path:`$.template${n.path.slice(1)}`}))),t.push(...s.warnings.map(n=>({...n,path:`$.template${n.path.slice(1)}`})))}return{ok:i.length===0,errors:i,warnings:t}}function T(e){const i=ne(e);if(!i.ok)throw new w(i.errors)}function Je(e){const i=[];if(D(e,i),i.length)throw new w(i);const t={...e,schemaVersion:e.schemaVersion??L};return T(t),R(t)}function We(e){let i=e;if(typeof e=="string"){if(e.length>C)throw new w([{path:"$",message:"模板 JSON 超过 1000 万字符的导出/导入上限"}]);try{i=JSON.parse(e)}catch{throw new w([{path:"$",message:"模板 JSON 语法无效"}])}}return T(i),R(i)}function Ge(e){T(e);const i=JSON.stringify(e,null,2);if(i.length>C)throw new w([{path:"$",message:"模板 JSON 超过 1000 万字符的导出/导入上限"}]);return i}function R(e){return JSON.parse(JSON.stringify(e))}function Ue(e=[]){const i=new Map,t={get:s=>{const n=i.get(s);return n?R(n):void 0},list:()=>Array.from(i.values(),({template:s,...n})=>({...n})),register:(s,n={})=>{if(T(s),i.has(s.id)&&!n.replace)throw new w([{path:"$.id",message:`模板 ID ${s.id} 已注册;更新需显式 replace:true`}]);i.set(s.id,R(s))},remove:s=>i.delete(s)};for(const s of e)t.register(s);return t}exports.REPORT_TEMPLATE_DOCUMENT_VERSION=L;exports.ReportTemplateError=w;exports.assertRenderPlan=ye;exports.createTemplateRegistry=Ue;exports.defineReportTemplate=Je;exports.parseReportTemplate=We;exports.reportFlowGroups=be;exports.serializeReportTemplate=Ge;exports.validateComponent=F;exports.validatePage=B;exports.validateRenderPlan=z;exports.validateReportPageFlow=X;exports.validateReportTemplate=se;exports.validateReportTemplateDocument=ne;exports.validateTemplateRepeat=Q;
|
|
1
|
+
"use strict";const oe=require("./matrix-gTHpDTGm.cjs"),H=require("./computed-C2GD3XcE.cjs"),x=require("./component-tree-DkGLEfZC.cjs"),ae=require("./code-options-BUTChiZZ.cjs"),J=require("./param-validation-C3HlcLLO.cjs"),j=require("./tree-CLpxYbKa.cjs");function fe(e,i,t){e!==void 0&&(typeof e!="string"||!e.trim()||e.length>4096)&&t.push({path:i,message:"来源范围应为不超过 4096 字符的非空字符串"})}function W(e,i,t){e.editable!==void 0&&typeof e.editable!="boolean"&&t.push({path:`${i}.editable`,message:"编辑控制应为布尔值"}),e.valueType!==void 0&&!["text","number","boolean"].includes(e.valueType)&&t.push({path:`${i}.valueType`,message:"编辑类型应为 text、number 或 boolean"})}function re(e,i,t){W(e,i,t),e.indentMm!==void 0&&(typeof e.indentMm!="number"||!Number.isFinite(e.indentMm)||e.indentMm<0)&&t.push({path:`${i}.indentMm`,message:"单元格缩进应为有限非负数"}),e.derived!==void 0&&typeof e.derived!="boolean"&&t.push({path:`${i}.derived`,message:"派生结果标记应为布尔值"}),G(e.source,`${i}.source`,t,!0),e.formula!==void 0&&typeof e.formula!="string"&&t.push({path:`${i}.formula`,message:"单元格公式应为字符串"})}function G(e,i,t,s=!1){if(e===void 0)return;if(!e||typeof e!="object"||Array.isArray(e)){t.push({path:i,message:"业务来源应为对象"});return}const n=e;fe(n.sourceScope,`${i}.sourceScope`,t);for(const o of["datasetId",...s?["field"]:[]])(typeof n[o]!="string"||!n[o].trim())&&t.push({path:`${i}.${o}`,message:"业务标识应为非空字符串"});for(const o of["rowKey","revision"]){const a=n[o];a===void 0&&!(s&&o==="rowKey")||typeof a!="string"&&!(typeof a=="number"&&Number.isFinite(a))&&t.push({path:`${i}.${o}`,message:"业务键及修订号应为字符串或有限数字"})}n.sourceToken!==void 0&&typeof n.sourceToken!="string"&&t.push({path:`${i}.sourceToken`,message:"来源令牌应为字符串"})}const de=new Set(["text","image","barcode","qrcode","chart","line","rect","ellipse"]);function g(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function k(e){return e===null?"null":typeof e=="string"?JSON.stringify(e.slice(0,120)):["number","boolean","undefined"].includes(typeof e)?String(e):`[${typeof e}]`}function ue(e,i,t,s){const n=e[i];(typeof n!="number"||!Number.isFinite(n))&&s.push({path:`${t}.${i}`,message:`应为有限数字,实际 ${k(n)}`})}function he(e,i,t){if(e!==void 0){const s=`${i}.table`;if(!g(e))t.push({path:s,message:"逻辑表来源应为对象"});else{G(e.source,`${s}.source`,t),(typeof e.id!="string"||!e.id.trim())&&t.push({path:`${s}.id`,message:"逻辑表 ID 应为非空字符串"});const n=e.role;["header","body","group-header","subtotal","grand-total"].includes(n)||t.push({path:`${s}.role`,message:"未知逻辑表行角色"});const o=e.rowIndex;(typeof o!="number"||!Number.isInteger(o)||(n==="header"?o!==-1:o<0))&&t.push({path:`${s}.rowIndex`,message:"表头索引应为 -1,内容行索引应为非负整数"}),(!Array.isArray(e.columnKeys)||e.columnKeys.some(a=>typeof a!="string"))&&t.push({path:`${s}.columnKeys`,message:"逻辑列字段应为字符串数组"}),e.layout!==void 0&&e.layout!=="page"&&e.layout!=="wide"&&t.push({path:`${s}.layout`,message:"布局应为 page 或 wide"}),e.title!==void 0&&typeof e.title!="string"&&t.push({path:`${s}.title`,message:"逻辑表名称应为字符串"})}}}function me(e,i,t,s){if(e!==void 0)if(!g(e)||!Array.isArray(e.cells))t.push({path:`${i}.grid.cells`,message:"grid.cells 应为二维数组"});else{const n=e.paddingMm;n!==void 0&&(typeof n!="number"||!Number.isFinite(n)||n<0)&&t.push({path:`${i}.grid.paddingMm`,message:"单元格内距应为有限非负数"}),e.cells.forEach((o,a)=>{if(!Array.isArray(o)){t.push({path:`${i}.grid.cells.${a}`,message:"行应为数组"});return}o.forEach((f,r)=>{if(f==null)return;const d=`${i}.grid.cells.${a}.${r}`;if(!g(f)){t.push({path:d,message:"网格单元格应为对象或 null"});return}re(f,d,t),U(f.richParagraphs,d,t),Array.isArray(f.children)&&f.children.forEach((u,p)=>{I(u,`${i}.grid.cells.${a}.${r}.children.${p}`,t,s)})})})}}function S(e,i,t,s){e!==void 0&&!i.includes(e)&&s.push({path:t,message:"未知富文本属性值"})}function O(e,i,t,s,n=0){for(const o of i){const a=e[o];a!==void 0&&(typeof a!="number"||!Number.isFinite(a)||a<n)&&s.push({path:`${t}.${o}`,message:"富文本数值应为范围内有限数字"})}}function ce(e,i,t){if(e!==void 0){if(!g(e)){t.push({path:i,message:"富文本样式应为对象"});return}for(const s of["fontFamily","color","backgroundColor","lineColor","borderColor"])e[s]!==void 0&&typeof e[s]!="string"&&t.push({path:`${i}.${s}`,message:"富文本样式应为字符串"});for(const s of["bold","italic","underline","borderTop","borderRight","borderBottom","borderLeft"])e[s]!==void 0&&typeof e[s]!="boolean"&&t.push({path:`${i}.${s}`,message:"富文本样式应为布尔值"});O(e,["fontSize","fontSizePx","lineWidthPt","lineHeight","opacity"],i,t),O(e,["letterSpacing","rotateDeg"],i,t,-1/0),typeof e.opacity=="number"&&e.opacity>1&&t.push({path:`${i}.opacity`,message:"透明度不能大于1"}),S(e.align,["left","center","right","justify"],`${i}.align`,t),S(e.verticalAlign,["top","middle","bottom"],`${i}.verticalAlign`,t)}}function ge(e,i,t){if(!g(e)){t.push({path:i,message:"富文本片段应为对象"});return}S(e.kind,["text","field"],`${i}.kind`,t);for(const s of["text","field"])e[s]!==void 0&&typeof e[s]!="string"&&t.push({path:`${i}.${s}`,message:"富文本内容应为字符串"});ce(e.style,`${i}.style`,t)}function U(e,i,t){if(e!==void 0){if(!Array.isArray(e)){t.push({path:`${i}.richParagraphs`,message:"richParagraphs 应为数组"});return}e.forEach((s,n)=>{const o=`${i}.richParagraphs.${n}`;if(!g(s)||!Array.isArray(s.segments)){t.push({path:o,message:"段落缺少 segments 数组"});return}S(s.align,["left","center","right","justify"],`${o}.align`,t),O(s,["lineHeight","spaceBeforeMm","spaceAfterMm","indentMm"],o,t),s.segments.forEach((a,f)=>ge(a,`${o}.segments.${f}`,t))})}}function F(e,i,t,s=[]){const n=x.componentTreeIssue([e],i);if(n){t.push(n);return}I(e,i,t,s)}function I(e,i,t,s=[]){if(!g(e)){t.push({path:i,message:"组件应为对象"});return}const n=e.kind;typeof n!="string"?t.push({path:`${i}.kind`,message:"组件缺少 kind 字符串"}):de.has(n)||s.push({path:`${i}.kind`,message:`未知组件类型 ${k(n)},将以兜底方式渲染`});for(const o of["leftMm","topMm","widthMm","heightMm"])ue(e,o,i,t);typeof e.leftMm=="number"&&e.leftMm<-100&&t.push({path:`${i}.leftMm`,message:"几何数值异常(leftMm<-100)"});for(const o of["widthMm","heightMm"])typeof e[o]=="number"&&e[o]<0&&t.push({path:`${i}.${o}`,message:"组件尺寸不能为负数"});he(e.table,i,t),pe(e.code,n,i,t),e.pageAnchor!==void 0&&!["header","footer"].includes(e.pageAnchor)&&t.push({path:`${i}.pageAnchor`,message:"页面锚点应为 header 或 footer"}),e.lineDirection!==void 0&&!["down","up"].includes(e.lineDirection)&&t.push({path:`${i}.lineDirection`,message:"线段方向应为 down 或 up"}),me(e.grid,i,t,s),U(e.richParagraphs,i,t)}function pe(e,i,t,s){if(e!==void 0)for(const n of ae.codeOptionIssues(e,i))s.push({path:`${t}.code${n.path?`.${n.path}`:""}`,message:n.message})}function q(e,i,t){if(!g(e))return;e.binding!==void 0&&t.push({path:`${i}.binding`,message:"渲染计划不允许未解析字段绑定"});const s=e.grid;!g(s)||!Array.isArray(s.cells)||s.cells.forEach((n,o)=>{Array.isArray(n)&&n.forEach((a,f)=>{!g(a)||!Array.isArray(a.children)||a.children.forEach((r,d)=>q(r,`${i}.grid.cells.${o}.${f}.children.${d}`,t))})})}function B(e,i,t,s=[]){if(!g(e)){t.push({path:i,message:"页应为对象"});return}const n=e.pageWidthMm,o=e.pageHeightMm;(typeof n!="number"||!Number.isFinite(n)||n<=0)&&t.push({path:`${i}.pageWidthMm`,message:`页宽非法: ${k(n)}`}),(typeof o!="number"||!(o>0&&o<5e3))&&t.push({path:`${i}.pageHeightMm`,message:`页高非法: ${k(o)}`}),e.layout!==void 0&&e.layout!=="page"&&e.layout!=="wide"&&t.push({path:`${i}.layout`,message:"布局应为 page 或 wide"});const a=e.components;if(!Array.isArray(a))t.push({path:`${i}.components`,message:"components 应为数组"});else if(Array.isArray(a)){const f=x.componentTreeIssue(a,`${i}.components`);if(f){t.push(f);return}a.forEach((r,d)=>{I(r,`${i}.components.${d}`,t,s),q(r,`${i}.components.${d}`,t)})}}function z(e){const i=[],t=[],s=g(e)?e.pages:void 0;if(g(e)&&e.requiresRecalculation!==void 0&&typeof e.requiresRecalculation!="boolean"&&i.push({path:"$.requiresRecalculation",message:"重算能力要求应为布尔值"}),!Array.isArray(s))i.push({path:"$.pages",message:e==null?"渲染计划为空":"渲染计划缺少 pages 数组"});else{const n=x.renderTreeIssue(s);if(n)return{ok:!1,errors:[...i,n],warnings:t};s.forEach((a,f)=>B(a,`$.pages.${f}`,i,t)),s.length>2e3&&t.push({path:"$.pages",message:`页数异常大(${s.length} 页),渲染与打印耗时可能显著增加`});const o=s.reduce((a,f)=>a+(g(f)&&Array.isArray(f.components)?f.components.length:0),0);o>5e4&&t.push({path:"$.pages",message:`组件总数异常大(${o} 个),可能触发浏览器性能限制`})}return{ok:i.length===0,errors:i,warnings:t}}function ye(e){const i=z(e);if(!i.ok){const t=i.errors.slice(0,3).map(s=>`${s.path}: ${s.message}`).join("; ");throw new Error(`渲染计划校验失败(${i.errors.length} 处): ${t}`)}return e.pages}function _(e){return e.kind==="list"?e.id:e.nid}function le(e){return e.kind==="list"?!1:e.pageAnchor!==void 0||e.kind==="text"&&typeof e.text=="string"&&/\{(?:page|totalPages)\}/.test(e.text)}function $e(e,i){const t=e.filter(n=>i.componentIds.includes(_(n)??""));if(t.filter(n=>n.kind==="list"&&n.cardinality!=="record").length&&t.length!==1)throw new Error("纵向重复区域必须独占流式分段,不能与静态或单记录区域并排");for(const n of t){const o=n.kind==="list"?n.topMm+(n.rowHeightMm??0):n.topMm+n.heightMm;if(n.topMm<i.topMm-.001||o>i.topMm+i.heightMm+.001)throw new Error("流式分段应完整包含其组件的原始纵向范围")}}function be(e,i){if(!i)return e.map(s=>({components:[s]}));const t=new Map(e.map(s=>[_(s),s]));return i.bands.map(s=>({band:s,components:s.componentIds.map(n=>{const o=t.get(n);if(!o)throw new Error(`流式区域引用不存在的组件:${n}`);return o})}))}function X(e,i){if(!i||!Array.isArray(i.bands)||!i.bands.length||i.bands.length>1e4)throw new Error("流式排版应包含 1–10000 个区域");const t=new Set,s=new Set;for(const n of e){if(le(n))continue;const o=_(n);if(!o||t.has(o))throw new Error("流式排版组件应具有唯一标识");t.add(o)}if(Ae(e,i,t,s),s.size!==t.size)throw new Error("流式排版必须显式包含每个非锚点组件")}function Ae(e,i,t,s){let n=-1/0;for(const o of i.bands){if(!Number.isFinite(o.topMm)||!Number.isFinite(o.heightMm)||o.topMm<0||o.heightMm<=0||o.topMm<n-.001)throw new Error("流式区域应按原始位置排序,尺寸有效且不重叠");if(!Array.isArray(o.componentIds)||!o.componentIds.length)throw new Error("流式区域不能没有组件");for(const a of o.componentIds){if(!t.has(a)||s.has(a))throw new Error(`流式区域组件缺失、重复或包含页锚点:${a}`);s.add(a)}$e(e,o),n=o.topMm+o.heightMm}}const we=new Set(["__proto__","prototype","constructor"]);function l(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function E(e){return typeof e=="string"&&!!e.trim()&&!we.has(e)}function v(e,i,t,s){for(const n of Object.keys(e))i.includes(n)||s.push({path:`${t}.${n}`,message:"存在未知配置字段"})}function Me(e,i,t){if(e!==void 0){if(!l(e)||!["number","percent","date"].includes(String(e.kind))){t.push({path:i,message:"绑定格式应为 number、percent 或 date"});return}v(e,e.kind==="date"?["kind","pattern"]:e.kind==="number"?["kind","digits","thousands"]:["kind","digits"],i,t),e.digits!==void 0&&(!Number.isInteger(e.digits)||Number(e.digits)<0||Number(e.digits)>100)&&t.push({path:`${i}.digits`,message:"精度应为 0..100 整数"}),e.thousands!==void 0&&typeof e.thousands!="boolean"&&t.push({path:`${i}.thousands`,message:"千分位开关应为布尔值"}),e.pattern!==void 0&&typeof e.pattern!="string"&&t.push({path:`${i}.pattern`,message:"日期格式应为字符串"})}}function Ee(e,i,t){const s=e.binding;if(s===void 0)return;const n=`${i}.binding`;if(!l(s)){t.push({path:n,message:"字段绑定应为对象"});return}(!["text","image","barcode","qrcode"].includes(String(e.kind))||e.grid!==void 0)&&t.push({path:n,message:"绑定仅支持独立文本、图片、条码与二维码组件"}),v(s,["field","format","prefix","suffix","emptyText"],n,t),E(s.field)||t.push({path:`${n}.field`,message:"绑定字段应为安全的非空字段名(按字面读取自有字段)"});for(const o of["prefix","suffix","emptyText"])s[o]!==void 0&&typeof s[o]!="string"&&t.push({path:`${n}.${o}`,message:"应为字符串"});Me(s.format,`${n}.format`,t),e.kind==="image"&&["format","prefix","suffix"].some(o=>s[o]!==void 0)&&t.push({path:n,message:"图片绑定直接读取 PNG/JPEG data URL,不支持文本格式或前后缀"})}function Ne(e,i){if(!l(e)){i.push({path:"$.repeat",message:"逐记录配置应为对象"});return}v(e,["dataset","rowKey","copies"],"$.repeat",i),E(e.dataset)||i.push({path:"$.repeat.dataset",message:"数据集应为安全的非空名称"}),e.rowKey!==void 0&&!E(e.rowKey)&&i.push({path:"$.repeat.rowKey",message:"业务主键应为安全的非空字段名"});const t=e.copies;t!==void 0&&(l(t)?(v(t,["field"],"$.repeat.copies",i),E(t.field)||i.push({path:"$.repeat.copies.field",message:"复制数字段应为安全的非空字段名"})):(!Number.isSafeInteger(t)||Number(t)<1||Number(t)>1e3)&&i.push({path:"$.repeat.copies",message:"每条记录复制数应为 1..1000 整数"}))}function Y(e,i,t,s){if(!l(e))return;Ee(e,i,s),e.binding!==void 0&&!t&&s.push({path:`${i}.binding`,message:"字段绑定需要模板 repeat 数据集;普通报表请使用列表字段"}),t&&e.kind==="list"&&s.push({path:i,message:"逐记录标签使用固定组件;动态列表请使用普通报表模板"});const n=e.grid;l(n)&&Array.isArray(n.cells)&&n.cells.forEach((o,a)=>{Array.isArray(o)&&o.forEach((f,r)=>{l(f)&&Array.isArray(f.children)&&f.children.forEach((d,u)=>Y(d,`${i}.grid.cells.${a}.${r}.children.${u}`,t,s))})})}function Q(e,i){const t=e.repeat!==void 0;t&&Ne(e.repeat,i),Array.isArray(e.pages)&&e.pages.forEach((s,n)=>{if(!l(s))return;const o=`$.pages.${n}`;t&&(s.layout==="wide"||s.flow!==void 0)&&i.push({path:o,message:"逐记录标签仅支持固定尺寸页面,不支持宽表或流式分区"}),Array.isArray(s.components)&&s.components.forEach((a,f)=>{const r=`${o}.components.${f}`;if(Y(a,r,t,i),!t||!l(a))return;const{leftMm:d,topMm:u,widthMm:p,heightMm:y}=a;[d,u,p,y,s.widthMm,s.heightMm].every(A=>typeof A=="number"&&Number.isFinite(A))&&(Number(d)<0||Number(u)<0||Number(d)+Number(p)>Number(s.widthMm)+.001||Number(u)+Number(y)>Number(s.heightMm)+.001)&&i.push({path:r,message:"标签组件超出纸张边界,请调整位置或尺寸"})})})}function Z(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function P(e,i,t){if(e!==void 0){if(!Z(e)){t.push({path:i,message:"条件应为对象"});return}(typeof e.field!="string"||!e.field.trim())&&t.push({path:`${i}.field`,message:"条件需要字段"}),e.numeric!==void 0&&e.numeric!=="number"&&e.numeric!=="decimal"&&t.push({path:`${i}.numeric`,message:"未知条件数值模式"}),[">",">=","<","<=","==","!="].includes(e.op)||t.push({path:`${i}.op`,message:"未知条件运算符"}),typeof e.value!="string"&&!(typeof e.value=="number"&&Number.isFinite(e.value))&&t.push({path:`${i}.value`,message:"条件值应为字符串或有限数字"})}}function ee(e,i,t){if(e===void 0)return;if(!Array.isArray(e)||e.length>2048){t.push({path:i,message:"聚合应为数组且最多 2048 项"});return}const s=new Set;e.forEach((n,o)=>{const a=`${i}.${o}`;if(!Z(n)){t.push({path:a,message:"聚合应为对象"});return}const f=n.field;typeof f!="string"||!f.trim()||s.has(f)?t.push({path:`${a}.field`,message:"聚合输出字段应非空且唯一"}):s.add(f),n.numeric!==void 0&&n.numeric!=="number"&&n.numeric!=="decimal"&&t.push({path:`${a}.numeric`,message:"数值模式应为 number 或 decimal"}),n.digits!==void 0&&(!Number.isInteger(n.digits)||Number(n.digits)<0||Number(n.digits)>100)&&t.push({path:`${a}.digits`,message:"小数位应为 0–100 的整数"});try{H.createAggregateAccumulator({...n,field:n.valueField??f})}catch(r){t.push({path:a,message:r instanceof Error?r.message:String(r)})}})}function ke(e,i,t){if(e===void 0)return;const s=H.validateComputedFields(e);for(const n of s.errors)t.push({path:i,message:n})}function Se(e,i,t){if(e!==void 0)try{oe.validateMatrixOptions(e)}catch(s){t.push({path:i,message:s instanceof Error?s.message:String(s)})}}function ve(e,i,t){if(e.tree===void 0)return;const s=`${i}.tree`;try{j.validateTreeOptions(e.tree);const n=e.tree;if(e.matrix||e.detail||e.groupBy||Array.isArray(e.groups)&&e.groups.length||e.rowVisibleWhen)throw new Error("树形布局不能同时配置普通分组、矩阵、主从或行可见条件");if(e.rowKey!==void 0&&e.rowKey!==n.idField)throw new Error("树形 rowKey 应与 idField 一致");if(!Array.isArray(e.columns)||!e.columns.some(o=>o&&o.field===n.labelField&&!o.hidden))throw new Error("树形布局需要可见的标签列");Array.isArray(e.computed)&&j.validateTreeComputed(n,e.computed)}catch(n){t.push({path:s,message:n instanceof Error?n.message:String(n)})}}const L="1.0";class w extends Error{constructor(i){super(`模板校验失败:${i.slice(0,3).map(t=>`${t.path}: ${t.message}`).join("; ")}`),this.errors=i,this.name="ReportTemplateError"}}const Re=new Set(["__proto__","prototype","constructor"]),xe=new Set(["schemaVersion","id","name","revision","description","template"]),Te=new Set(["left","center","right","justify"]),N=2e5,Oe=64,C=1e7;function h(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function Pe(e,i,t){const s=Object.getPrototypeOf(e),n=Array.isArray(e);if(n?s!==Array.prototype:s!==Object.prototype&&s!==null)return t.push({path:i,message:"模板对象必须使用普通 JSON 对象原型"}),!1;if(n){const o=Object.keys(e);if(o.length!==e.length||o.some(a=>!/^(0|[1-9]\d*)$/.test(a)||Number(a)>=e.length))return t.push({path:i,message:"模板数组不能包含空位或额外属性"}),!1}return Object.getOwnPropertySymbols(e).length>0?(t.push({path:i,message:"模板不能包含 Symbol 键"}),!1):!0}function Fe(e,i,t,s){return Re.has(e)?(s.push({path:t,message:"模板不能包含可能污染原型的键"}),!1):i.get||i.set||!i.enumerable?(s.push({path:t,message:"模板不能包含访问器或不可枚举字段"}),!1):!0}function Ie(e){return e===null||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e)}function D(e,i){const t=new Set;let s=0,n=0,o=!1;const a=(f,r,d)=>{if(!o){if(++s>N){s===N+1&&i.push({path:r,message:"模板超过 JSON 节点安全上限"});return}if(d>Oe){i.push({path:r,message:"模板嵌套层级过深"});return}if(typeof f=="string"){n+=f.length,n>C&&(o=!0,i.push({path:r,message:"模板文本超过 1000 万字符的安全上限"}));return}if(!Ie(f)){if(!f||typeof f!="object"){i.push({path:r,message:"模板只允许 JSON 值,不允许函数、undefined 或非有限数字"});return}if(t.has(f)){i.push({path:r,message:"模板不能包含循环引用"});return}if(Pe(f,r,i)){t.add(f);for(const[u,p]of Object.entries(Object.getOwnPropertyDescriptors(f))){if(Array.isArray(f)&&u==="length")continue;const y=`${r}.${u}`;if(Fe(u,p,y,i)&&a(p.value,y,d+1),s>N||o)break}t.delete(f)}}}};a(e,"$",0)}function m(e,i,t,s,n=!1){const o=e[i];o===void 0&&!n||(typeof o!="string"||n&&!o.trim())&&s.push({path:`${t}.${i}`,message:n?"应为非空字符串":"应为字符串"})}function c(e,i,t,s,n=0,o=!1){const a=e[i];a===void 0&&!o||(typeof a!="number"||!Number.isFinite(a)||a<n)&&s.push({path:`${t}.${i}`,message:`应为大于等于 ${n} 的有限数字`})}function b(e,i,t,s){e[i]!==void 0&&typeof e[i]!="boolean"&&s.push({path:`${t}.${i}`,message:"应为布尔值"})}function M(e,i,t,s=!1){e!==void 0&&!Te.has(e)&&!(s&&e==="auto")&&t.push({path:i,message:`未知对齐方式${s?"(支持 auto)":""}`})}function $(e,i,t){if(e!==void 0){if(!h(e)){t.push({path:i,message:"样式应为对象"});return}M(e.align,`${i}.align`,t),e.verticalAlign!==void 0&&!["top","middle","bottom"].includes(e.verticalAlign)&&t.push({path:`${i}.verticalAlign`,message:"未知垂直对齐方式"});for(const s of["fontSize","fontSizePx","lineWidthPt","lineHeight"])c(e,s,i,t);for(const s of["letterSpacing","rotateDeg"])c(e,s,i,t,-1/0);c(e,"opacity",i,t),typeof e.opacity=="number"&&e.opacity>1&&t.push({path:`${i}.opacity`,message:"透明度不能大于 1"});for(const s of["bold","italic","underline","borderTop","borderRight","borderBottom","borderLeft"])b(e,s,i,t);for(const s of["fontFamily","color","backgroundColor","lineColor","borderColor"])m(e,s,i,t)}}function _e(e,i,t){if(e===void 0)return;if(!Array.isArray(e)){t.push({path:i,message:"参数定义应为数组"});return}const s=new Set,n=t.length;e.forEach((o,a)=>{const f=`${i}.${a}`;if(!h(o)){t.push({path:f,message:"参数定义应为对象"});return}m(o,"field",f,t,!0),typeof o.field=="string"&&(s.has(o.field)&&t.push({path:`${f}.field`,message:"参数名重复"}),s.add(o.field)),o.type!==void 0&&!["text","number","date","month","year","dateRange","select"].includes(o.type)&&t.push({path:`${f}.type`,message:"未知参数类型"});for(const r of["label","defaultValue","placeholder"])m(o,r,f,t);b(o,"required",f,t);for(const r of["minLength","maxLength"]){const d=o[r];d!==void 0&&(typeof d!="number"||!Number.isSafeInteger(d)||d<0)&&t.push({path:`${f}.${r}`,message:"长度边界应为非负整数"})}Le(o,f,t),o.options!==void 0&&(Array.isArray(o.options)?o.options.forEach((r,d)=>{const u=`${f}.options.${d}`;if(!h(r))t.push({path:u,message:"选项应为对象"});else for(const p of["label","value"])typeof r[p]!="string"&&t.push({path:`${u}.${p}`,message:"选项标签与值应为字符串(允许空白选项)"})}):t.push({path:`${f}.options`,message:"选项应为数组"}))}),t.length===n&&t.push(...J.validateReportParamDefinitions(e).map(o=>({path:o.path.replace("$.paramDefs",i),message:o.message})))}function Le(e,i,t){for(const o of["min","max"]){const a=e[o];if(a===void 0)continue;J.isReportTemporalBound(e.type,a)||e.type==="number"&&typeof a=="number"&&Number.isFinite(a)||t.push({path:`${i}.${o}`,message:"数字使用有限数字边界,日期/月/年使用对应规范字符串边界"})}const s=typeof e.min=="number"&&typeof e.max=="number"&&e.min>e.max,n=typeof e.min=="string"&&typeof e.max=="string"&&e.min>e.max;(s||n)&&t.push({path:i,message:"最小边界不能大于最大边界"}),typeof e.minLength=="number"&&typeof e.maxLength=="number"&&e.minLength>e.maxLength&&t.push({path:i,message:"最小长度不能大于最大长度"})}function te(e,i,t){if(!Array.isArray(e)||e.length===0){t.push({path:i,message:"列表至少需要一列"});return}e.every(s=>h(s)&&s.hidden===!0)&&t.push({path:i,message:"列表至少需要一列可见列"}),e.forEach((s,n)=>{const o=`${i}.${n}`;if(!h(s)){t.push({path:o,message:"列应为对象"});return}if(W(s,o,t),b(s,"hidden",o,t),P(s.visibleWhen,`${o}.visibleWhen`,t),typeof s.header!="string"&&t.push({path:`${o}.header`,message:"表头应为字符串(允许空白表头)"}),m(s,"field",o,t,!0),c(s,"widthMm",o,t,Number.MIN_VALUE,!0),$(s.style,`${o}.style`,t),$(s.headerStyle,`${o}.headerStyle`,t),M(s.align,`${o}.align`,t,!0),M(s.headerAlign,`${o}.headerAlign`,t),s.semanticRole!==void 0&&!["identifier","dimension","measure","date","text"].includes(s.semanticRole)&&t.push({path:`${o}.semanticRole`,message:"未知列语义"}),s.format!==void 0)if(!h(s.format)||!["number","percent","date"].includes(s.format.kind))t.push({path:`${o}.format`,message:"未知列格式"});else{const a=s.format.digits;a!==void 0&&(typeof a!="number"||!Number.isInteger(a)||a<0||a>100)&&t.push({path:`${o}.format.digits`,message:"小数位应为 0–100 的整数"}),b(s.format,"thousands",`${o}.format`,t),m(s.format,"pattern",`${o}.format`,t)}s.rules!==void 0&&(Array.isArray(s.rules)?s.rules.forEach((a,f)=>{const r=`${o}.rules.${f}`;if(!h(a)||!h(a.when)){t.push({path:r,message:"条件格式缺少 when 对象"});return}P(a.when,`${r}.when`,t),m(a.when,"field",`${r}.when`,t,!0),[">",">=","<","<=","==","!="].includes(a.when.op)||t.push({path:`${r}.when.op`,message:"未知条件运算符"}),typeof a.when.value!="number"&&typeof a.when.value!="string"&&t.push({path:`${r}.when.value`,message:"条件值应为数字或字符串"}),$(a.style,`${r}.style`,t)}):t.push({path:`${o}.rules`,message:"条件格式应为数组"}))})}function ie(e,i,t){if(e!==void 0){if(!h(e)){t.push({path:i,message:"分组应为对象"});return}m(e,"field",i,t,!0);for(const s of["headerTemplate","subtotalLabel"])m(e,s,i,t);for(const s of["headerStyle","subtotalStyle"])$(e[s],`${i}.${s}`,t);b(e,"keepWithNext",i,t),b(e,"repeatHeader",i,t),ee(e.aggregates,`${i}.aggregates`,t),e.subtotal!==void 0&&(!Array.isArray(e.subtotal)||e.subtotal.some(s=>typeof s!="string"))&&t.push({path:`${i}.subtotal`,message:"小计字段应为字符串数组"})}}function Ce(e,i,t){if(!(e===void 0||typeof e=="boolean")){if(!h(e)){t.push({path:i,message:"合计应为布尔值或对象"});return}m(e,"label",i,t),ee(e.aggregates,`${i}.aggregates`,t),$(e.style,`${i}.style`,t),e.fields!==void 0&&(!Array.isArray(e.fields)||e.fields.some(s=>typeof s!="string"))&&t.push({path:`${i}.fields`,message:"合计字段应为字符串数组"})}}function De(e,i,t,s){const n={kind:"rect",leftMm:0,topMm:0,widthMm:1,heightMm:1,grid:e};if(F(n,t,s,[]),V(n,t,s),!h(e)||!Array.isArray(e.cells))return;const o=e.cells,a=Array.isArray(i)?i.length:0;if(o.length*a>N){s.push({path:t,message:"表头逻辑网格超过 20 万格安全上限"});return}e.cells.length||s.push({path:`${t}.cells`,message:"表头至少需要一行"}),Array.isArray(e.colWidthsMm)&&e.colWidthsMm.length!==a&&s.push({path:`${t}.colWidthsMm`,message:"表头列宽数量应与列表列数一致"}),Array.isArray(e.rowHeightsMm)&&e.rowHeightsMm.length!==e.cells.length&&s.push({path:`${t}.rowHeightsMm`,message:"表头行高数量应与行数一致"}),Ve(o,a,t,s)}function Ve(e,i,t,s){const n=new Set;e.forEach((o,a)=>{if(!Array.isArray(o))return;let f=0;o.forEach((r,d)=>{for(;n.has(`${a}:${f}`);)f++;const u=h(r)&&typeof r.colSpan=="number"?r.colSpan:1,p=h(r)&&typeof r.rowSpan=="number"?r.rowSpan:1;(f+u>i||a+p>e.length)&&s.push({path:`${t}.cells.${a}.${d}`,message:"表头合并区域超出表头边界"});for(let y=a;y<Math.min(e.length,a+p);y++)for(let A=f;A<Math.min(i,f+u);A++)n.has(`${y}:${A}`)&&s.push({path:`${t}.cells.${a}.${d}`,message:"表头合并区域重叠"}),n.add(`${y}:${A}`);f+=u})})}function je(e,i,t){if(ve(e,i,t),ke(e.computed,`${i}.computed`,t),Se(e.matrix,`${i}.matrix`,t),e.matrix&&(e.detail||e.groupBy||Array.isArray(e.groups)&&e.groups.length||e.grandTotal)&&t.push({path:`${i}.matrix`,message:"矩阵请使用自身 totals 汇总,不能同时配置普通分组、总计或主从明细"}),P(e.rowVisibleWhen,`${i}.rowVisibleWhen`,t),e.groups!==void 0&&(!Array.isArray(e.groups)||e.groups.length>16?t.push({path:`${i}.groups`,message:"分组应为数组,最多 16 级"}):e.groups.forEach((o,a)=>ie(o,`${i}.groups.${a}`,t))),e.detail===void 0)return;const s=e.detail,n=`${i}.detail`;if(!h(s)){t.push({path:n,message:"主从关联应为对象"});return}for(const o of["dataset","parentKey","foreignKey"])m(s,o,n,t,!0);for(const o of["rowKey","revisionField","sourceTokenField"])m(s,o,n,t,s[o]!==void 0);m(s,"label",n,t),b(s,"header",n,t),c(s,"rowHeightMm",n,t,Number.MIN_VALUE),te(s.columns,`${n}.columns`,t),s.unmatched!==void 0&&s.unmatched!=="error"&&s.unmatched!=="ignore"&&t.push({path:`${n}.unmatched`,message:"未关联明细策略应为 error 或 ignore"})}function Ke(e,i,t){for(const s of["leftMm","topMm"])c(e,s,i,t,-1/0,!0);c(e,"widthMm",i,t,Number.MIN_VALUE,!0),m(e,"dataset",i,t,!0),m(e,"title",i,t);for(const s of["rowKey","revisionField","sourceTokenField"])m(e,s,i,t,e[s]!==void 0);e.headerGrid!==void 0&&De(e.headerGrid,e.columns,`${i}.headerGrid`,t),e.layout!==void 0&&e.layout!=="page"&&e.layout!=="wide"&&t.push({path:`${i}.layout`,message:"布局应为 page 或 wide"}),te(e.columns,`${i}.columns`,t);for(const s of["fontSizePt","rowHeightMm"])c(e,s,i,t,Number.MIN_VALUE);c(e,"paddingMm",i,t);for(const s of["header","headerBold","headerEveryPage","border"])b(e,s,i,t);e.cardinality!==void 0&&e.cardinality!=="record"&&t.push({path:`${i}.cardinality`,message:"单记录区域类型应为 record"}),m(e,"headerBackgroundColor",i,t),M(e.align,`${i}.align`,t,!0),M(e.headerAlign,`${i}.headerAlign`,t),$(e.headerStyle,`${i}.headerStyle`,t),je(e,i,t),ie(e.groupBy,`${i}.groupBy`,t),Ce(e.grandTotal,`${i}.grandTotal`,t)}function K(e,i,t){Array.isArray(e.richParagraphs)&&e.richParagraphs.forEach((s,n)=>{if(!h(s))return;const o=`${i}.richParagraphs.${n}`;M(s.align,`${o}.align`,t);for(const a of["lineHeight","spaceBeforeMm","spaceAfterMm","indentMm"])c(s,a,o,t);Array.isArray(s.segments)&&s.segments.forEach((a,f)=>{const r=`${o}.segments.${f}`;if(!h(a)){t.push({path:r,message:"富文本片段应为对象"});return}a.kind!==void 0&&a.kind!=="text"&&a.kind!=="field"&&t.push({path:`${r}.kind`,message:"未知富文本片段类型"});for(const d of["text","field"])m(a,d,r,t);$(a.style,`${r}.style`,t)})})}function V(e,i,t){$(e.style,`${i}.style`,t);for(const n of["text","rawText","imageData","fallbackText","nid","rkey"])m(e,n,i,t);if(e.lines!==void 0&&(!Array.isArray(e.lines)||e.lines.some(n=>typeof n!="string"))&&t.push({path:`${i}.lines`,message:"文本行应为字符串数组"}),K(e,i,t),!h(e.grid))return;const s=e.grid;c(s,"gapMm",`${i}.grid`,t),c(s,"paddingMm",`${i}.grid`,t);for(const n of["colWidthsMm","rowHeightsMm"]){const o=s[n];o!==void 0&&(!Array.isArray(o)||o.some(a=>typeof a!="number"||!Number.isFinite(a)||a<0))&&t.push({path:`${i}.grid.${n}`,message:"网格尺寸应为有限非负数字数组"})}Array.isArray(s.cells)&&s.cells.forEach((n,o)=>{Array.isArray(n)&&n.forEach((a,f)=>{const r=`${i}.grid.cells.${o}.${f}`;if(a!==null){if(!h(a)){t.push({path:r,message:"网格单元格应为对象或 null"});return}for(const d of["text","rawText","numberFormat"])m(a,d,r,t);for(const d of["colSpan","rowSpan"]){const u=a[d];u!==void 0&&(typeof u!="number"||!Number.isInteger(u)||u<=0)&&t.push({path:`${r}.${d}`,message:"跨度应为正整数"})}a.value!==void 0&&a.value!==null&&!["string","number","boolean"].includes(typeof a.value)&&t.push({path:`${r}.value`,message:"Excel 原始值应为字符串、数字、布尔值或 null"}),$(a.style,`${r}.style`,t),K(a,r,t),a.children!==void 0&&(Array.isArray(a.children)?a.children.forEach((d,u)=>{h(d)&&V(d,`${r}.children.${u}`,t)}):t.push({path:`${r}.children`,message:"嵌套组件应为数组"}))}})})}function He(e,i,t){if(!(e.flow===void 0||!Array.isArray(e.components)))try{X(e.components,e.flow)}catch(s){t.push({path:`${i}.flow`,message:s instanceof Error?s.message:String(s)})}}function se(e){const i=[],t=[];return D(e,i),i.length?{ok:!1,errors:i,warnings:t}:(h(e)?(e.schemaVersion!==void 0&&e.schemaVersion!==x.RENDER_PLAN_SCHEMA_VERSION&&i.push({path:"$.schemaVersion",message:"不支持的模板 schemaVersion"}),_e(e.params,"$.params",i),Q(e,i),!Array.isArray(e.pages)||e.pages.length===0?i.push({path:"$.pages",message:"模板至少需要一页"}):e.pages.forEach((s,n)=>{const o=`$.pages.${n}`;if(!h(s)){i.push({path:o,message:"页应为对象"});return}c(s,"widthMm",o,i,Number.MIN_VALUE,!0),c(s,"heightMm",o,i,Number.MIN_VALUE,!0),s.layout!==void 0&&s.layout!=="page"&&s.layout!=="wide"&&i.push({path:`${o}.layout`,message:"布局应为 page 或 wide"}),typeof s.heightMm=="number"&&s.heightMm>=5e3&&i.push({path:`${o}.heightMm`,message:"页高应小于 5000mm"});for(const a of["marginTopMm","marginBottomMm","marginLeftMm","marginRightMm"])c(s,a,o,i);typeof s.widthMm=="number"&&Number(s.marginLeftMm??0)+Number(s.marginRightMm??0)>=s.widthMm&&i.push({path:o,message:"横向页边距占满页面"}),typeof s.heightMm=="number"&&Number(s.marginTopMm??0)+Number(s.marginBottomMm??0)>=s.heightMm&&i.push({path:o,message:"纵向页边距占满页面"}),Array.isArray(s.components)?s.components.forEach((a,f)=>{const r=`${o}.components.${f}`;h(a)&&a.kind==="list"?Ke(a,r,i):(F(a,r,i,t),h(a)&&V(a,r,i))}):i.push({path:`${o}.components`,message:"组件应为数组"}),He(s,o,i)})):i.push({path:"$",message:"模板应为对象"}),{ok:i.length===0,errors:i,warnings:t})}function ne(e){const i=[],t=[];if(D(e,i),i.length)return{ok:!1,errors:i,warnings:t};if(!h(e))i.push({path:"$",message:"模板文档应为对象"});else{for(const n of Object.keys(e))xe.has(n)||i.push({path:`$.${n}`,message:"模板文档存在未知字段;只保存模板与描述,不保存取数或业务数据"});e.schemaVersion!==L&&i.push({path:"$.schemaVersion",message:"不支持的模板文档版本"});for(const n of["id","name"])m(e,n,"$",i,!0);for(const n of["revision","description"])m(e,n,"$",i);const s=se(e.template);i.push(...s.errors.map(n=>({...n,path:`$.template${n.path.slice(1)}`}))),t.push(...s.warnings.map(n=>({...n,path:`$.template${n.path.slice(1)}`})))}return{ok:i.length===0,errors:i,warnings:t}}function T(e){const i=ne(e);if(!i.ok)throw new w(i.errors)}function Je(e){const i=[];if(D(e,i),i.length)throw new w(i);const t={...e,schemaVersion:e.schemaVersion??L};return T(t),R(t)}function We(e){let i=e;if(typeof e=="string"){if(e.length>C)throw new w([{path:"$",message:"模板 JSON 超过 1000 万字符的导出/导入上限"}]);try{i=JSON.parse(e)}catch{throw new w([{path:"$",message:"模板 JSON 语法无效"}])}}return T(i),R(i)}function Ge(e){T(e);const i=JSON.stringify(e,null,2);if(i.length>C)throw new w([{path:"$",message:"模板 JSON 超过 1000 万字符的导出/导入上限"}]);return i}function R(e){return JSON.parse(JSON.stringify(e))}function Ue(e=[]){const i=new Map,t={get:s=>{const n=i.get(s);return n?R(n):void 0},list:()=>Array.from(i.values(),({template:s,...n})=>({...n})),register:(s,n={})=>{if(T(s),i.has(s.id)&&!n.replace)throw new w([{path:"$.id",message:`模板 ID ${s.id} 已注册;更新需显式 replace:true`}]);i.set(s.id,R(s))},remove:s=>i.delete(s)};for(const s of e)t.register(s);return t}exports.REPORT_TEMPLATE_DOCUMENT_VERSION=L;exports.ReportTemplateError=w;exports.assertRenderPlan=ye;exports.createTemplateRegistry=Ue;exports.defineReportTemplate=Je;exports.parseReportTemplate=We;exports.reportFlowGroups=be;exports.serializeReportTemplate=Ge;exports.validateComponent=F;exports.validatePage=B;exports.validateRenderPlan=z;exports.validateReportPageFlow=X;exports.validateReportTemplate=se;exports.validateReportTemplateDocument=ne;exports.validateTemplateRepeat=Q;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { v as X } from "./matrix-
|
|
2
|
-
import { v as Y, c as Q } from "./computed-
|
|
1
|
+
import { v as X } from "./matrix-JLAXlux-.js";
|
|
2
|
+
import { v as Y, c as Q } from "./computed-BW5a8QFk.js";
|
|
3
3
|
import { c as j, r as Z, R as ee } from "./component-tree-Ca6YYfHq.js";
|
|
4
4
|
import { c as te } from "./code-options-BKXXY7NI.js";
|
|
5
5
|
import { v as ie, e as se } from "./param-validation-Do7Eg8Zv.js";
|
|
6
|
-
import { v as ne, a as oe } from "./tree-
|
|
6
|
+
import { v as ne, a as oe } from "./tree-DNJorJUf.js";
|
|
7
7
|
function ae(e, i, t) {
|
|
8
8
|
e !== void 0 && (typeof e != "string" || !e.trim() || e.length > 4096) && t.push({ path: i, message: "来源范围应为不超过 4096 字符的非空字符串" });
|
|
9
9
|
}
|
|
@@ -784,8 +784,8 @@ function st(e = []) {
|
|
|
784
784
|
}
|
|
785
785
|
export {
|
|
786
786
|
w as R,
|
|
787
|
-
|
|
788
|
-
|
|
787
|
+
B as a,
|
|
788
|
+
ye as b,
|
|
789
789
|
Qe as c,
|
|
790
790
|
st as d,
|
|
791
791
|
et as e,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const s=require("./computed-
|
|
1
|
+
"use strict";const s=require("./computed-C2GD3XcE.cjs");class g extends Error{constructor(r){super(`树节点超出行数预算 ${r}`),this.limit=r,this.code="tree-row-limit",this.name="TreeRowLimitError"}}function u(e,r,i,t){const n=e??r;if(!Number.isInteger(n)||n<1||n>i)throw new Error(`${t}应为 1–${i} 的整数`);return n}function w(e){return{rows:u(e.maxRows,1e5,1e6,"树行数预算"),depth:u(e.maxDepth,64,256,"树深度预算"),visits:u(e.maxAggregationVisits,1e6,1e7,"树聚合访问预算")}}function m(e){return typeof e=="string"&&!!e.trim()}function c(e){return m(e)&&!["__proto__","prototype","constructor"].includes(e)}function E(e){if(m(e)||typeof e=="number"&&Number.isFinite(e))return e;throw new Error("树节点业务键应为非空字符串或有限数字")}function p(e){return JSON.stringify([typeof e,e])}function F(e){return[e.idField,...e.input==="flat"?[e.parentField??""]:[e.childrenField??"children"]]}function y(e,r){const i=F(e);if(r?.some(t=>t.scope&&t.scope!=="row"||i.includes(t.field)))throw new Error("树形布局仅支持不覆盖结构键的当前行计算")}function h(e){if(!e?.aborted)return;const r=new Error("树报表处理已取消");throw r.name="AbortError",r}function k(e){const r=e.aggregates??[];if(!Array.isArray(r)||r.length>32)throw new Error("树聚合最多 32 项");if(e.parentValues!=="leaf-aggregate"&&r.length)throw new Error("树聚合需显式选择 leaf-aggregate 父级取值策略");if(e.parentValues==="leaf-aggregate"&&!r.length)throw new Error("叶子聚合策略至少需要一个聚合字段");const i=new Set;for(const t of r){if(!t||!c(t.field)||i.has(t.field))throw new Error("树聚合输出字段应安全、非空且唯一");for(const n of[t.valueField,t.weightField])if(n!==void 0&&!c(n))throw new Error("树聚合来源字段应安全且非空");if([...F(e),e.labelField].includes(t.field))throw new Error("树聚合不能覆盖结构键或标签字段");i.add(t.field),s.createAggregateAccumulator({...t,field:t.valueField??t.field})}}function N(e){if(!c(e.idField)||!c(e.labelField))throw new Error("树需要安全的业务键和标签字段");if(e.input==="flat"&&(!c(e.parentField)||e.parentField===e.idField))throw new Error("扁平树需要独立的父键字段");if(e.childrenField!==void 0&&!c(e.childrenField))throw new Error("子节点字段应安全且非空");if(e.input==="nested"&&[e.idField,e.labelField].includes(e.childrenField??"children"))throw new Error("子节点字段不能覆盖业务键或标签字段")}function v(e){if(!e||typeof e!="object"||!["flat","nested"].includes(e.input))throw new Error("树输入应为 flat 或 nested");if(N(e),e.orphan!==void 0&&!["error","root"].includes(e.orphan))throw new Error("树孤儿策略应为 error 或 root");if(e.parentValues!==void 0&&!["source","leaf-aggregate"].includes(e.parentValues))throw new Error("未知树父级取值策略");if(e.indentMm!==void 0&&(!Number.isFinite(e.indentMm)||e.indentMm<0||e.indentMm>20))throw new Error("树每级缩进应为 0–20 mm");w(e),k(e)}function A(e,r,i,t){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("树节点应为对象");if(i.size>=t.rows)throw new g(t.rows);const n=E(e[r.idField]),l=p(n);if(i.has(l))throw new Error(`树节点业务键重复:${String(n)}`);const o={original:e,row:e,key:n,depth:0,children:[]};return i.set(l,o),o}function $(e,r,i,t,n){for(const o of e)h(n),A(o,r,i,t);const l=[];for(const o of i.values()){h(n);const a=o.row[r.parentField];if(a==null){l.push(o);continue}const d=i.get(p(E(a)));if(!d){if(r.orphan!=="root")throw new Error(`树节点 ${String(o.key)} 的父节点不存在`);l.push(o);continue}if(d===o)throw new Error("树节点不能以自身为父节点");o.parent=d,d.children.push(o)}return l}function M(e,r,i,t,n){const l=[],o=[{rows:e,next:0}];for(;o.length;){h(n);const a=o[o.length-1];if(a.next>=a.rows.length){o.pop();continue}const d=A(a.rows[a.next++],r,i,t);if(d.parent=a.parent,d.depth=o.length-1,o.length>t.depth)throw new Error(`树节点超出深度预算 ${t.depth}`);(a.parent?.children??l).push(d);const f=d.row[r.childrenField??"children"];if(f!=null){if(!Array.isArray(f))throw new Error("嵌套树 children 字段应为数组");f.length&&o.push({rows:f,next:0,parent:d})}}return l}function V(e,r,i,t){const n=[],l=[{nodes:e,next:0}];for(;l.length;){h(t);const o=l[l.length-1];if(o.next>=o.nodes.length){l.pop();continue}if(l.length>i.depth)throw new Error(`树节点超出深度预算 ${i.depth}`);const a=o.nodes[o.next++];a.depth=l.length-1,n.push(a),a.children.length&&l.push({nodes:a.children,next:0})}if(n.length!==r)throw new Error("树父子关系存在循环");return n}function S(e,r,i,t){if(r.parentValues!=="leaf-aggregate")return;const n=r.aggregates,l=new Map;for(const a of e)a.children.length&&l.set(a,n.map(d=>s.createAggregateAccumulator({...d,field:d.valueField??d.field})));let o=0;for(const a of e)if(!a.children.length)for(let d=a.parent;d;d=d.parent){if(h(t),o+=n.length,o>i.visits)throw new Error(`树聚合超出访问预算 ${i.visits}`);for(const f of l.get(d))f.add(a.row)}for(const[a,d]of l)a.row={...a.row},n.forEach((f,T)=>{a.row[f.field]=d[T].value()})}function b(e,r,i){if(v(r),h(i),!Array.isArray(e))throw new Error("树数据应为节点数组");const t=w(r),n=new Map,l=r.input==="flat"?$(e,r,n,t,i):M(e,r,n,t,i);return V(l,n.size,t,i)}function x(e,r,i){return b(e,r,i).map(t=>t.original)}function O(e,r,i={}){const t=b(e,r,i.signal);if(y(r,i.computed?.fields),i.computed?.fields.length){const n=s.computeDataset(t.map(l=>l.row),{...i.computed,signal:i.signal}).rows;t.forEach((l,o)=>{l.row=n[o]})}return S(t,r,w(r),i.signal),{rows:t.map(n=>n.row),entries:t.map(n=>({row:n.row,original:n.original,key:n.key,depth:n.depth,hasChildren:!!n.children.length})),leaves:t.filter(n=>!n.children.length).map(n=>n.row)}}exports.TreeRowLimitError=g;exports.createTreeTable=O;exports.flattenTreeInput=x;exports.validateTreeComputed=y;exports.validateTreeOptions=v;
|
package/dist/vue/async.d.cts
CHANGED
|
@@ -29,13 +29,34 @@ declare interface AssetRenderBudget {
|
|
|
29
29
|
/** Wall-clock budget, including adapters that ignore AbortSignal. Default 30 seconds. */
|
|
30
30
|
maxDurationMs?: number;
|
|
31
31
|
}
|
|
32
|
+
declare interface AssetRenderBudget_2 {
|
|
33
|
+
/** Maximum newly rendered assets, default 1000. Existing imageData is kept unchanged. */
|
|
34
|
+
maxAssets?: number;
|
|
35
|
+
/** Maximum image payload bytes per new asset, default 32 MiB. */
|
|
36
|
+
maxImageBytes?: number;
|
|
37
|
+
/** Maximum total image payload bytes for new assets, default 128 MiB. */
|
|
38
|
+
maxTotalImageBytes?: number;
|
|
39
|
+
/** Wall-clock budget, including adapters that ignore AbortSignal. Default 30 seconds. */
|
|
40
|
+
maxDurationMs?: number;
|
|
41
|
+
}
|
|
32
42
|
declare interface AssetRenderOptions extends OutputDiagnosticOptions, ImageMediaOptions {
|
|
33
43
|
assetRenderers?: Partial<Record<ImageComponentKind, ComponentImageRenderer>>;
|
|
44
|
+
/** Explicit id/version registry; unbound components continue using assetRenderers by kind. */
|
|
45
|
+
assetRegistry?: ComponentAssetRegistry;
|
|
34
46
|
assetBudget?: AssetRenderBudget;
|
|
35
47
|
/** Default throw prevents an incomplete export; placeholder retains the component and emits diagnostics. */
|
|
36
48
|
assetFailure?: "throw" | "placeholder";
|
|
37
49
|
signal?: AbortSignal;
|
|
38
50
|
}
|
|
51
|
+
declare interface AssetRenderOptions_2 extends OutputDiagnosticOptions_2, ImageMediaOptions_2 {
|
|
52
|
+
assetRenderers?: Partial<Record<ImageComponentKind_2, ComponentImageRenderer_2>>;
|
|
53
|
+
/** Explicit id/version registry; unbound components continue using assetRenderers by kind. */
|
|
54
|
+
assetRegistry?: ComponentAssetRegistry_2;
|
|
55
|
+
assetBudget?: AssetRenderBudget_2;
|
|
56
|
+
/** Default throw prevents an incomplete export; placeholder retains the component and emits diagnostics. */
|
|
57
|
+
assetFailure?: "throw" | "placeholder";
|
|
58
|
+
signal?: AbortSignal;
|
|
59
|
+
}
|
|
39
60
|
declare interface BrowserReportWorker {
|
|
40
61
|
postMessage(value: unknown, transfer?: Transferable[]): void;
|
|
41
62
|
terminate(): void;
|
|
@@ -143,6 +164,14 @@ declare type ColumnFormat_3 = {
|
|
|
143
164
|
kind: "date";
|
|
144
165
|
pattern?: string;
|
|
145
166
|
};
|
|
167
|
+
declare interface ComponentAssetRegistry {
|
|
168
|
+
rendererFor(component: Readonly<PlanComponent>): ComponentImageRenderer | undefined;
|
|
169
|
+
hasExtension(id: string, version: string, kind: string): boolean;
|
|
170
|
+
}
|
|
171
|
+
declare interface ComponentAssetRegistry_2 {
|
|
172
|
+
rendererFor(component: Readonly<PlanComponent_2>): ComponentImageRenderer_2 | undefined;
|
|
173
|
+
hasExtension(id: string, version: string, kind: string): boolean;
|
|
174
|
+
}
|
|
146
175
|
/** A literal own field of the current label record; expressions and paths are not evaluated. */
|
|
147
176
|
declare interface ComponentBinding {
|
|
148
177
|
field: string;
|
|
@@ -174,7 +203,15 @@ declare interface ComponentImageContext {
|
|
|
174
203
|
readonly componentPath: readonly number[];
|
|
175
204
|
readonly signal: AbortSignal;
|
|
176
205
|
}
|
|
206
|
+
declare interface ComponentImageContext_2 {
|
|
207
|
+
readonly component: Readonly<PlanComponent_2>;
|
|
208
|
+
readonly pageIndex: number;
|
|
209
|
+
readonly componentIndex: number;
|
|
210
|
+
readonly componentPath: readonly number[];
|
|
211
|
+
readonly signal: AbortSignal;
|
|
212
|
+
}
|
|
177
213
|
declare type ComponentImageRenderer = (context: ComponentImageContext) => string | Promise<string>;
|
|
214
|
+
declare type ComponentImageRenderer_2 = (context: ComponentImageContext_2) => string | Promise<string>;
|
|
178
215
|
declare type ComponentKind = "text" | "image" | "barcode" | "qrcode" | "chart" | "line" | "rect" | "ellipse";
|
|
179
216
|
declare type ComponentKind_2 = "text" | "image" | "barcode" | "qrcode" | "chart" | "line" | "rect" | "ellipse";
|
|
180
217
|
declare type ComponentKind_3 = "text" | "image" | "barcode" | "qrcode" | "chart" | "line" | "rect" | "ellipse";
|
|
@@ -446,6 +483,7 @@ declare interface GridCell_3 {
|
|
|
446
483
|
style?: ComponentStyle_3;
|
|
447
484
|
}
|
|
448
485
|
declare type ImageComponentKind = "image" | "chart" | "barcode" | "qrcode";
|
|
486
|
+
declare type ImageComponentKind_2 = "image" | "chart" | "barcode" | "qrcode";
|
|
449
487
|
/** Bounded binary image inspection shared by PDF, Excel and template import. No decoder is loaded. */
|
|
450
488
|
declare interface ImageMediaOptions {
|
|
451
489
|
maxImageBytes?: number;
|
|
@@ -1028,6 +1066,40 @@ declare interface MachReportToolbarOptions {
|
|
|
1028
1066
|
/** 未传时显示全部已有出口;空数组表示不提供导出工具。 */
|
|
1029
1067
|
exportFormats?: ReportExportFormat[];
|
|
1030
1068
|
}
|
|
1069
|
+
declare interface MatrixAxisOptions {
|
|
1070
|
+
/** Display names in the same outer-to-inner order as the dimension fields. */
|
|
1071
|
+
labels?: readonly string[];
|
|
1072
|
+
/** Per-level sibling order; omitted levels retain first-seen order. */
|
|
1073
|
+
sort?: readonly MatrixDimensionOrder[];
|
|
1074
|
+
/** One-based prefix depths. Leaf depths are not subtotals. */
|
|
1075
|
+
subtotals?: readonly number[];
|
|
1076
|
+
}
|
|
1077
|
+
declare interface MatrixAxisOptions_2 {
|
|
1078
|
+
/** Display names in the same outer-to-inner order as the dimension fields. */
|
|
1079
|
+
labels?: readonly string[];
|
|
1080
|
+
/** Per-level sibling order; omitted levels retain first-seen order. */
|
|
1081
|
+
sort?: readonly MatrixDimensionOrder_2[];
|
|
1082
|
+
/** One-based prefix depths. Leaf depths are not subtotals. */
|
|
1083
|
+
subtotals?: readonly number[];
|
|
1084
|
+
}
|
|
1085
|
+
declare type MatrixDimensionOrder = "source" | "asc" | "desc";
|
|
1086
|
+
declare type MatrixDimensionOrder_2 = "source" | "asc" | "desc";
|
|
1087
|
+
declare interface MatrixHierarchyOptions {
|
|
1088
|
+
row?: MatrixAxisOptions;
|
|
1089
|
+
column?: MatrixAxisOptions;
|
|
1090
|
+
/** Only null/missing values use this label; empty strings and zero stay distinct. */
|
|
1091
|
+
emptyLabel?: string;
|
|
1092
|
+
subtotalLabel?: string;
|
|
1093
|
+
totalLabel?: string;
|
|
1094
|
+
}
|
|
1095
|
+
declare interface MatrixHierarchyOptions_2 {
|
|
1096
|
+
row?: MatrixAxisOptions_2;
|
|
1097
|
+
column?: MatrixAxisOptions_2;
|
|
1098
|
+
/** Only null/missing values use this label; empty strings and zero stay distinct. */
|
|
1099
|
+
emptyLabel?: string;
|
|
1100
|
+
subtotalLabel?: string;
|
|
1101
|
+
totalLabel?: string;
|
|
1102
|
+
}
|
|
1031
1103
|
declare interface MatrixTableOptions {
|
|
1032
1104
|
rowFields: readonly string[];
|
|
1033
1105
|
columnFields: readonly string[];
|
|
@@ -1042,6 +1114,10 @@ declare interface MatrixTableOptions {
|
|
|
1042
1114
|
maxColumns?: number;
|
|
1043
1115
|
maxInputRows?: number;
|
|
1044
1116
|
maxCells?: number;
|
|
1117
|
+
/** Opt-in hierarchical dimensions, physical merged headers and prefix subtotals. */
|
|
1118
|
+
hierarchy?: MatrixHierarchyOptions;
|
|
1119
|
+
/** Hierarchical aggregate work, checked before measure reads; default 10 million updates. */
|
|
1120
|
+
maxAggregateUpdates?: number;
|
|
1045
1121
|
}
|
|
1046
1122
|
declare interface MatrixTableOptions_2 {
|
|
1047
1123
|
rowFields: readonly string[];
|
|
@@ -1057,6 +1133,10 @@ declare interface MatrixTableOptions_2 {
|
|
|
1057
1133
|
maxColumns?: number;
|
|
1058
1134
|
maxInputRows?: number;
|
|
1059
1135
|
maxCells?: number;
|
|
1136
|
+
/** Opt-in hierarchical dimensions, physical merged headers and prefix subtotals. */
|
|
1137
|
+
hierarchy?: MatrixHierarchyOptions_2;
|
|
1138
|
+
/** Hierarchical aggregate work, checked before measure reads; default 10 million updates. */
|
|
1139
|
+
maxAggregateUpdates?: number;
|
|
1060
1140
|
}
|
|
1061
1141
|
declare interface OutputDiagnostic {
|
|
1062
1142
|
code: "invalid-image-data" | "image-budget-exceeded" | "component-render-failed" | "unsupported-text" | "output-degraded" | "missing-image" | "unsupported-component" | "unsupported-image-format" | "unsupported-style" | "rich-text-flattened" | "nested-components-omitted" | "async-image-required" | "image-decode-failed" | "asset-render-failed" | "asset-budget-exceeded";
|
|
@@ -1068,6 +1148,11 @@ declare interface OutputDiagnostic {
|
|
|
1068
1148
|
componentPath?: readonly number[];
|
|
1069
1149
|
kind: string;
|
|
1070
1150
|
nid?: string;
|
|
1151
|
+
/** Declarative extension identity only; no property values or business binding data enter diagnostics. */
|
|
1152
|
+
extension?: {
|
|
1153
|
+
id: string;
|
|
1154
|
+
version: string;
|
|
1155
|
+
};
|
|
1071
1156
|
message: string;
|
|
1072
1157
|
}
|
|
1073
1158
|
declare interface OutputDiagnostic_2 {
|
|
@@ -1080,6 +1165,11 @@ declare interface OutputDiagnostic_2 {
|
|
|
1080
1165
|
componentPath?: readonly number[];
|
|
1081
1166
|
kind: string;
|
|
1082
1167
|
nid?: string;
|
|
1168
|
+
/** Declarative extension identity only; no property values or business binding data enter diagnostics. */
|
|
1169
|
+
extension?: {
|
|
1170
|
+
id: string;
|
|
1171
|
+
version: string;
|
|
1172
|
+
};
|
|
1083
1173
|
message: string;
|
|
1084
1174
|
}
|
|
1085
1175
|
declare interface OutputDiagnosticOptions extends OutputTaskOptions {
|
|
@@ -1692,7 +1782,13 @@ declare interface ReportFetchInput extends ReportTaskMonitoring {
|
|
|
1692
1782
|
/** Index scopes diagnostics when reports share datasets or a report ID is repeated. */
|
|
1693
1783
|
onQueryResult?: (reportId: string, result: ReportQueryResult, reportIndex?: number) => void;
|
|
1694
1784
|
}
|
|
1695
|
-
declare
|
|
1785
|
+
declare type ReportFieldAggregation = "sum" | "avg" | "min" | "max" | "count" | "none";
|
|
1786
|
+
declare interface ReportFieldCalculation {
|
|
1787
|
+
/** Business-owned explanation, never executable JavaScript or an inferred business formula. */
|
|
1788
|
+
description: string;
|
|
1789
|
+
dependsOn: readonly string[];
|
|
1790
|
+
}
|
|
1791
|
+
declare interface ReportFieldContract extends ReportFieldSemantics {
|
|
1696
1792
|
field: string;
|
|
1697
1793
|
label?: string;
|
|
1698
1794
|
type: "text" | "number" | "boolean" | "date" | "decimal";
|
|
@@ -1706,6 +1802,16 @@ declare interface ReportFieldContract {
|
|
|
1706
1802
|
semanticRole?: "identifier" | "dimension" | "measure" | "date" | "text";
|
|
1707
1803
|
unit?: string;
|
|
1708
1804
|
}
|
|
1805
|
+
declare interface ReportFieldSemantics {
|
|
1806
|
+
description?: string;
|
|
1807
|
+
/** Explicit meaning of null/missing; does not convert blanks into zero. */
|
|
1808
|
+
missingMeaning?: string;
|
|
1809
|
+
/** Recommended aggregation; none marks non-additive measures such as ratios. No aggregation runs implicitly. */
|
|
1810
|
+
aggregation?: ReportFieldAggregation;
|
|
1811
|
+
/** Shared presentation only; raw values and calculation precision remain unchanged. */
|
|
1812
|
+
format?: ColumnFormat;
|
|
1813
|
+
calculation?: ReportFieldCalculation;
|
|
1814
|
+
}
|
|
1709
1815
|
declare interface ReportFieldTarget {
|
|
1710
1816
|
field: string;
|
|
1711
1817
|
datasetId?: string;
|
|
@@ -2202,7 +2308,7 @@ declare type XlsxImageOptions = ImageMediaOptions_2;
|
|
|
2202
2308
|
* 目标是"财务能直接用的对账表"而非复刻版面)
|
|
2203
2309
|
* - 原生 richText 保留基础字形;未支持组件、段落专有排版与单元格嵌套组件计入 diagnostics / warnings
|
|
2204
2310
|
*/
|
|
2205
|
-
declare interface XlsxRenderOptions extends
|
|
2311
|
+
declare interface XlsxRenderOptions extends AssetRenderOptions_2, XlsxImageOptions {
|
|
2206
2312
|
/** 工作表命名(连续表默认使用标题,其余默认 "Sheet1" 起序)。 */
|
|
2207
2313
|
sheetName?: (sheetIndex: number) => string;
|
|
2208
2314
|
/** auto 默认将 wide 逻辑表合并为连续 Sheet;pages 保留逐页;continuous 要求明确的表来源。 */
|