@stackone/cli 1.13.8 → 1.13.9
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/cli.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const e=require(`./cliCore-
|
|
2
|
+
const e=require(`./cliCore-BsjOfUWI.cjs`);new e.t().run();
|
package/dist/cli.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{t as e}from"./cliCore-
|
|
2
|
+
import{t as e}from"./cliCore-DxsQrkJc.mjs";new e().run();export{};
|
|
@@ -48,8 +48,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
48
48
|
`),await this.uploadFile(t,o,i.apiKey)&&n++;console.info(`
|
|
49
49
|
`),x.info(`Upload completed: ${n} of ${e.length} file(s) uploaded successfully.`),process.exit(n>0?0:1)}else t.endsWith(`.s1.yaml`)||(x.error(`Only .s1.yaml files are supported for upload.`),process.exit(1));let s=await this.uploadFile(t,o,i.apiKey);process.exit(s?0:1)}async uploadFile(e,t,n){try{console.info(l.default.blue(`📤 Uploading ${(0,_.basename)(e)}...`));let r=Ig(e);if(!r)return!1;let i=(0,_.basename)(e),a=new FormData,o=new Blob([r],{type:`application/x-yaml`});a.append(`file`,o,i);let s=Buffer.from(n).toString(`base64`),c=await fetch(`${t}/registry/connectors`,{method:`POST`,headers:{Authorization:`Basic ${s}`},body:a});if(!c.ok){let e=await c.text();return x.error(`Upload failed: ${c.status} - ${c.statusText}`),e&&console.error(l.default.red(e)),!1}let u=await c.json();return console.info(l.default.green(`✓ Successfully uploaded ${i} with connector "${u.provider}@${u.version}"`)),!0}catch(e){return x.error(`Failed to upload file: ${e}`),!1}}};const Ig=e=>{let t=(0,b.loadConnector)(e),n=(0,b.validateYamlConnector)(t),r=n?.errors??[];if(n.success){let n=e.split(`/`).pop()||e;return x.success(`Connector ${n} is valid!`),t}else r.length>0?(x.error(`Connector ${e} is not valid. Please fix the following errors:\n`),r.forEach(e=>{console.info(l.default.red(`- L${e.line}: ${e.message}`))})):x.error(`Connector ${e} is not valid. Please check the file for errors.`)},Lg=e=>{let t=[],n=(0,g.readdirSync)(e,{withFileTypes:!0});for(let r of n){let n=(0,_.join)(e,r.name);r.isDirectory()?t.push(...Lg(n)):r.name.endsWith(`.s1.yaml`)&&t.push(n)}return t},Rg=$.object({provider_key:$.string().optional(),provider_version:$.string().optional(),auth_config_key:$.string(),environment:$.string().default(`production`),organization_id:$.string().default(`cli-organization-id`),account_id:$.string().default(`cli-account-secure-id`),project_id:$.string().default(`cli-project-secure-id`),credentials:$.record($.string(),$.any()).default({})}),zg=$.record($.string(),$.any()),Bg=$.object({path:$.record($.string(),$.any()).default({}),queryParams:$.record($.string(),$.any()).default({}),header:$.record($.string(),$.any()).default({}),body:$.record($.string(),$.any()).default({})}),Vg=`https://api.stackone.com`;var Hg=class{async execute({connector:e,action:t,actionId:n,account:r,accountId:i,params:a,credentials:o,profile:s,outputFile:c,debug:u,apiUrl:d,apiKey:f}={}){if(!s&&!f&&i&&(S.error(`Profile or API key is required when providing an account ID`),S.log(`Please provide a profile using the ${C(`--profile`)} option or an API key using the ${C(`--api-key`)} option.`),S.log(`To create a profile, run ${C(`stackone init`)}.`),process.exit(1)),s&&f&&(S.error(`Please provide either a profile or an API key, not both`),process.exit(1)),s&&d&&S.warn(`Specifying --api-url with a profile won't have any effect. Using API url from profile.`),s&&!We(s)){S.error(`Configuration profile ${C(s)} not found`),S.log(`Run ${C(`stackone init`)} to create a new configuration profile.\n`);let e=Ke();e.length>0&&(S.info(`Available configuration profiles:`),e.forEach(e=>{S.log(` - ${l.default.blue(e)}`)})),process.exit(1)}let p=s?Ue(s):{apiUrl:d??Vg,apiKey:f};P(r)&&P(i)&&(S.error(`A valid account or account ID is required to run an action`),process.exit(1));let m;N(e)?this.#a(e)?(!s&&!f&&(S.error(`Profile or API key is required when using a connector identifier (provider_key@version)`),S.log(`Please provide a profile using the ${C(`--profile`)} option or an API key using the ${C(`--api-key`)} option.`),S.log(`Run ${C(`stackone init`)} to create a new configuration profile.`),process.exit(1)),m=await this.#o(e,p?.apiUrl??Vg,p?.apiKey)):m=this.#e(e):N(i)&&(m=await this.#s(i,p?.apiUrl??Vg,p?.apiKey));let h=N(t)?this.#r(t,e):m;P(h)&&(S.error(`A valid connector is required to run an action.`),process.exit(1));let ee=N(h?.actions)?Object.keys(h?.actions).length:0,_=N(h?.actions)?Object.keys(h.actions)[ee-1]:void 0,te=N(_)?h?.actions?.[_]?.id:void 0,v=(N(n)&&!n?.startsWith(`${h.key}_`)?`${h.key}_${n}`:n)??te;P(v)&&(S.error(`A valid action ID is required to run an action`),process.exit(1));let ne=N(i)?await this.#c(i,p?.apiUrl??Vg,p?.apiKey):{},re=N(r)?this.#i(r,h.key??`unknown`,h.version??`unknown`):void 0,y=N(o)?this.#l(o):{},ie={...ne,...re,credentials:{...ne.credentials??{},...y}};P(ie)&&(S.error(`A valid account data is required to run an action.`),process.exit(1));let ae=h.actions?.[v];P(ae)&&(S.error(`Action ID ${C(v)} not found in the connector ${C(h.key)}@${C(h.version)}.`),process.exit(1));let b=N(a)?this.#u(a,v):{path:{},queryParams:{},header:{},body:{}},oe=Date.now(),se=await this.#d({connector:h,actionId:v,account:ie,queryParams:{...b.queryParams,...u?{debug:`true`}:{}},pathParams:b.path,body:b.body,headers:b.header}),ce=Date.now()-oe;if(N(c))try{g.default.writeFileSync(c,JSON.stringify(se.output,null,2),`utf-8`),S.info(`Output written to file: ${c}`)}catch(e){S.error(`Failed to write output to file ${c}: ${e.message}`),process.exit(1)}else S.log(`\n${l.default.blue.inverse(` ACTION OUTPUT `)}`),pe(se.output);S.log(``),S.info(`Action ${C(v)} from connector ${C(h?.key)}@${C(h?.version)} finished in ${l.default.yellowBright((ce/1e3).toFixed(2))} seconds.`),process.exit(0)}#e=e=>{let t=e;try{t=(0,b.loadConnector)(e)}catch{}return t?this.#n(t):void 0};#t=e=>{try{return(0,b.loadConnector)(e)}catch(t){S.error(`Failed to load connector file from ${C(e)}: ${t.message}`),process.exit(1)}};#n=e=>{let t=(0,b.validateYamlConnector)(e),n=t?.errors??[];if(t.success)return t.connector||(S.error(`Failed to load connector.`),process.exit(1)),t.connector;n.length>0?(S.error(`Connector is not valid`),me(n,!0),process.exit(1)):(S.error(`Connector is not valid. Please check the file for errors.`),process.exit(1))};#r=(e,t)=>{let n=e;try{n=g.default.readFileSync(e,`utf-8`)}catch{}P(t)&&(S.error(`A valid connector is required to load an action.`),process.exit(1));let r=`${this.#t(t)} - ${n.split(`
|
|
50
50
|
`).map((e,t)=>t===0?e:` ${e}`).join(`
|
|
51
|
-
`)}`;return this.#n(r)};#i=(e,t,n)=>{let r=e;try{r=g.default.readFileSync(e,`utf-8`)}catch{}try{let e=Rg.parse(JSON.parse(r));return{providerKey:t,providerVersion:n,authConfigKey:e.auth_config_key,environment:e.environment,organizationId:e.organization_id,secureId:e.account_id,projectSecureId:e.project_id}}catch(e){let t=[];try{t=JSON.parse(e.message)}catch{}S.error(`Failed to parse account information`),me(t,!1),t.length===0&&S.log(e.message),process.exit(1)}};#a=e=>e.includes(`@`)&&e.split(`@`).length===2&&!e.includes(`/`)&&!e.includes(`\\`)&&!e.endsWith(`.yaml`)&&!e.endsWith(`.yml`);#o=async(e,t,n)=>{(P(e)||P(t)||P(n))&&(S.error(`Connector identifier, API URL, and API key are required to fetch connector from registry.`),process.exit(1));let r=(0,h.default)();try{r.text=`Fetching connector ${C(e)} from registry...`,r.start();let i=Buffer.from(n).toString(`base64`),a=await fetch(`${t}/registry/connectors/${e}`,{method:`GET`,headers:{Authorization:`Basic ${i}`}});r.stop(),a.ok||(await he(a,`Failed to fetch connector ${C(e)} from registry`),process.exit(1));let o=await a.text(),s=this.#n(o);return S.success(`Fetched connector ${C(s.key)}@${C(s.version)} from registry`),s}catch(n){r.stop(),S.error(`Failed to fetch connector ${C(e)} from registry: ${n.message}`),S.log(`Please ensure that the API at ${ge(t)} is reachable and the API key is valid.`),process.exit(1)}};#s=async(e,t,n)=>{(P(e)||P(t)||P(n))&&(S.error(`Account ID, API URL, and API key are required to fetch connector`),process.exit(1));let r=(0,h.default)();try{r.text=`Fetching connector for account ${C(e)} from API...`,r.start();let i=Buffer.from(n).toString(`base64`),a=await fetch(`${t}/accounts/${e}/connector`,{method:`GET`,headers:{Authorization:`Basic ${i}`}});r.stop(),a.ok||(await he(a,`Failed to fetch connector`),process.exit(1));let o=await a.text(),s=this.#n(o);return S.success(`Fetched connector ${C(s.key)}@${C(s.version)} for account ${C(e)}`),s}catch(e){r.stop(),S.error(`Failed to fetch connector: ${e.message}`),S.log(`Please ensure that the API at ${ge(t)} is reachable and the API key is valid.`),process.exit(1)}};#c=async(e,t,n)=>{(P(e)||P(t)||P(n))&&(S.error(`Account ID, API URL, and API key are required to fetch account information.`),process.exit(1));let r=(0,h.default)();try{r.text=`Fetching account ${C(e)} information from API...`,r.start();let i=Buffer.from(n).toString(`base64`),a=await fetch(`${t}/accounts/${e}/credentials`,{method:`GET`,headers:{Authorization:`Basic ${i}`}});r.stop(),a.ok||(await he(a,`Failed to fetch account ${C(e)} information`),process.exit(1));let o=await a.json();return S.success(`Fetched account ${C(e)} information from project ${C(o.project_id)}`),{providerKey:o.provider_key,providerVersion:o.provider_version,authConfigKey:o.auth_config_key,environment:o.environment,organizationId:o.organization_id,secureId:o.account_id,projectSecureId:o.project_id,credentials:o.credentials}}catch(n){r.stop(),S.error(`Failed to fetch account ${C(e)} information: ${n.message}`),S.log(`Please ensure that the API at ${ge(t)} is reachable and the API key is valid.`),process.exit(1)}};#l=e=>{let t=e;try{t=g.default.readFileSync(e,`utf-8`)}catch{}try{return zg.parse(JSON.parse(t))}catch(e){let t=[];try{t=JSON.parse(e.message)}catch{}S.error(`Failed to parse credentials`),me(t,!1),t.length===0&&S.log(e.message),process.exit(1)}};#u=(e,t)=>{let n=e;try{n=g.default.readFileSync(e,`utf-8`)}catch{}try{return Bg.parse(JSON.parse(n))}catch(e){let n=[];try{n=JSON.parse(e.message)}catch{}S.error(`Invalid parameters for action ${C(t)}.`),me(n,!1),n.length===0&&S.log(e.message),process.exit(1)}};async#d({connector:e,actionId:t,account:n,pathParams:r={},queryParams:i={},body:a={},headers:o={}}){try{let s=await(0,b.runAction)({mode:`action_id`,actionId:t,account:n,connector:e,pathParams:r,queryParams:i,body:a,headers:o,getHttpClient:async()=>new oe.HttpClient});if(s.response?.successful){let e={...this.#f(i,s.steps),...Qi(s.outputs)?s.outputs:{data:s.outputs}};return{statusCode:s.response?.statusCode,output:e}}else{let n=s.response?.message??`An error occurred while processing the request`;S.error(`Action ID ${C(t)} from connector ${C(e.key)}@${C(e.version)} failed with status ${s.response?.statusCode}: ${n}`);let r={...this.#f(i,s.steps)};Object.keys(r).length>0&&(S.log(`${l.default.yellow.inverse(` EXECUTION DETAILS `)}`),pe(r)),process.exit(1)}}catch(e){this.#p(e)}}#f(e,t){return e?.debug===`true`?{debug:{steps:t}}:{}}#p(e){let t=e;switch(P(t.errorType)&&(S.error(`An unknown error occurred`),S.log(`${e instanceof Error?e.message:String(e)}`),process.exit(1)),t.errorType){case`MISSING_ACTION_ERROR`:S.error(`The specified action was not found: ${t.message}`);break;case`INVALID_ACTION_INPUTS_ERROR`:let e=t;S.error(`Invalid action inputs`),me(e.validationErrors,!1);break;case`INVALID_CURSOR_ERROR`:S.error(`Invalid cursor: ${t.message}`);break;default:S.error(`An error occurred: ${t.message}`)}process.exit(1)}};const Ug=()=>{try{let e=(0,_.join)((0,_.dirname)((0,le.fileURLToPath)(require(`url`).pathToFileURL(__filename).href)),`..`,`package.json`);return JSON.parse((0,g.readFileSync)(e,`utf8`)).version}catch{return`unknown`}};var Wg=class{constructor(){this.packageName=`@stackone/cli`,this.currentVersion=Ug()}async execute(e={}){
|
|
51
|
+
`)}`;return this.#n(r)};#i=(e,t,n)=>{let r=e;try{r=g.default.readFileSync(e,`utf-8`)}catch{}try{let e=Rg.parse(JSON.parse(r));return{providerKey:t,providerVersion:n,authConfigKey:e.auth_config_key,environment:e.environment,organizationId:e.organization_id,secureId:e.account_id,projectSecureId:e.project_id}}catch(e){let t=[];try{t=JSON.parse(e.message)}catch{}S.error(`Failed to parse account information`),me(t,!1),t.length===0&&S.log(e.message),process.exit(1)}};#a=e=>e.includes(`@`)&&e.split(`@`).length===2&&!e.includes(`/`)&&!e.includes(`\\`)&&!e.endsWith(`.yaml`)&&!e.endsWith(`.yml`);#o=async(e,t,n)=>{(P(e)||P(t)||P(n))&&(S.error(`Connector identifier, API URL, and API key are required to fetch connector from registry.`),process.exit(1));let r=(0,h.default)();try{r.text=`Fetching connector ${C(e)} from registry...`,r.start();let i=Buffer.from(n).toString(`base64`),a=await fetch(`${t}/registry/connectors/${e}`,{method:`GET`,headers:{Authorization:`Basic ${i}`}});r.stop(),a.ok||(await he(a,`Failed to fetch connector ${C(e)} from registry`),process.exit(1));let o=await a.text(),s=this.#n(o);return S.success(`Fetched connector ${C(s.key)}@${C(s.version)} from registry`),s}catch(n){r.stop(),S.error(`Failed to fetch connector ${C(e)} from registry: ${n.message}`),S.log(`Please ensure that the API at ${ge(t)} is reachable and the API key is valid.`),process.exit(1)}};#s=async(e,t,n)=>{(P(e)||P(t)||P(n))&&(S.error(`Account ID, API URL, and API key are required to fetch connector`),process.exit(1));let r=(0,h.default)();try{r.text=`Fetching connector for account ${C(e)} from API...`,r.start();let i=Buffer.from(n).toString(`base64`),a=await fetch(`${t}/accounts/${e}/connector`,{method:`GET`,headers:{Authorization:`Basic ${i}`}});r.stop(),a.ok||(await he(a,`Failed to fetch connector`),process.exit(1));let o=await a.text(),s=this.#n(o);return S.success(`Fetched connector ${C(s.key)}@${C(s.version)} for account ${C(e)}`),s}catch(e){r.stop(),S.error(`Failed to fetch connector: ${e.message}`),S.log(`Please ensure that the API at ${ge(t)} is reachable and the API key is valid.`),process.exit(1)}};#c=async(e,t,n)=>{(P(e)||P(t)||P(n))&&(S.error(`Account ID, API URL, and API key are required to fetch account information.`),process.exit(1));let r=(0,h.default)();try{r.text=`Fetching account ${C(e)} information from API...`,r.start();let i=Buffer.from(n).toString(`base64`),a=await fetch(`${t}/accounts/${e}/credentials`,{method:`GET`,headers:{Authorization:`Basic ${i}`}});r.stop(),a.ok||(await he(a,`Failed to fetch account ${C(e)} information`),process.exit(1));let o=await a.json();return S.success(`Fetched account ${C(e)} information from project ${C(o.project_id)}`),{providerKey:o.provider_key,providerVersion:o.provider_version,authConfigKey:o.auth_config_key,environment:o.environment,organizationId:o.organization_id,secureId:o.account_id,projectSecureId:o.project_id,credentials:o.credentials}}catch(n){r.stop(),S.error(`Failed to fetch account ${C(e)} information: ${n.message}`),S.log(`Please ensure that the API at ${ge(t)} is reachable and the API key is valid.`),process.exit(1)}};#l=e=>{let t=e;try{t=g.default.readFileSync(e,`utf-8`)}catch{}try{return zg.parse(JSON.parse(t))}catch(e){let t=[];try{t=JSON.parse(e.message)}catch{}S.error(`Failed to parse credentials`),me(t,!1),t.length===0&&S.log(e.message),process.exit(1)}};#u=(e,t)=>{let n=e;try{n=g.default.readFileSync(e,`utf-8`)}catch{}try{return Bg.parse(JSON.parse(n))}catch(e){let n=[];try{n=JSON.parse(e.message)}catch{}S.error(`Invalid parameters for action ${C(t)}.`),me(n,!1),n.length===0&&S.log(e.message),process.exit(1)}};async#d({connector:e,actionId:t,account:n,pathParams:r={},queryParams:i={},body:a={},headers:o={}}){try{let s=await(0,b.runAction)({mode:`action_id`,actionId:t,account:n,connector:e,pathParams:r,queryParams:i,body:a,headers:o,getHttpClient:async()=>new oe.HttpClient});if(s.response?.successful){let e={...this.#f(i,s.steps),...Qi(s.outputs)?s.outputs:{data:s.outputs}};return{statusCode:s.response?.statusCode,output:e}}else{let n=s.response?.message??`An error occurred while processing the request`;S.error(`Action ID ${C(t)} from connector ${C(e.key)}@${C(e.version)} failed with status ${s.response?.statusCode}: ${n}`);let r={...this.#f(i,s.steps)};Object.keys(r).length>0&&(S.log(`${l.default.yellow.inverse(` EXECUTION DETAILS `)}`),pe(r)),process.exit(1)}}catch(e){this.#p(e)}}#f(e,t){return e?.debug===`true`?{debug:{steps:t}}:{}}#p(e){let t=e;switch(P(t.errorType)&&(S.error(`An unknown error occurred`),S.log(`${e instanceof Error?e.message:String(e)}`),process.exit(1)),t.errorType){case`MISSING_ACTION_ERROR`:S.error(`The specified action was not found: ${t.message}`);break;case`INVALID_ACTION_INPUTS_ERROR`:let e=t;S.error(`Invalid action inputs`),me(e.validationErrors,!1);break;case`INVALID_CURSOR_ERROR`:S.error(`Invalid cursor: ${t.message}`);break;default:S.error(`An error occurred: ${t.message}`)}process.exit(1)}};const Ug=()=>{try{let e=(0,_.join)((0,_.dirname)((0,le.fileURLToPath)(require(`url`).pathToFileURL(__filename).href)),`..`,`package.json`);return JSON.parse((0,g.readFileSync)(e,`utf8`)).version}catch{return`unknown`}};var Wg=class{constructor(){this.packageName=`@stackone/cli`,this.spinner=(0,h.default)(),this.currentVersion=Ug()}async execute(e={}){this.spinner.text=`Checking for updates...`,this.spinner.start();try{let t=this.getLatestVersion();this.spinner.stop(),t||(S.error(`Failed to check for updates`),process.exit(1)),this.isNewerVersion(t,this.currentVersion)?(S.box(`New version available: ${l.default.yellow(this.currentVersion)} → ${l.default.green(t)}`),this.performUpdate(t)):e.force?(S.warn(`No updates available, but forcing reinstall...`),this.performUpdate(t)):S.success(`You are already on the latest version (${this.currentVersion})`),process.exit(0)}catch(e){this.spinner.stop(),S.error(`Error while trying to update StackOne CLI: ${e?.message??`Unknown error`}`),process.exit(1)}}getLatestVersion(){try{return(0,d.execSync)(`npm view ${this.packageName} version`,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`]}).trim()}catch{return null}}isNewerVersion(e,t){return ce.default.gt(e,t)}isUsingVolta(){if(typeof process.env.VOLTA_HOME!=`string`||process.env.VOLTA_HOME.length===0)return!1;let e=(0,p.join)(process.env.VOLTA_HOME,`bin`),t=(0,p.join)(e,`stackone`),n=(0,p.join)(e,`stackone.exe`);return(0,se.existsSync)(t)||(0,se.existsSync)(n)}performUpdate(e){let t=this.isUsingVolta();this.spinner.text=`Updating to latest version (${C(e)})...`,this.spinner.start();try{(0,d.execSync)(t?`volta install ${this.packageName}@latest`:`npm install -g ${this.packageName}@latest`,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`]}),this.spinner.stop(),S.success(`StackOne CLI updated successfully to latest version (${C(e)})`)}catch{this.spinner.stop();let e=t?`volta install ${this.packageName}@latest`:`npm install -g ${this.packageName}@latest`;throw Error(`Failed to install update. Please try manually: ${e}`)}}},Gg=class{async execute(e){let{watchMode:t,fileOrDir:n}=e,r=(0,h.default)(`Watching for changes...`),i=()=>{console.clear(),console.info(l.default.yellow(`Watch mode enabled. Press "q" to quit.
|
|
52
52
|
`))};if(n){try{(0,g.statSync)(n)}catch{x.error(`File or directory not found: ${n}`),process.exit(1)}if(t){let{watch:e}=await import(`chokidar`),t=(await import(`readline`)).createInterface({input:process.stdin,output:process.stdout});process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.setEncoding(`utf8`);let a=()=>{console.info(l.default.grey(`
|
|
53
53
|
|
|
54
54
|
Exiting watch mode...`)),o.close(),r.stop(),t.close(),process.exit(0)};i(),console.info(l.default.blue(`Running connector(s) validations...`)),await Kg(n),r.start();let o=e(n||`.`,{ignored:/(^|[/\\])\../,persistent:!0});o.on(`change`,async e=>{i(),r.stop(),console.info(l.default.blue(`File change detected. Running connector(s) validations...`)),await Kg(n),r.start()}),process.stdin.on(`data`,e=>{e.toString()===`q`&&a()}),process.on(`SIGINT`,()=>{a()})}else await Kg(n),process.exit(0)}}};const Kg=async e=>{let t=(0,g.statSync)(e);if(t.isDirectory()){let t=(0,g.readdirSync)(e).filter(e=>e.endsWith(`.s1.yaml`));if(t.length===0){x.error(`No StackOne connectors found in directory: ${e}. Connector files need to have the extension .s1.yaml.\n`);return}let n=0,r=0;for(let i of t){let t=`${e}/${i}`;(0,g.statSync)(t).isFile()&&(await qg(t)?n++:r++)}x.info(`Validation completed: ${n} valid, ${r} invalid connectors.\n`)}else t.isFile()&&e.endsWith(`s1.yaml`)?await qg(e):x.error(`No StackOne connector found: ${e}. Connector files need to have the extension .s1.yaml.\n`)},qg=async e=>{let t=(0,b.validateYamlConnector)((0,b.loadConnector)(e)),n=t?.errors??[];if(t.success){let t=e.split(`/`).pop()||e;return x.success(`Connector ${t} is valid!\n`),!0}else if(n.length>0)return x.error(`Connector ${e} is not valid. Please fix the following errors:\n`),n.forEach(e=>{console.info(l.default.red(`- L${e.line}: ${e.message}`))}),console.info(`
|
|
55
|
-
`),!1;else return x.error(`Connector ${e} is not valid. Please check the file for errors.`),!1},Jg=`@stackone/cli`,Yg=2880*60*1e3,Xg=(0,p.join)((0,ue.homedir)(),`.stackone`),Zg=(0,p.join)(Xg,`version-check.json`),Qg=(e=!1)=>{let t=
|
|
55
|
+
`),!1;else return x.error(`Connector ${e} is not valid. Please check the file for errors.`),!1},Jg=`@stackone/cli`,Yg=2880*60*1e3,Xg=(0,p.join)((0,ue.homedir)(),`.stackone`),Zg=(0,p.join)(Xg,`version-check.json`),Qg=(e=!1)=>{let t=n_(),n=Date.now();if(e||!t||n-t.lastCheckTime>1728e5){let e=$g();e&&e_(e)&&t_(e),r_({lastCheckTime:n})}},$g=()=>{try{return(0,d.execSync)(`npm view @stackone/cli version`,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`],timeout:15e3}).trim()}catch{return null}},e_=e=>{try{let t=Ug();return ce.default.gt(e,t)}catch{return!1}},t_=e=>{let t=Ug(),n=`Update available: ${l.default.dim(t)} → ${l.default.green(e)}`,r=`\n\nRun ${l.default.cyan(`stackone update`)} to update`;S.box(n,r)},n_=()=>{try{if(!(0,se.existsSync)(Zg))return null;let e=(0,se.readFileSync)(Zg,`utf-8`);return JSON.parse(e)}catch{return null}},r_=e=>{try{(0,se.existsSync)(Xg)||(0,se.mkdirSync)(Xg,{recursive:!0}),(0,se.writeFileSync)(Zg,JSON.stringify(e,null,2),`utf-8`)}catch{}};var i_=class{constructor(e=new u.Command,t=Ug()){this.program=e,this.version=t,this.setupProgram(),this.registerCommands()}setupProgram(){this.program.name(`stackone`).description(`StackOne CLI`).version(this.version,`-v, --version`)}registerCommands(){let e=new Ng,t=new Fg,n=new Je,r=new kg,i=new Gg,a=new Ie,o=new Be,s=new je,c=new Hg,d=new Wg;this.program.configureOutput({writeOut:e=>process.stdout.write(e),writeErr:e=>process.stderr.write(e),outputError:(e,t)=>{t(l.default.red(e))}}),this.program.command(`init`).option(`-e, --env <environment>`,`Specify the environment for the configuration profile`).description(`Initialize & create a StackOne CLI configuration profile`).action(t=>{e.execute({environment:t.env})}),this.program.command(`push`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).addArgument(new u.Argument(`<path>`,`Connector file or directory to push`)).description(`Push a connector to the StackOne registry`).action((e,n)=>{t.execute({profile:n.profile,fileOrDir:e,apiUrl:n.apiUrl,apiKey:n.apiKey})}),this.program.command(`drop`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).addArgument(new u.Argument(`<connector>`,`Connector identifier in format provider_key@version`)).description(`Drop a connector from the StackOne registry`).action((e,t)=>{n.execute({profile:t.profile,connector:e,apiUrl:t.apiUrl,apiKey:t.apiKey})}),this.program.command(`get`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).option(`--connector <connector>`,`Connector identifier in format provider_key@version`).option(`--account-id <account-id>`,`Account ID to fetch connector from`).option(`-f, --format <format>`,`Output format: yaml or json (default: yaml)`,`yaml`).option(`-o, --output-file <output-file>`,`File to write the output to`).description(`Get a connector from the StackOne registry`).action(e=>{r.execute({profile:e.profile,connector:e.connector,accountId:e.accountId,format:e.format,outputFile:e.outputFile,apiUrl:e.apiUrl,apiKey:e.apiKey})}),this.program.command(`validate`).option(`-w, --watch`,`Run in watch mode`).addArgument(new u.Argument(`<path>`,`Connector file or directory with connectors to validate`)).description(`Validate a StackOne connector`).action((e,t)=>{i.execute({watchMode:t.watch,fileOrDir:e})}),this.program.command(`run`).option(`--connector <connector>`,`Connector file to run (optional when using --account-id)`).option(`--action <action>`,`Action to execute on the connector (path to file or inline string action code)`).option(`--action-id <action-id>`,`Action ID to execute on the connector`).option(`--account <account>`,`Account details to use for running the connector (path to file or inline string account data)`).option(`--account-id <account-id>`,`Account ID to use for running the connector against (fetches connector from API if --connector not provided)`).option(`--params <params>`,`Action parameters (path to file or inline string with JSON parameters)`).option(`--credentials <credentials>`,`Credentials to use (path to file or inline string with JSON credentials)`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).option(`-o, --output-file <output-file>`,`File to write the output to`).option(`-d, --debug`,`Enables debug mode to include more details in the action execution output`).description(`Run a connector action`).action(e=>{c.execute({connector:e.connector,action:e.action,actionId:e.actionId,account:e.account,accountId:e.accountId,params:e.params,credentials:e.credentials,profile:e.profile,outputFile:e.outputFile,debug:e.debug,apiUrl:e.apiUrl,apiKey:e.apiKey})});let f=this.program.command(`agent`).description(`StackOne agent commands`);f.command(`setup`).option(`-g, --global`,`Setup global configuration`).option(`-l, --local`,`Setup local project configuration`).description(`Setup StackOne agent (global or local)`).action(e=>{e.global?a.execute():o.execute()}),f.command(`cleanup`).description(`Remove all API keys and credentials from configurations`).action(()=>{s.execute()}),this.program.command(`update`).option(`-f, --force`,`Force reinstall even if already on latest version`).description(`Update the CLI to the latest version`).action(e=>{d.execute({force:e.force})}),this.program.command(`version`).description(`Show version information`).action(async()=>{S.log(`${l.default.inverse.greenBright(`StackOne`)} ${l.default.grey(`CLI`)} ${l.default.whiteBright(this.version)}`),Qg(!0),process.exit(0)})}run(){process.argv.includes(`version`)||Qg(),this.program.parse(process.argv)}};Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return i_}});
|
|
@@ -48,8 +48,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
48
48
|
`),await this.uploadFile(t,o,i.apiKey)&&n++;console.info(`
|
|
49
49
|
`),y.info(`Upload completed: ${n} of ${e.length} file(s) uploaded successfully.`),process.exit(n>0?0:1)}else t.endsWith(`.s1.yaml`)||(y.error(`Only .s1.yaml files are supported for upload.`),process.exit(1));let s=await this.uploadFile(t,o,i.apiKey);process.exit(s?0:1)}async uploadFile(e,n,r){try{console.info(t.blue(`📤 Uploading ${ie(e)}...`));let i=Pp(e);if(!i)return!1;let a=ie(e),o=new FormData,s=new Blob([i],{type:`application/x-yaml`});o.append(`file`,s,a);let c=Buffer.from(r).toString(`base64`),l=await fetch(`${n}/registry/connectors`,{method:`POST`,headers:{Authorization:`Basic ${c}`},body:o});if(!l.ok){let e=await l.text();return y.error(`Upload failed: ${l.status} - ${l.statusText}`),e&&console.error(t.red(e)),!1}let u=await l.json();return console.info(t.green(`✓ Successfully uploaded ${a} with connector "${u.provider}@${u.version}"`)),!0}catch(e){return y.error(`Failed to upload file: ${e}`),!1}}};const Pp=e=>{let n=he(e),r=_e(n),i=r?.errors??[];if(r.success){let t=e.split(`/`).pop()||e;return y.success(`Connector ${t} is valid!`),n}else i.length>0?(y.error(`Connector ${e} is not valid. Please fix the following errors:\n`),i.forEach(e=>{console.info(t.red(`- L${e.line}: ${e.message}`))})):y.error(`Connector ${e} is not valid. Please check the file for errors.`)},Fp=e=>{let t=[],n=g(e,{withFileTypes:!0});for(let r of n){let n=oe(e,r.name);r.isDirectory()?t.push(...Fp(n)):r.name.endsWith(`.s1.yaml`)&&t.push(n)}return t},Ip=$.object({provider_key:$.string().optional(),provider_version:$.string().optional(),auth_config_key:$.string(),environment:$.string().default(`production`),organization_id:$.string().default(`cli-organization-id`),account_id:$.string().default(`cli-account-secure-id`),project_id:$.string().default(`cli-project-secure-id`),credentials:$.record($.string(),$.any()).default({})}),Lp=$.record($.string(),$.any()),Rp=$.object({path:$.record($.string(),$.any()).default({}),queryParams:$.record($.string(),$.any()).default({}),header:$.record($.string(),$.any()).default({}),body:$.record($.string(),$.any()).default({})}),zp=`https://api.stackone.com`;var Bp=class{async execute({connector:e,action:n,actionId:r,account:i,accountId:a,params:o,credentials:s,profile:c,outputFile:l,debug:u,apiUrl:d,apiKey:p}={}){if(!c&&!p&&a&&(b.error(`Profile or API key is required when providing an account ID`),b.log(`Please provide a profile using the ${x(`--profile`)} option or an API key using the ${x(`--api-key`)} option.`),b.log(`To create a profile, run ${x(`stackone init`)}.`),process.exit(1)),c&&p&&(b.error(`Please provide either a profile or an API key, not both`),process.exit(1)),c&&d&&b.warn(`Specifying --api-url with a profile won't have any effect. Using API url from profile.`),c&&!ft(c)){b.error(`Configuration profile ${x(c)} not found`),b.log(`Run ${x(`stackone init`)} to create a new configuration profile.\n`);let e=mt();e.length>0&&(b.info(`Available configuration profiles:`),e.forEach(e=>{b.log(` - ${t.blue(e)}`)})),process.exit(1)}let m=c?dt(c):{apiUrl:d??zp,apiKey:p};P(i)&&P(a)&&(b.error(`A valid account or account ID is required to run an action`),process.exit(1));let h;N(e)?this.#a(e)?(!c&&!p&&(b.error(`Profile or API key is required when using a connector identifier (provider_key@version)`),b.log(`Please provide a profile using the ${x(`--profile`)} option or an API key using the ${x(`--api-key`)} option.`),b.log(`Run ${x(`stackone init`)} to create a new configuration profile.`),process.exit(1)),h=await this.#o(e,m?.apiUrl??zp,m?.apiKey)):h=this.#e(e):N(a)&&(h=await this.#s(a,m?.apiUrl??zp,m?.apiKey));let g=N(n)?this.#r(n,e):h;P(g)&&(b.error(`A valid connector is required to run an action.`),process.exit(1));let ee=N(g?.actions)?Object.keys(g?.actions).length:0,te=N(g?.actions)?Object.keys(g.actions)[ee-1]:void 0,ne=N(te)?g?.actions?.[te]?.id:void 0,re=(N(r)&&!r?.startsWith(`${g.key}_`)?`${g.key}_${r}`:r)??ne;P(re)&&(b.error(`A valid action ID is required to run an action`),process.exit(1));let ie=N(a)?await this.#c(a,m?.apiUrl??zp,m?.apiKey):{},ae=N(i)?this.#i(i,g.key??`unknown`,g.version??`unknown`):void 0,oe=N(s)?this.#l(s):{},se={...ie,...ae,credentials:{...ie.credentials??{},...oe}};P(se)&&(b.error(`A valid account data is required to run an action.`),process.exit(1));let _=g.actions?.[re];P(_)&&(b.error(`Action ID ${x(re)} not found in the connector ${x(g.key)}@${x(g.version)}.`),process.exit(1));let ce=N(o)?this.#u(o,re):{path:{},queryParams:{},header:{},body:{}},le=Date.now(),ue=await this.#d({connector:g,actionId:re,account:se,queryParams:{...ce.queryParams,...u?{debug:`true`}:{}},pathParams:ce.path,body:ce.body,headers:ce.header}),de=Date.now()-le;if(N(l))try{f.writeFileSync(l,JSON.stringify(ue.output,null,2),`utf-8`),b.info(`Output written to file: ${l}`)}catch(e){b.error(`Failed to write output to file ${l}: ${e.message}`),process.exit(1)}else b.log(`\n${t.blue.inverse(` ACTION OUTPUT `)}`),Re(ue.output);b.log(``),b.info(`Action ${x(re)} from connector ${x(g?.key)}@${x(g?.version)} finished in ${t.yellowBright((de/1e3).toFixed(2))} seconds.`),process.exit(0)}#e=e=>{let t=e;try{t=he(e)}catch{}return t?this.#n(t):void 0};#t=e=>{try{return he(e)}catch(t){b.error(`Failed to load connector file from ${x(e)}: ${t.message}`),process.exit(1)}};#n=e=>{let t=_e(e),n=t?.errors??[];if(t.success)return t.connector||(b.error(`Failed to load connector.`),process.exit(1)),t.connector;n.length>0?(b.error(`Connector is not valid`),ze(n,!0),process.exit(1)):(b.error(`Connector is not valid. Please check the file for errors.`),process.exit(1))};#r=(e,t)=>{let n=e;try{n=f.readFileSync(e,`utf-8`)}catch{}P(t)&&(b.error(`A valid connector is required to load an action.`),process.exit(1));let r=`${this.#t(t)} - ${n.split(`
|
|
50
50
|
`).map((e,t)=>t===0?e:` ${e}`).join(`
|
|
51
|
-
`)}`;return this.#n(r)};#i=(e,t,n)=>{let r=e;try{r=f.readFileSync(e,`utf-8`)}catch{}try{let e=Ip.parse(JSON.parse(r));return{providerKey:t,providerVersion:n,authConfigKey:e.auth_config_key,environment:e.environment,organizationId:e.organization_id,secureId:e.account_id,projectSecureId:e.project_id}}catch(e){let t=[];try{t=JSON.parse(e.message)}catch{}b.error(`Failed to parse account information`),ze(t,!1),t.length===0&&b.log(e.message),process.exit(1)}};#a=e=>e.includes(`@`)&&e.split(`@`).length===2&&!e.includes(`/`)&&!e.includes(`\\`)&&!e.endsWith(`.yaml`)&&!e.endsWith(`.yml`);#o=async(e,t,n)=>{(P(e)||P(t)||P(n))&&(b.error(`Connector identifier, API URL, and API key are required to fetch connector from registry.`),process.exit(1));let r=d();try{r.text=`Fetching connector ${x(e)} from registry...`,r.start();let i=Buffer.from(n).toString(`base64`),a=await fetch(`${t}/registry/connectors/${e}`,{method:`GET`,headers:{Authorization:`Basic ${i}`}});r.stop(),a.ok||(await Be(a,`Failed to fetch connector ${x(e)} from registry`),process.exit(1));let o=await a.text(),s=this.#n(o);return b.success(`Fetched connector ${x(s.key)}@${x(s.version)} from registry`),s}catch(n){r.stop(),b.error(`Failed to fetch connector ${x(e)} from registry: ${n.message}`),b.log(`Please ensure that the API at ${Ve(t)} is reachable and the API key is valid.`),process.exit(1)}};#s=async(e,t,n)=>{(P(e)||P(t)||P(n))&&(b.error(`Account ID, API URL, and API key are required to fetch connector`),process.exit(1));let r=d();try{r.text=`Fetching connector for account ${x(e)} from API...`,r.start();let i=Buffer.from(n).toString(`base64`),a=await fetch(`${t}/accounts/${e}/connector`,{method:`GET`,headers:{Authorization:`Basic ${i}`}});r.stop(),a.ok||(await Be(a,`Failed to fetch connector`),process.exit(1));let o=await a.text(),s=this.#n(o);return b.success(`Fetched connector ${x(s.key)}@${x(s.version)} for account ${x(e)}`),s}catch(e){r.stop(),b.error(`Failed to fetch connector: ${e.message}`),b.log(`Please ensure that the API at ${Ve(t)} is reachable and the API key is valid.`),process.exit(1)}};#c=async(e,t,n)=>{(P(e)||P(t)||P(n))&&(b.error(`Account ID, API URL, and API key are required to fetch account information.`),process.exit(1));let r=d();try{r.text=`Fetching account ${x(e)} information from API...`,r.start();let i=Buffer.from(n).toString(`base64`),a=await fetch(`${t}/accounts/${e}/credentials`,{method:`GET`,headers:{Authorization:`Basic ${i}`}});r.stop(),a.ok||(await Be(a,`Failed to fetch account ${x(e)} information`),process.exit(1));let o=await a.json();return b.success(`Fetched account ${x(e)} information from project ${x(o.project_id)}`),{providerKey:o.provider_key,providerVersion:o.provider_version,authConfigKey:o.auth_config_key,environment:o.environment,organizationId:o.organization_id,secureId:o.account_id,projectSecureId:o.project_id,credentials:o.credentials}}catch(n){r.stop(),b.error(`Failed to fetch account ${x(e)} information: ${n.message}`),b.log(`Please ensure that the API at ${Ve(t)} is reachable and the API key is valid.`),process.exit(1)}};#l=e=>{let t=e;try{t=f.readFileSync(e,`utf-8`)}catch{}try{return Lp.parse(JSON.parse(t))}catch(e){let t=[];try{t=JSON.parse(e.message)}catch{}b.error(`Failed to parse credentials`),ze(t,!1),t.length===0&&b.log(e.message),process.exit(1)}};#u=(e,t)=>{let n=e;try{n=f.readFileSync(e,`utf-8`)}catch{}try{return Rp.parse(JSON.parse(n))}catch(e){let n=[];try{n=JSON.parse(e.message)}catch{}b.error(`Invalid parameters for action ${x(t)}.`),ze(n,!1),n.length===0&&b.log(e.message),process.exit(1)}};async#d({connector:e,actionId:n,account:r,pathParams:i={},queryParams:a={},body:o={},headers:s={}}){try{let c=await ge({mode:`action_id`,actionId:n,account:r,connector:e,pathParams:i,queryParams:a,body:o,headers:s,getHttpClient:async()=>new ve});if(c.response?.successful){let e={...this.#f(a,c.steps),...jn(c.outputs)?c.outputs:{data:c.outputs}};return{statusCode:c.response?.statusCode,output:e}}else{let r=c.response?.message??`An error occurred while processing the request`;b.error(`Action ID ${x(n)} from connector ${x(e.key)}@${x(e.version)} failed with status ${c.response?.statusCode}: ${r}`);let i={...this.#f(a,c.steps)};Object.keys(i).length>0&&(b.log(`${t.yellow.inverse(` EXECUTION DETAILS `)}`),Re(i)),process.exit(1)}}catch(e){this.#p(e)}}#f(e,t){return e?.debug===`true`?{debug:{steps:t}}:{}}#p(e){let t=e;switch(P(t.errorType)&&(b.error(`An unknown error occurred`),b.log(`${e instanceof Error?e.message:String(e)}`),process.exit(1)),t.errorType){case`MISSING_ACTION_ERROR`:b.error(`The specified action was not found: ${t.message}`);break;case`INVALID_ACTION_INPUTS_ERROR`:let e=t;b.error(`Invalid action inputs`),ze(e.validationErrors,!1);break;case`INVALID_CURSOR_ERROR`:b.error(`Invalid cursor: ${t.message}`);break;default:b.error(`An error occurred: ${t.message}`)}process.exit(1)}};const Vp=()=>{try{let e=oe(ae(we(import.meta.url)),`..`,`package.json`);return JSON.parse(h(e,`utf8`)).version}catch{return`unknown`}};var Hp=class{constructor(){this.packageName=`@stackone/cli`,this.currentVersion=Vp()}async execute(e={}){
|
|
51
|
+
`)}`;return this.#n(r)};#i=(e,t,n)=>{let r=e;try{r=f.readFileSync(e,`utf-8`)}catch{}try{let e=Ip.parse(JSON.parse(r));return{providerKey:t,providerVersion:n,authConfigKey:e.auth_config_key,environment:e.environment,organizationId:e.organization_id,secureId:e.account_id,projectSecureId:e.project_id}}catch(e){let t=[];try{t=JSON.parse(e.message)}catch{}b.error(`Failed to parse account information`),ze(t,!1),t.length===0&&b.log(e.message),process.exit(1)}};#a=e=>e.includes(`@`)&&e.split(`@`).length===2&&!e.includes(`/`)&&!e.includes(`\\`)&&!e.endsWith(`.yaml`)&&!e.endsWith(`.yml`);#o=async(e,t,n)=>{(P(e)||P(t)||P(n))&&(b.error(`Connector identifier, API URL, and API key are required to fetch connector from registry.`),process.exit(1));let r=d();try{r.text=`Fetching connector ${x(e)} from registry...`,r.start();let i=Buffer.from(n).toString(`base64`),a=await fetch(`${t}/registry/connectors/${e}`,{method:`GET`,headers:{Authorization:`Basic ${i}`}});r.stop(),a.ok||(await Be(a,`Failed to fetch connector ${x(e)} from registry`),process.exit(1));let o=await a.text(),s=this.#n(o);return b.success(`Fetched connector ${x(s.key)}@${x(s.version)} from registry`),s}catch(n){r.stop(),b.error(`Failed to fetch connector ${x(e)} from registry: ${n.message}`),b.log(`Please ensure that the API at ${Ve(t)} is reachable and the API key is valid.`),process.exit(1)}};#s=async(e,t,n)=>{(P(e)||P(t)||P(n))&&(b.error(`Account ID, API URL, and API key are required to fetch connector`),process.exit(1));let r=d();try{r.text=`Fetching connector for account ${x(e)} from API...`,r.start();let i=Buffer.from(n).toString(`base64`),a=await fetch(`${t}/accounts/${e}/connector`,{method:`GET`,headers:{Authorization:`Basic ${i}`}});r.stop(),a.ok||(await Be(a,`Failed to fetch connector`),process.exit(1));let o=await a.text(),s=this.#n(o);return b.success(`Fetched connector ${x(s.key)}@${x(s.version)} for account ${x(e)}`),s}catch(e){r.stop(),b.error(`Failed to fetch connector: ${e.message}`),b.log(`Please ensure that the API at ${Ve(t)} is reachable and the API key is valid.`),process.exit(1)}};#c=async(e,t,n)=>{(P(e)||P(t)||P(n))&&(b.error(`Account ID, API URL, and API key are required to fetch account information.`),process.exit(1));let r=d();try{r.text=`Fetching account ${x(e)} information from API...`,r.start();let i=Buffer.from(n).toString(`base64`),a=await fetch(`${t}/accounts/${e}/credentials`,{method:`GET`,headers:{Authorization:`Basic ${i}`}});r.stop(),a.ok||(await Be(a,`Failed to fetch account ${x(e)} information`),process.exit(1));let o=await a.json();return b.success(`Fetched account ${x(e)} information from project ${x(o.project_id)}`),{providerKey:o.provider_key,providerVersion:o.provider_version,authConfigKey:o.auth_config_key,environment:o.environment,organizationId:o.organization_id,secureId:o.account_id,projectSecureId:o.project_id,credentials:o.credentials}}catch(n){r.stop(),b.error(`Failed to fetch account ${x(e)} information: ${n.message}`),b.log(`Please ensure that the API at ${Ve(t)} is reachable and the API key is valid.`),process.exit(1)}};#l=e=>{let t=e;try{t=f.readFileSync(e,`utf-8`)}catch{}try{return Lp.parse(JSON.parse(t))}catch(e){let t=[];try{t=JSON.parse(e.message)}catch{}b.error(`Failed to parse credentials`),ze(t,!1),t.length===0&&b.log(e.message),process.exit(1)}};#u=(e,t)=>{let n=e;try{n=f.readFileSync(e,`utf-8`)}catch{}try{return Rp.parse(JSON.parse(n))}catch(e){let n=[];try{n=JSON.parse(e.message)}catch{}b.error(`Invalid parameters for action ${x(t)}.`),ze(n,!1),n.length===0&&b.log(e.message),process.exit(1)}};async#d({connector:e,actionId:n,account:r,pathParams:i={},queryParams:a={},body:o={},headers:s={}}){try{let c=await ge({mode:`action_id`,actionId:n,account:r,connector:e,pathParams:i,queryParams:a,body:o,headers:s,getHttpClient:async()=>new ve});if(c.response?.successful){let e={...this.#f(a,c.steps),...jn(c.outputs)?c.outputs:{data:c.outputs}};return{statusCode:c.response?.statusCode,output:e}}else{let r=c.response?.message??`An error occurred while processing the request`;b.error(`Action ID ${x(n)} from connector ${x(e.key)}@${x(e.version)} failed with status ${c.response?.statusCode}: ${r}`);let i={...this.#f(a,c.steps)};Object.keys(i).length>0&&(b.log(`${t.yellow.inverse(` EXECUTION DETAILS `)}`),Re(i)),process.exit(1)}}catch(e){this.#p(e)}}#f(e,t){return e?.debug===`true`?{debug:{steps:t}}:{}}#p(e){let t=e;switch(P(t.errorType)&&(b.error(`An unknown error occurred`),b.log(`${e instanceof Error?e.message:String(e)}`),process.exit(1)),t.errorType){case`MISSING_ACTION_ERROR`:b.error(`The specified action was not found: ${t.message}`);break;case`INVALID_ACTION_INPUTS_ERROR`:let e=t;b.error(`Invalid action inputs`),ze(e.validationErrors,!1);break;case`INVALID_CURSOR_ERROR`:b.error(`Invalid cursor: ${t.message}`);break;default:b.error(`An error occurred: ${t.message}`)}process.exit(1)}};const Vp=()=>{try{let e=oe(ae(we(import.meta.url)),`..`,`package.json`);return JSON.parse(h(e,`utf8`)).version}catch{return`unknown`}};var Hp=class{constructor(){this.packageName=`@stackone/cli`,this.spinner=d(),this.currentVersion=Vp()}async execute(e={}){this.spinner.text=`Checking for updates...`,this.spinner.start();try{let n=this.getLatestVersion();this.spinner.stop(),n||(b.error(`Failed to check for updates`),process.exit(1)),this.isNewerVersion(n,this.currentVersion)?(b.box(`New version available: ${t.yellow(this.currentVersion)} → ${t.green(n)}`),this.performUpdate(n)):e.force?(b.warn(`No updates available, but forcing reinstall...`),this.performUpdate(n)):b.success(`You are already on the latest version (${this.currentVersion})`),process.exit(0)}catch(e){this.spinner.stop(),b.error(`Error while trying to update StackOne CLI: ${e?.message??`Unknown error`}`),process.exit(1)}}getLatestVersion(){try{return a(`npm view ${this.packageName} version`,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`]}).trim()}catch{return null}}isNewerVersion(e,t){return Ce.gt(e,t)}isUsingVolta(){if(typeof process.env.VOLTA_HOME!=`string`||process.env.VOLTA_HOME.length===0)return!1;let e=l(process.env.VOLTA_HOME,`bin`),t=l(e,`stackone`),n=l(e,`stackone.exe`);return ye(t)||ye(n)}performUpdate(e){let t=this.isUsingVolta();this.spinner.text=`Updating to latest version (${x(e)})...`,this.spinner.start();try{a(t?`volta install ${this.packageName}@latest`:`npm install -g ${this.packageName}@latest`,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`]}),this.spinner.stop(),b.success(`StackOne CLI updated successfully to latest version (${x(e)})`)}catch{this.spinner.stop();let e=t?`volta install ${this.packageName}@latest`:`npm install -g ${this.packageName}@latest`;throw Error(`Failed to install update. Please try manually: ${e}`)}}},Up=class{async execute(e){let{watchMode:n,fileOrDir:r}=e,i=d(`Watching for changes...`),a=()=>{console.clear(),console.info(t.yellow(`Watch mode enabled. Press "q" to quit.
|
|
52
52
|
`))};if(r){try{te(r)}catch{y.error(`File or directory not found: ${r}`),process.exit(1)}if(n){let{watch:e}=await import(`chokidar`),n=(await import(`readline`)).createInterface({input:process.stdin,output:process.stdout});process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.setEncoding(`utf8`);let o=()=>{console.info(t.grey(`
|
|
53
53
|
|
|
54
54
|
Exiting watch mode...`)),s.close(),i.stop(),n.close(),process.exit(0)};a(),console.info(t.blue(`Running connector(s) validations...`)),await Wp(r),i.start();let s=e(r||`.`,{ignored:/(^|[/\\])\../,persistent:!0});s.on(`change`,async e=>{a(),i.stop(),console.info(t.blue(`File change detected. Running connector(s) validations...`)),await Wp(r),i.start()}),process.stdin.on(`data`,e=>{e.toString()===`q`&&o()}),process.on(`SIGINT`,()=>{o()})}else await Wp(r),process.exit(0)}}};const Wp=async e=>{let t=te(e);if(t.isDirectory()){let t=g(e).filter(e=>e.endsWith(`.s1.yaml`));if(t.length===0){y.error(`No StackOne connectors found in directory: ${e}. Connector files need to have the extension .s1.yaml.\n`);return}let n=0,r=0;for(let i of t){let t=`${e}/${i}`;te(t).isFile()&&(await Gp(t)?n++:r++)}y.info(`Validation completed: ${n} valid, ${r} invalid connectors.\n`)}else t.isFile()&&e.endsWith(`s1.yaml`)?await Gp(e):y.error(`No StackOne connector found: ${e}. Connector files need to have the extension .s1.yaml.\n`)},Gp=async e=>{let n=_e(he(e)),r=n?.errors??[];if(n.success){let t=e.split(`/`).pop()||e;return y.success(`Connector ${t} is valid!\n`),!0}else if(r.length>0)return y.error(`Connector ${e} is not valid. Please fix the following errors:\n`),r.forEach(e=>{console.info(t.red(`- L${e.line}: ${e.message}`))}),console.info(`
|
|
55
|
-
`),!1;else return y.error(`Connector ${e} is not valid. Please check the file for errors.`),!1},Kp=l(Te(),`.stackone`),qp=l(Kp,`version-check.json`),Jp=(e=!1)=>{let t
|
|
55
|
+
`),!1;else return y.error(`Connector ${e} is not valid. Please check the file for errors.`),!1},Kp=l(Te(),`.stackone`),qp=l(Kp,`version-check.json`),Jp=(e=!1)=>{let t=Qp(),n=Date.now();if(e||!t||n-t.lastCheckTime>1728e5){let e=Yp();e&&Xp(e)&&Zp(e),$p({lastCheckTime:n})}},Yp=()=>{try{return a(`npm view @stackone/cli version`,{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`],timeout:15e3}).trim()}catch{return null}},Xp=e=>{try{let t=Vp();return Ce.gt(e,t)}catch{return!1}},Zp=e=>{let n=Vp(),r=`Update available: ${t.dim(n)} → ${t.green(e)}`,i=`\n\nRun ${t.cyan(`stackone update`)} to update`;b.box(r,i)},Qp=()=>{try{if(!ye(qp))return null;let e=xe(qp,`utf-8`);return JSON.parse(e)}catch{return null}},$p=e=>{try{ye(Kp)||be(Kp,{recursive:!0}),Se(qp,JSON.stringify(e,null,2),`utf-8`)}catch{}};var em=class{constructor(e=new r,t=Vp()){this.program=e,this.version=t,this.setupProgram(),this.registerCommands()}setupProgram(){this.program.name(`stackone`).description(`StackOne CLI`).version(this.version,`-v, --version`)}registerCommands(){let e=new jp,r=new Np,i=new gt,a=new Ap,o=new Up,s=new it,c=new ct,l=new et,u=new Bp,d=new Hp;this.program.configureOutput({writeOut:e=>process.stdout.write(e),writeErr:e=>process.stderr.write(e),outputError:(e,n)=>{n(t.red(e))}}),this.program.command(`init`).option(`-e, --env <environment>`,`Specify the environment for the configuration profile`).description(`Initialize & create a StackOne CLI configuration profile`).action(t=>{e.execute({environment:t.env})}),this.program.command(`push`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).addArgument(new n(`<path>`,`Connector file or directory to push`)).description(`Push a connector to the StackOne registry`).action((e,t)=>{r.execute({profile:t.profile,fileOrDir:e,apiUrl:t.apiUrl,apiKey:t.apiKey})}),this.program.command(`drop`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).addArgument(new n(`<connector>`,`Connector identifier in format provider_key@version`)).description(`Drop a connector from the StackOne registry`).action((e,t)=>{i.execute({profile:t.profile,connector:e,apiUrl:t.apiUrl,apiKey:t.apiKey})}),this.program.command(`get`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).option(`--connector <connector>`,`Connector identifier in format provider_key@version`).option(`--account-id <account-id>`,`Account ID to fetch connector from`).option(`-f, --format <format>`,`Output format: yaml or json (default: yaml)`,`yaml`).option(`-o, --output-file <output-file>`,`File to write the output to`).description(`Get a connector from the StackOne registry`).action(e=>{a.execute({profile:e.profile,connector:e.connector,accountId:e.accountId,format:e.format,outputFile:e.outputFile,apiUrl:e.apiUrl,apiKey:e.apiKey})}),this.program.command(`validate`).option(`-w, --watch`,`Run in watch mode`).addArgument(new n(`<path>`,`Connector file or directory with connectors to validate`)).description(`Validate a StackOne connector`).action((e,t)=>{o.execute({watchMode:t.watch,fileOrDir:e})}),this.program.command(`run`).option(`--connector <connector>`,`Connector file to run (optional when using --account-id)`).option(`--action <action>`,`Action to execute on the connector (path to file or inline string action code)`).option(`--action-id <action-id>`,`Action ID to execute on the connector`).option(`--account <account>`,`Account details to use for running the connector (path to file or inline string account data)`).option(`--account-id <account-id>`,`Account ID to use for running the connector against (fetches connector from API if --connector not provided)`).option(`--params <params>`,`Action parameters (path to file or inline string with JSON parameters)`).option(`--credentials <credentials>`,`Credentials to use (path to file or inline string with JSON credentials)`).option(`-p, --profile <label>`,`Configuration profile to use`).option(`--api-url <api url>`,`API URL`).option(`--api-key <api key>`,`API Key`).option(`-o, --output-file <output-file>`,`File to write the output to`).option(`-d, --debug`,`Enables debug mode to include more details in the action execution output`).description(`Run a connector action`).action(e=>{u.execute({connector:e.connector,action:e.action,actionId:e.actionId,account:e.account,accountId:e.accountId,params:e.params,credentials:e.credentials,profile:e.profile,outputFile:e.outputFile,debug:e.debug,apiUrl:e.apiUrl,apiKey:e.apiKey})});let f=this.program.command(`agent`).description(`StackOne agent commands`);f.command(`setup`).option(`-g, --global`,`Setup global configuration`).option(`-l, --local`,`Setup local project configuration`).description(`Setup StackOne agent (global or local)`).action(e=>{e.global?s.execute():c.execute()}),f.command(`cleanup`).description(`Remove all API keys and credentials from configurations`).action(()=>{l.execute()}),this.program.command(`update`).option(`-f, --force`,`Force reinstall even if already on latest version`).description(`Update the CLI to the latest version`).action(e=>{d.execute({force:e.force})}),this.program.command(`version`).description(`Show version information`).action(async()=>{b.log(`${t.inverse.greenBright(`StackOne`)} ${t.grey(`CLI`)} ${t.whiteBright(this.version)}`),Jp(!0),process.exit(0)})}run(){process.argv.includes(`version`)||Jp(),this.program.parse(process.argv)}};export{em as t};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=require(`./cliCore-
|
|
1
|
+
const e=require(`./cliCore-BsjOfUWI.cjs`);exports.CLI=e.t;
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./cliCore-
|
|
1
|
+
import{t as e}from"./cliCore-DxsQrkJc.mjs";export{e as CLI};
|