better-convex 0.6.1 → 0.6.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.
@@ -1,6 +1,6 @@
1
1
  import { t as GenericCtx } from "../context-utils-DSuX99Da.js";
2
2
  import { convex } from "@convex-dev/better-auth/plugins";
3
- import * as better_auth_adapters0 from "better-auth/adapters";
3
+ import * as better_auth_adapters1 from "better-auth/adapters";
4
4
  import { DBAdapterDebugLogOption } from "better-auth/adapters";
5
5
  import { BetterAuthDBSchema } from "better-auth/db";
6
6
  import * as convex_server24 from "convex/server";
@@ -45,19 +45,19 @@ declare const createClient: <DataModel extends GenericDataModel, Schema extends
45
45
  }) => {
46
46
  authFunctions: AuthFunctions;
47
47
  triggers: Triggers<DataModel, Schema, TriggerCtx> | undefined;
48
- adapter: (ctx: GenericCtx<DataModel>, getAuthOptions: (ctx: any) => BetterAuthOptions) => better_auth_adapters0.AdapterFactory;
48
+ adapter: (ctx: GenericCtx<DataModel>, getAuthOptions: (ctx: any) => BetterAuthOptions) => better_auth_adapters1.AdapterFactory;
49
49
  triggersApi: () => {
50
50
  beforeCreate: convex_server24.RegisteredMutation<"internal", {
51
- model: string;
52
51
  data: any;
52
+ model: string;
53
53
  }, Promise<any>>;
54
54
  beforeDelete: convex_server24.RegisteredMutation<"internal", {
55
55
  model: string;
56
56
  doc: any;
57
57
  }, Promise<any>>;
58
58
  beforeUpdate: convex_server24.RegisteredMutation<"internal", {
59
- model: string;
60
59
  update: any;
60
+ model: string;
61
61
  doc: any;
62
62
  }, Promise<any>>;
63
63
  onCreate: convex_server24.RegisteredMutation<"internal", {
@@ -150,7 +150,7 @@ declare const httpAdapter: <DataModel extends GenericDataModel, Schema extends S
150
150
  debugLogs?: DBAdapterDebugLogOption;
151
151
  schema?: Schema;
152
152
  triggers?: Triggers<DataModel, Schema>;
153
- }) => better_auth_adapters0.AdapterFactory;
153
+ }) => better_auth_adapters1.AdapterFactory;
154
154
  declare const dbAdapter: <DataModel extends GenericDataModel, Schema extends SchemaDefinition<any, any>>(ctx: GenericCtx<DataModel>, getAuthOptions: (ctx: any) => BetterAuthOptions, {
155
155
  authFunctions,
156
156
  debugLogs,
@@ -161,7 +161,7 @@ declare const dbAdapter: <DataModel extends GenericDataModel, Schema extends Sch
161
161
  schema: Schema;
162
162
  debugLogs?: DBAdapterDebugLogOption;
163
163
  triggers?: Triggers<DataModel, Schema>;
164
- }) => better_auth_adapters0.AdapterFactory;
164
+ }) => better_auth_adapters1.AdapterFactory;
165
165
  //#endregion
166
166
  //#region src/auth/adapter-utils.d.ts
167
167
  type AdapterPaginationOptions = PaginationOptions & {
@@ -181,8 +181,8 @@ declare const adapterWhereValidator: convex_values0.VObject<{
181
181
  }, "required", "connector" | "field" | "operator" | "value">;
182
182
  declare const adapterArgsValidator: convex_values0.VObject<{
183
183
  limit?: number | undefined;
184
- offset?: number | undefined;
185
184
  select?: string[] | undefined;
185
+ offset?: number | undefined;
186
186
  sortBy?: {
187
187
  field: string;
188
188
  direction: "asc" | "desc";
@@ -222,7 +222,7 @@ declare const adapterArgsValidator: convex_values0.VObject<{
222
222
  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>;
223
223
  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>;
224
224
  }, "required", "connector" | "field" | "operator" | "value">, "optional">;
225
- }, "required", "limit" | "model" | "offset" | "select" | "sortBy" | "where" | "sortBy.field" | "sortBy.direction">;
225
+ }, "required", "limit" | "model" | "select" | "offset" | "sortBy" | "where" | "sortBy.field" | "sortBy.direction">;
226
226
  declare const hasUniqueFields: (betterAuthSchema: BetterAuthDBSchema, model: string, input: Record<string, any>) => boolean;
227
227
  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>;
228
228
  declare const selectFields: <T extends TableNamesInDataModel<GenericDataModel>, D extends DocumentByName<GenericDataModel, T>>(doc: D | null, select?: string[]) => Promise<D | null>;
@@ -324,15 +324,15 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>>(schema: Sch
324
324
  beforeCreateHandle?: string | undefined;
325
325
  onCreateHandle?: string | undefined;
326
326
  input: {
327
- model: string;
328
327
  data: any;
329
- } | {
330
328
  model: string;
329
+ } | {
331
330
  data: {
332
331
  [x: string]: unknown;
333
332
  [x: number]: unknown;
334
333
  [x: symbol]: unknown;
335
334
  };
335
+ model: string;
336
336
  };
337
337
  }, Promise<any>>;
338
338
  deleteMany: convex_server24.RegisteredMutation<"internal", {
@@ -383,8 +383,8 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>>(schema: Sch
383
383
  };
384
384
  }, Promise<convex_server24.GenericDocument | undefined>>;
385
385
  findMany: convex_server24.RegisteredQuery<"internal", {
386
- join?: any;
387
386
  limit?: number | undefined;
387
+ join?: any;
388
388
  offset?: number | undefined;
389
389
  sortBy?: {
390
390
  field: string;
@@ -396,7 +396,6 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>>(schema: Sch
396
396
  field: string;
397
397
  value: string | number | boolean | string[] | number[] | null;
398
398
  }[] | undefined;
399
- model: string;
400
399
  paginationOpts: {
401
400
  id?: number;
402
401
  endCursor?: string | null;
@@ -405,6 +404,7 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>>(schema: Sch
405
404
  numItems: number;
406
405
  cursor: string | null;
407
406
  };
407
+ model: string;
408
408
  }, Promise<convex_server24.PaginationResult<convex_server24.GenericDocument>>>;
409
409
  findOne: convex_server24.RegisteredQuery<"internal", {
410
410
  join?: any;
@@ -430,8 +430,8 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>>(schema: Sch
430
430
  };
431
431
  input: {
432
432
  where?: any[] | undefined;
433
- model: string;
434
433
  update: any;
434
+ model: string;
435
435
  } | {
436
436
  where?: {
437
437
  connector?: "AND" | "OR" | undefined;
@@ -439,12 +439,12 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>>(schema: Sch
439
439
  field: string;
440
440
  value: string | number | boolean | string[] | number[] | null;
441
441
  }[] | undefined;
442
- model: string;
443
442
  update: {
444
443
  [x: string]: unknown;
445
444
  [x: number]: unknown;
446
445
  [x: symbol]: unknown;
447
446
  };
447
+ model: string;
448
448
  };
449
449
  }, Promise<{
450
450
  count: number;
@@ -459,8 +459,8 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>>(schema: Sch
459
459
  onUpdateHandle?: string | undefined;
460
460
  input: {
461
461
  where?: any[] | undefined;
462
- model: string;
463
462
  update: any;
463
+ model: string;
464
464
  } | {
465
465
  where?: {
466
466
  connector?: "AND" | "OR" | undefined;
@@ -468,12 +468,12 @@ declare const createApi: <Schema extends SchemaDefinition<any, any>>(schema: Sch
468
468
  field: string;
469
469
  value: string | number | boolean | string[] | number[] | null;
470
470
  }[] | undefined;
471
- model: string;
472
471
  update: {
473
472
  [x: string]: unknown;
474
473
  [x: number]: unknown;
475
474
  [x: symbol]: unknown;
476
475
  };
476
+ model: string;
477
477
  };
478
478
  }, Promise<any>>;
479
479
  getLatestJwks: convex_server24.RegisteredAction<"internal", {}, Promise<any>>;
@@ -1,5 +1,5 @@
1
1
  import { a as partial, h as asyncMap, l as isQueryCtx, n as customCtx, r as customMutation, u as isRunMutationCtx } from "../customFunctions-C1okqCzL.js";
2
- import { C as stream, D as unsetToken, L as eq, S as mergedStream } from "../orm-Banm-XXb.js";
2
+ import { C as stream, D as unsetToken, L as eq, S as mergedStream } from "../orm-CleikBIV.js";
3
3
  import { convex } from "@convex-dev/better-auth/plugins";
4
4
  import { createAdapterFactory } from "better-auth/adapters";
5
5
  import { getAuthTables } from "better-auth/db";
@@ -1098,6 +1098,29 @@ const getHeaders = async (ctx, session) => {
1098
1098
  });
1099
1099
  };
1100
1100
 
1101
+ //#endregion
1102
+ //#region src/auth/error-response.ts
1103
+ const isApiErrorLike = (error) => !!error && typeof error === "object" && (error.name === "APIError" && "statusCode" in error || typeof error.statusCode === "number");
1104
+ const toResponseInit = (error) => {
1105
+ const init = {
1106
+ headers: new Headers(error.headers ?? {}),
1107
+ status: typeof error.statusCode === "number" ? error.statusCode : 500
1108
+ };
1109
+ if (typeof error.status === "string") init.statusText = error.status;
1110
+ return init;
1111
+ };
1112
+ const toAuthErrorResponse = (error) => {
1113
+ if (!isApiErrorLike(error)) return null;
1114
+ const init = toResponseInit(error);
1115
+ const { body } = error;
1116
+ if (body === void 0) return new Response(null, init);
1117
+ if (typeof body === "string") {
1118
+ if (init.headers instanceof Headers && !init.headers.has("content-type")) init.headers.set("content-type", "text/plain");
1119
+ return new Response(body, init);
1120
+ }
1121
+ return Response.json(body, init);
1122
+ };
1123
+
1101
1124
  //#endregion
1102
1125
  //#region src/auth/middleware.ts
1103
1126
  /**
@@ -1123,7 +1146,15 @@ function authMiddleware(getAuth, opts = {}) {
1123
1146
  if (c.req.path === "/.well-known/openid-configuration") return c.redirect(`${process.env.CONVEX_SITE_URL}${basePath}/convex/.well-known/openid-configuration`);
1124
1147
  if (c.req.path.startsWith(basePath)) {
1125
1148
  if (opts.verbose) console.log("request headers", c.req.raw.headers);
1126
- const response = await getAuth(c.env).handler(c.req.raw);
1149
+ const auth = getAuth(c.env);
1150
+ let response;
1151
+ try {
1152
+ response = await auth.handler(c.req.raw);
1153
+ } catch (error) {
1154
+ const errorResponse = toAuthErrorResponse(error);
1155
+ if (errorResponse) return errorResponse;
1156
+ throw error;
1157
+ }
1127
1158
  if (opts.verbose) console.log("response headers", response.headers);
1128
1159
  return response;
1129
1160
  }
@@ -1395,7 +1426,15 @@ const registerRoutes = (http, getAuth, opts = {}) => {
1395
1426
  console.log("options.baseURL", staticAuth.options.baseURL);
1396
1427
  console.log("request headers", request.headers);
1397
1428
  }
1398
- const response = await getAuth(ctx).handler(request);
1429
+ const auth = getAuth(ctx);
1430
+ let response;
1431
+ try {
1432
+ response = await auth.handler(request);
1433
+ } catch (error) {
1434
+ const errorResponse = toAuthErrorResponse(error);
1435
+ if (errorResponse) return errorResponse;
1436
+ throw error;
1437
+ }
1399
1438
  if (opts?.verbose) console.log("response headers", response.headers);
1400
1439
  return response;
1401
1440
  });
@@ -530,6 +530,28 @@ declare class ConvexSystemIdBuilder<_TTableName extends string> extends ColumnBu
530
530
  */
531
531
  get convexValidator(): convex_values69.VString<string, "required">;
532
532
  }
533
+ /**
534
+ * System creation time field builder (_creationTime)
535
+ * Always present, always non-null, always a number (milliseconds)
536
+ */
537
+ type ConvexSystemCreationTimeConfig = ColumnBuilderBaseConfig<'number', 'ConvexSystemCreationTime'> & {
538
+ data: number;
539
+ driverParam: number;
540
+ enumValues: undefined;
541
+ };
542
+ declare class ConvexSystemCreationTimeBuilder extends ColumnBuilder<ConvexSystemCreationTimeConfig, {}, {
543
+ notNull: true;
544
+ }> {
545
+ static readonly [entityKind]: string;
546
+ readonly [entityKind]: string;
547
+ constructor();
548
+ build(): convex_values69.VFloat64<number, "required">;
549
+ /**
550
+ * Convex validator - runtime access
551
+ * System fields use v.number() for _creationTime
552
+ */
553
+ get convexValidator(): convex_values69.VFloat64<number, "required">;
554
+ }
533
555
  type ConvexSystemCreatedAtConfig = ColumnBuilderBaseConfig<'number', 'ConvexSystemCreatedAt'> & {
534
556
  data: number;
535
557
  driverParam: number;
@@ -551,9 +573,13 @@ declare class ConvexSystemCreatedAtBuilder extends ColumnBuilder<ConvexSystemCre
551
573
  type SystemFields<TName extends string> = {
552
574
  id: ColumnBuilderWithTableName<ConvexSystemIdBuilder<TName>, TName>;
553
575
  };
576
+ type InternalSystemFields<TName extends string> = {
577
+ _creationTime: ColumnBuilderWithTableName<ConvexSystemCreationTimeBuilder, TName>;
578
+ };
554
579
  type SystemFieldAliases<TName extends string, TColumns extends Record<string, unknown> = {}> = 'createdAt' extends keyof TColumns ? {} : {
555
580
  createdAt: ColumnBuilderWithTableName<ConvexSystemCreatedAtBuilder, TName>;
556
581
  };
582
+ type SystemFieldsWithAliases<TName extends string, TColumns extends Record<string, unknown> = {}> = SystemFields<TName> & InternalSystemFields<TName> & SystemFieldAliases<TName, TColumns>;
557
583
  //#endregion
558
584
  //#region src/orm/builders/text.d.ts
559
585
  /**
@@ -926,7 +952,6 @@ declare function or(...expressions: (FilterExpression<boolean> | undefined)[]):
926
952
  declare function not(expression: FilterExpression<boolean>): UnaryExpression;
927
953
  /**
928
954
  * Array membership operator: field IN array
929
- * Validates array is non-empty at construction time
930
955
  *
931
956
  * @example
932
957
  * const filter = inArray(cols.status, ['active', 'pending']);
@@ -1644,7 +1669,7 @@ declare function rlsRole(name: string, config?: RlsRoleConfig): RlsRole;
1644
1669
  //#endregion
1645
1670
  //#region src/orm/rls/policies.d.ts
1646
1671
  type RlsPolicyToOption = 'public' | 'current_role' | 'current_user' | 'session_user' | (string & {}) | RlsRole | RlsPolicyToOption[];
1647
- type PolicyExpression<TCtx, TTable> = FilterExpression<boolean> | ((ctx: TCtx, table: TTable) => FilterExpression<boolean>);
1672
+ type PolicyExpression<TCtx, TTable> = FilterExpression<boolean> | ((ctx: TCtx, table: TTable) => FilterExpression<boolean> | Promise<FilterExpression<boolean>>);
1648
1673
  interface RlsPolicyConfig<TCtx = any, TTable = ConvexTableWithColumns<any>> {
1649
1674
  as?: 'permissive' | 'restrictive';
1650
1675
  for?: 'all' | 'select' | 'insert' | 'update' | 'delete';
@@ -1684,6 +1709,7 @@ type ColumnsWithTableName<TColumns, TName extends string> = { [K in keyof TColum
1684
1709
  fieldName: K extends string ? K : never;
1685
1710
  };
1686
1711
  } : TColumns[K] };
1712
+ type ColumnsWithSystemFields<TColumns, TName extends string> = ColumnsWithTableName<TColumns, TName> & (TColumns extends Record<string, unknown> ? SystemFieldsWithAliases<TName, TColumns> : SystemFieldsWithAliases<TName>);
1687
1713
  type ConvexTableExtraConfigValue = ConvexIndexBuilder | ConvexSearchIndexBuilder | ConvexVectorIndexBuilder | ConvexForeignKeyBuilder | ConvexCheckBuilder | ConvexUniqueConstraintBuilder | ConvexDeletionBuilder | ConvexLifecycleBuilder | OrmTriggerLike | RlsPolicy;
1688
1714
  type ConvexTableExtraConfig = Record<string, ConvexTableExtraConfigValue>;
1689
1715
  type UnionToIntersection<T> = (T extends unknown ? (arg: T) => void : never) extends ((arg: infer U) => void) ? U : never;
@@ -1877,7 +1903,7 @@ type ConvexTableWithColumns<T extends TableConfig, Indexes extends GenericTableI
1877
1903
  * index('by_email').on(t.email),
1878
1904
  * ]);
1879
1905
  */
1880
- type ConvexTableFnInternal = <TName extends string, TColumns, TExtraConfig extends ConvexTableExtraConfigValue[] | ConvexTableExtraConfig | undefined = undefined>(name: TName, columns: TColumns, extraConfig?: (self: ColumnsWithTableName<TColumns, TName>) => TExtraConfig) => ConvexTableWithColumns<{
1906
+ type ConvexTableFnInternal = <TName extends string, TColumns, TExtraConfig extends ConvexTableExtraConfigValue[] | ConvexTableExtraConfig | undefined = undefined>(name: TName, columns: TColumns, extraConfig?: (self: ColumnsWithSystemFields<TColumns, TName>) => TExtraConfig) => ConvexTableWithColumns<{
1881
1907
  name: TName;
1882
1908
  columns: ColumnsWithTableName<TColumns, TName>;
1883
1909
  }, InferDbIndexesFromExtraConfig<TExtraConfig>, InferSearchIndexesFromExtraConfig<TExtraConfig>, InferVectorIndexesFromExtraConfig<TExtraConfig>>;
package/dist/orm/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import { $ as or, A as Brand, B as gte, D as unsetToken, E as OrmNotFoundError, F as contains, G as isNull, H as inArray, I as endsWith, J as lte, K as like, L as eq, M as TableName, N as and, O as RlsRole, P as between, Q as notInArray, R as fieldRef, T as desc, U as isFieldReference, V as ilike, W as isNotNull, X as not, Y as ne, Z as notBetween, _ as onInsert, a as getTableConfig, at as timestamp, b as rlsPolicy, c as uniqueIndex, ct as integer, d as scheduledMutationBatchFactory, dt as custom, et as startsWith, f as scheduledDeleteFactory, ft as json, g as onDelete, h as onChange, ht as bigint, i as getTableColumns, it as vector, j as Columns, k as rlsRole, l as vectorIndex, lt as id, m as deletion, mt as boolean, n as defineRelations, nt as foreignKey, o as index, ot as textEnum, p as convexTable, pt as bytes, q as lt, r as defineRelationsPart, rt as unique, s as searchIndex, st as text, t as defineSchema, tt as check, u as createOrm, ut as date, v as onUpdate, w as asc, x as extractRelationsConfig, y as RlsPolicy, z as gt } from "../orm-Banm-XXb.js";
1
+ import { $ as or, A as Brand, B as gte, D as unsetToken, E as OrmNotFoundError, F as contains, G as isNull, H as inArray, I as endsWith, J as lte, K as like, L as eq, M as TableName, N as and, O as RlsRole, P as between, Q as notInArray, R as fieldRef, T as desc, U as isFieldReference, V as ilike, W as isNotNull, X as not, Y as ne, Z as notBetween, _ as onInsert, a as getTableConfig, at as timestamp, b as rlsPolicy, c as uniqueIndex, ct as integer, d as scheduledMutationBatchFactory, dt as custom, et as startsWith, f as scheduledDeleteFactory, ft as json, g as onDelete, h as onChange, ht as bigint, i as getTableColumns, it as vector, j as Columns, k as rlsRole, l as vectorIndex, lt as id, m as deletion, mt as boolean, n as defineRelations, nt as foreignKey, o as index, ot as textEnum, p as convexTable, pt as bytes, q as lt, r as defineRelationsPart, rt as unique, s as searchIndex, st as text, t as defineSchema, tt as check, u as createOrm, ut as date, v as onUpdate, w as asc, x as extractRelationsConfig, y as RlsPolicy, z as gt } from "../orm-CleikBIV.js";
2
2
 
3
3
  export { Brand, Columns, OrmNotFoundError, RlsPolicy, RlsRole, TableName, and, asc, between, bigint, boolean, bytes, check, contains, convexTable, createOrm, custom, date, defineRelations, defineRelationsPart, defineSchema, deletion, desc, endsWith, eq, extractRelationsConfig, fieldRef, foreignKey, getTableColumns, getTableConfig, gt, gte, id, ilike, inArray, index, integer, isFieldReference, isNotNull, isNull, json, like, lt, lte, ne, not, notBetween, notInArray, onChange, onDelete, onInsert, onUpdate, or, rlsPolicy, rlsRole, scheduledDeleteFactory, scheduledMutationBatchFactory, searchIndex, startsWith, text, textEnum, timestamp, unique, uniqueIndex, unsetToken, vector, vectorIndex };
@@ -875,13 +875,11 @@ function not(expression) {
875
875
  }
876
876
  /**
877
877
  * Array membership operator: field IN array
878
- * Validates array is non-empty at construction time
879
878
  *
880
879
  * @example
881
880
  * const filter = inArray(cols.status, ['active', 'pending']);
882
881
  */
883
882
  function inArray(col, values) {
884
- if (!Array.isArray(values) || values.length === 0) throw new Error("inArray requires a non-empty array of values");
885
883
  return new BinaryExpressionImpl("inArray", [fieldRef(resolveColumn(col).columnName), values]);
886
884
  }
887
885
  /**
@@ -1887,6 +1885,7 @@ function toConvexFilter(expression) {
1887
1885
  case "inArray": {
1888
1886
  const values = value;
1889
1887
  return (q) => {
1888
+ if (values.length === 0) return q.eq(q.field("_id"), "__better_convex_never__");
1890
1889
  return values.map((v) => q.eq(q.field(fieldName), v)).reduce((acc, cond) => q.or(acc, cond));
1891
1890
  };
1892
1891
  }
@@ -2068,13 +2067,13 @@ function roleMatches(policy, rls) {
2068
2067
  if (targetRoles === "public") return true;
2069
2068
  return targetRoles.some((role) => roles.includes(role));
2070
2069
  }
2071
- function resolveExpression(policy, checkType, ctx, table) {
2070
+ async function resolveExpression(policy, checkType, ctx, table) {
2072
2071
  const candidate = checkType === "withCheck" ? policy.withCheck ?? policy.using : policy.using;
2073
2072
  if (!candidate) return;
2074
- if (typeof candidate === "function") return candidate(ctx, table);
2073
+ if (typeof candidate === "function") return await candidate(ctx, table);
2075
2074
  return candidate;
2076
2075
  }
2077
- function evaluatePolicySet({ table, operation, checkType, row, rls }) {
2076
+ async function evaluatePolicySet({ table, operation, checkType, row, rls }) {
2078
2077
  if (!isRlsEnabled(table)) return true;
2079
2078
  if (rls?.mode === "skip") return true;
2080
2079
  const ctx = rls?.ctx ?? {};
@@ -2082,18 +2081,24 @@ function evaluatePolicySet({ table, operation, checkType, row, rls }) {
2082
2081
  if (policies.length === 0) return false;
2083
2082
  const permissive = policies.filter((policy) => (policy.as ?? "permissive") !== "restrictive");
2084
2083
  if (permissive.length === 0) return false;
2085
- if (!permissive.some((policy) => {
2086
- const expression = resolveExpression(policy, checkType, ctx, table);
2087
- if (!expression) return true;
2088
- return evaluateFilter(row, expression);
2089
- })) return false;
2090
- return policies.filter((policy) => (policy.as ?? "permissive") === "restrictive").every((policy) => {
2091
- const expression = resolveExpression(policy, checkType, ctx, table);
2092
- if (!expression) return true;
2093
- return evaluateFilter(row, expression);
2094
- });
2084
+ let permissivePasses = false;
2085
+ for (const policy of permissive) {
2086
+ const expression = await resolveExpression(policy, checkType, ctx, table);
2087
+ if (!expression || evaluateFilter(row, expression)) {
2088
+ permissivePasses = true;
2089
+ break;
2090
+ }
2091
+ }
2092
+ if (!permissivePasses) return false;
2093
+ const restrictive = policies.filter((policy) => (policy.as ?? "permissive") === "restrictive");
2094
+ for (const policy of restrictive) {
2095
+ const expression = await resolveExpression(policy, checkType, ctx, table);
2096
+ if (!expression) continue;
2097
+ if (!evaluateFilter(row, expression)) return false;
2098
+ }
2099
+ return true;
2095
2100
  }
2096
- function canSelectRow(options) {
2101
+ async function canSelectRow(options) {
2097
2102
  return evaluatePolicySet({
2098
2103
  table: options.table,
2099
2104
  operation: "select",
@@ -2102,7 +2107,7 @@ function canSelectRow(options) {
2102
2107
  rls: options.rls
2103
2108
  });
2104
2109
  }
2105
- function canInsertRow(options) {
2110
+ async function canInsertRow(options) {
2106
2111
  return evaluatePolicySet({
2107
2112
  table: options.table,
2108
2113
  operation: "insert",
@@ -2111,7 +2116,7 @@ function canInsertRow(options) {
2111
2116
  rls: options.rls
2112
2117
  });
2113
2118
  }
2114
- function canDeleteRow(options) {
2119
+ async function canDeleteRow(options) {
2115
2120
  return evaluatePolicySet({
2116
2121
  table: options.table,
2117
2122
  operation: "delete",
@@ -2120,15 +2125,15 @@ function canDeleteRow(options) {
2120
2125
  rls: options.rls
2121
2126
  });
2122
2127
  }
2123
- function evaluateUpdateDecision(options) {
2124
- const usingAllowed = evaluatePolicySet({
2128
+ async function evaluateUpdateDecision(options) {
2129
+ const usingAllowed = await evaluatePolicySet({
2125
2130
  table: options.table,
2126
2131
  operation: "update",
2127
2132
  checkType: "using",
2128
2133
  row: options.existingRow,
2129
2134
  rls: options.rls
2130
2135
  });
2131
- const withCheckAllowed = evaluatePolicySet({
2136
+ const withCheckAllowed = await evaluatePolicySet({
2132
2137
  table: options.table,
2133
2138
  operation: "update",
2134
2139
  checkType: "withCheck",
@@ -2141,14 +2146,16 @@ function evaluateUpdateDecision(options) {
2141
2146
  withCheckAllowed
2142
2147
  };
2143
2148
  }
2144
- function filterSelectRows(options) {
2149
+ async function filterSelectRows(options) {
2145
2150
  if (!isRlsEnabled(options.table)) return options.rows;
2146
2151
  if (options.rls?.mode === "skip") return options.rows;
2147
- return options.rows.filter((row) => canSelectRow({
2152
+ const rows = [];
2153
+ for (const row of options.rows) if (await canSelectRow({
2148
2154
  table: options.table,
2149
2155
  row,
2150
2156
  rls: options.rls
2151
- }));
2157
+ })) rows.push(row);
2158
+ return rows;
2152
2159
  }
2153
2160
 
2154
2161
  //#endregion
@@ -2919,7 +2926,7 @@ var ConvexDeleteBuilder = class extends QueryPromise {
2919
2926
  };
2920
2927
  const fkBatchSize = isPaginated ? pagination.limit : batchSize;
2921
2928
  for (const row of rows) {
2922
- if (!canDeleteRow({
2929
+ if (!await canDeleteRow({
2923
2930
  table: this.table,
2924
2931
  row,
2925
2932
  rls
@@ -3036,7 +3043,7 @@ var ConvexInsertBuilder = class extends QueryPromise {
3036
3043
  const preparedValue = normalizeDateFieldsForWrite(this.table, applyDefaults(this.table, value));
3037
3044
  const rls = getOrmContext(this.db)?.rls;
3038
3045
  const tableName = getTableName(this.table);
3039
- if (!canInsertRow({
3046
+ if (!await canInsertRow({
3040
3047
  table: this.table,
3041
3048
  row: preparedValue,
3042
3049
  rls
@@ -3110,7 +3117,7 @@ var ConvexInsertBuilder = class extends QueryPromise {
3110
3117
  ...normalizedSet
3111
3118
  };
3112
3119
  const writeSet = normalizeDateFieldsForWrite(this.table, effectiveSet);
3113
- const updateDecision = evaluateUpdateDecision({
3120
+ const updateDecision = await evaluateUpdateDecision({
3114
3121
  table: this.table,
3115
3122
  existingRow: existing,
3116
3123
  updatedRow: {
@@ -4615,9 +4622,9 @@ var GelRelationalQuery = class extends QueryPromise {
4615
4622
  if (this.mode === "firstOrThrow" && first === void 0) throw new OrmNotFoundError(`Could not find ${this.tableConfig.name}.`, this.tableConfig.name);
4616
4623
  return first;
4617
4624
  }
4618
- _applyRlsSelectFilter(rows, tableConfig) {
4625
+ async _applyRlsSelectFilter(rows, tableConfig) {
4619
4626
  if (!rows.length || !tableConfig) return rows;
4620
- return filterSelectRows({
4627
+ return await filterSelectRows({
4621
4628
  table: tableConfig.table,
4622
4629
  rows,
4623
4630
  rls: this.rls
@@ -5598,7 +5605,7 @@ var GelRelationalQuery = class extends QueryPromise {
5598
5605
  if (id === null || id === void 0) return null;
5599
5606
  return this.db.get(id);
5600
5607
  })).filter((row) => !!row);
5601
- rows = this._applyRlsSelectFilter(rows, this.tableConfig);
5608
+ rows = await this._applyRlsSelectFilter(rows, this.tableConfig);
5602
5609
  if (orderSpecs.length > 0 && rows.length > 1) rows.sort((a, b) => this._compareByOrderSpecs(a, b, orderSpecs));
5603
5610
  if (offset > 0) rows = rows.slice(offset);
5604
5611
  if (typeof config.limit === "number") rows = rows.slice(0, config.limit);
@@ -5621,7 +5628,7 @@ var GelRelationalQuery = class extends QueryPromise {
5621
5628
  absoluteMaxRows: pageByKey.absoluteMaxRows,
5622
5629
  order: pageByKey.order
5623
5630
  });
5624
- let rows = this._applyRlsSelectFilter(page.page, this.tableConfig);
5631
+ let rows = await this._applyRlsSelectFilter(page.page, this.tableConfig);
5625
5632
  if (whereFilter) rows = await this._applyRelationsFilterToRows(rows, this.tableConfig, whereFilter, this.edgeMetadata, 0, 3, this.config.with);
5626
5633
  return {
5627
5634
  page: await this._finalizeRows(rows),
@@ -5653,7 +5660,7 @@ var GelRelationalQuery = class extends QueryPromise {
5653
5660
  maxScan
5654
5661
  });
5655
5662
  return {
5656
- page: await this._finalizeRows(this._applyRlsSelectFilter(paginationResult.page, this.tableConfig)),
5663
+ page: await this._finalizeRows(await this._applyRlsSelectFilter(paginationResult.page, this.tableConfig)),
5657
5664
  continueCursor: paginationResult.continueCursor,
5658
5665
  isDone: paginationResult.isDone,
5659
5666
  pageStatus: paginationResult.pageStatus,
@@ -5665,7 +5672,7 @@ var GelRelationalQuery = class extends QueryPromise {
5665
5672
  const limit = this._resolveNonPaginatedLimit(config);
5666
5673
  let rows = limit === void 0 ? await streamQuery.collect() : await streamQuery.take(offset > 0 ? offset + limit : limit);
5667
5674
  if (offset > 0) rows = rows.slice(offset);
5668
- rows = this._applyRlsSelectFilter(rows, this.tableConfig);
5675
+ rows = await this._applyRlsSelectFilter(rows, this.tableConfig);
5669
5676
  const selectedRows = await this._finalizeRows(rows);
5670
5677
  return this._returnSelectedRows(selectedRows);
5671
5678
  }
@@ -5698,7 +5705,7 @@ var GelRelationalQuery = class extends QueryPromise {
5698
5705
  _score: score
5699
5706
  };
5700
5707
  });
5701
- rows = this._applyRlsSelectFilter(rows, this.tableConfig);
5708
+ rows = await this._applyRlsSelectFilter(rows, this.tableConfig);
5702
5709
  const selectedRows = await this._finalizeRows(rows);
5703
5710
  return this._returnSelectedRows(selectedRows);
5704
5711
  }
@@ -5727,7 +5734,7 @@ var GelRelationalQuery = class extends QueryPromise {
5727
5734
  numItems: config.limit
5728
5735
  });
5729
5736
  let pageRows = paginationResult.page;
5730
- pageRows = this._applyRlsSelectFilter(pageRows, this.tableConfig);
5737
+ pageRows = await this._applyRlsSelectFilter(pageRows, this.tableConfig);
5731
5738
  if (whereFilter) pageRows = await this._applyRelationsFilterToRows(pageRows, this.tableConfig, whereFilter, this.edgeMetadata, 0, 3, this.config.with);
5732
5739
  return {
5733
5740
  page: await this._finalizeRows(pageRows),
@@ -5740,7 +5747,7 @@ var GelRelationalQuery = class extends QueryPromise {
5740
5747
  const limit = this._resolveNonPaginatedLimit(config);
5741
5748
  let rows = limit === void 0 ? await searchQuery.collect() : await searchQuery.take(offset > 0 ? offset + limit : limit);
5742
5749
  if (offset > 0) rows = rows.slice(offset);
5743
- rows = this._applyRlsSelectFilter(rows, this.tableConfig);
5750
+ rows = await this._applyRlsSelectFilter(rows, this.tableConfig);
5744
5751
  if (whereFilter) rows = await this._applyRelationsFilterToRows(rows, this.tableConfig, whereFilter, this.edgeMetadata, 0, 3, this.config.with);
5745
5752
  const selectedRows = await this._finalizeRows(rows);
5746
5753
  return this._returnSelectedRows(selectedRows);
@@ -5806,7 +5813,7 @@ var GelRelationalQuery = class extends QueryPromise {
5806
5813
  maxScan
5807
5814
  });
5808
5815
  let pageRows = paginationResult.page;
5809
- pageRows = this._applyRlsSelectFilter(pageRows, this.tableConfig);
5816
+ pageRows = await this._applyRlsSelectFilter(pageRows, this.tableConfig);
5810
5817
  if (whereFilter) pageRows = await this._applyRelationsFilterToRows(pageRows, this.tableConfig, whereFilter, this.edgeMetadata, 0, 3, this.config.with);
5811
5818
  let pageWithRelations = pageRows;
5812
5819
  if (this.config.with) pageWithRelations = await this._loadRelations(pageRows, this.config.with, 0, 3, this.edgeMetadata, this.tableConfig);
@@ -5825,7 +5832,7 @@ var GelRelationalQuery = class extends QueryPromise {
5825
5832
  const paginateAfterPostFetchSort = usePostFetchSort && postFetchOrders.length > 0;
5826
5833
  let rows = limit === void 0 || paginateAfterPostFetchSort ? await streamQuery.collect() : await streamQuery.take(offset > 0 ? offset + limit : limit);
5827
5834
  if (!paginateAfterPostFetchSort && offset > 0) rows = rows.slice(offset);
5828
- rows = this._applyRlsSelectFilter(rows, this.tableConfig);
5835
+ rows = await this._applyRlsSelectFilter(rows, this.tableConfig);
5829
5836
  if (whereFilter) rows = await this._applyRelationsFilterToRows(rows, this.tableConfig, whereFilter, this.edgeMetadata, 0, 3, this.config.with);
5830
5837
  if (usePostFetchSort && postFetchOrders.length > 0) rows = rows.sort((a, b) => this._compareByOrderSpecs(a, b, postFetchOrders));
5831
5838
  if (paginateAfterPostFetchSort) {
@@ -5857,7 +5864,7 @@ var GelRelationalQuery = class extends QueryPromise {
5857
5864
  }));
5858
5865
  let rows = Array.from(new Map(probeRows.flat().map((row) => [String(row._id), row])).values());
5859
5866
  if (queryConfig.postFilters.length > 0) rows = rows.filter((row) => queryConfig.postFilters.every((filter) => this._evaluatePostFetchFilter(row, filter)));
5860
- rows = this._applyRlsSelectFilter(rows, this.tableConfig);
5867
+ rows = await this._applyRlsSelectFilter(rows, this.tableConfig);
5861
5868
  if (whereFilter) rows = await this._applyRelationsFilterToRows(rows, this.tableConfig, whereFilter, this.edgeMetadata, 0, 3, this.config.with);
5862
5869
  if (usePostFetchSort && postFetchOrders.length > 0) rows = rows.sort((a, b) => this._compareByOrderSpecs(a, b, postFetchOrders));
5863
5870
  const offset = config.offset ?? 0;
@@ -5894,7 +5901,7 @@ var GelRelationalQuery = class extends QueryPromise {
5894
5901
  maxScan
5895
5902
  });
5896
5903
  let pageRows = paginationResult.page;
5897
- pageRows = this._applyRlsSelectFilter(pageRows, this.tableConfig);
5904
+ pageRows = await this._applyRlsSelectFilter(pageRows, this.tableConfig);
5898
5905
  if (whereFilter) pageRows = await this._applyRelationsFilterToRows(pageRows, this.tableConfig, whereFilter, this.edgeMetadata, 0, 3, this.config.with);
5899
5906
  let pageWithRelations = pageRows;
5900
5907
  if (this.config.with) pageWithRelations = await this._loadRelations(pageRows, this.config.with, 0, 3, this.edgeMetadata, this.tableConfig);
@@ -5928,7 +5935,7 @@ var GelRelationalQuery = class extends QueryPromise {
5928
5935
  maxScan
5929
5936
  });
5930
5937
  let pageRows = paginationResult.page;
5931
- pageRows = this._applyRlsSelectFilter(pageRows, this.tableConfig);
5938
+ pageRows = await this._applyRlsSelectFilter(pageRows, this.tableConfig);
5932
5939
  if (whereFilter) pageRows = await this._applyRelationsFilterToRows(pageRows, this.tableConfig, whereFilter, this.edgeMetadata, 0, 3, this.config.with);
5933
5940
  let pageWithRelations = pageRows;
5934
5941
  if (this.config.with) pageWithRelations = await this._loadRelations(pageRows, this.config.with, 0, 3, this.edgeMetadata, this.tableConfig);
@@ -5962,7 +5969,7 @@ var GelRelationalQuery = class extends QueryPromise {
5962
5969
  numItems: config.limit
5963
5970
  });
5964
5971
  let pageRows = paginationResult.page;
5965
- pageRows = this._applyRlsSelectFilter(pageRows, this.tableConfig);
5972
+ pageRows = await this._applyRlsSelectFilter(pageRows, this.tableConfig);
5966
5973
  if (whereFilter) pageRows = await this._applyRelationsFilterToRows(pageRows, this.tableConfig, whereFilter, this.edgeMetadata, 0, 3, this.config.with);
5967
5974
  let pageWithRelations = pageRows;
5968
5975
  if (this.config.with) pageWithRelations = await this._loadRelations(pageRows, this.config.with, 0, 3, this.edgeMetadata, this.tableConfig);
@@ -5988,7 +5995,7 @@ var GelRelationalQuery = class extends QueryPromise {
5988
5995
  let rows = limit === void 0 || paginateAfterPostFetchSort ? await query.collect() : await query.take(offset > 0 ? offset + limit : limit);
5989
5996
  if (!paginateAfterPostFetchSort && offset > 0) rows = rows.slice(offset);
5990
5997
  if (queryConfig.postFilters.length > 0) rows = rows.filter((row) => queryConfig.postFilters.every((filter) => this._evaluatePostFetchFilter(row, filter)));
5991
- rows = this._applyRlsSelectFilter(rows, this.tableConfig);
5998
+ rows = await this._applyRlsSelectFilter(rows, this.tableConfig);
5992
5999
  if (whereFilter) rows = await this._applyRelationsFilterToRows(rows, this.tableConfig, whereFilter, this.edgeMetadata, 0, 3, this.config.with);
5993
6000
  if (usePostFetchSort && postFetchOrders.length > 0) rows = rows.sort((a, b) => this._compareByOrderSpecs(a, b, postFetchOrders));
5994
6001
  if (paginateAfterPostFetchSort) {
@@ -6109,6 +6116,7 @@ var GelRelationalQuery = class extends QueryPromise {
6109
6116
  case "inArray": {
6110
6117
  const values = normalizedValue;
6111
6118
  return (q) => {
6119
+ if (values.length === 0) return q.eq(q.field("_id"), "__better_convex_never__");
6112
6120
  return values.map((v) => q.eq(q.field(fieldName), v)).reduce((acc, cond) => q.or(acc, cond));
6113
6121
  };
6114
6122
  }
@@ -6280,7 +6288,7 @@ var GelRelationalQuery = class extends QueryPromise {
6280
6288
  const targetsByKey = /* @__PURE__ */ new Map();
6281
6289
  for (const entry of fetched) targetsByKey.set(entry.key, entry.target ?? null);
6282
6290
  let targets = Array.from(targetsByKey.values()).filter((value) => !!value);
6283
- targets = this._applyRlsSelectFilter(targets, targetTableConfig);
6291
+ targets = await this._applyRlsSelectFilter(targets, targetTableConfig);
6284
6292
  if (relationDefinition?.where) targets = targets.filter((target) => this._evaluateTableFilter(target, targetTableConfig, relationDefinition.where));
6285
6293
  if (relationConfig && typeof relationConfig === "object" && "where" in relationConfig) {
6286
6294
  const whereFilter = relationConfig.where;
@@ -6414,7 +6422,7 @@ var GelRelationalQuery = class extends QueryPromise {
6414
6422
  return await query.collect();
6415
6423
  })).flat();
6416
6424
  }
6417
- targets = this._applyRlsSelectFilter(targets, targetTableConfig);
6425
+ targets = await this._applyRlsSelectFilter(targets, targetTableConfig);
6418
6426
  if (relationDefinition?.where) targets = targets.filter((target) => this._evaluateTableFilter(target, targetTableConfig, relationDefinition.where));
6419
6427
  if (relationConfig && typeof relationConfig === "object" && "where" in relationConfig) {
6420
6428
  const whereFilter = relationConfig.where;
@@ -6948,7 +6956,7 @@ var ConvexUpdateBuilder = class extends QueryPromise {
6948
6956
  const rls = ormContext?.rls;
6949
6957
  const foreignKeyGraph = ormContext?.foreignKeyGraph;
6950
6958
  if (!foreignKeyGraph) throw new Error("Foreign key actions require orm.db(ctx) configured from createOrm({ schema, ... }).");
6951
- const updates = rows.map((row) => {
6959
+ const updates = await Promise.all(rows.map(async (row) => {
6952
6960
  const updatedRow = {
6953
6961
  ...row,
6954
6962
  ...effectiveSet
@@ -6956,14 +6964,14 @@ var ConvexUpdateBuilder = class extends QueryPromise {
6956
6964
  return {
6957
6965
  row,
6958
6966
  updatedRow,
6959
- decision: evaluateUpdateDecision({
6967
+ decision: await evaluateUpdateDecision({
6960
6968
  table: this.table,
6961
6969
  existingRow: row,
6962
6970
  updatedRow,
6963
6971
  rls
6964
6972
  })
6965
6973
  };
6966
- });
6974
+ }));
6967
6975
  if (updates.find(({ decision }) => decision.usingAllowed && !decision.withCheckAllowed)) throw new Error(`RLS policy violation for update on table "${tableName}"`);
6968
6976
  const results = [];
6969
6977
  let numAffected = 0;
@@ -8021,7 +8029,7 @@ const convexTableInternal = (name, columns, extraConfig) => {
8021
8029
  configurable: true,
8022
8030
  writable: false
8023
8031
  });
8024
- applyExtraConfig(rawTable, extraConfig?.(rawTable[Columns]));
8032
+ applyExtraConfig(rawTable, extraConfig?.(table));
8025
8033
  return table;
8026
8034
  };
8027
8035
  const convexTableWithRLS = (name, columns, extraConfig) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "better-convex",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "description": "Better Convex - React Query integration and CLI tools for Convex",
5
5
  "keywords": [
6
6
  "convex",