domma-js 0.9.6-alpha → 0.9.7-alpha

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 (44) hide show
  1. package/bin/domma-cli.js +231 -22
  2. package/package.json +1 -1
  3. package/public/dist/domma-syntax.min.js +3 -3
  4. package/public/dist/domma.css +3 -3
  5. package/public/dist/domma.esm.js +4 -4
  6. package/public/dist/domma.min.js +4 -4
  7. package/public/dist/elements.css +3 -3
  8. package/public/dist/grid.css +3 -3
  9. package/public/dist/syntax.css +3 -3
  10. package/public/dist/themes/domma-themes.css +3 -3
  11. package/templates/kickstart/README.md +139 -0
  12. package/templates/kickstart/backend/.gitkeep +0 -0
  13. package/templates/kickstart/backend/README.md +160 -0
  14. package/templates/kickstart/domma.config.json +14 -10
  15. package/templates/kickstart/frontend/assets/logo/placeholder.svg +6 -0
  16. package/templates/kickstart/frontend/css/custom.css +121 -0
  17. package/templates/kickstart/frontend/js/app.js +166 -0
  18. package/templates/kickstart/frontend/pages/about/about.js +10 -0
  19. package/templates/kickstart/frontend/pages/about/index.html +229 -0
  20. package/templates/kickstart/frontend/pages/blog/blog.js +10 -0
  21. package/templates/kickstart/frontend/pages/blog/index.html +218 -0
  22. package/templates/kickstart/frontend/pages/contact/contact.js +33 -0
  23. package/templates/kickstart/frontend/pages/contact/index.html +196 -0
  24. package/templates/kickstart/frontend/pages/cookies/cookies.js +51 -0
  25. package/templates/kickstart/frontend/pages/cookies/index.html +381 -0
  26. package/templates/kickstart/frontend/pages/docs/docs.js +28 -0
  27. package/templates/kickstart/frontend/pages/docs/index.html +286 -0
  28. package/templates/kickstart/frontend/pages/index.html +161 -0
  29. package/templates/kickstart/frontend/pages/index.js +10 -0
  30. package/templates/kickstart/frontend/pages/privacy/index.html +277 -0
  31. package/templates/kickstart/frontend/pages/privacy/privacy.js +51 -0
  32. package/templates/kickstart/frontend/pages/terms/index.html +369 -0
  33. package/templates/kickstart/frontend/pages/terms/terms.js +51 -0
  34. package/templates/kickstart-old/domma.config.json +74 -0
  35. package/templates/page-template/page.html +51 -0
  36. package/templates/page-template/page.js +10 -0
  37. /package/templates/{kickstart → kickstart-old}/about/index.html +0 -0
  38. /package/templates/{kickstart → kickstart-old}/assets/logo/placeholder.svg +0 -0
  39. /package/templates/{kickstart → kickstart-old}/blog/index.html +0 -0
  40. /package/templates/{kickstart → kickstart-old}/contact/index.html +0 -0
  41. /package/templates/{kickstart → kickstart-old}/css/custom.css +0 -0
  42. /package/templates/{kickstart → kickstart-old}/docs/index.html +0 -0
  43. /package/templates/{kickstart → kickstart-old}/index.html +0 -0
  44. /package/templates/{kickstart → kickstart-old}/js/app.js +0 -0
package/bin/domma-cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import {existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync} from 'fs';
3
+ import {existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync, cpSync} from 'fs';
4
4
  import {dirname, join, relative} from 'path';
5
5
  import {fileURLToPath} from 'url';
6
6
  import * as readline from 'readline/promises';
@@ -10,24 +10,49 @@ const __filename = fileURLToPath(import.meta.url);
10
10
  const __dirname = dirname(__filename);
11
11
 
12
12
  const THEMES = [
13
- 'charcoal-dark',
14
- 'ocean-dark',
15
- 'forest-dark',
16
- 'sunset-light',
17
- 'silver-light',
18
- 'ocean-light',
19
- 'forest-light',
20
- 'sunset-dark',
21
- 'royal-dark',
22
- 'lemon-light'
13
+ 'charcoal-dark', 'ocean-dark', 'forest-dark', 'sunset-light',
14
+ 'silver-light', 'ocean-light', 'forest-light', 'sunset-dark',
15
+ 'royal-dark', 'lemon-light'
23
16
  ];
24
17
 
25
18
  // Parse command-line arguments
26
19
  const args = process.argv.slice(2);
27
- const quickMode = args.includes('--quick');
20
+ const command = args[0];
28
21
 
29
- // ASCII Art Banner
30
- console.log(`
22
+ // Command routing
23
+ // Check if first arg is a flag (starts with --)
24
+ if (command && command.startsWith('--')) {
25
+ // Treat flags as init command
26
+ handleInit();
27
+ } else {
28
+ switch (command) {
29
+ case 'init':
30
+ case undefined:
31
+ handleInit();
32
+ break;
33
+ case 'add':
34
+ handleAdd();
35
+ break;
36
+ case 'help':
37
+ case '--help':
38
+ case '-h':
39
+ showHelp();
40
+ break;
41
+ default:
42
+ console.error(`Unknown command: ${command}`);
43
+ showHelp();
44
+ process.exit(1);
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Handle project initialisation
50
+ */
51
+ async function handleInit() {
52
+ const quickMode = args.includes('--quick');
53
+
54
+ // ASCII Art Banner
55
+ console.log(`
31
56
  ╔═══════════════════════════════════════╗
32
57
  ║ ║
33
58
  ║ Welcome to Domma CLI! ║
@@ -37,7 +62,6 @@ console.log(`
37
62
  Let's set up your project.
38
63
  `);
39
64
 
40
- async function main() {
41
65
  let projectName = 'my-app';
42
66
  let theme = 'charcoal-dark';
43
67
  let includeThemeSelector = false;
@@ -78,6 +102,7 @@ async function main() {
78
102
 
79
103
  // Find templates directory
80
104
  const templatesDir = join(__dirname, '..', 'templates', 'kickstart');
105
+ const distDir = join(__dirname, '..', 'public', 'dist');
81
106
 
82
107
  if (!existsSync(templatesDir)) {
83
108
  console.error(`\n ✗ Error: Templates directory not found at ${templatesDir}`);
@@ -98,15 +123,180 @@ async function main() {
98
123
  // Copy all templates with variable substitution
99
124
  copyTemplatesRecursive(templatesDir, process.cwd(), vars);
100
125
 
126
+ // Copy Domma dist files to frontend/dist
127
+ const frontendDistDir = join(process.cwd(), 'frontend', 'dist');
128
+ console.log(`\n Copying Domma distribution files...\n`);
129
+
130
+ if (!existsSync(frontendDistDir)) {
131
+ mkdirSync(frontendDistDir, {recursive: true});
132
+ }
133
+
134
+ // Copy required dist files
135
+ const distFiles = [
136
+ 'domma.min.js',
137
+ 'domma.css',
138
+ 'grid.css',
139
+ 'elements.css',
140
+ 'syntax.css',
141
+ 'domma-syntax.min.js'
142
+ ];
143
+
144
+ for (const file of distFiles) {
145
+ const srcPath = join(distDir, file);
146
+ const destPath = join(frontendDistDir, file);
147
+ if (existsSync(srcPath)) {
148
+ cpSync(srcPath, destPath);
149
+ console.log(` ✓ Copied ${file}`);
150
+ }
151
+ }
152
+
153
+ // Copy themes folder
154
+ const themesDir = join(distDir, 'themes');
155
+ const destThemesDir = join(frontendDistDir, 'themes');
156
+ if (existsSync(themesDir)) {
157
+ cpSync(themesDir, destThemesDir, {recursive: true});
158
+ console.log(` ✓ Copied themes/`);
159
+ }
160
+
101
161
  console.log(`\n ✓ Done! Your project "${projectName}" is ready.\n`);
102
162
  console.log(` Next steps:`);
103
- console.log(` 1. Open index.html in your browser`);
163
+ console.log(` 1. Open frontend/pages/index.html in your browser`);
104
164
  console.log(` 2. Edit domma.config.json to customise`);
105
- console.log(` 3. Read the docs: https://github.com/dcbw-it/domma\n`);
165
+ console.log(` 3. Add new pages: npx domma-js add page <name>`);
166
+ console.log(` 4. Read the docs: https://github.com/dcbw-it/domma\n`);
167
+ }
168
+
169
+ /**
170
+ * Handle 'add' sub-commands
171
+ */
172
+ async function handleAdd() {
173
+ const subCommand = args[1];
174
+
175
+ switch (subCommand) {
176
+ case 'page':
177
+ await handleAddPage();
178
+ break;
179
+ default:
180
+ console.error(`Unknown add command: ${subCommand}`);
181
+ console.log('Usage: npx domma-js add page <name>');
182
+ process.exit(1);
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Handle adding a new page
188
+ */
189
+ async function handleAddPage() {
190
+ const quickMode = args.includes('--quick');
191
+ let pageName = args[2];
192
+
193
+ // Check if we're in a Domma project
194
+ const configPath = join(process.cwd(), 'domma.config.json');
195
+ if (!existsSync(configPath)) {
196
+ console.error('\n ✗ Error: Not in a Domma project directory');
197
+ console.error(' Run this command from your project root (where domma.config.json is located)\n');
198
+ process.exit(1);
199
+ }
200
+
201
+ if (!pageName && quickMode) {
202
+ console.error('Page name required with --quick flag');
203
+ console.log('Usage: npx domma-js add page <name> --quick');
204
+ process.exit(1);
205
+ }
206
+
207
+ if (!quickMode) {
208
+ const rl = readline.createInterface({input, output});
209
+
210
+ if (!pageName) {
211
+ const nameAnswer = await rl.question(' Page name: ');
212
+ pageName = nameAnswer.trim();
213
+ }
214
+
215
+ if (!pageName) {
216
+ console.error(' ✗ Page name is required');
217
+ rl.close();
218
+ process.exit(1);
219
+ }
220
+
221
+ rl.close();
222
+ }
223
+
224
+ // Validate and sanitize page name
225
+ pageName = pageName.toLowerCase().replace(/[^a-z0-9-]/g, '-');
226
+
227
+ // Create page
228
+ createPage(pageName);
229
+ }
230
+
231
+ /**
232
+ * Create a new page from template
233
+ */
234
+ function createPage(pageName) {
235
+ const pagesDir = join(process.cwd(), 'frontend', 'pages', pageName);
236
+
237
+ if (existsSync(pagesDir)) {
238
+ console.error(`\n ✗ Page "${pageName}" already exists`);
239
+ process.exit(1);
240
+ }
241
+
242
+ // Create directory
243
+ mkdirSync(pagesDir, {recursive: true});
244
+
245
+ // Get templates
246
+ const pageTemplateDir = join(__dirname, '..', 'templates', 'page-template');
247
+
248
+ if (!existsSync(pageTemplateDir)) {
249
+ console.error(`\n ✗ Error: Page template not found at ${pageTemplateDir}`);
250
+ process.exit(1);
251
+ }
252
+
253
+ // Read templates
254
+ const htmlTemplate = readFileSync(join(pageTemplateDir, 'page.html'), 'utf-8');
255
+ const jsTemplate = readFileSync(join(pageTemplateDir, 'page.js'), 'utf-8');
256
+
257
+ // Get project config for theme
258
+ let theme = 'charcoal-dark';
259
+ const configPath = join(process.cwd(), 'domma.config.json');
260
+ if (existsSync(configPath)) {
261
+ try {
262
+ const config = JSON.parse(readFileSync(configPath, 'utf-8'));
263
+ theme = config.theme?.default || theme;
264
+ } catch (e) {
265
+ // Use default theme
266
+ }
267
+ }
268
+
269
+ // Variable substitution
270
+ const titleCase = pageName.split('-').map(w =>
271
+ w.charAt(0).toUpperCase() + w.slice(1)
272
+ ).join(' ');
273
+
274
+ const vars = {
275
+ '{{pageName}}': pageName,
276
+ '{{pageTitle}}': titleCase,
277
+ '{{theme}}': theme
278
+ };
279
+
280
+ let html = htmlTemplate;
281
+ let js = jsTemplate;
282
+
283
+ for (const [key, value] of Object.entries(vars)) {
284
+ html = html.replaceAll(key, value);
285
+ js = js.replaceAll(key, value);
286
+ }
287
+
288
+ // Write files
289
+ writeFileSync(join(pagesDir, 'index.html'), html);
290
+ writeFileSync(join(pagesDir, `${pageName}.js`), js);
291
+
292
+ console.log(`\n ✓ Page created: frontend/pages/${pageName}/`);
293
+ console.log(` - index.html`);
294
+ console.log(` - ${pageName}.js\n`);
295
+ console.log(` Don't forget to add it to your navbar in domma.config.json!\n`);
106
296
  }
107
297
 
108
298
  /**
109
- * Recursively copy templates with variable substitution
299
+ * Copy templates recursively with variable substitution
110
300
  */
111
301
  function copyTemplatesRecursive(srcDir, destDir, vars) {
112
302
  const items = readdirSync(srcDir);
@@ -138,7 +328,26 @@ function copyTemplatesRecursive(srcDir, destDir, vars) {
138
328
  }
139
329
  }
140
330
 
141
- main().catch((error) => {
142
- console.error(`\n ✗ Error: ${error.message}`);
143
- process.exit(1);
144
- });
331
+ /**
332
+ * Show help information
333
+ */
334
+ function showHelp() {
335
+ console.log(`
336
+ Domma CLI - Project scaffolding and management
337
+
338
+ Commands:
339
+ npx domma-js Initialize a new Domma project
340
+ npx domma-js init Initialize a new Domma project
341
+ npx domma-js add page <name> Add a new page
342
+ --quick Skip interactive prompts
343
+
344
+ Options:
345
+ --help, -h Show this help message
346
+
347
+ Examples:
348
+ npx domma-js # Interactive project setup
349
+ npx domma-js --quick # Quick project setup with defaults
350
+ npx domma-js add page dashboard # Add a dashboard page (interactive)
351
+ npx domma-js add page faq --quick # Add FAQ page (non-interactive)
352
+ `);
353
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-js",
3
- "version": "0.9.6-alpha",
3
+ "version": "0.9.7-alpha",
4
4
  "description": "Dynamic Object Manipulation & Modeling API - A complete front-end toolkit.",
5
5
  "main": "public/dist/domma.min.js",
6
6
  "module": "public/dist/domma.esm.js",
@@ -1,8 +1,8 @@
1
1
  /*!
2
- * Domma Syntax Highlighter v0.9.5-alpha
2
+ * Domma Syntax Highlighter v0.9.6-alpha
3
3
  * Lightweight code syntax highlighting for JavaScript, HTML, and CSS
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-01-16T09:03:27.082Z
6
- * Commit: 72d7b45
5
+ * Built: 2026-01-16T11:22:47.592Z
6
+ * Commit: 90ec825
7
7
  */
8
8
  !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).DommaSyntax={})}(this,function(t){"use strict";const e={javascript:[{type:"comment",pattern:/\/\*[\s\S]*?\*\//g},{type:"comment",pattern:/\/\/.*/g},{type:"template-string",pattern:/`(?:\\.|[^`\\])*`/g},{type:"string",pattern:/"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/g},{type:"keyword",pattern:/\b(const|let|var|function|return|if|else|for|while|do|break|continue|switch|case|default|try|catch|finally|throw|async|await|class|extends|static|new|this|super|import|export|from|as|default|yield|typeof|instanceof|in|of|delete|void)\b/g},{type:"boolean",pattern:/\b(true|false|null|undefined|NaN|Infinity)\b/g},{type:"number",pattern:/\b\d+\.?\d*([eE][+-]?\d+)?\b/g},{type:"function",pattern:/\b([a-zA-Z_$][\w$]*)\s*(?=\()/g},{type:"class-name",pattern:/\b[A-Z][\w$]*\b/g},{type:"operator",pattern:/[+\-*/%=<>!&|^~?:]+|===|!==|==|!=|<=|>=|&&|\|\||<<|>>|>>>/g},{type:"punctuation",pattern:/[{}[\]();,.]/g}],html:[{type:"comment",pattern:/<!--[\s\S]*?-->/g},{type:"doctype",pattern:/<!DOCTYPE[^>]*>/gi},{type:"tag-open",pattern:/<\/?[a-zA-Z][\w-]*/g},{type:"tag-close",pattern:/\/?>/g},{type:"attr-name",pattern:/\s+[a-zA-Z:@][\w:.-]*(?=\s*=)/g},{type:"attr-value",pattern:/=\s*"[^"]*"|=\s*'[^']*'/g},{type:"entity",pattern:/&[#\w]+;/g}],css:[{type:"comment",pattern:/\/\*[\s\S]*?\*\//g},{type:"at-rule",pattern:/@[\w-]+/g},{type:"selector",pattern:/[.#]?[a-zA-Z][\w-]*(?=\s*[{,])/g},{type:"property",pattern:/\b[\w-]+(?=\s*:)/g},{type:"string",pattern:/"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/g},{type:"function",pattern:/\b[\w-]+(?=\()/g},{type:"important",pattern:/!important\b/g},{type:"number",pattern:/\b\d+\.?\d*(px|em|rem|%|vh|vw|pt|cm|mm|in|pc|ex|ch|vmin|vmax|fr)?\b/g},{type:"color",pattern:/#[\da-fA-F]{3,8}\b/g},{type:"punctuation",pattern:/[{}:;,()]/g}]};function n(t){const e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};return t.replace(/[&<>"']/g,t=>e[t])}class a{constructor(){this.config={autoDetect:!0,preserveOriginal:!0,selector:".code-block",showLanguageBadge:!1,languagePrefix:"language-"}}highlight(t,a=null){const r="string"==typeof t?document.querySelector(t):t;if(!r||r.hasAttribute("data-syntax-highlighted"))return!1;if(!a&&this.config.autoDetect){const t=Array.from(r.classList).find(t=>t.startsWith(this.config.languagePrefix));t&&(a=t.substring(this.config.languagePrefix.length))}if(!a||!e[a])return!1;const o=r.textContent||"";this.config.preserveOriginal&&r.setAttribute("data-original-code",o);const i=function(t,a){const r=e[a];if(!r)return n(t);const o=[];for(const{type:e,pattern:n}of r){if("html"===a&&"entity"===e)continue;let r;for(n.lastIndex=0;null!==(r=n.exec(t));)o.push({start:r.index,end:r.index+r[0].length,text:r[0],type:e})}o.sort((t,e)=>t.start-e.start);const i=[];let s=0;for(const t of o)t.start>=s&&(i.push(t),s=t.end);let c="",p=0;for(const e of i)e.start>p&&(c+=n(t.substring(p,e.start))),c+=`<span class="syntax-${e.type}">${n(e.text)}</span>`,p=e.end;return p<t.length&&(c+=n(t.substring(p))),c}(o,a);return r.innerHTML=i,r.setAttribute("data-syntax-highlighted","true"),r.setAttribute("data-language",a),this.config.showLanguageBadge&&this.addLanguageBadge(r,a),!0}scan(t={}){const e=t.selector||this.config.selector,n=document.querySelectorAll(e);let a=0;return n.forEach(e=>{this.highlight(e,t.language||null)&&(this.addCopyButton(e),a++)}),a}register(t,n){t&&Array.isArray(n)?e[t]=n:console.error("SyntaxHighlighter: Invalid language registration")}configure(t){return t?(Object.assign(this.config,t),this.config):{...this.config}}addLanguageBadge(t,e){if(t.querySelector(".syntax-language-badge"))return;const n=document.createElement("div");n.className="syntax-language-badge",n.textContent=e.toUpperCase(),t.style.position="relative",t.insertBefore(n,t.firstChild)}getLanguages(){return Object.keys(e)}isLanguageSupported(t){return t in e}addCopyButton(t){if(t.parentElement&&t.parentElement.classList.contains("code-block-wrapper"))return;const e=document.createElement("div");e.className="code-block-wrapper";const n=document.createElement("button");n.className="code-block-copy",n.setAttribute("aria-label","Copy code to clipboard"),n.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>',n.addEventListener("click",async()=>{const e=t.getAttribute("data-original-code")||t.textContent;try{if(navigator.clipboard&&navigator.clipboard.writeText)await navigator.clipboard.writeText(e);else{const t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t)}n.classList.add("copied"),n.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"></polyline></svg>',setTimeout(()=>{n.classList.remove("copied"),n.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>'},2e3)}catch(t){console.error("Failed to copy code:",t)}}),t.parentNode.insertBefore(e,t),e.appendChild(t),e.appendChild(n)}}const r=new a;"undefined"!=typeof document&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{r.scan()}):setTimeout(()=>r.scan(),0)),"undefined"!=typeof window&&(window.Domma&&(window.Domma.syntax=r),window.DommaSyntax=r),t.LANGUAGES=e,t.SyntaxHighlighter=a,t.default=r,t.syntax=r,Object.defineProperty(t,"__esModule",{value:!0})});
@@ -1,9 +1,9 @@
1
1
  /*!
2
- * Domma Core CSS v0.9.5-alpha
2
+ * Domma Core CSS v0.9.6-alpha
3
3
  * Dynamic Object Manipulation & Modeling API
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-01-16T09:03:57.612Z
6
- * Commit: 72d7b45
5
+ * Built: 2026-01-16T11:23:01.056Z
6
+ * Commit: 90ec825
7
7
  */
8
8
 
9
9
  /**