genbox 1.0.63 → 1.0.65
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/create.js +14 -294
- package/dist/commands/rebuild.js +501 -237
- package/dist/utils/branch-prompt.js +231 -0
- package/dist/utils/env-parser.js +127 -0
- package/dist/utils/git-utils.js +49 -0
- package/dist/utils/index.js +24 -0
- package/dist/utils/ssh-keys.js +98 -0
- package/package.json +1 -1
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Branch Prompt Utilities
|
|
4
|
+
* Shared functions for interactive branch selection
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
40
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
41
|
+
};
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.promptForBranchOptionsCreate = promptForBranchOptionsCreate;
|
|
44
|
+
exports.promptForBranchOptionsRebuild = promptForBranchOptionsRebuild;
|
|
45
|
+
const prompts = __importStar(require("@inquirer/prompts"));
|
|
46
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
47
|
+
/**
|
|
48
|
+
* Prompt for branch options interactively (for create command)
|
|
49
|
+
* Default behavior: create new branch from configured default (or 'main') with branch name = environment name
|
|
50
|
+
*/
|
|
51
|
+
async function promptForBranchOptionsCreate(resolved, config, envName) {
|
|
52
|
+
// Get the default/base branch from config (used as source for new branches)
|
|
53
|
+
const baseBranch = config.defaults?.branch || 'main';
|
|
54
|
+
console.log(chalk_1.default.blue('=== Branch Configuration ==='));
|
|
55
|
+
console.log('');
|
|
56
|
+
const branchChoice = await prompts.select({
|
|
57
|
+
message: 'Branch option:',
|
|
58
|
+
choices: [
|
|
59
|
+
{
|
|
60
|
+
name: `${chalk_1.default.green('Create new branch')} '${chalk_1.default.cyan(envName)}' from '${baseBranch}' ${chalk_1.default.dim('(recommended)')}`,
|
|
61
|
+
value: 'new-from-default',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: `Create new branch from a different source`,
|
|
65
|
+
value: 'new-custom',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'Use an existing branch',
|
|
69
|
+
value: 'existing',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: `Use '${baseBranch}' directly without creating new branch`,
|
|
73
|
+
value: 'default',
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
default: 'new-from-default',
|
|
77
|
+
});
|
|
78
|
+
if (branchChoice === 'new-from-default') {
|
|
79
|
+
// Create new branch from configured default with name = environment name
|
|
80
|
+
return {
|
|
81
|
+
...resolved,
|
|
82
|
+
repos: resolved.repos.map(repo => ({
|
|
83
|
+
...repo,
|
|
84
|
+
branch: envName,
|
|
85
|
+
newBranch: envName,
|
|
86
|
+
sourceBranch: baseBranch,
|
|
87
|
+
})),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (branchChoice === 'new-custom') {
|
|
91
|
+
const newBranchName = await prompts.input({
|
|
92
|
+
message: 'New branch name:',
|
|
93
|
+
default: envName,
|
|
94
|
+
validate: (value) => {
|
|
95
|
+
if (!value.trim())
|
|
96
|
+
return 'Branch name is required';
|
|
97
|
+
if (!/^[\w\-./]+$/.test(value))
|
|
98
|
+
return 'Invalid branch name (use letters, numbers, -, _, /, .)';
|
|
99
|
+
return true;
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
const sourceBranch = await prompts.input({
|
|
103
|
+
message: 'Create from branch:',
|
|
104
|
+
default: 'main',
|
|
105
|
+
validate: (value) => {
|
|
106
|
+
if (!value.trim())
|
|
107
|
+
return 'Source branch is required';
|
|
108
|
+
return true;
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
// Update all repos with new branch info
|
|
112
|
+
return {
|
|
113
|
+
...resolved,
|
|
114
|
+
repos: resolved.repos.map(repo => ({
|
|
115
|
+
...repo,
|
|
116
|
+
branch: newBranchName.trim(),
|
|
117
|
+
newBranch: newBranchName.trim(),
|
|
118
|
+
sourceBranch: sourceBranch.trim(),
|
|
119
|
+
})),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
if (branchChoice === 'existing') {
|
|
123
|
+
const branchName = await prompts.input({
|
|
124
|
+
message: 'Enter branch name:',
|
|
125
|
+
default: baseBranch,
|
|
126
|
+
validate: (value) => {
|
|
127
|
+
if (!value.trim())
|
|
128
|
+
return 'Branch name is required';
|
|
129
|
+
return true;
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
// Update all repos with the selected branch
|
|
133
|
+
return {
|
|
134
|
+
...resolved,
|
|
135
|
+
repos: resolved.repos.map(repo => ({
|
|
136
|
+
...repo,
|
|
137
|
+
branch: branchName.trim(),
|
|
138
|
+
newBranch: undefined,
|
|
139
|
+
sourceBranch: undefined,
|
|
140
|
+
})),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
if (branchChoice === 'default') {
|
|
144
|
+
// Keep resolved repos as-is (no new branch)
|
|
145
|
+
return resolved;
|
|
146
|
+
}
|
|
147
|
+
return resolved;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Prompt for branch options interactively (for rebuild command)
|
|
151
|
+
* Simpler version - just switch branches or create new
|
|
152
|
+
*/
|
|
153
|
+
async function promptForBranchOptionsRebuild(resolved, config) {
|
|
154
|
+
// Get the default branch from config or first repo
|
|
155
|
+
const defaultBranch = config.defaults?.branch || resolved.repos[0]?.branch || 'main';
|
|
156
|
+
console.log(chalk_1.default.blue('=== Branch Configuration ==='));
|
|
157
|
+
console.log(chalk_1.default.dim(`Default branch: ${defaultBranch}`));
|
|
158
|
+
console.log('');
|
|
159
|
+
const branchChoice = await prompts.select({
|
|
160
|
+
message: 'Branch option:',
|
|
161
|
+
choices: [
|
|
162
|
+
{
|
|
163
|
+
name: `Use default branch (${defaultBranch})`,
|
|
164
|
+
value: 'default',
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
name: 'Use a different existing branch',
|
|
168
|
+
value: 'existing',
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
name: 'Create a new branch',
|
|
172
|
+
value: 'new',
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
default: 'default',
|
|
176
|
+
});
|
|
177
|
+
if (branchChoice === 'default') {
|
|
178
|
+
return resolved;
|
|
179
|
+
}
|
|
180
|
+
if (branchChoice === 'existing') {
|
|
181
|
+
const branchName = await prompts.input({
|
|
182
|
+
message: 'Enter branch name:',
|
|
183
|
+
default: defaultBranch,
|
|
184
|
+
validate: (value) => {
|
|
185
|
+
if (!value.trim())
|
|
186
|
+
return 'Branch name is required';
|
|
187
|
+
return true;
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
return {
|
|
191
|
+
...resolved,
|
|
192
|
+
repos: resolved.repos.map(repo => ({
|
|
193
|
+
...repo,
|
|
194
|
+
branch: branchName.trim(),
|
|
195
|
+
newBranch: undefined,
|
|
196
|
+
sourceBranch: undefined,
|
|
197
|
+
})),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
if (branchChoice === 'new') {
|
|
201
|
+
const newBranchName = await prompts.input({
|
|
202
|
+
message: 'New branch name:',
|
|
203
|
+
validate: (value) => {
|
|
204
|
+
if (!value.trim())
|
|
205
|
+
return 'Branch name is required';
|
|
206
|
+
if (!/^[\w\-./]+$/.test(value))
|
|
207
|
+
return 'Invalid branch name (use letters, numbers, -, _, /, .)';
|
|
208
|
+
return true;
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
const sourceBranch = await prompts.input({
|
|
212
|
+
message: 'Create from branch:',
|
|
213
|
+
default: defaultBranch,
|
|
214
|
+
validate: (value) => {
|
|
215
|
+
if (!value.trim())
|
|
216
|
+
return 'Source branch is required';
|
|
217
|
+
return true;
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
return {
|
|
221
|
+
...resolved,
|
|
222
|
+
repos: resolved.repos.map(repo => ({
|
|
223
|
+
...repo,
|
|
224
|
+
branch: newBranchName.trim(),
|
|
225
|
+
newBranch: newBranchName.trim(),
|
|
226
|
+
sourceBranch: sourceBranch.trim(),
|
|
227
|
+
})),
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
return resolved;
|
|
231
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Environment File Parser Utilities
|
|
4
|
+
* Shared functions for parsing and processing .env.genbox files
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.parseEnvGenboxSections = parseEnvGenboxSections;
|
|
8
|
+
exports.buildServiceUrlMap = buildServiceUrlMap;
|
|
9
|
+
exports.buildAppEnvContent = buildAppEnvContent;
|
|
10
|
+
exports.parseEnvVarsFromSection = parseEnvVarsFromSection;
|
|
11
|
+
/**
|
|
12
|
+
* Parse .env.genbox file into segregated sections
|
|
13
|
+
* Sections are marked with: # === SECTION_NAME ===
|
|
14
|
+
*/
|
|
15
|
+
function parseEnvGenboxSections(content) {
|
|
16
|
+
const sections = new Map();
|
|
17
|
+
let currentSection = 'GLOBAL';
|
|
18
|
+
let currentContent = [];
|
|
19
|
+
for (const line of content.split('\n')) {
|
|
20
|
+
const sectionMatch = line.match(/^# === ([^=]+) ===$/);
|
|
21
|
+
if (sectionMatch) {
|
|
22
|
+
// Save previous section
|
|
23
|
+
if (currentContent.length > 0) {
|
|
24
|
+
sections.set(currentSection, currentContent.join('\n').trim());
|
|
25
|
+
}
|
|
26
|
+
currentSection = sectionMatch[1].trim();
|
|
27
|
+
currentContent = [];
|
|
28
|
+
}
|
|
29
|
+
else if (currentSection !== 'END') {
|
|
30
|
+
currentContent.push(line);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// Save last section
|
|
34
|
+
if (currentContent.length > 0 && currentSection !== 'END') {
|
|
35
|
+
sections.set(currentSection, currentContent.join('\n').trim());
|
|
36
|
+
}
|
|
37
|
+
return sections;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Build a map of service URL variables based on connection type
|
|
41
|
+
* e.g., if connectTo=staging: GATEWAY_URL → STAGING_GATEWAY_URL value
|
|
42
|
+
*/
|
|
43
|
+
function buildServiceUrlMap(envVarsFromFile, connectTo) {
|
|
44
|
+
const urlMap = {};
|
|
45
|
+
const prefix = connectTo ? `${connectTo.toUpperCase()}_` : 'LOCAL_';
|
|
46
|
+
// Find all service URL variables (LOCAL_*_URL and STAGING_*_URL patterns)
|
|
47
|
+
const serviceNames = new Set();
|
|
48
|
+
for (const key of Object.keys(envVarsFromFile)) {
|
|
49
|
+
const match = key.match(/^(LOCAL|STAGING|PRODUCTION)_(.+_URL)$/);
|
|
50
|
+
if (match) {
|
|
51
|
+
serviceNames.add(match[2]);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Build mapping: VARNAME → value from appropriate prefix
|
|
55
|
+
for (const serviceName of serviceNames) {
|
|
56
|
+
const prefixedKey = `${prefix}${serviceName}`;
|
|
57
|
+
const localKey = `LOCAL_${serviceName}`;
|
|
58
|
+
// Use prefixed value if available, otherwise fall back to local
|
|
59
|
+
const value = envVarsFromFile[prefixedKey] || envVarsFromFile[localKey];
|
|
60
|
+
if (value) {
|
|
61
|
+
urlMap[serviceName] = value;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Also handle legacy API_URL for backwards compatibility
|
|
65
|
+
if (!urlMap['API_URL']) {
|
|
66
|
+
const apiUrl = envVarsFromFile[`${prefix}API_URL`] ||
|
|
67
|
+
envVarsFromFile['LOCAL_API_URL'] ||
|
|
68
|
+
envVarsFromFile['STAGING_API_URL'];
|
|
69
|
+
if (apiUrl) {
|
|
70
|
+
urlMap['API_URL'] = apiUrl;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return urlMap;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Build env content for a specific app by combining GLOBAL + app-specific sections
|
|
77
|
+
*/
|
|
78
|
+
function buildAppEnvContent(sections, appName, serviceUrlMap) {
|
|
79
|
+
const parts = [];
|
|
80
|
+
// Always include GLOBAL section
|
|
81
|
+
const globalSection = sections.get('GLOBAL');
|
|
82
|
+
if (globalSection) {
|
|
83
|
+
parts.push(globalSection);
|
|
84
|
+
}
|
|
85
|
+
// Include app-specific section if exists
|
|
86
|
+
const appSection = sections.get(appName);
|
|
87
|
+
if (appSection) {
|
|
88
|
+
parts.push(appSection);
|
|
89
|
+
}
|
|
90
|
+
let envContent = parts.join('\n\n');
|
|
91
|
+
// Expand all ${VARNAME} references using the service URL map
|
|
92
|
+
for (const [varName, value] of Object.entries(serviceUrlMap)) {
|
|
93
|
+
const pattern = new RegExp(`\\$\\{${varName}\\}`, 'g');
|
|
94
|
+
envContent = envContent.replace(pattern, value);
|
|
95
|
+
}
|
|
96
|
+
// Keep only actual env vars (filter out pure comment lines but keep var definitions)
|
|
97
|
+
envContent = envContent
|
|
98
|
+
.split('\n')
|
|
99
|
+
.filter(line => {
|
|
100
|
+
const trimmed = line.trim();
|
|
101
|
+
// Keep empty lines, lines with = (even if commented), and non-comment lines
|
|
102
|
+
return trimmed === '' || trimmed.includes('=') || !trimmed.startsWith('#');
|
|
103
|
+
})
|
|
104
|
+
.join('\n')
|
|
105
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
106
|
+
.trim();
|
|
107
|
+
return envContent;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Parse env vars from a section content string
|
|
111
|
+
*/
|
|
112
|
+
function parseEnvVarsFromSection(sectionContent) {
|
|
113
|
+
const envVars = {};
|
|
114
|
+
for (const line of sectionContent.split('\n')) {
|
|
115
|
+
const match = line.match(/^([A-Z_][A-Z0-9_]*)=(.*)$/);
|
|
116
|
+
if (match) {
|
|
117
|
+
let value = match[2].trim();
|
|
118
|
+
// Remove quotes if present
|
|
119
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
120
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
121
|
+
value = value.slice(1, -1);
|
|
122
|
+
}
|
|
123
|
+
envVars[match[1]] = value;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return envVars;
|
|
127
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Git Utilities
|
|
4
|
+
* Shared functions for git configuration and validation
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.validateGitCredentials = validateGitCredentials;
|
|
8
|
+
exports.getGitConfig = getGitConfig;
|
|
9
|
+
const child_process_1 = require("child_process");
|
|
10
|
+
/**
|
|
11
|
+
* Validate git configuration and warn about missing credentials
|
|
12
|
+
*/
|
|
13
|
+
function validateGitCredentials(repos, gitToken, privateKey) {
|
|
14
|
+
const warnings = [];
|
|
15
|
+
const errors = [];
|
|
16
|
+
for (const repo of repos) {
|
|
17
|
+
const isHttps = repo.url.startsWith('https://');
|
|
18
|
+
const isSsh = repo.url.startsWith('git@') || repo.url.includes('ssh://');
|
|
19
|
+
const isPrivateRepo = repo.url.includes('github.com') && !repo.url.includes('/public/');
|
|
20
|
+
if (isHttps && !gitToken && isPrivateRepo) {
|
|
21
|
+
warnings.push(`Repository '${repo.name}' uses HTTPS URL but GIT_TOKEN is not set.`);
|
|
22
|
+
warnings.push(` Add GIT_TOKEN=<your-github-token> to .env.genbox for private repos.`);
|
|
23
|
+
}
|
|
24
|
+
if (isSsh && !privateKey) {
|
|
25
|
+
warnings.push(`Repository '${repo.name}' uses SSH URL but no SSH key was injected.`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return { warnings, errors };
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get local git config for commits on genbox
|
|
32
|
+
*/
|
|
33
|
+
function getGitConfig() {
|
|
34
|
+
let userName;
|
|
35
|
+
let userEmail;
|
|
36
|
+
try {
|
|
37
|
+
userName = (0, child_process_1.execSync)('git config --global user.name', { encoding: 'utf-8' }).trim();
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// Git config not set
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
userEmail = (0, child_process_1.execSync)('git config --global user.email', { encoding: 'utf-8' }).trim();
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// Git config not set
|
|
47
|
+
}
|
|
48
|
+
return { userName, userEmail };
|
|
49
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared Utilities
|
|
4
|
+
* Re-exports all utility modules for convenient importing
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
18
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
__exportStar(require("./ssh-keys"), exports);
|
|
22
|
+
__exportStar(require("./env-parser"), exports);
|
|
23
|
+
__exportStar(require("./git-utils"), exports);
|
|
24
|
+
__exportStar(require("./branch-prompt"), exports);
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SSH Key Utilities
|
|
4
|
+
* Shared functions for reading SSH keys
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.getPublicSshKey = getPublicSshKey;
|
|
41
|
+
exports.getPrivateSshKey = getPrivateSshKey;
|
|
42
|
+
exports.getPrivateSshKeyPath = getPrivateSshKeyPath;
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const path = __importStar(require("path"));
|
|
45
|
+
const os = __importStar(require("os"));
|
|
46
|
+
/**
|
|
47
|
+
* Get the public SSH key content
|
|
48
|
+
* Tries ed25519 first, then RSA
|
|
49
|
+
*/
|
|
50
|
+
function getPublicSshKey() {
|
|
51
|
+
const home = os.homedir();
|
|
52
|
+
const potentialKeys = [
|
|
53
|
+
path.join(home, '.ssh', 'id_ed25519.pub'),
|
|
54
|
+
path.join(home, '.ssh', 'id_rsa.pub'),
|
|
55
|
+
];
|
|
56
|
+
for (const keyPath of potentialKeys) {
|
|
57
|
+
if (fs.existsSync(keyPath)) {
|
|
58
|
+
const content = fs.readFileSync(keyPath, 'utf-8').trim();
|
|
59
|
+
if (content)
|
|
60
|
+
return content;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
throw new Error('No public SSH key found in ~/.ssh/');
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get the private SSH key content (for injection into remote server)
|
|
67
|
+
* Returns undefined if no key found
|
|
68
|
+
*/
|
|
69
|
+
function getPrivateSshKey() {
|
|
70
|
+
const home = os.homedir();
|
|
71
|
+
const potentialKeys = [
|
|
72
|
+
path.join(home, '.ssh', 'id_ed25519'),
|
|
73
|
+
path.join(home, '.ssh', 'id_rsa'),
|
|
74
|
+
];
|
|
75
|
+
for (const keyPath of potentialKeys) {
|
|
76
|
+
if (fs.existsSync(keyPath)) {
|
|
77
|
+
return fs.readFileSync(keyPath, 'utf-8');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get the path to the private SSH key (for local SSH commands)
|
|
84
|
+
* Throws if no key found
|
|
85
|
+
*/
|
|
86
|
+
function getPrivateSshKeyPath() {
|
|
87
|
+
const home = os.homedir();
|
|
88
|
+
const potentialKeys = [
|
|
89
|
+
path.join(home, '.ssh', 'id_ed25519'),
|
|
90
|
+
path.join(home, '.ssh', 'id_rsa'),
|
|
91
|
+
];
|
|
92
|
+
for (const keyPath of potentialKeys) {
|
|
93
|
+
if (fs.existsSync(keyPath)) {
|
|
94
|
+
return keyPath;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
throw new Error('No SSH private key found in ~/.ssh/');
|
|
98
|
+
}
|