diff --git a/.env b/.env
new file mode 100644
index 0000000..a134c0d
--- /dev/null
+++ b/.env
@@ -0,0 +1,2 @@
+PORT=3000
+DEBUG=true# 调试日志
diff --git a/.gitignore b/.gitignore
index 2ccbe46..ccce7c6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,13 @@
-/node_modules/
+/tmp
+/out-tsc
+
+/node_modules
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+/.pnp
+.pnp.js
+
+.vscode/*
+/dist/
+/logs/
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..35410ca
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
+# 基于编辑器的 HTTP 客户端请求
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/crystelf-core.iml b/.idea/crystelf-core.iml
new file mode 100644
index 0000000..24643cc
--- /dev/null
+++ b/.idea/crystelf-core.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..03d9549
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml
new file mode 100644
index 0000000..d23208f
--- /dev/null
+++ b/.idea/jsLibraryMappings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..a81eb2d
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..2ab8391
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,7 @@
+{
+ "semi": true,
+ "singleQuote": true,
+ "printWidth": 100,
+ "tabWidth": 2,
+ "trailingComma": "es5"
+}
diff --git a/README.md b/README.md
deleted file mode 100644
index c8367a5..0000000
--- a/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# crystelf-core
-晶灵核心服务
diff --git a/app.ts b/app.ts
deleted file mode 100644
index 74e5f22..0000000
--- a/app.ts
+++ /dev/null
@@ -1 +0,0 @@
-import express from 'express';
diff --git a/package.json b/package.json
index b07bce4..b00f9c7 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,22 @@
{
- "dependencies": {
- "express": "^5.1.0"
- }
+ "name": "crystelf-core",
+ "version": "1.0.0",
+ "scripts": {
+ "dev": "ts-node-dev src/main.ts",
+ "start": "node dist/main.js",
+ "build": "tsc"
+ },
+ "dependencies": {
+ "chalk": "4",
+ "dotenv": "^16.0.0",
+ "express": "^4.18.0"
+ },
+ "devDependencies": {
+ "@types/express": "^4.17.0",
+ "@types/mkdirp": "^2.0.0",
+ "@types/node": "^18.0.0",
+ "prettier": "^3.5.3",
+ "ts-node-dev": "^2.0.0",
+ "typescript": "^5.0.0"
+ }
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index fcf628f..79d89cb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,19 +8,156 @@ importers:
.:
dependencies:
+ chalk:
+ specifier: '4'
+ version: 4.1.2
+ dotenv:
+ specifier: ^16.0.0
+ version: 16.4.7
express:
- specifier: ^5.1.0
- version: 5.1.0
+ specifier: ^4.18.0
+ version: 4.21.2
+ mkdirp:
+ specifier: ^3.0.1
+ version: 3.0.1
+ devDependencies:
+ '@types/express':
+ specifier: ^4.17.0
+ version: 4.17.21
+ '@types/mkdirp':
+ specifier: ^2.0.0
+ version: 2.0.0
+ '@types/node':
+ specifier: ^18.0.0
+ version: 18.19.86
+ prettier:
+ specifier: ^3.5.3
+ version: 3.5.3
+ ts-node-dev:
+ specifier: ^2.0.0
+ version: 2.0.0(@types/node@18.19.86)(typescript@5.8.2)
+ typescript:
+ specifier: ^5.0.0
+ version: 5.8.2
packages:
- accepts@2.0.0:
- resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
+ '@cspotcode/source-map-support@0.8.1':
+ resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
+ engines: {node: '>=12'}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/sourcemap-codec@1.5.0':
+ resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
+
+ '@jridgewell/trace-mapping@0.3.9':
+ resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
+
+ '@tsconfig/node10@1.0.11':
+ resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==}
+
+ '@tsconfig/node12@1.0.11':
+ resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
+
+ '@tsconfig/node14@1.0.3':
+ resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
+
+ '@tsconfig/node16@1.0.4':
+ resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
+
+ '@types/body-parser@1.19.5':
+ resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==}
+
+ '@types/connect@3.4.38':
+ resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==}
+
+ '@types/express-serve-static-core@4.19.6':
+ resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==}
+
+ '@types/express@4.17.21':
+ resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==}
+
+ '@types/http-errors@2.0.4':
+ resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==}
+
+ '@types/mime@1.3.5':
+ resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==}
+
+ '@types/mkdirp@2.0.0':
+ resolution: {integrity: sha512-c/iUqMymAlxLAyIK3u5SzrwkrkyOdv1XDc91T+b5FsY7Jr6ERhUD19jJHOhPW4GD6tmN6mFEorfSdks525pwdQ==}
+ deprecated: This is a stub types definition. mkdirp provides its own type definitions, so you do not need this installed.
+
+ '@types/node@18.19.86':
+ resolution: {integrity: sha512-fifKayi175wLyKyc5qUfyENhQ1dCNI1UNjp653d8kuYcPQN5JhX3dGuP/XmvPTg/xRBn1VTLpbmi+H/Mr7tLfQ==}
+
+ '@types/qs@6.9.18':
+ resolution: {integrity: sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==}
+
+ '@types/range-parser@1.2.7':
+ resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==}
+
+ '@types/send@0.17.4':
+ resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==}
+
+ '@types/serve-static@1.15.7':
+ resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==}
+
+ '@types/strip-bom@3.0.0':
+ resolution: {integrity: sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==}
+
+ '@types/strip-json-comments@0.0.30':
+ resolution: {integrity: sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==}
+
+ accepts@1.3.8:
+ resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
engines: {node: '>= 0.6'}
- body-parser@2.2.0:
- resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==}
- engines: {node: '>=18'}
+ acorn-walk@8.3.4:
+ resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==}
+ engines: {node: '>=0.4.0'}
+
+ acorn@8.14.1:
+ resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
+ anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+
+ arg@4.1.3:
+ resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
+
+ array-flatten@1.1.1:
+ resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==}
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ binary-extensions@2.3.0:
+ resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
+ engines: {node: '>=8'}
+
+ body-parser@1.20.3:
+ resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==}
+ engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
+
+ brace-expansion@1.1.11:
+ resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
+
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
+ buffer-from@1.1.2:
+ resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
bytes@3.1.2:
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
@@ -34,25 +171,44 @@ packages:
resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
engines: {node: '>= 0.4'}
- content-disposition@1.0.0:
- resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==}
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+
+ chokidar@3.6.0:
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
+ engines: {node: '>= 8.10.0'}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ concat-map@0.0.1:
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+
+ content-disposition@0.5.4:
+ resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
engines: {node: '>= 0.6'}
content-type@1.0.5:
resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==}
engines: {node: '>= 0.6'}
- cookie-signature@1.2.2:
- resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==}
- engines: {node: '>=6.6.0'}
+ cookie-signature@1.0.6:
+ resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==}
- cookie@0.7.2:
- resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
+ cookie@0.7.1:
+ resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==}
engines: {node: '>= 0.6'}
- debug@4.4.0:
- resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
- engines: {node: '>=6.0'}
+ create-require@1.1.1:
+ resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
+
+ debug@2.6.9:
+ resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
@@ -63,13 +219,32 @@ packages:
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
engines: {node: '>= 0.8'}
+ destroy@1.2.0:
+ resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
+ engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
+
+ diff@4.0.2:
+ resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
+ engines: {node: '>=0.3.1'}
+
+ dotenv@16.4.7:
+ resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==}
+ engines: {node: '>=12'}
+
dunder-proto@1.0.1:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'}
+ dynamic-dedupe@0.3.0:
+ resolution: {integrity: sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==}
+
ee-first@1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
+ encodeurl@1.0.2:
+ resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
+ engines: {node: '>= 0.8'}
+
encodeurl@2.0.0:
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
engines: {node: '>= 0.8'}
@@ -93,21 +268,33 @@ packages:
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
engines: {node: '>= 0.6'}
- express@5.1.0:
- resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==}
- engines: {node: '>= 18'}
+ express@4.21.2:
+ resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==}
+ engines: {node: '>= 0.10.0'}
- finalhandler@2.1.0:
- resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==}
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
+ finalhandler@1.3.1:
+ resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==}
engines: {node: '>= 0.8'}
forwarded@0.2.0:
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
engines: {node: '>= 0.6'}
- fresh@2.0.0:
- resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==}
- engines: {node: '>= 0.8'}
+ fresh@0.5.2:
+ resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
+ engines: {node: '>= 0.6'}
+
+ fs.realpath@1.0.0:
+ resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
@@ -120,10 +307,22 @@ packages:
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
engines: {node: '>= 0.4'}
+ glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+
+ glob@7.2.3:
+ resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+ deprecated: Glob versions prior to v9 are no longer supported
+
gopd@1.2.0:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
has-symbols@1.1.0:
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
engines: {node: '>= 0.4'}
@@ -136,10 +335,14 @@ packages:
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
engines: {node: '>= 0.8'}
- iconv-lite@0.6.3:
- resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
+ iconv-lite@0.4.24:
+ resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
engines: {node: '>=0.10.0'}
+ inflight@1.0.6:
+ resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+ deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
+
inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
@@ -147,36 +350,87 @@ packages:
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
engines: {node: '>= 0.10'}
- is-promise@4.0.0:
- resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
+ is-binary-path@2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+
+ is-core-module@2.16.1:
+ resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
+ engines: {node: '>= 0.4'}
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ make-error@1.3.6:
+ resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
math-intrinsics@1.1.0:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
- media-typer@1.1.0:
- resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==}
- engines: {node: '>= 0.8'}
-
- merge-descriptors@2.0.0:
- resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==}
- engines: {node: '>=18'}
-
- mime-db@1.54.0:
- resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==}
+ media-typer@0.3.0:
+ resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
engines: {node: '>= 0.6'}
- mime-types@3.0.1:
- resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==}
+ merge-descriptors@1.0.3:
+ resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==}
+
+ methods@1.1.2:
+ resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==}
engines: {node: '>= 0.6'}
+ mime-db@1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+
+ mime@1.6.0:
+ resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ minimatch@3.1.2:
+ resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
+
+ minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+
+ mkdirp@1.0.4:
+ resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ mkdirp@3.0.1:
+ resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ ms@2.0.0:
+ resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
+
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
- negotiator@1.0.0:
- resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==}
+ negotiator@0.6.3:
+ resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
engines: {node: '>= 0.6'}
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
object-inspect@1.13.4:
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
engines: {node: '>= 0.4'}
@@ -192,29 +446,54 @@ packages:
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
engines: {node: '>= 0.8'}
- path-to-regexp@8.2.0:
- resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==}
- engines: {node: '>=16'}
+ path-is-absolute@1.0.1:
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
+ engines: {node: '>=0.10.0'}
+
+ path-parse@1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+
+ path-to-regexp@0.1.12:
+ resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==}
+
+ picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+
+ prettier@3.5.3:
+ resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==}
+ engines: {node: '>=14'}
+ hasBin: true
proxy-addr@2.0.7:
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
engines: {node: '>= 0.10'}
- qs@6.14.0:
- resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
+ qs@6.13.0:
+ resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==}
engines: {node: '>=0.6'}
range-parser@1.2.1:
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
engines: {node: '>= 0.6'}
- raw-body@3.0.0:
- resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==}
+ raw-body@2.5.2:
+ resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==}
engines: {node: '>= 0.8'}
- router@2.2.0:
- resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==}
- engines: {node: '>= 18'}
+ readdirp@3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+
+ resolve@1.22.10:
+ resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==}
+ engines: {node: '>= 0.4'}
+ hasBin: true
+
+ rimraf@2.7.1:
+ resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==}
+ deprecated: Rimraf versions prior to v4 are no longer supported
+ hasBin: true
safe-buffer@5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
@@ -222,13 +501,13 @@ packages:
safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
- send@1.2.0:
- resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==}
- engines: {node: '>= 18'}
+ send@0.19.0:
+ resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==}
+ engines: {node: '>= 0.8.0'}
- serve-static@2.2.0:
- resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==}
- engines: {node: '>= 18'}
+ serve-static@1.16.2:
+ resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==}
+ engines: {node: '>= 0.8.0'}
setprototypeof@1.2.0:
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
@@ -249,22 +528,96 @@ packages:
resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
engines: {node: '>= 0.4'}
+ source-map-support@0.5.21:
+ resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
+
+ source-map@0.6.1:
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
+ engines: {node: '>=0.10.0'}
+
statuses@2.0.1:
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
engines: {node: '>= 0.8'}
+ strip-bom@3.0.0:
+ resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
+ engines: {node: '>=4'}
+
+ strip-json-comments@2.0.1:
+ resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
+ engines: {node: '>=0.10.0'}
+
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ supports-preserve-symlinks-flag@1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
toidentifier@1.0.1:
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
engines: {node: '>=0.6'}
- type-is@2.0.1:
- resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==}
+ tree-kill@1.2.2:
+ resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
+ hasBin: true
+
+ ts-node-dev@2.0.0:
+ resolution: {integrity: sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==}
+ engines: {node: '>=0.8.0'}
+ hasBin: true
+ peerDependencies:
+ node-notifier: '*'
+ typescript: '*'
+ peerDependenciesMeta:
+ node-notifier:
+ optional: true
+
+ ts-node@10.9.2:
+ resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==}
+ hasBin: true
+ 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
+
+ tsconfig@7.0.0:
+ resolution: {integrity: sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==}
+
+ type-is@1.6.18:
+ resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==}
engines: {node: '>= 0.6'}
+ typescript@5.8.2:
+ resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ undici-types@5.26.5:
+ resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
+
unpipe@1.0.0:
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
engines: {node: '>= 0.8'}
+ utils-merge@1.0.1:
+ resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
+ engines: {node: '>= 0.4.0'}
+
+ v8-compile-cache-lib@3.0.1:
+ resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
+
vary@1.1.2:
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
@@ -272,27 +625,147 @@ packages:
wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+ xtend@4.0.2:
+ resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
+ engines: {node: '>=0.4'}
+
+ yn@3.1.1:
+ resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
+ engines: {node: '>=6'}
+
snapshots:
- accepts@2.0.0:
+ '@cspotcode/source-map-support@0.8.1':
dependencies:
- mime-types: 3.0.1
- negotiator: 1.0.0
+ '@jridgewell/trace-mapping': 0.3.9
- body-parser@2.2.0:
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/sourcemap-codec@1.5.0': {}
+
+ '@jridgewell/trace-mapping@0.3.9':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.0
+
+ '@tsconfig/node10@1.0.11': {}
+
+ '@tsconfig/node12@1.0.11': {}
+
+ '@tsconfig/node14@1.0.3': {}
+
+ '@tsconfig/node16@1.0.4': {}
+
+ '@types/body-parser@1.19.5':
+ dependencies:
+ '@types/connect': 3.4.38
+ '@types/node': 18.19.86
+
+ '@types/connect@3.4.38':
+ dependencies:
+ '@types/node': 18.19.86
+
+ '@types/express-serve-static-core@4.19.6':
+ dependencies:
+ '@types/node': 18.19.86
+ '@types/qs': 6.9.18
+ '@types/range-parser': 1.2.7
+ '@types/send': 0.17.4
+
+ '@types/express@4.17.21':
+ dependencies:
+ '@types/body-parser': 1.19.5
+ '@types/express-serve-static-core': 4.19.6
+ '@types/qs': 6.9.18
+ '@types/serve-static': 1.15.7
+
+ '@types/http-errors@2.0.4': {}
+
+ '@types/mime@1.3.5': {}
+
+ '@types/mkdirp@2.0.0':
+ dependencies:
+ mkdirp: 3.0.1
+
+ '@types/node@18.19.86':
+ dependencies:
+ undici-types: 5.26.5
+
+ '@types/qs@6.9.18': {}
+
+ '@types/range-parser@1.2.7': {}
+
+ '@types/send@0.17.4':
+ dependencies:
+ '@types/mime': 1.3.5
+ '@types/node': 18.19.86
+
+ '@types/serve-static@1.15.7':
+ dependencies:
+ '@types/http-errors': 2.0.4
+ '@types/node': 18.19.86
+ '@types/send': 0.17.4
+
+ '@types/strip-bom@3.0.0': {}
+
+ '@types/strip-json-comments@0.0.30': {}
+
+ accepts@1.3.8:
+ dependencies:
+ mime-types: 2.1.35
+ negotiator: 0.6.3
+
+ acorn-walk@8.3.4:
+ dependencies:
+ acorn: 8.14.1
+
+ acorn@8.14.1: {}
+
+ ansi-styles@4.3.0:
+ dependencies:
+ color-convert: 2.0.1
+
+ anymatch@3.1.3:
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.1
+
+ arg@4.1.3: {}
+
+ array-flatten@1.1.1: {}
+
+ balanced-match@1.0.2: {}
+
+ binary-extensions@2.3.0: {}
+
+ body-parser@1.20.3:
dependencies:
bytes: 3.1.2
content-type: 1.0.5
- debug: 4.4.0
+ debug: 2.6.9
+ depd: 2.0.0
+ destroy: 1.2.0
http-errors: 2.0.0
- iconv-lite: 0.6.3
+ iconv-lite: 0.4.24
on-finished: 2.4.1
- qs: 6.14.0
- raw-body: 3.0.0
- type-is: 2.0.1
+ qs: 6.13.0
+ raw-body: 2.5.2
+ type-is: 1.6.18
+ unpipe: 1.0.0
transitivePeerDependencies:
- supports-color
+ brace-expansion@1.1.11:
+ dependencies:
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
+
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
+ buffer-from@1.1.2: {}
+
bytes@3.1.2: {}
call-bind-apply-helpers@1.0.2:
@@ -305,30 +778,69 @@ snapshots:
call-bind-apply-helpers: 1.0.2
get-intrinsic: 1.3.0
- content-disposition@1.0.0:
+ chalk@4.1.2:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
+ chokidar@3.6.0:
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.3
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ color-convert@2.0.1:
+ dependencies:
+ color-name: 1.1.4
+
+ color-name@1.1.4: {}
+
+ concat-map@0.0.1: {}
+
+ content-disposition@0.5.4:
dependencies:
safe-buffer: 5.2.1
content-type@1.0.5: {}
- cookie-signature@1.2.2: {}
+ cookie-signature@1.0.6: {}
- cookie@0.7.2: {}
+ cookie@0.7.1: {}
- debug@4.4.0:
+ create-require@1.1.1: {}
+
+ debug@2.6.9:
dependencies:
- ms: 2.1.3
+ ms: 2.0.0
depd@2.0.0: {}
+ destroy@1.2.0: {}
+
+ diff@4.0.2: {}
+
+ dotenv@16.4.7: {}
+
dunder-proto@1.0.1:
dependencies:
call-bind-apply-helpers: 1.0.2
es-errors: 1.3.0
gopd: 1.2.0
+ dynamic-dedupe@0.3.0:
+ dependencies:
+ xtend: 4.0.2
+
ee-first@1.1.1: {}
+ encodeurl@1.0.2: {}
+
encodeurl@2.0.0: {}
es-define-property@1.0.1: {}
@@ -343,52 +855,66 @@ snapshots:
etag@1.8.1: {}
- express@5.1.0:
+ express@4.21.2:
dependencies:
- accepts: 2.0.0
- body-parser: 2.2.0
- content-disposition: 1.0.0
+ accepts: 1.3.8
+ array-flatten: 1.1.1
+ body-parser: 1.20.3
+ content-disposition: 0.5.4
content-type: 1.0.5
- cookie: 0.7.2
- cookie-signature: 1.2.2
- debug: 4.4.0
+ cookie: 0.7.1
+ cookie-signature: 1.0.6
+ debug: 2.6.9
+ depd: 2.0.0
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
- finalhandler: 2.1.0
- fresh: 2.0.0
+ finalhandler: 1.3.1
+ fresh: 0.5.2
http-errors: 2.0.0
- merge-descriptors: 2.0.0
- mime-types: 3.0.1
+ merge-descriptors: 1.0.3
+ methods: 1.1.2
on-finished: 2.4.1
- once: 1.4.0
parseurl: 1.3.3
+ path-to-regexp: 0.1.12
proxy-addr: 2.0.7
- qs: 6.14.0
+ qs: 6.13.0
range-parser: 1.2.1
- router: 2.2.0
- send: 1.2.0
- serve-static: 2.2.0
+ safe-buffer: 5.2.1
+ send: 0.19.0
+ serve-static: 1.16.2
+ setprototypeof: 1.2.0
statuses: 2.0.1
- type-is: 2.0.1
+ type-is: 1.6.18
+ utils-merge: 1.0.1
vary: 1.1.2
transitivePeerDependencies:
- supports-color
- finalhandler@2.1.0:
+ fill-range@7.1.1:
dependencies:
- debug: 4.4.0
+ to-regex-range: 5.0.1
+
+ finalhandler@1.3.1:
+ dependencies:
+ debug: 2.6.9
encodeurl: 2.0.0
escape-html: 1.0.3
on-finished: 2.4.1
parseurl: 1.3.3
statuses: 2.0.1
+ unpipe: 1.0.0
transitivePeerDependencies:
- supports-color
forwarded@0.2.0: {}
- fresh@2.0.0: {}
+ fresh@0.5.2: {}
+
+ fs.realpath@1.0.0: {}
+
+ fsevents@2.3.3:
+ optional: true
function-bind@1.1.2: {}
@@ -410,8 +936,23 @@ snapshots:
dunder-proto: 1.0.1
es-object-atoms: 1.1.1
+ glob-parent@5.1.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob@7.2.3:
+ dependencies:
+ fs.realpath: 1.0.0
+ inflight: 1.0.6
+ inherits: 2.0.4
+ minimatch: 3.1.2
+ once: 1.4.0
+ path-is-absolute: 1.0.1
+
gopd@1.2.0: {}
+ has-flag@4.0.0: {}
+
has-symbols@1.1.0: {}
hasown@2.0.2:
@@ -426,31 +967,70 @@ snapshots:
statuses: 2.0.1
toidentifier: 1.0.1
- iconv-lite@0.6.3:
+ iconv-lite@0.4.24:
dependencies:
safer-buffer: 2.1.2
+ inflight@1.0.6:
+ dependencies:
+ once: 1.4.0
+ wrappy: 1.0.2
+
inherits@2.0.4: {}
ipaddr.js@1.9.1: {}
- is-promise@4.0.0: {}
+ is-binary-path@2.1.0:
+ dependencies:
+ binary-extensions: 2.3.0
+
+ is-core-module@2.16.1:
+ dependencies:
+ hasown: 2.0.2
+
+ is-extglob@2.1.1: {}
+
+ is-glob@4.0.3:
+ dependencies:
+ is-extglob: 2.1.1
+
+ is-number@7.0.0: {}
+
+ make-error@1.3.6: {}
math-intrinsics@1.1.0: {}
- media-typer@1.1.0: {}
+ media-typer@0.3.0: {}
- merge-descriptors@2.0.0: {}
+ merge-descriptors@1.0.3: {}
- mime-db@1.54.0: {}
+ methods@1.1.2: {}
- mime-types@3.0.1:
+ mime-db@1.52.0: {}
+
+ mime-types@2.1.35:
dependencies:
- mime-db: 1.54.0
+ mime-db: 1.52.0
+
+ mime@1.6.0: {}
+
+ minimatch@3.1.2:
+ dependencies:
+ brace-expansion: 1.1.11
+
+ minimist@1.2.8: {}
+
+ mkdirp@1.0.4: {}
+
+ mkdirp@3.0.1: {}
+
+ ms@2.0.0: {}
ms@2.1.3: {}
- negotiator@1.0.0: {}
+ negotiator@0.6.3: {}
+
+ normalize-path@3.0.0: {}
object-inspect@1.13.4: {}
@@ -464,49 +1044,63 @@ snapshots:
parseurl@1.3.3: {}
- path-to-regexp@8.2.0: {}
+ path-is-absolute@1.0.1: {}
+
+ path-parse@1.0.7: {}
+
+ path-to-regexp@0.1.12: {}
+
+ picomatch@2.3.1: {}
+
+ prettier@3.5.3: {}
proxy-addr@2.0.7:
dependencies:
forwarded: 0.2.0
ipaddr.js: 1.9.1
- qs@6.14.0:
+ qs@6.13.0:
dependencies:
side-channel: 1.1.0
range-parser@1.2.1: {}
- raw-body@3.0.0:
+ raw-body@2.5.2:
dependencies:
bytes: 3.1.2
http-errors: 2.0.0
- iconv-lite: 0.6.3
+ iconv-lite: 0.4.24
unpipe: 1.0.0
- router@2.2.0:
+ readdirp@3.6.0:
dependencies:
- debug: 4.4.0
- depd: 2.0.0
- is-promise: 4.0.0
- parseurl: 1.3.3
- path-to-regexp: 8.2.0
- transitivePeerDependencies:
- - supports-color
+ picomatch: 2.3.1
+
+ resolve@1.22.10:
+ dependencies:
+ is-core-module: 2.16.1
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
+ rimraf@2.7.1:
+ dependencies:
+ glob: 7.2.3
safe-buffer@5.2.1: {}
safer-buffer@2.1.2: {}
- send@1.2.0:
+ send@0.19.0:
dependencies:
- debug: 4.4.0
- encodeurl: 2.0.0
+ debug: 2.6.9
+ depd: 2.0.0
+ destroy: 1.2.0
+ encodeurl: 1.0.2
escape-html: 1.0.3
etag: 1.8.1
- fresh: 2.0.0
+ fresh: 0.5.2
http-errors: 2.0.0
- mime-types: 3.0.1
+ mime: 1.6.0
ms: 2.1.3
on-finished: 2.4.1
range-parser: 1.2.1
@@ -514,12 +1108,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
- serve-static@2.2.0:
+ serve-static@1.16.2:
dependencies:
encodeurl: 2.0.0
escape-html: 1.0.3
parseurl: 1.3.3
- send: 1.2.0
+ send: 0.19.0
transitivePeerDependencies:
- supports-color
@@ -553,18 +1147,95 @@ snapshots:
side-channel-map: 1.0.1
side-channel-weakmap: 1.0.2
+ source-map-support@0.5.21:
+ dependencies:
+ buffer-from: 1.1.2
+ source-map: 0.6.1
+
+ source-map@0.6.1: {}
+
statuses@2.0.1: {}
+ strip-bom@3.0.0: {}
+
+ strip-json-comments@2.0.1: {}
+
+ supports-color@7.2.0:
+ dependencies:
+ has-flag: 4.0.0
+
+ supports-preserve-symlinks-flag@1.0.0: {}
+
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
+
toidentifier@1.0.1: {}
- type-is@2.0.1:
+ tree-kill@1.2.2: {}
+
+ ts-node-dev@2.0.0(@types/node@18.19.86)(typescript@5.8.2):
dependencies:
- content-type: 1.0.5
- media-typer: 1.1.0
- mime-types: 3.0.1
+ chokidar: 3.6.0
+ dynamic-dedupe: 0.3.0
+ minimist: 1.2.8
+ mkdirp: 1.0.4
+ resolve: 1.22.10
+ rimraf: 2.7.1
+ source-map-support: 0.5.21
+ tree-kill: 1.2.2
+ ts-node: 10.9.2(@types/node@18.19.86)(typescript@5.8.2)
+ tsconfig: 7.0.0
+ typescript: 5.8.2
+ transitivePeerDependencies:
+ - '@swc/core'
+ - '@swc/wasm'
+ - '@types/node'
+
+ ts-node@10.9.2(@types/node@18.19.86)(typescript@5.8.2):
+ dependencies:
+ '@cspotcode/source-map-support': 0.8.1
+ '@tsconfig/node10': 1.0.11
+ '@tsconfig/node12': 1.0.11
+ '@tsconfig/node14': 1.0.3
+ '@tsconfig/node16': 1.0.4
+ '@types/node': 18.19.86
+ acorn: 8.14.1
+ acorn-walk: 8.3.4
+ arg: 4.1.3
+ create-require: 1.1.1
+ diff: 4.0.2
+ make-error: 1.3.6
+ typescript: 5.8.2
+ v8-compile-cache-lib: 3.0.1
+ yn: 3.1.1
+
+ tsconfig@7.0.0:
+ dependencies:
+ '@types/strip-bom': 3.0.0
+ '@types/strip-json-comments': 0.0.30
+ strip-bom: 3.0.0
+ strip-json-comments: 2.0.1
+
+ type-is@1.6.18:
+ dependencies:
+ media-typer: 0.3.0
+ mime-types: 2.1.35
+
+ typescript@5.8.2: {}
+
+ undici-types@5.26.5: {}
unpipe@1.0.0: {}
+ utils-merge@1.0.1: {}
+
+ v8-compile-cache-lib@3.0.1: {}
+
vary@1.1.2: {}
wrappy@1.0.2: {}
+
+ xtend@4.0.2: {}
+
+ yn@3.1.1: {}
diff --git a/src/app.ts b/src/app.ts
new file mode 100644
index 0000000..5a00f04
--- /dev/null
+++ b/src/app.ts
@@ -0,0 +1,25 @@
+import express from 'express';
+import logger from './utils/logger';
+import fc from './utils/file';
+import paths from './utils/path';
+import sampleController from './modules/sample/sample.controller';
+import imageController from './modules/image/image.controller';
+
+const apps = {
+ createApp() {
+ const app = express();
+
+ app.use(express.json());
+ app.use('/public', express.static(paths.get('public')));
+ logger.debug(`路由/public挂载成功..`);
+ app.use('/api/sample', sampleController.getRouter());
+ logger.debug(`路由/api/sample挂载成功..`);
+ app.use('/images', imageController.getRouter());
+ logger.debug(`路由/images挂载成功..`);
+ fc.createDir(paths.get('log'));
+ logger.info('晶灵核心初始化成功!');
+ return app;
+ },
+};
+
+export default apps;
diff --git a/src/main.ts b/src/main.ts
new file mode 100644
index 0000000..9210984
--- /dev/null
+++ b/src/main.ts
@@ -0,0 +1,10 @@
+import apps from './app';
+import logger from './utils/logger';
+
+const PORT = process.env.PORT || 3000;
+
+const app = apps.createApp();
+
+app.listen(PORT, () => {
+ logger.info(`Crystelf-core listening on ${PORT}`);
+});
diff --git a/src/modules/image/image.controller.ts b/src/modules/image/image.controller.ts
new file mode 100644
index 0000000..f594e8c
--- /dev/null
+++ b/src/modules/image/image.controller.ts
@@ -0,0 +1,51 @@
+import express from 'express';
+import ImageService from './image.service';
+import logger from '../../utils/logger';
+
+class ImageController {
+ private readonly router: express.Router;
+ private readonly imageService: ImageService;
+
+ constructor() {
+ this.router = express.Router();
+ this.imageService = new ImageService();
+ this.initializeRoutes();
+ }
+
+ public getRouter(): express.Router {
+ return this.router;
+ }
+
+ private initializeRoutes(): void {
+ this.router.get('/:filename', this.handleGetImage);
+ }
+
+ private handleGetImage = (req: express.Request, res: express.Response): void => {
+ try {
+ const filename = req.params.filename;
+ logger.debug(`有个小可爱正在请求${filename}噢..`);
+
+ const filePath = this.imageService.getImage(filename);
+ if (!filePath) {
+ this.sendError(res, 404, '文件不存在啦!');
+ return;
+ }
+
+ res.sendFile(filePath);
+ logger.info(`成功投递文件: ${filePath}`);
+ } catch (error) {
+ this.sendError(res, 500, '晶灵服务处理图像请求时出错..');
+ logger.error('晶灵图像请求处理失败:', error);
+ }
+ };
+
+ private sendError(res: express.Response, statusCode: number, message: string): void {
+ res.status(statusCode).json({
+ success: false,
+ error: message,
+ timestamp: new Date().toISOString(),
+ });
+ }
+}
+
+export default new ImageController();
diff --git a/src/modules/image/image.service.ts b/src/modules/image/image.service.ts
new file mode 100644
index 0000000..4d9f0f6
--- /dev/null
+++ b/src/modules/image/image.service.ts
@@ -0,0 +1,30 @@
+import path from 'path';
+import fs from 'fs';
+import paths from '../../utils/path';
+import logger from '../../utils/logger';
+
+class ImageService {
+ private readonly imageDir: string;
+
+ constructor() {
+ this.imageDir = paths.get('images');
+ logger.info(`晶灵云图数据中心初始化..数据存储在: ${this.imageDir}`);
+ }
+
+ public getImage(filename: string): string | null {
+ const filePath = path.join(this.imageDir, filename);
+ logger.debug(`尝试访问图像路径: ${filePath}`);
+
+ if (!this.isValidFilename(filename)) {
+ throw new Error('无效的文件名格式..');
+ }
+
+ return fs.existsSync(filePath) ? filePath : null;
+ }
+
+ private isValidFilename(filename: string): boolean {
+ return /^[a-zA-Z0-9_\-\.]+$/.test(filename);
+ }
+}
+
+export default ImageService;
diff --git a/src/modules/sample/sample.controller.ts b/src/modules/sample/sample.controller.ts
new file mode 100644
index 0000000..ad7f15c
--- /dev/null
+++ b/src/modules/sample/sample.controller.ts
@@ -0,0 +1,57 @@
+import express from 'express';
+import sampleService from './sample.service';
+
+class SampleController {
+ private readonly router: express.Router;
+
+ constructor() {
+ this.router = express.Router();
+ this.initializeRoutes();
+ }
+
+ public getRouter(): express.Router {
+ return this.router;
+ }
+
+ private initializeRoutes(): void {
+ this.router.get('/hello', this.getHello);
+ this.router.post('/greet', this.postGreet);
+ }
+
+ private getHello = (req: express.Request, res: express.Response): void => {
+ try {
+ const result = sampleService.getHello();
+ this.sendSuccess(res, result);
+ } catch (error) {
+ this.sendError(res, error);
+ }
+ };
+
+ private postGreet = (req: express.Request, res: express.Response): void => {
+ try {
+ const { name } = req.body;
+ const result = sampleService.generateGreeting(name);
+ this.sendSuccess(res, result);
+ } catch (error) {
+ this.sendError(res, error);
+ }
+ };
+
+ private sendSuccess(res: express.Response, data: any, statusCode = 200): void {
+ res.status(statusCode).json({
+ success: true,
+ data,
+ timestamp: new Date().toISOString(),
+ });
+ }
+
+ private sendError(res: express.Response, error: any, statusCode = 500): void {
+ res.status(statusCode).json({
+ success: false,
+ message: error.message,
+ timestamp: new Date().toISOString(),
+ });
+ }
+}
+
+export default new SampleController();
diff --git a/src/modules/sample/sample.service.ts b/src/modules/sample/sample.service.ts
new file mode 100644
index 0000000..1b63290
--- /dev/null
+++ b/src/modules/sample/sample.service.ts
@@ -0,0 +1,19 @@
+import logger from '../../utils/logger';
+
+class SampleService {
+ getHello() {
+ logger.debug(`有个小可爱正在请求GetHello方法..`);
+ return { message: 'Hello World!' };
+ }
+
+ generateGreeting(name: string) {
+ logger.debug(`有个小可爱正在请求generateGreeting方法..`);
+ if (!name) {
+ logger.warn('Name is required');
+ throw new Error('Name is required');
+ }
+ return { message: `Hello, ${name}!` };
+ }
+}
+
+export default new SampleService();
diff --git a/src/utils/config.ts b/src/utils/config.ts
new file mode 100644
index 0000000..1c9a0d5
--- /dev/null
+++ b/src/utils/config.ts
@@ -0,0 +1,23 @@
+import dotenv from 'dotenv';
+
+dotenv.config();
+
+let config = {
+ get: (key: string, defaultValue: any) => {
+ const value = process.env[key];
+ if (value === undefined) {
+ if (defaultValue !== undefined) return defaultValue;
+ throw new Error(`环境变量${key}未定义..`);
+ }
+
+ if (typeof defaultValue === 'number') return Number(value);
+ if (typeof defaultValue === 'boolean') return value === 'true';
+ return value;
+ },
+
+ set: (key: string, value: any) => {
+ process.env[key] = value;
+ },
+};
+
+export default config;
diff --git a/src/utils/date.ts b/src/utils/date.ts
new file mode 100644
index 0000000..6d1d100
--- /dev/null
+++ b/src/utils/date.ts
@@ -0,0 +1,11 @@
+let date = {
+ getCurrentDate: () => {
+ const now = new Date();
+ return `${now.getFullYear()}${(now.getMonth() + 1).toString().padStart(2, '0')}${now.getDate().toString().padStart(2, '0')}`;
+ },
+ getCurrentTime: () => {
+ return new Date().toLocaleTimeString('en-US', { hour12: false });
+ },
+};
+
+export default date;
diff --git a/src/utils/file.ts b/src/utils/file.ts
new file mode 100644
index 0000000..b9603b1
--- /dev/null
+++ b/src/utils/file.ts
@@ -0,0 +1,46 @@
+import path from 'path';
+import paths from './path';
+import date from './date';
+import fs from 'fs';
+import chalk from 'chalk';
+import logger from './logger';
+
+let fc = {
+ createDir: (targetPath: string = '', includeFile: boolean = false) => {
+ const root = paths.get('root');
+ if (path.isAbsolute(targetPath)) {
+ if (includeFile) {
+ const parentDir = path.dirname(targetPath);
+ if (!fs.existsSync(parentDir)) {
+ fs.mkdirSync(parentDir, { recursive: true });
+ logger.debug(`成功创建绝对目录: ${parentDir}`);
+ }
+ return;
+ }
+ if (!fs.existsSync(targetPath)) {
+ fs.mkdirSync(targetPath, { recursive: true });
+ logger.debug(`成功创建绝对目录: ${targetPath}`);
+ }
+ return;
+ }
+
+ const fullPath = includeFile
+ ? path.join(root, path.dirname(targetPath))
+ : path.join(root, targetPath);
+ if (!fs.existsSync(fullPath)) {
+ fs.mkdirSync(fullPath, { recursive: true });
+ logger.debug(`成功创建相对目录: ${fullPath}`);
+ }
+ },
+
+ logToFile: (level: string, message: string) => {
+ const logFile = path.join(paths.get('log'), `${date.getCurrentDate()}.log`);
+ const logMessage = `[${date.getCurrentTime()}] [${level}] ${message}\n`;
+
+ fs.appendFile(logFile, logMessage, (err) => {
+ if (err) console.error(chalk.red('[LOGGER] 写入日志失败:'), err);
+ });
+ },
+};
+
+export default fc;
diff --git a/src/utils/logger.ts b/src/utils/logger.ts
new file mode 100644
index 0000000..4f0be5f
--- /dev/null
+++ b/src/utils/logger.ts
@@ -0,0 +1,30 @@
+import chalk from 'chalk';
+import config from './config';
+import fc from './file';
+
+const logger = {
+ debug: (...args: any[]) => {
+ if (config.get('DEBUG', false)) {
+ //const message = args.join(' ');
+ console.log(chalk.cyan('[DEBUG]'), ...args);
+ //fc.logToFile('DEBUG', message);
+ }
+ },
+ info: (...args: any[]) => {
+ const message = args.join(' ');
+ console.log(chalk.green('[INFO]'), ...args);
+ fc.logToFile('INFO', message);
+ },
+ warn: (...args: any[]) => {
+ const message = args.join(' ');
+ console.log(chalk.yellow('[WARN]'), ...args);
+ fc.logToFile('WARN', message);
+ },
+ error: (...args: any[]) => {
+ const message = args.join(' ');
+ console.log(chalk.red('[ERROR]'), ...args);
+ fc.logToFile('ERROR', message);
+ },
+};
+
+export default logger;
diff --git a/src/utils/path.ts b/src/utils/path.ts
new file mode 100644
index 0000000..a84feaa
--- /dev/null
+++ b/src/utils/path.ts
@@ -0,0 +1,24 @@
+import path from 'path';
+
+const paths = {
+ get: (value?: string) => {
+ switch (value) {
+ case 'root':
+ return path.join(__dirname, '..');
+ case 'public':
+ return path.join(__dirname, '../public');
+ case 'images':
+ return path.join(__dirname, '../../public/images/');
+ case 'log':
+ return path.join(__dirname, '../../logs');
+ default:
+ return path.join(__dirname, '..');
+ }
+ },
+
+ resolve: (segments: string) => {
+ return path.join(__dirname, segments);
+ },
+};
+
+export default paths;
diff --git a/src/utils/tool.ts b/src/utils/tool.ts
new file mode 100644
index 0000000..e69de29
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..1efdceb
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,12 @@
+{
+ "compilerOptions": {
+ "target": "es2016",
+ "module": "commonjs",
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "strict": true,
+ "skipLibCheck": true,
+ "outDir": "dist"
+ },
+ "include": ["src"]
+}