enpilink 1.0.2

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 (477) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +289 -0
  3. package/bin/run.js +5 -0
  4. package/dist/cli/build-helpers.d.ts +8 -0
  5. package/dist/cli/build-helpers.js +105 -0
  6. package/dist/cli/build-helpers.js.map +1 -0
  7. package/dist/cli/build-helpers.test.d.ts +1 -0
  8. package/dist/cli/build-helpers.test.js +100 -0
  9. package/dist/cli/build-helpers.test.js.map +1 -0
  10. package/dist/cli/detect-port.d.ts +18 -0
  11. package/dist/cli/detect-port.js +50 -0
  12. package/dist/cli/detect-port.js.map +1 -0
  13. package/dist/cli/ensure-ssh-key.d.ts +17 -0
  14. package/dist/cli/ensure-ssh-key.js +45 -0
  15. package/dist/cli/ensure-ssh-key.js.map +1 -0
  16. package/dist/cli/ensure-ssh-key.test.d.ts +1 -0
  17. package/dist/cli/ensure-ssh-key.test.js +68 -0
  18. package/dist/cli/ensure-ssh-key.test.js.map +1 -0
  19. package/dist/cli/header.d.ts +4 -0
  20. package/dist/cli/header.js +6 -0
  21. package/dist/cli/header.js.map +1 -0
  22. package/dist/cli/resolve-views-dir.d.ts +1 -0
  23. package/dist/cli/resolve-views-dir.js +17 -0
  24. package/dist/cli/resolve-views-dir.js.map +1 -0
  25. package/dist/cli/run-command.d.ts +2 -0
  26. package/dist/cli/run-command.js +43 -0
  27. package/dist/cli/run-command.js.map +1 -0
  28. package/dist/cli/telemetry.d.ts +14 -0
  29. package/dist/cli/telemetry.js +24 -0
  30. package/dist/cli/telemetry.js.map +1 -0
  31. package/dist/cli/tunnel-control-server.d.ts +11 -0
  32. package/dist/cli/tunnel-control-server.js +35 -0
  33. package/dist/cli/tunnel-control-server.js.map +1 -0
  34. package/dist/cli/tunnel-control-server.test.d.ts +1 -0
  35. package/dist/cli/tunnel-control-server.test.js +39 -0
  36. package/dist/cli/tunnel-control-server.test.js.map +1 -0
  37. package/dist/cli/tunnel-handler.d.ts +3 -0
  38. package/dist/cli/tunnel-handler.js +48 -0
  39. package/dist/cli/tunnel-handler.js.map +1 -0
  40. package/dist/cli/tunnel-handler.test.d.ts +1 -0
  41. package/dist/cli/tunnel-handler.test.js +107 -0
  42. package/dist/cli/tunnel-handler.test.js.map +1 -0
  43. package/dist/cli/tunnel-providers/index.d.ts +5 -0
  44. package/dist/cli/tunnel-providers/index.js +5 -0
  45. package/dist/cli/tunnel-providers/index.js.map +1 -0
  46. package/dist/cli/tunnel-providers/srv-us.d.ts +18 -0
  47. package/dist/cli/tunnel-providers/srv-us.js +66 -0
  48. package/dist/cli/tunnel-providers/srv-us.js.map +1 -0
  49. package/dist/cli/tunnel-providers/srv-us.test.d.ts +1 -0
  50. package/dist/cli/tunnel-providers/srv-us.test.js +74 -0
  51. package/dist/cli/tunnel-providers/srv-us.test.js.map +1 -0
  52. package/dist/cli/tunnel-providers/types.d.ts +49 -0
  53. package/dist/cli/tunnel-providers/types.js +2 -0
  54. package/dist/cli/tunnel-providers/types.js.map +1 -0
  55. package/dist/cli/tunnel.d.ts +75 -0
  56. package/dist/cli/tunnel.js +254 -0
  57. package/dist/cli/tunnel.js.map +1 -0
  58. package/dist/cli/tunnel.test.d.ts +1 -0
  59. package/dist/cli/tunnel.test.js +255 -0
  60. package/dist/cli/tunnel.test.js.map +1 -0
  61. package/dist/cli/types.d.ts +5 -0
  62. package/dist/cli/types.js +2 -0
  63. package/dist/cli/types.js.map +1 -0
  64. package/dist/cli/use-execute-steps.d.ts +11 -0
  65. package/dist/cli/use-execute-steps.js +36 -0
  66. package/dist/cli/use-execute-steps.js.map +1 -0
  67. package/dist/cli/use-messages.d.ts +3 -0
  68. package/dist/cli/use-messages.js +11 -0
  69. package/dist/cli/use-messages.js.map +1 -0
  70. package/dist/cli/use-nodemon.d.ts +2 -0
  71. package/dist/cli/use-nodemon.js +73 -0
  72. package/dist/cli/use-nodemon.js.map +1 -0
  73. package/dist/cli/use-open-browser.d.ts +1 -0
  74. package/dist/cli/use-open-browser.js +44 -0
  75. package/dist/cli/use-open-browser.js.map +1 -0
  76. package/dist/cli/use-open-tunnel-browser.d.ts +6 -0
  77. package/dist/cli/use-open-tunnel-browser.js +19 -0
  78. package/dist/cli/use-open-tunnel-browser.js.map +1 -0
  79. package/dist/cli/use-tunnel.d.ts +17 -0
  80. package/dist/cli/use-tunnel.js +131 -0
  81. package/dist/cli/use-tunnel.js.map +1 -0
  82. package/dist/cli/use-typescript-check.d.ts +9 -0
  83. package/dist/cli/use-typescript-check.js +94 -0
  84. package/dist/cli/use-typescript-check.js.map +1 -0
  85. package/dist/commands/build.d.ts +8 -0
  86. package/dist/commands/build.js +97 -0
  87. package/dist/commands/build.js.map +1 -0
  88. package/dist/commands/create.d.ts +9 -0
  89. package/dist/commands/create.js +30 -0
  90. package/dist/commands/create.js.map +1 -0
  91. package/dist/commands/dev.d.ts +13 -0
  92. package/dist/commands/dev.js +112 -0
  93. package/dist/commands/dev.js.map +1 -0
  94. package/dist/commands/start.d.ts +10 -0
  95. package/dist/commands/start.js +76 -0
  96. package/dist/commands/start.js.map +1 -0
  97. package/dist/commands/telemetry/disable.d.ts +5 -0
  98. package/dist/commands/telemetry/disable.js +12 -0
  99. package/dist/commands/telemetry/disable.js.map +1 -0
  100. package/dist/commands/telemetry/enable.d.ts +5 -0
  101. package/dist/commands/telemetry/enable.js +12 -0
  102. package/dist/commands/telemetry/enable.js.map +1 -0
  103. package/dist/commands/telemetry/status.d.ts +5 -0
  104. package/dist/commands/telemetry/status.js +12 -0
  105. package/dist/commands/telemetry/status.js.map +1 -0
  106. package/dist/server/admin.d.ts +79 -0
  107. package/dist/server/admin.js +239 -0
  108. package/dist/server/admin.js.map +1 -0
  109. package/dist/server/admin.test.d.ts +1 -0
  110. package/dist/server/admin.test.js +226 -0
  111. package/dist/server/admin.test.js.map +1 -0
  112. package/dist/server/analytics.d.ts +60 -0
  113. package/dist/server/analytics.js +168 -0
  114. package/dist/server/analytics.js.map +1 -0
  115. package/dist/server/analytics.test.d.ts +1 -0
  116. package/dist/server/analytics.test.js +179 -0
  117. package/dist/server/analytics.test.js.map +1 -0
  118. package/dist/server/asset-base-url-transform-plugin.d.ts +11 -0
  119. package/dist/server/asset-base-url-transform-plugin.js +48 -0
  120. package/dist/server/asset-base-url-transform-plugin.js.map +1 -0
  121. package/dist/server/asset-base-url-transform-plugin.test.d.ts +1 -0
  122. package/dist/server/asset-base-url-transform-plugin.test.js +134 -0
  123. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -0
  124. package/dist/server/auth.d.ts +20 -0
  125. package/dist/server/auth.js +28 -0
  126. package/dist/server/auth.js.map +1 -0
  127. package/dist/server/build-manifest.test.d.ts +1 -0
  128. package/dist/server/build-manifest.test.js +27 -0
  129. package/dist/server/build-manifest.test.js.map +1 -0
  130. package/dist/server/config/config.test.d.ts +1 -0
  131. package/dist/server/config/config.test.js +214 -0
  132. package/dist/server/config/config.test.js.map +1 -0
  133. package/dist/server/config/index.d.ts +3 -0
  134. package/dist/server/config/index.js +4 -0
  135. package/dist/server/config/index.js.map +1 -0
  136. package/dist/server/config/resolve.d.ts +73 -0
  137. package/dist/server/config/resolve.js +167 -0
  138. package/dist/server/config/resolve.js.map +1 -0
  139. package/dist/server/config/router.d.ts +23 -0
  140. package/dist/server/config/router.js +119 -0
  141. package/dist/server/config/router.js.map +1 -0
  142. package/dist/server/config/schema.d.ts +78 -0
  143. package/dist/server/config/schema.js +158 -0
  144. package/dist/server/config/schema.js.map +1 -0
  145. package/dist/server/content-helpers.d.ts +67 -0
  146. package/dist/server/content-helpers.js +79 -0
  147. package/dist/server/content-helpers.js.map +1 -0
  148. package/dist/server/content-helpers.test.d.ts +1 -0
  149. package/dist/server/content-helpers.test.js +70 -0
  150. package/dist/server/content-helpers.test.js.map +1 -0
  151. package/dist/server/express.d.ts +11 -0
  152. package/dist/server/express.js +129 -0
  153. package/dist/server/express.js.map +1 -0
  154. package/dist/server/express.test.d.ts +1 -0
  155. package/dist/server/express.test.js +464 -0
  156. package/dist/server/express.test.js.map +1 -0
  157. package/dist/server/file-ref.d.ts +28 -0
  158. package/dist/server/file-ref.js +27 -0
  159. package/dist/server/file-ref.js.map +1 -0
  160. package/dist/server/index.d.ts +17 -0
  161. package/dist/server/index.js +14 -0
  162. package/dist/server/index.js.map +1 -0
  163. package/dist/server/inferUtilityTypes.d.ts +64 -0
  164. package/dist/server/inferUtilityTypes.js +2 -0
  165. package/dist/server/inferUtilityTypes.js.map +1 -0
  166. package/dist/server/log-sink.d.ts +16 -0
  167. package/dist/server/log-sink.js +66 -0
  168. package/dist/server/log-sink.js.map +1 -0
  169. package/dist/server/metric.d.ts +12 -0
  170. package/dist/server/metric.js +13 -0
  171. package/dist/server/metric.js.map +1 -0
  172. package/dist/server/middleware.d.ts +137 -0
  173. package/dist/server/middleware.js +93 -0
  174. package/dist/server/middleware.js.map +1 -0
  175. package/dist/server/middleware.test-d.d.ts +1 -0
  176. package/dist/server/middleware.test-d.js +75 -0
  177. package/dist/server/middleware.test-d.js.map +1 -0
  178. package/dist/server/middleware.test.d.ts +1 -0
  179. package/dist/server/middleware.test.js +493 -0
  180. package/dist/server/middleware.test.js.map +1 -0
  181. package/dist/server/mock-seed.d.ts +62 -0
  182. package/dist/server/mock-seed.js +251 -0
  183. package/dist/server/mock-seed.js.map +1 -0
  184. package/dist/server/mock-seed.test.d.ts +1 -0
  185. package/dist/server/mock-seed.test.js +122 -0
  186. package/dist/server/mock-seed.test.js.map +1 -0
  187. package/dist/server/observability.d.ts +149 -0
  188. package/dist/server/observability.js +340 -0
  189. package/dist/server/observability.js.map +1 -0
  190. package/dist/server/observability.test.d.ts +1 -0
  191. package/dist/server/observability.test.js +251 -0
  192. package/dist/server/observability.test.js.map +1 -0
  193. package/dist/server/otel.d.ts +45 -0
  194. package/dist/server/otel.js +117 -0
  195. package/dist/server/otel.js.map +1 -0
  196. package/dist/server/otel.test.d.ts +1 -0
  197. package/dist/server/otel.test.js +122 -0
  198. package/dist/server/otel.test.js.map +1 -0
  199. package/dist/server/server.d.ts +422 -0
  200. package/dist/server/server.js +684 -0
  201. package/dist/server/server.js.map +1 -0
  202. package/dist/server/storage/index.d.ts +23 -0
  203. package/dist/server/storage/index.js +46 -0
  204. package/dist/server/storage/index.js.map +1 -0
  205. package/dist/server/storage/memory.d.ts +30 -0
  206. package/dist/server/storage/memory.js +98 -0
  207. package/dist/server/storage/memory.js.map +1 -0
  208. package/dist/server/storage/memory.test.d.ts +1 -0
  209. package/dist/server/storage/memory.test.js +81 -0
  210. package/dist/server/storage/memory.test.js.map +1 -0
  211. package/dist/server/storage/postgres.d.ts +65 -0
  212. package/dist/server/storage/postgres.js +242 -0
  213. package/dist/server/storage/postgres.js.map +1 -0
  214. package/dist/server/storage/postgres.test.d.ts +1 -0
  215. package/dist/server/storage/postgres.test.js +182 -0
  216. package/dist/server/storage/postgres.test.js.map +1 -0
  217. package/dist/server/storage/sqlite.d.ts +33 -0
  218. package/dist/server/storage/sqlite.js +250 -0
  219. package/dist/server/storage/sqlite.js.map +1 -0
  220. package/dist/server/storage/sqlite.test.d.ts +1 -0
  221. package/dist/server/storage/sqlite.test.js +133 -0
  222. package/dist/server/storage/sqlite.test.js.map +1 -0
  223. package/dist/server/storage/types.d.ts +119 -0
  224. package/dist/server/storage/types.js +11 -0
  225. package/dist/server/storage/types.js.map +1 -0
  226. package/dist/server/templateHelper.d.ts +16 -0
  227. package/dist/server/templateHelper.js +11 -0
  228. package/dist/server/templateHelper.js.map +1 -0
  229. package/dist/server/templates.generated.d.ts +4 -0
  230. package/dist/server/templates.generated.js +47 -0
  231. package/dist/server/templates.generated.js.map +1 -0
  232. package/dist/server/tunnel-proxy-router.d.ts +7 -0
  233. package/dist/server/tunnel-proxy-router.js +110 -0
  234. package/dist/server/tunnel-proxy-router.js.map +1 -0
  235. package/dist/server/tunnel-proxy-router.test.d.ts +1 -0
  236. package/dist/server/tunnel-proxy-router.test.js +229 -0
  237. package/dist/server/tunnel-proxy-router.test.js.map +1 -0
  238. package/dist/server/viewsDevServer.d.ts +14 -0
  239. package/dist/server/viewsDevServer.js +45 -0
  240. package/dist/server/viewsDevServer.js.map +1 -0
  241. package/dist/test/utils.d.ts +127 -0
  242. package/dist/test/utils.js +247 -0
  243. package/dist/test/utils.js.map +1 -0
  244. package/dist/test/view.test.d.ts +1 -0
  245. package/dist/test/view.test.js +568 -0
  246. package/dist/test/view.test.js.map +1 -0
  247. package/dist/version.d.ts +1 -0
  248. package/dist/version.js +3 -0
  249. package/dist/version.js.map +1 -0
  250. package/dist/web/bridges/apps-sdk/adaptor.d.ts +54 -0
  251. package/dist/web/bridges/apps-sdk/adaptor.js +164 -0
  252. package/dist/web/bridges/apps-sdk/adaptor.js.map +1 -0
  253. package/dist/web/bridges/apps-sdk/bridge.d.ts +11 -0
  254. package/dist/web/bridges/apps-sdk/bridge.js +47 -0
  255. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -0
  256. package/dist/web/bridges/apps-sdk/index.d.ts +5 -0
  257. package/dist/web/bridges/apps-sdk/index.js +5 -0
  258. package/dist/web/bridges/apps-sdk/index.js.map +1 -0
  259. package/dist/web/bridges/apps-sdk/types.d.ts +147 -0
  260. package/dist/web/bridges/apps-sdk/types.js +10 -0
  261. package/dist/web/bridges/apps-sdk/types.js.map +1 -0
  262. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +13 -0
  263. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +18 -0
  264. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -0
  265. package/dist/web/bridges/get-adaptor.d.ts +9 -0
  266. package/dist/web/bridges/get-adaptor.js +15 -0
  267. package/dist/web/bridges/get-adaptor.js.map +1 -0
  268. package/dist/web/bridges/index.d.ts +5 -0
  269. package/dist/web/bridges/index.js +6 -0
  270. package/dist/web/bridges/index.js.map +1 -0
  271. package/dist/web/bridges/mcp-app/adaptor.d.ts +81 -0
  272. package/dist/web/bridges/mcp-app/adaptor.js +346 -0
  273. package/dist/web/bridges/mcp-app/adaptor.js.map +1 -0
  274. package/dist/web/bridges/mcp-app/bridge.d.ts +28 -0
  275. package/dist/web/bridges/mcp-app/bridge.js +124 -0
  276. package/dist/web/bridges/mcp-app/bridge.js.map +1 -0
  277. package/dist/web/bridges/mcp-app/index.d.ts +4 -0
  278. package/dist/web/bridges/mcp-app/index.js +4 -0
  279. package/dist/web/bridges/mcp-app/index.js.map +1 -0
  280. package/dist/web/bridges/mcp-app/types.d.ts +8 -0
  281. package/dist/web/bridges/mcp-app/types.js +2 -0
  282. package/dist/web/bridges/mcp-app/types.js.map +1 -0
  283. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +19 -0
  284. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +19 -0
  285. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -0
  286. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.d.ts +1 -0
  287. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +26 -0
  288. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -0
  289. package/dist/web/bridges/mcp-app/view-tools.test.d.ts +1 -0
  290. package/dist/web/bridges/mcp-app/view-tools.test.js +144 -0
  291. package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -0
  292. package/dist/web/bridges/types.d.ts +243 -0
  293. package/dist/web/bridges/types.js +2 -0
  294. package/dist/web/bridges/types.js.map +1 -0
  295. package/dist/web/bridges/use-host-context.d.ts +7 -0
  296. package/dist/web/bridges/use-host-context.js +13 -0
  297. package/dist/web/bridges/use-host-context.js.map +1 -0
  298. package/dist/web/components/modal-provider.d.ts +4 -0
  299. package/dist/web/components/modal-provider.js +45 -0
  300. package/dist/web/components/modal-provider.js.map +1 -0
  301. package/dist/web/create-store.d.ts +29 -0
  302. package/dist/web/create-store.js +64 -0
  303. package/dist/web/create-store.js.map +1 -0
  304. package/dist/web/create-store.test.d.ts +1 -0
  305. package/dist/web/create-store.test.js +129 -0
  306. package/dist/web/create-store.test.js.map +1 -0
  307. package/dist/web/data-llm.d.ts +47 -0
  308. package/dist/web/data-llm.js +100 -0
  309. package/dist/web/data-llm.js.map +1 -0
  310. package/dist/web/data-llm.test.d.ts +1 -0
  311. package/dist/web/data-llm.test.js +142 -0
  312. package/dist/web/data-llm.test.js.map +1 -0
  313. package/dist/web/generate-helpers.d.ts +120 -0
  314. package/dist/web/generate-helpers.js +115 -0
  315. package/dist/web/generate-helpers.js.map +1 -0
  316. package/dist/web/generate-helpers.test-d.d.ts +1 -0
  317. package/dist/web/generate-helpers.test-d.js +211 -0
  318. package/dist/web/generate-helpers.test-d.js.map +1 -0
  319. package/dist/web/generate-helpers.test.d.ts +1 -0
  320. package/dist/web/generate-helpers.test.js +17 -0
  321. package/dist/web/generate-helpers.test.js.map +1 -0
  322. package/dist/web/helpers/state.d.ts +7 -0
  323. package/dist/web/helpers/state.js +45 -0
  324. package/dist/web/helpers/state.js.map +1 -0
  325. package/dist/web/helpers/state.test.d.ts +1 -0
  326. package/dist/web/helpers/state.test.js +53 -0
  327. package/dist/web/helpers/state.test.js.map +1 -0
  328. package/dist/web/hooks/index.d.ts +17 -0
  329. package/dist/web/hooks/index.js +18 -0
  330. package/dist/web/hooks/index.js.map +1 -0
  331. package/dist/web/hooks/test/utils.d.ts +20 -0
  332. package/dist/web/hooks/test/utils.js +75 -0
  333. package/dist/web/hooks/test/utils.js.map +1 -0
  334. package/dist/web/hooks/use-call-tool.d.ts +146 -0
  335. package/dist/web/hooks/use-call-tool.js +96 -0
  336. package/dist/web/hooks/use-call-tool.js.map +1 -0
  337. package/dist/web/hooks/use-call-tool.test-d.d.ts +1 -0
  338. package/dist/web/hooks/use-call-tool.test-d.js +104 -0
  339. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -0
  340. package/dist/web/hooks/use-call-tool.test.d.ts +1 -0
  341. package/dist/web/hooks/use-call-tool.test.js +211 -0
  342. package/dist/web/hooks/use-call-tool.test.js.map +1 -0
  343. package/dist/web/hooks/use-display-mode.d.ts +24 -0
  344. package/dist/web/hooks/use-display-mode.js +29 -0
  345. package/dist/web/hooks/use-display-mode.js.map +1 -0
  346. package/dist/web/hooks/use-display-mode.test-d.d.ts +1 -0
  347. package/dist/web/hooks/use-display-mode.test-d.js +8 -0
  348. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -0
  349. package/dist/web/hooks/use-display-mode.test.d.ts +1 -0
  350. package/dist/web/hooks/use-display-mode.test.js +41 -0
  351. package/dist/web/hooks/use-display-mode.test.js.map +1 -0
  352. package/dist/web/hooks/use-download.d.ts +5 -0
  353. package/dist/web/hooks/use-download.js +8 -0
  354. package/dist/web/hooks/use-download.js.map +1 -0
  355. package/dist/web/hooks/use-download.test.d.ts +1 -0
  356. package/dist/web/hooks/use-download.test.js +95 -0
  357. package/dist/web/hooks/use-download.test.js.map +1 -0
  358. package/dist/web/hooks/use-files.d.ts +39 -0
  359. package/dist/web/hooks/use-files.js +42 -0
  360. package/dist/web/hooks/use-files.js.map +1 -0
  361. package/dist/web/hooks/use-files.test.d.ts +1 -0
  362. package/dist/web/hooks/use-files.test.js +54 -0
  363. package/dist/web/hooks/use-files.test.js.map +1 -0
  364. package/dist/web/hooks/use-intent.d.ts +30 -0
  365. package/dist/web/hooks/use-intent.js +34 -0
  366. package/dist/web/hooks/use-intent.js.map +1 -0
  367. package/dist/web/hooks/use-intent.test.d.ts +1 -0
  368. package/dist/web/hooks/use-intent.test.js +85 -0
  369. package/dist/web/hooks/use-intent.test.js.map +1 -0
  370. package/dist/web/hooks/use-layout.d.ts +24 -0
  371. package/dist/web/hooks/use-layout.js +25 -0
  372. package/dist/web/hooks/use-layout.js.map +1 -0
  373. package/dist/web/hooks/use-layout.test.d.ts +1 -0
  374. package/dist/web/hooks/use-layout.test.js +96 -0
  375. package/dist/web/hooks/use-layout.test.js.map +1 -0
  376. package/dist/web/hooks/use-notify.d.ts +29 -0
  377. package/dist/web/hooks/use-notify.js +33 -0
  378. package/dist/web/hooks/use-notify.js.map +1 -0
  379. package/dist/web/hooks/use-notify.test.d.ts +1 -0
  380. package/dist/web/hooks/use-notify.test.js +105 -0
  381. package/dist/web/hooks/use-notify.test.js.map +1 -0
  382. package/dist/web/hooks/use-open-external.d.ts +20 -0
  383. package/dist/web/hooks/use-open-external.js +24 -0
  384. package/dist/web/hooks/use-open-external.js.map +1 -0
  385. package/dist/web/hooks/use-open-external.test.d.ts +1 -0
  386. package/dist/web/hooks/use-open-external.test.js +65 -0
  387. package/dist/web/hooks/use-open-external.test.js.map +1 -0
  388. package/dist/web/hooks/use-register-view-tool.d.ts +38 -0
  389. package/dist/web/hooks/use-register-view-tool.js +50 -0
  390. package/dist/web/hooks/use-register-view-tool.js.map +1 -0
  391. package/dist/web/hooks/use-request-close.d.ts +16 -0
  392. package/dist/web/hooks/use-request-close.js +21 -0
  393. package/dist/web/hooks/use-request-close.js.map +1 -0
  394. package/dist/web/hooks/use-request-close.test.d.ts +1 -0
  395. package/dist/web/hooks/use-request-close.test.js +52 -0
  396. package/dist/web/hooks/use-request-close.test.js.map +1 -0
  397. package/dist/web/hooks/use-request-modal.d.ts +24 -0
  398. package/dist/web/hooks/use-request-modal.js +31 -0
  399. package/dist/web/hooks/use-request-modal.js.map +1 -0
  400. package/dist/web/hooks/use-request-modal.test.d.ts +1 -0
  401. package/dist/web/hooks/use-request-modal.test.js +61 -0
  402. package/dist/web/hooks/use-request-modal.test.js.map +1 -0
  403. package/dist/web/hooks/use-request-size.d.ts +20 -0
  404. package/dist/web/hooks/use-request-size.js +24 -0
  405. package/dist/web/hooks/use-request-size.js.map +1 -0
  406. package/dist/web/hooks/use-request-size.test.d.ts +1 -0
  407. package/dist/web/hooks/use-request-size.test.js +65 -0
  408. package/dist/web/hooks/use-request-size.test.js.map +1 -0
  409. package/dist/web/hooks/use-send-follow-up-message.d.ts +19 -0
  410. package/dist/web/hooks/use-send-follow-up-message.js +25 -0
  411. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -0
  412. package/dist/web/hooks/use-set-open-in-app-url.d.ts +18 -0
  413. package/dist/web/hooks/use-set-open-in-app-url.js +25 -0
  414. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -0
  415. package/dist/web/hooks/use-set-open-in-app-url.test.d.ts +1 -0
  416. package/dist/web/hooks/use-set-open-in-app-url.test.js +43 -0
  417. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -0
  418. package/dist/web/hooks/use-tool-info.d.ts +87 -0
  419. package/dist/web/hooks/use-tool-info.js +49 -0
  420. package/dist/web/hooks/use-tool-info.js.map +1 -0
  421. package/dist/web/hooks/use-tool-info.test-d.d.ts +1 -0
  422. package/dist/web/hooks/use-tool-info.test-d.js +91 -0
  423. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -0
  424. package/dist/web/hooks/use-tool-info.test.d.ts +1 -0
  425. package/dist/web/hooks/use-tool-info.test.js +130 -0
  426. package/dist/web/hooks/use-tool-info.test.js.map +1 -0
  427. package/dist/web/hooks/use-user.d.ts +20 -0
  428. package/dist/web/hooks/use-user.js +37 -0
  429. package/dist/web/hooks/use-user.js.map +1 -0
  430. package/dist/web/hooks/use-user.test.d.ts +1 -0
  431. package/dist/web/hooks/use-user.test.js +122 -0
  432. package/dist/web/hooks/use-user.test.js.map +1 -0
  433. package/dist/web/hooks/use-view-state.d.ts +25 -0
  434. package/dist/web/hooks/use-view-state.js +32 -0
  435. package/dist/web/hooks/use-view-state.js.map +1 -0
  436. package/dist/web/hooks/use-view-state.test.d.ts +1 -0
  437. package/dist/web/hooks/use-view-state.test.js +177 -0
  438. package/dist/web/hooks/use-view-state.test.js.map +1 -0
  439. package/dist/web/index.d.ts +7 -0
  440. package/dist/web/index.js +8 -0
  441. package/dist/web/index.js.map +1 -0
  442. package/dist/web/mount-view.d.ts +20 -0
  443. package/dist/web/mount-view.js +46 -0
  444. package/dist/web/mount-view.js.map +1 -0
  445. package/dist/web/plugin/data-llm.test.d.ts +1 -0
  446. package/dist/web/plugin/data-llm.test.js +81 -0
  447. package/dist/web/plugin/data-llm.test.js.map +1 -0
  448. package/dist/web/plugin/plugin.d.ts +33 -0
  449. package/dist/web/plugin/plugin.js +189 -0
  450. package/dist/web/plugin/plugin.js.map +1 -0
  451. package/dist/web/plugin/scan-views.d.ts +16 -0
  452. package/dist/web/plugin/scan-views.js +88 -0
  453. package/dist/web/plugin/scan-views.js.map +1 -0
  454. package/dist/web/plugin/scan-views.test.d.ts +1 -0
  455. package/dist/web/plugin/scan-views.test.js +99 -0
  456. package/dist/web/plugin/scan-views.test.js.map +1 -0
  457. package/dist/web/plugin/transform-data-llm.d.ts +12 -0
  458. package/dist/web/plugin/transform-data-llm.js +96 -0
  459. package/dist/web/plugin/transform-data-llm.js.map +1 -0
  460. package/dist/web/plugin/transform-data-llm.test.d.ts +1 -0
  461. package/dist/web/plugin/transform-data-llm.test.js +81 -0
  462. package/dist/web/plugin/transform-data-llm.test.js.map +1 -0
  463. package/dist/web/plugin/validate-view.d.ts +1 -0
  464. package/dist/web/plugin/validate-view.js +9 -0
  465. package/dist/web/plugin/validate-view.js.map +1 -0
  466. package/dist/web/plugin/validate-view.test.d.ts +1 -0
  467. package/dist/web/plugin/validate-view.test.js +24 -0
  468. package/dist/web/plugin/validate-view.test.js.map +1 -0
  469. package/dist/web/proxy.d.ts +1 -0
  470. package/dist/web/proxy.js +52 -0
  471. package/dist/web/proxy.js.map +1 -0
  472. package/dist/web/types.d.ts +20 -0
  473. package/dist/web/types.js +2 -0
  474. package/dist/web/types.js.map +1 -0
  475. package/package.json +125 -0
  476. package/scripts/postinstall.mjs +45 -0
  477. package/tsconfig.base.json +36 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-base-url-transform-plugin.test.js","sourceRoot":"","sources":["../../src/server/asset-base-url-transform-plugin.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport {\n assetBaseUrlTransform,\n assetBaseUrlTransformPlugin,\n isCssRequest,\n} from \"./asset-base-url-transform-plugin.js\";\n\ndescribe(\"assetBaseUrlTransform\", () => {\n it(\"should transform asset paths to use window.enpilink.serverUrl\", () => {\n const cases = [\n {\n desc: \"single-quoted\",\n code: `const image = '/assets/logo.png';`,\n expected: `const image = (window.enpilink?.serverUrl ?? \"\") + \"/assets/logo.png\";`,\n },\n {\n desc: \"double-quoted\",\n code: `const image = \"/assets/logo.png\";`,\n expected: `const image = (window.enpilink?.serverUrl ?? \"\") + \"/assets/logo.png\";`,\n },\n {\n desc: \"backtick-quoted\",\n code: \"const image = `/assets/logo.png`;\",\n expected: `const image = (window.enpilink?.serverUrl ?? \"\") + \"/assets/logo.png\";`,\n },\n ];\n\n for (const { code, expected } of cases) {\n const result = assetBaseUrlTransform(code);\n expect(result).toBe(expected);\n }\n });\n\n it(\"should transform multiple asset paths\", () => {\n const code = `\n const logo = '/assets/logo.png';\n const icon = '/assets/icon.svg';\n const font = '/assets/font.woff2';\n `;\n const result = assetBaseUrlTransform(code);\n\n expect(result).toContain(\n `(window.enpilink?.serverUrl ?? \"\") + \"/assets/logo.png\"`,\n );\n expect(result).toContain(\n `(window.enpilink?.serverUrl ?? \"\") + \"/assets/icon.svg\"`,\n );\n expect(result).toContain(\n `(window.enpilink?.serverUrl ?? \"\") + \"/assets/font.woff2\"`,\n );\n });\n\n it(\"should not transform already absolute URLs\", () => {\n const code = `\n const local = '/assets/logo.png';\n const http = 'http://example.com/image.png';\n const https = 'https://example.com/image.png';\n `;\n const result = assetBaseUrlTransform(code);\n\n expect(result).toContain(\n `(window.enpilink?.serverUrl ?? \"\") + \"/assets/logo.png\"`,\n );\n expect(result).toContain(\"http://example.com/image.png\");\n expect(result).toContain(\"https://example.com/image.png\");\n });\n\n it(\"should not transform code without asset paths\", () => {\n const code = `const text = \"Hello World\";`;\n const result = assetBaseUrlTransform(code);\n\n expect(result).toBe(code);\n });\n\n it(\"should not transform asset paths inside static `import ... from` clauses\", () => {\n // Reproducer for #713: a dep does `import * as sprite from './icons.svg'`,\n // Vite resolves the relative path to absolute, then this transform used\n // to rewrite the resolved string — producing invalid JS like\n // `import * as sprite from (expr) + \"...\"` that crashes vite:import-analysis.\n const cases = [\n `import * as sprite from \"/Users/me/proj/node_modules/pkg/icons.svg\";`,\n `import sprite from '/assets/icons.svg';`,\n `import sprite from \"/assets/icons.svg\";`,\n `export { default } from \"/assets/icons.svg\";`,\n `export * from '/assets/sprites.svg';`,\n ];\n\n for (const code of cases) {\n expect(assetBaseUrlTransform(code)).toBe(code);\n }\n });\n\n it(\"should still transform value-position asset paths in files that also have unrelated imports\", () => {\n const code = [\n `import { foo } from \"./foo.js\";`,\n `import * as sprite from \"/assets/sprite.svg\";`,\n `const logo = \"/assets/logo.png\";`,\n ].join(\"\\n\");\n const result = assetBaseUrlTransform(code);\n\n // Imports untouched\n expect(result).toContain(`from \"./foo.js\"`);\n expect(result).toContain(`from \"/assets/sprite.svg\"`);\n // Value-position rewritten\n expect(result).toContain(\n `const logo = (window.enpilink?.serverUrl ?? \"\") + \"/assets/logo.png\";`,\n );\n });\n});\n\ndescribe(\"isCssRequest\", () => {\n it(\"returns true for CSS-family extensions\", () => {\n expect(isCssRequest(\"/src/styles.css\")).toBe(true);\n expect(isCssRequest(\"/src/styles.module.css\")).toBe(true);\n expect(isCssRequest(\"/src/styles.scss\")).toBe(true);\n expect(isCssRequest(\"/src/styles.sass\")).toBe(true);\n expect(isCssRequest(\"/src/styles.less\")).toBe(true);\n expect(isCssRequest(\"/src/styles.styl\")).toBe(true);\n });\n\n it(\"returns true for CSS modules with Vite query strings\", () => {\n expect(isCssRequest(\"/src/styles.css?direct\")).toBe(true);\n expect(isCssRequest(\"/src/styles.css?inline\")).toBe(true);\n expect(isCssRequest(\"/src/styles.css?used\")).toBe(true);\n expect(isCssRequest(\"/src/Foo.vue?vue&type=style&lang.css\")).toBe(true);\n });\n\n it(\"returns false for non-CSS modules\", () => {\n expect(isCssRequest(\"/src/index.tsx\")).toBe(false);\n expect(isCssRequest(\"/src/utils.ts\")).toBe(false);\n expect(isCssRequest(\"/src/Logo.svg\")).toBe(false);\n expect(isCssRequest(\"/src/notes.cssx\")).toBe(false);\n });\n});\n\ndescribe(\"assetBaseUrlTransformPlugin\", () => {\n type TransformResult = { code: string; map: null } | null;\n\n function runTransform(id: string, code: string): TransformResult {\n const plugin = assetBaseUrlTransformPlugin();\n const hook = plugin.transform;\n if (!hook) {\n throw new Error(\"plugin.transform is not defined\");\n }\n const handler = typeof hook === \"function\" ? hook : hook.handler;\n return handler.call(\n // biome-ignore lint/suspicious/noExplicitAny: vitest harness for plugin hook\n {} as any,\n code,\n id,\n { moduleType: \"js\" },\n ) as TransformResult;\n }\n\n it(\"rewrites asset paths in JS modules\", () => {\n const result = runTransform(\n \"/src/widget.tsx\",\n `const logo = \"/assets/logo.png\";`,\n );\n expect(result?.code).toContain(\n `(window.enpilink?.serverUrl ?? \"\") + \"/assets/logo.png\"`,\n );\n });\n\n // Reproducer for #697: CSS imports are served as JS modules with the\n // stylesheet embedded as a string. Rewriting url(\"/foo.woff2\") inside that\n // string would produce invalid CSS once the styles are injected.\n it(\"does not rewrite asset paths when transforming a CSS module\", () => {\n const cssCode = `__vite__updateStyle(\"style-id\", \"@font-face { src: url(\\\\\"/fonts/Brand.woff2\\\\\") format(\\\\\"woff2\\\\\"); }\");`;\n\n expect(runTransform(\"/src/fonts.css\", cssCode)).toBeNull();\n expect(runTransform(\"/src/fonts.css?direct\", cssCode)).toBeNull();\n expect(runTransform(\"/src/fonts.css?inline\", cssCode)).toBeNull();\n expect(runTransform(\"/src/styles.scss\", cssCode)).toBeNull();\n expect(\n runTransform(\"/src/Foo.vue?vue&type=style&lang.css\", cssCode),\n ).toBeNull();\n });\n});\n"]}
@@ -0,0 +1,20 @@
1
+ import { type BearerAuthMiddlewareOptions } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js";
2
+ import type { RequestHandler } from "express";
3
+ export { InvalidTokenError } from "@modelcontextprotocol/sdk/server/auth/errors.js";
4
+ export { type BearerAuthMiddlewareOptions, requireBearerAuth, } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js";
5
+ export { type AuthMetadataOptions, mcpAuthMetadataRouter, } from "@modelcontextprotocol/sdk/server/auth/router.js";
6
+ export type { AuthInfo } from "@modelcontextprotocol/sdk/server/auth/types.js";
7
+ /**
8
+ * Like `requireBearerAuth`, but lets requests through when no
9
+ * `Authorization` header is present. Used for mixed-auth servers where some
10
+ * tools are public and others require sign-in: each tool enforces its own
11
+ * `securitySchemes` against `extra.authInfo`.
12
+ *
13
+ * Behavior:
14
+ * - No `Authorization` header → `next()` without `req.auth`.
15
+ * - Valid Bearer token → `req.auth` set, same as `requireBearerAuth`.
16
+ * - Invalid / malformed / expired / insufficient-scope → same error response
17
+ * as `requireBearerAuth` (401/403). Sending a bad token is still a client
18
+ * error.
19
+ */
20
+ export declare function optionalBearerAuth(options: BearerAuthMiddlewareOptions): RequestHandler;
@@ -0,0 +1,28 @@
1
+ import { requireBearerAuth, } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js";
2
+ export { InvalidTokenError } from "@modelcontextprotocol/sdk/server/auth/errors.js";
3
+ export { requireBearerAuth, } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js";
4
+ export { mcpAuthMetadataRouter, } from "@modelcontextprotocol/sdk/server/auth/router.js";
5
+ /**
6
+ * Like `requireBearerAuth`, but lets requests through when no
7
+ * `Authorization` header is present. Used for mixed-auth servers where some
8
+ * tools are public and others require sign-in: each tool enforces its own
9
+ * `securitySchemes` against `extra.authInfo`.
10
+ *
11
+ * Behavior:
12
+ * - No `Authorization` header → `next()` without `req.auth`.
13
+ * - Valid Bearer token → `req.auth` set, same as `requireBearerAuth`.
14
+ * - Invalid / malformed / expired / insufficient-scope → same error response
15
+ * as `requireBearerAuth` (401/403). Sending a bad token is still a client
16
+ * error.
17
+ */
18
+ export function optionalBearerAuth(options) {
19
+ const required = requireBearerAuth(options);
20
+ return (req, res, next) => {
21
+ if (!req.headers.authorization) {
22
+ next();
23
+ return;
24
+ }
25
+ return required(req, res, next);
26
+ };
27
+ }
28
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/server/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,iBAAiB,GAClB,MAAM,gEAAgE,CAAC;AAIxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iDAAiD,CAAC;AACpF,OAAO,EAEL,iBAAiB,GAClB,MAAM,gEAAgE,CAAC;AACxE,OAAO,EAEL,qBAAqB,GACtB,MAAM,iDAAiD,CAAC;AAGzD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAoC;IAEpC,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACxB,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;YAC/B,IAAI,EAAE,CAAC;YACP,OAAO;QACT,CAAC;QACD,OAAO,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import {\n type BearerAuthMiddlewareOptions,\n requireBearerAuth,\n} from \"@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js\";\n\nimport type { RequestHandler } from \"express\";\n\nexport { InvalidTokenError } from \"@modelcontextprotocol/sdk/server/auth/errors.js\";\nexport {\n type BearerAuthMiddlewareOptions,\n requireBearerAuth,\n} from \"@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js\";\nexport {\n type AuthMetadataOptions,\n mcpAuthMetadataRouter,\n} from \"@modelcontextprotocol/sdk/server/auth/router.js\";\nexport type { AuthInfo } from \"@modelcontextprotocol/sdk/server/auth/types.js\";\n\n/**\n * Like `requireBearerAuth`, but lets requests through when no\n * `Authorization` header is present. Used for mixed-auth servers where some\n * tools are public and others require sign-in: each tool enforces its own\n * `securitySchemes` against `extra.authInfo`.\n *\n * Behavior:\n * - No `Authorization` header → `next()` without `req.auth`.\n * - Valid Bearer token → `req.auth` set, same as `requireBearerAuth`.\n * - Invalid / malformed / expired / insufficient-scope → same error response\n * as `requireBearerAuth` (401/403). Sending a bad token is still a client\n * error.\n */\nexport function optionalBearerAuth(\n options: BearerAuthMiddlewareOptions,\n): RequestHandler {\n const required = requireBearerAuth(options);\n return (req, res, next) => {\n if (!req.headers.authorization) {\n next();\n return;\n }\n return required(req, res, next);\n };\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { __setBuildManifest, McpServer } from "./index.js";
3
+ function manifestOf(server) {
4
+ return server.viteManifest;
5
+ }
6
+ function makeServer() {
7
+ return new McpServer({ name: "test", version: "0.0.1" }, { capabilities: {} });
8
+ }
9
+ describe("__setBuildManifest", () => {
10
+ it("primes the Vite manifest for the next McpServer constructed", () => {
11
+ const manifest = {
12
+ "src/views/index.tsx": { file: "assets/index-DEADBEEF.js" },
13
+ };
14
+ __setBuildManifest(manifest);
15
+ // viteManifest is private; reach into it to lock the contract that the
16
+ // generated `dist/__entry.js` relies on.
17
+ expect(manifestOf(makeServer())).toEqual(manifest);
18
+ });
19
+ it("is consume-once: a second McpServer built without re-priming gets no manifest", () => {
20
+ __setBuildManifest({
21
+ "src/views/index.tsx": { file: "assets/index-CAFEBABE.js" },
22
+ });
23
+ makeServer(); // consumes the primed manifest
24
+ expect(manifestOf(makeServer())).toBeNull();
25
+ });
26
+ });
27
+ //# sourceMappingURL=build-manifest.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-manifest.test.js","sourceRoot":"","sources":["../../src/server/build-manifest.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE3D,SAAS,UAAU,CACjB,MAAiB;IAEjB,OACE,MAGD,CAAC,YAAY,CAAC;AACjB,CAAC;AAED,SAAS,UAAU;IACjB,OAAO,IAAI,SAAS,CAClB,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,EAClC,EAAE,YAAY,EAAE,EAAE,EAAE,CACrB,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,QAAQ,GAAG;YACf,qBAAqB,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE;SAC5D,CAAC;QACF,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAE7B,uEAAuE;QACvE,yCAAyC;QACzC,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+EAA+E,EAAE,GAAG,EAAE;QACvF,kBAAkB,CAAC;YACjB,qBAAqB,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE;SAC5D,CAAC,CAAC;QAEH,UAAU,EAAE,CAAC,CAAC,+BAA+B;QAC7C,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { __setBuildManifest, McpServer } from \"./index.js\";\n\nfunction manifestOf(\n server: McpServer,\n): Record<string, { file: string }> | null {\n return (\n server as unknown as {\n viteManifest: Record<string, { file: string }> | null;\n }\n ).viteManifest;\n}\n\nfunction makeServer(): McpServer {\n return new McpServer(\n { name: \"test\", version: \"0.0.1\" },\n { capabilities: {} },\n );\n}\n\ndescribe(\"__setBuildManifest\", () => {\n it(\"primes the Vite manifest for the next McpServer constructed\", () => {\n const manifest = {\n \"src/views/index.tsx\": { file: \"assets/index-DEADBEEF.js\" },\n };\n __setBuildManifest(manifest);\n\n // viteManifest is private; reach into it to lock the contract that the\n // generated `dist/__entry.js` relies on.\n expect(manifestOf(makeServer())).toEqual(manifest);\n });\n\n it(\"is consume-once: a second McpServer built without re-priming gets no manifest\", () => {\n __setBuildManifest({\n \"src/views/index.tsx\": { file: \"assets/index-CAFEBABE.js\" },\n });\n\n makeServer(); // consumes the primed manifest\n expect(manifestOf(makeServer())).toBeNull();\n });\n});\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,214 @@
1
+ import fs from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import express from "express";
5
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
6
+ import { MemoryStorageAdapter } from "../storage/memory.js";
7
+ import { MASKED, resolveConfig, validateRuntimeWrite } from "./resolve.js";
8
+ import { createConfigRouter } from "./router.js";
9
+ /** A throwaway dir with no enpilink.config.* so file source never interferes. */
10
+ let cwd;
11
+ beforeEach(() => {
12
+ cwd = fs.mkdtempSync(path.join(os.tmpdir(), "enpi-cfg-"));
13
+ });
14
+ afterEach(() => {
15
+ fs.rmSync(cwd, { recursive: true, force: true });
16
+ // Clean any env we set.
17
+ for (const k of Object.keys(process.env)) {
18
+ if (k.startsWith("ENPILINK_CFG_") || k === "ENPILINK_ANALYTICS") {
19
+ delete process.env[k];
20
+ }
21
+ }
22
+ });
23
+ describe("resolveConfig precedence", () => {
24
+ it("defaults when no source supplies a value", async () => {
25
+ const { settings } = await resolveConfig(null, cwd);
26
+ const s = settings.find((x) => x.key === "analytics.sampleRate");
27
+ expect(s?.value).toBe(1);
28
+ expect(s?.source).toBe("default");
29
+ expect(s?.envLocked).toBe(false);
30
+ });
31
+ it("db beats default for runtime keys", async () => {
32
+ const storage = new MemoryStorageAdapter();
33
+ await storage.setConfig("analytics.sampleRate", 0.25, "tester");
34
+ const { settings, values } = await resolveConfig(storage, cwd);
35
+ const s = settings.find((x) => x.key === "analytics.sampleRate");
36
+ expect(s?.source).toBe("db");
37
+ expect(s?.value).toBe(0.25);
38
+ expect(values["analytics.sampleRate"]).toBe(0.25);
39
+ });
40
+ it("file beats db", async () => {
41
+ const storage = new MemoryStorageAdapter();
42
+ await storage.setConfig("analytics.sampleRate", 0.25);
43
+ fs.writeFileSync(path.join(cwd, "enpilink.config.json"), JSON.stringify({ "analytics.sampleRate": 0.5 }));
44
+ const { settings } = await resolveConfig(storage, cwd);
45
+ const s = settings.find((x) => x.key === "analytics.sampleRate");
46
+ expect(s?.source).toBe("file");
47
+ expect(s?.value).toBe(0.5);
48
+ expect(s?.envLocked).toBe(true); // file pins it → read-only in UI
49
+ });
50
+ it("env beats file and db", async () => {
51
+ const storage = new MemoryStorageAdapter();
52
+ await storage.setConfig("analytics.sampleRate", 0.25);
53
+ fs.writeFileSync(path.join(cwd, "enpilink.config.json"), JSON.stringify({ "analytics.sampleRate": 0.5 }));
54
+ process.env.ENPILINK_CFG_ANALYTICS_SAMPLE_RATE = "0.75";
55
+ const { settings } = await resolveConfig(storage, cwd);
56
+ const s = settings.find((x) => x.key === "analytics.sampleRate");
57
+ expect(s?.source).toBe("env");
58
+ expect(s?.value).toBe(0.75);
59
+ expect(s?.envLocked).toBe(true);
60
+ });
61
+ it("coerces env booleans/numbers to typed values", async () => {
62
+ process.env.ENPILINK_CFG_FLAGS_LIVE_LOGS = "false";
63
+ process.env.ENPILINK_CFG_RETENTION_EVENTS = "1234";
64
+ const { values } = await resolveConfig(null, cwd);
65
+ expect(values["flags.liveLogs"]).toBe(false);
66
+ expect(values["retention.events"]).toBe(1234);
67
+ });
68
+ });
69
+ describe("secret masking", () => {
70
+ it("never returns a secret value in plaintext", async () => {
71
+ process.env.ENPILINK_ADMIN_TOKEN = "super-secret-xyz";
72
+ const { settings } = await resolveConfig(null, cwd);
73
+ const s = settings.find((x) => x.key === "adminAuthToken");
74
+ expect(s?.secret).toBe(true);
75
+ expect(s?.envLocked).toBe(true);
76
+ expect(s?.value).toBe(MASKED);
77
+ expect(JSON.stringify(settings)).not.toContain("super-secret-xyz");
78
+ delete process.env.ENPILINK_ADMIN_TOKEN;
79
+ });
80
+ it("unset secret reports null, not masked", async () => {
81
+ const { settings } = await resolveConfig(null, cwd);
82
+ const s = settings.find((x) => x.key === "adminAuthToken");
83
+ expect(s?.value).toBeNull();
84
+ });
85
+ it("bootstrap keys are always env-locked", async () => {
86
+ const { settings } = await resolveConfig(null, cwd);
87
+ for (const key of ["storage", "dbPath", "port", "admin"]) {
88
+ const s = settings.find((x) => x.key === key);
89
+ expect(s?.tier).toBe("bootstrap");
90
+ expect(s?.envLocked).toBe(true);
91
+ }
92
+ });
93
+ });
94
+ describe("validateRuntimeWrite", () => {
95
+ it("accepts a valid runtime value", () => {
96
+ const r = validateRuntimeWrite("analytics.sampleRate", 0.3);
97
+ expect(r.ok).toBe(true);
98
+ if (r.ok) {
99
+ expect(r.value).toBe(0.3);
100
+ }
101
+ });
102
+ it("coerces a stringy boolean for a flag", () => {
103
+ const r = validateRuntimeWrite("flags.liveLogs", "true");
104
+ expect(r.ok).toBe(true);
105
+ if (r.ok) {
106
+ expect(r.value).toBe(true);
107
+ }
108
+ });
109
+ it("rejects out-of-range", () => {
110
+ const r = validateRuntimeWrite("analytics.sampleRate", 5);
111
+ expect(r.ok).toBe(false);
112
+ });
113
+ it("rejects bootstrap key", () => {
114
+ expect(validateRuntimeWrite("port", 8080).ok).toBe(false);
115
+ });
116
+ it("rejects secret key", () => {
117
+ expect(validateRuntimeWrite("adminAuthToken", "x").ok).toBe(false);
118
+ });
119
+ });
120
+ // --- Router integration tests ---
121
+ async function request(app, method, url, body) {
122
+ const { createServer } = await import("node:http");
123
+ const server = createServer(app);
124
+ await new Promise((r) => server.listen(0, r));
125
+ const addr = server.address();
126
+ const port = typeof addr === "object" && addr ? addr.port : 0;
127
+ try {
128
+ const res = await fetch(`http://127.0.0.1:${port}${url}`, {
129
+ method,
130
+ headers: body ? { "content-type": "application/json" } : undefined,
131
+ body: body ? JSON.stringify(body) : undefined,
132
+ });
133
+ return { status: res.status, json: await res.json().catch(() => null) };
134
+ }
135
+ finally {
136
+ await new Promise((r) => server.close(() => r()));
137
+ }
138
+ }
139
+ function appWith(storage) {
140
+ const app = express();
141
+ app.use(express.json());
142
+ app.use(createConfigRouter(() => storage));
143
+ return app;
144
+ }
145
+ describe("config router", () => {
146
+ it("GET /config returns settings; never 500 with no storage", async () => {
147
+ const app = appWith(null);
148
+ const { status, json } = await request(app, "GET", "/__enpilink/config");
149
+ expect(status).toBe(200);
150
+ const settings = json.settings;
151
+ expect(Array.isArray(settings)).toBe(true);
152
+ expect(settings.length).toBeGreaterThan(0);
153
+ });
154
+ it("PUT a runtime key persists + writes an audit row", async () => {
155
+ const storage = new MemoryStorageAdapter();
156
+ const app = appWith(storage);
157
+ const { status, json } = await request(app, "PUT", "/__enpilink/config/analytics.sampleRate", { value: 0.4 });
158
+ expect(status).toBe(200);
159
+ expect(json.ok).toBe(true);
160
+ expect(await storage.getConfig("analytics.sampleRate")).toBe(0.4);
161
+ const audit = await storage.getConfigAudit();
162
+ expect(audit[0]).toMatchObject({
163
+ key: "analytics.sampleRate",
164
+ newValue: 0.4,
165
+ });
166
+ });
167
+ it("PUT rejects a bootstrap key (403)", async () => {
168
+ const storage = new MemoryStorageAdapter();
169
+ const app = appWith(storage);
170
+ const { status } = await request(app, "PUT", "/__enpilink/config/port", {
171
+ value: 9999,
172
+ });
173
+ expect(status).toBe(403);
174
+ });
175
+ it("PUT rejects a secret key (403)", async () => {
176
+ const storage = new MemoryStorageAdapter();
177
+ const app = appWith(storage);
178
+ const { status } = await request(app, "PUT", "/__enpilink/config/adminAuthToken", { value: "x" });
179
+ expect(status).toBe(403);
180
+ });
181
+ it("PUT rejects an unknown key (404)", async () => {
182
+ const app = appWith(new MemoryStorageAdapter());
183
+ const { status } = await request(app, "PUT", "/__enpilink/config/nope", {
184
+ value: 1,
185
+ });
186
+ expect(status).toBe(404);
187
+ });
188
+ it("PUT rejects an out-of-range runtime value (400)", async () => {
189
+ const app = appWith(new MemoryStorageAdapter());
190
+ const { status } = await request(app, "PUT", "/__enpilink/config/analytics.sampleRate", { value: 99 });
191
+ expect(status).toBe(400);
192
+ });
193
+ it("PUT with no storage → 409 (nowhere to persist)", async () => {
194
+ const app = appWith(null);
195
+ const { status } = await request(app, "PUT", "/__enpilink/config/flags.liveLogs", { value: false });
196
+ expect(status).toBe(409);
197
+ });
198
+ it("GET /config/audit surfaces entries", async () => {
199
+ const storage = new MemoryStorageAdapter();
200
+ await storage.setConfig("flags.liveLogs", false, "tester");
201
+ const app = appWith(storage);
202
+ const { status, json } = await request(app, "GET", "/__enpilink/config/audit");
203
+ expect(status).toBe(200);
204
+ const audit = json.audit;
205
+ expect(audit[0]?.key).toBe("flags.liveLogs");
206
+ });
207
+ it("GET /config/audit with no storage → empty, never 500", async () => {
208
+ const app = appWith(null);
209
+ const { status, json } = await request(app, "GET", "/__enpilink/config/audit");
210
+ expect(status).toBe(200);
211
+ expect(json.audit).toEqual([]);
212
+ });
213
+ });
214
+ //# sourceMappingURL=config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../../src/server/config/config.test.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport express from \"express\";\nimport { afterEach, beforeEach, describe, expect, it } from \"vitest\";\nimport { MemoryStorageAdapter } from \"../storage/memory.js\";\nimport type { StorageAdapter } from \"../storage/types.js\";\nimport { MASKED, resolveConfig, validateRuntimeWrite } from \"./resolve.js\";\nimport { createConfigRouter } from \"./router.js\";\n\n/** A throwaway dir with no enpilink.config.* so file source never interferes. */\nlet cwd: string;\n\nbeforeEach(() => {\n cwd = fs.mkdtempSync(path.join(os.tmpdir(), \"enpi-cfg-\"));\n});\nafterEach(() => {\n fs.rmSync(cwd, { recursive: true, force: true });\n // Clean any env we set.\n for (const k of Object.keys(process.env)) {\n if (k.startsWith(\"ENPILINK_CFG_\") || k === \"ENPILINK_ANALYTICS\") {\n delete process.env[k];\n }\n }\n});\n\ndescribe(\"resolveConfig precedence\", () => {\n it(\"defaults when no source supplies a value\", async () => {\n const { settings } = await resolveConfig(null, cwd);\n const s = settings.find((x) => x.key === \"analytics.sampleRate\");\n expect(s?.value).toBe(1);\n expect(s?.source).toBe(\"default\");\n expect(s?.envLocked).toBe(false);\n });\n\n it(\"db beats default for runtime keys\", async () => {\n const storage = new MemoryStorageAdapter();\n await storage.setConfig(\"analytics.sampleRate\", 0.25, \"tester\");\n const { settings, values } = await resolveConfig(storage, cwd);\n const s = settings.find((x) => x.key === \"analytics.sampleRate\");\n expect(s?.source).toBe(\"db\");\n expect(s?.value).toBe(0.25);\n expect(values[\"analytics.sampleRate\"]).toBe(0.25);\n });\n\n it(\"file beats db\", async () => {\n const storage = new MemoryStorageAdapter();\n await storage.setConfig(\"analytics.sampleRate\", 0.25);\n fs.writeFileSync(\n path.join(cwd, \"enpilink.config.json\"),\n JSON.stringify({ \"analytics.sampleRate\": 0.5 }),\n );\n const { settings } = await resolveConfig(storage, cwd);\n const s = settings.find((x) => x.key === \"analytics.sampleRate\");\n expect(s?.source).toBe(\"file\");\n expect(s?.value).toBe(0.5);\n expect(s?.envLocked).toBe(true); // file pins it → read-only in UI\n });\n\n it(\"env beats file and db\", async () => {\n const storage = new MemoryStorageAdapter();\n await storage.setConfig(\"analytics.sampleRate\", 0.25);\n fs.writeFileSync(\n path.join(cwd, \"enpilink.config.json\"),\n JSON.stringify({ \"analytics.sampleRate\": 0.5 }),\n );\n process.env.ENPILINK_CFG_ANALYTICS_SAMPLE_RATE = \"0.75\";\n const { settings } = await resolveConfig(storage, cwd);\n const s = settings.find((x) => x.key === \"analytics.sampleRate\");\n expect(s?.source).toBe(\"env\");\n expect(s?.value).toBe(0.75);\n expect(s?.envLocked).toBe(true);\n });\n\n it(\"coerces env booleans/numbers to typed values\", async () => {\n process.env.ENPILINK_CFG_FLAGS_LIVE_LOGS = \"false\";\n process.env.ENPILINK_CFG_RETENTION_EVENTS = \"1234\";\n const { values } = await resolveConfig(null, cwd);\n expect(values[\"flags.liveLogs\"]).toBe(false);\n expect(values[\"retention.events\"]).toBe(1234);\n });\n});\n\ndescribe(\"secret masking\", () => {\n it(\"never returns a secret value in plaintext\", async () => {\n process.env.ENPILINK_ADMIN_TOKEN = \"super-secret-xyz\";\n const { settings } = await resolveConfig(null, cwd);\n const s = settings.find((x) => x.key === \"adminAuthToken\");\n expect(s?.secret).toBe(true);\n expect(s?.envLocked).toBe(true);\n expect(s?.value).toBe(MASKED);\n expect(JSON.stringify(settings)).not.toContain(\"super-secret-xyz\");\n delete process.env.ENPILINK_ADMIN_TOKEN;\n });\n\n it(\"unset secret reports null, not masked\", async () => {\n const { settings } = await resolveConfig(null, cwd);\n const s = settings.find((x) => x.key === \"adminAuthToken\");\n expect(s?.value).toBeNull();\n });\n\n it(\"bootstrap keys are always env-locked\", async () => {\n const { settings } = await resolveConfig(null, cwd);\n for (const key of [\"storage\", \"dbPath\", \"port\", \"admin\"]) {\n const s = settings.find((x) => x.key === key);\n expect(s?.tier).toBe(\"bootstrap\");\n expect(s?.envLocked).toBe(true);\n }\n });\n});\n\ndescribe(\"validateRuntimeWrite\", () => {\n it(\"accepts a valid runtime value\", () => {\n const r = validateRuntimeWrite(\"analytics.sampleRate\", 0.3);\n expect(r.ok).toBe(true);\n if (r.ok) {\n expect(r.value).toBe(0.3);\n }\n });\n it(\"coerces a stringy boolean for a flag\", () => {\n const r = validateRuntimeWrite(\"flags.liveLogs\", \"true\");\n expect(r.ok).toBe(true);\n if (r.ok) {\n expect(r.value).toBe(true);\n }\n });\n it(\"rejects out-of-range\", () => {\n const r = validateRuntimeWrite(\"analytics.sampleRate\", 5);\n expect(r.ok).toBe(false);\n });\n it(\"rejects bootstrap key\", () => {\n expect(validateRuntimeWrite(\"port\", 8080).ok).toBe(false);\n });\n it(\"rejects secret key\", () => {\n expect(validateRuntimeWrite(\"adminAuthToken\", \"x\").ok).toBe(false);\n });\n});\n\n// --- Router integration tests ---\n\nasync function request(\n app: express.Express,\n method: string,\n url: string,\n body?: unknown,\n): Promise<{ status: number; json: unknown }> {\n const { createServer } = await import(\"node:http\");\n const server = createServer(app);\n await new Promise<void>((r) => server.listen(0, r));\n const addr = server.address();\n const port = typeof addr === \"object\" && addr ? addr.port : 0;\n try {\n const res = await fetch(`http://127.0.0.1:${port}${url}`, {\n method,\n headers: body ? { \"content-type\": \"application/json\" } : undefined,\n body: body ? JSON.stringify(body) : undefined,\n });\n return { status: res.status, json: await res.json().catch(() => null) };\n } finally {\n await new Promise<void>((r) => server.close(() => r()));\n }\n}\n\nfunction appWith(storage: StorageAdapter | null): express.Express {\n const app = express();\n app.use(express.json());\n app.use(createConfigRouter(() => storage));\n return app;\n}\n\ndescribe(\"config router\", () => {\n it(\"GET /config returns settings; never 500 with no storage\", async () => {\n const app = appWith(null);\n const { status, json } = await request(app, \"GET\", \"/__enpilink/config\");\n expect(status).toBe(200);\n const settings = (json as { settings: unknown[] }).settings;\n expect(Array.isArray(settings)).toBe(true);\n expect(settings.length).toBeGreaterThan(0);\n });\n\n it(\"PUT a runtime key persists + writes an audit row\", async () => {\n const storage = new MemoryStorageAdapter();\n const app = appWith(storage);\n const { status, json } = await request(\n app,\n \"PUT\",\n \"/__enpilink/config/analytics.sampleRate\",\n { value: 0.4 },\n );\n expect(status).toBe(200);\n expect((json as { ok: boolean }).ok).toBe(true);\n expect(await storage.getConfig(\"analytics.sampleRate\")).toBe(0.4);\n const audit = await storage.getConfigAudit();\n expect(audit[0]).toMatchObject({\n key: \"analytics.sampleRate\",\n newValue: 0.4,\n });\n });\n\n it(\"PUT rejects a bootstrap key (403)\", async () => {\n const storage = new MemoryStorageAdapter();\n const app = appWith(storage);\n const { status } = await request(app, \"PUT\", \"/__enpilink/config/port\", {\n value: 9999,\n });\n expect(status).toBe(403);\n });\n\n it(\"PUT rejects a secret key (403)\", async () => {\n const storage = new MemoryStorageAdapter();\n const app = appWith(storage);\n const { status } = await request(\n app,\n \"PUT\",\n \"/__enpilink/config/adminAuthToken\",\n { value: \"x\" },\n );\n expect(status).toBe(403);\n });\n\n it(\"PUT rejects an unknown key (404)\", async () => {\n const app = appWith(new MemoryStorageAdapter());\n const { status } = await request(app, \"PUT\", \"/__enpilink/config/nope\", {\n value: 1,\n });\n expect(status).toBe(404);\n });\n\n it(\"PUT rejects an out-of-range runtime value (400)\", async () => {\n const app = appWith(new MemoryStorageAdapter());\n const { status } = await request(\n app,\n \"PUT\",\n \"/__enpilink/config/analytics.sampleRate\",\n { value: 99 },\n );\n expect(status).toBe(400);\n });\n\n it(\"PUT with no storage → 409 (nowhere to persist)\", async () => {\n const app = appWith(null);\n const { status } = await request(\n app,\n \"PUT\",\n \"/__enpilink/config/flags.liveLogs\",\n { value: false },\n );\n expect(status).toBe(409);\n });\n\n it(\"GET /config/audit surfaces entries\", async () => {\n const storage = new MemoryStorageAdapter();\n await storage.setConfig(\"flags.liveLogs\", false, \"tester\");\n const app = appWith(storage);\n const { status, json } = await request(\n app,\n \"GET\",\n \"/__enpilink/config/audit\",\n );\n expect(status).toBe(200);\n const audit = (json as { audit: Array<{ key: string }> }).audit;\n expect(audit[0]?.key).toBe(\"flags.liveLogs\");\n });\n\n it(\"GET /config/audit with no storage → empty, never 500\", async () => {\n const app = appWith(null);\n const { status, json } = await request(\n app,\n \"GET\",\n \"/__enpilink/config/audit\",\n );\n expect(status).toBe(200);\n expect((json as { audit: unknown[] }).audit).toEqual([]);\n });\n});\n"]}
@@ -0,0 +1,3 @@
1
+ export { type ConfigSource, loadConfigFile, MASKED, type ResolvedConfig, type ResolvedSetting, resolveConfig, validateRuntimeWrite, } from "./resolve.js";
2
+ export { createConfigRouter } from "./router.js";
3
+ export { allKeyMeta, BOOTSTRAP_KEYS, type BootstrapConfig, type BootstrapKey, bootstrapSchema, type Config, type ConfigKey, configSchema, ENV_VARS, isBootstrapKey, isKnownKey, isRuntimeKey, isSecretKey, type KeyMeta, keyMeta, RUNTIME_KEYS, type RuntimeConfig, type RuntimeKey, runtimeSchema, SECRET_KEYS, } from "./schema.js";
@@ -0,0 +1,4 @@
1
+ export { loadConfigFile, MASKED, resolveConfig, validateRuntimeWrite, } from "./resolve.js";
2
+ export { createConfigRouter } from "./router.js";
3
+ export { allKeyMeta, BOOTSTRAP_KEYS, bootstrapSchema, configSchema, ENV_VARS, isBootstrapKey, isKnownKey, isRuntimeKey, isSecretKey, keyMeta, RUNTIME_KEYS, runtimeSchema, SECRET_KEYS, } from "./schema.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,cAAc,EACd,MAAM,EAGN,aAAa,EACb,oBAAoB,GACrB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,UAAU,EACV,cAAc,EAGd,eAAe,EAGf,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,UAAU,EACV,YAAY,EACZ,WAAW,EAEX,OAAO,EACP,YAAY,EAGZ,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAC","sourcesContent":["export {\n type ConfigSource,\n loadConfigFile,\n MASKED,\n type ResolvedConfig,\n type ResolvedSetting,\n resolveConfig,\n validateRuntimeWrite,\n} from \"./resolve.js\";\nexport { createConfigRouter } from \"./router.js\";\nexport {\n allKeyMeta,\n BOOTSTRAP_KEYS,\n type BootstrapConfig,\n type BootstrapKey,\n bootstrapSchema,\n type Config,\n type ConfigKey,\n configSchema,\n ENV_VARS,\n isBootstrapKey,\n isKnownKey,\n isRuntimeKey,\n isSecretKey,\n type KeyMeta,\n keyMeta,\n RUNTIME_KEYS,\n type RuntimeConfig,\n type RuntimeKey,\n runtimeSchema,\n SECRET_KEYS,\n} from \"./schema.js\";\n"]}
@@ -0,0 +1,73 @@
1
+ import type { StorageAdapter } from "../storage/types.js";
2
+ import { type Config, type ConfigKey } from "./schema.js";
3
+ /**
4
+ * Config resolution (M4). Merges sources with precedence
5
+ * **env > file (`enpilink.config.{json,ts}`) > db (runtime only) > default**
6
+ * and reports, per key, which source supplied the value and whether the key is
7
+ * secret / env-locked (read-only).
8
+ *
9
+ * Secrets (e.g. `adminAuthToken`) are NEVER read from the DB and NEVER returned
10
+ * in plaintext — {@link resolveConfig} masks them to a placeholder and flags
11
+ * `secret: true`. Bootstrap keys and any key pinned by env/file are
12
+ * `envLocked: true` (the admin UI must render them read-only).
13
+ */
14
+ export type ConfigSource = "env" | "file" | "db" | "default";
15
+ /** A masked placeholder returned in place of any secret value. */
16
+ export declare const MASKED = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
17
+ /** A single resolved setting as exposed by the config API. */
18
+ export interface ResolvedSetting {
19
+ key: ConfigKey;
20
+ /** Tier: `bootstrap` (env/file only) or `runtime` (DB-editable). */
21
+ tier: "bootstrap" | "runtime";
22
+ /** The resolved value, or {@link MASKED} when secret. */
23
+ value: unknown;
24
+ /** Which source supplied the value. */
25
+ source: ConfigSource;
26
+ /** Whether this key is a secret (never returned in plaintext). */
27
+ secret: boolean;
28
+ /**
29
+ * Whether this key is read-only in the admin UI. True for all bootstrap keys,
30
+ * and for any runtime key pinned via env or file (the DB value is shadowed).
31
+ */
32
+ envLocked: boolean;
33
+ /** The env var that drives / can pin this key. */
34
+ env: string;
35
+ }
36
+ /** The full resolved config plus per-key reporting. */
37
+ export interface ResolvedConfig {
38
+ /** Effective typed values (secrets present in-process, masked only at the API). */
39
+ values: Config;
40
+ /** Per-key source + secret/env-lock reporting. */
41
+ settings: ResolvedSetting[];
42
+ }
43
+ /**
44
+ * Load the optional config file (JSON only — a `.ts` file is acknowledged but
45
+ * not executed here to avoid a runtime transpile dependency; M6 can add TS
46
+ * loading). Returns a flat partial keyed by {@link ConfigKey}. Never throws —
47
+ * a malformed/absent file yields `{}`.
48
+ */
49
+ export declare function loadConfigFile(cwd?: string): {
50
+ source: "file" | null;
51
+ values: Partial<Record<ConfigKey, unknown>>;
52
+ };
53
+ /**
54
+ * Resolve all config. Reads the DB (runtime keys only) when a storage adapter
55
+ * is provided; secrets are never read from the DB. Falls back to defaults when
56
+ * there is no storage. Never throws on a storage error — it degrades to
57
+ * file/env/default.
58
+ *
59
+ * @param storage active storage adapter, or `null` when analytics/admin is off.
60
+ */
61
+ export declare function resolveConfig(storage: StorageAdapter | null, cwd?: string): Promise<ResolvedConfig>;
62
+ /**
63
+ * Validate + coerce a single RUNTIME, non-secret value before persisting.
64
+ * Returns the coerced value or an error string. Rejects unknown/bootstrap/
65
+ * secret keys (those are handled by the caller with a clear 4xx).
66
+ */
67
+ export declare function validateRuntimeWrite(key: string, rawValue: unknown): {
68
+ ok: true;
69
+ value: unknown;
70
+ } | {
71
+ ok: false;
72
+ error: string;
73
+ };