refactor source code

This commit is contained in:
2024-10-29 17:42:54 +07:00
parent 3b23d9e0b7
commit 152bb50da8
83 changed files with 8473 additions and 7577 deletions

View File

@@ -1,82 +1,82 @@
import { DateTimeResolver, JSONObjectResolver } from 'graphql-scalars';
import { DateTimeResolver, JSONObjectResolver } from 'graphql-scalars'
import PrismaPlugin, {
PothosPrismaDatamodel,
PrismaClient,
} from '@pothos/plugin-prisma';
import { Request, Response } from 'express';
} from '@pothos/plugin-prisma'
import { Request, Response } from 'express'
import SmartSubscriptionPlugin, {
subscribeOptionsFromIterator,
} from '@pothos/plugin-smart-subscriptions';
} from '@pothos/plugin-smart-subscriptions'
import AuthzPlugin from '@pothos/plugin-authz';
import ErrorsPlugin from '@pothos/plugin-errors';
import type { FileUpload } from 'graphql-upload/processRequest.js';
import GraphQLUpload from 'graphql-upload/GraphQLUpload.js';
import { Injectable } from '@nestjs/common';
import { PrismaCrudGenerator } from './graphql.generator';
import type PrismaTypes from '../types/pothos.generated';
import PrismaUtils from '@pothos/plugin-prisma-utils';
import { PubSub } from 'graphql-subscriptions';
import RelayPlugin from '@pothos/plugin-relay';
import SchemaBuilder from '@pothos/core';
import SimpleObjectPlugin from '@pothos/plugin-simple-objects';
import { User } from '@prisma/client';
import { getDatamodel } from '../types/pothos.generated';
import AuthzPlugin from '@pothos/plugin-authz'
import ErrorsPlugin from '@pothos/plugin-errors'
import type { FileUpload } from 'graphql-upload/processRequest.js'
import GraphQLUpload from 'graphql-upload/GraphQLUpload.js'
import { Injectable } from '@nestjs/common'
import { PrismaCrudGenerator } from './graphql.generator'
import type PrismaTypes from '../types/pothos.generated'
import PrismaUtils from '@pothos/plugin-prisma-utils'
import { PubSub } from 'graphql-subscriptions'
import RelayPlugin from '@pothos/plugin-relay'
import SchemaBuilder from '@pothos/core'
import SimpleObjectPlugin from '@pothos/plugin-simple-objects'
import { User } from '@prisma/client'
import { getDatamodel } from '../types/pothos.generated'
// import { rules } from '../common/graphql/common.graphql.auth-rule';
export type SchemaContext =
| {
isSubscription: true;
isSubscription: true
websocket: {
pubSub: PubSub;
me: User;
generator: PrismaCrudGenerator<BuilderTypes>;
};
pubSub: PubSub
me: User
generator: PrismaCrudGenerator<BuilderTypes>
}
}
| {
isSubscription: false;
isSubscription: false
http: {
req: Request;
res: Response;
me: User;
pubSub: PubSub;
generator: PrismaCrudGenerator<BuilderTypes>;
};
};
req: Request
res: Response
me: User
pubSub: PubSub
generator: PrismaCrudGenerator<BuilderTypes>
}
}
// extend prisma types to contain string type
export interface SchemaBuilderOption {
Context: SchemaContext;
PrismaTypes: PrismaTypes;
DataModel: PothosPrismaDatamodel;
Context: SchemaContext
PrismaTypes: PrismaTypes
DataModel: PothosPrismaDatamodel
Connection: {
totalCount: number | (() => number | Promise<number>);
};
totalCount: number | (() => number | Promise<number>)
}
// AuthZRule: keyof typeof rules;
Scalars: {
DateTime: {
Input: Date;
Output: Date;
};
Input: Date
Output: Date
}
Json: {
Input: JSON;
Output: JSON;
};
Input: JSON
Output: JSON
}
Upload: {
Input: FileUpload;
Output: FileUpload;
};
Input: FileUpload
Output: FileUpload
}
Int: {
Input: number;
Output: number | bigint | string;
};
};
Input: number
Output: number | bigint | string
}
}
}
@Injectable()
export class Builder extends SchemaBuilder<SchemaBuilderOption> {
public generator: PrismaCrudGenerator<BuilderTypes>;
public generator: PrismaCrudGenerator<BuilderTypes>
constructor(private readonly prisma: PrismaClient) {
super({
@@ -93,9 +93,9 @@ export class Builder extends SchemaBuilder<SchemaBuilderOption> {
debounceDelay: 1000,
...subscribeOptionsFromIterator((name, ctx) => {
if (ctx.isSubscription) {
return ctx.websocket.pubSub.asyncIterator(name);
return ctx.websocket.pubSub.asyncIterator(name)
}
return ctx.http.pubSub.asyncIterator(name);
return ctx.http.pubSub.asyncIterator(name)
}),
},
relay: {},
@@ -109,15 +109,15 @@ export class Builder extends SchemaBuilder<SchemaBuilderOption> {
errors: {
defaultTypes: [],
},
});
this.generator = new PrismaCrudGenerator<BuilderTypes>(this);
this.addScalarType('DateTime', DateTimeResolver);
this.addScalarType('Json', JSONObjectResolver);
this.addScalarType('Upload', GraphQLUpload);
})
this.generator = new PrismaCrudGenerator<BuilderTypes>(this)
this.addScalarType('DateTime', DateTimeResolver)
this.addScalarType('Json', JSONObjectResolver)
this.addScalarType('Upload', GraphQLUpload)
this.queryType({});
this.mutationType({});
this.subscriptionType({});
this.queryType({})
this.mutationType({})
this.subscriptionType({})
this.globalConnectionField('totalCount', (t) =>
t.int({
@@ -127,10 +127,10 @@ export class Builder extends SchemaBuilder<SchemaBuilderOption> {
? parent.totalCount()
: parent.totalCount,
}),
);
)
// test print ManagedServiceWhereUniqueInput
}
}
export type BuilderTypes =
PothosSchemaTypes.ExtendDefaultTypes<SchemaBuilderOption>;
PothosSchemaTypes.ExtendDefaultTypes<SchemaBuilderOption>

View File

@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common'
import {
type BaseEnum,
@@ -7,14 +7,14 @@ import {
type InputType,
type InputTypeParam,
type SchemaTypes,
} from '@pothos/core';
import { type PrismaModelTypes, getModel } from '@pothos/plugin-prisma';
import type { FilterOps } from '@pothos/plugin-prisma-utils';
import * as Prisma from '@prisma/client';
import { SchemaBuilderToken } from '@smatch-corp/nestjs-pothos';
} from '@pothos/core'
import { type PrismaModelTypes, getModel } from '@pothos/plugin-prisma'
import type { FilterOps } from '@pothos/plugin-prisma-utils'
import * as Prisma from '@prisma/client'
import { SchemaBuilderToken } from '@smatch-corp/nestjs-pothos'
const filterOps = ['equals', 'in', 'notIn', 'not'] as const;
const sortableFilterProps = ['lt', 'lte', 'gt', 'gte'] as const;
const filterOps = ['equals', 'in', 'notIn', 'not'] as const
const sortableFilterProps = ['lt', 'lte', 'gt', 'gte'] as const
const stringFilterOps = [
...filterOps,
'contains',
@@ -22,29 +22,29 @@ const stringFilterOps = [
'endsWith',
'mode',
'search',
] as const;
const sortableTypes = ['String', 'Int', 'Float', 'DateTime', 'BigInt'] as const;
const listOps = ['every', 'some', 'none'] as const;
] as const
const sortableTypes = ['String', 'Int', 'Float', 'DateTime', 'BigInt'] as const
const listOps = ['every', 'some', 'none'] as const
const scalarListOps = [
'has',
'hasSome',
'hasEvery',
'isEmpty',
'equals',
] as const;
const JsonFilterOps = ['equals', 'in', 'notIn', 'not'] as const;
const EnumFilterOps = ['equals', 'not'] as const;
] as const
const JsonFilterOps = ['equals', 'in', 'notIn', 'not'] as const
const EnumFilterOps = ['equals', 'not'] as const
@Injectable()
export class PrismaCrudGenerator<Types extends SchemaTypes> {
private refCache = new Map<
InputType<Types> | string,
Map<string, InputObjectRef<Types, unknown>>
>();
>()
private enumRefs = new Map<string, EnumRef<Types, unknown>>();
private enumRefs = new Map<string, EnumRef<Types, unknown>>()
constructor(
//
//
@Inject(SchemaBuilderToken)
private builder: PothosSchemaTypes.SchemaBuilder<Types>,
) {}
@@ -75,7 +75,7 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
type: 'Int',
required: false,
}),
}));
}))
}
findUniqueArgs<Name extends string & keyof Types['PrismaTypes']>(
@@ -86,7 +86,7 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
type: this.getWhereUnique(modelName),
required: true,
}),
}));
}))
}
getWhere<Name extends string & keyof Types['PrismaTypes']>(
@@ -95,19 +95,19 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
) {
const withoutName = (without ?? [])
.map((name) => `Without${capitalize(name)}`)
.join('');
const fullName = `${modelName}${withoutName}Filter`;
.join('')
const fullName = `${modelName}${withoutName}Filter`
return this.getRef(modelName, fullName, () => {
const model = getModel(modelName, this.builder);
const model = getModel(modelName, this.builder)
return this.builder.prismaWhere(modelName, {
name: fullName,
fields: (() => {
const fields: Record<string, InputType<Types>> = {};
const fields: Record<string, InputType<Types>> = {}
const withoutFields = model.fields.filter((field) =>
without?.includes(field.name),
);
)
model.fields
.filter(
@@ -119,7 +119,7 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
),
)
.forEach((field) => {
let type;
let type
switch (field.kind) {
case 'scalar':
type = field.isList
@@ -128,49 +128,49 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
)
: this.getFilter(
this.mapScalarType(field.type) as InputType<Types>,
);
break;
)
break
case 'enum':
type = field.isList
? this.getScalarListFilter(this.getEnum(field.type))
: this.getFilter(this.getEnum(field.type));
break;
: this.getFilter(this.getEnum(field.type))
break
case 'object':
type = field.isList
? this.getListFilter(this.getWhere(field.type as Name))
: this.getWhere(field.type as Name);
break;
: this.getWhere(field.type as Name)
break
case 'unsupported':
break;
break
default:
throw new Error(`Unknown field kind ${field.kind}`);
throw new Error(`Unknown field kind ${field.kind}`)
}
if (!type) {
return;
return
}
fields[field.name] = type;
});
fields[field.name] = type
})
return fields;
return fields
}) as never,
}) as InputObjectRef<
Types,
(PrismaModelTypes & Types['PrismaTypes'][Name])['Where']
>;
});
>
})
}
getWhereUnique<Name extends string & keyof Types['PrismaTypes']>(
modelName: Name,
) {
const name = `${modelName}UniqueFilter`;
const name = `${modelName}UniqueFilter`
return this.getRef(modelName, name, () => {
const model = getModel(modelName, this.builder);
const model = getModel(modelName, this.builder)
return this.builder.prismaWhereUnique(modelName, {
name,
fields: (() => {
const fields: Record<string, InputType<Types>> = {};
const fields: Record<string, InputType<Types>> = {}
model.fields
.filter(
@@ -183,73 +183,73 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
model.primaryKey?.fields.includes(field.name),
)
.forEach((field) => {
let type;
let type
switch (field.kind) {
case 'scalar':
type = this.mapScalarType(field.type) as InputType<Types>;
break;
type = this.mapScalarType(field.type) as InputType<Types>
break
case 'enum':
type = this.getEnum(field.type);
break;
type = this.getEnum(field.type)
break
case 'object':
case 'unsupported':
break;
break
default:
throw new Error(`Unknown field kind ${field.kind}`);
throw new Error(`Unknown field kind ${field.kind}`)
}
if (!type) {
return;
return
}
fields[field.name] = type;
});
fields[field.name] = type
})
return fields;
return fields
}) as never,
}) as InputObjectRef<
Types,
(PrismaModelTypes & Types['PrismaTypes'][Name])['WhereUnique']
>;
});
>
})
}
getOrderBy<Name extends string & keyof Types['PrismaTypes']>(
modelName: Name,
) {
const name = `${modelName}OrderBy`;
const name = `${modelName}OrderBy`
return this.getRef(modelName, name, () => {
const model = getModel(modelName, this.builder);
const model = getModel(modelName, this.builder)
return this.builder.prismaOrderBy(modelName, {
name,
fields: () => {
const fields: Record<string, InputType<Types> | boolean> = {};
const fields: Record<string, InputType<Types> | boolean> = {}
model.fields.forEach((field) => {
let type;
let type
switch (field.kind) {
case 'scalar':
case 'enum':
type = true;
break;
type = true
break
case 'object':
type = this.getOrderBy(field.type as Name);
break;
type = this.getOrderBy(field.type as Name)
break
case 'unsupported':
break;
break
default:
throw new Error(`Unknown field kind ${field.kind}`);
throw new Error(`Unknown field kind ${field.kind}`)
}
if (type) {
fields[field.name] = type;
fields[field.name] = type
}
});
})
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
return fields as {};
return fields as {}
},
});
});
})
})
}
getCreateInput<Name extends string & keyof Types['PrismaTypes']>(
@@ -258,21 +258,21 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
) {
const withoutName = (without ?? [])
.map((name) => `Without${capitalize(name)}`)
.join('');
const fullName = `${modelName}Create${withoutName}Input`;
.join('')
const fullName = `${modelName}Create${withoutName}Input`
return this.getRef(modelName, fullName, () => {
const model = getModel(modelName, this.builder);
const model = getModel(modelName, this.builder)
return this.builder.prismaCreate(modelName, {
name: fullName,
fields: (() => {
const fields: Record<string, InputTypeParam<Types>> = {};
const fields: Record<string, InputTypeParam<Types>> = {}
const withoutFields = model.fields.filter((field) =>
without?.includes(field.name),
);
)
const relationIds = model.fields.flatMap(
(field) => field.relationFromFields ?? [],
);
)
model.fields
.filter(
@@ -284,35 +284,35 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
) && !relationIds.includes(field.name),
)
.forEach((field) => {
let type;
let type
switch (field.kind) {
case 'scalar':
type = this.mapScalarType(field.type) as InputType<Types>;
break;
type = this.mapScalarType(field.type) as InputType<Types>
break
case 'enum':
type = this.getEnum(field.type);
break;
type = this.getEnum(field.type)
break
case 'object':
type = this.getCreateRelationInput(modelName, field.name);
break;
type = this.getCreateRelationInput(modelName, field.name)
break
case 'unsupported':
break;
break
default:
throw new Error(`Unknown field kind ${field.kind}`);
throw new Error(`Unknown field kind ${field.kind}`)
}
if (type) {
fields[field.name] = type;
fields[field.name] = type
}
});
})
return fields;
return fields
}) as never,
}) as InputObjectRef<
Types,
(PrismaModelTypes & Types['PrismaTypes'][Name])['Create']
>;
});
>
})
}
getCreateRelationInput<
@@ -327,30 +327,30 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
`${modelName}${capitalize(relation)}`,
'CreateRelationInput',
() => {
const model = getModel(modelName, this.builder);
const model = getModel(modelName, this.builder)
return this.builder.prismaCreateRelation(modelName, relation, {
fields: () => {
const relationField = model.fields.find(
(field) => field.name === relation,
)!;
const relatedModel = getModel(relationField.type, this.builder);
)!
const relatedModel = getModel(relationField.type, this.builder)
const relatedFieldName = relatedModel.fields.find(
(field) => field.relationName === relationField.relationName,
)!;
)!
return {
create: this.getCreateInput(relationField.type as Name, [
relatedFieldName.name,
]),
connect: this.getWhereUnique(relationField.type as Name),
};
}
},
} as never) as InputObjectRef<
Types,
NonNullable<Model['Create'][Relation & keyof Model['Update']]>
>;
>
},
);
)
}
getCreateManyInput<Name extends string & keyof Types['PrismaTypes']>(
@@ -359,22 +359,22 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
) {
const withoutName = (without ?? [])
.map((name) => `Without${capitalize(name)}`)
.join('');
const fullName = `${modelName}Create${withoutName}Input`;
.join('')
const fullName = `${modelName}Create${withoutName}Input`
return this.getRef(modelName, fullName, () => {
const model = getModel(modelName, this.builder);
const model = getModel(modelName, this.builder)
return this.builder.prismaCreateMany(modelName, {
name: fullName,
fields: (() => {
const fields: Record<string, InputTypeParam<Types>> = {};
const fields: Record<string, InputTypeParam<Types>> = {}
const withoutFields = model.fields.filter((field) =>
without?.includes(field.name),
);
)
const relationIds = model.fields.flatMap(
(field) => field.relationFromFields ?? [],
);
)
model.fields
.filter(
@@ -386,32 +386,32 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
) && !relationIds.includes(field.name),
)
.forEach((field) => {
let type;
let type
switch (field.kind) {
case 'scalar':
type = this.mapScalarType(field.type) as InputType<Types>;
break;
type = this.mapScalarType(field.type) as InputType<Types>
break
case 'enum':
type = this.getEnum(field.type);
break;
type = this.getEnum(field.type)
break
case 'unsupported':
break;
break
default:
throw new Error(`Unknown field kind ${field.kind}`);
throw new Error(`Unknown field kind ${field.kind}`)
}
if (type) {
fields[field.name] = type;
fields[field.name] = type
}
});
})
return fields;
return fields
}) as never,
}) as InputObjectRef<
Types,
(PrismaModelTypes & Types['PrismaTypes'][Name])['Create']
>;
});
>
})
}
getUpdateInput<Name extends string & keyof Types['PrismaTypes']>(
@@ -420,21 +420,21 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
) {
const withoutName = (without ?? [])
.map((name) => `Without${capitalize(name)}`)
.join('');
const fullName = `${modelName}Update${withoutName}Input`;
.join('')
const fullName = `${modelName}Update${withoutName}Input`
return this.getRef(modelName, fullName, () => {
const model = getModel(modelName, this.builder);
const model = getModel(modelName, this.builder)
return this.builder.prismaUpdate(modelName, {
name: fullName,
fields: (() => {
const fields: Record<string, InputTypeParam<Types>> = {};
const fields: Record<string, InputTypeParam<Types>> = {}
const withoutFields = model.fields.filter((field) =>
without?.includes(field.name),
);
)
const relationIds = model.fields.flatMap(
(field) => field.relationFromFields ?? [],
);
)
model.fields
.filter(
@@ -446,35 +446,35 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
) && !relationIds.includes(field.name),
)
.forEach((field) => {
let type;
let type
switch (field.kind) {
case 'scalar':
type = this.mapScalarType(field.type) as InputType<Types>;
break;
type = this.mapScalarType(field.type) as InputType<Types>
break
case 'enum':
type = this.getEnum(field.type);
break;
type = this.getEnum(field.type)
break
case 'object':
type = this.getUpdateRelationInput(modelName, field.name);
break;
type = this.getUpdateRelationInput(modelName, field.name)
break
case 'unsupported':
break;
break
default:
throw new Error(`Unknown field kind ${field.kind}`);
throw new Error(`Unknown field kind ${field.kind}`)
}
if (type) {
fields[field.name] = type;
fields[field.name] = type
}
});
})
return fields;
return fields
}) as never,
}) as InputObjectRef<
Types,
(PrismaModelTypes & Types['PrismaTypes'][Name])['Update']
>;
});
>
})
}
getUpdateRelationInput<
Name extends string & keyof Types['PrismaTypes'],
@@ -488,16 +488,16 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
`${modelName}${capitalize(relation)}`,
'UpdateRelationInput',
() => {
const model = getModel(modelName, this.builder);
const model = getModel(modelName, this.builder)
return this.builder.prismaUpdateRelation(modelName, relation, {
fields: () => {
const relationField = model.fields.find(
(field) => field.name === relation,
)!;
const relatedModel = getModel(relationField.type, this.builder);
)!
const relatedModel = getModel(relationField.type, this.builder)
const relatedFieldName = relatedModel.fields.find(
(field) => field.relationName === relationField.relationName,
)!.name;
)!.name
if (relationField.isList) {
return {
@@ -531,7 +531,7 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
deleteMany: this.getWhere(relationField.type as Name, [
relatedFieldName,
]),
};
}
}
return {
@@ -544,38 +544,38 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
connect: this.getWhereUnique(relationField.type as Name),
disconnect: relationField.isRequired ? undefined : 'Boolean',
delete: relationField.isRequired ? undefined : 'Boolean',
};
}
},
} as never) as InputObjectRef<
Types,
NonNullable<Model['Update'][Relation & keyof Model['Update']]>
>;
>
},
);
)
}
private getFilter(type: InputType<Types>) {
return this.getRef(type, `${String(type)}Filter`, () => {
const ops: FilterOps[] = [...filterOps];
const ops: FilterOps[] = [...filterOps]
if (type === 'String') {
ops.push(...stringFilterOps);
ops.push(...stringFilterOps)
}
if (sortableTypes.includes(type as never)) {
ops.push(...sortableFilterProps);
ops.push(...sortableFilterProps)
}
if (type === 'Json') {
ops.push(...JsonFilterOps);
ops.push(...JsonFilterOps)
}
// type enum
if (type === 'Enum') {
ops.push(...EnumFilterOps);
ops.push(...EnumFilterOps)
}
return this.builder.prismaFilter(type, {
ops,
});
});
})
})
}
private getScalarListFilter(type: InputType<Types>) {
@@ -583,7 +583,7 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
this.builder.prismaScalarListFilter(type, {
ops: scalarListOps,
}),
);
)
}
private getListFilter(type: InputType<Types>) {
@@ -591,7 +591,7 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
this.builder.prismaListFilter(type, {
ops: listOps,
}),
);
)
}
private getEnum(name: string) {
@@ -601,12 +601,12 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
{
name,
},
);
)
this.enumRefs.set(name, enumRef);
this.enumRefs.set(name, enumRef)
}
return this.enumRefs.get(name)!;
return this.enumRefs.get(name)!
}
private mapScalarType(type: string) {
@@ -617,9 +617,9 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
case 'Float':
case 'DateTime':
case 'Json':
return type;
return type
default:
return null;
return null
}
}
@@ -629,24 +629,24 @@ export class PrismaCrudGenerator<Types extends SchemaTypes> {
create: () => T,
): T {
if (!this.refCache.has(key)) {
this.refCache.set(key, new Map());
this.refCache.set(key, new Map())
}
const cache = this.refCache.get(key)!;
const cache = this.refCache.get(key)!
if (cache.has(name)) {
return cache.get(name)! as T;
return cache.get(name)! as T
}
const ref = new InputObjectRef<Types, unknown>(name);
const ref = new InputObjectRef<Types, unknown>(name)
cache.set(name, ref);
cache.set(name, ref)
this.builder.configStore.associateParamWithRef(ref, create());
this.builder.configStore.associateParamWithRef(ref, create())
return ref as T;
return ref as T
}
}
function capitalize(str: string) {
return str[0].toUpperCase() + str.slice(1);
return str[0].toUpperCase() + str.slice(1)
}

View File

@@ -1,44 +1,44 @@
import { Global, Module } from '@nestjs/common';
import { Global, Module } from '@nestjs/common'
import { AdminNoteModule } from '../AdminNote/adminnote.module';
import { ApolloDriverConfig } from '@nestjs/apollo';
import { AppConfigModule } from '../AppConfig/appconfig.module';
import { Builder } from './graphql.builder';
import { CategoryModule } from '../Category/category.module';
import { CenterMentorModule } from '../CenterMentor/centermentor.module';
import { CenterModule } from '../Center/center.module';
import { ChatroomModule } from '../ChatRoom/chatroom.module';
import { CommonModule } from '../common/common.module';
import { ConfigModule } from '@nestjs/config';
import { GraphQLModule } from '@nestjs/graphql';
import { GraphqlService } from './graphql.service';
import { ManagedServiceModule } from '../ManagedService/managedservice.module';
import { MessageModule } from '../Message/message.module';
import { MilestoneModule } from '../Milestone/milestone.module';
import { OrderModule } from '../Order/order.module';
import { PaymentModule } from '../Payment/payment.module';
import { PothosApolloDriver } from '@smatch-corp/nestjs-pothos-apollo-driver';
import { PothosModule } from '@smatch-corp/nestjs-pothos';
import { PrismaCrudGenerator } from './graphql.generator';
import { PrismaModule } from '../Prisma/prisma.module';
import { PrismaService } from '../Prisma/prisma.service';
import { RedisModule } from 'src/Redis/redis.module';
import { RedisService } from 'src/Redis/redis.service';
import { RefundTicketModule } from '../RefundTicket/refundticket.module';
import { Request } from 'express';
import { ResumeModule } from '../Resume/resume.module';
import { ScheduleModule } from '../Schedule/schedule.module';
import { ServiceAndCategoryModule } from '../ServiceAndCategory/serviceandcategory.module';
import { ServiceFeedbackModule } from '../ServiceFeedback/servicefeedback.module';
import { ServiceMeetingRoomModule } from '../ServiceMeetingRoom/servicemeetingroom.module';
import { ServiceModule } from '../Service/service.module';
import { UploadedFileModule } from '../UploadedFile/uploadedfile.module';
import { UserModule } from '../User/user.module';
import { WorkshopMeetingRoomModule } from '../WorkshopMeetingRoom/workshopmeetingroom.module';
import { WorkshopModule } from '../Workshop/workshop.module';
import { WorkshopOrganizationModule } from '../WorkshopOrganization/workshoporganization.module';
import { WorkshopSubscriptionModule } from '../WorkshopSubscription/workshopsubscription.module';
import { initContextCache } from '@pothos/core';
import { AdminNoteModule } from '../AdminNote/adminnote.module'
import { ApolloDriverConfig } from '@nestjs/apollo'
import { AppConfigModule } from '../AppConfig/appconfig.module'
import { Builder } from './graphql.builder'
import { CategoryModule } from '../Category/category.module'
import { CenterMentorModule } from '../CenterMentor/centermentor.module'
import { CenterModule } from '../Center/center.module'
import { ChatroomModule } from '../ChatRoom/chatroom.module'
import { CommonModule } from '../common/common.module'
import { ConfigModule } from '@nestjs/config'
import { GraphQLModule } from '@nestjs/graphql'
import { GraphqlService } from './graphql.service'
import { ManagedServiceModule } from '../ManagedService/managedservice.module'
import { MessageModule } from '../Message/message.module'
import { MilestoneModule } from '../Milestone/milestone.module'
import { OrderModule } from '../Order/order.module'
import { PaymentModule } from '../Payment/payment.module'
import { PothosApolloDriver } from '@smatch-corp/nestjs-pothos-apollo-driver'
import { PothosModule } from '@smatch-corp/nestjs-pothos'
import { PrismaCrudGenerator } from './graphql.generator'
import { PrismaModule } from '../Prisma/prisma.module'
import { PrismaService } from '../Prisma/prisma.service'
import { RedisModule } from 'src/Redis/redis.module'
import { RedisService } from 'src/Redis/redis.service'
import { RefundTicketModule } from '../RefundTicket/refundticket.module'
import { Request } from 'express'
import { ResumeModule } from '../Resume/resume.module'
import { ScheduleModule } from '../Schedule/schedule.module'
import { ServiceAndCategoryModule } from '../ServiceAndCategory/serviceandcategory.module'
import { ServiceFeedbackModule } from '../ServiceFeedback/servicefeedback.module'
import { ServiceMeetingRoomModule } from '../ServiceMeetingRoom/servicemeetingroom.module'
import { ServiceModule } from '../Service/service.module'
import { UploadedFileModule } from '../UploadedFile/uploadedfile.module'
import { UserModule } from '../User/user.module'
import { WorkshopMeetingRoomModule } from '../WorkshopMeetingRoom/workshopmeetingroom.module'
import { WorkshopModule } from '../Workshop/workshop.module'
import { WorkshopOrganizationModule } from '../WorkshopOrganization/workshoporganization.module'
import { WorkshopSubscriptionModule } from '../WorkshopSubscription/workshopsubscription.module'
import { initContextCache } from '@pothos/core'
@Global()
@Module({

View File

@@ -3,13 +3,13 @@ import {
Injectable,
Logger,
UnauthorizedException,
} from '@nestjs/common';
} from '@nestjs/common'
import { PrismaService } from '../Prisma/prisma.service';
import { Request } from 'express';
import { clerkClient } from '@clerk/express';
import { PrismaService } from '../Prisma/prisma.service'
import { Request } from 'express'
import { clerkClient } from '@clerk/express'
import { RedisService } from '../Redis/redis.service';
import { RedisService } from '../Redis/redis.service'
@Injectable()
export class GraphqlService {
@@ -20,37 +20,37 @@ export class GraphqlService {
async acquireContext(req: Request) {
// get x-session-id from headers
let sessionId: string;
const disableAuth = process.env.DISABLE_AUTH === 'true';
let sessionId: string
const disableAuth = process.env.DISABLE_AUTH === 'true'
try {
sessionId = req.headers['x-session-id'] as string;
sessionId = req.headers['x-session-id'] as string
} catch (error) {
Logger.error('Error acquiring context', error);
Logger.error('Error acquiring context', error)
if (disableAuth) {
return null;
return null
}
throw new UnauthorizedException('Must provide a session ID');
throw new UnauthorizedException('Must provide a session ID')
}
if (disableAuth) {
return null;
return null
}
// redis context cache
const cachedUser = await this.redis.getUser(sessionId);
const cachedUser = await this.redis.getUser(sessionId)
if (cachedUser) {
return cachedUser;
return cachedUser
}
// check if the token is valid
const session = await clerkClient.sessions.getSession(sessionId as string);
const session = await clerkClient.sessions.getSession(sessionId as string)
if (!session) {
throw new UnauthorizedException('Invalid session');
throw new UnauthorizedException('Invalid session')
}
const user = await this.prisma.user.findUnique({
where: { id: session.userId },
});
})
if (!user) {
throw new UnauthorizedException('User not found');
throw new UnauthorizedException('User not found')
}
await this.redis.setUser(sessionId, user, session.expireAt);
return user;
await this.redis.setUser(sessionId, user, session.expireAt)
return user
}
}

File diff suppressed because it is too large Load Diff