add classwork-87

parent dd77e9f7
DB_HOST=
DB_PORT=
DB_USER=
DB_PASS=
DB_NAME=
PORT=
...@@ -21,15 +21,19 @@ ...@@ -21,15 +21,19 @@
}, },
"dependencies": { "dependencies": {
"@nestjs/common": "^11.0.1", "@nestjs/common": "^11.0.1",
"@nestjs/config": "^4.0.2",
"@nestjs/core": "^11.0.1", "@nestjs/core": "^11.0.1",
"@nestjs/mapped-types": "*", "@nestjs/mapped-types": "*",
"@nestjs/platform-express": "^11.0.1", "@nestjs/platform-express": "^11.0.1",
"@nestjs/serve-static": "^5.0.3", "@nestjs/serve-static": "^5.0.3",
"@nestjs/typeorm": "^11.0.0",
"class-transformer": "^0.5.1", "class-transformer": "^0.5.1",
"class-validator": "^0.14.2", "class-validator": "^0.14.2",
"multer": "^2.0.2", "multer": "^2.0.2",
"pg": "^8.16.3",
"reflect-metadata": "^0.2.2", "reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1" "rxjs": "^7.8.1",
"typeorm": "^0.3.26"
}, },
"devDependencies": { "devDependencies": {
"@eslint/eslintrc": "^3.2.0", "@eslint/eslintrc": "^3.2.0",
......
This diff is collapsed.
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ProductsModule } from './products/products.module'; import { ProductsModule } from './products/products.module';
import { CategoriesModule } from './categories/categories.module';
@Module({ @Module({
imports: [ProductsModule], imports: [
ConfigModule.forRoot({
isGlobal: true,
envFilePath: '.env',
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService) => ({
type: 'postgres',
host: configService.get<string>('DB_HOST'),
port: configService.get<number>('DB_PORT'),
username: configService.get<string>('DB_USER'),
password: configService.get<string>('DB_PASS'),
database: configService.get<string>('DB_NAME'),
autoLoadEntities: true,
synchronize: true,
}),
}),
ProductsModule,
CategoriesModule,
],
controllers: [], controllers: [],
providers: [], providers: [],
}) })
......
import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Put,
} from '@nestjs/common';
import { CategoriesService } from './categories.service';
import { CreateCategoryDto } from './dto/create-category.dto';
import { UpdateCategoryDto } from './dto/update-category.dto';
@Controller('categories')
export class CategoriesController {
constructor(private readonly categoriesService: CategoriesService) {}
@Post()
create(@Body() createCategoryDto: CreateCategoryDto) {
return this.categoriesService.create(createCategoryDto);
}
@Get()
findAll() {
return this.categoriesService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.categoriesService.findOne(+id);
}
@Put(':id')
update(
@Param('id') id: string,
@Body() updateCategoryDto: UpdateCategoryDto,
) {
return this.categoriesService.update(+id, updateCategoryDto);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.categoriesService.remove(+id);
}
}
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { CategoriesController } from './categories.controller';
import { CategoriesService } from './categories.service';
import { Category } from './entities/category.entity';
@Module({
imports: [TypeOrmModule.forFeature([Category])],
controllers: [CategoriesController],
providers: [CategoriesService],
exports: [CategoriesService],
})
export class CategoriesModule {}
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CreateCategoryDto } from './dto/create-category.dto';
import { UpdateCategoryDto } from './dto/update-category.dto';
import { Category } from './entities/category.entity';
@Injectable()
export class CategoriesService {
constructor(
@InjectRepository(Category)
private readonly categoryRepo: Repository<Category>,
) {}
async create(createCategoryDto: CreateCategoryDto): Promise<Category> {
const category = this.categoryRepo.create(createCategoryDto);
return await this.categoryRepo.save(category);
}
async findAll(): Promise<Category[]> {
return await this.categoryRepo.find();
}
async findOne(id: number): Promise<Category | null> {
return await this.categoryRepo.findOneBy({ id });
}
async update(
id: number,
updateCategoryDto: UpdateCategoryDto,
): Promise<Category | null> {
await this.categoryRepo.update(id, updateCategoryDto);
return await this.categoryRepo.findOneBy({ id });
}
async remove(id: number): Promise<number> {
await this.categoryRepo.delete(id);
return id;
}
}
import { IsOptional, IsString } from 'class-validator';
export class CreateCategoryDto {
@IsString({ message: 'Title must have be string' })
title: string;
@IsOptional()
@IsString({ message: 'Description must have be string' })
description?: string;
}
import { PartialType } from '@nestjs/mapped-types';
import { CreateCategoryDto } from './create-category.dto';
export class UpdateCategoryDto extends PartialType(CreateCategoryDto) {}
import { Product } from 'src/products/entity/product';
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
@Entity({ name: 'categories' })
export class Category {
@PrimaryGeneratedColumn()
id: number;
@Column({ type: 'varchar', length: 150 })
title: string;
@Column({ type: 'text', nullable: true })
description?: string;
@OneToMany(() => Product, (product) => product.category)
products: Product[];
}
...@@ -12,4 +12,8 @@ export class CreateProductDto { ...@@ -12,4 +12,8 @@ export class CreateProductDto {
@Type(() => Number) @Type(() => Number)
@IsNumber() @IsNumber()
price: number; price: number;
@Type(() => Number)
@IsNumber()
categoryId: number;
} }
import { Category } from 'src/categories/entities/category.entity';
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
@Entity({ name: 'products' })
export class Product {
@PrimaryGeneratedColumn()
id: number;
@Column({ type: 'varchar', length: 150 })
title: string;
@Column({ type: 'text', nullable: true })
description?: string;
@Column({ type: 'numeric' })
price: number;
@Column({ type: 'text', nullable: true })
image?: string;
@ManyToOne(() => Category, (category) => category.products)
category: Category;
}
...@@ -21,7 +21,7 @@ export class ProductsController { ...@@ -21,7 +21,7 @@ export class ProductsController {
@Body() createProductDto: CreateProductDto, @Body() createProductDto: CreateProductDto,
@UploadedFile() image: Express.Multer.File, @UploadedFile() image: Express.Multer.File,
) { ) {
return this.productsService.create(createProductDto, image.filename); return this.productsService.create(createProductDto, image?.filename);
} }
@Get() @Get()
......
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { ProductsService } from './products.service'; import { TypeOrmModule } from '@nestjs/typeorm';
import { CategoriesModule } from 'src/categories/categories.module';
import { Category } from 'src/categories/entities/category.entity';
import { Product } from './entity/product';
import { ProductsController } from './products.controller'; import { ProductsController } from './products.controller';
import { ProductsService } from './products.service';
@Module({ @Module({
imports: [TypeOrmModule.forFeature([Product, Category]), CategoriesModule],
controllers: [ProductsController], controllers: [ProductsController],
providers: [ProductsService], providers: [ProductsService],
}) })
......
import { Injectable } from '@nestjs/common'; import { Injectable, NotFoundException } from '@nestjs/common';
import { randomUUID } from 'crypto'; import { InjectRepository } from '@nestjs/typeorm';
import * as fs from 'fs'; import { Category } from 'src/categories/entities/category.entity';
import * as path from 'path'; import { Repository } from 'typeorm';
import { IProduct } from 'src/interface/product';
import { CreateProductDto } from './dto/create-product.dto'; import { CreateProductDto } from './dto/create-product.dto';
import { Product } from './entity/product';
@Injectable() @Injectable()
export class ProductsService { export class ProductsService {
constructor() { constructor(
this.init(); @InjectRepository(Product)
} private readonly productRepo: Repository<Product>,
@InjectRepository(Category)
private readonly categoryRepo: Repository<Category>,
) {}
private products: IProduct[] = []; async create(
private readonly filePath = path?.resolve( createProductDto: CreateProductDto,
process.cwd(), fileName?: string,
'src/data/products.json', ): Promise<Product> {
); const category = await this.categoryRepo.findOneBy({
id: createProductDto.categoryId,
});
private init(): void { if (!category) throw new NotFoundException('Category not found');
try {
const fileContents = fs.readFileSync(this.filePath);
this.products = JSON.parse(fileContents.toString()) as IProduct[];
} catch {
this.products = [];
}
}
create(createProductDto: CreateProductDto, fileName: string) { const product = this.productRepo.create({
const product = {
...createProductDto, ...createProductDto,
id: randomUUID(),
image: fileName, image: fileName,
}; category,
});
this.products.push(product);
this.save();
}
findAll(): IProduct[] { return await this.productRepo.save(product);
return this.products;
} }
private save(): void { async findAll(): Promise<Product[]> {
fs.writeFileSync(this.filePath, JSON.stringify(this.products, null, 2)); return await this.productRepo.find({
relations: {
category: true,
},
});
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment