diff --git a/.env.example b/.env.example index e9fce39..8a3dfc8 100644 --- a/.env.example +++ b/.env.example @@ -10,7 +10,7 @@ GH_ACCESS_TOKEN=---gh_access_token--- GOOGLE_SITE_VERIFICATION=---example-value--- GOOGLE_ANALYTICS=---example-value--- YANDEX_VERIFICATION=---example-value--- -EMAIL_PROVIDER="resend" +EMAIL_PROVIDER=provider_name RESEND_API_KEY=---resend_api_key--- RESEND_AUDIENCE_ID=---example-value--- RESEND_FROM_EMAIL=noreply@example.com diff --git a/.husky/pre-commit b/.husky/pre-commit index 245aa79..73ba06e 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -76,11 +76,11 @@ run_command() { return 1 fi else - echo -e "${RED}❌ yarn, pnpm veya npm bulunamadı${NC}" + echo -e "${RED}❌ yarn, pnpm or npm not found${NC}" return 1 fi - echo -e "${GREEN}✅ $command başarıyla tamamlandı${NC}" + echo -e "${GREEN}✅ $command successfully completed${NC}" return 0 } @@ -154,26 +154,29 @@ fi echo -e "\n${YELLOW}🔒 Sanitizing .env file before commit...${NC}" -# .env dosyası var mı kontrol et +# Check if .env file exists if [ -f .env ]; then echo -e "${BLUE}📝 Creating/updating .env.example with sanitized values...${NC}" - # Farklı değişken türleri için özel örnek değerler + # Specific example values for different variable types cat .env | while IFS='=' read -r key value; do - # Boş satırları atla + # Skip empty lines if [ -z "$key" ]; then echo "" continue fi - # Yorum satırlarını koru + # Preserve comment lines if echo "$key" | grep -q '^#'; then echo "$key" continue fi - # Değişken adına göre özel örnek değerler + # Specific example values based on variable name case "$key" in + *PROVIDER) + echo "${key}=provider_name" + ;; *API_KEY*|*SECRET*|*TOKEN*|*PASSWORD*) echo "${key}=---$(echo ${key} | tr '[:upper:]' '[:lower:]')---" ;; diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 16aff21..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,26 +0,0 @@ -# [1.3.0](https://github.com/nitrokit/nitrokit-nextjs/compare/v1.2.0...v1.3.0) (2025-10-11) - - -### Features - -* Adds 404 page with i18n support ([cd42e6d](https://github.com/nitrokit/nitrokit-nextjs/commit/cd42e6df3e6d21c0f3cc4be676b99205fdd8a807)) - -# [1.2.0](https://github.com/nitrokit/nitrokit-nextjs/compare/v1.1.0...v1.2.0) (2025-10-11) - -### Features - -- Adds Vercel badge to README ([aa5e217](https://github.com/nitrokit/nitrokit-nextjs/commit/aa5e217c930486d9a3b61cdb9c3ee58f01d3e2e1)) -- Configures dev environment with Docker ([de2fb06](https://github.com/nitrokit/nitrokit-nextjs/commit/de2fb06501a04a7df686dc0a4ce3ce9c0b21e961)) -- Enhances user session management ([32b5e01](https://github.com/nitrokit/nitrokit-nextjs/commit/32b5e0184f755d285b0c6fd8edc3f4910a497987)) - -# [1.1.0](https://github.com/nitrokit/nitrokit-nextjs/compare/v1.0.0...v1.1.0) (2025-10-10) - -### Features - -- Enhances documentation with CLI info ([ecc4372](https://github.com/nitrokit/nitrokit-nextjs/commit/ecc4372f1934e1a0edfba68c262e86042774648f)) - -# 1.0.0 (2025-10-10) - -### Features - -- first release of the application ([10dbd9a](https://github.com/nitrokit/nitrokit-nextjs/commit/10dbd9aa1da4edb60632f5b0facea5fd01454c33)) diff --git a/eslint.config.mjs b/eslint.config.mjs index 0b4a549..488b696 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -63,7 +63,9 @@ const eslintConfig = [ { argsIgnorePattern: '^_', varsIgnorePattern: '^_' } ], '@typescript-eslint/require-await': 'error', - '@typescript-eslint/no-misused-promises': process.env.CI ? 'error' : 'off', + '@typescript-eslint/no-misused-promises': 'error', + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': 'error', 'prefer-const': 'error', 'prettier/prettier': [ 'error', diff --git a/next.config.ts b/next.config.ts index 04e9dbe..b6dc024 100644 --- a/next.config.ts +++ b/next.config.ts @@ -10,6 +10,7 @@ const withNextIntl = createNextIntlPlugin({ const config: NextConfig = { trailingSlash: true, + typedRoutes: true, images: { remotePatterns: [ { @@ -20,9 +21,6 @@ const config: NextConfig = { } ] }, - eslint: { - ignoreDuringBuilds: true - }, async headers() { return [ { diff --git a/package.json b/package.json index 3322c0d..6b48eb4 100644 --- a/package.json +++ b/package.json @@ -54,8 +54,7 @@ "test:e2e:ui": "playwright test --ui", "test:e2e:debug": "playwright test --debug", "test:e2e:report": "playwright show-report", - "doppler:upload": "doppler secrets upload .env", - "env:sanitize": "echo '🔒 Sanitizing .env file...' && if [ -f .env ]; then cat .env | while IFS='=' read -r key value; do if [ -z \"$key\" ]; then echo \"\"; continue; fi; if echo \"$key\" | grep -q '^#'; then echo \"$key\"; continue; fi; case \"$key\" in *API_KEY*|*SECRET*|*TOKEN*|*PASSWORD*) echo \"${key}=---$(echo ${key} | tr '[:upper:]' '[:lower:]')---\" ;; *URL*|*ENDPOINT*) echo \"${key}=https://example.com/api\" ;; *PORT*) echo \"${key}=3000\" ;; *DATABASE*|*DB*) echo \"${key}=postgresql://user:password@localhost:5432/database\" ;; *EMAIL*) echo \"${key}=noreply@example.com\" ;; *DOMAIN*|*HOST*) echo \"${key}=localhost\" ;; *DEBUG*|*LOG*|*VERBOSE*) echo \"${key}=false\" ;; *ENV*|*NODE_ENV*) echo \"${key}=development\" ;; *) echo \"${key}=---example-value---\" ;; esac; done > .env.example && echo '✅ .env.example created/updated'; else echo '⚠️ .env file not found'; fi" + "doppler:upload": "doppler secrets upload .env" }, "dependencies": { "@auth/prisma-adapter": "^2.11.0", @@ -133,7 +132,7 @@ "@testing-library/react": "^16.3.0", "@testing-library/user-event": "^14.6.1", "@types/canvas-confetti": "^1.9.0", - "@types/node": "^24.7.1", + "@types/node": "^24.7.2", "@types/react": "^19.2.2", "@types/react-dom": "^19.2.1", "@types/rtl-detect": "^1.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8fab325..e700af4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -229,8 +229,8 @@ importers: specifier: ^1.9.0 version: 1.9.0 '@types/node': - specifier: ^24.7.1 - version: 24.7.1 + specifier: ^24.7.2 + version: 24.7.2 '@types/react': specifier: ^19.2.2 version: 19.2.2 @@ -248,13 +248,13 @@ importers: version: 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) '@vitejs/plugin-react': specifier: ^5.0.4 - version: 5.0.4(vite@7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2)) + version: 5.0.4(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)) '@vitest/browser': specifier: ^3.2.4 - version: 3.2.4(msw@2.11.5(@types/node@24.7.1)(typescript@5.9.3))(playwright@1.56.0)(vite@7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2))(vitest@3.2.4) + version: 3.2.4(msw@2.11.5(@types/node@24.7.2)(typescript@5.9.3))(playwright@1.56.0)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2))(vitest@3.2.4) '@vitest/coverage-v8': specifier: ^3.2.4 - version: 3.2.4(@vitest/browser@3.2.4(msw@2.11.5(@types/node@24.7.1)(typescript@5.9.3))(playwright@1.56.0)(vite@7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2))(vitest@3.2.4))(vitest@3.2.4(@types/node@24.7.1)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.11.5(@types/node@24.7.1)(typescript@5.9.3))) + version: 3.2.4(@vitest/browser@3.2.4(msw@2.11.5(@types/node@24.7.2)(typescript@5.9.3))(playwright@1.56.0)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2))(vitest@3.2.4))(vitest@3.2.4(@types/node@24.7.2)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.11.5(@types/node@24.7.2)(typescript@5.9.3))) '@vitest/ui': specifier: ^3.2.4 version: 3.2.4(vitest@3.2.4) @@ -299,13 +299,13 @@ importers: version: 24.2.9(typescript@5.9.3) shadcn: specifier: ^3.4.0 - version: 3.4.0(@types/node@24.7.1)(typescript@5.9.3) + version: 3.4.0(@types/node@24.7.2)(typescript@5.9.3) tailwindcss: specifier: ^4.1.14 version: 4.1.14 ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@24.7.1)(typescript@5.9.3) + version: 10.9.2(@types/node@24.7.2)(typescript@5.9.3) tw-animate-css: specifier: ^1.4.0 version: 1.4.0 @@ -314,10 +314,10 @@ importers: version: 5.9.3 vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2)) + version: 5.1.4(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)) vitest: specifier: ^3.2.4 - version: 3.2.4(@types/node@24.7.1)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.11.5(@types/node@24.7.1)(typescript@5.9.3)) + version: 3.2.4(@types/node@24.7.2)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.11.5(@types/node@24.7.2)(typescript@5.9.3)) packages: @@ -2824,8 +2824,8 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@24.7.1': - resolution: {integrity: sha512-CmyhGZanP88uuC5GpWU9q+fI61j2SkhO3UGMUdfYRE6Bcy0ccyzn1Rqj9YAB/ZY4kOXmNf0ocah5GtphmLMP6Q==} + '@types/node@24.7.2': + resolution: {integrity: sha512-/NbVmcGTP+lj5oa4yiYxxeBjRivKQ5Ns1eSZeB99ExsEQ6rX5XYU1Zy/gGxY/ilqtD4Etx9mKyrPxZRetiahhA==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -8304,31 +8304,31 @@ snapshots: '@inquirer/ansi@1.0.0': {} - '@inquirer/confirm@5.1.18(@types/node@24.7.1)': + '@inquirer/confirm@5.1.18(@types/node@24.7.2)': dependencies: - '@inquirer/core': 10.2.2(@types/node@24.7.1) - '@inquirer/type': 3.0.8(@types/node@24.7.1) + '@inquirer/core': 10.2.2(@types/node@24.7.2) + '@inquirer/type': 3.0.8(@types/node@24.7.2) optionalDependencies: - '@types/node': 24.7.1 + '@types/node': 24.7.2 - '@inquirer/core@10.2.2(@types/node@24.7.1)': + '@inquirer/core@10.2.2(@types/node@24.7.2)': dependencies: '@inquirer/ansi': 1.0.0 '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@24.7.1) + '@inquirer/type': 3.0.8(@types/node@24.7.2) cli-width: 4.1.0 mute-stream: 2.0.0 signal-exit: 4.1.0 wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.7.1 + '@types/node': 24.7.2 '@inquirer/figures@1.0.13': {} - '@inquirer/type@3.0.8(@types/node@24.7.1)': + '@inquirer/type@3.0.8(@types/node@24.7.2)': optionalDependencies: - '@types/node': 24.7.1 + '@types/node': 24.7.2 '@isaacs/balanced-match@4.0.1': {} @@ -10222,7 +10222,7 @@ snapshots: '@types/cross-spawn@6.0.2': dependencies: - '@types/node': 24.7.1 + '@types/node': 24.7.2 '@types/debug@4.1.8': dependencies: @@ -10238,7 +10238,7 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node@24.7.1': + '@types/node@24.7.2': dependencies: undici-types: 7.14.0 @@ -10436,7 +10436,7 @@ snapshots: next: 15.5.4(@babel/core@7.28.4)(@opentelemetry/api@1.9.0)(@playwright/test@1.56.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react: 19.2.0 - '@vitejs/plugin-react@5.0.4(vite@7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2))': + '@vitejs/plugin-react@5.0.4(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2))': dependencies: '@babel/core': 7.28.4 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.4) @@ -10444,20 +10444,20 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.38 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2) transitivePeerDependencies: - supports-color - '@vitest/browser@3.2.4(msw@2.11.5(@types/node@24.7.1)(typescript@5.9.3))(playwright@1.56.0)(vite@7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2))(vitest@3.2.4)': + '@vitest/browser@3.2.4(msw@2.11.5(@types/node@24.7.2)(typescript@5.9.3))(playwright@1.56.0)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2))(vitest@3.2.4)': dependencies: '@testing-library/dom': 10.4.1 '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.1) - '@vitest/mocker': 3.2.4(msw@2.11.5(@types/node@24.7.1)(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2)) + '@vitest/mocker': 3.2.4(msw@2.11.5(@types/node@24.7.2)(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)) '@vitest/utils': 3.2.4 magic-string: 0.30.19 sirv: 3.0.2 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/node@24.7.1)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.11.5(@types/node@24.7.1)(typescript@5.9.3)) + vitest: 3.2.4(@types/node@24.7.2)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.11.5(@types/node@24.7.2)(typescript@5.9.3)) ws: 8.18.3 optionalDependencies: playwright: 1.56.0 @@ -10467,7 +10467,7 @@ snapshots: - utf-8-validate - vite - '@vitest/coverage-v8@3.2.4(@vitest/browser@3.2.4(msw@2.11.5(@types/node@24.7.1)(typescript@5.9.3))(playwright@1.56.0)(vite@7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2))(vitest@3.2.4))(vitest@3.2.4(@types/node@24.7.1)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.11.5(@types/node@24.7.1)(typescript@5.9.3)))': + '@vitest/coverage-v8@3.2.4(@vitest/browser@3.2.4(msw@2.11.5(@types/node@24.7.2)(typescript@5.9.3))(playwright@1.56.0)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2))(vitest@3.2.4))(vitest@3.2.4(@types/node@24.7.2)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.11.5(@types/node@24.7.2)(typescript@5.9.3)))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -10482,9 +10482,9 @@ snapshots: std-env: 3.9.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/node@24.7.1)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.11.5(@types/node@24.7.1)(typescript@5.9.3)) + vitest: 3.2.4(@types/node@24.7.2)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.11.5(@types/node@24.7.2)(typescript@5.9.3)) optionalDependencies: - '@vitest/browser': 3.2.4(msw@2.11.5(@types/node@24.7.1)(typescript@5.9.3))(playwright@1.56.0)(vite@7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2))(vitest@3.2.4) + '@vitest/browser': 3.2.4(msw@2.11.5(@types/node@24.7.2)(typescript@5.9.3))(playwright@1.56.0)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2))(vitest@3.2.4) transitivePeerDependencies: - supports-color @@ -10496,14 +10496,14 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(msw@2.11.5(@types/node@24.7.1)(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2))': + '@vitest/mocker@3.2.4(msw@2.11.5(@types/node@24.7.2)(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.19 optionalDependencies: - msw: 2.11.5(@types/node@24.7.1)(typescript@5.9.3) - vite: 7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2) + msw: 2.11.5(@types/node@24.7.2)(typescript@5.9.3) + vite: 7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2) '@vitest/pretty-format@3.2.4': dependencies: @@ -10534,7 +10534,7 @@ snapshots: sirv: 3.0.2 tinyglobby: 0.2.15 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/node@24.7.1)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.11.5(@types/node@24.7.1)(typescript@5.9.3)) + vitest: 3.2.4(@types/node@24.7.2)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.11.5(@types/node@24.7.2)(typescript@5.9.3)) '@vitest/utils@3.2.4': dependencies: @@ -12992,9 +12992,9 @@ snapshots: ms@2.1.3: {} - msw@2.11.5(@types/node@24.7.1)(typescript@5.9.3): + msw@2.11.5(@types/node@24.7.2)(typescript@5.9.3): dependencies: - '@inquirer/confirm': 5.1.18(@types/node@24.7.1) + '@inquirer/confirm': 5.1.18(@types/node@24.7.2) '@mswjs/interceptors': 0.39.7 '@open-draft/deferred-promise': 2.2.0 '@types/statuses': 2.0.6 @@ -14020,7 +14020,7 @@ snapshots: setprototypeof@1.2.0: {} - shadcn@3.4.0(@types/node@24.7.1)(typescript@5.9.3): + shadcn@3.4.0(@types/node@24.7.2)(typescript@5.9.3): dependencies: '@antfu/ni': 25.0.0 '@babel/core': 7.28.4 @@ -14041,7 +14041,7 @@ snapshots: fuzzysort: 3.1.0 https-proxy-agent: 7.0.6 kleur: 4.1.5 - msw: 2.11.5(@types/node@24.7.1)(typescript@5.9.3) + msw: 2.11.5(@types/node@24.7.2)(typescript@5.9.3) node-fetch: 3.3.2 ora: 8.2.0 postcss: 8.5.6 @@ -14498,14 +14498,14 @@ snapshots: '@ts-morph/common': 0.27.0 code-block-writer: 13.0.3 - ts-node@10.9.2(@types/node@24.7.1)(typescript@5.9.3): + ts-node@10.9.2(@types/node@24.7.2)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 24.7.1 + '@types/node': 24.7.2 acorn: 8.15.0 acorn-walk: 8.3.4 arg: 4.1.3 @@ -14733,13 +14733,13 @@ snapshots: - '@types/react' - '@types/react-dom' - vite-node@3.2.4(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2): + vite-node@3.2.4(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2) transitivePeerDependencies: - '@types/node' - jiti @@ -14754,18 +14754,18 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2)): + vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)): dependencies: debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.3) optionalDependencies: - vite: 7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2) transitivePeerDependencies: - supports-color - typescript - vite@7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2): + vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2): dependencies: esbuild: 0.25.10 fdir: 6.5.0(picomatch@4.0.3) @@ -14774,16 +14774,16 @@ snapshots: rollup: 4.52.4 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.7.1 + '@types/node': 24.7.2 fsevents: 2.3.3 jiti: 2.6.1 lightningcss: 1.30.2 - vitest@3.2.4(@types/node@24.7.1)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.11.5(@types/node@24.7.1)(typescript@5.9.3)): + vitest@3.2.4(@types/node@24.7.2)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.11.5(@types/node@24.7.2)(typescript@5.9.3)): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(msw@2.11.5(@types/node@24.7.1)(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2)) + '@vitest/mocker': 3.2.4(msw@2.11.5(@types/node@24.7.2)(typescript@5.9.3))(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -14801,12 +14801,12 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2) - vite-node: 3.2.4(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2) + vite: 7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2) + vite-node: 3.2.4(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 24.7.1 - '@vitest/browser': 3.2.4(msw@2.11.5(@types/node@24.7.1)(typescript@5.9.3))(playwright@1.56.0)(vite@7.1.9(@types/node@24.7.1)(jiti@2.6.1)(lightningcss@1.30.2))(vitest@3.2.4) + '@types/node': 24.7.2 + '@vitest/browser': 3.2.4(msw@2.11.5(@types/node@24.7.2)(typescript@5.9.3))(playwright@1.56.0)(vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.2))(vitest@3.2.4) '@vitest/ui': 3.2.4(vitest@3.2.4) jsdom: 27.0.0(postcss@8.5.6) transitivePeerDependencies: diff --git a/scripts/README.md b/scripts/README.md deleted file mode 100644 index 4ba23aa..0000000 --- a/scripts/README.md +++ /dev/null @@ -1,98 +0,0 @@ -# 🛠️ Scripts - -Development and automation scripts for Nitrokit Next.js project. - -## Available Scripts - -### 🚀 Development Setup - -```bash -./dev-setup.sh -``` - -Sets up the development environment, installs dependencies, and configures the database. - -### 📦 Dependency Management - -```bash -./dependency-updater.sh [OPTIONS] -``` - -Updates project dependencies with security checks and backup functionality. - -**Options:** - -- `--package-manager TYPE` - Use npm, yarn, or pnpm (default: auto) -- `--update-mode MODE` - safe, patch, minor, major, all (default: safe) -- `--dry-run` - Preview changes without applying -- `--security-check` - Enable vulnerability scanning - -### 📝 Release Notes - -```bash -./generate-release-notes.sh -``` - -Generates comprehensive release notes from git commit history. - -**Example:** - -```bash -./generate-release-notes.sh v1.2.0 -``` - -### 🌍 i18n Declarations - -```bash -./generate-i18n-declaration.sh -``` - -Generates TypeScript declarations for internationalization modules. - -## Usage Examples - -### Initial Setup - -```bash -# Set up development environment -./dev-setup.sh - -# Start development server -pnpm dev -``` - -### Update Dependencies - -```bash -# Safe update with backup -./dependency-updater.sh - -# Preview major updates -./dependency-updater.sh --update-mode major --dry-run - -# Restore from backup -./dependency-updater.sh --restore 20250525_003649 -``` - -### Generate Release - -```bash -# Create release notes -./generate-release-notes.sh v1.0.0 > RELEASE_NOTES.md - -# Update i18n types -./generate-i18n-declaration.sh -``` - -## Requirements - -- **Node.js** (v18+) -- **pnpm** (recommended package manager) -- **Git** (for release notes) - -## Notes - -- All scripts are executable and include help documentation -- Scripts automatically detect project configuration -- Backup functionality available for dependency updates -- Cross-platform compatibility (macOS, Linux, Windows with WSL) diff --git a/scripts/dependency-updater.sh b/scripts/dependency-updater.sh deleted file mode 100644 index 4c7cd38..0000000 --- a/scripts/dependency-updater.sh +++ /dev/null @@ -1,813 +0,0 @@ -#!/bin/bash - -# dependency-updater.sh - Node.js/Next.js/Angular dependency management with security checks - -# Default configuration -DEFAULT_PACKAGE_MANAGER="auto" -DEFAULT_UPDATE_MODE="safe" -DEFAULT_BACKUP_DIR=".dependency" -DEFAULT_SECURITY_CHECK="true" -DEFAULT_DRY_RUN="false" -DEFAULT_PROJECT_ROOT="auto" - -# Configuration variables -PACKAGE_MANAGER="${PACKAGE_MANAGER:-$DEFAULT_PACKAGE_MANAGER}" -UPDATE_MODE="${UPDATE_MODE:-$DEFAULT_UPDATE_MODE}" -BACKUP_DIR="${BACKUP_DIR:-$DEFAULT_BACKUP_DIR}" -SECURITY_CHECK="${SECURITY_CHECK:-$DEFAULT_SECURITY_CHECK}" -DRY_RUN="${DRY_RUN:-$DEFAULT_DRY_RUN}" -PROJECT_ROOT="${PROJECT_ROOT:-$DEFAULT_PROJECT_ROOT}" - -# Color definitions -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -PURPLE='\033[0;35m' -CYAN='\033[0;36m' -NC='\033[0m' # No Color - -# Help function -show_help() { - cat << EOF -🔄 Node.js Dependency Updater - Automated package updates for Node.js projects - -USAGE: - ./dependency-updater.sh [OPTIONS] - -DESCRIPTION: - Automatically updates Node.js project dependencies (npm/yarn/pnpm) with security - vulnerability scanning and backup functionality. Optimized for Next.js and Angular projects. - -OPTIONS: - --package-manager TYPE Package manager to use (auto|npm|yarn|pnpm) (default: $DEFAULT_PACKAGE_MANAGER) - --update-mode MODE Update strategy (safe|major|patch|minor|all) (default: $DEFAULT_UPDATE_MODE) - --backup-dir DIR Backup directory for rollback (default: $DEFAULT_BACKUP_DIR) - --project-root DIR Project root directory (auto|.|..|path) (default: $DEFAULT_PROJECT_ROOT) - --security-check Enable security vulnerability scanning (default: $DEFAULT_SECURITY_CHECK) - --no-security Disable security vulnerability scanning - --dry-run Preview changes without applying them - --restore BACKUP_ID Restore from backup (use backup timestamp) - --list-backups Show available backups - --clean-backups Remove old backups (keeps last 5) - -h, --help Show this help message and exit - -UPDATE MODES: - safe - Only security updates and patch versions - patch - Patch version updates only - minor - Minor and patch version updates - major - Major version updates (potentially breaking) - all - Update everything to latest versions - -PROJECT ROOT DETECTION: - auto - Automatically search for package.json in current and parent directories - . - Use current directory - .. - Use parent directory - path - Use specific path - -SUPPORTED PACKAGE MANAGERS: - 🟢 npm - Node.js default package manager - 🟢 yarn - Facebook's package manager (yarn.lock detection) - 🟢 pnpm - Fast, disk space efficient package manager (pnpm-lock.yaml detection) - -PROJECT TYPES: - 📦 Next.js - Automatic Next.js optimizations and build cache handling - 🅰️ Angular - Angular CLI compatibility and dependency checks - ⚛️ React - React-specific dependency management - 📝 Node.js - General Node.js project support - -EXAMPLES: - ./dependency-updater.sh # Auto-detect and safe update - ./dependency-updater.sh --project-root .. # Use parent directory - ./dependency-updater.sh --package-manager yarn --dry-run # Preview yarn updates - ./dependency-updater.sh --update-mode major --no-security # Major updates without security scan - ./dependency-updater.sh --restore 20250525_003649 # Restore from backup - -SECURITY FEATURES: - 🔍 npm audit / yarn audit / pnpm audit vulnerability scanning - 🛡️ Automatic backup before updates - 🔄 Easy rollback functionality - 📊 Detailed security reports - ⚠️ Breaking change warnings for major version updates - 🚀 Next.js specific optimizations - -EOF -} - -# Parse command line arguments -while [[ $# -gt 0 ]]; do - case $1 in - --package-manager) - PACKAGE_MANAGER="$2" - shift 2 - ;; - --update-mode) - UPDATE_MODE="$2" - shift 2 - ;; - --backup-dir) - BACKUP_DIR="$2" - shift 2 - ;; - --project-root) - PROJECT_ROOT="$2" - shift 2 - ;; - --security-check) - SECURITY_CHECK="true" - shift - ;; - --no-security) - SECURITY_CHECK="false" - shift - ;; - --dry-run) - DRY_RUN="true" - shift - ;; - --restore) - RESTORE_BACKUP="$2" - shift 2 - ;; - --list-backups) - LIST_BACKUPS="true" - shift - ;; - --clean-backups) - CLEAN_BACKUPS="true" - shift - ;; - -h|--help) - show_help - exit 0 - ;; - *) - echo -e "${RED}❌ Unknown parameter: $1${NC}" - echo -e "${BLUE}💡 For help: $0 --help${NC}" - exit 1 - ;; - esac -done - -# Logging functions -log_info() { - echo -e "${BLUE}ℹ️ $1${NC}" -} - -log_success() { - echo -e "${GREEN}✅ $1${NC}" -} - -log_warning() { - echo -e "${YELLOW}⚠️ $1${NC}" -} - -log_error() { - echo -e "${RED}❌ $1${NC}" -} - -log_step() { - echo -e "${PURPLE}🔄 $1${NC}" -} - -# Function to find project root -find_project_root() { - local search_dir="${1:-$(pwd)}" - local max_depth=3 - local current_depth=0 - - # If PROJECT_ROOT is set to a specific path, use it - if [[ "$PROJECT_ROOT" != "auto" ]]; then - if [[ -d "$PROJECT_ROOT" ]]; then - # Convert to absolute path - cd "$PROJECT_ROOT" && pwd - return 0 - else - log_error "Specified project root does not exist: $PROJECT_ROOT" - return 1 - fi - fi - - # Search in current and parent directories for package.json - local check_dir="$(realpath "$search_dir")" - while [[ $current_depth -le $max_depth ]]; do - if [[ -f "$check_dir/package.json" ]]; then - echo "$check_dir" - return 0 - fi - - # Move to parent directory - check_dir="$(dirname "$check_dir")" - current_depth=$((current_depth + 1)) - - # Stop if we reach root - if [[ "$check_dir" == "/" ]]; then - break - fi - done - - log_error "No package.json found in current or parent directories" - return 1 -} - -# Function to detect package manager in specific directory -detect_package_manager() { - local project_dir="$1" - local detected="" - - if [[ -f "$project_dir/package.json" ]]; then - if [[ -f "$project_dir/pnpm-lock.yaml" ]]; then - detected="pnpm" - elif [[ -f "$project_dir/yarn.lock" ]]; then - detected="yarn" - else - detected="npm" - fi - fi - - echo "$detected" -} - -# Function to detect project type -detect_project_type() { - local project_dir="$1" - local project_type="node" - - if [[ -f "$project_dir/package.json" ]]; then - # Check for Next.js - if grep -q "next" "$project_dir/package.json" || [[ -f "$project_dir/next.config.js" ]] || [[ -f "$project_dir/next.config.mjs" ]]; then - project_type="nextjs" - # Check for Angular - elif grep -q "@angular/core" "$project_dir/package.json" || [[ -f "$project_dir/angular.json" ]]; then - project_type="angular" - # Check for React - elif grep -q "react" "$project_dir/package.json"; then - project_type="react" - fi - fi - - echo "$project_type" -} - -# Function to check if tool is installed -check_tool() { - local tool="$1" - if ! command -v "$tool" &> /dev/null; then - return 1 - fi - return 0 -} - -# Function to install package manager tools -install_package_manager() { - local pm="$1" - - case "$pm" in - npm) - if ! check_tool "node"; then - log_error "Node.js is required for npm" - if [[ "$OSTYPE" == "darwin"* ]]; then - log_info "Install with: brew install node" - else - log_info "Install Node.js from: https://nodejs.org/" - fi - return 1 - fi - ;; - yarn) - if ! check_tool "yarn"; then - log_step "Installing Yarn..." - npm install -g yarn - fi - ;; - pnpm) - if ! check_tool "pnpm"; then - log_step "Installing pnpm..." - npm install -g pnpm - fi - ;; - *) - log_error "Unsupported package manager: $pm" - log_info "Supported: npm, yarn, pnpm" - return 1 - ;; - esac - return 0 -} - -# Function to create backup -create_backup() { - local pm="$1" - local project_dir="$2" - local timestamp=$(date +"%Y%m%d_%H%M%S") - - # Get parent directory of script (nitrokit directory) - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - local parent_dir="$(dirname "$script_dir")" - local backup_path="$parent_dir/$BACKUP_DIR/$timestamp" - - log_step "Creating backup: $backup_path" - mkdir -p "$backup_path" - - # Backup package files - cp "$project_dir/package.json" "$backup_path/" 2>/dev/null || true - cp "$project_dir/package-lock.json" "$backup_path/" 2>/dev/null || true - cp "$project_dir/yarn.lock" "$backup_path/" 2>/dev/null || true - cp "$project_dir/pnpm-lock.yaml" "$backup_path/" 2>/dev/null || true - - # Backup Next.js config if exists - cp "$project_dir/next.config.js" "$backup_path/" 2>/dev/null || true - cp "$project_dir/next.config.mjs" "$backup_path/" 2>/dev/null || true - - # Backup Angular config if exists - cp "$project_dir/angular.json" "$backup_path/" 2>/dev/null || true - cp "$project_dir/tsconfig.json" "$backup_path/" 2>/dev/null || true - - # Create backup info file - { - echo "$timestamp" - echo "$pm" - date - echo "$project_dir" - } > "$backup_path/.backup_info" - - log_success "Backup created: $timestamp" - echo "$timestamp" -} - -# Function to restore from backup -restore_backup() { - local backup_id="$1" - - # Get parent directory of script (nitrokit directory) - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - local parent_dir="$(dirname "$script_dir")" - local backup_path="$parent_dir/$BACKUP_DIR/$backup_id" - - if [[ ! -d "$backup_path" ]]; then - log_error "Backup not found: $backup_id" - return 1 - fi - - local backup_info="$backup_path/.backup_info" - local original_project_dir="." - - if [[ -f "$backup_info" ]]; then - original_project_dir=$(sed -n '4p' "$backup_info") - fi - - log_step "Restoring from backup: $backup_id to $original_project_dir" - - # Copy files back to original project directory - for file in "$backup_path"/*; do - if [[ -f "$file" && "$(basename "$file")" != ".backup_info" ]]; then - cp "$file" "$original_project_dir/" - log_info "Restored: $(basename "$file") to $original_project_dir" - fi - done - - log_success "Backup restored successfully" -} - -# Function to list backups -list_backups() { - # Get parent directory of script (nitrokit directory) - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - local parent_dir="$(dirname "$script_dir")" - local backup_dir="$parent_dir/$BACKUP_DIR" - - if [[ ! -d "$backup_dir" ]]; then - log_info "No backups found" - return 0 - fi - - echo -e "${CYAN}📋 Available Backups:${NC}" - echo "----------------------------------------" - - for backup in "$backup_dir"/*; do - if [[ -d "$backup" && -f "$backup/.backup_info" ]]; then - local backup_id=$(basename "$backup") - local pm=$(sed -n '2p' "$backup/.backup_info") - local date=$(sed -n '3p' "$backup/.backup_info") - local project_dir=$(sed -n '4p' "$backup/.backup_info") - - echo -e "${YELLOW}🗂️ $backup_id${NC}" - echo " Package Manager: $pm" - echo " Project Dir: $project_dir" - echo " Created: $date" - echo "" - fi - done -} - -# Function to clean old backups -clean_backups() { - # Get parent directory of script (nitrokit directory) - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - local parent_dir="$(dirname "$script_dir")" - local backup_dir="$parent_dir/$BACKUP_DIR" - - if [[ ! -d "$backup_dir" ]]; then - log_info "No backups to clean" - return 0 - fi - - log_step "Cleaning old backups (keeping last 5)..." - - # Get sorted list of backups (newest first) - local backups=($(ls -1t "$backup_dir")) - local count=${#backups[@]} - - if [[ $count -le 5 ]]; then - log_info "Only $count backups found, nothing to clean" - return 0 - fi - - # Remove backups beyond the first 5 - for ((i=5; i/dev/null | head -15 - fi - - # Show project-specific information - case "$project_type" in - nextjs) - echo -e "${CYAN}🚀 Next.js Information:${NC}" - if [[ -f "package.json" ]]; then - grep -A 1 -B 1 "next" package.json | head -5 - fi - ;; - angular) - echo -e "${CYAN}🅰️ Angular Information:${NC}" - if check_tool "ng"; then - ng version 2>/dev/null | head -5 - fi - ;; - react) - echo -e "${CYAN}⚛️ React Information:${NC}" - if [[ -f "package.json" ]]; then - grep -A 1 -B 1 "react" package.json | head -5 - fi - ;; - esac - - # Return to original directory - cd "$original_dir" -} - -# Function to handle Prisma-specific updates -handle_prisma_updates() { - local project_dir="$1" - - if [[ -f "$project_dir/prisma/schema.prisma" ]]; then - log_step "Handling Prisma updates..." - - # Regenerate Prisma client with production flags - if check_tool "npx"; then - cd "$project_dir" - npx prisma generate --no-engine - log_success "Prisma client regenerated with production optimizations" - fi - - # Check for schema changes - if [[ -n "$(git diff --name-only | grep 'prisma/schema.prisma')" ]]; then - log_warning "Prisma schema changes detected. Consider running migrations:" - log_info " npx prisma migrate dev" - log_info " npx prisma db push" - fi - fi -} - -# Main function -main() { - echo -e "${PURPLE}🔄 Node.js Dependency Updater - Starting automation...${NC}" - echo "" - - # Handle special commands first - if [[ "$LIST_BACKUPS" == "true" ]]; then - list_backups - exit 0 - fi - - if [[ "$CLEAN_BACKUPS" == "true" ]]; then - clean_backups - exit 0 - fi - - if [[ -n "$RESTORE_BACKUP" ]]; then - restore_backup "$RESTORE_BACKUP" - exit 0 - fi - - # Find project root directory - log_step "Searching for Node.js project files..." - local project_root - project_root=$(find_project_root) - if [[ $? -ne 0 ]]; then - exit 1 - fi - - log_success "Project root found: $project_root" - - # Detect package manager if auto - if [[ "$PACKAGE_MANAGER" == "auto" ]]; then - log_step "Detecting package manager in: $project_root" - PACKAGE_MANAGER=$(detect_package_manager "$project_root") - if [[ -z "$PACKAGE_MANAGER" ]]; then - log_error "Could not detect package manager in: $project_root" - log_info "Make sure package.json exists" - exit 1 - fi - log_success "Detected package manager: $PACKAGE_MANAGER" - fi - - # Detect project type - local project_type - project_type=$(detect_project_type "$project_root") - log_success "Detected project type: $project_type" - - # Install/check package manager - if ! install_package_manager "$PACKAGE_MANAGER"; then - exit 1 - fi - - # Create backup (unless dry run) - local backup_id="" - if [[ "$DRY_RUN" != "true" ]]; then - backup_id=$(create_backup "$PACKAGE_MANAGER" "$project_root") - fi - - # Run security audit if enabled - if [[ "$SECURITY_CHECK" == "true" ]]; then - run_security_audit "$PACKAGE_MANAGER" "$project_root" - fi - - # Update dependencies - update_dependencies "$PACKAGE_MANAGER" "$UPDATE_MODE" "$project_root" "$project_type" - - # Handle Prisma if exists - if [[ "$DRY_RUN" != "true" ]]; then - handle_prisma_updates "$project_root" - fi - - # Show summary (unless dry run) - if [[ "$DRY_RUN" != "true" ]]; then - show_update_summary "$PACKAGE_MANAGER" "$project_root" "$project_type" - fi - - echo "" - if [[ "$DRY_RUN" == "true" ]]; then - log_success "Dry run completed! Use without --dry-run to apply changes." - else - log_success "Dependencies updated successfully!" - log_info "Project type: $project_type" - log_info "Project root: $project_root" - log_info "Package manager: $PACKAGE_MANAGER" - log_info "Backup created: $backup_id" - log_info "To rollback: $0 --restore $backup_id" - fi -} - -# Run main function -main "$@" \ No newline at end of file diff --git a/scripts/dev-setup.sh b/scripts/dev-setup.sh deleted file mode 100644 index 06dea5d..0000000 --- a/scripts/dev-setup.sh +++ /dev/null @@ -1,158 +0,0 @@ -#!/bin/bash - -# dev-setup.sh - Development environment setup for Nitrokit Next.js - -# Get the parent directory (nitrokit root) -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" - -echo "🔄 Setting up Nitrokit Next.js development environment..." -echo "📁 Project root: $PROJECT_ROOT" - -# Change to project root directory -cd "$PROJECT_ROOT" - -# 🧹 Clean up build artifacts and cache files before setup -echo "🧹 Cleaning up previous build artifacts..." - -# Remove directories -for dir in ".next" "coverage" "dist" "build" "node_modules" "src/generated"; do - if [ -d "$PROJECT_ROOT/$dir" ]; then - echo "🗑️ Removing $dir..." - rm -rf "$PROJECT_ROOT/$dir" - else - echo "✅ $dir already clean" - fi -done - -# Remove files -for file in "tsconfig.tsbuildinfo" "test-report.junit.xml"; do - if [ -f "$PROJECT_ROOT/$file" ]; then - echo "🗑️ Removing $file..." - rm -f "$PROJECT_ROOT/$file" - else - echo "✅ $file already clean" - fi -done - -# Clean pnpm cache directories if they exist -if [ -d "$PROJECT_ROOT/.pnpm" ]; then - echo "🗑️ Cleaning pnpm cache..." - rm -rf "$PROJECT_ROOT/.pnpm" -fi - -# Clean Prisma generated files -if [ -d "$PROJECT_ROOT/prisma/generated" ]; then - echo "🗑️ Cleaning Prisma generated files..." - rm -rf "$PROJECT_ROOT/prisma/generated" -fi - -# Clean Vitest cache -if [ -d "$PROJECT_ROOT/.vitest" ]; then - echo "🗑️ Cleaning Vitest cache..." - rm -rf "$PROJECT_ROOT/.vitest" -fi - -echo "✅ Cleanup completed!" -echo "" - -# Install dependencies with pnpm (preferred package manager) -echo "📥 Installing dependencies with pnpm..." -if command -v pnpm &> /dev/null; then - pnpm install --no-frozen-lockfile -elif command -v npm &> /dev/null; then - npm install -else - echo "❌ No package manager found. Please install pnpm or npm first." - exit 1 -fi - -# Check for Prisma models directory and handle database setup -if [ -d "$PROJECT_ROOT/prisma/models" ] && [ -f "$PROJECT_ROOT/prisma/schema.prisma" ]; then - echo "🗃️ Setting up Prisma database with multi-schema setup..." - - # Import schemas from models directory - echo "📦 Importing Prisma schemas..." - pnpm prisma:import || echo "⚠️ Failed to import Prisma schemas" - - # Check if database exists and run migrations first - echo "🔄 Running database migrations..." - pnpm prisma migrate dev --name init 2>/dev/null || echo "✅ Database up to date" - - # Then generate Prisma client - echo "📦 Generating Prisma client..." - pnpm prisma:generate - - echo "✅ Prisma setup completed" -elif [ -f "$PROJECT_ROOT/prisma/schema.prisma" ]; then - echo "🗃️ Setting up Prisma database..." - echo "📍 Found Prisma schema at: $PROJECT_ROOT/prisma/schema.prisma" - - # Run migrations and generate client - echo "🔄 Running database migrations..." - pnpm prisma migrate dev --name init 2>/dev/null || echo "✅ Database up to date" - - echo "📦 Generating Prisma client..." - pnpm prisma:generate - - echo "✅ Prisma setup completed" -else - echo "⚠️ Prisma schema not found. Skipping database setup." -fi - -# Check for environment file -if [ ! -f "$PROJECT_ROOT/.env" ] && [ -f "$PROJECT_ROOT/.env.example" ]; then - echo "🔧 Creating .env file from .env.example..." - cp "$PROJECT_ROOT/.env.example" "$PROJECT_ROOT/.env" - echo "⚠️ Please update .env file with your configuration" -elif [ ! -f "$PROJECT_ROOT/.env" ]; then - echo "⚠️ No .env file found. Consider creating one for local development" -fi - -# Check Next.js configuration -if [ -f "$PROJECT_ROOT/next.config.ts" ] || [ -f "$PROJECT_ROOT/next.config.js" ]; then - echo "✅ Next.js configuration found" -else - echo "⚠️ Next.js configuration not found" -fi - -# Check internationalization messages -if [ -d "$PROJECT_ROOT/messages" ]; then - echo "✅ i18n messages directory found" -else - echo "⚠️ i18n messages directory not found" -fi - -# Set up Husky hooks if available -if [ -f "$PROJECT_ROOT/package.json" ] && grep -q "husky" "$PROJECT_ROOT/package.json"; then - echo "🪝 Setting up Husky git hooks..." - pnpm husky install || echo "⚠️ Failed to install Husky hooks" -fi - -# Show available scripts -echo "" -echo "🎯 Available development commands:" -echo " pnpm dev - Start development server" -echo " pnpm build - Build for production" -echo " pnpm test - Run tests with Vitest" -echo " pnpm test:coverage - Run tests with coverage report" -echo " pnpm test:ui - Run tests with Vitest UI" -echo " pnpm playwright - Run Playwright e2e tests" -echo " pnpm prisma:studio - Open Prisma Studio" -echo " pnpm prisma:push - Push schema changes to database" -echo " pnpm prisma:migrate - Run database migrations" -echo " pnpm prisma:generate - Generate Prisma client" -echo " pnpm prisma:import - Import schemas from models directory" -echo " pnpm lint - Run ESLint" -echo " pnpm lint:fix - Fix ESLint issues" -echo " pnpm format - Format code with Prettier" -echo " pnpm type-check - Run TypeScript type checking" -echo " pnpm env:sanitize - Create sanitized .env.example" - -echo "" -echo "✅ Nitrokit Next.js development environment ready!" -echo "🚀 Run 'pnpm dev' to start development server" -echo "🌐 Application will be available at http://localhost:3000" - -# Return to original directory -cd - > /dev/null \ No newline at end of file diff --git a/scripts/generate-release-notes.sh b/scripts/generate-release-notes.sh deleted file mode 100644 index 1dc6fda..0000000 --- a/scripts/generate-release-notes.sh +++ /dev/null @@ -1,330 +0,0 @@ -#!/bin/bash - -# generate-release-notes.sh - Automatically generate release notes from git history - -TAG="$1" -PREV_TAG="" - -# Color definitions -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -PURPLE='\033[0;35m' -NC='\033[0m' # No Color - -# Get project root -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" - -echo -e "${BLUE}🚀 Generating release notes for Nitrokit Next.js${NC}" -echo -e "${YELLOW}📁 Project root: $PROJECT_ROOT${NC}" - -# Validate tag parameter -if [[ -z "$TAG" ]]; then - echo -e "${RED}❌ Error: Please provide a tag name${NC}" - echo -e "${YELLOW}Usage: $0 ${NC}" - echo -e "${YELLOW}Example: $0 v1.2.0${NC}" - exit 1 -fi - -# Check if tag exists -if ! git rev-parse "$TAG" >/dev/null 2>&1; then - echo -e "${RED}❌ Error: Tag '$TAG' does not exist${NC}" - exit 1 -fi - -# Find previous tag -PREV_TAG=$(git describe --tags --abbrev=0 "$TAG^" 2>/dev/null) - -if [[ -z "$PREV_TAG" ]]; then - PREV_TAG=$(git rev-list --max-parents=0 HEAD) - COMPARISON_RANGE="$PREV_TAG..$TAG" - COMPARISON_TEXT="Initial release" -else - COMPARISON_RANGE="$PREV_TAG..$TAG" - COMPARISON_TEXT="Changes since $PREV_TAG" -fi - -echo "# 🚀 Nitrokit Next.js $TAG" -echo "" - -# Get release date -RELEASE_DATE=$(git log -1 --format=%ai "$TAG" | cut -d' ' -f1) -echo "**Release Date:** $RELEASE_DATE" -echo "**$COMPARISON_TEXT**" -echo "" - -# Check if this is a pre-release -if [[ "$TAG" =~ -[a-zA-Z] ]]; then - echo "🚨 **This is a pre-release version** - Use with caution in production environments." - echo "" -fi - -# Generate commit categorization with better filtering -FEATURES=$(git log "$COMPARISON_RANGE" --pretty=format:"%s" --grep="feat" --grep="feature" --grep="add" --grep="new" -i | grep -v -E "(fix|bug|improve|refactor|doc|deps|bump|upgrade)" -i) -FIXES=$(git log "$COMPARISON_RANGE" --pretty=format:"%s" --grep="fix" --grep="bug" --grep="hotfix" --grep="resolve" -i) -IMPROVEMENTS=$(git log "$COMPARISON_RANGE" --pretty=format:"%s" --grep="improve" --grep="enhance" --grep="update" --grep="refactor" --grep="optimize" --grep="performance" -i) -DOCS=$(git log "$COMPARISON_RANGE" --pretty=format:"%s" --grep="doc" --grep="readme" --grep="comment" --grep="guide" -i) -DEPS=$(git log "$COMPARISON_RANGE" --pretty=format:"%s" --grep="dep" --grep="bump" --grep="upgrade" --grep="pnpm" --grep="npm" --grep="yarn" -i) -TRANSLATIONS=$(git log "$COMPARISON_RANGE" --pretty=format:"%s" --grep="translation" --grep="i18n" --grep="locale" --grep="lang" -i) -COMPONENTS=$(git log "$COMPARISON_RANGE" --pretty=format:"%s" --grep="component" --grep="ui" --grep="design" --grep="theme" -i) -TESTS=$(git log "$COMPARISON_RANGE" --pretty=format:"%s" --grep="test" --grep="spec" --grep="coverage" --grep="vitest" --grep="playwright" -i) - -# Components & UI -if [[ -n "$COMPONENTS" ]]; then - echo "## 🎨 Components & UI" - echo "" - while IFS= read -r commit; do - if [[ -n "$commit" ]]; then - echo "- $commit" - fi - done <<< "$COMPONENTS" - echo "" -fi - -# Features -if [[ -n "$FEATURES" ]]; then - echo "## ✨ New Features" - echo "" - while IFS= read -r commit; do - if [[ -n "$commit" ]]; then - echo "- $commit" - fi - done <<< "$FEATURES" - echo "" -fi - -# Bug Fixes -if [[ -n "$FIXES" ]]; then - echo "## 🐛 Bug Fixes" - echo "" - while IFS= read -r commit; do - if [[ -n "$commit" ]]; then - echo "- $commit" - fi - done <<< "$FIXES" - echo "" -fi - -# Improvements -if [[ -n "$IMPROVEMENTS" ]]; then - echo "## 🔧 Improvements" - echo "" - while IFS= read -r commit; do - if [[ -n "$commit" ]]; then - echo "- $commit" - fi - done <<< "$IMPROVEMENTS" - echo "" -fi - -# Tests -if [[ -n "$TESTS" ]]; then - echo "## 🧪 Testing" - echo "" - while IFS= read -r commit; do - if [[ -n "$commit" ]]; then - echo "- $commit" - fi - done <<< "$TESTS" - echo "" -fi - -# Translation Updates -if [[ -n "$TRANSLATIONS" ]]; then - echo "## 🌍 Internationalization" - echo "" - while IFS= read -r commit; do - if [[ -n "$commit" ]]; then - echo "- $commit" - fi - done <<< "$TRANSLATIONS" - echo "" -fi - -# Documentation -if [[ -n "$DOCS" ]]; then - echo "## 📚 Documentation" - echo "" - while IFS= read -r commit; do - if [[ -n "$commit" ]]; then - echo "- $commit" - fi - done <<< "$DOCS" - echo "" -fi - -# Dependencies -if [[ -n "$DEPS" ]]; then - echo "## 📦 Dependencies" - echo "" - while IFS= read -r commit; do - if [[ -n "$commit" ]]; then - echo "- $commit" - fi - done <<< "$DEPS" - echo "" -fi - -# Contributors with GitHub usernames -echo "## 👥 Contributors" -echo "" -echo "Thanks to all the contributors who made this release possible:" -echo "" - -# Get unique contributor emails and process them -git log "$COMPARISON_RANGE" --pretty=format:"%an|%ae" | sort | uniq | while IFS='|' read -r name email; do - if [[ -n "$name" && -n "$email" ]]; then - case "$email" in - *@users.noreply.github.com) - # GitHub no-reply email format - github_user=$(echo "$email" | sed 's/@users.noreply.github.com$//' | sed 's/^[0-9]*+//') - echo "- [@$github_user](https://github.com/$github_user)" - ;; - mustafagenc@*) - echo "- [@mustafagenc](https://github.com/mustafagenc) ($name)" - ;; - *) - # Try to get GitHub username from git config - github_user=$(git config --get user.githubusername 2>/dev/null || echo "") - if [[ -n "$github_user" ]]; then - echo "- [@$github_user](https://github.com/$github_user) ($name)" - else - echo "- $name" - fi - ;; - esac - fi -done - -echo "" - -# Tech Stack Information -echo "## 🛠️ Tech Stack" -echo "" -echo "This release is built with:" -echo "" -echo "- ⚡ **Next.js 15** - React framework with App Router" -echo "- 🎨 **Tailwind CSS** - Utility-first CSS framework" -echo "- 🧩 **shadcn/ui** - Beautiful and accessible components" -echo "- 🔒 **NextAuth.js** - Authentication for Next.js" -echo "- 🗃️ **Prisma** - Next-generation ORM" -echo "- 🌍 **next-intl** - Internationalization" -echo "- 🧪 **Vitest** - Fast unit testing framework" -echo "- 🎭 **Playwright** - End-to-end testing" -echo "- 📦 **pnpm** - Fast, disk space efficient package manager" -echo "" - -# Installation instructions -echo "## 🚀 Installation & Upgrade" -echo "" -echo "### For new projects:" -echo "\`\`\`bash" -echo "git clone https://github.com/nitrokit/nitrokit-nextjs.git" -echo "cd nitrokit-nextjs" -echo "git checkout $TAG" -echo "pnpm install" -echo "./scripts/dev-setup.sh" -echo "pnpm dev" -echo "\`\`\`" -echo "" -echo "### For existing projects:" -echo "\`\`\`bash" -echo "git pull origin main" -echo "git checkout $TAG" -echo "pnpm install --no-frozen-lockfile" -echo "pnpm prisma:generate" -echo "pnpm build # Test build" -echo "\`\`\`" -echo "" - -# Breaking changes warning -BREAKING_CHANGES=$(git log "$COMPARISON_RANGE" --pretty=format:"%s" --grep="BREAKING" --grep="breaking change" --grep="major" -i) -if [[ -n "$BREAKING_CHANGES" ]]; then - echo "## ⚠️ Breaking Changes" - echo "" - echo "🚨 **Important:** This release contains breaking changes. Please review carefully before upgrading." - echo "" - while IFS= read -r commit; do - if [[ -n "$commit" ]]; then - echo "- $commit" - fi - done <<< "$BREAKING_CHANGES" - echo "" - echo "### Migration Guide" - echo "" - echo "1. Backup your current project" - echo "2. Review the breaking changes above" - echo "3. Update your code accordingly" - echo "4. Run tests before deploying" - echo "" -fi - -# Security updates -SECURITY_UPDATES=$(git log "$COMPARISON_RANGE" --pretty=format:"%s" --grep="security" --grep="vulnerability" --grep="CVE" --grep="audit" -i) -if [[ -n "$SECURITY_UPDATES" ]]; then - echo "## 🔒 Security Updates" - echo "" - echo "🛡️ **Security patches included in this release:**" - echo "" - while IFS= read -r commit; do - if [[ -n "$commit" ]]; then - echo "- $commit" - fi - done <<< "$SECURITY_UPDATES" - echo "" - echo "**We recommend updating immediately to ensure your application remains secure.**" - echo "" -fi - -# Performance improvements -PERFORMANCE=$(git log "$COMPARISON_RANGE" --pretty=format:"%s" --grep="perf" --grep="performance" --grep="optimization" --grep="speed" -i) -if [[ -n "$PERFORMANCE" ]]; then - echo "## ⚡ Performance Improvements" - echo "" - while IFS= read -r commit; do - if [[ -n "$commit" ]]; then - echo "- $commit" - fi - done <<< "$PERFORMANCE" - echo "" -fi - -# Full changelog -echo "## 📝 Full Changelog" -echo "" -if [[ -n "$PREV_TAG" && "$PREV_TAG" != $(git rev-list --max-parents=0 HEAD) ]]; then - echo "**Full Changelog**: https://github.com/nitrokit/nitrokit-nextjs/compare/$PREV_TAG...$TAG" -else - echo "**Full Changelog**: https://github.com/nitrokit/nitrokit-nextjs/commits/$TAG" -fi -echo "" - -# Additional information -echo "---" -echo "" -echo "### 🔗 Useful Links" -echo "" -echo "- 📖 **Documentation**: [README.md](https://github.com/nitrokit/nitrokit-nextjs#readme)" -echo "- 🛠️ **Development Scripts**: [scripts/README.md](https://github.com/nitrokit/nitrokit-nextjs/blob/main/scripts/README.md)" -echo "- 🐛 **Report Issues**: [GitHub Issues](https://github.com/nitrokit/nitrokit-nextjs/issues)" -echo "- 💬 **Discussions**: [GitHub Discussions](https://github.com/nitrokit/nitrokit-nextjs/discussions)" -echo "- 🌐 **Live Demo**: [Coming Soon](https://nitrokit-nextjs-preview.vercel.app/)" -echo "" -echo "### 🆘 Getting Help" -echo "" -echo "If you encounter any issues with this release:" -echo "" -echo "1. Check the [troubleshooting section](https://github.com/nitrokit/nitrokit-nextjs#troubleshooting)" -echo "2. Search [existing issues](https://github.com/nitrokit/nitrokit-nextjs/issues)" -echo "3. Run \`./scripts/dev-setup.sh\` to reset your development environment" -echo "4. Create a [new issue](https://github.com/nitrokit/nitrokit-nextjs/issues/new) with detailed information" -echo "" -echo "### 🎯 What's Next?" -echo "" -echo "Check out our [roadmap](https://github.com/nitrokit/nitrokit-nextjs/projects) to see what's coming in future releases!" -echo "" -echo "---" -echo "" -echo "**Happy coding with Nitrokit Next.js! 🚀✨**" \ No newline at end of file diff --git a/src/app/[locale]/(website)/about/loading.tsx b/src/app/[locale]/(website)/about/loading.tsx index 1cafcb5..69eea9a 100644 --- a/src/app/[locale]/(website)/about/loading.tsx +++ b/src/app/[locale]/(website)/about/loading.tsx @@ -1,8 +1,5 @@ -import { getTranslations } from 'next-intl/server'; +import { PageLoading } from '@/components/shared'; -import { Loading } from '@/components/shared'; - -export default async function PageLoading() { - const t = await getTranslations('app'); - return ; +export default function Loading() { + return ; } diff --git a/src/app/[locale]/(website)/contact/components/contact-form.tsx b/src/app/[locale]/(website)/contact/components/contact-form.tsx index a5a260c..95fb4e2 100644 --- a/src/app/[locale]/(website)/contact/components/contact-form.tsx +++ b/src/app/[locale]/(website)/contact/components/contact-form.tsx @@ -102,7 +102,12 @@ export const ContactForm = () => {
- + { + void form.handleSubmit(handleFormSubmit)(event); + }} + className="space-y-6" + >
; +export default function Loading() { + return ; } diff --git a/src/app/[locale]/(website)/faq/loading.tsx b/src/app/[locale]/(website)/faq/loading.tsx index 1cafcb5..69eea9a 100644 --- a/src/app/[locale]/(website)/faq/loading.tsx +++ b/src/app/[locale]/(website)/faq/loading.tsx @@ -1,8 +1,5 @@ -import { getTranslations } from 'next-intl/server'; +import { PageLoading } from '@/components/shared'; -import { Loading } from '@/components/shared'; - -export default async function PageLoading() { - const t = await getTranslations('app'); - return ; +export default function Loading() { + return ; } diff --git a/src/app/[locale]/(website)/pricing/loading.tsx b/src/app/[locale]/(website)/pricing/loading.tsx index 1cafcb5..69eea9a 100644 --- a/src/app/[locale]/(website)/pricing/loading.tsx +++ b/src/app/[locale]/(website)/pricing/loading.tsx @@ -1,8 +1,5 @@ -import { getTranslations } from 'next-intl/server'; +import { PageLoading } from '@/components/shared'; -import { Loading } from '@/components/shared'; - -export default async function PageLoading() { - const t = await getTranslations('app'); - return ; +export default function Loading() { + return ; } diff --git a/src/app/[locale]/(website)/privacy/loading.tsx b/src/app/[locale]/(website)/privacy/loading.tsx index 1cafcb5..69eea9a 100644 --- a/src/app/[locale]/(website)/privacy/loading.tsx +++ b/src/app/[locale]/(website)/privacy/loading.tsx @@ -1,8 +1,5 @@ -import { getTranslations } from 'next-intl/server'; +import { PageLoading } from '@/components/shared'; -import { Loading } from '@/components/shared'; - -export default async function PageLoading() { - const t = await getTranslations('app'); - return ; +export default function Loading() { + return ; } diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx index d2836dd..3d1e541 100644 --- a/src/app/[locale]/layout.tsx +++ b/src/app/[locale]/layout.tsx @@ -1,5 +1,3 @@ -import '@/styles/globals.css'; - import { Metadata, Viewport } from 'next'; import { notFound } from 'next/navigation'; import { NextIntlClientProvider, hasLocale } from 'next-intl'; @@ -11,8 +9,6 @@ import { getLangDir } from 'rtl-detect'; import { ThemeProvider } from '@/providers/theme-provider'; import { CookieConsent } from '@/components/shared'; import { TooltipProvider } from '@/components/ui'; -import { SessionProvider } from 'next-auth/react'; -import { UserProvider } from '@/contexts/user-context'; export async function generateMetadata(): Promise { return await generateSiteMetadata(); @@ -50,19 +46,17 @@ export default async function LocaleLayout({ children, params }: LocaleLayoutPro className={`${lexend.variable} ${montserrat.variable} font-[family-name:var(--font-lexend)] antialiased`} > - - - - {children} - - - - + + {children} + + diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts deleted file mode 100644 index 0aa1cd7..0000000 --- a/src/app/api/auth/[...nextauth]/route.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { handlers } from '@/auth'; -export const { GET, POST } = handlers; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index d37401a..25bedd1 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,3 +1,5 @@ +import '@/styles/globals.css'; + import { ServiceWorkerRegister } from '@/components/shared/service-worker-register'; import { Toaster } from '@/components/ui'; import AnalyticsProvider from '@/providers/analytics-provider'; diff --git a/src/auth.ts b/src/auth.ts deleted file mode 100644 index 68bd66a..0000000 --- a/src/auth.ts +++ /dev/null @@ -1,51 +0,0 @@ -import NextAuth from 'next-auth'; -import { PrismaAdapter } from '@auth/prisma-adapter'; -import { prisma } from './lib/prisma'; - -export const { handlers, auth, signIn, signOut } = NextAuth({ - adapter: PrismaAdapter(prisma), - providers: [], - pages: { - signIn: '/login', - signOut: '/logout', - error: '/error', - verifyRequest: '/verify-request', - newUser: '/register' - }, - session: { - strategy: 'jwt', - maxAge: 30 * 24 * 60 * 60, // 30 days - updateAge: 24 * 60 * 60 // 24 hours - }, - jwt: { - maxAge: 30 * 24 * 60 * 60 // 30 days - }, - secret: process.env.AUTH_SECRET, - debug: process.env.NODE_ENV === 'development', - useSecureCookies: process.env.NODE_ENV === 'production', - cookies: { - sessionToken: { - name: - process.env.NODE_ENV === 'production' - ? '__Secure-authjs.session-token' - : 'authjs.session-token', - options: { - httpOnly: true, - sameSite: 'lax', - path: '/', - secure: process.env.NODE_ENV === 'production' - } - } - }, - logger: { - error(code: any, ...message: any[]) { - console.error(code, message); - }, - warn(code: any, ...message: any[]) { - console.warn(code, message); - }, - debug(code: any, ...message: any[]) { - console.debug(code, message); - } - } -}); diff --git a/src/components/navigation/custom-link.tsx b/src/components/navigation/custom-link.tsx new file mode 100644 index 0000000..5cfb564 --- /dev/null +++ b/src/components/navigation/custom-link.tsx @@ -0,0 +1,39 @@ +import { Link } from '@/lib/i18n/navigation'; +import { UrlObject } from 'url'; + +interface CustomLinkProps { + href: string | UrlObject; + children: React.ReactNode; + className?: string; + onClick?: () => void; +} + +const isInternalLink = (href: string | UrlObject): boolean => { + if (typeof href !== 'string') return true; + + try { + const url = new URL(href, window.location.origin); + return url.hostname === window.location.hostname; + } catch { + return true; + } +}; + +export function CustomLink({ href, children, className, ...props }: CustomLinkProps) { + const hrefString = typeof href === 'string' ? href : href.pathname || ''; + const internal = isInternalLink(href); + + if (!internal) { + return ( + + {children} + + ); + } + + return ( + + {children} + + ); +} diff --git a/src/components/navigation/footer-menu.tsx b/src/components/navigation/footer-menu.tsx index 080768e..c9e3507 100644 --- a/src/components/navigation/footer-menu.tsx +++ b/src/components/navigation/footer-menu.tsx @@ -1,6 +1,6 @@ -import Link from 'next/link'; import { ArrowRight, LucideIcon } from 'lucide-react'; import { useTranslations } from 'next-intl'; +import { CustomLink } from '.'; interface FooterMenuProps { title: string; @@ -29,14 +29,14 @@ export function FooterMenu({
diff --git a/src/components/navigation/index.ts b/src/components/navigation/index.ts index 575a586..9af337f 100644 --- a/src/components/navigation/index.ts +++ b/src/components/navigation/index.ts @@ -1,2 +1,3 @@ export * from './navbar'; export * from './footer-menu'; +export * from './custom-link'; diff --git a/src/components/shared/index.ts b/src/components/shared/index.ts index e17a58c..993a7ff 100644 --- a/src/components/shared/index.ts +++ b/src/components/shared/index.ts @@ -9,3 +9,4 @@ export * from './small-loading'; export * from './text-rotator'; export * from './themed-image'; export * from './version'; +export * from './page-loading'; diff --git a/src/components/shared/page-loading.tsx b/src/components/shared/page-loading.tsx new file mode 100644 index 0000000..fc37581 --- /dev/null +++ b/src/components/shared/page-loading.tsx @@ -0,0 +1,18 @@ +import { getTranslations } from 'next-intl/server'; + +import { Loading } from '@/components/shared'; +import { cn } from '@/lib'; + +interface Props { + text?: string; + className?: string; +} + +export async function PageLoading({ text, className }: Props) { + if (!text) { + const t = await getTranslations('app'); + text = t('loading'); + } + + return ; +} diff --git a/src/contexts/user-context.tsx b/src/contexts/user-context.tsx deleted file mode 100644 index 3e5bf8f..0000000 --- a/src/contexts/user-context.tsx +++ /dev/null @@ -1,38 +0,0 @@ -'use client'; - -import { createContext, useContext, useState, useEffect, ReactNode } from 'react'; -import { useSession } from 'next-auth/react'; -import { UserContextType, UserData } from '@/types/user'; - -const UserContext = createContext(undefined); - -export const UserProvider = ({ children }: { children: ReactNode }) => { - const { data: session, status } = useSession(); - const [user, setUser] = useState(session?.user || null); - - useEffect(() => { - if (session) { - setUser(session.user as UserData); - } - }, [session]); - - const updateUser = (newUserData: UserData) => { - setUser(newUserData); - }; - - const contextValue: UserContextType = { - user, - updateUser, - isLoading: status === 'loading' - }; - - return {children}; -}; - -export const useUser = () => { - const context = useContext(UserContext); - if (!context) { - throw new Error('useUser must be used within a UserProvider'); - } - return context; -}; diff --git a/src/hooks/useHotkeys.ts b/src/hooks/useHotkeys.ts index fe397cc..7bfc07f 100644 --- a/src/hooks/useHotkeys.ts +++ b/src/hooks/useHotkeys.ts @@ -59,5 +59,5 @@ export function useHotkeys(shortcuts: Shortcut[], dependencies: React.Dependency return () => { document.removeEventListener('keydown', down); }; - }, [...dependencies, shortcuts]); + }, [shortcuts, dependencies]); } diff --git a/src/hooks/useNewsletterConfirmDialog.ts b/src/hooks/useNewsletterConfirmDialog.ts index 32e291d..310bf56 100644 --- a/src/hooks/useNewsletterConfirmDialog.ts +++ b/src/hooks/useNewsletterConfirmDialog.ts @@ -51,7 +51,7 @@ export const useNewsletterConfirmDialog = (t: (key: string) => string) => { setStatus('error'); setMessage(t('app.errors.general')); }); - }, [searchParams, requestSent, router]); + }, [searchParams, requestSent, router, t]); const onOpenChange = useCallback( (open: boolean) => { diff --git a/src/middleware.ts b/src/middleware.ts index 6591e55..7c6a02b 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,54 +1,10 @@ -import { NextRequest, NextResponse } from 'next/server'; +import { NextRequest } from 'next/server'; import createMiddleware from 'next-intl/middleware'; import { routing } from './lib/i18n/routing'; -import { PUBLIC_ROUTES } from './constants'; -import { handleRateLimit } from './middlewares'; const intlMiddleware = createMiddleware(routing); export default function middleware(request: NextRequest) { - const publicRoutes = ['/api/newsletter/subscribe', ...PUBLIC_ROUTES]; - - if (request.nextUrl.pathname.startsWith('/api/')) { - const isAuthRoute = request.nextUrl.pathname.startsWith('/api/auth/'); - const isInternalRoute = request.nextUrl.pathname.startsWith('/api/internal/'); - - if (!isAuthRoute && !isInternalRoute) { - return handleRateLimit(request); - } - - return NextResponse.next(); - } - - const publicPathnameRegex = RegExp( - `^(/(${routing.locales.join('|')}))?(${publicRoutes - .flatMap((p) => (p === '/' ? ['', '/'] : p)) - .join('|')})/?$`, - 'i' - ); - - const isPublicPage = publicPathnameRegex.test(request.nextUrl.pathname); - - if (isPublicPage) { - return intlMiddleware(request); - } - - // Check for session token in cookies - const sessionToken = request.cookies.get( - process.env.NODE_ENV === 'production' - ? '__Secure-authjs.session-token' - : 'authjs.session-token' - ); - - if (!sessionToken?.value) { - // Redirect to login page with locale support - const signInUrl = new URL('/login', request.url); - if (request.nextUrl.pathname !== '/login') { - signInUrl.searchParams.set('callbackUrl', request.url); - } - return NextResponse.redirect(signInUrl); - } - return intlMiddleware(request); } diff --git a/src/styles/globals.css b/src/styles/globals.css index 7ff0ea4..7e9b335 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -1,5 +1,6 @@ @import 'tailwindcss'; @import 'tw-animate-css'; +@import './themes.css'; @custom-variant dark (&:is(.dark *)); diff --git a/src/styles/themes.css b/src/styles/themes.css new file mode 100644 index 0000000..99e9def --- /dev/null +++ b/src/styles/themes.css @@ -0,0 +1,55 @@ +@layer base { + /* Zinc Theme */ + .theme-zinc { + --background: oklch(1 0 0); + --foreground: oklch(0.15 0.01 265); + --card: oklch(1 0 0); + --card-foreground: oklch(0.15 0.01 265); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.15 0.01 265); + --primary: oklch(0.65 0.02 270); + --primary-foreground: oklch(0.98 0 0); + --secondary: oklch(0.94 0.01 270); + --secondary-foreground: oklch(0.15 0.01 265); + --muted: oklch(0.94 0.01 270); + --muted-foreground: oklch(0.45 0.01 265); + --accent: oklch(0.94 0.01 270); + --accent-foreground: oklch(0.15 0.01 265); + --destructive: oklch(0.65 0.2 25); + --border: oklch(0.94 0.01 270); + --input: oklch(0.94 0.01 270); + --ring: oklch(0.65 0.02 270); + } + + .dark.theme-zinc { + --background: oklch(0.17 0.01 265); + --foreground: oklch(0.96 0.01 270); + --card: oklch(0.17 0.01 265); + --card-foreground: oklch(0.96 0.01 270); + --popover: oklch(0.17 0.01 265); + --popover-foreground: oklch(0.96 0.01 270); + --primary: oklch(0.96 0.01 270); + --primary-foreground: oklch(0.15 0.01 265); + --secondary: oklch(0.24 0.01 270); + --secondary-foreground: oklch(0.96 0.01 270); + --muted: oklch(0.24 0.01 270); + --muted-foreground: oklch(0.65 0.01 265); + --accent: oklch(0.24 0.01 270); + --accent-foreground: oklch(0.96 0.01 270); + --destructive: oklch(0.65 0.2 25); + --border: oklch(0.24 0.01 270); + --input: oklch(0.24 0.01 270); + --ring: oklch(0.3 0.01 270); + } + + /* Rose Theme */ + .theme-rose { + --primary: oklch(0.6 0.2 15); + --ring: oklch(0.6 0.2 15); + } + + .dark.theme-rose { + --primary: oklch(0.7 0.15 15); + --ring: oklch(0.7 0.15 15); + } +} diff --git a/src/types/custom.d.ts b/src/types/custom.d.ts new file mode 100644 index 0000000..83b5cf8 --- /dev/null +++ b/src/types/custom.d.ts @@ -0,0 +1,4 @@ +declare module '*.css' { + const content: Record; + export default content; +}