@getstrata/bootstrap 0.2.21 → 0.2.23

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 (238) hide show
  1. package/dist/bootstrap/applicationRegistry.d.ts +1 -1
  2. package/dist/bootstrap/buildModuleRoutes.d.ts +10 -0
  3. package/dist/bootstrap/config.d.ts +1 -1
  4. package/dist/bootstrap/contracts.d.ts +4 -4
  5. package/dist/bootstrap/discoverModules.d.ts +7 -3
  6. package/dist/bootstrap/modules.d.ts +1 -1
  7. package/dist/bootstrap/public-api.d.ts +4 -0
  8. package/dist/entries/applicationRegistry.js +12 -115
  9. package/dist/entries/buildModuleRoutes.js +626 -0
  10. package/dist/entries/cache/modelCacheTags.js +56 -2
  11. package/dist/entries/config.js +9 -9
  12. package/dist/entries/context.js +177 -187
  13. package/dist/entries/contracts.js +10 -85
  14. package/dist/entries/createWebRoutes.js +68 -14
  15. package/dist/entries/dependencies.js +177 -187
  16. package/dist/entries/discoverModules.js +65 -0
  17. package/dist/entries/http/securedRouteModelBinding.js +4 -34
  18. package/dist/entries/httpKernel.js +9 -9
  19. package/dist/entries/membershipService.js +0 -34
  20. package/dist/entries/providers/view.js +9 -9
  21. package/dist/entries/providers.js +156 -113
  22. package/dist/entries/queue/defaultJobs.js +0 -34
  23. package/dist/entries/web/routing.js +20 -41
  24. package/dist/index.js +3830 -3762
  25. package/package.json +14 -4
  26. package/dist/cli/commands/scheduleRun.d.ts +0 -3
  27. package/dist/config/app.d.ts +0 -10
  28. package/dist/config/auth.d.ts +0 -7
  29. package/dist/config/contentSecurityPolicy.d.ts +0 -5
  30. package/dist/config/cors.d.ts +0 -9
  31. package/dist/config/database.d.ts +0 -10
  32. package/dist/config/features.d.ts +0 -18
  33. package/dist/config/frontend.d.ts +0 -6
  34. package/dist/config/queue.d.ts +0 -8
  35. package/dist/config/rateLimit.d.ts +0 -10
  36. package/dist/config/uploads.d.ts +0 -5
  37. package/dist/core/admin/formatValue.d.ts +0 -3
  38. package/dist/core/admin/index.d.ts +0 -3
  39. package/dist/core/admin/registry.d.ts +0 -11
  40. package/dist/core/admin/types.d.ts +0 -24
  41. package/dist/core/audit/exportAuditLogs.d.ts +0 -8
  42. package/dist/core/audit/siemFormatter.d.ts +0 -30
  43. package/dist/core/auth/abilityChecker.d.ts +0 -6
  44. package/dist/core/auth/accessControl.d.ts +0 -8
  45. package/dist/core/auth/authContext.d.ts +0 -11
  46. package/dist/core/auth/guard.d.ts +0 -36
  47. package/dist/core/auth/membershipContext.d.ts +0 -15
  48. package/dist/core/auth/membershipContextMiddleware.d.ts +0 -3
  49. package/dist/core/auth/membershipMiddleware.d.ts +0 -2
  50. package/dist/core/auth/membershipScope.d.ts +0 -16
  51. package/dist/core/auth/membershipService.d.ts +0 -23
  52. package/dist/core/auth/oauth/oidcProvider.d.ts +0 -18
  53. package/dist/core/auth/oauth/providers.d.ts +0 -22
  54. package/dist/core/auth/oauth/samlProvider.d.ts +0 -9
  55. package/dist/core/auth/oauth/types.d.ts +0 -11
  56. package/dist/core/auth/password.d.ts +0 -3
  57. package/dist/core/auth/policy.d.ts +0 -15
  58. package/dist/core/auth/resolveMembershipService.d.ts +0 -3
  59. package/dist/core/auth/scimAuthMiddleware.d.ts +0 -3
  60. package/dist/core/auth/sessionCookie.d.ts +0 -6
  61. package/dist/core/auth/sessionGuard.d.ts +0 -9
  62. package/dist/core/auth/tokenHash.d.ts +0 -3
  63. package/dist/core/cache/createCacheStore.d.ts +0 -11
  64. package/dist/core/cache/redisCacheStore.d.ts +0 -23
  65. package/dist/core/cache/repository.d.ts +0 -17
  66. package/dist/core/cache/simpleCache.d.ts +0 -23
  67. package/dist/core/cache/simpleCacheStore.d.ts +0 -16
  68. package/dist/core/cache/store.d.ts +0 -12
  69. package/dist/core/cache/taggedCache.d.ts +0 -9
  70. package/dist/core/cache/tags.d.ts +0 -11
  71. package/dist/core/config/envSchema.d.ts +0 -12
  72. package/dist/core/contracts/container.d.ts +0 -30
  73. package/dist/core/contracts/di.d.ts +0 -31
  74. package/dist/core/contracts/serviceContainer.d.ts +0 -1
  75. package/dist/core/contracts/serviceTokens.d.ts +0 -8
  76. package/dist/core/crypto/fieldEncryption.d.ts +0 -13
  77. package/dist/core/crypto/mfaSecret.d.ts +0 -3
  78. package/dist/core/crypto/nonCryptographicHash.d.ts +0 -2
  79. package/dist/core/database/baseRepository.d.ts +0 -67
  80. package/dist/core/database/bindConnection.d.ts +0 -3
  81. package/dist/core/database/boundConnection.d.ts +0 -5
  82. package/dist/core/database/connection.d.ts +0 -7
  83. package/dist/core/database/connectionContext.d.ts +0 -8
  84. package/dist/core/database/defaultConnection.d.ts +0 -6
  85. package/dist/core/database/errors.d.ts +0 -12
  86. package/dist/core/database/index.d.ts +0 -18
  87. package/dist/core/database/migrations/advisoryLock.d.ts +0 -6
  88. package/dist/core/database/migrations/runner.d.ts +0 -25
  89. package/dist/core/database/migrations/types.d.ts +0 -15
  90. package/dist/core/database/model.d.ts +0 -57
  91. package/dist/core/database/query.d.ts +0 -63
  92. package/dist/core/database/queryProxy.d.ts +0 -3
  93. package/dist/core/database/relationships.d.ts +0 -100
  94. package/dist/core/database/repositoryConnection.d.ts +0 -4
  95. package/dist/core/database/repositoryQuery.d.ts +0 -38
  96. package/dist/core/database/schema/blueprint.d.ts +0 -47
  97. package/dist/core/database/schema/columnDefinition.d.ts +0 -36
  98. package/dist/core/database/schema/driver.d.ts +0 -8
  99. package/dist/core/database/schema/errors.d.ts +0 -4
  100. package/dist/core/database/schema/grammars/compileStatements.d.ts +0 -8
  101. package/dist/core/database/schema/grammars/createGrammar.d.ts +0 -4
  102. package/dist/core/database/schema/grammars/grammar.d.ts +0 -10
  103. package/dist/core/database/schema/grammars/index.d.ts +0 -7
  104. package/dist/core/database/schema/grammars/mysqlGrammar.d.ts +0 -2
  105. package/dist/core/database/schema/grammars/postgresGrammar.d.ts +0 -2
  106. package/dist/core/database/schema/grammars/sqliteGrammar.d.ts +0 -2
  107. package/dist/core/database/schema/index.d.ts +0 -12
  108. package/dist/core/database/schema/schema.d.ts +0 -21
  109. package/dist/core/database/seeders/runner.d.ts +0 -6
  110. package/dist/core/database/seeders/types.d.ts +0 -8
  111. package/dist/core/database/table.d.ts +0 -13
  112. package/dist/core/database/transaction.d.ts +0 -3
  113. package/dist/core/database/types.d.ts +0 -66
  114. package/dist/core/database/whereBuilder.d.ts +0 -17
  115. package/dist/core/errors/http.d.ts +0 -33
  116. package/dist/core/events/eventBus.d.ts +0 -10
  117. package/dist/core/events/index.d.ts +0 -4
  118. package/dist/core/facades/index.d.ts +0 -10
  119. package/dist/core/http/authMiddleware.d.ts +0 -5
  120. package/dist/core/http/authorizeMiddleware.d.ts +0 -5
  121. package/dist/core/http/bodySizeLimitMiddleware.d.ts +0 -4
  122. package/dist/core/http/conditionalResponse.d.ts +0 -2
  123. package/dist/core/http/contentNegotiation.d.ts +0 -2
  124. package/dist/core/http/cookies.d.ts +0 -4
  125. package/dist/core/http/corsMiddleware.d.ts +0 -3
  126. package/dist/core/http/csrfMiddleware.d.ts +0 -3
  127. package/dist/core/http/csrfProtection.d.ts +0 -12
  128. package/dist/core/http/csrfToken.d.ts +0 -14
  129. package/dist/core/http/etag.d.ts +0 -18
  130. package/dist/core/http/flashMiddleware.d.ts +0 -3
  131. package/dist/core/http/flashSession.d.ts +0 -12
  132. package/dist/core/http/formRequest.d.ts +0 -10
  133. package/dist/core/http/index.d.ts +0 -27
  134. package/dist/core/http/loginThrottleMiddleware.d.ts +0 -11
  135. package/dist/core/http/memoryThrottleMiddleware.d.ts +0 -9
  136. package/dist/core/http/metricsMiddleware.d.ts +0 -4
  137. package/dist/core/http/middleware.d.ts +0 -8
  138. package/dist/core/http/pagination.d.ts +0 -11
  139. package/dist/core/http/parseFormBody.d.ts +0 -6
  140. package/dist/core/http/parseMultipartUpload.d.ts +0 -10
  141. package/dist/core/http/requestMetaContext.d.ts +0 -15
  142. package/dist/core/http/requireAbilityMiddleware.d.ts +0 -4
  143. package/dist/core/http/requireAuthMiddleware.d.ts +0 -4
  144. package/dist/core/http/requireGlobalAdminMiddleware.d.ts +0 -3
  145. package/dist/core/http/requireWebAuthMiddleware.d.ts +0 -4
  146. package/dist/core/http/resources.d.ts +0 -7
  147. package/dist/core/http/route.d.ts +0 -6
  148. package/dist/core/http/routeMiddleware.d.ts +0 -3
  149. package/dist/core/http/routeModelBinding.d.ts +0 -3
  150. package/dist/core/http/scimThrottleMiddleware.d.ts +0 -9
  151. package/dist/core/http/securedRouteModelBinding.d.ts +0 -11
  152. package/dist/core/http/securityHeadersMiddleware.d.ts +0 -3
  153. package/dist/core/http/throttleMiddleware.d.ts +0 -11
  154. package/dist/core/http/validation.d.ts +0 -23
  155. package/dist/core/http/webErrorResponse.d.ts +0 -5
  156. package/dist/core/http/webFormRequest.d.ts +0 -7
  157. package/dist/core/jobs/dispatchWebhookJob.d.ts +0 -13
  158. package/dist/core/jobs/invalidateCacheTagsJob.d.ts +0 -12
  159. package/dist/core/lifecycle/gracefulShutdown.d.ts +0 -6
  160. package/dist/core/logging/logger.d.ts +0 -17
  161. package/dist/core/logging/requestLoggingMiddleware.d.ts +0 -3
  162. package/dist/core/mail/mailer.d.ts +0 -38
  163. package/dist/core/mail/markdownMail.d.ts +0 -15
  164. package/dist/core/mail/markdownMailable.d.ts +0 -12
  165. package/dist/core/metrics/prometheus.d.ts +0 -26
  166. package/dist/core/notifications/dispatcher.d.ts +0 -13
  167. package/dist/core/notifications/index.d.ts +0 -3
  168. package/dist/core/notifications/notification.d.ts +0 -7
  169. package/dist/core/notifications/types.d.ts +0 -25
  170. package/dist/core/openapi/registeredRoute.d.ts +0 -6
  171. package/dist/core/pagination/index.d.ts +0 -27
  172. package/dist/core/queue/createAppQueue.d.ts +0 -5
  173. package/dist/core/queue/failedJobRepository.d.ts +0 -6
  174. package/dist/core/queue/failedJobService.d.ts +0 -16
  175. package/dist/core/queue/failedJobTable.d.ts +0 -3
  176. package/dist/core/queue/index.d.ts +0 -19
  177. package/dist/core/queue/jobRegistry.d.ts +0 -13
  178. package/dist/core/queue/jobRunner.d.ts +0 -9
  179. package/dist/core/queue/publicQueue.d.ts +0 -16
  180. package/dist/core/queue/queueMetrics.d.ts +0 -15
  181. package/dist/core/queue/redisQueue.d.ts +0 -29
  182. package/dist/core/queue/resilientQueue.d.ts +0 -9
  183. package/dist/core/queue/types.d.ts +0 -8
  184. package/dist/core/runtime/applicationRegistry.d.ts +0 -17
  185. package/dist/core/runtime/asyncContextStore.d.ts +0 -3
  186. package/dist/core/scheduler/schedule.d.ts +0 -15
  187. package/dist/core/security/publicReads.d.ts +0 -3
  188. package/dist/core/security/safeFetch.d.ts +0 -10
  189. package/dist/core/security/safeUrl.d.ts +0 -20
  190. package/dist/core/security/scimTenantTokens.d.ts +0 -3
  191. package/dist/core/security/securityEvents.d.ts +0 -6
  192. package/dist/core/security/timingSafeCompare.d.ts +0 -2
  193. package/dist/core/security/tokenExpiry.d.ts +0 -2
  194. package/dist/core/security/totp.d.ts +0 -3
  195. package/dist/core/storage/storage.d.ts +0 -44
  196. package/dist/core/tenant/databaseTenantContext.d.ts +0 -2
  197. package/dist/core/tenant/resolveTenant.d.ts +0 -3
  198. package/dist/core/tenant/tenantContext.d.ts +0 -13
  199. package/dist/core/tenant/tenantDatabaseScope.d.ts +0 -8
  200. package/dist/core/tenant/tenantMiddleware.d.ts +0 -6
  201. package/dist/core/tracing/otel.d.ts +0 -26
  202. package/dist/core/tracing/traceContext.d.ts +0 -9
  203. package/dist/core/tracing/tracingMiddleware.d.ts +0 -3
  204. package/dist/core/validation/rules.d.ts +0 -17
  205. package/dist/core/view/etaViewEngine.d.ts +0 -15
  206. package/dist/core/view/htmlResponse.d.ts +0 -6
  207. package/dist/core/view/index.d.ts +0 -5
  208. package/dist/core/view/viewEngine.d.ts +0 -6
  209. package/dist/core/view/webLayoutData.d.ts +0 -17
  210. package/dist/db/connection/createConnection.d.ts +0 -6
  211. package/dist/db/connection/index.d.ts +0 -11
  212. package/dist/domain/abilities.d.ts +0 -5
  213. package/dist/domain/auth.d.ts +0 -4
  214. package/dist/domain/scim.d.ts +0 -9
  215. package/dist/domain/workhub.d.ts +0 -35
  216. package/dist/framework/public-api.d.ts +0 -116
  217. package/dist/modules/organization/memberRepository.d.ts +0 -14
  218. package/dist/modules/organization/memberTypes.d.ts +0 -9
  219. package/dist/modules/organization/repository.d.ts +0 -14
  220. package/dist/modules/organization/table.d.ts +0 -3
  221. package/dist/modules/organization/types.d.ts +0 -10
  222. package/dist/modules/scim/controller.d.ts +0 -16
  223. package/dist/modules/scim/scimResponse.d.ts +0 -10
  224. package/dist/modules/scim/service.d.ts +0 -214
  225. package/dist/modules/user/apiTokenRepository.d.ts +0 -8
  226. package/dist/modules/user/apiTokenTable.d.ts +0 -3
  227. package/dist/modules/user/authService.d.ts +0 -23
  228. package/dist/modules/user/notificationRepository.d.ts +0 -6
  229. package/dist/modules/user/notificationService.d.ts +0 -25
  230. package/dist/modules/user/notificationTable.d.ts +0 -3
  231. package/dist/modules/user/notificationTypes.d.ts +0 -12
  232. package/dist/modules/user/oauthIdentityRepository.d.ts +0 -9
  233. package/dist/modules/user/provider.d.ts +0 -11
  234. package/dist/modules/user/repository.d.ts +0 -13
  235. package/dist/modules/user/table.d.ts +0 -3
  236. package/dist/modules/user/tokenService.d.ts +0 -29
  237. package/dist/modules/user/types.d.ts +0 -46
  238. package/dist/types/services.d.ts +0 -16
@@ -1,187 +1,86 @@
1
1
  // @bun
2
- // ../../src/core/contracts/di.ts
3
- var requiredDependencyKeys = [
4
- "container",
5
- "cache",
6
- "storage"
7
- ];
8
- function getRequiredDependency(dependencies, key) {
9
- const dependency = dependencies[key];
10
- if (dependency === undefined) {
11
- throw new Error(`Required dependency "${key}" is not registered.`);
12
- }
13
- return dependency;
14
- }
15
- function assertAppDependenciesComplete(dependencies) {
16
- for (const key of requiredDependencyKeys) {
17
- getRequiredDependency(dependencies, key);
18
- }
19
- }
20
- function resolveService(dependencies, token) {
21
- return dependencies.container.resolve(token);
22
- }
23
-
24
- // ../../src/core/contracts/serviceTokens.ts
25
- var CORE_CONFIG_TOKEN = "core.config";
26
- var CORE_CACHE_TOKEN = "core.cache";
27
- var CORE_QUEUE_TOKEN = "core.queue";
28
- var CORE_EVENT_BUS_TOKEN = "core.eventBus";
29
- var CORE_POLICY_GATE_TOKEN = "core.policyGate";
30
- var CORE_AUTH_TOKEN = "core.auth";
31
- var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
2
+ // ../../src/bootstrap/applicationRegistry.ts
3
+ import {
4
+ resolveApplicationAuth,
5
+ resolveApplicationCache,
6
+ resolveApplicationConfig,
7
+ resolveApplicationDependencies,
8
+ resolveApplicationEventBus,
9
+ resolveApplicationLogger,
10
+ resolveApplicationPolicyGate,
11
+ resolveApplicationQueue,
12
+ setActiveApplicationContext
13
+ } from "@getstrata/core/runtime/applicationRegistry.ts";
32
14
 
33
- // ../../src/core/logging/logger.ts
34
- class Logger {
35
- channel;
36
- constructor(channel = "app") {
37
- this.channel = channel;
38
- }
39
- write(level, message, context = {}) {
40
- const entry = {
41
- level,
42
- channel: this.channel,
43
- message,
44
- timestamp: new Date().toISOString(),
45
- ...context
46
- };
47
- const line = JSON.stringify(entry);
48
- if (level === "error") {
49
- console.error(line);
50
- return;
51
- }
52
- console.log(line);
53
- }
54
- debug(message, context) {
55
- this.write("debug", message, context);
56
- }
57
- info(message, context) {
58
- this.write("info", message, context);
59
- }
60
- warn(message, context) {
61
- this.write("warn", message, context);
62
- }
63
- error(message, context) {
64
- this.write("error", message, context);
65
- }
66
- }
67
- var appLogger = new Logger("app");
15
+ // ../../src/bootstrap/contracts.ts
16
+ import {
17
+ ConfigStore,
18
+ ServiceContainer
19
+ } from "@getstrata/core/contracts/container";
20
+ import {
21
+ assertAppDependenciesComplete,
22
+ getRequiredDependency,
23
+ resolveService
24
+ } from "@getstrata/core/contracts/di";
68
25
 
69
- // ../../src/core/runtime/applicationRegistry.ts
70
- var APPLICATION_CONTEXT_KEY = Symbol.for("@getstrata/applicationContext");
71
- var activeContext;
72
- function readStoredApplicationContext() {
73
- if (activeContext) {
74
- return activeContext;
75
- }
76
- const globalContext = globalThis[APPLICATION_CONTEXT_KEY];
77
- if (globalContext) {
78
- activeContext = globalContext;
79
- }
80
- return activeContext;
81
- }
82
- function setActiveApplicationContext(context) {
83
- activeContext = context;
84
- globalThis[APPLICATION_CONTEXT_KEY] = context;
85
- }
86
- function requireActiveApplicationContext() {
87
- const context = readStoredApplicationContext();
88
- if (!context) {
89
- throw new Error("The application context has not been bootstrapped.");
26
+ // ../../src/bootstrap/discoverModules.ts
27
+ import { readdirSync } from "fs";
28
+ import { join } from "path";
29
+ import { pathToFileURL } from "url";
30
+ var DISCOVER_MODULES_STATE_KEY = Symbol.for("@getstrata/discoverModulesState");
31
+ function readDiscoverModulesState() {
32
+ const existing = globalThis[DISCOVER_MODULES_STATE_KEY];
33
+ if (existing) {
34
+ return existing;
90
35
  }
91
- return context;
92
- }
93
- function resolveApplicationCache() {
94
- return getRequiredDependency(requireActiveApplicationContext().dependencies, "cache");
95
- }
96
- function resolveApplicationQueue() {
97
- return requireActiveApplicationContext().container.resolve(CORE_QUEUE_TOKEN);
98
- }
99
- function resolveApplicationEventBus() {
100
- return requireActiveApplicationContext().container.resolve(CORE_EVENT_BUS_TOKEN);
101
- }
102
- function resolveApplicationAuth() {
103
- return requireActiveApplicationContext().container.resolve(CORE_AUTH_TOKEN);
104
- }
105
- function resolveApplicationPolicyGate() {
106
- return requireActiveApplicationContext().container.resolve(CORE_POLICY_GATE_TOKEN);
107
- }
108
- function resolveApplicationConfig() {
109
- return requireActiveApplicationContext().config;
36
+ const state = { appModules: [] };
37
+ globalThis[DISCOVER_MODULES_STATE_KEY] = state;
38
+ return state;
110
39
  }
111
- function resolveApplicationLogger() {
112
- return appLogger;
40
+ function configureModulesDirectory(modulesDir) {
41
+ readDiscoverModulesState().configuredModulesDir = modulesDir;
113
42
  }
114
- function resolveApplicationDependencies() {
115
- return requireActiveApplicationContext().dependencies;
116
- }
117
- // ../../src/core/contracts/container.ts
118
- class ServiceContainer {
119
- services = new Map;
120
- singletonFactories = new Map;
121
- bindings = new Map;
122
- set(key, value) {
123
- this.singletonFactories.delete(key);
124
- this.bindings.delete(key);
125
- this.services.set(key, value);
126
- return value;
127
- }
128
- singleton(key, factory) {
129
- this.bindings.delete(key);
130
- this.services.delete(key);
131
- this.singletonFactories.set(key, factory);
132
- }
133
- bind(key, factory) {
134
- this.singletonFactories.delete(key);
135
- this.services.delete(key);
136
- this.bindings.set(key, factory);
137
- }
138
- get(key) {
139
- if (this.services.has(key)) {
140
- return this.services.get(key);
141
- }
142
- const singletonFactory = this.singletonFactories.get(key);
143
- if (singletonFactory) {
144
- const value = singletonFactory(this);
145
- this.services.set(key, value);
146
- return value;
147
- }
148
- const binding = this.bindings.get(key);
149
- if (binding) {
150
- return binding(this);
151
- }
152
- throw new Error(`Service "${key}" is not registered.`);
43
+ function resolveModulesDirectory(options) {
44
+ const state = readDiscoverModulesState();
45
+ if (options?.modulesDir) {
46
+ return options.modulesDir;
153
47
  }
154
- resolve(key) {
155
- return this.get(key);
156
- }
157
- has(key) {
158
- return this.services.has(key) || this.singletonFactories.has(key) || this.bindings.has(key);
48
+ if (state.configuredModulesDir) {
49
+ return state.configuredModulesDir;
159
50
  }
51
+ return join(import.meta.dir, "../modules");
160
52
  }
161
-
162
- class ConfigStore {
163
- values = new Map;
164
- set(key, value) {
165
- this.values.set(key, value);
166
- return value;
167
- }
168
- get(key) {
169
- return this.values.get(key);
170
- }
171
- require(key) {
172
- if (!this.values.has(key)) {
173
- throw new Error(`Config key "${key}" is not defined.`);
53
+ async function loadDiscoveredModules(options) {
54
+ const modulesDirectory = resolveModulesDirectory(options);
55
+ let moduleNames;
56
+ try {
57
+ moduleNames = readdirSync(modulesDirectory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
58
+ } catch (error) {
59
+ if (error.code === "ENOENT") {
60
+ return [];
174
61
  }
175
- return this.values.get(key);
62
+ throw error;
176
63
  }
177
- has(key) {
178
- return this.values.has(key);
64
+ const modules = await Promise.all(moduleNames.map(async (moduleName) => {
65
+ const moduleUrl = pathToFileURL(join(modulesDirectory, moduleName, "index.ts")).href;
66
+ const loaded = await import(moduleUrl);
67
+ return loaded.default;
68
+ }));
69
+ return modules.filter((module) => module?.name !== undefined).sort((left, right) => (left.order ?? 100) - (right.order ?? 100));
70
+ }
71
+ async function ensureModulesLoaded(options) {
72
+ const state = readDiscoverModulesState();
73
+ if (state.appModules.length > 0) {
74
+ return state.appModules;
179
75
  }
76
+ state.modulesReady ??= loadDiscoveredModules(options).then((modules) => {
77
+ state.appModules.splice(0, state.appModules.length, ...modules);
78
+ return state.appModules;
79
+ });
80
+ return state.modulesReady;
180
81
  }
181
- // ../../src/bootstrap/discoverModules.ts
182
- var appModules = [];
183
82
  function discoverModules() {
184
- return appModules;
83
+ return readDiscoverModulesState().appModules;
185
84
  }
186
85
  // ../../src/config/auth.ts
187
86
  var authConfig = {
@@ -228,6 +127,15 @@ function resolveAbilitiesForRole(role) {
228
127
  }
229
128
 
230
129
  // ../../src/bootstrap/config.ts
130
+ import {
131
+ CORE_AUTH_TOKEN,
132
+ CORE_CACHE_TOKEN,
133
+ CORE_CONFIG_TOKEN,
134
+ CORE_EVENT_BUS_TOKEN,
135
+ CORE_POLICY_GATE_TOKEN,
136
+ CORE_QUEUE_TOKEN,
137
+ CORE_TOKEN_SERVICE_TOKEN
138
+ } from "@getstrata/core/contracts/serviceTokens.ts";
231
139
  var APP_PORT_CONFIG_KEY = "app.port";
232
140
  var CACHE_TTL_MS_CONFIG_KEY = "cache.ttlMs";
233
141
  var CACHE_MAX_ENTRIES_CONFIG_KEY = "cache.maxEntries";
@@ -1462,14 +1370,14 @@ var eventsProvider = {
1462
1370
  var events_default = eventsProvider;
1463
1371
 
1464
1372
  // ../../src/bootstrap/discoverListeners.ts
1465
- import { readdirSync } from "fs";
1466
- import { join } from "path";
1467
- import { pathToFileURL } from "url";
1373
+ import { readdirSync as readdirSync2 } from "fs";
1374
+ import { join as join2 } from "path";
1375
+ import { pathToFileURL as pathToFileURL2 } from "url";
1468
1376
  async function loadDiscoveredListeners() {
1469
- const listenersDirectory = join(import.meta.dir, "../listeners");
1377
+ const listenersDirectory = join2(import.meta.dir, "../listeners");
1470
1378
  let entries;
1471
1379
  try {
1472
- entries = readdirSync(listenersDirectory, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => entry.name);
1380
+ entries = readdirSync2(listenersDirectory, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => entry.name);
1473
1381
  } catch (error) {
1474
1382
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
1475
1383
  return [];
@@ -1477,7 +1385,7 @@ async function loadDiscoveredListeners() {
1477
1385
  throw error;
1478
1386
  }
1479
1387
  const listeners = await Promise.all(entries.map(async (fileName) => {
1480
- const moduleUrl = pathToFileURL(join(listenersDirectory, fileName)).href;
1388
+ const moduleUrl = pathToFileURL2(join2(listenersDirectory, fileName)).href;
1481
1389
  const loaded = await import(moduleUrl);
1482
1390
  return loaded.default;
1483
1391
  }));
@@ -1798,10 +1706,10 @@ function buildHavingClause(tableName, having, params) {
1798
1706
  return body.length > 0 ? ` HAVING ${body}` : "";
1799
1707
  }
1800
1708
  function buildJoinClause(joins = []) {
1801
- return joins.map((join2) => {
1802
- const joinType = join2.type === "left" ? "LEFT JOIN" : "INNER JOIN";
1803
- const onClause = join2.on.map(({ left, right }) => `${qualifyColumn(left.table, left.column)} = ${qualifyColumn(right.table, right.column)}`).join(" AND ");
1804
- return ` ${joinType} ${quoteIdentifier(join2.table)} ON ${onClause}`;
1709
+ return joins.map((join3) => {
1710
+ const joinType = join3.type === "left" ? "LEFT JOIN" : "INNER JOIN";
1711
+ const onClause = join3.on.map(({ left, right }) => `${qualifyColumn(left.table, left.column)} = ${qualifyColumn(right.table, right.column)}`).join(" AND ");
1712
+ return ` ${joinType} ${quoteIdentifier(join3.table)} ON ${onClause}`;
1805
1713
  }).join("");
1806
1714
  }
1807
1715
  function buildLimitClause(limit) {
@@ -2237,7 +2145,7 @@ class RepositoryQuery {
2237
2145
  const rightRef = parseQualifiedColumn(right);
2238
2146
  const table = type === "inner" ? rightRef.table : rightRef.table;
2239
2147
  const joins = this.queryOptions.joins ?? [];
2240
- const existing = joins.find((join2) => join2.table === table && join2.type === type);
2148
+ const existing = joins.find((join3) => join3.table === table && join3.type === type);
2241
2149
  if (existing) {
2242
2150
  existing.on.push({ left: leftRef, right: rightRef });
2243
2151
  return this;
@@ -3713,10 +3621,92 @@ class DispatchWebhookJob extends Job {
3713
3621
  }
3714
3622
  var dispatchWebhookJob_default = DispatchWebhookJob;
3715
3623
 
3624
+ // ../../src/core/contracts/di.ts
3625
+ function getRequiredDependency2(dependencies, key) {
3626
+ const dependency = dependencies[key];
3627
+ if (dependency === undefined) {
3628
+ throw new Error(`Required dependency "${key}" is not registered.`);
3629
+ }
3630
+ return dependency;
3631
+ }
3632
+
3633
+ // ../../src/core/contracts/serviceTokens.ts
3634
+ var CORE_POLICY_GATE_TOKEN2 = "core.policyGate";
3635
+ var CORE_AUTH_TOKEN2 = "core.auth";
3636
+
3637
+ // ../../src/core/logging/logger.ts
3638
+ class Logger {
3639
+ channel;
3640
+ constructor(channel = "app") {
3641
+ this.channel = channel;
3642
+ }
3643
+ write(level, message, context = {}) {
3644
+ const entry = {
3645
+ level,
3646
+ channel: this.channel,
3647
+ message,
3648
+ timestamp: new Date().toISOString(),
3649
+ ...context
3650
+ };
3651
+ const line = JSON.stringify(entry);
3652
+ if (level === "error") {
3653
+ console.error(line);
3654
+ return;
3655
+ }
3656
+ console.log(line);
3657
+ }
3658
+ debug(message, context) {
3659
+ this.write("debug", message, context);
3660
+ }
3661
+ info(message, context) {
3662
+ this.write("info", message, context);
3663
+ }
3664
+ warn(message, context) {
3665
+ this.write("warn", message, context);
3666
+ }
3667
+ error(message, context) {
3668
+ this.write("error", message, context);
3669
+ }
3670
+ }
3671
+ var appLogger = new Logger("app");
3672
+
3673
+ // ../../src/core/runtime/applicationRegistry.ts
3674
+ var APPLICATION_CONTEXT_KEY = Symbol.for("@getstrata/applicationContext");
3675
+ var activeContext;
3676
+ function readStoredApplicationContext() {
3677
+ if (activeContext) {
3678
+ return activeContext;
3679
+ }
3680
+ const globalContext = globalThis[APPLICATION_CONTEXT_KEY];
3681
+ if (globalContext) {
3682
+ activeContext = globalContext;
3683
+ }
3684
+ return activeContext;
3685
+ }
3686
+ function requireActiveApplicationContext() {
3687
+ const context = readStoredApplicationContext();
3688
+ if (!context) {
3689
+ throw new Error("The application context has not been bootstrapped.");
3690
+ }
3691
+ return context;
3692
+ }
3693
+ function resolveApplicationCache2() {
3694
+ return getRequiredDependency2(requireActiveApplicationContext().dependencies, "cache");
3695
+ }
3696
+ function resolveApplicationAuth2() {
3697
+ return requireActiveApplicationContext().container.resolve(CORE_AUTH_TOKEN2);
3698
+ }
3699
+ function resolveApplicationPolicyGate2() {
3700
+ return requireActiveApplicationContext().container.resolve(CORE_POLICY_GATE_TOKEN2);
3701
+ }
3702
+ function resolveApplicationDependencies2() {
3703
+ return requireActiveApplicationContext().dependencies;
3704
+ }
3705
+
3716
3706
  // ../../src/bootstrap/queue/defaultJobs.ts
3717
3707
  function registerDefaultJobs() {
3718
3708
  jobRegistry.register("cache.invalidate-tags", () => {
3719
- return new invalidateCacheTagsJob_default(resolveApplicationCache());
3709
+ return new invalidateCacheTagsJob_default(resolveApplicationCache2());
3720
3710
  });
3721
3711
  jobRegistry.register("webhook.dispatch", () => new dispatchWebhookJob_default);
3722
3712
  }
@@ -3737,7 +3727,7 @@ var queue_default = queueProvider;
3737
3727
 
3738
3728
  // ../../src/core/storage/storage.ts
3739
3729
  import { mkdir, readFile, unlink, writeFile } from "fs/promises";
3740
- import { dirname, join as join2 } from "path";
3730
+ import { dirname, join as join3 } from "path";
3741
3731
  var {S3Client } = globalThis.Bun;
3742
3732
 
3743
3733
  class LocalStorageDriver {
@@ -3749,7 +3739,7 @@ class LocalStorageDriver {
3749
3739
  return this.rootDirectory ?? process.env.STORAGE_PATH ?? "storage";
3750
3740
  }
3751
3741
  resolvePath(path) {
3752
- return join2(this.resolveRootDirectory(), path.replace(/^\/+/, ""));
3742
+ return join3(this.resolveRootDirectory(), path.replace(/^\/+/, ""));
3753
3743
  }
3754
3744
  async put(path, contents) {
3755
3745
  const absolutePath = this.resolvePath(path);
@@ -3882,9 +3872,9 @@ function currentRequestMeta() {
3882
3872
  }
3883
3873
 
3884
3874
  // ../../src/core/view/etaViewEngine.ts
3885
- import { join as join3 } from "path";
3875
+ import { join as join4 } from "path";
3886
3876
  import { Eta } from "eta";
3887
- var DEFAULT_VIEWS_DIRECTORY = join3(process.cwd(), "resources/views");
3877
+ var DEFAULT_VIEWS_DIRECTORY = join4(process.cwd(), "resources/views");
3888
3878
  var DEFAULT_LAYOUT = "layouts/app.eta";
3889
3879
 
3890
3880
  class EtaViewEngine {
@@ -4177,7 +4167,7 @@ function assertProductionSecrets(env = process.env) {
4177
4167
  }
4178
4168
 
4179
4169
  // ../../src/bootstrap/context.ts
4180
- function collectProviders(modules = appModules) {
4170
+ function collectProviders(modules = discoverModules()) {
4181
4171
  return [...coreProviders, ...modules.flatMap((module) => module.providers ?? [])];
4182
4172
  }
4183
4173
  function runProviderPhase(providers, phase, context) {
@@ -1,89 +1,14 @@
1
1
  // @bun
2
- // ../../src/core/contracts/container.ts
3
- class ServiceContainer {
4
- services = new Map;
5
- singletonFactories = new Map;
6
- bindings = new Map;
7
- set(key, value) {
8
- this.singletonFactories.delete(key);
9
- this.bindings.delete(key);
10
- this.services.set(key, value);
11
- return value;
12
- }
13
- singleton(key, factory) {
14
- this.bindings.delete(key);
15
- this.services.delete(key);
16
- this.singletonFactories.set(key, factory);
17
- }
18
- bind(key, factory) {
19
- this.singletonFactories.delete(key);
20
- this.services.delete(key);
21
- this.bindings.set(key, factory);
22
- }
23
- get(key) {
24
- if (this.services.has(key)) {
25
- return this.services.get(key);
26
- }
27
- const singletonFactory = this.singletonFactories.get(key);
28
- if (singletonFactory) {
29
- const value = singletonFactory(this);
30
- this.services.set(key, value);
31
- return value;
32
- }
33
- const binding = this.bindings.get(key);
34
- if (binding) {
35
- return binding(this);
36
- }
37
- throw new Error(`Service "${key}" is not registered.`);
38
- }
39
- resolve(key) {
40
- return this.get(key);
41
- }
42
- has(key) {
43
- return this.services.has(key) || this.singletonFactories.has(key) || this.bindings.has(key);
44
- }
45
- }
46
-
47
- class ConfigStore {
48
- values = new Map;
49
- set(key, value) {
50
- this.values.set(key, value);
51
- return value;
52
- }
53
- get(key) {
54
- return this.values.get(key);
55
- }
56
- require(key) {
57
- if (!this.values.has(key)) {
58
- throw new Error(`Config key "${key}" is not defined.`);
59
- }
60
- return this.values.get(key);
61
- }
62
- has(key) {
63
- return this.values.has(key);
64
- }
65
- }
66
- // ../../src/core/contracts/di.ts
67
- var requiredDependencyKeys = [
68
- "container",
69
- "cache",
70
- "storage"
71
- ];
72
- function getRequiredDependency(dependencies, key) {
73
- const dependency = dependencies[key];
74
- if (dependency === undefined) {
75
- throw new Error(`Required dependency "${key}" is not registered.`);
76
- }
77
- return dependency;
78
- }
79
- function assertAppDependenciesComplete(dependencies) {
80
- for (const key of requiredDependencyKeys) {
81
- getRequiredDependency(dependencies, key);
82
- }
83
- }
84
- function resolveService(dependencies, token) {
85
- return dependencies.container.resolve(token);
86
- }
2
+ // ../../src/bootstrap/contracts.ts
3
+ import {
4
+ ConfigStore,
5
+ ServiceContainer
6
+ } from "@getstrata/core/contracts/container";
7
+ import {
8
+ assertAppDependenciesComplete,
9
+ getRequiredDependency,
10
+ resolveService
11
+ } from "@getstrata/core/contracts/di";
87
12
  export {
88
13
  resolveService,
89
14
  getRequiredDependency,
@@ -1,6 +1,6 @@
1
1
  // @bun
2
2
  // ../../src/bootstrap/createWebRoutes.ts
3
- import { join as join2 } from "path";
3
+ import { join as join3 } from "path";
4
4
 
5
5
  // ../../src/config/frontend.ts
6
6
  function readFrontendMode() {
@@ -110,16 +110,16 @@ function htmlResponse(html, init = {}) {
110
110
  }
111
111
  });
112
112
  }
113
- // ../../src/core/contracts/serviceTokens.ts
114
- var CORE_CONFIG_TOKEN = "core.config";
115
- var CORE_CACHE_TOKEN = "core.cache";
116
- var CORE_QUEUE_TOKEN = "core.queue";
117
- var CORE_EVENT_BUS_TOKEN = "core.eventBus";
118
- var CORE_POLICY_GATE_TOKEN = "core.policyGate";
119
- var CORE_AUTH_TOKEN = "core.auth";
120
- var CORE_TOKEN_SERVICE_TOKEN = "core.tokenService";
121
-
122
113
  // ../../src/bootstrap/config.ts
114
+ import {
115
+ CORE_AUTH_TOKEN,
116
+ CORE_CACHE_TOKEN,
117
+ CORE_CONFIG_TOKEN,
118
+ CORE_EVENT_BUS_TOKEN,
119
+ CORE_POLICY_GATE_TOKEN,
120
+ CORE_QUEUE_TOKEN,
121
+ CORE_TOKEN_SERVICE_TOKEN
122
+ } from "@getstrata/core/contracts/serviceTokens.ts";
123
123
  var APP_PORT_CONFIG_KEY = "app.port";
124
124
  var CACHE_TTL_MS_CONFIG_KEY = "cache.ttlMs";
125
125
  var CACHE_MAX_ENTRIES_CONFIG_KEY = "cache.maxEntries";
@@ -908,9 +908,63 @@ function createHttpKernel(dependencies) {
908
908
  }
909
909
 
910
910
  // ../../src/bootstrap/discoverModules.ts
911
- var appModules = [];
911
+ import { readdirSync } from "fs";
912
+ import { join as join2 } from "path";
913
+ import { pathToFileURL } from "url";
914
+ var DISCOVER_MODULES_STATE_KEY = Symbol.for("@getstrata/discoverModulesState");
915
+ function readDiscoverModulesState() {
916
+ const existing = globalThis[DISCOVER_MODULES_STATE_KEY];
917
+ if (existing) {
918
+ return existing;
919
+ }
920
+ const state = { appModules: [] };
921
+ globalThis[DISCOVER_MODULES_STATE_KEY] = state;
922
+ return state;
923
+ }
924
+ function configureModulesDirectory(modulesDir) {
925
+ readDiscoverModulesState().configuredModulesDir = modulesDir;
926
+ }
927
+ function resolveModulesDirectory(options) {
928
+ const state = readDiscoverModulesState();
929
+ if (options?.modulesDir) {
930
+ return options.modulesDir;
931
+ }
932
+ if (state.configuredModulesDir) {
933
+ return state.configuredModulesDir;
934
+ }
935
+ return join2(import.meta.dir, "../modules");
936
+ }
937
+ async function loadDiscoveredModules(options) {
938
+ const modulesDirectory = resolveModulesDirectory(options);
939
+ let moduleNames;
940
+ try {
941
+ moduleNames = readdirSync(modulesDirectory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
942
+ } catch (error) {
943
+ if (error.code === "ENOENT") {
944
+ return [];
945
+ }
946
+ throw error;
947
+ }
948
+ const modules = await Promise.all(moduleNames.map(async (moduleName) => {
949
+ const moduleUrl = pathToFileURL(join2(modulesDirectory, moduleName, "index.ts")).href;
950
+ const loaded = await import(moduleUrl);
951
+ return loaded.default;
952
+ }));
953
+ return modules.filter((module) => module?.name !== undefined).sort((left, right) => (left.order ?? 100) - (right.order ?? 100));
954
+ }
955
+ async function ensureModulesLoaded(options) {
956
+ const state = readDiscoverModulesState();
957
+ if (state.appModules.length > 0) {
958
+ return state.appModules;
959
+ }
960
+ state.modulesReady ??= loadDiscoveredModules(options).then((modules) => {
961
+ state.appModules.splice(0, state.appModules.length, ...modules);
962
+ return state.appModules;
963
+ });
964
+ return state.modulesReady;
965
+ }
912
966
  function discoverModules() {
913
- return appModules;
967
+ return readDiscoverModulesState().appModules;
914
968
  }
915
969
  // ../../src/bootstrap/routeRegistry.ts
916
970
  class RouteRegistry {
@@ -964,7 +1018,7 @@ function createWebRoutes(dependencies) {
964
1018
  "/": () => Response.redirect("/organizations", 302)
965
1019
  };
966
1020
  registerRoute("GET", "/", ["global", "web"]);
967
- for (const module of appModules) {
1021
+ for (const module of discoverModules()) {
968
1022
  if (!module.webRoutes) {
969
1023
  continue;
970
1024
  }
@@ -979,7 +1033,7 @@ function createWebRoutes(dependencies) {
979
1033
  registerRoute("GET", "/assets/*", ["global", "web"]);
980
1034
  const pathname = new URL(request.url).pathname;
981
1035
  const relativePath = pathname.replace(/^\//, "");
982
- const file = Bun.file(join2(process.cwd(), "public", relativePath));
1036
+ const file = Bun.file(join3(process.cwd(), "public", relativePath));
983
1037
  if (!await file.exists()) {
984
1038
  return htmlResponse("Not Found", { status: 404 });
985
1039
  }