@true-sight/model-schema 1.0.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/dist/constants.d.ts +1 -0
- package/dist/constants.js +4 -0
- package/dist/dsl/compile/compile-explore.d.ts +4 -0
- package/dist/dsl/compile/compile-explore.js +60 -0
- package/dist/dsl/compile/compile-model.d.ts +4 -0
- package/dist/dsl/compile/compile-model.js +39 -0
- package/dist/dsl/compile/compile-view.d.ts +2 -0
- package/dist/dsl/compile/compile-view.js +56 -0
- package/dist/dsl/compile/index.d.ts +3 -0
- package/dist/dsl/compile/index.js +10 -0
- package/dist/dsl/compile/join-helpers.d.ts +5 -0
- package/dist/dsl/compile/join-helpers.js +88 -0
- package/dist/dsl/decorators/dimension.decorator.d.ts +2 -0
- package/dist/dsl/decorators/dimension.decorator.js +12 -0
- package/dist/dsl/decorators/explore.decorator.d.ts +2 -0
- package/dist/dsl/decorators/explore.decorator.js +9 -0
- package/dist/dsl/decorators/index.d.ts +7 -0
- package/dist/dsl/decorators/index.js +18 -0
- package/dist/dsl/decorators/join.decorator.d.ts +2 -0
- package/dist/dsl/decorators/join.decorator.js +12 -0
- package/dist/dsl/decorators/measure.decorator.d.ts +2 -0
- package/dist/dsl/decorators/measure.decorator.js +12 -0
- package/dist/dsl/decorators/model.decorator.d.ts +2 -0
- package/dist/dsl/decorators/model.decorator.js +9 -0
- package/dist/dsl/decorators/view.decorator.d.ts +4 -0
- package/dist/dsl/decorators/view.decorator.js +20 -0
- package/dist/dsl/errors/compile-errors.d.ts +12 -0
- package/dist/dsl/errors/compile-errors.js +33 -0
- package/dist/dsl/expr/aggregates.d.ts +6 -0
- package/dist/dsl/expr/aggregates.js +21 -0
- package/dist/dsl/expr/field.d.ts +15 -0
- package/dist/dsl/expr/field.js +44 -0
- package/dist/dsl/expr/index.d.ts +4 -0
- package/dist/dsl/expr/index.js +16 -0
- package/dist/dsl/expr/join-scope.d.ts +5 -0
- package/dist/dsl/expr/join-scope.js +23 -0
- package/dist/dsl/expr/raw.d.ts +2 -0
- package/dist/dsl/expr/raw.js +6 -0
- package/dist/dsl/registry/explore-registry.d.ts +22 -0
- package/dist/dsl/registry/explore-registry.js +22 -0
- package/dist/dsl/registry/model-registry.d.ts +9 -0
- package/dist/dsl/registry/model-registry.js +11 -0
- package/dist/dsl/registry/view-registry.d.ts +32 -0
- package/dist/dsl/registry/view-registry.js +42 -0
- package/dist/dsl/types/join-scope.types.d.ts +9 -0
- package/dist/dsl/types/join-scope.types.js +8 -0
- package/dist/dsl/types/view-name-map.types.d.ts +13 -0
- package/dist/dsl/types/view-name-map.types.js +2 -0
- package/dist/dsl/types/view-proxy.types.d.ts +13 -0
- package/dist/dsl/types/view-proxy.types.js +2 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +39 -0
- package/dist/types/manifest-expr.types.d.ts +37 -0
- package/dist/types/manifest-expr.types.js +26 -0
- package/dist/types/manifest.types.d.ts +54 -0
- package/dist/types/manifest.types.js +2 -0
- package/dist/validate/expr-semantic.d.ts +6 -0
- package/dist/validate/expr-semantic.js +117 -0
- package/dist/validate/semantic-rules.d.ts +3 -0
- package/dist/validate/semantic-rules.js +68 -0
- package/dist/validate/structural.d.ts +2 -0
- package/dist/validate/structural.js +27 -0
- package/dist/validate/validate-manifest.d.ts +2 -0
- package/dist/validate/validate-manifest.js +16 -0
- package/dist/validate/validation-result.d.ts +10 -0
- package/dist/validate/validation-result.js +2 -0
- package/manifest.schema.json +207 -0
- package/package.json +47 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SCHEMA_VERSION: "1.1";
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compileExplore = compileExplore;
|
|
4
|
+
require("reflect-metadata");
|
|
5
|
+
const compile_errors_js_1 = require("../errors/compile-errors.js");
|
|
6
|
+
const explore_registry_js_1 = require("../registry/explore-registry.js");
|
|
7
|
+
const view_registry_js_1 = require("../registry/view-registry.js");
|
|
8
|
+
const compile_view_js_1 = require("./compile-view.js");
|
|
9
|
+
const join_helpers_js_1 = require("./join-helpers.js");
|
|
10
|
+
function compileExplore(ExploreClass) {
|
|
11
|
+
const exploreMeta = (0, explore_registry_js_1.getExploreMeta)(ExploreClass);
|
|
12
|
+
if (!exploreMeta) {
|
|
13
|
+
throw new compile_errors_js_1.MissingMetadataError('Explore', ExploreClass.name);
|
|
14
|
+
}
|
|
15
|
+
const fromViewMeta = (0, view_registry_js_1.getViewMeta)(exploreMeta.from);
|
|
16
|
+
if (!fromViewMeta) {
|
|
17
|
+
throw new compile_errors_js_1.MissingMetadataError('View', exploreMeta.from.name);
|
|
18
|
+
}
|
|
19
|
+
const joinEntries = (0, explore_registry_js_1.getJoins)(ExploreClass.prototype);
|
|
20
|
+
const scopedViewNames = [fromViewMeta.name];
|
|
21
|
+
const viewClasses = new Map([
|
|
22
|
+
[fromViewMeta.name, exploreMeta.from],
|
|
23
|
+
]);
|
|
24
|
+
const joins = [];
|
|
25
|
+
for (const entry of joinEntries) {
|
|
26
|
+
const fromViewClass = Reflect.getMetadata('design:type', ExploreClass.prototype, entry.propertyKey);
|
|
27
|
+
if (!fromViewClass) {
|
|
28
|
+
throw new compile_errors_js_1.MissingMetadataError('Join fromView', `${ExploreClass.name}.${entry.propertyKey}`);
|
|
29
|
+
}
|
|
30
|
+
const joinViewMeta = (0, view_registry_js_1.getViewMeta)(fromViewClass);
|
|
31
|
+
if (!joinViewMeta) {
|
|
32
|
+
throw new compile_errors_js_1.MissingMetadataError('View', fromViewClass.name);
|
|
33
|
+
}
|
|
34
|
+
const scopeViewNames = [...scopedViewNames, joinViewMeta.name];
|
|
35
|
+
const scope = (0, join_helpers_js_1.createJoinScope)(scopeViewNames);
|
|
36
|
+
const allowedViews = new Set(scopeViewNames);
|
|
37
|
+
const rawExpr = entry.options.sqlOn(scope);
|
|
38
|
+
(0, join_helpers_js_1.assertJoinScope)(rawExpr, allowedViews, exploreMeta.name, entry.propertyKey);
|
|
39
|
+
const on = (0, join_helpers_js_1.emitJoinOn)(fromViewMeta.name, joinViewMeta.name, rawExpr);
|
|
40
|
+
joins.push({
|
|
41
|
+
name: entry.propertyKey,
|
|
42
|
+
fromView: joinViewMeta.name,
|
|
43
|
+
on,
|
|
44
|
+
type: entry.options.type,
|
|
45
|
+
relationship: entry.options.relationship,
|
|
46
|
+
});
|
|
47
|
+
if (!viewClasses.has(joinViewMeta.name)) {
|
|
48
|
+
viewClasses.set(joinViewMeta.name, fromViewClass);
|
|
49
|
+
}
|
|
50
|
+
scopedViewNames.push(joinViewMeta.name);
|
|
51
|
+
}
|
|
52
|
+
const views = [...viewClasses.values()].map((ViewClass) => (0, compile_view_js_1.compileView)(ViewClass));
|
|
53
|
+
return {
|
|
54
|
+
name: exploreMeta.name,
|
|
55
|
+
label: exploreMeta.label,
|
|
56
|
+
from: fromViewMeta.name,
|
|
57
|
+
joins,
|
|
58
|
+
views,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Model } from '../../types/manifest.types.js';
|
|
2
|
+
import type { ViewConstructor } from '../registry/explore-registry.js';
|
|
3
|
+
export declare function compileModel(ModelClass: ViewConstructor): Model;
|
|
4
|
+
export declare function compileModels(classes: ViewConstructor[]): Model[];
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compileModel = compileModel;
|
|
4
|
+
exports.compileModels = compileModels;
|
|
5
|
+
const compile_errors_js_1 = require("../errors/compile-errors.js");
|
|
6
|
+
const model_registry_js_1 = require("../registry/model-registry.js");
|
|
7
|
+
const compile_explore_js_1 = require("./compile-explore.js");
|
|
8
|
+
function compileModel(ModelClass) {
|
|
9
|
+
const meta = (0, model_registry_js_1.getModelMeta)(ModelClass);
|
|
10
|
+
if (!meta) {
|
|
11
|
+
throw new compile_errors_js_1.MissingMetadataError('Model', ModelClass.name);
|
|
12
|
+
}
|
|
13
|
+
const exploreNames = new Set();
|
|
14
|
+
const explores = meta.explores.map((ExploreClass) => {
|
|
15
|
+
const compiled = (0, compile_explore_js_1.compileExplore)(ExploreClass);
|
|
16
|
+
if (exploreNames.has(compiled.name)) {
|
|
17
|
+
throw new compile_errors_js_1.DuplicateNameError('explore', compiled.name, meta.name);
|
|
18
|
+
}
|
|
19
|
+
exploreNames.add(compiled.name);
|
|
20
|
+
return compiled;
|
|
21
|
+
});
|
|
22
|
+
return {
|
|
23
|
+
name: meta.name,
|
|
24
|
+
label: meta.label,
|
|
25
|
+
connectionName: meta.connection,
|
|
26
|
+
explores,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function compileModels(classes) {
|
|
30
|
+
const modelNames = new Set();
|
|
31
|
+
return classes.map((ModelClass) => {
|
|
32
|
+
const model = compileModel(ModelClass);
|
|
33
|
+
if (modelNames.has(model.name)) {
|
|
34
|
+
throw new compile_errors_js_1.DuplicateNameError('model', model.name);
|
|
35
|
+
}
|
|
36
|
+
modelNames.add(model.name);
|
|
37
|
+
return model;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compileView = compileView;
|
|
4
|
+
const manifest_expr_types_js_1 = require("../../types/manifest-expr.types.js");
|
|
5
|
+
const compile_errors_js_1 = require("../errors/compile-errors.js");
|
|
6
|
+
const view_registry_js_1 = require("../registry/view-registry.js");
|
|
7
|
+
function compileView(ViewClass) {
|
|
8
|
+
const viewMeta = (0, view_registry_js_1.getViewMeta)(ViewClass);
|
|
9
|
+
if (!viewMeta) {
|
|
10
|
+
throw new compile_errors_js_1.MissingMetadataError('View', ViewClass.name);
|
|
11
|
+
}
|
|
12
|
+
const dimensionEntries = (0, view_registry_js_1.getDimensions)(ViewClass.prototype);
|
|
13
|
+
const measureEntries = (0, view_registry_js_1.getMeasures)(ViewClass.prototype);
|
|
14
|
+
const instance = new ViewClass();
|
|
15
|
+
const dimensions = dimensionEntries.map((entry) => ({
|
|
16
|
+
groupLabel: entry.options.groupLabel,
|
|
17
|
+
name: entry.propertyKey,
|
|
18
|
+
label: entry.options.label,
|
|
19
|
+
type: entry.options.type,
|
|
20
|
+
expression: `${viewMeta.name}.${entry.propertyKey}`,
|
|
21
|
+
}));
|
|
22
|
+
const measurements = measureEntries.map((entry) => {
|
|
23
|
+
const raw = instance[entry.propertyKey];
|
|
24
|
+
const expression = validateMeasureExpression(raw, entry.options.type, viewMeta.name, entry.propertyKey);
|
|
25
|
+
return {
|
|
26
|
+
groupLabel: entry.options.groupLabel,
|
|
27
|
+
name: entry.propertyKey,
|
|
28
|
+
label: entry.options.label,
|
|
29
|
+
type: entry.options.type,
|
|
30
|
+
expression,
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
return {
|
|
34
|
+
name: viewMeta.name,
|
|
35
|
+
label: viewMeta.label,
|
|
36
|
+
sql: { tableName: viewMeta.table },
|
|
37
|
+
dimensions,
|
|
38
|
+
measurements,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function validateMeasureExpression(value, expectedType, viewName, propertyKey) {
|
|
42
|
+
if (!(0, manifest_expr_types_js_1.isManifestExprObject)(value) || value.kind !== 'aggregate') {
|
|
43
|
+
throw new compile_errors_js_1.InvalidMeasureError(viewName, propertyKey, 'expression must be an aggregate node');
|
|
44
|
+
}
|
|
45
|
+
if (value.fn !== expectedType) {
|
|
46
|
+
throw new compile_errors_js_1.InvalidMeasureError(viewName, propertyKey, `aggregate fn '${value.fn}' does not match measure type '${expectedType}'`);
|
|
47
|
+
}
|
|
48
|
+
if (!(0, manifest_expr_types_js_1.isRefString)(value.operand)) {
|
|
49
|
+
throw new compile_errors_js_1.InvalidMeasureError(viewName, propertyKey, 'aggregate operand must be a view.field ref string');
|
|
50
|
+
}
|
|
51
|
+
const expectedPrefix = `${viewName}.`;
|
|
52
|
+
if (!value.operand.startsWith(expectedPrefix)) {
|
|
53
|
+
throw new compile_errors_js_1.InvalidMeasureError(viewName, propertyKey, `operand '${value.operand}' must reference view '${viewName}'`);
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compileModels = exports.compileModel = exports.compileExplore = exports.compileView = void 0;
|
|
4
|
+
var compile_view_js_1 = require("./compile-view.js");
|
|
5
|
+
Object.defineProperty(exports, "compileView", { enumerable: true, get: function () { return compile_view_js_1.compileView; } });
|
|
6
|
+
var compile_explore_js_1 = require("./compile-explore.js");
|
|
7
|
+
Object.defineProperty(exports, "compileExplore", { enumerable: true, get: function () { return compile_explore_js_1.compileExplore; } });
|
|
8
|
+
var compile_model_js_1 = require("./compile-model.js");
|
|
9
|
+
Object.defineProperty(exports, "compileModel", { enumerable: true, get: function () { return compile_model_js_1.compileModel; } });
|
|
10
|
+
Object.defineProperty(exports, "compileModels", { enumerable: true, get: function () { return compile_model_js_1.compileModels; } });
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { JoinOn, ManifestExpr } from '../../types/manifest-expr.types.js';
|
|
2
|
+
export declare function createJoinScope(viewNames: string[]): Record<string, unknown>;
|
|
3
|
+
export declare function collectRefViews(expr: ManifestExpr): Set<string>;
|
|
4
|
+
export declare function assertJoinScope(expr: ManifestExpr, allowedViews: Set<string>, exploreName: string, joinName: string): void;
|
|
5
|
+
export declare function emitJoinOn(fromViewName: string, joinFromViewName: string, expr: ManifestExpr): JoinOn;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createJoinScope = createJoinScope;
|
|
4
|
+
exports.collectRefViews = collectRefViews;
|
|
5
|
+
exports.assertJoinScope = assertJoinScope;
|
|
6
|
+
exports.emitJoinOn = emitJoinOn;
|
|
7
|
+
const manifest_expr_types_js_1 = require("../../types/manifest-expr.types.js");
|
|
8
|
+
const compile_errors_js_1 = require("../errors/compile-errors.js");
|
|
9
|
+
const field_js_1 = require("../expr/field.js");
|
|
10
|
+
function createJoinScope(viewNames) {
|
|
11
|
+
const scope = {};
|
|
12
|
+
for (const viewName of viewNames) {
|
|
13
|
+
scope[viewName] = createViewProxy(viewName);
|
|
14
|
+
}
|
|
15
|
+
return scope;
|
|
16
|
+
}
|
|
17
|
+
function createViewProxy(viewName) {
|
|
18
|
+
return new Proxy({}, {
|
|
19
|
+
get(_target, prop) {
|
|
20
|
+
if (typeof prop !== 'string') {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
return (0, field_js_1.field)(viewName, prop);
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function collectRefViews(expr) {
|
|
28
|
+
const views = new Set();
|
|
29
|
+
for (const ref of collectRefs(expr)) {
|
|
30
|
+
views.add(ref.split('.')[0]);
|
|
31
|
+
}
|
|
32
|
+
return views;
|
|
33
|
+
}
|
|
34
|
+
function collectRefs(expr) {
|
|
35
|
+
if ((0, manifest_expr_types_js_1.isRefString)(expr)) {
|
|
36
|
+
return [expr];
|
|
37
|
+
}
|
|
38
|
+
if (!(0, manifest_expr_types_js_1.isManifestExprObject)(expr)) {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
switch (expr.kind) {
|
|
42
|
+
case 'raw':
|
|
43
|
+
return [];
|
|
44
|
+
case 'not':
|
|
45
|
+
return collectRefs(expr.operand);
|
|
46
|
+
case 'aggregate':
|
|
47
|
+
return collectRefs(expr.operand);
|
|
48
|
+
case 'eq':
|
|
49
|
+
case 'neq':
|
|
50
|
+
case 'gt':
|
|
51
|
+
case 'gte':
|
|
52
|
+
case 'lt':
|
|
53
|
+
case 'lte':
|
|
54
|
+
return [...collectRefs(expr.left), ...collectRefs(expr.right)];
|
|
55
|
+
case 'and':
|
|
56
|
+
case 'or':
|
|
57
|
+
return [...collectRefs(expr.left), ...collectRefs(expr.right)];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function assertJoinScope(expr, allowedViews, exploreName, joinName) {
|
|
61
|
+
for (const viewName of collectRefViews(expr)) {
|
|
62
|
+
if (!allowedViews.has(viewName)) {
|
|
63
|
+
throw new compile_errors_js_1.JoinScopeError(exploreName, joinName, viewName);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function emitJoinOn(fromViewName, joinFromViewName, expr) {
|
|
68
|
+
const pair = tryEmitPair(fromViewName, joinFromViewName, expr);
|
|
69
|
+
return pair ?? expr;
|
|
70
|
+
}
|
|
71
|
+
function tryEmitPair(fromViewName, joinFromViewName, expr) {
|
|
72
|
+
if (!(0, manifest_expr_types_js_1.isManifestExprObject)(expr) || expr.kind !== 'eq') {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
const { left, right } = expr;
|
|
76
|
+
if (!(0, manifest_expr_types_js_1.isRefString)(left) || !(0, manifest_expr_types_js_1.isRefString)(right)) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
const [leftView, leftField] = left.split('.');
|
|
80
|
+
const [rightView, rightField] = right.split('.');
|
|
81
|
+
if (leftView === fromViewName && rightView === joinFromViewName) {
|
|
82
|
+
return { pair: [leftField, rightField] };
|
|
83
|
+
}
|
|
84
|
+
if (leftView === joinFromViewName && rightView === fromViewName) {
|
|
85
|
+
return { pair: [rightField, leftField] };
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Dimension = Dimension;
|
|
4
|
+
const view_registry_js_1 = require("../registry/view-registry.js");
|
|
5
|
+
function Dimension(options) {
|
|
6
|
+
return (target, propertyKey) => {
|
|
7
|
+
if (typeof propertyKey !== 'string') {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
(0, view_registry_js_1.addDimension)(target, { propertyKey, options });
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Explore = Explore;
|
|
4
|
+
const explore_registry_js_1 = require("../registry/explore-registry.js");
|
|
5
|
+
function Explore(options) {
|
|
6
|
+
return (target) => {
|
|
7
|
+
(0, explore_registry_js_1.registerExplore)(target, options);
|
|
8
|
+
};
|
|
9
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { View } from './view.decorator.js';
|
|
2
|
+
export { Dimension } from './dimension.decorator.js';
|
|
3
|
+
export { Measure } from './measure.decorator.js';
|
|
4
|
+
export { Explore } from './explore.decorator.js';
|
|
5
|
+
export { Join } from './join.decorator.js';
|
|
6
|
+
export { Model } from './model.decorator.js';
|
|
7
|
+
export { joinScope, isJoinScopeTagged } from '../expr/join-scope.js';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isJoinScopeTagged = exports.joinScope = exports.Model = exports.Join = exports.Explore = exports.Measure = exports.Dimension = exports.View = void 0;
|
|
4
|
+
var view_decorator_js_1 = require("./view.decorator.js");
|
|
5
|
+
Object.defineProperty(exports, "View", { enumerable: true, get: function () { return view_decorator_js_1.View; } });
|
|
6
|
+
var dimension_decorator_js_1 = require("./dimension.decorator.js");
|
|
7
|
+
Object.defineProperty(exports, "Dimension", { enumerable: true, get: function () { return dimension_decorator_js_1.Dimension; } });
|
|
8
|
+
var measure_decorator_js_1 = require("./measure.decorator.js");
|
|
9
|
+
Object.defineProperty(exports, "Measure", { enumerable: true, get: function () { return measure_decorator_js_1.Measure; } });
|
|
10
|
+
var explore_decorator_js_1 = require("./explore.decorator.js");
|
|
11
|
+
Object.defineProperty(exports, "Explore", { enumerable: true, get: function () { return explore_decorator_js_1.Explore; } });
|
|
12
|
+
var join_decorator_js_1 = require("./join.decorator.js");
|
|
13
|
+
Object.defineProperty(exports, "Join", { enumerable: true, get: function () { return join_decorator_js_1.Join; } });
|
|
14
|
+
var model_decorator_js_1 = require("./model.decorator.js");
|
|
15
|
+
Object.defineProperty(exports, "Model", { enumerable: true, get: function () { return model_decorator_js_1.Model; } });
|
|
16
|
+
var join_scope_js_1 = require("../expr/join-scope.js");
|
|
17
|
+
Object.defineProperty(exports, "joinScope", { enumerable: true, get: function () { return join_scope_js_1.joinScope; } });
|
|
18
|
+
Object.defineProperty(exports, "isJoinScopeTagged", { enumerable: true, get: function () { return join_scope_js_1.isJoinScopeTagged; } });
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Join = Join;
|
|
4
|
+
const explore_registry_js_1 = require("../registry/explore-registry.js");
|
|
5
|
+
function Join(options) {
|
|
6
|
+
return (target, propertyKey) => {
|
|
7
|
+
if (typeof propertyKey !== 'string') {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
(0, explore_registry_js_1.addJoin)(target, { propertyKey, options });
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Measure = Measure;
|
|
4
|
+
const view_registry_js_1 = require("../registry/view-registry.js");
|
|
5
|
+
function Measure(options) {
|
|
6
|
+
return (target, propertyKey) => {
|
|
7
|
+
if (typeof propertyKey !== 'string') {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
(0, view_registry_js_1.addMeasure)(target, { propertyKey, options });
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Model = Model;
|
|
4
|
+
const model_registry_js_1 = require("../registry/model-registry.js");
|
|
5
|
+
function Model(options) {
|
|
6
|
+
return (target) => {
|
|
7
|
+
(0, model_registry_js_1.registerModel)(target, options);
|
|
8
|
+
};
|
|
9
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.View = View;
|
|
4
|
+
const view_registry_js_1 = require("../registry/view-registry.js");
|
|
5
|
+
const field_js_1 = require("../expr/field.js");
|
|
6
|
+
function View(options) {
|
|
7
|
+
return (target) => {
|
|
8
|
+
(0, view_registry_js_1.registerView)(target, options);
|
|
9
|
+
(0, view_registry_js_1.setViewNameBrand)(target, options.name);
|
|
10
|
+
for (const entry of (0, view_registry_js_1.getDimensions)(target.prototype)) {
|
|
11
|
+
Object.defineProperty(target.prototype, entry.propertyKey, {
|
|
12
|
+
configurable: true,
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get() {
|
|
15
|
+
return (0, field_js_1.field)(options.name, entry.propertyKey);
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class MissingMetadataError extends Error {
|
|
2
|
+
constructor(kind: string, className: string);
|
|
3
|
+
}
|
|
4
|
+
export declare class InvalidMeasureError extends Error {
|
|
5
|
+
constructor(viewName: string, propertyKey: string, reason: string);
|
|
6
|
+
}
|
|
7
|
+
export declare class JoinScopeError extends Error {
|
|
8
|
+
constructor(exploreName: string, joinName: string, viewName: string);
|
|
9
|
+
}
|
|
10
|
+
export declare class DuplicateNameError extends Error {
|
|
11
|
+
constructor(kind: string, name: string, context?: string);
|
|
12
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DuplicateNameError = exports.JoinScopeError = exports.InvalidMeasureError = exports.MissingMetadataError = void 0;
|
|
4
|
+
class MissingMetadataError extends Error {
|
|
5
|
+
constructor(kind, className) {
|
|
6
|
+
super(`${kind} metadata missing on ${className}`);
|
|
7
|
+
this.name = 'MissingMetadataError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.MissingMetadataError = MissingMetadataError;
|
|
11
|
+
class InvalidMeasureError extends Error {
|
|
12
|
+
constructor(viewName, propertyKey, reason) {
|
|
13
|
+
super(`Invalid measure '${viewName}.${propertyKey}': ${reason}`);
|
|
14
|
+
this.name = 'InvalidMeasureError';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.InvalidMeasureError = InvalidMeasureError;
|
|
18
|
+
class JoinScopeError extends Error {
|
|
19
|
+
constructor(exploreName, joinName, viewName) {
|
|
20
|
+
super(`Join '${joinName}' on explore '${exploreName}' references view '${viewName}' outside scope`);
|
|
21
|
+
this.name = 'JoinScopeError';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.JoinScopeError = JoinScopeError;
|
|
25
|
+
class DuplicateNameError extends Error {
|
|
26
|
+
constructor(kind, name, context) {
|
|
27
|
+
super(context
|
|
28
|
+
? `Duplicate ${kind} "${name}" in ${context}`
|
|
29
|
+
: `Duplicate ${kind} "${name}"`);
|
|
30
|
+
this.name = 'DuplicateNameError';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.DuplicateNameError = DuplicateNameError;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ManifestExpr } from '../../types/manifest-expr.types.js';
|
|
2
|
+
import type { Field } from './field.js';
|
|
3
|
+
export declare function count(field: Field<unknown>): ManifestExpr;
|
|
4
|
+
export declare function sum(field: Field<unknown>): ManifestExpr;
|
|
5
|
+
export declare function min(field: Field<unknown>): ManifestExpr;
|
|
6
|
+
export declare function max(field: Field<unknown>): ManifestExpr;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.count = count;
|
|
4
|
+
exports.sum = sum;
|
|
5
|
+
exports.min = min;
|
|
6
|
+
exports.max = max;
|
|
7
|
+
function aggregate(fn, field) {
|
|
8
|
+
return { kind: 'aggregate', fn, operand: field.ref };
|
|
9
|
+
}
|
|
10
|
+
function count(field) {
|
|
11
|
+
return aggregate('count', field);
|
|
12
|
+
}
|
|
13
|
+
function sum(field) {
|
|
14
|
+
return aggregate('sum', field);
|
|
15
|
+
}
|
|
16
|
+
function min(field) {
|
|
17
|
+
return aggregate('min', field);
|
|
18
|
+
}
|
|
19
|
+
function max(field) {
|
|
20
|
+
return aggregate('max', field);
|
|
21
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ManifestExpr, RefString } from '../../types/manifest-expr.types.js';
|
|
2
|
+
export declare class Field<T> {
|
|
3
|
+
readonly ref: RefString;
|
|
4
|
+
constructor(viewName: string, fieldName: string);
|
|
5
|
+
eq(other: Field<unknown> | ManifestExpr): ManifestExpr;
|
|
6
|
+
neq(other: Field<unknown> | ManifestExpr): ManifestExpr;
|
|
7
|
+
gt(other: Field<unknown> | ManifestExpr): ManifestExpr;
|
|
8
|
+
gte(other: Field<unknown> | ManifestExpr): ManifestExpr;
|
|
9
|
+
lt(other: Field<unknown> | ManifestExpr): ManifestExpr;
|
|
10
|
+
lte(other: Field<unknown> | ManifestExpr): ManifestExpr;
|
|
11
|
+
and(other: ManifestExpr): ManifestExpr;
|
|
12
|
+
or(other: ManifestExpr): ManifestExpr;
|
|
13
|
+
not(): ManifestExpr;
|
|
14
|
+
}
|
|
15
|
+
export declare function field<T>(viewName: string, fieldName: string): Field<T>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Field = void 0;
|
|
4
|
+
exports.field = field;
|
|
5
|
+
class Field {
|
|
6
|
+
ref;
|
|
7
|
+
constructor(viewName, fieldName) {
|
|
8
|
+
this.ref = `${viewName}.${fieldName}`;
|
|
9
|
+
}
|
|
10
|
+
eq(other) {
|
|
11
|
+
return { kind: 'eq', left: this.ref, right: toExpr(other) };
|
|
12
|
+
}
|
|
13
|
+
neq(other) {
|
|
14
|
+
return { kind: 'neq', left: this.ref, right: toExpr(other) };
|
|
15
|
+
}
|
|
16
|
+
gt(other) {
|
|
17
|
+
return { kind: 'gt', left: this.ref, right: toExpr(other) };
|
|
18
|
+
}
|
|
19
|
+
gte(other) {
|
|
20
|
+
return { kind: 'gte', left: this.ref, right: toExpr(other) };
|
|
21
|
+
}
|
|
22
|
+
lt(other) {
|
|
23
|
+
return { kind: 'lt', left: this.ref, right: toExpr(other) };
|
|
24
|
+
}
|
|
25
|
+
lte(other) {
|
|
26
|
+
return { kind: 'lte', left: this.ref, right: toExpr(other) };
|
|
27
|
+
}
|
|
28
|
+
and(other) {
|
|
29
|
+
return { kind: 'and', left: this.ref, right: other };
|
|
30
|
+
}
|
|
31
|
+
or(other) {
|
|
32
|
+
return { kind: 'or', left: this.ref, right: other };
|
|
33
|
+
}
|
|
34
|
+
not() {
|
|
35
|
+
return { kind: 'not', operand: this.ref };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.Field = Field;
|
|
39
|
+
function field(viewName, fieldName) {
|
|
40
|
+
return new Field(viewName, fieldName);
|
|
41
|
+
}
|
|
42
|
+
function toExpr(value) {
|
|
43
|
+
return value instanceof Field ? value.ref : value;
|
|
44
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isJoinScopeTagged = exports.joinScope = exports.raw = exports.sum = exports.min = exports.max = exports.count = exports.field = exports.Field = void 0;
|
|
4
|
+
var field_js_1 = require("./field.js");
|
|
5
|
+
Object.defineProperty(exports, "Field", { enumerable: true, get: function () { return field_js_1.Field; } });
|
|
6
|
+
Object.defineProperty(exports, "field", { enumerable: true, get: function () { return field_js_1.field; } });
|
|
7
|
+
var aggregates_js_1 = require("./aggregates.js");
|
|
8
|
+
Object.defineProperty(exports, "count", { enumerable: true, get: function () { return aggregates_js_1.count; } });
|
|
9
|
+
Object.defineProperty(exports, "max", { enumerable: true, get: function () { return aggregates_js_1.max; } });
|
|
10
|
+
Object.defineProperty(exports, "min", { enumerable: true, get: function () { return aggregates_js_1.min; } });
|
|
11
|
+
Object.defineProperty(exports, "sum", { enumerable: true, get: function () { return aggregates_js_1.sum; } });
|
|
12
|
+
var raw_js_1 = require("./raw.js");
|
|
13
|
+
Object.defineProperty(exports, "raw", { enumerable: true, get: function () { return raw_js_1.raw; } });
|
|
14
|
+
var join_scope_js_1 = require("./join-scope.js");
|
|
15
|
+
Object.defineProperty(exports, "joinScope", { enumerable: true, get: function () { return join_scope_js_1.joinScope; } });
|
|
16
|
+
Object.defineProperty(exports, "isJoinScopeTagged", { enumerable: true, get: function () { return join_scope_js_1.isJoinScopeTagged; } });
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ManifestExpr } from '../../types/manifest-expr.types.js';
|
|
2
|
+
import type { JoinScopeProxy } from '../types/view-name-map.types.js';
|
|
3
|
+
import type { JoinScopeSqlOn, JoinScopeTagged } from '../types/join-scope.types.js';
|
|
4
|
+
export declare function joinScope(fn: (...proxies: JoinScopeProxy[]) => ManifestExpr): JoinScopeSqlOn & JoinScopeTagged;
|
|
5
|
+
export { isJoinScopeTagged } from '../types/join-scope.types.js';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isJoinScopeTagged = void 0;
|
|
4
|
+
exports.joinScope = joinScope;
|
|
5
|
+
const joinScopeBrand = Symbol('joinScope');
|
|
6
|
+
function wrapJoinScope(fn) {
|
|
7
|
+
const tagged = {
|
|
8
|
+
__joinScopeBrand: joinScopeBrand,
|
|
9
|
+
fn,
|
|
10
|
+
};
|
|
11
|
+
const sqlOn = ((scope) => {
|
|
12
|
+
const viewNames = Object.keys(scope);
|
|
13
|
+
const proxies = viewNames.map((name) => scope[name]);
|
|
14
|
+
return tagged.fn(...proxies);
|
|
15
|
+
});
|
|
16
|
+
Object.assign(sqlOn, tagged);
|
|
17
|
+
return sqlOn;
|
|
18
|
+
}
|
|
19
|
+
function joinScope(fn) {
|
|
20
|
+
return wrapJoinScope(fn);
|
|
21
|
+
}
|
|
22
|
+
var join_scope_types_js_1 = require("../types/join-scope.types.js");
|
|
23
|
+
Object.defineProperty(exports, "isJoinScopeTagged", { enumerable: true, get: function () { return join_scope_types_js_1.isJoinScopeTagged; } });
|