@sinch/cli 0.2.1-beta.0 → 0.2.1

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.
Files changed (2) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var Ao=Object.create;var Rt=Object.defineProperty;var Eo=Object.getOwnPropertyDescriptor;var xo=Object.getOwnPropertyNames;var Do=Object.getPrototypeOf,jo=Object.prototype.hasOwnProperty;var Q=(s,e)=>()=>(s&&(e=s(s=0)),e);var R=(s,e)=>()=>(e||s((e={exports:{}}).exports,e),e.exports),ut=(s,e)=>{for(var n in e)Rt(s,n,{get:e[n],enumerable:!0})},Vn=(s,e,n,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of xo(e))!jo.call(s,o)&&o!==n&&Rt(s,o,{get:()=>e[o],enumerable:!(i=Eo(e,o))||i.enumerable});return s};var h=(s,e,n)=>(n=s!=null?Ao(Do(s)):{},Vn(e||!s||!s.__esModule?Rt(n,"default",{value:s,enumerable:!0}):n,s)),M=s=>Vn(Rt({},"__esModule",{value:!0}),s);var zt=R((Sa,Ro)=>{Ro.exports={name:"@sinch/cli",version:"0.2.1-beta.0",description:"Official Sinch CLI - Manage all Sinch products from your terminal",main:"dist/index.js",bin:{sinch:"bin/sinch"},scripts:{start:"tsx src/index.ts",dev:"tsx watch src/index.ts",build:"tsc && node scripts/post-build.js","build:prod":"tsup src/index.ts --format cjs --dts --clean --minify",typecheck:"tsc --noEmit",test:"jest --config jest.config.js && jest --config tests/e2e/jest.config.js","test:unit":"jest --config jest.config.js","test:e2e":"jest --config tests/e2e/jest.config.js","test:e2e:staging":"jest --config tests/e2e/jest.config.js --env=staging",prepublishOnly:"npm run build:prod",format:"prettier --write .","format:check":"prettier --check ."},keywords:[],author:"Sinch <support@sinch.com> (https://www.sinch.com)",license:"MIT",private:!1,publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},homepage:"https://www.sinch.com/products/apis/voice/",files:["dist/","bin/","README.md","LICENSE"],dependencies:{"@inquirer/prompts":"^8.2.0","@sinch/fax":"^1.0.0","@sinch/sdk-core":"^1.2.1","adm-zip":"^0.5.10",axios:"^1.13.3",blessed:"^0.1.81",chalk:"^4.1.2",chokidar:"^3.6.0","cli-spinners":"^2.9.2","cli-table3":"^0.6.3",clipboardy:"^5.1.0",commander:"^14.0.0",eventsource:"^4.0.0","form-data":"^4.0.0","fs-extra":"^11.3.3",inquirer:"8.2.7",keytar:"^7.9.0",ora:"^4.1.1"},devDependencies:{"@types/adm-zip":"^0.5.7","@types/blessed":"^0.1.25","@types/fs-extra":"^11.0.4","@types/inquirer":"^9.0.9","@types/jest":"^30.0.0","@types/keytar":"^4.4.0","@types/node":"24.10.9",execa:"^5.1.1",jest:"^30.0.0",nodemon:"^3.0.1",prettier:"^3.8.1","ts-jest":"^29.4.6",tsup:"^8.5.0",tsx:"^4.20.4",typescript:"^5.9.2"},engines:{node:">=20.0.0",npm:">=9.0.0"}}});function Nt(s){if(!s)return s;let e=s;for(let n of Bo)e=e.replace(n,i=>{let o=i.match(/^[A-Za-z]+\s+/)?.[0]||"";return o?`${o}[REDACTED]`:"[REDACTED]"});return e}function zn(s){let e={...s};if(e.Authorization){let o=e.Authorization.match(/^([A-Za-z]+)\s+/),r=o?o[1]:"Bearer";e.Authorization=`${r} [REDACTED]`}let n=["x-api-key","x-auth-token","api-key","token"];for(let i of n){let o=Object.keys(e).find(r=>r.toLowerCase()===i);o&&(e[o]="[REDACTED]")}return e}var Bo,Wn=Q(()=>{"use strict";Bo=[/Bearer\s+[A-Za-z0-9\-_.]+/g,/Basic\s+[A-Za-z0-9+/=]+/g,/[Aa]uthorization["\s:=]+["']?[^"'\s]+/g]});var Xe={};ut(Xe,{SinchAPI:()=>T});var Ot,Yt,Ue,T,z=Q(()=>{"use strict";Ot=h(require("axios")),Yt=h(require("form-data")),Ue=h(require("chalk"));Wn();T=class{baseUrl;oauthUrl;projectId;timeout;credentials;client;constructor(e={}){this.baseUrl=e.apiUrl||"https://functions.api.sinch.com/",this.oauthUrl=e.oauthUrl||"https://auth.sinch.com/oauth2/token",this.projectId=e.projectId||"",this.timeout=6e4,this.credentials=e.credentials||null,this.client=Ot.default.create({baseURL:this.baseUrl,timeout:this.timeout,headers:{"User-Agent":"sinch-functions-cli/1.0.0"}}),this.client.interceptors.request.use(async n=>{if(this.credentials){let i=await this.getValidToken();i&&(n.headers.Authorization=`${i.token_type} ${i.access_token}`)}if(process.env.DEBUG_HTTP){let i=Nt(n.url||"");if(console.log(Ue.default.gray(`\u2192 ${n.method?.toUpperCase()} ${i}`)),process.env.DEBUG_HTTP==="2"||process.env.DEBUG_HTTP==="verbose"){let o=zn(n.headers);console.log(Ue.default.gray(" Headers:"),JSON.stringify(o,null,2))}}return n},n=>Promise.reject(n)),this.client.interceptors.response.use(n=>{if(process.env.DEBUG_HTTP){let i=Nt(n.config.url||"");console.log(Ue.default.gray(`\u2190 ${n.status} ${i}`))}return n},async n=>{if(process.env.DEBUG_HTTP){let i=Nt(n.config?.url||"");console.log(Ue.default.red(`\u2190 ${n.response?.status||"ERROR"} ${i}`))}if(n.response?.status===401&&this.credentials&&n.config){let i=n.config;if(!i._retry){i._retry=!0;try{let o=await this.getValidToken();if(o)return i.headers.Authorization=`${o.token_type} ${o.access_token}`,this.client.request(i)}catch{console.error(Ue.default.yellow("Token refresh failed during retry"))}}}return Promise.reject(n)})}async listAllTemplates(e=null){try{let n=e?{category:e}:{};return(await this.client.get(`/v1/projects/${this.projectId}/templates`,{params:n})).data}catch(n){throw this._handleError(n,"Failed to list templates")}}async listRuntimeTemplates(e,n=null){try{let i=n?{category:n}:{};return(await this.client.get(`/v1/projects/${this.projectId}/templates/${e}`,{params:i})).data}catch(i){throw this._handleError(i,`Failed to list ${e} templates`)}}async getTemplateDetails(e,n){try{return(await this.client.get(`/v1/projects/${this.projectId}/templates/${e}/${n}`)).data}catch(i){throw this._handleError(i,`Failed to get template details for ${e}/${n}`)}}async downloadTemplate(e,n){try{let i=await this.client.get(`/v1/projects/${this.projectId}/templates/${e}/${n}/download`,{responseType:"arraybuffer"});return Buffer.from(i.data)}catch(i){throw this._handleError(i,`Failed to download template ${e}/${n}`)}}async listFunctions(){try{return(await this.client.get(`/v1/projects/${this.projectId}/functions`)).data}catch(e){throw this._handleError(e,"Failed to list functions")}}async getFunction(e){try{return(await this.client.get(`/v1/projects/${this.projectId}/functions/${e}`)).data}catch(n){throw this._handleError(n,`Failed to get function ${e}`)}}async deployFunction(e,n,i,o,r="public"){try{let a=new Yt.default;return a.append("name",e),a.append("runtime",n),a.append("code",i,{filename:"function.zip"}),a.append("accessLevel",r),o&&a.append("configuration",JSON.stringify(o)),(await this.client.post(`/v1/projects/${this.projectId}/functions`,a,{headers:{...a.getHeaders()},maxContentLength:1/0,maxBodyLength:1/0})).data}catch(a){throw this._handleError(a,"Failed to deploy function")}}async updateFunction(e,n,i){try{let o=new Yt.default;return o.append("code",n,{filename:"function.zip"}),i&&o.append("configuration",JSON.stringify(i)),(await this.client.put(`/v1/projects/${this.projectId}/functions/${e}`,o,{headers:{...o.getHeaders()},maxContentLength:1/0,maxBodyLength:1/0})).data}catch(o){throw this._handleError(o,`Failed to update function ${e}`)}}async deleteFunction(e){try{await this.client.delete(`/v1/projects/${this.projectId}/functions/${e}`)}catch(n){throw this._handleError(n,`Failed to delete function ${e}`)}}async downloadFunction(e){try{let n=await this.client.get(`/v1/projects/${this.projectId}/functions/${e}/download`,{responseType:"arraybuffer"});return Buffer.from(n.data)}catch(n){throw this._handleError(n,`Failed to download function ${e}`)}}async getFunctionLogs(e,n={}){try{return(await this.client.get(`/v1/projects/${this.projectId}/functions/${e}/logs`,{params:n})).data}catch(i){throw this._handleError(i,`Failed to get logs for function ${e}`)}}async getFunctionStatus(e){try{return(await this.client.get(`/v1/projects/${this.projectId}/functions/${e}/deployment/status`)).data}catch(n){throw this._handleError(n,`Failed to get status for function ${e}`)}}async generateDocumentationFromCode(e,n="node",i="function"){try{return(await this.client.post(`/v1/projects/${this.projectId}/test/documentation`,{Code:e,Runtime:n,Name:i})).data}catch(o){throw this._handleError(o,"Failed to generate documentation from code")}}async generateDocumentationForFunction(e,n){try{let i=n?{MarkdownOverride:n}:{};return(await this.client.post(`/v1/projects/${this.projectId}/functions/${e}/documentation`,i)).data}catch(i){throw this._handleError(i,`Failed to generate documentation for function ${e}`)}}async getDocumentationForFunction(e){try{return(await this.client.get(`/v1/projects/${this.projectId}/functions/${e}/documentation`)).data}catch(n){throw this._handleError(n,`Failed to get documentation for function ${e}`)}}async streamDeployment(e,n,i){let o=p=>p.status?"status":p.progress?"progress":p.completed?"completed":p.failed||p.error?"failed":p.connected?"connected":"message",r=new URL(`v1/projects/${this.projectId}/functions/${e}/deployment/stream`,this.baseUrl).href,a={Accept:"text/event-stream","Cache-Control":"no-cache"};if(this.credentials)try{let p=await this.credentials.retrieve();if(p&&p.keyId&&p.keySecret){let d=Buffer.from(`${p.keyId}:${p.keySecret}`).toString("base64");a.Authorization=`Basic ${d}`}}catch(p){console.error("Failed to add authentication:",p)}let l=null;try{l=new AbortController;let p=await fetch(r,{method:"GET",headers:a,signal:l.signal});if(!p.ok)throw new Error(`SSE connection failed: ${p.status} ${p.statusText}`);if(!p.body)throw new Error("Response body is null");let d=p.body.getReader(),f=new TextDecoder,g="";return(async()=>{let y="";try{for(;;){let{done:v,value:$}=await d.read();if(v)break;let P=f.decode($,{stream:!0});g+=P;let D=g.split(`
2
+ "use strict";var Ao=Object.create;var Rt=Object.defineProperty;var Eo=Object.getOwnPropertyDescriptor;var xo=Object.getOwnPropertyNames;var Do=Object.getPrototypeOf,jo=Object.prototype.hasOwnProperty;var Q=(s,e)=>()=>(s&&(e=s(s=0)),e);var R=(s,e)=>()=>(e||s((e={exports:{}}).exports,e),e.exports),ut=(s,e)=>{for(var n in e)Rt(s,n,{get:e[n],enumerable:!0})},Vn=(s,e,n,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of xo(e))!jo.call(s,o)&&o!==n&&Rt(s,o,{get:()=>e[o],enumerable:!(i=Eo(e,o))||i.enumerable});return s};var h=(s,e,n)=>(n=s!=null?Ao(Do(s)):{},Vn(e||!s||!s.__esModule?Rt(n,"default",{value:s,enumerable:!0}):n,s)),M=s=>Vn(Rt({},"__esModule",{value:!0}),s);var zt=R((Sa,Ro)=>{Ro.exports={name:"@sinch/cli",version:"0.2.1",description:"Official Sinch CLI - Manage all Sinch products from your terminal",main:"dist/index.js",bin:{sinch:"bin/sinch"},scripts:{start:"tsx src/index.ts",dev:"tsx watch src/index.ts",build:"tsc && node scripts/post-build.js","build:prod":"tsup src/index.ts --format cjs --dts --clean --minify",typecheck:"tsc --noEmit",test:"jest --config jest.config.js && jest --config tests/e2e/jest.config.js","test:unit":"jest --config jest.config.js","test:e2e":"jest --config tests/e2e/jest.config.js","test:e2e:staging":"jest --config tests/e2e/jest.config.js --env=staging",prepublishOnly:"npm run build:prod",format:"prettier --write .","format:check":"prettier --check ."},keywords:[],author:"Sinch <support@sinch.com> (https://www.sinch.com)",license:"MIT",private:!1,publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},homepage:"https://www.sinch.com/products/apis/voice/",files:["dist/","bin/","README.md","LICENSE"],dependencies:{"@inquirer/prompts":"^8.2.0","@sinch/fax":"^1.0.0","@sinch/sdk-core":"^1.2.1","adm-zip":"^0.5.10",axios:"^1.13.3",blessed:"^0.1.81",chalk:"^4.1.2",chokidar:"^3.6.0","cli-spinners":"^2.9.2","cli-table3":"^0.6.3",clipboardy:"^5.1.0",commander:"^14.0.0",eventsource:"^4.0.0","form-data":"^4.0.0","fs-extra":"^11.3.3",inquirer:"8.2.7",keytar:"^7.9.0",ora:"^4.1.1"},devDependencies:{"@types/adm-zip":"^0.5.7","@types/blessed":"^0.1.25","@types/fs-extra":"^11.0.4","@types/inquirer":"^9.0.9","@types/jest":"^30.0.0","@types/keytar":"^4.4.0","@types/node":"24.10.9",execa:"^5.1.1",jest:"^30.0.0",nodemon:"^3.0.1",prettier:"^3.8.1","ts-jest":"^29.4.6",tsup:"^8.5.0",tsx:"^4.20.4",typescript:"^5.9.2"},engines:{node:">=20.0.0",npm:">=9.0.0"}}});function Nt(s){if(!s)return s;let e=s;for(let n of Bo)e=e.replace(n,i=>{let o=i.match(/^[A-Za-z]+\s+/)?.[0]||"";return o?`${o}[REDACTED]`:"[REDACTED]"});return e}function zn(s){let e={...s};if(e.Authorization){let o=e.Authorization.match(/^([A-Za-z]+)\s+/),r=o?o[1]:"Bearer";e.Authorization=`${r} [REDACTED]`}let n=["x-api-key","x-auth-token","api-key","token"];for(let i of n){let o=Object.keys(e).find(r=>r.toLowerCase()===i);o&&(e[o]="[REDACTED]")}return e}var Bo,Wn=Q(()=>{"use strict";Bo=[/Bearer\s+[A-Za-z0-9\-_.]+/g,/Basic\s+[A-Za-z0-9+/=]+/g,/[Aa]uthorization["\s:=]+["']?[^"'\s]+/g]});var Xe={};ut(Xe,{SinchAPI:()=>T});var Ot,Yt,Ue,T,z=Q(()=>{"use strict";Ot=h(require("axios")),Yt=h(require("form-data")),Ue=h(require("chalk"));Wn();T=class{baseUrl;oauthUrl;projectId;timeout;credentials;client;constructor(e={}){this.baseUrl=e.apiUrl||"https://functions.api.sinch.com/",this.oauthUrl=e.oauthUrl||"https://auth.sinch.com/oauth2/token",this.projectId=e.projectId||"",this.timeout=6e4,this.credentials=e.credentials||null,this.client=Ot.default.create({baseURL:this.baseUrl,timeout:this.timeout,headers:{"User-Agent":"sinch-functions-cli/1.0.0"}}),this.client.interceptors.request.use(async n=>{if(this.credentials){let i=await this.getValidToken();i&&(n.headers.Authorization=`${i.token_type} ${i.access_token}`)}if(process.env.DEBUG_HTTP){let i=Nt(n.url||"");if(console.log(Ue.default.gray(`\u2192 ${n.method?.toUpperCase()} ${i}`)),process.env.DEBUG_HTTP==="2"||process.env.DEBUG_HTTP==="verbose"){let o=zn(n.headers);console.log(Ue.default.gray(" Headers:"),JSON.stringify(o,null,2))}}return n},n=>Promise.reject(n)),this.client.interceptors.response.use(n=>{if(process.env.DEBUG_HTTP){let i=Nt(n.config.url||"");console.log(Ue.default.gray(`\u2190 ${n.status} ${i}`))}return n},async n=>{if(process.env.DEBUG_HTTP){let i=Nt(n.config?.url||"");console.log(Ue.default.red(`\u2190 ${n.response?.status||"ERROR"} ${i}`))}if(n.response?.status===401&&this.credentials&&n.config){let i=n.config;if(!i._retry){i._retry=!0;try{let o=await this.getValidToken();if(o)return i.headers.Authorization=`${o.token_type} ${o.access_token}`,this.client.request(i)}catch{console.error(Ue.default.yellow("Token refresh failed during retry"))}}}return Promise.reject(n)})}async listAllTemplates(e=null){try{let n=e?{category:e}:{};return(await this.client.get(`/v1/projects/${this.projectId}/templates`,{params:n})).data}catch(n){throw this._handleError(n,"Failed to list templates")}}async listRuntimeTemplates(e,n=null){try{let i=n?{category:n}:{};return(await this.client.get(`/v1/projects/${this.projectId}/templates/${e}`,{params:i})).data}catch(i){throw this._handleError(i,`Failed to list ${e} templates`)}}async getTemplateDetails(e,n){try{return(await this.client.get(`/v1/projects/${this.projectId}/templates/${e}/${n}`)).data}catch(i){throw this._handleError(i,`Failed to get template details for ${e}/${n}`)}}async downloadTemplate(e,n){try{let i=await this.client.get(`/v1/projects/${this.projectId}/templates/${e}/${n}/download`,{responseType:"arraybuffer"});return Buffer.from(i.data)}catch(i){throw this._handleError(i,`Failed to download template ${e}/${n}`)}}async listFunctions(){try{return(await this.client.get(`/v1/projects/${this.projectId}/functions`)).data}catch(e){throw this._handleError(e,"Failed to list functions")}}async getFunction(e){try{return(await this.client.get(`/v1/projects/${this.projectId}/functions/${e}`)).data}catch(n){throw this._handleError(n,`Failed to get function ${e}`)}}async deployFunction(e,n,i,o,r="public"){try{let a=new Yt.default;return a.append("name",e),a.append("runtime",n),a.append("code",i,{filename:"function.zip"}),a.append("accessLevel",r),o&&a.append("configuration",JSON.stringify(o)),(await this.client.post(`/v1/projects/${this.projectId}/functions`,a,{headers:{...a.getHeaders()},maxContentLength:1/0,maxBodyLength:1/0})).data}catch(a){throw this._handleError(a,"Failed to deploy function")}}async updateFunction(e,n,i){try{let o=new Yt.default;return o.append("code",n,{filename:"function.zip"}),i&&o.append("configuration",JSON.stringify(i)),(await this.client.put(`/v1/projects/${this.projectId}/functions/${e}`,o,{headers:{...o.getHeaders()},maxContentLength:1/0,maxBodyLength:1/0})).data}catch(o){throw this._handleError(o,`Failed to update function ${e}`)}}async deleteFunction(e){try{await this.client.delete(`/v1/projects/${this.projectId}/functions/${e}`)}catch(n){throw this._handleError(n,`Failed to delete function ${e}`)}}async downloadFunction(e){try{let n=await this.client.get(`/v1/projects/${this.projectId}/functions/${e}/download`,{responseType:"arraybuffer"});return Buffer.from(n.data)}catch(n){throw this._handleError(n,`Failed to download function ${e}`)}}async getFunctionLogs(e,n={}){try{return(await this.client.get(`/v1/projects/${this.projectId}/functions/${e}/logs`,{params:n})).data}catch(i){throw this._handleError(i,`Failed to get logs for function ${e}`)}}async getFunctionStatus(e){try{return(await this.client.get(`/v1/projects/${this.projectId}/functions/${e}/deployment/status`)).data}catch(n){throw this._handleError(n,`Failed to get status for function ${e}`)}}async generateDocumentationFromCode(e,n="node",i="function"){try{return(await this.client.post(`/v1/projects/${this.projectId}/test/documentation`,{Code:e,Runtime:n,Name:i})).data}catch(o){throw this._handleError(o,"Failed to generate documentation from code")}}async generateDocumentationForFunction(e,n){try{let i=n?{MarkdownOverride:n}:{};return(await this.client.post(`/v1/projects/${this.projectId}/functions/${e}/documentation`,i)).data}catch(i){throw this._handleError(i,`Failed to generate documentation for function ${e}`)}}async getDocumentationForFunction(e){try{return(await this.client.get(`/v1/projects/${this.projectId}/functions/${e}/documentation`)).data}catch(n){throw this._handleError(n,`Failed to get documentation for function ${e}`)}}async streamDeployment(e,n,i){let o=p=>p.status?"status":p.progress?"progress":p.completed?"completed":p.failed||p.error?"failed":p.connected?"connected":"message",r=new URL(`v1/projects/${this.projectId}/functions/${e}/deployment/stream`,this.baseUrl).href,a={Accept:"text/event-stream","Cache-Control":"no-cache"};if(this.credentials)try{let p=await this.credentials.retrieve();if(p&&p.keyId&&p.keySecret){let d=Buffer.from(`${p.keyId}:${p.keySecret}`).toString("base64");a.Authorization=`Basic ${d}`}}catch(p){console.error("Failed to add authentication:",p)}let l=null;try{l=new AbortController;let p=await fetch(r,{method:"GET",headers:a,signal:l.signal});if(!p.ok)throw new Error(`SSE connection failed: ${p.status} ${p.statusText}`);if(!p.body)throw new Error("Response body is null");let d=p.body.getReader(),f=new TextDecoder,g="";return(async()=>{let y="";try{for(;;){let{done:v,value:$}=await d.read();if(v)break;let P=f.decode($,{stream:!0});g+=P;let D=g.split(`
3
3
  `);g=D.pop()||"";for(let C of D){if(C.startsWith("event:")){y=C.substring(6).trim();continue}if(C.startsWith("data:")){let S=C.substring(5).trim();if(S)try{let b=JSON.parse(S),I=y||o(b);n({type:I,data:b}),y=""}catch{n({type:y||"message",data:S}),y=""}}C===""&&(y="")}}}catch(v){v.name!=="AbortError"&&i&&i(v)}})(),()=>{l&&l.abort()}}catch(p){throw console.error("Failed to create SSE stream:",p),i&&i(p),p}}async checkHealth(){try{return(await this.client.get("/health")).data}catch(e){throw this._handleError(e,"Health check failed")}}async getValidToken(){if(!this.credentials)return null;try{let e=await this.credentials.getOAuthToken();if(e)return{access_token:e,token_type:"Bearer",expires_in:3600};let n=await this.credentials.getBasicAuthToken();return n?{access_token:n,token_type:"Basic",expires_in:3600}:null}catch(e){return console.error(Ue.default.yellow("Failed to get authentication token:",e.message)),null}}async authenticateOAuth(e,n){try{let i=this.oauthUrl,o=new URLSearchParams;o.append("grant_type","client_credentials");let a=(await Ot.default.post(i,o,{headers:{"Content-Type":"application/x-www-form-urlencoded",Authorization:"Basic "+Buffer.from(`${e}:${n}`).toString("base64")},timeout:this.timeout})).data;return this.credentials&&await this.credentials.storeOAuthToken(a),a}catch(i){throw this._handleError(i,"OAuth authentication failed")}}_handleError(e,n){if(Ot.default.isAxiosError(e)){let i=e;if(i.response){let o=i.response.status,r=i.response.data,a=r?.message||r?.error||i.message;throw o===401?new Error('Authentication required. Please run "sinch auth login" first.'):o===403?new Error(`Permission denied: ${a}`):o===404?new Error(`Resource not found: ${a}`):o>=500?new Error(`Server error: ${a}`):new Error(`${n}: ${a}`)}else throw i.request?(console.error("DEBUG: Axios error details:",{code:i.code,message:i.message,url:i.config?.url,baseURL:i.config?.baseURL,method:i.config?.method}),i.code==="ECONNREFUSED"?new Error(`Cannot connect to API at ${this.baseUrl}. Is the server running?`):i.code==="ETIMEDOUT"?new Error(`Request timeout after ${this.timeout}ms`):new Error(`${n}: No response from server (${i.code||"unknown error"})`)):new Error(`${n}: ${i.message}`)}else throw new Error(`${n}: ${e.message||e}`)}}});function Tt(){if(!Zt)try{Zt=require("keytar")}catch{return null}return Zt}var Gn,G,Zt,ft,J,Ft,Yn=Q(()=>{"use strict";Gn=h(require("os")),G=h(require("chalk")),Zt=null;ft="sinch-functions-cli",J=Gn.userInfo().username,Ft=class{config;keychainAvailable=null;constructor(e){this.config=e}async isKeychainAvailable(){if(this.keychainAvailable!==null)return this.keychainAvailable;if(this.config.get("keySecretPlaintext"))return this.keychainAvailable=!1,!1;try{let e=Tt();if(!e)return this.keychainAvailable=!1,!1;let n=`${J}-test-${Date.now()}`;return await e.setPassword(ft,n,"test"),await e.deletePassword(ft,n),this.keychainAvailable=!0,!0}catch{return this.keychainAvailable=!1,!1}}async setPassword(e,n){if(!await this.isKeychainAvailable())return!1;let o=Tt();return o?(await o.setPassword(ft,e,n),!0):!1}async getPassword(e){if(!await this.isKeychainAvailable())return null;let i=Tt();return i?await i.getPassword(ft,e):null}async deletePassword(e){if(!await this.isKeychainAvailable())return!1;try{let i=Tt();return i?(await i.deletePassword(ft,e),!0):!1}catch{return!0}}async store(e){let{projectId:n,keyId:i,keySecret:o,applicationKey:r,applicationSecret:a}=e,l=await this.setPassword(`${J}-keySecret`,o),p=await this.setPassword(r,a);l&&p?(this.config.set("keySecretPlaintext",null),this.config.set("applicationSecretPlaintext",null)):(console.log(G.default.yellow(`
4
4
  \u26A0\uFE0F OS keychain not available (Docker/CI environment detected)`)),console.log(G.default.yellow("\u26A0\uFE0F Storing secrets in plaintext config file")),console.log(G.default.gray("Location: ~/.sinch/config.json")),console.log(G.default.gray(`
5
5
  For better security, export as environment variables instead:`)),console.log(G.default.cyan(' export SINCH_KEY_SECRET="'+o+'"')),console.log(G.default.cyan(' export SINCH_APPLICATION_SECRET="'+a+'"')),this.config.set("keySecretPlaintext",o),this.config.set("applicationSecretPlaintext",a)),this.config.set("projectId",n),this.config.set("keyId",i),this.config.set("defaultApplicationKey",r),this.config.set("credentialsStored",!0),await this.config.save()}async storeOAuthToken(e){let{access_token:n,refresh_token:i,expires_in:o,token_type:r}=e,a=new Date(Date.now()+o*1e3).toISOString(),l=await this.setPassword(`${J}-oauth-access`,n),p=!0;i&&(p=await this.setPassword(`${J}-oauth-refresh`,i)),this.config.set("oauthTokenType",r),this.config.set("oauthExpiresAt",a),this.config.set("oauthStored",l&&p),await this.config.save()}async reAuthenticateOAuth(){try{let e=await this.retrieve();if(!e)return null;let{SinchAPI:n}=(z(),M(Xe)),o=await new n({apiUrl:this.config.get("apiUrl")||"https://api.functions.dev.sinchvoice.org",projectId:e.projectId,credentials:null}).authenticateOAuth(e.keyId,e.keySecret);return await this.storeOAuthToken(o),o.access_token}catch{return null}}async getOAuthToken(){if(!this.config.get("oauthStored"))return await this.reAuthenticateOAuth();let n=this.config.get("oauthExpiresAt");if(n&&new Date(n)<new Date){console.log(G.default.gray("Token expired, re-authenticating..."));let i=await this.reAuthenticateOAuth();return i?console.log(G.default.green("\u2713 Token renewed successfully")):console.warn(G.default.yellow("Failed to renew OAuth token. Please login again.")),i}return await this.getPassword(`${J}-oauth-access`)}async storeApplicationSecret(e,n){await this.setPassword(e,n),this.config.get("defaultApplicationKey")||(this.config.set("defaultApplicationKey",e),await this.config.save())}async retrieve(){let e=process.env.SINCH_KEY_ID,n=process.env.SINCH_KEY_SECRET,i=process.env.SINCH_APPLICATION_KEY,o=process.env.SINCH_APPLICATION_SECRET;if(e&&n&&i&&o)return{projectId:process.env.SINCH_PROJECT_ID||this.config.get("projectId")||"",keyId:e,keySecret:n,applicationKey:i,applicationSecret:o};if(!this.config.get("credentialsStored"))return null;let a=this.config.get("projectId"),l=this.config.get("keyId"),p=this.config.get("defaultApplicationKey"),d=await this.getPassword(`${J}-keySecret`),f=p?await this.getPassword(p):null;return(!d||!f)&&(d=d||n||null,f=f||o||null),(!d||!f)&&(d=d||this.config.get("keySecretPlaintext"),f=f||this.config.get("applicationSecretPlaintext")),!d||!f?null:{projectId:a,keyId:l,keySecret:d,applicationKey:p,applicationSecret:f}}async getApplicationCredentials(e=null){if(e||(e=this.config.get("defaultApplicationKey")),!e)return null;let n=await this.getPassword(e);return n||(n=process.env.SINCH_APPLICATION_SECRET||null),n||(n=this.config.get("applicationSecretPlaintext")),n?{applicationKey:e,applicationSecret:n}:null}async clear(){let e=this.config.get("defaultApplicationKey");await this.deletePassword(`${J}-keySecret`),await this.deletePassword(`${J}-oauth-access`),await this.deletePassword(`${J}-oauth-refresh`),e&&await this.deletePassword(e),this.config.set("projectId",null),this.config.set("keyId",null),this.config.set("defaultApplicationKey",null),this.config.set("credentialsStored",!1),this.config.set("oauthStored",!1),this.config.set("oauthTokenType",null),this.config.set("oauthExpiresAt",null),this.config.set("keySecretPlaintext",null),this.config.set("applicationSecretPlaintext",null),await this.config.save()}async hasCredentials(){if(!!(process.env.SINCH_KEY_ID&&process.env.SINCH_KEY_SECRET&&process.env.SINCH_APPLICATION_KEY&&process.env.SINCH_APPLICATION_SECRET))return!0;if(!this.config.get("credentialsStored"))return!1;if(this.config.get("keySecretPlaintext"))return!0;let i=await this.getPassword(`${J}-keySecret`),o=this.config.get("defaultApplicationKey"),r=o?await this.getPassword(o):null;return!!(i&&r)}async hasOAuthToken(){return this.config.get("oauthStored")?!!await this.getPassword(`${J}-oauth-access`):!1}getPublicInfo(){return process.env.SINCH_KEY_ID&&process.env.SINCH_KEY_SECRET&&process.env.SINCH_APPLICATION_KEY&&process.env.SINCH_APPLICATION_SECRET?{projectId:process.env.SINCH_PROJECT_ID||this.config.get("projectId"),keyId:process.env.SINCH_KEY_ID,applicationKey:process.env.SINCH_APPLICATION_KEY,hasCredentials:!0,hasOAuth:!1,oauthExpiresAt:null,source:"environment"}:{projectId:this.config.get("projectId"),keyId:this.config.get("keyId"),applicationKey:this.config.get("defaultApplicationKey"),hasCredentials:this.config.get("credentialsStored",!1),hasOAuth:this.config.get("oauthStored",!1),oauthExpiresAt:this.config.get("oauthExpiresAt"),source:"config"}}async createSinchClient(e=null){let n=await this.retrieve();if(!n)throw new Error('No credentials found. Please run "sinch auth login" first.');let i=await this.getApplicationCredentials(e),{SinchClient:o}=require("@sinch/sdk-core");return new o({applicationKey:i?.applicationKey||n.applicationKey,applicationSecret:i?.applicationSecret||n.applicationSecret,projectId:n.projectId,keyId:n.keyId,keySecret:n.keySecret,conversationRegion:"us"})}async storeBasicAuthToken(e){await this.setPassword(`${J}-basic-auth`,e)&&(this.config.set("basicAuthStored",!0),await this.config.save())}async getBasicAuthToken(){return this.config.get("basicAuthStored")?await this.getPassword(`${J}-basic-auth`):null}async clearBasicAuthToken(){await this.deletePassword(`${J}-basic-auth`),this.config.set("basicAuthStored",!1),await this.config.save()}async storeFax(e){let{projectId:n,keyId:i,keySecret:o}=e;await this.setPassword(`${J}-fax-keySecret`,o)?this.config.set("faxKeySecretPlaintext",null):(console.log(G.default.yellow(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinch/cli",
3
- "version": "0.2.1-beta.0",
3
+ "version": "0.2.1",
4
4
  "description": "Official Sinch CLI - Manage all Sinch products from your terminal",
5
5
  "main": "dist/index.js",
6
6
  "bin": {