@open-core/framework 0.2.1-beta.1 → 0.2.4

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 (38) hide show
  1. package/LICENSE +373 -373
  2. package/README.md +217 -217
  3. package/dist/adapters/node/node-entity-server.js +3 -0
  4. package/dist/adapters/node/node-exports.d.ts +2 -2
  5. package/dist/kernel/utils/vector3.d.ts +1 -0
  6. package/dist/kernel/utils/vector3.js +1 -0
  7. package/dist/runtime/client/services/appearance.service.js +4 -0
  8. package/dist/runtime/server/bootstrap.js +1 -1
  9. package/dist/runtime/server/bootstrap.validation.js +2 -0
  10. package/dist/runtime/server/bus/core-event-bus.js +5 -2
  11. package/dist/runtime/server/controllers/principal-export.controller.js +1 -1
  12. package/dist/runtime/server/decorators/command.d.ts +6 -3
  13. package/dist/runtime/server/decorators/onNet.d.ts +5 -2
  14. package/dist/runtime/server/decorators/throttle.js +3 -1
  15. package/dist/runtime/server/helpers/command-validation.helper.d.ts +1 -1
  16. package/dist/runtime/server/helpers/function-helper.d.ts +1 -1
  17. package/dist/runtime/server/services/chat.service.d.ts +33 -0
  18. package/dist/runtime/server/services/chat.service.js +67 -1
  19. package/dist/runtime/server/services/core/command.service.d.ts +1 -1
  20. package/dist/runtime/server/services/parallel/worker-pool.js +4 -0
  21. package/dist/runtime/server/services/ports/command-execution.port.d.ts +1 -1
  22. package/dist/runtime/server/services/remote/remote-command.service.d.ts +1 -1
  23. package/dist/runtime/server/services/services.register.js +2 -2
  24. package/package.json +100 -98
  25. package/dist/kernel/di/tokens.d.ts +0 -30
  26. package/dist/kernel/di/tokens.js +0 -38
  27. package/dist/runtime/client/interfaces/appearance.interface.d.ts +0 -25
  28. package/dist/runtime/client/interfaces/appearance.interface.js +0 -2
  29. package/dist/runtime/server/controllers/command.controller.d.ts +0 -15
  30. package/dist/runtime/server/controllers/command.controller.js +0 -100
  31. package/dist/runtime/server/services/access-control.service.d.ts +0 -59
  32. package/dist/runtime/server/services/access-control.service.js +0 -127
  33. package/dist/runtime/server/services/core/vehicle-modification.service.d.ts +0 -104
  34. package/dist/runtime/server/services/core/vehicle-modification.service.js +0 -330
  35. package/dist/runtime/server/services/core/vehicle.service.d.ts +0 -128
  36. package/dist/runtime/server/services/core/vehicle.service.js +0 -391
  37. package/dist/runtime/server/services/remote/remote-principal.provider.d.ts +0 -55
  38. package/dist/runtime/server/services/remote/remote-principal.provider.js +0 -130
@@ -1,59 +0,0 @@
1
- import { Server } from '../../..'
2
- import { PrincipalProviderContract } from '../contracts'
3
- /**
4
- * **Core Security Service**
5
- *
6
- * This service acts as the central enforcement point for the Access Control system.
7
- * It uses the configured `PrincipalProvider` to query roles and validates them against requirements.
8
- *
9
- * It is primarily used internally by the `@Guard` decorator, but can be injected
10
- * into services to perform manual checks.
11
- */
12
- export declare class AccessControlService {
13
- private readonly principalProvider
14
- constructor(principalProvider: PrincipalProviderContract)
15
- /**
16
- * Verifies if a player meets a minimum numeric rank requirement.
17
- *
18
- * @param player - The target player.
19
- * @param minRank - The minimum numeric value required (Inclusive).
20
- *
21
- * @returns `true` if `Principal.rank >= minRank`.
22
- *
23
- * @throws {AppError} code `UNAUTHORIZED` if the player has no Principal (not logged in).
24
- * @throws {AppError} code `NO_RANK_IN_PRINCIPAL` if the Principal exists but has no `rank` defined.
25
- */
26
- hasRank(player: Server.Player, minRank: number): Promise<boolean>
27
- /**
28
- * Verifies if a player possesses a specific permission string.
29
- *
30
- * @remarks
31
- * This method supports the **Wildcard ('*')** permission. If the principal has `'*'`
32
- * in their permissions array, this method always returns `true`.
33
- *
34
- * @param player - The target player.
35
- * @param permission - The specific permission key (e.g., `'admin.ban'`).
36
- * @returns `true` if the player has the permission or the wildcard.
37
- */
38
- hasPermission(player: Server.Player, permission: string): Promise<boolean>
39
- /**
40
- * **Strict Enforcement**
41
- *
42
- * Validates a set of requirements against a player. If any requirement fails,
43
- * it throws an exception, halting the execution flow.
44
- *
45
- * Used primarily by the `@Guard` decorator logic.
46
- *
47
- * @param player - The server player to validate.
48
- * @param requirements - An object containing rank and/or permission constraints.
49
- *
50
- * @throws {AppError} code `PERMISSION_DENIED` if validation fails.
51
- */
52
- enforce(
53
- player: Server.Player,
54
- requirements: {
55
- minRank?: number
56
- permission?: string
57
- },
58
- ): Promise<void>
59
- }
@@ -1,127 +0,0 @@
1
- 'use strict'
2
- var __decorate =
3
- (this && this.__decorate) ||
4
- function (decorators, target, key, desc) {
5
- var c = arguments.length,
6
- r =
7
- c < 3
8
- ? target
9
- : desc === null
10
- ? (desc = Object.getOwnPropertyDescriptor(target, key))
11
- : desc,
12
- d
13
- if (typeof Reflect === 'object' && typeof Reflect.decorate === 'function')
14
- r = Reflect.decorate(decorators, target, key, desc)
15
- else
16
- for (var i = decorators.length - 1; i >= 0; i--)
17
- if ((d = decorators[i]))
18
- r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r
19
- return c > 3 && r && Object.defineProperty(target, key, r), r
20
- }
21
- var __metadata =
22
- (this && this.__metadata) ||
23
- ((k, v) => {
24
- if (typeof Reflect === 'object' && typeof Reflect.metadata === 'function')
25
- return Reflect.metadata(k, v)
26
- })
27
- Object.defineProperty(exports, '__esModule', { value: true })
28
- exports.AccessControlService = void 0
29
- const tsyringe_1 = require('tsyringe')
30
- const utils_1 = require('../../../kernel/utils')
31
- const contracts_1 = require('../contracts')
32
- /**
33
- * **Core Security Service**
34
- *
35
- * This service acts as the central enforcement point for the Access Control system.
36
- * It uses the configured `PrincipalProvider` to query roles and validates them against requirements.
37
- *
38
- * It is primarily used internally by the `@Guard` decorator, but can be injected
39
- * into services to perform manual checks.
40
- */
41
- let AccessControlService = class AccessControlService {
42
- constructor(principalProvider) {
43
- this.principalProvider = principalProvider
44
- }
45
- /**
46
- * Verifies if a player meets a minimum numeric rank requirement.
47
- *
48
- * @param player - The target player.
49
- * @param minRank - The minimum numeric value required (Inclusive).
50
- *
51
- * @returns `true` if `Principal.rank >= minRank`.
52
- *
53
- * @throws {AppError} code `UNAUTHORIZED` if the player has no Principal (not logged in).
54
- * @throws {AppError} code `NO_RANK_IN_PRINCIPAL` if the Principal exists but has no `rank` defined.
55
- */
56
- async hasRank(player, minRank) {
57
- const principal = await this.principalProvider.getPrincipal(player)
58
- if (!principal) throw new utils_1.AppError('AUTH:UNAUTHORIZED', 'No principal found', 'core')
59
- if (principal.rank === undefined)
60
- throw new utils_1.AppError(
61
- 'GAME:NO_RANK_IN_PRINCIPAL',
62
- "You're trying to compare a Principal rank, but there's no defined rank! ",
63
- 'core',
64
- )
65
- return principal.rank >= minRank
66
- }
67
- /**
68
- * Verifies if a player possesses a specific permission string.
69
- *
70
- * @remarks
71
- * This method supports the **Wildcard ('*')** permission. If the principal has `'*'`
72
- * in their permissions array, this method always returns `true`.
73
- *
74
- * @param player - The target player.
75
- * @param permission - The specific permission key (e.g., `'admin.ban'`).
76
- * @returns `true` if the player has the permission or the wildcard.
77
- */
78
- async hasPermission(player, permission) {
79
- const principal = await this.principalProvider.getPrincipal(player)
80
- if (!principal) return false
81
- if (principal.permissions.includes('*')) return true
82
- return principal.permissions.includes(permission)
83
- }
84
- /**
85
- * **Strict Enforcement**
86
- *
87
- * Validates a set of requirements against a player. If any requirement fails,
88
- * it throws an exception, halting the execution flow.
89
- *
90
- * Used primarily by the `@Guard` decorator logic.
91
- *
92
- * @param player - The server player to validate.
93
- * @param requirements - An object containing rank and/or permission constraints.
94
- *
95
- * @throws {AppError} code `PERMISSION_DENIED` if validation fails.
96
- */
97
- async enforce(player, requirements) {
98
- if (requirements.minRank !== undefined) {
99
- const hasRank = await this.hasRank(player, requirements.minRank)
100
- if (!hasRank) {
101
- throw new utils_1.AppError(
102
- 'AUTH:PERMISSION_DENIED',
103
- `Access Denied: Requires minimum rank level ${requirements.minRank}`,
104
- 'core',
105
- )
106
- }
107
- }
108
- if (requirements.permission) {
109
- const hasPerm = await this.hasPermission(player, requirements.permission)
110
- if (!hasPerm) {
111
- throw new utils_1.AppError(
112
- 'AUTH:PERMISSION_DENIED',
113
- `Access Denied: Missing required permission '${requirements.permission}'`,
114
- 'core',
115
- )
116
- }
117
- }
118
- }
119
- }
120
- exports.AccessControlService = AccessControlService
121
- exports.AccessControlService = AccessControlService = __decorate(
122
- [
123
- (0, tsyringe_1.injectable)(),
124
- __metadata('design:paramtypes', [contracts_1.PrincipalProviderContract]),
125
- ],
126
- AccessControlService,
127
- )
@@ -1,104 +0,0 @@
1
- import { VehicleService } from './vehicle.service'
2
- import type { VehicleModificationOptions, VehicleMods } from '../../types/vehicle.types'
3
- /**
4
- * Service for handling vehicle modifications with validation.
5
- *
6
- * This service is separated from VehicleService to maintain single responsibility.
7
- * All modifications are validated server-side before being applied.
8
- *
9
- * Security features:
10
- * - Ownership validation
11
- * - Proximity checks
12
- * - Modification limits
13
- * - Audit logging
14
- */
15
- export declare class VehicleModificationService {
16
- private readonly vehicleService
17
- constructor(vehicleService: VehicleService)
18
- /**
19
- * Applies modifications to a vehicle with validation.
20
- *
21
- * @param options - Modification options
22
- * @returns Success status
23
- */
24
- applyModifications(options: VehicleModificationOptions): boolean
25
- /**
26
- * Sets vehicle colors with validation.
27
- *
28
- * @param networkId - Network ID of the vehicle
29
- * @param primaryColor - Primary color ID
30
- * @param secondaryColor - Secondary color ID
31
- * @param requestedBy - Client ID requesting the change
32
- * @returns Success status
33
- */
34
- setColors(
35
- networkId: number,
36
- primaryColor: number,
37
- secondaryColor: number,
38
- requestedBy?: number,
39
- ): boolean
40
- /**
41
- * Sets vehicle livery with validation.
42
- *
43
- * @param networkId - Network ID of the vehicle
44
- * @param livery - Livery index
45
- * @param requestedBy - Client ID requesting the change
46
- * @returns Success status
47
- */
48
- setLivery(networkId: number, livery: number, requestedBy?: number): boolean
49
- /**
50
- * Toggles vehicle turbo with validation.
51
- *
52
- * @param networkId - Network ID of the vehicle
53
- * @param enabled - Whether turbo should be enabled
54
- * @param requestedBy - Client ID requesting the change
55
- * @returns Success status
56
- */
57
- setTurbo(networkId: number, enabled: boolean, requestedBy?: number): boolean
58
- /**
59
- * Sets vehicle window tint with validation.
60
- *
61
- * @param networkId - Network ID of the vehicle
62
- * @param tint - Tint level (0-6)
63
- * @param requestedBy - Client ID requesting the change
64
- * @returns Success status
65
- */
66
- setWindowTint(networkId: number, tint: number, requestedBy?: number): boolean
67
- /**
68
- * Sets vehicle neon lights with validation.
69
- *
70
- * @param networkId - Network ID of the vehicle
71
- * @param enabled - Array of [left, right, front, back] enabled states
72
- * @param color - RGB color array
73
- * @param requestedBy - Client ID requesting the change
74
- * @returns Success status
75
- */
76
- setNeon(
77
- networkId: number,
78
- enabled: [boolean, boolean, boolean, boolean],
79
- color?: [number, number, number],
80
- requestedBy?: number,
81
- ): boolean
82
- /**
83
- * Resets all modifications on a vehicle.
84
- *
85
- * @param networkId - Network ID of the vehicle
86
- * @param requestedBy - Client ID requesting the reset
87
- * @returns Success status
88
- */
89
- resetModifications(networkId: number, requestedBy?: number): boolean
90
- /**
91
- * Gets the current modifications of a vehicle.
92
- *
93
- * @param networkId - Network ID of the vehicle
94
- * @returns Vehicle mods or undefined
95
- */
96
- getModifications(networkId: number): VehicleMods | undefined
97
- /**
98
- * Validates modification values to prevent exploits.
99
- *
100
- * @param mods - Modifications to validate
101
- * @returns Validated modifications
102
- */
103
- private validateMods
104
- }
@@ -1,330 +0,0 @@
1
- 'use strict'
2
- var __decorate =
3
- (this && this.__decorate) ||
4
- function (decorators, target, key, desc) {
5
- var c = arguments.length,
6
- r =
7
- c < 3
8
- ? target
9
- : desc === null
10
- ? (desc = Object.getOwnPropertyDescriptor(target, key))
11
- : desc,
12
- d
13
- if (typeof Reflect === 'object' && typeof Reflect.decorate === 'function')
14
- r = Reflect.decorate(decorators, target, key, desc)
15
- else
16
- for (var i = decorators.length - 1; i >= 0; i--)
17
- if ((d = decorators[i]))
18
- r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r
19
- return c > 3 && r && Object.defineProperty(target, key, r), r
20
- }
21
- var __metadata =
22
- (this && this.__metadata) ||
23
- ((k, v) => {
24
- if (typeof Reflect === 'object' && typeof Reflect.metadata === 'function')
25
- return Reflect.metadata(k, v)
26
- })
27
- var __param =
28
- (this && this.__param) ||
29
- ((paramIndex, decorator) => (target, key) => {
30
- decorator(target, key, paramIndex)
31
- })
32
- Object.defineProperty(exports, '__esModule', { value: true })
33
- exports.VehicleModificationService = void 0
34
- const tsyringe_1 = require('tsyringe')
35
- const vehicle_service_1 = require('./vehicle.service')
36
- const logger_1 = require('../../../../kernel/shared/logger')
37
- /**
38
- * Service for handling vehicle modifications with validation.
39
- *
40
- * This service is separated from VehicleService to maintain single responsibility.
41
- * All modifications are validated server-side before being applied.
42
- *
43
- * Security features:
44
- * - Ownership validation
45
- * - Proximity checks
46
- * - Modification limits
47
- * - Audit logging
48
- */
49
- let VehicleModificationService = class VehicleModificationService {
50
- constructor(vehicleService) {
51
- this.vehicleService = vehicleService
52
- }
53
- /**
54
- * Applies modifications to a vehicle with validation.
55
- *
56
- * @param options - Modification options
57
- * @returns Success status
58
- */
59
- applyModifications(options) {
60
- const { networkId, mods, requestedBy } = options
61
- const vehicle = this.vehicleService.getByNetworkId(networkId)
62
- if (!vehicle) {
63
- logger_1.coreLogger.warn('Vehicle not found for modification', { networkId })
64
- return false
65
- }
66
- if (!vehicle.exists) {
67
- logger_1.coreLogger.warn('Vehicle no longer exists', { networkId })
68
- return false
69
- }
70
- if (requestedBy !== undefined) {
71
- if (!this.vehicleService.validateOwnership(networkId, requestedBy)) {
72
- logger_1.coreLogger.warn('Unauthorized modification attempt', {
73
- networkId,
74
- requestedBy,
75
- owner: vehicle.ownership.clientID,
76
- })
77
- return false
78
- }
79
- if (!this.vehicleService.validateProximity(networkId, requestedBy, 15.0)) {
80
- logger_1.coreLogger.warn('Player too far from vehicle for modification', {
81
- networkId,
82
- requestedBy,
83
- })
84
- return false
85
- }
86
- }
87
- const validatedMods = this.validateMods(mods)
88
- vehicle.applyMods(validatedMods)
89
- logger_1.coreLogger.debug('Vehicle modifications applied', {
90
- networkId,
91
- requestedBy,
92
- mods: Object.keys(validatedMods),
93
- })
94
- emitNet('opencore:vehicle:modified', -1, {
95
- networkId,
96
- mods: validatedMods,
97
- })
98
- return true
99
- }
100
- /**
101
- * Sets vehicle colors with validation.
102
- *
103
- * @param networkId - Network ID of the vehicle
104
- * @param primaryColor - Primary color ID
105
- * @param secondaryColor - Secondary color ID
106
- * @param requestedBy - Client ID requesting the change
107
- * @returns Success status
108
- */
109
- setColors(networkId, primaryColor, secondaryColor, requestedBy) {
110
- return this.applyModifications({
111
- networkId,
112
- mods: { primaryColor, secondaryColor },
113
- requestedBy,
114
- })
115
- }
116
- /**
117
- * Sets vehicle livery with validation.
118
- *
119
- * @param networkId - Network ID of the vehicle
120
- * @param livery - Livery index
121
- * @param requestedBy - Client ID requesting the change
122
- * @returns Success status
123
- */
124
- setLivery(networkId, livery, requestedBy) {
125
- return this.applyModifications({
126
- networkId,
127
- mods: { livery },
128
- requestedBy,
129
- })
130
- }
131
- /**
132
- * Toggles vehicle turbo with validation.
133
- *
134
- * @param networkId - Network ID of the vehicle
135
- * @param enabled - Whether turbo should be enabled
136
- * @param requestedBy - Client ID requesting the change
137
- * @returns Success status
138
- */
139
- setTurbo(networkId, enabled, requestedBy) {
140
- return this.applyModifications({
141
- networkId,
142
- mods: { turbo: enabled },
143
- requestedBy,
144
- })
145
- }
146
- /**
147
- * Sets vehicle window tint with validation.
148
- *
149
- * @param networkId - Network ID of the vehicle
150
- * @param tint - Tint level (0-6)
151
- * @param requestedBy - Client ID requesting the change
152
- * @returns Success status
153
- */
154
- setWindowTint(networkId, tint, requestedBy) {
155
- const validTint = Math.max(0, Math.min(6, tint))
156
- return this.applyModifications({
157
- networkId,
158
- mods: { windowTint: validTint },
159
- requestedBy,
160
- })
161
- }
162
- /**
163
- * Sets vehicle neon lights with validation.
164
- *
165
- * @param networkId - Network ID of the vehicle
166
- * @param enabled - Array of [left, right, front, back] enabled states
167
- * @param color - RGB color array
168
- * @param requestedBy - Client ID requesting the change
169
- * @returns Success status
170
- */
171
- setNeon(networkId, enabled, color, requestedBy) {
172
- const mods = { neonEnabled: enabled }
173
- if (color) {
174
- mods.neonColor = color
175
- }
176
- return this.applyModifications({
177
- networkId,
178
- mods,
179
- requestedBy,
180
- })
181
- }
182
- /**
183
- * Resets all modifications on a vehicle.
184
- *
185
- * @param networkId - Network ID of the vehicle
186
- * @param requestedBy - Client ID requesting the reset
187
- * @returns Success status
188
- */
189
- resetModifications(networkId, requestedBy) {
190
- const vehicle = this.vehicleService.getByNetworkId(networkId)
191
- if (!vehicle) return false
192
- if (requestedBy !== undefined) {
193
- if (!this.vehicleService.validateOwnership(networkId, requestedBy)) {
194
- return false
195
- }
196
- }
197
- const defaultMods = {
198
- spoiler: -1,
199
- frontBumper: -1,
200
- rearBumper: -1,
201
- sideSkirt: -1,
202
- exhaust: -1,
203
- frame: -1,
204
- grille: -1,
205
- hood: -1,
206
- fender: -1,
207
- rightFender: -1,
208
- roof: -1,
209
- engine: -1,
210
- brakes: -1,
211
- transmission: -1,
212
- horns: -1,
213
- suspension: -1,
214
- armor: -1,
215
- turbo: false,
216
- xenon: false,
217
- windowTint: 0,
218
- }
219
- vehicle.applyMods(defaultMods)
220
- logger_1.coreLogger.info('Vehicle modifications reset', { networkId, requestedBy })
221
- emitNet('opencore:vehicle:modified', -1, {
222
- networkId,
223
- mods: defaultMods,
224
- })
225
- return true
226
- }
227
- /**
228
- * Gets the current modifications of a vehicle.
229
- *
230
- * @param networkId - Network ID of the vehicle
231
- * @returns Vehicle mods or undefined
232
- */
233
- getModifications(networkId) {
234
- const vehicle = this.vehicleService.getByNetworkId(networkId)
235
- return vehicle === null || vehicle === void 0 ? void 0 : vehicle.mods
236
- }
237
- /**
238
- * Validates modification values to prevent exploits.
239
- *
240
- * @param mods - Modifications to validate
241
- * @returns Validated modifications
242
- */
243
- validateMods(mods) {
244
- const validated = {}
245
- const modSlots = [
246
- 'spoiler',
247
- 'frontBumper',
248
- 'rearBumper',
249
- 'sideSkirt',
250
- 'exhaust',
251
- 'frame',
252
- 'grille',
253
- 'hood',
254
- 'fender',
255
- 'rightFender',
256
- 'roof',
257
- 'engine',
258
- 'brakes',
259
- 'transmission',
260
- 'horns',
261
- 'suspension',
262
- 'armor',
263
- 'wheels',
264
- ]
265
- for (const slot of modSlots) {
266
- if (mods[slot] !== undefined) {
267
- const value = mods[slot]
268
- validated[slot] = Math.max(-1, Math.min(50, value))
269
- }
270
- }
271
- if (mods.turbo !== undefined) validated.turbo = Boolean(mods.turbo)
272
- if (mods.xenon !== undefined) validated.xenon = Boolean(mods.xenon)
273
- if (mods.wheelType !== undefined) {
274
- validated.wheelType = Math.max(0, Math.min(12, mods.wheelType))
275
- }
276
- if (mods.windowTint !== undefined) {
277
- validated.windowTint = Math.max(0, Math.min(6, mods.windowTint))
278
- }
279
- if (mods.livery !== undefined) {
280
- validated.livery = Math.max(-1, Math.min(50, mods.livery))
281
- }
282
- if (mods.plateStyle !== undefined) {
283
- validated.plateStyle = Math.max(0, Math.min(5, mods.plateStyle))
284
- }
285
- if (mods.primaryColor !== undefined) {
286
- validated.primaryColor = Math.max(0, Math.min(160, mods.primaryColor))
287
- }
288
- if (mods.secondaryColor !== undefined) {
289
- validated.secondaryColor = Math.max(0, Math.min(160, mods.secondaryColor))
290
- }
291
- if (mods.pearlescentColor !== undefined) {
292
- validated.pearlescentColor = Math.max(0, Math.min(160, mods.pearlescentColor))
293
- }
294
- if (mods.wheelColor !== undefined) {
295
- validated.wheelColor = Math.max(0, Math.min(160, mods.wheelColor))
296
- }
297
- if (mods.xenonColor !== undefined) {
298
- validated.xenonColor = Math.max(0, Math.min(12, mods.xenonColor))
299
- }
300
- if (mods.neonEnabled !== undefined) {
301
- validated.neonEnabled = mods.neonEnabled
302
- }
303
- if (mods.neonColor !== undefined) {
304
- validated.neonColor = [
305
- Math.max(0, Math.min(255, mods.neonColor[0])),
306
- Math.max(0, Math.min(255, mods.neonColor[1])),
307
- Math.max(0, Math.min(255, mods.neonColor[2])),
308
- ]
309
- }
310
- if (mods.extras !== undefined) {
311
- validated.extras = {}
312
- for (const [key, value] of Object.entries(mods.extras)) {
313
- const extraId = Number(key)
314
- if (extraId >= 0 && extraId <= 20) {
315
- validated.extras[extraId] = Boolean(value)
316
- }
317
- }
318
- }
319
- return validated
320
- }
321
- }
322
- exports.VehicleModificationService = VehicleModificationService
323
- exports.VehicleModificationService = VehicleModificationService = __decorate(
324
- [
325
- (0, tsyringe_1.injectable)(),
326
- __param(0, (0, tsyringe_1.inject)(vehicle_service_1.VehicleService)),
327
- __metadata('design:paramtypes', [vehicle_service_1.VehicleService]),
328
- ],
329
- VehicleModificationService,
330
- )