kitcn 0.25.1 → 0.25.3

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 (29) hide show
  1. package/dist/aggregate/index.d.ts +2 -2
  2. package/dist/auth/generated/index.d.ts +1 -1
  3. package/dist/auth/index.d.ts +5 -5
  4. package/dist/auth/nextjs/index.d.ts +1 -1
  5. package/dist/{builder-C6JSHkRK.js → builder-DoeyW4Vq.js} +64 -64
  6. package/dist/{capabilities-Bem7xvGK.d.ts → capabilities-DtDfpdcH.d.ts} +20 -1
  7. package/dist/cli.mjs +118 -20
  8. package/dist/{generated-contract-disabled-BEc4d98x.d.ts → generated-contract-disabled-SzH57bhp.d.ts} +1 -1
  9. package/dist/{middleware-CdqNVyp8.js → middleware-DIj-bwVi.js} +1 -1
  10. package/dist/orm/aggregate-index/index.d.ts +1 -1
  11. package/dist/orm/aggregate-index/index.js +15 -4
  12. package/dist/orm/index.d.ts +2 -2
  13. package/dist/orm/index.js +89 -19
  14. package/dist/orm/migrations/index.d.ts +2 -2
  15. package/dist/plugins/index.js +1 -1
  16. package/dist/{procedure-caller-CgLWu5F9.js → procedure-caller-Dxae9DW5.js} +3 -3
  17. package/dist/{procedure-name-Bjw1JDIS.d.ts → procedure-name-l2YusEZI.d.ts} +52 -52
  18. package/dist/ratelimit/index.js +2 -2
  19. package/dist/{schema-BQd2Xrfb.js → schema-D8sVYuYO.js} +25 -11
  20. package/dist/server/index.d.ts +1 -1
  21. package/dist/server/index.js +2 -2
  22. package/dist/{where-clause-compiler-Dmq4HMrK.d.ts → where-clause-compiler-Bke7ULoY.d.ts} +74 -74
  23. package/package.json +1 -1
  24. package/skills/kitcn/SKILL.md +1 -1
  25. package/skills/kitcn/references/features/aggregates.md +3 -0
  26. package/skills/kitcn/references/features/auth-polar.md +2 -2
  27. package/skills/kitcn/references/features/scheduling.md +1 -1
  28. package/skills/kitcn/references/setup/auth.md +1 -1
  29. package/skills/kitcn/references/setup/index.md +3 -3
@@ -1,6 +1,6 @@
1
1
  import { t as DirectAggregate } from "../../runtime-BdqTbgKh.js";
2
2
  import { a as Columns } from "../../table-CX2lnX7e.js";
3
- import { Y as normalizeTemporalComparableValue, _t as usesSystemCreatedAtAlias, c as AGGREGATE_ERROR, f as createError, gt as PUBLIC_CREATED_AT_FIELD, ht as INTERNAL_CREATION_TIME_FIELD, i as AGGREGATE_STATE_TABLE, it as mapWithConcurrency, l as COUNT_ERROR, n as AGGREGATE_EXTREMA_TABLE, o as getAggregateIndexDefinitions, r as AGGREGATE_MEMBER_TABLE, s as getRankIndexDefinitions, t as AGGREGATE_BUCKET_TABLE } from "../../schema-BQd2Xrfb.js";
3
+ import { Y as normalizeTemporalComparableValue, _t as PUBLIC_CREATED_AT_FIELD, c as AGGREGATE_ERROR, f as createError, gt as INTERNAL_CREATION_TIME_FIELD, i as AGGREGATE_STATE_TABLE, l as COUNT_ERROR, n as AGGREGATE_EXTREMA_TABLE, o as getAggregateIndexDefinitions, ot as mapWithConcurrency, r as AGGREGATE_MEMBER_TABLE, s as getRankIndexDefinitions, t as AGGREGATE_BUCKET_TABLE, vt as usesSystemCreatedAtAlias } from "../../schema-D8sVYuYO.js";
4
4
 
5
5
  //#region src/orm/aggregate-index/runtime.ts
6
6
  const UNDEFINED_SENTINEL = "__kitcnUndefined";
@@ -27,6 +27,17 @@ const normalizeUndefined = (value) => {
27
27
  return value;
28
28
  };
29
29
  const serializeStable = (value) => JSON.stringify(normalizeUndefined(value));
30
+ /**
31
+ * A nullable column is `v.optional(v.union(v.null(), ...))`, so a row that
32
+ * never had the column written stores it absent, and `computeCountKeyParts`
33
+ * encodes absent as the `__kitcnUndefined` sentinel — a different bucket from
34
+ * the one an explicit `null` lands in. `isNull` means null-or-absent
35
+ * everywhere else in the ORM, so probing only the `null` bucket silently
36
+ * undercounts every row written before the column existed. Both probes are
37
+ * looked up through `serializeStable`, which maps `undefined` onto the same
38
+ * sentinel the write path stored.
39
+ */
40
+ const NULLISH_PROBE_VALUES = [null, void 0];
30
41
  const toConstraintSet = (values) => {
31
42
  const set = /* @__PURE__ */ new Map();
32
43
  for (const value of values) set.set(serializeStable(value), value);
@@ -138,7 +149,7 @@ const parseFieldFilter = (tableConfig, fieldName, value, target, codes, methodNa
138
149
  if (Object.hasOwn(filter, "isNull")) {
139
150
  hasRecognizedOperator = true;
140
151
  if (filter.isNull !== true) throw createFilterError(codes, methodName, `field '${fieldName}'.isNull only supports true.`);
141
- pushConstraint(target, fieldName, [null]);
152
+ pushConstraint(target, fieldName, [...NULLISH_PROBE_VALUES]);
142
153
  }
143
154
  for (const operator of [
144
155
  "gt",
@@ -405,9 +416,9 @@ const enforceCartesianExpansionGuards = (options) => {
405
416
  const maxTrackedCombinations = Math.max(cartesianMaxKeys, maxCombinationsByWork);
406
417
  const combinations = countCartesianCombinations(options.fields, options.fieldValues, maxTrackedCombinations);
407
418
  if (combinations === 0) return;
408
- if (combinations > cartesianMaxKeys) throw createFilterError(options.codes, options.methodName, `expands IN filters to ${combinations} key combinations on aggregateIndex '${options.indexName}', exceeding aggregateCartesianMaxKeys (${cartesianMaxKeys}). Reduce IN list sizes, split the query, add a narrower aggregateIndex, or increase defineSchema(..., { defaults: { aggregateCartesianMaxKeys } }).`);
419
+ if (combinations > cartesianMaxKeys) throw createFilterError(options.codes, options.methodName, `expands to ${combinations} key combinations on aggregateIndex '${options.indexName}', exceeding aggregateCartesianMaxKeys (${cartesianMaxKeys}). Each 'in' value and each 'isNull' field (which reads both the null and the absent key) multiplies the combinations. Reduce IN list sizes, split the query, add a narrower aggregateIndex, or increase defineSchema(..., { defaults: { aggregateCartesianMaxKeys } }).`);
409
420
  const estimatedWork = combinations * workUnitsPerCombination;
410
- if (estimatedWork > workBudget) throw createFilterError(options.codes, options.methodName, `estimated ${options.workLabel} is ${estimatedWork} units on aggregateIndex '${options.indexName}', exceeding aggregateWorkBudget (${workBudget}). Reduce IN fan-out, split the query, or increase defineSchema(..., { defaults: { aggregateWorkBudget } }).`);
421
+ if (estimatedWork > workBudget) throw createFilterError(options.codes, options.methodName, `estimated ${options.workLabel} is ${estimatedWork} units on aggregateIndex '${options.indexName}', exceeding aggregateWorkBudget (${workBudget}). Reduce IN or isNull fan-out, split the query, or increase defineSchema(..., { defaults: { aggregateWorkBudget } }).`);
411
422
  };
412
423
  const hasLogicalOr = (where) => {
413
424
  if (Object.hasOwn(where, "OR")) return true;
@@ -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-Bem7xvGK.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-Dmq4HMrK.js";
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-DtDfpdcH.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-Bke7ULoY.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
@@ -4,7 +4,7 @@ import { a as pretendRequired, i as pretend, n as deprecated } from "../validato
4
4
  import { t as id } from "../id-CuSfWa5q.js";
5
5
  import { A as or, C as matchLikePattern, D as notIlike, E as notBetween, O as notInArray, S as lte, T as not, _ as isFieldReference, a as between, b as like, c as endsWith, d as filterValueInList, f as filterValuesEqual, g as inArray, h as ilike, i as arrayOverlaps, j as startsWith, k as notLike, l as eq, m as gte, n as arrayContained, o as column, p as gt, r as arrayContains, s as contains, t as and, u as fieldRef, v as isNotNull, w as ne, x as lt, y as isNull } from "../filter-expression-Dydt8wS0.js";
6
6
  import { a as indexKeyWithinBounds, c as streamIndexRange, i as getIndexFields, l as isUnsetToken, n as EmptyStream, o as mergedStream, r as QueryStream, s as stream, t as getByIdWithOrmQueryFallback, u as unsetToken } from "../query-context-DOm5Xm3H.js";
7
- import { $ as serializeFilterExpression, A as ensureNonNullValues, B as getMutationExecutionMode, C as deserializeFilterExpression, D as enforcePolymorphicWrite, E as enforceForeignKeys, F as getChecks, G as getUniqueIndexes, H as getTableColumns$2, I as getColumnName$1, J as normalizeDateFieldsForWrite, K as hardDeleteRow, L as getForeignKeys, M as evaluateCheckConstraintTriState, N as evaluateFilter, O as enforceUniqueIndexes, P as extractPrimaryIdLookup, Q as selectReturningRowWithHydration, R as getMutationAsyncDelayMs, S as decodeUndefinedDeep, T as enforceCheckConstraints, U as getTableDeleteConfig, V as getOrmContext, W as getTableName, X as patchReferencingRows, Y as normalizeTemporalComparableValue, Z as resolveOrmRuntimeDefaults, _ as applyIncomingForeignKeyActionsOnUpdate, _t as usesSystemCreatedAtAlias, a as aggregateExtension, at as markLifecycleHookedTables, b as collectMutationRowsBounded, c as AGGREGATE_ERROR, ct as findSearchIndexByName, d as createCountError, dt as getIndexes, et as softDeleteRow, ft as getRankIndexes, g as applyIncomingForeignKeyActionsOnDelete, gt as PUBLIC_CREATED_AT_FIELD, h as applyDefaults, ht as INTERNAL_CREATION_TIME_FIELD, it as mapWithConcurrency, j as ensureNullableColumns, k as ensureDefaultColumns, l as COUNT_ERROR, lt as findVectorIndexByName, m as ensureCountAllowedForRls, mt as CREATED_AT_MIGRATION_MESSAGE, nt as takeRowsWithinByteBudget, o as getAggregateIndexDefinitions, ot as findIndexForColumns, p as ensureAggregateAllowedForRls, pt as resolveIndexOrderPushdown, q as hydrateDateFieldsForRead, rt as toConvexFilter, s as getRankIndexDefinitions, st as findRelationIndex, tt as splitReturningSelection, u as createAggregateError, ut as getAggregateIndexes, v as buildForeignKeyGraph, w as encodeUndefinedDeep, x as collectPrimaryIdLookupRows, y as canUsePrimaryIdLookupCursor, z as getMutationCollectionLimits } from "../schema-BQd2Xrfb.js";
7
+ import { $ as serializeFilterExpression, A as ensureNonNullValues, B as getMutationExecutionMode, C as deserializeFilterExpression, D as enforcePolymorphicWrite, E as enforceForeignKeys, F as getChecks, G as getUniqueIndexes, H as getTableColumns$2, I as getColumnName$1, J as normalizeDateFieldsForWrite, K as hardDeleteRow, L as getForeignKeys, M as evaluateCheckConstraintTriState, N as evaluateFilter, O as enforceUniqueIndexes, P as extractPrimaryIdLookup, Q as selectReturningRowWithHydration, R as getMutationAsyncDelayMs, S as decodeUndefinedDeep, T as enforceCheckConstraints, U as getTableDeleteConfig, V as getOrmContext, W as getTableName, X as patchReferencingRows, Y as normalizeTemporalComparableValue, Z as resolveOrmRuntimeDefaults, _ as applyIncomingForeignKeyActionsOnUpdate, _t as PUBLIC_CREATED_AT_FIELD, a as aggregateExtension, at as markLifecycleHookedTables, b as collectMutationRowsBounded, c as AGGREGATE_ERROR, ct as findRelationIndex, d as createCountError, dt as getAggregateIndexes, et as softDeleteRow, ft as getIndexes, g as applyIncomingForeignKeyActionsOnDelete, gt as INTERNAL_CREATION_TIME_FIELD, h as applyDefaults, ht as CREATED_AT_MIGRATION_MESSAGE, it as hasLifecycleHooks, j as ensureNullableColumns, k as ensureDefaultColumns, l as COUNT_ERROR, lt as findSearchIndexByName, m as ensureCountAllowedForRls, mt as resolveIndexOrderPushdown, nt as takeRowsWithinByteBudget, o as getAggregateIndexDefinitions, ot as mapWithConcurrency, p as ensureAggregateAllowedForRls, pt as getRankIndexes, q as hydrateDateFieldsForRead, rt as toConvexFilter, s as getRankIndexDefinitions, st as findIndexForColumns, tt as splitReturningSelection, u as createAggregateError, ut as findVectorIndexByName, v as buildForeignKeyGraph, vt as usesSystemCreatedAtAlias, w as encodeUndefinedDeep, x as collectPrimaryIdLookupRows, y as canUsePrimaryIdLookupCursor, z as getMutationCollectionLimits } from "../schema-D8sVYuYO.js";
8
8
  import { t as defineSchemaExtension } from "../extensions-Blzsyekm.js";
9
9
  import { compareValues, v } from "convex/values";
10
10
  import { defineSchema as defineSchema$1, internalActionGeneric, internalMutationGeneric } from "convex/server";
@@ -3218,7 +3218,7 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
3218
3218
  if (Object.hasOwn(filter, "isNull")) {
3219
3219
  hasRecognized = true;
3220
3220
  if (filter.isNull !== true) throw createAggregateError(AGGREGATE_ERROR.FILTER_UNSUPPORTED, `groupBy() field '${fieldName}'.isNull only supports true.`);
3221
- this._pushGroupByConstraint(constraints, fieldName, [null]);
3221
+ this._pushGroupByConstraint(constraints, fieldName, [null, void 0]);
3222
3222
  }
3223
3223
  if (Object.hasOwn(filter, "gt") || Object.hasOwn(filter, "gte") || Object.hasOwn(filter, "lt") || Object.hasOwn(filter, "lte")) throw createAggregateError(AGGREGATE_ERROR.FILTER_UNSUPPORTED, `groupBy() requires finite eq/in/isNull constraints for 'by' field '${fieldName}'. Range operators are unsupported for group keys.`);
3224
3224
  const unsupportedKeys = Object.keys(filter).filter((key) => ![
@@ -3267,24 +3267,60 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
3267
3267
  }
3268
3268
  return output;
3269
3269
  }
3270
+ /**
3271
+ * One group per distinct value, where `null` and absent count as the same
3272
+ * value. They occupy different aggregate buckets, so the emitted group key
3273
+ * and the filter that reads it diverge: the key reports `null` while the
3274
+ * filter keeps `isNull` so the aggregate compiler reads both buckets and
3275
+ * combines their metrics into a single row.
3276
+ */
3277
+ _buildGroupBySlots(values) {
3278
+ const nullishValues = values.filter((value) => value === null || value === void 0);
3279
+ const slots = [];
3280
+ let mergedNullish = false;
3281
+ for (const value of values) {
3282
+ if (value !== null && value !== void 0) {
3283
+ slots.push({
3284
+ key: value,
3285
+ filter: value,
3286
+ probeCount: 1
3287
+ });
3288
+ continue;
3289
+ }
3290
+ if (mergedNullish) continue;
3291
+ mergedNullish = true;
3292
+ slots.push({
3293
+ key: null,
3294
+ filter: nullishValues.length > 1 ? { isNull: true } : value,
3295
+ probeCount: nullishValues.length
3296
+ });
3297
+ }
3298
+ return slots;
3299
+ }
3270
3300
  _buildGroupByCandidates(byFields, byFieldValues) {
3271
3301
  if (byFields.length === 0) return [];
3272
3302
  const output = [];
3273
- const current = {};
3274
- const build = (index) => {
3303
+ const key = {};
3304
+ const where = {};
3305
+ const build = (index, probeCount) => {
3275
3306
  if (index >= byFields.length) {
3276
- output.push({ ...current });
3307
+ output.push({
3308
+ key: { ...key },
3309
+ probeCount,
3310
+ where: { ...where }
3311
+ });
3277
3312
  return;
3278
3313
  }
3279
3314
  const field = byFields[index];
3280
- const values = byFieldValues[field] ?? [];
3281
- for (const value of values) {
3282
- current[field] = value;
3283
- build(index + 1);
3315
+ for (const slot of this._buildGroupBySlots(byFieldValues[field] ?? [])) {
3316
+ key[field] = slot.key;
3317
+ where[field] = slot.filter;
3318
+ build(index + 1, probeCount * slot.probeCount);
3284
3319
  }
3285
- delete current[field];
3320
+ delete key[field];
3321
+ delete where[field];
3286
3322
  };
3287
- build(0);
3323
+ build(0, 1);
3288
3324
  return output;
3289
3325
  }
3290
3326
  _coerceGroupByByFields(by) {
@@ -3631,9 +3667,11 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
3631
3667
  const orderSpecs = this._coerceGroupByOrderSpecs(config.orderBy, by, aggregate);
3632
3668
  const window = this._coerceGroupByWindowConfig(config, orderSpecs);
3633
3669
  const maxKeys = this._getAggregateCartesianMaxKeys();
3634
- if (candidates.length > maxKeys) throw createAggregateError(AGGREGATE_ERROR.ARGS_UNSUPPORTED, `groupBy() expands to ${candidates.length} groups, exceeding aggregateCartesianMaxKeys (${maxKeys}). Reduce IN fan-out or increase defineSchema(..., { defaults: { aggregateCartesianMaxKeys } }).`);
3670
+ let candidateProbeCount = 0;
3671
+ for (const candidate of candidates) candidateProbeCount += candidate.probeCount;
3672
+ if (candidateProbeCount > maxKeys) throw createAggregateError(AGGREGATE_ERROR.ARGS_UNSUPPORTED, `groupBy() expands to ${candidateProbeCount} aggregate key probes, exceeding aggregateCartesianMaxKeys (${maxKeys}). Reduce IN/isNull fan-out or increase defineSchema(..., { defaults: { aggregateCartesianMaxKeys } }).`);
3635
3673
  const metricReads = (aggregate.count === true ? 1 : aggregate.count ? (aggregate.count.all ? 1 : 0) + aggregate.count.fields.length : 0) + aggregate.sumFields.length + aggregate.avgFields.length + aggregate.minFields.length + aggregate.maxFields.length;
3636
- const estimatedWork = candidates.length * Math.max(1, metricReads);
3674
+ const estimatedWork = candidateProbeCount * Math.max(1, metricReads);
3637
3675
  const workBudget = this._getAggregateWorkBudget();
3638
3676
  if (estimatedWork > workBudget) throw createAggregateError(AGGREGATE_ERROR.ARGS_UNSUPPORTED, `groupBy() estimated work is ${estimatedWork} units, exceeding aggregateWorkBudget (${workBudget}). Reduce group fan-out or increase defineSchema(..., { defaults: { aggregateWorkBudget } }).`);
3639
3677
  return {
@@ -3667,13 +3705,13 @@ var GelRelationalQuery = class GelRelationalQuery extends QueryPromise {
3667
3705
  const metricConfig = this._buildAggregateMetricConfig(normalized.aggregate);
3668
3706
  const byOutputKeys = new Set(normalized.by.map((entry) => entry.raw));
3669
3707
  let rows = await this._mapWithConcurrency(normalized.candidates, async (candidate) => {
3670
- const groupWhere = this._isEmptyWhere(normalized.aggregate.where) ? candidate : { AND: [normalized.aggregate.where, candidate] };
3708
+ const groupWhere = this._isEmptyWhere(normalized.aggregate.where) ? candidate.where : { AND: [normalized.aggregate.where, candidate.where] };
3671
3709
  const aggregateRow = await this._executeAggregate({
3672
3710
  ...metricConfig,
3673
3711
  where: groupWhere
3674
3712
  });
3675
3713
  return {
3676
- ...Object.fromEntries(normalized.by.map((entry) => [entry.raw, this._coerceAggregateReturnValue(entry.field, candidate[entry.field])])),
3714
+ ...Object.fromEntries(normalized.by.map((entry) => [entry.raw, this._coerceAggregateReturnValue(entry.field, candidate.key[entry.field])])),
3677
3715
  ...aggregateRow
3678
3716
  };
3679
3717
  });
@@ -6703,11 +6741,43 @@ var ConvexUpdateBuilder = class extends QueryPromise {
6703
6741
  callCap: scheduleCallCap
6704
6742
  };
6705
6743
  const fkBatchSize = isPaginated ? pagination.limit : batchSize;
6744
+ const changedFields = new Set(Object.keys(writeSet));
6745
+ const incomingForeignKeys = foreignKeyGraph.incomingByTable.get(tableName) ?? [];
6746
+ const hooksCanWriteMidLoop = hasLifecycleHooks(this.db, tableName) || incomingForeignKeys.some((foreignKey) => hasLifecycleHooks(this.db, foreignKey.sourceTableName));
6747
+ const cascadeTargetsThisTable = incomingForeignKeys.some((foreignKey) => foreignKey.sourceTableName === tableName);
6748
+ const canDerivePostImage = !(hooksCanWriteMidLoop || cascadeTargetsThisTable);
6749
+ const unsetFields = Object.keys(writeSet).filter((field) => writeSet[field] === void 0);
6750
+ const derivePostImage = (candidate) => {
6751
+ if (unsetFields.length === 0) return candidate;
6752
+ const postImage = { ...candidate };
6753
+ for (const field of unsetFields) delete postImage[field];
6754
+ return postImage;
6755
+ };
6756
+ /**
6757
+ * A single-column `references()` FK to `_id` whose column is supplied by
6758
+ * `set()` probes a byte-identical id on every row, and nothing in this loop
6759
+ * can delete that document. Probe it once, then hide those columns from
6760
+ * `enforceForeignKeys` so the remaining keys still get their per-row check.
6761
+ * Composite FKs read columns off `row`, so they genuinely vary.
6762
+ */
6763
+ const memoizedFkColumns = /* @__PURE__ */ new Set();
6764
+ const perRowFkColumns = /* @__PURE__ */ new Set();
6765
+ for (const foreignKey of getForeignKeys(this.table)) {
6766
+ if (!hooksCanWriteMidLoop && foreignKey.columns.length === 1 && foreignKey.foreignColumns.length === 1 && foreignKey.foreignColumns[0] === "_id" && changedFields.has(foreignKey.columns[0])) {
6767
+ memoizedFkColumns.add(foreignKey.columns[0]);
6768
+ continue;
6769
+ }
6770
+ for (const column of foreignKey.columns) perRowFkColumns.add(column);
6771
+ }
6772
+ for (const column of perRowFkColumns) memoizedFkColumns.delete(column);
6773
+ const residualChangedFields = memoizedFkColumns.size === 0 ? changedFields : new Set([...changedFields].filter((field) => !memoizedFkColumns.has(field)));
6774
+ let foreignKeysProbed = false;
6706
6775
  for (const { row, updatedRow, decision } of updates) {
6707
6776
  if (!decision.allowed) continue;
6708
- enforcePolymorphicWrite(this.table, updatedRow, { changedFields: new Set(Object.keys(writeSet)) });
6777
+ enforcePolymorphicWrite(this.table, updatedRow, { changedFields });
6709
6778
  enforceCheckConstraints(this.table, updatedRow);
6710
- await enforceForeignKeys(this.db, this.table, updatedRow, { changedFields: new Set(Object.keys(writeSet)) });
6779
+ await enforceForeignKeys(this.db, this.table, updatedRow, { changedFields: foreignKeysProbed ? residualChangedFields : changedFields });
6780
+ foreignKeysProbed = true;
6711
6781
  await applyIncomingForeignKeyActionsOnUpdate(this.db, this.table, row, updatedRow, {
6712
6782
  graph: foreignKeyGraph,
6713
6783
  batchSize: fkBatchSize,
@@ -6724,12 +6794,12 @@ var ConvexUpdateBuilder = class extends QueryPromise {
6724
6794
  });
6725
6795
  await enforceUniqueIndexes(this.db, this.table, updatedRow, {
6726
6796
  currentId: row._id,
6727
- changedFields: new Set(Object.keys(writeSet))
6797
+ changedFields
6728
6798
  });
6729
6799
  await this.db.patch(tableName, row._id, writeSet);
6730
6800
  numAffected++;
6731
6801
  if (!this.returningFields) continue;
6732
- const updated = await this.db.get(row._id);
6802
+ const updated = canDerivePostImage ? derivePostImage(updatedRow) : await this.db.get(row._id);
6733
6803
  if (!updated) continue;
6734
6804
  if (this.returningFields === true) results.push(hydrateDateFieldsForRead(this.table, updated));
6735
6805
  else {
@@ -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-Bem7xvGK.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-Dmq4HMrK.js";
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-DtDfpdcH.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-Bke7ULoY.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,3 +1,3 @@
1
- import { n as resolvePluginOptions, t as definePlugin } from "../middleware-CdqNVyp8.js";
1
+ import { n as resolvePluginOptions, t as definePlugin } from "../middleware-DIj-bwVi.js";
2
2
 
3
3
  export { definePlugin, resolvePluginOptions };
@@ -1,6 +1,6 @@
1
1
  import { i as decodeWire, o as encodeWire } from "./transformer-D8wO-kEj.js";
2
- import { _ as CRPCError } from "./builder-C6JSHkRK.js";
3
- import { z } from "zod";
2
+ import { _ as CRPCError } from "./builder-DoeyW4Vq.js";
3
+ import * as z$1 from "zod";
4
4
 
5
5
  //#region src/server/env.ts
6
6
  function createEnv(options) {
@@ -34,7 +34,7 @@ function createEnv(options) {
34
34
  ...Object.fromEntries(Object.entries(schema.shape).map(([key, zodType]) => {
35
35
  const result = zodType.safeParse(void 0);
36
36
  if (!result.success) {
37
- if (zodType instanceof z.ZodEnum && Array.isArray(zodType.options) && zodType.options.length > 0) return [key, zodType.options[0]];
37
+ if (zodType instanceof z$1.ZodEnum && Array.isArray(zodType.options) && zodType.options.length > 0) return [key, zodType.options[0]];
38
38
  return [key, ""];
39
39
  }
40
40
  return [key, typeof result.data === "string" ? result.data : void 0];