@effect-app/infra 4.0.0-beta.24 → 4.0.0-beta.241
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/CHANGELOG.md +1818 -0
- package/_check.sh +1 -1
- package/dist/CUPS.d.ts +12 -7
- package/dist/CUPS.d.ts.map +1 -1
- package/dist/CUPS.js +16 -12
- package/dist/Emailer/Sendgrid.d.ts +15 -15
- package/dist/Emailer/Sendgrid.d.ts.map +1 -1
- package/dist/Emailer/Sendgrid.js +21 -17
- package/dist/Emailer/fake.d.ts +1 -1
- package/dist/Emailer/fake.js +3 -3
- package/dist/Emailer/service.d.ts +13 -4
- package/dist/Emailer/service.d.ts.map +1 -1
- package/dist/Emailer/service.js +4 -3
- package/dist/Emailer.d.ts +1 -1
- package/dist/MainFiberSet.d.ts +12 -9
- package/dist/MainFiberSet.d.ts.map +1 -1
- package/dist/MainFiberSet.js +10 -6
- package/dist/Model/Repository/Registry.d.ts +21 -0
- package/dist/Model/Repository/Registry.d.ts.map +1 -0
- package/dist/Model/Repository/Registry.js +18 -0
- package/dist/Model/Repository/ext.d.ts +35 -16
- package/dist/Model/Repository/ext.d.ts.map +1 -1
- package/dist/Model/Repository/ext.js +60 -3
- package/dist/Model/Repository/internal/internal.d.ts +9 -6
- package/dist/Model/Repository/internal/internal.d.ts.map +1 -1
- package/dist/Model/Repository/internal/internal.js +141 -59
- package/dist/Model/Repository/legacy.d.ts +4 -2
- package/dist/Model/Repository/legacy.d.ts.map +1 -1
- package/dist/Model/Repository/makeRepo.d.ts +10 -6
- package/dist/Model/Repository/makeRepo.d.ts.map +1 -1
- package/dist/Model/Repository/makeRepo.js +5 -2
- package/dist/Model/Repository/service.d.ts +32 -24
- package/dist/Model/Repository/service.d.ts.map +1 -1
- package/dist/Model/Repository/validation.d.ts +47 -18
- package/dist/Model/Repository/validation.d.ts.map +1 -1
- package/dist/Model/Repository/validation.js +6 -6
- package/dist/Model/Repository.d.ts +2 -1
- package/dist/Model/Repository.d.ts.map +1 -1
- package/dist/Model/Repository.js +2 -1
- package/dist/Model/dsl.d.ts +6 -5
- package/dist/Model/dsl.d.ts.map +1 -1
- package/dist/Model/dsl.js +2 -3
- package/dist/Model/filter/filterApi.d.ts +5 -5
- package/dist/Model/filter/filterApi.d.ts.map +1 -1
- package/dist/Model/filter/types/errors.d.ts +1 -1
- package/dist/Model/filter/types/fields.d.ts +1 -1
- package/dist/Model/filter/types/path/common.d.ts +1 -1
- package/dist/Model/filter/types/path/eager.d.ts +1 -1
- package/dist/Model/filter/types/path/eager.d.ts.map +1 -1
- package/dist/Model/filter/types/path/eager.js +1 -1
- package/dist/Model/filter/types/path/index.d.ts +1 -1
- package/dist/Model/filter/types/utils.d.ts +1 -1
- package/dist/Model/filter/types/validator.d.ts +1 -1
- package/dist/Model/filter/types.d.ts +5 -5
- package/dist/Model/query/dsl.d.ts +216 -18
- package/dist/Model/query/dsl.d.ts.map +1 -1
- package/dist/Model/query/dsl.js +240 -5
- package/dist/Model/query/new-kid-interpreter.d.ts +116 -8
- package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -1
- package/dist/Model/query/new-kid-interpreter.js +177 -6
- package/dist/Model/query.d.ts +1 -1
- package/dist/Model.d.ts +2 -1
- package/dist/Model.d.ts.map +1 -1
- package/dist/Model.js +2 -1
- package/dist/QueueMaker/SQLQueue.d.ts +7 -8
- package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
- package/dist/QueueMaker/SQLQueue.js +135 -117
- package/dist/QueueMaker/errors.d.ts +5 -3
- package/dist/QueueMaker/errors.d.ts.map +1 -1
- package/dist/QueueMaker/errors.js +4 -2
- package/dist/QueueMaker/memQueue.d.ts +9 -5
- package/dist/QueueMaker/memQueue.d.ts.map +1 -1
- package/dist/QueueMaker/memQueue.js +81 -65
- package/dist/QueueMaker/sbqueue.d.ts +8 -4
- package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
- package/dist/QueueMaker/sbqueue.js +57 -55
- package/dist/QueueMaker/service.d.ts +4 -2
- package/dist/QueueMaker/service.d.ts.map +1 -1
- package/dist/QueueMaker/service.js +1 -1
- package/dist/RequestContext.d.ts +75 -35
- package/dist/RequestContext.d.ts.map +1 -1
- package/dist/RequestContext.js +14 -14
- package/dist/RequestFiberSet.d.ts +10 -7
- package/dist/RequestFiberSet.d.ts.map +1 -1
- package/dist/RequestFiberSet.js +12 -7
- package/dist/Store/ContextMapContainer.d.ts +22 -3
- package/dist/Store/ContextMapContainer.d.ts.map +1 -1
- package/dist/Store/ContextMapContainer.js +18 -4
- package/dist/Store/Cosmos/query.d.ts +13 -2
- package/dist/Store/Cosmos/query.d.ts.map +1 -1
- package/dist/Store/Cosmos/query.js +179 -41
- package/dist/Store/Cosmos.d.ts +2 -2
- package/dist/Store/Cosmos.d.ts.map +1 -1
- package/dist/Store/Cosmos.js +343 -244
- package/dist/Store/Disk.d.ts +3 -3
- package/dist/Store/Disk.d.ts.map +1 -1
- package/dist/Store/Disk.js +76 -36
- package/dist/Store/Memory.d.ts +7 -4
- package/dist/Store/Memory.d.ts.map +1 -1
- package/dist/Store/Memory.js +327 -62
- package/dist/Store/SQL/Pg.d.ts +4 -0
- package/dist/Store/SQL/Pg.d.ts.map +1 -0
- package/dist/Store/SQL/Pg.js +233 -0
- package/dist/Store/SQL/query.d.ts +49 -0
- package/dist/Store/SQL/query.d.ts.map +1 -0
- package/dist/Store/SQL/query.js +527 -0
- package/dist/Store/SQL.d.ts +21 -0
- package/dist/Store/SQL.d.ts.map +1 -0
- package/dist/Store/SQL.js +450 -0
- package/dist/Store/codeFilter.d.ts +2 -2
- package/dist/Store/codeFilter.d.ts.map +1 -1
- package/dist/Store/codeFilter.js +6 -3
- package/dist/Store/index.d.ts +6 -3
- package/dist/Store/index.d.ts.map +1 -1
- package/dist/Store/index.js +18 -4
- package/dist/Store/service.d.ts +39 -9
- package/dist/Store/service.d.ts.map +1 -1
- package/dist/Store/service.js +31 -7
- package/dist/Store/utils.d.ts +3 -2
- package/dist/Store/utils.d.ts.map +1 -1
- package/dist/Store/utils.js +5 -5
- package/dist/Store.d.ts +1 -1
- package/dist/adapters/SQL/Model.d.ts +32 -43
- package/dist/adapters/SQL/Model.d.ts.map +1 -1
- package/dist/adapters/SQL/Model.js +30 -39
- package/dist/adapters/SQL.d.ts +1 -1
- package/dist/adapters/ServiceBus.d.ts +14 -11
- package/dist/adapters/ServiceBus.d.ts.map +1 -1
- package/dist/adapters/ServiceBus.js +30 -21
- package/dist/adapters/cosmos-client.d.ts +5 -3
- package/dist/adapters/cosmos-client.d.ts.map +1 -1
- package/dist/adapters/cosmos-client.js +6 -4
- package/dist/adapters/index.d.ts +8 -2
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +8 -2
- package/dist/adapters/logger.d.ts +1 -1
- package/dist/adapters/logger.d.ts.map +1 -1
- package/dist/adapters/memQueue.d.ts +5 -3
- package/dist/adapters/memQueue.d.ts.map +1 -1
- package/dist/adapters/memQueue.js +6 -5
- package/dist/adapters/mongo-client.d.ts +4 -3
- package/dist/adapters/mongo-client.d.ts.map +1 -1
- package/dist/adapters/mongo-client.js +5 -3
- package/dist/adapters/redis-client.d.ts +6 -3
- package/dist/adapters/redis-client.d.ts.map +1 -1
- package/dist/adapters/redis-client.js +7 -3
- package/dist/api/ContextProvider.d.ts +12 -9
- package/dist/api/ContextProvider.d.ts.map +1 -1
- package/dist/api/ContextProvider.js +9 -7
- package/dist/api/codec.d.ts +1 -1
- package/dist/api/internal/RequestContextMiddleware.d.ts +3 -3
- package/dist/api/internal/RequestContextMiddleware.d.ts.map +1 -1
- package/dist/api/internal/RequestContextMiddleware.js +18 -7
- package/dist/api/internal/auth.d.ts +45 -7
- package/dist/api/internal/auth.d.ts.map +1 -1
- package/dist/api/internal/auth.js +162 -29
- package/dist/api/internal/events.d.ts +6 -4
- package/dist/api/internal/events.d.ts.map +1 -1
- package/dist/api/internal/events.js +18 -11
- package/dist/api/internal/health.d.ts +1 -1
- package/dist/api/layerUtils.d.ts +15 -7
- package/dist/api/layerUtils.d.ts.map +1 -1
- package/dist/api/layerUtils.js +7 -6
- package/dist/api/middlewares.d.ts +1 -1
- package/dist/api/reportError.d.ts +2 -2
- package/dist/api/reportError.d.ts.map +1 -1
- package/dist/api/reportError.js +3 -2
- package/dist/api/routing/middleware/RouterMiddleware.d.ts +5 -4
- package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.d.ts +42 -3
- package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.js +53 -17
- package/dist/api/routing/middleware.d.ts +3 -4
- package/dist/api/routing/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware.js +1 -2
- package/dist/api/routing/schema/jwt.d.ts +1 -1
- package/dist/api/routing/schema/jwt.d.ts.map +1 -1
- package/dist/api/routing/schema/jwt.js +3 -2
- package/dist/api/routing/tsort.d.ts +1 -1
- package/dist/api/routing/tsort.d.ts.map +1 -1
- package/dist/api/routing/utils.d.ts +4 -4
- package/dist/api/routing/utils.d.ts.map +1 -1
- package/dist/api/routing/utils.js +3 -2
- package/dist/api/routing.d.ts +84 -38
- package/dist/api/routing.d.ts.map +1 -1
- package/dist/api/routing.js +115 -45
- package/dist/api/setupRequest.d.ts +13 -6
- package/dist/api/setupRequest.d.ts.map +1 -1
- package/dist/api/setupRequest.js +37 -11
- package/dist/api/util.d.ts +1 -1
- package/dist/arbs.d.ts +2 -2
- package/dist/arbs.d.ts.map +1 -1
- package/dist/arbs.js +5 -3
- package/dist/errorReporter.d.ts +7 -5
- package/dist/errorReporter.d.ts.map +1 -1
- package/dist/errorReporter.js +22 -26
- package/dist/errors.d.ts +1 -1
- package/dist/fileUtil.d.ts +2 -2
- package/dist/fileUtil.d.ts.map +1 -1
- package/dist/fileUtil.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/logger/jsonLogger.d.ts +2 -2
- package/dist/logger/jsonLogger.d.ts.map +1 -1
- package/dist/logger/jsonLogger.js +4 -2
- package/dist/logger/logFmtLogger.d.ts +2 -2
- package/dist/logger/logFmtLogger.d.ts.map +1 -1
- package/dist/logger/logFmtLogger.js +2 -2
- package/dist/logger/shared.d.ts +2 -2
- package/dist/logger/shared.d.ts.map +1 -1
- package/dist/logger/shared.js +3 -3
- package/dist/logger.d.ts +2 -2
- package/dist/logger.d.ts.map +1 -1
- package/dist/otel.d.ts +75 -0
- package/dist/otel.d.ts.map +1 -0
- package/dist/otel.js +65 -0
- package/dist/rateLimit.d.ts +12 -4
- package/dist/rateLimit.d.ts.map +1 -1
- package/dist/rateLimit.js +7 -12
- package/dist/test.d.ts +3 -3
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +2 -2
- package/dist/vitest.d.ts +1 -1
- package/examples/query.ts +46 -38
- package/package.json +46 -37
- package/src/CUPS.ts +15 -11
- package/src/Emailer/Sendgrid.ts +65 -57
- package/src/Emailer/fake.ts +2 -2
- package/src/Emailer/service.ts +13 -3
- package/src/MainFiberSet.ts +12 -10
- package/src/Model/Repository/Registry.ts +34 -0
- package/src/Model/Repository/ext.ts +103 -11
- package/src/Model/Repository/internal/internal.ts +266 -151
- package/src/Model/Repository/legacy.ts +3 -1
- package/src/Model/Repository/makeRepo.ts +15 -10
- package/src/Model/Repository/service.ts +35 -23
- package/src/Model/Repository/validation.ts +5 -5
- package/src/Model/Repository.ts +1 -0
- package/src/Model/dsl.ts +5 -4
- package/src/Model/filter/types/path/eager.ts +1 -2
- package/src/Model/filter/types.ts +4 -4
- package/src/Model/query/dsl.ts +456 -20
- package/src/Model/query/new-kid-interpreter.ts +281 -7
- package/src/Model.ts +1 -0
- package/src/QueueMaker/SQLQueue.ts +150 -153
- package/src/QueueMaker/errors.ts +3 -1
- package/src/QueueMaker/memQueue.ts +111 -105
- package/src/QueueMaker/sbqueue.ts +76 -88
- package/src/QueueMaker/service.ts +3 -1
- package/src/RequestContext.ts +15 -16
- package/src/RequestFiberSet.ts +12 -7
- package/src/Store/ContextMapContainer.ts +46 -3
- package/src/Store/Cosmos/query.ts +214 -50
- package/src/Store/Cosmos.ts +491 -350
- package/src/Store/Disk.ts +106 -66
- package/src/Store/Memory.ts +365 -91
- package/src/Store/SQL/Pg.ts +364 -0
- package/src/Store/SQL/query.ts +603 -0
- package/src/Store/SQL.ts +736 -0
- package/src/Store/codeFilter.ts +5 -2
- package/src/Store/index.ts +20 -3
- package/src/Store/service.ts +60 -11
- package/src/Store/utils.ts +25 -23
- package/src/adapters/SQL/Model.ts +42 -41
- package/src/adapters/ServiceBus.ts +131 -121
- package/src/adapters/cosmos-client.ts +5 -3
- package/src/adapters/index.ts +7 -0
- package/src/adapters/memQueue.ts +5 -4
- package/src/adapters/mongo-client.ts +4 -2
- package/src/adapters/redis-client.ts +6 -2
- package/src/api/ContextProvider.ts +19 -16
- package/src/api/internal/RequestContextMiddleware.ts +24 -6
- package/src/api/internal/auth.ts +248 -44
- package/src/api/internal/events.ts +21 -12
- package/src/api/layerUtils.ts +13 -9
- package/src/api/reportError.ts +2 -1
- package/src/api/routing/middleware/RouterMiddleware.ts +5 -4
- package/src/api/routing/middleware/middleware.ts +60 -15
- package/src/api/routing/middleware.ts +2 -4
- package/src/api/routing/schema/jwt.ts +2 -1
- package/src/api/routing/utils.ts +2 -1
- package/src/api/routing.ts +309 -139
- package/src/api/setupRequest.ts +63 -12
- package/src/arbs.ts +5 -3
- package/src/errorReporter.ts +65 -75
- package/src/fileUtil.ts +1 -1
- package/src/logger/jsonLogger.ts +3 -1
- package/src/logger/logFmtLogger.ts +1 -1
- package/src/logger/shared.ts +3 -2
- package/src/otel.ts +152 -0
- package/src/rateLimit.ts +34 -23
- package/src/test.ts +2 -2
- package/test/auth.test.ts +101 -0
- package/test/contextProvider.test.ts +14 -11
- package/test/controller.test.ts +25 -29
- package/test/cosmos-query.test.ts +159 -0
- package/test/dist/auth.test.d.ts.map +1 -0
- package/test/dist/contextProvider.test.d.ts.map +1 -1
- package/test/dist/controller.test.d.ts.map +1 -1
- package/test/dist/cosmos-query.test.d.ts.map +1 -0
- package/test/dist/date-query.test.d.ts.map +1 -0
- package/test/dist/fixtures.d.ts +30 -12
- package/test/dist/fixtures.d.ts.map +1 -1
- package/test/dist/fixtures.js +17 -10
- package/test/dist/query.test.d.ts.map +1 -1
- package/test/dist/rawQuery.test.d.ts.map +1 -1
- package/test/dist/repository-ext.test.d.ts.map +1 -0
- package/test/dist/requires.test.d.ts.map +1 -1
- package/test/dist/router-generator.test.d.ts.map +1 -0
- package/test/dist/routing-interruptibility.test.d.ts.map +1 -0
- package/test/dist/rpc-context-map-streaming.test.d.ts.map +1 -0
- package/test/dist/rpc-e2e-invalidation.test.d.ts.map +1 -0
- package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
- package/test/dist/rpc-stream-fullstack.test.d.ts.map +1 -0
- package/test/dist/sql-store.test.d.ts.map +1 -0
- package/test/fixtures.ts +16 -9
- package/test/layerUtils.test.ts +1 -1
- package/test/query.test.ts +901 -38
- package/test/rawQuery.test.ts +338 -20
- package/test/repository-ext.test.ts +62 -0
- package/test/requires.test.ts +10 -5
- package/test/router-generator.test.ts +187 -0
- package/test/routing-interruptibility.test.ts +66 -0
- package/test/rpc-context-map-streaming.test.ts +262 -0
- package/test/rpc-e2e-invalidation.test.ts +256 -0
- package/test/rpc-multi-middleware.test.ts +84 -9
- package/test/rpc-stream-fullstack.test.ts +304 -0
- package/test/sql-store.test.ts +1711 -0
- package/test/validateSample.test.ts +17 -12
- package/tsconfig.examples.json +1 -1
- package/tsconfig.json +2 -1
- package/tsconfig.json.bak +2 -2
- package/tsconfig.src.json +35 -35
- package/tsconfig.test.json +2 -2
- package/dist/Operations.d.ts +0 -55
- package/dist/Operations.d.ts.map +0 -1
- package/dist/Operations.js +0 -102
- package/dist/OperationsRepo.d.ts +0 -41
- package/dist/OperationsRepo.d.ts.map +0 -1
- package/dist/OperationsRepo.js +0 -14
- package/eslint.config.mjs +0 -24
- package/src/Operations.ts +0 -235
- package/src/OperationsRepo.ts +0 -16
|
@@ -1,13 +1,109 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
3
|
-
import
|
|
3
|
+
import * as Array from "effect-app/Array"
|
|
4
4
|
import { toNonEmptyArray } from "effect-app/Array"
|
|
5
|
+
import * as Option from "effect-app/Option"
|
|
6
|
+
import * as S from "effect-app/Schema"
|
|
5
7
|
import { dropUndefinedT } from "effect-app/utils"
|
|
8
|
+
import { identity, pipe } from "effect/Function"
|
|
9
|
+
import * as Match from "effect/Match"
|
|
10
|
+
import * as SchemaAST from "effect/SchemaAST"
|
|
6
11
|
import type { FilterResult } from "../filter/filterApi.js"
|
|
7
12
|
import type { FieldValues } from "../filter/types.js"
|
|
8
13
|
import type { FieldPath } from "../filter/types/path/eager.js"
|
|
9
14
|
import { make, type Q, type QAll } from "../query/dsl.js"
|
|
10
15
|
|
|
16
|
+
export type AggregateIrExpression =
|
|
17
|
+
| { readonly _tag: "agg-count" }
|
|
18
|
+
| { readonly _tag: "agg-count-when"; readonly filter: readonly FilterResult[] }
|
|
19
|
+
| { readonly _tag: "agg-sum"; readonly field: string }
|
|
20
|
+
| { readonly _tag: "agg-min"; readonly field: string }
|
|
21
|
+
| { readonly _tag: "agg-max"; readonly field: string }
|
|
22
|
+
|
|
23
|
+
export type AggregateIrItem =
|
|
24
|
+
| AggregateIrExpression
|
|
25
|
+
| { readonly _tag: "agg-field"; readonly path: string }
|
|
26
|
+
|
|
27
|
+
export type ComputedProjectionMathIrExpression =
|
|
28
|
+
| {
|
|
29
|
+
readonly _tag: "field"
|
|
30
|
+
readonly field: string
|
|
31
|
+
}
|
|
32
|
+
| {
|
|
33
|
+
readonly _tag: "mul"
|
|
34
|
+
readonly left: ComputedProjectionMathIrExpression
|
|
35
|
+
readonly right: ComputedProjectionMathIrExpression
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type ComputedProjectionIrExpression =
|
|
39
|
+
| {
|
|
40
|
+
readonly _tag: "relation-count"
|
|
41
|
+
readonly path: string
|
|
42
|
+
readonly filter: readonly FilterResult[]
|
|
43
|
+
}
|
|
44
|
+
| {
|
|
45
|
+
readonly _tag: "relation-any"
|
|
46
|
+
readonly path: string
|
|
47
|
+
readonly filter: readonly FilterResult[]
|
|
48
|
+
}
|
|
49
|
+
| {
|
|
50
|
+
readonly _tag: "relation-every"
|
|
51
|
+
readonly path: string
|
|
52
|
+
readonly filter: readonly FilterResult[]
|
|
53
|
+
}
|
|
54
|
+
| {
|
|
55
|
+
readonly _tag: "relation-distinct-count"
|
|
56
|
+
readonly path: string
|
|
57
|
+
readonly field: string
|
|
58
|
+
readonly filter: readonly FilterResult[]
|
|
59
|
+
}
|
|
60
|
+
| {
|
|
61
|
+
readonly _tag: "relation-sum"
|
|
62
|
+
readonly path: string
|
|
63
|
+
readonly field: string
|
|
64
|
+
readonly filter: readonly FilterResult[]
|
|
65
|
+
}
|
|
66
|
+
| {
|
|
67
|
+
readonly _tag: "relation-sum-expr"
|
|
68
|
+
readonly path: string
|
|
69
|
+
readonly expression: ComputedProjectionMathIrExpression
|
|
70
|
+
readonly filter: readonly FilterResult[]
|
|
71
|
+
}
|
|
72
|
+
| {
|
|
73
|
+
readonly _tag: "relation-sum-expr-by"
|
|
74
|
+
readonly path: string
|
|
75
|
+
readonly expression: ComputedProjectionMathIrExpression
|
|
76
|
+
readonly unit: string
|
|
77
|
+
readonly filter: readonly FilterResult[]
|
|
78
|
+
}
|
|
79
|
+
| {
|
|
80
|
+
readonly _tag: "relation-sum-expr-normalized"
|
|
81
|
+
readonly path: string
|
|
82
|
+
readonly expression: ComputedProjectionMathIrExpression
|
|
83
|
+
readonly unit: string
|
|
84
|
+
readonly toBase: string
|
|
85
|
+
readonly factors: Readonly<Record<string, number>>
|
|
86
|
+
readonly filter: readonly FilterResult[]
|
|
87
|
+
}
|
|
88
|
+
| {
|
|
89
|
+
readonly _tag: "relation-collect"
|
|
90
|
+
readonly path: string
|
|
91
|
+
readonly field: string
|
|
92
|
+
readonly distinct: boolean
|
|
93
|
+
readonly filter: readonly FilterResult[]
|
|
94
|
+
}
|
|
95
|
+
| {
|
|
96
|
+
readonly _tag: "relation-collect-fields"
|
|
97
|
+
readonly path: string
|
|
98
|
+
readonly fields: readonly string[]
|
|
99
|
+
readonly distinct: boolean
|
|
100
|
+
readonly filter: readonly FilterResult[]
|
|
101
|
+
}
|
|
102
|
+
| {
|
|
103
|
+
readonly _tag: "relation-length"
|
|
104
|
+
readonly path: string
|
|
105
|
+
}
|
|
106
|
+
|
|
11
107
|
type Result<TFieldValues extends FieldValues, A = TFieldValues, R = never> = {
|
|
12
108
|
filter: FilterResult[]
|
|
13
109
|
schema: S.Codec<A, TFieldValues, R> | undefined
|
|
@@ -15,7 +111,9 @@ type Result<TFieldValues extends FieldValues, A = TFieldValues, R = never> = {
|
|
|
15
111
|
skip: number | undefined
|
|
16
112
|
order: { key: FieldPath<TFieldValues>; direction: "ASC" | "DESC" }[]
|
|
17
113
|
ttype: "one" | "many" | "count" | undefined
|
|
18
|
-
mode: "collect" | "project" | "transform" | undefined
|
|
114
|
+
mode: "collect" | "project" | "transform" | "aggregate" | undefined
|
|
115
|
+
computed: Record<string, ComputedProjectionIrExpression> | undefined
|
|
116
|
+
aggregateMap: Record<string, AggregateIrItem> | undefined
|
|
19
117
|
}
|
|
20
118
|
|
|
21
119
|
const interpret = <
|
|
@@ -33,7 +131,9 @@ const interpret = <
|
|
|
33
131
|
skip: undefined,
|
|
34
132
|
order: [],
|
|
35
133
|
ttype: undefined,
|
|
36
|
-
mode: undefined
|
|
134
|
+
mode: undefined,
|
|
135
|
+
computed: undefined,
|
|
136
|
+
aggregateMap: undefined
|
|
37
137
|
}
|
|
38
138
|
|
|
39
139
|
const upd = (
|
|
@@ -46,6 +146,8 @@ const interpret = <
|
|
|
46
146
|
if (v.ttype !== undefined) data.ttype = v.ttype
|
|
47
147
|
if (v.schema !== undefined) data.schema = v.schema
|
|
48
148
|
if (v.mode !== undefined) data.mode = v.mode
|
|
149
|
+
if (v.computed !== undefined) data.computed = v.computed
|
|
150
|
+
if (v.aggregateMap !== undefined) data.aggregateMap = v.aggregateMap
|
|
49
151
|
}
|
|
50
152
|
|
|
51
153
|
const applyPath = (path: string) => (_: FilterResult): FilterResult =>
|
|
@@ -135,8 +237,112 @@ const interpret = <
|
|
|
135
237
|
},
|
|
136
238
|
project: (v) => {
|
|
137
239
|
upd(interpret(v.current))
|
|
240
|
+
if (v.mode === "aggregate" && v.aggregateMap) {
|
|
241
|
+
data.schema = v.schema
|
|
242
|
+
data.mode = "aggregate"
|
|
243
|
+
data.aggregateMap = Object.fromEntries(
|
|
244
|
+
Object.entries(v.aggregateMap).map(([key, expression]) => {
|
|
245
|
+
switch (expression._tag) {
|
|
246
|
+
case "agg-field":
|
|
247
|
+
return [key, { _tag: "agg-field" as const, path: expression.path }]
|
|
248
|
+
case "agg-count":
|
|
249
|
+
return [key, { _tag: "agg-count" as const }]
|
|
250
|
+
case "agg-count-when": {
|
|
251
|
+
const filter = interpret(expression.operation(make())).filter
|
|
252
|
+
return [key, { _tag: "agg-count-when" as const, filter }]
|
|
253
|
+
}
|
|
254
|
+
case "agg-sum":
|
|
255
|
+
return [key, { _tag: "agg-sum" as const, field: expression.field }]
|
|
256
|
+
case "agg-min":
|
|
257
|
+
return [key, { _tag: "agg-min" as const, field: expression.field }]
|
|
258
|
+
case "agg-max":
|
|
259
|
+
return [key, { _tag: "agg-max" as const, field: expression.field }]
|
|
260
|
+
}
|
|
261
|
+
})
|
|
262
|
+
)
|
|
263
|
+
return
|
|
264
|
+
}
|
|
265
|
+
if (v.computed && v.mode === "transform") {
|
|
266
|
+
throw new Error("Computed projections require mode 'project' or 'collect', not 'transform'")
|
|
267
|
+
}
|
|
138
268
|
data.schema = v.schema
|
|
139
|
-
data.mode = v.
|
|
269
|
+
data.mode = v.computed
|
|
270
|
+
? v.mode === "collect" ? "collect" : "project"
|
|
271
|
+
: v.mode
|
|
272
|
+
data.computed = v.computed
|
|
273
|
+
? Object.fromEntries(
|
|
274
|
+
Object.entries(v.computed).map(([key, expression]) => {
|
|
275
|
+
const e = expression
|
|
276
|
+
const op = "operation" in e ? e.operation : undefined
|
|
277
|
+
const filter = op ? interpret(op(make())).filter.map(applyPath(e.path)) : []
|
|
278
|
+
switch (e._tag) {
|
|
279
|
+
case "relation-count":
|
|
280
|
+
case "relation-any":
|
|
281
|
+
case "relation-every":
|
|
282
|
+
return [key, { _tag: e._tag, path: e.path, filter } as ComputedProjectionIrExpression]
|
|
283
|
+
case "relation-distinct-count":
|
|
284
|
+
case "relation-sum":
|
|
285
|
+
return [
|
|
286
|
+
key,
|
|
287
|
+
{ _tag: e._tag, path: e.path, field: e.field, filter } as ComputedProjectionIrExpression
|
|
288
|
+
]
|
|
289
|
+
case "relation-sum-expr":
|
|
290
|
+
return [
|
|
291
|
+
key,
|
|
292
|
+
{ _tag: e._tag, path: e.path, expression: e.expression, filter } as ComputedProjectionIrExpression
|
|
293
|
+
]
|
|
294
|
+
case "relation-sum-expr-by":
|
|
295
|
+
return [
|
|
296
|
+
key,
|
|
297
|
+
{
|
|
298
|
+
_tag: e._tag,
|
|
299
|
+
path: e.path,
|
|
300
|
+
expression: e.expression,
|
|
301
|
+
unit: e.unit,
|
|
302
|
+
filter
|
|
303
|
+
} as ComputedProjectionIrExpression
|
|
304
|
+
]
|
|
305
|
+
case "relation-sum-expr-normalized":
|
|
306
|
+
return [
|
|
307
|
+
key,
|
|
308
|
+
{
|
|
309
|
+
_tag: e._tag,
|
|
310
|
+
path: e.path,
|
|
311
|
+
expression: e.expression,
|
|
312
|
+
unit: e.unit,
|
|
313
|
+
toBase: e.toBase,
|
|
314
|
+
factors: e.factors,
|
|
315
|
+
filter
|
|
316
|
+
} as ComputedProjectionIrExpression
|
|
317
|
+
]
|
|
318
|
+
case "relation-collect":
|
|
319
|
+
return [
|
|
320
|
+
key,
|
|
321
|
+
{
|
|
322
|
+
_tag: e._tag,
|
|
323
|
+
path: e.path,
|
|
324
|
+
field: e.field,
|
|
325
|
+
distinct: e.distinct,
|
|
326
|
+
filter
|
|
327
|
+
} as ComputedProjectionIrExpression
|
|
328
|
+
]
|
|
329
|
+
case "relation-collect-fields":
|
|
330
|
+
return [
|
|
331
|
+
key,
|
|
332
|
+
{
|
|
333
|
+
_tag: e._tag,
|
|
334
|
+
path: e.path,
|
|
335
|
+
fields: e.fields,
|
|
336
|
+
distinct: e.distinct,
|
|
337
|
+
filter
|
|
338
|
+
} as ComputedProjectionIrExpression
|
|
339
|
+
]
|
|
340
|
+
case "relation-length":
|
|
341
|
+
return [key, { _tag: e._tag, path: e.path } as ComputedProjectionIrExpression]
|
|
342
|
+
}
|
|
343
|
+
})
|
|
344
|
+
)
|
|
345
|
+
: undefined
|
|
140
346
|
}
|
|
141
347
|
})
|
|
142
348
|
)
|
|
@@ -157,15 +363,42 @@ export const toFilter = <
|
|
|
157
363
|
R,
|
|
158
364
|
TFieldValuesRefined extends TFieldValues = TFieldValues
|
|
159
365
|
>(
|
|
160
|
-
q: QAll<TFieldValues, TFieldValuesRefined, A, R
|
|
366
|
+
q: QAll<TFieldValues, TFieldValuesRefined, A, R>,
|
|
367
|
+
baseSchema?: S.Schema<unknown>
|
|
161
368
|
) => {
|
|
162
369
|
// TODO: Native interpreter for each db adapter, instead of the intermediate "new-kid" format
|
|
163
370
|
const a = interpret(q)
|
|
371
|
+
|
|
372
|
+
// Aggregate mode: build select entirely from aggregateMap (no schema-driven field list)
|
|
373
|
+
if (a.mode === "aggregate" && a.aggregateMap) {
|
|
374
|
+
const aggSelect = Object.entries(a.aggregateMap).map(([key, item]) => {
|
|
375
|
+
if (item._tag === "agg-field") {
|
|
376
|
+
return { key, path: item.path }
|
|
377
|
+
}
|
|
378
|
+
return { key, aggregate: item }
|
|
379
|
+
})
|
|
380
|
+
return dropUndefinedT({
|
|
381
|
+
t: null as unknown as TFieldValues,
|
|
382
|
+
limit: a.limit,
|
|
383
|
+
skip: a.skip,
|
|
384
|
+
select: Option.getOrUndefined(toNonEmptyArray(aggSelect)) as any,
|
|
385
|
+
schema: a.schema,
|
|
386
|
+
computed: undefined,
|
|
387
|
+
order: Option.getOrUndefined(toNonEmptyArray(a.order)),
|
|
388
|
+
ttype: a.ttype,
|
|
389
|
+
mode: "aggregate" as const,
|
|
390
|
+
filter: a.filter.length ? a.filter : undefined
|
|
391
|
+
})
|
|
392
|
+
}
|
|
393
|
+
|
|
164
394
|
const schema = a.schema
|
|
165
|
-
let select: (keyof TFieldValues | { key: string; subKeys: string[] }
|
|
395
|
+
let select: (keyof TFieldValues | { key: string; subKeys: string[] } | {
|
|
396
|
+
key: string
|
|
397
|
+
computed: ComputedProjectionIrExpression
|
|
398
|
+
})[] = []
|
|
166
399
|
// TODO: support more complex (nested) schemas?
|
|
167
400
|
if (schema) {
|
|
168
|
-
const t = walkTransformation(schema.ast)
|
|
401
|
+
const t = walkTransformation(SchemaAST.toEncoded(schema.ast))
|
|
169
402
|
if (S.AST.isObjects(t)) {
|
|
170
403
|
select = t.propertySignatures.map((_) => _.name as string)
|
|
171
404
|
for (const prop of t.propertySignatures) {
|
|
@@ -194,12 +427,53 @@ export const toFilter = <
|
|
|
194
427
|
}
|
|
195
428
|
}
|
|
196
429
|
}
|
|
430
|
+
const computed = a.computed
|
|
431
|
+
const getSelectKey = (_: (typeof select)[number]) => {
|
|
432
|
+
if (typeof _ === "string") {
|
|
433
|
+
return _
|
|
434
|
+
}
|
|
435
|
+
if (typeof _ === "object" && _ !== null && "key" in _) {
|
|
436
|
+
return _.key
|
|
437
|
+
}
|
|
438
|
+
return String(_)
|
|
439
|
+
}
|
|
440
|
+
const schemaKeys = select.map(getSelectKey)
|
|
441
|
+
const nonEncodedSchemaKeys = (() => {
|
|
442
|
+
if (!baseSchema) {
|
|
443
|
+
return [] as string[]
|
|
444
|
+
}
|
|
445
|
+
const encoded = walkTransformation(SchemaAST.toEncoded(baseSchema.ast))
|
|
446
|
+
if (!S.AST.isObjects(encoded)) {
|
|
447
|
+
return [] as string[]
|
|
448
|
+
}
|
|
449
|
+
const encodedKeys = encoded.propertySignatures.map((_) => _.name as string)
|
|
450
|
+
return schemaKeys.filter((key) => !encodedKeys.includes(key))
|
|
451
|
+
})()
|
|
452
|
+
const missingComputedKeys = nonEncodedSchemaKeys.filter((key) => !(computed && key in computed))
|
|
453
|
+
|
|
454
|
+
if (Array.isArrayNonEmpty(missingComputedKeys)) {
|
|
455
|
+
throw new Error(`Missing computed projections for schema keys: ${missingComputedKeys.join(", ")}`)
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
if (computed) {
|
|
459
|
+
const computedKeys = Object.keys(computed)
|
|
460
|
+
const extraComputedKeys = computedKeys.filter((key) => !schemaKeys.includes(key))
|
|
461
|
+
if (Array.isArrayNonEmpty(extraComputedKeys)) {
|
|
462
|
+
throw new Error(`Computed projection keys must exist in projection schema: ${extraComputedKeys.join(", ")}`)
|
|
463
|
+
}
|
|
464
|
+
select = select.filter((_) => {
|
|
465
|
+
const key = getSelectKey(_)
|
|
466
|
+
return !(key in computed)
|
|
467
|
+
})
|
|
468
|
+
select.push(...Object.entries(computed).map(([key, expression]) => ({ key, computed: expression })))
|
|
469
|
+
}
|
|
197
470
|
return dropUndefinedT({
|
|
198
471
|
t: null as unknown as TFieldValues,
|
|
199
472
|
limit: a.limit,
|
|
200
473
|
skip: a.skip,
|
|
201
474
|
select: Option.getOrUndefined(toNonEmptyArray(select)),
|
|
202
475
|
schema,
|
|
476
|
+
computed,
|
|
203
477
|
order: Option.getOrUndefined(toNonEmptyArray(a.order)),
|
|
204
478
|
ttype: a.ttype,
|
|
205
479
|
mode: a.mode ?? "transform",
|
package/src/Model.ts
CHANGED