domma-cms 0.2.1 → 0.5.0

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 (166) hide show
  1. package/README.md +3 -3
  2. package/admin/css/admin.css +1 -1200
  3. package/admin/dist/domma/domma-tools.css +2313 -0
  4. package/admin/dist/domma/domma-tools.min.js +10 -0
  5. package/admin/index.html +4 -0
  6. package/admin/js/api.js +1 -242
  7. package/admin/js/app.js +9 -279
  8. package/admin/js/config/sidebar-config.js +1 -115
  9. package/admin/js/lib/card.js +1 -63
  10. package/admin/js/lib/image-editor.js +1 -869
  11. package/admin/js/lib/markdown-toolbar.js +54 -421
  12. package/admin/js/templates/action-editor.html +171 -0
  13. package/admin/js/templates/actions-list.html +19 -0
  14. package/admin/js/templates/api-reference.html +1411 -0
  15. package/admin/js/templates/block-editor.html +158 -0
  16. package/admin/js/templates/blocks.html +8 -0
  17. package/admin/js/templates/collection-editor.html +47 -0
  18. package/admin/js/templates/collection-entries.html +3 -0
  19. package/admin/js/templates/collections.html +51 -4
  20. package/admin/js/templates/documentation.html +258 -0
  21. package/admin/js/templates/form-editor.html +238 -0
  22. package/{plugins/form-builder/admin → admin/js}/templates/form-submissions.html +30 -30
  23. package/{plugins/form-builder/admin/templates/forms-list.html → admin/js/templates/forms.html} +17 -17
  24. package/admin/js/templates/layouts.html +44 -7
  25. package/admin/js/templates/login.html +29 -4
  26. package/admin/js/templates/my-profile.html +17 -0
  27. package/admin/js/templates/page-editor.html +48 -0
  28. package/admin/js/templates/pages.html +6 -1
  29. package/admin/js/templates/pro-docs.html +259 -0
  30. package/admin/js/templates/role-editor.html +59 -0
  31. package/admin/js/templates/roles.html +10 -0
  32. package/admin/js/templates/settings.html +137 -18
  33. package/admin/js/templates/tutorials.html +81 -0
  34. package/admin/js/templates/user-editor.html +7 -0
  35. package/admin/js/templates/users.html +3 -1
  36. package/admin/js/templates/view-editor.html +201 -0
  37. package/admin/js/templates/view-preview.html +51 -0
  38. package/admin/js/templates/views-list.html +19 -0
  39. package/admin/js/views/action-editor.js +1 -0
  40. package/admin/js/views/actions-list.js +1 -0
  41. package/admin/js/views/api-reference.js +1 -0
  42. package/admin/js/views/block-editor.js +8 -0
  43. package/admin/js/views/blocks.js +4 -0
  44. package/admin/js/views/collection-editor.js +3 -487
  45. package/admin/js/views/collection-entries.js +1 -484
  46. package/admin/js/views/collections.js +1 -153
  47. package/admin/js/views/dashboard.js +1 -56
  48. package/admin/js/views/documentation.js +1 -12
  49. package/admin/js/views/form-editor.js +8 -0
  50. package/admin/js/views/form-submissions.js +1 -0
  51. package/admin/js/views/forms.js +1 -0
  52. package/admin/js/views/index.js +1 -39
  53. package/admin/js/views/layouts.js +9 -42
  54. package/admin/js/views/login.js +7 -251
  55. package/admin/js/views/media.js +1 -240
  56. package/admin/js/views/my-profile.js +1 -0
  57. package/admin/js/views/navigation.js +14 -212
  58. package/admin/js/views/page-editor.js +72 -661
  59. package/admin/js/views/pages.js +5 -72
  60. package/admin/js/views/plugins.js +13 -90
  61. package/admin/js/views/pro-docs.js +1 -0
  62. package/admin/js/views/role-editor.js +1 -0
  63. package/admin/js/views/roles.js +4 -0
  64. package/admin/js/views/settings.js +3 -199
  65. package/admin/js/views/tutorials.js +1 -12
  66. package/admin/js/views/user-editor.js +1 -88
  67. package/admin/js/views/users.js +4 -76
  68. package/admin/js/views/view-editor.js +1 -0
  69. package/admin/js/views/view-preview.js +1 -0
  70. package/admin/js/views/views-list.js +1 -0
  71. package/bin/cli.js +1 -1
  72. package/config/auth.json +2 -17
  73. package/config/connections.json.bak +9 -0
  74. package/config/connections.json.example +9 -0
  75. package/config/navigation.json +15 -0
  76. package/config/plugins.json +19 -29
  77. package/config/server.json +6 -6
  78. package/config/site.json +17 -6
  79. package/package.json +24 -10
  80. package/plugins/domma-effects/public/celebrations/core/canvas.js +2 -104
  81. package/plugins/domma-effects/public/celebrations/core/particles.js +1 -144
  82. package/plugins/domma-effects/public/celebrations/core/physics.js +1 -166
  83. package/plugins/domma-effects/public/celebrations/index.js +1 -535
  84. package/plugins/domma-effects/public/celebrations/themes/christmas.js +1 -1805
  85. package/plugins/domma-effects/public/celebrations/themes/guy-fawkes.js +1 -1477
  86. package/plugins/domma-effects/public/celebrations/themes/halloween.js +1 -1837
  87. package/plugins/domma-effects/public/celebrations/themes/st-andrews.js +1 -1175
  88. package/plugins/domma-effects/public/celebrations/themes/st-davids.js +1 -1258
  89. package/plugins/domma-effects/public/celebrations/themes/st-georges.js +1 -1754
  90. package/plugins/domma-effects/public/celebrations/themes/st-patricks.js +1 -1290
  91. package/plugins/domma-effects/public/celebrations/themes/valentines.js +1 -1361
  92. package/plugins/example-analytics/stats.json +21 -12
  93. package/plugins/theme-roller/admin/templates/theme-roller.html +71 -0
  94. package/plugins/theme-roller/admin/views/theme-roller-view.js +403 -0
  95. package/plugins/theme-roller/config.js +1 -0
  96. package/plugins/theme-roller/plugin.js +233 -0
  97. package/plugins/theme-roller/plugin.json +31 -0
  98. package/plugins/theme-roller/public/active-theme.css +0 -0
  99. package/plugins/theme-roller/public/inject-head-late.html +1 -0
  100. package/public/css/forms.css +1 -0
  101. package/public/css/site.css +1 -302
  102. package/public/js/btt.js +1 -90
  103. package/public/js/cookie-consent.js +1 -61
  104. package/public/js/form-logic-engine.js +1 -0
  105. package/public/js/forms.js +1 -0
  106. package/public/js/site.js +1 -204
  107. package/scripts/build.js +194 -129
  108. package/scripts/pro.js +254 -0
  109. package/scripts/reset.js +33 -8
  110. package/scripts/seed.js +343 -78
  111. package/scripts/setup.js +5 -4
  112. package/server/middleware/auth.js +136 -97
  113. package/server/routes/api/actions.js +200 -0
  114. package/server/routes/api/auth.js +292 -116
  115. package/server/routes/api/blocks.js +84 -0
  116. package/server/routes/api/collections.js +88 -23
  117. package/{plugins/form-builder/plugin.js → server/routes/api/forms.js} +483 -505
  118. package/server/routes/api/layouts.js +49 -25
  119. package/server/routes/api/media.js +118 -93
  120. package/server/routes/api/navigation.js +40 -37
  121. package/server/routes/api/pages.js +132 -118
  122. package/server/routes/api/plugins.js +6 -3
  123. package/server/routes/api/settings.js +104 -89
  124. package/server/routes/api/users.js +27 -21
  125. package/server/routes/api/views.js +148 -0
  126. package/server/routes/public.js +124 -108
  127. package/server/server.js +269 -173
  128. package/server/services/actions.js +387 -0
  129. package/server/services/adapterRegistry.js +98 -0
  130. package/server/services/adapters/FileAdapter.js +192 -0
  131. package/server/services/adapters/MongoAdapter.js +220 -0
  132. package/server/services/blocks.js +162 -0
  133. package/server/services/collections.js +74 -86
  134. package/server/services/connectionManager.js +102 -0
  135. package/server/services/content.js +312 -307
  136. package/{plugins/form-builder → server/services}/email.js +126 -103
  137. package/server/services/forms.js +173 -0
  138. package/server/services/markdown.js +1378 -648
  139. package/server/services/permissionRegistry.js +173 -0
  140. package/server/services/presetCollections.js +251 -0
  141. package/server/services/renderer.js +75 -1
  142. package/server/services/roles.js +227 -0
  143. package/server/services/rowAccess.js +104 -0
  144. package/server/services/userProfiles.js +199 -0
  145. package/server/services/users.js +281 -212
  146. package/server/services/views.js +280 -0
  147. package/server/templates/page.html +119 -113
  148. package/plugins/form-builder/admin/templates/form-editor.html +0 -171
  149. package/plugins/form-builder/admin/templates/form-settings.html +0 -29
  150. package/plugins/form-builder/admin/views/form-editor.js +0 -1442
  151. package/plugins/form-builder/admin/views/form-settings.js +0 -38
  152. package/plugins/form-builder/admin/views/form-submissions.js +0 -295
  153. package/plugins/form-builder/admin/views/forms-list.js +0 -164
  154. package/plugins/form-builder/config.js +0 -9
  155. package/plugins/form-builder/data/forms/consent.json +0 -104
  156. package/plugins/form-builder/data/forms/contact-details.json +0 -63
  157. package/plugins/form-builder/data/forms/contacts.json +0 -66
  158. package/plugins/form-builder/data/submissions/consent.json +0 -13
  159. package/plugins/form-builder/data/submissions/contact-details.json +0 -1
  160. package/plugins/form-builder/data/submissions/contacts.json +0 -26
  161. package/plugins/form-builder/plugin.json +0 -52
  162. package/plugins/form-builder/public/form-logic-engine.js +0 -568
  163. package/plugins/form-builder/public/inject-body.html +0 -352
  164. package/plugins/form-builder/public/inject-head.html +0 -58
  165. package/plugins/form-builder/public/package.json +0 -1
  166. package/scripts/copy-domma.js +0 -48
@@ -1,352 +0,0 @@
1
- <script>
2
- (function () {
3
- 'use strict';
4
-
5
- var targets = document.querySelectorAll('[data-form]');
6
- if (!targets.length) return;
7
-
8
- function showMessage(wrapper, message, type) {
9
- var existing = wrapper.querySelector('.fb-form-success, .fb-form-error');
10
- if (existing) existing.remove();
11
- var div = document.createElement('div');
12
- div.className = type === 'success' ? 'fb-form-success' : 'fb-form-error';
13
- div.textContent = message;
14
- wrapper.appendChild(div);
15
- }
16
-
17
- function buildBlueprintFromFields(fields) {
18
- var blueprint = {};
19
- fields.forEach(function (field) {
20
- if (field.type === 'page-break' || field.type === 'spacer') return;
21
- var def = {
22
- type: field.type,
23
- label: field.label || field.name,
24
- required: field.required || false,
25
- placeholder: field.placeholder || ''
26
- };
27
- if (field.helper) def.helper = field.helper;
28
- if (field.options) def.options = field.options;
29
- if (field.formConfig) Object.assign(def, field.formConfig);
30
- if (field.minLength) def.minLength = field.minLength;
31
- if (field.maxLength) def.maxLength = field.maxLength;
32
- if (field.min !== undefined) def.min = field.min;
33
- if (field.max !== undefined) def.max = field.max;
34
- blueprint[field.name] = def;
35
- });
36
- return blueprint;
37
- }
38
-
39
- /**
40
- * Split a fields array at page-break entries into wizard steps.
41
- * Each step: { title, description, fieldGroup[] }
42
- */
43
- function buildWizardSteps(fields, formTitle) {
44
- var steps = [];
45
- var group = [];
46
- var title = formTitle || 'Step 1';
47
- var desc = '';
48
-
49
- fields.forEach(function (field) {
50
- if (field.type === 'page-break') {
51
- steps.push({ title: title, description: desc, fieldGroup: group });
52
- group = [];
53
- title = field.label || ('Step ' + (steps.length + 1));
54
- desc = field.description || '';
55
- } else if (field.type !== 'spacer') {
56
- group.push(field);
57
- }
58
- });
59
-
60
- // Always push the last (or only) group
61
- steps.push({ title: title, description: desc, fieldGroup: group });
62
- return steps;
63
- }
64
-
65
- function initFormTarget(target) {
66
- var slug = target.getAttribute('data-form');
67
- if (!slug) return;
68
-
69
- fetch('/api/plugins/form-builder/forms/' + slug + '/public')
70
- .then(function (res) {
71
- if (!res.ok) throw new Error('Form not found: ' + slug);
72
- return res.json();
73
- })
74
- .then(function (form) {
75
- var fields = form.fields || [];
76
- var settings = form.settings || {};
77
-
78
- var wrapper = document.createElement('div');
79
- wrapper.className = 'fb-form-wrapper';
80
- target.appendChild(wrapper);
81
-
82
- var hasPageBreaks = fields.some(function (f) { return f.type === 'page-break'; });
83
-
84
- if (typeof Domma !== 'undefined' && Domma.forms) {
85
-
86
- if (hasPageBreaks && Domma.forms.wizard) {
87
- // --- Wizard mode ---
88
- var rawSteps = buildWizardSteps(fields, form.title);
89
- var steps = rawSteps.map(function (step) {
90
- return {
91
- title: step.title,
92
- description: step.description,
93
- fields: buildBlueprintFromFields(step.fieldGroup)
94
- };
95
- });
96
-
97
- Domma.forms.wizard(wrapper, {
98
- schema: { steps: steps },
99
- onSubmit: function (data) {
100
- return submitForm(slug, data, settings, wrapper, null);
101
- }
102
- });
103
-
104
- // Init conditional logic engine on wizard form
105
- if (window.FormLogicEngine && fields.some(function (f) { return f.logic; })) {
106
- var wizardRuntime = new window.FormLogicEngine.FormLogicRuntime(form, wrapper);
107
- wizardRuntime.init();
108
- }
109
-
110
- // Inject honeypot into the first step's form element
111
- if (settings.honeypot) {
112
- var firstForm = wrapper.querySelector('form');
113
- if (firstForm) {
114
- injectHoneypot(firstForm);
115
- }
116
- }
117
-
118
- } else if (Domma.forms.render) {
119
- // --- Standard single-step mode ---
120
- var blueprint = buildBlueprintFromFields(fields);
121
-
122
- Domma.forms.render(wrapper, blueprint, {}, {
123
- submitText: settings.submitText || 'Submit',
124
- layout: settings.layout || 'stacked',
125
- onSubmit: function (data) {
126
- return submitForm(slug, data, settings, wrapper, null);
127
- }
128
- });
129
-
130
- // Init conditional logic engine on standard form
131
- if (window.FormLogicEngine && fields.some(function (f) { return f.logic; })) {
132
- var stdRuntime = new window.FormLogicEngine.FormLogicRuntime(form, wrapper);
133
- stdRuntime.init();
134
- }
135
-
136
- if (fields.some(function (f) {
137
- return f.type === 'spacer';
138
- })) {
139
- injectSpacers(wrapper, fields);
140
- }
141
-
142
- if (settings.honeypot) {
143
- var formEl = wrapper.querySelector('form');
144
- if (formEl) injectHoneypot(formEl);
145
- }
146
- }
147
-
148
- } else {
149
- // Fallback: manual form rendering (no Domma dependency)
150
- renderManualForm(wrapper, fields.filter(function (f) {
151
- return f.type !== 'page-break' && f.type !== 'spacer';
152
- }), settings, slug, form);
153
- }
154
- })
155
- .catch(function (err) {
156
- var msg = document.createElement('p');
157
- msg.textContent = 'Form unavailable.';
158
- msg.style.cssText = 'color:#f87171;font-style:italic;';
159
- target.appendChild(msg);
160
- console.warn('[form-builder]', err.message);
161
- });
162
- }
163
-
164
- /**
165
- * After Domma renders a form, insert .fb-spacer divs at the positions
166
- * where spacer pseudo-fields appear in the original fields array.
167
- */
168
- function injectSpacers(wrapper, allFields) {
169
- var form = wrapper.querySelector('form');
170
- if (!form) return;
171
- var groups = Array.from(form.querySelectorAll('.form-group'));
172
- var groupIdx = 0;
173
- allFields.forEach(function (field) {
174
- if (field.type === 'spacer') {
175
- var spacer = document.createElement('div');
176
- spacer.className = 'fb-spacer';
177
- var target = groups[groupIdx];
178
- if (target) {
179
- form.insertBefore(spacer, target);
180
- } else {
181
- var submitBtn = form.querySelector('[type="submit"]');
182
- if (submitBtn) form.insertBefore(spacer, submitBtn);
183
- else form.appendChild(spacer);
184
- }
185
- } else if (field.type !== 'page-break') {
186
- groupIdx++;
187
- }
188
- });
189
- }
190
-
191
- function injectHoneypot(formEl) {
192
- var hpWrap = document.createElement('div');
193
- hpWrap.className = 'fb-form-honeypot';
194
- hpWrap.setAttribute('aria-hidden', 'true');
195
- var hpInput = document.createElement('input');
196
- hpInput.name = '_hp';
197
- hpInput.type = 'text';
198
- hpInput.tabIndex = -1;
199
- hpInput.autocomplete = 'off';
200
- hpWrap.appendChild(hpInput);
201
- formEl.appendChild(hpWrap);
202
- }
203
-
204
- function submitForm(slug, data, settings, wrapper, formEl) {
205
- var hp = '';
206
- if (formEl) {
207
- var hpEl = formEl.querySelector('[name="_hp"]');
208
- hp = hpEl ? hpEl.value : '';
209
- } else {
210
- var hpEl2 = wrapper.querySelector('[name="_hp"]');
211
- hp = hpEl2 ? hpEl2.value : '';
212
- }
213
-
214
- var payload = Object.assign({}, data, { _hp: hp });
215
-
216
- return fetch('/api/plugins/form-builder/submit/' + slug, {
217
- method: 'POST',
218
- headers: { 'Content-Type': 'application/json' },
219
- body: JSON.stringify(payload)
220
- })
221
- .then(function (res) { return res.json().then(function (body) { return { ok: res.ok, body: body }; }); })
222
- .then(function (result) {
223
- if (result.ok && result.body.ok) {
224
- wrapper.textContent = '';
225
- showMessage(wrapper, result.body.message || settings.successMessage || 'Thank you.', 'success');
226
- } else {
227
- showMessage(wrapper, result.body.error || 'Something went wrong.', 'error');
228
- }
229
- })
230
- .catch(function () {
231
- showMessage(wrapper, 'Unable to submit. Please check your connection.', 'error');
232
- });
233
- }
234
-
235
- // Manual form renderer — used when Domma forms API is unavailable
236
- function renderManualForm(wrapper, fields, settings, slug, formDef) {
237
- var form = document.createElement('form');
238
- form.noValidate = true;
239
-
240
- fields.forEach(function (field) {
241
- var group = document.createElement('div');
242
- group.className = 'form-group';
243
- group.style.marginBottom = '1.25rem';
244
-
245
- var label = document.createElement('label');
246
- label.className = 'form-label';
247
- label.textContent = field.label || field.name;
248
- if (field.required) {
249
- var req = document.createElement('span');
250
- req.textContent = ' *';
251
- req.style.color = '#f87171';
252
- label.appendChild(req);
253
- }
254
-
255
- var input;
256
- if (field.type === 'textarea') {
257
- input = document.createElement('textarea');
258
- input.rows = field.formConfig?.rows || 4;
259
- input.className = 'form-input';
260
- } else if (field.type === 'select') {
261
- input = document.createElement('select');
262
- input.className = 'form-input';
263
- (field.options || []).forEach(function (opt) {
264
- var o = document.createElement('option');
265
- o.value = opt.value;
266
- o.textContent = opt.label || opt.value;
267
- input.appendChild(o);
268
- });
269
- } else {
270
- input = document.createElement('input');
271
- input.type = field.type || 'text';
272
- input.className = 'form-input';
273
- if (field.placeholder) input.placeholder = field.placeholder;
274
- }
275
- input.name = field.name;
276
- input.required = field.required || false;
277
-
278
- group.appendChild(label);
279
- group.appendChild(input);
280
- form.appendChild(group);
281
- });
282
-
283
- // Honeypot
284
- if (settings.honeypot) {
285
- injectHoneypot(form);
286
- }
287
-
288
- var submitBtn = document.createElement('button');
289
- submitBtn.type = 'submit';
290
- submitBtn.className = 'btn btn-primary';
291
- submitBtn.textContent = settings.submitText || 'Submit';
292
- form.appendChild(submitBtn);
293
-
294
- form.addEventListener('submit', function (e) {
295
- e.preventDefault();
296
-
297
- var data = {};
298
- fields.forEach(function (field) {
299
- var el = form.querySelector('[name="' + field.name + '"]');
300
- if (el) data[field.name] = el.value;
301
- });
302
-
303
- // Client-side logic validation for manual fallback
304
- if (window.FormLogicEngine && formDef) {
305
- var Engine = window.FormLogicEngine;
306
- var requiredErrors = [];
307
- var validationErrors = [];
308
- fields.forEach(function (field) {
309
- var vis = Engine.evaluateFieldVisibility(field, data);
310
- if (vis === 'hidden') {
311
- delete data[field.name];
312
- return;
313
- }
314
- var required = Engine.evaluateFieldRequirement(field, data);
315
- var val = data[field.name];
316
- if (required && (!val || !String(val).trim())) {
317
- requiredErrors.push(field.label || field.name);
318
- }
319
- var errors = Engine.validateField(field, val || '', data);
320
- if (errors.length) validationErrors.push(errors[0].message);
321
- });
322
- if (requiredErrors.length || validationErrors.length) {
323
- var errParts = [];
324
- if (requiredErrors.length) errParts.push('Required: ' + requiredErrors.join(', '));
325
- if (validationErrors.length) errParts.push(validationErrors.join('; '));
326
- showMessage(wrapper, errParts.join('. '), 'error');
327
- return;
328
- }
329
- }
330
-
331
- wrapper.classList.add('fb-form-loading');
332
- submitBtn.disabled = true;
333
-
334
- submitForm(slug, data, settings, wrapper, form).finally(function () {
335
- wrapper.classList.remove('fb-form-loading');
336
- submitBtn.disabled = false;
337
- });
338
- });
339
-
340
- wrapper.appendChild(form);
341
-
342
- // Init conditional logic engine on manual form
343
- if (window.FormLogicEngine && formDef && fields.some(function (f) { return f.logic; })) {
344
- var manualRuntime = new window.FormLogicEngine.FormLogicRuntime(formDef, wrapper);
345
- manualRuntime.init();
346
- }
347
- }
348
-
349
- // Initialise all form targets on the page
350
- targets.forEach(initFormTarget);
351
- })();
352
- </script>
@@ -1,58 +0,0 @@
1
- <style>
2
- .fb-form-wrapper {
3
- max-width: 600px;
4
- margin: 2rem auto;
5
- }
6
-
7
- .fb-form-honeypot {
8
- display: none !important;
9
- visibility: hidden;
10
- }
11
-
12
- .fb-form-success {
13
- padding: 1rem 1.25rem;
14
- border-radius: 6px;
15
- background: rgba(52, 211, 153, 0.12);
16
- border: 1px solid rgba(52, 211, 153, 0.3);
17
- color: #34d399;
18
- font-size: 0.95rem;
19
- margin-top: 0.5rem;
20
- }
21
-
22
- .fb-form-error {
23
- padding: 0.75rem 1rem;
24
- border-radius: 6px;
25
- background: rgba(239, 68, 68, 0.1);
26
- border: 1px solid rgba(239, 68, 68, 0.25);
27
- color: #f87171;
28
- font-size: 0.875rem;
29
- margin-top: 0.75rem;
30
- }
31
-
32
- .fb-form-loading {
33
- opacity: 0.6;
34
- pointer-events: none;
35
- }
36
-
37
- .wizard-progress { height: 4px; background: var(--border-color, #333); border-radius: 2px; margin-bottom: 1rem; }
38
- .wizard-progress-bar { height: 100%; background: var(--primary, #5b8cff); border-radius: 2px; transition: width .3s ease; }
39
- .wizard-step-title { font-size: 1.1rem; font-weight: 600; margin-bottom: .25rem; }
40
- .wizard-step-description { font-size: .875rem; color: var(--text-muted, #888); margin-bottom: 1rem; }
41
- .wizard-nav { display: flex; justify-content: space-between; gap: .5rem; margin-top: 1rem; }
42
-
43
- .fb-field-hidden { display: none !important; }
44
- .fb-validation-error { color: var(--danger, #ef4444); font-size: .8rem; margin-top: .25rem; }
45
-
46
- .fb-form-wrapper .domma-form-field {
47
- margin-bottom: 2rem;
48
- }
49
-
50
- .fb-form-wrapper .form-group:not(.form-buttons) {
51
- margin-bottom: 2rem;
52
- }
53
-
54
- .fb-spacer {
55
- height: 2rem;
56
- }
57
- </style>
58
- <script src="/plugins/form-builder/public/form-logic-engine.js"></script>
@@ -1 +0,0 @@
1
- { "type": "commonjs" }
@@ -1,48 +0,0 @@
1
- /**
2
- * Copy Domma dist files to admin and public directories.
3
- *
4
- * NOTE: This script is now OPTIONAL.
5
- * The server serves Domma directly from node_modules/domma-js/public/dist at /dist/domma/.
6
- * Only run this if you need the files as static copies (e.g. for deployment without node_modules).
7
- *
8
- * Run: node scripts/copy-domma.js
9
- */
10
- import fs from 'fs/promises';
11
- import path from 'path';
12
- import { fileURLToPath } from 'url';
13
- import { createRequire } from 'module';
14
-
15
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
16
- const ROOT = path.resolve(__dirname, '..');
17
- const require = createRequire(import.meta.url);
18
-
19
- // Resolve from npm package
20
- const dommaPackageDir = path.dirname(require.resolve('domma-js/package.json'));
21
- const DOMMA_DIST = path.join(dommaPackageDir, 'public', 'dist');
22
-
23
- const TARGETS = [
24
- path.join(ROOT, 'admin', 'dist', 'domma'),
25
- path.join(ROOT, 'public', 'dist', 'domma')
26
- ];
27
-
28
- async function copyDir(src, dest) {
29
- await fs.mkdir(dest, { recursive: true });
30
- const entries = await fs.readdir(src, { withFileTypes: true });
31
- for (const entry of entries) {
32
- const srcPath = path.join(src, entry.name);
33
- const destPath = path.join(dest, entry.name);
34
- if (entry.isDirectory()) {
35
- await copyDir(srcPath, destPath);
36
- } else {
37
- await fs.copyFile(srcPath, destPath);
38
- }
39
- }
40
- }
41
-
42
- console.log(`Source: ${DOMMA_DIST}`);
43
- console.log('Copying Domma dist files...');
44
- for (const target of TARGETS) {
45
- await copyDir(DOMMA_DIST, target);
46
- console.log(` ✓ → ${path.relative(ROOT, target)}`);
47
- }
48
- console.log('Done.');