UNPKG

@ycmd/creds

Version:

LSK.js CLI Creds is the easiest way to manage GitHub / Gitlab secrets and credentials

25 lines (20 loc) 10.6 kB
'use strict'; var fs = require('fs'); var err = require('@lsk4/err'); var fishbird = require('fishbird'); var promises = require('fs/promises'); var path = require('path'); var log = require('@lsk4/log'); var stringify = require('@lsk4/stringify'); var F = require('axios'); var S = require('libsodium-wrappers'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var F__default = /*#__PURE__*/_interopDefault(F); var S__default = /*#__PURE__*/_interopDefault(S); var T=Object.defineProperty;var n=(s,e)=>T(s,"name",{value:e,configurable:!0}),y=(s=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(s,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):s)(function(s){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+s+'" is not supported')});async function k(s){let e=await promises.readdir(s,{withFileTypes:!0});return (await fishbird.map(e,async r=>r.isDirectory()?[{name:r.name,dir:path.resolve(s),filename:path.resolve(s,r.name)},...await k(path.resolve(s,r.name))]:[])).flat()}n(k,"getDirs");var j=log.createLogger("creds");var f=class{static{n(this,"Service");}client;log=log.createLogger(this.constructor.name);constructor(e){this.assign(e),this.checkConfig(),this.client=this.createClient(e.clientOptions);}createClient(e={}){return F__default.default.create(e)}assign(e){Object.assign(this,e);}checkConfig(){throw new err.Err("NOT_IMPLEMENTED","checkConfig method not implemented")}getServiceHostname(){throw new err.Err("NOT_IMPLEMENTED","getServiceHostname method not implemented")}getProjectUrl(){throw new err.Err("NOT_IMPLEMENTED","getProjectUrl method not implemented")}getProjectCICDSettingURL(){throw new err.Err("NOT_IMPLEMENTED","getProjectCICDSettingURL method not implemented")}getProjectPath(){let e=this.projectPath;if(!e)throw new err.Err("!projectPath");return e}getProjectId(){return this.projectId}getProjectCredsUrl(){let e=this.projectCredsUrl;if(!e)throw new err.Err("!projectCredsUrl");return e}getProjectCredsOwner(){let e=this.projectCredsOwner;if(!e)throw new err.Err("!projectCredsOwner");return e}async uploadSecret(e,t){throw new err.Err("NOT_IMPLEMENTED","uploadSecret method not implemented")}async uploadVariable(e,t){throw new err.Err("NOT_IMPLEMENTED","uploadVariable method not implemented")}async removeOldHooks(){}async uploadHook(e){}async uploadHooks(e){if(!e)throw new err.Err("!env");let{hooks:t=[]}=e;try{await this.removeOldHooks();}catch(r){this.log.error("[ERR] Old hooks removing failed:",err.Err.getMessage(r));}await fishbird.map(t,async(r,o)=>{try{await this.uploadHook(r),this.log.info(`[OK] Hook ${o} uploaded`);}catch(a){this.log.error(`[ERR] Hook ${o} not uploaded:`,err.Err.getMessage(a));}});}async uploadAll(e){if(!e)throw new err.Err("!env");let{secrets:t={},variables:r={},files:o=[]}=e;await this.uploadHooks(e),await fishbird.map(Object.entries(t),async([a,i])=>{try{await this.uploadSecret(a,i),this.log.info(`[OK] Secret ${a} uploaded`);}catch(c){this.log.error(`[ERR] Secret ${a} not uploaded as secret, because`,err.Err.getMessage(c)),this.log.trace(c);}}),await fishbird.map(Object.entries(r),async([a,i])=>{try{await this.uploadVariable(a,i),this.log.info(`[OK] Variable ${a} uploaded`);}catch(c){this.log.error(`[ERR] Variable ${a} not uploaded as variable, because`,err.Err.getMessage(c)),this.log.trace(c);}}),await fishbird.map(Object.values(o),async({name:a,credType:i,content:c})=>{let h=a,g=c;try{if(i==="variable")await this.uploadVariable(h,g);else if(i==="secret")await this.uploadSecret(h,g);else if(i==="skip"){this.log.debug(`[SKIP] File ${h} uploaded as ${i}`);return}else throw new err.Err("unknown credType",{credType:i});this.log.info(`[OK] File ${h} uploaded as ${i}`);}catch(w){this.log.error(`[ERR] File ${h} not uploaded as ${i}, because`,err.Err.getMessage(w)),this.log.trace(w);}});}};var C=class extends f{static{n(this,"GithubService");}projectName;projectPath;projectCredsUrl;projectCredsOwner;token;server;log=log.createLogger(this.constructor.name);constructor(e){super(e),this.assign(e),this.checkConfig(),this.client=this.createClient(e.clientOptions);}checkConfig(){if(!this.projectName)throw new err.Err("!projectName");if(!this.projectPath)throw new err.Err("!projectPath");if(!this.projectCredsUrl)throw new err.Err("!projectCredsUrl");if(!this.projectCredsOwner)throw new err.Err("!projectCredsOwner");if(!this.token)throw new err.Err("!token")}createClient(e={}){let r=`https://${this.server||"api.github.com"}/repos/${this.getProjectPath()}`;return F__default.default.create({baseURL:r,headers:{Accept:"application/vnd.github+json",Authorization:`Bearer ${this.token}`,"X-GitHub-Api-Version":"2022-11-28"},...e})}getServiceHostname(){return "github.com"}getProjectPath(){return this.projectPath}getProjectUrl(){return `https://${this.getServiceHostname()}/${this.getProjectPath()}`}getProjectCICDSettingURL(){return `${this.getProjectUrl()}/settings/secrets/actions`}async uploadSecret(e,t){let{data:r}=await this.client({method:"get",url:"/actions/secrets/public-key"}).catch(w=>{throw new err.Err(w.message,{data:w?.response?.data})}),o=typeof t=="string"?t:t.value;if(!r?.key)throw new err.Err("!publicKey");if(!r?.key_id)throw new err.Err("!publicKeyId");await S__default.default.ready;let a=S__default.default,i=a.from_base64(r.key,a.base64_variants.ORIGINAL),c=a.from_string(o),h=a.crypto_box_seal(c,i),g=a.to_base64(h,a.base64_variants.ORIGINAL);await this.client({method:"put",url:`/actions/secrets/${e}`,data:{encrypted_value:g,key_id:r.key_id}});}async uploadVariable(e,t){let r=typeof t=="string"?t:t.value,{data:o,status:a}=await this.client({method:"get",url:`/actions/variables/${e}`}).catch(i=>i?.response);a===404&&await this.client({method:"post",url:"/actions/variables",data:{name:e,value:r}}),a===200&&o.name.toLowerCase()===e.toLowerCase()&&await this.client({method:"patch",url:`/actions/variables/${e}`,data:{name:e,value:r}});}uploadHook(){throw new err.Err("Github hooks not supported yet")}};var $=!0,P=class extends f{static{n(this,"GitlabService");}projectId;projectName;projectPath;projectCredsUrl;projectCredsOwner;token;server;force=!0;log=log.createLogger(this.constructor.name);constructor(e){super(e),this.assign(e),this.checkConfig(),this.client=this.createClient(e.clientOptions);}checkConfig(){if(!this.projectId)throw new err.Err("!projectId");if(!this.server)throw new err.Err("!server");if(!this.projectName)throw new err.Err("!projectName");if(!this.projectPath)throw new err.Err("!projectPath");if(!this.projectCredsUrl)throw new err.Err("!projectCredsUrl");if(!this.projectCredsOwner)throw new err.Err("!projectCredsOwner");if(!this.token)throw new err.Err("!token")}createClient(e={}){return F__default.default.create({baseURL:`https://${this.server}/api/v4/projects/${this.projectId}`,headers:{"PRIVATE-TOKEN":this.token},...e})}getServiceHostname(){return this.server}getProjectUrl(){return `https://${this.getServiceHostname()}/${this.projectPath}`}getProjectCICDSettingURL(){return `${this.getProjectUrl()}/-/settings/ci_cd`}async uploadVariableOrSecret(e,t,r={}){let o=typeof t=="string"?t:t.value,a=t?.type||r?.type||"file",i=!!(t?.protected??r?.protected??!1),{data:c}=await this.client({method:"get",url:`/variables/${e}`}).catch(h=>{return {data:{value:"@lskjs/creds"}}});if(c.value&&c.value.indexOf("@lskjs/creds")===-1&&!$){this.log.warn(`[IGNORE] Project ${this.projectId} ${e}`);return}await this.client({method:"delete",url:`/variables/${e}`}).catch(()=>{}),await this.client({method:"post",url:"/variables",data:{key:e,value:o,variable_type:a,protected:i,...r}});}async uploadSecret(e,t,r={}){return this.uploadVariableOrSecret(e,t,{type:"file",protected:!!(r.protected??!0)})}async uploadVariable(e,t,r={}){return this.uploadVariableOrSecret(e,t,{type:"env_var",protected:!!(r.protected??!1)})}async uploadEnv(){throw this.log.warn("GitLab uploading env doesn't supported"),new err.Err("NOT_IMPLEMENTED")}async removeOldHooks(){let{data:e}=await this.client({method:"get",url:"/hooks"}).catch(t=>{return {data:{value:"@lskjs/creds"}}});await fishbird.map(e,async({id:t})=>{await this.client({method:"delete",url:`/hooks/${t}`});});}async uploadHook(e){await this.client({method:"post",url:"/hooks",data:e});}};async function N(s,{removeCache:e}={}){try{let t=y(s);return e&&delete y.cache[y.resolve(s)],t}catch(t){if(err.Err.getCode(t)==="MODULE_NOT_FOUND")throw new err.Err(`${s} not found`,t);if(err.Err.getCode(t).startsWith("Dynamic require of")||err.Err.getCode(t).startsWith("ReferenceError: module is not defined in ES module scope"))try{return await import(s)}catch(o){throw err.Err.getCode(o)==="ERR_MODULE_NOT_FOUND"?new err.Err(`${s} not found`,o):new err.Err("importErr",o)}throw new err.Err("requireErr",t)}}n(N,"importRequire");async function U(s){let e=`${s}/config.js`,t=await N(e);return {path:e,config:t.default||t}}n(U,"loadConfig");async function L(s,e={}){let{path:t,config:r}=await U(s),o=r.service?.serviceName;if(!o)throw new err.Err("!serviceName",{data:{configPath:t}});let a,i={...r.service,...e,config:r};if(o==="github")a=new C(i);else if(o==="gitlab")a=new P(i);else throw new err.Err("incorrect serviceName",{serviceName:o});return a}n(L,"createService");async function _(s,e={}){let t=e.log||j,r=e.buildDir||`${s}/build`,o=await L(s,e);await promises.unlink(`${r}`).catch(()=>{}),await promises.mkdir(r,{recursive:!0});let{config:a}=o,{files:i=[]}=a;await fishbird.mapSeries(i,async c=>{let{filename:h,handler:g}=c,w=await g(c,a),{credType:E,name:O}=c,R=stringify.getComment({filename:h,values:[["File type",c.type],["Cred type",E],["Cred name",O],["Server",o.getServiceHostname()],["Project",o.getProjectPath()],["Project ID",o.getProjectId()],["Project Url",o.getProjectUrl()],["CI/CD Setting",o.getProjectCICDSettingURL()]],footer:o.getProjectCredsUrl()&&` Auto generated by ${o.getProjectCredsUrl()} If you want to change something, please contact admin repo: ${o.getProjectCredsOwner()}. `.trim()}),M=c.format||c.type,I=`${r}/${h}`,{status:H}=await stringify.jsonToFile(I,w,{format:M,compare:!e.force,comment:R}),x=path.relative(process.cwd(),I);t.info(`[${H}] ${o.getProjectPath()} (${O})[${E}] => ${x}`);});}n(_,"build");async function wt(s,e={}){let t=await k(s),r=(await fishbird.map(t,async o=>{let{filename:a}=o;return await fs.existsSync(`${a}/index.js`)?o:null})).filter(Boolean);return fishbird.mapSeries(r,async({filename:o})=>{await _(o,e).catch(a=>{j.error(`Build error ${o}: `,err.Err.getMessage(a)),j.error(a);});})}n(wt,"buildDeep"); exports.buildDeep = wt; //# sourceMappingURL=out.js.map //# sourceMappingURL=buildDeep.js.map