xtra-cli 0.1.0
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/LICENSE +21 -0
- package/README.md +87 -0
- package/dist/bin/xtra.js +124 -0
- package/dist/commands/access.js +107 -0
- package/dist/commands/admin.js +118 -0
- package/dist/commands/audit.js +67 -0
- package/dist/commands/branch.js +216 -0
- package/dist/commands/checkout.js +74 -0
- package/dist/commands/ci.js +330 -0
- package/dist/commands/completion.js +227 -0
- package/dist/commands/diff.js +163 -0
- package/dist/commands/doctor.js +176 -0
- package/dist/commands/env.js +70 -0
- package/dist/commands/export.js +84 -0
- package/dist/commands/generate.js +180 -0
- package/dist/commands/history.js +77 -0
- package/dist/commands/import.js +122 -0
- package/dist/commands/init.js +162 -0
- package/dist/commands/integration.js +188 -0
- package/dist/commands/local.js +198 -0
- package/dist/commands/login.js +176 -0
- package/dist/commands/login.test.js +51 -0
- package/dist/commands/logs.js +121 -0
- package/dist/commands/profile.js +184 -0
- package/dist/commands/project.js +98 -0
- package/dist/commands/rollback.js +96 -0
- package/dist/commands/rotate.js +94 -0
- package/dist/commands/run.js +215 -0
- package/dist/commands/scan.js +127 -0
- package/dist/commands/secrets.js +265 -0
- package/dist/commands/simulate.js +92 -0
- package/dist/commands/status.js +94 -0
- package/dist/commands/template.js +276 -0
- package/dist/commands/ui.js +218 -0
- package/dist/commands/watch.js +121 -0
- package/dist/lib/api.js +172 -0
- package/dist/lib/api.test.js +89 -0
- package/dist/lib/audit.js +136 -0
- package/dist/lib/config.js +42 -0
- package/dist/lib/config.test.js +47 -0
- package/dist/lib/crypto.js +50 -0
- package/dist/lib/manifest.js +52 -0
- package/dist/lib/profiles.js +103 -0
- package/package.json +67 -0
|
@@ -0,0 +1,52 @@
|
|
|
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.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
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
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.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 || "http://localhost:3000/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 || "http://localhost:3000/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
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "xtra-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI for XtraSecurity Platform",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"xtra": "dist/bin/xtra.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"start": "node dist/bin/xtra.js",
|
|
12
|
+
"dev": "ts-node src/bin/xtra.ts",
|
|
13
|
+
"test": "jest",
|
|
14
|
+
"test:watch": "jest --watch",
|
|
15
|
+
"prepublishOnly": "npm run build"
|
|
16
|
+
},
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=16.0.0"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"README.md"
|
|
23
|
+
],
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@types/diff": "^7.0.2",
|
|
26
|
+
"@types/dotenv": "^6.1.1",
|
|
27
|
+
"@types/table": "^6.0.0",
|
|
28
|
+
"@types/uuid": "^10.0.0",
|
|
29
|
+
"axios": "^1.6.0",
|
|
30
|
+
"chalk": "^4.1.2",
|
|
31
|
+
"commander": "^11.0.0",
|
|
32
|
+
"conf": "^10.2.0",
|
|
33
|
+
"csv-parse": "^6.1.0",
|
|
34
|
+
"csv-stringify": "^6.6.0",
|
|
35
|
+
"diff": "^8.0.3",
|
|
36
|
+
"dotenv": "^17.2.3",
|
|
37
|
+
"ink": "^6.8.0",
|
|
38
|
+
"ink-select-input": "^6.2.0",
|
|
39
|
+
"ink-text-input": "^6.0.0",
|
|
40
|
+
"inquirer": "^8.2.5",
|
|
41
|
+
"open": "^11.0.0",
|
|
42
|
+
"ora": "^5.4.1",
|
|
43
|
+
"react": "^19.2.4",
|
|
44
|
+
"table": "^6.9.0",
|
|
45
|
+
"uuid": "^13.0.0",
|
|
46
|
+
"yaml": "^2.8.2"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/babel__core": "^7.20.5",
|
|
50
|
+
"@types/inquirer": "^9.0.7",
|
|
51
|
+
"@types/jest": "^29.5.14",
|
|
52
|
+
"@types/node": "^20.0.0",
|
|
53
|
+
"@types/prettier": "^2.7.3",
|
|
54
|
+
"@types/react": "^19.2.14",
|
|
55
|
+
"jest": "^29.7.0",
|
|
56
|
+
"ts-jest": "^29.4.6",
|
|
57
|
+
"ts-node": "^10.9.1",
|
|
58
|
+
"typescript": "^5.0.0"
|
|
59
|
+
},
|
|
60
|
+
"keywords": [
|
|
61
|
+
"secrets",
|
|
62
|
+
"cli",
|
|
63
|
+
"security"
|
|
64
|
+
],
|
|
65
|
+
"author": "XtraSecurity",
|
|
66
|
+
"license": "ISC"
|
|
67
|
+
}
|