@prisma/orm-family-sql 0.16.0 → 0.17.0-dev.2
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/aggregate-descriptor-registry-DPV4z8MS.mjs +111 -0
- package/dist/aggregate-descriptor-registry-DPV4z8MS.mjs.map +1 -0
- package/dist/{ast-DSuzmsWn.d.mts → ast--BZUAzN1.d.mts} +3 -4
- package/dist/ast--BZUAzN1.d.mts.map +1 -0
- package/dist/{ast-BstHjAoG.mjs → ast-DDAyIKdt.mjs} +2 -2
- package/dist/ast-DDAyIKdt.mjs.map +1 -0
- package/dist/builder.d.mts +2 -2
- package/dist/builder__runtime.d.mts +14 -10
- package/dist/builder__runtime.d.mts.map +1 -1
- package/dist/builder__runtime.mjs +161 -107
- package/dist/builder__runtime.mjs.map +1 -1
- package/dist/builder__types.d.mts +2 -2
- package/dist/codec-types-B_xmJL2m-CC_Q-_u9.mjs +24 -0
- package/dist/codec-types-B_xmJL2m-CC_Q-_u9.mjs.map +1 -0
- package/dist/{config-types-47qB33rW.d.mts → config-types-DKKhWdzf.d.mts} +2 -2
- package/dist/{config-types-47qB33rW.d.mts.map → config-types-DKKhWdzf.d.mts.map} +1 -1
- package/dist/{contract-builder-MvJJrQ-5.d.mts → contract-builder-Cj-lKWgM.d.mts} +4 -4
- package/dist/{contract-builder-MvJJrQ-5.d.mts.map → contract-builder-Cj-lKWgM.d.mts.map} +1 -1
- package/dist/contract-emitter.mjs +1 -1
- package/dist/contract-psl.d.mts +2 -2
- package/dist/contract-psl__provider.d.mts +1 -1
- package/dist/contract-ts.d.mts +2 -2
- package/dist/contract-ts__config-types.d.mts +1 -1
- package/dist/contract-ts__contract-builder.d.mts +1 -1
- package/dist/contract.d.mts +6 -6
- package/dist/contract__factories.d.mts +1 -1
- package/dist/contract__index-type-validation.d.mts +1 -1
- package/dist/contract__types.d.mts +3 -3
- package/dist/contract__validators.d.mts +1 -1
- package/dist/{control-BHmsZudH.d.mts → control-BqrVERXN.d.mts} +10 -10
- package/dist/{control-BHmsZudH.d.mts.map → control-BqrVERXN.d.mts.map} +1 -1
- package/dist/{control-adapter-C99J7aEF-C-17lFY8.d.mts → control-adapter-C99J7aEF-mjOpiO_9.d.mts} +6 -6
- package/dist/{control-adapter-C99J7aEF-C-17lFY8.d.mts.map → control-adapter-C99J7aEF-mjOpiO_9.d.mts.map} +1 -1
- package/dist/control-adapter-xEtAQKd9.d.mts +1 -0
- package/dist/{control-B7iS4jv4.mjs → control-mG3RlNzm.mjs} +2 -2
- package/dist/{control-B7iS4jv4.mjs.map → control-mG3RlNzm.mjs.map} +1 -1
- package/dist/{db-DhMsmBS--DKENDi3l.d.mts → db-B5PMfDDd-BiWfkubp.d.mts} +65 -32
- package/dist/db-B5PMfDDd-BiWfkubp.d.mts.map +1 -0
- package/dist/{ddl-types-rrMsf77U-DGctYf-T.d.mts → ddl-types-h_3_pXmq-QBLq6WbP.d.mts} +4 -5
- package/dist/ddl-types-h_3_pXmq-QBLq6WbP.d.mts.map +1 -0
- package/dist/{diff-DhlzHOMD.d.mts → diff-CIIMSaVD.d.mts} +5 -5
- package/dist/{diff-DhlzHOMD.d.mts.map → diff-CIIMSaVD.d.mts.map} +1 -1
- package/dist/{dist-DrScXbhq.mjs → dist-CYkK9Vbk.mjs} +55 -2
- package/dist/dist-CYkK9Vbk.mjs.map +1 -0
- package/dist/{expression-RUO52bJB.mjs → expression-Dhu3dLiu.mjs} +2 -2
- package/dist/{expression-RUO52bJB.mjs.map → expression-Dhu3dLiu.mjs.map} +1 -1
- package/dist/{expression-DIf8F4Mc.d.mts → expression-KPBpeH4T.d.mts} +5 -6
- package/dist/expression-KPBpeH4T.d.mts.map +1 -0
- package/dist/{factories-B7tA4y9D.d.mts → factories-MfcqTt5R.d.mts} +2 -2
- package/dist/{factories-B7tA4y9D.d.mts.map → factories-MfcqTt5R.d.mts.map} +1 -1
- package/dist/family.d.mts +9 -9
- package/dist/family.mjs +1 -1
- package/dist/family__control-adapter.d.mts +2 -2
- package/dist/family__control.d.mts +3 -3
- package/dist/family__control.mjs +1 -1
- package/dist/family__diff.d.mts +2 -2
- package/dist/family__ir.d.mts +1 -1
- package/dist/family__migration.d.mts +1 -1
- package/dist/family__runtime.d.mts +1 -1
- package/dist/{index-BgaTJRxj.d.mts → index-BZF7Wehu.d.mts} +3 -3
- package/dist/{index-BgaTJRxj.d.mts.map → index-BZF7Wehu.d.mts.map} +1 -1
- package/dist/{index-Bb9U36N4.d.mts → index-D_QTT11u.d.mts} +15 -16
- package/dist/index-D_QTT11u.d.mts.map +1 -0
- package/dist/{index-type-validation-DN0L2mqm.d.mts → index-type-validation-D_vuj-76.d.mts} +2 -2
- package/dist/{index-type-validation-DN0L2mqm.d.mts.map → index-type-validation-D_vuj-76.d.mts.map} +1 -1
- package/dist/{ir-B3bKMnGQ.d.mts → ir-Cvj3eU-K.d.mts} +2 -2
- package/dist/{ir-B3bKMnGQ.d.mts.map → ir-Cvj3eU-K.d.mts.map} +1 -1
- package/dist/lane-query-builder.d.mts +3 -3
- package/dist/middleware-ChwIEKBC.d.mts +1 -0
- package/dist/{middleware-B4XbF4d4-tfwBl6mX.d.mts → middleware-eb7YwdD4-D0M6ACQ-.d.mts} +3 -3
- package/dist/{middleware-B4XbF4d4-tfwBl6mX.d.mts.map → middleware-eb7YwdD4-D0M6ACQ-.d.mts.map} +1 -1
- package/dist/{migration-CW0ZJLxP.d.mts → migration-Dtyw2JeL.d.mts} +3 -3
- package/dist/{migration-CW0ZJLxP.d.mts.map → migration-Dtyw2JeL.d.mts.map} +1 -1
- package/dist/operations.d.mts +1 -1
- package/dist/orm-client.d.mts +82 -39
- package/dist/orm-client.d.mts.map +1 -1
- package/dist/orm-client.mjs +174 -128
- package/dist/orm-client.mjs.map +1 -1
- package/dist/{plan-BTD8xFfa-Dd_K-A1R.d.mts → plan-Bmp5R9sq-DKMRkx6Z.d.mts} +4 -4
- package/dist/plan-Bmp5R9sq-DKMRkx6Z.d.mts.map +1 -0
- package/dist/plan-mKgmSe0R.d.mts +2 -0
- package/dist/query-lane-context-Dcj4eXUl.d.mts +1 -0
- package/dist/{query-lane-context-DtdVMqoz-C2Tj5QHA.d.mts → query-lane-context-DjyAyYht-HDNYE_oF.d.mts} +62 -6
- package/dist/query-lane-context-DjyAyYht-HDNYE_oF.d.mts.map +1 -0
- package/dist/relational-core.d.mts +12 -13
- package/dist/relational-core.mjs +4 -3
- package/dist/relational-core__aggregate-descriptor-registry.d.mts +12 -0
- package/dist/relational-core__aggregate-descriptor-registry.d.mts.map +1 -0
- package/dist/relational-core__aggregate-descriptor-registry.mjs +2 -0
- package/dist/relational-core__ast.d.mts +3 -4
- package/dist/relational-core__ast.mjs +3 -2
- package/dist/relational-core__codec-descriptor-registry.d.mts +3 -3
- package/dist/relational-core__contract-free.d.mts +3 -4
- package/dist/relational-core__contract-free.d.mts.map +1 -1
- package/dist/relational-core__contract-free.mjs +1 -1
- package/dist/relational-core__contract-free.mjs.map +1 -1
- package/dist/relational-core__expression.d.mts +1 -1
- package/dist/relational-core__expression.mjs +1 -1
- package/dist/relational-core__middleware.d.mts +2 -2
- package/dist/relational-core__plan.d.mts +3 -3
- package/dist/relational-core__query-lane-context.d.mts +3 -3
- package/dist/relational-core__types.d.mts +2 -2
- package/dist/{runtime-DNewRuec.d.mts → runtime-DXPO2ytG.d.mts} +2 -2
- package/dist/{runtime-DNewRuec.d.mts.map → runtime-DXPO2ytG.d.mts.map} +1 -1
- package/dist/runtime.d.mts +3 -3
- package/dist/runtime.mjs +12 -3
- package/dist/runtime.mjs.map +1 -1
- package/dist/{schema-differ-DpG_gnur-g5_iks8G.d.mts → schema-differ-DpG_gnur-zSwkxqxK.d.mts} +2 -2
- package/dist/{schema-differ-DpG_gnur-g5_iks8G.d.mts.map → schema-differ-DpG_gnur-zSwkxqxK.d.mts.map} +1 -1
- package/dist/{sql-execution-plan-CJmsCP7n-DoEpNn7r.d.mts → sql-execution-plan-Da_d82pz-IHBEmGSa.d.mts} +3 -3
- package/dist/sql-execution-plan-Da_d82pz-IHBEmGSa.d.mts.map +1 -0
- package/dist/{types-DIBA80mc-wf5wLmON.d.mts → types-BwePDa3m-BVrPIi8V.d.mts} +117 -5
- package/dist/types-BwePDa3m-BVrPIi8V.d.mts.map +1 -0
- package/dist/types-Cty2fvYD.d.mts +1 -0
- package/dist/{types-BgkZru_1-H7yfikSQ.mjs → types-D43EhRac-DOJmnq_t.mjs} +4 -21
- package/dist/types-D43EhRac-DOJmnq_t.mjs.map +1 -0
- package/dist/{types-CuDrWc5v-ISVXBmBs.d.mts → types-D_plAPEe-DqK5It_K.d.mts} +30 -4
- package/dist/types-D_plAPEe-DqK5It_K.d.mts.map +1 -0
- package/dist/{types-IqZMLrFC-DtdJNICr.d.mts → types-IqZMLrFC-C1Zu2oo9.d.mts} +5 -5
- package/dist/{types-IqZMLrFC-DtdJNICr.d.mts.map → types-IqZMLrFC-C1Zu2oo9.d.mts.map} +1 -1
- package/dist/{types-Dl20lxky-DC_jdA0T.d.mts → types-dD8JJfeD-BOvMw2Iu.d.mts} +9 -9
- package/dist/{types-Dl20lxky-DC_jdA0T.d.mts.map → types-dD8JJfeD-BOvMw2Iu.d.mts.map} +1 -1
- package/dist/{types-BchwQpmO.d.mts → types-wy2-Y8wQ.d.mts} +2 -2
- package/dist/{types-BchwQpmO.d.mts.map → types-wy2-Y8wQ.d.mts.map} +1 -1
- package/dist/{validators-CxeHhHrf.d.mts → validators-Ds_fvIs_.d.mts} +2 -2
- package/dist/{validators-CxeHhHrf.d.mts.map → validators-Ds_fvIs_.d.mts.map} +1 -1
- package/package.json +24 -18
- package/dist/ast-BstHjAoG.mjs.map +0 -1
- package/dist/ast-DSuzmsWn.d.mts.map +0 -1
- package/dist/codec-types-MOaceoPi-C5eL2sao.d.mts +0 -116
- package/dist/codec-types-MOaceoPi-C5eL2sao.d.mts.map +0 -1
- package/dist/control-adapter-4y1O8Ps3.d.mts +0 -1
- package/dist/db-DhMsmBS--DKENDi3l.d.mts.map +0 -1
- package/dist/ddl-types-rrMsf77U-DGctYf-T.d.mts.map +0 -1
- package/dist/dist-DrScXbhq.mjs.map +0 -1
- package/dist/expression-DIf8F4Mc.d.mts.map +0 -1
- package/dist/index-Bb9U36N4.d.mts.map +0 -1
- package/dist/middleware-ByRsXxxq.d.mts +0 -1
- package/dist/plan-BTD8xFfa-Dd_K-A1R.d.mts.map +0 -1
- package/dist/plan-Cm4jaoNM.d.mts +0 -2
- package/dist/query-lane-context-Bz8XJZ45.d.mts +0 -1
- package/dist/query-lane-context-DtdVMqoz-C2Tj5QHA.d.mts.map +0 -1
- package/dist/sql-execution-plan-CJmsCP7n-DoEpNn7r.d.mts.map +0 -1
- package/dist/types-BgkZru_1-H7yfikSQ.mjs.map +0 -1
- package/dist/types-CuDrWc5v-ISVXBmBs.d.mts.map +0 -1
- package/dist/types-DIBA80mc-wf5wLmON.d.mts.map +0 -1
- package/dist/types-DMxc5KZa.d.mts +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { C as LiteralExpr, D as OrExpr, F as SubqueryExpr, I as TableSource, L as UpdateAst, O as OrderByItem, P as SelectAst, S as ListExpression, T as NullCheckExpr, _ as InsertAst, c as DeleteAst, g as IdentifierRef, j as ProjectionItem, k as ParamRef, l as DerivedTableSource, n as AndExpr, o as ColumnRef, p as ExistsExpr, r as BinaryExpr, t as AggregateExpr, y as JoinAst } from "./types-
|
|
1
|
+
import { C as LiteralExpr, D as OrExpr, F as SubqueryExpr, I as TableSource, L as UpdateAst, O as OrderByItem, P as SelectAst, S as ListExpression, T as NullCheckExpr, _ as InsertAst, c as DeleteAst, g as IdentifierRef, j as ProjectionItem, k as ParamRef, l as DerivedTableSource, n as AndExpr, o as ColumnRef, p as ExistsExpr, r as BinaryExpr, t as AggregateExpr, y as JoinAst } from "./types-D43EhRac-DOJmnq_t.mjs";
|
|
2
2
|
import { t as collectOrderedParamRefs } from "./util-DQQgv2j1-D6INZaRG.mjs";
|
|
3
|
-
import { a as toExpr, n as codecOf, r as createRawSql } from "./expression-
|
|
3
|
+
import { a as toExpr, n as codecOf, r as createRawSql } from "./expression-Dhu3dLiu.mjs";
|
|
4
4
|
import { n as codecRefForStorageColumn } from "./codec-descriptor-registry-BJVJRftS.mjs";
|
|
5
5
|
import { assertAnnotationsApplicable } from "@prisma/orm-framework/components/runtime";
|
|
6
6
|
//#region ../../../2-sql/4-lanes/sql-builder/dist/runtime/index.mjs
|
|
@@ -8,20 +8,33 @@ import { assertAnnotationsApplicable } from "@prisma/orm-framework/components/ru
|
|
|
8
8
|
* Runtime wrapper around a relational-core AST expression node. Carries ScopeField metadata (codecId, nullable) so aggregate-like combinators can propagate the input codec onto their result.
|
|
9
9
|
*
|
|
10
10
|
* `codec` records the column-bound {@link CodecRef} when the field-proxy knows the binding — both the namespaced form (`f.user.email` → `ColumnRef`) and the top-level shortcut (`f.email` → `IdentifierRef`) stamp the ref derived from contract storage. `codecOf(expression)` exposes it for operation implementations forwarding the ref to `toExpr`.
|
|
11
|
+
*
|
|
12
|
+
* `projectionAst` carries the descriptor-lowered rendering of the expression, where a target declares one (e.g. SQLite's `CAST(count(*) AS TEXT)`). Lowering exists to carry the value across the driver boundary, so only the projection site consumes it — predicate and ordering positions (`buildAst()`) keep the plain form, where the rendering would change SQL semantics.
|
|
11
13
|
*/
|
|
12
14
|
var ExpressionImpl = class {
|
|
13
15
|
ast;
|
|
16
|
+
projectionAst;
|
|
14
17
|
returnType;
|
|
15
18
|
codec;
|
|
16
|
-
constructor(ast, returnType, codec) {
|
|
19
|
+
constructor(ast, returnType, codec, projectionAst) {
|
|
17
20
|
this.ast = ast;
|
|
18
21
|
this.returnType = returnType;
|
|
19
22
|
this.codec = codec;
|
|
23
|
+
this.projectionAst = projectionAst;
|
|
20
24
|
}
|
|
21
25
|
buildAst() {
|
|
22
26
|
return this.ast;
|
|
23
27
|
}
|
|
28
|
+
buildProjectionAst() {
|
|
29
|
+
return this.projectionAst ?? this.ast;
|
|
30
|
+
}
|
|
24
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* The AST to project for an expression: the descriptor-lowered form when the expression carries one, the plain form otherwise. `resolveSelectArgs` calls this where a lane expression becomes a `ProjectionItem` — the one place the value crosses the driver boundary.
|
|
34
|
+
*/
|
|
35
|
+
function projectionAstOf(expr) {
|
|
36
|
+
return expr instanceof ExpressionImpl ? expr.buildProjectionAst() : expr.buildAst();
|
|
37
|
+
}
|
|
25
38
|
function createFieldProxy(scope) {
|
|
26
39
|
return new Proxy({}, { get(_target, prop) {
|
|
27
40
|
if (Object.hasOwn(scope.topLevel, prop)) {
|
|
@@ -42,6 +55,85 @@ function createNamespaceProxy(namespaceName, fields) {
|
|
|
42
55
|
}
|
|
43
56
|
} });
|
|
44
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* **Last-resort escape hatch for unsafe type assertions. Not a sanctioned tool to reach for.**
|
|
60
|
+
*
|
|
61
|
+
* Before reaching for `blindCast`, **rewrite the surrounding code so the cast becomes
|
|
62
|
+
* unnecessary**: tighten an input type, add a runtime check that narrows via a type
|
|
63
|
+
* predicate, restructure a generic so the compiler can see the relationship you're
|
|
64
|
+
* asserting, or use {@link castAs} when the value already satisfies the target type.
|
|
65
|
+
* Only when no rewrite is feasible does `blindCast` become the right answer — and at
|
|
66
|
+
* that point, the `Reason` literal you supply must articulate the compromise in
|
|
67
|
+
* language a reviewer can evaluate.
|
|
68
|
+
*
|
|
69
|
+
* The reviewer **will** validate the `Reason`. If it doesn't hold up under scrutiny,
|
|
70
|
+
* that is not a signal to soften the reason; it is a signal to go back and solve the
|
|
71
|
+
* underlying type-system problem properly. An unconvincing justification is rework,
|
|
72
|
+
* not a free pass.
|
|
73
|
+
*
|
|
74
|
+
* `blindCast` is the auditable form of `as Foo` / `as unknown as Foo`: it bypasses
|
|
75
|
+
* the compiler's checks (the input type is `unknown`, the output type is whatever the
|
|
76
|
+
* caller asks for), but it forces the unsafety to be named at the call site instead of
|
|
77
|
+
* smuggled in via a bare `as`. The `Reason` type parameter exists only at compile
|
|
78
|
+
* time — it is not present in the emitted JavaScript — but it is grep-able and
|
|
79
|
+
* visible to future readers.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const stringValue = blindCast<
|
|
84
|
+
* string,
|
|
85
|
+
* "JSON.parse returns `unknown`; this field is documented to be a string in the API contract"
|
|
86
|
+
* >(parsed[key]);
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* @typeParam TargetType - The type the caller is asserting the input has.
|
|
90
|
+
* @typeParam _Reason - A string literal describing why bypassing the type system is necessary here.
|
|
91
|
+
* Only meaningful at compile time. The reviewer evaluates whether it justifies the unsafety.
|
|
92
|
+
*/
|
|
93
|
+
function blindCast(input) {
|
|
94
|
+
return input;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Returns an object with the key/value if value is defined, otherwise an empty object.
|
|
98
|
+
*
|
|
99
|
+
* Use with spread to conditionally include optional properties while satisfying
|
|
100
|
+
* exactOptionalPropertyTypes. This is explicit about which properties are optional
|
|
101
|
+
* and won't inadvertently strip other undefined values.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* // Instead of:
|
|
106
|
+
* const obj = {
|
|
107
|
+
* required: 'value',
|
|
108
|
+
* ...(optional ? { optional } : {}),
|
|
109
|
+
* };
|
|
110
|
+
*
|
|
111
|
+
* // Use:
|
|
112
|
+
* const obj = {
|
|
113
|
+
* required: 'value',
|
|
114
|
+
* ...ifDefined('optional', optional),
|
|
115
|
+
* };
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
function ifDefined(key, value) {
|
|
119
|
+
return value !== void 0 ? blindCast({ [key]: value }) : {};
|
|
120
|
+
}
|
|
121
|
+
function structuredError(code, message, options) {
|
|
122
|
+
const error = options?.cause !== void 0 ? new Error(message, { cause: options.cause }) : new Error(message);
|
|
123
|
+
Object.defineProperty(error, "name", {
|
|
124
|
+
value: "StructuredError",
|
|
125
|
+
configurable: true
|
|
126
|
+
});
|
|
127
|
+
return Object.assign(error, {
|
|
128
|
+
code,
|
|
129
|
+
...ifDefined("why", options?.why),
|
|
130
|
+
...ifDefined("fix", options?.fix),
|
|
131
|
+
...ifDefined("where", options?.where),
|
|
132
|
+
...ifDefined("severity", options?.severity),
|
|
133
|
+
...ifDefined("meta", options?.meta),
|
|
134
|
+
...ifDefined("docsUrl", options?.docsUrl)
|
|
135
|
+
});
|
|
136
|
+
}
|
|
45
137
|
const BOOL_FIELD = {
|
|
46
138
|
codecId: "pg/bool@1",
|
|
47
139
|
nullable: false
|
|
@@ -98,11 +190,50 @@ function inOrNotIn(expr, valuesOrSubquery, op) {
|
|
|
98
190
|
}
|
|
99
191
|
return boolExpr(binaryFn(left, SubqueryExpr.of(valuesOrSubquery.buildAst())));
|
|
100
192
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
193
|
+
/**
|
|
194
|
+
* Build an aggregate through the target's own answer for it.
|
|
195
|
+
*
|
|
196
|
+
* What an aggregate returns is neither the input's codec nor a fixed id: a
|
|
197
|
+
* target widens `sum` over small integers, takes `avg` somewhere else again,
|
|
198
|
+
* and may want the result rendered a particular way. All three come from the
|
|
199
|
+
* registry, and the result carries the codec it declared so decoding resolves
|
|
200
|
+
* through the ordinary path.
|
|
201
|
+
*
|
|
202
|
+
* The declared rendering (`lower`) exists to carry the value across the driver
|
|
203
|
+
* boundary — a projection concern. It is carried beside the plain form so only
|
|
204
|
+
* the projection site consumes it; HAVING and ORDER BY compare the value inside
|
|
205
|
+
* the database, where the rendering would change SQL semantics (SQLite's
|
|
206
|
+
* `CAST(count(*) AS TEXT)` compares and sorts lexicographically).
|
|
207
|
+
*
|
|
208
|
+
* A pair the target declares no overload for is rejected outright. The typed
|
|
209
|
+
* surface already makes it inexpressible; this backs that up for dynamic
|
|
210
|
+
* invocation, instead of executing SQL whose result no declaration types or
|
|
211
|
+
* decodes — SQLite's `sum` over text, which reads whatever leading numbers the
|
|
212
|
+
* rows happened to hold, is the shape of value that path would hand back.
|
|
213
|
+
*/
|
|
214
|
+
function aggregate(aggregates, fn, expr) {
|
|
215
|
+
const field = expr?.returnType;
|
|
216
|
+
const inputCodec = field === void 0 ? void 0 : field.codec ?? { codecId: field.codecId };
|
|
217
|
+
const resolved = aggregates.resolve(fn, inputCodec);
|
|
218
|
+
if (resolved === void 0) throw structuredError("ORM.AGGREGATE_UNSUPPORTED", inputCodec === void 0 ? `The composed target declares no '${fn}' aggregate for a call without an input.` : `The composed target declares no '${fn}' aggregate over codec '${inputCodec.codecId}'.`, {
|
|
219
|
+
why: "An aggregate result decodes through the codec its target declares; an undeclared pair has no declared result to type or decode.",
|
|
220
|
+
fix: `Aggregate an input the target declares '${fn}' for, or contribute an aggregate descriptor for this pair.`,
|
|
221
|
+
meta: {
|
|
222
|
+
operation: fn,
|
|
223
|
+
...ifDefined("inputCodecId", inputCodec?.codecId)
|
|
224
|
+
}
|
|
105
225
|
});
|
|
226
|
+
const inputAst = expr?.buildAst();
|
|
227
|
+
const ast = new AggregateExpr(fn, inputAst);
|
|
228
|
+
const projectionAst = resolved.lower?.({
|
|
229
|
+
expr: inputAst,
|
|
230
|
+
inputCodec
|
|
231
|
+
});
|
|
232
|
+
return new ExpressionImpl(ast, {
|
|
233
|
+
codecId: resolved.output.codecId,
|
|
234
|
+
nullable: resolved.nullable,
|
|
235
|
+
codec: resolved.output
|
|
236
|
+
}, void 0, projectionAst);
|
|
106
237
|
}
|
|
107
238
|
function createBuiltinFunctions(rawCodecInferer) {
|
|
108
239
|
return {
|
|
@@ -121,19 +252,20 @@ function createBuiltinFunctions(rawCodecInferer) {
|
|
|
121
252
|
raw: createRawSql(rawCodecInferer)
|
|
122
253
|
};
|
|
123
254
|
}
|
|
124
|
-
|
|
255
|
+
/**
|
|
256
|
+
* The aggregate implementations, erased.
|
|
257
|
+
*
|
|
258
|
+
* What each returns is the contract's answer — a function of the target's map
|
|
259
|
+
* and the input's codec — which no runtime value can state. The typed surface
|
|
260
|
+
* is `AggregateFunctions<QC>`, applied where these are handed out.
|
|
261
|
+
*/
|
|
262
|
+
function createAggregateOnlyFunctions(aggregates) {
|
|
125
263
|
return {
|
|
126
|
-
count: (expr) =>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
});
|
|
132
|
-
},
|
|
133
|
-
sum: (expr) => numericAgg("sum", expr),
|
|
134
|
-
avg: (expr) => numericAgg("avg", expr),
|
|
135
|
-
min: (expr) => numericAgg("min", expr),
|
|
136
|
-
max: (expr) => numericAgg("max", expr)
|
|
264
|
+
count: (expr) => aggregate(aggregates, "count", expr),
|
|
265
|
+
sum: (expr) => aggregate(aggregates, "sum", expr),
|
|
266
|
+
avg: (expr) => aggregate(aggregates, "avg", expr),
|
|
267
|
+
min: (expr) => aggregate(aggregates, "min", expr),
|
|
268
|
+
max: (expr) => aggregate(aggregates, "max", expr)
|
|
137
269
|
};
|
|
138
270
|
}
|
|
139
271
|
function createFunctions(operations, rawCodecInferer) {
|
|
@@ -144,9 +276,9 @@ function createFunctions(operations, rawCodecInferer) {
|
|
|
144
276
|
if (op) return op.impl;
|
|
145
277
|
} });
|
|
146
278
|
}
|
|
147
|
-
function createAggregateFunctions(operations, rawCodecInferer) {
|
|
279
|
+
function createAggregateFunctions(operations, rawCodecInferer, aggregateRegistry) {
|
|
148
280
|
const baseFns = createFunctions(operations, rawCodecInferer);
|
|
149
|
-
const aggregates = createAggregateOnlyFunctions();
|
|
281
|
+
const aggregates = createAggregateOnlyFunctions(aggregateRegistry);
|
|
150
282
|
return new Proxy({}, { get(_target, prop) {
|
|
151
283
|
const agg = aggregates[prop];
|
|
152
284
|
if (agg) return agg;
|
|
@@ -160,85 +292,6 @@ function resolveTableInNamespace(storage, namespaceId, tableName) {
|
|
|
160
292
|
if (tables === void 0 || !Object.hasOwn(tables, tableName)) return void 0;
|
|
161
293
|
return tables[tableName];
|
|
162
294
|
}
|
|
163
|
-
/**
|
|
164
|
-
* **Last-resort escape hatch for unsafe type assertions. Not a sanctioned tool to reach for.**
|
|
165
|
-
*
|
|
166
|
-
* Before reaching for `blindCast`, **rewrite the surrounding code so the cast becomes
|
|
167
|
-
* unnecessary**: tighten an input type, add a runtime check that narrows via a type
|
|
168
|
-
* predicate, restructure a generic so the compiler can see the relationship you're
|
|
169
|
-
* asserting, or use {@link castAs} when the value already satisfies the target type.
|
|
170
|
-
* Only when no rewrite is feasible does `blindCast` become the right answer — and at
|
|
171
|
-
* that point, the `Reason` literal you supply must articulate the compromise in
|
|
172
|
-
* language a reviewer can evaluate.
|
|
173
|
-
*
|
|
174
|
-
* The reviewer **will** validate the `Reason`. If it doesn't hold up under scrutiny,
|
|
175
|
-
* that is not a signal to soften the reason; it is a signal to go back and solve the
|
|
176
|
-
* underlying type-system problem properly. An unconvincing justification is rework,
|
|
177
|
-
* not a free pass.
|
|
178
|
-
*
|
|
179
|
-
* `blindCast` is the auditable form of `as Foo` / `as unknown as Foo`: it bypasses
|
|
180
|
-
* the compiler's checks (the input type is `unknown`, the output type is whatever the
|
|
181
|
-
* caller asks for), but it forces the unsafety to be named at the call site instead of
|
|
182
|
-
* smuggled in via a bare `as`. The `Reason` type parameter exists only at compile
|
|
183
|
-
* time — it is not present in the emitted JavaScript — but it is grep-able and
|
|
184
|
-
* visible to future readers.
|
|
185
|
-
*
|
|
186
|
-
* @example
|
|
187
|
-
* ```typescript
|
|
188
|
-
* const stringValue = blindCast<
|
|
189
|
-
* string,
|
|
190
|
-
* "JSON.parse returns `unknown`; this field is documented to be a string in the API contract"
|
|
191
|
-
* >(parsed[key]);
|
|
192
|
-
* ```
|
|
193
|
-
*
|
|
194
|
-
* @typeParam TargetType - The type the caller is asserting the input has.
|
|
195
|
-
* @typeParam _Reason - A string literal describing why bypassing the type system is necessary here.
|
|
196
|
-
* Only meaningful at compile time. The reviewer evaluates whether it justifies the unsafety.
|
|
197
|
-
*/
|
|
198
|
-
function blindCast(input) {
|
|
199
|
-
return input;
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Returns an object with the key/value if value is defined, otherwise an empty object.
|
|
203
|
-
*
|
|
204
|
-
* Use with spread to conditionally include optional properties while satisfying
|
|
205
|
-
* exactOptionalPropertyTypes. This is explicit about which properties are optional
|
|
206
|
-
* and won't inadvertently strip other undefined values.
|
|
207
|
-
*
|
|
208
|
-
* @example
|
|
209
|
-
* ```typescript
|
|
210
|
-
* // Instead of:
|
|
211
|
-
* const obj = {
|
|
212
|
-
* required: 'value',
|
|
213
|
-
* ...(optional ? { optional } : {}),
|
|
214
|
-
* };
|
|
215
|
-
*
|
|
216
|
-
* // Use:
|
|
217
|
-
* const obj = {
|
|
218
|
-
* required: 'value',
|
|
219
|
-
* ...ifDefined('optional', optional),
|
|
220
|
-
* };
|
|
221
|
-
* ```
|
|
222
|
-
*/
|
|
223
|
-
function ifDefined(key, value) {
|
|
224
|
-
return value !== void 0 ? blindCast({ [key]: value }) : {};
|
|
225
|
-
}
|
|
226
|
-
function structuredError(code, message, options) {
|
|
227
|
-
const error = options?.cause !== void 0 ? new Error(message, { cause: options.cause }) : new Error(message);
|
|
228
|
-
Object.defineProperty(error, "name", {
|
|
229
|
-
value: "StructuredError",
|
|
230
|
-
configurable: true
|
|
231
|
-
});
|
|
232
|
-
return Object.assign(error, {
|
|
233
|
-
code,
|
|
234
|
-
...ifDefined("why", options?.why),
|
|
235
|
-
...ifDefined("fix", options?.fix),
|
|
236
|
-
...ifDefined("where", options?.where),
|
|
237
|
-
...ifDefined("severity", options?.severity),
|
|
238
|
-
...ifDefined("meta", options?.meta),
|
|
239
|
-
...ifDefined("docsUrl", options?.docsUrl)
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
295
|
var BuilderBase = class {
|
|
243
296
|
ctx;
|
|
244
297
|
constructor(ctx) {
|
|
@@ -407,10 +460,10 @@ function resolveSelectArgs(args, scope, ctx) {
|
|
|
407
460
|
if (typeof args[0] === "string" && typeof args[1] === "function") {
|
|
408
461
|
const alias = args[0];
|
|
409
462
|
const exprFn = args[1];
|
|
410
|
-
const fns = createAggregateFunctions(ctx.queryOperationTypes, ctx.rawCodecInferer);
|
|
463
|
+
const fns = createAggregateFunctions(ctx.queryOperationTypes, ctx.rawCodecInferer, ctx.aggregates);
|
|
411
464
|
const result = exprFn(createFieldProxy(scope), fns);
|
|
412
465
|
const field = result.returnType;
|
|
413
|
-
projections.push(ProjectionItem.of(alias, result
|
|
466
|
+
projections.push(ProjectionItem.of(alias, projectionAstOf(result), field.codec));
|
|
414
467
|
newRowFields[alias] = field;
|
|
415
468
|
return {
|
|
416
469
|
projections,
|
|
@@ -419,11 +472,11 @@ function resolveSelectArgs(args, scope, ctx) {
|
|
|
419
472
|
}
|
|
420
473
|
if (typeof args[0] === "function") {
|
|
421
474
|
const callbackFn = args[0];
|
|
422
|
-
const fns = createAggregateFunctions(ctx.queryOperationTypes, ctx.rawCodecInferer);
|
|
475
|
+
const fns = createAggregateFunctions(ctx.queryOperationTypes, ctx.rawCodecInferer, ctx.aggregates);
|
|
423
476
|
const record = callbackFn(createFieldProxy(scope), fns);
|
|
424
477
|
for (const [key, expr] of Object.entries(record)) {
|
|
425
478
|
const field = expr.returnType;
|
|
426
|
-
projections.push(ProjectionItem.of(key, expr
|
|
479
|
+
projections.push(ProjectionItem.of(key, projectionAstOf(expr), field.codec));
|
|
427
480
|
newRowFields[key] = field;
|
|
428
481
|
}
|
|
429
482
|
return {
|
|
@@ -442,7 +495,7 @@ function resolveOrderBy(arg, options, scope, rowFields, ctx, useAggregateFns) {
|
|
|
442
495
|
}
|
|
443
496
|
if (typeof arg === "function") {
|
|
444
497
|
const combined = orderByScopeOf(scope, rowFields);
|
|
445
|
-
const fns = useAggregateFns ? createAggregateFunctions(ctx.queryOperationTypes, ctx.rawCodecInferer) : createFunctions(ctx.queryOperationTypes, ctx.rawCodecInferer);
|
|
498
|
+
const fns = useAggregateFns ? createAggregateFunctions(ctx.queryOperationTypes, ctx.rawCodecInferer, ctx.aggregates) : createFunctions(ctx.queryOperationTypes, ctx.rawCodecInferer);
|
|
446
499
|
const result = arg(createFieldProxy(combined), fns);
|
|
447
500
|
return dir === "asc" ? OrderByItem.asc(result.buildAst()) : OrderByItem.desc(result.buildAst());
|
|
448
501
|
}
|
|
@@ -574,7 +627,7 @@ var GroupedQueryImpl = class GroupedQueryImpl extends QueryBase {
|
|
|
574
627
|
}
|
|
575
628
|
having(expr) {
|
|
576
629
|
const combined = orderByScopeOf(this.state.scope, this.state.rowFields);
|
|
577
|
-
const fns = createAggregateFunctions(this.ctx.queryOperationTypes, this.ctx.rawCodecInferer);
|
|
630
|
+
const fns = createAggregateFunctions(this.ctx.queryOperationTypes, this.ctx.rawCodecInferer, this.ctx.aggregates);
|
|
578
631
|
const result = expr(createFieldProxy(combined), fns);
|
|
579
632
|
return new GroupedQueryImpl(cloneState(this.state, { having: result.buildAst() }), this.ctx);
|
|
580
633
|
}
|
|
@@ -935,7 +988,8 @@ function sql(options) {
|
|
|
935
988
|
storageHash: context.contract.storage.storageHash ?? "unknown",
|
|
936
989
|
storage: context.contract.storage,
|
|
937
990
|
applyMutationDefaults: (options) => context.applyMutationDefaults(options),
|
|
938
|
-
rawCodecInferer
|
|
991
|
+
rawCodecInferer,
|
|
992
|
+
aggregates: context.aggregateDescriptors
|
|
939
993
|
};
|
|
940
994
|
const { storage } = context.contract;
|
|
941
995
|
return new Proxy({}, { get(_target, prop) {
|