12 Commits

31 changed files with 2522 additions and 2094 deletions

7
.dockerignore Normal file
View File

@ -0,0 +1,7 @@
.*
!.npmrc
!.swcrc
build
coverage
node_modules
Dockerfile

View File

@ -1,3 +1,4 @@
COMPOSE_PROJECT_NAME=thream-file-uploads-api
API_KEY=apiKeySecret API_KEY=apiKeySecret
API_URL=http://localhost:8000 API_URL=http://localhost:8000
HOST=0.0.0.0 HOST=0.0.0.0

View File

@ -1,12 +1,10 @@
{ {
"extends": ["conventions", "prettier"], "extends": ["conventions", "prettier"],
"plugins": ["prettier", "import", "unicorn"], "plugins": ["prettier", "import", "unicorn"],
"parser": "@typescript-eslint/parser",
"parserOptions": { "parserOptions": {
"project": "./tsconfig.json" "project": "./tsconfig.json"
}, },
"env": {
"node": true
},
"rules": { "rules": {
"prettier/prettier": "error", "prettier/prettier": "error",
"import/extensions": ["error", "always"], "import/extensions": ["error", "always"],

View File

@ -10,12 +10,12 @@ jobs:
build: build:
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- uses: 'actions/checkout@v3.5.2' - uses: 'actions/checkout@v4.0.0'
- name: 'Setup Node.js' - name: 'Setup Node.js'
uses: 'actions/setup-node@v3.6.0' uses: 'actions/setup-node@v3.8.1'
with: with:
node-version: '18.x' node-version: '20.x'
cache: 'npm' cache: 'npm'
- name: 'Install dependencies' - name: 'Install dependencies'

View File

@ -10,12 +10,12 @@ jobs:
lint: lint:
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- uses: 'actions/checkout@v3.5.2' - uses: 'actions/checkout@v4.0.0'
- name: 'Setup Node.js' - name: 'Setup Node.js'
uses: 'actions/setup-node@v3.6.0' uses: 'actions/setup-node@v3.8.1'
with: with:
node-version: '18.x' node-version: '20.x'
cache: 'npm' cache: 'npm'
- name: 'Install dependencies' - name: 'Install dependencies'
@ -37,6 +37,6 @@ jobs:
run: 'npm run lint:prettier' run: 'npm run lint:prettier'
- name: 'lint:dotenv' - name: 'lint:dotenv'
uses: 'dotenv-linter/action-dotenv-linter@v2' uses: 'dotenv-linter/action-dotenv-linter@v2.18.0'
with: with:
github_token: ${{ secrets.github_token }} github_token: ${{ secrets.github_token }}

View File

@ -8,22 +8,22 @@ jobs:
release: release:
runs-on: 'ubuntu-latest' runs-on: 'ubuntu-latest'
steps: steps:
- uses: 'actions/checkout@v3.5.2' - uses: 'actions/checkout@v4.0.0'
with: with:
fetch-depth: 0 fetch-depth: 0
persist-credentials: false persist-credentials: false
- name: 'Import GPG key' - name: 'Import GPG key'
uses: 'crazy-max/ghaction-import-gpg@v5.3.0' uses: 'crazy-max/ghaction-import-gpg@v6.0.0'
with: with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
git_user_signingkey: true git_user_signingkey: true
git_commit_gpgsign: true git_commit_gpgsign: true
- name: 'Setup Node.js' - name: 'Setup Node.js'
uses: 'actions/setup-node@v3.6.0' uses: 'actions/setup-node@v3.8.1'
with: with:
node-version: '18.x' node-version: '20.x'
cache: 'npm' cache: 'npm'
- name: 'Install dependencies' - name: 'Install dependencies'

15
.swcrc
View File

@ -1,22 +1,13 @@
{ {
"sourceMaps": true,
"jsc": { "jsc": {
"parser": { "parser": {
"syntax": "typescript", "syntax": "typescript",
"decorators": true,
"dynamicImport": true "dynamicImport": true
}, },
"transform": { "target": "esnext"
"legacyDecorator": true,
"decoratorMetadata": true
},
"target": "es2022",
"loose": true
}, },
"module": { "module": {
"type": "es6", "type": "es6"
"strict": false,
"strictMode": true,
"lazy": false,
"noInterop": false
} }
} }

View File

@ -60,7 +60,7 @@ representative at an online or offline event.
Instances of abusive, harassing, or otherwise unacceptable behavior may be Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at reported to the community leaders responsible for enforcement at
<contact@divlo.fr>. <contact@theoludwig.fr>.
All complaints will be reviewed and investigated promptly and fairly. All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the All community leaders are obligated to respect the privacy and security of the

26
Dockerfile Normal file
View File

@ -0,0 +1,26 @@
FROM node:20.6.1 AS builder-dependencies
WORKDIR /usr/src/application
COPY ./package*.json ./
RUN npm clean-install
FROM node:20.6.1 AS runner-dependencies
WORKDIR /usr/src/application
ENV NODE_ENV=production
COPY ./package*.json ./
RUN npm clean-install --omit=dev --ignore-scripts
FROM node:20.6.1 AS builder
WORKDIR /usr/src/application
COPY --from=builder-dependencies /usr/src/application/node_modules ./node_modules
COPY ./ ./
RUN npm run build
FROM gcr.io/distroless/nodejs20-debian11:latest AS runner
WORKDIR /usr/src/application
ENV NODE_ENV=production
ENV NODE_OPTIONS=--enable-source-maps
COPY --from=runner-dependencies /usr/src/application/node_modules ./node_modules
COPY --from=builder /usr/src/application/package.json ./package.json
COPY --from=builder /usr/src/application/build ./build
COPY --from=builder /usr/src/application/uploads ./uploads
CMD ["./build/index.js"]

View File

@ -1,4 +1,4 @@
<h1 align="center"><a href="https://file-uploads-api.thream.divlo.fr/documentation">Thream/file-uploads-api</a></h1> <h1 align="center"><a href="https://file-uploads-api.thream.theoludwig.fr/documentation">Thream/file-uploads-api</a></h1>
<p align="center"> <p align="center">
<a href="./CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" /></a> <a href="./CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" /></a>
@ -27,7 +27,7 @@ Thream's application programming interface (API) to upload files.
```sh ```sh
# Clone the repository # Clone the repository
git clone https://github.com/Thream/file-uploads-api.git git clone git@github.com:Thream/file-uploads-api.git
# Go to the project root # Go to the project root
cd file-uploads-api cd file-uploads-api
@ -50,7 +50,13 @@ npm run dev
#### Services started #### Services started
- `file-uploads-api`: <http://localhost:8000> - `file-uploads-api`: <http://127.0.0.1:8000>
### Production environment (with [Docker](https://www.docker.com/))
```sh
docker compose up --build
```
## 💡 Contributing ## 💡 Contributing

11
compose.yaml Normal file
View File

@ -0,0 +1,11 @@
services:
thream-file-uploads-api:
container_name: ${COMPOSE_PROJECT_NAME}
image: 'thream-file-uploads-api'
restart: 'unless-stopped'
network_mode: 'host'
build:
context: './'
env_file: '.env'
volumes:
- './uploads:/usr/src/application/uploads'

4324
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,12 @@
{ {
"name": "@thream/file-uploads-api", "name": "@thream/file-uploads-api",
"version": "1.1.4", "version": "1.1.7",
"description": "Thream's application programming interface to upload files.", "description": "Thream's application programming interface to upload files.",
"private": true, "private": true,
"type": "module", "type": "module",
"imports": {
"#src/*": "./build/*"
},
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/Thream/file-uploads-api" "url": "https://github.com/Thream/file-uploads-api"
@ -16,63 +19,63 @@
"build": "rimraf ./build && swc ./src --out-dir ./build", "build": "rimraf ./build && swc ./src --out-dir ./build",
"build:dev": "swc ./src --out-dir ./build --watch", "build:dev": "swc ./src --out-dir ./build --watch",
"build:typescript": "tsc", "build:typescript": "tsc",
"start": "node build/index.js", "start": "node --enable-source-maps build/index.js",
"dev": "concurrently -k -n \"TypeScript,Node\" -p \"[{name}]\" -c \"blue,green\" \"npm run build:dev\" \"cross-env NODE_ENV=development nodemon build/index.js\"", "dev": "concurrently -k -n \"TypeScript,Node\" -p \"[{name}]\" -c \"blue,green\" \"npm run build:dev\" \"cross-env NODE_ENV=development node --watch --enable-source-maps build/index.js\"",
"lint:commit": "commitlint", "lint:commit": "commitlint",
"lint:editorconfig": "editorconfig-checker", "lint:editorconfig": "editorconfig-checker",
"lint:markdown": "markdownlint-cli2", "lint:markdown": "markdownlint-cli2",
"lint:eslint": "eslint \".\" --ignore-path \".gitignore\"", "lint:eslint": "eslint . --max-warnings 0 --report-unused-disable-directives --ignore-path .gitignore",
"lint:prettier": "prettier \".\" --check --ignore-path \".gitignore\"", "lint:prettier": "prettier . --check",
"lint:staged": "lint-staged", "lint:staged": "lint-staged",
"release": "semantic-release", "release": "semantic-release",
"postinstall": "husky install" "postinstall": "husky install"
}, },
"dependencies": { "dependencies": {
"@fastify/cors": "8.2.1", "@fastify/cors": "8.3.0",
"@fastify/helmet": "10.1.1", "@fastify/helmet": "11.1.1",
"@fastify/multipart": "7.6.0", "@fastify/multipart": "7.7.3",
"@fastify/rate-limit": "8.0.0", "@fastify/rate-limit": "8.0.3",
"@fastify/sensible": "5.2.0", "@fastify/sensible": "5.3.0",
"@fastify/static": "6.10.1", "@fastify/static": "6.11.2",
"@fastify/swagger": "8.3.1", "@fastify/swagger": "8.10.0",
"@fastify/swagger-ui": "1.8.1", "@fastify/swagger-ui": "1.9.3",
"@sinclair/typebox": "0.28.10", "@sinclair/typebox": "0.31.15",
"dotenv": "16.0.3", "dotenv": "16.3.1",
"fastify": "4.17.0", "fastify": "4.23.2",
"fastify-plugin": "4.5.0", "fastify-plugin": "4.5.1",
"http-errors": "2.0.0", "http-errors": "2.0.0",
"read-pkg": "8.0.0" "read-pkg": "8.1.0"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "17.6.3", "@commitlint/cli": "17.7.1",
"@commitlint/config-conventional": "17.6.3", "@commitlint/config-conventional": "17.7.0",
"@saithodev/semantic-release-backmerge": "3.2.0", "@saithodev/semantic-release-backmerge": "3.2.0",
"@semantic-release/git": "10.0.1", "@semantic-release/git": "10.0.1",
"@swc/cli": "0.1.62", "@swc/cli": "0.1.62",
"@swc/core": "1.3.57", "@swc/core": "1.3.85",
"@tsconfig/strictest": "2.0.1", "@tsconfig/strictest": "2.0.2",
"@types/busboy": "1.5.0", "@types/busboy": "1.5.1",
"@types/http-errors": "2.0.1", "@types/http-errors": "2.0.2",
"@types/node": "20.1.4", "@types/node": "20.6.2",
"@typescript-eslint/eslint-plugin": "5.59.5", "@typescript-eslint/eslint-plugin": "6.7.2",
"concurrently": "8.0.1", "chokidar": "3.5.3",
"concurrently": "8.2.1",
"cross-env": "7.0.3", "cross-env": "7.0.3",
"editorconfig-checker": "5.0.1", "editorconfig-checker": "5.1.1",
"eslint": "8.40.0", "eslint": "8.49.0",
"eslint-config-conventions": "9.0.0", "eslint-config-conventions": "11.0.1",
"eslint-config-prettier": "8.8.0", "eslint-config-prettier": "9.0.0",
"eslint-plugin-import": "2.27.5", "eslint-plugin-import": "2.28.1",
"eslint-plugin-prettier": "4.2.1", "eslint-plugin-prettier": "5.0.0",
"eslint-plugin-promise": "6.1.1", "eslint-plugin-promise": "6.1.1",
"eslint-plugin-unicorn": "47.0.0", "eslint-plugin-unicorn": "48.0.1",
"husky": "8.0.3", "husky": "8.0.3",
"lint-staged": "13.2.2", "lint-staged": "14.0.1",
"markdownlint-cli2": "0.7.1", "markdownlint-cli2": "0.10.0",
"markdownlint-rule-relative-links": "1.2.0", "markdownlint-rule-relative-links": "2.1.0",
"nodemon": "2.0.22", "prettier": "3.0.3",
"prettier": "2.8.8", "rimraf": "5.0.1",
"rimraf": "5.0.0", "semantic-release": "21.1.2",
"semantic-release": "21.0.2", "typescript": "5.2.2"
"typescript": "5.0.4"
} }
} }

View File

@ -11,8 +11,8 @@ import fastifySensible from '@fastify/sensible'
import fastifyStatic from '@fastify/static' import fastifyStatic from '@fastify/static'
import { readPackage } from 'read-pkg' import { readPackage } from 'read-pkg'
import { services } from './services/index.js' import { services } from '#src/services/index.js'
import { UPLOADS_URL } from './tools/configurations.js' import { UPLOADS_URL } from '#src/tools/configurations.js'
dotenv.config() dotenv.config()
const packageJSON = await readPackage() const packageJSON = await readPackage()

View File

@ -1,8 +1,8 @@
import { application } from './application.js' import { application } from '#src/application.js'
import { HOST, PORT } from './tools/configurations.js' import { HOST, PORT } from '#src/tools/configurations.js'
const address = await application.listen({ const address = await application.listen({
port: PORT, port: PORT,
host: HOST host: HOST
}) })
console.log('\u001B[36m%s\u001B[0m', `🚀 Server listening at ${address}`) console.log(`Server listening at ${address}`)

View File

@ -1,6 +1,6 @@
import type { FastifyPluginAsync } from 'fastify' import type { FastifyPluginAsync } from 'fastify'
import { uploadsService } from './uploads/index.js' import { uploadsService } from '#src/services/uploads/index.js'
export const services: FastifyPluginAsync = async (fastify) => { export const services: FastifyPluginAsync = async (fastify) => {
await fastify.register(uploadsService) await fastify.register(uploadsService)

View File

@ -1,13 +1,13 @@
import type { FastifyPluginAsync, FastifySchema } from 'fastify' import type { FastifyPluginAsync, FastifySchema } from 'fastify'
import { Type } from '@sinclair/typebox' import { Type } from '@sinclair/typebox'
import { fastifyErrors } from '../../../models/utils.js' import { fastifyErrors } from '#src/models/utils.js'
import verifyAPIKey from '../../../tools/plugins/verifyAPIKey.js' import verifyAPIKey from '#src/tools/plugins/verifyAPIKey.js'
import type { DeleteParameters } from '../../../tools/utils/deleteUploadedFile.js' import type { DeleteParameters } from '#src/tools/utils/deleteUploadedFile.js'
import { import {
deleteParameters, deleteParameters,
deleteUploadedFile deleteUploadedFile
} from '../../../tools/utils/deleteUploadedFile.js' } from '#src/tools/utils/deleteUploadedFile.js'
export const deleteServiceSchema: FastifySchema = { export const deleteServiceSchema: FastifySchema = {
tags: ['guilds'] as string[], tags: ['guilds'] as string[],

View File

@ -4,7 +4,7 @@ import type { FastifyPluginAsync, FastifySchema } from 'fastify'
import type { Static } from '@sinclair/typebox' import type { Static } from '@sinclair/typebox'
import { Type } from '@sinclair/typebox' import { Type } from '@sinclair/typebox'
import { fastifyErrors } from '../../../models/utils.js' import { fastifyErrors } from '#src/models/utils.js'
const parameters = Type.Object({ const parameters = Type.Object({
file: Type.String() file: Type.String()

View File

@ -2,13 +2,13 @@ import { Type } from '@sinclair/typebox'
import type { FastifyPluginAsync, FastifySchema } from 'fastify' import type { FastifyPluginAsync, FastifySchema } from 'fastify'
import fastifyMultipart from '@fastify/multipart' import fastifyMultipart from '@fastify/multipart'
import { fastifyErrors } from '../../../models/utils.js' import { fastifyErrors } from '#src/models/utils.js'
import { uploadFile } from '../../../tools/utils/uploadFile.js' import { uploadFile } from '#src/tools/utils/uploadFile.js'
import { import {
MAXIMUM_IMAGE_SIZE, MAXIMUM_IMAGE_SIZE,
SUPPORTED_IMAGE_MIMETYPE SUPPORTED_IMAGE_MIMETYPE
} from '../../../tools/configurations.js' } from '#src/tools/configurations.js'
import verifyAPIKey from '../../../tools/plugins/verifyAPIKey.js' import verifyAPIKey from '#src/tools/plugins/verifyAPIKey.js'
const postServiceSchema: FastifySchema = { const postServiceSchema: FastifySchema = {
description: 'Uploads guild icon', description: 'Uploads guild icon',

View File

@ -1,14 +1,14 @@
import type { FastifyPluginAsync } from 'fastify' import type { FastifyPluginAsync } from 'fastify'
import { deleteGuildsUploadsService } from './guilds/delete.js' import { deleteGuildsUploadsService } from '#src/services/uploads/guilds/delete.js'
import { getGuildsUploadsService } from './guilds/get.js' import { getGuildsUploadsService } from '#src/services/uploads/guilds/get.js'
import { postGuildsUploadsIconService } from './guilds/post.js' import { postGuildsUploadsIconService } from '#src/services/uploads/guilds/post.js'
import { deleteMessagesUploadsService } from './messages/delete.js' import { deleteMessagesUploadsService } from '#src/services/uploads/messages/delete.js'
import { getMessagesUploadsService } from './messages/get.js' import { getMessagesUploadsService } from '#src/services/uploads/messages/get.js'
import { postMessagesUploadsService } from './messages/post.js' import { postMessagesUploadsService } from '#src/services/uploads/messages/post.js'
import { deleteUsersUploadsService } from './users/delete.js' import { deleteUsersUploadsService } from '#src/services/uploads/users/delete.js'
import { getUsersUploadsService } from './users/get.js' import { getUsersUploadsService } from '#src/services/uploads/users/get.js'
import { postUsersUploadsLogoService } from './users/post.js' import { postUsersUploadsLogoService } from '#src/services/uploads/users/post.js'
export const uploadsService: FastifyPluginAsync = async (fastify) => { export const uploadsService: FastifyPluginAsync = async (fastify) => {
await fastify.register(deleteGuildsUploadsService) await fastify.register(deleteGuildsUploadsService)

View File

@ -1,13 +1,13 @@
import type { FastifyPluginAsync, FastifySchema } from 'fastify' import type { FastifyPluginAsync, FastifySchema } from 'fastify'
import { Type } from '@sinclair/typebox' import { Type } from '@sinclair/typebox'
import { fastifyErrors } from '../../../models/utils.js' import { fastifyErrors } from '#src/models/utils.js'
import verifyAPIKey from '../../../tools/plugins/verifyAPIKey.js' import verifyAPIKey from '#src/tools/plugins/verifyAPIKey.js'
import type { DeleteParameters } from '../../../tools/utils/deleteUploadedFile.js' import type { DeleteParameters } from '#src/tools/utils/deleteUploadedFile.js'
import { import {
deleteParameters, deleteParameters,
deleteUploadedFile deleteUploadedFile
} from '../../../tools/utils/deleteUploadedFile.js' } from '#src/tools/utils/deleteUploadedFile.js'
export const deleteServiceSchema: FastifySchema = { export const deleteServiceSchema: FastifySchema = {
tags: ['messages'] as string[], tags: ['messages'] as string[],

View File

@ -4,7 +4,7 @@ import type { FastifyPluginAsync, FastifySchema } from 'fastify'
import type { Static } from '@sinclair/typebox' import type { Static } from '@sinclair/typebox'
import { Type } from '@sinclair/typebox' import { Type } from '@sinclair/typebox'
import { fastifyErrors } from '../../../models/utils.js' import { fastifyErrors } from '#src/models/utils.js'
const parameters = Type.Object({ const parameters = Type.Object({
file: Type.String() file: Type.String()

View File

@ -2,10 +2,10 @@ import { Type } from '@sinclair/typebox'
import type { FastifyPluginAsync, FastifySchema } from 'fastify' import type { FastifyPluginAsync, FastifySchema } from 'fastify'
import fastifyMultipart from '@fastify/multipart' import fastifyMultipart from '@fastify/multipart'
import { fastifyErrors } from '../../../models/utils.js' import { fastifyErrors } from '#src/models/utils.js'
import { uploadFile } from '../../../tools/utils/uploadFile.js' import { uploadFile } from '#src/tools/utils/uploadFile.js'
import { MAXIMUM_IMAGE_SIZE } from '../../../tools/configurations.js' import { MAXIMUM_IMAGE_SIZE } from '#src/tools/configurations.js'
import verifyAPIKey from '../../../tools/plugins/verifyAPIKey.js' import verifyAPIKey from '#src/tools/plugins/verifyAPIKey.js'
const postServiceSchema: FastifySchema = { const postServiceSchema: FastifySchema = {
description: 'Uploads message file', description: 'Uploads message file',

View File

@ -1,13 +1,13 @@
import type { FastifyPluginAsync, FastifySchema } from 'fastify' import type { FastifyPluginAsync, FastifySchema } from 'fastify'
import { Type } from '@sinclair/typebox' import { Type } from '@sinclair/typebox'
import { fastifyErrors } from '../../../models/utils.js' import { fastifyErrors } from '#src/models/utils.js'
import verifyAPIKey from '../../../tools/plugins/verifyAPIKey.js' import verifyAPIKey from '#src/tools/plugins/verifyAPIKey.js'
import type { DeleteParameters } from '../../../tools/utils/deleteUploadedFile.js' import type { DeleteParameters } from '#src/tools/utils/deleteUploadedFile.js'
import { import {
deleteParameters, deleteParameters,
deleteUploadedFile deleteUploadedFile
} from '../../../tools/utils/deleteUploadedFile.js' } from '#src/tools/utils/deleteUploadedFile.js'
export const deleteServiceSchema: FastifySchema = { export const deleteServiceSchema: FastifySchema = {
tags: ['users'] as string[], tags: ['users'] as string[],

View File

@ -4,7 +4,7 @@ import type { FastifyPluginAsync, FastifySchema } from 'fastify'
import type { Static } from '@sinclair/typebox' import type { Static } from '@sinclair/typebox'
import { Type } from '@sinclair/typebox' import { Type } from '@sinclair/typebox'
import { fastifyErrors } from '../../../models/utils.js' import { fastifyErrors } from '#src/models/utils.js'
const parameters = Type.Object({ const parameters = Type.Object({
file: Type.String() file: Type.String()

View File

@ -2,13 +2,13 @@ import { Type } from '@sinclair/typebox'
import type { FastifyPluginAsync, FastifySchema } from 'fastify' import type { FastifyPluginAsync, FastifySchema } from 'fastify'
import fastifyMultipart from '@fastify/multipart' import fastifyMultipart from '@fastify/multipart'
import { fastifyErrors } from '../../../models/utils.js' import { fastifyErrors } from '#src/models/utils.js'
import { uploadFile } from '../../../tools/utils/uploadFile.js' import { uploadFile } from '#src/tools/utils/uploadFile.js'
import { import {
MAXIMUM_IMAGE_SIZE, MAXIMUM_IMAGE_SIZE,
SUPPORTED_IMAGE_MIMETYPE SUPPORTED_IMAGE_MIMETYPE
} from '../../../tools/configurations.js' } from '#src/tools/configurations.js'
import verifyAPIKey from '../../../tools/plugins/verifyAPIKey.js' import verifyAPIKey from '#src/tools/plugins/verifyAPIKey.js'
const postServiceSchema: FastifySchema = { const postServiceSchema: FastifySchema = {
description: 'Uploads user logo', description: 'Uploads user logo',

View File

@ -4,7 +4,7 @@ import dotenv from 'dotenv'
dotenv.config() dotenv.config()
export const PORT = parseInt(process.env['PORT'] ?? '8000', 10) export const PORT = Number.parseInt(process.env['PORT'] ?? '8000', 10)
export const HOST = process.env['HOST'] ?? '0.0.0.0' export const HOST = process.env['HOST'] ?? '0.0.0.0'
export const API_URL = process.env['API_URL'] ?? `http://${HOST}:${PORT}` export const API_URL = process.env['API_URL'] ?? `http://${HOST}:${PORT}`
export const API_KEY = process.env['API_KEY'] ?? 'apiKeySecret' export const API_KEY = process.env['API_KEY'] ?? 'apiKeySecret'

View File

@ -1,7 +1,7 @@
import fastifyPlugin from 'fastify-plugin' import fastifyPlugin from 'fastify-plugin'
import httpErrors from 'http-errors' import httpErrors from 'http-errors'
import { API_KEY } from '../configurations.js' import { API_KEY } from '#src/tools/configurations.js'
const { Unauthorized, Forbidden } = httpErrors const { Unauthorized, Forbidden } = httpErrors
@ -13,8 +13,8 @@ declare module 'fastify' {
export default fastifyPlugin( export default fastifyPlugin(
async (fastify) => { async (fastify) => {
await fastify.decorateRequest('apiKey', null) fastify.decorateRequest('apiKey', undefined)
await fastify.addHook('onRequest', async (request) => { fastify.addHook('onRequest', async (request) => {
const apiKey = request.headers['x-api-key'] const apiKey = request.headers['x-api-key']
if (apiKey == null || typeof apiKey !== 'string') { if (apiKey == null || typeof apiKey !== 'string') {
throw new Unauthorized() throw new Unauthorized()

View File

@ -12,7 +12,7 @@ import type {
FastifyTypeProviderDefault FastifyTypeProviderDefault
} from 'fastify' } from 'fastify'
import { isExistingFile } from './isExistingFile.js' import { isExistingFile } from '#src/tools/utils/isExistingFile.js'
export const deleteParameters = Type.Object({ export const deleteParameters = Type.Object({
file: Type.String() file: Type.String()

View File

@ -5,7 +5,7 @@ import { randomUUID } from 'node:crypto'
import type { FastifyInstance, FastifyRequest } from 'fastify' import type { FastifyInstance, FastifyRequest } from 'fastify'
import type { SavedMultipartFile } from '@fastify/multipart' import type { SavedMultipartFile } from '@fastify/multipart'
import { API_URL, ROOT_URL } from '../configurations.js' import { API_URL, ROOT_URL } from '#src/tools/configurations.js'
export interface UploadFileOptions { export interface UploadFileOptions {
folderInUploadsFolder: 'guilds' | 'messages' | 'users' folderInUploadsFolder: 'guilds' | 'messages' | 'users'
@ -42,6 +42,7 @@ export const uploadFile = async (
} }
}) })
} catch (error) { } catch (error) {
console.error(error)
throw fastify.httpErrors.requestHeaderFieldsTooLarge( throw fastify.httpErrors.requestHeaderFieldsTooLarge(
`File should be less than ${maximumFileSize}mb.` `File should be less than ${maximumFileSize}mb.`
) )

View File

@ -2,11 +2,15 @@
"extends": "@tsconfig/strictest/tsconfig.json", "extends": "@tsconfig/strictest/tsconfig.json",
"compilerOptions": { "compilerOptions": {
"target": "ESNext", "target": "ESNext",
"module": "ESNext",
"lib": ["ESNext"], "lib": ["ESNext"],
"moduleResolution": "node", "module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "./build", "outDir": "./build",
"rootDir": "./src", "rootDir": "./src",
"baseUrl": ".",
"paths": {
"#src/*": ["./src/*"]
},
"noEmit": true, "noEmit": true,
"exactOptionalPropertyTypes": false, "exactOptionalPropertyTypes": false,
"checkJs": false "checkJs": false