@ambiten/core 1.0.0

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 (304) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +247 -0
  3. package/bin/bootstrap.js +26 -0
  4. package/dist/ambiten-cache/ambitenCache.d.ts +64 -0
  5. package/dist/ambiten-cache/ambitenCache.d.ts.map +1 -0
  6. package/dist/ambiten-cache/ambitenCache.js +127 -0
  7. package/dist/ambiten-cache/index.d.ts +2 -0
  8. package/dist/ambiten-cache/index.d.ts.map +1 -0
  9. package/dist/ambiten-cache/index.js +4 -0
  10. package/dist/browser.d.ts +32 -0
  11. package/dist/browser.d.ts.map +1 -0
  12. package/dist/browser.js +37 -0
  13. package/dist/cli/ambiten-core-cli.d.ts +4 -0
  14. package/dist/cli/ambiten-core-cli.d.ts.map +1 -0
  15. package/dist/cli/ambiten-core-cli.js +41 -0
  16. package/dist/cli/buildInteractiveConfig.d.ts +4 -0
  17. package/dist/cli/buildInteractiveConfig.d.ts.map +1 -0
  18. package/dist/cli/buildInteractiveConfig.js +198 -0
  19. package/dist/cli/index.d.ts +5 -0
  20. package/dist/cli/index.d.ts.map +1 -0
  21. package/dist/cli/index.js +7 -0
  22. package/dist/cli/prompt.d.ts +10 -0
  23. package/dist/cli/prompt.d.ts.map +1 -0
  24. package/dist/cli/prompt.js +48 -0
  25. package/dist/cli/types.d.ts +11 -0
  26. package/dist/cli/types.d.ts.map +1 -0
  27. package/dist/cli/types.js +2 -0
  28. package/dist/config/ambiten.config.schema.json +278 -0
  29. package/dist/config/index.d.ts +2 -0
  30. package/dist/config/index.d.ts.map +1 -0
  31. package/dist/config/index.js +4 -0
  32. package/dist/config/loadAmbitenConfig.d.ts +3 -0
  33. package/dist/config/loadAmbitenConfig.d.ts.map +1 -0
  34. package/dist/config/loadAmbitenConfig.js +131 -0
  35. package/dist/context/ambitenContext.d.ts +35 -0
  36. package/dist/context/ambitenContext.d.ts.map +1 -0
  37. package/dist/context/ambitenContext.js +147 -0
  38. package/dist/context/helpers/runManualTransaction.d.ts +3 -0
  39. package/dist/context/helpers/runManualTransaction.d.ts.map +1 -0
  40. package/dist/context/helpers/runManualTransaction.js +22 -0
  41. package/dist/context/helpers/transactionSession.d.ts +9 -0
  42. package/dist/context/helpers/transactionSession.d.ts.map +1 -0
  43. package/dist/context/helpers/transactionSession.js +8 -0
  44. package/dist/context/index.d.ts +4 -0
  45. package/dist/context/index.d.ts.map +1 -0
  46. package/dist/context/index.js +6 -0
  47. package/dist/debug/debugLog.d.ts +2 -0
  48. package/dist/debug/debugLog.d.ts.map +1 -0
  49. package/dist/debug/debugLog.js +23 -0
  50. package/dist/debug/index.d.ts +2 -0
  51. package/dist/debug/index.d.ts.map +1 -0
  52. package/dist/debug/index.js +4 -0
  53. package/dist/gc/ambitenGC.d.ts +49 -0
  54. package/dist/gc/ambitenGC.d.ts.map +1 -0
  55. package/dist/gc/ambitenGC.js +138 -0
  56. package/dist/gc/gcCron.browser.d.ts +2 -0
  57. package/dist/gc/gcCron.browser.d.ts.map +1 -0
  58. package/dist/gc/gcCron.browser.js +9 -0
  59. package/dist/gc/gcCron.node.d.ts +19 -0
  60. package/dist/gc/gcCron.node.d.ts.map +1 -0
  61. package/dist/gc/gcCron.node.js +47 -0
  62. package/dist/gc/gcManager.d.ts +37 -0
  63. package/dist/gc/gcManager.d.ts.map +1 -0
  64. package/dist/gc/gcManager.js +62 -0
  65. package/dist/gc/index.d.ts +5 -0
  66. package/dist/gc/index.d.ts.map +1 -0
  67. package/dist/gc/index.js +7 -0
  68. package/dist/graphql/ambitenGraphQL.d.ts +24 -0
  69. package/dist/graphql/ambitenGraphQL.d.ts.map +1 -0
  70. package/dist/graphql/ambitenGraphQL.js +215 -0
  71. package/dist/graphql/index.d.ts +2 -0
  72. package/dist/graphql/index.d.ts.map +1 -0
  73. package/dist/graphql/index.js +4 -0
  74. package/dist/index-browser.js +25 -0
  75. package/dist/index-browser.js.map +1 -0
  76. package/dist/index-cli.js +26 -0
  77. package/dist/index-cli.js.map +1 -0
  78. package/dist/index.d.ts +30 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +25 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/init-cli/generate.project.d.ts +9 -0
  83. package/dist/init-cli/generate.project.d.ts.map +1 -0
  84. package/dist/init-cli/generate.project.js +38 -0
  85. package/dist/instrumentation/index.d.ts +3 -0
  86. package/dist/instrumentation/index.d.ts.map +1 -0
  87. package/dist/instrumentation/index.js +5 -0
  88. package/dist/instrumentation/measureQuery.browser.d.ts +3 -0
  89. package/dist/instrumentation/measureQuery.browser.d.ts.map +1 -0
  90. package/dist/instrumentation/measureQuery.browser.js +6 -0
  91. package/dist/instrumentation/measureQueryWithErrors.d.ts +11 -0
  92. package/dist/instrumentation/measureQueryWithErrors.d.ts.map +1 -0
  93. package/dist/instrumentation/measureQueryWithErrors.js +90 -0
  94. package/dist/lib-core/ambitenClient.d.ts +115 -0
  95. package/dist/lib-core/ambitenClient.d.ts.map +1 -0
  96. package/dist/lib-core/ambitenClient.js +537 -0
  97. package/dist/lib-core/ambitenModelFactory.d.ts +979 -0
  98. package/dist/lib-core/ambitenModelFactory.d.ts.map +1 -0
  99. package/dist/lib-core/ambitenModelFactory.js +3984 -0
  100. package/dist/lib-core/ambitenSchema.d.ts +126 -0
  101. package/dist/lib-core/ambitenSchema.d.ts.map +1 -0
  102. package/dist/lib-core/ambitenSchema.js +247 -0
  103. package/dist/lib-core/bootstrap/ambitenBootstrap.d.ts +38 -0
  104. package/dist/lib-core/bootstrap/ambitenBootstrap.d.ts.map +1 -0
  105. package/dist/lib-core/bootstrap/ambitenBootstrap.js +381 -0
  106. package/dist/lib-core/bootstrap/index.d.ts +2 -0
  107. package/dist/lib-core/bootstrap/index.d.ts.map +1 -0
  108. package/dist/lib-core/bootstrap/index.js +4 -0
  109. package/dist/lib-core/index.d.ts +5 -0
  110. package/dist/lib-core/index.d.ts.map +1 -0
  111. package/dist/lib-core/index.js +7 -0
  112. package/dist/middleware/authorization/auth.d.ts +22 -0
  113. package/dist/middleware/authorization/auth.d.ts.map +1 -0
  114. package/dist/middleware/authorization/auth.js +37 -0
  115. package/dist/middleware/index.d.ts +4 -0
  116. package/dist/middleware/index.d.ts.map +1 -0
  117. package/dist/middleware/index.js +6 -0
  118. package/dist/middleware/rbac/rbacMiddleware.d.ts +103 -0
  119. package/dist/middleware/rbac/rbacMiddleware.d.ts.map +1 -0
  120. package/dist/middleware/rbac/rbacMiddleware.js +246 -0
  121. package/dist/middleware/rbac/rbacTypes.d.ts +4 -0
  122. package/dist/middleware/rbac/rbacTypes.d.ts.map +1 -0
  123. package/dist/middleware/rbac/rbacTypes.js +8 -0
  124. package/dist/plugins/index.d.ts +3 -0
  125. package/dist/plugins/index.d.ts.map +1 -0
  126. package/dist/plugins/index.js +5 -0
  127. package/dist/plugins/softDelete/applySoftDelete.d.ts +5 -0
  128. package/dist/plugins/softDelete/applySoftDelete.d.ts.map +1 -0
  129. package/dist/plugins/softDelete/applySoftDelete.js +139 -0
  130. package/dist/plugins/softDelete/types.d.ts +14 -0
  131. package/dist/plugins/softDelete/types.d.ts.map +1 -0
  132. package/dist/plugins/softDelete/types.js +2 -0
  133. package/dist/redis-manager/index.d.ts +2 -0
  134. package/dist/redis-manager/index.d.ts.map +1 -0
  135. package/dist/redis-manager/index.js +4 -0
  136. package/dist/redis-manager/redisClient.d.ts +32 -0
  137. package/dist/redis-manager/redisClient.d.ts.map +1 -0
  138. package/dist/redis-manager/redisClient.js +146 -0
  139. package/dist/tanancy/MultiTenantManager.d.ts +98 -0
  140. package/dist/tanancy/MultiTenantManager.d.ts.map +1 -0
  141. package/dist/tanancy/MultiTenantManager.js +190 -0
  142. package/dist/tanancy/TenantContext.d.ts +31 -0
  143. package/dist/tanancy/TenantContext.d.ts.map +1 -0
  144. package/dist/tanancy/TenantContext.js +59 -0
  145. package/dist/tanancy/TenantModelResolver.d.ts +10 -0
  146. package/dist/tanancy/TenantModelResolver.d.ts.map +1 -0
  147. package/dist/tanancy/TenantModelResolver.js +114 -0
  148. package/dist/tanancy/index.d.ts +5 -0
  149. package/dist/tanancy/index.d.ts.map +1 -0
  150. package/dist/tanancy/index.js +7 -0
  151. package/dist/tanancy/init/initMultiTenancy.d.ts +29 -0
  152. package/dist/tanancy/init/initMultiTenancy.d.ts.map +1 -0
  153. package/dist/tanancy/init/initMultiTenancy.js +62 -0
  154. package/dist/templates/generateDefaultConfigContent.d.ts +10 -0
  155. package/dist/templates/generateDefaultConfigContent.d.ts.map +1 -0
  156. package/dist/templates/generateDefaultConfigContent.js +108 -0
  157. package/dist/templates/generateGCManagerFile.d.ts +2 -0
  158. package/dist/templates/generateGCManagerFile.d.ts.map +1 -0
  159. package/dist/templates/generateGCManagerFile.js +39 -0
  160. package/dist/templates/generateGCRunnerFile.d.ts +2 -0
  161. package/dist/templates/generateGCRunnerFile.d.ts.map +1 -0
  162. package/dist/templates/generateGCRunnerFile.js +25 -0
  163. package/dist/templates/generateMainEntry.d.ts +3 -0
  164. package/dist/templates/generateMainEntry.d.ts.map +1 -0
  165. package/dist/templates/generateMainEntry.js +24 -0
  166. package/dist/templates/index.d.ts +6 -0
  167. package/dist/templates/index.d.ts.map +1 -0
  168. package/dist/templates/index.js +8 -0
  169. package/dist/templates/scaffold/structureGenerator.d.ts +4 -0
  170. package/dist/templates/scaffold/structureGenerator.d.ts.map +1 -0
  171. package/dist/templates/scaffold/structureGenerator.js +193 -0
  172. package/dist/types/GCConfig.d.ts +7 -0
  173. package/dist/types/GCConfig.d.ts.map +1 -0
  174. package/dist/types/GCConfig.js +2 -0
  175. package/dist/types/ambiten-runtime-type.d.ts +24 -0
  176. package/dist/types/ambiten-runtime-type.d.ts.map +1 -0
  177. package/dist/types/ambiten-runtime-type.js +2 -0
  178. package/dist/types/ambiten.client.type.d.ts +136 -0
  179. package/dist/types/ambiten.client.type.d.ts.map +1 -0
  180. package/dist/types/ambiten.client.type.js +3 -0
  181. package/dist/types/ambiten.model.type.d.ts +135 -0
  182. package/dist/types/ambiten.model.type.d.ts.map +1 -0
  183. package/dist/types/ambiten.model.type.js +4 -0
  184. package/dist/types/ambitenConfig.d.ts +103 -0
  185. package/dist/types/ambitenConfig.d.ts.map +1 -0
  186. package/dist/types/ambitenConfig.js +3 -0
  187. package/dist/types/bootstrapClient.type.d.ts +11 -0
  188. package/dist/types/bootstrapClient.type.d.ts.map +1 -0
  189. package/dist/types/bootstrapClient.type.js +2 -0
  190. package/dist/types/db.provider.d.ts +66 -0
  191. package/dist/types/db.provider.d.ts.map +1 -0
  192. package/dist/types/db.provider.js +2 -0
  193. package/dist/types/document.d.ts +7 -0
  194. package/dist/types/document.d.ts.map +1 -0
  195. package/dist/types/document.js +2 -0
  196. package/dist/types/event.type.d.ts +6 -0
  197. package/dist/types/event.type.d.ts.map +1 -0
  198. package/dist/types/event.type.js +27 -0
  199. package/dist/types/graphql.type.d.ts +22 -0
  200. package/dist/types/graphql.type.d.ts.map +1 -0
  201. package/dist/types/graphql.type.js +2 -0
  202. package/dist/types/index.d.ts +15 -0
  203. package/dist/types/index.d.ts.map +1 -0
  204. package/dist/types/index.js +17 -0
  205. package/dist/types/logger.types.d.ts +15 -0
  206. package/dist/types/logger.types.d.ts.map +1 -0
  207. package/dist/types/logger.types.js +3 -0
  208. package/dist/types/middleware/types.d.ts +28 -0
  209. package/dist/types/middleware/types.d.ts.map +1 -0
  210. package/dist/types/middleware/types.js +2 -0
  211. package/dist/types/result.utils.types.d.ts +7 -0
  212. package/dist/types/result.utils.types.d.ts.map +1 -0
  213. package/dist/types/result.utils.types.js +2 -0
  214. package/dist/types/schema.type.d.ts +23 -0
  215. package/dist/types/schema.type.d.ts.map +1 -0
  216. package/dist/types/schema.type.js +10 -0
  217. package/dist/types/user.type.d.ts +11 -0
  218. package/dist/types/user.type.d.ts.map +1 -0
  219. package/dist/types/user.type.js +2 -0
  220. package/dist/utils/AuthUtils.d.ts +15 -0
  221. package/dist/utils/AuthUtils.d.ts.map +1 -0
  222. package/dist/utils/AuthUtils.js +26 -0
  223. package/dist/utils/ModelRegistry.d.ts +15 -0
  224. package/dist/utils/ModelRegistry.d.ts.map +1 -0
  225. package/dist/utils/ModelRegistry.js +35 -0
  226. package/dist/utils/banner.d.ts +2 -0
  227. package/dist/utils/banner.d.ts.map +1 -0
  228. package/dist/utils/banner.js +20 -0
  229. package/dist/utils/builders/createModel.d.ts +37 -0
  230. package/dist/utils/builders/createModel.d.ts.map +1 -0
  231. package/dist/utils/builders/createModel.js +38 -0
  232. package/dist/utils/builders/getTenantDb.d.ts +12 -0
  233. package/dist/utils/builders/getTenantDb.d.ts.map +1 -0
  234. package/dist/utils/builders/getTenantDb.js +25 -0
  235. package/dist/utils/builders/index.d.ts +4 -0
  236. package/dist/utils/builders/index.d.ts.map +1 -0
  237. package/dist/utils/builders/index.js +6 -0
  238. package/dist/utils/builders/schema.d.ts +22 -0
  239. package/dist/utils/builders/schema.d.ts.map +1 -0
  240. package/dist/utils/builders/schema.js +26 -0
  241. package/dist/utils/cacheWithRedis.d.ts +27 -0
  242. package/dist/utils/cacheWithRedis.d.ts.map +1 -0
  243. package/dist/utils/cacheWithRedis.js +22 -0
  244. package/dist/utils/castId.d.ts +5 -0
  245. package/dist/utils/castId.d.ts.map +1 -0
  246. package/dist/utils/castId.js +52 -0
  247. package/dist/utils/color-palatte.d.ts +4 -0
  248. package/dist/utils/color-palatte.d.ts.map +1 -0
  249. package/dist/utils/color-palatte.js +24 -0
  250. package/dist/utils/configureAmbitenContext.d.ts +13 -0
  251. package/dist/utils/configureAmbitenContext.d.ts.map +1 -0
  252. package/dist/utils/configureAmbitenContext.js +35 -0
  253. package/dist/utils/detect-package-manager.d.ts +5 -0
  254. package/dist/utils/detect-package-manager.d.ts.map +1 -0
  255. package/dist/utils/detect-package-manager.js +59 -0
  256. package/dist/utils/ensureModelNameSafe.d.ts +12 -0
  257. package/dist/utils/ensureModelNameSafe.d.ts.map +1 -0
  258. package/dist/utils/ensureModelNameSafe.js +28 -0
  259. package/dist/utils/ensureRedis.d.ts +7 -0
  260. package/dist/utils/ensureRedis.d.ts.map +1 -0
  261. package/dist/utils/ensureRedis.js +40 -0
  262. package/dist/utils/error/ambitenError-handler.d.ts +24 -0
  263. package/dist/utils/error/ambitenError-handler.d.ts.map +1 -0
  264. package/dist/utils/error/ambitenError-handler.js +39 -0
  265. package/dist/utils/error/errorTypes.d.ts +27 -0
  266. package/dist/utils/error/errorTypes.d.ts.map +1 -0
  267. package/dist/utils/error/errorTypes.js +30 -0
  268. package/dist/utils/error/index.d.ts +3 -0
  269. package/dist/utils/error/index.d.ts.map +1 -0
  270. package/dist/utils/error/index.js +5 -0
  271. package/dist/utils/eventOptions.d.ts +38 -0
  272. package/dist/utils/eventOptions.d.ts.map +1 -0
  273. package/dist/utils/eventOptions.js +130 -0
  274. package/dist/utils/events.d.ts +5 -0
  275. package/dist/utils/events.d.ts.map +1 -0
  276. package/dist/utils/events.js +7 -0
  277. package/dist/utils/index.d.ts +23 -0
  278. package/dist/utils/index.d.ts.map +1 -0
  279. package/dist/utils/index.js +25 -0
  280. package/dist/utils/invalidateTenantCache.d.ts +18 -0
  281. package/dist/utils/invalidateTenantCache.d.ts.map +1 -0
  282. package/dist/utils/invalidateTenantCache.js +27 -0
  283. package/dist/utils/logger.d.ts +3 -0
  284. package/dist/utils/logger.d.ts.map +1 -0
  285. package/dist/utils/logger.js +27 -0
  286. package/dist/utils/modelLoader.d.ts +3 -0
  287. package/dist/utils/modelLoader.d.ts.map +1 -0
  288. package/dist/utils/modelLoader.js +41 -0
  289. package/dist/utils/resolveAmbitenOption.d.ts +2 -0
  290. package/dist/utils/resolveAmbitenOption.d.ts.map +1 -0
  291. package/dist/utils/resolveAmbitenOption.js +10 -0
  292. package/dist/utils/resolveRuntimeConfig.d.ts +22 -0
  293. package/dist/utils/resolveRuntimeConfig.d.ts.map +1 -0
  294. package/dist/utils/resolveRuntimeConfig.js +33 -0
  295. package/dist/utils/scaffoldLoger.d.ts +11 -0
  296. package/dist/utils/scaffoldLoger.d.ts.map +1 -0
  297. package/dist/utils/scaffoldLoger.js +68 -0
  298. package/dist/utils/symbols.d.ts +4 -0
  299. package/dist/utils/symbols.d.ts.map +1 -0
  300. package/dist/utils/symbols.js +6 -0
  301. package/dist/utils/time.d.ts +5 -0
  302. package/dist/utils/time.d.ts.map +1 -0
  303. package/dist/utils/time.js +39 -0
  304. package/package.json +180 -0
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadAmbitenConfig = loadAmbitenConfig;
4
+ const tslib_1 = require("tslib");
5
+ const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
6
+ const path_1 = tslib_1.__importDefault(require("path"));
7
+ const ajv_1 = tslib_1.__importDefault(require("ajv"));
8
+ const ambiten_config_schema_json_1 = tslib_1.__importDefault(require("./ambiten.config.schema.json"));
9
+ const ajv = new ajv_1.default({
10
+ allErrors: true,
11
+ useDefaults: true,
12
+ strict: false,
13
+ coerceTypes: true,
14
+ });
15
+ let validate = null;
16
+ const DEFAULT_CONFIG_FILENAME = 'ambiten.config.json';
17
+ function normalizeAmbitenConfig(rawConfig) {
18
+ const cfg = { ...rawConfig };
19
+ if (typeof cfg.logger === 'boolean') {
20
+ cfg.logger = { enabled: cfg.logger };
21
+ }
22
+ if (cfg.logger && typeof cfg.logger === 'object') {
23
+ if (typeof cfg.logger.enableMetrics === 'boolean') {
24
+ cfg.logger.enableMetrics = {
25
+ enabled: cfg.logger.enableMetrics,
26
+ logInterval: 60000,
27
+ };
28
+ }
29
+ if (!cfg.logger.enableMetrics) {
30
+ cfg.logger.enableMetrics = {
31
+ enabled: false,
32
+ logInterval: 60000,
33
+ };
34
+ }
35
+ if (typeof cfg.logger.compressLogFiles === 'boolean') {
36
+ cfg.logger.compressLogFiles = {
37
+ enabled: cfg.logger.compressLogFiles,
38
+ };
39
+ }
40
+ if (!cfg.logger.compressLogFiles) {
41
+ cfg.logger.compressLogFiles = {
42
+ enabled: false,
43
+ };
44
+ }
45
+ }
46
+ if (typeof cfg.graphql === 'boolean') {
47
+ cfg.graphql = { enabled: cfg.graphql };
48
+ }
49
+ if (typeof cfg.advanced === 'boolean') {
50
+ cfg.advanced = {
51
+ garbageCollector: { enabled: cfg.advanced },
52
+ };
53
+ }
54
+ if (cfg.advanced && typeof cfg.advanced.garbageCollector === 'boolean') {
55
+ cfg.advanced.garbageCollector = {
56
+ enabled: cfg.advanced.garbageCollector,
57
+ };
58
+ }
59
+ if (!cfg.features) {
60
+ cfg.features = {};
61
+ }
62
+ if (typeof cfg.features.useRedisCache === 'undefined') {
63
+ cfg.features.useRedisCache = false;
64
+ }
65
+ return cfg;
66
+ }
67
+ function assertValidAmbitenConfig(config) {
68
+ if (!config.connection?.uri) {
69
+ throw new Error('Invalid config: "connection.uri" is required.');
70
+ }
71
+ if (config.multiTenant?.enabled &&
72
+ config.multiTenant.tenants &&
73
+ typeof config.multiTenant.tenants !== 'object') {
74
+ throw new Error('Invalid config: "multiTenant.tenants" must be a tenant-to-URI map.');
75
+ }
76
+ }
77
+ async function loadAmbitenConfig(configPath) {
78
+ const candidates = configPath
79
+ ? [path_1.default.resolve(configPath)]
80
+ : [
81
+ path_1.default.resolve(process.cwd(), DEFAULT_CONFIG_FILENAME),
82
+ path_1.default.resolve(process.cwd(), 'config', DEFAULT_CONFIG_FILENAME),
83
+ path_1.default.resolve(process.cwd(), 'src', 'config', DEFAULT_CONFIG_FILENAME),
84
+ path_1.default.resolve(__dirname, DEFAULT_CONFIG_FILENAME),
85
+ path_1.default.resolve(__dirname, '..', DEFAULT_CONFIG_FILENAME),
86
+ ];
87
+ let finalPath;
88
+ for (const candidate of candidates) {
89
+ if (await fs_extra_1.default.pathExists(candidate)) {
90
+ finalPath = candidate;
91
+ break;
92
+ }
93
+ }
94
+ if (!finalPath) {
95
+ throw new Error(`Config file not found at any of: ${candidates.join(', ')}`);
96
+ }
97
+ let parsed;
98
+ try {
99
+ const raw = await fs_extra_1.default.readFile(finalPath, 'utf-8');
100
+ parsed = normalizeAmbitenConfig(JSON.parse(raw));
101
+ }
102
+ catch (err) {
103
+ throw new Error(`[Ambiten] Failed to parse config file: ${err}`);
104
+ }
105
+ if (!validate) {
106
+ validate = ajv.compile(ambiten_config_schema_json_1.default);
107
+ }
108
+ const isValid = validate(parsed);
109
+ if (!isValid) {
110
+ console.error(JSON.stringify(validate.errors, null, 2));
111
+ const errors = validate.errors
112
+ ?.map((e) => {
113
+ const location = e.instancePath || '(root)';
114
+ const extra = e.keyword === 'additionalProperties'
115
+ ? `: ${e.params.additionalProperty}`
116
+ : '';
117
+ return `${location} ${e.message}${extra}`;
118
+ })
119
+ .join('; ');
120
+ throw new Error(`[Ambiten] Invalid configuration: ${errors}`);
121
+ }
122
+ assertValidAmbitenConfig(parsed);
123
+ parsed.graphql ??= { enabled: false };
124
+ parsed.features ??= { useRedisCache: false };
125
+ parsed.advanced ??= {
126
+ circuitBreaker: { enabled: false },
127
+ garbageCollector: { enabled: false },
128
+ };
129
+ return parsed;
130
+ }
131
+ ;
@@ -0,0 +1,35 @@
1
+ import type { ClientSession, MongoClient } from 'mongodb';
2
+ import { AmbitenContextState, AmbitenLoggerLike, AmbitenQueryObserver, AmbitenQuotaBudget, AmbitenQuotaBudgetInput } from '../types';
3
+ export interface AmbitenTransactionResolver {
4
+ resolveClient: (tenantId?: string, dbName?: string) => Promise<MongoClient | undefined> | MongoClient | undefined;
5
+ }
6
+ declare class AmbitenContextManager {
7
+ private readonly storage;
8
+ private transactionResolver?;
9
+ run<T>(context: AmbitenContextState, callback: () => T): T;
10
+ get(): AmbitenContextState;
11
+ hasActiveContext(): boolean;
12
+ set(patch: Partial<AmbitenContextState>): void;
13
+ clear(): void;
14
+ configureTransactionResolver(resolver: AmbitenTransactionResolver): void;
15
+ getTenantId(): string | undefined;
16
+ getRequestId(): string | undefined;
17
+ getDbName(): string | undefined;
18
+ getCollectionName(): string | undefined;
19
+ getSession(): ClientSession | undefined;
20
+ getLogger(): AmbitenLoggerLike | undefined;
21
+ getLoggerMeta(): Record<string, any> | undefined;
22
+ getObserver(): AmbitenQueryObserver | undefined;
23
+ normalizeBudget(budget?: AmbitenQuotaBudgetInput): AmbitenQuotaBudget;
24
+ getBudget(): AmbitenQuotaBudget;
25
+ setBudget(budget: AmbitenQuotaBudgetInput): void;
26
+ assertQueryBudget(): void;
27
+ incrementQueries(): AmbitenQuotaBudget;
28
+ addQueryTime(durationMs: number): AmbitenQuotaBudget;
29
+ isDebug(): boolean;
30
+ withTransaction<T>(callback: (session: ClientSession) => Promise<T>): Promise<T>;
31
+ hasTransactionResolver(): boolean;
32
+ }
33
+ export declare const AmbitenContext: AmbitenContextManager;
34
+ export {};
35
+ //# sourceMappingURL=ambitenContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ambitenContext.d.ts","sourceRoot":"","sources":["../../src/context/ambitenContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EACN,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,MAAM,UAAU,CAAC;AAGlB,MAAM,WAAW,0BAA0B;IAC1C,aAAa,EAAE,CACd,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,KACX,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,WAAW,GAAG,SAAS,CAAC;CAChE;AAQD,cAAM,qBAAqB;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgD;IACxE,OAAO,CAAC,mBAAmB,CAAC,CAA6B;IAEzD,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC;IAe1D,GAAG,IAAI,mBAAmB;IAI1B,gBAAgB,IAAI,OAAO;IAI3B,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAAG,IAAI;IAM9C,KAAK,IAAI,IAAI;IASb,4BAA4B,CAAC,QAAQ,EAAE,0BAA0B,GAAG,IAAI;IAIxE,WAAW,IAAI,MAAM,GAAG,SAAS;IAIjC,YAAY,IAAI,MAAM,GAAG,SAAS;IAIlC,SAAS,IAAI,MAAM,GAAG,SAAS;IAI/B,iBAAiB,IAAI,MAAM,GAAG,SAAS;IAIvC,UAAU,IAAI,aAAa,GAAG,SAAS;IAIvC,SAAS,IAAI,iBAAiB,GAAG,SAAS;IAI1C,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS;IAIhD,WAAW,IAAI,oBAAoB,GAAG,SAAS;IAI/C,eAAe,CAAC,MAAM,CAAC,EAAE,uBAAuB,GAAG,kBAAkB;IASrE,SAAS,IAAI,kBAAkB;IAO/B,SAAS,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI;IAKhD,iBAAiB,IAAI,IAAI;IAWzB,gBAAgB,IAAI,kBAAkB;IAOtC,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB;IAMpD,OAAO,IAAI,OAAO;IASZ,eAAe,CAAC,CAAC,EACtB,QAAQ,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,GAC9C,OAAO,CAAC,CAAC,CAAC;IA6Cb,sBAAsB,IAAI,OAAO;CAGjC;AAED,eAAO,MAAM,cAAc,uBAA8B,CAAC"}
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AmbitenContext = void 0;
4
+ const node_async_hooks_1 = require("node:async_hooks");
5
+ const runManualTransaction_1 = require("./helpers/runManualTransaction");
6
+ const DEFAULT_AMBITEN_BUDGET = {
7
+ maxQueries: Infinity,
8
+ queriesExecuted: 0,
9
+ totalTimeMs: 0
10
+ };
11
+ class AmbitenContextManager {
12
+ storage = new node_async_hooks_1.AsyncLocalStorage();
13
+ transactionResolver;
14
+ run(context, callback) {
15
+ const parent = this.storage.getStore() ?? {};
16
+ const merged = {
17
+ ...parent,
18
+ ...context,
19
+ budget: context.budget
20
+ ? this.normalizeBudget(context.budget)
21
+ : parent.budget
22
+ ? this.normalizeBudget(parent.budget)
23
+ : undefined
24
+ };
25
+ return this.storage.run(merged, callback);
26
+ }
27
+ get() {
28
+ return this.storage.getStore() ?? {};
29
+ }
30
+ hasActiveContext() {
31
+ return this.storage.getStore() !== undefined;
32
+ }
33
+ set(patch) {
34
+ const current = this.storage.getStore();
35
+ if (!current)
36
+ return;
37
+ Object.assign(current, patch);
38
+ }
39
+ clear() {
40
+ const current = this.storage.getStore();
41
+ if (!current)
42
+ return;
43
+ for (const key of Object.keys(current)) {
44
+ delete current[key];
45
+ }
46
+ }
47
+ configureTransactionResolver(resolver) {
48
+ this.transactionResolver = resolver;
49
+ }
50
+ getTenantId() {
51
+ return this.get().tenantId;
52
+ }
53
+ getRequestId() {
54
+ return this.get().requestId;
55
+ }
56
+ getDbName() {
57
+ return this.get().dbName;
58
+ }
59
+ getCollectionName() {
60
+ return this.get().collectionName;
61
+ }
62
+ getSession() {
63
+ return this.get().session;
64
+ }
65
+ getLogger() {
66
+ return this.get().logger;
67
+ }
68
+ getLoggerMeta() {
69
+ return this.get().loggerMeta;
70
+ }
71
+ getObserver() {
72
+ return this.get().observer;
73
+ }
74
+ normalizeBudget(budget) {
75
+ return {
76
+ maxQueries: budget?.maxQueries ?? DEFAULT_AMBITEN_BUDGET.maxQueries,
77
+ queriesExecuted: budget?.queriesExecuted ?? DEFAULT_AMBITEN_BUDGET.queriesExecuted,
78
+ totalTimeMs: budget?.totalTimeMs ?? DEFAULT_AMBITEN_BUDGET.totalTimeMs
79
+ };
80
+ }
81
+ getBudget() {
82
+ const state = this.get();
83
+ const normalized = this.normalizeBudget(state.budget);
84
+ state.budget = normalized;
85
+ return normalized;
86
+ }
87
+ setBudget(budget) {
88
+ const state = this.get();
89
+ state.budget = this.normalizeBudget(budget);
90
+ }
91
+ assertQueryBudget() {
92
+ const state = this.get();
93
+ const budget = this.getBudget();
94
+ if (budget.queriesExecuted >= budget.maxQueries) {
95
+ throw new Error(`[Ambiten] Tenant ${state.tenantId ?? 'unknown'} exceeded query budget for this request.`);
96
+ }
97
+ }
98
+ incrementQueries() {
99
+ this.assertQueryBudget();
100
+ const budget = this.getBudget();
101
+ budget.queriesExecuted += 1;
102
+ return budget;
103
+ }
104
+ addQueryTime(durationMs) {
105
+ const budget = this.getBudget();
106
+ budget.totalTimeMs += durationMs;
107
+ return budget;
108
+ }
109
+ isDebug() {
110
+ const ctx = this.get();
111
+ return Boolean(ctx.debug ||
112
+ process.env.AMBITEN_DEBUG === 'true' ||
113
+ process.env.AMBITEN_DEBUG === '1');
114
+ }
115
+ async withTransaction(callback) {
116
+ const current = this.get();
117
+ if (current.session) {
118
+ return callback(current.session);
119
+ }
120
+ if (!this.transactionResolver) {
121
+ throw new Error('AmbitenContext transaction resolver is not configured.');
122
+ }
123
+ const client = await this.transactionResolver.resolveClient(current.tenantId, current.dbName);
124
+ if (!client) {
125
+ throw new Error(`No MongoClient available for${current.tenantId ? ` tenant "${current.tenantId}"` : ' current context'}.`);
126
+ }
127
+ const session = client.startSession();
128
+ if (typeof session.withTransaction === 'function') {
129
+ try {
130
+ let result;
131
+ await session.withTransaction(async () => {
132
+ result = await this.run({ session }, () => callback(session));
133
+ return result;
134
+ });
135
+ return result;
136
+ }
137
+ finally {
138
+ await session.endSession();
139
+ }
140
+ }
141
+ return this.run({ session }, () => (0, runManualTransaction_1.runManualTransaction)(session, callback));
142
+ }
143
+ hasTransactionResolver() {
144
+ return Boolean(this.transactionResolver);
145
+ }
146
+ }
147
+ exports.AmbitenContext = new AmbitenContextManager();
@@ -0,0 +1,3 @@
1
+ import type { ClientSession } from 'mongodb';
2
+ export declare function runManualTransaction<T>(session: ClientSession, operation: (session: ClientSession) => Promise<T>): Promise<T>;
3
+ //# sourceMappingURL=runManualTransaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runManualTransaction.d.ts","sourceRoot":"","sources":["../../../src/context/helpers/runManualTransaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAG7C,wBAAsB,oBAAoB,CAAC,CAAC,EAC1C,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,GAChD,OAAO,CAAC,CAAC,CAAC,CAmBZ"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runManualTransaction = runManualTransaction;
4
+ const transactionSession_1 = require("./transactionSession");
5
+ async function runManualTransaction(session, operation) {
6
+ if (!(0, transactionSession_1.hasManualTransactionMethods)(session)) {
7
+ throw new Error('Session does not implement manual transaction methods.');
8
+ }
9
+ session.startTransaction();
10
+ try {
11
+ const result = await operation(session);
12
+ await session.commitTransaction();
13
+ return result;
14
+ }
15
+ catch (error) {
16
+ await session.abortTransaction();
17
+ throw error;
18
+ }
19
+ finally {
20
+ await session.endSession();
21
+ }
22
+ }
@@ -0,0 +1,9 @@
1
+ import type { ClientSession } from 'mongodb';
2
+ export interface ManualTransactionSession extends ClientSession {
3
+ startTransaction(): void;
4
+ commitTransaction(): Promise<void>;
5
+ abortTransaction(): Promise<void>;
6
+ endSession(): Promise<void>;
7
+ }
8
+ export declare function hasManualTransactionMethods(session: ClientSession): session is ManualTransactionSession;
9
+ //# sourceMappingURL=transactionSession.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transactionSession.d.ts","sourceRoot":"","sources":["../../../src/context/helpers/transactionSession.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,WAAW,wBAAyB,SAAQ,aAAa;IAC7D,gBAAgB,IAAI,IAAI,CAAC;IACzB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,aAAa,GACrB,OAAO,IAAI,wBAAwB,CAMrC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasManualTransactionMethods = hasManualTransactionMethods;
4
+ function hasManualTransactionMethods(session) {
5
+ return (typeof session.startTransaction === 'function' &&
6
+ typeof session.commitTransaction === 'function' &&
7
+ typeof session.abortTransaction === 'function');
8
+ }
@@ -0,0 +1,4 @@
1
+ export * from './ambitenContext';
2
+ export * from './helpers/transactionSession';
3
+ export * from './helpers/runManualTransaction';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gCAAgC,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./ambitenContext"), exports);
5
+ tslib_1.__exportStar(require("./helpers/transactionSession"), exports);
6
+ tslib_1.__exportStar(require("./helpers/runManualTransaction"), exports);
@@ -0,0 +1,2 @@
1
+ export declare function debugLog(message: string, meta?: Record<string, any>): void;
2
+ //# sourceMappingURL=debugLog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debugLog.d.ts","sourceRoot":"","sources":["../../src/debug/debugLog.ts"],"names":[],"mappings":"AAEA,wBAAgB,QAAQ,CACtB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAC7B,IAAI,CAqBN"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.debugLog = debugLog;
4
+ const context_1 = require("../context");
5
+ function debugLog(message, meta = {}) {
6
+ if (!context_1.AmbitenContext.isDebug())
7
+ return;
8
+ const logger = context_1.AmbitenContext.getLogger();
9
+ const loggerMeta = context_1.AmbitenContext.getLoggerMeta() ?? {};
10
+ const payload = {
11
+ tenantId: context_1.AmbitenContext.getTenantId(),
12
+ requestId: context_1.AmbitenContext.getRequestId(),
13
+ dbName: context_1.AmbitenContext.getDbName(),
14
+ collectionName: context_1.AmbitenContext.getCollectionName(),
15
+ ...loggerMeta,
16
+ ...meta
17
+ };
18
+ if (logger?.debug) {
19
+ logger.debug(message, payload);
20
+ return;
21
+ }
22
+ console.debug(`[AMBITEN_DEBUG] ${message}`, payload);
23
+ }
@@ -0,0 +1,2 @@
1
+ export * from './debugLog';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/debug/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./debugLog"), exports);
@@ -0,0 +1,49 @@
1
+ import type { ModelContext } from '../types';
2
+ import { type GarbageCollectorRunResult } from './gcManager';
3
+ export interface GCOptions {
4
+ enabled?: boolean;
5
+ interval?: string;
6
+ retentionPeriod?: number;
7
+ logResults?: boolean;
8
+ cron?: string;
9
+ ctx?: ModelContext;
10
+ continueOnError?: boolean;
11
+ logger?: {
12
+ info?: (message: string, meta?: Record<string, unknown>) => void;
13
+ warn?: (message: string, meta?: Record<string, unknown>) => void;
14
+ error?: (message: string, meta?: Record<string, unknown>) => void;
15
+ };
16
+ }
17
+ export declare class AmbitenGC {
18
+ private readonly options;
19
+ private readonly enabled;
20
+ private intervalMs;
21
+ private intervalRef;
22
+ private cronTask;
23
+ constructor(options?: GCOptions);
24
+ /**
25
+ * Starts interval-based garbage collection.
26
+ */
27
+ start(): void;
28
+ /**
29
+ * Stops interval or cron-based garbage collection.
30
+ */
31
+ stop(): void;
32
+ /**
33
+ * Runs garbage collection once across registered models.
34
+ *
35
+ * @param ctx - Optional model execution context override.
36
+ * @returns Summary of the GC run.
37
+ */
38
+ runOnce(ctx?: ModelContext): Promise<GarbageCollectorRunResult>;
39
+ /**
40
+ * Parses interval strings such as "30s", "5m", "1h", or "1d".
41
+ *
42
+ * @param duration - Interval duration.
43
+ * @returns Duration in milliseconds.
44
+ * @throws {Error} When the interval format is invalid.
45
+ */
46
+ private parseInterval;
47
+ private log;
48
+ }
49
+ //# sourceMappingURL=ambitenGC.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ambitenGC.d.ts","sourceRoot":"","sources":["../../src/gc/ambitenGC.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,YAAY,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;QACjE,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;QACjE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;KACnE,CAAC;CACH;AAED,qBAAa,SAAS;IAMR,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,QAAQ,CAAmC;gBAEtB,OAAO,GAAE,SAAc;IAiCpD;;OAEG;IACH,KAAK,IAAI,IAAI;IAmBb;;OAEG;IACH,IAAI,IAAI,IAAI;IAcZ;;;;;OAKG;IACG,OAAO,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAyBrE;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAwBrB,OAAO,CAAC,GAAG;CAwBZ"}
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AmbitenGC = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const cron = tslib_1.__importStar(require("node-cron"));
6
+ const utils_1 = require("../utils");
7
+ const gcManager_1 = require("./gcManager");
8
+ class AmbitenGC {
9
+ options;
10
+ enabled;
11
+ intervalMs;
12
+ intervalRef = null;
13
+ cronTask = null;
14
+ constructor(options = {}) {
15
+ this.options = options;
16
+ this.enabled = options.enabled !== false;
17
+ this.intervalMs = options.interval
18
+ ? this.parseInterval(options.interval)
19
+ : 60_000;
20
+ if (options.retentionPeriod) {
21
+ this.intervalMs = options.retentionPeriod * 24 * 60 * 60 * 1000;
22
+ }
23
+ if (!this.enabled) {
24
+ this.log('info', '[AmbitenGC] Garbage Collector is disabled.');
25
+ return;
26
+ }
27
+ if (options.cron) {
28
+ this.cronTask = cron.schedule(options.cron, () => {
29
+ void this.runOnce();
30
+ });
31
+ this.log('info', `[AmbitenGC] Cron schedule set to: ${options.cron}`);
32
+ return;
33
+ }
34
+ if (options.interval) {
35
+ this.start();
36
+ this.log('info', `[AmbitenGC] Interval set to: ${options.interval}`);
37
+ return;
38
+ }
39
+ this.log('info', '[AmbitenGC] Initialized. Manual run mode enabled.');
40
+ }
41
+ /**
42
+ * Starts interval-based garbage collection.
43
+ */
44
+ start() {
45
+ if (!this.enabled) {
46
+ return;
47
+ }
48
+ if (this.intervalRef) {
49
+ return;
50
+ }
51
+ this.intervalRef = setInterval(() => {
52
+ void this.runOnce();
53
+ }, this.intervalMs);
54
+ this.log('info', `[AmbitenGC] Started GC loop every ${this.intervalMs} ms`);
55
+ }
56
+ /**
57
+ * Stops interval or cron-based garbage collection.
58
+ */
59
+ stop() {
60
+ if (this.intervalRef) {
61
+ clearInterval(this.intervalRef);
62
+ this.intervalRef = null;
63
+ }
64
+ if (this.cronTask) {
65
+ this.cronTask.stop();
66
+ this.cronTask = null;
67
+ }
68
+ this.log('info', '[AmbitenGC] Stopped.');
69
+ }
70
+ /**
71
+ * Runs garbage collection once across registered models.
72
+ *
73
+ * @param ctx - Optional model execution context override.
74
+ * @returns Summary of the GC run.
75
+ */
76
+ async runOnce(ctx) {
77
+ if (!this.enabled) {
78
+ return {
79
+ scanned: 0,
80
+ succeeded: 0,
81
+ failed: 0,
82
+ models: []
83
+ };
84
+ }
85
+ const result = await (0, gcManager_1.runGarbageCollectorOnAllModels)({
86
+ ctx: ctx ?? this.options.ctx,
87
+ continueOnError: this.options.continueOnError ?? true
88
+ });
89
+ if (this.options.logResults) {
90
+ this.log(result.failed > 0 ? 'warn' : 'info', `[AmbitenGC] Completed. scanned=${result.scanned}, succeeded=${result.succeeded}, failed=${result.failed}`);
91
+ }
92
+ return result;
93
+ }
94
+ /**
95
+ * Parses interval strings such as "30s", "5m", "1h", or "1d".
96
+ *
97
+ * @param duration - Interval duration.
98
+ * @returns Duration in milliseconds.
99
+ * @throws {Error} When the interval format is invalid.
100
+ */
101
+ parseInterval(duration) {
102
+ const match = duration.match(/^(\d+)([smhd])$/);
103
+ if (!match) {
104
+ throw new Error(`Invalid interval format: ${duration}`);
105
+ }
106
+ const [, num, unit] = match;
107
+ const value = Number.parseInt(num, 10);
108
+ switch (unit) {
109
+ case 's':
110
+ return value * 1000;
111
+ case 'm':
112
+ return value * 60 * 1000;
113
+ case 'h':
114
+ return value * 60 * 60 * 1000;
115
+ case 'd':
116
+ return value * 24 * 60 * 60 * 1000;
117
+ default:
118
+ throw new Error(`Unknown time unit: ${unit}`);
119
+ }
120
+ }
121
+ log(level, message, meta) {
122
+ const logger = this.options.logger;
123
+ if (logger?.[level]) {
124
+ logger[level]?.(message, meta);
125
+ return;
126
+ }
127
+ if (level === 'error') {
128
+ console.error((0, utils_1.colorize)(message, 'red'), meta ?? '');
129
+ return;
130
+ }
131
+ if (level === 'warn') {
132
+ console.warn((0, utils_1.colorize)(message, 'yellow'), meta ?? '');
133
+ return;
134
+ }
135
+ console.log((0, utils_1.colorize)(message, 'blue'), meta ?? '');
136
+ }
137
+ }
138
+ exports.AmbitenGC = AmbitenGC;
@@ -0,0 +1,2 @@
1
+ export declare const startGarbageCollector: () => void;
2
+ //# sourceMappingURL=gcCron.browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gcCron.browser.d.ts","sourceRoot":"","sources":["../../src/gc/gcCron.browser.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,qBAAqB,YAGjC,CAAC"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.startGarbageCollector = void 0;
4
+ const utils_1 = require("../utils");
5
+ const startGarbageCollector = () => {
6
+ // No-op for browsers
7
+ console.warn((0, utils_1.colorize)('[GC] Garbage collector is disabled in the browser.', 'red'));
8
+ };
9
+ exports.startGarbageCollector = startGarbageCollector;
@@ -0,0 +1,19 @@
1
+ import * as cron from 'node-cron';
2
+ import type { ModelContext } from '../types';
3
+ export interface GarbageCollectorScheduleOptions {
4
+ cronExpr?: string;
5
+ ctx?: ModelContext;
6
+ continueOnError?: boolean;
7
+ }
8
+ /**
9
+ * Schedules registry-driven garbage collection.
10
+ *
11
+ * The cron task uses registered model instances and delegates cleanup to
12
+ * `model.runGC()` so Ambiten's runtime context, middleware, schema hooks,
13
+ * instrumentation, cache invalidation, and events remain centralized.
14
+ *
15
+ * @param options - Cron expression or scheduler options.
16
+ * @returns The scheduled cron task.
17
+ */
18
+ export declare function scheduleGarbageCollector(options?: string | GarbageCollectorScheduleOptions): cron.ScheduledTask;
19
+ //# sourceMappingURL=gcCron.node.d.ts.map