Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions dist/adapter.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type { Id, Paginated, PaginationOptions } from '@feathersjs/feathers';
import { AdapterBase, AdapterParams } from '@feathersjs/adapter-commons';
import { PrismaClient } from '@prisma/client';
import { PrismaServiceOptions } from './types';
export declare class PrismaAdapter<Result, Data extends Partial<Result> = Partial<Result>, ServiceParams extends AdapterParams = AdapterParams, PatchData extends Partial<Data> = Partial<Data>> extends AdapterBase<Result, Data, PatchData, ServiceParams, PrismaServiceOptions> {
Model: any;
client: PrismaClient;
constructor(options: PrismaServiceOptions, client: PrismaClient);
filterQuery(params: ServiceParams): {
filters: {
[key: string]: any;
};
query: import("@feathersjs/feathers").Query;
paginate: import("./types").Paginate | undefined;
};
_find(params?: ServiceParams & {
paginate?: PaginationOptions;
}): Promise<Paginated<Result>>;
_find(params?: ServiceParams & {
paginate: false;
}): Promise<Result[]>;
_find(params?: ServiceParams): Promise<Paginated<Result> | Result[]>;
_get(id: Id, params?: ServiceParams): Promise<Result>;
_create(data: Data, params?: ServiceParams): Promise<Result>;
_create(data: Data[], params?: ServiceParams): Promise<Result[]>;
_create(data: Data | Data[], params?: ServiceParams): Promise<Result | Result[]>;
_update(id: Id, data: Data, params?: ServiceParams): Promise<Result>;
private internalUpdate;
_patch(id: null, data: PatchData, params?: ServiceParams): Promise<Result[]>;
_patch(id: Id, data: PatchData, params?: ServiceParams): Promise<Result>;
_remove(id: null, params?: ServiceParams): Promise<Result[]>;
_remove(id: Id, params?: ServiceParams): Promise<Result>;
}
258 changes: 258 additions & 0 deletions dist/adapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PrismaAdapter = void 0;
const adapter_commons_1 = require("@feathersjs/adapter-commons");
const errors = require("@feathersjs/errors");
const utils_1 = require("./utils");
const constants_1 = require("./constants");
const error_handler_1 = require("./error-handler");
class PrismaAdapter extends adapter_commons_1.AdapterBase {
constructor(options, client) {
var _a, _b;
if (!client) {
throw new errors.GeneralError('PrismaClient is required.');
}
if (options.operators && !Array.isArray(options.operators)) {
throw new errors.GeneralError('The \'operators\' option must be an array. For migration from feathers.js v4 see example: https://github.com/feathersjs-ecosystem/feathers-sequelize/tree/dove#migrate-to-feathers-v5-dove');
}
super({
id: options.id || 'id',
paginate: {
default: (_a = options.paginate) === null || _a === void 0 ? void 0 : _a.default,
max: (_b = options.paginate) === null || _b === void 0 ? void 0 : _b.max,
},
model: options.model,
multi: options.multi || [],
filters: options.filters || {},
events: options.events || [],
operators: Object.values(constants_1.OPERATORS).concat(options.operators || []),
});
const { model } = options;
if (!model) {
throw new errors.GeneralError('You must provide a model string.');
}
if (!client[model]) {
throw new errors.GeneralError(`No model with name ${model} found in prisma client.`);
}
this.client = client;
this.Model = client[model];
}
filterQuery(params) {
const options = this.getOptions(params);
const { filters, query: _query } = (0, adapter_commons_1.filterQuery)(params.query || {}, options);
if (filters === null || filters === void 0 ? void 0 : filters.$select) {
if (!filters.$select.includes(this.id)) {
filters.$select.push(this.id);
}
filters.$select = filters.$select.map((select) => `${select}`);
}
return {
filters: filters !== null && filters !== void 0 ? filters : {},
query: _query,
paginate: options.paginate,
};
}
_find(params = {}) {
return __awaiter(this, void 0, void 0, function* () {
const { query, filters } = this.filterQuery(params !== null && params !== void 0 ? params : {});
const { operators = [] } = this.options;
const { skip, take, orderBy, where, select, include } = (0, utils_1.buildPrismaQueryParams)({
query, filters, whitelist: operators.concat(Object.keys(filters)),
}, this.options.id || 'id');
try {
const findMany = () => {
return this.Model.findMany(Object.assign(Object.assign(Object.assign({}, (typeof take === 'number' ? { skip, take } : { skip })), { orderBy,
where }), (0, utils_1.buildSelectOrInclude)({ select, include })));
};
if (!this.options.paginate || !this.options.paginate.default || (typeof take !== 'number' && !take)) {
const data = yield findMany();
return data;
}
const [data, count] = yield this.client.$transaction([
findMany(),
this.Model.count({
where,
}),
]);
const result = {
total: count,
skip,
limit: take,
data,
};
return result;
}
catch (e) {
(0, error_handler_1.errorHandler)(e);
}
});
}
_get(id, params = {}) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
try {
const { query, filters } = this.filterQuery(params);
const { operators = [] } = this.options;
const { where, select, include, _helper } = (0, utils_1.buildPrismaQueryParams)({
id, query, filters, whitelist: operators.concat(Object.keys(filters)),
}, (_a = this.options.id) !== null && _a !== void 0 ? _a : 'id');
if (_helper.idQueryIsObject || _helper.queryWhereExists) {
const result = yield this.Model.findFirst(Object.assign({ where: (0, utils_1.buildWhereWithOptionalIdObject)(id, where, this.options.id || 'id') }, (0, utils_1.buildSelectOrInclude)({ select, include })));
if (!result)
throw new errors.NotFound(`No record found for id '${id}' and query`);
return result;
}
(0, utils_1.checkIdInQuery)({ id, query, idField: this.options.id || 'id' });
const result = yield this.Model.findUnique(Object.assign({ where }, (0, utils_1.buildSelectOrInclude)({ select, include })));
if (!result) {
throw new errors.NotFound(`No record found for id '${id}'`);
}
return result;
}
catch (e) {
(0, error_handler_1.errorHandler)(e, 'findUnique');
}
});
}
_create(data, params = {}) {
return __awaiter(this, void 0, void 0, function* () {
const { query, filters } = this.filterQuery(params);
const { operators = [] } = this.options;
const { select, include } = (0, utils_1.buildPrismaQueryParams)({
query,
filters,
whitelist: operators.concat(Object.keys(filters))
}, this.options.id || 'id');
try {
if (Array.isArray(data)) {
if (!this.allowsMulti('create', params)) {
throw new errors.MethodNotAllowed();
}
const result = yield this.client.$transaction(data.map((d) => this.Model.create(Object.assign({ data: d }, (0, utils_1.buildSelectOrInclude)({ select, include })))));
return result;
}
const result = yield this.Model.create(Object.assign({ data }, (0, utils_1.buildSelectOrInclude)({ select, include })));
return result;
}
catch (e) {
(0, error_handler_1.errorHandler)(e);
}
});
}
_update(id, data, params = {}) {
return __awaiter(this, void 0, void 0, function* () {
return yield this.internalUpdate(id, data, params);
});
}
internalUpdate(id, data, params, returnResult = false) {
var _a, _b, _c, _d;
return __awaiter(this, void 0, void 0, function* () {
const { query, filters } = this.filterQuery(params);
const { operators = [] } = this.options;
const { where, select, include, _helper } = (0, utils_1.buildPrismaQueryParams)({
id, query, filters, whitelist: operators.concat(Object.keys(filters)),
}, (_a = this.options.id) !== null && _a !== void 0 ? _a : 'id');
try {
if (_helper.idQueryIsObject) {
const newWhere = (0, utils_1.buildWhereWithOptionalIdObject)(id, where, (_b = this.options.id) !== null && _b !== void 0 ? _b : 'id');
const [, result] = yield this.client.$transaction([
this.Model.updateMany(Object.assign({ data, where: newWhere }, (0, utils_1.buildSelectOrInclude)({ select, include }))),
this.Model.findFirst(Object.assign({ where: Object.assign(Object.assign({}, newWhere), data) }, (0, utils_1.buildSelectOrInclude)({ select, include }))),
]);
if (!result)
throw new errors.NotFound(`No record found for id '${id}'`);
return result;
}
(0, utils_1.checkIdInQuery)({ id, query, idField: (_c = this.options.id) !== null && _c !== void 0 ? _c : 'id' });
const result = yield this.Model.update(Object.assign({ data,
where }, (0, utils_1.buildSelectOrInclude)({ select, include })));
if (select || returnResult) {
return result;
}
// @ts-expect-error Type 'Result' is not assignable to type 'any'.
return Object.assign({ [(_d = this.options.id) !== null && _d !== void 0 ? _d : 'id']: result.id }, data);
}
catch (e) {
(0, error_handler_1.errorHandler)(e, 'update');
}
});
}
_patch(id, data, params = {}) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
if (!id || Array.isArray(data)) {
if (!this.allowsMulti('patch', params)) {
throw new errors.MethodNotAllowed();
}
}
if (id && !Array.isArray(data)) {
const result = yield this.internalUpdate(id, data, params, true);
return result;
}
const { query, filters } = this.filterQuery(params);
const { operators = [] } = this.options;
const { where, select, include } = (0, utils_1.buildPrismaQueryParams)({
query,
filters,
whitelist: operators.concat(Object.keys(filters)),
}, (_a = this.options.id) !== null && _a !== void 0 ? _a : 'id');
try {
const [, result] = yield this.client.$transaction([
this.Model.updateMany(Object.assign({ data,
where }, (0, utils_1.buildSelectOrInclude)({ select, include }))),
this.Model.findMany(Object.assign({ where: Object.assign(Object.assign({}, where), data) }, (0, utils_1.buildSelectOrInclude)({ select, include }))),
]);
return result;
}
catch (e) {
(0, error_handler_1.errorHandler)(e, 'updateMany');
}
});
}
_remove(id, params = {}) {
var _a, _b, _c, _d;
return __awaiter(this, void 0, void 0, function* () {
if (!id && !this.allowsMulti('remove', params)) {
throw new errors.MethodNotAllowed();
}
const { query, filters } = this.filterQuery(params);
const { operators = [] } = this.options;
const { where, select, include, _helper } = (0, utils_1.buildPrismaQueryParams)({
id: id || undefined, query, filters, whitelist: operators.concat(Object.keys(filters)),
}, (_a = this.options.id) !== null && _a !== void 0 ? _a : 'id');
if (id && !_helper.idQueryIsObject) {
try {
(0, utils_1.checkIdInQuery)({ id, query, allowOneOf: true, idField: (_b = this.options.id) !== null && _b !== void 0 ? _b : 'id' });
const result = yield this.Model.delete(Object.assign({ where: id ? { [(_c = this.options.id) !== null && _c !== void 0 ? _c : 'id']: id } : where }, (0, utils_1.buildSelectOrInclude)({ select, include })));
return result;
}
catch (e) {
(0, error_handler_1.errorHandler)(e, 'delete');
}
}
try {
const query = Object.assign({ where: id ? (0, utils_1.buildWhereWithOptionalIdObject)(id, where, (_d = this.options.id) !== null && _d !== void 0 ? _d : 'id') : where }, (0, utils_1.buildSelectOrInclude)({ select, include }));
const [data] = yield this.client.$transaction([
id ? this.Model.findFirst(query) : this.Model.findMany(query),
this.Model.deleteMany(query),
]);
if (id && !data)
throw new errors.NotFound(`No record found for id '${id}'`);
return data;
}
catch (e) {
(0, error_handler_1.errorHandler)(e, 'deleteMany');
}
});
}
}
exports.PrismaAdapter = PrismaAdapter;
2 changes: 1 addition & 1 deletion dist/error-handler.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export declare function errorHandler(error: any, prismaMethod?: string): void;
export declare function errorHandler(error: any, prismaMethod?: string): never;
32 changes: 18 additions & 14 deletions dist/service.d.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import type { Params } from '@feathersjs/feathers';
import { AdapterService } from '@feathersjs/adapter-commons';
import { Id, Paginated, PaginationOptions, Params, ServiceMethods } from '@feathersjs/feathers';
import { PrismaAdapter } from './adapter';
import { PaginatedOrArray, PrismaServiceOptions } from './types';
import { AdapterParams } from '@feathersjs/adapter-commons';
import { PrismaClient } from '@prisma/client';
import { IdField, PrismaServiceOptions } from './types';
export declare class PrismaService<ModelData = Record<string, any>> extends AdapterService {
Model: any;
client: PrismaClient;
constructor(options: PrismaServiceOptions, client: PrismaClient);
_find(params?: Params): Promise<any>;
_get(id: IdField, params?: Params): Promise<Partial<ModelData> | undefined>;
_create(data: Partial<ModelData> | Partial<ModelData>[], params?: Params): Promise<Partial<ModelData> | Partial<ModelData>[] | undefined>;
_update(id: IdField, data: Partial<ModelData>, params?: Params, returnResult?: boolean): Promise<any>;
_patch(id: IdField | null, data: Partial<ModelData> | Partial<ModelData>[], params?: Params): Promise<any>;
_remove(id: IdField | null, params?: Params): Promise<any>;
export declare class PrismaService<Result = any, Data extends Partial<Result> = Partial<Result>, ServiceParams extends Params<any> = AdapterParams, PatchData extends Partial<Data> = Partial<Data>> extends PrismaAdapter<Result, Data, ServiceParams, PatchData> implements ServiceMethods<Result | Paginated<Result>, Data, ServiceParams, PatchData> {
find<P extends ServiceParams & {
paginate?: PaginationOptions | false;
}>(params?: P): Promise<PaginatedOrArray<Result, P>>;
get(id: Id, params?: ServiceParams): Promise<Result>;
create(data: Data, params?: ServiceParams): Promise<Result>;
create(data: Data[], params?: ServiceParams): Promise<Result[]>;
create(data: Data | Data[], params?: ServiceParams): Promise<Result | Result[]>;
update(id: Id, data: Data, params?: ServiceParams): Promise<Result>;
patch(id: Id, data: PatchData, params?: ServiceParams): Promise<Result>;
patch(id: null, data: PatchData, params?: ServiceParams): Promise<Result[]>;
remove(id: Id, params?: ServiceParams): Promise<Result>;
remove(id: null, params?: ServiceParams): Promise<Result[]>;
}
export declare function service<ModelData = Record<string, any>>(options: PrismaServiceOptions, client: PrismaClient): PrismaService<ModelData>;
export declare function service<ModelData = Record<string, any>>(options: PrismaServiceOptions, client: PrismaClient): PrismaService<ModelData, Partial<ModelData>, AdapterParams<import("@feathersjs/adapter-commons").AdapterQuery, Partial<import("@feathersjs/adapter-commons").AdapterServiceOptions>>, Partial<Partial<ModelData>>>;
export declare const prismaService: typeof service;
Loading