kitcn 0.26.2 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -0
- package/dist/aggregate/index.d.ts +2 -2
- package/dist/auth/generated/index.d.ts +1 -1
- package/dist/auth/index.d.ts +6 -6
- package/dist/{capabilities-DtDfpdcH.d.ts → capabilities-CLCYgRdY.d.ts} +12 -1
- package/dist/{generated-contract-disabled-BEc4d98x.d.ts → generated-contract-disabled-DwYwySy3.d.ts} +2 -2
- package/dist/orm/aggregate-index/index.d.ts +1 -1
- package/dist/orm/index.d.ts +2 -2
- package/dist/orm/index.js +37 -22
- package/dist/orm/migrations/index.d.ts +2 -2
- package/dist/{where-clause-compiler-eTewPUGq.d.ts → where-clause-compiler-DAPEBp1y.d.ts} +60 -60
- package/package.json +1 -1
- package/skills/kitcn/references/features/aggregates.md +32 -0
- package/skills/kitcn/references/features/orm.md +33 -23
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,65 @@
|
|
|
1
1
|
# kitcn
|
|
2
2
|
|
|
3
|
+
## 0.27.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#395](https://github.com/udecode/kitcn/pull/395) [`2c9ffd2`](https://github.com/udecode/kitcn/commit/2c9ffd20987e4a94cb5790cbb72e6249f1fdfcf4) Thanks [@MikeyZhang75](https://github.com/MikeyZhang75)! - ## Breaking changes
|
|
8
|
+
|
|
9
|
+
- Nested `with:` now loads every level it is given, up to 10, instead of quietly dropping everything past the third. A config that nests deeper throws `RELATION_DEPTH_EXCEEDED` rather than returning a shorter tree. Deep `with:` configs that used to come back truncated now come back complete — and read the rows that completeness costs.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
// Before: the fourth level was dropped, with no error
|
|
13
|
+
const rows = await ctx.orm.query.comments.findMany({
|
|
14
|
+
limit: 20,
|
|
15
|
+
with: {
|
|
16
|
+
replies: {
|
|
17
|
+
limit: 10,
|
|
18
|
+
with: { replies: { limit: 10, with: { author: true } } },
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
rows[0].replies[0].replies[0].author; // undefined
|
|
23
|
+
|
|
24
|
+
// After: loaded, because it was asked for
|
|
25
|
+
rows[0].replies[0].replies[0].author; // { id, name }
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Patches
|
|
29
|
+
|
|
30
|
+
- Resolve `with: { _count }` at every level of a nested `with:`, including the deepest one returned. A tree can now report how many children it withheld without a second pass that re-reads every node the caller already holds.
|
|
31
|
+
|
|
32
|
+
## 0.26.3
|
|
33
|
+
|
|
34
|
+
### Patch Changes
|
|
35
|
+
|
|
36
|
+
- [#394](https://github.com/udecode/kitcn/pull/394) [`1317349`](https://github.com/udecode/kitcn/commit/13173495fa8db3d8a0568642981c1cdef4dcdf2b) Thanks [@MikeyZhang75](https://github.com/MikeyZhang75)! - ## Features
|
|
37
|
+
|
|
38
|
+
- Support a per-source `index: { name, range }` on `select().union([...])`, so each source walks its own index range instead of re-walking one shared range and filtering the misses in JS.
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
const page = await db.query.messages
|
|
42
|
+
.select()
|
|
43
|
+
.union([
|
|
44
|
+
{
|
|
45
|
+
index: {
|
|
46
|
+
name: "by_from_to",
|
|
47
|
+
range: (q) => q.eq("from", me).eq("to", them),
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
index: {
|
|
52
|
+
name: "by_from_to",
|
|
53
|
+
range: (q) => q.eq("from", them).eq("to", me),
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
])
|
|
57
|
+
.interleaveBy(["createdAt", "id"])
|
|
58
|
+
.paginate({ cursor: null, limit: 20 });
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
- Support union sources anchored on different indexes, as long as each source pins its leading fields with `eq` and ends up ordered by the `interleaveBy` fields.
|
|
62
|
+
|
|
3
63
|
## 0.26.2
|
|
4
64
|
|
|
5
65
|
### Patch Changes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Bn as ConvexTextBuilderInitial, Xt as ConvexTableWithColumns } from "../capabilities-
|
|
2
|
-
import { C as ConvexNumberBuilderInitial, E as ConvexIdBuilderInitial, N as ConvexCustomBuilderInitial } from "../where-clause-compiler-
|
|
1
|
+
import { Bn as ConvexTextBuilderInitial, Xt as ConvexTableWithColumns } from "../capabilities-CLCYgRdY.js";
|
|
2
|
+
import { C as ConvexNumberBuilderInitial, E as ConvexIdBuilderInitial, N as ConvexCustomBuilderInitial } from "../where-clause-compiler-DAPEBp1y.js";
|
|
3
3
|
import * as convex_values0 from "convex/values";
|
|
4
4
|
import { GenericId, Infer, Value } from "convex/values";
|
|
5
5
|
import { DocumentByName, GenericDataModel, GenericDatabaseReader, GenericDatabaseWriter, TableNamesInDataModel } from "convex/server";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { S as defineAuth, _ as GenericAuthBeforeResult, b as GenericAuthTriggerHandlers, g as BetterAuthOptionsWithoutDatabase, i as getGeneratedAuthDisabledReason, n as GeneratedAuthDisabledReasonKind, r as createDisabledAuthRuntime, t as AuthRuntime, v as GenericAuthDefinition, x as GenericAuthTriggers, y as GenericAuthTriggerChange } from "../../generated-contract-disabled-
|
|
1
|
+
import { S as defineAuth, _ as GenericAuthBeforeResult, b as GenericAuthTriggerHandlers, g as BetterAuthOptionsWithoutDatabase, i as getGeneratedAuthDisabledReason, n as GeneratedAuthDisabledReasonKind, r as createDisabledAuthRuntime, t as AuthRuntime, v as GenericAuthDefinition, x as GenericAuthTriggers, y as GenericAuthTriggerChange } from "../../generated-contract-disabled-DwYwySy3.js";
|
|
2
2
|
export { type AuthRuntime, BetterAuthOptionsWithoutDatabase, type GeneratedAuthDisabledReasonKind, GenericAuthBeforeResult, GenericAuthDefinition, GenericAuthTriggerChange, GenericAuthTriggerHandlers, GenericAuthTriggers, createDisabledAuthRuntime, defineAuth, getGeneratedAuthDisabledReason };
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { a as QueryCtxWithPreferredOrmQueryTable, n as LookupByIdResultByCtx, t as DocByCtx } from "../query-context-DJONf8X5.js";
|
|
2
2
|
import { t as GetAuth } from "../types-Bf3XQex5.js";
|
|
3
3
|
import { t as GenericCtx } from "../context-utils-DwZ3Cam1.js";
|
|
4
|
-
import { S as defineAuth, _ as GenericAuthBeforeResult, a as AuthFunctions, b as GenericAuthTriggerHandlers, c as createApi, d as deleteOneHandler, f as findManyHandler, g as BetterAuthOptionsWithoutDatabase, h as updateOneHandler, i as getGeneratedAuthDisabledReason, l as createHandler, m as updateManyHandler, n as GeneratedAuthDisabledReasonKind, o as Triggers, p as findOneHandler, r as createDisabledAuthRuntime, s as createClient, t as AuthRuntime, u as deleteManyHandler, v as GenericAuthDefinition, x as GenericAuthTriggers, y as GenericAuthTriggerChange } from "../generated-contract-disabled-
|
|
4
|
+
import { S as defineAuth, _ as GenericAuthBeforeResult, a as AuthFunctions, b as GenericAuthTriggerHandlers, c as createApi, d as deleteOneHandler, f as findManyHandler, g as BetterAuthOptionsWithoutDatabase, h as updateOneHandler, i as getGeneratedAuthDisabledReason, l as createHandler, m as updateManyHandler, n as GeneratedAuthDisabledReasonKind, o as Triggers, p as findOneHandler, r as createDisabledAuthRuntime, s as createClient, t as AuthRuntime, u as deleteManyHandler, v as GenericAuthDefinition, x as GenericAuthTriggers, y as GenericAuthTriggerChange } from "../generated-contract-disabled-DwYwySy3.js";
|
|
5
5
|
import * as convex_values0 from "convex/values";
|
|
6
6
|
import { Infer } from "convex/values";
|
|
7
7
|
import { AuthConfig, DocumentByName, GenericDataModel, GenericMutationCtx, GenericQueryCtx, GenericSchema, PaginationOptions, PaginationResult, SchemaDefinition, TableNamesInDataModel } from "convex/server";
|
|
@@ -123,6 +123,7 @@ declare const adapterWhereValidator: convex_values0.VObject<{
|
|
|
123
123
|
value: convex_values0.VUnion<string | number | boolean | string[] | number[] | null, [convex_values0.VString<string, "required">, convex_values0.VFloat64<number, "required">, convex_values0.VBoolean<boolean, "required">, convex_values0.VArray<string[], convex_values0.VString<string, "required">, "required">, convex_values0.VArray<number[], convex_values0.VFloat64<number, "required">, "required">, convex_values0.VNull<null, "required">], "required", never>;
|
|
124
124
|
}, "required", "mode" | "value" | "connector" | "field" | "operator">;
|
|
125
125
|
declare const adapterArgsValidator: convex_values0.VObject<{
|
|
126
|
+
limit?: number | undefined;
|
|
126
127
|
select?: string[] | undefined;
|
|
127
128
|
where?: {
|
|
128
129
|
mode?: "sensitive" | "insensitive" | undefined;
|
|
@@ -131,11 +132,10 @@ declare const adapterArgsValidator: convex_values0.VObject<{
|
|
|
131
132
|
value: string | number | boolean | string[] | number[] | null;
|
|
132
133
|
field: string;
|
|
133
134
|
}[] | undefined;
|
|
134
|
-
limit?: number | undefined;
|
|
135
135
|
offset?: number | undefined;
|
|
136
136
|
sortBy?: {
|
|
137
|
-
field: string;
|
|
138
137
|
direction: "asc" | "desc";
|
|
138
|
+
field: string;
|
|
139
139
|
} | undefined;
|
|
140
140
|
model: string;
|
|
141
141
|
}, {
|
|
@@ -144,12 +144,12 @@ declare const adapterArgsValidator: convex_values0.VObject<{
|
|
|
144
144
|
offset: convex_values0.VFloat64<number | undefined, "optional">;
|
|
145
145
|
select: convex_values0.VArray<string[] | undefined, convex_values0.VString<string, "required">, "optional">;
|
|
146
146
|
sortBy: convex_values0.VObject<{
|
|
147
|
-
field: string;
|
|
148
147
|
direction: "asc" | "desc";
|
|
148
|
+
field: string;
|
|
149
149
|
} | undefined, {
|
|
150
150
|
direction: convex_values0.VUnion<"asc" | "desc", [convex_values0.VLiteral<"asc", "required">, convex_values0.VLiteral<"desc", "required">], "required", never>;
|
|
151
151
|
field: convex_values0.VString<string, "required">;
|
|
152
|
-
}, "optional", "
|
|
152
|
+
}, "optional", "direction" | "field">;
|
|
153
153
|
where: convex_values0.VArray<{
|
|
154
154
|
mode?: "sensitive" | "insensitive" | undefined;
|
|
155
155
|
connector?: "AND" | "OR" | undefined;
|
|
@@ -169,7 +169,7 @@ declare const adapterArgsValidator: convex_values0.VObject<{
|
|
|
169
169
|
operator: convex_values0.VUnion<"lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined, [convex_values0.VLiteral<"lt", "required">, convex_values0.VLiteral<"lte", "required">, convex_values0.VLiteral<"gt", "required">, convex_values0.VLiteral<"gte", "required">, convex_values0.VLiteral<"eq", "required">, convex_values0.VLiteral<"in", "required">, convex_values0.VLiteral<"not_in", "required">, convex_values0.VLiteral<"ne", "required">, convex_values0.VLiteral<"contains", "required">, convex_values0.VLiteral<"starts_with", "required">, convex_values0.VLiteral<"ends_with", "required">], "optional", never>;
|
|
170
170
|
value: convex_values0.VUnion<string | number | boolean | string[] | number[] | null, [convex_values0.VString<string, "required">, convex_values0.VFloat64<number, "required">, convex_values0.VBoolean<boolean, "required">, convex_values0.VArray<string[], convex_values0.VString<string, "required">, "required">, convex_values0.VArray<number[], convex_values0.VFloat64<number, "required">, "required">, convex_values0.VNull<null, "required">], "required", never>;
|
|
171
171
|
}, "required", "mode" | "value" | "connector" | "field" | "operator">, "optional">;
|
|
172
|
-
}, "required", "
|
|
172
|
+
}, "required", "limit" | "model" | "select" | "where" | "offset" | "sortBy" | "sortBy.direction" | "sortBy.field">;
|
|
173
173
|
declare const hasUniqueFields: (betterAuthSchema: BetterAuthDBSchema, model: string, input: Record<string, any>) => boolean;
|
|
174
174
|
declare const checkUniqueFields: <Schema extends SchemaDefinition<any, any>>(ctx: GenericQueryCtx<GenericDataModel>, schema: Schema, betterAuthSchema: BetterAuthDBSchema, table: string, input: Record<string, any>, doc?: Record<string, any>) => Promise<void>;
|
|
175
175
|
declare const selectFields: <T extends TableNamesInDataModel<GenericDataModel>, D extends DocumentByName<GenericDataModel, T>>(doc: D | null, select?: string[]) => D | null;
|
|
@@ -1430,6 +1430,16 @@ type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y
|
|
|
1430
1430
|
type Merge<A, B> = { [K in keyof A | keyof B]: K extends keyof B ? B[K] : K extends keyof A ? A[K] : never };
|
|
1431
1431
|
type IndexKey = (Value | undefined)[];
|
|
1432
1432
|
type FindManyUnionSource<TTableConfig extends TableRelationalConfig = TableRelationalConfig> = {
|
|
1433
|
+
/**
|
|
1434
|
+
* Index anchor for this source alone. Overrides the chain-level
|
|
1435
|
+
* `.withIndex(...)`, so each source can walk its own range instead of
|
|
1436
|
+
* re-walking one shared range and discarding the misses in JS.
|
|
1437
|
+
*
|
|
1438
|
+
* Sources may pin different indexes: `interleaveBy` re-orders every source by
|
|
1439
|
+
* the same trailing fields before merging, so what has to match across
|
|
1440
|
+
* sources is that ordering suffix, not the index name.
|
|
1441
|
+
*/
|
|
1442
|
+
index?: PredicateWhereIndexConfig<TTableConfig>;
|
|
1433
1443
|
where?: RelationsFilter<TTableConfig, any> | WhereCallback<TTableConfig>;
|
|
1434
1444
|
};
|
|
1435
1445
|
type PipelineRelationName<TTableConfig extends TableRelationalConfig> = Extract<keyof TTableConfig['relations'], string>;
|
|
@@ -3121,7 +3131,7 @@ declare class GelRelationalQuery<TSchema extends TablesRelationalConfig, TTableC
|
|
|
3121
3131
|
* @param rows - Array of parent records to load relations for
|
|
3122
3132
|
* @param withConfig - Relation configuration object
|
|
3123
3133
|
* @param depth - Current recursion depth (default 0)
|
|
3124
|
-
* @param maxDepth -
|
|
3134
|
+
* @param maxDepth - Runaway ceiling for self-referential configs (default `MAX_RELATION_DEPTH`)
|
|
3125
3135
|
* @param targetTableEdges - Edge metadata for nested relations (optional, defaults to this.edgeMetadata)
|
|
3126
3136
|
*/
|
|
3127
3137
|
private _loadRelations;
|
|
@@ -3132,6 +3142,7 @@ declare class GelRelationalQuery<TSchema extends TablesRelationalConfig, TTableC
|
|
|
3132
3142
|
*/
|
|
3133
3143
|
private _loadSingleRelation;
|
|
3134
3144
|
private _createRelationCountError;
|
|
3145
|
+
private _createRelationDepthError;
|
|
3135
3146
|
private _remapRelationCountError;
|
|
3136
3147
|
private _coerceRelationCountWhere;
|
|
3137
3148
|
private _getRelationCountParentKey;
|
package/dist/{generated-contract-disabled-BEc4d98x.d.ts → generated-contract-disabled-DwYwySy3.d.ts}
RENAMED
|
@@ -224,6 +224,7 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>, DataModel e
|
|
|
224
224
|
};
|
|
225
225
|
}, Promise<Record<string, unknown> | undefined>>;
|
|
226
226
|
findMany: convex_server0.RegisteredQuery<"internal", {
|
|
227
|
+
limit?: number | undefined;
|
|
227
228
|
join?: any;
|
|
228
229
|
where?: {
|
|
229
230
|
mode?: "sensitive" | "insensitive" | undefined;
|
|
@@ -232,11 +233,10 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>, DataModel e
|
|
|
232
233
|
value: string | number | boolean | string[] | number[] | null;
|
|
233
234
|
field: string;
|
|
234
235
|
}[] | undefined;
|
|
235
|
-
limit?: number | undefined;
|
|
236
236
|
offset?: number | undefined;
|
|
237
237
|
sortBy?: {
|
|
238
|
-
field: string;
|
|
239
238
|
direction: "asc" | "desc";
|
|
239
|
+
field: string;
|
|
240
240
|
} | undefined;
|
|
241
241
|
model: string;
|
|
242
242
|
paginationOpts: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as RankOrderField, G as CountBackfillKickoffArgs, J as AggregateQueryPlan, K as CountBackfillMode, Q as RankIndexDefinition, W as CountBackfillChunkArgs, X as AggregateIndexDefinition, Y as CountQueryPlan, Z as CountIndexDefinition, q as CountBackfillStatusArgs, r as OrmCapability } from "../../capabilities-
|
|
1
|
+
import { $ as RankOrderField, G as CountBackfillKickoffArgs, J as AggregateQueryPlan, K as CountBackfillMode, Q as RankIndexDefinition, W as CountBackfillChunkArgs, X as AggregateIndexDefinition, Y as CountQueryPlan, Z as CountIndexDefinition, q as CountBackfillStatusArgs, r as OrmCapability } from "../../capabilities-CLCYgRdY.js";
|
|
2
2
|
|
|
3
3
|
//#region src/orm/aggregate-index/capability.d.ts
|
|
4
4
|
/**
|
package/dist/orm/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { $n as BinaryExpression, $t as OrmLifecycleOperation, A as DatabaseWithMutations, An as ConvexCheckConfig, Ar as AnyColumn, At as VectorQueryConfig, B as RlsContext, Bn as ConvexTextBuilderInitial, Br as IsUnique, Bt as RelationsBuilderColumnConfig, C as MigrationTableName, Cn as aggregateIndex, Cr as notBetween, Ct as OrderDirection, D as defineMigrationSet, Dn as uniqueIndex, Dt as ReturningResult, E as defineMigration, En as searchIndex, Er as startsWith, Et as ReturningAll, Fn as ConvexUniqueConstraintConfig, Fr as ColumnBuilderWithTableName, Ft as ExtractTablesWithRelations, Gt as defineRelations, H as EdgeMetadata, In as check, Ir as ColumnDataType, It as ManyConfig, Jt as ConvexDeletionConfig, Kt as defineRelationsPart, Ln as foreignKey, Lr as DrizzleEntity, Lt as OneConfig, M as OrmReader$1, Mn as ConvexForeignKeyConfig, Mr as ColumnBuilderBaseConfig, Mt as unsetToken, N as OrmWriter$1, Nn as ConvexUniqueConstraintBuilder, Nr as ColumnBuilderRuntimeConfig, O as detectMigrationDrift, On as vectorIndex, Or as SystemFields, Ot as ReturningSelection, Pn as ConvexUniqueConstraintBuilderOn, Pr as ColumnBuilderTypeConfig, Pt as ExtractTablesFromSchema, Qn as TableName, Qt as OrmLifecycleChange, Rn as unique, Rr as HasDefault, Rt as RelationsBuilder, S as MigrationStep, Sn as ConvexVectorIndexConfig, Sr as not, St as OrderByClause, T as buildMigrationPlan, Tn as rankIndex, Tr as or, Tt as PredicateWhereIndexConfig, U as extractRelationsConfig, Un as Brand, Ut as TableRelationalConfig, V as RlsMode, Vn as text, Vr as NotNull, Wn as Columns, Wt as TablesRelationalConfig, Xn as OrmSchemaRelations, Xt as ConvexTableWithColumns, Yn as OrmSchemaExtensions, Yt as ConvexTable, Zn as OrmSchemaTriggers, Zt as DiscriminatorBuilderConfig, _ as MigrationMigrateOne, _n as ConvexSearchIndexBuilder, _r as isNull, _t as MutationPaginateConfig, an as RlsPolicyConfig, ar as and, at as CountConfig, b as MigrationSet, bn as ConvexVectorIndexBuilder, br as lte, bt as MutationReturning, cn as RlsRole, cr as endsWith, ct as FilterOperators, d as MigrationDefinition, dn as ConvexAggregateIndexBuilder, dr as gt, dt as InferModelFromColumns, en as TableConfig, er as ExpressionVisitor, et as AggregateConfig, f as MigrationDirection, fn as ConvexAggregateIndexBuilderOn, fr as gte, ft as InferSelectModel, g as MigrationManifestEntry, gn as ConvexRankIndexBuilderOn, gr as isNotNull, gt as MutationExecutionMode, h as MigrationDriftIssue, hn as ConvexRankIndexBuilder, hr as isFieldReference, ht as MutationExecuteResult, i as OrmMigrationCapability, in as RlsPolicy, ir as UnaryExpression, it as BuildRelationResult, j as DatabaseWithQuery, jn as ConvexForeignKeyBuilder, jr as ColumnBuilder, jt as VectorSearchProvider, kn as ConvexCheckBuilder, kt as UpdateSet, ln as RlsRoleConfig, lr as eq, lt as GetColumnData, m as MigrationDocContext, mn as ConvexIndexBuilderOn, mr as inArray, mt as MutationExecuteConfig, n as OrmCapabilities, nn as deletion, nr as FilterExpression, nt as AggregateResult, on as RlsPolicyToOption, or as between, ot as CountResult, p as MigrationDoc, pn as ConvexIndexBuilder, pr as ilike, pt as InsertValue, qn as OrmSchemaExtensionTables, qt as ConvexDeletionBuilder, r as OrmCapability, rn as discriminator, rr as LogicalExpression, rt as BuildQueryResult, sn as rlsPolicy, sr as contains, st as DBQueryConfig, t as OrmAggregateCapability, tn as convexTable, tr as FieldReference, tt as AggregateFieldValue, u as MigrationAppliedState, un as rlsRole, ur as fieldRef, ut as InferInsertModel, v as MigrationPlan, vn as ConvexSearchIndexBuilderOn, vr as like, vt as MutationPaginatedResult, w as MigrationWriteMode, wn as index, wr as notInArray, wt as PaginatedResult, x as MigrationStateMap, xn as ConvexVectorIndexBuilderOn, xr as ne, xt as MutationRunMode, y as MigrationRunStatus, yn as ConvexSearchIndexConfig, yr as lt, yt as MutationResult, zn as ConvexTextBuilder, zr as IsPrimaryKey, zt as RelationsBuilderColumnBase } from "../capabilities-
|
|
2
|
-
import { $ as OrmClientWithApi$1, A as ConvexDateMode, B as ConvexBytesBuilderInitial, C as ConvexNumberBuilderInitial, D as id, E as ConvexIdBuilderInitial, F as custom, G as ConvexBigIntBuilder, H as ConvexBooleanBuilder, I as json, J as CreateOrmOptions, K as ConvexBigIntBuilderInitial, L as objectOf, M as ConvexCustomBuilder, N as ConvexCustomBuilderInitial, O as ConvexDateBuilder, P as arrayOf, Q as OrmClientBase$1, R as unionOf, S as ConvexNumberBuilder, St as defineTriggers, T as ConvexIdBuilder, U as ConvexBooleanBuilderInitial, V as bytes, W as boolean, X as GenericOrmCtx$1, Y as GenericOrm$1, Z as OrmApiResult, _ as ConvexTimestampMode, _t as OrmBeforeResult, a as requireSchemaRelations, at as ScheduledMutationBatchArgs, b as ConvexTextEnumBuilderInitial, bt as OrmTriggerContext, c as TableConfigResult, ct as scheduledDeleteFactory, d as OrmNotFoundError, et as OrmFunctions, f as ConvexVectorBuilder, g as ConvexTimestampBuilderInitial, gt as defineSchemaExtension, h as ConvexTimestampBuilder, ht as SchemaExtension, i as getSchemaTriggers, it as createOrm, j as date, k as ConvexDateBuilderInitial, l as getTableColumns, m as vector, n as defineSchema, nt as OrmWriterCtx, o as asc, ot as scheduledMutationBatchFactory, p as ConvexVectorBuilderInitial, q as bigint, r as getSchemaRelations, rt as ResolveOrmSchema, s as desc, st as ScheduledDeleteArgs, t as WhereClauseResult, tt as OrmReaderCtx, u as getTableConfig, v as timestamp, vt as OrmTableTriggers, w as integer, x as textEnum, xt as OrmTriggers, y as ConvexTextEnumBuilder, yt as OrmTriggerChange, z as ConvexBytesBuilder } from "../where-clause-compiler-
|
|
1
|
+
import { $n as BinaryExpression, $t as OrmLifecycleOperation, A as DatabaseWithMutations, An as ConvexCheckConfig, Ar as AnyColumn, At as VectorQueryConfig, B as RlsContext, Bn as ConvexTextBuilderInitial, Br as IsUnique, Bt as RelationsBuilderColumnConfig, C as MigrationTableName, Cn as aggregateIndex, Cr as notBetween, Ct as OrderDirection, D as defineMigrationSet, Dn as uniqueIndex, Dt as ReturningResult, E as defineMigration, En as searchIndex, Er as startsWith, Et as ReturningAll, Fn as ConvexUniqueConstraintConfig, Fr as ColumnBuilderWithTableName, Ft as ExtractTablesWithRelations, Gt as defineRelations, H as EdgeMetadata, In as check, Ir as ColumnDataType, It as ManyConfig, Jt as ConvexDeletionConfig, Kt as defineRelationsPart, Ln as foreignKey, Lr as DrizzleEntity, Lt as OneConfig, M as OrmReader$1, Mn as ConvexForeignKeyConfig, Mr as ColumnBuilderBaseConfig, Mt as unsetToken, N as OrmWriter$1, Nn as ConvexUniqueConstraintBuilder, Nr as ColumnBuilderRuntimeConfig, O as detectMigrationDrift, On as vectorIndex, Or as SystemFields, Ot as ReturningSelection, Pn as ConvexUniqueConstraintBuilderOn, Pr as ColumnBuilderTypeConfig, Pt as ExtractTablesFromSchema, Qn as TableName, Qt as OrmLifecycleChange, Rn as unique, Rr as HasDefault, Rt as RelationsBuilder, S as MigrationStep, Sn as ConvexVectorIndexConfig, Sr as not, St as OrderByClause, T as buildMigrationPlan, Tn as rankIndex, Tr as or, Tt as PredicateWhereIndexConfig, U as extractRelationsConfig, Un as Brand, Ut as TableRelationalConfig, V as RlsMode, Vn as text, Vr as NotNull, Wn as Columns, Wt as TablesRelationalConfig, Xn as OrmSchemaRelations, Xt as ConvexTableWithColumns, Yn as OrmSchemaExtensions, Yt as ConvexTable, Zn as OrmSchemaTriggers, Zt as DiscriminatorBuilderConfig, _ as MigrationMigrateOne, _n as ConvexSearchIndexBuilder, _r as isNull, _t as MutationPaginateConfig, an as RlsPolicyConfig, ar as and, at as CountConfig, b as MigrationSet, bn as ConvexVectorIndexBuilder, br as lte, bt as MutationReturning, cn as RlsRole, cr as endsWith, ct as FilterOperators, d as MigrationDefinition, dn as ConvexAggregateIndexBuilder, dr as gt, dt as InferModelFromColumns, en as TableConfig, er as ExpressionVisitor, et as AggregateConfig, f as MigrationDirection, fn as ConvexAggregateIndexBuilderOn, fr as gte, ft as InferSelectModel, g as MigrationManifestEntry, gn as ConvexRankIndexBuilderOn, gr as isNotNull, gt as MutationExecutionMode, h as MigrationDriftIssue, hn as ConvexRankIndexBuilder, hr as isFieldReference, ht as MutationExecuteResult, i as OrmMigrationCapability, in as RlsPolicy, ir as UnaryExpression, it as BuildRelationResult, j as DatabaseWithQuery, jn as ConvexForeignKeyBuilder, jr as ColumnBuilder, jt as VectorSearchProvider, kn as ConvexCheckBuilder, kt as UpdateSet, ln as RlsRoleConfig, lr as eq, lt as GetColumnData, m as MigrationDocContext, mn as ConvexIndexBuilderOn, mr as inArray, mt as MutationExecuteConfig, n as OrmCapabilities, nn as deletion, nr as FilterExpression, nt as AggregateResult, on as RlsPolicyToOption, or as between, ot as CountResult, p as MigrationDoc, pn as ConvexIndexBuilder, pr as ilike, pt as InsertValue, qn as OrmSchemaExtensionTables, qt as ConvexDeletionBuilder, r as OrmCapability, rn as discriminator, rr as LogicalExpression, rt as BuildQueryResult, sn as rlsPolicy, sr as contains, st as DBQueryConfig, t as OrmAggregateCapability, tn as convexTable, tr as FieldReference, tt as AggregateFieldValue, u as MigrationAppliedState, un as rlsRole, ur as fieldRef, ut as InferInsertModel, v as MigrationPlan, vn as ConvexSearchIndexBuilderOn, vr as like, vt as MutationPaginatedResult, w as MigrationWriteMode, wn as index, wr as notInArray, wt as PaginatedResult, x as MigrationStateMap, xn as ConvexVectorIndexBuilderOn, xr as ne, xt as MutationRunMode, y as MigrationRunStatus, yn as ConvexSearchIndexConfig, yr as lt, yt as MutationResult, zn as ConvexTextBuilder, zr as IsPrimaryKey, zt as RelationsBuilderColumnBase } from "../capabilities-CLCYgRdY.js";
|
|
2
|
+
import { $ as OrmClientWithApi$1, A as ConvexDateMode, B as ConvexBytesBuilderInitial, C as ConvexNumberBuilderInitial, D as id, E as ConvexIdBuilderInitial, F as custom, G as ConvexBigIntBuilder, H as ConvexBooleanBuilder, I as json, J as CreateOrmOptions, K as ConvexBigIntBuilderInitial, L as objectOf, M as ConvexCustomBuilder, N as ConvexCustomBuilderInitial, O as ConvexDateBuilder, P as arrayOf, Q as OrmClientBase$1, R as unionOf, S as ConvexNumberBuilder, St as defineTriggers, T as ConvexIdBuilder, U as ConvexBooleanBuilderInitial, V as bytes, W as boolean, X as GenericOrmCtx$1, Y as GenericOrm$1, Z as OrmApiResult, _ as ConvexTimestampMode, _t as OrmBeforeResult, a as requireSchemaRelations, at as ScheduledMutationBatchArgs, b as ConvexTextEnumBuilderInitial, bt as OrmTriggerContext, c as TableConfigResult, ct as scheduledDeleteFactory, d as OrmNotFoundError, et as OrmFunctions, f as ConvexVectorBuilder, g as ConvexTimestampBuilderInitial, gt as defineSchemaExtension, h as ConvexTimestampBuilder, ht as SchemaExtension, i as getSchemaTriggers, it as createOrm, j as date, k as ConvexDateBuilderInitial, l as getTableColumns, m as vector, n as defineSchema, nt as OrmWriterCtx, o as asc, ot as scheduledMutationBatchFactory, p as ConvexVectorBuilderInitial, q as bigint, r as getSchemaRelations, rt as ResolveOrmSchema, s as desc, st as ScheduledDeleteArgs, t as WhereClauseResult, tt as OrmReaderCtx, u as getTableConfig, v as timestamp, vt as OrmTableTriggers, w as integer, x as textEnum, xt as OrmTriggers, y as ConvexTextEnumBuilder, yt as OrmTriggerChange, z as ConvexBytesBuilder } from "../where-clause-compiler-DAPEBp1y.js";
|
|
3
3
|
import { i as pretendRequired, n as deprecated, r as pretend } from "../validators-wOIjhkfN.js";
|
|
4
4
|
import { a as QueryCtxWithPreferredOrmQueryTable, i as QueryCtxWithOrmQueryTable, n as LookupByIdResultByCtx, o as getByIdWithOrmQueryFallback, r as QueryCtxWithOptionalOrmQueryTable, t as DocByCtx } from "../query-context-DJONf8X5.js";
|
|
5
5
|
import { DefineSchemaOptions, GenericDatabaseReader, GenericDatabaseWriter, GenericSchema, SchemaDefinition } from "convex/server";
|
package/dist/orm/index.js
CHANGED
|
@@ -1287,6 +1287,16 @@ const RELATION_COUNT_ERROR = {
|
|
|
1287
1287
|
NOT_INDEXED: "RELATION_COUNT_NOT_INDEXED",
|
|
1288
1288
|
FILTER_UNSUPPORTED: "RELATION_COUNT_FILTER_UNSUPPORTED"
|
|
1289
1289
|
};
|
|
1290
|
+
const RELATION_DEPTH_ERROR = "RELATION_DEPTH_EXCEEDED";
|
|
1291
|
+
/**
|
|
1292
|
+
* How many levels of `with` the relation loader will follow. A `with` config is
|
|
1293
|
+
* a finite object the caller wrote, so its own nesting is the real bound; this
|
|
1294
|
+
* ceiling only stops a self-referential config from recursing forever. Reaching
|
|
1295
|
+
* it throws rather than returning a shallower tree than was asked for, because
|
|
1296
|
+
* a page that quietly drops its deepest level is indistinguishable from a page
|
|
1297
|
+
* whose deepest level is genuinely empty.
|
|
1298
|
+
*/
|
|
1299
|
+
const MAX_RELATION_DEPTH = 10;
|
|
1290
1300
|
/**
|
|
1291
1301
|
* Physical-table-name lookup, keyed on schema identity. The schema is a
|
|
1292
1302
|
* module-level immutable, so the index outlives any single request.
|
|
@@ -2425,7 +2435,9 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
|
|
|
2425
2435
|
operation: "select",
|
|
2426
2436
|
rls: this.rls
|
|
2427
2437
|
});
|
|
2428
|
-
if (!withConfig
|
|
2438
|
+
if (!withConfig) return;
|
|
2439
|
+
const relationNames = Object.keys(withConfig).filter((relationName) => relationName !== "_count");
|
|
2440
|
+
if (relationNames.length > 0 && depth >= maxDepth) throw this._createRelationDepthError(tableConfig, relationNames[0], maxDepth);
|
|
2429
2441
|
for (const [relationName, relationConfig] of Object.entries(withConfig)) {
|
|
2430
2442
|
if (relationName === "_count") {
|
|
2431
2443
|
this._assertRelationCountRlsPlan(relationConfig, edges);
|
|
@@ -2481,9 +2493,9 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
|
|
|
2481
2493
|
const extrasConfig = this.config.extras;
|
|
2482
2494
|
const resolvedExtras = typeof extrasConfig === "function" ? extrasConfig(tableColumns) : extrasConfig;
|
|
2483
2495
|
if (polymorphicState) this._assertPolymorphicAliasCollisions(polymorphicState.configs, requestedWith, resolvedExtras);
|
|
2484
|
-
this._assertRlsSelectPlan(effectiveWith, this.tableConfig, this.edgeMetadata, 0,
|
|
2496
|
+
this._assertRlsSelectPlan(effectiveWith, this.tableConfig, this.edgeMetadata, 0, MAX_RELATION_DEPTH);
|
|
2485
2497
|
let rowsWithRelations = rows;
|
|
2486
|
-
if (effectiveWith) rowsWithRelations = await this._loadRelations(rowsWithRelations, effectiveWith, 0,
|
|
2498
|
+
if (effectiveWith) rowsWithRelations = await this._loadRelations(rowsWithRelations, effectiveWith, 0, MAX_RELATION_DEPTH, this.edgeMetadata, this.tableConfig);
|
|
2487
2499
|
if (polymorphicState) this._synthesizePolymorphicRows(rowsWithRelations, polymorphicState.configs);
|
|
2488
2500
|
if (resolvedExtras) rowsWithRelations = this._applyExtras(rowsWithRelations, resolvedExtras, tableColumns, effectiveWith, this.tableConfig.name, this.tableConfig);
|
|
2489
2501
|
return this._selectColumns(rowsWithRelations, this.config.columns, tableColumns, this.tableConfig);
|
|
@@ -2675,16 +2687,16 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
|
|
|
2675
2687
|
return streamQuery;
|
|
2676
2688
|
}
|
|
2677
2689
|
_buildUnionSourceStream(source, fallbackOrder) {
|
|
2678
|
-
const
|
|
2690
|
+
const sourceIndex = source.index ?? this.configuredIndex;
|
|
2679
2691
|
this._assertWhereIndexRequirement({
|
|
2680
2692
|
where: source.where,
|
|
2681
2693
|
tableConfig: this.tableConfig,
|
|
2682
|
-
hasConfiguredIndex: Boolean(
|
|
2694
|
+
hasConfiguredIndex: Boolean(sourceIndex?.name),
|
|
2683
2695
|
context: "pipeline.union source"
|
|
2684
2696
|
});
|
|
2685
2697
|
const schemaDefinition = this._getSchemaDefinitionOrThrow();
|
|
2686
2698
|
let sourceStream = stream(this.db, schemaDefinition).query(this.tableConfig.name);
|
|
2687
|
-
if (
|
|
2699
|
+
if (sourceIndex?.name) sourceStream = sourceStream.withIndex(sourceIndex.name, sourceIndex.range ? sourceIndex.range : (q) => q);
|
|
2688
2700
|
sourceStream = sourceStream.order(fallbackOrder);
|
|
2689
2701
|
const sourcePredicate = this._buildTableFilterPredicate(source.where, this.tableConfig);
|
|
2690
2702
|
if (sourcePredicate) sourceStream = sourceStream.filterWith(sourcePredicate);
|
|
@@ -3774,8 +3786,8 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
|
|
|
3774
3786
|
if (pipeline) throw new Error("pageByKey cannot be combined with pipeline.");
|
|
3775
3787
|
}
|
|
3776
3788
|
const preflightWith = this._resolveWithVariantsState(config.with, this._resolvePolymorphicFinalizeState()).effectiveWith;
|
|
3777
|
-
this._assertRlsSelectPlan(preflightWith, this.tableConfig, this.edgeMetadata, 0,
|
|
3778
|
-
if (whereFilter) this._assertRlsSelectPlan(this._buildFilterWithConfig(whereFilter, this.tableConfig), this.tableConfig, this.edgeMetadata, 0,
|
|
3789
|
+
this._assertRlsSelectPlan(preflightWith, this.tableConfig, this.edgeMetadata, 0, MAX_RELATION_DEPTH);
|
|
3790
|
+
if (whereFilter) this._assertRlsSelectPlan(this._buildFilterWithConfig(whereFilter, this.tableConfig), this.tableConfig, this.edgeMetadata, 0, MAX_RELATION_DEPTH);
|
|
3779
3791
|
const idLookup = this._extractIdOnlyWhere(whereFilter);
|
|
3780
3792
|
if (idLookup && !vectorSearchConfig && !searchConfig && !wherePredicate && !isCursorPaginated && !pipeline && !pageByKey && endCursor === void 0 && configuredIndex === void 0) {
|
|
3781
3793
|
const orderSpecs = this._orderBySpecs(config.orderBy);
|
|
@@ -3809,7 +3821,7 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
|
|
|
3809
3821
|
order: pageByKey.order
|
|
3810
3822
|
});
|
|
3811
3823
|
let rows = await this._applyRlsSelectFilter(page.page, this.tableConfig);
|
|
3812
|
-
if (whereFilter) rows = await this._applyRelationsFilterToRows(rows, this.tableConfig, whereFilter, this.edgeMetadata, 0,
|
|
3824
|
+
if (whereFilter) rows = await this._applyRelationsFilterToRows(rows, this.tableConfig, whereFilter, this.edgeMetadata, 0, MAX_RELATION_DEPTH, this.config.with);
|
|
3813
3825
|
return {
|
|
3814
3826
|
page: await this._finalizeRows(rows),
|
|
3815
3827
|
indexKeys: page.indexKeys,
|
|
@@ -3935,7 +3947,7 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
|
|
|
3935
3947
|
});
|
|
3936
3948
|
let pageRows = paginationResult.page;
|
|
3937
3949
|
pageRows = await this._applyRlsSelectFilter(pageRows, this.tableConfig);
|
|
3938
|
-
if (whereFilter) pageRows = await this._applyRelationsFilterToRows(pageRows, this.tableConfig, whereFilter, this.edgeMetadata, 0,
|
|
3950
|
+
if (whereFilter) pageRows = await this._applyRelationsFilterToRows(pageRows, this.tableConfig, whereFilter, this.edgeMetadata, 0, MAX_RELATION_DEPTH, this.config.with);
|
|
3939
3951
|
return {
|
|
3940
3952
|
page: await this._finalizeRows(pageRows),
|
|
3941
3953
|
continueCursor: paginationResult.continueCursor,
|
|
@@ -3948,7 +3960,7 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
|
|
|
3948
3960
|
let rows = limit === void 0 ? await searchQuery.collect() : await searchQuery.take(offset > 0 ? offset + limit : limit);
|
|
3949
3961
|
if (offset > 0) rows = rows.slice(offset);
|
|
3950
3962
|
rows = await this._applyRlsSelectFilter(rows, this.tableConfig);
|
|
3951
|
-
if (whereFilter) rows = await this._applyRelationsFilterToRows(rows, this.tableConfig, whereFilter, this.edgeMetadata, 0,
|
|
3963
|
+
if (whereFilter) rows = await this._applyRelationsFilterToRows(rows, this.tableConfig, whereFilter, this.edgeMetadata, 0, MAX_RELATION_DEPTH, this.config.with);
|
|
3952
3964
|
const selectedRows = await this._finalizeRows(rows);
|
|
3953
3965
|
return this._returnSelectedRows(selectedRows);
|
|
3954
3966
|
}
|
|
@@ -4028,7 +4040,7 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
|
|
|
4028
4040
|
});
|
|
4029
4041
|
let pageRows = paginationResult.page;
|
|
4030
4042
|
pageRows = await this._applyRlsSelectFilter(pageRows, this.tableConfig);
|
|
4031
|
-
if (whereFilter) pageRows = await this._applyRelationsFilterToRows(pageRows, this.tableConfig, whereFilter, this.edgeMetadata, 0,
|
|
4043
|
+
if (whereFilter) pageRows = await this._applyRelationsFilterToRows(pageRows, this.tableConfig, whereFilter, this.edgeMetadata, 0, MAX_RELATION_DEPTH, this.config.with);
|
|
4032
4044
|
return {
|
|
4033
4045
|
page: await this._finalizeRows(pageRows),
|
|
4034
4046
|
continueCursor: paginationResult.continueCursor,
|
|
@@ -4044,7 +4056,7 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
|
|
|
4044
4056
|
let rows = limit === void 0 || paginateAfterPostFetchSort ? await streamQuery.collect() : await streamQuery.take(offset > 0 ? offset + limit : limit);
|
|
4045
4057
|
if (!paginateAfterPostFetchSort && offset > 0) rows = rows.slice(offset);
|
|
4046
4058
|
rows = await this._applyRlsSelectFilter(rows, this.tableConfig);
|
|
4047
|
-
if (whereFilter) rows = await this._applyRelationsFilterToRows(rows, this.tableConfig, whereFilter, this.edgeMetadata, 0,
|
|
4059
|
+
if (whereFilter) rows = await this._applyRelationsFilterToRows(rows, this.tableConfig, whereFilter, this.edgeMetadata, 0, MAX_RELATION_DEPTH, this.config.with);
|
|
4048
4060
|
if (usePostFetchSort && postFetchOrders.length > 0) rows = rows.sort((a, b) => this._compareByOrderSpecs(a, b, postFetchOrders));
|
|
4049
4061
|
if (paginateAfterPostFetchSort) {
|
|
4050
4062
|
if (offset > 0) rows = rows.slice(offset);
|
|
@@ -4079,7 +4091,7 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
|
|
|
4079
4091
|
let rows = Array.from(new Map(probeRows.flat().map((row) => [String(row._id), row])).values());
|
|
4080
4092
|
if (queryConfig.postFilters.length > 0) rows = rows.filter((row) => queryConfig.postFilters.every((filter) => this._evaluatePostFetchFilter(row, filter)));
|
|
4081
4093
|
rows = await this._applyRlsSelectFilter(rows, this.tableConfig);
|
|
4082
|
-
if (whereFilter) rows = await this._applyRelationsFilterToRows(rows, this.tableConfig, whereFilter, this.edgeMetadata, 0,
|
|
4094
|
+
if (whereFilter) rows = await this._applyRelationsFilterToRows(rows, this.tableConfig, whereFilter, this.edgeMetadata, 0, MAX_RELATION_DEPTH, this.config.with);
|
|
4083
4095
|
if (postFetchOrders.length > 0) rows = rows.sort((a, b) => this._compareByOrderSpecs(a, b, postFetchOrders));
|
|
4084
4096
|
if (probeOffset > 0) rows = rows.slice(probeOffset);
|
|
4085
4097
|
if (probeLimit !== void 0) rows = rows.slice(0, probeLimit);
|
|
@@ -4090,7 +4102,7 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
|
|
|
4090
4102
|
const visibleRows = await this._applyRlsSelectFilter([row], this.tableConfig);
|
|
4091
4103
|
if (visibleRows.length === 0) return false;
|
|
4092
4104
|
if (!whereFilter) return true;
|
|
4093
|
-
return (await this._applyRelationsFilterToRows(visibleRows, this.tableConfig, whereFilter, this.edgeMetadata, 0,
|
|
4105
|
+
return (await this._applyRelationsFilterToRows(visibleRows, this.tableConfig, whereFilter, this.edgeMetadata, 0, MAX_RELATION_DEPTH, this.config.with)).length > 0;
|
|
4094
4106
|
};
|
|
4095
4107
|
if (isCursorPaginated) {
|
|
4096
4108
|
if (queryConfig.strategy === "multiProbe") if (maxScan === void 0) {
|
|
@@ -4116,7 +4128,7 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
|
|
|
4116
4128
|
});
|
|
4117
4129
|
let pageRows = paginationResult.page;
|
|
4118
4130
|
pageRows = await this._applyRlsSelectFilter(pageRows, this.tableConfig);
|
|
4119
|
-
if (whereFilter) pageRows = await this._applyRelationsFilterToRows(pageRows, this.tableConfig, whereFilter, this.edgeMetadata, 0,
|
|
4131
|
+
if (whereFilter) pageRows = await this._applyRelationsFilterToRows(pageRows, this.tableConfig, whereFilter, this.edgeMetadata, 0, MAX_RELATION_DEPTH, this.config.with);
|
|
4120
4132
|
return {
|
|
4121
4133
|
page: await this._finalizeRows(pageRows),
|
|
4122
4134
|
continueCursor: paginationResult.continueCursor,
|
|
@@ -4148,7 +4160,7 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
|
|
|
4148
4160
|
});
|
|
4149
4161
|
let pageRows = paginationResult.page;
|
|
4150
4162
|
pageRows = await this._applyRlsSelectFilter(pageRows, this.tableConfig);
|
|
4151
|
-
if (whereFilter) pageRows = await this._applyRelationsFilterToRows(pageRows, this.tableConfig, whereFilter, this.edgeMetadata, 0,
|
|
4163
|
+
if (whereFilter) pageRows = await this._applyRelationsFilterToRows(pageRows, this.tableConfig, whereFilter, this.edgeMetadata, 0, MAX_RELATION_DEPTH, this.config.with);
|
|
4152
4164
|
return {
|
|
4153
4165
|
page: await this._finalizeRows(pageRows),
|
|
4154
4166
|
continueCursor: paginationResult.continueCursor,
|
|
@@ -4203,7 +4215,7 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
|
|
|
4203
4215
|
});
|
|
4204
4216
|
let pageRows = paginationResult.page;
|
|
4205
4217
|
pageRows = await this._applyRlsSelectFilter(pageRows, this.tableConfig);
|
|
4206
|
-
if (whereFilter) pageRows = await this._applyRelationsFilterToRows(pageRows, this.tableConfig, whereFilter, this.edgeMetadata, 0,
|
|
4218
|
+
if (whereFilter) pageRows = await this._applyRelationsFilterToRows(pageRows, this.tableConfig, whereFilter, this.edgeMetadata, 0, MAX_RELATION_DEPTH, this.config.with);
|
|
4207
4219
|
return {
|
|
4208
4220
|
page: await this._finalizeRows(pageRows),
|
|
4209
4221
|
continueCursor: paginationResult.continueCursor,
|
|
@@ -4235,7 +4247,7 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
|
|
|
4235
4247
|
if (queryConfig.postFilters.length > 0) rows = rows.filter((row) => queryConfig.postFilters.every((filter) => this._evaluatePostFetchFilter(row, filter)));
|
|
4236
4248
|
if (!residualLimitStream) {
|
|
4237
4249
|
rows = await this._applyRlsSelectFilter(rows, this.tableConfig);
|
|
4238
|
-
if (whereFilter) rows = await this._applyRelationsFilterToRows(rows, this.tableConfig, whereFilter, this.edgeMetadata, 0,
|
|
4250
|
+
if (whereFilter) rows = await this._applyRelationsFilterToRows(rows, this.tableConfig, whereFilter, this.edgeMetadata, 0, MAX_RELATION_DEPTH, this.config.with);
|
|
4239
4251
|
}
|
|
4240
4252
|
if (sizeAfterPostFilter) {
|
|
4241
4253
|
if (offset > 0) rows = rows.slice(offset);
|
|
@@ -4420,14 +4432,14 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
|
|
|
4420
4432
|
* @param rows - Array of parent records to load relations for
|
|
4421
4433
|
* @param withConfig - Relation configuration object
|
|
4422
4434
|
* @param depth - Current recursion depth (default 0)
|
|
4423
|
-
* @param maxDepth -
|
|
4435
|
+
* @param maxDepth - Runaway ceiling for self-referential configs (default `MAX_RELATION_DEPTH`)
|
|
4424
4436
|
* @param targetTableEdges - Edge metadata for nested relations (optional, defaults to this.edgeMetadata)
|
|
4425
4437
|
*/
|
|
4426
|
-
async _loadRelations(rows, withConfig, depth = 0, maxDepth =
|
|
4438
|
+
async _loadRelations(rows, withConfig, depth = 0, maxDepth = MAX_RELATION_DEPTH, targetTableEdges = this.edgeMetadata, tableConfig = this.tableConfig) {
|
|
4427
4439
|
if (!withConfig || rows.length === 0) return rows;
|
|
4428
|
-
if (depth >= maxDepth) return rows;
|
|
4429
4440
|
const relationCountConfig = withConfig._count;
|
|
4430
4441
|
const relationEntries = Object.entries(withConfig).filter(([relationName]) => relationName !== "_count");
|
|
4442
|
+
if (relationEntries.length > 0 && depth >= maxDepth) throw this._createRelationDepthError(tableConfig, relationEntries[0][0], maxDepth);
|
|
4431
4443
|
await Promise.all(relationEntries.map(([relationName, relationConfig]) => this._loadSingleRelation(rows, relationName, relationConfig, depth, maxDepth, targetTableEdges, tableConfig)));
|
|
4432
4444
|
if (relationCountConfig !== void 0) await this._loadRelationCounts(rows, relationCountConfig, targetTableEdges, tableConfig);
|
|
4433
4445
|
return rows;
|
|
@@ -4446,6 +4458,9 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
|
|
|
4446
4458
|
_createRelationCountError(code, message) {
|
|
4447
4459
|
return /* @__PURE__ */ new Error(`${code}: ${message}`);
|
|
4448
4460
|
}
|
|
4461
|
+
_createRelationDepthError(tableConfig, relationName, maxDepth) {
|
|
4462
|
+
return /* @__PURE__ */ new Error(`${RELATION_DEPTH_ERROR}: '${tableConfig.name}.${relationName}' nests \`with\` more than ${maxDepth} levels deep. Trim the nesting, or check whether the config object references itself.`);
|
|
4463
|
+
}
|
|
4449
4464
|
_remapRelationCountError(error, relationPath) {
|
|
4450
4465
|
const message = error instanceof Error ? error.message : String(error);
|
|
4451
4466
|
if (message.startsWith(`${COUNT_ERROR.NOT_INDEXED}:`)) return this._createRelationCountError(RELATION_COUNT_ERROR.NOT_INDEXED, `${relationPath} ${message.slice(`${COUNT_ERROR.NOT_INDEXED}: `.length)}`);
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as MigrationTableName, D as defineMigrationSet, E as defineMigration, O as detectMigrationDrift, S as MigrationStep, T as buildMigrationPlan, _ as MigrationMigrateOne, a as MigrationCancelArgs, b as MigrationSet, c as MigrationStatusArgs, d as MigrationDefinition, f as MigrationDirection, g as MigrationManifestEntry, h as MigrationDriftIssue, l as createMigrationHandlers, m as MigrationDocContext, o as MigrationRunArgs, p as MigrationDoc, s as MigrationRunChunkArgs, u as MigrationAppliedState, v as MigrationPlan, w as MigrationWriteMode, x as MigrationStateMap, y as MigrationRunStatus } from "../../capabilities-
|
|
2
|
-
import { Ct as migrationCapability, dt as MIGRATION_STORAGE_TABLE_NAMES, ft as injectMigrationStorageTables, lt as MIGRATION_RUN_TABLE, mt as migrationStorageTables, pt as migrationExtension, ut as MIGRATION_STATE_TABLE } from "../../where-clause-compiler-
|
|
1
|
+
import { C as MigrationTableName, D as defineMigrationSet, E as defineMigration, O as detectMigrationDrift, S as MigrationStep, T as buildMigrationPlan, _ as MigrationMigrateOne, a as MigrationCancelArgs, b as MigrationSet, c as MigrationStatusArgs, d as MigrationDefinition, f as MigrationDirection, g as MigrationManifestEntry, h as MigrationDriftIssue, l as createMigrationHandlers, m as MigrationDocContext, o as MigrationRunArgs, p as MigrationDoc, s as MigrationRunChunkArgs, u as MigrationAppliedState, v as MigrationPlan, w as MigrationWriteMode, x as MigrationStateMap, y as MigrationRunStatus } from "../../capabilities-CLCYgRdY.js";
|
|
2
|
+
import { Ct as migrationCapability, dt as MIGRATION_STORAGE_TABLE_NAMES, ft as injectMigrationStorageTables, lt as MIGRATION_RUN_TABLE, mt as migrationStorageTables, pt as migrationExtension, ut as MIGRATION_STATE_TABLE } from "../../where-clause-compiler-DAPEBp1y.js";
|
|
3
3
|
export { MIGRATION_RUN_TABLE, MIGRATION_STATE_TABLE, MIGRATION_STORAGE_TABLE_NAMES, type MigrationAppliedState, type MigrationCancelArgs, type MigrationDefinition, type MigrationDirection, type MigrationDoc, type MigrationDocContext, type MigrationDriftIssue, type MigrationManifestEntry, type MigrationMigrateOne, type MigrationPlan, type MigrationRunArgs, type MigrationRunChunkArgs, type MigrationRunStatus, type MigrationSet, type MigrationStateMap, type MigrationStatusArgs, type MigrationStep, type MigrationTableName, type MigrationWriteMode, buildMigrationPlan, createMigrationHandlers, defineMigration, defineMigrationSet, detectMigrationDrift, injectMigrationStorageTables, migrationCapability, migrationExtension, migrationStorageTables };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Bn as ConvexTextBuilderInitial, Dr as SystemFieldAliases, F as DeleteMode, Gn as OrmRuntimeDefaults, H as EdgeMetadata, Hn as ConvexColumnBuilder, Hr as entityKind, Ht as RelationsConfigWithSchema, I as SerializedFilterExpression, Jn as OrmSchemaExtensionTriggers, Kn as OrmSchemaExtensionRelations, L as getChecks, M as OrmReader, Mr as ColumnBuilderBaseConfig, N as OrmWriter, Nt as AnyRelationsBuilderConfig, Or as SystemFields, P as CascadeMode, Pt as ExtractTablesFromSchema, Qt as OrmLifecycleChange, R as getForeignKeys, Rr as HasDefault, Rt as RelationsBuilder, St as OrderByClause, Ut as TableRelationalConfig, Vt as RelationsBuilderConfigValue, Wn as Columns, Wt as TablesRelationalConfig, Xn as OrmSchemaRelations, Xt as ConvexTableWithColumns, Yt as ConvexTable, Zn as OrmSchemaTriggers, b as MigrationSet, ft as InferSelectModel, in as RlsPolicy, jr as ColumnBuilder, jt as VectorSearchProvider, k as CreateDatabaseOptions, kr as $Type, nr as FilterExpression$1, r as OrmCapability, ut as InferInsertModel, z as getUniqueIndexes } from "./capabilities-
|
|
1
|
+
import { Bn as ConvexTextBuilderInitial, Dr as SystemFieldAliases, F as DeleteMode, Gn as OrmRuntimeDefaults, H as EdgeMetadata, Hn as ConvexColumnBuilder, Hr as entityKind, Ht as RelationsConfigWithSchema, I as SerializedFilterExpression, Jn as OrmSchemaExtensionTriggers, Kn as OrmSchemaExtensionRelations, L as getChecks, M as OrmReader, Mr as ColumnBuilderBaseConfig, N as OrmWriter, Nt as AnyRelationsBuilderConfig, Or as SystemFields, P as CascadeMode, Pt as ExtractTablesFromSchema, Qt as OrmLifecycleChange, R as getForeignKeys, Rr as HasDefault, Rt as RelationsBuilder, St as OrderByClause, Ut as TableRelationalConfig, Vt as RelationsBuilderConfigValue, Wn as Columns, Wt as TablesRelationalConfig, Xn as OrmSchemaRelations, Xt as ConvexTableWithColumns, Yt as ConvexTable, Zn as OrmSchemaTriggers, b as MigrationSet, ft as InferSelectModel, in as RlsPolicy, jr as ColumnBuilder, jt as VectorSearchProvider, k as CreateDatabaseOptions, kr as $Type, nr as FilterExpression$1, r as OrmCapability, ut as InferInsertModel, z as getUniqueIndexes } from "./capabilities-CLCYgRdY.js";
|
|
2
2
|
import * as convex_values0 from "convex/values";
|
|
3
3
|
import { GenericId, Validator, Value } from "convex/values";
|
|
4
4
|
import { DefineSchemaOptions, GenericDatabaseReader, GenericDatabaseWriter, GenericSchema, SchedulableFunctionReference, Scheduler, SchemaDefinition, internalActionGeneric, internalMutationGeneric } from "convex/server";
|
|
@@ -102,25 +102,20 @@ declare const migrationStorageTables: {
|
|
|
102
102
|
fieldName: "status";
|
|
103
103
|
};
|
|
104
104
|
};
|
|
105
|
-
|
|
105
|
+
migrationId: ConvexTextBuilderInitial<""> & {
|
|
106
106
|
_: {
|
|
107
|
-
|
|
107
|
+
notNull: true;
|
|
108
108
|
};
|
|
109
109
|
} & {
|
|
110
|
-
_: {
|
|
111
|
-
fieldName: "cursor";
|
|
112
|
-
};
|
|
113
|
-
};
|
|
114
|
-
direction: ConvexTextBuilderInitial<""> & {
|
|
115
110
|
_: {
|
|
116
111
|
tableName: "migration_state";
|
|
117
112
|
};
|
|
118
113
|
} & {
|
|
119
114
|
_: {
|
|
120
|
-
fieldName: "
|
|
115
|
+
fieldName: "migrationId";
|
|
121
116
|
};
|
|
122
117
|
};
|
|
123
|
-
|
|
118
|
+
checksum: ConvexTextBuilderInitial<""> & {
|
|
124
119
|
_: {
|
|
125
120
|
notNull: true;
|
|
126
121
|
};
|
|
@@ -130,10 +125,10 @@ declare const migrationStorageTables: {
|
|
|
130
125
|
};
|
|
131
126
|
} & {
|
|
132
127
|
_: {
|
|
133
|
-
fieldName: "
|
|
128
|
+
fieldName: "checksum";
|
|
134
129
|
};
|
|
135
130
|
};
|
|
136
|
-
|
|
131
|
+
applied: ConvexBooleanBuilderInitial<""> & {
|
|
137
132
|
_: {
|
|
138
133
|
notNull: true;
|
|
139
134
|
};
|
|
@@ -143,29 +138,34 @@ declare const migrationStorageTables: {
|
|
|
143
138
|
};
|
|
144
139
|
} & {
|
|
145
140
|
_: {
|
|
146
|
-
fieldName: "
|
|
141
|
+
fieldName: "applied";
|
|
147
142
|
};
|
|
148
143
|
};
|
|
149
|
-
|
|
144
|
+
direction: ConvexTextBuilderInitial<""> & {
|
|
150
145
|
_: {
|
|
151
|
-
|
|
146
|
+
tableName: "migration_state";
|
|
152
147
|
};
|
|
153
148
|
} & {
|
|
149
|
+
_: {
|
|
150
|
+
fieldName: "direction";
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
runId: ConvexTextBuilderInitial<""> & {
|
|
154
154
|
_: {
|
|
155
155
|
tableName: "migration_state";
|
|
156
156
|
};
|
|
157
157
|
} & {
|
|
158
158
|
_: {
|
|
159
|
-
fieldName: "
|
|
159
|
+
fieldName: "runId";
|
|
160
160
|
};
|
|
161
161
|
};
|
|
162
|
-
|
|
162
|
+
cursor: ConvexTextBuilderInitial<""> & {
|
|
163
163
|
_: {
|
|
164
164
|
tableName: "migration_state";
|
|
165
165
|
};
|
|
166
166
|
} & {
|
|
167
167
|
_: {
|
|
168
|
-
fieldName: "
|
|
168
|
+
fieldName: "cursor";
|
|
169
169
|
};
|
|
170
170
|
};
|
|
171
171
|
processed: ConvexNumberBuilderInitial<""> & {
|
|
@@ -1133,7 +1133,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1133
1133
|
readonly aggregate_member: ConvexTableWithColumns<{
|
|
1134
1134
|
name: "aggregate_member";
|
|
1135
1135
|
columns: {
|
|
1136
|
-
|
|
1136
|
+
updatedAt: ConvexNumberBuilderInitial<""> & {
|
|
1137
1137
|
_: {
|
|
1138
1138
|
notNull: true;
|
|
1139
1139
|
};
|
|
@@ -1143,10 +1143,10 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1143
1143
|
};
|
|
1144
1144
|
} & {
|
|
1145
1145
|
_: {
|
|
1146
|
-
fieldName: "
|
|
1146
|
+
fieldName: "updatedAt";
|
|
1147
1147
|
};
|
|
1148
1148
|
};
|
|
1149
|
-
|
|
1149
|
+
kind: ConvexTextBuilderInitial<""> & {
|
|
1150
1150
|
_: {
|
|
1151
1151
|
notNull: true;
|
|
1152
1152
|
};
|
|
@@ -1156,7 +1156,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1156
1156
|
};
|
|
1157
1157
|
} & {
|
|
1158
1158
|
_: {
|
|
1159
|
-
fieldName: "
|
|
1159
|
+
fieldName: "kind";
|
|
1160
1160
|
};
|
|
1161
1161
|
};
|
|
1162
1162
|
indexName: ConvexTextBuilderInitial<""> & {
|
|
@@ -1323,11 +1323,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1323
1323
|
readonly aggregate_extrema: ConvexTableWithColumns<{
|
|
1324
1324
|
name: "aggregate_extrema";
|
|
1325
1325
|
columns: {
|
|
1326
|
-
|
|
1327
|
-
_: {
|
|
1328
|
-
$type: convex_values0.Value;
|
|
1329
|
-
};
|
|
1330
|
-
} & {
|
|
1326
|
+
updatedAt: ConvexNumberBuilderInitial<""> & {
|
|
1331
1327
|
_: {
|
|
1332
1328
|
notNull: true;
|
|
1333
1329
|
};
|
|
@@ -1337,10 +1333,14 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1337
1333
|
};
|
|
1338
1334
|
} & {
|
|
1339
1335
|
_: {
|
|
1340
|
-
fieldName: "
|
|
1336
|
+
fieldName: "updatedAt";
|
|
1341
1337
|
};
|
|
1342
1338
|
};
|
|
1343
|
-
|
|
1339
|
+
value: ConvexCustomBuilderInitial<"", convex_values0.VAny<any, "required", string>> & {
|
|
1340
|
+
_: {
|
|
1341
|
+
$type: convex_values0.Value;
|
|
1342
|
+
};
|
|
1343
|
+
} & {
|
|
1344
1344
|
_: {
|
|
1345
1345
|
notNull: true;
|
|
1346
1346
|
};
|
|
@@ -1350,7 +1350,7 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1350
1350
|
};
|
|
1351
1351
|
} & {
|
|
1352
1352
|
_: {
|
|
1353
|
-
fieldName: "
|
|
1353
|
+
fieldName: "value";
|
|
1354
1354
|
};
|
|
1355
1355
|
};
|
|
1356
1356
|
count: ConvexNumberBuilderInitial<""> & {
|
|
@@ -1589,19 +1589,6 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1589
1589
|
fieldName: "status";
|
|
1590
1590
|
};
|
|
1591
1591
|
};
|
|
1592
|
-
kind: ConvexTextBuilderInitial<""> & {
|
|
1593
|
-
_: {
|
|
1594
|
-
notNull: true;
|
|
1595
|
-
};
|
|
1596
|
-
} & {
|
|
1597
|
-
_: {
|
|
1598
|
-
tableName: "aggregate_state";
|
|
1599
|
-
};
|
|
1600
|
-
} & {
|
|
1601
|
-
_: {
|
|
1602
|
-
fieldName: "kind";
|
|
1603
|
-
};
|
|
1604
|
-
};
|
|
1605
1592
|
cursor: ConvexTextBuilderInitial<""> & {
|
|
1606
1593
|
_: {
|
|
1607
1594
|
tableName: "aggregate_state";
|
|
@@ -1668,6 +1655,19 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1668
1655
|
fieldName: "lastError";
|
|
1669
1656
|
};
|
|
1670
1657
|
};
|
|
1658
|
+
kind: ConvexTextBuilderInitial<""> & {
|
|
1659
|
+
_: {
|
|
1660
|
+
notNull: true;
|
|
1661
|
+
};
|
|
1662
|
+
} & {
|
|
1663
|
+
_: {
|
|
1664
|
+
tableName: "aggregate_state";
|
|
1665
|
+
};
|
|
1666
|
+
} & {
|
|
1667
|
+
_: {
|
|
1668
|
+
fieldName: "kind";
|
|
1669
|
+
};
|
|
1670
|
+
};
|
|
1671
1671
|
indexName: ConvexTextBuilderInitial<""> & {
|
|
1672
1672
|
_: {
|
|
1673
1673
|
notNull: true;
|
|
@@ -1744,25 +1744,20 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1744
1744
|
fieldName: "status";
|
|
1745
1745
|
};
|
|
1746
1746
|
};
|
|
1747
|
-
|
|
1747
|
+
migrationId: ConvexTextBuilderInitial<""> & {
|
|
1748
1748
|
_: {
|
|
1749
|
-
|
|
1749
|
+
notNull: true;
|
|
1750
1750
|
};
|
|
1751
1751
|
} & {
|
|
1752
|
-
_: {
|
|
1753
|
-
fieldName: "cursor";
|
|
1754
|
-
};
|
|
1755
|
-
};
|
|
1756
|
-
direction: ConvexTextBuilderInitial<""> & {
|
|
1757
1752
|
_: {
|
|
1758
1753
|
tableName: "migration_state";
|
|
1759
1754
|
};
|
|
1760
1755
|
} & {
|
|
1761
1756
|
_: {
|
|
1762
|
-
fieldName: "
|
|
1757
|
+
fieldName: "migrationId";
|
|
1763
1758
|
};
|
|
1764
1759
|
};
|
|
1765
|
-
|
|
1760
|
+
checksum: ConvexTextBuilderInitial<""> & {
|
|
1766
1761
|
_: {
|
|
1767
1762
|
notNull: true;
|
|
1768
1763
|
};
|
|
@@ -1772,10 +1767,10 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1772
1767
|
};
|
|
1773
1768
|
} & {
|
|
1774
1769
|
_: {
|
|
1775
|
-
fieldName: "
|
|
1770
|
+
fieldName: "checksum";
|
|
1776
1771
|
};
|
|
1777
1772
|
};
|
|
1778
|
-
|
|
1773
|
+
applied: ConvexBooleanBuilderInitial<""> & {
|
|
1779
1774
|
_: {
|
|
1780
1775
|
notNull: true;
|
|
1781
1776
|
};
|
|
@@ -1785,29 +1780,34 @@ declare const BUILTIN_SCHEMA_EXTENSIONS: readonly [SchemaExtension<{
|
|
|
1785
1780
|
};
|
|
1786
1781
|
} & {
|
|
1787
1782
|
_: {
|
|
1788
|
-
fieldName: "
|
|
1783
|
+
fieldName: "applied";
|
|
1789
1784
|
};
|
|
1790
1785
|
};
|
|
1791
|
-
|
|
1786
|
+
direction: ConvexTextBuilderInitial<""> & {
|
|
1792
1787
|
_: {
|
|
1793
|
-
|
|
1788
|
+
tableName: "migration_state";
|
|
1794
1789
|
};
|
|
1795
1790
|
} & {
|
|
1791
|
+
_: {
|
|
1792
|
+
fieldName: "direction";
|
|
1793
|
+
};
|
|
1794
|
+
};
|
|
1795
|
+
runId: ConvexTextBuilderInitial<""> & {
|
|
1796
1796
|
_: {
|
|
1797
1797
|
tableName: "migration_state";
|
|
1798
1798
|
};
|
|
1799
1799
|
} & {
|
|
1800
1800
|
_: {
|
|
1801
|
-
fieldName: "
|
|
1801
|
+
fieldName: "runId";
|
|
1802
1802
|
};
|
|
1803
1803
|
};
|
|
1804
|
-
|
|
1804
|
+
cursor: ConvexTextBuilderInitial<""> & {
|
|
1805
1805
|
_: {
|
|
1806
1806
|
tableName: "migration_state";
|
|
1807
1807
|
};
|
|
1808
1808
|
} & {
|
|
1809
1809
|
_: {
|
|
1810
|
-
fieldName: "
|
|
1810
|
+
fieldName: "cursor";
|
|
1811
1811
|
};
|
|
1812
1812
|
};
|
|
1813
1813
|
processed: ConvexNumberBuilderInitial<""> & {
|
package/package.json
CHANGED
|
@@ -211,6 +211,38 @@ const users = await ctx.orm.query.users.findMany({
|
|
|
211
211
|
|
|
212
212
|
Works on `findMany`, `findFirst`, `findFirstOrThrow`. Access via `row._count?.relation ?? 0`.
|
|
213
213
|
|
|
214
|
+
`_count` reads an aggregate index rather than the rows, so it resolves at every level of a nested `with:`, including the deepest level returned. Ask for it there instead of re-reading the returned tree to attach counts — that second pass costs one read per node the caller already holds:
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
// ❌ BAD: second pass over nodes already in hand
|
|
218
|
+
const roots = await ctx.orm.query.comments.findMany({
|
|
219
|
+
where: { parentId: { isNull: true } },
|
|
220
|
+
limit: 20,
|
|
221
|
+
with: { replies: { limit: 10 } },
|
|
222
|
+
});
|
|
223
|
+
const ids = collectIds(roots);
|
|
224
|
+
const counts = await ctx.orm.query.comments.findMany({
|
|
225
|
+
where: { id: { in: ids } },
|
|
226
|
+
limit: ids.length,
|
|
227
|
+
columns: { id: true },
|
|
228
|
+
with: { _count: { replies: true } },
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
// ✅ GOOD: counted inline, at every level
|
|
232
|
+
const roots = await ctx.orm.query.comments.findMany({
|
|
233
|
+
where: { parentId: { isNull: true } },
|
|
234
|
+
limit: 20,
|
|
235
|
+
with: {
|
|
236
|
+
_count: { replies: true },
|
|
237
|
+
replies: {
|
|
238
|
+
limit: 10,
|
|
239
|
+
with: { _count: { replies: true } },
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
// roots[0].replies[0]._count?.replies => replies not in this page
|
|
244
|
+
```
|
|
245
|
+
|
|
214
246
|
### Mutation `returning({ _count })`
|
|
215
247
|
|
|
216
248
|
```ts
|
|
@@ -261,6 +261,14 @@ orders by creation time, so `with: { posts: { limit: 5, orderBy: { createdAt:
|
|
|
261
261
|
parent's whole child partition and sorts in memory — put the sort column in the
|
|
262
262
|
relation index (`index('by_user_rank').on(t.userId, t.rank)`) to stay bounded.
|
|
263
263
|
|
|
264
|
+
### Nested `with` depth
|
|
265
|
+
|
|
266
|
+
Nested `with:` loads every level it is given, up to 10. A tree that still has
|
|
267
|
+
rows to expand past that throws `RELATION_DEPTH_EXCEEDED` rather than coming back
|
|
268
|
+
shorter than requested — which is how a `with` object that references itself
|
|
269
|
+
surfaces. Fan-out per level is bounded by that level's `limit`, not by the depth
|
|
270
|
+
ceiling.
|
|
271
|
+
|
|
264
272
|
## Schema Definition
|
|
265
273
|
|
|
266
274
|
```ts
|
|
@@ -543,45 +551,47 @@ return await ctx.orm.query.articles.findMany({
|
|
|
543
551
|
|
|
544
552
|
```ts
|
|
545
553
|
return await ctx.orm.query.messages
|
|
546
|
-
.withIndex("by_from_to")
|
|
547
|
-
.select()
|
|
548
|
-
.union([
|
|
549
|
-
{ where: { from: input.me, to: input.them } },
|
|
550
|
-
{ where: { from: input.them, to: input.me } },
|
|
551
|
-
])
|
|
552
|
-
.interleaveBy(["createdAt", "id"])
|
|
553
|
-
.filter(async (m) => !m.deletedAt)
|
|
554
|
-
.map(async (m) => ({ ...m, body: m.body.slice(0, 240) }))
|
|
555
|
-
.paginate({
|
|
556
|
-
cursor: input.cursor,
|
|
557
|
-
limit: input.limit,
|
|
558
|
-
maxScan: 500,
|
|
559
|
-
});
|
|
560
|
-
```
|
|
561
|
-
|
|
562
|
-
### Union with index ranges
|
|
563
|
-
|
|
564
|
-
```ts
|
|
565
|
-
const page = await ctx.orm.query.messages
|
|
566
554
|
.select()
|
|
567
555
|
.union([
|
|
568
556
|
{
|
|
569
557
|
index: {
|
|
570
558
|
name: "by_from_to",
|
|
571
|
-
range: (q) => q.eq("from", me).eq("to", them),
|
|
559
|
+
range: (q) => q.eq("from", input.me).eq("to", input.them),
|
|
572
560
|
},
|
|
573
561
|
},
|
|
574
562
|
{
|
|
575
563
|
index: {
|
|
576
564
|
name: "by_from_to",
|
|
577
|
-
range: (q) => q.eq("from", them).eq("to", me),
|
|
565
|
+
range: (q) => q.eq("from", input.them).eq("to", input.me),
|
|
578
566
|
},
|
|
579
567
|
},
|
|
580
568
|
])
|
|
581
569
|
.interleaveBy(["createdAt", "id"])
|
|
582
|
-
.
|
|
570
|
+
.filter(async (m) => !m.deletedAt)
|
|
571
|
+
.map(async (m) => ({ ...m, body: m.body.slice(0, 240) }))
|
|
572
|
+
.paginate({
|
|
573
|
+
cursor: input.cursor,
|
|
574
|
+
limit: input.limit,
|
|
575
|
+
maxScan: 500,
|
|
576
|
+
});
|
|
583
577
|
```
|
|
584
578
|
|
|
579
|
+
Per source:
|
|
580
|
+
|
|
581
|
+
- `index: { name, range }` anchors that source on its own range. It overrides
|
|
582
|
+
the chain-level `.withIndex(...)`; sources that omit it use the chain index.
|
|
583
|
+
- `where` filters that source's rows after the read.
|
|
584
|
+
|
|
585
|
+
`interleaveBy` fields must be the trailing fields each source is already ordered
|
|
586
|
+
by, so every field before them has to be pinned with `eq` in that source's
|
|
587
|
+
range. Sources may name different indexes when they land on the same trailing
|
|
588
|
+
fields — e.g. `by_author_likes` (authorId, numLikes) with `eq("authorId", ...)`
|
|
589
|
+
merges with `numLikesAndType` (type, numLikes) with `eq("type", ...)` under
|
|
590
|
+
`interleaveBy(["numLikes"])`.
|
|
591
|
+
|
|
592
|
+
Anchor every source. A shared `.withIndex(...)` plus per-source `where` makes
|
|
593
|
+
each source walk the same range and discard the misses after reading them.
|
|
594
|
+
|
|
585
595
|
### Pre-pagination transforms
|
|
586
596
|
|
|
587
597
|
```ts
|