@padua/cli 1.7.1 → 1.11.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/README.md +198 -3
- package/dist/commands/doctor/checks.d.ts +30 -0
- package/dist/commands/doctor/checks.d.ts.map +1 -0
- package/dist/commands/doctor/checks.js +374 -0
- package/dist/commands/doctor/checks.js.map +1 -0
- package/dist/commands/doctor/index.d.ts +28 -0
- package/dist/commands/doctor/index.d.ts.map +1 -0
- package/dist/commands/doctor/index.js +168 -0
- package/dist/commands/doctor/index.js.map +1 -0
- package/dist/commands/doctor/suggestions.d.ts +31 -0
- package/dist/commands/doctor/suggestions.d.ts.map +1 -0
- package/dist/commands/doctor/suggestions.js +89 -0
- package/dist/commands/doctor/suggestions.js.map +1 -0
- package/dist/commands/doctor/types.d.ts +55 -0
- package/dist/commands/doctor/types.d.ts.map +1 -0
- package/dist/commands/doctor/types.js +18 -0
- package/dist/commands/doctor/types.js.map +1 -0
- package/dist/commands/init/aws-profile.d.ts +1 -1
- package/dist/commands/init/aws-profile.d.ts.map +1 -1
- package/dist/commands/init/aws-profile.js +146 -31
- package/dist/commands/init/aws-profile.js.map +1 -1
- package/dist/commands/init/index.d.ts +1 -0
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +134 -2
- package/dist/commands/init/index.js.map +1 -1
- package/dist/commands/login/codeartifact.d.ts +4 -1
- package/dist/commands/login/codeartifact.d.ts.map +1 -1
- package/dist/commands/login/codeartifact.js +55 -19
- package/dist/commands/login/codeartifact.js.map +1 -1
- package/dist/commands/login/index.d.ts.map +1 -1
- package/dist/commands/login/index.js +2 -1
- package/dist/commands/login/index.js.map +1 -1
- package/dist/commands/login/npmrc.d.ts +50 -0
- package/dist/commands/login/npmrc.d.ts.map +1 -0
- package/dist/commands/login/npmrc.js +168 -0
- package/dist/commands/login/npmrc.js.map +1 -0
- package/dist/commands/login/types.d.ts +2 -0
- package/dist/commands/login/types.d.ts.map +1 -1
- package/dist/commands/login/types.js.map +1 -1
- package/dist/commands/status/checks.d.ts +1 -1
- package/dist/commands/status/checks.d.ts.map +1 -1
- package/dist/commands/status/checks.js +22 -6
- package/dist/commands/status/checks.js.map +1 -1
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +3 -0
- package/dist/commands/status/index.js.map +1 -1
- package/dist/commands/status/types.d.ts +2 -0
- package/dist/commands/status/types.d.ts.map +1 -1
- package/dist/commands/tunnel/aws.d.ts +22 -3
- package/dist/commands/tunnel/aws.d.ts.map +1 -1
- package/dist/commands/tunnel/aws.js +143 -14
- package/dist/commands/tunnel/aws.js.map +1 -1
- package/dist/commands/tunnel/rds.d.ts.map +1 -1
- package/dist/commands/tunnel/rds.js +67 -18
- package/dist/commands/tunnel/rds.js.map +1 -1
- package/dist/commands/tunnel/types.d.ts +6 -0
- package/dist/commands/tunnel/types.d.ts.map +1 -1
- package/dist/commands/tunnel/types.js +29 -0
- package/dist/commands/tunnel/types.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Doctor command - Validate configuration and diagnose issues
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import { DoctorOptions, DoctorResult, DoctorCheck } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* Doctor command definition
|
|
8
|
+
*/
|
|
9
|
+
export declare const doctorCommand: Command;
|
|
10
|
+
/**
|
|
11
|
+
* Main handler for doctor command
|
|
12
|
+
*/
|
|
13
|
+
declare function handleDoctor(options: DoctorOptions): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Display a single check result
|
|
16
|
+
*/
|
|
17
|
+
declare function displayCheck(check: DoctorCheck, options: {
|
|
18
|
+
noColor?: boolean;
|
|
19
|
+
verbose?: boolean;
|
|
20
|
+
}): void;
|
|
21
|
+
/**
|
|
22
|
+
* Display summary of all checks
|
|
23
|
+
*/
|
|
24
|
+
declare function displaySummary(result: DoctorResult, options: {
|
|
25
|
+
noColor?: boolean;
|
|
26
|
+
}): void;
|
|
27
|
+
export { handleDoctor, displayCheck, displaySummary };
|
|
28
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAiB,WAAW,EAAE,MAAM,SAAS,CAAC;AAUlF;;GAEG;AACH,eAAO,MAAM,aAAa,SAKH,CAAC;AAExB;;GAEG;AACH,iBAAe,YAAY,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAyFjE;AAED;;GAEG;AACH,iBAAS,YAAY,CACnB,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAChD,IAAI,CAwCN;AAED;;GAEG;AACH,iBAAS,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CA4BlF;AAGD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Doctor command - Validate configuration and diagnose issues
|
|
4
|
+
*/
|
|
5
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.doctorCommand = void 0;
|
|
10
|
+
exports.handleDoctor = handleDoctor;
|
|
11
|
+
exports.displayCheck = displayCheck;
|
|
12
|
+
exports.displaySummary = displaySummary;
|
|
13
|
+
const commander_1 = require("commander");
|
|
14
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
15
|
+
const config_1 = require("../login/config");
|
|
16
|
+
const types_1 = require("../login/types");
|
|
17
|
+
const types_2 = require("./types");
|
|
18
|
+
const checks_1 = require("./checks");
|
|
19
|
+
/**
|
|
20
|
+
* Doctor command definition
|
|
21
|
+
*/
|
|
22
|
+
exports.doctorCommand = new commander_1.Command('doctor')
|
|
23
|
+
.description('Validate configuration and diagnose common issues')
|
|
24
|
+
.option('--fix', 'Attempt to auto-fix common issues (not yet implemented)')
|
|
25
|
+
.option('-v, --verbose', 'Show detailed diagnostic information')
|
|
26
|
+
.option('--no-color', 'Disable colored output')
|
|
27
|
+
.action(handleDoctor);
|
|
28
|
+
/**
|
|
29
|
+
* Main handler for doctor command
|
|
30
|
+
*/
|
|
31
|
+
async function handleDoctor(options) {
|
|
32
|
+
const { noColor, verbose } = options;
|
|
33
|
+
// Helper functions for colored output
|
|
34
|
+
const title = (text) => noColor ? text : chalk_1.default.bold(text);
|
|
35
|
+
const success = (text) => noColor ? text : chalk_1.default.green(text);
|
|
36
|
+
const warning = (text) => noColor ? text : chalk_1.default.yellow(text);
|
|
37
|
+
const error = (text) => noColor ? text : chalk_1.default.red(text);
|
|
38
|
+
const dim = (text) => noColor ? text : chalk_1.default.dim(text);
|
|
39
|
+
console.log('');
|
|
40
|
+
console.log(title('🏥 Padua CLI Doctor'));
|
|
41
|
+
console.log('');
|
|
42
|
+
const allChecks = [];
|
|
43
|
+
// 1. Config File Validation
|
|
44
|
+
console.log(title(types_2.CheckCategory.CONFIG));
|
|
45
|
+
const configFileCheck = await (0, checks_1.checkConfigFile)();
|
|
46
|
+
allChecks.push(configFileCheck);
|
|
47
|
+
displayCheck(configFileCheck, { noColor, verbose });
|
|
48
|
+
// If config file is invalid, stop here
|
|
49
|
+
if (configFileCheck.status === 'fail') {
|
|
50
|
+
console.log('');
|
|
51
|
+
displaySummary({ checks: allChecks, issuesFound: 1, warningsFound: 0 }, { noColor });
|
|
52
|
+
process.exit(2);
|
|
53
|
+
}
|
|
54
|
+
// Load config
|
|
55
|
+
const config = await (0, config_1.loadConfig)();
|
|
56
|
+
if (!config) {
|
|
57
|
+
console.log('');
|
|
58
|
+
console.log(error('Error: Unable to load config file'));
|
|
59
|
+
process.exit(2);
|
|
60
|
+
}
|
|
61
|
+
// 2. Config Schema Validation
|
|
62
|
+
const schemaChecks = await (0, checks_1.checkConfigSchema)(config);
|
|
63
|
+
allChecks.push(...schemaChecks);
|
|
64
|
+
schemaChecks.forEach(check => displayCheck(check, { noColor, verbose }));
|
|
65
|
+
// 3. Profile Validation
|
|
66
|
+
const profileCheck = await (0, checks_1.checkDefaultProfile)(config);
|
|
67
|
+
allChecks.push(profileCheck);
|
|
68
|
+
displayCheck(profileCheck, { noColor, verbose });
|
|
69
|
+
console.log('');
|
|
70
|
+
// 4. Prerequisites
|
|
71
|
+
console.log(title(types_2.CheckCategory.PREREQUISITES));
|
|
72
|
+
const prereqChecks = await (0, checks_1.checkPrerequisitesStatus)();
|
|
73
|
+
allChecks.push(...prereqChecks);
|
|
74
|
+
prereqChecks.forEach(check => displayCheck(check, { noColor, verbose }));
|
|
75
|
+
console.log('');
|
|
76
|
+
// 5. Authentication Status
|
|
77
|
+
console.log(title(types_2.CheckCategory.AUTHENTICATION));
|
|
78
|
+
const profile = (0, types_1.getEffectiveProfile)({ profile: config.defaultProfile }, config);
|
|
79
|
+
const authChecks = await (0, checks_1.checkAuthStatus)(profile, config);
|
|
80
|
+
allChecks.push(...authChecks);
|
|
81
|
+
authChecks.forEach(check => displayCheck(check, { noColor, verbose }));
|
|
82
|
+
console.log('');
|
|
83
|
+
// 6. Installation Health
|
|
84
|
+
console.log(title(types_2.CheckCategory.INSTALLATION));
|
|
85
|
+
const versionCheck = await (0, checks_1.checkCliVersion)();
|
|
86
|
+
allChecks.push(versionCheck);
|
|
87
|
+
displayCheck(versionCheck, { noColor, verbose });
|
|
88
|
+
console.log('');
|
|
89
|
+
// Calculate summary
|
|
90
|
+
const result = {
|
|
91
|
+
checks: allChecks,
|
|
92
|
+
issuesFound: allChecks.filter(c => c.status === 'fail').length,
|
|
93
|
+
warningsFound: allChecks.filter(c => c.status === 'warn').length,
|
|
94
|
+
};
|
|
95
|
+
// Display summary
|
|
96
|
+
displaySummary(result, { noColor });
|
|
97
|
+
// Exit with appropriate code
|
|
98
|
+
if (result.issuesFound > 0) {
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
process.exit(0);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Display a single check result
|
|
105
|
+
*/
|
|
106
|
+
function displayCheck(check, options) {
|
|
107
|
+
const { noColor, verbose } = options;
|
|
108
|
+
// Helper functions
|
|
109
|
+
const success = (text) => noColor ? text : chalk_1.default.green(text);
|
|
110
|
+
const warning = (text) => noColor ? text : chalk_1.default.yellow(text);
|
|
111
|
+
const error = (text) => noColor ? text : chalk_1.default.red(text);
|
|
112
|
+
const dim = (text) => noColor ? text : chalk_1.default.dim(text);
|
|
113
|
+
// Status icon
|
|
114
|
+
let icon;
|
|
115
|
+
let statusColor;
|
|
116
|
+
switch (check.status) {
|
|
117
|
+
case 'pass':
|
|
118
|
+
icon = '[✓]';
|
|
119
|
+
statusColor = success;
|
|
120
|
+
break;
|
|
121
|
+
case 'warn':
|
|
122
|
+
icon = '[⚠]';
|
|
123
|
+
statusColor = warning;
|
|
124
|
+
break;
|
|
125
|
+
case 'fail':
|
|
126
|
+
icon = '[✗]';
|
|
127
|
+
statusColor = error;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
// Display check
|
|
131
|
+
console.log(` ${statusColor(icon)} ${check.name}: ${check.message}`);
|
|
132
|
+
// Display suggestion if present
|
|
133
|
+
if (check.suggestion) {
|
|
134
|
+
console.log(` ${dim('→ ' + check.suggestion)}`);
|
|
135
|
+
}
|
|
136
|
+
// Display additional info in verbose mode
|
|
137
|
+
if (verbose && check.status === 'pass') {
|
|
138
|
+
// Could add more verbose details here in the future
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Display summary of all checks
|
|
143
|
+
*/
|
|
144
|
+
function displaySummary(result, options) {
|
|
145
|
+
const { noColor } = options;
|
|
146
|
+
// Helper functions
|
|
147
|
+
const bold = (text) => noColor ? text : chalk_1.default.bold(text);
|
|
148
|
+
const success = (text) => noColor ? text : chalk_1.default.green(text);
|
|
149
|
+
const warning = (text) => noColor ? text : chalk_1.default.yellow(text);
|
|
150
|
+
const error = (text) => noColor ? text : chalk_1.default.red(text);
|
|
151
|
+
if (result.issuesFound === 0 && result.warningsFound === 0) {
|
|
152
|
+
console.log(success(bold('Summary: All checks passed ✓')));
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
const parts = [];
|
|
156
|
+
if (result.issuesFound > 0) {
|
|
157
|
+
const issueText = `${result.issuesFound} error${result.issuesFound !== 1 ? 's' : ''}`;
|
|
158
|
+
parts.push(error(issueText));
|
|
159
|
+
}
|
|
160
|
+
if (result.warningsFound > 0) {
|
|
161
|
+
const warnText = `${result.warningsFound} warning${result.warningsFound !== 1 ? 's' : ''}`;
|
|
162
|
+
parts.push(warning(warnText));
|
|
163
|
+
}
|
|
164
|
+
console.log(bold(`Summary: ${parts.join(', ')}`));
|
|
165
|
+
}
|
|
166
|
+
console.log('');
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/doctor/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fuzzy matching and suggestion utilities for profile names
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Calculate Levenshtein distance between two strings
|
|
6
|
+
* Used for fuzzy matching of profile names
|
|
7
|
+
*
|
|
8
|
+
* @param a First string
|
|
9
|
+
* @param b Second string
|
|
10
|
+
* @returns Edit distance (lower = more similar)
|
|
11
|
+
*/
|
|
12
|
+
export declare function levenshteinDistance(a: string, b: string): number;
|
|
13
|
+
/**
|
|
14
|
+
* Find the closest matching profile name from available profiles
|
|
15
|
+
*
|
|
16
|
+
* @param target Target profile name (potentially misspelled)
|
|
17
|
+
* @param availableProfiles List of valid profile names
|
|
18
|
+
* @param maxDistance Maximum edit distance to consider (default: 3)
|
|
19
|
+
* @returns Best matching profile name, or undefined if no close match
|
|
20
|
+
*/
|
|
21
|
+
export declare function findClosestProfile(target: string, availableProfiles: string[], maxDistance?: number): string | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Find all profiles that are similar to the target
|
|
24
|
+
*
|
|
25
|
+
* @param target Target profile name
|
|
26
|
+
* @param availableProfiles List of valid profile names
|
|
27
|
+
* @param maxDistance Maximum edit distance (default: 3)
|
|
28
|
+
* @returns Array of similar profile names sorted by distance
|
|
29
|
+
*/
|
|
30
|
+
export declare function findSimilarProfiles(target: string, availableProfiles: string[], maxDistance?: number): string[];
|
|
31
|
+
//# sourceMappingURL=suggestions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggestions.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/suggestions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAgChE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,MAAM,EAAE,EAC3B,WAAW,GAAE,MAAU,GACtB,MAAM,GAAG,SAAS,CAkBpB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,MAAM,EAAE,EAC3B,WAAW,GAAE,MAAU,GACtB,MAAM,EAAE,CAWV"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Fuzzy matching and suggestion utilities for profile names
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.levenshteinDistance = levenshteinDistance;
|
|
7
|
+
exports.findClosestProfile = findClosestProfile;
|
|
8
|
+
exports.findSimilarProfiles = findSimilarProfiles;
|
|
9
|
+
/**
|
|
10
|
+
* Calculate Levenshtein distance between two strings
|
|
11
|
+
* Used for fuzzy matching of profile names
|
|
12
|
+
*
|
|
13
|
+
* @param a First string
|
|
14
|
+
* @param b Second string
|
|
15
|
+
* @returns Edit distance (lower = more similar)
|
|
16
|
+
*/
|
|
17
|
+
function levenshteinDistance(a, b) {
|
|
18
|
+
if (a.length === 0)
|
|
19
|
+
return b.length;
|
|
20
|
+
if (b.length === 0)
|
|
21
|
+
return a.length;
|
|
22
|
+
const matrix = [];
|
|
23
|
+
// Initialize first column
|
|
24
|
+
for (let i = 0; i <= b.length; i++) {
|
|
25
|
+
matrix[i] = [i];
|
|
26
|
+
}
|
|
27
|
+
// Initialize first row
|
|
28
|
+
for (let j = 0; j <= a.length; j++) {
|
|
29
|
+
matrix[0][j] = j;
|
|
30
|
+
}
|
|
31
|
+
// Fill in the rest of the matrix
|
|
32
|
+
for (let i = 1; i <= b.length; i++) {
|
|
33
|
+
for (let j = 1; j <= a.length; j++) {
|
|
34
|
+
if (b.charAt(i - 1) === a.charAt(j - 1)) {
|
|
35
|
+
matrix[i][j] = matrix[i - 1][j - 1];
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution
|
|
39
|
+
matrix[i][j - 1] + 1, // insertion
|
|
40
|
+
matrix[i - 1][j] + 1 // deletion
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return matrix[b.length][a.length];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Find the closest matching profile name from available profiles
|
|
49
|
+
*
|
|
50
|
+
* @param target Target profile name (potentially misspelled)
|
|
51
|
+
* @param availableProfiles List of valid profile names
|
|
52
|
+
* @param maxDistance Maximum edit distance to consider (default: 3)
|
|
53
|
+
* @returns Best matching profile name, or undefined if no close match
|
|
54
|
+
*/
|
|
55
|
+
function findClosestProfile(target, availableProfiles, maxDistance = 3) {
|
|
56
|
+
if (availableProfiles.length === 0) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
let bestMatch = undefined;
|
|
60
|
+
let bestDistance = Infinity;
|
|
61
|
+
for (const profile of availableProfiles) {
|
|
62
|
+
const distance = levenshteinDistance(target.toLowerCase(), profile.toLowerCase());
|
|
63
|
+
if (distance < bestDistance && distance <= maxDistance) {
|
|
64
|
+
bestDistance = distance;
|
|
65
|
+
bestMatch = profile;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return bestMatch;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Find all profiles that are similar to the target
|
|
72
|
+
*
|
|
73
|
+
* @param target Target profile name
|
|
74
|
+
* @param availableProfiles List of valid profile names
|
|
75
|
+
* @param maxDistance Maximum edit distance (default: 3)
|
|
76
|
+
* @returns Array of similar profile names sorted by distance
|
|
77
|
+
*/
|
|
78
|
+
function findSimilarProfiles(target, availableProfiles, maxDistance = 3) {
|
|
79
|
+
const matches = availableProfiles
|
|
80
|
+
.map(profile => ({
|
|
81
|
+
profile,
|
|
82
|
+
distance: levenshteinDistance(target.toLowerCase(), profile.toLowerCase()),
|
|
83
|
+
}))
|
|
84
|
+
.filter(match => match.distance <= maxDistance && match.distance > 0)
|
|
85
|
+
.sort((a, b) => a.distance - b.distance)
|
|
86
|
+
.map(match => match.profile);
|
|
87
|
+
return matches;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=suggestions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggestions.js","sourceRoot":"","sources":["../../../src/commands/doctor/suggestions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for the doctor command
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Status of a single diagnostic check
|
|
6
|
+
*/
|
|
7
|
+
export type CheckStatus = 'pass' | 'warn' | 'fail';
|
|
8
|
+
/**
|
|
9
|
+
* Result of a single diagnostic check
|
|
10
|
+
*/
|
|
11
|
+
export interface DoctorCheck {
|
|
12
|
+
/** Name of the check */
|
|
13
|
+
name: string;
|
|
14
|
+
/** Status of the check */
|
|
15
|
+
status: CheckStatus;
|
|
16
|
+
/** Primary message describing the result */
|
|
17
|
+
message: string;
|
|
18
|
+
/** Suggestion for fixing the issue (if applicable) */
|
|
19
|
+
suggestion?: string;
|
|
20
|
+
/** Whether this issue can be auto-fixed (future enhancement) */
|
|
21
|
+
fixable?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Aggregated result of all diagnostic checks
|
|
25
|
+
*/
|
|
26
|
+
export interface DoctorResult {
|
|
27
|
+
/** All checks performed */
|
|
28
|
+
checks: DoctorCheck[];
|
|
29
|
+
/** Number of failed checks */
|
|
30
|
+
issuesFound: number;
|
|
31
|
+
/** Number of warning checks */
|
|
32
|
+
warningsFound: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Command-line options for `padua doctor`
|
|
36
|
+
*/
|
|
37
|
+
export interface DoctorOptions {
|
|
38
|
+
/** Attempt to auto-fix common issues (future enhancement) */
|
|
39
|
+
fix?: boolean;
|
|
40
|
+
/** Show detailed diagnostic information */
|
|
41
|
+
verbose?: boolean;
|
|
42
|
+
/** Disable colored output */
|
|
43
|
+
noColor?: boolean;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Category grouping for checks
|
|
47
|
+
*/
|
|
48
|
+
export declare enum CheckCategory {
|
|
49
|
+
CONFIG = "Config Validation",
|
|
50
|
+
PROFILE = "Profile Validation",
|
|
51
|
+
PREREQUISITES = "Prerequisites",
|
|
52
|
+
AUTHENTICATION = "Authentication",
|
|
53
|
+
INSTALLATION = "Installation"
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,2BAA2B;IAC3B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,8BAA8B;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,+BAA+B;IAC/B,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,2CAA2C;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,oBAAY,aAAa;IACvB,MAAM,sBAAsB;IAC5B,OAAO,uBAAuB;IAC9B,aAAa,kBAAkB;IAC/B,cAAc,mBAAmB;IACjC,YAAY,iBAAiB;CAC9B"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Type definitions for the doctor command
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CheckCategory = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Category grouping for checks
|
|
9
|
+
*/
|
|
10
|
+
var CheckCategory;
|
|
11
|
+
(function (CheckCategory) {
|
|
12
|
+
CheckCategory["CONFIG"] = "Config Validation";
|
|
13
|
+
CheckCategory["PROFILE"] = "Profile Validation";
|
|
14
|
+
CheckCategory["PREREQUISITES"] = "Prerequisites";
|
|
15
|
+
CheckCategory["AUTHENTICATION"] = "Authentication";
|
|
16
|
+
CheckCategory["INSTALLATION"] = "Installation";
|
|
17
|
+
})(CheckCategory || (exports.CheckCategory = CheckCategory = {}));
|
|
18
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/commands/doctor/types.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AA+CH;;GAEG;AACH,IAAY,aAMX;AAND,WAAY,aAAa;IACvB,6CAA4B,CAAA;IAC5B,+CAA8B,CAAA;IAC9B,gDAA+B,CAAA;IAC/B,kDAAiC,CAAA;IACjC,8CAA6B,CAAA;AAC/B,CAAC,EANW,aAAa,6BAAb,aAAa,QAMxB"}
|
|
@@ -35,5 +35,5 @@ export declare function removeSSOSession(configContent: string, sessionName: str
|
|
|
35
35
|
/**
|
|
36
36
|
* Write SSO session and multiple profiles to ~/.aws/config
|
|
37
37
|
*/
|
|
38
|
-
export declare function writeFullSSOConfig(ssoSession: SSOSessionConfig, profiles: ProfileConfig[], defaultRegion: string, overwrite?: boolean): Promise<string>;
|
|
38
|
+
export declare function writeFullSSOConfig(ssoSession: SSOSessionConfig, profiles: ProfileConfig[], defaultRegion: string, overwrite?: boolean, keepExisting?: boolean): Promise<string>;
|
|
39
39
|
//# sourceMappingURL=aws-profile.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aws-profile.d.ts","sourceRoot":"","sources":["../../../src/commands/init/aws-profile.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"aws-profile.d.ts","sourceRoot":"","sources":["../../../src/commands/init/aws-profile.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA+KlE;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,SAAS,EACjB,SAAS,GAAE,OAAe,GACzB,OAAO,CAAC,MAAM,CAAC,CAwCjB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAO1D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAK1E;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,GACpB,MAAM,CAMR;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAGpF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAMnF;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,gBAAgB,EAC5B,QAAQ,EAAE,aAAa,EAAE,EACzB,aAAa,EAAE,MAAM,EACrB,SAAS,GAAE,OAAe,EAC1B,YAAY,GAAE,OAAe,GAC5B,OAAO,CAAC,MAAM,CAAC,CAuDjB"}
|
|
@@ -45,6 +45,128 @@ const fs = __importStar(require("fs"));
|
|
|
45
45
|
const path = __importStar(require("path"));
|
|
46
46
|
const os = __importStar(require("os"));
|
|
47
47
|
const AWS_CONFIG_PATH = path.join(os.homedir(), '.aws', 'config');
|
|
48
|
+
/**
|
|
49
|
+
* Create a timestamped backup of the AWS config file
|
|
50
|
+
* @param configPath - Path to the AWS config file
|
|
51
|
+
* @returns Path to backup file, or null if no backup created
|
|
52
|
+
*/
|
|
53
|
+
function createBackup(configPath) {
|
|
54
|
+
if (!fs.existsSync(configPath)) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
const now = new Date();
|
|
58
|
+
const timestamp = now.toISOString()
|
|
59
|
+
.replace(/T/, '-')
|
|
60
|
+
.replace(/:/g, '')
|
|
61
|
+
.replace(/\..+/, '')
|
|
62
|
+
.slice(0, 15); // YYYYMMDD-HHMMSS format
|
|
63
|
+
const backupPath = `${configPath}.backup.${timestamp}`;
|
|
64
|
+
try {
|
|
65
|
+
fs.copyFileSync(configPath, backupPath);
|
|
66
|
+
return backupPath;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
console.warn(`Warning: Failed to create backup: ${error.message}`);
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Clean up old backup files, keeping only the most recent N backups
|
|
75
|
+
* @param awsDir - Path to ~/.aws directory
|
|
76
|
+
* @param keepCount - Number of backups to keep
|
|
77
|
+
*/
|
|
78
|
+
function cleanupOldBackups(awsDir, keepCount = 5) {
|
|
79
|
+
if (!fs.existsSync(awsDir)) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
const files = fs.readdirSync(awsDir);
|
|
84
|
+
const backupFiles = files
|
|
85
|
+
.filter(f => f.startsWith('config.backup.'))
|
|
86
|
+
.map(f => ({
|
|
87
|
+
name: f,
|
|
88
|
+
path: path.join(awsDir, f),
|
|
89
|
+
stat: fs.statSync(path.join(awsDir, f))
|
|
90
|
+
}))
|
|
91
|
+
.sort((a, b) => b.stat.mtime.getTime() - a.stat.mtime.getTime());
|
|
92
|
+
// Remove backups beyond keepCount
|
|
93
|
+
if (backupFiles.length > keepCount) {
|
|
94
|
+
const toRemove = backupFiles.slice(keepCount);
|
|
95
|
+
for (const backup of toRemove) {
|
|
96
|
+
try {
|
|
97
|
+
fs.unlinkSync(backup.path);
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
// Ignore errors removing old backups
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
// Ignore errors during cleanup
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Delete the AWS config file
|
|
111
|
+
* @param configPath - Path to the AWS config file
|
|
112
|
+
*/
|
|
113
|
+
function deleteAwsConfig(configPath) {
|
|
114
|
+
if (fs.existsSync(configPath)) {
|
|
115
|
+
fs.unlinkSync(configPath);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Check if a profile section references the Padua SSO session
|
|
120
|
+
* @param profileSection - The profile section text
|
|
121
|
+
* @returns True if it's a Padua-managed profile
|
|
122
|
+
*/
|
|
123
|
+
function isPaduaManagedProfile(profileSection) {
|
|
124
|
+
return /sso_session\s*=\s*padua/i.test(profileSection);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Extract non-Padua profiles from AWS config content
|
|
128
|
+
* @param configContent - The AWS config file content
|
|
129
|
+
* @returns Array of profile section strings (non-Padua profiles)
|
|
130
|
+
*/
|
|
131
|
+
function extractNonPaduaProfiles(configContent) {
|
|
132
|
+
const profiles = [];
|
|
133
|
+
// Split into sections by profile headers
|
|
134
|
+
const sections = configContent.split(/(?=\[(?:profile |sso-session ))/);
|
|
135
|
+
for (const section of sections) {
|
|
136
|
+
const trimmed = section.trim();
|
|
137
|
+
if (!trimmed)
|
|
138
|
+
continue;
|
|
139
|
+
// Skip SSO session sections (we manage these)
|
|
140
|
+
if (trimmed.startsWith('[sso-session')) {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
// Skip Padua-managed profiles
|
|
144
|
+
if (trimmed.startsWith('[profile') && isPaduaManagedProfile(trimmed)) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
// Keep custom profiles
|
|
148
|
+
if (trimmed.startsWith('[profile')) {
|
|
149
|
+
profiles.push(trimmed);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return profiles;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Merge custom profiles back into new config content
|
|
156
|
+
* @param newContent - The new Padua-generated config
|
|
157
|
+
* @param customProfiles - Array of custom profile sections to preserve
|
|
158
|
+
* @returns Merged config content
|
|
159
|
+
*/
|
|
160
|
+
function mergeCustomProfiles(newContent, customProfiles) {
|
|
161
|
+
if (customProfiles.length === 0) {
|
|
162
|
+
return newContent;
|
|
163
|
+
}
|
|
164
|
+
let result = newContent.trim();
|
|
165
|
+
for (const profile of customProfiles) {
|
|
166
|
+
result += '\n\n' + profile.trim();
|
|
167
|
+
}
|
|
168
|
+
return result + '\n';
|
|
169
|
+
}
|
|
48
170
|
/**
|
|
49
171
|
* Generate AWS config profile content for SSO
|
|
50
172
|
*/
|
|
@@ -165,52 +287,45 @@ function removeSSOSession(configContent, sessionName) {
|
|
|
165
287
|
/**
|
|
166
288
|
* Write SSO session and multiple profiles to ~/.aws/config
|
|
167
289
|
*/
|
|
168
|
-
async function writeFullSSOConfig(ssoSession, profiles, defaultRegion, overwrite = false) {
|
|
290
|
+
async function writeFullSSOConfig(ssoSession, profiles, defaultRegion, overwrite = false, keepExisting = false) {
|
|
169
291
|
// Ensure ~/.aws directory exists
|
|
170
292
|
const awsDir = path.dirname(AWS_CONFIG_PATH);
|
|
171
293
|
if (!fs.existsSync(awsDir)) {
|
|
172
294
|
fs.mkdirSync(awsDir, { recursive: true, mode: 0o700 });
|
|
173
295
|
}
|
|
174
|
-
//
|
|
175
|
-
let
|
|
176
|
-
if (fs.existsSync(AWS_CONFIG_PATH)) {
|
|
177
|
-
existingContent = fs.readFileSync(AWS_CONFIG_PATH, 'utf-8');
|
|
178
|
-
|
|
179
|
-
// Remove existing SSO session if overwriting
|
|
180
|
-
if (ssoSessionExists(existingContent, ssoSession.sessionName)) {
|
|
181
|
-
if (!overwrite) {
|
|
182
|
-
throw new Error(`SSO session '${ssoSession.sessionName}' already exists in ${AWS_CONFIG_PATH}. ` +
|
|
183
|
-
`Use --force to overwrite.`);
|
|
184
|
-
}
|
|
185
|
-
existingContent = removeSSOSession(existingContent, ssoSession.sessionName);
|
|
296
|
+
// Extract custom profiles before deletion if keepExisting is true
|
|
297
|
+
let customProfiles = [];
|
|
298
|
+
if (keepExisting && fs.existsSync(AWS_CONFIG_PATH)) {
|
|
299
|
+
const existingContent = fs.readFileSync(AWS_CONFIG_PATH, 'utf-8');
|
|
300
|
+
customProfiles = extractNonPaduaProfiles(existingContent);
|
|
186
301
|
}
|
|
187
|
-
//
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
193
|
-
// If not overwriting, we'll just skip adding this profile (don't throw error)
|
|
302
|
+
// Create backup if file exists
|
|
303
|
+
if (fs.existsSync(AWS_CONFIG_PATH)) {
|
|
304
|
+
const backupPath = createBackup(AWS_CONFIG_PATH);
|
|
305
|
+
if (backupPath) {
|
|
306
|
+
console.log(`Backup created: ${backupPath}`);
|
|
194
307
|
}
|
|
308
|
+
// Cleanup old backups
|
|
309
|
+
cleanupOldBackups(awsDir, 5);
|
|
195
310
|
}
|
|
196
|
-
//
|
|
311
|
+
// Delete existing config file (fresh start)
|
|
312
|
+
deleteAwsConfig(AWS_CONFIG_PATH);
|
|
313
|
+
// Build new content from scratch
|
|
197
314
|
const ssoSessionContent = generateSSOSessionContent(ssoSession);
|
|
198
315
|
const profileContents = [];
|
|
199
316
|
for (const p of profiles) {
|
|
200
|
-
|
|
201
|
-
if (!profileExists(existingContent, p.name)) {
|
|
202
|
-
profileContents.push(generateSSOSessionProfileContent(p.name, p.accountId, p.roleName, ssoSession.sessionName, defaultRegion));
|
|
203
|
-
}
|
|
317
|
+
profileContents.push(generateSSOSessionProfileContent(p.name, p.accountId, p.roleName, ssoSession.sessionName, defaultRegion));
|
|
204
318
|
}
|
|
205
|
-
// Combine all content
|
|
206
|
-
let finalContent =
|
|
207
|
-
if (finalContent) {
|
|
208
|
-
finalContent += '\n\n';
|
|
209
|
-
}
|
|
210
|
-
finalContent += ssoSessionContent + '\n';
|
|
319
|
+
// Combine all new content
|
|
320
|
+
let finalContent = ssoSessionContent + '\n';
|
|
211
321
|
for (const profileContent of profileContents) {
|
|
212
322
|
finalContent += '\n' + profileContent + '\n';
|
|
213
323
|
}
|
|
324
|
+
// Merge custom profiles back if keepExisting
|
|
325
|
+
if (keepExisting && customProfiles.length > 0) {
|
|
326
|
+
finalContent = mergeCustomProfiles(finalContent, customProfiles);
|
|
327
|
+
console.log(`Preserved ${customProfiles.length} custom profile(s)`);
|
|
328
|
+
}
|
|
214
329
|
// Write the config file
|
|
215
330
|
fs.writeFileSync(AWS_CONFIG_PATH, finalContent, { mode: 0o600 });
|
|
216
331
|
return AWS_CONFIG_PATH;
|