@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,887 @@
1
+ import { z } from "zod";
2
+ import { SettingTab } from "./settings.svelte";
3
+ import { cloneDeep, isEqual } from "lodash-es";
4
+ import { EventDispatcher } from "./events";
5
+ import { dirname } from "./storage";
6
+ function isRecoverableConfigurationReadError(error) {
7
+ let current = error;
8
+ while (current) {
9
+ const err = current;
10
+ if (err?.name === "NotFoundError" ||
11
+ err?.name === "NotReadableError" ||
12
+ err?.name === "NoModificationAllowedError" ||
13
+ err?.name === "InvalidStateError" ||
14
+ err?.code === "ENOENT" ||
15
+ /\bENOENT\b|not found|could not be found/i.test(err?.message ?? "") ||
16
+ /state cached in an interface object was made but the state had changed/i.test(err?.message ?? "")) {
17
+ return true;
18
+ }
19
+ current = err?.cause;
20
+ }
21
+ return false;
22
+ }
23
+ const schemaType = () => z.union([
24
+ z.union([enumOption, stringOption]),
25
+ numberOption,
26
+ integerOption,
27
+ booleanOption,
28
+ arrayOption,
29
+ objectOption,
30
+ customType,
31
+ ]);
32
+ const deprecationFields = {
33
+ deprecationMessage: z.string().optional(),
34
+ markdownDeprecationMessage: z.string().optional(),
35
+ };
36
+ const stringOption = z.object({
37
+ order: z.number().int().nonnegative().optional(),
38
+ type: z.literal("string"),
39
+ default: z.string().optional(),
40
+ title: z.string().optional(),
41
+ format: z.string().optional(),
42
+ editPresentation: z.literal("multilineText").optional(),
43
+ optionsSource: z.string().optional(),
44
+ allowUnknownOptions: z.boolean().optional(),
45
+ optionsSourceParams: z.record(z.string(), z.unknown()).optional(),
46
+ description: z.string().optional(),
47
+ markdownDescription: z.string().optional(),
48
+ ...deprecationFields,
49
+ });
50
+ const numberOption = z.object({
51
+ order: z.number().int().nonnegative().optional(),
52
+ type: z.literal("number"),
53
+ default: z.number().optional(),
54
+ minimum: z.number().optional(),
55
+ maximum: z.number().optional(),
56
+ step: z.number().optional().default(1),
57
+ title: z.string().optional(),
58
+ description: z.string().optional(),
59
+ markdownDescription: z.string().optional(),
60
+ ...deprecationFields,
61
+ });
62
+ const integerOption = z.object({
63
+ order: z.number().int().nonnegative().optional(),
64
+ type: z.literal("integer"),
65
+ default: z.number().int().optional(),
66
+ minimum: z.number().optional(),
67
+ maximum: z.number().optional(),
68
+ step: z.number().optional().default(1),
69
+ title: z.string().optional(),
70
+ description: z.string().optional(),
71
+ markdownDescription: z.string().optional(),
72
+ ...deprecationFields,
73
+ });
74
+ const booleanOption = z.object({
75
+ order: z.number().int().nonnegative().optional(),
76
+ type: z.literal("boolean"),
77
+ default: z.boolean().default(false).optional(),
78
+ title: z.string().optional(),
79
+ description: z.string().optional(),
80
+ markdownDescription: z.string().optional(),
81
+ ...deprecationFields,
82
+ });
83
+ const enumOption = z
84
+ .object({
85
+ order: z.number().int().nonnegative().optional(),
86
+ type: z.literal("string"),
87
+ enum: z.array(z.string()),
88
+ enumDescriptions: z.array(z.string()).optional(),
89
+ enumMarkdownDescriptions: z.array(z.string()).optional(),
90
+ enumItemLabels: z.array(z.string()).optional(),
91
+ default: z.string().optional(),
92
+ title: z.string().optional(),
93
+ optionsSource: z.string().optional(),
94
+ allowUnknownOptions: z.boolean().optional(),
95
+ optionsSourceParams: z.record(z.string(), z.unknown()).optional(),
96
+ description: z.string().optional(),
97
+ markdownDescription: z.string().optional(),
98
+ ...deprecationFields,
99
+ })
100
+ .superRefine((data, ctx) => {
101
+ if (data.enumDescriptions &&
102
+ data.enum.length !== data.enumDescriptions.length) {
103
+ ctx.addIssue({
104
+ code: z.ZodIssueCode.custom,
105
+ message: `enumDescriptions(${data.enumDescriptions.length}) must be same length as enums(${data.enum.length})`,
106
+ path: [...ctx.path, "enumDescriptions"],
107
+ });
108
+ }
109
+ if (data.enumMarkdownDescriptions &&
110
+ data.enum.length !== data.enumMarkdownDescriptions.length) {
111
+ ctx.addIssue({
112
+ code: z.ZodIssueCode.custom,
113
+ message: `enumMarkdownDescriptions(${data.enumMarkdownDescriptions.length}) must be same length as enums(${data.enum.length})`,
114
+ path: [...ctx.path, "enumMarkdownDescriptions"],
115
+ });
116
+ }
117
+ if (data.enumItemLabels &&
118
+ data.enum.length !== data.enumItemLabels.length) {
119
+ ctx.addIssue({
120
+ code: z.ZodIssueCode.custom,
121
+ message: `enumItemLabels(${data.enumItemLabels.length}) must be same length as enums(${data.enum.length})`,
122
+ path: [...ctx.path, "enumItemLabels"],
123
+ });
124
+ }
125
+ data.default = data.enum[0];
126
+ });
127
+ const arrayOption = z.object({
128
+ order: z.number().int().nonnegative().optional(),
129
+ type: z.literal("array"),
130
+ items: z.lazy(() => schemaType()),
131
+ minItems: z.number().int().nonnegative().optional(),
132
+ maxItems: z.number().int().nonnegative().optional(),
133
+ default: z.array(z.any()).optional(),
134
+ title: z.string().optional(),
135
+ description: z.string().optional(),
136
+ markdownDescription: z.string().optional(),
137
+ ...deprecationFields,
138
+ });
139
+ const objectOption = z.object({
140
+ order: z.number().int().nonnegative().optional(),
141
+ type: z.literal("object"),
142
+ title: z.string().optional(),
143
+ description: z.string().optional(),
144
+ markdownDescription: z.string().optional(),
145
+ properties: z.record(z.string(), z.lazy(schemaType)).default({}),
146
+ additionalProperties: z
147
+ .union([z.boolean(), z.lazy(() => schemaType())])
148
+ .optional(),
149
+ default: z.record(z.string(), z.any()).optional(),
150
+ ...deprecationFields,
151
+ });
152
+ const customType = z.object({
153
+ type: z.literal("custom"),
154
+ order: z.number().int().nonnegative().optional(),
155
+ component: z.instanceof(SettingTab),
156
+ title: z.string().optional(),
157
+ description: z.string().optional(),
158
+ markdownDescription: z.string().optional(),
159
+ });
160
+ export function isFlatPrimitiveObjectSchema(schema) {
161
+ const props = Object.values(schema.properties);
162
+ if (props.length === 0) {
163
+ return false;
164
+ }
165
+ return props.every((property) => property.type === "boolean" ||
166
+ property.type === "number" ||
167
+ property.type === "integer" ||
168
+ (property.type === "string" && !("enum" in property)));
169
+ }
170
+ export function isRecordObjectSchema(schema) {
171
+ return (typeof schema.additionalProperties === "object" &&
172
+ schema.additionalProperties !== null);
173
+ }
174
+ export function isPrimitiveArraySchema(schema) {
175
+ const items = schema.items;
176
+ if (items.type === "boolean" ||
177
+ items.type === "number" ||
178
+ items.type === "integer") {
179
+ return true;
180
+ }
181
+ return items.type === "string" && !("enum" in items);
182
+ }
183
+ const TABLE_CELL_STRING_FORMATS = new Set(["email", "uri", "ipv4"]);
184
+ export function isTableCellSchema(schema) {
185
+ if (schema.type === "boolean" ||
186
+ schema.type === "number" ||
187
+ schema.type === "integer") {
188
+ return true;
189
+ }
190
+ if (schema.type !== "string") {
191
+ return false;
192
+ }
193
+ if ("editPresentation" in schema &&
194
+ schema.editPresentation === "multilineText") {
195
+ return false;
196
+ }
197
+ if ("format" in schema) {
198
+ if (schema.format === "textarea") {
199
+ return false;
200
+ }
201
+ if (schema.format && !TABLE_CELL_STRING_FORMATS.has(schema.format)) {
202
+ return false;
203
+ }
204
+ }
205
+ return true;
206
+ }
207
+ export function isArrayOfFlatObjectSchema(schema) {
208
+ if (schema.type !== "array") {
209
+ return false;
210
+ }
211
+ const itemSchema = schema.items;
212
+ if (itemSchema.type !== "object") {
213
+ return false;
214
+ }
215
+ if (!itemSchema.properties) {
216
+ return false;
217
+ }
218
+ if (Object.keys(itemSchema.properties).length === 0) {
219
+ return false;
220
+ }
221
+ if (itemSchema.additionalProperties === true ||
222
+ typeof itemSchema.additionalProperties === "object") {
223
+ return false;
224
+ }
225
+ return Object.values(itemSchema.properties).every(isTableCellSchema);
226
+ }
227
+ const configurationType = z.object({
228
+ id: z.string().optional(),
229
+ $schema: z.string().url().optional(),
230
+ title: z.string(),
231
+ type: z.literal("object"),
232
+ properties: z.record(z.string(), z.lazy(schemaType)),
233
+ });
234
+ export const configType = z.lazy(schemaType);
235
+ export const contributesType = z.union([
236
+ configurationType,
237
+ z.array(configurationType),
238
+ ]);
239
+ function humanizeConfigKey(key) {
240
+ const value = key.split(".").pop() ?? key;
241
+ return value
242
+ .replace(/[-_]+/g, " ")
243
+ .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
244
+ .replace(/^./, (char) => char.toUpperCase());
245
+ }
246
+ function joinConfigId(baseId, key) {
247
+ if (!baseId) {
248
+ return key;
249
+ }
250
+ if (key === baseId || key.startsWith(`${baseId}.`)) {
251
+ return key;
252
+ }
253
+ return `${baseId}.${key}`;
254
+ }
255
+ function resolveSchemaDefault(schema) {
256
+ if (schema.type === "object") {
257
+ if (schema.default !== undefined) {
258
+ return cloneDeep(schema.default);
259
+ }
260
+ const value = Object.entries(schema.properties).reduce((acc, [key, child]) => {
261
+ const childDefault = resolveSchemaDefault(child);
262
+ if (childDefault !== undefined) {
263
+ acc[key] = childDefault;
264
+ }
265
+ return acc;
266
+ }, {});
267
+ return Object.keys(value).length > 0 ? value : undefined;
268
+ }
269
+ if (schema.type === "string" && "enum" in schema) {
270
+ return cloneDeep(schema.default ?? schema.enum[0]);
271
+ }
272
+ return "default" in schema ? cloneDeep(schema.default) : undefined;
273
+ }
274
+ function validateConfigurationValue(schema, value, key) {
275
+ switch (schema.type) {
276
+ case "string": {
277
+ if (typeof value !== "string") {
278
+ throw new Error(`${key} must be a string.`);
279
+ }
280
+ if ("enum" in schema && !schema.enum.includes(value)) {
281
+ throw new Error(`${key} must be one of: ${schema.enum.join(", ")}. Received ${JSON.stringify(value)}.`);
282
+ }
283
+ return value;
284
+ }
285
+ case "number":
286
+ case "integer": {
287
+ const parsed = typeof value === "number"
288
+ ? value
289
+ : typeof value === "string" && value.trim().length > 0
290
+ ? Number(value)
291
+ : Number.NaN;
292
+ if (!Number.isFinite(parsed)) {
293
+ throw new Error(`${key} must be a ${schema.type}.`);
294
+ }
295
+ if (schema.type === "integer" && !Number.isInteger(parsed)) {
296
+ throw new Error(`${key} must be an integer.`);
297
+ }
298
+ if (schema.minimum !== undefined && parsed < schema.minimum) {
299
+ throw new Error(`${key} must be at least ${schema.minimum}.`);
300
+ }
301
+ if (schema.maximum !== undefined && parsed > schema.maximum) {
302
+ throw new Error(`${key} must be at most ${schema.maximum}.`);
303
+ }
304
+ return parsed;
305
+ }
306
+ case "boolean": {
307
+ if (typeof value !== "boolean") {
308
+ throw new Error(`${key} must be true or false.`);
309
+ }
310
+ return value;
311
+ }
312
+ case "array": {
313
+ if (!Array.isArray(value)) {
314
+ throw new Error(`${key} must be an array.`);
315
+ }
316
+ if (schema.minItems !== undefined && value.length < schema.minItems) {
317
+ throw new Error(`${key} must include at least ${schema.minItems} item${schema.minItems === 1 ? "" : "s"}.`);
318
+ }
319
+ if (schema.maxItems !== undefined && value.length > schema.maxItems) {
320
+ throw new Error(`${key} must include at most ${schema.maxItems} item${schema.maxItems === 1 ? "" : "s"}.`);
321
+ }
322
+ return value.map((item, index) => validateConfigurationValue(schema.items, item, `${key}[${index}]`));
323
+ }
324
+ case "object": {
325
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
326
+ throw new Error(`${key} must be an object.`);
327
+ }
328
+ const record = value;
329
+ const result = Object.entries(schema.properties).reduce((acc, [childKey, childSchema]) => {
330
+ if (!(childKey in record)) {
331
+ const childDefault = resolveSchemaDefault(childSchema);
332
+ if (childDefault !== undefined) {
333
+ acc[childKey] = childDefault;
334
+ }
335
+ return acc;
336
+ }
337
+ acc[childKey] = validateConfigurationValue(childSchema, record[childKey], `${key}.${childKey}`);
338
+ return acc;
339
+ }, {});
340
+ for (const [childKey, childValue] of Object.entries(record)) {
341
+ if (childKey in schema.properties) {
342
+ continue;
343
+ }
344
+ if (schema.additionalProperties === false) {
345
+ throw new Error(`${key}.${childKey} is not a supported property.`);
346
+ }
347
+ if (typeof schema.additionalProperties === "object") {
348
+ result[childKey] = validateConfigurationValue(schema.additionalProperties, childValue, `${key}.${childKey}`);
349
+ continue;
350
+ }
351
+ if (schema.additionalProperties === true) {
352
+ result[childKey] = childValue;
353
+ }
354
+ }
355
+ return result;
356
+ }
357
+ case "custom":
358
+ return value;
359
+ }
360
+ }
361
+ function getKey(config, key) {
362
+ if (key) {
363
+ if (typeof config === "object") {
364
+ const keys = Object.keys(config).filter((k) => k === key || k.startsWith(`${key}.`));
365
+ if (!keys.length) {
366
+ return undefined;
367
+ }
368
+ if (keys.length === 1 && keys[0] === key) {
369
+ return config[keys[0]];
370
+ }
371
+ return keys.reduce((acc, k) => {
372
+ const subKey = k.startsWith(`${key}.`)
373
+ ? k.substring(`${key}.`.length)
374
+ : k;
375
+ acc[subKey] = config[k];
376
+ return acc;
377
+ }, {});
378
+ }
379
+ }
380
+ }
381
+ function lookUp(tree, key) {
382
+ if (key) {
383
+ const parts = key.split(".");
384
+ let node = tree;
385
+ for (let i = 0; node !== undefined && i < parts.length; i++) {
386
+ node = getKey(node, parts[i]);
387
+ }
388
+ return node;
389
+ }
390
+ }
391
+ function findValue(key, values) {
392
+ let parts = key.split(".");
393
+ const keys = [];
394
+ for (let i = 1; i <= parts.length; i++) {
395
+ keys.push(parts.slice(0, i));
396
+ }
397
+ const sectionId = keys
398
+ .reverse()
399
+ .map((it) => it.join("."))
400
+ .filter((it) => it)
401
+ .find((it) => lookUp(values, it));
402
+ if (!sectionId) {
403
+ throw new Error(`Invalid key for configuration: ${key}`);
404
+ }
405
+ const id = key.replace(`${sectionId}.`, "");
406
+ if (sectionId === key) {
407
+ return [sectionId, "", sectionId];
408
+ }
409
+ parts = id.split(".");
410
+ const [setterId, ...prefix] = [parts.pop(), ...parts];
411
+ return [sectionId, prefix.join("."), setterId];
412
+ }
413
+ function flattenConfigurationProperties(properties, options) {
414
+ const flattened = [];
415
+ for (const [key, value] of Object.entries(properties)) {
416
+ const configId = joinConfigId(options.baseId, key);
417
+ if (value.type === "object") {
418
+ if (isFlatPrimitiveObjectSchema(value) || isRecordObjectSchema(value)) {
419
+ flattened.push({
420
+ ...value,
421
+ configId,
422
+ category: options.category,
423
+ categoryId: options.categoryId ?? configId.split(".")[0] ?? configId,
424
+ groupPath: options.groupPath ? [...options.groupPath] : undefined,
425
+ });
426
+ continue;
427
+ }
428
+ flattened.push(...flattenConfigurationProperties(value.properties, {
429
+ ...options,
430
+ baseId: configId,
431
+ groupPath: [
432
+ ...(options.groupPath ?? []),
433
+ {
434
+ id: configId,
435
+ title: value.title ?? humanizeConfigKey(key),
436
+ description: value.description,
437
+ markdownDescription: value.markdownDescription,
438
+ },
439
+ ],
440
+ }));
441
+ continue;
442
+ }
443
+ flattened.push({
444
+ ...value,
445
+ configId,
446
+ category: options.category,
447
+ categoryId: options.categoryId ?? configId.split(".")[0] ?? configId,
448
+ groupPath: options.groupPath ? [...options.groupPath] : undefined,
449
+ });
450
+ }
451
+ return flattened;
452
+ }
453
+ export class ConfigurationSchema extends EventDispatcher {
454
+ values = $state({});
455
+ constructor() {
456
+ super();
457
+ }
458
+ getConfiguration(section) {
459
+ const config = section ? lookUp(this.values, section) : this.values;
460
+ const self = this;
461
+ const result = {
462
+ has(key) {
463
+ return lookUp(config, key) !== undefined;
464
+ },
465
+ get(key, defaultValue) {
466
+ let result = lookUp(config, key);
467
+ if (typeof result === "undefined") {
468
+ result = defaultValue;
469
+ }
470
+ return result;
471
+ },
472
+ update: (key, value) => {
473
+ key = section ? `${section}.${key}` : key;
474
+ if (value !== undefined) {
475
+ return self.updateConfigurationOption(key, value);
476
+ }
477
+ else {
478
+ return self.removeConfigurationOption(key);
479
+ }
480
+ },
481
+ entries() {
482
+ return Object.entries(config || {});
483
+ },
484
+ values() {
485
+ return Object.values(config || {});
486
+ },
487
+ keys: () => {
488
+ return Object.keys(config || {});
489
+ },
490
+ };
491
+ return Object.freeze(result);
492
+ }
493
+ getDefinition(key) {
494
+ return lookUp(this.values, key);
495
+ }
496
+ validateConfigurationOption(key, value) {
497
+ const schema = this.getDefinition(key);
498
+ if (!schema) {
499
+ return value;
500
+ }
501
+ return validateConfigurationValue(schema, value, key);
502
+ }
503
+ getDefaultEntries() {
504
+ return Object.entries(this.values).flatMap(([key, schema]) => {
505
+ const defaultValue = resolveSchemaDefault(schema);
506
+ return defaultValue === undefined ? [] : [[key, defaultValue]];
507
+ });
508
+ }
509
+ register(...schemas) {
510
+ for (const schema of schemas) {
511
+ const parsedSchema = contributesType.parse(schema);
512
+ const schemaData = Array.isArray(parsedSchema)
513
+ ? parsedSchema
514
+ : [parsedSchema];
515
+ for (const data of schemaData) {
516
+ for (const value of flattenConfigurationProperties(data.properties, {
517
+ baseId: data.id,
518
+ category: data.title,
519
+ categoryId: data.id,
520
+ })) {
521
+ const existing = lookUp(this.values, value.configId);
522
+ if (existing === undefined) {
523
+ this.values[value.configId] = value;
524
+ }
525
+ else {
526
+ console.warn(`Duplicate property: ${value.configId} already defined as: `, {
527
+ existing,
528
+ duplicate: value,
529
+ });
530
+ }
531
+ }
532
+ }
533
+ }
534
+ }
535
+ unregister(...schemas) {
536
+ for (const schema of schemas) {
537
+ const parsedSchema = contributesType.parse(schema);
538
+ const schemaData = Array.isArray(parsedSchema)
539
+ ? parsedSchema
540
+ : [parsedSchema];
541
+ for (const data of schemaData) {
542
+ for (const value of flattenConfigurationProperties(data.properties, {
543
+ baseId: data.id,
544
+ category: data.title,
545
+ categoryId: data.id,
546
+ })) {
547
+ delete this.values[value.configId];
548
+ }
549
+ }
550
+ }
551
+ }
552
+ removeWebView(id) {
553
+ const deleted = Object.keys(this.values)
554
+ .filter((k) => {
555
+ const property = this.values[k];
556
+ return property.type === "custom" && property.configId === id;
557
+ })
558
+ .reduce((obj, key) => {
559
+ obj[key] = this.values[key];
560
+ return obj;
561
+ }, {});
562
+ const keys = Object.keys(deleted);
563
+ if (keys.length) {
564
+ keys.forEach((k) => delete this.values[k]);
565
+ this.emit("updated", { key: id, value: deleted });
566
+ }
567
+ }
568
+ registerWebView(id, title, component) {
569
+ const existing = this.values[id];
570
+ if (existing) {
571
+ console.warn(`Duplicate property: ${id} already defined as: `, {
572
+ existing,
573
+ });
574
+ return;
575
+ }
576
+ const value = {
577
+ type: "custom",
578
+ title,
579
+ component,
580
+ };
581
+ this.values[id] = {
582
+ ...value,
583
+ configId: id,
584
+ category: title,
585
+ categoryId: "extensions",
586
+ };
587
+ this.emit("updated", { key: id, value, prev: undefined });
588
+ }
589
+ async updateConfigurationOption(key, value) {
590
+ const [sectionId, prefix, id] = findValue(key, this.values);
591
+ const data = cloneDeep({ ...this.values[sectionId] });
592
+ const parent = prefix.length ? lookUp(data, prefix) : data;
593
+ const prev = parent[id];
594
+ parent[id] = validateConfigurationValue(data, value, key);
595
+ const config = configType.parse(data);
596
+ this.values[sectionId] = {
597
+ ...config,
598
+ configId: data.configId,
599
+ category: data.category,
600
+ categoryId: data.categoryId,
601
+ groupPath: data.groupPath,
602
+ };
603
+ this.emit("updated", { key, value: parent[id], prev });
604
+ }
605
+ async removeConfigurationOption(key) {
606
+ const [sectionId, prefix, id] = findValue(key, this.values);
607
+ const data = cloneDeep({ ...this.values[sectionId] });
608
+ const parent = prefix.length ? lookUp(data, prefix) : data;
609
+ const prev = parent[id];
610
+ if (prev !== undefined) {
611
+ delete parent[id];
612
+ const config = configType.parse(data);
613
+ this.values[sectionId] = {
614
+ ...config,
615
+ configId: data.configId,
616
+ category: data.category,
617
+ categoryId: data.categoryId,
618
+ groupPath: data.groupPath,
619
+ };
620
+ this.emit("updated", { key, prev, value: undefined });
621
+ }
622
+ }
623
+ }
624
+ export class Configuration extends EventDispatcher {
625
+ app;
626
+ basePath;
627
+ values = $state({});
628
+ loaded = false;
629
+ schema = new ConfigurationSchema();
630
+ constructor(app, basePath) {
631
+ super();
632
+ this.app = app;
633
+ this.basePath = basePath;
634
+ this.watchExternalConfigChanges();
635
+ }
636
+ async load() {
637
+ await this.reloadFromDisk({ emitPluginDataEvents: false });
638
+ }
639
+ hasPluginData(pluginId) {
640
+ return Object.hasOwn(this.getPluginDataStore(this.values), pluginId);
641
+ }
642
+ getPluginData(pluginId) {
643
+ const pluginData = this.getPluginDataStore(this.values);
644
+ if (!Object.hasOwn(pluginData, pluginId)) {
645
+ return null;
646
+ }
647
+ return cloneDeep(pluginData[pluginId]);
648
+ }
649
+ async updatePluginData(pluginId, value, options = {}) {
650
+ const prev = this.getPluginData(pluginId);
651
+ const pluginData = this.getPluginDataStore(this.values);
652
+ const nextPluginData = {
653
+ ...pluginData,
654
+ [pluginId]: cloneDeep(value),
655
+ };
656
+ const next = { ...this.values, pluginData: nextPluginData };
657
+ await this.persist(next);
658
+ this.emit("plugin-data-updated", {
659
+ pluginId,
660
+ value: this.getPluginData(pluginId),
661
+ prev,
662
+ origin: options.origin ?? "configuration-update",
663
+ });
664
+ }
665
+ async removePluginData(pluginId, options = {}) {
666
+ const pluginData = this.getPluginDataStore(this.values);
667
+ if (!Object.hasOwn(pluginData, pluginId)) {
668
+ return;
669
+ }
670
+ const prev = cloneDeep(pluginData[pluginId]);
671
+ const nextPluginData = { ...pluginData };
672
+ delete nextPluginData[pluginId];
673
+ const next = { ...this.values };
674
+ if (Object.keys(nextPluginData).length > 0) {
675
+ next.pluginData = nextPluginData;
676
+ }
677
+ else {
678
+ delete next.pluginData;
679
+ }
680
+ await this.persist(next);
681
+ this.emit("plugin-data-updated", {
682
+ pluginId,
683
+ value: undefined,
684
+ prev,
685
+ origin: options.origin ?? "configuration-update",
686
+ });
687
+ }
688
+ async reloadFromDisk(options = {}) {
689
+ const previousValues = cloneDeep(this.values);
690
+ this.values = await this.readValuesFromDisk();
691
+ this.loaded = true;
692
+ await this.materializeSchemaDefaults();
693
+ if (options.emitPluginDataEvents !== false) {
694
+ this.emitPluginDataDiffs(previousValues, this.values, options.origin ?? "external-reload");
695
+ }
696
+ }
697
+ getConfiguration(section) {
698
+ const config = section ? lookUp(this.values, section) : this.values;
699
+ const self = this;
700
+ const result = {
701
+ has(key) {
702
+ return lookUp(config, key) !== undefined;
703
+ },
704
+ get(key, defaultValue) {
705
+ let result = lookUp(config, key);
706
+ if (typeof result === "undefined") {
707
+ if (defaultValue === undefined) {
708
+ const schemaConfig = self.schema.getConfiguration().get(key);
709
+ defaultValue = schemaConfig?.default;
710
+ }
711
+ result = defaultValue;
712
+ }
713
+ return result;
714
+ },
715
+ update: (key, value) => {
716
+ key = section ? `${section}.${key}` : key;
717
+ if (value !== undefined) {
718
+ return self.updateConfigurationOption(key, value);
719
+ }
720
+ else {
721
+ return self.removeConfigurationOption(key);
722
+ }
723
+ },
724
+ entries() {
725
+ return Object.entries(config || {});
726
+ },
727
+ values() {
728
+ return Object.values(config || {});
729
+ },
730
+ keys: () => {
731
+ return Object.keys(config || {});
732
+ },
733
+ };
734
+ return Object.freeze(result);
735
+ }
736
+ async updateConfigurationOption(key, value) {
737
+ await this.updateConfigurationOptions({ [key]: value });
738
+ }
739
+ /**
740
+ * Validate and persist a set of flat configuration keys as one update.
741
+ *
742
+ * Validation and the vault write both complete before observable state or
743
+ * update events change, so consumers never see a partially applied batch.
744
+ *
745
+ * @public
746
+ */
747
+ async updateConfigurationOptions(changes) {
748
+ const validated = Object.entries(changes).map(([key, value]) => ({
749
+ key,
750
+ value: this.schema.validateConfigurationOption(key, value),
751
+ }));
752
+ const changed = validated
753
+ .map(({ key, value }) => ({
754
+ key,
755
+ value,
756
+ prev: this.values[key],
757
+ }))
758
+ .filter(({ value, prev }) => !isEqual(value, prev));
759
+ if (changed.length === 0)
760
+ return;
761
+ const next = { ...this.values };
762
+ for (const { key, value } of changed) {
763
+ next[key] = cloneDeep(value);
764
+ }
765
+ await this.persist(next);
766
+ for (const { key, value, prev } of changed) {
767
+ this.emit("updated", {
768
+ key,
769
+ value: cloneDeep(value),
770
+ prev: cloneDeep(prev),
771
+ });
772
+ }
773
+ }
774
+ async removeConfigurationOption(key) {
775
+ const value = this.values[key];
776
+ if (value !== undefined) {
777
+ const next = { ...this.values };
778
+ delete next[key];
779
+ await this.persist(next);
780
+ this.emit("updated", { key, prev: value, value: undefined });
781
+ }
782
+ }
783
+ async persist(data) {
784
+ const file = this.app.vault.getFileByPath(this.basePath);
785
+ if (file) {
786
+ await this.app.vault.modify(file, JSON.stringify(data, null, 2));
787
+ }
788
+ else {
789
+ await this.app.vault.mkpath(dirname(this.basePath));
790
+ await this.app.vault.create(this.basePath, JSON.stringify(data, null, 2));
791
+ }
792
+ this.values = data;
793
+ }
794
+ getPluginDataStore(values) {
795
+ const pluginData = values.pluginData;
796
+ if (typeof pluginData === "object" &&
797
+ pluginData !== null &&
798
+ !Array.isArray(pluginData)) {
799
+ return pluginData;
800
+ }
801
+ return {};
802
+ }
803
+ async readValuesFromDisk() {
804
+ const file = this.app.vault.getFileByPath(this.basePath);
805
+ if (!file) {
806
+ return {};
807
+ }
808
+ try {
809
+ const contents = await this.app.vault.read(file);
810
+ const data = JSON.parse(contents);
811
+ if (typeof data === "object" && data !== null && !Array.isArray(data)) {
812
+ return data;
813
+ }
814
+ }
815
+ catch (error) {
816
+ if (isRecoverableConfigurationReadError(error)) {
817
+ return cloneDeep(this.values);
818
+ }
819
+ console.error(`Error loading configuration: ${this.basePath}`, error);
820
+ }
821
+ return {};
822
+ }
823
+ emitPluginDataDiffs(previousValues, nextValues, origin) {
824
+ const previousPluginData = this.getPluginDataStore(previousValues);
825
+ const nextPluginData = this.getPluginDataStore(nextValues);
826
+ const pluginIds = new Set([
827
+ ...Object.keys(previousPluginData),
828
+ ...Object.keys(nextPluginData),
829
+ ]);
830
+ for (const pluginId of pluginIds) {
831
+ const prev = previousPluginData[pluginId];
832
+ const value = nextPluginData[pluginId];
833
+ if (isEqual(prev, value)) {
834
+ continue;
835
+ }
836
+ this.emit("plugin-data-updated", {
837
+ pluginId,
838
+ value: cloneDeep(value),
839
+ prev: cloneDeep(prev),
840
+ origin,
841
+ });
842
+ }
843
+ }
844
+ watchExternalConfigChanges() {
845
+ this.app.workspace?.on?.("file-change", async (file, event) => {
846
+ if (file.path !== this.basePath || event === "delete") {
847
+ return;
848
+ }
849
+ await this.reloadFromDisk({
850
+ emitPluginDataEvents: true,
851
+ origin: "external-reload",
852
+ });
853
+ });
854
+ }
855
+ async materializeSchemaDefaults() {
856
+ if (!this.loaded) {
857
+ return;
858
+ }
859
+ const next = { ...this.values };
860
+ let changed = false;
861
+ for (const [key, defaultValue] of this.schema.getDefaultEntries()) {
862
+ if (!(key in next) || next[key] === undefined) {
863
+ next[key] = cloneDeep(defaultValue);
864
+ changed = true;
865
+ continue;
866
+ }
867
+ try {
868
+ const validated = this.schema.validateConfigurationOption(key, next[key]);
869
+ if (!isEqual(validated, next[key])) {
870
+ next[key] = validated;
871
+ changed = true;
872
+ }
873
+ }
874
+ catch (error) {
875
+ console.warn(`Invalid configuration value for ${key}; restoring default.`, error);
876
+ next[key] = cloneDeep(defaultValue);
877
+ changed = true;
878
+ }
879
+ }
880
+ if (changed) {
881
+ await this.persist(next);
882
+ }
883
+ else {
884
+ this.values = next;
885
+ }
886
+ }
887
+ }