minimaz-cli 0.3.5 → 0.4.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.
package/README.md CHANGED
@@ -35,6 +35,8 @@ npx mz b
35
35
  npx mz v
36
36
  ```
37
37
 
38
+ > During `npm install`, a post-install script runs to finalize setup automatically.
39
+
38
40
  ## 📁 Project Structure
39
41
 
40
42
  ```txt
@@ -54,34 +56,44 @@ Customize your build using a `minimaz.config.json` file:
54
56
 
55
57
  ```json
56
58
  {
57
- "src": "src",
58
- "dist": "dist",
59
- "public": "public",
60
- "bundling": {
61
- "css": true,
62
- "js": true
63
- },
64
- "minify": {
65
- "html": true,
66
- "css": true,
67
- "js": true,
68
- "ts": true
69
- },
70
- "replace": {
71
- "../public/": "public/"
72
- },
73
- "folders": {
74
- "src": "",
75
- "public": "public"
76
- },
77
- "styles": [
78
- "../node_modules/some-package/dist/library.css",
79
- "C:/Users/YourUser/Desktop/custom.css"
80
- ],
81
- "scripts": [
82
- "../node_modules/some-package/dist/library.js",
83
- "D:/Scripts/custom.js"
84
- ]
59
+ outDir: "dist",
60
+ bundling: {
61
+ css: {
62
+ enabled: true,
63
+ outFile: "styles.css"
64
+ },
65
+ js: {
66
+ enabled: true,
67
+ outFile: "scripts.js"
68
+ },
69
+ outDir: ""
70
+ },
71
+ minify: {
72
+ "html": true,
73
+ "css": true,
74
+ "js": true,
75
+ "ts": true
76
+
77
+ },
78
+
79
+ replace: {
80
+ "../public/": "public/"
81
+ },
82
+
83
+ styles: [
84
+ "style.css",
85
+ "style-2.css"
86
+ ],
87
+
88
+ scripts: [
89
+ "script.js",
90
+ "script-2.js"
91
+ ],
92
+
93
+ folders: {
94
+ src: "",
95
+ public: "public"
96
+ }
85
97
  }
86
98
  ```
87
99
 
@@ -109,46 +121,54 @@ minimaz clear # Delete the dist folder
109
121
  mz c # alias
110
122
 
111
123
  # -----------------------------
112
- # Init
124
+ # Config
113
125
  # -----------------------------
114
- minimaz init <project-name> # Initialize a new project with default template
115
- mz i <project-name> # alias
116
-
117
- minimaz init <project-name> --template <name> # Use a specific template
118
- mz i <project-name> -t <name> # alias
126
+ minimaz config # Create or update global configuration ~/.minimaz/
127
+ mz config --overwrite # Overwrites default templates and settings.json
119
128
 
120
- minimaz init <project-name> --npm # Initialize npm project
121
- minimaz init <project-name> --git # Initialize git repository
129
+ # -----------------------------
130
+ # Init
131
+ # -----------------------------
132
+ minimaz init <project-name> [options] # Initialize a new project
133
+ mz i <project-name> [options] # Alias
122
134
 
123
- # Specify git provider or remote URL
124
- minimaz init <project-name> --git --gitprovider <provider-or-url>
125
- mz i <project-name> --git --gitprovider github # alias example
135
+ Options:
136
+ -t, --template <name> # Use a specific template (default: 'default')
137
+ --npm # Initialize npm project (creates package.json and runs npm install)
138
+ --git # Initialize git repository
139
+ --gitprovider <provider> # Git provider: 'github', 'gitlab', or URL to existing repo
140
+ --gitremote <url> # Specify custom remote URL for git
126
141
 
127
142
  # -----------------------------
128
143
  # Help
129
144
  # -----------------------------
130
145
  minimaz help # Show general help
131
- mz h # alias
146
+ mz h # alias
132
147
  minimaz help <command> # Show help for a specific command
133
- mz h build # alias example
148
+ mz h build # alias example
134
149
 
135
150
  # -----------------------------
136
151
  # Template management
137
152
  # -----------------------------
138
- minimaz template <template-path> # Save current folder as a template
139
- minimaz t <template-path> # alias
140
-
141
- minimaz template --list # List available global templates
142
- minimaz t -l # alias
143
-
144
- minimaz template --delete <template-name> # Delete a saved template
145
- minimaz t -d <template-name> # alias
146
-
147
- minimaz template --update <template-name> # Update a specific template from current folder
148
- minimaz t -u <template-name> # alias
149
-
150
- minimaz template --update # Update all templates from node_modules
151
- minimaz t -u # alias
153
+ minimaz template [options] [<folder-path>] # Save, list, update, or delete templates
154
+ mz t [options] [<folder-path>] # Alias
155
+
156
+ Options:
157
+ -l, --list # List all global templates (~/.minimaz/templates)
158
+ -d, --delete <name> # Delete a global template by name (asks confirmation)
159
+ -u, --update [name] # Update templates
160
+ # - With a name → updates that template from current folder
161
+ # - Without argument → updates all templates from installed package defaults
162
+
163
+ Default action (no options):
164
+ Saves the specified folder (or current folder if none provided) as a new global template.
165
+ If template already exists, asks for confirmation before overwriting.
166
+
167
+ Notes:
168
+ * Global templates are stored in `~/.minimaz/templates`.
169
+ * Interactive prompts are used to confirm overwrite or deletion.
170
+ * If specified folder does not exist, you can choose to use the current folder instead.
171
+ * Errors are thrown if operations fail or are cancelled.
152
172
 
153
173
  # -----------------------------
154
174
  # Version
package/bin/cli.js CHANGED
@@ -1,17 +1,19 @@
1
1
  #!/usr/bin/env node
2
- var ht=Object.defineProperty;var d=(t,e)=>()=>(t&&(e=t(t=0)),e);var bt=(t,e)=>{for(var i in e)ht(t,i,{get:e[i],enumerable:!0})};import g from"fs-extra";import h from"path";import M from"clean-css";import{minify as xt}from"html-minifier-terser";import{minify as z}from"terser";import F from"typescript";async function I(){let t=await G(),e=u(),i=h.resolve(e,t.dist);if(await T(i),await g.ensureDir(i),!t.folders||Object.keys(t.folders).length===0){r("warn","No folders defined in config. Nothing to build.");return}for(let[n,s]of Object.entries(t.folders))r("debug",`Building folder: ${n} -> /${s}`),await vt(n,s,t,i);r("success",`Build completed. Output saved in /${t.dist}`)}async function vt(t,e,i,n){let s=u([t]),a=h.join(n,e);if(!await g.pathExists(s)){r("warn",`Folder not found: ${t}`);return}let o={css:[],js:[]};await V(s,a,i,o),t===i.src&&await zt(o,i,n),r("success",`Processed folder: ${t} -> /${e}`)}async function V(t,e,i,n){await g.ensureDir(e);for(let s of await g.readdir(t)){let a=h.join(t,s),o=h.join(e,s),l=await g.stat(a);if(r("debug",`Found ${l.isDirectory()?"DIRECTORY":"FILE"}: ${s}`),l.isDirectory()){await V(a,o,i,n);continue}await $t(a,o,i,n)}}async function $t(t,e,i,n){switch(r("debug",`Processing file: ${t}`),h.extname(t).toLowerCase()){case".html":await Ct(t,e,i);break;case".css":{await jt(t,e,i,n.css);break}case".js":{await Pt(t,e,i,n.js);break}case".ts":{await Et(t,e,i,n.js);break}default:await g.copy(t,e)}}async function Ct(t,e,i){let n=await S(t,i.replace),s=/<script([^>]*)>([\s\S]*?)<\/script>/gi,a=0,o="",l;for(;(l=s.exec(n))!==null;){let[c,x,v]=l;if(o+=n.slice(a,l.index),a=l.index+c.length,/src=/i.test(x)){o+=c;continue}let E=(x.match(/type=["']([^"']+)["']/i)?.[1]||"").toLowerCase(),Y=/module/i.test(E),yt=/nomodule/i.test(x);if(E==="application/json")try{let C=JSON.stringify(JSON.parse(v));o+=`<script${x}>${C}</script>`}catch(C){r("warn",`Invalid JSON in ${t}: ${C}`),o+=c}else if(E===""||E==="text/javascript"||Y||yt)try{let C=await z(v,{format:{semicolons:!0},module:Y});o+=`<script${x}>${C.code||""}</script>`}catch(C){r("warn",`JS minify error in ${t}: ${C}`),o+=c}else o+=c}o+=n.slice(a),i.minify?.html&&(o=await xt(o,{collapseWhitespace:!0,removeComments:!0,minifyCSS:i.minify.css,minifyJS:!1})),await g.outputFile(e,o)}async function jt(t,e,i,n){let s=await S(t,i.replace);if(i.bundling?.css)n.push(s);else{let a=s;if(i.minify?.css){let o=new M().minify(s);o.warnings.length&&o.warnings.forEach(l=>r("warn",l)),a=o.styles}await g.outputFile(e,a)}}async function Pt(t,e,i,n){let s=await S(t,i.replace);if(i.bundling?.js)n.push(s);else{let a=s;i.minify?.js&&(a=(await z(s)).code??""),await g.outputFile(e,a)}}async function Et(t,e,i,n){let s=await S(t,i.replace),o=F.transpileModule(s,{compilerOptions:{module:F.ModuleKind.ESNext,target:F.ScriptTarget.ES2020,sourceMap:!1,strict:!0}}).outputText;if(i.bundling?.js)n.push(o);else{let l=o;i.minify?.js&&(l=(await z(l)).code??""),await g.outputFile(e.replace(/\.ts$/,".js"),l)}}async function zt(t,e,i){await K(e.styles,t.css,e,"css",!!e.bundling?.css,i),await K(e.scripts,t.js,e,"js",!!e.bundling?.js,i),e.bundling?.css&&await St(t.css,e,i),e.bundling?.js&&await Tt(t.js,e,i)}async function K(t,e,i,n,s,a){if(t?.length)for(let o of t){let l=u([o]);if(!await g.pathExists(l)){r("warn",`File not found: ${o} `);continue}let c=await g.readFile(l,"utf-8");if(c=k(c,i.replace),s)e.push(c);else{if(n==="css"&&i.minify?.css){let v=new M().minify(c);v.warnings.length&&v.warnings.forEach(E=>r("warn",E)),c=v.styles}else if(n==="js"&&i.minify?.js)try{c=(await z(c)).code??""}catch(v){r("warn",`JS minify failed for external file ${o}: ${v} `)}let x=h.basename(o);await g.outputFile(h.join(a,x),c),r("info",`Copied external ${n} file: ${x} `)}}}async function St(t,e,i){if(!t.length)return;let n=t.join("");if(e.minify?.css){let s=new M().minify(n);s.warnings.length&&s.warnings.forEach(a=>r("warn",a)),n=s.styles}await g.outputFile(h.join(i,"style.css"),n)}async function Tt(t,e,i){if(!t.length)return;let n=t.join("");if(e.minify?.js)try{n=(await z(n)).code??""}catch(s){r("warn",`JS minify failed: ${s} `)}n&&await g.outputFile(h.join(i,"script.js"),n)}var Q=d(()=>{"use strict";f()});import L from"fs-extra";async function B(t,e){let i=await X(e.template),n=u([t]);if(!await L.pathExists(i))throw new Error(`Template '${e.template}' not found.`);if(await L.pathExists(n))throw new Error(`Target directory '${n}' already exists.`);r("debug",`Copying template from '${i}' to '${n}'`),await L.copy(i,n),r("debug","Initializing minimaz.config.json..."),await R(D,[n,"minimaz.config.json"]),(e.npm!==void 0?!!e.npm:(await y("Init NPM? [Y/n]:","y")).toLowerCase().startsWith("y"))&&await Ot(n,t),(e.git!==void 0?!!e.git:(await y("Init Git repository? [Y/n]:","y")).toLowerCase().startsWith("y"))&&await Rt(t,n,e.gitprovider),r("success",`Project '${t}' created using template '${e.template}'.`)}async function Rt(t,e,i,n="origin"){i||(i=(await y("Select a provider or paste a url to connect your existing repo (cli tools needed) [LOCAL/github/gitlab]:","local")).toLowerCase().trim()),r("info","Initializing Git repository..."),r("debug","Initializing gitignore..."),await R(tt,[e,".gitignore"]),r("debug","Running git init..."),await j("git",["init"],e),i?(await Dt(t,e,i,n),r("success","Git repository initialized.")):r("info","Git repository initialized locally (no remote).")}async function Dt(t,e,i,n="origin"){if(/^https?:\/\//.test(i)||i.startsWith("git@")){r("info",`Connecting existing remote '${i}'`),await j("git",["remote","add",n,i],e);return}if(i==="github"){r("info",`Creating GitHub repository '${t}'`),await j("gh",["repo","create",t,"--private","--source=.","--remote",n],e);return}if(i==="gitlab"){r("info",`Creating GitLab repository '${t}'`);let s=process.env.GITLAB_USER;if(!s)throw new Error("GITLAB_USER environment variable not set");await j("glab",["repo","create",t,"--source=."],e),await j("git",["remote","add",n,`git@gitlab.com:${s}/${t}.git`],e);return}throw new Error(`Unsupported git provider or remote: '${i}'`)}async function Ot(t,e){r("info","Initializing NPM..."),await R({name:e,...Z},[t,"package.json"]),r("debug","Running npm install..."),await j("npm",["i"],t)}var q=d(()=>{"use strict";f()});function O(t){if(t){let e=A[t];if(!e){console.log(`No help found for command: ${t}
2
+ var vt=Object.defineProperty;var u=(t,e)=>()=>(t&&(e=t(t=0)),e);var $t=(t,e)=>{for(var i in e)vt(t,i,{get:e[i],enumerable:!0})};import d from"fs-extra";import h from"path";import q from"clean-css";import{minify as Pt}from"html-minifier-terser";import{minify as Q}from"terser";import{transform as jt,build as Ct}from"esbuild";async function G(){let t=await U(),e=h.resolve(f(),t.outDir);await O(e),await d.ensureDir(e);let i={outDir:Ot(t,e),css:[],js:[]};if(await d.ensureDir(i.outDir),!t.folders||Object.keys(t.folders).length===0){s("warn","No folders defined in config. Nothing to build.");return}for(let[n,o]of Object.entries(t.folders))s("debug",`Building folder: ${n} -> /${o}`),await Et(f([n]),h.join(e,o),t,i);t.styles?.length&&await K(e,t.styles,i,t),t.scripts?.length&&await K(e,t.scripts,i,t),t.bundling?.css&&await Tt(i.css,!!t.minify?.css,i.outDir),t.bundling?.js&&await Ft(i.js,!!t.minify?.js,i.outDir),s("success",`Build completed. Output saved in /${t.outDir}`)}async function Et(t,e,i,n){if(!await d.pathExists(t)){s("warn",`Folder not found: ${t}`);return}await B(t,e,i,n),s("success",`Processed folder: ${t} -> /${e}`)}async function B(t,e,i,n){await d.ensureDir(e);for(let o of await z(t)){let r=h.join(t,o),a=h.join(e,o),l=await d.stat(r);if(s("debug",`Found ${l.isDirectory()?"DIRECTORY":"FILE"}: ${o}`),l.isDirectory()){await B(r,a,i,n);continue}let y=await L(r,i.replace);if(y.length>0){let m=h.extname(r).toLowerCase();await X({src:r,dest:a,content:y,ext:m},i,n)}}}async function X(t,e,i){switch(s("debug",`Processing file: ${t.src}`),t.ext){case".html":await Dt(t,e);break;case".css":{await St(t,i.css,!!e.bundling?.css,!!e.minify?.css);break}case".js":{await Z(t,i.js,!!e.bundling?.js,!!e.minify?.js);break}case".tsx":case".ts":{await zt(t,i.js,!!e.bundling?.js,!!e.minify?.js);break}default:await d.copy(t.src,t.dest)}}async function Dt(t,e){let i=/<script([^>]*)>([\s\S]*?)<\/script>/gi,n=0,o="",r;for(;(r=i.exec(t.content))!==null;){let[a,l,y]=r;if(o+=t.content.slice(n,r.index),n=r.index+a.length,/src=/i.test(l)){o+=a;continue}let m=(l.match(/type=["']([^"']+)["']/i)?.[1]||"").toLowerCase(),p=/module/i.test(m),S=/nomodule/i.test(l);if(m==="application/json")try{let c=JSON.stringify(JSON.parse(y));o+=`<script${l}>${c}</script>`}catch(c){s("warn",`Invalid JSON in ${t.src}: ${c}`),o+=a}else if(m===""||m==="text/javascript"||p||S)try{let c=await Q(y,{format:{semicolons:!0},module:p});o+=`<script${l}>${c.code||""}</script>`}catch(c){s("warn",`JS minify error in ${t.src}: ${c}`),o+=a}else o+=a}o+=t.content.slice(n),e.minify?.html&&(o=await Pt(o,{collapseWhitespace:!0,removeComments:!0,minifyCSS:e.minify.css,minifyJS:!1})),await d.outputFile(t.dest,o)}async function St(t,e,i,n){if(i)e.push(t.content);else{let o=t.content;if(n){let r=new q().minify(t.content);r.warnings.length&&r.warnings.forEach(a=>s("warn",a)),o=r.styles}await d.outputFile(t.dest,o)}}async function Z(t,e,i,n){if(/require\s*\(|module\.exports|exports\./.test(t.content)&&s("warn","CommonJS detected consider converting to ESM"),i)e.push(t.content);else{let o=t.content;n&&(o=(await Q(o)).code??""),await d.outputFile(t.dest,o)}}async function zt(t,e,i,n){/require\s*\(|module\.exports|exports\./.test(t.content)&&s("warn",`CommonJS detected in ${t.src}, consider converting to ESM`);let o=t.ext===".ts"?"ts":"tsx",a=(await jt(t.content,{loader:o,target:"es2020",format:"esm",sourcemap:!1})).code,l=t.dest.replace(/\.(ts|tsx)$/i,".js");await Z({src:t.src,dest:l,content:a,ext:"js"},e,i,n)}async function K(t,e,i,n){s("info","Processing externals...");for(let o of e){let r=f([o]);if(!await d.pathExists(r)){s("warn",`External not found: ${o}`);continue}if((await d.stat(r)).isDirectory()){s("debug",`Processing external folder: ${o}`),await B(r,t,n,i);continue}s("debug",`Processing external file: ${o}`);let l=h.extname(r).toLowerCase(),y=await L(r,n.replace);await X({src:r,dest:h.join(i.outDir,h.basename(r)),content:y,ext:l},n,i)}}async function Tt(t,e,i){if(!t.length)return;let n=t.join("");if(e){let o=new q().minify(n);o.warnings.length&&o.warnings.forEach(r=>s("warn",r)),n=o.styles}await d.outputFile(h.join(i,"style.css"),n)}async function Ft(t,e,i){if(t.length)try{let n=await Ct({stdin:{contents:t.join(`
3
+ `),resolveDir:i,loader:"js",sourcefile:"bundle.js"},bundle:!0,format:"esm",minify:e,sourcemap:!1,write:!1});await d.outputFile(h.join(i,"script.js"),n.outputFiles[0].text),s("success",`JS bundle written to /${i}/script.js`)}catch(n){s("warn",`ESBuild JS bundle failed: ${n}`)}}function Ot(t,e){return t.bundling?.outDir?h.join(e,t.bundling.outDir):e}var tt=u(()=>{"use strict";w()});import et from"fs-extra";async function J(t,e){let i=f([t]);if(await et.pathExists(i))throw new Error(`Target directory '${i}' already exists.`);let n=await nt(e.template);s("debug",`Copying template from '${n}' to '${i}'`),await et.copy(n,i),s("debug","Initializing minimaz.config.json..."),await j(R,[i,"minimaz.config.json"],!1),(e.npm!==void 0?!!e.npm:(await v("Init NPM? [Y/n]:","y")).toLowerCase().startsWith("y"))&&await It(i,t),(e.git!==void 0?!!e.git:(await v("Init Git repository? [Y/n]:","y")).toLowerCase().startsWith("y"))&&await Rt(t,i,e.gitprovider),s("success",`Project '${t}' created using template '${e.template}'.`)}async function Rt(t,e,i,n="origin"){i||(i=await v("Select a provider or paste a url to connect your existing repo (cli tools needed) [LOCAL/github/gitlab]:","local")),i=i.toLowerCase().trim(),s("info","Initializing Git repository..."),s("debug","Running git init..."),await E("git",["init"],e),i&&i!=="false"&&i!=="local"?await kt(t,e,i,n):s("info","Git repository initialized locally. No remote linked."),s("debug","Initializing gitignore..."),await j(ot,[e,".gitignore"]),s("success","Git repository initialized.")}async function kt(t,e,i,n="origin"){if(i==="local"){s("info","Using local Git repository only. No remote linked.");return}if(/^https?:\/\//.test(i)||i.startsWith("git@")){s("info",`Connecting existing remote '${i}'`),await E("git",["remote","add",n,i],e);return}if(i==="github"){s("info",`Creating GitHub repository '${t}'`),await E("gh",["repo","create",t,"--private","--source=.","--remote",n],e);return}if(i==="gitlab"){s("info",`Creating GitLab repository '${t}'`);let o=process.env.GITLAB_USER;if(!o)throw new Error("GITLAB_USER environment variable not set");await E("glab",["repo","create",t,"--source=."],e),await E("git",["remote","add",n,`git@gitlab.com:${o}/${t}.git`],e);return}throw new Error(`Unsupported git provider or remote: '${i}'`)}async function It(t,e){s("info","Initializing NPM..."),await j({name:e,...st},[t,"package.json"]),s("debug","Running npm install..."),await E("npm",["i"],t)}var it=u(()=>{"use strict";w()});function k(t){if(t){let e=A[t];if(!e){console.log(`No help found for command: ${t}
3
4
  `);return}if(console.log(e.usage,`
4
5
  ${e.description}`),e.options){console.log(" Options:");for(let[i,n]of Object.entries(e.options))console.log(` ${i} ${n}`)}console.log("");return}console.log(`Usage:
5
6
  `);for(let e of Object.values(A)){if(console.log(e.usage,`
6
- ${e.description}`),e.options){console.log(" Options:");for(let[i,n]of Object.entries(e.options))console.log(` ${i} ${n}`)}console.log("")}}var et=d(()=>{"use strict";f()});import w from"fs-extra";import P from"path";async function J(t,e){let i=await U();if(t.list)return await Gt(i);if(t.delete)return await It(i,t.delete);if(await kt(i,e),t.update)return typeof t.update=="string"&&t.update.trim()?await Ft(i,t.update.trim()):await Mt(i)}async function Ft(t,e){let i=u([]),n=P.join(t,e);if(!await w.pathExists(n))throw new Error(`Template '${e}' not found in ~/.minimaz/templates`);if(!(await y(`Update '${e}' with current directory? [Y/n]:`,"y")).startsWith("y")){r("info","Update cancelled.");return}try{await w.copy(i,n,{overwrite:!0}),r("success",`Template '${e}' updated from current directory.`)}catch{throw new Error(`Failed to update '${e}'`)}}async function Mt(t){let e=await _(),i=await w.readdir(e);if(!(await y("Update local templates overwriting them with defaults? [Y/n]:","y")).startsWith("y")){r("info","Update cancelled.");return}try{for(let n of i){let s=P.join(e,n),a=P.join(t,n);await w.copy(s,a,{overwrite:!0}),r("success",`Updated '${n}'`)}r("info","\u2728 All templates and files updated successfully.")}catch(n){throw new Error(`Update failed: ${n.message}`)}}async function It(t,e){let i=P.join(t,e);if(!await w.pathExists(i))throw new Error(`Template not found: ${e}`);if(!(await y(`Confirm delete '${e}'? [Y/n]:`,"y")).startsWith("y")){r("info","Delete cancelled.");return}try{await w.remove(i),r("success",`Template '${e}' deleted.`)}catch(n){throw new Error(`Delete error: ${n.message}`)}}async function kt(t,e){let i=u(e?[e]:[]);if(!await w.pathExists(i))if(r("warn",`Path not found: ${i}`),(await y("Use current directory instead? [Y/n]:","y")).startsWith("y"))i=process.cwd();else throw new Error("Operation cancelled.");try{await w.ensureDir(t);let n=P.join(t,P.basename(i));if(await w.pathExists(n)&&!(await y(`Template '${P.basename(n)}' already exists. Overwrite? [y/N]:`,"n")).startsWith("y")){r("info","Save cancelled.");return}await w.copy(i,n,{overwrite:!0}),r("success",`Template saved to ${n}`)}catch(n){throw new Error(`Failed to save template: ${n.message}`)}}async function Gt(t){let e=await w.readdir(t);if(e.length===0){r("info","No global templates available.");return}r("info","Available global templates:");for(let i=0;i<e.length;i++)console.log(`${i} - ${e[i]}`)}var it=d(()=>{"use strict";f()});async function W(){T()}var nt=d(()=>{"use strict";f()});async function N(){let t=u(["package.json"]),{version:e}=await rt(t);if(typeof e!="string")throw new Error("Invalid or missing version in package.json");console.log("==========================================",`
7
+ ${e.description}`),e.options){console.log(" Options:");for(let[i,n]of Object.entries(e.options))console.log(` ${i} ${n}`)}console.log("")}}var rt=u(()=>{"use strict";w()});import $ from"fs-extra";import D from"path";async function N(t,e){let i=await _();if(t.list)return await Ut(i);if(t.delete)return await Bt(i,t.delete);if(await Lt(i,e),t.update)return typeof t.update=="string"&&t.update.trim()?await Mt(i,t.update.trim()):await Gt(i)}async function Mt(t,e){let i=f([]),n=D.join(t,e);if(!await $.pathExists(n))throw new Error(`Template '${e}' not found in ~/.minimaz/templates`);if(!(await v(`Update '${e}' with current directory? [Y/n]:`,"y")).startsWith("y")){s("info","Update cancelled.");return}try{await $.copy(i,n,{overwrite:!0}),s("success",`Template '${e}' updated from current directory.`)}catch{throw new Error(`Failed to update '${e}'`)}}async function Gt(t){let e=await I(),i=await z(e);if(!(await v("Update local templates overwriting them with defaults? [Y/n]:","y")).startsWith("y")){s("info","Update cancelled.");return}try{for(let n of i){let o=D.join(e,n),r=D.join(t,n);await $.copy(o,r,{overwrite:!0}),s("success",`Updated '${n}'`)}s("info","\u2728 All templates and files updated successfully.")}catch(n){throw new Error(`Update failed: ${n.message}`)}}async function Bt(t,e){let i=D.join(t,e);if(!await $.pathExists(i))throw new Error(`Template not found: ${e}`);if(!(await v(`Confirm delete '${e}'? [Y/n]:`,"y")).startsWith("y")){s("info","Delete cancelled.");return}try{await $.remove(i),s("success",`Template '${e}' deleted.`)}catch(n){throw new Error(`Delete error: ${n.message}`)}}async function Lt(t,e){let i=f(e?[e]:[]);if(!await $.pathExists(i))if(s("warn",`Path not found: ${i}`),(await v("Use current directory instead? [Y/n]:","y")).startsWith("y"))i=process.cwd();else throw new Error("Operation cancelled.");try{await $.ensureDir(t);let n=D.join(t,D.basename(i));if(await $.pathExists(n)&&!(await v(`Template '${D.basename(n)}' already exists. Overwrite? [y/N]:`,"n")).startsWith("y")){s("info","Save cancelled.");return}await $.copy(i,n,{overwrite:!0}),s("success",`Template saved to ${n}`)}catch(n){throw new Error(`Failed to save template: ${n.message}`)}}async function Ut(t){let e=await z(t);if(e.length===0){s("info","No global templates available.");return}s("info","Available global templates:");for(let i=0;i<e.length;i++)console.log(`${i} - ${e[i]}`)}var at=u(()=>{"use strict";w()});async function W(){O()}var ct=u(()=>{"use strict";w()});async function H(){let t=f(["package.json"]),{version:e}=await mt(t);if(typeof e!="string")throw new Error("Invalid or missing version in package.json");console.log("==========================================",`
7
8
  `,`minimaz-cli version: ${e}`,`
8
- `,"==========================================")}var st=d(()=>{"use strict";f()});var ot=d(()=>{"use strict"});import Lt from"readline";import p from"fs-extra";import m from"path";import Bt from"cross-spawn";import{homedir as at}from"os";import{execSync as At}from"child_process";function lt(t){let e={_:[]};for(let i=0;i<t.length;i++){let n=t[i].toLowerCase();if(!n.startsWith("-")){e._.push(n);continue}if(n.startsWith("--")&&n.includes("=")){let[o,l]=n.slice(2).split("=");e[o]=l;continue}let s=n.replace(/^-+/,""),a=t[i+1];a&&!a.startsWith("-")?(e[s]=a,i++):e[s]=!0}return e}function y(t,e=""){return new Promise(i=>{let n=Lt.createInterface({input:process.stdin,output:process.stdout}),s=setTimeout(()=>{n.close(),i(e)},6e4);n.question(`\u2753 ${t} `,a=>{clearTimeout(s),n.close(),i(a.trim()||e)}),n.on("SIGINT",()=>{clearTimeout(s),n.close(),process.exit(130)})})}function k(t,e={}){return Object.entries(e).reduce((i,[n,s])=>{let a=n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),o=new RegExp(a,"gi");return i.replace(o,s)},t)}async function S(t,e){try{let i=await p.readFile(t,"utf8");return e&&(i=k(i,e)),i}catch(i){return r("error",`Failed to read file ${t}: ${i.message}`),""}}async function ct(){try{let t=At("npm config get prefix",{encoding:"utf8"}).trim();if(!t)throw new Error("Empty npm prefix");return process.platform==="win32"?m.join(t,"node_modules","minimaz-cli"):m.join(t,"lib","node_modules","minimaz-cli")}catch{return process.platform==="win32"?m.join(process.env.APPDATA||"","npm","node_modules","minimaz-cli"):"/usr/local/lib/node_modules/minimaz-cli"}}async function Jt(){return await H(),m.join(at(),".minimaz")}async function U(){return m.join(await Jt(),"templates")}async function X(t){return m.join(await U(),t)}async function _(){return m.join(await ct(),"templates")}async function H(){let t=m.join(at(),".minimaz"),e=m.join(t,"templates"),i=await _(),n=m.join(t,"settings.json");try{await p.ensureDir(t),await p.pathExists(n)||(await p.outputJson(n,{createdAt:new Date().toISOString(),templatesPath:e,npmGlobalPath:await ct()},{spaces:2}),r("success",`Created settings.json at ${n}`));let s=await p.pathExists(e),a=s?(await p.readdir(e)).length===0:!0;if(s||(await p.ensureDir(e),r("success","Created global templates directory.")),!a){r("debug","Global templates directory not empty. Skipping copy.");return}if(await p.pathExists(i))for(let o of await p.readdir(i))await p.copy(m.join(i,o),m.join(e,o)),r("success",`Copied template '${o}'.`);else r("warn","Default templates directory not found.");r("success","Default templates setup completed.")}catch(s){throw r("error",`Failed to create global templates directory: ${s.message}`),s}}function j(t,e,i){return new Promise((n,s)=>{r("debug",`Running: ${t} ${e.join(" ")}`);let a=Bt(t,e,{cwd:i,stdio:"inherit"});a.on("error",s),a.on("close",o=>o===0?n():s(new Error(`${t} exited with code ${o}`)))})}async function R(t,e){let i=m.resolve(...e),n="";if(t!==void 0)if(typeof t=="string")n=t.endsWith(`
9
+ `,"==========================================")}var lt=u(()=>{"use strict";w()});import Jt from"readline";import g from"fs-extra";import b from"path";import At from"cross-spawn";import{homedir as Nt}from"os";import{execSync as _t}from"child_process";function gt(t){let e={_:[]};for(let i=0;i<t.length;i++){let n=t[i].toLowerCase();if(!n.startsWith("-")){e._.push(n);continue}if(n.startsWith("--")&&n.includes("=")){let[a,l]=n.slice(2).split("=");e[a]=l;continue}let o=n.replace(/^-+/,""),r=t[i+1];r&&!r.startsWith("-")?(e[o]=r,i++):e[o]=!0}return e}function v(t,e=""){return new Promise(i=>{let n=Jt.createInterface({input:process.stdin,output:process.stdout}),o=setTimeout(()=>{n.close(),i(e)},6e4);n.question(`\u2753 ${t} `,r=>{clearTimeout(o),n.close(),i(r.trim()||e)}),n.on("SIGINT",()=>{clearTimeout(o),n.close(),process.exit(130)})})}function Wt(t,e={}){return Object.entries(e).reduce((i,[n,o])=>{let r=n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=new RegExp(r,"gi");return i.replace(a,o)},t)}async function L(t,e){try{let i=await g.readFile(t,"utf8");return e&&(i=Wt(i,e)),i}catch(i){return s("error",`Failed to read file ${t}: ${i.message}`),""}}async function pt(){s("debug","Getting global node modules path...");try{let t=_t("npm config get prefix",{encoding:"utf8"}).trim();if(!t)throw new Error("Empty npm prefix");return process.platform==="win32"?b.join(t,"node_modules","minimaz-cli"):b.join(t,"lib","node_modules","minimaz-cli")}catch{return process.platform==="win32"?b.join(process.env.APPDATA||"","npm","node_modules","minimaz-cli"):"/usr/local/lib/node_modules/minimaz-cli"}}async function Ht(){s("debug","Checking existence of global Minimaz directory...");let t=b.join(Nt(),".minimaz");if(!await g.pathExists(t))throw new Error(`Global Minimaz folder does not exist.
10
+ Run 'minimaz config' to generate it.`);return t}async function _(){s("debug","Getting global templates directory path...");let t=b.join(await Ht(),"templates");if(!await g.pathExists(t))throw new Error("Template directory not found in global directory");return t}async function nt(t){s("debug",`Getting template '${t}'directory path...`);let e=b.join(await _(),t);if(!await g.pathExists(e))throw new Error(`Template '${t}' not found.`);return e}async function I(){s("debug","Getting default templates directory path...");let t=b.join(await pt(),"templates");if(!await g.pathExists(t))throw new Error("Default template folder not found");return t}function E(t,e,i){return s("debug",`Running: ${t} ${e.join(" ")}`),new Promise((n,o)=>{let r=At(t,e,{cwd:i,stdio:"inherit"});r.on("error",o),r.on("close",a=>a===0?n():o(new Error(`${t} exited with code ${a}`)))})}async function j(t,e,i=!0){s("debug","Creating file from template...");let n=b.resolve(...e),o="";if(t!==void 0)if(typeof t=="string")o=t.endsWith(`
9
11
  `)?t:`${t}
10
- `;else if(typeof t=="object"&&t!==null)n=`${JSON.stringify(t,null,2)}
11
- `;else throw new Error("Unsupported template type. Must be string or object.");try{await p.outputFile(i,n)}catch(s){let a=s instanceof Error?s.message:String(s);throw new Error(`Failed to create file at '${i}': ${a}`)}}async function T(t){let e=t?m.isAbsolute(t)?t:u([t]):m.resolve(process.cwd(),(await G()).dist??"dist"),i=process.cwd();if(e===i||e.length<=i.length)throw new Error(`Refusing to delete unsafe directory: ${e}`);if(!await p.pathExists(e)){r("debug",`No dist folder found: ${e}`);return}await p.remove(e),r("success",`Cleared ${e}`)}async function G(){let t=u(["minimaz.config.json"]),e;return await p.pathExists(t)?(e=await p.readJson(t),r("success","Loaded config from minimaz.config.json")):(e=JSON.parse(JSON.stringify(D)),r("warn","No minimaz.config.json found. Using default config")),e}function pt(t){process.env.VERBOSE=t?"true":"false",r("debug",`VERBOSE = ${process.env.VERBOSE}`),process.env.CLI_WORKDIR=process.cwd(),r("debug",`CLI_WORKDIR = ${process.env.CLI_WORKDIR}`)}function u(t=[]){return m.resolve(process.env.CLI_WORKDIR??process.cwd(),...t)}async function rt(t){return await p.readJson(t)}function $(t,e){return`${e}${t}${b.reset}`}var mt=d(()=>{"use strict";f()});var Z,tt,D,A,b,gt,ut=d(()=>{"use strict";f();Z={version:"0.0.1",license:"ISC",type:"commonjs",scripts:{build:"npx mz b",start:"npx mz b && npx serve dist/"},devDependencies:{"minimaz-cli":"latest",serve:"latest"}},tt=`
12
+ `;else if(typeof t=="object"&&t!==null)o=`${JSON.stringify(t,null,2)}
13
+ `;else throw new Error("Unsupported template type. Must be string or object.");try{if(!i&&await g.pathExists(n)){s("info",`File already exists at '${n}', skipping creation.`);return}await g.outputFile(n,o)}catch(r){let a=r instanceof Error?r.message:String(r);throw new Error(`Failed to create file at '${n}': ${a}`)}}async function O(t){s("debug","Removing outDir...");let e=t?b.isAbsolute(t)?t:f([t]):b.resolve(process.cwd(),(await U()).outDir??"dist"),i=process.cwd();if(e===i||e.length<=i.length)throw new Error(`Refusing to delete unsafe directory: ${e}`);if(!await g.pathExists(e)){s("debug",`No dist folder found: ${e}`);return}await g.remove(e),s("success",`Cleared ${e}`)}async function U(){let t=f(["minimaz.config.json"]),e;if(await g.pathExists(t)?(e=await g.readJson(t),s("success","Loaded config from minimaz.config.json")):(s("warn","No minimaz.config.json found. Using default config"),e=JSON.parse(JSON.stringify(R))),!e.outDir||typeof e.outDir!="string")throw new Error("Invalid config: outDir must be a string");if(!e.folders||typeof e.folders!="object")throw new Error("Invalid config: folders must be an object");return e.bundling??={outDir:""},e.minify??={},e.replace??={},e}function ut(t){s("debug","Initializing environments variables..."),process.env.VERBOSE=t?"true":"false",s("debug",`VERBOSE = ${process.env.VERBOSE}`),process.env.CLI_WORKDIR=process.cwd(),s("debug",`CLI_WORKDIR = ${process.env.CLI_WORKDIR}`)}function f(t=[]){return s("debug","Resolving current path..."),b.resolve(process.env.CLI_WORKDIR??process.cwd(),...t)}async function mt(t){if(!await g.pathExists(t))throw new Error(`NOT FOUND: '${t}' does not exist`);return await g.readJson(t)}async function z(t){return s("debug",`Reading elements of ${t}...`),await g.pathExists(t)?await g.readdir(t):(s("warn",`Directory does not exist: ${t}`),[])}function C(t,e){return`${e}${t}${P.reset}`}async function dt(t){return{createdAt:new Date().toISOString(),templatesPath:t,npmGlobalPath:await pt()}}var M=u(()=>{"use strict";w()});function s(t="info",e){let i=process.env.VERBOSE==="true";if(t==="debug"&&!i)return;let o=`${i?C(`[${Yt()}] `,P.gray):""}${ft[t]} ${e}`;switch(t){case"error":console.error(o);break;case"warn":console.warn(o);break;default:console.log(o);break}}function Yt(t=new Date){let e=y=>y.toString().padStart(2,"0"),i=t.getFullYear(),n=e(t.getMonth()+1),o=e(t.getDate()),r=e(t.getHours()),a=e(t.getMinutes()),l=e(t.getSeconds());return`${i}-${n}-${o} ${r}:${a}:${l}`}var Y=u(()=>{"use strict";w()});import{homedir as Vt}from"os";import T from"path";import x from"fs-extra";async function F(t){s("debug",""+t);let e=T.join(Vt(),".minimaz");await x.pathExists(e)?s("info","~/.minimaz already exists. Skipping..."):await r();let i=await I();if(!await x.pathExists(i)){s("error","Default templates directory not found. Try reinstalling minimaz or open an issue on github");return}let n=T.join(e,"templates");await x.pathExists(n)?s("info","~/.minimaz/templates already exists. Skipping..."):await a(),await l();let o=T.join(e,"settings.json");await y();async function r(){s("info","~/.minimaz doesn't exist. Generating..."),await x.ensureDir(e)}async function a(){await x.ensureDir(n),s("success",`Created templates directory at ${n}`)}async function l(){s("info","Checking default templates...");let m=await x.readdir(i);if(m.length===0){s("warn","Default templates directory is empty");return}for(let p of m){let S=T.join(i,p),c=T.join(n,p),V=await x.pathExists(c);if(V&&!t){s("info",`Template '${p}' already exists. Skipping...`);continue}await x.copy(S,c,{overwrite:t}),V&&t?s("success",`Overwritten template '${p}'.`):s("success",`Copied template '${p}'.`)}}async function y(){let m=await dt(n);if(!await x.pathExists(o)||t){await j(m,[o]),t&&await x.pathExists(o)?s("success",`Overwritten settings.json at ${o}`):s("success",`Created settings.json at ${o}`);return}let p;try{p=await x.readJson(o)}catch{s("warn","Failed to read settings.json. Recreating from template..."),await j(m,[o]);return}let S=!1;for(let c of Object.keys(m))c in p||(p[c]=m[c],s("warn",`Added missing key '${c}' to settings.json`),S=!0);for(let c of Object.keys(p))c in m||s("warn",`Unknown key '${c}' found in settings.json`);S?(await j(p,[o]),s("success","Updated settings.json to match template")):s("info","settings.json is valid and up-to-date")}}var wt=u(()=>{"use strict";M();Y();M()});var yt=u(()=>{"use strict"});var st,ot,R,A,P,ft,ht=u(()=>{"use strict";w();st={version:"0.0.1",license:"ISC",type:"commonjs",scripts:{build:"npx mz b",start:"npx mz b && npx serve dist/"},devDependencies:{"minimaz-cli":"latest",serve:"latest"}},ot=`
12
14
  node_modules
13
15
  dist
14
16
  .env
15
17
  .vscode
16
18
  .DS_Store
17
- `.trim(),D={src:"src",dist:"dist",public:"public",bundling:{css:!0,js:!0},minify:{html:!0,css:!0,js:!0},replace:{"../public/":"public/"},styles:["style.css","style-2.css"],scripts:["script.js","script-2.js"],folders:{src:"",public:"public"}},A={init:{usage:"minimaz init | i <project-name>",description:'Create a new project (default: "minimaz-site")',options:{"--template | -t <template-name>":'Use a global template (default: "default")'}},build:{usage:"minimaz build | b",description:"Build and minify files into the dist folder"},template:{usage:"minimaz template | t [path]",description:"Save current folder as a template (no path = current folder)",options:{"--list | -l":"List available global templates","--delete | -d <template-name>":"Delete a global template"}},help:{usage:"minimaz help | h",description:"Show this help message"},clear:{usage:"minimaz clear | c",description:"Clear the dist folder"},version:{usage:"minimaz version | v",description:"Show Minimaz version"}},b={reset:"\x1B[0m",red:"\x1B[31m",yellow:"\x1B[33m",green:"\x1B[32m",blue:"\x1B[34m",gray:"\x1B[90m"},gt={error:$("[ --- ERROR ----- ] ",b.red),warn:$("[ --- WARN ------ ] ",b.yellow),success:$("[ --- SUCCESS --- ] ",b.green),info:$("[ --- INFO ------ ] ",b.blue),debug:$("[ --- DEBUG ----- ] ",b.gray)}});function r(t="info",e){let i=process.env.VERBOSE==="true";if(t==="debug"&&!i)return;let s=`${i?$(`[${Ut()}] `,b.gray):""}${gt[t]} ${e}`;switch(t){case"error":console.error(s);break;case"warn":console.warn(s);break;default:console.log(s);break}}function Ut(t=new Date){let e=c=>c.toString().padStart(2,"0"),i=t.getFullYear(),n=e(t.getMonth()+1),s=e(t.getDate()),a=e(t.getHours()),o=e(t.getMinutes()),l=e(t.getSeconds());return`${i}-${n}-${s} ${a}:${o}:${l}`}var dt=d(()=>{"use strict";f()});var f=d(()=>{"use strict";Q();q();et();it();nt();st();ot();mt();ut();dt()});var ft={};bt(ft,{postInstall:()=>_t});async function _t(){try{r("info","Running Post Install..."),await H(),r("success","Postinstall: Global templates setup completed")}catch(t){r("error",`Postinstall setup failed: ${t.message}`)}}var wt=d(()=>{"use strict";f()});f();process.env.npm_lifecycle_event==="postinstall"&&(Promise.resolve().then(()=>(wt(),ft)).then(({postInstall:t})=>t()),process.exit(0));async function Wt(){let t=lt(process.argv.slice(2)),e=t._[0]||"",i=t._[1];pt(!!t.v),(e==="help"||t.h||t.help)&&(O(i||(t.h||t.help?e:void 0)),process.exit(0));let n={build:async()=>I(),clear:()=>W(),init:async()=>{await B(i||"minimaz-project",{template:t.template||t.t||"default",npm:t.npm,git:t.git,gitremote:t.gitremote,gitprovider:t.gitprovider})},template:async()=>{await J({list:t.l||t.list,delete:t.d||t.delete,update:t.u||t.update})},version:()=>N(),b:()=>n.build(),c:()=>n.clear(),i:()=>n.init(),t:()=>n.template(),v:()=>n.version()};try{n[e]?(r("info",`Executing command '${e}'...`),await n[e]()):(r("error",`Unknown command '${e}'. Use 'minimaz help' to see available commands.`),O())}catch(s){r("error",s instanceof Error?process.env.DEBUG?s.stack??s.message:s.message:String(s)),process.exit(1)}}Wt();
19
+ `.trim(),R={outDir:"dist",bundling:{css:{enabled:!0,outFile:"styles.css"},js:{enabled:!0,outFile:"scripts.js"},outDir:""},minify:{html:!0,css:!0,js:!0},replace:{"../public/":"public/"},styles:["style.css","style-2.css"],scripts:["script.js","script-2.js"],folders:{src:"",public:"public"}},A={init:{usage:"minimaz init | i <project-name>",description:'Create a new project (default: "minimaz-site")',options:{"--template | -t <template-name>":'Use a global template (default: "default")'}},build:{usage:"minimaz build | b",description:"Build and minify files into the dist folder"},template:{usage:"minimaz template | t [path]",description:"Save current folder as a template (no path = current folder)",options:{"--list | -l":"List available global templates","--delete | -d <template-name>":"Delete a global template"}},help:{usage:"minimaz help | h",description:"Show this help message"},clear:{usage:"minimaz clear | c",description:"Clear the dist folder"},version:{usage:"minimaz version | v",description:"Show Minimaz version"}},P={reset:"\x1B[0m",red:"\x1B[31m",yellow:"\x1B[33m",green:"\x1B[32m",blue:"\x1B[34m",gray:"\x1B[90m"},ft={error:C("[ --- ERROR ----- ] ",P.red),warn:C("[ --- WARN ------ ] ",P.yellow),success:C("[ --- SUCCESS --- ] ",P.green),info:C("[ --- INFO ------ ] ",P.blue),debug:C("[ --- DEBUG ----- ] ",P.gray)}});var w=u(()=>{"use strict";tt();it();rt();at();ct();lt();wt();yt();M();ht();Y()});var bt={};$t(bt,{postInstall:()=>Kt});async function Kt(){try{s("info","Running Post Install..."),await F(!1),s("success","Postinstall: Global templates setup completed")}catch(t){s("error",`Postinstall setup failed: ${t.message}`)}}var xt=u(()=>{"use strict";w()});w();process.env.npm_lifecycle_event==="postinstall"&&(Promise.resolve().then(()=>(xt(),bt)).then(({postInstall:t})=>t()),process.exit(0));async function qt(){let t=gt(process.argv.slice(2)),e=t._[0]||"",i=t._[1];ut(!!t.v),(e==="help"||t.h||t.help)&&(k(i||(t.h||t.help?e:void 0)),process.exit(0));let n={build:async()=>G(),clear:()=>W(),config:async()=>F(t.overwrite===!0||t.overwrite==="true"),init:async()=>{await J(i||"minimaz-project",{template:t.template||t.t||"default",npm:t.npm,git:t.git,gitremote:t.gitremote,gitprovider:t.gitprovider})},template:async()=>{await N({list:t.l||t.list,delete:t.d||t.delete,update:t.u||t.update})},version:()=>H(),b:()=>n.build(),c:()=>n.clear(),i:()=>n.init(),t:()=>n.template(),v:()=>n.version()};try{n[e]?(s("info",`Executing command '${e}'...`),await n[e]()):(s("error",`Unknown command '${e}'. Use 'minimaz help' to see available commands.`),k())}catch(o){s("error",o instanceof Error?process.env.DEBUG?o.stack??o.message:o.message:String(o)),process.exit(1)}}qt();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minimaz-cli",
3
- "version": "0.3.5",
3
+ "version": "0.4.0",
4
4
  "description": "Minimal project initializer and builder CLI",
5
5
  "author": "MrZeller",
6
6
  "license": "MIT",
@@ -33,7 +33,8 @@
33
33
  "cross-spawn": "^7.0.6",
34
34
  "fs-extra": "^11.3.0",
35
35
  "html-minifier-terser": "^7.2.0",
36
- "terser": "^5.44.0"
36
+ "terser": "^5.44.0",
37
+ "esbuild": "^0.25.12"
37
38
  },
38
39
  "postinstall": "node dist/bin/cli.js",
39
40
  "bin": {
@@ -0,0 +1,25 @@
1
+ {
2
+ "src": "src",
3
+ "dist": "dist",
4
+ "public": "public",
5
+ "bundling": {
6
+ "css": true,
7
+ "js": true
8
+ },
9
+ "minify": {
10
+ "html": true,
11
+ "css": true,
12
+ "js": true
13
+ },
14
+ "replace": {
15
+ "../public/": "/public/",
16
+ "<link rel=\"stylesheet\" href=\"styles/bootstrap-icons.css\">": "",
17
+ "../../node_modules/bootstrap-icons/font/fonts/bootstrap-icons.woff2": "/public/fonts/bootstrap-icons.woff2",
18
+ "../../node_modules/bootstrap-icons/font/fonts/bootstrap-icons.woff": "/public/fonts/bootstrap-icons.woff"
19
+ },
20
+ "folders": {
21
+ "public": "public",
22
+ "src": "",
23
+ "node_modules/bootstrap-icons/font/fonts": "public/fonts"
24
+ }
25
+ }
@@ -1,80 +1,452 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
+
4
+ <!-- ======================================== -->
5
+ <!-- HEAD -->
6
+ <!-- ======================================== -->
7
+
3
8
  <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Welcome to Minimaz</title>
7
- <link rel="stylesheet" href="style.css" />
8
- <link rel="icon" href="../public/favicon.ico" type="image/x-icon" />
9
+ <meta charset="UTF-8">
10
+ <meta name="viewport" content="width=device-width, initial-scale=1">
11
+ <title>Minimaz CLI – Minimal Static Site Builder</title>
12
+
13
+ <!-- SEO -->
14
+ <meta name="description"
15
+ content="Minimaz CLI is a minimal, low-dependency static site builder and project initializer. Compile TypeScript, bundle and minify HTML, CSS, and JS with a fast and simple CLI.">
16
+ <meta name="keywords"
17
+ content="minimaz, minimaz-cli, static site builder, project initializer, nodejs cli, html css js, typescript, minimal build tool">
18
+ <meta name="author" content="MrZeller">
19
+ <meta name="robots" content="index, follow">
20
+ <meta property="og:title" content="Minimaz CLI – Minimal Static Site Builder">
21
+ <meta property="og:description"
22
+ content="Initialize projects from templates, compile TypeScript, bundle and minify assets, and build clean static sites with a lightweight CLI.">
23
+ <meta property="og:url" content="https://github.com/zeller-dev/minimaz-cli">
24
+ <meta property="og:type" content="website">
25
+ <meta name="theme-color" content="#0d0d0d">
26
+
27
+ <link rel="icon" type="image/x-icon" href="../public/favicon.ico">
28
+ <link rel="shortcut icon" href="../public/favicon.ico">
29
+ <link rel="stylesheet" href="style.css">
30
+ <link rel="stylesheet" href="styles/bootstrap-icons.css">
9
31
  </head>
32
+
10
33
  <body>
11
- <header>
12
- <nav>
13
- <a class="btn active" href="#">Home</a>
14
- <a class="btn" href="pages/about.html">About</a>
15
- <a class="btn" href="https://github.com/zeller-dev/minimaz" target="_blank">GitHub</a>
16
- </nav>
17
- </header>
18
-
19
- <main class="container">
20
- <h1>🚀 Welcome to Minimaz</h1>
21
- <p><strong>Minimaz</strong> is a minimal static site builder designed for speed and simplicity. It helps you:</p>
22
- <ul>
23
- <li>💡 Organize your files with a simple structure</li>
24
- <li>⚙️ Automatically build and minify HTML, CSS, JS, and TS</li>
25
- <li>🔄 Customize file inclusion order using <code>minimaz.config.json</code></li>
26
- </ul>
27
-
28
- <h2>🔧 Getting Started</h2>
29
- <p>Install and use Minimaz with the following commands:</p>
30
- <pre><code># 🔨 Initialize a new project
31
- npx minimaz init my-site
32
-
33
- # 🏗️ Build the site
34
+
35
+ <!-- ======================================== -->
36
+ <!-- HEADER -->
37
+ <!-- ======================================== -->
38
+ <header>
39
+ <img src="../public/assets/logo.webp" alt="Minimaz Logo">
40
+ <h1 class="sr-only">Minimaz CLI <i class="icon lightning-fill"></i></h1>
41
+ <p id="tagline">Minimal input. Clean output</p>
42
+ <p class="version">Version: <strong>v0.4.0</strong></p>
43
+ </header>
44
+
45
+ <main id="main-content">
46
+
47
+ <!-- ======================================== -->
48
+ <!-- ABOUT -->
49
+ <!-- ======================================== -->
50
+ <section id="about" class="max-width">
51
+ <h2>
52
+ <i class="icon info-circle"></i>
53
+ <span>About</span>
54
+ </h2>
55
+ <p>
56
+ <strong>Minimaz</strong> is a minimal, low-dependency static site builder
57
+ and project initializer focused on speed, simplicity, and clean output.
58
+ It supports HTML, CSS, JavaScript, and TypeScript (<code>.ts → .js</code>),
59
+ with optional bundling and minification.
60
+ </p>
61
+ <p>
62
+ Designed for small static sites, utility tools, prototypes,
63
+ and teams that want reproducible minimal build systems.
64
+ </p>
65
+ </section>
66
+
67
+ <section id="features" class="max-width">
68
+ <h2>
69
+ <i class="icon gear-fill"></i>
70
+ <span>Features</span>
71
+ </h2>
72
+
73
+ <div class="grid">
74
+ <div class="grid-item">Initialize projects from templates</div>
75
+ <div class="grid-item">Save, list, delete, and update global templates</div>
76
+ <div class="grid-item">Minify HTML, CSS, JS, and compiled TS</div>
77
+ <div class="grid-item">Optional CSS and JS bundling</div>
78
+ <div class="grid-item">Include external styles/scripts (relative, absolute, node_modules)</div>
79
+ <div class="grid-item">Configurable via <code>minimaz.config.json</code></div>
80
+ <div class="grid-item">Path replacement support for asset links</div>
81
+ <div class="grid-item">Optional npm initialization</div>
82
+ <div class="grid-item">Optional Git repository initialization</div>
83
+ <div class="grid-item">Git provider / remote URL support</div>
84
+ <div class="grid-item">Interactive prompts with 60s timeout</div>
85
+ <div class="grid-item">Alias support: <code>minimaz</code> or <code>mz</code></div>
86
+ <div class="grid-item">Lightweight and fast</div>
87
+ </div>
88
+ </section>
89
+
90
+ <!-- ======================================== -->
91
+ <!-- INSTALLATION -->
92
+ <!-- ======================================== -->
93
+ <section id="installation" class="max-width">
94
+ <h2>
95
+ <i class="icon download"></i>
96
+ <span>Installation</span>
97
+ </h2>
98
+ <p>Run directly using <code>npx</code> (no global install required):</p>
99
+
100
+ <pre><code>npx minimaz init my-site
101
+ cd my-site
34
102
  npx minimaz build
103
+ npx minimaz version</code></pre>
35
104
 
36
- # 📦 Save template or list/delete existing ones
37
- npx minimaz template &lt;path&gt; [--list|-l] [--delete|-d]
38
-
39
- # 💬 Show help guide
40
- npx minimaz help</code></pre>
41
-
42
- <h2>📁 Project Structure</h2>
43
- <pre><code>my-site/
44
- ├── src/ # Source files (HTML, CSS, JS, TS)
45
- ├── public/ # Static assets (images, fonts, etc.)
46
- ├── dist/ # Output directory (auto-generated)
47
- └── minimaz.config.json # Configuration file</code></pre>
48
-
49
- <h2>⚙️ Configuration</h2>
50
- <pre><code>{
51
- "src": "src",
52
- "dist": "dist",
53
- "public": "public",
54
- "minify": { "html": true, "css": true, "js": true, "ts": true },
55
- "replace": { "../public/": "public/" },
56
- "styles": [ "reset.css", "style.css", "theme.css" ],
57
- "scripts": [ "libs/jquery.js", "utils.js", "script.js" ]
105
+ <p>Using alias:</p>
106
+
107
+ <pre><code>npx mz i my-site
108
+ npx mz b
109
+ npx mz v</code></pre>
110
+ </section>
111
+
112
+ <!-- ======================================== -->
113
+ <!-- PROJECT STRUCTURE -->
114
+ <!-- ======================================== -->
115
+ <section id="project-structure" class="max-width">
116
+ <h2>
117
+ <i class="icon folder2-open"></i>
118
+ <span>Project Structure</span>
119
+ </h2>
120
+
121
+ <pre><code>my-site/
122
+ ├── dist/ # Output folder (generated)
123
+ ├── public/ # Static assets
124
+ ├── src/ # HTML, CSS, JS, TS files
125
+ ├── minimaz.config.json
126
+ ├── package.json # Optional (if npm init used)
127
+ ├── .gitignore
128
+ └── ...</code></pre>
129
+ </section>
130
+
131
+ <!-- ======================================== -->
132
+ <!-- CONFIGURATION -->
133
+ <!-- ======================================== -->
134
+ <section id="configuration" class="max-width">
135
+ <h2>
136
+ <i class="icon sliders"></i>
137
+ <span>Configuration</span>
138
+ </h2>
139
+
140
+ <pre><code>{
141
+ "outDir": "dist",
142
+ "bundling": {
143
+ "css": {
144
+ "enabled": true,
145
+ "outFile": "styles.css"
146
+ },
147
+ "js": {
148
+ "enabled": true,
149
+ "outFile": "scripts.js"
150
+ }
151
+ },
152
+ "minify": {
153
+ "html": true,
154
+ "css": true,
155
+ "js": true,
156
+ "ts": true
157
+ },
158
+ "replace": {
159
+ "../public/": "public/"
160
+ },
161
+ "styles": [
162
+ "style.css",
163
+ "style-2.css"
164
+ ],
165
+ "scripts": [
166
+ "script.js",
167
+ "script-2.js"
168
+ ],
169
+ "folders": {
170
+ "src": "",
171
+ "public": "public"
172
+ }
58
173
  }</code></pre>
59
174
 
60
- <h2>📤 Production</h2>
61
- <p>The final output will be generated in the <code>dist/</code> folder, ready for deployment.</p>
175
+ <ul>
176
+ <li><strong>bundling.css/js</strong> concatenate files</li>
177
+ <li><strong>minify.html/css/js/ts</strong> → toggle per file type</li>
178
+ <li><strong>styles/scripts</strong> → include external files</li>
179
+ <li><strong>replace</strong> → asset path replacements</li>
180
+ <li><strong>styles & scripts</strong> → external styles or scripts to add</li>
181
+ <li><strong>folders</strong> → folders to scan</li>
182
+ </ul>
183
+ </section>
184
+
185
+ <!-- ======================================== -->
186
+ <!-- COMMANDS -->
187
+ <!-- ======================================== -->
188
+ <section id="commands" class="max-width">
189
+ <h2>
190
+ <i class="icon command"></i>
191
+ <span>Commands</span>
192
+ </h2>
193
+
194
+ <pre><code># Build
195
+ minimaz build
196
+ mz b
197
+
198
+ # Clear
199
+ minimaz clear
200
+ mz c
201
+
202
+ # Config
203
+ minimaz config # Create or update global configuration ~/.minimaz/
204
+ mz config --overwrite # Overwrites default templates and settings.json
205
+
206
+ # Init
207
+ minimaz init &lt;project-name&gt;
208
+ minimaz init &lt;project-name&gt; --template &lt;name&gt;
209
+ minimaz init &lt;project-name&gt; --npm
210
+ minimaz init &lt;project-name&gt; --git --gitprovider github --gitremote &lt;url&gt;
211
+ mz i my-site -t template
212
+
213
+ # Help
214
+ minimaz help
215
+ minimaz help build
216
+ mz h build
217
+
218
+ # Template management
219
+ minimaz template &lt;path&gt;
220
+ minimaz template --list
221
+ minimaz template --delete &lt;name&gt;
222
+ minimaz template --update &lt;name&gt;
223
+ minimaz template --update
62
224
 
63
- <h2>❓ Available Commands</h2>
64
- <ul>
65
- <li><code>init</code> / <code>i</code> – Initialize a new project</li>
66
- <li><code>build</code> / <code>b</code> – Build and minify the project</li>
67
- <li><code>help</code> / <code>h</code> – Show the help message</li>
68
- <li><code>template</code> / <code>t</code> – Manage templates (with <code>--list</code> and <code>--delete</code> options)</li>
69
- </ul>
225
+ # Version
226
+ minimaz version
227
+ mz v</code></pre>
228
+ </section>
70
229
 
71
- <p>You're ready to build fast and clean static websites. Happy coding! 🛠️</p>
72
- </main>
230
+ <!-- ======================================== -->
231
+ <!-- FUTURE FEATURES / ROADMAP -->
232
+ <!-- ======================================== -->
233
+ <section id="future-features" class="max-width">
234
+ <h2>
235
+ <i class="icon rocket-takeoff"></i>
236
+ <span>Upcoming & Future Features</span>
237
+ </h2>
73
238
 
74
- <footer>
75
- <p>&copy; 2025 Minimaz. All rights reserved.</p>
76
- </footer>
239
+ <p>
240
+ Planned improvements and roadmap direction.
241
+ Scope is intentionally controlled to preserve simplicity.
242
+ </p>
243
+
244
+ <div class="grid">
245
+
246
+ <!-- ======================================== -->
247
+ <!-- PACKAGE DISTRIBUTION -->
248
+ <!-- ======================================== -->
249
+ <article class="grid-item">
250
+ <header>
251
+ <h3>@minimaz Package Distribution</h3>
252
+ <span class="status status-planned">Planned</span>
253
+ </header>
254
+ <p>
255
+ Publish Minimaz as an installable scoped package.
256
+ </p>
257
+ <pre><code>npm install -g @minimaz/cli</code></pre>
258
+ </article>
259
+
260
+ <!-- ======================================== -->
261
+ <!-- TEMPLATE GIT INTEGRATION -->
262
+ <!-- ======================================== -->
263
+ <article class="grid-item">
264
+ <header>
265
+ <h3>Template Git Integration</h3>
266
+ <span class="status status-planned">Planned</span>
267
+ </header>
268
+ <p>
269
+ Pull project templates directly from remote Git repositories.
270
+ </p>
271
+ <pre><code>minimaz template &lt;repo-url&gt;</code></pre>
272
+ </article>
273
+
274
+ <!-- ======================================== -->
275
+ <!-- CONVERT COMMAND -->
276
+ <!-- ======================================== -->
277
+ <article class="grid-item">
278
+ <header>
279
+ <h3>minimaz convert</h3>
280
+ <span class="status status-planned">Planned</span>
281
+ </header>
282
+ <p>
283
+ Convert and optimize assets (e.g. JPEG → WebP).
284
+ </p>
285
+ <pre><code>minimaz convert input.jpg --to webp</code></pre>
286
+ </article>
287
+
288
+ <!-- ======================================== -->
289
+ <!-- ANALYZE COMMAND -->
290
+ <!-- ======================================== -->
291
+ <article class="grid-item">
292
+ <header>
293
+ <h3>minimaz analyze</h3>
294
+ <span class="status status-planned">Planned</span>
295
+ </header>
296
+ <p>
297
+ Static analysis to detect build errors, broken links,
298
+ duplicate IDs, and missing assets.
299
+ </p>
300
+ <pre><code>minimaz analyze</code></pre>
301
+ </article>
302
+
303
+ <!-- ======================================== -->
304
+ <!-- OPTIMIZE COMMAND -->
305
+ <!-- ======================================== -->
306
+ <article class="grid-item">
307
+ <header>
308
+ <h3>minimaz optimize</h3>
309
+ <span class="status status-research">Research</span>
310
+ </header>
311
+ <p>
312
+ Extended optimization pipeline (HTML, CSS, JS, images).
313
+ Scope under evaluation.
314
+ </p>
315
+ </article>
316
+
317
+ <!-- ======================================== -->
318
+ <!-- BLOCK SYSTEM -->
319
+ <!-- ======================================== -->
320
+ <article class="grid-item">
321
+ <header>
322
+ <h3>minimaz blocks</h3>
323
+ <span class="status status-planned">Planned</span>
324
+ </header>
325
+ <p>
326
+ Inject reusable HTML blocks into files.
327
+ </p>
328
+ <pre><code>&lt;block src="header.html"&gt;&lt;/block&gt;</code></pre>
329
+ </article>
330
+
331
+ <!-- ======================================== -->
332
+ <!-- TRANSLATE -->
333
+ <!-- ======================================== -->
334
+ <article class="grid-item">
335
+ <header>
336
+ <h3>minimaz translate</h3>
337
+ <span class="status status-idea">Concept</span>
338
+ </header>
339
+ <p>
340
+ Internationalization or content conversion system.
341
+ Direction to be defined.
342
+ </p>
343
+ </article>
344
+
345
+ <!-- ======================================== -->
346
+ <!-- EXTENDED CSS SUPPORT -->
347
+ <!-- ======================================== -->
348
+ <article class="grid-item">
349
+ <header>
350
+ <h3>SCSS / Extended CSS Support</h3>
351
+ <span class="status status-planned">Planned</span>
352
+ </header>
353
+ <p>
354
+ Optional support for SCSS and other preprocessors.
355
+ </p>
356
+ </article>
357
+
358
+ </div>
359
+ </section>
360
+
361
+ <!-- ======================================== -->
362
+ <!-- GLOBAL TEMPLATES -->
363
+ <!-- ======================================== -->
364
+ <section id="templates" class="max-width">
365
+ <h2>
366
+ <i class="icon collection-fill"></i>
367
+ <span>Global Folder</span>
368
+ </h2>
369
+
370
+ <pre><code>~/.minimaz/templates</code></pre>
371
+
372
+ <p>Use templates to quickly initialize consistent projects across environments.</p>
373
+ </section>
374
+
375
+ <!-- ======================================== -->
376
+ <!-- LINKS -->
377
+ <!-- ======================================== -->
378
+ <section id="links" class="max-width">
379
+ <h2>
380
+ <i class="icon link-45deg"></i>
381
+ <span>Links</span>
382
+ </h2>
383
+ <ul>
384
+ <li>
385
+ <a href="https://github.com/zeller-dev/minimaz-cli">
386
+ GitHub Repository
387
+ </a>
388
+ </li>
389
+ <li>
390
+ <a href="https://www.npmjs.com/package/minimaz-cli">
391
+ npm Package
392
+ </a>
393
+ </li>
394
+ </ul>
395
+ </section>
396
+
397
+ </main>
398
+
399
+ <!-- ======================================== -->
400
+ <!-- FOOTER -->
401
+ <!-- ======================================== -->
402
+ <footer class="site-footer">
403
+
404
+ <div class="footer-grid">
405
+
406
+ <!-- Brand -->
407
+ <div class="footer-col">
408
+ <h3>Minimaz CLI</h3>
409
+ <p>
410
+ A minimal static site builder focused on speed,
411
+ simplicity, and reproducible builds.
412
+ </p>
413
+ </div>
414
+
415
+ <!-- Quick Links -->
416
+ <div class="footer-col">
417
+ <h4>Resources</h4>
418
+ <ul>
419
+ <li>
420
+ <a href="https://github.com/zeller-dev/minimaz-cli">
421
+ GitHub
422
+ </a>
423
+ </li>
424
+ <li>
425
+ <a href="https://www.npmjs.com/package/minimaz-cli">
426
+ npm Package
427
+ </a>
428
+ </li>
429
+ </ul>
430
+ </div>
431
+
432
+ <!-- Technical -->
433
+ <div class="footer-col">
434
+ <h4>Technical</h4>
435
+ <ul>
436
+ <li>License: MIT</li>
437
+ <li>Node.js CLI</li>
438
+ <li>Zero heavy dependencies</li>
439
+ </ul>
440
+ </div>
441
+
442
+ </div>
443
+
444
+ <div class="footer-bottom">
445
+ <p>© 2026 MrZeller. Built with simplicity in mind.</p>
446
+ </div>
447
+
448
+ </footer>
77
449
 
78
- <script src="script.js"></script>
79
450
  </body>
80
- </html>
451
+
452
+ </html>
@@ -1,99 +1,321 @@
1
+ /* =========================================================
2
+ ROOT VARIABLES
3
+ ========================================================= */
1
4
  :root {
2
- --primary-color: #338ca8;
3
- --background-color: #222;
4
- --foreground-color: #f5f5f5;
5
- --code-bg: #333;
6
- --code-text: #eeeeff;
7
- font-size: 16px;
5
+ color-scheme: dark;
6
+
7
+ /* Base colors */
8
+ --bg: #222;
9
+ --fg: #999;
10
+ --accent: #60b5e6;
11
+ --accent2: #fdc503;
12
+ --border: #222;
13
+ --code-bg: #1a1a1a;
14
+
15
+ /* UI components */
16
+ --card-bg: #141414;
17
+ --badge-bg: #1e1e1e;
18
+
19
+ /* Typography */
20
+ --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
21
+ --font-mono: "Fira Code", monospace;
22
+
23
+ /* Layout */
24
+ --radius-sm: 4px;
25
+ --radius-md: 6px;
26
+ --space-xs: 0.25rem;
27
+ --space-sm: 0.5rem;
28
+ --space-md: 1rem;
29
+ --space-lg: 1.5rem;
8
30
  }
9
31
 
10
- * {
11
- box-sizing: border-box;
32
+ /* =========================================================
33
+ GLOBAL RESET
34
+ ========================================================= */
35
+ *,
36
+ *::before,
37
+ *::after {
38
+ box-sizing: border-box;
39
+ margin: 0;
40
+ padding: 0;
12
41
  }
13
42
 
14
- header,
15
- footer {
16
- background-color: var(--code-bg);
17
- padding:1rem;
43
+ html {
44
+ font-size: 16px;
45
+ scroll-behavior: smooth;
46
+ line-height: 1.6;
18
47
  }
19
48
 
20
49
  body {
21
- font-family: 'Segoe UI', sans-serif;
22
- margin: 0;
23
- background: var(--background-color);
24
- color: var(--foreground-color);
25
- line-height: 1.6;
50
+ background-color: var(--bg);
51
+ color: var(--fg);
52
+ font-family: var(--font-sans);
53
+ margin: 0;
54
+ }
55
+
56
+ /* =========================================================
57
+ STRUCTURAL ELEMENTS
58
+ ========================================================= */
59
+
60
+ section {
61
+ margin: 3rem auto;
62
+ }
63
+
64
+ /* =========================================================
65
+ HEADER
66
+ ========================================================= */
67
+ header {
68
+ text-align: center;
69
+ padding-block: var(--space-md);
70
+ border-bottom: 1px solid var(--border);
71
+ }
72
+
73
+ header h1 {
74
+ color: var(--accent);
75
+ font-size: 2rem;
76
+ margin-bottom: 0.25rem;
77
+ }
78
+
79
+ main {
80
+ padding: 0 var(--space-md);
81
+ }
82
+
83
+ #tagline {
84
+ color: var(--accent2);
85
+ font-weight: 500;
86
+ }
87
+
88
+ /* =========================================================
89
+ HEADINGS
90
+ ========================================================= */
91
+ h2 {
92
+ display: flex;
93
+ align-items: center;
94
+ line-height: 1;
95
+ gap: var(--space-md);
96
+ color: var(--accent);
97
+ margin-bottom: var(--space-md);
26
98
  }
27
99
 
28
- .container {
29
- max-width: 800px;
30
- margin: auto;
31
- padding: 1rem;
100
+ h2 i {
101
+ padding: var(--space-md);
102
+ background-color: var(--accent2);
103
+ border-radius: 100%;
104
+ color: var(--bg);
105
+ }
106
+
107
+ h2 span {
108
+ padding: var(--space-md) 0;
109
+ flex-grow: 1;
110
+ border-bottom: 2px solid var(--accent);
32
111
  }
33
112
 
34
- h1,
35
- h2,
36
113
  h3 {
37
- color: var(--primary-color);
38
- margin-top: 2rem;
114
+ color: var(--accent2);
115
+ }
116
+
117
+ /* =========================================================
118
+ TYPOGRAPHY
119
+ ========================================================= */
120
+
121
+ ul {
122
+ padding-left: 1.2rem;
123
+ list-style: disc;
39
124
  }
40
125
 
41
126
  p {
42
- margin: 1rem 0;
127
+ margin-bottom: var(--space-md);
43
128
  }
44
129
 
45
- code {
46
- background: var(--code-bg);
47
- color: var(--code-text);
48
- padding: 0.2rem 0.4rem;
49
- border-radius: 4px;
50
- font-family: monospace;
130
+ p:last-child {
131
+ margin-bottom: 0;
51
132
  }
52
133
 
134
+ /* =========================================================
135
+ CODE BLOCKS
136
+ ========================================================= */
137
+ code,
53
138
  pre {
54
- background: var(--code-bg);
55
- color: #ddd;
56
- padding: 1rem;
57
- overflow-x: auto;
58
- border-radius: 6px;
59
- font-family: monospace;
60
- border-left: 4px solid var(--primary-color);
139
+ font-family: var(--font-mono);
140
+ background-color: var(--code-bg);
141
+ color: var(--accent2);
61
142
  }
62
143
 
144
+ pre {
145
+ padding: var(--space-md);
146
+ border-radius: var(--radius-sm);
147
+ overflow-x: auto;
148
+ border: 1px solid var(--border);
149
+ }
150
+
151
+ /* =========================================================
152
+ TABLES
153
+ ========================================================= */
154
+ table {
155
+ width: 100%;
156
+ border-collapse: collapse;
157
+ margin-top: var(--space-md);
158
+ }
159
+
160
+ th,
161
+ td {
162
+ text-align: left;
163
+ padding: var(--space-sm);
164
+ border: 1px solid var(--border);
165
+ }
166
+
167
+ th {
168
+ background-color: var(--card-bg);
169
+ color: var(--accent2);
170
+ }
171
+
172
+ tr:nth-child(even) {
173
+ background-color: #151515;
174
+ }
175
+
176
+ /* =========================================================
177
+ LINKS
178
+ ========================================================= */
63
179
  a {
64
- color: var(--primary-color);
65
- text-decoration: none;
180
+ color: var(--accent);
181
+ text-decoration: none;
182
+ transition: color 0.2s ease;
66
183
  }
67
184
 
68
- .btn {
69
- transition: all 0.15s ease-in-out;
70
- background-color: var(--primary-color);
71
- border: none;
72
- color: #fff;
73
- padding: 10px 20px;
74
- font-size: 1rem;
75
- margin: .5rem .2rem;
76
- cursor: pointer;
77
- border-radius: 5px;
78
- display: inline-block;
79
- text-align: center;
185
+ a:hover,
186
+ a:focus {
187
+ color: var(--accent2);
188
+ text-decoration: underline;
189
+ outline: none;
80
190
  }
81
191
 
82
- .btn:hover {
83
- opacity: 0.85;
192
+ /* =========================================================
193
+ STATUS BADGES
194
+ ========================================================= */
195
+ .status {
196
+ font-size: 0.75rem;
197
+ padding: var(--space-xs) var(--space-sm);
198
+ border-radius: var(--radius-sm);
199
+ text-transform: uppercase;
200
+ letter-spacing: 0.5px;
201
+ background-color: var(--badge-bg);
202
+ border: 1px solid var(--border);
84
203
  }
85
204
 
86
- .btn.active {
87
- background-color: var(--code-bg);
88
- color: #fff;
89
- pointer-events: none;
205
+ .status-planned {
206
+ color: var(--accent);
90
207
  }
91
208
 
92
- header {
93
- font-weight: 600;
209
+ .status-inprogress {
210
+ color: var(--accent2);
94
211
  }
95
212
 
96
- footer p {
97
- text-align: center;
98
- margin: 0;
213
+ .status-research {
214
+ color: #b98cff;
215
+ }
216
+
217
+ .status-idea {
218
+ color: #999;
219
+ }
220
+
221
+ .sr-only {
222
+ display: none;
223
+ }
224
+
225
+ .max-width {
226
+ max-width: 900px;
227
+ }
228
+
229
+ /* =========================================================
230
+ LOGO
231
+ ========================================================= */
232
+ header img {
233
+ display: block;
234
+ margin: 0 auto var(--space-sm);
235
+ max-width: 180px;
236
+ width: 100%;
237
+ height: auto;
238
+ }
239
+
240
+ /* =========================================================
241
+ FOOTER
242
+ ========================================================= */
243
+ /* =========================================================
244
+ ENHANCED FOOTER
245
+ ========================================================= */
246
+
247
+ .site-footer {
248
+ margin-top: 4rem;
249
+ padding: var(--space-lg);
250
+ border-top: 1px solid var(--border);
251
+ font-size: 0.9rem;
252
+ color: #999;
253
+ }
254
+
255
+ .footer-grid {
256
+ display: grid;
257
+ gap: var(--space-lg);
258
+ margin-bottom: 2rem;
259
+ }
260
+
261
+ @media (min-width: 700px) {
262
+ .footer-grid {
263
+ grid-template-columns: repeat(3, 1fr);
264
+ }
265
+ }
266
+
267
+ .footer-col h3,
268
+ .footer-col h4 {
269
+ margin-bottom: var(--space-sm);
270
+ color: var(--accent);
271
+ }
272
+
273
+ .footer-col h4 {
274
+ padding-bottom: var(--space-sm);
275
+ border-bottom: 2px solid var(--accent);
276
+ }
277
+
278
+ .footer-col p {
279
+ margin-bottom: var(--space-sm);
280
+ }
281
+
282
+ .footer-col ul {
283
+ list-style: none;
284
+ padding: 0;
285
+ }
286
+
287
+ .footer-col li {
288
+ margin-top: var(--space-xs);
289
+ }
290
+
291
+ .footer-col a {
292
+ color: var(--accent);
293
+ }
294
+
295
+ .footer-col a:hover {
296
+ color: var(--accent2);
297
+ }
298
+
299
+ .footer-bottom {
300
+ border-top: 1px solid var(--border);
301
+ padding-top: 1rem;
302
+ text-align: center;
303
+ font-size: 0.85rem;
304
+ color: #777;
305
+ }
306
+
307
+
308
+ /* =========================================================
309
+ ACCESSIBILITY
310
+ ========================================================= */
311
+ @media (prefers-reduced-motion: reduce) {
312
+ html {
313
+ scroll-behavior: auto;
314
+ }
315
+
316
+ *,
317
+ *::before,
318
+ *::after {
319
+ transition: none !important;
320
+ }
99
321
  }
File without changes
@@ -1,46 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
-
4
- <head>
5
- <meta charset="UTF-8" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>Welcome to Minimaz</title>
8
- <link rel="stylesheet" href="../style.css" />
9
- <link rel="shortcut icon" href="../../public/favicon.ico" type="image/x-icon">
10
-
11
- </head>
12
-
13
- <body>
14
- <header>
15
- <nav>
16
- <a class='btn' href="../index.html">Home</a>
17
- <a class='btn active' href="pages/about.html">About</a>
18
- <a class='btn' target="_blank" href="https://github.com/zeller-dev/minimaz">GitHub</a>
19
- </nav>
20
- </header>
21
- <div class="container">
22
- <h1>About Minimaz</h1>
23
- <p><strong>Minimaz</strong> is a minimal build tool that helps you quickly scaffold and minify HTML, CSS, and
24
- JavaScript projects.</p>
25
-
26
- <h2>Features</h2>
27
- <ul>
28
- <li>Zero-config HTML/CSS/JS minification</li>
29
- <li>Folder structure based on <code>src</code>, <code>public</code>, and <code>dist</code></li>
30
- <li>Simple CLI with <code>init</code>, <code>build</code>, and <code>help</code> commands</li>
31
- </ul>
32
-
33
- <h2>Getting Started</h2>
34
- <pre><code>$ minimaz init my-project
35
- $ cd my-project
36
- $ minimaz build</code></pre>
37
-
38
- <p>Learn more or contribute on <a href="#">GitHub</a>.</p>
39
- </div>
40
- <footer>
41
- <p>&copy; 2023 Minimaz. All rights reserved.</p>
42
- </footer>
43
- <script src="../script.js"></script>
44
- </body>
45
-
46
- </html>
@@ -1 +0,0 @@
1
- console.log('Minimaz is ready!')