@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.
Files changed (102) hide show
  1. package/LICENSE +136 -0
  2. package/README.md +450 -0
  3. package/dist/client/api-client.js +1057 -0
  4. package/dist/client/index.js +21 -0
  5. package/dist/commands/agent.js +1280 -0
  6. package/dist/commands/ai.js +608 -0
  7. package/dist/commands/application.js +885 -0
  8. package/dist/commands/auth.js +570 -0
  9. package/dist/commands/base/BaseCommand.js +93 -0
  10. package/dist/commands/base/CommandHandler.js +7 -0
  11. package/dist/commands/base/command-wrapper.js +58 -0
  12. package/dist/commands/base/middleware.js +77 -0
  13. package/dist/commands/config.js +116 -0
  14. package/dist/commands/connectivity.js +59 -0
  15. package/dist/commands/debug.js +98 -0
  16. package/dist/commands/discover.js +144 -0
  17. package/dist/commands/examples/migrated-command-example.js +180 -0
  18. package/dist/commands/gateway.js +494 -0
  19. package/dist/commands/managedGateway.js +787 -0
  20. package/dist/commands/utils/config-validator.js +76 -0
  21. package/dist/commands/utils/gateway-prompt.js +79 -0
  22. package/dist/commands/utils/input-parser.js +120 -0
  23. package/dist/commands/utils/output-formatter.js +109 -0
  24. package/dist/config/app-config.js +99 -0
  25. package/dist/detection/SystemCapabilityDetector.js +1244 -0
  26. package/dist/detection/ToolDetector.js +305 -0
  27. package/dist/detection/WorkloadDetector.js +314 -0
  28. package/dist/di/bindings.js +99 -0
  29. package/dist/di/container.js +88 -0
  30. package/dist/di/types.js +32 -0
  31. package/dist/index.js +52 -0
  32. package/dist/interfaces/IDaemonManager.js +3 -0
  33. package/dist/repositories/config-repository.js +62 -0
  34. package/dist/repositories/gateway-repository.js +35 -0
  35. package/dist/scripts/postinstall.js +101 -0
  36. package/dist/services/AgentStatusManager.js +299 -0
  37. package/dist/services/ConnectivityTester.js +271 -0
  38. package/dist/services/DependencyInstaller.js +475 -0
  39. package/dist/services/LocalAgentManager.js +2216 -0
  40. package/dist/services/application/ApplicationService.js +299 -0
  41. package/dist/services/auth/AuthService.js +214 -0
  42. package/dist/services/aws.js +644 -0
  43. package/dist/services/daemon/DaemonManagerFactory.js +65 -0
  44. package/dist/services/daemon/DockerDaemonManager.js +395 -0
  45. package/dist/services/daemon/LaunchdDaemonManager.js +257 -0
  46. package/dist/services/daemon/PodmanDaemonManager.js +369 -0
  47. package/dist/services/daemon/SystemdDaemonManager.js +221 -0
  48. package/dist/services/daemon/WindowsServiceDaemonManager.js +210 -0
  49. package/dist/services/daemon/index.js +16 -0
  50. package/dist/services/edgible.js +3060 -0
  51. package/dist/services/gateway/GatewayService.js +334 -0
  52. package/dist/state/config.js +146 -0
  53. package/dist/types/AgentConfig.js +5 -0
  54. package/dist/types/AgentStatus.js +5 -0
  55. package/dist/types/ApiClient.js +5 -0
  56. package/dist/types/ApiRequests.js +5 -0
  57. package/dist/types/ApiResponses.js +5 -0
  58. package/dist/types/Application.js +5 -0
  59. package/dist/types/CaddyJson.js +5 -0
  60. package/dist/types/UnifiedAgentStatus.js +56 -0
  61. package/dist/types/WireGuard.js +5 -0
  62. package/dist/types/Workload.js +5 -0
  63. package/dist/types/agent.js +5 -0
  64. package/dist/types/command-options.js +5 -0
  65. package/dist/types/connectivity.js +5 -0
  66. package/dist/types/errors.js +250 -0
  67. package/dist/types/gateway-types.js +5 -0
  68. package/dist/types/index.js +48 -0
  69. package/dist/types/models/ApplicationData.js +5 -0
  70. package/dist/types/models/CertificateData.js +5 -0
  71. package/dist/types/models/DeviceData.js +5 -0
  72. package/dist/types/models/DevicePoolData.js +5 -0
  73. package/dist/types/models/OrganizationData.js +5 -0
  74. package/dist/types/models/OrganizationInviteData.js +5 -0
  75. package/dist/types/models/ProviderConfiguration.js +5 -0
  76. package/dist/types/models/ResourceData.js +5 -0
  77. package/dist/types/models/ServiceResourceData.js +5 -0
  78. package/dist/types/models/UserData.js +5 -0
  79. package/dist/types/route.js +5 -0
  80. package/dist/types/validation/schemas.js +218 -0
  81. package/dist/types/validation.js +5 -0
  82. package/dist/utils/FileIntegrityManager.js +256 -0
  83. package/dist/utils/PathMigration.js +219 -0
  84. package/dist/utils/PathResolver.js +235 -0
  85. package/dist/utils/PlatformDetector.js +277 -0
  86. package/dist/utils/console-logger.js +130 -0
  87. package/dist/utils/docker-compose-parser.js +179 -0
  88. package/dist/utils/errors.js +130 -0
  89. package/dist/utils/health-checker.js +155 -0
  90. package/dist/utils/json-logger.js +72 -0
  91. package/dist/utils/log-formatter.js +293 -0
  92. package/dist/utils/logger.js +59 -0
  93. package/dist/utils/network-utils.js +217 -0
  94. package/dist/utils/output.js +182 -0
  95. package/dist/utils/passwordValidation.js +91 -0
  96. package/dist/utils/progress.js +167 -0
  97. package/dist/utils/sudo-checker.js +22 -0
  98. package/dist/utils/urls.js +32 -0
  99. package/dist/utils/validation.js +31 -0
  100. package/dist/validation/schemas.js +175 -0
  101. package/dist/validation/validator.js +67 -0
  102. 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