Compare commits
1 Commits
fix/update
...
feat/intl-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78cdc7b539 |
@@ -1,34 +0,0 @@
|
|||||||
name: PR Checks
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened, ready_for_review]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
lint-and-build:
|
|
||||||
runs-on: node-22
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: 📥 Install dependencies
|
|
||||||
run: npm ci
|
|
||||||
|
|
||||||
- name: 🔍 Run ESLint
|
|
||||||
run: npm run lint
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: 💅 Check code formatting (Prettier)
|
|
||||||
run: npm run format:check
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: 🔤 TypeScript type checking
|
|
||||||
run: npx tsc --noEmit
|
|
||||||
|
|
||||||
- name: ✅ All quality checks passed
|
|
||||||
run: |
|
|
||||||
echo "✅ All code quality checks passed successfully!"
|
|
||||||
echo " - ESLint: No linting errors"
|
|
||||||
echo " - Prettier: Code is properly formatted"
|
|
||||||
echo " - TypeScript: No type errors"
|
|
||||||
@@ -1,384 +0,0 @@
|
|||||||
# Gitea Actions Workflow for Next.js Blog Application - Staging Environment
|
|
||||||
# This workflow builds a Docker image and deploys it to staging
|
|
||||||
#
|
|
||||||
# Workflow triggers:
|
|
||||||
# - Push to staging branch (automatic deployment)
|
|
||||||
# - Manual trigger via workflow_dispatch
|
|
||||||
#
|
|
||||||
# Required Secrets (configure in Gitea repository settings):
|
|
||||||
# - PRODUCTION_HOST: IP address or hostname of production server (same server hosts staging)
|
|
||||||
# - PRODUCTION_USER: SSH username (e.g., 'deployer')
|
|
||||||
# - SSH_PRIVATE_KEY: Private SSH key for authentication
|
|
||||||
#
|
|
||||||
# Environment Variables (configured below):
|
|
||||||
# - REGISTRY: Docker registry URL
|
|
||||||
# - IMAGE_NAME: Docker image name
|
|
||||||
#
|
|
||||||
# Docker Registry Configuration:
|
|
||||||
# - Current registry (repository.workspace:5000) is INSECURE - no authentication required
|
|
||||||
# - Registry login steps are SKIPPED to avoid 7+ minute timeout delays
|
|
||||||
# - Docker push/pull operations work without credentials
|
|
||||||
# - If switching to authenticated registry: uncomment login steps and configure secrets
|
|
||||||
|
|
||||||
name: Build and Deploy Next.js Blog to Staging
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- staging # Trigger on push to staging branch
|
|
||||||
workflow_dispatch: # Allow manual trigger from Gitea UI
|
|
||||||
|
|
||||||
env:
|
|
||||||
# Docker registry configuration
|
|
||||||
# Update this to match your private registry URL
|
|
||||||
REGISTRY: repository.workspace:5000
|
|
||||||
IMAGE_NAME: mypage
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
# ============================================
|
|
||||||
# Job 1: Code Quality Checks (Linting)
|
|
||||||
# ============================================
|
|
||||||
lint:
|
|
||||||
name: 🔍 Code Quality Checks
|
|
||||||
runs-on: node-22
|
|
||||||
# env:
|
|
||||||
# ACTIONS_RUNTIME_URL: http://192.168.1.53:3000 # Setează la nivel de job
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: 🔎 Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
# with:
|
|
||||||
# github-server-url: ${{ env.ACTIONS_RUNTIME_URL }}
|
|
||||||
|
|
||||||
# - name: 📦 Setup Node.js
|
|
||||||
# uses: actions/setup-node@v4
|
|
||||||
# with:
|
|
||||||
# node-version: "22"
|
|
||||||
# cache: "npm"
|
|
||||||
|
|
||||||
- name: 📥 Install dependencies
|
|
||||||
run: npm ci
|
|
||||||
|
|
||||||
- name: 🔍 Run ESLint
|
|
||||||
run: npm run lint
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: 💅 Check code formatting (Prettier)
|
|
||||||
run: npm run format:check
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: 🔤 TypeScript type checking
|
|
||||||
run: npx tsc --noEmit
|
|
||||||
|
|
||||||
- name: ✅ All quality checks passed
|
|
||||||
run: |
|
|
||||||
echo "✅ All code quality checks passed successfully!"
|
|
||||||
echo " - ESLint: No linting errors"
|
|
||||||
echo " - Prettier: Code is properly formatted"
|
|
||||||
echo " - TypeScript: No type errors"
|
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# Job 2: Build and Push Docker Image
|
|
||||||
# ============================================
|
|
||||||
build-and-push:
|
|
||||||
name: 🏗️ Build and Push Docker Image
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [lint] # Wait for lint job to complete successfully
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: 🔎 Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: 📝 Create .env file from Gitea secrets
|
|
||||||
run: |
|
|
||||||
echo "Creating .env file for Docker build..."
|
|
||||||
cat > .env << EOF
|
|
||||||
# Build-time environment variables
|
|
||||||
NEXT_PUBLIC_SITE_URL=${{ vars.NEXT_PUBLIC_SITE_URL }}
|
|
||||||
NODE_ENV=production
|
|
||||||
NEXT_TELEMETRY_DISABLED=1
|
|
||||||
|
|
||||||
# Add other build-time variables here as needed
|
|
||||||
# NEXT_PUBLIC_GA_ID=${{ vars.NEXT_PUBLIC_GA_ID }}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "✅ .env file created successfully"
|
|
||||||
echo "Preview (secrets masked):"
|
|
||||||
cat .env | sed 's/=.*/=***MASKED***/g'
|
|
||||||
|
|
||||||
# Insecure registry configuration - no authentication required
|
|
||||||
# The registry at repository.workspace:5000 does not require login
|
|
||||||
# Docker push/pull operations work without credentials
|
|
||||||
- name: ℹ️ Registry configuration (insecure - no login required)
|
|
||||||
run: |
|
|
||||||
echo "=== Docker Registry Configuration ==="
|
|
||||||
echo "Registry: ${{ env.REGISTRY }}"
|
|
||||||
echo "Type: Insecure (no authentication required)"
|
|
||||||
echo ""
|
|
||||||
echo "ℹ️ Skipping registry login - insecure registry allows push/pull without credentials"
|
|
||||||
echo ""
|
|
||||||
echo "If your registry requires authentication in the future:"
|
|
||||||
echo " 1. Set REGISTRY_USERNAME and REGISTRY_PASSWORD secrets in Gitea"
|
|
||||||
echo " 2. Uncomment the login step below this message"
|
|
||||||
echo " 3. Change registry URL to authenticated registry"
|
|
||||||
|
|
||||||
# Uncomment this step if registry requires authentication in the future
|
|
||||||
# - name: 🔐 Log in to Docker Registry
|
|
||||||
# timeout-minutes: 1
|
|
||||||
# run: |
|
|
||||||
# if [ -n "${{ secrets.REGISTRY_USERNAME }}" ] && [ -n "${{ secrets.REGISTRY_PASSWORD }}" ]; then
|
|
||||||
# echo "Attempting login to ${{ env.REGISTRY }}..."
|
|
||||||
# timeout 30s bash -c 'echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin' || {
|
|
||||||
# echo "⚠️ Login failed - continuing anyway"
|
|
||||||
# }
|
|
||||||
# fi
|
|
||||||
|
|
||||||
- name: 🏗️ Build Docker image
|
|
||||||
timeout-minutes: 30
|
|
||||||
env:
|
|
||||||
DOCKER_BUILDKIT: 1 # Enable BuildKit for faster builds and better caching
|
|
||||||
run: |
|
|
||||||
echo "Building Next.js Docker image with BuildKit (staging)..."
|
|
||||||
echo "Build context size:"
|
|
||||||
du -sh . 2>/dev/null || echo "Cannot measure context size"
|
|
||||||
|
|
||||||
# Build the Docker image for staging
|
|
||||||
# - Uses Dockerfile.nextjs from project root
|
|
||||||
# - Tags image with 'staging' tag
|
|
||||||
# - Enables inline cache for faster subsequent builds
|
|
||||||
docker build \
|
|
||||||
--progress=plain \
|
|
||||||
--build-arg BUILDKIT_INLINE_CACHE=1 \
|
|
||||||
-t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:staging \
|
|
||||||
-f Dockerfile.nextjs \
|
|
||||||
.
|
|
||||||
|
|
||||||
echo "✅ Build successful"
|
|
||||||
echo "Image size:"
|
|
||||||
docker images ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:staging
|
|
||||||
|
|
||||||
- name: 🚀 Push Docker image to registry
|
|
||||||
run: |
|
|
||||||
echo "Pushing staging image to registry..."
|
|
||||||
|
|
||||||
# Push staging tag
|
|
||||||
docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:staging
|
|
||||||
|
|
||||||
echo "✅ Image pushed successfully"
|
|
||||||
echo " - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:staging"
|
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# Job 3: Deploy to Staging Server
|
|
||||||
# ============================================
|
|
||||||
deploy-staging:
|
|
||||||
name: 🚀 Deploy to Staging
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: [build-and-push] # Wait for build job to complete
|
|
||||||
environment:
|
|
||||||
name: staging
|
|
||||||
url: http://192.168.1.54:3031
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: 🔎 Checkout code (for docker-compose file)
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
# Verify Docker is accessible on staging server
|
|
||||||
# Registry authentication is not required for insecure registry
|
|
||||||
- name: ℹ️ Verify staging server Docker access
|
|
||||||
uses: appleboy/ssh-action@v1.0.3
|
|
||||||
with:
|
|
||||||
host: ${{ vars.PRODUCTION_HOST }}
|
|
||||||
username: ${{ vars.PRODUCTION_USER }}
|
|
||||||
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
|
||||||
port: 22
|
|
||||||
script: |
|
|
||||||
echo "=== Verifying Docker is accessible ==="
|
|
||||||
docker info > /dev/null 2>&1 || {
|
|
||||||
echo "❌ Docker is not running or user has no access"
|
|
||||||
echo "Please ensure Docker is installed and user is in docker group"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
echo "✅ Docker is accessible"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=== Registry Configuration ==="
|
|
||||||
echo "Registry: ${{ env.REGISTRY }}"
|
|
||||||
echo "Type: Insecure (no authentication)"
|
|
||||||
echo "ℹ️ Skipping registry login - push/pull will work without credentials"
|
|
||||||
|
|
||||||
- name: 📁 Ensure staging directory structure
|
|
||||||
uses: appleboy/ssh-action@v1.0.3
|
|
||||||
with:
|
|
||||||
host: ${{ vars.PRODUCTION_HOST }}
|
|
||||||
username: ${{ vars.PRODUCTION_USER }}
|
|
||||||
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
|
||||||
port: 22
|
|
||||||
script: |
|
|
||||||
echo "=== Ensuring staging directory structure ==="
|
|
||||||
|
|
||||||
# Verify base directory exists and is writable
|
|
||||||
# Update /opt/mypage-staging to match your deployment directory
|
|
||||||
if [ ! -d /opt/mypage-staging ]; then
|
|
||||||
echo "❌ /opt/mypage-staging does not exist!"
|
|
||||||
echo "Please run manually on staging server:"
|
|
||||||
echo " sudo mkdir -p /opt/mypage-staging"
|
|
||||||
echo " sudo chown -R deployer:docker /opt/mypage-staging"
|
|
||||||
echo " sudo chmod -R 775 /opt/mypage-staging"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -w /opt/mypage-staging ]; then
|
|
||||||
echo "❌ /opt/mypage-staging is not writable by $USER user"
|
|
||||||
echo "Please run manually on staging server:"
|
|
||||||
echo " sudo chown -R deployer:docker /opt/mypage-staging"
|
|
||||||
echo " sudo chmod -R 775 /opt/mypage-staging"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create data directories for logs
|
|
||||||
mkdir -p /opt/mypage-staging/data/logs || { echo "❌ Failed to create logs directory"; exit 1; }
|
|
||||||
|
|
||||||
echo "✅ Directory structure ready"
|
|
||||||
ls -la /opt/mypage-staging
|
|
||||||
|
|
||||||
- name: 📦 Copy docker-compose.staging.yml to staging server
|
|
||||||
uses: appleboy/scp-action@v0.1.7
|
|
||||||
with:
|
|
||||||
host: ${{ vars.PRODUCTION_HOST }}
|
|
||||||
username: ${{ vars.PRODUCTION_USER }}
|
|
||||||
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
|
||||||
port: 22
|
|
||||||
source: "docker-compose.staging.yml"
|
|
||||||
target: "/opt/mypage-staging/"
|
|
||||||
overwrite: true
|
|
||||||
|
|
||||||
- name: 🐳 Deploy application via Docker Compose
|
|
||||||
uses: appleboy/ssh-action@v1.0.3
|
|
||||||
env:
|
|
||||||
# Optional: only needed if registry requires authentication
|
|
||||||
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD || '' }}
|
|
||||||
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME || '' }}
|
|
||||||
REGISTRY_URL: ${{ env.REGISTRY }}
|
|
||||||
IMAGE_FULL: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:staging
|
|
||||||
with:
|
|
||||||
host: ${{ vars.PRODUCTION_HOST }}
|
|
||||||
username: ${{ vars.PRODUCTION_USER }}
|
|
||||||
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
|
||||||
port: 22
|
|
||||||
envs: REGISTRY_PASSWORD,REGISTRY_USERNAME,REGISTRY_URL,IMAGE_FULL
|
|
||||||
script_stop: true # Stop execution on any error
|
|
||||||
script: |
|
|
||||||
echo "=== Starting deployment to staging server ==="
|
|
||||||
cd /opt/mypage-staging
|
|
||||||
|
|
||||||
# Registry configuration - insecure registry does not require authentication
|
|
||||||
echo "=== Registry Configuration ==="
|
|
||||||
echo "Registry: $REGISTRY_URL"
|
|
||||||
echo "Type: Insecure (no authentication required)"
|
|
||||||
echo "ℹ️ Skipping registry login"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Verify docker-compose.staging.yml exists (copied by previous step)
|
|
||||||
if [ ! -f docker-compose.staging.yml ]; then
|
|
||||||
echo "❌ docker-compose.staging.yml not found in /opt/mypage-staging"
|
|
||||||
echo "File should have been copied by CI/CD workflow"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "✅ Using docker-compose.staging.yml"
|
|
||||||
|
|
||||||
# Pull latest staging image from registry
|
|
||||||
echo "=== Pulling latest Docker image (staging) ==="
|
|
||||||
docker pull "$IMAGE_FULL"
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "❌ Failed to pull image, aborting deployment"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Deploy new container
|
|
||||||
# - Stops old container
|
|
||||||
# - Removes old container
|
|
||||||
# - Creates and starts new container with fresh image
|
|
||||||
echo "=== Deploying new staging container ==="
|
|
||||||
docker compose -f docker-compose.staging.yml up -d --force-recreate
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "❌ Failed to deploy new container"
|
|
||||||
echo "Check logs above for errors"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check container status
|
|
||||||
echo "=== Container Status ==="
|
|
||||||
docker compose -f docker-compose.staging.yml ps
|
|
||||||
|
|
||||||
# Show recent logs for debugging
|
|
||||||
echo "=== Recent application logs ==="
|
|
||||||
docker compose -f docker-compose.staging.yml logs --tail=50
|
|
||||||
|
|
||||||
# Clean up old/unused images to save disk space
|
|
||||||
echo "=== Cleaning up old Docker images ==="
|
|
||||||
docker image prune -f
|
|
||||||
|
|
||||||
echo "✅ Staging deployment completed successfully ==="
|
|
||||||
|
|
||||||
- name: ❤️ Health check
|
|
||||||
uses: appleboy/ssh-action@v1.0.3
|
|
||||||
with:
|
|
||||||
host: ${{ vars.PRODUCTION_HOST }}
|
|
||||||
username: ${{ vars.PRODUCTION_USER }}
|
|
||||||
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
|
||||||
port: 22
|
|
||||||
script: |
|
|
||||||
echo "=== Performing health check ==="
|
|
||||||
cd /opt/mypage-staging
|
|
||||||
max_attempts=15
|
|
||||||
attempt=1
|
|
||||||
|
|
||||||
# Wait for container to be healthy (respect start_period from health check)
|
|
||||||
echo "Waiting for application to start (40s start period)..."
|
|
||||||
sleep 40
|
|
||||||
|
|
||||||
# Retry health check up to 15 times
|
|
||||||
while [ $attempt -le $max_attempts ]; do
|
|
||||||
# Check if application responds at port 3031
|
|
||||||
if curl -f http://localhost:3031/ > /dev/null 2>&1; then
|
|
||||||
echo "✅ Health check passed!"
|
|
||||||
echo "Application is healthy and responding to requests"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
echo "Attempt $attempt/$max_attempts: Health check failed, retrying in 5s..."
|
|
||||||
sleep 5
|
|
||||||
attempt=$((attempt + 1))
|
|
||||||
done
|
|
||||||
|
|
||||||
# Health check failed - gather diagnostic information
|
|
||||||
echo "❌ Health check failed after $max_attempts attempts"
|
|
||||||
echo ""
|
|
||||||
echo "=== Container Status ==="
|
|
||||||
docker compose -f docker-compose.staging.yml ps
|
|
||||||
echo ""
|
|
||||||
echo "=== Container Health ==="
|
|
||||||
docker inspect mypage-staging --format='{{.State.Health.Status}}' 2>/dev/null || echo "No health status"
|
|
||||||
echo ""
|
|
||||||
echo "=== Recent Application Logs ==="
|
|
||||||
docker compose -f docker-compose.staging.yml logs --tail=100
|
|
||||||
|
|
||||||
exit 1
|
|
||||||
|
|
||||||
- name: 📊 Deployment summary
|
|
||||||
if: always() # Run even if previous steps fail
|
|
||||||
run: |
|
|
||||||
echo "### 🚀 Deployment Summary" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "- **Environment**: Staging" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "- **Image**: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:staging" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "- **Commit**: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "- **Workflow Run**: #${{ github.run_number }}" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "- **Triggered By**: ${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "- **Status**: ${{ job.status }}" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "**Next Steps:**" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "1. Verify application is accessible at http://192.168.1.54:3031" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "2. Check application logs for any errors" >> $GITHUB_STEP_SUMMARY
|
|
||||||
echo "3. Test staging features before promoting to production" >> $GITHUB_STEP_SUMMARY
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
# Docker Compose Configuration for Staging Deployment
|
|
||||||
# This file is used by CI/CD to deploy the application on staging servers
|
|
||||||
#
|
|
||||||
# Key differences from production docker-compose.prod.yml:
|
|
||||||
# - Container name: mypage-staging (vs mypage-prod)
|
|
||||||
# - Port mapping: 3031:3030 (vs 3030:3030)
|
|
||||||
# - Network name: mypage-staging-network (vs mypage-network)
|
|
||||||
# - Image tag: staging (vs latest)
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# 1. This file is automatically copied to server by CI/CD workflow
|
|
||||||
# 2. Server pulls image from registry: docker compose -f docker-compose.staging.yml pull
|
|
||||||
# 3. Server starts container: docker compose -f docker-compose.staging.yml up -d
|
|
||||||
#
|
|
||||||
# Manual deployment (if CI/CD is not available):
|
|
||||||
# ssh user@staging-server
|
|
||||||
# cd /opt/mypage-staging
|
|
||||||
# docker compose -f docker-compose.staging.yml pull
|
|
||||||
# docker compose -f docker-compose.staging.yml up -d --force-recreate
|
|
||||||
|
|
||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
|
||||||
mypage:
|
|
||||||
# Use pre-built image from private registry with staging tag
|
|
||||||
# This image is built and pushed by the CI/CD workflow
|
|
||||||
# Format: REGISTRY_URL/IMAGE_NAME:TAG
|
|
||||||
image: repository.workspace:5000/mypage:staging
|
|
||||||
|
|
||||||
container_name: mypage-staging
|
|
||||||
|
|
||||||
# Restart policy: always restart on failure or server reboot
|
|
||||||
# This ensures high availability in staging
|
|
||||||
restart: always
|
|
||||||
|
|
||||||
# Port mapping: host:container
|
|
||||||
# Staging runs on port 3031 to avoid conflicts with production (3030)
|
|
||||||
# The application will be accessible at http://SERVER_IP:3031
|
|
||||||
ports:
|
|
||||||
- "3031:3030"
|
|
||||||
|
|
||||||
# Staging environment variables
|
|
||||||
environment:
|
|
||||||
- NODE_ENV=production
|
|
||||||
- NEXT_TELEMETRY_DISABLED=1
|
|
||||||
- PORT=3030
|
|
||||||
- HOSTNAME=0.0.0.0
|
|
||||||
# Add any other staging-specific environment variables here
|
|
||||||
# Example:
|
|
||||||
# - DATABASE_URL=postgresql://user:pass@db:5432/mypage_staging
|
|
||||||
# - REDIS_URL=redis://redis:6379
|
|
||||||
|
|
||||||
# Persistent volumes for logs (optional)
|
|
||||||
# Uncomment if your application writes logs
|
|
||||||
volumes:
|
|
||||||
- ./data/logs:/app/logs
|
|
||||||
|
|
||||||
# Health check configuration
|
|
||||||
# Docker monitors the application and marks it unhealthy if checks fail
|
|
||||||
# If container is unhealthy, restart policy will trigger a restart
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:3030/", "||", "exit", "1"]
|
|
||||||
interval: 30s # Check every 30 seconds
|
|
||||||
timeout: 10s # Wait up to 10 seconds for response
|
|
||||||
retries: 3 # Mark unhealthy after 3 consecutive failures
|
|
||||||
start_period: 40s # Grace period during container startup
|
|
||||||
|
|
||||||
# Resource limits for staging
|
|
||||||
# Prevents container from consuming all server resources
|
|
||||||
# deploy:
|
|
||||||
# resources:
|
|
||||||
# limits:
|
|
||||||
# cpus: '1.0' # Maximum 1 CPU core
|
|
||||||
# memory: 512M # Maximum 512MB RAM
|
|
||||||
# reservations:
|
|
||||||
# cpus: '0.25' # Reserve at least 0.25 CPU cores
|
|
||||||
# memory: 256M # Reserve at least 256MB RAM
|
|
||||||
|
|
||||||
# Network configuration
|
|
||||||
networks:
|
|
||||||
- mypage-staging-network
|
|
||||||
|
|
||||||
# Logging configuration
|
|
||||||
# Prevents logs from consuming all disk space
|
|
||||||
logging:
|
|
||||||
driver: "json-file"
|
|
||||||
options:
|
|
||||||
max-size: "10m" # Maximum 10MB per log file
|
|
||||||
max-file: "3" # Keep only 3 log files (30MB total)
|
|
||||||
|
|
||||||
# Network definition
|
|
||||||
networks:
|
|
||||||
mypage-staging-network:
|
|
||||||
driver: bridge
|
|
||||||
|
|
||||||
# ============================================
|
|
||||||
# Staging Deployment Commands
|
|
||||||
# ============================================
|
|
||||||
#
|
|
||||||
# Pull latest image from registry:
|
|
||||||
# docker compose -f docker-compose.staging.yml pull
|
|
||||||
#
|
|
||||||
# Start/update containers:
|
|
||||||
# docker compose -f docker-compose.staging.yml up -d --force-recreate
|
|
||||||
#
|
|
||||||
# View logs:
|
|
||||||
# docker compose -f docker-compose.staging.yml logs -f mypage
|
|
||||||
#
|
|
||||||
# Check health status:
|
|
||||||
# docker inspect mypage-staging | grep -A 10 Health
|
|
||||||
#
|
|
||||||
# Stop containers:
|
|
||||||
# docker compose -f docker-compose.staging.yml down
|
|
||||||
#
|
|
||||||
# Restart containers:
|
|
||||||
# docker compose -f docker-compose.staging.yml restart
|
|
||||||
#
|
|
||||||
# Remove old/unused images (cleanup):
|
|
||||||
# docker image prune -f
|
|
||||||
#
|
|
||||||
# ============================================
|
|
||||||
# Troubleshooting
|
|
||||||
# ============================================
|
|
||||||
#
|
|
||||||
# If container keeps restarting:
|
|
||||||
# 1. Check logs: docker compose -f docker-compose.staging.yml logs --tail=100
|
|
||||||
# 2. Check health: docker inspect mypage-staging | grep -A 10 Health
|
|
||||||
# 3. Verify port is not already in use: netstat -tulpn | grep 3031
|
|
||||||
# 4. Check resource usage: docker stats mypage-staging
|
|
||||||
#
|
|
||||||
# If health check fails:
|
|
||||||
# 1. Test manually: docker exec mypage-staging curl -f http://localhost:3030/
|
|
||||||
# 2. Check if Next.js server is running: docker exec mypage-staging ps aux
|
|
||||||
# 3. Verify environment variables: docker exec mypage-staging env
|
|
||||||
#
|
|
||||||
379
package-lock.json
generated
379
package-lock.json
generated
@@ -11,16 +11,16 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tailwindcss/postcss": "^4.1.17",
|
"@tailwindcss/postcss": "^4.1.17",
|
||||||
"@tailwindcss/typography": "^0.5.19",
|
"@tailwindcss/typography": "^0.5.19",
|
||||||
"@types/node": "^24.10.1",
|
"@types/node": "^24.10.0",
|
||||||
"@types/react": "^19.2.7",
|
"@types/react": "^19.2.2",
|
||||||
"autoprefixer": "^10.4.22",
|
"autoprefixer": "^10.4.21",
|
||||||
"gray-matter": "^4.0.3",
|
"gray-matter": "^4.0.3",
|
||||||
"next": "^16.0.7",
|
"next": "^16.0.1",
|
||||||
"next-intl": "^4.5.8",
|
"next-intl": "^4.5.7",
|
||||||
"next-themes": "^0.4.6",
|
"next-themes": "^0.4.6",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.6",
|
||||||
"react": "^19.2.1",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.1",
|
"react-dom": "^19.2.0",
|
||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
"rehype-raw": "^7.0.0",
|
"rehype-raw": "^7.0.0",
|
||||||
"rehype-sanitize": "^6.0.0",
|
"rehype-sanitize": "^6.0.0",
|
||||||
@@ -32,17 +32,17 @@
|
|||||||
"unist-util-visit": "^5.0.0"
|
"unist-util-visit": "^5.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/eslintrc": "^3.3.3",
|
"@eslint/eslintrc": "^3.3.1",
|
||||||
"@eslint/js": "^9.39.1",
|
"@eslint/js": "^9.39.1",
|
||||||
"@next/bundle-analyzer": "^16.0.7",
|
"@next/bundle-analyzer": "^16.0.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.48.1",
|
"@typescript-eslint/eslint-plugin": "^8.46.4",
|
||||||
"@typescript-eslint/parser": "^8.48.1",
|
"@typescript-eslint/parser": "^8.46.4",
|
||||||
"eslint": "^9.39.1",
|
"eslint": "^9.39.1",
|
||||||
"eslint-config-next": "^16.0.7",
|
"eslint-config-next": "^16.0.3",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-prettier": "^5.5.4",
|
"eslint-plugin-prettier": "^5.5.4",
|
||||||
"prettier": "^3.7.4",
|
"prettier": "^3.6.2",
|
||||||
"typescript-eslint": "^8.48.1"
|
"typescript-eslint": "^8.46.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@alloc/quick-lru": {
|
"node_modules/@alloc/quick-lru": {
|
||||||
@@ -453,9 +453,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/eslintrc": {
|
"node_modules/@eslint/eslintrc": {
|
||||||
"version": "3.3.3",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
|
||||||
"integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==",
|
"integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -465,7 +465,7 @@
|
|||||||
"globals": "^14.0.0",
|
"globals": "^14.0.0",
|
||||||
"ignore": "^5.2.0",
|
"ignore": "^5.2.0",
|
||||||
"import-fresh": "^3.2.1",
|
"import-fresh": "^3.2.1",
|
||||||
"js-yaml": "^4.1.1",
|
"js-yaml": "^4.1.0",
|
||||||
"minimatch": "^3.1.2",
|
"minimatch": "^3.1.2",
|
||||||
"strip-json-comments": "^3.1.1"
|
"strip-json-comments": "^3.1.1"
|
||||||
},
|
},
|
||||||
@@ -1202,9 +1202,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/bundle-analyzer": {
|
"node_modules/@next/bundle-analyzer": {
|
||||||
"version": "16.0.7",
|
"version": "16.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-16.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-16.0.3.tgz",
|
||||||
"integrity": "sha512-Um2YA3TSQND+DpqlMDuPZsdjdpcgLzo1wF3zx4zcBCLecS7ucP7O9YFqvHhg000HXTgt++KIjZ9FUwyJSKk1Kw==",
|
"integrity": "sha512-6Xo8f8/ZXtASfTPa6TH1aUn+xDg9Pkyl1YHVxu+89cVdLH7MnYjxv3rPOfEJ9BwCZCU2q4Flyw5MwltfD2pGbA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1212,25 +1212,55 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/env": {
|
"node_modules/@next/env": {
|
||||||
"version": "16.0.7",
|
"version": "16.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.0.1.tgz",
|
||||||
"integrity": "sha512-gpaNgUh5nftFKRkRQGnVi5dpcYSKGcZZkQffZ172OrG/XkrnS7UBTQ648YY+8ME92cC4IojpI2LqTC8sTDhAaw==",
|
"integrity": "sha512-LFvlK0TG2L3fEOX77OC35KowL8D7DlFF45C0OvKMC4hy8c/md1RC4UMNDlUGJqfCoCS2VWrZ4dSE6OjaX5+8mw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@next/eslint-plugin-next": {
|
"node_modules/@next/eslint-plugin-next": {
|
||||||
"version": "16.0.7",
|
"version": "16.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.0.3.tgz",
|
||||||
"integrity": "sha512-hFrTNZcMEG+k7qxVxZJq3F32Kms130FAhG8lvw2zkKBgAcNOJIxlljNiCjGygvBshvaGBdf88q2CqWtnqezDHA==",
|
"integrity": "sha512-6sPWmZetzFWMsz7Dhuxsdmbu3fK+/AxKRtj7OB0/3OZAI2MHB/v2FeYh271LZ9abvnM1WIwWc/5umYjx0jo5sQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fast-glob": "3.3.1"
|
"fast-glob": "3.3.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@next/eslint-plugin-next/node_modules/fast-glob": {
|
||||||
|
"version": "3.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz",
|
||||||
|
"integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@nodelib/fs.stat": "^2.0.2",
|
||||||
|
"@nodelib/fs.walk": "^1.2.3",
|
||||||
|
"glob-parent": "^5.1.2",
|
||||||
|
"merge2": "^1.3.0",
|
||||||
|
"micromatch": "^4.0.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/eslint-plugin-next/node_modules/glob-parent": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"is-glob": "^4.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@next/swc-darwin-arm64": {
|
"node_modules/@next/swc-darwin-arm64": {
|
||||||
"version": "16.0.7",
|
"version": "16.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.0.1.tgz",
|
||||||
"integrity": "sha512-LlDtCYOEj/rfSnEn/Idi+j1QKHxY9BJFmxx7108A6D8K0SB+bNgfYQATPk/4LqOl4C0Wo3LACg2ie6s7xqMpJg==",
|
"integrity": "sha512-R0YxRp6/4W7yG1nKbfu41bp3d96a0EalonQXiMe+1H9GTHfKxGNCGFNWUho18avRBPsO8T3RmdWuzmfurlQPbg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1244,9 +1274,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-darwin-x64": {
|
"node_modules/@next/swc-darwin-x64": {
|
||||||
"version": "16.0.7",
|
"version": "16.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.0.1.tgz",
|
||||||
"integrity": "sha512-rtZ7BhnVvO1ICf3QzfW9H3aPz7GhBrnSIMZyr4Qy6boXF0b5E3QLs+cvJmg3PsTCG2M1PBoC+DANUi4wCOKXpA==",
|
"integrity": "sha512-kETZBocRux3xITiZtOtVoVvXyQLB7VBxN7L6EPqgI5paZiUlnsgYv4q8diTNYeHmF9EiehydOBo20lTttCbHAg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1260,9 +1290,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-linux-arm64-gnu": {
|
"node_modules/@next/swc-linux-arm64-gnu": {
|
||||||
"version": "16.0.7",
|
"version": "16.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.0.1.tgz",
|
||||||
"integrity": "sha512-mloD5WcPIeIeeZqAIP5c2kdaTa6StwP4/2EGy1mUw8HiexSHGK/jcM7lFuS3u3i2zn+xH9+wXJs6njO7VrAqww==",
|
"integrity": "sha512-hWg3BtsxQuSKhfe0LunJoqxjO4NEpBmKkE+P2Sroos7yB//OOX3jD5ISP2wv8QdUwtRehMdwYz6VB50mY6hqAg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1276,9 +1306,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-linux-arm64-musl": {
|
"node_modules/@next/swc-linux-arm64-musl": {
|
||||||
"version": "16.0.7",
|
"version": "16.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.0.1.tgz",
|
||||||
"integrity": "sha512-+ksWNrZrthisXuo9gd1XnjHRowCbMtl/YgMpbRvFeDEqEBd523YHPWpBuDjomod88U8Xliw5DHhekBC3EOOd9g==",
|
"integrity": "sha512-UPnOvYg+fjAhP3b1iQStcYPWeBFRLrugEyK/lDKGk7kLNua8t5/DvDbAEFotfV1YfcOY6bru76qN9qnjLoyHCQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1292,9 +1322,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-linux-x64-gnu": {
|
"node_modules/@next/swc-linux-x64-gnu": {
|
||||||
"version": "16.0.7",
|
"version": "16.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.0.1.tgz",
|
||||||
"integrity": "sha512-4WtJU5cRDxpEE44Ana2Xro1284hnyVpBb62lIpU5k85D8xXxatT+rXxBgPkc7C1XwkZMWpK5rXLXTh9PFipWsA==",
|
"integrity": "sha512-Et81SdWkcRqAJziIgFtsFyJizHoWne4fzJkvjd6V4wEkWTB4MX6J0uByUb0peiJQ4WeAt6GGmMszE5KrXK6WKg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1308,9 +1338,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-linux-x64-musl": {
|
"node_modules/@next/swc-linux-x64-musl": {
|
||||||
"version": "16.0.7",
|
"version": "16.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.0.1.tgz",
|
||||||
"integrity": "sha512-HYlhqIP6kBPXalW2dbMTSuB4+8fe+j9juyxwfMwCe9kQPPeiyFn7NMjNfoFOfJ2eXkeQsoUGXg+O2SE3m4Qg2w==",
|
"integrity": "sha512-qBbgYEBRrC1egcG03FZaVfVxrJm8wBl7vr8UFKplnxNRprctdP26xEv9nJ07Ggq4y1adwa0nz2mz83CELY7N6Q==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1324,9 +1354,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-win32-arm64-msvc": {
|
"node_modules/@next/swc-win32-arm64-msvc": {
|
||||||
"version": "16.0.7",
|
"version": "16.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.0.1.tgz",
|
||||||
"integrity": "sha512-EviG+43iOoBRZg9deGauXExjRphhuYmIOJ12b9sAPy0eQ6iwcPxfED2asb/s2/yiLYOdm37kPaiZu8uXSYPs0Q==",
|
"integrity": "sha512-cPuBjYP6I699/RdbHJonb3BiRNEDm5CKEBuJ6SD8k3oLam2fDRMKAvmrli4QMDgT2ixyRJ0+DTkiODbIQhRkeQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1340,9 +1370,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@next/swc-win32-x64-msvc": {
|
"node_modules/@next/swc-win32-x64-msvc": {
|
||||||
"version": "16.0.7",
|
"version": "16.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.0.1.tgz",
|
||||||
"integrity": "sha512-gniPjy55zp5Eg0896qSrf3yB1dw4F/3s8VK1ephdsZZ129j2n6e1WqCbE2YgcKhW9hPB9TVZENugquWJD5x0ug==",
|
"integrity": "sha512-XeEUJsE4JYtfrXe/LaJn3z1pD19fK0Q6Er8Qoufi+HqvdO4LEPyCxLUt4rxA+4RfYo6S9gMlmzCMU2F+AatFqQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1961,21 +1991,21 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "24.10.1",
|
"version": "24.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.0.tgz",
|
||||||
"integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==",
|
"integrity": "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~7.16.0"
|
"undici-types": "~7.16.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "19.2.7",
|
"version": "19.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz",
|
||||||
"integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==",
|
"integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csstype": "^3.2.2"
|
"csstype": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/unist": {
|
"node_modules/@types/unist": {
|
||||||
@@ -1985,17 +2015,17 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "8.48.1",
|
"version": "8.46.4",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.48.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.4.tgz",
|
||||||
"integrity": "sha512-X63hI1bxl5ohelzr0LY5coufyl0LJNthld+abwxpCoo6Gq+hSqhKwci7MUWkXo67mzgUK6YFByhmaHmUcuBJmA==",
|
"integrity": "sha512-R48VhmTJqplNyDxCyqqVkFSZIx1qX6PzwqgcXn1olLrzxcSBDlOsbtcnQuQhNtnNiJ4Xe5gREI1foajYaYU2Vg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/regexpp": "^4.10.0",
|
"@eslint-community/regexpp": "^4.10.0",
|
||||||
"@typescript-eslint/scope-manager": "8.48.1",
|
"@typescript-eslint/scope-manager": "8.46.4",
|
||||||
"@typescript-eslint/type-utils": "8.48.1",
|
"@typescript-eslint/type-utils": "8.46.4",
|
||||||
"@typescript-eslint/utils": "8.48.1",
|
"@typescript-eslint/utils": "8.46.4",
|
||||||
"@typescript-eslint/visitor-keys": "8.48.1",
|
"@typescript-eslint/visitor-keys": "8.46.4",
|
||||||
"graphemer": "^1.4.0",
|
"graphemer": "^1.4.0",
|
||||||
"ignore": "^7.0.0",
|
"ignore": "^7.0.0",
|
||||||
"natural-compare": "^1.4.0",
|
"natural-compare": "^1.4.0",
|
||||||
@@ -2009,22 +2039,22 @@
|
|||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@typescript-eslint/parser": "^8.48.1",
|
"@typescript-eslint/parser": "^8.46.4",
|
||||||
"eslint": "^8.57.0 || ^9.0.0",
|
"eslint": "^8.57.0 || ^9.0.0",
|
||||||
"typescript": ">=4.8.4 <6.0.0"
|
"typescript": ">=4.8.4 <6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/parser": {
|
"node_modules/@typescript-eslint/parser": {
|
||||||
"version": "8.48.1",
|
"version": "8.46.4",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.48.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.4.tgz",
|
||||||
"integrity": "sha512-PC0PDZfJg8sP7cmKe6L3QIL8GZwU5aRvUFedqSIpw3B+QjRSUZeeITC2M5XKeMXEzL6wccN196iy3JLwKNvDVA==",
|
"integrity": "sha512-tK3GPFWbirvNgsNKto+UmB/cRtn6TZfyw0D6IKrW55n6Vbs7KJoZtI//kpTKzE/DUmmnAFD8/Ca46s7Obs92/w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "8.48.1",
|
"@typescript-eslint/scope-manager": "8.46.4",
|
||||||
"@typescript-eslint/types": "8.48.1",
|
"@typescript-eslint/types": "8.46.4",
|
||||||
"@typescript-eslint/typescript-estree": "8.48.1",
|
"@typescript-eslint/typescript-estree": "8.46.4",
|
||||||
"@typescript-eslint/visitor-keys": "8.48.1",
|
"@typescript-eslint/visitor-keys": "8.46.4",
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.3.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -2040,14 +2070,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/project-service": {
|
"node_modules/@typescript-eslint/project-service": {
|
||||||
"version": "8.48.1",
|
"version": "8.46.4",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.48.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.4.tgz",
|
||||||
"integrity": "sha512-HQWSicah4s9z2/HifRPQ6b6R7G+SBx64JlFQpgSSHWPKdvCZX57XCbszg/bapbRsOEv42q5tayTYcEFpACcX1w==",
|
"integrity": "sha512-nPiRSKuvtTN+no/2N1kt2tUh/HoFzeEgOm9fQ6XQk4/ApGqjx0zFIIaLJ6wooR1HIoozvj2j6vTi/1fgAz7UYQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/tsconfig-utils": "^8.48.1",
|
"@typescript-eslint/tsconfig-utils": "^8.46.4",
|
||||||
"@typescript-eslint/types": "^8.48.1",
|
"@typescript-eslint/types": "^8.46.4",
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.3.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -2062,14 +2092,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/scope-manager": {
|
"node_modules/@typescript-eslint/scope-manager": {
|
||||||
"version": "8.48.1",
|
"version": "8.46.4",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.48.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.4.tgz",
|
||||||
"integrity": "sha512-rj4vWQsytQbLxC5Bf4XwZ0/CKd362DkWMUkviT7DCS057SK64D5lH74sSGzhI6PDD2HCEq02xAP9cX68dYyg1w==",
|
"integrity": "sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.48.1",
|
"@typescript-eslint/types": "8.46.4",
|
||||||
"@typescript-eslint/visitor-keys": "8.48.1"
|
"@typescript-eslint/visitor-keys": "8.46.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -2080,9 +2110,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/tsconfig-utils": {
|
"node_modules/@typescript-eslint/tsconfig-utils": {
|
||||||
"version": "8.48.1",
|
"version": "8.46.4",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.48.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.4.tgz",
|
||||||
"integrity": "sha512-k0Jhs4CpEffIBm6wPaCXBAD7jxBtrHjrSgtfCjUvPp9AZ78lXKdTR8fxyZO5y4vWNlOvYXRtngSZNSn+H53Jkw==",
|
"integrity": "sha512-+/XqaZPIAk6Cjg7NWgSGe27X4zMGqrFqZ8atJsX3CWxH/jACqWnrWI68h7nHQld0y+k9eTTjb9r+KU4twLoo9A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -2097,15 +2127,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/type-utils": {
|
"node_modules/@typescript-eslint/type-utils": {
|
||||||
"version": "8.48.1",
|
"version": "8.46.4",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.48.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.4.tgz",
|
||||||
"integrity": "sha512-1jEop81a3LrJQLTf/1VfPQdhIY4PlGDBc/i67EVWObrtvcziysbLN3oReexHOM6N3jyXgCrkBsZpqwH0hiDOQg==",
|
"integrity": "sha512-V4QC8h3fdT5Wro6vANk6eojqfbv5bpwHuMsBcJUJkqs2z5XnYhJzyz9Y02eUmF9u3PgXEUiOt4w4KHR3P+z0PQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.48.1",
|
"@typescript-eslint/types": "8.46.4",
|
||||||
"@typescript-eslint/typescript-estree": "8.48.1",
|
"@typescript-eslint/typescript-estree": "8.46.4",
|
||||||
"@typescript-eslint/utils": "8.48.1",
|
"@typescript-eslint/utils": "8.46.4",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"ts-api-utils": "^2.1.0"
|
"ts-api-utils": "^2.1.0"
|
||||||
},
|
},
|
||||||
@@ -2122,9 +2152,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/types": {
|
"node_modules/@typescript-eslint/types": {
|
||||||
"version": "8.48.1",
|
"version": "8.46.4",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.48.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.4.tgz",
|
||||||
"integrity": "sha512-+fZ3LZNeiELGmimrujsDCT4CRIbq5oXdHe7chLiW8qzqyPMnn1puNstCrMNVAqwcl2FdIxkuJ4tOs/RFDBVc/Q==",
|
"integrity": "sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -2136,20 +2166,21 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree": {
|
"node_modules/@typescript-eslint/typescript-estree": {
|
||||||
"version": "8.48.1",
|
"version": "8.46.4",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.48.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.4.tgz",
|
||||||
"integrity": "sha512-/9wQ4PqaefTK6POVTjJaYS0bynCgzh6ClJHGSBj06XEHjkfylzB+A3qvyaXnErEZSaxhIo4YdyBgq6j4RysxDg==",
|
"integrity": "sha512-7oV2qEOr1d4NWNmpXLR35LvCfOkTNymY9oyW+lUHkmCno7aOmIf/hMaydnJBUTBMRCOGZh8YjkFOc8dadEoNGA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/project-service": "8.48.1",
|
"@typescript-eslint/project-service": "8.46.4",
|
||||||
"@typescript-eslint/tsconfig-utils": "8.48.1",
|
"@typescript-eslint/tsconfig-utils": "8.46.4",
|
||||||
"@typescript-eslint/types": "8.48.1",
|
"@typescript-eslint/types": "8.46.4",
|
||||||
"@typescript-eslint/visitor-keys": "8.48.1",
|
"@typescript-eslint/visitor-keys": "8.46.4",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
|
"fast-glob": "^3.3.2",
|
||||||
|
"is-glob": "^4.0.3",
|
||||||
"minimatch": "^9.0.4",
|
"minimatch": "^9.0.4",
|
||||||
"semver": "^7.6.0",
|
"semver": "^7.6.0",
|
||||||
"tinyglobby": "^0.2.15",
|
|
||||||
"ts-api-utils": "^2.1.0"
|
"ts-api-utils": "^2.1.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -2164,16 +2195,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/utils": {
|
"node_modules/@typescript-eslint/utils": {
|
||||||
"version": "8.48.1",
|
"version": "8.46.4",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.48.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.4.tgz",
|
||||||
"integrity": "sha512-fAnhLrDjiVfey5wwFRwrweyRlCmdz5ZxXz2G/4cLn0YDLjTapmN4gcCsTBR1N2rWnZSDeWpYtgLDsJt+FpmcwA==",
|
"integrity": "sha512-AbSv11fklGXV6T28dp2Me04Uw90R2iJ30g2bgLz529Koehrmkbs1r7paFqr1vPCZi7hHwYxYtxfyQMRC8QaVSg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.7.0",
|
"@eslint-community/eslint-utils": "^4.7.0",
|
||||||
"@typescript-eslint/scope-manager": "8.48.1",
|
"@typescript-eslint/scope-manager": "8.46.4",
|
||||||
"@typescript-eslint/types": "8.48.1",
|
"@typescript-eslint/types": "8.46.4",
|
||||||
"@typescript-eslint/typescript-estree": "8.48.1"
|
"@typescript-eslint/typescript-estree": "8.46.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -2188,13 +2219,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/visitor-keys": {
|
"node_modules/@typescript-eslint/visitor-keys": {
|
||||||
"version": "8.48.1",
|
"version": "8.46.4",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.48.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.4.tgz",
|
||||||
"integrity": "sha512-BmxxndzEWhE4TIEEMBs8lP3MBWN3jFPs/p6gPm/wkv02o41hI6cq9AuSmGAaTTHPtA1FTi2jBre4A9rm5ZmX+Q==",
|
"integrity": "sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.48.1",
|
"@typescript-eslint/types": "8.46.4",
|
||||||
"eslint-visitor-keys": "^4.2.1"
|
"eslint-visitor-keys": "^4.2.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -2759,9 +2790,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/autoprefixer": {
|
"node_modules/autoprefixer": {
|
||||||
"version": "10.4.22",
|
"version": "10.4.21",
|
||||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.22.tgz",
|
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
|
||||||
"integrity": "sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg==",
|
"integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -2778,9 +2809,9 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"browserslist": "^4.27.0",
|
"browserslist": "^4.24.4",
|
||||||
"caniuse-lite": "^1.0.30001754",
|
"caniuse-lite": "^1.0.30001702",
|
||||||
"fraction.js": "^5.3.4",
|
"fraction.js": "^4.3.7",
|
||||||
"normalize-range": "^0.1.2",
|
"normalize-range": "^0.1.2",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
"postcss-value-parser": "^4.2.0"
|
"postcss-value-parser": "^4.2.0"
|
||||||
@@ -3148,9 +3179,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/csstype": {
|
"node_modules/csstype": {
|
||||||
"version": "3.2.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/damerau-levenshtein": {
|
"node_modules/damerau-levenshtein": {
|
||||||
@@ -3663,13 +3694,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-config-next": {
|
"node_modules/eslint-config-next": {
|
||||||
"version": "16.0.7",
|
"version": "16.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.0.3.tgz",
|
||||||
"integrity": "sha512-WubFGLFHfk2KivkdRGfx6cGSFhaQqhERRfyO8BRx+qiGPGp7WLKcPvYC4mdx1z3VhVRcrfFzczjjTrbJZOpnEQ==",
|
"integrity": "sha512-5F6qDjcZldf0Y0ZbqvWvap9xzYUxyDf7/of37aeyhvkrQokj/4bT1JYWZdlWUr283aeVa+s52mPq9ogmGg+5dw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@next/eslint-plugin-next": "16.0.7",
|
"@next/eslint-plugin-next": "16.0.3",
|
||||||
"eslint-import-resolver-node": "^0.3.6",
|
"eslint-import-resolver-node": "^0.3.6",
|
||||||
"eslint-import-resolver-typescript": "^3.5.2",
|
"eslint-import-resolver-typescript": "^3.5.2",
|
||||||
"eslint-plugin-import": "^2.32.0",
|
"eslint-plugin-import": "^2.32.0",
|
||||||
@@ -4294,9 +4325,9 @@
|
|||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
},
|
},
|
||||||
"node_modules/fast-glob": {
|
"node_modules/fast-glob": {
|
||||||
"version": "3.3.1",
|
"version": "3.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
|
||||||
"integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==",
|
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -4304,7 +4335,7 @@
|
|||||||
"@nodelib/fs.walk": "^1.2.3",
|
"@nodelib/fs.walk": "^1.2.3",
|
||||||
"glob-parent": "^5.1.2",
|
"glob-parent": "^5.1.2",
|
||||||
"merge2": "^1.3.0",
|
"merge2": "^1.3.0",
|
||||||
"micromatch": "^4.0.4"
|
"micromatch": "^4.0.8"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.6.0"
|
"node": ">=8.6.0"
|
||||||
@@ -4428,15 +4459,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fraction.js": {
|
"node_modules/fraction.js": {
|
||||||
"version": "5.3.4",
|
"version": "4.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
|
||||||
"integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==",
|
"integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "*"
|
"node": "*"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "github",
|
"type": "patreon",
|
||||||
"url": "https://github.com/sponsors/rawify"
|
"url": "https://github.com/sponsors/rawify"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -6976,12 +7007,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/next": {
|
"node_modules/next": {
|
||||||
"version": "16.0.7",
|
"version": "16.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/next/-/next-16.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/next/-/next-16.0.1.tgz",
|
||||||
"integrity": "sha512-3mBRJyPxT4LOxAJI6IsXeFtKfiJUbjCLgvXO02fV8Wy/lIhPvP94Fe7dGhUgHXcQy4sSuYwQNcOLhIfOm0rL0A==",
|
"integrity": "sha512-e9RLSssZwd35p7/vOa+hoDFggUZIUbZhIUSLZuETCwrCVvxOs87NamoUzT+vbcNAL8Ld9GobBnWOA6SbV/arOw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@next/env": "16.0.7",
|
"@next/env": "16.0.1",
|
||||||
"@swc/helpers": "0.5.15",
|
"@swc/helpers": "0.5.15",
|
||||||
"caniuse-lite": "^1.0.30001579",
|
"caniuse-lite": "^1.0.30001579",
|
||||||
"postcss": "8.4.31",
|
"postcss": "8.4.31",
|
||||||
@@ -6994,14 +7025,14 @@
|
|||||||
"node": ">=20.9.0"
|
"node": ">=20.9.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@next/swc-darwin-arm64": "16.0.7",
|
"@next/swc-darwin-arm64": "16.0.1",
|
||||||
"@next/swc-darwin-x64": "16.0.7",
|
"@next/swc-darwin-x64": "16.0.1",
|
||||||
"@next/swc-linux-arm64-gnu": "16.0.7",
|
"@next/swc-linux-arm64-gnu": "16.0.1",
|
||||||
"@next/swc-linux-arm64-musl": "16.0.7",
|
"@next/swc-linux-arm64-musl": "16.0.1",
|
||||||
"@next/swc-linux-x64-gnu": "16.0.7",
|
"@next/swc-linux-x64-gnu": "16.0.1",
|
||||||
"@next/swc-linux-x64-musl": "16.0.7",
|
"@next/swc-linux-x64-musl": "16.0.1",
|
||||||
"@next/swc-win32-arm64-msvc": "16.0.7",
|
"@next/swc-win32-arm64-msvc": "16.0.1",
|
||||||
"@next/swc-win32-x64-msvc": "16.0.7",
|
"@next/swc-win32-x64-msvc": "16.0.1",
|
||||||
"sharp": "^0.34.4"
|
"sharp": "^0.34.4"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
@@ -7028,9 +7059,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/next-intl": {
|
"node_modules/next-intl": {
|
||||||
"version": "4.5.8",
|
"version": "4.5.7",
|
||||||
"resolved": "https://registry.npmjs.org/next-intl/-/next-intl-4.5.8.tgz",
|
"resolved": "https://registry.npmjs.org/next-intl/-/next-intl-4.5.7.tgz",
|
||||||
"integrity": "sha512-BdN6494nvt09WtmW5gbWdwRhDDHC/Sg7tBMhN7xfYds3vcRCngSDXat81gmJkblw9jYOv8zXzzFJyu5VYXnJzg==",
|
"integrity": "sha512-7iT9rBEFZvsJI5uLoOLgI1kAieg1k7zCwbuby6ylKRbpvt08I1vkZ5FJnIBey1M+r1jam/wANlnqRYeJagjL2Q==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -7042,9 +7073,9 @@
|
|||||||
"@formatjs/intl-localematcher": "^0.5.4",
|
"@formatjs/intl-localematcher": "^0.5.4",
|
||||||
"@swc/core": "^1.15.2",
|
"@swc/core": "^1.15.2",
|
||||||
"negotiator": "^1.0.0",
|
"negotiator": "^1.0.0",
|
||||||
"next-intl-swc-plugin-extractor": "^4.5.8",
|
"next-intl-swc-plugin-extractor": "^4.5.7",
|
||||||
"po-parser": "^1.0.2",
|
"po-parser": "^1.0.2",
|
||||||
"use-intl": "^4.5.8"
|
"use-intl": "^4.5.7"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
|
"next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
|
||||||
@@ -7058,9 +7089,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/next-intl-swc-plugin-extractor": {
|
"node_modules/next-intl-swc-plugin-extractor": {
|
||||||
"version": "4.5.8",
|
"version": "4.5.7",
|
||||||
"resolved": "https://registry.npmjs.org/next-intl-swc-plugin-extractor/-/next-intl-swc-plugin-extractor-4.5.8.tgz",
|
"resolved": "https://registry.npmjs.org/next-intl-swc-plugin-extractor/-/next-intl-swc-plugin-extractor-4.5.7.tgz",
|
||||||
"integrity": "sha512-hscCKUv+5GQ0CCNbvqZ8gaxnAGToCgDTbL++jgCq8SCk/ljtZDEeQZcMk46Nm6Ynn49Q/JKF4Npo/Sq1mpbusA==",
|
"integrity": "sha512-cSHtDpEoSHuEC4CzUDmAAfB0H3fqSephpJNd/GtS9LvUoZM78wJQwkEaqN9yTxXEvJ8uQG60nnOeSl2LQU9qdQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/next-intl/node_modules/@swc/core": {
|
"node_modules/next-intl/node_modules/@swc/core": {
|
||||||
@@ -7536,9 +7567,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/prettier": {
|
"node_modules/prettier": {
|
||||||
"version": "3.7.4",
|
"version": "3.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
|
||||||
"integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==",
|
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -7618,24 +7649,24 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/react": {
|
"node_modules/react": {
|
||||||
"version": "19.2.1",
|
"version": "19.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/react/-/react-19.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz",
|
||||||
"integrity": "sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw==",
|
"integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-dom": {
|
"node_modules/react-dom": {
|
||||||
"version": "19.2.1",
|
"version": "19.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz",
|
||||||
"integrity": "sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg==",
|
"integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"scheduler": "^0.27.0"
|
"scheduler": "^0.27.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^19.2.1"
|
"react": "^19.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-is": {
|
"node_modules/react-is": {
|
||||||
@@ -8744,16 +8775,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript-eslint": {
|
"node_modules/typescript-eslint": {
|
||||||
"version": "8.48.1",
|
"version": "8.46.4",
|
||||||
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.48.1.tgz",
|
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.46.4.tgz",
|
||||||
"integrity": "sha512-FbOKN1fqNoXp1hIl5KYpObVrp0mCn+CLgn479nmu2IsRMrx2vyv74MmsBLVlhg8qVwNFGbXSp8fh1zp8pEoC2A==",
|
"integrity": "sha512-KALyxkpYV5Ix7UhvjTwJXZv76VWsHG+NjNlt/z+a17SOQSiOcBdUXdbJdyXi7RPxrBFECtFOiPwUJQusJuCqrg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": "8.48.1",
|
"@typescript-eslint/eslint-plugin": "8.46.4",
|
||||||
"@typescript-eslint/parser": "8.48.1",
|
"@typescript-eslint/parser": "8.46.4",
|
||||||
"@typescript-eslint/typescript-estree": "8.48.1",
|
"@typescript-eslint/typescript-estree": "8.46.4",
|
||||||
"@typescript-eslint/utils": "8.48.1"
|
"@typescript-eslint/utils": "8.46.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -8955,9 +8986,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/use-intl": {
|
"node_modules/use-intl": {
|
||||||
"version": "4.5.8",
|
"version": "4.5.7",
|
||||||
"resolved": "https://registry.npmjs.org/use-intl/-/use-intl-4.5.8.tgz",
|
"resolved": "https://registry.npmjs.org/use-intl/-/use-intl-4.5.7.tgz",
|
||||||
"integrity": "sha512-rWPV2Sirw55BQbA/7ndUBtsikh8WXwBrUkZJ1mD35+emj/ogPPqgCZdv1DdrEFK42AjF1g5w8d3x8govhqPH6Q==",
|
"integrity": "sha512-WBVD1fxV9td5osQFK0TRQhz217zHERhxBuA3EmZuH7wCINJPXbYPs+0FH2oMpy6p6BBwuHCJK2ER8hKwxf0LQA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@formatjs/fast-memoize": "^2.2.0",
|
"@formatjs/fast-memoize": "^2.2.0",
|
||||||
|
|||||||
28
package.json
28
package.json
@@ -30,16 +30,16 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tailwindcss/postcss": "^4.1.17",
|
"@tailwindcss/postcss": "^4.1.17",
|
||||||
"@tailwindcss/typography": "^0.5.19",
|
"@tailwindcss/typography": "^0.5.19",
|
||||||
"@types/node": "^24.10.1",
|
"@types/node": "^24.10.0",
|
||||||
"@types/react": "^19.2.7",
|
"@types/react": "^19.2.2",
|
||||||
"autoprefixer": "^10.4.22",
|
"autoprefixer": "^10.4.21",
|
||||||
"gray-matter": "^4.0.3",
|
"gray-matter": "^4.0.3",
|
||||||
"next": "^16.0.7",
|
"next": "^16.0.1",
|
||||||
"next-intl": "^4.5.8",
|
"next-intl": "^4.5.7",
|
||||||
"next-themes": "^0.4.6",
|
"next-themes": "^0.4.6",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.6",
|
||||||
"react": "^19.2.1",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.1",
|
"react-dom": "^19.2.0",
|
||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
"rehype-raw": "^7.0.0",
|
"rehype-raw": "^7.0.0",
|
||||||
"rehype-sanitize": "^6.0.0",
|
"rehype-sanitize": "^6.0.0",
|
||||||
@@ -51,16 +51,16 @@
|
|||||||
"unist-util-visit": "^5.0.0"
|
"unist-util-visit": "^5.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/eslintrc": "^3.3.3",
|
"@eslint/eslintrc": "^3.3.1",
|
||||||
"@eslint/js": "^9.39.1",
|
"@eslint/js": "^9.39.1",
|
||||||
"@next/bundle-analyzer": "^16.0.7",
|
"@next/bundle-analyzer": "^16.0.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.48.1",
|
"@typescript-eslint/eslint-plugin": "^8.46.4",
|
||||||
"@typescript-eslint/parser": "^8.48.1",
|
"@typescript-eslint/parser": "^8.46.4",
|
||||||
"eslint": "^9.39.1",
|
"eslint": "^9.39.1",
|
||||||
"eslint-config-next": "^16.0.7",
|
"eslint-config-next": "^16.0.3",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-prettier": "^5.5.4",
|
"eslint-plugin-prettier": "^5.5.4",
|
||||||
"prettier": "^3.7.4",
|
"prettier": "^3.6.2",
|
||||||
"typescript-eslint": "^8.48.1"
|
"typescript-eslint": "^8.46.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
20
public/blog/tech/articol-tehnic.md
Normal file
20
public/blog/tech/articol-tehnic.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
title: 'Technical Article'
|
||||||
|
description: 'A technical article to test internal links'
|
||||||
|
date: '2025-01-10'
|
||||||
|
author: 'John Doe'
|
||||||
|
category: 'Tech'
|
||||||
|
tags: ['tech', 'test']
|
||||||
|
---
|
||||||
|
|
||||||
|
# Technical Article
|
||||||
|
|
||||||
|
This is a test article for internal blog post linking.
|
||||||
|
|
||||||
|
Imagine cooler:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Content
|
||||||
|
|
||||||
|
You are reading the technical article that was linked from the example post.
|
||||||
Reference in New Issue
Block a user