xtra-cli 0.1.6 → 0.1.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/bin/xtra.js +16 -2
- package/dist/commands/init.js +25 -11
- package/dist/lib/config.js +9 -2
- package/package.json +1 -1
package/dist/bin/xtra.js
CHANGED
|
@@ -76,8 +76,11 @@ program
|
|
|
76
76
|
.description("XtraSync CLI - Secure Runtime Secret Injection")
|
|
77
77
|
.version(pkg.version)
|
|
78
78
|
.option("--profile <name>", "Use a specific named profile for this command");
|
|
79
|
-
//
|
|
80
|
-
|
|
79
|
+
// Commands that do NOT require authentication
|
|
80
|
+
const PUBLIC_COMMANDS = new Set(["login", "completion", "doctor", "help"]);
|
|
81
|
+
// Apply profile + auth guard before any subcommand runs
|
|
82
|
+
program.hook("preSubcommand", (thisCommand, subCommand) => {
|
|
83
|
+
// ── Profile override ──────────────────────────────────────────
|
|
81
84
|
const profileName = thisCommand.opts().profile;
|
|
82
85
|
if (profileName) {
|
|
83
86
|
try {
|
|
@@ -88,6 +91,17 @@ program.hook("preSubcommand", (thisCommand) => {
|
|
|
88
91
|
process.exit(1);
|
|
89
92
|
}
|
|
90
93
|
}
|
|
94
|
+
// ── Auth guard ────────────────────────────────────────────────
|
|
95
|
+
const cmdName = subCommand.name();
|
|
96
|
+
if (PUBLIC_COMMANDS.has(cmdName))
|
|
97
|
+
return; // allow unauthenticated
|
|
98
|
+
const { getAuthToken } = require("../lib/config");
|
|
99
|
+
const token = getAuthToken();
|
|
100
|
+
if (!token) {
|
|
101
|
+
console.error("\x1b[31m✖ You are not logged in.\x1b[0m\n" +
|
|
102
|
+
" Run \x1b[36mxtra login\x1b[0m to authenticate before using this command.\n");
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
91
105
|
});
|
|
92
106
|
program.addCommand(login_1.loginCommand);
|
|
93
107
|
program.addCommand(run_1.runCommand);
|
package/dist/commands/init.js
CHANGED
|
@@ -74,20 +74,34 @@ exports.initCommand = new commander_1.Command("init")
|
|
|
74
74
|
// Interactive prompts if not --yes
|
|
75
75
|
if (!options.yes) {
|
|
76
76
|
// ── API Projects Fetch ─────────────────────────────────────────────
|
|
77
|
+
const { getAuthToken } = await Promise.resolve().then(() => __importStar(require("../lib/config")));
|
|
78
|
+
const token = getAuthToken();
|
|
77
79
|
const ora = (await Promise.resolve().then(() => __importStar(require("ora")))).default;
|
|
78
|
-
const apiSpinner = ora("Fetching your projects...").start();
|
|
79
80
|
let remoteProjects = [];
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
apiSpinner.succeed(`Found ${remoteProjects.length} projects`);
|
|
84
|
-
if (remoteProjects.length === 0) {
|
|
85
|
-
console.log(chalk_1.default.yellow("\nYou don't have any projects in this workspace yet."));
|
|
86
|
-
console.log(chalk_1.default.yellow("Create one in the web dashboard first, or manually paste a Project ID below."));
|
|
87
|
-
}
|
|
81
|
+
if (!token) {
|
|
82
|
+
console.log(chalk_1.default.yellow(" ℹ Not logged in — project list unavailable. Run `xtra login` first."));
|
|
83
|
+
console.log(chalk_1.default.yellow(" You can still enter a Project ID manually below.\n"));
|
|
88
84
|
}
|
|
89
|
-
|
|
90
|
-
apiSpinner
|
|
85
|
+
else {
|
|
86
|
+
const apiSpinner = ora("Fetching your projects...").start();
|
|
87
|
+
try {
|
|
88
|
+
const { api } = await Promise.resolve().then(() => __importStar(require("../lib/api")));
|
|
89
|
+
const result = await api.getProjects();
|
|
90
|
+
// API might return { projects: [...] } or directly an array
|
|
91
|
+
remoteProjects = Array.isArray(result) ? result : result.projects ?? [];
|
|
92
|
+
if (remoteProjects.length === 0) {
|
|
93
|
+
apiSpinner.warn(chalk_1.default.yellow("No projects found in your workspace. Create one at xtra-security.vercel.app first."));
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
apiSpinner.succeed(`Found ${remoteProjects.length} project${remoteProjects.length > 1 ? "s" : ""}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
const reason = err?.response?.status === 401
|
|
101
|
+
? "session expired — run `xtra login` again"
|
|
102
|
+
: err?.response?.data?.error || err?.message || "network error";
|
|
103
|
+
apiSpinner.warn(chalk_1.default.yellow(`Could not fetch projects (${reason}). Enter the Project ID manually.`));
|
|
104
|
+
}
|
|
91
105
|
}
|
|
92
106
|
const fallbackProject = project || (0, config_1.getConfigValue)("project") || "";
|
|
93
107
|
const { project: selectedProject } = await inquirer_1.default.prompt([
|
package/dist/lib/config.js
CHANGED
|
@@ -5,15 +5,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getProjectConfig = exports.getAuthToken = exports.clearConfig = exports.setConfig = exports.getConfigValue = exports.getConfig = void 0;
|
|
7
7
|
const conf_1 = __importDefault(require("conf"));
|
|
8
|
+
const PRODUCTION_API_URL = "https://xtra-security.vercel.app/api";
|
|
8
9
|
const config = new conf_1.default({
|
|
9
10
|
projectName: "xtra-cli",
|
|
10
11
|
defaults: {
|
|
11
|
-
apiUrl:
|
|
12
|
+
apiUrl: PRODUCTION_API_URL,
|
|
12
13
|
},
|
|
13
14
|
});
|
|
15
|
+
// Auto-heal: if an old localhost value 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 && _storedApiUrl.includes("localhost") && !process.env.XTRA_API_URL) {
|
|
19
|
+
config.set("apiUrl", PRODUCTION_API_URL);
|
|
20
|
+
}
|
|
14
21
|
const getConfig = () => ({
|
|
15
22
|
...config.store,
|
|
16
|
-
apiUrl: process.env.XTRA_API_URL || config.get("apiUrl") ||
|
|
23
|
+
apiUrl: process.env.XTRA_API_URL || config.get("apiUrl") || PRODUCTION_API_URL
|
|
17
24
|
});
|
|
18
25
|
exports.getConfig = getConfig;
|
|
19
26
|
const getConfigValue = (key) => config.get(key);
|