@geekmidas/testkit 0.0.15 → 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-D7P3bKKb.d.mts → Factory-BZ8uMoXl.d.cts} +3 -2
- package/dist/{Factory-pNV7ZQ7-.d.cts → Factory-CRquB4vz.d.mts} +3 -2
- package/dist/Factory-WMhTNZ9S.cjs +2 -1
- package/dist/Factory-WMhTNZ9S.cjs.map +1 -0
- package/dist/Factory-z2m01hMj.mjs +2 -1
- package/dist/Factory-z2m01hMj.mjs.map +1 -0
- package/dist/Factory.d.cts +2 -2
- package/dist/Factory.d.mts +2 -2
- package/dist/{KyselyFactory-72P98y5I.d.mts → KyselyFactory-BDS_QqRT.d.mts} +4 -3
- package/dist/KyselyFactory-BcYkC0t2.mjs +2 -1
- package/dist/KyselyFactory-BcYkC0t2.mjs.map +1 -0
- package/dist/KyselyFactory-Cf0o2YxO.cjs +2 -1
- package/dist/KyselyFactory-Cf0o2YxO.cjs.map +1 -0
- package/dist/{KyselyFactory-DLBrYWxU.d.cts → KyselyFactory-DRQ83r0o.d.cts} +4 -3
- package/dist/KyselyFactory.d.cts +3 -3
- package/dist/KyselyFactory.d.mts +3 -3
- package/dist/ObjectionFactory-8hebmnai.mjs +2 -1
- package/dist/ObjectionFactory-8hebmnai.mjs.map +1 -0
- package/dist/{ObjectionFactory-B40NQWSe.d.mts → ObjectionFactory-C3tHvX1d.d.mts} +4 -3
- package/dist/{ObjectionFactory-D3l1VuyX.d.cts → ObjectionFactory-C4X78k0B.d.cts} +4 -3
- package/dist/ObjectionFactory-CDriunkS.cjs +2 -1
- package/dist/ObjectionFactory-CDriunkS.cjs.map +1 -0
- package/dist/ObjectionFactory.d.cts +3 -3
- package/dist/ObjectionFactory.d.mts +3 -3
- package/dist/{PostgresKyselyMigrator-_6yHZigp.d.mts → PostgresKyselyMigrator-CIx3AFSR.d.mts} +3 -2
- package/dist/PostgresKyselyMigrator-CQ3aUoy_.d.cts +2 -1
- package/dist/PostgresKyselyMigrator-CfytARcA.cjs +2 -1
- package/dist/PostgresKyselyMigrator-CfytARcA.cjs.map +1 -0
- package/dist/{PostgresKyselyMigrator-Bdhl251C.mjs → PostgresKyselyMigrator-upT-hmrz.mjs} +3 -2
- package/dist/PostgresKyselyMigrator-upT-hmrz.mjs.map +1 -0
- package/dist/PostgresKyselyMigrator.d.mts +2 -2
- package/dist/PostgresKyselyMigrator.mjs +2 -2
- package/dist/PostgresMigrator-D5UkK1_K.d.cts +2 -1
- package/dist/PostgresMigrator-DFcNdCvD.cjs +2 -1
- package/dist/PostgresMigrator-DFcNdCvD.cjs.map +1 -0
- package/dist/{PostgresMigrator-BlvuQl7d.d.mts → PostgresMigrator-DQaRxoaY.d.mts} +2 -1
- package/dist/{PostgresMigrator-DxPC_gGu.mjs → PostgresMigrator-DbuJGAVy.mjs} +4 -3
- package/dist/PostgresMigrator-DbuJGAVy.mjs.map +1 -0
- package/dist/PostgresMigrator.d.mts +1 -1
- package/dist/PostgresMigrator.mjs +1 -1
- package/dist/PostgresObjectionMigrator-BG6ymgnt.cjs +2 -1
- package/dist/PostgresObjectionMigrator-BG6ymgnt.cjs.map +1 -0
- package/dist/PostgresObjectionMigrator-CZHHcCOv.d.cts +2 -1
- package/dist/{PostgresObjectionMigrator-G4h5FLvU.mjs → PostgresObjectionMigrator-DPj2pOpX.mjs} +3 -2
- package/dist/PostgresObjectionMigrator-DPj2pOpX.mjs.map +1 -0
- package/dist/{PostgresObjectionMigrator-C69n7vzr.d.mts → PostgresObjectionMigrator-D_hCcrQu.d.mts} +3 -2
- package/dist/PostgresObjectionMigrator.d.mts +2 -2
- package/dist/PostgresObjectionMigrator.mjs +2 -2
- package/dist/VitestKyselyTransactionIsolator-BxjlD1YM.mjs +2 -1
- package/dist/VitestKyselyTransactionIsolator-BxjlD1YM.mjs.map +1 -0
- package/dist/{VitestKyselyTransactionIsolator-CnxpE9cH.d.mts → VitestKyselyTransactionIsolator-COCVfvfr.d.mts} +3 -2
- package/dist/VitestKyselyTransactionIsolator-Cst3vFjb.cjs +2 -1
- package/dist/VitestKyselyTransactionIsolator-Cst3vFjb.cjs.map +1 -0
- package/dist/VitestKyselyTransactionIsolator-DYUYVEh9.d.cts +2 -1
- package/dist/VitestKyselyTransactionIsolator.d.mts +2 -2
- package/dist/VitestObjectionTransactionIsolator-BU-jXEhz.mjs +2 -1
- package/dist/VitestObjectionTransactionIsolator-BU-jXEhz.mjs.map +1 -0
- package/dist/VitestObjectionTransactionIsolator-CJ4ds5Qv.d.cts +2 -1
- package/dist/VitestObjectionTransactionIsolator-DzeF4UAq.cjs +2 -1
- package/dist/VitestObjectionTransactionIsolator-DzeF4UAq.cjs.map +1 -0
- package/dist/{VitestObjectionTransactionIsolator-DIM79dCq.d.mts → VitestObjectionTransactionIsolator-b973r9O1.d.mts} +3 -2
- package/dist/VitestObjectionTransactionIsolator.d.mts +2 -2
- package/dist/VitestTransactionIsolator-BQ5FpLtC.cjs +2 -1
- package/dist/VitestTransactionIsolator-BQ5FpLtC.cjs.map +1 -0
- package/dist/{VitestTransactionIsolator-zdyiS_SY.d.mts → VitestTransactionIsolator-CsfJBxcb.d.mts} +2 -1
- package/dist/VitestTransactionIsolator-CskiiJbW.mjs +2 -1
- package/dist/VitestTransactionIsolator-CskiiJbW.mjs.map +1 -0
- package/dist/VitestTransactionIsolator-DdLNODZg.d.cts +2 -1
- package/dist/VitestTransactionIsolator.d.mts +1 -1
- package/dist/aws.cjs +126 -0
- package/dist/aws.cjs.map +1 -0
- package/dist/aws.d.cts +22 -0
- package/dist/aws.d.mts +22 -0
- package/dist/aws.mjs +123 -0
- package/dist/aws.mjs.map +1 -0
- 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/directory-B-Ozljzk.mjs +22 -0
- package/dist/directory-B-Ozljzk.mjs.map +1 -0
- package/dist/directory-B4oYx02C.d.mts +12 -0
- package/dist/directory-BUcnztHI.d.cts +12 -0
- package/dist/directory-BVC8g7cX.cjs +28 -0
- package/dist/directory-BVC8g7cX.cjs.map +1 -0
- package/dist/faker-B14IEMIN.cjs +2 -1
- package/dist/faker-B14IEMIN.cjs.map +1 -0
- package/dist/faker-BGKYFoCT.mjs +2 -1
- package/dist/faker-BGKYFoCT.mjs.map +1 -0
- package/dist/{faker-C-Iuk_R1.d.mts → faker-Br8MzXil.d.mts} +4 -3
- package/dist/{faker-BSH1EMtg.d.cts → faker-Cg76aFNO.d.cts} +4 -3
- package/dist/faker.d.cts +1 -1
- package/dist/faker.d.mts +1 -1
- package/dist/helpers.cjs +48 -2
- package/dist/helpers.cjs.map +1 -0
- package/dist/helpers.d.cts +2 -1
- package/dist/helpers.d.mts +2 -1
- package/dist/helpers.mjs +47 -2
- package/dist/helpers.mjs.map +1 -0
- package/dist/kysely.cjs +65 -2
- package/dist/kysely.cjs.map +1 -0
- package/dist/kysely.d.cts +5 -4
- package/dist/kysely.d.mts +9 -8
- package/dist/kysely.mjs +67 -4
- package/dist/kysely.mjs.map +1 -0
- package/dist/logger.cjs +23 -0
- package/dist/logger.cjs.map +1 -0
- package/dist/logger.d.cts +11 -0
- package/dist/logger.d.mts +11 -0
- package/dist/logger.mjs +22 -0
- package/dist/logger.mjs.map +1 -0
- package/dist/objection.cjs +80 -2
- package/dist/objection.cjs.map +1 -0
- package/dist/objection.d.cts +5 -4
- package/dist/objection.d.mts +9 -8
- package/dist/objection.mjs +82 -4
- package/dist/objection.mjs.map +1 -0
- package/dist/os/directory.cjs +3 -0
- package/dist/os/directory.d.cts +2 -0
- package/dist/os/directory.d.mts +2 -0
- package/dist/os/directory.mjs +3 -0
- package/dist/os/index.cjs +3 -0
- package/dist/os/index.d.cts +2 -0
- package/dist/os/index.d.mts +2 -0
- package/dist/os/index.mjs +3 -0
- package/dist/timer.cjs +9 -0
- package/dist/timer.cjs.map +1 -0
- package/dist/timer.d.cts +5 -0
- package/dist/timer.d.mts +5 -0
- package/dist/timer.mjs +8 -0
- package/dist/timer.mjs.map +1 -0
- package/package.json +30 -2
- package/src/__tests__/better-auth.spec.ts +21 -0
- package/src/aws.ts +131 -0
- package/src/better-auth.ts +327 -0
- package/src/logger.ts +18 -0
- package/src/os/directory.ts +21 -0
- package/src/os/index.ts +1 -0
- package/src/timer.ts +3 -0
- package/dist/__tests__/Factory.spec.cjs +0 -139
- package/dist/__tests__/Factory.spec.d.cts +0 -1
- package/dist/__tests__/Factory.spec.d.mts +0 -1
- package/dist/__tests__/Factory.spec.mjs +0 -138
- package/dist/__tests__/KyselyFactory.spec.cjs +0 -235
- package/dist/__tests__/KyselyFactory.spec.d.cts +0 -1
- package/dist/__tests__/KyselyFactory.spec.d.mts +0 -1
- package/dist/__tests__/KyselyFactory.spec.mjs +0 -234
- package/dist/__tests__/ObjectionFactory.spec.cjs +0 -340
- package/dist/__tests__/ObjectionFactory.spec.d.cts +0 -1
- package/dist/__tests__/ObjectionFactory.spec.d.mts +0 -1
- package/dist/__tests__/ObjectionFactory.spec.mjs +0 -339
- package/dist/__tests__/PostgresKyselyMigrator.spec.cjs +0 -397
- package/dist/__tests__/PostgresKyselyMigrator.spec.d.cts +0 -1
- package/dist/__tests__/PostgresKyselyMigrator.spec.d.mts +0 -1
- package/dist/__tests__/PostgresKyselyMigrator.spec.mjs +0 -396
- package/dist/__tests__/PostgresMigrator.spec.cjs +0 -256
- package/dist/__tests__/PostgresMigrator.spec.d.cts +0 -1
- package/dist/__tests__/PostgresMigrator.spec.d.mts +0 -1
- package/dist/__tests__/PostgresMigrator.spec.mjs +0 -255
- package/dist/__tests__/PostgresObjectionMigrator.spec.cjs +0 -432
- package/dist/__tests__/PostgresObjectionMigrator.spec.d.cts +0 -1
- package/dist/__tests__/PostgresObjectionMigrator.spec.d.mts +0 -1
- package/dist/__tests__/PostgresObjectionMigrator.spec.mjs +0 -431
- package/dist/__tests__/VitestObjectionTransactionIsolator.spec.cjs +0 -122
- package/dist/__tests__/VitestObjectionTransactionIsolator.spec.d.cts +0 -1
- package/dist/__tests__/VitestObjectionTransactionIsolator.spec.d.mts +0 -1
- package/dist/__tests__/VitestObjectionTransactionIsolator.spec.mjs +0 -121
- package/dist/__tests__/faker.spec.cjs +0 -115
- package/dist/__tests__/faker.spec.d.cts +0 -1
- package/dist/__tests__/faker.spec.d.mts +0 -1
- package/dist/__tests__/faker.spec.mjs +0 -114
- package/dist/__tests__/integration.spec.cjs +0 -282
- package/dist/__tests__/integration.spec.d.cts +0 -1
- package/dist/__tests__/integration.spec.d.mts +0 -1
- package/dist/__tests__/integration.spec.mjs +0 -281
- package/dist/helpers-B4TXg3Wp.mjs +0 -86
- package/dist/helpers-Bf0nXhbu.cjs +0 -116
- package/dist/helpers-BuPmgzyQ.mjs +0 -47
- package/dist/helpers-nEUtQ7eo.cjs +0 -53
- package/dist/kysely-C3h7kitU.mjs +0 -67
- package/dist/kysely-VU3MwvMD.cjs +0 -72
- package/dist/objection-BI7F86qf.mjs +0 -82
- package/dist/objection-BpLv_ZfC.cjs +0 -87
|
@@ -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
|
+
};
|
package/src/logger.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Logger } from '@geekmidas/logger';
|
|
2
|
+
import { vi } from 'vitest';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a mock Logger for testing
|
|
6
|
+
*/
|
|
7
|
+
export function createMockLogger(): Logger {
|
|
8
|
+
const logger: Logger = {
|
|
9
|
+
debug: vi.fn(),
|
|
10
|
+
info: vi.fn(),
|
|
11
|
+
warn: vi.fn(),
|
|
12
|
+
error: vi.fn(),
|
|
13
|
+
fatal: vi.fn(),
|
|
14
|
+
trace: vi.fn(),
|
|
15
|
+
child: vi.fn(() => logger),
|
|
16
|
+
};
|
|
17
|
+
return logger;
|
|
18
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { it } from 'vitest';
|
|
6
|
+
|
|
7
|
+
export const itWithDir = it.extend<DirectoryFixtures>({
|
|
8
|
+
// This fixture automatically provides a transaction to each test
|
|
9
|
+
dir: async ({}, use) => {
|
|
10
|
+
const tempDir = os.tmpdir();
|
|
11
|
+
const directoryName = crypto.randomUUID().replace(/-/g, '').toUpperCase();
|
|
12
|
+
const dir = path.join(tempDir, directoryName);
|
|
13
|
+
await fs.mkdir(dir, { recursive: true });
|
|
14
|
+
await use(dir);
|
|
15
|
+
await fs.rm(dir, { recursive: true, force: true });
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export interface DirectoryFixtures {
|
|
20
|
+
dir: string;
|
|
21
|
+
}
|
package/src/os/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { itWithDir } from './directory';
|
package/src/timer.ts
ADDED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
const require_chunk = require('../chunk-CUT6urMc.cjs');
|
|
2
|
-
const require_Factory = require('../Factory-WMhTNZ9S.cjs');
|
|
3
|
-
const vitest = require_chunk.__toESM(require("vitest"));
|
|
4
|
-
|
|
5
|
-
//#region src/__tests__/Factory.spec.ts
|
|
6
|
-
var TestFactory = class extends require_Factory.Factory {
|
|
7
|
-
async insert(builderName, attrs) {
|
|
8
|
-
return Promise.resolve({
|
|
9
|
-
id: 1,
|
|
10
|
-
...attrs
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
async insertMany(count, builderName, attrs) {
|
|
14
|
-
const results = [];
|
|
15
|
-
for (let i = 0; i < count; i++) {
|
|
16
|
-
const newAttrs = typeof attrs === "function" ? attrs(i) : attrs;
|
|
17
|
-
results.push(await this.insert(builderName, newAttrs));
|
|
18
|
-
}
|
|
19
|
-
return results;
|
|
20
|
-
}
|
|
21
|
-
seed(seedName, attrs) {
|
|
22
|
-
return Promise.resolve({
|
|
23
|
-
seedResult: true,
|
|
24
|
-
...attrs
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
(0, vitest.describe)("Factory", () => {
|
|
29
|
-
(0, vitest.describe)("abstract class functionality", () => {
|
|
30
|
-
(0, vitest.it)("should be instantiable through concrete implementation", () => {
|
|
31
|
-
const factory = new TestFactory();
|
|
32
|
-
(0, vitest.expect)(factory).toBeInstanceOf(require_Factory.Factory);
|
|
33
|
-
(0, vitest.expect)(factory).toBeInstanceOf(TestFactory);
|
|
34
|
-
});
|
|
35
|
-
(0, vitest.it)("should have abstract methods defined", () => {
|
|
36
|
-
const factory = new TestFactory();
|
|
37
|
-
(0, vitest.expect)(typeof factory.insert).toBe("function");
|
|
38
|
-
(0, vitest.expect)(typeof factory.insertMany).toBe("function");
|
|
39
|
-
(0, vitest.expect)(typeof factory.seed).toBe("function");
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
(0, vitest.describe)("createSeed static method", () => {
|
|
43
|
-
(0, vitest.it)("should return the seed function unchanged", () => {
|
|
44
|
-
const seedFn = async (attrs, factory, db) => {
|
|
45
|
-
return {
|
|
46
|
-
id: 1,
|
|
47
|
-
name: "test"
|
|
48
|
-
};
|
|
49
|
-
};
|
|
50
|
-
const result = require_Factory.Factory.createSeed(seedFn);
|
|
51
|
-
(0, vitest.expect)(result).toBe(seedFn);
|
|
52
|
-
(0, vitest.expect)(typeof result).toBe("function");
|
|
53
|
-
});
|
|
54
|
-
(0, vitest.it)("should work with different seed function signatures", () => {
|
|
55
|
-
const simpleSeed = () => Promise.resolve({ simple: true });
|
|
56
|
-
const complexSeed = async (attrs, factory, db) => {
|
|
57
|
-
return {
|
|
58
|
-
name: attrs.name,
|
|
59
|
-
created: true
|
|
60
|
-
};
|
|
61
|
-
};
|
|
62
|
-
const result1 = require_Factory.Factory.createSeed(simpleSeed);
|
|
63
|
-
const result2 = require_Factory.Factory.createSeed(complexSeed);
|
|
64
|
-
(0, vitest.expect)(result1).toBe(simpleSeed);
|
|
65
|
-
(0, vitest.expect)(result2).toBe(complexSeed);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
(0, vitest.describe)("concrete implementation behavior", () => {
|
|
69
|
-
let factory;
|
|
70
|
-
(0, vitest.beforeEach)(() => {
|
|
71
|
-
factory = new TestFactory();
|
|
72
|
-
});
|
|
73
|
-
(0, vitest.it)("should implement insert method", async () => {
|
|
74
|
-
const result = await factory.insert("testBuilder", { name: "test" });
|
|
75
|
-
(0, vitest.expect)(result).toEqual({
|
|
76
|
-
id: 1,
|
|
77
|
-
name: "test"
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
(0, vitest.it)("should implement insertMany method", async () => {
|
|
81
|
-
const results = await factory.insertMany(3, "testBuilder", { name: "test" });
|
|
82
|
-
(0, vitest.expect)(results).toHaveLength(3);
|
|
83
|
-
(0, vitest.expect)(results[0]).toEqual({
|
|
84
|
-
id: 1,
|
|
85
|
-
name: "test"
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
(0, vitest.it)("should implement insertMany with function attributes", async () => {
|
|
89
|
-
const results = await factory.insertMany(2, "testBuilder", (idx) => ({ name: `test${idx}` }));
|
|
90
|
-
(0, vitest.expect)(results).toHaveLength(2);
|
|
91
|
-
(0, vitest.expect)(results[0]).toEqual({
|
|
92
|
-
id: 1,
|
|
93
|
-
name: "test0"
|
|
94
|
-
});
|
|
95
|
-
(0, vitest.expect)(results[1]).toEqual({
|
|
96
|
-
id: 1,
|
|
97
|
-
name: "test1"
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
(0, vitest.it)("should implement seed method", async () => {
|
|
101
|
-
const result = await factory.seed("testSeed", { custom: "value" });
|
|
102
|
-
(0, vitest.expect)(result).toEqual({
|
|
103
|
-
seedResult: true,
|
|
104
|
-
custom: "value"
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
(0, vitest.describe)("type definitions", () => {
|
|
109
|
-
(0, vitest.it)("should properly type MixedFactoryBuilder", () => {
|
|
110
|
-
const syncBuilder = (attrs, factory, db) => ({ sync: true });
|
|
111
|
-
const asyncBuilder = async (attrs, factory, db) => ({ async: true });
|
|
112
|
-
(0, vitest.expect)(typeof syncBuilder).toBe("function");
|
|
113
|
-
(0, vitest.expect)(typeof asyncBuilder).toBe("function");
|
|
114
|
-
});
|
|
115
|
-
(0, vitest.it)("should properly type FactorySeed", () => {
|
|
116
|
-
const seed = async (attrs, factory, db) => ({ seeded: true });
|
|
117
|
-
(0, vitest.expect)(typeof seed).toBe("function");
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
(0, vitest.describe)("Factory types", () => {
|
|
122
|
-
(0, vitest.it)("should export MixedFactoryBuilder type", () => {
|
|
123
|
-
const builder = (attrs, factory, db) => {
|
|
124
|
-
return {
|
|
125
|
-
id: 1,
|
|
126
|
-
name: attrs.name
|
|
127
|
-
};
|
|
128
|
-
};
|
|
129
|
-
(0, vitest.expect)(typeof builder).toBe("function");
|
|
130
|
-
});
|
|
131
|
-
(0, vitest.it)("should export FactorySeed type", () => {
|
|
132
|
-
const seed = async (attrs, factory, db) => {
|
|
133
|
-
return { created: attrs.count };
|
|
134
|
-
};
|
|
135
|
-
(0, vitest.expect)(typeof seed).toBe("function");
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
//#endregion
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { };
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import { Factory } from "../Factory-z2m01hMj.mjs";
|
|
2
|
-
import { beforeEach, describe, expect, it } from "vitest";
|
|
3
|
-
|
|
4
|
-
//#region src/__tests__/Factory.spec.ts
|
|
5
|
-
var TestFactory = class extends Factory {
|
|
6
|
-
async insert(builderName, attrs) {
|
|
7
|
-
return Promise.resolve({
|
|
8
|
-
id: 1,
|
|
9
|
-
...attrs
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
async insertMany(count, builderName, attrs) {
|
|
13
|
-
const results = [];
|
|
14
|
-
for (let i = 0; i < count; i++) {
|
|
15
|
-
const newAttrs = typeof attrs === "function" ? attrs(i) : attrs;
|
|
16
|
-
results.push(await this.insert(builderName, newAttrs));
|
|
17
|
-
}
|
|
18
|
-
return results;
|
|
19
|
-
}
|
|
20
|
-
seed(seedName, attrs) {
|
|
21
|
-
return Promise.resolve({
|
|
22
|
-
seedResult: true,
|
|
23
|
-
...attrs
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
describe("Factory", () => {
|
|
28
|
-
describe("abstract class functionality", () => {
|
|
29
|
-
it("should be instantiable through concrete implementation", () => {
|
|
30
|
-
const factory = new TestFactory();
|
|
31
|
-
expect(factory).toBeInstanceOf(Factory);
|
|
32
|
-
expect(factory).toBeInstanceOf(TestFactory);
|
|
33
|
-
});
|
|
34
|
-
it("should have abstract methods defined", () => {
|
|
35
|
-
const factory = new TestFactory();
|
|
36
|
-
expect(typeof factory.insert).toBe("function");
|
|
37
|
-
expect(typeof factory.insertMany).toBe("function");
|
|
38
|
-
expect(typeof factory.seed).toBe("function");
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
describe("createSeed static method", () => {
|
|
42
|
-
it("should return the seed function unchanged", () => {
|
|
43
|
-
const seedFn = async (attrs, factory, db) => {
|
|
44
|
-
return {
|
|
45
|
-
id: 1,
|
|
46
|
-
name: "test"
|
|
47
|
-
};
|
|
48
|
-
};
|
|
49
|
-
const result = Factory.createSeed(seedFn);
|
|
50
|
-
expect(result).toBe(seedFn);
|
|
51
|
-
expect(typeof result).toBe("function");
|
|
52
|
-
});
|
|
53
|
-
it("should work with different seed function signatures", () => {
|
|
54
|
-
const simpleSeed = () => Promise.resolve({ simple: true });
|
|
55
|
-
const complexSeed = async (attrs, factory, db) => {
|
|
56
|
-
return {
|
|
57
|
-
name: attrs.name,
|
|
58
|
-
created: true
|
|
59
|
-
};
|
|
60
|
-
};
|
|
61
|
-
const result1 = Factory.createSeed(simpleSeed);
|
|
62
|
-
const result2 = Factory.createSeed(complexSeed);
|
|
63
|
-
expect(result1).toBe(simpleSeed);
|
|
64
|
-
expect(result2).toBe(complexSeed);
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
describe("concrete implementation behavior", () => {
|
|
68
|
-
let factory;
|
|
69
|
-
beforeEach(() => {
|
|
70
|
-
factory = new TestFactory();
|
|
71
|
-
});
|
|
72
|
-
it("should implement insert method", async () => {
|
|
73
|
-
const result = await factory.insert("testBuilder", { name: "test" });
|
|
74
|
-
expect(result).toEqual({
|
|
75
|
-
id: 1,
|
|
76
|
-
name: "test"
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
it("should implement insertMany method", async () => {
|
|
80
|
-
const results = await factory.insertMany(3, "testBuilder", { name: "test" });
|
|
81
|
-
expect(results).toHaveLength(3);
|
|
82
|
-
expect(results[0]).toEqual({
|
|
83
|
-
id: 1,
|
|
84
|
-
name: "test"
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
it("should implement insertMany with function attributes", async () => {
|
|
88
|
-
const results = await factory.insertMany(2, "testBuilder", (idx) => ({ name: `test${idx}` }));
|
|
89
|
-
expect(results).toHaveLength(2);
|
|
90
|
-
expect(results[0]).toEqual({
|
|
91
|
-
id: 1,
|
|
92
|
-
name: "test0"
|
|
93
|
-
});
|
|
94
|
-
expect(results[1]).toEqual({
|
|
95
|
-
id: 1,
|
|
96
|
-
name: "test1"
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
it("should implement seed method", async () => {
|
|
100
|
-
const result = await factory.seed("testSeed", { custom: "value" });
|
|
101
|
-
expect(result).toEqual({
|
|
102
|
-
seedResult: true,
|
|
103
|
-
custom: "value"
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
describe("type definitions", () => {
|
|
108
|
-
it("should properly type MixedFactoryBuilder", () => {
|
|
109
|
-
const syncBuilder = (attrs, factory, db) => ({ sync: true });
|
|
110
|
-
const asyncBuilder = async (attrs, factory, db) => ({ async: true });
|
|
111
|
-
expect(typeof syncBuilder).toBe("function");
|
|
112
|
-
expect(typeof asyncBuilder).toBe("function");
|
|
113
|
-
});
|
|
114
|
-
it("should properly type FactorySeed", () => {
|
|
115
|
-
const seed = async (attrs, factory, db) => ({ seeded: true });
|
|
116
|
-
expect(typeof seed).toBe("function");
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
describe("Factory types", () => {
|
|
121
|
-
it("should export MixedFactoryBuilder type", () => {
|
|
122
|
-
const builder = (attrs, factory, db) => {
|
|
123
|
-
return {
|
|
124
|
-
id: 1,
|
|
125
|
-
name: attrs.name
|
|
126
|
-
};
|
|
127
|
-
};
|
|
128
|
-
expect(typeof builder).toBe("function");
|
|
129
|
-
});
|
|
130
|
-
it("should export FactorySeed type", () => {
|
|
131
|
-
const seed = async (attrs, factory, db) => {
|
|
132
|
-
return { created: attrs.count };
|
|
133
|
-
};
|
|
134
|
-
expect(typeof seed).toBe("function");
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
//#endregion
|