minimaz-cli 0.5.0 → 0.5.2
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/bin/cli.js +9 -8
- package/package.json +3 -3
package/bin/cli.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{transform as fe}from"esbuild";import{cp as Yt,lstat as Kt,mkdir as ot,readdir as Qt,readFile as it,rm as nt,stat as qt,writeFile as Xt}from"node:fs/promises";import{dirname as Zt}from"node:path";var Nt={error:"\x1B[31m[ --- ERROR ----- ] \x1B[0m",warn:"\x1B[33m[ --- WARN ------ ] \x1B[0m",success:"\x1B[32m[ --- SUCCESS --- ] \x1B[0m",info:"\x1B[34m[ --- INFO ------ ] \x1B[0m",debug:"\x1B[90m[ --- DEBUG ----- ] \x1B[0m"};function _t(t=new Date){let e=p=>p<10?"0"+p:""+p,r=t.getFullYear(),o=e(t.getMonth()+1),n=e(t.getDate()),a=e(t.getHours()),s=e(t.getMinutes()),c=e(t.getSeconds());return`${r}-${o}-${n} ${a}:${s}:${c}`}var rt=()=>process.env.VERBOSE==="true";function Ht(t){return Array.isArray(t)?t:[t]}function Jt(t,e){let r=Nt[t]+e;if(t==="error"){console.error(r);return}if(t==="warn"){console.warn(r);return}console.log(r)}function Vt(){return rt()?`[${_t()}] `:""}function E(t,e,r=!1,o=!1){let n=rt();if(o&&!n)return;let a=Ht(e);for(let s=0;s<a.length;s++){let c=a[s];if(r){console.log(n?`${Vt()}${c}`:c);continue}Jt(t,c)}}var i={debug(t){E("debug",t,!1,!0)},default(t){E("info",t,!0)},error(t){E("error",t)},info(t){E("info",t)},success(t){E("success",t,!1)},verbose(t){E("info",t,!0,!0)},warn(t){E("warn",t)}};async function m(t){try{return await qt(t),!0}catch{return!1}}async function L(t){if(!await m(t))throw new Error(`NOT FOUND: "${t}" does not exist`);try{let r=await it(t,"utf8");return JSON.parse(r)}catch(r){let o=r instanceof Error?r.message:String(r);throw new Error(`PARSE ERROR: Failed to parse JSON in "${t}" - ${o}`,{cause:r})}}async function y(t){return i.debug(`Reading directory: ${t}`),await m(t)?await Qt(t):(i.warn(`Directory does not exist: ${t}`),[])}async function I(t){await nt(t,{recursive:!0,force:!0})}async function P(t){await ot(t,{recursive:!0})}async function $(t,e,r=!1){r&&(i.debug(`${e} exists, removing...`),await nt(e,{recursive:!0,force:!0})),i.debug(`[COPY] ${t} to ${e}...`),await Yt(t,e,{recursive:!0})}async function x(t,e,r){let o=Zt(t);await ot(o,{recursive:!0}),await Xt(t,e,r||"utf8")}async function T(t){return Kt(t).then(e=>e.isDirectory()).catch(()=>!1)}async function F(t){try{return await it(t,"utf8")}catch(e){let r=e instanceof Error?e.message:String(e);return i.error(`Failed to read file at "${t}": ${r}`),""}}import{basename as R,dirname as V,extname as S,isAbsolute as A,join as u,normalize as b,resolve as w}from"node:path";var g={globalDir:".minimaz",inputDir:"./src",outputDir:"./dist"},G={input:{dir:g.inputDir,mapping:{pages:"",scripts:"",styles:"",public:""},externals:{"./node_modules/example/fonts":"assets/fonts","https://example.com/library.js":"js/vendor/vue.js"},exclude:["**/test/**","**dev**"]},output:{dir:g.outputDir,replace:{"../public/":"/"},css:{bundling:!0,minify:!0},html:{minify:!0},js:{bundling:!0,minify:!0}}};var U=new Map;import{spawn as re}from"cross-spawn";import{execSync as oe}from"node:child_process";import{homedir as ie}from"node:os";import{createInterface as ne}from"node:readline";import{transform as te}from"esbuild";import{minify as ee}from"html-minifier-terser";async function st(t,e,r){try{let o=r===".css"?"css":r.includes("ts")?"ts":"js";await te(e,{loader:o,format:"esm",logLevel:"silent"}),i.success(`${o.toUpperCase()} Valid: ${t}`)}catch(o){i.error(`Syntax Error in ${t}:`);let n=o;n.errors&&Array.isArray(n.errors)&&n.errors.forEach(a=>{let s=a.location?.line??"??";i.error(` -> Line ${s}: ${a.text}`)})}}async function at(t,e){try{await ee(e,{continueOnParseError:!1,caseSensitive:!0}),i.success(`HTML Valid: ${t}`)}catch(r){let o=r instanceof Error?r.message:String(r);i.error(`HTML Error [${t}]: ${o}`)}}var W=class extends Error{errors;constructor(e){super("Config validation error"),this.name="ConfigValidationError",this.errors=e}};function Y(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)&&Object.values(t).every(e=>typeof e=="string")}function B(t,e){try{let r=JSON.parse(e);if(typeof r!="object"||r===null)throw new Error("Invalid config root object");let o=r,n=[];if(!o.input)n.push("Missing 'input' section");else{let{input:s}=o;typeof s.dir!="string"&&n.push("input.dir must be a string"),Y(s.mapping)||n.push("input.mapping must be a valid key-value record of strings"),s.externals!==void 0&&!Y(s.externals)&&n.push("input.externals must be a valid key-value record of strings"),s.exclude!==void 0&&!Array.isArray(s.exclude)&&n.push("input.exclude must be an array of strings")}if(!o.output)n.push("Missing 'output' section");else{let{output:s}=o;typeof s.dir!="string"&&n.push("output.dir must be a string"),s.replace!==void 0&&!Y(s.replace)&&n.push("output.replace must be a valid key-value record of strings"),["css","js"].forEach(p=>{let l=s[p];(!l||typeof l.bundling!="boolean"||typeof l.minify!="boolean")&&n.push(`output.${p} must contain 'bundling' (boolean) and 'minify' (boolean)`)}),(!s.html||typeof s.html.minify!="boolean")&&n.push("output.html must contain 'minify' (boolean)")}let a=Object.keys(G);if(Object.keys(o).forEach(s=>{a.includes(s)||i.warn(`Unknown configuration key: '${s}' in ${t}`)}),n.length>0)throw new W(n);i.success("Config: valid")}catch(r){i.error(`Config Error in ${t}:`),r instanceof W?r.errors.forEach(o=>{i.error(` -> ${o}`)}):r instanceof SyntaxError?i.error(` -> Invalid JSON syntax: ${r.message}`):r instanceof Error?i.error(` -> ${r.message}`):i.error(" -> Unknown error")}}function h(t,e=""){return new Promise(r=>{let o=ne({input:process.stdin,output:process.stdout}),n=setTimeout(()=>{o.close(),r(e)},6e4);o.question(`[QUESTION] ${t}`,a=>{clearTimeout(n),o.close(),r(a.trim()||e)}),o.on("SIGINT",()=>{clearTimeout(n),o.close(),process.exit(130)})})}function O(t,e={}){return Object.entries(e).reduce((r,[o,n])=>{let a=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),s=new RegExp(a,"g");return r.replace(s,n)},t)}async function D(t,e){try{let r=b(t),o;return U.has(r)?(o=U.get(r),i.debug(`Cache hit: ${r}`)):(o=await F(r),U.set(r,o),i.debug(`Cache miss (Disk read): ${r}`)),e&&(o=O(o,e)),o}catch(r){let o=r instanceof Error?r.message:String(r);return i.error(`Failed to read file ${t}: ${o}`),""}}function ct(){i.debug("Getting global node modules");try{let t=oe("npm config get prefix",{encoding:"utf8"}).trim();if(!t)throw new Error("Empty npm prefix");return process.platform==="win32"?u(t,"node_modules","minimaz-cli"):u(t,"lib","node_modules","minimaz-cli")}catch{return process.platform==="win32"?u(process.env.APPDATA||"","npm","node_modules","minimaz-cli"):"/usr/local/lib/node_modules/minimaz-cli"}}async function se(){i.debug("Checking existence of global Minimaz directory");let t=u(ie(),g.globalDir);if(!await m(t))throw new Error('Global Minimaz folder does not exist.Run "minimaz config" to generate it');return t}async function K(){i.debug("Getting global templates directory");let t=u(await se(),"templates");if(!await m(t))throw new Error("Template directory not found in global directory");return t}async function pt(t){i.debug(`Getting template "${t}"directory`);let e=u(await K(),t);if(!await m(e))throw new Error(`Template "${t}" not found`);return e}async function N(){i.debug("Getting default templates directory");let t=u(ct(),"templates");if(!await m(t))throw new Error("Default template folder not found");return t}function j(t,e,r){return i.debug(`Running: ${t} ${e.join(" ")}`),new Promise((o,n)=>{let a=re(t,e,{cwd:r,stdio:"inherit"});a.on("error",n),a.on("close",s=>s===0?o():n(new Error(`${t} exited with code ${s}`)))})}async function C(t,e,r=!0){i.debug("Creating file from template");let o=w(...e),n="";if(t!==void 0)if(typeof t=="string")n=t.endsWith(`
|
|
2
3
|
`)?t:`${t}
|
|
3
4
|
`;else if(typeof t=="object"&&t!==null)n=`${JSON.stringify(t,null,2)}
|
|
4
|
-
`;else throw new Error("Unsupported template type. Must be string or object");try{if(!r&&await m(o)){i.info(`File already exists at "${o}", skipping`);return}await x(o,n)}catch(a){let s=a instanceof Error?a.message:String(a);throw new Error(`Failed to create file at "${o}": ${s}`,{cause:a})}}async function _(t){i.debug("Output Directory: removing");let e=t?A(t)?t:f([t]):
|
|
5
|
-
${n}`),t}}import{build as
|
|
5
|
+
`;else throw new Error("Unsupported template type. Must be string or object");try{if(!r&&await m(o)){i.info(`File already exists at "${o}", skipping`);return}await x(o,n)}catch(a){let s=a instanceof Error?a.message:String(a);throw new Error(`Failed to create file at "${o}": ${s}`,{cause:a})}}async function _(t){i.debug("Output Directory: removing");let e=t?A(t)?t:f([t]):w(process.cwd(),(await Q()).output.dir??g.outputDir),r=process.cwd();if(e===r||e.length<=r.length)throw new Error(`Refusing to delete unsafe directory: ${e}`);if(!await m(e)){i.debug(`No output.dir folder found: ${e}`);return}await I(e),i.success("Output Directory: removed")}async function Q(){i.info("Loading minimaz.config.json");let t=f(["minimaz.config.json"]);if(!await m(t))throw new Error("minimaz.config.json not found");try{let e=await F(t);B(t,e);let r=JSON.parse(e);return i.success("Loaded config from minimaz.config.json"),r}catch(e){let r=e instanceof Error?e.message:String(e);throw new Error(`Failed to load configuration: ${r}`,{cause:e})}}function f(t=[]){i.debug("Current path: resolving");let e=w(process.env.CLI_WORKDIR??process.cwd(),...t);return i.debug(`Current path: ${e}`),e}function mt(t){return{createdAt:new Date().toISOString(),templatesPath:t,npmGlobalPath:ct()}}function q(t){if(t===void 0)return;if(typeof t=="boolean")return t;let e=t.toLowerCase();return!(e==="false"||e==="0"||e==="n")}import{build as ae}from"esbuild";async function ut(t,e,r,o,n,a,s){if(i.debug(`Processing CSS: ${t.src}`),o){let c=await ae({stdin:{contents:t.content,resolveDir:w(t.src,".."),loader:"css",sourcefile:t.src},bundle:!0,write:!1,metafile:!0,minify:n,charset:"utf8",legalComments:"none",plugins:[{name:"external-assets",setup(l){l.onResolve({filter:/\.(woff2?|ttf|otf|eot|svg|png|jpe?g|gif|webp|avif|ico)(\?.*)?(#.*)?$/i},d=>({path:d.path,external:!0}))}}],target:["chrome80","safari13","firefox70","edge79"]}),p=c.outputFiles[0]?.text??"";if(s&&(p=O(p,s)),a){for(let l of Object.values(a))if(l.startsWith("/")){let d=l.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),v=new RegExp(`(\\.\\.\\/|\\.\\/)+${d}`,"g");p=p.replace(v,l)}}if(c.metafile){let l=b(w(t.src));for(let d of Object.keys(c.metafile.inputs)){let v=b(w(d));v!==l&&r.add(v)}}e.chunks.push(p),await x(t.dest,p)}else{let c=t.content;n&&(c=await ce(c)),await x(t.dest,c)}}async function ce(t){return M(t,{loader:"css",minify:!0,charset:"utf8",sourcemap:!1,legalComments:"none",target:["chrome80","safari13","firefox70","edge79"]},"MinifyCSS")}import{minify as pe}from"html-minifier-terser";async function lt(t,e){i.debug(`Processing HTML: ${t.src}`);let r=t.content;e.output?.html?.minify&&(r=await me(r,t.src)),await x(t.dest,r)}async function me(t,e="unknown"){if(typeof t!="string")throw new Error(`[MinifyHTML] Input for ${e} must be a string`);let r=t.trim();if(!r)return"";try{return await pe(r,{collapseWhitespace:!0,removeComments:!0,removeRedundantAttributes:!0,removeScriptTypeAttributes:!0,removeStyleLinkTypeAttributes:!0,useShortDoctype:!0,minifyJS:!0,minifyCSS:!0,processConditionalComments:!0,ignoreCustomComments:[/^!/],caseSensitive:!0})}catch(o){let n=o instanceof Error?o.message:String(o);return i.error(`[MinifyHTML Failed in ${e}]
|
|
6
|
+
${n}`),t}}import{build as ue}from"esbuild";async function ft(t,e,r,o,n,a,s){if(/require\s*\(|module\.exports|exports\./.test(t.content)&&i.warn(`CommonJS detected in ${t.src}. Esbuild will attempt to convert, but ESM is recommended.`),o){let c=await dt(t,n,r,a,s);e.chunks.push(c),await x(t.dest,c)}else{let c=t.content;n&&(c=await le(c,!0)),await x(t.dest,c)}}async function gt(t,e,r,o,n,a,s){let c=t.dest.replace(/\.(ts|tsx)$/i,".js");if(o){let p=await dt(t,n,r,a,s);e.chunks.push(p),await x(c,p)}else{let p=t.ext===".tsx"?"tsx":"ts",l=await M(t.content,{loader:p,target:"es2022",format:"esm",minify:n},"ProcessTS");await x(c,l)}}async function dt(t,e,r,o,n){let a=t.ext===".tsx"?"tsx":t.ext===".ts"?"ts":"js",s=await ue({stdin:{contents:t.content,resolveDir:w(t.src,".."),loader:a,sourcefile:t.src},bundle:!0,write:!1,metafile:!0,format:"esm",platform:"browser",target:"es2022",minify:e,splitting:!1,treeShaking:!0,mainFields:["module","main"],conditions:["import","browser"],footer:{js:""},legalComments:"none"}),c=s.outputFiles[0]?.text??"";if(n&&(c=O(c,n)),o){for(let p of Object.values(o))if(p.startsWith("/")){let l=p.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),d=new RegExp(`(\\.\\.\\/|\\.\\/)+${l}`,"g");c=c.replace(d,p)}}if(s.metafile){let p=b(w(t.src));for(let l of Object.keys(s.metafile.inputs)){let d=b(w(l));d!==p&&r.add(d)}}return c}async function le(t,e=!0){return M(t,{loader:"js",format:"esm",minify:e,treeShaking:!0,sourcemap:!1,legalComments:"none",target:"es2022",pure:["console.log","console.debug"]},"MinifyJS")}async function M(t,e,r){if(typeof t!="string")throw new Error(`[${r}] Input must be a string`);let o=t.trim();if(!o)return i.debug(`[${r}] empty input skipped`),"";i.debug(`[${r}] transform start`);try{let{code:n}=await fe(o,{...e,charset:"utf8",logLevel:"silent"});return i.debug(`[${r}] transform success`),n??""}catch(n){let a=n,s=(a.errors||[]).map(c=>`[Line ${c.location?.line??"?"}] ${c.text}`).join(`
|
|
6
7
|
`);return i.error(`[${r} Failed]
|
|
7
|
-
${s||a.message}`),""}}async function H(t,e,r,o){let n=await y(t),a=f([r.input.dir]),s=f([r.output.dir]),c=
|
|
8
|
+
${s||a.message}`),""}}async function H(t,e,r,o){let n=await y(t),a=f([r.input.dir]),s=f([r.output.dir]),c=w(t);for(let p of n){if(r.input.exclude?.includes(p))continue;let l=u(t,p),d=b(l),k=(r.input.mapping||{})[p],z;if(c===a&&typeof k=="string"?z=u(s,k):z=u(e,p),o.has(d)){i.debug(`Skipping bundled dependency: ${d}`);continue}if(await T(l)){await H(l,z,r,o);continue}await P(V(z));let Wt=await D(l,r.output.replace),Bt=S(l).toLowerCase();await wt({src:l,dest:z,content:Wt,ext:Bt},r,o)}}async function wt(t,e,r){let o={chunks:[],outFile:t.dest};switch(t.ext){case".html":await lt(t,e);break;case".css":await ut(t,o,r,!!e.output?.css?.bundling,!!e.output?.css?.minify,e.input.externals,e.output.replace);break;case".js":await ft(t,o,r,!!e.output?.js?.bundling,!!e.output?.js?.minify,e.input?.externals,e.output?.replace);break;case".ts":case".tsx":await gt(t,o,r,!!e.output?.js?.bundling,!!e.output?.js?.minify,e.input?.externals,e.output?.replace);break;default:await $(t.src,t.dest)}}async function yt(t,e,r,o){i.debug("External: Processing");for(let[n,a]of Object.entries(e)){if(n.startsWith("http")){i.info(`Remote external: ${n} \u2192 ${a}`);continue}let s=f([n]);if(o.has(b(s)))continue;if(!await m(s)){i.warn(`External not found: ${n}`);continue}let c=u(t,a);if(await T(s)){await H(s,c,r,o);continue}let p=await D(s,r.output.replace);await wt({src:s,dest:c,content:p,ext:S(s).toLowerCase()},r,o)}}async function xt(t){await _(t),await P(t)}function ge(t,e){let r=[],o=/import\s+(?:(?:[\w\s{},*]+\s+from\s+)?["'](.+?)["']|["'](.+?)["'])\s*;?/g,a={".css":/@import\s+(?:url\s*\()?\s*["']([^"']+)["']\s*\)?\s*;?/g,".js":o,".ts":o,".tsx":o}[e];if(!a)return[];let s=Array.from(t.matchAll(a));for(let c of s){let p=c[1]||c[2];p&&r.push(p)}return r}async function X(t,e,r,o){let n=await y(t);for(let a of n){if(e.input.exclude?.includes(a))continue;let s=u(t,a);if(await T(s)){await X(s,e,r,o);continue}let c=S(s).toLowerCase();if([".css",".js",".ts",".tsx"].includes(c)){let p=await D(s,o),l=ge(p,c);for(let d of l){let v=w(V(s),d);if(!S(v)){for(let k of[".ts",".js",".css",".tsx"])if(await m(v+k)){v+=k;break}}r.add(b(v))}}}}async function bt(){let t=await Q(),e=f([t.input.dir]),r=f([t.output.dir]);await xt(r);let o=new Set;if((await y(t.input.dir)).length===0){i.error(`Directory ${t.input.dir} is empty`);return}i.info("Discovery: starting"),await X(e,t,o,t.output.replace??{}),i.info("Processing: starting"),await H(e,r,t,o);let a=t.input.externals||{},s=Object.keys(a);s.length>0&&(i.debug(`Processing ${s.length} external resources`),await yt(r,a,t,o)),i.success(`Build completed. Output saved in ${t.output.dir}`)}async function ht(){await _()}import{homedir as de}from"node:os";async function vt(t){if(await m(t)){i.info(`~/${g.globalDir} already exists. Skipping`);return}i.info(`~/${g.globalDir} does not exist. Generating`),await P(t)}async function $t(t){if(await m(t)){i.info(`~/${g.globalDir}/templates already exists, skipping`);return}await P(t),i.success(`Templates directory created at ${t}`)}async function Ct(t,e,r){i.info("Checking default templates");let o=await y(t);if(o.length===0){i.warn("No default templates available");return}for(let n of o){let a=u(t,n),s=u(e,n),c=await m(s);if(c&&!r){i.info(`Template "${n}" already exists. Skipping`);continue}await $(a,s,r),i.success(c&&r?`Template "${n}" overwritten`:`Template "${n}" copied`)}}async function Et(t,e,r){let o=mt(e);if(!await m(t)||r){await C(o,[t]),await m(t)&&r?i.success(`Overwritten settings.json at ${t}`):i.success(`Created settings.json at ${t}`);return}let n;try{n=await L(t)}catch{i.warn("Failed to read settings.json. Recreating from template"),await C(o,[t]);return}let a=!1;for(let s of Object.keys(o))s in n||(n[s]=o[s],i.warn(`Added missing key "${s}" to settings.json`),a=!0);for(let s of Object.keys(n))s in o||i.warn(`Unknown key "${s}" found in settings.json`);a?(await C(n,[t]),i.success("Updated settings.json")):i.info("settings.json is valid and up-to-date")}async function J(t){i.debug(`Config initialization (overwrite=${t})`);let e=u(de(),g.globalDir);await vt(e);let r=await N();if(!await m(r)){i.error("Default templates directory not found");return}let o=u(e,"templates");await $t(o),await Ct(r,o,t);let n=u(e,"settings.json");await Et(n,o,t)}var Z={build:{usage:"minimaz build | b",description:`Build project into output.dir folder (default: ${g.outputDir})`},clear:{usage:"minimaz clear | c",description:`Clear the output.dir folder (default: ${g.outputDir})`},help:{usage:"minimaz help | h",description:"Show this help message"},init:{usage:"minimaz init | i <project-name>",description:"Create a new project (default: 'minimaz-project')",options:{"--template | -t <template-name>":"Use a global template (default: 'default')"}},template:{usage:"minimaz template | t [path]",description:"Save folder as a template (no path = current folder)",options:{"--list | -l":"List available global templates","--delete | -d <template-name>":"Delete a global template"}},validate:{usage:"minimaz validate",description:"Validate file"},version:{usage:"minimaz version | v",description:"Show Minimaz version"}};function tt(t){if(t){let e=Z[t];if(!e){i.default(`No help found for: ${t}
|
|
8
9
|
`);return}if(i.default([e.usage,`
|
|
9
10
|
${e.description}`]),e.options){i.default(" Options:");for(let[r,o]of Object.entries(e.options))i.default(` ${r} ${o}`)}i.default("");return}i.default(`Usage:
|
|
10
11
|
`);for(let e of Object.values(Z)){if(i.default([e.usage,`
|
|
11
|
-
${e.description}`]),e.options){i.default(" Options:");for(let[r,o]of Object.entries(e.options))i.default(` ${r} ${o}`)}i.default("")}}var
|
|
12
|
+
${e.description}`]),e.options){i.default(" Options:");for(let[r,o]of Object.entries(e.options))i.default(` ${r} ${o}`)}i.default("")}}var Pt={version:"0.0.1",license:"ISC",type:"commonjs",scripts:{build:"npx mz b",start:`npx mz b && npx serve ${g.outputDir}`},devDependencies:{"minimaz-cli":"latest",serve:"latest"}},St=`node_modules
|
|
12
13
|
${g.outputDir.replace("./","")}
|
|
13
14
|
.env
|
|
14
15
|
.vscode
|
|
15
|
-
.DS_Store`;async function
|
|
16
|
-
${e}`,{cause:t})}}process.env.npm_lifecycle_event==="postinstall"&&(await
|
|
17
|
-
Use "minimaz help" to see available commands`),tt())}catch(n){let a=process.env.DEBUG==="true",s=n instanceof Error?a?n.stack??n.message:n.message:String(n);i.error(s),process.exit(1)}}await ye();export{
|
|
16
|
+
.DS_Store`;async function jt(t,e){i.info("npm: initializing"),await C({name:e,...Pt},[t,"package.json"]),await j("npm",["i"],t)}async function we(t,e,r,o="origin"){if(r==="local"){i.info("Using local Git repository");return}if(/^https?:\/\//.test(r)||r.startsWith("git@")){i.info(`Connecting existing remote "${r}"`),await j("git",["remote","add",o,r],e);return}if(r==="github"){i.info(`Creating GitHub repository "${t}"`),await j("gh",["repo","create",t,"--private","--source=.","--remote",o],e);return}if(r==="gitlab"){i.info(`Creating GitLab repository "${t}"`);let n=process.env.GITLAB_USER;if(!n)throw new Error("GITLAB_USER not set");await j("glab",["repo","create",t,"--source=."],e),await j("git",["remote","add",o,`git@gitlab.com:${n}/${t}.git`],e);return}throw new Error(`Unsupported git provider or remote: "${r}"`)}async function Tt(t,e,r,o="origin"){r||(r=(await h("Select a provider or paste a url to connect your existing repo (cli tools needed) [LOCAL/github/gitlab]:","local")).toLowerCase().trim()),i.info("Initializing Git repository"),await j("git",["init"],e),r&&r!=="false"&&r!=="local"?await we(t,e,r,o):i.info("Git repository initialized locally"),i.debug("Initializing gitignore"),await C(St,[e,".gitignore"]),i.success("Git repository initialized")}async function Dt(t,e){let r=f([t]);if(await m(r))throw new Error(`Target directory "${r}" already exists`);let o=await pt(e.template);i.debug(`Copying template from "${o}" to "${r}"`),await $(o,r),i.debug("Initializing minimaz.config.json"),await C(G,[r,"minimaz.config.json"],!1),(q(e.npm)??(await h("Init NPM? [Y/n]:","y")).toLowerCase().startsWith("y"))&&await jt(r,t),(q(e.git)??(await h("Init Git repository? [Y/n]:","y")).toLowerCase().startsWith("y"))&&await Tt(t,r,e.gitprovider),i.success(`Project "${t}" created using template "${e.template}"`)}async function kt(t,e){let r=f([]),o=u(t,e);if(!await m(o))throw new Error(`Template "${e}" not found`);if(!(await h(`Update "${e}" with current directory? [Y/n]:`,"y")).startsWith("y")){i.info("Update cancelled");return}try{await $(r,o,!0),i.success(`Template "${e}" updated`)}catch(n){let a=n instanceof Error?n.message:String(n);throw new Error(`Update template error: ${a}`,{cause:n})}}async function zt(t){let e=await N(),r=await y(e);if(!(await h("Update local templates overwriting them with defaults? [Y/n]:","y")).startsWith("y")){i.info("Update cancelled");return}try{for(let o of r){let n=u(e,o),a=u(t,o);await $(n,a,!0),i.success(`Updated "${o}"`)}i.info("Templates updated successfully")}catch(o){let n=o instanceof Error?o.message:String(o);throw new Error(`Update template error: ${n}`,{cause:o})}}async function Ft(t,e){let r=u(t,e);if(!await m(r))throw new Error(`Template not found: ${e}`);if(!(await h(`Confirm delete "${e}"? [Y/n]:`,"y")).startsWith("y")){i.info("Delete cancelled");return}try{await I(r),i.success(`Template "${e}" deleted`)}catch(o){let n=o instanceof Error?o.message:String(o);throw new Error(`Delete template error: ${n}`,{cause:o})}}async function Rt(t,e){let r=f(e?[e]:[]);if(!await m(r))if(i.warn(`Not found: ${r}`),(await h("Use current directory? [Y/n]:","y")).startsWith("y"))r=process.cwd();else throw new Error("Operation cancelled");try{await P(t);let o=u(t,R(r));if(await m(o)&&!(await h(`Template "${R(o)}" exists. Overwrite? [y/N]:`,"n")).startsWith("y")){i.info("Save cancelled");return}await $(r,o,!0),i.success(`Template saved to ${o}`)}catch(o){let n=o instanceof Error?o.message:String(o);throw new Error(`Save template error: ${n}`,{cause:o})}}async function Ot(t){let e=await y(t);if(e.length===0){i.info("No global templates available");return}i.info("Available global templates:");for(let r=0;r<e.length;r++)i.default(`${r} - ${e[r]}`)}async function Mt(t,e){let r=await K();if(t.list)return await Ot(r);if(t.delete)return await Ft(r,t.delete);if(await Rt(r,e),t.update)return typeof t.update=="string"&&t.update.trim()?await kt(r,t.update.trim()):await zt(r)}var Lt=[".js",".cjs",".mjs",".ts",".cts",".mts",".jsx",".tsx",".json",".css"];async function et(t){if(t==="undefined")throw new Error("No target path");let e=A(t)?t:f([t]);if(!await m(e))throw new Error(`Path does not exist: ${e}`);if(await T(e)){let a=await y(e);await Promise.all(a.map(s=>et(u(e,s))))}let r=R(e),o=S(e).toLowerCase(),n=await D(e);if(!n&&(await F(e)).length>0)throw new Error(`Failed to read content from non-empty file: ${e}`);if(r==="minimaz.config.json"){B(e,n);return}if(o===".html"){await at(e,n);return}if(Lt.includes(o)){await st(e,n,o);return}i.debug(`Skipping: ${e}`)}async function It(){let t=f(["package.json"]),e=await L(t);if(typeof e.version!="string")throw new Error("Invalid or missing version in package.json");i.default(e.version)}function At(t){let e={_:[]};for(let r=0;r<t.length;r++){let o=t[r].toLowerCase();if(!o.startsWith("-")){e._.push(o);continue}if(o.startsWith("--")&&o.includes("=")){let[s,c]=o.slice(2).split("=");e[s]=c;continue}let n=o.replace(/^-+/,""),a=t[r+1];a&&!a.startsWith("-")?(e[n]=a,r++):e[n]=!0}return e}function Gt(t,e){process.env.VERBOSE=t?"true":"false",process.env.CLI_WORKDIR=e??process.cwd(),i.debug(["Initializing environment variables",`CLI_WORKDIR = ${process.env.CLI_WORKDIR}`,`VERBOSE = ${process.env.VERBOSE}`])}async function Ut(){try{i.info("Post install: running"),await J(!1),i.success("Post install: completed")}catch(t){let e=t instanceof Error?t.message:String(t);throw new Error(`Post install: Failed
|
|
17
|
+
${e}`,{cause:t})}}process.env.npm_lifecycle_event==="postinstall"&&(await Ut(),process.exit(0));async function ye(){let t=At(process.argv.slice(2)),e=t._[0]||"",r=t._[1];Gt(t.v),(e==="help"||t.help||t.h)&&(tt(r||(t.help||t.h?e:void 0)),process.exit(0));let o={build:async()=>bt(),clear:()=>ht(),config:async()=>J(t.overwrite===!0||t.overwrite==="true"),init:async()=>{await Dt(r||"minimaz-project",{template:t.template||t.t||"default",npm:t.npm,git:t.git,gitremote:t.gitremote,gitprovider:t.gitprovider})},template:async()=>{await Mt({list:t.list||t.l,delete:t.delete||t.d,update:t.update||t.u},r)},validate:async()=>{await et(String(t.path))},version:()=>It(),b:()=>o.build(),c:()=>o.clear(),i:()=>o.init(),t:()=>o.template(),v:()=>o.version()};try{o[e]?(i.info(`Executing "${e}"`),await o[e]()):(i.error(`Unknown command "${e}"
|
|
18
|
+
Use "minimaz help" to see available commands`),tt())}catch(n){let a=process.env.DEBUG==="true",s=n instanceof Error?a?n.stack??n.message:n.message:String(n);i.error(s),process.exit(1)}}await ye();export{Gt as initEnv,At as parseArgs,Ut as postInstall};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "minimaz-cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "Minimal project initializer and builder CLI",
|
|
5
5
|
"author": "MrZeller",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"cross-spawn": "^7.0.6",
|
|
33
|
-
"esbuild": "^0.
|
|
33
|
+
"esbuild": "^0.28.0",
|
|
34
34
|
"html-minifier-terser": "^7.2.0"
|
|
35
35
|
},
|
|
36
|
-
"postinstall": "node
|
|
36
|
+
"postinstall": "node bin/cli.js",
|
|
37
37
|
"bin": {
|
|
38
38
|
"minimaz": "bin/cli.js",
|
|
39
39
|
"mz": "bin/cli.js"
|