@delmaredigital/payload-better-auth 0.1.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.
- package/LICENSE +21 -0
- package/README.md +734 -0
- package/dist/adapter/index.d.mts +70 -0
- package/dist/adapter/index.d.ts +70 -0
- package/dist/adapter/index.js +368 -0
- package/dist/adapter/index.js.map +1 -0
- package/dist/adapter/index.mjs +366 -0
- package/dist/adapter/index.mjs.map +1 -0
- package/dist/client.d.mts +1 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.js +12 -0
- package/dist/client.js.map +1 -0
- package/dist/client.mjs +3 -0
- package/dist/client.mjs.map +1 -0
- package/dist/index.d.mts +120 -0
- package/dist/index.d.ts +120 -0
- package/dist/index.js +611 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +603 -0
- package/dist/index.mjs.map +1 -0
- package/dist/plugin/index.d.mts +78 -0
- package/dist/plugin/index.d.ts +78 -0
- package/dist/plugin/index.js +86 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/index.mjs +82 -0
- package/dist/plugin/index.mjs.map +1 -0
- package/package.json +73 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,603 @@
|
|
|
1
|
+
import { getAuthTables } from 'better-auth/db';
|
|
2
|
+
|
|
3
|
+
// src/adapter/index.ts
|
|
4
|
+
var DEFAULT_COLLECTIONS = {
|
|
5
|
+
user: "users",
|
|
6
|
+
session: "sessions",
|
|
7
|
+
account: "accounts",
|
|
8
|
+
verification: "verifications"
|
|
9
|
+
};
|
|
10
|
+
function payloadAdapter({
|
|
11
|
+
payloadClient,
|
|
12
|
+
adapterConfig
|
|
13
|
+
}) {
|
|
14
|
+
const { collections = {}, enableDebugLogs = false, idType } = adapterConfig;
|
|
15
|
+
const finalCollections = { ...DEFAULT_COLLECTIONS, ...collections };
|
|
16
|
+
const log = (...args) => {
|
|
17
|
+
if (enableDebugLogs) console.log("[payload-adapter]", ...args);
|
|
18
|
+
};
|
|
19
|
+
async function resolvePayloadClient() {
|
|
20
|
+
return typeof payloadClient === "function" ? await payloadClient() : payloadClient;
|
|
21
|
+
}
|
|
22
|
+
function getCollection(model) {
|
|
23
|
+
return finalCollections[model] ?? model;
|
|
24
|
+
}
|
|
25
|
+
function transformFieldName(fieldName) {
|
|
26
|
+
if (fieldName.endsWith("Id") && fieldName !== "id" && fieldName !== "accountId" && fieldName !== "providerId") {
|
|
27
|
+
return fieldName.slice(0, -2);
|
|
28
|
+
}
|
|
29
|
+
return fieldName;
|
|
30
|
+
}
|
|
31
|
+
function convertWhere(where) {
|
|
32
|
+
if (!where || where.length === 0) return {};
|
|
33
|
+
if (where.length === 1) {
|
|
34
|
+
const w = where[0];
|
|
35
|
+
return {
|
|
36
|
+
[transformFieldName(w.field)]: convertOperator(w.operator, w.value)
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const andConditions = where.filter((w) => w.connector !== "OR");
|
|
40
|
+
const orConditions = where.filter((w) => w.connector === "OR");
|
|
41
|
+
const result = {};
|
|
42
|
+
if (andConditions.length > 0) {
|
|
43
|
+
result.and = andConditions.map((w) => ({
|
|
44
|
+
[transformFieldName(w.field)]: convertOperator(w.operator, w.value)
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
if (orConditions.length > 0) {
|
|
48
|
+
result.or = orConditions.map((w) => ({
|
|
49
|
+
[transformFieldName(w.field)]: convertOperator(w.operator, w.value)
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
function convertOperator(operator, value) {
|
|
55
|
+
switch (operator) {
|
|
56
|
+
case "eq":
|
|
57
|
+
return { equals: value };
|
|
58
|
+
case "ne":
|
|
59
|
+
return { not_equals: value };
|
|
60
|
+
case "gt":
|
|
61
|
+
return { greater_than: value };
|
|
62
|
+
case "gte":
|
|
63
|
+
return { greater_than_equal: value };
|
|
64
|
+
case "lt":
|
|
65
|
+
return { less_than: value };
|
|
66
|
+
case "lte":
|
|
67
|
+
return { less_than_equal: value };
|
|
68
|
+
case "in":
|
|
69
|
+
return { in: value };
|
|
70
|
+
case "contains":
|
|
71
|
+
return { contains: value };
|
|
72
|
+
case "starts_with":
|
|
73
|
+
return { like: `${value}%` };
|
|
74
|
+
case "ends_with":
|
|
75
|
+
return { like: `%${value}` };
|
|
76
|
+
default:
|
|
77
|
+
return { equals: value };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function extractSingleId(where) {
|
|
81
|
+
if ("and" in where || "or" in where) return null;
|
|
82
|
+
const idCondition = where.id;
|
|
83
|
+
if (idCondition && typeof idCondition === "object" && "equals" in idCondition) {
|
|
84
|
+
const value = idCondition.equals;
|
|
85
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
86
|
+
return value;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
function transformInput(data) {
|
|
92
|
+
const result = {};
|
|
93
|
+
for (const [key, value] of Object.entries(data)) {
|
|
94
|
+
if (key.endsWith("Id") && key !== "id" && key !== "accountId" && key !== "providerId") {
|
|
95
|
+
const fieldName = key.slice(0, -2);
|
|
96
|
+
if (idType === "number" && typeof value === "string") {
|
|
97
|
+
const num = parseInt(value, 10);
|
|
98
|
+
result[fieldName] = isNaN(num) ? value : num;
|
|
99
|
+
} else {
|
|
100
|
+
result[fieldName] = value;
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
result[key] = value;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
function transformOutput(doc) {
|
|
109
|
+
if (!doc || typeof doc !== "object") return doc;
|
|
110
|
+
const result = { ...doc };
|
|
111
|
+
if ("id" in result && result.id !== void 0) {
|
|
112
|
+
result.id = String(result.id);
|
|
113
|
+
}
|
|
114
|
+
for (const [key, value] of Object.entries(result)) {
|
|
115
|
+
if (value && typeof value === "object" && "id" in value) {
|
|
116
|
+
result[`${key}Id`] = String(value.id);
|
|
117
|
+
delete result[key];
|
|
118
|
+
} else if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(value)) {
|
|
119
|
+
result[key] = new Date(value);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
124
|
+
function convertId(id) {
|
|
125
|
+
if (idType === "number" && typeof id === "string") {
|
|
126
|
+
const num = parseInt(id, 10);
|
|
127
|
+
return isNaN(num) ? id : num;
|
|
128
|
+
}
|
|
129
|
+
if (idType === "text" && typeof id === "number") {
|
|
130
|
+
return String(id);
|
|
131
|
+
}
|
|
132
|
+
return id;
|
|
133
|
+
}
|
|
134
|
+
async function handleJoins(payload, doc, model, join) {
|
|
135
|
+
const result = { ...doc };
|
|
136
|
+
for (const [joinKey, joinConfig] of Object.entries(join)) {
|
|
137
|
+
if (!joinConfig) continue;
|
|
138
|
+
const limit = typeof joinConfig === "object" ? joinConfig.limit : void 0;
|
|
139
|
+
log("handleJoins", { model, joinKey, docId: doc.id });
|
|
140
|
+
if (model === "user" && joinKey === "account") {
|
|
141
|
+
const accounts = await payload.find({
|
|
142
|
+
collection: getCollection("account"),
|
|
143
|
+
where: { user: { equals: doc.id } },
|
|
144
|
+
limit: limit ?? 100,
|
|
145
|
+
depth: 0
|
|
146
|
+
});
|
|
147
|
+
result[joinKey] = accounts.docs.map((a) => transformOutput(a));
|
|
148
|
+
} else if (model === "session" && joinKey === "user") {
|
|
149
|
+
const userId = doc.userId;
|
|
150
|
+
if (userId) {
|
|
151
|
+
try {
|
|
152
|
+
const user = await payload.findByID({
|
|
153
|
+
collection: getCollection("user"),
|
|
154
|
+
id: userId,
|
|
155
|
+
depth: 0
|
|
156
|
+
});
|
|
157
|
+
result[joinKey] = transformOutput(user);
|
|
158
|
+
} catch {
|
|
159
|
+
result[joinKey] = null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
} else if (model === "account" && joinKey === "user") {
|
|
163
|
+
const userId = doc.userId;
|
|
164
|
+
if (userId) {
|
|
165
|
+
try {
|
|
166
|
+
const user = await payload.findByID({
|
|
167
|
+
collection: getCollection("user"),
|
|
168
|
+
id: userId,
|
|
169
|
+
depth: 0
|
|
170
|
+
});
|
|
171
|
+
result[joinKey] = transformOutput(user);
|
|
172
|
+
} catch {
|
|
173
|
+
result[joinKey] = null;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return result;
|
|
179
|
+
}
|
|
180
|
+
return (_options) => {
|
|
181
|
+
log("Adapter initialized", { collections: finalCollections });
|
|
182
|
+
return {
|
|
183
|
+
id: "payload-adapter",
|
|
184
|
+
async create({
|
|
185
|
+
model,
|
|
186
|
+
data
|
|
187
|
+
}) {
|
|
188
|
+
const payload = await resolvePayloadClient();
|
|
189
|
+
const collection = getCollection(model);
|
|
190
|
+
const transformedData = transformInput(data);
|
|
191
|
+
log("create", { collection, data: transformedData });
|
|
192
|
+
try {
|
|
193
|
+
const result = await payload.create({
|
|
194
|
+
collection,
|
|
195
|
+
data: transformedData,
|
|
196
|
+
depth: 0
|
|
197
|
+
});
|
|
198
|
+
return transformOutput(result);
|
|
199
|
+
} catch (error) {
|
|
200
|
+
console.error("[payload-adapter] create failed:", {
|
|
201
|
+
collection,
|
|
202
|
+
model,
|
|
203
|
+
error: error instanceof Error ? error.message : error
|
|
204
|
+
});
|
|
205
|
+
throw error;
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
async findOne({
|
|
209
|
+
model,
|
|
210
|
+
where,
|
|
211
|
+
select: _select,
|
|
212
|
+
join
|
|
213
|
+
}) {
|
|
214
|
+
try {
|
|
215
|
+
const payload = await resolvePayloadClient();
|
|
216
|
+
const collection = getCollection(model);
|
|
217
|
+
const payloadWhere = convertWhere(where);
|
|
218
|
+
const id = extractSingleId(payloadWhere);
|
|
219
|
+
if (id) {
|
|
220
|
+
try {
|
|
221
|
+
const result2 = await payload.findByID({
|
|
222
|
+
collection,
|
|
223
|
+
id: convertId(id),
|
|
224
|
+
depth: 1
|
|
225
|
+
});
|
|
226
|
+
let doc2 = transformOutput(result2);
|
|
227
|
+
if (join) {
|
|
228
|
+
doc2 = await handleJoins(payload, doc2, model, join);
|
|
229
|
+
}
|
|
230
|
+
return doc2;
|
|
231
|
+
} catch (error) {
|
|
232
|
+
if (error instanceof Error && "status" in error && error.status === 404) {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
const result = await payload.find({
|
|
239
|
+
collection,
|
|
240
|
+
where: payloadWhere,
|
|
241
|
+
limit: 1,
|
|
242
|
+
depth: 1
|
|
243
|
+
});
|
|
244
|
+
let doc = result.docs[0] ? transformOutput(result.docs[0]) : null;
|
|
245
|
+
if (doc && join) {
|
|
246
|
+
doc = await handleJoins(payload, doc, model, join);
|
|
247
|
+
}
|
|
248
|
+
return doc;
|
|
249
|
+
} catch (error) {
|
|
250
|
+
console.error("[payload-adapter] findOne FAILED", {
|
|
251
|
+
model,
|
|
252
|
+
where,
|
|
253
|
+
error
|
|
254
|
+
});
|
|
255
|
+
throw error;
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
async findMany({
|
|
259
|
+
model,
|
|
260
|
+
where,
|
|
261
|
+
limit,
|
|
262
|
+
offset,
|
|
263
|
+
sortBy
|
|
264
|
+
}) {
|
|
265
|
+
const payload = await resolvePayloadClient();
|
|
266
|
+
const collection = getCollection(model);
|
|
267
|
+
const payloadWhere = convertWhere(where);
|
|
268
|
+
const result = await payload.find({
|
|
269
|
+
collection,
|
|
270
|
+
where: payloadWhere,
|
|
271
|
+
limit: limit ?? 100,
|
|
272
|
+
page: offset ? Math.floor(offset / (limit ?? 100)) + 1 : 1,
|
|
273
|
+
sort: sortBy ? `${sortBy.direction === "desc" ? "-" : ""}${sortBy.field}` : void 0,
|
|
274
|
+
depth: 1
|
|
275
|
+
});
|
|
276
|
+
return result.docs.map((doc) => transformOutput(doc));
|
|
277
|
+
},
|
|
278
|
+
async update({
|
|
279
|
+
model,
|
|
280
|
+
where,
|
|
281
|
+
update: data
|
|
282
|
+
}) {
|
|
283
|
+
const payload = await resolvePayloadClient();
|
|
284
|
+
const collection = getCollection(model);
|
|
285
|
+
const payloadWhere = convertWhere(where);
|
|
286
|
+
const transformedData = transformInput(data);
|
|
287
|
+
const id = extractSingleId(payloadWhere);
|
|
288
|
+
if (id) {
|
|
289
|
+
const result2 = await payload.update({
|
|
290
|
+
collection,
|
|
291
|
+
id: convertId(id),
|
|
292
|
+
data: transformedData,
|
|
293
|
+
depth: 1
|
|
294
|
+
});
|
|
295
|
+
return transformOutput(result2);
|
|
296
|
+
}
|
|
297
|
+
const result = await payload.update({
|
|
298
|
+
collection,
|
|
299
|
+
where: payloadWhere,
|
|
300
|
+
data: transformedData,
|
|
301
|
+
depth: 1
|
|
302
|
+
});
|
|
303
|
+
return result.docs[0] ? transformOutput(result.docs[0]) : null;
|
|
304
|
+
},
|
|
305
|
+
async updateMany({
|
|
306
|
+
model,
|
|
307
|
+
where,
|
|
308
|
+
update: data
|
|
309
|
+
}) {
|
|
310
|
+
const payload = await resolvePayloadClient();
|
|
311
|
+
const collection = getCollection(model);
|
|
312
|
+
const payloadWhere = convertWhere(where);
|
|
313
|
+
const transformedData = transformInput(data);
|
|
314
|
+
const result = await payload.update({
|
|
315
|
+
collection,
|
|
316
|
+
where: payloadWhere,
|
|
317
|
+
data: transformedData,
|
|
318
|
+
depth: 0
|
|
319
|
+
});
|
|
320
|
+
return result.docs.length;
|
|
321
|
+
},
|
|
322
|
+
async delete({ model, where }) {
|
|
323
|
+
const payload = await resolvePayloadClient();
|
|
324
|
+
const collection = getCollection(model);
|
|
325
|
+
const payloadWhere = convertWhere(where);
|
|
326
|
+
const id = extractSingleId(payloadWhere);
|
|
327
|
+
if (id) {
|
|
328
|
+
await payload.delete({ collection, id: convertId(id) });
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
await payload.delete({ collection, where: payloadWhere });
|
|
332
|
+
},
|
|
333
|
+
async deleteMany({
|
|
334
|
+
model,
|
|
335
|
+
where
|
|
336
|
+
}) {
|
|
337
|
+
const payload = await resolvePayloadClient();
|
|
338
|
+
const collection = getCollection(model);
|
|
339
|
+
const payloadWhere = convertWhere(where);
|
|
340
|
+
const result = await payload.delete({
|
|
341
|
+
collection,
|
|
342
|
+
where: payloadWhere
|
|
343
|
+
});
|
|
344
|
+
return result.docs.length;
|
|
345
|
+
},
|
|
346
|
+
async count({
|
|
347
|
+
model,
|
|
348
|
+
where
|
|
349
|
+
}) {
|
|
350
|
+
const payload = await resolvePayloadClient();
|
|
351
|
+
const collection = getCollection(model);
|
|
352
|
+
const payloadWhere = convertWhere(where);
|
|
353
|
+
const result = await payload.count({
|
|
354
|
+
collection,
|
|
355
|
+
where: payloadWhere
|
|
356
|
+
});
|
|
357
|
+
return result.totalDocs;
|
|
358
|
+
},
|
|
359
|
+
async transaction(callback) {
|
|
360
|
+
return callback(this);
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
var DEFAULT_SLUG_OVERRIDES = {
|
|
366
|
+
user: "users",
|
|
367
|
+
session: "sessions",
|
|
368
|
+
account: "accounts",
|
|
369
|
+
verification: "verifications"
|
|
370
|
+
};
|
|
371
|
+
function mapFieldType(type, fieldName, hasReferences) {
|
|
372
|
+
if (hasReferences) {
|
|
373
|
+
return "relationship";
|
|
374
|
+
}
|
|
375
|
+
switch (type) {
|
|
376
|
+
case "boolean":
|
|
377
|
+
return "checkbox";
|
|
378
|
+
case "number":
|
|
379
|
+
return "number";
|
|
380
|
+
case "date":
|
|
381
|
+
return "date";
|
|
382
|
+
case "string":
|
|
383
|
+
if (fieldName === "email") return "email";
|
|
384
|
+
return "text";
|
|
385
|
+
default:
|
|
386
|
+
return "text";
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
function extractRelationTarget(fieldName, slugOverrides) {
|
|
390
|
+
const base = fieldName.replace(/(_id|Id)$/, "");
|
|
391
|
+
const pluralized = base.endsWith("s") ? base : `${base}s`;
|
|
392
|
+
return slugOverrides[base] ?? slugOverrides[pluralized] ?? pluralized;
|
|
393
|
+
}
|
|
394
|
+
function generateCollection(modelKey, table, slugOverrides, adminGroup, customAccess) {
|
|
395
|
+
const slug = slugOverrides[modelKey] ?? table.modelName ?? modelKey;
|
|
396
|
+
const fields = [];
|
|
397
|
+
for (const [fieldKey, fieldDef] of Object.entries(table.fields)) {
|
|
398
|
+
if (["id", "createdAt", "updatedAt"].includes(fieldKey)) {
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
const fieldName = fieldDef.fieldName ?? fieldKey;
|
|
402
|
+
const hasReferences = fieldDef.references !== void 0;
|
|
403
|
+
const fieldType = mapFieldType(fieldDef.type, fieldKey, hasReferences);
|
|
404
|
+
if (fieldType === "relationship") {
|
|
405
|
+
const relationTo = fieldDef.references?.model ? slugOverrides[fieldDef.references.model] ?? fieldDef.references.model : extractRelationTarget(fieldKey, slugOverrides);
|
|
406
|
+
fields.push({
|
|
407
|
+
name: fieldName.replace(/(_id|Id)$/, ""),
|
|
408
|
+
type: "relationship",
|
|
409
|
+
relationTo,
|
|
410
|
+
required: fieldDef.required ?? false,
|
|
411
|
+
index: true
|
|
412
|
+
});
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
const field = {
|
|
416
|
+
name: fieldName,
|
|
417
|
+
type: fieldType
|
|
418
|
+
};
|
|
419
|
+
if (fieldDef.required) field.required = true;
|
|
420
|
+
if (fieldDef.unique) {
|
|
421
|
+
field.unique = true;
|
|
422
|
+
field.index = true;
|
|
423
|
+
}
|
|
424
|
+
if (fieldDef.defaultValue !== void 0) {
|
|
425
|
+
let defaultValue = fieldDef.defaultValue;
|
|
426
|
+
if (typeof defaultValue === "function") {
|
|
427
|
+
try {
|
|
428
|
+
defaultValue = defaultValue();
|
|
429
|
+
} catch {
|
|
430
|
+
defaultValue = void 0;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
if (defaultValue !== void 0 && defaultValue !== null) {
|
|
434
|
+
field.defaultValue = defaultValue;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
fields.push(field);
|
|
438
|
+
}
|
|
439
|
+
const titleField = ["name", "email", "title", "identifier"].find(
|
|
440
|
+
(f) => fields.some((field) => "name" in field && field.name === f)
|
|
441
|
+
);
|
|
442
|
+
const defaultAccess = {
|
|
443
|
+
read: ({ req }) => req.user?.role === "admin",
|
|
444
|
+
create: () => false,
|
|
445
|
+
update: () => false,
|
|
446
|
+
delete: ({ req }) => req.user?.role === "admin"
|
|
447
|
+
};
|
|
448
|
+
return {
|
|
449
|
+
slug,
|
|
450
|
+
admin: {
|
|
451
|
+
useAsTitle: titleField ?? "id",
|
|
452
|
+
group: adminGroup,
|
|
453
|
+
description: `Auto-generated from Better Auth schema (${modelKey})`
|
|
454
|
+
},
|
|
455
|
+
access: customAccess ?? defaultAccess,
|
|
456
|
+
fields,
|
|
457
|
+
timestamps: true
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
function betterAuthCollections(options = {}) {
|
|
461
|
+
const {
|
|
462
|
+
betterAuthOptions = {},
|
|
463
|
+
slugOverrides = {},
|
|
464
|
+
skipCollections = ["user"],
|
|
465
|
+
adminGroup = "Auth",
|
|
466
|
+
access
|
|
467
|
+
} = options;
|
|
468
|
+
const finalSlugOverrides = { ...DEFAULT_SLUG_OVERRIDES, ...slugOverrides };
|
|
469
|
+
return (incomingConfig) => {
|
|
470
|
+
const existingCollectionSlugs = new Set(
|
|
471
|
+
(incomingConfig.collections ?? []).map((c) => c.slug)
|
|
472
|
+
);
|
|
473
|
+
const tables = getAuthTables(betterAuthOptions);
|
|
474
|
+
const generatedCollections = [];
|
|
475
|
+
for (const [modelKey, table] of Object.entries(tables)) {
|
|
476
|
+
if (skipCollections.includes(modelKey)) {
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
const slug = finalSlugOverrides[modelKey] ?? table.modelName ?? modelKey;
|
|
480
|
+
if (existingCollectionSlugs.has(slug)) {
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
483
|
+
const collection = generateCollection(
|
|
484
|
+
modelKey,
|
|
485
|
+
table,
|
|
486
|
+
finalSlugOverrides,
|
|
487
|
+
adminGroup,
|
|
488
|
+
access
|
|
489
|
+
);
|
|
490
|
+
generatedCollections.push(collection);
|
|
491
|
+
}
|
|
492
|
+
return {
|
|
493
|
+
...incomingConfig,
|
|
494
|
+
collections: [
|
|
495
|
+
...incomingConfig.collections ?? [],
|
|
496
|
+
...generatedCollections
|
|
497
|
+
]
|
|
498
|
+
};
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// src/plugin/index.ts
|
|
503
|
+
var authInstance = null;
|
|
504
|
+
function createBetterAuthPlugin(options) {
|
|
505
|
+
const { createAuth } = options;
|
|
506
|
+
return (incomingConfig) => {
|
|
507
|
+
const existingOnInit = incomingConfig.onInit;
|
|
508
|
+
return {
|
|
509
|
+
...incomingConfig,
|
|
510
|
+
onInit: async (payload) => {
|
|
511
|
+
if (existingOnInit) {
|
|
512
|
+
await existingOnInit(payload);
|
|
513
|
+
}
|
|
514
|
+
if ("betterAuth" in payload) {
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
if (!authInstance) {
|
|
518
|
+
try {
|
|
519
|
+
authInstance = createAuth(payload);
|
|
520
|
+
} catch (error) {
|
|
521
|
+
console.error("[better-auth] Failed to create auth:", error);
|
|
522
|
+
throw error;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
Object.defineProperty(payload, "betterAuth", {
|
|
526
|
+
value: authInstance,
|
|
527
|
+
writable: false,
|
|
528
|
+
enumerable: false,
|
|
529
|
+
configurable: false
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
function betterAuthStrategy(options = {}) {
|
|
536
|
+
const { usersCollection = "users" } = options;
|
|
537
|
+
return {
|
|
538
|
+
name: "better-auth",
|
|
539
|
+
authenticate: async ({
|
|
540
|
+
payload,
|
|
541
|
+
headers
|
|
542
|
+
}) => {
|
|
543
|
+
try {
|
|
544
|
+
const payloadWithAuth = payload;
|
|
545
|
+
const auth = payloadWithAuth.betterAuth;
|
|
546
|
+
if (!auth) {
|
|
547
|
+
console.error("Better Auth not initialized on payload instance");
|
|
548
|
+
return { user: null };
|
|
549
|
+
}
|
|
550
|
+
const session = await auth.api.getSession({ headers });
|
|
551
|
+
if (!session?.user?.id) {
|
|
552
|
+
return { user: null };
|
|
553
|
+
}
|
|
554
|
+
const users = await payload.find({
|
|
555
|
+
collection: usersCollection,
|
|
556
|
+
where: { id: { equals: session.user.id } },
|
|
557
|
+
limit: 1,
|
|
558
|
+
depth: 0
|
|
559
|
+
});
|
|
560
|
+
if (users.docs.length === 0) {
|
|
561
|
+
return { user: null };
|
|
562
|
+
}
|
|
563
|
+
return {
|
|
564
|
+
user: {
|
|
565
|
+
...users.docs[0],
|
|
566
|
+
collection: usersCollection,
|
|
567
|
+
_strategy: "better-auth"
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
} catch (error) {
|
|
571
|
+
console.error("Better Auth strategy error:", error);
|
|
572
|
+
return { user: null };
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
function resetAuthInstance() {
|
|
578
|
+
authInstance = null;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// src/utils/session.ts
|
|
582
|
+
async function getServerSession(payload, headers) {
|
|
583
|
+
try {
|
|
584
|
+
const payloadWithAuth = payload;
|
|
585
|
+
if (!payloadWithAuth.betterAuth) {
|
|
586
|
+
console.error("[session] Better Auth not initialized");
|
|
587
|
+
return null;
|
|
588
|
+
}
|
|
589
|
+
const session = await payloadWithAuth.betterAuth.api.getSession({ headers });
|
|
590
|
+
return session;
|
|
591
|
+
} catch (error) {
|
|
592
|
+
console.error("[session] Error getting session:", error);
|
|
593
|
+
return null;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
async function getServerUser(payload, headers) {
|
|
597
|
+
const session = await getServerSession(payload, headers);
|
|
598
|
+
return session?.user ?? null;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
export { betterAuthCollections, betterAuthStrategy, createBetterAuthPlugin, getServerSession, getServerUser, payloadAdapter, resetAuthInstance };
|
|
602
|
+
//# sourceMappingURL=index.mjs.map
|
|
603
|
+
//# sourceMappingURL=index.mjs.map
|