Vitron-Front/package.json
Arda Samadi bac93568f5 feat(upload): convert HEIC/HEIF to JPEG on the client before preview/upload
Most browsers (everything but Safari/WebKit) can't decode HEIC in <img> or
canvas, so picking an iPhone HEIC photo broke the preview and the crop editor,
and could reach the backend in a format it couldn't process. Convert HEIC/HEIF
to JPEG right after selection via heic2any (dynamically imported, browser-only).

- new util app/utils/convert-heic.ts: isHeic() detection (MIME or extension
  when iOS reports no type) + convertHeicToJpeg()/convertHeicFiles(); never
  throws — falls back to the original file on failure.
- wired into the product image picker (store.add.manual) and the store
  logo picker (StoreForm).
- adds heic2any dependency.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 16:43:30 +03:30

90 lines
2.9 KiB
JSON

{
"name": "vitrown",
"private": true,
"sideEffects": false,
"type": "module",
"scripts": {
"build": "remix vite:build",
"build:dev": "NODE_ENV=development remix vite:build --mode development",
"build:fast": "NODE_ENV=development VITE_BUILD_TARGET=development remix vite:build --mode development --minify false",
"dev": "remix vite:dev",
"lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
"generate:types": "bash ./generate-types.sh",
"generate:types:win": "powershell -ExecutionPolicy Bypass -File ./generate-types.ps1",
"start": "remix-serve ./build/server/index.js",
"typecheck": "tsc"
},
"dependencies": {
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@radix-ui/react-dialog": "^1.1.6",
"@radix-ui/react-dropdown-menu": "^2.1.14",
"@radix-ui/react-label": "^2.1.2",
"@radix-ui/react-popover": "^1.1.6",
"@radix-ui/react-radio-group": "^1.2.3",
"@radix-ui/react-select": "^2.1.6",
"@radix-ui/react-slider": "^1.3.4",
"@radix-ui/react-slot": "^1.1.2",
"@radix-ui/react-switch": "^1.2.5",
"@radix-ui/react-toast": "^1.2.6",
"@remix-run/node": "^2.17.2",
"@remix-run/react": "^2.16.0",
"@remix-run/serve": "^2.16.0",
"@tanstack/react-query": "^5.66.11",
"@tanstack/react-query-devtools": "^5.66.11",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"embla-carousel-react": "^8.5.2",
"framer-motion": "^12.4.10",
"heic2any": "^0.0.4",
"i18next": "^24.2.2",
"i18next-browser-languagedetector": "^8.0.4",
"i18next-http-backend": "^3.0.2",
"input-otp": "^1.4.2",
"isbot": "^4.1.0",
"jalali-moment": "^3.3.11",
"leaflet": "^1.9.4",
"lucide-react": "^0.477.0",
"moment-jalaali": "^0.10.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^15.4.1",
"react-leaflet": "^4.2.1",
"remix-auth": "^3.6.0",
"remix-auth-form": "^1.4.0",
"tailwind-merge": "^3.0.2",
"tailwindcss-animate": "^1.0.7",
"universal-cookie": "^7.2.2",
"vaul": "^1.1.2",
"zustand": "^5.0.3"
},
"devDependencies": {
"@remix-run/dev": "^2.16.0",
"@types/leaflet": "^1.9.17",
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"autoprefixer": "^10.4.19",
"eslint": "^8.38.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"glob": "^11.0.3",
"postcss": "^8.4.38",
"rollup": "^4.52.5",
"sharp": "^0.34.3",
"tailwindcss": "^3.4.4",
"terser": "^5.43.1",
"typescript": "^5.9.2",
"vite": "^6.0.0",
"vite-tsconfig-paths": "^4.2.1"
},
"engines": {
"node": ">=20.0.0"
}
}