@open-core/framework 0.1.0-alpha.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.
Files changed (281) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +360 -0
  3. package/dist/client/client-bootstrap.d.ts +1 -0
  4. package/dist/client/client-bootstrap.js +50 -0
  5. package/dist/client/client-container.d.ts +2 -0
  6. package/dist/client/client-container.js +6 -0
  7. package/dist/client/client-core.d.ts +1 -0
  8. package/dist/client/client-core.js +7 -0
  9. package/dist/client/controllers/spawner.controller.d.ts +12 -0
  10. package/dist/client/controllers/spawner.controller.js +51 -0
  11. package/dist/client/decorators/controller.d.ts +3 -0
  12. package/dist/client/decorators/controller.js +14 -0
  13. package/dist/client/decorators/export.d.ts +7 -0
  14. package/dist/client/decorators/export.js +15 -0
  15. package/dist/client/decorators/gameEvent.d.ts +47 -0
  16. package/dist/client/decorators/gameEvent.js +54 -0
  17. package/dist/client/decorators/index.d.ts +10 -0
  18. package/dist/client/decorators/index.js +26 -0
  19. package/dist/client/decorators/interval.d.ts +7 -0
  20. package/dist/client/decorators/interval.js +15 -0
  21. package/dist/client/decorators/key.d.ts +2 -0
  22. package/dist/client/decorators/key.js +10 -0
  23. package/dist/client/decorators/localEvent.d.ts +7 -0
  24. package/dist/client/decorators/localEvent.js +15 -0
  25. package/dist/client/decorators/nui.d.ts +1 -0
  26. package/dist/client/decorators/nui.js +9 -0
  27. package/dist/client/decorators/onNet.d.ts +1 -0
  28. package/dist/client/decorators/onNet.js +9 -0
  29. package/dist/client/decorators/resourceLifecycle.d.ts +11 -0
  30. package/dist/client/decorators/resourceLifecycle.js +24 -0
  31. package/dist/client/decorators/tick.d.ts +1 -0
  32. package/dist/client/decorators/tick.js +9 -0
  33. package/dist/client/index.d.ts +7 -0
  34. package/dist/client/index.js +23 -0
  35. package/dist/client/interfaces/appearance.interface.d.ts +19 -0
  36. package/dist/client/interfaces/appearance.interface.js +2 -0
  37. package/dist/client/player/player.d.ts +262 -0
  38. package/dist/client/player/player.js +480 -0
  39. package/dist/client/player/player.loader.d.ts +1 -0
  40. package/dist/client/player/player.loader.js +22 -0
  41. package/dist/client/services/appearance.service.d.ts +6 -0
  42. package/dist/client/services/appearance.service.js +89 -0
  43. package/dist/client/services/blip.service.d.ts +112 -0
  44. package/dist/client/services/blip.service.js +215 -0
  45. package/dist/client/services/index.d.ts +9 -0
  46. package/dist/client/services/index.js +25 -0
  47. package/dist/client/services/marker.service.d.ts +94 -0
  48. package/dist/client/services/marker.service.js +153 -0
  49. package/dist/client/services/notification.service.d.ts +76 -0
  50. package/dist/client/services/notification.service.js +111 -0
  51. package/dist/client/services/ped.service.d.ts +182 -0
  52. package/dist/client/services/ped.service.js +302 -0
  53. package/dist/client/services/progress.service.d.ts +82 -0
  54. package/dist/client/services/progress.service.js +210 -0
  55. package/dist/client/services/spawn.service.d.ts +73 -0
  56. package/dist/client/services/spawn.service.js +261 -0
  57. package/dist/client/services/streaming.service.d.ts +165 -0
  58. package/dist/client/services/streaming.service.js +341 -0
  59. package/dist/client/services/textui.service.d.ts +82 -0
  60. package/dist/client/services/textui.service.js +156 -0
  61. package/dist/client/services/vehicle.service.d.ts +168 -0
  62. package/dist/client/services/vehicle.service.js +296 -0
  63. package/dist/client/system/metadata-client.keys.d.ts +13 -0
  64. package/dist/client/system/metadata-client.keys.js +16 -0
  65. package/dist/client/system/processors/export.processor.d.ts +7 -0
  66. package/dist/client/system/processors/export.processor.js +39 -0
  67. package/dist/client/system/processors/gameEvent.processor.d.ts +10 -0
  68. package/dist/client/system/processors/gameEvent.processor.js +58 -0
  69. package/dist/client/system/processors/interval.processor.d.ts +7 -0
  70. package/dist/client/system/processors/interval.processor.js +43 -0
  71. package/dist/client/system/processors/key.processor.d.ts +8 -0
  72. package/dist/client/system/processors/key.processor.js +27 -0
  73. package/dist/client/system/processors/localEvent.processor.d.ts +7 -0
  74. package/dist/client/system/processors/localEvent.processor.js +38 -0
  75. package/dist/client/system/processors/netEvent.processor.d.ts +7 -0
  76. package/dist/client/system/processors/netEvent.processor.js +38 -0
  77. package/dist/client/system/processors/nui.processor.d.ts +7 -0
  78. package/dist/client/system/processors/nui.processor.js +40 -0
  79. package/dist/client/system/processors/resourceLifecycle.processor.d.ts +9 -0
  80. package/dist/client/system/processors/resourceLifecycle.processor.js +69 -0
  81. package/dist/client/system/processors/tick.processor.d.ts +5 -0
  82. package/dist/client/system/processors/tick.processor.js +37 -0
  83. package/dist/client/system/processors.register.d.ts +1 -0
  84. package/dist/client/system/processors.register.js +27 -0
  85. package/dist/client/types/game-events.d.ts +126 -0
  86. package/dist/client/types/game-events.js +83 -0
  87. package/dist/client/types/index.d.ts +1 -0
  88. package/dist/client/types/index.js +17 -0
  89. package/dist/client/ui-bridge.d.ts +116 -0
  90. package/dist/client/ui-bridge.js +201 -0
  91. package/dist/index.d.ts +5 -0
  92. package/dist/index.js +41 -0
  93. package/dist/server/bootstrap.d.ts +16 -0
  94. package/dist/server/bootstrap.js +57 -0
  95. package/dist/server/bus/core-event-bus.d.ts +6 -0
  96. package/dist/server/bus/core-event-bus.js +31 -0
  97. package/dist/server/configs/api.config.d.ts +71 -0
  98. package/dist/server/configs/api.config.js +81 -0
  99. package/dist/server/configs/config.base.d.ts +63 -0
  100. package/dist/server/configs/config.base.js +64 -0
  101. package/dist/server/configs/index.d.ts +2 -0
  102. package/dist/server/configs/index.js +18 -0
  103. package/dist/server/container.d.ts +2 -0
  104. package/dist/server/container.js +6 -0
  105. package/dist/server/controllers/chat.controller.d.ts +10 -0
  106. package/dist/server/controllers/chat.controller.js +50 -0
  107. package/dist/server/controllers/command.controller.d.ts +7 -0
  108. package/dist/server/controllers/command.controller.js +47 -0
  109. package/dist/server/controllers/session.controller.d.ts +9 -0
  110. package/dist/server/controllers/session.controller.js +70 -0
  111. package/dist/server/core.d.ts +1 -0
  112. package/dist/server/core.js +7 -0
  113. package/dist/server/database/adapters/oxmysql.adapter.d.ts +89 -0
  114. package/dist/server/database/adapters/oxmysql.adapter.js +149 -0
  115. package/dist/server/database/database.contract.d.ts +128 -0
  116. package/dist/server/database/database.contract.js +29 -0
  117. package/dist/server/database/database.service.d.ts +216 -0
  118. package/dist/server/database/database.service.js +301 -0
  119. package/dist/server/database/index.d.ts +53 -0
  120. package/dist/server/database/index.js +70 -0
  121. package/dist/server/database/types.d.ts +67 -0
  122. package/dist/server/database/types.js +7 -0
  123. package/dist/server/database.d.ts +7 -0
  124. package/dist/server/database.js +23 -0
  125. package/dist/server/decorators/bind.d.ts +2 -0
  126. package/dist/server/decorators/bind.js +15 -0
  127. package/dist/server/decorators/command.d.ts +49 -0
  128. package/dist/server/decorators/command.js +23 -0
  129. package/dist/server/decorators/controller.d.ts +25 -0
  130. package/dist/server/decorators/controller.js +36 -0
  131. package/dist/server/decorators/export.d.ts +39 -0
  132. package/dist/server/decorators/export.js +47 -0
  133. package/dist/server/decorators/guard.d.ts +56 -0
  134. package/dist/server/decorators/guard.js +82 -0
  135. package/dist/server/decorators/index.d.ts +10 -0
  136. package/dist/server/decorators/index.js +29 -0
  137. package/dist/server/decorators/onFiveMEvent.d.ts +6 -0
  138. package/dist/server/decorators/onFiveMEvent.js +14 -0
  139. package/dist/server/decorators/onFrameworkEvent.d.ts +22 -0
  140. package/dist/server/decorators/onFrameworkEvent.js +29 -0
  141. package/dist/server/decorators/onNet.d.ts +58 -0
  142. package/dist/server/decorators/onNet.js +57 -0
  143. package/dist/server/decorators/onTick.d.ts +32 -0
  144. package/dist/server/decorators/onTick.js +40 -0
  145. package/dist/server/decorators/public.d.ts +27 -0
  146. package/dist/server/decorators/public.js +36 -0
  147. package/dist/server/decorators/requiresState.d.ts +56 -0
  148. package/dist/server/decorators/requiresState.js +63 -0
  149. package/dist/server/decorators/throttle.d.ts +48 -0
  150. package/dist/server/decorators/throttle.js +63 -0
  151. package/dist/server/decorators/utils.d.ts +57 -0
  152. package/dist/server/decorators/utils.js +63 -0
  153. package/dist/server/entities/index.d.ts +1 -0
  154. package/dist/server/entities/index.js +17 -0
  155. package/dist/server/entities/player.d.ts +157 -0
  156. package/dist/server/entities/player.js +217 -0
  157. package/dist/server/error-handler.d.ts +2 -0
  158. package/dist/server/error-handler.js +43 -0
  159. package/dist/server/helpers/resolve-method.d.ts +5 -0
  160. package/dist/server/helpers/resolve-method.js +18 -0
  161. package/dist/server/index.d.ts +10 -0
  162. package/dist/server/index.js +31 -0
  163. package/dist/server/loaders/exports.loader.d.ts +0 -0
  164. package/dist/server/loaders/exports.loader.js +23 -0
  165. package/dist/server/loaders/playerSession.loader.d.ts +1 -0
  166. package/dist/server/loaders/playerSession.loader.js +51 -0
  167. package/dist/server/services/access-control.service.d.ts +56 -0
  168. package/dist/server/services/access-control.service.js +99 -0
  169. package/dist/server/services/chat.service.d.ts +7 -0
  170. package/dist/server/services/chat.service.js +31 -0
  171. package/dist/server/services/command.service.d.ts +15 -0
  172. package/dist/server/services/command.service.js +77 -0
  173. package/dist/server/services/config.service.d.ts +75 -0
  174. package/dist/server/services/config.service.js +116 -0
  175. package/dist/server/services/default/default-security.handler.d.ts +6 -0
  176. package/dist/server/services/default/default-security.handler.js +26 -0
  177. package/dist/server/services/http/http.service.d.ts +50 -0
  178. package/dist/server/services/http/http.service.js +126 -0
  179. package/dist/server/services/index.d.ts +10 -0
  180. package/dist/server/services/index.js +26 -0
  181. package/dist/server/services/parallel/index.d.ts +49 -0
  182. package/dist/server/services/parallel/index.js +67 -0
  183. package/dist/server/services/parallel/parallel-compute.service.d.ts +132 -0
  184. package/dist/server/services/parallel/parallel-compute.service.js +449 -0
  185. package/dist/server/services/parallel/types.d.ts +188 -0
  186. package/dist/server/services/parallel/types.js +7 -0
  187. package/dist/server/services/parallel/worker-pool.d.ts +83 -0
  188. package/dist/server/services/parallel/worker-pool.js +350 -0
  189. package/dist/server/services/parallel/worker.d.ts +19 -0
  190. package/dist/server/services/parallel/worker.js +49 -0
  191. package/dist/server/services/persistence.service.d.ts +59 -0
  192. package/dist/server/services/persistence.service.js +166 -0
  193. package/dist/server/services/player.service.d.ts +96 -0
  194. package/dist/server/services/player.service.js +132 -0
  195. package/dist/server/services/rate-limiter.service.d.ts +5 -0
  196. package/dist/server/services/rate-limiter.service.js +39 -0
  197. package/dist/server/services/registers.d.ts +1 -0
  198. package/dist/server/services/registers.js +18 -0
  199. package/dist/server/setup.d.ts +9 -0
  200. package/dist/server/setup.js +28 -0
  201. package/dist/server/system/metadata-server.keys.d.ts +10 -0
  202. package/dist/server/system/metadata-server.keys.js +13 -0
  203. package/dist/server/system/processors/command.processor.d.ts +9 -0
  204. package/dist/server/system/processors/command.processor.js +30 -0
  205. package/dist/server/system/processors/coreEvent.processor.d.ts +7 -0
  206. package/dist/server/system/processors/coreEvent.processor.js +41 -0
  207. package/dist/server/system/processors/export.processor.d.ts +7 -0
  208. package/dist/server/system/processors/export.processor.js +30 -0
  209. package/dist/server/system/processors/fivemEvent.processor.d.ts +7 -0
  210. package/dist/server/system/processors/fivemEvent.processor.js +40 -0
  211. package/dist/server/system/processors/netEvent.processor.d.ts +11 -0
  212. package/dist/server/system/processors/netEvent.processor.js +103 -0
  213. package/dist/server/system/processors/tick.processor.d.ts +5 -0
  214. package/dist/server/system/processors/tick.processor.js +36 -0
  215. package/dist/server/system/processors.register.d.ts +1 -0
  216. package/dist/server/system/processors.register.js +23 -0
  217. package/dist/server/system/schema-generator.d.ts +2 -0
  218. package/dist/server/system/schema-generator.js +34 -0
  219. package/dist/server/templates/admin/admin.controller-template.d.ts +12 -0
  220. package/dist/server/templates/admin/admin.controller-template.js +2 -0
  221. package/dist/server/templates/auth/auth-provider.contract.d.ts +58 -0
  222. package/dist/server/templates/auth/auth-provider.contract.js +23 -0
  223. package/dist/server/templates/index.d.ts +8 -0
  224. package/dist/server/templates/index.js +21 -0
  225. package/dist/server/templates/persistence/index.d.ts +30 -0
  226. package/dist/server/templates/persistence/index.js +34 -0
  227. package/dist/server/templates/persistence/player-persistence.contract.d.ts +86 -0
  228. package/dist/server/templates/persistence/player-persistence.contract.js +52 -0
  229. package/dist/server/templates/repository/index.d.ts +57 -0
  230. package/dist/server/templates/repository/index.js +61 -0
  231. package/dist/server/templates/repository/repository.contract.d.ts +224 -0
  232. package/dist/server/templates/repository/repository.contract.js +342 -0
  233. package/dist/server/templates/repository/repository.types.d.ts +51 -0
  234. package/dist/server/templates/repository/repository.types.js +7 -0
  235. package/dist/server/templates/security/permission.types.d.ts +32 -0
  236. package/dist/server/templates/security/permission.types.js +2 -0
  237. package/dist/server/templates/security/principal-provider.contract.d.ts +43 -0
  238. package/dist/server/templates/security/principal-provider.contract.js +19 -0
  239. package/dist/server/templates/security/security-handler.contract.d.ts +5 -0
  240. package/dist/server/templates/security/security-handler.contract.js +6 -0
  241. package/dist/server/types/core-events.d.ts +22 -0
  242. package/dist/server/types/core-events.js +2 -0
  243. package/dist/server/types/security.types.d.ts +7 -0
  244. package/dist/server/types/security.types.js +2 -0
  245. package/dist/shared/index.d.ts +1 -0
  246. package/dist/shared/index.js +17 -0
  247. package/dist/shared/logger/core-logger.d.ts +35 -0
  248. package/dist/shared/logger/core-logger.js +52 -0
  249. package/dist/shared/logger/index.d.ts +11 -0
  250. package/dist/shared/logger/index.js +26 -0
  251. package/dist/shared/logger/logger.config.d.ts +47 -0
  252. package/dist/shared/logger/logger.config.js +33 -0
  253. package/dist/shared/logger/logger.service.d.ts +161 -0
  254. package/dist/shared/logger/logger.service.js +279 -0
  255. package/dist/shared/logger/logger.types.d.ts +85 -0
  256. package/dist/shared/logger/logger.types.js +74 -0
  257. package/dist/shared/logger/transports/buffered.transport.d.ts +88 -0
  258. package/dist/shared/logger/transports/buffered.transport.js +174 -0
  259. package/dist/shared/logger/transports/console.transport.d.ts +37 -0
  260. package/dist/shared/logger/transports/console.transport.js +134 -0
  261. package/dist/shared/logger/transports/index.d.ts +3 -0
  262. package/dist/shared/logger/transports/index.js +19 -0
  263. package/dist/shared/logger/transports/transport.interface.d.ts +40 -0
  264. package/dist/shared/logger/transports/transport.interface.js +2 -0
  265. package/dist/system/class-constructor.d.ts +1 -0
  266. package/dist/system/class-constructor.js +2 -0
  267. package/dist/system/decorator-processor.d.ts +4 -0
  268. package/dist/system/decorator-processor.js +2 -0
  269. package/dist/system/metadata.scanner.d.ts +7 -0
  270. package/dist/system/metadata.scanner.js +45 -0
  271. package/dist/utils/errors.d.ts +14 -0
  272. package/dist/utils/errors.js +25 -0
  273. package/dist/utils/index.d.ts +4 -0
  274. package/dist/utils/index.js +20 -0
  275. package/dist/utils/result.d.ts +12 -0
  276. package/dist/utils/result.js +10 -0
  277. package/dist/utils/rgb.d.ts +5 -0
  278. package/dist/utils/rgb.js +2 -0
  279. package/dist/utils/vector3.d.ts +13 -0
  280. package/dist/utils/vector3.js +27 -0
  281. package/package.json +98 -0
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RequiresState = RequiresState;
4
+ const utils_1 = require("../../utils");
5
+ /**
6
+ * Enforces gameplay state requirements before executing a method.
7
+ *
8
+ * The decorator intercepts the method call and verifies whether
9
+ * the player satisfies required state flags (e.g. "dead", "cuffed",
10
+ * "on_duty_police").
11
+ *
12
+ * ## Whitelist (`has`)
13
+ * The player MUST have *all* required states. Missing any state blocks execution.
14
+ *
15
+ * ## Blacklist (`missing`)
16
+ * The player MUST NOT have any of the forbidden states.
17
+ *
18
+ * ## Error Handling
19
+ * - Throws a normal Error if the method is called without a valid Player.
20
+ * - Throws an `AppError(GAME_STATE_ERROR)` if validation fails.
21
+ *
22
+ * ## Example
23
+ * ```ts
24
+ * @RequiresState({ missing: ["dead", "cuffed"] })
25
+ * openInventory(player: Server.Player) { ... }
26
+ *
27
+ * @RequiresState({
28
+ * has: ["police_duty"],
29
+ * missing: ["dead"],
30
+ * errorMessage: "You must be on duty to access the armory."
31
+ * })
32
+ * openArmory(player: Server.Player) { ... }
33
+ * ```
34
+ *
35
+ * @param req - State validation configuration.
36
+ */
37
+ function RequiresState(req) {
38
+ return function (target, propertyKey, descriptor) {
39
+ const originalMethod = descriptor.value;
40
+ descriptor.value = async function (...args) {
41
+ const player = args[0];
42
+ if (!player) {
43
+ throw new Error(`@RequiresState used on ${propertyKey} without Player context`);
44
+ }
45
+ if (req.has) {
46
+ for (const state of req.has) {
47
+ if (!player.hasState(state)) {
48
+ throw new utils_1.AppError('GAME_STATE_ERROR', req.errorMessage || `You must be [${state}] to do this.`, 'client');
49
+ }
50
+ }
51
+ }
52
+ if (req.missing) {
53
+ for (const state of req.missing) {
54
+ if (player.hasState(state)) {
55
+ throw new utils_1.AppError('GAME_STATE_ERROR', req.errorMessage || `You can't do this while you're [${state}].`, 'client');
56
+ }
57
+ }
58
+ }
59
+ return originalMethod.apply(this, args);
60
+ };
61
+ return descriptor;
62
+ };
63
+ }
@@ -0,0 +1,48 @@
1
+ import type { SecurityAction } from '../types/security.types';
2
+ interface ThrottleOptions {
3
+ /**
4
+ * limit of calls per windowMs
5
+ */
6
+ limit: number;
7
+ /**
8
+ * time window for numeric overload
9
+ */
10
+ windowMs: number;
11
+ /**
12
+ * action to perform on exceed limit
13
+ */
14
+ onExceed?: SecurityAction;
15
+ /**
16
+ * custom message to display on exceed limit (ERROR MESSAGE)
17
+ */
18
+ message?: string;
19
+ }
20
+ /**
21
+ * Rate-limits how frequently a method can be called by a specific player.
22
+ *
23
+ * Uses `RateLimiterService` and a unique key composed of:
24
+ * `playerID:ClassName:MethodName`.
25
+ *
26
+ * ## Overload
27
+ * - `@Throttle(5, 1000)` → limit = 5 calls per 1000 ms
28
+ * - `@Throttle({ limit, windowMs, onExceed, message })`
29
+ *
30
+ * ## Behavior
31
+ * If the rate limit is exceeded:
32
+ * - A `SecurityError` is thrown.
33
+ * - Optional custom behavior (`onExceed`) may be executed.
34
+ *
35
+ * ## Example
36
+ * ```ts
37
+ * @Throttle(5, 2000)
38
+ * async search(player: Server.Player, query: string) { ... }
39
+ *
40
+ * @Throttle({ limit: 1, windowMs: 5000, message: "Too fast!" })
41
+ * async placeOrder(player: Server.Player) { ... }
42
+ * ```
43
+ *
44
+ * @param optionsOrLimit - Number (simple mode) or full config object.
45
+ * @param windowMs - Time window for numeric overload.
46
+ */
47
+ export declare function Throttle(optionsOrLimit: number | ThrottleOptions, windowMs?: number): (target: any, propertyKey: string, descriptor?: PropertyDescriptor) => PropertyDescriptor | undefined;
48
+ export {};
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Throttle = Throttle;
4
+ const tsyringe_1 = require("tsyringe");
5
+ const rate_limiter_service_1 = require("../services/rate-limiter.service");
6
+ const utils_1 = require("../../utils");
7
+ /**
8
+ * Rate-limits how frequently a method can be called by a specific player.
9
+ *
10
+ * Uses `RateLimiterService` and a unique key composed of:
11
+ * `playerID:ClassName:MethodName`.
12
+ *
13
+ * ## Overload
14
+ * - `@Throttle(5, 1000)` → limit = 5 calls per 1000 ms
15
+ * - `@Throttle({ limit, windowMs, onExceed, message })`
16
+ *
17
+ * ## Behavior
18
+ * If the rate limit is exceeded:
19
+ * - A `SecurityError` is thrown.
20
+ * - Optional custom behavior (`onExceed`) may be executed.
21
+ *
22
+ * ## Example
23
+ * ```ts
24
+ * @Throttle(5, 2000)
25
+ * async search(player: Server.Player, query: string) { ... }
26
+ *
27
+ * @Throttle({ limit: 1, windowMs: 5000, message: "Too fast!" })
28
+ * async placeOrder(player: Server.Player) { ... }
29
+ * ```
30
+ *
31
+ * @param optionsOrLimit - Number (simple mode) or full config object.
32
+ * @param windowMs - Time window for numeric overload.
33
+ */
34
+ function Throttle(optionsOrLimit, windowMs) {
35
+ return function (target, propertyKey, descriptor) {
36
+ if (!descriptor) {
37
+ // In benchmarks or edge cases, skip method wrapping
38
+ // This should NOT happen in production code with proper TypeScript compilation
39
+ // Note: Throttle cannot work without descriptor, so we just skip it
40
+ return;
41
+ }
42
+ const originalMethod = descriptor.value;
43
+ let opts;
44
+ if (typeof optionsOrLimit === 'number') {
45
+ opts = { limit: optionsOrLimit, windowMs: windowMs || 1000, onExceed: 'LOG' };
46
+ }
47
+ else {
48
+ opts = Object.assign({ onExceed: 'LOG' }, optionsOrLimit);
49
+ }
50
+ descriptor.value = async function (...args) {
51
+ const player = args[0];
52
+ if (player === null || player === void 0 ? void 0 : player.clientID) {
53
+ const service = tsyringe_1.container.resolve(rate_limiter_service_1.RateLimiterService);
54
+ const key = `${player.clientID}:${target.constructor.name}:${propertyKey}`;
55
+ if (!service.checkLimit(key, opts.limit, opts.windowMs)) {
56
+ throw new utils_1.SecurityError(opts.onExceed, opts.message || `Rate limit exceeded on ${propertyKey}`, { limit: opts.limit, key });
57
+ }
58
+ }
59
+ return originalMethod.apply(this, args);
60
+ };
61
+ return descriptor;
62
+ };
63
+ }
@@ -0,0 +1,57 @@
1
+ import type { BindingScope } from './bind';
2
+ /**
3
+ * Marks a class as a framework-managed Service.
4
+ *
5
+ * The decorator binds the class into the dependency injection
6
+ * container using the provided scope (default: `singleton`).
7
+ *
8
+ * Services represent reusable, stateless or stateful logic such as:
9
+ * - Business rules
10
+ * - Utility layers
11
+ * - Gameplay systems
12
+ * - Internal modules
13
+ *
14
+ * This decorator is a convenience wrapper over `@Bind()`, allowing
15
+ * future extension of service-specific behavior without changing
16
+ * end-user code.
17
+ *
18
+ * ## Example
19
+ * ```ts
20
+ * @Service()
21
+ * export class InventoryService {
22
+ * addItem() { ... }
23
+ * }
24
+ * ```
25
+ *
26
+ * @param options.scope - Optional binding scope (`singleton` | `transient`)
27
+ */
28
+ export declare function Service(options?: {
29
+ scope?: BindingScope;
30
+ }): (target: any) => void;
31
+ /**
32
+ * Marks a class as a Repository within the framework.
33
+ *
34
+ * A Repository abstracts persistence operations (e.g., database,
35
+ * API, in-memory, or hybrid storage). It is registered in the
36
+ * dependency injection container using the provided scope
37
+ * (default: `singleton`).
38
+ *
39
+ * `@Repo()` is intentionally separate from `@Service()` to clearly
40
+ * distinguish persistence-oriented classes from business logic.
41
+ * In the future, repository-specific behavior (caching layers,
42
+ * transactional wrappers, profiling, etc.) can be attached here
43
+ * without modifying user code.
44
+ *
45
+ * ## Example
46
+ * ```ts
47
+ * @Repo()
48
+ * export class AccountRepository {
49
+ * async findById(id: string) { ... }
50
+ * }
51
+ * ```
52
+ *
53
+ * @param options.scope - Optional binding scope (`singleton` | `transient`)
54
+ */
55
+ export declare function Repo(options?: {
56
+ scope?: BindingScope;
57
+ }): (target: any) => void;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Service = Service;
4
+ exports.Repo = Repo;
5
+ const bind_1 = require("./bind");
6
+ /**
7
+ * Marks a class as a framework-managed Service.
8
+ *
9
+ * The decorator binds the class into the dependency injection
10
+ * container using the provided scope (default: `singleton`).
11
+ *
12
+ * Services represent reusable, stateless or stateful logic such as:
13
+ * - Business rules
14
+ * - Utility layers
15
+ * - Gameplay systems
16
+ * - Internal modules
17
+ *
18
+ * This decorator is a convenience wrapper over `@Bind()`, allowing
19
+ * future extension of service-specific behavior without changing
20
+ * end-user code.
21
+ *
22
+ * ## Example
23
+ * ```ts
24
+ * @Service()
25
+ * export class InventoryService {
26
+ * addItem() { ... }
27
+ * }
28
+ * ```
29
+ *
30
+ * @param options.scope - Optional binding scope (`singleton` | `transient`)
31
+ */
32
+ function Service(options) {
33
+ var _a;
34
+ return (0, bind_1.Bind)((_a = options === null || options === void 0 ? void 0 : options.scope) !== null && _a !== void 0 ? _a : 'singleton');
35
+ }
36
+ /**
37
+ * Marks a class as a Repository within the framework.
38
+ *
39
+ * A Repository abstracts persistence operations (e.g., database,
40
+ * API, in-memory, or hybrid storage). It is registered in the
41
+ * dependency injection container using the provided scope
42
+ * (default: `singleton`).
43
+ *
44
+ * `@Repo()` is intentionally separate from `@Service()` to clearly
45
+ * distinguish persistence-oriented classes from business logic.
46
+ * In the future, repository-specific behavior (caching layers,
47
+ * transactional wrappers, profiling, etc.) can be attached here
48
+ * without modifying user code.
49
+ *
50
+ * ## Example
51
+ * ```ts
52
+ * @Repo()
53
+ * export class AccountRepository {
54
+ * async findById(id: string) { ... }
55
+ * }
56
+ * ```
57
+ *
58
+ * @param options.scope - Optional binding scope (`singleton` | `transient`)
59
+ */
60
+ function Repo(options) {
61
+ var _a;
62
+ return (0, bind_1.Bind)((_a = options === null || options === void 0 ? void 0 : options.scope) !== null && _a !== void 0 ? _a : 'singleton');
63
+ }
@@ -0,0 +1 @@
1
+ export * from './player';
@@ -0,0 +1,17 @@
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"), exports);
@@ -0,0 +1,157 @@
1
+ import type { Vector3 } from '../../utils';
2
+ import type { LinkedID, PlayerSession } from '../services/player.service';
3
+ /**
4
+ * Core-level representation of a connected player on the server.
5
+ *
6
+ * This class wraps FiveM natives and session information.
7
+ * It serves as an abstraction layer to interact with the connected client
8
+ * (kicking, teleporting, emitting events) without dealing with raw IDs everywhere.
9
+ *
10
+ * ⚠️ **Design Note:** This class does NOT contain gameplay logic (money, jobs, inventory).
11
+ * Domain logic should live in your modules' services/models (e.g., `EconomyService`, `JobModel`).
12
+ */
13
+ export declare class Player {
14
+ private readonly session;
15
+ private states;
16
+ /**
17
+ * Creates a new Player entity instance.
18
+ * This is typically instantiated by the `PlayerService` upon connection.
19
+ *
20
+ * @param session - The internal session data structure holding ID and metadata.
21
+ */
22
+ constructor(session: PlayerSession);
23
+ /**
24
+ * The numeric FiveM Server ID (Source) of the player.
25
+ * Useful for internal logic and array indexing.
26
+ */
27
+ get clientID(): number;
28
+ /**
29
+ * The FiveM Server ID as a string.
30
+ * Required by most FiveM native functions (e.g., `GetPlayerName`, `DropPlayer`).
31
+ */
32
+ get clientIDStr(): string;
33
+ /**
34
+ * The persistent Account ID linked to this session, if the player is authenticated.
35
+ * Returns `undefined` if the player has not logged in yet.
36
+ */
37
+ get accountID(): string | undefined;
38
+ /**
39
+ * The display name of the player (Steam name or FiveM username).
40
+ */
41
+ get name(): string;
42
+ /**
43
+ * Retrieves all platform identifiers associated with the player (steam, license, discord, ip, etc.).
44
+ *
45
+ * @returns An array of identifier strings (e.g., `['steam:11000...', 'license:2332...']`).
46
+ */
47
+ getIdentifiers(): string[];
48
+ /**
49
+ * Sends a network event exclusively to this specific player (Client-side).
50
+ * Wrapper for `emitNet` ensuring the correct target Source ID is used.
51
+ *
52
+ * @param eventName - The name of the event to trigger on the client.
53
+ * @param args - Data to send to the client.
54
+ */
55
+ emit(eventName: string, ...args: any[]): void;
56
+ /**
57
+ * Teleports the player to a given position using Server-Side natives.
58
+ *
59
+ * **Note:** This forces the entity position on the server. For smoother gameplay transitions
60
+ * (e.g., inside interiors or across the map), consider using `teleportClient`.
61
+ *
62
+ * @param vector - The target coordinates (x, y, z).
63
+ */
64
+ teleport(vector: Vector3): void;
65
+ /**
66
+ * Requests the Client to teleport itself via the Core Spawner system.
67
+ *
68
+ * This method is preferred for gameplay logic as it allows the client to handle
69
+ * loading screens, fading, and collision loading gracefully.
70
+ *
71
+ * @param vector - The target coordinates (x, y, z).
72
+ */
73
+ teleportClient(vector: Vector3): void;
74
+ /**
75
+ * Disconnects the player from the server.
76
+ *
77
+ * @param reason - The message displayed to the player upon disconnection.
78
+ */
79
+ kick(reason?: string): void;
80
+ /**
81
+ * Sets the routing bucket (virtual world / dimension) for the player.
82
+ * Players in different buckets cannot see or interact with each other.
83
+ *
84
+ * @param bucket - The bucket ID (0 is the default shared world).
85
+ */
86
+ setRoutingBucket(bucket: number): void;
87
+ /**
88
+ * Stores arbitrary transient metadata for this player's session.
89
+ * Useful for flags like `isDead`, `isInRaid`, `lastLocation`, etc.
90
+ *
91
+ * @param key - The unique key for the metadata.
92
+ * @param value - The value to store.
93
+ */
94
+ setMeta(key: string, value: unknown): void;
95
+ /**
96
+ * Retrieves metadata previously stored in the session.
97
+ *
98
+ * @template T - The expected type of the value.
99
+ * @param key - The metadata key.
100
+ * @returns The value cast to T, or `undefined` if not set.
101
+ */
102
+ getMeta<T = unknown>(key: string): T | undefined;
103
+ /**
104
+ * Links a persistent Account ID to the current session.
105
+ * Should be called after successful authentication.
106
+ *
107
+ * @param accountID - The unique ID from the database.
108
+ */
109
+ linkAccount(accountID: LinkedID): void;
110
+ /**
111
+ * Checks if the player currently possesses a specific state flag.
112
+ *
113
+ * @param state - The unique string identifier of the state (e.g., 'dead', 'cuffed').
114
+ * @returns `true` if the state is active, `false` otherwise.
115
+ */
116
+ hasState(state: string): boolean;
117
+ /**
118
+ * Applies a state flag to the player.
119
+ *
120
+ * @remarks
121
+ * Since states are stored in a `Set`, adding an existing state has no effect (idempotent).
122
+ * Ideally, this should trigger a sync event to the client if needed.
123
+ *
124
+ * @param state - The state key to add.
125
+ */
126
+ addState(state: string): void;
127
+ /**
128
+ * Removes a specific state flag from the player.
129
+ *
130
+ * @param state - The state key to remove.
131
+ */
132
+ removeState(state: string): void;
133
+ /**
134
+ * Toggles the presence of a state flag.
135
+ *
136
+ * @param state - The state key to toggle.
137
+ * @param force - If provided, forces the state to be added (`true`) or removed (`false`) regardless of its current status.
138
+ *
139
+ * @returns The final status of the state (`true` if active, `false` if inactive).
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * // Standard toggle
144
+ * player.toggleState('duty'); // turns on if off, off if on
145
+ *
146
+ * // Force enable (equivalent to addState but returns boolean)
147
+ * player.toggleState('duty', true); // always results in true
148
+ * ```
149
+ */
150
+ toggleState(state: string, force?: boolean): boolean;
151
+ /**
152
+ * Retrieves a snapshot of all currently active state flags for this player.
153
+ *
154
+ * @returns An array containing all active state keys.
155
+ */
156
+ getStates(): string[];
157
+ }
@@ -0,0 +1,217 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Player = void 0;
4
+ /**
5
+ * Core-level representation of a connected player on the server.
6
+ *
7
+ * This class wraps FiveM natives and session information.
8
+ * It serves as an abstraction layer to interact with the connected client
9
+ * (kicking, teleporting, emitting events) without dealing with raw IDs everywhere.
10
+ *
11
+ * ⚠️ **Design Note:** This class does NOT contain gameplay logic (money, jobs, inventory).
12
+ * Domain logic should live in your modules' services/models (e.g., `EconomyService`, `JobModel`).
13
+ */
14
+ class Player {
15
+ /**
16
+ * Creates a new Player entity instance.
17
+ * This is typically instantiated by the `PlayerService` upon connection.
18
+ *
19
+ * @param session - The internal session data structure holding ID and metadata.
20
+ */
21
+ constructor(session) {
22
+ this.session = session;
23
+ this.states = new Set();
24
+ }
25
+ /**
26
+ * The numeric FiveM Server ID (Source) of the player.
27
+ * Useful for internal logic and array indexing.
28
+ */
29
+ get clientID() {
30
+ return this.session.clientID;
31
+ }
32
+ /**
33
+ * The FiveM Server ID as a string.
34
+ * Required by most FiveM native functions (e.g., `GetPlayerName`, `DropPlayer`).
35
+ */
36
+ get clientIDStr() {
37
+ return this.session.clientID.toString();
38
+ }
39
+ /**
40
+ * The persistent Account ID linked to this session, if the player is authenticated.
41
+ * Returns `undefined` if the player has not logged in yet.
42
+ */
43
+ get accountID() {
44
+ var _a;
45
+ return (_a = this.session.accountID) === null || _a === void 0 ? void 0 : _a.toString();
46
+ }
47
+ /**
48
+ * The display name of the player (Steam name or FiveM username).
49
+ */
50
+ get name() {
51
+ return GetPlayerName(this.clientIDStr);
52
+ }
53
+ /**
54
+ * Retrieves all platform identifiers associated with the player (steam, license, discord, ip, etc.).
55
+ *
56
+ * @returns An array of identifier strings (e.g., `['steam:11000...', 'license:2332...']`).
57
+ */
58
+ getIdentifiers() {
59
+ const ids = [];
60
+ for (let i = 0;; i++) {
61
+ const id = GetPlayerIdentifier(this.clientIDStr, i);
62
+ if (!id)
63
+ break;
64
+ ids.push(id);
65
+ }
66
+ return ids;
67
+ }
68
+ /**
69
+ * Sends a network event exclusively to this specific player (Client-side).
70
+ * Wrapper for `emitNet` ensuring the correct target Source ID is used.
71
+ *
72
+ * @param eventName - The name of the event to trigger on the client.
73
+ * @param args - Data to send to the client.
74
+ */
75
+ emit(eventName, ...args) {
76
+ emitNet(eventName, this.clientID, ...args);
77
+ }
78
+ /**
79
+ * Teleports the player to a given position using Server-Side natives.
80
+ *
81
+ * **Note:** This forces the entity position on the server. For smoother gameplay transitions
82
+ * (e.g., inside interiors or across the map), consider using `teleportClient`.
83
+ *
84
+ * @param vector - The target coordinates (x, y, z).
85
+ */
86
+ teleport(vector) {
87
+ SetEntityCoords(GetPlayerPed(this.clientIDStr), vector.x, vector.y, vector.z, false, false, false, true);
88
+ }
89
+ /**
90
+ * Requests the Client to teleport itself via the Core Spawner system.
91
+ *
92
+ * This method is preferred for gameplay logic as it allows the client to handle
93
+ * loading screens, fading, and collision loading gracefully.
94
+ *
95
+ * @param vector - The target coordinates (x, y, z).
96
+ */
97
+ teleportClient(vector) {
98
+ this.emit('opencore:spawner:teleport', vector);
99
+ }
100
+ /**
101
+ * Disconnects the player from the server.
102
+ *
103
+ * @param reason - The message displayed to the player upon disconnection.
104
+ */
105
+ kick(reason = 'Kicked from server') {
106
+ DropPlayer(this.clientID.toString(), reason);
107
+ }
108
+ /**
109
+ * Sets the routing bucket (virtual world / dimension) for the player.
110
+ * Players in different buckets cannot see or interact with each other.
111
+ *
112
+ * @param bucket - The bucket ID (0 is the default shared world).
113
+ */
114
+ setRoutingBucket(bucket) {
115
+ SetPlayerRoutingBucket(this.clientID.toString(), bucket);
116
+ }
117
+ /**
118
+ * Stores arbitrary transient metadata for this player's session.
119
+ * Useful for flags like `isDead`, `isInRaid`, `lastLocation`, etc.
120
+ *
121
+ * @param key - The unique key for the metadata.
122
+ * @param value - The value to store.
123
+ */
124
+ setMeta(key, value) {
125
+ this.session.meta[key] = value;
126
+ }
127
+ /**
128
+ * Retrieves metadata previously stored in the session.
129
+ *
130
+ * @template T - The expected type of the value.
131
+ * @param key - The metadata key.
132
+ * @returns The value cast to T, or `undefined` if not set.
133
+ */
134
+ getMeta(key) {
135
+ return this.session.meta[key];
136
+ }
137
+ /**
138
+ * Links a persistent Account ID to the current session.
139
+ * Should be called after successful authentication.
140
+ *
141
+ * @param accountID - The unique ID from the database.
142
+ */
143
+ linkAccount(accountID) {
144
+ this.session.accountID = accountID;
145
+ }
146
+ /**
147
+ * Checks if the player currently possesses a specific state flag.
148
+ *
149
+ * @param state - The unique string identifier of the state (e.g., 'dead', 'cuffed').
150
+ * @returns `true` if the state is active, `false` otherwise.
151
+ */
152
+ hasState(state) {
153
+ return this.states.has(state);
154
+ }
155
+ /**
156
+ * Applies a state flag to the player.
157
+ *
158
+ * @remarks
159
+ * Since states are stored in a `Set`, adding an existing state has no effect (idempotent).
160
+ * Ideally, this should trigger a sync event to the client if needed.
161
+ *
162
+ * @param state - The state key to add.
163
+ */
164
+ addState(state) {
165
+ this.states.add(state);
166
+ // this.emit('core:state:add', state) // ? optional !!
167
+ }
168
+ /**
169
+ * Removes a specific state flag from the player.
170
+ *
171
+ * @param state - The state key to remove.
172
+ */
173
+ removeState(state) {
174
+ this.states.delete(state);
175
+ // this.emit('core:state:remove', state) // ? optional !!
176
+ }
177
+ /**
178
+ * Toggles the presence of a state flag.
179
+ *
180
+ * @param state - The state key to toggle.
181
+ * @param force - If provided, forces the state to be added (`true`) or removed (`false`) regardless of its current status.
182
+ *
183
+ * @returns The final status of the state (`true` if active, `false` if inactive).
184
+ *
185
+ * @example
186
+ * ```ts
187
+ * // Standard toggle
188
+ * player.toggleState('duty'); // turns on if off, off if on
189
+ *
190
+ * // Force enable (equivalent to addState but returns boolean)
191
+ * player.toggleState('duty', true); // always results in true
192
+ * ```
193
+ */
194
+ toggleState(state, force) {
195
+ if (force !== undefined) {
196
+ force ? this.addState(state) : this.removeState(state);
197
+ return force;
198
+ }
199
+ if (this.hasState(state)) {
200
+ this.removeState(state);
201
+ return false;
202
+ }
203
+ else {
204
+ this.addState(state);
205
+ return true;
206
+ }
207
+ }
208
+ /**
209
+ * Retrieves a snapshot of all currently active state flags for this player.
210
+ *
211
+ * @returns An array containing all active state keys.
212
+ */
213
+ getStates() {
214
+ return Array.from(this.states);
215
+ }
216
+ }
217
+ exports.Player = Player;
@@ -0,0 +1,2 @@
1
+ import type { CommandMetadata } from './decorators/command';
2
+ export declare function handleCommandError(error: unknown, meta: CommandMetadata, playerId: number | null): void;