nebula-cms 0.1.0 → 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 (386) 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 +8 -1
  156. package/.claude/settings.local.json +0 -42
  157. package/.github/workflows/ci.yml +0 -31
  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/.claude/settings.local.json +0 -5
  163. package/playground/astro.config.mjs +0 -7
  164. package/playground/node_modules/.bin/astro +0 -21
  165. package/playground/node_modules/.bin/rollup +0 -21
  166. package/playground/node_modules/.bin/tsc +0 -21
  167. package/playground/node_modules/.bin/tsserver +0 -21
  168. package/playground/node_modules/.bin/vite +0 -21
  169. package/playground/node_modules/.vite/_svelte_metadata.json +0 -1
  170. package/playground/node_modules/.vite/deps/@astrojs_svelte_client__js.js +0 -80
  171. package/playground/node_modules/.vite/deps/@astrojs_svelte_client__js.js.map +0 -7
  172. package/playground/node_modules/.vite/deps/_metadata.json +0 -184
  173. package/playground/node_modules/.vite/deps/astro___aria-query.js +0 -6776
  174. package/playground/node_modules/.vite/deps/astro___aria-query.js.map +0 -7
  175. package/playground/node_modules/.vite/deps/astro___axobject-query.js +0 -3754
  176. package/playground/node_modules/.vite/deps/astro___axobject-query.js.map +0 -7
  177. package/playground/node_modules/.vite/deps/astro___html-escaper.js +0 -34
  178. package/playground/node_modules/.vite/deps/astro___html-escaper.js.map +0 -7
  179. package/playground/node_modules/.vite/deps/chunk-AJXJMYAF.js +0 -0
  180. package/playground/node_modules/.vite/deps/chunk-AJXJMYAF.js.map +0 -7
  181. package/playground/node_modules/.vite/deps/chunk-ALJIOON6.js +0 -1005
  182. package/playground/node_modules/.vite/deps/chunk-ALJIOON6.js.map +0 -7
  183. package/playground/node_modules/.vite/deps/chunk-BUSYA2B4.js +0 -8
  184. package/playground/node_modules/.vite/deps/chunk-BUSYA2B4.js.map +0 -7
  185. package/playground/node_modules/.vite/deps/chunk-CNYJBM5F.js +0 -21
  186. package/playground/node_modules/.vite/deps/chunk-CNYJBM5F.js.map +0 -7
  187. package/playground/node_modules/.vite/deps/chunk-DBPNBGEI.js +0 -223
  188. package/playground/node_modules/.vite/deps/chunk-DBPNBGEI.js.map +0 -7
  189. package/playground/node_modules/.vite/deps/chunk-G3C2FXJT.js +0 -204
  190. package/playground/node_modules/.vite/deps/chunk-G3C2FXJT.js.map +0 -7
  191. package/playground/node_modules/.vite/deps/chunk-GKDKFWC5.js +0 -27
  192. package/playground/node_modules/.vite/deps/chunk-GKDKFWC5.js.map +0 -7
  193. package/playground/node_modules/.vite/deps/chunk-HNCLEOC5.js +0 -4376
  194. package/playground/node_modules/.vite/deps/chunk-HNCLEOC5.js.map +0 -7
  195. package/playground/node_modules/.vite/deps/chunk-JICYXBFU.js +0 -688
  196. package/playground/node_modules/.vite/deps/chunk-JICYXBFU.js.map +0 -7
  197. package/playground/node_modules/.vite/deps/chunk-KCUTL6DD.js +0 -5099
  198. package/playground/node_modules/.vite/deps/chunk-KCUTL6DD.js.map +0 -7
  199. package/playground/node_modules/.vite/deps/chunk-ZP4UNCSN.js +0 -23
  200. package/playground/node_modules/.vite/deps/chunk-ZP4UNCSN.js.map +0 -7
  201. package/playground/node_modules/.vite/deps/chunk-ZREFNRZZ.js +0 -148
  202. package/playground/node_modules/.vite/deps/chunk-ZREFNRZZ.js.map +0 -7
  203. package/playground/node_modules/.vite/deps/package.json +0 -3
  204. package/playground/node_modules/.vite/deps/smol-toml.js +0 -843
  205. package/playground/node_modules/.vite/deps/smol-toml.js.map +0 -7
  206. package/playground/node_modules/.vite/deps/svelte.js +0 -55
  207. package/playground/node_modules/.vite/deps/svelte.js.map +0 -7
  208. package/playground/node_modules/.vite/deps/svelte___clsx.js +0 -9
  209. package/playground/node_modules/.vite/deps/svelte___clsx.js.map +0 -7
  210. package/playground/node_modules/.vite/deps/svelte_animate.js +0 -57
  211. package/playground/node_modules/.vite/deps/svelte_animate.js.map +0 -7
  212. package/playground/node_modules/.vite/deps/svelte_attachments.js +0 -15
  213. package/playground/node_modules/.vite/deps/svelte_attachments.js.map +0 -7
  214. package/playground/node_modules/.vite/deps/svelte_easing.js +0 -67
  215. package/playground/node_modules/.vite/deps/svelte_easing.js.map +0 -7
  216. package/playground/node_modules/.vite/deps/svelte_events.js +0 -11
  217. package/playground/node_modules/.vite/deps/svelte_events.js.map +0 -7
  218. package/playground/node_modules/.vite/deps/svelte_internal.js +0 -5
  219. package/playground/node_modules/.vite/deps/svelte_internal.js.map +0 -7
  220. package/playground/node_modules/.vite/deps/svelte_internal_client.js +0 -402
  221. package/playground/node_modules/.vite/deps/svelte_internal_client.js.map +0 -7
  222. package/playground/node_modules/.vite/deps/svelte_internal_disclose-version.js +0 -10
  223. package/playground/node_modules/.vite/deps/svelte_internal_disclose-version.js.map +0 -7
  224. package/playground/node_modules/.vite/deps/svelte_internal_flags_async.js +0 -8
  225. package/playground/node_modules/.vite/deps/svelte_internal_flags_async.js.map +0 -7
  226. package/playground/node_modules/.vite/deps/svelte_internal_flags_legacy.js +0 -8
  227. package/playground/node_modules/.vite/deps/svelte_internal_flags_legacy.js.map +0 -7
  228. package/playground/node_modules/.vite/deps/svelte_internal_flags_tracing.js +0 -8
  229. package/playground/node_modules/.vite/deps/svelte_internal_flags_tracing.js.map +0 -7
  230. package/playground/node_modules/.vite/deps/svelte_legacy.js +0 -35
  231. package/playground/node_modules/.vite/deps/svelte_legacy.js.map +0 -7
  232. package/playground/node_modules/.vite/deps/svelte_motion.js +0 -545
  233. package/playground/node_modules/.vite/deps/svelte_motion.js.map +0 -7
  234. package/playground/node_modules/.vite/deps/svelte_reactivity.js +0 -29
  235. package/playground/node_modules/.vite/deps/svelte_reactivity.js.map +0 -7
  236. package/playground/node_modules/.vite/deps/svelte_reactivity_window.js +0 -127
  237. package/playground/node_modules/.vite/deps/svelte_reactivity_window.js.map +0 -7
  238. package/playground/node_modules/.vite/deps/svelte_store.js +0 -103
  239. package/playground/node_modules/.vite/deps/svelte_store.js.map +0 -7
  240. package/playground/node_modules/.vite/deps/svelte_transition.js +0 -208
  241. package/playground/node_modules/.vite/deps/svelte_transition.js.map +0 -7
  242. package/playground/package.json +0 -16
  243. package/playground/pnpm-lock.yaml +0 -3167
  244. package/playground/src/content/authors/jane-doe.json +0 -8
  245. package/playground/src/content/config/build.toml +0 -2
  246. package/playground/src/content/courses/web-fundamentals.json +0 -29
  247. package/playground/src/content/docs/advanced.mdx +0 -6
  248. package/playground/src/content/docs/intro.md +0 -6
  249. package/playground/src/content/guides/getting-started.mdx +0 -6
  250. package/playground/src/content/posts/hello-world.md +0 -7
  251. package/playground/src/content/products/t-shirt.json +0 -16
  252. package/playground/src/content/recipes/pancakes.mdoc +0 -8
  253. package/playground/src/content/settings/site.yml +0 -2
  254. package/playground/src/content.config.ts +0 -198
  255. package/playground/src/env.d.ts +0 -1
  256. package/playground/src/pages/index.astro +0 -11
  257. package/playground/src/pages/nebula.astro +0 -14
  258. package/pnpm-workspace.yaml +0 -2
  259. package/scripts/subset-icons.mjs +0 -178
  260. package/src/astro/index.ts +0 -295
  261. package/src/client/js/drafts/merge.svelte.ts +0 -121
  262. package/src/client/js/drafts/ops.svelte.ts +0 -227
  263. package/src/client/js/drafts/storage.ts +0 -108
  264. package/src/client/js/drafts/workers/diff.ts +0 -40
  265. package/src/client/js/editor/editor.svelte.ts +0 -343
  266. package/src/client/js/editor/languages.ts +0 -98
  267. package/src/client/js/editor/markdown-shortcuts.ts +0 -261
  268. package/src/client/js/handlers/admin.ts +0 -246
  269. package/src/client/js/state/dialogs.svelte.ts +0 -35
  270. package/src/client/js/state/router.svelte.ts +0 -156
  271. package/src/client/js/state/state.svelte.ts +0 -334
  272. package/src/client/js/storage/adapter.ts +0 -102
  273. package/src/client/js/storage/client.ts +0 -150
  274. package/src/client/js/storage/db.ts +0 -36
  275. package/src/client/js/storage/fsa.ts +0 -110
  276. package/src/client/js/storage/github.ts +0 -297
  277. package/src/client/js/storage/storage.ts +0 -83
  278. package/src/client/js/storage/workers/frontmatter.ts +0 -320
  279. package/src/client/js/storage/workers/storage.ts +0 -177
  280. package/src/client/js/storage/workers/toml-parser.ts +0 -106
  281. package/src/client/js/storage/workers/yaml-parser.ts +0 -132
  282. package/src/client/js/utils/frontmatter.ts +0 -38
  283. package/src/client/js/utils/schema-utils.ts +0 -295
  284. package/src/client/js/utils/sort.ts +0 -84
  285. package/src/client/js/utils/stable-stringify.ts +0 -27
  286. package/src/types.ts +0 -25
  287. package/svelte.config.js +0 -4
  288. package/tests/astro/build.test.ts +0 -63
  289. package/tests/astro/index.test.ts +0 -689
  290. package/tests/client/components/Admin.test.ts +0 -446
  291. package/tests/client/components/BackendPicker.test.ts +0 -239
  292. package/tests/client/components/DraftChip.test.ts +0 -53
  293. package/tests/client/components/MetadataForm.test.ts +0 -164
  294. package/tests/client/components/dialogs/DeleteDraftDialog.test.ts +0 -91
  295. package/tests/client/components/dialogs/FilenameDialog.test.ts +0 -209
  296. package/tests/client/components/dialogs/dialog-stubs.ts +0 -19
  297. package/tests/client/components/editor/EditorPane.test.ts +0 -100
  298. package/tests/client/components/editor/EditorTabs.test.ts +0 -253
  299. package/tests/client/components/editor/EditorToolbar.test.ts +0 -252
  300. package/tests/client/components/editor/fixtures.ts +0 -31
  301. package/tests/client/components/fields/ArrayField.test.ts +0 -197
  302. package/tests/client/components/fields/BooleanField.test.ts +0 -206
  303. package/tests/client/components/fields/DateField.test.ts +0 -210
  304. package/tests/client/components/fields/EnumField.test.ts +0 -246
  305. package/tests/client/components/fields/NumberField.test.ts +0 -240
  306. package/tests/client/components/fields/ObjectField.test.ts +0 -157
  307. package/tests/client/components/fields/SchemaField.test.ts +0 -190
  308. package/tests/client/components/fields/StringField.test.ts +0 -223
  309. package/tests/client/components/sidebar/AdminSidebar.test.ts +0 -285
  310. package/tests/client/components/sidebar/AdminSidebarSort.test.ts +0 -135
  311. package/tests/client/components/sidebar/sort-mock.ts +0 -23
  312. package/tests/client/js/drafts/fixtures.ts +0 -22
  313. package/tests/client/js/drafts/merge.test.ts +0 -282
  314. package/tests/client/js/drafts/ops.test.ts +0 -658
  315. package/tests/client/js/drafts/storage.test.ts +0 -200
  316. package/tests/client/js/drafts/workers/diff.test.ts +0 -165
  317. package/tests/client/js/editor/editor.test.ts +0 -616
  318. package/tests/client/js/editor/link-wrap.test.ts +0 -225
  319. package/tests/client/js/editor/markdown-shortcuts.test.ts +0 -370
  320. package/tests/client/js/handlers/admin.test.ts +0 -467
  321. package/tests/client/js/state/router.test.ts +0 -619
  322. package/tests/client/js/state/schema.test.ts +0 -266
  323. package/tests/client/js/state/state.test.ts +0 -328
  324. package/tests/client/js/storage/adapter.test.ts +0 -115
  325. package/tests/client/js/storage/client.test.ts +0 -250
  326. package/tests/client/js/storage/db.test.ts +0 -59
  327. package/tests/client/js/storage/fsa.test.ts +0 -284
  328. package/tests/client/js/storage/github.test.ts +0 -349
  329. package/tests/client/js/storage/mock-port.ts +0 -95
  330. package/tests/client/js/storage/storage.test.ts +0 -77
  331. package/tests/client/js/storage/workers/frontmatter.test.ts +0 -479
  332. package/tests/client/js/storage/workers/storage.test.ts +0 -299
  333. package/tests/client/js/storage/workers/toml-parser.test.ts +0 -169
  334. package/tests/client/js/storage/workers/yaml-parser.test.ts +0 -168
  335. package/tests/client/js/utils/file-types.test.ts +0 -268
  336. package/tests/client/js/utils/frontmatter.test.ts +0 -87
  337. package/tests/client/js/utils/schema-utils.test.ts +0 -318
  338. package/tests/client/js/utils/slug.test.ts +0 -58
  339. package/tests/client/js/utils/sort.test.ts +0 -276
  340. package/tests/client/js/utils/stable-stringify.test.ts +0 -68
  341. package/tests/client/js/utils/url-utils.test.ts +0 -70
  342. package/tests/e2e/backend-connection.test.ts +0 -301
  343. package/tests/e2e/draft-lifecycle.test.ts +0 -388
  344. package/tests/e2e/editing.test.ts +0 -355
  345. package/tests/e2e/github-adapter.test.ts +0 -330
  346. package/tests/e2e/helpers/mock-adapter.ts +0 -166
  347. package/tests/e2e/helpers/test-app.ts +0 -155
  348. package/tests/e2e/navigation.test.ts +0 -358
  349. package/tests/e2e/publishing.test.ts +0 -345
  350. package/tests/e2e/unsaved-changes.test.ts +0 -317
  351. package/tests/setup.ts +0 -2
  352. package/tests/stubs/codemirror.ts +0 -197
  353. package/tsconfig.json +0 -19
  354. package/vitest.config.ts +0 -178
  355. /package/{src → dist}/client/Admin.svelte +0 -0
  356. /package/{src → dist}/client/components/BackendPicker.svelte +0 -0
  357. /package/{src → dist}/client/components/DraftChip.svelte +0 -0
  358. /package/{src → dist}/client/components/MetadataForm.svelte +0 -0
  359. /package/{src → dist}/client/components/ThemeToggle.svelte +0 -0
  360. /package/{src → dist}/client/components/dialogs/DeleteDraftDialog.svelte +0 -0
  361. /package/{src → dist}/client/components/dialogs/FilenameDialog.svelte +0 -0
  362. /package/{src → dist}/client/components/editor/EditorPane.svelte +0 -0
  363. /package/{src → dist}/client/components/editor/EditorTabs.svelte +0 -0
  364. /package/{src → dist}/client/components/editor/EditorToolbar.svelte +0 -0
  365. /package/{src → dist}/client/components/editor/FormatSelector.svelte +0 -0
  366. /package/{src → dist}/client/components/editor/Toolbar.svelte +0 -0
  367. /package/{src → dist}/client/components/fields/ArrayField.svelte +0 -0
  368. /package/{src → dist}/client/components/fields/ArrayItem.svelte +0 -0
  369. /package/{src → dist}/client/components/fields/BooleanField.svelte +0 -0
  370. /package/{src → dist}/client/components/fields/DateField.svelte +0 -0
  371. /package/{src → dist}/client/components/fields/EnumField.svelte +0 -0
  372. /package/{src → dist}/client/components/fields/FieldWrapper.svelte +0 -0
  373. /package/{src → dist}/client/components/fields/NumberField.svelte +0 -0
  374. /package/{src → dist}/client/components/fields/ObjectField.svelte +0 -0
  375. /package/{src → dist}/client/components/fields/SchemaField.svelte +0 -0
  376. /package/{src → dist}/client/components/fields/StringField.svelte +0 -0
  377. /package/{src → dist}/client/components/sidebar/AdminSidebar.svelte +0 -0
  378. /package/{src → dist}/client/components/sidebar/AdminSidebarSort.svelte +0 -0
  379. /package/{src → dist}/client/css/a11y.css +0 -0
  380. /package/{src → dist}/client/css/btn.css +0 -0
  381. /package/{src → dist}/client/css/dialog.css +0 -0
  382. /package/{src → dist}/client/css/field-input.css +0 -0
  383. /package/{src → dist}/client/css/reset.css +0 -0
  384. /package/{src → dist}/client/css/theme.css +0 -0
  385. /package/{src/client/index.ts → dist/client/index.js} +0 -0
  386. /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
- });