diff --git a/.gitignore b/.gitignore index 5220d77..9b103d8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,8 @@ 04_poc +**/*del +**/*bak +**/*copy* + # Created by https://www.toptal.com/developers/gitignore/api/node,python,nextjs # Edit at https://www.toptal.com/developers/gitignore?templates=node,python,nextjs diff --git a/03_source/cms_backend/package.json b/03_source/cms_backend/package.json index f54a697..673645c 100644 --- a/03_source/cms_backend/package.json +++ b/03_source/cms_backend/package.json @@ -45,6 +45,7 @@ "dayjs": "^1.11.13", "es-toolkit": "^1.33.0", "jose": "^6.0.10", + "lodash": "^4.17.21", "next": "^14.2.26", "pg": "^8.16.0", "prisma": "^5.6.0", @@ -56,6 +57,7 @@ }, "devDependencies": { "@eslint/js": "^9.23.0", + "@types/lodash": "^4.17.17", "@types/node": "^22.13.13", "@types/react": "^18.3.20", "@types/react-dom": "^18.3.5", diff --git a/03_source/cms_backend/prisma/schema copy.prisma b/03_source/cms_backend/prisma/schema copy.prisma deleted file mode 100644 index fc97bbe..0000000 --- a/03_source/cms_backend/prisma/schema copy.prisma +++ /dev/null @@ -1,1064 +0,0 @@ -generator client { - provider = "prisma-client-js" -} - -datasource db { - provider = "postgresql" - url = env("DATABASE_URI") -} - -model Account { - id String @id @default(cuid()) - userId String @map("user_id") - type String - provider String - providerAccountId String @map("provider_account_id") - refresh_token String? - access_token String? - expires_at Int? - token_type String? - scope String? - id_token String? - session_state String? - oauth_token_secret String? - oauth_token String? - - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - - @@unique([provider, providerAccountId]) -} - -model Session { - id String @id @default(cuid()) - sessionToken String @unique @map("session_token") - userId String @map("user_id") - expires DateTime - user User @relation(fields: [userId], references: [id], onDelete: Cascade) -} - -model User { - id String @id @default(cuid()) - name String? - username String? @unique - email String @unique - emailVerified DateTime? - password String? - image String? - bucketImage String? - admin Boolean @default(false) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - accounts Account[] - sessions Session[] - info Json? -} - -model VerificationToken { - id Int @id @default(autoincrement()) - identifier String - token String @unique - expires DateTime - - @@unique([identifier, token]) -} - -// ---------------------------------------------------------------- - -// REQ0044/near_by_page -model Member { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - email String @unique - name String? - Event Event[] - eventId Int? - age Int? - rank String @default("Beginner") - verified String @default("NOT_VERIFIED") - hobbies String[] @default([]) - distance String @default("10km") - location_area String @default("Sai Kung") - greetings String @default("Hi, I am") - gender String @default("not disclosed") - tall_cm Int? - weight_kg Int? - occupation String @default("not disclosed") - language String[] @default([]) - education String[] @default([]) - self_introduction String @default("") - music String[] @default([]) - pets String[] @default([]) - character String[] @default([]) -} - -model Order { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - title String? - order_time DateTime @default(now()) - last_payment_date DateTime? - status String @default("pending") - Event Event[] -} - -// REQ0042/event-detail -model Event { - id Int @id @default(autoincrement()) - eventDate DateTime - title String - joinMembers Member[] // Assuming Member model exists - price Float - currency String - duration_m Int - ageBottom Int - ageTop Int - location String - avatar String // Assuming avatar is stored as a file path or URL - Order Order[] -} - -// cms_backend - -// mapped to IProductReview -model ProductReview { - id Int @id @default(autoincrement()) - name String - rating Float - comment String - helpful Float - avatarUrl String - postedAt DateTime @default(now()) // Assuming IDateValue maps to DateTime - isPurchased Boolean - attachments String[] - ProductItem ProductItem[] - // - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt -} - -// mapped to IProductFilters -model ProductFilters { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - rating String - gender String[] - category String - colors String[] - priceRange Int[] -} - -// mapped to IProductTableFilters -model ProductTableFilters { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - stock String[] - publish String[] -} - -// mapped to IProductItem -model ProductItem { - id String @id @default(uuid()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - sku String - name String - code String - price Float - taxes Float - tags String[] - sizes String[] - publish String - gender String[] - coverUrl String - images String[] - colors String[] - quantity Int - category String - available Int - totalSold Int - description String - totalRatings Float - totalReviews Int - inventoryType String - subDescription String - priceSale Float? - newLabel Json - saleLabel Json - ratings Json[] - reviews ProductReview[] -} - -// -model Helloworld { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - hello String @default("") -} - -model MailSender { - // Define fields for MailSender here - // Example: - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - email String - name String - avatarUrl String? - // - // SendMail Mail[] @relation("mail_from") - // ReceiveMail Mail[] @relation("mail_to") -} - -model MailLabel { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - type String - name String - color String - unreadCount Int? -} - -model MailAttachment { - // Define fields for MailAttachment here - // Example: - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - filename String - url String - size Int - // Mail Mail? @relation(fields: [mailId], references: [id]) - // mailId Int? -} - -model Mail { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - folder String - labelIds String[] - subject String - isUnread Boolean - isImportant Boolean - message String - isStarred Boolean - // - // from MailSender @relation("mail_from", fields: [mailFromId], references: [id]) - // mailFromId Int - // - // to MailSender[] @relation("mail_to") - // - // attachments MailAttachment[] -} - -model OrderHistory { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - orderTime DateTime - paymentTime DateTime - deliveryTime DateTime - completionTime DateTime - timeline Json[] - OrderItem OrderItem? @relation(fields: [orderItemId], references: [id]) - orderItemId Int? -} - -model OrderShippingAddress { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - fullAddress String - phoneNumber String - OrderItem OrderItem? @relation(fields: [orderItemId], references: [id]) - orderItemId Int? -} - -model OrderPayment { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - cardType String - cardNumber String - OrderItem OrderItem? @relation(fields: [orderItemId], references: [id]) - orderItemId Int? -} - -model OrderDelivery { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - shipBy String - speedy String - trackingNumber String - OrderItem OrderItem? @relation(fields: [orderItemId], references: [id]) - orderItemId Int? -} - -model OrderCustomer { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - name String - email String - avatarUrl String - ipAddress String - OrderItem OrderItem? @relation(fields: [orderItemId], references: [id]) - orderItemId Int? -} - -model OrderProductItem { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - sku String - name String - price Float - coverUrl String - quantity Float - OrderItem OrderItem? @relation(fields: [orderItemId], references: [id]) - orderItemId Int? -} - -model OrderItem { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - taxes Float - status String - shipping Float - discount Float - subtotal Float - orderNumber String - totalAmount Float - totalQuantity Float - history OrderHistory[] - payment OrderPayment[] - customer OrderCustomer[] - delivery OrderDelivery[] - items OrderProductItem[] - shippingAddress OrderShippingAddress[] -} - -// src/types/tour.ts -model TourGuide { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - name String - avatarUrl String - phoneNumber String - TourItem TourItem? @relation(fields: [tourItemId], references: [id]) - tourItemId Int? - TourFilters TourFilters? @relation(fields: [tourFiltersId], references: [id]) - tourFiltersId Int? -} - -model TourBooker { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - - name String - guests Float - avatarUrl String - TourItem TourItem? @relation(fields: [tourItemId], references: [id]) - tourItemId Int? -} - -model TourItem { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - - name String - price Float - tags String[] - content String - publish String - images String[] - durations String - priceSale Float - totalViews Float - services String[] - destination String - ratingNumber Float - bookers TourBooker[] - tourGuides TourGuide[] - available Json -} - -model TourFilters { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - - services String[] - destination String[] - tourGuides TourGuide[] - endDate DateTime - startDate DateTime -} - -// src/types/user.ts -model UserProfileCover { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - name String - role String - coverUrl String - avatarUrl String -} - -model UserProfile { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - role String - quote String - email String - school String - country String - company String - totalFollowers Float - totalFollowing Float - // socialLinks: ISocialLink -} - -model UserProfileFollower { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - name String - country String - avatarUrl String -} - -model UserProfileGallery { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - title String - imageUrl String - postedAt DateTime -} - -model UserProfileFriend { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - name String - role String - avatarUrl String -} - -model UserProfilePost { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - - media String - message String - personLikes Json[] - comments Json[] -} - -model UserCard { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - name String - role String - coverUrl String - avatarUrl String - totalPosts Float - totalFollowers Float - totalFollowing Float -} - -model UserItem { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - name String - city String - role String - email String - state String - status String - address String - country String - zipCode String - company String - avatarUrl String - phoneNumber String - isVerified Boolean -} - -model UserAccountBillingHistory { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - price Float - invoiceNumber String -} - -// src/types/blog.ts -model PostFilters { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - publish String -} - -model PostHero { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - title String - coverUrl String - author Json? -} - -model PostComment { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - name String - message String - avatarUrl String - postedAt DateTime - users Json[] - replyComment Json[] - PostItem PostItem? @relation(fields: [postItemId], references: [id]) - postItemId Int? -} - -model PostItem { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - title String - tags String[] - publish String - content String - coverUrl String - metaTitle String - totalViews Float - totalShares Float - description String - totalComments Float - totalFavorites Float - metaKeywords String[] - metaDescription String - comments PostComment[] - author Json - favoritePerson Json[] -} - -// src/types/calendar.ts -model CalendarFilters { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - colors String[] - startDate DateTime - endDate DateTime -} - -model CalendarRange { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - start String? - end String? -} - -model CalendarEvent { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - color String - title String - allDay Boolean - description String - end String - start String -} - -// src/types/chat.ts -model ChatAttachment { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - name String - size Int - type String - path String - preview String - ChatMessage ChatMessage? @relation(fields: [chatMessageId], references: [id]) - chatMessageId Int? -} - -model ChatMessage { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - body String - senderId String - contentType String - attachments ChatAttachment[] - ChatConversation ChatConversation? @relation(fields: [chatConversationId], references: [id]) - chatConversationId Int? -} - -model ChatParticipant { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - name String - role String - email String - address String - avatarUrl String - phoneNumber String - lastActivity DateTime - status String - ChatConversation ChatConversation? @relation(fields: [chatConversationId], references: [id]) - chatConversationId Int? -} - -model ChatConversation { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - type String - unreadCount Int - messages ChatMessage[] - participants ChatParticipant[] -} - -model ChatConversations { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - allIds String[] - byId Json -} - -// src/types/checkout.ts -model CheckoutItem { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - name String - size String - price Float - coverUrl String - colors String[] - quantity Float - available Float - subtotal Float - CheckoutState CheckoutState? @relation(fields: [checkoutStateId], references: [id]) - checkoutStateId Int? -} - -model CheckoutDeliveryOption { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - label String - value Float - description String -} - -model CheckoutPaymentOption { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - value String - label String - description String -} - -model CheckoutCardOption { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - value String - label String -} - -model CheckoutState { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - total Float - subtotal Float - discount Float - shipping Float - totalItems Float - items CheckoutItem[] - billing AddressItem[] -} - -// common.ts -model PaymentCard { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - cardType String - primary Boolean? - cardNumber String -} - -model AddressItem { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - name String - company String? - primary Boolean? - fullAddress String - phoneNumber String? - addressType String? - CheckoutState CheckoutState[] - checkoutStateId Int? - InvoiceTo Invoice[] @relation("invoice_to") - InvoiceFrom Invoice[] @relation("invoice_from") -} - -model SocialLink { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - twitter String - facebook String - linkedin String - instagram String -} - -// file.ts -model FileFilters { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - name String - type String[] - endDate DateTime - startDate DateTime -} - -model FileShared { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - name String - email String - avatarUrl String - permission String - FolderManager FolderManager? @relation(fields: [folderManagerId], references: [id]) - folderManagerId Int? - FileManager FileManager? @relation(fields: [fileManagerId], references: [id]) - fileManagerId Int? -} - -model FolderManager { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - url String - name String - size Int - type String - tags String[] - totalFiles Int? - isFavorited Boolean - modifiedAt DateTime - shared FileShared[] -} - -model FileManager { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - url String - name String - size Int - type String - tags String[] - isFavorited Boolean - modifiedAt DateTime - shared FileShared[] -} - -model FileStore { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - modifiedAt DateTime @updatedAt - // - name String - path String - preview String - size Float - type String -} - -// invoice.ts -model InvoiceTableFilters { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - name String - status String - service String[] - endDate DateTime - startDate DateTime -} - -model InvoiceItem { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - title String - price Float - total Float - service String - quantity Int - description String - Invoice Invoice? @relation(fields: [invoiceId], references: [id]) - invoiceId Int? -} - -model Invoice { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - sent Int - taxes Float - status String - subtotal Float - discount Float - shipping Float - totalAmount Float - dueDate DateTime - invoiceNumber String - items InvoiceItem[] - createDate DateTime - invoiceTo AddressItem[] @relation("invoice_to") - invoiceFrom AddressItem[] @relation("invoice_from") -} - -// job.ts -model JobFilters { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - - roles String[] - experience String - benefits String[] - locations String[] - employmentTypes String[] -} - -model JobCandidate { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - - name String - role String - avatarUrl String - JobItem JobItem[] -} - -model JobCompany { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - - name String - logo String - phoneNumber String - fullAddress String - JobItem JobItem[] -} - -model JobSalary { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - - type String - price Float - negotiable Boolean - JobItem JobItem[] -} - -model JobItem { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - role String - title String - content String - publish String - skills String[] - totalViews Float - experience String - benefits String[] - locations String[] - employmentTypes String[] - workingSchedule String[] - expiredDate DateTime? @db.Timestamp(3) - salary JobSalary[] - company JobCompany[] - candidates JobCandidate[] -} - -// kanban.ts -model KanbanColumn { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - name String - Kanban Kanban? @relation(fields: [kanbanId], references: [id]) - kanbanId Int? -} - -model KanbanComment { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - name String - message String - avatarUrl String - messageType String - KanbanTask KanbanTask? @relation(fields: [kanbanTaskId], references: [id]) - kanbanTaskId Int? -} - -model KanbanAssignee { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - name String - role String - email String - status String - address String - avatarUrl String - phoneNumber String - lastActivity DateTime - KanbanTask KanbanTask? @relation(fields: [kanbanTaskId], references: [id]) - kanbanTaskId Int? -} - -model Reporter { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - name String - avatarUrl String - KanbanTask KanbanTask? @relation(fields: [kanbanTaskId], references: [id]) - kanbanTaskId Int? -} - -model KanbanTask { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - name String - status String - priority String - labels String[] - description String? - attachments String[] - comments KanbanComment[] - assignee KanbanAssignee[] - due DateTime[] - reporter Reporter[] - Kanban Kanban? @relation(fields: [kanbanId], references: [id]) - kanbanId Int? -} - -model Kanban { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - // - columns KanbanColumn[] - tasks KanbanTask[] -} diff --git a/03_source/cms_backend/src/app/api/product/details/route.ts b/03_source/cms_backend/src/app/api/product/details/route.ts index dbf459c..592a78a 100644 --- a/03_source/cms_backend/src/app/api/product/details/route.ts +++ b/03_source/cms_backend/src/app/api/product/details/route.ts @@ -1,25 +1,32 @@ +// src/app/api/product/details/route.ts + import type { NextRequest } from 'next/server'; import { logger } from 'src/utils/logger'; import { STATUS, response, handleError } from 'src/utils/response'; -import { _products } from 'src/_mock/_product'; +import prisma from '../../../lib/prisma'; // ---------------------------------------------------------------------- -export const runtime = 'edge'; - /** ************************************** * Get product details *************************************** */ export async function GET(req: NextRequest) { try { const { searchParams } = req.nextUrl; + + // RULES: productId must exist const productId = searchParams.get('productId'); + if (!productId) { + return response({ message: 'Product ID is required!' }, STATUS.BAD_REQUEST); + } - const products = _products(); - - const product = products.find((productItem) => productItem.id === productId); + // NOTE: productId confirmed exist, run below + const product = await prisma.productItem.findFirst({ + include: { reviews: true }, + where: { id: productId }, + }); if (!product) { return response({ message: 'Product not found!' }, STATUS.NOT_FOUND); diff --git a/03_source/cms_backend/src/app/api/product/list/route.ts b/03_source/cms_backend/src/app/api/product/list/route.ts index 87d4032..027d97b 100644 --- a/03_source/cms_backend/src/app/api/product/list/route.ts +++ b/03_source/cms_backend/src/app/api/product/list/route.ts @@ -1,3 +1,4 @@ +// src/app/api/product/list/route.ts import { logger } from 'src/utils/logger'; import { STATUS, response, handleError } from 'src/utils/response'; diff --git a/03_source/cms_backend/yarn.lock b/03_source/cms_backend/yarn.lock index 648606c..4f4d74a 100644 --- a/03_source/cms_backend/yarn.lock +++ b/03_source/cms_backend/yarn.lock @@ -780,6 +780,11 @@ resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/lodash@^4.17.17": + version "4.17.17" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.17.tgz#fb85a04f47e9e4da888384feead0de05f7070355" + integrity sha512-RRVJ+J3J+WmyOTqnz3PiBLA501eKwXl2noseKOrNo/6+XEHjTAxO4xHvxQB6QuNm+s4WRbn6rSiap8+EA+ykFQ== + "@types/node@^22.13.13": version "22.13.13" resolved "https://registry.npmjs.org/@types/node/-/node-22.13.13.tgz" @@ -2428,6 +2433,11 @@ lodash.merge@^4.6.2: resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"