kitcn 0.0.1 → 0.12.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 (93) hide show
  1. package/bin/intent.js +3 -0
  2. package/dist/aggregate/index.d.ts +388 -0
  3. package/dist/aggregate/index.js +37 -0
  4. package/dist/api-entry-BckXqaLb.js +66 -0
  5. package/dist/auth/client/index.d.ts +37 -0
  6. package/dist/auth/client/index.js +217 -0
  7. package/dist/auth/config/index.d.ts +45 -0
  8. package/dist/auth/config/index.js +24 -0
  9. package/dist/auth/generated/index.d.ts +2 -0
  10. package/dist/auth/generated/index.js +3 -0
  11. package/dist/auth/http/index.d.ts +64 -0
  12. package/dist/auth/http/index.js +461 -0
  13. package/dist/auth/index.d.ts +221 -0
  14. package/dist/auth/index.js +1398 -0
  15. package/dist/auth/nextjs/index.d.ts +50 -0
  16. package/dist/auth/nextjs/index.js +81 -0
  17. package/dist/auth-store-Cljlmdmi.js +197 -0
  18. package/dist/builder-CBdG5W6A.js +1974 -0
  19. package/dist/caller-factory-cTXNvYdz.js +216 -0
  20. package/dist/cli.mjs +13255 -0
  21. package/dist/codegen-lF80HSWu.mjs +3416 -0
  22. package/dist/context-utils-HPC5nXzx.d.ts +17 -0
  23. package/dist/create-schema-odyF4kCy.js +156 -0
  24. package/dist/create-schema-orm-DOyiNDCx.js +246 -0
  25. package/dist/crpc/index.d.ts +105 -0
  26. package/dist/crpc/index.js +169 -0
  27. package/dist/customFunctions-C0voKmtx.js +144 -0
  28. package/dist/error-BZEnI7Sq.js +41 -0
  29. package/dist/generated-contract-disabled-Cih4eITO.js +50 -0
  30. package/dist/generated-contract-disabled-D-sOFy92.d.ts +354 -0
  31. package/dist/http-types-DqJubRPJ.d.ts +292 -0
  32. package/dist/meta-utils-0Pu0Nrap.js +117 -0
  33. package/dist/middleware-BUybuv9n.d.ts +34 -0
  34. package/dist/middleware-C2qTZ3V7.js +84 -0
  35. package/dist/orm/index.d.ts +17 -0
  36. package/dist/orm/index.js +10713 -0
  37. package/dist/plugins/index.d.ts +2 -0
  38. package/dist/plugins/index.js +3 -0
  39. package/dist/procedure-caller-DtxLmGwA.d.ts +1467 -0
  40. package/dist/procedure-caller-MWcxhQDv.js +349 -0
  41. package/dist/query-context-B8o6-8kC.js +1518 -0
  42. package/dist/query-context-CFZqIvD7.d.ts +42 -0
  43. package/dist/query-options-Dw7cOyXl.js +121 -0
  44. package/dist/ratelimit/index.d.ts +269 -0
  45. package/dist/ratelimit/index.js +856 -0
  46. package/dist/ratelimit/react/index.d.ts +76 -0
  47. package/dist/ratelimit/react/index.js +183 -0
  48. package/dist/react/index.d.ts +1284 -0
  49. package/dist/react/index.js +2526 -0
  50. package/dist/rsc/index.d.ts +276 -0
  51. package/dist/rsc/index.js +233 -0
  52. package/dist/runtime-CtvJPkur.js +2453 -0
  53. package/dist/server/index.d.ts +5 -0
  54. package/dist/server/index.js +6 -0
  55. package/dist/solid/index.d.ts +1221 -0
  56. package/dist/solid/index.js +2940 -0
  57. package/dist/transformer-DtDhR3Lc.js +194 -0
  58. package/dist/types-BTb_4BaU.d.ts +42 -0
  59. package/dist/types-BiJE7qxR.d.ts +4 -0
  60. package/dist/types-DEJpkIhw.d.ts +88 -0
  61. package/dist/types-HhO_R6pd.d.ts +213 -0
  62. package/dist/validators-B7oIJCAp.js +279 -0
  63. package/dist/validators-vzRKjBJC.d.ts +88 -0
  64. package/dist/watcher.mjs +96 -0
  65. package/dist/where-clause-compiler-DdjN63Io.d.ts +4756 -0
  66. package/package.json +107 -35
  67. package/skills/convex/SKILL.md +486 -0
  68. package/skills/convex/references/features/aggregates.md +353 -0
  69. package/skills/convex/references/features/auth-admin.md +446 -0
  70. package/skills/convex/references/features/auth-organizations.md +1141 -0
  71. package/skills/convex/references/features/auth-polar.md +579 -0
  72. package/skills/convex/references/features/auth.md +470 -0
  73. package/skills/convex/references/features/create-plugins.md +153 -0
  74. package/skills/convex/references/features/http.md +676 -0
  75. package/skills/convex/references/features/migrations.md +162 -0
  76. package/skills/convex/references/features/orm.md +1166 -0
  77. package/skills/convex/references/features/react.md +657 -0
  78. package/skills/convex/references/features/scheduling.md +267 -0
  79. package/skills/convex/references/features/testing.md +209 -0
  80. package/skills/convex/references/setup/auth.md +501 -0
  81. package/skills/convex/references/setup/biome.md +190 -0
  82. package/skills/convex/references/setup/doc-guidelines.md +145 -0
  83. package/skills/convex/references/setup/index.md +759 -0
  84. package/skills/convex/references/setup/next.md +116 -0
  85. package/skills/convex/references/setup/react.md +175 -0
  86. package/skills/convex/references/setup/server.md +473 -0
  87. package/skills/convex/references/setup/start.md +67 -0
  88. package/LICENSE +0 -21
  89. package/README.md +0 -0
  90. package/dist/index.d.mts +0 -5
  91. package/dist/index.d.mts.map +0 -1
  92. package/dist/index.mjs +0 -6
  93. package/dist/index.mjs.map +0 -1
@@ -0,0 +1,1398 @@
1
+ import { r as partial, s as asyncMap } from "../validators-B7oIJCAp.js";
2
+ import { i as defineAuth, n as createDisabledAuthRuntime, r as getGeneratedAuthDisabledReason, t as DEFAULT_AUTH_DEFINITION_PATH } from "../generated-contract-disabled-Cih4eITO.js";
3
+ import { n as createGeneratedFunctionReference, o as isQueryCtx, s as isRunMutationCtx } from "../api-entry-BckXqaLb.js";
4
+ import { n as customCtx, r as customMutation } from "../customFunctions-C0voKmtx.js";
5
+ import { a as mergedStream, l as unsetToken, o as stream, t as getByIdWithOrmQueryFallback, v as eq } from "../query-context-B8o6-8kC.js";
6
+ import { v } from "convex/values";
7
+ import { internalActionGeneric, internalMutationGeneric, internalQueryGeneric, paginationOptsValidator } from "convex/server";
8
+ import { convex } from "@convex-dev/better-auth/plugins";
9
+ import { createAdapterFactory } from "better-auth/adapters";
10
+ import { getAuthTables } from "better-auth/db";
11
+ import { prop, sortBy } from "remeda";
12
+ import { stripIndent } from "common-tags";
13
+ import { betterAuth } from "better-auth/minimal";
14
+
15
+ //#region src/auth/adapter-utils.ts
16
+ const adapterWhereValidator = v.object({
17
+ connector: v.optional(v.union(v.literal("AND"), v.literal("OR"))),
18
+ field: v.string(),
19
+ operator: v.optional(v.union(v.literal("lt"), v.literal("lte"), v.literal("gt"), v.literal("gte"), v.literal("eq"), v.literal("in"), v.literal("not_in"), v.literal("ne"), v.literal("contains"), v.literal("starts_with"), v.literal("ends_with"))),
20
+ value: v.union(v.string(), v.number(), v.boolean(), v.array(v.string()), v.array(v.number()), v.null())
21
+ });
22
+ const adapterArgsValidator = v.object({
23
+ limit: v.optional(v.number()),
24
+ model: v.string(),
25
+ offset: v.optional(v.number()),
26
+ select: v.optional(v.array(v.string())),
27
+ sortBy: v.optional(v.object({
28
+ direction: v.union(v.literal("asc"), v.literal("desc")),
29
+ field: v.string()
30
+ })),
31
+ where: v.optional(v.array(adapterWhereValidator))
32
+ });
33
+ const isUniqueField = (betterAuthSchema, model, field) => {
34
+ const modelSchema = betterAuthSchema[Object.keys(betterAuthSchema).find((key) => betterAuthSchema[key].modelName === model) || model];
35
+ if (!modelSchema?.fields) return false;
36
+ return Object.entries(modelSchema.fields).filter(([, value]) => value.unique).map(([key]) => key).includes(field);
37
+ };
38
+ const hasUniqueFields = (betterAuthSchema, model, input) => {
39
+ for (const field of Object.keys(input)) if (isUniqueField(betterAuthSchema, model, field)) return true;
40
+ return false;
41
+ };
42
+ const findIndex = (schema, args) => {
43
+ if ((args.where?.length ?? 0) > 1 && args.where?.some((w) => w.connector === "OR")) throw new Error(`OR connector not supported with multiple where statements in findIndex, split up the where statements before calling findIndex: ${JSON.stringify(args.where)}`);
44
+ const where = args.where?.filter((w) => (!w.operator || [
45
+ "eq",
46
+ "gt",
47
+ "gte",
48
+ "in",
49
+ "lt",
50
+ "lte",
51
+ "not_in"
52
+ ].includes(w.operator)) && w.field !== "_id");
53
+ if (!where?.length && !args.sortBy) return;
54
+ const lowerBounds = where?.filter((w) => w.operator === "lt" || w.operator === "lte") ?? [];
55
+ if (lowerBounds.length > 1) throw new Error(`cannot have more than one lower bound where clause: ${JSON.stringify(where)}`);
56
+ const upperBounds = where?.filter((w) => w.operator === "gt" || w.operator === "gte") ?? [];
57
+ if (upperBounds.length > 1) throw new Error(`cannot have more than one upper bound where clause: ${JSON.stringify(where)}`);
58
+ const lowerBound = lowerBounds[0];
59
+ const upperBound = upperBounds[0];
60
+ if (lowerBound && upperBound && lowerBound.field !== upperBound.field) throw new Error(`lower bound and upper bound must have the same field: ${JSON.stringify(where)}`);
61
+ const boundField = lowerBound?.field || upperBound?.field;
62
+ if (boundField && where?.some((w) => w.field === boundField && w !== lowerBound && w !== upperBound)) throw new Error(`too many where clauses on the bound field: ${JSON.stringify(where)}`);
63
+ const indexEqFields = where?.filter((w) => !w.operator || w.operator === "eq").sort((a, b) => a.field.localeCompare(b.field)).map((w) => [w.field, w.value]) ?? [];
64
+ if (!indexEqFields?.length && !boundField && !args.sortBy) return;
65
+ const table = schema.tables[args.model];
66
+ if (!table) throw new Error(`Table ${args.model} not found`);
67
+ const indexes = table[" indexes"] ? table[" indexes"]() : table.export().indexes;
68
+ const sortField = args.sortBy?.field;
69
+ const indexFields = indexEqFields.map(([field]) => field).concat(boundField && boundField !== "createdAt" ? `${indexEqFields.length > 0 ? "_" : ""}${boundField}` : "").concat(sortField && sortField !== "createdAt" && boundField !== sortField ? `${indexEqFields.length > 0 || boundField ? "_" : ""}${sortField}` : "").filter(Boolean);
70
+ if (indexFields.length === 0 && !boundField && !sortField) return;
71
+ const index = indexFields.length === 0 ? {
72
+ fields: [],
73
+ indexDescriptor: "by_creation_time"
74
+ } : indexes.find(({ fields }) => {
75
+ const fieldsMatch = indexFields.every((field, idx) => field === fields[idx]);
76
+ const boundFieldMatch = boundField === "createdAt" || sortField === "createdAt" ? indexFields.length === fields.length : true;
77
+ return fieldsMatch && boundFieldMatch;
78
+ });
79
+ if (!index) return { indexFields };
80
+ return {
81
+ boundField,
82
+ index: {
83
+ fields: [...index.fields, "_creationTime"],
84
+ indexDescriptor: index.indexDescriptor
85
+ },
86
+ sortField,
87
+ values: {
88
+ eq: indexEqFields.map(([, value]) => value),
89
+ gt: upperBound?.operator === "gt" ? upperBound.value : void 0,
90
+ gte: upperBound?.operator === "gte" ? upperBound.value : void 0,
91
+ lt: lowerBound?.operator === "lt" ? lowerBound.value : void 0,
92
+ lte: lowerBound?.operator === "lte" ? lowerBound.value : void 0
93
+ }
94
+ };
95
+ };
96
+ const checkUniqueFields = async (ctx, schema, betterAuthSchema, table, input, doc) => {
97
+ if (!hasUniqueFields(betterAuthSchema, table, input)) return;
98
+ for (const field of Object.keys(input)) {
99
+ if (!isUniqueField(betterAuthSchema, table, field)) continue;
100
+ const { index } = findIndex(schema, {
101
+ model: table,
102
+ where: [{
103
+ field,
104
+ operator: "eq",
105
+ value: input[field]
106
+ }]
107
+ }) || {};
108
+ if (!index) throw new Error(`No index found for ${table}${field}`);
109
+ const existingDoc = await ctx.db.query(table).withIndex(index.indexDescriptor, (q) => q.eq(field, input[field])).unique();
110
+ if (existingDoc && existingDoc._id !== doc?._id) throw new Error(`${table} ${field} already exists`);
111
+ }
112
+ };
113
+ const selectFields = (doc, select) => {
114
+ if (!doc) return null;
115
+ if (!select?.length) return doc;
116
+ return select.reduce((acc, field) => {
117
+ const sourceField = field === "id" && "_id" in doc ? "_id" : field;
118
+ acc[sourceField] = doc[sourceField];
119
+ return acc;
120
+ }, {});
121
+ };
122
+ const filterByWhere = (doc, where, filterWhere) => {
123
+ if (!doc) return false;
124
+ for (const w of where ?? []) {
125
+ if (filterWhere && !filterWhere(w)) continue;
126
+ const value = doc[w.field];
127
+ const isLessThan = (val, wVal) => {
128
+ if (wVal === void 0 || wVal === null) return false;
129
+ if (val === void 0 || val === null) return true;
130
+ return val < wVal;
131
+ };
132
+ const isGreaterThan = (val, wVal) => {
133
+ if (val === void 0 || val === null) return false;
134
+ if (wVal === void 0 || wVal === null) return true;
135
+ return val > wVal;
136
+ };
137
+ const filter = (w) => {
138
+ switch (w.operator) {
139
+ case "contains": return typeof value === "string" && value.includes(w.value);
140
+ case "ends_with": return typeof value === "string" && value.endsWith(w.value);
141
+ case "eq":
142
+ case void 0: return value === w.value;
143
+ case "gt": return isGreaterThan(value, w.value);
144
+ case "gte": return value === w.value || isGreaterThan(value, w.value);
145
+ case "in": return Array.isArray(w.value) && w.value.includes(value);
146
+ case "lt": return isLessThan(value, w.value);
147
+ case "lte": return value === w.value || isLessThan(value, w.value);
148
+ case "ne": return value !== w.value;
149
+ case "not_in": return Array.isArray(w.value) && !w.value.includes(value);
150
+ case "starts_with": return typeof value === "string" && value.startsWith(w.value);
151
+ }
152
+ };
153
+ if (!filter(w)) return false;
154
+ }
155
+ return true;
156
+ };
157
+ const generateQuery = (ctx, schema, args) => {
158
+ const { boundField, index, indexFields, values } = findIndex(schema, args) ?? {};
159
+ const usableIndex = index?.indexDescriptor === "by_creation_time" ? void 0 : index;
160
+ const query = stream(ctx.db, schema).query(args.model);
161
+ const hasValues = (values?.eq?.length ?? 0) > 0 || values?.lt !== void 0 || values?.lte !== void 0 || values?.gt !== void 0 || values?.gte !== void 0;
162
+ const indexedQuery = usableIndex ? query.withIndex(usableIndex.indexDescriptor, hasValues ? (q) => {
163
+ let query = q;
164
+ for (const [idx, value] of (values?.eq ?? []).entries()) query = query.eq(usableIndex.fields[idx], value);
165
+ if (values?.lt !== void 0) query = query.lt(boundField, values.lt);
166
+ if (values?.lte !== void 0) query = query.lte(boundField, values.lte);
167
+ if (values?.gt !== void 0) query = query.gt(boundField, values.gt);
168
+ if (values?.gte !== void 0) query = query.gte(boundField, values.gte);
169
+ return query;
170
+ } : void 0) : query;
171
+ const orderedQuery = args.sortBy ? indexedQuery.order(args.sortBy.direction === "desc" ? "desc" : "asc") : indexedQuery;
172
+ if (!usableIndex && indexFields?.length) console.warn(stripIndent`
173
+ Querying without an index on table "${args.model}".
174
+ This can cause performance issues, and may hit the document read limit.
175
+ To fix, add an index that begins with the following fields in order:
176
+ [${indexFields.join(", ")}]
177
+ `);
178
+ return orderedQuery.filterWith(async (doc) => {
179
+ if (!usableIndex) return filterByWhere(doc, args.where);
180
+ return filterByWhere(doc, args.where, (w) => w.operator && [
181
+ "contains",
182
+ "ends_with",
183
+ "ne",
184
+ "not_in",
185
+ "starts_with"
186
+ ].includes(w.operator));
187
+ });
188
+ };
189
+ const paginate = async (ctx, schema, betterAuthSchema, args) => {
190
+ if (args.offset) throw new Error(`offset not supported: ${JSON.stringify(args.offset)}`);
191
+ if (args.where?.some((w) => w.connector === "OR") && args.where?.length > 1) throw new Error(`OR connector not supported with multiple where statements in paginate, split up the where statements before calling paginate: ${JSON.stringify(args.where)}`);
192
+ if (args.where?.some((w) => w.field === "_id" && w.operator && ![
193
+ "eq",
194
+ "in",
195
+ "ne",
196
+ "not_in"
197
+ ].includes(w.operator))) throw new Error(`id can only be used with eq, in, not_in, or ne operator: ${JSON.stringify(args.where)}`);
198
+ const uniqueWhere = args.where?.find((w) => (!w.operator || w.operator === "eq") && (isUniqueField(betterAuthSchema, args.model, w.field) || w.field === "_id"));
199
+ if (uniqueWhere) {
200
+ const { index } = findIndex(schema, {
201
+ model: args.model,
202
+ where: [uniqueWhere]
203
+ }) || {};
204
+ const doc = uniqueWhere.field === "_id" ? await ctx.db.get(uniqueWhere.value) : await ctx.db.query(args.model).withIndex(index?.indexDescriptor, (q) => q.eq(index?.fields[0], uniqueWhere.value)).unique();
205
+ if (filterByWhere(doc, args.where, (w) => w !== uniqueWhere)) return {
206
+ continueCursor: "",
207
+ isDone: true,
208
+ page: [selectFields(doc, args.select)].filter(Boolean)
209
+ };
210
+ return {
211
+ continueCursor: "",
212
+ isDone: true,
213
+ page: []
214
+ };
215
+ }
216
+ const paginationLimit = args.paginationOpts.numItems ?? args.limit ?? 200;
217
+ const paginationMaxScan = Math.max(args.paginationOpts.maximumRowsRead ?? 0, paginationLimit + 1, 200);
218
+ const paginationOpts = {
219
+ cursor: args.paginationOpts.cursor,
220
+ endCursor: args.paginationOpts.endCursor,
221
+ limit: paginationLimit,
222
+ maxScan: paginationMaxScan
223
+ };
224
+ const inWhere = args.where?.find((w) => w.operator === "in");
225
+ if (inWhere) {
226
+ if (!Array.isArray(inWhere.value)) throw new TypeError("in clause value must be an array");
227
+ if (inWhere.field === "_id") return {
228
+ continueCursor: "",
229
+ isDone: true,
230
+ page: (await asyncMap(inWhere.value, async (value) => ctx.db.get(value))).flatMap((doc) => doc ? [doc] : []).filter((doc) => filterByWhere(doc, args.where, (w) => w !== inWhere)).sort((a, b) => {
231
+ if (args.sortBy?.field === "createdAt") return args.sortBy.direction === "asc" ? a._creationTime - b._creationTime : b._creationTime - a._creationTime;
232
+ if (args.sortBy) {
233
+ const aValue = a[args.sortBy.field];
234
+ const bValue = b[args.sortBy.field];
235
+ if (aValue === bValue) return 0;
236
+ return args.sortBy.direction === "asc" ? aValue > bValue ? 1 : -1 : aValue > bValue ? -1 : 1;
237
+ }
238
+ return 0;
239
+ }).map((doc) => selectFields(doc, args.select)).flatMap((doc) => doc ? [doc] : [])
240
+ };
241
+ const result = await mergedStream(inWhere.value.map((value) => generateQuery(ctx, schema, {
242
+ ...args,
243
+ where: args.where?.map((w) => {
244
+ if (w === inWhere) return {
245
+ ...w,
246
+ operator: "eq",
247
+ value
248
+ };
249
+ return w;
250
+ })
251
+ })), [args.sortBy?.field !== "createdAt" && args.sortBy?.field, "_creationTime"].flatMap((f) => f ? [f] : [])).paginate(paginationOpts);
252
+ return {
253
+ ...result,
254
+ page: result.page.map((doc) => selectFields(doc, args.select))
255
+ };
256
+ }
257
+ const notInWhere = args.where?.find((w) => w.operator === "not_in");
258
+ if (notInWhere) {
259
+ if (!Array.isArray(notInWhere.value)) throw new TypeError("not_in clause value must be an array");
260
+ const result = await generateQuery(ctx, schema, {
261
+ ...args,
262
+ where: args.where?.filter((w) => w !== notInWhere)
263
+ }).paginate(paginationOpts);
264
+ const filteredPage = result.page.filter((doc) => filterByWhere(doc, [notInWhere]));
265
+ return {
266
+ ...result,
267
+ page: filteredPage.map((doc) => selectFields(doc, args.select))
268
+ };
269
+ }
270
+ const result = await generateQuery(ctx, schema, args).paginate(paginationOpts);
271
+ return {
272
+ ...result,
273
+ page: result.page.map((doc) => selectFields(doc, args.select))
274
+ };
275
+ };
276
+ const listOne = async (ctx, schema, betterAuthSchema, args) => (await paginate(ctx, schema, betterAuthSchema, {
277
+ ...args,
278
+ paginationOpts: {
279
+ cursor: null,
280
+ numItems: 1
281
+ }
282
+ })).page[0];
283
+
284
+ //#endregion
285
+ //#region src/auth/create-api.ts
286
+ const AUTH_TABLE_TRIGGER_KEYS = new Set([
287
+ "create",
288
+ "update",
289
+ "delete",
290
+ "change"
291
+ ]);
292
+ const LEGACY_AUTH_TRIGGER_KEYS = new Set([
293
+ "beforeCreate",
294
+ "beforeDelete",
295
+ "beforeUpdate",
296
+ "onCreate",
297
+ "onDelete",
298
+ "onUpdate"
299
+ ]);
300
+ const whereValidator = (schema, tableName) => v.object({
301
+ connector: v.optional(v.union(v.literal("AND"), v.literal("OR"))),
302
+ field: v.union(...Object.keys(schema.tables[tableName].validator.fields).map((field) => v.literal(field)), v.literal("_id")),
303
+ operator: v.optional(v.union(v.literal("lt"), v.literal("lte"), v.literal("gt"), v.literal("gte"), v.literal("eq"), v.literal("in"), v.literal("not_in"), v.literal("ne"), v.literal("contains"), v.literal("starts_with"), v.literal("ends_with"))),
304
+ value: v.union(v.string(), v.number(), v.boolean(), v.array(v.string()), v.array(v.number()), v.null())
305
+ });
306
+ const resolveSchemaTableName = (schema, betterAuthSchema, model) => {
307
+ if (schema.tables[model]) return model;
308
+ const modelConfig = betterAuthSchema?.[model];
309
+ if (modelConfig?.modelName && schema.tables[modelConfig.modelName]) return modelConfig.modelName;
310
+ for (const [key, value] of Object.entries(betterAuthSchema ?? {})) {
311
+ if (value?.modelName !== model) continue;
312
+ if (schema.tables[key]) return key;
313
+ if (schema.tables[value.modelName]) return value.modelName;
314
+ }
315
+ };
316
+ const resolveOrmTable = (ctx, schema, betterAuthSchema, model) => {
317
+ if (!ctx?.orm || typeof ctx.orm.insert !== "function" || typeof ctx.orm.update !== "function" || typeof ctx.orm.delete !== "function") return;
318
+ const tableName = resolveSchemaTableName(schema, betterAuthSchema, model);
319
+ if (!tableName) return;
320
+ const table = schema.tables[tableName];
321
+ if (!table?._id) return;
322
+ return {
323
+ table,
324
+ tableName
325
+ };
326
+ };
327
+ const normalizeUpdateForOrm = (update) => Object.fromEntries(Object.entries(update).map(([key, value]) => [key, value === void 0 ? unsetToken : value]));
328
+ const ormInsert = async (ctx, table, data) => (await ctx.orm.insert(table).values(data).returning())[0];
329
+ const ormUpdate = async (ctx, table, id, update) => (await ctx.orm.update(table).set(normalizeUpdateForOrm(update)).returning().where(eq(table._id, id)))[0];
330
+ const ormDelete = async (ctx, table, id) => {
331
+ await ctx.orm.delete(table).where(eq(table._id, id));
332
+ };
333
+ const withBothIdFields = (doc) => {
334
+ if (!doc || typeof doc !== "object" || Array.isArray(doc)) return doc;
335
+ const record = doc;
336
+ const existingUnderscoreId = record._id;
337
+ const existingId = record.id;
338
+ const id = existingUnderscoreId ?? existingId;
339
+ if (!id) return doc;
340
+ return {
341
+ ...record,
342
+ _id: existingUnderscoreId ?? id,
343
+ id: existingId ?? id
344
+ };
345
+ };
346
+ const isPlainObject = (value) => !!value && typeof value === "object" && !Array.isArray(value);
347
+ const isBeforeDataResult = (value) => isPlainObject(value) && "data" in value && isPlainObject(value.data);
348
+ const ensureRuntimeTableTriggers = (model, value) => {
349
+ if (value === void 0) return;
350
+ if (!isPlainObject(value)) throw new Error(`Invalid auth triggers for '${model}'. Expected an object with create/update/delete/change keys.`);
351
+ for (const key of Object.keys(value)) {
352
+ if (LEGACY_AUTH_TRIGGER_KEYS.has(key)) throw new Error(`Invalid auth trigger key '${key}' for '${model}'. Auth triggers now use { create, update, delete, change } shape.`);
353
+ if (!AUTH_TABLE_TRIGGER_KEYS.has(key)) throw new Error(`Invalid auth trigger key '${key}' for '${model}'. Allowed keys: create, update, delete, change.`);
354
+ }
355
+ const create = value.create;
356
+ const update = value.update;
357
+ const del = value.delete;
358
+ const change = value.change;
359
+ const validateOperationHook = (operation, operationHooks) => {
360
+ if (operationHooks === void 0) return;
361
+ if (!isPlainObject(operationHooks)) throw new Error(`Invalid auth trigger '${operation}' for '${model}'. Expected an object with optional before/after handlers.`);
362
+ if (operationHooks.before !== void 0 && typeof operationHooks.before !== "function") throw new Error(`Invalid auth trigger '${operation}.before' for '${model}'. Expected a function.`);
363
+ if (operationHooks.after !== void 0 && typeof operationHooks.after !== "function") throw new Error(`Invalid auth trigger '${operation}.after' for '${model}'. Expected a function.`);
364
+ };
365
+ validateOperationHook("create", create);
366
+ validateOperationHook("update", update);
367
+ validateOperationHook("delete", del);
368
+ if (change !== void 0 && typeof change !== "function") throw new Error(`Invalid auth trigger 'change' for '${model}'. Expected a function.`);
369
+ return {
370
+ ...create ? { create } : {},
371
+ ...update ? { update } : {},
372
+ ...del ? { delete: del } : {},
373
+ ...change ? { change } : {}
374
+ };
375
+ };
376
+ const applyBeforeHook = async (model, operation, data, beforeHook, triggerCtx) => {
377
+ if (!beforeHook) return data;
378
+ const result = await beforeHook(data, triggerCtx);
379
+ if (result === false) throw new Error(`Auth trigger cancelled ${operation} on '${model}'.`);
380
+ if (isBeforeDataResult(result)) return {
381
+ ...data,
382
+ ...result.data
383
+ };
384
+ return data;
385
+ };
386
+ const getDocId$1 = (doc) => doc._id ?? doc.id;
387
+ const serializeDatesForConvex = (value) => {
388
+ if (value instanceof Date) return value.getTime();
389
+ if (Array.isArray(value)) {
390
+ let result;
391
+ for (let index = 0; index < value.length; index += 1) {
392
+ const entry = value[index];
393
+ const serialized = serializeDatesForConvex(entry);
394
+ if (serialized !== entry) {
395
+ if (!result) result = value.slice();
396
+ result[index] = serialized;
397
+ }
398
+ }
399
+ return result ?? value;
400
+ }
401
+ if (!isPlainObject(value)) return value;
402
+ let serialized;
403
+ for (const key in value) {
404
+ if (!Object.hasOwn(value, key)) continue;
405
+ const nested = value[key];
406
+ const encoded = serializeDatesForConvex(nested);
407
+ if (encoded !== nested) {
408
+ if (!serialized) serialized = { ...value };
409
+ serialized[key] = encoded;
410
+ }
411
+ }
412
+ return serialized ?? value;
413
+ };
414
+ const toConvexSafe = (value) => serializeDatesForConvex(value);
415
+ const withAuthTimestamps = (data) => {
416
+ if (data.createdAt !== void 0) return data;
417
+ const now = Date.now();
418
+ return {
419
+ ...data,
420
+ createdAt: now,
421
+ ...data.updatedAt === void 0 ? { updatedAt: now } : {}
422
+ };
423
+ };
424
+ const createHandler = async (ctx, args, schema, betterAuthSchema) => {
425
+ const triggerCtx = args.triggerCtx ?? ctx;
426
+ const tableTriggers = args.tableTriggers;
427
+ const data = serializeDatesForConvex(withAuthTimestamps(await applyBeforeHook(args.input.model, "create", args.input.data, tableTriggers?.create?.before, triggerCtx)));
428
+ await checkUniqueFields(ctx, schema, betterAuthSchema, args.input.model, data);
429
+ const ormTable = resolveOrmTable(ctx, schema, betterAuthSchema, args.input.model);
430
+ const doc = ormTable ? await ormInsert(ctx, ormTable.table, data) : await (async () => {
431
+ const id = await ctx.db.insert(args.input.model, data);
432
+ return ctx.db.get(id);
433
+ })();
434
+ if (!doc) throw new Error(`Failed to create ${args.input.model}`);
435
+ const normalizedDoc = withBothIdFields(doc);
436
+ const result = await selectFields(normalizedDoc, args.select);
437
+ const hookDoc = serializeDatesForConvex(normalizedDoc);
438
+ const id = getDocId$1(hookDoc);
439
+ await tableTriggers?.create?.after?.(hookDoc, triggerCtx);
440
+ await tableTriggers?.change?.({
441
+ id,
442
+ newDoc: hookDoc,
443
+ oldDoc: null,
444
+ operation: "insert"
445
+ }, triggerCtx);
446
+ return toConvexSafe(result);
447
+ };
448
+ const findOneHandler = async (ctx, args, schema, betterAuthSchema) => toConvexSafe(await listOne(ctx, schema, betterAuthSchema, args));
449
+ const findManyHandler = async (ctx, args, schema, betterAuthSchema) => toConvexSafe(await paginate(ctx, schema, betterAuthSchema, args));
450
+ const updateOneHandler = async (ctx, args, schema, betterAuthSchema) => {
451
+ const triggerCtx = args.triggerCtx ?? ctx;
452
+ const tableTriggers = args.tableTriggers;
453
+ const doc = await listOne(ctx, schema, betterAuthSchema, args.input);
454
+ if (!doc) throw new Error(`Failed to update ${args.input.model}`);
455
+ const normalizedDoc = withBothIdFields(doc);
456
+ const update = serializeDatesForConvex(await applyBeforeHook(args.input.model, "update", args.input.update, tableTriggers?.update?.before, triggerCtx));
457
+ await checkUniqueFields(ctx, schema, betterAuthSchema, args.input.model, update, normalizedDoc);
458
+ const ormTable = resolveOrmTable(ctx, schema, betterAuthSchema, args.input.model);
459
+ const updatedDoc = ormTable ? await ormUpdate(ctx, ormTable.table, normalizedDoc._id, update) : await (async () => {
460
+ await ctx.db.patch(normalizedDoc._id, update);
461
+ return ctx.db.get(normalizedDoc._id);
462
+ })();
463
+ if (!updatedDoc) throw new Error(`Failed to update ${args.input.model}`);
464
+ const normalizedUpdatedDoc = withBothIdFields(updatedDoc);
465
+ const hookNewDoc = serializeDatesForConvex(normalizedUpdatedDoc);
466
+ const hookOldDoc = serializeDatesForConvex(normalizedDoc);
467
+ const id = getDocId$1(hookNewDoc);
468
+ await tableTriggers?.update?.after?.(hookNewDoc, triggerCtx);
469
+ await tableTriggers?.change?.({
470
+ id,
471
+ newDoc: hookNewDoc,
472
+ oldDoc: hookOldDoc,
473
+ operation: "update"
474
+ }, triggerCtx);
475
+ return toConvexSafe(normalizedUpdatedDoc);
476
+ };
477
+ const updateManyHandler = async (ctx, args, schema, betterAuthSchema) => {
478
+ const triggerCtx = args.triggerCtx ?? ctx;
479
+ const tableTriggers = args.tableTriggers;
480
+ const { page, ...result } = await paginate(ctx, schema, betterAuthSchema, {
481
+ ...args.input,
482
+ paginationOpts: args.paginationOpts
483
+ });
484
+ const ormTable = resolveOrmTable(ctx, schema, betterAuthSchema, args.input.model);
485
+ if (args.input.update) {
486
+ if (hasUniqueFields(betterAuthSchema, args.input.model, args.input.update ?? {}) && page.length > 1) throw new Error(`Attempted to set unique fields in multiple documents in ${args.input.model} with the same value. Fields: ${Object.keys(args.input.update ?? {}).join(", ")}`);
487
+ await asyncMap(page, async (doc) => {
488
+ const normalizedDoc = withBothIdFields(doc);
489
+ const update = serializeDatesForConvex(await applyBeforeHook(args.input.model, "update", args.input.update ?? {}, tableTriggers?.update?.before, triggerCtx));
490
+ await checkUniqueFields(ctx, schema, betterAuthSchema, args.input.model, update ?? {}, normalizedDoc);
491
+ const hookNewDoc = serializeDatesForConvex(withBothIdFields(ormTable ? await ormUpdate(ctx, ormTable.table, normalizedDoc._id, update ?? {}) : await (async () => {
492
+ await ctx.db.patch(normalizedDoc._id, update);
493
+ return ctx.db.get(normalizedDoc._id);
494
+ })()));
495
+ const hookOldDoc = serializeDatesForConvex(normalizedDoc);
496
+ const id = getDocId$1(hookNewDoc);
497
+ await tableTriggers?.update?.after?.(hookNewDoc, triggerCtx);
498
+ await tableTriggers?.change?.({
499
+ id,
500
+ newDoc: hookNewDoc,
501
+ oldDoc: hookOldDoc,
502
+ operation: "update"
503
+ }, triggerCtx);
504
+ });
505
+ }
506
+ return toConvexSafe({
507
+ ...result,
508
+ count: page.length,
509
+ ids: page.map((doc) => withBothIdFields(doc)._id)
510
+ });
511
+ };
512
+ const deleteOneHandler = async (ctx, args, schema, betterAuthSchema) => {
513
+ const triggerCtx = args.triggerCtx ?? ctx;
514
+ const tableTriggers = args.tableTriggers;
515
+ const doc = await listOne(ctx, schema, betterAuthSchema, args.input);
516
+ if (!doc) return;
517
+ const normalizedDoc = withBothIdFields(doc);
518
+ const hookDoc = withBothIdFields(serializeDatesForConvex(await applyBeforeHook(args.input.model, "delete", normalizedDoc, tableTriggers?.delete?.before, triggerCtx)));
519
+ const id = getDocId$1(normalizedDoc);
520
+ const ormTable = resolveOrmTable(ctx, schema, betterAuthSchema, args.input.model);
521
+ if (ormTable) await ormDelete(ctx, ormTable.table, normalizedDoc._id);
522
+ else await ctx.db.delete(normalizedDoc._id);
523
+ await tableTriggers?.delete?.after?.(hookDoc, triggerCtx);
524
+ await tableTriggers?.change?.({
525
+ id,
526
+ newDoc: null,
527
+ oldDoc: hookDoc,
528
+ operation: "delete"
529
+ }, triggerCtx);
530
+ return toConvexSafe(withBothIdFields(hookDoc));
531
+ };
532
+ const deleteManyHandler = async (ctx, args, schema, betterAuthSchema) => {
533
+ const triggerCtx = args.triggerCtx ?? ctx;
534
+ const tableTriggers = args.tableTriggers;
535
+ const { page, ...result } = await paginate(ctx, schema, betterAuthSchema, {
536
+ ...args.input,
537
+ paginationOpts: args.paginationOpts
538
+ });
539
+ const ormTable = resolveOrmTable(ctx, schema, betterAuthSchema, args.input.model);
540
+ await asyncMap(page, async (doc) => {
541
+ const normalizedDoc = withBothIdFields(doc);
542
+ const hookDoc = withBothIdFields(serializeDatesForConvex(await applyBeforeHook(args.input.model, "delete", normalizedDoc, tableTriggers?.delete?.before, triggerCtx)));
543
+ const id = getDocId$1(normalizedDoc);
544
+ if (ormTable) await ormDelete(ctx, ormTable.table, normalizedDoc._id);
545
+ else await ctx.db.delete(normalizedDoc._id);
546
+ await tableTriggers?.delete?.after?.(hookDoc, triggerCtx);
547
+ await tableTriggers?.change?.({
548
+ id,
549
+ newDoc: null,
550
+ oldDoc: hookDoc,
551
+ operation: "delete"
552
+ }, triggerCtx);
553
+ });
554
+ return toConvexSafe({
555
+ ...result,
556
+ count: page.length,
557
+ ids: page.map((doc) => withBothIdFields(doc)._id)
558
+ });
559
+ };
560
+ const createApi = (schema, getAuth, options) => {
561
+ const { internalMutation, validateInput = false, context, triggers } = options ?? {};
562
+ let betterAuthSchema;
563
+ const getBetterAuthSchema = () => {
564
+ betterAuthSchema ??= getAuthTables(getAuth({}).options);
565
+ return betterAuthSchema;
566
+ };
567
+ const mutationBuilderBase = internalMutation ?? internalMutationGeneric;
568
+ const mutationBuilder = context ? customMutation(mutationBuilderBase, customCtx(async (ctx) => await context?.(ctx) ?? ctx)) : mutationBuilderBase;
569
+ const resolveTableTriggers = (model, triggerCtx) => {
570
+ const tableTriggers = (typeof triggers === "function" ? triggers(triggerCtx) : triggers)?.[model];
571
+ return ensureRuntimeTableTriggers(model, tableTriggers);
572
+ };
573
+ const anyInput = v.object({
574
+ data: v.any(),
575
+ model: v.string()
576
+ });
577
+ const anyInputWithWhere = v.object({
578
+ model: v.string(),
579
+ where: v.optional(v.array(v.any()))
580
+ });
581
+ const anyInputWithUpdate = v.object({
582
+ model: v.string(),
583
+ update: v.any(),
584
+ where: v.optional(v.array(v.any()))
585
+ });
586
+ const authSchemaForValidation = validateInput ? getBetterAuthSchema() : {};
587
+ const authTableNames = new Set(Object.keys(authSchemaForValidation));
588
+ const authTables = Object.entries(schema.tables).filter(([name]) => authTableNames.has(name));
589
+ const authTableKeys = authTables.map(([name]) => name);
590
+ const createInput = validateInput ? v.union(...authTables.map(([model, table]) => {
591
+ const fields = partial(table.validator.fields);
592
+ return v.object({
593
+ data: v.object(fields),
594
+ model: v.literal(model)
595
+ });
596
+ })) : anyInput;
597
+ const deleteInput = validateInput ? v.union(...authTableKeys.map((tableName) => v.object({
598
+ model: v.literal(tableName),
599
+ where: v.optional(v.array(whereValidator(schema, tableName)))
600
+ }))) : anyInputWithWhere;
601
+ const modelValidator = validateInput ? v.union(...authTableKeys.map((model) => v.literal(model))) : v.string();
602
+ const updateInput = validateInput ? v.union(...authTables.map(([tableName, table]) => {
603
+ const fields = partial(table.validator.fields);
604
+ return v.object({
605
+ model: v.literal(tableName),
606
+ update: v.object(fields),
607
+ where: v.optional(v.array(whereValidator(schema, tableName)))
608
+ });
609
+ })) : anyInputWithUpdate;
610
+ return {
611
+ create: mutationBuilder({
612
+ args: {
613
+ input: createInput,
614
+ select: v.optional(v.array(v.string()))
615
+ },
616
+ handler: async (ctx, args) => {
617
+ const triggerCtx = ctx;
618
+ return createHandler(ctx, {
619
+ input: args.input,
620
+ select: args.select,
621
+ tableTriggers: resolveTableTriggers(args.input.model, triggerCtx),
622
+ triggerCtx
623
+ }, schema, getBetterAuthSchema());
624
+ }
625
+ }),
626
+ deleteMany: mutationBuilder({
627
+ args: {
628
+ input: deleteInput,
629
+ paginationOpts: paginationOptsValidator
630
+ },
631
+ handler: async (ctx, args) => {
632
+ const triggerCtx = ctx;
633
+ return deleteManyHandler(ctx, {
634
+ input: args.input,
635
+ paginationOpts: args.paginationOpts,
636
+ tableTriggers: resolveTableTriggers(args.input.model, triggerCtx),
637
+ triggerCtx
638
+ }, schema, getBetterAuthSchema());
639
+ }
640
+ }),
641
+ deleteOne: mutationBuilder({
642
+ args: { input: deleteInput },
643
+ handler: async (ctx, args) => {
644
+ const triggerCtx = ctx;
645
+ return deleteOneHandler(ctx, {
646
+ input: args.input,
647
+ tableTriggers: resolveTableTriggers(args.input.model, triggerCtx),
648
+ triggerCtx
649
+ }, schema, getBetterAuthSchema());
650
+ }
651
+ }),
652
+ findMany: internalQueryGeneric({
653
+ args: {
654
+ join: v.optional(v.any()),
655
+ limit: v.optional(v.number()),
656
+ model: modelValidator,
657
+ offset: v.optional(v.number()),
658
+ paginationOpts: paginationOptsValidator,
659
+ sortBy: v.optional(v.object({
660
+ direction: v.union(v.literal("asc"), v.literal("desc")),
661
+ field: v.string()
662
+ })),
663
+ where: v.optional(v.array(adapterWhereValidator))
664
+ },
665
+ handler: async (ctx, args) => findManyHandler(ctx, args, schema, getBetterAuthSchema())
666
+ }),
667
+ findOne: internalQueryGeneric({
668
+ args: {
669
+ join: v.optional(v.any()),
670
+ model: modelValidator,
671
+ select: v.optional(v.array(v.string())),
672
+ where: v.optional(v.array(adapterWhereValidator))
673
+ },
674
+ handler: async (ctx, args) => findOneHandler(ctx, args, schema, getBetterAuthSchema())
675
+ }),
676
+ getLatestJwks: internalActionGeneric({
677
+ args: {},
678
+ handler: async (ctx) => {
679
+ return getAuth(ctx).api.getLatestJwks();
680
+ }
681
+ }),
682
+ rotateKeys: internalActionGeneric({
683
+ args: {},
684
+ handler: async (ctx) => {
685
+ return getAuth(ctx).api.rotateKeys();
686
+ }
687
+ }),
688
+ updateMany: mutationBuilder({
689
+ args: {
690
+ input: updateInput,
691
+ paginationOpts: paginationOptsValidator
692
+ },
693
+ handler: async (ctx, args) => {
694
+ const triggerCtx = ctx;
695
+ return updateManyHandler(ctx, {
696
+ input: args.input,
697
+ paginationOpts: args.paginationOpts,
698
+ tableTriggers: resolveTableTriggers(args.input.model, triggerCtx),
699
+ triggerCtx
700
+ }, schema, getBetterAuthSchema());
701
+ }
702
+ }),
703
+ updateOne: mutationBuilder({
704
+ args: { input: updateInput },
705
+ handler: async (ctx, args) => {
706
+ const triggerCtx = ctx;
707
+ return updateOneHandler(ctx, {
708
+ input: args.input,
709
+ tableTriggers: resolveTableTriggers(args.input.model, triggerCtx),
710
+ triggerCtx
711
+ }, schema, getBetterAuthSchema());
712
+ }
713
+ })
714
+ };
715
+ };
716
+
717
+ //#endregion
718
+ //#region src/auth/adapter.ts
719
+ let didWarnExperimentalJoinsUnsupported = false;
720
+ const handlePagination = async (next, { limit, numItems } = {}) => {
721
+ const state = {
722
+ count: 0,
723
+ cursor: null,
724
+ docs: [],
725
+ isDone: false
726
+ };
727
+ const onResult = (result) => {
728
+ state.cursor = result.pageStatus === "SplitRecommended" || result.pageStatus === "SplitRequired" ? result.splitCursor ?? result.continueCursor : result.continueCursor;
729
+ if (result.page) {
730
+ state.docs.push(...result.page);
731
+ state.isDone = limit && state.docs.length >= limit || result.isDone;
732
+ return;
733
+ }
734
+ if (result.count) {
735
+ state.count += result.count;
736
+ state.isDone = limit && state.count >= limit || result.isDone;
737
+ return;
738
+ }
739
+ state.isDone = result.isDone;
740
+ };
741
+ do
742
+ onResult(await next({ paginationOpts: {
743
+ cursor: state.cursor,
744
+ numItems: Math.min(numItems ?? 200, (limit ?? 200) - state.docs.length, 200)
745
+ } }));
746
+ while (!state.isDone);
747
+ return state;
748
+ };
749
+ const hasOrWhere = (where) => where?.some((clause) => clause.connector === "OR") ?? false;
750
+ const assertSupportedBulkOrWhere = (where, operation) => {
751
+ if (hasOrWhere(where) && !where?.every((clause) => clause.connector === "OR")) throw new Error(`Mixed OR/AND where clauses are not supported for ${operation}`);
752
+ };
753
+ const parseWhere = (where) => {
754
+ if (!where) return [];
755
+ return (Array.isArray(where) ? where : [where]).map((w) => {
756
+ if (w.value instanceof Date) return {
757
+ ...w,
758
+ value: w.value.getTime()
759
+ };
760
+ return w;
761
+ });
762
+ };
763
+ const getDocId = (doc) => {
764
+ if (doc?._id !== void 0 && doc?._id !== null) return String(doc._id);
765
+ if (doc?.id !== void 0 && doc?.id !== null) return String(doc.id);
766
+ };
767
+ const dedupeDocsById = (docs) => {
768
+ const seen = /* @__PURE__ */ new Set();
769
+ const deduped = [];
770
+ for (const doc of docs) {
771
+ const id = getDocId(doc);
772
+ if (!id) {
773
+ deduped.push(doc);
774
+ continue;
775
+ }
776
+ if (seen.has(id)) continue;
777
+ seen.add(id);
778
+ deduped.push(doc);
779
+ }
780
+ return deduped;
781
+ };
782
+ const selectDocFields = (doc, select) => {
783
+ if (!select?.length) return doc;
784
+ return select.reduce((acc, field) => {
785
+ const sourceField = field === "id" && "_id" in doc ? "_id" : field;
786
+ acc[sourceField] = doc[sourceField];
787
+ return acc;
788
+ }, {});
789
+ };
790
+ const adapterConfig = {
791
+ adapterId: "convex",
792
+ adapterName: "Convex Adapter",
793
+ debugLogs: false,
794
+ disableIdGeneration: true,
795
+ mapKeysTransformInput: { id: "_id" },
796
+ mapKeysTransformOutput: { _id: "id" },
797
+ supportsJSON: false,
798
+ supportsNumericIds: false,
799
+ supportsDates: false,
800
+ supportsArrays: true,
801
+ transaction: false,
802
+ usePlural: false,
803
+ customTransformInput: ({ data, fieldAttributes }) => {
804
+ if (data && fieldAttributes.type === "date") return new Date(data).getTime();
805
+ return data;
806
+ },
807
+ customTransformOutput: ({ data, fieldAttributes }) => {
808
+ if (data && fieldAttributes.type === "date") return new Date(data).getTime();
809
+ return data;
810
+ }
811
+ };
812
+ const ORM_SCHEMA_OPTIONS = Symbol.for("kitcn:OrmSchemaOptions");
813
+ const hasOrmSchemaMetadata = (schema) => !!schema && typeof schema === "object" && ORM_SCHEMA_OPTIONS in schema;
814
+ const createAuthSchema = async ({ file, schema, tables }) => {
815
+ if (hasOrmSchemaMetadata(schema)) {
816
+ const { createSchemaOrm } = await import("../create-schema-orm-DOyiNDCx.js");
817
+ return createSchemaOrm({
818
+ file,
819
+ tables
820
+ });
821
+ }
822
+ const { createSchema } = await import("../create-schema-odyF4kCy.js");
823
+ return createSchema({
824
+ file,
825
+ tables
826
+ });
827
+ };
828
+ const httpAdapter = (ctx, { authFunctions, debugLogs, schema }) => {
829
+ return createAdapterFactory({
830
+ config: {
831
+ ...adapterConfig,
832
+ debugLogs: debugLogs || false
833
+ },
834
+ adapter: ({ options }) => {
835
+ options.telemetry = { enabled: false };
836
+ if (options.experimental?.joins) {
837
+ options.experimental = {
838
+ ...options.experimental,
839
+ joins: false
840
+ };
841
+ if (!didWarnExperimentalJoinsUnsupported) {
842
+ didWarnExperimentalJoinsUnsupported = true;
843
+ console.warn("[kitcn] Better Auth experimental.joins is not supported by the Convex adapter yet. Forcing experimental.joins = false.");
844
+ }
845
+ }
846
+ const collectIdsForOrWhere = async (data) => {
847
+ return dedupeDocsById((await asyncMap(data.where, async (w) => handlePagination(async ({ paginationOpts }) => await ctx.runQuery(authFunctions.findMany, {
848
+ model: data.model,
849
+ paginationOpts,
850
+ where: parseWhere(w)
851
+ })))).flatMap((result) => result.docs)).map((doc) => getDocId(doc)).flatMap((id) => id ? [id] : []);
852
+ };
853
+ return {
854
+ id: "convex",
855
+ options: { isRunMutationCtx: isRunMutationCtx(ctx) },
856
+ count: async (data) => {
857
+ if (hasOrWhere(data.where)) return dedupeDocsById((await asyncMap(data.where, async (w) => handlePagination(async ({ paginationOpts }) => await ctx.runQuery(authFunctions.findMany, {
858
+ ...data,
859
+ paginationOpts,
860
+ where: parseWhere(w)
861
+ })))).flatMap((r) => r.docs)).length;
862
+ return (await handlePagination(async ({ paginationOpts }) => await ctx.runQuery(authFunctions.findMany, {
863
+ ...data,
864
+ paginationOpts,
865
+ where: parseWhere(data.where)
866
+ }))).docs.length;
867
+ },
868
+ create: async ({ data, model, select }) => {
869
+ if (!("runMutation" in ctx)) throw new Error("ctx is not a mutation ctx");
870
+ return await ctx.runMutation(authFunctions.create, {
871
+ input: {
872
+ data,
873
+ model
874
+ },
875
+ select
876
+ });
877
+ },
878
+ createSchema: async ({ file, tables }) => createAuthSchema({
879
+ file,
880
+ schema,
881
+ tables
882
+ }),
883
+ delete: async (data) => {
884
+ if (!("runMutation" in ctx)) throw new Error("ctx is not a mutation ctx");
885
+ await ctx.runMutation(authFunctions.deleteOne, { input: {
886
+ model: data.model,
887
+ where: parseWhere(data.where)
888
+ } });
889
+ },
890
+ deleteMany: async (data) => {
891
+ if (!("runMutation" in ctx)) throw new Error("ctx is not a mutation ctx");
892
+ assertSupportedBulkOrWhere(data.where, "deleteMany");
893
+ if (hasOrWhere(data.where)) {
894
+ const ids = await collectIdsForOrWhere({
895
+ model: data.model,
896
+ where: data.where
897
+ });
898
+ await asyncMap(ids, async (id) => {
899
+ await ctx.runMutation(authFunctions.deleteOne, { input: {
900
+ model: data.model,
901
+ where: [{
902
+ field: "_id",
903
+ operator: "eq",
904
+ value: id
905
+ }]
906
+ } });
907
+ });
908
+ return ids.length;
909
+ }
910
+ return (await handlePagination(async ({ paginationOpts }) => await ctx.runMutation(authFunctions.deleteMany, {
911
+ input: {
912
+ ...data,
913
+ where: parseWhere(data.where)
914
+ },
915
+ paginationOpts
916
+ }))).count;
917
+ },
918
+ findMany: async (data) => {
919
+ if (data.offset) throw new Error("offset not supported");
920
+ if (hasOrWhere(data.where)) {
921
+ const { select: _ignoredSelect, ...queryData } = data;
922
+ let docs = dedupeDocsById((await asyncMap(data.where, async (w) => handlePagination(async ({ paginationOpts }) => await ctx.runQuery(authFunctions.findMany, {
923
+ ...queryData,
924
+ paginationOpts,
925
+ where: parseWhere(w)
926
+ }), { limit: data.limit }))).flatMap((r) => r.docs));
927
+ if (data.sortBy) docs = sortBy(docs, [prop(data.sortBy.field), data.sortBy.direction]);
928
+ if (data.limit !== void 0) docs = docs.slice(0, data.limit);
929
+ return docs.map((doc) => selectDocFields(doc, data.select));
930
+ }
931
+ return (await handlePagination(async ({ paginationOpts }) => await ctx.runQuery(authFunctions.findMany, {
932
+ ...data,
933
+ paginationOpts,
934
+ where: parseWhere(data.where)
935
+ }), { limit: data.limit })).docs;
936
+ },
937
+ findOne: async (data) => {
938
+ const parsedWhere = parseWhere(data.where);
939
+ if (data.where?.every((w) => w.connector === "OR")) for (const w of data.where) {
940
+ const result = await ctx.runQuery(authFunctions.findOne, {
941
+ ...data,
942
+ where: parseWhere(w)
943
+ });
944
+ if (result) return result;
945
+ }
946
+ return await ctx.runQuery(authFunctions.findOne, {
947
+ ...data,
948
+ where: parsedWhere
949
+ });
950
+ },
951
+ update: async (data) => {
952
+ if (!("runMutation" in ctx)) throw new Error("ctx is not a mutation ctx");
953
+ if (data.where?.length && data.where.every((w) => (w.operator === "eq" || w.operator === void 0) && w.connector !== "OR")) {
954
+ const countResult = await handlePagination(async ({ paginationOpts }) => await ctx.runQuery(authFunctions.findMany, {
955
+ model: data.model,
956
+ paginationOpts,
957
+ where: parseWhere(data.where)
958
+ }), { limit: 2 });
959
+ if (countResult.docs.length === 0) throw new Error(`No ${data.model} found matching criteria`);
960
+ if (countResult.docs.length > 1) throw new Error(`Multiple ${data.model} found matching criteria. Expected exactly 1.`);
961
+ return await ctx.runMutation(authFunctions.updateOne, { input: {
962
+ model: data.model,
963
+ update: data.update,
964
+ where: parseWhere(data.where)
965
+ } });
966
+ }
967
+ throw new Error("where clause not supported");
968
+ },
969
+ updateMany: async (data) => {
970
+ if (!("runMutation" in ctx)) throw new Error("ctx is not a mutation ctx");
971
+ assertSupportedBulkOrWhere(data.where, "updateMany");
972
+ if (hasOrWhere(data.where)) {
973
+ const ids = await collectIdsForOrWhere({
974
+ model: data.model,
975
+ where: data.where
976
+ });
977
+ if (!ids.length) return 0;
978
+ return (await handlePagination(async ({ paginationOpts }) => await ctx.runMutation(authFunctions.updateMany, {
979
+ input: {
980
+ ...data,
981
+ where: [{
982
+ field: "_id",
983
+ operator: "in",
984
+ value: ids
985
+ }]
986
+ },
987
+ paginationOpts
988
+ }), { limit: ids.length })).count;
989
+ }
990
+ return (await handlePagination(async ({ paginationOpts }) => await ctx.runMutation(authFunctions.updateMany, {
991
+ input: {
992
+ ...data,
993
+ where: parseWhere(data.where)
994
+ },
995
+ paginationOpts
996
+ }))).count;
997
+ }
998
+ };
999
+ }
1000
+ });
1001
+ };
1002
+ const dbAdapter = (ctx, getAuthOptions, { authFunctions, debugLogs, schema }) => {
1003
+ const betterAuthSchema = getAuthTables(getAuthOptions({}));
1004
+ return createAdapterFactory({
1005
+ config: {
1006
+ ...adapterConfig,
1007
+ debugLogs: debugLogs || false
1008
+ },
1009
+ adapter: ({ options }) => {
1010
+ options.telemetry = { enabled: false };
1011
+ if (options.experimental?.joins) {
1012
+ options.experimental = {
1013
+ ...options.experimental,
1014
+ joins: false
1015
+ };
1016
+ if (!didWarnExperimentalJoinsUnsupported) {
1017
+ didWarnExperimentalJoinsUnsupported = true;
1018
+ console.warn("[kitcn] Better Auth experimental.joins is not supported by the Convex adapter yet. Forcing experimental.joins = false.");
1019
+ }
1020
+ }
1021
+ const collectIdsForOrWhere = async (data) => {
1022
+ return dedupeDocsById((await asyncMap(data.where, async (w) => handlePagination(async ({ paginationOpts }) => await findManyHandler(ctx, {
1023
+ model: data.model,
1024
+ paginationOpts,
1025
+ where: parseWhere(w)
1026
+ }, schema, betterAuthSchema)))).flatMap((result) => result.docs)).map((doc) => getDocId(doc)).flatMap((id) => id ? [id] : []);
1027
+ };
1028
+ return {
1029
+ id: "convex",
1030
+ options: { isRunMutationCtx: isRunMutationCtx(ctx) },
1031
+ count: async (data) => {
1032
+ if (hasOrWhere(data.where)) return dedupeDocsById((await asyncMap(data.where, async (w) => handlePagination(async ({ paginationOpts }) => await findManyHandler(ctx, {
1033
+ ...data,
1034
+ paginationOpts,
1035
+ where: parseWhere(w)
1036
+ }, schema, betterAuthSchema)))).flatMap((r) => r.docs)).length;
1037
+ return (await handlePagination(async ({ paginationOpts }) => await findManyHandler(ctx, {
1038
+ ...data,
1039
+ paginationOpts,
1040
+ where: parseWhere(data.where)
1041
+ }, schema, betterAuthSchema))).docs.length;
1042
+ },
1043
+ create: async ({ data, model, select }) => {
1044
+ if (!("runMutation" in ctx)) throw new Error("ctx is not a mutation ctx");
1045
+ return await ctx.runMutation(authFunctions.create, {
1046
+ input: {
1047
+ data,
1048
+ model
1049
+ },
1050
+ select
1051
+ });
1052
+ },
1053
+ createSchema: async ({ file, tables }) => createAuthSchema({
1054
+ file,
1055
+ schema,
1056
+ tables
1057
+ }),
1058
+ delete: async (data) => {
1059
+ if (!("runMutation" in ctx)) throw new Error("ctx is not a mutation ctx");
1060
+ await ctx.runMutation(authFunctions.deleteOne, { input: {
1061
+ model: data.model,
1062
+ where: parseWhere(data.where)
1063
+ } });
1064
+ },
1065
+ deleteMany: async (data) => {
1066
+ if (!("runMutation" in ctx)) throw new Error("ctx is not a mutation ctx");
1067
+ assertSupportedBulkOrWhere(data.where, "deleteMany");
1068
+ if (hasOrWhere(data.where)) {
1069
+ const ids = await collectIdsForOrWhere({
1070
+ model: data.model,
1071
+ where: data.where
1072
+ });
1073
+ await asyncMap(ids, async (id) => {
1074
+ await ctx.runMutation(authFunctions.deleteOne, { input: {
1075
+ model: data.model,
1076
+ where: [{
1077
+ field: "_id",
1078
+ operator: "eq",
1079
+ value: id
1080
+ }]
1081
+ } });
1082
+ });
1083
+ return ids.length;
1084
+ }
1085
+ return (await handlePagination(async ({ paginationOpts }) => await ctx.runMutation(authFunctions.deleteMany, {
1086
+ input: {
1087
+ ...data,
1088
+ where: parseWhere(data.where)
1089
+ },
1090
+ paginationOpts
1091
+ }))).count;
1092
+ },
1093
+ findMany: async (data) => {
1094
+ if (data.offset) throw new Error("offset not supported");
1095
+ if (hasOrWhere(data.where)) {
1096
+ const { select: _ignoredSelect, ...queryData } = data;
1097
+ let docs = dedupeDocsById((await asyncMap(data.where, async (w) => handlePagination(async ({ paginationOpts }) => await findManyHandler(ctx, {
1098
+ ...queryData,
1099
+ paginationOpts,
1100
+ where: parseWhere(w)
1101
+ }, schema, betterAuthSchema), { limit: data.limit }))).flatMap((r) => r.docs));
1102
+ if (data.sortBy) docs = sortBy(docs, [prop(data.sortBy.field), data.sortBy.direction]);
1103
+ if (data.limit !== void 0) docs = docs.slice(0, data.limit);
1104
+ return docs.map((doc) => selectDocFields(doc, data.select));
1105
+ }
1106
+ return (await handlePagination(async ({ paginationOpts }) => await findManyHandler(ctx, {
1107
+ ...data,
1108
+ paginationOpts,
1109
+ where: parseWhere(data.where)
1110
+ }, schema, betterAuthSchema), { limit: data.limit })).docs;
1111
+ },
1112
+ findOne: async (data) => {
1113
+ if (data.where?.every((w) => w.connector === "OR")) for (const w of data.where) {
1114
+ const result = await findOneHandler(ctx, {
1115
+ ...data,
1116
+ where: parseWhere(w)
1117
+ }, schema, betterAuthSchema);
1118
+ if (result) return result;
1119
+ }
1120
+ return await findOneHandler(ctx, {
1121
+ ...data,
1122
+ where: parseWhere(data.where)
1123
+ }, schema, betterAuthSchema);
1124
+ },
1125
+ update: async (data) => {
1126
+ if (data.where?.length && data.where.every((w) => (w.operator === "eq" || w.operator === void 0) && w.connector !== "OR")) {
1127
+ const countResult = await handlePagination(async ({ paginationOpts }) => await findManyHandler(ctx, {
1128
+ model: data.model,
1129
+ paginationOpts,
1130
+ where: parseWhere(data.where)
1131
+ }, schema, betterAuthSchema), { limit: 2 });
1132
+ if (countResult.docs.length === 0) throw new Error(`No ${data.model} found matching criteria`);
1133
+ if (countResult.docs.length > 1) throw new Error(`Multiple ${data.model} found matching criteria. Expected exactly 1.`);
1134
+ if (!("runMutation" in ctx)) throw new Error("ctx is not a mutation ctx");
1135
+ return await ctx.runMutation(authFunctions.updateOne, { input: {
1136
+ model: data.model,
1137
+ update: data.update,
1138
+ where: parseWhere(data.where)
1139
+ } });
1140
+ }
1141
+ throw new Error("where clause not supported");
1142
+ },
1143
+ updateMany: async (data) => {
1144
+ if (!("runMutation" in ctx)) throw new Error("ctx is not a mutation ctx");
1145
+ assertSupportedBulkOrWhere(data.where, "updateMany");
1146
+ if (hasOrWhere(data.where)) {
1147
+ const ids = await collectIdsForOrWhere({
1148
+ model: data.model,
1149
+ where: data.where
1150
+ });
1151
+ if (!ids.length) return 0;
1152
+ return (await handlePagination(async ({ paginationOpts }) => await ctx.runMutation(authFunctions.updateMany, {
1153
+ input: {
1154
+ ...data,
1155
+ where: [{
1156
+ field: "_id",
1157
+ operator: "in",
1158
+ value: ids
1159
+ }]
1160
+ },
1161
+ paginationOpts
1162
+ }), { limit: ids.length })).count;
1163
+ }
1164
+ return (await handlePagination(async ({ paginationOpts }) => await ctx.runMutation(authFunctions.updateMany, {
1165
+ input: {
1166
+ ...data,
1167
+ where: parseWhere(data.where)
1168
+ },
1169
+ paginationOpts
1170
+ }))).count;
1171
+ }
1172
+ };
1173
+ }
1174
+ });
1175
+ };
1176
+
1177
+ //#endregion
1178
+ //#region src/auth/create-client.ts
1179
+ const createClient = (config) => ({
1180
+ authFunctions: config.authFunctions,
1181
+ triggers: config.triggers,
1182
+ adapter: (ctx, getAuthOptions) => isQueryCtx(ctx) ? dbAdapter(ctx, getAuthOptions, config) : httpAdapter(ctx, config)
1183
+ });
1184
+
1185
+ //#endregion
1186
+ //#region src/auth/generated-contract.ts
1187
+ const GENERATED_AUTH_TDZ_RE = /before initialization/i;
1188
+ const KITCN_DISABLED_RATE_LIMIT_RULES = {
1189
+ "/convex/.well-known/openid-configuration": false,
1190
+ "/convex/jwks": false,
1191
+ "/convex/latest-jwks": false,
1192
+ "/convex/rotate-keys": false
1193
+ };
1194
+ const resolveAuthDefinitionPath = (authDefinitionPath) => {
1195
+ const normalized = authDefinitionPath?.trim();
1196
+ return normalized && normalized.length > 0 ? normalized : DEFAULT_AUTH_DEFINITION_PATH;
1197
+ };
1198
+ const getInvalidAuthDefinitionExportReason = (authDefinitionPath) => {
1199
+ return `Invalid auth definition export. Expected ${resolveAuthDefinitionPath(authDefinitionPath)} default export to be \`defineAuth((ctx) => ({ ... }))\`.`;
1200
+ };
1201
+ const resolveGeneratedAuthDefinition = (input, reason) => {
1202
+ const createDeferredResolver = () => ((...args) => {
1203
+ const deferred = resolveValue();
1204
+ if (typeof deferred === "function") return deferred(...args);
1205
+ throw new Error(reason);
1206
+ });
1207
+ const resolveValue = () => {
1208
+ if (typeof input === "function") return input;
1209
+ if (typeof input !== "object" || input === null || !("default" in input)) return;
1210
+ const defaultExport = input.default;
1211
+ return typeof defaultExport === "function" ? defaultExport : void 0;
1212
+ };
1213
+ let resolved;
1214
+ try {
1215
+ resolved = resolveValue();
1216
+ } catch (error) {
1217
+ if (error instanceof ReferenceError && GENERATED_AUTH_TDZ_RE.test(error.message)) return createDeferredResolver();
1218
+ throw error;
1219
+ }
1220
+ if (typeof resolved === "function") return resolved;
1221
+ if (typeof input === "object" && input !== null && "default" in input) return createDeferredResolver();
1222
+ throw new Error(reason);
1223
+ };
1224
+ const withDatabase = (authOptions, ctx, adapter) => ({
1225
+ ...authOptions,
1226
+ database: adapter(ctx)
1227
+ });
1228
+ const withAuthDefaults = (authOptions) => {
1229
+ const nextRateLimit = {
1230
+ ...authOptions.rateLimit ?? {},
1231
+ customRules: {
1232
+ ...KITCN_DISABLED_RATE_LIMIT_RULES,
1233
+ ...authOptions.rateLimit?.customRules ?? {}
1234
+ }
1235
+ };
1236
+ return {
1237
+ ...authOptions,
1238
+ rateLimit: nextRateLimit
1239
+ };
1240
+ };
1241
+ const withoutTriggers = (authOptions) => {
1242
+ const { triggers: _triggers, ...options } = authOptions;
1243
+ return options;
1244
+ };
1245
+ const createLazyAuthProxy = (resolve) => new Proxy({}, { get(_target, prop, receiver) {
1246
+ const auth = resolve();
1247
+ const value = Reflect.get(auth, prop, receiver);
1248
+ return typeof value === "function" ? value.bind(auth) : value;
1249
+ } });
1250
+ const AUTH_RUNTIME_PROCEDURE_TYPES = {
1251
+ create: "mutation",
1252
+ deleteMany: "mutation",
1253
+ deleteOne: "mutation",
1254
+ findMany: "query",
1255
+ findOne: "query",
1256
+ getLatestJwks: "action",
1257
+ rotateKeys: "action",
1258
+ updateMany: "mutation",
1259
+ updateOne: "mutation"
1260
+ };
1261
+ const createGeneratedInternalFunctionReference = (name) => createGeneratedFunctionReference(name);
1262
+ const resolveAuthFunctions = (internal, moduleName) => {
1263
+ const existing = internal?.[moduleName] ?? {};
1264
+ return {
1265
+ create: existing.create ?? createGeneratedInternalFunctionReference(`${moduleName}:create`),
1266
+ deleteMany: existing.deleteMany ?? createGeneratedInternalFunctionReference(`${moduleName}:deleteMany`),
1267
+ deleteOne: existing.deleteOne ?? createGeneratedInternalFunctionReference(`${moduleName}:deleteOne`),
1268
+ findMany: existing.findMany ?? createGeneratedInternalFunctionReference(`${moduleName}:findMany`),
1269
+ findOne: existing.findOne ?? createGeneratedInternalFunctionReference(`${moduleName}:findOne`),
1270
+ updateMany: existing.updateMany ?? createGeneratedInternalFunctionReference(`${moduleName}:updateMany`),
1271
+ updateOne: existing.updateOne ?? createGeneratedInternalFunctionReference(`${moduleName}:updateOne`)
1272
+ };
1273
+ };
1274
+ const decorateProcedureExport = (value, procedureType) => {
1275
+ if (value === null || typeof value !== "object" && typeof value !== "function") return;
1276
+ const procedure = value;
1277
+ if (typeof procedure._handler !== "function") return;
1278
+ procedure._crpcMeta = {
1279
+ ...procedure._crpcMeta ?? {},
1280
+ internal: true,
1281
+ type: procedureType
1282
+ };
1283
+ if (typeof procedure.__kitcnRawHandler !== "function") procedure.__kitcnRawHandler = ({ ctx, input }) => procedure._handler?.(ctx, input);
1284
+ };
1285
+ const decorateAuthRuntimeProcedures = (exportsObject) => {
1286
+ for (const [name, procedureType] of Object.entries(AUTH_RUNTIME_PROCEDURE_TYPES)) decorateProcedureExport(exportsObject[name], procedureType);
1287
+ return exportsObject;
1288
+ };
1289
+ const createAuthRuntime = (config) => {
1290
+ const authDefinition = resolveGeneratedAuthDefinition(config.auth, getInvalidAuthDefinitionExportReason());
1291
+ const authFunctions = resolveAuthFunctions(config.internal, config.moduleName);
1292
+ const resolveRuntimeTriggers = (ctx) => authDefinition(ctx).triggers;
1293
+ const authClient = createClient({
1294
+ authFunctions,
1295
+ schema: config.schema,
1296
+ ...config.context ? { context: config.context } : {},
1297
+ triggers: resolveRuntimeTriggers
1298
+ });
1299
+ const adapterGetAuthOptions = ((ctx) => withoutTriggers(authDefinition(ctx)));
1300
+ const resolveAuthOptions = (ctx) => withDatabase(withAuthDefaults(withoutTriggers(authDefinition(ctx))), ctx, (_ctx) => authClient.adapter(_ctx, adapterGetAuthOptions));
1301
+ const getAuth = (ctx) => betterAuth(resolveAuthOptions(ctx));
1302
+ const decoratedAuthApi = decorateAuthRuntimeProcedures(createApi(config.schema, getAuth, {
1303
+ ...config.context ? { context: config.context } : {},
1304
+ triggers: resolveRuntimeTriggers
1305
+ }));
1306
+ let staticAuth;
1307
+ const getStaticAuth = () => {
1308
+ staticAuth ??= betterAuth(resolveAuthOptions({}));
1309
+ return staticAuth;
1310
+ };
1311
+ return {
1312
+ authEnabled: true,
1313
+ authClient,
1314
+ getAuth,
1315
+ auth: createLazyAuthProxy(getStaticAuth),
1316
+ ...decoratedAuthApi
1317
+ };
1318
+ };
1319
+
1320
+ //#endregion
1321
+ //#region src/auth/helpers.ts
1322
+ const SESSION_TOKEN_COOKIE_NAME = "better-auth.session_token";
1323
+ const normalizeSignal = (value) => {
1324
+ if (typeof value !== "string") return;
1325
+ const trimmed = value.trim();
1326
+ return trimmed.length > 0 ? trimmed : void 0;
1327
+ };
1328
+ const parseSessionTokenFromCookie = (cookieHeader) => {
1329
+ if (!cookieHeader) return null;
1330
+ const parts = cookieHeader.split(";");
1331
+ for (const rawPart of parts) {
1332
+ const part = rawPart.trim();
1333
+ const equalsIndex = part.indexOf("=");
1334
+ if (equalsIndex <= 0) continue;
1335
+ const cookieName = part.slice(0, equalsIndex);
1336
+ const normalizedCookieName = cookieName.startsWith("__Secure-") ? cookieName.slice(9) : cookieName;
1337
+ if (!(normalizedCookieName === SESSION_TOKEN_COOKIE_NAME || normalizedCookieName.endsWith(".session_token") || normalizedCookieName === "session_token")) continue;
1338
+ const value = part.slice(equalsIndex + 1);
1339
+ return value ? decodeURIComponent(value) : null;
1340
+ }
1341
+ return null;
1342
+ };
1343
+ const getCookieHeaderFromCtx = (ctx) => {
1344
+ const headers = (ctx?.req)?.headers;
1345
+ if (!headers) return null;
1346
+ if (headers instanceof Headers) return headers.get("cookie");
1347
+ const cookie = headers.cookie ?? headers.Cookie ?? headers["set-cookie"] ?? headers["Set-Cookie"];
1348
+ return typeof cookie === "string" ? cookie : null;
1349
+ };
1350
+ const getAuthUserIdentity = async (ctx) => {
1351
+ const identity = await ctx.auth.getUserIdentity();
1352
+ if (!identity) return null;
1353
+ return {
1354
+ ...identity,
1355
+ sessionId: identity.sessionId,
1356
+ userId: identity.subject
1357
+ };
1358
+ };
1359
+ const getAuthUserId = async (ctx) => {
1360
+ const identity = await getAuthUserIdentity(ctx);
1361
+ if (!identity) return null;
1362
+ return identity.subject;
1363
+ };
1364
+ async function getSession(ctx, _sessionId) {
1365
+ let sessionId = _sessionId;
1366
+ if (!sessionId) {
1367
+ const identity = await getAuthUserIdentity(ctx);
1368
+ if (!identity) return null;
1369
+ sessionId = identity.sessionId;
1370
+ }
1371
+ if (!sessionId) return null;
1372
+ return await getByIdWithOrmQueryFallback(ctx, "session", sessionId);
1373
+ }
1374
+ const getSessionNetworkSignals = async (ctx, session) => {
1375
+ const resolvedSession = session ?? await getSession(ctx);
1376
+ if (!resolvedSession) return {};
1377
+ const ip = normalizeSignal(resolvedSession.ipAddress);
1378
+ const userAgent = normalizeSignal(resolvedSession.userAgent);
1379
+ return {
1380
+ ...ip ? { ip } : {},
1381
+ ...userAgent ? { userAgent } : {}
1382
+ };
1383
+ };
1384
+ const getHeaders = async (ctx, session) => {
1385
+ const resolvedSession = session ?? await getSession(ctx);
1386
+ if (!resolvedSession) {
1387
+ const sessionToken = parseSessionTokenFromCookie(getCookieHeaderFromCtx(ctx));
1388
+ if (sessionToken) return new Headers({ authorization: `Bearer ${sessionToken}` });
1389
+ return new Headers();
1390
+ }
1391
+ return new Headers({
1392
+ ...resolvedSession?.token ? { authorization: `Bearer ${resolvedSession.token}` } : {},
1393
+ ...resolvedSession?.ipAddress ? { "x-forwarded-for": resolvedSession.ipAddress } : {}
1394
+ });
1395
+ };
1396
+
1397
+ //#endregion
1398
+ export { adapterArgsValidator, adapterConfig, adapterWhereValidator, checkUniqueFields, convex, createApi, createAuthRuntime, createClient, createDisabledAuthRuntime, createHandler, dbAdapter, defineAuth, deleteManyHandler, deleteOneHandler, findManyHandler, findOneHandler, getAuthUserId, getAuthUserIdentity, getGeneratedAuthDisabledReason, getHeaders, getInvalidAuthDefinitionExportReason, getSession, getSessionNetworkSignals, handlePagination, hasUniqueFields, httpAdapter, listOne, paginate, resolveGeneratedAuthDefinition, selectFields, updateManyHandler, updateOneHandler };