threadforge 0.1.1 → 0.2.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 (358) hide show
  1. package/README.md +52 -20
  2. package/bin/forge.js +2 -1058
  3. package/bin/host-commands.d.ts +2 -0
  4. package/bin/host-commands.d.ts.map +1 -0
  5. package/bin/host-commands.js +7 -8
  6. package/bin/platform-commands.d.ts +2 -0
  7. package/bin/platform-commands.d.ts.map +1 -0
  8. package/bin/platform-commands.js +118 -36
  9. package/dist/cli/base-command.d.ts +12 -0
  10. package/dist/cli/base-command.d.ts.map +1 -0
  11. package/dist/cli/base-command.js +25 -0
  12. package/dist/cli/base-command.js.map +1 -0
  13. package/dist/cli/commands/build.d.ts +10 -0
  14. package/dist/cli/commands/build.d.ts.map +1 -0
  15. package/dist/cli/commands/build.js +110 -0
  16. package/dist/cli/commands/build.js.map +1 -0
  17. package/dist/cli/commands/deploy.d.ts +12 -0
  18. package/dist/cli/commands/deploy.d.ts.map +1 -0
  19. package/dist/cli/commands/deploy.js +143 -0
  20. package/dist/cli/commands/deploy.js.map +1 -0
  21. package/dist/cli/commands/dev.d.ts +10 -0
  22. package/dist/cli/commands/dev.d.ts.map +1 -0
  23. package/dist/cli/commands/dev.js +138 -0
  24. package/dist/cli/commands/dev.js.map +1 -0
  25. package/dist/cli/commands/generate.d.ts +10 -0
  26. package/dist/cli/commands/generate.d.ts.map +1 -0
  27. package/dist/cli/commands/generate.js +76 -0
  28. package/dist/cli/commands/generate.js.map +1 -0
  29. package/dist/cli/commands/host.d.ts +8 -0
  30. package/dist/cli/commands/host.d.ts.map +1 -0
  31. package/dist/cli/commands/host.js +20 -0
  32. package/dist/cli/commands/host.js.map +1 -0
  33. package/dist/cli/commands/init.d.ts +16 -0
  34. package/dist/cli/commands/init.d.ts.map +1 -0
  35. package/dist/cli/commands/init.js +246 -0
  36. package/dist/cli/commands/init.js.map +1 -0
  37. package/dist/cli/commands/platform.d.ts +8 -0
  38. package/dist/cli/commands/platform.d.ts.map +1 -0
  39. package/dist/cli/commands/platform.js +20 -0
  40. package/dist/cli/commands/platform.js.map +1 -0
  41. package/dist/cli/commands/restart.d.ts +8 -0
  42. package/dist/cli/commands/restart.d.ts.map +1 -0
  43. package/dist/cli/commands/restart.js +13 -0
  44. package/dist/cli/commands/restart.js.map +1 -0
  45. package/dist/cli/commands/scaffold/frontend.d.ts +10 -0
  46. package/dist/cli/commands/scaffold/frontend.d.ts.map +1 -0
  47. package/dist/cli/commands/scaffold/frontend.js +130 -0
  48. package/dist/cli/commands/scaffold/frontend.js.map +1 -0
  49. package/dist/cli/commands/scaffold/react.d.ts +7 -0
  50. package/dist/cli/commands/scaffold/react.d.ts.map +1 -0
  51. package/dist/cli/commands/scaffold/react.js +12 -0
  52. package/dist/cli/commands/scaffold/react.js.map +1 -0
  53. package/dist/cli/commands/scale.d.ts +8 -0
  54. package/dist/cli/commands/scale.d.ts.map +1 -0
  55. package/dist/cli/commands/scale.js +13 -0
  56. package/dist/cli/commands/scale.js.map +1 -0
  57. package/dist/cli/commands/start.d.ts +10 -0
  58. package/dist/cli/commands/start.d.ts.map +1 -0
  59. package/dist/cli/commands/start.js +71 -0
  60. package/dist/cli/commands/start.js.map +1 -0
  61. package/dist/cli/commands/status.d.ts +11 -0
  62. package/dist/cli/commands/status.d.ts.map +1 -0
  63. package/dist/cli/commands/status.js +60 -0
  64. package/dist/cli/commands/status.js.map +1 -0
  65. package/dist/cli/commands/stop.d.ts +10 -0
  66. package/dist/cli/commands/stop.d.ts.map +1 -0
  67. package/dist/cli/commands/stop.js +89 -0
  68. package/dist/cli/commands/stop.js.map +1 -0
  69. package/dist/cli/util/config-discovery.d.ts +8 -0
  70. package/dist/cli/util/config-discovery.d.ts.map +1 -0
  71. package/dist/cli/util/config-discovery.js +70 -0
  72. package/dist/cli/util/config-discovery.js.map +1 -0
  73. package/dist/cli/util/config-patcher.d.ts +17 -0
  74. package/dist/cli/util/config-patcher.d.ts.map +1 -0
  75. package/dist/cli/util/config-patcher.js +439 -0
  76. package/dist/cli/util/config-patcher.js.map +1 -0
  77. package/dist/cli/util/frontend-dev.d.ts +8 -0
  78. package/dist/cli/util/frontend-dev.d.ts.map +1 -0
  79. package/dist/cli/util/frontend-dev.js +117 -0
  80. package/dist/cli/util/frontend-dev.js.map +1 -0
  81. package/dist/cli/util/process.d.ts +5 -0
  82. package/dist/cli/util/process.d.ts.map +1 -0
  83. package/dist/cli/util/process.js +17 -0
  84. package/dist/cli/util/process.js.map +1 -0
  85. package/dist/cli/util/templates.d.ts +10 -0
  86. package/dist/cli/util/templates.d.ts.map +1 -0
  87. package/dist/cli/util/templates.js +157 -0
  88. package/dist/cli/util/templates.js.map +1 -0
  89. package/dist/core/AlertSink.d.ts +83 -0
  90. package/dist/core/AlertSink.d.ts.map +1 -0
  91. package/dist/core/AlertSink.js +126 -0
  92. package/dist/core/AlertSink.js.map +1 -0
  93. package/dist/core/DirectMessageBus.d.ts +88 -0
  94. package/dist/core/DirectMessageBus.d.ts.map +1 -0
  95. package/dist/core/DirectMessageBus.js +352 -0
  96. package/dist/core/DirectMessageBus.js.map +1 -0
  97. package/dist/core/EndpointResolver.d.ts +111 -0
  98. package/dist/core/EndpointResolver.d.ts.map +1 -0
  99. package/dist/core/EndpointResolver.js +336 -0
  100. package/dist/core/EndpointResolver.js.map +1 -0
  101. package/dist/core/ForgeContext.d.ts +221 -0
  102. package/dist/core/ForgeContext.d.ts.map +1 -0
  103. package/dist/core/ForgeContext.js +1169 -0
  104. package/dist/core/ForgeContext.js.map +1 -0
  105. package/dist/core/ForgeEndpoints.d.ts +71 -0
  106. package/dist/core/ForgeEndpoints.d.ts.map +1 -0
  107. package/dist/core/ForgeEndpoints.js +442 -0
  108. package/dist/core/ForgeEndpoints.js.map +1 -0
  109. package/dist/core/ForgeHost.d.ts +82 -0
  110. package/dist/core/ForgeHost.d.ts.map +1 -0
  111. package/dist/core/ForgeHost.js +107 -0
  112. package/dist/core/ForgeHost.js.map +1 -0
  113. package/dist/core/ForgePlatform.d.ts +96 -0
  114. package/dist/core/ForgePlatform.d.ts.map +1 -0
  115. package/dist/core/ForgePlatform.js +136 -0
  116. package/dist/core/ForgePlatform.js.map +1 -0
  117. package/dist/core/ForgeWebSocket.d.ts +56 -0
  118. package/dist/core/ForgeWebSocket.d.ts.map +1 -0
  119. package/dist/core/ForgeWebSocket.js +415 -0
  120. package/dist/core/ForgeWebSocket.js.map +1 -0
  121. package/dist/core/Ingress.d.ts +329 -0
  122. package/dist/core/Ingress.d.ts.map +1 -0
  123. package/dist/core/Ingress.js +694 -0
  124. package/dist/core/Ingress.js.map +1 -0
  125. package/dist/core/Interceptors.d.ts +134 -0
  126. package/dist/core/Interceptors.d.ts.map +1 -0
  127. package/dist/core/Interceptors.js +416 -0
  128. package/dist/core/Interceptors.js.map +1 -0
  129. package/dist/core/Logger.d.ts +20 -0
  130. package/dist/core/Logger.d.ts.map +1 -0
  131. package/dist/core/Logger.js +77 -0
  132. package/dist/core/Logger.js.map +1 -0
  133. package/dist/core/MessageBus.d.ts +15 -0
  134. package/dist/core/MessageBus.d.ts.map +1 -0
  135. package/dist/core/MessageBus.js +18 -0
  136. package/dist/core/MessageBus.js.map +1 -0
  137. package/dist/core/Prometheus.d.ts +80 -0
  138. package/dist/core/Prometheus.d.ts.map +1 -0
  139. package/dist/core/Prometheus.js +332 -0
  140. package/dist/core/Prometheus.js.map +1 -0
  141. package/dist/core/RequestContext.d.ts +214 -0
  142. package/dist/core/RequestContext.d.ts.map +1 -0
  143. package/dist/core/RequestContext.js +556 -0
  144. package/dist/core/RequestContext.js.map +1 -0
  145. package/dist/core/Router.d.ts +45 -0
  146. package/dist/core/Router.d.ts.map +1 -0
  147. package/dist/core/Router.js +285 -0
  148. package/dist/core/Router.js.map +1 -0
  149. package/dist/core/RoutingStrategy.d.ts +116 -0
  150. package/dist/core/RoutingStrategy.d.ts.map +1 -0
  151. package/dist/core/RoutingStrategy.js +306 -0
  152. package/dist/core/RoutingStrategy.js.map +1 -0
  153. package/dist/core/RpcConfig.d.ts +72 -0
  154. package/dist/core/RpcConfig.d.ts.map +1 -0
  155. package/dist/core/RpcConfig.js +127 -0
  156. package/dist/core/RpcConfig.js.map +1 -0
  157. package/dist/core/SignatureCache.d.ts +81 -0
  158. package/dist/core/SignatureCache.d.ts.map +1 -0
  159. package/dist/core/SignatureCache.js +172 -0
  160. package/dist/core/SignatureCache.js.map +1 -0
  161. package/dist/core/StaticFileServer.d.ts +34 -0
  162. package/dist/core/StaticFileServer.d.ts.map +1 -0
  163. package/dist/core/StaticFileServer.js +497 -0
  164. package/dist/core/StaticFileServer.js.map +1 -0
  165. package/dist/core/Supervisor.d.ts +198 -0
  166. package/dist/core/Supervisor.d.ts.map +1 -0
  167. package/dist/core/Supervisor.js +1418 -0
  168. package/dist/core/Supervisor.js.map +1 -0
  169. package/dist/core/ThreadAllocator.d.ts +52 -0
  170. package/dist/core/ThreadAllocator.d.ts.map +1 -0
  171. package/dist/core/ThreadAllocator.js +174 -0
  172. package/dist/core/ThreadAllocator.js.map +1 -0
  173. package/dist/core/WorkerChannelManager.d.ts +130 -0
  174. package/dist/core/WorkerChannelManager.d.ts.map +1 -0
  175. package/dist/core/WorkerChannelManager.js +956 -0
  176. package/dist/core/WorkerChannelManager.js.map +1 -0
  177. package/dist/core/config-enums.d.ts +41 -0
  178. package/dist/core/config-enums.d.ts.map +1 -0
  179. package/dist/core/config-enums.js +59 -0
  180. package/dist/core/config-enums.js.map +1 -0
  181. package/dist/core/config.d.ts +159 -0
  182. package/dist/core/config.d.ts.map +1 -0
  183. package/dist/core/config.js +694 -0
  184. package/dist/core/config.js.map +1 -0
  185. package/dist/core/host-config.d.ts +146 -0
  186. package/dist/core/host-config.d.ts.map +1 -0
  187. package/dist/core/host-config.js +312 -0
  188. package/dist/core/host-config.js.map +1 -0
  189. package/dist/core/ipc-errors.d.ts +27 -0
  190. package/dist/core/ipc-errors.d.ts.map +1 -0
  191. package/dist/core/ipc-errors.js +36 -0
  192. package/dist/core/ipc-errors.js.map +1 -0
  193. package/dist/core/network-utils.d.ts +35 -0
  194. package/dist/core/network-utils.d.ts.map +1 -0
  195. package/dist/core/network-utils.js +145 -0
  196. package/dist/core/network-utils.js.map +1 -0
  197. package/dist/core/platform-config.d.ts +142 -0
  198. package/dist/core/platform-config.d.ts.map +1 -0
  199. package/dist/core/platform-config.js +299 -0
  200. package/dist/core/platform-config.js.map +1 -0
  201. package/dist/decorators/ServiceProxy.d.ts +175 -0
  202. package/dist/decorators/ServiceProxy.d.ts.map +1 -0
  203. package/dist/decorators/ServiceProxy.js +969 -0
  204. package/dist/decorators/ServiceProxy.js.map +1 -0
  205. package/dist/decorators/index.d.ts +146 -0
  206. package/dist/decorators/index.d.ts.map +1 -0
  207. package/dist/decorators/index.js +545 -0
  208. package/dist/decorators/index.js.map +1 -0
  209. package/dist/deploy/NginxGenerator.d.ts +165 -0
  210. package/dist/deploy/NginxGenerator.d.ts.map +1 -0
  211. package/dist/deploy/NginxGenerator.js +781 -0
  212. package/dist/deploy/NginxGenerator.js.map +1 -0
  213. package/dist/deploy/PlatformManifestGenerator.d.ts +43 -0
  214. package/dist/deploy/PlatformManifestGenerator.d.ts.map +1 -0
  215. package/dist/deploy/PlatformManifestGenerator.js +80 -0
  216. package/dist/deploy/PlatformManifestGenerator.js.map +1 -0
  217. package/dist/deploy/RouteManifestGenerator.d.ts +42 -0
  218. package/dist/deploy/RouteManifestGenerator.d.ts.map +1 -0
  219. package/dist/deploy/RouteManifestGenerator.js +105 -0
  220. package/dist/deploy/RouteManifestGenerator.js.map +1 -0
  221. package/dist/deploy/index.d.ts +210 -0
  222. package/dist/deploy/index.d.ts.map +1 -0
  223. package/dist/deploy/index.js +918 -0
  224. package/dist/deploy/index.js.map +1 -0
  225. package/dist/frontend/FrontendDevLifecycle.d.ts +26 -0
  226. package/dist/frontend/FrontendDevLifecycle.d.ts.map +1 -0
  227. package/dist/frontend/FrontendDevLifecycle.js +60 -0
  228. package/dist/frontend/FrontendDevLifecycle.js.map +1 -0
  229. package/dist/frontend/FrontendPluginOrchestrator.d.ts +64 -0
  230. package/dist/frontend/FrontendPluginOrchestrator.d.ts.map +1 -0
  231. package/dist/frontend/FrontendPluginOrchestrator.js +167 -0
  232. package/dist/frontend/FrontendPluginOrchestrator.js.map +1 -0
  233. package/dist/frontend/SiteResolver.d.ts +33 -0
  234. package/dist/frontend/SiteResolver.d.ts.map +1 -0
  235. package/dist/frontend/SiteResolver.js +53 -0
  236. package/dist/frontend/SiteResolver.js.map +1 -0
  237. package/dist/frontend/StaticMountRegistry.d.ts +36 -0
  238. package/dist/frontend/StaticMountRegistry.d.ts.map +1 -0
  239. package/dist/frontend/StaticMountRegistry.js +94 -0
  240. package/dist/frontend/StaticMountRegistry.js.map +1 -0
  241. package/dist/frontend/index.d.ts +7 -0
  242. package/dist/frontend/index.d.ts.map +1 -0
  243. package/{src → dist}/frontend/index.js +4 -2
  244. package/dist/frontend/index.js.map +1 -0
  245. package/dist/frontend/pathUtils.d.ts +8 -0
  246. package/dist/frontend/pathUtils.d.ts.map +1 -0
  247. package/dist/frontend/pathUtils.js +17 -0
  248. package/dist/frontend/pathUtils.js.map +1 -0
  249. package/dist/frontend/plugins/index.d.ts +2 -0
  250. package/dist/frontend/plugins/index.d.ts.map +1 -0
  251. package/{src → dist}/frontend/plugins/index.js +1 -1
  252. package/dist/frontend/plugins/index.js.map +1 -0
  253. package/dist/frontend/plugins/viteFrontend.d.ts +51 -0
  254. package/dist/frontend/plugins/viteFrontend.d.ts.map +1 -0
  255. package/dist/frontend/plugins/viteFrontend.js +134 -0
  256. package/dist/frontend/plugins/viteFrontend.js.map +1 -0
  257. package/dist/frontend/types.d.ts +25 -0
  258. package/dist/frontend/types.d.ts.map +1 -0
  259. package/dist/frontend/types.js +2 -0
  260. package/dist/frontend/types.js.map +1 -0
  261. package/dist/index.d.ts +17 -0
  262. package/dist/index.d.ts.map +1 -0
  263. package/dist/index.js +32 -0
  264. package/dist/index.js.map +1 -0
  265. package/dist/internals.d.ts +21 -0
  266. package/dist/internals.d.ts.map +1 -0
  267. package/{src → dist}/internals.js +12 -14
  268. package/dist/internals.js.map +1 -0
  269. package/dist/plugins/PluginManager.d.ts +209 -0
  270. package/dist/plugins/PluginManager.d.ts.map +1 -0
  271. package/dist/plugins/PluginManager.js +365 -0
  272. package/dist/plugins/PluginManager.js.map +1 -0
  273. package/dist/plugins/ScopedPostgres.d.ts +78 -0
  274. package/dist/plugins/ScopedPostgres.d.ts.map +1 -0
  275. package/dist/plugins/ScopedPostgres.js +190 -0
  276. package/dist/plugins/ScopedPostgres.js.map +1 -0
  277. package/dist/plugins/ScopedRedis.d.ts +88 -0
  278. package/dist/plugins/ScopedRedis.d.ts.map +1 -0
  279. package/dist/plugins/ScopedRedis.js +169 -0
  280. package/dist/plugins/ScopedRedis.js.map +1 -0
  281. package/dist/plugins/index.d.ts +289 -0
  282. package/dist/plugins/index.d.ts.map +1 -0
  283. package/dist/plugins/index.js +1942 -0
  284. package/dist/plugins/index.js.map +1 -0
  285. package/dist/plugins/types.d.ts +59 -0
  286. package/dist/plugins/types.d.ts.map +1 -0
  287. package/dist/plugins/types.js +2 -0
  288. package/dist/plugins/types.js.map +1 -0
  289. package/dist/registry/ServiceRegistry.d.ts +305 -0
  290. package/dist/registry/ServiceRegistry.d.ts.map +1 -0
  291. package/dist/registry/ServiceRegistry.js +735 -0
  292. package/dist/registry/ServiceRegistry.js.map +1 -0
  293. package/dist/scaling/ScaleAdvisor.d.ts +214 -0
  294. package/dist/scaling/ScaleAdvisor.d.ts.map +1 -0
  295. package/dist/scaling/ScaleAdvisor.js +526 -0
  296. package/dist/scaling/ScaleAdvisor.js.map +1 -0
  297. package/dist/services/Service.d.ts +164 -0
  298. package/dist/services/Service.d.ts.map +1 -0
  299. package/dist/services/Service.js +106 -0
  300. package/dist/services/Service.js.map +1 -0
  301. package/dist/services/worker-bootstrap.d.ts +15 -0
  302. package/dist/services/worker-bootstrap.d.ts.map +1 -0
  303. package/dist/services/worker-bootstrap.js +744 -0
  304. package/dist/services/worker-bootstrap.js.map +1 -0
  305. package/dist/templates/auth-service.d.ts +42 -0
  306. package/dist/templates/auth-service.d.ts.map +1 -0
  307. package/dist/templates/auth-service.js +54 -0
  308. package/dist/templates/auth-service.js.map +1 -0
  309. package/dist/templates/identity-service.d.ts +50 -0
  310. package/dist/templates/identity-service.d.ts.map +1 -0
  311. package/dist/templates/identity-service.js +62 -0
  312. package/dist/templates/identity-service.js.map +1 -0
  313. package/dist/types/contract.d.ts +120 -0
  314. package/dist/types/contract.d.ts.map +1 -0
  315. package/dist/types/contract.js +69 -0
  316. package/dist/types/contract.js.map +1 -0
  317. package/package.json +78 -20
  318. package/src/core/DirectMessageBus.js +0 -364
  319. package/src/core/EndpointResolver.js +0 -259
  320. package/src/core/ForgeContext.js +0 -2236
  321. package/src/core/ForgeHost.js +0 -122
  322. package/src/core/ForgePlatform.js +0 -145
  323. package/src/core/Ingress.js +0 -768
  324. package/src/core/Interceptors.js +0 -420
  325. package/src/core/MessageBus.js +0 -321
  326. package/src/core/Prometheus.js +0 -305
  327. package/src/core/RequestContext.js +0 -413
  328. package/src/core/RoutingStrategy.js +0 -330
  329. package/src/core/Supervisor.js +0 -1349
  330. package/src/core/ThreadAllocator.js +0 -196
  331. package/src/core/WorkerChannelManager.js +0 -879
  332. package/src/core/config.js +0 -637
  333. package/src/core/host-config.js +0 -311
  334. package/src/core/network-utils.js +0 -166
  335. package/src/core/platform-config.js +0 -308
  336. package/src/decorators/ServiceProxy.js +0 -904
  337. package/src/decorators/index.js +0 -571
  338. package/src/deploy/NginxGenerator.js +0 -865
  339. package/src/deploy/PlatformManifestGenerator.js +0 -96
  340. package/src/deploy/RouteManifestGenerator.js +0 -112
  341. package/src/deploy/index.js +0 -984
  342. package/src/frontend/FrontendDevLifecycle.js +0 -65
  343. package/src/frontend/FrontendPluginOrchestrator.js +0 -187
  344. package/src/frontend/SiteResolver.js +0 -63
  345. package/src/frontend/StaticMountRegistry.js +0 -90
  346. package/src/frontend/plugins/viteFrontend.js +0 -79
  347. package/src/frontend/types.js +0 -35
  348. package/src/index.js +0 -58
  349. package/src/plugins/PluginManager.js +0 -537
  350. package/src/plugins/ScopedPostgres.js +0 -192
  351. package/src/plugins/ScopedRedis.js +0 -142
  352. package/src/plugins/index.js +0 -1756
  353. package/src/registry/ServiceRegistry.js +0 -797
  354. package/src/scaling/ScaleAdvisor.js +0 -442
  355. package/src/services/Service.js +0 -195
  356. package/src/services/worker-bootstrap.js +0 -679
  357. package/src/templates/auth-service.js +0 -65
  358. package/src/templates/identity-service.js +0 -75
@@ -0,0 +1,172 @@
1
+ /**
2
+ * SignatureCache - Rotating HMAC signature cache for internal RPC optimization
3
+ *
4
+ * P-PERF-29: Reduce per-request HMAC computation cost by caching signatures with
5
+ * periodic rotation. Maintains replay protection guarantees while reducing CPU overhead.
6
+ *
7
+ * Security Model:
8
+ * - Signatures rotate every 5 seconds (configurable)
9
+ * - Multiple signatures active during overlap window for clock drift tolerance
10
+ * - Replay protection window: 30 seconds (INTERNAL_SIG_MAX_AGE_MS)
11
+ * - Rotation interval (5s) << replay window (30s) = safe
12
+ *
13
+ * Performance:
14
+ * - Reduces HMAC computations by ~5s/rotation_interval ratio
15
+ * - At 1000 RPS: 5000 HMAC ops/rotation vs 1 per rotation = ~5000x reduction
16
+ * - Memory overhead: ~200 bytes per cached signature entry
17
+ */
18
+ import { createHmac } from "node:crypto";
19
+ const MIN_SECRET_LENGTH = 32;
20
+ /**
21
+ * SignatureCache maintains a rotating set of precomputed HMAC signatures
22
+ * for internal RPC authentication. Reduces per-request CPU cost while
23
+ * preserving replay protection guarantees.
24
+ */
25
+ export class SignatureCache {
26
+ secret;
27
+ rotationIntervalMs;
28
+ enabled;
29
+ // Current and previous signatures for overlap tolerance, keyed by method:path
30
+ currentSignatures = new Map();
31
+ previousSignatures = new Map();
32
+ // Current rotation timestamp (shared across all keys)
33
+ currentTimestamp = null;
34
+ previousTimestamp = null;
35
+ // Timer for automatic rotation
36
+ rotationTimer = null;
37
+ constructor(secret, config = {}) {
38
+ this.secret = secret;
39
+ this.rotationIntervalMs = config.rotationIntervalMs ?? 5000; // 5 seconds default
40
+ this.enabled = config.enabled ?? false; // Opt-in for safety
41
+ // SEC-L2: Warn on short FORGE_INTERNAL_SECRET
42
+ if (secret.length < MIN_SECRET_LENGTH) {
43
+ process.stderr.write(`${JSON.stringify({
44
+ timestamp: new Date().toISOString(),
45
+ level: "warn",
46
+ message: `FORGE_INTERNAL_SECRET is shorter than ${MIN_SECRET_LENGTH} characters — this is insecure. Use a longer secret in production.`,
47
+ })}\n`);
48
+ }
49
+ if (this.rotationIntervalMs < 1000) {
50
+ throw new Error("rotationIntervalMs must be at least 1000ms");
51
+ }
52
+ // Validate rotation interval doesn't exceed replay window
53
+ // INTERNAL_SIG_MAX_AGE_MS is 30000ms - rotation should be significantly smaller
54
+ const REPLAY_WINDOW_MS = 30000;
55
+ if (this.rotationIntervalMs >= REPLAY_WINDOW_MS / 2) {
56
+ throw new Error(`rotationIntervalMs (${this.rotationIntervalMs}ms) must be less than half the replay window (${REPLAY_WINDOW_MS}ms)`);
57
+ }
58
+ if (this.enabled) {
59
+ this._initializeCache();
60
+ this._startRotation();
61
+ }
62
+ }
63
+ /**
64
+ * Get a signature for the given method and path.
65
+ * If caching is disabled, computes a fresh signature each time.
66
+ * If caching is enabled, returns the current cached signature.
67
+ */
68
+ getSignature(method, path) {
69
+ if (!this.enabled) {
70
+ // Fallback to per-request computation (original behavior)
71
+ const ts = Date.now();
72
+ const sig = createHmac("sha256", this.secret).update(`${method}:${path}:${ts}`).digest("hex");
73
+ return { signature: sig, timestamp: String(ts) };
74
+ }
75
+ if (this.currentTimestamp === null) {
76
+ // Shouldn't happen if properly initialized, but handle gracefully
77
+ return this._computeFreshSignature(method, path);
78
+ }
79
+ const key = `${method}:${path}`;
80
+ let entry = this.currentSignatures.get(key);
81
+ if (!entry) {
82
+ // Lazily compute and cache for this method:path at the current rotation timestamp
83
+ const signature = createHmac("sha256", this.secret)
84
+ .update(`${method}:${path}:${this.currentTimestamp}`)
85
+ .digest("hex");
86
+ entry = { signature, timestamp: this.currentTimestamp };
87
+ this.currentSignatures.set(key, entry);
88
+ }
89
+ return {
90
+ signature: entry.signature,
91
+ timestamp: String(entry.timestamp),
92
+ };
93
+ }
94
+ /**
95
+ * Check if caching is enabled
96
+ */
97
+ isEnabled() {
98
+ return this.enabled;
99
+ }
100
+ /**
101
+ * Get cache statistics for monitoring
102
+ */
103
+ getStats() {
104
+ return {
105
+ enabled: this.enabled,
106
+ rotationIntervalMs: this.rotationIntervalMs,
107
+ currentTimestamp: this.currentTimestamp,
108
+ previousTimestamp: this.previousTimestamp,
109
+ };
110
+ }
111
+ /**
112
+ * Stop the rotation timer (for cleanup)
113
+ */
114
+ stop() {
115
+ if (this.rotationTimer) {
116
+ clearInterval(this.rotationTimer);
117
+ this.rotationTimer = null;
118
+ }
119
+ }
120
+ /**
121
+ * Force an immediate rotation (useful for testing)
122
+ */
123
+ rotate() {
124
+ this._rotateSignature();
125
+ }
126
+ // ─── Private Methods ────────────────────────────────────────
127
+ _initializeCache() {
128
+ // Generate initial signature
129
+ this._rotateSignature();
130
+ }
131
+ _startRotation() {
132
+ // Set up periodic rotation
133
+ this.rotationTimer = setInterval(() => {
134
+ this._rotateSignature();
135
+ }, this.rotationIntervalMs);
136
+ // Don't keep process alive for rotation timer
137
+ this.rotationTimer.unref?.();
138
+ }
139
+ _rotateSignature() {
140
+ // Move current to previous
141
+ this.previousSignatures = this.currentSignatures;
142
+ this.previousTimestamp = this.currentTimestamp;
143
+ // Start new rotation with fresh map and timestamp
144
+ // Signatures are lazily computed per method:path on first access
145
+ const now = Date.now();
146
+ this.currentTimestamp = now;
147
+ this.currentSignatures = new Map();
148
+ }
149
+ _computeFreshSignature(method, path) {
150
+ const ts = Date.now();
151
+ const sig = createHmac("sha256", this.secret).update(`${method}:${path}:${ts}`).digest("hex");
152
+ return { signature: sig, timestamp: String(ts) };
153
+ }
154
+ }
155
+ /**
156
+ * Create a signature cache instance from environment configuration
157
+ */
158
+ export function createSignatureCacheFromEnv() {
159
+ const secret = process.env.FORGE_INTERNAL_SECRET;
160
+ if (!secret) {
161
+ return null;
162
+ }
163
+ const enableCache = process.env.FORGE_CACHE_SIGNATURES === "true";
164
+ const rotationMs = process.env.FORGE_SIGNATURE_ROTATION_MS
165
+ ? parseInt(process.env.FORGE_SIGNATURE_ROTATION_MS, 10)
166
+ : 5000;
167
+ return new SignatureCache(secret, {
168
+ enabled: enableCache,
169
+ rotationIntervalMs: rotationMs,
170
+ });
171
+ }
172
+ //# sourceMappingURL=SignatureCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignatureCache.js","sourceRoot":"","sources":["../../src/core/SignatureCache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ import type { ResolvedStaticMount } from "../frontend/StaticMountRegistry.js";
3
+ import type { StaticMountRegistry } from "../frontend/StaticMountRegistry.js";
4
+ export interface StaticMount extends ResolvedStaticMount {
5
+ spaExclude?: string[];
6
+ }
7
+ interface LoggerLike {
8
+ warn: (message: string, meta?: Record<string, unknown>) => void;
9
+ error: (message: string, meta?: Record<string, unknown>) => void;
10
+ }
11
+ interface MetricsLike {
12
+ httpRequestEnd: (durationSeconds: number, labels: Record<string, string | number>) => void;
13
+ }
14
+ interface StaticFileServerOptions {
15
+ staticRegistry: StaticMountRegistry;
16
+ logger: LoggerLike;
17
+ metrics: MetricsLike;
18
+ }
19
+ export declare class StaticFileServer {
20
+ private readonly _staticRegistry;
21
+ private readonly _logger;
22
+ private readonly _metrics;
23
+ constructor(options: StaticFileServerOptions);
24
+ resolveMountForRequest(req: IncomingMessage, pathname: string): ResolvedStaticMount | null;
25
+ tryServeStatic(req: IncomingMessage, res: ServerResponse, start: number): Promise<boolean>;
26
+ private _proxyStaticToDevServer;
27
+ private _resolveStaticFile;
28
+ private _resolveExistingStaticFile;
29
+ private _isWithinRoot;
30
+ private _parseRange;
31
+ private _staticCacheControl;
32
+ }
33
+ export {};
34
+ //# sourceMappingURL=StaticFileServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StaticFileServer.d.ts","sourceRoot":"","sources":["../../src/core/StaticFileServer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAIjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAiB9E,MAAM,WAAW,WAAY,SAAQ,mBAAmB;IACtD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAChE,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CAClE;AAED,UAAU,WAAW;IACnB,cAAc,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;CAC5F;AAED,UAAU,uBAAuB;IAC/B,cAAc,EAAE,mBAAmB,CAAC;IACpC,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,WAAW,CAAC;CACtB;AA0ED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAsB;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAc;gBAE3B,OAAO,EAAE,uBAAuB;IAM5C,sBAAsB,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI;IAMpF,cAAc,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAiPlF,uBAAuB;IAuFrC,OAAO,CAAC,kBAAkB;YAmBZ,0BAA0B;YAmB1B,aAAa;IAU3B,OAAO,CAAC,WAAW;IAyBnB,OAAO,CAAC,mBAAmB;CAoB5B"}