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
@@ -0,0 +1,242 @@
1
+ /*
2
+ * Utilities for reading and resolving JSON Schema nodes.
3
+ * Provides type resolution, path traversal, tab extraction, and
4
+ * convenience accessors for common schema annotations.
5
+ */
6
+ import { toTitleCase } from './format';
7
+ /*
8
+ //////////////////////////////
9
+ // resolveFieldType
10
+ //////////////////////////////
11
+ */
12
+ /**
13
+ * Resolves a JSON Schema node to a `FieldType` discriminated union.
14
+ * Handles anyOf nullable unwrapping, enum detection, and date-time format.
15
+ * @param {SchemaNode} schema - The JSON Schema node to resolve
16
+ * @return {FieldType} The resolved field type descriptor
17
+ */
18
+ export function resolveFieldType(schema) {
19
+ // Unwrap nullable anyOf: [<innerType>, { type: 'null' }]
20
+ const anyOf = schema['anyOf'];
21
+ if (Array.isArray(anyOf)) {
22
+ const nonNull = anyOf.find((s) => s['type'] !== 'null');
23
+ if (nonNull) {
24
+ const inner = resolveFieldType(nonNull);
25
+ return { ...inner, nullable: true };
26
+ }
27
+ }
28
+ const type = schema['type'];
29
+ const format = schema['format'];
30
+ const enumValues = schema['enum'];
31
+ // date-time format takes precedence over plain string
32
+ if (type === 'string' && format === 'date-time') {
33
+ return { kind: 'date' };
34
+ }
35
+ // enum values present — treat as enum regardless of string subtype
36
+ if (type === 'string' && Array.isArray(enumValues)) {
37
+ return { kind: 'enum', options: enumValues };
38
+ }
39
+ if (type === 'string')
40
+ return { kind: 'string' };
41
+ if (type === 'number' || type === 'integer')
42
+ return { kind: 'number' };
43
+ if (type === 'boolean')
44
+ return { kind: 'boolean' };
45
+ if (type === 'array')
46
+ return { kind: 'array' };
47
+ if (type === 'object')
48
+ return { kind: 'object' };
49
+ return { kind: 'unknown' };
50
+ }
51
+ /*
52
+ //////////////////////////////
53
+ // extractTabs
54
+ //////////////////////////////
55
+ */
56
+ /**
57
+ * Scans an object schema's properties for `tab` arrays and returns a sorted, deduplicated list of all tab names found.
58
+ * @param {SchemaNode} schema - A JSON Schema node with an optional `properties` map
59
+ * @return {string[]} Sorted, deduplicated list of tab names
60
+ */
61
+ export function extractTabs(schema) {
62
+ const properties = getProperties(schema);
63
+ if (!properties)
64
+ return [];
65
+ const tabs = new Set();
66
+ for (const field of Object.values(properties)) {
67
+ const tab = field['tab'];
68
+ if (Array.isArray(tab)) {
69
+ for (const name of tab) {
70
+ tabs.add(name);
71
+ }
72
+ }
73
+ }
74
+ return Array.from(tabs).sort();
75
+ }
76
+ /*
77
+ //////////////////////////////
78
+ // createDefaultValue
79
+ //////////////////////////////
80
+ */
81
+ /**
82
+ * Returns a type-appropriate default value for a given JSON Schema node.
83
+ * Honors `schema.default` when present, returns null for nullable types, and recurses into object properties.
84
+ * @param {SchemaNode} schema - The JSON Schema node to generate a default value for
85
+ * @return {unknown} A default value appropriate for the schema type
86
+ */
87
+ export function createDefaultValue(schema) {
88
+ // Honour an explicit schema default first
89
+ if ('default' in schema) {
90
+ return schema['default'];
91
+ }
92
+ // Nullable anyOf — default to null
93
+ const anyOf = schema['anyOf'];
94
+ if (Array.isArray(anyOf)) {
95
+ const hasNull = anyOf.some((s) => s['type'] === 'null');
96
+ if (hasNull)
97
+ return null;
98
+ }
99
+ const type = schema['type'];
100
+ if (type === 'string')
101
+ return '';
102
+ if (type === 'number' || type === 'integer')
103
+ return 0;
104
+ if (type === 'boolean')
105
+ return false;
106
+ if (type === 'array')
107
+ return [];
108
+ if (type === 'object') {
109
+ const properties = getProperties(schema);
110
+ if (!properties)
111
+ return {};
112
+ const result = {};
113
+ for (const [key, fieldSchema] of Object.entries(properties)) {
114
+ result[key] = createDefaultValue(fieldSchema);
115
+ }
116
+ return result;
117
+ }
118
+ return null;
119
+ }
120
+ /*
121
+ //////////////////////////////
122
+ // getByPath
123
+ //////////////////////////////
124
+ */
125
+ /**
126
+ * Reads a deeply nested value from an object by following path segments.
127
+ * Returns `undefined` if any segment along the path is missing.
128
+ * @param {unknown} obj - The root object to traverse
129
+ * @param {PathSegment[]} path - Ordered path segments (string keys or numeric indices)
130
+ * @return {unknown} The value at the resolved path, or undefined if any segment is missing
131
+ */
132
+ export function getByPath(obj, path) {
133
+ let current = obj;
134
+ for (const segment of path) {
135
+ if (current === null || current === undefined)
136
+ return undefined;
137
+ current = current[segment];
138
+ }
139
+ return current;
140
+ }
141
+ /*
142
+ //////////////////////////////
143
+ // setByPath
144
+ //////////////////////////////
145
+ */
146
+ /**
147
+ * Sets a deeply nested value in an object by following path segments, creating intermediate objects as needed.
148
+ * @param {unknown} obj - The root object to mutate
149
+ * @param {PathSegment[]} path - Ordered path segments (string keys or numeric indices)
150
+ * @param {unknown} value - The value to assign at the resolved path
151
+ * @return {void}
152
+ */
153
+ export function setByPath(obj, path, value) {
154
+ if (path.length === 0)
155
+ return;
156
+ let current = obj;
157
+ // Walk down to the parent of the final segment, creating objects as needed
158
+ for (let i = 0; i < path.length - 1; i++) {
159
+ const segment = path[i];
160
+ if (current[segment] === null || current[segment] === undefined) {
161
+ current[segment] = {};
162
+ }
163
+ current = current[segment];
164
+ }
165
+ current[path[path.length - 1]] = value;
166
+ }
167
+ /*
168
+ //////////////////////////////
169
+ // getFieldsForTab
170
+ //////////////////////////////
171
+ */
172
+ /**
173
+ * Returns property names from a schema that belong to the given tab.
174
+ * When `tab` is `null`, all property names are returned (no filtering — every field appears in the catch-all Metadata view).
175
+ * @param {SchemaNode} schema - A JSON Schema node with an optional `properties` map
176
+ * @param {string | null} tab - Tab name to filter by, or `null` to return all fields
177
+ * @return {string[]} Array of property names belonging to the specified tab
178
+ */
179
+ export function getFieldsForTab(schema, tab) {
180
+ const properties = getProperties(schema);
181
+ if (!properties)
182
+ return [];
183
+ // Filter out $schema — it's a JSON Schema meta-property that Astro adds
184
+ // to every generated schema, not a user-editable frontmatter field
185
+ const keys = Object.keys(properties).filter((k) => k !== '$schema');
186
+ // null means "all fields" — no tab filtering applied
187
+ if (tab === null) {
188
+ return keys;
189
+ }
190
+ return keys.filter((key) => {
191
+ const fieldTab = properties[key]['tab'];
192
+ return Array.isArray(fieldTab) && fieldTab.includes(tab);
193
+ });
194
+ }
195
+ /*
196
+ //////////////////////////////
197
+ // Schema property accessors
198
+ //////////////////////////////
199
+ */
200
+ /**
201
+ * Extracts the `properties` map from a schema node, with a safe cast.
202
+ * @param {SchemaNode} schema - A JSON Schema node
203
+ * @return {Record<string, SchemaNode> | undefined} The properties map, or undefined if absent
204
+ */
205
+ export function getProperties(schema) {
206
+ return schema['properties'];
207
+ }
208
+ /**
209
+ * Extracts the `required` array from a schema node, returning an empty array if absent.
210
+ * @param {SchemaNode} schema - A JSON Schema node
211
+ * @return {string[]} Array of required property names
212
+ */
213
+ export function getRequiredFields(schema) {
214
+ return Array.isArray(schema['required'])
215
+ ? schema['required']
216
+ : [];
217
+ }
218
+ /**
219
+ * Returns whether a schema node is marked as read-only.
220
+ * @param {SchemaNode} schema - A JSON Schema node
221
+ * @return {boolean} True if the schema has readOnly set to true
222
+ */
223
+ export function isReadOnly(schema) {
224
+ return !!schema['readOnly'];
225
+ }
226
+ /**
227
+ * Returns whether a schema node was unwrapped from a nullable anyOf and flagged as nullable by SchemaField.
228
+ * @param {SchemaNode} schema - A JSON Schema node (possibly annotated with _nullable)
229
+ * @return {boolean} True if the schema has the _nullable annotation
230
+ */
231
+ export function isNullable(schema) {
232
+ return !!schema['_nullable'];
233
+ }
234
+ /**
235
+ * Returns the display label for a schema field — the schema title if present, otherwise the property name converted to title case.
236
+ * @param {SchemaNode} schema - A JSON Schema node
237
+ * @param {string} name - The raw property name used as a fallback
238
+ * @return {string} The human-readable label
239
+ */
240
+ export function getLabel(schema, name) {
241
+ return schema['title'] ?? toTitleCase(name);
242
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Converts a string to a URL-friendly slug.
3
+ * Lowercases, replaces non-alphanumeric characters with hyphens, collapses consecutive hyphens, and trims edge hyphens.
4
+ * @param {string} input - The string to slugify
5
+ * @return {string} A URL-safe slug
6
+ */
7
+ export declare function slugify(input: string): string;
8
+ //# sourceMappingURL=slug.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slug.d.ts","sourceRoot":"","sources":["../../../../src/client/js/utils/slug.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM7C"}
@@ -2,17 +2,16 @@
2
2
  * URL-friendly slug generation without external dependencies.
3
3
  * Replicates the behavior of the `slugify` package with `lower: true, strict: true`.
4
4
  */
5
-
6
5
  /**
7
6
  * Converts a string to a URL-friendly slug.
8
7
  * Lowercases, replaces non-alphanumeric characters with hyphens, collapses consecutive hyphens, and trims edge hyphens.
9
8
  * @param {string} input - The string to slugify
10
9
  * @return {string} A URL-safe slug
11
10
  */
12
- export function slugify(input: string): string {
13
- return input
14
- .toLowerCase()
15
- .replace(/[^a-z0-9-]/g, '-')
16
- .replace(/-{2,}/g, '-')
17
- .replace(/^-|-$/g, '');
11
+ export function slugify(input) {
12
+ return input
13
+ .toLowerCase()
14
+ .replace(/[^a-z0-9-]/g, '-')
15
+ .replace(/-{2,}/g, '-')
16
+ .replace(/^-|-$/g, '');
18
17
  }
@@ -0,0 +1,41 @@
1
+ export type SidebarItem = {
2
+ label: string;
3
+ href: string;
4
+ subtitle?: string;
5
+ date?: Date;
6
+ draftId?: string;
7
+ isDraft?: boolean;
8
+ isOutdated?: boolean;
9
+ };
10
+ export type SortMode = 'alpha' | 'date-asc' | 'date-desc';
11
+ export declare const SORT_MODES: Record<SortMode, {
12
+ icon: string;
13
+ label: string;
14
+ }>;
15
+ export declare const SORT_ORDER: SortMode[];
16
+ /**
17
+ * Reads the persisted sort mode from localStorage, defaulting to 'alpha' if absent or invalid.
18
+ * @param {string} key - Collection name used to construct the storage key
19
+ * @return {SortMode} The persisted sort mode, or 'alpha' if not set
20
+ */
21
+ export declare function readSortMode(key: string): SortMode;
22
+ /**
23
+ * Persists the sort mode to localStorage.
24
+ * @param {string} key - Collection name used to construct the storage key
25
+ * @param {SortMode} mode - The sort mode to persist
26
+ * @return {void}
27
+ */
28
+ export declare function writeSortMode(key: string, mode: SortMode): void;
29
+ /**
30
+ * Coerces a frontmatter published value (Date object or ISO string) into a Date for sorting. Returns undefined if the value is not a recognized date type.
31
+ * @param {unknown} val - The published value from frontmatter
32
+ * @return {Date | undefined} The resolved Date, or undefined
33
+ */
34
+ export declare function toSortDate(val: unknown): Date | undefined;
35
+ /**
36
+ * Returns a comparator function for sorting SidebarItems by the given mode.
37
+ * @param {SortMode} mode - The sort mode to use
38
+ * @return {(a: SidebarItem, b: SidebarItem) => number} A comparator function suitable for Array.sort
39
+ */
40
+ export declare function createComparator(mode: SortMode): (a: SidebarItem, b: SidebarItem) => number;
41
+ //# sourceMappingURL=sort.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sort.d.ts","sourceRoot":"","sources":["../../../../src/client/js/utils/sort.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,IAAI,CAAC;IAEZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAGF,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,WAAW,CAAC;AAG1D,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,QAAQ,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAIxE,CAAC;AAGF,eAAO,MAAM,UAAU,EAAE,QAAQ,EAAuC,CAAC;AAEzE;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAMlD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAE/D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAGzD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,QAAQ,GACb,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,KAAK,MAAM,CAa5C"}
@@ -0,0 +1,65 @@
1
+ /*
2
+ * Sorting utilities and types for admin sidebar content lists.
3
+ * Handles sort mode persistence, date coercion, and comparator generation.
4
+ */
5
+ // Sort mode configuration: icon name and display label
6
+ export const SORT_MODES = {
7
+ alpha: { icon: 'sort_by_alpha', label: 'Alphabetical' },
8
+ 'date-asc': { icon: 'hourglass_arrow_down', label: 'Oldest first' },
9
+ 'date-desc': { icon: 'hourglass_arrow_up', label: 'Newest first' },
10
+ };
11
+ // Fixed display order for sort options in the popover
12
+ export const SORT_ORDER = ['alpha', 'date-asc', 'date-desc'];
13
+ /**
14
+ * Reads the persisted sort mode from localStorage, defaulting to 'alpha' if absent or invalid.
15
+ * @param {string} key - Collection name used to construct the storage key
16
+ * @return {SortMode} The persisted sort mode, or 'alpha' if not set
17
+ */
18
+ export function readSortMode(key) {
19
+ const stored = localStorage.getItem(`cms-sort-${key}`);
20
+ if (stored === 'alpha' || stored === 'date-asc' || stored === 'date-desc') {
21
+ return stored;
22
+ }
23
+ return 'alpha';
24
+ }
25
+ /**
26
+ * Persists the sort mode to localStorage.
27
+ * @param {string} key - Collection name used to construct the storage key
28
+ * @param {SortMode} mode - The sort mode to persist
29
+ * @return {void}
30
+ */
31
+ export function writeSortMode(key, mode) {
32
+ localStorage.setItem(`cms-sort-${key}`, mode);
33
+ }
34
+ /**
35
+ * Coerces a frontmatter published value (Date object or ISO string) into a Date for sorting. Returns undefined if the value is not a recognized date type.
36
+ * @param {unknown} val - The published value from frontmatter
37
+ * @return {Date | undefined} The resolved Date, or undefined
38
+ */
39
+ export function toSortDate(val) {
40
+ if (val instanceof Date)
41
+ return val;
42
+ return typeof val === 'string' ? new Date(val) : undefined;
43
+ }
44
+ /**
45
+ * Returns a comparator function for sorting SidebarItems by the given mode.
46
+ * @param {SortMode} mode - The sort mode to use
47
+ * @return {(a: SidebarItem, b: SidebarItem) => number} A comparator function suitable for Array.sort
48
+ */
49
+ export function createComparator(mode) {
50
+ return (a, b) => {
51
+ if (mode === 'date-asc' || mode === 'date-desc') {
52
+ // Items without a date sort to the top (e.g. new drafts without a published date)
53
+ if (!a.date && !b.date)
54
+ return 0;
55
+ if (!a.date)
56
+ return -1;
57
+ if (!b.date)
58
+ return 1;
59
+ return mode === 'date-asc'
60
+ ? a.date.getTime() - b.date.getTime()
61
+ : b.date.getTime() - a.date.getTime();
62
+ }
63
+ return a.label.toLowerCase().localeCompare(b.label.toLowerCase());
64
+ };
65
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Recursively sorts object keys and serializes to JSON.
3
+ * Produces deterministic output regardless of key insertion order.
4
+ * @param {unknown} value - The value to serialize
5
+ * @return {string} A JSON string with sorted keys at every nesting level
6
+ */
7
+ export declare function stableStringify(value: unknown): string;
8
+ //# sourceMappingURL=stable-stringify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stable-stringify.d.ts","sourceRoot":"","sources":["../../../../src/client/js/utils/stable-stringify.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAetD"}
@@ -0,0 +1,23 @@
1
+ /*
2
+ * Deterministic JSON serialization with sorted keys.
3
+ * Prevents false-positive outdated detection when comparing snapshots.
4
+ */
5
+ /**
6
+ * Recursively sorts object keys and serializes to JSON.
7
+ * Produces deterministic output regardless of key insertion order.
8
+ * @param {unknown} value - The value to serialize
9
+ * @return {string} A JSON string with sorted keys at every nesting level
10
+ */
11
+ export function stableStringify(value) {
12
+ return JSON.stringify(value, (_key, val) => {
13
+ if (val !== null && typeof val === 'object' && !Array.isArray(val)) {
14
+ return Object.keys(val)
15
+ .sort()
16
+ .reduce((sorted, k) => {
17
+ sorted[k] = val[k];
18
+ return sorted;
19
+ }, {});
20
+ }
21
+ return val;
22
+ });
23
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Checks whether a string is a valid URL (absolute with scheme, or absolute path).
3
+ * Used by the smart paste handler to determine whether clipboard content should
4
+ * be auto-wrapped as a markdown link rather than inserted as plain text.
5
+ * Trims whitespace before validating. Rejects plain words and relative paths
6
+ * without a leading slash to avoid false positives on normal text.
7
+ * @param {string} text - The string to validate
8
+ * @return {boolean} True if the text is a valid URL or absolute path
9
+ */
10
+ export declare function isURL(text: string): boolean;
11
+ //# sourceMappingURL=url-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-utils.d.ts","sourceRoot":"","sources":["../../../../src/client/js/utils/url-utils.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAwB3C"}
@@ -1,7 +1,6 @@
1
1
  /*
2
2
  * URL validation utilities for the editor's smart paste handler.
3
3
  */
4
-
5
4
  /**
6
5
  * Checks whether a string is a valid URL (absolute with scheme, or absolute path).
7
6
  * Used by the smart paste handler to determine whether clipboard content should
@@ -11,28 +10,28 @@
11
10
  * @param {string} text - The string to validate
12
11
  * @return {boolean} True if the text is a valid URL or absolute path
13
12
  */
14
- export function isURL(text: string): boolean {
15
- const trimmed = text.trim();
16
- if (!trimmed) return false;
17
-
18
- // Absolute URL with scheme (https://, mailto:, etc.)
19
- try {
20
- new URL(trimmed);
21
- return true;
22
- } catch {
23
- // Not an absolute URL — fall through
24
- }
25
-
26
- // Absolute path starting with /
27
- if (trimmed.startsWith('/')) {
13
+ export function isURL(text) {
14
+ const trimmed = text.trim();
15
+ if (!trimmed)
16
+ return false;
17
+ // Absolute URL with scheme (https://, mailto:, etc.)
28
18
  try {
29
- // Dummy base required by URL constructor to resolve absolute paths
30
- new URL(trimmed, 'https://a.com');
31
- return true;
32
- } catch {
33
- return false;
19
+ new URL(trimmed);
20
+ return true;
34
21
  }
35
- }
36
-
37
- return false;
22
+ catch {
23
+ // Not an absolute URL — fall through
24
+ }
25
+ // Absolute path starting with /
26
+ if (trimmed.startsWith('/')) {
27
+ try {
28
+ // Dummy base required by URL constructor to resolve absolute paths
29
+ new URL(trimmed, 'https://a.com');
30
+ return true;
31
+ }
32
+ catch {
33
+ return false;
34
+ }
35
+ }
36
+ return false;
38
37
  }
@@ -0,0 +1,22 @@
1
+ export interface NebulaCMSConfig {
2
+ /**
3
+ * URL prefix for the admin SPA.
4
+ * Accepts a relative or absolute path. Normalized automatically: leading `/`
5
+ * prepended if missing, consecutive slashes collapsed, trailing `/` stripped.
6
+ * After normalization, must contain only segments of letters, digits, hyphens,
7
+ * and underscores — or be `/` for root mount.
8
+ * @default '/admin'
9
+ */
10
+ basePath?: string;
11
+ /**
12
+ * URL prefix under which collection schema files are served.
13
+ * Accepts a relative or absolute path. Normalized automatically: leading `/`
14
+ * prepended if missing, consecutive slashes collapsed, trailing `/` stripped.
15
+ * After normalization, must contain only segments of letters, digits, hyphens,
16
+ * and underscores. Cannot be `/` (root) — collections require at least one
17
+ * path segment.
18
+ * @default '/collections'
19
+ */
20
+ collectionsPath?: string;
21
+ }
22
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B"}
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "nebula-cms",
3
- "version": "0.1.0",
3
+ "version": "0.1.4",
4
4
  "description": "A native CMS for Astro",
5
5
  "type": "module",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/Snugug/nebula-cms"
9
+ },
6
10
  "exports": {
7
11
  ".": {
8
12
  "types": "./dist/astro/index.d.ts",
@@ -43,6 +47,9 @@
43
47
  "svelte": "^5.0.0"
44
48
  },
45
49
  "author": "Sam Richard<sam@snug.ug>",
50
+ "files": [
51
+ "dist"
52
+ ],
46
53
  "license": "Apache-2.0",
47
54
  "devDependencies": {
48
55
  "@astrojs/svelte": "^8.0.3",
@@ -1,42 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "mcp__plugin_context7_context7__resolve-library-id",
5
- "mcp__plugin_context7_context7__query-docs",
6
- "Bash(pnpm fix:*)",
7
- "Bash(pnpm lint:*)",
8
- "Bash(git add:*)",
9
- "Bash(git commit:*)",
10
- "mcp__plugin_playwright_playwright__browser_navigate",
11
- "mcp__plugin_playwright_playwright__browser_close",
12
- "Bash(git worktree:*)",
13
- "Bash(pnpm test:*)",
14
- "Bash(pnpm sync:*)",
15
- "Bash(pnpm build:*)",
16
- "Bash(ag:*)",
17
- "Bash(git ls-tree:*)",
18
- "Bash(git stash:*)",
19
- "Bash(pnpm vitest:*)",
20
- "mcp__plugin_playwright_playwright__browser_console_messages",
21
- "mcp__plugin_playwright_playwright__browser_click",
22
- "mcp__plugin_playwright_playwright__browser_take_screenshot",
23
- "mcp__plugin_playwright_playwright__browser_snapshot",
24
- "mcp__plugin_playwright_playwright__browser_evaluate",
25
- "WebSearch",
26
- "mcp__playwright__browser_navigate",
27
- "mcp__playwright__browser_take_screenshot",
28
- "mcp__playwright__browser_snapshot",
29
- "mcp__playwright__browser_click",
30
- "mcp__playwright__browser_console_messages",
31
- "mcp__playwright__browser_network_requests",
32
- "Bash(/Users/avalon/.claude/plugins/cache/claude-plugins-official/superpowers/5.0.7/skills/brainstorming/scripts/start-server.sh --project-dir /Users/avalon/Development/nebula-cms)",
33
- "WebFetch(domain:discuss.codemirror.net)",
34
- "Bash(/Users/avalon/.claude/plugins/cache/claude-plugins-official/superpowers/5.0.7/skills/brainstorming/scripts/stop-server.sh /Users/avalon/Development/nebula-cms/.superpowers/brainstorm/53523-1775161916)",
35
- "mcp__playwright__browser_tabs",
36
- "mcp__playwright__browser_select_option",
37
- "Bash(git check-ignore:*)"
38
- ]
39
- },
40
- "enableAllProjectMcpServers": true,
41
- "enabledMcpjsonServers": ["playwright"]
42
- }
@@ -1,31 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- push:
5
- branches: [main]
6
- pull_request:
7
-
8
- jobs:
9
- test:
10
- runs-on: ubuntu-latest
11
- steps:
12
- - uses: actions/checkout@v4
13
-
14
- - uses: pnpm/action-setup@v4
15
-
16
- - uses: actions/setup-node@v4
17
- with:
18
- node-version: 22
19
- cache: pnpm
20
-
21
- - name: Install dependencies
22
- run: pnpm install
23
-
24
- - name: Install Playwright browsers
25
- run: pnpm exec playwright install --with-deps chromium
26
-
27
- - name: Lint
28
- run: pnpm lint
29
-
30
- - name: Test
31
- run: pnpm test
package/.mcp.json DELETED
@@ -1,12 +0,0 @@
1
- {
2
- "mcpServers": {
3
- "playwright": {
4
- "command": "npx",
5
- "args": [
6
- "@playwright/mcp@latest",
7
- "--cdp-endpoint",
8
- "http://localhost:9222"
9
- ]
10
- }
11
- }
12
- }
package/.prettierignore DELETED
@@ -1,5 +0,0 @@
1
- dist
2
- pnpm-lock.yaml
3
- node_modules
4
- .astro
5
- .coverage