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,467 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
2
-
3
- //////////////////////////////
4
- // admin handler tests
5
- //
6
- // All three imported state modules are mocked so the handlers run in
7
- // isolation without requiring Svelte reactivity or IDB. Each test
8
- // configures the mocks to reflect the scenario under test.
9
- //
10
- // vi.mock() is hoisted to the top of the file by vitest, which means any
11
- // top-level `const mock = vi.fn()` declarations would not yet be initialised
12
- // when the factory runs. We use vi.hoisted() to pre-declare the spy
13
- // references so they are available inside the hoisted vi.mock() factories.
14
- //////////////////////////////
15
-
16
- // ── Hoisted mock refs ──────────────────────────────────────────────────────
17
-
18
- const {
19
- mockSaveDraftToIDB,
20
- mockPublishFile,
21
- mockDeleteCurrentDraft,
22
- mockClearEditor,
23
- mockGetEditorFile,
24
- mockSetFilename,
25
- mockOriginalFilename,
26
- mockReloadCollection,
27
- mockRefreshDrafts,
28
- mockUpdateContentItem,
29
- mockNavigate,
30
- mockAdminPath,
31
- } = vi.hoisted(() => ({
32
- mockSaveDraftToIDB: vi.fn(),
33
- mockPublishFile: vi.fn(),
34
- mockDeleteCurrentDraft: vi.fn(),
35
- mockClearEditor: vi.fn(),
36
- mockGetEditorFile: vi.fn(),
37
- mockSetFilename: vi.fn(),
38
- mockOriginalFilename: vi.fn(),
39
- mockReloadCollection: vi.fn(),
40
- mockRefreshDrafts: vi.fn(),
41
- mockUpdateContentItem: vi.fn(),
42
- mockNavigate: vi.fn(),
43
- // Default implementation for /admin; tests that change basePath override via mockImplementation
44
- mockAdminPath: vi.fn((...segments: string[]) =>
45
- segments.length === 0 ? '/admin' : '/admin/' + segments.join('/'),
46
- ),
47
- }));
48
-
49
- // ── Mocks ──────────────────────────────────────────────────────────────────
50
-
51
- vi.mock('../../../../src/client/js/editor/editor.svelte', () => ({
52
- clearEditor: mockClearEditor,
53
- getEditorFile: mockGetEditorFile,
54
- setFilename: mockSetFilename,
55
- editor: {
56
- get originalFilename() {
57
- return mockOriginalFilename();
58
- },
59
- },
60
- }));
61
-
62
- vi.mock('../../../../src/client/js/drafts/ops.svelte', () => ({
63
- saveDraftToIDB: mockSaveDraftToIDB,
64
- publishFile: mockPublishFile,
65
- deleteCurrentDraft: mockDeleteCurrentDraft,
66
- }));
67
-
68
- vi.mock('../../../../src/client/js/state/state.svelte', () => ({
69
- collections: ['posts', 'pages'],
70
- reloadCollection: mockReloadCollection,
71
- refreshDrafts: mockRefreshDrafts,
72
- updateContentItem: mockUpdateContentItem,
73
- }));
74
-
75
- vi.mock('../../../../src/client/js/state/schema.svelte', () => ({
76
- getCollectionTitle: vi.fn(() => null),
77
- getCollectionDescription: vi.fn(() => null),
78
- }));
79
-
80
- vi.mock('../../../../src/client/js/state/router.svelte', () => ({
81
- navigate: mockNavigate,
82
- adminPath: mockAdminPath,
83
- }));
84
-
85
- // ── Import handlers ────────────────────────────────────────────────────────
86
-
87
- import {
88
- handleSave,
89
- handlePublish,
90
- handleDeleteDraft,
91
- handleFilenameConfirm,
92
- computePublishDisabled,
93
- buildContentItems,
94
- } from '../../../../src/client/js/handlers/admin';
95
-
96
- // ── Tests ─────────────────────────────────────────────────────────────────────
97
-
98
- describe('handleSave', () => {
99
- beforeEach(() => {
100
- vi.clearAllMocks();
101
- mockSaveDraftToIDB.mockResolvedValue(undefined);
102
- mockRefreshDrafts.mockResolvedValue(undefined);
103
- });
104
-
105
- it('calls saveDraftToIDB', async () => {
106
- await handleSave(null);
107
- expect(mockSaveDraftToIDB).toHaveBeenCalledOnce();
108
- });
109
-
110
- it('calls refreshDrafts when activeCollection is provided', async () => {
111
- await handleSave('posts');
112
- expect(mockRefreshDrafts).toHaveBeenCalledWith('posts');
113
- });
114
-
115
- it('skips refreshDrafts when activeCollection is null', async () => {
116
- await handleSave(null);
117
- expect(mockRefreshDrafts).not.toHaveBeenCalled();
118
- });
119
- });
120
-
121
- describe('handlePublish', () => {
122
- beforeEach(() => {
123
- vi.clearAllMocks();
124
- mockRefreshDrafts.mockResolvedValue(undefined);
125
- mockPublishFile.mockResolvedValue(undefined);
126
- });
127
-
128
- it('returns no-file when getEditorFile returns null', async () => {
129
- mockGetEditorFile.mockReturnValue(null);
130
- const result = await handlePublish('posts');
131
- expect(result).toEqual({ status: 'no-file' });
132
- });
133
-
134
- it('returns no-file when activeCollection is null and file exists', async () => {
135
- mockGetEditorFile.mockReturnValue({
136
- filename: 'test.md',
137
- isNewDraft: false,
138
- formData: {},
139
- });
140
- const result = await handlePublish(null);
141
- expect(result).toEqual({ status: 'no-file' });
142
- });
143
-
144
- it('returns needs-filename when file has no filename', async () => {
145
- mockGetEditorFile.mockReturnValue({
146
- filename: '',
147
- isNewDraft: true,
148
- formData: {},
149
- });
150
- const result = await handlePublish('posts');
151
- expect(result).toEqual({ status: 'needs-filename' });
152
- });
153
-
154
- it('publishes and returns ok for existing file', async () => {
155
- mockGetEditorFile.mockReturnValue({
156
- filename: 'hello.md',
157
- isNewDraft: false,
158
- formData: { title: 'Hello' },
159
- });
160
- // Same filename means no rename — originalFilename arg should be undefined
161
- mockOriginalFilename.mockReturnValue('hello.md');
162
- const result = await handlePublish('posts');
163
- expect(mockPublishFile).toHaveBeenCalledWith(
164
- 'posts',
165
- 'hello.md',
166
- undefined,
167
- );
168
- expect(result).toEqual({ status: 'ok' });
169
- });
170
-
171
- it('calls reloadCollection for a new draft after publish', async () => {
172
- mockGetEditorFile.mockReturnValue({
173
- filename: 'new.md',
174
- isNewDraft: true,
175
- formData: {},
176
- });
177
- // New draft — originalFilename is empty
178
- mockOriginalFilename.mockReturnValue('');
179
- await handlePublish('posts');
180
- expect(mockReloadCollection).toHaveBeenCalledWith('posts');
181
- expect(mockUpdateContentItem).not.toHaveBeenCalled();
182
- });
183
-
184
- it('calls updateContentItem for an existing file after publish', async () => {
185
- const formData = { title: 'Existing' };
186
- mockGetEditorFile.mockReturnValue({
187
- filename: 'existing.md',
188
- isNewDraft: false,
189
- formData,
190
- });
191
- // Same filename — no rename
192
- mockOriginalFilename.mockReturnValue('existing.md');
193
- await handlePublish('posts');
194
- expect(mockUpdateContentItem).toHaveBeenCalledWith('existing.md', formData);
195
- expect(mockReloadCollection).not.toHaveBeenCalled();
196
- });
197
-
198
- it('calls refreshDrafts after a successful publish', async () => {
199
- mockGetEditorFile.mockReturnValue({
200
- filename: 'f.md',
201
- isNewDraft: false,
202
- formData: {},
203
- });
204
- mockOriginalFilename.mockReturnValue('f.md');
205
- await handlePublish('posts');
206
- expect(mockRefreshDrafts).toHaveBeenCalledWith('posts');
207
- });
208
- });
209
-
210
- describe('handleDeleteDraft', () => {
211
- beforeEach(() => {
212
- vi.clearAllMocks();
213
- mockRefreshDrafts.mockResolvedValue(undefined);
214
- mockDeleteCurrentDraft.mockResolvedValue(undefined);
215
- });
216
-
217
- it('deletes the current draft', async () => {
218
- mockGetEditorFile.mockReturnValue(null);
219
- await handleDeleteDraft('posts');
220
- expect(mockDeleteCurrentDraft).toHaveBeenCalledOnce();
221
- });
222
-
223
- it('navigates to collection list when draft is new', async () => {
224
- mockGetEditorFile.mockReturnValue({
225
- filename: null,
226
- isNewDraft: true,
227
- formData: {},
228
- });
229
- await handleDeleteDraft('posts');
230
- expect(mockNavigate).toHaveBeenCalledWith('/admin/posts');
231
- });
232
-
233
- it('navigates to the live file URL when draft is for existing content', async () => {
234
- mockGetEditorFile.mockReturnValue({
235
- filename: 'my-post.md',
236
- isNewDraft: false,
237
- formData: {},
238
- });
239
- await handleDeleteDraft('posts');
240
- expect(mockNavigate).toHaveBeenCalledWith('/admin/posts/my-post');
241
- });
242
-
243
- it('strips .mdx extension when navigating to live file', async () => {
244
- mockGetEditorFile.mockReturnValue({
245
- filename: 'component-post.mdx',
246
- isNewDraft: false,
247
- formData: {},
248
- });
249
- await handleDeleteDraft('posts');
250
- expect(mockNavigate).toHaveBeenCalledWith('/admin/posts/component-post');
251
- });
252
-
253
- it('calls refreshDrafts after deleting', async () => {
254
- mockGetEditorFile.mockReturnValue(null);
255
- await handleDeleteDraft('posts');
256
- expect(mockRefreshDrafts).toHaveBeenCalledWith('posts');
257
- });
258
-
259
- it('clears the editor before navigating', async () => {
260
- mockGetEditorFile.mockReturnValue(null);
261
- await handleDeleteDraft('posts');
262
- expect(mockClearEditor).toHaveBeenCalledOnce();
263
- });
264
-
265
- it('does not navigate when activeCollection is null', async () => {
266
- mockGetEditorFile.mockReturnValue(null);
267
- await handleDeleteDraft(null);
268
- expect(mockNavigate).not.toHaveBeenCalled();
269
- });
270
- });
271
-
272
- describe('handleFilenameConfirm', () => {
273
- beforeEach(() => {
274
- vi.clearAllMocks();
275
- mockRefreshDrafts.mockResolvedValue(undefined);
276
- mockPublishFile.mockResolvedValue(undefined);
277
- mockGetEditorFile.mockReturnValue({
278
- filename: 'chosen-name.md',
279
- isNewDraft: true,
280
- formData: {},
281
- });
282
- // New draft — no original filename
283
- mockOriginalFilename.mockReturnValue('');
284
- });
285
-
286
- it('sets the filename then calls handlePublish', async () => {
287
- await handleFilenameConfirm('chosen-name.md', 'posts');
288
- expect(mockSetFilename).toHaveBeenCalledWith('chosen-name.md');
289
- expect(mockPublishFile).toHaveBeenCalled();
290
- });
291
-
292
- it('passes the chosen filename to setFilename', async () => {
293
- await handleFilenameConfirm('my-article.md', 'posts');
294
- expect(mockSetFilename).toHaveBeenCalledWith('my-article.md');
295
- });
296
- });
297
-
298
- describe('handlers use configurable basePath', () => {
299
- beforeEach(() => {
300
- vi.clearAllMocks();
301
- mockRefreshDrafts.mockResolvedValue(undefined);
302
- mockDeleteCurrentDraft.mockResolvedValue(undefined);
303
- // Override the default basePath for this group
304
- mockAdminPath.mockImplementation((...segments: string[]) =>
305
- segments.length === 0 ? '/cms' : '/cms/' + segments.join('/'),
306
- );
307
- });
308
-
309
- it('buildContentItems uses adminPath for live item hrefs', () => {
310
- const items = buildContentItems(
311
- [{ filename: 'hello.md', data: { title: 'Hello' } }],
312
- [],
313
- {},
314
- 'posts',
315
- );
316
- expect(items[0].href).toBe('/cms/posts/hello');
317
- });
318
-
319
- it('buildContentItems uses adminPath for new draft hrefs', () => {
320
- const items = buildContentItems(
321
- [],
322
- [
323
- {
324
- id: 'abc',
325
- collection: 'posts',
326
- filename: null,
327
- isNew: true,
328
- formData: { title: 'Draft' },
329
- body: '',
330
- snapshot: null,
331
- createdAt: new Date().toISOString(),
332
- },
333
- ],
334
- {},
335
- 'posts',
336
- );
337
- expect(items[0].href).toBe('/cms/posts/draft-abc');
338
- });
339
-
340
- it('handleDeleteDraft navigates with custom basePath for new draft', async () => {
341
- mockGetEditorFile.mockReturnValue({
342
- filename: null,
343
- isNewDraft: true,
344
- formData: {},
345
- });
346
- await handleDeleteDraft('posts');
347
- expect(mockNavigate).toHaveBeenCalledWith('/cms/posts');
348
- });
349
-
350
- it('handleDeleteDraft navigates with custom basePath for live file', async () => {
351
- mockGetEditorFile.mockReturnValue({
352
- filename: 'my-post.md',
353
- isNewDraft: false,
354
- formData: {},
355
- });
356
- await handleDeleteDraft('posts');
357
- expect(mockNavigate).toHaveBeenCalledWith('/cms/posts/my-post');
358
- });
359
- });
360
-
361
- describe('handlers with root basePath (/)', () => {
362
- beforeEach(() => {
363
- vi.clearAllMocks();
364
- mockRefreshDrafts.mockResolvedValue(undefined);
365
- mockDeleteCurrentDraft.mockResolvedValue(undefined);
366
- // Root basePath — the bug scenario where paths got double-slashed
367
- mockAdminPath.mockImplementation((...segments: string[]) =>
368
- segments.length === 0 ? '/' : '/' + segments.join('/'),
369
- );
370
- });
371
-
372
- it('buildContentItems produces single-slash hrefs for live items', () => {
373
- const items = buildContentItems(
374
- [{ filename: 'hello.md', data: { title: 'Hello' } }],
375
- [],
376
- {},
377
- 'posts',
378
- );
379
- expect(items[0].href).toBe('/posts/hello');
380
- });
381
-
382
- it('buildContentItems produces single-slash hrefs for new drafts', () => {
383
- const items = buildContentItems(
384
- [],
385
- [
386
- {
387
- id: 'abc',
388
- collection: 'posts',
389
- filename: null,
390
- isNew: true,
391
- formData: { title: 'Draft' },
392
- body: '',
393
- snapshot: null,
394
- createdAt: new Date().toISOString(),
395
- },
396
- ],
397
- {},
398
- 'posts',
399
- );
400
- expect(items[0].href).toBe('/posts/draft-abc');
401
- });
402
-
403
- it('handleDeleteDraft navigates to /posts (not //posts) for new draft', async () => {
404
- mockGetEditorFile.mockReturnValue({
405
- filename: null,
406
- isNewDraft: true,
407
- formData: {},
408
- });
409
- await handleDeleteDraft('posts');
410
- expect(mockNavigate).toHaveBeenCalledWith('/posts');
411
- });
412
-
413
- it('handleDeleteDraft navigates to /posts/my-post (not //posts/my-post) for live file', async () => {
414
- mockGetEditorFile.mockReturnValue({
415
- filename: 'my-post.md',
416
- isNewDraft: false,
417
- formData: {},
418
- });
419
- await handleDeleteDraft('posts');
420
- expect(mockNavigate).toHaveBeenCalledWith('/posts/my-post');
421
- });
422
- });
423
-
424
- describe('computePublishDisabled', () => {
425
- it('returns true when schema is null', () => {
426
- expect(computePublishDisabled(null, {})).toBe(true);
427
- });
428
-
429
- it('returns false when schema has no required array', () => {
430
- expect(computePublishDisabled({ title: 'Schema' }, {})).toBe(false);
431
- });
432
-
433
- it('returns false when all required fields are populated', () => {
434
- const schema = { required: ['title', 'date'] };
435
- const formData = { title: 'Hello', date: '2026-01-01' };
436
- expect(computePublishDisabled(schema, formData)).toBe(false);
437
- });
438
-
439
- it('returns true when a required field is undefined', () => {
440
- const schema = { required: ['title', 'date'] };
441
- const formData = { title: 'Hello' };
442
- expect(computePublishDisabled(schema, formData)).toBe(true);
443
- });
444
-
445
- it('returns true when a required field is null', () => {
446
- const schema = { required: ['title'] };
447
- const formData = { title: null };
448
- expect(computePublishDisabled(schema, formData)).toBe(true);
449
- });
450
-
451
- it('returns true when a required field is an empty string', () => {
452
- const schema = { required: ['title'] };
453
- const formData = { title: '' };
454
- expect(computePublishDisabled(schema, formData)).toBe(true);
455
- });
456
-
457
- it('returns false when required is an empty array', () => {
458
- const schema = { required: [] };
459
- expect(computePublishDisabled(schema, {})).toBe(false);
460
- });
461
-
462
- it('returns true when only some required fields are missing', () => {
463
- const schema = { required: ['title', 'date', 'author'] };
464
- const formData = { title: 'T', author: 'A' };
465
- expect(computePublishDisabled(schema, formData)).toBe(true);
466
- });
467
- });