@eve-horizon/cli 0.1.4 → 0.2.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/dist/commands/profile.js +77 -7
- package/dist/lib/context.js +70 -15
- package/package.json +1 -1
package/dist/commands/profile.js
CHANGED
|
@@ -2,39 +2,109 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.handleProfile = handleProfile;
|
|
4
4
|
const config_1 = require("../lib/config");
|
|
5
|
+
const context_1 = require("../lib/context");
|
|
5
6
|
const output_1 = require("../lib/output");
|
|
6
7
|
function handleProfile(subcommand, positionals, flags, config) {
|
|
7
8
|
const json = Boolean(flags.json);
|
|
8
9
|
switch (subcommand) {
|
|
9
10
|
case 'list': {
|
|
11
|
+
const repoProfile = (0, context_1.loadRepoProfile)();
|
|
12
|
+
const localProfileName = repoProfile?.profile;
|
|
10
13
|
const profiles = Object.entries(config.profiles).map(([name, profile]) => ({
|
|
11
14
|
name,
|
|
12
15
|
active: name === config.active_profile,
|
|
16
|
+
local: name === localProfileName,
|
|
13
17
|
...profile,
|
|
14
18
|
}));
|
|
15
|
-
(0, output_1.outputJson)({
|
|
19
|
+
(0, output_1.outputJson)({
|
|
20
|
+
active_profile: config.active_profile,
|
|
21
|
+
local_profile: localProfileName ?? null,
|
|
22
|
+
profiles,
|
|
23
|
+
}, json);
|
|
16
24
|
return;
|
|
17
25
|
}
|
|
18
26
|
case 'show': {
|
|
19
|
-
|
|
27
|
+
// Check for local profile first
|
|
28
|
+
const repoProfile = (0, context_1.loadRepoProfile)();
|
|
29
|
+
const localProfileName = repoProfile?.profile;
|
|
30
|
+
// Determine which profile to show
|
|
31
|
+
const requestedName = positionals[0];
|
|
32
|
+
let name;
|
|
33
|
+
let source;
|
|
34
|
+
if (requestedName) {
|
|
35
|
+
// Explicit name requested
|
|
36
|
+
name = requestedName;
|
|
37
|
+
source = localProfileName === requestedName ? 'local' : 'global';
|
|
38
|
+
}
|
|
39
|
+
else if (localProfileName) {
|
|
40
|
+
// No name specified, use local profile if exists
|
|
41
|
+
name = localProfileName;
|
|
42
|
+
source = 'local';
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// Fall back to global active profile
|
|
46
|
+
name = config.active_profile;
|
|
47
|
+
source = 'global';
|
|
48
|
+
}
|
|
20
49
|
const profile = config.profiles[name];
|
|
21
50
|
if (!profile) {
|
|
22
51
|
throw new Error(`Profile ${name} not found`);
|
|
23
52
|
}
|
|
24
|
-
|
|
53
|
+
// Merge local overrides if showing local profile
|
|
54
|
+
const effectiveProfile = source === 'local' && repoProfile
|
|
55
|
+
? {
|
|
56
|
+
...profile,
|
|
57
|
+
...(repoProfile.api_url && { api_url: repoProfile.api_url }),
|
|
58
|
+
...(repoProfile.org_id && { org_id: repoProfile.org_id }),
|
|
59
|
+
...(repoProfile.project_id && { project_id: repoProfile.project_id }),
|
|
60
|
+
}
|
|
61
|
+
: profile;
|
|
62
|
+
const sourceLabel = source === 'local' ? ` (local: .eve/profile.yaml)` : ' (global)';
|
|
63
|
+
(0, output_1.outputJson)({ name, source, ...effectiveProfile }, json, `${name}${sourceLabel}`);
|
|
25
64
|
return;
|
|
26
65
|
}
|
|
27
66
|
case 'use': {
|
|
67
|
+
const isLocal = Boolean(flags.local);
|
|
68
|
+
const isClear = Boolean(flags.clear);
|
|
69
|
+
// Handle --local --clear: remove local profile
|
|
70
|
+
if (isLocal && isClear) {
|
|
71
|
+
const removed = (0, context_1.removeRepoProfile)();
|
|
72
|
+
if (removed) {
|
|
73
|
+
(0, output_1.outputJson)({ cleared: true, path: (0, context_1.getRepoProfilePath)() }, json, `✓ Removed local profile`);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
(0, output_1.outputJson)({ cleared: false }, json, `No local profile to remove`);
|
|
77
|
+
}
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
28
80
|
const name = positionals[0];
|
|
29
81
|
if (!name) {
|
|
30
|
-
throw new Error('Usage: eve profile use <name>');
|
|
82
|
+
throw new Error('Usage: eve profile use <name> [--local]');
|
|
31
83
|
}
|
|
84
|
+
// Validate profile exists in global config
|
|
32
85
|
if (!config.profiles[name]) {
|
|
33
86
|
config.profiles[name] = {};
|
|
87
|
+
(0, config_1.saveConfig)(config);
|
|
88
|
+
}
|
|
89
|
+
if (isLocal) {
|
|
90
|
+
// Write to .eve/profile.yaml
|
|
91
|
+
const repoProfile = { profile: name };
|
|
92
|
+
// Apply any override flags
|
|
93
|
+
if (typeof flags['api-url'] === 'string')
|
|
94
|
+
repoProfile.api_url = flags['api-url'];
|
|
95
|
+
if (typeof flags.org === 'string')
|
|
96
|
+
repoProfile.org_id = flags.org;
|
|
97
|
+
if (typeof flags.project === 'string')
|
|
98
|
+
repoProfile.project_id = flags.project;
|
|
99
|
+
(0, context_1.saveRepoProfile)(repoProfile);
|
|
100
|
+
(0, output_1.outputJson)({ profile: name, local: true, path: (0, context_1.getRepoProfilePath)(), ...repoProfile }, json, `✓ Local profile set: ${name} (${(0, context_1.getRepoProfilePath)()})`);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
// Set global active profile
|
|
104
|
+
config.active_profile = name;
|
|
105
|
+
(0, config_1.saveConfig)(config);
|
|
106
|
+
(0, output_1.outputJson)({ active_profile: name }, json, `✓ Active profile: ${name}`);
|
|
34
107
|
}
|
|
35
|
-
config.active_profile = name;
|
|
36
|
-
(0, config_1.saveConfig)(config);
|
|
37
|
-
(0, output_1.outputJson)({ active_profile: name }, json, `✓ Active profile: ${name}`);
|
|
38
108
|
return;
|
|
39
109
|
}
|
|
40
110
|
case 'create': {
|
package/dist/lib/context.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getRepoProfilePath = getRepoProfilePath;
|
|
4
|
+
exports.loadRepoProfile = loadRepoProfile;
|
|
5
|
+
exports.saveRepoProfile = saveRepoProfile;
|
|
6
|
+
exports.removeRepoProfile = removeRepoProfile;
|
|
3
7
|
exports.resolveContext = resolveContext;
|
|
4
8
|
exports.parseHarnessSpec = parseHarnessSpec;
|
|
5
9
|
const node_fs_1 = require("node:fs");
|
|
@@ -9,45 +13,95 @@ const args_1 = require("./args");
|
|
|
9
13
|
// Default to Ingress URL for k8s stack (works via lvh.me → 127.0.0.1)
|
|
10
14
|
// Override with EVE_API_URL for other environments (docker compose, local dev)
|
|
11
15
|
const DEFAULT_API_URL = 'http://api.eve.lvh.me';
|
|
16
|
+
/**
|
|
17
|
+
* Get the path to the repo profile file
|
|
18
|
+
*/
|
|
19
|
+
function getRepoProfilePath() {
|
|
20
|
+
return (0, node_path_1.join)(process.cwd(), '.eve', 'profile.yaml');
|
|
21
|
+
}
|
|
12
22
|
/**
|
|
13
23
|
* Load repository profile from .eve/profile.yaml if it exists
|
|
14
|
-
* Returns
|
|
24
|
+
* Returns null if file not found
|
|
15
25
|
*/
|
|
16
26
|
function loadRepoProfile() {
|
|
17
|
-
const profilePath = (
|
|
27
|
+
const profilePath = getRepoProfilePath();
|
|
18
28
|
if (!(0, node_fs_1.existsSync)(profilePath)) {
|
|
19
|
-
return
|
|
29
|
+
return null;
|
|
20
30
|
}
|
|
21
31
|
try {
|
|
22
32
|
const content = (0, node_fs_1.readFileSync)(profilePath, 'utf-8');
|
|
23
33
|
const parsed = (0, yaml_1.parse)(content);
|
|
24
|
-
return parsed ||
|
|
34
|
+
return parsed || null;
|
|
25
35
|
}
|
|
26
|
-
catch
|
|
27
|
-
// Silently ignore parse errors
|
|
28
|
-
return
|
|
36
|
+
catch {
|
|
37
|
+
// Silently ignore parse errors
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Save repository profile to .eve/profile.yaml
|
|
43
|
+
*/
|
|
44
|
+
function saveRepoProfile(repoProfile) {
|
|
45
|
+
const profilePath = getRepoProfilePath();
|
|
46
|
+
const dir = (0, node_path_1.dirname)(profilePath);
|
|
47
|
+
if (!(0, node_fs_1.existsSync)(dir)) {
|
|
48
|
+
(0, node_fs_1.mkdirSync)(dir, { recursive: true });
|
|
49
|
+
}
|
|
50
|
+
(0, node_fs_1.writeFileSync)(profilePath, (0, yaml_1.stringify)(repoProfile));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Remove repository profile file
|
|
54
|
+
*/
|
|
55
|
+
function removeRepoProfile() {
|
|
56
|
+
const profilePath = getRepoProfilePath();
|
|
57
|
+
if (!(0, node_fs_1.existsSync)(profilePath)) {
|
|
58
|
+
return false;
|
|
29
59
|
}
|
|
60
|
+
(0, node_fs_1.unlinkSync)(profilePath);
|
|
61
|
+
return true;
|
|
30
62
|
}
|
|
31
63
|
function resolveContext(flags, config, credentials) {
|
|
32
|
-
const profileName = (0, args_1.getStringFlag)(flags, ['profile']) ||
|
|
33
|
-
process.env.EVE_PROFILE ||
|
|
34
|
-
config.active_profile ||
|
|
35
|
-
'default';
|
|
36
|
-
const profile = config.profiles[profileName] ?? {};
|
|
37
64
|
const repoProfile = loadRepoProfile();
|
|
65
|
+
// Determine profile name and source
|
|
66
|
+
// Priority: flag > env > local (.eve/profile.yaml) > global active
|
|
67
|
+
let profileName;
|
|
68
|
+
let profileSource;
|
|
69
|
+
const flagProfile = (0, args_1.getStringFlag)(flags, ['profile']);
|
|
70
|
+
const envProfile = process.env.EVE_PROFILE;
|
|
71
|
+
const localProfile = repoProfile?.profile;
|
|
72
|
+
if (flagProfile) {
|
|
73
|
+
profileName = flagProfile;
|
|
74
|
+
profileSource = 'flag';
|
|
75
|
+
}
|
|
76
|
+
else if (envProfile) {
|
|
77
|
+
profileName = envProfile;
|
|
78
|
+
profileSource = 'env';
|
|
79
|
+
}
|
|
80
|
+
else if (localProfile) {
|
|
81
|
+
profileName = localProfile;
|
|
82
|
+
profileSource = 'local';
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
profileName = config.active_profile || 'default';
|
|
86
|
+
profileSource = 'global';
|
|
87
|
+
}
|
|
88
|
+
// Get base profile config from global profiles
|
|
89
|
+
const profile = config.profiles[profileName] ?? {};
|
|
90
|
+
// Apply overrides from repo profile on top of base profile
|
|
38
91
|
const apiUrl = (0, args_1.getStringFlag)(flags, ['api', 'api-url']) ||
|
|
39
|
-
repoProfile
|
|
92
|
+
repoProfile?.api_url ||
|
|
40
93
|
process.env.EVE_API_URL ||
|
|
41
94
|
profile.api_url ||
|
|
42
95
|
DEFAULT_API_URL;
|
|
43
96
|
const orgId = (0, args_1.getStringFlag)(flags, ['org']) ||
|
|
44
|
-
repoProfile
|
|
97
|
+
repoProfile?.org_id ||
|
|
45
98
|
process.env.EVE_ORG_ID ||
|
|
46
99
|
profile.org_id;
|
|
47
100
|
const projectId = (0, args_1.getStringFlag)(flags, ['project']) ||
|
|
48
|
-
repoProfile
|
|
101
|
+
repoProfile?.project_id ||
|
|
49
102
|
process.env.EVE_PROJECT_ID ||
|
|
50
103
|
profile.project_id;
|
|
104
|
+
// Credentials are always keyed by profile name (from global credentials file)
|
|
51
105
|
const tokenEntry = credentials.profiles[profileName];
|
|
52
106
|
return {
|
|
53
107
|
apiUrl,
|
|
@@ -58,6 +112,7 @@ function resolveContext(flags, config, credentials) {
|
|
|
58
112
|
token: tokenEntry?.access_token,
|
|
59
113
|
refreshToken: tokenEntry?.refresh_token,
|
|
60
114
|
expiresAt: tokenEntry?.expires_at,
|
|
115
|
+
profileSource,
|
|
61
116
|
};
|
|
62
117
|
}
|
|
63
118
|
/**
|