@atscript/db 0.1.135 → 0.1.136
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/{agg-DKuf_v2L.d.cts → agg-CV7y8nC6.d.cts} +13 -3
- package/dist/{agg-BtlGeRfj.d.mts → agg-D5DHsAby.d.mts} +13 -3
- package/dist/agg.cjs +35 -3
- package/dist/agg.d.cts +2 -2
- package/dist/agg.d.mts +2 -2
- package/dist/agg.mjs +34 -1
- package/dist/aggregate-fns-CGBv3E8S.cjs +87 -0
- package/dist/aggregate-fns-CfsveE1w.mjs +58 -0
- package/dist/{buckets-D6PBXKRJ.d.cts → buckets-kKY0RKYN.d.cts} +60 -17
- package/dist/{buckets-GruoVxH5.d.mts → buckets-y4EzoX7D.d.mts} +60 -17
- package/dist/{db-space-9CH5neN7.d.mts → db-space-BX4K3vb6.d.mts} +126 -7
- package/dist/{db-space-BdtBNTeH.d.cts → db-space-ClG41vJh.d.cts} +126 -7
- package/dist/{db-view-Dm7MpUGB.cjs → db-view-BAzhEUxB.cjs} +391 -92
- package/dist/{db-view-Doh8vPg3.mjs → db-view-BrAtbaOx.mjs} +385 -92
- package/dist/index.cjs +17 -3
- package/dist/index.d.cts +12 -10
- package/dist/index.d.mts +12 -10
- package/dist/index.mjs +14 -4
- package/dist/{nested-writer-wk1EFUNY.cjs → nested-writer-BZNCuqI6.cjs} +16 -2
- package/dist/{nested-writer-CqL24ojl.mjs → nested-writer-FWD5oOYh.mjs} +11 -3
- package/dist/plugin.cjs +215 -75
- package/dist/plugin.mjs +215 -76
- package/dist/rel.cjs +2 -2
- package/dist/rel.d.cts +2 -20
- package/dist/rel.d.mts +2 -20
- package/dist/rel.mjs +2 -2
- package/dist/relation-helpers-BVjQflL_.d.cts +30 -0
- package/dist/relation-helpers-D4haLo1n.d.mts +30 -0
- package/dist/{relation-loader-BD4xANQJ.cjs → relation-loader-6ZB_5KFq.cjs} +1 -1
- package/dist/{relation-loader-B68R1LET.mjs → relation-loader-CTFaZpVa.mjs} +1 -1
- package/dist/shared.cjs +5 -1
- package/dist/shared.d.cts +16 -3
- package/dist/shared.d.mts +16 -3
- package/dist/shared.mjs +2 -2
- package/dist/sync.cjs +37 -10
- package/dist/sync.d.cts +24 -4
- package/dist/sync.d.mts +24 -4
- package/dist/sync.mjs +37 -10
- package/dist/{validation-utils-MWOP1Ts4.mjs → validation-utils-B4h-GW4d.mjs} +29 -7
- package/dist/{validation-utils-B7SXPkm7.cjs → validation-utils-Dg0hW6dn.cjs} +52 -6
- package/dist/{validator-CewfnGZj.d.mts → validator-Drb2N-YL.d.cts} +1 -1
- package/dist/{validator-CewfnGZj.d.cts → validator-Drb2N-YL.d.mts} +1 -1
- package/dist/validator.d.cts +1 -1
- package/dist/validator.d.mts +1 -1
- package/package.json +1 -1
- package/dist/agg-CvXDGnKi.mjs +0 -61
- package/dist/agg-EcIbAFnJ.cjs +0 -78
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import { AggregateControls, AggregateExpr as AggregateExpr$1, AggregateFn, AggregateFn as AggregateFn$1, AggregateQuery as AggregateQuery$1, AggregateResult, BucketExpr, BucketUnit as BucketUnit$1, CalendarBucketLabel, ComputedExpr, ResolvedBucket as ResolvedBucket$1, WeekStart, isAggregateExpr, isBucketExpr, resolveAlias } from "@uniqu/core";
|
|
2
2
|
|
|
3
3
|
//#region src/query/aggregate-fns.d.ts
|
|
4
|
-
/**
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* The aggregate functions atscript-db knows — uniqu's full `AggregateFn` set.
|
|
6
|
+
* Which of them an adapter renders is its `aggregateFns()` capability.
|
|
7
|
+
*/
|
|
8
|
+
type TDbAggregateFn = AggregateFn;
|
|
9
|
+
/**
|
|
10
|
+
* Every aggregate function — what an adapter that renders them all returns
|
|
11
|
+
* from `aggregateFns()`.
|
|
12
|
+
*
|
|
13
|
+
* @since 0.1.136
|
|
14
|
+
*/
|
|
15
|
+
declare const ALL_AGGREGATE_FNS: ReadonlySet<TDbAggregateFn>;
|
|
6
16
|
/**
|
|
7
17
|
* Throws `DbError` `INVALID_QUERY` (uniqu's wording) unless `fn` is in
|
|
8
18
|
* `SUPPORTED_AGGREGATE_FNS` — for adapters to re-assert before rendering.
|
|
@@ -40,4 +50,4 @@ declare function resolveAggregateSearch(controls: {
|
|
|
40
50
|
[key: `$${string}`]: unknown;
|
|
41
51
|
} | undefined): TAggregateSearch | undefined;
|
|
42
52
|
//#endregion
|
|
43
|
-
export {
|
|
53
|
+
export { TDbAggregateFn as _, AggregateResult as a, CalendarBucketLabel as c, WeekStart as d, isAggregateExpr as f, ALL_AGGREGATE_FNS as g, resolveAlias as h, AggregateQuery$1 as i, ComputedExpr as l, resolveAggregateSearch as m, AggregateExpr$1 as n, BucketExpr as o, isBucketExpr as p, AggregateFn$1 as r, BucketUnit$1 as s, AggregateControls as t, ResolvedBucket$1 as u, assertAggregateFn as v };
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import { AggregateControls, AggregateExpr as AggregateExpr$1, AggregateFn, AggregateFn as AggregateFn$1, AggregateQuery as AggregateQuery$1, AggregateResult, BucketExpr, BucketUnit as BucketUnit$1, CalendarBucketLabel, ComputedExpr, ResolvedBucket as ResolvedBucket$1, WeekStart, isAggregateExpr as isAggregateExpr$1, isBucketExpr as isBucketExpr$1, resolveAlias } from "@uniqu/core";
|
|
2
2
|
|
|
3
3
|
//#region src/query/aggregate-fns.d.ts
|
|
4
|
-
/**
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* The aggregate functions atscript-db knows — uniqu's full `AggregateFn` set.
|
|
6
|
+
* Which of them an adapter renders is its `aggregateFns()` capability.
|
|
7
|
+
*/
|
|
8
|
+
type TDbAggregateFn = AggregateFn;
|
|
9
|
+
/**
|
|
10
|
+
* Every aggregate function — what an adapter that renders them all returns
|
|
11
|
+
* from `aggregateFns()`.
|
|
12
|
+
*
|
|
13
|
+
* @since 0.1.136
|
|
14
|
+
*/
|
|
15
|
+
declare const ALL_AGGREGATE_FNS: ReadonlySet<TDbAggregateFn>;
|
|
6
16
|
/**
|
|
7
17
|
* Throws `DbError` `INVALID_QUERY` (uniqu's wording) unless `fn` is in
|
|
8
18
|
* `SUPPORTED_AGGREGATE_FNS` — for adapters to re-assert before rendering.
|
|
@@ -40,4 +50,4 @@ declare function resolveAggregateSearch(controls: {
|
|
|
40
50
|
[key: `$${string}`]: unknown;
|
|
41
51
|
} | undefined): TAggregateSearch | undefined;
|
|
42
52
|
//#endregion
|
|
43
|
-
export {
|
|
53
|
+
export { TDbAggregateFn as _, AggregateResult as a, CalendarBucketLabel as c, WeekStart as d, isAggregateExpr$1 as f, ALL_AGGREGATE_FNS as g, resolveAlias as h, AggregateQuery$1 as i, ComputedExpr as l, resolveAggregateSearch as m, AggregateExpr$1 as n, BucketExpr as o, isBucketExpr$1 as p, AggregateFn$1 as r, BucketUnit$1 as s, AggregateControls as t, ResolvedBucket$1 as u, assertAggregateFn as v };
|
package/dist/agg.cjs
CHANGED
|
@@ -1,7 +1,39 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const
|
|
2
|
+
const require_aggregate_fns = require("./aggregate-fns-CGBv3E8S.cjs");
|
|
3
3
|
let _uniqu_core = require("@uniqu/core");
|
|
4
|
-
|
|
4
|
+
//#region src/agg.ts
|
|
5
|
+
/**
|
|
6
|
+
* Reads the `$search` / `$index` controls of an aggregate query.
|
|
7
|
+
*
|
|
8
|
+
* Search and grouping are orthogonal: `$search` narrows the ROWS, `$groupBy`
|
|
9
|
+
* shapes what is left. Every adapter must therefore apply the search predicate
|
|
10
|
+
* BEFORE grouping, so the groups — and `$count`, which counts them — only ever
|
|
11
|
+
* describe rows that matched. An adapter that silently ignored the term would
|
|
12
|
+
* report totals for rows the same search excludes from the leaf list.
|
|
13
|
+
*
|
|
14
|
+
* Two rules the leaf search path applies and the grouped path must NOT:
|
|
15
|
+
* - **No implicit relevance ordering.** Relevance is a property of a row, not
|
|
16
|
+
* of a group; after `$group` there is no per-row score left to sort on.
|
|
17
|
+
* Grouped results order by `$sort` or not at all.
|
|
18
|
+
* - **No implicit row cap.** The leaf runners cap an unbounded search at 1000
|
|
19
|
+
* rows; applying that before `$group` would silently truncate group counts.
|
|
20
|
+
*
|
|
21
|
+
* Returns `undefined` when there is nothing to search for, so callers fall
|
|
22
|
+
* straight through to the plain grouped path.
|
|
23
|
+
*/
|
|
24
|
+
function resolveAggregateSearch(controls) {
|
|
25
|
+
const raw = controls?.$search;
|
|
26
|
+
if (typeof raw !== "string") return;
|
|
27
|
+
const text = raw.trim();
|
|
28
|
+
if (!text) return;
|
|
29
|
+
const index = controls?.$index;
|
|
30
|
+
return {
|
|
31
|
+
text,
|
|
32
|
+
indexName: typeof index === "string" && index ? index : void 0
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
exports.assertAggregateFn = require_aggregate_fns.assertAggregateFn;
|
|
5
37
|
Object.defineProperty(exports, "isAggregateExpr", {
|
|
6
38
|
enumerable: true,
|
|
7
39
|
get: function() {
|
|
@@ -14,7 +46,7 @@ Object.defineProperty(exports, "isBucketExpr", {
|
|
|
14
46
|
return _uniqu_core.isBucketExpr;
|
|
15
47
|
}
|
|
16
48
|
});
|
|
17
|
-
exports.resolveAggregateSearch =
|
|
49
|
+
exports.resolveAggregateSearch = resolveAggregateSearch;
|
|
18
50
|
Object.defineProperty(exports, "resolveAlias", {
|
|
19
51
|
enumerable: true,
|
|
20
52
|
get: function() {
|
package/dist/agg.d.cts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as TResolvedBucket } from "./buckets-
|
|
2
|
-
import { _ as
|
|
1
|
+
import { n as TResolvedBucket } from "./buckets-kKY0RKYN.cjs";
|
|
2
|
+
import { _ as TDbAggregateFn, a as AggregateResult, c as CalendarBucketLabel, d as WeekStart, f as isAggregateExpr, h as resolveAlias, i as AggregateQuery, l as ComputedExpr, m as resolveAggregateSearch, n as AggregateExpr, o as BucketExpr, p as isBucketExpr, r as AggregateFn, s as BucketUnit, t as AggregateControls, u as ResolvedBucket, v as assertAggregateFn } from "./agg-CV7y8nC6.cjs";
|
|
3
3
|
export { type AggregateControls, type AggregateExpr, type AggregateFn, type AggregateQuery, type AggregateResult, type BucketExpr, type BucketUnit, type CalendarBucketLabel, type ComputedExpr, type ResolvedBucket, type TDbAggregateFn, type TResolvedBucket, type WeekStart, assertAggregateFn, isAggregateExpr, isBucketExpr, resolveAggregateSearch, resolveAlias };
|
package/dist/agg.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as TResolvedBucket } from "./buckets-
|
|
2
|
-
import { _ as
|
|
1
|
+
import { n as TResolvedBucket } from "./buckets-y4EzoX7D.mjs";
|
|
2
|
+
import { _ as TDbAggregateFn, a as AggregateResult, c as CalendarBucketLabel, d as WeekStart, f as isAggregateExpr, h as resolveAlias, i as AggregateQuery, l as ComputedExpr, m as resolveAggregateSearch, n as AggregateExpr, o as BucketExpr, p as isBucketExpr, r as AggregateFn, s as BucketUnit, t as AggregateControls, u as ResolvedBucket, v as assertAggregateFn } from "./agg-D5DHsAby.mjs";
|
|
3
3
|
export { type AggregateControls, type AggregateExpr, type AggregateFn, type AggregateQuery, type AggregateResult, type BucketExpr, type BucketUnit, type CalendarBucketLabel, type ComputedExpr, type ResolvedBucket, type TDbAggregateFn, type TResolvedBucket, type WeekStart, assertAggregateFn, isAggregateExpr, isBucketExpr, resolveAggregateSearch, resolveAlias };
|
package/dist/agg.mjs
CHANGED
|
@@ -1,2 +1,35 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as assertAggregateFn } from "./aggregate-fns-CfsveE1w.mjs";
|
|
2
|
+
import { isAggregateExpr, isBucketExpr, resolveAlias } from "@uniqu/core";
|
|
3
|
+
//#region src/agg.ts
|
|
4
|
+
/**
|
|
5
|
+
* Reads the `$search` / `$index` controls of an aggregate query.
|
|
6
|
+
*
|
|
7
|
+
* Search and grouping are orthogonal: `$search` narrows the ROWS, `$groupBy`
|
|
8
|
+
* shapes what is left. Every adapter must therefore apply the search predicate
|
|
9
|
+
* BEFORE grouping, so the groups — and `$count`, which counts them — only ever
|
|
10
|
+
* describe rows that matched. An adapter that silently ignored the term would
|
|
11
|
+
* report totals for rows the same search excludes from the leaf list.
|
|
12
|
+
*
|
|
13
|
+
* Two rules the leaf search path applies and the grouped path must NOT:
|
|
14
|
+
* - **No implicit relevance ordering.** Relevance is a property of a row, not
|
|
15
|
+
* of a group; after `$group` there is no per-row score left to sort on.
|
|
16
|
+
* Grouped results order by `$sort` or not at all.
|
|
17
|
+
* - **No implicit row cap.** The leaf runners cap an unbounded search at 1000
|
|
18
|
+
* rows; applying that before `$group` would silently truncate group counts.
|
|
19
|
+
*
|
|
20
|
+
* Returns `undefined` when there is nothing to search for, so callers fall
|
|
21
|
+
* straight through to the plain grouped path.
|
|
22
|
+
*/
|
|
23
|
+
function resolveAggregateSearch(controls) {
|
|
24
|
+
const raw = controls?.$search;
|
|
25
|
+
if (typeof raw !== "string") return;
|
|
26
|
+
const text = raw.trim();
|
|
27
|
+
if (!text) return;
|
|
28
|
+
const index = controls?.$index;
|
|
29
|
+
return {
|
|
30
|
+
text,
|
|
31
|
+
indexName: typeof index === "string" && index ? index : void 0
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
2
35
|
export { assertAggregateFn, isAggregateExpr, isBucketExpr, resolveAggregateSearch, resolveAlias };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const require_db_error = require("./db-error-DTkkeu5b.cjs");
|
|
2
|
+
//#region src/query/aggregate-fns.ts
|
|
3
|
+
/**
|
|
4
|
+
* The only `$fn` names a `$select` aggregate may use. Any other name is rejected with
|
|
5
|
+
* `INVALID_QUERY` (HTTP 400 through moost-db) before a query reaches an
|
|
6
|
+
* adapter, so no adapter ever renders an unchecked function name into SQL or
|
|
7
|
+
* a pipeline. A known name missing from the adapter's `aggregateFns()` is
|
|
8
|
+
* `AGG_FN_NOT_SUPPORTED`.
|
|
9
|
+
*/
|
|
10
|
+
const SUPPORTED_AGGREGATE_FNS = [
|
|
11
|
+
"sum",
|
|
12
|
+
"count",
|
|
13
|
+
"avg",
|
|
14
|
+
"min",
|
|
15
|
+
"max",
|
|
16
|
+
"countDistinct"
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* The aggregates that are NULL over no (non-null) value — every function but
|
|
20
|
+
* the counts, which are 0. So a view field reading a left-joined table must be
|
|
21
|
+
* optional unless it counts, and a CONDITIONAL one must be optional when no
|
|
22
|
+
* row may match — except `sum`, whose conditional form is rendered as
|
|
23
|
+
* `COALESCE(…, 0)`.
|
|
24
|
+
*/
|
|
25
|
+
const NULL_WHEN_EMPTY_AGGREGATE_FNS = new Set([
|
|
26
|
+
"sum",
|
|
27
|
+
"avg",
|
|
28
|
+
"min",
|
|
29
|
+
"max"
|
|
30
|
+
]);
|
|
31
|
+
/** `BaseDbAdapter.aggregateFns()` by default: every function except `countDistinct`. */
|
|
32
|
+
const BASE_AGGREGATE_FNS = new Set([
|
|
33
|
+
"sum",
|
|
34
|
+
"count",
|
|
35
|
+
"avg",
|
|
36
|
+
"min",
|
|
37
|
+
"max"
|
|
38
|
+
]);
|
|
39
|
+
/**
|
|
40
|
+
* Every aggregate function — what an adapter that renders them all returns
|
|
41
|
+
* from `aggregateFns()`.
|
|
42
|
+
*
|
|
43
|
+
* @since 0.1.136
|
|
44
|
+
*/
|
|
45
|
+
const ALL_AGGREGATE_FNS = new Set(SUPPORTED_AGGREGATE_FNS);
|
|
46
|
+
const SUPPORTED_LIST = `${SUPPORTED_AGGREGATE_FNS.slice(0, -1).join(", ")} or ${SUPPORTED_AGGREGATE_FNS.at(-1)}`;
|
|
47
|
+
/**
|
|
48
|
+
* Throws `DbError` `INVALID_QUERY` (uniqu's wording) unless `fn` is in
|
|
49
|
+
* `SUPPORTED_AGGREGATE_FNS` — for adapters to re-assert before rendering.
|
|
50
|
+
*/
|
|
51
|
+
function assertAggregateFn(fn, path = "$select") {
|
|
52
|
+
if (!SUPPORTED_AGGREGATE_FNS.includes(fn)) throw new require_db_error.DbError("INVALID_QUERY", [{
|
|
53
|
+
path,
|
|
54
|
+
message: `Unknown aggregate function "${String(fn)}" — use ${SUPPORTED_LIST}`
|
|
55
|
+
}]);
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
Object.defineProperty(exports, "ALL_AGGREGATE_FNS", {
|
|
59
|
+
enumerable: true,
|
|
60
|
+
get: function() {
|
|
61
|
+
return ALL_AGGREGATE_FNS;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
Object.defineProperty(exports, "BASE_AGGREGATE_FNS", {
|
|
65
|
+
enumerable: true,
|
|
66
|
+
get: function() {
|
|
67
|
+
return BASE_AGGREGATE_FNS;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
Object.defineProperty(exports, "NULL_WHEN_EMPTY_AGGREGATE_FNS", {
|
|
71
|
+
enumerable: true,
|
|
72
|
+
get: function() {
|
|
73
|
+
return NULL_WHEN_EMPTY_AGGREGATE_FNS;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
Object.defineProperty(exports, "SUPPORTED_AGGREGATE_FNS", {
|
|
77
|
+
enumerable: true,
|
|
78
|
+
get: function() {
|
|
79
|
+
return SUPPORTED_AGGREGATE_FNS;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
Object.defineProperty(exports, "assertAggregateFn", {
|
|
83
|
+
enumerable: true,
|
|
84
|
+
get: function() {
|
|
85
|
+
return assertAggregateFn;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { r as DbError } from "./db-error-D5uilS_A.mjs";
|
|
2
|
+
//#region src/query/aggregate-fns.ts
|
|
3
|
+
/**
|
|
4
|
+
* The only `$fn` names a `$select` aggregate may use. Any other name is rejected with
|
|
5
|
+
* `INVALID_QUERY` (HTTP 400 through moost-db) before a query reaches an
|
|
6
|
+
* adapter, so no adapter ever renders an unchecked function name into SQL or
|
|
7
|
+
* a pipeline. A known name missing from the adapter's `aggregateFns()` is
|
|
8
|
+
* `AGG_FN_NOT_SUPPORTED`.
|
|
9
|
+
*/
|
|
10
|
+
const SUPPORTED_AGGREGATE_FNS = [
|
|
11
|
+
"sum",
|
|
12
|
+
"count",
|
|
13
|
+
"avg",
|
|
14
|
+
"min",
|
|
15
|
+
"max",
|
|
16
|
+
"countDistinct"
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* The aggregates that are NULL over no (non-null) value — every function but
|
|
20
|
+
* the counts, which are 0. So a view field reading a left-joined table must be
|
|
21
|
+
* optional unless it counts, and a CONDITIONAL one must be optional when no
|
|
22
|
+
* row may match — except `sum`, whose conditional form is rendered as
|
|
23
|
+
* `COALESCE(…, 0)`.
|
|
24
|
+
*/
|
|
25
|
+
const NULL_WHEN_EMPTY_AGGREGATE_FNS = new Set([
|
|
26
|
+
"sum",
|
|
27
|
+
"avg",
|
|
28
|
+
"min",
|
|
29
|
+
"max"
|
|
30
|
+
]);
|
|
31
|
+
/** `BaseDbAdapter.aggregateFns()` by default: every function except `countDistinct`. */
|
|
32
|
+
const BASE_AGGREGATE_FNS = new Set([
|
|
33
|
+
"sum",
|
|
34
|
+
"count",
|
|
35
|
+
"avg",
|
|
36
|
+
"min",
|
|
37
|
+
"max"
|
|
38
|
+
]);
|
|
39
|
+
/**
|
|
40
|
+
* Every aggregate function — what an adapter that renders them all returns
|
|
41
|
+
* from `aggregateFns()`.
|
|
42
|
+
*
|
|
43
|
+
* @since 0.1.136
|
|
44
|
+
*/
|
|
45
|
+
const ALL_AGGREGATE_FNS = new Set(SUPPORTED_AGGREGATE_FNS);
|
|
46
|
+
const SUPPORTED_LIST = `${SUPPORTED_AGGREGATE_FNS.slice(0, -1).join(", ")} or ${SUPPORTED_AGGREGATE_FNS.at(-1)}`;
|
|
47
|
+
/**
|
|
48
|
+
* Throws `DbError` `INVALID_QUERY` (uniqu's wording) unless `fn` is in
|
|
49
|
+
* `SUPPORTED_AGGREGATE_FNS` — for adapters to re-assert before rendering.
|
|
50
|
+
*/
|
|
51
|
+
function assertAggregateFn(fn, path = "$select") {
|
|
52
|
+
if (!SUPPORTED_AGGREGATE_FNS.includes(fn)) throw new DbError("INVALID_QUERY", [{
|
|
53
|
+
path,
|
|
54
|
+
message: `Unknown aggregate function "${String(fn)}" — use ${SUPPORTED_LIST}`
|
|
55
|
+
}]);
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
export { assertAggregateFn as a, SUPPORTED_AGGREGATE_FNS as i, BASE_AGGREGATE_FNS as n, NULL_WHEN_EMPTY_AGGREGATE_FNS as r, ALL_AGGREGATE_FNS as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { f as TFieldOps } from "./ops-AqhV7s9o.cjs";
|
|
2
|
-
import { AggregateControls, AggregateExpr, AggregateExpr as AggregateExpr$1, AggregateFn as AggregateFn$1, AggregateQuery, AggregateQuery as AggregateQuery$1, AggregateResult, BucketUnit, FieldOpsFor, FilterExpr, FilterExpr as FilterExpr$1, ResolvedBucket, TypedWithRelation, Uniquery, Uniquery as Uniquery$1, UniqueryControls, UniqueryControls as UniqueryControls$1, UniqueryInsights, WithRelation, WithRelation as WithRelation$1 } from "@uniqu/core";
|
|
2
|
+
import { AggregateControls, AggregateExpr, AggregateExpr as AggregateExpr$1, AggregateFn, AggregateFn as AggregateFn$1, AggregateQuery, AggregateQuery as AggregateQuery$1, AggregateResult, BucketUnit, FieldOpsFor, FilterExpr, FilterExpr as FilterExpr$1, ResolvedBucket, TypedWithRelation, Uniquery, Uniquery as Uniquery$1, UniqueryControls, UniqueryControls as UniqueryControls$1, UniqueryInsights, WithRelation, WithRelation as WithRelation$1 } from "@uniqu/core";
|
|
3
3
|
import { FlatOf, FlatOf as FlatOf$1, NavPropsOf, NavPropsOf as NavPropsOf$1, OwnPropsOf, OwnPropsOf as OwnPropsOf$1, PrimaryKeyOf, PrimaryKeyOf as PrimaryKeyOf$1, TAtscriptAnnotatedType, TAtscriptDataType, TAtscriptTypeObject, TMetadataMap, TSerializedAnnotatedType, TValidatorOptions, TValidatorPlugin, Validator } from "@atscript/typescript/utils";
|
|
4
4
|
|
|
5
5
|
//#region src/query/uniqu-select.d.ts
|
|
@@ -15,7 +15,7 @@ import { FlatOf, FlatOf as FlatOf$1, NavPropsOf, NavPropsOf as NavPropsOf$1, Own
|
|
|
15
15
|
* An array `$select` holds plain field names and computed entries —
|
|
16
16
|
* aggregates (`{ $fn, $field }`, {@link aggregates}) and calendar buckets
|
|
17
17
|
* (`{ $bucket, $field }`, {@link buckets}). Entries arrive normalized
|
|
18
|
-
* (`
|
|
18
|
+
* (`normalizeComputedSelect` rejects any other shape before translation).
|
|
19
19
|
*/
|
|
20
20
|
declare class UniquSelect {
|
|
21
21
|
private static readonly UNRESOLVED;
|
|
@@ -101,7 +101,7 @@ declare abstract class FieldMappingStrategy {
|
|
|
101
101
|
* equals a field name).
|
|
102
102
|
*
|
|
103
103
|
* `buckets` are the query's calendar buckets as the core's normalizer
|
|
104
|
-
* resolved them (`
|
|
104
|
+
* resolved them (`normalizeComputedSelect` — `AtscriptDbReadable.aggregate`
|
|
105
105
|
* runs it before the guards); they reach adapters with `field` made
|
|
106
106
|
* physical and the source descriptor as `fd`.
|
|
107
107
|
*/
|
|
@@ -111,7 +111,10 @@ declare abstract class FieldMappingStrategy {
|
|
|
111
111
|
/**
|
|
112
112
|
* `$select` with its field paths made physical: array-form names and
|
|
113
113
|
* computed `$field`s (`'*'` kept), or the keys of the object
|
|
114
|
-
* (inclusion / exclusion) form.
|
|
114
|
+
* (inclusion / exclusion) form. An aggregate's output alias is fixed
|
|
115
|
+
* (`$as`) from its LOGICAL field first, so a default alias never leaks a
|
|
116
|
+
* physical name (`sum(amount)` over `@db.column 'amount_cents'` stays
|
|
117
|
+
* `sum_amount`); a bucket's alias is already resolved.
|
|
115
118
|
*/
|
|
116
119
|
protected physicalSelect(select: NonNullable<UniqueryControls["$select"]>, meta: TableMetadata): NonNullable<UniqueryControls["$select"]>;
|
|
117
120
|
/** `$sort` with physical keys; computed `aliases` (grouped queries) pass through. */
|
|
@@ -478,13 +481,15 @@ declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnn
|
|
|
478
481
|
*
|
|
479
482
|
* Validates:
|
|
480
483
|
* - `$select` computed entries and calendar buckets (the shared normalizer,
|
|
481
|
-
* `
|
|
484
|
+
* `normalizeComputedSelect`: shapes, unit, zone, alias, grouping)
|
|
482
485
|
* - Plain fields in $select are a subset of $groupBy
|
|
483
486
|
* - When dimensions/measures are defined (strict mode): $groupBy fields
|
|
484
|
-
* must be dimensions, aggregate $field values must be measures (or '*'
|
|
487
|
+
* must be dimensions, aggregate $field values must be measures (or '*';
|
|
488
|
+
* a `countDistinct` field may also be a dimension)
|
|
485
489
|
* - the path guard (a bucket source must pass `bucketSourceVerdict` —
|
|
486
490
|
* timestamp type, no JSON ancestor, a dimension in strict mode, an
|
|
487
|
-
* adapter with calendar buckets)
|
|
491
|
+
* adapter with calendar buckets), the adapter's aggregate functions
|
|
492
|
+
* (`AGG_FN_NOT_SUPPORTED`) and calendar-bucket units
|
|
488
493
|
* (`BUCKET_NOT_SUPPORTED`)
|
|
489
494
|
*
|
|
490
495
|
* Translates field names, delegates to adapter.aggregate(),
|
|
@@ -497,6 +502,8 @@ declare class AtscriptDbReadable<T extends TAtscriptAnnotatedType = TAtscriptAnn
|
|
|
497
502
|
canFilterField(fd: TDbFieldMeta): boolean;
|
|
498
503
|
/** Calendar-bucket units the adapter can group by (proxies adapter capability; empty = none). */
|
|
499
504
|
calendarBucketUnits(): ReadonlySet<BucketUnit>;
|
|
505
|
+
/** Aggregate functions the adapter renders (proxies adapter capability). @since 0.1.136 */
|
|
506
|
+
aggregateFns(): ReadonlySet<AggregateFn>;
|
|
500
507
|
/** Whether the adapter can sort by a given field (proxies adapter capability). */
|
|
501
508
|
canSortField(fd: TDbFieldMeta): boolean;
|
|
502
509
|
/** Returns available search indexes from the adapter. */
|
|
@@ -799,6 +806,18 @@ declare abstract class BaseDbAdapter {
|
|
|
799
806
|
* out-of-range source, uniqu's `bucketLabel` semantics). Since 0.1.132.
|
|
800
807
|
*/
|
|
801
808
|
calendarBucketUnits(): ReadonlySet<BucketUnit>;
|
|
809
|
+
/**
|
|
810
|
+
* Aggregate functions (`{ $fn, $field }` in an aggregate `$select`) this
|
|
811
|
+
* adapter renders. The default is `sum`, `count`, `avg`, `min` and `max`;
|
|
812
|
+
* an adapter that also implements `countDistinct` (distinct non-null
|
|
813
|
+
* values) returns `ALL_AGGREGATE_FNS`. The core rejects a known function
|
|
814
|
+
* missing from this set with `AGG_FN_NOT_SUPPORTED` before dispatch, so
|
|
815
|
+
* `aggregate()` only ever receives functions listed here; moost-db's
|
|
816
|
+
* `/meta` advertises the set as `aggregateFns`.
|
|
817
|
+
*
|
|
818
|
+
* @since 0.1.136
|
|
819
|
+
*/
|
|
820
|
+
aggregateFns(): ReadonlySet<AggregateFn>;
|
|
802
821
|
/**
|
|
803
822
|
* Whether this adapter enforces foreign key constraints natively.
|
|
804
823
|
* When `true`, the generic layer skips application-level cascade/setNull
|
|
@@ -1468,8 +1487,6 @@ declare class TableMetadata {
|
|
|
1468
1487
|
* Builds the bidirectional pathToPhysical / physicalToPath maps.
|
|
1469
1488
|
*/
|
|
1470
1489
|
private _classifyFields;
|
|
1471
|
-
/** Returns the `__`-separated parent prefix for a dot-separated path, or empty string for top-level paths. */
|
|
1472
|
-
private _flattenedPrefix;
|
|
1473
1490
|
/** Nearest `@db.encrypted` ancestor of `path` (exclusive), or `undefined`. */
|
|
1474
1491
|
/**
|
|
1475
1492
|
* Indexes non-ignored descriptors by logical path and retains the JSON-parent
|
|
@@ -1619,6 +1636,14 @@ interface TMetaResponse {
|
|
|
1619
1636
|
* none. Since 0.1.132.
|
|
1620
1637
|
*/
|
|
1621
1638
|
bucketUnits?: BucketUnit[];
|
|
1639
|
+
/**
|
|
1640
|
+
* Aggregate functions the adapter renders (`{ $fn }` in an aggregate
|
|
1641
|
+
* `$select`, URL `sum(field)` / `countDistinct(field)` …) — see
|
|
1642
|
+
* `BaseDbAdapter.aggregateFns()`.
|
|
1643
|
+
*
|
|
1644
|
+
* @since 0.1.136
|
|
1645
|
+
*/
|
|
1646
|
+
aggregateFns?: AggregateFn[];
|
|
1622
1647
|
}
|
|
1623
1648
|
/** Where the action applies on the UI. */
|
|
1624
1649
|
type TDbActionLevel = "table" | "row" | "rows";
|
|
@@ -1684,12 +1709,24 @@ interface TDbActionInfo {
|
|
|
1684
1709
|
disabled?: string;
|
|
1685
1710
|
/**
|
|
1686
1711
|
* Name of the `.as` interface the action's `@InputForm()` parameter expects
|
|
1687
|
-
* (the compiled class's `.name`). Present
|
|
1688
|
-
*
|
|
1689
|
-
* `GET /meta/form/:name` on the same controller and
|
|
1690
|
-
* collect the `input` field of the action's request
|
|
1712
|
+
* (the compiled class's `.name`). Present for an `@InputForm(FormType)`
|
|
1713
|
+
* parameter or a class-level `inputForm` entry. Clients fetch the
|
|
1714
|
+
* serialized schema via `GET /meta/form/:name` on the same controller and
|
|
1715
|
+
* render a form to collect the `input` field of the action's request
|
|
1716
|
+
* envelope. A class-level entry may name a form served elsewhere — then
|
|
1717
|
+
* {@link formUrl} is present and clients fetch it instead of `meta/form/:name`.
|
|
1691
1718
|
*/
|
|
1692
1719
|
inputForm?: string;
|
|
1720
|
+
/**
|
|
1721
|
+
* Server-absolute path of the serialized form schema —
|
|
1722
|
+
* same convention as `value` for `'backend'` actions: clients prefix
|
|
1723
|
+
* their base URL. Present only together with {@link inputForm}, when the
|
|
1724
|
+
* form is served by another endpoint than this controller's
|
|
1725
|
+
* `meta/form/:name`; clients fetch it instead of the relative route.
|
|
1726
|
+
*
|
|
1727
|
+
* @since 0.1.136
|
|
1728
|
+
*/
|
|
1729
|
+
formUrl?: string;
|
|
1693
1730
|
}
|
|
1694
1731
|
interface TDbInsertResult {
|
|
1695
1732
|
insertedId: unknown;
|
|
@@ -2217,14 +2254,15 @@ interface TBucketFieldSource {
|
|
|
2217
2254
|
navFields: ReadonlySet<string>;
|
|
2218
2255
|
}
|
|
2219
2256
|
/**
|
|
2220
|
-
* The one normalizer of `$select` computed entries
|
|
2257
|
+
* The one normalizer of `$select` computed entries — uniqu's
|
|
2221
2258
|
* `resolveBuckets` (entry shapes, unit, time zone canonicalization, week
|
|
2222
2259
|
* start, alias syntax and uniqueness, "grouped queries only", "must also
|
|
2223
2260
|
* appear in $groupBy", string `$groupBy` entries) with the table's names as
|
|
2224
2261
|
* the collision set: a bucket alias may not equal a logical path, a physical
|
|
2225
2262
|
* column or a navigation field, so a label is never reverse-mapped as a
|
|
2226
2263
|
* column. Aggregate entries are checked against `SUPPORTED_AGGREGATE_FNS`
|
|
2227
|
-
* (and `'*'` is `count`'s only)
|
|
2264
|
+
* (and `'*'` is `count`'s only); whether the adapter renders a function is
|
|
2265
|
+
* `guardAggregate`'s (`aggregateFns()` → `AGG_FN_NOT_SUPPORTED`).
|
|
2228
2266
|
*
|
|
2229
2267
|
* Which layer validates what:
|
|
2230
2268
|
* - **Shapes** (this normalizer) run FIRST at every entry point — the core's
|
|
@@ -2246,10 +2284,15 @@ interface TBucketFieldSource {
|
|
|
2246
2284
|
*
|
|
2247
2285
|
* @throws DbError `INVALID_QUERY` carrying every issue (`path` `$select` / `$groupBy`).
|
|
2248
2286
|
*/
|
|
2249
|
-
declare function
|
|
2287
|
+
declare function normalizeComputedSelect(controls: {
|
|
2250
2288
|
$select?: unknown;
|
|
2251
2289
|
$groupBy?: unknown;
|
|
2252
2290
|
} | undefined, fields: TBucketFieldSource, aggregate?: boolean): ResolvedBucket[];
|
|
2291
|
+
/**
|
|
2292
|
+
* @deprecated since 0.1.136 — renamed {@link normalizeComputedSelect} (it
|
|
2293
|
+
* normalizes every computed `$select` entry, aggregates included).
|
|
2294
|
+
*/
|
|
2295
|
+
declare const resolveCalendarBuckets: typeof normalizeComputedSelect;
|
|
2253
2296
|
/**
|
|
2254
2297
|
* Whether a field's TYPE allows it to be the source of a calendar bucket: a
|
|
2255
2298
|
* `number` / `integer` leaf carrying the `timestamp` tag
|
|
@@ -2275,4 +2318,4 @@ declare function isJsonValueField(fd: TDbFieldMeta): boolean;
|
|
|
2275
2318
|
*/
|
|
2276
2319
|
declare function jsonValueAncestor(path: string, jsonValueParents: ReadonlySet<string>): string | undefined;
|
|
2277
2320
|
//#endregion
|
|
2278
|
-
export {
|
|
2321
|
+
export { TDbWriteGuard as $, TDbActionInfo as A, findAncestorInSet as At, TDbIndex as B, DocumentFieldMapper as Bt, OwnPropsOf$1 as C, TWriteOptions as Ct, TColumnDiff as D, UniqueryControls$1 as Dt, TCascadeTarget as E, Uniquery$1 as Et, TDbDefaultFn as F, AtscriptDbReadable as Ft, TDbObjectKind as G, TDbIndexType as H, NoopLogger as Ht, TDbDefaultValue as I, DbResponse as It, TDbRemoveGuard as J, TDbReferentialAction as K, TDbDeleteResult as L, resolveDesignType as Lt, TDbActionLevel as M, isGeoPointType as Mt, TDbActionProcessor as N, ALL_BUCKET_UNITS as Nt, TCrudOp as O, WithRelation$1 as Ot, TDbCollation as P, BaseDbAdapter as Pt, TDbWriteAction as Q, TDbFieldMeta as R, DbEncryption as Rt, NullableOptional as S, TValueFormatterPair as St, TCascadeResolver as T, TypedWithRelation as Tt, TDbInsertManyResult as U, TGenericLogger as Ut, TDbIndexField as V, FieldMappingStrategy as Vt, TDbInsertResult as W, UniquSelect as Wt, TDbStorageType as X, TDbRemoveGuardContext as Y, TDbUpdateResult as Z, DbRow as _, TSearchIndexInfo as _t, jsonValueAncestor as a, TExistingTableOption as at, FlatOf$1 as b, TTableResolver as bt, AggregateControls as c, TFkLookupTarget as ct, AggregateQuery$1 as d, TIdentification as dt, TDbWriteGuardContext as et, AggregateResult as f, TMetaResponse as ft, DbQuery as g, TRelationInfo as gt, DbPatch as h, TReferencingForeignKey as ht, isJsonValueField as i, TExistingForeignKey as it, TDbActionIntent as j, isGeoIndexableType as jt, TCrudPermissions as k, TableMetadata as kt, AggregateExpr$1 as l, TIdDescriptor as lt, DbControls as m, TPrimaryKeyChange as mt, TResolvedBucket as n, TEnsureTableOptions as nt, normalizeComputedSelect as o, TFieldMeta as ot, AtscriptDbWritable as p, TMetadataOverrides as pt, TDbRelation as q, isBucketableField as r, TExistingColumn as rt, resolveCalendarBuckets as s, TFkLookupResolver as st, TBucketFieldSource as t, TDeleteOptions as tt, AggregateFn$1 as u, TIdResolveOptions as ut, FieldOpsFor as v, TSyncColumnResult as vt, PrimaryKeyOf$1 as w, TWriteTableResolver as wt, NavPropsOf$1 as x, TTouchManyOptions as xt, FilterExpr$1 as y, TTableOptionDiff as yt, TDbForeignKey as z, TDbEncryptionOptions as zt };
|