From c5a675c52c701b4dd3365cdbe3bbb647d35470b9 Mon Sep 17 00:00:00 2001
From: YuGilJong <101111364+XionWCFM@users.noreply.github.com>
Date: Tue, 11 Feb 2025 12:08:48 +0900
Subject: [PATCH] feat: add useQueryString | Image Automation (#91)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: querystirng, vite configuration
* feat: image migration
* fix: build error fix
* fix: 자동변환 로직 추가
---
imageConstantsGenerator.mts | 100 ++
package-lock.json | 1216 +++++++++++++++--
package.json | 7 +-
packages/http/index.ts | 6 +-
.../BookRecordWriteProgressStep.tsx | 26 +-
.../components/SearchStep/WriteSearchList.tsx | 16 +-
src/entities/user/api/postUsersTest.ts | 21 +
src/entities/user/model/user.model.ts | 3 +
.../timer/components/TimerSpeechBubble.tsx | 7 +-
src/features/timer/lib/timer.constants.ts | 5 -
src/features/userExp/HabitSection.tsx | 15 +-
src/features/userInfo/UserInfoSection.tsx | 9 +-
src/pages/OnBoardingPage.tsx | 11 +-
src/pages/ProfilePage.tsx | 11 +-
src/pages/TimerPage.tsx | 4 +-
src/shared/hooks/useBooleanQueryString.ts | 19 +
src/shared/hooks/useQueryString.ts | 146 ++
.../images/bookrecord/bookrecordImages.ts | 9 +
src/shared/images/common/commonImages.ts | 6 +
src/shared/images/gauge/gaugeImages.ts | 5 +
src/shared/images/habit/habitImages.ts | 4 +
src/shared/images/home/homeImages.ts | 4 +
src/shared/images/logo/logoImages.ts | 4 +
.../images/notification/notificationImages.ts | 3 +
src/shared/images/timer/timerImages.ts | 5 +
src/shared/images/toast/toastImages.ts | 3 +
tsconfig.app.json | 3 +-
vite.config.ts | 12 +-
28 files changed, 1501 insertions(+), 179 deletions(-)
create mode 100644 imageConstantsGenerator.mts
create mode 100644 src/entities/user/api/postUsersTest.ts
delete mode 100644 src/features/timer/lib/timer.constants.ts
create mode 100644 src/shared/hooks/useBooleanQueryString.ts
create mode 100644 src/shared/hooks/useQueryString.ts
create mode 100644 src/shared/images/bookrecord/bookrecordImages.ts
create mode 100644 src/shared/images/common/commonImages.ts
create mode 100644 src/shared/images/gauge/gaugeImages.ts
create mode 100644 src/shared/images/habit/habitImages.ts
create mode 100644 src/shared/images/home/homeImages.ts
create mode 100644 src/shared/images/logo/logoImages.ts
create mode 100644 src/shared/images/notification/notificationImages.ts
create mode 100644 src/shared/images/timer/timerImages.ts
create mode 100644 src/shared/images/toast/toastImages.ts
diff --git a/imageConstantsGenerator.mts b/imageConstantsGenerator.mts
new file mode 100644
index 0000000..f1eefd9
--- /dev/null
+++ b/imageConstantsGenerator.mts
@@ -0,0 +1,100 @@
+import fs from "node:fs";
+import path from "node:path";
+import sharp from "sharp";
+
+const __dirname = path.dirname(new URL(import.meta.url).pathname);
+
+const publicImagesDir = path.join(__dirname, "public/images");
+const srcDir = path.join(__dirname, "src/shared/images");
+
+// 이미지 파일을 WebP 형식으로 변환하는 함수
+const convertToWebP = async (inputPath: string, outputPath: string) => {
+ try {
+ await sharp(inputPath)
+ .webp({ quality: 80 }) // 80% 품질로 WebP로 변환
+ .toFile(outputPath);
+ } catch (error) {
+ console.error(`Error converting ${inputPath}: ${error}`);
+ }
+};
+
+// 원본 파일 삭제 함수
+const deleteOriginalFile = (filePath: string) => {
+ try {
+ fs.unlinkSync(filePath);
+ } catch (error) {
+ console.error(`Error deleting file: ${filePath} - ${error}`);
+ }
+};
+
+const getImageFiles = (dir: string) => {
+ const files = fs.readdirSync(dir);
+ return files.filter((file) =>
+ ["webp", "png", "jpg", "jpeg"].includes(path.extname(file).slice(1)),
+ );
+};
+
+const toPascalCase = (str: string) => {
+ return str
+ .replace(/([a-zA-Z0-9])([._-])([a-zA-Z0-9])/g, (_match, p1, _p2, p3) => {
+ return `${p1.toUpperCase()}_${p3.toUpperCase()}`;
+ })
+ .replace(/^\w/, (match) => match.toUpperCase())
+ .replace(/[^A-Za-z0-9_]/g, "_")
+ .toUpperCase();
+};
+
+const createTSFile = (folderName: string, images: string[]) => {
+ const folderPath = path.join(srcDir, folderName);
+
+ if (!fs.existsSync(folderPath)) {
+ fs.mkdirSync(folderPath, { recursive: true });
+ }
+
+ const tsFilePath = path.join(folderPath, `${folderName}Images.ts`);
+ const content = `export const ${folderName.toUpperCase()}_ASSETS = {
+${images.map((image) => ` ${toPascalCase(image)}: "/images/${folderName}/${image}"`).join(",\n")}
+};`;
+
+ fs.writeFileSync(tsFilePath, content);
+};
+
+// 이미지를 변환하고, TS 파일을 생성하는 함수
+const processImageFiles = async (folderName: string) => {
+ const imageFiles = getImageFiles(path.join(publicImagesDir, folderName));
+
+ const processedImages: string[] = [];
+
+ for (const imageFile of imageFiles) {
+ const extname = path.extname(imageFile).toLowerCase();
+ const inputPath = path.join(publicImagesDir, folderName, imageFile);
+ const webpFileName = `${path.basename(imageFile, extname)}.webp`;
+ const outputPath = path.join(publicImagesDir, folderName, webpFileName);
+
+ // 이미지가 webp가 아니면 변환
+ if (extname !== ".webp") {
+ await convertToWebP(inputPath, outputPath);
+ processedImages.push(webpFileName); // 변환된 WebP 파일 추가
+ deleteOriginalFile(inputPath); // 원본 파일 삭제
+ } else {
+ processedImages.push(imageFile); // 이미 WebP인 경우 그대로 추가
+ }
+ }
+
+ // 변환이 끝난 후에 코드 생성
+ if (processedImages.length > 0) {
+ createTSFile(folderName, processedImages);
+ }
+};
+
+const generateImageTSFiles = async () => {
+ const subDirs = fs
+ .readdirSync(publicImagesDir)
+ .filter((subDir) => fs.statSync(path.join(publicImagesDir, subDir)).isDirectory());
+
+ for (const subDir of subDirs) {
+ await processImageFiles(subDir);
+ }
+};
+
+generateImageTSFiles();
diff --git a/package-lock.json b/package-lock.json
index 091710e..89711ff 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -80,11 +80,13 @@
"lefthook": "^1.10.1",
"msw": "^2.7.0",
"postcss": "^8.4.49",
+ "sharp": "^0.33.5",
"storybook": "^8.4.7",
"tailwind-merge": "^2.6.0",
"tailwindcss": "^3.4.17",
"tailwindcss-animate": "^1.0.7",
"tailwindcss-animated": "^1.1.2",
+ "tsx": "^4.19.2",
"typescript": "~5.6.2",
"typescript-eslint": "^8.18.2",
"vite": "^6.0.5",
@@ -899,6 +901,17 @@
"node": ">=v18"
}
},
+ "node_modules/@emnapi/runtime": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz",
+ "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@esbuild/aix-ppc64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
@@ -1602,165 +1615,545 @@
"url": "https://github.com/sponsors/nzakas"
}
},
- "node_modules/@inquirer/confirm": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.2.tgz",
- "integrity": "sha512-VKgaKxw2I3cu2smedeMFyxuYyI+HABlFY1Px4j8NueA7xDskKAo9hxEQemTpp1Fu4OiTtOCgU4eK91BVuBKH3g==",
+ "node_modules/@img/sharp-darwin-arm64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz",
+ "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
- "license": "MIT",
- "dependencies": {
- "@inquirer/core": "^10.1.3",
- "@inquirer/type": "^3.0.2"
- },
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
"engines": {
- "node": ">=18"
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
- "peerDependencies": {
- "@types/node": ">=18"
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-arm64": "1.0.4"
}
},
- "node_modules/@inquirer/core": {
- "version": "10.1.3",
- "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.3.tgz",
- "integrity": "sha512-+7/dCYwDku2xfcWJWX6Urxb8aRz6d0K+4lRgIBM08ktE84dm++RPROgnVfWq4hLK5FVu/O4rbO9HnJtaz3pt2w==",
+ "node_modules/@img/sharp-darwin-x64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz",
+ "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
- "license": "MIT",
- "dependencies": {
- "@inquirer/figures": "^1.0.9",
- "@inquirer/type": "^3.0.2",
- "ansi-escapes": "^4.3.2",
- "cli-width": "^4.1.0",
- "mute-stream": "^2.0.0",
- "signal-exit": "^4.1.0",
- "strip-ansi": "^6.0.1",
- "wrap-ansi": "^6.2.0",
- "yoctocolors-cjs": "^2.1.2"
- },
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
"engines": {
- "node": ">=18"
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-x64": "1.0.4"
}
},
- "node_modules/@inquirer/core/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "node_modules/@img/sharp-libvips-darwin-arm64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz",
+ "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@inquirer/figures": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.9.tgz",
- "integrity": "sha512-BXvGj0ehzrngHTPTDqUoDT3NXL8U0RxUk2zJm2A66RhCEIWdtU1v6GuUqNAgArW4PQ9CinqIWyHdQgdwOj06zQ==",
+ "node_modules/@img/sharp-libvips-darwin-x64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz",
+ "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@inquirer/type": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.2.tgz",
- "integrity": "sha512-ZhQ4TvhwHZF+lGhQ2O/rsjo80XoZR5/5qhOY3t6FJuX5XBg5Be8YzYTvaUGJnc12AUGI2nr4QSUE4PhKSigx7g==",
+ "node_modules/@img/sharp-libvips-linux-arm": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz",
+ "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==",
+ "cpu": [
+ "arm"
+ ],
"dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@isaacs/cliui": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
- "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "node_modules/@img/sharp-libvips-linux-arm64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz",
+ "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
- "license": "ISC",
- "dependencies": {
- "string-width": "^5.1.2",
- "string-width-cjs": "npm:string-width@^4.2.0",
- "strip-ansi": "^7.0.1",
- "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
- "wrap-ansi": "^8.1.0",
- "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
- },
- "engines": {
- "node": ">=12"
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
- "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "node_modules/@img/sharp-libvips-linux-s390x": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz",
+ "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==",
+ "cpu": [
+ "s390x"
+ ],
"dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ "url": "https://opencollective.com/libvips"
}
},
- "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
- "version": "9.2.2",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
- "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "node_modules/@img/sharp-libvips-linux-x64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz",
+ "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==",
+ "cpu": [
+ "x64"
+ ],
"dev": true,
- "license": "MIT"
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
},
- "node_modules/@isaacs/cliui/node_modules/string-width": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
- "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz",
+ "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
- "license": "MIT",
- "dependencies": {
- "eastasianwidth": "^0.2.0",
- "emoji-regex": "^9.2.2",
- "strip-ansi": "^7.0.1"
- },
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz",
+ "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "LGPL-3.0-or-later",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz",
+ "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">=12"
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm": "1.0.5"
}
},
- "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
- "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "node_modules/@img/sharp-linux-arm64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz",
+ "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^6.1.0",
- "string-width": "^5.0.1",
- "strip-ansi": "^7.0.1"
- },
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">=12"
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm64": "1.0.4"
}
},
- "node_modules/@istanbuljs/schema": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
- "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "node_modules/@img/sharp-linux-s390x": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz",
+ "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==",
+ "cpu": [
+ "s390x"
+ ],
"dev": true,
- "license": "MIT",
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
"engines": {
- "node": ">=8"
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-s390x": "1.0.4"
}
},
- "node_modules/@joshwooding/vite-plugin-react-docgen-typescript": {
+ "node_modules/@img/sharp-linux-x64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz",
+ "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-x64": "1.0.4"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-arm64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz",
+ "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.0.4"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-x64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz",
+ "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.0.4"
+ }
+ },
+ "node_modules/@img/sharp-wasm32": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz",
+ "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.2.0"
+ },
+ "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.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz",
+ "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "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-x64": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz",
+ "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "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/@inquirer/confirm": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.2.tgz",
+ "integrity": "sha512-VKgaKxw2I3cu2smedeMFyxuYyI+HABlFY1Px4j8NueA7xDskKAo9hxEQemTpp1Fu4OiTtOCgU4eK91BVuBKH3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/core": "^10.1.3",
+ "@inquirer/type": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ }
+ },
+ "node_modules/@inquirer/core": {
+ "version": "10.1.3",
+ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.3.tgz",
+ "integrity": "sha512-+7/dCYwDku2xfcWJWX6Urxb8aRz6d0K+4lRgIBM08ktE84dm++RPROgnVfWq4hLK5FVu/O4rbO9HnJtaz3pt2w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/figures": "^1.0.9",
+ "@inquirer/type": "^3.0.2",
+ "ansi-escapes": "^4.3.2",
+ "cli-width": "^4.1.0",
+ "mute-stream": "^2.0.0",
+ "signal-exit": "^4.1.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^6.2.0",
+ "yoctocolors-cjs": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@inquirer/core/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@inquirer/figures": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.9.tgz",
+ "integrity": "sha512-BXvGj0ehzrngHTPTDqUoDT3NXL8U0RxUk2zJm2A66RhCEIWdtU1v6GuUqNAgArW4PQ9CinqIWyHdQgdwOj06zQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@inquirer/type": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.2.tgz",
+ "integrity": "sha512-ZhQ4TvhwHZF+lGhQ2O/rsjo80XoZR5/5qhOY3t6FJuX5XBg5Be8YzYTvaUGJnc12AUGI2nr4QSUE4PhKSigx7g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ }
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@isaacs/cliui/node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@joshwooding/vite-plugin-react-docgen-typescript": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/@joshwooding/vite-plugin-react-docgen-typescript/-/vite-plugin-react-docgen-typescript-0.4.2.tgz",
"integrity": "sha512-feQ+ntr+8hbVudnsTUapiMN9q8T90XA1d5jn9QzY09sNoj4iD9wi0PY1vsBFTda4ZjEaxRK9S81oarR2nj7TFQ==",
@@ -5406,6 +5799,20 @@
"node": ">=6"
}
},
+ "node_modules/color": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
+ "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1",
+ "color-string": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=12.5.0"
+ }
+ },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -5426,10 +5833,21 @@
"dev": true,
"license": "MIT"
},
- "node_modules/commander": {
- "version": "12.1.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
- "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
+ "node_modules/color-string": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
+ "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "^1.0.0",
+ "simple-swizzle": "^0.2.2"
+ }
+ },
+ "node_modules/commander": {
+ "version": "12.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
+ "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
"license": "MIT",
"engines": {
"node": ">=18"
@@ -5709,6 +6127,16 @@
"node": ">=6"
}
},
+ "node_modules/detect-libc": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
+ "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/detect-node-es": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
@@ -6687,6 +7115,19 @@
"node": ">= 0.4"
}
},
+ "node_modules/get-tsconfig": {
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz",
+ "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
"node_modules/git-raw-commits": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz",
@@ -9051,6 +9492,16 @@
"node": ">=8"
}
},
+ "node_modules/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ }
+ },
"node_modules/reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@@ -9202,6 +9653,46 @@
"node": ">= 0.4"
}
},
+ "node_modules/sharp": {
+ "version": "0.33.5",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz",
+ "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "color": "^4.2.3",
+ "detect-libc": "^2.0.3",
+ "semver": "^7.6.3"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-darwin-arm64": "0.33.5",
+ "@img/sharp-darwin-x64": "0.33.5",
+ "@img/sharp-libvips-darwin-arm64": "1.0.4",
+ "@img/sharp-libvips-darwin-x64": "1.0.4",
+ "@img/sharp-libvips-linux-arm": "1.0.5",
+ "@img/sharp-libvips-linux-arm64": "1.0.4",
+ "@img/sharp-libvips-linux-s390x": "1.0.4",
+ "@img/sharp-libvips-linux-x64": "1.0.4",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.0.4",
+ "@img/sharp-libvips-linuxmusl-x64": "1.0.4",
+ "@img/sharp-linux-arm": "0.33.5",
+ "@img/sharp-linux-arm64": "0.33.5",
+ "@img/sharp-linux-s390x": "0.33.5",
+ "@img/sharp-linux-x64": "0.33.5",
+ "@img/sharp-linuxmusl-arm64": "0.33.5",
+ "@img/sharp-linuxmusl-x64": "0.33.5",
+ "@img/sharp-wasm32": "0.33.5",
+ "@img/sharp-win32-ia32": "0.33.5",
+ "@img/sharp-win32-x64": "0.33.5"
+ }
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -9245,6 +9736,23 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/simple-swizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+ "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-arrayish": "^0.3.1"
+ }
+ },
+ "node_modules/simple-swizzle/node_modules/is-arrayish": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -9863,6 +10371,474 @@
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
+ "node_modules/tsx": {
+ "version": "4.19.2",
+ "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz",
+ "integrity": "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "~0.23.0",
+ "get-tsconfig": "^4.7.5"
+ },
+ "bin": {
+ "tsx": "dist/cli.mjs"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/aix-ppc64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz",
+ "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/android-arm": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz",
+ "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/android-arm64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz",
+ "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/android-x64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz",
+ "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/darwin-arm64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz",
+ "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/darwin-x64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz",
+ "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz",
+ "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/freebsd-x64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz",
+ "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-arm": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz",
+ "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-arm64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz",
+ "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-ia32": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz",
+ "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-loong64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz",
+ "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-mips64el": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz",
+ "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-ppc64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz",
+ "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-riscv64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz",
+ "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-s390x": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz",
+ "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/linux-x64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz",
+ "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/netbsd-x64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz",
+ "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz",
+ "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/openbsd-x64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz",
+ "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/sunos-x64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz",
+ "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/win32-arm64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz",
+ "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/win32-ia32": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz",
+ "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/@esbuild/win32-x64": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz",
+ "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tsx/node_modules/esbuild": {
+ "version": "0.23.1",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz",
+ "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.23.1",
+ "@esbuild/android-arm": "0.23.1",
+ "@esbuild/android-arm64": "0.23.1",
+ "@esbuild/android-x64": "0.23.1",
+ "@esbuild/darwin-arm64": "0.23.1",
+ "@esbuild/darwin-x64": "0.23.1",
+ "@esbuild/freebsd-arm64": "0.23.1",
+ "@esbuild/freebsd-x64": "0.23.1",
+ "@esbuild/linux-arm": "0.23.1",
+ "@esbuild/linux-arm64": "0.23.1",
+ "@esbuild/linux-ia32": "0.23.1",
+ "@esbuild/linux-loong64": "0.23.1",
+ "@esbuild/linux-mips64el": "0.23.1",
+ "@esbuild/linux-ppc64": "0.23.1",
+ "@esbuild/linux-riscv64": "0.23.1",
+ "@esbuild/linux-s390x": "0.23.1",
+ "@esbuild/linux-x64": "0.23.1",
+ "@esbuild/netbsd-x64": "0.23.1",
+ "@esbuild/openbsd-arm64": "0.23.1",
+ "@esbuild/openbsd-x64": "0.23.1",
+ "@esbuild/sunos-x64": "0.23.1",
+ "@esbuild/win32-arm64": "0.23.1",
+ "@esbuild/win32-ia32": "0.23.1",
+ "@esbuild/win32-x64": "0.23.1"
+ }
+ },
"node_modules/turbo-stream": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz",
diff --git a/package.json b/package.json
index 7c8a7bb..fc973fa 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
"version": "0.0.0",
"type": "module",
"scripts": {
- "dev": "vite --host",
+ "dev": "npm run generate:image && vite --host",
"build": "tsc -b && vite build",
"preview": "vite preview",
"storybook": "storybook dev -p 6006",
@@ -14,7 +14,8 @@
"ci:test": "vitest run",
"report": "vitest run --coverage.enabled true",
"ci:check": "npx @biomejs/biome check --config-path=./biome-ci.json --diagnostic-level=error --write .",
- "ci:check:nowrite": "npx @biomejs/biome check --config-path=./biome-ci.json --diagnostic-level=error ."
+ "ci:check:nowrite": "npx @biomejs/biome check --config-path=./biome-ci.json --diagnostic-level=error .",
+ "generate:image": "tsx imageConstantsGenerator.mts"
},
"dependencies": {
"@hookform/resolvers": "^3.9.1",
@@ -89,11 +90,13 @@
"lefthook": "^1.10.1",
"msw": "^2.7.0",
"postcss": "^8.4.49",
+ "sharp": "^0.33.5",
"storybook": "^8.4.7",
"tailwind-merge": "^2.6.0",
"tailwindcss": "^3.4.17",
"tailwindcss-animate": "^1.0.7",
"tailwindcss-animated": "^1.1.2",
+ "tsx": "^4.19.2",
"typescript": "~5.6.2",
"typescript-eslint": "^8.18.2",
"vite": "^6.0.5",
diff --git a/packages/http/index.ts b/packages/http/index.ts
index bfd4708..68fb5a4 100644
--- a/packages/http/index.ts
+++ b/packages/http/index.ts
@@ -3,7 +3,11 @@ import { createHttp } from "./createHttp";
import { isHttpError } from "./error";
import type { ApiSuccessResponse } from "./type";
-const http = createHttp({ prefixUrl: env.VITE_API_URL, retry: { limit: 0 } });
+const http = createHttp({
+ prefixUrl: env.VITE_API_URL,
+ retry: { limit: 0 },
+ credentials: "include",
+});
export { createHttp, isHttpError, http };
diff --git a/src/entities/record/components/ProgressStep/BookRecordWriteProgressStep.tsx b/src/entities/record/components/ProgressStep/BookRecordWriteProgressStep.tsx
index 00a6eaa..4d7a1e5 100644
--- a/src/entities/record/components/ProgressStep/BookRecordWriteProgressStep.tsx
+++ b/src/entities/record/components/ProgressStep/BookRecordWriteProgressStep.tsx
@@ -9,6 +9,7 @@ import { Stack } from "@repo/ui/Stack";
import { useDraft } from "@xionwcfm/react";
import { memo } from "react";
import { getGaugeMessage } from "~/entities/record/model/record.constants";
+import { GAUGE_ASSETS } from "~/shared/images/gauge/gaugeImages";
export interface BookRecordWriteProgressStepProps {
gauge?: number;
@@ -79,8 +80,12 @@ const ImageSection = memo((props: { status: "0" | "50" | "100"; value: number })
key={"0"}
transition={{ duration: GAUGE_DURATION_POLICY, ease: GAUGE_EASE_POLICY }}
>
-
-
+
+
{props.value}%
@@ -90,7 +95,11 @@ const ImageSection = memo((props: { status: "0" | "50" | "100"; value: number })
key={"50"}
transition={{ duration: GAUGE_DURATION_POLICY, ease: GAUGE_EASE_POLICY }}
>
-
+
{props.value}%
@@ -101,7 +110,11 @@ const ImageSection = memo((props: { status: "0" | "50" | "100"; value: number })
key={"100"}
transition={{ duration: GAUGE_DURATION_POLICY, ease: GAUGE_EASE_POLICY }}
>
-
+
{props.value}%
@@ -115,11 +128,6 @@ const ImageSection = memo((props: { status: "0" | "50" | "100"; value: number })
const GAUGE_DURATION_POLICY = 0.3; // 300ms duration
const GAUGE_EASE_POLICY = "easeOut" as const;
-const GAUGE_ASSETS = {
- "0": "/images/gauge/gauge_0.webp",
- "50": "/images/gauge/gauge_50.webp",
- "100": "/images/gauge/gauge_100.webp",
-};
const getStatus = (value: number) => {
if (value >= 70) {
diff --git a/src/entities/record/components/SearchStep/WriteSearchList.tsx b/src/entities/record/components/SearchStep/WriteSearchList.tsx
index 4033714..be320f7 100644
--- a/src/entities/record/components/SearchStep/WriteSearchList.tsx
+++ b/src/entities/record/components/SearchStep/WriteSearchList.tsx
@@ -10,6 +10,7 @@ import { useInfiniteQuery } from "@tanstack/react-query";
import { InView } from "@xionwcfm/react";
import { getBooksSearchInfiniteQueryOptions } from "~/entities/record/api/getBooksSearch";
import type { Book } from "~/entities/record/model/book.model";
+import { BOOKRECORD_ASSETS } from "~/shared/images/bookrecord/bookrecordImages";
import { SearchBookItem } from "./WriteSearchBookItem";
import { useWriteSearchStore } from "./WriteSearchStep.store";
@@ -65,11 +66,6 @@ export const WriteSearchList = wrap.Suspense().on(
},
);
-const SEARCH_ASSETS = {
- FIRST_FALLBACK: "/images/bookrecord/bookrecord_search_empty_fallback.webp",
- SEARCH_RESULT_EMPTY_FALLBACK: "/images/bookrecord/bookrecord_tab_no_search_result_fallback.webp",
-};
-
const FirstFallback = (props: { isLoading?: boolean }) => {
const { isLoading } = props;
return (
@@ -81,7 +77,10 @@ const FirstFallback = (props: { isLoading?: boolean }) => {
)}
>
-
+
{
-
+
diff --git a/src/entities/user/api/postUsersTest.ts b/src/entities/user/api/postUsersTest.ts
new file mode 100644
index 0000000..e49fcce
--- /dev/null
+++ b/src/entities/user/api/postUsersTest.ts
@@ -0,0 +1,21 @@
+import { http } from "@repo/http";
+
+type PostUsersTestRequestBody = {
+ email: string;
+ isShortLivedAccessToken?: boolean;
+};
+
+type PostUsersTestResponse = {
+ id: number | string;
+ nickname: string;
+ email: string;
+ exp: number;
+};
+
+export const postUsersTest = async (body: PostUsersTestRequestBody) => {
+ const response = await http.post(
+ "/users/test",
+ body,
+ );
+ return response.data;
+};
diff --git a/src/entities/user/model/user.model.ts b/src/entities/user/model/user.model.ts
index 84e80df..b8975cb 100644
--- a/src/entities/user/model/user.model.ts
+++ b/src/entities/user/model/user.model.ts
@@ -1,4 +1,7 @@
export interface User {
+ id: number | string;
+ nickname: string;
+ email: string;
exp: number;
}
diff --git a/src/features/timer/components/TimerSpeechBubble.tsx b/src/features/timer/components/TimerSpeechBubble.tsx
index 5ce4f8b..731d23a 100644
--- a/src/features/timer/components/TimerSpeechBubble.tsx
+++ b/src/features/timer/components/TimerSpeechBubble.tsx
@@ -4,8 +4,8 @@ import { Text } from "@repo/design-system/Text";
import { cn } from "@repo/design-system/cn";
import { Box } from "@repo/ui/Box";
import type { ComponentPropsWithoutRef } from "react";
+import { TIMER_ASSETS } from "~/shared/images/timer/timerImages";
import { getTimerSpeechBubbleText } from "../lib/getTimerSpeechBubbleText";
-import { TIMER_ASSETS } from "../lib/timer.constants";
import { useTimerStore } from "../model/TimerProvider";
interface TimerSpeechBubbleProps extends ComponentPropsWithoutRef<"div"> {}
@@ -17,7 +17,10 @@ export const TimerSpeechBubble = (props: Omit
-
+
{
const { normalText, boldText } = props;
return (
@@ -172,14 +172,18 @@ const TodayHabit = () => {
{"6일 연속 \n성공했어요!"}
-
+
{
>
);
};
-
-const HABIIT_ASSETS = {
- LOGO: "/images/habit/mercury_habit_logo.webp",
- BLOCK: "/images/habit/habit_block.webp",
-};
diff --git a/src/features/userInfo/UserInfoSection.tsx b/src/features/userInfo/UserInfoSection.tsx
index 650a039..439c6f4 100644
--- a/src/features/userInfo/UserInfoSection.tsx
+++ b/src/features/userInfo/UserInfoSection.tsx
@@ -10,6 +10,7 @@ import { motion } from "motion/react";
import { useTestUserQueryOptions } from "~/entities/user/api/getTestUser";
import { ExpProgressBar } from "~/entities/user/components/ExpProgressBar";
import { calculateUserLevel, getExpPercentage, getGoalExp } from "~/entities/user/model/user.model";
+import { HOME_ASSETS } from "~/shared/images/home/homeImages";
const ExpSection = (props: { exp: number; goalExp: number; percentage: number; level: string }) => {
const { exp, goalExp, percentage, level } = props;
@@ -45,7 +46,7 @@ const Fallback = () => {
머큐리와 함께한 지 000일
-
+
@@ -90,7 +91,7 @@ export const MainSection = wrap
);
});
-
-const HOME_ASSETS = {
- HOME_MERCURY: "/images/home/home_mercury.webp",
-};
diff --git a/src/pages/OnBoardingPage.tsx b/src/pages/OnBoardingPage.tsx
index 04f4448..ec4a19d 100644
--- a/src/pages/OnBoardingPage.tsx
+++ b/src/pages/OnBoardingPage.tsx
@@ -1,6 +1,7 @@
import { AspectRatio } from "@repo/design-system/AspectRatio";
import { Image } from "@repo/design-system/Image";
import { Text, textVariants } from "@repo/design-system/Text";
+
import { toast } from "@repo/design-system/Toast";
import { cn } from "@repo/design-system/cn";
import { Center } from "@repo/ui/Center";
@@ -9,6 +10,7 @@ import { Flex } from "@repo/ui/Flex";
import { Spacing } from "@repo/ui/Spacing";
import { Stack } from "@repo/ui/Stack";
import { Link } from "react-router";
+import { LOGO_ASSETS } from "~/shared/images/logo/logoImages";
import { AppleButton } from "~/shared/ui/AppleButton";
import { GoogleButton } from "~/shared/ui/GoogleButton";
import { KakaoButton } from "~/shared/ui/KakaoButton";
@@ -27,13 +29,13 @@ const MercuryImageSection = () => {
-
+
@@ -71,8 +73,3 @@ const SignUpSection = () => {
);
};
-
-const ONBOARDING_ASSETS = {
- MERCURY_LOGIN_LOGO: "/images/logo/mercury_login_logo.webp",
- WORDMARKLOGO_DARKBG: "/images/logo/wordmarklogo_darkbg.webp",
-};
diff --git a/src/pages/ProfilePage.tsx b/src/pages/ProfilePage.tsx
index 71d8c9b..c4cf8de 100644
--- a/src/pages/ProfilePage.tsx
+++ b/src/pages/ProfilePage.tsx
@@ -2,6 +2,7 @@ import { AspectRatio } from "@repo/design-system/AspectRatio";
import { Image } from "@repo/design-system/Image";
import { Stack } from "@repo/ui/Stack";
import { motion } from "motion/react";
+import { LOGO_ASSETS } from "~/shared/images/logo/logoImages";
export default function Page() {
return (
@@ -20,7 +21,11 @@ export default function Page() {
transition={{ duration: 1.5, delay: 0.8 }}
>
-
+
);
}
-
-const PROFILE_ASSETS = {
- PROFILE_LOGO: "/images/logo/mercury_login_logo.webp",
-};
diff --git a/src/pages/TimerPage.tsx b/src/pages/TimerPage.tsx
index fbe9a35..b418ea4 100644
--- a/src/pages/TimerPage.tsx
+++ b/src/pages/TimerPage.tsx
@@ -9,8 +9,8 @@ import { TimerButtonSection } from "~/features/timer/components/TimerButtonSecti
import { TimerDescription } from "~/features/timer/components/TimerDescription";
import { TimerSpeechBubble } from "~/features/timer/components/TimerSpeechBubble";
import { TimerText } from "~/features/timer/components/TimerText";
-import { TIMER_ASSETS } from "~/features/timer/lib/timer.constants";
import { TimerEffector } from "~/features/timer/model/TimerEffector";
+import { TIMER_ASSETS } from "~/shared/images/timer/timerImages";
export default function TimerPage() {
return (
@@ -32,7 +32,7 @@ export default function TimerPage() {
-
+
diff --git a/src/shared/hooks/useBooleanQueryString.ts b/src/shared/hooks/useBooleanQueryString.ts
new file mode 100644
index 0000000..a631a5a
--- /dev/null
+++ b/src/shared/hooks/useBooleanQueryString.ts
@@ -0,0 +1,19 @@
+import { useCallback } from "react";
+import { useQueryString } from "~/shared/hooks/useQueryString";
+
+export const useBooleanQueryString = (key: string, initialValue: boolean) => {
+ const [query, setQuery] = useQueryString({ [key]: initialValue }, { dependencies: [key] });
+
+ const onOpenChange = useCallback(
+ (bool: boolean) => {
+ setQuery({ [key]: bool });
+ },
+ [setQuery, key],
+ );
+
+ const toggle = useCallback(() => {
+ setQuery({ [key]: !query[key] });
+ }, [setQuery, query, key]);
+
+ return [query[key] ?? initialValue, onOpenChange, toggle] as const;
+};
diff --git a/src/shared/hooks/useQueryString.ts b/src/shared/hooks/useQueryString.ts
new file mode 100644
index 0000000..e8ddeb0
--- /dev/null
+++ b/src/shared/hooks/useQueryString.ts
@@ -0,0 +1,146 @@
+import { useRef, useSyncExternalStore } from "react";
+
+type UseQueryStringProps = Record;
+
+export const useQueryString = (
+ initialValue: T,
+ options?: { dependencies?: Array },
+) => {
+ const lastSnapshot = useRef(null);
+ const lastSearch = useRef(null);
+
+ const getSnapshot = (): T => {
+ const currentSearch = window.location.search;
+
+ // 이전 검색 문자열과 동일하면 캐시된 스냅샷 반환
+ if (lastSearch.current === currentSearch && lastSnapshot.current) {
+ return lastSnapshot.current;
+ }
+
+ const params = new URLSearchParams(currentSearch);
+ const obj: Partial = { ...initialValue };
+
+ params.forEach((value, key) => {
+ if (key in initialValue) {
+ const initialType = typeof initialValue[key as keyof T];
+ //@ts-ignore
+ obj[key as keyof T] =
+ initialType === "number"
+ ? (Number(value) as T[keyof T])
+ : initialType === "boolean"
+ ? value === ("true" as T[keyof T])
+ : (value as T[keyof T]);
+ }
+ });
+
+ // 새로운 스냅샷과 검색 문자열 캐시
+ lastSnapshot.current = obj as T;
+ lastSearch.current = currentSearch;
+
+ return obj as T;
+ };
+
+ const getServerSnapshot = (): T => initialValue;
+
+ const subscribe = (callback: () => void) => {
+ let previousValues: Partial = {};
+
+ if (options?.dependencies) {
+ const currentValues = getSnapshot();
+ previousValues = options.dependencies.reduce(
+ (acc, key) => {
+ acc[key] = currentValues[key];
+ return acc;
+ },
+ {} as Partial,
+ );
+ }
+
+ const onChange = () => {
+ if (options?.dependencies) {
+ const currentValues = getSnapshot();
+ const hasChanges = options.dependencies.some(
+ (key) => !isEqual(previousValues[key], currentValues[key]),
+ );
+
+ if (hasChanges) {
+ previousValues = options.dependencies.reduce(
+ (acc, key) => {
+ acc[key] = currentValues[key];
+ return acc;
+ },
+ {} as Partial,
+ );
+ callback();
+ }
+ } else {
+ callback();
+ }
+ };
+
+ window.addEventListener("popstate", onChange);
+
+ const patchHistoryMethod = (method: "pushState" | "replaceState") => {
+ const original = history[method];
+ history[method] = function (...args) {
+ original.apply(this, args);
+ onChange();
+ };
+ };
+
+ patchHistoryMethod("pushState");
+ patchHistoryMethod("replaceState");
+
+ return () => {
+ window.removeEventListener("popstate", onChange);
+ };
+ };
+
+ const query = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
+
+ const setQuery = (newState: Partial, options: { replace?: boolean } = {}) => {
+ const params = new URLSearchParams(window.location.search);
+
+ Object.entries(newState).forEach(([key, value]) => {
+ if (value === undefined || value === null) {
+ params.delete(key);
+ } else {
+ params.set(key, String(value));
+ }
+ });
+
+ const newUrl = `${window.location.pathname}?${params.toString()}`;
+
+ if (options.replace) {
+ window.history.replaceState({}, "", newUrl);
+ } else {
+ window.history.pushState({}, "", newUrl);
+ }
+
+ window.dispatchEvent(new Event("popstate")); // 강제 상태 업데이트
+ };
+
+ return [query, setQuery] as const;
+};
+
+function isEqual(a: any, b: any): boolean {
+ if (a === b) {
+ return true;
+ }
+ if (typeof a !== typeof b) {
+ return false;
+ }
+
+ if (typeof a === "object") {
+ const aEntries = Object.entries(a);
+ const bEntries = Object.entries(b);
+
+ if (aEntries.length !== bEntries.length) {
+ return false;
+ }
+
+ return aEntries.every(([key, value]) => b[key as any] === value);
+ }
+
+ return false;
+}
diff --git a/src/shared/images/bookrecord/bookrecordImages.ts b/src/shared/images/bookrecord/bookrecordImages.ts
new file mode 100644
index 0000000..e95b652
--- /dev/null
+++ b/src/shared/images/bookrecord/bookrecordImages.ts
@@ -0,0 +1,9 @@
+export const BOOKRECORD_ASSETS = {
+ BOOKRECORD_SEARCH_EMPTY_FALLBACK_WEBP: "/images/bookrecord/bookrecord_search_empty_fallback.webp",
+ BOOKRECORD_TAB_EMPTY_FALLBACK_WEBP: "/images/bookrecord/bookrecord_tab_empty_fallback.webp",
+ BOOKRECORD_TAB_NO_RECORD_RESULT_FALLBACK_WEBP:
+ "/images/bookrecord/bookrecord_tab_no_record_result_fallback.webp",
+ BOOKRECORD_TAB_NO_SEARCH_RESULT_FALLBACK_WEBP:
+ "/images/bookrecord/bookrecord_tab_no_search_result_fallback.webp",
+ FLOATING_ICON_WEBP: "/images/bookrecord/floating_icon.webp",
+};
diff --git a/src/shared/images/common/commonImages.ts b/src/shared/images/common/commonImages.ts
new file mode 100644
index 0000000..b09e1c4
--- /dev/null
+++ b/src/shared/images/common/commonImages.ts
@@ -0,0 +1,6 @@
+export const COMMON_ASSETS = {
+ APPLE_BUTTON_WEBP: "/images/common/apple_button.webp",
+ GOOGLE_BUTTON_WEBP: "/images/common/google_button.webp",
+ KAKAO_BUTTON_WEBP: "/images/common/kakao_button.webp",
+ POLYGON_YELLOW_GREEN_WEBP: "/images/common/polygon_yellow_green.webp",
+};
diff --git a/src/shared/images/gauge/gaugeImages.ts b/src/shared/images/gauge/gaugeImages.ts
new file mode 100644
index 0000000..e473a9e
--- /dev/null
+++ b/src/shared/images/gauge/gaugeImages.ts
@@ -0,0 +1,5 @@
+export const GAUGE_ASSETS = {
+ GAUGE_0_WEBP: "/images/gauge/gauge_0.webp",
+ GAUGE_100_WEBP: "/images/gauge/gauge_100.webp",
+ GAUGE_50_WEBP: "/images/gauge/gauge_50.webp",
+};
diff --git a/src/shared/images/habit/habitImages.ts b/src/shared/images/habit/habitImages.ts
new file mode 100644
index 0000000..374130c
--- /dev/null
+++ b/src/shared/images/habit/habitImages.ts
@@ -0,0 +1,4 @@
+export const HABIT_ASSETS = {
+ HABIT_BLOCK_WEBP: "/images/habit/habit_block.webp",
+ MERCURY_HABIT_LOGO_WEBP: "/images/habit/mercury_habit_logo.webp",
+};
diff --git a/src/shared/images/home/homeImages.ts b/src/shared/images/home/homeImages.ts
new file mode 100644
index 0000000..c7e798c
--- /dev/null
+++ b/src/shared/images/home/homeImages.ts
@@ -0,0 +1,4 @@
+export const HOME_ASSETS = {
+ HOME_LOGO_WEBP: "/images/home/home_logo.webp",
+ HOME_MERCURY_WEBP: "/images/home/home_mercury.webp",
+};
diff --git a/src/shared/images/logo/logoImages.ts b/src/shared/images/logo/logoImages.ts
new file mode 100644
index 0000000..3eef70b
--- /dev/null
+++ b/src/shared/images/logo/logoImages.ts
@@ -0,0 +1,4 @@
+export const LOGO_ASSETS = {
+ MERCURY_LOGIN_LOGO_WEBP: "/images/logo/mercury_login_logo.webp",
+ WORDMARKLOGO_DARKBG_WEBP: "/images/logo/wordmarklogo_darkbg.webp",
+};
diff --git a/src/shared/images/notification/notificationImages.ts b/src/shared/images/notification/notificationImages.ts
new file mode 100644
index 0000000..95a8ccb
--- /dev/null
+++ b/src/shared/images/notification/notificationImages.ts
@@ -0,0 +1,3 @@
+export const NOTIFICATION_ASSETS = {
+ NOTIFICATION_EMPTY_WEBP: "/images/notification/notification_empty.webp",
+};
diff --git a/src/shared/images/timer/timerImages.ts b/src/shared/images/timer/timerImages.ts
new file mode 100644
index 0000000..331f3cc
--- /dev/null
+++ b/src/shared/images/timer/timerImages.ts
@@ -0,0 +1,5 @@
+export const TIMER_ASSETS = {
+ TIMER_CHARACTER_WEBP: "/images/timer/timer_character.webp",
+ TIMER_SPEECH_BUBBLE_BG_WEBP: "/images/timer/timer_speech_bubble_bg.webp",
+ TIMER_THUMB_WEBP: "/images/timer/timer_thumb.webp",
+};
diff --git a/src/shared/images/toast/toastImages.ts b/src/shared/images/toast/toastImages.ts
new file mode 100644
index 0000000..890896d
--- /dev/null
+++ b/src/shared/images/toast/toastImages.ts
@@ -0,0 +1,3 @@
+export const TOAST_ASSETS = {
+ TOAST_MERCURY_ICON_WEBP: "/images/toast/toast_mercury_icon.webp",
+};
diff --git a/tsconfig.app.json b/tsconfig.app.json
index 2094155..ad62e85 100644
--- a/tsconfig.app.json
+++ b/tsconfig.app.json
@@ -30,6 +30,7 @@
"vitest.config.mts",
".storybook/Configure.mdx",
"__tests__",
- ".storybook/**/*.tsx"
+ ".storybook/**/*.tsx",
+ "vite.config.ts"
]
}
diff --git a/vite.config.ts b/vite.config.ts
index 5b08c0c..8702216 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,7 +1,11 @@
import react from "@vitejs/plugin-react-swc";
-import { defineConfig } from "vite";
+import { defineConfig, loadEnv } from "vite";
import tsConfigPaths from "vite-tsconfig-paths";
-export default defineConfig({
- plugins: [react(), tsConfigPaths()],
-});
+export default ({ mode }: { mode: string }) => {
+ process.env = { ...process.env, ...loadEnv(mode, process.cwd()) };
+ return defineConfig({
+ plugins: [react(), tsConfigPaths()],
+ server: {},
+ });
+};