domma-cms 0.44.0 → 0.45.1

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 (254) hide show
  1. package/CLAUDE.md +53 -53
  2. package/README.md +27 -27
  3. package/admin/css/admin.css +1 -1
  4. package/admin/dist/domma/domma-tools.css +3 -3
  5. package/admin/dist/domma/domma-tools.min.js +3 -3
  6. package/admin/index.html +2 -2
  7. package/admin/js/app.js +1 -1
  8. package/admin/js/lib/card-builder.js +2 -2
  9. package/admin/js/lib/crud-tutorial.js +1 -1
  10. package/admin/js/lib/effect-defs.js +1 -1
  11. package/admin/js/lib/effects-builder.js +1 -1
  12. package/admin/js/lib/image-editor.js +1 -1
  13. package/admin/js/lib/markdown-toolbar.js +2 -2
  14. package/admin/js/lib/project-context.js +1 -1
  15. package/admin/js/lib/project-quick-create.js +1 -1
  16. package/admin/js/lib/scribe-composer.js +1 -1
  17. package/admin/js/lib/server-restart.js +1 -1
  18. package/admin/js/lib/shortcode-context-menu.js +2 -2
  19. package/admin/js/lib/simple-editor.js +1 -1
  20. package/admin/js/lib/themes.js +1 -1
  21. package/admin/js/lib/timeline-builder.js +1 -1
  22. package/admin/js/templates/action-editor.html +8 -8
  23. package/admin/js/templates/api-endpoint-editor.html +7 -7
  24. package/admin/js/templates/api-endpoints.html +1 -1
  25. package/admin/js/templates/api-reference.html +1 -1
  26. package/admin/js/templates/block-editor.html +6 -6
  27. package/admin/js/templates/collection-editor.html +1 -1
  28. package/admin/js/templates/component-editor.html +2 -2
  29. package/admin/js/templates/dashboard/cache.html +3 -3
  30. package/admin/js/templates/dashboard/journeys.html +3 -3
  31. package/admin/js/templates/dashboard/kpi-strip.html +3 -3
  32. package/admin/js/templates/dashboard/top-pages.html +1 -1
  33. package/admin/js/templates/dashboard/traffic-chart.html +1 -1
  34. package/admin/js/templates/docs/api-actions.html +1 -1
  35. package/admin/js/templates/docs/api-collections.html +4 -4
  36. package/admin/js/templates/docs/api-pages.html +2 -2
  37. package/admin/js/templates/docs/api-plugins.html +1 -1
  38. package/admin/js/templates/docs/api-settings.html +2 -2
  39. package/admin/js/templates/docs/api-users.html +1 -1
  40. package/admin/js/templates/docs/components-howto.html +4 -4
  41. package/admin/js/templates/docs/components-reference.html +21 -21
  42. package/admin/js/templates/docs/components-rules.html +14 -14
  43. package/admin/js/templates/docs/components-walkthrough.html +13 -13
  44. package/admin/js/templates/docs/tutorial-crud.html +49 -49
  45. package/admin/js/templates/docs/tutorial-forms.html +4 -4
  46. package/admin/js/templates/docs/tutorial-plugin.html +10 -10
  47. package/admin/js/templates/docs/usage-actions.html +6 -6
  48. package/admin/js/templates/docs/usage-cta-shortcode.html +9 -9
  49. package/admin/js/templates/docs/usage-dconfig.html +4 -4
  50. package/admin/js/templates/docs/usage-navigation.html +1 -1
  51. package/admin/js/templates/docs/usage-pages.html +1 -1
  52. package/admin/js/templates/docs/usage-shortcodes.html +24 -24
  53. package/admin/js/templates/docs/usage-users-roles.html +3 -3
  54. package/admin/js/templates/docs/usage-views.html +4 -4
  55. package/admin/js/templates/documentation.html +1 -1
  56. package/admin/js/templates/effects.html +752 -752
  57. package/admin/js/templates/form-editor.html +5 -5
  58. package/admin/js/templates/forms.html +17 -17
  59. package/admin/js/templates/login.html +5 -5
  60. package/admin/js/templates/menu-editor.html +10 -10
  61. package/admin/js/templates/my-profile.html +17 -17
  62. package/admin/js/templates/navigation.html +11 -11
  63. package/admin/js/templates/notifications.html +1 -1
  64. package/admin/js/templates/page-editor.html +4 -4
  65. package/admin/js/templates/pro-docs.html +14 -14
  66. package/admin/js/templates/role-editor.html +70 -70
  67. package/admin/js/templates/roles.html +10 -10
  68. package/admin/js/templates/settings.html +10 -10
  69. package/admin/js/templates/tutorials.html +3 -3
  70. package/admin/js/templates/view-editor.html +15 -15
  71. package/admin/js/views/action-editor.js +1 -1
  72. package/admin/js/views/actions-list.js +1 -1
  73. package/admin/js/views/api-endpoint-editor.js +2 -2
  74. package/admin/js/views/api-endpoints.js +2 -2
  75. package/admin/js/views/api-tokens.js +3 -3
  76. package/admin/js/views/blocks.js +2 -2
  77. package/admin/js/views/collection-editor.js +1 -1
  78. package/admin/js/views/collection-entries.js +1 -1
  79. package/admin/js/views/collections.js +1 -1
  80. package/admin/js/views/component-editor.js +1 -1
  81. package/admin/js/views/components.js +4 -4
  82. package/admin/js/views/dashboard/widgets/cache.js +1 -1
  83. package/admin/js/views/dashboard/widgets/journeys.js +1 -1
  84. package/admin/js/views/dashboard/widgets/kpi-strip.js +1 -1
  85. package/admin/js/views/form-editor.js +7 -7
  86. package/admin/js/views/form-submissions.js +1 -1
  87. package/admin/js/views/forms.js +1 -1
  88. package/admin/js/views/layouts.js +1 -1
  89. package/admin/js/views/login.js +2 -2
  90. package/admin/js/views/menu-editor.js +3 -3
  91. package/admin/js/views/menu-locations.js +1 -1
  92. package/admin/js/views/menus.js +3 -3
  93. package/admin/js/views/navigation.js +8 -8
  94. package/admin/js/views/page-editor.js +40 -40
  95. package/admin/js/views/pages.js +3 -3
  96. package/admin/js/views/plugin-code.js +2 -2
  97. package/admin/js/views/plugins.js +1 -1
  98. package/admin/js/views/project-settings.js +1 -1
  99. package/admin/js/views/projects.js +1 -1
  100. package/admin/js/views/roles.js +1 -1
  101. package/admin/js/views/user-editor.js +1 -1
  102. package/admin/js/views/users.js +3 -3
  103. package/admin/js/views/view-editor.js +1 -1
  104. package/admin/js/views/view-preview.js +1 -1
  105. package/admin/js/views/views-list.js +1 -1
  106. package/bin/cli.js +8 -8
  107. package/bin/lib/config-merge.js +44 -44
  108. package/bin/update.js +16 -16
  109. package/config/plugins.json +1 -1
  110. package/package.json +2 -2
  111. package/plugins/_template/admin/views/index.js +1 -1
  112. package/plugins/_template/config.js +1 -1
  113. package/plugins/_template/plugin.js +1 -1
  114. package/plugins/analytics/admin/templates/analytics.html +3 -3
  115. package/plugins/analytics/admin/views/analytics.js +1 -1
  116. package/plugins/analytics/config.js +1 -1
  117. package/plugins/analytics/plugin.js +4 -4
  118. package/plugins/analytics/plugin.json +1 -1
  119. package/plugins/analytics/public/inject-body.html +2 -2
  120. package/plugins/analytics/public/inject-head.html +1 -1
  121. package/plugins/blog/admin/templates/blog.html +4 -4
  122. package/plugins/blog/admin/views/blog.js +3 -3
  123. package/plugins/blog/admin/views/categories.js +2 -2
  124. package/plugins/blog/admin/views/comments.js +4 -4
  125. package/plugins/blog/admin/views/post-editor.js +1 -1
  126. package/plugins/blog/plugin.js +2 -2
  127. package/plugins/blog/plugin.json +4 -4
  128. package/plugins/contacts/admin/views/contacts.js +8 -8
  129. package/plugins/contacts/plugin.js +4 -4
  130. package/plugins/contacts/plugin.json +1 -1
  131. package/plugins/invoice/admin/templates/editor.html +6 -6
  132. package/plugins/invoice/admin/templates/index.html +4 -4
  133. package/plugins/invoice/admin/views/editor.js +3 -3
  134. package/plugins/invoice/admin/views/index.js +4 -4
  135. package/plugins/invoice/admin/views/issuers.js +1 -1
  136. package/plugins/invoice/admin/views/party-view.js +3 -3
  137. package/plugins/invoice/admin/views/receivers.js +1 -1
  138. package/plugins/invoice/config.js +1 -1
  139. package/plugins/invoice/plugin.js +1 -1
  140. package/plugins/invoice/plugin.json +4 -4
  141. package/plugins/notes/admin/views/notes.js +4 -4
  142. package/plugins/notes/plugin.js +1 -1
  143. package/plugins/notes/plugin.json +1 -1
  144. package/plugins/site-search/admin/templates/site-search.html +3 -3
  145. package/plugins/site-search/admin/views/site-search.js +1 -1
  146. package/plugins/site-search/config.js +1 -1
  147. package/plugins/site-search/plugin.js +4 -4
  148. package/plugins/site-search/plugin.json +1 -1
  149. package/plugins/surveys/admin/templates/results.html +1 -1
  150. package/plugins/surveys/admin/templates/survey-editor.html +4 -4
  151. package/plugins/surveys/admin/views/audience.js +6 -6
  152. package/plugins/surveys/admin/views/results.js +3 -3
  153. package/plugins/surveys/admin/views/survey-editor.js +1 -1
  154. package/plugins/surveys/admin/views/surveys.js +2 -2
  155. package/plugins/surveys/plugin.js +1 -1
  156. package/plugins/surveys/plugin.json +4 -4
  157. package/plugins/theme-switcher/admin/views/theme-switcher.js +1 -1
  158. package/plugins/theme-switcher/plugin.json +3 -3
  159. package/plugins/theme-switcher/public/inject-body.html +28 -28
  160. package/plugins/theme-switcher/public/inject-head.html +1 -1
  161. package/plugins/todo/plugin.js +1 -1
  162. package/public/css/forms.css +1 -1
  163. package/public/js/collection-browser.js +1 -1
  164. package/public/js/collection-context.js +1 -1
  165. package/public/js/form-logic-engine.js +1 -1
  166. package/public/js/forms.js +2 -1
  167. package/public/js/site.js +1 -1
  168. package/scripts/build.js +14 -14
  169. package/scripts/create-plugin.js +2 -2
  170. package/scripts/fresh.js +2 -2
  171. package/scripts/gen-instance-secret.js +1 -1
  172. package/scripts/pro.js +12 -12
  173. package/scripts/reset.js +2 -2
  174. package/scripts/setup.js +15 -15
  175. package/scripts/users.js +5 -5
  176. package/scripts/verify-assets.mjs +6 -6
  177. package/server/config.js +1 -1
  178. package/server/middleware/auth.js +253 -253
  179. package/server/middleware/managerAuth.js +3 -3
  180. package/server/routes/api/actions.js +4 -4
  181. package/server/routes/api/api-endpoints.js +7 -7
  182. package/server/routes/api/api-tokens.js +5 -5
  183. package/server/routes/api/auth.js +309 -309
  184. package/server/routes/api/blocks.js +3 -3
  185. package/server/routes/api/collections.js +18 -18
  186. package/server/routes/api/dashboard.js +5 -5
  187. package/server/routes/api/effects.js +2 -2
  188. package/server/routes/api/endpoints-public.js +5 -5
  189. package/server/routes/api/forms.js +47 -47
  190. package/server/routes/api/menu-locations.js +3 -3
  191. package/server/routes/api/menus.js +7 -7
  192. package/server/routes/api/navigation.js +42 -42
  193. package/server/routes/api/notifications.js +2 -2
  194. package/server/routes/api/pages.js +14 -2
  195. package/server/routes/api/plugin-marketplace.js +3 -3
  196. package/server/routes/api/plugins.js +6 -6
  197. package/server/routes/api/projects.js +9 -9
  198. package/server/routes/api/scaffold.js +7 -7
  199. package/server/routes/api/settings.js +6 -6
  200. package/server/routes/api/sidebar.js +1 -1
  201. package/server/routes/api/users.js +5 -5
  202. package/server/routes/api/versions.js +1 -1
  203. package/server/routes/api/views.js +1 -1
  204. package/server/routes/docs-public.js +3 -3
  205. package/server/routes/public.js +14 -14
  206. package/server/server.js +34 -16
  207. package/server/services/actions.js +19 -19
  208. package/server/services/adapters/FileAdapter.js +2 -2
  209. package/server/services/adapters/MongoAdapter.js +5 -5
  210. package/server/services/apiEndpoints.js +15 -15
  211. package/server/services/apiTokens.js +7 -7
  212. package/server/services/blocks.js +13 -13
  213. package/server/services/cache/drivers/MemoryDriver.js +3 -3
  214. package/server/services/cache/drivers/NoneDriver.js +1 -1
  215. package/server/services/cache/index.js +5 -5
  216. package/server/services/collections.js +14 -14
  217. package/server/services/components.js +9 -9
  218. package/server/services/connectionManager.js +4 -4
  219. package/server/services/content.js +25 -2
  220. package/server/services/docs.js +14 -14
  221. package/server/services/email.js +167 -167
  222. package/server/services/filterEngine.js +6 -6
  223. package/server/services/forms.js +18 -10
  224. package/server/services/health.js +1 -1
  225. package/server/services/hooks.js +7 -7
  226. package/server/services/images.js +4 -4
  227. package/server/services/managerClient.js +1 -1
  228. package/server/services/markdown.js +79 -79
  229. package/server/services/menuRender.js +5 -5
  230. package/server/services/menus-migration.js +3 -3
  231. package/server/services/menus.js +31 -31
  232. package/server/services/permissionRegistry.js +1 -1
  233. package/server/services/pluginFiles.js +5 -5
  234. package/server/services/pluginInstaller.js +17 -17
  235. package/server/services/pluginScaffold.js +1 -1
  236. package/server/services/plugins.js +17 -17
  237. package/server/services/presetCollections.js +2 -2
  238. package/server/services/projects.js +35 -26
  239. package/server/services/recipes/contact-list.json +1 -1
  240. package/server/services/recipes/onboarding.json +8 -8
  241. package/server/services/references.js +8 -8
  242. package/server/services/renderer.js +9 -9
  243. package/server/services/roles.js +9 -9
  244. package/server/services/rowAccess.js +10 -10
  245. package/server/services/scaffolder.js +30 -30
  246. package/server/services/sidebar-migration.js +10 -10
  247. package/server/services/sitemap.js +1 -1
  248. package/server/services/userProfiles.js +199 -199
  249. package/server/services/userRoles.js +7 -7
  250. package/server/services/users.js +302 -302
  251. package/server/services/versions.js +3 -3
  252. package/server/services/viewPipeline.js +6 -6
  253. package/server/services/views.js +11 -11
  254. package/server/templates/page.html +5 -5
package/scripts/build.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Build script — creates a publishable staging copy in _publish/
2
+ * Build script - creates a publishable staging copy in _publish/
3
3
  * Browser-facing JS/CSS is minified; server-side code is copied as-is.
4
4
  * Run: node scripts/build.js
5
5
  */
@@ -29,7 +29,7 @@ const COPY_AS_IS = [
29
29
  ];
30
30
 
31
31
  // Glob patterns for browser-facing assets to minify. NOTE: both .js AND .mjs
32
- // must be listed — the browser ESM modules served raw (e.g. public/js/*.mjs)
32
+ // must be listed - the browser ESM modules served raw (e.g. public/js/*.mjs)
33
33
  // use the .mjs extension, and omitting it silently drops those files from the
34
34
  // published package (this is the bug that shipped 0.22.1 without menu-decor.mjs).
35
35
  const MINIFY_PATTERNS = [
@@ -177,7 +177,7 @@ async function stampPluginVersions() {
177
177
  * `/dist/domma/domma.min.js` is served straight from `node_modules/domma-js` (server.js), so a
178
178
  * `npm install domma-js@next` silently upgrades one half of the admin and leaves the other on
179
179
  * whatever version was last copied across. The tools bundle's own banner says
180
- * `Requires: domma.min.js` — it is built against a specific core and is not version-independent.
180
+ * `Requires: domma.min.js` - it is built against a specific core and is not version-independent.
181
181
  *
182
182
  * That skew is invisible: both files load, no import dangles, nothing throws. It surfaces later as
183
183
  * a Theme Roller or Page Roller that misbehaves against a core it was not built for. This is the
@@ -203,14 +203,14 @@ function verifyDommaToolsVersion(toolsRelPaths) {
203
203
  // admin/index.html loads both unconditionally, so an absent file is a dead <script>/<link>
204
204
  // in the published admin. The copy step already tolerates absence; flag it rather than
205
205
  // silently agreeing.
206
- problems.push(`${rel} is missing — the published admin will reference a file that isn't there`);
206
+ problems.push(`${rel} is missing - the published admin will reference a file that isn't there`);
207
207
  continue;
208
208
  }
209
209
  // The banner is in the first few lines; no need to read a 230 KB bundle in full.
210
210
  const head = readFileSync(src, 'utf8').slice(0, 512);
211
211
  const match = head.match(BANNER);
212
212
  if (!match) {
213
- problems.push(`${rel} carries no recognisable Domma Tools banner — cannot confirm its version`);
213
+ problems.push(`${rel} carries no recognisable Domma Tools banner - cannot confirm its version`);
214
214
  found.push({rel, version: null});
215
215
  continue;
216
216
  }
@@ -238,7 +238,7 @@ async function build() {
238
238
  }
239
239
  }
240
240
 
241
- // Strip prepublishOnly from _publish/package.json — the guard is for the
241
+ // Strip prepublishOnly from _publish/package.json - the guard is for the
242
242
  // source tree only; running npm publish inside _publish/ must succeed.
243
243
  const pkgPath = join(OUT, 'package.json');
244
244
  const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
@@ -247,7 +247,7 @@ async function build() {
247
247
 
248
248
  // Scrub this machine's local config out of the staged copy. config/site.json
249
249
  // is a working file on a development install, so it carries whatever SMTP
250
- // host and site URL were last set here — published releases up to 0.43.1 put
250
+ // host and site URL were last set here - published releases up to 0.43.1 put
251
251
  // a LAN address on the public registry and handed every manual installer a
252
252
  // mail host that does not exist for them. Same reasoning as the analytics
253
253
  // counters in .npmignore: runtime state must not ride along in the tarball.
@@ -265,7 +265,7 @@ async function build() {
265
265
  }
266
266
 
267
267
  // .bak files are migration leftovers from whichever machine built the
268
- // release — never something an installer should receive.
268
+ // release - never something an installer should receive.
269
269
  for (const rel of ['config/navigation.json.bak', 'config/connections.json.bak']) {
270
270
  const bak = join(OUT, rel);
271
271
  if (existsSync(bak)) rmSync(bak, {force: true});
@@ -293,14 +293,14 @@ async function build() {
293
293
  'admin/dist/domma/domma-tools.min.js',
294
294
  ];
295
295
 
296
- // Version-skew gate — see verifyDommaToolsVersion() for why this cannot be left to npm.
296
+ // Version-skew gate - see verifyDommaToolsVersion() for why this cannot be left to npm.
297
297
  const toolsCheck = verifyDommaToolsVersion(dommaTools);
298
298
  if (toolsCheck.ok) {
299
- console.log(`Domma Tools v${toolsCheck.installed} — matches installed domma-js`);
299
+ console.log(`Domma Tools v${toolsCheck.installed} - matches installed domma-js`);
300
300
  } else {
301
301
  for (const problem of toolsCheck.problems) console.error(` ${problem}`);
302
302
  throw new Error(
303
- `Domma Tools is out of step with domma-js v${toolsCheck.installed} — copy `
303
+ `Domma Tools is out of step with domma-js v${toolsCheck.installed} - copy `
304
304
  + `domma-tools.min.js and domma-tools.css from that version's build into admin/dist/domma/, `
305
305
  + `then rebuild`,
306
306
  );
@@ -338,16 +338,16 @@ async function build() {
338
338
 
339
339
  await stampPluginVersions();
340
340
 
341
- console.log(`Built into _publish/ — JS: ${jsCount} minified, CSS: ${cssCount} minified, ${totalCopied} entries copied`);
341
+ console.log(`Built into _publish/ - JS: ${jsCount} minified, CSS: ${cssCount} minified, ${totalCopied} entries copied`);
342
342
 
343
- // Integrity gate — fail the build (and therefore `make pack` / `make
343
+ // Integrity gate - fail the build (and therefore `make pack` / `make
344
344
  // release-npm`) if the staged set ships any ESM import pointing at a file
345
345
  // that isn't there. This is what stops a "shipped code that imports a missing
346
346
  // file" release (the 0.22.1 menu-decor.mjs incident) from ever publishing.
347
347
  const integrity = await verifyAssetImports({projectRoot: OUT});
348
348
  console.log(formatReport(integrity, '_publish/'));
349
349
  if (!integrity.ok) {
350
- throw new Error(`asset integrity check failed — ${integrity.missing.length} dangling import(s); refusing to package a broken release`);
350
+ throw new Error(`asset integrity check failed - ${integrity.missing.length} dangling import(s); refusing to package a broken release`);
351
351
  }
352
352
  }
353
353
 
@@ -69,12 +69,12 @@ const templateDir = join(ROOT, 'plugins', '_template');
69
69
  const targetDir = join(ROOT, 'plugins', slug);
70
70
 
71
71
  if (!existsSync(templateDir)) {
72
- console.error(`Template not found at plugins/_template/ — cannot scaffold.`);
72
+ console.error(`Template not found at plugins/_template/ - cannot scaffold.`);
73
73
  process.exit(1);
74
74
  }
75
75
 
76
76
  if (existsSync(targetDir)) {
77
- console.error(`plugins/${slug}/ already exists — choose a different name.`);
77
+ console.error(`plugins/${slug}/ already exists - choose a different name.`);
78
78
  process.exit(1);
79
79
  }
80
80
 
package/scripts/fresh.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Domma CMS — Fresh Install
3
+ * Domma CMS - Fresh Install
4
4
  * Chains: reset → setup
5
5
  * Gives you a clean CMS install ready to use.
6
6
  * Run: npm run fresh
@@ -24,7 +24,7 @@ function run(script) {
24
24
 
25
25
  console.log('');
26
26
  console.log(' ╔══════════════════════════════════════╗');
27
- console.log(' ║ Domma CMS — Fresh Install ║');
27
+ console.log(' ║ Domma CMS - Fresh Install ║');
28
28
  console.log(' ║ reset → setup ║');
29
29
  console.log(' ╚══════════════════════════════════════╝');
30
30
  console.log('');
@@ -36,7 +36,7 @@ async function writeEnv(env) {
36
36
 
37
37
  const env = await readEnv();
38
38
  if (env.INSTANCE_SECRET && env.INSTANCE_SECRET.length >= 32) {
39
- console.log(' ✓ INSTANCE_SECRET already set — skipping.');
39
+ console.log(' ✓ INSTANCE_SECRET already set - skipping.');
40
40
  process.exit(0);
41
41
  }
42
42
 
package/scripts/pro.js CHANGED
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Domma CMS — Pro Mode Toggle
3
+ * Domma CMS - Pro Mode Toggle
4
4
  *
5
5
  * Enables or disables MongoDB storage adapter (Pro feature).
6
6
  *
7
7
  * Usage:
8
- * npm run pro enable — copy connections.json.example, prompt for URI/DB, install mongodb
9
- * npm run pro disable — back up connections.json, optionally uninstall mongodb
10
- * npm run pro status — report current mode and connection summary
8
+ * npm run pro enable - copy connections.json.example, prompt for URI/DB, install mongodb
9
+ * npm run pro disable - back up connections.json, optionally uninstall mongodb
10
+ * npm run pro status - report current mode and connection summary
11
11
  */
12
12
  import {createInterface} from 'node:readline/promises';
13
13
  import {copyFile, readFile, rename, writeFile} from 'node:fs/promises';
@@ -75,7 +75,7 @@ async function cmdStatus() {
75
75
  }
76
76
 
77
77
  console.log(' Mode : Pro (MongoDB)');
78
- console.log(` mongodb : ${mongoInstalled ? 'installed ✓' : 'NOT installed — run: npm install mongodb'}`);
78
+ console.log(` mongodb : ${mongoInstalled ? 'installed ✓' : 'NOT installed - run: npm install mongodb'}`);
79
79
 
80
80
  try {
81
81
  const raw = await readFile(CONNECTIONS_FILE, 'utf8');
@@ -95,7 +95,7 @@ async function cmdStatus() {
95
95
  }
96
96
  }
97
97
  } catch (err) {
98
- console.log(` Warning : Could not parse connections.json — ${err.message}`);
98
+ console.log(` Warning : Could not parse connections.json - ${err.message}`);
99
99
  }
100
100
 
101
101
  console.log('');
@@ -105,7 +105,7 @@ async function cmdEnable() {
105
105
  section('Enable Pro Mode');
106
106
 
107
107
  if (existsSync(CONNECTIONS_FILE)) {
108
- console.log(' ✓ config/connections.json already exists — Pro mode is already enabled.');
108
+ console.log(' ✓ config/connections.json already exists - Pro mode is already enabled.');
109
109
  console.log(' Run "npm run pro status" to review the current configuration.\n');
110
110
  return;
111
111
  }
@@ -140,7 +140,7 @@ async function cmdEnable() {
140
140
  await writeFile(CONNECTIONS_FILE, JSON.stringify(cfg, null, 4) + '\n', 'utf8');
141
141
 
142
142
  console.log('\n ✓ config/connections.json updated with your connection details.');
143
- console.log(' (This file is gitignored — credentials stay local.)\n');
143
+ console.log(' (This file is gitignored - credentials stay local.)\n');
144
144
 
145
145
  // Install mongodb package
146
146
  console.log(' Installing mongodb package…');
@@ -168,13 +168,13 @@ async function cmdDisable() {
168
168
  section('Disable Pro Mode');
169
169
 
170
170
  if (!existsSync(CONNECTIONS_FILE)) {
171
- console.log(' Already in file-based mode — nothing to disable.\n');
171
+ console.log(' Already in file-based mode - nothing to disable.\n');
172
172
  return;
173
173
  }
174
174
 
175
175
  // Back up connections.json
176
176
  if (existsSync(CONNECTIONS_BAK)) {
177
- console.log(' Note: connections.json.bak already exists — it will be overwritten.');
177
+ console.log(' Note: connections.json.bak already exists - it will be overwritten.');
178
178
  }
179
179
 
180
180
  await rename(CONNECTIONS_FILE, CONNECTIONS_BAK);
@@ -195,7 +195,7 @@ async function cmdDisable() {
195
195
  console.log('\n Warning: npm uninstall mongodb failed. Remove it manually if needed.');
196
196
  }
197
197
  } else {
198
- console.log(' Skipping uninstall — mongodb package remains (unused).');
198
+ console.log(' Skipping uninstall - mongodb package remains (unused).');
199
199
  }
200
200
 
201
201
  console.log('');
@@ -209,7 +209,7 @@ async function cmdDisable() {
209
209
  function printUsage() {
210
210
  console.log('');
211
211
  console.log(' ┌─────────────────────────────────────┐');
212
- console.log(' │ Domma CMS — Pro Mode Toggle │');
212
+ console.log(' │ Domma CMS - Pro Mode Toggle │');
213
213
  console.log(' └─────────────────────────────────────┘');
214
214
  console.log('');
215
215
  console.log(' Usage: npm run pro <command>');
package/scripts/reset.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Domma CMS — Factory Reset
3
+ * Domma CMS - Factory Reset
4
4
  * Wipes all content, users, and resets config to defaults.
5
5
  * Run: npm run reset
6
6
  */
@@ -74,7 +74,7 @@ async function resetEnv() {
74
74
 
75
75
  console.log('');
76
76
  console.log(' ┌──────────────────────────────────┐');
77
- console.log(' │ Domma CMS — Factory Reset │');
77
+ console.log(' │ Domma CMS - Factory Reset │');
78
78
  console.log(' └──────────────────────────────────┘');
79
79
  console.log('');
80
80
  console.log(' This will permanently delete:');
package/scripts/setup.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Domma CMS — Interactive Setup Wizard
3
+ * Domma CMS - Interactive Setup Wizard
4
4
  *
5
5
  * Run once after cloning: npm run setup
6
- * Operates directly on files — does NOT import the Fastify server.
6
+ * Operates directly on files - does NOT import the Fastify server.
7
7
  *
8
8
  * Steps:
9
9
  * 1. Generate JWT_SECRET (skips if already set)
@@ -134,7 +134,7 @@ console.log(' │ Domma CMS Setup Wizard │');
134
134
  console.log(' └────────────────────────────┘');
135
135
 
136
136
  // ---------------------------------------------------------------------------
137
- // Step 1 — JWT Secret
137
+ // Step 1 - JWT Secret
138
138
  // ---------------------------------------------------------------------------
139
139
  section('1. JWT Secret');
140
140
 
@@ -145,7 +145,7 @@ const isPlaceholder = !existingSecret
145
145
  || existingSecret.length < 32;
146
146
 
147
147
  if (!isPlaceholder) {
148
- console.log(' ✓ JWT_SECRET already configured — skipping.');
148
+ console.log(' ✓ JWT_SECRET already configured - skipping.');
149
149
  } else {
150
150
  const secret = randomBytes(48).toString('hex');
151
151
  env.JWT_SECRET = secret;
@@ -155,18 +155,18 @@ if (!isPlaceholder) {
155
155
  }
156
156
 
157
157
  // ---------------------------------------------------------------------------
158
- // Step 2 — Instance Secret
158
+ // Step 2 - Instance Secret
159
159
  // ---------------------------------------------------------------------------
160
160
  section('2. Instance Secret');
161
161
 
162
- // Distinct name from step 1's existingSecret — both are module-scope consts,
162
+ // Distinct name from step 1's existingSecret - both are module-scope consts,
163
163
  // so reusing the identifier made the whole file a SyntaxError and setup could
164
164
  // not run at all.
165
165
  const existingInstanceSecret = env.INSTANCE_SECRET ?? '';
166
166
  const isInstanceSecretSet = existingInstanceSecret && existingInstanceSecret.length >= 32;
167
167
 
168
168
  if (isInstanceSecretSet) {
169
- console.log(' ✓ INSTANCE_SECRET already configured — skipping.');
169
+ console.log(' ✓ INSTANCE_SECRET already configured - skipping.');
170
170
  } else {
171
171
  const secret = randomBytes(32).toString('hex');
172
172
  env.INSTANCE_SECRET = secret;
@@ -175,13 +175,13 @@ if (isInstanceSecretSet) {
175
175
  }
176
176
 
177
177
  // ---------------------------------------------------------------------------
178
- // Step 3 — Admin Account
178
+ // Step 3 - Admin Account
179
179
  // ---------------------------------------------------------------------------
180
180
  section('3. Admin Account');
181
181
 
182
182
  const userCount = await countUsers();
183
183
  if (userCount > 0) {
184
- console.log(` ✓ ${userCount} user(s) already exist — skipping admin creation.`);
184
+ console.log(` ✓ ${userCount} user(s) already exist - skipping admin creation.`);
185
185
  } else {
186
186
  console.log(' No users found. Create the first admin account.\n');
187
187
 
@@ -228,7 +228,7 @@ if (userCount > 0) {
228
228
  }
229
229
 
230
230
  // ---------------------------------------------------------------------------
231
- // Step 4 — Site Identity
231
+ // Step 4 - Site Identity
232
232
  // ---------------------------------------------------------------------------
233
233
  section('4. Site Identity');
234
234
 
@@ -256,7 +256,7 @@ section('4. Site Identity');
256
256
  }
257
257
 
258
258
  // ---------------------------------------------------------------------------
259
- // Step 5 — Theme
259
+ // Step 5 - Theme
260
260
  // ---------------------------------------------------------------------------
261
261
  section('5. Theme');
262
262
 
@@ -268,7 +268,7 @@ THEMES.forEach((t, i) => {
268
268
 
269
269
  {
270
270
  const rl = createInterface({ input: process.stdin, output: process.stdout });
271
- const choice = (await rl.question(`\n Choice (1–${THEMES.length}, Enter = charcoal-dark): `)).trim();
271
+ const choice = (await rl.question(`\n Choice (1-${THEMES.length}, Enter = charcoal-dark): `)).trim();
272
272
  rl.close();
273
273
 
274
274
  const idx = parseInt(choice, 10) - 1;
@@ -282,7 +282,7 @@ THEMES.forEach((t, i) => {
282
282
  }
283
283
 
284
284
  // ---------------------------------------------------------------------------
285
- // Step 6 — Port
285
+ // Step 6 - Port
286
286
  // ---------------------------------------------------------------------------
287
287
  section('6. Server Port');
288
288
 
@@ -305,7 +305,7 @@ section('6. Server Port');
305
305
  // Git hooks
306
306
  // ---------------------------------------------------------------------------
307
307
  // The hooks in .githooks/ are committed, but git will not run them until this
308
- // clone points at that directory — core.hooksPath is local config, so it cannot
308
+ // clone points at that directory - core.hooksPath is local config, so it cannot
309
309
  // travel with the repository. Every clone that misses this step silently loses
310
310
  // both hooks: the commit-msg trailer strip and the pre-commit minified-source
311
311
  // guard. Enable it here so a fresh clone is protected by default.
@@ -315,7 +315,7 @@ try {
315
315
  execSync('git config core.hooksPath .githooks', {stdio: 'ignore'});
316
316
  console.log(' ✓ Git hooks enabled (core.hooksPath = .githooks)');
317
317
  } catch {
318
- // Not a git checkout — an npm install of the published package, most
318
+ // Not a git checkout - an npm install of the published package, most
319
319
  // likely. Nothing to enable, and nothing worth warning about.
320
320
  }
321
321
 
package/scripts/users.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Domma CMS — User Management CLI
3
+ * Domma CMS - User Management CLI
4
4
  *
5
5
  * Run from the project root:
6
6
  * npm run users -- <command> [args] [options]
@@ -105,7 +105,7 @@ async function cmdList() {
105
105
  name: u.name,
106
106
  role: u.role,
107
107
  active: u.isActive ? 'yes' : 'no',
108
- last: u.lastLogin ? u.lastLogin.slice(0, 16).replace('T', ' ') : '—'
108
+ last: u.lastLogin ? u.lastLogin.slice(0, 16).replace('T', ' ') : '-'
109
109
  }));
110
110
  printTable(['email', 'name', 'role', 'active', 'last'], rows);
111
111
  }
@@ -203,7 +203,7 @@ async function resolvePassword({confirm: requireConfirm = false} = {}) {
203
203
  if (flags.has('generate')) {
204
204
  const pw = generatePassword(20);
205
205
  console.log(`\n Generated password: ${pw}`);
206
- console.log(' (this is the only time it will be shown — copy it now)\n');
206
+ console.log(' (this is the only time it will be shown - copy it now)\n');
207
207
  return pw;
208
208
  }
209
209
 
@@ -221,7 +221,7 @@ function generatePassword(bytes) {
221
221
  }
222
222
 
223
223
  /**
224
- * Prompt with masked echo — reads raw TTY input so keystrokes don't appear on screen.
224
+ * Prompt with masked echo - reads raw TTY input so keystrokes don't appear on screen.
225
225
  * Falls back to a plain (visible) readline when stdin isn't a TTY (e.g. piped input).
226
226
  *
227
227
  * @param {string} prompt
@@ -286,7 +286,7 @@ function printTable(headers, rows) {
286
286
 
287
287
  function printHelp() {
288
288
  console.log(`
289
- Domma CMS — User Management CLI
289
+ Domma CMS - User Management CLI
290
290
 
291
291
  Usage:
292
292
  npm run users -- <command> [args] [options]
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Asset Import Verifier — build/publish gate
2
+ * Asset Import Verifier - build/publish gate
3
3
  *
4
4
  * Statically resolves every local ESM import under the browser-facing code
5
5
  * (admin/ + public/) against the files that actually exist, and fails if any
@@ -11,7 +11,7 @@
11
11
  * import natively (no bundler). If a release ships consumer code that imports a
12
12
  * new module but forgets to include the module file (as 0.22.1 did with
13
13
  * /public/js/menu-decor.mjs), every page 404s on the import and the whole site
14
- * breaks — with no signal but a browser console error, and it cascades to every
14
+ * breaks - with no signal but a browser console error, and it cascades to every
15
15
  * downstream project that copies these dirs on update. A bundler would catch
16
16
  * this at build time; because we don't bundle, this gate stands in for that.
17
17
  *
@@ -21,8 +21,8 @@
21
21
  * Exits 1 (with a report) on any dangling import, 0 otherwise. Wired into
22
22
  * scripts/build.js so `make pack` / `make release-npm` cannot ship a broken set.
23
23
  *
24
- * Scope (deliberately conservative — zero false positives is the whole point):
25
- * only STATIC, LOCAL specifiers with an explicit extension are checked — the
24
+ * Scope (deliberately conservative - zero false positives is the whole point):
25
+ * only STATIC, LOCAL specifiers with an explicit extension are checked - the
26
26
  * only kind this codebase emits. Bare (npm) specifiers, URLs, dynamic/template
27
27
  * specifiers, commented-out imports, and extension-less paths are all ignored.
28
28
  */
@@ -160,12 +160,12 @@ export async function verifyAssetImports({ projectRoot, roots = ['admin', 'publi
160
160
 
161
161
  export function formatReport(result, label) {
162
162
  if (result.ok) {
163
- return `[verify-assets] OK — ${result.scanned} files scanned, all local imports resolve (${label}).`;
163
+ return `[verify-assets] OK - ${result.scanned} files scanned, all local imports resolve (${label}).`;
164
164
  }
165
165
  const lines = [
166
166
  '',
167
167
  ' ╔════════════════════════════════════════════════════════════════╗',
168
- ' ║ ASSET INTEGRITY FAILURE — dangling front-end imports detected ║',
168
+ ' ║ ASSET INTEGRITY FAILURE - dangling front-end imports detected ║',
169
169
  ' ╚════════════════════════════════════════════════════════════════╝',
170
170
  ` Context: ${label}`,
171
171
  ` ${result.missing.length} import(s) reference files that do not exist:`,
package/server/config.js CHANGED
@@ -43,7 +43,7 @@ export function saveConfig(name, data) {
43
43
  }
44
44
 
45
45
  /**
46
- * Structural config — loaded once at startup.
46
+ * Structural config - loaded once at startup.
47
47
  * Do not use for admin-editable settings (site, navigation, presets, plugins).
48
48
  */
49
49
  const serverConfig = loadJson('server');