@lapis-notes/api 0.1.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 (400) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE.md +4 -0
  3. package/README.md +43 -0
  4. package/dist/__tests__/data-adapter-conformance.js +205 -0
  5. package/dist/__tests__/lapis-runtime-manifest.js +32 -0
  6. package/dist/__tests__/svelte-internal-client.d.ts +3 -0
  7. package/dist/agent-result-views.d.ts +52 -0
  8. package/dist/agent-result-views.js +89 -0
  9. package/dist/agent-skills.d.ts +99 -0
  10. package/dist/agent-skills.js +182 -0
  11. package/dist/agent-tools.d.ts +92 -0
  12. package/dist/agent-tools.js +139 -0
  13. package/dist/app-database-host.d.ts +4 -0
  14. package/dist/app-database-host.js +4 -0
  15. package/dist/app-shell-plugin-persistence.d.ts +15 -0
  16. package/dist/app-shell-plugin-persistence.js +34 -0
  17. package/dist/app-url.d.ts +54 -0
  18. package/dist/app-url.js +269 -0
  19. package/dist/application-compatibility.d.ts +31 -0
  20. package/dist/application-compatibility.js +64 -0
  21. package/dist/application-state.svelte.d.ts +14 -0
  22. package/dist/application-state.svelte.js +30 -0
  23. package/dist/assets/lapis-logo.svg +471 -0
  24. package/dist/bases.d.ts +281 -0
  25. package/dist/bases.js +475 -0
  26. package/dist/cache.svelte.d.ts +569 -0
  27. package/dist/cache.svelte.js +1433 -0
  28. package/dist/command.svelte.d.ts +337 -0
  29. package/dist/command.svelte.js +571 -0
  30. package/dist/compat.d.ts +29 -0
  31. package/dist/compat.js +30 -0
  32. package/dist/components/configuration/configuration.css +199 -0
  33. package/dist/components/configuration/date-setting.svelte +71 -0
  34. package/dist/components/configuration/date-setting.svelte.d.ts +8 -0
  35. package/dist/components/configuration/list-setting.svelte +128 -0
  36. package/dist/components/configuration/list-setting.svelte.d.ts +13 -0
  37. package/dist/components/configuration/object-array-row-grip.svelte +78 -0
  38. package/dist/components/configuration/object-array-row-grip.svelte.d.ts +9 -0
  39. package/dist/components/configuration/object-array-row.svelte +163 -0
  40. package/dist/components/configuration/object-array-row.svelte.d.ts +19 -0
  41. package/dist/components/configuration/object-array-setting.svelte +196 -0
  42. package/dist/components/configuration/object-array-setting.svelte.d.ts +15 -0
  43. package/dist/components/configuration/object-array-table-dnd.d.ts +8 -0
  44. package/dist/components/configuration/object-array-table-dnd.js +10 -0
  45. package/dist/components/configuration/object-array-utils.d.ts +11 -0
  46. package/dist/components/configuration/object-array-utils.js +103 -0
  47. package/dist/components/configuration/object-grid-setting.svelte +79 -0
  48. package/dist/components/configuration/object-grid-setting.svelte.d.ts +10 -0
  49. package/dist/components/configuration/object-map-row.svelte +147 -0
  50. package/dist/components/configuration/object-map-row.svelte.d.ts +15 -0
  51. package/dist/components/configuration/object-map-setting.svelte +137 -0
  52. package/dist/components/configuration/object-map-setting.svelte.d.ts +14 -0
  53. package/dist/components/configuration/object-map-types.d.ts +5 -0
  54. package/dist/components/configuration/object-map-types.js +1 -0
  55. package/dist/components/configuration/options-combobox-setting.svelte +129 -0
  56. package/dist/components/configuration/options-combobox-setting.svelte.d.ts +12 -0
  57. package/dist/components/copy-button/button.svelte +93 -0
  58. package/dist/components/copy-button/button.svelte.d.ts +13 -0
  59. package/dist/components/copy-button/index.d.ts +2 -0
  60. package/dist/components/copy-button/index.js +2 -0
  61. package/dist/components/editor/editor.css +565 -0
  62. package/dist/components/editor/editor.d.ts +33 -0
  63. package/dist/components/editor/editor.js +132 -0
  64. package/dist/components/editor/editor.svelte +176 -0
  65. package/dist/components/editor/editor.svelte.d.ts +15 -0
  66. package/dist/components/editor/embedded-editor-surface.d.ts +12 -0
  67. package/dist/components/editor/embedded-editor-surface.js +22 -0
  68. package/dist/components/editor/embedded-editor-surface.svelte +115 -0
  69. package/dist/components/editor/embedded-editor-surface.svelte.d.ts +17 -0
  70. package/dist/components/editor/extensions/autocomplete/index.d.ts +2 -0
  71. package/dist/components/editor/extensions/autocomplete/index.js +2 -0
  72. package/dist/components/editor/extensions/autocomplete/lapis-code-mirror-autocomplete.d.ts +16 -0
  73. package/dist/components/editor/extensions/autocomplete/lapis-code-mirror-autocomplete.js +34 -0
  74. package/dist/components/editor/extensions/autocomplete/vault-completion-sources.d.ts +27 -0
  75. package/dist/components/editor/extensions/autocomplete/vault-completion-sources.js +55 -0
  76. package/dist/components/editor/extensions/class-highlighter/index.d.ts +1 -0
  77. package/dist/components/editor/extensions/class-highlighter/index.js +47 -0
  78. package/dist/components/editor/extensions/fold-gutter/index.d.ts +8 -0
  79. package/dist/components/editor/extensions/fold-gutter/index.js +40 -0
  80. package/dist/components/editor/extensions/gutter-line-style-sync/index.d.ts +2 -0
  81. package/dist/components/editor/extensions/gutter-line-style-sync/index.js +118 -0
  82. package/dist/components/editor/extensions/lint/index.d.ts +4 -0
  83. package/dist/components/editor/extensions/lint/index.js +4 -0
  84. package/dist/components/editor/extensions/lint/lapis-code-mirror-lint.d.ts +26 -0
  85. package/dist/components/editor/extensions/lint/lapis-code-mirror-lint.js +101 -0
  86. package/dist/components/editor/extensions/lint/lapis-lint-diagnostic-helpers.d.ts +8 -0
  87. package/dist/components/editor/extensions/lint/lapis-lint-diagnostic-helpers.js +7 -0
  88. package/dist/components/editor/extensions/lint/lapis-lint-diagnostic.d.ts +20 -0
  89. package/dist/components/editor/extensions/lint/lapis-lint-diagnostic.js +47 -0
  90. package/dist/components/editor/extensions/lint/lapis-lint-hover-tooltip.d.ts +9 -0
  91. package/dist/components/editor/extensions/lint/lapis-lint-hover-tooltip.js +373 -0
  92. package/dist/components/editor/extensions/lint/lapis-lint-inline-widget.d.ts +31 -0
  93. package/dist/components/editor/extensions/lint/lapis-lint-inline-widget.js +191 -0
  94. package/dist/components/editor/extensions/lint/lapis-lint-tooltip.svelte +176 -0
  95. package/dist/components/editor/extensions/lint/lapis-lint-tooltip.svelte.d.ts +15 -0
  96. package/dist/components/editor/extensions/lint/lint-tooltip-actions.d.ts +11 -0
  97. package/dist/components/editor/extensions/lint/lint-tooltip-actions.js +21 -0
  98. package/dist/components/editor/extensions/lint/mount-lint-tooltip.d.ts +16 -0
  99. package/dist/components/editor/extensions/lint/mount-lint-tooltip.js +60 -0
  100. package/dist/components/editor/extensions/search/dom.d.ts +2 -0
  101. package/dist/components/editor/extensions/search/dom.js +6 -0
  102. package/dist/components/editor/extensions/search/index.d.ts +35 -0
  103. package/dist/components/editor/extensions/search/index.js +44 -0
  104. package/dist/components/editor/extensions/search/search.svelte +335 -0
  105. package/dist/components/editor/extensions/search/search.svelte.d.ts +8 -0
  106. package/dist/components/editor/index.d.ts +9 -0
  107. package/dist/components/editor/index.js +9 -0
  108. package/dist/components/editor/language-service/dom.d.ts +1 -0
  109. package/dist/components/editor/language-service/dom.js +6 -0
  110. package/dist/components/editor/language-service/index.d.ts +28 -0
  111. package/dist/components/editor/language-service/index.js +342 -0
  112. package/dist/components/empty-view/empty-view.css +39 -0
  113. package/dist/components/empty-view/empty-view.svelte +26 -0
  114. package/dist/components/empty-view/empty-view.svelte.d.ts +9 -0
  115. package/dist/components/empty-view/index.d.ts +2 -0
  116. package/dist/components/empty-view/index.js +2 -0
  117. package/dist/components/icon/icon-list.css +74 -0
  118. package/dist/components/icon/icon-list.svelte +213 -0
  119. package/dist/components/icon/icon-list.svelte.d.ts +11 -0
  120. package/dist/components/icon/icon.svelte +15 -0
  121. package/dist/components/icon/icon.svelte.d.ts +7 -0
  122. package/dist/components/icon/index.d.ts +3 -0
  123. package/dist/components/icon/index.js +3 -0
  124. package/dist/components/menu/context-menu.svelte +89 -0
  125. package/dist/components/menu/context-menu.svelte.d.ts +11 -0
  126. package/dist/components/menu/drawer-menu.svelte +83 -0
  127. package/dist/components/menu/drawer-menu.svelte.d.ts +8 -0
  128. package/dist/components/menu/dropdown-menu.svelte +89 -0
  129. package/dist/components/menu/dropdown-menu.svelte.d.ts +11 -0
  130. package/dist/components/menu/index.d.ts +6 -0
  131. package/dist/components/menu/index.js +6 -0
  132. package/dist/components/menu/menu.css +139 -0
  133. package/dist/components/menu/menu.svelte +37 -0
  134. package/dist/components/menu/menu.svelte.d.ts +11 -0
  135. package/dist/components/menu/mobile-menu-query.svelte.d.ts +3 -0
  136. package/dist/components/menu/mobile-menu-query.svelte.js +21 -0
  137. package/dist/components/menu/popover-menu.svelte +90 -0
  138. package/dist/components/menu/popover-menu.svelte.d.ts +10 -0
  139. package/dist/components/select/index.d.ts +2 -0
  140. package/dist/components/select/index.js +2 -0
  141. package/dist/components/select/select.svelte +72 -0
  142. package/dist/components/select/select.svelte.d.ts +25 -0
  143. package/dist/configuration-option-source-providers.d.ts +17 -0
  144. package/dist/configuration-option-source-providers.js +59 -0
  145. package/dist/configuration-option-source-registry.d.ts +59 -0
  146. package/dist/configuration-option-source-registry.js +123 -0
  147. package/dist/configuration.svelte.d.ts +258 -0
  148. package/dist/configuration.svelte.js +887 -0
  149. package/dist/context-keys.svelte.d.ts +42 -0
  150. package/dist/context-keys.svelte.js +278 -0
  151. package/dist/context.svelte.d.ts +247 -0
  152. package/dist/context.svelte.js +540 -0
  153. package/dist/daily-document-provider.d.ts +38 -0
  154. package/dist/daily-document-provider.js +176 -0
  155. package/dist/design-core-button-types.d.ts +7 -0
  156. package/dist/design-core-button-types.js +1 -0
  157. package/dist/diagnostics.d.ts +93 -0
  158. package/dist/diagnostics.js +84 -0
  159. package/dist/dialog-portal.d.ts +3 -0
  160. package/dist/dialog-portal.js +3 -0
  161. package/dist/docs-api.d.ts +44 -0
  162. package/dist/docs-api.js +29 -0
  163. package/dist/editor-view-registry.d.ts +35 -0
  164. package/dist/editor-view-registry.js +112 -0
  165. package/dist/editor.svelte.d.ts +126 -0
  166. package/dist/editor.svelte.js +454 -0
  167. package/dist/embed-registry.d.ts +15 -0
  168. package/dist/embed-registry.js +16 -0
  169. package/dist/enhance.d.ts +111 -0
  170. package/dist/enhance.js +309 -0
  171. package/dist/events.d.ts +28 -0
  172. package/dist/events.js +49 -0
  173. package/dist/file-manager.d.ts +90 -0
  174. package/dist/file-manager.js +289 -0
  175. package/dist/file-tools/app-tools.d.ts +3 -0
  176. package/dist/file-tools/app-tools.js +242 -0
  177. package/dist/file-tools/index.d.ts +3 -0
  178. package/dist/file-tools/index.js +3 -0
  179. package/dist/file-tools/paths.d.ts +14 -0
  180. package/dist/file-tools/paths.js +33 -0
  181. package/dist/file-tools/vault-operations.d.ts +3 -0
  182. package/dist/file-tools/vault-operations.js +60 -0
  183. package/dist/generated/plugin-host-modules.schema.generated.d.ts +371 -0
  184. package/dist/generated/plugin-host-modules.schema.generated.js +374 -0
  185. package/dist/glob.d.ts +15 -0
  186. package/dist/glob.js +68 -0
  187. package/dist/history.svelte.d.ts +24 -0
  188. package/dist/history.svelte.js +74 -0
  189. package/dist/hooks/createVirtualizer.svelte.d.ts +7 -0
  190. package/dist/hooks/createVirtualizer.svelte.js +70 -0
  191. package/dist/hooks/index.d.ts +5 -0
  192. package/dist/hooks/index.js +5 -0
  193. package/dist/hooks/is-mobile.svelte.d.ts +5 -0
  194. package/dist/hooks/is-mobile.svelte.js +23 -0
  195. package/dist/hooks/mountComponent.svelte.d.ts +7 -0
  196. package/dist/hooks/mountComponent.svelte.js +16 -0
  197. package/dist/hooks/use-text-highlight.d.ts +17 -0
  198. package/dist/hooks/use-text-highlight.js +82 -0
  199. package/dist/hooks/useBoundingRect.svelte.d.ts +11 -0
  200. package/dist/hooks/useBoundingRect.svelte.js +46 -0
  201. package/dist/icons/index.d.ts +57 -0
  202. package/dist/icons/index.js +288 -0
  203. package/dist/index.d.ts +87 -0
  204. package/dist/index.js +87 -0
  205. package/dist/language-service/index.d.ts +9 -0
  206. package/dist/language-service/index.js +7 -0
  207. package/dist/language-service/manager.d.ts +47 -0
  208. package/dist/language-service/manager.js +404 -0
  209. package/dist/language-service/types.d.ts +92 -0
  210. package/dist/language-service/types.js +1 -0
  211. package/dist/language-service/virtual-document.d.ts +11 -0
  212. package/dist/language-service/virtual-document.js +45 -0
  213. package/dist/language-service/worker-protocol.d.ts +63 -0
  214. package/dist/language-service/worker-protocol.js +1 -0
  215. package/dist/language-service/worker-provider.d.ts +9 -0
  216. package/dist/language-service/worker-provider.js +38 -0
  217. package/dist/lapis-extension.d.ts +244 -0
  218. package/dist/lapis-extension.js +591 -0
  219. package/dist/links.d.ts +34 -0
  220. package/dist/links.js +191 -0
  221. package/dist/loaders.d.ts +9 -0
  222. package/dist/loaders.js +59 -0
  223. package/dist/localization-manager.svelte.d.ts +56 -0
  224. package/dist/localization-manager.svelte.js +157 -0
  225. package/dist/logging.d.ts +172 -0
  226. package/dist/logging.js +352 -0
  227. package/dist/markdown-extension-registry.d.ts +31 -0
  228. package/dist/markdown-extension-registry.js +31 -0
  229. package/dist/markdown-file-surface-registry.d.ts +25 -0
  230. package/dist/markdown-file-surface-registry.js +23 -0
  231. package/dist/markdown.d.ts +205 -0
  232. package/dist/markdown.js +147 -0
  233. package/dist/menu-utils.d.ts +1 -0
  234. package/dist/menu-utils.js +47 -0
  235. package/dist/menu.svelte.d.ts +121 -0
  236. package/dist/menu.svelte.js +295 -0
  237. package/dist/metadata-value.d.ts +10 -0
  238. package/dist/metadata-value.js +173 -0
  239. package/dist/metadata.svelte.d.ts +106 -0
  240. package/dist/metadata.svelte.js +608 -0
  241. package/dist/notifications.d.ts +209 -0
  242. package/dist/notifications.js +338 -0
  243. package/dist/open-file.d.ts +23 -0
  244. package/dist/open-file.js +102 -0
  245. package/dist/platform.d.ts +86 -0
  246. package/dist/platform.js +86 -0
  247. package/dist/plugin-asset-server.d.ts +60 -0
  248. package/dist/plugin-asset-server.js +222 -0
  249. package/dist/plugin-assets.d.ts +4 -0
  250. package/dist/plugin-assets.js +3 -0
  251. package/dist/plugin-capability-facade.d.ts +104 -0
  252. package/dist/plugin-capability-facade.js +61 -0
  253. package/dist/plugin-dependency-resolver.d.ts +36 -0
  254. package/dist/plugin-dependency-resolver.js +54 -0
  255. package/dist/plugin-dependency-scanner.d.ts +9 -0
  256. package/dist/plugin-dependency-scanner.js +274 -0
  257. package/dist/plugin-distribution/canonical-json.d.ts +1 -0
  258. package/dist/plugin-distribution/canonical-json.js +40 -0
  259. package/dist/plugin-distribution/compatibility.d.ts +5 -0
  260. package/dist/plugin-distribution/compatibility.js +38 -0
  261. package/dist/plugin-distribution/errors.d.ts +11 -0
  262. package/dist/plugin-distribution/errors.js +13 -0
  263. package/dist/plugin-distribution/hashes.d.ts +2 -0
  264. package/dist/plugin-distribution/hashes.js +17 -0
  265. package/dist/plugin-distribution/index.d.ts +18 -0
  266. package/dist/plugin-distribution/index.js +18 -0
  267. package/dist/plugin-distribution/installed-plugin-state.d.ts +20 -0
  268. package/dist/plugin-distribution/installed-plugin-state.js +73 -0
  269. package/dist/plugin-distribution/installer.d.ts +89 -0
  270. package/dist/plugin-distribution/installer.js +395 -0
  271. package/dist/plugin-distribution/manager.d.ts +128 -0
  272. package/dist/plugin-distribution/manager.js +358 -0
  273. package/dist/plugin-distribution/path-safety.d.ts +2 -0
  274. package/dist/plugin-distribution/path-safety.js +20 -0
  275. package/dist/plugin-distribution/plugin-bundle-verifier.d.ts +28 -0
  276. package/dist/plugin-distribution/plugin-bundle-verifier.js +96 -0
  277. package/dist/plugin-distribution/plugin-bundle-worker.d.ts +34 -0
  278. package/dist/plugin-distribution/plugin-bundle-worker.js +99 -0
  279. package/dist/plugin-distribution/plugin-bundle.d.ts +16 -0
  280. package/dist/plugin-distribution/plugin-bundle.js +244 -0
  281. package/dist/plugin-distribution/plugin-bundle.worker.d.ts +1 -0
  282. package/dist/plugin-distribution/plugin-bundle.worker.js +38 -0
  283. package/dist/plugin-distribution/registry-cache.d.ts +26 -0
  284. package/dist/plugin-distribution/registry-cache.js +85 -0
  285. package/dist/plugin-distribution/registry-client.d.ts +36 -0
  286. package/dist/plugin-distribution/registry-client.js +115 -0
  287. package/dist/plugin-distribution/reserved-ids.d.ts +4 -0
  288. package/dist/plugin-distribution/reserved-ids.js +10 -0
  289. package/dist/plugin-distribution/runtime-validation.d.ts +14 -0
  290. package/dist/plugin-distribution/runtime-validation.js +388 -0
  291. package/dist/plugin-distribution/schemas.d.ts +4895 -0
  292. package/dist/plugin-distribution/schemas.js +299 -0
  293. package/dist/plugin-distribution/signing.d.ts +5 -0
  294. package/dist/plugin-distribution/signing.js +38 -0
  295. package/dist/plugin-distribution/types.d.ts +217 -0
  296. package/dist/plugin-distribution/types.js +1 -0
  297. package/dist/plugin-install-progress.d.ts +15 -0
  298. package/dist/plugin-install-progress.js +86 -0
  299. package/dist/plugin-manager.d.ts +306 -0
  300. package/dist/plugin-manager.js +2848 -0
  301. package/dist/plugin-runtime-entry.d.ts +19 -0
  302. package/dist/plugin-runtime-entry.js +135 -0
  303. package/dist/plugin.d.ts +350 -0
  304. package/dist/plugin.js +754 -0
  305. package/dist/popover.d.ts +20 -0
  306. package/dist/popover.js +32 -0
  307. package/dist/promise-worker.d.ts +22 -0
  308. package/dist/promise-worker.js +65 -0
  309. package/dist/prompt-confirm.d.ts +9 -0
  310. package/dist/prompt-confirm.js +33 -0
  311. package/dist/search-document-provider.d.ts +45 -0
  312. package/dist/search-document-provider.js +54 -0
  313. package/dist/search-query/index.d.ts +78 -0
  314. package/dist/search-query/index.js +426 -0
  315. package/dist/search-query/parser.d.ts +3 -0
  316. package/dist/search-query/parser.js +16 -0
  317. package/dist/search-query/parser.terms.js +26 -0
  318. package/dist/search-query/search-query.grammar +128 -0
  319. package/dist/search.d.ts +19 -0
  320. package/dist/search.js +104 -0
  321. package/dist/setting-section-layout.d.ts +19 -0
  322. package/dist/setting-section-layout.js +194 -0
  323. package/dist/settings.svelte.d.ts +474 -0
  324. package/dist/settings.svelte.js +1421 -0
  325. package/dist/source-text-file-view.d.ts +25 -0
  326. package/dist/source-text-file-view.js +78 -0
  327. package/dist/status-bar.svelte.d.ts +29 -0
  328. package/dist/status-bar.svelte.js +72 -0
  329. package/dist/storage/app-database.d.ts +860 -0
  330. package/dist/storage/app-database.js +2372 -0
  331. package/dist/storage/blob-store.d.ts +12 -0
  332. package/dist/storage/blob-store.js +1 -0
  333. package/dist/storage/browser-app-database-coordination.d.ts +35 -0
  334. package/dist/storage/browser-app-database-coordination.js +207 -0
  335. package/dist/storage/browser-coordinated-app-database.d.ts +109 -0
  336. package/dist/storage/browser-coordinated-app-database.js +704 -0
  337. package/dist/storage/browser.d.ts +153 -0
  338. package/dist/storage/browser.js +794 -0
  339. package/dist/storage/desktop-native.d.ts +184 -0
  340. package/dist/storage/desktop-native.js +415 -0
  341. package/dist/storage/fs.d.ts +188 -0
  342. package/dist/storage/fs.js +307 -0
  343. package/dist/storage/index-projection.d.ts +236 -0
  344. package/dist/storage/index-projection.js +402 -0
  345. package/dist/storage/index.d.ts +17 -0
  346. package/dist/storage/index.js +17 -0
  347. package/dist/storage/keyval.d.ts +94 -0
  348. package/dist/storage/keyval.js +199 -0
  349. package/dist/storage/memory-vault-adapter.d.ts +44 -0
  350. package/dist/storage/memory-vault-adapter.js +351 -0
  351. package/dist/storage/native-vault-bootstrap-kv.d.ts +22 -0
  352. package/dist/storage/native-vault-bootstrap-kv.js +96 -0
  353. package/dist/storage/path.d.ts +22 -0
  354. package/dist/storage/path.js +110 -0
  355. package/dist/storage/search-embedding-provider.d.ts +75 -0
  356. package/dist/storage/search-embedding-provider.js +446 -0
  357. package/dist/storage/search-embedding-worker.d.ts +1 -0
  358. package/dist/storage/search-embedding-worker.js +63 -0
  359. package/dist/storage/search-query-evaluator.d.ts +14 -0
  360. package/dist/storage/search-query-evaluator.js +678 -0
  361. package/dist/storage/task-projection.d.ts +152 -0
  362. package/dist/storage/task-projection.js +154 -0
  363. package/dist/storage/turso-app-database.d.ts +150 -0
  364. package/dist/storage/turso-app-database.js +2671 -0
  365. package/dist/storage/vault-session.d.ts +37 -0
  366. package/dist/storage/vault-session.js +196 -0
  367. package/dist/storage/vault-state.d.ts +74 -0
  368. package/dist/storage/vault-state.js +181 -0
  369. package/dist/storage/vault.svelte.d.ts +257 -0
  370. package/dist/storage/vault.svelte.js +661 -0
  371. package/dist/suggest.d.ts +193 -0
  372. package/dist/suggest.js +391 -0
  373. package/dist/tasks.d.ts +7 -0
  374. package/dist/tasks.js +18 -0
  375. package/dist/telemetry.d.ts +116 -0
  376. package/dist/telemetry.js +103 -0
  377. package/dist/utils.d.ts +55 -0
  378. package/dist/utils.js +314 -0
  379. package/dist/vault-api.d.ts +5 -0
  380. package/dist/vault-api.js +3 -0
  381. package/dist/vault-maintenance-commands.d.ts +5 -0
  382. package/dist/vault-maintenance-commands.js +32 -0
  383. package/dist/view.svelte.d.ts +215 -0
  384. package/dist/view.svelte.js +381 -0
  385. package/dist/vite-env.d.ts +2 -0
  386. package/dist/workspace-host-internal.d.ts +7 -0
  387. package/dist/workspace-host-internal.js +7 -0
  388. package/dist/workspace-host.d.ts +10 -0
  389. package/dist/workspace-host.js +14 -0
  390. package/dist/workspace-layout-commands.d.ts +3 -0
  391. package/dist/workspace-layout-commands.js +72 -0
  392. package/dist/workspace-layout-normalizer.d.ts +92 -0
  393. package/dist/workspace-layout-normalizer.js +301 -0
  394. package/dist/workspace-layouts.d.ts +7 -0
  395. package/dist/workspace-layouts.js +23 -0
  396. package/dist/workspace-trust.d.ts +32 -0
  397. package/dist/workspace-trust.js +72 -0
  398. package/dist/workspace.svelte.d.ts +796 -0
  399. package/dist/workspace.svelte.js +4380 -0
  400. package/package.json +240 -0
@@ -0,0 +1,244 @@
1
+ import { Unzip, UnzipInflate } from "fflate";
2
+ import { PluginDistributionError } from "./errors";
3
+ import { assertSafePluginRelativePath } from "./path-safety";
4
+ export const PLUGIN_BUNDLE_RELEASE_MANIFEST_PATH = "release.signed.json";
5
+ export const PLUGIN_BUNDLE_STORED_METHOD = 0;
6
+ export const PLUGIN_BUNDLE_DEFLATE_METHOD = 8;
7
+ export const parsePluginBundle = (input, options = {}) => {
8
+ const bytes = toUint8(input);
9
+ const expectedEntries = inspectPluginBundleMetadata(bytes);
10
+ const entries = new Map();
11
+ let seenFileCount = 0;
12
+ let processedBytes = 0;
13
+ const fileCount = expectedEntries.length;
14
+ const totalBytes = expectedEntries.reduce((sum, entry) => sum + entry.uncompressedSize, 0);
15
+ let firstError = null;
16
+ const unzip = new Unzip((file) => {
17
+ if (firstError) {
18
+ return;
19
+ }
20
+ try {
21
+ const expectedEntry = expectedEntries[seenFileCount];
22
+ const fileIndex = seenFileCount + 1;
23
+ seenFileCount += 1;
24
+ if (!expectedEntry) {
25
+ throw invalidBundle(`Unexpected file in .lapis-plugin bundle: ${file.name}`);
26
+ }
27
+ if (file.name !== expectedEntry.path ||
28
+ file.compression !== expectedEntry.compressionMethod) {
29
+ throw invalidBundle(`Plugin bundle local entry order or method is invalid: ${file.name}`);
30
+ }
31
+ assertBundlePath(file.name);
32
+ if (entries.has(file.name)) {
33
+ throw invalidBundle(`Duplicate file in .lapis-plugin bundle: ${file.name}`);
34
+ }
35
+ if (!isSupportedCompressionMethod(file.compression)) {
36
+ throw invalidBundle(`Unsupported plugin bundle compression method ${file.compression}: ${file.name}`);
37
+ }
38
+ const chunks = [];
39
+ let byteLength = 0;
40
+ file.ondata = (error, chunk, final) => {
41
+ if (error) {
42
+ firstError = invalidBundle(`Unable to extract plugin bundle file: ${file.name}`, error);
43
+ return;
44
+ }
45
+ chunks.push(chunk);
46
+ byteLength += chunk.byteLength;
47
+ processedBytes += chunk.byteLength;
48
+ options.onProgress?.({
49
+ phase: "extracting-files",
50
+ message: `Extracting ${file.name}`,
51
+ filePath: file.name,
52
+ fileIndex,
53
+ fileCount,
54
+ processedBytes,
55
+ totalBytes,
56
+ });
57
+ if (final) {
58
+ entries.set(file.name, concatChunks(chunks, byteLength));
59
+ }
60
+ };
61
+ file.start();
62
+ }
63
+ catch (error) {
64
+ firstError = toInvalidBundleError(error);
65
+ }
66
+ });
67
+ unzip.register(UnzipInflate);
68
+ try {
69
+ unzip.push(bytes, true);
70
+ }
71
+ catch (error) {
72
+ firstError = toInvalidBundleError(error);
73
+ }
74
+ if (firstError) {
75
+ throw firstError;
76
+ }
77
+ if (seenFileCount !== expectedEntries.length) {
78
+ throw invalidBundle(".lapis-plugin bundle entry count is invalid.");
79
+ }
80
+ for (const expectedEntry of expectedEntries) {
81
+ if (!entries.has(expectedEntry.path)) {
82
+ throw invalidBundle(`.lapis-plugin bundle did not extract ${expectedEntry.path}.`);
83
+ }
84
+ }
85
+ if (!entries.has(PLUGIN_BUNDLE_RELEASE_MANIFEST_PATH)) {
86
+ throw invalidBundle(".lapis-plugin bundle is missing release.signed.json.");
87
+ }
88
+ return entries;
89
+ };
90
+ const inspectPluginBundleMetadata = (bytes) => {
91
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
92
+ const eocdOffset = findEndOfCentralDirectory(view);
93
+ const totalEntries = readUint16(view, eocdOffset + 10);
94
+ const centralDirectorySize = readUint32(view, eocdOffset + 12);
95
+ const centralDirectoryOffset = readUint32(view, eocdOffset + 16);
96
+ if (readUint16(view, eocdOffset + 4) !== 0 ||
97
+ readUint16(view, eocdOffset + 6) !== 0 ||
98
+ readUint16(view, eocdOffset + 8) !== totalEntries) {
99
+ throw invalidBundle("Multi-disk .lapis-plugin bundles are not supported.");
100
+ }
101
+ if (totalEntries === 0xffff ||
102
+ centralDirectorySize === 0xffffffff ||
103
+ centralDirectoryOffset === 0xffffffff) {
104
+ throw invalidBundle("ZIP64 .lapis-plugin bundles are not supported.");
105
+ }
106
+ assertRange(centralDirectoryOffset, centralDirectorySize, bytes.byteLength, "central directory");
107
+ const decoder = new TextDecoder();
108
+ const entries = [];
109
+ const seenPaths = new Set();
110
+ let offset = centralDirectoryOffset;
111
+ for (let index = 0; index < totalEntries; index += 1) {
112
+ assertSignature(view, offset, 0x02014b50, "central directory entry");
113
+ const flags = readUint16(view, offset + 8);
114
+ const compressionMethod = readUint16(view, offset + 10);
115
+ const compressedSize = readUint32(view, offset + 20);
116
+ const uncompressedSize = readUint32(view, offset + 24);
117
+ const nameLength = readUint16(view, offset + 28);
118
+ const extraLength = readUint16(view, offset + 30);
119
+ const commentLength = readUint16(view, offset + 32);
120
+ const localHeaderOffset = readUint32(view, offset + 42);
121
+ const nameStart = offset + 46;
122
+ const nameEnd = nameStart + nameLength;
123
+ assertRange(nameStart, nameLength, bytes.byteLength, "entry name");
124
+ const path = decoder.decode(bytes.subarray(nameStart, nameEnd));
125
+ assertBundlePath(path);
126
+ if (seenPaths.has(path)) {
127
+ throw invalidBundle(`Duplicate file in .lapis-plugin bundle: ${path}`);
128
+ }
129
+ seenPaths.add(path);
130
+ if ((flags & 0x41) !== 0) {
131
+ throw invalidBundle(`Encrypted plugin bundle file is not supported: ${path}`);
132
+ }
133
+ if (!isSupportedCompressionMethod(compressionMethod)) {
134
+ throw invalidBundle(`Unsupported plugin bundle compression method ${compressionMethod}: ${path}`);
135
+ }
136
+ if (compressedSize === 0xffffffff || uncompressedSize === 0xffffffff) {
137
+ throw invalidBundle(`ZIP64 plugin bundle file metadata is not supported: ${path}`);
138
+ }
139
+ entries.push({
140
+ ...inspectLocalEntry({
141
+ bytes,
142
+ view,
143
+ decoder,
144
+ path,
145
+ localHeaderOffset,
146
+ compressionMethod,
147
+ flags,
148
+ }),
149
+ uncompressedSize,
150
+ });
151
+ offset += 46 + nameLength + extraLength + commentLength;
152
+ }
153
+ if (offset !== centralDirectoryOffset + centralDirectorySize) {
154
+ throw invalidBundle(".lapis-plugin central directory size is invalid.");
155
+ }
156
+ const localOrder = [...entries].sort((left, right) => left.localHeaderOffset - right.localHeaderOffset);
157
+ const firstEntry = localOrder[0];
158
+ if (firstEntry?.path !== PLUGIN_BUNDLE_RELEASE_MANIFEST_PATH) {
159
+ throw invalidBundle(".lapis-plugin bundle must store release.signed.json as the first entry.");
160
+ }
161
+ if (firstEntry.compressionMethod !== PLUGIN_BUNDLE_STORED_METHOD) {
162
+ throw invalidBundle(".lapis-plugin release.signed.json entry must be stored.");
163
+ }
164
+ if (!seenPaths.has(PLUGIN_BUNDLE_RELEASE_MANIFEST_PATH)) {
165
+ throw invalidBundle(".lapis-plugin bundle is missing release.signed.json.");
166
+ }
167
+ return localOrder;
168
+ };
169
+ const inspectLocalEntry = ({ bytes, view, decoder, path, localHeaderOffset, compressionMethod, flags, }) => {
170
+ assertSignature(view, localHeaderOffset, 0x04034b50, "local file header");
171
+ const localFlags = readUint16(view, localHeaderOffset + 6);
172
+ const localCompressionMethod = readUint16(view, localHeaderOffset + 8);
173
+ const nameLength = readUint16(view, localHeaderOffset + 26);
174
+ const extraLength = readUint16(view, localHeaderOffset + 28);
175
+ const nameStart = localHeaderOffset + 30;
176
+ const nameEnd = nameStart + nameLength;
177
+ assertRange(nameStart, nameLength, bytes.byteLength, "local entry name");
178
+ assertRange(nameEnd, extraLength, bytes.byteLength, "local entry extra");
179
+ const localPath = decoder.decode(bytes.subarray(nameStart, nameEnd));
180
+ if (localPath !== path ||
181
+ localFlags !== flags ||
182
+ localCompressionMethod !== compressionMethod) {
183
+ throw invalidBundle(`Plugin bundle local header mismatch: ${path}`);
184
+ }
185
+ return { path, compressionMethod, localHeaderOffset };
186
+ };
187
+ const assertBundlePath = (path) => {
188
+ if (path.endsWith("/")) {
189
+ throw invalidBundle(`Plugin bundle directories are not supported: ${path}`);
190
+ }
191
+ if (path === PLUGIN_BUNDLE_RELEASE_MANIFEST_PATH) {
192
+ return;
193
+ }
194
+ assertSafePluginRelativePath(path);
195
+ };
196
+ const isSupportedCompressionMethod = (compressionMethod) => compressionMethod === PLUGIN_BUNDLE_STORED_METHOD ||
197
+ compressionMethod === PLUGIN_BUNDLE_DEFLATE_METHOD;
198
+ const findEndOfCentralDirectory = (view) => {
199
+ const minimumSize = 22;
200
+ const minOffset = Math.max(0, view.byteLength - 0xffff - minimumSize);
201
+ for (let offset = view.byteLength - minimumSize; offset >= minOffset; offset -= 1) {
202
+ if (readUint32(view, offset) !== 0x06054b50) {
203
+ continue;
204
+ }
205
+ const commentLength = readUint16(view, offset + 20);
206
+ if (offset + minimumSize + commentLength === view.byteLength) {
207
+ return offset;
208
+ }
209
+ }
210
+ throw invalidBundle(".lapis-plugin bundle is not a ZIP-compatible archive.");
211
+ };
212
+ const assertSignature = (view, offset, expected, label) => {
213
+ assertRange(offset, 4, view.byteLength, label);
214
+ if (readUint32(view, offset) !== expected) {
215
+ throw invalidBundle(`Invalid .lapis-plugin ${label}.`);
216
+ }
217
+ };
218
+ const assertRange = (offset, length, totalLength, label) => {
219
+ if (!Number.isInteger(offset) ||
220
+ !Number.isInteger(length) ||
221
+ offset < 0 ||
222
+ length < 0 ||
223
+ offset + length > totalLength) {
224
+ throw invalidBundle(`Invalid .lapis-plugin ${label} range.`);
225
+ }
226
+ };
227
+ const readUint16 = (view, offset) => view.getUint16(offset, true);
228
+ const readUint32 = (view, offset) => view.getUint32(offset, true);
229
+ const toUint8 = (input) => input instanceof Uint8Array ? input : new Uint8Array(input);
230
+ const concatChunks = (chunks, byteLength) => {
231
+ const bytes = new Uint8Array(byteLength);
232
+ let offset = 0;
233
+ for (const chunk of chunks) {
234
+ bytes.set(chunk, offset);
235
+ offset += chunk.byteLength;
236
+ }
237
+ return bytes;
238
+ };
239
+ const toInvalidBundleError = (error) => error instanceof PluginDistributionError
240
+ ? error
241
+ : invalidBundle(error instanceof Error
242
+ ? error.message
243
+ : ".lapis-plugin bundle is invalid.", error);
244
+ const invalidBundle = (message, cause) => new PluginDistributionError("metadata-invalid", message, { cause });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,38 @@
1
+ import { serializeWorkerError, } from "./plugin-bundle-worker";
2
+ import { verifyPluginBundlePayload } from "./plugin-bundle-verifier";
3
+ const worker = self;
4
+ worker.addEventListener("message", async (event) => {
5
+ if (event.data.type !== "verify") {
6
+ return;
7
+ }
8
+ try {
9
+ const payload = await verifyPluginBundlePayload({
10
+ bundle: event.data.bundle,
11
+ trustedKeys: event.data.trustedKeys,
12
+ expectedBundle: event.data.expectedBundle,
13
+ onProgress: (progress) => {
14
+ worker.postMessage({
15
+ type: "progress",
16
+ progress,
17
+ });
18
+ },
19
+ });
20
+ const files = [...payload.files.entries()];
21
+ worker.postMessage({
22
+ type: "result",
23
+ payload: {
24
+ releaseEnvelope: payload.releaseEnvelope,
25
+ releaseManifest: payload.releaseManifest,
26
+ releaseManifestSha256: payload.releaseManifestSha256,
27
+ files,
28
+ },
29
+ }, files.map(([, bytes]) => bytes.buffer));
30
+ }
31
+ catch (error) {
32
+ worker.postMessage({
33
+ type: "error",
34
+ error: serializeWorkerError(error),
35
+ });
36
+ }
37
+ });
38
+ export {};
@@ -0,0 +1,26 @@
1
+ import type { DataAdapter } from "../storage/fs";
2
+ import type { PluginCatalogDetail, PluginCatalogIndex, PluginRevocationIndex } from "./types";
3
+ export interface PluginRegistryCacheRecord {
4
+ schemaVersion: 1;
5
+ updatedAt: string;
6
+ sourceUrl: string;
7
+ index: PluginCatalogIndex;
8
+ details: Record<string, PluginCatalogDetail>;
9
+ revocations?: PluginRevocationIndex;
10
+ }
11
+ export declare class PluginRegistryCache {
12
+ private readonly options;
13
+ private memory;
14
+ constructor(options?: {
15
+ adapter?: DataAdapter;
16
+ cachePath?: string;
17
+ now?: () => Date;
18
+ });
19
+ getMemory(): PluginRegistryCacheRecord | null;
20
+ read(): Promise<PluginRegistryCacheRecord | null>;
21
+ write(sourceUrl: string, index: PluginCatalogIndex, details?: Record<string, PluginCatalogDetail>, revocations?: PluginRevocationIndex): Promise<PluginRegistryCacheRecord>;
22
+ putDetail(pluginId: string, detail: PluginCatalogDetail): Promise<PluginRegistryCacheRecord | null>;
23
+ putRevocations(revocations: PluginRevocationIndex): Promise<PluginRegistryCacheRecord | null>;
24
+ private get cachePath();
25
+ private get cacheFolder();
26
+ }
@@ -0,0 +1,85 @@
1
+ import { pluginCatalogDetailSchema, pluginCatalogIndexSchema, pluginRevocationIndexSchema, parsePluginDistributionMetadata, } from "./schemas";
2
+ export class PluginRegistryCache {
3
+ options;
4
+ memory = null;
5
+ constructor(options = {}) {
6
+ this.options = options;
7
+ }
8
+ getMemory() {
9
+ return this.memory;
10
+ }
11
+ async read() {
12
+ if (this.memory)
13
+ return this.memory;
14
+ if (!this.options.adapter)
15
+ return null;
16
+ try {
17
+ const raw = await this.options.adapter.read(this.cachePath);
18
+ const parsed = JSON.parse(raw);
19
+ this.memory = {
20
+ schemaVersion: 1,
21
+ updatedAt: parsed.updatedAt,
22
+ sourceUrl: parsed.sourceUrl,
23
+ index: parsePluginDistributionMetadata(pluginCatalogIndexSchema, parsed.index),
24
+ details: Object.fromEntries(Object.entries(parsed.details ?? {}).map(([pluginId, detail]) => [
25
+ pluginId,
26
+ parsePluginDistributionMetadata(pluginCatalogDetailSchema, detail),
27
+ ])),
28
+ revocations: parsed.revocations
29
+ ? parsePluginDistributionMetadata(pluginRevocationIndexSchema, parsed.revocations)
30
+ : undefined,
31
+ };
32
+ return this.memory;
33
+ }
34
+ catch {
35
+ return null;
36
+ }
37
+ }
38
+ async write(sourceUrl, index, details = {}, revocations) {
39
+ const record = {
40
+ schemaVersion: 1,
41
+ updatedAt: (this.options.now?.() ?? new Date()).toISOString(),
42
+ sourceUrl,
43
+ index,
44
+ details,
45
+ };
46
+ if (revocations)
47
+ record.revocations = revocations;
48
+ this.memory = record;
49
+ if (this.options.adapter) {
50
+ await ensureFolder(this.options.adapter, this.cacheFolder);
51
+ await this.options.adapter.write(this.cachePath, JSON.stringify(record));
52
+ }
53
+ return record;
54
+ }
55
+ async putDetail(pluginId, detail) {
56
+ const existing = await this.read();
57
+ if (!existing)
58
+ return null;
59
+ return this.write(existing.sourceUrl, existing.index, {
60
+ ...existing.details,
61
+ [pluginId]: detail,
62
+ }, existing.revocations);
63
+ }
64
+ async putRevocations(revocations) {
65
+ const existing = await this.read();
66
+ if (!existing)
67
+ return null;
68
+ return this.write(existing.sourceUrl, existing.index, existing.details, revocations);
69
+ }
70
+ get cachePath() {
71
+ return this.options.cachePath ?? ".obsidian/plugin-registry-cache.json";
72
+ }
73
+ get cacheFolder() {
74
+ const parts = this.cachePath.split("/");
75
+ parts.pop();
76
+ return parts.join("/") || "/";
77
+ }
78
+ }
79
+ const ensureFolder = async (adapter, folderPath) => {
80
+ if (folderPath === "/" || (await adapter.exists(folderPath)))
81
+ return;
82
+ const parent = folderPath.split("/").slice(0, -1).join("/") || "/";
83
+ await ensureFolder(adapter, parent);
84
+ await adapter.mkdir(folderPath);
85
+ };
@@ -0,0 +1,36 @@
1
+ import type { PluginCatalogDetail, PluginCatalogEntry, PluginCatalogIndex, PluginRegistrySource, PluginRevocationIndex, SignatureRecord, TrustedSigningKey } from "./types";
2
+ import { PluginRegistryCache } from "./registry-cache";
3
+ export type PluginRegistryFetch = (url: string, init?: RequestInit) => Promise<Pick<Response, "ok" | "status" | "statusText" | "text">>;
4
+ export interface PluginRegistryRefreshResult {
5
+ index: PluginCatalogIndex;
6
+ revocations: PluginRevocationIndex;
7
+ stale: boolean;
8
+ source: PluginRegistrySource;
9
+ }
10
+ export interface PluginRegistryDetailResult {
11
+ detail: PluginCatalogDetail;
12
+ stale: boolean;
13
+ }
14
+ export declare class PluginRegistryClient {
15
+ private readonly options;
16
+ private currentIndex;
17
+ private readonly fetchImpl;
18
+ private readonly cache;
19
+ constructor(options: {
20
+ trustedKeys: TrustedSigningKey[];
21
+ fetch?: PluginRegistryFetch;
22
+ cache?: PluginRegistryCache;
23
+ });
24
+ refresh(source: PluginRegistrySource): Promise<PluginRegistryRefreshResult>;
25
+ getDetail(entry: PluginCatalogEntry): Promise<PluginRegistryDetailResult>;
26
+ getCachedIndex(): PluginCatalogIndex | null;
27
+ private fetchJson;
28
+ private verifyIndex;
29
+ private fetchRevocations;
30
+ private verifyDetail;
31
+ private normalizeEntry;
32
+ private trustedKeysFor;
33
+ }
34
+ export declare const verifyInlineSignedMetadata: <T extends {
35
+ signatures?: SignatureRecord[];
36
+ }>(metadata: T, signatures: SignatureRecord[] | undefined, trustedKeys: TrustedSigningKey[]) => Promise<Omit<T, "signatures">>;
@@ -0,0 +1,115 @@
1
+ import { PluginDistributionError } from "./errors";
2
+ import { assertPluginIdAllowedForProvenance } from "./reserved-ids";
3
+ import { pluginCatalogDetailSchema, pluginCatalogIndexSchema, pluginRevocationIndexSchema, parsePluginDistributionMetadata, } from "./schemas";
4
+ import { verifySignedEnvelope } from "./signing";
5
+ import { PluginRegistryCache } from "./registry-cache";
6
+ export class PluginRegistryClient {
7
+ options;
8
+ currentIndex = null;
9
+ fetchImpl;
10
+ cache;
11
+ constructor(options) {
12
+ this.options = options;
13
+ this.fetchImpl =
14
+ options.fetch ??
15
+ ((url, init) => globalThis.fetch(url, init));
16
+ this.cache = options.cache ?? new PluginRegistryCache();
17
+ }
18
+ async refresh(source) {
19
+ try {
20
+ const metadata = await this.fetchJson(source.url);
21
+ const index = await this.verifyIndex(metadata, source);
22
+ const revocations = await this.fetchRevocations(source);
23
+ this.currentIndex = index;
24
+ await this.cache.write(source.url, index, {}, revocations);
25
+ return { index, revocations, stale: false, source };
26
+ }
27
+ catch (error) {
28
+ const cached = await this.cache.read();
29
+ if (cached && cached.sourceUrl === source.url) {
30
+ this.currentIndex = cached.index;
31
+ return {
32
+ index: cached.index,
33
+ revocations: cached.revocations ?? emptyRevocationIndex(),
34
+ stale: true,
35
+ source,
36
+ };
37
+ }
38
+ throw error;
39
+ }
40
+ }
41
+ async getDetail(entry) {
42
+ try {
43
+ const metadata = await this.fetchJson(entry.detail);
44
+ const detail = await this.verifyDetail(metadata, entry);
45
+ await this.cache.putDetail(entry.id, detail);
46
+ return { detail, stale: false };
47
+ }
48
+ catch (error) {
49
+ const cached = await this.cache.read();
50
+ const detail = cached?.details[entry.id];
51
+ if (detail)
52
+ return { detail, stale: true };
53
+ throw error;
54
+ }
55
+ }
56
+ getCachedIndex() {
57
+ return this.currentIndex ?? this.cache.getMemory()?.index ?? null;
58
+ }
59
+ async fetchJson(url) {
60
+ const response = await this.fetchImpl(url);
61
+ if (!response.ok) {
62
+ throw new PluginDistributionError("metadata-invalid", `Registry fetch failed for ${url}: ${response.status} ${response.statusText}`, { details: { url, status: response.status } });
63
+ }
64
+ return JSON.parse(await response.text());
65
+ }
66
+ async verifyIndex(metadata, source) {
67
+ const index = parsePluginDistributionMetadata(pluginCatalogIndexSchema, metadata);
68
+ const verified = (await verifyInlineSignedMetadata(index, index.signatures, this.trustedKeysFor(source.trustTier)));
69
+ return {
70
+ ...verified,
71
+ plugins: verified.plugins.map((entry) => this.normalizeEntry(entry, source)),
72
+ };
73
+ }
74
+ async fetchRevocations(source) {
75
+ const url = new URL("revoked.json", source.url).toString();
76
+ const metadata = await this.fetchJson(url);
77
+ const revocations = parsePluginDistributionMetadata(pluginRevocationIndexSchema, metadata);
78
+ const verified = await verifyInlineSignedMetadata(revocations, revocations.signatures, this.trustedKeysFor(source.trustTier));
79
+ return verified;
80
+ }
81
+ async verifyDetail(metadata, entry) {
82
+ const detail = parsePluginDistributionMetadata(pluginCatalogDetailSchema, metadata);
83
+ const verified = (await verifyInlineSignedMetadata(detail, detail.signatures, this.options.trustedKeys));
84
+ if (verified.id !== entry.id) {
85
+ throw new PluginDistributionError("metadata-invalid", `Plugin detail id ${verified.id} does not match catalog entry ${entry.id}.`, { details: { entryId: entry.id, detailId: verified.id } });
86
+ }
87
+ return verified;
88
+ }
89
+ normalizeEntry(entry, source) {
90
+ const provenance = source.trustTier === "official" ? "official" : "community";
91
+ assertPluginIdAllowedForProvenance(entry.id, provenance);
92
+ if (entry.channel === "official" && source.trustTier !== "official") {
93
+ throw new PluginDistributionError("metadata-invalid", `Non-official registry source ${source.id} cannot publish official entry ${entry.id}.`, { details: { sourceId: source.id, pluginId: entry.id } });
94
+ }
95
+ return {
96
+ ...entry,
97
+ detail: new URL(entry.detail, source.url).toString(),
98
+ };
99
+ }
100
+ trustedKeysFor(trustTier) {
101
+ return this.options.trustedKeys.filter((key) => key.trustTier === trustTier || key.trustTier === "official");
102
+ }
103
+ }
104
+ export const verifyInlineSignedMetadata = async (metadata, signatures, trustedKeys) => {
105
+ if (!signatures?.length) {
106
+ throw new PluginDistributionError("signature-invalid", "Signed registry metadata did not include any signatures.");
107
+ }
108
+ const { signatures: _signatures, ...signed } = metadata;
109
+ return verifySignedEnvelope({ signed, signatures }, trustedKeys);
110
+ };
111
+ const emptyRevocationIndex = () => ({
112
+ schemaVersion: 1,
113
+ generatedAt: new Date(0).toISOString(),
114
+ revoked: [],
115
+ });
@@ -0,0 +1,4 @@
1
+ import type { PluginProvenance } from "./types";
2
+ export declare const isReservedPluginId: (pluginId: string) => boolean;
3
+ export declare const assertPluginIdAllowedForProvenance: (pluginId: string, provenance: PluginProvenance) => void;
4
+ export declare const provenanceFromPluginManifest: (_manifest?: unknown) => "community";
@@ -0,0 +1,10 @@
1
+ import { PluginDistributionError } from "./errors";
2
+ const RESERVED_PREFIXES = ["lapis-"];
3
+ export const isReservedPluginId = (pluginId) => RESERVED_PREFIXES.some((prefix) => pluginId.startsWith(prefix));
4
+ export const assertPluginIdAllowedForProvenance = (pluginId, provenance) => {
5
+ if (isReservedPluginId(pluginId) &&
6
+ (provenance === "community" || provenance === "manual")) {
7
+ throw new PluginDistributionError("reserved-id", `Plugin id ${pluginId} is reserved for bundled, official, or development plugins.`, { details: { pluginId, provenance } });
8
+ }
9
+ };
10
+ export const provenanceFromPluginManifest = (_manifest) => "community";
@@ -0,0 +1,14 @@
1
+ import type { PluginManifest } from "../plugin";
2
+ import type { PluginProvenance, PluginReleaseManifest, PluginReleaseRuntimeDiagnostic } from "./types";
3
+ export interface PluginReleaseRuntimeValidationOptions {
4
+ releaseManifest: PluginReleaseManifest;
5
+ pluginManifest: PluginManifest;
6
+ files: ReadonlyMap<string, Uint8Array>;
7
+ provenance?: PluginProvenance;
8
+ }
9
+ export interface PluginReleaseRuntimeValidationResult {
10
+ diagnostics: PluginReleaseRuntimeDiagnostic[];
11
+ errors: PluginReleaseRuntimeDiagnostic[];
12
+ warnings: PluginReleaseRuntimeDiagnostic[];
13
+ }
14
+ export declare function validatePluginReleaseRuntime(options: PluginReleaseRuntimeValidationOptions): PluginReleaseRuntimeValidationResult;