@better-auth/mongo-adapter 1.5.5 → 1.5.7-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,6 +1,5 @@
1
1
  import { createAdapterFactory } from "@better-auth/core/db/adapter";
2
- import { ObjectId } from "mongodb";
3
-
2
+ import { ObjectId, UUID } from "mongodb";
4
3
  //#region src/mongodb-adapter.ts
5
4
  var MongoAdapterError = class extends Error {
6
5
  constructor(code, message) {
@@ -17,27 +16,36 @@ const mongodbAdapter = (db, config) => {
17
16
  };
18
17
  const createCustomAdapter = (db, session) => ({ getFieldAttributes, getFieldName, schema, getDefaultModelName, options }) => {
19
18
  const customIdGen = getCustomIdGenerator(options);
19
+ const useUUIDs = options.advanced?.database?.generateId === "uuid";
20
+ function coerceToIdType(value) {
21
+ if (useUUIDs) return new UUID(value);
22
+ return new ObjectId(value);
23
+ }
24
+ function isIdInstance(value) {
25
+ if (useUUIDs) return value instanceof UUID;
26
+ return value instanceof ObjectId;
27
+ }
20
28
  function serializeID({ field, value, model }) {
21
29
  if (customIdGen) return value;
22
30
  model = getDefaultModelName(model);
23
31
  if (field === "id" || field === "_id" || schema[model].fields[field]?.references?.field === "id") {
24
32
  if (value === null || value === void 0) return value;
25
33
  if (typeof value !== "string") {
26
- if (value instanceof ObjectId) return value;
34
+ if (isIdInstance(value)) return value;
27
35
  if (Array.isArray(value)) return value.map((v) => {
28
36
  if (v === null || v === void 0) return v;
29
37
  if (typeof v === "string") try {
30
- return new ObjectId(v);
38
+ return coerceToIdType(v);
31
39
  } catch {
32
40
  return v;
33
41
  }
34
- if (v instanceof ObjectId) return v;
42
+ if (isIdInstance(v)) return v;
35
43
  throw new MongoAdapterError("INVALID_ID", "Invalid id value");
36
44
  });
37
45
  throw new MongoAdapterError("INVALID_ID", "Invalid id value");
38
46
  }
39
47
  try {
40
- return new ObjectId(value);
48
+ return coerceToIdType(value);
41
49
  } catch {
42
50
  return value;
43
51
  }
@@ -350,30 +358,33 @@ const mongodbAdapter = (db, config) => {
350
358
  if (field === "_id" || fieldAttributes.references?.field === "id") {
351
359
  if (customIdGen) return data;
352
360
  if (action !== "create" && action !== "update") return data;
353
- if (data instanceof ObjectId) return data;
361
+ const IdClass = options.advanced?.database?.generateId === "uuid" ? UUID : ObjectId;
362
+ if (data instanceof IdClass) return data;
354
363
  if (Array.isArray(data)) return data.map((v) => {
355
364
  if (typeof v === "string") try {
356
- return new ObjectId(v);
365
+ return new IdClass(v);
357
366
  } catch {
358
367
  return v;
359
368
  }
360
369
  return v;
361
370
  });
362
371
  if (typeof data === "string") try {
363
- return new ObjectId(data);
372
+ return new IdClass(data);
364
373
  } catch {
365
374
  return data;
366
375
  }
367
376
  if (fieldAttributes?.references?.field === "id" && !fieldAttributes?.required && data === null) return null;
368
377
  if (action === "update") return data;
369
- return new ObjectId();
378
+ return new IdClass();
370
379
  }
371
380
  return data;
372
381
  },
373
382
  customTransformOutput({ data, field, fieldAttributes }) {
374
383
  if (field === "id" || fieldAttributes.references?.field === "id") {
384
+ if (data instanceof UUID) return data.toString();
375
385
  if (data instanceof ObjectId) return data.toHexString();
376
386
  if (Array.isArray(data)) return data.map((v) => {
387
+ if (v instanceof UUID) return v.toString();
377
388
  if (v instanceof ObjectId) return v.toHexString();
378
389
  return v;
379
390
  });
@@ -406,7 +417,7 @@ function escapeForMongoRegex(input, maxLength = 256) {
406
417
  if (typeof input !== "string") return "";
407
418
  return input.slice(0, maxLength).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
408
419
  }
409
-
410
420
  //#endregion
411
421
  export { mongodbAdapter };
422
+
412
423
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/mongodb-adapter.ts"],"sourcesContent":["import type { BetterAuthOptions } from \"@better-auth/core\";\nimport type {\n\tAdapterFactoryCustomizeAdapterCreator,\n\tAdapterFactoryOptions,\n\tDBAdapter,\n\tDBAdapterDebugLogOption,\n\tWhere,\n} from \"@better-auth/core/db/adapter\";\nimport { createAdapterFactory } from \"@better-auth/core/db/adapter\";\nimport type { ClientSession, Db, MongoClient } from \"mongodb\";\nimport { ObjectId } from \"mongodb\";\n\nclass MongoAdapterError extends Error {\n\tconstructor(\n\t\tpublic code: \"INVALID_ID\" | \"UNSUPPORTED_OPERATOR\",\n\t\tmessage: string,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"MongoAdapterError\";\n\t}\n}\n\nexport interface MongoDBAdapterConfig {\n\t/**\n\t * MongoDB client instance\n\t * If not provided, Database transactions won't be enabled.\n\t */\n\tclient?: MongoClient | undefined;\n\t/**\n\t * Enable debug logs for the adapter\n\t *\n\t * @default false\n\t */\n\tdebugLogs?: DBAdapterDebugLogOption | undefined;\n\t/**\n\t * Use plural table names\n\t *\n\t * @default false\n\t */\n\tusePlural?: boolean | undefined;\n\t/**\n\t * Whether to execute multiple operations in a transaction.\n\t *\n\t * ⚠️ Important:\n\t * - Defaults to `true` when a MongoDB client is provided.\n\t * - If your MongoDB instance does not support transactions\n\t * (e.g. standalone server without a replica set),\n\t * you must explicitly set `transaction: false`.\n\t */\n\ttransaction?: boolean | undefined;\n}\n\nexport const mongodbAdapter = (\n\tdb: Db,\n\tconfig?: MongoDBAdapterConfig | undefined,\n) => {\n\tlet lazyOptions: BetterAuthOptions | null;\n\n\tconst getCustomIdGenerator = (options: BetterAuthOptions) => {\n\t\tconst generator = options.advanced?.database?.generateId;\n\t\tif (typeof generator === \"function\") {\n\t\t\treturn generator;\n\t\t}\n\t\treturn undefined;\n\t};\n\n\tconst createCustomAdapter =\n\t\t(\n\t\t\tdb: Db,\n\t\t\tsession?: ClientSession | undefined,\n\t\t): AdapterFactoryCustomizeAdapterCreator =>\n\t\t({\n\t\t\tgetFieldAttributes,\n\t\t\tgetFieldName,\n\t\t\tschema,\n\t\t\tgetDefaultModelName,\n\t\t\toptions,\n\t\t}) => {\n\t\t\tconst customIdGen = getCustomIdGenerator(options);\n\n\t\t\tfunction serializeID({\n\t\t\t\tfield,\n\t\t\t\tvalue,\n\t\t\t\tmodel,\n\t\t\t}: {\n\t\t\t\tfield: string;\n\t\t\t\tvalue: any;\n\t\t\t\tmodel: string;\n\t\t\t}) {\n\t\t\t\tif (customIdGen) {\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t\tmodel = getDefaultModelName(model);\n\t\t\t\tif (\n\t\t\t\t\tfield === \"id\" ||\n\t\t\t\t\tfield === \"_id\" ||\n\t\t\t\t\tschema[model]!.fields[field]?.references?.field === \"id\"\n\t\t\t\t) {\n\t\t\t\t\tif (value === null || value === undefined) {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof value !== \"string\") {\n\t\t\t\t\t\tif (value instanceof ObjectId) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\t\t\treturn value.map((v) => {\n\t\t\t\t\t\t\t\tif (v === null || v === undefined) {\n\t\t\t\t\t\t\t\t\treturn v;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (typeof v === \"string\") {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\treturn new ObjectId(v);\n\t\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\t\treturn v;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (v instanceof ObjectId) {\n\t\t\t\t\t\t\t\t\treturn v;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthrow new MongoAdapterError(\"INVALID_ID\", \"Invalid id value\");\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow new MongoAdapterError(\"INVALID_ID\", \"Invalid id value\");\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn new ObjectId(value);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t\tfunction convertWhereClause({\n\t\t\t\twhere,\n\t\t\t\tmodel,\n\t\t\t}: {\n\t\t\t\twhere: Where[];\n\t\t\t\tmodel: string;\n\t\t\t}) {\n\t\t\t\tif (!where.length) return {};\n\t\t\t\tconst conditions = where.map((w) => {\n\t\t\t\t\tconst {\n\t\t\t\t\t\tfield: field_,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\toperator = \"eq\",\n\t\t\t\t\t\tconnector = \"AND\",\n\t\t\t\t\t} = w;\n\t\t\t\t\tlet condition: any;\n\t\t\t\t\tlet field = getFieldName({ model, field: field_ });\n\t\t\t\t\tif (field === \"id\") field = \"_id\";\n\t\t\t\t\tswitch (operator.toLowerCase()) {\n\t\t\t\t\t\tcase \"eq\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: serializeID({\n\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"in\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: {\n\t\t\t\t\t\t\t\t\t$in: Array.isArray(value)\n\t\t\t\t\t\t\t\t\t\t? value.map((v) => serializeID({ field, value: v, model }))\n\t\t\t\t\t\t\t\t\t\t: [serializeID({ field, value, model })],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"not_in\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: {\n\t\t\t\t\t\t\t\t\t$nin: Array.isArray(value)\n\t\t\t\t\t\t\t\t\t\t? value.map((v) => serializeID({ field, value: v, model }))\n\t\t\t\t\t\t\t\t\t\t: [serializeID({ field, value, model })],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"gt\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: {\n\t\t\t\t\t\t\t\t\t$gt: serializeID({\n\t\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"gte\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: {\n\t\t\t\t\t\t\t\t\t$gte: serializeID({\n\t\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"lt\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: {\n\t\t\t\t\t\t\t\t\t$lt: serializeID({\n\t\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"lte\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: {\n\t\t\t\t\t\t\t\t\t$lte: serializeID({\n\t\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"ne\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: {\n\t\t\t\t\t\t\t\t\t$ne: serializeID({\n\t\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"contains\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: {\n\t\t\t\t\t\t\t\t\t$regex: `.*${escapeForMongoRegex(value as string)}.*`,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"starts_with\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: { $regex: `^${escapeForMongoRegex(value as string)}` },\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"ends_with\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: { $regex: `${escapeForMongoRegex(value as string)}$` },\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow new MongoAdapterError(\n\t\t\t\t\t\t\t\t\"UNSUPPORTED_OPERATOR\",\n\t\t\t\t\t\t\t\t`Unsupported operator: ${operator}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn { condition, connector };\n\t\t\t\t});\n\t\t\t\tif (conditions.length === 1) {\n\t\t\t\t\treturn conditions[0]!.condition;\n\t\t\t\t}\n\t\t\t\tconst andConditions = conditions\n\t\t\t\t\t.filter((c) => c.connector === \"AND\")\n\t\t\t\t\t.map((c) => c.condition);\n\t\t\t\tconst orConditions = conditions\n\t\t\t\t\t.filter((c) => c.connector === \"OR\")\n\t\t\t\t\t.map((c) => c.condition);\n\n\t\t\t\tlet clause = {};\n\t\t\t\tif (andConditions.length) {\n\t\t\t\t\tclause = { ...clause, $and: andConditions };\n\t\t\t\t}\n\t\t\t\tif (orConditions.length) {\n\t\t\t\t\tclause = { ...clause, $or: orConditions };\n\t\t\t\t}\n\t\t\t\treturn clause;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tasync create({ model, data: values }) {\n\t\t\t\t\tconst res = await db.collection(model).insertOne(values, { session });\n\t\t\t\t\tconst insertedData = { _id: res.insertedId.toString(), ...values };\n\t\t\t\t\treturn insertedData as any;\n\t\t\t\t},\n\t\t\t\tasync findOne({ model, where, select, join }) {\n\t\t\t\t\tconst matchStage = where\n\t\t\t\t\t\t? { $match: convertWhereClause({ where, model }) }\n\t\t\t\t\t\t: { $match: {} };\n\t\t\t\t\tconst pipeline: any[] = [matchStage];\n\n\t\t\t\t\tif (join) {\n\t\t\t\t\t\tfor (const [joinedModel, joinConfig] of Object.entries(join)) {\n\t\t\t\t\t\t\tconst localField = getFieldName({\n\t\t\t\t\t\t\t\tfield: joinConfig.on.from,\n\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconst foreignField = getFieldName({\n\t\t\t\t\t\t\t\tfield: joinConfig.on.to,\n\t\t\t\t\t\t\t\tmodel: joinedModel,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tconst localFieldName = localField === \"id\" ? \"_id\" : localField;\n\t\t\t\t\t\t\tconst foreignFieldName =\n\t\t\t\t\t\t\t\tforeignField === \"id\" ? \"_id\" : foreignField;\n\n\t\t\t\t\t\t\t// Only unwind if the foreign field has a unique constraint (one-to-one relationship)\n\t\t\t\t\t\t\tconst joinedModelSchema =\n\t\t\t\t\t\t\t\tschema[getDefaultModelName(joinedModel)];\n\t\t\t\t\t\t\tconst foreignFieldAttribute =\n\t\t\t\t\t\t\t\tjoinedModelSchema?.fields[joinConfig.on.to];\n\t\t\t\t\t\t\tconst isUnique = foreignFieldAttribute?.unique === true;\n\n\t\t\t\t\t\t\t// For unique relationships, limit is ignored (as per JoinConfig type)\n\t\t\t\t\t\t\t// For non-unique relationships, apply limit if specified\n\t\t\t\t\t\t\tconst shouldLimit = !isUnique && joinConfig.limit !== undefined;\n\t\t\t\t\t\t\tconst limit =\n\t\t\t\t\t\t\t\tjoinConfig.limit ??\n\t\t\t\t\t\t\t\toptions.advanced?.database?.defaultFindManyLimit ??\n\t\t\t\t\t\t\t\t100;\n\t\t\t\t\t\t\tif (shouldLimit && limit > 0) {\n\t\t\t\t\t\t\t\t// Use pipeline syntax to support limit\n\t\t\t\t\t\t\t\t// Construct the field reference string for the foreign field\n\t\t\t\t\t\t\t\tconst foreignFieldRef = `$${foreignFieldName}`;\n\t\t\t\t\t\t\t\tpipeline.push({\n\t\t\t\t\t\t\t\t\t$lookup: {\n\t\t\t\t\t\t\t\t\t\tfrom: joinedModel,\n\t\t\t\t\t\t\t\t\t\tlet: { localFieldValue: `$${localFieldName}` },\n\t\t\t\t\t\t\t\t\t\tpipeline: [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t$match: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$expr: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$eq: [foreignFieldRef, \"$$localFieldValue\"],\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{ $limit: limit },\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\tas: joinedModel,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Use simple syntax when no limit is needed\n\t\t\t\t\t\t\t\tpipeline.push({\n\t\t\t\t\t\t\t\t\t$lookup: {\n\t\t\t\t\t\t\t\t\t\tfrom: joinedModel,\n\t\t\t\t\t\t\t\t\t\tlocalField: localFieldName,\n\t\t\t\t\t\t\t\t\t\tforeignField: foreignFieldName,\n\t\t\t\t\t\t\t\t\t\tas: joinedModel,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (isUnique) {\n\t\t\t\t\t\t\t\t// For one-to-one relationships, unwind to flatten to a single object\n\t\t\t\t\t\t\t\tpipeline.push({\n\t\t\t\t\t\t\t\t\t$unwind: {\n\t\t\t\t\t\t\t\t\t\tpath: `$${joinedModel}`,\n\t\t\t\t\t\t\t\t\t\tpreserveNullAndEmptyArrays: true,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// For one-to-many, keep as array - no unwind\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (select) {\n\t\t\t\t\t\tconst projection: any = {};\n\t\t\t\t\t\tselect.forEach((field) => {\n\t\t\t\t\t\t\tprojection[getFieldName({ field, model })] = 1;\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t// Include joined collections in projection\n\t\t\t\t\t\tif (join) {\n\t\t\t\t\t\t\tfor (const joinedModel of Object.keys(join)) {\n\t\t\t\t\t\t\t\tprojection[joinedModel] = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tpipeline.push({ $project: projection });\n\t\t\t\t\t}\n\n\t\t\t\t\tpipeline.push({ $limit: 1 });\n\n\t\t\t\t\tconst res = await db\n\t\t\t\t\t\t.collection(model)\n\t\t\t\t\t\t.aggregate(pipeline, { session })\n\t\t\t\t\t\t.toArray();\n\n\t\t\t\t\tif (!res || res.length === 0) return null;\n\t\t\t\t\treturn res[0] as any;\n\t\t\t\t},\n\t\t\t\tasync findMany({ model, where, limit, select, offset, sortBy, join }) {\n\t\t\t\t\tconst matchStage = where\n\t\t\t\t\t\t? { $match: convertWhereClause({ where, model }) }\n\t\t\t\t\t\t: { $match: {} };\n\t\t\t\t\tconst pipeline: any[] = [matchStage];\n\n\t\t\t\t\tif (join) {\n\t\t\t\t\t\tfor (const [joinedModel, joinConfig] of Object.entries(join)) {\n\t\t\t\t\t\t\tconst localField = getFieldName({\n\t\t\t\t\t\t\t\tfield: joinConfig.on.from,\n\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconst foreignField = getFieldName({\n\t\t\t\t\t\t\t\tfield: joinConfig.on.to,\n\t\t\t\t\t\t\t\tmodel: joinedModel,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tconst localFieldName = localField === \"id\" ? \"_id\" : localField;\n\t\t\t\t\t\t\tconst foreignFieldName =\n\t\t\t\t\t\t\t\tforeignField === \"id\" ? \"_id\" : foreignField;\n\n\t\t\t\t\t\t\t// Only unwind if the foreign field has a unique constraint (one-to-one relationship)\n\t\t\t\t\t\t\tconst foreignFieldAttribute = getFieldAttributes({\n\t\t\t\t\t\t\t\tmodel: joinedModel,\n\t\t\t\t\t\t\t\tfield: joinConfig.on.to,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconst isUnique = foreignFieldAttribute?.unique === true;\n\n\t\t\t\t\t\t\t// For unique relationships, limit is ignored (as per JoinConfig type)\n\t\t\t\t\t\t\t// For non-unique relationships, apply limit if specified\n\t\t\t\t\t\t\tconst shouldLimit =\n\t\t\t\t\t\t\t\tjoinConfig.relation !== \"one-to-one\" &&\n\t\t\t\t\t\t\t\tjoinConfig.limit !== undefined;\n\n\t\t\t\t\t\t\tconst limit =\n\t\t\t\t\t\t\t\tjoinConfig.limit ??\n\t\t\t\t\t\t\t\toptions.advanced?.database?.defaultFindManyLimit ??\n\t\t\t\t\t\t\t\t100;\n\t\t\t\t\t\t\tif (shouldLimit && limit > 0) {\n\t\t\t\t\t\t\t\t// Use pipeline syntax to support limit\n\t\t\t\t\t\t\t\t// Construct the field reference string for the foreign field\n\t\t\t\t\t\t\t\tconst foreignFieldRef = `$${foreignFieldName}`;\n\t\t\t\t\t\t\t\tpipeline.push({\n\t\t\t\t\t\t\t\t\t$lookup: {\n\t\t\t\t\t\t\t\t\t\tfrom: joinedModel,\n\t\t\t\t\t\t\t\t\t\tlet: { localFieldValue: `$${localFieldName}` },\n\t\t\t\t\t\t\t\t\t\tpipeline: [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t$match: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$expr: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$eq: [foreignFieldRef, \"$$localFieldValue\"],\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{ $limit: limit },\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\tas: joinedModel,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Use simple syntax when no limit is needed\n\t\t\t\t\t\t\t\tpipeline.push({\n\t\t\t\t\t\t\t\t\t$lookup: {\n\t\t\t\t\t\t\t\t\t\tfrom: joinedModel,\n\t\t\t\t\t\t\t\t\t\tlocalField: localFieldName,\n\t\t\t\t\t\t\t\t\t\tforeignField: foreignFieldName,\n\t\t\t\t\t\t\t\t\t\tas: joinedModel,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (isUnique) {\n\t\t\t\t\t\t\t\t// For one-to-one relationships, unwind to flatten to a single object\n\t\t\t\t\t\t\t\tpipeline.push({\n\t\t\t\t\t\t\t\t\t$unwind: {\n\t\t\t\t\t\t\t\t\t\tpath: `$${joinedModel}`,\n\t\t\t\t\t\t\t\t\t\tpreserveNullAndEmptyArrays: true,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// For one-to-many, keep as array - no unwind\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (select?.length && select.length > 0) {\n\t\t\t\t\t\tconst projection: any = {};\n\t\t\t\t\t\tselect.forEach((field) => {\n\t\t\t\t\t\t\tprojection[getFieldName({ field, model })] = 1;\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t// Include joined collections in projection\n\t\t\t\t\t\tif (join) {\n\t\t\t\t\t\t\tfor (const joinedModel of Object.keys(join)) {\n\t\t\t\t\t\t\t\tprojection[joinedModel] = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tpipeline.push({ $project: projection });\n\t\t\t\t\t}\n\n\t\t\t\t\tif (sortBy) {\n\t\t\t\t\t\tpipeline.push({\n\t\t\t\t\t\t\t$sort: {\n\t\t\t\t\t\t\t\t[getFieldName({ field: sortBy.field, model })]:\n\t\t\t\t\t\t\t\t\tsortBy.direction === \"desc\" ? -1 : 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (offset) {\n\t\t\t\t\t\tpipeline.push({ $skip: offset });\n\t\t\t\t\t}\n\n\t\t\t\t\tif (limit) {\n\t\t\t\t\t\tpipeline.push({ $limit: limit });\n\t\t\t\t\t}\n\n\t\t\t\t\tconst res = await db\n\t\t\t\t\t\t.collection(model)\n\t\t\t\t\t\t.aggregate(pipeline, { session })\n\t\t\t\t\t\t.toArray();\n\n\t\t\t\t\treturn res as any;\n\t\t\t\t},\n\t\t\t\tasync count({ model, where }) {\n\t\t\t\t\tconst matchStage = where\n\t\t\t\t\t\t? { $match: convertWhereClause({ where, model }) }\n\t\t\t\t\t\t: { $match: {} };\n\t\t\t\t\tconst pipeline: any[] = [matchStage, { $count: \"total\" }];\n\n\t\t\t\t\tconst res = await db\n\t\t\t\t\t\t.collection(model)\n\t\t\t\t\t\t.aggregate(pipeline, { session })\n\t\t\t\t\t\t.toArray();\n\n\t\t\t\t\tif (!res || res.length === 0) return 0;\n\t\t\t\t\treturn res[0]?.total ?? 0;\n\t\t\t\t},\n\t\t\t\tasync update({ model, where, update: values }) {\n\t\t\t\t\tconst clause = convertWhereClause({ where, model });\n\n\t\t\t\t\tconst res = await db.collection(model).findOneAndUpdate(\n\t\t\t\t\t\tclause,\n\t\t\t\t\t\t{ $set: values as any },\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsession,\n\t\t\t\t\t\t\treturnDocument: \"after\",\n\t\t\t\t\t\t\tincludeResultMetadata: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tconst doc = (res as any)?.value ?? null;\n\t\t\t\t\tif (!doc) return null;\n\t\t\t\t\treturn doc as any;\n\t\t\t\t},\n\t\t\t\tasync updateMany({ model, where, update: values }) {\n\t\t\t\t\tconst clause = convertWhereClause({ where, model });\n\n\t\t\t\t\tconst res = await db.collection(model).updateMany(\n\t\t\t\t\t\tclause,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t$set: values as any,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ session },\n\t\t\t\t\t);\n\t\t\t\t\treturn res.modifiedCount;\n\t\t\t\t},\n\t\t\t\tasync delete({ model, where }) {\n\t\t\t\t\tconst clause = convertWhereClause({ where, model });\n\t\t\t\t\tawait db.collection(model).deleteOne(clause, { session });\n\t\t\t\t},\n\t\t\t\tasync deleteMany({ model, where }) {\n\t\t\t\t\tconst clause = convertWhereClause({ where, model });\n\t\t\t\t\tconst res = await db\n\t\t\t\t\t\t.collection(model)\n\t\t\t\t\t\t.deleteMany(clause, { session });\n\t\t\t\t\treturn res.deletedCount;\n\t\t\t\t},\n\t\t\t};\n\t\t};\n\n\tlet lazyAdapter:\n\t\t| ((options: BetterAuthOptions) => DBAdapter<BetterAuthOptions>)\n\t\t| null = null;\n\tlet adapterOptions: AdapterFactoryOptions | null = null;\n\tadapterOptions = {\n\t\tconfig: {\n\t\t\tadapterId: \"mongodb-adapter\",\n\t\t\tadapterName: \"MongoDB Adapter\",\n\t\t\tusePlural: config?.usePlural ?? false,\n\t\t\tdebugLogs: config?.debugLogs ?? false,\n\t\t\tmapKeysTransformInput: {\n\t\t\t\tid: \"_id\",\n\t\t\t},\n\t\t\tmapKeysTransformOutput: {\n\t\t\t\t_id: \"id\",\n\t\t\t},\n\t\t\tsupportsArrays: true,\n\t\t\tsupportsNumericIds: false,\n\t\t\ttransaction:\n\t\t\t\tconfig?.client && (config?.transaction ?? true)\n\t\t\t\t\t? async (cb) => {\n\t\t\t\t\t\t\tif (!config.client) {\n\t\t\t\t\t\t\t\treturn cb(lazyAdapter!(lazyOptions!));\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst session = config.client.startSession();\n\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tsession.startTransaction();\n\n\t\t\t\t\t\t\t\tconst adapter = createAdapterFactory({\n\t\t\t\t\t\t\t\t\tconfig: adapterOptions!.config,\n\t\t\t\t\t\t\t\t\tadapter: createCustomAdapter(db, session),\n\t\t\t\t\t\t\t\t})(lazyOptions!);\n\n\t\t\t\t\t\t\t\tconst result = await cb(adapter);\n\n\t\t\t\t\t\t\t\tawait session.commitTransaction();\n\t\t\t\t\t\t\t\treturn result;\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\tawait session.abortTransaction();\n\t\t\t\t\t\t\t\tthrow err;\n\t\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\t\tawait session.endSession();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t: false,\n\t\t\tcustomTransformInput({\n\t\t\t\taction,\n\t\t\t\tdata,\n\t\t\t\tfield,\n\t\t\t\tfieldAttributes,\n\t\t\t\tschema,\n\t\t\t\tmodel,\n\t\t\t\toptions,\n\t\t\t}) {\n\t\t\t\tconst customIdGen = getCustomIdGenerator(options);\n\t\t\t\tif (field === \"_id\" || fieldAttributes.references?.field === \"id\") {\n\t\t\t\t\tif (customIdGen) {\n\t\t\t\t\t\treturn data;\n\t\t\t\t\t}\n\t\t\t\t\tif (action !== \"create\" && action !== \"update\") {\n\t\t\t\t\t\treturn data;\n\t\t\t\t\t}\n\t\t\t\t\tif (data instanceof ObjectId) {\n\t\t\t\t\t\treturn data;\n\t\t\t\t\t}\n\t\t\t\t\tif (Array.isArray(data)) {\n\t\t\t\t\t\treturn data.map((v) => {\n\t\t\t\t\t\t\tif (typeof v === \"string\") {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst oid = new ObjectId(v);\n\t\t\t\t\t\t\t\t\treturn oid;\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\treturn v;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn v;\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof data === \"string\") {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst oid = new ObjectId(data);\n\t\t\t\t\t\t\treturn oid;\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\treturn data;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (\n\t\t\t\t\t\tfieldAttributes?.references?.field === \"id\" &&\n\t\t\t\t\t\t!fieldAttributes?.required &&\n\t\t\t\t\t\tdata === null\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tif (action === \"update\") {\n\t\t\t\t\t\treturn data;\n\t\t\t\t\t}\n\t\t\t\t\tconst oid = new ObjectId();\n\t\t\t\t\treturn oid;\n\t\t\t\t}\n\t\t\t\treturn data;\n\t\t\t},\n\t\t\tcustomTransformOutput({ data, field, fieldAttributes }) {\n\t\t\t\tif (field === \"id\" || fieldAttributes.references?.field === \"id\") {\n\t\t\t\t\tif (data instanceof ObjectId) {\n\t\t\t\t\t\treturn data.toHexString();\n\t\t\t\t\t}\n\t\t\t\t\tif (Array.isArray(data)) {\n\t\t\t\t\t\treturn data.map((v) => {\n\t\t\t\t\t\t\tif (v instanceof ObjectId) {\n\t\t\t\t\t\t\t\treturn v.toHexString();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn v;\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\t\t\t\treturn data;\n\t\t\t},\n\t\t\tcustomIdGenerator() {\n\t\t\t\treturn new ObjectId().toString();\n\t\t\t},\n\t\t},\n\t\tadapter: createCustomAdapter(db),\n\t};\n\tlazyAdapter = createAdapterFactory(adapterOptions);\n\n\treturn (options: BetterAuthOptions): DBAdapter<BetterAuthOptions> => {\n\t\tlazyOptions = options;\n\t\treturn lazyAdapter(options);\n\t};\n};\n\n/**\n * Safely escape user input for use in a MongoDB regex.\n * This ensures the resulting pattern is treated as literal text,\n * and not as a regex with special syntax.\n *\n * @param input - The input string to escape. Any type that isn't a string will be converted to an empty string.\n * @param maxLength - The maximum length of the input string to escape. Defaults to 256. This is to prevent DOS attacks.\n * @returns The escaped string.\n */\nfunction escapeForMongoRegex(input: string, maxLength = 256): string {\n\tif (typeof input !== \"string\") return \"\";\n\n\t// Escape all PCRE special characters\n\t// Source: PCRE docs — https://www.pcre.org/original/doc/html/pcrepattern.html\n\treturn input.slice(0, maxLength).replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n"],"mappings":";;;;AAYA,IAAM,oBAAN,cAAgC,MAAM;CACrC,YACC,AAAO,MACP,SACC;AACD,QAAM,QAAQ;EAHP;AAIP,OAAK,OAAO;;;AAkCd,MAAa,kBACZ,IACA,WACI;CACJ,IAAI;CAEJ,MAAM,wBAAwB,YAA+B;EAC5D,MAAM,YAAY,QAAQ,UAAU,UAAU;AAC9C,MAAI,OAAO,cAAc,WACxB,QAAO;;CAKT,MAAM,uBAEJ,IACA,aAEA,EACA,oBACA,cACA,QACA,qBACA,cACK;EACL,MAAM,cAAc,qBAAqB,QAAQ;EAEjD,SAAS,YAAY,EACpB,OACA,OACA,SAKE;AACF,OAAI,YACH,QAAO;AAER,WAAQ,oBAAoB,MAAM;AAClC,OACC,UAAU,QACV,UAAU,SACV,OAAO,OAAQ,OAAO,QAAQ,YAAY,UAAU,MACnD;AACD,QAAI,UAAU,QAAQ,UAAU,OAC/B,QAAO;AAER,QAAI,OAAO,UAAU,UAAU;AAC9B,SAAI,iBAAiB,SACpB,QAAO;AAER,SAAI,MAAM,QAAQ,MAAM,CACvB,QAAO,MAAM,KAAK,MAAM;AACvB,UAAI,MAAM,QAAQ,MAAM,OACvB,QAAO;AAER,UAAI,OAAO,MAAM,SAChB,KAAI;AACH,cAAO,IAAI,SAAS,EAAE;cACf;AACP,cAAO;;AAGT,UAAI,aAAa,SAChB,QAAO;AAER,YAAM,IAAI,kBAAkB,cAAc,mBAAmB;OAC5D;AAEH,WAAM,IAAI,kBAAkB,cAAc,mBAAmB;;AAE9D,QAAI;AACH,YAAO,IAAI,SAAS,MAAM;YACnB;AACP,YAAO;;;AAGT,UAAO;;EAGR,SAAS,mBAAmB,EAC3B,OACA,SAIE;AACF,OAAI,CAAC,MAAM,OAAQ,QAAO,EAAE;GAC5B,MAAM,aAAa,MAAM,KAAK,MAAM;IACnC,MAAM,EACL,OAAO,QACP,OACA,WAAW,MACX,YAAY,UACT;IACJ,IAAI;IACJ,IAAI,QAAQ,aAAa;KAAE;KAAO,OAAO;KAAQ,CAAC;AAClD,QAAI,UAAU,KAAM,SAAQ;AAC5B,YAAQ,SAAS,aAAa,EAA9B;KACC,KAAK;AACJ,kBAAY,GACV,QAAQ,YAAY;OACpB;OACA;OACA;OACA,CAAC,EACF;AACD;KACD,KAAK;AACJ,kBAAY,GACV,QAAQ,EACR,KAAK,MAAM,QAAQ,MAAM,GACtB,MAAM,KAAK,MAAM,YAAY;OAAE;OAAO,OAAO;OAAG;OAAO,CAAC,CAAC,GACzD,CAAC,YAAY;OAAE;OAAO;OAAO;OAAO,CAAC,CAAC,EACzC,EACD;AACD;KACD,KAAK;AACJ,kBAAY,GACV,QAAQ,EACR,MAAM,MAAM,QAAQ,MAAM,GACvB,MAAM,KAAK,MAAM,YAAY;OAAE;OAAO,OAAO;OAAG;OAAO,CAAC,CAAC,GACzD,CAAC,YAAY;OAAE;OAAO;OAAO;OAAO,CAAC,CAAC,EACzC,EACD;AACD;KACD,KAAK;AACJ,kBAAY,GACV,QAAQ,EACR,KAAK,YAAY;OAChB;OACA;OACA;OACA,CAAC,EACF,EACD;AACD;KACD,KAAK;AACJ,kBAAY,GACV,QAAQ,EACR,MAAM,YAAY;OACjB;OACA;OACA;OACA,CAAC,EACF,EACD;AACD;KACD,KAAK;AACJ,kBAAY,GACV,QAAQ,EACR,KAAK,YAAY;OAChB;OACA;OACA;OACA,CAAC,EACF,EACD;AACD;KACD,KAAK;AACJ,kBAAY,GACV,QAAQ,EACR,MAAM,YAAY;OACjB;OACA;OACA;OACA,CAAC,EACF,EACD;AACD;KACD,KAAK;AACJ,kBAAY,GACV,QAAQ,EACR,KAAK,YAAY;OAChB;OACA;OACA;OACA,CAAC,EACF,EACD;AACD;KACD,KAAK;AACJ,kBAAY,GACV,QAAQ,EACR,QAAQ,KAAK,oBAAoB,MAAgB,CAAC,KAClD,EACD;AACD;KACD,KAAK;AACJ,kBAAY,GACV,QAAQ,EAAE,QAAQ,IAAI,oBAAoB,MAAgB,IAAI,EAC/D;AACD;KACD,KAAK;AACJ,kBAAY,GACV,QAAQ,EAAE,QAAQ,GAAG,oBAAoB,MAAgB,CAAC,IAAI,EAC/D;AACD;KACD,QACC,OAAM,IAAI,kBACT,wBACA,yBAAyB,WACzB;;AAEH,WAAO;KAAE;KAAW;KAAW;KAC9B;AACF,OAAI,WAAW,WAAW,EACzB,QAAO,WAAW,GAAI;GAEvB,MAAM,gBAAgB,WACpB,QAAQ,MAAM,EAAE,cAAc,MAAM,CACpC,KAAK,MAAM,EAAE,UAAU;GACzB,MAAM,eAAe,WACnB,QAAQ,MAAM,EAAE,cAAc,KAAK,CACnC,KAAK,MAAM,EAAE,UAAU;GAEzB,IAAI,SAAS,EAAE;AACf,OAAI,cAAc,OACjB,UAAS;IAAE,GAAG;IAAQ,MAAM;IAAe;AAE5C,OAAI,aAAa,OAChB,UAAS;IAAE,GAAG;IAAQ,KAAK;IAAc;AAE1C,UAAO;;AAGR,SAAO;GACN,MAAM,OAAO,EAAE,OAAO,MAAM,UAAU;AAGrC,WADqB;KAAE,MADX,MAAM,GAAG,WAAW,MAAM,CAAC,UAAU,QAAQ,EAAE,SAAS,CAAC,EACrC,WAAW,UAAU;KAAE,GAAG;KAAQ;;GAGnE,MAAM,QAAQ,EAAE,OAAO,OAAO,QAAQ,QAAQ;IAI7C,MAAM,WAAkB,CAHL,QAChB,EAAE,QAAQ,mBAAmB;KAAE;KAAO;KAAO,CAAC,EAAE,GAChD,EAAE,QAAQ,EAAE,EAAE,CACmB;AAEpC,QAAI,KACH,MAAK,MAAM,CAAC,aAAa,eAAe,OAAO,QAAQ,KAAK,EAAE;KAC7D,MAAM,aAAa,aAAa;MAC/B,OAAO,WAAW,GAAG;MACrB;MACA,CAAC;KACF,MAAM,eAAe,aAAa;MACjC,OAAO,WAAW,GAAG;MACrB,OAAO;MACP,CAAC;KAEF,MAAM,iBAAiB,eAAe,OAAO,QAAQ;KACrD,MAAM,mBACL,iBAAiB,OAAO,QAAQ;KAOjC,MAAM,YAHL,OAAO,oBAAoB,YAAY,GAEpB,OAAO,WAAW,GAAG,MACD,WAAW;KAInD,MAAM,cAAc,CAAC,YAAY,WAAW,UAAU;KACtD,MAAM,QACL,WAAW,SACX,QAAQ,UAAU,UAAU,wBAC5B;AACD,SAAI,eAAe,QAAQ,GAAG;MAG7B,MAAM,kBAAkB,IAAI;AAC5B,eAAS,KAAK,EACb,SAAS;OACR,MAAM;OACN,KAAK,EAAE,iBAAiB,IAAI,kBAAkB;OAC9C,UAAU,CACT,EACC,QAAQ,EACP,OAAO,EACN,KAAK,CAAC,iBAAiB,oBAAoB,EAC3C,EACD,EACD,EACD,EAAE,QAAQ,OAAO,CACjB;OACD,IAAI;OACJ,EACD,CAAC;WAGF,UAAS,KAAK,EACb,SAAS;MACR,MAAM;MACN,YAAY;MACZ,cAAc;MACd,IAAI;MACJ,EACD,CAAC;AAGH,SAAI,SAEH,UAAS,KAAK,EACb,SAAS;MACR,MAAM,IAAI;MACV,4BAA4B;MAC5B,EACD,CAAC;;AAML,QAAI,QAAQ;KACX,MAAM,aAAkB,EAAE;AAC1B,YAAO,SAAS,UAAU;AACzB,iBAAW,aAAa;OAAE;OAAO;OAAO,CAAC,IAAI;OAC5C;AAGF,SAAI,KACH,MAAK,MAAM,eAAe,OAAO,KAAK,KAAK,CAC1C,YAAW,eAAe;AAI5B,cAAS,KAAK,EAAE,UAAU,YAAY,CAAC;;AAGxC,aAAS,KAAK,EAAE,QAAQ,GAAG,CAAC;IAE5B,MAAM,MAAM,MAAM,GAChB,WAAW,MAAM,CACjB,UAAU,UAAU,EAAE,SAAS,CAAC,CAChC,SAAS;AAEX,QAAI,CAAC,OAAO,IAAI,WAAW,EAAG,QAAO;AACrC,WAAO,IAAI;;GAEZ,MAAM,SAAS,EAAE,OAAO,OAAO,OAAO,QAAQ,QAAQ,QAAQ,QAAQ;IAIrE,MAAM,WAAkB,CAHL,QAChB,EAAE,QAAQ,mBAAmB;KAAE;KAAO;KAAO,CAAC,EAAE,GAChD,EAAE,QAAQ,EAAE,EAAE,CACmB;AAEpC,QAAI,KACH,MAAK,MAAM,CAAC,aAAa,eAAe,OAAO,QAAQ,KAAK,EAAE;KAC7D,MAAM,aAAa,aAAa;MAC/B,OAAO,WAAW,GAAG;MACrB;MACA,CAAC;KACF,MAAM,eAAe,aAAa;MACjC,OAAO,WAAW,GAAG;MACrB,OAAO;MACP,CAAC;KAEF,MAAM,iBAAiB,eAAe,OAAO,QAAQ;KACrD,MAAM,mBACL,iBAAiB,OAAO,QAAQ;KAOjC,MAAM,WAJwB,mBAAmB;MAChD,OAAO;MACP,OAAO,WAAW,GAAG;MACrB,CAAC,EACsC,WAAW;KAInD,MAAM,cACL,WAAW,aAAa,gBACxB,WAAW,UAAU;KAEtB,MAAM,QACL,WAAW,SACX,QAAQ,UAAU,UAAU,wBAC5B;AACD,SAAI,eAAe,QAAQ,GAAG;MAG7B,MAAM,kBAAkB,IAAI;AAC5B,eAAS,KAAK,EACb,SAAS;OACR,MAAM;OACN,KAAK,EAAE,iBAAiB,IAAI,kBAAkB;OAC9C,UAAU,CACT,EACC,QAAQ,EACP,OAAO,EACN,KAAK,CAAC,iBAAiB,oBAAoB,EAC3C,EACD,EACD,EACD,EAAE,QAAQ,OAAO,CACjB;OACD,IAAI;OACJ,EACD,CAAC;WAGF,UAAS,KAAK,EACb,SAAS;MACR,MAAM;MACN,YAAY;MACZ,cAAc;MACd,IAAI;MACJ,EACD,CAAC;AAGH,SAAI,SAEH,UAAS,KAAK,EACb,SAAS;MACR,MAAM,IAAI;MACV,4BAA4B;MAC5B,EACD,CAAC;;AAML,QAAI,QAAQ,UAAU,OAAO,SAAS,GAAG;KACxC,MAAM,aAAkB,EAAE;AAC1B,YAAO,SAAS,UAAU;AACzB,iBAAW,aAAa;OAAE;OAAO;OAAO,CAAC,IAAI;OAC5C;AAGF,SAAI,KACH,MAAK,MAAM,eAAe,OAAO,KAAK,KAAK,CAC1C,YAAW,eAAe;AAI5B,cAAS,KAAK,EAAE,UAAU,YAAY,CAAC;;AAGxC,QAAI,OACH,UAAS,KAAK,EACb,OAAO,GACL,aAAa;KAAE,OAAO,OAAO;KAAO;KAAO,CAAC,GAC5C,OAAO,cAAc,SAAS,KAAK,GACpC,EACD,CAAC;AAGH,QAAI,OACH,UAAS,KAAK,EAAE,OAAO,QAAQ,CAAC;AAGjC,QAAI,MACH,UAAS,KAAK,EAAE,QAAQ,OAAO,CAAC;AAQjC,WALY,MAAM,GAChB,WAAW,MAAM,CACjB,UAAU,UAAU,EAAE,SAAS,CAAC,CAChC,SAAS;;GAIZ,MAAM,MAAM,EAAE,OAAO,SAAS;IAI7B,MAAM,WAAkB,CAHL,QAChB,EAAE,QAAQ,mBAAmB;KAAE;KAAO;KAAO,CAAC,EAAE,GAChD,EAAE,QAAQ,EAAE,EAAE,EACoB,EAAE,QAAQ,SAAS,CAAC;IAEzD,MAAM,MAAM,MAAM,GAChB,WAAW,MAAM,CACjB,UAAU,UAAU,EAAE,SAAS,CAAC,CAChC,SAAS;AAEX,QAAI,CAAC,OAAO,IAAI,WAAW,EAAG,QAAO;AACrC,WAAO,IAAI,IAAI,SAAS;;GAEzB,MAAM,OAAO,EAAE,OAAO,OAAO,QAAQ,UAAU;IAC9C,MAAM,SAAS,mBAAmB;KAAE;KAAO;KAAO,CAAC;IAWnD,MAAM,OATM,MAAM,GAAG,WAAW,MAAM,CAAC,iBACtC,QACA,EAAE,MAAM,QAAe,EACvB;KACC;KACA,gBAAgB;KAChB,uBAAuB;KACvB,CACD,GACyB,SAAS;AACnC,QAAI,CAAC,IAAK,QAAO;AACjB,WAAO;;GAER,MAAM,WAAW,EAAE,OAAO,OAAO,QAAQ,UAAU;IAClD,MAAM,SAAS,mBAAmB;KAAE;KAAO;KAAO,CAAC;AASnD,YAPY,MAAM,GAAG,WAAW,MAAM,CAAC,WACtC,QACA,EACC,MAAM,QACN,EACD,EAAE,SAAS,CACX,EACU;;GAEZ,MAAM,OAAO,EAAE,OAAO,SAAS;IAC9B,MAAM,SAAS,mBAAmB;KAAE;KAAO;KAAO,CAAC;AACnD,UAAM,GAAG,WAAW,MAAM,CAAC,UAAU,QAAQ,EAAE,SAAS,CAAC;;GAE1D,MAAM,WAAW,EAAE,OAAO,SAAS;IAClC,MAAM,SAAS,mBAAmB;KAAE;KAAO;KAAO,CAAC;AAInD,YAHY,MAAM,GAChB,WAAW,MAAM,CACjB,WAAW,QAAQ,EAAE,SAAS,CAAC,EACtB;;GAEZ;;CAGH,IAAI,cAEM;CACV,IAAI,iBAA+C;AACnD,kBAAiB;EAChB,QAAQ;GACP,WAAW;GACX,aAAa;GACb,WAAW,QAAQ,aAAa;GAChC,WAAW,QAAQ,aAAa;GAChC,uBAAuB,EACtB,IAAI,OACJ;GACD,wBAAwB,EACvB,KAAK,MACL;GACD,gBAAgB;GAChB,oBAAoB;GACpB,aACC,QAAQ,WAAW,QAAQ,eAAe,QACvC,OAAO,OAAO;AACd,QAAI,CAAC,OAAO,OACX,QAAO,GAAG,YAAa,YAAa,CAAC;IAGtC,MAAM,UAAU,OAAO,OAAO,cAAc;AAE5C,QAAI;AACH,aAAQ,kBAAkB;KAO1B,MAAM,SAAS,MAAM,GALL,qBAAqB;MACpC,QAAQ,eAAgB;MACxB,SAAS,oBAAoB,IAAI,QAAQ;MACzC,CAAC,CAAC,YAAa,CAEgB;AAEhC,WAAM,QAAQ,mBAAmB;AACjC,YAAO;aACC,KAAK;AACb,WAAM,QAAQ,kBAAkB;AAChC,WAAM;cACG;AACT,WAAM,QAAQ,YAAY;;OAG3B;GACJ,qBAAqB,EACpB,QACA,MACA,OACA,iBACA,QACA,OACA,WACE;IACF,MAAM,cAAc,qBAAqB,QAAQ;AACjD,QAAI,UAAU,SAAS,gBAAgB,YAAY,UAAU,MAAM;AAClE,SAAI,YACH,QAAO;AAER,SAAI,WAAW,YAAY,WAAW,SACrC,QAAO;AAER,SAAI,gBAAgB,SACnB,QAAO;AAER,SAAI,MAAM,QAAQ,KAAK,CACtB,QAAO,KAAK,KAAK,MAAM;AACtB,UAAI,OAAO,MAAM,SAChB,KAAI;AAEH,cADY,IAAI,SAAS,EAAE;cAEpB;AACP,cAAO;;AAGT,aAAO;OACN;AAEH,SAAI,OAAO,SAAS,SACnB,KAAI;AAEH,aADY,IAAI,SAAS,KAAK;aAEvB;AACP,aAAO;;AAGT,SACC,iBAAiB,YAAY,UAAU,QACvC,CAAC,iBAAiB,YAClB,SAAS,KAET,QAAO;AAER,SAAI,WAAW,SACd,QAAO;AAGR,YADY,IAAI,UAAU;;AAG3B,WAAO;;GAER,sBAAsB,EAAE,MAAM,OAAO,mBAAmB;AACvD,QAAI,UAAU,QAAQ,gBAAgB,YAAY,UAAU,MAAM;AACjE,SAAI,gBAAgB,SACnB,QAAO,KAAK,aAAa;AAE1B,SAAI,MAAM,QAAQ,KAAK,CACtB,QAAO,KAAK,KAAK,MAAM;AACtB,UAAI,aAAa,SAChB,QAAO,EAAE,aAAa;AAEvB,aAAO;OACN;AAEH,YAAO;;AAER,WAAO;;GAER,oBAAoB;AACnB,WAAO,IAAI,UAAU,CAAC,UAAU;;GAEjC;EACD,SAAS,oBAAoB,GAAG;EAChC;AACD,eAAc,qBAAqB,eAAe;AAElD,SAAQ,YAA6D;AACpE,gBAAc;AACd,SAAO,YAAY,QAAQ;;;;;;;;;;;;AAa7B,SAAS,oBAAoB,OAAe,YAAY,KAAa;AACpE,KAAI,OAAO,UAAU,SAAU,QAAO;AAItC,QAAO,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,uBAAuB,OAAO"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/mongodb-adapter.ts"],"sourcesContent":["import type { BetterAuthOptions } from \"@better-auth/core\";\nimport type {\n\tAdapterFactoryCustomizeAdapterCreator,\n\tAdapterFactoryOptions,\n\tDBAdapter,\n\tDBAdapterDebugLogOption,\n\tWhere,\n} from \"@better-auth/core/db/adapter\";\nimport { createAdapterFactory } from \"@better-auth/core/db/adapter\";\nimport type { ClientSession, Db, MongoClient } from \"mongodb\";\nimport { ObjectId, UUID } from \"mongodb\";\n\nclass MongoAdapterError extends Error {\n\tconstructor(\n\t\tpublic code: \"INVALID_ID\" | \"UNSUPPORTED_OPERATOR\",\n\t\tmessage: string,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"MongoAdapterError\";\n\t}\n}\n\nexport interface MongoDBAdapterConfig {\n\t/**\n\t * MongoDB client instance\n\t * If not provided, Database transactions won't be enabled.\n\t */\n\tclient?: MongoClient | undefined;\n\t/**\n\t * Enable debug logs for the adapter\n\t *\n\t * @default false\n\t */\n\tdebugLogs?: DBAdapterDebugLogOption | undefined;\n\t/**\n\t * Use plural table names\n\t *\n\t * @default false\n\t */\n\tusePlural?: boolean | undefined;\n\t/**\n\t * Whether to execute multiple operations in a transaction.\n\t *\n\t * ⚠️ Important:\n\t * - Defaults to `true` when a MongoDB client is provided.\n\t * - If your MongoDB instance does not support transactions\n\t * (e.g. standalone server without a replica set),\n\t * you must explicitly set `transaction: false`.\n\t */\n\ttransaction?: boolean | undefined;\n}\n\nexport const mongodbAdapter = (\n\tdb: Db,\n\tconfig?: MongoDBAdapterConfig | undefined,\n) => {\n\tlet lazyOptions: BetterAuthOptions | null;\n\n\tconst getCustomIdGenerator = (options: BetterAuthOptions) => {\n\t\tconst generator = options.advanced?.database?.generateId;\n\t\tif (typeof generator === \"function\") {\n\t\t\treturn generator;\n\t\t}\n\t\treturn undefined;\n\t};\n\n\tconst createCustomAdapter =\n\t\t(\n\t\t\tdb: Db,\n\t\t\tsession?: ClientSession | undefined,\n\t\t): AdapterFactoryCustomizeAdapterCreator =>\n\t\t({\n\t\t\tgetFieldAttributes,\n\t\t\tgetFieldName,\n\t\t\tschema,\n\t\t\tgetDefaultModelName,\n\t\t\toptions,\n\t\t}) => {\n\t\t\tconst customIdGen = getCustomIdGenerator(options);\n\t\t\tconst useUUIDs = options.advanced?.database?.generateId === \"uuid\";\n\n\t\t\tfunction coerceToIdType(value: string): ObjectId | UUID {\n\t\t\t\tif (useUUIDs) return new UUID(value);\n\t\t\t\treturn new ObjectId(value);\n\t\t\t}\n\n\t\t\tfunction isIdInstance(value: unknown): value is ObjectId | UUID {\n\t\t\t\tif (useUUIDs) return value instanceof UUID;\n\t\t\t\treturn value instanceof ObjectId;\n\t\t\t}\n\n\t\t\tfunction serializeID({\n\t\t\t\tfield,\n\t\t\t\tvalue,\n\t\t\t\tmodel,\n\t\t\t}: {\n\t\t\t\tfield: string;\n\t\t\t\tvalue: any;\n\t\t\t\tmodel: string;\n\t\t\t}) {\n\t\t\t\tif (customIdGen) {\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t\tmodel = getDefaultModelName(model);\n\t\t\t\tif (\n\t\t\t\t\tfield === \"id\" ||\n\t\t\t\t\tfield === \"_id\" ||\n\t\t\t\t\tschema[model]!.fields[field]?.references?.field === \"id\"\n\t\t\t\t) {\n\t\t\t\t\tif (value === null || value === undefined) {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof value !== \"string\") {\n\t\t\t\t\t\tif (isIdInstance(value)) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\t\t\treturn value.map((v) => {\n\t\t\t\t\t\t\t\tif (v === null || v === undefined) {\n\t\t\t\t\t\t\t\t\treturn v;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (typeof v === \"string\") {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\treturn coerceToIdType(v);\n\t\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\t\treturn v;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (isIdInstance(v)) {\n\t\t\t\t\t\t\t\t\treturn v;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthrow new MongoAdapterError(\"INVALID_ID\", \"Invalid id value\");\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow new MongoAdapterError(\"INVALID_ID\", \"Invalid id value\");\n\t\t\t\t\t}\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn coerceToIdType(value);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t\tfunction convertWhereClause({\n\t\t\t\twhere,\n\t\t\t\tmodel,\n\t\t\t}: {\n\t\t\t\twhere: Where[];\n\t\t\t\tmodel: string;\n\t\t\t}) {\n\t\t\t\tif (!where.length) return {};\n\t\t\t\tconst conditions = where.map((w) => {\n\t\t\t\t\tconst {\n\t\t\t\t\t\tfield: field_,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\toperator = \"eq\",\n\t\t\t\t\t\tconnector = \"AND\",\n\t\t\t\t\t} = w;\n\t\t\t\t\tlet condition: any;\n\t\t\t\t\tlet field = getFieldName({ model, field: field_ });\n\t\t\t\t\tif (field === \"id\") field = \"_id\";\n\t\t\t\t\tswitch (operator.toLowerCase()) {\n\t\t\t\t\t\tcase \"eq\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: serializeID({\n\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"in\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: {\n\t\t\t\t\t\t\t\t\t$in: Array.isArray(value)\n\t\t\t\t\t\t\t\t\t\t? value.map((v) => serializeID({ field, value: v, model }))\n\t\t\t\t\t\t\t\t\t\t: [serializeID({ field, value, model })],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"not_in\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: {\n\t\t\t\t\t\t\t\t\t$nin: Array.isArray(value)\n\t\t\t\t\t\t\t\t\t\t? value.map((v) => serializeID({ field, value: v, model }))\n\t\t\t\t\t\t\t\t\t\t: [serializeID({ field, value, model })],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"gt\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: {\n\t\t\t\t\t\t\t\t\t$gt: serializeID({\n\t\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"gte\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: {\n\t\t\t\t\t\t\t\t\t$gte: serializeID({\n\t\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"lt\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: {\n\t\t\t\t\t\t\t\t\t$lt: serializeID({\n\t\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"lte\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: {\n\t\t\t\t\t\t\t\t\t$lte: serializeID({\n\t\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"ne\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: {\n\t\t\t\t\t\t\t\t\t$ne: serializeID({\n\t\t\t\t\t\t\t\t\t\tfield,\n\t\t\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"contains\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: {\n\t\t\t\t\t\t\t\t\t$regex: `.*${escapeForMongoRegex(value as string)}.*`,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"starts_with\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: { $regex: `^${escapeForMongoRegex(value as string)}` },\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"ends_with\":\n\t\t\t\t\t\t\tcondition = {\n\t\t\t\t\t\t\t\t[field]: { $regex: `${escapeForMongoRegex(value as string)}$` },\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow new MongoAdapterError(\n\t\t\t\t\t\t\t\t\"UNSUPPORTED_OPERATOR\",\n\t\t\t\t\t\t\t\t`Unsupported operator: ${operator}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn { condition, connector };\n\t\t\t\t});\n\t\t\t\tif (conditions.length === 1) {\n\t\t\t\t\treturn conditions[0]!.condition;\n\t\t\t\t}\n\t\t\t\tconst andConditions = conditions\n\t\t\t\t\t.filter((c) => c.connector === \"AND\")\n\t\t\t\t\t.map((c) => c.condition);\n\t\t\t\tconst orConditions = conditions\n\t\t\t\t\t.filter((c) => c.connector === \"OR\")\n\t\t\t\t\t.map((c) => c.condition);\n\n\t\t\t\tlet clause = {};\n\t\t\t\tif (andConditions.length) {\n\t\t\t\t\tclause = { ...clause, $and: andConditions };\n\t\t\t\t}\n\t\t\t\tif (orConditions.length) {\n\t\t\t\t\tclause = { ...clause, $or: orConditions };\n\t\t\t\t}\n\t\t\t\treturn clause;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tasync create({ model, data: values }) {\n\t\t\t\t\tconst res = await db.collection(model).insertOne(values, { session });\n\t\t\t\t\tconst insertedData = { _id: res.insertedId.toString(), ...values };\n\t\t\t\t\treturn insertedData as any;\n\t\t\t\t},\n\t\t\t\tasync findOne({ model, where, select, join }) {\n\t\t\t\t\tconst matchStage = where\n\t\t\t\t\t\t? { $match: convertWhereClause({ where, model }) }\n\t\t\t\t\t\t: { $match: {} };\n\t\t\t\t\tconst pipeline: any[] = [matchStage];\n\n\t\t\t\t\tif (join) {\n\t\t\t\t\t\tfor (const [joinedModel, joinConfig] of Object.entries(join)) {\n\t\t\t\t\t\t\tconst localField = getFieldName({\n\t\t\t\t\t\t\t\tfield: joinConfig.on.from,\n\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconst foreignField = getFieldName({\n\t\t\t\t\t\t\t\tfield: joinConfig.on.to,\n\t\t\t\t\t\t\t\tmodel: joinedModel,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tconst localFieldName = localField === \"id\" ? \"_id\" : localField;\n\t\t\t\t\t\t\tconst foreignFieldName =\n\t\t\t\t\t\t\t\tforeignField === \"id\" ? \"_id\" : foreignField;\n\n\t\t\t\t\t\t\t// Only unwind if the foreign field has a unique constraint (one-to-one relationship)\n\t\t\t\t\t\t\tconst joinedModelSchema =\n\t\t\t\t\t\t\t\tschema[getDefaultModelName(joinedModel)];\n\t\t\t\t\t\t\tconst foreignFieldAttribute =\n\t\t\t\t\t\t\t\tjoinedModelSchema?.fields[joinConfig.on.to];\n\t\t\t\t\t\t\tconst isUnique = foreignFieldAttribute?.unique === true;\n\n\t\t\t\t\t\t\t// For unique relationships, limit is ignored (as per JoinConfig type)\n\t\t\t\t\t\t\t// For non-unique relationships, apply limit if specified\n\t\t\t\t\t\t\tconst shouldLimit = !isUnique && joinConfig.limit !== undefined;\n\t\t\t\t\t\t\tconst limit =\n\t\t\t\t\t\t\t\tjoinConfig.limit ??\n\t\t\t\t\t\t\t\toptions.advanced?.database?.defaultFindManyLimit ??\n\t\t\t\t\t\t\t\t100;\n\t\t\t\t\t\t\tif (shouldLimit && limit > 0) {\n\t\t\t\t\t\t\t\t// Use pipeline syntax to support limit\n\t\t\t\t\t\t\t\t// Construct the field reference string for the foreign field\n\t\t\t\t\t\t\t\tconst foreignFieldRef = `$${foreignFieldName}`;\n\t\t\t\t\t\t\t\tpipeline.push({\n\t\t\t\t\t\t\t\t\t$lookup: {\n\t\t\t\t\t\t\t\t\t\tfrom: joinedModel,\n\t\t\t\t\t\t\t\t\t\tlet: { localFieldValue: `$${localFieldName}` },\n\t\t\t\t\t\t\t\t\t\tpipeline: [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t$match: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$expr: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$eq: [foreignFieldRef, \"$$localFieldValue\"],\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{ $limit: limit },\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\tas: joinedModel,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Use simple syntax when no limit is needed\n\t\t\t\t\t\t\t\tpipeline.push({\n\t\t\t\t\t\t\t\t\t$lookup: {\n\t\t\t\t\t\t\t\t\t\tfrom: joinedModel,\n\t\t\t\t\t\t\t\t\t\tlocalField: localFieldName,\n\t\t\t\t\t\t\t\t\t\tforeignField: foreignFieldName,\n\t\t\t\t\t\t\t\t\t\tas: joinedModel,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (isUnique) {\n\t\t\t\t\t\t\t\t// For one-to-one relationships, unwind to flatten to a single object\n\t\t\t\t\t\t\t\tpipeline.push({\n\t\t\t\t\t\t\t\t\t$unwind: {\n\t\t\t\t\t\t\t\t\t\tpath: `$${joinedModel}`,\n\t\t\t\t\t\t\t\t\t\tpreserveNullAndEmptyArrays: true,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// For one-to-many, keep as array - no unwind\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (select) {\n\t\t\t\t\t\tconst projection: any = {};\n\t\t\t\t\t\tselect.forEach((field) => {\n\t\t\t\t\t\t\tprojection[getFieldName({ field, model })] = 1;\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t// Include joined collections in projection\n\t\t\t\t\t\tif (join) {\n\t\t\t\t\t\t\tfor (const joinedModel of Object.keys(join)) {\n\t\t\t\t\t\t\t\tprojection[joinedModel] = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tpipeline.push({ $project: projection });\n\t\t\t\t\t}\n\n\t\t\t\t\tpipeline.push({ $limit: 1 });\n\n\t\t\t\t\tconst res = await db\n\t\t\t\t\t\t.collection(model)\n\t\t\t\t\t\t.aggregate(pipeline, { session })\n\t\t\t\t\t\t.toArray();\n\n\t\t\t\t\tif (!res || res.length === 0) return null;\n\t\t\t\t\treturn res[0] as any;\n\t\t\t\t},\n\t\t\t\tasync findMany({ model, where, limit, select, offset, sortBy, join }) {\n\t\t\t\t\tconst matchStage = where\n\t\t\t\t\t\t? { $match: convertWhereClause({ where, model }) }\n\t\t\t\t\t\t: { $match: {} };\n\t\t\t\t\tconst pipeline: any[] = [matchStage];\n\n\t\t\t\t\tif (join) {\n\t\t\t\t\t\tfor (const [joinedModel, joinConfig] of Object.entries(join)) {\n\t\t\t\t\t\t\tconst localField = getFieldName({\n\t\t\t\t\t\t\t\tfield: joinConfig.on.from,\n\t\t\t\t\t\t\t\tmodel,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconst foreignField = getFieldName({\n\t\t\t\t\t\t\t\tfield: joinConfig.on.to,\n\t\t\t\t\t\t\t\tmodel: joinedModel,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tconst localFieldName = localField === \"id\" ? \"_id\" : localField;\n\t\t\t\t\t\t\tconst foreignFieldName =\n\t\t\t\t\t\t\t\tforeignField === \"id\" ? \"_id\" : foreignField;\n\n\t\t\t\t\t\t\t// Only unwind if the foreign field has a unique constraint (one-to-one relationship)\n\t\t\t\t\t\t\tconst foreignFieldAttribute = getFieldAttributes({\n\t\t\t\t\t\t\t\tmodel: joinedModel,\n\t\t\t\t\t\t\t\tfield: joinConfig.on.to,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconst isUnique = foreignFieldAttribute?.unique === true;\n\n\t\t\t\t\t\t\t// For unique relationships, limit is ignored (as per JoinConfig type)\n\t\t\t\t\t\t\t// For non-unique relationships, apply limit if specified\n\t\t\t\t\t\t\tconst shouldLimit =\n\t\t\t\t\t\t\t\tjoinConfig.relation !== \"one-to-one\" &&\n\t\t\t\t\t\t\t\tjoinConfig.limit !== undefined;\n\n\t\t\t\t\t\t\tconst limit =\n\t\t\t\t\t\t\t\tjoinConfig.limit ??\n\t\t\t\t\t\t\t\toptions.advanced?.database?.defaultFindManyLimit ??\n\t\t\t\t\t\t\t\t100;\n\t\t\t\t\t\t\tif (shouldLimit && limit > 0) {\n\t\t\t\t\t\t\t\t// Use pipeline syntax to support limit\n\t\t\t\t\t\t\t\t// Construct the field reference string for the foreign field\n\t\t\t\t\t\t\t\tconst foreignFieldRef = `$${foreignFieldName}`;\n\t\t\t\t\t\t\t\tpipeline.push({\n\t\t\t\t\t\t\t\t\t$lookup: {\n\t\t\t\t\t\t\t\t\t\tfrom: joinedModel,\n\t\t\t\t\t\t\t\t\t\tlet: { localFieldValue: `$${localFieldName}` },\n\t\t\t\t\t\t\t\t\t\tpipeline: [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t$match: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$expr: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$eq: [foreignFieldRef, \"$$localFieldValue\"],\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t{ $limit: limit },\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\tas: joinedModel,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Use simple syntax when no limit is needed\n\t\t\t\t\t\t\t\tpipeline.push({\n\t\t\t\t\t\t\t\t\t$lookup: {\n\t\t\t\t\t\t\t\t\t\tfrom: joinedModel,\n\t\t\t\t\t\t\t\t\t\tlocalField: localFieldName,\n\t\t\t\t\t\t\t\t\t\tforeignField: foreignFieldName,\n\t\t\t\t\t\t\t\t\t\tas: joinedModel,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (isUnique) {\n\t\t\t\t\t\t\t\t// For one-to-one relationships, unwind to flatten to a single object\n\t\t\t\t\t\t\t\tpipeline.push({\n\t\t\t\t\t\t\t\t\t$unwind: {\n\t\t\t\t\t\t\t\t\t\tpath: `$${joinedModel}`,\n\t\t\t\t\t\t\t\t\t\tpreserveNullAndEmptyArrays: true,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// For one-to-many, keep as array - no unwind\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (select?.length && select.length > 0) {\n\t\t\t\t\t\tconst projection: any = {};\n\t\t\t\t\t\tselect.forEach((field) => {\n\t\t\t\t\t\t\tprojection[getFieldName({ field, model })] = 1;\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t// Include joined collections in projection\n\t\t\t\t\t\tif (join) {\n\t\t\t\t\t\t\tfor (const joinedModel of Object.keys(join)) {\n\t\t\t\t\t\t\t\tprojection[joinedModel] = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tpipeline.push({ $project: projection });\n\t\t\t\t\t}\n\n\t\t\t\t\tif (sortBy) {\n\t\t\t\t\t\tpipeline.push({\n\t\t\t\t\t\t\t$sort: {\n\t\t\t\t\t\t\t\t[getFieldName({ field: sortBy.field, model })]:\n\t\t\t\t\t\t\t\t\tsortBy.direction === \"desc\" ? -1 : 1,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (offset) {\n\t\t\t\t\t\tpipeline.push({ $skip: offset });\n\t\t\t\t\t}\n\n\t\t\t\t\tif (limit) {\n\t\t\t\t\t\tpipeline.push({ $limit: limit });\n\t\t\t\t\t}\n\n\t\t\t\t\tconst res = await db\n\t\t\t\t\t\t.collection(model)\n\t\t\t\t\t\t.aggregate(pipeline, { session })\n\t\t\t\t\t\t.toArray();\n\n\t\t\t\t\treturn res as any;\n\t\t\t\t},\n\t\t\t\tasync count({ model, where }) {\n\t\t\t\t\tconst matchStage = where\n\t\t\t\t\t\t? { $match: convertWhereClause({ where, model }) }\n\t\t\t\t\t\t: { $match: {} };\n\t\t\t\t\tconst pipeline: any[] = [matchStage, { $count: \"total\" }];\n\n\t\t\t\t\tconst res = await db\n\t\t\t\t\t\t.collection(model)\n\t\t\t\t\t\t.aggregate(pipeline, { session })\n\t\t\t\t\t\t.toArray();\n\n\t\t\t\t\tif (!res || res.length === 0) return 0;\n\t\t\t\t\treturn res[0]?.total ?? 0;\n\t\t\t\t},\n\t\t\t\tasync update({ model, where, update: values }) {\n\t\t\t\t\tconst clause = convertWhereClause({ where, model });\n\n\t\t\t\t\tconst res = await db.collection(model).findOneAndUpdate(\n\t\t\t\t\t\tclause,\n\t\t\t\t\t\t{ $set: values as any },\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsession,\n\t\t\t\t\t\t\treturnDocument: \"after\",\n\t\t\t\t\t\t\tincludeResultMetadata: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tconst doc = (res as any)?.value ?? null;\n\t\t\t\t\tif (!doc) return null;\n\t\t\t\t\treturn doc as any;\n\t\t\t\t},\n\t\t\t\tasync updateMany({ model, where, update: values }) {\n\t\t\t\t\tconst clause = convertWhereClause({ where, model });\n\n\t\t\t\t\tconst res = await db.collection(model).updateMany(\n\t\t\t\t\t\tclause,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t$set: values as any,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ session },\n\t\t\t\t\t);\n\t\t\t\t\treturn res.modifiedCount;\n\t\t\t\t},\n\t\t\t\tasync delete({ model, where }) {\n\t\t\t\t\tconst clause = convertWhereClause({ where, model });\n\t\t\t\t\tawait db.collection(model).deleteOne(clause, { session });\n\t\t\t\t},\n\t\t\t\tasync deleteMany({ model, where }) {\n\t\t\t\t\tconst clause = convertWhereClause({ where, model });\n\t\t\t\t\tconst res = await db\n\t\t\t\t\t\t.collection(model)\n\t\t\t\t\t\t.deleteMany(clause, { session });\n\t\t\t\t\treturn res.deletedCount;\n\t\t\t\t},\n\t\t\t};\n\t\t};\n\n\tlet lazyAdapter:\n\t\t| ((options: BetterAuthOptions) => DBAdapter<BetterAuthOptions>)\n\t\t| null = null;\n\tlet adapterOptions: AdapterFactoryOptions | null = null;\n\tadapterOptions = {\n\t\tconfig: {\n\t\t\tadapterId: \"mongodb-adapter\",\n\t\t\tadapterName: \"MongoDB Adapter\",\n\t\t\tusePlural: config?.usePlural ?? false,\n\t\t\tdebugLogs: config?.debugLogs ?? false,\n\t\t\tmapKeysTransformInput: {\n\t\t\t\tid: \"_id\",\n\t\t\t},\n\t\t\tmapKeysTransformOutput: {\n\t\t\t\t_id: \"id\",\n\t\t\t},\n\t\t\tsupportsArrays: true,\n\t\t\tsupportsNumericIds: false,\n\t\t\ttransaction:\n\t\t\t\tconfig?.client && (config?.transaction ?? true)\n\t\t\t\t\t? async (cb) => {\n\t\t\t\t\t\t\tif (!config.client) {\n\t\t\t\t\t\t\t\treturn cb(lazyAdapter!(lazyOptions!));\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst session = config.client.startSession();\n\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tsession.startTransaction();\n\n\t\t\t\t\t\t\t\tconst adapter = createAdapterFactory({\n\t\t\t\t\t\t\t\t\tconfig: adapterOptions!.config,\n\t\t\t\t\t\t\t\t\tadapter: createCustomAdapter(db, session),\n\t\t\t\t\t\t\t\t})(lazyOptions!);\n\n\t\t\t\t\t\t\t\tconst result = await cb(adapter);\n\n\t\t\t\t\t\t\t\tawait session.commitTransaction();\n\t\t\t\t\t\t\t\treturn result;\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\tawait session.abortTransaction();\n\t\t\t\t\t\t\t\tthrow err;\n\t\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\t\tawait session.endSession();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t: false,\n\t\t\tcustomTransformInput({\n\t\t\t\taction,\n\t\t\t\tdata,\n\t\t\t\tfield,\n\t\t\t\tfieldAttributes,\n\t\t\t\tschema,\n\t\t\t\tmodel,\n\t\t\t\toptions,\n\t\t\t}) {\n\t\t\t\tconst customIdGen = getCustomIdGenerator(options);\n\t\t\t\tif (field === \"_id\" || fieldAttributes.references?.field === \"id\") {\n\t\t\t\t\tif (customIdGen) {\n\t\t\t\t\t\treturn data;\n\t\t\t\t\t}\n\t\t\t\t\tif (action !== \"create\" && action !== \"update\") {\n\t\t\t\t\t\treturn data;\n\t\t\t\t\t}\n\t\t\t\t\tconst IdClass =\n\t\t\t\t\t\toptions.advanced?.database?.generateId === \"uuid\" ? UUID : ObjectId;\n\t\t\t\t\tif (data instanceof IdClass) {\n\t\t\t\t\t\treturn data;\n\t\t\t\t\t}\n\t\t\t\t\tif (Array.isArray(data)) {\n\t\t\t\t\t\treturn data.map((v) => {\n\t\t\t\t\t\t\tif (typeof v === \"string\") {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\treturn new IdClass(v);\n\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\treturn v;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn v;\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof data === \"string\") {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\treturn new IdClass(data);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\treturn data;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (\n\t\t\t\t\t\tfieldAttributes?.references?.field === \"id\" &&\n\t\t\t\t\t\t!fieldAttributes?.required &&\n\t\t\t\t\t\tdata === null\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tif (action === \"update\") {\n\t\t\t\t\t\treturn data;\n\t\t\t\t\t}\n\t\t\t\t\treturn new IdClass();\n\t\t\t\t}\n\t\t\t\treturn data;\n\t\t\t},\n\t\t\tcustomTransformOutput({ data, field, fieldAttributes }) {\n\t\t\t\tif (field === \"id\" || fieldAttributes.references?.field === \"id\") {\n\t\t\t\t\tif (data instanceof UUID) {\n\t\t\t\t\t\treturn data.toString();\n\t\t\t\t\t}\n\t\t\t\t\tif (data instanceof ObjectId) {\n\t\t\t\t\t\treturn data.toHexString();\n\t\t\t\t\t}\n\t\t\t\t\tif (Array.isArray(data)) {\n\t\t\t\t\t\treturn data.map((v) => {\n\t\t\t\t\t\t\tif (v instanceof UUID) {\n\t\t\t\t\t\t\t\treturn v.toString();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (v instanceof ObjectId) {\n\t\t\t\t\t\t\t\treturn v.toHexString();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn v;\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\t\t\t\treturn data;\n\t\t\t},\n\t\t\tcustomIdGenerator() {\n\t\t\t\treturn new ObjectId().toString();\n\t\t\t},\n\t\t},\n\t\tadapter: createCustomAdapter(db),\n\t};\n\tlazyAdapter = createAdapterFactory(adapterOptions);\n\n\treturn (options: BetterAuthOptions): DBAdapter<BetterAuthOptions> => {\n\t\tlazyOptions = options;\n\t\treturn lazyAdapter(options);\n\t};\n};\n\n/**\n * Safely escape user input for use in a MongoDB regex.\n * This ensures the resulting pattern is treated as literal text,\n * and not as a regex with special syntax.\n *\n * @param input - The input string to escape. Any type that isn't a string will be converted to an empty string.\n * @param maxLength - The maximum length of the input string to escape. Defaults to 256. This is to prevent DOS attacks.\n * @returns The escaped string.\n */\nfunction escapeForMongoRegex(input: string, maxLength = 256): string {\n\tif (typeof input !== \"string\") return \"\";\n\n\t// Escape all PCRE special characters\n\t// Source: PCRE docs — https://www.pcre.org/original/doc/html/pcrepattern.html\n\treturn input.slice(0, maxLength).replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@better-auth/mongo-adapter",
3
- "version": "1.5.5",
3
+ "version": "1.5.7-beta.1",
4
4
  "description": "Mongo adapter for Better Auth",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -36,14 +36,19 @@
36
36
  "peerDependencies": {
37
37
  "@better-auth/utils": "^0.3.0",
38
38
  "mongodb": "^6.0.0 || ^7.0.0",
39
- "@better-auth/core": "1.5.5"
39
+ "@better-auth/core": "1.5.7-beta.1"
40
+ },
41
+ "peerDependenciesMeta": {
42
+ "mongodb": {
43
+ "optional": true
44
+ }
40
45
  },
41
46
  "devDependencies": {
42
47
  "@better-auth/utils": "^0.3.1",
43
48
  "mongodb": "^7.1.0",
44
- "tsdown": "0.21.0-beta.2",
49
+ "tsdown": "0.21.1",
45
50
  "typescript": "^5.9.3",
46
- "@better-auth/core": "1.5.5"
51
+ "@better-auth/core": "1.5.7-beta.1"
47
52
  },
48
53
  "scripts": {
49
54
  "build": "tsdown",