fundus 0.17.2 → 0.19.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 (221) hide show
  1. package/README.md +60 -121
  2. package/build/client/_app/immutable/assets/2.C-1MfvLQ.css +1 -0
  3. package/build/client/_app/immutable/assets/2.C-1MfvLQ.css.br +0 -0
  4. package/build/client/_app/immutable/assets/2.C-1MfvLQ.css.gz +0 -0
  5. package/build/client/_app/immutable/assets/{3.66PJT3JC.css → 3.q3CUOEpz.css} +1 -1
  6. package/build/client/_app/immutable/assets/3.q3CUOEpz.css.br +0 -0
  7. package/build/client/_app/immutable/assets/3.q3CUOEpz.css.gz +0 -0
  8. package/build/client/_app/immutable/assets/{AssetSourceMenu.Buj2UxUg.css → AssetSourceMenu.CgyMTAb6.css} +1 -1
  9. package/build/client/_app/immutable/assets/AssetSourceMenu.CgyMTAb6.css.br +0 -0
  10. package/build/client/_app/immutable/assets/AssetSourceMenu.CgyMTAb6.css.gz +0 -0
  11. package/build/client/_app/immutable/chunks/Bly9uffh.js +1 -0
  12. package/build/client/_app/immutable/chunks/Bly9uffh.js.br +0 -0
  13. package/build/client/_app/immutable/chunks/Bly9uffh.js.gz +0 -0
  14. package/build/client/_app/immutable/chunks/{R0o69z6O.js → BpsKkIFc.js} +1 -1
  15. package/build/client/_app/immutable/chunks/BpsKkIFc.js.br +2 -0
  16. package/build/client/_app/immutable/chunks/BpsKkIFc.js.gz +0 -0
  17. package/build/client/_app/immutable/chunks/{jEVVu5G9.js → CrIZjnDr.js} +1 -1
  18. package/build/client/_app/immutable/chunks/CrIZjnDr.js.br +0 -0
  19. package/build/client/_app/immutable/chunks/CrIZjnDr.js.gz +0 -0
  20. package/build/client/_app/immutable/chunks/ZGU9Utak.js +108 -0
  21. package/build/client/_app/immutable/chunks/ZGU9Utak.js.br +0 -0
  22. package/build/client/_app/immutable/chunks/ZGU9Utak.js.gz +0 -0
  23. package/build/client/_app/immutable/chunks/lw3KP4og.js +2 -0
  24. package/build/client/_app/immutable/chunks/lw3KP4og.js.br +0 -0
  25. package/build/client/_app/immutable/chunks/lw3KP4og.js.gz +0 -0
  26. package/build/client/_app/immutable/entry/{app.DxYfHxs-.js → app.D-lO1MC-.js} +2 -2
  27. package/build/client/_app/immutable/entry/app.D-lO1MC-.js.br +0 -0
  28. package/build/client/_app/immutable/entry/app.D-lO1MC-.js.gz +0 -0
  29. package/build/client/_app/immutable/entry/start.BrSEFrid.js +1 -0
  30. package/build/client/_app/immutable/entry/start.BrSEFrid.js.br +1 -0
  31. package/build/client/_app/immutable/entry/start.BrSEFrid.js.gz +0 -0
  32. package/build/client/_app/immutable/nodes/{0.Do0MsVUC.js → 0.BPGg3A-F.js} +1 -1
  33. package/build/client/_app/immutable/nodes/0.BPGg3A-F.js.br +0 -0
  34. package/build/client/_app/immutable/nodes/0.BPGg3A-F.js.gz +0 -0
  35. package/build/client/_app/immutable/nodes/{1.DhfAdUbg.js → 1.-VJ5Mlss.js} +1 -1
  36. package/build/client/_app/immutable/nodes/1.-VJ5Mlss.js.br +1 -0
  37. package/build/client/_app/immutable/nodes/1.-VJ5Mlss.js.gz +0 -0
  38. package/build/client/_app/immutable/nodes/2.Dhyvb4bF.js +3 -0
  39. package/build/client/_app/immutable/nodes/2.Dhyvb4bF.js.br +0 -0
  40. package/build/client/_app/immutable/nodes/2.Dhyvb4bF.js.gz +0 -0
  41. package/build/client/_app/immutable/nodes/3.D9Fgsq-b.js +1 -0
  42. package/build/client/_app/immutable/nodes/3.D9Fgsq-b.js.br +0 -0
  43. package/build/client/_app/immutable/nodes/3.D9Fgsq-b.js.gz +0 -0
  44. package/build/client/_app/immutable/nodes/{4.gPNAednG.js → 4.DErtysFP.js} +1 -1
  45. package/build/client/_app/immutable/nodes/4.DErtysFP.js.br +0 -0
  46. package/build/client/_app/immutable/nodes/4.DErtysFP.js.gz +0 -0
  47. package/build/client/_app/version.json +1 -1
  48. package/build/client/_app/version.json.br +0 -0
  49. package/build/client/_app/version.json.gz +0 -0
  50. package/build/handler.js +7 -7
  51. package/build/index.js +7 -7
  52. package/build/server/chunks/chunks/{context.js-Dh0ibRIF.js → context.js-BIgcUcEl.js} +216 -604
  53. package/build/server/chunks/chunks/context.js-BIgcUcEl.js.map +1 -0
  54. package/build/server/chunks/chunks/{contract.js-_LTMZBo2.js → contract.js-B6KBK8D9.js} +59 -95
  55. package/build/server/chunks/chunks/contract.js-B6KBK8D9.js.map +1 -0
  56. package/build/server/chunks/chunks/{core.js-CTyKR4bu.js → core.js-Bp-ReC60.js} +38 -38
  57. package/build/server/chunks/chunks/core.js-Bp-ReC60.js.map +1 -0
  58. package/build/server/chunks/chunks/dependencies.js-pUkjICr5.js +45 -0
  59. package/build/server/chunks/chunks/dependencies.js-pUkjICr5.js.map +1 -0
  60. package/build/server/chunks/chunks/{exports.js-gUMFfqhw.js → exports.js-bhKV7cEL.js} +2 -2
  61. package/build/server/chunks/chunks/{exports.js-gUMFfqhw.js.map → exports.js-bhKV7cEL.js.map} +1 -1
  62. package/build/server/chunks/chunks/{http.js-BiqUcAuu.js → http.js-BTq44nR5.js} +2 -2
  63. package/build/server/chunks/chunks/{http.js-BiqUcAuu.js.map → http.js-BTq44nR5.js.map} +1 -1
  64. package/build/server/chunks/chunks/{internal.js-DvC1GD8s.js → internal.js-7MmaxxwZ.js} +3 -3
  65. package/build/server/chunks/chunks/{internal.js-DvC1GD8s.js.map → internal.js-7MmaxxwZ.js.map} +1 -1
  66. package/build/server/chunks/chunks/internal2.js-BlXt2rfE.js.map +1 -1
  67. package/build/server/chunks/chunks/{manifest-membership.js-at1ixQdW.js → manifest-membership.js-Dj3WwZgz.js} +2 -2
  68. package/build/server/chunks/chunks/{manifest-membership.js-at1ixQdW.js.map → manifest-membership.js-Dj3WwZgz.js.map} +1 -1
  69. package/build/server/chunks/chunks/{raw-reconciliation.js-CUH8IIJx.js → raw-reconciliation.js-mWOAOdgL.js} +3 -3
  70. package/build/server/chunks/chunks/raw-reconciliation.js-mWOAOdgL.js.map +1 -0
  71. package/build/server/chunks/chunks/{raw-reconciliation2.js-z4xl5zw2.js → raw-reconciliation2.js-Bo1jJgvd.js} +2 -2
  72. package/build/server/chunks/chunks/{raw-reconciliation2.js-z4xl5zw2.js.map → raw-reconciliation2.js-Bo1jJgvd.js.map} +1 -1
  73. package/build/server/chunks/chunks/{shared.js-nXNT--BO.js → shared.js-B0m3s2U9.js} +2 -2
  74. package/build/server/chunks/chunks/{shared.js-nXNT--BO.js.map → shared.js-B0m3s2U9.js.map} +1 -1
  75. package/build/server/chunks/chunks/{utils.js-C5pr7OK-.js → utils.js-BXV0zq44.js} +3 -3
  76. package/build/server/chunks/chunks/{utils.js-C5pr7OK-.js.map → utils.js-BXV0zq44.js.map} +1 -1
  77. package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-CdDjuW0r.js → _server.ts.js-B_aa_zh7.js} +6 -6
  78. package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-CdDjuW0r.js.map → _server.ts.js-B_aa_zh7.js.map} +1 -1
  79. package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-OWM1eORG.js → _server.ts.js-DbEPdkbO.js} +8 -8
  80. package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-OWM1eORG.js.map → _server.ts.js-DbEPdkbO.js.map} +1 -1
  81. package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-DoG-7ZpZ.js → _server.ts.js-BzA96yBM.js} +8 -8
  82. package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-DoG-7ZpZ.js.map → _server.ts.js-BzA96yBM.js.map} +1 -1
  83. package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-CAWjVeGd.js → _server.ts.js-fQAXFRLh.js} +8 -8
  84. package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-CAWjVeGd.js.map → _server.ts.js-fQAXFRLh.js.map} +1 -1
  85. package/build/server/chunks/entries/endpoints/api/assets/_id_/retag/{_server.ts.js-CqS4aALY.js → _server.ts.js-RTBrlhk5.js} +8 -8
  86. package/build/server/chunks/entries/endpoints/api/assets/_id_/retag/{_server.ts.js-CqS4aALY.js.map → _server.ts.js-RTBrlhk5.js.map} +1 -1
  87. package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-Bo_EsYXJ.js → _server.ts.js-Baz4gPRd.js} +8 -8
  88. package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-Bo_EsYXJ.js.map → _server.ts.js-Baz4gPRd.js.map} +1 -1
  89. package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-DW4w0XAr.js → _server.ts.js-CnqdPxWQ.js} +8 -8
  90. package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-DW4w0XAr.js.map → _server.ts.js-CnqdPxWQ.js.map} +1 -1
  91. package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-_MiNPnSy.js → _server.ts.js-bvrtSRDz.js} +8 -8
  92. package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-_MiNPnSy.js.map → _server.ts.js-bvrtSRDz.js.map} +1 -1
  93. package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-DwbrQnBc.js → _server.ts.js-cgYcVXgU.js} +8 -8
  94. package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-DwbrQnBc.js.map → _server.ts.js-cgYcVXgU.js.map} +1 -1
  95. package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-CEnHQf3b.js → _server.ts.js-DbXw3YEr.js} +8 -8
  96. package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-CEnHQf3b.js.map → _server.ts.js-DbXw3YEr.js.map} +1 -1
  97. package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-BZDuJZtF.js → _server.ts.js-D0PEYlzG.js} +8 -8
  98. package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-BZDuJZtF.js.map → _server.ts.js-D0PEYlzG.js.map} +1 -1
  99. package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-DRgdpKKd.js → _server.ts.js-Dt9Wfgs7.js} +8 -8
  100. package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-DRgdpKKd.js.map → _server.ts.js-Dt9Wfgs7.js.map} +1 -1
  101. package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-CP5QyIhz.js → _server.ts.js-BBuZYakQ.js} +8 -8
  102. package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-CP5QyIhz.js.map → _server.ts.js-BBuZYakQ.js.map} +1 -1
  103. package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-BKEvt065.js → _server.ts.js-DQ_CWMTu.js} +8 -8
  104. package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-BKEvt065.js.map → _server.ts.js-DQ_CWMTu.js.map} +1 -1
  105. package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-C_zihkDS.js → _server.ts.js-B3TVoDCl.js} +8 -8
  106. package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-C_zihkDS.js.map → _server.ts.js-B3TVoDCl.js.map} +1 -1
  107. package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-watkBmy6.js → _server.ts.js--2C2x6Q0.js} +8 -8
  108. package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-watkBmy6.js.map → _server.ts.js--2C2x6Q0.js.map} +1 -1
  109. package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-YtumLIou.js → _server.ts.js-DD2Hz15k.js} +8 -8
  110. package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-YtumLIou.js.map → _server.ts.js-DD2Hz15k.js.map} +1 -1
  111. package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-Dkouuu-M.js → _server.ts.js-Ei98ilB5.js} +8 -8
  112. package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-Dkouuu-M.js.map → _server.ts.js-Ei98ilB5.js.map} +1 -1
  113. package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-DwsEQeuf.js → _server.ts.js-NNuDGwyK.js} +8 -8
  114. package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-DwsEQeuf.js.map → _server.ts.js-NNuDGwyK.js.map} +1 -1
  115. package/build/server/chunks/entries/endpoints/api/usage/{_server.ts.js-CdQxfhV3.js → _server.ts.js-6_Wl_k0H.js} +8 -8
  116. package/build/server/chunks/entries/endpoints/api/usage/{_server.ts.js-CdQxfhV3.js.map → _server.ts.js-6_Wl_k0H.js.map} +1 -1
  117. package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-DDdMocWj.js → _server.ts.js-DkYQlG9U.js} +6 -6
  118. package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-DDdMocWj.js.map → _server.ts.js-DkYQlG9U.js.map} +1 -1
  119. package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-DbzjbH32.js → _server.ts.js-Dft0Zgh3.js} +8 -8
  120. package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-DbzjbH32.js.map → _server.ts.js-Dft0Zgh3.js.map} +1 -1
  121. package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-K_JbXZsU.js → _server.ts.js-rlV0QRQS.js} +8 -8
  122. package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-K_JbXZsU.js.map → _server.ts.js-rlV0QRQS.js.map} +1 -1
  123. package/build/server/chunks/entries/{hooks.server.js-DgZAVFbQ.js → hooks.server.js-C345JVQ2.js} +7 -7
  124. package/build/server/chunks/entries/{hooks.server.js-DgZAVFbQ.js.map → hooks.server.js-C345JVQ2.js.map} +1 -1
  125. package/build/server/chunks/{handler-C4m7sKKb.js → handler-C_S3CtEF.js} +5 -5
  126. package/build/server/chunks/{handler-C4m7sKKb.js.map → handler-C_S3CtEF.js.map} +1 -1
  127. package/build/server/chunks/{index.js-pAnkrzRH.js → index.js-CSCxgyyg.js} +5 -5
  128. package/build/server/chunks/{index.js-pAnkrzRH.js.map → index.js-CSCxgyyg.js.map} +1 -1
  129. package/build/server/chunks/{manifest.js-CXQHeYnS.js → manifest.js-CO6AjAUm.js} +30 -30
  130. package/build/server/chunks/{manifest.js-CXQHeYnS.js.map → manifest.js-CO6AjAUm.js.map} +1 -1
  131. package/build/server/chunks/nodes/{0.js-lmQMhWZd.js → 0.js-CRc8onmc.js} +2 -2
  132. package/build/server/chunks/nodes/{0.js-lmQMhWZd.js.map → 0.js-CRc8onmc.js.map} +1 -1
  133. package/build/server/chunks/nodes/1.js-CZm_Doa7.js +7 -0
  134. package/build/server/chunks/nodes/{1.js-CdH3UJI2.js.map → 1.js-CZm_Doa7.js.map} +1 -1
  135. package/build/server/chunks/nodes/2.js-B92vn1Hu.js +7 -0
  136. package/build/server/chunks/nodes/2.js-B92vn1Hu.js.map +1 -0
  137. package/build/server/chunks/nodes/3.js-C14BP7Jm.js +7 -0
  138. package/build/server/chunks/nodes/3.js-C14BP7Jm.js.map +1 -0
  139. package/build/server/chunks/nodes/4.js-BLNdVCa1.js +7 -0
  140. package/build/server/chunks/nodes/{4.js-DtgDNAZF.js.map → 4.js-BLNdVCa1.js.map} +1 -1
  141. package/dist/config.d.ts +5 -3
  142. package/dist/config.js +3 -2
  143. package/dist/core/api-types.d.ts +7 -22
  144. package/dist/core/config.d.ts +8 -82
  145. package/dist/core/config.js +0 -9
  146. package/dist/core/dependencies.d.ts +52 -0
  147. package/dist/core/dependencies.js +56 -0
  148. package/dist/core/dependency-validation.d.ts +17 -0
  149. package/dist/core/dependency-validation.js +19 -0
  150. package/dist/core/index.d.ts +8 -10
  151. package/dist/core/index.js +4 -5
  152. package/dist/core/library.d.ts +0 -19
  153. package/dist/core/library.js +4 -4
  154. package/dist/core/manifest-membership.d.ts +2 -2
  155. package/dist/core/reference-graph.d.ts +3 -3
  156. package/dist/server/build.js +12 -26
  157. package/dist/server/check.d.ts +3 -13
  158. package/dist/server/check.js +33 -112
  159. package/dist/server/codegen.d.ts +1 -3
  160. package/dist/server/codegen.js +0 -18
  161. package/dist/server/config-loader.d.ts +10 -33
  162. package/dist/server/config-loader.js +87 -156
  163. package/dist/server/index.d.ts +1 -1
  164. package/dist/server/index.js +1 -1
  165. package/dist/server/library-store.d.ts +1 -11
  166. package/dist/server/library-store.js +60 -42
  167. package/dist/server/operations.js +54 -161
  168. package/package.json +1 -1
  169. package/build/client/_app/immutable/assets/2.X44Wyac-.css +0 -1
  170. package/build/client/_app/immutable/assets/2.X44Wyac-.css.br +0 -0
  171. package/build/client/_app/immutable/assets/2.X44Wyac-.css.gz +0 -0
  172. package/build/client/_app/immutable/assets/3.66PJT3JC.css.br +0 -0
  173. package/build/client/_app/immutable/assets/3.66PJT3JC.css.gz +0 -0
  174. package/build/client/_app/immutable/assets/AssetSourceMenu.Buj2UxUg.css.br +0 -0
  175. package/build/client/_app/immutable/assets/AssetSourceMenu.Buj2UxUg.css.gz +0 -0
  176. package/build/client/_app/immutable/chunks/0SQyBKXe.js +0 -108
  177. package/build/client/_app/immutable/chunks/0SQyBKXe.js.br +0 -0
  178. package/build/client/_app/immutable/chunks/0SQyBKXe.js.gz +0 -0
  179. package/build/client/_app/immutable/chunks/DXiUbZ9S.js +0 -2
  180. package/build/client/_app/immutable/chunks/DXiUbZ9S.js.br +0 -0
  181. package/build/client/_app/immutable/chunks/DXiUbZ9S.js.gz +0 -0
  182. package/build/client/_app/immutable/chunks/R0o69z6O.js.br +0 -0
  183. package/build/client/_app/immutable/chunks/R0o69z6O.js.gz +0 -0
  184. package/build/client/_app/immutable/chunks/TrnW_5ju.js +0 -1
  185. package/build/client/_app/immutable/chunks/TrnW_5ju.js.br +0 -0
  186. package/build/client/_app/immutable/chunks/TrnW_5ju.js.gz +0 -0
  187. package/build/client/_app/immutable/chunks/jEVVu5G9.js.br +0 -0
  188. package/build/client/_app/immutable/chunks/jEVVu5G9.js.gz +0 -0
  189. package/build/client/_app/immutable/entry/app.DxYfHxs-.js.br +0 -0
  190. package/build/client/_app/immutable/entry/app.DxYfHxs-.js.gz +0 -0
  191. package/build/client/_app/immutable/entry/start.CdM7ozdO.js +0 -1
  192. package/build/client/_app/immutable/entry/start.CdM7ozdO.js.br +0 -0
  193. package/build/client/_app/immutable/entry/start.CdM7ozdO.js.gz +0 -0
  194. package/build/client/_app/immutable/nodes/0.Do0MsVUC.js.br +0 -0
  195. package/build/client/_app/immutable/nodes/0.Do0MsVUC.js.gz +0 -0
  196. package/build/client/_app/immutable/nodes/1.DhfAdUbg.js.br +0 -1
  197. package/build/client/_app/immutable/nodes/1.DhfAdUbg.js.gz +0 -0
  198. package/build/client/_app/immutable/nodes/2.lLNAdU5s.js +0 -3
  199. package/build/client/_app/immutable/nodes/2.lLNAdU5s.js.br +0 -0
  200. package/build/client/_app/immutable/nodes/2.lLNAdU5s.js.gz +0 -0
  201. package/build/client/_app/immutable/nodes/3.DA8xzCvA.js +0 -1
  202. package/build/client/_app/immutable/nodes/3.DA8xzCvA.js.br +0 -0
  203. package/build/client/_app/immutable/nodes/3.DA8xzCvA.js.gz +0 -0
  204. package/build/client/_app/immutable/nodes/4.gPNAednG.js.br +0 -0
  205. package/build/client/_app/immutable/nodes/4.gPNAednG.js.gz +0 -0
  206. package/build/server/chunks/chunks/context.js-Dh0ibRIF.js.map +0 -1
  207. package/build/server/chunks/chunks/contract.js-_LTMZBo2.js.map +0 -1
  208. package/build/server/chunks/chunks/core.js-CTyKR4bu.js.map +0 -1
  209. package/build/server/chunks/chunks/raw-reconciliation.js-CUH8IIJx.js.map +0 -1
  210. package/build/server/chunks/nodes/1.js-CdH3UJI2.js +0 -7
  211. package/build/server/chunks/nodes/2.js-BHnsJqcE.js +0 -7
  212. package/build/server/chunks/nodes/2.js-BHnsJqcE.js.map +0 -1
  213. package/build/server/chunks/nodes/3.js-cR9NdrYS.js +0 -7
  214. package/build/server/chunks/nodes/3.js-cR9NdrYS.js.map +0 -1
  215. package/build/server/chunks/nodes/4.js-DtgDNAZF.js +0 -7
  216. package/dist/core/library-validation.d.ts +0 -13
  217. package/dist/core/library-validation.js +0 -48
  218. package/dist/core/package-declaration.d.ts +0 -43
  219. package/dist/core/package-declaration.js +0 -80
  220. package/dist/core/package-merge.d.ts +0 -65
  221. package/dist/core/package-merge.js +0 -173
@@ -35,24 +35,6 @@ export function kebabCaseFromCamel(name) {
35
35
  export function manifestModuleFileName(manifestName) {
36
36
  return `${kebabCaseFromCamel(manifestName)}.generated.ts`;
37
37
  }
38
- /** Two manifest names that would generate the same kebab-case module file. */
39
- export function manifestModuleCollisionIssues(manifests) {
40
- const issues = [];
41
- const namesByModuleFile = new Map();
42
- for (const name of Object.keys(manifests)) {
43
- const fileName = manifestModuleFileName(name);
44
- const existingName = namesByModuleFile.get(fileName);
45
- if (existingName !== undefined) {
46
- issues.push({
47
- message: `Manifests "${existingName}" and "${name}" would both generate "${fileName}".`
48
- });
49
- }
50
- else {
51
- namesByModuleFile.set(fileName, name);
52
- }
53
- }
54
- return issues;
55
- }
56
38
  /**
57
39
  * Build the entry data codegen emits for one asset — delegated to
58
40
  * the owning server plugin's `buildManifestEntry`. Reference fields
@@ -1,4 +1,4 @@
1
- import { type AudioPreset, type FigmaImportScale, type ImagePreset, type PackageDeclaration, type ResolvedVideoPreset, type UsageConfig } from '../core/index.js';
1
+ import type { AudioPreset, FigmaImportScale, ImagePreset, ResolvedDependency, ResolvedVideoPreset, UsageConfig } from '../core/index.js';
2
2
  import type { ServerPluginRegistry } from './plugins/contract.js';
3
3
  export interface ResolvedPresetPluginConfig {
4
4
  presets: Record<string, ImagePreset>;
@@ -13,27 +13,6 @@ export interface ResolvedVideoPluginConfig {
13
13
  export interface ResolvedAudioPluginConfig {
14
14
  presets: Record<string, AudioPreset>;
15
15
  }
16
- /**
17
- * A `packages` entry after pure normalization (no disk): its declared origin,
18
- * whether it is a package name or a path, the resolved reference (absolute path
19
- * for the path form; the bare name for the name form), and an optional raw-root
20
- * override. Package files are read later, in `loadConfig`.
21
- */
22
- export interface NormalizedPackageSource {
23
- origin: string;
24
- kind: 'name' | 'path';
25
- reference: string;
26
- rawDirOverride?: string;
27
- }
28
- /** A fully resolved Package: its parsed declaration plus provenance. */
29
- export interface ResolvedPackage {
30
- origin: string;
31
- /** Absolute path of the resolved fundus.package.json. */
32
- file: string;
33
- /** Absolute raw root (recorded for provenance; unused in v1 slots-only). */
34
- rawDir: string;
35
- declaration: PackageDeclaration;
36
- }
37
16
  export interface ResolvedFundusConfig {
38
17
  /** Absolute host project directory containing fundus.config.ts. */
39
18
  projectRoot: string;
@@ -44,6 +23,11 @@ export interface ResolvedFundusConfig {
44
23
  manifestsDir: string;
45
24
  /** URL prefix baked into generated proxy `src` values; always ends with '/'. */
46
25
  proxyBasePath: string;
26
+ /**
27
+ * Aggregated, deduplicated dependency declarations from all configured
28
+ * sources. Empty when none are configured.
29
+ */
30
+ dependencies: readonly ResolvedDependency[];
47
31
  plugins: {
48
32
  image: ResolvedPresetPluginConfig;
49
33
  slice: ResolvedPresetPluginConfig;
@@ -61,22 +45,15 @@ export interface ResolvedFundusConfig {
61
45
  };
62
46
  };
63
47
  usage: UsageConfig | null;
64
- /** Normalized `packages` entries (from the pure `resolveConfig`, no disk). */
65
- packageSources: NormalizedPackageSource[];
66
- /** Parsed Packages (filled by `loadConfig`; always [] from `resolveConfig`). */
67
- packages: ResolvedPackage[];
68
48
  }
69
49
  export declare const USAGE_NOT_CONFIGURED_MESSAGE = "Usage analysis is not configured; add usage.referenceProvider and usage.openLocation to fundus.config.ts.";
70
50
  /** Pure resolution step (testable without a config file on disk). */
71
51
  export declare function resolveConfig(projectRoot: string, value: unknown, registry?: ServerPluginRegistry): ResolvedFundusConfig;
72
52
  /**
73
- * Read and parse every declared Package from disk. Name entries resolve through
74
- * the host's module resolver (respecting `exports`), then walk up to the nearest
75
- * `package.json` that declares the name and read its `"fundus"` field. Path
76
- * entries point directly at a `fundus.package.json`. Throws a clear,
77
- * origin-tagged error on any resolution/read/parse failure — Package assembly
78
- * failures are symmetric with a missing `fundus.config.ts`.
53
+ * Load and aggregate every configured dependency source (D3, D6). `requireAnchor`
54
+ * anchors npm-name resolution at the host project (injectable for tests). Flat:
55
+ * the dependencies of a referenced npm package are not resolved recursively.
79
56
  */
80
- export declare function loadPackages(projectRoot: string, sources: NormalizedPackageSource[]): Promise<ResolvedPackage[]>;
57
+ export declare function resolveDependencies(projectRoot: string, specs: readonly string[], requireAnchor?: string): Promise<ResolvedDependency[]>;
81
58
  /** Load `fundus.config.ts` from the host project root. */
82
59
  export declare function loadConfig(projectRoot: string): Promise<ResolvedFundusConfig>;
@@ -4,12 +4,10 @@
4
4
  * absolute, and merges the built-in plugin preset defaults under the host's.
5
5
  */
6
6
  import { existsSync, readFileSync } from 'node:fs';
7
- import { readFile } from 'node:fs/promises';
8
7
  import { createRequire } from 'node:module';
9
- import { dirname, isAbsolute, join, resolve } from 'node:path';
10
- import { pathToFileURL } from 'node:url';
8
+ import { dirname, join, resolve } from 'node:path';
11
9
  import { createJiti } from 'jiti';
12
- import { parsePackageDeclaration, validatePackageDeclaration } from '../core/index.js';
10
+ import { validateDependencyList } from '../core/index.js';
13
11
  import { serverPluginsByType } from './plugins.js';
14
12
  import { isRecord } from './plugins/config.js';
15
13
  export const USAGE_NOT_CONFIGURED_MESSAGE = 'Usage analysis is not configured; add usage.referenceProvider and usage.openLocation to fundus.config.ts.';
@@ -36,88 +34,6 @@ function configDefinitionsFor(registry) {
36
34
  }
37
35
  return [...byNamespace.values()];
38
36
  }
39
- /**
40
- * A string `packages` entry is a *path* when it looks like one (starts with
41
- * `.`/`/`, is absolute, or ends `.json`), or a bare relative path with a
42
- * separator; otherwise it is a package *name*. A scoped name (`@scope/pkg`)
43
- * contains a `/` but is a name.
44
- */
45
- function classifyPackageSpec(spec) {
46
- if (spec.startsWith('.') || spec.startsWith('/') || isAbsolute(spec))
47
- return 'path';
48
- if (DECLARATION_FILE_RE.test(spec))
49
- return 'path';
50
- if (spec.startsWith('@'))
51
- return 'name';
52
- if (spec.includes('/') || spec.includes('\\'))
53
- return 'path';
54
- return 'name';
55
- }
56
- /** A declaration file is JSON or a JS/TS module (the latter loaded via jiti). */
57
- const DECLARATION_FILE_RE = /\.(json|[mc]?[jt]s)$/;
58
- /**
59
- * Read a package declaration from its resolved file: a JSON `fundus.package.json`
60
- * (parsed as text) or a JS/TS module (`fundus.package.ts`) whose default export is
61
- * the declaration — loaded through the same jiti path as `fundus.config.ts`, which
62
- * keeps the resource `type`s literal for the package's `PackageAssets<…>` derivation.
63
- */
64
- async function loadPackageDeclaration(file, origin) {
65
- if (/\.[mc]?[jt]s$/.test(file)) {
66
- let module;
67
- try {
68
- const jiti = createJiti(import.meta.url, { interopDefault: false });
69
- module = await jiti.import(file);
70
- }
71
- catch (cause) {
72
- throw new Error(`Cannot load fundus package "${origin}" (${file}): ${cause instanceof Error ? cause.message : String(cause)}`);
73
- }
74
- const value = isRecord(module) && 'default' in module ? module.default : module;
75
- return validatePackageDeclaration(value, origin);
76
- }
77
- let text;
78
- try {
79
- text = await readFile(file, 'utf8');
80
- }
81
- catch (cause) {
82
- throw new Error(`Cannot read fundus package "${origin}" (${file}): ${cause instanceof Error ? cause.message : String(cause)}`);
83
- }
84
- return parsePackageDeclaration(text, origin);
85
- }
86
- function normalizePackageSource(projectRoot, entry) {
87
- let spec;
88
- let rawDirOverride;
89
- if (typeof entry === 'string') {
90
- spec = entry;
91
- }
92
- else if (isRecord(entry) && typeof entry.package === 'string' && entry.package.length > 0) {
93
- spec = entry.package;
94
- if (entry.rawDir !== undefined) {
95
- if (typeof entry.rawDir !== 'string' || entry.rawDir.length === 0) {
96
- throw new Error('fundus.config: a "packages" entry "rawDir" must be a non-empty string.');
97
- }
98
- rawDirOverride = entry.rawDir;
99
- }
100
- }
101
- else {
102
- throw new Error('fundus.config: each "packages" entry must be a package name, a path string, or { package: string; rawDir?: string }.');
103
- }
104
- const kind = classifyPackageSpec(spec);
105
- const reference = kind === 'path' ? resolve(projectRoot, spec) : spec;
106
- return {
107
- origin: spec,
108
- kind,
109
- reference,
110
- ...(rawDirOverride !== undefined ? { rawDirOverride } : {})
111
- };
112
- }
113
- function resolvePackageSources(projectRoot, value) {
114
- if (value === undefined)
115
- return [];
116
- if (!Array.isArray(value)) {
117
- throw new Error('fundus.config: "packages" must be an array.');
118
- }
119
- return value.map((entry) => normalizePackageSource(projectRoot, entry));
120
- }
121
37
  /** Pure resolution step (testable without a config file on disk). */
122
38
  export function resolveConfig(projectRoot, value, registry = serverPluginsByType) {
123
39
  if (!isRecord(value)) {
@@ -161,6 +77,9 @@ export function resolveConfig(projectRoot, value, registry = serverPluginsByType
161
77
  if (scale !== 1 && scale !== 2 && scale !== 3 && scale !== 4) {
162
78
  throw new Error('fundus.config: "import.figma.defaults.scale" must be 1, 2, 3, or 4.');
163
79
  }
80
+ // Fail fast on a malformed `dependencies` shape; the result is discarded
81
+ // because the sources are resolved asynchronously in `loadConfig`.
82
+ dependencySpecs(value);
164
83
  const usage = value.usage;
165
84
  if (usage !== undefined && !isRecord(usage)) {
166
85
  throw new Error('fundus.config: "usage" must be an object.');
@@ -178,6 +97,8 @@ export function resolveConfig(projectRoot, value, registry = serverPluginsByType
178
97
  library: resolvePath(projectRoot, requiredString(value, 'library')),
179
98
  manifestsDir: resolvePath(projectRoot, requiredString(value, 'manifestsDir')),
180
99
  proxyBasePath,
100
+ // Placeholder; `loadConfig` resolves the sources asynchronously through jiti.
101
+ dependencies: [],
181
102
  plugins: resolvedPlugins,
182
103
  import: {
183
104
  figma: {
@@ -186,23 +107,43 @@ export function resolveConfig(projectRoot, value, registry = serverPluginsByType
186
107
  defaults: { scale }
187
108
  }
188
109
  },
189
- usage: usage === undefined ? null : usage,
190
- packageSources: resolvePackageSources(projectRoot, value.packages),
191
- packages: []
110
+ usage: usage === undefined ? null : usage
192
111
  };
193
112
  }
194
- function nearestNamedPackageJson(entryPath, name) {
195
- let dir = dirname(entryPath);
113
+ /** Validated dependency source specs (shape only; absent means none). */
114
+ function dependencySpecs(value) {
115
+ const specs = value.dependencies;
116
+ if (specs === undefined)
117
+ return [];
118
+ if (!Array.isArray(specs) ||
119
+ specs.some((spec) => typeof spec !== 'string' || spec.length === 0)) {
120
+ throw new Error('fundus.config: "dependencies" must be an array of non-empty strings.');
121
+ }
122
+ return specs;
123
+ }
124
+ /** Reject a `.json` dependency source: JSON carries no literal types (D4). */
125
+ function assertNotJson(spec, context) {
126
+ if (spec.endsWith('.json')) {
127
+ throw new Error(`Dependency ${context} "${spec}" must be a .ts or .js module; JSON is not supported.`);
128
+ }
129
+ }
130
+ /** A dependency spec is a path when it is relative/absolute or names a module file. */
131
+ function isPathSpec(spec) {
132
+ return (spec.startsWith('.') || spec.startsWith('/') || spec.endsWith('.ts') || spec.endsWith('.js'));
133
+ }
134
+ /** Walk up from `fromPath` to the nearest package.json whose `name` matches. */
135
+ function nearestPackageJson(fromPath, name) {
136
+ let dir = dirname(fromPath);
196
137
  for (;;) {
197
138
  const candidate = join(dir, 'package.json');
198
139
  if (existsSync(candidate)) {
199
140
  try {
200
141
  const pkg = JSON.parse(readFileSync(candidate, 'utf8'));
201
- if (isRecord(pkg) && pkg.name === name)
202
- return { dir, pkg };
142
+ if (pkg.name === name)
143
+ return candidate;
203
144
  }
204
145
  catch {
205
- // Malformed package.json — keep walking up.
146
+ // Ignore unreadable/malformed package.json and keep walking up.
206
147
  }
207
148
  }
208
149
  const parent = dirname(dir);
@@ -210,78 +151,65 @@ function nearestNamedPackageJson(entryPath, name) {
210
151
  break;
211
152
  dir = parent;
212
153
  }
213
- throw new Error(`Cannot find the package.json for fundus package "${name}" (resolved to ${entryPath}).`);
154
+ throw new Error(`Cannot resolve the package.json of dependency "${name}".`);
214
155
  }
215
- /**
216
- * Resolve a name-form Package to its root directory + parsed `package.json`. A
217
- * declaration-only Package ships no JS entry module, so resolving the bare name
218
- * would throw `MODULE_NOT_FOUND`; resolve its `package.json` subpath first and
219
- * only fall back to entry resolution when an `exports` map hides it.
220
- */
221
- function resolvePackageRoot(require, reference, origin) {
156
+ /** Resolve an npm-name dependency spec to its declared source module path. */
157
+ function resolveNpmDependencyModule(spec, require) {
158
+ let packageJsonPath;
222
159
  try {
223
- const manifestPath = require.resolve(`${reference}/package.json`);
224
- const pkg = JSON.parse(readFileSync(manifestPath, 'utf8'));
225
- if (isRecord(pkg))
226
- return { dir: dirname(manifestPath), pkg };
160
+ packageJsonPath = require.resolve(`${spec}/package.json`);
227
161
  }
228
- catch {
229
- // No resolvable ./package.json subpath — fall back to the entry module.
230
- }
231
- let entry;
232
- try {
233
- entry = require.resolve(reference);
162
+ catch (cause) {
163
+ if (cause !== null &&
164
+ typeof cause === 'object' &&
165
+ cause.code === 'ERR_PACKAGE_PATH_NOT_EXPORTED') {
166
+ packageJsonPath = nearestPackageJson(require.resolve(spec), spec);
167
+ }
168
+ else {
169
+ throw cause;
170
+ }
234
171
  }
235
- catch {
236
- throw new Error(`Cannot resolve fundus package "${origin}": no installed package declares it — is it a dependency?`);
172
+ const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
173
+ const field = pkg.fundus?.dependencies;
174
+ if (typeof field !== 'string' || field.length === 0) {
175
+ throw new Error(`Dependency "${spec}" is missing a non-empty "fundus".dependencies module path in its package.json.`);
237
176
  }
238
- return nearestNamedPackageJson(entry, reference);
177
+ assertNotJson(field, `package.json "fundus".dependencies field of "${spec}"`);
178
+ return resolve(dirname(packageJsonPath), field);
239
179
  }
240
180
  /**
241
- * Read and parse every declared Package from disk. Name entries resolve through
242
- * the host's module resolver (respecting `exports`), then walk up to the nearest
243
- * `package.json` that declares the name and read its `"fundus"` field. Path
244
- * entries point directly at a `fundus.package.json`. Throws a clear,
245
- * origin-tagged error on any resolution/read/parse failure — Package assembly
246
- * failures are symmetric with a missing `fundus.config.ts`.
181
+ * Load and aggregate every configured dependency source (D3, D6). `requireAnchor`
182
+ * anchors npm-name resolution at the host project (injectable for tests). Flat:
183
+ * the dependencies of a referenced npm package are not resolved recursively.
247
184
  */
248
- export async function loadPackages(projectRoot, sources) {
249
- const require = createRequire(pathToFileURL(join(projectRoot, 'fundus.config.ts')).href);
250
- const packages = [];
251
- for (const source of sources) {
252
- let file;
253
- let defaultRawDir;
254
- if (source.kind === 'path') {
255
- file = source.reference;
256
- if (!existsSync(file)) {
257
- throw new Error(`Fundus package file not found: ${file} (from "${source.origin}").`);
258
- }
259
- defaultRawDir = dirname(file);
260
- }
261
- else {
262
- const { dir, pkg } = resolvePackageRoot(require, source.reference, source.origin);
263
- const fundusField = pkg.fundus;
264
- if (!isRecord(fundusField) ||
265
- typeof fundusField.package !== 'string' ||
266
- fundusField.package.length === 0) {
267
- throw new Error(`Fundus package "${source.origin}" is missing a "fundus.package" field in its package.json.`);
185
+ export async function resolveDependencies(projectRoot, specs, requireAnchor = join(resolve(projectRoot), 'package.json')) {
186
+ if (specs.length === 0)
187
+ return [];
188
+ const jiti = createJiti(import.meta.url, { interopDefault: false });
189
+ const require = createRequire(requireAnchor);
190
+ const aggregated = new Map();
191
+ for (const spec of specs) {
192
+ assertNotJson(spec, 'source');
193
+ const modulePath = isPathSpec(spec)
194
+ ? resolve(resolve(projectRoot), spec)
195
+ : resolveNpmDependencyModule(spec, require);
196
+ const loaded = (await jiti.import(modulePath));
197
+ const value = loaded.default ?? loaded;
198
+ for (const dependency of validateDependencyList(spec, value)) {
199
+ const existing = aggregated.get(dependency.id);
200
+ if (existing === undefined) {
201
+ aggregated.set(dependency.id, { type: dependency.type, sources: [spec] });
202
+ continue;
268
203
  }
269
- file = resolve(dir, fundusField.package);
270
- if (!existsSync(file)) {
271
- throw new Error(`Fundus package "${source.origin}" declaration not found: ${file}.`);
204
+ if (existing.type !== dependency.type) {
205
+ throw new Error(`Dependency "${dependency.id}" is declared as "${existing.type}" by "${existing.sources.join('", "')}" and as "${dependency.type}" by "${spec}".`);
272
206
  }
273
- defaultRawDir =
274
- typeof fundusField.rawDir === 'string' && fundusField.rawDir.length > 0
275
- ? resolve(dir, fundusField.rawDir)
276
- : dir;
207
+ // Same id + same type from another source: dedupe (D3), keep the source.
208
+ if (!existing.sources.includes(spec))
209
+ existing.sources.push(spec);
277
210
  }
278
- const declaration = await loadPackageDeclaration(file, source.origin);
279
- const rawDir = source.rawDirOverride !== undefined
280
- ? resolve(projectRoot, source.rawDirOverride)
281
- : defaultRawDir;
282
- packages.push({ origin: source.origin, file, rawDir, declaration });
283
211
  }
284
- return packages;
212
+ return [...aggregated].map(([id, { type, sources }]) => ({ id, type, sources }));
285
213
  }
286
214
  /** Load `fundus.config.ts` from the host project root. */
287
215
  export async function loadConfig(projectRoot) {
@@ -298,6 +226,9 @@ export async function loadConfig(projectRoot) {
298
226
  catch (cause) {
299
227
  throw new Error(`Cannot load fundus.config.ts: ${cause instanceof Error ? cause.message : String(cause)}`);
300
228
  }
301
- const config = resolveConfig(root, isRecord(module) && 'default' in module ? module.default : module);
302
- return { ...config, packages: await loadPackages(root, config.packageSources) };
229
+ const value = isRecord(module) && 'default' in module ? module.default : module;
230
+ const resolved = resolveConfig(root, value);
231
+ const specs = isRecord(value) ? dependencySpecs(value) : [];
232
+ const dependencies = await resolveDependencies(root, specs);
233
+ return { ...resolved, dependencies };
303
234
  }
@@ -1,5 +1,5 @@
1
1
  export type { ResolvedFundusConfig, ResolvedPresetPluginConfig, ResolvedVideoPluginConfig, ResolvedAudioPluginConfig } from './config-loader.js';
2
- export { loadConfig, resolveConfig } from './config-loader.js';
2
+ export { loadConfig, resolveConfig, resolveDependencies } from './config-loader.js';
3
3
  export { LibraryStore } from './library-store.js';
4
4
  export type { IngestOptions, ReplaceRawFileOptions } from './library-store.js';
5
5
  export type { AssetProxyInfo, ProxyOutputInfo, ProcessingReport } from './processing/processor.js';
@@ -1,4 +1,4 @@
1
- export { loadConfig, resolveConfig } from './config-loader.js';
1
+ export { loadConfig, resolveConfig, resolveDependencies } from './config-loader.js';
2
2
  export { LibraryStore } from './library-store.js';
3
3
  export { processAssets, expectedProxyFileName, expectedProxyRelativePath, deliveredAssetIds, isProxyFileName, readProxyOutputInfo } from './processing/processor.js';
4
4
  export { ffmpegBinaryPath, runToolchainBinary } from './processing/ffmpeg.js';
@@ -26,14 +26,6 @@ export interface IngestOptions {
26
26
  export interface CreateAssetOptions extends IngestOptions {
27
27
  manifests?: string[];
28
28
  importSource?: ImportSourceRecord;
29
- /**
30
- * Fill/override a Package slot: store these parameters verbatim as a host
31
- * override record instead of expanding plugin defaults. Partial by design
32
- * (only the overridden keys) — the merge deep-merges them over the Package
33
- * base, and they are schema-validated over the effective library, not here.
34
- * When set, `prepareParameters` is ignored.
35
- */
36
- parametersOverride?: unknown;
37
29
  }
38
30
  export interface CreateAssetStaging {
39
31
  rawPath: string;
@@ -141,8 +133,6 @@ export declare class LibraryStore {
141
133
  * type, dangling raw pointer, invalid parameters, unknown manifest names,
142
134
  * and reference errors (dangling target, type mismatch, cycles).
143
135
  */
144
- validate(library: Library, options?: {
145
- flatSpace?: boolean;
146
- }): Promise<ValidationIssueDto[]>;
136
+ validate(library: Library): Promise<ValidationIssueDto[]>;
147
137
  syncFolders(library: Library): Promise<void>;
148
138
  }
@@ -8,8 +8,8 @@ import { existsSync } from 'node:fs';
8
8
  import { mkdir, readFile, rename, rm, unlink, writeFile } from 'node:fs/promises';
9
9
  import { dirname, extname, join } from 'node:path';
10
10
  import { createHash } from 'node:crypto';
11
- import { assetIdError, canonicalizeParameters, createEmptyLibrary, flatLibraryIssues, folderNameError, folderNameOf, folderOfRawPath, folderPathError, isFolderOrDescendant, joinFolderPath, manifestColorError, manifestEmojiError, parseLibrary, normalizeFolderPath, parentFolderPath, portableFolderPathKey, rawFilePathError, rawFileNameOfPath, replaceFolderPrefix, manifestNameError, serializeLibrary } from '../core/index.js';
12
- import { manifestModuleCollisionIssues, manifestModuleFileName } from './codegen.js';
11
+ import { assetIdError, collectAllReferences, canonicalizeParameters, createEmptyLibrary, folderNameError, folderNameOf, folderOfRawPath, folderPathError, isFolderOrDescendant, joinFolderPath, manifestColorError, manifestEmojiError, parseLibrary, referenceErrors, normalizeFolderPath, parentFolderPath, portableFolderPathKey, rawFilePathError, rawFileNameOfPath, replaceFolderPrefix, manifestNameError, serializeLibrary } from '../core/index.js';
12
+ import { manifestModuleFileName } from './codegen.js';
13
13
  import { descriptorsByType, serverPluginForType, serverPluginsByType } from './plugins.js';
14
14
  import { isProxyFileNameFor } from './processing/processor.js';
15
15
  import { ensureManagedFolder, listRelativeFiles, syncManagedFolders } from './folder-filesystem.js';
@@ -135,9 +135,8 @@ export class LibraryStore {
135
135
  const folder = options.folder === undefined ? '' : normalizeFolderPath(options.folder);
136
136
  this.#requireFolder(library, folder);
137
137
  const manifests = [...new Set(options.manifests ?? [])].sort();
138
- const validManifests = this.#validManifestNames(library);
139
138
  for (const manifest of manifests) {
140
- if (!validManifests.has(manifest)) {
139
+ if (!Object.hasOwn(library.manifests, manifest)) {
141
140
  throw new Error(`Unknown manifest "${manifest}".`);
142
141
  }
143
142
  }
@@ -150,15 +149,9 @@ export class LibraryStore {
150
149
  let installed = false;
151
150
  try {
152
151
  await writeFile(temporaryPath, options.bytes);
153
- let parameters;
154
- if (options.parametersOverride !== undefined) {
155
- parameters = options.parametersOverride;
156
- }
157
- else {
158
- parameters = plugin.descriptor.validateParameters(plugin.descriptor.defaultParameters(plugin.pluginConfig(this.#config)));
159
- if (prepareParameters) {
160
- parameters = plugin.descriptor.validateParameters(await prepareParameters({ rawPath: temporaryPath, rawFileName: storedName, parameters }));
161
- }
152
+ let parameters = plugin.descriptor.validateParameters(plugin.descriptor.defaultParameters(plugin.pluginConfig(this.#config)));
153
+ if (prepareParameters) {
154
+ parameters = plugin.descriptor.validateParameters(await prepareParameters({ rawPath: temporaryPath, rawFileName: storedName, parameters }));
162
155
  }
163
156
  const record = {
164
157
  type: options.type,
@@ -446,9 +439,8 @@ export class LibraryStore {
446
439
  const library = await this.read();
447
440
  const record = this.#requireAsset(library, id);
448
441
  const unique = [...new Set(manifests)];
449
- const validManifests = this.#validManifestNames(library);
450
442
  for (const name of unique) {
451
- if (!validManifests.has(name)) {
443
+ if (!Object.hasOwn(library.manifests, name)) {
452
444
  throw new Error(`Unknown manifest "${name}".`);
453
445
  }
454
446
  }
@@ -902,14 +894,7 @@ export class LibraryStore {
902
894
  * type, dangling raw pointer, invalid parameters, unknown manifest names,
903
895
  * and reference errors (dangling target, type mismatch, cycles).
904
896
  */
905
- async validate(library, options = {}) {
906
- // The default preserves single-root behaviour (host === effective). When
907
- // merging Packages, disk/host checks run on the host library with
908
- // `flatSpace: false`, while the flat-space checks (id/type/parameters/
909
- // membership/appearance/references) run separately over the *effective*
910
- // library — host override records store partial parameters that only
911
- // validate once merged, and references may cross the host/Package boundary.
912
- const flatSpace = options.flatSpace ?? true;
897
+ async validate(library) {
913
898
  const issues = [];
914
899
  const folderKeys = new Map();
915
900
  for (const folder of library.folders) {
@@ -939,7 +924,53 @@ export class LibraryStore {
939
924
  }
940
925
  }
941
926
  }
927
+ for (const [name, record] of Object.entries(library.manifests)) {
928
+ const nameProblem = manifestNameError(name);
929
+ if (nameProblem)
930
+ issues.push({ message: nameProblem });
931
+ if (record.color !== undefined) {
932
+ const colorProblem = manifestColorError(record.color);
933
+ if (colorProblem)
934
+ issues.push({ message: `Manifest "${name}": ${colorProblem}` });
935
+ }
936
+ if (record.emoji !== undefined) {
937
+ const emojiProblem = manifestEmojiError(record.emoji);
938
+ if (emojiProblem)
939
+ issues.push({ message: `Manifest "${name}": ${emojiProblem}` });
940
+ }
941
+ }
942
+ const namesByModuleFile = new Map();
943
+ for (const name of Object.keys(library.manifests)) {
944
+ const fileName = manifestModuleFileName(name);
945
+ const existingName = namesByModuleFile.get(fileName);
946
+ if (existingName !== undefined) {
947
+ issues.push({
948
+ message: `Manifests "${existingName}" and "${name}" would both generate "${fileName}".`
949
+ });
950
+ }
951
+ else {
952
+ namesByModuleFile.set(fileName, name);
953
+ }
954
+ }
942
955
  for (const [assetId, record] of Object.entries(library.assets)) {
956
+ const idProblem = assetIdError(assetId);
957
+ if (idProblem)
958
+ issues.push({ assetId, message: idProblem });
959
+ const plugin = this.#registry[record.type];
960
+ if (!plugin) {
961
+ issues.push({ assetId, message: `Unknown asset type "${record.type}".` });
962
+ }
963
+ else {
964
+ try {
965
+ plugin.descriptor.validateParameters(record.parameters);
966
+ }
967
+ catch (cause) {
968
+ issues.push({
969
+ assetId,
970
+ message: `Invalid parameters: ${cause instanceof Error ? cause.message : String(cause)}`
971
+ });
972
+ }
973
+ }
943
974
  try {
944
975
  assertSafeRelativeFilePath(record.raw);
945
976
  }
@@ -959,11 +990,13 @@ export class LibraryStore {
959
990
  message: `Raw file "${record.raw}" is missing from the raw directory.`
960
991
  });
961
992
  }
993
+ for (const manifest of record.manifests) {
994
+ if (!library.manifests[manifest]) {
995
+ issues.push({ assetId, message: `Unknown manifest "${manifest}".` });
996
+ }
997
+ }
962
998
  }
963
- if (flatSpace) {
964
- issues.push(...flatLibraryIssues(library, descriptorsByType(this.#registry)));
965
- issues.push(...manifestModuleCollisionIssues(library.manifests));
966
- }
999
+ issues.push(...referenceErrors(library, collectAllReferences(library, descriptorsByType(this.#registry))));
967
1000
  return issues;
968
1001
  }
969
1002
  async #deleteProxiesOf(assetId) {
@@ -986,21 +1019,6 @@ export class LibraryStore {
986
1019
  }
987
1020
  return library.assets[id];
988
1021
  }
989
- /**
990
- * Valid manifest names for asset membership: the host library's own manifests
991
- * plus any a configured Package introduces. The effective (merged) library
992
- * unions both, so a host asset (or slot fill) may be placed into a
993
- * Package-introduced manifest — validating against the host manifests alone
994
- * would wrongly reject that placement.
995
- */
996
- #validManifestNames(library) {
997
- const names = new Set(Object.keys(library.manifests));
998
- for (const pkg of this.#config.packages ?? []) {
999
- for (const name of Object.keys(pkg.declaration.manifests))
1000
- names.add(name);
1001
- }
1002
- return names;
1003
- }
1004
1022
  /** Resolve a non-colliding raw file name, appending `-1`, `-2`, … before the extension. */
1005
1023
  #uniqueRawName(fileName, folder) {
1006
1024
  if (!existsSync(join(this.#config.rawDir, folder, fileName)))