@edgible-team/cli 1.0.1
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 +136 -0
- package/README.md +450 -0
- package/dist/client/api-client.js +1057 -0
- package/dist/client/index.js +21 -0
- package/dist/commands/agent.js +1280 -0
- package/dist/commands/ai.js +608 -0
- package/dist/commands/application.js +885 -0
- package/dist/commands/auth.js +570 -0
- package/dist/commands/base/BaseCommand.js +93 -0
- package/dist/commands/base/CommandHandler.js +7 -0
- package/dist/commands/base/command-wrapper.js +58 -0
- package/dist/commands/base/middleware.js +77 -0
- package/dist/commands/config.js +116 -0
- package/dist/commands/connectivity.js +59 -0
- package/dist/commands/debug.js +98 -0
- package/dist/commands/discover.js +144 -0
- package/dist/commands/examples/migrated-command-example.js +180 -0
- package/dist/commands/gateway.js +494 -0
- package/dist/commands/managedGateway.js +787 -0
- package/dist/commands/utils/config-validator.js +76 -0
- package/dist/commands/utils/gateway-prompt.js +79 -0
- package/dist/commands/utils/input-parser.js +120 -0
- package/dist/commands/utils/output-formatter.js +109 -0
- package/dist/config/app-config.js +99 -0
- package/dist/detection/SystemCapabilityDetector.js +1244 -0
- package/dist/detection/ToolDetector.js +305 -0
- package/dist/detection/WorkloadDetector.js +314 -0
- package/dist/di/bindings.js +99 -0
- package/dist/di/container.js +88 -0
- package/dist/di/types.js +32 -0
- package/dist/index.js +52 -0
- package/dist/interfaces/IDaemonManager.js +3 -0
- package/dist/repositories/config-repository.js +62 -0
- package/dist/repositories/gateway-repository.js +35 -0
- package/dist/scripts/postinstall.js +101 -0
- package/dist/services/AgentStatusManager.js +299 -0
- package/dist/services/ConnectivityTester.js +271 -0
- package/dist/services/DependencyInstaller.js +475 -0
- package/dist/services/LocalAgentManager.js +2216 -0
- package/dist/services/application/ApplicationService.js +299 -0
- package/dist/services/auth/AuthService.js +214 -0
- package/dist/services/aws.js +644 -0
- package/dist/services/daemon/DaemonManagerFactory.js +65 -0
- package/dist/services/daemon/DockerDaemonManager.js +395 -0
- package/dist/services/daemon/LaunchdDaemonManager.js +257 -0
- package/dist/services/daemon/PodmanDaemonManager.js +369 -0
- package/dist/services/daemon/SystemdDaemonManager.js +221 -0
- package/dist/services/daemon/WindowsServiceDaemonManager.js +210 -0
- package/dist/services/daemon/index.js +16 -0
- package/dist/services/edgible.js +3060 -0
- package/dist/services/gateway/GatewayService.js +334 -0
- package/dist/state/config.js +146 -0
- package/dist/types/AgentConfig.js +5 -0
- package/dist/types/AgentStatus.js +5 -0
- package/dist/types/ApiClient.js +5 -0
- package/dist/types/ApiRequests.js +5 -0
- package/dist/types/ApiResponses.js +5 -0
- package/dist/types/Application.js +5 -0
- package/dist/types/CaddyJson.js +5 -0
- package/dist/types/UnifiedAgentStatus.js +56 -0
- package/dist/types/WireGuard.js +5 -0
- package/dist/types/Workload.js +5 -0
- package/dist/types/agent.js +5 -0
- package/dist/types/command-options.js +5 -0
- package/dist/types/connectivity.js +5 -0
- package/dist/types/errors.js +250 -0
- package/dist/types/gateway-types.js +5 -0
- package/dist/types/index.js +48 -0
- package/dist/types/models/ApplicationData.js +5 -0
- package/dist/types/models/CertificateData.js +5 -0
- package/dist/types/models/DeviceData.js +5 -0
- package/dist/types/models/DevicePoolData.js +5 -0
- package/dist/types/models/OrganizationData.js +5 -0
- package/dist/types/models/OrganizationInviteData.js +5 -0
- package/dist/types/models/ProviderConfiguration.js +5 -0
- package/dist/types/models/ResourceData.js +5 -0
- package/dist/types/models/ServiceResourceData.js +5 -0
- package/dist/types/models/UserData.js +5 -0
- package/dist/types/route.js +5 -0
- package/dist/types/validation/schemas.js +218 -0
- package/dist/types/validation.js +5 -0
- package/dist/utils/FileIntegrityManager.js +256 -0
- package/dist/utils/PathMigration.js +219 -0
- package/dist/utils/PathResolver.js +235 -0
- package/dist/utils/PlatformDetector.js +277 -0
- package/dist/utils/console-logger.js +130 -0
- package/dist/utils/docker-compose-parser.js +179 -0
- package/dist/utils/errors.js +130 -0
- package/dist/utils/health-checker.js +155 -0
- package/dist/utils/json-logger.js +72 -0
- package/dist/utils/log-formatter.js +293 -0
- package/dist/utils/logger.js +59 -0
- package/dist/utils/network-utils.js +217 -0
- package/dist/utils/output.js +182 -0
- package/dist/utils/passwordValidation.js +91 -0
- package/dist/utils/progress.js +167 -0
- package/dist/utils/sudo-checker.js +22 -0
- package/dist/utils/urls.js +32 -0
- package/dist/utils/validation.js +31 -0
- package/dist/validation/schemas.js +175 -0
- package/dist/validation/validator.js +67 -0
- package/package.json +83 -0
|
@@ -0,0 +1,182 @@
|
|
|
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.outputConfig = void 0;
|
|
7
|
+
exports.success = success;
|
|
8
|
+
exports.error = error;
|
|
9
|
+
exports.warning = warning;
|
|
10
|
+
exports.info = info;
|
|
11
|
+
exports.gray = gray;
|
|
12
|
+
exports.cyan = cyan;
|
|
13
|
+
exports.white = white;
|
|
14
|
+
exports.heading = heading;
|
|
15
|
+
exports.section = section;
|
|
16
|
+
exports.field = field;
|
|
17
|
+
exports.formatOutput = formatOutput;
|
|
18
|
+
exports.outputJSON = outputJSON;
|
|
19
|
+
exports.detectColorSupport = detectColorSupport;
|
|
20
|
+
exports.applyOutputConfig = applyOutputConfig;
|
|
21
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
22
|
+
/**
|
|
23
|
+
* Configuration for output formatting
|
|
24
|
+
*/
|
|
25
|
+
class OutputConfig {
|
|
26
|
+
constructor() {
|
|
27
|
+
this.colorEnabled = true;
|
|
28
|
+
this.plainMode = false;
|
|
29
|
+
this.emojiEnabled = true;
|
|
30
|
+
}
|
|
31
|
+
setNoColor() {
|
|
32
|
+
this.colorEnabled = false;
|
|
33
|
+
// Disable chalk colors
|
|
34
|
+
chalk_1.default.level = 0;
|
|
35
|
+
}
|
|
36
|
+
setPlainMode() {
|
|
37
|
+
this.plainMode = true;
|
|
38
|
+
this.emojiEnabled = false;
|
|
39
|
+
this.setNoColor();
|
|
40
|
+
}
|
|
41
|
+
reset() {
|
|
42
|
+
this.colorEnabled = true;
|
|
43
|
+
this.plainMode = false;
|
|
44
|
+
this.emojiEnabled = true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.outputConfig = new OutputConfig();
|
|
48
|
+
/**
|
|
49
|
+
* Format success message
|
|
50
|
+
*/
|
|
51
|
+
function success(message) {
|
|
52
|
+
if (exports.outputConfig.plainMode)
|
|
53
|
+
return `✓ ${message}`;
|
|
54
|
+
return exports.outputConfig.colorEnabled ? chalk_1.default.green(`✓ ${message}`) : `✓ ${message}`;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Format error message
|
|
58
|
+
*/
|
|
59
|
+
function error(message) {
|
|
60
|
+
if (exports.outputConfig.plainMode)
|
|
61
|
+
return `✗ ${message}`;
|
|
62
|
+
return exports.outputConfig.colorEnabled ? chalk_1.default.red(`✗ ${message}`) : `✗ ${message}`;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Format warning message
|
|
66
|
+
*/
|
|
67
|
+
function warning(message) {
|
|
68
|
+
if (exports.outputConfig.plainMode)
|
|
69
|
+
return `⚠ ${message}`;
|
|
70
|
+
return exports.outputConfig.colorEnabled ? chalk_1.default.yellow(`⚠ ${message}`) : `⚠ ${message}`;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Format info message
|
|
74
|
+
*/
|
|
75
|
+
function info(message) {
|
|
76
|
+
if (exports.outputConfig.plainMode)
|
|
77
|
+
return message;
|
|
78
|
+
return exports.outputConfig.colorEnabled ? chalk_1.default.blue(message) : message;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Format gray message
|
|
82
|
+
*/
|
|
83
|
+
function gray(message) {
|
|
84
|
+
if (exports.outputConfig.plainMode)
|
|
85
|
+
return message;
|
|
86
|
+
return exports.outputConfig.colorEnabled ? chalk_1.default.gray(message) : message;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Format cyan message
|
|
90
|
+
*/
|
|
91
|
+
function cyan(message) {
|
|
92
|
+
if (exports.outputConfig.plainMode)
|
|
93
|
+
return message;
|
|
94
|
+
return exports.outputConfig.colorEnabled ? chalk_1.default.cyan(message) : message;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Format white message
|
|
98
|
+
*/
|
|
99
|
+
function white(message) {
|
|
100
|
+
if (exports.outputConfig.plainMode)
|
|
101
|
+
return message;
|
|
102
|
+
return exports.outputConfig.colorEnabled ? chalk_1.default.white(message) : message;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Format heading
|
|
106
|
+
*/
|
|
107
|
+
function heading(message) {
|
|
108
|
+
if (exports.outputConfig.plainMode)
|
|
109
|
+
return `\n${message}\n`;
|
|
110
|
+
const border = exports.outputConfig.emojiEnabled ? '═'.repeat(60) : '='.repeat(60);
|
|
111
|
+
return exports.outputConfig.colorEnabled
|
|
112
|
+
? chalk_1.default.blue.bold(`\n${border}\n${message}\n${border}`)
|
|
113
|
+
: `\n${message}\n`;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Format section header
|
|
117
|
+
*/
|
|
118
|
+
function section(title) {
|
|
119
|
+
if (exports.outputConfig.plainMode)
|
|
120
|
+
return `\n${title}:\n`;
|
|
121
|
+
return exports.outputConfig.colorEnabled ? chalk_1.default.blue(title) : title;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Format field label and value
|
|
125
|
+
*/
|
|
126
|
+
function field(label, value, highlight = false) {
|
|
127
|
+
const labelText = `${label}:`;
|
|
128
|
+
if (exports.outputConfig.plainMode)
|
|
129
|
+
return ` ${labelText} ${value}`;
|
|
130
|
+
const formattedLabel = exports.outputConfig.colorEnabled ? chalk_1.default.gray(labelText) : labelText;
|
|
131
|
+
const formattedValue = highlight && exports.outputConfig.colorEnabled
|
|
132
|
+
? chalk_1.default.cyan.bold(value)
|
|
133
|
+
: exports.outputConfig.colorEnabled
|
|
134
|
+
? chalk_1.default.white(value)
|
|
135
|
+
: value;
|
|
136
|
+
return ` ${formattedLabel} ${formattedValue}`;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Output structured data as formatted text
|
|
140
|
+
*/
|
|
141
|
+
function formatOutput(data) {
|
|
142
|
+
return Object.entries(data).map(([key, value]) => field(key, String(value)));
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Output JSON
|
|
146
|
+
*/
|
|
147
|
+
function outputJSON(data) {
|
|
148
|
+
console.log(JSON.stringify(data, null, 2));
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Detect if color should be enabled
|
|
152
|
+
*/
|
|
153
|
+
function detectColorSupport() {
|
|
154
|
+
// Support NO_COLOR environment variable
|
|
155
|
+
if (process.env.NO_COLOR !== undefined && process.env.NO_COLOR !== '') {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
// Support --no-color flag
|
|
159
|
+
if (process.argv.includes('--no-color')) {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
// Check if TTY supports color
|
|
163
|
+
if (!process.stdout.isTTY) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Apply global output configuration based on flags
|
|
170
|
+
*/
|
|
171
|
+
function applyOutputConfig(flags) {
|
|
172
|
+
if (flags.plain) {
|
|
173
|
+
exports.outputConfig.setPlainMode();
|
|
174
|
+
}
|
|
175
|
+
else if (flags.noColor) {
|
|
176
|
+
exports.outputConfig.setNoColor();
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
exports.outputConfig.colorEnabled = detectColorSupport();
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Password validation utility for Cognito requirements
|
|
4
|
+
* Based on AWS Cognito password policy requirements
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.validateCognitoPassword = validateCognitoPassword;
|
|
8
|
+
exports.generateSecurePassword = generateSecurePassword;
|
|
9
|
+
exports.validateEmail = validateEmail;
|
|
10
|
+
exports.isEmail = isEmail;
|
|
11
|
+
/**
|
|
12
|
+
* Validates password against Cognito password policy requirements
|
|
13
|
+
* @param password - Password to validate
|
|
14
|
+
* @returns PasswordValidationResult with validation status and errors
|
|
15
|
+
*/
|
|
16
|
+
function validateCognitoPassword(password) {
|
|
17
|
+
const errors = [];
|
|
18
|
+
// Minimum length requirement (8 characters)
|
|
19
|
+
if (password.length < 8) {
|
|
20
|
+
errors.push('Password must be at least 8 characters long');
|
|
21
|
+
}
|
|
22
|
+
// Maximum length requirement (128 characters)
|
|
23
|
+
if (password.length > 128) {
|
|
24
|
+
errors.push('Password must be no more than 128 characters long');
|
|
25
|
+
}
|
|
26
|
+
// Uppercase letter requirement
|
|
27
|
+
if (!/[A-Z]/.test(password)) {
|
|
28
|
+
errors.push('Password must contain at least one uppercase letter');
|
|
29
|
+
}
|
|
30
|
+
// Lowercase letter requirement
|
|
31
|
+
if (!/[a-z]/.test(password)) {
|
|
32
|
+
errors.push('Password must contain at least one lowercase letter');
|
|
33
|
+
}
|
|
34
|
+
// Number requirement
|
|
35
|
+
if (!/[0-9]/.test(password)) {
|
|
36
|
+
errors.push('Password must contain at least one number');
|
|
37
|
+
}
|
|
38
|
+
// Special character requirement
|
|
39
|
+
if (!/[!@#$%^&*()_+\-=\[\]{}|;:,.<>?]/.test(password)) {
|
|
40
|
+
errors.push('Password must contain at least one special character (!@#$%^&*()_+-=[]{}|;:,.<>?)');
|
|
41
|
+
}
|
|
42
|
+
// No spaces allowed
|
|
43
|
+
if (/\s/.test(password)) {
|
|
44
|
+
errors.push('Password cannot contain spaces');
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
isValid: errors.length === 0,
|
|
48
|
+
errors
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Generates a secure password that meets Cognito requirements
|
|
53
|
+
* @returns A secure password string
|
|
54
|
+
*/
|
|
55
|
+
function generateSecurePassword() {
|
|
56
|
+
const uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
57
|
+
const lowercase = 'abcdefghijklmnopqrstuvwxyz';
|
|
58
|
+
const numbers = '0123456789';
|
|
59
|
+
const symbols = '!@#$%^&*()_+-=[]{}|;:,.<>?';
|
|
60
|
+
// Ensure at least one character from each required category
|
|
61
|
+
let password = '';
|
|
62
|
+
password += uppercase[Math.floor(Math.random() * uppercase.length)];
|
|
63
|
+
password += lowercase[Math.floor(Math.random() * lowercase.length)];
|
|
64
|
+
password += numbers[Math.floor(Math.random() * numbers.length)];
|
|
65
|
+
password += symbols[Math.floor(Math.random() * symbols.length)];
|
|
66
|
+
// Fill the rest with random characters from all categories
|
|
67
|
+
const allChars = uppercase + lowercase + numbers + symbols;
|
|
68
|
+
for (let i = 4; i < 12; i++) { // Minimum 8 chars, we'll have 12
|
|
69
|
+
password += allChars[Math.floor(Math.random() * allChars.length)];
|
|
70
|
+
}
|
|
71
|
+
// Shuffle the password
|
|
72
|
+
return password.split('').sort(() => Math.random() - 0.5).join('');
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Validates email format
|
|
76
|
+
* @param email - Email to validate
|
|
77
|
+
* @returns boolean indicating if email is valid
|
|
78
|
+
*/
|
|
79
|
+
function validateEmail(email) {
|
|
80
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
81
|
+
return emailRegex.test(email);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Determines if input is an email or device ID
|
|
85
|
+
* @param input - Input to check
|
|
86
|
+
* @returns boolean indicating if input is an email
|
|
87
|
+
*/
|
|
88
|
+
function isEmail(input) {
|
|
89
|
+
return validateEmail(input);
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=passwordValidation.js.map
|
|
@@ -0,0 +1,167 @@
|
|
|
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.ProgressBar = exports.Spinner = void 0;
|
|
7
|
+
exports.spinner = spinner;
|
|
8
|
+
exports.progressBar = progressBar;
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const output_1 = require("./output");
|
|
11
|
+
/**
|
|
12
|
+
* Simple spinner implementation for progress indication
|
|
13
|
+
*/
|
|
14
|
+
class Spinner {
|
|
15
|
+
constructor(message) {
|
|
16
|
+
this.interval = null;
|
|
17
|
+
this.frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
18
|
+
this.currentFrame = 0;
|
|
19
|
+
this.message = message;
|
|
20
|
+
this.startTime = new Date();
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Start the spinner
|
|
24
|
+
*/
|
|
25
|
+
start() {
|
|
26
|
+
if (output_1.outputConfig.plainMode) {
|
|
27
|
+
console.log(this.message);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const writeMessage = () => {
|
|
31
|
+
const frame = output_1.outputConfig.colorEnabled
|
|
32
|
+
? chalk_1.default.cyan(this.frames[this.currentFrame])
|
|
33
|
+
: this.frames[this.currentFrame];
|
|
34
|
+
process.stdout.write(`\r${frame} ${this.message}`);
|
|
35
|
+
this.currentFrame = (this.currentFrame + 1) % this.frames.length;
|
|
36
|
+
};
|
|
37
|
+
writeMessage();
|
|
38
|
+
this.interval = setInterval(writeMessage, 80);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Update the spinner message
|
|
42
|
+
*/
|
|
43
|
+
update(message) {
|
|
44
|
+
this.message = message;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Stop the spinner with success message
|
|
48
|
+
*/
|
|
49
|
+
succeed(message) {
|
|
50
|
+
this.stop();
|
|
51
|
+
if (message) {
|
|
52
|
+
console.log(chalk_1.default.green(`✓ ${message}`));
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
console.log(chalk_1.default.green(`✓ ${this.message}`));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Stop the spinner with failure message
|
|
60
|
+
*/
|
|
61
|
+
fail(message) {
|
|
62
|
+
this.stop();
|
|
63
|
+
if (message) {
|
|
64
|
+
console.log(chalk_1.default.red(`✗ ${message}`));
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
console.log(chalk_1.default.red(`✗ ${this.message}`));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Stop the spinner with info message
|
|
72
|
+
*/
|
|
73
|
+
info(message) {
|
|
74
|
+
this.stop();
|
|
75
|
+
if (message) {
|
|
76
|
+
console.log(chalk_1.default.blue(`ℹ ${message}`));
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
console.log(chalk_1.default.blue(`ℹ ${this.message}`));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Stop the spinner without any message
|
|
84
|
+
*/
|
|
85
|
+
stop() {
|
|
86
|
+
if (this.interval) {
|
|
87
|
+
clearInterval(this.interval);
|
|
88
|
+
this.interval = null;
|
|
89
|
+
process.stdout.write('\r' + ' '.repeat(process.stdout.columns) + '\r');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get elapsed time in milliseconds
|
|
94
|
+
*/
|
|
95
|
+
elapsed() {
|
|
96
|
+
return Date.now() - this.startTime.getTime();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.Spinner = Spinner;
|
|
100
|
+
/**
|
|
101
|
+
* Create and start a new spinner
|
|
102
|
+
*/
|
|
103
|
+
function spinner(message) {
|
|
104
|
+
const spinnerInstance = new Spinner(message);
|
|
105
|
+
spinnerInstance.start();
|
|
106
|
+
return spinnerInstance;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Progress bar implementation
|
|
110
|
+
*/
|
|
111
|
+
class ProgressBar {
|
|
112
|
+
constructor(total, filled = 0, message = '') {
|
|
113
|
+
this.current = 0;
|
|
114
|
+
this.width = 40;
|
|
115
|
+
this.total = total;
|
|
116
|
+
this.current = filled;
|
|
117
|
+
this.message = message;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Update progress and render
|
|
121
|
+
*/
|
|
122
|
+
update(current) {
|
|
123
|
+
this.current = current;
|
|
124
|
+
this.render();
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Increment progress and render
|
|
128
|
+
*/
|
|
129
|
+
increment(amount = 1) {
|
|
130
|
+
this.current = Math.min(this.current + amount, this.total);
|
|
131
|
+
this.render();
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Render the progress bar
|
|
135
|
+
*/
|
|
136
|
+
render() {
|
|
137
|
+
const percentage = Math.min(100, (this.current / this.total) * 100);
|
|
138
|
+
const filled = Math.floor((this.current / this.total) * this.width);
|
|
139
|
+
const empty = this.width - filled;
|
|
140
|
+
const filledBar = '█'.repeat(filled);
|
|
141
|
+
const emptyBar = '░'.repeat(empty);
|
|
142
|
+
const bar = output_1.outputConfig.colorEnabled
|
|
143
|
+
? chalk_1.default.green(filledBar) + chalk_1.default.gray(emptyBar)
|
|
144
|
+
: filledBar + emptyBar;
|
|
145
|
+
const text = `${this.message} ${bar} ${percentage.toFixed(0)}% (${this.current}/${this.total})`;
|
|
146
|
+
process.stdout.write('\r' + text);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Complete the progress bar
|
|
150
|
+
*/
|
|
151
|
+
complete(message) {
|
|
152
|
+
this.current = this.total;
|
|
153
|
+
this.render();
|
|
154
|
+
console.log(''); // New line
|
|
155
|
+
if (message) {
|
|
156
|
+
console.log(message);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
exports.ProgressBar = ProgressBar;
|
|
161
|
+
/**
|
|
162
|
+
* Create a new progress bar
|
|
163
|
+
*/
|
|
164
|
+
function progressBar(total, message = '') {
|
|
165
|
+
return new ProgressBar(total, 0, message);
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Utility to check if the current process is running with elevated permissions (sudo/root)
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.checkSudoPermissions = checkSudoPermissions;
|
|
7
|
+
/**
|
|
8
|
+
* Check if the current process is running with elevated permissions
|
|
9
|
+
* @returns true if running as root/sudo, false otherwise
|
|
10
|
+
*/
|
|
11
|
+
function checkSudoPermissions() {
|
|
12
|
+
// On Unix-like systems, root user has UID 0
|
|
13
|
+
// On Windows, this will be undefined, so we return false
|
|
14
|
+
try {
|
|
15
|
+
const uid = process.getuid ? process.getuid() : undefined;
|
|
16
|
+
return uid === 0;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=sudo-checker.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* URL utilities for building stage-based URLs
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getStage = getStage;
|
|
7
|
+
exports.getDistributionUrl = getDistributionUrl;
|
|
8
|
+
exports.getApiBaseUrl = getApiBaseUrl;
|
|
9
|
+
/**
|
|
10
|
+
* Get the current stage from environment variables
|
|
11
|
+
* @returns Stage string (dev, staging, production, or default 'production')
|
|
12
|
+
*/
|
|
13
|
+
function getStage() {
|
|
14
|
+
return process.env['STAGE'] || process.env['SST_STAGE'] || 'prod';
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Build the agent distribution URL based on stage
|
|
18
|
+
* @returns Distribution URL (e.g., https://distribution.production.edgible.com)
|
|
19
|
+
*/
|
|
20
|
+
function getDistributionUrl() {
|
|
21
|
+
const stage = getStage();
|
|
22
|
+
return `https://distribution.${stage}.edgible.com`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Build the API base URL based on stage
|
|
26
|
+
* @returns API URL (e.g., https://api.v2.production.edgible.com)
|
|
27
|
+
*/
|
|
28
|
+
function getApiBaseUrl() {
|
|
29
|
+
const stage = getStage();
|
|
30
|
+
return `https://api.v2.${stage}.edgible.com`;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=urls.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateEmail = validateEmail;
|
|
4
|
+
exports.validateName = validateName;
|
|
5
|
+
exports.isEmail = isEmail;
|
|
6
|
+
/**
|
|
7
|
+
* Email validation utility
|
|
8
|
+
* @param email - Email address to validate
|
|
9
|
+
* @returns boolean indicating if email is valid
|
|
10
|
+
*/
|
|
11
|
+
function validateEmail(email) {
|
|
12
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
13
|
+
return emailRegex.test(email);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Name validation utility
|
|
17
|
+
* @param name - Name to validate
|
|
18
|
+
* @returns boolean indicating if name is valid
|
|
19
|
+
*/
|
|
20
|
+
function validateName(name) {
|
|
21
|
+
return name.trim().length >= 2;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Determines if input is an email or device ID
|
|
25
|
+
* @param input - Input to check
|
|
26
|
+
* @returns boolean indicating if input is an email
|
|
27
|
+
*/
|
|
28
|
+
function isEmail(input) {
|
|
29
|
+
return validateEmail(input);
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Validation schemas using Zod
|
|
4
|
+
* Provides runtime validation for all command inputs
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.gatewayLogsOptionsSchema = exports.createDeviceWithOrganizationRequestSchema = exports.deviceLoginRequestSchema = exports.loginRequestSchema = exports.createGatewayRequestSchema = exports.createApplicationRequestSchema = exports.urlSchema = exports.gatewayIdSchema = exports.applicationIdSchema = exports.deviceIdSchema = exports.awsProfileSchema = exports.awsInstanceTypeSchema = exports.awsRegionSchema = exports.gatewayNameSchema = exports.applicationNameSchema = exports.protocolSchema = exports.portSchema = exports.deviceNameSchema = exports.passwordSchema = exports.emailSchema = void 0;
|
|
8
|
+
exports.validate = validate;
|
|
9
|
+
exports.safeValidate = safeValidate;
|
|
10
|
+
exports.formatValidationError = formatValidationError;
|
|
11
|
+
const zod_1 = require("zod");
|
|
12
|
+
/**
|
|
13
|
+
* Email validation schema
|
|
14
|
+
*/
|
|
15
|
+
exports.emailSchema = zod_1.z.string().email('Invalid email address').toLowerCase().trim();
|
|
16
|
+
/**
|
|
17
|
+
* Password validation schema (Cognito requirements)
|
|
18
|
+
*/
|
|
19
|
+
exports.passwordSchema = zod_1.z
|
|
20
|
+
.string()
|
|
21
|
+
.min(8, 'Password must be at least 8 characters')
|
|
22
|
+
.max(128, 'Password must be at most 128 characters')
|
|
23
|
+
.regex(/[A-Z]/, 'Password must contain at least one uppercase letter')
|
|
24
|
+
.regex(/[a-z]/, 'Password must contain at least one lowercase letter')
|
|
25
|
+
.regex(/[0-9]/, 'Password must contain at least one number')
|
|
26
|
+
.regex(/[^A-Za-z0-9]/, 'Password must contain at least one special character');
|
|
27
|
+
/**
|
|
28
|
+
* Device name schema
|
|
29
|
+
*/
|
|
30
|
+
exports.deviceNameSchema = zod_1.z
|
|
31
|
+
.string()
|
|
32
|
+
.min(1, 'Device name is required')
|
|
33
|
+
.max(100, 'Device name must be at most 100 characters')
|
|
34
|
+
.regex(/^[a-zA-Z0-9-_]+$/, 'Device name can only contain letters, numbers, hyphens, and underscores');
|
|
35
|
+
/**
|
|
36
|
+
* Port number schema
|
|
37
|
+
*/
|
|
38
|
+
exports.portSchema = zod_1.z
|
|
39
|
+
.number()
|
|
40
|
+
.int('Port must be an integer')
|
|
41
|
+
.min(1, 'Port must be between 1 and 65535')
|
|
42
|
+
.max(65535, 'Port must be between 1 and 65535');
|
|
43
|
+
/**
|
|
44
|
+
* Protocol schema
|
|
45
|
+
*/
|
|
46
|
+
exports.protocolSchema = zod_1.z.enum(['http', 'https', 'tcp', 'udp'], {
|
|
47
|
+
errorMap: () => ({ message: 'Protocol must be one of: http, https, tcp, udp' }),
|
|
48
|
+
});
|
|
49
|
+
/**
|
|
50
|
+
* Application name schema
|
|
51
|
+
*/
|
|
52
|
+
exports.applicationNameSchema = zod_1.z
|
|
53
|
+
.string()
|
|
54
|
+
.min(1, 'Application name is required')
|
|
55
|
+
.max(100, 'Application name must be at most 100 characters')
|
|
56
|
+
.regex(/^[a-zA-Z0-9-_]+$/, 'Application name can only contain letters, numbers, hyphens, and underscores');
|
|
57
|
+
/**
|
|
58
|
+
* Gateway name schema
|
|
59
|
+
*/
|
|
60
|
+
exports.gatewayNameSchema = zod_1.z
|
|
61
|
+
.string()
|
|
62
|
+
.min(1, 'Gateway name is required')
|
|
63
|
+
.max(100, 'Gateway name must be at most 100 characters');
|
|
64
|
+
/**
|
|
65
|
+
* AWS region schema
|
|
66
|
+
*/
|
|
67
|
+
exports.awsRegionSchema = zod_1.z.string().regex(/^[a-z0-9-]+$/, 'Invalid AWS region format');
|
|
68
|
+
/**
|
|
69
|
+
* AWS instance type schema
|
|
70
|
+
*/
|
|
71
|
+
exports.awsInstanceTypeSchema = zod_1.z.string().regex(/^[a-z0-9.]+$/, 'Invalid AWS instance type format');
|
|
72
|
+
/**
|
|
73
|
+
* AWS profile schema
|
|
74
|
+
*/
|
|
75
|
+
exports.awsProfileSchema = zod_1.z.string().min(1, 'AWS profile is required');
|
|
76
|
+
/**
|
|
77
|
+
* Device ID schema (UUID format)
|
|
78
|
+
*/
|
|
79
|
+
exports.deviceIdSchema = zod_1.z.string().uuid('Device ID must be a valid UUID');
|
|
80
|
+
/**
|
|
81
|
+
* Application ID schema (UUID format)
|
|
82
|
+
*/
|
|
83
|
+
exports.applicationIdSchema = zod_1.z.string().uuid('Application ID must be a valid UUID');
|
|
84
|
+
/**
|
|
85
|
+
* Gateway ID schema (UUID format)
|
|
86
|
+
*/
|
|
87
|
+
exports.gatewayIdSchema = zod_1.z.string().uuid('Gateway ID must be a valid UUID');
|
|
88
|
+
/**
|
|
89
|
+
* URL schema
|
|
90
|
+
*/
|
|
91
|
+
exports.urlSchema = zod_1.z.string().url('Invalid URL format');
|
|
92
|
+
/**
|
|
93
|
+
* Create application request schema
|
|
94
|
+
*/
|
|
95
|
+
exports.createApplicationRequestSchema = zod_1.z.object({
|
|
96
|
+
name: exports.applicationNameSchema,
|
|
97
|
+
description: zod_1.z.string().max(500, 'Description must be at most 500 characters').optional(),
|
|
98
|
+
port: exports.portSchema,
|
|
99
|
+
protocol: exports.protocolSchema,
|
|
100
|
+
deviceId: exports.deviceIdSchema,
|
|
101
|
+
gatewayIds: zod_1.z.array(exports.gatewayIdSchema).optional(),
|
|
102
|
+
subtype: zod_1.z.enum(['local-preexisting', 'managed-docker', 'systemd', 'docker-compose']),
|
|
103
|
+
});
|
|
104
|
+
/**
|
|
105
|
+
* Create gateway request schema
|
|
106
|
+
*/
|
|
107
|
+
exports.createGatewayRequestSchema = zod_1.z.object({
|
|
108
|
+
name: exports.gatewayNameSchema,
|
|
109
|
+
description: zod_1.z.string().max(500, 'Description must be at most 500 characters').optional(),
|
|
110
|
+
awsProfile: exports.awsProfileSchema.optional(),
|
|
111
|
+
region: exports.awsRegionSchema.optional(),
|
|
112
|
+
instanceType: exports.awsInstanceTypeSchema.optional(),
|
|
113
|
+
});
|
|
114
|
+
/**
|
|
115
|
+
* Login request schema
|
|
116
|
+
*/
|
|
117
|
+
exports.loginRequestSchema = zod_1.z.object({
|
|
118
|
+
email: exports.emailSchema,
|
|
119
|
+
password: zod_1.z.string().min(1, 'Password is required'),
|
|
120
|
+
});
|
|
121
|
+
/**
|
|
122
|
+
* Device login request schema
|
|
123
|
+
*/
|
|
124
|
+
exports.deviceLoginRequestSchema = zod_1.z.object({
|
|
125
|
+
deviceId: exports.deviceIdSchema,
|
|
126
|
+
password: zod_1.z.string().min(1, 'Password is required'),
|
|
127
|
+
});
|
|
128
|
+
/**
|
|
129
|
+
* Create device with organization request schema
|
|
130
|
+
*/
|
|
131
|
+
exports.createDeviceWithOrganizationRequestSchema = zod_1.z.object({
|
|
132
|
+
deviceName: exports.deviceNameSchema,
|
|
133
|
+
password: exports.passwordSchema,
|
|
134
|
+
userEmail: exports.emailSchema.optional(),
|
|
135
|
+
deviceType: zod_1.z.enum(['serving', 'gateway']).optional(),
|
|
136
|
+
});
|
|
137
|
+
/**
|
|
138
|
+
* Gateway logs options schema
|
|
139
|
+
*/
|
|
140
|
+
exports.gatewayLogsOptionsSchema = zod_1.z.object({
|
|
141
|
+
gatewayId: exports.gatewayIdSchema.optional(),
|
|
142
|
+
lines: zod_1.z.number().int().min(1).max(10000).optional(),
|
|
143
|
+
follow: zod_1.z.boolean().optional(),
|
|
144
|
+
level: zod_1.z.enum(['error', 'warn', 'info', 'debug', 'all']).optional(),
|
|
145
|
+
comprehensive: zod_1.z.boolean().optional(),
|
|
146
|
+
});
|
|
147
|
+
/**
|
|
148
|
+
* Validate and parse data with schema
|
|
149
|
+
*/
|
|
150
|
+
function validate(schema, data) {
|
|
151
|
+
return schema.parse(data);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Safe validate - returns result instead of throwing
|
|
155
|
+
*/
|
|
156
|
+
function safeValidate(schema, data) {
|
|
157
|
+
const result = schema.safeParse(data);
|
|
158
|
+
if (result.success) {
|
|
159
|
+
return { success: true, data: result.data };
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
return { success: false, error: result.error };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Format Zod error for user display
|
|
167
|
+
*/
|
|
168
|
+
function formatValidationError(error) {
|
|
169
|
+
const issues = error.issues.map((issue) => {
|
|
170
|
+
const path = issue.path.length > 0 ? issue.path.join('.') : 'root';
|
|
171
|
+
return `${path}: ${issue.message}`;
|
|
172
|
+
});
|
|
173
|
+
return issues.join(', ');
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=schemas.js.map
|