@ycmd/creds
Version:
LSK.js CLI Creds is the easiest way to manage GitHub / Gitlab secrets and credentials
15 lines (13 loc) • 9.44 kB
JavaScript
import { existsSync } from 'node:fs';
import { Err } from '@lsk4/err';
import { map, mapSeries } from 'fishbird';
import { readdir } from 'fs/promises';
import { resolve } from 'path';
import { createLogger } from '@lsk4/log';
import { readFile } from 'node:fs/promises';
import K from 'axios';
import $ from 'libsodium-wrappers';
var M=Object.defineProperty;var c=(s,e)=>M(s,"name",{value:e,configurable:!0}),v=(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 E(s){let e=await readdir(s,{withFileTypes:!0});return (await map(e,async r=>r.isDirectory()?[{name:r.name,dir:resolve(s),filename:resolve(s,r.name)},...await E(resolve(s,r.name))]:[])).flat()}c(E,"getDirs");var O=createLogger("creds");var j=class{static{c(this,"Service");}client;log=createLogger(this.constructor.name);constructor(e){this.assign(e),this.checkConfig(),this.client=this.createClient(e.clientOptions);}createClient(e={}){return K.create(e)}assign(e){Object.assign(this,e);}checkConfig(){throw new Err("NOT_IMPLEMENTED","checkConfig method not implemented")}getServiceHostname(){throw new Err("NOT_IMPLEMENTED","getServiceHostname method not implemented")}getProjectUrl(){throw new Err("NOT_IMPLEMENTED","getProjectUrl method not implemented")}getProjectCICDSettingURL(){throw new Err("NOT_IMPLEMENTED","getProjectCICDSettingURL method not implemented")}getProjectPath(){let e=this.projectPath;if(!e)throw new Err("!projectPath");return e}getProjectId(){return this.projectId}getProjectCredsUrl(){let e=this.projectCredsUrl;if(!e)throw new Err("!projectCredsUrl");return e}getProjectCredsOwner(){let e=this.projectCredsOwner;if(!e)throw new Err("!projectCredsOwner");return e}async uploadSecret(e,t){throw new Err("NOT_IMPLEMENTED","uploadSecret method not implemented")}async uploadVariable(e,t){throw new Err("NOT_IMPLEMENTED","uploadVariable method not implemented")}async removeOldHooks(){}async uploadHook(e){}async uploadHooks(e){if(!e)throw new Err("!env");let{hooks:t=[]}=e;try{await this.removeOldHooks();}catch(r){this.log.error("[ERR] Old hooks removing failed:",Err.getMessage(r));}await map(t,async(r,i)=>{try{await this.uploadHook(r),this.log.info(`[OK] Hook ${i} uploaded`);}catch(o){this.log.error(`[ERR] Hook ${i} not uploaded:`,Err.getMessage(o));}});}async uploadAll(e){if(!e)throw new Err("!env");let{secrets:t={},variables:r={},files:i=[]}=e;await this.uploadHooks(e),await map(Object.entries(t),async([o,a])=>{try{await this.uploadSecret(o,a),this.log.info(`[OK] Secret ${o} uploaded`);}catch(l){this.log.error(`[ERR] Secret ${o} not uploaded as secret, because`,Err.getMessage(l)),this.log.trace(l);}}),await map(Object.entries(r),async([o,a])=>{try{await this.uploadVariable(o,a),this.log.info(`[OK] Variable ${o} uploaded`);}catch(l){this.log.error(`[ERR] Variable ${o} not uploaded as variable, because`,Err.getMessage(l)),this.log.trace(l);}}),await map(Object.values(i),async({name:o,credType:a,content:l})=>{let h=o,g=l;try{if(a==="variable")await this.uploadVariable(h,g);else if(a==="secret")await this.uploadSecret(h,g);else if(a==="skip"){this.log.debug(`[SKIP] File ${h} uploaded as ${a}`);return}else throw new Err("unknown credType",{credType:a});this.log.info(`[OK] File ${h} uploaded as ${a}`);}catch(m){this.log.error(`[ERR] File ${h} not uploaded as ${a}, because`,Err.getMessage(m)),this.log.trace(m);}});}};var k=class extends j{static{c(this,"GithubService");}projectName;projectPath;projectCredsUrl;projectCredsOwner;token;server;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("!projectName");if(!this.projectPath)throw new Err("!projectPath");if(!this.projectCredsUrl)throw new Err("!projectCredsUrl");if(!this.projectCredsOwner)throw new Err("!projectCredsOwner");if(!this.token)throw new Err("!token")}createClient(e={}){let r=`https://${this.server||"api.github.com"}/repos/${this.getProjectPath()}`;return K.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(m=>{throw new Err(m.message,{data:m?.response?.data})}),i=typeof t=="string"?t:t.value;if(!r?.key)throw new Err("!publicKey");if(!r?.key_id)throw new Err("!publicKeyId");await $.ready;let o=$,a=o.from_base64(r.key,o.base64_variants.ORIGINAL),l=o.from_string(i),h=o.crypto_box_seal(l,a),g=o.to_base64(h,o.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:i,status:o}=await this.client({method:"get",url:`/actions/variables/${e}`}).catch(a=>a?.response);o===404&&await this.client({method:"post",url:"/actions/variables",data:{name:e,value:r}}),o===200&&i.name.toLowerCase()===e.toLowerCase()&&await this.client({method:"patch",url:`/actions/variables/${e}`,data:{name:e,value:r}});}uploadHook(){throw new Err("Github hooks not supported yet")}};var P=!0,C=class extends j{static{c(this,"GitlabService");}projectId;projectName;projectPath;projectCredsUrl;projectCredsOwner;token;server;force=!0;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("!projectId");if(!this.server)throw new Err("!server");if(!this.projectName)throw new Err("!projectName");if(!this.projectPath)throw new Err("!projectPath");if(!this.projectCredsUrl)throw new Err("!projectCredsUrl");if(!this.projectCredsOwner)throw new Err("!projectCredsOwner");if(!this.token)throw new Err("!token")}createClient(e={}){return K.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 i=typeof t=="string"?t:t.value,o=t?.type||r?.type||"file",a=!!(t?.protected??r?.protected??!1),{data:l}=await this.client({method:"get",url:`/variables/${e}`}).catch(h=>{return {data:{value:"@lskjs/creds"}}});if(l.value&&l.value.indexOf("@lskjs/creds")===-1&&!P){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:i,variable_type:o,protected:a,...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("NOT_IMPLEMENTED")}async removeOldHooks(){let{data:e}=await this.client({method:"get",url:"/hooks"}).catch(t=>{return {data:{value:"@lskjs/creds"}}});await 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=v(s);return e&&delete v.cache[v.resolve(s)],t}catch(t){if(Err.getCode(t)==="MODULE_NOT_FOUND")throw new Err(`${s} not found`,t);if(Err.getCode(t).startsWith("Dynamic require of")||Err.getCode(t).startsWith("ReferenceError: module is not defined in ES module scope"))try{return await import(s)}catch(i){throw Err.getCode(i)==="ERR_MODULE_NOT_FOUND"?new Err(`${s} not found`,i):new Err("importErr",i)}throw new Err("requireErr",t)}}c(N,"importRequire");async function S(s){let e=`${s}/config.js`,t=await N(e);return {path:e,config:t.default||t}}c(S,"loadConfig");async function _(s,e={}){let{path:t,config:r}=await S(s),i=r.service?.serviceName;if(!i)throw new Err("!serviceName",{data:{configPath:t}});let o,a={...r.service,...e,config:r};if(i==="github")o=new k(a);else if(i==="gitlab")o=new C(a);else throw new Err("incorrect serviceName",{serviceName:i});return o}c(_,"createService");async function D(s,e){let t=e.buildDir||`${s}/build`,r=await _(s,e),{config:i}=r,{files:o=[],variables:a,secrets:l,hooks:h}=i,g=await map(o,async m=>{let{filename:L}=m,R=await readFile(`${t}/${L}`).then(U=>U.toString());return {...m,content:R}});await r.uploadAll({files:g,variables:a,secrets:l,hooks:h});}c(D,"upload");async function it(s,e={}){let t=await E(s),r=(await map(t,async i=>{let{filename:o}=i;return await existsSync(`${o}/index.js`)?i:null})).filter(Boolean);return mapSeries(r,async({filename:i})=>{await D(i,e).catch(o=>{O.error(`Build error ${i}: `,Err.getMessage(o)),O.error(o);});})}c(it,"uploadDeep");
export { it as uploadDeep };
//# sourceMappingURL=out.js.map
//# sourceMappingURL=uploadDeep.js.map