@sinch/cli 0.0.0-dev.2090814404 → 0.0.0-dev.2090888165

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 +2 -2
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var Vn=Object.create;var Ne=Object.defineProperty;var Kn=Object.getOwnPropertyDescriptor;var qn=Object.getOwnPropertyNames;var Mn=Object.getPrototypeOf,Jn=Object.prototype.hasOwnProperty;var fe=(o,e)=>()=>(o&&(e=o(o=0)),e);var _=(o,e)=>()=>(e||o((e={exports:{}}).exports,e),e.exports),Ue=(o,e)=>{for(var n in e)Ne(o,n,{get:e[n],enumerable:!0})},ht=(o,e,n,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of qn(e))!Jn.call(o,r)&&r!==n&&Ne(o,r,{get:()=>e[r],enumerable:!(i=Kn(e,r))||i.enumerable});return o};var m=(o,e,n)=>(n=o!=null?Vn(Mn(o)):{},ht(e||!o||!o.__esModule?Ne(n,"default",{value:o,enumerable:!0}):n,o)),N=o=>ht(Ne({},"__esModule",{value:!0}),o);var yt=_((ei,Wn)=>{Wn.exports={name:"@sinch/cli",version:"0.1.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",prepublishOnly:"npm run build:prod"},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:{"@sinch/sdk-core":"^1.2.1","adm-zip":"^0.5.10",axios:"^1.7.9",blessed:"^0.1.81",chalk:"^4.1.2",chokidar:"^3.6.0","cli-spinners":"^3.2.0","cli-table3":"^0.6.3",clipboardy:"^2.3.0",commander:"^12.1.0",eventsource:"^4.0.0","form-data":"^4.0.0","fs-extra":"^11.1.1",inquirer:"8.2.6",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/keytar":"^4.4.0","@types/node":"^24.3.0",jest:"^29.7.0",nodemon:"^3.0.1",tsup:"^8.5.0",tsx:"^4.20.4",typescript:"^5.9.2"},engines:{node:">=20.0.0",npm:">=9.0.0"}}});var Ve={};Ue(Ve,{SinchAPI:()=>E});var Be,ze,Se,E,U=fe(()=>{"use strict";Be=m(require("axios")),ze=m(require("form-data")),Se=m(require("chalk")),E=class{baseUrl;projectId;timeout;credentials;client;constructor(e={}){this.baseUrl=e.apiUrl||"https://functions.api.sinch.com/",this.projectId=e.projectId||"",this.timeout=e.timeout||3e4,this.credentials=e.credentials||null,this.client=Be.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}`)}return process.env.DEBUG_HTTP&&console.log(Se.default.gray(`\u2192 ${n.method?.toUpperCase()} ${n.url}`)),n},n=>Promise.reject(n)),this.client.interceptors.response.use(n=>(process.env.DEBUG_HTTP&&console.log(Se.default.gray(`\u2190 ${n.status} ${n.config.url}`)),n),async n=>{if(process.env.DEBUG_HTTP&&console.log(Se.default.red(`\u2190 ${n.response?.status||"ERROR"} ${n.config?.url}`)),n.response?.status===401&&this.credentials&&n.config){let i=n.config;if(!i._retry){i._retry=!0;try{let r=await this.getValidToken();if(r)return i.headers.Authorization=`${r.token_type} ${r.access_token}`,this.client.request(i)}catch{console.error(Se.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,r){try{let s=new ze.default;return s.append("name",e),s.append("runtime",n),s.append("code",i,{filename:"function.zip"}),r&&s.append("configuration",JSON.stringify(r)),(await this.client.post(`/v1/projects/${this.projectId}/functions`,s,{headers:{...s.getHeaders()},maxContentLength:1/0,maxBodyLength:1/0})).data}catch(s){throw this._handleError(s,"Failed to deploy function")}}async updateFunction(e,n,i){try{let r=new ze.default;return r.append("code",n,{filename:"function.zip"}),i&&r.append("configuration",JSON.stringify(i)),(await this.client.put(`/v1/projects/${this.projectId}/functions/${e}`,r,{headers:{...r.getHeaders()},maxContentLength:1/0,maxBodyLength:1/0})).data}catch(r){throw this._handleError(r,`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(r){throw this._handleError(r,"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 r=u=>u.status?"status":u.progress?"progress":u.completed?"completed":u.failed||u.error?"failed":u.connected?"connected":"message",s=`${this.baseUrl}v1/projects/${this.projectId}/functions/${e}/deployment/stream`,a={Accept:"text/event-stream","Cache-Control":"no-cache"};if(this.credentials)try{let u=await this.credentials.retrieve();if(u&&u.keyId&&u.keySecret){let l=Buffer.from(`${u.keyId}:${u.keySecret}`).toString("base64");a.Authorization=`Basic ${l}`}}catch(u){console.error("Failed to add authentication:",u)}let c=null;try{c=new AbortController;let u=await fetch(s,{method:"GET",headers:a,signal:c.signal});if(!u.ok)throw new Error(`SSE connection failed: ${u.status} ${u.statusText}`);if(!u.body)throw new Error("Response body is null");let l=u.body.getReader(),g=new TextDecoder,h="";return(async()=>{let C="";try{for(;;){let{done:M,value:G}=await l.read();if(M)break;let P=g.decode(G,{stream:!0});h+=P;let b=h.split(`
2
+ "use strict";var Vn=Object.create;var Ne=Object.defineProperty;var Kn=Object.getOwnPropertyDescriptor;var qn=Object.getOwnPropertyNames;var Mn=Object.getPrototypeOf,Jn=Object.prototype.hasOwnProperty;var fe=(o,e)=>()=>(o&&(e=o(o=0)),e);var _=(o,e)=>()=>(e||o((e={exports:{}}).exports,e),e.exports),Ue=(o,e)=>{for(var n in e)Ne(o,n,{get:e[n],enumerable:!0})},ht=(o,e,n,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of qn(e))!Jn.call(o,r)&&r!==n&&Ne(o,r,{get:()=>e[r],enumerable:!(i=Kn(e,r))||i.enumerable});return o};var m=(o,e,n)=>(n=o!=null?Vn(Mn(o)):{},ht(e||!o||!o.__esModule?Ne(n,"default",{value:o,enumerable:!0}):n,o)),N=o=>ht(Ne({},"__esModule",{value:!0}),o);var yt=_((ei,Wn)=>{Wn.exports={name:"@sinch/cli",version:"0.1.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",prepublishOnly:"npm run build:prod"},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:{"@sinch/sdk-core":"^1.2.1","adm-zip":"^0.5.10",axios:"^1.7.9",blessed:"^0.1.81",chalk:"^4.1.2",chokidar:"^3.6.0","cli-spinners":"^2.9.2","cli-table3":"^0.6.3",clipboardy:"^2.3.0",commander:"^12.1.0",eventsource:"^4.0.0","form-data":"^4.0.0","fs-extra":"^11.1.1",inquirer:"8.2.6",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/keytar":"^4.4.0","@types/node":"^24.3.0",jest:"^29.7.0",nodemon:"^3.0.1",tsup:"^8.5.0",tsx:"^4.20.4",typescript:"^5.9.2"},engines:{node:">=20.0.0",npm:">=9.0.0"}}});var Ve={};Ue(Ve,{SinchAPI:()=>E});var Be,ze,Se,E,U=fe(()=>{"use strict";Be=m(require("axios")),ze=m(require("form-data")),Se=m(require("chalk")),E=class{baseUrl;projectId;timeout;credentials;client;constructor(e={}){this.baseUrl=e.apiUrl||"https://functions.api.sinch.com/",this.projectId=e.projectId||"",this.timeout=e.timeout||3e4,this.credentials=e.credentials||null,this.client=Be.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}`)}return process.env.DEBUG_HTTP&&console.log(Se.default.gray(`\u2192 ${n.method?.toUpperCase()} ${n.url}`)),n},n=>Promise.reject(n)),this.client.interceptors.response.use(n=>(process.env.DEBUG_HTTP&&console.log(Se.default.gray(`\u2190 ${n.status} ${n.config.url}`)),n),async n=>{if(process.env.DEBUG_HTTP&&console.log(Se.default.red(`\u2190 ${n.response?.status||"ERROR"} ${n.config?.url}`)),n.response?.status===401&&this.credentials&&n.config){let i=n.config;if(!i._retry){i._retry=!0;try{let r=await this.getValidToken();if(r)return i.headers.Authorization=`${r.token_type} ${r.access_token}`,this.client.request(i)}catch{console.error(Se.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,r){try{let s=new ze.default;return s.append("name",e),s.append("runtime",n),s.append("code",i,{filename:"function.zip"}),r&&s.append("configuration",JSON.stringify(r)),(await this.client.post(`/v1/projects/${this.projectId}/functions`,s,{headers:{...s.getHeaders()},maxContentLength:1/0,maxBodyLength:1/0})).data}catch(s){throw this._handleError(s,"Failed to deploy function")}}async updateFunction(e,n,i){try{let r=new ze.default;return r.append("code",n,{filename:"function.zip"}),i&&r.append("configuration",JSON.stringify(i)),(await this.client.put(`/v1/projects/${this.projectId}/functions/${e}`,r,{headers:{...r.getHeaders()},maxContentLength:1/0,maxBodyLength:1/0})).data}catch(r){throw this._handleError(r,`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(r){throw this._handleError(r,"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 r=u=>u.status?"status":u.progress?"progress":u.completed?"completed":u.failed||u.error?"failed":u.connected?"connected":"message",s=`${this.baseUrl}v1/projects/${this.projectId}/functions/${e}/deployment/stream`,a={Accept:"text/event-stream","Cache-Control":"no-cache"};if(this.credentials)try{let u=await this.credentials.retrieve();if(u&&u.keyId&&u.keySecret){let l=Buffer.from(`${u.keyId}:${u.keySecret}`).toString("base64");a.Authorization=`Basic ${l}`}}catch(u){console.error("Failed to add authentication:",u)}let c=null;try{c=new AbortController;let u=await fetch(s,{method:"GET",headers:a,signal:c.signal});if(!u.ok)throw new Error(`SSE connection failed: ${u.status} ${u.statusText}`);if(!u.body)throw new Error("Response body is null");let l=u.body.getReader(),g=new TextDecoder,h="";return(async()=>{let C="";try{for(;;){let{done:M,value:G}=await l.read();if(M)break;let P=g.decode(G,{stream:!0});h+=P;let b=h.split(`
3
3
  `);h=b.pop()||"";for(let w of b){if(w.startsWith("event:")){C=w.substring(6).trim();continue}if(w.startsWith("data:")){let y=w.substring(5).trim();if(y)try{let k=JSON.parse(y),X=C||r(k);n({type:X,data:k}),C=""}catch{n({type:C||"message",data:y}),C=""}}w===""&&(C="")}}}catch(M){M.name!=="AbortError"&&i&&i(M)}})(),()=>{c&&c.abort()}}catch(u){throw console.error("Failed to create SSE stream:",u),i&&i(u),u}}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(Se.default.yellow("Failed to get authentication token:",e.message)),null}}async authenticateOAuth(e,n){try{let i="https://auth.sinch.com/oauth2/token",r=new URLSearchParams;r.append("grant_type","client_credentials");let a=(await Be.default.post(i,r,{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(Be.default.isAxiosError(e)){let i=e;if(i.response){let r=i.response.status,s=i.response.data,a=s?.message||s?.error||i.message;throw r===401?new Error('Authentication required. Please run "sinch auth login" first.'):r===403?new Error(`Permission denied: ${a}`):r===404?new Error(`Resource not found: ${a}`):r>=500?new Error(`Server error: ${a}`):new Error(`${n}: ${a}`)}else throw i.request?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`):new Error(`${n}: ${i.message}`)}else throw new Error(`${n}: ${e.message||e}`)}}});var A,wt,ve,R,B,Ke,bt=fe(()=>{"use strict";A=m(require("keytar")),wt=m(require("os")),ve=m(require("chalk")),R="sinch-functions-cli",B=wt.userInfo().username,Ke=class{config;constructor(e){this.config=e}async store(e){let{projectId:n,keyId:i,keySecret:r,applicationKey:s,applicationSecret:a}=e;await A.setPassword(R,`${B}-keySecret`,r),await A.setPassword(R,s,a),this.config.set("projectId",n),this.config.set("keyId",i),this.config.set("defaultApplicationKey",s),this.config.set("credentialsStored",!0),await this.config.save()}async storeOAuthToken(e){let{access_token:n,refresh_token:i,expires_in:r,token_type:s}=e,a=new Date(Date.now()+r*1e3).toISOString();await A.setPassword(R,`${B}-oauth-access`,n),i&&await A.setPassword(R,`${B}-oauth-refresh`,i),this.config.set("oauthTokenType",s),this.config.set("oauthExpiresAt",a),this.config.set("oauthStored",!0),await this.config.save()}async getOAuthToken(){if(!this.config.get("oauthStored"))return null;let n=this.config.get("oauthExpiresAt");if(n&&new Date(n)<new Date){console.log(ve.default.gray("Token expired, re-authenticating..."));try{let r=await A.getPassword(R,`${B}-keySecret`),s=this.config.get("keyId");if(s&&r){let{SinchAPI:a}=(U(),N(Ve)),u=await new a({apiUrl:this.config.get("apiUrl")||"http://localhost:5000",projectId:this.config.get("projectId"),credentials:null}).authenticateOAuth(s,r);return await this.storeOAuthToken(u),console.log(ve.default.green("\u2713 Token renewed successfully")),u.access_token}else return console.warn(ve.default.yellow("Missing credentials for re-authentication. Please login again.")),null}catch(r){return console.warn(ve.default.yellow("Failed to renew OAuth token. Please login again.")),console.error(ve.default.gray(`Authentication error: ${r.message}`)),null}}return await A.getPassword(R,`${B}-oauth-access`)}async storeApplicationSecret(e,n){await A.setPassword(R,e,n),this.config.get("defaultApplicationKey")||(this.config.set("defaultApplicationKey",e),await this.config.save())}async retrieve(){if(!this.config.get("credentialsStored"))return null;let n=this.config.get("projectId"),i=this.config.get("keyId"),r=this.config.get("defaultApplicationKey"),s=await A.getPassword(R,`${B}-keySecret`),a=r?await A.getPassword(R,r):null;return!s||!a?null:{projectId:n,keyId:i,keySecret:s,applicationKey:r,applicationSecret:a}}async getApplicationCredentials(e=null){if(e||(e=this.config.get("defaultApplicationKey")),!e)return null;let n=await A.getPassword(R,e);return n?{applicationKey:e,applicationSecret:n}:null}async clear(){let e=this.config.get("defaultApplicationKey");await A.deletePassword(R,`${B}-keySecret`),await A.deletePassword(R,`${B}-oauth-access`),await A.deletePassword(R,`${B}-oauth-refresh`),e&&await A.deletePassword(R,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),await this.config.save()}async hasCredentials(){if(!this.config.get("credentialsStored"))return!1;let n=await A.getPassword(R,`${B}-keySecret`),i=this.config.get("defaultApplicationKey"),r=i?await A.getPassword(R,i):null;return!!(n&&r)}async hasOAuthToken(){return this.config.get("oauthStored")?!!await A.getPassword(R,`${B}-oauth-access`):!1}getPublicInfo(){return{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")}}async createSinchClient(e=null){let n=await this.getApplicationCredentials(e);if(!n)throw new Error('No credentials found. Please run "sinch auth login" first.');let{SinchClient:i}=require("@sinch/sdk-core");return new i({applicationKey:n.applicationKey,applicationSecret:n.applicationSecret,projectId:this.config.get("projectId")})}async storeBasicAuthToken(e){await A.setPassword(R,`${B}-basic-auth`,e),this.config.set("basicAuthStored",!0),await this.config.save()}async getBasicAuthToken(){return this.config.get("basicAuthStored")?await A.getPassword(R,`${B}-basic-auth`):null}async clearBasicAuthToken(){await A.deletePassword(R,`${B}-basic-auth`),this.config.set("basicAuthStored",!1),await this.config.save()}}});var ge={};Ue(ge,{Config:()=>qe,config:()=>p});var H,Te,Ct,Ye,qe,p,T=fe(()=>{"use strict";H=m(require("fs-extra")),Te=m(require("path")),Ct=m(require("os")),Ye=m(require("chalk"));bt();qe=class{configDir;configFile;projectConfigFile;_config=null;_projectConfig=null;_credentials=null;constructor(){this.configDir=Te.join(Ct.homedir(),".sinch"),this.configFile=Te.join(this.configDir,"config.json"),this.projectConfigFile=Te.join(process.cwd(),"sinch.json")}async load(){try{await H.ensureDir(this.configDir),await H.pathExists(this.configFile)?this._config=await H.readJson(this.configFile):(this._config=this._getDefaultConfig(),await this.save())}catch(e){console.warn(Ye.default.yellow(`Warning: Could not load config: ${e.message}`)),this._config=this._getDefaultConfig()}this._credentials=new Ke(this);try{await H.pathExists(this.projectConfigFile)&&(this._projectConfig=await H.readJson(this.projectConfigFile))}catch(e){console.warn(Ye.default.yellow(`Warning: Could not load project config: ${e.message}`))}}async save(){try{await H.ensureDir(this.configDir),await H.writeJson(this.configFile,this._config,{spaces:2})}catch(e){throw new Error(`Could not save config: ${e.message}`)}}async saveProjectConfig(){try{if(this._projectConfig){let e=Te.join(process.cwd(),"sinch.json");await H.writeJson(e,this._projectConfig,{spaces:2})}}catch(e){throw new Error(`Could not save project config: ${e.message}`)}}get(e,n=null){if(!this._config)throw new Error("Config not loaded. Call load() first.");return this._projectConfig&&this._projectConfig[e]!==void 0?this._projectConfig[e]:this._config[e]!==void 0?this._config[e]:n}set(e,n,i=!1){if(!this._config)throw new Error("Config not loaded. Call load() first.");i?(this._projectConfig||(this._projectConfig={}),this._projectConfig[e]=n):this._config[e]=n}getApiConfig(){return{apiUrl:this.get("apiUrl"),projectId:this.get("projectId"),timeout:this.get("timeout"),credentials:this._credentials}}async initProject(e,n="node",i={},r=null){let s={name:e,runtime:n,version:"1.0.0",description:`Sinch Functions project: ${e}`,created:new Date().toISOString()};return i&&Object.keys(i).length>0&&(s.variables=i),r&&(s.applicationKey=r),this._projectConfig=s,await this.saveProjectConfig(),s}isInProject(){return this._projectConfig!==null}getProjectConfig(){return this._projectConfig}_getDefaultConfig(){return{apiUrl:"https://api.functions.dev.sinchvoice.org",projectId:"default-project",timeout:0,created:new Date().toISOString(),version:"1.0.0"}}async storeCredentials(e){if(!this._credentials)throw new Error("Config not loaded. Call load() first.");return await this._credentials.store(e)}async getCredentials(){if(!this._credentials)throw new Error("Config not loaded. Call load() first.");return await this._credentials.retrieve()}async clearCredentials(){if(!this._credentials)throw new Error("Config not loaded. Call load() first.");return await this._credentials.clear()}async hasCredentials(){if(!this._credentials)throw new Error("Config not loaded. Call load() first.");return await this._credentials.hasCredentials()}getPublicCredentialInfo(){if(!this._credentials)throw new Error("Config not loaded. Call load() first.");return this._credentials.getPublicInfo()}async createSinchClient(e=null){if(!this._credentials)throw new Error("Config not loaded. Call load() first.");return!e&&this.isInProject()&&(e=this._projectConfig?.applicationKey||null),await this._credentials.createSinchClient(e)}async getApplicationCredentials(e=null){if(!this._credentials)throw new Error("Config not loaded. Call load() first.");return!e&&this.isInProject()&&(e=this._projectConfig?.applicationKey||null),await this._credentials.getApplicationCredentials(e)}async storeApplicationSecret(e,n){if(!this._credentials)throw new Error("Config not loaded. Call load() first.");return await this._credentials.storeApplicationSecret(e,n)}getTunnelPreference(){return this._projectConfig&&this._projectConfig.tunnel?.preference||null}async setTunnelPreference(e){if(!this._projectConfig)throw new Error("Not in a project directory");this._projectConfig.tunnel||(this._projectConfig.tunnel={}),this._projectConfig.tunnel.preference=e,this._projectConfig.tunnel.lastUpdated=new Date().toISOString(),await this.saveProjectConfig()}getTunnelSubdomain(){return this._projectConfig&&this._projectConfig.tunnel?.subdomain||null}async setTunnelSubdomain(e){if(!this._projectConfig)throw new Error("Not in a project directory");this._projectConfig.tunnel||(this._projectConfig.tunnel={}),this._projectConfig.tunnel.subdomain=e,this._projectConfig.tunnel.lastUpdated=new Date().toISOString(),await this.saveProjectConfig()}getTunnelUrl(){return this._projectConfig&&this._projectConfig.tunnel?.lastUrl||null}async setTunnelUrl(e){if(!this._projectConfig)throw new Error("Not in a project directory");this._projectConfig.tunnel||(this._projectConfig.tunnel={}),this._projectConfig.tunnel.lastUrl=e,this._projectConfig.tunnel.lastUpdated=new Date().toISOString(),await this.saveProjectConfig()}},p=new qe});var z,se,Qe,$t,Ze,t,V=fe(()=>{"use strict";z=m(require("chalk")),se=m(require("fs")),Qe=m(require("path")),$t=m(require("os")),Ze=class{verbose;logFile;constructor(e={}){this.verbose=e.verbose||process.env.VERBOSE==="true";let n="cli";try{let i=Qe.join(process.cwd(),"sinch.json");se.existsSync(i)&&(n=JSON.parse(se.readFileSync(i,"utf8")).name||"cli")}catch{}this.logFile=Qe.join($t.tmpdir(),`sinch-${n}.log`);try{se.writeFileSync(this.logFile,`=== Sinch CLI Debug Log - ${new Date().toISOString()} ===
4
4
  `,{flag:"w"})}catch{}}writeToFile(e,n,...i){try{let s=`[${new Date().toISOString()}] ${e}: ${n} ${i.length>0?JSON.stringify(i):""}
5
5
  `;se.appendFileSync(this.logFile,s)}catch{}}info(e,...n){console.log(z.default.blue("\u2139"),e,...n),this.writeToFile("INFO",e,...n)}success(e,...n){console.log(z.default.green("\u2705"),e,...n),this.writeToFile("SUCCESS",e,...n)}warn(e,...n){console.log(z.default.yellow("\u26A0\uFE0F "),e,...n),this.writeToFile("WARN",e,...n)}error(e,...n){console.log(z.default.red("\u274C"),e,...n),this.writeToFile("ERROR",e,...n)}debug(e,...n){this.writeToFile("DEBUG",e,...n),(this.verbose||process.env.DEBUG)&&console.log(z.default.gray("\u{1F41B}"),z.default.gray(e),...n)}log(e,...n){console.log(e,...n)}title(e){console.log(z.default.blue.bold(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinch/cli",
3
- "version": "0.0.0-dev.2090814404",
3
+ "version": "0.0.0-dev.2090888165",
4
4
  "description": "Official Sinch CLI - Manage all Sinch products from your terminal",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -37,7 +37,7 @@
37
37
  "blessed": "^0.1.81",
38
38
  "chalk": "^4.1.2",
39
39
  "chokidar": "^3.6.0",
40
- "cli-spinners": "^3.2.0",
40
+ "cli-spinners": "^2.9.2",
41
41
  "cli-table3": "^0.6.3",
42
42
  "clipboardy": "^2.3.0",
43
43
  "commander": "^12.1.0",