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/lib/config.js
CHANGED
|
@@ -1,72 +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.getRcConfig = exports.getProjectConfig = exports.getAuthToken = exports.clearConfig = exports.setConfig = exports.getConfigValue = exports.getConfig = void 0;
|
|
7
|
-
const conf_1 = __importDefault(require("conf"));
|
|
8
|
-
const PRODUCTION_API_URL = "https://www.xtrasecurity.in/api";
|
|
9
|
-
const config = new conf_1.default({
|
|
10
|
-
projectName: "xtra-cli",
|
|
11
|
-
defaults: {
|
|
12
|
-
apiUrl: PRODUCTION_API_URL,
|
|
13
|
-
},
|
|
14
|
-
});
|
|
15
|
-
// Auto-heal: if an old localhost or deprecated domain was persisted, clear it so we use production.
|
|
16
|
-
// Users who intentionally want localhost should set XTRA_API_URL env var instead.
|
|
17
|
-
const _storedApiUrl = config.get("apiUrl");
|
|
18
|
-
if (_storedApiUrl && !process.env.XTRA_API_URL) {
|
|
19
|
-
if (_storedApiUrl.includes("localhost") || _storedApiUrl.includes("xtra-security.vercel.app")) {
|
|
20
|
-
config.set("apiUrl", PRODUCTION_API_URL);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
const getConfig = () => ({
|
|
24
|
-
...config.store,
|
|
25
|
-
apiUrl: process.env.XTRA_API_URL || config.get("apiUrl") || PRODUCTION_API_URL
|
|
26
|
-
});
|
|
27
|
-
exports.getConfig = getConfig;
|
|
28
|
-
const getConfigValue = (key) => config.get(key);
|
|
29
|
-
exports.getConfigValue = getConfigValue;
|
|
30
|
-
const setConfig = (key, value) => config.set(key, value);
|
|
31
|
-
exports.setConfig = setConfig;
|
|
32
|
-
const clearConfig = () => config.clear();
|
|
33
|
-
exports.clearConfig = clearConfig;
|
|
34
|
-
const getAuthToken = () => config.get("token");
|
|
35
|
-
exports.getAuthToken = getAuthToken;
|
|
36
|
-
const fs_1 = __importDefault(require("fs"));
|
|
37
|
-
const path_1 = __importDefault(require("path"));
|
|
38
|
-
const getProjectConfig = async () => {
|
|
39
|
-
try {
|
|
40
|
-
const configPath = path_1.default.join(process.cwd(), "xtra.json");
|
|
41
|
-
if (fs_1.default.existsSync(configPath)) {
|
|
42
|
-
const content = fs_1.default.readFileSync(configPath, "utf-8");
|
|
43
|
-
return JSON.parse(content);
|
|
44
|
-
}
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
catch (error) {
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
exports.getProjectConfig = getProjectConfig;
|
|
52
|
-
/**
|
|
53
|
-
* Reads .xtrarc from the current working directory.
|
|
54
|
-
* Returns project/env/branch with fallback to the global conf store.
|
|
55
|
-
* All commands should use this instead of calling getConfigValue() directly.
|
|
56
|
-
*/
|
|
57
|
-
const getRcConfig = () => {
|
|
58
|
-
let rc = {};
|
|
59
|
-
try {
|
|
60
|
-
const rcPath = path_1.default.join(process.cwd(), ".xtrarc");
|
|
61
|
-
if (fs_1.default.existsSync(rcPath)) {
|
|
62
|
-
rc = JSON.parse(fs_1.default.readFileSync(rcPath, "utf-8"));
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
catch (_) { }
|
|
66
|
-
return {
|
|
67
|
-
project: rc.project || config.get("project") || "",
|
|
68
|
-
env: rc.env || config.get("env") || "development",
|
|
69
|
-
branch: rc.branch || config.get("branch") || "main",
|
|
70
|
-
};
|
|
71
|
-
};
|
|
72
|
-
exports.getRcConfig = getRcConfig;
|
|
1
|
+
var x=Object.create;var c=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,y=Object.prototype.hasOwnProperty;var m=(e,t)=>{for(var n in t)c(e,n,{get:t[n],enumerable:!0})},f=(e,t,n,l)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of d(t))!y.call(e,o)&&o!==n&&c(e,o,{get:()=>t[o],enumerable:!(l=S(t,o))||l.enumerable});return e};var i=(e,t,n)=>(n=e!=null?x(u(e)):{},f(t||!e||!e.__esModule?c(n,"default",{value:e,enumerable:!0}):n,e)),k=e=>f(c({},"__esModule",{value:!0}),e);var R={};m(R,{clearConfig:()=>b,deleteConfig:()=>v,getAuthToken:()=>_,getBreakGlassSession:()=>w,getConfig:()=>C,getConfigValue:()=>U,getProjectConfig:()=>A,getRcConfig:()=>P,setBreakGlassSession:()=>I,setConfig:()=>j});module.exports=k(R);var h=i(require("conf")),s=i(require("fs")),g=i(require("path")),p="https://www.xtrasecurity.in/api",r=new h.default({projectName:"xtra-cli",defaults:{apiUrl:p}}),a=r.get("apiUrl");a&&!process.env.XTRA_API_URL&&(a.includes("localhost")||a.includes("xtra-security.vercel.app"))&&r.set("apiUrl",p);var C=()=>({...r.store,apiUrl:process.env.XTRA_API_URL||r.get("apiUrl")||p}),U=e=>r.get(e),j=(e,t)=>{if(r.set(e,t),e==="token"&&process.platform!=="win32"&&s.default.existsSync(r.path))try{s.default.chmodSync(r.path,384)}catch{}},b=()=>r.clear(),v=e=>r.delete(e),_=()=>r.get("token"),w=()=>r.get("breakGlassSessionId"),I=e=>{e?r.set("breakGlassSessionId",e):r.delete("breakGlassSessionId")},A=async()=>{try{let e=g.default.join(process.cwd(),"xtra.json");if(s.default.existsSync(e)){let t=s.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}},P=()=>{let e={};try{let t=g.default.join(process.cwd(),".xtrarc");s.default.existsSync(t)&&(e=JSON.parse(s.default.readFileSync(t,"utf-8")))}catch{}return{project:e.project||r.get("project")||"",env:e.env||r.get("env")||"development",branch:e.branch||r.get("branch")||"main"}};0&&(module.exports={clearConfig,deleteConfig,getAuthToken,getBreakGlassSession,getConfig,getConfigValue,getProjectConfig,getRcConfig,setBreakGlassSession,setConfig});
|
package/dist/lib/config.test.js
CHANGED
|
@@ -1,47 +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
|
-
const config_1 = require("./config");
|
|
7
|
-
const fs_1 = __importDefault(require("fs"));
|
|
8
|
-
// Mock Conf module
|
|
9
|
-
jest.mock('conf');
|
|
10
|
-
describe('Config Management', () => {
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
jest.clearAllMocks();
|
|
13
|
-
});
|
|
14
|
-
describe('getConfig', () => {
|
|
15
|
-
it('should return config with API URL from env if set', () => {
|
|
16
|
-
process.env.XTRA_API_URL = 'https://api.production.com';
|
|
17
|
-
const config = (0, config_1.getConfig)();
|
|
18
|
-
expect(config.apiUrl).toBe('https://api.production.com');
|
|
19
|
-
delete process.env.XTRA_API_URL;
|
|
20
|
-
});
|
|
21
|
-
it('should fallback to default API URL', () => {
|
|
22
|
-
delete process.env.XTRA_API_URL;
|
|
23
|
-
const config = (0, config_1.getConfig)();
|
|
24
|
-
expect(config.apiUrl).toBeDefined();
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
describe('getProjectConfig', () => {
|
|
28
|
-
it('should return null if xtra.json does not exist', async () => {
|
|
29
|
-
jest.spyOn(fs_1.default, 'existsSync').mockReturnValue(false);
|
|
30
|
-
const projectConfig = await (0, config_1.getProjectConfig)();
|
|
31
|
-
expect(projectConfig).toBeNull();
|
|
32
|
-
});
|
|
33
|
-
it('should parse and return xtra.json if it exists', async () => {
|
|
34
|
-
const mockConfig = { projectId: 'test-project', env: 'production' };
|
|
35
|
-
jest.spyOn(fs_1.default, 'existsSync').mockReturnValue(true);
|
|
36
|
-
jest.spyOn(fs_1.default, 'readFileSync').mockReturnValue(JSON.stringify(mockConfig));
|
|
37
|
-
const projectConfig = await (0, config_1.getProjectConfig)();
|
|
38
|
-
expect(projectConfig).toEqual(mockConfig);
|
|
39
|
-
});
|
|
40
|
-
it('should return null if JSON parsing fails', async () => {
|
|
41
|
-
jest.spyOn(fs_1.default, 'existsSync').mockReturnValue(true);
|
|
42
|
-
jest.spyOn(fs_1.default, 'readFileSync').mockReturnValue('invalid json{');
|
|
43
|
-
const projectConfig = await (0, config_1.getProjectConfig)();
|
|
44
|
-
expect(projectConfig).toBeNull();
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
});
|
|
1
|
+
var m=Object.create;var u=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var j=Object.getPrototypeOf,S=Object.prototype.hasOwnProperty;var C=(e,t,o,f)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of y(t))!S.call(e,s)&&s!==o&&u(e,s,{get:()=>t[s],enumerable:!(f=x(t,s))||f.enumerable});return e};var r=(e,t,o)=>(o=e!=null?m(j(e)):{},C(t||!e||!e.__esModule?u(o,"default",{value:e,enumerable:!0}):o,e));var d=r(require("conf")),p=r(require("fs")),h=r(require("path")),l="https://www.xtrasecurity.in/api",c=new d.default({projectName:"xtra-cli",defaults:{apiUrl:l}}),a=c.get("apiUrl");a&&!process.env.XTRA_API_URL&&(a.includes("localhost")||a.includes("xtra-security.vercel.app"))&&c.set("apiUrl",l);var g=()=>({...c.store,apiUrl:process.env.XTRA_API_URL||c.get("apiUrl")||l});var i=async()=>{try{let e=h.default.join(process.cwd(),"xtra.json");if(p.default.existsSync(e)){let t=p.default.readFileSync(e,"utf-8");return JSON.parse(t)}return null}catch{return null}};var n=r(require("fs"));jest.mock("conf");describe("Config Management",()=>{beforeEach(()=>{jest.clearAllMocks()}),describe("getConfig",()=>{it("should return config with API URL from env if set",()=>{process.env.XTRA_API_URL="https://api.production.com";let e=g();expect(e.apiUrl).toBe("https://api.production.com"),delete process.env.XTRA_API_URL}),it("should fallback to default API URL",()=>{delete process.env.XTRA_API_URL;let e=g();expect(e.apiUrl).toBeDefined()})}),describe("getProjectConfig",()=>{it("should return null if xtra.json does not exist",async()=>{jest.spyOn(n.default,"existsSync").mockReturnValue(!1);let e=await i();expect(e).toBeNull()}),it("should parse and return xtra.json if it exists",async()=>{let e={projectId:"test-project",env:"production"};jest.spyOn(n.default,"existsSync").mockReturnValue(!0),jest.spyOn(n.default,"readFileSync").mockReturnValue(JSON.stringify(e));let t=await i();expect(t).toEqual(e)}),it("should return null if JSON parsing fails",async()=>{jest.spyOn(n.default,"existsSync").mockReturnValue(!0),jest.spyOn(n.default,"readFileSync").mockReturnValue("invalid json{");let e=await i();expect(e).toBeNull()})})});
|
package/dist/lib/crypto.js
CHANGED
|
@@ -1,50 +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.hash = exports.decrypt = exports.encrypt = void 0;
|
|
7
|
-
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
-
const conf_1 = __importDefault(require("conf"));
|
|
9
|
-
// We'll use the machine-id or a generated master key stored in the system keychain
|
|
10
|
-
// (or simple config for MVP) to encrypt the local cache.
|
|
11
|
-
// For now, we will generate a random key and store it in the config (simulate keychain).
|
|
12
|
-
const algorithm = "aes-256-gcm";
|
|
13
|
-
const config = new conf_1.default({ projectName: "xtra-cli-crypto" });
|
|
14
|
-
function getMasterKey() {
|
|
15
|
-
let keyHex = config.get("masterKey");
|
|
16
|
-
if (!keyHex) {
|
|
17
|
-
keyHex = crypto_1.default.randomBytes(32).toString("hex");
|
|
18
|
-
config.set("masterKey", keyHex);
|
|
19
|
-
}
|
|
20
|
-
return Buffer.from(keyHex, "hex");
|
|
21
|
-
}
|
|
22
|
-
const encrypt = (text) => {
|
|
23
|
-
const iv = crypto_1.default.randomBytes(16);
|
|
24
|
-
const key = getMasterKey();
|
|
25
|
-
const cipher = crypto_1.default.createCipheriv(algorithm, key, iv);
|
|
26
|
-
let encrypted = cipher.update(text, "utf8", "hex");
|
|
27
|
-
encrypted += cipher.final("hex");
|
|
28
|
-
const tag = cipher.getAuthTag();
|
|
29
|
-
return {
|
|
30
|
-
iv: iv.toString("hex"),
|
|
31
|
-
content: encrypted,
|
|
32
|
-
tag: tag.toString("hex"),
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
|
-
exports.encrypt = encrypt;
|
|
36
|
-
const decrypt = (encrypted) => {
|
|
37
|
-
const key = getMasterKey();
|
|
38
|
-
const iv = Buffer.from(encrypted.iv, "hex");
|
|
39
|
-
const tag = Buffer.from(encrypted.tag, "hex");
|
|
40
|
-
const decipher = crypto_1.default.createDecipheriv(algorithm, key, iv);
|
|
41
|
-
decipher.setAuthTag(tag);
|
|
42
|
-
let decrypted = decipher.update(encrypted.content, "hex", "utf8");
|
|
43
|
-
decrypted += decipher.final("utf8");
|
|
44
|
-
return decrypted;
|
|
45
|
-
};
|
|
46
|
-
exports.decrypt = decrypt;
|
|
47
|
-
const hash = (text) => {
|
|
48
|
-
return crypto_1.default.createHash("sha256").update(text).digest("hex");
|
|
49
|
-
};
|
|
50
|
-
exports.hash = hash;
|
|
1
|
+
var d=Object.create;var a=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var v=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty;var B=(t,e)=>{for(var r in e)a(t,r,{get:e[r],enumerable:!0})},c=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of y(e))!l.call(t,n)&&n!==r&&a(t,n,{get:()=>e[n],enumerable:!(o=x(e,n))||o.enumerable});return t};var g=(t,e,r)=>(r=t!=null?d(v(t)):{},c(e||!t||!t.__esModule?a(r,"default",{value:t,enumerable:!0}):r,t)),S=t=>c(a({},"__esModule",{value:!0}),t);var C={};B(C,{decrypt:()=>K,encrypt:()=>k,hash:()=>A});module.exports=S(C);var s=g(require("crypto")),f=g(require("conf")),p=require("node-machine-id"),m="aes-256-gcm",h=new f.default({projectName:"xtra-cli-crypto"});function u(){let t=h.get("masterKey");t||(t=s.default.randomBytes(32).toString("hex"),h.set("masterKey",t));let e=(0,p.machineIdSync)();return s.default.createHash("sha256").update(t+e).digest()}var k=t=>{let e=s.default.randomBytes(16),r=u(),o=s.default.createCipheriv(m,r,e),n=o.update(t,"utf8","hex");n+=o.final("hex");let i=o.getAuthTag();return{iv:e.toString("hex"),content:n,tag:i.toString("hex")}},K=t=>{let e=u(),r=Buffer.from(t.iv,"hex"),o=Buffer.from(t.tag,"hex"),n=s.default.createDecipheriv(m,e,r);n.setAuthTag(o);let i=n.update(t.content,"hex","utf8");return i+=n.final("utf8"),i},A=t=>s.default.createHash("sha256").update(t).digest("hex");0&&(module.exports={decrypt,encrypt,hash});
|
package/dist/lib/manifest.js
CHANGED
|
@@ -1,52 +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.MANIFEST_FILE = exports.MANIFEST_DIR = void 0;
|
|
7
|
-
exports.loadManifest = loadManifest;
|
|
8
|
-
exports.saveManifest = saveManifest;
|
|
9
|
-
exports.updateManifest = updateManifest;
|
|
10
|
-
const fs_1 = __importDefault(require("fs"));
|
|
11
|
-
const path_1 = __importDefault(require("path"));
|
|
12
|
-
exports.MANIFEST_DIR = path_1.default.join(process.cwd(), ".xtra");
|
|
13
|
-
exports.MANIFEST_FILE = path_1.default.join(exports.MANIFEST_DIR, "manifest.json");
|
|
14
|
-
function loadManifest() {
|
|
15
|
-
if (!fs_1.default.existsSync(exports.MANIFEST_FILE)) {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
try {
|
|
19
|
-
const data = fs_1.default.readFileSync(exports.MANIFEST_FILE, "utf-8");
|
|
20
|
-
return JSON.parse(data);
|
|
21
|
-
}
|
|
22
|
-
catch (error) {
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
function saveManifest(manifest) {
|
|
27
|
-
if (!fs_1.default.existsSync(exports.MANIFEST_DIR)) {
|
|
28
|
-
fs_1.default.mkdirSync(exports.MANIFEST_DIR, { recursive: true });
|
|
29
|
-
}
|
|
30
|
-
fs_1.default.writeFileSync(exports.MANIFEST_FILE, JSON.stringify(manifest, null, 2), "utf-8");
|
|
31
|
-
}
|
|
32
|
-
function updateManifest(projectId, env, secrets, hasher) {
|
|
33
|
-
const manifest = loadManifest() || {
|
|
34
|
-
projectId,
|
|
35
|
-
environment: env,
|
|
36
|
-
lastSyncedAt: new Date().toISOString(),
|
|
37
|
-
secrets: {}
|
|
38
|
-
};
|
|
39
|
-
// Update sync metadata
|
|
40
|
-
manifest.projectId = projectId;
|
|
41
|
-
manifest.environment = env;
|
|
42
|
-
manifest.lastSyncedAt = new Date().toISOString();
|
|
43
|
-
// Update secrets
|
|
44
|
-
Object.entries(secrets).forEach(([key, value]) => {
|
|
45
|
-
const hash = hasher(value);
|
|
46
|
-
manifest.secrets[key] = {
|
|
47
|
-
hash,
|
|
48
|
-
updatedAt: new Date().toISOString()
|
|
49
|
-
};
|
|
50
|
-
});
|
|
51
|
-
saveManifest(manifest);
|
|
52
|
-
}
|
|
1
|
+
var x=Object.create;var o=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var M=Object.getPrototypeOf,j=Object.prototype.hasOwnProperty;var v=(t,e)=>{for(var r in e)o(t,r,{get:e[r],enumerable:!0})},S=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of I(e))!j.call(t,n)&&n!==r&&o(t,n,{get:()=>e[n],enumerable:!(s=y(e,n))||s.enumerable});return t};var d=(t,e,r)=>(r=t!=null?x(M(t)):{},S(e||!t||!t.__esModule?o(r,"default",{value:t,enumerable:!0}):r,t)),h=t=>S(o({},"__esModule",{value:!0}),t);var O={};v(O,{MANIFEST_DIR:()=>c,MANIFEST_FILE:()=>a,loadManifest:()=>g,saveManifest:()=>p,updateManifest:()=>A});module.exports=h(O);var i=d(require("fs")),f=d(require("path")),c=f.default.join(process.cwd(),".xtra"),a=f.default.join(c,"manifest.json");function g(){if(!i.default.existsSync(a))return null;try{let t=i.default.readFileSync(a,"utf-8");return JSON.parse(t)}catch{return null}}function p(t){i.default.existsSync(c)||i.default.mkdirSync(c,{recursive:!0}),i.default.writeFileSync(a,JSON.stringify(t,null,2),"utf-8")}function A(t,e,r,s){let n=g()||{projectId:t,environment:e,lastSyncedAt:new Date().toISOString(),secrets:{}};n.projectId=t,n.environment=e,n.lastSyncedAt=new Date().toISOString(),Object.entries(r).forEach(([u,l])=>{let m=s(l);n.secrets[u]={hash:m,updatedAt:new Date().toISOString()}}),p(n)}0&&(module.exports={MANIFEST_DIR,MANIFEST_FILE,loadManifest,saveManifest,updateManifest});
|
package/dist/lib/profiles.js
CHANGED
|
@@ -1,103 +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.listProfiles = listProfiles;
|
|
7
|
-
exports.getActiveProfileName = getActiveProfileName;
|
|
8
|
-
exports.getActiveProfile = getActiveProfile;
|
|
9
|
-
exports.setActiveProfile = setActiveProfile;
|
|
10
|
-
exports.createProfile = createProfile;
|
|
11
|
-
exports.deleteProfile = deleteProfile;
|
|
12
|
-
exports.setProfileValue = setProfileValue;
|
|
13
|
-
exports.getProfileValue = getProfileValue;
|
|
14
|
-
exports.useProfile = useProfile;
|
|
15
|
-
/**
|
|
16
|
-
* profiles.ts - Multi-Profile config management for xtra-cli
|
|
17
|
-
*
|
|
18
|
-
* Profiles are stored in the existing Conf store under the key "profiles"
|
|
19
|
-
* as a nested object: { profileName: { token, apiUrl, project, ... } }
|
|
20
|
-
*
|
|
21
|
-
* The active profile is tracked under "activeProfile".
|
|
22
|
-
*/
|
|
23
|
-
const conf_1 = __importDefault(require("conf"));
|
|
24
|
-
const store = new conf_1.default({
|
|
25
|
-
projectName: "xtra-cli",
|
|
26
|
-
defaults: {
|
|
27
|
-
activeProfile: "default",
|
|
28
|
-
profiles: {
|
|
29
|
-
default: {
|
|
30
|
-
apiUrl: process.env.XTRA_API_URL || "https://www.xtrasecurity.in/api",
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
});
|
|
35
|
-
// ── Profile CRUD ───────────────────────────────────────────────────────────────
|
|
36
|
-
function listProfiles() {
|
|
37
|
-
return store.get("profiles") || {};
|
|
38
|
-
}
|
|
39
|
-
function getActiveProfileName() {
|
|
40
|
-
// Environment variable always wins
|
|
41
|
-
return process.env.XTRA_PROFILE || store.get("activeProfile") || "default";
|
|
42
|
-
}
|
|
43
|
-
function getActiveProfile() {
|
|
44
|
-
const name = getActiveProfileName();
|
|
45
|
-
const profiles = listProfiles();
|
|
46
|
-
return profiles[name] || {};
|
|
47
|
-
}
|
|
48
|
-
function setActiveProfile(name) {
|
|
49
|
-
const profiles = listProfiles();
|
|
50
|
-
if (!profiles[name]) {
|
|
51
|
-
throw new Error(`Profile '${name}' does not exist. Create it first with 'xtra profile create ${name}'.`);
|
|
52
|
-
}
|
|
53
|
-
store.set("activeProfile", name);
|
|
54
|
-
}
|
|
55
|
-
function createProfile(name, data = {}) {
|
|
56
|
-
const profiles = listProfiles();
|
|
57
|
-
if (profiles[name]) {
|
|
58
|
-
throw new Error(`Profile '${name}' already exists. Use 'xtra profile set' to edit it.`);
|
|
59
|
-
}
|
|
60
|
-
profiles[name] = {
|
|
61
|
-
apiUrl: process.env.XTRA_API_URL || "https://www.xtrasecurity.in/api",
|
|
62
|
-
...data,
|
|
63
|
-
};
|
|
64
|
-
store.set("profiles", profiles);
|
|
65
|
-
}
|
|
66
|
-
function deleteProfile(name) {
|
|
67
|
-
if (name === "default") {
|
|
68
|
-
throw new Error("Cannot delete the 'default' profile.");
|
|
69
|
-
}
|
|
70
|
-
const profiles = listProfiles();
|
|
71
|
-
if (!profiles[name]) {
|
|
72
|
-
throw new Error(`Profile '${name}' not found.`);
|
|
73
|
-
}
|
|
74
|
-
delete profiles[name];
|
|
75
|
-
store.set("profiles", profiles);
|
|
76
|
-
// If the deleted profile was active, fall back to default
|
|
77
|
-
if (getActiveProfileName() === name) {
|
|
78
|
-
store.set("activeProfile", "default");
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
function setProfileValue(name, key, value) {
|
|
82
|
-
const profiles = listProfiles();
|
|
83
|
-
if (!profiles[name]) {
|
|
84
|
-
throw new Error(`Profile '${name}' not found.`);
|
|
85
|
-
}
|
|
86
|
-
profiles[name][key] = value;
|
|
87
|
-
store.set("profiles", profiles);
|
|
88
|
-
}
|
|
89
|
-
function getProfileValue(key) {
|
|
90
|
-
return getActiveProfile()[key];
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Called at startup when --profile flag is passed.
|
|
94
|
-
* Temporarily overrides the active profile for this CLI run.
|
|
95
|
-
*/
|
|
96
|
-
function useProfile(name) {
|
|
97
|
-
const profiles = listProfiles();
|
|
98
|
-
if (!profiles[name]) {
|
|
99
|
-
throw new Error(`Profile '${name}' does not exist. Run 'xtra profile create ${name}' first.`);
|
|
100
|
-
}
|
|
101
|
-
// Override in environment so all subsequent getActiveProfileName() calls pick it up
|
|
102
|
-
process.env.XTRA_PROFILE = name;
|
|
103
|
-
}
|
|
1
|
+
var P=Object.create;var l=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var v=(e,r)=>{for(var t in r)l(e,t,{get:r[t],enumerable:!0})},c=(e,r,t,f)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of d(r))!w.call(e,s)&&s!==t&&l(e,s,{get:()=>r[s],enumerable:!(f=u(r,s))||f.enumerable});return e};var x=(e,r,t)=>(t=e!=null?P(g(e)):{},c(r||!e||!e.__esModule?l(t,"default",{value:e,enumerable:!0}):t,e)),h=e=>c(l({},"__esModule",{value:!0}),e);var _={};v(_,{createProfile:()=>A,deleteProfile:()=>E,getActiveProfile:()=>a,getActiveProfileName:()=>n,getProfileValue:()=>$,listProfiles:()=>i,setActiveProfile:()=>R,setProfileValue:()=>D,useProfile:()=>U});module.exports=h(_);var p=x(require("conf")),o=new p.default({projectName:"xtra-cli",defaults:{activeProfile:"default",profiles:{default:{apiUrl:process.env.XTRA_API_URL||"https://www.xtrasecurity.in/api"}}}});function i(){return o.get("profiles")||{}}function n(){return process.env.XTRA_PROFILE||o.get("activeProfile")||"default"}function a(){let e=n();return i()[e]||{}}function R(e){if(!i()[e])throw new Error(`Profile '${e}' does not exist. Create it first with 'xtra profile create ${e}'.`);o.set("activeProfile",e)}function A(e,r={}){let t=i();if(t[e])throw new Error(`Profile '${e}' already exists. Use 'xtra profile set' to edit it.`);t[e]={apiUrl:process.env.XTRA_API_URL||"https://www.xtrasecurity.in/api",...r},o.set("profiles",t)}function E(e){if(e==="default")throw new Error("Cannot delete the 'default' profile.");let r=i();if(!r[e])throw new Error(`Profile '${e}' not found.`);delete r[e],o.set("profiles",r),n()===e&&o.set("activeProfile","default")}function D(e,r,t){let f=i();if(!f[e])throw new Error(`Profile '${e}' not found.`);f[e][r]=t,o.set("profiles",f)}function $(e){return a()[e]}function U(e){if(!i()[e])throw new Error(`Profile '${e}' does not exist. Run 'xtra profile create ${e}' first.`);process.env.XTRA_PROFILE=e}0&&(module.exports={createProfile,deleteProfile,getActiveProfile,getActiveProfileName,getProfileValue,listProfiles,setActiveProfile,setProfileValue,useProfile});
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xtra-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "CLI for XtraSecurity Platform",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"xtra": "dist/bin/xtra.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"build": "tsup src/bin/xtra.ts --format cjs --out-dir dist
|
|
10
|
+
"build": "tsup src/bin/xtra.ts src/commands/*.ts src/lib/*.ts --format cjs --out-dir dist --minify --clean",
|
|
11
11
|
"start": "node dist/bin/xtra.js",
|
|
12
12
|
"dev": "ts-node src/bin/xtra.ts",
|
|
13
13
|
"test": "jest",
|