pecunia-root 0.0.3
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/adapters/drizzle/index.d.mts +47 -0
- package/dist/adapters/drizzle/index.mjs +218 -0
- package/dist/adapters/drizzle/index.mjs.map +1 -0
- package/dist/adapters/get-adapter.d.mts +7 -0
- package/dist/adapters/get-adapter.mjs +31 -0
- package/dist/adapters/get-adapter.mjs.map +1 -0
- package/dist/adapters/internal/index.mjs +11 -0
- package/dist/adapters/internal/index.mjs.map +1 -0
- package/dist/adapters/kysely/bun-sqlite-dialect.mjs +156 -0
- package/dist/adapters/kysely/bun-sqlite-dialect.mjs.map +1 -0
- package/dist/adapters/kysely/dialect.mjs +83 -0
- package/dist/adapters/kysely/dialect.mjs.map +1 -0
- package/dist/adapters/kysely/index.d.mts +34 -0
- package/dist/adapters/kysely/index.mjs +183 -0
- package/dist/adapters/kysely/index.mjs.map +1 -0
- package/dist/adapters/kysely/node-sqlite-dialect.mjs +156 -0
- package/dist/adapters/kysely/node-sqlite-dialect.mjs.map +1 -0
- package/dist/adapters/mongodb/index.d.mts +35 -0
- package/dist/adapters/mongodb/index.mjs +313 -0
- package/dist/adapters/mongodb/index.mjs.map +1 -0
- package/dist/adapters/prisma/index.d.mts +34 -0
- package/dist/adapters/prisma/index.mjs +213 -0
- package/dist/adapters/prisma/index.mjs.map +1 -0
- package/dist/api/index.d.mts +23 -0
- package/dist/api/index.mjs +126 -0
- package/dist/api/index.mjs.map +1 -0
- package/dist/context/index.mjs +77 -0
- package/dist/context/index.mjs.map +1 -0
- package/dist/db/index.d.mts +3 -0
- package/dist/db/index.mjs +4 -0
- package/dist/db/migrations/index.d.mts +21 -0
- package/dist/db/migrations/index.mjs +327 -0
- package/dist/db/migrations/index.mjs.map +1 -0
- package/dist/db/schema/get-schema.d.mts +10 -0
- package/dist/db/schema/get-schema.mjs +39 -0
- package/dist/db/schema/get-schema.mjs.map +1 -0
- package/dist/index.d.mts +9 -0
- package/dist/index.mjs +7 -0
- package/dist/payment/base.mjs +38 -0
- package/dist/payment/base.mjs.map +1 -0
- package/dist/payment/index.d.mts +21 -0
- package/dist/payment/index.mjs +23 -0
- package/dist/payment/index.mjs.map +1 -0
- package/dist/types/payment.d.mts +11 -0
- package/dist/types/payment.mjs +1 -0
- package/dist/utils/is-promise.mjs +8 -0
- package/dist/utils/is-promise.mjs.map +1 -0
- package/dist/utils/url.mjs +77 -0
- package/dist/utils/url.mjs.map +1 -0
- package/package.json +183 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import { createAdapterFactory } from "pecunia-core";
|
|
2
|
+
import { ObjectId } from "mongodb";
|
|
3
|
+
|
|
4
|
+
//#region src/adapters/mongodb/index.ts
|
|
5
|
+
const mongodbAdapter = (db, config) => {
|
|
6
|
+
let lazyOptions;
|
|
7
|
+
const createCustomAdapter = (db$1, session) => ({ getFieldName, schema, getDefaultModelName, options }) => {
|
|
8
|
+
function serializeID({ field, value, model }) {
|
|
9
|
+
model = getDefaultModelName(model);
|
|
10
|
+
if (field === "id" || field === "_id" || schema[model].fields[field]?.references?.field === "id") {
|
|
11
|
+
if (value === null || value === void 0) return value;
|
|
12
|
+
if (typeof value !== "string") {
|
|
13
|
+
if (value instanceof ObjectId) return value;
|
|
14
|
+
if (Array.isArray(value)) return value.map((v) => {
|
|
15
|
+
if (v === null || v === void 0) return v;
|
|
16
|
+
if (typeof v === "string") try {
|
|
17
|
+
return new ObjectId(v);
|
|
18
|
+
} catch {
|
|
19
|
+
return v;
|
|
20
|
+
}
|
|
21
|
+
if (v instanceof ObjectId) return v;
|
|
22
|
+
throw new Error("Invalid id value, received: " + JSON.stringify(v));
|
|
23
|
+
});
|
|
24
|
+
throw new Error("Invalid id value, received: " + JSON.stringify(value));
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
return new ObjectId(value);
|
|
28
|
+
} catch {
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
function convertWhereClause({ where, model }) {
|
|
35
|
+
if (!where.length) return {};
|
|
36
|
+
const conditions = where.map((w) => {
|
|
37
|
+
const { field: field_, value, operator = "eq", connector = "AND" } = w;
|
|
38
|
+
let condition;
|
|
39
|
+
let field = getFieldName({
|
|
40
|
+
model,
|
|
41
|
+
field: field_
|
|
42
|
+
});
|
|
43
|
+
if (field === "id") field = "_id";
|
|
44
|
+
switch (operator.toLowerCase()) {
|
|
45
|
+
case "eq":
|
|
46
|
+
condition = { [field]: serializeID({
|
|
47
|
+
field,
|
|
48
|
+
value,
|
|
49
|
+
model
|
|
50
|
+
}) };
|
|
51
|
+
break;
|
|
52
|
+
case "in":
|
|
53
|
+
condition = { [field]: { $in: Array.isArray(value) ? value.map((v) => serializeID({
|
|
54
|
+
field,
|
|
55
|
+
value: v,
|
|
56
|
+
model
|
|
57
|
+
})) : [serializeID({
|
|
58
|
+
field,
|
|
59
|
+
value,
|
|
60
|
+
model
|
|
61
|
+
})] } };
|
|
62
|
+
break;
|
|
63
|
+
case "not_in":
|
|
64
|
+
condition = { [field]: { $nin: Array.isArray(value) ? value.map((v) => serializeID({
|
|
65
|
+
field,
|
|
66
|
+
value: v,
|
|
67
|
+
model
|
|
68
|
+
})) : [serializeID({
|
|
69
|
+
field,
|
|
70
|
+
value,
|
|
71
|
+
model
|
|
72
|
+
})] } };
|
|
73
|
+
break;
|
|
74
|
+
case "gt":
|
|
75
|
+
condition = { [field]: { $gt: serializeID({
|
|
76
|
+
field,
|
|
77
|
+
value,
|
|
78
|
+
model
|
|
79
|
+
}) } };
|
|
80
|
+
break;
|
|
81
|
+
case "gte":
|
|
82
|
+
condition = { [field]: { $gte: serializeID({
|
|
83
|
+
field,
|
|
84
|
+
value,
|
|
85
|
+
model
|
|
86
|
+
}) } };
|
|
87
|
+
break;
|
|
88
|
+
case "lt":
|
|
89
|
+
condition = { [field]: { $lt: serializeID({
|
|
90
|
+
field,
|
|
91
|
+
value,
|
|
92
|
+
model
|
|
93
|
+
}) } };
|
|
94
|
+
break;
|
|
95
|
+
case "lte":
|
|
96
|
+
condition = { [field]: { $lte: serializeID({
|
|
97
|
+
field,
|
|
98
|
+
value,
|
|
99
|
+
model
|
|
100
|
+
}) } };
|
|
101
|
+
break;
|
|
102
|
+
case "ne":
|
|
103
|
+
condition = { [field]: { $ne: serializeID({
|
|
104
|
+
field,
|
|
105
|
+
value,
|
|
106
|
+
model
|
|
107
|
+
}) } };
|
|
108
|
+
break;
|
|
109
|
+
case "contains":
|
|
110
|
+
condition = { [field]: { $regex: `.*${escapeForMongoRegex(value)}.*` } };
|
|
111
|
+
break;
|
|
112
|
+
case "starts_with":
|
|
113
|
+
condition = { [field]: { $regex: `^${escapeForMongoRegex(value)}` } };
|
|
114
|
+
break;
|
|
115
|
+
case "ends_with":
|
|
116
|
+
condition = { [field]: { $regex: `${escapeForMongoRegex(value)}$` } };
|
|
117
|
+
break;
|
|
118
|
+
default: throw new Error(`Unsupported operator: ${operator}`);
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
condition,
|
|
122
|
+
connector
|
|
123
|
+
};
|
|
124
|
+
});
|
|
125
|
+
if (conditions.length === 1) return conditions[0].condition;
|
|
126
|
+
const andConditions = conditions.filter((c) => c.connector === "AND").map((c) => c.condition);
|
|
127
|
+
const orConditions = conditions.filter((c) => c.connector === "OR").map((c) => c.condition);
|
|
128
|
+
let clause = {};
|
|
129
|
+
if (andConditions.length) clause = {
|
|
130
|
+
...clause,
|
|
131
|
+
$and: andConditions
|
|
132
|
+
};
|
|
133
|
+
if (orConditions.length) clause = {
|
|
134
|
+
...clause,
|
|
135
|
+
$or: orConditions
|
|
136
|
+
};
|
|
137
|
+
return clause;
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
async create({ model, data: values }) {
|
|
141
|
+
return {
|
|
142
|
+
_id: (await db$1.collection(model).insertOne(values, { session })).insertedId.toString(),
|
|
143
|
+
...values
|
|
144
|
+
};
|
|
145
|
+
},
|
|
146
|
+
async findOne({ model, where, select }) {
|
|
147
|
+
const pipeline = [where ? { $match: convertWhereClause({
|
|
148
|
+
where,
|
|
149
|
+
model
|
|
150
|
+
}) } : { $match: {} }];
|
|
151
|
+
if (select) {
|
|
152
|
+
const projection = {};
|
|
153
|
+
select.forEach((field) => {
|
|
154
|
+
projection[getFieldName({
|
|
155
|
+
field,
|
|
156
|
+
model
|
|
157
|
+
})] = 1;
|
|
158
|
+
});
|
|
159
|
+
pipeline.push({ $project: projection });
|
|
160
|
+
}
|
|
161
|
+
pipeline.push({ $limit: 1 });
|
|
162
|
+
const res = await db$1.collection(model).aggregate(pipeline, { session }).toArray();
|
|
163
|
+
if (!res || res.length === 0) return null;
|
|
164
|
+
return res[0];
|
|
165
|
+
},
|
|
166
|
+
async findMany({ model, where, limit, offset, sortBy }) {
|
|
167
|
+
const pipeline = [where ? { $match: convertWhereClause({
|
|
168
|
+
where,
|
|
169
|
+
model
|
|
170
|
+
}) } : { $match: {} }];
|
|
171
|
+
if (sortBy) pipeline.push({ $sort: { [getFieldName({
|
|
172
|
+
field: sortBy.field,
|
|
173
|
+
model
|
|
174
|
+
})]: sortBy.direction === "desc" ? -1 : 1 } });
|
|
175
|
+
if (offset) pipeline.push({ $skip: offset });
|
|
176
|
+
if (limit) pipeline.push({ $limit: limit });
|
|
177
|
+
return await db$1.collection(model).aggregate(pipeline, { session }).toArray();
|
|
178
|
+
},
|
|
179
|
+
async count({ model, where }) {
|
|
180
|
+
const pipeline = [where ? { $match: convertWhereClause({
|
|
181
|
+
where,
|
|
182
|
+
model
|
|
183
|
+
}) } : { $match: {} }, { $count: "total" }];
|
|
184
|
+
const res = await db$1.collection(model).aggregate(pipeline, { session }).toArray();
|
|
185
|
+
if (!res || res.length === 0) return 0;
|
|
186
|
+
return res[0]?.total ?? 0;
|
|
187
|
+
},
|
|
188
|
+
async update({ model, where, update: values }) {
|
|
189
|
+
const clause = convertWhereClause({
|
|
190
|
+
where,
|
|
191
|
+
model
|
|
192
|
+
});
|
|
193
|
+
const doc = (await db$1.collection(model).findOneAndUpdate(clause, { $set: values }, {
|
|
194
|
+
session,
|
|
195
|
+
returnDocument: "after",
|
|
196
|
+
includeResultMetadata: true
|
|
197
|
+
}))?.value ?? null;
|
|
198
|
+
if (!doc) return null;
|
|
199
|
+
return doc;
|
|
200
|
+
},
|
|
201
|
+
async updateMany({ model, where, update: values }) {
|
|
202
|
+
const clause = convertWhereClause({
|
|
203
|
+
where,
|
|
204
|
+
model
|
|
205
|
+
});
|
|
206
|
+
return (await db$1.collection(model).updateMany(clause, { $set: values }, { session })).modifiedCount;
|
|
207
|
+
},
|
|
208
|
+
async delete({ model, where }) {
|
|
209
|
+
const clause = convertWhereClause({
|
|
210
|
+
where,
|
|
211
|
+
model
|
|
212
|
+
});
|
|
213
|
+
await db$1.collection(model).deleteOne(clause, { session });
|
|
214
|
+
},
|
|
215
|
+
async deleteMany({ model, where }) {
|
|
216
|
+
const clause = convertWhereClause({
|
|
217
|
+
where,
|
|
218
|
+
model
|
|
219
|
+
});
|
|
220
|
+
return (await db$1.collection(model).deleteMany(clause, { session })).deletedCount;
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
};
|
|
224
|
+
let lazyAdapter = null;
|
|
225
|
+
let adapterOptions = null;
|
|
226
|
+
adapterOptions = {
|
|
227
|
+
config: {
|
|
228
|
+
adapterId: "mongodb-adapter",
|
|
229
|
+
adapterName: "MongoDB Adapter",
|
|
230
|
+
usePlural: config?.usePlural ?? false,
|
|
231
|
+
mapKeysTransformInput: { id: "_id" },
|
|
232
|
+
mapKeysTransformOutput: { _id: "id" },
|
|
233
|
+
supportsArrays: true,
|
|
234
|
+
supportsNumericIds: false,
|
|
235
|
+
transaction: config?.client && (config?.transaction ?? true) ? async (cb) => {
|
|
236
|
+
if (!config.client) return cb(lazyAdapter(lazyOptions));
|
|
237
|
+
const session = config.client.startSession();
|
|
238
|
+
try {
|
|
239
|
+
session.startTransaction();
|
|
240
|
+
const result = await cb(createAdapterFactory({
|
|
241
|
+
config: adapterOptions.config,
|
|
242
|
+
adapter: createCustomAdapter(db, session)
|
|
243
|
+
})(lazyOptions));
|
|
244
|
+
await session.commitTransaction();
|
|
245
|
+
return result;
|
|
246
|
+
} catch (err) {
|
|
247
|
+
await session.abortTransaction();
|
|
248
|
+
throw err;
|
|
249
|
+
} finally {
|
|
250
|
+
await session.endSession();
|
|
251
|
+
}
|
|
252
|
+
} : false,
|
|
253
|
+
customTransformInput({ action, data, field, fieldAttributes, options }) {
|
|
254
|
+
if (field === "_id" || fieldAttributes.references?.field === "id") {
|
|
255
|
+
if (action !== "create") return data;
|
|
256
|
+
if (Array.isArray(data)) return data.map((v) => {
|
|
257
|
+
if (typeof v === "string") try {
|
|
258
|
+
return new ObjectId(v);
|
|
259
|
+
} catch {
|
|
260
|
+
return v;
|
|
261
|
+
}
|
|
262
|
+
return v;
|
|
263
|
+
});
|
|
264
|
+
if (typeof data === "string") try {
|
|
265
|
+
return new ObjectId(data);
|
|
266
|
+
} catch {
|
|
267
|
+
return data;
|
|
268
|
+
}
|
|
269
|
+
if (fieldAttributes?.references?.field === "id" && !fieldAttributes?.required && data === null) return null;
|
|
270
|
+
return new ObjectId();
|
|
271
|
+
}
|
|
272
|
+
return data;
|
|
273
|
+
},
|
|
274
|
+
customTransformOutput({ data, field, fieldAttributes }) {
|
|
275
|
+
if (field === "id" || fieldAttributes.references?.field === "id") {
|
|
276
|
+
if (data instanceof ObjectId) return data.toHexString();
|
|
277
|
+
if (Array.isArray(data)) return data.map((v) => {
|
|
278
|
+
if (v instanceof ObjectId) return v.toHexString();
|
|
279
|
+
return v;
|
|
280
|
+
});
|
|
281
|
+
return data;
|
|
282
|
+
}
|
|
283
|
+
return data;
|
|
284
|
+
},
|
|
285
|
+
customIdGenerator() {
|
|
286
|
+
return new ObjectId().toString();
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
adapter: createCustomAdapter(db)
|
|
290
|
+
};
|
|
291
|
+
lazyAdapter = createAdapterFactory(adapterOptions);
|
|
292
|
+
return (options) => {
|
|
293
|
+
lazyOptions = options;
|
|
294
|
+
return lazyAdapter(options);
|
|
295
|
+
};
|
|
296
|
+
};
|
|
297
|
+
/**
|
|
298
|
+
* Safely escape user input for use in a MongoDB regex.
|
|
299
|
+
* This ensures the resulting pattern is treated as literal text,
|
|
300
|
+
* and not as a regex with special syntax.
|
|
301
|
+
*
|
|
302
|
+
* @param input - The input string to escape. Any type that isn't a string will be converted to an empty string.
|
|
303
|
+
* @param maxLength - The maximum length of the input string to escape. Defaults to 256. This is to prevent DOS attacks.
|
|
304
|
+
* @returns The escaped string.
|
|
305
|
+
*/
|
|
306
|
+
function escapeForMongoRegex(input, maxLength = 256) {
|
|
307
|
+
if (typeof input !== "string") return "";
|
|
308
|
+
return input.slice(0, maxLength).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
//#endregion
|
|
312
|
+
export { mongodbAdapter };
|
|
313
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["lazyOptions: PecuniaOptions | null","condition: any","clause: any","db","pipeline: any[]","projection: any","lazyAdapter:\n | ((options: PecuniaOptions) => DBAdapter<PecuniaOptions>)\n | null","adapterOptions: AdapterFactoryOptions | null"],"sources":["../../../src/adapters/mongodb/index.ts"],"sourcesContent":["import type { PecuniaOptions } from \"pecunia-core\";\nimport type {\n AdapterFactoryCreator,\n AdapterFactoryOptions,\n DBAdapter,\n DBAdapterDebugLogOption,\n Where,\n} from \"pecunia-core\";\nimport { createAdapterFactory } from \"pecunia-core\";\nimport type { ClientSession, Db, MongoClient } from \"mongodb\";\nimport { ObjectId } from \"mongodb\";\n\nexport interface MongoDBAdapterConfig {\n /**\n * MongoDB client instance\n * If not provided, Database transactions won't be enabled.\n */\n client?: MongoClient | undefined;\n /**\n * Enable debug logs for the adapter\n *\n * @default false\n */\n debugLogs?: DBAdapterDebugLogOption | undefined;\n /**\n * Use plural table names\n *\n * @default false\n */\n usePlural?: boolean | undefined;\n /**\n * Whether to execute multiple operations in a transaction.\n *\n * If the database doesn't support transactions,\n * set this to `false` and operations will be executed sequentially.\n * @default false\n */\n transaction?: boolean | undefined;\n}\n\nexport const mongodbAdapter = (\n db: Db,\n config?: MongoDBAdapterConfig | undefined,\n) => {\n let lazyOptions: PecuniaOptions | null;\n\n const createCustomAdapter =\n (db: Db, session?: ClientSession | undefined): AdapterFactoryCreator =>\n ({ getFieldName, schema, getDefaultModelName, options }) => {\n function serializeID({\n field,\n value,\n model,\n }: {\n field: string;\n value: any;\n model: string;\n }) {\n model = getDefaultModelName(model);\n\n if (\n field === \"id\" ||\n field === \"_id\" ||\n schema[model]!.fields[field]?.references?.field === \"id\"\n ) {\n if (value === null || value === undefined) return value;\n\n if (typeof value !== \"string\") {\n if (value instanceof ObjectId) return value;\n\n if (Array.isArray(value)) {\n return value.map((v) => {\n if (v === null || v === undefined) return v;\n\n if (typeof v === \"string\") {\n try {\n return new ObjectId(v);\n } catch {\n return v;\n }\n }\n\n if (v instanceof ObjectId) return v;\n\n throw new Error(\n \"Invalid id value, received: \" + JSON.stringify(v),\n );\n });\n }\n\n throw new Error(\n \"Invalid id value, received: \" + JSON.stringify(value),\n );\n }\n\n try {\n return new ObjectId(value);\n } catch {\n return value;\n }\n }\n\n return value;\n }\n\n function convertWhereClause({\n where,\n model,\n }: {\n where: Where[];\n model: string;\n }) {\n if (!where.length) return {};\n\n const conditions = where.map((w) => {\n const {\n field: field_,\n value,\n operator = \"eq\",\n connector = \"AND\",\n } = w;\n\n let condition: any;\n let field = getFieldName({ model, field: field_ });\n if (field === \"id\") field = \"_id\";\n\n switch (operator.toLowerCase()) {\n case \"eq\":\n condition = {\n [field]: serializeID({ field, value, model }),\n };\n break;\n\n case \"in\":\n condition = {\n [field]: {\n $in: Array.isArray(value)\n ? value.map((v) => serializeID({ field, value: v, model }))\n : [serializeID({ field, value, model })],\n },\n };\n break;\n\n case \"not_in\":\n condition = {\n [field]: {\n $nin: Array.isArray(value)\n ? value.map((v) => serializeID({ field, value: v, model }))\n : [serializeID({ field, value, model })],\n },\n };\n break;\n\n case \"gt\":\n condition = {\n [field]: { $gt: serializeID({ field, value, model }) },\n };\n break;\n\n case \"gte\":\n condition = {\n [field]: { $gte: serializeID({ field, value, model }) },\n };\n break;\n\n case \"lt\":\n condition = {\n [field]: { $lt: serializeID({ field, value, model }) },\n };\n break;\n\n case \"lte\":\n condition = {\n [field]: { $lte: serializeID({ field, value, model }) },\n };\n break;\n\n case \"ne\":\n condition = {\n [field]: { $ne: serializeID({ field, value, model }) },\n };\n break;\n\n case \"contains\":\n condition = {\n [field]: {\n $regex: `.*${escapeForMongoRegex(value as string)}.*`,\n },\n };\n break;\n\n case \"starts_with\":\n condition = {\n [field]: {\n $regex: `^${escapeForMongoRegex(value as string)}`,\n },\n };\n break;\n\n case \"ends_with\":\n condition = {\n [field]: {\n $regex: `${escapeForMongoRegex(value as string)}$`,\n },\n };\n break;\n\n default:\n throw new Error(`Unsupported operator: ${operator}`);\n }\n\n return { condition, connector };\n });\n\n if (conditions.length === 1) {\n return conditions[0]!.condition;\n }\n\n const andConditions = conditions\n .filter((c) => c.connector === \"AND\")\n .map((c) => c.condition);\n\n const orConditions = conditions\n .filter((c) => c.connector === \"OR\")\n .map((c) => c.condition);\n\n let clause: any = {};\n if (andConditions.length) clause = { ...clause, $and: andConditions };\n if (orConditions.length) clause = { ...clause, $or: orConditions };\n\n return clause;\n }\n\n return {\n async create({ model, data: values }) {\n const res = await db.collection(model).insertOne(values, { session });\n const insertedData = { _id: res.insertedId.toString(), ...values };\n return insertedData as any;\n },\n\n async findOne({ model, where, select }) {\n const matchStage = where\n ? { $match: convertWhereClause({ where, model }) }\n : { $match: {} };\n\n const pipeline: any[] = [matchStage];\n\n if (select) {\n const projection: any = {};\n select.forEach((field) => {\n projection[getFieldName({ field, model })] = 1;\n });\n pipeline.push({ $project: projection });\n }\n\n pipeline.push({ $limit: 1 });\n\n const res = await db\n .collection(model)\n .aggregate(pipeline, { session })\n .toArray();\n\n if (!res || res.length === 0) return null;\n return res[0] as any;\n },\n\n async findMany({ model, where, limit, offset, sortBy }) {\n const matchStage = where\n ? { $match: convertWhereClause({ where, model }) }\n : { $match: {} };\n\n const pipeline: any[] = [matchStage];\n\n if (sortBy) {\n pipeline.push({\n $sort: {\n [getFieldName({ field: sortBy.field, model })]:\n sortBy.direction === \"desc\" ? -1 : 1,\n },\n });\n }\n\n if (offset) {\n pipeline.push({ $skip: offset });\n }\n\n if (limit) {\n pipeline.push({ $limit: limit });\n }\n\n const res = await db\n .collection(model)\n .aggregate(pipeline, { session })\n .toArray();\n\n return res as any;\n },\n\n async count({ model, where }) {\n const matchStage = where\n ? { $match: convertWhereClause({ where, model }) }\n : { $match: {} };\n\n const pipeline: any[] = [matchStage, { $count: \"total\" }];\n\n const res = await db\n .collection(model)\n .aggregate(pipeline, { session })\n .toArray();\n\n if (!res || res.length === 0) return 0;\n return res[0]?.total ?? 0;\n },\n\n async update({ model, where, update: values }) {\n const clause = convertWhereClause({ where, model });\n\n const res = await db.collection(model).findOneAndUpdate(\n clause,\n { $set: values as any },\n {\n session,\n returnDocument: \"after\",\n includeResultMetadata: true,\n },\n );\n\n const doc = (res as any)?.value ?? null;\n if (!doc) return null;\n return doc as any;\n },\n\n async updateMany({ model, where, update: values }) {\n const clause = convertWhereClause({ where, model });\n\n const res = await db\n .collection(model)\n .updateMany(clause, { $set: values as any }, { session });\n\n return res.modifiedCount;\n },\n\n async delete({ model, where }) {\n const clause = convertWhereClause({ where, model });\n await db.collection(model).deleteOne(clause, { session });\n },\n\n async deleteMany({ model, where }) {\n const clause = convertWhereClause({ where, model });\n const res = await db\n .collection(model)\n .deleteMany(clause, { session });\n return res.deletedCount;\n },\n };\n };\n\n let lazyAdapter:\n | ((options: PecuniaOptions) => DBAdapter<PecuniaOptions>)\n | null = null;\n\n let adapterOptions: AdapterFactoryOptions | null = null;\n\n adapterOptions = {\n config: {\n adapterId: \"mongodb-adapter\",\n adapterName: \"MongoDB Adapter\",\n usePlural: config?.usePlural ?? false,\n mapKeysTransformInput: {\n id: \"_id\",\n },\n mapKeysTransformOutput: {\n _id: \"id\",\n },\n supportsArrays: true,\n supportsNumericIds: false,\n transaction:\n config?.client && (config?.transaction ?? true)\n ? async (cb) => {\n if (!config.client) {\n return cb(lazyAdapter!(lazyOptions!));\n }\n\n const session = config.client.startSession();\n\n try {\n session.startTransaction();\n\n const adapter = createAdapterFactory({\n config: adapterOptions!.config,\n adapter: createCustomAdapter(db, session),\n })(lazyOptions!);\n\n const result = await cb(adapter);\n\n await session.commitTransaction();\n return result;\n } catch (err) {\n await session.abortTransaction();\n throw err;\n } finally {\n await session.endSession();\n }\n }\n : false,\n customTransformInput({ action, data, field, fieldAttributes, options }) {\n if (field === \"_id\" || fieldAttributes.references?.field === \"id\") {\n if (action !== \"create\") return data;\n\n if (Array.isArray(data)) {\n return data.map((v) => {\n if (typeof v === \"string\") {\n try {\n return new ObjectId(v);\n } catch {\n return v;\n }\n }\n return v;\n });\n }\n\n if (typeof data === \"string\") {\n try {\n return new ObjectId(data);\n } catch {\n return data;\n }\n }\n\n if (\n fieldAttributes?.references?.field === \"id\" &&\n !fieldAttributes?.required &&\n data === null\n ) {\n return null;\n }\n\n return new ObjectId();\n }\n\n return data;\n },\n customTransformOutput({ data, field, fieldAttributes }) {\n if (field === \"id\" || fieldAttributes.references?.field === \"id\") {\n if (data instanceof ObjectId) return data.toHexString();\n\n if (Array.isArray(data)) {\n return data.map((v) => {\n if (v instanceof ObjectId) return v.toHexString();\n return v;\n });\n }\n\n return data;\n }\n\n return data;\n },\n customIdGenerator() {\n return new ObjectId().toString();\n },\n },\n adapter: createCustomAdapter(db),\n };\n\n lazyAdapter = createAdapterFactory(adapterOptions);\n\n return (options: PecuniaOptions): DBAdapter<PecuniaOptions> => {\n lazyOptions = options;\n return lazyAdapter(options);\n };\n};\n\n/**\n * Safely escape user input for use in a MongoDB regex.\n * This ensures the resulting pattern is treated as literal text,\n * and not as a regex with special syntax.\n *\n * @param input - The input string to escape. Any type that isn't a string will be converted to an empty string.\n * @param maxLength - The maximum length of the input string to escape. Defaults to 256. This is to prevent DOS attacks.\n * @returns The escaped string.\n */\nfunction escapeForMongoRegex(input: string, maxLength = 256): string {\n if (typeof input !== \"string\") return \"\";\n\n // Escape all PCRE special characters\n // Source: PCRE docs — https://www.pcre.org/original/doc/html/pcrepattern.html\n return input.slice(0, maxLength).replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { DBAdapter, DBAdapterDebugLogOption, PecuniaOptions } from "pecunia-core";
|
|
2
|
+
|
|
3
|
+
//#region src/adapters/prisma/index.d.ts
|
|
4
|
+
interface PrismaConfig {
|
|
5
|
+
/**
|
|
6
|
+
* Database provider.
|
|
7
|
+
*/
|
|
8
|
+
provider: "sqlite" | "cockroachdb" | "mysql" | "postgresql" | "sqlserver" | "mongodb";
|
|
9
|
+
/**
|
|
10
|
+
* Enable debug logs for the adapter
|
|
11
|
+
*
|
|
12
|
+
* @default false
|
|
13
|
+
*/
|
|
14
|
+
debugLogs?: DBAdapterDebugLogOption | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Use plural table names
|
|
17
|
+
*
|
|
18
|
+
* @default false
|
|
19
|
+
*/
|
|
20
|
+
usePlural?: boolean | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Whether to execute multiple operations in a transaction.
|
|
23
|
+
*
|
|
24
|
+
* If the database doesn't support transactions,
|
|
25
|
+
* set this to `false` and operations will be executed sequentially.
|
|
26
|
+
* @default false
|
|
27
|
+
*/
|
|
28
|
+
transaction?: boolean | undefined;
|
|
29
|
+
}
|
|
30
|
+
interface PrismaClient {}
|
|
31
|
+
declare const prismaAdapter: (prisma: PrismaClient, config: PrismaConfig) => (options: PecuniaOptions) => DBAdapter<PecuniaOptions>;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { PrismaConfig, prismaAdapter };
|
|
34
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { PecuniaError, createAdapterFactory } from "pecunia-core";
|
|
2
|
+
|
|
3
|
+
//#region src/adapters/prisma/index.ts
|
|
4
|
+
const prismaAdapter = (prisma, config) => {
|
|
5
|
+
let lazyOptions = null;
|
|
6
|
+
const createCustomAdapter = (prisma$1) => ({ getFieldName }) => {
|
|
7
|
+
const db = prisma$1;
|
|
8
|
+
function operatorToPrismaOperator(operator) {
|
|
9
|
+
switch (operator) {
|
|
10
|
+
case "starts_with": return "startsWith";
|
|
11
|
+
case "ends_with": return "endsWith";
|
|
12
|
+
case "ne": return "not";
|
|
13
|
+
case "not_in": return "notIn";
|
|
14
|
+
default: return operator;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const convertWhereClause = ({ action, model, where }) => {
|
|
18
|
+
if (!where || !where.length) return {};
|
|
19
|
+
const buildSingleCondition = (w) => {
|
|
20
|
+
const fieldName = getFieldName({
|
|
21
|
+
model,
|
|
22
|
+
field: w.field
|
|
23
|
+
});
|
|
24
|
+
if (w.operator === "ne" && w.value === null) return {};
|
|
25
|
+
if ((w.operator === "in" || w.operator === "not_in") && Array.isArray(w.value)) {
|
|
26
|
+
const filtered = w.value.filter((v) => v != null);
|
|
27
|
+
if (filtered.length === 0) {
|
|
28
|
+
if (w.operator === "in") return { AND: [{ [fieldName]: { equals: "__never__" } }, { [fieldName]: { not: "__never__" } }] };
|
|
29
|
+
return {};
|
|
30
|
+
}
|
|
31
|
+
const prismaOp = operatorToPrismaOperator(w.operator);
|
|
32
|
+
return { [fieldName]: { [prismaOp]: filtered } };
|
|
33
|
+
}
|
|
34
|
+
if (w.operator === "eq" || !w.operator) return { [fieldName]: w.value };
|
|
35
|
+
return { [fieldName]: { [operatorToPrismaOperator(w.operator)]: w.value } };
|
|
36
|
+
};
|
|
37
|
+
if (action === "update") {
|
|
38
|
+
const and$1 = where.filter((w) => w.connector === "AND" || !w.connector);
|
|
39
|
+
const or$1 = where.filter((w) => w.connector === "OR");
|
|
40
|
+
const andSimple = and$1.filter((w) => w.operator === "eq" || !w.operator);
|
|
41
|
+
const andComplex = and$1.filter((w) => w.operator !== "eq" && w.operator !== void 0);
|
|
42
|
+
const andSimpleClause = andSimple.map((w) => buildSingleCondition(w));
|
|
43
|
+
const andComplexClause = andComplex.map((w) => buildSingleCondition(w));
|
|
44
|
+
const orClause$1 = or$1.map((w) => buildSingleCondition(w));
|
|
45
|
+
const result = {};
|
|
46
|
+
for (const clause of andSimpleClause) Object.assign(result, clause);
|
|
47
|
+
if (andComplexClause.length > 0) result.AND = andComplexClause;
|
|
48
|
+
if (orClause$1.length > 0) result.OR = orClause$1;
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
if (action === "delete") {
|
|
52
|
+
const idCondition = where.find((w) => w.field === "id");
|
|
53
|
+
if (idCondition) {
|
|
54
|
+
const idFieldName = getFieldName({
|
|
55
|
+
model,
|
|
56
|
+
field: "id"
|
|
57
|
+
});
|
|
58
|
+
const idClause = buildSingleCondition(idCondition);
|
|
59
|
+
const remainingWhere = where.filter((w) => w.field !== "id");
|
|
60
|
+
if (remainingWhere.length === 0) return idClause;
|
|
61
|
+
const and$1 = remainingWhere.filter((w) => w.connector === "AND" || !w.connector);
|
|
62
|
+
const or$1 = remainingWhere.filter((w) => w.connector === "OR");
|
|
63
|
+
const andClause$1 = and$1.map((w) => buildSingleCondition(w));
|
|
64
|
+
const orClause$1 = or$1.map((w) => buildSingleCondition(w));
|
|
65
|
+
const result = {};
|
|
66
|
+
if (idFieldName in idClause) result[idFieldName] = idClause[idFieldName];
|
|
67
|
+
else Object.assign(result, idClause);
|
|
68
|
+
if (andClause$1.length > 0) result.AND = andClause$1;
|
|
69
|
+
if (orClause$1.length > 0) result.OR = orClause$1;
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (where.length === 1) return buildSingleCondition(where[0]);
|
|
74
|
+
const and = where.filter((w) => w.connector === "AND" || !w.connector);
|
|
75
|
+
const or = where.filter((w) => w.connector === "OR");
|
|
76
|
+
const andClause = and.map((w) => buildSingleCondition(w));
|
|
77
|
+
const orClause = or.map((w) => buildSingleCondition(w));
|
|
78
|
+
return {
|
|
79
|
+
...andClause.length ? { AND: andClause } : {},
|
|
80
|
+
...orClause.length ? { OR: orClause } : {}
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
return {
|
|
84
|
+
async create({ model, data: values, select }) {
|
|
85
|
+
if (!db[model]) throw new PecuniaError(`Model ${model} does not exist in the database. If you haven't generated the Prisma client, you need to run 'npx prisma generate'`);
|
|
86
|
+
return await db[model].create({
|
|
87
|
+
data: values,
|
|
88
|
+
select: select ? Object.fromEntries(select.map((field) => [getFieldName({
|
|
89
|
+
model,
|
|
90
|
+
field
|
|
91
|
+
}), true])) : void 0
|
|
92
|
+
});
|
|
93
|
+
},
|
|
94
|
+
async findOne({ model, where, select }) {
|
|
95
|
+
const whereClause = convertWhereClause({
|
|
96
|
+
model,
|
|
97
|
+
where,
|
|
98
|
+
action: "findOne"
|
|
99
|
+
});
|
|
100
|
+
if (!db[model]) throw new PecuniaError(`Model ${model} does not exist in the database. If you haven't generated the Prisma client, you need to run 'npx prisma generate'`);
|
|
101
|
+
return await db[model].findFirst({
|
|
102
|
+
where: whereClause,
|
|
103
|
+
select: select ? Object.fromEntries(select.map((field) => [getFieldName({
|
|
104
|
+
model,
|
|
105
|
+
field
|
|
106
|
+
}), true])) : void 0
|
|
107
|
+
});
|
|
108
|
+
},
|
|
109
|
+
async findMany({ model, where, limit, offset, sortBy }) {
|
|
110
|
+
const whereClause = convertWhereClause({
|
|
111
|
+
model,
|
|
112
|
+
where,
|
|
113
|
+
action: "findMany"
|
|
114
|
+
});
|
|
115
|
+
if (!db[model]) throw new PecuniaError(`Model ${model} does not exist in the database. If you haven't generated the Prisma client, you need to run 'npx prisma generate'`);
|
|
116
|
+
return await db[model].findMany({
|
|
117
|
+
where: whereClause,
|
|
118
|
+
take: limit || 100,
|
|
119
|
+
skip: offset || 0,
|
|
120
|
+
...sortBy?.field ? { orderBy: { [getFieldName({
|
|
121
|
+
model,
|
|
122
|
+
field: sortBy.field
|
|
123
|
+
})]: sortBy.direction === "desc" ? "desc" : "asc" } } : {},
|
|
124
|
+
select: void 0
|
|
125
|
+
});
|
|
126
|
+
},
|
|
127
|
+
async count({ model, where }) {
|
|
128
|
+
const whereClause = convertWhereClause({
|
|
129
|
+
model,
|
|
130
|
+
where,
|
|
131
|
+
action: "count"
|
|
132
|
+
});
|
|
133
|
+
if (!db[model]) throw new PecuniaError(`Model ${model} does not exist in the database. If you haven't generated the Prisma client, you need to run 'npx prisma generate'`);
|
|
134
|
+
return await db[model].count({ where: whereClause });
|
|
135
|
+
},
|
|
136
|
+
async update({ model, where, update }) {
|
|
137
|
+
if (!db[model]) throw new PecuniaError(`Model ${model} does not exist in the database. If you haven't generated the Prisma client, you need to run 'npx prisma generate'`);
|
|
138
|
+
const whereClause = convertWhereClause({
|
|
139
|
+
model,
|
|
140
|
+
where,
|
|
141
|
+
action: "update"
|
|
142
|
+
});
|
|
143
|
+
return await db[model].update({
|
|
144
|
+
where: whereClause,
|
|
145
|
+
data: update
|
|
146
|
+
});
|
|
147
|
+
},
|
|
148
|
+
async updateMany({ model, where, update }) {
|
|
149
|
+
if (!db[model]) throw new PecuniaError(`Model ${model} does not exist in the database. If you haven't generated the Prisma client, you need to run 'npx prisma generate'`);
|
|
150
|
+
const whereClause = convertWhereClause({
|
|
151
|
+
model,
|
|
152
|
+
where,
|
|
153
|
+
action: "updateMany"
|
|
154
|
+
});
|
|
155
|
+
const result = await db[model].updateMany({
|
|
156
|
+
where: whereClause,
|
|
157
|
+
data: update
|
|
158
|
+
});
|
|
159
|
+
return result ? result.count : 0;
|
|
160
|
+
},
|
|
161
|
+
async delete({ model, where }) {
|
|
162
|
+
if (!db[model]) throw new PecuniaError(`Model ${model} does not exist in the database. If you haven't generated the Prisma client, you need to run 'npx prisma generate'`);
|
|
163
|
+
const whereClause = convertWhereClause({
|
|
164
|
+
model,
|
|
165
|
+
where,
|
|
166
|
+
action: "delete"
|
|
167
|
+
});
|
|
168
|
+
try {
|
|
169
|
+
await db[model].delete({ where: whereClause });
|
|
170
|
+
} catch (e) {
|
|
171
|
+
if (e?.meta?.cause === "Record to delete does not exist.") return;
|
|
172
|
+
console.log(e);
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
async deleteMany({ model, where }) {
|
|
176
|
+
const whereClause = convertWhereClause({
|
|
177
|
+
model,
|
|
178
|
+
where,
|
|
179
|
+
action: "deleteMany"
|
|
180
|
+
});
|
|
181
|
+
const result = await db[model].deleteMany({ where: whereClause });
|
|
182
|
+
return result ? result.count : 0;
|
|
183
|
+
},
|
|
184
|
+
options: config
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
let adapterOptions = null;
|
|
188
|
+
adapterOptions = {
|
|
189
|
+
config: {
|
|
190
|
+
adapterId: "prisma",
|
|
191
|
+
adapterName: "Prisma Adapter",
|
|
192
|
+
usePlural: config.usePlural ?? false,
|
|
193
|
+
supportsUUIDs: config.provider === "postgresql" ? true : false,
|
|
194
|
+
supportsArrays: config.provider === "postgresql" || config.provider === "mongodb" ? true : false,
|
|
195
|
+
transaction: config.transaction ?? false ? (cb) => prisma.$transaction((tx) => {
|
|
196
|
+
return cb(createAdapterFactory({
|
|
197
|
+
config: adapterOptions.config,
|
|
198
|
+
adapter: createCustomAdapter(tx)
|
|
199
|
+
})(lazyOptions));
|
|
200
|
+
}) : false
|
|
201
|
+
},
|
|
202
|
+
adapter: createCustomAdapter(prisma)
|
|
203
|
+
};
|
|
204
|
+
const adapter = createAdapterFactory(adapterOptions);
|
|
205
|
+
return (options) => {
|
|
206
|
+
lazyOptions = options;
|
|
207
|
+
return adapter(options);
|
|
208
|
+
};
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
//#endregion
|
|
212
|
+
export { prismaAdapter };
|
|
213
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["lazyOptions: PecuniaOptions | null","prisma","and","or","orClause","result: Record<string, any>","andClause","e: any","adapterOptions: AdapterFactoryOptions | null"],"sources":["../../../src/adapters/prisma/index.ts"],"sourcesContent":["import type { Awaitable, PecuniaOptions } from \"pecunia-core\";\nimport type {\n AdapterFactoryCreator,\n AdapterFactoryOptions,\n DBAdapter,\n DBAdapterDebugLogOption,\n Where,\n} from \"pecunia-core\";\nimport { createAdapterFactory } from \"pecunia-core\";\nimport { PecuniaError } from \"pecunia-core\";\n\nexport interface PrismaConfig {\n /**\n * Database provider.\n */\n provider:\n | \"sqlite\"\n | \"cockroachdb\"\n | \"mysql\"\n | \"postgresql\"\n | \"sqlserver\"\n | \"mongodb\";\n\n /**\n * Enable debug logs for the adapter\n *\n * @default false\n */\n debugLogs?: DBAdapterDebugLogOption | undefined;\n\n /**\n * Use plural table names\n *\n * @default false\n */\n usePlural?: boolean | undefined;\n\n /**\n * Whether to execute multiple operations in a transaction.\n *\n * If the database doesn't support transactions,\n * set this to `false` and operations will be executed sequentially.\n * @default false\n */\n transaction?: boolean | undefined;\n}\n\ninterface PrismaClient {}\n\ntype PrismaClientInternal = {\n $transaction: (\n callback: (db: PrismaClient) => Awaitable<any>,\n ) => Promise<any>;\n} & {\n [model: string]: {\n create: (data: any) => Promise<any>;\n findFirst: (data: any) => Promise<any>;\n findMany: (data: any) => Promise<any>;\n update: (data: any) => Promise<any>;\n updateMany: (data: any) => Promise<any>;\n delete: (data: any) => Promise<any>;\n count: (data: any) => Promise<any>;\n [key: string]: any;\n };\n};\n\nexport const prismaAdapter = (prisma: PrismaClient, config: PrismaConfig) => {\n let lazyOptions: PecuniaOptions | null = null;\n\n const createCustomAdapter =\n (prisma: PrismaClient): AdapterFactoryCreator =>\n ({ getFieldName }) => {\n const db = prisma as PrismaClientInternal;\n\n function operatorToPrismaOperator(operator: string) {\n switch (operator) {\n case \"starts_with\":\n return \"startsWith\";\n case \"ends_with\":\n return \"endsWith\";\n case \"ne\":\n return \"not\";\n case \"not_in\":\n return \"notIn\";\n default:\n return operator;\n }\n }\n\n const convertWhereClause = ({\n action,\n model,\n where,\n }: {\n model: string;\n where?: Where[] | undefined;\n action:\n | \"create\"\n | \"update\"\n | \"delete\"\n | \"findOne\"\n | \"findMany\"\n | \"count\"\n | \"updateMany\"\n | \"deleteMany\";\n }) => {\n if (!where || !where.length) return {};\n\n const buildSingleCondition = (w: Where) => {\n const fieldName = getFieldName({ model, field: w.field });\n\n // Prisma null semantics: \"not: null\" on nullable can behave unexpectedly;\n // for non-nullable fields it's a tautology. Skip.\n if (w.operator === \"ne\" && w.value === null) {\n return {};\n }\n\n if (\n (w.operator === \"in\" || w.operator === \"not_in\") &&\n Array.isArray(w.value)\n ) {\n const filtered = w.value.filter((v) => v != null);\n\n if (filtered.length === 0) {\n if (w.operator === \"in\") {\n return {\n AND: [\n { [fieldName]: { equals: \"__never__\" } },\n { [fieldName]: { not: \"__never__\" } },\n ],\n };\n }\n return {};\n }\n\n const prismaOp = operatorToPrismaOperator(w.operator);\n return { [fieldName]: { [prismaOp]: filtered } };\n }\n\n if (w.operator === \"eq\" || !w.operator) {\n return { [fieldName]: w.value };\n }\n\n return {\n [fieldName]: {\n [operatorToPrismaOperator(w.operator)]: w.value,\n },\n };\n };\n\n // Update: extract simple equality AND conditions to root (Prisma unique where)\n if (action === \"update\") {\n const and = where.filter(\n (w) => w.connector === \"AND\" || !w.connector,\n );\n const or = where.filter((w) => w.connector === \"OR\");\n\n const andSimple = and.filter(\n (w) => w.operator === \"eq\" || !w.operator,\n );\n const andComplex = and.filter(\n (w) => w.operator !== \"eq\" && w.operator !== undefined,\n );\n\n const andSimpleClause = andSimple.map((w) => buildSingleCondition(w));\n const andComplexClause = andComplex.map((w) =>\n buildSingleCondition(w),\n );\n const orClause = or.map((w) => buildSingleCondition(w));\n\n const result: Record<string, any> = {};\n for (const clause of andSimpleClause) Object.assign(result, clause);\n if (andComplexClause.length > 0) result.AND = andComplexClause;\n if (orClause.length > 0) result.OR = orClause;\n\n return result;\n }\n\n // Delete: extract id to root if present\n if (action === \"delete\") {\n const idCondition = where.find((w) => w.field === \"id\");\n if (idCondition) {\n const idFieldName = getFieldName({ model, field: \"id\" });\n const idClause = buildSingleCondition(idCondition);\n const remainingWhere = where.filter((w) => w.field !== \"id\");\n\n if (remainingWhere.length === 0) return idClause;\n\n const and = remainingWhere.filter(\n (w) => w.connector === \"AND\" || !w.connector,\n );\n const or = remainingWhere.filter((w) => w.connector === \"OR\");\n const andClause = and.map((w) => buildSingleCondition(w));\n const orClause = or.map((w) => buildSingleCondition(w));\n\n const result: Record<string, any> = {};\n\n if (idFieldName in idClause) {\n result[idFieldName] = (idClause as Record<string, any>)[\n idFieldName\n ];\n } else {\n Object.assign(result, idClause);\n }\n\n if (andClause.length > 0) result.AND = andClause;\n if (orClause.length > 0) result.OR = orClause;\n\n return result;\n }\n }\n\n if (where.length === 1) {\n return buildSingleCondition(where[0]!);\n }\n\n const and = where.filter((w) => w.connector === \"AND\" || !w.connector);\n const or = where.filter((w) => w.connector === \"OR\");\n\n const andClause = and.map((w) => buildSingleCondition(w));\n const orClause = or.map((w) => buildSingleCondition(w));\n\n return {\n ...(andClause.length ? { AND: andClause } : {}),\n ...(orClause.length ? { OR: orClause } : {}),\n };\n };\n\n return {\n async create({ model, data: values, select }) {\n if (!db[model]) {\n throw new PecuniaError(\n `Model ${model} does not exist in the database. If you haven't generated the Prisma client, you need to run 'npx prisma generate'`,\n );\n }\n\n const result = await db[model]!.create({\n data: values,\n select: select\n ? Object.fromEntries(\n select.map((field) => [getFieldName({ model, field }), true]),\n )\n : undefined,\n });\n\n return result;\n },\n\n async findOne({ model, where, select }) {\n const whereClause = convertWhereClause({\n model,\n where,\n action: \"findOne\",\n });\n\n if (!db[model]) {\n throw new PecuniaError(\n `Model ${model} does not exist in the database. If you haven't generated the Prisma client, you need to run 'npx prisma generate'`,\n );\n }\n\n return await db[model]!.findFirst({\n where: whereClause,\n select: select\n ? Object.fromEntries(\n select.map((field) => [getFieldName({ model, field }), true]),\n )\n : undefined,\n });\n },\n\n async findMany({ model, where, limit, offset, sortBy }) {\n const whereClause = convertWhereClause({\n model,\n where,\n action: \"findMany\",\n });\n\n if (!db[model]) {\n throw new PecuniaError(\n `Model ${model} does not exist in the database. If you haven't generated the Prisma client, you need to run 'npx prisma generate'`,\n );\n }\n\n return await db[model]!.findMany({\n where: whereClause,\n take: limit || 100,\n skip: offset || 0,\n ...(sortBy?.field\n ? {\n orderBy: {\n [getFieldName({ model, field: sortBy.field })]:\n sortBy.direction === \"desc\" ? \"desc\" : \"asc\",\n },\n }\n : {}),\n select: undefined,\n });\n },\n\n async count({ model, where }) {\n const whereClause = convertWhereClause({\n model,\n where,\n action: \"count\",\n });\n\n if (!db[model]) {\n throw new PecuniaError(\n `Model ${model} does not exist in the database. If you haven't generated the Prisma client, you need to run 'npx prisma generate'`,\n );\n }\n\n return await db[model]!.count({ where: whereClause });\n },\n\n async update({ model, where, update }) {\n if (!db[model]) {\n throw new PecuniaError(\n `Model ${model} does not exist in the database. If you haven't generated the Prisma client, you need to run 'npx prisma generate'`,\n );\n }\n\n const whereClause = convertWhereClause({\n model,\n where,\n action: \"update\",\n });\n\n return await db[model]!.update({\n where: whereClause,\n data: update,\n });\n },\n\n async updateMany({ model, where, update }) {\n if (!db[model]) {\n throw new PecuniaError(\n `Model ${model} does not exist in the database. If you haven't generated the Prisma client, you need to run 'npx prisma generate'`,\n );\n }\n\n const whereClause = convertWhereClause({\n model,\n where,\n action: \"updateMany\",\n });\n\n const result = await db[model]!.updateMany({\n where: whereClause,\n data: update,\n });\n\n return result ? (result.count as number) : 0;\n },\n\n async delete({ model, where }) {\n if (!db[model]) {\n throw new PecuniaError(\n `Model ${model} does not exist in the database. If you haven't generated the Prisma client, you need to run 'npx prisma generate'`,\n );\n }\n\n const whereClause = convertWhereClause({\n model,\n where,\n action: \"delete\",\n });\n\n try {\n await db[model]!.delete({ where: whereClause });\n } catch (e: any) {\n if (e?.meta?.cause === \"Record to delete does not exist.\") return;\n console.log(e);\n }\n },\n\n async deleteMany({ model, where }) {\n const whereClause = convertWhereClause({\n model,\n where,\n action: \"deleteMany\",\n });\n\n const result = await db[model]!.deleteMany({\n where: whereClause,\n });\n\n return result ? (result.count as number) : 0;\n },\n\n options: config,\n };\n };\n\n let adapterOptions: AdapterFactoryOptions | null = null;\n\n adapterOptions = {\n config: {\n adapterId: \"prisma\",\n adapterName: \"Prisma Adapter\",\n usePlural: config.usePlural ?? false,\n supportsUUIDs: config.provider === \"postgresql\" ? true : false,\n supportsArrays:\n config.provider === \"postgresql\" || config.provider === \"mongodb\"\n ? true\n : false,\n transaction:\n (config.transaction ?? false)\n ? (cb) =>\n (prisma as PrismaClientInternal).$transaction((tx) => {\n const adapter = createAdapterFactory({\n config: adapterOptions!.config,\n adapter: createCustomAdapter(tx),\n })(lazyOptions!);\n return cb(adapter);\n })\n : false,\n },\n adapter: createCustomAdapter(prisma),\n };\n\n const adapter = createAdapterFactory(adapterOptions);\n\n return (options: PecuniaOptions): DBAdapter<PecuniaOptions> => {\n lazyOptions = options;\n return adapter(options);\n };\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Awaitable, PecuniaContext, PecuniaEndpoint, PecuniaOptions, PecuniaPlugin } from "pecunia-core";
|
|
2
|
+
import { EndpointOptions, UnionToIntersection } from "better-call";
|
|
3
|
+
|
|
4
|
+
//#region src/api/index.d.ts
|
|
5
|
+
declare function toAuthEndpoints<const E extends Record<string, Omit<PecuniaEndpoint<string, EndpointOptions, any>, "wrap">>>(endpoints: E, ctx: PecuniaContext | Promise<PecuniaContext>): E;
|
|
6
|
+
declare function getEndpoints<Option extends PecuniaOptions>(ctx: Awaitable<PecuniaContext>, options: Option): {
|
|
7
|
+
api: {} & UnionToIntersection<Option["plugins"] extends (infer T)[] ? T extends PecuniaPlugin ? T extends {
|
|
8
|
+
endpoints: infer E;
|
|
9
|
+
} ? E : {} : {} : {}>;
|
|
10
|
+
middlewares: {
|
|
11
|
+
path: string;
|
|
12
|
+
middleware: any;
|
|
13
|
+
}[];
|
|
14
|
+
};
|
|
15
|
+
declare const router: <Option extends PecuniaOptions>(ctx: PecuniaContext, options: Option) => {
|
|
16
|
+
handler: (request: Request) => Promise<Response>;
|
|
17
|
+
endpoints: {} & UnionToIntersection<Option["plugins"] extends (infer T)[] ? T extends PecuniaPlugin ? T extends {
|
|
18
|
+
endpoints: infer E;
|
|
19
|
+
} ? E : {} : {} : {}>;
|
|
20
|
+
};
|
|
21
|
+
//#endregion
|
|
22
|
+
export { getEndpoints, router, toAuthEndpoints };
|
|
23
|
+
//# sourceMappingURL=index.d.mts.map
|