@dataql/prisma-adapter
Version:
Prisma adapter for DataQL with zero API changes
383 lines • 14.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PrismaClientValidationError = exports.PrismaClientInitializationError = exports.PrismaClientRustPanicError = exports.PrismaClientUnknownRequestError = exports.PrismaClientKnownRequestError = exports.PrismaClient = exports.PrismaModelDelegate = void 0;
exports.createPrismaClient = createPrismaClient;
const core_1 = require("@dataql/core");
// Prisma model delegate
class PrismaModelDelegate {
constructor(data, modelName, schema) {
this._data = data;
this._modelName = modelName;
this._collection = data.collection(modelName, schema);
}
async findMany(args) {
const filter = this._convertWhereToDataQL(args?.where);
let results = await this._collection.find(filter);
// Apply ordering
if (args?.orderBy) {
results = this._applyOrderBy(results, args.orderBy);
}
// Apply pagination
if (args?.skip) {
results = results.slice(args.skip);
}
if (args?.take) {
results = results.slice(0, args.take);
}
// Apply selection
if (args?.select) {
results = results.map((item) => this._applySelect(item, args.select));
}
return results;
}
async findUnique(args) {
const filter = this._convertWhereToDataQL(args.where);
const results = await this._collection.find(filter);
if (results.length === 0)
return null;
let result = results[0];
if (args.select) {
result = this._applySelect(result, args.select);
}
return result;
}
async findFirst(args) {
const findManyArgs = {
...args,
take: 1,
};
const results = await this.findMany(findManyArgs);
return results.length > 0 ? results[0] : null;
}
async create(args) {
const result = await this._collection.create(args.data);
if (args.select) {
return this._applySelect(result, args.select);
}
return result;
}
async createMany(args) {
const data = Array.isArray(args.data) ? args.data : [args.data];
const results = await this._collection.create(data);
return {
count: Array.isArray(results) ? results.length : 1,
};
}
async update(args) {
const filter = this._convertWhereToDataQL(args.where);
const result = await this._collection.update(filter, args.data);
if (args.select) {
return this._applySelect(result, args.select);
}
return result;
}
async updateMany(args) {
const filter = this._convertWhereToDataQL(args.where);
const results = await this._collection.update(filter, args.data);
return {
count: Array.isArray(results) ? results.length : 1,
};
}
async upsert(args) {
const filter = this._convertWhereToDataQL(args.where);
const existing = await this._collection.find(filter);
let result;
if (existing.length > 0) {
result = await this._collection.update(filter, args.update);
}
else {
result = await this._collection.create(args.create);
}
if (args.select) {
return this._applySelect(result, args.select);
}
return result;
}
async delete(args) {
const filter = this._convertWhereToDataQL(args.where);
const existing = await this._collection.find(filter);
if (existing.length === 0) {
throw new Error("Record to delete does not exist.");
}
await this._collection.delete(filter);
let result = existing[0];
if (args.select) {
result = this._applySelect(result, args.select);
}
return result;
}
async deleteMany(args) {
const filter = this._convertWhereToDataQL(args?.where);
const existing = await this._collection.find(filter);
const count = existing.length;
if (count > 0) {
await this._collection.delete(filter);
}
return { count };
}
async count(args) {
const filter = this._convertWhereToDataQL(args?.where);
const results = await this._collection.find(filter);
return results.length;
}
async aggregate(args) {
const filter = this._convertWhereToDataQL(args?.where);
let results = await this._collection.find(filter);
// Apply ordering
if (args?.orderBy) {
results = this._applyOrderBy(results, args.orderBy);
}
// Apply pagination
if (args?.skip) {
results = results.slice(args.skip);
}
if (args?.take) {
results = results.slice(0, args.take);
}
const aggregateResult = {};
// Count
if (args?._count) {
if (typeof args._count === "boolean") {
aggregateResult._count = results.length;
}
else {
const countResult = {};
for (const field in args._count) {
if (args._count[field]) {
countResult[field] = results.filter((item) => item[field] !== null && item[field] !== undefined).length;
}
}
aggregateResult._count = countResult;
}
}
// Other aggregations (avg, sum, min, max) would need more sophisticated implementation
// For now, we'll provide basic implementations
return aggregateResult;
}
_convertWhereToDataQL(where) {
if (!where)
return {};
const result = {};
for (const [key, value] of Object.entries(where)) {
if (key === "AND") {
// Handle AND conditions
const conditions = Array.isArray(value) ? value : [value];
for (const condition of conditions) {
Object.assign(result, this._convertWhereToDataQL(condition));
}
}
else if (key === "OR") {
// Handle OR conditions (simplified - DataQL might need native OR support)
result.$or = Array.isArray(value)
? value.map((v) => this._convertWhereToDataQL(v))
: [this._convertWhereToDataQL(value)];
}
else if (key === "NOT") {
// Handle NOT conditions (simplified - DataQL might need native NOT support)
result.$not = this._convertWhereToDataQL(value);
}
else if (typeof value === "object" && value !== null) {
// Handle field filters
const fieldFilter = {};
for (const [filterKey, filterValue] of Object.entries(value)) {
switch (filterKey) {
case "equals":
result[key] = filterValue;
break;
case "in":
result[key] = { $in: filterValue };
break;
case "notIn":
result[key] = { $nin: filterValue };
break;
case "lt":
result[key] = { $lt: filterValue };
break;
case "lte":
result[key] = { $lte: filterValue };
break;
case "gt":
result[key] = { $gt: filterValue };
break;
case "gte":
result[key] = { $gte: filterValue };
break;
case "contains":
result[key] = { $regex: filterValue, $options: "i" };
break;
case "startsWith":
result[key] = { $regex: `^${filterValue}`, $options: "i" };
break;
case "endsWith":
result[key] = { $regex: `${filterValue}$`, $options: "i" };
break;
case "not":
result[key] = { $ne: filterValue };
break;
default:
// Default case
result[key] = { [`$${filterKey}`]: filterValue };
}
}
}
else {
// Direct value
result[key] = value;
}
}
return result;
}
_applyOrderBy(results, orderBy) {
const orderBys = Array.isArray(orderBy) ? orderBy : [orderBy];
return results.sort((a, b) => {
for (const order of orderBys) {
for (const [field, direction] of Object.entries(order)) {
const aVal = a[field];
const bVal = b[field];
if (aVal < bVal)
return direction === "asc" ? -1 : 1;
if (aVal > bVal)
return direction === "asc" ? 1 : -1;
}
}
return 0;
});
}
_applySelect(item, select) {
if (!select)
return item;
const result = {};
for (const [key, value] of Object.entries(select)) {
if (value === true) {
result[key] = item[key];
}
else if (typeof value === "object") {
// Nested selection (simplified)
result[key] = item[key];
}
}
return result;
}
}
exports.PrismaModelDelegate = PrismaModelDelegate;
// Main Prisma client class
class PrismaClient {
constructor(options) {
this._models = new Map();
this._schemas = new Map();
// Ensure proper DataQL infrastructure routing (Client → Worker → Lambda → Database)
const dataqlOptions = {
appToken: options?.appToken || "default", // Required for DataQL routing
env: options?.env || "prod", // Routes to production infrastructure
devPrefix: options?.devPrefix || "dev_", // Optional prefix for dev environments
dbName: options?.dbName, // Database isolation per client
customConnection: options?.customConnection, // Optional custom connection
};
this._data = new core_1.Data(dataqlOptions);
}
// Register a model with schema
_registerModel(name, schema) {
const delegate = new PrismaModelDelegate(this._data, name, schema);
this._models.set(name, delegate);
this._schemas.set(name, schema);
return delegate;
}
// Get a model delegate
_getModel(name) {
const delegate = this._models.get(name);
if (!delegate) {
throw new Error(`Model ${name} has not been registered. Use _registerModel() first.`);
}
return delegate;
}
async $transaction(fnOrQueries) {
if (typeof fnOrQueries === "function") {
// Interactive transaction
return await this._data.transaction(async () => {
return await fnOrQueries(this);
});
}
else {
// Batch transaction
return await this._data.transaction(async () => {
const results = [];
for (const query of fnOrQueries) {
const result = await query;
results.push(result);
}
return results;
});
}
}
// Raw query methods (mocked for now)
async $queryRaw(query, ...values) {
// This would need to be implemented based on DataQL's raw query capabilities
throw new Error("Raw queries not yet supported in DataQL Prisma adapter");
}
async $executeRaw(query, ...values) {
// This would need to be implemented based on DataQL's raw query capabilities
throw new Error("Raw queries not yet supported in DataQL Prisma adapter");
}
// Connection management
async $connect() {
// DataQL connections are handled automatically
return Promise.resolve();
}
async $disconnect() {
// DataQL connections are handled automatically
return Promise.resolve();
}
}
exports.PrismaClient = PrismaClient;
// Helper function to create a Prisma client with schema registration
function createPrismaClient(options, schemas) {
const client = new PrismaClient(options);
if (schemas) {
for (const [modelName, schema] of Object.entries(schemas)) {
const delegate = client._registerModel(modelName, schema);
client[modelName] = delegate;
}
}
return client;
}
// Error classes
class PrismaClientKnownRequestError extends Error {
constructor(message, code, meta) {
super(message);
this.name = "PrismaClientKnownRequestError";
this.code = code;
this.meta = meta;
}
}
exports.PrismaClientKnownRequestError = PrismaClientKnownRequestError;
class PrismaClientUnknownRequestError extends Error {
constructor(message) {
super(message);
this.name = "PrismaClientUnknownRequestError";
}
}
exports.PrismaClientUnknownRequestError = PrismaClientUnknownRequestError;
class PrismaClientRustPanicError extends Error {
constructor(message) {
super(message);
this.name = "PrismaClientRustPanicError";
}
}
exports.PrismaClientRustPanicError = PrismaClientRustPanicError;
class PrismaClientInitializationError extends Error {
constructor(message) {
super(message);
this.name = "PrismaClientInitializationError";
}
}
exports.PrismaClientInitializationError = PrismaClientInitializationError;
class PrismaClientValidationError extends Error {
constructor(message) {
super(message);
this.name = "PrismaClientValidationError";
}
}
exports.PrismaClientValidationError = PrismaClientValidationError;
// Export the main client
exports.default = PrismaClient;
//# sourceMappingURL=index.js.map