@open-core/framework 1.0.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +373 -0
- package/README.md +350 -0
- package/dist/client/client-bootstrap.d.ts +1 -0
- package/dist/client/client-bootstrap.js +53 -0
- package/dist/client/client-container.d.ts +2 -0
- package/dist/client/client-container.js +6 -0
- package/dist/client/client-core.d.ts +18 -0
- package/dist/client/client-core.js +52 -0
- package/dist/client/decorators/controller.d.ts +3 -0
- package/dist/client/decorators/controller.js +14 -0
- package/dist/client/decorators/export.d.ts +7 -0
- package/dist/client/decorators/export.js +15 -0
- package/dist/client/decorators/gameEvent.d.ts +47 -0
- package/dist/client/decorators/gameEvent.js +54 -0
- package/dist/client/decorators/index.d.ts +10 -0
- package/dist/client/decorators/index.js +26 -0
- package/dist/client/decorators/interval.d.ts +7 -0
- package/dist/client/decorators/interval.js +15 -0
- package/dist/client/decorators/key.d.ts +2 -0
- package/dist/client/decorators/key.js +10 -0
- package/dist/client/decorators/localEvent.d.ts +7 -0
- package/dist/client/decorators/localEvent.js +15 -0
- package/dist/client/decorators/nui.d.ts +1 -0
- package/dist/client/decorators/nui.js +9 -0
- package/dist/client/decorators/onNet.d.ts +1 -0
- package/dist/client/decorators/onNet.js +9 -0
- package/dist/client/decorators/resourceLifecycle.d.ts +11 -0
- package/dist/client/decorators/resourceLifecycle.js +24 -0
- package/dist/client/decorators/tick.d.ts +1 -0
- package/dist/client/decorators/tick.js +9 -0
- package/dist/client/index.d.ts +6 -0
- package/dist/client/index.js +22 -0
- package/dist/client/loaders/exports.loader.d.ts +1 -0
- package/dist/client/loaders/exports.loader.js +13 -0
- package/dist/client/player/player.d.ts +262 -0
- package/dist/client/player/player.js +480 -0
- package/dist/client/player/player.loader.d.ts +1 -0
- package/dist/client/player/player.loader.js +22 -0
- package/dist/client/services/core/index.d.ts +1 -0
- package/dist/client/services/core/index.js +17 -0
- package/dist/client/services/core/spawn.service.d.ts +20 -0
- package/dist/client/services/core/spawn.service.js +143 -0
- package/dist/client/services/index.d.ts +4 -0
- package/dist/client/services/index.js +24 -0
- package/dist/client/services/streaming/index.d.ts +1 -0
- package/dist/client/services/streaming/index.js +17 -0
- package/dist/client/services/streaming/streaming.service.d.ts +165 -0
- package/dist/client/services/streaming/streaming.service.js +341 -0
- package/dist/client/services/ui/index.d.ts +3 -0
- package/dist/client/services/ui/index.js +19 -0
- package/dist/client/services/ui/notification.service.d.ts +76 -0
- package/dist/client/services/ui/notification.service.js +111 -0
- package/dist/client/services/ui/progress.service.d.ts +82 -0
- package/dist/client/services/ui/progress.service.js +210 -0
- package/dist/client/services/ui/textui.service.d.ts +82 -0
- package/dist/client/services/ui/textui.service.js +156 -0
- package/dist/client/services/world/blip.service.d.ts +112 -0
- package/dist/client/services/world/blip.service.js +215 -0
- package/dist/client/services/world/index.d.ts +4 -0
- package/dist/client/services/world/index.js +20 -0
- package/dist/client/services/world/marker.service.d.ts +94 -0
- package/dist/client/services/world/marker.service.js +153 -0
- package/dist/client/services/world/ped.service.d.ts +182 -0
- package/dist/client/services/world/ped.service.js +302 -0
- package/dist/client/services/world/vehicle.service.d.ts +168 -0
- package/dist/client/services/world/vehicle.service.js +296 -0
- package/dist/client/system/metadata-client.keys.d.ts +13 -0
- package/dist/client/system/metadata-client.keys.js +16 -0
- package/dist/client/system/processors/export.processor.d.ts +7 -0
- package/dist/client/system/processors/export.processor.js +39 -0
- package/dist/client/system/processors/gameEvent.processor.d.ts +10 -0
- package/dist/client/system/processors/gameEvent.processor.js +58 -0
- package/dist/client/system/processors/interval.processor.d.ts +7 -0
- package/dist/client/system/processors/interval.processor.js +43 -0
- package/dist/client/system/processors/key.processor.d.ts +8 -0
- package/dist/client/system/processors/key.processor.js +27 -0
- package/dist/client/system/processors/localEvent.processor.d.ts +7 -0
- package/dist/client/system/processors/localEvent.processor.js +38 -0
- package/dist/client/system/processors/netEvent.processor.d.ts +7 -0
- package/dist/client/system/processors/netEvent.processor.js +38 -0
- package/dist/client/system/processors/nui.processor.d.ts +7 -0
- package/dist/client/system/processors/nui.processor.js +40 -0
- package/dist/client/system/processors/resourceLifecycle.processor.d.ts +9 -0
- package/dist/client/system/processors/resourceLifecycle.processor.js +69 -0
- package/dist/client/system/processors/tick.processor.d.ts +5 -0
- package/dist/client/system/processors/tick.processor.js +37 -0
- package/dist/client/system/processors.register.d.ts +1 -0
- package/dist/client/system/processors.register.js +27 -0
- package/dist/client/types/game-events.d.ts +126 -0
- package/dist/client/types/game-events.js +83 -0
- package/dist/client/types/index.d.ts +1 -0
- package/dist/client/types/index.js +17 -0
- package/dist/client/ui-bridge.d.ts +116 -0
- package/dist/client/ui-bridge.js +201 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +46 -0
- package/dist/server/bootstrap.d.ts +16 -0
- package/dist/server/bootstrap.js +57 -0
- package/dist/server/bus/core-event-bus.d.ts +6 -0
- package/dist/server/bus/core-event-bus.js +31 -0
- package/dist/server/configs/api.config.d.ts +71 -0
- package/dist/server/configs/api.config.js +81 -0
- package/dist/server/configs/config.base.d.ts +63 -0
- package/dist/server/configs/config.base.js +64 -0
- package/dist/server/configs/index.d.ts +2 -0
- package/dist/server/configs/index.js +18 -0
- package/dist/server/container.d.ts +2 -0
- package/dist/server/container.js +6 -0
- package/dist/server/controllers/chat.controller.d.ts +10 -0
- package/dist/server/controllers/chat.controller.js +50 -0
- package/dist/server/controllers/command.controller.d.ts +7 -0
- package/dist/server/controllers/command.controller.js +47 -0
- package/dist/server/core.d.ts +1 -0
- package/dist/server/core.js +7 -0
- package/dist/server/database/adapters/oxmysql.adapter.d.ts +89 -0
- package/dist/server/database/adapters/oxmysql.adapter.js +149 -0
- package/dist/server/database/database.contract.d.ts +128 -0
- package/dist/server/database/database.contract.js +29 -0
- package/dist/server/database/database.service.d.ts +216 -0
- package/dist/server/database/database.service.js +301 -0
- package/dist/server/database/index.d.ts +53 -0
- package/dist/server/database/index.js +70 -0
- package/dist/server/database/types.d.ts +67 -0
- package/dist/server/database/types.js +7 -0
- package/dist/server/database.d.ts +7 -0
- package/dist/server/database.js +23 -0
- package/dist/server/decorators/bind.d.ts +2 -0
- package/dist/server/decorators/bind.js +15 -0
- package/dist/server/decorators/command.d.ts +19 -0
- package/dist/server/decorators/command.js +18 -0
- package/dist/server/decorators/controller.d.ts +3 -0
- package/dist/server/decorators/controller.js +14 -0
- package/dist/server/decorators/coreEvent.d.ts +2 -0
- package/dist/server/decorators/coreEvent.js +9 -0
- package/dist/server/decorators/export.d.ts +1 -0
- package/dist/server/decorators/export.js +9 -0
- package/dist/server/decorators/guard.d.ts +5 -0
- package/dist/server/decorators/guard.js +39 -0
- package/dist/server/decorators/index.d.ts +10 -0
- package/dist/server/decorators/index.js +26 -0
- package/dist/server/decorators/netEvent.d.ts +36 -0
- package/dist/server/decorators/netEvent.js +40 -0
- package/dist/server/decorators/onTick.d.ts +1 -0
- package/dist/server/decorators/onTick.js +9 -0
- package/dist/server/decorators/public.d.ts +16 -0
- package/dist/server/decorators/public.js +25 -0
- package/dist/server/decorators/requiresState.d.ts +55 -0
- package/dist/server/decorators/requiresState.js +62 -0
- package/dist/server/decorators/throttle.d.ts +9 -0
- package/dist/server/decorators/throttle.js +36 -0
- package/dist/server/decorators/utils.d.ts +7 -0
- package/dist/server/decorators/utils.js +13 -0
- package/dist/server/entities/index.d.ts +1 -0
- package/dist/server/entities/index.js +17 -0
- package/dist/server/entities/player.d.ts +157 -0
- package/dist/server/entities/player.js +217 -0
- package/dist/server/error-handler.d.ts +2 -0
- package/dist/server/error-handler.js +43 -0
- package/dist/server/index.d.ts +10 -0
- package/dist/server/index.js +29 -0
- package/dist/server/loaders/exports.loader.d.ts +0 -0
- package/dist/server/loaders/exports.loader.js +23 -0
- package/dist/server/loaders/playerSession.loader.d.ts +1 -0
- package/dist/server/loaders/playerSession.loader.js +42 -0
- package/dist/server/services/access-control.service.d.ts +56 -0
- package/dist/server/services/access-control.service.js +99 -0
- package/dist/server/services/chat.service.d.ts +7 -0
- package/dist/server/services/chat.service.js +31 -0
- package/dist/server/services/command.service.d.ts +15 -0
- package/dist/server/services/command.service.js +74 -0
- package/dist/server/services/config.service.d.ts +75 -0
- package/dist/server/services/config.service.js +116 -0
- package/dist/server/services/default/default-security.handler.d.ts +6 -0
- package/dist/server/services/default/default-security.handler.js +26 -0
- package/dist/server/services/http/http.service.d.ts +50 -0
- package/dist/server/services/http/http.service.js +126 -0
- package/dist/server/services/index.d.ts +10 -0
- package/dist/server/services/index.js +26 -0
- package/dist/server/services/parallel/index.d.ts +49 -0
- package/dist/server/services/parallel/index.js +67 -0
- package/dist/server/services/parallel/parallel-compute.service.d.ts +132 -0
- package/dist/server/services/parallel/parallel-compute.service.js +449 -0
- package/dist/server/services/parallel/types.d.ts +188 -0
- package/dist/server/services/parallel/types.js +7 -0
- package/dist/server/services/parallel/worker-pool.d.ts +83 -0
- package/dist/server/services/parallel/worker-pool.js +350 -0
- package/dist/server/services/parallel/worker.d.ts +19 -0
- package/dist/server/services/parallel/worker.js +49 -0
- package/dist/server/services/persistence.service.d.ts +59 -0
- package/dist/server/services/persistence.service.js +166 -0
- package/dist/server/services/player.service.d.ts +96 -0
- package/dist/server/services/player.service.js +132 -0
- package/dist/server/services/rate-limiter.service.d.ts +5 -0
- package/dist/server/services/rate-limiter.service.js +39 -0
- package/dist/server/services/registers.d.ts +1 -0
- package/dist/server/services/registers.js +18 -0
- package/dist/server/setup.d.ts +9 -0
- package/dist/server/setup.js +28 -0
- package/dist/server/system/metadata-server.keys.d.ts +9 -0
- package/dist/server/system/metadata-server.keys.js +12 -0
- package/dist/server/system/processors/command.processor.d.ts +9 -0
- package/dist/server/system/processors/command.processor.js +31 -0
- package/dist/server/system/processors/coreEvent.processor.d.ts +7 -0
- package/dist/server/system/processors/coreEvent.processor.js +38 -0
- package/dist/server/system/processors/export.processor.d.ts +7 -0
- package/dist/server/system/processors/export.processor.js +26 -0
- package/dist/server/system/processors/netEvent.processor.d.ts +11 -0
- package/dist/server/system/processors/netEvent.processor.js +100 -0
- package/dist/server/system/processors/tick.processor.d.ts +5 -0
- package/dist/server/system/processors/tick.processor.js +36 -0
- package/dist/server/system/processors.register.d.ts +1 -0
- package/dist/server/system/processors.register.js +21 -0
- package/dist/server/templates/admin/admin.controller-template.d.ts +10 -0
- package/dist/server/templates/admin/admin.controller-template.js +2 -0
- package/dist/server/templates/auth/auth-provider.contract.d.ts +58 -0
- package/dist/server/templates/auth/auth-provider.contract.js +23 -0
- package/dist/server/templates/index.d.ts +8 -0
- package/dist/server/templates/index.js +21 -0
- package/dist/server/templates/persistence/index.d.ts +30 -0
- package/dist/server/templates/persistence/index.js +34 -0
- package/dist/server/templates/persistence/player-persistence.contract.d.ts +86 -0
- package/dist/server/templates/persistence/player-persistence.contract.js +52 -0
- package/dist/server/templates/repository/index.d.ts +57 -0
- package/dist/server/templates/repository/index.js +61 -0
- package/dist/server/templates/repository/repository.contract.d.ts +224 -0
- package/dist/server/templates/repository/repository.contract.js +342 -0
- package/dist/server/templates/repository/repository.types.d.ts +51 -0
- package/dist/server/templates/repository/repository.types.js +7 -0
- package/dist/server/templates/security/permission.types.d.ts +32 -0
- package/dist/server/templates/security/permission.types.js +2 -0
- package/dist/server/templates/security/principal-provider.contract.d.ts +43 -0
- package/dist/server/templates/security/principal-provider.contract.js +19 -0
- package/dist/server/templates/security/security-handler.contract.d.ts +5 -0
- package/dist/server/templates/security/security-handler.contract.js +6 -0
- package/dist/server/types/core-events.d.ts +17 -0
- package/dist/server/types/core-events.js +2 -0
- package/dist/server/types/security.types.d.ts +7 -0
- package/dist/server/types/security.types.js +2 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +17 -0
- package/dist/shared/logger/core-logger.d.ts +35 -0
- package/dist/shared/logger/core-logger.js +52 -0
- package/dist/shared/logger/index.d.ts +11 -0
- package/dist/shared/logger/index.js +26 -0
- package/dist/shared/logger/logger.config.d.ts +47 -0
- package/dist/shared/logger/logger.config.js +33 -0
- package/dist/shared/logger/logger.service.d.ts +161 -0
- package/dist/shared/logger/logger.service.js +279 -0
- package/dist/shared/logger/logger.types.d.ts +85 -0
- package/dist/shared/logger/logger.types.js +74 -0
- package/dist/shared/logger/transports/buffered.transport.d.ts +88 -0
- package/dist/shared/logger/transports/buffered.transport.js +174 -0
- package/dist/shared/logger/transports/console.transport.d.ts +37 -0
- package/dist/shared/logger/transports/console.transport.js +134 -0
- package/dist/shared/logger/transports/index.d.ts +3 -0
- package/dist/shared/logger/transports/index.js +19 -0
- package/dist/shared/logger/transports/transport.interface.d.ts +40 -0
- package/dist/shared/logger/transports/transport.interface.js +2 -0
- package/dist/system/class-constructor.d.ts +1 -0
- package/dist/system/class-constructor.js +2 -0
- package/dist/system/decorator-processor.d.ts +4 -0
- package/dist/system/decorator-processor.js +2 -0
- package/dist/system/metadata.scanner.d.ts +7 -0
- package/dist/system/metadata.scanner.js +45 -0
- package/dist/utils/errors.d.ts +14 -0
- package/dist/utils/errors.js +25 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +20 -0
- package/dist/utils/result.d.ts +12 -0
- package/dist/utils/result.js +10 -0
- package/dist/utils/rgb.d.ts +5 -0
- package/dist/utils/rgb.js +2 -0
- package/dist/utils/vector3.d.ts +13 -0
- package/dist/utils/vector3.js +27 -0
- package/package.json +70 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.AccessControlService = void 0;
|
|
13
|
+
const tsyringe_1 = require("tsyringe");
|
|
14
|
+
const utils_1 = require("../../utils");
|
|
15
|
+
const templates_1 = require("../templates");
|
|
16
|
+
/**
|
|
17
|
+
* **Core Security Service**
|
|
18
|
+
*
|
|
19
|
+
* This service acts as the central enforcement point for the Access Control system.
|
|
20
|
+
* It uses the configured `PrincipalProvider` to query roles and validates them against requirements.
|
|
21
|
+
*
|
|
22
|
+
* It is primarily used internally by the `@Guard` decorator, but can be injected
|
|
23
|
+
* into services to perform manual checks.
|
|
24
|
+
*/
|
|
25
|
+
let AccessControlService = class AccessControlService {
|
|
26
|
+
constructor(principalProvider) {
|
|
27
|
+
this.principalProvider = principalProvider;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Verifies if a player meets a minimum numeric rank requirement.
|
|
31
|
+
*
|
|
32
|
+
* @param player - The target player.
|
|
33
|
+
* @param minRank - The minimum numeric value required (Inclusive).
|
|
34
|
+
*
|
|
35
|
+
* @returns `true` if `Principal.rank >= minRank`.
|
|
36
|
+
*
|
|
37
|
+
* @throws {AppError} code `UNAUTHORIZED` if the player has no Principal (not logged in).
|
|
38
|
+
* @throws {AppError} code `NO_RANK_IN_PRINCIPAL` if the Principal exists but has no `rank` defined.
|
|
39
|
+
*/
|
|
40
|
+
async hasRank(player, minRank) {
|
|
41
|
+
const principal = await this.principalProvider.getPrincipal(player);
|
|
42
|
+
if (!principal)
|
|
43
|
+
throw new utils_1.AppError('UNAUTHORIZED', 'No principal found', 'core');
|
|
44
|
+
if (principal.rank === undefined)
|
|
45
|
+
throw new utils_1.AppError('NO_RANK_IN_PRINCIPAL', "You're trying to compare a Principal rank, but there's no defined rank! ", 'core');
|
|
46
|
+
return principal.rank >= minRank;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Verifies if a player possesses a specific permission string.
|
|
50
|
+
*
|
|
51
|
+
* @remarks
|
|
52
|
+
* This method supports the **Wildcard ('*')** permission. If the principal has `'*'`
|
|
53
|
+
* in their permissions array, this method always returns `true`.
|
|
54
|
+
*
|
|
55
|
+
* @param player - The target player.
|
|
56
|
+
* @param permission - The specific permission key (e.g., `'admin.ban'`).
|
|
57
|
+
* @returns `true` if the player has the permission or the wildcard.
|
|
58
|
+
*/
|
|
59
|
+
async hasPermission(player, permission) {
|
|
60
|
+
const principal = await this.principalProvider.getPrincipal(player);
|
|
61
|
+
if (!principal)
|
|
62
|
+
return false;
|
|
63
|
+
if (principal.permissions.includes('*'))
|
|
64
|
+
return true;
|
|
65
|
+
return principal.permissions.includes(permission);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* **Strict Enforcement**
|
|
69
|
+
*
|
|
70
|
+
* Validates a set of requirements against a player. If any requirement fails,
|
|
71
|
+
* it throws an exception, halting the execution flow.
|
|
72
|
+
*
|
|
73
|
+
* Used primarily by the `@Guard` decorator logic.
|
|
74
|
+
*
|
|
75
|
+
* @param player - The server player to validate.
|
|
76
|
+
* @param requirements - An object containing rank and/or permission constraints.
|
|
77
|
+
*
|
|
78
|
+
* @throws {AppError} code `PERMISSION_DENIED` if validation fails.
|
|
79
|
+
*/
|
|
80
|
+
async enforce(player, requirements) {
|
|
81
|
+
if (requirements.minRank !== undefined) {
|
|
82
|
+
const hasRank = await this.hasRank(player, requirements.minRank);
|
|
83
|
+
if (!hasRank) {
|
|
84
|
+
throw new utils_1.AppError('PERMISSION_DENIED', `Access Denied: Requires minimum rank level ${requirements.minRank}`, 'core');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (requirements.permission) {
|
|
88
|
+
const hasPerm = await this.hasPermission(player, requirements.permission);
|
|
89
|
+
if (!hasPerm) {
|
|
90
|
+
throw new utils_1.AppError('PERMISSION_DENIED', `Access Denied: Missing required permission '${requirements.permission}'`, 'core');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
exports.AccessControlService = AccessControlService;
|
|
96
|
+
exports.AccessControlService = AccessControlService = __decorate([
|
|
97
|
+
(0, tsyringe_1.injectable)(),
|
|
98
|
+
__metadata("design:paramtypes", [templates_1.PrincipalProviderContract])
|
|
99
|
+
], AccessControlService);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Server } from '../..';
|
|
2
|
+
import { RGB } from '../../utils';
|
|
3
|
+
export declare class ChatService {
|
|
4
|
+
broadcast(message: string, author?: string, color?: RGB): void;
|
|
5
|
+
sendPrivate(player: Server.Player, message: string, author?: string, color?: RGB): void;
|
|
6
|
+
clearChat(player: Server.Player): void;
|
|
7
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ChatService = void 0;
|
|
10
|
+
const tsyringe_1 = require("tsyringe");
|
|
11
|
+
let ChatService = class ChatService {
|
|
12
|
+
broadcast(message, author = 'SYSTEM', color = { r: 255, g: 255, b: 255 }) {
|
|
13
|
+
emitNet('core:chat:message', -1, {
|
|
14
|
+
args: [author, message],
|
|
15
|
+
color: color,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
sendPrivate(player, message, author = 'Private', color = { r: 200, g: 200, b: 200 }) {
|
|
19
|
+
emitNet('core:chat:addMessage', player.clientID, {
|
|
20
|
+
args: [author, message],
|
|
21
|
+
color: color,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
clearChat(player) {
|
|
25
|
+
emitNet('core:chat:clear', player.clientID);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
exports.ChatService = ChatService;
|
|
29
|
+
exports.ChatService = ChatService = __decorate([
|
|
30
|
+
(0, tsyringe_1.injectable)()
|
|
31
|
+
], ChatService);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CommandMetadata } from '../decorators/command';
|
|
2
|
+
import { Server } from '../..';
|
|
3
|
+
import { SecurityHandlerContract } from '../templates/security/security-handler.contract';
|
|
4
|
+
export declare class CommandService {
|
|
5
|
+
private securityHandler;
|
|
6
|
+
constructor(securityHandler: SecurityHandlerContract);
|
|
7
|
+
private commands;
|
|
8
|
+
register(meta: CommandMetadata, handler: Function): void;
|
|
9
|
+
execute(player: Server.Player, commandName: string, args: string[], raw: string): Promise<void>;
|
|
10
|
+
getAllCommands(): {
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
usage: string;
|
|
14
|
+
}[];
|
|
15
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.CommandService = void 0;
|
|
16
|
+
const tsyringe_1 = require("tsyringe");
|
|
17
|
+
const utils_1 = require("../../utils");
|
|
18
|
+
const zod_1 = __importDefault(require("zod"));
|
|
19
|
+
const security_handler_contract_1 = require("../templates/security/security-handler.contract");
|
|
20
|
+
const logger_1 = require("../../shared/logger");
|
|
21
|
+
let CommandService = class CommandService {
|
|
22
|
+
constructor(securityHandler) {
|
|
23
|
+
this.securityHandler = securityHandler;
|
|
24
|
+
this.commands = new Map();
|
|
25
|
+
}
|
|
26
|
+
register(meta, handler) {
|
|
27
|
+
this.commands.set(meta.name.toLowerCase(), { meta, handler });
|
|
28
|
+
logger_1.loggers.command.debug(`Registered: /${meta.name}${meta.schema ? ' [Validated]' : ''}`);
|
|
29
|
+
}
|
|
30
|
+
async execute(player, commandName, args, raw) {
|
|
31
|
+
const entry = this.commands.get(commandName.toLowerCase());
|
|
32
|
+
if (!entry) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const { meta, handler } = entry;
|
|
36
|
+
let validatedArgs = args;
|
|
37
|
+
if (meta.schema) {
|
|
38
|
+
try {
|
|
39
|
+
const result = await meta.schema.parseAsync(args);
|
|
40
|
+
validatedArgs = Array.isArray(result) ? result : [result];
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error instanceof zod_1.default.ZodError) {
|
|
44
|
+
throw new utils_1.AppError('VALIDATION_ERROR', `Incorrect usage: ${error.message}`, 'client', {
|
|
45
|
+
usage: meta.usage,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (error instanceof utils_1.AppError) {
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
if (error instanceof utils_1.SecurityError) {
|
|
52
|
+
this.securityHandler.handleViolation(player, error);
|
|
53
|
+
}
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
await handler(player, validatedArgs, raw);
|
|
58
|
+
}
|
|
59
|
+
getAllCommands() {
|
|
60
|
+
return Array.from(this.commands.values()).map((c) => {
|
|
61
|
+
var _a, _b;
|
|
62
|
+
return ({
|
|
63
|
+
name: c.meta.name,
|
|
64
|
+
description: (_a = c.meta.description) !== null && _a !== void 0 ? _a : '',
|
|
65
|
+
usage: (_b = c.meta.usage) !== null && _b !== void 0 ? _b : '',
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
exports.CommandService = CommandService;
|
|
71
|
+
exports.CommandService = CommandService = __decorate([
|
|
72
|
+
(0, tsyringe_1.injectable)(),
|
|
73
|
+
__metadata("design:paramtypes", [security_handler_contract_1.SecurityHandlerContract])
|
|
74
|
+
], CommandService);
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic configuration service for accessing FiveM Convars.
|
|
3
|
+
*
|
|
4
|
+
* Provides type-safe access to configuration values with automatic
|
|
5
|
+
* prefix handling and type conversion.
|
|
6
|
+
*
|
|
7
|
+
* All keys are automatically prefixed with `opencore_`.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const config = di.resolve(ConfigService)
|
|
12
|
+
*
|
|
13
|
+
* // Get string value
|
|
14
|
+
* const apiUrl = config.get('api_url', 'http://localhost:3000')
|
|
15
|
+
*
|
|
16
|
+
* // Get number value
|
|
17
|
+
* const timeout = config.getNumber('timeout', 5000)
|
|
18
|
+
*
|
|
19
|
+
* // Get boolean value
|
|
20
|
+
* const debug = config.getBoolean('debug', false)
|
|
21
|
+
*
|
|
22
|
+
* // Get required value (throws if not set)
|
|
23
|
+
* const secretKey = config.getRequired('secret_key')
|
|
24
|
+
*
|
|
25
|
+
* // Get JSON value
|
|
26
|
+
* const settings = config.getJson('settings', { enabled: true })
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @scope Singleton
|
|
30
|
+
*/
|
|
31
|
+
export declare class ConfigService {
|
|
32
|
+
private readonly PREFIX;
|
|
33
|
+
/**
|
|
34
|
+
* Gets a string configuration value.
|
|
35
|
+
*
|
|
36
|
+
* @param key - The configuration key (without prefix)
|
|
37
|
+
* @param defaultValue - Default value if not set
|
|
38
|
+
* @returns The configuration value or default
|
|
39
|
+
*/
|
|
40
|
+
get(key: string, defaultValue: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Gets a numeric configuration value.
|
|
43
|
+
*
|
|
44
|
+
* @param key - The configuration key (without prefix)
|
|
45
|
+
* @param defaultValue - Default value if not set or invalid
|
|
46
|
+
* @returns The configuration value as number
|
|
47
|
+
*/
|
|
48
|
+
getNumber(key: string, defaultValue: number): number;
|
|
49
|
+
/**
|
|
50
|
+
* Gets a boolean configuration value.
|
|
51
|
+
*
|
|
52
|
+
* Recognizes 'true', '1' as true, everything else as false.
|
|
53
|
+
*
|
|
54
|
+
* @param key - The configuration key (without prefix)
|
|
55
|
+
* @param defaultValue - Default value if not set
|
|
56
|
+
* @returns The configuration value as boolean
|
|
57
|
+
*/
|
|
58
|
+
getBoolean(key: string, defaultValue: boolean): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Gets a required configuration value.
|
|
61
|
+
*
|
|
62
|
+
* @param key - The configuration key (without prefix)
|
|
63
|
+
* @returns The configuration value
|
|
64
|
+
* @throws Error if the value is not set
|
|
65
|
+
*/
|
|
66
|
+
getRequired(key: string): string;
|
|
67
|
+
/**
|
|
68
|
+
* Gets a JSON configuration value.
|
|
69
|
+
*
|
|
70
|
+
* @param key - The configuration key (without prefix)
|
|
71
|
+
* @param defaultValue - Default value if not set or invalid JSON
|
|
72
|
+
* @returns The parsed JSON value or default
|
|
73
|
+
*/
|
|
74
|
+
getJson<T>(key: string, defaultValue: T): T;
|
|
75
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ConfigService = void 0;
|
|
10
|
+
const decorators_1 = require("../decorators");
|
|
11
|
+
/**
|
|
12
|
+
* Generic configuration service for accessing FiveM Convars.
|
|
13
|
+
*
|
|
14
|
+
* Provides type-safe access to configuration values with automatic
|
|
15
|
+
* prefix handling and type conversion.
|
|
16
|
+
*
|
|
17
|
+
* All keys are automatically prefixed with `opencore_`.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const config = di.resolve(ConfigService)
|
|
22
|
+
*
|
|
23
|
+
* // Get string value
|
|
24
|
+
* const apiUrl = config.get('api_url', 'http://localhost:3000')
|
|
25
|
+
*
|
|
26
|
+
* // Get number value
|
|
27
|
+
* const timeout = config.getNumber('timeout', 5000)
|
|
28
|
+
*
|
|
29
|
+
* // Get boolean value
|
|
30
|
+
* const debug = config.getBoolean('debug', false)
|
|
31
|
+
*
|
|
32
|
+
* // Get required value (throws if not set)
|
|
33
|
+
* const secretKey = config.getRequired('secret_key')
|
|
34
|
+
*
|
|
35
|
+
* // Get JSON value
|
|
36
|
+
* const settings = config.getJson('settings', { enabled: true })
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @scope Singleton
|
|
40
|
+
*/
|
|
41
|
+
let ConfigService = class ConfigService {
|
|
42
|
+
constructor() {
|
|
43
|
+
this.PREFIX = 'opencore_';
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Gets a string configuration value.
|
|
47
|
+
*
|
|
48
|
+
* @param key - The configuration key (without prefix)
|
|
49
|
+
* @param defaultValue - Default value if not set
|
|
50
|
+
* @returns The configuration value or default
|
|
51
|
+
*/
|
|
52
|
+
get(key, defaultValue) {
|
|
53
|
+
return GetConvar(this.PREFIX + key, defaultValue);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Gets a numeric configuration value.
|
|
57
|
+
*
|
|
58
|
+
* @param key - The configuration key (without prefix)
|
|
59
|
+
* @param defaultValue - Default value if not set or invalid
|
|
60
|
+
* @returns The configuration value as number
|
|
61
|
+
*/
|
|
62
|
+
getNumber(key, defaultValue) {
|
|
63
|
+
const value = GetConvar(this.PREFIX + key, String(defaultValue));
|
|
64
|
+
const parsed = Number(value);
|
|
65
|
+
return isNaN(parsed) ? defaultValue : parsed;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Gets a boolean configuration value.
|
|
69
|
+
*
|
|
70
|
+
* Recognizes 'true', '1' as true, everything else as false.
|
|
71
|
+
*
|
|
72
|
+
* @param key - The configuration key (without prefix)
|
|
73
|
+
* @param defaultValue - Default value if not set
|
|
74
|
+
* @returns The configuration value as boolean
|
|
75
|
+
*/
|
|
76
|
+
getBoolean(key, defaultValue) {
|
|
77
|
+
const value = GetConvar(this.PREFIX + key, String(defaultValue));
|
|
78
|
+
return value === 'true' || value === '1';
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Gets a required configuration value.
|
|
82
|
+
*
|
|
83
|
+
* @param key - The configuration key (without prefix)
|
|
84
|
+
* @returns The configuration value
|
|
85
|
+
* @throws Error if the value is not set
|
|
86
|
+
*/
|
|
87
|
+
getRequired(key) {
|
|
88
|
+
const value = GetConvar(this.PREFIX + key, '');
|
|
89
|
+
if (!value) {
|
|
90
|
+
throw new Error(`[OpenCore] Configuration '${this.PREFIX}${key}' is required but not set`);
|
|
91
|
+
}
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Gets a JSON configuration value.
|
|
96
|
+
*
|
|
97
|
+
* @param key - The configuration key (without prefix)
|
|
98
|
+
* @param defaultValue - Default value if not set or invalid JSON
|
|
99
|
+
* @returns The parsed JSON value or default
|
|
100
|
+
*/
|
|
101
|
+
getJson(key, defaultValue) {
|
|
102
|
+
const value = GetConvar(this.PREFIX + key, '');
|
|
103
|
+
if (!value)
|
|
104
|
+
return defaultValue;
|
|
105
|
+
try {
|
|
106
|
+
return JSON.parse(value);
|
|
107
|
+
}
|
|
108
|
+
catch (_a) {
|
|
109
|
+
return defaultValue;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
exports.ConfigService = ConfigService;
|
|
114
|
+
exports.ConfigService = ConfigService = __decorate([
|
|
115
|
+
(0, decorators_1.Bind)('singleton')
|
|
116
|
+
], ConfigService);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { SecurityHandlerContract } from '../../templates/security/security-handler.contract';
|
|
2
|
+
import { Server } from '../../..';
|
|
3
|
+
import { SecurityError } from '../../../utils/errors';
|
|
4
|
+
export declare class DefaultSecurityHandler extends SecurityHandlerContract {
|
|
5
|
+
handleViolation(player: Server.Player, error: SecurityError): Promise<void>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.DefaultSecurityHandler = void 0;
|
|
10
|
+
const tsyringe_1 = require("tsyringe");
|
|
11
|
+
const security_handler_contract_1 = require("../../templates/security/security-handler.contract");
|
|
12
|
+
const logger_1 = require("../../../shared/logger");
|
|
13
|
+
let DefaultSecurityHandler = class DefaultSecurityHandler extends security_handler_contract_1.SecurityHandlerContract {
|
|
14
|
+
async handleViolation(player, error) {
|
|
15
|
+
logger_1.loggers.security.warn(`Security violation detected`, {
|
|
16
|
+
playerName: player.name,
|
|
17
|
+
playerId: player.clientID,
|
|
18
|
+
message: error.message,
|
|
19
|
+
suggestedAction: error.action,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
exports.DefaultSecurityHandler = DefaultSecurityHandler;
|
|
24
|
+
exports.DefaultSecurityHandler = DefaultSecurityHandler = __decorate([
|
|
25
|
+
(0, tsyringe_1.injectable)()
|
|
26
|
+
], DefaultSecurityHandler);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface HttpOptions {
|
|
2
|
+
headers?: Record<string, string>;
|
|
3
|
+
timeoutMs?: number;
|
|
4
|
+
}
|
|
5
|
+
export declare class HttpService {
|
|
6
|
+
/**
|
|
7
|
+
* Performs an HTTP GET request to the specified URL.
|
|
8
|
+
*
|
|
9
|
+
* @template T - The expected return type of the response data.
|
|
10
|
+
* @param url - The endpoint URL to fetch data from.
|
|
11
|
+
* @param options - Optional configuration for the request (headers, timeout).
|
|
12
|
+
* @returns A Promise that resolves to the response data of type T.
|
|
13
|
+
* @throws {AppError} If the request fails, times out, or returns a non-2xx status code.
|
|
14
|
+
*/
|
|
15
|
+
get<T = any>(url: string, options?: HttpOptions): Promise<T>;
|
|
16
|
+
/**
|
|
17
|
+
* Performs an HTTP POST request to the specified URL with a JSON payload.
|
|
18
|
+
*
|
|
19
|
+
* @template T - The expected return type of the response data.
|
|
20
|
+
* @param url - The endpoint URL to send data to.
|
|
21
|
+
* @param body - The data payload to be sent as the request body (will be stringified to JSON).
|
|
22
|
+
* @param options - Optional configuration for the request (headers, timeout).
|
|
23
|
+
* @returns A Promise that resolves to the response data of type T.
|
|
24
|
+
* @throws {AppError} If the request fails, times out, or returns a non-2xx status code.
|
|
25
|
+
*/
|
|
26
|
+
post<T = any>(url: string, body: any, options?: HttpOptions): Promise<T>;
|
|
27
|
+
/**
|
|
28
|
+
* Performs an HTTP PUT request to the specified URL to update a resource.
|
|
29
|
+
*
|
|
30
|
+
* @template T - The expected return type of the response data.
|
|
31
|
+
* @param url - The endpoint URL to update.
|
|
32
|
+
* @param body - The data payload to be sent as the request body (will be stringified to JSON).
|
|
33
|
+
* @param options - Optional configuration for the request (headers, timeout).
|
|
34
|
+
* @returns A Promise that resolves to the response data of type T.
|
|
35
|
+
* @throws {AppError} If the request fails, times out, or returns a non-2xx status code.
|
|
36
|
+
*/
|
|
37
|
+
put<T = any>(url: string, body: any, options?: HttpOptions): Promise<T>;
|
|
38
|
+
/**
|
|
39
|
+
* Performs an HTTP DELETE request to the specified URL.
|
|
40
|
+
*
|
|
41
|
+
* @template T - The expected return type of the response data (often void or the deleted entity).
|
|
42
|
+
* @param url - The endpoint URL to delete the resource from.
|
|
43
|
+
* @param options - Optional configuration for the request (headers, timeout).
|
|
44
|
+
* @returns A Promise that resolves to the response data of type T.
|
|
45
|
+
* @throws {AppError} If the request fails, times out, or returns a non-2xx status code.
|
|
46
|
+
*/
|
|
47
|
+
delete<T = any>(url: string, options?: HttpOptions): Promise<T>;
|
|
48
|
+
private request;
|
|
49
|
+
private handleResponse;
|
|
50
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.HttpService = void 0;
|
|
10
|
+
const tsyringe_1 = require("tsyringe");
|
|
11
|
+
const utils_1 = require("../../../utils");
|
|
12
|
+
let HttpService = class HttpService {
|
|
13
|
+
/**
|
|
14
|
+
* Performs an HTTP GET request to the specified URL.
|
|
15
|
+
*
|
|
16
|
+
* @template T - The expected return type of the response data.
|
|
17
|
+
* @param url - The endpoint URL to fetch data from.
|
|
18
|
+
* @param options - Optional configuration for the request (headers, timeout).
|
|
19
|
+
* @returns A Promise that resolves to the response data of type T.
|
|
20
|
+
* @throws {AppError} If the request fails, times out, or returns a non-2xx status code.
|
|
21
|
+
*/
|
|
22
|
+
async get(url, options = {}) {
|
|
23
|
+
return this.request(url, 'GET', undefined, options);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Performs an HTTP POST request to the specified URL with a JSON payload.
|
|
27
|
+
*
|
|
28
|
+
* @template T - The expected return type of the response data.
|
|
29
|
+
* @param url - The endpoint URL to send data to.
|
|
30
|
+
* @param body - The data payload to be sent as the request body (will be stringified to JSON).
|
|
31
|
+
* @param options - Optional configuration for the request (headers, timeout).
|
|
32
|
+
* @returns A Promise that resolves to the response data of type T.
|
|
33
|
+
* @throws {AppError} If the request fails, times out, or returns a non-2xx status code.
|
|
34
|
+
*/
|
|
35
|
+
async post(url, body, options = {}) {
|
|
36
|
+
return this.request(url, 'POST', body, options);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Performs an HTTP PUT request to the specified URL to update a resource.
|
|
40
|
+
*
|
|
41
|
+
* @template T - The expected return type of the response data.
|
|
42
|
+
* @param url - The endpoint URL to update.
|
|
43
|
+
* @param body - The data payload to be sent as the request body (will be stringified to JSON).
|
|
44
|
+
* @param options - Optional configuration for the request (headers, timeout).
|
|
45
|
+
* @returns A Promise that resolves to the response data of type T.
|
|
46
|
+
* @throws {AppError} If the request fails, times out, or returns a non-2xx status code.
|
|
47
|
+
*/
|
|
48
|
+
async put(url, body, options = {}) {
|
|
49
|
+
return this.request(url, 'PUT', body, options);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Performs an HTTP DELETE request to the specified URL.
|
|
53
|
+
*
|
|
54
|
+
* @template T - The expected return type of the response data (often void or the deleted entity).
|
|
55
|
+
* @param url - The endpoint URL to delete the resource from.
|
|
56
|
+
* @param options - Optional configuration for the request (headers, timeout).
|
|
57
|
+
* @returns A Promise that resolves to the response data of type T.
|
|
58
|
+
* @throws {AppError} If the request fails, times out, or returns a non-2xx status code.
|
|
59
|
+
*/
|
|
60
|
+
async delete(url, options = {}) {
|
|
61
|
+
return this.request(url, 'DELETE', undefined, options);
|
|
62
|
+
}
|
|
63
|
+
async request(url, method, body, options) {
|
|
64
|
+
const { headers = {}, timeoutMs = 5000 } = options;
|
|
65
|
+
const finalHeaders = Object.assign({ 'Content-Type': 'application/json' }, headers);
|
|
66
|
+
const controller = new AbortController();
|
|
67
|
+
const id = setTimeout(() => controller.abort(), timeoutMs);
|
|
68
|
+
try {
|
|
69
|
+
const response = await fetch(url, {
|
|
70
|
+
method,
|
|
71
|
+
headers: finalHeaders,
|
|
72
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
73
|
+
signal: controller.signal,
|
|
74
|
+
});
|
|
75
|
+
return await this.handleResponse(response, method, url);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
if (err instanceof utils_1.AppError)
|
|
79
|
+
throw err;
|
|
80
|
+
if (err instanceof DOMException && err.name === 'AbortError') {
|
|
81
|
+
throw new utils_1.AppError('NETWORK_ERROR', `${method} ${url} timed out after ${timeoutMs}ms`, 'external', { timeout: timeoutMs });
|
|
82
|
+
}
|
|
83
|
+
throw new utils_1.AppError('NETWORK_ERROR', `Network error calling ${method} ${url}`, 'external', {
|
|
84
|
+
endpoint: url,
|
|
85
|
+
method,
|
|
86
|
+
cause: err instanceof Error ? err.message : String(err),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
clearTimeout(id);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async handleResponse(response, method, url) {
|
|
94
|
+
if (!response.ok) {
|
|
95
|
+
let code = 'API_ERROR';
|
|
96
|
+
let errorBody = null;
|
|
97
|
+
if (response.status === 401 || response.status === 403) {
|
|
98
|
+
code = 'UNAUTHORIZED';
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
errorBody = await response.json();
|
|
102
|
+
}
|
|
103
|
+
catch (_) { }
|
|
104
|
+
throw new utils_1.AppError(code, `${method} ${url} failed with status ${response.status}`, 'external', {
|
|
105
|
+
status: response.status,
|
|
106
|
+
endpoint: url,
|
|
107
|
+
method,
|
|
108
|
+
body: errorBody,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
if (response.status === 204) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
return (await response.json());
|
|
116
|
+
}
|
|
117
|
+
catch (_) {
|
|
118
|
+
// TODO: define better behavior for non-JSON responses
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
exports.HttpService = HttpService;
|
|
124
|
+
exports.HttpService = HttpService = __decorate([
|
|
125
|
+
(0, tsyringe_1.injectable)()
|
|
126
|
+
], HttpService);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './player.service';
|
|
2
|
+
export * from './command.service';
|
|
3
|
+
export * from './http/http.service';
|
|
4
|
+
export * from './access-control.service';
|
|
5
|
+
export * from './chat.service';
|
|
6
|
+
export * from './rate-limiter.service';
|
|
7
|
+
export * from './persistence.service';
|
|
8
|
+
export * from './parallel';
|
|
9
|
+
export * from './config.service';
|
|
10
|
+
export * from '../database';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./player.service"), exports);
|
|
18
|
+
__exportStar(require("./command.service"), exports);
|
|
19
|
+
__exportStar(require("./http/http.service"), exports);
|
|
20
|
+
__exportStar(require("./access-control.service"), exports);
|
|
21
|
+
__exportStar(require("./chat.service"), exports);
|
|
22
|
+
__exportStar(require("./rate-limiter.service"), exports);
|
|
23
|
+
__exportStar(require("./persistence.service"), exports);
|
|
24
|
+
__exportStar(require("./parallel"), exports);
|
|
25
|
+
__exportStar(require("./config.service"), exports);
|
|
26
|
+
__exportStar(require("../database"), exports);
|