@happyvertical/smrt-reports 0.57.32 → 0.57.34
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/AGENTS.md +1 -0
- package/README.md +64 -3
- package/dist/adapter.d.ts +18 -1
- package/dist/adapter.d.ts.map +1 -1
- package/dist/chunks/compiler-IUB2YNgM.js +341 -0
- package/dist/chunks/compiler-IUB2YNgM.js.map +1 -0
- package/dist/compiler.d.ts +2 -0
- package/dist/compiler.d.ts.map +1 -1
- package/dist/compiler.js +2 -171
- package/dist/decorators.d.ts +22 -22
- package/dist/decorators.d.ts.map +1 -1
- package/dist/decorators.js +16 -8
- package/dist/decorators.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +54 -20
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +1 -1
- package/dist/refresh.d.ts +0 -1
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +6 -18
- package/dist/refresh.js.map +1 -1
- package/dist/registry-columns.d.ts +14 -0
- package/dist/registry-columns.d.ts.map +1 -0
- package/dist/runtime-compiler.d.ts.map +1 -1
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +2 -2
- package/dist/scheduler.js.map +1 -1
- package/dist/smrt-knowledge.json +7 -7
- package/dist/state.js +1 -1
- package/dist/state.js.map +1 -1
- package/dist/types.d.ts +64 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/views.d.ts.map +1 -1
- package/package.json +9 -9
- package/dist/compiler.js.map +0 -1
package/dist/compiler.js
CHANGED
|
@@ -1,171 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { toSnakeCase } from "@happyvertical/smrt-core/utils";
|
|
4
|
-
//#region src/compiler.ts
|
|
5
|
-
var REPORT_BASE_FIELDS = /* @__PURE__ */ new Set([
|
|
6
|
-
"id",
|
|
7
|
-
"slug",
|
|
8
|
-
"context",
|
|
9
|
-
"created_at",
|
|
10
|
-
"updated_at",
|
|
11
|
-
"createdAt",
|
|
12
|
-
"updatedAt",
|
|
13
|
-
"refreshedAt"
|
|
14
|
-
]);
|
|
15
|
-
function sourceClassName(source) {
|
|
16
|
-
if (typeof source === "string") return source;
|
|
17
|
-
return source.name;
|
|
18
|
-
}
|
|
19
|
-
function reportOptionsFromRegistry(reportCtor) {
|
|
20
|
-
return (ObjectRegistry.getClassByConstructor(reportCtor) ?? ObjectRegistry.getClass(reportCtor.name))?.config?.report;
|
|
21
|
-
}
|
|
22
|
-
function getReportOptions(reportCtor) {
|
|
23
|
-
const options = getRuntimeReportOptions(reportCtor) ?? reportOptionsFromRegistry(reportCtor);
|
|
24
|
-
if (!options?.source) throw new Error(`${reportCtor.name} is missing @report({ source }) metadata. Decorate the report class with @report({ source: SourceClass }).`);
|
|
25
|
-
return options;
|
|
26
|
-
}
|
|
27
|
-
function getRegisteredClassName(ctor) {
|
|
28
|
-
const registered = ObjectRegistry.getClassByConstructor(ctor) ?? ObjectRegistry.getClass(ctor.name);
|
|
29
|
-
return registered?.qualifiedName ?? registered?.name ?? ctor.name;
|
|
30
|
-
}
|
|
31
|
-
function resolveTableName(className) {
|
|
32
|
-
const tableName = ObjectRegistry.getTableName(className);
|
|
33
|
-
if (!tableName) throw new Error(`No SMRT table registered for ${className}. Ensure the class is decorated with @smrt() and its manifest is loaded.`);
|
|
34
|
-
return tableName;
|
|
35
|
-
}
|
|
36
|
-
function parseWhereKey(key) {
|
|
37
|
-
const trimmed = key.trim();
|
|
38
|
-
const operators = [
|
|
39
|
-
" is not null",
|
|
40
|
-
" is null",
|
|
41
|
-
" not in",
|
|
42
|
-
" like",
|
|
43
|
-
" in",
|
|
44
|
-
" !=",
|
|
45
|
-
" >=",
|
|
46
|
-
" <=",
|
|
47
|
-
" >",
|
|
48
|
-
" <",
|
|
49
|
-
" ="
|
|
50
|
-
];
|
|
51
|
-
const lower = trimmed.toLowerCase();
|
|
52
|
-
for (const operator of operators) if (lower.endsWith(operator)) return {
|
|
53
|
-
field: trimmed.slice(0, -operator.length).trim(),
|
|
54
|
-
suffix: operator
|
|
55
|
-
};
|
|
56
|
-
return {
|
|
57
|
-
field: trimmed,
|
|
58
|
-
suffix: ""
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
function normalizeConditionKey(key, mapField) {
|
|
62
|
-
const { field, suffix } = parseWhereKey(key);
|
|
63
|
-
const mapped = mapField(field);
|
|
64
|
-
return suffix ? `${mapped}${suffix}` : mapped;
|
|
65
|
-
}
|
|
66
|
-
function normalizeWhere(where, mapField) {
|
|
67
|
-
if (!where) return void 0;
|
|
68
|
-
if (Array.isArray(where)) return where.map((andGroup) => andGroup.map((condition) => Object.fromEntries(Object.entries(condition).map(([key, value]) => [normalizeConditionKey(key, mapField), value]))));
|
|
69
|
-
return Object.fromEntries(Object.entries(where).map(([key, value]) => [normalizeConditionKey(key, mapField), value]));
|
|
70
|
-
}
|
|
71
|
-
function readReportMetadata(field) {
|
|
72
|
-
return field?._meta?.__report ?? field?.__report;
|
|
73
|
-
}
|
|
74
|
-
function isReportSystemField(fieldName, field) {
|
|
75
|
-
return REPORT_BASE_FIELDS.has(fieldName) || field?._meta?.__smrtSystemField || field?._meta?.__tenancy?.isTenantIdField;
|
|
76
|
-
}
|
|
77
|
-
async function buildReportDefinition(reportCtor) {
|
|
78
|
-
const options = getReportOptions(reportCtor);
|
|
79
|
-
const reportClassName = getRegisteredClassName(reportCtor);
|
|
80
|
-
const sourceName = sourceClassName(options.source);
|
|
81
|
-
const sourceTable = resolveTableName(sourceName);
|
|
82
|
-
const fields = await ObjectRegistry.getAllFields(reportClassName);
|
|
83
|
-
const reportFields = [];
|
|
84
|
-
for (const [fieldName, field] of fields.entries()) {
|
|
85
|
-
const report = readReportMetadata(field);
|
|
86
|
-
if (!report) {
|
|
87
|
-
if (!isReportSystemField(fieldName, field) && !field?.transient) throw new Error(`Report field ${reportCtor.name}.${fieldName} is neither a grouping key nor an aggregate. Add @groupBy(), a time-bucket decorator, or an aggregate decorator.`);
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
reportFields.push({
|
|
91
|
-
fieldName,
|
|
92
|
-
columnName: toSnakeCase(fieldName),
|
|
93
|
-
type: field.type,
|
|
94
|
-
report
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
return {
|
|
98
|
-
reportClassName,
|
|
99
|
-
sourceClassName: sourceName,
|
|
100
|
-
sourceTable,
|
|
101
|
-
fields: reportFields,
|
|
102
|
-
where: options.where,
|
|
103
|
-
having: options.having,
|
|
104
|
-
refresh: options.refresh
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
function sourceColumn(field) {
|
|
108
|
-
const report = field.report;
|
|
109
|
-
if (!report) throw new Error(`Report field ${field.fieldName} is missing metadata`);
|
|
110
|
-
if (report.kind === "group") return toSnakeCase(report.sourceColumn ?? field.fieldName);
|
|
111
|
-
if (report.kind === "bucket") return toSnakeCase(report.sourceColumn);
|
|
112
|
-
if (report.kind === "aggregate") {
|
|
113
|
-
if (!report.column) return "";
|
|
114
|
-
return toSnakeCase(report.column);
|
|
115
|
-
}
|
|
116
|
-
return "";
|
|
117
|
-
}
|
|
118
|
-
function getReportGroupingColumns(definition) {
|
|
119
|
-
const columns = definition.fields.filter((field) => field.report?.kind === "group" || field.report?.kind === "bucket").map((field) => field.columnName ?? toSnakeCase(field.fieldName));
|
|
120
|
-
return columns.length > 0 ? columns : ["id"];
|
|
121
|
-
}
|
|
122
|
-
function compileReportDefinition(definition) {
|
|
123
|
-
const select = [];
|
|
124
|
-
const groupBy = [];
|
|
125
|
-
const reportFieldToColumn = /* @__PURE__ */ new Map();
|
|
126
|
-
for (const field of definition.fields) {
|
|
127
|
-
const outputColumn = field.columnName ?? toSnakeCase(field.fieldName);
|
|
128
|
-
reportFieldToColumn.set(field.fieldName, outputColumn);
|
|
129
|
-
reportFieldToColumn.set(outputColumn, outputColumn);
|
|
130
|
-
const report = field.report;
|
|
131
|
-
if (!report) continue;
|
|
132
|
-
if (report.kind === "group") {
|
|
133
|
-
select.push({
|
|
134
|
-
column: sourceColumn(field),
|
|
135
|
-
as: outputColumn
|
|
136
|
-
});
|
|
137
|
-
groupBy.push(outputColumn);
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
|
-
if (report.kind === "bucket") {
|
|
141
|
-
select.push({
|
|
142
|
-
bucket: report.unit,
|
|
143
|
-
column: sourceColumn(field),
|
|
144
|
-
as: outputColumn
|
|
145
|
-
});
|
|
146
|
-
groupBy.push(outputColumn);
|
|
147
|
-
continue;
|
|
148
|
-
}
|
|
149
|
-
select.push({
|
|
150
|
-
fn: report.fn,
|
|
151
|
-
column: report.column ? sourceColumn(field) : void 0,
|
|
152
|
-
as: outputColumn,
|
|
153
|
-
distinct: report.distinct
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
if (select.length === 0) throw new Error(`${definition.reportClassName} has no report fields. Add @groupBy(), a time-bucket decorator, or an aggregate decorator.`);
|
|
157
|
-
return {
|
|
158
|
-
from: definition.sourceTable,
|
|
159
|
-
select,
|
|
160
|
-
groupBy,
|
|
161
|
-
where: normalizeWhere(definition.where, (field) => toSnakeCase(field)),
|
|
162
|
-
having: normalizeWhere(definition.having, (field) => reportFieldToColumn.get(field) ?? toSnakeCase(field))
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
async function compileReportSpec(reportCtor) {
|
|
166
|
-
return compileReportDefinition(await buildReportDefinition(reportCtor));
|
|
167
|
-
}
|
|
168
|
-
//#endregion
|
|
169
|
-
export { buildReportDefinition, compileReportDefinition, compileReportSpec, getReportGroupingColumns };
|
|
170
|
-
|
|
171
|
-
//# sourceMappingURL=compiler.js.map
|
|
1
|
+
import { a as getReportGroupingColumns, i as compileReportSpec, n as buildReportDefinition, r as compileReportDefinition, t as REPORT_SOURCE_ALIAS } from "./chunks/compiler-IUB2YNgM.js";
|
|
2
|
+
export { REPORT_SOURCE_ALIAS, buildReportDefinition, compileReportDefinition, compileReportSpec, getReportGroupingColumns };
|
package/dist/decorators.d.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
import type { ReportAggregateFn, ReportOptions } from './types.js';
|
|
1
|
+
import type { ReportAggregateFn, ReportOperand, ReportOptions } from './types.js';
|
|
2
2
|
export declare function report(options: ReportOptions): <T extends abstract new (...args: any[]) => any>(ctor: T) => T;
|
|
3
3
|
export declare function getRuntimeReportOptions(ctor: Function): ReportOptions | undefined;
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Group by a source column (`'status'`), a joined model's column
|
|
6
|
+
* (`'wo.title'`), or a value computed from each row (`{ expr }`).
|
|
7
|
+
*/
|
|
8
|
+
export declare function groupBy(sourceColumnOrExpr?: string | {
|
|
9
|
+
expr: ReportOperand;
|
|
10
|
+
}): PropertyDecorator;
|
|
5
11
|
export declare const minute: (sourceColumn: string) => PropertyDecorator;
|
|
6
12
|
export declare const hour: (sourceColumn: string) => PropertyDecorator;
|
|
7
13
|
export declare const day: (sourceColumn: string) => PropertyDecorator;
|
|
@@ -9,29 +15,23 @@ export declare const week: (sourceColumn: string) => PropertyDecorator;
|
|
|
9
15
|
export declare const month: (sourceColumn: string) => PropertyDecorator;
|
|
10
16
|
export declare const quarter: (sourceColumn: string) => PropertyDecorator;
|
|
11
17
|
export declare const year: (sourceColumn: string) => PropertyDecorator;
|
|
12
|
-
export interface
|
|
18
|
+
export interface AggregateMeasureOptions {
|
|
19
|
+
distinct?: boolean;
|
|
20
|
+
/** Aggregate a computed value of each row instead of a column. */
|
|
21
|
+
expr?: ReportOperand;
|
|
22
|
+
/** Aggregate only the rows this predicate holds for (a filtered count or sum). */
|
|
23
|
+
filter?: ReportOperand;
|
|
24
|
+
}
|
|
25
|
+
export interface AggregateDecoratorOptions extends AggregateMeasureOptions {
|
|
13
26
|
fn: ReportAggregateFn;
|
|
14
27
|
column?: string;
|
|
15
|
-
distinct?: boolean;
|
|
16
28
|
}
|
|
17
29
|
export declare function aggregate(options: AggregateDecoratorOptions): PropertyDecorator;
|
|
18
|
-
export declare const sum: (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
export declare const
|
|
22
|
-
distinct?: boolean;
|
|
23
|
-
}) => PropertyDecorator;
|
|
24
|
-
export declare const min: (column?: string, options?: {
|
|
25
|
-
distinct?: boolean;
|
|
26
|
-
}) => PropertyDecorator;
|
|
27
|
-
export declare const max: (column?: string, options?: {
|
|
28
|
-
distinct?: boolean;
|
|
29
|
-
}) => PropertyDecorator;
|
|
30
|
+
export declare const sum: (columnOrOptions?: string | AggregateMeasureOptions, options?: AggregateMeasureOptions) => PropertyDecorator;
|
|
31
|
+
export declare const avg: (columnOrOptions?: string | AggregateMeasureOptions, options?: AggregateMeasureOptions) => PropertyDecorator;
|
|
32
|
+
export declare const min: (columnOrOptions?: string | AggregateMeasureOptions, options?: AggregateMeasureOptions) => PropertyDecorator;
|
|
33
|
+
export declare const max: (columnOrOptions?: string | AggregateMeasureOptions, options?: AggregateMeasureOptions) => PropertyDecorator;
|
|
30
34
|
export declare function count(): PropertyDecorator;
|
|
31
|
-
export declare function count(column: string, options?:
|
|
32
|
-
|
|
33
|
-
}): PropertyDecorator;
|
|
34
|
-
export declare function count(options: {
|
|
35
|
-
distinct?: boolean;
|
|
36
|
-
}): PropertyDecorator;
|
|
35
|
+
export declare function count(column: string, options?: AggregateMeasureOptions): PropertyDecorator;
|
|
36
|
+
export declare function count(options: AggregateMeasureOptions): PropertyDecorator;
|
|
37
37
|
//# sourceMappingURL=decorators.d.ts.map
|
package/dist/decorators.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,iBAAiB,EAGjB,aAAa,EAEd,MAAM,YAAY,CAAC;AAIpB,wBAAgB,MAAM,CAAC,OAAO,EAAE,aAAa,IACnC,CAAC,SAAS,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,CAAC,KAAG,CAAC,CAIpE;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,QAAQ,GACb,aAAa,GAAG,SAAS,CAE3B;AAsBD,wBAAgB,OAAO,
|
|
1
|
+
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,iBAAiB,EAGjB,aAAa,EACb,aAAa,EAEd,MAAM,YAAY,CAAC;AAIpB,wBAAgB,MAAM,CAAC,OAAO,EAAE,aAAa,IACnC,CAAC,SAAS,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,CAAC,KAAG,CAAC,CAIpE;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,QAAQ,GACb,aAAa,GAAG,SAAS,CAE3B;AAsBD;;;GAGG;AACH,wBAAgB,OAAO,CACrB,kBAAkB,CAAC,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACpD,iBAAiB,CAWnB;AAaD,eAAO,MAAM,MAAM,GAAI,cAAc,MAAM,sBAAmC,CAAC;AAC/E,eAAO,MAAM,IAAI,GAAI,cAAc,MAAM,sBAAiC,CAAC;AAC3E,eAAO,MAAM,GAAG,GAAI,cAAc,MAAM,sBAAgC,CAAC;AACzE,eAAO,MAAM,IAAI,GAAI,cAAc,MAAM,sBAAiC,CAAC;AAC3E,eAAO,MAAM,KAAK,GAAI,cAAc,MAAM,sBAAkC,CAAC;AAC7E,eAAO,MAAM,OAAO,GAAI,cAAc,MAAM,sBACX,CAAC;AAClC,eAAO,MAAM,IAAI,GAAI,cAAc,MAAM,sBAAiC,CAAC;AAE3E,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kEAAkE;IAClE,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,kFAAkF;IAClF,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,yBAA0B,SAAQ,uBAAuB;IACxE,EAAE,EAAE,iBAAiB,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,SAAS,CACvB,OAAO,EAAE,yBAAyB,GACjC,iBAAiB,CASnB;AAeD,eAAO,MAAM,GAAG,qBAXM,MAAM,GAAG,uBAAuB,YACzC,uBAAuB,sBAUQ,CAAC;AAC7C,eAAO,MAAM,GAAG,qBAZM,MAAM,GAAG,uBAAuB,YACzC,uBAAuB,sBAWQ,CAAC;AAC7C,eAAO,MAAM,GAAG,qBAbM,MAAM,GAAG,uBAAuB,YACzC,uBAAuB,sBAYQ,CAAC;AAC7C,eAAO,MAAM,GAAG,qBAdM,MAAM,GAAG,uBAAuB,YACzC,uBAAuB,sBAaQ,CAAC;AAE7C,wBAAgB,KAAK,IAAI,iBAAiB,CAAC;AAC3C,wBAAgB,KAAK,CACnB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,uBAAuB,GAChC,iBAAiB,CAAC;AACrB,wBAAgB,KAAK,CAAC,OAAO,EAAE,uBAAuB,GAAG,iBAAiB,CAAC"}
|
package/dist/decorators.js
CHANGED
|
@@ -18,10 +18,14 @@ function registerReportField(metadata) {
|
|
|
18
18
|
});
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
|
-
function groupBy(
|
|
21
|
+
function groupBy(sourceColumnOrExpr) {
|
|
22
|
+
if (typeof sourceColumnOrExpr === "object" && sourceColumnOrExpr !== null) return registerReportField({
|
|
23
|
+
kind: "group",
|
|
24
|
+
expr: sourceColumnOrExpr.expr
|
|
25
|
+
});
|
|
22
26
|
return registerReportField({
|
|
23
27
|
kind: "group",
|
|
24
|
-
sourceColumn
|
|
28
|
+
sourceColumn: sourceColumnOrExpr
|
|
25
29
|
});
|
|
26
30
|
}
|
|
27
31
|
function bucket(unit, sourceColumn) {
|
|
@@ -43,15 +47,19 @@ function aggregate(options) {
|
|
|
43
47
|
kind: "aggregate",
|
|
44
48
|
fn: options.fn,
|
|
45
49
|
column: options.column,
|
|
50
|
+
...options.expr ? { expr: options.expr } : {},
|
|
51
|
+
...options.filter ? { filter: options.filter } : {},
|
|
46
52
|
distinct: options.distinct
|
|
47
53
|
});
|
|
48
54
|
}
|
|
49
55
|
function aggregateDecorator(fn) {
|
|
50
|
-
return (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
return (columnOrOptions, options = {}) => {
|
|
57
|
+
return aggregate({
|
|
58
|
+
fn,
|
|
59
|
+
column: typeof columnOrOptions === "string" ? columnOrOptions : void 0,
|
|
60
|
+
...typeof columnOrOptions === "object" ? columnOrOptions : options
|
|
61
|
+
});
|
|
62
|
+
};
|
|
55
63
|
}
|
|
56
64
|
var sum = aggregateDecorator("sum");
|
|
57
65
|
var avg = aggregateDecorator("avg");
|
|
@@ -61,7 +69,7 @@ function count(columnOrOptions, options = {}) {
|
|
|
61
69
|
return aggregate({
|
|
62
70
|
fn: "count",
|
|
63
71
|
column: typeof columnOrOptions === "string" ? columnOrOptions : void 0,
|
|
64
|
-
|
|
72
|
+
...typeof columnOrOptions === "object" ? columnOrOptions : options
|
|
65
73
|
});
|
|
66
74
|
}
|
|
67
75
|
//#endregion
|
package/dist/decorators.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorators.js","names":[],"sources":["../src/decorators.ts"],"sourcesContent":["import {\n ObjectRegistry,\n registerCompatibleFieldDecorator,\n} from '@happyvertical/smrt-core';\nimport type {\n ReportAggregateFieldMetadata,\n ReportAggregateFn,\n ReportBucketFieldMetadata,\n ReportFieldMetadata,\n ReportOptions,\n ReportTimeBucketUnit,\n} from './types.js';\n\nconst reportOptionsByConstructor = new WeakMap<Function, ReportOptions>();\n\nexport function report(options: ReportOptions) {\n return <T extends abstract new (...args: any[]) => any>(ctor: T): T => {\n reportOptionsByConstructor.set(ctor, options);\n return ctor;\n };\n}\n\nexport function getRuntimeReportOptions(\n ctor: Function,\n): ReportOptions | undefined {\n return reportOptionsByConstructor.get(ctor);\n}\n\nfunction registerReportField(metadata: ReportFieldMetadata) {\n return ((targetOrValue: any, propertyKeyOrContext: any) => {\n registerCompatibleFieldDecorator(\n targetOrValue,\n propertyKeyOrContext,\n (className, propertyKey, ctor) => {\n const options = {\n __report: metadata,\n };\n ObjectRegistry.registerFieldDecorator(\n className,\n propertyKey,\n options,\n ctor,\n );\n },\n );\n }) as PropertyDecorator;\n}\n\nexport function groupBy(
|
|
1
|
+
{"version":3,"file":"decorators.js","names":[],"sources":["../src/decorators.ts"],"sourcesContent":["import {\n ObjectRegistry,\n registerCompatibleFieldDecorator,\n} from '@happyvertical/smrt-core';\nimport type {\n ReportAggregateFieldMetadata,\n ReportAggregateFn,\n ReportBucketFieldMetadata,\n ReportFieldMetadata,\n ReportOperand,\n ReportOptions,\n ReportTimeBucketUnit,\n} from './types.js';\n\nconst reportOptionsByConstructor = new WeakMap<Function, ReportOptions>();\n\nexport function report(options: ReportOptions) {\n return <T extends abstract new (...args: any[]) => any>(ctor: T): T => {\n reportOptionsByConstructor.set(ctor, options);\n return ctor;\n };\n}\n\nexport function getRuntimeReportOptions(\n ctor: Function,\n): ReportOptions | undefined {\n return reportOptionsByConstructor.get(ctor);\n}\n\nfunction registerReportField(metadata: ReportFieldMetadata) {\n return ((targetOrValue: any, propertyKeyOrContext: any) => {\n registerCompatibleFieldDecorator(\n targetOrValue,\n propertyKeyOrContext,\n (className, propertyKey, ctor) => {\n const options = {\n __report: metadata,\n };\n ObjectRegistry.registerFieldDecorator(\n className,\n propertyKey,\n options,\n ctor,\n );\n },\n );\n }) as PropertyDecorator;\n}\n\n/**\n * Group by a source column (`'status'`), a joined model's column\n * (`'wo.title'`), or a value computed from each row (`{ expr }`).\n */\nexport function groupBy(\n sourceColumnOrExpr?: string | { expr: ReportOperand },\n): PropertyDecorator {\n if (typeof sourceColumnOrExpr === 'object' && sourceColumnOrExpr !== null) {\n return registerReportField({\n kind: 'group',\n expr: sourceColumnOrExpr.expr,\n });\n }\n return registerReportField({\n kind: 'group',\n sourceColumn: sourceColumnOrExpr,\n });\n}\n\nfunction bucket(\n unit: ReportTimeBucketUnit,\n sourceColumn: string,\n): PropertyDecorator {\n return registerReportField({\n kind: 'bucket',\n unit,\n sourceColumn,\n } satisfies ReportBucketFieldMetadata);\n}\n\nexport const minute = (sourceColumn: string) => bucket('minute', sourceColumn);\nexport const hour = (sourceColumn: string) => bucket('hour', sourceColumn);\nexport const day = (sourceColumn: string) => bucket('day', sourceColumn);\nexport const week = (sourceColumn: string) => bucket('week', sourceColumn);\nexport const month = (sourceColumn: string) => bucket('month', sourceColumn);\nexport const quarter = (sourceColumn: string) =>\n bucket('quarter', sourceColumn);\nexport const year = (sourceColumn: string) => bucket('year', sourceColumn);\n\nexport interface AggregateMeasureOptions {\n distinct?: boolean;\n /** Aggregate a computed value of each row instead of a column. */\n expr?: ReportOperand;\n /** Aggregate only the rows this predicate holds for (a filtered count or sum). */\n filter?: ReportOperand;\n}\n\nexport interface AggregateDecoratorOptions extends AggregateMeasureOptions {\n fn: ReportAggregateFn;\n column?: string;\n}\n\nexport function aggregate(\n options: AggregateDecoratorOptions,\n): PropertyDecorator {\n return registerReportField({\n kind: 'aggregate',\n fn: options.fn,\n column: options.column,\n ...(options.expr ? { expr: options.expr } : {}),\n ...(options.filter ? { filter: options.filter } : {}),\n distinct: options.distinct,\n } satisfies ReportAggregateFieldMetadata);\n}\n\nfunction aggregateDecorator(fn: ReportAggregateFn) {\n return (\n columnOrOptions?: string | AggregateMeasureOptions,\n options: AggregateMeasureOptions = {},\n ) => {\n const column =\n typeof columnOrOptions === 'string' ? columnOrOptions : undefined;\n const resolved =\n typeof columnOrOptions === 'object' ? columnOrOptions : options;\n return aggregate({ fn, column, ...resolved });\n };\n}\n\nexport const sum = aggregateDecorator('sum');\nexport const avg = aggregateDecorator('avg');\nexport const min = aggregateDecorator('min');\nexport const max = aggregateDecorator('max');\n\nexport function count(): PropertyDecorator;\nexport function count(\n column: string,\n options?: AggregateMeasureOptions,\n): PropertyDecorator;\nexport function count(options: AggregateMeasureOptions): PropertyDecorator;\nexport function count(\n columnOrOptions?: string | AggregateMeasureOptions,\n options: AggregateMeasureOptions = {},\n): PropertyDecorator {\n const column =\n typeof columnOrOptions === 'string' ? columnOrOptions : undefined;\n const resolvedOptions =\n typeof columnOrOptions === 'object' ? columnOrOptions : options;\n return aggregate({ fn: 'count', column, ...resolvedOptions });\n}\n"],"mappings":";;AAcA,IAAM,6CAA6B,IAAI,QAAiC;AAEjE,SAAS,OAAO,SAAwB;CAC7C,QAAwD,SAAe;EACrE,2BAA2B,IAAI,MAAM,OAAO;EAC5C,OAAO;CACT;AACF;AAEO,SAAS,wBACd,MAC2B;CAC3B,OAAO,2BAA2B,IAAI,IAAI;AAC5C;AAEA,SAAS,oBAAoB,UAA+B;CAC1D,SAAS,eAAoB,yBAA8B;EACzD,iCACE,eACA,uBACC,WAAW,aAAa,SAAS;GAChC,MAAM,UAAU,EACd,UAAU,SACZ;GACA,eAAe,uBACb,WACA,aACA,SACA,IACF;EACF,CACF;CACF;AACF;AAMO,SAAS,QACd,oBACmB;CACnB,IAAI,OAAO,uBAAuB,YAAY,uBAAuB,MACnE,OAAO,oBAAoB;EACzB,MAAM;EACN,MAAM,mBAAmB;CAC3B,CAAC;CAEH,OAAO,oBAAoB;EACzB,MAAM;EACN,cAAc;CAChB,CAAC;AACH;AAEA,SAAS,OACP,MACA,cACmB;CACnB,OAAO,oBAAoB;EACzB,MAAM;EACN;EACA;CACF,CAAqC;AACvC;AAEO,IAAM,UAAU,iBAAyB,OAAO,UAAU,YAAY;AACtE,IAAM,QAAQ,iBAAyB,OAAO,QAAQ,YAAY;AAClE,IAAM,OAAO,iBAAyB,OAAO,OAAO,YAAY;AAChE,IAAM,QAAQ,iBAAyB,OAAO,QAAQ,YAAY;AAClE,IAAM,SAAS,iBAAyB,OAAO,SAAS,YAAY;AACpE,IAAM,WAAW,iBACtB,OAAO,WAAW,YAAY;AACzB,IAAM,QAAQ,iBAAyB,OAAO,QAAQ,YAAY;AAelE,SAAS,UACd,SACmB;CACnB,OAAO,oBAAoB;EACzB,MAAM;EACN,IAAI,QAAQ;EACZ,QAAQ,QAAQ;EAChB,GAAI,QAAQ,OAAO,EAAE,MAAM,QAAQ,KAAK,IAAI,CAAC;EAC7C,GAAI,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;EACnD,UAAU,QAAQ;CACpB,CAAwC;AAC1C;AAEA,SAAS,mBAAmB,IAAuB;CACjD,QACE,iBACA,UAAmC,CAAC,MACjC;EAKH,OAAO,UAAU;GAAE;GAAI,QAHrB,OAAO,oBAAoB,WAAW,kBAAkB,KAAA;GAG3B,GAD7B,OAAO,oBAAoB,WAAW,kBAAkB;EACf,CAAC;CAC9C;AACF;AAEO,IAAM,MAAM,mBAAmB,KAAK;AACpC,IAAM,MAAM,mBAAmB,KAAK;AACpC,IAAM,MAAM,mBAAmB,KAAK;AACpC,IAAM,MAAM,mBAAmB,KAAK;AAQpC,SAAS,MACd,iBACA,UAAmC,CAAC,GACjB;CAKnB,OAAO,UAAU;EAAE,IAAI;EAAS,QAH9B,OAAO,oBAAoB,WAAW,kBAAkB,KAAA;EAGlB,GADtC,OAAO,oBAAoB,WAAW,kBAAkB;CACC,CAAC;AAC9D"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export type { ReportAdapterDescriptor, ReportAdapterOptions, ReportBackgroundQue
|
|
|
3
3
|
export { buildReportAdapterDescriptor, buildReportDrilldownQuery, queryReportMaterializedRows, reportMaterializedRowKey, splitReportFilterScopes, } from './adapter.js';
|
|
4
4
|
export { bucketExpr, buildAggregate, } from './aggregate.js';
|
|
5
5
|
export { buildReportDefinition, compileReportDefinition, compileReportSpec, getReportGroupingColumns, } from './compiler.js';
|
|
6
|
+
export type { AggregateDecoratorOptions, AggregateMeasureOptions, } from './decorators.js';
|
|
6
7
|
export { aggregate, avg, count, day, getRuntimeReportOptions, groupBy, hour, max, min, minute, month, quarter, report, sum, week, year, } from './decorators.js';
|
|
7
8
|
export type { AppliedReportRefresh, ApplyReportRefreshOptions, PreviewReportRefreshOptions, ReportLifecycleOptions, ReportLifecycleRun, ReportLifecycleSnapshot, ReportLifecycleState, ReportRefreshActionContext, ReportRefreshActionHost, ReportRefreshJobHandle, ReportRefreshOutcome, ReportRefreshPreview, } from './lifecycle.js';
|
|
8
9
|
export { applyReportRefresh, getReportLifecycle, previewReportRefresh, reportRefreshOutcome, } from './lifecycle.js';
|
|
@@ -27,7 +28,7 @@ export { parseRuntimeReportTime, resolveRuntimeReportTimeRange, runtimeReportBuc
|
|
|
27
28
|
export type { EnqueueReportRefreshOptions, EnsureReportSchedulesOptions, ReportExecutionPrincipalReference, ReportRefreshExecutionAuditEvent, ReportRefreshExecutionAuthority, ReportRefreshExecutionAuthorityContext, ReportRefreshExecutionAuthorityHost, ReportRefreshInterceptorOptions, ReportRefreshJobArgs, ReportScheduleInfo, ReportScheduleRunnerConfig, ReportScheduleRunnerEvents, } from './scheduler.js';
|
|
28
29
|
export { enqueueReportRefresh, ensureReportRefreshSchedules, ReportScheduleRunner, registerReportRefreshExecutionAuthorityHost, registerReportRefreshInterceptor, registerReportRefreshJobIntegritySigner, SmrtPrincipalReportRefreshTask, SmrtReportRefreshTask, } from './scheduler.js';
|
|
29
30
|
export { assertReportTablesReady, REPORT_LOCKS_TABLE, REPORT_REFRESH_TASKS_TABLE, REPORT_RUNS_TABLE, REPORT_RUNTIME_TABLES, REPORT_SCHEDULER_TABLES, REPORT_SCHEDULES_TABLE, REPORT_WATERMARKS_TABLE, SmrtReportLock, SmrtReportLockCollection, SmrtReportRun, SmrtReportRunCollection, SmrtReportSchedule, SmrtReportScheduleCollection, SmrtReportWatermark, SmrtReportWatermarkCollection, scopeKeyForTenant, } from './state.js';
|
|
30
|
-
export type { AggregateBuildResult, AggregateSelectExpr, AggregateSpec, ReportAggregateFieldMetadata, ReportAggregateFn, ReportBucketFieldMetadata, ReportDefinition, ReportFieldDefinition, ReportFieldMetadata, ReportGroupFieldMetadata, ReportOptions, ReportRefreshConfig, ReportRefreshMode, ReportRefreshOptions, ReportRefreshResult, ReportRefreshTrigger, ReportSource, ReportTimeBucketUnit, } from './types.js';
|
|
31
|
+
export type { AggregateBuildResult, AggregateSelectExpr, AggregateSpec, ReportAggregateFieldMetadata, ReportAggregateFn, ReportBucketFieldMetadata, ReportDefinition, ReportFieldDefinition, ReportFieldMetadata, ReportGroupFieldMetadata, ReportJoinDefinition, ReportJoinOptions, ReportOperand, ReportOptions, ReportRefreshConfig, ReportRefreshMode, ReportRefreshOptions, ReportRefreshResult, ReportRefreshTrigger, ReportRelatedFieldPolicy, ReportSource, ReportTimeBucketUnit, } from './types.js';
|
|
31
32
|
export type { AppliedReportExport, ReportBackgroundExportTask, ReportExportActionContext, ReportExportActionHost, ReportExportArtifact, ReportExportFormat, ReportExportLimits, ReportExportPreview, ReportExportProgress, ReportExportReadPlan, ReportExportRequest, ReportExportSnapshot, ReportExportSnapshotBinding, ReportExportSnapshotContext, ReportSavedView, ReportSavedViewColumn, ReportSavedViewDisplay, ReportSavedViewGrouping, ReportSavedViewPinnedSide, } from './views.js';
|
|
32
33
|
export { applyReportExport, createReportExportPageRequest, createReportExportRequest, createReportExportSnapshot, migrateReportSavedView, normalizeReportSavedView, previewReportExport, ReportSurfaceValidationError, reportDefinitionFingerprint, restoreReportSavedView, validateReportExportArtifact, validateReportExportExecution, validateReportExportRequest, verifyReportExportSnapshot, } from './views.js';
|
|
33
34
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,wBAAwB,CAAC;AAEhC,YAAY,EACV,uBAAuB,EACvB,oBAAoB,EACpB,4BAA4B,EAC5B,2BAA2B,EAC3B,yBAAyB,EACzB,sBAAsB,EACtB,sBAAsB,EACtB,gBAAgB,EAChB,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,6BAA6B,EAC7B,+BAA+B,EAC/B,yBAAyB,EACzB,yBAAyB,EACzB,gCAAgC,EAChC,kCAAkC,EAClC,4BAA4B,EAC5B,iCAAiC,EACjC,gCAAgC,EAChC,0BAA0B,EAC1B,yBAAyB,EACzB,yBAAyB,EACzB,8BAA8B,EAC9B,oBAAoB,EACpB,iBAAiB,EACjB,+BAA+B,EAC/B,8BAA8B,EAC9B,wBAAwB,EACxB,kBAAkB,EAClB,6BAA6B,EAC7B,uBAAuB,GACxB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,UAAU,EACV,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,SAAS,EACT,GAAG,EACH,KAAK,EACL,GAAG,EACH,uBAAuB,EACvB,OAAO,EACP,IAAI,EACJ,GAAG,EACH,GAAG,EACH,MAAM,EACN,KAAK,EACL,OAAO,EACP,MAAM,EACN,GAAG,EACH,IAAI,EACJ,IAAI,GACL,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,oBAAoB,EACpB,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,kBAAkB,EAClB,uBAAuB,EACvB,oBAAoB,EACpB,0BAA0B,EAC1B,uBAAuB,EACvB,sBAAsB,EACtB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,KAAK,6BAA6B,EAClC,KAAK,sCAAsC,EAC3C,KAAK,uCAAuC,EAC5C,KAAK,iCAAiC,EACtC,KAAK,kCAAkC,EACvC,KAAK,sBAAsB,EAC3B,KAAK,6BAA6B,GACnC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EACL,aAAa,EACb,iBAAiB,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC/D,YAAY,EACV,qBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,2BAA2B,EAC3B,mBAAmB,EACnB,6BAA6B,EAC7B,8BAA8B,GAC/B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,wBAAwB,EACxB,2BAA2B,EAC3B,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,+BAA+B,EAC/B,wBAAwB,EACxB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,iCAAiC,EACjC,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,mBAAmB,EACnB,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,uBAAuB,EACvB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,iCAAiC,EACjC,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,gCAAgC,EAChC,iCAAiC,EACjC,6BAA6B,EAC7B,sBAAsB,EACtB,sBAAsB,EACtB,4BAA4B,GAC7B,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,EACzB,yBAAyB,EACzB,qBAAqB,EACrB,0BAA0B,EAC1B,2BAA2B,EAC3B,kBAAkB,EAClB,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,YAAY,EACV,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,sBAAsB,EACtB,6BAA6B,EAC7B,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,2BAA2B,EAC3B,4BAA4B,EAC5B,iCAAiC,EACjC,gCAAgC,EAChC,+BAA+B,EAC/B,sCAAsC,EACtC,mCAAmC,EACnC,+BAA+B,EAC/B,oBAAoB,EACpB,kBAAkB,EAClB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,oBAAoB,EACpB,2CAA2C,EAC3C,gCAAgC,EAChC,uCAAuC,EACvC,8BAA8B,EAC9B,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,0BAA0B,EAC1B,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,cAAc,EACd,wBAAwB,EACxB,aAAa,EACb,uBAAuB,EACvB,kBAAkB,EAClB,4BAA4B,EAC5B,mBAAmB,EACnB,6BAA6B,EAC7B,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,4BAA4B,EAC5B,iBAAiB,EACjB,yBAAyB,EACzB,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,EACnB,wBAAwB,EACxB,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,mBAAmB,EACnB,0BAA0B,EAC1B,yBAAyB,EACzB,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,2BAA2B,EAC3B,2BAA2B,EAC3B,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,6BAA6B,EAC7B,yBAAyB,EACzB,0BAA0B,EAC1B,sBAAsB,EACtB,wBAAwB,EACxB,mBAAmB,EACnB,4BAA4B,EAC5B,2BAA2B,EAC3B,sBAAsB,EACtB,4BAA4B,EAC5B,6BAA6B,EAC7B,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { aggregate, avg, count, day, getRuntimeReportOptions, groupBy, hour, max, min, minute, month, quarter, report, sum, week, year } from "./decorators.js";
|
|
2
|
-
import {
|
|
2
|
+
import { a as getReportGroupingColumns, c as tenantColumn, i as compileReportSpec, n as buildReportDefinition, r as compileReportDefinition, s as fieldPolicy } from "./chunks/compiler-IUB2YNgM.js";
|
|
3
3
|
import { REPORT_LOCKS_TABLE, REPORT_REFRESH_TASKS_TABLE, REPORT_RUNS_TABLE, REPORT_RUNTIME_TABLES, REPORT_SCHEDULER_TABLES, REPORT_SCHEDULES_TABLE, REPORT_WATERMARKS_TABLE, SmrtReportLock, SmrtReportLockCollection, SmrtReportRun, SmrtReportRunCollection, SmrtReportSchedule, SmrtReportScheduleCollection, SmrtReportWatermark, SmrtReportWatermarkCollection, assertReportTablesReady, scopeKeyForTenant } from "./state.js";
|
|
4
|
-
import { adapterTypeFromDb, refreshReport, reportRowIdentity
|
|
4
|
+
import { adapterTypeFromDb, refreshReport, reportRowIdentity } from "./refresh.js";
|
|
5
5
|
import { ReportScheduleRunner, SmrtPrincipalReportRefreshTask, SmrtReportRefreshTask, enqueueReportRefresh, ensureReportRefreshSchedules, registerReportRefreshExecutionAuthorityHost, registerReportRefreshInterceptor, registerReportRefreshJobIntegritySigner } from "./scheduler.js";
|
|
6
6
|
import { bucketExpr, buildAggregate } from "./aggregate.js";
|
|
7
7
|
import { C as runtimeReportSpecDigest, S as parseRuntimeReportSpec, _ as RUNTIME_REPORT_HAVING_OPS, a as runRuntimeReportInMemory, b as RUNTIME_REPORT_SPEC_VERSION, c as coerceRuntimeReportValue, d as planRuntimeReportColumns, f as resolveRuntimeReportFieldPolicy, g as RUNTIME_REPORT_FILTER_OPS, h as RUNTIME_REPORT_CHART_TYPES, i as describeRuntimeReportMemorySource, l as humanizeRuntimeReportName, m as RUNTIME_REPORT_BUCKETS, n as resolveRuntimeReportTimeRange, o as describeRuntimeReportSourceFields, p as unknownRuntimeReportField, r as runtimeReportBucketForSpan, s as assertRuntimeReportFilterOperator, t as parseRuntimeReportTime, u as normalizeRuntimeReportCell, v as RUNTIME_REPORT_LIMITS, w as serializeRuntimeReportSpec, x as RuntimeReportError, y as RUNTIME_REPORT_MEASURE_FNS } from "./chunks/runtime-time-D7JZ1e4J.js";
|
|
@@ -213,14 +213,6 @@ var SENSITIVITIES = /* @__PURE__ */ new Set([
|
|
|
213
213
|
function registeredClass(ctor) {
|
|
214
214
|
return ObjectRegistry.getClassByConstructor(ctor) ?? ObjectRegistry.getClass(ctor.name);
|
|
215
215
|
}
|
|
216
|
-
function fieldPolicy(field) {
|
|
217
|
-
const meta = field?._meta ?? {};
|
|
218
|
-
const sensitivity = [field?.sensitivity, meta.sensitivity].find((value) => typeof value === "string");
|
|
219
|
-
return {
|
|
220
|
-
sensitive: field?.sensitive === true || meta.sensitive === true || sensitivity === "sensitive" || sensitivity === "secret",
|
|
221
|
-
readPermission: typeof field?.readPermission === "string" ? field.readPermission : typeof meta.readPermission === "string" ? meta.readPermission : void 0
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
216
|
function descriptorMetadata(field) {
|
|
225
217
|
const metadata = field?._meta ?? {};
|
|
226
218
|
const format = [field?.format, metadata.format].find((value) => typeof value === "string" && value.length > 0);
|
|
@@ -243,6 +235,34 @@ function queryType(type) {
|
|
|
243
235
|
default: return "string";
|
|
244
236
|
}
|
|
245
237
|
}
|
|
238
|
+
function canonical(value) {
|
|
239
|
+
if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
|
|
240
|
+
if (value && typeof value === "object") {
|
|
241
|
+
const object = value;
|
|
242
|
+
return `{${Object.keys(object).filter((key) => object[key] !== void 0).sort().map((key) => `${JSON.stringify(key)}:${canonical(object[key])}`).join(",")}}`;
|
|
243
|
+
}
|
|
244
|
+
return JSON.stringify(value ?? null);
|
|
245
|
+
}
|
|
246
|
+
function columnSemantics(field, joins) {
|
|
247
|
+
const report = field.report;
|
|
248
|
+
if (!report) return void 0;
|
|
249
|
+
const expr = report.kind === "aggregate" || report.kind === "group" ? report.expr : void 0;
|
|
250
|
+
const filter = report.kind === "aggregate" ? report.filter : void 0;
|
|
251
|
+
const text = canonical([expr, filter]);
|
|
252
|
+
const aliases = new Set([...text.matchAll(/"col":"([a-z][a-z0-9_]*)\./g)].map((match) => match[1]));
|
|
253
|
+
const own = report.kind === "group" ? report.sourceColumn : report.kind === "bucket" ? report.sourceColumn : report.column;
|
|
254
|
+
if (own?.includes(".")) aliases.add(own.split(".")[0]);
|
|
255
|
+
const used = joins.filter((join) => aliases.has(join.alias)).map((join) => ({ ...join }));
|
|
256
|
+
if (!expr && !filter && used.length === 0) return void 0;
|
|
257
|
+
return canonical({
|
|
258
|
+
expr,
|
|
259
|
+
filter,
|
|
260
|
+
joins: used
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
function columnRef(ref) {
|
|
264
|
+
return ref.split(".").map(toSnakeCase).join(".");
|
|
265
|
+
}
|
|
246
266
|
function configuredTenantField(configured) {
|
|
247
267
|
return configured ? toSnakeCase(configured) : void 0;
|
|
248
268
|
}
|
|
@@ -255,15 +275,16 @@ function isColumnBackedField(field) {
|
|
|
255
275
|
"manyToMany"
|
|
256
276
|
].includes(field.type ?? "");
|
|
257
277
|
}
|
|
258
|
-
function reportColumn(field, registryField) {
|
|
278
|
+
function reportColumn(field, registryField, joins = []) {
|
|
259
279
|
const policy = fieldPolicy(registryField);
|
|
260
|
-
|
|
280
|
+
const relatedRestricted = (field.related ?? []).some((related) => related.sensitive || related.readPermission);
|
|
281
|
+
if (policy.sensitive || policy.readPermission || relatedRestricted || !isColumnBackedField(registryField)) return;
|
|
261
282
|
const id = field.columnName ?? toSnakeCase(field.fieldName);
|
|
262
283
|
const report = field.report;
|
|
263
284
|
if (!report) return void 0;
|
|
264
285
|
const type = queryType(field.type ?? registryField?.type);
|
|
265
286
|
const filterOperators = filterOperatorsFor(type);
|
|
266
|
-
|
|
287
|
+
const base = {
|
|
267
288
|
id,
|
|
268
289
|
fieldName: field.fieldName,
|
|
269
290
|
label: registryField?.description || labelFor(field.fieldName),
|
|
@@ -282,18 +303,21 @@ function reportColumn(field, registryField) {
|
|
|
282
303
|
...report.kind !== "aggregate" ? ["facet"] : [],
|
|
283
304
|
...report.kind === "aggregate" ? ["aggregate"] : report.kind === "group" ? ["group"] : []
|
|
284
305
|
],
|
|
285
|
-
...report.kind === "group" ? { sourceColumn:
|
|
306
|
+
...report.kind === "group" && !report.expr ? { sourceColumn: columnRef(report.sourceColumn ?? field.fieldName) } : {},
|
|
286
307
|
...report.kind === "bucket" ? {
|
|
287
308
|
bucket: report.unit,
|
|
288
|
-
sourceColumn:
|
|
309
|
+
sourceColumn: columnRef(report.sourceColumn)
|
|
289
310
|
} : {},
|
|
290
311
|
...report.kind === "aggregate" ? {
|
|
291
312
|
aggregate: report.fn,
|
|
292
|
-
...report.column ? { sourceColumn:
|
|
313
|
+
...report.column ? { sourceColumn: columnRef(report.column) } : {},
|
|
293
314
|
...report.distinct === void 0 ? {} : { distinct: report.distinct }
|
|
294
315
|
} : {},
|
|
295
316
|
...descriptorMetadata(registryField)
|
|
296
317
|
};
|
|
318
|
+
const semantics = columnSemantics(field, joins);
|
|
319
|
+
if (semantics) base.semantics = semantics;
|
|
320
|
+
return base;
|
|
297
321
|
}
|
|
298
322
|
function identityColumn() {
|
|
299
323
|
return {
|
|
@@ -526,7 +550,7 @@ function drilldownDescriptor(columns, sourceClassName) {
|
|
|
526
550
|
return {
|
|
527
551
|
id: "drilldown",
|
|
528
552
|
sourceClassName,
|
|
529
|
-
fields: columns.filter((column) => (column.kind === "group" || column.kind === "bucket") && typeof column.sourceColumn === "string").map((column) => ({
|
|
553
|
+
fields: columns.filter((column) => (column.kind === "group" || column.kind === "bucket") && typeof column.sourceColumn === "string" && !column.sourceColumn.includes(".")).map((column) => ({
|
|
530
554
|
id: column.id,
|
|
531
555
|
sourceColumn: column.sourceColumn,
|
|
532
556
|
kind: column.kind,
|
|
@@ -545,7 +569,7 @@ async function buildReportAdapterDescriptor(reportCtor, options = {}) {
|
|
|
545
569
|
const registered = registeredClass(reportCtor);
|
|
546
570
|
const fields = await ObjectRegistry.getAllFields(definition.reportClassName);
|
|
547
571
|
const tenantField = configuredTenantField(registered?.tenantScopedConfig?.field);
|
|
548
|
-
const columns = [identityColumn(), ...definition.fields.map((field) => reportColumn(field, fields.get(field.fieldName))).filter((field) => Boolean(field))].sort((left, right) => left.id.localeCompare(right.id));
|
|
572
|
+
const columns = [identityColumn(), ...definition.fields.map((field) => reportColumn(field, fields.get(field.fieldName), definition.joins)).filter((field) => Boolean(field))].sort((left, right) => left.id.localeCompare(right.id));
|
|
549
573
|
const schema = {
|
|
550
574
|
version: 1,
|
|
551
575
|
identityField: "id",
|
|
@@ -597,6 +621,11 @@ async function buildReportAdapterDescriptor(reportCtor, options = {}) {
|
|
|
597
621
|
},
|
|
598
622
|
dataTable,
|
|
599
623
|
drilldown: drilldownDescriptor(columns, definition.sourceClassName),
|
|
624
|
+
...definition.joins?.length ? { semantics: canonical({
|
|
625
|
+
joins: definition.joins,
|
|
626
|
+
where: definition.where,
|
|
627
|
+
having: definition.having
|
|
628
|
+
}) } : {},
|
|
600
629
|
refresh: refreshDescriptor(definition.refresh, options.refreshPermission)
|
|
601
630
|
};
|
|
602
631
|
}
|
|
@@ -604,6 +633,9 @@ function publicFieldMap(descriptor) {
|
|
|
604
633
|
return new Map(descriptor.columns.map((column) => [column.id, column.fieldName]));
|
|
605
634
|
}
|
|
606
635
|
async function buildReportDrilldownQuery(reportCtor, row, options = {}) {
|
|
636
|
+
const definition = await buildReportDefinition(reportCtor);
|
|
637
|
+
const unbindable = definition.fields.find((field) => field.report?.kind === "group" && (field.report.expr || field.report.sourceColumn?.includes(".")) || field.report?.kind === "bucket" && field.report.sourceColumn.includes("."));
|
|
638
|
+
if (unbindable) throw new DataQueryValidationError(`Report drilldown is not available for ${definition.reportClassName}: ${unbindable.fieldName} groups by a joined or computed value`, "DATA_QUERY_UNSUPPORTED");
|
|
607
639
|
const descriptor = await buildReportAdapterDescriptor(reportCtor, options);
|
|
608
640
|
const constraints = descriptor.drilldown.fields.map((field) => {
|
|
609
641
|
if (!Object.hasOwn(row, field.id)) throw new DataQueryValidationError(`Report drilldown row is missing grouping field: ${field.id}`, "DATA_QUERY_RESULT_INVALID");
|
|
@@ -2009,9 +2041,11 @@ function reportDefinitionFingerprint(descriptor) {
|
|
|
2009
2041
|
sourceColumn: column.sourceColumn ?? null,
|
|
2010
2042
|
bucket: column.bucket ?? null,
|
|
2011
2043
|
aggregate: column.aggregate ?? null,
|
|
2012
|
-
distinct: column.distinct ?? null
|
|
2044
|
+
distinct: column.distinct ?? null,
|
|
2045
|
+
...column.semantics ? { semantics: column.semantics } : {}
|
|
2013
2046
|
})),
|
|
2014
|
-
schema: descriptor.schema
|
|
2047
|
+
schema: descriptor.schema,
|
|
2048
|
+
...descriptor.semantics ? { semantics: descriptor.semantics } : {}
|
|
2015
2049
|
};
|
|
2016
2050
|
return "rv1_" + createHash("sha256").update(stable(definition), "utf8").digest("base64url");
|
|
2017
2051
|
}
|