threadforge 0.1.0 → 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 (359) hide show
  1. package/README.md +52 -20
  2. package/bin/forge.js +2 -1049
  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 +160 -49
  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 +84 -22
  318. package/shared/identity.js +26 -0
  319. package/src/core/DirectMessageBus.js +0 -364
  320. package/src/core/EndpointResolver.js +0 -247
  321. package/src/core/ForgeContext.js +0 -2227
  322. package/src/core/ForgeHost.js +0 -122
  323. package/src/core/ForgePlatform.js +0 -145
  324. package/src/core/Ingress.js +0 -768
  325. package/src/core/Interceptors.js +0 -420
  326. package/src/core/MessageBus.js +0 -310
  327. package/src/core/Prometheus.js +0 -305
  328. package/src/core/RequestContext.js +0 -413
  329. package/src/core/RoutingStrategy.js +0 -316
  330. package/src/core/Supervisor.js +0 -1306
  331. package/src/core/ThreadAllocator.js +0 -196
  332. package/src/core/WorkerChannelManager.js +0 -879
  333. package/src/core/config.js +0 -624
  334. package/src/core/host-config.js +0 -311
  335. package/src/core/network-utils.js +0 -166
  336. package/src/core/platform-config.js +0 -308
  337. package/src/decorators/ServiceProxy.js +0 -899
  338. package/src/decorators/index.js +0 -571
  339. package/src/deploy/NginxGenerator.js +0 -865
  340. package/src/deploy/PlatformManifestGenerator.js +0 -96
  341. package/src/deploy/RouteManifestGenerator.js +0 -112
  342. package/src/deploy/index.js +0 -984
  343. package/src/frontend/FrontendDevLifecycle.js +0 -65
  344. package/src/frontend/FrontendPluginOrchestrator.js +0 -187
  345. package/src/frontend/SiteResolver.js +0 -63
  346. package/src/frontend/StaticMountRegistry.js +0 -90
  347. package/src/frontend/plugins/viteFrontend.js +0 -79
  348. package/src/frontend/types.js +0 -35
  349. package/src/index.js +0 -56
  350. package/src/plugins/PluginManager.js +0 -537
  351. package/src/plugins/ScopedPostgres.js +0 -192
  352. package/src/plugins/ScopedRedis.js +0 -142
  353. package/src/plugins/index.js +0 -1729
  354. package/src/registry/ServiceRegistry.js +0 -796
  355. package/src/scaling/ScaleAdvisor.js +0 -442
  356. package/src/services/Service.js +0 -195
  357. package/src/services/worker-bootstrap.js +0 -676
  358. package/src/templates/auth-service.js +0 -65
  359. 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"}