diff --git a/README.md b/README.md index fafc876..0cf0a6d 100644 --- a/README.md +++ b/README.md @@ -1 +1,487 @@ -# games-api \ No newline at end of file +# Games API + +A RESTful API and WebSocket service for managing game logs across multiple game types. This service provides endpoints for logging game events and retrieving game history, with real-time WebSocket support for receiving game logs from external brokers. + +## Table of Contents + +- [Features](#features) +- [Supported Games](#supported-games) +- [Tech Stack](#tech-stack) +- [Prerequisites](#prerequisites) +- [Installation](#installation) +- [Configuration](#configuration) +- [Usage](#usage) +- [API Endpoints](#api-endpoints) +- [WebSocket Integration](#websocket-integration) +- [Project Structure](#project-structure) +- [Development](#development) +- [Docker](#docker) +- [Scripts](#scripts) +- [Contributing](#contributing) +- [License](#license) + +## Features + +- 🎮 **Multi-Game Support**: Logs and manages data for multiple game types +- 📊 **Game Logging**: RESTful API for creating and retrieving game logs +- 🔌 **WebSocket Client**: Real-time log ingestion from external message brokers +- 🗄️ **MongoDB Integration**: Automatic collection creation per game type +- 🐳 **Docker Support**: Containerized deployment with Docker and Docker Compose +- 🔄 **Auto-Reconnection**: WebSocket client automatically reconnects on connection loss +- 📝 **TypeScript**: Fully typed codebase for better developer experience + +## Supported Games + +The API currently supports the following games: + +| Game Key | Game Name | Min Players | Max Players | +| -------- | ------------------- | ----------- | ----------- | +| `NBT` | Naval Battle | 2 | 2 | +| `RPS` | Rock Paper Scissors | 2 | 2 | +| `QTT` | Quick Tac Toe | 2 | 2 | +| `CNW` | Carnaval World | 2 | 10 | +| `PNP` | Planning Poker | 2 | 20 | + +## Tech Stack + +- **Runtime**: Node.js 20.x +- **Language**: TypeScript +- **Framework**: Express.js +- **Database**: MongoDB +- **WebSocket**: ws (WebSocket library) +- **Caching**: Redis (configured but optional) +- **Package Manager**: Yarn +- **Containerization**: Docker + +## Prerequisites + +- Node.js 20.x +- Yarn package manager +- MongoDB instance (local or remote) +- (Optional) Redis instance for caching +- (Optional) WebSocket broker for real-time log ingestion + +## Installation + +1. **Clone the repository**: + ```bash + git clone https://github.com/pedrodarma/games-api.git + cd games-api + ``` + +2. **Install dependencies**: + ```bash + yarn install + ``` + Or use the installation script: + ```bash + ./_install.sh + ``` + +3. **Set up environment variables** (see [Configuration](#configuration)) + +4. **Build the project**: + ```bash + yarn build + ``` + +5. **Start the server**: + ```bash + yarn start + ``` + +For development with hot-reload: +```bash +yarn dev +``` + +## Configuration + +Create a `.env` file in the root directory with the following variables: + +```env +# Server Configuration +PORT=8060 +NODE_ENV=production + +# MongoDB Configuration +MONGODB=mongodb://username:password@host:port/databaseName + +# WebSocket Broker Configuration +BROKER_URL=ws://your-broker-url:port + +# Redis Configuration (Optional) +REDIS_HOST=localhost +REDIS_PORT=6379 +REDIS_USERNAME=admin +REDIS_PASSWORD=default +``` + +### Environment Variables + +| Variable | Description | Default | Required | +| ---------------- | ---------------------- | --------- | ---------------------------- | +| `PORT` | Server port | `8060` | No | +| `NODE_ENV` | Environment mode | - | No | +| `MONGODB` | MongoDB connection URI | - | Yes | +| `BROKER_URL` | WebSocket broker URL | - | Yes (for WebSocket features) | +| `REDIS_HOST` | Redis host | `redis` | No | +| `REDIS_PORT` | Redis port | `1118` | No | +| `REDIS_USERNAME` | Redis username | `admin` | No | +| `REDIS_PASSWORD` | Redis password | `default` | No | + +## Usage + +### Starting the Server + +**Development mode** (with hot-reload): +```bash +yarn dev +``` + +**Production mode**: +```bash +yarn build +yarn start +``` + +The server will start on the port specified in your `.env` file (default: `8060`). + +### Health Check + +Verify the server is running: +```bash +curl http://localhost:8060/healthcheck +``` + +## API Endpoints + +### Base URL +``` +http://localhost:8060 +``` + +### Endpoints + +#### `GET /` +Returns a simple greeting message. + +**Response:** +``` +Games API +``` + +--- + +#### `GET /healthcheck` +Health check endpoint to verify server status. + +**Response:** +- Status: `200 OK` + +--- + +#### `POST /log/:gameKey` +Creates a new game log entry. + +**Parameters:** +- `gameKey` (path parameter): One of the supported game keys (`NBT`, `RPS`, `QTT`, `CNW`, `PNP`) + +**Request Body:** +```json +{ + "hash": "unique-game-hash", + "status": "completed", + "startedAt": "2024-01-01T00:00:00.000Z", + "finishedAt": "2024-01-01T00:30:00.000Z", + // ... game-specific fields +} +``` + +**Response:** +- **201 Created**: Log entry created successfully + ```json + { + "message": "Log entry created successfully" + } + ``` +- **400 Bad Request**: Game key is required +- **500 Internal Server Error**: Failed to create log entry + +**Example:** +```bash +curl -X POST http://localhost:8060/log/QTT \ + -H "Content-Type: application/json" \ + -d '{ + "hash": "game-123", + "status": "completed", + "startedAt": "2024-01-01T00:00:00.000Z", + "type": "standard", + "mode": "online", + "playerXId": "player-1", + "playerOId": "player-2" + }' +``` + +--- + +#### `GET /logs/:gameKey` +Retrieves all logs for a specific game. + +**Parameters:** +- `gameKey` (path parameter): One of the supported game keys + +**Response:** +- **200 OK**: Array of log entries + ```json + [ + { + "_id": "...", + "hash": "game-123", + "status": "completed", + "createdAt": "2024-01-01T00:00:00.000Z", + // ... other fields + } + ] + ``` +- **400 Bad Request**: Game key is required +- **500 Internal Server Error**: Internal server error + +**Example:** +```bash +curl http://localhost:8060/logs/QTT +``` + +## WebSocket Integration + +The API includes a WebSocket client that connects to an external message broker to receive game logs in real-time. + +### WebSocket Client Features + +- **Auto-Connection**: Automatically connects to the broker on server startup +- **Auto-Reconnection**: Automatically reconnects after connection loss (5-second delay) +- **Message Handling**: Processes different message types: + - `log`: Stores game logs in MongoDB + - `event`: Handles server registration events + - `ping/pong`: Heartbeat mechanism + +### WebSocket Message Format + +```typescript +{ + type: 'log' | 'chat' | 'command' | 'event' | 'action' | 'registered', + from: string, + to?: string, + data: { + // Game log data or other message data + gameKey: string, + hash: string, + status: string, + // ... other fields + } +} +``` + +### Configuration + +Set the `BROKER_URL` environment variable to enable WebSocket functionality: +```env +BROKER_URL=ws://your-broker-url:port +``` + +The client connects to: `{BROKER_URL}/logs` + +## Project Structure + +``` +games-api/ +├── src/ +│ ├── _constants/ # Game constants and configurations +│ │ ├── _continents.ts +│ │ ├── _countries.ts +│ │ ├── _games.ts # Game definitions +│ │ └── index.ts +│ ├── contollers/ # Request handlers +│ │ ├── logs/ +│ │ │ ├── logs.controller.ts +│ │ │ └── index.ts +│ │ └── index.ts +│ ├── databases/ # Database connections +│ │ ├── mongodb/ +│ │ │ ├── mongodb.ts +│ │ │ └── index.ts +│ │ └── index.ts +│ ├── models/ # Data models +│ │ ├── game.model.ts +│ │ ├── log.model.ts +│ │ ├── log-quicktactoe.model.ts +│ │ ├── websocket-message.model.ts +│ │ └── index.ts +│ ├── repositories/ # Data access layer +│ │ ├── logs/ +│ │ │ ├── logs.repository.ts +│ │ │ └── index.ts +│ │ └── index.ts +│ ├── utils/ # Utility functions +│ │ ├── id.utils.ts +│ │ └── index.ts +│ ├── websocket/ # WebSocket client +│ │ ├── websocket.ts +│ │ └── index.ts +│ └── routes.ts # API routes +├── _scripts/ # Utility scripts +│ ├── get_version_local.sh +│ ├── get_version_remote.sh +│ ├── post-commit +│ ├── pre-commit +│ ├── update_git_hooks.sh +│ └── upgrade_version.sh +├── _build.sh # Build script +├── _install.sh # Installation script +├── _prepare.sh # Preparation script +├── docker-compose.yml # Docker Compose configuration +├── Dockerfile # Docker image definition +├── index.ts # Application entry point +├── package.json # Dependencies and scripts +├── tsconfig.json # TypeScript configuration +└── README.md # This file +``` + +## Development + +### Development Scripts + +```bash +# Start development server with hot-reload +yarn dev + +# Build for production +yarn build + +# Run linter +yarn lint + +# Fix linting issues +yarn lint:fix + +# Type checking +yarn typecheck +``` + +### Code Structure + +- **Controllers**: Handle HTTP requests and responses +- **Repositories**: Abstract database operations +- **Models**: Define data structures and interfaces +- **WebSocket**: Manages real-time connections +- **Utils**: Shared utility functions + +### TypeScript Path Aliases + +The project uses path aliases for cleaner imports: + +- `@constants` → `./src/_constants` +- `@databases` → `./src/databases` +- `@controllers` → `./src/contollers` +- `@models` → `./src/models` +- `@repositories` → `./src/repositories` +- `@routes` → `./src/routes.ts` +- `@utils` → `./src/utils` + +## Docker + +### Building the Docker Image + +```bash +docker build -t games-api . +``` + +### Running with Docker Compose + +```bash +docker-compose up -d +``` + +The `docker-compose.yml` file includes: +- Pre-configured environment variables +- Network configuration +- Port mapping (8060:8060) +- Restart policy + +### Docker Image + +The Dockerfile uses a multi-stage build: +1. **Base stage**: Sets up the working directory +2. **Build stage**: Installs dependencies and builds the project +3. **Final stage**: Copies built files and runs the application + +## Scripts + +### Build Scripts + +- `_build.sh`: Cleans and builds the project +- `_install.sh`: Cleans and installs dependencies +- `_prepare.sh`: Runs during postinstall + +### Version Management + +- `_scripts/get_version_local.sh`: Gets local version +- `_scripts/get_version_remote.sh`: Gets remote version +- `_scripts/upgrade_version.sh`: Upgrades version number + +### Git Hooks + +- `_scripts/pre-commit`: Pre-commit hook +- `_scripts/post-commit`: Post-commit hook +- `_scripts/update_git_hooks.sh`: Updates git hooks + +## Database + +### MongoDB Collections + +The API automatically creates MongoDB collections for each game type on startup: +- `nbt_logs` - Naval Battle logs +- `rps_logs` - Rock Paper Scissors logs +- `qtt_logs` - Quick Tac Toe logs +- `cnw_logs` - Carnaval World logs +- `pnp_logs` - Planning Poker logs + +### Database Name + +All collections are stored in the `logs` database (configurable via MongoDB connection URI). + +## Error Handling + +The API includes error handling for: +- Missing required parameters (400 Bad Request) +- Database connection errors (500 Internal Server Error) +- WebSocket connection failures (automatic reconnection) +- Invalid game keys + +## Contributing + +1. Fork the repository +2. Create a feature branch (`git checkout -b feature/amazing-feature`) +3. Commit your changes (`git commit -m 'Add some amazing feature'`) +4. Push to the branch (`git push origin feature/amazing-feature`) +5. Open a Pull Request + +## License + +ISC License + +## Author + +**Pedro Darma** + +- GitHub: [@pedrodarma](https://github.com/pedrodarma) +- Repository: [games-api](https://github.com/pedrodarma/games-api) + +## Support + +For issues and questions: +- GitHub Issues: [https://github.com/pedrodarma/games-api/issues](https://github.com/pedrodarma/games-api/issues) + +--- + +**Note**: This API is designed to work as part of a larger gaming ecosystem. Ensure your MongoDB instance is properly configured and accessible before starting the server. diff --git a/env.example b/env.example new file mode 100644 index 0000000..ed808e5 --- /dev/null +++ b/env.example @@ -0,0 +1,50 @@ +# ============================================ +# Games API - Environment Variables +# ============================================ +# Copy this file to .env and fill in your values +# cp env.example .env + +# ============================================ +# Server Configuration +# ============================================ + +# Server port (optional, default: 8060) +PORT=8060 + +# Node environment: development, production, or test (optional, default: development) +NODE_ENV=development + +# ============================================ +# Database Configuration +# ============================================ + +# MongoDB connection URI (REQUIRED) +# Format: mongodb://username:password@host:port/databaseName +# Example: mongodb://admin:password123@localhost:27017/logs +MONGODB=mongodb://username:password@host:port/databaseName + +# ============================================ +# WebSocket Configuration +# ============================================ + +# WebSocket broker URL for real-time log ingestion (REQUIRED) +# Format: ws://broker-url:port or wss://broker-url:port +# Example: ws://localhost:8080 +BROKER_URL=ws://broker-url:port + +# ============================================ +# Redis Configuration (Optional) +# ============================================ + +# Redis host (optional, default: localhost) +REDIS_HOST=localhost + +# Redis port (optional, default: 6379) +REDIS_PORT=6379 + +# Redis username (optional, default: admin) +REDIS_USERNAME=admin + +# Redis password (optional, default: default) +REDIS_PASSWORD=default + diff --git a/index.ts b/index.ts index ed8b4e4..401f170 100644 --- a/index.ts +++ b/index.ts @@ -1,11 +1,12 @@ import dotenv from 'dotenv'; dotenv.config(); +import { AppConfig } from '@config'; +import Databases from '@databases'; +import { router } from '@routes'; +import cors from 'cors'; import express from 'express'; import { createServer } from 'http'; -import cors from 'cors'; -import { router } from '@routes'; -import Databases from '@databases'; import { WebsocketClient } from './src/websocket/websocket'; const app: express.Application = express(); @@ -20,7 +21,7 @@ app.set('trust proxy', true); app.use('/', router); -const port = process.env.PORT || 8060; +const port = AppConfig.server.port; server.listen(port, () => { // eslint-disable-next-line no-console console.warn(`Server listening on port ${port}`); diff --git a/package.json b/package.json index 61c0e4e..223024b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "games-api", - "version": "1.0.0", + "version": "1.0.1", "description": "Games API", "main": "index", "scripts": { @@ -32,6 +32,7 @@ "devDependencies": { "@types/cors": "^2.8.18", "@types/express": "^4.17.21", + "@types/node": "^24.10.1", "@types/ws": "^8.5.12", "@typescript-eslint/eslint-plugin": "^8.43.0", "eslint": "^8.56.0", diff --git a/src/_config/app-configuration.ts b/src/_config/app-configuration.ts new file mode 100644 index 0000000..8fec63e --- /dev/null +++ b/src/_config/app-configuration.ts @@ -0,0 +1,145 @@ +/** + * Application Configuration + * + * Centralized configuration management with environment variable validation. + * This module validates all required environment variables and provides + * type-safe access to configuration values. + */ + +// Ensure dotenv is loaded before accessing process.env +import dotenv from 'dotenv'; +dotenv.config(); + +interface AppConfig { + server: { + port: number; + nodeEnv: string; + }; + database: { + mongodb: { + uri: string; + }; + }; + websocket: { + brokerUrl: string; + }; + redis: { + host: string; + port: number; + username: string; + password: string; + }; +} + +/** + * Validates that a required environment variable is present. + * Throws an error with a descriptive message if the variable is missing. + */ +function validateRequiredEnv( + key: string, + value: string | undefined, + description?: string, +): string { + if (!value || value.trim() === '') { + const errorMessage = description + ? `Missing required environment variable: ${key}\nDescription: ${description}\n\nPlease set ${key} in your .env file or environment.` + : `Missing required environment variable: ${key}\n\nPlease set ${key} in your .env file or environment.`; + + throw new Error(errorMessage); + } + return value; +} + +/** + * Gets an optional environment variable with a default value. + */ +function getOptionalEnv(key: string, defaultValue: string): string { + return process.env[key] || defaultValue; +} + +/** + * Gets an optional numeric environment variable with a default value. + */ +function getOptionalNumberEnv(key: string, defaultValue: number): number { + const value = process.env[key]; + if (value === undefined || value === '') { + return defaultValue; + } + const parsed = parseInt(value, 10); + if (isNaN(parsed)) { + console.warn( + `Warning: ${key} is not a valid number. Using default value: ${defaultValue}`, + ); + return defaultValue; + } + return parsed; +} + +/** + * Application configuration object with validated environment variables. + * This object is initialized immediately when the module is imported. + * + * @throws {Error} If any required environment variable is missing + */ +export const AppConfig: AppConfig = (() => { + const mongodbUri = validateRequiredEnv( + 'MONGODB', + process.env.MONGODB, + 'MongoDB connection URI (e.g., mongodb://username:password@host:port/databaseName)', + ); + + const brokerUrl = validateRequiredEnv( + 'BROKER_URL', + process.env.BROKER_URL, + 'WebSocket broker URL for real-time log ingestion (e.g., ws://broker-url:port)', + ); + + const port = getOptionalNumberEnv('PORT', 8060); + const nodeEnv = getOptionalEnv('NODE_ENV', 'development'); + const redisHost = getOptionalEnv('REDIS_HOST', 'localhost'); + const redisPort = getOptionalNumberEnv('REDIS_PORT', 6379); + const redisUsername = getOptionalEnv('REDIS_USERNAME', 'admin'); + const redisPassword = getOptionalEnv('REDIS_PASSWORD', 'default'); + + return { + server: { + port, + nodeEnv, + }, + database: { + mongodb: { + uri: mongodbUri, + }, + }, + websocket: { + brokerUrl, + }, + redis: { + host: redisHost, + port: redisPort, + username: redisUsername, + password: redisPassword, + }, + }; +})(); + +/** + * Helper function to check if the application is running in production mode. + */ +export function isProduction(): boolean { + return AppConfig.server.nodeEnv === 'production'; +} + +/** + * Helper function to check if the application is running in development mode. + */ +export function isDevelopment(): boolean { + return AppConfig.server.nodeEnv === 'development'; +} + +/** + * Helper function to check if the application is running in test mode. + */ +export function isTest(): boolean { + return AppConfig.server.nodeEnv === 'test'; +} diff --git a/src/_config/index.ts b/src/_config/index.ts new file mode 100644 index 0000000..65024c0 --- /dev/null +++ b/src/_config/index.ts @@ -0,0 +1,6 @@ +export { + AppConfig, + isDevelopment, + isProduction, + isTest, +} from './app-configuration'; diff --git a/src/databases/mongodb/mongodb.ts b/src/databases/mongodb/mongodb.ts index 565c6a1..0d7e1ce 100644 --- a/src/databases/mongodb/mongodb.ts +++ b/src/databases/mongodb/mongodb.ts @@ -1,3 +1,4 @@ +import { AppConfig } from '@config'; import { GameKeys, games } from '@constants/game_types'; import { MongoClient } from 'mongodb'; @@ -12,9 +13,9 @@ export class MongoDB { constructor(uri?: string) { // Ex.: 'mongodb://username:password@host:port/databaseName'; - const _uri = process.env.MONGODB || ''; + const _uri = uri ?? AppConfig.database.mongodb.uri; - this._client = new MongoClient(uri ?? _uri); + this._client = new MongoClient(_uri); } public static initialize(): MongoDB { diff --git a/src/websocket/websocket.ts b/src/websocket/websocket.ts index 78d7e06..3ea5f07 100644 --- a/src/websocket/websocket.ts +++ b/src/websocket/websocket.ts @@ -1,3 +1,4 @@ +import { AppConfig } from '@config'; import { MongoDB } from '@databases'; import { LogQuickTacToe, WebSocketMessage } from '@models'; import { LogsRepository } from '@repositories'; @@ -31,12 +32,10 @@ export class WebsocketClient { private async _initialize(uri?: string) { try { - const _uri = process.env.BROKER_URL || ''; + const _uri = uri ?? AppConfig.websocket.brokerUrl; if (!this._client) { - console.log( - `Connecting to WebSocket at ${uri ?? _uri}/${this._channel}`, - ); - this._client = new WebSocket(`${uri ?? _uri}/${this._channel}`); + console.log(`Connecting to WebSocket at ${_uri}/${this._channel}`); + this._client = new WebSocket(`${_uri}/${this._channel}`); if (this._client) { // Register client after connection opens diff --git a/tsconfig.json b/tsconfig.json index 7cd2502..1a6f821 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,125 +1,105 @@ { - "compilerOptions": { - "target": "es6", - "module": "CommonJS", - "outDir": "./dist", - "rootDir": "./", - "moduleResolution": "node", - "lib": [ - "es2017" - ], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - "declaration": true, // Generate d.ts files - "paths": { - "@constants": [ - "./src/_constants" - ], - "@constants/game_types": [ - "./src/_constants/_games" - ], - "@databases": [ - "./src/databases" - ], - "@controllers": [ - "./src/controllers" - ], - "@models": [ - "./src/models" - ], - "@repositories": [ - "./src/repositories" - ], - "@routes": [ - "./src/routes.ts" - ], - // "@services": [ - // "./src/services" - // ], - "@utils": [ - "./src/utils" - ], - // "@middlewares": ["./src/middlewares"], - // "@config": ["./src/config"], - // "@interfaces": ["./src/interfaces"], - // "@types": ["./src/types"], - // "@helpers": ["./src/helpers"], - // "@validators": ["./src/validators"], - // "@hooks": ["./src/hooks"], - // "@assets": ["./src/assets"], - // "@components": ["./src/components"], - // "@stores": ["./src/stores"], - }, - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - "resolveJsonModule": true, /* Enable importing .json files */ - // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ - /* JavaScript Support */ - "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ - /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ - // "outDir": "./", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - /* Interop Constraints */ - "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ - /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ - // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ - // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true, /* Skip type checking all .d.ts files. */ - }, - "exclude": [ - "_website/*", - "dist/*", - "website/*", - ], - "ts-node": { - "experimentalSpecifierResolution": "node", - "transpileOnly": true, - "esm": true, - } -} \ No newline at end of file + "compilerOptions": { + "target": "es6", + "module": "CommonJS", + "outDir": "./dist", + "rootDir": "./", + "moduleResolution": "node", + "lib": [ + "es2017" + ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, + "declaration": true, // Generate d.ts files + "paths": { + "@constants": ["./src/_constants"], + "@constants/game_types": ["./src/_constants/_games"], + "@databases": ["./src/databases"], + "@controllers": ["./src/controllers"], + "@models": ["./src/models"], + "@repositories": ["./src/repositories"], + "@routes": ["./src/routes.ts"], + // "@services": [ + // "./src/services" + // ], + "@utils": ["./src/utils"], + "@config": ["./src/_config"] + // "@middlewares": ["./src/middlewares"], + // "@interfaces": ["./src/interfaces"], + // "@types": ["./src/types"], + // "@helpers": ["./src/helpers"], + // "@validators": ["./src/validators"], + // "@hooks": ["./src/hooks"], + // "@assets": ["./src/assets"], + // "@components": ["./src/components"], + // "@stores": ["./src/stores"], + }, + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + "resolveJsonModule": true /* Enable importing .json files */, + // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ + /* JavaScript Support */ + "allowJs": true /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */, + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + /* Interop Constraints */ + "isolatedModules": true /* Ensure that each file can be safely transpiled without relying on other imports. */, + "allowSyntheticDefaultImports": true /* Allow 'import x from y' when a module doesn't have a default export. */, + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + /* Type Checking */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ + // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ + // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "exclude": ["_website/*", "dist/*", "website/*"], + "ts-node": { + "experimentalSpecifierResolution": "node", + "transpileOnly": true, + "esm": true + } +} diff --git a/yarn.lock b/yarn.lock index 8e3346f..ea5fc4d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -287,6 +287,13 @@ dependencies: undici-types "~7.16.0" +"@types/node@^24.10.1": + version "24.10.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-24.10.1.tgz#91e92182c93db8bd6224fca031e2370cef9a8f01" + integrity sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ== + dependencies: + undici-types "~7.16.0" + "@types/qs@*": version "6.14.0" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.14.0.tgz#d8b60cecf62f2db0fb68e5e006077b9178b85de5"