@zentto/report-core 0.5.0 → 1.1.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.
Files changed (36) hide show
  1. package/dist/engine/conditional-format.d.ts +48 -0
  2. package/dist/engine/conditional-format.d.ts.map +1 -0
  3. package/dist/engine/conditional-format.js +167 -0
  4. package/dist/engine/conditional-format.js.map +1 -0
  5. package/dist/engine/cross-tab.d.ts +68 -0
  6. package/dist/engine/cross-tab.d.ts.map +1 -0
  7. package/dist/engine/cross-tab.js +549 -0
  8. package/dist/engine/cross-tab.js.map +1 -0
  9. package/dist/engine/expression.d.ts +46 -2
  10. package/dist/engine/expression.d.ts.map +1 -1
  11. package/dist/engine/expression.js +1415 -90
  12. package/dist/engine/expression.js.map +1 -1
  13. package/dist/engine/multi-pass-engine.d.ts +74 -0
  14. package/dist/engine/multi-pass-engine.d.ts.map +1 -0
  15. package/dist/engine/multi-pass-engine.js +1082 -0
  16. package/dist/engine/multi-pass-engine.js.map +1 -0
  17. package/dist/engine/running-totals.d.ts +74 -0
  18. package/dist/engine/running-totals.d.ts.map +1 -0
  19. package/dist/engine/running-totals.js +247 -0
  20. package/dist/engine/running-totals.js.map +1 -0
  21. package/dist/engine/subreport.d.ts +59 -0
  22. package/dist/engine/subreport.d.ts.map +1 -0
  23. package/dist/engine/subreport.js +295 -0
  24. package/dist/engine/subreport.js.map +1 -0
  25. package/dist/index.d.ts +11 -1
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +10 -0
  28. package/dist/index.js.map +1 -1
  29. package/dist/schema/report-schema.d.ts +346 -346
  30. package/dist/serialization/json.d.ts +88 -88
  31. package/dist/templates/page-sizes.d.ts.map +1 -1
  32. package/dist/templates/page-sizes.js +95 -3
  33. package/dist/templates/page-sizes.js.map +1 -1
  34. package/dist/types.d.ts +38 -2
  35. package/dist/types.d.ts.map +1 -1
  36. package/package.json +1 -1
@@ -0,0 +1,48 @@
1
+ import type { ElementStyle } from '../types.js';
2
+ import type { BindingContext } from './data-binding.js';
3
+ export interface ConditionalFormatRule {
4
+ id: string;
5
+ /** Target element ID, or '*' for all elements */
6
+ targetElementId: string;
7
+ /** Target band ID — if set, rule applies to all elements in that band */
8
+ targetBandId?: string;
9
+ /** Priority — lower number = higher priority */
10
+ priority: number;
11
+ /** Expression that evaluates to boolean (without leading '=') */
12
+ condition: string;
13
+ /** Styles to apply when condition is true */
14
+ style: Partial<ElementStyle>;
15
+ /** Whether to stop evaluating further rules after this one matches */
16
+ stopIfTrue: boolean;
17
+ }
18
+ export interface ConditionalFormatResult {
19
+ elementId: string;
20
+ /** Merged style from all matching rules (higher priority wins per property) */
21
+ computedStyle: Partial<ElementStyle>;
22
+ /** IDs of rules that triggered, in order of evaluation */
23
+ triggeredRules: string[];
24
+ }
25
+ /**
26
+ * Evaluate all conditional format rules against the current context
27
+ * and return the computed styles for the given element IDs.
28
+ *
29
+ * Rules are sorted by priority (lowest number = highest priority).
30
+ * For each element, matching rules are applied in priority order.
31
+ * If a rule has `stopIfTrue`, no further rules are evaluated for that element.
32
+ * Style properties from higher-priority rules override lower-priority ones.
33
+ */
34
+ export declare function evaluateConditionalFormats(rules: ConditionalFormatRule[], ctx: BindingContext, elementIds: string[]): ConditionalFormatResult[];
35
+ /**
36
+ * Filter rules that apply to a specific band, expanding band-level
37
+ * rules to all element IDs in that band.
38
+ *
39
+ * Use this to pre-filter rules before calling evaluateConditionalFormats
40
+ * so that band-level targeting works correctly.
41
+ */
42
+ export declare function resolveRulesForBand(rules: ConditionalFormatRule[], bandId: string, bandElementIds: string[]): ConditionalFormatRule[];
43
+ /**
44
+ * Apply conditional format results to an element's existing style.
45
+ * Returns a new style object with the conditional styles merged on top.
46
+ */
47
+ export declare function applyConditionalStyle(baseStyle: Partial<ElementStyle> | undefined, results: ConditionalFormatResult[], elementId: string): Partial<ElementStyle>;
48
+ //# sourceMappingURL=conditional-format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conditional-format.d.ts","sourceRoot":"","sources":["../../src/engine/conditional-format.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAKxD,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,iDAAiD;IACjD,eAAe,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7B,sEAAsE;IACtE,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,aAAa,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACrC,0DAA0D;IAC1D,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAID;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,qBAAqB,EAAE,EAC9B,GAAG,EAAE,cAAc,EACnB,UAAU,EAAE,MAAM,EAAE,GACnB,uBAAuB,EAAE,CAqD3B;AAkED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,qBAAqB,EAAE,EAC9B,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EAAE,GACvB,qBAAqB,EAAE,CAyBzB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,EAC5C,OAAO,EAAE,uBAAuB,EAAE,EAClC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,CAAC,CAcvB"}
@@ -0,0 +1,167 @@
1
+ // @zentto/report-core — Conditional formatting engine
2
+ // Crystal Reports-style conditional formatting with priority rules
3
+ import { evaluateExpression } from './expression.js';
4
+ // ─── Core evaluation ────────────────────────────────────────────────
5
+ /**
6
+ * Evaluate all conditional format rules against the current context
7
+ * and return the computed styles for the given element IDs.
8
+ *
9
+ * Rules are sorted by priority (lowest number = highest priority).
10
+ * For each element, matching rules are applied in priority order.
11
+ * If a rule has `stopIfTrue`, no further rules are evaluated for that element.
12
+ * Style properties from higher-priority rules override lower-priority ones.
13
+ */
14
+ export function evaluateConditionalFormats(rules, ctx, elementIds) {
15
+ if (rules.length === 0 || elementIds.length === 0)
16
+ return [];
17
+ // Sort rules by priority ascending (lower number = higher priority)
18
+ const sorted = [...rules].sort((a, b) => a.priority - b.priority);
19
+ // Pre-evaluate all rule conditions once (each condition is the same
20
+ // regardless of which element it targets)
21
+ const conditionCache = new Map();
22
+ for (const rule of sorted) {
23
+ if (!conditionCache.has(rule.id)) {
24
+ conditionCache.set(rule.id, evaluateCondition(rule.condition, ctx));
25
+ }
26
+ }
27
+ // Build results per element
28
+ const results = [];
29
+ for (const elementId of elementIds) {
30
+ const triggeredRules = [];
31
+ // Collect styles from lowest priority to highest so that
32
+ // higher-priority properties overwrite lower ones in the final merge.
33
+ // We iterate highest-priority first and track which props are already set.
34
+ const computedStyle = {};
35
+ const setProps = new Set();
36
+ let stopped = false;
37
+ for (const rule of sorted) {
38
+ if (stopped)
39
+ break;
40
+ // Check if this rule targets the current element
41
+ if (!ruleTargetsElement(rule, elementId))
42
+ continue;
43
+ // Check if condition passed
44
+ const passed = conditionCache.get(rule.id) ?? false;
45
+ if (!passed)
46
+ continue;
47
+ // Rule matched — merge styles (higher-priority props win)
48
+ triggeredRules.push(rule.id);
49
+ mergeStyle(computedStyle, rule.style, setProps);
50
+ if (rule.stopIfTrue) {
51
+ stopped = true;
52
+ }
53
+ }
54
+ // Only include elements that had at least one triggered rule
55
+ if (triggeredRules.length > 0) {
56
+ results.push({ elementId, computedStyle, triggeredRules });
57
+ }
58
+ }
59
+ return results;
60
+ }
61
+ // ─── Helpers ────────────────────────────────────────────────────────
62
+ /** Check if a rule targets a specific element ID */
63
+ function ruleTargetsElement(rule, elementId) {
64
+ // Wildcard — targets every element
65
+ if (rule.targetElementId === '*')
66
+ return true;
67
+ // Direct element match
68
+ if (rule.targetElementId === elementId)
69
+ return true;
70
+ // Band-level rule: targetBandId is set and targetElementId is '*'
71
+ // The caller is responsible for passing only the element IDs that
72
+ // belong to the band. When targetBandId is set with a specific
73
+ // targetElementId, we still match only that element.
74
+ // Band-level filtering (which elements belong to which band) is
75
+ // handled externally; here we just match the element ID.
76
+ return false;
77
+ }
78
+ /** Evaluate a condition expression against the binding context */
79
+ function evaluateCondition(condition, ctx) {
80
+ if (!condition || condition.trim() === '')
81
+ return false;
82
+ // Normalize: ensure the expression starts with '=' for the expression engine
83
+ const expr = condition.startsWith('=') ? condition : `=${condition}`;
84
+ try {
85
+ const result = evaluateExpression(expr, ctx);
86
+ // Handle various truthy evaluations
87
+ if (typeof result === 'boolean')
88
+ return result;
89
+ if (typeof result === 'number')
90
+ return result !== 0;
91
+ if (typeof result === 'string') {
92
+ if (result === 'true')
93
+ return true;
94
+ if (result === 'false' || result === '' || result.startsWith('#ERR'))
95
+ return false;
96
+ return true;
97
+ }
98
+ return !!result;
99
+ }
100
+ catch {
101
+ return false;
102
+ }
103
+ }
104
+ /**
105
+ * Merge source style into target, only setting properties that
106
+ * have not already been set by a higher-priority rule.
107
+ */
108
+ function mergeStyle(target, source, setProps) {
109
+ for (const [key, value] of Object.entries(source)) {
110
+ if (value === undefined)
111
+ continue;
112
+ if (!setProps.has(key)) {
113
+ target[key] = value;
114
+ setProps.add(key);
115
+ }
116
+ }
117
+ }
118
+ // ─── Utility: resolve rules for a band ─────────────────────────────
119
+ /**
120
+ * Filter rules that apply to a specific band, expanding band-level
121
+ * rules to all element IDs in that band.
122
+ *
123
+ * Use this to pre-filter rules before calling evaluateConditionalFormats
124
+ * so that band-level targeting works correctly.
125
+ */
126
+ export function resolveRulesForBand(rules, bandId, bandElementIds) {
127
+ const result = [];
128
+ for (const rule of rules) {
129
+ // Rule explicitly targets this band
130
+ if (rule.targetBandId === bandId) {
131
+ if (rule.targetElementId === '*') {
132
+ // Expand to one rule per element in the band
133
+ for (const elementId of bandElementIds) {
134
+ result.push({ ...rule, targetElementId: elementId });
135
+ }
136
+ }
137
+ else {
138
+ // Specific element within this band
139
+ result.push(rule);
140
+ }
141
+ continue;
142
+ }
143
+ // No targetBandId — global rule (wildcard or specific element)
144
+ if (!rule.targetBandId) {
145
+ result.push(rule);
146
+ }
147
+ }
148
+ return result;
149
+ }
150
+ /**
151
+ * Apply conditional format results to an element's existing style.
152
+ * Returns a new style object with the conditional styles merged on top.
153
+ */
154
+ export function applyConditionalStyle(baseStyle, results, elementId) {
155
+ const result = { ...(baseStyle ?? {}) };
156
+ const match = results.find(r => r.elementId === elementId);
157
+ if (!match)
158
+ return result;
159
+ // Conditional styles override base styles
160
+ for (const [key, value] of Object.entries(match.computedStyle)) {
161
+ if (value !== undefined) {
162
+ result[key] = value;
163
+ }
164
+ }
165
+ return result;
166
+ }
167
+ //# sourceMappingURL=conditional-format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conditional-format.js","sourceRoot":"","sources":["../../src/engine/conditional-format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import type { ElementStyle } from '../types.js';
2
+ export interface CrossTabDef {
3
+ id: string;
4
+ dataSource: string;
5
+ /** Fields that define rows */
6
+ rowFields: CrossTabField[];
7
+ /** Fields that define columns (dynamic) */
8
+ columnFields: CrossTabField[];
9
+ /** Summary field and function */
10
+ summaryFields: CrossTabSummary[];
11
+ /** Show row totals */
12
+ showRowTotals: boolean;
13
+ /** Show column totals */
14
+ showColumnTotals: boolean;
15
+ /** Show grand total */
16
+ showGrandTotal: boolean;
17
+ /** Sort row values */
18
+ rowSort?: 'asc' | 'desc' | 'none';
19
+ /** Sort column values */
20
+ columnSort?: 'asc' | 'desc' | 'none';
21
+ /** Style for header cells */
22
+ headerStyle?: Partial<ElementStyle>;
23
+ /** Style for data cells */
24
+ dataStyle?: Partial<ElementStyle>;
25
+ /** Style for total cells */
26
+ totalStyle?: Partial<ElementStyle>;
27
+ /** Show values as percentage of total */
28
+ showAsPercentage?: boolean;
29
+ /** Suppress empty rows */
30
+ suppressEmptyRows?: boolean;
31
+ /** Suppress empty columns */
32
+ suppressEmptyColumns?: boolean;
33
+ }
34
+ export interface CrossTabField {
35
+ field: string;
36
+ label?: string;
37
+ groupBy?: 'value' | 'year' | 'quarter' | 'month' | 'week' | 'day';
38
+ }
39
+ export interface CrossTabSummary {
40
+ field: string;
41
+ function: 'sum' | 'avg' | 'count' | 'min' | 'max' | 'distinctCount';
42
+ label?: string;
43
+ format?: string;
44
+ }
45
+ export interface CrossTabResult {
46
+ /** Unique row keys — each entry is an array of grouped values (one per rowField) */
47
+ rowKeys: string[][];
48
+ /** Unique column keys — each entry is an array of grouped values (one per columnField) */
49
+ columnKeys: string[][];
50
+ /** Cell values: [rowIndex][colIndex][summaryIndex] */
51
+ cells: (number | null)[][][];
52
+ /** Row totals: [rowIndex][summaryIndex] */
53
+ rowTotals: number[][];
54
+ /** Column totals: [colIndex][summaryIndex] */
55
+ columnTotals: number[][];
56
+ /** Grand totals: [summaryIndex] */
57
+ grandTotals: number[];
58
+ }
59
+ /**
60
+ * Process raw data into a CrossTabResult structure.
61
+ * This is the main cross-tab computation engine.
62
+ */
63
+ export declare function buildCrossTab(def: CrossTabDef, data: Record<string, unknown>[]): CrossTabResult;
64
+ /**
65
+ * Render a CrossTabResult as an HTML table.
66
+ */
67
+ export declare function renderCrossTabHtml(def: CrossTabDef, result: CrossTabResult, prefix?: string): string;
68
+ //# sourceMappingURL=cross-tab.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross-tab.d.ts","sourceRoot":"","sources":["../../src/engine/cross-tab.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,2CAA2C;IAC3C,YAAY,EAAE,aAAa,EAAE,CAAC;IAC9B,iCAAiC;IACjC,aAAa,EAAE,eAAe,EAAE,CAAC;IACjC,sBAAsB;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,yBAAyB;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,uBAAuB;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,sBAAsB;IACtB,OAAO,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IAClC,yBAAyB;IACzB,UAAU,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IACrC,6BAA6B;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACpC,2BAA2B;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAClC,4BAA4B;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACnC,yCAAyC;IACzC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,0BAA0B;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,6BAA6B;IAC7B,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;CACnE;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,eAAe,CAAC;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,oFAAoF;IACpF,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;IACpB,0FAA0F;IAC1F,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC;IACvB,sDAAsD;IACtD,KAAK,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC;IAC7B,2CAA2C;IAC3C,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC;IACtB,8CAA8C;IAC9C,YAAY,EAAE,MAAM,EAAE,EAAE,CAAC;IACzB,mCAAmC;IACnC,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAgHD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAC9B,cAAc,CAyNhB;AAyBD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,cAAc,EACtB,MAAM,GAAE,MAAa,GACpB,MAAM,CAsLR"}