xtra-cli 1.0.4 → 1.0.5
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/bin/xtra.js +2 -294
- package/dist/commands/access.js +1 -184
- package/dist/commands/admin.js +5 -118
- package/dist/commands/audit.js +1 -67
- package/dist/commands/branch.js +1 -212
- package/dist/commands/checkout.js +1 -80
- package/dist/commands/ci.js +31 -341
- package/dist/commands/completion.js +85 -224
- package/dist/commands/diff.js +6 -162
- package/dist/commands/doctor.js +2 -164
- package/dist/commands/env.js +2 -70
- package/dist/commands/export.js +2 -83
- package/dist/commands/generate.js +3 -179
- package/dist/commands/history.js +4 -77
- package/dist/commands/import.js +1 -121
- package/dist/commands/init.js +7 -205
- package/dist/commands/integration.js +11 -188
- package/dist/commands/jit-run.js +5 -0
- package/dist/commands/local.js +16 -198
- package/dist/commands/login.js +16 -198
- package/dist/commands/login.test.js +16 -51
- package/dist/commands/logout.js +1 -0
- package/dist/commands/logs.js +3 -121
- package/dist/commands/profile.js +14 -184
- package/dist/commands/project.js +1 -165
- package/dist/commands/rollback.js +1 -95
- package/dist/commands/rotate.js +3 -93
- package/dist/commands/run.js +11 -215
- package/dist/commands/scan.js +25 -127
- package/dist/commands/secrets.js +14 -305
- package/dist/commands/simulate.js +6 -109
- package/dist/commands/status.js +2 -93
- package/dist/commands/template.js +22 -276
- package/dist/commands/ui.js +2 -289
- package/dist/commands/watch.js +17 -123
- package/dist/lib/api.js +1 -187
- package/dist/lib/api.test.js +1 -89
- package/dist/lib/audit.js +1 -136
- package/dist/lib/config.js +1 -72
- package/dist/lib/config.test.js +1 -47
- package/dist/lib/crypto.js +1 -50
- package/dist/lib/manifest.js +1 -52
- package/dist/lib/profiles.js +1 -103
- package/package.json +2 -2
package/dist/commands/branch.js
CHANGED
|
@@ -1,212 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.branchCommand = void 0;
|
|
7
|
-
const commander_1 = require("commander");
|
|
8
|
-
const api_1 = require("../lib/api");
|
|
9
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
-
const ora_1 = __importDefault(require("ora"));
|
|
11
|
-
const table_1 = require("table");
|
|
12
|
-
const config_1 = require("../lib/config");
|
|
13
|
-
const inquirer_1 = __importDefault(require("inquirer"));
|
|
14
|
-
exports.branchCommand = new commander_1.Command("branch")
|
|
15
|
-
.description("Manage branches")
|
|
16
|
-
.option("-p, --project <projectId>", "Project ID");
|
|
17
|
-
// LIST
|
|
18
|
-
exports.branchCommand
|
|
19
|
-
.command("list")
|
|
20
|
-
.description("List all branches")
|
|
21
|
-
.action(async (options) => {
|
|
22
|
-
// Access parent options (project ID)
|
|
23
|
-
const parentOpts = exports.branchCommand.opts();
|
|
24
|
-
let { project } = parentOpts;
|
|
25
|
-
if (!project)
|
|
26
|
-
project = (0, config_1.getRcConfig)().project;
|
|
27
|
-
if (!project) {
|
|
28
|
-
console.error(chalk_1.default.red("Error: Project ID is required. Use -p <id> or checkout a branch."));
|
|
29
|
-
process.exit(1);
|
|
30
|
-
}
|
|
31
|
-
const spinner = (0, ora_1.default)("Fetching branches...").start();
|
|
32
|
-
try {
|
|
33
|
-
const branches = await api_1.api.getBranches(project);
|
|
34
|
-
spinner.stop();
|
|
35
|
-
if (!branches) {
|
|
36
|
-
console.log(chalk_1.default.yellow("No branches found."));
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
if (!Array.isArray(branches)) {
|
|
40
|
-
// Check for error object
|
|
41
|
-
if (branches.error) {
|
|
42
|
-
console.error(chalk_1.default.red(`Error: ${branches.error}`));
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
console.error(chalk_1.default.red("Error: Unexpected API response format (not an array)."));
|
|
46
|
-
}
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
if (branches.length === 0) {
|
|
50
|
-
console.log(chalk_1.default.yellow("No branches found."));
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
const data = [[chalk_1.default.bold("Name"), chalk_1.default.bold("ID"), chalk_1.default.bold("Created By")]];
|
|
54
|
-
branches.forEach((b) => {
|
|
55
|
-
const createdBy = b.user?.email || b.user?.name || b.createdBy || "-";
|
|
56
|
-
data.push([b.name, b.id, createdBy]);
|
|
57
|
-
});
|
|
58
|
-
console.log((0, table_1.table)(data));
|
|
59
|
-
}
|
|
60
|
-
catch (error) {
|
|
61
|
-
spinner.fail("Failed to fetch branches");
|
|
62
|
-
if (error.response && error.response.data && error.response.data.error) {
|
|
63
|
-
console.error(chalk_1.default.red(`Server Error: ${error.response.data.error}`));
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
console.error(chalk_1.default.red(error.message));
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
// CREATE
|
|
71
|
-
exports.branchCommand
|
|
72
|
-
.command("create")
|
|
73
|
-
.description("Create a new branch")
|
|
74
|
-
.argument("<name>", "Branch name")
|
|
75
|
-
.option("-d, --description <text>", "Description")
|
|
76
|
-
.action(async (name, options) => {
|
|
77
|
-
const parentOpts = exports.branchCommand.opts();
|
|
78
|
-
let { project } = parentOpts;
|
|
79
|
-
const { description } = options;
|
|
80
|
-
if (!project)
|
|
81
|
-
project = (0, config_1.getRcConfig)().project;
|
|
82
|
-
if (!project) {
|
|
83
|
-
console.error(chalk_1.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first."));
|
|
84
|
-
process.exit(1);
|
|
85
|
-
}
|
|
86
|
-
const spinner = (0, ora_1.default)(`Creating branch '${name}'...`).start();
|
|
87
|
-
try {
|
|
88
|
-
await api_1.api.createBranch(project, name, description);
|
|
89
|
-
spinner.succeed(`Branch '${name}' created successfully.`);
|
|
90
|
-
}
|
|
91
|
-
catch (error) {
|
|
92
|
-
spinner.fail("Failed to create branch");
|
|
93
|
-
if (error.response && error.response.data && error.response.data.error) {
|
|
94
|
-
console.error(chalk_1.default.red(`Server Error: ${error.response.data.error}`));
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
console.error(chalk_1.default.red(error.message));
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
// DELETE
|
|
102
|
-
exports.branchCommand
|
|
103
|
-
.command("delete")
|
|
104
|
-
.description("Delete a branch")
|
|
105
|
-
.argument("<name>", "Branch name")
|
|
106
|
-
.option("-y, --yes", "Skip confirmation prompt", false)
|
|
107
|
-
.action(async (name, options) => {
|
|
108
|
-
const parentOpts = exports.branchCommand.opts();
|
|
109
|
-
let { project } = parentOpts;
|
|
110
|
-
const { yes } = options;
|
|
111
|
-
if (!project)
|
|
112
|
-
project = (0, config_1.getRcConfig)().project;
|
|
113
|
-
if (!project) {
|
|
114
|
-
console.error(chalk_1.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first."));
|
|
115
|
-
process.exit(1);
|
|
116
|
-
}
|
|
117
|
-
if (name === "main") {
|
|
118
|
-
console.error(chalk_1.default.red("Error: Cannot delete the 'main' branch."));
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
const spinner = (0, ora_1.default)("Resolving branch...").start();
|
|
122
|
-
try {
|
|
123
|
-
// 1. Resolve Name to ID
|
|
124
|
-
const branches = await api_1.api.getBranches(project);
|
|
125
|
-
const target = branches.find((b) => b.name === name);
|
|
126
|
-
if (!target) {
|
|
127
|
-
spinner.fail(`Branch '${name}' not found.`);
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
spinner.stop();
|
|
131
|
-
// 2. Confirm
|
|
132
|
-
if (!yes) {
|
|
133
|
-
const { confirm } = await inquirer_1.default.prompt([{
|
|
134
|
-
type: "confirm",
|
|
135
|
-
name: "confirm",
|
|
136
|
-
message: `Are you sure you want to DELETE branch '${name}'? This action cannot be undone.`,
|
|
137
|
-
default: false
|
|
138
|
-
}]);
|
|
139
|
-
if (!confirm) {
|
|
140
|
-
console.log(chalk_1.default.gray("Operation cancelled."));
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
// 3. Delete
|
|
145
|
-
spinner.start("Deleting branch...");
|
|
146
|
-
await api_1.api.deleteBranch(target.id);
|
|
147
|
-
spinner.succeed(`Branch '${name}' deleted successfully.`);
|
|
148
|
-
// Audit log
|
|
149
|
-
try {
|
|
150
|
-
const { logAudit } = require("../lib/audit");
|
|
151
|
-
logAudit("BRANCH_DELETED", project, null, { branchName: name, branchId: target.id });
|
|
152
|
-
}
|
|
153
|
-
catch (e) { }
|
|
154
|
-
}
|
|
155
|
-
catch (error) {
|
|
156
|
-
spinner.fail("Failed to delete branch");
|
|
157
|
-
if (error.response && error.response.data && error.response.data.error) {
|
|
158
|
-
console.error(chalk_1.default.red(`Server Error: ${error.response.data.error}`));
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
console.error(chalk_1.default.red(error.message));
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
// UPDATE
|
|
166
|
-
exports.branchCommand
|
|
167
|
-
.command("update")
|
|
168
|
-
.description("Update a branch")
|
|
169
|
-
.argument("<name>", "Current branch name")
|
|
170
|
-
.option("-n, --new-name <newName>", "New branch name")
|
|
171
|
-
.option("-d, --description <description>", "New description")
|
|
172
|
-
.action(async (name, options) => {
|
|
173
|
-
const parentOpts = exports.branchCommand.opts();
|
|
174
|
-
let { project } = parentOpts;
|
|
175
|
-
const { newName, description } = options;
|
|
176
|
-
if (!project)
|
|
177
|
-
project = (0, config_1.getRcConfig)().project;
|
|
178
|
-
if (!project) {
|
|
179
|
-
console.error(chalk_1.default.red("Error: Project ID is required. Use -p <id> or checkout a branch."));
|
|
180
|
-
process.exit(1);
|
|
181
|
-
}
|
|
182
|
-
if (!newName && !description) {
|
|
183
|
-
console.log(chalk_1.default.yellow("No updates specified. Use --new-name or --description."));
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
const spinner = (0, ora_1.default)("Resolving branch...").start();
|
|
187
|
-
try {
|
|
188
|
-
// 1. Resolve Name to ID
|
|
189
|
-
const branches = await api_1.api.getBranches(project);
|
|
190
|
-
const target = branches.find((b) => b.name === name);
|
|
191
|
-
if (!target) {
|
|
192
|
-
spinner.fail(`Branch '${name}' not found.`);
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
spinner.text = "Updating branch...";
|
|
196
|
-
// 2. Update
|
|
197
|
-
await api_1.api.updateBranch(target.id, {
|
|
198
|
-
name: newName,
|
|
199
|
-
description
|
|
200
|
-
});
|
|
201
|
-
spinner.succeed(`Branch updated successfully.`);
|
|
202
|
-
}
|
|
203
|
-
catch (error) {
|
|
204
|
-
spinner.fail("Failed to update branch");
|
|
205
|
-
if (error.response && error.response.data && error.response.data.error) {
|
|
206
|
-
console.error(chalk_1.default.red(`Server Error: ${error.response.data.error}`));
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
console.error(chalk_1.default.red(error.message));
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
});
|
|
1
|
+
var se=Object.create;var j=Object.defineProperty;var ne=Object.getOwnPropertyDescriptor;var oe=Object.getOwnPropertyNames;var ae=Object.getPrototypeOf,ie=Object.prototype.hasOwnProperty;var x=(e,t)=>()=>(e&&(t=e(e=0)),t);var N=(e,t)=>{for(var r in t)j(e,r,{get:t[r],enumerable:!0})},R=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of oe(t))!ie.call(e,n)&&n!==r&&j(e,n,{get:()=>t[n],enumerable:!(s=ne(t,n))||s.enumerable});return e};var g=(e,t,r)=>(r=e!=null?se(ae(e)):{},R(t||!e||!e.__esModule?j(r,"default",{value:e,enumerable:!0}):r,e)),L=e=>R(j({},"__esModule",{value:!0}),e);var O,A,T,C,f,k,y,P,w,S=x(()=>{O=g(require("conf")),A=g(require("fs")),T=g(require("path")),C="https://www.xtrasecurity.in/api",f=new O.default({projectName:"xtra-cli",defaults:{apiUrl:C}}),k=f.get("apiUrl");k&&!process.env.XTRA_API_URL&&(k.includes("localhost")||k.includes("xtra-security.vercel.app"))&&f.set("apiUrl",C);y=()=>({...f.store,apiUrl:process.env.XTRA_API_URL||f.get("apiUrl")||C}),P=()=>f.get("token"),w=()=>{let e={};try{let t=T.default.join(process.cwd(),".xtrarc");A.default.existsSync(t)&&(e=JSON.parse(A.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||f.get("project")||"",env:e.env||f.get("env")||"development",branch:e.branch||f.get("branch")||"main"}}});var _,F,q,ce,o,u,B=x(()=>{_=g(require("axios"));S();F=g(require("fs")),q=g(require("path")),ce=JSON.parse(F.readFileSync(q.join(__dirname,"../../package.json"),"utf-8")),o=()=>{let{apiUrl:e}=y(),t=P();return _.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":ce.version,...t?{Authorization:`Bearer ${t}`}:{}}})},u={login:async(e,t,r)=>(await o().post("/auth/cli-login",{email:e,password:t,apiKey:r})).data,getSecrets:async(e,t,r="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?branch=${r}`)).data,getSecretVersions:async(e,t,r="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${r}`)).data,setSecrets:async(e,t,r,s,n="main")=>(await o().post(`/projects/${e}/envs/${t}/secrets`,{secrets:r,expectedVersions:s,branch:n})).data,getSecretDetails:async(e,t,r,s="main")=>(await o().get(`/projects/${e}/envs/${t}/secrets/${r}?branch=${s}`)).data,syncLogs:async e=>(await o().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,r,s,n,a)=>(await o().post(`/projects/${e}/envs/${t}/secrets/link`,{key:r,sourceProjectId:s,sourceEnv:n,sourceKey:a})).data,rotateSecret:async(e,t,r,s,n)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/rotate`,{strategy:s,parsedNewValue:n})).data,promoteSecret:async(e,t,r)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/promote`,{})).data,verifyAuditLogs:async()=>(await o().get("/audit/verify")).data,exportAuditLogs:async(e,t,r,s)=>{let n={format:e};return t&&(n.startDate=t),r&&(n.endDate=r),s&&(n.projectId=s),(await o().post("/audit/export",n,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,r,s)=>(await o().post("/access/request",{projectId:e,secretId:s,reason:t,duration:r})).data,approveAccess:async(e,t)=>(await o().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=y(),r=t?`&workspaceId=${t}`:"";return(await o().get(`/access/list?mode=${e}${r}`)).data},getAccessRequestStatus:async e=>(await o().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=y(),t=e?`/project?workspaceId=${e}`:"/project";return(await o().get(t)).data},getBranches:async e=>(await o().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,r)=>(await o().post("/branch",{projectId:e,name:t,description:r})).data,deleteBranch:async e=>(await o().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await o().put("/branch",{id:e,...t})).data,getRoles:async()=>(await o().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await o().get(`/admin/users${t}`)).data},setUserRole:async(e,t,r)=>(await o().put("/admin/users/role",{email:e,role:t,teamId:r})).data,getIntegrationStatus:async e=>(await o().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await o().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await o().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let r=new URLSearchParams(t).toString();return(await o().get(`/projects/${e}/kubernetes?${r}`)).data},getSecretHistory:async(e,t,r)=>(await o().get(`/projects/${e}/envs/${t}/secrets/${r}/history`)).data,rollbackSecret:async(e,t,r,s)=>(await o().post(`/projects/${e}/envs/${t}/secrets/${r}/history`,{version:s})).data,cloneEnvironment:async(e,t,r,s,n)=>(await o().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:r,overwrite:s,branch:n})).data,generateJitLink:async e=>(await o().post("/jit/generate",e)).data,claimJitLink:async e=>(await o().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await o().get(`/jit/${e}`)).data,post:async(e,t)=>(await o().post(e,t)).data}});function H(){let e=J.get("masterKey");e||(e=m.default.randomBytes(32).toString("hex"),J.set("masterKey",e));let t=(0,K.machineIdSync)();return m.default.createHash("sha256").update(e+t).digest()}var m,G,K,V,J,z,M,X=x(()=>{m=g(require("crypto")),G=g(require("conf")),K=require("node-machine-id"),V="aes-256-gcm",J=new G.default({projectName:"xtra-cli-crypto"});z=e=>{let t=m.default.randomBytes(16),r=H(),s=m.default.createCipheriv(V,r,t),n=s.update(e,"utf8","hex");n+=s.final("hex");let a=s.getAuthTag();return{iv:t.toString("hex"),content:n,tag:a.toString("hex")}},M=e=>{let t=H(),r=Buffer.from(e.iv,"hex"),s=Buffer.from(e.tag,"hex"),n=m.default.createDecipheriv(V,t,r);n.setAuthTag(s);let a=n.update(e.content,"hex","utf8");return a+=n.final("utf8"),a}});var Y={};N(Y,{loadAuditLogs:()=>v,logAudit:()=>ge,saveAuditLogs:()=>$,syncAuditLogs:()=>de});function pe(e){if(!e||typeof e!="object")return e;let t={...e},r=["password","token","secret","value","apiKey","secretValue"];for(let s of Object.keys(t))r.some(n=>s.toLowerCase().includes(n))&&(t[s]="[REDACTED]");return t}async function W(e){try{if(!y().token)return!1;let r={action:e.action,entity:"cli-project",entityId:e.projectId||"global",details:pe(e.details),timestamp:e.timestamp,projectId:e.projectId};return await u.post("/audit/cli-logs",{logs:[r]}),!0}catch(t){return process.env.DEBUG&&console.error("Failed to send audit log to backend:",t),!1}}function ge(e,t,r,s){let n={id:(0,Q.v4)(),timestamp:new Date().toISOString(),action:e,projectId:t,environment:r,details:s,synced:!1},a=v();a.push(n),$(a),W(n).then(i=>{if(i){n.synced=!0;let p=v(),d=p.findIndex(I=>I.id===n.id);d!==-1&&(p[d].synced=!0,$(p))}}).catch(()=>{})}function v(){if(!h.default.existsSync(U))return[];try{let e=h.default.readFileSync(U,"utf-8"),t=JSON.parse(e),r=M(t);return JSON.parse(r)}catch{return[]}}function $(e){h.default.existsSync(E)||h.default.mkdirSync(E,{recursive:!0});let t=JSON.stringify(e),r=z(t);h.default.writeFileSync(U,JSON.stringify(r),"utf-8")}async function de(){let e=v(),t=e.filter(s=>!s.synced);if(t.length===0)return 0;let r=0;for(let s of t)await W(s)&&(s.synced=!0,r++);return r>0&&$(e),r}var h,D,Q,E,U,Z=x(()=>{h=g(require("fs")),D=g(require("path")),Q=require("uuid");X();S();B();E=D.default.join(process.cwd(),".xtra"),U=D.default.join(E,"audit.enc")});var ue={};N(ue,{branchCommand:()=>l});module.exports=L(ue);var ee=require("commander");B();var c=g(require("chalk")),b=g(require("ora")),te=require("table");S();var re=g(require("inquirer")),l=new ee.Command("branch").description("Manage branches").option("-p, --project <projectId>","Project ID");l.command("list").description("List all branches").action(async e=>{let t=l.opts(),{project:r}=t;r||(r=w().project),r||(console.error(c.default.red("Error: Project ID is required. Use -p <id> or checkout a branch.")),process.exit(1));let s=(0,b.default)("Fetching branches...").start();try{let n=await u.getBranches(r);if(s.stop(),!n){console.log(c.default.yellow("No branches found."));return}if(!Array.isArray(n)){n.error?console.error(c.default.red(`Error: ${n.error}`)):console.error(c.default.red("Error: Unexpected API response format (not an array)."));return}if(n.length===0){console.log(c.default.yellow("No branches found."));return}let a=[[c.default.bold("Name"),c.default.bold("ID"),c.default.bold("Created By")]];n.forEach(i=>{let p=i.user?.email||i.user?.name||i.createdBy||"-";a.push([i.name,i.id,p])}),console.log((0,te.table)(a))}catch(n){s.fail("Failed to fetch branches"),n.response&&n.response.data&&n.response.data.error?console.error(c.default.red(`Server Error: ${n.response.data.error}`)):console.error(c.default.red(n.message))}});l.command("create").description("Create a new branch").argument("<name>","Branch name").option("-d, --description <text>","Description").action(async(e,t)=>{let r=l.opts(),{project:s}=r,{description:n}=t;s||(s=w().project),s||(console.error(c.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1));let a=(0,b.default)(`Creating branch '${e}'...`).start();try{await u.createBranch(s,e,n),a.succeed(`Branch '${e}' created successfully.`)}catch(i){a.fail("Failed to create branch"),i.response&&i.response.data&&i.response.data.error?console.error(c.default.red(`Server Error: ${i.response.data.error}`)):console.error(c.default.red(i.message))}});l.command("delete").description("Delete a branch").argument("<name>","Branch name").option("-y, --yes","Skip confirmation prompt",!1).action(async(e,t)=>{let r=l.opts(),{project:s}=r,{yes:n}=t;if(s||(s=w().project),s||(console.error(c.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1)),e==="main"){console.error(c.default.red("Error: Cannot delete the 'main' branch."));return}let a=(0,b.default)("Resolving branch...").start();try{let p=(await u.getBranches(s)).find(d=>d.name===e);if(!p){a.fail(`Branch '${e}' not found.`);return}if(a.stop(),!n){let{confirm:d}=await re.default.prompt([{type:"confirm",name:"confirm",message:`Are you sure you want to DELETE branch '${e}'? This action cannot be undone.`,default:!1}]);if(!d){console.log(c.default.gray("Operation cancelled."));return}}a.start("Deleting branch..."),await u.deleteBranch(p.id),a.succeed(`Branch '${e}' deleted successfully.`);try{let{logAudit:d}=(Z(),L(Y));d("BRANCH_DELETED",s,null,{branchName:e,branchId:p.id})}catch{}}catch(i){a.fail("Failed to delete branch"),i.response&&i.response.data&&i.response.data.error?console.error(c.default.red(`Server Error: ${i.response.data.error}`)):console.error(c.default.red(i.message))}});l.command("update").description("Update a branch").argument("<name>","Current branch name").option("-n, --new-name <newName>","New branch name").option("-d, --description <description>","New description").action(async(e,t)=>{let r=l.opts(),{project:s}=r,{newName:n,description:a}=t;if(s||(s=w().project),s||(console.error(c.default.red("Error: Project ID is required. Use -p <id> or checkout a branch.")),process.exit(1)),!n&&!a){console.log(c.default.yellow("No updates specified. Use --new-name or --description."));return}let i=(0,b.default)("Resolving branch...").start();try{let d=(await u.getBranches(s)).find(I=>I.name===e);if(!d){i.fail(`Branch '${e}' not found.`);return}i.text="Updating branch...",await u.updateBranch(d.id,{name:n,description:a}),i.succeed("Branch updated successfully.")}catch(p){i.fail("Failed to update branch"),p.response&&p.response.data&&p.response.data.error?console.error(c.default.red(`Server Error: ${p.response.data.error}`)):console.error(c.default.red(p.message))}});0&&(module.exports={branchCommand});
|
|
@@ -1,80 +1 @@
|
|
|
1
|
-
"
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.checkoutCommand = void 0;
|
|
7
|
-
const commander_1 = require("commander");
|
|
8
|
-
const api_1 = require("../lib/api");
|
|
9
|
-
const config_1 = require("../lib/config");
|
|
10
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
11
|
-
const ora_1 = __importDefault(require("ora"));
|
|
12
|
-
const inquirer_1 = __importDefault(require("inquirer"));
|
|
13
|
-
exports.checkoutCommand = new commander_1.Command("checkout")
|
|
14
|
-
.description("Switch the active branch context")
|
|
15
|
-
.argument("[branchName]", "Branch name to switch to (optional - will show list if not provided)")
|
|
16
|
-
.option("-p, --project <projectId>", "Project ID")
|
|
17
|
-
.option("-e, --env <environment>", "Set the active environment (e.g. development, staging, production)")
|
|
18
|
-
.action(async (branchName, options) => {
|
|
19
|
-
let { project } = options;
|
|
20
|
-
// Try to get project from config if not provided
|
|
21
|
-
if (!project)
|
|
22
|
-
project = (0, config_1.getRcConfig)().project;
|
|
23
|
-
if (!project) {
|
|
24
|
-
console.error(chalk_1.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first."));
|
|
25
|
-
process.exit(1);
|
|
26
|
-
}
|
|
27
|
-
const spinner = (0, ora_1.default)("Fetching branches...").start();
|
|
28
|
-
try {
|
|
29
|
-
// Fetch branches
|
|
30
|
-
const branches = await api_1.api.getBranches(project);
|
|
31
|
-
spinner.stop();
|
|
32
|
-
if (!Array.isArray(branches) || branches.length === 0) {
|
|
33
|
-
console.log(chalk_1.default.yellow("No branches found in this project."));
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
let selectedBranch = branchName;
|
|
37
|
-
// If no branch name provided, show interactive selector
|
|
38
|
-
if (!selectedBranch) {
|
|
39
|
-
const choices = branches.map((b) => ({
|
|
40
|
-
name: b.name,
|
|
41
|
-
value: b.name
|
|
42
|
-
}));
|
|
43
|
-
const { selected } = await inquirer_1.default.prompt([{
|
|
44
|
-
type: "list",
|
|
45
|
-
name: "selected",
|
|
46
|
-
message: "Select a branch:",
|
|
47
|
-
choices
|
|
48
|
-
}]);
|
|
49
|
-
selectedBranch = selected;
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
// Verify branch exists
|
|
53
|
-
const exists = branches.find((b) => b.name === selectedBranch);
|
|
54
|
-
if (!exists) {
|
|
55
|
-
console.error(chalk_1.default.red(`Branch '${selectedBranch}' does not exist.`));
|
|
56
|
-
console.log(chalk_1.default.yellow(`Use 'xtra branch create ${selectedBranch}' to create it.`));
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
// Save to config
|
|
61
|
-
(0, config_1.setConfig)("branch", selectedBranch);
|
|
62
|
-
(0, config_1.setConfig)("project", project);
|
|
63
|
-
if (options.env) {
|
|
64
|
-
(0, config_1.setConfig)("env", options.env);
|
|
65
|
-
}
|
|
66
|
-
console.log(chalk_1.default.green(`\u2714 Switched to branch '${selectedBranch}'`));
|
|
67
|
-
if (options.env) {
|
|
68
|
-
console.log(chalk_1.default.green(`\u2714 Environment set to '${options.env}'`));
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
catch (error) {
|
|
72
|
-
spinner.fail("Failed to fetch branches");
|
|
73
|
-
if (error.response?.data?.error) {
|
|
74
|
-
console.error(chalk_1.default.red(`Error: ${error.response.data.error}`));
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
console.error(chalk_1.default.red(error.message));
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
});
|
|
1
|
+
var P=Object.create;var d=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var _=Object.getPrototypeOf,q=Object.prototype.hasOwnProperty;var N=(e,t)=>{for(var s in t)d(e,s,{get:t[s],enumerable:!0})},$=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of L(t))!q.call(e,o)&&o!==s&&d(e,o,{get:()=>t[o],enumerable:!(n=B(t,o))||n.enumerable});return e};var c=(e,t,s)=>(s=e!=null?P(_(e)):{},$(t||!e||!e.__esModule?d(s,"default",{value:e,enumerable:!0}):s,e)),T=e=>$(d({},"__esModule",{value:!0}),e);var J={};N(J,{checkoutCommand:()=>D});module.exports=T(J);var U=require("commander");var x=c(require("axios"));var j=c(require("conf")),g=c(require("fs")),b=c(require("path")),f="https://www.xtrasecurity.in/api",i=new j.default({projectName:"xtra-cli",defaults:{apiUrl:f}}),h=i.get("apiUrl");h&&!process.env.XTRA_API_URL&&(h.includes("localhost")||h.includes("xtra-security.vercel.app"))&&i.set("apiUrl",f);var l=()=>({...i.store,apiUrl:process.env.XTRA_API_URL||i.get("apiUrl")||f});var u=(e,t)=>{if(i.set(e,t),e==="token"&&process.platform!=="win32"&&g.default.existsSync(i.path))try{g.default.chmodSync(i.path,384)}catch{}};var v=()=>i.get("token");var S=()=>{let e={};try{let t=b.default.join(process.cwd(),".xtrarc");g.default.existsSync(t)&&(e=JSON.parse(g.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||i.get("project")||"",env:e.env||i.get("env")||"development",branch:e.branch||i.get("branch")||"main"}};var k=c(require("fs")),I=c(require("path")),G=JSON.parse(k.readFileSync(I.join(__dirname,"../../package.json"),"utf-8")),r=()=>{let{apiUrl:e}=l(),t=v();return x.default.create({baseURL:e,headers:{"Content-Type":"application/json","X-CLI-Version":G.version,...t?{Authorization:`Bearer ${t}`}:{}}})},C={login:async(e,t,s)=>(await r().post("/auth/cli-login",{email:e,password:t,apiKey:s})).data,getSecrets:async(e,t,s="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets?branch=${s}`)).data,getSecretVersions:async(e,t,s="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets?includeVersions=true&branch=${s}`)).data,setSecrets:async(e,t,s,n,o="main")=>(await r().post(`/projects/${e}/envs/${t}/secrets`,{secrets:s,expectedVersions:n,branch:o})).data,getSecretDetails:async(e,t,s,n="main")=>(await r().get(`/projects/${e}/envs/${t}/secrets/${s}?branch=${n}`)).data,syncLogs:async e=>(await r().post("/audit/cli-logs",{logs:e})).data,linkSecret:async(e,t,s,n,o,a)=>(await r().post(`/projects/${e}/envs/${t}/secrets/link`,{key:s,sourceProjectId:n,sourceEnv:o,sourceKey:a})).data,rotateSecret:async(e,t,s,n,o)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/rotate`,{strategy:n,parsedNewValue:o})).data,promoteSecret:async(e,t,s)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/promote`,{})).data,verifyAuditLogs:async()=>(await r().get("/audit/verify")).data,exportAuditLogs:async(e,t,s,n)=>{let o={format:e};return t&&(o.startDate=t),s&&(o.endDate=s),n&&(o.projectId=n),(await r().post("/audit/export",o,{responseType:e==="csv"?"text":"json"})).data},requestAccess:async(e,t,s,n)=>(await r().post("/access/request",{projectId:e,secretId:n,reason:t,duration:s})).data,approveAccess:async(e,t)=>(await r().post("/access/approve",{requestId:e,decision:t})).data,listAccessRequests:async e=>{let{workspace:t}=l(),s=t?`&workspaceId=${t}`:"";return(await r().get(`/access/list?mode=${e}${s}`)).data},getAccessRequestStatus:async e=>(await r().get(`/access/request?id=${e}`)).data,getProjects:async()=>{let{workspace:e}=l(),t=e?`/project?workspaceId=${e}`:"/project";return(await r().get(t)).data},getBranches:async e=>(await r().get(`/branch?projectId=${e}`)).data,createBranch:async(e,t,s)=>(await r().post("/branch",{projectId:e,name:t,description:s})).data,deleteBranch:async e=>(await r().delete(`/branch/${e}`)).data,updateBranch:async(e,t)=>(await r().put("/branch",{id:e,...t})).data,getRoles:async()=>(await r().get("/admin/roles")).data,getUsers:async e=>{let t=e?`?teamId=${e}`:"";return(await r().get(`/admin/users${t}`)).data},setUserRole:async(e,t,s)=>(await r().put("/admin/users/role",{email:e,role:t,teamId:s})).data,getIntegrationStatus:async e=>(await r().get(`/integrations/${e}`)).data,getIntegrationRepos:async e=>(await r().get(`/integrations/${e}/sync`)).data.repos,syncSecretsToGithub:async e=>(await r().post("/integrations/github/sync",e)).data,exportKubernetesSecret:async(e,t)=>{let s=new URLSearchParams(t).toString();return(await r().get(`/projects/${e}/kubernetes?${s}`)).data},getSecretHistory:async(e,t,s)=>(await r().get(`/projects/${e}/envs/${t}/secrets/${s}/history`)).data,rollbackSecret:async(e,t,s,n)=>(await r().post(`/projects/${e}/envs/${t}/secrets/${s}/history`,{version:n})).data,cloneEnvironment:async(e,t,s,n,o)=>(await r().post(`/projects/${e}/envs/clone`,{fromEnv:t,toEnv:s,overwrite:n,branch:o})).data,generateJitLink:async e=>(await r().post("/jit/generate",e)).data,claimJitLink:async e=>(await r().post("/jit/claim",{token:e})).data,getJitInfo:async e=>(await r().get(`/jit/${e}`)).data,post:async(e,t)=>(await r().post(e,t)).data};var p=c(require("chalk")),A=c(require("ora")),R=c(require("inquirer")),D=new U.Command("checkout").description("Switch the active branch context").argument("[branchName]","Branch name to switch to (optional - will show list if not provided)").option("-p, --project <projectId>","Project ID").option("-e, --env <environment>","Set the active environment (e.g. development, staging, production)").action(async(e,t)=>{let{project:s}=t;s||(s=S().project),s||(console.error(p.default.red("Error: Project ID is required. Use -p <id> or run 'xtra project set' first.")),process.exit(1));let n=(0,A.default)("Fetching branches...").start();try{let o=await C.getBranches(s);if(n.stop(),!Array.isArray(o)||o.length===0){console.log(p.default.yellow("No branches found in this project."));return}let a=e;if(a){if(!o.find(y=>y.name===a)){console.error(p.default.red(`Branch '${a}' does not exist.`)),console.log(p.default.yellow(`Use 'xtra branch create ${a}' to create it.`));return}}else{let m=o.map(w=>({name:w.name,value:w.name})),{selected:y}=await R.default.prompt([{type:"list",name:"selected",message:"Select a branch:",choices:m}]);a=y}u("branch",a),u("project",s),t.env&&u("env",t.env),console.log(p.default.green(`\u2714 Switched to branch '${a}'`)),t.env&&console.log(p.default.green(`\u2714 Environment set to '${t.env}'`))}catch(o){n.fail("Failed to fetch branches"),o.response?.data?.error?console.error(p.default.red(`Error: ${o.response.data.error}`)):console.error(p.default.red(o.message))}});0&&(module.exports={checkoutCommand});
|