UNPKG

@dataql/prisma-adapter

Version:

Prisma adapter for DataQL with zero API changes

383 lines 14.5 kB
"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