svhost 1.0.16 → 1.0.17
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/dist/{chunk-RUIWK3KB.mjs → chunk-QFX4LT7J.mjs} +7 -7
- package/dist/chunk-QFX4LT7J.mjs.map +1 -0
- package/dist/index.js +11 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/svhost-nginx.js +11 -11
- package/dist/svhost-nginx.js.map +1 -1
- package/dist/svhost-nginx.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-RUIWK3KB.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as D,c as ee,e as R,f as b,g as N}from"./chunk-OVT4E7N5.mjs";var L,q=D(()=>{"use strict";L=class{constructor(e){this.svhostNginx=e}}});import T from"fs-extra";import{constants as _e,readdir as he}from"fs/promises";import y from"path";async function
|
|
1
|
+
import{a as D,c as ee,e as R,f as b,g as N}from"./chunk-OVT4E7N5.mjs";var L,q=D(()=>{"use strict";L=class{constructor(e){this.svhostNginx=e}}});import T from"fs-extra";import{constants as _e,readdir as he}from"fs/promises";import y from"path";async function H(c){try{return await T.exists(c)}catch{return!1}}async function A(c){try{return(await T.stat(c)).isFile()}catch{return!1}}async function S(c){try{return(await T.stat(c)).isDirectory()}catch{return!1}}async function M(c,e){let{recursive:r=!1,filesOnly:t=!1,dirsOnly:s=!1,returnType:o="absolute",forwardSlashes:n=!1,ignorefile:a,quiet:i=!0,includeIgnorefile:h=!1}=e||{};return new Promise(async(l,f)=>{function p(m){return n?m.replace(/\\/g,"/"):m}i||console.log(`Reading directory: ${c}`,{recursive:r,filesOnly:t,dirsOnly:s,returnType:o,forwardSlashes:n,quiet:i,includeIgnorefile:h,ignorefile:a});try{if(!await H(c))return f(new Error(`Directory does not exist: ${c}`));if(!await S(c))return f(new Error(`Path is not a directory: ${c}`));let g=(await he(c,{withFileTypes:!0,recursive:r})).filter(d=>!h&&d.name===".ignore"&&y.resolve(c)===y.resolve(d.parentPath)?!1:t?d.isFile():s?d.isDirectory():!0);if(a?.data||a?.path||await H(y.join(c,".ignore"))){i||console.log(`Applying ignore rules from: ${a?.path||"provided data"}`);let d="";if(a?.data)d=a.data;else if(a?.path)try{d=await T.readFile(a.path,"utf8")}catch(u){i||console.warn(`Warning: Could not read ignorefile at ${a.path}: ${u.message}`)}else try{d=await T.readFile(y.join(c,".ignore"),"utf8")}catch(u){i||console.warn(`Warning: Could not read ignorefile at ${y.join(c,".ignore")}: ${u.message}`)}if(d){i||(console.log(`All .ignore data:
|
|
2
2
|
------------------------`),console.log(d),console.log("------------------------"));let u="",x="",Y=v=>v?.replace(/(([ \t]*)#.*$)/gm,"")?.replace(/^([ \t])*|([ \t])*$/gm,"")?.split(/\r?\n/)?.filter(P=>P.length),ce=v=>v.match(/RegExp[ \s]*\([ \s]*['"`](?<regex>.*)['"`][ \s]*,[ \s]*['"`](?<flags>.*)['"`][ \s]*\)|RegExp[ \s]*\([ \s]*['"`](?<regex>.*)['"`][ \s]*\)/m),z=(v,J,P)=>v.filter(Z=>{let $=p(y.relative(c,y.resolve(Z.parentPath,Z.name)));for(let Q of J){let B=ce(Q);if($){if(B){let O=B?.groups?.regex||"",j=B?.groups?.flags||"m";if($?.match(new RegExp(O,j)))return P?(i||console.log(`Included path "${$}" via Regex("${O}","${j}") Match pattern.`),!0):(i||console.log(`Ignored path "${$}" via Regex("${O}","${j}") Match pattern.`),!1)}if($?.match(new RegExp(`^${Q}$`,"gm")))return P?(i||console.log(`Included path "${$}" via Match pattern.`),!0):(i||console.log(`Ignored path "${$}" via Match pattern.`),!1)}}return!P});if(d.match(/^[ \t]*#?[ \t]*EXCLUDE EXCLUDE EXCLUDE[ \t]*$/gm)&&(d.match(/^[ \t]*#[ \t]*EXCLUDE EXCLUDE EXCLUDE[ \t]*$/gm)?u=d.replace(/^[ \t]*#[ \t]*EXCLUDE EXCLUDE EXCLUDE[ \t]*.*/gms,""):x=d.replace(/.*[ \t]*EXCLUDE EXCLUDE EXCLUDE[ \t]*$/gms,"")),i||(console.log(`Include data:
|
|
3
3
|
------------------------`),console.log(x),console.log("------------------------"),console.log(`Exclude data - EXCLUDE EXCLUDE EXCLUDE:
|
|
4
4
|
------------------------`),console.log(u),console.log("------------------------")),console.log("Applying exclude and include rules from .ignore file"),console.log("Initial file count before applying ignore rules:",g.length),u){let v=Y(u);i||console.log("Exclude lines:",v),g=z(g,v,!1)}if(x){let v=Y(x);i||console.log("Include lines:",v),g=z(g,v,!0)}console.log("Final file count after applying ignore rules:",g.length)}}let F=y.resolve(c);switch(o){case"absolute":{let d=g.map(u=>{let x=y.join(u.parentPath,u.name);return p(x)});return l(d)}case"relative":{let d=g.map(u=>{let x=y.join(u.parentPath,u.name);return p(y.relative(F,x))});return l(d)}case"dirent":return l(g);case"all":{let d=g.map(u=>{let x=y.join(u.parentPath,u.name);return{name:u.name,absolutePath:p(x),relativePath:p(y.relative(F,x)),isFile:u.isFile(),isDirectory:u.isDirectory()}});return l(d)}default:return f(new Error(`Invalid returnType option: ${o}`))}}catch(m){f(m)}})}var U=D(()=>{"use strict";(async(c=!1)=>{let e=`
|
|
@@ -10,13 +10,13 @@ EXCLUDE EXCLUDE EXCLUDE
|
|
|
10
10
|
react-app.yml
|
|
11
11
|
RegExp("node-app.yml$")
|
|
12
12
|
|
|
13
|
-
`;if(c){let t=y.resolve("src/classes/svhost-nginx/sample/data"),s=await M(t,{recursive:!0,returnType:"relative",forwardSlashes:!0,filesOnly:!1,quiet:!1,ignorefile:{data:e}});console.log("Directory contents:",s)}})(!1)});function te(c){let e=c?.date||new Date;switch(c?.format||"standard"){case"email":{let t={timeZone:"Asia/Kolkata",year:"numeric",month:"short",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1,timeZoneName:"longOffset"};return new Intl.DateTimeFormat("en-IN",t).format(e)}case"standard":{let t=e.getFullYear(),s=String(e.getMonth()+1).padStart(2,"0"),o=String(e.getDate()).padStart(2,"0"),n=String(e.getHours()).padStart(2,"0"),a=String(e.getMinutes()).padStart(2,"0"),i=String(e.getSeconds()).padStart(2,"0");return`${t}-${s}-${o} ${n}:${a}:${i}`}}}var re=D(()=>{"use strict"});import{load as pe}from"js-yaml";import{readFile as fe,stat as de}from"fs/promises";import{resolve as ue}from"path";var C,se=D(()=>{"use strict";C=class{constructor(){}async _readFile(e){if(!e||typeof e!="string")throw new TypeError("Path must be a non-empty string");let r=ue(e);if(!(await de(r)).isFile())throw new Error(`Not a readable file: ${r}`);try{return await fe(r,{encoding:"utf8"})}catch(s){let o=s;throw o.code==="EACCES"||o.code==="EPERM"?new Error(`No read permission for file: ${r}`,{cause:o}):new Error(`Error reading file: ${r}`,{cause:o})}}_resolveVars(e,r){return JSON.parse(JSON.stringify(e),(t,s)=>typeof s=="string"?s.replace(/\$\{(\w+)\}/g,(o,n)=>String(r[n])):s)}async read(e){let r=await this._readFile(e),t=pe(r);return this._resolveVars(t,t?.vars)}}});var w,
|
|
14
|
-
`):t}}});var _,X=D(()=>{"use strict";N();
|
|
13
|
+
`;if(c){let t=y.resolve("src/classes/svhost-nginx/sample/data"),s=await M(t,{recursive:!0,returnType:"relative",forwardSlashes:!0,filesOnly:!1,quiet:!1,ignorefile:{data:e}});console.log("Directory contents:",s)}})(!1)});function te(c){let e=c?.date||new Date;switch(c?.format||"standard"){case"email":{let t={timeZone:"Asia/Kolkata",year:"numeric",month:"short",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1,timeZoneName:"longOffset"};return new Intl.DateTimeFormat("en-IN",t).format(e)}case"standard":{let t=e.getFullYear(),s=String(e.getMonth()+1).padStart(2,"0"),o=String(e.getDate()).padStart(2,"0"),n=String(e.getHours()).padStart(2,"0"),a=String(e.getMinutes()).padStart(2,"0"),i=String(e.getSeconds()).padStart(2,"0");return`${t}-${s}-${o} ${n}:${a}:${i}`}}}var re=D(()=>{"use strict"});import{load as pe}from"js-yaml";import{readFile as fe,stat as de}from"fs/promises";import{resolve as ue}from"path";var C,se=D(()=>{"use strict";C=class{constructor(){}async _readFile(e){if(!e||typeof e!="string")throw new TypeError("Path must be a non-empty string");let r=ue(e);if(!(await de(r)).isFile())throw new Error(`Not a readable file: ${r}`);try{return await fe(r,{encoding:"utf8"})}catch(s){let o=s;throw o.code==="EACCES"||o.code==="EPERM"?new Error(`No read permission for file: ${r}`,{cause:o}):new Error(`Error reading file: ${r}`,{cause:o})}}_resolveVars(e,r){return JSON.parse(JSON.stringify(e),(t,s)=>typeof s=="string"?s.replace(/\$\{(\w+)\}/g,(o,n)=>String(r[n])):s)}async read(e){let r=await this._readFile(e),t=pe(r);return this._resolveVars(t,t?.vars)}}});var w,k=D(()=>{"use strict";N();w=class{constructor(e){this.order=10;this.items=[];R({location:e}),this.location=e}setItem(e=""){Array.isArray(e)?this.items.push(...e):this.items.push(e)}setOrder(e){this.order=e}getData(e){let{joinArray:r=!1}=e||{},t=[];return t.push(`location ${this.location} {`),t.push(...b(this.items)),t.push("}"),r?t.join(`
|
|
14
|
+
`):t}}});var _,X=D(()=>{"use strict";N();k();_=class{constructor(e){let{host:r="localhost",port:t,location:s="/",hostUri:o="/",headers:n=new Map,resetHeader:a=!1}=e;if(R({port:t},{message:i=>`"${i}" is required in ReverseProxy constructor.`}),this.host=r,this.port=t,this.location=s,this.hostUri=o,this.resetHeader=a,!(n instanceof Map))throw new Error('"headers" must be a Map');this.headers=new Map,this.headerArgs=n,this.setDefaultHeaders()}setHost(e){this.host=e}setPort(e){this.port=e}setResetHeader(e){this.resetHeader=e,this.setDefaultHeaders()}setHeader(e,r){this.headers.set(e,r)}deleteHeader(e){this.headers.delete(e)}getHeader(e){return this.headers.get(e)}getHeaders(){return new Map(this.headers)}getHeadersList(){let e=[];for(let[r,t]of this.headers.entries())e.push(`${r} ${t};`);return e}setDefaultHeaders(e){let r=e?.reset||!1;this.headers.clear();let t=new Map;t.set("proxy_pass",`http://${this.host}:${this.port}${this.hostUri}`),r||(this.resetHeader||(t.set("proxy_set_header Host","$host"),t.set("proxy_set_header X-Real-IP","$remote_addr"),t.set("proxy_set_header X-Forwarded-Host","$http_host"),t.set("proxy_set_header X-Forwarded-Proto","$scheme"),t.set("proxy_set_header X-Forwarded-For","$proxy_add_x_forwarded_for"),t.set("proxy_cache_bypass","$http_upgrade"),t.set("proxy_http_version","1.1"),t.set("proxy_set_header Upgrade","$http_upgrade"),t.set("proxy_set_header Connection","upgrade")),this.headers=new Map([...t,...this.headerArgs]))}getData(e={}){let{joinArray:r=!1}=e,t=this.getHeadersList(),s=new w(this.location);return s.setItem(t),s.getData({joinArray:r})}}});var I,oe=D(()=>{"use strict";N();k();I=class{constructor(){this.serverItems=[];this.sslItems=[];this.locationBlocks=[];this.redirectItems=[]}addServerItem(e){Array.isArray(e)?this.serverItems.push(...e):this.serverItems.push(e)}addSslItem(e){Array.isArray(e)?this.sslItems.push(...e):this.sslItems.push(e)}addLocationBlock(e=null){e&&e instanceof w&&this.locationBlocks.push(e)}addRedirectItem(e){Array.isArray(e)?this.redirectItems.push(...e):this.redirectItems.push(e)}getData(e={}){let{joinArray:r=!1}=e,t=[];if(t.push("server {"),t.push(...b(this.serverItems)),this.sslItems?.length&&(t.push(`
|
|
15
15
|
`),this.sslItems.forEach(s=>{t.push(b(s))})),this.redirectItems?.length)t.push(`
|
|
16
16
|
`),this.redirectItems.forEach(s=>{t.push(b(s))});else if(this.locationBlocks?.length){let s=this.locationBlocks.toSorted((o,n)=>o.order-n.order);t.push(""),s.forEach(o=>{t.push(""),t.push(...b(o.getData()))})}return t.push("}"),r?t.join(`
|
|
17
|
-
`):t}}});var W,ie=D(()=>{"use strict";N();
|
|
18
|
-
`):l})({joinArray:r})}}});import E from"path";import{copyFile as ge,mkdir as me,readdir as ye,rm as ve,writeFile as ne}from"fs/promises";var V,G=D(()=>{"use strict";U();q();re();se();ie();X();V=class{constructor(e){this.helper=new L(this)}async yamlToVhostInstances(e,r){let{quiet:t=!1}=r||{};try{let o=await new C().read(e),n=o?.vhosts||[],a=o?.meta||{};t||(console.log(`YAML Config Data : -------- Total VHosts in file "${e}":`,n.length),console.log("VHosts Default Meta:",{defaultMeta:a}));for(let h of n)t||(console.log("VHost Data:",h),console.log("VHost reverseProxies:",h?.reverseProxies));let i=[];return n.forEach(h=>{let l=structuredClone(h);l.meta={...a,...l.meta??{}},delete l.reverseProxies,console.log(
|
|
17
|
+
`):t}}});var W,ie=D(()=>{"use strict";N();k();X();oe();W=class{constructor(e){let{id:r,domainName:t="",tld:s="com",serverNames:o=[],redirectToFirstServer:n=!0,appType:a="reverseProxy",reverseProxies:i=new Map,ssl:h=!1,sslCertificateName:l,redirectToHttps:f=!1,rootDirectory:p="/var/www/html",http_port:m=80,https_port:g="443 ssl",meta:F}=e||{};if(R({id:r,domainName:t,tld:s,serverNames:o,rootDirectory:p,appType:a,http_port:m,https_port:g},{noEmptyArray:!0,noEmptyObject:!0}),this.reverseProxies=i,!Array.isArray(o)||o.length===0)throw new Error('"serverNames" must be a non-empty array of server-names');this.id=r,this.domainName=t,this.tld=s,this.serverNames=o,this.redirectToFirstServer=n,this.appType=a,this.ssl=h,this.sslCertificateName=l??`${t}.${s}`,this.redirectToHttps=f,this.rootDirectory=p,this.http_port=m,this.https_port=g,this.meta=F??{},this.meta.group=this.meta?.group??"default"}setReverseProxy(e){if(e instanceof _&&e?.location){if(this.reverseProxies)this.reverseProxies.set(e?.location,e);else{let r=`Error: Server ID: ${this.id} - reverseProxies Map is not initialized.`;throw console.error(r),new Error(r)}return}console.warn("Error: Server ID: ${this.id} - Invalid reverseProxy passed",JSON.stringify(e))}getLocationBlocks(){let e=[];if(this.reverseProxies?.size&&this.reverseProxies instanceof Map)this.reverseProxies?.forEach(r=>{let t=new w(r.location);t.setItem(r.getHeadersList()),e.push(t)});else{let r=new w("/");r.setItem("try_files $uri $uri/ =404;"),e.push(r)}return e}createServerBlock(e={}){let{joinArray:r=!1,serverDirectives:t=[],addSslCertificates:s=!1,redirects:o=[],locationBlocks:n=[]}=e,a=new I;if(t?.length&&t.forEach(i=>{a.addServerItem(i)}),s){let i=[];if(this.ssl===void 0)throw new Error(`Please provide/set valid value for "this.ssl" in 'Vhost' constructor, if you want to redirect to HTTPS`);if(this.ssl===!0)a.addSslItem([`ssl_certificate /etc/letsencrypt/live/${this.sslCertificateName}/fullchain.pem;`,`ssl_certificate_key /etc/letsencrypt/live/${this.sslCertificateName}/privkey.pem;`,...i]);else if(this.ssl!==!1)if(typeof this.ssl=="object")a.addSslItem([`ssl_certificate ${this.ssl?.crt};`,`ssl_certificate_key ${this.ssl?.key};`,...i]);else throw new Error("Something Went Wrong in SSL Directives.")}if(o?.length)a.addRedirectItem(o);else{let h=[...this.getLocationBlocks(),...n].sort((l,f)=>l?.order-f?.order);h?.length&&h.forEach(l=>{a.addLocationBlock(l)})}return a.getData({joinArray:r})}getIndexDirective(){let e="index index.html index.htm";switch(this.appType){case"reverseProxy":return`${e};`;case"html":return`${e};`;case"react":return`${e};`;case"node":return`${e};`;case"react-node":return`${e};`;case"php":return`index.php ${e};`;case"python":return`index.py ${e};`;default:return`${e}; # Default`}}getServerDirectives(e={}){let{serverNames:r,redirect:t=!1,port:s=this.http_port}=e,o=[`listen ${s};`,`listen [::]:${s};`,"",`server_name ${r?.join(" ")};`];return t||o.push("",this.getIndexDirective(),`root ${this.rootDirectory};`),o}_generateFullServerBlock(e){let{redirectHttps:r=!1,redirectWWW:t=!1,port:s,onlyFirstServerName:o=!1}=e||{},n=[];if(r||t){let h=r||s===this.https_port?"s":"",l=t?this.serverNames?.[0]:"$host";n.push(`return 301 http${h}://${l}$request_uri;`)}let a=t?this.serverNames?.slice(1):this.serverNames;return this.createServerBlock({serverDirectives:this.getServerDirectives({serverNames:o?[a?.[0]]:a,port:s,redirect:r||t}),addSslCertificates:!!(this.ssl&&s===this.https_port),redirects:n?.length?n:void 0})}getData(e){let{joinArray:r=!1}=e??{},t=[],s=this.serverNames,o=this.redirectToFirstServer&&this.serverNames?.length>1?this.serverNames?.[0]:"";return this.redirectToHttps?o?(t.push(this._generateFullServerBlock({port:this.http_port,redirectHttps:!0,redirectWWW:!0})),t.push(this._generateFullServerBlock({port:this.https_port,redirectHttps:!0,redirectWWW:!0})),t.push(this._generateFullServerBlock({port:this.http_port,redirectHttps:!0,redirectWWW:!1,onlyFirstServerName:!0})),t.push(this._generateFullServerBlock({port:this.https_port,redirectHttps:!1,redirectWWW:!1,onlyFirstServerName:!0}))):(t.push(this._generateFullServerBlock({port:this.http_port,redirectHttps:!0,redirectWWW:!1})),t.push(this._generateFullServerBlock({port:this.https_port,redirectHttps:!1,redirectWWW:!1}))):o?(t.push(this._generateFullServerBlock({port:this.http_port,redirectHttps:!1,redirectWWW:!0})),t.push(this._generateFullServerBlock({port:this.https_port,redirectHttps:!1,redirectWWW:!0})),t.push(this._generateFullServerBlock({port:this.http_port,redirectHttps:!1,redirectWWW:!1,onlyFirstServerName:!0})),t.push(this._generateFullServerBlock({port:this.https_port,redirectHttps:!1,redirectWWW:!1,onlyFirstServerName:!0}))):(t.push(this._generateFullServerBlock({port:this.http_port,redirectHttps:!1,redirectWWW:!1})),this.ssl&&t.push(this._generateFullServerBlock({port:this.https_port,redirectHttps:!1,redirectWWW:!1}))),((i={})=>{let{joinArray:h=!1}=i,l=[];return t?.map((f,p)=>{l.push(...f),p+1<t?.length&&l.push("")}),h?l?.join(`
|
|
18
|
+
`):l})({joinArray:r})}}});import E from"path";import{copyFile as ge,mkdir as me,readdir as ye,rm as ve,writeFile as ne}from"fs/promises";var V,G=D(()=>{"use strict";U();q();re();se();ie();X();V=class{constructor(e){this.helper=new L(this)}async yamlToVhostInstances(e,r){let{quiet:t=!1}=r||{};try{let o=await new C().read(e),n=o?.vhosts||[],a=o?.meta||{};t||(console.log(`YAML Config Data : -------- Total VHosts in file "${e}":`,n.length),console.log("VHosts Default Meta:",{defaultMeta:a}));for(let h of n)t||(console.log("VHost Data:",h),console.log("VHost reverseProxies:",h?.reverseProxies));let i=[];return n.forEach(h=>{let l=structuredClone(h);l.meta={...a,...l.meta??{}},delete l.reverseProxies,t||console.log("New VHost Data (without reverseProxies):",l);let f=new W(l);i.push(f),t||(console.log("Processing VHost:",f.id),console.log("vhostData?.reverseProxies:",h?.reverseProxies)),[...h?.reverseProxies??[]].forEach(p=>{let[[m,g]]=Object.entries(p??{});t||console.log("Reverse Proxy Data:",{pathKey:m,proxyConfig:g}),g.location=m;let F=new _(g);f.setReverseProxy(F)})}),t||console.log(`Loaded (${i.length}) vhost(s) from YAML file: "${e}"`),i}catch(s){throw new Error(`Error reading YAML file "${e}": ${s?.message}`,{cause:s})}}async getVhostInstanceArray(e,r){let{quiet:t=!1}=r||{};try{return A(e)?await this.yamlToVhostInstances(e,{quiet:t}):(t||console.warn(`The path "${e}" is not a valid file.`),null)}catch(s){throw console.error("-----------------------------------"),console.error(`Error Message: ${s?.message}`),console.error("----------------- Complete Error ------------------"),console.error(s),console.error("-----------------------------------"),new Error(`YAML File Error, while importing "${e}": ${s?.message}`)}}async getVhostInstances(e,r){let{quiet:t=!1}=r||{};try{let s=await M(e,{recursive:!0,filesOnly:!0,returnType:"relative",forwardSlashes:!0,quiet:t});t||(console.log(4444,{quiet:t},{files:s}),console.log(s));let o=[];for(let n of s)if(n.endsWith(".yml")||n.endsWith(".yaml")){let a=E.resolve(e,n),i=await this.getVhostInstanceArray(a,{quiet:t});i?.length&&o.push(...i)}return o}catch(s){throw new Error(`Error in "getVhostInstances()" from directory "${e}": Error:"${s.message}"`,{cause:s})}}async ensureDir(e,r){let{quiet:t=!1,directoryName:s="Output"}=r||{};if(!await S(e))if(await S(E.dirname(e)))t||console.log(`## ${s} directory does not exist. Creating directory: "${e}"`),await me(e,{recursive:!0});else throw new Error(`## ${s} directory does not exist: ${e}`)}getVhostConfigFileData(e,r){let{joinArray:t=!1}=r||{},s=e.getData()??[],o=e.reverseProxies?.size?[...e.reverseProxies].map(([a,i])=>`${a} => ${i?.host}:${i?.port}${i?.hostUri}`).join(", "):"",n=[`# Created at: ${te()}`,`# ID: ${e.id}`,`# HOST (s): ${o}`,`# GROUP: ${e?.meta?.group}`,"###################################",`
|
|
19
19
|
|
|
20
20
|
`,...s];return t?n.join(`
|
|
21
|
-
`):n}async generateVhostConfig(e){let{vhosts:r,destDir:t,quiet:s=!1}=e;await this.ensureDir(t,{quiet:s,directoryName:"Destination"});for(let o of r){let n=this.getVhostConfigFileData(o,{joinArray:!0}),a=o?.meta?.confFileName??`${o?.meta?.group}--${o.id}.conf`,i=E.resolve(t,a);console.log(`Generating vhost config file: "${i}" ...`,n);try{await ne(i,n)}catch(h){throw new Error(`Error writing vhost config file "${i}": ${h?.message}`,{cause:h})}}}async generate(e){let{file:r,srcDir:t,outputDir:s,quiet:o=!1,cleanDir:n=!1,createEmptyFile:a=!1,nginxConfFile:i,subConfdDir:h=!0}=e;try{if(!r&&!t)throw new Error('Either "file" or "srcDir" must be provided.');if(r&&!await A(r))throw new Error(`The specified file does not exist: ${r}`);if(t&&!await S(t))throw new Error(`The specified source directory does not exist: ${t}`);await this.ensureDir(s,{quiet:o,directoryName:"output"}),h&&await this.ensureDir(E.resolve(s,"conf.d"),{quiet:o,directoryName:"output/conf.d"});let l=[];if(o||console.log(1111,{file:r,srcDir:t}),r){let p=await this.getVhostInstanceArray(r,{quiet:o});p?.length&&l.push(...p)}if(t){let p=await this.getVhostInstances(t,{quiet:o});o||(console.log({"vhostInstances Count":p.length}),console.log(3333,p)),l.push(...p)}if(n){let p=(await ye(s)).map(m=>E.resolve(s,m));await Promise.all(p.map(m=>ve(m,{recursive:!0,force:!0})))}if(a&&await ne(E.resolve(s,".empty"),""),i){let p=E.resolve(i);await
|
|
22
|
-
//# sourceMappingURL=chunk-
|
|
21
|
+
`):n}async generateVhostConfig(e){let{vhosts:r,destDir:t,quiet:s=!1}=e;await this.ensureDir(t,{quiet:s,directoryName:"Destination"});for(let o of r){let n=this.getVhostConfigFileData(o,{joinArray:!0}),a=o?.meta?.confFileName??`${o?.meta?.group}--${o.id}.conf`,i=E.resolve(t,a);s||console.log(`Generating vhost config file: "${i}" ...`,n);try{await ne(i,n)}catch(h){throw new Error(`Error writing vhost config file "${i}": ${h?.message}`,{cause:h})}}}async generate(e){let{file:r,srcDir:t,outputDir:s,quiet:o=!1,cleanDir:n=!1,createEmptyFile:a=!1,nginxConfFile:i,subConfdDir:h=!0}=e;try{if(!r&&!t)throw new Error('Either "file" or "srcDir" must be provided.');if(r&&!await A(r))throw new Error(`The specified file does not exist: ${r}`);if(t&&!await S(t))throw new Error(`The specified source directory does not exist: ${t}`);await this.ensureDir(s,{quiet:o,directoryName:"output"}),h&&await this.ensureDir(E.resolve(s,"conf.d"),{quiet:o,directoryName:"output/conf.d"});let l=[];if(o||console.log(1111,{file:r,srcDir:t}),r){let p=await this.getVhostInstanceArray(r,{quiet:o});p?.length&&l.push(...p)}if(t){let p=await this.getVhostInstances(t,{quiet:o});o||(console.log({"vhostInstances Count":p.length}),console.log(3333,p)),l.push(...p)}if(n){let p=(await ye(s)).map(m=>E.resolve(s,m));await Promise.all(p.map(m=>ve(m,{recursive:!0,force:!0})))}if(a&&await ne(E.resolve(s,".empty"),""),i){let p=E.resolve(i);await H(p)&&await ge(p,E.resolve(s,"nginx.conf"))}let f=h?E.resolve(s,"conf.d"):s;o||(console.log(`Total vhosts to generate: ${l.length} . Output Directory: "${s}"`),console.log({subConfdDir:h}),console.log(`conf.d Directory: "${f}"`)),await this.generateVhostConfig({vhosts:l,destDir:f,quiet:o}),o||console.log(`Generated (${l.length}) vhost configuration file(s) in "${s}".`)}catch(l){throw new Error(`Error in generate method: "${l.message}"`,{cause:l})}}}});import{Command as xe}from"commander";import K from"path";var ae,le=D(()=>{"use strict";N();U();G();ae=class extends ee{constructor(){super();this.quiet=!0}setupCommand(){let r=new xe;return r.name("svhost-nginx").description("Nginx - Simple Virtual Host").version("1.0.0"),r.description("Generate Nginx configuration for a virtual host").option("-f, --src-file <srcFile>","Source file for configuration").option("--src-dir <srcDir>","Source directory for configuration").requiredOption("-d, --dest-dir <destDir>","Destination directory for configuration").action(this.actionDefault.bind(this)),r.parseAsync(process.argv)}async run(r){let{quiet:t=!0}=r||{};this.quiet=t,await this.setupCommand()}async actionDefault(r,t,s){let{srcFile:o,srcDir:n,destDir:a}=r;if(this.quiet||console.log("Commander:",{name:r,command:s}),o&&n)throw new Error("Please provide either --src-file or --src-dir, not both.");if(!o&&!n)throw new Error("Please provide either --src-file or --src-dir.");let i=K.resolve(o||""),h=K.resolve(n||""),l=K.resolve(a);if(this.quiet||console.table({"Source File":i,"Source Directory":h,"Destination Directory":l}),o&&!await A(o))throw new Error(`Source file does not exist: "${o}"`);if(n&&!await S(n))throw new Error(`Source directory does not exist: "${n}"`);console.log("Generating Nginx configuration ...");let f=new V;o?await f.generate({file:i,outputDir:l,quiet:this.quiet,cleanDir:!0}):n&&await f.generate({srcDir:h,outputDir:l,quiet:this.quiet,cleanDir:!0}),this.quiet||(console.log("option1 action executed"),console.log("Name:",r,typeof r))}}});var De=D(()=>{"use strict";G();le();q()});export{L as a,q as b,k as c,X as d,oe as e,ie as f,V as g,G as h,ae as i,le as j,De as k};
|
|
22
|
+
//# sourceMappingURL=chunk-QFX4LT7J.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/classes/svhost-nginx/SvhostNginxHelper.ts","../src/lib/utils/fs-extra.ts","../src/lib/utils/datetime.ts","../src/lib/utils/js-yaml.ts","../src/classes/vhost/LocationBlock.ts","../src/classes/vhost/ReverseProxy.ts","../src/classes/vhost/ServerBlock.ts","../src/classes/vhost/Vhost.ts","../src/classes/svhost-nginx/SvhostNginx.ts","../src/classes/svhost-nginx/SvhostNginxCli.ts","../src/commands/svhost-nginx/index.ts"],"sourcesContent":["import { SvhostNginx } from './SvhostNginx';\n\nexport class SvhostNginxHelper {\n private svhostNginx: SvhostNginx;\n constructor(svhostNginx: SvhostNginx) {\n this.svhostNginx = svhostNginx;\n }\n}\n","import { Dirent } from 'fs';\nimport fs from 'fs-extra';\nimport { constants, readdir } from 'fs/promises';\n// import { console } from 'inspector';\nimport path from 'path';\n\nexport async function exists(path: string): Promise<boolean> {\n try {\n return await fs.exists(path);\n } catch {\n return false;\n }\n}\n\nexport async function isFile(path: string): Promise<boolean> {\n try {\n return (await fs.stat(path)).isFile();\n } catch {\n return false;\n }\n}\n\nexport async function isDir(path: string): Promise<boolean> {\n try {\n return (await fs.stat(path)).isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function canRead(path: string): Promise<boolean> {\n try {\n await fs.access(path, constants.R_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function canWrite(path: string): Promise<boolean> {\n try {\n await fs.access(path, constants.W_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function canReadWrite(path: string): Promise<boolean> {\n try {\n await fs.access(path, constants.R_OK | constants.W_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function inspectPath(targetPath: string) {\n try {\n const stats = await fs.stat(targetPath);\n\n const readable = await fs\n .access(targetPath, constants.R_OK)\n .then(() => true)\n .catch(() => false);\n const writable = await fs\n .access(targetPath, constants.W_OK)\n .then(() => true)\n .catch(() => false);\n\n return {\n exists: true,\n isFile: stats.isFile(),\n isDir: stats.isDirectory(),\n canRead: readable,\n canWrite: writable,\n canReadWrite: readable && writable,\n };\n } catch {\n // path does not exist\n const dir = path.dirname(targetPath);\n const canWriteParent = await fs\n .access(dir, constants.W_OK)\n .then(() => true)\n .catch(() => false);\n\n return {\n exists: false,\n isFile: false,\n isDir: false,\n canRead: false,\n canWrite: canWriteParent,\n canReadWrite: false,\n };\n }\n}\n\n/**\n * Read Directory\n */\nexport enum ReadDirReturnEnum {\n ABSOLUTE = 'absolute',\n RELATIVE = 'relative',\n DIRENT = 'dirent',\n ALL = 'all',\n}\n\nexport type ReadDirReturnType = 'absolute' | 'relative' | 'dirent' | 'all';\n\nexport type ReadDirOptionsBase = {\n recursive?: boolean;\n filesOnly?: boolean;\n dirsOnly?: boolean;\n encoding?: BufferEncoding | null;\n returnType?: ReadDirReturnType; // default = 'absolute'\n forwardSlashes?: boolean;\n ignorefile?: {\n path?: string;\n data?: string;\n };\n quiet?: boolean;\n includeIgnorefile?: boolean;\n};\n\nexport interface ReadDirectoryItem {\n name: string;\n absolutePath: string;\n relativePath: string;\n isFile: boolean;\n isDirectory: boolean;\n}\n\ntype ReadDirResult<T extends ReadDirReturnType> = T extends 'absolute'\n ? string[]\n : T extends 'relative'\n ? string[]\n : T extends 'dirent'\n ? Dirent[]\n : T extends 'all'\n ? ReadDirectoryItem[]\n : [];\n\nexport async function readDirectory<T extends ReadDirReturnType = 'absolute'>(\n dirPath: string,\n options?: ReadDirOptionsBase & { returnType?: ReadDirReturnType },\n): Promise<ReadDirResult<T>> {\n const {\n recursive = false,\n filesOnly = false,\n dirsOnly = false,\n returnType = 'absolute',\n forwardSlashes = false,\n ignorefile,\n quiet = true,\n includeIgnorefile = false,\n // encoding = 'utf8',\n } = options || {};\n return new Promise(async (resolve, reject) => {\n function normalize(path: string): string {\n return forwardSlashes ? path.replace(/\\\\/g, '/') : path; // Normalize Windows paths to use forward slashes\n }\n\n if (!quiet) {\n console.log(`Reading directory: ${dirPath}`, {\n recursive,\n filesOnly,\n dirsOnly,\n returnType,\n forwardSlashes,\n quiet,\n includeIgnorefile,\n ignorefile,\n });\n }\n\n try {\n if (!(await exists(dirPath))) {\n return reject(new Error(`Directory does not exist: ${dirPath}`));\n }\n if (!(await isDir(dirPath))) {\n return reject(new Error(`Path is not a directory: ${dirPath}`));\n }\n\n const files = await readdir(dirPath, { withFileTypes: true, recursive });\n let filteredFiles = files.filter((dirent) => {\n if (\n !includeIgnorefile &&\n dirent.name === '.ignore' &&\n path.resolve(dirPath) === path.resolve(dirent.parentPath)\n // .ignore is handled only at the top level directory\n ) {\n return false;\n }\n if (filesOnly) return dirent.isFile();\n if (dirsOnly) return dirent.isDirectory();\n return true;\n });\n\n /**\n * Handle ignore rules from .ignore file or (ignorefile option)\n */\n if (ignorefile?.data || ignorefile?.path || (await exists(path.join(dirPath, '.ignore')))) {\n if (!quiet) {\n console.log(`Applying ignore rules from: ${ignorefile?.path || 'provided data'}`);\n }\n let ignoreData = '';\n if (ignorefile?.data) {\n ignoreData = ignorefile.data;\n } else if (ignorefile?.path) {\n try {\n ignoreData = await fs.readFile(ignorefile.path, 'utf8');\n } catch (err) {\n if (!quiet) {\n console.warn(\n `Warning: Could not read ignorefile at ${ignorefile.path}: ${(err as Error).message}`,\n );\n }\n }\n } else {\n // Read from .ignore in dirPath\n try {\n ignoreData = await fs.readFile(path.join(dirPath, '.ignore'), 'utf8');\n } catch (err) {\n if (!quiet) {\n console.warn(\n `Warning: Could not read ignorefile at ${path.join(dirPath, '.ignore')}: ${\n (err as Error).message\n }`,\n );\n }\n }\n }\n\n if (ignoreData) {\n if (!quiet) {\n console.log('All .ignore data:\\n------------------------');\n console.log(ignoreData);\n console.log('------------------------');\n }\n let excludeData = '';\n let includeData = '';\n const extractLines = (data: string) => {\n const lines = data\n ?.replace(/(([ \\t]*)#.*$)/gm, '') // Remove comments\n ?.replace(/^([ \\t])*|([ \\t])*$/gm, '') // Trim lines\n ?.split(/\\r?\\n/)\n ?.filter((v) => v.length);\n\n return lines;\n };\n\n const matchRegExp = (line: string) => {\n return line.match(\n /RegExp[ \\s]*\\([ \\s]*['\"`](?<regex>.*)['\"`][ \\s]*,[ \\s]*['\"`](?<flags>.*)['\"`][ \\s]*\\)|RegExp[ \\s]*\\([ \\s]*['\"`](?<regex>.*)['\"`][ \\s]*\\)/m,\n );\n };\n\n const applyIgnoreRules = (filterLines: Dirent[], rules: string[], includeMatched: boolean) => {\n return filterLines.filter((dirent) => {\n const relativePath = normalize(\n path.relative(dirPath, path.resolve(dirent.parentPath, dirent.name)),\n );\n for (const rule of rules) {\n const checkIsRegExp = matchRegExp(rule);\n if (relativePath) {\n if (checkIsRegExp) {\n const regex = checkIsRegExp?.groups?.regex || '';\n const flags = checkIsRegExp?.groups?.flags || 'm';\n if (relativePath?.match(new RegExp(regex, flags))) {\n if (includeMatched) {\n if (!quiet) {\n console.log(\n `Included path \"${relativePath}\" \\t\\t via Regex(\"${regex}\",\"${flags}\") Match pattern.`,\n );\n }\n return true;\n } else {\n if (!quiet) {\n console.log(\n `Ignored path \"${relativePath}\" \\t\\t via Regex(\"${regex}\",\"${flags}\") Match pattern.`,\n );\n }\n return false;\n }\n }\n }\n const match = relativePath?.match(new RegExp(`^${rule}$`, 'gm'));\n if (match) {\n if (includeMatched) {\n if (!quiet) {\n console.log(`Included path \"${relativePath}\" \\t\\t via Match pattern.`);\n }\n return true;\n } else {\n if (!quiet) {\n console.log(`Ignored path \"${relativePath}\" \\t\\t via Match pattern.`);\n }\n return false;\n }\n }\n }\n }\n // return true;\n return includeMatched ? false : true;\n });\n };\n\n // Look for `EXCLUDE EXCLUDE EXCLUDE`\n const excludeLineExists = ignoreData.match(/^[ \\t]*#?[ \\t]*EXCLUDE EXCLUDE EXCLUDE[ \\t]*$/gm);\n if (excludeLineExists) {\n const excludeLineCommented = ignoreData.match(/^[ \\t]*#[ \\t]*EXCLUDE EXCLUDE EXCLUDE[ \\t]*$/gm);\n if (excludeLineCommented) {\n excludeData = ignoreData.replace(/^[ \\t]*#[ \\t]*EXCLUDE EXCLUDE EXCLUDE[ \\t]*.*/gms, '');\n } else {\n includeData = ignoreData.replace(/.*[ \\t]*EXCLUDE EXCLUDE EXCLUDE[ \\t]*$/gms, '');\n }\n }\n if (!quiet) {\n console.log('Include data:\\n------------------------');\n console.log(includeData);\n console.log('------------------------');\n console.log('Exclude data - EXCLUDE EXCLUDE EXCLUDE:\\n------------------------');\n console.log(excludeData);\n console.log('------------------------');\n }\n\n console.log('Applying exclude and include rules from .ignore file');\n console.log('Initial file count before applying ignore rules:', filteredFiles.length);\n if (excludeData) {\n const excludeLines = extractLines(excludeData);\n if (!quiet) {\n console.log('Exclude lines:', excludeLines);\n }\n filteredFiles = applyIgnoreRules(filteredFiles, excludeLines, false);\n }\n if (includeData) {\n const includeLines = extractLines(includeData);\n if (!quiet) {\n console.log('Include lines:', includeLines);\n }\n filteredFiles = applyIgnoreRules(filteredFiles, includeLines, true);\n }\n console.log('Final file count after applying ignore rules:', filteredFiles.length);\n }\n }\n\n const baseDir = path.resolve(dirPath);\n\n switch (returnType) {\n case ReadDirReturnEnum.ABSOLUTE: {\n const filePaths = filteredFiles.map((dirent) => {\n const absPath = path.join(dirent.parentPath, dirent.name);\n return normalize(absPath);\n });\n return resolve(filePaths as ReadDirResult<T>);\n }\n\n case ReadDirReturnEnum.RELATIVE: {\n const filePaths = filteredFiles.map((dirent) => {\n const absPath = path.join(dirent.parentPath, dirent.name);\n return normalize(path.relative(baseDir, absPath));\n });\n return resolve(filePaths as ReadDirResult<T>);\n }\n case ReadDirReturnEnum.DIRENT: {\n return resolve(filteredFiles as ReadDirResult<T>);\n }\n case ReadDirReturnEnum.ALL: {\n const filePaths = filteredFiles.map((dirent) => {\n const absPath = path.join(dirent.parentPath, dirent.name);\n return {\n name: dirent.name,\n absolutePath: normalize(absPath),\n relativePath: normalize(path.relative(baseDir, absPath)),\n isFile: dirent.isFile(),\n isDirectory: dirent.isDirectory(),\n };\n });\n return resolve(filePaths as ReadDirResult<T>);\n }\n default: {\n return reject(new Error(`Invalid returnType option: ${returnType}`));\n }\n }\n } catch (err) {\n reject(err);\n }\n });\n}\n\n////////////////////////////////////////\n\n/**\n * Commands to run this file directly for testing purposes\n *\n * npx ts-node src/lib/utils/fs-extra.ts\n *\n *\n * Expamples:\n */\n\n(async (run = false) => {\n const ignoreFileData = `\n# Ignore files and directories\n\ndir1\n\nEXCLUDE EXCLUDE EXCLUDE\nreact-app.yml\nRegExp(\"node-app.yml$\")\n\n`;\n if (run) {\n const testPath = 'src/classes/svhost-nginx/sample/data';\n const testFullPath = path.resolve(testPath);\n const dirContents = await readDirectory(testFullPath, {\n recursive: true,\n returnType: 'relative',\n forwardSlashes: true,\n filesOnly: false,\n quiet: false,\n ignorefile: {\n data: ignoreFileData,\n // path: path.resolve('src/lib/utils/.ignore'),\n },\n });\n console.log('Directory contents:', dirContents);\n }\n})(false);\n","export function getFullDateTime(options?: { date?: Date; format?: 'email' | 'standard' }): string {\r\n // Get the current date and time\r\n const now = options?.date || new Date();\r\n const format = options?.format || 'standard';\r\n\r\n switch (format) {\r\n case 'email': {\r\n // Create an options object for formatting\r\n const dateOptions: Intl.DateTimeFormatOptions = {\r\n timeZone: 'Asia/Kolkata',\r\n year: 'numeric',\r\n month: 'short',\r\n day: '2-digit',\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n second: '2-digit',\r\n hour12: false, // Use 24-hour format\r\n timeZoneName: 'longOffset',\r\n };\r\n\r\n // Format the date and time for IST\r\n const formatter = new Intl.DateTimeFormat('en-IN', dateOptions);\r\n const istTime = formatter.format(now);\r\n return istTime;\r\n // console.log(\"Current time in IST:\", istTime);\r\n }\r\n case 'standard': {\r\n const year = now.getFullYear();\r\n const month = String(now.getMonth() + 1).padStart(2, '0');\r\n const day = String(now.getDate()).padStart(2, '0');\r\n const hours = String(now.getHours()).padStart(2, '0');\r\n const minutes = String(now.getMinutes()).padStart(2, '0');\r\n const seconds = String(now.getSeconds()).padStart(2, '0');\r\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;\r\n }\r\n }\r\n}\r\n\r\n// console.log(getFullDateTime({ format: 'email' }));\r\n// console.log(getFullDateTime());\r\n","import { load } from 'js-yaml';\r\nimport { readFile as fsReadFile, stat } from 'node:fs/promises';\r\nimport { resolve } from 'node:path';\r\nimport Ajv, { Options } from 'ajv';\r\n\r\nexport default class JsYaml {\r\n constructor() {}\r\n\r\n async _readFile(path: string): Promise<string> {\r\n if (!path || typeof path !== 'string') {\r\n throw new TypeError('Path must be a non-empty string');\r\n }\r\n\r\n const resolvedPath = resolve(path);\r\n const stats = await stat(resolvedPath);\r\n\r\n if (!stats.isFile()) {\r\n throw new Error(`Not a readable file: ${resolvedPath}`);\r\n }\r\n\r\n try {\r\n return await fsReadFile(resolvedPath, { encoding: 'utf8' });\r\n } catch (error) {\r\n const err = error as NodeJS.ErrnoException;\r\n\r\n if (err.code === 'EACCES' || err.code === 'EPERM') {\r\n throw new Error(`No read permission for file: ${resolvedPath}`, { cause: err });\r\n }\r\n throw new Error(`Error reading file: ${resolvedPath}`, { cause: err });\r\n }\r\n }\r\n\r\n _resolveVars(obj: any, vars: Record<string, string | number>) {\r\n return JSON.parse(JSON.stringify(obj), (_, v) =>\r\n typeof v === 'string' ? v.replace(/\\$\\{(\\w+)\\}/g, (_, k) => String(vars[k])) : v,\r\n );\r\n }\r\n\r\n async read(path: string): Promise<any> {\r\n const content = await this._readFile(path);\r\n const data = load(content) as any;\r\n return this._resolveVars(data, data?.vars);\r\n }\r\n\r\n /**\r\n * Load config and validate against schema from URL\r\n */\r\n /**\r\n * Note: This method is not implemented correctly.\r\n */\r\n // async validate<TData = VHostConfig>(options: {\r\n // configPath?: string;\r\n // schemaUrl: string;\r\n // data?: TData;\r\n // options?: Options;\r\n // }): Promise<TData>;\r\n // async validate<TData = VHostConfig>(options: {\r\n // configPath: string;\r\n // schemaUrl?: string;\r\n // data?: TData;\r\n // options?: Options;\r\n // }): Promise<TData>;\r\n // async validate<TData = VHostConfig>(options: {\r\n // configPath?: string;\r\n // schemaUrl?: string;\r\n // data?: TData;\r\n // options?: Options;\r\n // }): Promise<TData> {\r\n // try {\r\n // const { configPath, schemaUrl, options: ajvOptions = {}, data } = options;\r\n // let schema: unknown = {};\r\n // if (schemaUrl) {\r\n // const res = await fetch(schemaUrl);\r\n // if (!res.ok) throw new Error(`Failed to fetch ${schemaUrl}: ${res.status}`);\r\n // const text = await res.text();\r\n // schema = await load(text);\r\n // } else if (configPath) {\r\n // const content = await fsReadFile(configPath, 'utf8');\r\n // schema = await load(content);\r\n // } else {\r\n // throw new Error('Either schemaUrl or configPath must be provided');\r\n // }\r\n\r\n // /**\r\n // * Validate config\r\n // */\r\n // console.log(1111111111111, schema);\r\n\r\n // const ajv = new Ajv({ allErrors: true, strict: true, useDefaults: true, ...ajvOptions });\r\n // console.log(22222222222, ajv);\r\n\r\n // const validate = ajv.compile(schema as object);\r\n // console.log(33333333333, validate);\r\n\r\n // return validate as TData;\r\n // // return function validate(data: T) {\r\n // // return validate(data);\r\n // // };\r\n\r\n // // if (!validate(schema)) {\r\n // // throw new Error('Config validation failed:\\n' + ajv.errorsText(validate.errors, { separator: '\\n' }));\r\n // // }\r\n\r\n // // return rawConfig as T;\r\n // } catch (error) {\r\n // throw new Error(`Error loading config: ${(error as Error).message}`, { cause: error });\r\n // }\r\n // }\r\n}\r\n","import { indent, validateRequired } from '../../lib';\n\n/**\n * Helper class to create Nginx Location Blocks\n */\n\nexport default class LocationBlock {\n location;\n order = 10;\n items: string[] = [];\n\n constructor(location: string) {\n validateRequired({\n location,\n });\n\n this.location = location;\n }\n\n setItem(item: string | string[] = '') {\n if (Array.isArray(item)) {\n this.items.push(...item);\n } else {\n this.items.push(item);\n }\n }\n\n setOrder(order: number) {\n this.order = order;\n }\n\n getData(options?: { joinArray?: boolean }) {\n const { joinArray = false } = options || {};\n\n const finalArr = [];\n finalArr.push(`location ${this.location} {`);\n finalArr.push(...indent(this.items));\n finalArr.push('}');\n\n return joinArray ? finalArr.join('\\n') : finalArr;\n }\n}\n","import { indent, validateRequired } from '../../lib';\nimport LocationBlock from './LocationBlock';\n\ninterface ReverseProxyOptions {\n host?: string;\n port: number;\n location?: string;\n hostUri?: string;\n headers?: Map<string, string>;\n resetHeader?: boolean;\n}\n\nexport default class ReverseProxy {\n host: string;\n port: number;\n location: string;\n hostUri: string;\n headers: Map<string, string>;\n private headerArgs: Map<string, string>;\n resetHeader: boolean;\n\n constructor(options: ReverseProxyOptions) {\n const {\n host = 'localhost',\n port,\n location = '/',\n hostUri = '/',\n headers = new Map(),\n resetHeader = false,\n } = options;\n\n validateRequired({ port }, { message: (v) => `\"${v}\" is required in ReverseProxy constructor.` });\n\n this.host = host;\n this.port = port;\n this.location = location;\n this.hostUri = hostUri;\n this.resetHeader = resetHeader;\n\n if (!(headers instanceof Map)) {\n throw new Error(`\"headers\" must be a Map`);\n }\n this.headers = new Map();\n this.headerArgs = headers;\n\n this.setDefaultHeaders();\n }\n\n /* =======================\n Mutators\n ======================= */\n\n setHost(host: string): void {\n this.host = host;\n }\n\n setPort(port: number): void {\n this.port = port;\n }\n\n setResetHeader(reset: boolean): void {\n this.resetHeader = reset;\n this.setDefaultHeaders();\n }\n\n setHeader(header: string, value: string): void {\n this.headers.set(header, value);\n }\n\n deleteHeader(header: string): void {\n this.headers.delete(header);\n }\n\n /* =======================\n Accessors\n ======================= */\n\n getHeader(header: string): string | undefined {\n return this.headers.get(header);\n }\n\n getHeaders(): Map<string, string> {\n return new Map(this.headers);\n }\n\n /* =======================\n Private Helper Methods\n ======================= */\n\n getHeadersList(): string[] {\n const headers: string[] = [];\n for (const [key, value] of this.headers.entries()) {\n headers.push(`${key} ${value};`);\n }\n return headers;\n }\n\n private setDefaultHeaders(props?: { reset: boolean }): void {\n const reset = props?.reset || false;\n\n // Set main Headers\n this.headers.clear();\n const headers = new Map<string, string>();\n headers.set('proxy_pass', `http://${this.host}:${this.port}${this.hostUri}`);\n\n if (!reset) {\n if (!this.resetHeader) {\n headers.set('proxy_set_header Host', '$host');\n headers.set('proxy_set_header X-Real-IP', '$remote_addr');\n headers.set('proxy_set_header X-Forwarded-Host', '$http_host');\n headers.set('proxy_set_header X-Forwarded-Proto', '$scheme');\n headers.set('proxy_set_header X-Forwarded-For', '$proxy_add_x_forwarded_for');\n headers.set('proxy_cache_bypass', '$http_upgrade');\n\n // add support for websockets\n headers.set('proxy_http_version', '1.1');\n headers.set('proxy_set_header Upgrade', '$http_upgrade');\n headers.set('proxy_set_header Connection', 'upgrade');\n }\n\n this.headers = new Map([...headers, ...this.headerArgs]);\n }\n }\n\n /* =======================\n Nginx Config Helpers\n ======================= */\n\n getData(options: { joinArray?: boolean } = {}) {\n const { joinArray = false } = options;\n const headers = this.getHeadersList();\n\n const locationBlock = new LocationBlock(this.location);\n locationBlock.setItem(headers);\n\n return locationBlock.getData({ joinArray });\n }\n}\n","import { indent } from '../../lib';\nimport LocationBlock from './LocationBlock';\n\nexport default class ServerBlock {\n serverItems: string[] = [];\n sslItems: string[] = [];\n locationBlocks: LocationBlock[] = [];\n redirectItems: string[] = [];\n\n addServerItem(item: string | string[]) {\n if (Array.isArray(item)) {\n this.serverItems.push(...item);\n } else {\n this.serverItems.push(item);\n }\n }\n\n addSslItem(item: string | string[]) {\n if (Array.isArray(item)) {\n this.sslItems.push(...item);\n } else {\n this.sslItems.push(item);\n }\n }\n\n addLocationBlock(block: LocationBlock | null = null) {\n if (block && block instanceof LocationBlock) {\n this.locationBlocks.push(block);\n }\n }\n\n addRedirectItem(item: string | string[]) {\n if (Array.isArray(item)) {\n this.redirectItems.push(...item);\n } else {\n this.redirectItems.push(item);\n }\n }\n\n getData(options: { joinArray?: boolean } = {}) {\n const { joinArray = false } = options;\n\n const finalArr = [];\n finalArr.push('server {');\n\n // 1. Server Items\n finalArr.push(...indent(this.serverItems));\n\n // 2. SSL Items\n if (this.sslItems?.length) {\n finalArr.push('\\n');\n this.sslItems.forEach((sslItem) => {\n finalArr.push(indent(sslItem));\n });\n }\n\n // 3. Either `Redirect Items` or `Location Blocks`\n\n if (this.redirectItems?.length) {\n finalArr.push('\\n');\n this.redirectItems.forEach((redirectItem) => {\n finalArr.push(indent(redirectItem));\n });\n } else if (this.locationBlocks?.length) {\n const orderedLocationBlocks = this.locationBlocks.toSorted((a, b) => {\n return a.order - b.order;\n });\n finalArr.push('');\n orderedLocationBlocks.forEach((block) => {\n finalArr.push('');\n finalArr.push(...indent(block.getData()));\n });\n }\n\n finalArr.push('}');\n return joinArray ? finalArr.join('\\n') : finalArr;\n }\n}\n","// import ReverseProxy from './ReverseProxy.mjs';\n// import { getDate, indent, validateRequired } from './../utils.mjs';\n// import ServerBlock from './ServerBlock.mjs';\n// import LocationBlock from './LocationBlock.mjs';\n// import { writeFile } from '../fileUtils.mjs';\n\nimport { validateRequired } from '../../lib';\nimport LocationBlock from './LocationBlock';\nimport ReverseProxy from './ReverseProxy';\nimport ServerBlock from './ServerBlock';\n\nexport type VhostAppType = 'reverseProxy' | 'html' | 'react' | 'node' | 'react-node' | 'php' | 'python';\n\ntype VhostSslType = boolean | { crt: string; key: string };\n// Default: false\n// true => use Let's Encrypt certs using sslCertificateName\n// false => no SSL\n// {crt, key} => use custom certs\n\nexport interface VhostArgs {\n id: string;\n domainName: string;\n tld?: string;\n serverNames: string[];\n redirectToFirstServer?: boolean;\n appType?: VhostAppType;\n\n reverseProxies?: Map<string, ReverseProxy>;\n\n ssl?: VhostSslType;\n sslCertificateName?: string;\n redirectToHttps?: boolean;\n\n // Fixed values\n rootDirectory?: string;\n http_port?: number;\n https_port?: number;\n\n meta?: VhostMeta;\n}\n\nexport interface VhostMeta {\n confFileName?: string;\n group?: string;\n}\n\nexport default class Vhost {\n id: string;\n domainName: string;\n tld: string;\n serverNames: string[];\n redirectToFirstServer: boolean;\n\n appType: VhostAppType;\n\n reverseProxies?: Map<string, ReverseProxy>;\n\n ssl: boolean | { crt: string; key: string };\n sslCertificateName: string;\n redirectToHttps: boolean;\n\n rootDirectory: string;\n http_port: number;\n https_port: number | string;\n\n meta?: VhostMeta;\n\n constructor(args: VhostArgs) {\n const {\n id,\n domainName = '',\n tld = 'com',\n serverNames = [],\n redirectToFirstServer = true,\n appType = 'reverseProxy',\n\n reverseProxies = new Map<string, ReverseProxy>(),\n\n ssl = false,\n sslCertificateName, // required if `ssl` is empty array\n redirectToHttps = false,\n\n rootDirectory = '/var/www/html',\n http_port = 80,\n https_port = `443 ssl`,\n\n meta,\n } = args || {};\n\n validateRequired(\n {\n id,\n domainName,\n tld,\n serverNames,\n rootDirectory,\n appType,\n http_port,\n https_port,\n },\n {\n noEmptyArray: true,\n noEmptyObject: true,\n },\n );\n\n this.reverseProxies = reverseProxies;\n\n if (!Array.isArray(serverNames) || serverNames.length === 0) {\n throw new Error(`\"serverNames\" must be a non-empty array of server-names`);\n }\n\n this.id = id;\n this.domainName = domainName;\n this.tld = tld;\n this.serverNames = serverNames;\n this.redirectToFirstServer = redirectToFirstServer;\n this.appType = appType;\n this.ssl = ssl;\n this.sslCertificateName = sslCertificateName ?? `${domainName}.${tld}`;\n this.redirectToHttps = redirectToHttps;\n this.rootDirectory = rootDirectory;\n this.http_port = http_port;\n this.https_port = https_port;\n\n this.meta = meta ?? {};\n this.meta.group = this.meta?.group ?? 'default';\n\n // this.leSslFolderName = \"\";\n // this.sslCertificateFile = \"\";\n // this.sslCertificateKeyFile = \"\";\n }\n\n /* ========================\n Reverse Proxy\n ======================== */\n\n setReverseProxy(reverseProxy: ReverseProxy) {\n if (reverseProxy instanceof ReverseProxy) {\n if (reverseProxy?.location) {\n if (this.reverseProxies) {\n this.reverseProxies.set(reverseProxy?.location, reverseProxy);\n } else {\n const errMsg = `Error: Server ID: ${this.id} - reverseProxies Map is not initialized.`;\n console.error(errMsg);\n throw new Error(errMsg);\n }\n return;\n }\n }\n console.warn('Error: Server ID: ${this.id} - Invalid reverseProxy passed', JSON.stringify(reverseProxy));\n }\n\n /* ========================\n Location Blocks\n ======================== */\n\n getLocationBlocks() {\n const locationBlocks = [];\n if (this.reverseProxies?.size && this.reverseProxies instanceof Map) {\n this.reverseProxies?.forEach((rp) => {\n const locationBlock = new LocationBlock(rp.location);\n locationBlock.setItem(rp.getHeadersList());\n locationBlocks.push(locationBlock);\n });\n } else {\n // This will be used for non-reverse-proxy vhosts\n const locationBlock = new LocationBlock('/');\n locationBlock.setItem('try_files $uri $uri/ =404;');\n locationBlocks.push(locationBlock);\n }\n return locationBlocks;\n }\n\n /* ========================\n Server Block Creation\n ======================== */\n\n createServerBlock(\n options: {\n joinArray?: boolean;\n serverDirectives?: string[];\n addSslCertificates?: boolean;\n redirects?: string[];\n locationBlocks?: LocationBlock[];\n } = {},\n ) {\n const {\n joinArray = false,\n serverDirectives = [],\n addSslCertificates = false,\n redirects = [],\n locationBlocks = [],\n } = options;\n\n const serverBlock = new ServerBlock();\n\n if (serverDirectives?.length) {\n serverDirectives.forEach((directive) => {\n serverBlock.addServerItem(directive);\n });\n }\n\n if (addSslCertificates) {\n const sslDirectives: string[] = [\n // ``,\n // `ssl_session_cache shared:le_nginx_SSL:30m;`,\n // `keepalive_timeout 120;`,\n // `ssl_protocols TLSv1.2 TLSv1.3;`, // TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;\n // `ssl_prefer_server_ciphers on;`,\n // `ssl_ciphers HIGH:!aNULL:!MD5;`,\n ];\n if (this.ssl === undefined) {\n throw new Error(\n `Please provide/set valid value for \"this.ssl\" in 'Vhost' constructor, if you want to redirect to HTTPS`,\n );\n }\n if (this.ssl === true) {\n serverBlock.addSslItem([\n `ssl_certificate /etc/letsencrypt/live/${this.sslCertificateName}/fullchain.pem;`,\n `ssl_certificate_key /etc/letsencrypt/live/${this.sslCertificateName}/privkey.pem;`,\n ...sslDirectives,\n ]);\n } else if (this.ssl === false) {\n // do nothing\n } else if (typeof this.ssl === 'object') {\n serverBlock.addSslItem([\n `ssl_certificate ${this.ssl?.crt};`,\n `ssl_certificate_key ${this.ssl?.key};`,\n ...sslDirectives,\n ]);\n } else {\n throw new Error('Something Went Wrong in SSL Directives.');\n }\n }\n\n if (redirects?.length) {\n serverBlock.addRedirectItem(redirects);\n } else {\n const defaultLocationBlocks = this.getLocationBlocks();\n const allLocationBlocks = [...defaultLocationBlocks, ...locationBlocks].sort((a, b) => {\n return a?.order - b?.order;\n });\n\n if (allLocationBlocks?.length) {\n allLocationBlocks.forEach((block) => {\n serverBlock.addLocationBlock(block);\n });\n }\n }\n\n // serverBlock.addLocationItem(this.getLocationDirectives());\n return serverBlock.getData({ joinArray });\n }\n\n /* ========================\n Directives\n ======================== */\n\n getIndexDirective() {\n const indexFiles = `index index.html index.htm`;\n switch (this.appType) {\n case 'reverseProxy': {\n return `${indexFiles};`;\n }\n case 'html': {\n return `${indexFiles};`;\n }\n case 'react': {\n return `${indexFiles};`;\n }\n case 'node': {\n return `${indexFiles};`;\n }\n case 'react-node': {\n return `${indexFiles};`;\n }\n case 'php': {\n return `index.php ${indexFiles};`;\n }\n case 'python': {\n return `index.py ${indexFiles};`;\n }\n default: {\n return `${indexFiles}; # Default`;\n }\n }\n }\n\n getServerDirectives(\n options: {\n serverNames?: string[];\n redirect?: boolean;\n port?: number | string;\n } = {},\n ) {\n const { serverNames, redirect = false, port = this.http_port } = options;\n\n let arr = [`listen ${port};`, `listen [::]:${port};`, ``, `server_name ${serverNames?.join(' ')};`];\n\n if (!redirect) {\n arr.push(``, this.getIndexDirective(), `root ${this.rootDirectory};`);\n }\n\n return arr;\n }\n\n _generateFullServerBlock(options: {\n redirectHttps: boolean;\n redirectWWW: boolean;\n port: number | string;\n onlyFirstServerName?: boolean;\n }) {\n const { redirectHttps = false, redirectWWW = false, port, onlyFirstServerName = false } = options || {};\n\n const redirects = [];\n\n if (redirectHttps || redirectWWW) {\n const httpSecured = redirectHttps || port === this.https_port ? 's' : '';\n const serverName = redirectWWW ? this.serverNames?.[0] : '$host';\n\n redirects.push(`return 301 http${httpSecured}://${serverName}$request_uri;`);\n }\n\n const serverNames = redirectWWW ? this.serverNames?.slice(1) : this.serverNames;\n const block = this.createServerBlock({\n serverDirectives: this.getServerDirectives({\n serverNames: onlyFirstServerName ? [serverNames?.[0]] : serverNames,\n port,\n redirect: redirectHttps || redirectWWW,\n }),\n addSslCertificates: Boolean(this.ssl && port === this.https_port),\n redirects: redirects?.length ? redirects : undefined,\n });\n return block;\n }\n\n /* ========================\n VHost Creation (createVHost())\n ======================== */\n\n getData(options?: { joinArray: false }): string[];\n getData(options?: { joinArray?: true }): string;\n getData(options?: { joinArray?: boolean }): string | string[] {\n const { joinArray = false } = options ?? {};\n\n const serverBlocks: any[] = [];\n\n const serverNames = this.serverNames;\n const redirectToFirtServerName =\n this.redirectToFirstServer && this.serverNames?.length > 1 ? this.serverNames?.[0] : '';\n const redirectToHttps = this.redirectToHttps;\n\n if (!redirectToHttps) {\n if (!redirectToFirtServerName) {\n // console.log(22222222222222, { redirectToHttps, redirectToFirtServerName, serverNames });\n serverBlocks.push(\n this._generateFullServerBlock({\n port: this.http_port,\n redirectHttps: false,\n redirectWWW: false,\n }),\n );\n\n if (Boolean(this.ssl)) {\n serverBlocks.push(\n this._generateFullServerBlock({\n port: this.https_port,\n redirectHttps: false,\n redirectWWW: false,\n }),\n );\n }\n } else {\n serverBlocks.push(\n this._generateFullServerBlock({\n port: this.http_port,\n redirectHttps: false,\n redirectWWW: true,\n }),\n );\n\n serverBlocks.push(\n this._generateFullServerBlock({\n port: this.https_port,\n redirectHttps: false,\n redirectWWW: true,\n }),\n );\n\n serverBlocks.push(\n this._generateFullServerBlock({\n port: this.http_port,\n redirectHttps: false,\n redirectWWW: false,\n onlyFirstServerName: true,\n }),\n );\n\n serverBlocks.push(\n this._generateFullServerBlock({\n port: this.https_port,\n redirectHttps: false,\n redirectWWW: false,\n onlyFirstServerName: true,\n }),\n );\n }\n } else {\n if (!redirectToFirtServerName) {\n serverBlocks.push(\n this._generateFullServerBlock({\n port: this.http_port,\n redirectHttps: true,\n redirectWWW: false,\n }),\n );\n\n serverBlocks.push(\n this._generateFullServerBlock({\n port: this.https_port,\n redirectHttps: false,\n redirectWWW: false,\n }),\n );\n } else {\n serverBlocks.push(\n this._generateFullServerBlock({\n port: this.http_port,\n redirectHttps: true,\n redirectWWW: true,\n }),\n );\n\n serverBlocks.push(\n this._generateFullServerBlock({\n port: this.https_port,\n redirectHttps: true,\n redirectWWW: true,\n }),\n );\n\n serverBlocks.push(\n this._generateFullServerBlock({\n port: this.http_port,\n redirectHttps: true,\n redirectWWW: false,\n onlyFirstServerName: true,\n }),\n );\n\n serverBlocks.push(\n this._generateFullServerBlock({\n port: this.https_port,\n redirectHttps: false,\n redirectWWW: false,\n onlyFirstServerName: true,\n }),\n );\n }\n }\n\n const serverBlocksArr = (\n options: {\n joinArray?: boolean;\n } = {},\n ) => {\n const { joinArray = false } = options;\n const arr: any[] = [];\n serverBlocks?.map((serverBlock, i) => {\n arr.push(...serverBlock);\n if (i + 1 < serverBlocks?.length) {\n arr.push('');\n }\n });\n return joinArray ? arr?.join(`\\n`) : arr;\n };\n return serverBlocksArr({ joinArray });\n }\n\n /* ========================\n File Generation\n ======================== */\n\n // async generateServerConfFile() {\n // const data = this.createVHost({\n // joinArray: true,\n // });\n\n // const HOSTS = new Set();\n // if (this.isReverseProxy) {\n // this.reverseProxies?.forEach((rp) => {\n // if (rp?.host) {\n // HOSTS.add(rp?.host);\n // }\n // });\n // }\n // // console.log(11111111, data);\n\n // const HOSTS_STR = HOSTS.size ? [...HOSTS].join(', ') : '';\n\n // const dataArr = [\n // `# Created at: ${getDate()}`,\n // `# ID: ${this.id}`,\n // `# HOST: ${HOSTS_STR}`,\n // `###################################`,\n // `\\n\\n`,\n // data,\n // ];\n // const fileName = this.id + '.conf';\n // // writeFile(fileName, dataArr.join('\\n'));\n // }\n}\n\n// npx ts-node src/classes/vhost/sample/vhost.ts\n","import path from 'path';\nimport { exists, isDir, isFile, readDirectory } from '../../lib/utils/fs-extra';\nimport { SvhostNginxHelper } from './SvhostNginxHelper';\n\nimport { getFullDateTime } from '../../lib/utils/datetime';\nimport { copyFile, mkdir, readdir, rm, writeFile } from 'fs/promises';\nimport JsYaml from '../../lib/utils/js-yaml';\nimport Vhost, { VhostArgs } from '../vhost/Vhost';\nimport { VHostConfig } from './yaml/types';\nimport ReverseProxy from '../vhost/ReverseProxy';\n\ninterface SvhostNginxOptions {}\n\ninterface SvhostNginxGenerateOptions {\n file?: string;\n srcDir?: string;\n outputDir: string;\n quiet?: boolean;\n cleanDir?: boolean;\n createEmptyFile?: boolean;\n nginxConfFile?: string;\n subConfdDir?: boolean;\n}\n\nexport class SvhostNginx {\n private helper: SvhostNginxHelper;\n\n constructor(props?: SvhostNginxOptions) {\n this.helper = new SvhostNginxHelper(this);\n }\n\n async yamlToVhostInstances(yamlFilePath: string, options?: { quiet?: boolean }): Promise<Vhost[]> {\n const { quiet = false } = options || {};\n try {\n const jsYaml = new JsYaml();\n const yamlConfig = (await jsYaml.read(yamlFilePath)) as VHostConfig;\n const vhostsData = yamlConfig?.vhosts || [];\n const defaultMeta = yamlConfig?.meta || {};\n\n if (!quiet) {\n console.log(`YAML Config Data : -------- Total VHosts in file \"${yamlFilePath}\":`, vhostsData.length);\n console.log('VHosts Default Meta:', { defaultMeta });\n }\n for (const vhost of vhostsData) {\n if (!quiet) {\n console.log('VHost Data:', vhost);\n console.log('VHost reverseProxies:', vhost?.reverseProxies);\n }\n }\n\n const vhosts: Vhost[] = [];\n\n vhostsData.forEach((vhostData) => {\n const newVhostData = structuredClone(vhostData) as VhostArgs;\n newVhostData.meta = { ...defaultMeta, ...(newVhostData.meta ?? {}) };\n delete newVhostData.reverseProxies;\n if (!quiet) {\n console.log('New VHost Data (without reverseProxies):', newVhostData);\n }\n\n const vhost = new Vhost(newVhostData);\n vhosts.push(vhost);\n if (!quiet) {\n console.log('Processing VHost:', vhost.id);\n console.log('vhostData?.reverseProxies:', vhostData?.reverseProxies);\n }\n [...(vhostData?.reverseProxies ?? [])]?.forEach((reverseProxyItem) => {\n const [[pathKey, proxyConfig]] = Object.entries(reverseProxyItem ?? {});\n if (!quiet) {\n console.log('Reverse Proxy Data:', { pathKey, proxyConfig });\n }\n proxyConfig.location = pathKey;\n const reverseProxy = new ReverseProxy(proxyConfig);\n // console.log(6666, { pathKey, reverseProxy });\n vhost.setReverseProxy(reverseProxy);\n });\n });\n\n if (!quiet) {\n console.log(`Loaded (${vhosts.length}) vhost(s) from YAML file: \"${yamlFilePath}\"`);\n }\n\n return vhosts;\n } catch (error: any) {\n throw new Error(`Error reading YAML file \"${yamlFilePath}\": ${error?.message}`, { cause: error });\n }\n }\n\n async getVhostInstanceArray(filePath: string, options?: { quiet?: boolean }): Promise<Vhost[] | null> {\n const { quiet = false } = options || {};\n\n try {\n if (!isFile(filePath)) {\n if (!quiet) {\n console.warn(`The path \"${filePath}\" is not a valid file.`);\n }\n return null;\n }\n const vhostInstances = await this.yamlToVhostInstances(filePath, { quiet });\n return vhostInstances;\n } catch (error: any) {\n console.error('-----------------------------------');\n console.error(`Error Message: ${error?.message}`);\n console.error('----------------- Complete Error ------------------');\n console.error(error);\n console.error('-----------------------------------');\n throw new Error(`YAML File Error, while importing \"${filePath}\": ${error?.message}`);\n }\n }\n\n async getVhostInstances(dirPath: string, options?: { quiet?: boolean }): Promise<Vhost[]> {\n const { quiet = false } = options || {};\n\n try {\n const files = await readDirectory(dirPath, {\n recursive: true,\n filesOnly: true,\n returnType: 'relative',\n forwardSlashes: true,\n quiet,\n });\n if (!quiet) {\n console.log(4444, { quiet }, { files });\n console.log(files);\n }\n\n const vhosts: Vhost[] = [];\n\n for (const file of files) {\n if (file.endsWith('.yml') || file.endsWith('.yaml')) {\n const fullPath = path.resolve(dirPath, file);\n // console.log(5555, { fullPath });\n const vhostArray = await this.getVhostInstanceArray(fullPath, { quiet });\n if (vhostArray?.length) {\n vhosts.push(...vhostArray);\n }\n }\n }\n return vhosts;\n } catch (error) {\n throw new Error(\n `Error in \"getVhostInstances()\" from directory \"${dirPath}\": Error:\"${(error as Error).message}\"`,\n { cause: error },\n );\n }\n }\n\n async ensureDir(outputDir: string, options?: { quiet?: boolean; directoryName?: string }): Promise<void> {\n const { quiet = false, directoryName = 'Output' } = options || {};\n if (!(await isDir(outputDir))) {\n if (!(await isDir(path.dirname(outputDir)))) {\n throw new Error(`## ${directoryName} directory does not exist: ${outputDir}`);\n } else {\n if (!quiet) {\n console.log(`## ${directoryName} directory does not exist. Creating directory: \"${outputDir}\"`);\n }\n await mkdir(outputDir, { recursive: true });\n }\n }\n }\n\n getVhostConfigFileData(confData: Vhost, options?: { joinArray: false }): string[];\n getVhostConfigFileData(confData: Vhost, options?: { joinArray?: true }): string;\n getVhostConfigFileData(vhost: Vhost, options?: { joinArray?: boolean }): string | string[] {\n const { joinArray = false } = options || {};\n const confData = vhost.getData() ?? [];\n const hosts_list = vhost.reverseProxies?.size\n ? [...vhost.reverseProxies]\n ?.map(([key, value]) => `${key} => ${value?.host}:${value?.port}${value?.hostUri}`)\n .join(', ')\n : '';\n\n const dataArr = [\n `# Created at: ${getFullDateTime()}`,\n `# ID: ${vhost.id}`,\n `# HOST (s): ${hosts_list}`,\n `# GROUP: ${vhost?.meta?.group}`,\n `###################################`,\n `\\n\\n`,\n ...confData,\n ];\n\n return joinArray ? dataArr.join('\\n') : dataArr;\n }\n\n async generateVhostConfig(options: { vhosts: Vhost[]; destDir: string; quiet?: boolean }): Promise<void> {\n const { vhosts, destDir, quiet = false } = options;\n\n await this.ensureDir(destDir, { quiet, directoryName: 'Destination' });\n\n for (const vhost of vhosts) {\n const vhostConfData = this.getVhostConfigFileData(vhost, { joinArray: true });\n const fileName = vhost?.meta?.confFileName ?? `${vhost?.meta?.group}--${vhost.id}.conf`;\n const filePath = path.resolve(destDir, fileName);\n if (!quiet) {\n console.log(`Generating vhost config file: \"${filePath}\" ...`, vhostConfData);\n }\n try {\n await writeFile(filePath, vhostConfData);\n } catch (error: any) {\n throw new Error(`Error writing vhost config file \"${filePath}\": ${error?.message}`, { cause: error });\n }\n }\n }\n\n async generate(options: SvhostNginxGenerateOptions & { file: string }): Promise<void>;\n async generate(options: SvhostNginxGenerateOptions & { srcDir: string }): Promise<void>;\n async generate(options: SvhostNginxGenerateOptions): Promise<void> {\n const {\n file,\n srcDir,\n outputDir,\n quiet = false,\n cleanDir = false,\n createEmptyFile = false,\n nginxConfFile,\n subConfdDir = true,\n } = options;\n\n try {\n if (!file && !srcDir) {\n throw new Error('Either \"file\" or \"srcDir\" must be provided.');\n }\n if (file && !(await isFile(file))) {\n throw new Error(`The specified file does not exist: ${file}`);\n }\n if (srcDir && !(await isDir(srcDir))) {\n throw new Error(`The specified source directory does not exist: ${srcDir}`);\n }\n\n await this.ensureDir(outputDir, { quiet, directoryName: 'output' });\n if (subConfdDir) {\n await this.ensureDir(path.resolve(outputDir, 'conf.d'), { quiet, directoryName: 'output/conf.d' });\n }\n\n const vhosts: Vhost[] = [];\n if (!quiet) {\n console.log(1111, { file, srcDir });\n }\n\n if (file) {\n const vhostInstancesArray = await this.getVhostInstanceArray(file, { quiet });\n if (vhostInstancesArray?.length) {\n vhosts.push(...vhostInstancesArray);\n }\n }\n\n if (srcDir) {\n const vhostInstances = await this.getVhostInstances(srcDir, { quiet });\n if (!quiet) {\n console.log({ 'vhostInstances Count': vhostInstances.length });\n console.log(3333, vhostInstances);\n }\n vhosts.push(...vhostInstances);\n }\n if (cleanDir) {\n const paths = (await readdir(outputDir)).map((f) => path.resolve(outputDir, f));\n await Promise.all(paths.map((filePath) => rm(filePath, { recursive: true, force: true })));\n }\n\n if (createEmptyFile) {\n await writeFile(path.resolve(outputDir, '.empty'), '');\n }\n\n if (nginxConfFile) {\n const nginxConfFilePath = path.resolve(nginxConfFile);\n if (await exists(nginxConfFilePath)) {\n await copyFile(nginxConfFilePath, path.resolve(outputDir, 'nginx.conf'));\n }\n }\n\n const confdDir = subConfdDir ? path.resolve(outputDir, 'conf.d') : outputDir;\n if (!quiet) {\n console.log(`Total vhosts to generate: ${vhosts.length} . Output Directory: \"${outputDir}\"`);\n console.log({ subConfdDir });\n console.log(`conf.d Directory: \"${confdDir}\"`);\n }\n\n // console.log(4444, 'Total vhosts to generate:', { vhosts, destDir: outputDir, quiet });\n\n await this.generateVhostConfig({ vhosts, destDir: confdDir, quiet });\n\n if (!quiet) {\n console.log(`Generated (${vhosts.length}) vhost configuration file(s) in \"${outputDir}\".`);\n }\n } catch (error) {\n throw new Error(`Error in generate method: \"${(error as Error).message}\"`, { cause: error });\n }\n }\n}\n","import { Command } from '../../lib';\nimport { Command as CommanderCommand } from 'commander';\nimport { isDir, isFile } from '../../lib/utils/fs-extra';\nimport path from 'path';\nimport { SvhostNginx } from './SvhostNginx';\n// import { SvhostNginxHelper } from './SvhostNginxHelper';\n\nexport class SvhostNginxCli extends Command {\n // private helper: SvhostNginxHelper;\n private quiet: boolean = true;\n\n constructor() {\n super();\n // this.helper = new SvhostNginxHelper(this);\n }\n\n setupCommand(): Promise<CommanderCommand> {\n const program = new CommanderCommand();\n program.name('svhost-nginx').description('Nginx - Simple Virtual Host').version('1.0.0');\n\n program\n .description('Generate Nginx configuration for a virtual host')\n .option('-f, --src-file <srcFile>', 'Source file for configuration')\n .option('--src-dir <srcDir>', 'Source directory for configuration')\n .requiredOption('-d, --dest-dir <destDir>', 'Destination directory for configuration')\n .action(this.actionDefault.bind(this));\n\n return program.parseAsync(process.argv);\n }\n\n async run(options?: { quiet?: boolean }): Promise<void> {\n const { quiet = true } = options || {};\n this.quiet = quiet;\n await this.setupCommand();\n }\n\n async actionDefault(name: { [key: string]: string }, options: any, command: CommanderCommand) {\n const { srcFile, srcDir, destDir } = name;\n if (!this.quiet) {\n console.log('Commander:', { name, command });\n }\n\n if (srcFile && srcDir) {\n throw new Error('Please provide either --src-file or --src-dir, not both.');\n }\n\n if (!srcFile && !srcDir) {\n throw new Error('Please provide either --src-file or --src-dir.');\n }\n\n // Implement the logic to generate Nginx configuration here using srcFile/srcDir and destDir\n const srcFilePath = path.resolve(srcFile || '');\n const srcDirPath = path.resolve(srcDir || '');\n const destDirPath = path.resolve(destDir);\n\n if (!this.quiet) {\n console.table({\n 'Source File': srcFilePath,\n 'Source Directory': srcDirPath,\n 'Destination Directory': destDirPath,\n });\n }\n if (srcFile && !(await isFile(srcFile))) {\n throw new Error(`Source file does not exist: \"${srcFile}\"`);\n }\n\n if (srcDir && !(await isDir(srcDir))) {\n throw new Error(`Source directory does not exist: \"${srcDir}\"`);\n }\n\n console.log(`Generating Nginx configuration ...`);\n const svhostNginx = new SvhostNginx();\n if (srcFile) {\n await svhostNginx.generate({\n file: srcFilePath,\n outputDir: destDirPath,\n quiet: this.quiet,\n cleanDir: true,\n });\n } else if (srcDir) {\n await svhostNginx.generate({\n srcDir: srcDirPath,\n outputDir: destDirPath,\n quiet: this.quiet,\n cleanDir: true,\n });\n }\n\n if (!this.quiet) {\n console.log('option1 action executed');\n console.log('Name:', name, typeof name);\n // console.log('Options:', options);\n }\n }\n}\n","export * from './../../classes/svhost-nginx/SvhostNginx';\nexport * from './../../classes/svhost-nginx/SvhostNginxCli';\nexport * from './../../classes/svhost-nginx/SvhostNginxHelper';\n"],"mappings":"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","names":["SvhostNginxHelper","init_SvhostNginxHelper","__esmMin","svhostNginx","fs","constants","readdir","path","exists","isFile","isDir","readDirectory","dirPath","options","recursive","filesOnly","dirsOnly","returnType","forwardSlashes","ignorefile","quiet","includeIgnorefile","resolve","reject","normalize","filteredFiles","dirent","ignoreData","err","excludeData","includeData","extractLines","data","v","matchRegExp","line","applyIgnoreRules","filterLines","rules","includeMatched","relativePath","rule","checkIsRegExp","regex","flags","excludeLines","includeLines","baseDir","filePaths","absPath","init_fs_extra","__esmMin","run","ignoreFileData","testFullPath","dirContents","getFullDateTime","options","now","dateOptions","year","month","day","hours","minutes","seconds","init_datetime","__esmMin","load","fsReadFile","stat","resolve","JsYaml","init_js_yaml","__esmMin","path","resolvedPath","error","err","obj","vars","_","v","k","content","data","LocationBlock","init_LocationBlock","__esmMin","init_lib","location","validateRequired","item","order","options","joinArray","finalArr","indent","ReverseProxy","init_ReverseProxy","__esmMin","init_lib","init_LocationBlock","options","host","port","location","hostUri","headers","resetHeader","validateRequired","v","reset","header","value","key","props","joinArray","locationBlock","LocationBlock","ServerBlock","init_ServerBlock","__esmMin","init_lib","init_LocationBlock","item","block","LocationBlock","options","joinArray","finalArr","indent","sslItem","redirectItem","orderedLocationBlocks","a","b","Vhost","init_Vhost","__esmMin","init_lib","init_LocationBlock","init_ReverseProxy","init_ServerBlock","args","id","domainName","tld","serverNames","redirectToFirstServer","appType","reverseProxies","ssl","sslCertificateName","redirectToHttps","rootDirectory","http_port","https_port","meta","validateRequired","reverseProxy","ReverseProxy","errMsg","locationBlocks","rp","locationBlock","LocationBlock","options","joinArray","serverDirectives","addSslCertificates","redirects","serverBlock","ServerBlock","directive","sslDirectives","allLocationBlocks","a","b","block","indexFiles","redirect","port","arr","redirectHttps","redirectWWW","onlyFirstServerName","httpSecured","serverName","serverBlocks","redirectToFirtServerName","i","path","copyFile","mkdir","readdir","rm","writeFile","SvhostNginx","init_SvhostNginx","__esmMin","init_fs_extra","init_SvhostNginxHelper","init_datetime","init_js_yaml","init_Vhost","init_ReverseProxy","props","SvhostNginxHelper","yamlFilePath","options","quiet","yamlConfig","JsYaml","vhostsData","defaultMeta","vhost","vhosts","vhostData","newVhostData","Vhost","reverseProxyItem","pathKey","proxyConfig","reverseProxy","ReverseProxy","error","filePath","isFile","dirPath","files","readDirectory","file","fullPath","vhostArray","outputDir","directoryName","isDir","joinArray","confData","hosts_list","key","value","dataArr","getFullDateTime","destDir","vhostConfData","fileName","srcDir","cleanDir","createEmptyFile","nginxConfFile","subConfdDir","vhostInstancesArray","vhostInstances","paths","f","nginxConfFilePath","exists","confdDir","CommanderCommand","path","SvhostNginxCli","init_SvhostNginxCli","__esmMin","init_lib","init_fs_extra","init_SvhostNginx","Command","program","options","quiet","name","command","srcFile","srcDir","destDir","srcFilePath","srcDirPath","destDirPath","isFile","isDir","svhostNginx","SvhostNginx","init_svhost_nginx","__esmMin","init_SvhostNginx","init_SvhostNginxCli","init_SvhostNginxHelper"]}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use strict";var he=Object.create;var k=Object.defineProperty;var de=Object.getOwnPropertyDescriptor;var fe=Object.getOwnPropertyNames;var ge=Object.getPrototypeOf,ue=Object.prototype.hasOwnProperty;var me=(i,e)=>{for(var r in e)k(i,r,{get:e[r],enumerable:!0})},oe=(i,e,r,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of fe(e))!ue.call(i,s)&&s!==r&&k(i,s,{get:()=>e[s],enumerable:!(t=de(e,s))||t.enumerable});return i};var O=(i,e,r)=>(r=i!=null?he(ge(i)):{},oe(e||!i||!i.__esModule?k(r,"default",{value:i,enumerable:!0}):r,i)),ye=i=>oe(k({},"__esModule",{value:!0}),i);var ve={};me(ve,{SvhostCli:()=>Y,SvhostNginx:()=>H,SvhostNginxCli:()=>Z,SvhostNginxHelper:()=>N});module.exports=ye(ve);var P=class{};var V=class{constructor(e){this.enableCommandCliLogging=!1;this.enableCommandCliLogging=e?.enableCommandCliLogging||!1}async run(){try{await this.setUpCommands(),this.enableCommandCliLogging&&(console.log("Command CLI executed successfully."),console.log("Running CLI... with args:",process.argv))}catch(e){this.enableCommandCliLogging&&console.error("Error running Command CLI:",e?.message,e),process.exit(1)}}};function A(i,e={}){let{notAllowed:r=[void 0,null,"",0],message:t=s=>`"${s}" is required.`}=e;if(typeof i=="object"&&Object.keys(i).length){Object.entries(i).forEach(([s,o])=>{if(r.includes(o))throw new Error(t(s));if(e.noEmptyArray&&Array.isArray(o)&&o.length===0)throw new Error(`${s} cannot be an empty array.`);if(e.noEmptyObject&&o instanceof Object&&Object.keys(o).length===0)throw new Error(`${s} cannot be an empty object.`)});return}throw new Error('Invalid arg passed to "validateRequired"')}function b(i,e={}){let{tab:r=1,joinArray:t=!1,tabSize:s=4}=e;if(typeof i=="string")return b([i],e);if(Array.isArray(i)){let o=" ".repeat(r*s),
|
|
2
|
-
`):
|
|
3
|
-
------------------------`),console.log(f),console.log("------------------------"));let g="",x="",Q=v=>v?.replace(/(([ \t]*)#.*$)/gm,"")?.replace(/^([ \t])*|([ \t])*$/gm,"")?.split(/\r?\n/)?.filter(F=>F.length),pe=v=>v.match(/RegExp[ \s]*\([ \s]*['"`](?<regex>.*)['"`][ \s]*,[ \s]*['"`](?<flags>.*)['"`][ \s]*\)|RegExp[ \s]*\([ \s]*['"`](?<regex>.*)['"`][ \s]*\)/m),ee=(v,te,F)=>v.filter(re=>{let $=h(y.default.relative(i,y.default.resolve(re.parentPath,re.name)));for(let se of te){let X=pe(se);if($){if(X){let G=X?.groups?.regex||"",K=X?.groups?.flags||"m";if($?.match(new RegExp(G,K)))return F?(
|
|
1
|
+
"use strict";var he=Object.create;var k=Object.defineProperty;var de=Object.getOwnPropertyDescriptor;var fe=Object.getOwnPropertyNames;var ge=Object.getPrototypeOf,ue=Object.prototype.hasOwnProperty;var me=(i,e)=>{for(var r in e)k(i,r,{get:e[r],enumerable:!0})},oe=(i,e,r,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of fe(e))!ue.call(i,s)&&s!==r&&k(i,s,{get:()=>e[s],enumerable:!(t=de(e,s))||t.enumerable});return i};var O=(i,e,r)=>(r=i!=null?he(ge(i)):{},oe(e||!i||!i.__esModule?k(r,"default",{value:i,enumerable:!0}):r,i)),ye=i=>oe(k({},"__esModule",{value:!0}),i);var ve={};me(ve,{SvhostCli:()=>Y,SvhostNginx:()=>H,SvhostNginxCli:()=>Z,SvhostNginxHelper:()=>N});module.exports=ye(ve);var P=class{};var V=class{constructor(e){this.enableCommandCliLogging=!1;this.enableCommandCliLogging=e?.enableCommandCliLogging||!1}async run(){try{await this.setUpCommands(),this.enableCommandCliLogging&&(console.log("Command CLI executed successfully."),console.log("Running CLI... with args:",process.argv))}catch(e){this.enableCommandCliLogging&&console.error("Error running Command CLI:",e?.message,e),process.exit(1)}}};function A(i,e={}){let{notAllowed:r=[void 0,null,"",0],message:t=s=>`"${s}" is required.`}=e;if(typeof i=="object"&&Object.keys(i).length){Object.entries(i).forEach(([s,o])=>{if(r.includes(o))throw new Error(t(s));if(e.noEmptyArray&&Array.isArray(o)&&o.length===0)throw new Error(`${s} cannot be an empty array.`);if(e.noEmptyObject&&o instanceof Object&&Object.keys(o).length===0)throw new Error(`${s} cannot be an empty object.`)});return}throw new Error('Invalid arg passed to "validateRequired"')}function b(i,e={}){let{tab:r=1,joinArray:t=!1,tabSize:s=4}=e;if(typeof i=="string")return b([i],e);if(Array.isArray(i)){let o=" ".repeat(r*s),a=i.map(c=>`${o}${c}`);return t?a.join(`
|
|
2
|
+
`):a}else throw new Error("Argument passed to indent method should be string or string[].")}var ie=require("commander");var B=class{constructor(e){this.svhost=e}};var j=class extends P{constructor(){super(),this.helper=new B(this)}setupCommand(){let e=new ie.Command;return e.name("svhost").description("Simple Virtual Host").version("1.0.0"),e.command("nginx").description("Push secrets or variables to GitHub").option("-a, --args","Send secrets only").action(this.actionOption1),e.command("option2").description("Push secrets or variables to GitHub").option("-a, --args","Send secrets only").action(this.actionOption2),e.parseAsync(process.argv)}async actionOption1(e,r,t){console.log("option1 action executed")}async actionOption2(e,r,t){console.log("option2 action executed")}};var Y=class extends V{constructor(e){super(e)}async setUpCommands(){await new j().setupCommand()}};var E=O(require("path"));var R=O(require("fs-extra")),z=require("fs/promises"),y=O(require("path"));async function q(i){try{return await R.default.exists(i)}catch{return!1}}async function I(i){try{return(await R.default.stat(i)).isFile()}catch{return!1}}async function C(i){try{return(await R.default.stat(i)).isDirectory()}catch{return!1}}async function J(i,e){let{recursive:r=!1,filesOnly:t=!1,dirsOnly:s=!1,returnType:o="absolute",forwardSlashes:a=!1,ignorefile:c,quiet:n=!0,includeIgnorefile:p=!1}=e||{};return new Promise(async(l,d)=>{function h(m){return a?m.replace(/\\/g,"/"):m}n||console.log(`Reading directory: ${i}`,{recursive:r,filesOnly:t,dirsOnly:s,returnType:o,forwardSlashes:a,quiet:n,includeIgnorefile:p,ignorefile:c});try{if(!await q(i))return d(new Error(`Directory does not exist: ${i}`));if(!await C(i))return d(new Error(`Path is not a directory: ${i}`));let u=(await(0,z.readdir)(i,{withFileTypes:!0,recursive:r})).filter(f=>!p&&f.name===".ignore"&&y.default.resolve(i)===y.default.resolve(f.parentPath)?!1:t?f.isFile():s?f.isDirectory():!0);if(c?.data||c?.path||await q(y.default.join(i,".ignore"))){n||console.log(`Applying ignore rules from: ${c?.path||"provided data"}`);let f="";if(c?.data)f=c.data;else if(c?.path)try{f=await R.default.readFile(c.path,"utf8")}catch(g){n||console.warn(`Warning: Could not read ignorefile at ${c.path}: ${g.message}`)}else try{f=await R.default.readFile(y.default.join(i,".ignore"),"utf8")}catch(g){n||console.warn(`Warning: Could not read ignorefile at ${y.default.join(i,".ignore")}: ${g.message}`)}if(f){n||(console.log(`All .ignore data:
|
|
3
|
+
------------------------`),console.log(f),console.log("------------------------"));let g="",x="",Q=v=>v?.replace(/(([ \t]*)#.*$)/gm,"")?.replace(/^([ \t])*|([ \t])*$/gm,"")?.split(/\r?\n/)?.filter(F=>F.length),pe=v=>v.match(/RegExp[ \s]*\([ \s]*['"`](?<regex>.*)['"`][ \s]*,[ \s]*['"`](?<flags>.*)['"`][ \s]*\)|RegExp[ \s]*\([ \s]*['"`](?<regex>.*)['"`][ \s]*\)/m),ee=(v,te,F)=>v.filter(re=>{let $=h(y.default.relative(i,y.default.resolve(re.parentPath,re.name)));for(let se of te){let X=pe(se);if($){if(X){let G=X?.groups?.regex||"",K=X?.groups?.flags||"m";if($?.match(new RegExp(G,K)))return F?(n||console.log(`Included path "${$}" via Regex("${G}","${K}") Match pattern.`),!0):(n||console.log(`Ignored path "${$}" via Regex("${G}","${K}") Match pattern.`),!1)}if($?.match(new RegExp(`^${se}$`,"gm")))return F?(n||console.log(`Included path "${$}" via Match pattern.`),!0):(n||console.log(`Ignored path "${$}" via Match pattern.`),!1)}}return!F});if(f.match(/^[ \t]*#?[ \t]*EXCLUDE EXCLUDE EXCLUDE[ \t]*$/gm)&&(f.match(/^[ \t]*#[ \t]*EXCLUDE EXCLUDE EXCLUDE[ \t]*$/gm)?g=f.replace(/^[ \t]*#[ \t]*EXCLUDE EXCLUDE EXCLUDE[ \t]*.*/gms,""):x=f.replace(/.*[ \t]*EXCLUDE EXCLUDE EXCLUDE[ \t]*$/gms,"")),n||(console.log(`Include data:
|
|
4
4
|
------------------------`),console.log(x),console.log("------------------------"),console.log(`Exclude data - EXCLUDE EXCLUDE EXCLUDE:
|
|
5
|
-
------------------------`),console.log(g),console.log("------------------------")),console.log("Applying exclude and include rules from .ignore file"),console.log("Initial file count before applying ignore rules:",u.length),g){let v=Q(g);
|
|
5
|
+
------------------------`),console.log(g),console.log("------------------------")),console.log("Applying exclude and include rules from .ignore file"),console.log("Initial file count before applying ignore rules:",u.length),g){let v=Q(g);n||console.log("Exclude lines:",v),u=ee(u,v,!1)}if(x){let v=Q(x);n||console.log("Include lines:",v),u=ee(u,v,!0)}console.log("Final file count after applying ignore rules:",u.length)}}let _=y.default.resolve(i);switch(o){case"absolute":{let f=u.map(g=>{let x=y.default.join(g.parentPath,g.name);return h(x)});return l(f)}case"relative":{let f=u.map(g=>{let x=y.default.join(g.parentPath,g.name);return h(y.default.relative(_,x))});return l(f)}case"dirent":return l(u);case"all":{let f=u.map(g=>{let x=y.default.join(g.parentPath,g.name);return{name:g.name,absolutePath:h(x),relativePath:h(y.default.relative(_,x)),isFile:g.isFile(),isDirectory:g.isDirectory()}});return l(f)}default:return d(new Error(`Invalid returnType option: ${o}`))}}catch(m){d(m)}})}(async(i=!1)=>{let e=`
|
|
6
6
|
# Ignore files and directories
|
|
7
7
|
|
|
8
8
|
dir1
|
|
@@ -11,13 +11,13 @@ EXCLUDE EXCLUDE EXCLUDE
|
|
|
11
11
|
react-app.yml
|
|
12
12
|
RegExp("node-app.yml$")
|
|
13
13
|
|
|
14
|
-
`;if(i){let t=y.default.resolve("src/classes/svhost-nginx/sample/data"),s=await J(t,{recursive:!0,returnType:"relative",forwardSlashes:!0,filesOnly:!1,quiet:!1,ignorefile:{data:e}});console.log("Directory contents:",s)}})(!1);var N=class{constructor(e){this.svhostNginx=e}};function ne(i){let e=i?.date||new Date;switch(i?.format||"standard"){case"email":{let t={timeZone:"Asia/Kolkata",year:"numeric",month:"short",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1,timeZoneName:"longOffset"};return new Intl.DateTimeFormat("en-IN",t).format(e)}case"standard":{let t=e.getFullYear(),s=String(e.getMonth()+1).padStart(2,"0"),o=String(e.getDate()).padStart(2,"0"),
|
|
15
|
-
`):t}};var S=class{constructor(e){let{host:r="localhost",port:t,location:s="/",hostUri:o="/",headers:
|
|
14
|
+
`;if(i){let t=y.default.resolve("src/classes/svhost-nginx/sample/data"),s=await J(t,{recursive:!0,returnType:"relative",forwardSlashes:!0,filesOnly:!1,quiet:!1,ignorefile:{data:e}});console.log("Directory contents:",s)}})(!1);var N=class{constructor(e){this.svhostNginx=e}};function ne(i){let e=i?.date||new Date;switch(i?.format||"standard"){case"email":{let t={timeZone:"Asia/Kolkata",year:"numeric",month:"short",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1,timeZoneName:"longOffset"};return new Intl.DateTimeFormat("en-IN",t).format(e)}case"standard":{let t=e.getFullYear(),s=String(e.getMonth()+1).padStart(2,"0"),o=String(e.getDate()).padStart(2,"0"),a=String(e.getHours()).padStart(2,"0"),c=String(e.getMinutes()).padStart(2,"0"),n=String(e.getSeconds()).padStart(2,"0");return`${t}-${s}-${o} ${a}:${c}:${n}`}}}var w=require("fs/promises");var ae=require("js-yaml"),M=require("fs/promises"),ce=require("path"),T=class{constructor(){}async _readFile(e){if(!e||typeof e!="string")throw new TypeError("Path must be a non-empty string");let r=(0,ce.resolve)(e);if(!(await(0,M.stat)(r)).isFile())throw new Error(`Not a readable file: ${r}`);try{return await(0,M.readFile)(r,{encoding:"utf8"})}catch(s){let o=s;throw o.code==="EACCES"||o.code==="EPERM"?new Error(`No read permission for file: ${r}`,{cause:o}):new Error(`Error reading file: ${r}`,{cause:o})}}_resolveVars(e,r){return JSON.parse(JSON.stringify(e),(t,s)=>typeof s=="string"?s.replace(/\$\{(\w+)\}/g,(o,a)=>String(r[a])):s)}async read(e){let r=await this._readFile(e),t=(0,ae.load)(r);return this._resolveVars(t,t?.vars)}};var D=class{constructor(e){this.order=10;this.items=[];A({location:e}),this.location=e}setItem(e=""){Array.isArray(e)?this.items.push(...e):this.items.push(e)}setOrder(e){this.order=e}getData(e){let{joinArray:r=!1}=e||{},t=[];return t.push(`location ${this.location} {`),t.push(...b(this.items)),t.push("}"),r?t.join(`
|
|
15
|
+
`):t}};var S=class{constructor(e){let{host:r="localhost",port:t,location:s="/",hostUri:o="/",headers:a=new Map,resetHeader:c=!1}=e;if(A({port:t},{message:n=>`"${n}" is required in ReverseProxy constructor.`}),this.host=r,this.port=t,this.location=s,this.hostUri=o,this.resetHeader=c,!(a instanceof Map))throw new Error('"headers" must be a Map');this.headers=new Map,this.headerArgs=a,this.setDefaultHeaders()}setHost(e){this.host=e}setPort(e){this.port=e}setResetHeader(e){this.resetHeader=e,this.setDefaultHeaders()}setHeader(e,r){this.headers.set(e,r)}deleteHeader(e){this.headers.delete(e)}getHeader(e){return this.headers.get(e)}getHeaders(){return new Map(this.headers)}getHeadersList(){let e=[];for(let[r,t]of this.headers.entries())e.push(`${r} ${t};`);return e}setDefaultHeaders(e){let r=e?.reset||!1;this.headers.clear();let t=new Map;t.set("proxy_pass",`http://${this.host}:${this.port}${this.hostUri}`),r||(this.resetHeader||(t.set("proxy_set_header Host","$host"),t.set("proxy_set_header X-Real-IP","$remote_addr"),t.set("proxy_set_header X-Forwarded-Host","$http_host"),t.set("proxy_set_header X-Forwarded-Proto","$scheme"),t.set("proxy_set_header X-Forwarded-For","$proxy_add_x_forwarded_for"),t.set("proxy_cache_bypass","$http_upgrade"),t.set("proxy_http_version","1.1"),t.set("proxy_set_header Upgrade","$http_upgrade"),t.set("proxy_set_header Connection","upgrade")),this.headers=new Map([...t,...this.headerArgs]))}getData(e={}){let{joinArray:r=!1}=e,t=this.getHeadersList(),s=new D(this.location);return s.setItem(t),s.getData({joinArray:r})}};var L=class{constructor(){this.serverItems=[];this.sslItems=[];this.locationBlocks=[];this.redirectItems=[]}addServerItem(e){Array.isArray(e)?this.serverItems.push(...e):this.serverItems.push(e)}addSslItem(e){Array.isArray(e)?this.sslItems.push(...e):this.sslItems.push(e)}addLocationBlock(e=null){e&&e instanceof D&&this.locationBlocks.push(e)}addRedirectItem(e){Array.isArray(e)?this.redirectItems.push(...e):this.redirectItems.push(e)}getData(e={}){let{joinArray:r=!1}=e,t=[];if(t.push("server {"),t.push(...b(this.serverItems)),this.sslItems?.length&&(t.push(`
|
|
16
16
|
`),this.sslItems.forEach(s=>{t.push(b(s))})),this.redirectItems?.length)t.push(`
|
|
17
|
-
`),this.redirectItems.forEach(s=>{t.push(b(s))});else if(this.locationBlocks?.length){let s=this.locationBlocks.toSorted((o,
|
|
18
|
-
`):t}};var W=class{constructor(e){let{id:r,domainName:t="",tld:s="com",serverNames:o=[],redirectToFirstServer:
|
|
19
|
-
`):l})({joinArray:r})}};var H=class{constructor(e){this.helper=new N(this)}async yamlToVhostInstances(e,r){let{quiet:t=!1}=r||{};try{let o=await new T().read(e),
|
|
17
|
+
`),this.redirectItems.forEach(s=>{t.push(b(s))});else if(this.locationBlocks?.length){let s=this.locationBlocks.toSorted((o,a)=>o.order-a.order);t.push(""),s.forEach(o=>{t.push(""),t.push(...b(o.getData()))})}return t.push("}"),r?t.join(`
|
|
18
|
+
`):t}};var W=class{constructor(e){let{id:r,domainName:t="",tld:s="com",serverNames:o=[],redirectToFirstServer:a=!0,appType:c="reverseProxy",reverseProxies:n=new Map,ssl:p=!1,sslCertificateName:l,redirectToHttps:d=!1,rootDirectory:h="/var/www/html",http_port:m=80,https_port:u="443 ssl",meta:_}=e||{};if(A({id:r,domainName:t,tld:s,serverNames:o,rootDirectory:h,appType:c,http_port:m,https_port:u},{noEmptyArray:!0,noEmptyObject:!0}),this.reverseProxies=n,!Array.isArray(o)||o.length===0)throw new Error('"serverNames" must be a non-empty array of server-names');this.id=r,this.domainName=t,this.tld=s,this.serverNames=o,this.redirectToFirstServer=a,this.appType=c,this.ssl=p,this.sslCertificateName=l??`${t}.${s}`,this.redirectToHttps=d,this.rootDirectory=h,this.http_port=m,this.https_port=u,this.meta=_??{},this.meta.group=this.meta?.group??"default"}setReverseProxy(e){if(e instanceof S&&e?.location){if(this.reverseProxies)this.reverseProxies.set(e?.location,e);else{let r=`Error: Server ID: ${this.id} - reverseProxies Map is not initialized.`;throw console.error(r),new Error(r)}return}console.warn("Error: Server ID: ${this.id} - Invalid reverseProxy passed",JSON.stringify(e))}getLocationBlocks(){let e=[];if(this.reverseProxies?.size&&this.reverseProxies instanceof Map)this.reverseProxies?.forEach(r=>{let t=new D(r.location);t.setItem(r.getHeadersList()),e.push(t)});else{let r=new D("/");r.setItem("try_files $uri $uri/ =404;"),e.push(r)}return e}createServerBlock(e={}){let{joinArray:r=!1,serverDirectives:t=[],addSslCertificates:s=!1,redirects:o=[],locationBlocks:a=[]}=e,c=new L;if(t?.length&&t.forEach(n=>{c.addServerItem(n)}),s){let n=[];if(this.ssl===void 0)throw new Error(`Please provide/set valid value for "this.ssl" in 'Vhost' constructor, if you want to redirect to HTTPS`);if(this.ssl===!0)c.addSslItem([`ssl_certificate /etc/letsencrypt/live/${this.sslCertificateName}/fullchain.pem;`,`ssl_certificate_key /etc/letsencrypt/live/${this.sslCertificateName}/privkey.pem;`,...n]);else if(this.ssl!==!1)if(typeof this.ssl=="object")c.addSslItem([`ssl_certificate ${this.ssl?.crt};`,`ssl_certificate_key ${this.ssl?.key};`,...n]);else throw new Error("Something Went Wrong in SSL Directives.")}if(o?.length)c.addRedirectItem(o);else{let p=[...this.getLocationBlocks(),...a].sort((l,d)=>l?.order-d?.order);p?.length&&p.forEach(l=>{c.addLocationBlock(l)})}return c.getData({joinArray:r})}getIndexDirective(){let e="index index.html index.htm";switch(this.appType){case"reverseProxy":return`${e};`;case"html":return`${e};`;case"react":return`${e};`;case"node":return`${e};`;case"react-node":return`${e};`;case"php":return`index.php ${e};`;case"python":return`index.py ${e};`;default:return`${e}; # Default`}}getServerDirectives(e={}){let{serverNames:r,redirect:t=!1,port:s=this.http_port}=e,o=[`listen ${s};`,`listen [::]:${s};`,"",`server_name ${r?.join(" ")};`];return t||o.push("",this.getIndexDirective(),`root ${this.rootDirectory};`),o}_generateFullServerBlock(e){let{redirectHttps:r=!1,redirectWWW:t=!1,port:s,onlyFirstServerName:o=!1}=e||{},a=[];if(r||t){let p=r||s===this.https_port?"s":"",l=t?this.serverNames?.[0]:"$host";a.push(`return 301 http${p}://${l}$request_uri;`)}let c=t?this.serverNames?.slice(1):this.serverNames;return this.createServerBlock({serverDirectives:this.getServerDirectives({serverNames:o?[c?.[0]]:c,port:s,redirect:r||t}),addSslCertificates:!!(this.ssl&&s===this.https_port),redirects:a?.length?a:void 0})}getData(e){let{joinArray:r=!1}=e??{},t=[],s=this.serverNames,o=this.redirectToFirstServer&&this.serverNames?.length>1?this.serverNames?.[0]:"";return this.redirectToHttps?o?(t.push(this._generateFullServerBlock({port:this.http_port,redirectHttps:!0,redirectWWW:!0})),t.push(this._generateFullServerBlock({port:this.https_port,redirectHttps:!0,redirectWWW:!0})),t.push(this._generateFullServerBlock({port:this.http_port,redirectHttps:!0,redirectWWW:!1,onlyFirstServerName:!0})),t.push(this._generateFullServerBlock({port:this.https_port,redirectHttps:!1,redirectWWW:!1,onlyFirstServerName:!0}))):(t.push(this._generateFullServerBlock({port:this.http_port,redirectHttps:!0,redirectWWW:!1})),t.push(this._generateFullServerBlock({port:this.https_port,redirectHttps:!1,redirectWWW:!1}))):o?(t.push(this._generateFullServerBlock({port:this.http_port,redirectHttps:!1,redirectWWW:!0})),t.push(this._generateFullServerBlock({port:this.https_port,redirectHttps:!1,redirectWWW:!0})),t.push(this._generateFullServerBlock({port:this.http_port,redirectHttps:!1,redirectWWW:!1,onlyFirstServerName:!0})),t.push(this._generateFullServerBlock({port:this.https_port,redirectHttps:!1,redirectWWW:!1,onlyFirstServerName:!0}))):(t.push(this._generateFullServerBlock({port:this.http_port,redirectHttps:!1,redirectWWW:!1})),this.ssl&&t.push(this._generateFullServerBlock({port:this.https_port,redirectHttps:!1,redirectWWW:!1}))),((n={})=>{let{joinArray:p=!1}=n,l=[];return t?.map((d,h)=>{l.push(...d),h+1<t?.length&&l.push("")}),p?l?.join(`
|
|
19
|
+
`):l})({joinArray:r})}};var H=class{constructor(e){this.helper=new N(this)}async yamlToVhostInstances(e,r){let{quiet:t=!1}=r||{};try{let o=await new T().read(e),a=o?.vhosts||[],c=o?.meta||{};t||(console.log(`YAML Config Data : -------- Total VHosts in file "${e}":`,a.length),console.log("VHosts Default Meta:",{defaultMeta:c}));for(let p of a)t||(console.log("VHost Data:",p),console.log("VHost reverseProxies:",p?.reverseProxies));let n=[];return a.forEach(p=>{let l=structuredClone(p);l.meta={...c,...l.meta??{}},delete l.reverseProxies,t||console.log("New VHost Data (without reverseProxies):",l);let d=new W(l);n.push(d),t||(console.log("Processing VHost:",d.id),console.log("vhostData?.reverseProxies:",p?.reverseProxies)),[...p?.reverseProxies??[]].forEach(h=>{let[[m,u]]=Object.entries(h??{});t||console.log("Reverse Proxy Data:",{pathKey:m,proxyConfig:u}),u.location=m;let _=new S(u);d.setReverseProxy(_)})}),t||console.log(`Loaded (${n.length}) vhost(s) from YAML file: "${e}"`),n}catch(s){throw new Error(`Error reading YAML file "${e}": ${s?.message}`,{cause:s})}}async getVhostInstanceArray(e,r){let{quiet:t=!1}=r||{};try{return I(e)?await this.yamlToVhostInstances(e,{quiet:t}):(t||console.warn(`The path "${e}" is not a valid file.`),null)}catch(s){throw console.error("-----------------------------------"),console.error(`Error Message: ${s?.message}`),console.error("----------------- Complete Error ------------------"),console.error(s),console.error("-----------------------------------"),new Error(`YAML File Error, while importing "${e}": ${s?.message}`)}}async getVhostInstances(e,r){let{quiet:t=!1}=r||{};try{let s=await J(e,{recursive:!0,filesOnly:!0,returnType:"relative",forwardSlashes:!0,quiet:t});t||(console.log(4444,{quiet:t},{files:s}),console.log(s));let o=[];for(let a of s)if(a.endsWith(".yml")||a.endsWith(".yaml")){let c=E.default.resolve(e,a),n=await this.getVhostInstanceArray(c,{quiet:t});n?.length&&o.push(...n)}return o}catch(s){throw new Error(`Error in "getVhostInstances()" from directory "${e}": Error:"${s.message}"`,{cause:s})}}async ensureDir(e,r){let{quiet:t=!1,directoryName:s="Output"}=r||{};if(!await C(e))if(await C(E.default.dirname(e)))t||console.log(`## ${s} directory does not exist. Creating directory: "${e}"`),await(0,w.mkdir)(e,{recursive:!0});else throw new Error(`## ${s} directory does not exist: ${e}`)}getVhostConfigFileData(e,r){let{joinArray:t=!1}=r||{},s=e.getData()??[],o=e.reverseProxies?.size?[...e.reverseProxies].map(([c,n])=>`${c} => ${n?.host}:${n?.port}${n?.hostUri}`).join(", "):"",a=[`# Created at: ${ne()}`,`# ID: ${e.id}`,`# HOST (s): ${o}`,`# GROUP: ${e?.meta?.group}`,"###################################",`
|
|
20
20
|
|
|
21
|
-
`,...s];return t?
|
|
22
|
-
`):
|
|
21
|
+
`,...s];return t?a.join(`
|
|
22
|
+
`):a}async generateVhostConfig(e){let{vhosts:r,destDir:t,quiet:s=!1}=e;await this.ensureDir(t,{quiet:s,directoryName:"Destination"});for(let o of r){let a=this.getVhostConfigFileData(o,{joinArray:!0}),c=o?.meta?.confFileName??`${o?.meta?.group}--${o.id}.conf`,n=E.default.resolve(t,c);s||console.log(`Generating vhost config file: "${n}" ...`,a);try{await(0,w.writeFile)(n,a)}catch(p){throw new Error(`Error writing vhost config file "${n}": ${p?.message}`,{cause:p})}}}async generate(e){let{file:r,srcDir:t,outputDir:s,quiet:o=!1,cleanDir:a=!1,createEmptyFile:c=!1,nginxConfFile:n,subConfdDir:p=!0}=e;try{if(!r&&!t)throw new Error('Either "file" or "srcDir" must be provided.');if(r&&!await I(r))throw new Error(`The specified file does not exist: ${r}`);if(t&&!await C(t))throw new Error(`The specified source directory does not exist: ${t}`);await this.ensureDir(s,{quiet:o,directoryName:"output"}),p&&await this.ensureDir(E.default.resolve(s,"conf.d"),{quiet:o,directoryName:"output/conf.d"});let l=[];if(o||console.log(1111,{file:r,srcDir:t}),r){let h=await this.getVhostInstanceArray(r,{quiet:o});h?.length&&l.push(...h)}if(t){let h=await this.getVhostInstances(t,{quiet:o});o||(console.log({"vhostInstances Count":h.length}),console.log(3333,h)),l.push(...h)}if(a){let h=(await(0,w.readdir)(s)).map(m=>E.default.resolve(s,m));await Promise.all(h.map(m=>(0,w.rm)(m,{recursive:!0,force:!0})))}if(c&&await(0,w.writeFile)(E.default.resolve(s,".empty"),""),n){let h=E.default.resolve(n);await q(h)&&await(0,w.copyFile)(h,E.default.resolve(s,"nginx.conf"))}let d=p?E.default.resolve(s,"conf.d"):s;o||(console.log(`Total vhosts to generate: ${l.length} . Output Directory: "${s}"`),console.log({subConfdDir:p}),console.log(`conf.d Directory: "${d}"`)),await this.generateVhostConfig({vhosts:l,destDir:d,quiet:o}),o||console.log(`Generated (${l.length}) vhost configuration file(s) in "${s}".`)}catch(l){throw new Error(`Error in generate method: "${l.message}"`,{cause:l})}}};var le=require("commander");var U=O(require("path"));var Z=class extends P{constructor(){super();this.quiet=!0}setupCommand(){let r=new le.Command;return r.name("svhost-nginx").description("Nginx - Simple Virtual Host").version("1.0.0"),r.description("Generate Nginx configuration for a virtual host").option("-f, --src-file <srcFile>","Source file for configuration").option("--src-dir <srcDir>","Source directory for configuration").requiredOption("-d, --dest-dir <destDir>","Destination directory for configuration").action(this.actionDefault.bind(this)),r.parseAsync(process.argv)}async run(r){let{quiet:t=!0}=r||{};this.quiet=t,await this.setupCommand()}async actionDefault(r,t,s){let{srcFile:o,srcDir:a,destDir:c}=r;if(this.quiet||console.log("Commander:",{name:r,command:s}),o&&a)throw new Error("Please provide either --src-file or --src-dir, not both.");if(!o&&!a)throw new Error("Please provide either --src-file or --src-dir.");let n=U.default.resolve(o||""),p=U.default.resolve(a||""),l=U.default.resolve(c);if(this.quiet||console.table({"Source File":n,"Source Directory":p,"Destination Directory":l}),o&&!await I(o))throw new Error(`Source file does not exist: "${o}"`);if(a&&!await C(a))throw new Error(`Source directory does not exist: "${a}"`);console.log("Generating Nginx configuration ...");let d=new H;o?await d.generate({file:n,outputDir:l,quiet:this.quiet,cleanDir:!0}):a&&await d.generate({srcDir:p,outputDir:l,quiet:this.quiet,cleanDir:!0}),this.quiet||(console.log("option1 action executed"),console.log("Name:",r,typeof r))}};0&&(module.exports={SvhostCli,SvhostNginx,SvhostNginxCli,SvhostNginxHelper});
|
|
23
23
|
//# sourceMappingURL=index.js.map
|