-
handleFileSelect(e.target.files)}
- disabled={isUploading}
- />
Arrastre y suelte imágenes aquí
o haga clic para buscar (máximo 5MB por imagen)
-
- {uploadingFiles.length > 0 && (
-
-
Subiendo imágenes ({uploadingFiles.length})
-
- {uploadingFiles.map((item, index) => (
-
- ))}
-
-
- )}
-
{value.length > 0 && (
Imágenes del Producto ({value.length})
@@ -301,6 +196,31 @@ export function ImageUpload({ value, onChange, storeId }: ImageUploadProps) {
)}
+
+ {
+ if (selectedImage) {
+ let imagesToAdd: ImageFile[] = []
+ if (Array.isArray(selectedImage)) {
+ imagesToAdd = selectedImage.map(img => ({
+ url: img.url,
+ alt: '',
+ }))
+ } else {
+ imagesToAdd.push({
+ url: selectedImage.url,
+ alt: '',
+ })
+ }
+ onChange([...value, ...imagesToAdd])
+ }
+ setIsModalOpen(false)
+ }}
+ initialSelectedImage={value.length > 0 ? value[0].url : null}
+ />
)
}
diff --git a/app/store/components/product-management/InventoryManager.tsx b/app/store/components/product-management/main-components/InventoryManager.tsx
similarity index 84%
rename from app/store/components/product-management/InventoryManager.tsx
rename to app/store/components/product-management/main-components/InventoryManager.tsx
index f6685bde..bcf6fbcd 100644
--- a/app/store/components/product-management/InventoryManager.tsx
+++ b/app/store/components/product-management/main-components/InventoryManager.tsx
@@ -1,8 +1,8 @@
import { useProducts } from '@/app/store/hooks/useProducts'
-import { InventoryTracking } from './InventoryTracking'
-import { InventoryPage } from './InventoryPage'
+import { InventoryTracking } from '@/app/store/components/product-management/main-components/InventoryTracking'
+import { InventoryPage } from '@/app/store/components/product-management/main-components/InventoryPage'
import { Loader } from '@/components/ui/loader'
-import { useProductPagination } from './hooks/useProductPagination'
+import { useProductPagination } from '@/app/store/components/product-management/hooks/useProductPagination'
interface InventoryManagerProps {
storeId: string
diff --git a/app/store/components/product-management/InventoryPage.tsx b/app/store/components/product-management/main-components/InventoryPage.tsx
similarity index 100%
rename from app/store/components/product-management/InventoryPage.tsx
rename to app/store/components/product-management/main-components/InventoryPage.tsx
diff --git a/app/store/components/product-management/InventoryTracking.tsx b/app/store/components/product-management/main-components/InventoryTracking.tsx
similarity index 100%
rename from app/store/components/product-management/InventoryTracking.tsx
rename to app/store/components/product-management/main-components/InventoryTracking.tsx
diff --git a/app/store/components/product-management/ProductForm.tsx b/app/store/components/product-management/main-components/ProductForm.tsx
similarity index 100%
rename from app/store/components/product-management/ProductForm.tsx
rename to app/store/components/product-management/main-components/ProductForm.tsx
diff --git a/app/store/components/product-management/ProductList.tsx b/app/store/components/product-management/main-components/ProductList.tsx
similarity index 100%
rename from app/store/components/product-management/ProductList.tsx
rename to app/store/components/product-management/main-components/ProductList.tsx
diff --git a/app/store/components/product-management/ProductManager.tsx b/app/store/components/product-management/main-components/ProductManager.tsx
similarity index 92%
rename from app/store/components/product-management/ProductManager.tsx
rename to app/store/components/product-management/main-components/ProductManager.tsx
index 8b5f449f..ef90fb4f 100644
--- a/app/store/components/product-management/ProductManager.tsx
+++ b/app/store/components/product-management/main-components/ProductManager.tsx
@@ -1,7 +1,7 @@
import { useProducts } from '@/app/store/hooks/useProducts'
-import { ProductForm } from '@/app/store/components/product-management/ProductForm'
-import { ProductList } from '@/app/store/components/product-management/ProductList'
-import { ProductsPage } from '@/app/store/components/product-management/ProductPage'
+import { ProductForm } from '@/app/store/components/product-management/main-components/ProductForm'
+import { ProductList } from '@/app/store/components/product-management/main-components/ProductList'
+import { ProductsPage } from '@/app/store/components/product-management/main-components/ProductPage'
import { Loader } from '@/components/ui/loader'
interface ProductManagerProps {
diff --git a/app/store/components/product-management/ProductPage.tsx b/app/store/components/product-management/main-components/ProductPage.tsx
similarity index 100%
rename from app/store/components/product-management/ProductPage.tsx
rename to app/store/components/product-management/main-components/ProductPage.tsx
diff --git a/app/store/components/product-management/product-sections/attributes-section.tsx b/app/store/components/product-management/product-sections/attributes-section.tsx
index 338db5db..1acafc43 100644
--- a/app/store/components/product-management/product-sections/attributes-section.tsx
+++ b/app/store/components/product-management/product-sections/attributes-section.tsx
@@ -1,5 +1,5 @@
import type { UseFormReturn } from 'react-hook-form'
-import { AttributesForm } from '@/app/store/components/product-management/AttributesForm'
+import { AttributesForm } from '@/app/store/components/product-management/main-components/AttributesForm'
import type { ProductFormValues } from '@/lib/zod-schemas/product-schema'
interface AttributesSectionProps {
diff --git a/app/store/components/product-management/product-sections/images-section.tsx b/app/store/components/product-management/product-sections/images-section.tsx
index 248d3dd4..04e8d248 100644
--- a/app/store/components/product-management/product-sections/images-section.tsx
+++ b/app/store/components/product-management/product-sections/images-section.tsx
@@ -1,5 +1,5 @@
import type { UseFormReturn } from 'react-hook-form'
-import { ImageUpload } from '@/app/store/components/product-management/ImageUpload'
+import { ImageUpload } from '@/app/store/components/product-management/main-components/ImageUpload'
import type { ProductFormValues } from '@/lib/zod-schemas/product-schema'
interface ImagesSectionProps {
diff --git a/app/store/config/StoreLayoutClient.tsx b/app/store/config/StoreLayoutClient.tsx
new file mode 100644
index 00000000..0cc992cf
--- /dev/null
+++ b/app/store/config/StoreLayoutClient.tsx
@@ -0,0 +1,112 @@
+'use client'
+
+import { AppSidebar } from '@/app/store/components/sidebar/app-sidebar'
+import { SidebarProvider, SidebarInset, SidebarTrigger } from '@/components/ui/sidebar'
+import { Separator } from '@/components/ui/separator'
+import { useEffect, useState } from 'react'
+import { SearchNavigation } from '@/app/store/components/search-bar/SearchNavigation'
+import { NotificationPopover } from '@/app/store/components/notifications/NotificationPopover'
+import { PageTransition } from '@/components/ui/page-transition'
+import { getStoreId } from '@/utils/store-utils'
+import { useParams, usePathname } from 'next/navigation'
+import { useStore } from '@/app/store/hooks/useStore'
+import { ChatTrigger } from '@/app/store/components/ai-chat/ChatTrigger'
+import { Amplify } from 'aws-amplify'
+import outputs from '@/amplify_outputs.json'
+
+Amplify.configure(outputs)
+const existingConfig = Amplify.getConfig()
+Amplify.configure({
+ ...existingConfig,
+ API: {
+ ...existingConfig.API,
+ REST: outputs.custom.APIs,
+ },
+})
+
+export const StoreLayoutClient = ({ children }: { children: React.ReactNode }) => {
+ const pathname = usePathname()
+ const params = useParams()
+ const storeId = getStoreId(params, pathname)
+ useStore(storeId)
+ const [prefersReducedMotion, setPrefersReducedMotion] = useState(false)
+
+ useEffect(() => {
+ const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)')
+ setPrefersReducedMotion(mediaQuery.matches)
+
+ const handleChange = (e: MediaQueryListEvent) => {
+ setPrefersReducedMotion(e.matches)
+ }
+
+ mediaQuery.addEventListener('change', handleChange)
+ return () => mediaQuery.removeEventListener('change', handleChange)
+ }, [])
+
+ useEffect(() => {
+ const adjustViewport = () => {
+ if (window.innerWidth < 768) {
+ let viewportMeta = document.querySelector('meta[name="viewport"]')
+ if (!viewportMeta) {
+ viewportMeta = document.createElement('meta')
+ viewportMeta.setAttribute('name', 'viewport')
+ document.head.appendChild(viewportMeta)
+ }
+
+ viewportMeta.setAttribute(
+ 'content',
+ 'width=device-width, initial-scale=0.95, maximum-scale=3, user-scalable=yes'
+ )
+ }
+ }
+
+ adjustViewport()
+
+ window.addEventListener('resize', adjustViewport)
+
+ return () => {
+ window.removeEventListener('resize', adjustViewport)
+
+ const viewportMeta = document.querySelector('meta[name="viewport"]')
+ if (viewportMeta) {
+ viewportMeta.setAttribute(
+ 'content',
+ 'width=device-width, initial-scale=1, maximum-scale=5, user-scalable=yes'
+ )
+ }
+ }
+ }, [])
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {children}
+
+
+
+ )
+}
diff --git a/app/store/hooks/useProductImageUpload.ts b/app/store/hooks/useProductImageUpload.ts
index 1803223a..0215a191 100644
--- a/app/store/hooks/useProductImageUpload.ts
+++ b/app/store/hooks/useProductImageUpload.ts
@@ -2,7 +2,6 @@ import { useState } from 'react'
import { uploadData } from 'aws-amplify/storage'
import { Amplify } from 'aws-amplify'
import { v4 as uuidv4 } from 'uuid'
-import { getCurrentUser } from 'aws-amplify/auth'
import outputs from '@/amplify_outputs.json'
Amplify.configure(outputs)
@@ -38,13 +37,10 @@ export function useProductImageUpload() {
try {
// Generar un UUID único para el archivo
const uniqueFileName = `${uuidv4()}-${file.name.replace(/\s+/g, '-')}`
- // Obtener el usuario actual para usar su ID en la ruta
- const user = await getCurrentUser()
- const userId = user.userId
// Subir la imagen al bucket correcto
const result = await uploadData({
- path: `products/${userId}/${uniqueFileName}`,
+ path: `products/${storeId}/${uniqueFileName}`,
options: {
bucket: 'fasttifyAssets',
contentType: file.type,
diff --git a/app/store/hooks/useS3Images.ts b/app/store/hooks/useS3Images.ts
index 863422a0..2e31c114 100644
--- a/app/store/hooks/useS3Images.ts
+++ b/app/store/hooks/useS3Images.ts
@@ -21,6 +21,7 @@ interface S3ImagesResponse {
images?: S3Image[]
success?: boolean
image?: S3Image
+ nextContinuationToken?: string
}
export function useS3Images(options: UseS3ImagesOptions = {}) {
@@ -28,96 +29,132 @@ export function useS3Images(options: UseS3ImagesOptions = {}) {
const [loading, setLoading] = useState(true)
const [error, setError] = useState
(null)
const { storeId } = useStoreDataStore()
+ const [nextContinuationToken, setNextContinuationToken] = useState(undefined)
+ const [loadingMore, setLoadingMore] = useState(false)
+
+ const fetchImages = async (token?: string) => {
+ if (!storeId) {
+ setLoading(false)
+ setImages([])
+ setNextContinuationToken(undefined)
+ return
+ }
- useEffect(() => {
- const fetchImages = async () => {
- if (!storeId) {
- setLoading(false)
- setImages([])
+ if (!token) {
+ setLoading(true)
+ setImages([])
+ } else {
+ setLoadingMore(true)
+ }
+ setError(null)
+
+ try {
+ const restOperation = post({
+ apiName: 'StoreImagesApi',
+ path: 'store-images',
+ options: {
+ body: {
+ action: 'list',
+ storeId,
+ limit: options.limit || 18,
+ prefix: options.prefix || '',
+ continuationToken: token,
+ } as any,
+ },
+ })
+
+ const { body } = await restOperation.response
+ const response = (await body.json()) as S3ImagesResponse
+
+ if (!response.images) {
+ if (!token) {
+ setImages([])
+ }
+ setNextContinuationToken(undefined)
return
}
- setLoading(true)
+ const processedImages = response.images.map(img => ({
+ ...img,
+ lastModified: img.lastModified ? new Date(img.lastModified) : undefined,
+ }))
+
+ setImages(prev => (token ? [...prev, ...processedImages] : processedImages))
+ setNextContinuationToken(response.nextContinuationToken)
+ } catch (err) {
+ console.error(token ? 'Error fetching more S3 images:' : 'Error fetching S3 images:', err)
+ setError(err instanceof Error ? err : new Error('Unknown error occurred'))
+ setNextContinuationToken(undefined)
+ } finally {
+ if (!token) {
+ setLoading(false)
+ } else {
+ setLoadingMore(false)
+ }
+ }
+ }
+
+ useEffect(() => {
+ fetchImages()
+ }, [storeId, options.prefix])
+
+ const fetchMoreImages = () => {
+ if (nextContinuationToken && !loadingMore && !loading) {
+ fetchImages(nextContinuationToken)
+ }
+ }
+
+ const uploadImage = async (files: File[]): Promise => {
+ if (!storeId || files.length === 0) return null
+
+ const uploadedImages: S3Image[] = []
+
+ for (const file of files) {
try {
+ const base64File = await fileToBase64(file)
+
const restOperation = post({
apiName: 'StoreImagesApi',
path: 'store-images',
options: {
body: {
- action: 'list',
+ action: 'upload',
storeId,
- limit: options.limit || 1000,
- prefix: options.prefix || '',
- },
+ filename: file.name,
+ contentType: file.type,
+ fileContent: base64File,
+ } as any,
},
})
const { body } = await restOperation.response
const response = (await body.json()) as S3ImagesResponse
- if (!response.images) {
- setImages([])
- return
+ if (!response.image) {
+ console.error('Failed to upload image:', file.name)
+ continue
}
- const processedImages = response.images.map(img => ({
- ...img,
- lastModified: img.lastModified ? new Date(img.lastModified) : undefined,
- }))
+ const newImage = {
+ ...response.image,
+ lastModified: response.image.lastModified
+ ? new Date(response.image.lastModified)
+ : new Date(),
+ }
- setImages(processedImages)
+ uploadedImages.push(newImage)
} catch (err) {
- console.error('Error fetching S3 images:', err)
- setError(err instanceof Error ? err : new Error('Unknown error occurred'))
- } finally {
- setLoading(false)
- }
- }
-
- fetchImages()
- }, [storeId, options.prefix, options.limit])
-
- const uploadImage = async (file: File): Promise => {
- if (!storeId || !file) return null
-
- try {
- const base64File = await fileToBase64(file)
-
- const restOperation = post({
- apiName: 'StoreImagesApi',
- path: 'store-images',
- options: {
- body: {
- action: 'upload',
- storeId,
- filename: file.name,
- contentType: file.type,
- fileContent: base64File,
- },
- },
- })
-
- const { body } = await restOperation.response
- const response = (await body.json()) as S3ImagesResponse
+ console.error('Error uploading image:', file.name, err)
- if (!response.image) {
- throw new Error('Failed to upload image')
+ continue
}
+ }
- const newImage = {
- ...response.image,
- lastModified: response.image.lastModified
- ? new Date(response.image.lastModified)
- : new Date(),
- }
-
- setImages(prev => [newImage, ...prev])
-
- return newImage
- } catch (err) {
- console.error('Error uploading image:', err)
- return null
+ if (uploadedImages.length > 0) {
+ setImages(prev => [...uploadedImages, ...prev])
}
+
+ return uploadedImages.length > 0 ? uploadedImages : null
}
const deleteImage = async (key: string): Promise => {
@@ -132,7 +169,7 @@ export function useS3Images(options: UseS3ImagesOptions = {}) {
action: 'delete',
storeId,
key,
- },
+ } as any,
},
})
@@ -168,5 +205,14 @@ export function useS3Images(options: UseS3ImagesOptions = {}) {
})
}
- return { images, loading, error, uploadImage, deleteImage }
+ return {
+ images,
+ loading,
+ error,
+ uploadImage,
+ deleteImage,
+ fetchMoreImages,
+ loadingMore,
+ nextContinuationToken,
+ }
}
diff --git a/app/store/layout.tsx b/app/store/layout.tsx
index e7574e91..ffafa2be 100644
--- a/app/store/layout.tsx
+++ b/app/store/layout.tsx
@@ -1,124 +1,10 @@
-'use client'
+import { StoreLayoutClient } from '@/app/store/config/StoreLayoutClient'
-import { AppSidebar } from '@/app/store/components/sidebar/app-sidebar'
-import { SidebarProvider, SidebarInset, SidebarTrigger } from '@/components/ui/sidebar'
-import { Separator } from '@/components/ui/separator'
-import { useEffect, useState } from 'react'
-import { SearchNavigation } from '@/app/store/components/search-bar/SearchNavigation'
-import { NotificationPopover } from '@/app/store/components/notifications/NotificationPopover'
-import { PageTransition } from '@/components/ui/page-transition'
-import { getStoreId } from '@/utils/store-utils'
-import { useParams, usePathname } from 'next/navigation'
-import { useStore } from '@/app/store/hooks/useStore'
-import { ChatTrigger } from '@/app/store/components/ai-chat/ChatTrigger'
-import { Amplify } from 'aws-amplify'
-import outputs from '@/amplify_outputs.json'
-
-Amplify.configure(outputs)
-const existingConfig = Amplify.getConfig()
-Amplify.configure({
- ...existingConfig,
- API: {
- ...existingConfig.API,
- REST: outputs.custom.APIs,
- },
-})
+export const metadata = {
+ title: 'Mi tienda',
+ description: 'Dashboard de tu tienda en Fasttify',
+}
export default function StoreLayout({ children }: { children: React.ReactNode }) {
- const pathname = usePathname()
- const params = useParams()
- const storeId = getStoreId(params, pathname)
- useStore(storeId)
- const [prefersReducedMotion, setPrefersReducedMotion] = useState(false)
-
- useEffect(() => {
- document.title = 'Mi tienda • Fasttify'
-
- // Comprobar si el usuario prefiere reducir el movimiento
- const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)')
- setPrefersReducedMotion(mediaQuery.matches)
-
- const handleChange = (e: MediaQueryListEvent) => {
- setPrefersReducedMotion(e.matches)
- }
-
- mediaQuery.addEventListener('change', handleChange)
- return () => mediaQuery.removeEventListener('change', handleChange)
- }, [])
-
- // Efecto para ajustar el viewport en dispositivos móviles
- useEffect(() => {
- // Función para ajustar la escala de visualización
- const adjustViewport = () => {
- // Verificar si es un dispositivo móvil (ancho menor a 768px)
- if (window.innerWidth < 768) {
- // Crear o actualizar la meta tag de viewport
- let viewportMeta = document.querySelector('meta[name="viewport"]')
- if (!viewportMeta) {
- viewportMeta = document.createElement('meta')
- viewportMeta.setAttribute('name', 'viewport')
- document.head.appendChild(viewportMeta)
- }
-
- // Establecer una escala inicial más pequeña para las vistas de store
- viewportMeta.setAttribute(
- 'content',
- 'width=device-width, initial-scale=0.95, maximum-scale=3, user-scalable=yes'
- )
- }
- }
-
- // Aplicar el ajuste al cargar la página
- adjustViewport()
-
- // Aplicar el ajuste al cambiar el tamaño de la ventana
- window.addEventListener('resize', adjustViewport)
-
- // Limpiar el event listener cuando el componente se desmonte
- return () => {
- window.removeEventListener('resize', adjustViewport)
-
- // Restaurar el viewport original al salir de las rutas /store
- const viewportMeta = document.querySelector('meta[name="viewport"]')
- if (viewportMeta) {
- viewportMeta.setAttribute(
- 'content',
- 'width=device-width, initial-scale=1, maximum-scale=5, user-scalable=yes'
- )
- }
- }
- }, [])
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {children}
-
-
-
- )
+ return {children}
}
diff --git a/config/fonts.ts b/config/fonts.ts
new file mode 100644
index 00000000..869e7362
--- /dev/null
+++ b/config/fonts.ts
@@ -0,0 +1,7 @@
+import { Plus_Jakarta_Sans } from 'next/font/google'
+
+export const plusJakartaSans = Plus_Jakarta_Sans({
+ subsets: ['latin'],
+ weight: ['300', '400', '500', '700'],
+ display: 'swap',
+})
diff --git a/hooks/ui/use-media-query.ts b/hooks/ui/use-media-query.ts
index bc13fe34..afceb6a3 100644
--- a/hooks/ui/use-media-query.ts
+++ b/hooks/ui/use-media-query.ts
@@ -8,18 +8,14 @@ export function useMediaQuery(query: string): boolean {
useEffect(() => {
const mediaQuery = window.matchMedia(query)
- // Set initial value
setMatches(mediaQuery.matches)
- // Create event listener function
const handleChange = (event: MediaQueryListEvent) => {
setMatches(event.matches)
}
- // Add event listener
mediaQuery.addEventListener('change', handleChange)
- // Clean up
return () => {
mediaQuery.removeEventListener('change', handleChange)
}
diff --git a/package-lock.json b/package-lock.json
index e617026d..5bd9aef4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27313,9 +27313,9 @@
}
},
"node_modules/@img/sharp-darwin-arm64": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.1.tgz",
- "integrity": "sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A==",
+ "version": "0.34.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.2.tgz",
+ "integrity": "sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==",
"cpu": [
"arm64"
],
@@ -27335,9 +27335,9 @@
}
},
"node_modules/@img/sharp-darwin-x64": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.1.tgz",
- "integrity": "sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q==",
+ "version": "0.34.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.2.tgz",
+ "integrity": "sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==",
"cpu": [
"x64"
],
@@ -27501,9 +27501,9 @@
}
},
"node_modules/@img/sharp-linux-arm": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.1.tgz",
- "integrity": "sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA==",
+ "version": "0.34.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.2.tgz",
+ "integrity": "sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==",
"cpu": [
"arm"
],
@@ -27523,9 +27523,9 @@
}
},
"node_modules/@img/sharp-linux-arm64": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.1.tgz",
- "integrity": "sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ==",
+ "version": "0.34.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.2.tgz",
+ "integrity": "sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==",
"cpu": [
"arm64"
],
@@ -27545,9 +27545,9 @@
}
},
"node_modules/@img/sharp-linux-s390x": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.1.tgz",
- "integrity": "sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA==",
+ "version": "0.34.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.2.tgz",
+ "integrity": "sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==",
"cpu": [
"s390x"
],
@@ -27567,9 +27567,9 @@
}
},
"node_modules/@img/sharp-linux-x64": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.1.tgz",
- "integrity": "sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA==",
+ "version": "0.34.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.2.tgz",
+ "integrity": "sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==",
"cpu": [
"x64"
],
@@ -27589,9 +27589,9 @@
}
},
"node_modules/@img/sharp-linuxmusl-arm64": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.1.tgz",
- "integrity": "sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ==",
+ "version": "0.34.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.2.tgz",
+ "integrity": "sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==",
"cpu": [
"arm64"
],
@@ -27611,9 +27611,9 @@
}
},
"node_modules/@img/sharp-linuxmusl-x64": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.1.tgz",
- "integrity": "sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg==",
+ "version": "0.34.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.2.tgz",
+ "integrity": "sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==",
"cpu": [
"x64"
],
@@ -27633,16 +27633,16 @@
}
},
"node_modules/@img/sharp-wasm32": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.1.tgz",
- "integrity": "sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg==",
+ "version": "0.34.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.2.tgz",
+ "integrity": "sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==",
"cpu": [
"wasm32"
],
"license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
"optional": true,
"dependencies": {
- "@emnapi/runtime": "^1.4.0"
+ "@emnapi/runtime": "^1.4.3"
},
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
@@ -27651,10 +27651,29 @@
"url": "https://opencollective.com/libvips"
}
},
+ "node_modules/@img/sharp-win32-arm64": {
+ "version": "0.34.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.2.tgz",
+ "integrity": "sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "Apache-2.0 AND LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
"node_modules/@img/sharp-win32-ia32": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.1.tgz",
- "integrity": "sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw==",
+ "version": "0.34.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.2.tgz",
+ "integrity": "sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==",
"cpu": [
"ia32"
],
@@ -27671,9 +27690,9 @@
}
},
"node_modules/@img/sharp-win32-x64": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.1.tgz",
- "integrity": "sha512-hw1iIAHpNE8q3uMIRCgGOeDoz9KtFNarFLQclLxr/LK1VBkj8nby18RjFvr6aP7USRYAjTZW6yisnBWMX571Tw==",
+ "version": "0.34.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.2.tgz",
+ "integrity": "sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==",
"cpu": [
"x64"
],
@@ -48047,9 +48066,9 @@
}
},
"node_modules/semver": {
- "version": "7.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
- "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"devOptional": true,
"license": "ISC",
"bin": {
@@ -48141,16 +48160,16 @@
"license": "MIT"
},
"node_modules/sharp": {
- "version": "0.34.1",
- "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.1.tgz",
- "integrity": "sha512-1j0w61+eVxu7DawFJtnfYcvSv6qPFvfTaqzTQ2BLknVhHTwGS8sc63ZBF4rzkWMBVKybo4S5OBtDdZahh2A1xg==",
+ "version": "0.34.2",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.2.tgz",
+ "integrity": "sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==",
"hasInstallScript": true,
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"color": "^4.2.3",
- "detect-libc": "^2.0.3",
- "semver": "^7.7.1"
+ "detect-libc": "^2.0.4",
+ "semver": "^7.7.2"
},
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
@@ -48159,8 +48178,8 @@
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-darwin-arm64": "0.34.1",
- "@img/sharp-darwin-x64": "0.34.1",
+ "@img/sharp-darwin-arm64": "0.34.2",
+ "@img/sharp-darwin-x64": "0.34.2",
"@img/sharp-libvips-darwin-arm64": "1.1.0",
"@img/sharp-libvips-darwin-x64": "1.1.0",
"@img/sharp-libvips-linux-arm": "1.1.0",
@@ -48170,15 +48189,16 @@
"@img/sharp-libvips-linux-x64": "1.1.0",
"@img/sharp-libvips-linuxmusl-arm64": "1.1.0",
"@img/sharp-libvips-linuxmusl-x64": "1.1.0",
- "@img/sharp-linux-arm": "0.34.1",
- "@img/sharp-linux-arm64": "0.34.1",
- "@img/sharp-linux-s390x": "0.34.1",
- "@img/sharp-linux-x64": "0.34.1",
- "@img/sharp-linuxmusl-arm64": "0.34.1",
- "@img/sharp-linuxmusl-x64": "0.34.1",
- "@img/sharp-wasm32": "0.34.1",
- "@img/sharp-win32-ia32": "0.34.1",
- "@img/sharp-win32-x64": "0.34.1"
+ "@img/sharp-linux-arm": "0.34.2",
+ "@img/sharp-linux-arm64": "0.34.2",
+ "@img/sharp-linux-s390x": "0.34.2",
+ "@img/sharp-linux-x64": "0.34.2",
+ "@img/sharp-linuxmusl-arm64": "0.34.2",
+ "@img/sharp-linuxmusl-x64": "0.34.2",
+ "@img/sharp-wasm32": "0.34.2",
+ "@img/sharp-win32-arm64": "0.34.2",
+ "@img/sharp-win32-ia32": "0.34.2",
+ "@img/sharp-win32-x64": "0.34.2"
}
},
"node_modules/sharp/node_modules/detect-libc": {