@qodalis/cli-speed-test 0.0.1 → 0.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 CHANGED
@@ -8,4 +8,10 @@ The `@qodalis/cli-speed-test` package is a CLI extension designed to provide uti
8
8
  packages add @qodalis/cli-speed-test
9
9
  ```
10
10
 
11
+ # Usage
12
+
13
+ ```bash
14
+ speed-test run
15
+ ```
16
+
11
17
  This command downloads and registers the extension for use within the CLI environment.
@@ -1,29 +1,21 @@
1
1
  import { DefaultLibraryAuthor } from '@qodalis/cli-core';
2
2
  import axios from 'axios';
3
+ import { LIBRARY_VERSION } from '../version';
3
4
  export class CliSpeedTestCommandProcessor {
4
5
  constructor() {
5
6
  this.command = 'speed-test';
6
7
  this.description = 'Run an internet speed test';
7
8
  this.author = DefaultLibraryAuthor;
8
9
  this.processors = [];
10
+ this.version = LIBRARY_VERSION;
11
+ this.metadata = {
12
+ icon: '🚀',
13
+ };
9
14
  this.processors = [
10
15
  {
11
16
  command: 'run',
12
17
  description: 'Run the internet speed test',
13
18
  parameters: [
14
- {
15
- name: 'proxy',
16
- description: 'Use a proxy server for the test',
17
- type: 'boolean',
18
- required: false,
19
- },
20
- {
21
- name: 'proxy-url',
22
- description: 'URL of the proxy server',
23
- type: 'string',
24
- required: false,
25
- defaultValue: '/proxy',
26
- },
27
19
  {
28
20
  name: 'download-url',
29
21
  description: 'URL to download the file',
@@ -45,11 +37,8 @@ export class CliSpeedTestCommandProcessor {
45
37
  });
46
38
  new Promise(async (resolve, reject) => {
47
39
  context.writer.writeInfo('Starting live speed test...');
48
- const proxyUrl = command.args['proxy-url'] || '/speed-test';
49
40
  const downloadUrl = command.args['download-url'] ||
50
- (command.args['proxy']
51
- ? proxyUrl
52
- : 'https://nbg1-speed.hetzner.com/100MB.bin');
41
+ 'https://proxy.qodalis.com/proxy/https/nbg1-speed.hetzner.com/100MB.bin';
53
42
  const uploadUrl = command.args['upload-url'] ||
54
43
  'https://httpbin.org/post';
55
44
  try {
@@ -170,4 +159,4 @@ export class CliSpeedTestCommandProcessor {
170
159
  }
171
160
  }
172
161
  }
173
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLXNwZWVkLXRlc3QtY29tbWFuZC1wcm9jZXNzb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zcGVlZC10ZXN0L3NyYy9saWIvcHJvY2Vzc29ycy9jbGktc3BlZWQtdGVzdC1jb21tYW5kLXByb2Nlc3Nvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQU16RCxPQUFPLEtBQXlDLE1BQU0sT0FBTyxDQUFDO0FBRTlELE1BQU0sT0FBTyw0QkFBNEI7SUFTckM7UUFSQSxZQUFPLEdBQUcsWUFBWSxDQUFDO1FBRXZCLGdCQUFXLEdBQUcsNEJBQTRCLENBQUM7UUFFM0MsV0FBTSxHQUFHLG9CQUFvQixDQUFDO1FBRTlCLGVBQVUsR0FBd0MsRUFBRSxDQUFDO1FBR2pELElBQUksQ0FBQyxVQUFVLEdBQUc7WUFDZDtnQkFDSSxPQUFPLEVBQUUsS0FBSztnQkFDZCxXQUFXLEVBQUUsNkJBQTZCO2dCQUMxQyxVQUFVLEVBQUU7b0JBQ1I7d0JBQ0ksSUFBSSxFQUFFLE9BQU87d0JBQ2IsV0FBVyxFQUFFLGlDQUFpQzt3QkFDOUMsSUFBSSxFQUFFLFNBQVM7d0JBQ2YsUUFBUSxFQUFFLEtBQUs7cUJBQ2xCO29CQUNEO3dCQUNJLElBQUksRUFBRSxXQUFXO3dCQUNqQixXQUFXLEVBQUUseUJBQXlCO3dCQUN0QyxJQUFJLEVBQUUsUUFBUTt3QkFDZCxRQUFRLEVBQUUsS0FBSzt3QkFDZixZQUFZLEVBQUUsUUFBUTtxQkFDekI7b0JBQ0Q7d0JBQ0ksSUFBSSxFQUFFLGNBQWM7d0JBQ3BCLFdBQVcsRUFBRSwwQkFBMEI7d0JBQ3ZDLElBQUksRUFBRSxRQUFRO3dCQUNkLFFBQVEsRUFBRSxLQUFLO3FCQUNsQjtvQkFDRDt3QkFDSSxJQUFJLEVBQUUsWUFBWTt3QkFDbEIsV0FBVyxFQUFFLHdCQUF3Qjt3QkFDckMsSUFBSSxFQUFFLFFB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O29CQUMvQyxPQUFPLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FDdkIsNEJBQTRCLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FDN0QsQ0FBQztpQkFDTDthQUNKO2lCQUFNO2dCQUNILE1BQU0sQ0FBQyxDQUFDO2FBQ1g7U0FDSjtJQUNMLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERlZmF1bHRMaWJyYXJ5QXV0aG9yIH0gZnJvbSAnQHFvZGFsaXMvY2xpLWNvcmUnO1xuaW1wb3J0IHtcbiAgICBDbGlQcm9jZXNzQ29tbWFuZCxcbiAgICBJQ2xpQ29tbWFuZFByb2Nlc3NvcixcbiAgICBJQ2xpRXhlY3V0aW9uQ29udGV4dCxcbn0gZnJvbSAnQHFvZGFsaXMvY2xpLWNvcmUnO1xuaW1wb3J0IGF4aW9zLCB7IENhbmNlbFRva2VuLCBDYW5jZWxUb2tlblNvdXJjZSB9IGZyb20gJ2F4aW9zJztcblxuZXhwb3J0IGNsYXNzIENsaVNwZWVkVGVzdENvbW1hbmRQcm9jZXNzb3IgaW1wbGVtZW50cyBJQ2xpQ29tbWFuZFByb2Nlc3NvciB7XG4gICAgY29tbWFuZCA9ICdzcGVlZC10ZXN0JztcblxuICAgIGRlc2NyaXB0aW9uID0gJ1J1biBhbiBpbnRlcm5ldCBzcGVlZCB0ZXN0JztcblxuICAgIGF1dGhvciA9IERlZmF1bHRMaWJyYXJ5QXV0aG9yO1xuXG4gICAgcHJvY2Vzc29ycz86IElDbGlDb21tYW5kUHJvY2Vzc29yW10gfCB1bmRlZmluZWQgPSBbXTtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnByb2Nlc3NvcnMgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY29tbWFuZDogJ3J1bicsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdSdW4gdGhlIGludGVybmV0IHNwZWVkIHRlc3QnLFxuICAgICAgICAgICAgICAgIHBhcmFtZXRlcnM6IFtcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ3Byb3h5JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnVXNlIGEgcHJveHkgc2VydmVyIGZvciB0aGUgdGVzdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdwcm94eS11cmwnLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdVUkwgb2YgdGhlIHByb3h5IHNlcnZlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZTogJy9wcm94eScsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdkb3dubG9hZC11cmwnLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdVUkwgdG8gZG93bmxvYWQgdGhlIGZpbGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICd1cGxvYWQtdXJsJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnVVJMIHRvIHVwbG9hZCB0aGUgZmlsZScsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgIHByb2Nlc3NDb21tYW5kOiBhc3luYyAoY29tbWFuZCwgY29udGV4dCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2U6IENhbmNlbFRva2VuU291cmNlID1cbiAgICAgICAgICAgICAgICAgICAgICAgIGF4aW9zLkNhbmNlbFRva2VuLnNvdXJjZSgpO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9IGNvbnRleHQub25BYm9ydC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlLmNhbmNlbCgnU3BlZWQgdGVzdCBhYm9ydGVkIGJ5IHVzZXInKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIG5ldyBQcm9taXNlPHZvaWQ+KGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlSW5mbygnU3RhcnRpbmcgbGl2ZSBzcGVlZCB0ZXN0Li4uJyk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHByb3h5VXJsID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kLmFyZ3NbJ3Byb3h5LXVybCddIHx8ICcvc3BlZWQtdGVzdCc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRvd25sb2FkVXJsID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kLmFyZ3NbJ2Rvd25sb2FkLXVybCddIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvbW1hbmQuYXJnc1sncHJveHknXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHByb3h5VXJsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogJ2h0dHBzOi8vbmJnMS1zcGVlZC5oZXR6bmVyLmNvbS8xMDBNQi5iaW4nKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBsb2FkVXJsID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kLmFyZ3NbJ3VwbG9hZC11cmwnXSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdodHRwczovL2h0dHBiaW4ub3JnL3Bvc3QnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucnVuRG93bmxvYWRTcGVlZFRlc3QoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvd25sb2FkVXJsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UudG9rZW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucnVuVXBsb2FkU3BlZWRUZXN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGxvYWRVcmwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVJbmZvKCdTcGVlZCB0ZXN0IGNvbXBsZXRlZCcpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgU3BlZWQgdGVzdCBmYWlsZWQ6ICR7ZXJyb3I/LnRvU3RyaW5nKCl9YCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuc2hvd1Byb21wdCgpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICB9XG5cbiAgICBhc3luYyBwcm9jZXNzQ29tbWFuZChcbiAgICAgICAgXzogQ2xpUHJvY2Vzc0NvbW1hbmQsXG4gICAgICAgIGNvbnRleHQ6IElDbGlFeGVjdXRpb25Db250ZXh0LFxuICAgICk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZUVycm9yKFwiVXNlICdzcGVlZC10ZXN0JyBjb21tYW5kIHdpdGggYSBzdWJjb21tYW5kXCIpO1xuICAgIH1cblxuICAgIHdyaXRlRGVzY3JpcHRpb24oY29udGV4dDogSUNsaUV4ZWN1dGlvbkNvbnRleHQpOiB2b2lkIHtcbiAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVsbih0aGlzLmRlc2NyaXB0aW9uKTtcbiAgICAgICAgLy8gRXhhbXBsZXNcbiAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVsbignRXhhbXBsZXM6Jyk7XG4gICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlbG4oJyAgc3BlZWQtdGVzdCBydW4nKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSdW4gdGhlIGRvd25sb2FkIHNwZWVkIHRlc3Qgd2l0aCBsaXZlIHVwZGF0ZXMuXG4gICAgICogQHBhcmFtIGNvbnRleHQgQ0xJIGV4ZWN1dGlvbiBjb250ZXh0LlxuICAgICAqL1xuICAgIHByaXZhdGUgYXN5bmMgcnVuRG93bmxvYWRTcGVlZFRlc3QoXG4gICAgICAgIHVybDogc3RyaW5nLFxuICAgICAgICBjb250ZXh0OiBJQ2xpRXhlY3V0aW9uQ29udGV4dCxcbiAgICAgICAgY2FuY2VsVG9rZW46IENhbmNlbFRva2VuLFxuICAgICk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCBzdGFydFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICAgICAgbGV0IHByZXZpb3VzVGltZSA9IHN0YXJ0VGltZTtcbiAgICAgICAgbGV0IHByZXZpb3VzTG9hZGVkID0gMDtcblxuICAgICAgICBhd2FpdCBheGlvcy5nZXQodXJsLCB7XG4gICAgICAgICAgICByZXNwb25zZVR5cGU6ICdhcnJheWJ1ZmZlcicsXG4gICAgICAgICAgICBjYW5jZWxUb2tlbjogY2FuY2VsVG9rZW4sXG4gICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICAgT3JpZ2luOiBudWxsLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9uRG93bmxvYWRQcm9ncmVzczogKHByb2dyZXNzRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFjYW5jZWxUb2tlbi5yZWFzb24pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTcGVlZCB0ZXN0IGFib3J0ZWQgYnkgdXNlcicpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgICAgICAgICAgICAgY29uc3QgZWxhcHNlZFRpbWUgPSAoY3VycmVudFRpbWUgLSBwcmV2aW91c1RpbWUpIC8gMTAwMDtcbiAgICAgICAgICAgICAgICBjb25zdCBieXRlc1NpbmNlTGFzdFVwZGF0ZSA9XG4gICAgICAgICAgICAgICAgICAgIHByb2dyZXNzRXZlbnQubG9hZGVkIC0gcHJldmlvdXNMb2FkZWQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoZWxhcHNlZFRpbWUgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwZWVkSW5CcHMgPSBieXRlc1NpbmNlTGFzdFVwZGF0ZSAvIGVsYXBzZWRUaW1lOyAvLyBCeXRlcyBwZXIgc2Vjb25kXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwZWVkSW5NYnBzID0gKHNwZWVkSW5CcHMgKiA4KSAvICgxMDI0ICogMTAyNCk7IC8vIENvbnZlcnQgdG8gTWJwc1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZWxuKFxuICAgICAgICAgICAgICAgICAgICAgICAgYERvd25sb2FkIFNwZWVkOiAke3NwZWVkSW5NYnBzLnRvRml4ZWQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMixcbiAgICAgICAgICAgICAgICAgICAgICAgICl9IE1icHMgKFByb2dyZXNzOiAkeyhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAocHJvZ3Jlc3NFdmVudC5sb2FkZWQgLyBwcm9ncmVzc0V2ZW50LnRvdGFsISkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEwMFxuICAgICAgICAgICAgICAgICAgICAgICAgKS50b0ZpeGVkKDIpfSUpYCxcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgcHJldmlvdXMgdmFsdWVzXG4gICAgICAgICAgICAgICAgcHJldmlvdXNUaW1lID0gY3VycmVudFRpbWU7XG4gICAgICAgICAgICAgICAgcHJldmlvdXNMb2FkZWQgPSBwcm9ncmVzc0V2ZW50LmxvYWRlZDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGVuZFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICAgICAgY29uc3QgdG90YWxUaW1lID0gKGVuZFRpbWUgLSBzdGFydFRpbWUpIC8gMTAwMDtcbiAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVTdWNjZXNzKFxuICAgICAgICAgICAgYERvd25sb2FkIHRlc3QgY29tcGxldGVkIGluICR7dG90YWxUaW1lLnRvRml4ZWQoMil9IHNlY29uZHNgLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJ1biB0aGUgdXBsb2FkIHNwZWVkIHRlc3Qgd2l0aCBsaXZlIHVwZGF0ZXMuXG4gICAgICogQHBhcmFtIGNvbnRleHQgQ0xJIGV4ZWN1dGlvbiBjb250ZXh0LlxuICAgICAqL1xuICAgIHByaXZhdGUgYXN5bmMgcnVuVXBsb2FkU3BlZWRUZXN0KFxuICAgICAgICB1cmw6IHN0cmluZyxcbiAgICAgICAgY29udGV4dDogSUNsaUV4ZWN1dGlvbkNvbnRleHQsXG4gICAgICAgIHNvdXJjZTogQ2FuY2VsVG9rZW5Tb3VyY2UsXG4gICAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IHRlc3REYXRhID0gbmV3IFVpbnQ4QXJyYXkoMjAgKiAxMDI0ICogMTAyNCk7IC8vIDIwIE1CIG9mIHJhbmRvbSBkYXRhXG4gICAgICAgIHRlc3REYXRhLmZpbGwoMCk7XG4gICAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgICAgICBsZXQgcHJldmlvdXNUaW1lID0gc3RhcnRUaW1lO1xuICAgICAgICBsZXQgcHJldmlvdXNVcGxvYWRlZCA9IDA7XG5cbiAgICAgICAgbGV0IHVwbG9hZENvbXBsZXRlID0gZmFsc2U7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IGF4aW9zLnBvc3QodXJsLCB0ZXN0RGF0YSwge1xuICAgICAgICAgICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nIH0sXG4gICAgICAgICAgICAgICAgY2FuY2VsVG9rZW46IHNvdXJjZS50b2tlbixcbiAgICAgICAgICAgICAgICByZXNwb25zZVR5cGU6ICdzdHJlYW0nLFxuICAgICAgICAgICAgICAgIG9uVXBsb2FkUHJvZ3Jlc3M6IChwcm9ncmVzc0V2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIXNvdXJjZS50b2tlbi5yZWFzb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignU3BlZWQgdGVzdCBhYm9ydGVkIGJ5IHVzZXInKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVsYXBzZWRUaW1lID0gKGN1cnJlbnRUaW1lIC0gcHJldmlvdXNUaW1lKSAvIDEwMDA7IC8vIFRpbWUgc2luY2UgbGFzdCB1cGRhdGVcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYnl0ZXNTaW5jZUxhc3RVcGRhdGUgPVxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvZ3Jlc3NFdmVudC5sb2FkZWQgLSBwcmV2aW91c1VwbG9hZGVkO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChlbGFwc2VkVGltZSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwZWVkSW5CcHMgPSBieXRlc1NpbmNlTGFzdFVwZGF0ZSAvIGVsYXBzZWRUaW1lOyAvLyBCeXRlcyBwZXIgc2Vjb25kXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzcGVlZEluTWJwcyA9IChzcGVlZEluQnBzICogOCkgLyAoMTAyNCAqIDEwMjQpOyAvLyBDb252ZXJ0IHRvIE1icHNcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlbG4oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYFVwbG9hZCBTcGVlZDogJHtzcGVlZEluTWJwcy50b0ZpeGVkKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICl9IE1icHMgKFByb2dyZXNzOiAkeyhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHByb2dyZXNzRXZlbnQubG9hZGVkIC8gcHJvZ3Jlc3NFdmVudC50b3RhbCEpICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMTAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKS50b0ZpeGVkKDIpfSUpYCxcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBVcGRhdGUgcHJldmlvdXMgdmFsdWVzXG4gICAgICAgICAgICAgICAgICAgIHByZXZpb3VzVGltZSA9IGN1cnJlbnRUaW1lO1xuICAgICAgICAgICAgICAgICAgICBwcmV2aW91c1VwbG9hZGVkID0gcHJvZ3Jlc3NFdmVudC5sb2FkZWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb2dyZXNzRXZlbnQubG9hZGVkID49IHByb2dyZXNzRXZlbnQudG90YWwhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cGxvYWRDb21wbGV0ZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UuY2FuY2VsKCdVcGxvYWQgdGVzdCBjb21wbGV0ZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgaWYgKGF4aW9zLmlzQ2FuY2VsKGUpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF1cGxvYWRDb21wbGV0ZSkge1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZUVycm9yKCdVcGxvYWQgdGVzdCBhYm9ydGVkIGJ5IHVzZXInKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmRUaW1lID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRvdGFsVGltZSA9IChlbmRUaW1lIC0gc3RhcnRUaW1lKSAvIDEwMDA7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlU3VjY2VzcyhcbiAgICAgICAgICAgICAgICAgICAgICAgIGBVcGxvYWQgdGVzdCBjb21wbGV0ZWQgaW4gJHt0b3RhbFRpbWUudG9GaXhlZCgyKX0gc2Vjb25kc2AsXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuIl19
162
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLXNwZWVkLXRlc3QtY29tbWFuZC1wcm9jZXNzb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zcGVlZC10ZXN0L3NyYy9saWIvcHJvY2Vzc29ycy9jbGktc3BlZWQtdGVzdC1jb21tYW5kLXByb2Nlc3Nvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQXdCLG9CQUFvQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFNL0UsT0FBTyxLQUF5QyxNQUFNLE9BQU8sQ0FBQztBQUM5RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRTdDLE1BQU0sT0FBTyw0QkFBNEI7SUFlckM7UUFkQSxZQUFPLEdBQUcsWUFBWSxDQUFDO1FBRXZCLGdCQUFXLEdBQUcsNEJBQTRCLENBQUM7UUFFM0MsV0FBTSxHQUFHLG9CQUFvQixDQUFDO1FBRTlCLGVBQVUsR0FBd0MsRUFBRSxDQUFDO1FBRXJELFlBQU8sR0FBRyxlQUFlLENBQUM7UUFFMUIsYUFBUSxHQUFzQztZQUMxQyxJQUFJLEVBQUUsSUFBSTtTQUNiLENBQUM7UUFHRSxJQUFJLENBQUMsVUFBVSxHQUFHO1lBQ2Q7Z0JBQ0ksT0FBTyxFQUFFLEtBQUs7Z0JBQ2QsV0FBVyxFQUFFLDZCQUE2QjtnQkFDMUMsVUFBVSxFQUFFO29CQUNSO3dCQUNJLElBQUksRUFBRSxjQUFjO3dCQUNwQixXQUFXLEVBQUUsMEJBQTBCO3dCQUN2QyxJQUFJLEVBQUUsUUFBUTt3QkFDZCxRQUFRLEVBQUUsS0FBSztxQkFDbEI7b0JBQ0Q7d0JBQ0ksSUFBSSxFQUFFLFlBQVk7d0JBQ2xCLFdBQVcsRUFBRSx3QkFBd0I7d0JBQ3JDLElBQUksRUFBRSxRQUFRO3dCQUNkLFFBQVEsRUFBRSxLQUFLO3FCQUNsQjtpQkFDSjtnQkFDRCxjQUFjLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFBRTtvQkFDdkMsTUFBTSxNQUFNLEdB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QUFPLENBQ2hDLENBQUMsQ0FDSixvQkFBb0IsQ0FDakIsQ0FBQyxhQUFhLENBQUMsTUFBTSxHQUFHLGFBQWEsQ0FBQyxLQUFNLENBQUM7NEJBQzdDLEdBQUcsQ0FDTixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUNuQixDQUFDO3FCQUNMO29CQUVELHlCQUF5QjtvQkFDekIsWUFBWSxHQUFHLFdBQVcsQ0FBQztvQkFDM0IsZ0JBQWdCLEdBQUcsYUFBYSxDQUFDLE1BQU0sQ0FBQztvQkFFeEMsSUFBSSxhQUFhLENBQUMsTUFBTSxJQUFJLGFBQWEsQ0FBQyxLQUFNLEVBQUU7d0JBQzlDLGNBQWMsR0FBRyxJQUFJLENBQUM7d0JBQ3RCLE1BQU0sQ0FBQyxNQUFNLENBQUMsdUJBQXVCLENBQUMsQ0FBQztxQkFDMUM7Z0JBQ0wsQ0FBQzthQUNKLENBQUMsQ0FBQztTQUNOO1FBQUMsT0FBTyxDQUFDLEVBQUU7WUFDUixJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ25CLElBQUksQ0FBQyxjQUFjLEVBQUU7b0JBQ2pCLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLDZCQUE2QixDQUFDLENBQUM7aUJBQzVEO3FCQUFNO29CQUNILE1BQU0sT0FBTyxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztvQkFDbEMsTUFBTSxTQUFTLEdBQUcsQ0FBQyxPQUFPLEdBQUcsU0FBUyxDQUFDLEdBQUcsSUFBSSxDQUFDO29CQUMvQyxPQUFPLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FDdkIsNEJBQTRCLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FDN0QsQ0FBQztpQkFDTDthQUNKO2lCQUFNO2dCQUNILE1BQU0sQ0FBQyxDQUFDO2FBQ1g7U0FDSjtJQUNMLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENsaVByb2Nlc3Nvck1ldGFkYXRhLCBEZWZhdWx0TGlicmFyeUF1dGhvciB9IGZyb20gJ0Bxb2RhbGlzL2NsaS1jb3JlJztcbmltcG9ydCB7XG4gICAgQ2xpUHJvY2Vzc0NvbW1hbmQsXG4gICAgSUNsaUNvbW1hbmRQcm9jZXNzb3IsXG4gICAgSUNsaUV4ZWN1dGlvbkNvbnRleHQsXG59IGZyb20gJ0Bxb2RhbGlzL2NsaS1jb3JlJztcbmltcG9ydCBheGlvcywgeyBDYW5jZWxUb2tlbiwgQ2FuY2VsVG9rZW5Tb3VyY2UgfSBmcm9tICdheGlvcyc7XG5pbXBvcnQgeyBMSUJSQVJZX1ZFUlNJT04gfSBmcm9tICcuLi92ZXJzaW9uJztcblxuZXhwb3J0IGNsYXNzIENsaVNwZWVkVGVzdENvbW1hbmRQcm9jZXNzb3IgaW1wbGVtZW50cyBJQ2xpQ29tbWFuZFByb2Nlc3NvciB7XG4gICAgY29tbWFuZCA9ICdzcGVlZC10ZXN0JztcblxuICAgIGRlc2NyaXB0aW9uID0gJ1J1biBhbiBpbnRlcm5ldCBzcGVlZCB0ZXN0JztcblxuICAgIGF1dGhvciA9IERlZmF1bHRMaWJyYXJ5QXV0aG9yO1xuXG4gICAgcHJvY2Vzc29ycz86IElDbGlDb21tYW5kUHJvY2Vzc29yW10gfCB1bmRlZmluZWQgPSBbXTtcblxuICAgIHZlcnNpb24gPSBMSUJSQVJZX1ZFUlNJT047XG5cbiAgICBtZXRhZGF0YT86IENsaVByb2Nlc3Nvck1ldGFkYXRhIHwgdW5kZWZpbmVkID0ge1xuICAgICAgICBpY29uOiAn8J+agCcsXG4gICAgfTtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnByb2Nlc3NvcnMgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY29tbWFuZDogJ3J1bicsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdSdW4gdGhlIGludGVybmV0IHNwZWVkIHRlc3QnLFxuICAgICAgICAgICAgICAgIHBhcmFtZXRlcnM6IFtcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ2Rvd25sb2FkLXVybCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ1VSTCB0byBkb3dubG9hZCB0aGUgZmlsZScsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ3VwbG9hZC11cmwnLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdVUkwgdG8gdXBsb2FkIHRoZSBmaWxlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgcHJvY2Vzc0NvbW1hbmQ6IGFzeW5jIChjb21tYW5kLCBjb250ZXh0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZTogQ2FuY2VsVG9rZW5Tb3VyY2UgPVxuICAgICAgICAgICAgICAgICAgICAgICAgYXhpb3MuQ2FuY2VsVG9rZW4uc291cmNlKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uID0gY29udGV4dC5vbkFib3J0LnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UuY2FuY2VsKCdTcGVlZCB0ZXN0IGFib3J0ZWQgYnkgdXNlcicpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgbmV3IFByb21pc2U8dm9pZD4oYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVJbmZvKCdTdGFydGluZyBsaXZlIHNwZWVkIHRlc3QuLi4nKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZG93bmxvYWRVcmwgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQuYXJnc1snZG93bmxvYWQtdXJsJ10gfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaHR0cHM6Ly9wcm94eS5xb2RhbGlzLmNvbS9wcm94eS9odHRwcy9uYmcxLXNwZWVkLmhldHpuZXIuY29tLzEwME1CLmJpbic7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwbG9hZFVybCA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWFuZC5hcmdzWyd1cGxvYWQtdXJsJ10gfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaHR0cHM6Ly9odHRwYmluLm9yZy9wb3N0JztcblxuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJ1bkRvd25sb2FkU3BlZWRUZXN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3dubG9hZFVybCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlLnRva2VuLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJ1blVwbG9hZFNwZWVkVGVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBsb2FkVXJsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlSW5mbygnU3BlZWQgdGVzdCBjb21wbGV0ZWQnKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYFNwZWVkIHRlc3QgZmFpbGVkOiAke2Vycm9yPy50b1N0cmluZygpfWAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LnNob3dQcm9tcHQoKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIF07XG4gICAgfVxuXG4gICAgYXN5bmMgcHJvY2Vzc0NvbW1hbmQoXG4gICAgICAgIF86IENsaVByb2Nlc3NDb21tYW5kLFxuICAgICAgICBjb250ZXh0OiBJQ2xpRXhlY3V0aW9uQ29udGV4dCxcbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVFcnJvcihcIlVzZSAnc3BlZWQtdGVzdCcgY29tbWFuZCB3aXRoIGEgc3ViY29tbWFuZFwiKTtcbiAgICB9XG5cbiAgICB3cml0ZURlc2NyaXB0aW9uKGNvbnRleHQ6IElDbGlFeGVjdXRpb25Db250ZXh0KTogdm9pZCB7XG4gICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlbG4odGhpcy5kZXNjcmlwdGlvbik7XG4gICAgICAgIC8vIEV4YW1wbGVzXG4gICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlbG4oJ0V4YW1wbGVzOicpO1xuICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZWxuKCcgIHNwZWVkLXRlc3QgcnVuJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUnVuIHRoZSBkb3dubG9hZCBzcGVlZCB0ZXN0IHdpdGggbGl2ZSB1cGRhdGVzLlxuICAgICAqIEBwYXJhbSBjb250ZXh0IENMSSBleGVjdXRpb24gY29udGV4dC5cbiAgICAgKi9cbiAgICBwcml2YXRlIGFzeW5jIHJ1bkRvd25sb2FkU3BlZWRUZXN0KFxuICAgICAgICB1cmw6IHN0cmluZyxcbiAgICAgICAgY29udGV4dDogSUNsaUV4ZWN1dGlvbkNvbnRleHQsXG4gICAgICAgIGNhbmNlbFRva2VuOiBDYW5jZWxUb2tlbixcbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3Qgc3RhcnRUaW1lID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgICAgIGxldCBwcmV2aW91c1RpbWUgPSBzdGFydFRpbWU7XG4gICAgICAgIGxldCBwcmV2aW91c0xvYWRlZCA9IDA7XG5cbiAgICAgICAgYXdhaXQgYXhpb3MuZ2V0KHVybCwge1xuICAgICAgICAgICAgcmVzcG9uc2VUeXBlOiAnYXJyYXlidWZmZXInLFxuICAgICAgICAgICAgY2FuY2VsVG9rZW46IGNhbmNlbFRva2VuLFxuICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAgIE9yaWdpbjogbnVsbCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvbkRvd25sb2FkUHJvZ3Jlc3M6IChwcm9ncmVzc0V2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhY2FuY2VsVG9rZW4ucmVhc29uKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignU3BlZWQgdGVzdCBhYm9ydGVkIGJ5IHVzZXInKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50VGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGVsYXBzZWRUaW1lID0gKGN1cnJlbnRUaW1lIC0gcHJldmlvdXNUaW1lKSAvIDEwMDA7XG4gICAgICAgICAgICAgICAgY29uc3QgYnl0ZXNTaW5jZUxhc3RVcGRhdGUgPVxuICAgICAgICAgICAgICAgICAgICBwcm9ncmVzc0V2ZW50LmxvYWRlZCAtIHByZXZpb3VzTG9hZGVkO1xuXG4gICAgICAgICAgICAgICAgaWYgKGVsYXBzZWRUaW1lID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzcGVlZEluQnBzID0gYnl0ZXNTaW5jZUxhc3RVcGRhdGUgLyBlbGFwc2VkVGltZTsgLy8gQnl0ZXMgcGVyIHNlY29uZFxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzcGVlZEluTWJwcyA9IChzcGVlZEluQnBzICogOCkgLyAoMTAyNCAqIDEwMjQpOyAvLyBDb252ZXJ0IHRvIE1icHNcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVsbihcbiAgICAgICAgICAgICAgICAgICAgICAgIGBEb3dubG9hZCBTcGVlZDogJHtzcGVlZEluTWJwcy50b0ZpeGVkKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDIsXG4gICAgICAgICAgICAgICAgICAgICAgICApfSBNYnBzIChQcm9ncmVzczogJHsoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHByb2dyZXNzRXZlbnQubG9hZGVkIC8gcHJvZ3Jlc3NFdmVudC50b3RhbCEpICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMDBcbiAgICAgICAgICAgICAgICAgICAgICAgICkudG9GaXhlZCgyKX0lKWAsXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gVXBkYXRlIHByZXZpb3VzIHZhbHVlc1xuICAgICAgICAgICAgICAgIHByZXZpb3VzVGltZSA9IGN1cnJlbnRUaW1lO1xuICAgICAgICAgICAgICAgIHByZXZpb3VzTG9hZGVkID0gcHJvZ3Jlc3NFdmVudC5sb2FkZWQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBlbmRUaW1lID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgICAgIGNvbnN0IHRvdGFsVGltZSA9IChlbmRUaW1lIC0gc3RhcnRUaW1lKSAvIDEwMDA7XG4gICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlU3VjY2VzcyhcbiAgICAgICAgICAgIGBEb3dubG9hZCB0ZXN0IGNvbXBsZXRlZCBpbiAke3RvdGFsVGltZS50b0ZpeGVkKDIpfSBzZWNvbmRzYCxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSdW4gdGhlIHVwbG9hZCBzcGVlZCB0ZXN0IHdpdGggbGl2ZSB1cGRhdGVzLlxuICAgICAqIEBwYXJhbSBjb250ZXh0IENMSSBleGVjdXRpb24gY29udGV4dC5cbiAgICAgKi9cbiAgICBwcml2YXRlIGFzeW5jIHJ1blVwbG9hZFNwZWVkVGVzdChcbiAgICAgICAgdXJsOiBzdHJpbmcsXG4gICAgICAgIGNvbnRleHQ6IElDbGlFeGVjdXRpb25Db250ZXh0LFxuICAgICAgICBzb3VyY2U6IENhbmNlbFRva2VuU291cmNlLFxuICAgICk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCB0ZXN0RGF0YSA9IG5ldyBVaW50OEFycmF5KDIwICogMTAyNCAqIDEwMjQpOyAvLyAyMCBNQiBvZiByYW5kb20gZGF0YVxuICAgICAgICB0ZXN0RGF0YS5maWxsKDApO1xuICAgICAgICBjb25zdCBzdGFydFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICAgICAgbGV0IHByZXZpb3VzVGltZSA9IHN0YXJ0VGltZTtcbiAgICAgICAgbGV0IHByZXZpb3VzVXBsb2FkZWQgPSAwO1xuXG4gICAgICAgIGxldCB1cGxvYWRDb21wbGV0ZSA9IGZhbHNlO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCBheGlvcy5wb3N0KHVybCwgdGVzdERhdGEsIHtcbiAgICAgICAgICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJyB9LFxuICAgICAgICAgICAgICAgIGNhbmNlbFRva2VuOiBzb3VyY2UudG9rZW4sXG4gICAgICAgICAgICAgICAgcmVzcG9uc2VUeXBlOiAnc3RyZWFtJyxcbiAgICAgICAgICAgICAgICBvblVwbG9hZFByb2dyZXNzOiAocHJvZ3Jlc3NFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFzb3VyY2UudG9rZW4ucmVhc29uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NwZWVkIHRlc3QgYWJvcnRlZCBieSB1c2VyJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50VGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbGFwc2VkVGltZSA9IChjdXJyZW50VGltZSAtIHByZXZpb3VzVGltZSkgLyAxMDAwOyAvLyBUaW1lIHNpbmNlIGxhc3QgdXBkYXRlXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGJ5dGVzU2luY2VMYXN0VXBkYXRlID1cbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2dyZXNzRXZlbnQubG9hZGVkIC0gcHJldmlvdXNVcGxvYWRlZDtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoZWxhcHNlZFRpbWUgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzcGVlZEluQnBzID0gYnl0ZXNTaW5jZUxhc3RVcGRhdGUgLyBlbGFwc2VkVGltZTsgLy8gQnl0ZXMgcGVyIHNlY29uZFxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3BlZWRJbk1icHMgPSAoc3BlZWRJbkJwcyAqIDgpIC8gKDEwMjQgKiAxMDI0KTsgLy8gQ29udmVydCB0byBNYnBzXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZWxuKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBVcGxvYWQgU3BlZWQ6ICR7c3BlZWRJbk1icHMudG9GaXhlZChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApfSBNYnBzIChQcm9ncmVzczogJHsoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChwcm9ncmVzc0V2ZW50LmxvYWRlZCAvIHByb2dyZXNzRXZlbnQudG90YWwhKSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEwMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICkudG9GaXhlZCgyKX0lKWAsXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gVXBkYXRlIHByZXZpb3VzIHZhbHVlc1xuICAgICAgICAgICAgICAgICAgICBwcmV2aW91c1RpbWUgPSBjdXJyZW50VGltZTtcbiAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNVcGxvYWRlZCA9IHByb2dyZXNzRXZlbnQubG9hZGVkO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9ncmVzc0V2ZW50LmxvYWRlZCA+PSBwcm9ncmVzc0V2ZW50LnRvdGFsISkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdXBsb2FkQ29tcGxldGUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlLmNhbmNlbCgnVXBsb2FkIHRlc3QgY29tcGxldGVkJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmIChheGlvcy5pc0NhbmNlbChlKSkge1xuICAgICAgICAgICAgICAgIGlmICghdXBsb2FkQ29tcGxldGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVFcnJvcignVXBsb2FkIHRlc3QgYWJvcnRlZCBieSB1c2VyJyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5kVGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0b3RhbFRpbWUgPSAoZW5kVGltZSAtIHN0YXJ0VGltZSkgLyAxMDAwO1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZVN1Y2Nlc3MoXG4gICAgICAgICAgICAgICAgICAgICAgICBgVXBsb2FkIHRlc3QgY29tcGxldGVkIGluICR7dG90YWxUaW1lLnRvRml4ZWQoMil9IHNlY29uZHNgLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbiJdfQ==
@@ -0,0 +1,3 @@
1
+ // Automatically generated during build
2
+ export const LIBRARY_VERSION = '0.0.2';
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3NwZWVkLXRlc3Qvc3JjL2xpYi92ZXJzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLHVDQUF1QztBQUN2QyxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsT0FBTyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiXG4vLyBBdXRvbWF0aWNhbGx5IGdlbmVyYXRlZCBkdXJpbmcgYnVpbGRcbmV4cG9ydCBjb25zdCBMSUJSQVJZX1ZFUlNJT04gPSAnMC4wLjInO1xuICAiXX0=
@@ -4,30 +4,24 @@ import { resolveCommandProcessorProvider } from '@qodalis/angular-cli';
4
4
  import { DefaultLibraryAuthor } from '@qodalis/cli-core';
5
5
  import axios from 'axios';
6
6
 
7
+ // Automatically generated during build
8
+ const LIBRARY_VERSION = '0.0.2';
9
+
7
10
  class CliSpeedTestCommandProcessor {
8
11
  constructor() {
9
12
  this.command = 'speed-test';
10
13
  this.description = 'Run an internet speed test';
11
14
  this.author = DefaultLibraryAuthor;
12
15
  this.processors = [];
16
+ this.version = LIBRARY_VERSION;
17
+ this.metadata = {
18
+ icon: '🚀',
19
+ };
13
20
  this.processors = [
14
21
  {
15
22
  command: 'run',
16
23
  description: 'Run the internet speed test',
17
24
  parameters: [
18
- {
19
- name: 'proxy',
20
- description: 'Use a proxy server for the test',
21
- type: 'boolean',
22
- required: false,
23
- },
24
- {
25
- name: 'proxy-url',
26
- description: 'URL of the proxy server',
27
- type: 'string',
28
- required: false,
29
- defaultValue: '/proxy',
30
- },
31
25
  {
32
26
  name: 'download-url',
33
27
  description: 'URL to download the file',
@@ -49,11 +43,8 @@ class CliSpeedTestCommandProcessor {
49
43
  });
50
44
  new Promise(async (resolve, reject) => {
51
45
  context.writer.writeInfo('Starting live speed test...');
52
- const proxyUrl = command.args['proxy-url'] || '/speed-test';
53
46
  const downloadUrl = command.args['download-url'] ||
54
- (command.args['proxy']
55
- ? proxyUrl
56
- : 'https://nbg1-speed.hetzner.com/100MB.bin');
47
+ 'https://proxy.qodalis.com/proxy/https/nbg1-speed.hetzner.com/100MB.bin';
57
48
  const uploadUrl = command.args['upload-url'] ||
58
49
  'https://httpbin.org/post';
59
50
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"qodalis-cli-speed-test.mjs","sources":["../../../projects/speed-test/src/lib/processors/cli-speed-test-command-processor.ts","../../../projects/speed-test/src/lib/cli-speed-test.module.ts","../../../projects/speed-test/src/public-api.ts","../../../projects/speed-test/src/qodalis-cli-speed-test.ts"],"sourcesContent":["import { DefaultLibraryAuthor } from '@qodalis/cli-core';\nimport {\n CliProcessCommand,\n ICliCommandProcessor,\n ICliExecutionContext,\n} from '@qodalis/cli-core';\nimport axios, { CancelToken, CancelTokenSource } from 'axios';\n\nexport class CliSpeedTestCommandProcessor implements ICliCommandProcessor {\n command = 'speed-test';\n\n description = 'Run an internet speed test';\n\n author = DefaultLibraryAuthor;\n\n processors?: ICliCommandProcessor[] | undefined = [];\n\n constructor() {\n this.processors = [\n {\n command: 'run',\n description: 'Run the internet speed test',\n parameters: [\n {\n name: 'proxy',\n description: 'Use a proxy server for the test',\n type: 'boolean',\n required: false,\n },\n {\n name: 'proxy-url',\n description: 'URL of the proxy server',\n type: 'string',\n required: false,\n defaultValue: '/proxy',\n },\n {\n name: 'download-url',\n description: 'URL to download the file',\n type: 'string',\n required: false,\n },\n {\n name: 'upload-url',\n description: 'URL to upload the file',\n type: 'string',\n required: false,\n },\n ],\n processCommand: async (command, context) => {\n const source: CancelTokenSource =\n axios.CancelToken.source();\n\n const subscription = context.onAbort.subscribe(() => {\n source.cancel('Speed test aborted by user');\n\n subscription.unsubscribe();\n });\n\n new Promise<void>(async (resolve, reject) => {\n context.writer.writeInfo('Starting live speed test...');\n\n const proxyUrl =\n command.args['proxy-url'] || '/speed-test';\n\n const downloadUrl =\n command.args['download-url'] ||\n (command.args['proxy']\n ? proxyUrl\n : 'https://nbg1-speed.hetzner.com/100MB.bin');\n\n const uploadUrl =\n command.args['upload-url'] ||\n 'https://httpbin.org/post';\n\n try {\n await this.runDownloadSpeedTest(\n downloadUrl,\n context,\n source.token,\n );\n\n await this.runUploadSpeedTest(\n uploadUrl,\n context,\n source,\n );\n\n context.writer.writeInfo('Speed test completed');\n\n resolve();\n } catch (error) {\n context.writer.writeError(\n `Speed test failed: ${error?.toString()}`,\n );\n\n reject(error);\n }\n\n subscription.unsubscribe();\n\n context.showPrompt();\n });\n },\n },\n ];\n }\n\n async processCommand(\n _: CliProcessCommand,\n context: ICliExecutionContext,\n ): Promise<void> {\n context.writer.writeError(\"Use 'speed-test' command with a subcommand\");\n }\n\n writeDescription(context: ICliExecutionContext): void {\n context.writer.writeln(this.description);\n // Examples\n context.writer.writeln('Examples:');\n context.writer.writeln(' speed-test run');\n }\n\n /**\n * Run the download speed test with live updates.\n * @param context CLI execution context.\n */\n private async runDownloadSpeedTest(\n url: string,\n context: ICliExecutionContext,\n cancelToken: CancelToken,\n ): Promise<void> {\n const startTime = performance.now();\n let previousTime = startTime;\n let previousLoaded = 0;\n\n await axios.get(url, {\n responseType: 'arraybuffer',\n cancelToken: cancelToken,\n headers: {\n Origin: null,\n },\n onDownloadProgress: (progressEvent) => {\n if (!!cancelToken.reason) {\n throw new Error('Speed test aborted by user');\n }\n\n const currentTime = performance.now();\n const elapsedTime = (currentTime - previousTime) / 1000;\n const bytesSinceLastUpdate =\n progressEvent.loaded - previousLoaded;\n\n if (elapsedTime > 0) {\n const speedInBps = bytesSinceLastUpdate / elapsedTime; // Bytes per second\n const speedInMbps = (speedInBps * 8) / (1024 * 1024); // Convert to Mbps\n context.writer.writeln(\n `Download Speed: ${speedInMbps.toFixed(\n 2,\n )} Mbps (Progress: ${(\n (progressEvent.loaded / progressEvent.total!) *\n 100\n ).toFixed(2)}%)`,\n );\n }\n\n // Update previous values\n previousTime = currentTime;\n previousLoaded = progressEvent.loaded;\n },\n });\n\n const endTime = performance.now();\n const totalTime = (endTime - startTime) / 1000;\n context.writer.writeSuccess(\n `Download test completed in ${totalTime.toFixed(2)} seconds`,\n );\n }\n\n /**\n * Run the upload speed test with live updates.\n * @param context CLI execution context.\n */\n private async runUploadSpeedTest(\n url: string,\n context: ICliExecutionContext,\n source: CancelTokenSource,\n ): Promise<void> {\n const testData = new Uint8Array(20 * 1024 * 1024); // 20 MB of random data\n testData.fill(0);\n const startTime = performance.now();\n let previousTime = startTime;\n let previousUploaded = 0;\n\n let uploadComplete = false;\n\n try {\n await axios.post(url, testData, {\n headers: { 'Content-Type': 'application/octet-stream' },\n cancelToken: source.token,\n responseType: 'stream',\n onUploadProgress: (progressEvent) => {\n if (!!source.token.reason) {\n throw new Error('Speed test aborted by user');\n }\n\n const currentTime = performance.now();\n const elapsedTime = (currentTime - previousTime) / 1000; // Time since last update\n const bytesSinceLastUpdate =\n progressEvent.loaded - previousUploaded;\n\n if (elapsedTime > 0) {\n const speedInBps = bytesSinceLastUpdate / elapsedTime; // Bytes per second\n const speedInMbps = (speedInBps * 8) / (1024 * 1024); // Convert to Mbps\n context.writer.writeln(\n `Upload Speed: ${speedInMbps.toFixed(\n 2,\n )} Mbps (Progress: ${(\n (progressEvent.loaded / progressEvent.total!) *\n 100\n ).toFixed(2)}%)`,\n );\n }\n\n // Update previous values\n previousTime = currentTime;\n previousUploaded = progressEvent.loaded;\n\n if (progressEvent.loaded >= progressEvent.total!) {\n uploadComplete = true;\n source.cancel('Upload test completed');\n }\n },\n });\n } catch (e) {\n if (axios.isCancel(e)) {\n if (!uploadComplete) {\n context.writer.writeError('Upload test aborted by user');\n } else {\n const endTime = performance.now();\n const totalTime = (endTime - startTime) / 1000;\n context.writer.writeSuccess(\n `Upload test completed in ${totalTime.toFixed(2)} seconds`,\n );\n }\n } else {\n throw e;\n }\n }\n }\n}\n","import { NgModule } from '@angular/core';\nimport { resolveCommandProcessorProvider } from '@qodalis/angular-cli';\nimport { CliSpeedTestCommandProcessor } from './processors/cli-speed-test-command-processor';\n\n@NgModule({\n declarations: [],\n imports: [],\n exports: [],\n providers: [resolveCommandProcessorProvider(CliSpeedTestCommandProcessor)],\n})\nexport class CliSpeedTestModule {}\n","/*\n * Public API Surface of speed-test\n */\n\nexport * from './lib/cli-speed-test.module';\n\nexport * from './lib/processors/cli-speed-test-command-processor';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"qodalis-cli-speed-test.mjs","sources":["../../../projects/speed-test/src/lib/version.ts","../../../projects/speed-test/src/lib/processors/cli-speed-test-command-processor.ts","../../../projects/speed-test/src/lib/cli-speed-test.module.ts","../../../projects/speed-test/src/public-api.ts","../../../projects/speed-test/src/qodalis-cli-speed-test.ts"],"sourcesContent":["\n// Automatically generated during build\nexport const LIBRARY_VERSION = '0.0.2';\n ","import { CliProcessorMetadata, DefaultLibraryAuthor } from '@qodalis/cli-core';\nimport {\n CliProcessCommand,\n ICliCommandProcessor,\n ICliExecutionContext,\n} from '@qodalis/cli-core';\nimport axios, { CancelToken, CancelTokenSource } from 'axios';\nimport { LIBRARY_VERSION } from '../version';\n\nexport class CliSpeedTestCommandProcessor implements ICliCommandProcessor {\n command = 'speed-test';\n\n description = 'Run an internet speed test';\n\n author = DefaultLibraryAuthor;\n\n processors?: ICliCommandProcessor[] | undefined = [];\n\n version = LIBRARY_VERSION;\n\n metadata?: CliProcessorMetadata | undefined = {\n icon: '🚀',\n };\n\n constructor() {\n this.processors = [\n {\n command: 'run',\n description: 'Run the internet speed test',\n parameters: [\n {\n name: 'download-url',\n description: 'URL to download the file',\n type: 'string',\n required: false,\n },\n {\n name: 'upload-url',\n description: 'URL to upload the file',\n type: 'string',\n required: false,\n },\n ],\n processCommand: async (command, context) => {\n const source: CancelTokenSource =\n axios.CancelToken.source();\n\n const subscription = context.onAbort.subscribe(() => {\n source.cancel('Speed test aborted by user');\n\n subscription.unsubscribe();\n });\n\n new Promise<void>(async (resolve, reject) => {\n context.writer.writeInfo('Starting live speed test...');\n\n const downloadUrl =\n command.args['download-url'] ||\n 'https://proxy.qodalis.com/proxy/https/nbg1-speed.hetzner.com/100MB.bin';\n\n const uploadUrl =\n command.args['upload-url'] ||\n 'https://httpbin.org/post';\n\n try {\n await this.runDownloadSpeedTest(\n downloadUrl,\n context,\n source.token,\n );\n\n await this.runUploadSpeedTest(\n uploadUrl,\n context,\n source,\n );\n\n context.writer.writeInfo('Speed test completed');\n\n resolve();\n } catch (error) {\n context.writer.writeError(\n `Speed test failed: ${error?.toString()}`,\n );\n\n reject(error);\n }\n\n subscription.unsubscribe();\n\n context.showPrompt();\n });\n },\n },\n ];\n }\n\n async processCommand(\n _: CliProcessCommand,\n context: ICliExecutionContext,\n ): Promise<void> {\n context.writer.writeError(\"Use 'speed-test' command with a subcommand\");\n }\n\n writeDescription(context: ICliExecutionContext): void {\n context.writer.writeln(this.description);\n // Examples\n context.writer.writeln('Examples:');\n context.writer.writeln(' speed-test run');\n }\n\n /**\n * Run the download speed test with live updates.\n * @param context CLI execution context.\n */\n private async runDownloadSpeedTest(\n url: string,\n context: ICliExecutionContext,\n cancelToken: CancelToken,\n ): Promise<void> {\n const startTime = performance.now();\n let previousTime = startTime;\n let previousLoaded = 0;\n\n await axios.get(url, {\n responseType: 'arraybuffer',\n cancelToken: cancelToken,\n headers: {\n Origin: null,\n },\n onDownloadProgress: (progressEvent) => {\n if (!!cancelToken.reason) {\n throw new Error('Speed test aborted by user');\n }\n\n const currentTime = performance.now();\n const elapsedTime = (currentTime - previousTime) / 1000;\n const bytesSinceLastUpdate =\n progressEvent.loaded - previousLoaded;\n\n if (elapsedTime > 0) {\n const speedInBps = bytesSinceLastUpdate / elapsedTime; // Bytes per second\n const speedInMbps = (speedInBps * 8) / (1024 * 1024); // Convert to Mbps\n context.writer.writeln(\n `Download Speed: ${speedInMbps.toFixed(\n 2,\n )} Mbps (Progress: ${(\n (progressEvent.loaded / progressEvent.total!) *\n 100\n ).toFixed(2)}%)`,\n );\n }\n\n // Update previous values\n previousTime = currentTime;\n previousLoaded = progressEvent.loaded;\n },\n });\n\n const endTime = performance.now();\n const totalTime = (endTime - startTime) / 1000;\n context.writer.writeSuccess(\n `Download test completed in ${totalTime.toFixed(2)} seconds`,\n );\n }\n\n /**\n * Run the upload speed test with live updates.\n * @param context CLI execution context.\n */\n private async runUploadSpeedTest(\n url: string,\n context: ICliExecutionContext,\n source: CancelTokenSource,\n ): Promise<void> {\n const testData = new Uint8Array(20 * 1024 * 1024); // 20 MB of random data\n testData.fill(0);\n const startTime = performance.now();\n let previousTime = startTime;\n let previousUploaded = 0;\n\n let uploadComplete = false;\n\n try {\n await axios.post(url, testData, {\n headers: { 'Content-Type': 'application/octet-stream' },\n cancelToken: source.token,\n responseType: 'stream',\n onUploadProgress: (progressEvent) => {\n if (!!source.token.reason) {\n throw new Error('Speed test aborted by user');\n }\n\n const currentTime = performance.now();\n const elapsedTime = (currentTime - previousTime) / 1000; // Time since last update\n const bytesSinceLastUpdate =\n progressEvent.loaded - previousUploaded;\n\n if (elapsedTime > 0) {\n const speedInBps = bytesSinceLastUpdate / elapsedTime; // Bytes per second\n const speedInMbps = (speedInBps * 8) / (1024 * 1024); // Convert to Mbps\n context.writer.writeln(\n `Upload Speed: ${speedInMbps.toFixed(\n 2,\n )} Mbps (Progress: ${(\n (progressEvent.loaded / progressEvent.total!) *\n 100\n ).toFixed(2)}%)`,\n );\n }\n\n // Update previous values\n previousTime = currentTime;\n previousUploaded = progressEvent.loaded;\n\n if (progressEvent.loaded >= progressEvent.total!) {\n uploadComplete = true;\n source.cancel('Upload test completed');\n }\n },\n });\n } catch (e) {\n if (axios.isCancel(e)) {\n if (!uploadComplete) {\n context.writer.writeError('Upload test aborted by user');\n } else {\n const endTime = performance.now();\n const totalTime = (endTime - startTime) / 1000;\n context.writer.writeSuccess(\n `Upload test completed in ${totalTime.toFixed(2)} seconds`,\n );\n }\n } else {\n throw e;\n }\n }\n }\n}\n","import { NgModule } from '@angular/core';\nimport { resolveCommandProcessorProvider } from '@qodalis/angular-cli';\nimport { CliSpeedTestCommandProcessor } from './processors/cli-speed-test-command-processor';\n\n@NgModule({\n declarations: [],\n imports: [],\n exports: [],\n providers: [resolveCommandProcessorProvider(CliSpeedTestCommandProcessor)],\n})\nexport class CliSpeedTestModule {}\n","/*\n * Public API Surface of speed-test\n */\n\nexport * from './lib/cli-speed-test.module';\n\nexport * from './lib/processors/cli-speed-test-command-processor';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -1,9 +1,12 @@
1
+ import { CliProcessorMetadata } from '@qodalis/cli-core';
1
2
  import { CliProcessCommand, ICliCommandProcessor, ICliExecutionContext } from '@qodalis/cli-core';
2
3
  export declare class CliSpeedTestCommandProcessor implements ICliCommandProcessor {
3
4
  command: string;
4
5
  description: string;
5
6
  author: import("@qodalis/cli-core").ICliCommandAuthor;
6
7
  processors?: ICliCommandProcessor[] | undefined;
8
+ version: string;
9
+ metadata?: CliProcessorMetadata | undefined;
7
10
  constructor();
8
11
  processCommand(_: CliProcessCommand, context: ICliExecutionContext): Promise<void>;
9
12
  writeDescription(context: ICliExecutionContext): void;
@@ -0,0 +1 @@
1
+ export declare const LIBRARY_VERSION = "0.0.2";
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@qodalis/cli-speed-test",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "An Angular CLI extension that provides speed test utilities",
5
5
  "author": "Nicolae Lupei, Qodalis Solutions",
6
6
  "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "https://github.com/qodalis-solutions/qodalis-angular-cli"
9
+ "url": "https://github.com/qodalis-solutions/angular-web-cli"
10
10
  },
11
11
  "homepage": "https://qodalis.com",
12
12
  "keywords": [
package/umd/index.js CHANGED
@@ -1,184 +1,175 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('@qodalis/cli-core'), require('axios')) :
3
- typeof define === 'function' && define.amd ? define(['@qodalis/cli-core', 'axios'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.cliCore, global.axios));
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('@qodalis/cli-core'), require('axios')) :
3
+ typeof define === 'function' && define.amd ? define(['@qodalis/cli-core', 'axios'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.cliCore, global.axios));
5
5
  })(this, (function (cliCore, axios) { 'use strict';
6
6
 
7
- class CliSpeedTestCommandProcessor {
8
- constructor() {
9
- this.command = 'speed-test';
10
- this.description = 'Run an internet speed test';
11
- this.author = cliCore.DefaultLibraryAuthor;
12
- this.processors = [];
13
- this.processors = [
14
- {
15
- command: 'run',
16
- description: 'Run the internet speed test',
17
- parameters: [
18
- {
19
- name: 'proxy',
20
- description: 'Use a proxy server for the test',
21
- type: 'boolean',
22
- required: false,
23
- },
24
- {
25
- name: 'proxy-url',
26
- description: 'URL of the proxy server',
27
- type: 'string',
28
- required: false,
29
- defaultValue: '/proxy',
30
- },
31
- {
32
- name: 'download-url',
33
- description: 'URL to download the file',
34
- type: 'string',
35
- required: false,
36
- },
37
- {
38
- name: 'upload-url',
39
- description: 'URL to upload the file',
40
- type: 'string',
41
- required: false,
42
- },
43
- ],
44
- processCommand: async (command, context) => {
45
- const source = axios.CancelToken.source();
46
- const subscription = context.onAbort.subscribe(() => {
47
- source.cancel('Speed test aborted by user');
48
- subscription.unsubscribe();
49
- });
50
- new Promise(async (resolve, reject) => {
51
- context.writer.writeInfo('Starting live speed test...');
52
- const proxyUrl = command.args['proxy-url'] || '/speed-test';
53
- const downloadUrl = command.args['download-url'] ||
54
- (command.args['proxy']
55
- ? proxyUrl
56
- : 'https://nbg1-speed.hetzner.com/100MB.bin');
57
- const uploadUrl = command.args['upload-url'] ||
58
- 'https://httpbin.org/post';
59
- try {
60
- await this.runDownloadSpeedTest(downloadUrl, context, source.token);
61
- await this.runUploadSpeedTest(uploadUrl, context, source);
62
- context.writer.writeInfo('Speed test completed');
63
- resolve();
64
- }
65
- catch (error) {
66
- context.writer.writeError(`Speed test failed: ${error?.toString()}`);
67
- reject(error);
68
- }
69
- subscription.unsubscribe();
70
- context.showPrompt();
71
- });
72
- },
73
- },
74
- ];
75
- }
76
- async processCommand(_, context) {
77
- context.writer.writeError("Use 'speed-test' command with a subcommand");
78
- }
79
- writeDescription(context) {
80
- context.writer.writeln(this.description);
81
- // Examples
82
- context.writer.writeln('Examples:');
83
- context.writer.writeln(' speed-test run');
84
- }
85
- /**
86
- * Run the download speed test with live updates.
87
- * @param context CLI execution context.
88
- */
89
- async runDownloadSpeedTest(url, context, cancelToken) {
90
- const startTime = performance.now();
91
- let previousTime = startTime;
92
- let previousLoaded = 0;
93
- await axios.get(url, {
94
- responseType: 'arraybuffer',
95
- cancelToken: cancelToken,
96
- headers: {
97
- Origin: null,
98
- },
99
- onDownloadProgress: (progressEvent) => {
100
- if (!!cancelToken.reason) {
101
- throw new Error('Speed test aborted by user');
102
- }
103
- const currentTime = performance.now();
104
- const elapsedTime = (currentTime - previousTime) / 1000;
105
- const bytesSinceLastUpdate = progressEvent.loaded - previousLoaded;
106
- if (elapsedTime > 0) {
107
- const speedInBps = bytesSinceLastUpdate / elapsedTime; // Bytes per second
108
- const speedInMbps = (speedInBps * 8) / (1024 * 1024); // Convert to Mbps
109
- context.writer.writeln(`Download Speed: ${speedInMbps.toFixed(2)} Mbps (Progress: ${((progressEvent.loaded / progressEvent.total) *
7
+ // Automatically generated during build
8
+ const LIBRARY_VERSION = '0.0.2';
9
+
10
+ class CliSpeedTestCommandProcessor {
11
+ constructor() {
12
+ this.command = 'speed-test';
13
+ this.description = 'Run an internet speed test';
14
+ this.author = cliCore.DefaultLibraryAuthor;
15
+ this.processors = [];
16
+ this.version = LIBRARY_VERSION;
17
+ this.metadata = {
18
+ icon: '🚀',
19
+ };
20
+ this.processors = [
21
+ {
22
+ command: 'run',
23
+ description: 'Run the internet speed test',
24
+ parameters: [
25
+ {
26
+ name: 'download-url',
27
+ description: 'URL to download the file',
28
+ type: 'string',
29
+ required: false,
30
+ },
31
+ {
32
+ name: 'upload-url',
33
+ description: 'URL to upload the file',
34
+ type: 'string',
35
+ required: false,
36
+ },
37
+ ],
38
+ processCommand: async (command, context) => {
39
+ const source = axios.CancelToken.source();
40
+ const subscription = context.onAbort.subscribe(() => {
41
+ source.cancel('Speed test aborted by user');
42
+ subscription.unsubscribe();
43
+ });
44
+ new Promise(async (resolve, reject) => {
45
+ context.writer.writeInfo('Starting live speed test...');
46
+ const downloadUrl = command.args['download-url'] ||
47
+ 'https://proxy.qodalis.com/proxy/https/nbg1-speed.hetzner.com/100MB.bin';
48
+ const uploadUrl = command.args['upload-url'] ||
49
+ 'https://httpbin.org/post';
50
+ try {
51
+ await this.runDownloadSpeedTest(downloadUrl, context, source.token);
52
+ await this.runUploadSpeedTest(uploadUrl, context, source);
53
+ context.writer.writeInfo('Speed test completed');
54
+ resolve();
55
+ }
56
+ catch (error) {
57
+ context.writer.writeError(`Speed test failed: ${error?.toString()}`);
58
+ reject(error);
59
+ }
60
+ subscription.unsubscribe();
61
+ context.showPrompt();
62
+ });
63
+ },
64
+ },
65
+ ];
66
+ }
67
+ async processCommand(_, context) {
68
+ context.writer.writeError("Use 'speed-test' command with a subcommand");
69
+ }
70
+ writeDescription(context) {
71
+ context.writer.writeln(this.description);
72
+ // Examples
73
+ context.writer.writeln('Examples:');
74
+ context.writer.writeln(' speed-test run');
75
+ }
76
+ /**
77
+ * Run the download speed test with live updates.
78
+ * @param context CLI execution context.
79
+ */
80
+ async runDownloadSpeedTest(url, context, cancelToken) {
81
+ const startTime = performance.now();
82
+ let previousTime = startTime;
83
+ let previousLoaded = 0;
84
+ await axios.get(url, {
85
+ responseType: 'arraybuffer',
86
+ cancelToken: cancelToken,
87
+ headers: {
88
+ Origin: null,
89
+ },
90
+ onDownloadProgress: (progressEvent) => {
91
+ if (!!cancelToken.reason) {
92
+ throw new Error('Speed test aborted by user');
93
+ }
94
+ const currentTime = performance.now();
95
+ const elapsedTime = (currentTime - previousTime) / 1000;
96
+ const bytesSinceLastUpdate = progressEvent.loaded - previousLoaded;
97
+ if (elapsedTime > 0) {
98
+ const speedInBps = bytesSinceLastUpdate / elapsedTime; // Bytes per second
99
+ const speedInMbps = (speedInBps * 8) / (1024 * 1024); // Convert to Mbps
100
+ context.writer.writeln(`Download Speed: ${speedInMbps.toFixed(2)} Mbps (Progress: ${((progressEvent.loaded / progressEvent.total) *
110
101
  100).toFixed(2)}%)`);
111
- }
112
- // Update previous values
113
- previousTime = currentTime;
114
- previousLoaded = progressEvent.loaded;
115
- },
116
- });
117
- const endTime = performance.now();
118
- const totalTime = (endTime - startTime) / 1000;
119
- context.writer.writeSuccess(`Download test completed in ${totalTime.toFixed(2)} seconds`);
120
- }
121
- /**
122
- * Run the upload speed test with live updates.
123
- * @param context CLI execution context.
124
- */
125
- async runUploadSpeedTest(url, context, source) {
126
- const testData = new Uint8Array(20 * 1024 * 1024); // 20 MB of random data
127
- testData.fill(0);
128
- const startTime = performance.now();
129
- let previousTime = startTime;
130
- let previousUploaded = 0;
131
- let uploadComplete = false;
132
- try {
133
- await axios.post(url, testData, {
134
- headers: { 'Content-Type': 'application/octet-stream' },
135
- cancelToken: source.token,
136
- responseType: 'stream',
137
- onUploadProgress: (progressEvent) => {
138
- if (!!source.token.reason) {
139
- throw new Error('Speed test aborted by user');
140
- }
141
- const currentTime = performance.now();
142
- const elapsedTime = (currentTime - previousTime) / 1000; // Time since last update
143
- const bytesSinceLastUpdate = progressEvent.loaded - previousUploaded;
144
- if (elapsedTime > 0) {
145
- const speedInBps = bytesSinceLastUpdate / elapsedTime; // Bytes per second
146
- const speedInMbps = (speedInBps * 8) / (1024 * 1024); // Convert to Mbps
147
- context.writer.writeln(`Upload Speed: ${speedInMbps.toFixed(2)} Mbps (Progress: ${((progressEvent.loaded / progressEvent.total) *
102
+ }
103
+ // Update previous values
104
+ previousTime = currentTime;
105
+ previousLoaded = progressEvent.loaded;
106
+ },
107
+ });
108
+ const endTime = performance.now();
109
+ const totalTime = (endTime - startTime) / 1000;
110
+ context.writer.writeSuccess(`Download test completed in ${totalTime.toFixed(2)} seconds`);
111
+ }
112
+ /**
113
+ * Run the upload speed test with live updates.
114
+ * @param context CLI execution context.
115
+ */
116
+ async runUploadSpeedTest(url, context, source) {
117
+ const testData = new Uint8Array(20 * 1024 * 1024); // 20 MB of random data
118
+ testData.fill(0);
119
+ const startTime = performance.now();
120
+ let previousTime = startTime;
121
+ let previousUploaded = 0;
122
+ let uploadComplete = false;
123
+ try {
124
+ await axios.post(url, testData, {
125
+ headers: { 'Content-Type': 'application/octet-stream' },
126
+ cancelToken: source.token,
127
+ responseType: 'stream',
128
+ onUploadProgress: (progressEvent) => {
129
+ if (!!source.token.reason) {
130
+ throw new Error('Speed test aborted by user');
131
+ }
132
+ const currentTime = performance.now();
133
+ const elapsedTime = (currentTime - previousTime) / 1000; // Time since last update
134
+ const bytesSinceLastUpdate = progressEvent.loaded - previousUploaded;
135
+ if (elapsedTime > 0) {
136
+ const speedInBps = bytesSinceLastUpdate / elapsedTime; // Bytes per second
137
+ const speedInMbps = (speedInBps * 8) / (1024 * 1024); // Convert to Mbps
138
+ context.writer.writeln(`Upload Speed: ${speedInMbps.toFixed(2)} Mbps (Progress: ${((progressEvent.loaded / progressEvent.total) *
148
139
  100).toFixed(2)}%)`);
149
- }
150
- // Update previous values
151
- previousTime = currentTime;
152
- previousUploaded = progressEvent.loaded;
153
- if (progressEvent.loaded >= progressEvent.total) {
154
- uploadComplete = true;
155
- source.cancel('Upload test completed');
156
- }
157
- },
158
- });
159
- }
160
- catch (e) {
161
- if (axios.isCancel(e)) {
162
- if (!uploadComplete) {
163
- context.writer.writeError('Upload test aborted by user');
164
- }
165
- else {
166
- const endTime = performance.now();
167
- const totalTime = (endTime - startTime) / 1000;
168
- context.writer.writeSuccess(`Upload test completed in ${totalTime.toFixed(2)} seconds`);
169
- }
170
- }
171
- else {
172
- throw e;
173
- }
174
- }
175
- }
176
- }
140
+ }
141
+ // Update previous values
142
+ previousTime = currentTime;
143
+ previousUploaded = progressEvent.loaded;
144
+ if (progressEvent.loaded >= progressEvent.total) {
145
+ uploadComplete = true;
146
+ source.cancel('Upload test completed');
147
+ }
148
+ },
149
+ });
150
+ }
151
+ catch (e) {
152
+ if (axios.isCancel(e)) {
153
+ if (!uploadComplete) {
154
+ context.writer.writeError('Upload test aborted by user');
155
+ }
156
+ else {
157
+ const endTime = performance.now();
158
+ const totalTime = (endTime - startTime) / 1000;
159
+ context.writer.writeSuccess(`Upload test completed in ${totalTime.toFixed(2)} seconds`);
160
+ }
161
+ }
162
+ else {
163
+ throw e;
164
+ }
165
+ }
166
+ }
167
+ }
177
168
 
178
- const module = {
179
- name: '@qodalis/cli-speed-test',
180
- processors: [new CliSpeedTestCommandProcessor()],
181
- };
182
- cliCore.bootUmdModule(module);
169
+ const module = {
170
+ name: '@qodalis/cli-speed-test',
171
+ processors: [new CliSpeedTestCommandProcessor()],
172
+ };
173
+ cliCore.bootUmdModule(module);
183
174
 
184
175
  }));