Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Basic Crud #33

Merged
merged 6 commits into from
Sep 5, 2024
Merged
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
3 changes: 2 additions & 1 deletion src/bundles/bundles.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { DampLabServicesModule } from '../services/damplab-services.module';
import { Bundle, BundleSchema } from './bundles.model';
import { BundlesResolver } from './bundles.resolver';
import { BundlesService } from './bundles.service';
import { BundleUpdatePipe } from './update.pipe';

@Module({
imports: [MongooseModule.forFeature([{ name: Bundle.name, schema: BundleSchema }]), DampLabServicesModule],
providers: [BundlesService, BundlesResolver]
providers: [BundlesService, BundlesResolver, BundleUpdatePipe]
})
export class BundlesModule {}
17 changes: 17 additions & 0 deletions src/bundles/bundles.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Injectable, NotFoundException, PipeTransform } from '@nestjs/common';
import { Bundle } from './bundles.model';
import { BundlesService } from './bundles.service';

@Injectable()
export class BundlesPipe implements PipeTransform<string, Promise<Bundle>> {
constructor(private readonly bundleService: BundlesService) {}

async transform(value: string): Promise<Bundle> {
const bundle = await this.bundleService.find(value);

if (!bundle) {
throw new NotFoundException(`Bundle with id ${value} not found`);
}

Check warning on line 14 in src/bundles/bundles.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 14 in src/bundles/bundles.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
return bundle;
}
}

Check warning on line 17 in src/bundles/bundles.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 17 in src/bundles/bundles.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
10 changes: 9 additions & 1 deletion src/bundles/bundles.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
import { Parent, Query, ResolveField, Resolver } from '@nestjs/graphql';
import { Parent, Query, ResolveField, Resolver, Args, Mutation, ID } from '@nestjs/graphql';
import { DampLabServices } from '../services/damplab-services.services';
import { DampLabService } from '../services/models/damplab-service.model';
import { Bundle } from './bundles.model';
import { BundlesService } from './bundles.service';
import { BundlesPipe } from './bundles.pipe';
import { BundleChange } from './dtos/update.dto';
import { BundleUpdatePipe } from './update.pipe';

@Resolver(() => Bundle)
export class BundlesResolver {
constructor(private readonly bundlesService: BundlesService, private readonly dampLabServices: DampLabServices) {}

@Query(() => [Bundle])
async bundles(): Promise<Bundle[]> {
return this.bundlesService.findAll();
}

@Mutation(() => Bundle)
async updateBundle(@Args('bundle', { type: () => ID }, BundlesPipe) bundle: Bundle, @Args('changes', { type: () => BundleChange }, BundleUpdatePipe) changes: BundleChange): Promise<Bundle> {

Check warning on line 20 in src/bundles/bundles.resolver.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 20 in src/bundles/bundles.resolver.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 20 in src/bundles/bundles.resolver.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function

Check warning on line 20 in src/bundles/bundles.resolver.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function

Check warning on line 20 in src/bundles/bundles.resolver.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function
return this.bundlesService.update(bundle, changes);
}

Check warning on line 22 in src/bundles/bundles.resolver.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

@ResolveField()
async services(@Parent() bundle: Bundle): Promise<DampLabService[]> {
return this.dampLabServices.findByIds(bundle.services);
Expand Down
10 changes: 10 additions & 0 deletions src/bundles/bundles.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,22 @@
import { InjectModel } from '@nestjs/mongoose';
import { Bundle } from './bundles.model';
import { Model } from 'mongoose';
import { BundleChange } from './dtos/update.dto';

@Injectable()
export class BundlesService {
constructor(@InjectModel(Bundle.name) private readonly bundleModel: Model<Bundle>) {}

async find(id: string): Promise<Bundle | null> {

Check warning on line 11 in src/bundles/bundles.service.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function
return this.bundleModel.findById(id);

Check warning on line 12 in src/bundles/bundles.service.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
}

async findAll(): Promise<Bundle[]> {
return this.bundleModel.find().exec();
}

async update(bundle: Bundle, changes: BundleChange): Promise<Bundle> {

Check warning on line 19 in src/bundles/bundles.service.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function
await this.bundleModel.updateOne({ _id: bundle.id }, changes);

Check warning on line 20 in src/bundles/bundles.service.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
return (await this.find(bundle.id))!;

Check warning on line 21 in src/bundles/bundles.service.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
}
}

Check warning on line 23 in src/bundles/bundles.service.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 23 in src/bundles/bundles.service.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
8 changes: 8 additions & 0 deletions src/bundles/dtos/update.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Bundle } from '../bundles.model';
import { ID, InputType, OmitType, PartialType, Field } from '@nestjs/graphql';

@InputType()
export class BundleChange extends PartialType(OmitType(Bundle, ['id', 'services'] as const), InputType) {
@Field(() => [ID], { nullable: true })
services: string[];
}
17 changes: 17 additions & 0 deletions src/bundles/update.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Injectable, PipeTransform } from '@nestjs/common';
import { DampLabServicePipe } from '../services/damplab-services.pipe';

Check warning on line 2 in src/bundles/update.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
import { BundleChange } from './dtos/update.dto';

@Injectable()
export class BundleUpdatePipe implements PipeTransform<BundleChange, Promise<BundleChange>> {
constructor(private readonly damplabServicePipe: DampLabServicePipe) {}

async transform(value: BundleChange): Promise<BundleChange> {
// If services is includes, make sure they are all valid
if (value.services) {
await Promise.all(value.services.map((service) => this.damplabServicePipe.transform(service)));
}

return value;
}
}
4 changes: 3 additions & 1 deletion src/categories/categories.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import { Category, CategorySchema } from './category.model';
import { CategoryService } from './categories.service';
import { CategoryResolver } from './categories.resolver';
import { DampLabServicesModule } from '../services/damplab-services.module';
import { CategoryPipe } from './categories.pipe';
import { CategoryUpdatePipe } from './update.pipe';

@Module({
imports: [MongooseModule.forFeature([{ name: Category.name, schema: CategorySchema }]), DampLabServicesModule],
providers: [CategoryService, CategoryResolver]
providers: [CategoryService, CategoryResolver, CategoryPipe, CategoryUpdatePipe]
})
export class CategoriesModule {}
19 changes: 19 additions & 0 deletions src/categories/categories.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { NotFoundException, Injectable, PipeTransform } from '@nestjs/common';

Check warning on line 1 in src/categories/categories.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
import { Category } from './category.model';
import { CategoryService } from './categories.service';

Check warning on line 3 in src/categories/categories.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

@Injectable()
export class CategoryPipe implements PipeTransform<string, Promise<Category>> {

Check warning on line 6 in src/categories/categories.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
constructor(private readonly categoryService: CategoryService) {}

Check warning on line 7 in src/categories/categories.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 7 in src/categories/categories.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function

async transform(value: string): Promise<Category> {

Check warning on line 9 in src/categories/categories.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function
try {
const category = await this.categoryService.find(value);

Check warning on line 11 in src/categories/categories.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
if (category) {
return category;

Check warning on line 13 in src/categories/categories.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
}

Check warning on line 14 in src/categories/categories.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 14 in src/categories/categories.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
} catch (e) {}

Check warning on line 15 in src/categories/categories.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

throw new NotFoundException(`Category with id ${value} not found`);

Check warning on line 17 in src/categories/categories.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
}
}

Check warning on line 19 in src/categories/categories.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 19 in src/categories/categories.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
13 changes: 12 additions & 1 deletion src/categories/categories.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
import { Query, ResolveField, Resolver } from '@nestjs/graphql';
import { Args, Mutation, Query, ResolveField, Resolver, ID } from '@nestjs/graphql';
import { Category } from './category.model';
import { CategoryService } from './categories.service';
import { DampLabServices } from '../services/damplab-services.services';
import { DampLabService } from '../services/models/damplab-service.model';
import { CategoryPipe } from './categories.pipe';
import { CategoryChange } from './dtos/update.dto';
import { CategoryUpdatePipe } from './update.pipe';

@Resolver(() => Category)
export class CategoryResolver {
constructor(private readonly categoryService: CategoryService, private readonly damplabServices: DampLabServices) {}

@Query(() => [Category])
async categories(): Promise<Category[]> {
return this.categoryService.findAll();
}

@Mutation(() => Category)
async updateCategory(
@Args('category', { type: () => ID }, CategoryPipe) category: Category,
@Args('changes', { type: () => CategoryChange }, CategoryUpdatePipe) changes: CategoryChange
): Promise<Category> {
return this.categoryService.update(category, changes);
}

Check warning on line 25 in src/categories/categories.resolver.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

/**
* Resolver for the services field of the Category type
*/
Expand Down
10 changes: 10 additions & 0 deletions src/categories/categories.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,22 @@
import { InjectModel } from '@nestjs/mongoose';
import { Category, CategoryDocument } from './category.model';
import { Model } from 'mongoose';
import { CategoryChange } from './dtos/update.dto';

@Injectable()
export class CategoryService {
constructor(@InjectModel(Category.name) private readonly categoryModel: Model<CategoryDocument>) {}

async findAll(): Promise<Category[]> {
return this.categoryModel.find().exec();
}

async find(id: string): Promise<Category | null> {

Check warning on line 15 in src/categories/categories.service.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function
return this.categoryModel.findById(id);

Check warning on line 16 in src/categories/categories.service.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
}

async update(category: Category, change: CategoryChange): Promise<Category> {

Check warning on line 19 in src/categories/categories.service.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function
await this.categoryModel.updateOne({ _id: category._id }, change);

Check warning on line 20 in src/categories/categories.service.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
return (await this.find(category._id))!;

Check warning on line 21 in src/categories/categories.service.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
}
}

Check warning on line 23 in src/categories/categories.service.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 23 in src/categories/categories.service.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
8 changes: 8 additions & 0 deletions src/categories/dtos/update.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Category } from '../category.model';
import { ID, OmitType, PartialType, Field, InputType } from '@nestjs/graphql';

@InputType()
export class CategoryChange extends PartialType(OmitType(Category, ['_id', 'services'] as const), InputType) {
@Field(() => [ID], { nullable: true })
services: string[];
}
17 changes: 17 additions & 0 deletions src/categories/update.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Injectable, PipeTransform } from '@nestjs/common';
import { DampLabServicePipe } from '../services/damplab-services.pipe';

Check warning on line 2 in src/categories/update.pipe.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
import { CategoryChange } from './dtos/update.dto';

@Injectable()
export class CategoryUpdatePipe implements PipeTransform<CategoryChange, Promise<CategoryChange>> {
constructor(private readonly damplabServicePipe: DampLabServicePipe) {}

async transform(value: CategoryChange): Promise<CategoryChange> {
// If services is includes, make sure they are all valid
if (value.services) {
await Promise.all(value.services.map((service) => this.damplabServicePipe.transform(service)));
}

return value;
}
}
3 changes: 2 additions & 1 deletion src/services/damplab-services.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { DampLabServicePipe } from './damplab-services.pipe';
import { DampLabServicesResolver } from './damplab-services.resolver';
import { DampLabServices } from './damplab-services.services';
import { DampLabService, DampLabServiceSchema } from './models/damplab-service.model';
import { ServiceUpdatePipe } from './update.pipe';

@Module({
imports: [MongooseModule.forFeature([{ name: DampLabService.name, schema: DampLabServiceSchema }])],
providers: [DampLabServicesResolver, DampLabServices, DampLabServicePipe],
providers: [DampLabServicesResolver, DampLabServices, DampLabServicePipe, ServiceUpdatePipe],
exports: [DampLabServices, DampLabServicePipe]
})
export class DampLabServicesModule {}
13 changes: 12 additions & 1 deletion src/services/damplab-services.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
import { Resolver, Query, ResolveField, Parent } from '@nestjs/graphql';
import { Resolver, Query, ResolveField, Parent, ID, Args, Mutation } from '@nestjs/graphql';
import { DampLabServicePipe } from './damplab-services.pipe';
import { DampLabServices } from './damplab-services.services';
import { ServiceChange } from './dtos/update.dto';
import { DampLabService } from './models/damplab-service.model';
import { ServiceUpdatePipe } from './update.pipe';

@Resolver(() => DampLabService)
export class DampLabServicesResolver {
constructor(private readonly dampLabServices: DampLabServices) {}

@Query(() => [DampLabService])
async services(): Promise<DampLabService[]> {
return this.dampLabServices.findAll();
}

@Mutation(() => DampLabService)
async updateService(
@Args('service', { type: () => ID }, DampLabServicePipe) service: DampLabService,
@Args('changes', { type: () => ServiceChange }, ServiceUpdatePipe) changes: ServiceChange

Check warning on line 20 in src/services/damplab-services.resolver.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
): Promise<DampLabService> {
return this.dampLabServices.update(service, changes);
}

Check warning on line 23 in src/services/damplab-services.resolver.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

/**
* Resolver which the `allowedConnections` field of the `DampLabService`
* type. Allows for the recursive search on possible connections.
Expand Down
6 changes: 6 additions & 0 deletions src/services/damplab-services.services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { DampLabService, DampLabServiceDocument } from './models/damplab-service
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import mongoose from 'mongoose';
import { ServiceChange } from './dtos/update.dto';

@Injectable()
export class DampLabServices {
Expand All @@ -22,4 +23,9 @@ export class DampLabServices {
async findOne(id: string): Promise<DampLabService | null> {
return this.dampLabServiceModel.findById(id).exec();
}

async update(service: DampLabService, changes: ServiceChange): Promise<DampLabService> {
await this.dampLabServiceModel.updateOne({ _id: service._id }, changes);
return (await this.dampLabServiceModel.findById(service._id))!;
}
}
8 changes: 8 additions & 0 deletions src/services/dtos/update.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { DampLabService } from '../models/damplab-service.model';
import { ID, InputType, OmitType, PartialType, Field } from '@nestjs/graphql';

@InputType()
export class ServiceChange extends PartialType(OmitType(DampLabService, ['_id', 'allowedConnections'] as const), InputType) {
@Field(() => [ID], { nullable: true })
allowedConnections: string[];
}
17 changes: 17 additions & 0 deletions src/services/update.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Injectable, PipeTransform } from '@nestjs/common';
import { DampLabServicePipe } from '../services/damplab-services.pipe';
import { ServiceChange } from './dtos/update.dto';

@Injectable()
export class ServiceUpdatePipe implements PipeTransform<ServiceChange, Promise<ServiceChange>> {
constructor(private readonly damplabServicePipe: DampLabServicePipe) {}

async transform(value: ServiceChange): Promise<ServiceChange> {
// If services is includes, make sure they are all valid
if (value.allowedConnections) {
await Promise.all(value.allowedConnections.map((service) => this.damplabServicePipe.transform(service)));
}

return value;
}
}
Loading