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
@@ -0,0 +1,100 @@
1
+ /*
2
+ * YAML Parser Worker
3
+ *
4
+ * Handles YAML parsing and serialization on behalf of the main thread.
5
+ * Messages are dispatched by type: 'parse', 'parse-batch', 'stringify'.
6
+ * Each handler wraps its logic in try/catch and always posts a typed result.
7
+ */
8
+ import { load, dump } from 'js-yaml';
9
+ /*
10
+ //////////////////////////////
11
+ // Message handler
12
+ //////////////////////////////
13
+ */
14
+ /**
15
+ * Handles a single YAML parse request. Parses the provided content string
16
+ * and posts a parse-result message with the resulting data object or error.
17
+ * @param {ParseMessage} msg - The inbound parse message
18
+ * @return {void}
19
+ */
20
+ function handleParse(msg) {
21
+ try {
22
+ const data = load(msg.content);
23
+ self.postMessage({ type: 'parse-result', id: msg.id, ok: true, data });
24
+ }
25
+ catch (err) {
26
+ const error = err instanceof Error ? err.message : String(err);
27
+ self.postMessage({ type: 'parse-result', id: msg.id, ok: false, error });
28
+ }
29
+ }
30
+ /**
31
+ * Handles a batch YAML parse request. Iterates over all items, parses each
32
+ * one, and posts a parse-batch-result with a key-to-data results map.
33
+ * If any item fails to parse, the entire batch result is marked as failed.
34
+ * @param {ParseBatchMessage} msg - The inbound parse-batch message
35
+ * @return {void}
36
+ */
37
+ function handleParseBatch(msg) {
38
+ try {
39
+ const results = {};
40
+ for (const item of msg.items) {
41
+ results[item.key] = load(item.content);
42
+ }
43
+ self.postMessage({
44
+ type: 'parse-batch-result',
45
+ id: msg.id,
46
+ ok: true,
47
+ results,
48
+ });
49
+ }
50
+ catch (err) {
51
+ const error = err instanceof Error ? err.message : String(err);
52
+ self.postMessage({
53
+ type: 'parse-batch-result',
54
+ id: msg.id,
55
+ ok: false,
56
+ error,
57
+ });
58
+ }
59
+ }
60
+ /**
61
+ * Handles a YAML stringify request. Serializes the provided data object to
62
+ * a YAML string and posts a stringify-result message with the content.
63
+ * lineWidth: -1 disables js-yaml's automatic line folding so long values
64
+ * are not wrapped across lines, which would corrupt multi-line string values.
65
+ * @param {StringifyMessage} msg - The inbound stringify message
66
+ * @return {void}
67
+ */
68
+ function handleStringify(msg) {
69
+ try {
70
+ const content = dump(msg.data, { lineWidth: -1 });
71
+ self.postMessage({
72
+ type: 'stringify-result',
73
+ id: msg.id,
74
+ ok: true,
75
+ content,
76
+ });
77
+ }
78
+ catch (err) {
79
+ const error = err instanceof Error ? err.message : String(err);
80
+ self.postMessage({
81
+ type: 'stringify-result',
82
+ id: msg.id,
83
+ ok: false,
84
+ error,
85
+ });
86
+ }
87
+ }
88
+ // Listen for messages from the main thread and dispatch by type
89
+ self.addEventListener('message', (event) => {
90
+ const msg = event.data;
91
+ if (msg.type === 'parse') {
92
+ handleParse(msg);
93
+ }
94
+ else if (msg.type === 'parse-batch') {
95
+ handleParseBatch(msg);
96
+ }
97
+ else if (msg.type === 'stringify') {
98
+ handleStringify(msg);
99
+ }
100
+ });
@@ -0,0 +1,58 @@
1
+ export type FileTypeConfig = {
2
+ extensions: string[];
3
+ hasBody: boolean;
4
+ category: 'frontmatter' | 'data';
5
+ dataFormat?: 'json' | 'yaml' | 'toml';
6
+ };
7
+ export declare const FILE_TYPES: Record<string, FileTypeConfig>;
8
+ /**
9
+ * Resolves a schema's `files` array of type identifiers to a flat list of file extensions.
10
+ * Used by storage adapters for file discovery filtering.
11
+ * @param {Record<string, unknown>} schema - A collection JSON Schema with an optional `files` array
12
+ * @return {string[]} Ordered list of extensions (e.g. ['.md', '.markdown', '.json'])
13
+ */
14
+ export declare function getExtensionsForSchema(schema: Record<string, unknown>): string[];
15
+ /**
16
+ * Returns whether a file should show the body editor panel.
17
+ * True for markdown, MDX, and Markdoc files; false for pure data files.
18
+ * @param {string} filename - The filename to check
19
+ * @return {boolean} True if the file type has a body editor
20
+ */
21
+ export declare function hasBodyEditor(filename: string): boolean;
22
+ /**
23
+ * Returns the category of a file based on its extension.
24
+ * Used to determine whether to render frontmatter fields or data-only fields.
25
+ * @param {string} filename - The filename to categorise
26
+ * @return {'frontmatter' | 'data' | null} The file category, or null for unrecognised extensions
27
+ */
28
+ export declare function getFileCategory(filename: string): 'frontmatter' | 'data' | null;
29
+ /**
30
+ * Returns the serialization format for a data file.
31
+ * Returns null for frontmatter files and unrecognised extensions.
32
+ * @param {string} filename - The filename to inspect
33
+ * @return {'json' | 'yaml' | 'toml' | null} The data format, or null if not a data file
34
+ */
35
+ export declare function getDataFormat(filename: string): 'json' | 'yaml' | 'toml' | null;
36
+ /**
37
+ * Strips the file extension from a filename when the extension is a known type.
38
+ * Returns the filename unchanged if the extension is not recognised.
39
+ * Used for generating URL slugs from filenames.
40
+ * @param {string} filename - The filename to strip the extension from
41
+ * @return {string} The filename without its known extension, or the original filename
42
+ */
43
+ export declare function stripExtension(filename: string): string;
44
+ /**
45
+ * Returns the default (first) file extension for a given type identifier.
46
+ * Used when creating new files to pick the canonical extension for a format.
47
+ * @param {string} type - A type identifier (e.g. 'md', 'yaml', 'toml')
48
+ * @return {string | null} The default extension including the leading dot, or null for unknown types
49
+ */
50
+ export declare function getDefaultExtension(type: string): string | null;
51
+ /**
52
+ * Returns the type identifier for a given filename by looking up its extension.
53
+ * Used when the active file's type must be determined for the format selector.
54
+ * @param {string} filename - The filename to look up
55
+ * @return {string | null} The type identifier (e.g. 'md', 'yaml'), or null for unrecognised extensions
56
+ */
57
+ export declare function getTypeForFilename(filename: string): string | null;
58
+ //# sourceMappingURL=file-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-types.d.ts","sourceRoot":"","sources":["../../../../src/client/js/utils/file-types.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,cAAc,GAAG;IAE3B,UAAU,EAAE,MAAM,EAAE,CAAC;IAErB,OAAO,EAAE,OAAO,CAAC;IAEjB,QAAQ,EAAE,aAAa,GAAG,MAAM,CAAC;IAEjC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CACvC,CAAC;AAGF,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAkCrD,CAAC;AA6CF;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,EAAE,CAYV;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGvD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,GACf,aAAa,GAAG,MAAM,GAAG,IAAI,CAG/B;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAGjC;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMvD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE/D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAElE"}
@@ -4,158 +4,128 @@
4
4
  * (storage adapters, orchestrator worker, editor, publish handler) derive
5
5
  * extension lists, category, and serialization format from this registry.
6
6
  */
7
-
8
- // Configuration for a single supported file type.
9
- export type FileTypeConfig = {
10
- // All file extensions associated with this type, first entry is the default.
11
- extensions: string[];
12
- // Whether this type has a body editor (markdown/MDX/Markdoc).
13
- hasBody: boolean;
14
- // Whether the file holds frontmatter+body or pure data.
15
- category: 'frontmatter' | 'data';
16
- // For data files, which serialization format to use.
17
- dataFormat?: 'json' | 'yaml' | 'toml';
18
- };
19
-
20
7
  // Registry mapping type identifiers (as used in schema `files` arrays) to their config.
21
- export const FILE_TYPES: Record<string, FileTypeConfig> = {
22
- md: {
23
- extensions: ['.md', '.markdown'],
24
- hasBody: true,
25
- category: 'frontmatter',
26
- },
27
- mdx: {
28
- extensions: ['.mdx'],
29
- hasBody: true,
30
- category: 'frontmatter',
31
- },
32
- markdoc: {
33
- extensions: ['.mdoc', '.markdoc'],
34
- hasBody: true,
35
- category: 'frontmatter',
36
- },
37
- json: {
38
- extensions: ['.json'],
39
- hasBody: false,
40
- category: 'data',
41
- dataFormat: 'json',
42
- },
43
- yaml: {
44
- extensions: ['.yml', '.yaml'],
45
- hasBody: false,
46
- category: 'data',
47
- dataFormat: 'yaml',
48
- },
49
- toml: {
50
- extensions: ['.toml'],
51
- hasBody: false,
52
- category: 'data',
53
- dataFormat: 'toml',
54
- },
8
+ export const FILE_TYPES = {
9
+ md: {
10
+ extensions: ['.md', '.markdown'],
11
+ hasBody: true,
12
+ category: 'frontmatter',
13
+ },
14
+ mdx: {
15
+ extensions: ['.mdx'],
16
+ hasBody: true,
17
+ category: 'frontmatter',
18
+ },
19
+ markdoc: {
20
+ extensions: ['.mdoc', '.markdoc'],
21
+ hasBody: true,
22
+ category: 'frontmatter',
23
+ },
24
+ json: {
25
+ extensions: ['.json'],
26
+ hasBody: false,
27
+ category: 'data',
28
+ dataFormat: 'json',
29
+ },
30
+ yaml: {
31
+ extensions: ['.yml', '.yaml'],
32
+ hasBody: false,
33
+ category: 'data',
34
+ dataFormat: 'yaml',
35
+ },
36
+ toml: {
37
+ extensions: ['.toml'],
38
+ hasBody: false,
39
+ category: 'data',
40
+ dataFormat: 'toml',
41
+ },
55
42
  };
56
-
57
43
  /*
58
44
  //////////////////////////////
59
45
  // Extension reverse-lookup map
60
46
  // Built once at module load for O(1) extension-to-config lookups.
61
47
  //////////////////////////////
62
48
  */
63
-
64
49
  // Maps each known extension to its FileTypeConfig.
65
- const extensionMap = new Map<string, FileTypeConfig>();
66
-
50
+ const extensionMap = new Map();
67
51
  // Maps each known extension to its type identifier (e.g. '.md' -> 'md').
68
- const extensionToTypeID = new Map<string, string>();
69
-
52
+ const extensionToTypeID = new Map();
70
53
  for (const [typeId, config] of Object.entries(FILE_TYPES)) {
71
- for (const ext of config.extensions) {
72
- extensionMap.set(ext, config);
73
- extensionToTypeID.set(ext, typeId);
74
- }
54
+ for (const ext of config.extensions) {
55
+ extensionMap.set(ext, config);
56
+ extensionToTypeID.set(ext, typeId);
57
+ }
75
58
  }
76
-
77
59
  /*
78
60
  //////////////////////////////
79
61
  // Helper: extract extension
80
62
  //////////////////////////////
81
63
  */
82
-
83
64
  /**
84
65
  * Extracts the last dot-prefixed extension from a filename, or an empty string if none.
85
66
  * @param {string} filename - The filename to extract the extension from
86
67
  * @return {string} The extension including the leading dot (e.g. '.md'), or ''
87
68
  */
88
- function getExtension(filename: string): string {
89
- const idx = filename.lastIndexOf('.');
90
- if (idx === -1) return '';
91
- return filename.slice(idx);
69
+ function getExtension(filename) {
70
+ const idx = filename.lastIndexOf('.');
71
+ if (idx === -1)
72
+ return '';
73
+ return filename.slice(idx);
92
74
  }
93
-
94
75
  /*
95
76
  //////////////////////////////
96
77
  // Exported helpers
97
78
  //////////////////////////////
98
79
  */
99
-
100
80
  /**
101
81
  * Resolves a schema's `files` array of type identifiers to a flat list of file extensions.
102
82
  * Used by storage adapters for file discovery filtering.
103
83
  * @param {Record<string, unknown>} schema - A collection JSON Schema with an optional `files` array
104
84
  * @return {string[]} Ordered list of extensions (e.g. ['.md', '.markdown', '.json'])
105
85
  */
106
- export function getExtensionsForSchema(
107
- schema: Record<string, unknown>,
108
- ): string[] {
109
- const files = schema['files'];
110
- if (!Array.isArray(files)) return [];
111
-
112
- const extensions: string[] = [];
113
- for (const typeId of files as string[]) {
114
- const config = FILE_TYPES[typeId];
115
- if (config) {
116
- extensions.push(...config.extensions);
86
+ export function getExtensionsForSchema(schema) {
87
+ const files = schema['files'];
88
+ if (!Array.isArray(files))
89
+ return [];
90
+ const extensions = [];
91
+ for (const typeId of files) {
92
+ const config = FILE_TYPES[typeId];
93
+ if (config) {
94
+ extensions.push(...config.extensions);
95
+ }
117
96
  }
118
- }
119
- return extensions;
97
+ return extensions;
120
98
  }
121
-
122
99
  /**
123
100
  * Returns whether a file should show the body editor panel.
124
101
  * True for markdown, MDX, and Markdoc files; false for pure data files.
125
102
  * @param {string} filename - The filename to check
126
103
  * @return {boolean} True if the file type has a body editor
127
104
  */
128
- export function hasBodyEditor(filename: string): boolean {
129
- const config = extensionMap.get(getExtension(filename));
130
- return config?.hasBody ?? false;
105
+ export function hasBodyEditor(filename) {
106
+ const config = extensionMap.get(getExtension(filename));
107
+ return config?.hasBody ?? false;
131
108
  }
132
-
133
109
  /**
134
110
  * Returns the category of a file based on its extension.
135
111
  * Used to determine whether to render frontmatter fields or data-only fields.
136
112
  * @param {string} filename - The filename to categorise
137
113
  * @return {'frontmatter' | 'data' | null} The file category, or null for unrecognised extensions
138
114
  */
139
- export function getFileCategory(
140
- filename: string,
141
- ): 'frontmatter' | 'data' | null {
142
- const config = extensionMap.get(getExtension(filename));
143
- return config?.category ?? null;
115
+ export function getFileCategory(filename) {
116
+ const config = extensionMap.get(getExtension(filename));
117
+ return config?.category ?? null;
144
118
  }
145
-
146
119
  /**
147
120
  * Returns the serialization format for a data file.
148
121
  * Returns null for frontmatter files and unrecognised extensions.
149
122
  * @param {string} filename - The filename to inspect
150
123
  * @return {'json' | 'yaml' | 'toml' | null} The data format, or null if not a data file
151
124
  */
152
- export function getDataFormat(
153
- filename: string,
154
- ): 'json' | 'yaml' | 'toml' | null {
155
- const config = extensionMap.get(getExtension(filename));
156
- return config?.dataFormat ?? null;
125
+ export function getDataFormat(filename) {
126
+ const config = extensionMap.get(getExtension(filename));
127
+ return config?.dataFormat ?? null;
157
128
  }
158
-
159
129
  /**
160
130
  * Strips the file extension from a filename when the extension is a known type.
161
131
  * Returns the filename unchanged if the extension is not recognised.
@@ -163,30 +133,28 @@ export function getDataFormat(
163
133
  * @param {string} filename - The filename to strip the extension from
164
134
  * @return {string} The filename without its known extension, or the original filename
165
135
  */
166
- export function stripExtension(filename: string): string {
167
- const ext = getExtension(filename);
168
- if (ext && extensionMap.has(ext)) {
169
- return filename.slice(0, filename.length - ext.length);
170
- }
171
- return filename;
136
+ export function stripExtension(filename) {
137
+ const ext = getExtension(filename);
138
+ if (ext && extensionMap.has(ext)) {
139
+ return filename.slice(0, filename.length - ext.length);
140
+ }
141
+ return filename;
172
142
  }
173
-
174
143
  /**
175
144
  * Returns the default (first) file extension for a given type identifier.
176
145
  * Used when creating new files to pick the canonical extension for a format.
177
146
  * @param {string} type - A type identifier (e.g. 'md', 'yaml', 'toml')
178
147
  * @return {string | null} The default extension including the leading dot, or null for unknown types
179
148
  */
180
- export function getDefaultExtension(type: string): string | null {
181
- return FILE_TYPES[type]?.extensions[0] ?? null;
149
+ export function getDefaultExtension(type) {
150
+ return FILE_TYPES[type]?.extensions[0] ?? null;
182
151
  }
183
-
184
152
  /**
185
153
  * Returns the type identifier for a given filename by looking up its extension.
186
154
  * Used when the active file's type must be determined for the format selector.
187
155
  * @param {string} filename - The filename to look up
188
156
  * @return {string | null} The type identifier (e.g. 'md', 'yaml'), or null for unrecognised extensions
189
157
  */
190
- export function getTypeForFilename(filename: string): string | null {
191
- return extensionToTypeID.get(getExtension(filename)) ?? null;
158
+ export function getTypeForFilename(filename) {
159
+ return extensionToTypeID.get(getExtension(filename)) ?? null;
192
160
  }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Converts a property name string to Title Case for display in form labels.
3
+ * Splits on camelCase boundaries, hyphens, and underscores, then capitalizes each word.
4
+ * @param {string} str - The raw property name to convert (e.g., "firstName", "last-name", "zip_code")
5
+ * @return {string} The title-cased display string (e.g., "First Name", "Last Name", "Zip Code")
6
+ */
7
+ export declare function toTitleCase(str: string): string;
8
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../../src/client/js/utils/format.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK/C"}
@@ -1,16 +1,15 @@
1
1
  /*
2
2
  * Display formatting utilities for property names and labels.
3
3
  */
4
-
5
4
  /**
6
5
  * Converts a property name string to Title Case for display in form labels.
7
6
  * Splits on camelCase boundaries, hyphens, and underscores, then capitalizes each word.
8
7
  * @param {string} str - The raw property name to convert (e.g., "firstName", "last-name", "zip_code")
9
8
  * @return {string} The title-cased display string (e.g., "First Name", "Last Name", "Zip Code")
10
9
  */
11
- export function toTitleCase(str: string): string {
12
- return str
13
- .replace(/([a-z])([A-Z])/g, '$1 $2')
14
- .replace(/[-_]/g, ' ')
15
- .replace(/\b\w/g, (c) => c.toUpperCase());
10
+ export function toTitleCase(str) {
11
+ return str
12
+ .replace(/([a-z])([A-Z])/g, '$1 $2')
13
+ .replace(/[-_]/g, ' ')
14
+ .replace(/\b\w/g, (c) => c.toUpperCase());
16
15
  }
@@ -0,0 +1,12 @@
1
+ export type SplitResult = {
2
+ rawFrontmatter: string;
3
+ body: string;
4
+ };
5
+ /**
6
+ * Splits a markdown/MDX file into raw YAML frontmatter and body content.
7
+ * Handles BOM stripping, CRLF normalization, and horizontal rule rejection.
8
+ * @param {string} content - Raw file content
9
+ * @return {SplitResult} The separated frontmatter and body strings
10
+ */
11
+ export declare function splitFrontmatter(content: string): SplitResult;
12
+ //# sourceMappingURL=frontmatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../../../src/client/js/utils/frontmatter.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,WAAW,GAAG;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAyB7D"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Splits a markdown/MDX file into raw YAML frontmatter and body content.
3
+ * Handles BOM stripping, CRLF normalization, and horizontal rule rejection.
4
+ * @param {string} content - Raw file content
5
+ * @return {SplitResult} The separated frontmatter and body strings
6
+ */
7
+ export function splitFrontmatter(content) {
8
+ let str = content.startsWith('\uFEFF') ? content.slice(1) : content;
9
+ str = str.replace(/\r\n/g, '\n');
10
+ // Reject horizontal rules (----) and content not starting with frontmatter delimiter
11
+ if (str.startsWith('----') || !str.startsWith('---\n')) {
12
+ return { rawFrontmatter: '', body: str };
13
+ }
14
+ const closeIndex = str.indexOf('\n---\n', 3);
15
+ if (closeIndex === -1) {
16
+ // Check for --- at end of file with no trailing newline
17
+ if (str.endsWith('\n---')) {
18
+ return {
19
+ rawFrontmatter: str.slice(4, str.length - 4),
20
+ body: '',
21
+ };
22
+ }
23
+ return { rawFrontmatter: '', body: str };
24
+ }
25
+ return {
26
+ rawFrontmatter: str.slice(4, closeIndex),
27
+ body: str.slice(closeIndex + 5),
28
+ };
29
+ }
@@ -0,0 +1,110 @@
1
+ export type SchemaNode = Record<string, unknown>;
2
+ /**
3
+ * Discriminated union describing the resolved type of a schema field. All variants carry an optional `nullable` flag set when the field was expressed as `anyOf: [<type>, { type: 'null' }]`.
4
+ */
5
+ export type FieldType = {
6
+ kind: 'string';
7
+ nullable?: boolean;
8
+ } | {
9
+ kind: 'number';
10
+ nullable?: boolean;
11
+ } | {
12
+ kind: 'boolean';
13
+ nullable?: boolean;
14
+ } | {
15
+ kind: 'date';
16
+ nullable?: boolean;
17
+ } | {
18
+ kind: 'enum';
19
+ options: string[];
20
+ nullable?: boolean;
21
+ } | {
22
+ kind: 'array';
23
+ nullable?: boolean;
24
+ } | {
25
+ kind: 'object';
26
+ nullable?: boolean;
27
+ } | {
28
+ kind: 'unknown';
29
+ nullable?: boolean;
30
+ };
31
+ /**
32
+ * A path segment used to address nested values. Strings address object keys; numbers address array indices.
33
+ */
34
+ export type PathSegment = string | number;
35
+ /**
36
+ * Resolves a JSON Schema node to a `FieldType` discriminated union.
37
+ * Handles anyOf nullable unwrapping, enum detection, and date-time format.
38
+ * @param {SchemaNode} schema - The JSON Schema node to resolve
39
+ * @return {FieldType} The resolved field type descriptor
40
+ */
41
+ export declare function resolveFieldType(schema: SchemaNode): FieldType;
42
+ /**
43
+ * Scans an object schema's properties for `tab` arrays and returns a sorted, deduplicated list of all tab names found.
44
+ * @param {SchemaNode} schema - A JSON Schema node with an optional `properties` map
45
+ * @return {string[]} Sorted, deduplicated list of tab names
46
+ */
47
+ export declare function extractTabs(schema: SchemaNode): string[];
48
+ /**
49
+ * Returns a type-appropriate default value for a given JSON Schema node.
50
+ * Honors `schema.default` when present, returns null for nullable types, and recurses into object properties.
51
+ * @param {SchemaNode} schema - The JSON Schema node to generate a default value for
52
+ * @return {unknown} A default value appropriate for the schema type
53
+ */
54
+ export declare function createDefaultValue(schema: SchemaNode): unknown;
55
+ /**
56
+ * Reads a deeply nested value from an object by following path segments.
57
+ * Returns `undefined` if any segment along the path is missing.
58
+ * @param {unknown} obj - The root object to traverse
59
+ * @param {PathSegment[]} path - Ordered path segments (string keys or numeric indices)
60
+ * @return {unknown} The value at the resolved path, or undefined if any segment is missing
61
+ */
62
+ export declare function getByPath(obj: unknown, path: PathSegment[]): unknown;
63
+ /**
64
+ * Sets a deeply nested value in an object by following path segments, creating intermediate objects as needed.
65
+ * @param {unknown} obj - The root object to mutate
66
+ * @param {PathSegment[]} path - Ordered path segments (string keys or numeric indices)
67
+ * @param {unknown} value - The value to assign at the resolved path
68
+ * @return {void}
69
+ */
70
+ export declare function setByPath(obj: unknown, path: PathSegment[], value: unknown): void;
71
+ /**
72
+ * Returns property names from a schema that belong to the given tab.
73
+ * When `tab` is `null`, all property names are returned (no filtering — every field appears in the catch-all Metadata view).
74
+ * @param {SchemaNode} schema - A JSON Schema node with an optional `properties` map
75
+ * @param {string | null} tab - Tab name to filter by, or `null` to return all fields
76
+ * @return {string[]} Array of property names belonging to the specified tab
77
+ */
78
+ export declare function getFieldsForTab(schema: SchemaNode, tab: string | null): string[];
79
+ /**
80
+ * Extracts the `properties` map from a schema node, with a safe cast.
81
+ * @param {SchemaNode} schema - A JSON Schema node
82
+ * @return {Record<string, SchemaNode> | undefined} The properties map, or undefined if absent
83
+ */
84
+ export declare function getProperties(schema: SchemaNode): Record<string, SchemaNode> | undefined;
85
+ /**
86
+ * Extracts the `required` array from a schema node, returning an empty array if absent.
87
+ * @param {SchemaNode} schema - A JSON Schema node
88
+ * @return {string[]} Array of required property names
89
+ */
90
+ export declare function getRequiredFields(schema: SchemaNode): string[];
91
+ /**
92
+ * Returns whether a schema node is marked as read-only.
93
+ * @param {SchemaNode} schema - A JSON Schema node
94
+ * @return {boolean} True if the schema has readOnly set to true
95
+ */
96
+ export declare function isReadOnly(schema: SchemaNode): boolean;
97
+ /**
98
+ * Returns whether a schema node was unwrapped from a nullable anyOf and flagged as nullable by SchemaField.
99
+ * @param {SchemaNode} schema - A JSON Schema node (possibly annotated with _nullable)
100
+ * @return {boolean} True if the schema has the _nullable annotation
101
+ */
102
+ export declare function isNullable(schema: SchemaNode): boolean;
103
+ /**
104
+ * Returns the display label for a schema field — the schema title if present, otherwise the property name converted to title case.
105
+ * @param {SchemaNode} schema - A JSON Schema node
106
+ * @param {string} name - The raw property name used as a fallback
107
+ * @return {string} The human-readable label
108
+ */
109
+ export declare function getLabel(schema: SchemaNode, name: string): string;
110
+ //# sourceMappingURL=schema-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-utils.d.ts","sourceRoot":"","sources":["../../../../src/client/js/utils/schema-utils.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE5C;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;AAQ1C;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAgC9D;AAQD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,EAAE,CAgBxD;AAQD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CA+B9D;AAQD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,OAAO,CAOpE;AAQD;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,WAAW,EAAE,EACnB,KAAK,EAAE,OAAO,GACb,IAAI,CAeN;AAQD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,MAAM,GAAG,IAAI,GACjB,MAAM,EAAE,CAiBV;AAQD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,UAAU,GACjB,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,SAAS,CAExC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,EAAE,CAI9D;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAEtD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjE"}