@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.
Files changed (275) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +350 -0
  3. package/dist/client/client-bootstrap.d.ts +1 -0
  4. package/dist/client/client-bootstrap.js +53 -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 +18 -0
  8. package/dist/client/client-core.js +52 -0
  9. package/dist/client/decorators/controller.d.ts +3 -0
  10. package/dist/client/decorators/controller.js +14 -0
  11. package/dist/client/decorators/export.d.ts +7 -0
  12. package/dist/client/decorators/export.js +15 -0
  13. package/dist/client/decorators/gameEvent.d.ts +47 -0
  14. package/dist/client/decorators/gameEvent.js +54 -0
  15. package/dist/client/decorators/index.d.ts +10 -0
  16. package/dist/client/decorators/index.js +26 -0
  17. package/dist/client/decorators/interval.d.ts +7 -0
  18. package/dist/client/decorators/interval.js +15 -0
  19. package/dist/client/decorators/key.d.ts +2 -0
  20. package/dist/client/decorators/key.js +10 -0
  21. package/dist/client/decorators/localEvent.d.ts +7 -0
  22. package/dist/client/decorators/localEvent.js +15 -0
  23. package/dist/client/decorators/nui.d.ts +1 -0
  24. package/dist/client/decorators/nui.js +9 -0
  25. package/dist/client/decorators/onNet.d.ts +1 -0
  26. package/dist/client/decorators/onNet.js +9 -0
  27. package/dist/client/decorators/resourceLifecycle.d.ts +11 -0
  28. package/dist/client/decorators/resourceLifecycle.js +24 -0
  29. package/dist/client/decorators/tick.d.ts +1 -0
  30. package/dist/client/decorators/tick.js +9 -0
  31. package/dist/client/index.d.ts +6 -0
  32. package/dist/client/index.js +22 -0
  33. package/dist/client/loaders/exports.loader.d.ts +1 -0
  34. package/dist/client/loaders/exports.loader.js +13 -0
  35. package/dist/client/player/player.d.ts +262 -0
  36. package/dist/client/player/player.js +480 -0
  37. package/dist/client/player/player.loader.d.ts +1 -0
  38. package/dist/client/player/player.loader.js +22 -0
  39. package/dist/client/services/core/index.d.ts +1 -0
  40. package/dist/client/services/core/index.js +17 -0
  41. package/dist/client/services/core/spawn.service.d.ts +20 -0
  42. package/dist/client/services/core/spawn.service.js +143 -0
  43. package/dist/client/services/index.d.ts +4 -0
  44. package/dist/client/services/index.js +24 -0
  45. package/dist/client/services/streaming/index.d.ts +1 -0
  46. package/dist/client/services/streaming/index.js +17 -0
  47. package/dist/client/services/streaming/streaming.service.d.ts +165 -0
  48. package/dist/client/services/streaming/streaming.service.js +341 -0
  49. package/dist/client/services/ui/index.d.ts +3 -0
  50. package/dist/client/services/ui/index.js +19 -0
  51. package/dist/client/services/ui/notification.service.d.ts +76 -0
  52. package/dist/client/services/ui/notification.service.js +111 -0
  53. package/dist/client/services/ui/progress.service.d.ts +82 -0
  54. package/dist/client/services/ui/progress.service.js +210 -0
  55. package/dist/client/services/ui/textui.service.d.ts +82 -0
  56. package/dist/client/services/ui/textui.service.js +156 -0
  57. package/dist/client/services/world/blip.service.d.ts +112 -0
  58. package/dist/client/services/world/blip.service.js +215 -0
  59. package/dist/client/services/world/index.d.ts +4 -0
  60. package/dist/client/services/world/index.js +20 -0
  61. package/dist/client/services/world/marker.service.d.ts +94 -0
  62. package/dist/client/services/world/marker.service.js +153 -0
  63. package/dist/client/services/world/ped.service.d.ts +182 -0
  64. package/dist/client/services/world/ped.service.js +302 -0
  65. package/dist/client/services/world/vehicle.service.d.ts +168 -0
  66. package/dist/client/services/world/vehicle.service.js +296 -0
  67. package/dist/client/system/metadata-client.keys.d.ts +13 -0
  68. package/dist/client/system/metadata-client.keys.js +16 -0
  69. package/dist/client/system/processors/export.processor.d.ts +7 -0
  70. package/dist/client/system/processors/export.processor.js +39 -0
  71. package/dist/client/system/processors/gameEvent.processor.d.ts +10 -0
  72. package/dist/client/system/processors/gameEvent.processor.js +58 -0
  73. package/dist/client/system/processors/interval.processor.d.ts +7 -0
  74. package/dist/client/system/processors/interval.processor.js +43 -0
  75. package/dist/client/system/processors/key.processor.d.ts +8 -0
  76. package/dist/client/system/processors/key.processor.js +27 -0
  77. package/dist/client/system/processors/localEvent.processor.d.ts +7 -0
  78. package/dist/client/system/processors/localEvent.processor.js +38 -0
  79. package/dist/client/system/processors/netEvent.processor.d.ts +7 -0
  80. package/dist/client/system/processors/netEvent.processor.js +38 -0
  81. package/dist/client/system/processors/nui.processor.d.ts +7 -0
  82. package/dist/client/system/processors/nui.processor.js +40 -0
  83. package/dist/client/system/processors/resourceLifecycle.processor.d.ts +9 -0
  84. package/dist/client/system/processors/resourceLifecycle.processor.js +69 -0
  85. package/dist/client/system/processors/tick.processor.d.ts +5 -0
  86. package/dist/client/system/processors/tick.processor.js +37 -0
  87. package/dist/client/system/processors.register.d.ts +1 -0
  88. package/dist/client/system/processors.register.js +27 -0
  89. package/dist/client/types/game-events.d.ts +126 -0
  90. package/dist/client/types/game-events.js +83 -0
  91. package/dist/client/types/index.d.ts +1 -0
  92. package/dist/client/types/index.js +17 -0
  93. package/dist/client/ui-bridge.d.ts +116 -0
  94. package/dist/client/ui-bridge.js +201 -0
  95. package/dist/index.d.ts +7 -0
  96. package/dist/index.js +46 -0
  97. package/dist/server/bootstrap.d.ts +16 -0
  98. package/dist/server/bootstrap.js +57 -0
  99. package/dist/server/bus/core-event-bus.d.ts +6 -0
  100. package/dist/server/bus/core-event-bus.js +31 -0
  101. package/dist/server/configs/api.config.d.ts +71 -0
  102. package/dist/server/configs/api.config.js +81 -0
  103. package/dist/server/configs/config.base.d.ts +63 -0
  104. package/dist/server/configs/config.base.js +64 -0
  105. package/dist/server/configs/index.d.ts +2 -0
  106. package/dist/server/configs/index.js +18 -0
  107. package/dist/server/container.d.ts +2 -0
  108. package/dist/server/container.js +6 -0
  109. package/dist/server/controllers/chat.controller.d.ts +10 -0
  110. package/dist/server/controllers/chat.controller.js +50 -0
  111. package/dist/server/controllers/command.controller.d.ts +7 -0
  112. package/dist/server/controllers/command.controller.js +47 -0
  113. package/dist/server/core.d.ts +1 -0
  114. package/dist/server/core.js +7 -0
  115. package/dist/server/database/adapters/oxmysql.adapter.d.ts +89 -0
  116. package/dist/server/database/adapters/oxmysql.adapter.js +149 -0
  117. package/dist/server/database/database.contract.d.ts +128 -0
  118. package/dist/server/database/database.contract.js +29 -0
  119. package/dist/server/database/database.service.d.ts +216 -0
  120. package/dist/server/database/database.service.js +301 -0
  121. package/dist/server/database/index.d.ts +53 -0
  122. package/dist/server/database/index.js +70 -0
  123. package/dist/server/database/types.d.ts +67 -0
  124. package/dist/server/database/types.js +7 -0
  125. package/dist/server/database.d.ts +7 -0
  126. package/dist/server/database.js +23 -0
  127. package/dist/server/decorators/bind.d.ts +2 -0
  128. package/dist/server/decorators/bind.js +15 -0
  129. package/dist/server/decorators/command.d.ts +19 -0
  130. package/dist/server/decorators/command.js +18 -0
  131. package/dist/server/decorators/controller.d.ts +3 -0
  132. package/dist/server/decorators/controller.js +14 -0
  133. package/dist/server/decorators/coreEvent.d.ts +2 -0
  134. package/dist/server/decorators/coreEvent.js +9 -0
  135. package/dist/server/decorators/export.d.ts +1 -0
  136. package/dist/server/decorators/export.js +9 -0
  137. package/dist/server/decorators/guard.d.ts +5 -0
  138. package/dist/server/decorators/guard.js +39 -0
  139. package/dist/server/decorators/index.d.ts +10 -0
  140. package/dist/server/decorators/index.js +26 -0
  141. package/dist/server/decorators/netEvent.d.ts +36 -0
  142. package/dist/server/decorators/netEvent.js +40 -0
  143. package/dist/server/decorators/onTick.d.ts +1 -0
  144. package/dist/server/decorators/onTick.js +9 -0
  145. package/dist/server/decorators/public.d.ts +16 -0
  146. package/dist/server/decorators/public.js +25 -0
  147. package/dist/server/decorators/requiresState.d.ts +55 -0
  148. package/dist/server/decorators/requiresState.js +62 -0
  149. package/dist/server/decorators/throttle.d.ts +9 -0
  150. package/dist/server/decorators/throttle.js +36 -0
  151. package/dist/server/decorators/utils.d.ts +7 -0
  152. package/dist/server/decorators/utils.js +13 -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/index.d.ts +10 -0
  160. package/dist/server/index.js +29 -0
  161. package/dist/server/loaders/exports.loader.d.ts +0 -0
  162. package/dist/server/loaders/exports.loader.js +23 -0
  163. package/dist/server/loaders/playerSession.loader.d.ts +1 -0
  164. package/dist/server/loaders/playerSession.loader.js +42 -0
  165. package/dist/server/services/access-control.service.d.ts +56 -0
  166. package/dist/server/services/access-control.service.js +99 -0
  167. package/dist/server/services/chat.service.d.ts +7 -0
  168. package/dist/server/services/chat.service.js +31 -0
  169. package/dist/server/services/command.service.d.ts +15 -0
  170. package/dist/server/services/command.service.js +74 -0
  171. package/dist/server/services/config.service.d.ts +75 -0
  172. package/dist/server/services/config.service.js +116 -0
  173. package/dist/server/services/default/default-security.handler.d.ts +6 -0
  174. package/dist/server/services/default/default-security.handler.js +26 -0
  175. package/dist/server/services/http/http.service.d.ts +50 -0
  176. package/dist/server/services/http/http.service.js +126 -0
  177. package/dist/server/services/index.d.ts +10 -0
  178. package/dist/server/services/index.js +26 -0
  179. package/dist/server/services/parallel/index.d.ts +49 -0
  180. package/dist/server/services/parallel/index.js +67 -0
  181. package/dist/server/services/parallel/parallel-compute.service.d.ts +132 -0
  182. package/dist/server/services/parallel/parallel-compute.service.js +449 -0
  183. package/dist/server/services/parallel/types.d.ts +188 -0
  184. package/dist/server/services/parallel/types.js +7 -0
  185. package/dist/server/services/parallel/worker-pool.d.ts +83 -0
  186. package/dist/server/services/parallel/worker-pool.js +350 -0
  187. package/dist/server/services/parallel/worker.d.ts +19 -0
  188. package/dist/server/services/parallel/worker.js +49 -0
  189. package/dist/server/services/persistence.service.d.ts +59 -0
  190. package/dist/server/services/persistence.service.js +166 -0
  191. package/dist/server/services/player.service.d.ts +96 -0
  192. package/dist/server/services/player.service.js +132 -0
  193. package/dist/server/services/rate-limiter.service.d.ts +5 -0
  194. package/dist/server/services/rate-limiter.service.js +39 -0
  195. package/dist/server/services/registers.d.ts +1 -0
  196. package/dist/server/services/registers.js +18 -0
  197. package/dist/server/setup.d.ts +9 -0
  198. package/dist/server/setup.js +28 -0
  199. package/dist/server/system/metadata-server.keys.d.ts +9 -0
  200. package/dist/server/system/metadata-server.keys.js +12 -0
  201. package/dist/server/system/processors/command.processor.d.ts +9 -0
  202. package/dist/server/system/processors/command.processor.js +31 -0
  203. package/dist/server/system/processors/coreEvent.processor.d.ts +7 -0
  204. package/dist/server/system/processors/coreEvent.processor.js +38 -0
  205. package/dist/server/system/processors/export.processor.d.ts +7 -0
  206. package/dist/server/system/processors/export.processor.js +26 -0
  207. package/dist/server/system/processors/netEvent.processor.d.ts +11 -0
  208. package/dist/server/system/processors/netEvent.processor.js +100 -0
  209. package/dist/server/system/processors/tick.processor.d.ts +5 -0
  210. package/dist/server/system/processors/tick.processor.js +36 -0
  211. package/dist/server/system/processors.register.d.ts +1 -0
  212. package/dist/server/system/processors.register.js +21 -0
  213. package/dist/server/templates/admin/admin.controller-template.d.ts +10 -0
  214. package/dist/server/templates/admin/admin.controller-template.js +2 -0
  215. package/dist/server/templates/auth/auth-provider.contract.d.ts +58 -0
  216. package/dist/server/templates/auth/auth-provider.contract.js +23 -0
  217. package/dist/server/templates/index.d.ts +8 -0
  218. package/dist/server/templates/index.js +21 -0
  219. package/dist/server/templates/persistence/index.d.ts +30 -0
  220. package/dist/server/templates/persistence/index.js +34 -0
  221. package/dist/server/templates/persistence/player-persistence.contract.d.ts +86 -0
  222. package/dist/server/templates/persistence/player-persistence.contract.js +52 -0
  223. package/dist/server/templates/repository/index.d.ts +57 -0
  224. package/dist/server/templates/repository/index.js +61 -0
  225. package/dist/server/templates/repository/repository.contract.d.ts +224 -0
  226. package/dist/server/templates/repository/repository.contract.js +342 -0
  227. package/dist/server/templates/repository/repository.types.d.ts +51 -0
  228. package/dist/server/templates/repository/repository.types.js +7 -0
  229. package/dist/server/templates/security/permission.types.d.ts +32 -0
  230. package/dist/server/templates/security/permission.types.js +2 -0
  231. package/dist/server/templates/security/principal-provider.contract.d.ts +43 -0
  232. package/dist/server/templates/security/principal-provider.contract.js +19 -0
  233. package/dist/server/templates/security/security-handler.contract.d.ts +5 -0
  234. package/dist/server/templates/security/security-handler.contract.js +6 -0
  235. package/dist/server/types/core-events.d.ts +17 -0
  236. package/dist/server/types/core-events.js +2 -0
  237. package/dist/server/types/security.types.d.ts +7 -0
  238. package/dist/server/types/security.types.js +2 -0
  239. package/dist/shared/index.d.ts +1 -0
  240. package/dist/shared/index.js +17 -0
  241. package/dist/shared/logger/core-logger.d.ts +35 -0
  242. package/dist/shared/logger/core-logger.js +52 -0
  243. package/dist/shared/logger/index.d.ts +11 -0
  244. package/dist/shared/logger/index.js +26 -0
  245. package/dist/shared/logger/logger.config.d.ts +47 -0
  246. package/dist/shared/logger/logger.config.js +33 -0
  247. package/dist/shared/logger/logger.service.d.ts +161 -0
  248. package/dist/shared/logger/logger.service.js +279 -0
  249. package/dist/shared/logger/logger.types.d.ts +85 -0
  250. package/dist/shared/logger/logger.types.js +74 -0
  251. package/dist/shared/logger/transports/buffered.transport.d.ts +88 -0
  252. package/dist/shared/logger/transports/buffered.transport.js +174 -0
  253. package/dist/shared/logger/transports/console.transport.d.ts +37 -0
  254. package/dist/shared/logger/transports/console.transport.js +134 -0
  255. package/dist/shared/logger/transports/index.d.ts +3 -0
  256. package/dist/shared/logger/transports/index.js +19 -0
  257. package/dist/shared/logger/transports/transport.interface.d.ts +40 -0
  258. package/dist/shared/logger/transports/transport.interface.js +2 -0
  259. package/dist/system/class-constructor.d.ts +1 -0
  260. package/dist/system/class-constructor.js +2 -0
  261. package/dist/system/decorator-processor.d.ts +4 -0
  262. package/dist/system/decorator-processor.js +2 -0
  263. package/dist/system/metadata.scanner.d.ts +7 -0
  264. package/dist/system/metadata.scanner.js +45 -0
  265. package/dist/utils/errors.d.ts +14 -0
  266. package/dist/utils/errors.js +25 -0
  267. package/dist/utils/index.d.ts +4 -0
  268. package/dist/utils/index.js +20 -0
  269. package/dist/utils/result.d.ts +12 -0
  270. package/dist/utils/result.js +10 -0
  271. package/dist/utils/rgb.d.ts +5 -0
  272. package/dist/utils/rgb.js +2 -0
  273. package/dist/utils/vector3.d.ts +13 -0
  274. package/dist/utils/vector3.js +27 -0
  275. package/package.json +70 -0
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ /**
3
+ * Repository Pattern Module
4
+ *
5
+ * Provides an abstract Repository base class for implementing
6
+ * the Repository Pattern with type-safe CRUD operations.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { Repository, FindOptions } from '@open-core/framework/server'
11
+ * import type { DatabaseContract } from '@open-core/framework/server'
12
+ *
13
+ * interface User {
14
+ * id: number
15
+ * name: string
16
+ * email: string
17
+ * active: boolean
18
+ * }
19
+ *
20
+ * class UserRepository extends Repository<User> {
21
+ * protected tableName = 'users'
22
+ *
23
+ * constructor(db: DatabaseContract) {
24
+ * super(db)
25
+ * }
26
+ *
27
+ * protected toEntity(row: any): User {
28
+ * return {
29
+ * id: row.id,
30
+ * name: row.name,
31
+ * email: row.email,
32
+ * active: Boolean(row.active)
33
+ * }
34
+ * }
35
+ *
36
+ * protected toRow(entity: User): Record<string, any> {
37
+ * return {
38
+ * id: entity.id,
39
+ * name: entity.name,
40
+ * email: entity.email,
41
+ * active: entity.active ? 1 : 0
42
+ * }
43
+ * }
44
+ *
45
+ * // Custom methods
46
+ * async findByEmail(email: string): Promise<User | null> {
47
+ * return this.findOne({ email })
48
+ * }
49
+ *
50
+ * async findActive(options?: FindOptions<User>): Promise<User[]> {
51
+ * const { data } = await this.findMany({ active: true }, options)
52
+ * return data
53
+ * }
54
+ * }
55
+ * ```
56
+ */
57
+ Object.defineProperty(exports, "__esModule", { value: true });
58
+ exports.Repository = void 0;
59
+ // Contract
60
+ var repository_contract_1 = require("./repository.contract");
61
+ Object.defineProperty(exports, "Repository", { enumerable: true, get: function () { return repository_contract_1.Repository; } });
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Repository Contract
3
+ *
4
+ * Abstract base class for implementing the Repository Pattern.
5
+ * Provides common CRUD operations with support for pagination, ordering, and field selection.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * interface User {
10
+ * id: number
11
+ * name: string
12
+ * email: string
13
+ * createdAt: Date
14
+ * }
15
+ *
16
+ * class UserRepository extends Repository<User> {
17
+ * protected tableName = 'users'
18
+ *
19
+ * constructor(db: DatabaseContract) {
20
+ * super(db)
21
+ * }
22
+ *
23
+ * protected toEntity(row: any): User {
24
+ * return {
25
+ * id: row.id,
26
+ * name: row.name,
27
+ * email: row.email,
28
+ * createdAt: new Date(row.created_at)
29
+ * }
30
+ * }
31
+ *
32
+ * protected toRow(entity: User): Record<string, any> {
33
+ * return {
34
+ * id: entity.id,
35
+ * name: entity.name,
36
+ * email: entity.email,
37
+ * created_at: entity.createdAt.toISOString()
38
+ * }
39
+ * }
40
+ * }
41
+ *
42
+ * // Usage
43
+ * const userRepo = new UserRepository(db)
44
+ * const user = await userRepo.findById(1)
45
+ * const users = await userRepo.findMany({ active: true }, { limit: 10, orderBy: { createdAt: 'DESC' } })
46
+ * ```
47
+ */
48
+ import type { DatabaseContract } from '../../database/database.contract';
49
+ import type { FindOptions, FindManyResult, WhereCondition, OrderDirection } from './repository.types';
50
+ /**
51
+ * Abstract Repository base class
52
+ *
53
+ * Extend this class to create type-safe repositories for your entities.
54
+ *
55
+ * @typeParam TEntity - The entity type this repository manages
56
+ * @typeParam TId - The type of the primary key (defaults to number)
57
+ */
58
+ export declare abstract class Repository<TEntity, TId = number> {
59
+ protected readonly db: DatabaseContract;
60
+ /**
61
+ * The database table name for this entity
62
+ */
63
+ protected abstract tableName: string;
64
+ /**
65
+ * The primary key column name (defaults to 'id')
66
+ */
67
+ protected primaryKey: string;
68
+ /**
69
+ * Creates a new repository instance
70
+ *
71
+ * @param db - The database contract/service to use for queries
72
+ */
73
+ constructor(db: DatabaseContract);
74
+ /**
75
+ * Maps a database row to an entity instance
76
+ *
77
+ * @param row - Raw database row
78
+ * @returns The mapped entity
79
+ */
80
+ protected abstract toEntity(row: any): TEntity;
81
+ /**
82
+ * Maps an entity to a database row
83
+ *
84
+ * @param entity - The entity to map
85
+ * @returns Object suitable for database operations
86
+ */
87
+ protected abstract toRow(entity: TEntity): Record<string, any>;
88
+ /**
89
+ * Find an entity by its primary key
90
+ *
91
+ * @param id - The primary key value
92
+ * @returns The entity or null if not found
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * const user = await userRepo.findById(1)
97
+ * if (user) {
98
+ * console.log(user.name)
99
+ * }
100
+ * ```
101
+ */
102
+ findById(id: TId): Promise<TEntity | null>;
103
+ /**
104
+ * Find a single entity matching the given conditions
105
+ *
106
+ * @param where - Conditions to match (equality only)
107
+ * @returns The first matching entity or null
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * const user = await userRepo.findOne({ email: 'john@example.com' })
112
+ * ```
113
+ */
114
+ findOne(where: WhereCondition<TEntity>): Promise<TEntity | null>;
115
+ /**
116
+ * Find multiple entities with optional filtering, pagination, and ordering
117
+ *
118
+ * @param where - Optional conditions to filter by
119
+ * @param options - Query options (select, orderBy, limit, offset)
120
+ * @returns Result containing data array and optional total count
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * // Simple query
125
+ * const { data: users } = await userRepo.findMany({ active: true })
126
+ *
127
+ * // With pagination and ordering
128
+ * const result = await userRepo.findMany(
129
+ * { role: 'admin' },
130
+ * { limit: 10, offset: 20, orderBy: { createdAt: 'DESC' } }
131
+ * )
132
+ * console.log(`Page of ${result.data.length} admins`)
133
+ * ```
134
+ */
135
+ findMany(where?: WhereCondition<TEntity>, options?: FindOptions<TEntity>): Promise<FindManyResult<TEntity>>;
136
+ /**
137
+ * Count entities matching the given conditions
138
+ *
139
+ * @param where - Optional conditions to filter by
140
+ * @returns The count of matching entities
141
+ *
142
+ * @example
143
+ * ```typescript
144
+ * const activeCount = await userRepo.count({ active: true })
145
+ * ```
146
+ */
147
+ count(where?: WhereCondition<TEntity>): Promise<number>;
148
+ /**
149
+ * Save an entity (insert if new, update if exists)
150
+ *
151
+ * If the entity has a primary key value, it will be updated.
152
+ * Otherwise, a new record will be inserted.
153
+ *
154
+ * @param entity - The entity to save
155
+ * @returns The saved entity with updated ID (for inserts)
156
+ *
157
+ * @example
158
+ * ```typescript
159
+ * // Insert new user
160
+ * const newUser = await userRepo.save({ name: 'John', email: 'john@example.com' })
161
+ * console.log(newUser.id) // Generated ID
162
+ *
163
+ * // Update existing user
164
+ * user.name = 'John Doe'
165
+ * await userRepo.save(user)
166
+ * ```
167
+ */
168
+ save(entity: TEntity): Promise<TEntity>;
169
+ /**
170
+ * Delete an entity by its primary key
171
+ *
172
+ * @param id - The primary key of the entity to delete
173
+ * @returns true if deleted, false if not found
174
+ *
175
+ * @example
176
+ * ```typescript
177
+ * const deleted = await userRepo.delete(1)
178
+ * if (deleted) {
179
+ * console.log('User deleted')
180
+ * }
181
+ * ```
182
+ */
183
+ delete(id: TId): Promise<boolean>;
184
+ /**
185
+ * Delete entities matching the given conditions
186
+ *
187
+ * @param where - Conditions to match for deletion
188
+ * @returns Number of deleted entities
189
+ *
190
+ * @example
191
+ * ```typescript
192
+ * const count = await userRepo.deleteWhere({ active: false })
193
+ * console.log(`Deleted ${count} inactive users`)
194
+ * ```
195
+ */
196
+ deleteWhere(where: WhereCondition<TEntity>): Promise<number>;
197
+ /**
198
+ * Update an entity by ID
199
+ */
200
+ protected update(id: TId, row: Record<string, any>): Promise<void>;
201
+ /**
202
+ * Insert a new row and return the inserted ID
203
+ */
204
+ protected insertRow(row: Record<string, any>): Promise<TId>;
205
+ /**
206
+ * Build SELECT clause from field selection
207
+ */
208
+ protected buildSelectClause(select?: (keyof TEntity)[]): string;
209
+ /**
210
+ * Build WHERE clause from conditions
211
+ */
212
+ protected buildWhereClause(where?: WhereCondition<TEntity>): {
213
+ clause: string;
214
+ params: any[];
215
+ };
216
+ /**
217
+ * Build ORDER BY clause from orderBy options
218
+ */
219
+ protected buildOrderClause(orderBy?: Partial<Record<keyof TEntity, OrderDirection>>): string;
220
+ /**
221
+ * Build LIMIT/OFFSET clause
222
+ */
223
+ protected buildLimitClause(limit?: number, offset?: number): string;
224
+ }
@@ -0,0 +1,342 @@
1
+ "use strict";
2
+ /**
3
+ * Repository Contract
4
+ *
5
+ * Abstract base class for implementing the Repository Pattern.
6
+ * Provides common CRUD operations with support for pagination, ordering, and field selection.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * interface User {
11
+ * id: number
12
+ * name: string
13
+ * email: string
14
+ * createdAt: Date
15
+ * }
16
+ *
17
+ * class UserRepository extends Repository<User> {
18
+ * protected tableName = 'users'
19
+ *
20
+ * constructor(db: DatabaseContract) {
21
+ * super(db)
22
+ * }
23
+ *
24
+ * protected toEntity(row: any): User {
25
+ * return {
26
+ * id: row.id,
27
+ * name: row.name,
28
+ * email: row.email,
29
+ * createdAt: new Date(row.created_at)
30
+ * }
31
+ * }
32
+ *
33
+ * protected toRow(entity: User): Record<string, any> {
34
+ * return {
35
+ * id: entity.id,
36
+ * name: entity.name,
37
+ * email: entity.email,
38
+ * created_at: entity.createdAt.toISOString()
39
+ * }
40
+ * }
41
+ * }
42
+ *
43
+ * // Usage
44
+ * const userRepo = new UserRepository(db)
45
+ * const user = await userRepo.findById(1)
46
+ * const users = await userRepo.findMany({ active: true }, { limit: 10, orderBy: { createdAt: 'DESC' } })
47
+ * ```
48
+ */
49
+ var __rest = (this && this.__rest) || function (s, e) {
50
+ var t = {};
51
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
52
+ t[p] = s[p];
53
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
54
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
55
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
56
+ t[p[i]] = s[p[i]];
57
+ }
58
+ return t;
59
+ };
60
+ Object.defineProperty(exports, "__esModule", { value: true });
61
+ exports.Repository = void 0;
62
+ /**
63
+ * Abstract Repository base class
64
+ *
65
+ * Extend this class to create type-safe repositories for your entities.
66
+ *
67
+ * @typeParam TEntity - The entity type this repository manages
68
+ * @typeParam TId - The type of the primary key (defaults to number)
69
+ */
70
+ class Repository {
71
+ /**
72
+ * Creates a new repository instance
73
+ *
74
+ * @param db - The database contract/service to use for queries
75
+ */
76
+ constructor(db) {
77
+ this.db = db;
78
+ /**
79
+ * The primary key column name (defaults to 'id')
80
+ */
81
+ this.primaryKey = 'id';
82
+ }
83
+ // ─────────────────────────────────────────────────────────────────────────────
84
+ // CRUD Operations
85
+ // ─────────────────────────────────────────────────────────────────────────────
86
+ /**
87
+ * Find an entity by its primary key
88
+ *
89
+ * @param id - The primary key value
90
+ * @returns The entity or null if not found
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * const user = await userRepo.findById(1)
95
+ * if (user) {
96
+ * console.log(user.name)
97
+ * }
98
+ * ```
99
+ */
100
+ async findById(id) {
101
+ const sql = `SELECT * FROM ${this.tableName} WHERE ${this.primaryKey} = ?`;
102
+ const row = await this.db.single(sql, [id]);
103
+ return row ? this.toEntity(row) : null;
104
+ }
105
+ /**
106
+ * Find a single entity matching the given conditions
107
+ *
108
+ * @param where - Conditions to match (equality only)
109
+ * @returns The first matching entity or null
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * const user = await userRepo.findOne({ email: 'john@example.com' })
114
+ * ```
115
+ */
116
+ async findOne(where) {
117
+ const { clause, params } = this.buildWhereClause(where);
118
+ const sql = `SELECT * FROM ${this.tableName}${clause} LIMIT 1`;
119
+ const row = await this.db.single(sql, params);
120
+ return row ? this.toEntity(row) : null;
121
+ }
122
+ /**
123
+ * Find multiple entities with optional filtering, pagination, and ordering
124
+ *
125
+ * @param where - Optional conditions to filter by
126
+ * @param options - Query options (select, orderBy, limit, offset)
127
+ * @returns Result containing data array and optional total count
128
+ *
129
+ * @example
130
+ * ```typescript
131
+ * // Simple query
132
+ * const { data: users } = await userRepo.findMany({ active: true })
133
+ *
134
+ * // With pagination and ordering
135
+ * const result = await userRepo.findMany(
136
+ * { role: 'admin' },
137
+ * { limit: 10, offset: 20, orderBy: { createdAt: 'DESC' } }
138
+ * )
139
+ * console.log(`Page of ${result.data.length} admins`)
140
+ * ```
141
+ */
142
+ async findMany(where, options) {
143
+ const selectClause = this.buildSelectClause(options === null || options === void 0 ? void 0 : options.select);
144
+ const { clause: whereClause, params } = this.buildWhereClause(where);
145
+ const orderClause = this.buildOrderClause(options === null || options === void 0 ? void 0 : options.orderBy);
146
+ const limitClause = this.buildLimitClause(options === null || options === void 0 ? void 0 : options.limit, options === null || options === void 0 ? void 0 : options.offset);
147
+ const sql = `SELECT ${selectClause} FROM ${this.tableName}${whereClause}${orderClause}${limitClause}`;
148
+ const rows = await this.db.query(sql, params);
149
+ const data = rows.map((row) => this.toEntity(row));
150
+ // If pagination is used, also get total count
151
+ let total;
152
+ if ((options === null || options === void 0 ? void 0 : options.limit) !== undefined) {
153
+ total = await this.count(where);
154
+ }
155
+ return { data, total };
156
+ }
157
+ /**
158
+ * Count entities matching the given conditions
159
+ *
160
+ * @param where - Optional conditions to filter by
161
+ * @returns The count of matching entities
162
+ *
163
+ * @example
164
+ * ```typescript
165
+ * const activeCount = await userRepo.count({ active: true })
166
+ * ```
167
+ */
168
+ async count(where) {
169
+ const { clause, params } = this.buildWhereClause(where);
170
+ const sql = `SELECT COUNT(*) as count FROM ${this.tableName}${clause}`;
171
+ const result = await this.db.scalar(sql, params);
172
+ return result !== null && result !== void 0 ? result : 0;
173
+ }
174
+ /**
175
+ * Save an entity (insert if new, update if exists)
176
+ *
177
+ * If the entity has a primary key value, it will be updated.
178
+ * Otherwise, a new record will be inserted.
179
+ *
180
+ * @param entity - The entity to save
181
+ * @returns The saved entity with updated ID (for inserts)
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * // Insert new user
186
+ * const newUser = await userRepo.save({ name: 'John', email: 'john@example.com' })
187
+ * console.log(newUser.id) // Generated ID
188
+ *
189
+ * // Update existing user
190
+ * user.name = 'John Doe'
191
+ * await userRepo.save(user)
192
+ * ```
193
+ */
194
+ async save(entity) {
195
+ const row = this.toRow(entity);
196
+ const id = row[this.primaryKey];
197
+ if (id !== undefined && id !== null) {
198
+ // Update existing entity
199
+ await this.update(id, row);
200
+ return entity;
201
+ }
202
+ else {
203
+ // Insert new entity
204
+ const insertedId = await this.insertRow(row);
205
+ // Return entity with the new ID
206
+ return this.toEntity(Object.assign(Object.assign({}, row), { [this.primaryKey]: insertedId }));
207
+ }
208
+ }
209
+ /**
210
+ * Delete an entity by its primary key
211
+ *
212
+ * @param id - The primary key of the entity to delete
213
+ * @returns true if deleted, false if not found
214
+ *
215
+ * @example
216
+ * ```typescript
217
+ * const deleted = await userRepo.delete(1)
218
+ * if (deleted) {
219
+ * console.log('User deleted')
220
+ * }
221
+ * ```
222
+ */
223
+ async delete(id) {
224
+ const sql = `DELETE FROM ${this.tableName} WHERE ${this.primaryKey} = ?`;
225
+ const result = await this.db.execute(sql, [id]);
226
+ return result.affectedRows > 0;
227
+ }
228
+ /**
229
+ * Delete entities matching the given conditions
230
+ *
231
+ * @param where - Conditions to match for deletion
232
+ * @returns Number of deleted entities
233
+ *
234
+ * @example
235
+ * ```typescript
236
+ * const count = await userRepo.deleteWhere({ active: false })
237
+ * console.log(`Deleted ${count} inactive users`)
238
+ * ```
239
+ */
240
+ async deleteWhere(where) {
241
+ const { clause, params } = this.buildWhereClause(where);
242
+ if (!clause) {
243
+ throw new Error('deleteWhere requires at least one condition to prevent accidental full table deletion');
244
+ }
245
+ const sql = `DELETE FROM ${this.tableName}${clause}`;
246
+ const result = await this.db.execute(sql, params);
247
+ return result.affectedRows;
248
+ }
249
+ // ─────────────────────────────────────────────────────────────────────────────
250
+ // Protected Helper Methods
251
+ // ─────────────────────────────────────────────────────────────────────────────
252
+ /**
253
+ * Update an entity by ID
254
+ */
255
+ async update(id, row) {
256
+ const _a = row, _b = this.primaryKey, _ = _a[_b], updateData = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
257
+ const columns = Object.keys(updateData);
258
+ const setClause = columns.map((col) => `${col} = ?`).join(', ');
259
+ const values = columns.map((col) => updateData[col]);
260
+ const sql = `UPDATE ${this.tableName} SET ${setClause} WHERE ${this.primaryKey} = ?`;
261
+ await this.db.execute(sql, [...values, id]);
262
+ }
263
+ /**
264
+ * Insert a new row and return the inserted ID
265
+ */
266
+ async insertRow(row) {
267
+ const _a = row, _b = this.primaryKey, _ = _a[_b], insertData = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
268
+ const columns = Object.keys(insertData);
269
+ const placeholders = columns.map(() => '?').join(', ');
270
+ const values = columns.map((col) => insertData[col]);
271
+ const sql = `INSERT INTO ${this.tableName} (${columns.join(', ')}) VALUES (${placeholders})`;
272
+ const result = await this.db.insert(sql, values);
273
+ return result.insertId;
274
+ }
275
+ /**
276
+ * Build SELECT clause from field selection
277
+ */
278
+ buildSelectClause(select) {
279
+ if (!select || select.length === 0) {
280
+ return '*';
281
+ }
282
+ return select.map((field) => String(field)).join(', ');
283
+ }
284
+ /**
285
+ * Build WHERE clause from conditions
286
+ */
287
+ buildWhereClause(where) {
288
+ if (!where || Object.keys(where).length === 0) {
289
+ return { clause: '', params: [] };
290
+ }
291
+ const conditions = [];
292
+ const params = [];
293
+ for (const [key, value] of Object.entries(where)) {
294
+ if (value === null) {
295
+ conditions.push(`${key} IS NULL`);
296
+ }
297
+ else if (value === undefined) {
298
+ continue; // Skip undefined values
299
+ }
300
+ else {
301
+ conditions.push(`${key} = ?`);
302
+ params.push(value);
303
+ }
304
+ }
305
+ if (conditions.length === 0) {
306
+ return { clause: '', params: [] };
307
+ }
308
+ return {
309
+ clause: ` WHERE ${conditions.join(' AND ')}`,
310
+ params,
311
+ };
312
+ }
313
+ /**
314
+ * Build ORDER BY clause from orderBy options
315
+ */
316
+ buildOrderClause(orderBy) {
317
+ if (!orderBy || Object.keys(orderBy).length === 0) {
318
+ return '';
319
+ }
320
+ const orders = Object.entries(orderBy)
321
+ .filter(([_, direction]) => direction)
322
+ .map(([field, direction]) => `${field} ${direction}`);
323
+ if (orders.length === 0) {
324
+ return '';
325
+ }
326
+ return ` ORDER BY ${orders.join(', ')}`;
327
+ }
328
+ /**
329
+ * Build LIMIT/OFFSET clause
330
+ */
331
+ buildLimitClause(limit, offset) {
332
+ if (limit === undefined) {
333
+ return '';
334
+ }
335
+ let clause = ` LIMIT ${limit}`;
336
+ if (offset !== undefined && offset > 0) {
337
+ clause += ` OFFSET ${offset}`;
338
+ }
339
+ return clause;
340
+ }
341
+ }
342
+ exports.Repository = Repository;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Repository Pattern Types
3
+ *
4
+ * Types and interfaces for the generic repository pattern.
5
+ */
6
+ /**
7
+ * Sort direction for orderBy clauses
8
+ */
9
+ export type OrderDirection = 'ASC' | 'DESC';
10
+ /**
11
+ * Options for findMany queries with pagination, ordering, and field selection
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const options: FindOptions<User> = {
16
+ * select: ['id', 'name', 'email'],
17
+ * orderBy: { createdAt: 'DESC' },
18
+ * limit: 10,
19
+ * offset: 0
20
+ * }
21
+ * ```
22
+ */
23
+ export interface FindOptions<TEntity> {
24
+ /** Fields to select (SELECT clause). If omitted, selects all fields (*) */
25
+ select?: (keyof TEntity)[];
26
+ /** Order by fields with direction */
27
+ orderBy?: Partial<Record<keyof TEntity, OrderDirection>>;
28
+ /** Maximum number of records to return */
29
+ limit?: number;
30
+ /** Number of records to skip (for pagination) */
31
+ offset?: number;
32
+ }
33
+ /**
34
+ * Result of a findMany query with optional total count for pagination
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * const result = await userRepo.findMany({}, { limit: 10 })
39
+ * console.log(`Showing ${result.data.length} of ${result.total} users`)
40
+ * ```
41
+ */
42
+ export interface FindManyResult<TEntity> {
43
+ /** Array of entities matching the query */
44
+ data: TEntity[];
45
+ /** Total count of matching records (useful for pagination) */
46
+ total?: number;
47
+ }
48
+ /**
49
+ * Where clause condition - partial entity for simple equality matching
50
+ */
51
+ export type WhereCondition<TEntity> = Partial<TEntity>;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ /**
3
+ * Repository Pattern Types
4
+ *
5
+ * Types and interfaces for the generic repository pattern.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });