better-convex 0.7.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/aggregate/index.d.ts +1 -1
  2. package/dist/aggregate/index.js +1 -1
  3. package/dist/auth/http/index.d.ts +1 -1
  4. package/dist/auth/index.d.ts +10 -10
  5. package/dist/auth/index.js +5 -4
  6. package/dist/auth/nextjs/index.d.ts +2 -2
  7. package/dist/auth/nextjs/index.js +2 -2
  8. package/dist/{caller-factory-D3OuR1eI.js → caller-factory-CCsm4Dut.js} +2 -2
  9. package/dist/cli.mjs +414 -5
  10. package/dist/{codegen-Cz1idI3-.mjs → codegen-BS36cYTH.mjs} +88 -5
  11. package/dist/{create-schema-orm-69VF4CFV.js → create-schema-orm-OcyA0apQ.js} +10 -13
  12. package/dist/crpc/index.d.ts +2 -2
  13. package/dist/crpc/index.js +3 -3
  14. package/dist/customFunctions-RnzME_cJ.js +167 -0
  15. package/dist/{http-types-BCf2wCgp.d.ts → http-types-BK7FuIcR.d.ts} +1 -1
  16. package/dist/id-BcBb900m.js +121 -0
  17. package/dist/orm/index.d.ts +4 -3
  18. package/dist/orm/index.js +706 -165
  19. package/dist/plugins/index.d.ts +9 -0
  20. package/dist/plugins/index.js +3 -0
  21. package/dist/plugins/ratelimit/index.d.ts +222 -0
  22. package/dist/plugins/ratelimit/index.js +846 -0
  23. package/dist/plugins/ratelimit/react/index.d.ts +76 -0
  24. package/dist/plugins/ratelimit/react/index.js +294 -0
  25. package/dist/{procedure-caller-CcjtUFvL.d.ts → procedure-caller-DYjpq7rG.d.ts} +4 -19
  26. package/dist/rsc/index.d.ts +3 -3
  27. package/dist/rsc/index.js +4 -4
  28. package/dist/runtime-C0WcYGY0.js +1028 -0
  29. package/dist/schema-Bx6j2doh.js +204 -0
  30. package/dist/server/index.d.ts +2 -2
  31. package/dist/server/index.js +4 -3
  32. package/dist/{runtime-B9xQFY8W.js → table-B7yzBihE.js} +3 -1088
  33. package/dist/text-enum-CFdcLUuw.js +30 -0
  34. package/dist/{types-CIBGEYXq.d.ts → types-f53SgpBL.d.ts} +1 -1
  35. package/dist/validators-BcQFm1oY.d.ts +88 -0
  36. package/dist/{customFunctions-CZnCwoR3.js → validators-D_i3BK7v.js} +67 -165
  37. package/dist/watcher.mjs +1 -1
  38. package/dist/{where-clause-compiler-CRP-i1Qa.d.ts → where-clause-compiler-BIjTkVVJ.d.ts} +138 -2
  39. package/package.json +4 -1
  40. /package/dist/{create-schema-BdZOL6ns.js → create-schema-BsN0jL5S.js} +0 -0
  41. /package/dist/{error-Be4OcwwD.js → error-CAGGSN5H.js} +0 -0
  42. /package/dist/{meta-utils-DDVYp9Xf.js → meta-utils-NRyocOSc.js} +0 -0
  43. /package/dist/{query-context-BDSis9rT.js → query-context-DEUFBhXS.js} +0 -0
  44. /package/dist/{query-context-DGExXZIV.d.ts → query-context-ji7By8u0.d.ts} +0 -0
  45. /package/dist/{query-options-B0c1b6pZ.js → query-options-CSCmKYdJ.js} +0 -0
  46. /package/dist/{transformer-Dh0w2py0.js → transformer-ogg-4d78.js} +0 -0
  47. /package/dist/{types-DwGkkq2s.d.ts → types-BTb_4BaU.d.ts} +0 -0
  48. /package/dist/{types-DgwvxKbT.d.ts → types-CM67ko7K.d.ts} +0 -0
@@ -0,0 +1,30 @@
1
+ import { T as entityKind, w as ConvexColumnBuilder } from "./table-B7yzBihE.js";
2
+ import { v } from "convex/values";
3
+
4
+ //#region src/orm/builders/text-enum.ts
5
+ var ConvexTextEnumBuilder = class extends ConvexColumnBuilder {
6
+ static [entityKind] = "ConvexTextEnumBuilder";
7
+ constructor(name, values) {
8
+ super(name, "string", "ConvexText");
9
+ this.config.values = [...values];
10
+ }
11
+ _enumValidator() {
12
+ const literals = this.config.values.map((value) => v.literal(value));
13
+ if (literals.length === 1) return literals[0];
14
+ return v.union(...literals);
15
+ }
16
+ get convexValidator() {
17
+ const base = this._enumValidator();
18
+ if (this.config.notNull) return base;
19
+ return v.optional(v.union(v.null(), base));
20
+ }
21
+ build() {
22
+ return this.convexValidator;
23
+ }
24
+ };
25
+ function textEnum(values) {
26
+ return new ConvexTextEnumBuilder("", values);
27
+ }
28
+
29
+ //#endregion
30
+ export { textEnum as t };
@@ -1,4 +1,4 @@
1
- import { n as DeepPartial, o as Simplify, r as DistributiveOmit } from "./types-DwGkkq2s.js";
1
+ import { n as DeepPartial, o as Simplify, r as DistributiveOmit } from "./types-BTb_4BaU.js";
2
2
  import { FunctionArgs, FunctionReference, FunctionReturnType } from "convex/server";
3
3
  import { DefaultError, QueryFilters, SkipToken, UseMutationOptions, UseQueryOptions } from "@tanstack/react-query";
4
4
  import { Watch, WatchQueryOptions } from "convex/react";
@@ -0,0 +1,88 @@
1
+ import { GenericId, GenericValidator, Infer, ObjectType, OptionalProperty, PropertyValidators, VAny, VArray, VBoolean, VBytes, VFloat64, VId, VInt64, VLiteral, VNull, VObject, VOptional, VRecord, VString, VUnion, Validator, v } from "convex/values";
2
+ import { GenericDataModel, GenericDatabaseReader, SchemaDefinition, TableNamesInDataModel } from "convex/server";
3
+
4
+ //#region src/internal/upstream/validators.d.ts
5
+ /** Mark fields as deprecated with this permissive validator typed as null */
6
+ declare const deprecated: Validator<null, "optional">;
7
+ /** A maximally permissive validator that type checks as a given validator.
8
+ *
9
+ * If you want to have types that match some validator but you have invalid data
10
+ * and you want to temporarily not validate schema for this field,
11
+ * you can use this function to cast the permissive validator.
12
+ *
13
+ * Example in a schema:
14
+ * ```ts
15
+ * export default defineSchema({
16
+ * myTable: defineTable({
17
+ * myString: pretend(v.array(v.string())),
18
+ * }),
19
+ * });
20
+ * //...in some mutation
21
+ * ctx.db.insert("myTable", { myString: 123 as any }); // no runtime error
22
+ * ```
23
+ * Example in function argument validation:
24
+ * ```ts
25
+ * const myQuery = defineQuery({
26
+ * args: { myNumber: pretend(v.number()) },
27
+ * handler: async (ctx, args) => {
28
+ * // args.myNumber is typed as number, but it's not validated.
29
+ * const num = typeof args.myNumber === "number" ?
30
+ * args.myNumber : Number(args.myNumber);
31
+ * },
32
+ * });
33
+ */
34
+ declare const pretend: <T extends GenericValidator>(_typeToImmitate: T) => T;
35
+ /** A validator that validates as optional but type checks as required.
36
+ *
37
+ * If you want to assume a field is set for type checking, but your data may not
38
+ * actually have it set for all documents (e.g. when adding a new field),
39
+ * you can use this function to allow the field to be unset at runtime.
40
+ * This is unsafe, but can be convenient in these situations:
41
+ *
42
+ * 1. You are developing locally and want to add a required field and write
43
+ * code assuming it is set. Once you push the code & schema, you can update
44
+ * the data to match before running your code.
45
+ * 2. You are going to run a migration right after pushing code, and are ok with
46
+ * and you don't want to edit your code to handle the field being unset,
47
+ * your app being in an inconsistent state until the migration completes.
48
+ *
49
+ * This differs from {@link pretend} in that it type checks the inner validator,
50
+ * if the value is provided.
51
+ *
52
+ * Example in a schema:
53
+ * ```ts
54
+ * export default defineSchema({
55
+ * myTable: defineTable({
56
+ * myString: pretendRequired(v.array(v.string())),
57
+ * }),
58
+ * });
59
+ * //...in some mutation
60
+ * ctx.db.insert("myTable", { myString: undefined }); // no runtime error
61
+ * ```
62
+ * Example in function argument validation:
63
+ * ```ts
64
+ * const myQuery = defineQuery({
65
+ * args: { myNumber: pretendRequired(v.number()) },
66
+ * handler: async (ctx, args) => {
67
+ * // args.myNumber is typed as number, but it might be undefined
68
+ * const num = args.myNumber || 0;
69
+ * },
70
+ * });
71
+ */
72
+ declare const pretendRequired: <T extends Validator<any, "required", any>>(optionalType: T) => T;
73
+ type NotUndefined<T> = Exclude<T, undefined>;
74
+ /**
75
+ * A type that converts an optional validator to a required validator.
76
+ *
77
+ * This is the inverse of `VOptional`. It takes a validator that may be optional
78
+ * and returns the equivalent required validator type.
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * type OptionalString = VOptional<VString<string, "required">>;
83
+ * type RequiredString = VRequired<OptionalString>; // VString<string, "required">
84
+ * ```
85
+ */
86
+ type VRequired<T extends Validator<any, OptionalProperty, any>> = T extends VId<infer Type, OptionalProperty> ? VId<NotUndefined<Type>, 'required'> : T extends VString<infer Type, OptionalProperty> ? VString<NotUndefined<Type>, 'required'> : T extends VFloat64<infer Type, OptionalProperty> ? VFloat64<NotUndefined<Type>, 'required'> : T extends VInt64<infer Type, OptionalProperty> ? VInt64<NotUndefined<Type>, 'required'> : T extends VBoolean<infer Type, OptionalProperty> ? VBoolean<NotUndefined<Type>, 'required'> : T extends VNull<infer Type, OptionalProperty> ? VNull<NotUndefined<Type>, 'required'> : T extends VAny<infer Type, OptionalProperty> ? VAny<NotUndefined<Type>, 'required'> : T extends VLiteral<infer Type, OptionalProperty> ? VLiteral<NotUndefined<Type>, 'required'> : T extends VBytes<infer Type, OptionalProperty> ? VBytes<NotUndefined<Type>, 'required'> : T extends VObject<infer Type, infer Fields, OptionalProperty, infer FieldPaths> ? VObject<NotUndefined<Type>, Fields, 'required', FieldPaths> : T extends VArray<infer Type, infer Element, OptionalProperty> ? VArray<NotUndefined<Type>, Element, 'required'> : T extends VRecord<infer Type, infer Key, infer Value, OptionalProperty, infer FieldPaths> ? VRecord<NotUndefined<Type>, Key, Value, 'required', FieldPaths> : T extends VUnion<infer Type, infer Members, OptionalProperty, infer FieldPaths> ? VUnion<NotUndefined<Type>, Members, 'required', FieldPaths> : never;
87
+ //#endregion
88
+ export { pretendRequired as i, deprecated as n, pretend as r, VRequired as t };
@@ -82,29 +82,6 @@ function assert(value, message) {
82
82
  if (!value) throw new Error(typeof message === "function" ? message() : message);
83
83
  }
84
84
 
85
- //#endregion
86
- //#region src/server/context-utils.ts
87
- const isQueryCtx = (ctx) => "db" in ctx;
88
- const isMutationCtx = (ctx) => "db" in ctx && "scheduler" in ctx;
89
- const isActionCtx = (ctx) => "runAction" in ctx;
90
- const isRunMutationCtx = (ctx) => "runMutation" in ctx;
91
- const requireQueryCtx = (ctx) => {
92
- if (!isQueryCtx(ctx)) throw new Error("Query context required");
93
- return ctx;
94
- };
95
- const requireMutationCtx = (ctx) => {
96
- if (!isMutationCtx(ctx)) throw new Error("Mutation context required");
97
- return ctx;
98
- };
99
- const requireActionCtx = (ctx) => {
100
- if (!isActionCtx(ctx)) throw new Error("Action context required");
101
- return ctx;
102
- };
103
- const requireRunMutationCtx = (ctx) => {
104
- if (!isRunMutationCtx(ctx)) throw new Error("Mutation or action context required");
105
- return ctx;
106
- };
107
-
108
85
  //#endregion
109
86
  //#region src/internal/upstream/validators.ts
110
87
  function partial(fieldsOrObjOrUnion) {
@@ -193,6 +170,72 @@ function intersectValidators(fields, fields2) {
193
170
  }
194
171
  /** Mark fields as deprecated with this permissive validator typed as null */
195
172
  const deprecated = v.optional(v.any());
173
+ /** A maximally permissive validator that type checks as a given validator.
174
+ *
175
+ * If you want to have types that match some validator but you have invalid data
176
+ * and you want to temporarily not validate schema for this field,
177
+ * you can use this function to cast the permissive validator.
178
+ *
179
+ * Example in a schema:
180
+ * ```ts
181
+ * export default defineSchema({
182
+ * myTable: defineTable({
183
+ * myString: pretend(v.array(v.string())),
184
+ * }),
185
+ * });
186
+ * //...in some mutation
187
+ * ctx.db.insert("myTable", { myString: 123 as any }); // no runtime error
188
+ * ```
189
+ * Example in function argument validation:
190
+ * ```ts
191
+ * const myQuery = defineQuery({
192
+ * args: { myNumber: pretend(v.number()) },
193
+ * handler: async (ctx, args) => {
194
+ * // args.myNumber is typed as number, but it's not validated.
195
+ * const num = typeof args.myNumber === "number" ?
196
+ * args.myNumber : Number(args.myNumber);
197
+ * },
198
+ * });
199
+ */
200
+ const pretend = (_typeToImmitate) => v.optional(v.any());
201
+ /** A validator that validates as optional but type checks as required.
202
+ *
203
+ * If you want to assume a field is set for type checking, but your data may not
204
+ * actually have it set for all documents (e.g. when adding a new field),
205
+ * you can use this function to allow the field to be unset at runtime.
206
+ * This is unsafe, but can be convenient in these situations:
207
+ *
208
+ * 1. You are developing locally and want to add a required field and write
209
+ * code assuming it is set. Once you push the code & schema, you can update
210
+ * the data to match before running your code.
211
+ * 2. You are going to run a migration right after pushing code, and are ok with
212
+ * and you don't want to edit your code to handle the field being unset,
213
+ * your app being in an inconsistent state until the migration completes.
214
+ *
215
+ * This differs from {@link pretend} in that it type checks the inner validator,
216
+ * if the value is provided.
217
+ *
218
+ * Example in a schema:
219
+ * ```ts
220
+ * export default defineSchema({
221
+ * myTable: defineTable({
222
+ * myString: pretendRequired(v.array(v.string())),
223
+ * }),
224
+ * });
225
+ * //...in some mutation
226
+ * ctx.db.insert("myTable", { myString: undefined }); // no runtime error
227
+ * ```
228
+ * Example in function argument validation:
229
+ * ```ts
230
+ * const myQuery = defineQuery({
231
+ * args: { myNumber: pretendRequired(v.number()) },
232
+ * handler: async (ctx, args) => {
233
+ * // args.myNumber is typed as number, but it might be undefined
234
+ * const num = args.myNumber || 0;
235
+ * },
236
+ * });
237
+ */
238
+ const pretendRequired = (optionalType) => v.optional(optionalType);
196
239
  /**
197
240
  * Converts an optional validator to a required validator.
198
241
  *
@@ -233,145 +276,4 @@ function vRequired(validator) {
233
276
  }
234
277
 
235
278
  //#endregion
236
- //#region src/internal/upstream/server/customFunctions.ts
237
- /**
238
- * A helper for defining a Customization when your mod doesn't need to add or remove
239
- * anything from args.
240
- * @param modifyCtx A function that defines how to modify the ctx.
241
- * @returns A ctx delta to be applied to the original ctx.
242
- */
243
- function customCtx(modifyCtx) {
244
- return {
245
- args: {},
246
- input: async (ctx, _, extra) => ({
247
- ctx: await modifyCtx(ctx, extra),
248
- args: {}
249
- })
250
- };
251
- }
252
- /**
253
- * A Customization that doesn't add or remove any context or args.
254
- */
255
- const NoOp = {
256
- args: {},
257
- input() {
258
- return {
259
- args: {},
260
- ctx: {}
261
- };
262
- }
263
- };
264
- /**
265
- * customMutation helps define custom behavior on top of `mutation`
266
- * or `internalMutation` by passing a function that modifies the ctx and args.
267
- *
268
- * Example usage:
269
- * ```js
270
- * const myMutationBuilder = customMutation(mutation, {
271
- * args: { sessionId: v.id("sessions") },
272
- * input: async (ctx, args) => {
273
- * const user = await getUserOrNull(ctx);
274
- * const session = await db.get(sessionId);
275
- * const db = wrapDatabaseReader({ user }, ctx.db, rlsRules);
276
- * return {
277
- * ctx: { db, user, session },
278
- * args: {},
279
- * onSuccess: ({ result }) => {
280
- * // Optional callback that runs after the function executes
281
- * // Has access to resources created during input processing
282
- * console.log(`User ${user.name} returned:`, result);
283
- * }
284
- * };
285
- * },
286
- * });
287
- *
288
- * // Using the custom builder
289
- * export const setSomeData = myMutationBuilder({
290
- * args: { someArg: v.string() },
291
- * handler: async (ctx, args) => {
292
- * const { db, user, session, scheduler } = ctx;
293
- * const { someArg } = args;
294
- * // ...
295
- * }
296
- * });
297
- * ```
298
- *
299
- * Simple usage only modifying ctx:
300
- * ```js
301
- * const myUserMutation = customMutation(
302
- * mutation,
303
- * customCtx(async (ctx) => {
304
- * return {
305
- * // Throws an exception if the user isn't logged in
306
- * user: await getUserByTokenIdentifier(ctx),
307
- * };
308
- * })
309
- * );
310
- *
311
- * // Using it
312
- * export const setMyName = myUserMutation({
313
- * args: { name: v.string() },
314
- * handler: async (ctx, args) => {
315
- * await ctx.db.patch(ctx.user._id, { name: args.name });
316
- * },
317
- * });
318
- *
319
- * @param mutation The mutation to be modified. Usually `mutation` or `internalMutation`
320
- * from `_generated/server`.
321
- * @param customization The modifier to be applied to the mutation, changing ctx and args.
322
- * @returns A new mutation builder to define queries with modified ctx and args.
323
- */
324
- function customMutation(mutation, customization) {
325
- return customFnBuilder(mutation, customization);
326
- }
327
- function customFnBuilder(builder, customization) {
328
- const customInput = customization.input ?? NoOp.input;
329
- const inputArgs = customization.args ?? NoOp.args;
330
- return function customBuilder(fn) {
331
- const { args, handler = fn, returns, ...extra } = fn;
332
- if (args) return builder({
333
- args: addFieldsToValidator(args, inputArgs),
334
- returns,
335
- handler: async (ctx, allArgs) => {
336
- const added = await customInput(ctx, pick(allArgs, Object.keys(inputArgs)), extra);
337
- const args = omit(allArgs, Object.keys(inputArgs));
338
- const result = await handler({
339
- ...ctx,
340
- ...added.ctx
341
- }, {
342
- ...args,
343
- ...added.args
344
- });
345
- if (added.onSuccess) await added.onSuccess({
346
- ctx,
347
- args,
348
- result
349
- });
350
- return result;
351
- }
352
- });
353
- if (Object.keys(inputArgs).length > 0) throw new Error("If you're using a custom function with arguments for the input customization, you must declare the arguments for the function too.");
354
- return builder({
355
- returns: fn.returns,
356
- handler: async (ctx, args) => {
357
- const added = await customInput(ctx, args, extra);
358
- const result = await handler({
359
- ...ctx,
360
- ...added.ctx
361
- }, {
362
- ...args,
363
- ...added.args
364
- });
365
- if (added.onSuccess) await added.onSuccess({
366
- ctx,
367
- args,
368
- result
369
- });
370
- return result;
371
- }
372
- });
373
- };
374
- }
375
-
376
- //#endregion
377
- export { partial as a, isMutationCtx as c, requireActionCtx as d, requireMutationCtx as f, pick as g, asyncMap as h, addFieldsToValidator as i, isQueryCtx as l, requireRunMutationCtx as m, customCtx as n, vRequired as o, requireQueryCtx as p, customMutation as r, isActionCtx as s, NoOp as t, isRunMutationCtx as u };
279
+ export { pretendRequired as a, omit as c, pretend as i, pick as l, deprecated as n, vRequired as o, partial as r, asyncMap as s, addFieldsToValidator as t };
package/dist/watcher.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as getConvexConfig, t as generateMeta } from "./codegen-Cz1idI3-.mjs";
2
+ import { n as getConvexConfig, t as generateMeta } from "./codegen-BS36cYTH.mjs";
3
3
  import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
 
@@ -1,4 +1,4 @@
1
- import { a as ReturnTypeOrValue, i as KnownKeysOnly, o as Simplify, t as Assume } from "./types-DwGkkq2s.js";
1
+ import { a as ReturnTypeOrValue, i as KnownKeysOnly, o as Simplify, t as Assume } from "./types-BTb_4BaU.js";
2
2
  import * as convex_values0 from "convex/values";
3
3
  import { GenericId, Validator, Value } from "convex/values";
4
4
  import { DefineSchemaOptions, FilterExpression, GenericDatabaseReader, GenericDatabaseWriter, GenericIndexFields, GenericSchema, GenericTableIndexes, GenericTableSearchIndexes, GenericTableVectorIndexes, IndexRange, IndexRangeBuilder, SchedulableFunctionReference, Scheduler, SchemaDefinition, TableDefinition, VectorFilterBuilder, internalActionGeneric, internalMutationGeneric } from "convex/server";
@@ -336,6 +336,11 @@ type OrmTableDeleteConfig = {
336
336
  mode: OrmDeleteMode;
337
337
  delayMs?: number;
338
338
  };
339
+ type OrmSchemaPlugin = {
340
+ key: string;
341
+ tableNames: readonly string[];
342
+ inject: <TSchema extends Record<string, unknown>>(schema: TSchema) => TSchema & Record<string, unknown>;
343
+ };
339
344
  declare const TableName: unique symbol;
340
345
  declare const Columns: unique symbol;
341
346
  declare const Brand: unique symbol;
@@ -343,6 +348,7 @@ declare const RlsPolicies: unique symbol;
343
348
  declare const EnableRLS: unique symbol;
344
349
  declare const TableDeleteConfig: unique symbol;
345
350
  declare const OrmSchemaDefinition: unique symbol;
351
+ declare const OrmSchemaPluginTables: unique symbol;
346
352
  //#endregion
347
353
  //#region src/orm/filter-expression.d.ts
348
354
  /**
@@ -2071,6 +2077,19 @@ declare function bytes<TName extends string>(name: TName): ConvexBytesBuilderIni
2071
2077
  //#endregion
2072
2078
  //#region src/orm/builders/custom.d.ts
2073
2079
  type AnyValidator = Validator<any, any, any>;
2080
+ type AnyColumnBuilder = ColumnBuilder<any, any, any>;
2081
+ interface NestedShapeInput {
2082
+ [key: string]: NestedInput;
2083
+ }
2084
+ type NestedInput = AnyValidator | AnyColumnBuilder | NestedShapeInput;
2085
+ type InferBuilderNestedValue<TBuilder extends AnyColumnBuilder> = TBuilder['_'] extends {
2086
+ $type: infer TType;
2087
+ } ? TType : TBuilder['_'] extends {
2088
+ data: infer TData;
2089
+ } ? TData : never;
2090
+ type InferValidatorNestedValue<TValidator extends AnyValidator> = Exclude<TValidator['type'], undefined>;
2091
+ type InferNestedValue<TInput extends NestedInput> = TInput extends AnyColumnBuilder ? InferBuilderNestedValue<TInput> : TInput extends AnyValidator ? InferValidatorNestedValue<TInput> : TInput extends NestedShapeInput ? InferObjectShape<TInput> : never;
2092
+ type InferObjectShape<TShape extends NestedShapeInput> = { [K in keyof TShape]: InferNestedValue<TShape[K]> };
2074
2093
  type ConvexCustomBuilderInitial<TName extends string, TValidator extends AnyValidator> = ConvexCustomBuilder<{
2075
2094
  name: TName;
2076
2095
  dataType: 'any';
@@ -2089,6 +2108,18 @@ declare class ConvexCustomBuilder<T extends ColumnBuilderBaseConfig<'any', 'Conv
2089
2108
  }
2090
2109
  declare function custom<TValidator extends AnyValidator>(validator: TValidator): ConvexCustomBuilderInitial<'', TValidator>;
2091
2110
  declare function custom<TName extends string, TValidator extends AnyValidator>(name: TName, validator: TValidator): ConvexCustomBuilderInitial<TName, TValidator>;
2111
+ /**
2112
+ * Creates an array column from a nested validator or builder.
2113
+ *
2114
+ * Values in nested arrays are always compiled as required validators.
2115
+ */
2116
+ declare function arrayOf<TElement extends NestedInput>(element: TElement): $Type<ConvexCustomBuilderInitial<"", convex_values0.VArray<any[], AnyValidator, "required">>, InferNestedValue<TElement>[]>;
2117
+ /**
2118
+ * Creates an object column from a nested shape of validators/builders.
2119
+ *
2120
+ * Fields in nested objects are always compiled as required validators.
2121
+ */
2122
+ declare function objectOf<TShape extends NestedShapeInput>(shape: TShape): $Type<ConvexCustomBuilderInitial<"", AnyValidator>, InferObjectShape<TShape>>;
2092
2123
  /**
2093
2124
  * Convenience wrapper for Convex "JSON" values.
2094
2125
  *
@@ -3195,6 +3226,104 @@ type CreateDatabaseOptions = {
3195
3226
  };
3196
3227
  };
3197
3228
  //#endregion
3229
+ //#region src/orm/migrations/definitions.d.ts
3230
+ type MigrationDirection = 'up' | 'down';
3231
+ type MigrationRunStatus = 'pending' | 'running' | 'completed' | 'failed' | 'canceled' | 'dry_run' | 'noop';
3232
+ type MigrationWriteMode = 'safe_bypass' | 'normal';
3233
+ type MigrationTableName<TSchema extends TablesRelationalConfig = TablesRelationalConfig> = { [K in keyof TSchema]-?: TSchema[K] extends TableRelationalConfig ? TSchema[K]['name'] : never }[keyof TSchema] & string;
3234
+ type MigrationTableConfigByName<TSchema extends TablesRelationalConfig, TTableName extends MigrationTableName<TSchema>> = { [K in keyof TSchema]-?: TSchema[K] extends TableRelationalConfig ? TSchema[K]['name'] extends TTableName ? TSchema[K] : never : never }[keyof TSchema];
3235
+ type MigrationDoc<TSchema extends TablesRelationalConfig = TablesRelationalConfig, TTableName extends MigrationTableName<TSchema> = MigrationTableName<TSchema>> = MigrationTableConfigByName<TSchema, TTableName> extends TableRelationalConfig ? Partial<InferSelectModel<MigrationTableConfigByName<TSchema, TTableName>['table']>> & Record<string, unknown> : Record<string, unknown>;
3236
+ type MigrationDocContext<TSchema extends TablesRelationalConfig = TablesRelationalConfig> = {
3237
+ db: GenericDatabaseWriter<any>;
3238
+ orm: OrmWriter<TSchema>;
3239
+ migrationId: string;
3240
+ runId: string;
3241
+ direction: MigrationDirection;
3242
+ dryRun: boolean;
3243
+ writeMode: MigrationWriteMode;
3244
+ };
3245
+ type MigrationMigrateOne<TSchema extends TablesRelationalConfig = TablesRelationalConfig, TTableName extends MigrationTableName<TSchema> = MigrationTableName<TSchema>> = (ctx: MigrationDocContext<TSchema>, doc: MigrationDoc<TSchema, TTableName>) => Promise<unknown> | unknown;
3246
+ type MigrationStepByTable<TSchema extends TablesRelationalConfig = TablesRelationalConfig, TTableName extends MigrationTableName<TSchema> = MigrationTableName<TSchema>> = {
3247
+ table: TTableName;
3248
+ batchSize?: number;
3249
+ writeMode?: MigrationWriteMode;
3250
+ migrateOne: MigrationMigrateOne<TSchema, TTableName>;
3251
+ };
3252
+ type MigrationStep<TSchema extends TablesRelationalConfig = TablesRelationalConfig> = { [TTableName in MigrationTableName<TSchema>]: MigrationStepByTable<TSchema, TTableName> }[MigrationTableName<TSchema>];
3253
+ type MigrationDefinition<TSchema extends TablesRelationalConfig = TablesRelationalConfig> = {
3254
+ id: string;
3255
+ name?: string;
3256
+ description?: string;
3257
+ up: MigrationStep<TSchema>;
3258
+ down?: MigrationStep<TSchema>;
3259
+ checksum?: string;
3260
+ };
3261
+ type MigrationManifestEntry<TSchema extends TablesRelationalConfig = TablesRelationalConfig> = MigrationDefinition<TSchema> & {
3262
+ checksum: string;
3263
+ };
3264
+ type MigrationSet<TSchema extends TablesRelationalConfig = TablesRelationalConfig> = {
3265
+ migrations: readonly MigrationManifestEntry<TSchema>[];
3266
+ ids: readonly string[];
3267
+ byId: Readonly<Record<string, MigrationManifestEntry<TSchema>>>;
3268
+ };
3269
+ type MigrationAppliedState = {
3270
+ applied: boolean;
3271
+ checksum?: string;
3272
+ cursor?: string | null;
3273
+ processed?: number;
3274
+ };
3275
+ type MigrationStateMap = Readonly<Record<string, MigrationAppliedState>>;
3276
+ type MigrationDriftIssue = {
3277
+ kind: 'missing_from_manifest';
3278
+ migrationId: string;
3279
+ message: string;
3280
+ } | {
3281
+ kind: 'checksum_mismatch';
3282
+ migrationId: string;
3283
+ message: string;
3284
+ expectedChecksum: string;
3285
+ actualChecksum: string;
3286
+ };
3287
+ type MigrationPlan<TSchema extends TablesRelationalConfig = TablesRelationalConfig> = {
3288
+ direction: MigrationDirection;
3289
+ migrations: readonly MigrationManifestEntry<TSchema>[];
3290
+ };
3291
+ declare function defineMigration<TSchema extends TablesRelationalConfig = TablesRelationalConfig>(migration: MigrationDefinition<TSchema>): MigrationDefinition<TSchema>;
3292
+ declare function defineMigrationSet<TSchema extends TablesRelationalConfig = TablesRelationalConfig>(migrations: readonly MigrationDefinition<TSchema>[]): MigrationSet<TSchema>;
3293
+ declare function detectMigrationDrift<TSchema extends TablesRelationalConfig = TablesRelationalConfig>(params: {
3294
+ migrationSet: MigrationSet<TSchema>;
3295
+ appliedState: MigrationStateMap;
3296
+ }): MigrationDriftIssue[];
3297
+ declare function buildMigrationPlan<TSchema extends TablesRelationalConfig = TablesRelationalConfig>(params: {
3298
+ direction: MigrationDirection;
3299
+ migrationSet: MigrationSet<TSchema>;
3300
+ appliedState: MigrationStateMap;
3301
+ steps?: number;
3302
+ to?: string;
3303
+ }): MigrationPlan<TSchema>;
3304
+ //#endregion
3305
+ //#region src/orm/migrations/runtime.d.ts
3306
+ type MigrationRunArgs = {
3307
+ direction?: MigrationDirection;
3308
+ steps?: number;
3309
+ to?: string;
3310
+ dryRun?: boolean;
3311
+ allowDrift?: boolean;
3312
+ batchSize?: number;
3313
+ restart?: boolean;
3314
+ };
3315
+ type MigrationRunChunkArgs = {
3316
+ runId: string;
3317
+ batchSize?: number;
3318
+ };
3319
+ type MigrationStatusArgs = {
3320
+ runId?: string;
3321
+ limit?: number;
3322
+ };
3323
+ type MigrationCancelArgs = {
3324
+ runId?: string;
3325
+ };
3326
+ //#endregion
3198
3327
  //#region src/orm/triggers.d.ts
3199
3328
  type MaybePromise<T> = T | Promise<T>;
3200
3329
  type AnyRecord = Record<string, unknown>;
@@ -3286,6 +3415,7 @@ type OrmFunctions = {
3286
3415
  scheduledMutationBatch: SchedulableFunctionReference;
3287
3416
  scheduledDelete: SchedulableFunctionReference;
3288
3417
  aggregateBackfillChunk?: SchedulableFunctionReference;
3418
+ migrationRunChunk?: SchedulableFunctionReference;
3289
3419
  resetChunk?: SchedulableFunctionReference;
3290
3420
  };
3291
3421
  type CreateOrmOptions = CreateDatabaseOptions;
@@ -3314,6 +3444,7 @@ type GenericOrmCtx<Ctx extends {
3314
3444
  type CreateOrmConfigBase<TSchema extends TablesRelationalConfig> = {
3315
3445
  schema: TSchema;
3316
3446
  triggers?: OrmTriggers<TSchema, any>;
3447
+ migrations?: MigrationSet<any>;
3317
3448
  internalMutation?: typeof internalMutationGeneric;
3318
3449
  };
3319
3450
  type CreateOrmConfigWithFunctions<TSchema extends TablesRelationalConfig> = CreateOrmConfigBase<TSchema> & {
@@ -3329,6 +3460,10 @@ type OrmApiResult = {
3329
3460
  aggregateBackfill: ReturnType<typeof internalMutationGeneric>;
3330
3461
  aggregateBackfillChunk: ReturnType<typeof internalMutationGeneric>;
3331
3462
  aggregateBackfillStatus: ReturnType<typeof internalMutationGeneric>;
3463
+ migrationRun: ReturnType<typeof internalMutationGeneric>;
3464
+ migrationRunChunk: ReturnType<typeof internalMutationGeneric>;
3465
+ migrationStatus: ReturnType<typeof internalMutationGeneric>;
3466
+ migrationCancel: ReturnType<typeof internalMutationGeneric>;
3332
3467
  resetChunk: ReturnType<typeof internalMutationGeneric>;
3333
3468
  reset: ReturnType<typeof internalActionGeneric>;
3334
3469
  };
@@ -3418,6 +3553,7 @@ declare function desc<TBuilder extends ColumnBuilder<any, any, any>>(builder: TB
3418
3553
  type BetterConvexSchemaOptions<StrictTableNameTypes extends boolean> = DefineSchemaOptions<StrictTableNameTypes> & {
3419
3554
  strict?: boolean;
3420
3555
  defaults?: OrmRuntimeDefaults;
3556
+ plugins?: readonly OrmSchemaPlugin[];
3421
3557
  };
3422
3558
  /**
3423
3559
  * Better Convex schema definition
@@ -3460,4 +3596,4 @@ interface IndexLike {
3460
3596
  indexName: string;
3461
3597
  }
3462
3598
  //#endregion
3463
- export { ConvexIdBuilder as $, VectorSearchProvider as $n, ConvexRankIndexBuilderOn as $t, DatabaseWithQuery as A, FilterOperators as An, Columns as Ar, defineRelations as At, ConvexTimestampBuilder as B, MutationPaginatedResult as Bn, DrizzleEntity as Br, deletion as Bt, OrmBeforeResult as C, AggregateFieldValue as Cn, ne as Cr, ManyConfig as Ct, OrmTriggers as D, CountConfig as Dn, or as Dr, RelationsBuilderColumnConfig as Dt, OrmTriggerContext as E, BuildRelationResult as En, notInArray as Er, RelationsBuilderColumnBase as Et, EdgeMetadata as F, InsertValue as Fn, ColumnBuilderBaseConfig as Fr, ConvexTableWithColumns as Ft, ConvexTextEnumBuilderInitial as G, OrderDirection as Gn, RlsRole as Gt, ConvexTimestampMode as H, MutationReturning as Hn, IsPrimaryKey as Hr, RlsPolicyConfig as Ht, extractRelationsConfig as I, MutationExecuteConfig as In, ColumnBuilderRuntimeConfig as Ir, OrmLifecycleChange as It, ConvexTextBuilderInitial as J, ReturningAll as Jn, ConvexAggregateIndexBuilder as Jt, textEnum as K, PaginatedResult as Kn, RlsRoleConfig as Kt, ConvexVectorBuilder as L, MutationExecuteResult as Ln, ColumnBuilderTypeConfig as Lr, OrmLifecycleOperation as Lt, OrmWriter as M, InferInsertModel as Mn, SystemFields as Mr, ConvexDeletionBuilder as Mt, RlsContext as N, InferModelFromColumns as Nn, AnyColumn as Nr, ConvexDeletionConfig as Nt, defineTriggers as O, CountResult as On, startsWith as Or, TableRelationalConfig as Ot, RlsMode as P, InferSelectModel as Pn, ColumnBuilder as Pr, ConvexTable as Pt, integer as Q, VectorQueryConfig as Qn, ConvexRankIndexBuilder as Qt, ConvexVectorBuilderInitial as R, MutationExecutionMode as Rn, ColumnBuilderWithTableName as Rr, TableConfig as Rt, scheduledDeleteFactory as S, AggregateConfig as Sn, lte as Sr, ExtractTablesWithRelations as St, OrmTriggerChange as T, BuildQueryResult as Tn, notBetween as Tr, RelationsBuilder as Tt, timestamp as U, MutationRunMode as Un, IsUnique as Ur, RlsPolicyToOption as Ut, ConvexTimestampBuilderInitial as V, MutationResult as Vn, HasDefault as Vr, RlsPolicy as Vt, ConvexTextEnumBuilder as W, OrderByClause as Wn, NotNull as Wr, rlsPolicy as Wt, ConvexNumberBuilder as X, ReturningSelection as Xn, ConvexIndexBuilder as Xt, text as Y, ReturningResult as Yn, ConvexAggregateIndexBuilderOn as Yt, ConvexNumberBuilderInitial as Z, UpdateSet as Zn, ConvexIndexBuilderOn as Zt, OrmWriterCtx as _, ConvexUniqueConstraintBuilderOn as _n, isFieldReference as _r, ConvexBigIntBuilderInitial as _t, TableConfigResult as a, ConvexVectorIndexConfig as an, LogicalExpression as ar, date as at, scheduledMutationBatchFactory as b, foreignKey as bn, like as br, CountBackfillKickoffArgs as bt, OrmNotFoundError as c, rankIndex as cn, between as cr, custom as ct, GenericOrmCtx as d, vectorIndex as dn, eq as dr, ConvexBytesBuilderInitial as dt, ConvexSearchIndexBuilder as en, unsetToken as er, ConvexIdBuilderInitial as et, OrmApiResult as f, ConvexCheckBuilder as fn, fieldRef as fr, bytes as ft, OrmReaderCtx as g, ConvexUniqueConstraintBuilder as gn, inArray as gr, ConvexBigIntBuilder as gt, OrmFunctions as h, ConvexForeignKeyConfig as hn, ilike as hr, boolean as ht, desc as i, ConvexVectorIndexBuilderOn as in, FilterExpression$1 as ir, ConvexDateMode as it, OrmReader as j, GetColumnData as jn, TableName as jr, defineRelationsPart as jt, DatabaseWithMutations as k, DBQueryConfig as kn, Brand as kr, TablesRelationalConfig as kt, CreateOrmOptions as l, searchIndex as ln, contains as lr, json as lt, OrmClientWithApi as m, ConvexForeignKeyBuilder as mn, gte as mr, ConvexBooleanBuilderInitial as mt, defineSchema$1 as n, ConvexSearchIndexConfig as nn, ExpressionVisitor as nr, ConvexDateBuilder as nt, getTableColumns as o, aggregateIndex as on, UnaryExpression as or, ConvexCustomBuilder as ot, OrmClientBase as p, ConvexCheckConfig as pn, gt as pr, ConvexBooleanBuilder as pt, ConvexTextBuilder as q, PredicateWhereIndexConfig as qn, rlsRole as qt, asc as r, ConvexVectorIndexBuilder as rn, FieldReference as rr, ConvexDateBuilderInitial as rt, getTableConfig as s, index as sn, and as sr, ConvexCustomBuilderInitial as st, WhereClauseResult as t, ConvexSearchIndexBuilderOn as tn, BinaryExpression as tr, id as tt, GenericOrm as u, uniqueIndex as un, endsWith as ur, ConvexBytesBuilder as ut, createOrm as v, ConvexUniqueConstraintConfig as vn, isNotNull as vr, bigint as vt, OrmTableTriggers as w, AggregateResult as wn, not as wr, OneConfig as wt, ScheduledDeleteArgs as x, unique as xn, lt as xr, CountBackfillStatusArgs as xt, ScheduledMutationBatchArgs as y, check as yn, isNull as yr, CountBackfillChunkArgs as yt, vector as z, MutationPaginateConfig as zn, ColumnDataType as zr, convexTable as zt };
3599
+ export { DatabaseWithQuery as $, CountResult as $n, startsWith as $r, TableRelationalConfig as $t, MigrationRunArgs as A, ConvexVectorIndexConfig as An, LogicalExpression as Ar, ConvexCustomBuilderInitial as At, MigrationMigrateOne as B, ConvexForeignKeyConfig as Bn, ilike as Br, boolean as Bt, OrmBeforeResult as C, ConvexRankIndexBuilder as Cn, VectorQueryConfig as Cr, ConvexIdBuilderInitial as Ct, OrmTriggers as D, ConvexSearchIndexConfig as Dn, ExpressionVisitor as Dr, ConvexDateMode as Dt, OrmTriggerContext as E, ConvexSearchIndexBuilderOn as En, BinaryExpression as Er, ConvexDateBuilderInitial as Et, MigrationDirection as F, uniqueIndex as Fn, endsWith as Fr, ConvexBytesBuilder as Ft, MigrationStep as G, foreignKey as Gn, like as Gr, CountBackfillKickoffArgs as Gt, MigrationRunStatus as H, ConvexUniqueConstraintBuilderOn as Hn, isFieldReference as Hr, ConvexBigIntBuilderInitial as Ht, MigrationDoc as I, vectorIndex as In, eq as Ir, ConvexBytesBuilderInitial as It, buildMigrationPlan as J, AggregateFieldValue as Jn, ne as Jr, ManyConfig as Jt, MigrationTableName as K, unique as Kn, lt as Kr, CountBackfillStatusArgs as Kt, MigrationDocContext as L, ConvexCheckBuilder as Ln, fieldRef as Lr, bytes as Lt, MigrationStatusArgs as M, index as Mn, and as Mr, custom as Mt, MigrationAppliedState as N, rankIndex as Nn, between as Nr, json as Nt, defineTriggers as O, ConvexVectorIndexBuilder as On, FieldReference as Or, date as Ot, MigrationDefinition as P, searchIndex as Pn, contains as Pr, objectOf as Pt, DatabaseWithMutations as Q, CountConfig as Qn, or as Qr, RelationsBuilderColumnConfig as Qt, MigrationDriftIssue as R, ConvexCheckConfig as Rn, gt as Rr, ConvexBooleanBuilder as Rt, scheduledDeleteFactory as S, ConvexIndexBuilderOn as Sn, UpdateSet as Sr, ConvexIdBuilder as St, OrmTriggerChange as T, ConvexSearchIndexBuilder as Tn, unsetToken as Tr, ConvexDateBuilder as Tt, MigrationSet as U, ConvexUniqueConstraintConfig as Un, isNotNull as Ur, bigint as Ut, MigrationPlan as V, ConvexUniqueConstraintBuilder as Vn, inArray as Vr, ConvexBigIntBuilder as Vt, MigrationStateMap as W, check as Wn, isNull as Wr, CountBackfillChunkArgs as Wt, defineMigrationSet as X, BuildQueryResult as Xn, notBetween as Xr, RelationsBuilder as Xt, defineMigration as Y, AggregateResult as Yn, not as Yr, OneConfig as Yt, detectMigrationDrift as Z, BuildRelationResult as Zn, notInArray as Zr, RelationsBuilderColumnBase as Zt, OrmWriterCtx as _, NotNull as _i, RlsRoleConfig as _n, PaginatedResult as _r, ConvexTextBuilderInitial as _t, TableConfigResult as a, SystemFields as ai, ConvexTable as an, InferSelectModel as ar, extractRelationsConfig as at, scheduledMutationBatchFactory as b, ConvexAggregateIndexBuilderOn as bn, ReturningResult as br, ConvexNumberBuilderInitial as bt, OrmNotFoundError as c, ColumnBuilderBaseConfig as ci, OrmLifecycleOperation as cn, MutationExecuteResult as cr, vector as ct, GenericOrmCtx as d, ColumnBuilderWithTableName as di, deletion as dn, MutationPaginatedResult as dr, ConvexTimestampMode as dt, Brand as ei, TablesRelationalConfig as en, DBQueryConfig as er, OrmReader as et, OrmApiResult as f, ColumnDataType as fi, RlsPolicy as fn, MutationResult as fr, timestamp as ft, OrmReaderCtx as g, IsUnique as gi, RlsRole as gn, OrderDirection as gr, ConvexTextBuilder as gt, OrmFunctions as h, IsPrimaryKey as hi, rlsPolicy as hn, OrderByClause as hr, textEnum as ht, desc as i, TableName as ii, ConvexDeletionConfig as in, InferModelFromColumns as ir, EdgeMetadata as it, MigrationRunChunkArgs as j, aggregateIndex as jn, UnaryExpression as jr, arrayOf as jt, MigrationCancelArgs as k, ConvexVectorIndexBuilderOn as kn, FilterExpression$1 as kr, ConvexCustomBuilder as kt, CreateOrmOptions as l, ColumnBuilderRuntimeConfig as li, TableConfig as ln, MutationExecutionMode as lr, ConvexTimestampBuilder as lt, OrmClientWithApi as m, HasDefault as mi, RlsPolicyToOption as mn, MutationRunMode as mr, ConvexTextEnumBuilderInitial as mt, defineSchema$1 as n, OrmSchemaPlugin as ni, defineRelationsPart as nn, GetColumnData as nr, RlsContext as nt, getTableColumns as o, AnyColumn as oi, ConvexTableWithColumns as on, InsertValue as or, ConvexVectorBuilder as ot, OrmClientBase as p, DrizzleEntity as pi, RlsPolicyConfig as pn, MutationReturning as pr, ConvexTextEnumBuilder as pt, MigrationWriteMode as q, AggregateConfig as qn, lte as qr, ExtractTablesWithRelations as qt, asc as r, OrmSchemaPluginTables as ri, ConvexDeletionBuilder as rn, InferInsertModel as rr, RlsMode as rt, getTableConfig as s, ColumnBuilder as si, OrmLifecycleChange as sn, MutationExecuteConfig as sr, ConvexVectorBuilderInitial as st, WhereClauseResult as t, Columns as ti, defineRelations as tn, FilterOperators as tr, OrmWriter as tt, GenericOrm as u, ColumnBuilderTypeConfig as ui, convexTable as un, MutationPaginateConfig as ur, ConvexTimestampBuilderInitial as ut, createOrm as v, rlsRole as vn, PredicateWhereIndexConfig as vr, text as vt, OrmTableTriggers as w, ConvexRankIndexBuilderOn as wn, VectorSearchProvider as wr, id as wt, ScheduledDeleteArgs as x, ConvexIndexBuilder as xn, ReturningSelection as xr, integer as xt, ScheduledMutationBatchArgs as y, ConvexAggregateIndexBuilder as yn, ReturningAll as yr, ConvexNumberBuilder as yt, MigrationManifestEntry as z, ConvexForeignKeyBuilder as zn, gte as zr, ConvexBooleanBuilderInitial as zt };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "better-convex",
3
- "version": "0.7.2",
3
+ "version": "0.8.0",
4
4
  "description": "Better Convex - React Query integration and CLI tools for Convex",
5
5
  "keywords": [
6
6
  "convex",
@@ -20,6 +20,9 @@
20
20
  "./auth/nextjs": "./dist/auth/nextjs/index.js",
21
21
  "./crpc": "./dist/crpc/index.js",
22
22
  "./orm": "./dist/orm/index.js",
23
+ "./plugins": "./dist/plugins/index.js",
24
+ "./plugins/ratelimit": "./dist/plugins/ratelimit/index.js",
25
+ "./plugins/ratelimit/react": "./dist/plugins/ratelimit/react/index.js",
23
26
  "./react": "./dist/react/index.js",
24
27
  "./rsc": "./dist/rsc/index.js",
25
28
  "./server": "./dist/server/index.js",
File without changes