@testingbot/cli 1.0.1 → 1.0.2
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 +3 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +55 -8
- package/dist/models/espresso_options.d.ts +9 -0
- package/dist/models/espresso_options.d.ts.map +1 -1
- package/dist/models/espresso_options.js +14 -0
- package/dist/models/maestro_options.d.ts +19 -7
- package/dist/models/maestro_options.d.ts.map +1 -1
- package/dist/models/maestro_options.js +17 -8
- package/dist/models/testingbot_error.d.ts +3 -0
- package/dist/models/testingbot_error.d.ts.map +1 -1
- package/dist/models/testingbot_error.js +5 -0
- package/dist/models/xcuitest_options.d.ts +9 -0
- package/dist/models/xcuitest_options.d.ts.map +1 -1
- package/dist/models/xcuitest_options.js +14 -0
- package/dist/providers/base_provider.d.ts +119 -0
- package/dist/providers/base_provider.d.ts.map +1 -0
- package/dist/providers/base_provider.js +296 -0
- package/dist/providers/espresso.d.ts +14 -21
- package/dist/providers/espresso.d.ts.map +1 -1
- package/dist/providers/espresso.js +39 -168
- package/dist/providers/login.d.ts +1 -0
- package/dist/providers/login.d.ts.map +1 -1
- package/dist/providers/login.js +16 -7
- package/dist/providers/maestro.d.ts +53 -21
- package/dist/providers/maestro.d.ts.map +1 -1
- package/dist/providers/maestro.js +614 -263
- package/dist/providers/xcuitest.d.ts +14 -21
- package/dist/providers/xcuitest.d.ts.map +1 -1
- package/dist/providers/xcuitest.js +39 -168
- package/dist/upload.d.ts +10 -0
- package/dist/upload.d.ts.map +1 -1
- package/dist/upload.js +46 -21
- package/dist/utils/connectivity.d.ts +25 -0
- package/dist/utils/connectivity.d.ts.map +1 -0
- package/dist/utils/connectivity.js +118 -0
- package/dist/utils/error-helpers.d.ts +26 -0
- package/dist/utils/error-helpers.d.ts.map +1 -0
- package/dist/utils/error-helpers.js +237 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +7 -2
- package/package.json +1 -1
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Utility for checking internet connectivity using third-party endpoints
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.checkInternetConnectivity = checkInternetConnectivity;
|
|
7
|
+
exports.formatConnectivityResults = formatConnectivityResults;
|
|
8
|
+
/**
|
|
9
|
+
* Check if the system has internet connectivity by testing against
|
|
10
|
+
* multiple reliable third-party endpoints with detailed diagnostics.
|
|
11
|
+
*/
|
|
12
|
+
async function checkInternetConnectivity() {
|
|
13
|
+
const testEndpoints = [
|
|
14
|
+
{ url: 'https://www.google.com/generate_204', description: 'Google' },
|
|
15
|
+
{
|
|
16
|
+
url: 'https://www.cloudflare.com/cdn-cgi/trace',
|
|
17
|
+
description: 'Cloudflare',
|
|
18
|
+
},
|
|
19
|
+
{ url: 'https://1.1.1.1/', description: 'Cloudflare DNS' },
|
|
20
|
+
];
|
|
21
|
+
const endpointResults = [];
|
|
22
|
+
let anySuccess = false;
|
|
23
|
+
for (const { url, description } of testEndpoints) {
|
|
24
|
+
const startTime = Date.now();
|
|
25
|
+
try {
|
|
26
|
+
const controller = new AbortController();
|
|
27
|
+
const timeoutId = setTimeout(() => controller.abort(), 3000);
|
|
28
|
+
const response = await fetch(url, {
|
|
29
|
+
method: 'HEAD',
|
|
30
|
+
signal: controller.signal,
|
|
31
|
+
redirect: 'manual',
|
|
32
|
+
});
|
|
33
|
+
clearTimeout(timeoutId);
|
|
34
|
+
const latencyMs = Date.now() - startTime;
|
|
35
|
+
if (response) {
|
|
36
|
+
anySuccess = true;
|
|
37
|
+
endpointResults.push({
|
|
38
|
+
endpoint: `${description} (${url})`,
|
|
39
|
+
success: true,
|
|
40
|
+
statusCode: response.status,
|
|
41
|
+
latencyMs,
|
|
42
|
+
});
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
const latencyMs = Date.now() - startTime;
|
|
48
|
+
let errorMessage = 'Unknown error';
|
|
49
|
+
if (error instanceof Error) {
|
|
50
|
+
if (error.name === 'AbortError') {
|
|
51
|
+
errorMessage = 'Request timeout (>3s)';
|
|
52
|
+
}
|
|
53
|
+
else if (error.message.includes('fetch failed')) {
|
|
54
|
+
errorMessage = 'Network request failed (DNS/connection error)';
|
|
55
|
+
}
|
|
56
|
+
else if (error.message.includes('ENOTFOUND')) {
|
|
57
|
+
errorMessage = 'DNS resolution failed';
|
|
58
|
+
}
|
|
59
|
+
else if (error.message.includes('ECONNREFUSED')) {
|
|
60
|
+
errorMessage = 'Connection refused';
|
|
61
|
+
}
|
|
62
|
+
else if (error.message.includes('ETIMEDOUT')) {
|
|
63
|
+
errorMessage = 'Connection timeout';
|
|
64
|
+
}
|
|
65
|
+
else if (error.message.includes('ENETUNREACH')) {
|
|
66
|
+
errorMessage = 'Network unreachable';
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
errorMessage = error.message;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
endpointResults.push({
|
|
73
|
+
endpoint: `${description} (${url})`,
|
|
74
|
+
success: false,
|
|
75
|
+
error: errorMessage,
|
|
76
|
+
latencyMs,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
let message;
|
|
81
|
+
if (anySuccess) {
|
|
82
|
+
const successfulEndpoint = endpointResults.find((r) => r.success);
|
|
83
|
+
message = `Internet connectivity verified via ${successfulEndpoint?.endpoint} (${successfulEndpoint?.latencyMs}ms)`;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
const testedEndpoints = endpointResults.map((r) => r.endpoint).join(', ');
|
|
87
|
+
message = `No internet connectivity detected. Tested endpoints: ${testedEndpoints}`;
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
connected: anySuccess,
|
|
91
|
+
endpointResults,
|
|
92
|
+
message,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Format connectivity check results for display
|
|
97
|
+
*/
|
|
98
|
+
function formatConnectivityResults(result) {
|
|
99
|
+
const lines = [];
|
|
100
|
+
if (result.connected) {
|
|
101
|
+
lines.push(`✓ ${result.message}`);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
lines.push(`✗ ${result.message}`);
|
|
105
|
+
lines.push('');
|
|
106
|
+
lines.push('Endpoint results:');
|
|
107
|
+
for (const endpoint of result.endpointResults) {
|
|
108
|
+
lines.push(` • ${endpoint.endpoint}: ${endpoint.error} (${endpoint.latencyMs}ms)`);
|
|
109
|
+
}
|
|
110
|
+
lines.push('');
|
|
111
|
+
lines.push('Troubleshooting steps:');
|
|
112
|
+
lines.push(' 1. Check your internet connection');
|
|
113
|
+
lines.push(' 2. Verify no firewall is blocking outbound connections');
|
|
114
|
+
lines.push(' 3. Check if a VPN or proxy is interfering');
|
|
115
|
+
lines.push(' 4. Try: ping google.com');
|
|
116
|
+
}
|
|
117
|
+
return lines.join('\n');
|
|
118
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error enhancement utilities for better diagnostics
|
|
3
|
+
*/
|
|
4
|
+
import { AxiosError } from 'axios';
|
|
5
|
+
import TestingBotError from '../models/testingbot_error';
|
|
6
|
+
/**
|
|
7
|
+
* Enhances generic network errors with more specific diagnostic information
|
|
8
|
+
*/
|
|
9
|
+
export declare function enhanceNetworkError(error: Error, url: string): TestingBotError;
|
|
10
|
+
/**
|
|
11
|
+
* Get a user-friendly error message for an HTTP status code
|
|
12
|
+
*/
|
|
13
|
+
export declare function getStatusCodeMessage(statusCode: number, serverMessage?: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Handle Axios errors with enhanced diagnostics
|
|
16
|
+
*/
|
|
17
|
+
export declare function handleAxiosError(error: AxiosError, operation: string): TestingBotError;
|
|
18
|
+
/**
|
|
19
|
+
* Check if an error is a network-level error (vs HTTP error)
|
|
20
|
+
*/
|
|
21
|
+
export declare function isNetworkError(error: AxiosError): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Check if error is retryable
|
|
24
|
+
*/
|
|
25
|
+
export declare function isRetryableError(error: AxiosError): boolean;
|
|
26
|
+
//# sourceMappingURL=error-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-helpers.d.ts","sourceRoot":"","sources":["../../src/utils/error-helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,eAAe,MAAM,4BAA4B,CAAC;AAEzD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,MAAM,GACV,eAAe,CAkCjB;AAoFD;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,MAAM,GACrB,MAAM,CAwBR;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,MAAM,GAChB,eAAe,CA8DjB;AA6BD;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAW3D"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Error enhancement utilities for better diagnostics
|
|
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.enhanceNetworkError = enhanceNetworkError;
|
|
10
|
+
exports.getStatusCodeMessage = getStatusCodeMessage;
|
|
11
|
+
exports.handleAxiosError = handleAxiosError;
|
|
12
|
+
exports.isNetworkError = isNetworkError;
|
|
13
|
+
exports.isRetryableError = isRetryableError;
|
|
14
|
+
const testingbot_error_1 = __importDefault(require("../models/testingbot_error"));
|
|
15
|
+
/**
|
|
16
|
+
* Enhances generic network errors with more specific diagnostic information
|
|
17
|
+
*/
|
|
18
|
+
function enhanceNetworkError(error, url) {
|
|
19
|
+
let hostname;
|
|
20
|
+
let origin;
|
|
21
|
+
try {
|
|
22
|
+
const urlObj = new URL(url);
|
|
23
|
+
hostname = urlObj.hostname;
|
|
24
|
+
origin = urlObj.origin;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
hostname = url;
|
|
28
|
+
origin = url;
|
|
29
|
+
}
|
|
30
|
+
const lines = [
|
|
31
|
+
`Network request failed: ${url}`,
|
|
32
|
+
'',
|
|
33
|
+
'Possible causes:',
|
|
34
|
+
` 1. No internet connection - check your network connectivity`,
|
|
35
|
+
` 2. DNS resolution failed - unable to resolve "${hostname}"`,
|
|
36
|
+
` 3. Firewall or proxy blocking the request`,
|
|
37
|
+
` 4. API server is down or unreachable`,
|
|
38
|
+
` 5. SSL/TLS certificate validation failed`,
|
|
39
|
+
'',
|
|
40
|
+
'Troubleshooting steps:',
|
|
41
|
+
` • Check internet connection: ping google.com`,
|
|
42
|
+
` • Test API reachability: curl ${origin}`,
|
|
43
|
+
` • Verify API URL is correct: ${origin}`,
|
|
44
|
+
` • Check for proxy/VPN interference`,
|
|
45
|
+
` • Try again in a few moments if server is temporarily down`,
|
|
46
|
+
'',
|
|
47
|
+
`Original error: ${error.message}`,
|
|
48
|
+
];
|
|
49
|
+
return new testingbot_error_1.default(lines.join('\n'), { cause: error });
|
|
50
|
+
}
|
|
51
|
+
const STATUS_CODE_MESSAGES = {
|
|
52
|
+
400: {
|
|
53
|
+
message: 'Invalid request',
|
|
54
|
+
troubleshooting: [
|
|
55
|
+
'Check that all required parameters are provided',
|
|
56
|
+
'Verify the file format is correct (APK for Android, IPA/ZIP for iOS)',
|
|
57
|
+
'Ensure the request payload is valid',
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
401: {
|
|
61
|
+
message: 'Invalid TestingBot credentials. Please check your API key and secret',
|
|
62
|
+
troubleshooting: [
|
|
63
|
+
'Run "testingbot login" to authenticate via browser',
|
|
64
|
+
'Use --api-key and --api-secret command line options',
|
|
65
|
+
'Set TB_KEY and TB_SECRET environment variables',
|
|
66
|
+
'Create ~/.testingbot file with content: key:secret',
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
403: {
|
|
70
|
+
message: 'Access denied',
|
|
71
|
+
troubleshooting: [
|
|
72
|
+
'Check your account has the required permissions',
|
|
73
|
+
'Verify your subscription plan includes this feature',
|
|
74
|
+
'Contact support if you believe this is an error',
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
404: {
|
|
78
|
+
message: 'Resource not found',
|
|
79
|
+
troubleshooting: [
|
|
80
|
+
'Verify the resource ID or path is correct',
|
|
81
|
+
'Check if the resource was deleted or expired',
|
|
82
|
+
],
|
|
83
|
+
},
|
|
84
|
+
429: {
|
|
85
|
+
message: 'Your TestingBot credits are depleted',
|
|
86
|
+
troubleshooting: [
|
|
87
|
+
'Check your remaining credits at https://testingbot.com/members',
|
|
88
|
+
'Upgrade your plan at https://testingbot.com/pricing',
|
|
89
|
+
'Contact support if you believe this is an error',
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
500: {
|
|
93
|
+
message: 'Server error occurred',
|
|
94
|
+
troubleshooting: [
|
|
95
|
+
'This is a temporary issue on our end',
|
|
96
|
+
'Please try again in a few moments',
|
|
97
|
+
'Contact support if the issue persists',
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
502: {
|
|
101
|
+
message: 'Bad gateway - service temporarily unavailable',
|
|
102
|
+
troubleshooting: [
|
|
103
|
+
'The service is experiencing issues',
|
|
104
|
+
'Please try again in a few moments',
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
503: {
|
|
108
|
+
message: 'Service temporarily unavailable',
|
|
109
|
+
troubleshooting: [
|
|
110
|
+
'The service is under maintenance or overloaded',
|
|
111
|
+
'Please try again in a few moments',
|
|
112
|
+
],
|
|
113
|
+
},
|
|
114
|
+
504: {
|
|
115
|
+
message: 'Gateway timeout',
|
|
116
|
+
troubleshooting: [
|
|
117
|
+
'The request took too long to process',
|
|
118
|
+
'Try with a smaller file or simpler request',
|
|
119
|
+
'Check your network connection speed',
|
|
120
|
+
],
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Get a user-friendly error message for an HTTP status code
|
|
125
|
+
*/
|
|
126
|
+
function getStatusCodeMessage(statusCode, serverMessage) {
|
|
127
|
+
const config = STATUS_CODE_MESSAGES[statusCode];
|
|
128
|
+
if (!config) {
|
|
129
|
+
return serverMessage
|
|
130
|
+
? `Request failed (HTTP ${statusCode}): ${serverMessage}`
|
|
131
|
+
: `Request failed with HTTP status ${statusCode}`;
|
|
132
|
+
}
|
|
133
|
+
const lines = [config.message];
|
|
134
|
+
if (serverMessage) {
|
|
135
|
+
lines.push(`Details: ${serverMessage}`);
|
|
136
|
+
}
|
|
137
|
+
if (config.troubleshooting && config.troubleshooting.length > 0) {
|
|
138
|
+
lines.push('');
|
|
139
|
+
lines.push('Troubleshooting:');
|
|
140
|
+
for (const step of config.troubleshooting) {
|
|
141
|
+
lines.push(` • ${step}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return lines.join('\n');
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Handle Axios errors with enhanced diagnostics
|
|
148
|
+
*/
|
|
149
|
+
function handleAxiosError(error, operation) {
|
|
150
|
+
// Network-level errors (no response)
|
|
151
|
+
if (!error.response) {
|
|
152
|
+
if (error.code === 'ECONNREFUSED') {
|
|
153
|
+
return new testingbot_error_1.default(`${operation}: Connection refused. The server may be down or unreachable.\n\n` +
|
|
154
|
+
'Troubleshooting:\n' +
|
|
155
|
+
' • Check if the API server is running\n' +
|
|
156
|
+
' • Verify the API URL is correct\n' +
|
|
157
|
+
' • Check for firewall or proxy issues', { cause: error });
|
|
158
|
+
}
|
|
159
|
+
if (error.code === 'ENOTFOUND') {
|
|
160
|
+
return new testingbot_error_1.default(`${operation}: DNS resolution failed. Could not resolve the server hostname.\n\n` +
|
|
161
|
+
'Troubleshooting:\n' +
|
|
162
|
+
' • Check your internet connection\n' +
|
|
163
|
+
' • Verify the API URL is correct\n' +
|
|
164
|
+
' • Try: ping api.testingbot.com', { cause: error });
|
|
165
|
+
}
|
|
166
|
+
if (error.code === 'ETIMEDOUT' || error.code === 'ECONNABORTED') {
|
|
167
|
+
return new testingbot_error_1.default(`${operation}: Connection timed out. The request took too long to complete.\n\n` +
|
|
168
|
+
'Troubleshooting:\n' +
|
|
169
|
+
' • Check your internet connection speed\n' +
|
|
170
|
+
' • Try again - the server may be temporarily slow\n' +
|
|
171
|
+
' • For large files, ensure stable connection', { cause: error });
|
|
172
|
+
}
|
|
173
|
+
if (error.code === 'CERT_HAS_EXPIRED' ||
|
|
174
|
+
error.code === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE') {
|
|
175
|
+
return new testingbot_error_1.default(`${operation}: SSL/TLS certificate error.\n\n` +
|
|
176
|
+
'Troubleshooting:\n' +
|
|
177
|
+
' • Check your system date and time are correct\n' +
|
|
178
|
+
' • Update your CA certificates\n' +
|
|
179
|
+
' • Check for proxy/VPN interference', { cause: error });
|
|
180
|
+
}
|
|
181
|
+
// Generic network error
|
|
182
|
+
return enhanceNetworkError(error, error.config?.url || 'unknown URL');
|
|
183
|
+
}
|
|
184
|
+
// HTTP errors (have response)
|
|
185
|
+
const statusCode = error.response.status;
|
|
186
|
+
const serverMessage = extractServerMessage(error.response.data);
|
|
187
|
+
return new testingbot_error_1.default(`${operation}: ${getStatusCodeMessage(statusCode, serverMessage)}`, { cause: error });
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Extract error message from various server response formats
|
|
191
|
+
*/
|
|
192
|
+
function extractServerMessage(data) {
|
|
193
|
+
if (!data)
|
|
194
|
+
return undefined;
|
|
195
|
+
if (typeof data === 'string') {
|
|
196
|
+
// Try to parse as JSON
|
|
197
|
+
try {
|
|
198
|
+
const parsed = JSON.parse(data);
|
|
199
|
+
return parsed.message || parsed.error || data;
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
return data;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (typeof data === 'object') {
|
|
206
|
+
const obj = data;
|
|
207
|
+
if (typeof obj.message === 'string')
|
|
208
|
+
return obj.message;
|
|
209
|
+
if (typeof obj.error === 'string')
|
|
210
|
+
return obj.error;
|
|
211
|
+
if (typeof obj.errors === 'string')
|
|
212
|
+
return obj.errors;
|
|
213
|
+
if (Array.isArray(obj.errors))
|
|
214
|
+
return obj.errors.join(', ');
|
|
215
|
+
}
|
|
216
|
+
return undefined;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Check if an error is a network-level error (vs HTTP error)
|
|
220
|
+
*/
|
|
221
|
+
function isNetworkError(error) {
|
|
222
|
+
return !error.response && !!error.code;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Check if error is retryable
|
|
226
|
+
*/
|
|
227
|
+
function isRetryableError(error) {
|
|
228
|
+
// Network errors are usually retryable
|
|
229
|
+
if (isNetworkError(error)) {
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
232
|
+
// Some HTTP errors are retryable
|
|
233
|
+
const retryableStatusCodes = [408, 429, 500, 502, 503, 504];
|
|
234
|
+
return error.response
|
|
235
|
+
? retryableStatusCodes.includes(error.response.status)
|
|
236
|
+
: false;
|
|
237
|
+
}
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";oBAOkB,MAAM;yBAID,MAAM;IAI3B;;;OAGG;wBACiB,MAAM,MAAM,MAAM,GAAG,MAAM;IAa/C;;OAEG;kCAC2B,MAAM,GAAG,SAAS,GAAG,IAAI;;AA7BzD,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";oBAOkB,MAAM;yBAID,MAAM;IAI3B;;;OAGG;wBACiB,MAAM,MAAM,MAAM,GAAG,MAAM;IAa/C;;OAEG;kCAC2B,MAAM,GAAG,SAAS,GAAG,IAAI;;AA7BzD,wBAuDE"}
|
package/dist/utils.js
CHANGED
|
@@ -41,8 +41,13 @@ exports.default = {
|
|
|
41
41
|
const currentVersion = this.getCurrentVersion();
|
|
42
42
|
if (this.compareVersions(currentVersion, latestVersion) < 0) {
|
|
43
43
|
versionCheckDisplayed = true;
|
|
44
|
-
|
|
45
|
-
logger_1.default.
|
|
44
|
+
const border = '─'.repeat(80);
|
|
45
|
+
logger_1.default.info(`\nCLI Version: ${colors_1.default.cyan(currentVersion)}\n`);
|
|
46
|
+
logger_1.default.warn(colors_1.default.yellow(border));
|
|
47
|
+
logger_1.default.warn(colors_1.default.yellow('⚠ Update Available'));
|
|
48
|
+
logger_1.default.warn(colors_1.default.yellow(` A new version of the TestingBot CLI is available: ${colors_1.default.green(latestVersion)}`));
|
|
49
|
+
logger_1.default.warn(colors_1.default.yellow(` Run: ${colors_1.default.cyan('npm install -g @testingbot/cli@latest')}`));
|
|
50
|
+
logger_1.default.warn(colors_1.default.yellow(border) + '\n');
|
|
46
51
|
}
|
|
47
52
|
},
|
|
48
53
|
};
|