kitcn 0.30.0 → 0.31.1

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.
Files changed (71) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/dist/aggregate/index.d.ts +11 -6
  3. package/dist/aggregate/index.js +2 -1
  4. package/dist/auth/generated/index.d.ts +1 -1
  5. package/dist/auth/generated/index.js +1 -1
  6. package/dist/auth/http/index.d.ts +1 -1
  7. package/dist/auth/index.d.ts +15 -15
  8. package/dist/auth/index.js +133 -9
  9. package/dist/auth/nextjs/index.d.ts +2 -2
  10. package/dist/auth/nextjs/index.js +3 -3
  11. package/dist/auth/start/server/index.d.ts +2 -2
  12. package/dist/auth/start/server/index.js +3 -3
  13. package/dist/{builder-CsAw-DK8.js → builder-Cyd5nCxZ.js} +2 -2
  14. package/dist/{caller-factory-D4pz5GcZ.js → caller-factory-C-N540BC.js} +3 -3
  15. package/dist/{capabilities-6PZBmvc8.d.ts → capabilities-CG-oIMyR.d.ts} +25 -11
  16. package/dist/cli.mjs +1 -1
  17. package/dist/{create-schema-orm-HcJzGCxj.js → create-schema-orm-CwJD930B.js} +1 -1
  18. package/dist/crpc/index.d.ts +2 -2
  19. package/dist/crpc/index.js +3 -3
  20. package/dist/{customFunctions-ivbc6-_g.js → customFunctions-X_B4kET8.js} +64 -1
  21. package/dist/{definitions-DS8ZDc74.js → definitions-3PX4ywR-.js} +2 -2
  22. package/dist/{extensions-Blzsyekm.js → extensions-Bp0XHanR.js} +1 -1
  23. package/dist/{generated-contract-disabled-CgYQZCw2.d.ts → generated-contract-disabled-BKvk4lFx.d.ts} +41 -12
  24. package/dist/{generated-contract-disabled-_1Mjg9pW.js → generated-contract-disabled-RyPYlwq0.js} +1 -0
  25. package/dist/{http-types-90mapMP9.d.ts → http-types-BhhPZtwa.d.ts} +2 -2
  26. package/dist/{filter-expression-Dydt8wS0.js → index-utils-C1DyktHe.js} +95 -1
  27. package/dist/{local-env-Dk8RJvt5.mjs → local-env-CYYSNf_o.mjs} +92 -72
  28. package/dist/{middleware-CE_MC6Gi.d.ts → middleware-BBS7oLtT.d.ts} +1 -1
  29. package/dist/{middleware-BvnabcNq.js → middleware-D61Nm-iB.js} +1 -1
  30. package/dist/orm/aggregate-index/index.d.ts +1 -1
  31. package/dist/orm/aggregate-index/index.js +32 -34
  32. package/dist/orm/index.d.ts +4 -4
  33. package/dist/orm/index.js +8 -7
  34. package/dist/orm/migrations/index.d.ts +2 -2
  35. package/dist/orm/migrations/index.js +1 -1
  36. package/dist/plugins/index.d.ts +1 -1
  37. package/dist/plugins/index.js +1 -1
  38. package/dist/{procedure-caller-BR-Wb0si.js → procedure-caller-DgMiD0-a.js} +2 -2
  39. package/dist/{procedure-name-l2YusEZI.d.ts → procedure-name-DPYyLiVS.d.ts} +3 -3
  40. package/dist/ratelimit/index.d.ts +2 -2
  41. package/dist/ratelimit/index.js +3 -3
  42. package/dist/rsc/index.d.ts +4 -4
  43. package/dist/rsc/index.js +4 -4
  44. package/dist/{runtime-CcOvOf4K.js → runtime-B-8HKSIE.js} +21 -40
  45. package/dist/schema-BFP_awgP.js +67 -0
  46. package/dist/{schema-D8ZZMSKd.js → schema-DbPcDW-N.js} +10 -117
  47. package/dist/server/index.d.ts +4 -4
  48. package/dist/server/index.js +4 -4
  49. package/dist/symbols-DDNAddkd.js +21 -0
  50. package/dist/{table-CX2lnX7e.js → table-d9o_n4R3.js} +2 -21
  51. package/dist/{token-B0NKKxqP.js → token-CuJopBdP.js} +1 -1
  52. package/dist/{types-In-ZZOsd.d.ts → types-BXpu7xIU.d.ts} +1 -1
  53. package/dist/watcher.mjs +1 -1
  54. package/dist/{where-clause-compiler-DvYSTJXe.d.ts → where-clause-compiler-Bgkzm3Y-.d.ts} +85 -81
  55. package/package.json +1 -1
  56. package/dist/id-CuSfWa5q.js +0 -37
  57. /package/dist/{api-entry-CkDpGYVg.js → api-entry-Buvjl9hn.js} +0 -0
  58. /package/dist/{context-utils-DwZ3Cam1.d.ts → context-utils-Cbv4r0AA.d.ts} +0 -0
  59. /package/dist/{convex-plugin-Dic0l-k8.js → convex-plugin-AbNQl1Sg.js} +0 -0
  60. /package/dist/{create-schema-ojI-OH_9.js → create-schema-BmVH4gPc.js} +0 -0
  61. /package/dist/{error-CMLeCadS.js → error-Dyqhgbf6.js} +0 -0
  62. /package/dist/{meta-utils-D2lqN2Lg.js → meta-utils-Cc7neQOB.js} +0 -0
  63. /package/dist/{query-context-DJONf8X5.d.ts → query-context-BkNjkDCk.d.ts} +0 -0
  64. /package/dist/{query-context-DOm5Xm3H.js → query-context-DdSg3fuk.js} +0 -0
  65. /package/dist/{query-options-DUiOj01a.js → query-options-DGG93--5.js} +0 -0
  66. /package/dist/{token-kQaqFby4.d.ts → token-tlbNKQS0.d.ts} +0 -0
  67. /package/dist/{transformer-D8wO-kEj.js → transformer-C8lVwHNT.js} +0 -0
  68. /package/dist/{types-eNzQmbqM.d.ts → types-Bkeicpo6.d.ts} +0 -0
  69. /package/dist/{types-MHYXboyy.d.ts → types-Bqi_ivSd.d.ts} +0 -0
  70. /package/dist/{types-Bf3XQex5.d.ts → types-ex0-J-SC.d.ts} +0 -0
  71. /package/dist/{validators-wOIjhkfN.d.ts → validators-0I-Ik1EN.d.ts} +0 -0
@@ -30,6 +30,69 @@ const NoOp = {
30
30
  }
31
31
  };
32
32
  /**
33
+ * customQuery helps define custom behavior on top of `query` or `internalQuery`
34
+ * by passing a function that modifies the ctx and args.
35
+ *
36
+ * Example usage:
37
+ * ```js
38
+ * const myQueryBuilder = customQuery(query, {
39
+ * args: { sessionId: v.id("sessions") },
40
+ * input: async (ctx, args) => {
41
+ * const user = await getUserOrNull(ctx);
42
+ * const session = await db.get(sessionId);
43
+ * const db = wrapDatabaseReader({ user }, ctx.db, rlsRules);
44
+ * return {
45
+ * ctx: { db, user, session },
46
+ * args: {},
47
+ * onSuccess: ({ result }) => {
48
+ * // Optional callback that runs after the function executes
49
+ * // Has access to resources created during input processing
50
+ * console.log(`Query for ${user.name} returned:`, result);
51
+ * }
52
+ * };
53
+ * },
54
+ * });
55
+ *
56
+ * // Using the custom builder
57
+ * export const getSomeData = myQueryBuilder({
58
+ * args: { someArg: v.string() },
59
+ * handler: async (ctx, args) => {
60
+ * const { db, user, session, scheduler } = ctx;
61
+ * const { someArg } = args;
62
+ * // ...
63
+ * }
64
+ * });
65
+ * ```
66
+ *
67
+ * Simple usage only modifying ctx:
68
+ * ```js
69
+ * const myInternalQuery = customQuery(
70
+ * internalQuery,
71
+ * customCtx(async (ctx) => {
72
+ * return {
73
+ * // Throws an exception if the user isn't logged in
74
+ * user: await getUserByTokenIdentifier(ctx),
75
+ * };
76
+ * })
77
+ * );
78
+ *
79
+ * // Using it
80
+ * export const getUser = myInternalQuery({
81
+ * args: {},
82
+ * handler: async (ctx, args) => {
83
+ * return ctx.user;
84
+ * },
85
+ * });
86
+ *
87
+ * @param query The query to be modified. Usually `query` or `internalQuery`
88
+ * from `_generated/server`.
89
+ * @param customization The modifier to be applied to the query, changing ctx and args.
90
+ * @returns A new query builder to define queries with modified ctx and args.
91
+ */
92
+ function customQuery(query, customization) {
93
+ return customFnBuilder(query, customization);
94
+ }
95
+ /**
33
96
  * customMutation helps define custom behavior on top of `mutation`
34
97
  * or `internalMutation` by passing a function that modifies the ctx and args.
35
98
  *
@@ -142,4 +205,4 @@ function customFnBuilder(builder, customization) {
142
205
  }
143
206
 
144
207
  //#endregion
145
- export { customCtx as n, customMutation as r, NoOp as t };
208
+ export { customQuery as i, customCtx as n, customMutation as r, NoOp as t };
@@ -1,5 +1,5 @@
1
- import { A as integer, C as index, I as ConvexColumnBuilder, L as entityKind, M as custom, O as text, t as convexTable } from "./table-CX2lnX7e.js";
2
- import { t as defineSchemaExtension } from "./extensions-Blzsyekm.js";
1
+ import { b as ConvexColumnBuilder, f as text, g as custom, m as integer, s as index, t as convexTable, x as entityKind } from "./table-d9o_n4R3.js";
2
+ import { t as defineSchemaExtension } from "./extensions-Bp0XHanR.js";
3
3
  import { v } from "convex/values";
4
4
 
5
5
  //#region src/orm/builders/boolean.ts
@@ -1,4 +1,4 @@
1
- import { d as OrmSchemaExtensionTriggers, l as OrmSchemaExtensionRelations } from "./table-CX2lnX7e.js";
1
+ import { c as OrmSchemaExtensionTriggers, o as OrmSchemaExtensionRelations } from "./symbols-DDNAddkd.js";
2
2
 
3
3
  //#region src/orm/extensions.ts
4
4
  function defineChainMethod(target, key, value) {
@@ -1,5 +1,5 @@
1
- import { t as GetAuth } from "./types-Bf3XQex5.js";
2
- import { t as GenericCtx } from "./context-utils-DwZ3Cam1.js";
1
+ import { t as GetAuth } from "./types-ex0-J-SC.js";
2
+ import { t as GenericCtx } from "./context-utils-Cbv4r0AA.js";
3
3
  import * as convex_server0 from "convex/server";
4
4
  import { DocumentByName, FunctionReference, GenericDataModel, GenericMutationCtx, GenericSchema, PaginationResult, SchemaDefinition, TableNamesInDataModel, internalMutationGeneric } from "convex/server";
5
5
  import * as better_auth_adapters0 from "better-auth/adapters";
@@ -93,6 +93,24 @@ declare const findOneHandler: (ctx: any, args: {
93
93
  select?: string[];
94
94
  where?: any[];
95
95
  }, schema: Schema, betterAuthSchema: any) => Promise<convex_server0.GenericDocument | null>;
96
+ /**
97
+ * Row count for one Better Auth model, or `null` when the requested shape can
98
+ * only be answered by reading the rows.
99
+ *
100
+ * Two shapes are bounded:
101
+ * - An empty `where` uses Convex's native table count, which reads no
102
+ * documents. This is the shape `countTotalUsers` issues, and the only one
103
+ * that also works on a plain (non-ORM) auth schema.
104
+ * - An equality-only `where` whose field set exactly matches a declared
105
+ * `aggregateIndex` reads a constant number of bucket rows through the ORM.
106
+ *
107
+ * Everything else returns `null` so the caller walks pages instead. That walk
108
+ * returns the same number; it is only linear in matching rows.
109
+ */
110
+ declare const countHandler: (ctx: any, args: {
111
+ model: string;
112
+ where?: any[];
113
+ }, schema: Schema, betterAuthSchema: any) => Promise<number | null>;
96
114
  declare const findManyHandler: (ctx: any, args: {
97
115
  model: string;
98
116
  paginationOpts: any;
@@ -178,13 +196,23 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>, DataModel e
178
196
  triggers?: GenericAuthTriggers<DataModel, Schema, TriggerCtx> | ((ctx: TriggerCtx) => GenericAuthTriggers<DataModel, Schema, TriggerCtx> | undefined); /** Validate input validators against auth table schemas. Defaults to false for smaller generated types. */
179
197
  validateInput?: boolean;
180
198
  }) => {
199
+ count: convex_server0.RegisteredQuery<"internal", {
200
+ where?: {
201
+ mode?: "sensitive" | "insensitive" | undefined;
202
+ connector?: "AND" | "OR" | undefined;
203
+ operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
204
+ value: string | number | boolean | string[] | number[] | null;
205
+ field: string;
206
+ }[] | undefined;
207
+ model: string;
208
+ }, Promise<number | null>>;
181
209
  consumeOne: convex_server0.RegisteredMutation<"internal", {
182
210
  input: {
183
211
  where?: {
184
212
  connector?: "AND" | "OR" | undefined;
185
213
  operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
186
- field: string;
187
214
  value: string | number | boolean | string[] | number[] | null;
215
+ field: string;
188
216
  }[] | undefined;
189
217
  model: string;
190
218
  } | {
@@ -211,8 +239,8 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>, DataModel e
211
239
  where?: {
212
240
  connector?: "AND" | "OR" | undefined;
213
241
  operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
214
- field: string;
215
242
  value: string | number | boolean | string[] | number[] | null;
243
+ field: string;
216
244
  }[] | undefined;
217
245
  model: string;
218
246
  } | {
@@ -240,8 +268,8 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>, DataModel e
240
268
  where?: {
241
269
  connector?: "AND" | "OR" | undefined;
242
270
  operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
243
- field: string;
244
271
  value: string | number | boolean | string[] | number[] | null;
272
+ field: string;
245
273
  }[] | undefined;
246
274
  model: string;
247
275
  } | {
@@ -255,14 +283,14 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>, DataModel e
255
283
  mode?: "sensitive" | "insensitive" | undefined;
256
284
  connector?: "AND" | "OR" | undefined;
257
285
  operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
258
- field: string;
259
286
  value: string | number | boolean | string[] | number[] | null;
287
+ field: string;
260
288
  }[] | undefined;
261
289
  limit?: number | undefined;
262
290
  offset?: number | undefined;
263
291
  sortBy?: {
264
- field: string;
265
292
  direction: "asc" | "desc";
293
+ field: string;
266
294
  } | undefined;
267
295
  model: string;
268
296
  paginationOpts: {
@@ -280,8 +308,8 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>, DataModel e
280
308
  mode?: "sensitive" | "insensitive" | undefined;
281
309
  connector?: "AND" | "OR" | undefined;
282
310
  operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
283
- field: string;
284
311
  value: string | number | boolean | string[] | number[] | null;
312
+ field: string;
285
313
  }[] | undefined;
286
314
  select?: string[] | undefined;
287
315
  model: string;
@@ -293,8 +321,8 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>, DataModel e
293
321
  mode?: "sensitive" | "insensitive" | undefined;
294
322
  connector?: "AND" | "OR" | undefined;
295
323
  operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
296
- field: string;
297
324
  value: string | number | boolean | string[] | number[] | null;
325
+ field: string;
298
326
  }[] | undefined;
299
327
  set?: Record<string, any> | undefined;
300
328
  model: string;
@@ -307,8 +335,8 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>, DataModel e
307
335
  where?: {
308
336
  connector?: "AND" | "OR" | undefined;
309
337
  operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
310
- field: string;
311
338
  value: string | number | boolean | string[] | number[] | null;
339
+ field: string;
312
340
  }[] | undefined;
313
341
  model: string;
314
342
  update: {
@@ -342,8 +370,8 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>, DataModel e
342
370
  where?: {
343
371
  connector?: "AND" | "OR" | undefined;
344
372
  operator?: "lt" | "lte" | "gt" | "gte" | "eq" | "in" | "not_in" | "ne" | "contains" | "starts_with" | "ends_with" | undefined;
345
- field: string;
346
373
  value: string | number | boolean | string[] | number[] | null;
374
+ field: string;
347
375
  }[] | undefined;
348
376
  model: string;
349
377
  update: {
@@ -361,6 +389,7 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>, DataModel e
361
389
  //#endregion
362
390
  //#region src/auth/create-client.d.ts
363
391
  type AuthFunctions = {
392
+ count: FunctionReference<'query', 'internal', Record<string, any>>;
364
393
  consumeOne: FunctionReference<'mutation', 'internal', Record<string, any>>;
365
394
  create: FunctionReference<'mutation', 'internal', Record<string, any>>;
366
395
  deleteMany: FunctionReference<'mutation', 'internal', Record<string, any>>;
@@ -408,4 +437,4 @@ declare const createDisabledAuthRuntime: <DataModel extends GenericDataModel, Sc
408
437
  reason?: string;
409
438
  }) => AuthRuntime<DataModel, Schema, TriggerCtx, GenericCtx, AuthOptions>;
410
439
  //#endregion
411
- export { GenericAuthTriggers as C, GenericAuthTriggerHandlers as S, updateOneHandler as _, AuthFunctions as a, GenericAuthDefinition as b, consumeOneHandler as c, deleteManyHandler as d, deleteOneHandler as f, updateManyHandler as g, incrementOneHandler as h, getGeneratedAuthDisabledReason as i, createApi as l, findOneHandler as m, GeneratedAuthDisabledReasonKind as n, Triggers as o, findManyHandler as p, createDisabledAuthRuntime as r, createClient as s, AuthRuntime as t, createHandler as u, BetterAuthOptionsWithoutDatabase as v, defineAuth as w, GenericAuthTriggerChange as x, GenericAuthBeforeResult as y };
440
+ export { GenericAuthTriggerHandlers as C, GenericAuthTriggerChange as S, defineAuth as T, updateManyHandler as _, AuthFunctions as a, GenericAuthBeforeResult as b, consumeOneHandler as c, createHandler as d, deleteManyHandler as f, incrementOneHandler as g, findOneHandler as h, getGeneratedAuthDisabledReason as i, countHandler as l, findManyHandler as m, GeneratedAuthDisabledReasonKind as n, Triggers as o, deleteOneHandler as p, createDisabledAuthRuntime as r, createClient as s, AuthRuntime as t, createApi as u, updateOneHandler as v, GenericAuthTriggers as w, GenericAuthDefinition as x, BetterAuthOptionsWithoutDatabase as y };
@@ -34,6 +34,7 @@ const createDisabledAuthRuntime = (config) => {
34
34
  throw new Error(`${message} (auth)`);
35
35
  } }),
36
36
  getAuth: createDisabledError(message, "getAuth"),
37
+ count: createDisabledRuntimeExport(message, "count"),
37
38
  consumeOne: createDisabledRuntimeExport(message, "consumeOne"),
38
39
  create: createDisabledRuntimeExport(message, "create"),
39
40
  deleteMany: createDisabledRuntimeExport(message, "deleteMany"),
@@ -1,5 +1,5 @@
1
- import { o as Simplify } from "./types-MHYXboyy.js";
2
- import { g as UnsetMarker, t as AnyMiddleware } from "./types-eNzQmbqM.js";
1
+ import { o as Simplify } from "./types-Bqi_ivSd.js";
2
+ import { g as UnsetMarker, t as AnyMiddleware } from "./types-Bkeicpo6.js";
3
3
  import { GenericActionCtx, GenericDataModel, HttpRouter } from "convex/server";
4
4
  import { z } from "zod";
5
5
  import { Context, Hono } from "hono";
@@ -1,3 +1,5 @@
1
+ import { n as Columns } from "./symbols-DDNAddkd.js";
2
+
1
3
  //#region src/orm/filter-expression.ts
2
4
  /**
3
5
  * Unique symbol for FilterExpression brand
@@ -399,4 +401,96 @@ function isNotNull(col) {
399
401
  }
400
402
 
401
403
  //#endregion
402
- export { or as A, matchLikePattern as C, notIlike as D, notBetween as E, notInArray as O, lte as S, not as T, isFieldReference as _, between as a, like as b, endsWith as c, filterValueInList as d, filterValuesEqual as f, inArray as g, ilike as h, arrayOverlaps as i, startsWith as j, notLike as k, eq as l, gte as m, arrayContained as n, column as o, gt as p, arrayContains as r, contains as s, and as t, fieldRef as u, isNotNull as v, ne as w, lt as x, isNull as y };
404
+ //#region src/orm/timestamp-mode.ts
405
+ const PUBLIC_CREATED_AT_FIELD = "createdAt";
406
+ const INTERNAL_CREATION_TIME_FIELD = "_creationTime";
407
+ const CREATED_AT_MIGRATION_MESSAGE = "`_creationTime` is no longer public. Use `createdAt` instead.";
408
+ const hasUserCreatedAtColumn = (table) => {
409
+ if (!table || typeof table !== "object") return false;
410
+ const columns = table[Columns];
411
+ if (!columns || typeof columns !== "object") return false;
412
+ return Object.hasOwn(columns, PUBLIC_CREATED_AT_FIELD);
413
+ };
414
+ const usesSystemCreatedAtAlias = (_table) => true;
415
+
416
+ //#endregion
417
+ //#region src/orm/index-utils.ts
418
+ function getIndexes(table) {
419
+ const indexes = table.getIndexes?.();
420
+ return Array.isArray(indexes) ? indexes : [];
421
+ }
422
+ function getAggregateIndexes(table) {
423
+ const indexes = table.getAggregateIndexes?.();
424
+ return Array.isArray(indexes) ? indexes : [];
425
+ }
426
+ function getRankIndexes(table) {
427
+ const indexes = table.getRankIndexes?.();
428
+ return Array.isArray(indexes) ? indexes : [];
429
+ }
430
+ function getSearchIndexes(table) {
431
+ const indexes = table.getSearchIndexes?.();
432
+ return Array.isArray(indexes) ? indexes : [];
433
+ }
434
+ function findSearchIndexByName(table, indexName) {
435
+ return getSearchIndexes(table).find((index) => index.name === indexName) ?? null;
436
+ }
437
+ function getVectorIndexes(table) {
438
+ const indexes = table.getVectorIndexes?.();
439
+ return Array.isArray(indexes) ? indexes : [];
440
+ }
441
+ function findVectorIndexByName(table, indexName) {
442
+ return getVectorIndexes(table).find((index) => index.name === indexName) ?? null;
443
+ }
444
+ function findIndexForColumns(indexes, columns) {
445
+ for (const index of indexes) if (hasColumnPrefix(index, columns)) return index.name;
446
+ return null;
447
+ }
448
+ function findExactIndexForColumns(indexes, columns) {
449
+ return indexes.find((candidate) => candidate.fields.length === columns.length && candidate.fields.every((field, position) => field === columns[position]))?.name ?? null;
450
+ }
451
+ const hasColumnPrefix = (index, columns) => {
452
+ if (index.fields.length < columns.length) return false;
453
+ for (let i = 0; i < columns.length; i += 1) if (index.fields[i] !== columns[i]) return false;
454
+ return true;
455
+ };
456
+ /**
457
+ * Answers "does scanning this index already produce the requested order?".
458
+ *
459
+ * Convex walks an index in full key order, so once a leading run of fields is
460
+ * pinned to a single value by `eq`, the remainder of the scan is already sorted
461
+ * by the next index field — and by `_creationTime` once every declared field is
462
+ * pinned, because Convex appends it as the implicit trailing key. When that
463
+ * field is the one the caller asked to sort by, `.order(dir).take(n)` returns
464
+ * the exact page and nothing has to be collected and sorted afterwards.
465
+ *
466
+ * This is the single owner of that decision. The top-level query planner and
467
+ * the relation loader both call it, so a bound one of them can push into the
468
+ * index can never be one the other silently drops.
469
+ *
470
+ * Returns the direction to hand to `.order()`, or null when the sort must run
471
+ * after the fetch.
472
+ */
473
+ function resolveIndexOrderPushdown(params) {
474
+ const { indexFields, pinnedEqCount, orderSpecs } = params;
475
+ if (!indexFields || orderSpecs.length !== 1) return null;
476
+ const primary = orderSpecs[0];
477
+ const eqCount = Math.min(Math.max(pinnedEqCount, 0), indexFields.length);
478
+ for (let i = 0; i < eqCount; i += 1) if (indexFields[i] === primary.field) return primary.direction;
479
+ const nativeField = eqCount >= indexFields.length ? INTERNAL_CREATION_TIME_FIELD : indexFields[eqCount];
480
+ return primary.field === nativeField ? primary.direction : null;
481
+ }
482
+ function findRelationIndex(table, columns, relationName, targetTableName, strict = true, allowFullScan = false, orderSpecs = []) {
483
+ const indexes = getIndexes(table);
484
+ const fallbackIndex = findIndexForColumns(indexes, columns);
485
+ const index = (orderSpecs.length === 0 ? void 0 : indexes.find((candidate) => hasColumnPrefix(candidate, columns) && resolveIndexOrderPushdown({
486
+ indexFields: candidate.fields,
487
+ pinnedEqCount: columns.length,
488
+ orderSpecs
489
+ }) !== null))?.name ?? fallbackIndex;
490
+ if (!index && !allowFullScan) throw new Error(`Relation ${relationName} requires index on '${targetTableName}(${columns.join(", ")})'. Set allowFullScan: true to override.`);
491
+ if (!index && strict) console.warn(`Relation ${relationName} running without index (allowFullScan: true).`);
492
+ return index;
493
+ }
494
+
495
+ //#endregion
496
+ export { inArray as A, notBetween as B, eq as C, gt as D, filterValuesEqual as E, lt as F, startsWith as G, notInArray as H, lte as I, matchLikePattern as L, isNotNull as M, isNull as N, gte as O, like as P, ne as R, endsWith as S, filterValueInList as T, notLike as U, notIlike as V, or as W, arrayContains as _, findVectorIndexByName as a, column as b, getRankIndexes as c, INTERNAL_CREATION_TIME_FIELD as d, PUBLIC_CREATED_AT_FIELD as f, arrayContained as g, and as h, findSearchIndexByName as i, isFieldReference as j, ilike as k, resolveIndexOrderPushdown as l, usesSystemCreatedAtAlias as m, findIndexForColumns as n, getAggregateIndexes as o, hasUserCreatedAtColumn as p, findRelationIndex as r, getIndexes as s, findExactIndexForColumns as t, CREATED_AT_MIGRATION_MESSAGE as u, arrayOverlaps as v, fieldRef as w, contains as x, between as y, not as z };
@@ -937,58 +937,6 @@ function text(name) {
937
937
  return new ConvexTextBuilder(name ?? "");
938
938
  }
939
939
 
940
- //#endregion
941
- //#region src/orm/extensions.ts
942
- function defineChainMethod(target, key, value) {
943
- Object.defineProperty(target, key, {
944
- value,
945
- enumerable: false,
946
- configurable: true
947
- });
948
- }
949
- function createSchemaExtensionChain(state, capabilities) {
950
- const extension = {
951
- key: state.key,
952
- tables: state.tables
953
- };
954
- Object.defineProperty(extension, OrmSchemaExtensionRelations, {
955
- value: state.relations,
956
- enumerable: false,
957
- configurable: true
958
- });
959
- Object.defineProperty(extension, OrmSchemaExtensionTriggers, {
960
- value: state.triggers,
961
- enumerable: false,
962
- configurable: true
963
- });
964
- if (capabilities.canRelations) defineChainMethod(extension, "relations", (relations) => createSchemaExtensionChain({
965
- ...state,
966
- relations
967
- }, {
968
- canRelations: false,
969
- canTriggers: true
970
- }));
971
- if (capabilities.canTriggers) defineChainMethod(extension, "triggers", (triggers) => createSchemaExtensionChain({
972
- ...state,
973
- triggers
974
- }, {
975
- canRelations: false,
976
- canTriggers: false
977
- }));
978
- return extension;
979
- }
980
- function defineSchemaExtension(key, tables) {
981
- return createSchemaExtensionChain({
982
- key,
983
- tables,
984
- relations: void 0,
985
- triggers: void 0
986
- }, {
987
- canRelations: true,
988
- canTriggers: true
989
- });
990
- }
991
-
992
940
  //#endregion
993
941
  //#region src/orm/indexes.ts
994
942
  var ConvexIndexBuilderOn = class {
@@ -1961,14 +1909,98 @@ const convexTableWithRLS = (name, columns, extraConfig) => {
1961
1909
  };
1962
1910
  const convexTable = Object.assign(convexTableInternal, { withRLS: convexTableWithRLS });
1963
1911
 
1912
+ //#endregion
1913
+ //#region src/aggregate-core/schema.ts
1914
+ const AGGREGATE_TREE_TABLE = "aggregate_rank_tree";
1915
+ const AGGREGATE_NODE_TABLE = "aggregate_rank_node";
1916
+ const aggregateCounterValidator = v.object({
1917
+ count: v.number(),
1918
+ sum: v.number()
1919
+ });
1920
+ const aggregateItemValidator = v.object({
1921
+ k: v.any(),
1922
+ v: v.any(),
1923
+ s: v.number()
1924
+ });
1925
+ const aggregateTreeTable = convexTable(AGGREGATE_TREE_TABLE, {
1926
+ aggregateName: text().notNull(),
1927
+ deletionStack: custom(v.array(v.id(AGGREGATE_NODE_TABLE))),
1928
+ maxNodeSize: integer().notNull(),
1929
+ namespace: custom(v.any()),
1930
+ root: id(AGGREGATE_NODE_TABLE).notNull()
1931
+ }, (tree) => [index("by_namespace").on(tree.namespace), index("by_aggregate_name").on(tree.aggregateName)]);
1932
+ const aggregateNodeTable = convexTable(AGGREGATE_NODE_TABLE, {
1933
+ aggregate: custom(aggregateCounterValidator),
1934
+ items: custom(v.array(aggregateItemValidator)).notNull(),
1935
+ subtrees: custom(v.array(v.string())).notNull()
1936
+ });
1937
+ const aggregateStorageTables$1 = {
1938
+ [AGGREGATE_NODE_TABLE]: aggregateNodeTable,
1939
+ [AGGREGATE_TREE_TABLE]: aggregateTreeTable
1940
+ };
1941
+
1942
+ //#endregion
1943
+ //#region src/orm/extensions.ts
1944
+ function defineChainMethod(target, key, value) {
1945
+ Object.defineProperty(target, key, {
1946
+ value,
1947
+ enumerable: false,
1948
+ configurable: true
1949
+ });
1950
+ }
1951
+ function createSchemaExtensionChain(state, capabilities) {
1952
+ const extension = {
1953
+ key: state.key,
1954
+ tables: state.tables
1955
+ };
1956
+ Object.defineProperty(extension, OrmSchemaExtensionRelations, {
1957
+ value: state.relations,
1958
+ enumerable: false,
1959
+ configurable: true
1960
+ });
1961
+ Object.defineProperty(extension, OrmSchemaExtensionTriggers, {
1962
+ value: state.triggers,
1963
+ enumerable: false,
1964
+ configurable: true
1965
+ });
1966
+ if (capabilities.canRelations) defineChainMethod(extension, "relations", (relations) => createSchemaExtensionChain({
1967
+ ...state,
1968
+ relations
1969
+ }, {
1970
+ canRelations: false,
1971
+ canTriggers: true
1972
+ }));
1973
+ if (capabilities.canTriggers) defineChainMethod(extension, "triggers", (triggers) => createSchemaExtensionChain({
1974
+ ...state,
1975
+ triggers
1976
+ }, {
1977
+ canRelations: false,
1978
+ canTriggers: false
1979
+ }));
1980
+ return extension;
1981
+ }
1982
+ function defineSchemaExtension(key, tables) {
1983
+ return createSchemaExtensionChain({
1984
+ key,
1985
+ tables,
1986
+ relations: void 0,
1987
+ triggers: void 0
1988
+ }, {
1989
+ canRelations: true,
1990
+ canTriggers: true
1991
+ });
1992
+ }
1993
+
1964
1994
  //#endregion
1965
1995
  //#region src/orm/aggregate-index/schema.ts
1966
1996
  const AGGREGATE_BUCKET_TABLE = "aggregate_bucket";
1967
1997
  const AGGREGATE_MEMBER_TABLE = "aggregate_member";
1968
1998
  const AGGREGATE_EXTREMA_TABLE = "aggregate_extrema";
1969
- const AGGREGATE_RANK_TREE_TABLE = "aggregate_rank_tree";
1970
- const AGGREGATE_RANK_NODE_TABLE = "aggregate_rank_node";
1971
1999
  const AGGREGATE_STATE_TABLE = "aggregate_state";
2000
+ const AGGREGATE_RANK_TREE_TABLE = AGGREGATE_TREE_TABLE;
2001
+ const AGGREGATE_RANK_NODE_TABLE = AGGREGATE_NODE_TABLE;
2002
+ const rankTreeTable = aggregateTreeTable;
2003
+ const rankNodeTable = aggregateNodeTable;
1972
2004
  const countBucketTable = convexTable(AGGREGATE_BUCKET_TABLE, {
1973
2005
  tableKey: text().notNull(),
1974
2006
  indexName: text().notNull(),
@@ -2027,24 +2059,6 @@ const countStateTable = convexTable(AGGREGATE_STATE_TABLE, {
2027
2059
  index("by_kind_status").on(t.kind, t.status),
2028
2060
  index("by_table_status").on(t.tableKey, t.status)
2029
2061
  ]);
2030
- const rankTreeTable = convexTable(AGGREGATE_RANK_TREE_TABLE, {
2031
- aggregateName: text().notNull(),
2032
- maxNodeSize: integer().notNull(),
2033
- namespace: json(),
2034
- root: id(AGGREGATE_RANK_NODE_TABLE).notNull()
2035
- }, (tree) => [index("by_namespace").on(tree.namespace), index("by_aggregate_name").on(tree.aggregateName)]);
2036
- const rankNodeTable = convexTable(AGGREGATE_RANK_NODE_TABLE, {
2037
- aggregate: objectOf({
2038
- count: integer().notNull(),
2039
- sum: integer().notNull()
2040
- }),
2041
- items: arrayOf(objectOf({
2042
- k: json(),
2043
- v: json(),
2044
- s: integer().notNull()
2045
- })).notNull(),
2046
- subtrees: arrayOf(text().notNull()).notNull()
2047
- });
2048
2062
  const aggregateStorageTables = {
2049
2063
  [AGGREGATE_BUCKET_TABLE]: countBucketTable,
2050
2064
  [AGGREGATE_MEMBER_TABLE]: countMemberTable,
@@ -2739,6 +2753,11 @@ function resolveGenerationMode(options) {
2739
2753
  };
2740
2754
  }
2741
2755
  const AUTH_RUNTIME_PROCEDURES = [
2756
+ {
2757
+ exportName: "count",
2758
+ internal: true,
2759
+ type: "query"
2760
+ },
2742
2761
  {
2743
2762
  exportName: "create",
2744
2763
  internal: true,
@@ -3611,6 +3630,7 @@ export const {
3611
3630
  authClient,
3612
3631
  getAuth,
3613
3632
  auth,
3633
+ count,
3614
3634
  create,
3615
3635
  deleteMany,
3616
3636
  deleteOne,
@@ -1,4 +1,4 @@
1
- import { o as MiddlewareBuilder } from "./types-eNzQmbqM.js";
1
+ import { o as MiddlewareBuilder } from "./types-Bkeicpo6.js";
2
2
 
3
3
  //#region src/plugins/middleware.d.ts
4
4
  declare const PLUGIN_CONFIG_RESOLVERS: unique symbol;
@@ -1,4 +1,4 @@
1
- import { a as createMiddlewareFactory } from "./builder-CsAw-DK8.js";
1
+ import { a as createMiddlewareFactory } from "./builder-Cyd5nCxZ.js";
2
2
 
3
3
  //#region src/plugins/middleware.ts
4
4
  const PLUGIN_CONFIG_RESOLVERS = Symbol.for("kitcn:PluginConfigResolvers");
@@ -1,4 +1,4 @@
1
- import { $ as RankIndexDefinition, G as CountBackfillChunkArgs, J as CountBackfillStatusArgs, K as CountBackfillKickoffArgs, Q as CountIndexDefinition, X as CountQueryPlan, Y as AggregateQueryPlan, Z as AggregateIndexDefinition, et as RankOrderField, q as CountBackfillMode, r as OrmCapability } from "../../capabilities-6PZBmvc8.js";
1
+ import { $ as RankIndexDefinition, G as CountBackfillChunkArgs, J as CountBackfillStatusArgs, K as CountBackfillKickoffArgs, Q as CountIndexDefinition, X as CountQueryPlan, Y as AggregateQueryPlan, Z as AggregateIndexDefinition, et as RankOrderField, q as CountBackfillMode, r as OrmCapability } from "../../capabilities-CG-oIMyR.js";
2
2
 
3
3
  //#region src/orm/aggregate-index/capability.d.ts
4
4
  /**