@geekmidas/testkit 0.0.16 → 0.0.17
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/{Factory-Cmr3s3-s.d.mts → Factory-CRquB4vz.d.mts} +2 -2
- package/dist/Factory.d.mts +2 -2
- package/dist/{KyselyFactory-Cx3sezwH.d.mts → KyselyFactory-BDS_QqRT.d.mts} +3 -3
- package/dist/KyselyFactory.d.mts +3 -3
- package/dist/{ObjectionFactory-C-59Hjwj.d.mts → ObjectionFactory-C3tHvX1d.d.mts} +3 -3
- package/dist/ObjectionFactory.d.mts +3 -3
- package/dist/better-auth.cjs +245 -0
- package/dist/better-auth.cjs.map +1 -0
- package/dist/better-auth.d.cts +17 -0
- package/dist/better-auth.d.mts +17 -0
- package/dist/better-auth.mjs +244 -0
- package/dist/better-auth.mjs.map +1 -0
- package/dist/{faker-DHh7xs4u.d.mts → faker-Br8MzXil.d.mts} +3 -3
- package/dist/faker.d.mts +1 -1
- package/dist/kysely.d.mts +3 -3
- package/dist/objection.d.mts +3 -3
- package/package.json +7 -1
- package/src/__tests__/better-auth.spec.ts +21 -0
- package/src/better-auth.ts +327 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FakerFactory } from "./faker-
|
|
1
|
+
import { FakerFactory } from "./faker-Br8MzXil.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/Factory.d.ts
|
|
4
4
|
|
|
@@ -129,4 +129,4 @@ type MixedFactoryBuilder<Attrs = any, Factory = any, Result = any, DB = any> = (
|
|
|
129
129
|
type FactorySeed<Attrs = any, Factory = any, Result = any, DB = any> = (attrs: Attrs, factory: Factory, db: DB) => Promise<Result>;
|
|
130
130
|
//#endregion
|
|
131
131
|
export { Factory, FactorySeed, MixedFactoryBuilder };
|
|
132
|
-
//# sourceMappingURL=Factory-
|
|
132
|
+
//# sourceMappingURL=Factory-CRquB4vz.d.mts.map
|
package/dist/Factory.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import "./faker-
|
|
2
|
-
import { Factory, FactorySeed, MixedFactoryBuilder } from "./Factory-
|
|
1
|
+
import "./faker-Br8MzXil.mjs";
|
|
2
|
+
import { Factory, FactorySeed, MixedFactoryBuilder } from "./Factory-CRquB4vz.mjs";
|
|
3
3
|
export { Factory, FactorySeed, MixedFactoryBuilder };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { FakerFactory } from "./faker-
|
|
2
|
-
import { Factory, FactorySeed } from "./Factory-
|
|
1
|
+
import { FakerFactory } from "./faker-Br8MzXil.mjs";
|
|
2
|
+
import { Factory, FactorySeed } from "./Factory-CRquB4vz.mjs";
|
|
3
3
|
import { ControlledTransaction, Insertable, Kysely, Selectable } from "kysely";
|
|
4
4
|
|
|
5
5
|
//#region src/KyselyFactory.d.ts
|
|
@@ -198,4 +198,4 @@ declare class KyselyFactory<DB, Builders extends Record<string, any>, Seeds exte
|
|
|
198
198
|
}
|
|
199
199
|
//#endregion
|
|
200
200
|
export { KyselyFactory };
|
|
201
|
-
//# sourceMappingURL=KyselyFactory-
|
|
201
|
+
//# sourceMappingURL=KyselyFactory-BDS_QqRT.d.mts.map
|
package/dist/KyselyFactory.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./faker-
|
|
2
|
-
import "./Factory-
|
|
3
|
-
import { KyselyFactory } from "./KyselyFactory-
|
|
1
|
+
import "./faker-Br8MzXil.mjs";
|
|
2
|
+
import "./Factory-CRquB4vz.mjs";
|
|
3
|
+
import { KyselyFactory } from "./KyselyFactory-BDS_QqRT.mjs";
|
|
4
4
|
export { KyselyFactory };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { FakerFactory } from "./faker-
|
|
2
|
-
import { Factory, FactorySeed } from "./Factory-
|
|
1
|
+
import { FakerFactory } from "./faker-Br8MzXil.mjs";
|
|
2
|
+
import { Factory, FactorySeed } from "./Factory-CRquB4vz.mjs";
|
|
3
3
|
import { Knex } from "knex";
|
|
4
4
|
import { Model } from "objection";
|
|
5
5
|
|
|
@@ -211,4 +211,4 @@ declare class ObjectionFactory<Builders extends Record<string, any>, Seeds exten
|
|
|
211
211
|
}
|
|
212
212
|
//#endregion
|
|
213
213
|
export { ObjectionFactory };
|
|
214
|
-
//# sourceMappingURL=ObjectionFactory-
|
|
214
|
+
//# sourceMappingURL=ObjectionFactory-C3tHvX1d.d.mts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./faker-
|
|
2
|
-
import "./Factory-
|
|
3
|
-
import { ObjectionFactory } from "./ObjectionFactory-
|
|
1
|
+
import "./faker-Br8MzXil.mjs";
|
|
2
|
+
import "./Factory-CRquB4vz.mjs";
|
|
3
|
+
import { ObjectionFactory } from "./ObjectionFactory-C3tHvX1d.mjs";
|
|
4
4
|
export { ObjectionFactory };
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
2
|
+
const better_auth_adapters = require_chunk.__toESM(require("better-auth/adapters"));
|
|
3
|
+
|
|
4
|
+
//#region src/better-auth.ts
|
|
5
|
+
var MemoryStore = class {
|
|
6
|
+
constructor(initialData, data = /* @__PURE__ */ new Map()) {
|
|
7
|
+
this.data = data;
|
|
8
|
+
if (initialData) for (const [model, records] of Object.entries(initialData)) {
|
|
9
|
+
const modelData = /* @__PURE__ */ new Map();
|
|
10
|
+
for (const record of records) modelData.set(record.id, { ...record });
|
|
11
|
+
this.data.set(model, modelData);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
getModel(modelName) {
|
|
15
|
+
if (!this.data.has(modelName)) this.data.set(modelName, /* @__PURE__ */ new Map());
|
|
16
|
+
return this.data.get(modelName);
|
|
17
|
+
}
|
|
18
|
+
clear() {
|
|
19
|
+
this.data.clear();
|
|
20
|
+
}
|
|
21
|
+
getAllData() {
|
|
22
|
+
const result = {};
|
|
23
|
+
for (const [model, records] of this.data.entries()) result[model] = Array.from(records.values());
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
function matchesWhere(record, where) {
|
|
28
|
+
if (!where || where.length === 0) return true;
|
|
29
|
+
let result = null;
|
|
30
|
+
for (const condition of where) {
|
|
31
|
+
const { field, value, operator = "eq", connector = "AND" } = condition;
|
|
32
|
+
const recordValue = record[field];
|
|
33
|
+
let matches = false;
|
|
34
|
+
switch (operator) {
|
|
35
|
+
case "eq":
|
|
36
|
+
matches = recordValue === value;
|
|
37
|
+
break;
|
|
38
|
+
case "ne":
|
|
39
|
+
matches = recordValue !== value;
|
|
40
|
+
break;
|
|
41
|
+
case "lt":
|
|
42
|
+
matches = recordValue < value;
|
|
43
|
+
break;
|
|
44
|
+
case "lte":
|
|
45
|
+
matches = recordValue <= value;
|
|
46
|
+
break;
|
|
47
|
+
case "gt":
|
|
48
|
+
matches = recordValue > value;
|
|
49
|
+
break;
|
|
50
|
+
case "gte":
|
|
51
|
+
matches = recordValue >= value;
|
|
52
|
+
break;
|
|
53
|
+
case "in":
|
|
54
|
+
matches = Array.isArray(value) && value.includes(recordValue);
|
|
55
|
+
break;
|
|
56
|
+
case "not_in":
|
|
57
|
+
matches = Array.isArray(value) && !value.includes(recordValue);
|
|
58
|
+
break;
|
|
59
|
+
case "contains":
|
|
60
|
+
matches = typeof recordValue === "string" && typeof value === "string" && recordValue.includes(value);
|
|
61
|
+
break;
|
|
62
|
+
case "starts_with":
|
|
63
|
+
matches = typeof recordValue === "string" && typeof value === "string" && recordValue.startsWith(value);
|
|
64
|
+
break;
|
|
65
|
+
case "ends_with":
|
|
66
|
+
matches = typeof recordValue === "string" && typeof value === "string" && recordValue.endsWith(value);
|
|
67
|
+
break;
|
|
68
|
+
default: matches = recordValue === value;
|
|
69
|
+
}
|
|
70
|
+
if (result === null) result = matches;
|
|
71
|
+
else if (connector === "OR") result = result || matches;
|
|
72
|
+
else result = result && matches;
|
|
73
|
+
}
|
|
74
|
+
return result ?? true;
|
|
75
|
+
}
|
|
76
|
+
function applySorting(records, sortBy) {
|
|
77
|
+
if (!sortBy) return records;
|
|
78
|
+
const { field, direction } = sortBy;
|
|
79
|
+
return records.sort((a, b) => {
|
|
80
|
+
const aVal = a[field];
|
|
81
|
+
const bVal = b[field];
|
|
82
|
+
if (aVal === bVal) return 0;
|
|
83
|
+
if (aVal == null) return direction === "asc" ? -1 : 1;
|
|
84
|
+
if (bVal == null) return direction === "asc" ? 1 : -1;
|
|
85
|
+
const comparison = aVal < bVal ? -1 : 1;
|
|
86
|
+
return direction === "asc" ? comparison : -comparison;
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
const memoryAdapter = (config = {}, store = /* @__PURE__ */ new Map()) => {
|
|
90
|
+
const storeInstance = new MemoryStore(config.initialData, store);
|
|
91
|
+
const adapterInstance = (0, better_auth_adapters.createAdapterFactory)({
|
|
92
|
+
config: {
|
|
93
|
+
adapterId: "memory-adapter",
|
|
94
|
+
adapterName: "Memory Adapter",
|
|
95
|
+
usePlural: config.usePlural ?? false,
|
|
96
|
+
debugLogs: config.debugLogs ?? false,
|
|
97
|
+
supportsJSON: true,
|
|
98
|
+
supportsDates: true,
|
|
99
|
+
supportsBooleans: true,
|
|
100
|
+
supportsNumericIds: false
|
|
101
|
+
},
|
|
102
|
+
adapter: ({ debugLog, transformInput, transformOutput, getModelName, transformWhereClause }) => ({
|
|
103
|
+
create: async ({ data, model, select }) => {
|
|
104
|
+
debugLog("CREATE", {
|
|
105
|
+
model,
|
|
106
|
+
data
|
|
107
|
+
});
|
|
108
|
+
const modelName = getModelName(model);
|
|
109
|
+
const modelData = storeInstance.getModel(modelName);
|
|
110
|
+
const transformedData = await transformInput(data, model, "create");
|
|
111
|
+
if (!transformedData.id) transformedData.id = crypto.randomUUID();
|
|
112
|
+
modelData.set(transformedData.id, {
|
|
113
|
+
...transformedData,
|
|
114
|
+
...data
|
|
115
|
+
});
|
|
116
|
+
if (data.email_address) modelData.set(transformedData.id, {
|
|
117
|
+
...transformedData,
|
|
118
|
+
email: data.email_address
|
|
119
|
+
});
|
|
120
|
+
const created = modelData.get(transformedData.id);
|
|
121
|
+
const out = await transformOutput(created, model, select);
|
|
122
|
+
return out;
|
|
123
|
+
},
|
|
124
|
+
findOne: async ({ where, model, select }) => {
|
|
125
|
+
debugLog("FIND_ONE", {
|
|
126
|
+
model,
|
|
127
|
+
where
|
|
128
|
+
});
|
|
129
|
+
const modelName = getModelName(model);
|
|
130
|
+
const modelData = storeInstance.getModel(modelName);
|
|
131
|
+
const transformedWhere = transformWhereClause({
|
|
132
|
+
model,
|
|
133
|
+
where
|
|
134
|
+
});
|
|
135
|
+
for (const record of modelData.values()) if (matchesWhere(record, transformedWhere)) {
|
|
136
|
+
const t = await transformOutput(record, model, select);
|
|
137
|
+
return t;
|
|
138
|
+
}
|
|
139
|
+
return null;
|
|
140
|
+
},
|
|
141
|
+
findMany: async ({ where, model, limit, offset, sortBy, select }) => {
|
|
142
|
+
debugLog("FIND_MANY", {
|
|
143
|
+
model,
|
|
144
|
+
where
|
|
145
|
+
});
|
|
146
|
+
const modelName = getModelName(model);
|
|
147
|
+
const modelData = storeInstance.getModel(modelName);
|
|
148
|
+
const transformedWhere = transformWhereClause({
|
|
149
|
+
model,
|
|
150
|
+
where
|
|
151
|
+
});
|
|
152
|
+
let results = Array.from(modelData.values()).filter((record) => matchesWhere(record, transformedWhere));
|
|
153
|
+
if (sortBy) results = applySorting(results, sortBy);
|
|
154
|
+
if (offset) results = results.slice(offset);
|
|
155
|
+
if (limit) results = results.slice(0, limit);
|
|
156
|
+
return Promise.all(results.map(async (record) => {
|
|
157
|
+
const transformed = await transformOutput(record, model, select);
|
|
158
|
+
return transformed;
|
|
159
|
+
}));
|
|
160
|
+
},
|
|
161
|
+
update: async ({ where, update, model, select }) => {
|
|
162
|
+
debugLog("UPDATE", {
|
|
163
|
+
model,
|
|
164
|
+
where
|
|
165
|
+
});
|
|
166
|
+
const modelName = getModelName(model);
|
|
167
|
+
const modelData = storeInstance.getModel(modelName);
|
|
168
|
+
const transformedWhere = transformWhereClause({
|
|
169
|
+
model,
|
|
170
|
+
where
|
|
171
|
+
});
|
|
172
|
+
for (const [id, record] of modelData.entries()) if (matchesWhere(record, transformedWhere)) {
|
|
173
|
+
const transformedData = await transformInput(update, model, "update");
|
|
174
|
+
const updated = {
|
|
175
|
+
...record,
|
|
176
|
+
...transformedData
|
|
177
|
+
};
|
|
178
|
+
modelData.set(id, updated);
|
|
179
|
+
return transformOutput(updated, model, select);
|
|
180
|
+
}
|
|
181
|
+
return null;
|
|
182
|
+
},
|
|
183
|
+
updateMany: async ({ where, update, model }) => {
|
|
184
|
+
debugLog("UPDATE_MANY", {
|
|
185
|
+
model,
|
|
186
|
+
where
|
|
187
|
+
});
|
|
188
|
+
const modelName = getModelName(model);
|
|
189
|
+
const modelData = storeInstance.getModel(modelName);
|
|
190
|
+
const transformedWhere = transformWhereClause({
|
|
191
|
+
model,
|
|
192
|
+
where
|
|
193
|
+
});
|
|
194
|
+
let count = 0;
|
|
195
|
+
const transformedData = await transformInput(update, model, "update");
|
|
196
|
+
for (const [id, record] of modelData.entries()) if (matchesWhere(record, transformedWhere)) {
|
|
197
|
+
modelData.set(id, {
|
|
198
|
+
...record,
|
|
199
|
+
...transformedData
|
|
200
|
+
});
|
|
201
|
+
count++;
|
|
202
|
+
}
|
|
203
|
+
return count;
|
|
204
|
+
},
|
|
205
|
+
delete: async ({ where, model }) => {
|
|
206
|
+
debugLog("DELETE", {
|
|
207
|
+
model,
|
|
208
|
+
where
|
|
209
|
+
});
|
|
210
|
+
const modelName = getModelName(model);
|
|
211
|
+
const modelData = storeInstance.getModel(modelName);
|
|
212
|
+
for (const [id, record] of modelData.entries()) if (matchesWhere(record, where)) {
|
|
213
|
+
modelData.delete(id);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
deleteMany: async ({ where, model }) => {
|
|
218
|
+
debugLog("DELETE_MANY", {
|
|
219
|
+
model,
|
|
220
|
+
where
|
|
221
|
+
});
|
|
222
|
+
const modelName = getModelName(model);
|
|
223
|
+
const modelData = storeInstance.getModel(modelName);
|
|
224
|
+
const toDelete = [];
|
|
225
|
+
for (const [id, record] of modelData.entries()) if (matchesWhere(record, where)) toDelete.push(id);
|
|
226
|
+
toDelete.forEach((id) => modelData.delete(id));
|
|
227
|
+
return toDelete.length;
|
|
228
|
+
},
|
|
229
|
+
count: async ({ where, model }) => {
|
|
230
|
+
const modelName = getModelName(model);
|
|
231
|
+
const modelData = storeInstance.getModel(modelName);
|
|
232
|
+
return Array.from(modelData.values()).filter((record) => matchesWhere(record, where)).length;
|
|
233
|
+
}
|
|
234
|
+
})
|
|
235
|
+
});
|
|
236
|
+
return Object.assign(adapterInstance, {
|
|
237
|
+
clear: () => store.clear(),
|
|
238
|
+
getAllData: () => storeInstance.getAllData(),
|
|
239
|
+
getStore: () => store
|
|
240
|
+
});
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
//#endregion
|
|
244
|
+
exports.memoryAdapter = memoryAdapter;
|
|
245
|
+
//# sourceMappingURL=better-auth.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"better-auth.cjs","names":["initialData?: Record<string, any[]>","data: Map<string, any>","modelName: string","result: Record<string, any[]>","record: any","where?: Where[]","result: boolean | null","records: any[]","sortBy?: SortBy","config: MemoryAdapterConfig","toDelete: string[]"],"sources":["../src/better-auth.ts"],"sourcesContent":["import {\n type DBAdapterDebugLogOption,\n type Where,\n createAdapterFactory,\n} from 'better-auth/adapters';\n\ninterface MemoryAdapterConfig {\n debugLogs?: DBAdapterDebugLogOption;\n usePlural?: boolean;\n initialData?: Record<string, any[]>;\n}\n\nclass MemoryStore {\n constructor(\n initialData?: Record<string, any[]>,\n private readonly data: Map<string, any> = new Map(),\n ) {\n if (initialData) {\n for (const [model, records] of Object.entries(initialData)) {\n const modelData = new Map();\n for (const record of records) {\n modelData.set(record.id, { ...record });\n }\n this.data.set(model, modelData);\n }\n }\n }\n\n getModel(modelName: string): Map<string, any> {\n if (!this.data.has(modelName)) {\n this.data.set(modelName, new Map());\n }\n return this.data.get(modelName)!;\n }\n\n clear() {\n this.data.clear();\n }\n\n getAllData() {\n const result: Record<string, any[]> = {};\n for (const [model, records] of this.data.entries()) {\n result[model] = Array.from(records.values());\n }\n return result;\n }\n}\n\nfunction matchesWhere(record: any, where?: Where[]): boolean {\n if (!where || where.length === 0) return true;\n\n let result: boolean | null = null;\n\n for (const condition of where) {\n const { field, value, operator = 'eq', connector = 'AND' } = condition;\n const recordValue = record[field];\n\n let matches = false;\n\n switch (operator) {\n case 'eq':\n matches = recordValue === value;\n break;\n case 'ne':\n matches = recordValue !== value;\n break;\n case 'lt':\n matches = recordValue < value;\n break;\n case 'lte':\n matches = recordValue <= value;\n break;\n case 'gt':\n matches = recordValue > value;\n break;\n case 'gte':\n matches = recordValue >= value;\n break;\n case 'in':\n matches = Array.isArray(value) && value.includes(recordValue);\n break;\n case 'not_in':\n matches = Array.isArray(value) && !value.includes(recordValue);\n break;\n case 'contains':\n matches =\n typeof recordValue === 'string' &&\n typeof value === 'string' &&\n recordValue.includes(value);\n break;\n case 'starts_with':\n matches =\n typeof recordValue === 'string' &&\n typeof value === 'string' &&\n recordValue.startsWith(value);\n break;\n case 'ends_with':\n matches =\n typeof recordValue === 'string' &&\n typeof value === 'string' &&\n recordValue.endsWith(value);\n break;\n default:\n matches = recordValue === value;\n }\n\n // Apply connector logic\n if (result === null) {\n result = matches;\n } else if (connector === 'OR') {\n result = result || matches;\n } else {\n // Default: AND\n result = result && matches;\n }\n }\n\n return result ?? true;\n}\ntype SortBy = {\n field: string;\n direction: 'asc' | 'desc';\n};\n\nfunction applySorting(records: any[], sortBy?: SortBy): any[] {\n if (!sortBy) return records;\n\n const { field, direction } = sortBy;\n\n return records.sort((a, b) => {\n const aVal = a[field];\n const bVal = b[field];\n\n if (aVal === bVal) return 0;\n if (aVal == null) return direction === 'asc' ? -1 : 1;\n if (bVal == null) return direction === 'asc' ? 1 : -1;\n\n const comparison = aVal < bVal ? -1 : 1;\n return direction === 'asc' ? comparison : -comparison;\n });\n}\n\nexport const memoryAdapter = (\n config: MemoryAdapterConfig = {},\n store = new Map(),\n) => {\n const storeInstance = new MemoryStore(config.initialData, store);\n\n const adapterInstance = createAdapterFactory({\n config: {\n adapterId: 'memory-adapter',\n adapterName: 'Memory Adapter',\n usePlural: config.usePlural ?? false,\n debugLogs: config.debugLogs ?? false,\n supportsJSON: true,\n supportsDates: true,\n supportsBooleans: true,\n supportsNumericIds: false,\n },\n\n adapter: ({\n debugLog,\n transformInput,\n transformOutput,\n getModelName,\n transformWhereClause,\n }) => ({\n create: async ({ data, model, select }) => {\n debugLog('CREATE', { model, data });\n const modelName = getModelName(model);\n const modelData = storeInstance.getModel(modelName);\n\n const transformedData = await transformInput(data, model, 'create');\n\n if (!transformedData.id) {\n transformedData.id = crypto.randomUUID();\n }\n\n modelData.set(transformedData.id, { ...transformedData, ...data });\n\n if (data.email_address) {\n modelData.set(transformedData.id, {\n ...transformedData,\n email: data.email_address,\n });\n }\n const created = modelData.get(transformedData.id);\n\n const out = (await transformOutput(created, model, select)) as any;\n\n return out;\n },\n\n findOne: async ({ where, model, select }) => {\n debugLog('FIND_ONE', { model, where });\n const modelName = getModelName(model);\n const modelData = storeInstance.getModel(modelName);\n const transformedWhere = transformWhereClause({ model, where });\n\n for (const record of modelData.values()) {\n if (matchesWhere(record, transformedWhere)) {\n const t = (await transformOutput(record, model, select)) as any;\n\n return t;\n }\n }\n return null;\n },\n\n findMany: async ({ where, model, limit, offset, sortBy, select }) => {\n debugLog('FIND_MANY', { model, where });\n\n const modelName = getModelName(model);\n const modelData = storeInstance.getModel(modelName);\n const transformedWhere = transformWhereClause({ model, where });\n\n let results = Array.from(modelData.values()).filter((record) =>\n matchesWhere(record, transformedWhere),\n );\n\n if (sortBy) {\n results = applySorting(results, sortBy);\n }\n\n if (offset) {\n results = results.slice(offset);\n }\n if (limit) {\n results = results.slice(0, limit);\n }\n\n return Promise.all(\n results.map(async (record) => {\n const transformed = await transformOutput(record, model, select);\n\n return transformed;\n }),\n );\n },\n\n update: async ({ where, update, model, select }) => {\n debugLog('UPDATE', { model, where });\n\n const modelName = getModelName(model);\n const modelData = storeInstance.getModel(modelName);\n const transformedWhere = transformWhereClause({ model, where });\n\n for (const [id, record] of modelData.entries()) {\n if (matchesWhere(record, transformedWhere)) {\n const transformedData = await transformInput(\n update as any,\n model,\n 'update',\n );\n const updated = { ...record, ...transformedData };\n modelData.set(id, updated);\n return transformOutput(updated, model, select) as any;\n }\n }\n return null;\n },\n\n updateMany: async ({ where, update, model }) => {\n debugLog('UPDATE_MANY', { model, where });\n const modelName = getModelName(model);\n const modelData = storeInstance.getModel(modelName);\n const transformedWhere = transformWhereClause({ model, where });\n\n let count = 0;\n const transformedData = await transformInput(update, model, 'update');\n\n for (const [id, record] of modelData.entries()) {\n if (matchesWhere(record, transformedWhere)) {\n modelData.set(id, { ...record, ...transformedData });\n count++;\n }\n }\n return count;\n },\n\n delete: async ({ where, model }) => {\n debugLog('DELETE', { model, where });\n const modelName = getModelName(model);\n const modelData = storeInstance.getModel(modelName);\n\n for (const [id, record] of modelData.entries()) {\n if (matchesWhere(record, where)) {\n modelData.delete(id);\n return;\n }\n }\n },\n\n deleteMany: async ({ where, model }) => {\n debugLog('DELETE_MANY', { model, where });\n const modelName = getModelName(model);\n const modelData = storeInstance.getModel(modelName);\n\n const toDelete: string[] = [];\n for (const [id, record] of modelData.entries()) {\n if (matchesWhere(record, where)) {\n toDelete.push(id);\n }\n }\n\n toDelete.forEach((id) => modelData.delete(id));\n return toDelete.length;\n },\n\n count: async ({ where, model }) => {\n const modelName = getModelName(model);\n const modelData = storeInstance.getModel(modelName);\n\n return Array.from(modelData.values()).filter((record) =>\n matchesWhere(record, where),\n ).length;\n },\n }),\n });\n\n // Add utility methods to the adapter\n return Object.assign(adapterInstance, {\n clear: () => store.clear(),\n getAllData: () => storeInstance.getAllData(),\n getStore: () => store,\n });\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as better_auth_adapters2 from "better-auth/adapters";
|
|
2
|
+
import { DBAdapterDebugLogOption } from "better-auth/adapters";
|
|
3
|
+
|
|
4
|
+
//#region src/better-auth.d.ts
|
|
5
|
+
interface MemoryAdapterConfig {
|
|
6
|
+
debugLogs?: DBAdapterDebugLogOption;
|
|
7
|
+
usePlural?: boolean;
|
|
8
|
+
initialData?: Record<string, any[]>;
|
|
9
|
+
}
|
|
10
|
+
declare const memoryAdapter: (config?: MemoryAdapterConfig, store?: Map<any, any>) => better_auth_adapters2.AdapterFactory & {
|
|
11
|
+
clear: () => void;
|
|
12
|
+
getAllData: () => Record<string, any[]>;
|
|
13
|
+
getStore: () => Map<any, any>;
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
export { memoryAdapter };
|
|
17
|
+
//# sourceMappingURL=better-auth.d.cts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as better_auth_adapters1 from "better-auth/adapters";
|
|
2
|
+
import { DBAdapterDebugLogOption } from "better-auth/adapters";
|
|
3
|
+
|
|
4
|
+
//#region src/better-auth.d.ts
|
|
5
|
+
interface MemoryAdapterConfig {
|
|
6
|
+
debugLogs?: DBAdapterDebugLogOption;
|
|
7
|
+
usePlural?: boolean;
|
|
8
|
+
initialData?: Record<string, any[]>;
|
|
9
|
+
}
|
|
10
|
+
declare const memoryAdapter: (config?: MemoryAdapterConfig, store?: Map<any, any>) => better_auth_adapters1.AdapterFactory & {
|
|
11
|
+
clear: () => void;
|
|
12
|
+
getAllData: () => Record<string, any[]>;
|
|
13
|
+
getStore: () => Map<any, any>;
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
export { memoryAdapter };
|
|
17
|
+
//# sourceMappingURL=better-auth.d.mts.map
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { createAdapterFactory } from "better-auth/adapters";
|
|
2
|
+
|
|
3
|
+
//#region src/better-auth.ts
|
|
4
|
+
var MemoryStore = class {
|
|
5
|
+
constructor(initialData, data = /* @__PURE__ */ new Map()) {
|
|
6
|
+
this.data = data;
|
|
7
|
+
if (initialData) for (const [model, records] of Object.entries(initialData)) {
|
|
8
|
+
const modelData = /* @__PURE__ */ new Map();
|
|
9
|
+
for (const record of records) modelData.set(record.id, { ...record });
|
|
10
|
+
this.data.set(model, modelData);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
getModel(modelName) {
|
|
14
|
+
if (!this.data.has(modelName)) this.data.set(modelName, /* @__PURE__ */ new Map());
|
|
15
|
+
return this.data.get(modelName);
|
|
16
|
+
}
|
|
17
|
+
clear() {
|
|
18
|
+
this.data.clear();
|
|
19
|
+
}
|
|
20
|
+
getAllData() {
|
|
21
|
+
const result = {};
|
|
22
|
+
for (const [model, records] of this.data.entries()) result[model] = Array.from(records.values());
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
function matchesWhere(record, where) {
|
|
27
|
+
if (!where || where.length === 0) return true;
|
|
28
|
+
let result = null;
|
|
29
|
+
for (const condition of where) {
|
|
30
|
+
const { field, value, operator = "eq", connector = "AND" } = condition;
|
|
31
|
+
const recordValue = record[field];
|
|
32
|
+
let matches = false;
|
|
33
|
+
switch (operator) {
|
|
34
|
+
case "eq":
|
|
35
|
+
matches = recordValue === value;
|
|
36
|
+
break;
|
|
37
|
+
case "ne":
|
|
38
|
+
matches = recordValue !== value;
|
|
39
|
+
break;
|
|
40
|
+
case "lt":
|
|
41
|
+
matches = recordValue < value;
|
|
42
|
+
break;
|
|
43
|
+
case "lte":
|
|
44
|
+
matches = recordValue <= value;
|
|
45
|
+
break;
|
|
46
|
+
case "gt":
|
|
47
|
+
matches = recordValue > value;
|
|
48
|
+
break;
|
|
49
|
+
case "gte":
|
|
50
|
+
matches = recordValue >= value;
|
|
51
|
+
break;
|
|
52
|
+
case "in":
|
|
53
|
+
matches = Array.isArray(value) && value.includes(recordValue);
|
|
54
|
+
break;
|
|
55
|
+
case "not_in":
|
|
56
|
+
matches = Array.isArray(value) && !value.includes(recordValue);
|
|
57
|
+
break;
|
|
58
|
+
case "contains":
|
|
59
|
+
matches = typeof recordValue === "string" && typeof value === "string" && recordValue.includes(value);
|
|
60
|
+
break;
|
|
61
|
+
case "starts_with":
|
|
62
|
+
matches = typeof recordValue === "string" && typeof value === "string" && recordValue.startsWith(value);
|
|
63
|
+
break;
|
|
64
|
+
case "ends_with":
|
|
65
|
+
matches = typeof recordValue === "string" && typeof value === "string" && recordValue.endsWith(value);
|
|
66
|
+
break;
|
|
67
|
+
default: matches = recordValue === value;
|
|
68
|
+
}
|
|
69
|
+
if (result === null) result = matches;
|
|
70
|
+
else if (connector === "OR") result = result || matches;
|
|
71
|
+
else result = result && matches;
|
|
72
|
+
}
|
|
73
|
+
return result ?? true;
|
|
74
|
+
}
|
|
75
|
+
function applySorting(records, sortBy) {
|
|
76
|
+
if (!sortBy) return records;
|
|
77
|
+
const { field, direction } = sortBy;
|
|
78
|
+
return records.sort((a, b) => {
|
|
79
|
+
const aVal = a[field];
|
|
80
|
+
const bVal = b[field];
|
|
81
|
+
if (aVal === bVal) return 0;
|
|
82
|
+
if (aVal == null) return direction === "asc" ? -1 : 1;
|
|
83
|
+
if (bVal == null) return direction === "asc" ? 1 : -1;
|
|
84
|
+
const comparison = aVal < bVal ? -1 : 1;
|
|
85
|
+
return direction === "asc" ? comparison : -comparison;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const memoryAdapter = (config = {}, store = /* @__PURE__ */ new Map()) => {
|
|
89
|
+
const storeInstance = new MemoryStore(config.initialData, store);
|
|
90
|
+
const adapterInstance = createAdapterFactory({
|
|
91
|
+
config: {
|
|
92
|
+
adapterId: "memory-adapter",
|
|
93
|
+
adapterName: "Memory Adapter",
|
|
94
|
+
usePlural: config.usePlural ?? false,
|
|
95
|
+
debugLogs: config.debugLogs ?? false,
|
|
96
|
+
supportsJSON: true,
|
|
97
|
+
supportsDates: true,
|
|
98
|
+
supportsBooleans: true,
|
|
99
|
+
supportsNumericIds: false
|
|
100
|
+
},
|
|
101
|
+
adapter: ({ debugLog, transformInput, transformOutput, getModelName, transformWhereClause }) => ({
|
|
102
|
+
create: async ({ data, model, select }) => {
|
|
103
|
+
debugLog("CREATE", {
|
|
104
|
+
model,
|
|
105
|
+
data
|
|
106
|
+
});
|
|
107
|
+
const modelName = getModelName(model);
|
|
108
|
+
const modelData = storeInstance.getModel(modelName);
|
|
109
|
+
const transformedData = await transformInput(data, model, "create");
|
|
110
|
+
if (!transformedData.id) transformedData.id = crypto.randomUUID();
|
|
111
|
+
modelData.set(transformedData.id, {
|
|
112
|
+
...transformedData,
|
|
113
|
+
...data
|
|
114
|
+
});
|
|
115
|
+
if (data.email_address) modelData.set(transformedData.id, {
|
|
116
|
+
...transformedData,
|
|
117
|
+
email: data.email_address
|
|
118
|
+
});
|
|
119
|
+
const created = modelData.get(transformedData.id);
|
|
120
|
+
const out = await transformOutput(created, model, select);
|
|
121
|
+
return out;
|
|
122
|
+
},
|
|
123
|
+
findOne: async ({ where, model, select }) => {
|
|
124
|
+
debugLog("FIND_ONE", {
|
|
125
|
+
model,
|
|
126
|
+
where
|
|
127
|
+
});
|
|
128
|
+
const modelName = getModelName(model);
|
|
129
|
+
const modelData = storeInstance.getModel(modelName);
|
|
130
|
+
const transformedWhere = transformWhereClause({
|
|
131
|
+
model,
|
|
132
|
+
where
|
|
133
|
+
});
|
|
134
|
+
for (const record of modelData.values()) if (matchesWhere(record, transformedWhere)) {
|
|
135
|
+
const t = await transformOutput(record, model, select);
|
|
136
|
+
return t;
|
|
137
|
+
}
|
|
138
|
+
return null;
|
|
139
|
+
},
|
|
140
|
+
findMany: async ({ where, model, limit, offset, sortBy, select }) => {
|
|
141
|
+
debugLog("FIND_MANY", {
|
|
142
|
+
model,
|
|
143
|
+
where
|
|
144
|
+
});
|
|
145
|
+
const modelName = getModelName(model);
|
|
146
|
+
const modelData = storeInstance.getModel(modelName);
|
|
147
|
+
const transformedWhere = transformWhereClause({
|
|
148
|
+
model,
|
|
149
|
+
where
|
|
150
|
+
});
|
|
151
|
+
let results = Array.from(modelData.values()).filter((record) => matchesWhere(record, transformedWhere));
|
|
152
|
+
if (sortBy) results = applySorting(results, sortBy);
|
|
153
|
+
if (offset) results = results.slice(offset);
|
|
154
|
+
if (limit) results = results.slice(0, limit);
|
|
155
|
+
return Promise.all(results.map(async (record) => {
|
|
156
|
+
const transformed = await transformOutput(record, model, select);
|
|
157
|
+
return transformed;
|
|
158
|
+
}));
|
|
159
|
+
},
|
|
160
|
+
update: async ({ where, update, model, select }) => {
|
|
161
|
+
debugLog("UPDATE", {
|
|
162
|
+
model,
|
|
163
|
+
where
|
|
164
|
+
});
|
|
165
|
+
const modelName = getModelName(model);
|
|
166
|
+
const modelData = storeInstance.getModel(modelName);
|
|
167
|
+
const transformedWhere = transformWhereClause({
|
|
168
|
+
model,
|
|
169
|
+
where
|
|
170
|
+
});
|
|
171
|
+
for (const [id, record] of modelData.entries()) if (matchesWhere(record, transformedWhere)) {
|
|
172
|
+
const transformedData = await transformInput(update, model, "update");
|
|
173
|
+
const updated = {
|
|
174
|
+
...record,
|
|
175
|
+
...transformedData
|
|
176
|
+
};
|
|
177
|
+
modelData.set(id, updated);
|
|
178
|
+
return transformOutput(updated, model, select);
|
|
179
|
+
}
|
|
180
|
+
return null;
|
|
181
|
+
},
|
|
182
|
+
updateMany: async ({ where, update, model }) => {
|
|
183
|
+
debugLog("UPDATE_MANY", {
|
|
184
|
+
model,
|
|
185
|
+
where
|
|
186
|
+
});
|
|
187
|
+
const modelName = getModelName(model);
|
|
188
|
+
const modelData = storeInstance.getModel(modelName);
|
|
189
|
+
const transformedWhere = transformWhereClause({
|
|
190
|
+
model,
|
|
191
|
+
where
|
|
192
|
+
});
|
|
193
|
+
let count = 0;
|
|
194
|
+
const transformedData = await transformInput(update, model, "update");
|
|
195
|
+
for (const [id, record] of modelData.entries()) if (matchesWhere(record, transformedWhere)) {
|
|
196
|
+
modelData.set(id, {
|
|
197
|
+
...record,
|
|
198
|
+
...transformedData
|
|
199
|
+
});
|
|
200
|
+
count++;
|
|
201
|
+
}
|
|
202
|
+
return count;
|
|
203
|
+
},
|
|
204
|
+
delete: async ({ where, model }) => {
|
|
205
|
+
debugLog("DELETE", {
|
|
206
|
+
model,
|
|
207
|
+
where
|
|
208
|
+
});
|
|
209
|
+
const modelName = getModelName(model);
|
|
210
|
+
const modelData = storeInstance.getModel(modelName);
|
|
211
|
+
for (const [id, record] of modelData.entries()) if (matchesWhere(record, where)) {
|
|
212
|
+
modelData.delete(id);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
deleteMany: async ({ where, model }) => {
|
|
217
|
+
debugLog("DELETE_MANY", {
|
|
218
|
+
model,
|
|
219
|
+
where
|
|
220
|
+
});
|
|
221
|
+
const modelName = getModelName(model);
|
|
222
|
+
const modelData = storeInstance.getModel(modelName);
|
|
223
|
+
const toDelete = [];
|
|
224
|
+
for (const [id, record] of modelData.entries()) if (matchesWhere(record, where)) toDelete.push(id);
|
|
225
|
+
toDelete.forEach((id) => modelData.delete(id));
|
|
226
|
+
return toDelete.length;
|
|
227
|
+
},
|
|
228
|
+
count: async ({ where, model }) => {
|
|
229
|
+
const modelName = getModelName(model);
|
|
230
|
+
const modelData = storeInstance.getModel(modelName);
|
|
231
|
+
return Array.from(modelData.values()).filter((record) => matchesWhere(record, where)).length;
|
|
232
|
+
}
|
|
233
|
+
})
|
|
234
|
+
});
|
|
235
|
+
return Object.assign(adapterInstance, {
|
|
236
|
+
clear: () => store.clear(),
|
|
237
|
+
getAllData: () => storeInstance.getAllData(),
|
|
238
|
+
getStore: () => store
|
|
239
|
+
});
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
//#endregion
|
|
243
|
+
export { memoryAdapter };
|
|
244
|
+
//# sourceMappingURL=better-auth.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"better-auth.mjs","names":["initialData?: Record<string, any[]>","data: Map<string, any>","modelName: string","result: Record<string, any[]>","record: any","where?: Where[]","result: boolean | null","records: any[]","sortBy?: SortBy","config: MemoryAdapterConfig","toDelete: string[]"],"sources":["../src/better-auth.ts"],"sourcesContent":["import {\n type DBAdapterDebugLogOption,\n type Where,\n createAdapterFactory,\n} from 'better-auth/adapters';\n\ninterface MemoryAdapterConfig {\n debugLogs?: DBAdapterDebugLogOption;\n usePlural?: boolean;\n initialData?: Record<string, any[]>;\n}\n\nclass MemoryStore {\n constructor(\n initialData?: Record<string, any[]>,\n private readonly data: Map<string, any> = new Map(),\n ) {\n if (initialData) {\n for (const [model, records] of Object.entries(initialData)) {\n const modelData = new Map();\n for (const record of records) {\n modelData.set(record.id, { ...record });\n }\n this.data.set(model, modelData);\n }\n }\n }\n\n getModel(modelName: string): Map<string, any> {\n if (!this.data.has(modelName)) {\n this.data.set(modelName, new Map());\n }\n return this.data.get(modelName)!;\n }\n\n clear() {\n this.data.clear();\n }\n\n getAllData() {\n const result: Record<string, any[]> = {};\n for (const [model, records] of this.data.entries()) {\n result[model] = Array.from(records.values());\n }\n return result;\n }\n}\n\nfunction matchesWhere(record: any, where?: Where[]): boolean {\n if (!where || where.length === 0) return true;\n\n let result: boolean | null = null;\n\n for (const condition of where) {\n const { field, value, operator = 'eq', connector = 'AND' } = condition;\n const recordValue = record[field];\n\n let matches = false;\n\n switch (operator) {\n case 'eq':\n matches = recordValue === value;\n break;\n case 'ne':\n matches = recordValue !== value;\n break;\n case 'lt':\n matches = recordValue < value;\n break;\n case 'lte':\n matches = recordValue <= value;\n break;\n case 'gt':\n matches = recordValue > value;\n break;\n case 'gte':\n matches = recordValue >= value;\n break;\n case 'in':\n matches = Array.isArray(value) && value.includes(recordValue);\n break;\n case 'not_in':\n matches = Array.isArray(value) && !value.includes(recordValue);\n break;\n case 'contains':\n matches =\n typeof recordValue === 'string' &&\n typeof value === 'string' &&\n recordValue.includes(value);\n break;\n case 'starts_with':\n matches =\n typeof recordValue === 'string' &&\n typeof value === 'string' &&\n recordValue.startsWith(value);\n break;\n case 'ends_with':\n matches =\n typeof recordValue === 'string' &&\n typeof value === 'string' &&\n recordValue.endsWith(value);\n break;\n default:\n matches = recordValue === value;\n }\n\n // Apply connector logic\n if (result === null) {\n result = matches;\n } else if (connector === 'OR') {\n result = result || matches;\n } else {\n // Default: AND\n result = result && matches;\n }\n }\n\n return result ?? true;\n}\ntype SortBy = {\n field: string;\n direction: 'asc' | 'desc';\n};\n\nfunction applySorting(records: any[], sortBy?: SortBy): any[] {\n if (!sortBy) return records;\n\n const { field, direction } = sortBy;\n\n return records.sort((a, b) => {\n const aVal = a[field];\n const bVal = b[field];\n\n if (aVal === bVal) return 0;\n if (aVal == null) return direction === 'asc' ? -1 : 1;\n if (bVal == null) return direction === 'asc' ? 1 : -1;\n\n const comparison = aVal < bVal ? -1 : 1;\n return direction === 'asc' ? comparison : -comparison;\n });\n}\n\nexport const memoryAdapter = (\n config: MemoryAdapterConfig = {},\n store = new Map(),\n) => {\n const storeInstance = new MemoryStore(config.initialData, store);\n\n const adapterInstance = createAdapterFactory({\n config: {\n adapterId: 'memory-adapter',\n adapterName: 'Memory Adapter',\n usePlural: config.usePlural ?? false,\n debugLogs: config.debugLogs ?? false,\n supportsJSON: true,\n supportsDates: true,\n supportsBooleans: true,\n supportsNumericIds: false,\n },\n\n adapter: ({\n debugLog,\n transformInput,\n transformOutput,\n getModelName,\n transformWhereClause,\n }) => ({\n create: async ({ data, model, select }) => {\n debugLog('CREATE', { model, data });\n const modelName = getModelName(model);\n const modelData = storeInstance.getModel(modelName);\n\n const transformedData = await transformInput(data, model, 'create');\n\n if (!transformedData.id) {\n transformedData.id = crypto.randomUUID();\n }\n\n modelData.set(transformedData.id, { ...transformedData, ...data });\n\n if (data.email_address) {\n modelData.set(transformedData.id, {\n ...transformedData,\n email: data.email_address,\n });\n }\n const created = modelData.get(transformedData.id);\n\n const out = (await transformOutput(created, model, select)) as any;\n\n return out;\n },\n\n findOne: async ({ where, model, select }) => {\n debugLog('FIND_ONE', { model, where });\n const modelName = getModelName(model);\n const modelData = storeInstance.getModel(modelName);\n const transformedWhere = transformWhereClause({ model, where });\n\n for (const record of modelData.values()) {\n if (matchesWhere(record, transformedWhere)) {\n const t = (await transformOutput(record, model, select)) as any;\n\n return t;\n }\n }\n return null;\n },\n\n findMany: async ({ where, model, limit, offset, sortBy, select }) => {\n debugLog('FIND_MANY', { model, where });\n\n const modelName = getModelName(model);\n const modelData = storeInstance.getModel(modelName);\n const transformedWhere = transformWhereClause({ model, where });\n\n let results = Array.from(modelData.values()).filter((record) =>\n matchesWhere(record, transformedWhere),\n );\n\n if (sortBy) {\n results = applySorting(results, sortBy);\n }\n\n if (offset) {\n results = results.slice(offset);\n }\n if (limit) {\n results = results.slice(0, limit);\n }\n\n return Promise.all(\n results.map(async (record) => {\n const transformed = await transformOutput(record, model, select);\n\n return transformed;\n }),\n );\n },\n\n update: async ({ where, update, model, select }) => {\n debugLog('UPDATE', { model, where });\n\n const modelName = getModelName(model);\n const modelData = storeInstance.getModel(modelName);\n const transformedWhere = transformWhereClause({ model, where });\n\n for (const [id, record] of modelData.entries()) {\n if (matchesWhere(record, transformedWhere)) {\n const transformedData = await transformInput(\n update as any,\n model,\n 'update',\n );\n const updated = { ...record, ...transformedData };\n modelData.set(id, updated);\n return transformOutput(updated, model, select) as any;\n }\n }\n return null;\n },\n\n updateMany: async ({ where, update, model }) => {\n debugLog('UPDATE_MANY', { model, where });\n const modelName = getModelName(model);\n const modelData = storeInstance.getModel(modelName);\n const transformedWhere = transformWhereClause({ model, where });\n\n let count = 0;\n const transformedData = await transformInput(update, model, 'update');\n\n for (const [id, record] of modelData.entries()) {\n if (matchesWhere(record, transformedWhere)) {\n modelData.set(id, { ...record, ...transformedData });\n count++;\n }\n }\n return count;\n },\n\n delete: async ({ where, model }) => {\n debugLog('DELETE', { model, where });\n const modelName = getModelName(model);\n const modelData = storeInstance.getModel(modelName);\n\n for (const [id, record] of modelData.entries()) {\n if (matchesWhere(record, where)) {\n modelData.delete(id);\n return;\n }\n }\n },\n\n deleteMany: async ({ where, model }) => {\n debugLog('DELETE_MANY', { model, where });\n const modelName = getModelName(model);\n const modelData = storeInstance.getModel(modelName);\n\n const toDelete: string[] = [];\n for (const [id, record] of modelData.entries()) {\n if (matchesWhere(record, where)) {\n toDelete.push(id);\n }\n }\n\n toDelete.forEach((id) => modelData.delete(id));\n return toDelete.length;\n },\n\n count: async ({ where, model }) => {\n const modelName = getModelName(model);\n const modelData = storeInstance.getModel(modelName);\n\n return Array.from(modelData.values()).filter((record) =>\n matchesWhere(record, where),\n ).length;\n },\n }),\n });\n\n // Add utility methods to the adapter\n return Object.assign(adapterInstance, {\n clear: () => store.clear(),\n getAllData: () => storeInstance.getAllData(),\n getStore: () => store,\n });\n};\n"],"mappings":";;;AAYA,IAAM,cAAN,MAAkB;CAChB,YACEA,aACiBC,uBAAyB,IAAI,OAC9C;EADiB;AAEjB,MAAI,YACF,MAAK,MAAM,CAAC,OAAO,QAAQ,IAAI,OAAO,QAAQ,YAAY,EAAE;GAC1D,MAAM,4BAAY,IAAI;AACtB,QAAK,MAAM,UAAU,QACnB,WAAU,IAAI,OAAO,IAAI,EAAE,GAAG,OAAQ,EAAC;AAEzC,QAAK,KAAK,IAAI,OAAO,UAAU;EAChC;CAEJ;CAED,SAASC,WAAqC;AAC5C,OAAK,KAAK,KAAK,IAAI,UAAU,CAC3B,MAAK,KAAK,IAAI,2BAAW,IAAI,MAAM;AAErC,SAAO,KAAK,KAAK,IAAI,UAAU;CAChC;CAED,QAAQ;AACN,OAAK,KAAK,OAAO;CAClB;CAED,aAAa;EACX,MAAMC,SAAgC,CAAE;AACxC,OAAK,MAAM,CAAC,OAAO,QAAQ,IAAI,KAAK,KAAK,SAAS,CAChD,QAAO,SAAS,MAAM,KAAK,QAAQ,QAAQ,CAAC;AAE9C,SAAO;CACR;AACF;AAED,SAAS,aAAaC,QAAaC,OAA0B;AAC3D,MAAK,SAAS,MAAM,WAAW,EAAG,QAAO;CAEzC,IAAIC,SAAyB;AAE7B,MAAK,MAAM,aAAa,OAAO;EAC7B,MAAM,EAAE,OAAO,OAAO,WAAW,MAAM,YAAY,OAAO,GAAG;EAC7D,MAAM,cAAc,OAAO;EAE3B,IAAI,UAAU;AAEd,UAAQ,UAAR;GACE,KAAK;AACH,cAAU,gBAAgB;AAC1B;GACF,KAAK;AACH,cAAU,gBAAgB;AAC1B;GACF,KAAK;AACH,cAAU,cAAc;AACxB;GACF,KAAK;AACH,cAAU,eAAe;AACzB;GACF,KAAK;AACH,cAAU,cAAc;AACxB;GACF,KAAK;AACH,cAAU,eAAe;AACzB;GACF,KAAK;AACH,cAAU,MAAM,QAAQ,MAAM,IAAI,MAAM,SAAS,YAAY;AAC7D;GACF,KAAK;AACH,cAAU,MAAM,QAAQ,MAAM,KAAK,MAAM,SAAS,YAAY;AAC9D;GACF,KAAK;AACH,qBACS,gBAAgB,mBAChB,UAAU,YACjB,YAAY,SAAS,MAAM;AAC7B;GACF,KAAK;AACH,qBACS,gBAAgB,mBAChB,UAAU,YACjB,YAAY,WAAW,MAAM;AAC/B;GACF,KAAK;AACH,qBACS,gBAAgB,mBAChB,UAAU,YACjB,YAAY,SAAS,MAAM;AAC7B;GACF,QACE,WAAU,gBAAgB;EAC7B;AAGD,MAAI,WAAW,KACb,UAAS;WACA,cAAc,KACvB,UAAS,UAAU;MAGnB,UAAS,UAAU;CAEtB;AAED,QAAO,UAAU;AAClB;AAMD,SAAS,aAAaC,SAAgBC,QAAwB;AAC5D,MAAK,OAAQ,QAAO;CAEpB,MAAM,EAAE,OAAO,WAAW,GAAG;AAE7B,QAAO,QAAQ,KAAK,CAAC,GAAG,MAAM;EAC5B,MAAM,OAAO,EAAE;EACf,MAAM,OAAO,EAAE;AAEf,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,QAAQ,KAAM,QAAO,cAAc,QAAQ,KAAK;AACpD,MAAI,QAAQ,KAAM,QAAO,cAAc,QAAQ,IAAI;EAEnD,MAAM,aAAa,OAAO,OAAO,KAAK;AACtC,SAAO,cAAc,QAAQ,cAAc;CAC5C,EAAC;AACH;AAED,MAAa,gBAAgB,CAC3BC,SAA8B,CAAE,GAChC,wBAAQ,IAAI,UACT;CACH,MAAM,gBAAgB,IAAI,YAAY,OAAO,aAAa;CAE1D,MAAM,kBAAkB,qBAAqB;EAC3C,QAAQ;GACN,WAAW;GACX,aAAa;GACb,WAAW,OAAO,aAAa;GAC/B,WAAW,OAAO,aAAa;GAC/B,cAAc;GACd,eAAe;GACf,kBAAkB;GAClB,oBAAoB;EACrB;EAED,SAAS,CAAC,EACR,UACA,gBACA,iBACA,cACA,sBACD,MAAM;GACL,QAAQ,OAAO,EAAE,MAAM,OAAO,QAAQ,KAAK;AACzC,aAAS,UAAU;KAAE;KAAO;IAAM,EAAC;IACnC,MAAM,YAAY,aAAa,MAAM;IACrC,MAAM,YAAY,cAAc,SAAS,UAAU;IAEnD,MAAM,kBAAkB,MAAM,eAAe,MAAM,OAAO,SAAS;AAEnE,SAAK,gBAAgB,GACnB,iBAAgB,KAAK,OAAO,YAAY;AAG1C,cAAU,IAAI,gBAAgB,IAAI;KAAE,GAAG;KAAiB,GAAG;IAAM,EAAC;AAElE,QAAI,KAAK,cACP,WAAU,IAAI,gBAAgB,IAAI;KAChC,GAAG;KACH,OAAO,KAAK;IACb,EAAC;IAEJ,MAAM,UAAU,UAAU,IAAI,gBAAgB,GAAG;IAEjD,MAAM,MAAO,MAAM,gBAAgB,SAAS,OAAO,OAAO;AAE1D,WAAO;GACR;GAED,SAAS,OAAO,EAAE,OAAO,OAAO,QAAQ,KAAK;AAC3C,aAAS,YAAY;KAAE;KAAO;IAAO,EAAC;IACtC,MAAM,YAAY,aAAa,MAAM;IACrC,MAAM,YAAY,cAAc,SAAS,UAAU;IACnD,MAAM,mBAAmB,qBAAqB;KAAE;KAAO;IAAO,EAAC;AAE/D,SAAK,MAAM,UAAU,UAAU,QAAQ,CACrC,KAAI,aAAa,QAAQ,iBAAiB,EAAE;KAC1C,MAAM,IAAK,MAAM,gBAAgB,QAAQ,OAAO,OAAO;AAEvD,YAAO;IACR;AAEH,WAAO;GACR;GAED,UAAU,OAAO,EAAE,OAAO,OAAO,OAAO,QAAQ,QAAQ,QAAQ,KAAK;AACnE,aAAS,aAAa;KAAE;KAAO;IAAO,EAAC;IAEvC,MAAM,YAAY,aAAa,MAAM;IACrC,MAAM,YAAY,cAAc,SAAS,UAAU;IACnD,MAAM,mBAAmB,qBAAqB;KAAE;KAAO;IAAO,EAAC;IAE/D,IAAI,UAAU,MAAM,KAAK,UAAU,QAAQ,CAAC,CAAC,OAAO,CAAC,WACnD,aAAa,QAAQ,iBAAiB,CACvC;AAED,QAAI,OACF,WAAU,aAAa,SAAS,OAAO;AAGzC,QAAI,OACF,WAAU,QAAQ,MAAM,OAAO;AAEjC,QAAI,MACF,WAAU,QAAQ,MAAM,GAAG,MAAM;AAGnC,WAAO,QAAQ,IACb,QAAQ,IAAI,OAAO,WAAW;KAC5B,MAAM,cAAc,MAAM,gBAAgB,QAAQ,OAAO,OAAO;AAEhE,YAAO;IACR,EAAC,CACH;GACF;GAED,QAAQ,OAAO,EAAE,OAAO,QAAQ,OAAO,QAAQ,KAAK;AAClD,aAAS,UAAU;KAAE;KAAO;IAAO,EAAC;IAEpC,MAAM,YAAY,aAAa,MAAM;IACrC,MAAM,YAAY,cAAc,SAAS,UAAU;IACnD,MAAM,mBAAmB,qBAAqB;KAAE;KAAO;IAAO,EAAC;AAE/D,SAAK,MAAM,CAAC,IAAI,OAAO,IAAI,UAAU,SAAS,CAC5C,KAAI,aAAa,QAAQ,iBAAiB,EAAE;KAC1C,MAAM,kBAAkB,MAAM,eAC5B,QACA,OACA,SACD;KACD,MAAM,UAAU;MAAE,GAAG;MAAQ,GAAG;KAAiB;AACjD,eAAU,IAAI,IAAI,QAAQ;AAC1B,YAAO,gBAAgB,SAAS,OAAO,OAAO;IAC/C;AAEH,WAAO;GACR;GAED,YAAY,OAAO,EAAE,OAAO,QAAQ,OAAO,KAAK;AAC9C,aAAS,eAAe;KAAE;KAAO;IAAO,EAAC;IACzC,MAAM,YAAY,aAAa,MAAM;IACrC,MAAM,YAAY,cAAc,SAAS,UAAU;IACnD,MAAM,mBAAmB,qBAAqB;KAAE;KAAO;IAAO,EAAC;IAE/D,IAAI,QAAQ;IACZ,MAAM,kBAAkB,MAAM,eAAe,QAAQ,OAAO,SAAS;AAErE,SAAK,MAAM,CAAC,IAAI,OAAO,IAAI,UAAU,SAAS,CAC5C,KAAI,aAAa,QAAQ,iBAAiB,EAAE;AAC1C,eAAU,IAAI,IAAI;MAAE,GAAG;MAAQ,GAAG;KAAiB,EAAC;AACpD;IACD;AAEH,WAAO;GACR;GAED,QAAQ,OAAO,EAAE,OAAO,OAAO,KAAK;AAClC,aAAS,UAAU;KAAE;KAAO;IAAO,EAAC;IACpC,MAAM,YAAY,aAAa,MAAM;IACrC,MAAM,YAAY,cAAc,SAAS,UAAU;AAEnD,SAAK,MAAM,CAAC,IAAI,OAAO,IAAI,UAAU,SAAS,CAC5C,KAAI,aAAa,QAAQ,MAAM,EAAE;AAC/B,eAAU,OAAO,GAAG;AACpB;IACD;GAEJ;GAED,YAAY,OAAO,EAAE,OAAO,OAAO,KAAK;AACtC,aAAS,eAAe;KAAE;KAAO;IAAO,EAAC;IACzC,MAAM,YAAY,aAAa,MAAM;IACrC,MAAM,YAAY,cAAc,SAAS,UAAU;IAEnD,MAAMC,WAAqB,CAAE;AAC7B,SAAK,MAAM,CAAC,IAAI,OAAO,IAAI,UAAU,SAAS,CAC5C,KAAI,aAAa,QAAQ,MAAM,CAC7B,UAAS,KAAK,GAAG;AAIrB,aAAS,QAAQ,CAAC,OAAO,UAAU,OAAO,GAAG,CAAC;AAC9C,WAAO,SAAS;GACjB;GAED,OAAO,OAAO,EAAE,OAAO,OAAO,KAAK;IACjC,MAAM,YAAY,aAAa,MAAM;IACrC,MAAM,YAAY,cAAc,SAAS,UAAU;AAEnD,WAAO,MAAM,KAAK,UAAU,QAAQ,CAAC,CAAC,OAAO,CAAC,WAC5C,aAAa,QAAQ,MAAM,CAC5B,CAAC;GACH;EACF;CACF,EAAC;AAGF,QAAO,OAAO,OAAO,iBAAiB;EACpC,OAAO,MAAM,MAAM,OAAO;EAC1B,YAAY,MAAM,cAAc,YAAY;EAC5C,UAAU,MAAM;CACjB,EAAC;AACH"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _faker_js_faker2 from "@faker-js/faker";
|
|
2
2
|
|
|
3
3
|
//#region src/faker.d.ts
|
|
4
4
|
|
|
@@ -134,7 +134,7 @@ declare function coordinateOutsideRadius(center: Coordinate, minRadiusMeters: nu
|
|
|
134
134
|
* const productPrice = faker.price();
|
|
135
135
|
* ```
|
|
136
136
|
*/
|
|
137
|
-
declare const faker$1: Readonly<
|
|
137
|
+
declare const faker$1: Readonly<_faker_js_faker2.Faker & {
|
|
138
138
|
timestamps: typeof timestamps;
|
|
139
139
|
identifier: typeof identifier;
|
|
140
140
|
sequence: typeof sequence;
|
|
@@ -163,4 +163,4 @@ type Timestamps = {
|
|
|
163
163
|
type FakerFactory = typeof faker$1;
|
|
164
164
|
//#endregion
|
|
165
165
|
export { FakerFactory, Timestamps, coordinateInRadius, faker$1 as faker, identifier, resetAllSequences, resetSequence, sequence, timestamps };
|
|
166
|
-
//# sourceMappingURL=faker-
|
|
166
|
+
//# sourceMappingURL=faker-Br8MzXil.d.mts.map
|
package/dist/faker.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { FakerFactory, Timestamps, coordinateInRadius, faker, identifier, resetAllSequences, resetSequence, sequence, timestamps } from "./faker-
|
|
1
|
+
import { FakerFactory, Timestamps, coordinateInRadius, faker, identifier, resetAllSequences, resetSequence, sequence, timestamps } from "./faker-Br8MzXil.mjs";
|
|
2
2
|
export { FakerFactory, Timestamps, coordinateInRadius, faker, identifier, resetAllSequences, resetSequence, sequence, timestamps };
|
package/dist/kysely.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import "./faker-
|
|
2
|
-
import "./Factory-
|
|
3
|
-
import { KyselyFactory } from "./KyselyFactory-
|
|
1
|
+
import "./faker-Br8MzXil.mjs";
|
|
2
|
+
import "./Factory-CRquB4vz.mjs";
|
|
3
|
+
import { KyselyFactory } from "./KyselyFactory-BDS_QqRT.mjs";
|
|
4
4
|
import "./PostgresMigrator-DQaRxoaY.mjs";
|
|
5
5
|
import { PostgresKyselyMigrator } from "./PostgresKyselyMigrator-CIx3AFSR.mjs";
|
|
6
6
|
import { DatabaseConnection, IsolationLevel } from "./VitestTransactionIsolator-CsfJBxcb.mjs";
|
package/dist/objection.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import "./faker-
|
|
2
|
-
import "./Factory-
|
|
3
|
-
import { ObjectionFactory } from "./ObjectionFactory-
|
|
1
|
+
import "./faker-Br8MzXil.mjs";
|
|
2
|
+
import "./Factory-CRquB4vz.mjs";
|
|
3
|
+
import { ObjectionFactory } from "./ObjectionFactory-C3tHvX1d.mjs";
|
|
4
4
|
import "./PostgresMigrator-DQaRxoaY.mjs";
|
|
5
5
|
import { PostgresObjectionMigrator } from "./PostgresObjectionMigrator-D_hCcrQu.mjs";
|
|
6
6
|
import { DatabaseConnection, IsolationLevel } from "./VitestTransactionIsolator-CsfJBxcb.mjs";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geekmidas/testkit",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.17",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -38,6 +38,11 @@
|
|
|
38
38
|
"types": "./dist/logger.d.ts",
|
|
39
39
|
"import": "./dist/logger.mjs",
|
|
40
40
|
"require": "./dist/logger.cjs"
|
|
41
|
+
},
|
|
42
|
+
"./better-auth": {
|
|
43
|
+
"types": "./dist/better-auth.d.ts",
|
|
44
|
+
"import": "./dist/better-auth.mjs",
|
|
45
|
+
"require": "./dist/better-auth.cjs"
|
|
41
46
|
}
|
|
42
47
|
},
|
|
43
48
|
"dependencies": {
|
|
@@ -59,6 +64,7 @@
|
|
|
59
64
|
"db-errors": "~0.2.3",
|
|
60
65
|
"vitest": "~3.2.4",
|
|
61
66
|
"@types/aws-lambda": ">=8.10.92",
|
|
67
|
+
"better-auth": ">=1.3.34",
|
|
62
68
|
"@geekmidas/envkit": "0.0.7"
|
|
63
69
|
}
|
|
64
70
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { runAdapterTest } from 'better-auth/adapters/test';
|
|
2
|
+
import { afterAll, describe } from 'vitest';
|
|
3
|
+
import { memoryAdapter } from '../better-auth';
|
|
4
|
+
|
|
5
|
+
describe.skip('Memory Adapter Tests', async () => {
|
|
6
|
+
afterAll(async () => {
|
|
7
|
+
// Run DB cleanup here...
|
|
8
|
+
});
|
|
9
|
+
const adapter = memoryAdapter({
|
|
10
|
+
debugLogs: {
|
|
11
|
+
// If your adapter config allows passing in debug logs, then pass this here.
|
|
12
|
+
isRunningAdapterTests: true, // This is our super secret flag to let us know to only log debug logs if a test fails.
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
await runAdapterTest({
|
|
17
|
+
getAdapter: async (betterAuthOptions = {}) => {
|
|
18
|
+
return adapter(betterAuthOptions);
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type DBAdapterDebugLogOption,
|
|
3
|
+
type Where,
|
|
4
|
+
createAdapterFactory,
|
|
5
|
+
} from 'better-auth/adapters';
|
|
6
|
+
|
|
7
|
+
interface MemoryAdapterConfig {
|
|
8
|
+
debugLogs?: DBAdapterDebugLogOption;
|
|
9
|
+
usePlural?: boolean;
|
|
10
|
+
initialData?: Record<string, any[]>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
class MemoryStore {
|
|
14
|
+
constructor(
|
|
15
|
+
initialData?: Record<string, any[]>,
|
|
16
|
+
private readonly data: Map<string, any> = new Map(),
|
|
17
|
+
) {
|
|
18
|
+
if (initialData) {
|
|
19
|
+
for (const [model, records] of Object.entries(initialData)) {
|
|
20
|
+
const modelData = new Map();
|
|
21
|
+
for (const record of records) {
|
|
22
|
+
modelData.set(record.id, { ...record });
|
|
23
|
+
}
|
|
24
|
+
this.data.set(model, modelData);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
getModel(modelName: string): Map<string, any> {
|
|
30
|
+
if (!this.data.has(modelName)) {
|
|
31
|
+
this.data.set(modelName, new Map());
|
|
32
|
+
}
|
|
33
|
+
return this.data.get(modelName)!;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
clear() {
|
|
37
|
+
this.data.clear();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
getAllData() {
|
|
41
|
+
const result: Record<string, any[]> = {};
|
|
42
|
+
for (const [model, records] of this.data.entries()) {
|
|
43
|
+
result[model] = Array.from(records.values());
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function matchesWhere(record: any, where?: Where[]): boolean {
|
|
50
|
+
if (!where || where.length === 0) return true;
|
|
51
|
+
|
|
52
|
+
let result: boolean | null = null;
|
|
53
|
+
|
|
54
|
+
for (const condition of where) {
|
|
55
|
+
const { field, value, operator = 'eq', connector = 'AND' } = condition;
|
|
56
|
+
const recordValue = record[field];
|
|
57
|
+
|
|
58
|
+
let matches = false;
|
|
59
|
+
|
|
60
|
+
switch (operator) {
|
|
61
|
+
case 'eq':
|
|
62
|
+
matches = recordValue === value;
|
|
63
|
+
break;
|
|
64
|
+
case 'ne':
|
|
65
|
+
matches = recordValue !== value;
|
|
66
|
+
break;
|
|
67
|
+
case 'lt':
|
|
68
|
+
matches = recordValue < value;
|
|
69
|
+
break;
|
|
70
|
+
case 'lte':
|
|
71
|
+
matches = recordValue <= value;
|
|
72
|
+
break;
|
|
73
|
+
case 'gt':
|
|
74
|
+
matches = recordValue > value;
|
|
75
|
+
break;
|
|
76
|
+
case 'gte':
|
|
77
|
+
matches = recordValue >= value;
|
|
78
|
+
break;
|
|
79
|
+
case 'in':
|
|
80
|
+
matches = Array.isArray(value) && value.includes(recordValue);
|
|
81
|
+
break;
|
|
82
|
+
case 'not_in':
|
|
83
|
+
matches = Array.isArray(value) && !value.includes(recordValue);
|
|
84
|
+
break;
|
|
85
|
+
case 'contains':
|
|
86
|
+
matches =
|
|
87
|
+
typeof recordValue === 'string' &&
|
|
88
|
+
typeof value === 'string' &&
|
|
89
|
+
recordValue.includes(value);
|
|
90
|
+
break;
|
|
91
|
+
case 'starts_with':
|
|
92
|
+
matches =
|
|
93
|
+
typeof recordValue === 'string' &&
|
|
94
|
+
typeof value === 'string' &&
|
|
95
|
+
recordValue.startsWith(value);
|
|
96
|
+
break;
|
|
97
|
+
case 'ends_with':
|
|
98
|
+
matches =
|
|
99
|
+
typeof recordValue === 'string' &&
|
|
100
|
+
typeof value === 'string' &&
|
|
101
|
+
recordValue.endsWith(value);
|
|
102
|
+
break;
|
|
103
|
+
default:
|
|
104
|
+
matches = recordValue === value;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Apply connector logic
|
|
108
|
+
if (result === null) {
|
|
109
|
+
result = matches;
|
|
110
|
+
} else if (connector === 'OR') {
|
|
111
|
+
result = result || matches;
|
|
112
|
+
} else {
|
|
113
|
+
// Default: AND
|
|
114
|
+
result = result && matches;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return result ?? true;
|
|
119
|
+
}
|
|
120
|
+
type SortBy = {
|
|
121
|
+
field: string;
|
|
122
|
+
direction: 'asc' | 'desc';
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
function applySorting(records: any[], sortBy?: SortBy): any[] {
|
|
126
|
+
if (!sortBy) return records;
|
|
127
|
+
|
|
128
|
+
const { field, direction } = sortBy;
|
|
129
|
+
|
|
130
|
+
return records.sort((a, b) => {
|
|
131
|
+
const aVal = a[field];
|
|
132
|
+
const bVal = b[field];
|
|
133
|
+
|
|
134
|
+
if (aVal === bVal) return 0;
|
|
135
|
+
if (aVal == null) return direction === 'asc' ? -1 : 1;
|
|
136
|
+
if (bVal == null) return direction === 'asc' ? 1 : -1;
|
|
137
|
+
|
|
138
|
+
const comparison = aVal < bVal ? -1 : 1;
|
|
139
|
+
return direction === 'asc' ? comparison : -comparison;
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export const memoryAdapter = (
|
|
144
|
+
config: MemoryAdapterConfig = {},
|
|
145
|
+
store = new Map(),
|
|
146
|
+
) => {
|
|
147
|
+
const storeInstance = new MemoryStore(config.initialData, store);
|
|
148
|
+
|
|
149
|
+
const adapterInstance = createAdapterFactory({
|
|
150
|
+
config: {
|
|
151
|
+
adapterId: 'memory-adapter',
|
|
152
|
+
adapterName: 'Memory Adapter',
|
|
153
|
+
usePlural: config.usePlural ?? false,
|
|
154
|
+
debugLogs: config.debugLogs ?? false,
|
|
155
|
+
supportsJSON: true,
|
|
156
|
+
supportsDates: true,
|
|
157
|
+
supportsBooleans: true,
|
|
158
|
+
supportsNumericIds: false,
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
adapter: ({
|
|
162
|
+
debugLog,
|
|
163
|
+
transformInput,
|
|
164
|
+
transformOutput,
|
|
165
|
+
getModelName,
|
|
166
|
+
transformWhereClause,
|
|
167
|
+
}) => ({
|
|
168
|
+
create: async ({ data, model, select }) => {
|
|
169
|
+
debugLog('CREATE', { model, data });
|
|
170
|
+
const modelName = getModelName(model);
|
|
171
|
+
const modelData = storeInstance.getModel(modelName);
|
|
172
|
+
|
|
173
|
+
const transformedData = await transformInput(data, model, 'create');
|
|
174
|
+
|
|
175
|
+
if (!transformedData.id) {
|
|
176
|
+
transformedData.id = crypto.randomUUID();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
modelData.set(transformedData.id, { ...transformedData, ...data });
|
|
180
|
+
|
|
181
|
+
if (data.email_address) {
|
|
182
|
+
modelData.set(transformedData.id, {
|
|
183
|
+
...transformedData,
|
|
184
|
+
email: data.email_address,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
const created = modelData.get(transformedData.id);
|
|
188
|
+
|
|
189
|
+
const out = (await transformOutput(created, model, select)) as any;
|
|
190
|
+
|
|
191
|
+
return out;
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
findOne: async ({ where, model, select }) => {
|
|
195
|
+
debugLog('FIND_ONE', { model, where });
|
|
196
|
+
const modelName = getModelName(model);
|
|
197
|
+
const modelData = storeInstance.getModel(modelName);
|
|
198
|
+
const transformedWhere = transformWhereClause({ model, where });
|
|
199
|
+
|
|
200
|
+
for (const record of modelData.values()) {
|
|
201
|
+
if (matchesWhere(record, transformedWhere)) {
|
|
202
|
+
const t = (await transformOutput(record, model, select)) as any;
|
|
203
|
+
|
|
204
|
+
return t;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return null;
|
|
208
|
+
},
|
|
209
|
+
|
|
210
|
+
findMany: async ({ where, model, limit, offset, sortBy, select }) => {
|
|
211
|
+
debugLog('FIND_MANY', { model, where });
|
|
212
|
+
|
|
213
|
+
const modelName = getModelName(model);
|
|
214
|
+
const modelData = storeInstance.getModel(modelName);
|
|
215
|
+
const transformedWhere = transformWhereClause({ model, where });
|
|
216
|
+
|
|
217
|
+
let results = Array.from(modelData.values()).filter((record) =>
|
|
218
|
+
matchesWhere(record, transformedWhere),
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
if (sortBy) {
|
|
222
|
+
results = applySorting(results, sortBy);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (offset) {
|
|
226
|
+
results = results.slice(offset);
|
|
227
|
+
}
|
|
228
|
+
if (limit) {
|
|
229
|
+
results = results.slice(0, limit);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return Promise.all(
|
|
233
|
+
results.map(async (record) => {
|
|
234
|
+
const transformed = await transformOutput(record, model, select);
|
|
235
|
+
|
|
236
|
+
return transformed;
|
|
237
|
+
}),
|
|
238
|
+
);
|
|
239
|
+
},
|
|
240
|
+
|
|
241
|
+
update: async ({ where, update, model, select }) => {
|
|
242
|
+
debugLog('UPDATE', { model, where });
|
|
243
|
+
|
|
244
|
+
const modelName = getModelName(model);
|
|
245
|
+
const modelData = storeInstance.getModel(modelName);
|
|
246
|
+
const transformedWhere = transformWhereClause({ model, where });
|
|
247
|
+
|
|
248
|
+
for (const [id, record] of modelData.entries()) {
|
|
249
|
+
if (matchesWhere(record, transformedWhere)) {
|
|
250
|
+
const transformedData = await transformInput(
|
|
251
|
+
update as any,
|
|
252
|
+
model,
|
|
253
|
+
'update',
|
|
254
|
+
);
|
|
255
|
+
const updated = { ...record, ...transformedData };
|
|
256
|
+
modelData.set(id, updated);
|
|
257
|
+
return transformOutput(updated, model, select) as any;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return null;
|
|
261
|
+
},
|
|
262
|
+
|
|
263
|
+
updateMany: async ({ where, update, model }) => {
|
|
264
|
+
debugLog('UPDATE_MANY', { model, where });
|
|
265
|
+
const modelName = getModelName(model);
|
|
266
|
+
const modelData = storeInstance.getModel(modelName);
|
|
267
|
+
const transformedWhere = transformWhereClause({ model, where });
|
|
268
|
+
|
|
269
|
+
let count = 0;
|
|
270
|
+
const transformedData = await transformInput(update, model, 'update');
|
|
271
|
+
|
|
272
|
+
for (const [id, record] of modelData.entries()) {
|
|
273
|
+
if (matchesWhere(record, transformedWhere)) {
|
|
274
|
+
modelData.set(id, { ...record, ...transformedData });
|
|
275
|
+
count++;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return count;
|
|
279
|
+
},
|
|
280
|
+
|
|
281
|
+
delete: async ({ where, model }) => {
|
|
282
|
+
debugLog('DELETE', { model, where });
|
|
283
|
+
const modelName = getModelName(model);
|
|
284
|
+
const modelData = storeInstance.getModel(modelName);
|
|
285
|
+
|
|
286
|
+
for (const [id, record] of modelData.entries()) {
|
|
287
|
+
if (matchesWhere(record, where)) {
|
|
288
|
+
modelData.delete(id);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
},
|
|
293
|
+
|
|
294
|
+
deleteMany: async ({ where, model }) => {
|
|
295
|
+
debugLog('DELETE_MANY', { model, where });
|
|
296
|
+
const modelName = getModelName(model);
|
|
297
|
+
const modelData = storeInstance.getModel(modelName);
|
|
298
|
+
|
|
299
|
+
const toDelete: string[] = [];
|
|
300
|
+
for (const [id, record] of modelData.entries()) {
|
|
301
|
+
if (matchesWhere(record, where)) {
|
|
302
|
+
toDelete.push(id);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
toDelete.forEach((id) => modelData.delete(id));
|
|
307
|
+
return toDelete.length;
|
|
308
|
+
},
|
|
309
|
+
|
|
310
|
+
count: async ({ where, model }) => {
|
|
311
|
+
const modelName = getModelName(model);
|
|
312
|
+
const modelData = storeInstance.getModel(modelName);
|
|
313
|
+
|
|
314
|
+
return Array.from(modelData.values()).filter((record) =>
|
|
315
|
+
matchesWhere(record, where),
|
|
316
|
+
).length;
|
|
317
|
+
},
|
|
318
|
+
}),
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
// Add utility methods to the adapter
|
|
322
|
+
return Object.assign(adapterInstance, {
|
|
323
|
+
clear: () => store.clear(),
|
|
324
|
+
getAllData: () => storeInstance.getAllData(),
|
|
325
|
+
getStore: () => store,
|
|
326
|
+
});
|
|
327
|
+
};
|