@algochad/prisma-core
Version:
A comprehensive NestJS library that provides EF-Core-like operations using Prisma and GraphQL. Features LINQ-style query builders, advanced data manipulation, GraphQL integration with genql, and a unified API for both Prisma and GraphQL operations. Includ
265 lines • 8.57 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GraphQLQueryBuilder = void 0;
const collections_1 = require("../../collections");
const graphql_queryable_1 = require("../../collections/graphql/graphql-queryable");
class GraphQLQueryBuilder {
genqlClient;
operationName;
operationType;
whereClause = {};
selectClause;
includeClause;
orderByClause;
firstClause;
skipClause;
argsClause = {};
constructor(genqlClient, operationName, operationType = 'query') {
this.genqlClient = genqlClient;
this.operationName = operationName;
this.operationType = operationType;
}
static create(genqlClient, operationName, operationType = 'query') {
return new GraphQLQueryBuilder(genqlClient, operationName, operationType);
}
static createFrom(builder, genqlClient, operationName) {
return new GraphQLQueryBuilder(genqlClient, operationName, builder.operationType);
}
Where(where) {
this.whereClause = { ...this.whereClause, ...where };
return this;
}
Select(select) {
this.selectClause = select;
return this;
}
Include(include) {
this.includeClause = include;
return this;
}
OrderBy(orderBy) {
this.orderByClause = Array.isArray(orderBy) ? orderBy : [orderBy];
return this;
}
Take(n) {
this.firstClause = n;
return this;
}
Skip(n) {
this.skipClause = n;
return this;
}
buildQuery() {
const query = {};
const operationQuery = {};
const args = {};
if (this.whereClause && Object.keys(this.whereClause).length > 0) {
args.where = this.whereClause;
}
if (this.firstClause !== undefined) {
args.take = this.firstClause;
}
if (this.skipClause !== undefined) {
args.skip = this.skipClause;
}
if (this.orderByClause) {
args.orderBy = this.orderByClause[0];
}
if (Object.keys(args).length > 0) {
operationQuery.__args = args;
}
if (this.selectClause) {
Object.assign(operationQuery, this.selectClause);
}
if (this.includeClause) {
Object.assign(operationQuery, this.includeClause);
}
if (!this.selectClause && !this.includeClause) {
operationQuery.id = true;
}
query[this.operationName] = operationQuery;
return query;
}
async ToArray() {
const query = this.buildQuery();
let result;
switch (this.operationType) {
case 'mutation':
if (!this.genqlClient.mutation) {
throw new Error('Mutation not supported by this GraphQL client');
}
result = await this.genqlClient.mutation(query);
break;
case 'subscription':
if (!this.genqlClient.subscription) {
throw new Error('Subscription not supported by this GraphQL client');
}
const subscription = this.genqlClient.subscription(query);
const { value } = await subscription.next();
result = value;
break;
default:
result = await this.genqlClient.query(query);
}
const data = result[this.operationName];
return Array.isArray(data) ? data : [data].filter(Boolean);
}
async ToArrayAsync() {
return await this.ToArray();
}
async First() {
const originalFirst = this.firstClause;
this.firstClause = 1;
try {
const results = await this.ToArray();
return results.length > 0 ? results[0] : null;
}
finally {
this.firstClause = originalFirst;
}
}
async FirstOrDefault() {
const result = await this.First();
return result ?? undefined;
}
async Single() {
const results = await this.ToArray();
if (results.length === 0) {
return null;
}
if (results.length > 1) {
throw new Error('More than one element found');
}
return results[0];
}
async Count() {
const results = await this.ToArray();
return results.length;
}
async Exists() {
const originalFirst = this.firstClause;
this.firstClause = 1;
try {
const results = await this.ToArray();
return results.length > 0;
}
finally {
this.firstClause = originalFirst;
}
}
async Any() {
return this.Exists();
}
async Min(field) {
const results = await this.ToArray();
if (results.length === 0) {
return null;
}
return results.reduce((min, current) => {
const value = current[field];
return value < min ? value : min;
}, results[0][field]);
}
async Max(field) {
const results = await this.ToArray();
if (results.length === 0) {
return null;
}
return results.reduce((max, current) => {
const value = current[field];
return value > max ? value : max;
}, results[0][field]);
}
async Sum(field) {
const results = await this.ToArray();
return results.reduce((sum, current) => {
const value = current[field];
return sum + (typeof value === 'number' ? value : 0);
}, 0);
}
async Avg(field) {
const results = await this.ToArray();
if (results.length === 0) {
return 0;
}
const sum = await this.Sum(field);
return sum / results.length;
}
async ToEnumerable() {
const results = await this.ToArray();
return new collections_1.Enumerable(results);
}
async Project(selector) {
const results = await this.ToArray();
const projected = results.map(selector);
return new collections_1.Enumerable(projected);
}
get Provider() {
return new graphql_queryable_1.GraphQLQueryProvider(this.genqlClient, this.operationName, this.operationType);
}
get Expression() {
return {
where: this.whereClause,
select: this.selectClause,
orderBy: this.orderByClause ? [this.orderByClause] : undefined,
first: this.firstClause,
skip: this.skipClause,
operationType: this.operationType,
operationName: this.operationName,
};
}
AsQueryable() {
const provider = this.Provider;
const expression = this.Expression;
return new graphql_queryable_1.GraphQLQueryable(provider, expression);
}
reset() {
this.whereClause = {};
this.selectClause = undefined;
this.includeClause = undefined;
this.orderByClause = undefined;
this.firstClause = undefined;
this.skipClause = undefined;
this.argsClause = {};
return this;
}
Fresh() {
return new GraphQLQueryBuilder(this.genqlClient, this.operationName, this.operationType);
}
async *Subscribe() {
if (this.operationType !== 'subscription') {
throw new Error('Subscribe() can only be called on subscription operations');
}
if (!this.genqlClient.subscription) {
throw new Error('Subscription not supported by this GraphQL client');
}
const query = this.buildQuery();
const subscription = this.genqlClient.subscription(query);
for await (const result of subscription) {
const data = result[this.operationName];
if (data) {
if (Array.isArray(data)) {
for (const item of data) {
yield item;
}
}
else {
yield data;
}
}
}
}
AsAsyncEnumerable() {
return collections_1.AsyncEnumerable.from(async function* () {
const results = await this.ToArray();
for (const item of results) {
yield item;
}
}.bind(this));
}
ToAsyncEnumerable() {
return this.AsAsyncEnumerable();
}
}
exports.GraphQLQueryBuilder = GraphQLQueryBuilder;
//# sourceMappingURL=graphql-query-builder.js.map