nebula-cms 0.1.3 → 0.1.4

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 (380) hide show
  1. package/README.md +2 -0
  2. package/dist/astro/index.d.ts +43 -0
  3. package/dist/astro/index.d.ts.map +1 -0
  4. package/dist/astro/index.js +223 -0
  5. package/dist/client/Admin.svelte.d.ts +11 -0
  6. package/dist/client/Admin.svelte.d.ts.map +1 -0
  7. package/dist/client/components/BackendPicker.svelte.d.ts +4 -0
  8. package/dist/client/components/BackendPicker.svelte.d.ts.map +1 -0
  9. package/dist/client/components/DraftChip.svelte.d.ts +10 -0
  10. package/dist/client/components/DraftChip.svelte.d.ts.map +1 -0
  11. package/dist/client/components/MetadataForm.svelte.d.ts +12 -0
  12. package/dist/client/components/MetadataForm.svelte.d.ts.map +1 -0
  13. package/dist/client/components/ThemeToggle.svelte.d.ts +19 -0
  14. package/dist/client/components/ThemeToggle.svelte.d.ts.map +1 -0
  15. package/dist/client/components/dialogs/DeleteDraftDialog.svelte.d.ts +11 -0
  16. package/dist/client/components/dialogs/DeleteDraftDialog.svelte.d.ts.map +1 -0
  17. package/dist/client/components/dialogs/FilenameDialog.svelte.d.ts +13 -0
  18. package/dist/client/components/dialogs/FilenameDialog.svelte.d.ts.map +1 -0
  19. package/dist/client/components/editor/EditorPane.svelte.d.ts +4 -0
  20. package/dist/client/components/editor/EditorPane.svelte.d.ts.map +1 -0
  21. package/dist/client/components/editor/EditorTabs.svelte.d.ts +8 -0
  22. package/dist/client/components/editor/EditorTabs.svelte.d.ts.map +1 -0
  23. package/dist/client/components/editor/EditorToolbar.svelte.d.ts +4 -0
  24. package/dist/client/components/editor/EditorToolbar.svelte.d.ts.map +1 -0
  25. package/dist/client/components/editor/FormatSelector.svelte.d.ts +4 -0
  26. package/dist/client/components/editor/FormatSelector.svelte.d.ts.map +1 -0
  27. package/dist/client/components/editor/Toolbar.svelte.d.ts +19 -0
  28. package/dist/client/components/editor/Toolbar.svelte.d.ts.map +1 -0
  29. package/dist/client/components/fields/ArrayField.svelte.d.ts +15 -0
  30. package/dist/client/components/fields/ArrayField.svelte.d.ts.map +1 -0
  31. package/dist/client/components/fields/ArrayItem.svelte.d.ts +28 -0
  32. package/dist/client/components/fields/ArrayItem.svelte.d.ts.map +1 -0
  33. package/dist/client/components/fields/BooleanField.svelte.d.ts +16 -0
  34. package/dist/client/components/fields/BooleanField.svelte.d.ts.map +1 -0
  35. package/dist/client/components/fields/DateField.svelte.d.ts +16 -0
  36. package/dist/client/components/fields/DateField.svelte.d.ts.map +1 -0
  37. package/dist/client/components/fields/EnumField.svelte.d.ts +17 -0
  38. package/dist/client/components/fields/EnumField.svelte.d.ts.map +1 -0
  39. package/dist/client/components/fields/FieldWrapper.svelte.d.ts +18 -0
  40. package/dist/client/components/fields/FieldWrapper.svelte.d.ts.map +1 -0
  41. package/dist/client/components/fields/NumberField.svelte.d.ts +16 -0
  42. package/dist/client/components/fields/NumberField.svelte.d.ts.map +1 -0
  43. package/dist/client/components/fields/ObjectField.svelte.d.ts +16 -0
  44. package/dist/client/components/fields/ObjectField.svelte.d.ts.map +1 -0
  45. package/dist/client/components/fields/SchemaField.svelte.d.ts +16 -0
  46. package/dist/client/components/fields/SchemaField.svelte.d.ts.map +1 -0
  47. package/dist/client/components/fields/StringField.svelte.d.ts +16 -0
  48. package/dist/client/components/fields/StringField.svelte.d.ts.map +1 -0
  49. package/dist/client/components/sidebar/AdminSidebar.svelte.d.ts +19 -0
  50. package/dist/client/components/sidebar/AdminSidebar.svelte.d.ts.map +1 -0
  51. package/dist/client/components/sidebar/AdminSidebarSort.svelte.d.ts +12 -0
  52. package/dist/client/components/sidebar/AdminSidebarSort.svelte.d.ts.map +1 -0
  53. package/dist/client/css/icons.css +29 -0
  54. package/dist/client/index.d.ts +2 -0
  55. package/dist/client/index.d.ts.map +1 -0
  56. package/dist/client/js/drafts/merge.svelte.d.ts +24 -0
  57. package/dist/client/js/drafts/merge.svelte.d.ts.map +1 -0
  58. package/dist/client/js/drafts/merge.svelte.js +106 -0
  59. package/dist/client/js/drafts/ops.svelte.d.ts +31 -0
  60. package/dist/client/js/drafts/ops.svelte.d.ts.map +1 -0
  61. package/dist/client/js/drafts/ops.svelte.js +182 -0
  62. package/dist/client/js/drafts/storage.d.ts +45 -0
  63. package/dist/client/js/drafts/storage.d.ts.map +1 -0
  64. package/dist/client/js/drafts/storage.js +76 -0
  65. package/dist/client/js/drafts/workers/diff.d.ts +2 -0
  66. package/dist/client/js/drafts/workers/diff.d.ts.map +1 -0
  67. package/dist/client/js/drafts/workers/diff.js +20 -0
  68. package/dist/client/js/editor/editor.svelte.d.ts +124 -0
  69. package/dist/client/js/editor/editor.svelte.d.ts.map +1 -0
  70. package/dist/client/js/editor/editor.svelte.js +294 -0
  71. package/dist/client/js/editor/languages.d.ts +11 -0
  72. package/dist/client/js/editor/languages.d.ts.map +1 -0
  73. package/dist/client/js/editor/languages.js +93 -0
  74. package/dist/client/js/editor/link-wrap.d.ts +6 -0
  75. package/dist/client/js/editor/link-wrap.d.ts.map +1 -0
  76. package/{src/client/js/editor/link-wrap.ts → dist/client/js/editor/link-wrap.js} +17 -24
  77. package/dist/client/js/editor/markdown-shortcuts.d.ts +4 -0
  78. package/dist/client/js/editor/markdown-shortcuts.d.ts.map +1 -0
  79. package/dist/client/js/editor/markdown-shortcuts.js +219 -0
  80. package/dist/client/js/handlers/admin.d.ts +64 -0
  81. package/dist/client/js/handlers/admin.d.ts.map +1 -0
  82. package/dist/client/js/handlers/admin.js +186 -0
  83. package/dist/client/js/state/dialogs.svelte.d.ts +16 -0
  84. package/dist/client/js/state/dialogs.svelte.d.ts.map +1 -0
  85. package/dist/client/js/state/dialogs.svelte.js +28 -0
  86. package/dist/client/js/state/router.svelte.d.ts +44 -0
  87. package/dist/client/js/state/router.svelte.d.ts.map +1 -0
  88. package/dist/client/js/state/router.svelte.js +135 -0
  89. package/dist/client/js/state/schema.svelte.d.ts +51 -0
  90. package/dist/client/js/state/schema.svelte.d.ts.map +1 -0
  91. package/{src/client/js/state/schema.svelte.ts → dist/client/js/state/schema.svelte.js} +55 -70
  92. package/dist/client/js/state/state.svelte.d.ts +68 -0
  93. package/dist/client/js/state/state.svelte.d.ts.map +1 -0
  94. package/dist/client/js/state/state.svelte.js +291 -0
  95. package/dist/client/js/state/theme.svelte.d.ts +24 -0
  96. package/dist/client/js/state/theme.svelte.d.ts.map +1 -0
  97. package/{src/client/js/state/theme.svelte.ts → dist/client/js/state/theme.svelte.js} +54 -91
  98. package/dist/client/js/storage/adapter.d.ts +130 -0
  99. package/dist/client/js/storage/adapter.d.ts.map +1 -0
  100. package/dist/client/js/storage/adapter.js +5 -0
  101. package/dist/client/js/storage/client.d.ts +72 -0
  102. package/dist/client/js/storage/client.d.ts.map +1 -0
  103. package/dist/client/js/storage/client.js +121 -0
  104. package/dist/client/js/storage/db.d.ts +8 -0
  105. package/dist/client/js/storage/db.d.ts.map +1 -0
  106. package/dist/client/js/storage/db.js +35 -0
  107. package/dist/client/js/storage/fsa.d.ts +51 -0
  108. package/dist/client/js/storage/fsa.d.ts.map +1 -0
  109. package/dist/client/js/storage/fsa.js +91 -0
  110. package/dist/client/js/storage/github.d.ts +62 -0
  111. package/dist/client/js/storage/github.d.ts.map +1 -0
  112. package/dist/client/js/storage/github.js +216 -0
  113. package/dist/client/js/storage/storage.d.ts +32 -0
  114. package/dist/client/js/storage/storage.d.ts.map +1 -0
  115. package/dist/client/js/storage/storage.js +68 -0
  116. package/dist/client/js/storage/workers/frontmatter.d.ts +2 -0
  117. package/dist/client/js/storage/workers/frontmatter.d.ts.map +1 -0
  118. package/dist/client/js/storage/workers/frontmatter.js +253 -0
  119. package/dist/client/js/storage/workers/storage.d.ts +2 -0
  120. package/dist/client/js/storage/workers/storage.d.ts.map +1 -0
  121. package/dist/client/js/storage/workers/storage.js +167 -0
  122. package/dist/client/js/storage/workers/toml-parser.d.ts +2 -0
  123. package/dist/client/js/storage/workers/toml-parser.d.ts.map +1 -0
  124. package/dist/client/js/storage/workers/toml-parser.js +75 -0
  125. package/dist/client/js/storage/workers/yaml-parser.d.ts +2 -0
  126. package/dist/client/js/storage/workers/yaml-parser.d.ts.map +1 -0
  127. package/dist/client/js/storage/workers/yaml-parser.js +100 -0
  128. package/dist/client/js/utils/file-types.d.ts +58 -0
  129. package/dist/client/js/utils/file-types.d.ts.map +1 -0
  130. package/{src/client/js/utils/file-types.ts → dist/client/js/utils/file-types.js} +75 -107
  131. package/dist/client/js/utils/format.d.ts +8 -0
  132. package/dist/client/js/utils/format.d.ts.map +1 -0
  133. package/{src/client/js/utils/format.ts → dist/client/js/utils/format.js} +5 -6
  134. package/dist/client/js/utils/frontmatter.d.ts +12 -0
  135. package/dist/client/js/utils/frontmatter.d.ts.map +1 -0
  136. package/dist/client/js/utils/frontmatter.js +29 -0
  137. package/dist/client/js/utils/schema-utils.d.ts +110 -0
  138. package/dist/client/js/utils/schema-utils.d.ts.map +1 -0
  139. package/dist/client/js/utils/schema-utils.js +242 -0
  140. package/dist/client/js/utils/slug.d.ts +8 -0
  141. package/dist/client/js/utils/slug.d.ts.map +1 -0
  142. package/{src/client/js/utils/slug.ts → dist/client/js/utils/slug.js} +6 -7
  143. package/dist/client/js/utils/sort.d.ts +41 -0
  144. package/dist/client/js/utils/sort.d.ts.map +1 -0
  145. package/dist/client/js/utils/sort.js +65 -0
  146. package/dist/client/js/utils/stable-stringify.d.ts +8 -0
  147. package/dist/client/js/utils/stable-stringify.d.ts.map +1 -0
  148. package/dist/client/js/utils/stable-stringify.js +23 -0
  149. package/dist/client/js/utils/url-utils.d.ts +11 -0
  150. package/dist/client/js/utils/url-utils.d.ts.map +1 -0
  151. package/{src/client/js/utils/url-utils.ts → dist/client/js/utils/url-utils.js} +22 -23
  152. package/dist/types.d.ts +22 -0
  153. package/dist/types.d.ts.map +1 -0
  154. package/dist/types.js +1 -0
  155. package/package.json +4 -1
  156. package/.github/workflows/ci.yml +0 -27
  157. package/.github/workflows/publish.yml +0 -34
  158. package/.mcp.json +0 -12
  159. package/.prettierignore +0 -5
  160. package/.prettierrc.cjs +0 -22
  161. package/AGENTS.md +0 -183
  162. package/playground/astro.config.mjs +0 -7
  163. package/playground/node_modules/.bin/astro +0 -21
  164. package/playground/node_modules/.vite/deps/@astrojs_svelte_client__js.js +0 -85
  165. package/playground/node_modules/.vite/deps/@astrojs_svelte_client__js.js.map +0 -7
  166. package/playground/node_modules/.vite/deps/_metadata.json +0 -184
  167. package/playground/node_modules/.vite/deps/astro___aria-query.js +0 -6776
  168. package/playground/node_modules/.vite/deps/astro___aria-query.js.map +0 -7
  169. package/playground/node_modules/.vite/deps/astro___axobject-query.js +0 -3754
  170. package/playground/node_modules/.vite/deps/astro___axobject-query.js.map +0 -7
  171. package/playground/node_modules/.vite/deps/astro___html-escaper.js +0 -34
  172. package/playground/node_modules/.vite/deps/astro___html-escaper.js.map +0 -7
  173. package/playground/node_modules/.vite/deps/chunk-AJXJMYAF.js +0 -0
  174. package/playground/node_modules/.vite/deps/chunk-AJXJMYAF.js.map +0 -7
  175. package/playground/node_modules/.vite/deps/chunk-BUSYA2B4.js +0 -8
  176. package/playground/node_modules/.vite/deps/chunk-BUSYA2B4.js.map +0 -7
  177. package/playground/node_modules/.vite/deps/chunk-CNYJBM5F.js +0 -21
  178. package/playground/node_modules/.vite/deps/chunk-CNYJBM5F.js.map +0 -7
  179. package/playground/node_modules/.vite/deps/chunk-DBPNBGEI.js +0 -223
  180. package/playground/node_modules/.vite/deps/chunk-DBPNBGEI.js.map +0 -7
  181. package/playground/node_modules/.vite/deps/chunk-FPEUJ7DG.js +0 -27
  182. package/playground/node_modules/.vite/deps/chunk-FPEUJ7DG.js.map +0 -7
  183. package/playground/node_modules/.vite/deps/chunk-MHDZ3SK7.js +0 -1005
  184. package/playground/node_modules/.vite/deps/chunk-MHDZ3SK7.js.map +0 -7
  185. package/playground/node_modules/.vite/deps/chunk-RBDTDTPY.js +0 -204
  186. package/playground/node_modules/.vite/deps/chunk-RBDTDTPY.js.map +0 -7
  187. package/playground/node_modules/.vite/deps/chunk-RJGEXL5C.js +0 -688
  188. package/playground/node_modules/.vite/deps/chunk-RJGEXL5C.js.map +0 -7
  189. package/playground/node_modules/.vite/deps/chunk-YL4MIWGJ.js +0 -5099
  190. package/playground/node_modules/.vite/deps/chunk-YL4MIWGJ.js.map +0 -7
  191. package/playground/node_modules/.vite/deps/chunk-ZOV3DWEJ.js +0 -4376
  192. package/playground/node_modules/.vite/deps/chunk-ZOV3DWEJ.js.map +0 -7
  193. package/playground/node_modules/.vite/deps/chunk-ZP4UNCSN.js +0 -23
  194. package/playground/node_modules/.vite/deps/chunk-ZP4UNCSN.js.map +0 -7
  195. package/playground/node_modules/.vite/deps/chunk-ZREFNRZZ.js +0 -148
  196. package/playground/node_modules/.vite/deps/chunk-ZREFNRZZ.js.map +0 -7
  197. package/playground/node_modules/.vite/deps/package.json +0 -3
  198. package/playground/node_modules/.vite/deps/smol-toml.js +0 -843
  199. package/playground/node_modules/.vite/deps/smol-toml.js.map +0 -7
  200. package/playground/node_modules/.vite/deps/svelte.js +0 -55
  201. package/playground/node_modules/.vite/deps/svelte.js.map +0 -7
  202. package/playground/node_modules/.vite/deps/svelte___clsx.js +0 -9
  203. package/playground/node_modules/.vite/deps/svelte___clsx.js.map +0 -7
  204. package/playground/node_modules/.vite/deps/svelte_animate.js +0 -57
  205. package/playground/node_modules/.vite/deps/svelte_animate.js.map +0 -7
  206. package/playground/node_modules/.vite/deps/svelte_attachments.js +0 -15
  207. package/playground/node_modules/.vite/deps/svelte_attachments.js.map +0 -7
  208. package/playground/node_modules/.vite/deps/svelte_easing.js +0 -67
  209. package/playground/node_modules/.vite/deps/svelte_easing.js.map +0 -7
  210. package/playground/node_modules/.vite/deps/svelte_events.js +0 -11
  211. package/playground/node_modules/.vite/deps/svelte_events.js.map +0 -7
  212. package/playground/node_modules/.vite/deps/svelte_internal.js +0 -5
  213. package/playground/node_modules/.vite/deps/svelte_internal.js.map +0 -7
  214. package/playground/node_modules/.vite/deps/svelte_internal_client.js +0 -402
  215. package/playground/node_modules/.vite/deps/svelte_internal_client.js.map +0 -7
  216. package/playground/node_modules/.vite/deps/svelte_internal_disclose-version.js +0 -10
  217. package/playground/node_modules/.vite/deps/svelte_internal_disclose-version.js.map +0 -7
  218. package/playground/node_modules/.vite/deps/svelte_internal_flags_async.js +0 -8
  219. package/playground/node_modules/.vite/deps/svelte_internal_flags_async.js.map +0 -7
  220. package/playground/node_modules/.vite/deps/svelte_internal_flags_legacy.js +0 -8
  221. package/playground/node_modules/.vite/deps/svelte_internal_flags_legacy.js.map +0 -7
  222. package/playground/node_modules/.vite/deps/svelte_internal_flags_tracing.js +0 -8
  223. package/playground/node_modules/.vite/deps/svelte_internal_flags_tracing.js.map +0 -7
  224. package/playground/node_modules/.vite/deps/svelte_legacy.js +0 -35
  225. package/playground/node_modules/.vite/deps/svelte_legacy.js.map +0 -7
  226. package/playground/node_modules/.vite/deps/svelte_motion.js +0 -545
  227. package/playground/node_modules/.vite/deps/svelte_motion.js.map +0 -7
  228. package/playground/node_modules/.vite/deps/svelte_reactivity.js +0 -29
  229. package/playground/node_modules/.vite/deps/svelte_reactivity.js.map +0 -7
  230. package/playground/node_modules/.vite/deps/svelte_reactivity_window.js +0 -127
  231. package/playground/node_modules/.vite/deps/svelte_reactivity_window.js.map +0 -7
  232. package/playground/node_modules/.vite/deps/svelte_store.js +0 -103
  233. package/playground/node_modules/.vite/deps/svelte_store.js.map +0 -7
  234. package/playground/node_modules/.vite/deps/svelte_transition.js +0 -208
  235. package/playground/node_modules/.vite/deps/svelte_transition.js.map +0 -7
  236. package/playground/package.json +0 -16
  237. package/playground/pnpm-lock.yaml +0 -3167
  238. package/playground/src/content/authors/jane-doe.json +0 -8
  239. package/playground/src/content/config/build.toml +0 -2
  240. package/playground/src/content/courses/web-fundamentals.json +0 -29
  241. package/playground/src/content/docs/advanced.mdx +0 -6
  242. package/playground/src/content/docs/intro.md +0 -6
  243. package/playground/src/content/guides/getting-started.mdx +0 -6
  244. package/playground/src/content/posts/hello-world.md +0 -7
  245. package/playground/src/content/products/t-shirt.json +0 -16
  246. package/playground/src/content/recipes/pancakes.mdoc +0 -8
  247. package/playground/src/content/settings/site.yml +0 -2
  248. package/playground/src/content.config.ts +0 -198
  249. package/playground/src/env.d.ts +0 -1
  250. package/playground/src/pages/index.astro +0 -11
  251. package/playground/src/pages/nebula.astro +0 -14
  252. package/pnpm-workspace.yaml +0 -2
  253. package/scripts/subset-icons.mjs +0 -178
  254. package/src/astro/index.ts +0 -295
  255. package/src/client/js/drafts/merge.svelte.ts +0 -121
  256. package/src/client/js/drafts/ops.svelte.ts +0 -227
  257. package/src/client/js/drafts/storage.ts +0 -108
  258. package/src/client/js/drafts/workers/diff.ts +0 -40
  259. package/src/client/js/editor/editor.svelte.ts +0 -343
  260. package/src/client/js/editor/languages.ts +0 -98
  261. package/src/client/js/editor/markdown-shortcuts.ts +0 -261
  262. package/src/client/js/handlers/admin.ts +0 -246
  263. package/src/client/js/state/dialogs.svelte.ts +0 -35
  264. package/src/client/js/state/router.svelte.ts +0 -156
  265. package/src/client/js/state/state.svelte.ts +0 -334
  266. package/src/client/js/storage/adapter.ts +0 -102
  267. package/src/client/js/storage/client.ts +0 -150
  268. package/src/client/js/storage/db.ts +0 -36
  269. package/src/client/js/storage/fsa.ts +0 -110
  270. package/src/client/js/storage/github.ts +0 -297
  271. package/src/client/js/storage/storage.ts +0 -83
  272. package/src/client/js/storage/workers/frontmatter.ts +0 -320
  273. package/src/client/js/storage/workers/storage.ts +0 -177
  274. package/src/client/js/storage/workers/toml-parser.ts +0 -106
  275. package/src/client/js/storage/workers/yaml-parser.ts +0 -132
  276. package/src/client/js/utils/frontmatter.ts +0 -38
  277. package/src/client/js/utils/schema-utils.ts +0 -295
  278. package/src/client/js/utils/sort.ts +0 -84
  279. package/src/client/js/utils/stable-stringify.ts +0 -27
  280. package/src/types.ts +0 -25
  281. package/svelte.config.js +0 -4
  282. package/tests/astro/build.test.ts +0 -63
  283. package/tests/astro/index.test.ts +0 -689
  284. package/tests/client/components/Admin.test.ts +0 -446
  285. package/tests/client/components/BackendPicker.test.ts +0 -239
  286. package/tests/client/components/DraftChip.test.ts +0 -53
  287. package/tests/client/components/MetadataForm.test.ts +0 -164
  288. package/tests/client/components/dialogs/DeleteDraftDialog.test.ts +0 -91
  289. package/tests/client/components/dialogs/FilenameDialog.test.ts +0 -209
  290. package/tests/client/components/dialogs/dialog-stubs.ts +0 -19
  291. package/tests/client/components/editor/EditorPane.test.ts +0 -100
  292. package/tests/client/components/editor/EditorTabs.test.ts +0 -253
  293. package/tests/client/components/editor/EditorToolbar.test.ts +0 -252
  294. package/tests/client/components/editor/fixtures.ts +0 -31
  295. package/tests/client/components/fields/ArrayField.test.ts +0 -197
  296. package/tests/client/components/fields/BooleanField.test.ts +0 -206
  297. package/tests/client/components/fields/DateField.test.ts +0 -210
  298. package/tests/client/components/fields/EnumField.test.ts +0 -246
  299. package/tests/client/components/fields/NumberField.test.ts +0 -240
  300. package/tests/client/components/fields/ObjectField.test.ts +0 -157
  301. package/tests/client/components/fields/SchemaField.test.ts +0 -190
  302. package/tests/client/components/fields/StringField.test.ts +0 -223
  303. package/tests/client/components/sidebar/AdminSidebar.test.ts +0 -285
  304. package/tests/client/components/sidebar/AdminSidebarSort.test.ts +0 -135
  305. package/tests/client/components/sidebar/sort-mock.ts +0 -23
  306. package/tests/client/js/drafts/fixtures.ts +0 -22
  307. package/tests/client/js/drafts/merge.test.ts +0 -282
  308. package/tests/client/js/drafts/ops.test.ts +0 -658
  309. package/tests/client/js/drafts/storage.test.ts +0 -200
  310. package/tests/client/js/drafts/workers/diff.test.ts +0 -165
  311. package/tests/client/js/editor/editor.test.ts +0 -616
  312. package/tests/client/js/editor/link-wrap.test.ts +0 -225
  313. package/tests/client/js/editor/markdown-shortcuts.test.ts +0 -370
  314. package/tests/client/js/handlers/admin.test.ts +0 -467
  315. package/tests/client/js/state/router.test.ts +0 -619
  316. package/tests/client/js/state/schema.test.ts +0 -266
  317. package/tests/client/js/state/state.test.ts +0 -328
  318. package/tests/client/js/storage/adapter.test.ts +0 -115
  319. package/tests/client/js/storage/client.test.ts +0 -250
  320. package/tests/client/js/storage/db.test.ts +0 -59
  321. package/tests/client/js/storage/fsa.test.ts +0 -284
  322. package/tests/client/js/storage/github.test.ts +0 -349
  323. package/tests/client/js/storage/mock-port.ts +0 -95
  324. package/tests/client/js/storage/storage.test.ts +0 -77
  325. package/tests/client/js/storage/workers/frontmatter.test.ts +0 -479
  326. package/tests/client/js/storage/workers/storage.test.ts +0 -299
  327. package/tests/client/js/storage/workers/toml-parser.test.ts +0 -169
  328. package/tests/client/js/storage/workers/yaml-parser.test.ts +0 -168
  329. package/tests/client/js/utils/file-types.test.ts +0 -268
  330. package/tests/client/js/utils/frontmatter.test.ts +0 -87
  331. package/tests/client/js/utils/schema-utils.test.ts +0 -318
  332. package/tests/client/js/utils/slug.test.ts +0 -58
  333. package/tests/client/js/utils/sort.test.ts +0 -276
  334. package/tests/client/js/utils/stable-stringify.test.ts +0 -68
  335. package/tests/client/js/utils/url-utils.test.ts +0 -70
  336. package/tests/e2e/backend-connection.test.ts +0 -301
  337. package/tests/e2e/draft-lifecycle.test.ts +0 -388
  338. package/tests/e2e/editing.test.ts +0 -355
  339. package/tests/e2e/github-adapter.test.ts +0 -330
  340. package/tests/e2e/helpers/mock-adapter.ts +0 -166
  341. package/tests/e2e/helpers/test-app.ts +0 -155
  342. package/tests/e2e/navigation.test.ts +0 -358
  343. package/tests/e2e/publishing.test.ts +0 -345
  344. package/tests/e2e/unsaved-changes.test.ts +0 -317
  345. package/tests/setup.ts +0 -2
  346. package/tests/stubs/codemirror.ts +0 -197
  347. package/tsconfig.json +0 -19
  348. package/vitest.config.ts +0 -178
  349. /package/{src → dist}/client/Admin.svelte +0 -0
  350. /package/{src → dist}/client/components/BackendPicker.svelte +0 -0
  351. /package/{src → dist}/client/components/DraftChip.svelte +0 -0
  352. /package/{src → dist}/client/components/MetadataForm.svelte +0 -0
  353. /package/{src → dist}/client/components/ThemeToggle.svelte +0 -0
  354. /package/{src → dist}/client/components/dialogs/DeleteDraftDialog.svelte +0 -0
  355. /package/{src → dist}/client/components/dialogs/FilenameDialog.svelte +0 -0
  356. /package/{src → dist}/client/components/editor/EditorPane.svelte +0 -0
  357. /package/{src → dist}/client/components/editor/EditorTabs.svelte +0 -0
  358. /package/{src → dist}/client/components/editor/EditorToolbar.svelte +0 -0
  359. /package/{src → dist}/client/components/editor/FormatSelector.svelte +0 -0
  360. /package/{src → dist}/client/components/editor/Toolbar.svelte +0 -0
  361. /package/{src → dist}/client/components/fields/ArrayField.svelte +0 -0
  362. /package/{src → dist}/client/components/fields/ArrayItem.svelte +0 -0
  363. /package/{src → dist}/client/components/fields/BooleanField.svelte +0 -0
  364. /package/{src → dist}/client/components/fields/DateField.svelte +0 -0
  365. /package/{src → dist}/client/components/fields/EnumField.svelte +0 -0
  366. /package/{src → dist}/client/components/fields/FieldWrapper.svelte +0 -0
  367. /package/{src → dist}/client/components/fields/NumberField.svelte +0 -0
  368. /package/{src → dist}/client/components/fields/ObjectField.svelte +0 -0
  369. /package/{src → dist}/client/components/fields/SchemaField.svelte +0 -0
  370. /package/{src → dist}/client/components/fields/StringField.svelte +0 -0
  371. /package/{src → dist}/client/components/sidebar/AdminSidebar.svelte +0 -0
  372. /package/{src → dist}/client/components/sidebar/AdminSidebarSort.svelte +0 -0
  373. /package/{src → dist}/client/css/a11y.css +0 -0
  374. /package/{src → dist}/client/css/btn.css +0 -0
  375. /package/{src → dist}/client/css/dialog.css +0 -0
  376. /package/{src → dist}/client/css/field-input.css +0 -0
  377. /package/{src → dist}/client/css/reset.css +0 -0
  378. /package/{src → dist}/client/css/theme.css +0 -0
  379. /package/{src/client/index.ts → dist/client/index.js} +0 -0
  380. /package/{src → dist}/virtual.d.ts +0 -0
@@ -1,616 +0,0 @@
1
- import { describe, it, expect, vi, afterEach } from 'vitest';
2
-
3
- //////////////////////////////
4
- // Editor module test strategy
5
- //
6
- // editor.svelte.ts calls registerDirtyChecker() at the top level when the
7
- // module is first evaluated, which requires the router to already be mocked.
8
- // The module also holds all state at module scope — to get a clean starting
9
- // state for each describe block that needs it we use vi.resetModules() +
10
- // dynamic import. All dependency mocks are declared here before static
11
- // imports so Vitest's vi.mock() hoisting guarantees they are in place.
12
- //////////////////////////////
13
-
14
- vi.mock('../../../../src/client/js/state/router.svelte', () => ({
15
- registerDirtyChecker: vi.fn(),
16
- adminPath: vi.fn((...segments) =>
17
- segments.length === 0 ? '/admin' : '/admin/' + segments.join('/'),
18
- ),
19
- }));
20
-
21
- vi.mock('../../../../src/client/js/utils/frontmatter', () => ({
22
- splitFrontmatter: vi.fn((text: string) => ({
23
- rawFrontmatter: '',
24
- body: text,
25
- })),
26
- }));
27
-
28
- vi.mock('../../../../src/client/js/utils/schema-utils', () => ({
29
- setByPath: vi.fn(
30
- (
31
- obj: Record<string, unknown>,
32
- path: (string | number)[],
33
- value: unknown,
34
- ) => {
35
- // Minimal real implementation so updateFormField tests work correctly
36
- let current = obj as Record<string | number, unknown>;
37
- for (let i = 0; i < path.length - 1; i++) {
38
- if (!current[path[i]]) current[path[i]] = {};
39
- current = current[path[i]] as Record<string | number, unknown>;
40
- }
41
- current[path[path.length - 1]] = value;
42
- },
43
- ),
44
- }));
45
-
46
- vi.mock('../../../../src/client/js/drafts/storage', () => ({
47
- getDraftByFile: vi.fn(async () => null),
48
- }));
49
-
50
- // storageClient is a direct object export (not a getter function), so the
51
- // mock uses a hoisted ref that tests swap between null and a fake client.
52
- const { mockStorageClientRef } = vi.hoisted(() => ({
53
- mockStorageClientRef: { current: null as any },
54
- }));
55
- vi.mock('../../../../src/client/js/state/state.svelte', () => ({
56
- get storageClient() {
57
- return mockStorageClientRef.current;
58
- },
59
- }));
60
-
61
- vi.mock(
62
- import('../../../../src/client/js/utils/file-types'),
63
- async (importOriginal) => ({
64
- ...(await importOriginal()),
65
- getFileCategory: vi.fn(() => null),
66
- }),
67
- );
68
-
69
- // ops.svelte re-exports — editor.svelte.ts re-exports these; mock them so
70
- // importing the editor does not pull in the real ops module's dependencies.
71
- vi.mock('../../../../src/client/js/drafts/ops.svelte', () => ({
72
- saveDraftToIDB: vi.fn(async () => undefined),
73
- saveFile: vi.fn(async () => undefined),
74
- publishFile: vi.fn(async () => undefined),
75
- loadDraftById: vi.fn(async () => undefined),
76
- deleteCurrentDraft: vi.fn(async () => undefined),
77
- }));
78
-
79
- import { getDraftByFile } from '../../../../src/client/js/drafts/storage';
80
- // storageClient import removed — tests configure mockStorageClientRef.current directly
81
- import { splitFrontmatter } from '../../../../src/client/js/utils/frontmatter';
82
- import { getFileCategory } from '../../../../src/client/js/utils/file-types';
83
-
84
- import type { Draft } from '../../../../src/client/js/drafts/storage';
85
-
86
- /**
87
- * Builds a minimal Draft fixture for editor tests.
88
- * @param {Partial<Draft>} overrides - Optional field overrides
89
- * @return {Draft} A complete Draft object
90
- */
91
- function makeDraft(overrides: Partial<Draft> = {}): Draft {
92
- return {
93
- id: 'ed-draft-01',
94
- collection: 'posts',
95
- filename: 'post.md',
96
- isNew: false,
97
- formData: { title: 'Draft Title' },
98
- body: 'Draft body content',
99
- snapshot: '{"body":"orig","formData":{"title":"Orig"}}',
100
- createdAt: '2026-01-01T00:00:00.000Z',
101
- ...overrides,
102
- };
103
- }
104
-
105
- //////////////////////////////
106
- // getEditorFile / formData — initial state
107
- //////////////////////////////
108
-
109
- describe('getEditorFile — initial state', () => {
110
- afterEach(() => {
111
- vi.resetModules();
112
- });
113
-
114
- it('returns null when no file has been opened', async () => {
115
- vi.resetModules();
116
- const { getEditorFile } =
117
- await import('../../../../src/client/js/editor/editor.svelte');
118
- expect(getEditorFile()).toBeNull();
119
- });
120
- });
121
-
122
- describe('formData — initial state', () => {
123
- afterEach(() => {
124
- vi.resetModules();
125
- });
126
-
127
- it('returns an empty object before any file is loaded', async () => {
128
- vi.resetModules();
129
- const { editor } =
130
- await import('../../../../src/client/js/editor/editor.svelte');
131
- expect(editor.data).toEqual({});
132
- });
133
- });
134
-
135
- //////////////////////////////
136
- // activeTab / setActiveTab
137
- //////////////////////////////
138
-
139
- describe('activeTab / setActiveTab', () => {
140
- afterEach(() => {
141
- vi.resetModules();
142
- });
143
-
144
- it('returns "metadata" as the default active tab', async () => {
145
- vi.resetModules();
146
- const { editor } =
147
- await import('../../../../src/client/js/editor/editor.svelte');
148
- expect(editor.tab).toBe('metadata');
149
- });
150
-
151
- it('updates the active tab via setActiveTab', async () => {
152
- vi.resetModules();
153
- const mod = await import('../../../../src/client/js/editor/editor.svelte');
154
- mod.setActiveTab('content');
155
- expect(mod.editor.tab).toBe('content');
156
- });
157
-
158
- it('can set any arbitrary tab string', async () => {
159
- vi.resetModules();
160
- const mod = await import('../../../../src/client/js/editor/editor.svelte');
161
- mod.setActiveTab('seo');
162
- expect(mod.editor.tab).toBe('seo');
163
- });
164
- });
165
-
166
- //////////////////////////////
167
- // applyEditorState
168
- //////////////////////////////
169
-
170
- describe('applyEditorState', () => {
171
- afterEach(() => {
172
- vi.resetModules();
173
- });
174
-
175
- it('opens the file and populates getEditorFile when open=true', async () => {
176
- vi.resetModules();
177
- const { applyEditorState, getEditorFile } =
178
- await import('../../../../src/client/js/editor/editor.svelte');
179
- applyEditorState(
180
- {
181
- body: 'Hello',
182
- formData: { title: 'T' },
183
- filename: 'test.md',
184
- bodyLoaded: true,
185
- draftId: null,
186
- isNewDraft: false,
187
- snapshot: null,
188
- collection: 'posts',
189
- draftCreatedAt: null,
190
- },
191
- true,
192
- );
193
- const file = getEditorFile();
194
- expect(file).not.toBeNull();
195
- expect(file?.body).toBe('Hello');
196
- expect(file?.filename).toBe('test.md');
197
- expect(file?.dirty).toBe(false);
198
- });
199
-
200
- it('resets activeTab to "metadata" on each apply', async () => {
201
- vi.resetModules();
202
- const mod = await import('../../../../src/client/js/editor/editor.svelte');
203
- mod.setActiveTab('content');
204
- mod.applyEditorState(
205
- {
206
- body: '',
207
- formData: {},
208
- filename: 'x.md',
209
- bodyLoaded: false,
210
- draftId: null,
211
- isNewDraft: false,
212
- snapshot: null,
213
- collection: 'posts',
214
- draftCreatedAt: null,
215
- },
216
- true,
217
- );
218
- expect(mod.editor.tab).toBe('metadata');
219
- });
220
-
221
- it('keeps getEditorFile null when open=false', async () => {
222
- vi.resetModules();
223
- const { applyEditorState, getEditorFile } =
224
- await import('../../../../src/client/js/editor/editor.svelte');
225
- applyEditorState(
226
- {
227
- body: '',
228
- formData: {},
229
- filename: '',
230
- bodyLoaded: false,
231
- draftId: null,
232
- isNewDraft: false,
233
- snapshot: null,
234
- collection: '',
235
- draftCreatedAt: null,
236
- },
237
- false,
238
- );
239
- expect(getEditorFile()).toBeNull();
240
- });
241
- });
242
-
243
- //////////////////////////////
244
- // updateFormField
245
- //////////////////////////////
246
-
247
- describe('updateFormField', () => {
248
- afterEach(() => {
249
- vi.resetModules();
250
- });
251
-
252
- it('updates a top-level formData field', async () => {
253
- vi.resetModules();
254
- const mod = await import('../../../../src/client/js/editor/editor.svelte');
255
- mod.applyEditorState(
256
- {
257
- body: '',
258
- formData: { title: 'Original' },
259
- filename: 'f.md',
260
- bodyLoaded: true,
261
- draftId: null,
262
- isNewDraft: false,
263
- snapshot: null,
264
- collection: 'posts',
265
- draftCreatedAt: null,
266
- },
267
- true,
268
- );
269
- mod.updateFormField(['title'], 'Updated');
270
- expect(mod.editor.data['title']).toBe('Updated');
271
- });
272
-
273
- it('marks the file dirty after a formData change', async () => {
274
- vi.resetModules();
275
- const { applyEditorState, updateFormField, getEditorFile } =
276
- await import('../../../../src/client/js/editor/editor.svelte');
277
- applyEditorState(
278
- {
279
- body: '',
280
- formData: { title: 'Same' },
281
- filename: 'f.md',
282
- bodyLoaded: true,
283
- draftId: null,
284
- isNewDraft: false,
285
- snapshot: null,
286
- collection: 'posts',
287
- draftCreatedAt: null,
288
- },
289
- true,
290
- );
291
- updateFormField(['title'], 'Different');
292
- expect(getEditorFile()?.dirty).toBe(true);
293
- });
294
- });
295
-
296
- //////////////////////////////
297
- // updateBody
298
- //////////////////////////////
299
-
300
- describe('updateBody', () => {
301
- afterEach(() => {
302
- vi.resetModules();
303
- });
304
-
305
- it('updates the body content', async () => {
306
- vi.resetModules();
307
- const { applyEditorState, updateBody, getEditorFile } =
308
- await import('../../../../src/client/js/editor/editor.svelte');
309
- applyEditorState(
310
- {
311
- body: 'original',
312
- formData: {},
313
- filename: 'f.md',
314
- bodyLoaded: true,
315
- draftId: null,
316
- isNewDraft: false,
317
- snapshot: null,
318
- collection: 'posts',
319
- draftCreatedAt: null,
320
- },
321
- true,
322
- );
323
- updateBody('new content');
324
- expect(getEditorFile()?.body).toBe('new content');
325
- });
326
-
327
- it('marks the file dirty when body differs from last saved', async () => {
328
- vi.resetModules();
329
- const { applyEditorState, updateBody, getEditorFile } =
330
- await import('../../../../src/client/js/editor/editor.svelte');
331
- applyEditorState(
332
- {
333
- body: 'saved',
334
- formData: {},
335
- filename: 'f.md',
336
- bodyLoaded: true,
337
- draftId: null,
338
- isNewDraft: false,
339
- snapshot: null,
340
- collection: 'posts',
341
- draftCreatedAt: null,
342
- },
343
- true,
344
- );
345
- updateBody('changed');
346
- expect(getEditorFile()?.dirty).toBe(true);
347
- });
348
-
349
- it('clears dirty when body is restored to last saved value', async () => {
350
- vi.resetModules();
351
- const { applyEditorState, updateBody, getEditorFile } =
352
- await import('../../../../src/client/js/editor/editor.svelte');
353
- applyEditorState(
354
- {
355
- body: 'saved body',
356
- formData: {},
357
- filename: 'f.md',
358
- bodyLoaded: true,
359
- draftId: null,
360
- isNewDraft: false,
361
- snapshot: null,
362
- collection: 'posts',
363
- draftCreatedAt: null,
364
- },
365
- true,
366
- );
367
- updateBody('changed');
368
- updateBody('saved body');
369
- expect(getEditorFile()?.dirty).toBe(false);
370
- });
371
- });
372
-
373
- //////////////////////////////
374
- // clearEditor
375
- //////////////////////////////
376
-
377
- describe('clearEditor', () => {
378
- afterEach(() => {
379
- vi.resetModules();
380
- });
381
-
382
- it('returns null from getEditorFile after clearing', async () => {
383
- vi.resetModules();
384
- const { applyEditorState, clearEditor, getEditorFile } =
385
- await import('../../../../src/client/js/editor/editor.svelte');
386
- applyEditorState(
387
- {
388
- body: 'content',
389
- formData: { title: 'T' },
390
- filename: 'f.md',
391
- bodyLoaded: true,
392
- draftId: null,
393
- isNewDraft: false,
394
- snapshot: null,
395
- collection: 'posts',
396
- draftCreatedAt: null,
397
- },
398
- true,
399
- );
400
- clearEditor();
401
- expect(getEditorFile()).toBeNull();
402
- });
403
-
404
- it('resets formData to empty object', async () => {
405
- vi.resetModules();
406
- const mod = await import('../../../../src/client/js/editor/editor.svelte');
407
- mod.applyEditorState(
408
- {
409
- body: '',
410
- formData: { title: 'X' },
411
- filename: 'f.md',
412
- bodyLoaded: true,
413
- draftId: null,
414
- isNewDraft: false,
415
- snapshot: null,
416
- collection: 'posts',
417
- draftCreatedAt: null,
418
- },
419
- true,
420
- );
421
- mod.clearEditor();
422
- expect(mod.editor.data).toEqual({});
423
- });
424
- });
425
-
426
- //////////////////////////////
427
- // preloadFile
428
- //////////////////////////////
429
-
430
- describe('preloadFile', () => {
431
- afterEach(() => {
432
- vi.resetModules();
433
- vi.clearAllMocks();
434
- });
435
-
436
- it('loads draft data when a draft exists for the file', async () => {
437
- vi.resetModules();
438
- const draft = makeDraft();
439
- vi.mocked(getDraftByFile).mockResolvedValue(draft);
440
-
441
- const { preloadFile, getEditorFile } =
442
- await import('../../../../src/client/js/editor/editor.svelte');
443
- await preloadFile('posts', 'post.md', { title: 'Live' });
444
-
445
- const file = getEditorFile();
446
- expect(file?.body).toBe(draft.body);
447
- expect(file?.formData).toEqual(draft.formData);
448
- expect(file?.draftId).toBe(draft.id);
449
- expect(file?.bodyLoaded).toBe(true);
450
- });
451
-
452
- it('loads live data when no draft exists', async () => {
453
- vi.resetModules();
454
- vi.mocked(getDraftByFile).mockResolvedValue(null);
455
-
456
- const { preloadFile, getEditorFile } =
457
- await import('../../../../src/client/js/editor/editor.svelte');
458
- await preloadFile('posts', 'live-file.md', { title: 'Live Title' });
459
-
460
- const file = getEditorFile();
461
- expect(file?.body).toBe('');
462
- expect(file?.formData).toEqual({ title: 'Live Title' });
463
- expect(file?.draftId).toBeNull();
464
- expect(file?.bodyLoaded).toBe(false);
465
- });
466
-
467
- it('is a no-op when the same file is already open', async () => {
468
- vi.resetModules();
469
- vi.mocked(getDraftByFile).mockResolvedValue(null);
470
-
471
- const { preloadFile } =
472
- await import('../../../../src/client/js/editor/editor.svelte');
473
- await preloadFile('posts', 'same.md', { title: 'First' });
474
-
475
- vi.clearAllMocks();
476
- await preloadFile('posts', 'same.md', { title: 'Second' });
477
-
478
- // getDraftByFile should not be called on the second preload of the same file
479
- expect(getDraftByFile).not.toHaveBeenCalled();
480
- });
481
- });
482
-
483
- //////////////////////////////
484
- // loadFileBody
485
- //////////////////////////////
486
-
487
- describe('loadFileBody', () => {
488
- afterEach(() => {
489
- vi.resetModules();
490
- vi.clearAllMocks();
491
- });
492
-
493
- it('does nothing when no storage client is connected', async () => {
494
- vi.resetModules();
495
- mockStorageClientRef.current = null;
496
- vi.mocked(getDraftByFile).mockResolvedValue(null);
497
-
498
- const { preloadFile, loadFileBody, getEditorFile } =
499
- await import('../../../../src/client/js/editor/editor.svelte');
500
- await preloadFile('posts', 'f.md', {});
501
- await loadFileBody('posts', 'f.md');
502
-
503
- // bodyLoaded should remain false since client was null
504
- expect(getEditorFile()?.bodyLoaded).toBe(false);
505
- });
506
-
507
- it('reads the file and updates body + bodyLoaded flag', async () => {
508
- vi.resetModules();
509
- vi.mocked(getDraftByFile).mockResolvedValue(null);
510
- vi.mocked(splitFrontmatter).mockReturnValue({
511
- rawFrontmatter: 'title: T',
512
- body: '\n\nThe markdown body\n\n',
513
- });
514
- const fakeClient = {
515
- readFile: vi.fn(
516
- async () => '---\ntitle: T\n---\n\nThe markdown body\n\n',
517
- ),
518
- };
519
- mockStorageClientRef.current = fakeClient;
520
-
521
- const { preloadFile, loadFileBody, getEditorFile } =
522
- await import('../../../../src/client/js/editor/editor.svelte');
523
- await preloadFile('posts', 'body-file.md', { title: 'T' });
524
- await loadFileBody('posts', 'body-file.md');
525
-
526
- const file = getEditorFile();
527
- expect(file?.bodyLoaded).toBe(true);
528
- // Leading/trailing newlines are stripped from the body
529
- expect(file?.body).toBe('The markdown body');
530
- });
531
-
532
- it('skips disk read and sets bodyLoaded for data-only files', async () => {
533
- vi.resetModules();
534
- vi.mocked(getDraftByFile).mockResolvedValue(null);
535
- // Simulate a data file — category is 'data', so no disk read should occur
536
- vi.mocked(getFileCategory).mockReturnValue('data');
537
- const fakeClient = {
538
- readFile: vi.fn(async () => '{}'),
539
- };
540
- mockStorageClientRef.current = fakeClient;
541
-
542
- const { preloadFile, loadFileBody, getEditorFile } =
543
- await import('../../../../src/client/js/editor/editor.svelte');
544
- await preloadFile('authors', 'jane.json', { name: 'Jane' });
545
- await loadFileBody('authors', 'jane.json');
546
-
547
- // readFile must not be called — data files have no body to read
548
- expect(fakeClient.readFile).not.toHaveBeenCalled();
549
- expect(getEditorFile()?.bodyLoaded).toBe(true);
550
- });
551
- });
552
-
553
- //////////////////////////////
554
- // _getDraftState / _setDraftState
555
- //////////////////////////////
556
-
557
- describe('_getDraftState / _setDraftState', () => {
558
- afterEach(() => {
559
- vi.resetModules();
560
- });
561
-
562
- it('_getDraftState returns current internal state snapshot', async () => {
563
- vi.resetModules();
564
- const { _getDraftState } =
565
- await import('../../../../src/client/js/editor/editor.svelte');
566
- const state = _getDraftState();
567
- expect(state).toHaveProperty('saving');
568
- expect(state).toHaveProperty('draftId');
569
- expect(state).toHaveProperty('isNewDraft');
570
- expect(state).toHaveProperty('snapshot');
571
- expect(state).toHaveProperty('currentCollection');
572
- expect(state).toHaveProperty('body');
573
- expect(state).toHaveProperty('formData');
574
- });
575
-
576
- it('_setDraftState updates the saving flag', async () => {
577
- vi.resetModules();
578
- const { _setDraftState, _getDraftState } =
579
- await import('../../../../src/client/js/editor/editor.svelte');
580
- _setDraftState({ saving: true });
581
- expect(_getDraftState().saving).toBe(true);
582
- _setDraftState({ saving: false });
583
- expect(_getDraftState().saving).toBe(false);
584
- });
585
-
586
- it('_setDraftState updates draftId', async () => {
587
- vi.resetModules();
588
- const { _setDraftState, _getDraftState } =
589
- await import('../../../../src/client/js/editor/editor.svelte');
590
- _setDraftState({ draftId: 'new-id' });
591
- expect(_getDraftState().draftId).toBe('new-id');
592
- });
593
-
594
- it('_setDraftState only mutates the specified fields', async () => {
595
- vi.resetModules();
596
- const { applyEditorState, _setDraftState, _getDraftState } =
597
- await import('../../../../src/client/js/editor/editor.svelte');
598
- applyEditorState(
599
- {
600
- body: 'body',
601
- formData: { title: 'T' },
602
- filename: 'f.md',
603
- bodyLoaded: true,
604
- draftId: null,
605
- isNewDraft: true,
606
- snapshot: null,
607
- collection: 'posts',
608
- draftCreatedAt: null,
609
- },
610
- true,
611
- );
612
- _setDraftState({ saving: true });
613
- // isNewDraft should be unchanged
614
- expect(_getDraftState().isNewDraft).toBe(true);
615
- });
616
- });