From 78b5d8dcf9f4cb5d25a2e2271f969ed7fdceacd5 Mon Sep 17 00:00:00 2001 From: Zubaidat Shuka <129978758+Shukazuby@users.noreply.github.com> Date: Wed, 12 Feb 2025 16:37:00 +0100 Subject: [PATCH] Issue #132: Added Module for Product Images (#143) * Issue #132: Added Prisma Model For ProductImages * Issue #132: Added provisional product object, service and resolver * Added Product Image Object entity * Added product Image dto * Added a service to add product image to the database * added service and resolver to query and fetch all product images * service ad resolver for getting a single product image by its ID * feat: PR changes effected * feat: prisma model and migration updated --- .../migration.sql | 23 ++++++++ .../prisma/migrations/migration_lock.toml | 2 +- apps/backend/prisma/schema.prisma | 19 +++++++ apps/backend/src/core/core.module.ts | 4 ++ apps/backend/src/core/graphql/schema.gql | 47 +++++++++++++--- .../categories/category.resolver.spec.ts | 12 ++-- .../categories/category.service.spec.ts | 10 ++-- .../product-image/dto/product-image.input.ts | 10 ++++ .../entities/product-image.entity.ts | 20 +++++++ .../product-image/product-image.graphql | 28 ++++++++++ .../product-image/product-image.module.ts | 8 +++ .../product-image.resolver.spec.ts | 19 +++++++ .../product-image/product-image.resolver.ts | 26 +++++++++ .../product-image.service.spec.ts | 18 ++++++ .../product-image/product-image.service.ts | 33 +++++++++++ .../product/dto/create-product.input.ts | 7 +++ .../product/entities/product.entity.ts | 16 ++++++ .../src/modules/product/product.module.ts | 8 +++ .../modules/product/product.resolver.spec.ts | 19 +++++++ .../src/modules/product/product.resolver.ts | 16 ++++++ .../modules/product/product.service.spec.ts | 18 ++++++ .../src/modules/product/product.service.ts | 12 ++++ package-lock.json | 56 +++++++++---------- package.json | 2 +- 24 files changed, 384 insertions(+), 49 deletions(-) create mode 100644 apps/backend/prisma/migrations/20250211173007_add_product_images/migration.sql create mode 100644 apps/backend/src/modules/product-image/dto/product-image.input.ts create mode 100644 apps/backend/src/modules/product-image/entities/product-image.entity.ts create mode 100644 apps/backend/src/modules/product-image/product-image.graphql create mode 100644 apps/backend/src/modules/product-image/product-image.module.ts create mode 100644 apps/backend/src/modules/product-image/product-image.resolver.spec.ts create mode 100644 apps/backend/src/modules/product-image/product-image.resolver.ts create mode 100644 apps/backend/src/modules/product-image/product-image.service.spec.ts create mode 100644 apps/backend/src/modules/product-image/product-image.service.ts create mode 100644 apps/backend/src/modules/product/dto/create-product.input.ts create mode 100644 apps/backend/src/modules/product/entities/product.entity.ts create mode 100644 apps/backend/src/modules/product/product.module.ts create mode 100644 apps/backend/src/modules/product/product.resolver.spec.ts create mode 100644 apps/backend/src/modules/product/product.resolver.ts create mode 100644 apps/backend/src/modules/product/product.service.spec.ts create mode 100644 apps/backend/src/modules/product/product.service.ts diff --git a/apps/backend/prisma/migrations/20250211173007_add_product_images/migration.sql b/apps/backend/prisma/migrations/20250211173007_add_product_images/migration.sql new file mode 100644 index 0000000..fd74764 --- /dev/null +++ b/apps/backend/prisma/migrations/20250211173007_add_product_images/migration.sql @@ -0,0 +1,23 @@ +-- CreateTable +CREATE TABLE "productImages" ( + "id" TEXT NOT NULL, + "image_url" TEXT NOT NULL, + "product_id" TEXT NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "productImages_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "products" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "products_pkey" PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "productImages" ADD CONSTRAINT "productImages_product_id_fkey" FOREIGN KEY ("product_id") REFERENCES "products"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/apps/backend/prisma/migrations/migration_lock.toml b/apps/backend/prisma/migrations/migration_lock.toml index 044d57c..648c57f 100644 --- a/apps/backend/prisma/migrations/migration_lock.toml +++ b/apps/backend/prisma/migrations/migration_lock.toml @@ -1,3 +1,3 @@ # Please do not edit this file manually # It should be added in your version-control system (e.g., Git) -provider = "postgresql" +provider = "postgresql" \ No newline at end of file diff --git a/apps/backend/prisma/schema.prisma b/apps/backend/prisma/schema.prisma index 55a9b98..64d366e 100644 --- a/apps/backend/prisma/schema.prisma +++ b/apps/backend/prisma/schema.prisma @@ -15,3 +15,22 @@ model Category { updatedAt DateTime @updatedAt @map("updated_at") @@map("categories") } + +model ProductImage { + id String @id @default(uuid()) + imageUrl String @map("image_url") + productId String @map("product_id") + product Product @relation(fields: [productId], references: [id]) + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + @@map("productImages") +} + +model Product { + id String @id @default(uuid()) + name String + images ProductImage[] + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + @@map("products") +} diff --git a/apps/backend/src/core/core.module.ts b/apps/backend/src/core/core.module.ts index acfcf20..398643e 100644 --- a/apps/backend/src/core/core.module.ts +++ b/apps/backend/src/core/core.module.ts @@ -4,6 +4,8 @@ import { ConfigModule, ConfigService } from "@nestjs/config"; import { GraphQLModule } from "@nestjs/graphql"; import { CategoryModule } from "src/modules/categories/category.module"; +import { ProductImageModule } from "src/modules/product-image/product-image.module"; +import { ProductModule } from "src/modules/product/product.module"; import { IS_DEV_ENV } from "src/shared/utils/is-dev.util"; import { getGraphQLConfig } from "./config/graphql.config"; import { PrismaModule } from "./prisma/prisma.module"; @@ -22,6 +24,8 @@ import { PrismaModule } from "./prisma/prisma.module"; }), PrismaModule, CategoryModule, + ProductModule, + ProductImageModule, ], controllers: [], providers: [], diff --git a/apps/backend/src/core/graphql/schema.gql b/apps/backend/src/core/graphql/schema.gql index 3fab6d0..fc12e92 100644 --- a/apps/backend/src/core/graphql/schema.gql +++ b/apps/backend/src/core/graphql/schema.gql @@ -3,11 +3,11 @@ # ------------------------------------------------------ type Category { - createdAt: DateTime! - id: ID! - imageUrl: String - name: String! - updatedAt: DateTime! + createdAt: DateTime! + id: ID! + imageUrl: String + name: String! + updatedAt: DateTime! } """ @@ -15,7 +15,38 @@ A date-time string at UTC, such as 2019-12-03T09:54:33Z, compliant with the date """ scalar DateTime +type Mutation { + createProduct(createProduct: ProductDTO!): Product! + createProductImage(createProductImage: ProductImageDTO!): ProductImage! +} + +type Product { + createdAt: DateTime! + id: ID! + name: String! + updatedAt: DateTime! +} + +input ProductDTO { + name: String! +} + +type ProductImage { + createdAt: DateTime! + id: ID! + imageUrl: String! + productId: String! + updatedAt: DateTime! +} + +input ProductImageDTO { + imageUrl: String! + productId: String! +} + type Query { - categories: [Category!]! - category(id: String!): Category -} \ No newline at end of file + categories: [Category!]! + category(id: String!): Category + productImage(id: String!): ProductImage + productImages: [ProductImage!]! +} diff --git a/apps/backend/src/modules/categories/category.resolver.spec.ts b/apps/backend/src/modules/categories/category.resolver.spec.ts index acbf967..432ea21 100644 --- a/apps/backend/src/modules/categories/category.resolver.spec.ts +++ b/apps/backend/src/modules/categories/category.resolver.spec.ts @@ -1,16 +1,16 @@ import { Test, TestingModule } from "@nestjs/testing"; -import { CategoriesResolver } from "./category.resolver"; -import { CategoriesService } from "./category.service"; +import { CategoryResolver } from "./category.resolver"; +import { CategoryService } from "./category.service"; -describe("CategoriesResolver", () => { - let resolver: CategoriesResolver; +describe("CategoryResolver", () => { + let resolver: CategoryResolver; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [CategoriesResolver, CategoriesService], + providers: [CategoryResolver, CategoryService], }).compile(); - resolver = module.get(CategoriesResolver); + resolver = module.get(CategoryResolver); }); it("should be defined", () => { diff --git a/apps/backend/src/modules/categories/category.service.spec.ts b/apps/backend/src/modules/categories/category.service.spec.ts index b6950c1..4e837cb 100644 --- a/apps/backend/src/modules/categories/category.service.spec.ts +++ b/apps/backend/src/modules/categories/category.service.spec.ts @@ -1,15 +1,15 @@ import { Test, TestingModule } from "@nestjs/testing"; -import { CategoriesService } from "./category.service"; +import { CategoryService } from "./category.service"; -describe("CategoriesService", () => { - let service: CategoriesService; +describe("CategoryService", () => { + let service: CategoryService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [CategoriesService], + providers: [CategoryService], }).compile(); - service = module.get(CategoriesService); + service = module.get(CategoryService); }); it("should be defined", () => { diff --git a/apps/backend/src/modules/product-image/dto/product-image.input.ts b/apps/backend/src/modules/product-image/dto/product-image.input.ts new file mode 100644 index 0000000..ffa606e --- /dev/null +++ b/apps/backend/src/modules/product-image/dto/product-image.input.ts @@ -0,0 +1,10 @@ +import { Field, InputType } from "@nestjs/graphql"; + +@InputType() +export class ProductImageDTO { + @Field(() => String) + imageUrl: string; + + @Field(() => String) + productId: string; +} diff --git a/apps/backend/src/modules/product-image/entities/product-image.entity.ts b/apps/backend/src/modules/product-image/entities/product-image.entity.ts new file mode 100644 index 0000000..be897e7 --- /dev/null +++ b/apps/backend/src/modules/product-image/entities/product-image.entity.ts @@ -0,0 +1,20 @@ +import { Field, ID, ObjectType } from "@nestjs/graphql"; +import { Product } from "../../product/entities/product.entity"; + +@ObjectType() +export class ProductImage { + @Field(() => ID) + id: string; + + @Field(() => String) + imageUrl: string; + + @Field(() => String) + productId: string; + + @Field(() => Date) + createdAt: Date; + + @Field(() => Date) + updatedAt: Date; +} diff --git a/apps/backend/src/modules/product-image/product-image.graphql b/apps/backend/src/modules/product-image/product-image.graphql new file mode 100644 index 0000000..69f3e6d --- /dev/null +++ b/apps/backend/src/modules/product-image/product-image.graphql @@ -0,0 +1,28 @@ +type ProductImage { + # Example field (placeholder) + exampleField: Int +} + +input CreateProductImageInput { + # Example field (placeholder) + exampleField: Int +} + +input UpdateProductImageInput { + id: Int! +} + +type Query { + productImage: [ProductImage]! + productImage(id: Int!): ProductImage +} + +type Mutation { + createProductImage( + createProductImageInput: CreateProductImageInput! + ): ProductImage! + updateProductImage( + updateProductImageInput: UpdateProductImageInput! + ): ProductImage! + removeProductImage(id: Int!): ProductImage +} diff --git a/apps/backend/src/modules/product-image/product-image.module.ts b/apps/backend/src/modules/product-image/product-image.module.ts new file mode 100644 index 0000000..8997a3a --- /dev/null +++ b/apps/backend/src/modules/product-image/product-image.module.ts @@ -0,0 +1,8 @@ +import { Module } from "@nestjs/common"; +import { ProductImageResolver } from "./product-image.resolver"; +import { ProductImageService } from "./product-image.service"; + +@Module({ + providers: [ProductImageResolver, ProductImageService], +}) +export class ProductImageModule {} diff --git a/apps/backend/src/modules/product-image/product-image.resolver.spec.ts b/apps/backend/src/modules/product-image/product-image.resolver.spec.ts new file mode 100644 index 0000000..c0a1c0b --- /dev/null +++ b/apps/backend/src/modules/product-image/product-image.resolver.spec.ts @@ -0,0 +1,19 @@ +import { Test, TestingModule } from "@nestjs/testing"; +import { ProductImageResolver } from "./product-image.resolver"; +import { ProductImageService } from "./product-image.service"; + +describe("ProductImageResolver", () => { + let resolver: ProductImageResolver; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ProductImageResolver, ProductImageService], + }).compile(); + + resolver = module.get(ProductImageResolver); + }); + + it("should be defined", () => { + expect(resolver).toBeDefined(); + }); +}); diff --git a/apps/backend/src/modules/product-image/product-image.resolver.ts b/apps/backend/src/modules/product-image/product-image.resolver.ts new file mode 100644 index 0000000..eeda810 --- /dev/null +++ b/apps/backend/src/modules/product-image/product-image.resolver.ts @@ -0,0 +1,26 @@ +import { Args, Mutation, Query, Resolver } from "@nestjs/graphql"; +import { ProductImageDTO } from "./dto/product-image.input"; +import { ProductImage } from "./entities/product-image.entity"; +import { ProductImageService } from "./product-image.service"; + +@Resolver("ProductImage") +export class ProductImageResolver { + constructor(private readonly productImageService: ProductImageService) {} + + @Mutation(() => ProductImage) + async createProductImage( + @Args("createProductImage") payload: ProductImageDTO, + ): Promise { + return await this.productImageService.createProductImage(payload); + } + + @Query(() => [ProductImage]) + async productImages() { + return await this.productImageService.getAllProductImages(); + } + + @Query(() => ProductImage, { nullable: true }) + async productImage(@Args("id") id: string) { + return await this.productImageService.getAProductImage(id); + } +} diff --git a/apps/backend/src/modules/product-image/product-image.service.spec.ts b/apps/backend/src/modules/product-image/product-image.service.spec.ts new file mode 100644 index 0000000..f822f34 --- /dev/null +++ b/apps/backend/src/modules/product-image/product-image.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from "@nestjs/testing"; +import { ProductImageService } from "./product-image.service"; + +describe("ProductImageService", () => { + let service: ProductImageService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ProductImageService], + }).compile(); + + service = module.get(ProductImageService); + }); + + it("should be defined", () => { + expect(service).toBeDefined(); + }); +}); diff --git a/apps/backend/src/modules/product-image/product-image.service.ts b/apps/backend/src/modules/product-image/product-image.service.ts new file mode 100644 index 0000000..90ebc9b --- /dev/null +++ b/apps/backend/src/modules/product-image/product-image.service.ts @@ -0,0 +1,33 @@ +import { Injectable } from "@nestjs/common"; +import { PrismaService } from "src/core/prisma/prisma.service"; +import { ProductImageDTO } from "./dto/product-image.input"; + +@Injectable() +export class ProductImageService { + constructor(private readonly prisma: PrismaService) {} + + // Service to create product Image + async createProductImage(data: ProductImageDTO) { + return await this.prisma.productImage.create({ data }); + } + + async getAllProductImages() { + const productImages = await this.prisma.productImage.findMany(); + if (productImages.length === 0) { + return []; + } + return productImages; + } + + async getAProductImage(id: string) { + const productImage = await this.prisma.productImage.findUnique({ + where: { id }, + }); + + if (!productImage) { + throw new Error("Product image not found."); + } + + return productImage; + } +} diff --git a/apps/backend/src/modules/product/dto/create-product.input.ts b/apps/backend/src/modules/product/dto/create-product.input.ts new file mode 100644 index 0000000..fb28bd0 --- /dev/null +++ b/apps/backend/src/modules/product/dto/create-product.input.ts @@ -0,0 +1,7 @@ +import { Field, InputType } from "@nestjs/graphql"; + +@InputType() +export class ProductDTO { + @Field(() => String) + name: string; +} diff --git a/apps/backend/src/modules/product/entities/product.entity.ts b/apps/backend/src/modules/product/entities/product.entity.ts new file mode 100644 index 0000000..c836023 --- /dev/null +++ b/apps/backend/src/modules/product/entities/product.entity.ts @@ -0,0 +1,16 @@ +import { Field, ID, ObjectType } from "@nestjs/graphql"; + +@ObjectType() +export class Product { + @Field(() => ID) + id: string; + + @Field(() => String) + name: string; + + @Field(() => Date) + createdAt: Date; + + @Field(() => Date) + updatedAt: Date; +} diff --git a/apps/backend/src/modules/product/product.module.ts b/apps/backend/src/modules/product/product.module.ts new file mode 100644 index 0000000..f6eeef1 --- /dev/null +++ b/apps/backend/src/modules/product/product.module.ts @@ -0,0 +1,8 @@ +import { Module } from "@nestjs/common"; +import { ProductResolver } from "./product.resolver"; +import { ProductService } from "./product.service"; + +@Module({ + providers: [ProductResolver, ProductService], +}) +export class ProductModule {} diff --git a/apps/backend/src/modules/product/product.resolver.spec.ts b/apps/backend/src/modules/product/product.resolver.spec.ts new file mode 100644 index 0000000..521d788 --- /dev/null +++ b/apps/backend/src/modules/product/product.resolver.spec.ts @@ -0,0 +1,19 @@ +import { Test, TestingModule } from "@nestjs/testing"; +import { ProductResolver } from "./product.resolver"; +import { ProductService } from "./product.service"; + +describe("ProductResolver", () => { + let resolver: ProductResolver; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ProductResolver, ProductService], + }).compile(); + + resolver = module.get(ProductResolver); + }); + + it("should be defined", () => { + expect(resolver).toBeDefined(); + }); +}); diff --git a/apps/backend/src/modules/product/product.resolver.ts b/apps/backend/src/modules/product/product.resolver.ts new file mode 100644 index 0000000..0d1682d --- /dev/null +++ b/apps/backend/src/modules/product/product.resolver.ts @@ -0,0 +1,16 @@ +import { Args, Int, Mutation, Resolver } from "@nestjs/graphql"; +import { ProductDTO } from "./dto/create-product.input"; +import { Product } from "./entities/product.entity"; +import { ProductService } from "./product.service"; + +@Resolver(() => Product) +export class ProductResolver { + constructor(private readonly productService: ProductService) {} + + @Mutation(() => Product) + async createProduct( + @Args("createProduct") payload: ProductDTO, + ): Promise { + return await this.productService.createProduct(payload); + } +} diff --git a/apps/backend/src/modules/product/product.service.spec.ts b/apps/backend/src/modules/product/product.service.spec.ts new file mode 100644 index 0000000..50cc9f6 --- /dev/null +++ b/apps/backend/src/modules/product/product.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from "@nestjs/testing"; +import { ProductService } from "./product.service"; + +describe("ProductService", () => { + let service: ProductService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ProductService], + }).compile(); + + service = module.get(ProductService); + }); + + it("should be defined", () => { + expect(service).toBeDefined(); + }); +}); diff --git a/apps/backend/src/modules/product/product.service.ts b/apps/backend/src/modules/product/product.service.ts new file mode 100644 index 0000000..e5408f8 --- /dev/null +++ b/apps/backend/src/modules/product/product.service.ts @@ -0,0 +1,12 @@ +import { Injectable } from "@nestjs/common"; +import { PrismaService } from "src/core/prisma/prisma.service"; +import { ProductDTO } from "./dto/create-product.input"; + +@Injectable() +export class ProductService { + constructor(private readonly prisma: PrismaService) {} + + async createProduct(data: ProductDTO) { + return await this.prisma.product.create({ data }); + } +} diff --git a/package-lock.json b/package-lock.json index 004dc40..1b76be5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "devDependencies": { "@biomejs/biome": "1.9.4", "lefthook": "^1.8.2", - "turbo": "^2.3.3" + "turbo": "^2.4.1" } }, "apps/backend": { @@ -15095,27 +15095,27 @@ "license": "0BSD" }, "node_modules/turbo": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/turbo/-/turbo-2.4.0.tgz", - "integrity": "sha512-ah/yQp2oMif1X0u7fBJ4MLMygnkbKnW5O8SG6pJvloPCpHfFoZctkSVQiJ3VnvNTq71V2JJIdwmOeu1i34OQyg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/turbo/-/turbo-2.4.1.tgz", + "integrity": "sha512-XIIHXAhvD3sv34WLaN/969WTHCHYmm3zf0XQ+CrEP1A7ffIQG50cwNcp7Gh96CaGyjEXMh9odoHyggoZQ3Prvw==", "dev": true, "license": "MIT", "bin": { "turbo": "bin/turbo" }, "optionalDependencies": { - "turbo-darwin-64": "2.4.0", - "turbo-darwin-arm64": "2.4.0", - "turbo-linux-64": "2.4.0", - "turbo-linux-arm64": "2.4.0", - "turbo-windows-64": "2.4.0", - "turbo-windows-arm64": "2.4.0" + "turbo-darwin-64": "2.4.1", + "turbo-darwin-arm64": "2.4.1", + "turbo-linux-64": "2.4.1", + "turbo-linux-arm64": "2.4.1", + "turbo-windows-64": "2.4.1", + "turbo-windows-arm64": "2.4.1" } }, "node_modules/turbo-darwin-64": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-2.4.0.tgz", - "integrity": "sha512-kVMScnPUa3R4n7woNmkR15kOY0aUwCLJcUyH5UC59ggKqr5HIHwweKYK8N1pwBQso0LQF4I9i93hIzfJguCcwQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/turbo-darwin-64/-/turbo-darwin-64-2.4.1.tgz", + "integrity": "sha512-oos3Gz5N6ol2/7+ys0wPENhl7ZzeVKIumn2BR7X2oE5dEPxNPDMOpKBwreU9ToCxM94e+uFTzKgjcUJpBqpTHA==", "cpu": [ "x64" ], @@ -15127,9 +15127,9 @@ ] }, "node_modules/turbo-darwin-arm64": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-2.4.0.tgz", - "integrity": "sha512-8JObIpfun1guA7UlFR5jC/SOVm49lRscxMxfg5jZ5ABft79rhFC+ygN9AwAhGKv6W2DUhIh2xENkSgu4EDmUyg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/turbo-darwin-arm64/-/turbo-darwin-arm64-2.4.1.tgz", + "integrity": "sha512-NoIQsSSvCJDTShgX+v+doSP/g0kAhHhq5p2fpsEAlougs2wcQvwv/LndeqojzkHbxB39lOQmqBYHJcki46Q3oQ==", "cpu": [ "arm64" ], @@ -15141,9 +15141,9 @@ ] }, "node_modules/turbo-linux-64": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-2.4.0.tgz", - "integrity": "sha512-xWDGGcRlBuGV7HXWAVuTY6vsQi4aZxGMAnuiuNDg8Ij1aHGohOM0RUsWMXjxz4vuJmjk9+/D6NQqHH3AJEXezg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/turbo-linux-64/-/turbo-linux-64-2.4.1.tgz", + "integrity": "sha512-iXIeG8YhluaJF/5KQEudRf8ECBWND8X0yxXDrFIq2wmLLCg4A7gSSzVcBq30rYYeyyU4xMj/sm3HbsAaao3jjg==", "cpu": [ "x64" ], @@ -15155,9 +15155,9 @@ ] }, "node_modules/turbo-linux-arm64": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-2.4.0.tgz", - "integrity": "sha512-c3En99xMguc/Pdtk/rZP53LnDdw0W6lgUc04he8r8F+UHYSNvgzHh0WGXXmCC6lGbBH72kPhhGx4bAwyvi7dug==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/turbo-linux-arm64/-/turbo-linux-arm64-2.4.1.tgz", + "integrity": "sha512-jd5apBV7lBGn3CnkQN/hEMbwazNgZcrwLt6DIkWy/TSi5xfSQEqcR3k9HxviQ7hKMcr1Q1hN6FHWm8Vw90Ej4A==", "cpu": [ "arm64" ], @@ -15169,9 +15169,9 @@ ] }, "node_modules/turbo-windows-64": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-2.4.0.tgz", - "integrity": "sha512-/gOORuOlyA8JDPzyA16CD3wvyRcuBFePa1URAnFUof9hXQmKxK0VvSDO79cYZFsJSchCKNJpckUS0gYxGsWwoA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/turbo-windows-64/-/turbo-windows-64-2.4.1.tgz", + "integrity": "sha512-4RYRAijohyQ7uetZY4SSikSgGccq+7tmnljdm/XezpK9t0+3gldKA2vHF0++yLZeZr+CFgqmBeGSFi7B+vhc2g==", "cpu": [ "x64" ], @@ -15183,9 +15183,9 @@ ] }, "node_modules/turbo-windows-arm64": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/turbo-windows-arm64/-/turbo-windows-arm64-2.4.0.tgz", - "integrity": "sha512-/DJIdTFijEMM5LSiEpSfarDOMOlYqJV+EzmppqWtHqDsOLF4hbbIBH9sJR6OOp5dURAu5eURBYdmvBRz9Lo6TA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/turbo-windows-arm64/-/turbo-windows-arm64-2.4.1.tgz", + "integrity": "sha512-4lZB0+AxWB01Adx5xHZhO746FgaHR0T3qzEDF2nf/nx8LAUtN3iwaZQgAsTsblaAKjiM7lxWDI0s/Q3fektsPg==", "cpu": [ "arm64" ], diff --git a/package.json b/package.json index 4faebc5..82c08ec 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,6 @@ "devDependencies": { "@biomejs/biome": "1.9.4", "lefthook": "^1.8.2", - "turbo": "^2.3.3" + "turbo": "^2.4.1" } }