diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 5125765..6601e89 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -43,7 +43,8 @@ "Bash(ssh:*)", "Bash(scp:*)", "Bash(cat:*)", - "Bash(./deploy-manual.sh)" + "Bash(./deploy-manual.sh)", + "Bash(npm install)" ], "deny": [], "ask": [], diff --git a/alternative-git-servers.md b/alternative-git-servers.md deleted file mode 100644 index 26efc10..0000000 --- a/alternative-git-servers.md +++ /dev/null @@ -1,298 +0,0 @@ -# 시놀로지 NAS 대안 Git 서버 설치 방안 - -## 🚀 개요 - -시놀로지 Git Server 패키지가 작동하지 않을 때 사용할 수 있는 대안적인 Git 서버 설치 방법들을 제공합니다. - -## 🐳 방법 1: Docker를 이용한 Gitea 설치 (권장) - -### 1.1 장점 -- 웹 기반 Git 관리 인터페이스 -- GitHub와 유사한 사용자 경험 -- 이슈 관리, 위키, 프로젝트 관리 기능 -- 가벼움 (Go 언어 기반) - -### 1.2 설치 과정 - -#### Docker 설치 확인 -```bash -# DSM > 패키지 센터 > Docker 설치 -# 또는 SSH에서 확인 -docker --version -``` - -#### Gitea 컨테이너 실행 -```bash -# SSH로 NAS 접속 -ssh admin@your-nas-ip - -# Gitea 데이터 디렉토리 생성 -sudo mkdir -p /volume1/docker/gitea - -# Gitea 컨테이너 실행 -docker run -d \ - --name gitea \ - -p 3000:3000 \ - -p 222:22 \ - -v /volume1/docker/gitea:/data \ - -e USER_UID=1000 \ - -e USER_GID=1000 \ - gitea/gitea:latest -``` - -#### 웹 설정 -1. 브라우저에서 `http://your-nas-ip:3000` 접속 -2. 초기 설정 완료: - - 데이터베이스: SQLite3 (기본) - - 관리자 계정 생성 - - 저장소 루트 경로: `/data/git/repositories` - -### 1.3 저장소 생성 및 연결 -```bash -# 웹 인터페이스에서 새 저장소 'jaryo-file-manager' 생성 -# 로컬에서 연결 -git remote add gitea http://your-nas-ip:3000/username/jaryo-file-manager.git -git push gitea master -``` - -## 📦 방법 2: 순수 Git 서버 설치 - -### 2.1 수동 Git 설치 -```bash -# SSH로 NAS 접속 -ssh admin@your-nas-ip - -# 패키지 관리자 업데이트 -sudo apt update - -# Git 설치 -sudo apt install git git-daemon-run - -# 버전 확인 -git --version -``` - -### 2.2 Git 서비스 설정 -```bash -# Git 사용자 생성 -sudo adduser git -sudo su git -cd /home/git - -# SSH 키 디렉토리 생성 -mkdir .ssh && chmod 700 .ssh -touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys - -# Git 저장소 디렉토리 생성 -mkdir /home/git/repositories -``` - -### 2.3 systemd 서비스 설정 -```bash -# Git daemon 서비스 파일 생성 -sudo tee /etc/systemd/system/git-daemon.service << EOF -[Unit] -Description=Git Daemon -After=network.target - -[Service] -ExecStart=/usr/bin/git daemon --reuseaddr --base-path=/home/git/repositories --export-all --verbose --enable=receive-pack -Restart=always -User=git -Group=git -StandardOutput=journal -StandardError=journal - -[Install] -WantedBy=multi-user.target -EOF - -# 서비스 활성화 -sudo systemctl enable git-daemon -sudo systemctl start git-daemon -sudo systemctl status git-daemon -``` - -### 2.4 저장소 생성 -```bash -# git 사용자로 전환 -sudo su git -cd /home/git/repositories - -# bare 저장소 생성 -git init --bare jaryo-file-manager.git -``` - -## 🌐 방법 3: GitLab CE Docker 설치 - -### 3.1 특징 -- 기업급 Git 관리 플랫폼 -- CI/CD 파이프라인 지원 -- 이슈 추적, 위키, 프로젝트 관리 -- 더 많은 리소스 필요 - -### 3.2 설치 과정 -```bash -# GitLab 데이터 디렉토리 생성 -sudo mkdir -p /volume1/docker/gitlab/{config,logs,data} - -# GitLab 컨테이너 실행 (최소 4GB RAM 권장) -docker run -d \ - --hostname your-nas-ip \ - --name gitlab \ - -p 8080:80 \ - -p 8443:443 \ - -p 8022:22 \ - -v /volume1/docker/gitlab/config:/etc/gitlab \ - -v /volume1/docker/gitlab/logs:/var/log/gitlab \ - -v /volume1/docker/gitlab/data:/var/opt/gitlab \ - gitlab/gitlab-ce:latest -``` - -### 3.3 초기 설정 -```bash -# 컨테이너 시작 대기 (2-3분) -docker logs -f gitlab - -# 브라우저에서 http://your-nas-ip:8080 접속 -# 초기 root 비밀번호 확인 -docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password -``` - -## 🔧 방법 4: Forgejo (Gitea Fork) 설치 - -### 4.1 특징 -- Gitea의 커뮤니티 중심 포크 -- 더 빠른 개발 주기 -- 오픈소스 중심 - -### 4.2 설치 과정 -```bash -# Forgejo 데이터 디렉토리 생성 -sudo mkdir -p /volume1/docker/forgejo - -# Forgejo 컨테이너 실행 -docker run -d \ - --name forgejo \ - -p 3000:3000 \ - -p 222:22 \ - -v /volume1/docker/forgejo:/data \ - -e USER_UID=1000 \ - -e USER_GID=1000 \ - codeberg.org/forgejo/forgejo:latest -``` - -## 📱 방법 5: 간단한 HTTP Git 서버 - -### 5.1 Python 기반 간단 서버 -```bash -# Python Git HTTP 서버 스크립트 생성 -cat > /volume1/web/git-http-server.py << 'EOF' -#!/usr/bin/env python3 -import os -import http.server -import socketserver -from subprocess import Popen, PIPE - -class GitHTTPHandler(http.server.SimpleHTTPRequestHandler): - def do_GET(self): - if self.path.endswith('.git/info/refs'): - # Git 정보 요청 처리 - self.send_response(200) - self.send_header('Content-type', 'text/plain') - self.end_headers() - - repo_path = self.path.split('/')[1] - git_dir = f'/volume1/git/{repo_path}' - - if os.path.exists(git_dir): - proc = Popen(['git', 'upload-pack', '--advertise-refs', git_dir], - stdout=PIPE, stderr=PIPE) - output, _ = proc.communicate() - self.wfile.write(output) - else: - self.wfile.write(b'Repository not found') - else: - super().do_GET() - -PORT = 8000 -with socketserver.TCPServer(("", PORT), GitHTTPHandler) as httpd: - print(f"Git HTTP Server running on port {PORT}") - httpd.serve_forever() -EOF - -# 실행 권한 부여 -chmod +x /volume1/web/git-http-server.py - -# 서버 실행 -python3 /volume1/web/git-http-server.py -``` - -## 🔀 방법별 비교표 - -| 방법 | 난이도 | 리소스 사용량 | 기능 | 웹 UI | 권장도 | -|------|--------|---------------|------|-------|--------| -| Gitea | 쉬움 | 낮음 | 풍부 | ✅ | ⭐⭐⭐⭐⭐ | -| 순수 Git | 보통 | 매우 낮음 | 기본 | ❌ | ⭐⭐⭐ | -| GitLab CE | 어려움 | 높음 | 매우 풍부 | ✅ | ⭐⭐⭐⭐ | -| Forgejo | 쉬움 | 낮음 | 풍부 | ✅ | ⭐⭐⭐⭐ | -| Python 서버 | 보통 | 낮음 | 제한적 | ❌ | ⭐⭐ | - -## 🚀 빠른 시작 가이드 (Gitea 권장) - -### 1단계: Docker 설치 확인 -```bash -# DSM 패키지 센터에서 Docker 설치 -``` - -### 2단계: Gitea 설치 -```bash -ssh admin@your-nas-ip -sudo mkdir -p /volume1/docker/gitea -docker run -d --name gitea -p 3000:3000 -p 222:22 -v /volume1/docker/gitea:/data gitea/gitea:latest -``` - -### 3단계: 웹 설정 -- `http://your-nas-ip:3000` 접속 -- 초기 설정 완료 -- 관리자 계정 생성 - -### 4단계: 저장소 생성 및 연결 -```bash -# 웹에서 새 저장소 생성 -# 로컬에서 연결 -cd /c/Users/COMTREE/claude_code/jaryo -git remote add gitea http://your-nas-ip:3000/admin/jaryo-file-manager.git -git push gitea master -``` - -## 🛠️ 문제 해결 - -### Docker 관련 문제 -```bash -# 컨테이너 상태 확인 -docker ps -a - -# 로그 확인 -docker logs gitea - -# 컨테이너 재시작 -docker restart gitea -``` - -### 포트 충돌 문제 -```bash -# 사용 중인 포트 확인 -sudo netstat -tulpn | grep :3000 - -# 다른 포트 사용 -docker run -d --name gitea -p 3001:3000 -p 223:22 -v /volume1/docker/gitea:/data gitea/gitea:latest -``` - -### 권한 문제 -```bash -# 데이터 디렉토리 권한 수정 -sudo chown -R 1000:1000 /volume1/docker/gitea -``` - -이 가이드를 통해 시놀로지 NAS Git Server 패키지 문제를 우회하여 안정적인 Git 서버를 구축할 수 있습니다. \ No newline at end of file diff --git a/api/files.js b/api/files.js deleted file mode 100644 index ae4fc90..0000000 --- a/api/files.js +++ /dev/null @@ -1,40 +0,0 @@ -// 파일 API -module.exports = (req, res) => { - // CORS 헤더 설정 - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); - - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - - // 샘플 파일 데이터 - const files = [ - { - id: 1, - title: '샘플 문서', - description: '데모용 파일입니다', - category: '문서', - tags: ['샘플', '테스트'], - created_at: new Date().toISOString(), - file_url: '#' - }, - { - id: 2, - title: '이미지 파일', - description: '예시 이미지', - category: '이미지', - tags: ['샘플'], - created_at: new Date().toISOString(), - file_url: '#' - } - ]; - - res.status(200).json({ - success: true, - data: files, - message: '파일 목록을 성공적으로 불러왔습니다.' - }); -}; \ No newline at end of file diff --git a/api/index.js b/api/index.js deleted file mode 100644 index 3a025de..0000000 --- a/api/index.js +++ /dev/null @@ -1,4 +0,0 @@ -const app = require('../server'); - -// Vercel 서버리스 함수로 export -module.exports = app; diff --git a/api/simple.js b/api/simple.js deleted file mode 100644 index a857985..0000000 --- a/api/simple.js +++ /dev/null @@ -1,124 +0,0 @@ -// Vercel Serverless 함수 핸들러 -module.exports = function handler(req, res) { - // CORS 헤더 설정 - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); - - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - - const { url, method } = req; - - // 헬스 체크 - if (url === '/health' || url === '/api/health') { - res.json({ - success: true, - message: 'Jaryo File Manager is running', - timestamp: new Date().toISOString(), - environment: process.env.NODE_ENV || 'production', - path: url - }); - return; - } - - // 루트 경로 - if (url === '/' || url === '/api') { - res.setHeader('Content-Type', 'text/html'); - res.end(` - - - - - - Jaryo File Manager - - - -
-

🚀 Jaryo File Manager

-
-

✅ 배포 성공!

-

Vercel Serverless에서 성공적으로 실행 중입니다.

-

시간: ${new Date().toLocaleString('ko-KR')}

-
-
-

🔧 API 엔드포인트

-

헬스 체크

-

파일 목록 API

-

공개 파일 API

-
-
-

📱 페이지

-

메인 페이지

-

관리자 페이지

-
-
- - - `); - return; - } - - // API 라우트들 - if (url === '/api/files' || url === '/api/files/public') { - res.json({ - success: true, - data: [ - { - id: 1, - title: '샘플 문서', - description: '데모용 파일입니다', - category: '문서', - tags: ['샘플', '테스트'], - created_at: new Date().toISOString(), - file_url: '#' - }, - { - id: 2, - title: '이미지 파일', - description: '예시 이미지', - category: '이미지', - tags: ['샘플'], - created_at: new Date().toISOString(), - file_url: '#' - } - ], - message: url.includes('public') ? '공개 파일 목록' : '파일 목록 API (데모 모드)' - }); - return; - } - - if (url === '/api/categories') { - res.json({ - success: true, - data: [ - { id: 1, name: '문서', description: '문서 파일' }, - { id: 2, name: '이미지', description: '이미지 파일' }, - { id: 3, name: '동영상', description: '동영상 파일' }, - { id: 4, name: '프레젠테이션', description: '프레젠테이션 파일' }, - { id: 5, name: '기타', description: '기타 파일' } - ], - message: '카테고리 목록' - }); - return; - } - - // 404 핸들러 - res.status(404).json({ - success: false, - error: '요청한 리소스를 찾을 수 없습니다.', - path: url, - method: method - }); -} diff --git a/api/test.js b/api/test.js deleted file mode 100644 index bcca53f..0000000 --- a/api/test.js +++ /dev/null @@ -1,21 +0,0 @@ -// 테스트용 간단한 API -module.exports = (req, res) => { - // CORS 헤더 설정 - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); - - if (req.method === 'OPTIONS') { - res.status(200).end(); - return; - } - - // 간단한 응답 - res.status(200).json({ - success: true, - message: 'API가 정상 작동합니다!', - timestamp: new Date().toISOString(), - url: req.url, - method: req.method - }); -}; \ No newline at end of file diff --git a/backup/supabase/admin-supabase-config.js b/backup/supabase/admin-supabase-config.js deleted file mode 100644 index 1dd95ee..0000000 --- a/backup/supabase/admin-supabase-config.js +++ /dev/null @@ -1,119 +0,0 @@ -// Supabase configuration (오프라인 모드) -// ⚠️ 오프라인 모드로 강제 설정됨 -const SUPABASE_CONFIG = { - url: 'https://kncudtzthmjegowbgnto.supabase.co', - anonKey: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImtuY3VkdHp0aG1qZWdvd2JnbnRvIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTU1Njc5OTksImV4cCI6MjA3MTE0Mzk5OX0.NlJN2vdgM96RvyVJE6ILQeDVUOU9X2F9vUn-jr_xlKc' -}; - -// Supabase 클라이언트 초기화 (강제 비활성화) -let supabase = null; - -// 설정이 유효한지 확인 -function isSupabaseConfigured() { - return false; // 강제로 false 반환 -} - -// Supabase 클라이언트 초기화 함수 (오프라인 모드 강제) -function initializeSupabase() { - console.log('⚠️ 오프라인 모드로 강제 설정되었습니다.'); - return false; -} - -// 인증 상태 변경 리스너 (오프라인 모드용 - 빈 함수) -function setupAuthListener(callback) { - // 오프라인 모드에서는 아무것도 하지 않음 - return; -} - -// 현재 사용자 가져오기 (오프라인 모드용 - null 반환) -async function getCurrentUser() { - return null; -} - -// 로그인 (오프라인 모드용 - 빈 함수) -async function signIn(email, password) { - throw new Error('오프라인 모드에서는 로그인할 수 없습니다.'); -} - -// 회원가입 (오프라인 모드용 - 빈 함수) -async function signUp(email, password, metadata = {}) { - throw new Error('오프라인 모드에서는 회원가입할 수 없습니다.'); -} - -// 로그아웃 (오프라인 모드용 - 빈 함수) -async function signOut() { - throw new Error('오프라인 모드에서는 로그아웃할 수 없습니다.'); -} - -// 데이터베이스 헬퍼 함수들 (오프라인 모드용) -const SupabaseHelper = { - // 파일 목록 가져오기 (오프라인 모드용) - async getFiles(userId) { - console.log('🔍 SupabaseHelper.getFiles 호출됨 (오프라인 모드)'); - throw new Error('오프라인 모드에서는 Supabase 데이터베이스를 사용할 수 없습니다.'); - }, - - // 파일 추가 (오프라인 모드용) - async addFile(fileData, userId) { - console.log('🔍 SupabaseHelper.addFile 호출됨 (오프라인 모드)'); - throw new Error('오프라인 모드에서는 Supabase 데이터베이스를 사용할 수 없습니다.'); - }, - - // 파일 수정 (오프라인 모드용) - async updateFile(id, updates, userId) { - console.log('🔍 SupabaseHelper.updateFile 호출됨 (오프라인 모드)'); - throw new Error('오프라인 모드에서는 Supabase 데이터베이스를 사용할 수 없습니다.'); - }, - - // 파일 삭제 (오프라인 모드용) - async deleteFile(id, userId) { - console.log('🔍 SupabaseHelper.deleteFile 호출됨 (오프라인 모드)'); - throw new Error('오프라인 모드에서는 Supabase 데이터베이스를 사용할 수 없습니다.'); - }, - - // 실시간 구독 설정 (오프라인 모드용) - subscribeToFiles(userId, callback) { - console.log('🔍 SupabaseHelper.subscribeToFiles 호출됨 (오프라인 모드)'); - return null; - }, - - // 파일 업로드 (오프라인 모드용) - async uploadFile(file, filePath) { - console.log('🔍 SupabaseHelper.uploadFile 호출됨 (오프라인 모드)'); - throw new Error('오프라인 모드에서는 Supabase Storage를 사용할 수 없습니다.'); - }, - - // 파일 다운로드 URL 가져오기 (오프라인 모드용) - async getFileUrl(filePath) { - console.log('🔍 SupabaseHelper.getFileUrl 호출됨 (오프라인 모드)'); - throw new Error('오프라인 모드에서는 Supabase Storage를 사용할 수 없습니다.'); - }, - - // 파일 삭제 (Storage) (오프라인 모드용) - async deleteStorageFile(filePath) { - console.log('🔍 SupabaseHelper.deleteStorageFile 호출됨 (오프라인 모드)'); - throw new Error('오프라인 모드에서는 Supabase Storage를 사용할 수 없습니다.'); - }, - - // 첨부파일 정보 추가 (오프라인 모드용) - async addFileAttachment(fileId, attachmentData) { - console.log('🔍 SupabaseHelper.addFileAttachment 호출됨 (오프라인 모드)'); - throw new Error('오프라인 모드에서는 Supabase 데이터베이스를 사용할 수 없습니다.'); - }, - - // Storage 버킷 확인 및 생성 (오프라인 모드용) - async checkOrCreateBucket() { - console.log('🔍 SupabaseHelper.checkOrCreateBucket 호출됨 (오프라인 모드)'); - return false; - } -}; - -// 전역으로 내보내기 -window.SupabaseHelper = SupabaseHelper; -window.initializeSupabase = initializeSupabase; -window.isSupabaseConfigured = isSupabaseConfigured; -window.setupAuthListener = setupAuthListener; -window.getCurrentUser = getCurrentUser; -window.signIn = signIn; -window.signUp = signUp; -window.signOut = signOut; \ No newline at end of file diff --git a/backup/supabase/clean-storage-setup.sql b/backup/supabase/clean-storage-setup.sql deleted file mode 100644 index 01dbb5e..0000000 --- a/backup/supabase/clean-storage-setup.sql +++ /dev/null @@ -1,62 +0,0 @@ --- 완전 초기화 후 Storage 정책 재설정 - --- 1단계: 모든 기존 Storage 정책 삭제 -DROP POLICY IF EXISTS "Users can upload to own folder" ON storage.objects; -DROP POLICY IF EXISTS "Users can view own files" ON storage.objects; -DROP POLICY IF EXISTS "Users can update own files" ON storage.objects; -DROP POLICY IF EXISTS "Users can delete own files" ON storage.objects; -DROP POLICY IF EXISTS "Public upload for testing" ON storage.objects; -DROP POLICY IF EXISTS "Public read for testing" ON storage.objects; - --- 혹시 다른 이름으로 생성된 정책들도 삭제 -DROP POLICY IF EXISTS "Enable insert for authenticated users only" ON storage.objects; -DROP POLICY IF EXISTS "Enable select for authenticated users only" ON storage.objects; -DROP POLICY IF EXISTS "Enable update for authenticated users only" ON storage.objects; -DROP POLICY IF EXISTS "Enable delete for authenticated users only" ON storage.objects; - --- 2단계: RLS 활성화 확인 (보통 이미 활성화되어 있음) -ALTER TABLE storage.objects ENABLE ROW LEVEL SECURITY; - --- 3단계: 새 정책 생성 --- 업로드 정책 -CREATE POLICY "Users can upload to own folder" -ON storage.objects -FOR INSERT -WITH CHECK ( - bucket_id = 'files' AND - auth.uid()::text = (storage.foldername(name))[1] -); - --- 조회 정책 -CREATE POLICY "Users can view own files" -ON storage.objects -FOR SELECT -USING ( - bucket_id = 'files' AND - auth.uid()::text = (storage.foldername(name))[1] -); - --- 업데이트 정책 -CREATE POLICY "Users can update own files" -ON storage.objects -FOR UPDATE -USING ( - bucket_id = 'files' AND - auth.uid()::text = (storage.foldername(name))[1] -); - --- 삭제 정책 -CREATE POLICY "Users can delete own files" -ON storage.objects -FOR DELETE -USING ( - bucket_id = 'files' AND - auth.uid()::text = (storage.foldername(name))[1] -); - --- 4단계: 정책 생성 확인 -SELECT - 'Storage policies created successfully!' as message, - COUNT(*) as policy_count -FROM pg_policies -WHERE schemaname = 'storage' AND tablename = 'objects'; \ No newline at end of file diff --git a/backup/supabase/setup-guide.md b/backup/supabase/setup-guide.md deleted file mode 100644 index f5f9ec7..0000000 --- a/backup/supabase/setup-guide.md +++ /dev/null @@ -1,150 +0,0 @@ -# Supabase 설정 가이드 - -이 문서는 자료실 시스템을 Supabase와 연동하기 위한 설정 가이드입니다. - -## 1. Supabase 프로젝트 생성 - -1. [Supabase](https://supabase.com)에 접속하여 계정을 생성합니다. -2. 새 프로젝트를 생성합니다. -3. 프로젝트 이름과 비밀번호를 설정합니다. -4. 리전은 `ap-northeast-1` (Asia Pacific - Tokyo)를 선택하는 것을 권장합니다. - -## 2. 데이터베이스 스키마 설정 - -1. Supabase 대시보드에서 **SQL Editor**로 이동합니다. -2. `supabase-schema.sql` 파일의 내용을 복사하여 실행합니다. -3. 스키마가 성공적으로 생성되었는지 **Table Editor**에서 확인합니다. - -### 생성되는 테이블 -- `files`: 파일 메타데이터 저장 -- `file_attachments`: 첨부파일 정보 저장 - -## 3. Storage 버킷 설정 - -1. Supabase 대시보드에서 **Storage**로 이동합니다. -2. **New bucket** 버튼을 클릭합니다. -3. 버킷 이름을 `files`로 설정합니다. -4. **Public bucket** 체크박스는 해제합니다 (보안상 권장). -5. 버킷을 생성합니다. - -### Storage 정책 설정 -버킷 생성 후 **Policies** 탭에서 다음 정책들을 추가합니다: - -#### SELECT 정책 (파일 조회) -```sql -CREATE POLICY "Users can view their own files" ON storage.objects -FOR SELECT USING ( - bucket_id = 'files' AND - auth.uid()::text = (storage.foldername(name))[1] -); -``` - -#### INSERT 정책 (파일 업로드) -```sql -CREATE POLICY "Users can upload their own files" ON storage.objects -FOR INSERT WITH CHECK ( - bucket_id = 'files' AND - auth.uid()::text = (storage.foldername(name))[1] -); -``` - -#### DELETE 정책 (파일 삭제) -```sql -CREATE POLICY "Users can delete their own files" ON storage.objects -FOR DELETE USING ( - bucket_id = 'files' AND - auth.uid()::text = (storage.foldername(name))[1] -); -``` - -## 4. API 키 및 URL 설정 - -1. Supabase 대시보드에서 **Settings** > **API**로 이동합니다. -2. 다음 정보를 확인합니다: - - **Project URL**: `https://your-project-id.supabase.co` - - **Project API keys** > **anon public**: `eyJ...` - -3. `supabase-config.js` 파일을 수정합니다: -```javascript -const SUPABASE_CONFIG = { - url: 'https://your-project-id.supabase.co', // 실제 Project URL로 교체 - anonKey: 'eyJ...' // 실제 anon public key로 교체 -}; -``` - -## 5. 인증 설정 (선택사항) - -### 이메일 인증 비활성화 (개발용) -개발 환경에서 빠른 테스트를 위해 이메일 인증을 비활성화할 수 있습니다: - -1. **Authentication** > **Settings**로 이동 -2. **Enable email confirmations** 체크박스 해제 -3. **Save** 클릭 - -⚠️ **주의**: 프로덕션 환경에서는 이메일 인증을 활성화하는 것을 강력히 권장합니다. - -### 이메일 템플릿 설정 (프로덕션용) -1. **Authentication** > **Email Templates**에서 이메일 템플릿을 커스터마이징할 수 있습니다. -2. 회사 브랜드에 맞게 이메일 디자인을 수정하세요. - -## 6. 보안 설정 - -### Row Level Security (RLS) -스키마 실행 시 자동으로 설정되지만, 다음 사항을 확인하세요: - -1. **Authentication** > **Policies**에서 정책이 올바르게 설정되었는지 확인 -2. 각 테이블에 사용자별 접근 제한이 적용되어 있는지 확인 - -### 환경변수 보안 -프로덕션 환경에서는 API 키를 환경변수로 관리하세요: - -```javascript -const SUPABASE_CONFIG = { - url: process.env.SUPABASE_URL || 'YOUR_SUPABASE_PROJECT_URL', - anonKey: process.env.SUPABASE_ANON_KEY || 'YOUR_SUPABASE_ANON_KEY' -}; -``` - -## 7. 테스트 - -설정 완료 후 다음 기능들을 테스트하세요: - -1. **회원가입/로그인** - 새 계정 생성 및 로그인 -2. **파일 추가** - 새 자료 추가 (첨부파일 포함) -3. **파일 수정** - 기존 자료 수정 -4. **파일 삭제** - 자료 삭제 (첨부파일도 함께 삭제되는지 확인) -5. **파일 다운로드** - 첨부파일 다운로드 -6. **실시간 동기화** - 다른 브라우저에서 같은 계정으로 로그인하여 실시간 동기화 확인 - -## 8. 문제 해결 - -### 연결 오류 -- Supabase URL과 API 키가 올바른지 확인 -- 브라우저 콘솔에서 오류 메시지 확인 -- CORS 설정 확인 (대부분 자동으로 설정됨) - -### 권한 오류 -- RLS 정책이 올바르게 설정되었는지 확인 -- 사용자가 올바르게 인증되었는지 확인 - -### 파일 업로드 오류 -- Storage 버킷이 올바르게 생성되었는지 확인 -- Storage 정책이 올바르게 설정되었는지 확인 -- 파일 크기 제한 확인 (Supabase 기본값: 50MB) - -## 9. 추가 개선사항 - -### 성능 최적화 -- 대용량 파일 처리를 위한 chunk 업로드 구현 -- 이미지 최적화 및 썸네일 생성 -- CDN 연동 고려 - -### 기능 확장 -- 파일 공유 기능 -- 버전 관리 -- 협업 기능 -- 백업 및 복원 기능 - ---- - -설정 중 문제가 발생하면 [Supabase 공식 문서](https://supabase.com/docs)를 참고하거나 이슈를 등록해주세요. \ No newline at end of file diff --git a/backup/supabase/storage-policies.sql b/backup/supabase/storage-policies.sql deleted file mode 100644 index 95ec94c..0000000 --- a/backup/supabase/storage-policies.sql +++ /dev/null @@ -1,39 +0,0 @@ --- Storage 전용 정책 (Supabase Dashboard → Storage → Policies에서 실행) - --- 1. 파일 업로드 정책 -CREATE POLICY "Users can upload to own folder" -ON storage.objects -FOR INSERT -WITH CHECK ( - bucket_id = 'files' AND - auth.uid()::text = (storage.foldername(name))[1] -); - --- 2. 파일 조회 정책 -CREATE POLICY "Users can view own files" -ON storage.objects -FOR SELECT -USING ( - bucket_id = 'files' AND - auth.uid()::text = (storage.foldername(name))[1] -); - --- 3. 파일 업데이트 정책 -CREATE POLICY "Users can update own files" -ON storage.objects -FOR UPDATE -USING ( - bucket_id = 'files' AND - auth.uid()::text = (storage.foldername(name))[1] -); - --- 4. 파일 삭제 정책 -CREATE POLICY "Users can delete own files" -ON storage.objects -FOR DELETE -USING ( - bucket_id = 'files' AND - auth.uid()::text = (storage.foldername(name))[1] -); - --- 참고: storage.foldername(name)[1]은 'user_id/filename.txt'에서 'user_id' 부분을 추출합니다. \ No newline at end of file diff --git a/backup/supabase/supabase-config.js b/backup/supabase/supabase-config.js deleted file mode 100644 index 21061ab..0000000 --- a/backup/supabase/supabase-config.js +++ /dev/null @@ -1,309 +0,0 @@ -// Supabase configuration -// ⚠️ 실제 사용 시에는 이 값들을 환경변수나 설정 파일로 관리하세요 -const SUPABASE_CONFIG = { - // 실제 Supabase 프로젝트 URL로 교체하세요 - url: 'https://kncudtzthmjegowbgnto.supabase.co', - // 실제 Supabase anon key로 교체하세요 - anonKey: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImtuY3VkdHp0aG1qZWdvd2JnbnRvIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTU1Njc5OTksImV4cCI6MjA3MTE0Mzk5OX0.NlJN2vdgM96RvyVJE6ILQeDVUOU9X2F9vUn-jr_xlKc' -}; - -// Supabase 클라이언트 초기화 -let supabase; - -// 설정이 유효한지 확인 -function isSupabaseConfigured() { - return SUPABASE_CONFIG.url !== 'YOUR_SUPABASE_PROJECT_URL' && - SUPABASE_CONFIG.anonKey !== 'YOUR_SUPABASE_ANON_KEY'; -} - -// Supabase 클라이언트 초기화 함수 -function initializeSupabase() { - if (!isSupabaseConfigured()) { - console.warn('⚠️ Supabase가 설정되지 않았습니다. localStorage를 사용합니다.'); - return false; - } - - try { - supabase = window.supabase.createClient(SUPABASE_CONFIG.url, SUPABASE_CONFIG.anonKey); - console.log('✅ Supabase 클라이언트가 초기화되었습니다.'); - return true; - } catch (error) { - console.error('❌ Supabase 초기화 오류:', error); - return false; - } -} - -// 인증 상태 변경 리스너 -function setupAuthListener(callback) { - if (!supabase) return; - - supabase.auth.onAuthStateChange((event, session) => { - console.log('Auth state changed:', event, session); - if (callback) callback(event, session); - }); -} - -// 현재 사용자 가져오기 -async function getCurrentUser() { - if (!supabase) return null; - - try { - const { data: { user }, error } = await supabase.auth.getUser(); - if (error) throw error; - return user; - } catch (error) { - console.error('사용자 정보 가져오기 오류:', error); - return null; - } -} - -// 로그인 -async function signIn(email, password) { - if (!supabase) throw new Error('Supabase가 초기화되지 않았습니다.'); - - const { data, error } = await supabase.auth.signInWithPassword({ - email, - password - }); - - if (error) throw error; - return data; -} - -// 회원가입 -async function signUp(email, password, metadata = {}) { - if (!supabase) throw new Error('Supabase가 초기화되지 않았습니다.'); - - const { data, error } = await supabase.auth.signUp({ - email, - password, - options: { - data: metadata - } - }); - - if (error) throw error; - return data; -} - -// 로그아웃 -async function signOut() { - if (!supabase) throw new Error('Supabase가 초기화되지 않았습니다.'); - - const { error } = await supabase.auth.signOut(); - if (error) throw error; -} - -// 데이터베이스 헬퍼 함수들 -const SupabaseHelper = { - // 파일 목록 가져오기 - async getFiles(userId) { - if (!supabase) throw new Error('Supabase가 초기화되지 않았습니다.'); - - let query = supabase - .from('files') - .select(` - *, - file_attachments (*) - `); - - // 공개 파일 요청이 아닌 경우에만 사용자 ID로 필터링 - if (userId !== 'public') { - query = query.eq('user_id', userId); - } - - const { data, error } = await query.order('created_at', { ascending: false }); - - if (error) throw error; - return data; - }, - - // 파일 추가 - async addFile(fileData, userId) { - if (!supabase) throw new Error('Supabase가 초기화되지 않았습니다.'); - - // 데이터베이스 스키마에 맞는 필드만 추출 - const dbFileData = { - title: fileData.title, - description: fileData.description || '', - category: fileData.category, - tags: fileData.tags || [], - user_id: userId - // created_at, updated_at은 데이터베이스에서 자동 생성 - }; - - const { data, error } = await supabase - .from('files') - .insert([dbFileData]) - .select() - .single(); - - if (error) throw error; - return data; - }, - - // 파일 수정 - async updateFile(id, updates, userId) { - if (!supabase) throw new Error('Supabase가 초기화되지 않았습니다.'); - - // 데이터베이스 스키마에 맞는 필드만 추출 - const dbUpdates = { - title: updates.title, - description: updates.description, - category: updates.category, - tags: updates.tags || [] - // updated_at은 트리거에 의해 자동 업데이트됨 - }; - - const { data, error } = await supabase - .from('files') - .update(dbUpdates) - .eq('id', id) - .eq('user_id', userId) - .select() - .single(); - - if (error) throw error; - return data; - }, - - // 파일 삭제 - async deleteFile(id, userId) { - if (!supabase) throw new Error('Supabase가 초기화되지 않았습니다.'); - - const { error } = await supabase - .from('files') - .delete() - .eq('id', id) - .eq('user_id', userId); - - if (error) throw error; - }, - - // 실시간 구독 설정 - subscribeToFiles(userId, callback) { - if (!supabase) return null; - - return supabase - .channel('files') - .on('postgres_changes', { - event: '*', - schema: 'public', - table: 'files', - filter: `user_id=eq.${userId}` - }, callback) - .subscribe(); - }, - - // 파일 업로드 (Storage) - async uploadFile(file, filePath) { - if (!supabase) throw new Error('Supabase가 초기화되지 않았습니다.'); - - const { data, error } = await supabase.storage - .from('files') - .upload(filePath, file); - - if (error) throw error; - return data; - }, - - // 파일 다운로드 URL 가져오기 - async getFileUrl(filePath) { - if (!supabase) throw new Error('Supabase가 초기화되지 않았습니다.'); - - try { - // 먼저 파일이 존재하는지 확인 - const { data: fileExists, error: checkError } = await supabase.storage - .from('files') - .list(filePath.substring(0, filePath.lastIndexOf('/')), { - search: filePath.substring(filePath.lastIndexOf('/') + 1) - }); - - if (checkError) { - throw new Error(`Storage 버킷 오류: ${checkError.message}`); - } - - if (!fileExists || fileExists.length === 0) { - throw new Error('파일을 찾을 수 없습니다.'); - } - - // 파일이 존재하면 URL 생성 - const { data } = supabase.storage - .from('files') - .getPublicUrl(filePath); - - return data.publicUrl; - } catch (error) { - console.error('파일 URL 생성 오류:', error); - throw error; - } - }, - - // 파일 삭제 (Storage) - async deleteStorageFile(filePath) { - if (!supabase) throw new Error('Supabase가 초기화되지 않았습니다.'); - - const { error } = await supabase.storage - .from('files') - .remove([filePath]); - - if (error) throw error; - }, - - // 첨부파일 정보 추가 - async addFileAttachment(fileId, attachmentData) { - if (!supabase) throw new Error('Supabase가 초기화되지 않았습니다.'); - - const { data, error } = await supabase - .from('file_attachments') - .insert([{ - file_id: fileId, - ...attachmentData - }]) - .select() - .single(); - - if (error) throw error; - return data; - }, - - // Storage 버킷 확인 및 생성 - async checkOrCreateBucket() { - if (!supabase) throw new Error('Supabase가 초기화되지 않았습니다.'); - - try { - // 버킷 목록 확인 - const { data: buckets, error: listError } = await supabase.storage.listBuckets(); - - if (listError) { - console.error('버킷 목록 조회 오류:', listError); - return false; - } - - // 'files' 버킷이 있는지 확인 - const filesBucket = buckets.find(bucket => bucket.name === 'files'); - - if (filesBucket) { - console.log('✅ files 버킷이 존재합니다.'); - return true; - } else { - console.warn('⚠️ files 버킷이 존재하지 않습니다.'); - console.log('Supabase Dashboard에서 files 버킷을 생성해주세요.'); - return false; - } - } catch (error) { - console.error('버킷 확인 오류:', error); - return false; - } - } -}; - -// 전역으로 내보내기 -window.SupabaseHelper = SupabaseHelper; -window.initializeSupabase = initializeSupabase; -window.isSupabaseConfigured = isSupabaseConfigured; -window.setupAuthListener = setupAuthListener; -window.getCurrentUser = getCurrentUser; -window.signIn = signIn; -window.signUp = signUp; -window.signOut = signOut; \ No newline at end of file diff --git a/backup/supabase/supabase-schema.sql b/backup/supabase/supabase-schema.sql deleted file mode 100644 index 3d408a8..0000000 --- a/backup/supabase/supabase-schema.sql +++ /dev/null @@ -1,128 +0,0 @@ --- Supabase 데이터베이스 스키마 --- 이 파일을 Supabase SQL 에디터에서 실행하세요 - --- 1. files 테이블 생성 -CREATE TABLE IF NOT EXISTS public.files ( - id UUID DEFAULT gen_random_uuid() PRIMARY KEY, - title TEXT NOT NULL, - description TEXT, - category TEXT NOT NULL, - tags TEXT[] DEFAULT '{}', - user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE NOT NULL, - created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL, - updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL -); - --- 2. file_attachments 테이블 생성 (파일 첨부 정보) -CREATE TABLE IF NOT EXISTS public.file_attachments ( - id UUID DEFAULT gen_random_uuid() PRIMARY KEY, - file_id UUID REFERENCES public.files(id) ON DELETE CASCADE NOT NULL, - original_name TEXT NOT NULL, - storage_path TEXT NOT NULL, - file_size INTEGER NOT NULL, - mime_type TEXT NOT NULL, - created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL -); - --- 3. Row Level Security (RLS) 정책 활성화 -ALTER TABLE public.files ENABLE ROW LEVEL SECURITY; -ALTER TABLE public.file_attachments ENABLE ROW LEVEL SECURITY; - --- 4. files 테이블 RLS 정책 --- 사용자는 자신의 파일만 조회할 수 있음 -CREATE POLICY "Users can view their own files" ON public.files - FOR SELECT USING (auth.uid() = user_id); - --- 사용자는 자신의 파일만 생성할 수 있음 -CREATE POLICY "Users can create their own files" ON public.files - FOR INSERT WITH CHECK (auth.uid() = user_id); - --- 사용자는 자신의 파일만 수정할 수 있음 -CREATE POLICY "Users can update their own files" ON public.files - FOR UPDATE USING (auth.uid() = user_id); - --- 사용자는 자신의 파일만 삭제할 수 있음 -CREATE POLICY "Users can delete their own files" ON public.files - FOR DELETE USING (auth.uid() = user_id); - --- 5. file_attachments 테이블 RLS 정책 --- 사용자는 자신의 파일 첨부만 조회할 수 있음 -CREATE POLICY "Users can view their own file attachments" ON public.file_attachments - FOR SELECT USING ( - auth.uid() = ( - SELECT user_id FROM public.files WHERE id = file_attachments.file_id - ) - ); - --- 사용자는 자신의 파일에만 첨부를 생성할 수 있음 -CREATE POLICY "Users can create attachments for their own files" ON public.file_attachments - FOR INSERT WITH CHECK ( - auth.uid() = ( - SELECT user_id FROM public.files WHERE id = file_attachments.file_id - ) - ); - --- 사용자는 자신의 파일 첨부만 삭제할 수 있음 -CREATE POLICY "Users can delete their own file attachments" ON public.file_attachments - FOR DELETE USING ( - auth.uid() = ( - SELECT user_id FROM public.files WHERE id = file_attachments.file_id - ) - ); - --- 6. 인덱스 생성 (성능 최적화) -CREATE INDEX IF NOT EXISTS idx_files_user_id ON public.files(user_id); -CREATE INDEX IF NOT EXISTS idx_files_created_at ON public.files(created_at DESC); -CREATE INDEX IF NOT EXISTS idx_files_category ON public.files(category); -CREATE INDEX IF NOT EXISTS idx_files_tags ON public.files USING GIN(tags); -CREATE INDEX IF NOT EXISTS idx_file_attachments_file_id ON public.file_attachments(file_id); - --- 7. 업데이트 트리거 함수 (updated_at 자동 갱신) -CREATE OR REPLACE FUNCTION update_updated_at_column() -RETURNS TRIGGER AS $$ -BEGIN - NEW.updated_at = NOW(); - RETURN NEW; -END; -$$ language 'plpgsql'; - --- 8. updated_at 자동 갱신 트리거 -CREATE TRIGGER update_files_updated_at - BEFORE UPDATE ON public.files - FOR EACH ROW - EXECUTE FUNCTION update_updated_at_column(); - --- 9. Storage 버킷 생성 (실제로는 Supabase Dashboard에서 생성) --- 버킷 이름: 'files' --- 공개 액세스: false (인증된 사용자만 접근) --- --- Storage 정책은 Supabase Dashboard에서 다음과 같이 설정: --- SELECT: 사용자는 자신의 파일만 조회 가능 --- INSERT: 사용자는 자신의 폴더에만 업로드 가능 --- UPDATE: 사용자는 자신의 파일만 수정 가능 --- DELETE: 사용자는 자신의 파일만 삭제 가능 - --- 10. 유용한 뷰 생성 (파일과 첨부 정보 조인) --- 주의: 뷰는 자동으로 기본 테이블의 RLS 정책을 상속받으므로 별도 정책 설정 불필요 -CREATE OR REPLACE VIEW public.files_with_attachments AS -SELECT - f.*, - COALESCE( - JSON_AGG( - JSON_BUILD_OBJECT( - 'id', fa.id, - 'original_name', fa.original_name, - 'storage_path', fa.storage_path, - 'file_size', fa.file_size, - 'mime_type', fa.mime_type, - 'created_at', fa.created_at - ) - ) FILTER (WHERE fa.id IS NOT NULL), - '[]'::json - ) AS attachments -FROM public.files f -LEFT JOIN public.file_attachments fa ON f.id = fa.file_id -GROUP BY f.id, f.title, f.description, f.category, f.tags, f.user_id, f.created_at, f.updated_at; - --- 설정 완료 메시지 -SELECT 'Supabase 스키마 설정이 완료되었습니다!' as message; \ No newline at end of file diff --git a/backup/supabase/temp-public-policy.sql b/backup/supabase/temp-public-policy.sql deleted file mode 100644 index e0813fa..0000000 --- a/backup/supabase/temp-public-policy.sql +++ /dev/null @@ -1,16 +0,0 @@ --- 임시 공개 접근 정책 (테스트용만 사용!) --- 보안상 권장하지 않음 - 운영환경에서는 사용하지 마세요 - --- 모든 사용자가 files 버킷에 업로드 가능 (임시) -CREATE POLICY "Public upload for testing" -ON storage.objects -FOR INSERT -WITH CHECK (bucket_id = 'files'); - --- 모든 사용자가 files 버킷 파일 조회 가능 (임시) -CREATE POLICY "Public read for testing" -ON storage.objects -FOR SELECT -USING (bucket_id = 'files'); - --- 주의: 이 정책들은 테스트 후 반드시 삭제하고 위의 사용자별 정책으로 교체하세요! \ No newline at end of file diff --git a/cookies.txt b/cookies.txt deleted file mode 100644 index c153b4c..0000000 --- a/cookies.txt +++ /dev/null @@ -1,5 +0,0 @@ -# Netscape HTTP Cookie File -# https://curl.se/docs/http-cookies.html -# This file was generated by libcurl! Edit at your own risk. - -#HttpOnly_localhost FALSE / FALSE 1755826306 connect.sid s%3Alkct8oX-9zlTMoD6Mu3BP0RwCz0CFR-X.Mad5GaxzMugYjbnKEOxUq9mnbJkkJY3O79f3q%2BaE%2BJ4 diff --git a/create-git-repo.sh b/create-git-repo.sh deleted file mode 100644 index 0657132..0000000 --- a/create-git-repo.sh +++ /dev/null @@ -1,141 +0,0 @@ -#!/bin/bash - -# 시놀로지 NAS Git 저장소 생성 스크립트 (개선 버전) -# 사용법: ./create-git-repo.sh [repo-name] [git-dir] - -# 기본 설정 -DEFAULT_GIT_DIR="/volume1/git" -DEFAULT_REPO_NAME="jaryo-file-manager" - -# 매개변수 처리 -REPO_NAME="${1:-$DEFAULT_REPO_NAME}" -GIT_DIR="${2:-$DEFAULT_GIT_DIR}" -REPO_PATH="$GIT_DIR/$REPO_NAME.git" - -echo "=== 시놀로지 NAS Git 저장소 생성 ===" -echo "저장소 이름: $REPO_NAME" -echo "Git 디렉토리: $GIT_DIR" -echo "저장소 경로: $REPO_PATH" -echo "==========================================" - -# 권한 확인 -if [ "$EUID" -ne 0 ] && [ "$(whoami)" != "admin" ]; then - echo "⚠️ 경고: 관리자 권한이 필요할 수 있습니다." - echo "sudo 또는 admin 계정으로 실행하세요." -fi - -# Git 설치 확인 -if ! command -v git &> /dev/null; then - echo "❌ Git이 설치되지 않았습니다." - echo "패키지 센터에서 Git Server를 설치하거나 다음 명령어를 실행하세요:" - echo "sudo apt update && sudo apt install git" - exit 1 -fi - -# Git 디렉토리 확인 및 생성 -echo "📁 Git 디렉토리 확인 중..." -if [ ! -d "$GIT_DIR" ]; then - echo "Git 디렉토리가 없습니다. 생성 중..." - mkdir -p "$GIT_DIR" || { - echo "❌ Git 디렉토리 생성 실패. 권한을 확인하세요." - exit 1 - } - - # 권한 설정 - if command -v chown &> /dev/null; then - chown admin:users "$GIT_DIR" 2>/dev/null || echo "⚠️ chown 권한 부족" - fi - chmod 755 "$GIT_DIR" 2>/dev/null || echo "⚠️ chmod 권한 부족" - echo "✅ Git 디렉토리 생성 완료: $GIT_DIR" -else - echo "✅ Git 디렉토리 존재 확인: $GIT_DIR" -fi - -# 기존 저장소 확인 -if [ -d "$REPO_PATH" ]; then - echo "⚠️ 저장소가 이미 존재합니다: $REPO_PATH" - read -p "삭제 후 재생성하시겠습니까? (y/N): " confirm - if [[ $confirm =~ ^[Yy]$ ]]; then - rm -rf "$REPO_PATH" - echo "🗑️ 기존 저장소 삭제 완료" - else - echo "❌ 작업을 취소합니다." - exit 1 - fi -fi - -# 저장소 디렉토리 생성 -echo "📂 저장소 디렉토리 생성 중..." -mkdir -p "$REPO_PATH" || { - echo "❌ 저장소 디렉토리 생성 실패" - exit 1 -} - -# Git 저장소 초기화 -echo "🔧 Git 저장소 초기화 중..." -cd "$REPO_PATH" || exit 1 -git init --bare || { - echo "❌ Git 저장소 초기화 실패" - exit 1 -} - -# 권한 설정 -echo "🔐 권한 설정 중..." -if command -v chown &> /dev/null; then - chown -R admin:users "$REPO_PATH" 2>/dev/null || echo "⚠️ chown 권한 부족" -fi -chmod -R 755 "$REPO_PATH" 2>/dev/null || echo "⚠️ chmod 권한 부족" - -# Git hooks 설정 (선택사항) -echo "🪝 Git hooks 설정 중..." -cat > "$REPO_PATH/hooks/post-receive" << 'EOF' -#!/bin/bash -# 자동 배포 hook (선택사항) -echo "푸시 완료: $(date)" -echo "저장소: $PWD" -EOF -chmod +x "$REPO_PATH/hooks/post-receive" 2>/dev/null - -# 저장소 설명 파일 생성 -echo "📄 저장소 설명 파일 생성 중..." -cat > "$REPO_PATH/description" << EOF -Jaryo File Manager - 시놀로지 NAS 자료실 파일 관리 시스템 -EOF - -# Git 서비스 확인 및 시작 -echo "🔄 Git 서비스 상태 확인 중..." -NAS_IP=$(hostname -I | awk '{print $1}' | tr -d ' ') - -# 다양한 방법으로 IP 확인 -if [ -z "$NAS_IP" ]; then - NAS_IP=$(ip route get 1 | awk '{print $7; exit}' 2>/dev/null) -fi -if [ -z "$NAS_IP" ]; then - NAS_IP="your-nas-ip" -fi - -echo "✅ Git 저장소 생성 완료!" -echo "==========================================" -echo "📋 저장소 정보:" -echo " - 이름: $REPO_NAME" -echo " - 경로: $REPO_PATH" -echo " - 설명: 자료실 파일 관리 시스템" -echo "" -echo "🌐 연결 URL:" -echo " SSH: ssh://admin@$NAS_IP$REPO_PATH" -echo " HTTP: http://$NAS_IP:3000/git/$REPO_NAME.git" -echo "" -echo "🔗 로컬에서 연결하는 방법:" -echo " git remote add nas ssh://admin@$NAS_IP$REPO_PATH" -echo " git push nas master" -echo "" -echo "📝 다음 단계:" -echo " 1. 로컬 프로젝트에서 원격 저장소 추가" -echo " 2. 첫 번째 push 실행" -echo " 3. Git 서비스 동작 확인" -echo "" -echo "🔧 Git 서비스 수동 시작 (필요시):" -echo " sudo systemctl start git-daemon" -echo " sudo git daemon --base-path=$GIT_DIR --export-all --reuseaddr &" -echo "" -echo "📖 자세한 설정은 synology-git-diagnostic.md 파일을 참조하세요." diff --git a/debug-files.js b/debug-files.js deleted file mode 100644 index 5789cf8..0000000 --- a/debug-files.js +++ /dev/null @@ -1,68 +0,0 @@ -const DatabaseHelper = require('./database/db-helper'); -const fs = require('fs'); -const path = require('path'); - -async function debugFiles() { - const db = new DatabaseHelper(); - - try { - await db.connect(); - - console.log('\n📋 데이터베이스의 모든 파일:'); - const files = await db.getAllFiles(); - - files.forEach((file, index) => { - console.log(`\n${index + 1}. ${file.title} (ID: ${file.id})`); - console.log(` 카테고리: ${file.category}`); - console.log(` 첨부파일: ${file.files?.length || 0}개`); - - if (file.files && file.files.length > 0) { - file.files.forEach((attachment, idx) => { - console.log(` ${idx + 1}) ${attachment.original_name}`); - console.log(` - ID: ${attachment.id}`); - console.log(` - 경로: ${attachment.file_path}`); - console.log(` - 파일명: ${attachment.file_name}`); - console.log(` - 크기: ${attachment.file_size}`); - - // 실제 파일 존재 확인 - const fullPath = path.join(__dirname, attachment.file_path); - const exists = fs.existsSync(fullPath); - console.log(` - 실제 파일 존재: ${exists ? '✅' : '❌'} (${fullPath})`); - - if (!exists) { - // 다른 경로들 시도 - const paths = [ - path.join(__dirname, 'uploads', attachment.file_name), - path.join(__dirname, 'uploads', attachment.original_name), - attachment.file_path, - ]; - - console.log(` - 시도할 경로들:`); - paths.forEach(p => { - const pathExists = fs.existsSync(p); - console.log(` ${pathExists ? '✅' : '❌'} ${p}`); - }); - } - }); - } - }); - - console.log('\n📁 uploads 폴더의 실제 파일들:'); - const uploadsDir = path.join(__dirname, 'uploads'); - if (fs.existsSync(uploadsDir)) { - const actualFiles = fs.readdirSync(uploadsDir); - actualFiles.forEach(file => { - const filePath = path.join(uploadsDir, file); - const stats = fs.statSync(filePath); - console.log(` - ${file} (크기: ${stats.size})`); - }); - } - - } catch (error) { - console.error('❌ 오류:', error.message); - } finally { - await db.close(); - } -} - -debugFiles(); \ No newline at end of file diff --git a/deploy-manual.sh b/deploy-manual.sh deleted file mode 100644 index b865fb9..0000000 --- a/deploy-manual.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -# 수동 배포 스크립트 - 각 단계를 개별 실행 -NAS_IP="119.64.1.86" -NAS_USER="vibsin9322" -DEPLOY_DIR="/volume1/web/jaryo" -GITEA_URL="http://119.64.1.86:3000/vibsin9322/jaryo.git" - -echo "==========================================" -echo "🔧 수동 배포 가이드" -echo "==========================================" -echo "다음 명령들을 하나씩 실행하세요:" -echo "" - -echo "1️⃣ SSH 연결 테스트:" -echo "ssh -p 2222 $NAS_USER@$NAS_IP" -echo "" - -echo "2️⃣ 기존 배포 백업 (있는 경우):" -echo "ssh -p 2222 $NAS_USER@$NAS_IP 'sudo cp -r $DEPLOY_DIR ${DEPLOY_DIR}_backup_\$(date +%Y%m%d_%H%M%S) 2>/dev/null || true'" -echo "" - -echo "3️⃣ 배포 디렉토리 준비:" -echo "ssh -p 2222 $NAS_USER@$NAS_IP 'sudo rm -rf $DEPLOY_DIR && sudo mkdir -p $DEPLOY_DIR && sudo chown $NAS_USER:users $DEPLOY_DIR'" -echo "" - -echo "4️⃣ Git 클론:" -echo "ssh -p 2222 $NAS_USER@$NAS_IP 'cd $DEPLOY_DIR && git clone $GITEA_URL .'" -echo "" - -echo "5️⃣ 의존성 설치:" -echo "ssh -p 2222 $NAS_USER@$NAS_IP 'cd $DEPLOY_DIR && npm install'" -echo "" - -echo "6️⃣ 데이터베이스 처리:" -echo "ssh -p 2222 $NAS_USER@$NAS_IP 'cd $DEPLOY_DIR && if [ -f data/database.db ]; then echo \"기존 DB 유지\"; else npm run init-db; fi'" -echo "" - -echo "7️⃣ 서비스 시작:" -echo "ssh -p 2222 $NAS_USER@$NAS_IP 'cd $DEPLOY_DIR && PORT=3005 nohup node server.js > logs/app.log 2>&1 & echo \$! > jaryo.pid'" -echo "" - -echo "8️⃣ 서비스 확인:" -echo "curl http://$NAS_IP:3005" -echo "" -echo "==========================================" \ No newline at end of file diff --git a/enhanced-server.js b/enhanced-server.js deleted file mode 100644 index c8d9cc0..0000000 --- a/enhanced-server.js +++ /dev/null @@ -1,234 +0,0 @@ -const http = require("http"); -const fs = require("fs"); -const path = require("path"); -const url = require("url"); - -const PORT = 3005; -const DATA_FILE = path.join(__dirname, 'data.json'); -const UPLOAD_DIR = path.join(__dirname, 'uploads'); - -// 데이터 파일 초기화 -function initializeData() { - const defaultData = { - users: [ - { - id: '1', - email: 'admin@jaryo.com', - password: 'admin123', - name: '관리자', - role: 'admin' - } - ], - files: [ - { - id: '1', - title: '샘플 문서', - description: '자료실 테스트용 샘플 파일입니다.', - category: '문서', - tags: ['샘플', '테스트'], - user_id: '1', - created_at: new Date().toISOString(), - updated_at: new Date().toISOString(), - attachments: [] - } - ], - categories: ['문서', '이미지', '동영상', '프레젠테이션', '기타'] - }; - - if (!fs.existsSync(DATA_FILE)) { - fs.writeFileSync(DATA_FILE, JSON.stringify(defaultData, null, 2)); - } - - if (!fs.existsSync(UPLOAD_DIR)) { - fs.mkdirSync(UPLOAD_DIR, { recursive: true }); - } -} - -// 데이터 읽기/쓰기 -function readData() { - try { - const data = fs.readFileSync(DATA_FILE, 'utf8'); - return JSON.parse(data); - } catch (error) { - console.error('데이터 읽기 오류:', error); - return { users: [], files: [], categories: [] }; - } -} - -function writeData(data) { - try { - fs.writeFileSync(DATA_FILE, JSON.stringify(data, null, 2)); - return true; - } catch (error) { - console.error('데이터 쓰기 오류:', error); - return false; - } -} - -// MIME 타입 -const mimeTypes = { - ".html": "text/html; charset=utf-8", - ".css": "text/css", - ".js": "application/javascript", - ".json": "application/json", - ".png": "image/png", - ".jpg": "image/jpeg" -}; - -// API 요청 처리 -async function handleApiRequest(req, res, pathname, query) { - const data = readData(); - - if (pathname === "/api/files/public" && req.method === "GET") { - res.writeHead(200, { "Content-Type": "application/json" }); - res.end(JSON.stringify({ - success: true, - data: data.files, - total: data.files.length - })); - return; - } - - if (pathname === "/api/files" && req.method === "GET") { - res.writeHead(200, { "Content-Type": "application/json" }); - res.end(JSON.stringify({ - success: true, - data: data.files, - total: data.files.length - })); - return; - } - - if (pathname === "/api/auth/login" && req.method === "POST") { - let body = ''; - req.on('data', chunk => body += chunk); - req.on('end', () => { - try { - const { email, password } = JSON.parse(body); - const user = data.users.find(u => u.email === email && u.password === password); - - if (user) { - res.writeHead(200, { "Content-Type": "application/json" }); - res.end(JSON.stringify({ - success: true, - user: { - id: user.id, - email: user.email, - name: user.name, - role: user.role - } - })); - } else { - res.writeHead(401, { "Content-Type": "application/json" }); - res.end(JSON.stringify({ - success: false, - error: '이메일 또는 비밀번호가 올바르지 않습니다.' - })); - } - } catch (error) { - res.writeHead(400, { "Content-Type": "application/json" }); - res.end(JSON.stringify({ - success: false, - error: '잘못된 요청입니다.' - })); - } - }); - return; - } - - // 기본 응답 - res.writeHead(200, { "Content-Type": "application/json" }); - res.end(JSON.stringify({ - success: true, - message: "자료실 API 서버 실행 중", - timestamp: new Date().toISOString(), - path: pathname - })); -} - -// 정적 파일 서빙 -async function serveStaticFile(req, res, pathname) { - const filePath = path.join(__dirname, pathname); - - fs.readFile(filePath, (err, data) => { - if (err) { - res.writeHead(404, { "Content-Type": "text/html; charset=utf-8" }); - res.end(` - - 404 Not Found - -

404 - 파일을 찾을 수 없습니다

-

요청한 파일: ${pathname}

-

홈으로 돌아가기

- - - `); - return; - } - - const ext = path.extname(filePath); - const contentType = mimeTypes[ext] || "text/plain"; - - res.writeHead(200, { "Content-Type": contentType }); - res.end(data); - }); -} - -// HTTP 서버 -const server = http.createServer(async (req, res) => { - res.setHeader("Access-Control-Allow-Origin", "*"); - res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); - res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With"); - - if (req.method === "OPTIONS") { - res.writeHead(200); - res.end(); - return; - } - - const parsedUrl = url.parse(req.url, true); - let pathname = parsedUrl.pathname; - const query = parsedUrl.query; - - console.log(`📨 ${req.method} ${pathname}`); - - if (pathname.startsWith("/api/")) { - try { - await handleApiRequest(req, res, pathname, query); - } catch (error) { - console.error('API 처리 오류:', error); - res.writeHead(500, { "Content-Type": "application/json" }); - res.end(JSON.stringify({ - success: false, - error: '서버 내부 오류가 발생했습니다.' - })); - } - return; - } - - if (pathname === "/" || pathname === "/index.html") { - pathname = "/index.html"; - } else if (pathname === "/admin" || pathname === "/admin/") { - pathname = "/admin/index.html"; - } - - await serveStaticFile(req, res, pathname); -}); - -server.listen(PORT, () => { - console.log(`🚀 향상된 자료실 서버가 포트 ${PORT}에서 실행 중입니다`); - console.log(`📍 접속 URL: http://119.64.1.86:${PORT}`); - console.log(`🔧 관리자 URL: http://119.64.1.86:${PORT}/admin`); - console.log(`⏰ 시작 시간: ${new Date().toLocaleString("ko-KR")}`); - - initializeData(); - console.log(`✅ 데이터 파일 초기화 완료`); -}); - -process.on("SIGINT", () => { - console.log("\n🛑 서버를 종료합니다..."); - server.close(() => { - console.log("✅ 서버가 정상적으로 종료되었습니다"); - process.exit(0); - }); -}); \ No newline at end of file diff --git a/manual-nas-deployment-guide.md b/manual-nas-deployment-guide.md deleted file mode 100644 index 3f36a5c..0000000 --- a/manual-nas-deployment-guide.md +++ /dev/null @@ -1,328 +0,0 @@ -# 시놀로지 NAS 수동 배포 가이드 - -## 🚀 시놀로지 NAS에서 자료실 서비스 배포하기 - -### 사전 준비사항 ✅ - -1. **DSM 패키지 설치 확인** - - Node.js v16+ (패키지 센터에서 설치) - - Git Server (패키지 센터에서 설치) - - SSH 서비스 활성화 (제어판 > 터미널 및 SNMP) - -2. **방화벽 설정** - - SSH 포트: 2222 허용 - - 서비스 포트: 3005 허용 - - Gitea 포트: 3000 허용 - -### 1단계: SSH 접속 🔗 - -```bash -# Windows에서 NAS 접속 -ssh -p 2222 admin@119.64.1.86 - -# 접속 후 관리자 권한 확인 -sudo whoami -``` - -### 2단계: 배포 디렉토리 준비 📁 - -```bash -# 웹 디렉토리로 이동 -cd /volume1/web - -# 기존 jaryo 폴더가 있다면 백업 -if [ -d "jaryo" ]; then - sudo mv jaryo jaryo_backup_$(date +%Y%m%d_%H%M%S) -fi - -# 새 디렉토리 생성 -sudo mkdir -p jaryo -sudo chown admin:users jaryo -cd jaryo -``` - -### 3단계: 소스 코드 클론 📥 - -```bash -# Gitea에서 소스 코드 클론 -git clone http://119.64.1.86:3000/vibsin9322/jaryo.git . - -# 클론 성공 확인 -ls -la -``` - -### 4단계: 의존성 설치 📦 - -```bash -# 기존 node_modules 제거 (있다면) -rm -rf node_modules package-lock.json - -# npm 의존성 설치 -npm install - -# 설치 확인 -ls -la node_modules -``` - -### 5단계: 데이터베이스 초기화 🗄️ - -```bash -# SQLite 데이터베이스 초기화 -npm run init-db - -# 데이터베이스 파일 확인 -ls -la *.db -``` - -### 6단계: 서비스 시작 스크립트 생성 📝 - -```bash -# 시작 스크립트 생성 -cat > start-jaryo.sh << 'EOF' -#!/bin/bash - -# 자료실 서비스 시작 스크립트 -PROJECT_DIR="/volume1/web/jaryo" -SERVICE_PORT="3005" -PID_FILE="$PROJECT_DIR/jaryo.pid" -LOG_FILE="$PROJECT_DIR/jaryo.log" - -# 로그 디렉토리 생성 -mkdir -p "$PROJECT_DIR/logs" - -# 기존 프로세스 확인 및 종료 -if [ -f "$PID_FILE" ]; then - OLD_PID=$(cat "$PID_FILE") - if ps -p "$OLD_PID" > /dev/null; then - echo "기존 서비스 종료 중... (PID: $OLD_PID)" - kill "$OLD_PID" - sleep 2 - fi - rm -f "$PID_FILE" -fi - -# 포트 사용 확인 -if netstat -tulpn | grep ":$SERVICE_PORT " > /dev/null; then - echo "⚠️ 포트 $SERVICE_PORT가 이미 사용 중입니다." - echo "사용 중인 프로세스:" - netstat -tulpn | grep ":$SERVICE_PORT " - exit 1 -fi - -# 서비스 시작 -echo "🚀 자료실 서비스 시작 중..." -cd "$PROJECT_DIR" -PORT="$SERVICE_PORT" nohup node server.js > "$LOG_FILE" 2>&1 & -echo $! > "$PID_FILE" - -sleep 2 - -# 시작 확인 -if ps -p $(cat "$PID_FILE") > /dev/null; then - echo "✅ 자료실 서비스 시작 완료!" - echo "📍 접속 URL: http://119.64.1.86:$SERVICE_PORT" - echo "📋 PID: $(cat "$PID_FILE")" - echo "📄 로그: $LOG_FILE" -else - echo "❌ 서비스 시작 실패" - echo "로그 확인:" - tail -20 "$LOG_FILE" - exit 1 -fi -EOF - -# 실행 권한 부여 -chmod +x start-jaryo.sh -``` - -### 7단계: 중지 스크립트 생성 🛑 - -```bash -# 중지 스크립트 생성 -cat > stop-jaryo.sh << 'EOF' -#!/bin/bash - -# 자료실 서비스 중지 스크립트 -PROJECT_DIR="/volume1/web/jaryo" -PID_FILE="$PROJECT_DIR/jaryo.pid" - -if [ -f "$PID_FILE" ]; then - PID=$(cat "$PID_FILE") - if ps -p "$PID" > /dev/null; then - echo "🛑 자료실 서비스 중지 중... (PID: $PID)" - kill "$PID" - sleep 2 - - # 강제 종료 확인 - if ps -p "$PID" > /dev/null; then - echo "⚡ 강제 종료 중..." - kill -9 "$PID" - fi - - rm -f "$PID_FILE" - echo "✅ 자료실 서비스 중지 완료" - else - echo "⚠️ 프로세스가 이미 종료됨" - rm -f "$PID_FILE" - fi -else - echo "⚠️ PID 파일이 없습니다. 수동으로 프로세스를 확인하세요." - echo "실행 중인 Node.js 프로세스:" - ps aux | grep 'node.*server.js' | grep -v grep -fi -EOF - -# 실행 권한 부여 -chmod +x stop-jaryo.sh -``` - -### 8단계: 서비스 시작 🎬 - -```bash -# 서비스 시작 -./start-jaryo.sh - -# 로그 확인 (별도 터미널에서) -tail -f jaryo.log -``` - -### 9단계: 접속 테스트 🧪 - -**브라우저에서 접속:** -- **메인 페이지**: `http://119.64.1.86:3005` -- **관리자 페이지**: `http://119.64.1.86:3005/admin` - -**명령줄에서 테스트:** -```bash -# 서비스 상태 확인 -curl -s http://119.64.1.86:3005 - -# 프로세스 확인 -ps aux | grep 'node.*server.js' | grep -v grep - -# 포트 확인 -netstat -tulpn | grep :3005 -``` - -## 🔧 서비스 관리 - -### 일상적인 관리 명령어 - -```bash -# 서비스 시작 -/volume1/web/jaryo/start-jaryo.sh - -# 서비스 중지 -/volume1/web/jaryo/stop-jaryo.sh - -# 서비스 재시작 -/volume1/web/jaryo/stop-jaryo.sh && /volume1/web/jaryo/start-jaryo.sh - -# 로그 확인 -tail -f /volume1/web/jaryo/jaryo.log - -# 실시간 로그 보기 -ssh -p 2222 admin@119.64.1.86 'tail -f /volume1/web/jaryo/jaryo.log' -``` - -### 상태 모니터링 - -```bash -# 서비스 상태 스크립트 -cat > status-jaryo.sh << 'EOF' -#!/bin/bash - -PROJECT_DIR="/volume1/web/jaryo" -PID_FILE="$PROJECT_DIR/jaryo.pid" -LOG_FILE="$PROJECT_DIR/jaryo.log" - -echo "=== 자료실 서비스 상태 ===" - -if [ -f "$PID_FILE" ]; then - PID=$(cat "$PID_FILE") - if ps -p "$PID" > /dev/null; then - echo "✅ 서비스 실행 중 (PID: $PID)" - echo "📊 메모리 사용량:" - ps -o pid,ppid,cmd,%mem,%cpu -p "$PID" - echo "" - echo "🌐 포트 상태:" - netstat -tulpn | grep :3005 - else - echo "❌ 서비스 중지됨 (PID 파일 존재하지만 프로세스 없음)" - fi -else - echo "❌ 서비스 중지됨 (PID 파일 없음)" -fi - -echo "" -echo "📄 최근 로그 (최근 5줄):" -if [ -f "$LOG_FILE" ]; then - tail -5 "$LOG_FILE" -else - echo "로그 파일이 없습니다." -fi -EOF - -chmod +x status-jaryo.sh -``` - -## 🔄 자동 시작 설정 (선택사항) - -### DSM 작업 스케줄러 사용 - -1. **DSM 로그인** → **제어판** → **작업 스케줄러** -2. **생성** → **예약된 작업** → **사용자 정의 스크립트** -3. 설정: - - **작업 이름**: Jaryo 자료실 자동 시작 - - **사용자**: root - - **스케줄**: 시스템 부팅 시 - - **스크립트**: `/volume1/web/jaryo/start-jaryo.sh` - -## 🚨 문제 해결 - -### 일반적인 문제들 - -**1. 포트 충돌** -```bash -# 포트 사용 확인 -netstat -tulpn | grep :3005 - -# 다른 포트 사용시 (예: 3006) -PORT=3006 node server.js -``` - -**2. 권한 문제** -```bash -# 디렉토리 권한 수정 -sudo chown -R admin:users /volume1/web/jaryo -chmod -R 755 /volume1/web/jaryo -``` - -**3. Node.js 버전 문제** -```bash -# Node.js 버전 확인 -node --version - -# 최소 요구 버전: v16.0.0 -``` - -**4. 데이터베이스 문제** -```bash -# 데이터베이스 재초기화 -rm -f jaryo.db -npm run init-db -``` - -## 📱 최종 확인 - -배포 완료 후 다음 URL들이 정상 작동하는지 확인: - -- ✅ **메인 페이지**: http://119.64.1.86:3005 -- ✅ **관리자 페이지**: http://119.64.1.86:3005/admin -- ✅ **API 상태**: http://119.64.1.86:3005/api/files -- ✅ **Gitea 저장소**: http://119.64.1.86:3000/vibsin9322/jaryo - -## 🎉 배포 완료! - -시놀로지 NAS에서 자료실 서비스가 성공적으로 실행되고 있습니다. -서비스 관리는 위의 스크립트들을 사용하여 쉽게 할 수 있습니다. \ No newline at end of file diff --git a/nas-git-connection-test.md b/nas-git-connection-test.md deleted file mode 100644 index c231768..0000000 --- a/nas-git-connection-test.md +++ /dev/null @@ -1,257 +0,0 @@ -# 시놀로지 NAS Git 서버 연결 테스트 가이드 - -## 🧪 연결 테스트 단계별 가이드 - -### 1단계: 기본 연결 테스트 - -#### 1.1 SSH 연결 확인 -```bash -# NAS SSH 연결 테스트 -ssh admin@your-nas-ip - -# 성공시 NAS 터미널에 접속됨 -# 실패시 확인사항: -# - SSH 서비스 활성화 여부 -# - 방화벽 설정 -# - IP 주소 정확성 -``` - -#### 1.2 Git 설치 확인 -```bash -# NAS에서 Git 명령어 확인 -which git -git --version - -# Git 서비스 상태 확인 -sudo systemctl status git-daemon -ps aux | grep git -``` - -### 2단계: 저장소 생성 및 설정 - -#### 2.1 자동 스크립트 실행 -```bash -# 로컬에서 NAS로 스크립트 복사 -scp create-git-repo.sh admin@your-nas-ip:/tmp/ - -# NAS에서 스크립트 실행 -ssh admin@your-nas-ip -cd /tmp -chmod +x create-git-repo.sh -./create-git-repo.sh jaryo-file-manager -``` - -#### 2.2 수동 저장소 생성 (스크립트 실패시) -```bash -# NAS에서 직접 실행 -ssh admin@your-nas-ip - -# Git 디렉토리 생성 -sudo mkdir -p /volume1/git -sudo chown admin:users /volume1/git -cd /volume1/git - -# Bare 저장소 생성 -mkdir jaryo-file-manager.git -cd jaryo-file-manager.git -git init --bare -sudo chown -R admin:users . -``` - -### 3단계: 로컬에서 연결 테스트 - -#### 3.1 기존 프로젝트에 원격 저장소 추가 -```bash -# 현재 jaryo 프로젝트 디렉토리에서 -cd /c/Users/COMTREE/claude_code/jaryo - -# NAS Git 원격 저장소 추가 -git remote add nas ssh://admin@your-nas-ip/volume1/git/jaryo-file-manager.git - -# 원격 저장소 확인 -git remote -v -``` - -#### 3.2 첫 번째 Push 테스트 -```bash -# 모든 변경사항 커밋 (필요시) -git add . -git commit -m "Initial commit for NAS deployment" - -# NAS로 푸시 -git push nas master - -# 성공시 출력 예시: -# Enumerating objects: X, done. -# Counting objects: 100% (X/X), done. -# Delta compression using up to Y threads -# Compressing objects: 100% (X/X), done. -# Writing objects: 100% (X/X), X.XX KiB | X.XX MiB/s, done. -# Total X (delta X), reused X (delta X), pack-reused 0 -# To ssh://admin@your-nas-ip/volume1/git/jaryo-file-manager.git -# * [new branch] master -> master -``` - -### 4단계: 클론 테스트 - -#### 4.1 다른 디렉토리에서 클론 테스트 -```bash -# 테스트용 디렉토리 생성 -mkdir /tmp/git-test -cd /tmp/git-test - -# NAS에서 클론 -git clone ssh://admin@your-nas-ip/volume1/git/jaryo-file-manager.git - -# 성공시 프로젝트 파일들이 다운로드됨 -cd jaryo-file-manager -ls -la -``` - -#### 4.2 HTTP 클론 테스트 (Git HTTP 서버 실행시) -```bash -# Git HTTP 서버가 실행 중인 경우 -git clone http://your-nas-ip:3000/jaryo-file-manager.git -``` - -### 5단계: 웹 인터페이스 테스트 - -#### 5.1 GitWeb 접속 테스트 -- 브라우저에서 `http://your-nas-ip/git` 접속 -- 또는 `http://your-nas-ip:3000` 접속 -- 저장소 목록에서 `jaryo-file-manager` 확인 - -#### 5.2 Git HTTP 서버 상태 확인 -```bash -# NAS에서 Git HTTP 서버 실행 확인 -sudo netstat -tulpn | grep :3000 -ps aux | grep git-daemon -``` - -## 🚨 문제 해결 - -### 연결 실패 시 체크리스트 - -#### ❌ "Connection refused" 오류 -```bash -# 1. SSH 서비스 확인 -ssh -v admin@your-nas-ip - -# 2. 포트 확인 (기본: 22) -ssh -p 22 admin@your-nas-ip - -# 3. 방화벽 확인 -# DSM > 제어판 > 보안 > 방화벽 -``` - -#### ❌ "Permission denied" 오류 -```bash -# 1. 사용자 권한 확인 -# DSM > 제어판 > 사용자 및 그룹 > admin > 애플리케이션 - -# 2. SSH 키 설정 (선택사항) -ssh-keygen -t rsa -ssh-copy-id admin@your-nas-ip -``` - -#### ❌ "Repository not found" 오류 -```bash -# 1. 저장소 경로 확인 -ssh admin@your-nas-ip -ls -la /volume1/git/ -ls -la /volume1/git/jaryo-file-manager.git/ - -# 2. 권한 확인 -sudo chown -R admin:users /volume1/git/jaryo-file-manager.git -chmod -R 755 /volume1/git/jaryo-file-manager.git -``` - -#### ❌ Git 명령어 없음 -```bash -# Git 설치 확인 -which git - -# 패키지 센터에서 Git Server 설치 -# 또는 수동 설치: -sudo apt update -sudo apt install git -``` - -### 네트워크 설정 문제 - -#### 내부 네트워크 접속 실패 -```bash -# IP 주소 확인 -ping your-nas-ip -nslookup your-nas-ip - -# 포트 스캔 -nmap -p 22,3000 your-nas-ip -``` - -#### 외부 네트워크 접속 설정 -```bash -# 라우터 포트 포워딩 설정 -# 22 (SSH) -> NAS_IP:22 -# 3000 (Git HTTP) -> NAS_IP:3000 - -# 동적 DNS 설정 (선택사항) -# your-domain.dyndns.org -> your-public-ip -``` - -## 📊 연결 성공 확인 - -### ✅ 성공 지표들 - -1. **SSH 연결**: `ssh admin@your-nas-ip` 성공 -2. **저장소 존재**: `/volume1/git/jaryo-file-manager.git` 확인 -3. **Push 성공**: `git push nas master` 완료 -4. **Clone 성공**: 다른 위치에서 클론 가능 -5. **웹 접속**: 브라우저에서 Git 저장소 확인 - -### 📈 성능 테스트 - -```bash -# 대용량 파일 Push 테스트 -dd if=/dev/zero of=test-large-file.bin bs=1M count=10 -git add test-large-file.bin -git commit -m "Large file test" -time git push nas master - -# 클론 속도 테스트 -time git clone ssh://admin@your-nas-ip/volume1/git/jaryo-file-manager.git test-clone -``` - -## 🔧 고급 설정 - -### Git Hooks 활용 -```bash -# NAS에서 post-receive hook 설정 -ssh admin@your-nas-ip -cd /volume1/git/jaryo-file-manager.git/hooks - -# 자동 배포 hook -cat > post-receive << 'EOF' -#!/bin/bash -echo "코드 푸시 완료: $(date)" -# 자동 배포 로직 추가 가능 -# cd /volume1/web/jaryo && git pull -EOF - -chmod +x post-receive -``` - -### 백업 설정 -```bash -# 저장소 백업 스크립트 -#!/bin/bash -BACKUP_DIR="/volume1/backup/git" -REPO_DIR="/volume1/git" -DATE=$(date +%Y%m%d_%H%M%S) - -mkdir -p "$BACKUP_DIR" -tar -czf "$BACKUP_DIR/git-repos-$DATE.tar.gz" -C "$REPO_DIR" . -echo "백업 완료: $BACKUP_DIR/git-repos-$DATE.tar.gz" -``` - -이 가이드를 따라하면 시놀로지 NAS Git 서버와의 연결을 성공적으로 테스트하고 설정할 수 있습니다. \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index fcf1fa0..de23ebd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,26 +1,116 @@ { "name": "jaryo-file-manager", - "version": "1.0.0", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "jaryo-file-manager", - "version": "1.0.0", + "version": "2.0.0", "license": "MIT", "dependencies": { "bcrypt": "^5.1.1", "cors": "^2.8.5", "express": "^4.18.2", "express-session": "^1.17.3", - "fs": "^0.0.1-security", "multer": "^1.4.5-lts.1", - "path": "^0.12.7", "sqlite3": "^5.1.6", "uuid": "^9.0.1" }, "devDependencies": { - "nodemon": "^3.0.1" + "vercel": "^32.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@edge-runtime/cookies": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@edge-runtime/cookies/-/cookies-3.4.1.tgz", + "integrity": "sha512-z27BvgPxI73CgSlxU/NAUf1Q/shnqi6cobHEowf6VuLdSjGR3NjI2Y5dZUIBbK2zOJVZbXcHsVzJjz8LklteFQ==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=16" + } + }, + "node_modules/@edge-runtime/format": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@edge-runtime/format/-/format-2.2.0.tgz", + "integrity": "sha512-gPrS6AVw/qJJL0vcxMXv4kFXCU3ZTCD1uuJpwX15YxHV8BgU9OG5v9LrkkXcr96PBT/9epypfNJMhlWADuEziw==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=16" + } + }, + "node_modules/@edge-runtime/node-utils": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@edge-runtime/node-utils/-/node-utils-2.2.1.tgz", + "integrity": "sha512-RUl/439BHKshkhSGFRlZ1kzy68wL4mn8VNKDSZr3p0tciyZ33Mjfpl+vofqnHqXRmDI6nLnZpfJvhY3D88o0pA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@edge-runtime/cookies": "3.4.1" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@edge-runtime/ponyfill": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@edge-runtime/ponyfill/-/ponyfill-2.4.1.tgz", + "integrity": "sha512-ZbR/EViY3gg2rmEAQTKPa6mXl4aR1/+cFcQe4r1segCjEbTAxT6PWu40odbu/KlZKSysEb2O/BWIC2lJgSJOMQ==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=16" + } + }, + "node_modules/@edge-runtime/primitives": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@edge-runtime/primitives/-/primitives-4.0.5.tgz", + "integrity": "sha512-t7QiN5d/KpXgCvIfSt6Nm9Hj3WVdNgc5CpOD73jasY+9EvTI7Ngdj5cXvjcHrPcmYWJZMySPgeEeoL/1N/Llag==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=16" + } + }, + "node_modules/@edge-runtime/vm": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@edge-runtime/vm/-/vm-3.1.7.tgz", + "integrity": "sha512-hUMFbDQ/nZN+1TLMi6iMO1QFz9RSV8yGG8S42WFPFma1d7VSNE0eMdJUmwjmtav22/iQkzHMmu6oTSfAvRGS8g==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@edge-runtime/primitives": "4.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" } }, "node_modules/@gar/promisify": { @@ -30,6 +120,34 @@ "license": "MIT", "optional": true }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@mapbox/node-pre-gyp": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", @@ -112,6 +230,44 @@ "node": ">= 6" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@npmcli/fs": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", @@ -151,6 +307,27 @@ "node": ">=10" } }, + "node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -161,6 +338,559 @@ "node": ">= 6" } }, + "node_modules/@ts-morph/common": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.11.1.tgz", + "integrity": "sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "^3.2.7", + "minimatch": "^3.0.4", + "mkdirp": "^1.0.4", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@ts-morph/common/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "14.18.33", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.33.tgz", + "integrity": "sha512-qelS/Ra6sacc4loe/3MSjXNL1dNQ/GjxNHVzuChwMfmk7HuycRLVQN2qNY3XahK+fZc5E2szqQSKUyAF0E+2bg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vercel/build-utils": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@vercel/build-utils/-/build-utils-7.3.0.tgz", + "integrity": "sha512-RJwqrGYSk75auHZqWmlSL+a5JsWv+4SF1AxNQJ+KpF3XWZ/8yThkN/jHBfNxMmW6VvNczSVtMaXI0/2Sess6Eg==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@vercel/error-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vercel/error-utils/-/error-utils-2.0.2.tgz", + "integrity": "sha512-Sj0LFafGpYr6pfCqrQ82X6ukRl5qpmVrHM/191kNYFqkkB9YkjlMAj6QcEsvCG259x4QZ7Tya++0AB85NDPbKQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@vercel/fun": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@vercel/fun/-/fun-1.1.0.tgz", + "integrity": "sha512-SpuPAo+MlAYMtcMcC0plx7Tv4Mp7SQhJJj1iIENlOnABL24kxHpL09XLQMGzZIzIW7upR8c3edwgfpRtp+dhVw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@tootallnate/once": "2.0.0", + "async-listen": "1.2.0", + "debug": "4.1.1", + "execa": "3.2.0", + "fs-extra": "8.1.0", + "generic-pool": "3.4.2", + "micro": "9.3.5-canary.3", + "ms": "2.1.1", + "node-fetch": "2.6.7", + "path-match": "1.2.4", + "promisepipe": "3.0.0", + "semver": "7.3.5", + "stat-mode": "0.3.0", + "stream-to-promise": "2.2.0", + "tar": "4.4.18", + "tree-kill": "1.2.2", + "uid-promise": "1.0.0", + "uuid": "3.3.2", + "xdg-app-paths": "5.1.0", + "yauzl-promise": "2.1.3" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@vercel/fun/node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@vercel/fun/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true, + "license": "ISC" + }, + "node_modules/@vercel/fun/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@vercel/fun/node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/@vercel/fun/node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "license": "ISC", + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/@vercel/fun/node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/@vercel/fun/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vercel/fun/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@vercel/fun/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@vercel/fun/node_modules/tar": { + "version": "4.4.18", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.18.tgz", + "integrity": "sha512-ZuOtqqmkV9RE1+4odd+MhBpibmCxNP6PJhH/h2OqNuotTX7/XHPZQJv2pKvWMplFH9SIZZhitehh6vBH6LO8Pg==", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/@vercel/fun/node_modules/uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/@vercel/fun/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@vercel/gatsby-plugin-vercel-analytics": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@vercel/gatsby-plugin-vercel-analytics/-/gatsby-plugin-vercel-analytics-1.0.11.tgz", + "integrity": "sha512-iTEA0vY6RBPuEzkwUTVzSHDATo1aF6bdLLspI68mQ/BTbi5UQEGjpjyzdKOVcSYApDtFU6M6vypZ1t4vIEnHvw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "web-vitals": "0.2.4" + } + }, + "node_modules/@vercel/gatsby-plugin-vercel-builder": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@vercel/gatsby-plugin-vercel-builder/-/gatsby-plugin-vercel-builder-2.0.12.tgz", + "integrity": "sha512-S1RkywrUItewqg06T3L4cgYfiwi2BFngHIIerhOYhVuD9A+yfMgxnH5dkbu6nujmV1SEws+Q92wSiPfLPmO0eA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "0.25.24", + "@vercel/build-utils": "7.3.0", + "@vercel/routing-utils": "3.1.0", + "esbuild": "0.14.47", + "etag": "1.8.1", + "fs-extra": "11.1.0" + } + }, + "node_modules/@vercel/gatsby-plugin-vercel-builder/node_modules/fs-extra": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz", + "integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@vercel/gatsby-plugin-vercel-builder/node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@vercel/gatsby-plugin-vercel-builder/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@vercel/go": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@vercel/go/-/go-3.0.4.tgz", + "integrity": "sha512-hMIJm2xwU1HT56YRNF8HNOnIFNH7WnGl1l2D6lc6UJk7XdCCh1Dm0nsqLqki2SprTUh3I+53pTQaqgRsFGf06A==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@vercel/hydrogen": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@vercel/hydrogen/-/hydrogen-1.0.1.tgz", + "integrity": "sha512-4PYk4LeIWPTjGtgnxvB0Hdw7aqCau843/96K2xX3z9pa0Hn//pUnZBMz2jrs5MRseCm1Li1LdQAK3u8/vaUnVQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@vercel/static-config": "3.0.0", + "ts-morph": "12.0.0" + } + }, + "node_modules/@vercel/next": { + "version": "4.0.15", + "resolved": "https://registry.npmjs.org/@vercel/next/-/next-4.0.15.tgz", + "integrity": "sha512-BxMxIJrya7MS6IWrQIaQaYHPmq7WoZFLX909RBpNoAG5wgzrTrW756d2EsibBwGo7sQYBv2atyI5GqBIHzYbWg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@vercel/nft": "0.24.2" + } + }, + "node_modules/@vercel/nft": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.24.2.tgz", + "integrity": "sha512-KhY3Ky/lCqE+fHpOXiKOLnXYJ49PZh1dyDSfVtZhmYtmica0NQgyO6kPOAGDNWqD9IOBx8hb65upxxjfnfa1JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.5", + "@rollup/pluginutils": "^4.0.0", + "acorn": "^8.6.0", + "async-sema": "^3.1.1", + "bindings": "^1.4.0", + "estree-walker": "2.0.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.2", + "node-gyp-build": "^4.2.2", + "resolve-from": "^5.0.0" + }, + "bin": { + "nft": "out/cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@vercel/node": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@vercel/node/-/node-3.0.12.tgz", + "integrity": "sha512-OiNHiUe1LX/CfDrQ07ntPsoYhJiC38mEeErYeqA6YNVAz3QGdX3pthiaIig2KPqeeYkEx5bSkVIqQtQOTJBuLQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@edge-runtime/node-utils": "2.2.1", + "@edge-runtime/primitives": "4.0.5", + "@edge-runtime/vm": "3.1.7", + "@types/node": "14.18.33", + "@vercel/build-utils": "7.3.0", + "@vercel/error-utils": "2.0.2", + "@vercel/nft": "0.24.2", + "@vercel/static-config": "3.0.0", + "async-listen": "3.0.0", + "edge-runtime": "2.5.7", + "esbuild": "0.14.47", + "etag": "1.8.1", + "exit-hook": "2.2.1", + "node-fetch": "2.6.9", + "path-to-regexp": "6.2.1", + "ts-morph": "12.0.0", + "ts-node": "10.9.1", + "typescript": "4.9.5", + "undici": "5.26.5" + } + }, + "node_modules/@vercel/node/node_modules/async-listen": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/async-listen/-/async-listen-3.0.0.tgz", + "integrity": "sha512-V+SsTpDqkrWTimiotsyl33ePSjA5/KrithwupuvJ6ztsqPvGv6ge4OredFhPffVXiLN/QUWvE0XcqJaYgt6fOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/@vercel/node/node_modules/node-fetch": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@vercel/node/node_modules/path-to-regexp": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vercel/python": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vercel/python/-/python-4.1.0.tgz", + "integrity": "sha512-EIQXK5zL6fce0Barh74gc7xyLtRyvgmLZDIVQ8yJLtFxPlPCRY3GXkdJ7Jdcw8Pd0uuVF0vIHatv18xSLbcwtg==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@vercel/redwood": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vercel/redwood/-/redwood-2.0.5.tgz", + "integrity": "sha512-9iWTxfMkC7yNnwN2xxOdptiIDAgXe1V1fh3aw92MWt5PBRcFY9RqgIPF7Q3Qa7yzQFgpbHwCnSTqWO+HCEuFtw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@vercel/nft": "0.24.2", + "@vercel/routing-utils": "3.1.0", + "semver": "6.3.1" + } + }, + "node_modules/@vercel/redwood/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@vercel/remix-builder": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@vercel/remix-builder/-/remix-builder-2.0.14.tgz", + "integrity": "sha512-c+ILERSRq404sf6kt0qWhYhuxWkkoTEm2FdLoUnVs21K6kzGtJMJbUExEHoPZvN9a0tq86ZU86jVvRZV6WL0cQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@vercel/nft": "0.24.2", + "@vercel/static-config": "3.0.0", + "ts-morph": "12.0.0" + } + }, + "node_modules/@vercel/routing-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@vercel/routing-utils/-/routing-utils-3.1.0.tgz", + "integrity": "sha512-Ci5xTjVTJY/JLZXpCXpLehMft97i9fH34nu9PGav6DtwkVUF6TOPX86U0W0niQjMZ5n6/ZP0BwcJK2LOozKaGw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "path-to-regexp": "6.1.0" + }, + "optionalDependencies": { + "ajv": "^6.0.0" + } + }, + "node_modules/@vercel/routing-utils/node_modules/path-to-regexp": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.1.0.tgz", + "integrity": "sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vercel/ruby": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@vercel/ruby/-/ruby-2.0.4.tgz", + "integrity": "sha512-EpZyfF6wFGzFDmubFIh/EZtYpKindmXx/69xSfKEBTVU0afgljyOOICbyZePe5tvigfOEBLSLgrt/2nN+MlLtA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@vercel/static-build": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@vercel/static-build/-/static-build-2.0.14.tgz", + "integrity": "sha512-l5eQtJbk5Pc+P8XARDnpcbX4LnK3bGy7uf6S1aFOD4h6F8iBdg0agWTufZnq5BI91pcPVICPazM5BYhigIEznQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@vercel/gatsby-plugin-vercel-analytics": "1.0.11", + "@vercel/gatsby-plugin-vercel-builder": "2.0.12", + "@vercel/static-config": "3.0.0", + "ts-morph": "12.0.0" + } + }, + "node_modules/@vercel/static-config": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@vercel/static-config/-/static-config-3.0.0.tgz", + "integrity": "sha512-2qtvcBJ1bGY0dYGYh3iM7yGKkk971FujLEDXzuW5wcZsPr1GSEjO/w2iSr3qve6nDDtBImsGoDEnus5FI4+fIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "ajv": "8.6.3", + "json-schema-to-ts": "1.6.4", + "ts-morph": "12.0.0" + } + }, + "node_modules/@vercel/static-config/node_modules/ajv": { + "version": "8.6.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", + "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@vercel/static-config/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -180,6 +910,32 @@ "node": ">= 0.6" } }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -242,6 +998,24 @@ "node": ">=8" } }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -251,6 +1025,13 @@ "node": ">=8" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -307,12 +1088,33 @@ "node": ">= 6" } }, + "node_modules/arg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", + "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==", + "dev": true, + "license": "MIT" + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "license": "MIT" }, + "node_modules/async-listen": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/async-listen/-/async-listen-1.2.0.tgz", + "integrity": "sha512-CcEtRh/oc9Jc4uWeUwdpG/+Mb2YUHKmdaTf0gUr7Wa+bfp4xx70HOb3RuSTJMvqKNB1TkdTfjLdrcz2X4rkkZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-sema": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/async-sema/-/async-sema-3.1.1.tgz", + "integrity": "sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==", + "dev": true, + "license": "MIT" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -477,6 +1279,16 @@ "ieee754": "^1.1.13" } }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -575,31 +1387,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "node_modules/chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -619,6 +1406,13 @@ "node": ">=6" } }, + "node_modules/code-block-writer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-10.1.1.tgz", + "integrity": "sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==", + "dev": true, + "license": "MIT" + }, "node_modules/color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", @@ -676,6 +1470,16 @@ "node": ">= 0.6" } }, + "node_modules/convert-hrtime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-3.0.0.tgz", + "integrity": "sha512-7V+KqSvMiHp8yWDuwfww06XleMWVVB9b9tURBx+G7UTADuo5hYPuowKloz4OzOqbPezxgo+fdQ1522WzPG4OeA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/cookie": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", @@ -710,6 +1514,28 @@ "node": ">= 0.10" } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -777,6 +1603,16 @@ "node": ">=8" } }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -791,6 +1627,53 @@ "node": ">= 0.4" } }, + "node_modules/edge-runtime": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/edge-runtime/-/edge-runtime-2.5.7.tgz", + "integrity": "sha512-gA4qSVP0sNwJlkdQ2nahDPASlSl8twUd17o+JolPa1EtXpLTGzIpOETvodgJwXIxa+zaD8bnAXCdsWrx2PhlVQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@edge-runtime/format": "2.2.0", + "@edge-runtime/ponyfill": "2.4.1", + "@edge-runtime/vm": "3.1.7", + "async-listen": "3.0.1", + "mri": "1.2.0", + "picocolors": "1.0.0", + "pretty-ms": "7.0.1", + "signal-exit": "4.0.2", + "time-span": "4.0.0" + }, + "bin": { + "edge-runtime": "dist/cli/index.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/edge-runtime/node_modules/async-listen": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/async-listen/-/async-listen-3.0.1.tgz", + "integrity": "sha512-cWMaNwUJnf37C/S5TfCkk/15MwbPRwVYALA2jtjkbHjCmAPiDXyNJy2q3p1KAZzDLHAWyarUWSujUoHR4pEgrA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/edge-runtime/node_modules/signal-exit": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", + "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -891,12 +1774,395 @@ "node": ">= 0.4" } }, + "node_modules/esbuild": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.47.tgz", + "integrity": "sha512-wI4ZiIfFxpkuxB8ju4MHrGwGLyp1+awEHAHVpx6w7a+1pmYIq8T9FGEVVwFo0iFierDoMj++Xq69GXWYn2EiwA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "esbuild-android-64": "0.14.47", + "esbuild-android-arm64": "0.14.47", + "esbuild-darwin-64": "0.14.47", + "esbuild-darwin-arm64": "0.14.47", + "esbuild-freebsd-64": "0.14.47", + "esbuild-freebsd-arm64": "0.14.47", + "esbuild-linux-32": "0.14.47", + "esbuild-linux-64": "0.14.47", + "esbuild-linux-arm": "0.14.47", + "esbuild-linux-arm64": "0.14.47", + "esbuild-linux-mips64le": "0.14.47", + "esbuild-linux-ppc64le": "0.14.47", + "esbuild-linux-riscv64": "0.14.47", + "esbuild-linux-s390x": "0.14.47", + "esbuild-netbsd-64": "0.14.47", + "esbuild-openbsd-64": "0.14.47", + "esbuild-sunos-64": "0.14.47", + "esbuild-windows-32": "0.14.47", + "esbuild-windows-64": "0.14.47", + "esbuild-windows-arm64": "0.14.47" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.47.tgz", + "integrity": "sha512-R13Bd9+tqLVFndncMHssZrPWe6/0Kpv2/dt4aA69soX4PRxlzsVpCvoJeFE8sOEoeVEiBkI0myjlkDodXlHa0g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.47.tgz", + "integrity": "sha512-OkwOjj7ts4lBp/TL6hdd8HftIzOy/pdtbrNA4+0oVWgGG64HrdVzAF5gxtJufAPOsEjkyh1oIYvKAUinKKQRSQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.47.tgz", + "integrity": "sha512-R6oaW0y5/u6Eccti/TS6c/2c1xYTb1izwK3gajJwi4vIfNs1s8B1dQzI1UiC9T61YovOQVuePDcfqHLT3mUZJA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.47.tgz", + "integrity": "sha512-seCmearlQyvdvM/noz1L9+qblC5vcBrhUaOoLEDDoLInF/VQ9IkobGiLlyTPYP5dW1YD4LXhtBgOyevoIHGGnw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.47.tgz", + "integrity": "sha512-ZH8K2Q8/Ux5kXXvQMDsJcxvkIwut69KVrYQhza/ptkW50DC089bCVrJZZ3sKzIoOx+YPTrmsZvqeZERjyYrlvQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.47.tgz", + "integrity": "sha512-ZJMQAJQsIOhn3XTm7MPQfCzEu5b9STNC+s90zMWe2afy9EwnHV7Ov7ohEMv2lyWlc2pjqLW8QJnz2r0KZmeAEQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.47.tgz", + "integrity": "sha512-FxZOCKoEDPRYvq300lsWCTv1kcHgiiZfNrPtEhFAiqD7QZaXrad8LxyJ8fXGcWzIFzRiYZVtB3ttvITBvAFhKw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.47.tgz", + "integrity": "sha512-nFNOk9vWVfvWYF9YNYksZptgQAdstnDCMtR6m42l5Wfugbzu11VpMCY9XrD4yFxvPo9zmzcoUL/88y0lfJZJJw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.47.tgz", + "integrity": "sha512-ZGE1Bqg/gPRXrBpgpvH81tQHpiaGxa8c9Rx/XOylkIl2ypLuOcawXEAo8ls+5DFCcRGt/o3sV+PzpAFZobOsmA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.47.tgz", + "integrity": "sha512-ywfme6HVrhWcevzmsufjd4iT3PxTfCX9HOdxA7Hd+/ZM23Y9nXeb+vG6AyA6jgq/JovkcqRHcL9XwRNpWG6XRw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.47.tgz", + "integrity": "sha512-mg3D8YndZ1LvUiEdDYR3OsmeyAew4MA/dvaEJxvyygahWmpv1SlEEnhEZlhPokjsUMfRagzsEF/d/2XF+kTQGg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.47.tgz", + "integrity": "sha512-WER+f3+szmnZiWoK6AsrTKGoJoErG2LlauSmk73LEZFQ/iWC+KhhDsOkn1xBUpzXWsxN9THmQFltLoaFEH8F8w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.47.tgz", + "integrity": "sha512-1fI6bP3A3rvI9BsaaXbMoaOjLE3lVkJtLxsgLHqlBhLlBVY7UqffWBvkrX/9zfPhhVMd9ZRFiaqXnB1T7BsL2g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.47.tgz", + "integrity": "sha512-eZrWzy0xFAhki1CWRGnhsHVz7IlSKX6yT2tj2Eg8lhAwlRE5E96Hsb0M1mPSE1dHGpt1QVwwVivXIAacF/G6mw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.47.tgz", + "integrity": "sha512-Qjdjr+KQQVH5Q2Q1r6HBYswFTToPpss3gqCiSw2Fpq/ua8+eXSQyAMG+UvULPqXceOwpnPo4smyZyHdlkcPppQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.47.tgz", + "integrity": "sha512-QpgN8ofL7B9z8g5zZqJE+eFvD1LehRlxr25PBkjyyasakm4599iroUpaj96rdqRlO2ShuyqwJdr+oNqWwTUmQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.47.tgz", + "integrity": "sha512-uOeSgLUwukLioAJOiGYm3kNl+1wJjgJA8R671GYgcPgCx7QR73zfvYqXFFcIO93/nBdIbt5hd8RItqbbf3HtAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.47.tgz", + "integrity": "sha512-H0fWsLTp2WBfKLBgwYT4OTfFly4Im/8B5f3ojDv1Kx//kiubVY0IQunP2Koc/fr/0wI7hj3IiBDbSrmKlrNgLQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.47.tgz", + "integrity": "sha512-/Pk5jIEH34T68r8PweKRi77W49KwanZ8X6lr3vDAtOlH5EumPE4pBHqkCUdELanvsT14yMXLQ/C/8XPi1pAtkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.14.47", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.47.tgz", + "integrity": "sha512-HFSW2lnp62fl86/qPQlqw6asIwCnEsEoNIL1h2uVMgakddf+vUuMcCbtUY1i8sst7KkgHrVKCJQB33YhhOweCQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -906,6 +2172,48 @@ "node": ">= 0.6" } }, + "node_modules/events-intercept": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/events-intercept/-/events-intercept-2.0.0.tgz", + "integrity": "sha512-blk1va0zol9QOrdZt0rFXo5KMkNPVSp92Eju/Qz8THwKWKRKeE0T8Br/1aW6+Edkyq9xHYgYxn2QtOnUKPUp+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/execa": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-3.2.0.tgz", + "integrity": "sha512-kJJfVbI/lZE1PZYDI5VPxp8zXPO9rtxOkhpZ0jMKha56AI9y2gGVC6bkukStQf0ka5Rh15BA5m7cCCH4jmHqkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": "^8.12.0 || >=9.7.0" + } + }, + "node_modules/exit-hook": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-2.2.1.tgz", + "integrity": "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", @@ -995,6 +2303,58 @@ "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", "license": "MIT" }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "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.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, "node_modules/file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", @@ -1050,18 +2410,27 @@ "node": ">= 0.6" } }, - "node_modules/fs": { - "version": "0.0.1-security", - "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", - "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==", - "license": "ISC" - }, "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "license": "MIT" }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -1080,21 +2449,6 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "license": "ISC" }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -1125,6 +2479,16 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/generic-pool": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.4.2.tgz", + "integrity": "sha512-H7cUpwCQSiJmAHM4c/aFu6fUfrhWXW1ncyh8ftxEPMu6AiYkHw9K8br720TGPZJbk5eOH2bynjZD1yPvdDAmag==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -1162,6 +2526,22 @@ "node": ">= 0.4" } }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", @@ -1218,18 +2598,8 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC", - "optional": true - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } + "devOptional": true, + "license": "ISC" }, "node_modules/has-symbols": { "version": "1.1.0", @@ -1360,6 +2730,16 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8.12.0" + } + }, "node_modules/humanize-ms": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", @@ -1402,13 +2782,6 @@ ], "license": "BSD-3-Clause" }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", - "dev": true, - "license": "ISC" - }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -1540,6 +2913,19 @@ "node": ">=0.12.0" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -1550,15 +2936,44 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC", + "devOptional": true, + "license": "ISC" + }, + "node_modules/json-schema-to-ts": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-1.6.4.tgz", + "integrity": "sha512-pR4yQ9DHz6itqswtHCm26mw45FSNfQ9rEQjosaZErhn5J3J2sIViQiz8rDaezjKAhFGpmsoczYVBgGHzFw/stA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.6", + "ts-toolbelt": "^6.15.5" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT", "optional": true }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "devOptional": true, "license": "ISC", - "optional": true, "dependencies": { "yallist": "^4.0.0" }, @@ -1590,6 +3005,13 @@ "semver": "bin/semver.js" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, "node_modules/make-fetch-happen": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", @@ -1645,6 +3067,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -1654,6 +3093,128 @@ "node": ">= 0.6" } }, + "node_modules/micro": { + "version": "9.3.5-canary.3", + "resolved": "https://registry.npmjs.org/micro/-/micro-9.3.5-canary.3.tgz", + "integrity": "sha512-viYIo9PefV+w9dvoIBh1gI44Mvx1BOk67B4BpC2QK77qdY0xZF0Q+vWLt/BII6cLkIc8rLmSIcJaB/OrXXKe1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "arg": "4.1.0", + "content-type": "1.0.4", + "raw-body": "2.4.1" + }, + "bin": { + "micro": "bin/micro.js" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/micro/node_modules/bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/micro/node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micro/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micro/node_modules/http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micro/node_modules/raw-body": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", + "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.3", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/micro/node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true, + "license": "ISC" + }, + "node_modules/micro/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micro/node_modules/toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -1687,6 +3248,16 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/mimic-response": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", @@ -1833,6 +3404,16 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "license": "MIT" }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -1936,60 +3517,18 @@ "node": ">= 10.12.0" } }, - "node_modules/nodemon": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.10.tgz", - "integrity": "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==", + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", "dev": true, "license": "MIT", - "dependencies": { - "chokidar": "^3.5.2", - "debug": "^4", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^7.5.3", - "simple-update-notifier": "^2.0.0", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" } }, - "node_modules/nodemon/node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/nodemon/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, "node_modules/nopt": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", @@ -2015,6 +3554,19 @@ "node": ">=0.10.0" } }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/npmlog": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", @@ -2083,6 +3635,42 @@ "wrappy": "1" } }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-paths": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/os-paths/-/os-paths-4.4.0.tgz", + "integrity": "sha512-wrAwOeXp1RRMFfQY8Sy7VaGVmPocaLwSFOYCGKSyo8qmJ+/yaafCl5BCA1IQZWqFSRBrKDYFeR9d/VyQzfH/jg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0" + } + }, + "node_modules/p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/p-map": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", @@ -2099,6 +3687,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -2108,15 +3706,12 @@ "node": ">= 0.8" } }, - "node_modules/path": { - "version": "0.12.7", - "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", - "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==", - "license": "MIT", - "dependencies": { - "process": "^0.11.1", - "util": "^0.10.3" - } + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" }, "node_modules/path-is-absolute": { "version": "1.0.1", @@ -2127,12 +3722,96 @@ "node": ">=0.10.0" } }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-match": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/path-match/-/path-match-1.2.4.tgz", + "integrity": "sha512-UWlehEdqu36jmh4h5CWJ7tARp1OEVKGHKm6+dg9qMq5RKUTV5WJrGgaZ3dN2m7WFAXDbjlHzvJvL/IUpy84Ktw==", + "deprecated": "This package is archived and no longer maintained. For support, visit https://github.com/expressjs/express/discussions", + "dev": true, + "license": "MIT", + "dependencies": { + "http-errors": "~1.4.0", + "path-to-regexp": "^1.0.0" + } + }, + "node_modules/path-match/node_modules/http-errors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.4.0.tgz", + "integrity": "sha512-oLjPqve1tuOl5aRhv8GK5eHpqP1C9fb+Ol+XTLjKfLltE44zdDbEdjPSbU7Ch5rSNsVFqZn97SrMmZLdu1/YMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "2.0.1", + "statuses": ">= 1.2.1 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/path-match/node_modules/inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==", + "dev": true, + "license": "ISC" + }, + "node_modules/path-match/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-match/node_modules/path-to-regexp": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-match/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/path-to-regexp": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "license": "MIT" }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true, + "license": "ISC" + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -2172,13 +3851,20 @@ "node": ">=10" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "node_modules/pretty-ms": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", + "dev": true, "license": "MIT", + "dependencies": { + "parse-ms": "^2.1.0" + }, "engines": { - "node": ">= 0.6.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/process-nextick-args": { @@ -2208,6 +3894,13 @@ "node": ">=10" } }, + "node_modules/promisepipe": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/promisepipe/-/promisepipe-3.0.0.tgz", + "integrity": "sha512-V6TbZDJ/ZswevgkDNpGt/YqNCiZP9ASfgU+p83uJE6NrGtvSGoOcHLiDCqkMs2+yg7F5qHdLV8d0aS8O26G/KA==", + "dev": true, + "license": "MIT" + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -2221,13 +3914,6 @@ "node": ">= 0.10" } }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true, - "license": "MIT" - }, "node_modules/pump": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", @@ -2238,6 +3924,16 @@ "once": "^1.3.1" } }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", @@ -2253,6 +3949,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/random-bytes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", @@ -2322,17 +4039,24 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, "engines": { - "node": ">=8.10.0" + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, "node_modules/retry": { @@ -2345,6 +4069,17 @@ "node": ">= 4" } }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -2361,6 +4096,30 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2465,6 +4224,29 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", @@ -2588,19 +4370,6 @@ "simple-concat": "^1.0.0" } }, - "node_modules/simple-update-notifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -2704,6 +4473,13 @@ "node": ">= 8" } }, + "node_modules/stat-mode": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-0.3.0.tgz", + "integrity": "sha512-QjMLR0A3WwFY2aZdV0okfFEJB5TRjkggXZjxP3A1RsWsNHNu3YPv8btmtc6iCFZ0Rul3FE93OYogvhOUClU+ng==", + "dev": true, + "license": "MIT" + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -2713,6 +4489,48 @@ "node": ">= 0.8" } }, + "node_modules/stream-to-array": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz", + "integrity": "sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.1.0" + } + }, + "node_modules/stream-to-promise": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stream-to-promise/-/stream-to-promise-2.2.0.tgz", + "integrity": "sha512-HAGUASw8NT0k8JvIVutB2Y/9iBk7gpgEyAudXwNJmZERdMITGdajOa4VJfD/kNiA3TppQpTP4J+CtcHwdzKBAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "~1.3.0", + "end-of-stream": "~1.1.0", + "stream-to-array": "~2.3.0" + } + }, + "node_modules/stream-to-promise/node_modules/end-of-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz", + "integrity": "sha512-EoulkdKF/1xa92q25PbjuDcgJ9RDHYU2Rs3SCIvs2/dSQ3BpmxneNHmA/M7fe60M3PrV7nNGTTNbkK62l6vXiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "~1.3.0" + } + }, + "node_modules/stream-to-promise/node_modules/once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha512-6vaNInhu+CHxtONf3zw3vq4SP2DOQhjBvIa3rNcG0+P7eKWlYH6Peu7rHizSloRU2EwMz6GraLieis9Ac9+p1w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -2762,6 +4580,16 @@ "node": ">=8" } }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -2771,19 +4599,6 @@ "node": ">=0.10.0" } }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/tar": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", @@ -2870,6 +4685,22 @@ "node": ">=10" } }, + "node_modules/time-span": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/time-span/-/time-span-4.0.0.tgz", + "integrity": "sha512-MyqZCTGLDZ77u4k+jqg4UlrzPTPZ49NDlaekU6uuFaJLzPIN1woaRXCbGeqOfxwc3Y37ZROGAJ614Rdv7Olt+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "convert-hrtime": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -2892,22 +4723,84 @@ "node": ">=0.6" } }, - "node_modules/touch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", - "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", - "dev": true, - "license": "ISC", - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-morph": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-12.0.0.tgz", + "integrity": "sha512-VHC8XgU2fFW7yO1f/b3mxKDje1vmyzFXHWzOYmKEkCEwcLjDtbdLgBQviqj4ZwP4MJkQtRo6Ha2I29lq/B+VxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ts-morph/common": "~0.11.0", + "code-block-writer": "^10.1.1" + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-toolbelt": { + "version": "6.15.5", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz", + "integrity": "sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -2939,6 +4832,27 @@ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "license": "MIT" }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/uid-promise": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/uid-promise/-/uid-promise-1.0.0.tgz", + "integrity": "sha512-R8375j0qwXyIu/7R0tjdF06/sElHqbmdmWC9M2qQHpEVbvE4I5+38KJI7LUUmQMp7NVq4tKHiBMkT0NFM453Ig==", + "dev": true, + "license": "MIT" + }, "node_modules/uid-safe": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", @@ -2951,12 +4865,18 @@ "node": ">= 0.8" } }, - "node_modules/undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "node_modules/undici": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.5.tgz", + "integrity": "sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } }, "node_modules/unique-filename": { "version": "1.1.1", @@ -2978,6 +4898,16 @@ "imurmurhash": "^0.1.4" } }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -2987,13 +4917,14 @@ "node": ">= 0.8" } }, - "node_modules/util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "license": "MIT", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "inherits": "2.0.3" + "punycode": "^2.1.0" } }, "node_modules/util-deprecate": { @@ -3002,12 +4933,6 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, - "node_modules/util/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "license": "ISC" - }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -3030,6 +4955,13 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -3039,6 +4971,91 @@ "node": ">= 0.8" } }, + "node_modules/vercel": { + "version": "32.7.2", + "resolved": "https://registry.npmjs.org/vercel/-/vercel-32.7.2.tgz", + "integrity": "sha512-esyeo67OZ/f7usKFCrx6NSjsvpo/BP/C8Mfron2uiCb4vXVcjkwOM7TwliHx6b0DbXjpzomdGVUHKRs34VNn2Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@vercel/build-utils": "7.3.0", + "@vercel/fun": "1.1.0", + "@vercel/go": "3.0.4", + "@vercel/hydrogen": "1.0.1", + "@vercel/next": "4.0.15", + "@vercel/node": "3.0.12", + "@vercel/python": "4.1.0", + "@vercel/redwood": "2.0.5", + "@vercel/remix-builder": "2.0.14", + "@vercel/ruby": "2.0.4", + "@vercel/static-build": "2.0.14", + "chokidar": "3.3.1" + }, + "bin": { + "vc": "dist/index.js", + "vercel": "dist/index.js" + }, + "engines": { + "node": ">= 16" + } + }, + "node_modules/vercel/node_modules/chokidar": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", + "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.3.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.1.2" + } + }, + "node_modules/vercel/node_modules/fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/vercel/node_modules/readdirp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", + "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.0.7" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/web-vitals": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-0.2.4.tgz", + "integrity": "sha512-6BjspCO9VriYy12z356nL6JBS0GYeEcA457YyRzD+dD6XYCQ75NKhcOHUMHentOE7OcVCIXXDvOm0jKFfQG2Gg==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -3059,8 +5076,8 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "devOptional": true, "license": "ISC", - "optional": true, "dependencies": { "isexe": "^2.0.0" }, @@ -3086,6 +5103,32 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, + "node_modules/xdg-app-paths": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-app-paths/-/xdg-app-paths-5.1.0.tgz", + "integrity": "sha512-RAQ3WkPf4KTU1A8RtFx3gWywzVKe00tfOPFfl2NDGqbIFENQO4kqAJp7mhQjNj/33W5x5hiWWUdyfPq/5SU3QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xdg-portable": "^7.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/xdg-portable": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/xdg-portable/-/xdg-portable-7.3.0.tgz", + "integrity": "sha512-sqMMuL1rc0FmMBOzCpd0yuy9trqF2yTTVe+E9ogwCSWQCdDEtQUwrZPT6AxqtsFGRNxycgncbP/xmOOSPw5ZUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-paths": "^4.0.1" + }, + "engines": { + "node": ">= 6.0" + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -3100,6 +5143,54 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "license": "ISC" + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yauzl-clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/yauzl-clone/-/yauzl-clone-1.0.4.tgz", + "integrity": "sha512-igM2RRCf3k8TvZoxR2oguuw4z1xasOnA31joCqHIyLkeWrvAc2Jgay5ISQ2ZplinkoGaJ6orCz56Ey456c5ESA==", + "dev": true, + "license": "MIT", + "dependencies": { + "events-intercept": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yauzl-promise": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yauzl-promise/-/yauzl-promise-2.1.3.tgz", + "integrity": "sha512-A1pf6fzh6eYkK0L4Qp7g9jzJSDrM6nN0bOn5T0IbY4Yo3w+YkWlHFkJP7mzknMXjqusHFHlKsK2N+4OLsK2MRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "yauzl": "^2.9.1", + "yauzl-clone": "^1.0.4" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } } } } diff --git a/package.json b/package.json index e7e4075..7d9c0e4 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,26 @@ { "name": "jaryo-file-manager", "version": "2.0.0", - "description": "자료실 파일 관리 시스템 - Vercel Serverless", + "description": "자료실 파일 관리 시스템", + "main": "server.js", "scripts": { - "dev": "vercel dev", - "build": "echo 'Build complete'", - "start": "vercel dev" + "start": "node server.js", + "dev": "node server.js", + "build": "echo 'Build complete'" + }, + "dependencies": { + "express": "^4.18.2", + "cors": "^2.8.5", + "multer": "^1.4.5-lts.1", + "bcrypt": "^5.1.1", + "express-session": "^1.17.3", + "uuid": "^9.0.1", + "sqlite3": "^5.1.6" }, - "dependencies": {}, "devDependencies": { "vercel": "^32.0.0" }, - "keywords": ["file-manager", "vercel", "serverless", "admin"], + "keywords": ["file-manager", "admin"], "author": "Claude Code", "license": "MIT", "engines": { diff --git a/pm2-ecosystem.config.js b/pm2-ecosystem.config.js deleted file mode 100644 index 2e4d0f0..0000000 --- a/pm2-ecosystem.config.js +++ /dev/null @@ -1,25 +0,0 @@ -module.exports = { - apps: [{ - name: 'jaryo-file-manager', - script: 'server.js', - cwd: '/volume1/web/jaryo', - instances: 1, - autorestart: true, - watch: false, - max_memory_restart: '1G', - env: { - NODE_ENV: 'production', - PORT: 3005 - }, - env_production: { - NODE_ENV: 'production', - PORT: 3005 - }, - log_file: '/volume1/web/jaryo/logs/combined.log', - out_file: '/volume1/web/jaryo/logs/out.log', - error_file: '/volume1/web/jaryo/logs/error.log', - log_date_format: 'YYYY-MM-DD HH:mm:ss Z', - merge_logs: true, - time: true - }] -}; diff --git a/pm2-start.sh b/pm2-start.sh deleted file mode 100644 index f399990..0000000 --- a/pm2-start.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash - -# PM2를 사용한 시놀로지 NAS 서비스 시작 스크립트 -# 사용법: ./pm2-start.sh - -PROJECT_DIR="/volume1/web/jaryo" -LOG_DIR="/volume1/web/jaryo/logs" - -echo "=== PM2로 Jaryo File Manager 서비스 시작 ===" - -# 로그 디렉토리 생성 -mkdir -p "$LOG_DIR" - -# 프로젝트 디렉토리로 이동 -cd "$PROJECT_DIR" || { - echo "오류: 프로젝트 디렉토리를 찾을 수 없습니다: $PROJECT_DIR" - exit 1 -} - -# PM2 설치 확인 및 설치 -if ! command -v pm2 &> /dev/null; then - echo "PM2 설치 중..." - npm install -g pm2 -fi - -# 의존성 설치 확인 -if [ ! -d "node_modules" ]; then - echo "의존성 설치 중..." - npm install -fi - -# 데이터베이스 초기화 -echo "데이터베이스 초기화 중..." -node scripts/init-database.js - -# 기존 PM2 프로세스 중지 -echo "기존 프로세스 정리 중..." -pm2 delete jaryo-file-manager 2>/dev/null || true - -# PM2로 서비스 시작 -echo "PM2로 서비스 시작 중..." -pm2 start pm2-ecosystem.config.js --env production - -# PM2 시작 스크립트 생성 -pm2 startup -pm2 save - -echo "서비스가 PM2로 시작되었습니다." -echo "상태 확인: pm2 status" -echo "로그 확인: pm2 logs jaryo-file-manager" -echo "서비스 중지: pm2 stop jaryo-file-manager" diff --git a/render.yaml b/render.yaml deleted file mode 100644 index b230060..0000000 --- a/render.yaml +++ /dev/null @@ -1,12 +0,0 @@ -services: - - type: web - name: jaryo-file-manager - env: node - plan: free - buildCommand: npm install - startCommand: npm start - envVars: - - key: NODE_ENV - value: production - - key: PORT - value: 10000 diff --git a/scripts/init-database.js b/scripts/init-database.js deleted file mode 100644 index 7ec2682..0000000 --- a/scripts/init-database.js +++ /dev/null @@ -1,73 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const sqlite3 = require('sqlite3').verbose(); - -// 데이터베이스 파일 경로 -const dbPath = path.join(__dirname, '../database/jaryo.db'); -const schemaPath = path.join(__dirname, '../database/schema.sql'); - -// database 폴더가 없으면 생성 -const dbDir = path.dirname(dbPath); -if (!fs.existsSync(dbDir)) { - fs.mkdirSync(dbDir, { recursive: true }); -} - -// uploads 폴더도 생성 -const uploadsDir = path.join(__dirname, '../uploads'); -if (!fs.existsSync(uploadsDir)) { - fs.mkdirSync(uploadsDir, { recursive: true }); -} - -console.log('🔧 SQLite 데이터베이스 초기화 시작...'); - -// 데이터베이스 연결 -const db = new sqlite3.Database(dbPath, (err) => { - if (err) { - console.error('❌ 데이터베이스 연결 오류:', err.message); - return; - } - console.log('✅ SQLite 데이터베이스 연결 성공'); -}); - -// 스키마 파일 읽기 및 실행 -fs.readFile(schemaPath, 'utf8', (err, schema) => { - if (err) { - console.error('❌ 스키마 파일 읽기 오류:', err.message); - return; - } - - // 여러 SQL 문을 분리하여 실행 - const statements = schema.split(';').filter(stmt => stmt.trim().length > 0); - - db.serialize(() => { - statements.forEach((statement, index) => { - if (statement.trim()) { - db.run(statement + ';', (err) => { - if (err) { - console.error(`❌ SQL 실행 오류 (${index + 1}):`, err.message); - console.error('실행하려던 SQL:', statement); - } - }); - } - }); - - console.log('✅ 데이터베이스 스키마 생성 완료'); - - // 데이터 확인 - db.all('SELECT COUNT(*) as count FROM files', (err, rows) => { - if (err) { - console.error('❌ 데이터 확인 오류:', err.message); - } else { - console.log(`📊 파일 테이블 레코드 수: ${rows[0].count}`); - } - - db.close((err) => { - if (err) { - console.error('❌ 데이터베이스 종료 오류:', err.message); - } else { - console.log('🏁 데이터베이스 초기화 완료'); - } - }); - }); - }); -}); \ No newline at end of file diff --git a/simple.html b/simple.html deleted file mode 100644 index fac682a..0000000 --- a/simple.html +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - Jaryo File Manager - 테스트 - - - -
-

🚀 Jaryo File Manager

- -
-

✅ 정적 페이지 테스트

-

이 페이지가 보인다면 Vercel 배포가 성공한 것입니다!

-

시간:

-
- -
-

🔧 테스트 버튼들

- 메인 페이지 - API 테스트 - 파일 API -
- -
-

📡 AJAX 테스트

- -
-
-
- - - - \ No newline at end of file diff --git a/ssh-connect.sh b/ssh-connect.sh deleted file mode 100644 index 2142941..0000000 --- a/ssh-connect.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -# SSH 연결 헬퍼 스크립트 -NAS_IP="${1:-119.64.1.86}" -NAS_USER="${2:-vibsin9322}" -COMMAND="${3:-echo 'SSH 연결 성공'}" - -# 비밀번호를 입력받아 SSH 연결 -echo "🔑 SSH 연결 시도: $NAS_USER@$NAS_IP:2222" -echo "📝 비밀번호를 입력하세요:" - -ssh -p 2222 -o StrictHostKeyChecking=no "$NAS_USER@$NAS_IP" "$COMMAND" \ No newline at end of file diff --git a/styles.css b/styles.css index e89fe78..61e686f 100644 --- a/styles.css +++ b/styles.css @@ -619,7 +619,7 @@ header p { /* 제목 스타일 */ .board-title { color: #667eea; - font-weight: 500; + font-weight: 700; text-decoration: none; cursor: pointer; display: block; diff --git a/synology-git-diagnostic.md b/synology-git-diagnostic.md deleted file mode 100644 index e480777..0000000 --- a/synology-git-diagnostic.md +++ /dev/null @@ -1,203 +0,0 @@ -# 시놀로지 NAS Git Server 진단 및 해결 가이드 - -## 🔍 1단계: Git Server 패키지 상태 확인 - -### 1.1 DSM 패키지 센터 점검 -1. **DSM 로그인** → **패키지 센터** -2. **설치됨** 탭에서 "Git Server" 검색 -3. 상태 확인: - - ✅ **실행 중**: 정상 동작 - - ⚠️ **중지됨**: 서비스 시작 필요 - - ❌ **미설치**: 패키지 설치 필요 - -### 1.2 Git Server 서비스 시작 -```bash -# SSH로 NAS 접속 후 -sudo systemctl status git-daemon -sudo systemctl start git-daemon -sudo systemctl enable git-daemon -``` - -## 🛠️ 2단계: 기본 설정 확인 - -### 2.1 SSH 서비스 활성화 -1. **DSM 제어판** → **터미널 및 SNMP** -2. **SSH 서비스 활성화** 체크 -3. 포트 번호 확인 (기본: 22) - -### 2.2 사용자 권한 설정 -1. **DSM 제어판** → **사용자 및 그룹** -2. 사용자 선택 → **편집** → **애플리케이션** -3. **Git Server** 권한 부여 - -### 2.3 방화벽 설정 -1. **DSM 제어판** → **보안** → **방화벽** -2. 다음 포트 허용: - - SSH: 22 - - Git HTTP: 3000 - - Git HTTPS: 3001 - -## 📁 3단계: Git 디렉토리 구조 확인 - -### 3.1 기본 경로 확인 -```bash -# SSH 접속 후 확인 -ls -la /volume1/ -ls -la /volume1/git/ - -# Git 설정 디렉토리 확인 -ls -la /usr/local/git/ -``` - -### 3.2 권한 문제 해결 -```bash -# Git 디렉토리 생성 -sudo mkdir -p /volume1/git -sudo chown -R admin:users /volume1/git -sudo chmod 755 /volume1/git - -# Git Server 사용자 추가 (필요시) -sudo adduser git -sudo usermod -a -G users git -``` - -## 🔧 4단계: 레포지토리 수동 생성 - -### 4.1 Bare 레포지토리 생성 -```bash -# SSH로 NAS 접속 -ssh admin@your-nas-ip - -# 프로젝트 디렉토리 생성 -cd /volume1/git -sudo mkdir jaryo-file-manager.git -cd jaryo-file-manager.git - -# Bare 레포지토리 초기화 -sudo git init --bare -sudo chown -R admin:users . -``` - -### 4.2 웹 인터페이스 활성화 -```bash -# Git HTTP 서버 시작 -cd /volume1/git -sudo git daemon --reuseaddr --base-path=. --export-all --verbose --enable=receive-pack -``` - -## 🌐 5단계: 웹 인터페이스 설정 - -### 5.1 Git Web 설정 -```bash -# CGit 또는 GitWeb 설치 -sudo apt update -sudo apt install gitweb - -# Apache 설정 (Web Station 사용시) -sudo ln -s /usr/share/gitweb /volume1/web/git -``` - -### 5.2 브라우저에서 접속 -- URL: `http://your-nas-ip/git` -- 또는: `http://your-nas-ip:3000` - -## 🚨 6단계: 문제 해결 - -### 6.1 "레포지토리 설정이 안보임" 해결 -**원인 1: Git Server 패키지 미설치** -```bash -# 패키지 센터에서 Git Server 재설치 -# 또는 수동 Git 설치 -sudo apt update -sudo apt install git git-daemon-run -``` - -**원인 2: 서비스 시작 실패** -```bash -# 서비스 상태 확인 -sudo systemctl status git-daemon -sudo journalctl -u git-daemon - -# 수동 재시작 -sudo systemctl restart git-daemon -``` - -**원인 3: 권한 문제** -```bash -# 권한 재설정 -sudo chown -R www-data:www-data /volume1/git -sudo chmod -R 755 /volume1/git -``` - -### 6.2 포트 충돌 해결 -```bash -# 포트 사용 확인 -sudo netstat -tulpn | grep :3000 -sudo netstat -tulpn | grep :22 - -# 다른 포트로 변경 -sudo git daemon --port=3001 --reuseaddr --base-path=/volume1/git --export-all -``` - -## 📋 7단계: 연결 테스트 - -### 7.1 로컬에서 연결 테스트 -```bash -# SSH 연결 테스트 -ssh admin@your-nas-ip - -# Git 클론 테스트 -git clone ssh://admin@your-nas-ip/volume1/git/jaryo-file-manager.git - -# 또는 HTTP 연결 -git clone http://your-nas-ip:3000/jaryo-file-manager.git -``` - -### 7.2 기존 프로젝트 푸시 -```bash -# 기존 프로젝트에서 -git remote add nas ssh://admin@your-nas-ip/volume1/git/jaryo-file-manager.git -git push nas master -``` - -## 🔄 8단계: 자동화 설정 - -### 8.1 systemd 서비스 생성 -```bash -# /etc/systemd/system/git-daemon.service -sudo tee /etc/systemd/system/git-daemon.service << EOF -[Unit] -Description=Git Daemon -After=network.target - -[Service] -ExecStart=/usr/bin/git daemon --reuseaddr --base-path=/volume1/git --export-all --verbose --enable=receive-pack -Restart=always -User=git -Group=git - -[Install] -WantedBy=multi-user.target -EOF - -sudo systemctl enable git-daemon -sudo systemctl start git-daemon -``` - -## 📊 요약 - -레포지토리 설정이 보이지 않는 주요 원인: -1. ❌ Git Server 패키지 미설치/미실행 -2. ❌ SSH 서비스 비활성화 -3. ❌ 사용자 권한 부족 -4. ❌ 방화벽 차단 -5. ❌ Git 디렉토리 부재 - -해결 순서: -1. 패키지 설치/재시작 -2. SSH 및 권한 설정 -3. 수동 레포지토리 생성 -4. 연결 테스트 -5. 자동화 설정 - -이 가이드를 따라하면 시놀로지 NAS에서 Git 레포지토리를 성공적으로 설정할 수 있습니다. \ No newline at end of file diff --git a/synology-setup.md b/synology-setup.md deleted file mode 100644 index f5722ce..0000000 --- a/synology-setup.md +++ /dev/null @@ -1,248 +0,0 @@ -# 시놀로지 NAS에서 Jaryo File Manager 서비스 실행 가이드 - -## 1. 사전 준비사항 - -### 1.1 DSM 패키지 설치 -1. **DSM 제어판** → **패키지 센터** 접속 -2. 다음 패키지들을 설치: - - **Node.js** (최신 LTS 버전 권장) - - **Git Server** (선택사항, 소스코드 관리용) - - **Web Station** (선택사항, 웹 서버 프록시용) - -### 1.2 SSH 활성화 -1. **DSM 제어판** → **터미널 및 SNMP** → **SSH 서비스 활성화** -2. 포트 번호 확인 (기본: 22) - -## 2. 프로젝트 배포 - -### 2.1 방법 1: 직접 파일 업로드 (간단한 방법) - -1. **File Station**에서 `/volume1/web/` 폴더 생성 -2. 프로젝트 파일들을 `jaryo` 폴더에 업로드 -3. SSH로 접속하여 설정 - -### 2.2 방법 2: Git을 통한 배포 (권장) - -```bash -# NAS에 SSH 접속 -ssh admin@your-nas-ip - -# 프로젝트 디렉토리 생성 -mkdir -p /volume1/web/jaryo -cd /volume1/web/jaryo - -# Git 저장소 클론 (로컬에서 push한 경우) -git clone [your-repository-url] . - -# 또는 로컬에서 직접 파일 복사 -# scp -r ./jaryo/* admin@your-nas-ip:/volume1/web/jaryo/ -``` - -## 3. 서비스 설정 및 실행 - -### 3.1 스크립트 권한 설정 - -```bash -# SSH로 NAS 접속 -ssh admin@your-nas-ip - -# 프로젝트 디렉토리로 이동 -cd /volume1/web/jaryo - -# 스크립트 실행 권한 부여 -chmod +x start-service.sh -chmod +x stop-service.sh -``` - -### 3.2 서비스 시작 - -```bash -# 서비스 시작 -./start-service.sh - -# 로그 확인 -tail -f logs/app.log - -# 프로세스 상태 확인 -ps aux | grep "node server.js" -``` - -### 3.3 서비스 중지 - -```bash -# 서비스 중지 -./stop-service.sh -``` - -## 4. 자동 시작 설정 (선택사항) - -### 4.1 Task Scheduler 사용 - -1. **DSM 제어판** → **작업 스케줄러** -2. **작업 생성** → **사용자 정의 스크립트** -3. 설정: - - **작업 이름**: Jaryo Service Start - - **사용자**: root - - **스케줄**: 시스템 부팅 시 - - **작업 설정**: `/volume1/web/jaryo/start-service.sh` - -### 4.2 rc.local 사용 (고급 사용자) - -```bash -# /etc/rc.local 파일 편집 -sudo vi /etc/rc.local - -# 다음 라인 추가 -/volume1/web/jaryo/start-service.sh & - -# 파일 저장 후 권한 설정 -chmod +x /etc/rc.local -``` - -## 5. 방화벽 및 포트 설정 - -### 5.1 DSM 방화벽 설정 - -1. **DSM 제어판** → **보안** → **방화벽** -2. **방화벽 규칙 편집** → **규칙 생성** -3. 설정: - - **포트**: 3005 (애플리케이션 포트) - - **프로토콜**: TCP - - **소스**: 허용할 IP 범위 - -### 5.2 라우터 포트 포워딩 (외부 접속용) - -라우터에서 포트 3005를 NAS의 IP로 포워딩 설정 - -## 6. 웹 서버 프록시 설정 (Web Station 사용) - -### 6.1 Web Station 설정 - -1. **Web Station** → **가상 호스트** → **생성** -2. 설정: - - **도메인 이름**: your-domain.com (또는 IP) - - **포트**: 80 (또는 443 for HTTPS) - - **문서 루트**: `/volume1/web/jaryo` - - **HTTP 백엔드 서버**: `http://localhost:3005` - -### 6.2 Apache 설정 (고급) - -```apache -# /volume1/web/apache/conf/vhost/VirtualHost.conf - - ServerName your-domain.com - DocumentRoot /volume1/web/jaryo - - ProxyPreserveHost On - ProxyPass / http://localhost:3005/ - ProxyPassReverse / http://localhost:3005/ - - - AllowOverride All - Require all granted - - -``` - -## 7. 모니터링 및 유지보수 - -### 7.1 로그 모니터링 - -```bash -# 실시간 로그 확인 -tail -f /volume1/web/jaryo/logs/app.log - -# 로그 파일 크기 확인 -du -h /volume1/web/jaryo/logs/app.log - -# 로그 로테이션 설정 (logrotate 사용) -``` - -### 7.2 서비스 상태 확인 - -```bash -# 프로세스 확인 -ps aux | grep "node server.js" - -# 포트 사용 확인 -netstat -tlnp | grep :3005 - -# 메모리 사용량 확인 -top -p $(cat /volume1/web/jaryo/app.pid) -``` - -### 7.3 백업 설정 - -1. **Hyper Backup** 패키지 설치 -2. `/volume1/web/jaryo` 폴더 백업 스케줄 설정 -3. 데이터베이스 파일 (`jaryo.db`) 별도 백업 권장 - -## 8. 문제 해결 - -### 8.1 일반적인 문제들 - -**서비스가 시작되지 않는 경우:** -```bash -# Node.js 설치 확인 -which node -node --version - -# 의존성 재설치 -cd /volume1/web/jaryo -rm -rf node_modules package-lock.json -npm install - -# 권한 문제 확인 -ls -la /volume1/web/jaryo/ -chown -R admin:users /volume1/web/jaryo/ -``` - -**포트 충돌 문제:** -```bash -# 포트 사용 확인 -netstat -tlnp | grep :3005 - -# 다른 포트로 변경 (server.js 수정) -# const PORT = process.env.PORT || 3006; -``` - -**메모리 부족 문제:** -```bash -# 메모리 사용량 확인 -free -h - -# Node.js 메모리 제한 설정 -# node --max-old-space-size=512 server.js -``` - -### 8.2 로그 분석 - -```bash -# 에러 로그만 확인 -grep -i error /volume1/web/jaryo/logs/app.log - -# 최근 100줄 확인 -tail -100 /volume1/web/jaryo/logs/app.log - -# 특정 시간대 로그 확인 -grep "2024-01-15" /volume1/web/jaryo/logs/app.log -``` - -## 9. 보안 고려사항 - -1. **HTTPS 설정**: Let's Encrypt 인증서 사용 -2. **방화벽 강화**: 필요한 포트만 개방 -3. **정기 업데이트**: Node.js 및 패키지 업데이트 -4. **백업**: 정기적인 데이터 백업 -5. **모니터링**: 로그 모니터링 및 알림 설정 - -## 10. 성능 최적화 - -1. **PM2 사용**: 프로세스 관리자로 PM2 사용 고려 -2. **캐싱**: 정적 파일 캐싱 설정 -3. **압축**: gzip 압축 활성화 -4. **CDN**: 정적 파일 CDN 사용 고려 - ---- - -**참고**: 이 가이드는 시놀로지 DSM 7.x 기준으로 작성되었습니다. 버전에 따라 일부 설정이 다를 수 있습니다. diff --git a/vercel.json b/vercel.json deleted file mode 100644 index 58ac9fe..0000000 --- a/vercel.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "version": 2, - "routes": [ - { - "src": "/simple", - "dest": "/simple.html" - }, - { - "src": "/api/test", - "dest": "/api/test.js" - }, - { - "src": "/api/files/public", - "dest": "/api/files.js" - }, - { - "src": "/api/files", - "dest": "/api/files.js" - }, - { - "src": "/(.*\\.(css|js|json|svg|png|jpg|jpeg|gif|ico|woff|woff2|ttf|eot|html))", - "dest": "/$1" - }, - { - "src": "/admin/(.*)", - "dest": "/admin/$1" - }, - { - "src": "/", - "dest": "/simple.html" - } - ] -} diff --git a/게시판.png b/게시판.png deleted file mode 100644 index 099b68d..0000000 Binary files a/게시판.png and /dev/null differ diff --git a/오류.png b/오류.png deleted file mode 100644 index 7b98a61..0000000 Binary files a/오류.png and /dev/null differ