everything-dev 1.53.2 → 2.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (713) hide show
  1. package/README.md +2 -11
  2. package/dist/_virtual/_rolldown/runtime.cjs +17 -2
  3. package/dist/_virtual/_rolldown/runtime.mjs +36 -0
  4. package/dist/api/auth-middleware.cjs +161 -0
  5. package/dist/api/auth-middleware.cjs.map +1 -0
  6. package/dist/api/auth-middleware.d.cts +69 -0
  7. package/dist/api/auth-middleware.d.mts +69 -0
  8. package/dist/api/auth-middleware.mjs +160 -0
  9. package/dist/api/auth-middleware.mjs.map +1 -0
  10. package/dist/api-contract.cjs +250 -62
  11. package/dist/api-contract.cjs.map +1 -1
  12. package/dist/api-contract.mjs +246 -65
  13. package/dist/api-contract.mjs.map +1 -1
  14. package/dist/app.cjs +99 -26
  15. package/dist/app.cjs.map +1 -1
  16. package/dist/app.d.cts +3 -0
  17. package/dist/app.d.mts +3 -0
  18. package/dist/app.mjs +100 -27
  19. package/dist/app.mjs.map +1 -1
  20. package/dist/auth-login.cjs +163 -0
  21. package/dist/auth-login.cjs.map +1 -0
  22. package/dist/auth-login.mjs +162 -0
  23. package/dist/auth-login.mjs.map +1 -0
  24. package/dist/auth-session.cjs +64 -0
  25. package/dist/auth-session.cjs.map +1 -0
  26. package/dist/auth-session.mjs +58 -0
  27. package/dist/auth-session.mjs.map +1 -0
  28. package/dist/auth-types-gen.cjs +0 -1
  29. package/dist/auth-types-gen.cjs.map +1 -1
  30. package/dist/build.cjs +37 -173
  31. package/dist/build.cjs.map +1 -1
  32. package/dist/build.mjs +37 -171
  33. package/dist/build.mjs.map +1 -1
  34. package/dist/bundle-cache.cjs +74 -0
  35. package/dist/bundle-cache.cjs.map +1 -0
  36. package/dist/bundle-cache.d.cts +27 -0
  37. package/dist/bundle-cache.d.mts +27 -0
  38. package/dist/bundle-cache.mjs +68 -0
  39. package/dist/bundle-cache.mjs.map +1 -0
  40. package/dist/bundle-fs-resolve.cjs +209 -0
  41. package/dist/bundle-fs-resolve.cjs.map +1 -0
  42. package/dist/bundle-fs-resolve.d.cts +76 -0
  43. package/dist/bundle-fs-resolve.d.mts +76 -0
  44. package/dist/bundle-fs-resolve.mjs +202 -0
  45. package/dist/bundle-fs-resolve.mjs.map +1 -0
  46. package/dist/cdn-deploy.cjs +126 -0
  47. package/dist/cdn-deploy.cjs.map +1 -0
  48. package/dist/cdn-deploy.mjs +124 -0
  49. package/dist/cdn-deploy.mjs.map +1 -0
  50. package/dist/cli/db-doctor.cjs +19 -19
  51. package/dist/cli/db-doctor.cjs.map +1 -1
  52. package/dist/cli/db-doctor.mjs +18 -18
  53. package/dist/cli/db-doctor.mjs.map +1 -1
  54. package/dist/cli/db-repair.cjs +9 -32
  55. package/dist/cli/db-repair.cjs.map +1 -1
  56. package/dist/cli/db-repair.mjs +9 -32
  57. package/dist/cli/db-repair.mjs.map +1 -1
  58. package/dist/cli/framework-version.cjs +7 -3
  59. package/dist/cli/framework-version.cjs.map +1 -1
  60. package/dist/cli/framework-version.mjs +7 -3
  61. package/dist/cli/framework-version.mjs.map +1 -1
  62. package/dist/cli/infra.cjs +159 -251
  63. package/dist/cli/infra.cjs.map +1 -1
  64. package/dist/cli/infra.mjs +154 -242
  65. package/dist/cli/infra.mjs.map +1 -1
  66. package/dist/cli/init.cjs +624 -196
  67. package/dist/cli/init.cjs.map +1 -1
  68. package/dist/cli/init.d.cts +61 -8
  69. package/dist/cli/init.d.mts +61 -8
  70. package/dist/cli/init.mjs +613 -194
  71. package/dist/cli/init.mjs.map +1 -1
  72. package/dist/cli/parse.cjs +8 -7
  73. package/dist/cli/parse.cjs.map +1 -1
  74. package/dist/cli/parse.mjs +9 -7
  75. package/dist/cli/parse.mjs.map +1 -1
  76. package/dist/cli/prompts.cjs +14 -1
  77. package/dist/cli/prompts.cjs.map +1 -1
  78. package/dist/cli/prompts.mjs +14 -1
  79. package/dist/cli/prompts.mjs.map +1 -1
  80. package/dist/cli/prune.cjs +220 -0
  81. package/dist/cli/prune.cjs.map +1 -0
  82. package/dist/cli/prune.mjs +220 -0
  83. package/dist/cli/prune.mjs.map +1 -0
  84. package/dist/cli/snapshot.cjs +2 -1
  85. package/dist/cli/snapshot.cjs.map +1 -1
  86. package/dist/cli/snapshot.mjs +2 -1
  87. package/dist/cli/snapshot.mjs.map +1 -1
  88. package/dist/cli/status.cjs +5 -4
  89. package/dist/cli/status.cjs.map +1 -1
  90. package/dist/cli/status.mjs +6 -5
  91. package/dist/cli/status.mjs.map +1 -1
  92. package/dist/cli/sync.cjs +156 -58
  93. package/dist/cli/sync.cjs.map +1 -1
  94. package/dist/cli/sync.mjs +158 -63
  95. package/dist/cli/sync.mjs.map +1 -1
  96. package/dist/cli/timing.cjs +0 -1
  97. package/dist/cli/timing.cjs.map +1 -1
  98. package/dist/cli/upgrade.cjs +95 -69
  99. package/dist/cli/upgrade.cjs.map +1 -1
  100. package/dist/cli/upgrade.mjs +97 -72
  101. package/dist/cli/upgrade.mjs.map +1 -1
  102. package/dist/cli/utils/helpers.cjs.map +1 -1
  103. package/dist/cli.cjs +320 -72
  104. package/dist/cli.cjs.map +1 -1
  105. package/dist/cli.mjs +316 -68
  106. package/dist/cli.mjs.map +1 -1
  107. package/dist/code-artifacts.cjs +76 -8
  108. package/dist/code-artifacts.cjs.map +1 -1
  109. package/dist/code-artifacts.mjs +76 -10
  110. package/dist/code-artifacts.mjs.map +1 -1
  111. package/dist/commands/build.cjs +65 -0
  112. package/dist/commands/build.cjs.map +1 -0
  113. package/dist/commands/build.mjs +65 -0
  114. package/dist/commands/build.mjs.map +1 -0
  115. package/dist/commands/config.cjs +77 -0
  116. package/dist/commands/config.cjs.map +1 -0
  117. package/dist/commands/config.d.cts +8 -0
  118. package/dist/commands/config.d.mts +8 -0
  119. package/dist/commands/config.mjs +74 -0
  120. package/dist/commands/config.mjs.map +1 -0
  121. package/dist/commands/db.cjs +107 -0
  122. package/dist/commands/db.cjs.map +1 -0
  123. package/dist/commands/db.mjs +107 -0
  124. package/dist/commands/db.mjs.map +1 -0
  125. package/dist/commands/deploy.cjs +336 -0
  126. package/dist/commands/deploy.cjs.map +1 -0
  127. package/dist/commands/deploy.mjs +334 -0
  128. package/dist/commands/deploy.mjs.map +1 -0
  129. package/dist/commands/dev.cjs +75 -0
  130. package/dist/commands/dev.cjs.map +1 -0
  131. package/dist/commands/dev.mjs +73 -0
  132. package/dist/commands/dev.mjs.map +1 -0
  133. package/dist/commands/init.cjs +234 -0
  134. package/dist/commands/init.cjs.map +1 -0
  135. package/dist/commands/init.mjs +231 -0
  136. package/dist/commands/init.mjs.map +1 -0
  137. package/dist/commands/keys.cjs +255 -0
  138. package/dist/commands/keys.cjs.map +1 -0
  139. package/dist/commands/keys.mjs +253 -0
  140. package/dist/commands/keys.mjs.map +1 -0
  141. package/dist/commands/ops.cjs +199 -0
  142. package/dist/commands/ops.cjs.map +1 -0
  143. package/dist/commands/ops.mjs +197 -0
  144. package/dist/commands/ops.mjs.map +1 -0
  145. package/dist/commands/plugins.cjs +211 -0
  146. package/dist/commands/plugins.cjs.map +1 -0
  147. package/dist/commands/plugins.mjs +211 -0
  148. package/dist/commands/plugins.mjs.map +1 -0
  149. package/dist/commands/shared.cjs +8 -0
  150. package/dist/commands/shared.cjs.map +1 -0
  151. package/dist/commands/shared.d.cts +6 -0
  152. package/dist/commands/shared.d.mts +6 -0
  153. package/dist/commands/shared.mjs +8 -0
  154. package/dist/commands/shared.mjs.map +1 -0
  155. package/dist/commands/upgrade.cjs +325 -0
  156. package/dist/commands/upgrade.cjs.map +1 -0
  157. package/dist/commands/upgrade.mjs +323 -0
  158. package/dist/commands/upgrade.mjs.map +1 -0
  159. package/dist/components/dev-render.cjs +340 -0
  160. package/dist/components/dev-render.cjs.map +1 -0
  161. package/dist/components/dev-render.mjs +332 -0
  162. package/dist/components/dev-render.mjs.map +1 -0
  163. package/dist/config.cjs +460 -221
  164. package/dist/config.cjs.map +1 -1
  165. package/dist/config.d.cts +491 -48
  166. package/dist/config.d.mts +491 -48
  167. package/dist/config.mjs +439 -212
  168. package/dist/config.mjs.map +1 -1
  169. package/dist/contract.cjs +327 -50
  170. package/dist/contract.cjs.map +1 -1
  171. package/dist/contract.d.cts +1951 -1062
  172. package/dist/contract.d.mts +1951 -1062
  173. package/dist/contract.meta.cjs +107 -12
  174. package/dist/contract.meta.cjs.map +1 -1
  175. package/dist/contract.meta.d.cts +166 -8
  176. package/dist/contract.meta.d.mts +166 -8
  177. package/dist/contract.meta.mjs +107 -11
  178. package/dist/contract.meta.mjs.map +1 -1
  179. package/dist/contract.mjs +580 -327
  180. package/dist/contract.mjs.map +1 -1
  181. package/dist/dag.cjs +5 -3
  182. package/dist/dag.cjs.map +1 -1
  183. package/dist/dag.mjs +6 -3
  184. package/dist/dag.mjs.map +1 -1
  185. package/dist/db/binding.cjs +80 -0
  186. package/dist/db/binding.cjs.map +1 -0
  187. package/dist/db/binding.d.cts +39 -0
  188. package/dist/db/binding.d.mts +39 -0
  189. package/dist/db/binding.mjs +78 -0
  190. package/dist/db/binding.mjs.map +1 -0
  191. package/dist/db/bindings.cjs +78 -0
  192. package/dist/db/bindings.cjs.map +1 -0
  193. package/dist/db/bindings.d.cts +34 -0
  194. package/dist/db/bindings.d.mts +34 -0
  195. package/dist/db/bindings.mjs +76 -0
  196. package/dist/db/bindings.mjs.map +1 -0
  197. package/dist/db/core.cjs +204 -0
  198. package/dist/db/core.cjs.map +1 -0
  199. package/dist/db/core.d.cts +69 -0
  200. package/dist/db/core.d.mts +69 -0
  201. package/dist/db/core.mjs +192 -0
  202. package/dist/db/core.mjs.map +1 -0
  203. package/dist/db/driver.cjs +167 -0
  204. package/dist/db/driver.cjs.map +1 -0
  205. package/dist/db/driver.d.cts +50 -0
  206. package/dist/db/driver.d.mts +50 -0
  207. package/dist/db/driver.mjs +165 -0
  208. package/dist/db/driver.mjs.map +1 -0
  209. package/dist/db/drizzle-kit.cjs +177 -0
  210. package/dist/db/drizzle-kit.cjs.map +1 -0
  211. package/dist/db/drizzle-kit.d.cts +25 -0
  212. package/dist/db/drizzle-kit.d.mts +25 -0
  213. package/dist/db/drizzle-kit.mjs +175 -0
  214. package/dist/db/drizzle-kit.mjs.map +1 -0
  215. package/dist/db/errors.cjs +27 -0
  216. package/dist/db/errors.cjs.map +1 -0
  217. package/dist/db/errors.d.cts +16 -0
  218. package/dist/db/errors.d.mts +16 -0
  219. package/dist/db/errors.mjs +26 -0
  220. package/dist/db/errors.mjs.map +1 -0
  221. package/dist/db/identity.cjs +55 -0
  222. package/dist/db/identity.cjs.map +1 -0
  223. package/dist/db/identity.d.cts +40 -0
  224. package/dist/db/identity.d.mts +40 -0
  225. package/dist/db/identity.mjs +53 -0
  226. package/dist/db/identity.mjs.map +1 -0
  227. package/dist/db/index.cjs +43 -0
  228. package/dist/db/index.d.cts +9 -0
  229. package/dist/db/index.d.mts +9 -0
  230. package/dist/db/index.mjs +10 -0
  231. package/dist/db/run-migrations.cjs +343 -0
  232. package/dist/db/run-migrations.cjs.map +1 -0
  233. package/dist/db/run-migrations.d.cts +87 -0
  234. package/dist/db/run-migrations.d.mts +87 -0
  235. package/dist/db/run-migrations.mjs +341 -0
  236. package/dist/db/run-migrations.mjs.map +1 -0
  237. package/dist/delegate-signer.cjs +85 -0
  238. package/dist/delegate-signer.cjs.map +1 -0
  239. package/dist/delegate-signer.mjs +84 -0
  240. package/dist/delegate-signer.mjs.map +1 -0
  241. package/dist/deploy-diff.cjs +119 -0
  242. package/dist/deploy-diff.cjs.map +1 -0
  243. package/dist/deploy-diff.mjs +109 -0
  244. package/dist/deploy-diff.mjs.map +1 -0
  245. package/dist/descriptor/constructors.cjs +49 -0
  246. package/dist/descriptor/constructors.cjs.map +1 -0
  247. package/dist/descriptor/constructors.d.cts +27 -0
  248. package/dist/descriptor/constructors.d.mts +27 -0
  249. package/dist/descriptor/constructors.mjs +45 -0
  250. package/dist/descriptor/constructors.mjs.map +1 -0
  251. package/dist/descriptor/index.cjs +24 -0
  252. package/dist/descriptor/index.d.cts +5 -0
  253. package/dist/descriptor/index.d.mts +5 -0
  254. package/dist/descriptor/index.mjs +6 -0
  255. package/dist/descriptor/resolve.cjs +258 -0
  256. package/dist/descriptor/resolve.cjs.map +1 -0
  257. package/dist/descriptor/resolve.d.cts +50 -0
  258. package/dist/descriptor/resolve.d.mts +50 -0
  259. package/dist/descriptor/resolve.mjs +252 -0
  260. package/dist/descriptor/resolve.mjs.map +1 -0
  261. package/dist/descriptor/schema.cjs +109 -0
  262. package/dist/descriptor/schema.cjs.map +1 -0
  263. package/dist/descriptor/schema.d.cts +217 -0
  264. package/dist/descriptor/schema.d.mts +217 -0
  265. package/dist/descriptor/schema.mjs +102 -0
  266. package/dist/descriptor/schema.mjs.map +1 -0
  267. package/dist/descriptor/serialize.cjs +45 -0
  268. package/dist/descriptor/serialize.cjs.map +1 -0
  269. package/dist/descriptor/serialize.d.cts +7 -0
  270. package/dist/descriptor/serialize.d.mts +7 -0
  271. package/dist/descriptor/serialize.mjs +45 -0
  272. package/dist/descriptor/serialize.mjs.map +1 -0
  273. package/dist/dev-log-pipeline.cjs +273 -0
  274. package/dist/dev-log-pipeline.cjs.map +1 -0
  275. package/dist/dev-log-pipeline.mjs +267 -0
  276. package/dist/dev-log-pipeline.mjs.map +1 -0
  277. package/dist/dev-logs.cjs +39 -8
  278. package/dist/dev-logs.cjs.map +1 -1
  279. package/dist/dev-logs.mjs +37 -9
  280. package/dist/dev-logs.mjs.map +1 -1
  281. package/dist/dev-program.cjs +405 -0
  282. package/dist/dev-program.cjs.map +1 -0
  283. package/dist/dev-program.d.cts +10 -0
  284. package/dist/dev-program.d.mts +10 -0
  285. package/dist/dev-program.mjs +395 -0
  286. package/dist/dev-program.mjs.map +1 -0
  287. package/dist/dev-session-data.d.cts +27 -0
  288. package/dist/dev-session-data.d.mts +27 -0
  289. package/dist/dev-session.cjs +178 -105
  290. package/dist/dev-session.cjs.map +1 -1
  291. package/dist/dev-session.mjs +180 -105
  292. package/dist/dev-session.mjs.map +1 -1
  293. package/dist/env/process-env.cjs +16 -0
  294. package/dist/env/process-env.cjs.map +1 -0
  295. package/dist/env/process-env.mjs +13 -0
  296. package/dist/env/process-env.mjs.map +1 -0
  297. package/dist/env/project-env.cjs +144 -0
  298. package/dist/env/project-env.cjs.map +1 -0
  299. package/dist/env/project-env.d.cts +1 -0
  300. package/dist/env/project-env.d.mts +1 -0
  301. package/dist/env/project-env.mjs +132 -0
  302. package/dist/env/project-env.mjs.map +1 -0
  303. package/dist/fastkv.cjs +59 -12
  304. package/dist/fastkv.cjs.map +1 -1
  305. package/dist/fastkv.d.cts +42 -6
  306. package/dist/fastkv.d.mts +42 -6
  307. package/dist/fastkv.mjs +58 -13
  308. package/dist/fastkv.mjs.map +1 -1
  309. package/dist/fingerprint.cjs +57 -0
  310. package/dist/fingerprint.cjs.map +1 -0
  311. package/dist/fingerprint.d.cts +14 -0
  312. package/dist/fingerprint.d.mts +14 -0
  313. package/dist/fingerprint.mjs +55 -0
  314. package/dist/fingerprint.mjs.map +1 -0
  315. package/dist/http-client.cjs +17 -17
  316. package/dist/http-client.cjs.map +1 -1
  317. package/dist/http-client.mjs +17 -17
  318. package/dist/http-client.mjs.map +1 -1
  319. package/dist/image-deploy.cjs +186 -0
  320. package/dist/image-deploy.cjs.map +1 -0
  321. package/dist/image-deploy.mjs +182 -0
  322. package/dist/image-deploy.mjs.map +1 -0
  323. package/dist/index.cjs +66 -18
  324. package/dist/index.d.cts +8 -7
  325. package/dist/index.d.mts +8 -7
  326. package/dist/index.mjs +6 -5
  327. package/dist/infra/docker.cjs +77 -0
  328. package/dist/infra/docker.cjs.map +1 -0
  329. package/dist/infra/docker.d.cts +10 -0
  330. package/dist/infra/docker.d.mts +10 -0
  331. package/dist/infra/docker.mjs +69 -0
  332. package/dist/infra/docker.mjs.map +1 -0
  333. package/dist/infra/materializer.cjs +74 -0
  334. package/dist/infra/materializer.cjs.map +1 -0
  335. package/dist/infra/materializer.mjs +70 -0
  336. package/dist/infra/materializer.mjs.map +1 -0
  337. package/dist/infra/planner.cjs +135 -103
  338. package/dist/infra/planner.cjs.map +1 -1
  339. package/dist/infra/planner.mjs +137 -104
  340. package/dist/infra/planner.mjs.map +1 -1
  341. package/dist/infra/port-ownership.cjs +57 -0
  342. package/dist/infra/port-ownership.cjs.map +1 -0
  343. package/dist/infra/port-ownership.mjs +57 -0
  344. package/dist/infra/port-ownership.mjs.map +1 -0
  345. package/dist/infra/preflight.cjs +45 -33
  346. package/dist/infra/preflight.cjs.map +1 -1
  347. package/dist/infra/preflight.d.cts +1 -0
  348. package/dist/infra/preflight.d.mts +1 -0
  349. package/dist/infra/preflight.mjs +46 -34
  350. package/dist/infra/preflight.mjs.map +1 -1
  351. package/dist/infra/types.cjs.map +1 -1
  352. package/dist/infra/types.d.cts +2 -0
  353. package/dist/infra/types.d.mts +2 -0
  354. package/dist/infra/types.mjs.map +1 -1
  355. package/dist/integrity.cjs +50 -61
  356. package/dist/integrity.cjs.map +1 -1
  357. package/dist/integrity.d.cts +16 -10
  358. package/dist/integrity.d.mts +16 -10
  359. package/dist/integrity.mjs +50 -59
  360. package/dist/integrity.mjs.map +1 -1
  361. package/dist/internal/manifest-normalizer.cjs +8 -2
  362. package/dist/internal/manifest-normalizer.cjs.map +1 -1
  363. package/dist/internal/manifest-normalizer.mjs +9 -3
  364. package/dist/internal/manifest-normalizer.mjs.map +1 -1
  365. package/dist/merge.cjs +19 -1
  366. package/dist/merge.cjs.map +1 -1
  367. package/dist/merge.d.cts +1 -1
  368. package/dist/merge.d.mts +1 -1
  369. package/dist/merge.mjs +19 -2
  370. package/dist/merge.mjs.map +1 -1
  371. package/dist/mf.cjs +190 -3
  372. package/dist/mf.cjs.map +1 -1
  373. package/dist/mf.d.cts +24 -2
  374. package/dist/mf.d.mts +24 -2
  375. package/dist/mf.mjs +189 -4
  376. package/dist/mf.mjs.map +1 -1
  377. package/dist/near-cli.cjs +59 -91
  378. package/dist/near-cli.cjs.map +1 -1
  379. package/dist/near-cli.mjs +58 -90
  380. package/dist/near-cli.mjs.map +1 -1
  381. package/dist/near-signer.cjs +73 -0
  382. package/dist/near-signer.cjs.map +1 -0
  383. package/dist/near-signer.mjs +70 -0
  384. package/dist/near-signer.mjs.map +1 -0
  385. package/dist/network.cjs +0 -1
  386. package/dist/network.cjs.map +1 -1
  387. package/dist/orchestrator.cjs +256 -87
  388. package/dist/orchestrator.cjs.map +1 -1
  389. package/dist/orchestrator.mjs +248 -87
  390. package/dist/orchestrator.mjs.map +1 -1
  391. package/dist/platform-deploy.cjs +81 -0
  392. package/dist/platform-deploy.cjs.map +1 -0
  393. package/dist/platform-deploy.mjs +80 -0
  394. package/dist/platform-deploy.mjs.map +1 -0
  395. package/dist/plugin.cjs +54 -1389
  396. package/dist/plugin.cjs.map +1 -1
  397. package/dist/plugin.d.cts +6 -896
  398. package/dist/plugin.d.mts +6 -896
  399. package/dist/plugin.mjs +53 -1387
  400. package/dist/plugin.mjs.map +1 -1
  401. package/dist/process-kill.cjs +44 -0
  402. package/dist/process-kill.cjs.map +1 -0
  403. package/dist/process-kill.mjs +43 -0
  404. package/dist/process-kill.mjs.map +1 -0
  405. package/dist/process-registry.cjs +64 -9
  406. package/dist/process-registry.cjs.map +1 -1
  407. package/dist/process-registry.mjs +61 -10
  408. package/dist/process-registry.mjs.map +1 -1
  409. package/dist/progress.cjs +45 -0
  410. package/dist/progress.cjs.map +1 -0
  411. package/dist/progress.d.cts +13 -0
  412. package/dist/progress.d.mts +13 -0
  413. package/dist/progress.mjs +42 -0
  414. package/dist/progress.mjs.map +1 -0
  415. package/dist/publish.cjs +513 -79
  416. package/dist/publish.cjs.map +1 -1
  417. package/dist/publish.mjs +515 -82
  418. package/dist/publish.mjs.map +1 -1
  419. package/dist/registry-use.cjs +41 -0
  420. package/dist/registry-use.cjs.map +1 -0
  421. package/dist/registry-use.mjs +40 -0
  422. package/dist/registry-use.mjs.map +1 -0
  423. package/dist/resolution/session.cjs +335 -0
  424. package/dist/resolution/session.cjs.map +1 -0
  425. package/dist/resolution/session.d.cts +105 -0
  426. package/dist/resolution/session.d.mts +105 -0
  427. package/dist/resolution/session.mjs +331 -0
  428. package/dist/resolution/session.mjs.map +1 -0
  429. package/dist/rollback.cjs +131 -0
  430. package/dist/rollback.cjs.map +1 -0
  431. package/dist/rollback.mjs +128 -0
  432. package/dist/rollback.mjs.map +1 -0
  433. package/dist/sdk.cjs +7 -7
  434. package/dist/sdk.d.cts +3 -3
  435. package/dist/sdk.d.mts +3 -3
  436. package/dist/sdk.mjs +2 -2
  437. package/dist/service-descriptor.cjs +67 -34
  438. package/dist/service-descriptor.cjs.map +1 -1
  439. package/dist/service-descriptor.d.cts +4 -1
  440. package/dist/service-descriptor.d.mts +3 -0
  441. package/dist/service-descriptor.mjs +63 -35
  442. package/dist/service-descriptor.mjs.map +1 -1
  443. package/dist/shared-deps.cjs +17 -16
  444. package/dist/shared-deps.cjs.map +1 -1
  445. package/dist/shared-deps.mjs +17 -16
  446. package/dist/shared-deps.mjs.map +1 -1
  447. package/dist/start-config-source.cjs +24 -0
  448. package/dist/start-config-source.cjs.map +1 -0
  449. package/dist/start-config-source.d.cts +29 -0
  450. package/dist/start-config-source.d.mts +29 -0
  451. package/dist/start-config-source.mjs +22 -0
  452. package/dist/start-config-source.mjs.map +1 -0
  453. package/dist/storage-upload.cjs +145 -0
  454. package/dist/storage-upload.cjs.map +1 -0
  455. package/dist/storage-upload.mjs +143 -0
  456. package/dist/storage-upload.mjs.map +1 -0
  457. package/dist/types.cjs +126 -20
  458. package/dist/types.cjs.map +1 -1
  459. package/dist/types.d.cts +867 -585
  460. package/dist/types.d.mts +867 -585
  461. package/dist/types.mjs +307 -208
  462. package/dist/types.mjs.map +1 -1
  463. package/dist/ui/api.cjs +105 -0
  464. package/dist/ui/api.cjs.map +1 -0
  465. package/dist/ui/api.d.cts +31 -0
  466. package/dist/ui/api.d.mts +31 -0
  467. package/dist/ui/api.mjs +99 -0
  468. package/dist/ui/api.mjs.map +1 -0
  469. package/dist/ui/auth-guards.cjs +50 -0
  470. package/dist/ui/auth-guards.cjs.map +1 -0
  471. package/dist/ui/auth-guards.d.cts +39 -0
  472. package/dist/ui/auth-guards.d.mts +39 -0
  473. package/dist/ui/auth-guards.mjs +48 -0
  474. package/dist/ui/auth-guards.mjs.map +1 -0
  475. package/dist/ui/auth.cjs +197 -0
  476. package/dist/ui/auth.cjs.map +1 -0
  477. package/dist/ui/auth.d.cts +56 -0
  478. package/dist/ui/auth.d.mts +56 -0
  479. package/dist/ui/auth.mjs +179 -0
  480. package/dist/ui/auth.mjs.map +1 -0
  481. package/dist/ui/entry.cjs +16 -0
  482. package/dist/ui/entry.cjs.map +1 -0
  483. package/dist/ui/entry.d.cts +12 -0
  484. package/dist/ui/entry.d.mts +12 -0
  485. package/dist/ui/entry.mjs +15 -0
  486. package/dist/ui/entry.mjs.map +1 -0
  487. package/dist/ui/head.cjs +14 -7
  488. package/dist/ui/head.cjs.map +1 -1
  489. package/dist/ui/head.mjs +15 -7
  490. package/dist/ui/head.mjs.map +1 -1
  491. package/dist/ui/hydrate.cjs +265 -0
  492. package/dist/ui/hydrate.cjs.map +1 -0
  493. package/dist/ui/hydrate.d.cts +48 -0
  494. package/dist/ui/hydrate.d.mts +48 -0
  495. package/dist/ui/hydrate.mjs +263 -0
  496. package/dist/ui/hydrate.mjs.map +1 -0
  497. package/dist/ui/i18n.cjs +153 -0
  498. package/dist/ui/i18n.cjs.map +1 -0
  499. package/dist/ui/i18n.d.cts +29 -0
  500. package/dist/ui/i18n.d.mts +29 -0
  501. package/dist/ui/i18n.mjs +140 -0
  502. package/dist/ui/i18n.mjs.map +1 -0
  503. package/dist/ui/index.cjs +19 -1
  504. package/dist/ui/index.d.cts +6 -3
  505. package/dist/ui/index.d.mts +6 -3
  506. package/dist/ui/index.mjs +5 -2
  507. package/dist/ui/locale.cjs +53 -0
  508. package/dist/ui/locale.cjs.map +1 -0
  509. package/dist/ui/locale.d.cts +18 -0
  510. package/dist/ui/locale.d.mts +18 -0
  511. package/dist/ui/locale.mjs +49 -0
  512. package/dist/ui/locale.mjs.map +1 -0
  513. package/dist/ui/manifest/index.cjs +25 -0
  514. package/dist/ui/manifest/index.cjs.map +1 -0
  515. package/dist/ui/manifest/index.d.cts +9 -0
  516. package/dist/ui/manifest/index.d.mts +9 -0
  517. package/dist/ui/manifest/index.mjs +13 -0
  518. package/dist/ui/manifest/index.mjs.map +1 -0
  519. package/dist/ui/manifest-generator.cjs +8 -0
  520. package/dist/ui/manifest-generator.d.cts +1 -0
  521. package/dist/ui/manifest-generator.d.mts +1 -0
  522. package/dist/ui/manifest-generator.mjs +3 -0
  523. package/dist/ui/message-catalogs.cjs +8 -0
  524. package/dist/ui/message-catalogs.cjs.map +1 -0
  525. package/dist/ui/message-catalogs.d.cts +5 -0
  526. package/dist/ui/message-catalogs.d.mts +5 -0
  527. package/dist/ui/message-catalogs.mjs +8 -0
  528. package/dist/ui/message-catalogs.mjs.map +1 -0
  529. package/dist/ui/metadata.cjs +0 -1
  530. package/dist/ui/metadata.cjs.map +1 -1
  531. package/dist/ui/metadata.d.cts +1 -1
  532. package/dist/ui/metadata.d.mts +1 -1
  533. package/dist/ui/plugin-path.cjs +37 -0
  534. package/dist/ui/plugin-path.cjs.map +1 -0
  535. package/dist/ui/plugin-path.d.cts +25 -0
  536. package/dist/ui/plugin-path.d.mts +25 -0
  537. package/dist/ui/plugin-path.mjs +35 -0
  538. package/dist/ui/plugin-path.mjs.map +1 -0
  539. package/dist/ui/router-client.cjs +61 -0
  540. package/dist/ui/router-client.cjs.map +1 -0
  541. package/dist/ui/router-client.d.cts +20 -0
  542. package/dist/ui/router-client.d.mts +20 -0
  543. package/dist/ui/router-client.mjs +60 -0
  544. package/dist/ui/router-client.mjs.map +1 -0
  545. package/dist/ui/router-defaults.cjs +48 -0
  546. package/dist/ui/router-defaults.cjs.map +1 -0
  547. package/dist/ui/router-defaults.d.cts +8 -0
  548. package/dist/ui/router-defaults.d.mts +8 -0
  549. package/dist/ui/router-defaults.mjs +45 -0
  550. package/dist/ui/router-defaults.mjs.map +1 -0
  551. package/dist/ui/router-error.cjs +70 -0
  552. package/dist/ui/router-error.cjs.map +1 -0
  553. package/dist/ui/router-error.d.cts +19 -0
  554. package/dist/ui/router-error.d.mts +19 -0
  555. package/dist/ui/router-error.mjs +69 -0
  556. package/dist/ui/router-error.mjs.map +1 -0
  557. package/dist/ui/router-server.cjs +153 -0
  558. package/dist/ui/router-server.cjs.map +1 -0
  559. package/dist/ui/router-server.d.cts +38 -0
  560. package/dist/ui/router-server.d.mts +38 -0
  561. package/dist/ui/router-server.mjs +152 -0
  562. package/dist/ui/router-server.mjs.map +1 -0
  563. package/dist/ui/router.cjs +4 -16
  564. package/dist/ui/router.cjs.map +1 -1
  565. package/dist/ui/router.mjs +4 -15
  566. package/dist/ui/router.mjs.map +1 -1
  567. package/dist/ui/runtime.cjs +5 -1
  568. package/dist/ui/runtime.cjs.map +1 -1
  569. package/dist/ui/runtime.d.cts +2 -1
  570. package/dist/ui/runtime.d.mts +2 -1
  571. package/dist/ui/runtime.mjs +5 -1
  572. package/dist/ui/runtime.mjs.map +1 -1
  573. package/dist/ui/slot.cjs +34 -0
  574. package/dist/ui/slot.cjs.map +1 -0
  575. package/dist/ui/slot.d.cts +43 -0
  576. package/dist/ui/slot.d.mts +43 -0
  577. package/dist/ui/slot.mjs +34 -0
  578. package/dist/ui/slot.mjs.map +1 -0
  579. package/dist/ui/tenant.cjs +300 -0
  580. package/dist/ui/tenant.cjs.map +1 -0
  581. package/dist/ui/tenant.d.cts +122 -0
  582. package/dist/ui/tenant.d.mts +122 -0
  583. package/dist/ui/tenant.mjs +279 -0
  584. package/dist/ui/tenant.mjs.map +1 -0
  585. package/dist/ui/types.d.cts +32 -2
  586. package/dist/ui/types.d.mts +32 -2
  587. package/dist/ui/version-check.cjs +47 -0
  588. package/dist/ui/version-check.cjs.map +1 -0
  589. package/dist/ui/version-check.d.cts +23 -0
  590. package/dist/ui/version-check.d.mts +23 -0
  591. package/dist/ui/version-check.mjs +46 -0
  592. package/dist/ui/version-check.mjs.map +1 -0
  593. package/dist/utils/banner.cjs +2 -2
  594. package/dist/utils/banner.cjs.map +1 -1
  595. package/dist/utils/banner.mjs +2 -2
  596. package/dist/utils/banner.mjs.map +1 -1
  597. package/dist/utils/linkify.cjs +1 -1
  598. package/dist/utils/linkify.cjs.map +1 -1
  599. package/dist/utils/linkify.mjs +1 -0
  600. package/dist/utils/linkify.mjs.map +1 -1
  601. package/dist/utils/run.cjs +6 -6
  602. package/dist/utils/run.cjs.map +1 -1
  603. package/dist/utils/run.mjs +6 -6
  604. package/dist/utils/run.mjs.map +1 -1
  605. package/dist/utils/save-config.cjs +12 -0
  606. package/dist/utils/save-config.cjs.map +1 -1
  607. package/dist/utils/save-config.mjs +12 -0
  608. package/dist/utils/save-config.mjs.map +1 -1
  609. package/dist/utils/snapshot-hash.cjs +10 -0
  610. package/dist/utils/snapshot-hash.cjs.map +1 -0
  611. package/dist/utils/snapshot-hash.mjs +10 -0
  612. package/dist/utils/snapshot-hash.mjs.map +1 -0
  613. package/dist/utils/string.cjs +0 -1
  614. package/dist/utils/string.cjs.map +1 -1
  615. package/dist/utils/theme.cjs +30 -12
  616. package/dist/utils/theme.cjs.map +1 -1
  617. package/dist/utils/theme.mjs +30 -11
  618. package/dist/utils/theme.mjs.map +1 -1
  619. package/dist/version-manifest-deploy.cjs +50 -0
  620. package/dist/version-manifest-deploy.cjs.map +1 -0
  621. package/dist/version-manifest-deploy.mjs +49 -0
  622. package/dist/version-manifest-deploy.mjs.map +1 -0
  623. package/dist/version-manifest-resolve.cjs +42 -0
  624. package/dist/version-manifest-resolve.cjs.map +1 -0
  625. package/dist/version-manifest-resolve.d.cts +38 -0
  626. package/dist/version-manifest-resolve.d.mts +38 -0
  627. package/dist/version-manifest-resolve.mjs +40 -0
  628. package/dist/version-manifest-resolve.mjs.map +1 -0
  629. package/dist/version-status.cjs +18 -0
  630. package/dist/version-status.cjs.map +1 -0
  631. package/dist/version-status.d.cts +22 -0
  632. package/dist/version-status.d.mts +22 -0
  633. package/dist/version-status.mjs +17 -0
  634. package/dist/version-status.mjs.map +1 -0
  635. package/dist/workspace-catalog.cjs +53 -0
  636. package/dist/workspace-catalog.cjs.map +1 -0
  637. package/dist/workspace-catalog.mjs +51 -0
  638. package/dist/workspace-catalog.mjs.map +1 -0
  639. package/dist/workspace.cjs +237 -0
  640. package/dist/workspace.cjs.map +1 -0
  641. package/dist/workspace.mjs +233 -0
  642. package/dist/workspace.mjs.map +1 -0
  643. package/package.json +179 -27
  644. package/skills/add-a-route/SKILL.md +132 -0
  645. package/skills/api-and-auth/SKILL.md +87 -21
  646. package/skills/api-and-auth/references/middleware.md +1 -1
  647. package/skills/cli-reference/SKILL.md +48 -21
  648. package/skills/code-style/SKILL.md +8 -0
  649. package/skills/dev-workflow/SKILL.md +50 -26
  650. package/skills/extends-config/SKILL.md +31 -19
  651. package/skills/init-upgrade/SKILL.md +29 -16
  652. package/skills/plugin-development/SKILL.md +46 -112
  653. package/skills/plugin-development/references/database.md +82 -0
  654. package/skills/plugin-development/references/request-context.md +67 -0
  655. package/skills/publish-sync/SKILL.md +99 -22
  656. package/skills/registry/SKILL.md +82 -0
  657. package/skills/super-app/SKILL.md +25 -15
  658. package/skills/talk-to-the-app/SKILL.md +138 -0
  659. package/skills/ui-integration/SKILL.md +93 -11
  660. package/dist/cli/db-studio.cjs +0 -131
  661. package/dist/cli/db-studio.cjs.map +0 -1
  662. package/dist/cli/db-studio.mjs +0 -127
  663. package/dist/cli/db-studio.mjs.map +0 -1
  664. package/dist/cli/init.d.cts.map +0 -1
  665. package/dist/cli/init.d.mts.map +0 -1
  666. package/dist/components/dev-view.cjs +0 -309
  667. package/dist/components/dev-view.cjs.map +0 -1
  668. package/dist/components/dev-view.mjs +0 -309
  669. package/dist/components/dev-view.mjs.map +0 -1
  670. package/dist/components/streaming-view.cjs +0 -134
  671. package/dist/components/streaming-view.cjs.map +0 -1
  672. package/dist/components/streaming-view.mjs +0 -132
  673. package/dist/components/streaming-view.mjs.map +0 -1
  674. package/dist/config.d.cts.map +0 -1
  675. package/dist/config.d.mts.map +0 -1
  676. package/dist/contract.d.cts.map +0 -1
  677. package/dist/contract.d.mts.map +0 -1
  678. package/dist/contract.meta.d.cts.map +0 -1
  679. package/dist/contract.meta.d.mts.map +0 -1
  680. package/dist/dag.d.cts.map +0 -1
  681. package/dist/dag.d.mts.map +0 -1
  682. package/dist/db.cjs +0 -81
  683. package/dist/db.cjs.map +0 -1
  684. package/dist/db.d.cts +0 -30
  685. package/dist/db.d.cts.map +0 -1
  686. package/dist/db.d.mts +0 -30
  687. package/dist/db.d.mts.map +0 -1
  688. package/dist/db.mjs +0 -75
  689. package/dist/db.mjs.map +0 -1
  690. package/dist/fastkv.d.cts.map +0 -1
  691. package/dist/fastkv.d.mts.map +0 -1
  692. package/dist/integrity.d.cts.map +0 -1
  693. package/dist/integrity.d.mts.map +0 -1
  694. package/dist/merge.d.cts.map +0 -1
  695. package/dist/merge.d.mts.map +0 -1
  696. package/dist/mf.d.cts.map +0 -1
  697. package/dist/mf.d.mts.map +0 -1
  698. package/dist/plugin.d.cts.map +0 -1
  699. package/dist/plugin.d.mts.map +0 -1
  700. package/dist/service-descriptor.d.cts.map +0 -1
  701. package/dist/service-descriptor.d.mts.map +0 -1
  702. package/dist/types.d.cts.map +0 -1
  703. package/dist/types.d.mts.map +0 -1
  704. package/dist/ui/head.d.cts.map +0 -1
  705. package/dist/ui/head.d.mts.map +0 -1
  706. package/dist/ui/metadata.d.cts.map +0 -1
  707. package/dist/ui/metadata.d.mts.map +0 -1
  708. package/dist/ui/router.d.cts.map +0 -1
  709. package/dist/ui/router.d.mts.map +0 -1
  710. package/dist/ui/runtime.d.cts.map +0 -1
  711. package/dist/ui/runtime.d.mts.map +0 -1
  712. package/dist/ui/types.d.cts.map +0 -1
  713. package/dist/ui/types.d.mts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"integrity.cjs","names":["fetchResponse","fetchBosConfigFromFastKv"],"sources":["../src/integrity.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { fetchBosConfigFromFastKv } from \"./fastkv\";\nimport { fetchResponse } from \"./http-client\";\n\nconst DEFAULT_MAX_SRI_RESPONSE_BYTES = 20 * 1024 * 1024;\n\ninterface SriUrlOptions {\n resolveEntryUrl?: boolean;\n maxBytes?: number;\n}\n\nexport function computeSriHash(content: string | Buffer): string {\n return `sha384-${createHash(\"sha384\").update(content).digest(\"base64\")}`;\n}\n\nfunction resolveSriTargetUrl(url: string, options?: SriUrlOptions): string {\n return options?.resolveEntryUrl === false ? url : resolveEntryUrl(url);\n}\n\nfunction getMaxSriResponseBytes(options?: SriUrlOptions): number {\n return options?.maxBytes ?? DEFAULT_MAX_SRI_RESPONSE_BYTES;\n}\n\nasync function computeSriHashFromResponse(\n response: Response,\n url: string,\n options?: SriUrlOptions,\n): Promise<string> {\n const maxBytes = getMaxSriResponseBytes(options);\n const contentLengthHeader = response.headers.get(\"content-length\");\n\n if (contentLengthHeader) {\n const contentLength = Number(contentLengthHeader);\n if (Number.isFinite(contentLength) && contentLength > maxBytes) {\n throw new Error(\n `[SRI] Response for ${url} exceeds max size of ${maxBytes} bytes (${contentLength})`,\n );\n }\n }\n\n if (!response.body) {\n throw new Error(`[SRI] Missing response body for ${url}`);\n }\n\n const hash = createHash(\"sha384\");\n const reader = response.body.getReader();\n let totalBytes = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n\n totalBytes += value.byteLength;\n if (totalBytes > maxBytes) {\n await reader.cancel();\n throw new Error(\n `[SRI] Response for ${url} exceeds max size of ${maxBytes} bytes (${totalBytes})`,\n );\n }\n\n hash.update(value);\n }\n\n return `sha384-${hash.digest(\"base64\")}`;\n}\n\nexport async function computeSriHashForUrl(\n url: string,\n options?: SriUrlOptions,\n): Promise<string | null> {\n try {\n const entryUrl = resolveSriTargetUrl(url, options);\n\n const response = await fetchResponse(entryUrl, { timeout: \"30 seconds\" });\n if (!response.ok) {\n console.warn(`[SRI] Failed to fetch ${entryUrl}: ${response.status} ${response.statusText}`);\n return null;\n }\n return await computeSriHashFromResponse(response, entryUrl, options);\n } catch (error) {\n console.warn(\n `[SRI] Error computing integrity for ${url}:`,\n error instanceof Error ? error.message : error,\n );\n return null;\n }\n}\n\nexport function resolveEntryUrl(url: string): string {\n if (url.endsWith(\"/remoteEntry.js\")) return url;\n if (url.endsWith(\"/mf-manifest.json\"))\n return `${url.replace(/\\/mf-manifest\\.json$/, \"\")}/remoteEntry.js`;\n return `${url.replace(/\\/$/, \"\")}/remoteEntry.js`;\n}\n\nexport async function verifySriForUrl(\n url: string,\n expectedIntegrity: string,\n options?: SriUrlOptions,\n): Promise<void> {\n const entryUrl = resolveSriTargetUrl(url, options);\n\n const response = await fetchResponse(entryUrl, { timeout: \"30 seconds\" });\n if (!response.ok) {\n console.warn(`[SRI] Failed to fetch ${entryUrl} for verification: ${response.status}`);\n return;\n }\n\n const computed = await computeSriHashFromResponse(response, entryUrl, options);\n\n if (computed !== expectedIntegrity) {\n throw new Error(\n `[SRI] Integrity check failed for ${entryUrl}\\n Expected: ${expectedIntegrity}\\n Computed: ${computed}`,\n );\n }\n}\n\nexport class IntegrityRegistry {\n private hashes = new Map<string, string>();\n\n register(url: string, integrity: string): void {\n this.hashes.set(url, integrity);\n }\n\n registerEntry(baseUrl: string, integrity: string): void {\n this.hashes.set(resolveEntryUrl(baseUrl), integrity);\n }\n\n get(url: string): string | undefined {\n return this.hashes.get(url);\n }\n\n has(url: string): boolean {\n return this.hashes.has(url);\n }\n\n entries(): IterableIterator<[string, string]> {\n return this.hashes.entries();\n }\n}\n\nfunction extractIntegrityHashes(config: Record<string, unknown>): Map<string, string> {\n const hashes = new Map<string, string>();\n const app = config.app as Record<string, Record<string, unknown>> | undefined;\n const plugins = config.plugins as Record<string, Record<string, unknown>> | undefined;\n\n if (app) {\n for (const [, entry] of Object.entries(app)) {\n if (entry?.integrity && entry?.production) {\n hashes.set(resolveEntryUrl(entry.production as string), entry.integrity as string);\n }\n }\n }\n\n if (plugins) {\n for (const [, entry] of Object.entries(plugins)) {\n if (entry?.integrity && entry?.production) {\n hashes.set(resolveEntryUrl(entry.production as string), entry.integrity as string);\n }\n }\n }\n\n return hashes;\n}\n\nexport async function verifyConfigAgainstChain(\n localConfig: Record<string, unknown>,\n bosUrl: string,\n): Promise<{ verified: boolean; mismatches: string[] }> {\n const mismatches: string[] = [];\n\n let chainConfig: Record<string, unknown>;\n try {\n chainConfig = await fetchBosConfigFromFastKv<Record<string, unknown>>(bosUrl);\n } catch (error) {\n console.warn(\n `[Attestation] Failed to fetch on-chain config: ${error instanceof Error ? error.message : String(error)}`,\n );\n return { verified: false, mismatches: [\"chain-fetch-failed\"] };\n }\n\n const localHashes = extractIntegrityHashes(localConfig);\n const chainHashes = extractIntegrityHashes(chainConfig);\n\n for (const [url, chainHash] of chainHashes) {\n const localHash = localHashes.get(url);\n if (localHash && localHash !== chainHash) {\n mismatches.push(url);\n console.error(\n `[Attestation] Integrity mismatch for ${url}\\n Local: ${localHash}\\n Chain: ${chainHash}`,\n );\n }\n }\n\n if (mismatches.length === 0 && localHashes.size > 0) {\n console.log(\n `[Attestation] Local config verified against on-chain anchor (${localHashes.size} entries checked)`,\n );\n }\n\n return { verified: mismatches.length === 0, mismatches };\n}\n\nexport interface DeployResultEntry {\n url: string;\n integrity?: string;\n urlField: string;\n integrityField?: string;\n}\n\nfunction setNestedPath(obj: Record<string, unknown>, dottedPath: string, value: unknown): void {\n const keys = dottedPath.split(\".\");\n let current = obj;\n for (let i = 0; i < keys.length - 1; i += 1) {\n const key = keys[i]!;\n if (current[key] === undefined || current[key] === null || typeof current[key] !== \"object\") {\n current[key] = {};\n }\n current = current[key] as Record<string, unknown>;\n }\n current[keys[keys.length - 1]!] = value;\n}\n\nfunction deleteNestedPath(obj: Record<string, unknown>, dottedPath: string): void {\n const keys = dottedPath.split(\".\");\n let current = obj;\n for (let i = 0; i < keys.length - 1; i += 1) {\n const key = keys[i]!;\n if (current[key] === undefined || typeof current[key] !== \"object\") return;\n current = current[key] as Record<string, unknown>;\n }\n delete current[keys[keys.length - 1]!];\n}\n\nexport function reportDeployResult(opts: {\n url: string;\n integrity?: string | null;\n bosConfigPath: string;\n urlField: string;\n integrityField?: string;\n}): void {\n console.log(\n `[BOS_DEPLOY] url=${opts.url} urlField=${opts.urlField} integrityField=${opts.integrityField ?? \"\"} integrity=${opts.integrity ?? \"\"}`,\n );\n\n try {\n const config = JSON.parse(readFileSync(opts.bosConfigPath, \"utf8\")) as Record<string, unknown>;\n setNestedPath(config, opts.urlField, opts.url);\n if (opts.integrityField) {\n if (opts.integrity) {\n setNestedPath(config, opts.integrityField, opts.integrity);\n } else {\n deleteNestedPath(config, opts.integrityField);\n }\n }\n writeFileSync(opts.bosConfigPath, `${JSON.stringify(config, null, 2)}\\n`);\n console.log(` ✅ Updated bos.config.json: ${opts.urlField}`);\n if (opts.integrityField && opts.integrity) {\n console.log(` ✅ Updated bos.config.json: ${opts.integrityField}`);\n }\n } catch (err) {\n console.error(\" ❌ Failed to update bos.config.json:\", (err as Error).message);\n }\n}\n\nexport function parseDeployLines(output: string): DeployResultEntry[] {\n const results: DeployResultEntry[] = [];\n for (const line of output.split(\"\\n\")) {\n if (!line.includes(\"[BOS_DEPLOY]\")) continue;\n const urlMatch = line.match(/url=(\\S+)/);\n const urlFieldMatch = line.match(/urlField=(\\S+)/);\n if (!urlMatch || !urlFieldMatch) continue;\n const integrityFieldMatch = line.match(/integrityField=(\\S+)/);\n const integrityMatch = line.match(/integrity=(\\S+)/);\n results.push({\n url: urlMatch[1],\n urlField: urlFieldMatch[1],\n integrityField: integrityFieldMatch?.[1] || undefined,\n integrity: integrityMatch?.[1] || undefined,\n });\n }\n return results;\n}\n\nexport function applyDeployResults(\n config: Record<string, unknown>,\n results: DeployResultEntry[],\n): Record<string, unknown> {\n const merged = structuredClone(config);\n for (const result of results) {\n setNestedPath(merged, result.urlField, result.url);\n if (result.integrityField) {\n if (result.integrity) {\n setNestedPath(merged, result.integrityField, result.integrity);\n } else {\n deleteNestedPath(merged, result.integrityField);\n }\n }\n }\n return merged;\n}\n\nexport function findPluginKey(bosConfigPath: string, pluginDir: string): string | null {\n const config = JSON.parse(readFileSync(bosConfigPath, \"utf8\")) as Record<string, unknown>;\n const plugins = config.plugins as Record<string, Record<string, unknown>> | undefined;\n if (!plugins) return null;\n const configRoot = join(bosConfigPath, \"..\");\n const normalizedPluginDir = pluginDir.replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\");\n for (const [key, plugin] of Object.entries(plugins)) {\n const dev = plugin?.development;\n if (typeof dev !== \"string\" || !dev.startsWith(\"local:\")) continue;\n const resolved = join(configRoot, dev.slice(\"local:\".length))\n .replace(/\\\\/g, \"/\")\n .replace(/\\/+$/, \"\");\n if (resolved === normalizedPluginDir) return key;\n }\n return null;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"integrity.cjs","names":["createHash","fetchResponse","Data","fetchBosConfigFromFastKv"],"sources":["../src/integrity.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { Data } from \"effect\";\nimport { fetchBosConfigFromFastKv } from \"./fastkv\";\nimport { fetchResponse } from \"./http-client\";\n\nconst DEFAULT_MAX_SRI_RESPONSE_BYTES = 20 * 1024 * 1024;\n\ninterface SriUrlOptions {\n resolveEntryUrl?: boolean;\n maxBytes?: number;\n}\n\nexport function computeSriHash(content: string | Buffer): string {\n return `sha384-${createHash(\"sha384\").update(content).digest(\"base64\")}`;\n}\n\nfunction resolveSriTargetUrl(url: string, options?: SriUrlOptions): string {\n return options?.resolveEntryUrl === false ? url : resolveEntryUrl(url);\n}\n\nfunction getMaxSriResponseBytes(options?: SriUrlOptions): number {\n return options?.maxBytes ?? DEFAULT_MAX_SRI_RESPONSE_BYTES;\n}\n\nasync function computeSriHashFromResponse(\n response: Response,\n url: string,\n options?: SriUrlOptions,\n): Promise<string> {\n const maxBytes = getMaxSriResponseBytes(options);\n const contentLengthHeader = response.headers.get(\"content-length\");\n\n if (contentLengthHeader) {\n const contentLength = Number(contentLengthHeader);\n if (Number.isFinite(contentLength) && contentLength > maxBytes) {\n throw new Error(\n `[SRI] Response for ${url} exceeds max size of ${maxBytes} bytes (${contentLength})`,\n );\n }\n }\n\n if (!response.body) {\n throw new Error(`[SRI] Missing response body for ${url}`);\n }\n\n const hash = createHash(\"sha384\");\n const reader = response.body.getReader();\n let totalBytes = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n\n totalBytes += value.byteLength;\n if (totalBytes > maxBytes) {\n await reader.cancel();\n throw new Error(\n `[SRI] Response for ${url} exceeds max size of ${maxBytes} bytes (${totalBytes})`,\n );\n }\n\n hash.update(value);\n }\n\n return `sha384-${hash.digest(\"base64\")}`;\n}\n\nexport async function computeSriHashForUrl(\n url: string,\n options?: SriUrlOptions,\n): Promise<string | null> {\n const attempts = 3;\n for (let attempt = 1; attempt < attempts; attempt++) {\n const hash = await computeSriHashOnce(url, options);\n if (hash) return hash;\n await new Promise((resolve) => setTimeout(resolve, 1000 * attempt));\n }\n return computeSriHashOnce(url, options);\n}\n\nasync function computeSriHashOnce(url: string, options?: SriUrlOptions): Promise<string | null> {\n try {\n const entryUrl = resolveSriTargetUrl(url, options);\n\n const response = await fetchResponse(entryUrl, { timeout: \"30 seconds\" });\n if (!response.ok) {\n console.warn(`[SRI] Failed to fetch ${entryUrl}: ${response.status} ${response.statusText}`);\n return null;\n }\n return await computeSriHashFromResponse(response, entryUrl, options);\n } catch (error) {\n console.warn(\n `[SRI] Error computing integrity for ${url}:`,\n error instanceof Error ? error.message : error,\n );\n return null;\n }\n}\n\nexport function resolveEntryUrl(url: string): string {\n if (url.endsWith(\"/remoteEntry.js\")) return url;\n if (url.endsWith(\"/mf-manifest.json\"))\n return `${url.replace(/\\/mf-manifest\\.json$/, \"\")}/remoteEntry.js`;\n return `${url.replace(/\\/$/, \"\")}/remoteEntry.js`;\n}\n\nexport class SriVerificationError extends Data.TaggedError(\"SriVerificationError\")<{\n readonly detail: string;\n}> {\n constructor(message: string) {\n super({ detail: message });\n }\n\n override get message() {\n return this.detail;\n }\n}\n\nexport async function verifySriForUrl(\n url: string,\n expectedIntegrity: string,\n options?: SriUrlOptions,\n): Promise<void> {\n const entryUrl = resolveSriTargetUrl(url, options);\n\n const response = await fetchResponse(entryUrl, { timeout: \"30 seconds\" });\n if (!response.ok) {\n throw new SriVerificationError(\n `Failed to fetch ${entryUrl} for verification: ${response.status}`,\n );\n }\n\n const computed = await computeSriHashFromResponse(response, entryUrl, options);\n\n if (computed !== expectedIntegrity) {\n throw new Error(\n `[SRI] Integrity check failed for ${entryUrl}\\n Expected: ${expectedIntegrity}\\n Computed: ${computed}`,\n );\n }\n}\n\nexport class IntegrityRegistry {\n private hashes = new Map<string, string>();\n\n register(url: string, integrity: string): void {\n this.hashes.set(url, integrity);\n }\n\n registerEntry(baseUrl: string, integrity: string): void {\n this.hashes.set(resolveEntryUrl(baseUrl), integrity);\n }\n\n get(url: string): string | undefined {\n return this.hashes.get(url);\n }\n\n has(url: string): boolean {\n return this.hashes.has(url);\n }\n\n entries(): IterableIterator<[string, string]> {\n return this.hashes.entries();\n }\n}\n\nfunction extractIntegrityHashes(config: Record<string, unknown>): Map<string, string> {\n const hashes = new Map<string, string>();\n const app = config.app as Record<string, Record<string, unknown>> | undefined;\n const plugins = config.plugins as Record<string, Record<string, unknown>> | undefined;\n\n for (const entry of [...Object.values(app ?? {}), ...Object.values(plugins ?? {})]) {\n if (!entry) continue;\n const slotHash = slotHashOf(entry);\n if (slotHash) hashes.set(slotHash.key, slotHash.hash);\n }\n\n return hashes;\n}\n\n/**\n * The integrity anchor a slot contributes to local↔chain attestation: pinned\n * slots anchor at the pinned manifest document (the pin's SRI), unpinned\n * slots at their fixed-name entry (the direct entry SRI).\n */\nfunction slotHashOf(entry: Record<string, unknown>): { key: string; hash: string } | null {\n const production = entry.production;\n if (typeof production !== \"string\") return null;\n const pin = entry.pin as { manifest?: unknown; integrity?: unknown } | undefined;\n if (pin && typeof pin.manifest === \"string\" && typeof pin.integrity === \"string\") {\n return {\n key: `${production.replace(/\\/$/, \"\")}/${pin.manifest.replace(/^\\//, \"\")}`,\n hash: pin.integrity,\n };\n }\n if (typeof entry.integrity === \"string\") {\n return { key: resolveEntryUrl(production), hash: entry.integrity };\n }\n return null;\n}\n\nexport async function verifyConfigAgainstChain(\n localConfig: Record<string, unknown>,\n bosUrl: string,\n): Promise<{ verified: boolean; mismatches: string[] }> {\n const mismatches: string[] = [];\n\n let chainConfig: Record<string, unknown>;\n try {\n chainConfig = await fetchBosConfigFromFastKv<Record<string, unknown>>(bosUrl);\n } catch (error) {\n console.warn(\n `[Attestation] Failed to fetch on-chain config: ${error instanceof Error ? error.message : String(error)}`,\n );\n return { verified: false, mismatches: [\"chain-fetch-failed\"] };\n }\n\n const localHashes = extractIntegrityHashes(localConfig);\n const chainHashes = extractIntegrityHashes(chainConfig);\n\n for (const [url, chainHash] of chainHashes) {\n const localHash = localHashes.get(url);\n if (localHash && localHash !== chainHash) {\n mismatches.push(url);\n console.error(\n `[Attestation] Integrity mismatch for ${url}\\n Local: ${localHash}\\n Chain: ${chainHash}`,\n );\n }\n }\n\n if (mismatches.length === 0 && localHashes.size > 0) {\n console.log(\n `[Attestation] Local config verified against on-chain anchor (${localHashes.size} entries checked)`,\n );\n }\n\n return { verified: mismatches.length === 0, mismatches };\n}\n\nexport interface DeployResultEntry {\n url: string;\n integrity?: string;\n urlField: string;\n integrityField?: string;\n /** A plain pipeline-state value (e.g. the built MF container name). */\n value?: string;\n valueField?: string;\n /** Dotted paths deleted after applying this entry — clears stale\n * pipeline-state fields (e.g. the retired flat `manifest` pointer). */\n removeFields?: string[];\n}\n\nfunction setNestedPath(obj: Record<string, unknown>, dottedPath: string, value: unknown): void {\n const keys = dottedPath.split(\".\");\n let current = obj;\n for (let i = 0; i < keys.length - 1; i += 1) {\n const key = keys[i]!;\n if (current[key] === undefined || current[key] === null || typeof current[key] !== \"object\") {\n current[key] = {};\n }\n current = current[key] as Record<string, unknown>;\n }\n current[keys[keys.length - 1]!] = value;\n}\n\nfunction deleteNestedPath(obj: Record<string, unknown>, dottedPath: string): void {\n const keys = dottedPath.split(\".\");\n let current = obj;\n for (let i = 0; i < keys.length - 1; i += 1) {\n const key = keys[i]!;\n if (current[key] === undefined || typeof current[key] !== \"object\") return;\n current = current[key] as Record<string, unknown>;\n }\n delete current[keys[keys.length - 1]!];\n}\n\nexport function applyDeployResults(\n config: Record<string, unknown>,\n results: DeployResultEntry[],\n): Record<string, unknown> {\n const merged = structuredClone(config);\n for (const result of results) {\n setNestedPath(merged, result.urlField, result.url);\n if (result.integrityField) {\n if (result.integrity) {\n setNestedPath(merged, result.integrityField, result.integrity);\n } else {\n deleteNestedPath(merged, result.integrityField);\n }\n }\n if (result.valueField && result.value !== undefined && result.value !== null) {\n setNestedPath(merged, result.valueField, result.value);\n }\n for (const field of result.removeFields ?? []) {\n deleteNestedPath(merged, field);\n }\n }\n return merged;\n}\n"],"mappings":"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"}
@@ -6,6 +6,15 @@ interface SriUrlOptions {
6
6
  declare function computeSriHash(content: string | Buffer): string;
7
7
  declare function computeSriHashForUrl(url: string, options?: SriUrlOptions): Promise<string | null>;
8
8
  declare function resolveEntryUrl(url: string): string;
9
+ declare const SriVerificationError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
10
+ readonly _tag: "SriVerificationError";
11
+ } & Readonly<A>;
12
+ declare class SriVerificationError extends SriVerificationError_base<{
13
+ readonly detail: string;
14
+ }> {
15
+ constructor(message: string);
16
+ get message(): string;
17
+ }
9
18
  declare function verifySriForUrl(url: string, expectedIntegrity: string, options?: SriUrlOptions): Promise<void>;
10
19
  declare class IntegrityRegistry {
11
20
  private hashes;
@@ -24,17 +33,14 @@ interface DeployResultEntry {
24
33
  integrity?: string;
25
34
  urlField: string;
26
35
  integrityField?: string;
36
+ /** A plain pipeline-state value (e.g. the built MF container name). */
37
+ value?: string;
38
+ valueField?: string;
39
+ /** Dotted paths deleted after applying this entry — clears stale
40
+ * pipeline-state fields (e.g. the retired flat `manifest` pointer). */
41
+ removeFields?: string[];
27
42
  }
28
- declare function reportDeployResult(opts: {
29
- url: string;
30
- integrity?: string | null;
31
- bosConfigPath: string;
32
- urlField: string;
33
- integrityField?: string;
34
- }): void;
35
- declare function parseDeployLines(output: string): DeployResultEntry[];
36
43
  declare function applyDeployResults(config: Record<string, unknown>, results: DeployResultEntry[]): Record<string, unknown>;
37
- declare function findPluginKey(bosConfigPath: string, pluginDir: string): string | null;
38
44
  //#endregion
39
- export { DeployResultEntry, IntegrityRegistry, applyDeployResults, computeSriHash, computeSriHashForUrl, findPluginKey, parseDeployLines, reportDeployResult, resolveEntryUrl, verifyConfigAgainstChain, verifySriForUrl };
45
+ export { DeployResultEntry, IntegrityRegistry, SriVerificationError, applyDeployResults, computeSriHash, computeSriHashForUrl, resolveEntryUrl, verifyConfigAgainstChain, verifySriForUrl };
40
46
  //# sourceMappingURL=integrity.d.cts.map
@@ -6,6 +6,15 @@ interface SriUrlOptions {
6
6
  declare function computeSriHash(content: string | Buffer): string;
7
7
  declare function computeSriHashForUrl(url: string, options?: SriUrlOptions): Promise<string | null>;
8
8
  declare function resolveEntryUrl(url: string): string;
9
+ declare const SriVerificationError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
10
+ readonly _tag: "SriVerificationError";
11
+ } & Readonly<A>;
12
+ declare class SriVerificationError extends SriVerificationError_base<{
13
+ readonly detail: string;
14
+ }> {
15
+ constructor(message: string);
16
+ get message(): string;
17
+ }
9
18
  declare function verifySriForUrl(url: string, expectedIntegrity: string, options?: SriUrlOptions): Promise<void>;
10
19
  declare class IntegrityRegistry {
11
20
  private hashes;
@@ -24,17 +33,14 @@ interface DeployResultEntry {
24
33
  integrity?: string;
25
34
  urlField: string;
26
35
  integrityField?: string;
36
+ /** A plain pipeline-state value (e.g. the built MF container name). */
37
+ value?: string;
38
+ valueField?: string;
39
+ /** Dotted paths deleted after applying this entry — clears stale
40
+ * pipeline-state fields (e.g. the retired flat `manifest` pointer). */
41
+ removeFields?: string[];
27
42
  }
28
- declare function reportDeployResult(opts: {
29
- url: string;
30
- integrity?: string | null;
31
- bosConfigPath: string;
32
- urlField: string;
33
- integrityField?: string;
34
- }): void;
35
- declare function parseDeployLines(output: string): DeployResultEntry[];
36
43
  declare function applyDeployResults(config: Record<string, unknown>, results: DeployResultEntry[]): Record<string, unknown>;
37
- declare function findPluginKey(bosConfigPath: string, pluginDir: string): string | null;
38
44
  //#endregion
39
- export { DeployResultEntry, IntegrityRegistry, applyDeployResults, computeSriHash, computeSriHashForUrl, findPluginKey, parseDeployLines, reportDeployResult, resolveEntryUrl, verifyConfigAgainstChain, verifySriForUrl };
45
+ export { DeployResultEntry, IntegrityRegistry, SriVerificationError, applyDeployResults, computeSriHash, computeSriHashForUrl, resolveEntryUrl, verifyConfigAgainstChain, verifySriForUrl };
40
46
  //# sourceMappingURL=integrity.d.mts.map
@@ -1,11 +1,10 @@
1
1
  import { fetchResponse } from "./http-client.mjs";
2
2
  import { fetchBosConfigFromFastKv } from "./fastkv.mjs";
3
- import { readFileSync, writeFileSync } from "node:fs";
4
- import { join } from "node:path";
3
+ import { Data } from "effect";
5
4
  import { createHash } from "node:crypto";
6
5
 
7
6
  //#region src/integrity.ts
8
- const DEFAULT_MAX_SRI_RESPONSE_BYTES = 20 * 1024 * 1024;
7
+ const DEFAULT_MAX_SRI_RESPONSE_BYTES = 20971520;
9
8
  function computeSriHash(content) {
10
9
  return `sha384-${createHash("sha384").update(content).digest("base64")}`;
11
10
  }
@@ -39,6 +38,15 @@ async function computeSriHashFromResponse(response, url, options) {
39
38
  return `sha384-${hash.digest("base64")}`;
40
39
  }
41
40
  async function computeSriHashForUrl(url, options) {
41
+ const attempts = 3;
42
+ for (let attempt = 1; attempt < attempts; attempt++) {
43
+ const hash = await computeSriHashOnce(url, options);
44
+ if (hash) return hash;
45
+ await new Promise((resolve) => setTimeout(resolve, 1e3 * attempt));
46
+ }
47
+ return computeSriHashOnce(url, options);
48
+ }
49
+ async function computeSriHashOnce(url, options) {
42
50
  try {
43
51
  const entryUrl = resolveSriTargetUrl(url, options);
44
52
  const response = await fetchResponse(entryUrl, { timeout: "30 seconds" });
@@ -57,13 +65,18 @@ function resolveEntryUrl(url) {
57
65
  if (url.endsWith("/mf-manifest.json")) return `${url.replace(/\/mf-manifest\.json$/, "")}/remoteEntry.js`;
58
66
  return `${url.replace(/\/$/, "")}/remoteEntry.js`;
59
67
  }
68
+ var SriVerificationError = class extends Data.TaggedError("SriVerificationError") {
69
+ constructor(message) {
70
+ super({ detail: message });
71
+ }
72
+ get message() {
73
+ return this.detail;
74
+ }
75
+ };
60
76
  async function verifySriForUrl(url, expectedIntegrity, options) {
61
77
  const entryUrl = resolveSriTargetUrl(url, options);
62
78
  const response = await fetchResponse(entryUrl, { timeout: "30 seconds" });
63
- if (!response.ok) {
64
- console.warn(`[SRI] Failed to fetch ${entryUrl} for verification: ${response.status}`);
65
- return;
66
- }
79
+ if (!response.ok) throw new SriVerificationError(`Failed to fetch ${entryUrl} for verification: ${response.status}`);
67
80
  const computed = await computeSriHashFromResponse(response, entryUrl, options);
68
81
  if (computed !== expectedIntegrity) throw new Error(`[SRI] Integrity check failed for ${entryUrl}\n Expected: ${expectedIntegrity}\n Computed: ${computed}`);
69
82
  }
@@ -89,14 +102,32 @@ function extractIntegrityHashes(config) {
89
102
  const hashes = /* @__PURE__ */ new Map();
90
103
  const app = config.app;
91
104
  const plugins = config.plugins;
92
- if (app) {
93
- for (const [, entry] of Object.entries(app)) if (entry?.integrity && entry?.production) hashes.set(resolveEntryUrl(entry.production), entry.integrity);
94
- }
95
- if (plugins) {
96
- for (const [, entry] of Object.entries(plugins)) if (entry?.integrity && entry?.production) hashes.set(resolveEntryUrl(entry.production), entry.integrity);
105
+ for (const entry of [...Object.values(app ?? {}), ...Object.values(plugins ?? {})]) {
106
+ if (!entry) continue;
107
+ const slotHash = slotHashOf(entry);
108
+ if (slotHash) hashes.set(slotHash.key, slotHash.hash);
97
109
  }
98
110
  return hashes;
99
111
  }
112
+ /**
113
+ * The integrity anchor a slot contributes to local↔chain attestation: pinned
114
+ * slots anchor at the pinned manifest document (the pin's SRI), unpinned
115
+ * slots at their fixed-name entry (the direct entry SRI).
116
+ */
117
+ function slotHashOf(entry) {
118
+ const production = entry.production;
119
+ if (typeof production !== "string") return null;
120
+ const pin = entry.pin;
121
+ if (pin && typeof pin.manifest === "string" && typeof pin.integrity === "string") return {
122
+ key: `${production.replace(/\/$/, "")}/${pin.manifest.replace(/^\//, "")}`,
123
+ hash: pin.integrity
124
+ };
125
+ if (typeof entry.integrity === "string") return {
126
+ key: resolveEntryUrl(production),
127
+ hash: entry.integrity
128
+ };
129
+ return null;
130
+ }
100
131
  async function verifyConfigAgainstChain(localConfig, bosUrl) {
101
132
  const mismatches = [];
102
133
  let chainConfig;
@@ -144,60 +175,20 @@ function deleteNestedPath(obj, dottedPath) {
144
175
  }
145
176
  delete current[keys[keys.length - 1]];
146
177
  }
147
- function reportDeployResult(opts) {
148
- console.log(`[BOS_DEPLOY] url=${opts.url} urlField=${opts.urlField} integrityField=${opts.integrityField ?? ""} integrity=${opts.integrity ?? ""}`);
149
- try {
150
- const config = JSON.parse(readFileSync(opts.bosConfigPath, "utf8"));
151
- setNestedPath(config, opts.urlField, opts.url);
152
- if (opts.integrityField) if (opts.integrity) setNestedPath(config, opts.integrityField, opts.integrity);
153
- else deleteNestedPath(config, opts.integrityField);
154
- writeFileSync(opts.bosConfigPath, `${JSON.stringify(config, null, 2)}\n`);
155
- console.log(` ✅ Updated bos.config.json: ${opts.urlField}`);
156
- if (opts.integrityField && opts.integrity) console.log(` ✅ Updated bos.config.json: ${opts.integrityField}`);
157
- } catch (err) {
158
- console.error(" ❌ Failed to update bos.config.json:", err.message);
159
- }
160
- }
161
- function parseDeployLines(output) {
162
- const results = [];
163
- for (const line of output.split("\n")) {
164
- if (!line.includes("[BOS_DEPLOY]")) continue;
165
- const urlMatch = line.match(/url=(\S+)/);
166
- const urlFieldMatch = line.match(/urlField=(\S+)/);
167
- if (!urlMatch || !urlFieldMatch) continue;
168
- const integrityFieldMatch = line.match(/integrityField=(\S+)/);
169
- const integrityMatch = line.match(/integrity=(\S+)/);
170
- results.push({
171
- url: urlMatch[1],
172
- urlField: urlFieldMatch[1],
173
- integrityField: integrityFieldMatch?.[1] || void 0,
174
- integrity: integrityMatch?.[1] || void 0
175
- });
176
- }
177
- return results;
178
- }
179
178
  function applyDeployResults(config, results) {
180
179
  const merged = structuredClone(config);
181
180
  for (const result of results) {
182
181
  setNestedPath(merged, result.urlField, result.url);
183
- if (result.integrityField) if (result.integrity) setNestedPath(merged, result.integrityField, result.integrity);
184
- else deleteNestedPath(merged, result.integrityField);
182
+ if (result.integrityField) {
183
+ if (result.integrity) setNestedPath(merged, result.integrityField, result.integrity);
184
+ else deleteNestedPath(merged, result.integrityField);
185
+ }
186
+ if (result.valueField && result.value !== void 0 && result.value !== null) setNestedPath(merged, result.valueField, result.value);
187
+ for (const field of result.removeFields ?? []) deleteNestedPath(merged, field);
185
188
  }
186
189
  return merged;
187
190
  }
188
- function findPluginKey(bosConfigPath, pluginDir) {
189
- const plugins = JSON.parse(readFileSync(bosConfigPath, "utf8")).plugins;
190
- if (!plugins) return null;
191
- const configRoot = join(bosConfigPath, "..");
192
- const normalizedPluginDir = pluginDir.replace(/\\/g, "/").replace(/\/+$/, "");
193
- for (const [key, plugin] of Object.entries(plugins)) {
194
- const dev = plugin?.development;
195
- if (typeof dev !== "string" || !dev.startsWith("local:")) continue;
196
- if (join(configRoot, dev.slice(6)).replace(/\\/g, "/").replace(/\/+$/, "") === normalizedPluginDir) return key;
197
- }
198
- return null;
199
- }
200
191
 
201
192
  //#endregion
202
- export { IntegrityRegistry, applyDeployResults, computeSriHash, computeSriHashForUrl, findPluginKey, parseDeployLines, reportDeployResult, resolveEntryUrl, verifyConfigAgainstChain, verifySriForUrl };
193
+ export { IntegrityRegistry, SriVerificationError, applyDeployResults, computeSriHash, computeSriHashForUrl, resolveEntryUrl, verifyConfigAgainstChain, verifySriForUrl };
203
194
  //# sourceMappingURL=integrity.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"integrity.mjs","names":[],"sources":["../src/integrity.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { fetchBosConfigFromFastKv } from \"./fastkv\";\nimport { fetchResponse } from \"./http-client\";\n\nconst DEFAULT_MAX_SRI_RESPONSE_BYTES = 20 * 1024 * 1024;\n\ninterface SriUrlOptions {\n resolveEntryUrl?: boolean;\n maxBytes?: number;\n}\n\nexport function computeSriHash(content: string | Buffer): string {\n return `sha384-${createHash(\"sha384\").update(content).digest(\"base64\")}`;\n}\n\nfunction resolveSriTargetUrl(url: string, options?: SriUrlOptions): string {\n return options?.resolveEntryUrl === false ? url : resolveEntryUrl(url);\n}\n\nfunction getMaxSriResponseBytes(options?: SriUrlOptions): number {\n return options?.maxBytes ?? DEFAULT_MAX_SRI_RESPONSE_BYTES;\n}\n\nasync function computeSriHashFromResponse(\n response: Response,\n url: string,\n options?: SriUrlOptions,\n): Promise<string> {\n const maxBytes = getMaxSriResponseBytes(options);\n const contentLengthHeader = response.headers.get(\"content-length\");\n\n if (contentLengthHeader) {\n const contentLength = Number(contentLengthHeader);\n if (Number.isFinite(contentLength) && contentLength > maxBytes) {\n throw new Error(\n `[SRI] Response for ${url} exceeds max size of ${maxBytes} bytes (${contentLength})`,\n );\n }\n }\n\n if (!response.body) {\n throw new Error(`[SRI] Missing response body for ${url}`);\n }\n\n const hash = createHash(\"sha384\");\n const reader = response.body.getReader();\n let totalBytes = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n\n totalBytes += value.byteLength;\n if (totalBytes > maxBytes) {\n await reader.cancel();\n throw new Error(\n `[SRI] Response for ${url} exceeds max size of ${maxBytes} bytes (${totalBytes})`,\n );\n }\n\n hash.update(value);\n }\n\n return `sha384-${hash.digest(\"base64\")}`;\n}\n\nexport async function computeSriHashForUrl(\n url: string,\n options?: SriUrlOptions,\n): Promise<string | null> {\n try {\n const entryUrl = resolveSriTargetUrl(url, options);\n\n const response = await fetchResponse(entryUrl, { timeout: \"30 seconds\" });\n if (!response.ok) {\n console.warn(`[SRI] Failed to fetch ${entryUrl}: ${response.status} ${response.statusText}`);\n return null;\n }\n return await computeSriHashFromResponse(response, entryUrl, options);\n } catch (error) {\n console.warn(\n `[SRI] Error computing integrity for ${url}:`,\n error instanceof Error ? error.message : error,\n );\n return null;\n }\n}\n\nexport function resolveEntryUrl(url: string): string {\n if (url.endsWith(\"/remoteEntry.js\")) return url;\n if (url.endsWith(\"/mf-manifest.json\"))\n return `${url.replace(/\\/mf-manifest\\.json$/, \"\")}/remoteEntry.js`;\n return `${url.replace(/\\/$/, \"\")}/remoteEntry.js`;\n}\n\nexport async function verifySriForUrl(\n url: string,\n expectedIntegrity: string,\n options?: SriUrlOptions,\n): Promise<void> {\n const entryUrl = resolveSriTargetUrl(url, options);\n\n const response = await fetchResponse(entryUrl, { timeout: \"30 seconds\" });\n if (!response.ok) {\n console.warn(`[SRI] Failed to fetch ${entryUrl} for verification: ${response.status}`);\n return;\n }\n\n const computed = await computeSriHashFromResponse(response, entryUrl, options);\n\n if (computed !== expectedIntegrity) {\n throw new Error(\n `[SRI] Integrity check failed for ${entryUrl}\\n Expected: ${expectedIntegrity}\\n Computed: ${computed}`,\n );\n }\n}\n\nexport class IntegrityRegistry {\n private hashes = new Map<string, string>();\n\n register(url: string, integrity: string): void {\n this.hashes.set(url, integrity);\n }\n\n registerEntry(baseUrl: string, integrity: string): void {\n this.hashes.set(resolveEntryUrl(baseUrl), integrity);\n }\n\n get(url: string): string | undefined {\n return this.hashes.get(url);\n }\n\n has(url: string): boolean {\n return this.hashes.has(url);\n }\n\n entries(): IterableIterator<[string, string]> {\n return this.hashes.entries();\n }\n}\n\nfunction extractIntegrityHashes(config: Record<string, unknown>): Map<string, string> {\n const hashes = new Map<string, string>();\n const app = config.app as Record<string, Record<string, unknown>> | undefined;\n const plugins = config.plugins as Record<string, Record<string, unknown>> | undefined;\n\n if (app) {\n for (const [, entry] of Object.entries(app)) {\n if (entry?.integrity && entry?.production) {\n hashes.set(resolveEntryUrl(entry.production as string), entry.integrity as string);\n }\n }\n }\n\n if (plugins) {\n for (const [, entry] of Object.entries(plugins)) {\n if (entry?.integrity && entry?.production) {\n hashes.set(resolveEntryUrl(entry.production as string), entry.integrity as string);\n }\n }\n }\n\n return hashes;\n}\n\nexport async function verifyConfigAgainstChain(\n localConfig: Record<string, unknown>,\n bosUrl: string,\n): Promise<{ verified: boolean; mismatches: string[] }> {\n const mismatches: string[] = [];\n\n let chainConfig: Record<string, unknown>;\n try {\n chainConfig = await fetchBosConfigFromFastKv<Record<string, unknown>>(bosUrl);\n } catch (error) {\n console.warn(\n `[Attestation] Failed to fetch on-chain config: ${error instanceof Error ? error.message : String(error)}`,\n );\n return { verified: false, mismatches: [\"chain-fetch-failed\"] };\n }\n\n const localHashes = extractIntegrityHashes(localConfig);\n const chainHashes = extractIntegrityHashes(chainConfig);\n\n for (const [url, chainHash] of chainHashes) {\n const localHash = localHashes.get(url);\n if (localHash && localHash !== chainHash) {\n mismatches.push(url);\n console.error(\n `[Attestation] Integrity mismatch for ${url}\\n Local: ${localHash}\\n Chain: ${chainHash}`,\n );\n }\n }\n\n if (mismatches.length === 0 && localHashes.size > 0) {\n console.log(\n `[Attestation] Local config verified against on-chain anchor (${localHashes.size} entries checked)`,\n );\n }\n\n return { verified: mismatches.length === 0, mismatches };\n}\n\nexport interface DeployResultEntry {\n url: string;\n integrity?: string;\n urlField: string;\n integrityField?: string;\n}\n\nfunction setNestedPath(obj: Record<string, unknown>, dottedPath: string, value: unknown): void {\n const keys = dottedPath.split(\".\");\n let current = obj;\n for (let i = 0; i < keys.length - 1; i += 1) {\n const key = keys[i]!;\n if (current[key] === undefined || current[key] === null || typeof current[key] !== \"object\") {\n current[key] = {};\n }\n current = current[key] as Record<string, unknown>;\n }\n current[keys[keys.length - 1]!] = value;\n}\n\nfunction deleteNestedPath(obj: Record<string, unknown>, dottedPath: string): void {\n const keys = dottedPath.split(\".\");\n let current = obj;\n for (let i = 0; i < keys.length - 1; i += 1) {\n const key = keys[i]!;\n if (current[key] === undefined || typeof current[key] !== \"object\") return;\n current = current[key] as Record<string, unknown>;\n }\n delete current[keys[keys.length - 1]!];\n}\n\nexport function reportDeployResult(opts: {\n url: string;\n integrity?: string | null;\n bosConfigPath: string;\n urlField: string;\n integrityField?: string;\n}): void {\n console.log(\n `[BOS_DEPLOY] url=${opts.url} urlField=${opts.urlField} integrityField=${opts.integrityField ?? \"\"} integrity=${opts.integrity ?? \"\"}`,\n );\n\n try {\n const config = JSON.parse(readFileSync(opts.bosConfigPath, \"utf8\")) as Record<string, unknown>;\n setNestedPath(config, opts.urlField, opts.url);\n if (opts.integrityField) {\n if (opts.integrity) {\n setNestedPath(config, opts.integrityField, opts.integrity);\n } else {\n deleteNestedPath(config, opts.integrityField);\n }\n }\n writeFileSync(opts.bosConfigPath, `${JSON.stringify(config, null, 2)}\\n`);\n console.log(` ✅ Updated bos.config.json: ${opts.urlField}`);\n if (opts.integrityField && opts.integrity) {\n console.log(` ✅ Updated bos.config.json: ${opts.integrityField}`);\n }\n } catch (err) {\n console.error(\" ❌ Failed to update bos.config.json:\", (err as Error).message);\n }\n}\n\nexport function parseDeployLines(output: string): DeployResultEntry[] {\n const results: DeployResultEntry[] = [];\n for (const line of output.split(\"\\n\")) {\n if (!line.includes(\"[BOS_DEPLOY]\")) continue;\n const urlMatch = line.match(/url=(\\S+)/);\n const urlFieldMatch = line.match(/urlField=(\\S+)/);\n if (!urlMatch || !urlFieldMatch) continue;\n const integrityFieldMatch = line.match(/integrityField=(\\S+)/);\n const integrityMatch = line.match(/integrity=(\\S+)/);\n results.push({\n url: urlMatch[1],\n urlField: urlFieldMatch[1],\n integrityField: integrityFieldMatch?.[1] || undefined,\n integrity: integrityMatch?.[1] || undefined,\n });\n }\n return results;\n}\n\nexport function applyDeployResults(\n config: Record<string, unknown>,\n results: DeployResultEntry[],\n): Record<string, unknown> {\n const merged = structuredClone(config);\n for (const result of results) {\n setNestedPath(merged, result.urlField, result.url);\n if (result.integrityField) {\n if (result.integrity) {\n setNestedPath(merged, result.integrityField, result.integrity);\n } else {\n deleteNestedPath(merged, result.integrityField);\n }\n }\n }\n return merged;\n}\n\nexport function findPluginKey(bosConfigPath: string, pluginDir: string): string | null {\n const config = JSON.parse(readFileSync(bosConfigPath, \"utf8\")) as Record<string, unknown>;\n const plugins = config.plugins as Record<string, Record<string, unknown>> | undefined;\n if (!plugins) return null;\n const configRoot = join(bosConfigPath, \"..\");\n const normalizedPluginDir = pluginDir.replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\");\n for (const [key, plugin] of Object.entries(plugins)) {\n const dev = plugin?.development;\n if (typeof dev !== \"string\" || !dev.startsWith(\"local:\")) continue;\n const resolved = join(configRoot, dev.slice(\"local:\".length))\n .replace(/\\\\/g, \"/\")\n .replace(/\\/+$/, \"\");\n if (resolved === normalizedPluginDir) return key;\n }\n return null;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"integrity.mjs","names":[],"sources":["../src/integrity.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { Data } from \"effect\";\nimport { fetchBosConfigFromFastKv } from \"./fastkv\";\nimport { fetchResponse } from \"./http-client\";\n\nconst DEFAULT_MAX_SRI_RESPONSE_BYTES = 20 * 1024 * 1024;\n\ninterface SriUrlOptions {\n resolveEntryUrl?: boolean;\n maxBytes?: number;\n}\n\nexport function computeSriHash(content: string | Buffer): string {\n return `sha384-${createHash(\"sha384\").update(content).digest(\"base64\")}`;\n}\n\nfunction resolveSriTargetUrl(url: string, options?: SriUrlOptions): string {\n return options?.resolveEntryUrl === false ? url : resolveEntryUrl(url);\n}\n\nfunction getMaxSriResponseBytes(options?: SriUrlOptions): number {\n return options?.maxBytes ?? DEFAULT_MAX_SRI_RESPONSE_BYTES;\n}\n\nasync function computeSriHashFromResponse(\n response: Response,\n url: string,\n options?: SriUrlOptions,\n): Promise<string> {\n const maxBytes = getMaxSriResponseBytes(options);\n const contentLengthHeader = response.headers.get(\"content-length\");\n\n if (contentLengthHeader) {\n const contentLength = Number(contentLengthHeader);\n if (Number.isFinite(contentLength) && contentLength > maxBytes) {\n throw new Error(\n `[SRI] Response for ${url} exceeds max size of ${maxBytes} bytes (${contentLength})`,\n );\n }\n }\n\n if (!response.body) {\n throw new Error(`[SRI] Missing response body for ${url}`);\n }\n\n const hash = createHash(\"sha384\");\n const reader = response.body.getReader();\n let totalBytes = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n\n totalBytes += value.byteLength;\n if (totalBytes > maxBytes) {\n await reader.cancel();\n throw new Error(\n `[SRI] Response for ${url} exceeds max size of ${maxBytes} bytes (${totalBytes})`,\n );\n }\n\n hash.update(value);\n }\n\n return `sha384-${hash.digest(\"base64\")}`;\n}\n\nexport async function computeSriHashForUrl(\n url: string,\n options?: SriUrlOptions,\n): Promise<string | null> {\n const attempts = 3;\n for (let attempt = 1; attempt < attempts; attempt++) {\n const hash = await computeSriHashOnce(url, options);\n if (hash) return hash;\n await new Promise((resolve) => setTimeout(resolve, 1000 * attempt));\n }\n return computeSriHashOnce(url, options);\n}\n\nasync function computeSriHashOnce(url: string, options?: SriUrlOptions): Promise<string | null> {\n try {\n const entryUrl = resolveSriTargetUrl(url, options);\n\n const response = await fetchResponse(entryUrl, { timeout: \"30 seconds\" });\n if (!response.ok) {\n console.warn(`[SRI] Failed to fetch ${entryUrl}: ${response.status} ${response.statusText}`);\n return null;\n }\n return await computeSriHashFromResponse(response, entryUrl, options);\n } catch (error) {\n console.warn(\n `[SRI] Error computing integrity for ${url}:`,\n error instanceof Error ? error.message : error,\n );\n return null;\n }\n}\n\nexport function resolveEntryUrl(url: string): string {\n if (url.endsWith(\"/remoteEntry.js\")) return url;\n if (url.endsWith(\"/mf-manifest.json\"))\n return `${url.replace(/\\/mf-manifest\\.json$/, \"\")}/remoteEntry.js`;\n return `${url.replace(/\\/$/, \"\")}/remoteEntry.js`;\n}\n\nexport class SriVerificationError extends Data.TaggedError(\"SriVerificationError\")<{\n readonly detail: string;\n}> {\n constructor(message: string) {\n super({ detail: message });\n }\n\n override get message() {\n return this.detail;\n }\n}\n\nexport async function verifySriForUrl(\n url: string,\n expectedIntegrity: string,\n options?: SriUrlOptions,\n): Promise<void> {\n const entryUrl = resolveSriTargetUrl(url, options);\n\n const response = await fetchResponse(entryUrl, { timeout: \"30 seconds\" });\n if (!response.ok) {\n throw new SriVerificationError(\n `Failed to fetch ${entryUrl} for verification: ${response.status}`,\n );\n }\n\n const computed = await computeSriHashFromResponse(response, entryUrl, options);\n\n if (computed !== expectedIntegrity) {\n throw new Error(\n `[SRI] Integrity check failed for ${entryUrl}\\n Expected: ${expectedIntegrity}\\n Computed: ${computed}`,\n );\n }\n}\n\nexport class IntegrityRegistry {\n private hashes = new Map<string, string>();\n\n register(url: string, integrity: string): void {\n this.hashes.set(url, integrity);\n }\n\n registerEntry(baseUrl: string, integrity: string): void {\n this.hashes.set(resolveEntryUrl(baseUrl), integrity);\n }\n\n get(url: string): string | undefined {\n return this.hashes.get(url);\n }\n\n has(url: string): boolean {\n return this.hashes.has(url);\n }\n\n entries(): IterableIterator<[string, string]> {\n return this.hashes.entries();\n }\n}\n\nfunction extractIntegrityHashes(config: Record<string, unknown>): Map<string, string> {\n const hashes = new Map<string, string>();\n const app = config.app as Record<string, Record<string, unknown>> | undefined;\n const plugins = config.plugins as Record<string, Record<string, unknown>> | undefined;\n\n for (const entry of [...Object.values(app ?? {}), ...Object.values(plugins ?? {})]) {\n if (!entry) continue;\n const slotHash = slotHashOf(entry);\n if (slotHash) hashes.set(slotHash.key, slotHash.hash);\n }\n\n return hashes;\n}\n\n/**\n * The integrity anchor a slot contributes to local↔chain attestation: pinned\n * slots anchor at the pinned manifest document (the pin's SRI), unpinned\n * slots at their fixed-name entry (the direct entry SRI).\n */\nfunction slotHashOf(entry: Record<string, unknown>): { key: string; hash: string } | null {\n const production = entry.production;\n if (typeof production !== \"string\") return null;\n const pin = entry.pin as { manifest?: unknown; integrity?: unknown } | undefined;\n if (pin && typeof pin.manifest === \"string\" && typeof pin.integrity === \"string\") {\n return {\n key: `${production.replace(/\\/$/, \"\")}/${pin.manifest.replace(/^\\//, \"\")}`,\n hash: pin.integrity,\n };\n }\n if (typeof entry.integrity === \"string\") {\n return { key: resolveEntryUrl(production), hash: entry.integrity };\n }\n return null;\n}\n\nexport async function verifyConfigAgainstChain(\n localConfig: Record<string, unknown>,\n bosUrl: string,\n): Promise<{ verified: boolean; mismatches: string[] }> {\n const mismatches: string[] = [];\n\n let chainConfig: Record<string, unknown>;\n try {\n chainConfig = await fetchBosConfigFromFastKv<Record<string, unknown>>(bosUrl);\n } catch (error) {\n console.warn(\n `[Attestation] Failed to fetch on-chain config: ${error instanceof Error ? error.message : String(error)}`,\n );\n return { verified: false, mismatches: [\"chain-fetch-failed\"] };\n }\n\n const localHashes = extractIntegrityHashes(localConfig);\n const chainHashes = extractIntegrityHashes(chainConfig);\n\n for (const [url, chainHash] of chainHashes) {\n const localHash = localHashes.get(url);\n if (localHash && localHash !== chainHash) {\n mismatches.push(url);\n console.error(\n `[Attestation] Integrity mismatch for ${url}\\n Local: ${localHash}\\n Chain: ${chainHash}`,\n );\n }\n }\n\n if (mismatches.length === 0 && localHashes.size > 0) {\n console.log(\n `[Attestation] Local config verified against on-chain anchor (${localHashes.size} entries checked)`,\n );\n }\n\n return { verified: mismatches.length === 0, mismatches };\n}\n\nexport interface DeployResultEntry {\n url: string;\n integrity?: string;\n urlField: string;\n integrityField?: string;\n /** A plain pipeline-state value (e.g. the built MF container name). */\n value?: string;\n valueField?: string;\n /** Dotted paths deleted after applying this entry — clears stale\n * pipeline-state fields (e.g. the retired flat `manifest` pointer). */\n removeFields?: string[];\n}\n\nfunction setNestedPath(obj: Record<string, unknown>, dottedPath: string, value: unknown): void {\n const keys = dottedPath.split(\".\");\n let current = obj;\n for (let i = 0; i < keys.length - 1; i += 1) {\n const key = keys[i]!;\n if (current[key] === undefined || current[key] === null || typeof current[key] !== \"object\") {\n current[key] = {};\n }\n current = current[key] as Record<string, unknown>;\n }\n current[keys[keys.length - 1]!] = value;\n}\n\nfunction deleteNestedPath(obj: Record<string, unknown>, dottedPath: string): void {\n const keys = dottedPath.split(\".\");\n let current = obj;\n for (let i = 0; i < keys.length - 1; i += 1) {\n const key = keys[i]!;\n if (current[key] === undefined || typeof current[key] !== \"object\") return;\n current = current[key] as Record<string, unknown>;\n }\n delete current[keys[keys.length - 1]!];\n}\n\nexport function applyDeployResults(\n config: Record<string, unknown>,\n results: DeployResultEntry[],\n): Record<string, unknown> {\n const merged = structuredClone(config);\n for (const result of results) {\n setNestedPath(merged, result.urlField, result.url);\n if (result.integrityField) {\n if (result.integrity) {\n setNestedPath(merged, result.integrityField, result.integrity);\n } else {\n deleteNestedPath(merged, result.integrityField);\n }\n }\n if (result.valueField && result.value !== undefined && result.value !== null) {\n setNestedPath(merged, result.valueField, result.value);\n }\n for (const field of result.removeFields ?? []) {\n deleteNestedPath(merged, field);\n }\n }\n return merged;\n}\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ const require_workspace_catalog = require('../workspace-catalog.cjs');
1
2
  let node_fs = require("node:fs");
2
3
  let node_path = require("node:path");
3
4
  let glob = require("glob");
@@ -28,7 +29,7 @@ function writeJson(filePath, value) {
28
29
  (0, node_fs.writeFileSync)(filePath, `${JSON.stringify(value, null, 2)}\n`);
29
30
  }
30
31
  function loadManifestNormalizationSpec(sourceRootDir) {
31
- const rootCatalog = { ...readJson((0, node_path.join)(sourceRootDir, "package.json")).workspaces?.catalog ?? {} };
32
+ const rootCatalog = require_workspace_catalog.readWorkspaceCatalog(sourceRootDir);
32
33
  const frameworkVersions = {};
33
34
  for (const packageName of FRAMEWORK_PACKAGES) {
34
35
  const sourcePackagePath = (0, node_path.join)(sourceRootDir, "packages", packageName, "package.json");
@@ -54,7 +55,7 @@ function normalizeDependencyMap(map, spec, options) {
54
55
  }
55
56
  continue;
56
57
  }
57
- if (version === "workspace:*") {
58
+ if (version.startsWith("workspace:")) {
58
59
  const frameworkVersion = spec.frameworkVersions[name];
59
60
  if (frameworkVersion) {
60
61
  map[name] = `^${frameworkVersion}`;
@@ -64,6 +65,11 @@ function normalizeDependencyMap(map, spec, options) {
64
65
  if (options.removeWorkspaceDeps?.includes(name)) {
65
66
  delete map[name];
66
67
  modified = true;
68
+ continue;
69
+ }
70
+ if (spec.rootCatalog[name]) {
71
+ map[name] = options.preserveCatalogRefs ? "catalog:" : spec.rootCatalog[name];
72
+ modified = true;
67
73
  }
68
74
  continue;
69
75
  }
@@ -1 +1 @@
1
- {"version":3,"file":"manifest-normalizer.cjs","names":[],"sources":["../../src/internal/manifest-normalizer.ts"],"sourcesContent":["import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, relative, sep } from \"node:path\";\nimport { glob } from \"glob\";\n\nconst FRAMEWORK_PACKAGES = [\"every-plugin\", \"everything-dev\"] as const;\n\nconst CATALOG_TOOL_PACKAGES = [\n \"@rspack/core\",\n \"@rspack/cli\",\n \"@rsbuild/core\",\n \"@rsbuild/plugin-react\",\n \"@module-federation/enhanced\",\n \"@module-federation/node\",\n \"@module-federation/rsbuild-plugin\",\n \"@module-federation/runtime-core\",\n \"@module-federation/sdk\",\n \"@module-federation/dts-plugin\",\n] as const;\n\ntype PackageJson = Record<string, unknown>;\n\ntype NormalizationSpec = {\n rootCatalog: Record<string, string>;\n frameworkVersions: Record<string, string>;\n};\n\ntype NormalizeManifestOptions = {\n resolveCatalogRefs: boolean;\n preserveCatalogRefs?: boolean;\n excludeFrameworkWorkspaces?: boolean;\n removeWorkspaceDeps?: string[];\n removeWorkspaces?: boolean;\n removePublishScripts?: boolean;\n};\n\nexport type NormalizeTreeOptions = NormalizeManifestOptions & {\n sourceRootDir: string;\n targetDir: string;\n};\n\nfunction readJson<T>(filePath: string): T {\n return JSON.parse(readFileSync(filePath, \"utf-8\")) as T;\n}\n\nfunction extractExactVersion(input: string | undefined): string | null {\n if (!input) return null;\n const match = input.match(/\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?/);\n return match ? match[0] : null;\n}\n\nfunction writeJson(filePath: string, value: PackageJson) {\n writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\\n`);\n}\n\nexport function loadManifestNormalizationSpec(sourceRootDir: string): NormalizationSpec {\n const rootPackage = readJson<PackageJson>(join(sourceRootDir, \"package.json\"));\n const rootCatalog = {\n ...(((rootPackage.workspaces as { catalog?: Record<string, string> } | undefined)?.catalog ??\n {}) as Record<string, string>),\n };\n const frameworkVersions: Record<string, string> = {};\n\n for (const packageName of FRAMEWORK_PACKAGES) {\n const sourcePackagePath = join(sourceRootDir, \"packages\", packageName, \"package.json\");\n const localPackagePath = join(import.meta.dirname, \"..\", \"..\", packageName, \"package.json\");\n const packageVersion = existsSync(localPackagePath)\n ? readJson<{ version: string }>(localPackagePath).version\n : existsSync(sourcePackagePath)\n ? readJson<{ version: string }>(sourcePackagePath).version\n : extractExactVersion(rootCatalog[packageName]);\n\n if (!packageVersion) {\n throw new Error(`Could not resolve version for ${packageName}`);\n }\n\n frameworkVersions[packageName] = packageVersion;\n rootCatalog[packageName] = `^${packageVersion}`;\n }\n\n return { rootCatalog, frameworkVersions };\n}\n\nfunction normalizeDependencyMap(\n map: Record<string, string>,\n spec: NormalizationSpec,\n options: NormalizeManifestOptions,\n) {\n const catalogPackages = new Set<string>([...FRAMEWORK_PACKAGES, ...CATALOG_TOOL_PACKAGES]);\n\n let modified = false;\n\n for (const [name, version] of Object.entries(map)) {\n if (options.preserveCatalogRefs && catalogPackages.has(name)) {\n if (version !== \"catalog:\") {\n map[name] = \"catalog:\";\n modified = true;\n }\n continue;\n }\n\n if (version === \"workspace:*\") {\n const frameworkVersion = spec.frameworkVersions[name];\n if (frameworkVersion) {\n map[name] = `^${frameworkVersion}`;\n modified = true;\n continue;\n }\n\n if (options.removeWorkspaceDeps?.includes(name)) {\n delete map[name];\n modified = true;\n }\n continue;\n }\n\n if (options.resolveCatalogRefs && version.startsWith(\"catalog:\")) {\n const resolved = spec.rootCatalog[name];\n if (resolved) {\n map[name] = resolved;\n modified = true;\n }\n }\n }\n\n return modified;\n}\n\nexport function normalizePackageManifest(\n pkg: PackageJson,\n spec: NormalizationSpec,\n options: NormalizeManifestOptions,\n) {\n let modified = false;\n\n for (const depField of [\"dependencies\", \"devDependencies\", \"peerDependencies\"]) {\n const deps = pkg[depField];\n if (!deps || typeof deps !== \"object\") continue;\n if (normalizeDependencyMap(deps as Record<string, string>, spec, options)) {\n modified = true;\n }\n }\n\n if (pkg.workspaces && typeof pkg.workspaces === \"object\") {\n const workspaces = pkg.workspaces as {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n\n if (options.excludeFrameworkWorkspaces && Array.isArray(workspaces.packages)) {\n const nextPackages = workspaces.packages.filter(\n (entry) => !FRAMEWORK_PACKAGES.some((name) => entry === `packages/${name}`),\n );\n if (nextPackages.length !== workspaces.packages.length) {\n workspaces.packages = nextPackages;\n modified = true;\n }\n }\n\n if (workspaces.catalog && typeof workspaces.catalog === \"object\") {\n for (const [name, version] of Object.entries(workspaces.catalog)) {\n const resolved = spec.rootCatalog[name];\n if (resolved && resolved !== version) {\n workspaces.catalog[name] = resolved;\n modified = true;\n continue;\n }\n\n if (version === \"workspace:*\" && spec.frameworkVersions[name]) {\n workspaces.catalog[name] = `^${spec.frameworkVersions[name]}`;\n modified = true;\n }\n }\n }\n }\n\n if (options.removeWorkspaces && \"workspaces\" in pkg) {\n delete pkg.workspaces;\n modified = true;\n }\n\n if (options.removePublishScripts && pkg.scripts && typeof pkg.scripts === \"object\") {\n const scripts = pkg.scripts as Record<string, string>;\n let scriptsModified = false;\n for (const key of [\"prepublishOnly\", \"prepack\", \"prepare\", \"postpack\"]) {\n if (key in scripts) {\n delete scripts[key];\n scriptsModified = true;\n }\n }\n if (scriptsModified) {\n modified = true;\n if (Object.keys(scripts).length === 0) {\n delete pkg.scripts;\n }\n }\n }\n\n return modified;\n}\n\nexport async function normalizePackageManifestsInTree(opts: NormalizeTreeOptions) {\n const spec = loadManifestNormalizationSpec(opts.sourceRootDir);\n const files = await glob(\"**/package.json\", {\n cwd: opts.targetDir,\n nodir: true,\n dot: false,\n absolute: true,\n ignore: [\"**/node_modules/**\"],\n });\n\n const updatedFiles: string[] = [];\n\n for (const filePath of files) {\n const pkg = readJson<PackageJson>(filePath);\n if (normalizePackageManifest(pkg, spec, opts)) {\n writeJson(filePath, pkg);\n updatedFiles.push(filePath);\n }\n }\n\n return updatedFiles;\n}\n\nfunction shouldCopyPackageFile(sourceDir: string, filePath: string) {\n const relPath = relative(sourceDir, filePath);\n if (!relPath) return true;\n const segments = relPath.split(sep);\n return !segments.includes(\"node_modules\") && !segments.includes(\"tests\");\n}\n\nfunction stripDevelopmentExports(pkg: PackageJson) {\n const exports = pkg.exports;\n if (!exports || typeof exports !== \"object\") return;\n\n for (const key of Object.keys(exports as Record<string, unknown>)) {\n const entry = (exports as Record<string, unknown>)[key];\n if (entry && typeof entry === \"object\") {\n delete (entry as Record<string, unknown>).development;\n }\n }\n}\n\nexport function stageReleasePackage(opts: {\n repoRoot: string;\n packageName: string;\n outDir: string;\n}) {\n const sourceDir = join(opts.repoRoot, \"packages\", opts.packageName);\n\n rmSync(opts.outDir, { recursive: true, force: true });\n mkdirSync(dirname(opts.outDir), { recursive: true });\n cpSync(sourceDir, opts.outDir, {\n recursive: true,\n filter: (filePath) => shouldCopyPackageFile(sourceDir, filePath),\n });\n rmSync(join(opts.outDir, \"tests\"), { recursive: true, force: true });\n\n const packageJsonPath = join(opts.outDir, \"package.json\");\n const spec = loadManifestNormalizationSpec(opts.repoRoot);\n const pkg = readJson<PackageJson>(packageJsonPath);\n\n normalizePackageManifest(pkg, spec, {\n resolveCatalogRefs: true,\n preserveCatalogRefs: false,\n removeWorkspaces: true,\n removePublishScripts: true,\n });\n\n stripDevelopmentExports(pkg);\n\n writeJson(packageJsonPath, pkg);\n}\n\nexport function stageReleasePackages(opts: {\n repoRoot: string;\n outDir: string;\n packageNames?: string[];\n}) {\n const packageNames = opts.packageNames ?? [...FRAMEWORK_PACKAGES];\n rmSync(opts.outDir, { recursive: true, force: true });\n mkdirSync(opts.outDir, { recursive: true });\n\n for (const packageName of packageNames) {\n stageReleasePackage({\n repoRoot: opts.repoRoot,\n packageName,\n outDir: join(opts.outDir, packageName),\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"manifest-normalizer.cjs","names":["readFileSync","readWorkspaceCatalog","join","existsSync"],"sources":["../../src/internal/manifest-normalizer.ts"],"sourcesContent":["import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, relative, sep } from \"node:path\";\nimport { glob } from \"glob\";\nimport { readWorkspaceCatalog } from \"../workspace-catalog\";\n\nconst FRAMEWORK_PACKAGES = [\"every-plugin\", \"everything-dev\"] as const;\n\nconst CATALOG_TOOL_PACKAGES = [\n \"@rspack/core\",\n \"@rspack/cli\",\n \"@rsbuild/core\",\n \"@rsbuild/plugin-react\",\n \"@module-federation/enhanced\",\n \"@module-federation/node\",\n \"@module-federation/rsbuild-plugin\",\n \"@module-federation/runtime-core\",\n \"@module-federation/sdk\",\n \"@module-federation/dts-plugin\",\n] as const;\n\ntype PackageJson = Record<string, unknown>;\n\ntype NormalizationSpec = {\n rootCatalog: Record<string, string>;\n frameworkVersions: Record<string, string>;\n};\n\ntype NormalizeManifestOptions = {\n resolveCatalogRefs: boolean;\n preserveCatalogRefs?: boolean;\n excludeFrameworkWorkspaces?: boolean;\n removeWorkspaceDeps?: string[];\n removeWorkspaces?: boolean;\n removePublishScripts?: boolean;\n};\n\nexport type NormalizeTreeOptions = NormalizeManifestOptions & {\n sourceRootDir: string;\n targetDir: string;\n};\n\nfunction readJson<T>(filePath: string): T {\n return JSON.parse(readFileSync(filePath, \"utf-8\")) as T;\n}\n\nfunction extractExactVersion(input: string | undefined): string | null {\n if (!input) return null;\n const match = input.match(/\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?/);\n return match ? match[0] : null;\n}\n\nfunction writeJson(filePath: string, value: PackageJson) {\n writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\\n`);\n}\n\nexport function loadManifestNormalizationSpec(sourceRootDir: string): NormalizationSpec {\n const rootCatalog = readWorkspaceCatalog(sourceRootDir);\n const frameworkVersions: Record<string, string> = {};\n\n for (const packageName of FRAMEWORK_PACKAGES) {\n const sourcePackagePath = join(sourceRootDir, \"packages\", packageName, \"package.json\");\n const localPackagePath = join(import.meta.dirname, \"..\", \"..\", packageName, \"package.json\");\n const packageVersion = existsSync(localPackagePath)\n ? readJson<{ version: string }>(localPackagePath).version\n : existsSync(sourcePackagePath)\n ? readJson<{ version: string }>(sourcePackagePath).version\n : extractExactVersion(rootCatalog[packageName]);\n\n if (!packageVersion) {\n throw new Error(`Could not resolve version for ${packageName}`);\n }\n\n frameworkVersions[packageName] = packageVersion;\n rootCatalog[packageName] = `^${packageVersion}`;\n }\n\n return { rootCatalog, frameworkVersions };\n}\n\nfunction normalizeDependencyMap(\n map: Record<string, string>,\n spec: NormalizationSpec,\n options: NormalizeManifestOptions,\n) {\n const catalogPackages = new Set<string>([...FRAMEWORK_PACKAGES, ...CATALOG_TOOL_PACKAGES]);\n\n let modified = false;\n\n for (const [name, version] of Object.entries(map)) {\n if (options.preserveCatalogRefs && catalogPackages.has(name)) {\n if (version !== \"catalog:\") {\n map[name] = \"catalog:\";\n modified = true;\n }\n continue;\n }\n\n if (version.startsWith(\"workspace:\")) {\n const frameworkVersion = spec.frameworkVersions[name];\n if (frameworkVersion) {\n map[name] = `^${frameworkVersion}`;\n modified = true;\n continue;\n }\n\n if (options.removeWorkspaceDeps?.includes(name)) {\n delete map[name];\n modified = true;\n continue;\n }\n\n // A workspace dep on a non-framework member (e.g. better-near-auth)\n // cannot resolve in a generated child — the member does not exist\n // there. Children keep the catalog: protocol (the catalog pins the\n // published version); release staging resolves the real range.\n if (spec.rootCatalog[name]) {\n map[name] = options.preserveCatalogRefs ? \"catalog:\" : spec.rootCatalog[name];\n modified = true;\n }\n continue;\n }\n\n if (options.resolveCatalogRefs && version.startsWith(\"catalog:\")) {\n const resolved = spec.rootCatalog[name];\n if (resolved) {\n map[name] = resolved;\n modified = true;\n }\n }\n }\n\n return modified;\n}\n\nexport function normalizePackageManifest(\n pkg: PackageJson,\n spec: NormalizationSpec,\n options: NormalizeManifestOptions,\n) {\n let modified = false;\n\n for (const depField of [\"dependencies\", \"devDependencies\", \"peerDependencies\"]) {\n const deps = pkg[depField];\n if (!deps || typeof deps !== \"object\") continue;\n if (normalizeDependencyMap(deps as Record<string, string>, spec, options)) {\n modified = true;\n }\n }\n\n if (pkg.workspaces && typeof pkg.workspaces === \"object\") {\n const workspaces = pkg.workspaces as {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n\n if (options.excludeFrameworkWorkspaces && Array.isArray(workspaces.packages)) {\n const nextPackages = workspaces.packages.filter(\n (entry) => !FRAMEWORK_PACKAGES.some((name) => entry === `packages/${name}`),\n );\n if (nextPackages.length !== workspaces.packages.length) {\n workspaces.packages = nextPackages;\n modified = true;\n }\n }\n\n if (workspaces.catalog && typeof workspaces.catalog === \"object\") {\n for (const [name, version] of Object.entries(workspaces.catalog)) {\n const resolved = spec.rootCatalog[name];\n if (resolved && resolved !== version) {\n workspaces.catalog[name] = resolved;\n modified = true;\n continue;\n }\n\n if (version === \"workspace:*\" && spec.frameworkVersions[name]) {\n workspaces.catalog[name] = `^${spec.frameworkVersions[name]}`;\n modified = true;\n }\n }\n }\n }\n\n if (options.removeWorkspaces && \"workspaces\" in pkg) {\n delete pkg.workspaces;\n modified = true;\n }\n\n if (options.removePublishScripts && pkg.scripts && typeof pkg.scripts === \"object\") {\n const scripts = pkg.scripts as Record<string, string>;\n let scriptsModified = false;\n for (const key of [\"prepublishOnly\", \"prepack\", \"prepare\", \"postpack\"]) {\n if (key in scripts) {\n delete scripts[key];\n scriptsModified = true;\n }\n }\n if (scriptsModified) {\n modified = true;\n if (Object.keys(scripts).length === 0) {\n delete pkg.scripts;\n }\n }\n }\n\n return modified;\n}\n\nexport async function normalizePackageManifestsInTree(opts: NormalizeTreeOptions) {\n const spec = loadManifestNormalizationSpec(opts.sourceRootDir);\n const files = await glob(\"**/package.json\", {\n cwd: opts.targetDir,\n nodir: true,\n dot: false,\n absolute: true,\n ignore: [\"**/node_modules/**\"],\n });\n\n const updatedFiles: string[] = [];\n\n for (const filePath of files) {\n const pkg = readJson<PackageJson>(filePath);\n if (normalizePackageManifest(pkg, spec, opts)) {\n writeJson(filePath, pkg);\n updatedFiles.push(filePath);\n }\n }\n\n return updatedFiles;\n}\n\nfunction shouldCopyPackageFile(sourceDir: string, filePath: string) {\n const relPath = relative(sourceDir, filePath);\n if (!relPath) return true;\n const segments = relPath.split(sep);\n return !segments.includes(\"node_modules\") && !segments.includes(\"tests\");\n}\n\nfunction stripDevelopmentExports(pkg: PackageJson) {\n const exports = pkg.exports;\n if (!exports || typeof exports !== \"object\") return;\n\n for (const key of Object.keys(exports as Record<string, unknown>)) {\n const entry = (exports as Record<string, unknown>)[key];\n if (entry && typeof entry === \"object\") {\n delete (entry as Record<string, unknown>).development;\n }\n }\n}\n\nexport function stageReleasePackage(opts: {\n repoRoot: string;\n packageName: string;\n outDir: string;\n}) {\n const sourceDir = join(opts.repoRoot, \"packages\", opts.packageName);\n\n rmSync(opts.outDir, { recursive: true, force: true });\n mkdirSync(dirname(opts.outDir), { recursive: true });\n cpSync(sourceDir, opts.outDir, {\n recursive: true,\n filter: (filePath) => shouldCopyPackageFile(sourceDir, filePath),\n });\n rmSync(join(opts.outDir, \"tests\"), { recursive: true, force: true });\n\n const packageJsonPath = join(opts.outDir, \"package.json\");\n const spec = loadManifestNormalizationSpec(opts.repoRoot);\n const pkg = readJson<PackageJson>(packageJsonPath);\n\n normalizePackageManifest(pkg, spec, {\n resolveCatalogRefs: true,\n preserveCatalogRefs: false,\n removeWorkspaces: true,\n removePublishScripts: true,\n });\n\n stripDevelopmentExports(pkg);\n\n writeJson(packageJsonPath, pkg);\n}\n\nexport function stageReleasePackages(opts: {\n repoRoot: string;\n outDir: string;\n packageNames?: string[];\n}) {\n const packageNames = opts.packageNames ?? [...FRAMEWORK_PACKAGES];\n rmSync(opts.outDir, { recursive: true, force: true });\n mkdirSync(opts.outDir, { recursive: true });\n\n for (const packageName of packageNames) {\n stageReleasePackage({\n repoRoot: opts.repoRoot,\n packageName,\n outDir: join(opts.outDir, packageName),\n });\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
+ import { readWorkspaceCatalog } from "../workspace-catalog.mjs";
1
2
  import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2
- import { dirname, join, relative } from "node:path";
3
+ import { dirname, join, relative, sep } from "node:path";
3
4
  import { glob } from "glob";
4
5
 
5
6
  //#region src/internal/manifest-normalizer.ts
@@ -28,7 +29,7 @@ function writeJson(filePath, value) {
28
29
  writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`);
29
30
  }
30
31
  function loadManifestNormalizationSpec(sourceRootDir) {
31
- const rootCatalog = { ...readJson(join(sourceRootDir, "package.json")).workspaces?.catalog ?? {} };
32
+ const rootCatalog = readWorkspaceCatalog(sourceRootDir);
32
33
  const frameworkVersions = {};
33
34
  for (const packageName of FRAMEWORK_PACKAGES) {
34
35
  const sourcePackagePath = join(sourceRootDir, "packages", packageName, "package.json");
@@ -54,7 +55,7 @@ function normalizeDependencyMap(map, spec, options) {
54
55
  }
55
56
  continue;
56
57
  }
57
- if (version === "workspace:*") {
58
+ if (version.startsWith("workspace:")) {
58
59
  const frameworkVersion = spec.frameworkVersions[name];
59
60
  if (frameworkVersion) {
60
61
  map[name] = `^${frameworkVersion}`;
@@ -64,6 +65,11 @@ function normalizeDependencyMap(map, spec, options) {
64
65
  if (options.removeWorkspaceDeps?.includes(name)) {
65
66
  delete map[name];
66
67
  modified = true;
68
+ continue;
69
+ }
70
+ if (spec.rootCatalog[name]) {
71
+ map[name] = options.preserveCatalogRefs ? "catalog:" : spec.rootCatalog[name];
72
+ modified = true;
67
73
  }
68
74
  continue;
69
75
  }
@@ -1 +1 @@
1
- {"version":3,"file":"manifest-normalizer.mjs","names":[],"sources":["../../src/internal/manifest-normalizer.ts"],"sourcesContent":["import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, relative, sep } from \"node:path\";\nimport { glob } from \"glob\";\n\nconst FRAMEWORK_PACKAGES = [\"every-plugin\", \"everything-dev\"] as const;\n\nconst CATALOG_TOOL_PACKAGES = [\n \"@rspack/core\",\n \"@rspack/cli\",\n \"@rsbuild/core\",\n \"@rsbuild/plugin-react\",\n \"@module-federation/enhanced\",\n \"@module-federation/node\",\n \"@module-federation/rsbuild-plugin\",\n \"@module-federation/runtime-core\",\n \"@module-federation/sdk\",\n \"@module-federation/dts-plugin\",\n] as const;\n\ntype PackageJson = Record<string, unknown>;\n\ntype NormalizationSpec = {\n rootCatalog: Record<string, string>;\n frameworkVersions: Record<string, string>;\n};\n\ntype NormalizeManifestOptions = {\n resolveCatalogRefs: boolean;\n preserveCatalogRefs?: boolean;\n excludeFrameworkWorkspaces?: boolean;\n removeWorkspaceDeps?: string[];\n removeWorkspaces?: boolean;\n removePublishScripts?: boolean;\n};\n\nexport type NormalizeTreeOptions = NormalizeManifestOptions & {\n sourceRootDir: string;\n targetDir: string;\n};\n\nfunction readJson<T>(filePath: string): T {\n return JSON.parse(readFileSync(filePath, \"utf-8\")) as T;\n}\n\nfunction extractExactVersion(input: string | undefined): string | null {\n if (!input) return null;\n const match = input.match(/\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?/);\n return match ? match[0] : null;\n}\n\nfunction writeJson(filePath: string, value: PackageJson) {\n writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\\n`);\n}\n\nexport function loadManifestNormalizationSpec(sourceRootDir: string): NormalizationSpec {\n const rootPackage = readJson<PackageJson>(join(sourceRootDir, \"package.json\"));\n const rootCatalog = {\n ...(((rootPackage.workspaces as { catalog?: Record<string, string> } | undefined)?.catalog ??\n {}) as Record<string, string>),\n };\n const frameworkVersions: Record<string, string> = {};\n\n for (const packageName of FRAMEWORK_PACKAGES) {\n const sourcePackagePath = join(sourceRootDir, \"packages\", packageName, \"package.json\");\n const localPackagePath = join(import.meta.dirname, \"..\", \"..\", packageName, \"package.json\");\n const packageVersion = existsSync(localPackagePath)\n ? readJson<{ version: string }>(localPackagePath).version\n : existsSync(sourcePackagePath)\n ? readJson<{ version: string }>(sourcePackagePath).version\n : extractExactVersion(rootCatalog[packageName]);\n\n if (!packageVersion) {\n throw new Error(`Could not resolve version for ${packageName}`);\n }\n\n frameworkVersions[packageName] = packageVersion;\n rootCatalog[packageName] = `^${packageVersion}`;\n }\n\n return { rootCatalog, frameworkVersions };\n}\n\nfunction normalizeDependencyMap(\n map: Record<string, string>,\n spec: NormalizationSpec,\n options: NormalizeManifestOptions,\n) {\n const catalogPackages = new Set<string>([...FRAMEWORK_PACKAGES, ...CATALOG_TOOL_PACKAGES]);\n\n let modified = false;\n\n for (const [name, version] of Object.entries(map)) {\n if (options.preserveCatalogRefs && catalogPackages.has(name)) {\n if (version !== \"catalog:\") {\n map[name] = \"catalog:\";\n modified = true;\n }\n continue;\n }\n\n if (version === \"workspace:*\") {\n const frameworkVersion = spec.frameworkVersions[name];\n if (frameworkVersion) {\n map[name] = `^${frameworkVersion}`;\n modified = true;\n continue;\n }\n\n if (options.removeWorkspaceDeps?.includes(name)) {\n delete map[name];\n modified = true;\n }\n continue;\n }\n\n if (options.resolveCatalogRefs && version.startsWith(\"catalog:\")) {\n const resolved = spec.rootCatalog[name];\n if (resolved) {\n map[name] = resolved;\n modified = true;\n }\n }\n }\n\n return modified;\n}\n\nexport function normalizePackageManifest(\n pkg: PackageJson,\n spec: NormalizationSpec,\n options: NormalizeManifestOptions,\n) {\n let modified = false;\n\n for (const depField of [\"dependencies\", \"devDependencies\", \"peerDependencies\"]) {\n const deps = pkg[depField];\n if (!deps || typeof deps !== \"object\") continue;\n if (normalizeDependencyMap(deps as Record<string, string>, spec, options)) {\n modified = true;\n }\n }\n\n if (pkg.workspaces && typeof pkg.workspaces === \"object\") {\n const workspaces = pkg.workspaces as {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n\n if (options.excludeFrameworkWorkspaces && Array.isArray(workspaces.packages)) {\n const nextPackages = workspaces.packages.filter(\n (entry) => !FRAMEWORK_PACKAGES.some((name) => entry === `packages/${name}`),\n );\n if (nextPackages.length !== workspaces.packages.length) {\n workspaces.packages = nextPackages;\n modified = true;\n }\n }\n\n if (workspaces.catalog && typeof workspaces.catalog === \"object\") {\n for (const [name, version] of Object.entries(workspaces.catalog)) {\n const resolved = spec.rootCatalog[name];\n if (resolved && resolved !== version) {\n workspaces.catalog[name] = resolved;\n modified = true;\n continue;\n }\n\n if (version === \"workspace:*\" && spec.frameworkVersions[name]) {\n workspaces.catalog[name] = `^${spec.frameworkVersions[name]}`;\n modified = true;\n }\n }\n }\n }\n\n if (options.removeWorkspaces && \"workspaces\" in pkg) {\n delete pkg.workspaces;\n modified = true;\n }\n\n if (options.removePublishScripts && pkg.scripts && typeof pkg.scripts === \"object\") {\n const scripts = pkg.scripts as Record<string, string>;\n let scriptsModified = false;\n for (const key of [\"prepublishOnly\", \"prepack\", \"prepare\", \"postpack\"]) {\n if (key in scripts) {\n delete scripts[key];\n scriptsModified = true;\n }\n }\n if (scriptsModified) {\n modified = true;\n if (Object.keys(scripts).length === 0) {\n delete pkg.scripts;\n }\n }\n }\n\n return modified;\n}\n\nexport async function normalizePackageManifestsInTree(opts: NormalizeTreeOptions) {\n const spec = loadManifestNormalizationSpec(opts.sourceRootDir);\n const files = await glob(\"**/package.json\", {\n cwd: opts.targetDir,\n nodir: true,\n dot: false,\n absolute: true,\n ignore: [\"**/node_modules/**\"],\n });\n\n const updatedFiles: string[] = [];\n\n for (const filePath of files) {\n const pkg = readJson<PackageJson>(filePath);\n if (normalizePackageManifest(pkg, spec, opts)) {\n writeJson(filePath, pkg);\n updatedFiles.push(filePath);\n }\n }\n\n return updatedFiles;\n}\n\nfunction shouldCopyPackageFile(sourceDir: string, filePath: string) {\n const relPath = relative(sourceDir, filePath);\n if (!relPath) return true;\n const segments = relPath.split(sep);\n return !segments.includes(\"node_modules\") && !segments.includes(\"tests\");\n}\n\nfunction stripDevelopmentExports(pkg: PackageJson) {\n const exports = pkg.exports;\n if (!exports || typeof exports !== \"object\") return;\n\n for (const key of Object.keys(exports as Record<string, unknown>)) {\n const entry = (exports as Record<string, unknown>)[key];\n if (entry && typeof entry === \"object\") {\n delete (entry as Record<string, unknown>).development;\n }\n }\n}\n\nexport function stageReleasePackage(opts: {\n repoRoot: string;\n packageName: string;\n outDir: string;\n}) {\n const sourceDir = join(opts.repoRoot, \"packages\", opts.packageName);\n\n rmSync(opts.outDir, { recursive: true, force: true });\n mkdirSync(dirname(opts.outDir), { recursive: true });\n cpSync(sourceDir, opts.outDir, {\n recursive: true,\n filter: (filePath) => shouldCopyPackageFile(sourceDir, filePath),\n });\n rmSync(join(opts.outDir, \"tests\"), { recursive: true, force: true });\n\n const packageJsonPath = join(opts.outDir, \"package.json\");\n const spec = loadManifestNormalizationSpec(opts.repoRoot);\n const pkg = readJson<PackageJson>(packageJsonPath);\n\n normalizePackageManifest(pkg, spec, {\n resolveCatalogRefs: true,\n preserveCatalogRefs: false,\n removeWorkspaces: true,\n removePublishScripts: true,\n });\n\n stripDevelopmentExports(pkg);\n\n writeJson(packageJsonPath, pkg);\n}\n\nexport function stageReleasePackages(opts: {\n repoRoot: string;\n outDir: string;\n packageNames?: string[];\n}) {\n const packageNames = opts.packageNames ?? [...FRAMEWORK_PACKAGES];\n rmSync(opts.outDir, { recursive: true, force: true });\n mkdirSync(opts.outDir, { recursive: true });\n\n for (const packageName of packageNames) {\n stageReleasePackage({\n repoRoot: opts.repoRoot,\n packageName,\n outDir: join(opts.outDir, packageName),\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"manifest-normalizer.mjs","names":[],"sources":["../../src/internal/manifest-normalizer.ts"],"sourcesContent":["import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, relative, sep } from \"node:path\";\nimport { glob } from \"glob\";\nimport { readWorkspaceCatalog } from \"../workspace-catalog\";\n\nconst FRAMEWORK_PACKAGES = [\"every-plugin\", \"everything-dev\"] as const;\n\nconst CATALOG_TOOL_PACKAGES = [\n \"@rspack/core\",\n \"@rspack/cli\",\n \"@rsbuild/core\",\n \"@rsbuild/plugin-react\",\n \"@module-federation/enhanced\",\n \"@module-federation/node\",\n \"@module-federation/rsbuild-plugin\",\n \"@module-federation/runtime-core\",\n \"@module-federation/sdk\",\n \"@module-federation/dts-plugin\",\n] as const;\n\ntype PackageJson = Record<string, unknown>;\n\ntype NormalizationSpec = {\n rootCatalog: Record<string, string>;\n frameworkVersions: Record<string, string>;\n};\n\ntype NormalizeManifestOptions = {\n resolveCatalogRefs: boolean;\n preserveCatalogRefs?: boolean;\n excludeFrameworkWorkspaces?: boolean;\n removeWorkspaceDeps?: string[];\n removeWorkspaces?: boolean;\n removePublishScripts?: boolean;\n};\n\nexport type NormalizeTreeOptions = NormalizeManifestOptions & {\n sourceRootDir: string;\n targetDir: string;\n};\n\nfunction readJson<T>(filePath: string): T {\n return JSON.parse(readFileSync(filePath, \"utf-8\")) as T;\n}\n\nfunction extractExactVersion(input: string | undefined): string | null {\n if (!input) return null;\n const match = input.match(/\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?/);\n return match ? match[0] : null;\n}\n\nfunction writeJson(filePath: string, value: PackageJson) {\n writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\\n`);\n}\n\nexport function loadManifestNormalizationSpec(sourceRootDir: string): NormalizationSpec {\n const rootCatalog = readWorkspaceCatalog(sourceRootDir);\n const frameworkVersions: Record<string, string> = {};\n\n for (const packageName of FRAMEWORK_PACKAGES) {\n const sourcePackagePath = join(sourceRootDir, \"packages\", packageName, \"package.json\");\n const localPackagePath = join(import.meta.dirname, \"..\", \"..\", packageName, \"package.json\");\n const packageVersion = existsSync(localPackagePath)\n ? readJson<{ version: string }>(localPackagePath).version\n : existsSync(sourcePackagePath)\n ? readJson<{ version: string }>(sourcePackagePath).version\n : extractExactVersion(rootCatalog[packageName]);\n\n if (!packageVersion) {\n throw new Error(`Could not resolve version for ${packageName}`);\n }\n\n frameworkVersions[packageName] = packageVersion;\n rootCatalog[packageName] = `^${packageVersion}`;\n }\n\n return { rootCatalog, frameworkVersions };\n}\n\nfunction normalizeDependencyMap(\n map: Record<string, string>,\n spec: NormalizationSpec,\n options: NormalizeManifestOptions,\n) {\n const catalogPackages = new Set<string>([...FRAMEWORK_PACKAGES, ...CATALOG_TOOL_PACKAGES]);\n\n let modified = false;\n\n for (const [name, version] of Object.entries(map)) {\n if (options.preserveCatalogRefs && catalogPackages.has(name)) {\n if (version !== \"catalog:\") {\n map[name] = \"catalog:\";\n modified = true;\n }\n continue;\n }\n\n if (version.startsWith(\"workspace:\")) {\n const frameworkVersion = spec.frameworkVersions[name];\n if (frameworkVersion) {\n map[name] = `^${frameworkVersion}`;\n modified = true;\n continue;\n }\n\n if (options.removeWorkspaceDeps?.includes(name)) {\n delete map[name];\n modified = true;\n continue;\n }\n\n // A workspace dep on a non-framework member (e.g. better-near-auth)\n // cannot resolve in a generated child — the member does not exist\n // there. Children keep the catalog: protocol (the catalog pins the\n // published version); release staging resolves the real range.\n if (spec.rootCatalog[name]) {\n map[name] = options.preserveCatalogRefs ? \"catalog:\" : spec.rootCatalog[name];\n modified = true;\n }\n continue;\n }\n\n if (options.resolveCatalogRefs && version.startsWith(\"catalog:\")) {\n const resolved = spec.rootCatalog[name];\n if (resolved) {\n map[name] = resolved;\n modified = true;\n }\n }\n }\n\n return modified;\n}\n\nexport function normalizePackageManifest(\n pkg: PackageJson,\n spec: NormalizationSpec,\n options: NormalizeManifestOptions,\n) {\n let modified = false;\n\n for (const depField of [\"dependencies\", \"devDependencies\", \"peerDependencies\"]) {\n const deps = pkg[depField];\n if (!deps || typeof deps !== \"object\") continue;\n if (normalizeDependencyMap(deps as Record<string, string>, spec, options)) {\n modified = true;\n }\n }\n\n if (pkg.workspaces && typeof pkg.workspaces === \"object\") {\n const workspaces = pkg.workspaces as {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n\n if (options.excludeFrameworkWorkspaces && Array.isArray(workspaces.packages)) {\n const nextPackages = workspaces.packages.filter(\n (entry) => !FRAMEWORK_PACKAGES.some((name) => entry === `packages/${name}`),\n );\n if (nextPackages.length !== workspaces.packages.length) {\n workspaces.packages = nextPackages;\n modified = true;\n }\n }\n\n if (workspaces.catalog && typeof workspaces.catalog === \"object\") {\n for (const [name, version] of Object.entries(workspaces.catalog)) {\n const resolved = spec.rootCatalog[name];\n if (resolved && resolved !== version) {\n workspaces.catalog[name] = resolved;\n modified = true;\n continue;\n }\n\n if (version === \"workspace:*\" && spec.frameworkVersions[name]) {\n workspaces.catalog[name] = `^${spec.frameworkVersions[name]}`;\n modified = true;\n }\n }\n }\n }\n\n if (options.removeWorkspaces && \"workspaces\" in pkg) {\n delete pkg.workspaces;\n modified = true;\n }\n\n if (options.removePublishScripts && pkg.scripts && typeof pkg.scripts === \"object\") {\n const scripts = pkg.scripts as Record<string, string>;\n let scriptsModified = false;\n for (const key of [\"prepublishOnly\", \"prepack\", \"prepare\", \"postpack\"]) {\n if (key in scripts) {\n delete scripts[key];\n scriptsModified = true;\n }\n }\n if (scriptsModified) {\n modified = true;\n if (Object.keys(scripts).length === 0) {\n delete pkg.scripts;\n }\n }\n }\n\n return modified;\n}\n\nexport async function normalizePackageManifestsInTree(opts: NormalizeTreeOptions) {\n const spec = loadManifestNormalizationSpec(opts.sourceRootDir);\n const files = await glob(\"**/package.json\", {\n cwd: opts.targetDir,\n nodir: true,\n dot: false,\n absolute: true,\n ignore: [\"**/node_modules/**\"],\n });\n\n const updatedFiles: string[] = [];\n\n for (const filePath of files) {\n const pkg = readJson<PackageJson>(filePath);\n if (normalizePackageManifest(pkg, spec, opts)) {\n writeJson(filePath, pkg);\n updatedFiles.push(filePath);\n }\n }\n\n return updatedFiles;\n}\n\nfunction shouldCopyPackageFile(sourceDir: string, filePath: string) {\n const relPath = relative(sourceDir, filePath);\n if (!relPath) return true;\n const segments = relPath.split(sep);\n return !segments.includes(\"node_modules\") && !segments.includes(\"tests\");\n}\n\nfunction stripDevelopmentExports(pkg: PackageJson) {\n const exports = pkg.exports;\n if (!exports || typeof exports !== \"object\") return;\n\n for (const key of Object.keys(exports as Record<string, unknown>)) {\n const entry = (exports as Record<string, unknown>)[key];\n if (entry && typeof entry === \"object\") {\n delete (entry as Record<string, unknown>).development;\n }\n }\n}\n\nexport function stageReleasePackage(opts: {\n repoRoot: string;\n packageName: string;\n outDir: string;\n}) {\n const sourceDir = join(opts.repoRoot, \"packages\", opts.packageName);\n\n rmSync(opts.outDir, { recursive: true, force: true });\n mkdirSync(dirname(opts.outDir), { recursive: true });\n cpSync(sourceDir, opts.outDir, {\n recursive: true,\n filter: (filePath) => shouldCopyPackageFile(sourceDir, filePath),\n });\n rmSync(join(opts.outDir, \"tests\"), { recursive: true, force: true });\n\n const packageJsonPath = join(opts.outDir, \"package.json\");\n const spec = loadManifestNormalizationSpec(opts.repoRoot);\n const pkg = readJson<PackageJson>(packageJsonPath);\n\n normalizePackageManifest(pkg, spec, {\n resolveCatalogRefs: true,\n preserveCatalogRefs: false,\n removeWorkspaces: true,\n removePublishScripts: true,\n });\n\n stripDevelopmentExports(pkg);\n\n writeJson(packageJsonPath, pkg);\n}\n\nexport function stageReleasePackages(opts: {\n repoRoot: string;\n outDir: string;\n packageNames?: string[];\n}) {\n const packageNames = opts.packageNames ?? [...FRAMEWORK_PACKAGES];\n rmSync(opts.outDir, { recursive: true, force: true });\n mkdirSync(opts.outDir, { recursive: true });\n\n for (const packageName of packageNames) {\n stageReleasePackage({\n repoRoot: opts.repoRoot,\n packageName,\n outDir: join(opts.outDir, packageName),\n });\n }\n}\n"],"mappings":"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"}