@asyncapi/cli 1.7.3 → 1.8.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.
@@ -14,6 +14,7 @@ const flags_1 = require("../../flags");
14
14
  const generator_2 = require("../../utils/generator");
15
15
  const validation_error_1 = require("../../errors/validation-error");
16
16
  const generator_error_1 = require("../../errors/generator-error");
17
+ const parser_1 = require("@asyncapi/parser");
17
18
  const red = (text) => `\x1b[31m${text}\x1b[0m`;
18
19
  const magenta = (text) => `\x1b[35m${text}\x1b[0m`;
19
20
  const yellow = (text) => `\x1b[33m${text}\x1b[0m`;
@@ -43,6 +44,7 @@ function verifyTemplateSupportForV3(template) {
43
44
  class Template extends base_1.default {
44
45
  constructor() {
45
46
  super(...arguments);
47
+ this.parser = new parser_1.Parser();
46
48
  this.getMapBaseUrlToFolderResolver = (urlToFolder) => {
47
49
  return {
48
50
  order: 1,
@@ -90,6 +92,8 @@ class Template extends base_1.default {
90
92
  disabledHooks: parsedFlags.disableHooks,
91
93
  };
92
94
  const asyncapiInput = (yield (0, SpecificationFile_1.load)(asyncapi)) || (yield (0, SpecificationFile_1.load)());
95
+ this.specFile = asyncapiInput;
96
+ this.metricsMetadata.template = template;
93
97
  const watchTemplate = flags['watch'];
94
98
  const genOption = {};
95
99
  if (flags['map-base-url']) {
@@ -7,6 +7,7 @@ const base_1 = tslib_1.__importDefault(require("../../base"));
7
7
  const inquirer = tslib_1.__importStar(require("inquirer"));
8
8
  const Studio_1 = require("../../models/Studio");
9
9
  const path_1 = require("path");
10
+ const SpecificationFile_1 = require("../../models/SpecificationFile");
10
11
  const { writeFile, readFile } = fs_1.promises;
11
12
  const DEFAULT_ASYNCAPI_FILE_NAME = 'asyncapi.yaml';
12
13
  const DEFAULT_ASYNCAPI_TEMPLATE = 'default-example.yaml';
@@ -143,6 +144,8 @@ class NewFile extends base_1.default {
143
144
  }
144
145
  yield writeFile(fileNameToWriteToDisk, asyncApiFile, { encoding: 'utf8' });
145
146
  console.log(`Created file ${fileNameToWriteToDisk}...`);
147
+ this.specFile = yield (0, SpecificationFile_1.load)(fileNameToWriteToDisk);
148
+ this.metricsMetadata.selected_template = selectedTemplate;
146
149
  });
147
150
  }
148
151
  }
@@ -1,9 +1,10 @@
1
1
  import Command from '../base';
2
2
  import { Example } from '@oclif/core/lib/interfaces';
3
+ import { Parser } from '@asyncapi/parser';
3
4
  export declare enum Optimizations {
4
5
  REMOVE_COMPONENTS = "remove-components",
5
6
  REUSE_COMPONENTS = "reuse-components",
6
- MOVE_TO_COMPONETS = "move-to-components"
7
+ MOVE_TO_COMPONENTS = "move-to-components"
7
8
  }
8
9
  export declare enum Outputs {
9
10
  TERMINAL = "terminal",
@@ -13,7 +14,7 @@ export declare enum Outputs {
13
14
  export default class Optimize extends Command {
14
15
  static description: string;
15
16
  isInteractive: boolean;
16
- optimizations?: Optimizations[];
17
+ selectedOptimizations?: Optimizations[];
17
18
  outputMethod?: Outputs;
18
19
  static examples: Example[];
19
20
  static flags: {
@@ -27,7 +28,9 @@ export default class Optimize extends Command {
27
28
  description: string;
28
29
  required: boolean;
29
30
  }[];
31
+ parser: Parser;
30
32
  run(): Promise<void>;
31
33
  private showOptimizations;
32
34
  private interactiveRun;
35
+ private collectMetricsData;
33
36
  }
@@ -10,12 +10,13 @@ const SpecificationFile_1 = require("../models/SpecificationFile");
10
10
  const inquirer = tslib_1.__importStar(require("inquirer"));
11
11
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
12
12
  const fs_1 = require("fs");
13
+ const parser_1 = require("@asyncapi/parser");
13
14
  const { writeFile } = fs_1.promises;
14
15
  var Optimizations;
15
16
  (function (Optimizations) {
16
17
  Optimizations["REMOVE_COMPONENTS"] = "remove-components";
17
18
  Optimizations["REUSE_COMPONENTS"] = "reuse-components";
18
- Optimizations["MOVE_TO_COMPONETS"] = "move-to-components";
19
+ Optimizations["MOVE_TO_COMPONENTS"] = "move-to-components";
19
20
  })(Optimizations = exports.Optimizations || (exports.Optimizations = {}));
20
21
  var Outputs;
21
22
  (function (Outputs) {
@@ -27,15 +28,15 @@ class Optimize extends base_1.default {
27
28
  constructor() {
28
29
  super(...arguments);
29
30
  this.isInteractive = false;
31
+ this.parser = new parser_1.Parser();
30
32
  }
31
33
  run() {
32
34
  var _a, _b, _c, _d;
33
35
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
34
36
  const { args, flags } = yield this.parse(Optimize); //NOSONAR
35
37
  const filePath = args['spec-file'];
36
- let specFile;
37
38
  try {
38
- specFile = yield (0, SpecificationFile_1.load)(filePath);
39
+ this.specFile = yield (0, SpecificationFile_1.load)(filePath);
39
40
  }
40
41
  catch (err) {
41
42
  this.error(new validation_error_1.ValidationError({
@@ -43,13 +44,13 @@ class Optimize extends base_1.default {
43
44
  filepath: filePath,
44
45
  }));
45
46
  }
46
- if (specFile.isAsyncAPI3()) {
47
+ if (this.specFile.isAsyncAPI3()) {
47
48
  this.error('Optimize command does not support AsyncAPI v3 yet, please checkout https://github.com/asyncapi/optimizer/issues/168');
48
49
  }
49
50
  let optimizer;
50
51
  let report;
51
52
  try {
52
- optimizer = new optimizer_1.Optimizer(specFile.text());
53
+ optimizer = new optimizer_1.Optimizer(this.specFile.text());
53
54
  report = yield optimizer.getReport();
54
55
  }
55
56
  catch (err) {
@@ -59,10 +60,11 @@ class Optimize extends base_1.default {
59
60
  }));
60
61
  }
61
62
  this.isInteractive = !flags['no-tty'];
62
- this.optimizations = flags.optimization;
63
+ this.selectedOptimizations = flags.optimization;
63
64
  this.outputMethod = flags.output;
65
+ this.metricsMetadata.optimized = false;
64
66
  if (!(((_a = report.moveToComponents) === null || _a === void 0 ? void 0 : _a.length) || ((_b = report.removeComponents) === null || _b === void 0 ? void 0 : _b.length) || ((_c = report.reuseComponents) === null || _c === void 0 ? void 0 : _c.length))) {
65
- this.log(`No optimization has been applied since ${(_d = specFile.getFilePath()) !== null && _d !== void 0 ? _d : specFile.getFileURL()} looks optimized!`);
67
+ this.log(`No optimization has been applied since ${(_d = this.specFile.getFilePath()) !== null && _d !== void 0 ? _d : this.specFile.getFileURL()} looks optimized!`);
66
68
  return;
67
69
  }
68
70
  const isTTY = process.stdout.isTTY;
@@ -71,11 +73,12 @@ class Optimize extends base_1.default {
71
73
  }
72
74
  try {
73
75
  const optimizedDocument = optimizer.getOptimizedDocument({ rules: {
74
- moveToComponents: this.optimizations.includes(Optimizations.MOVE_TO_COMPONETS),
75
- removeComponents: this.optimizations.includes(Optimizations.REMOVE_COMPONENTS),
76
- reuseComponents: this.optimizations.includes(Optimizations.REUSE_COMPONENTS)
76
+ moveToComponents: this.selectedOptimizations.includes(Optimizations.MOVE_TO_COMPONENTS),
77
+ removeComponents: this.selectedOptimizations.includes(Optimizations.REMOVE_COMPONENTS),
78
+ reuseComponents: this.selectedOptimizations.includes(Optimizations.REUSE_COMPONENTS)
77
79
  }, output: optimizer_1.Output.YAML });
78
- const specPath = specFile.getFilePath();
80
+ this.collectMetricsData(report);
81
+ const specPath = this.specFile.getFilePath();
79
82
  let newPath = '';
80
83
  if (specPath) {
81
84
  const pos = specPath.lastIndexOf('.');
@@ -84,16 +87,18 @@ class Optimize extends base_1.default {
84
87
  else {
85
88
  newPath = 'optimized-asyncapi.yaml';
86
89
  }
87
- if (this.outputMethod === Outputs.TERMINAL) {
88
- this.log(optimizedDocument);
89
- }
90
- else if (this.outputMethod === Outputs.NEW_FILE) {
91
- yield writeFile(newPath, optimizedDocument, { encoding: 'utf8' });
92
- this.log(`Created file ${newPath}...`);
93
- }
94
- else if (this.outputMethod === Outputs.OVERWRITE) {
95
- yield writeFile(specPath !== null && specPath !== void 0 ? specPath : 'asyncapi.yaml', optimizedDocument, { encoding: 'utf8' });
96
- this.log(`Updated file ${specPath}...`);
90
+ switch (this.outputMethod) {
91
+ case Outputs.TERMINAL:
92
+ this.log(optimizedDocument);
93
+ break;
94
+ case Outputs.NEW_FILE:
95
+ yield writeFile(newPath, optimizedDocument, { encoding: 'utf8' });
96
+ this.log(`Created file ${newPath}...`);
97
+ break;
98
+ case Outputs.OVERWRITE:
99
+ yield writeFile(specPath !== null && specPath !== void 0 ? specPath : 'asyncapi.yaml', optimizedDocument, { encoding: 'utf8' });
100
+ this.log(`Updated file ${specPath}...`);
101
+ break;
97
102
  }
98
103
  }
99
104
  catch (error) {
@@ -133,7 +138,7 @@ class Optimize extends base_1.default {
133
138
  const totalMove = (_d = report.moveToComponents) === null || _d === void 0 ? void 0 : _d.filter((e) => e.action === 'move').length;
134
139
  this.log(`\n${chalk_1.default.green(totalMove)} components can be moved to the components sections.\nthe following changes will be made:`);
135
140
  this.showOptimizations(report.moveToComponents);
136
- choices.push({ name: 'move to components section', value: Optimizations.MOVE_TO_COMPONETS });
141
+ choices.push({ name: 'move to components section', value: Optimizations.MOVE_TO_COMPONENTS });
137
142
  }
138
143
  if (canRemove) {
139
144
  const totalMove = (_e = report.removeComponents) === null || _e === void 0 ? void 0 : _e.length;
@@ -154,7 +159,7 @@ class Optimize extends base_1.default {
154
159
  default: 'all',
155
160
  choices
156
161
  }]);
157
- this.optimizations = optimizationRes.optimization;
162
+ this.selectedOptimizations = optimizationRes.optimization;
158
163
  const outputRes = yield inquirer.prompt([{
159
164
  name: 'output',
160
165
  message: 'where do you want to save the result:',
@@ -165,14 +170,24 @@ class Optimize extends base_1.default {
165
170
  this.outputMethod = outputRes.output;
166
171
  });
167
172
  }
173
+ collectMetricsData(report) {
174
+ var _a;
175
+ for (const availableOptimization in report) {
176
+ const availableOptimizationKebabCase = availableOptimization.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase(); // optimization flags are kebab case
177
+ if (availableOptimization.length && ((_a = this.selectedOptimizations) === null || _a === void 0 ? void 0 : _a.includes(availableOptimizationKebabCase))) {
178
+ this.metricsMetadata[`optimization_${availableOptimization}`] = true;
179
+ this.metricsMetadata.optimized = true;
180
+ }
181
+ }
182
+ }
168
183
  }
169
184
  exports.default = Optimize;
170
185
  Optimize.description = 'optimize asyncapi specification file';
171
186
  Optimize.examples = [
172
187
  'asyncapi optimize ./asyncapi.yaml',
173
188
  'asyncapi optimize ./asyncapi.yaml --no-tty',
174
- 'asyncapi optimize ./asyncapi.yaml --optimization=remove-components,reuse-components,move-to-components --no-tty',
175
- 'asyncapi optimize ./asyncapi.yaml --optimization=remove-components,reuse-components,move-to-components --output=terminal --no-tty',
189
+ 'asyncapi optimize ./asyncapi.yaml --optimization=remove-components --optimization=reuse-components --optimization=move-to-components --no-tty',
190
+ 'asyncapi optimize ./asyncapi.yaml --optimization=remove-components --output=terminal --no-tty',
176
191
  ];
177
192
  Optimize.flags = {
178
193
  help: core_1.Flags.help({ char: 'h' }),
@@ -13,12 +13,13 @@ class Validate extends base_1.default {
13
13
  const { args, flags } = yield this.parse(Validate); //NOSONAR
14
14
  const filePath = args['spec-file'];
15
15
  const watchMode = flags.watch;
16
- const specFile = yield (0, SpecificationFile_1.load)(filePath);
16
+ this.specFile = yield (0, SpecificationFile_1.load)(filePath);
17
17
  if (watchMode) {
18
- (0, globals_1.specWatcher)({ spec: specFile, handler: this, handlerName: 'validate' });
18
+ (0, globals_1.specWatcher)({ spec: this.specFile, handler: this, handlerName: 'validate' });
19
19
  }
20
- const validationResult = yield (0, parser_1.validate)(this, specFile, flags);
21
- if (validationResult === 'invalid') {
20
+ const result = yield (0, parser_1.validate)(this, this.specFile, flags);
21
+ this.metricsMetadata.validation_result = result;
22
+ if (result === 'invalid') {
22
23
  process.exitCode = 1;
23
24
  }
24
25
  });
@@ -259,8 +259,8 @@
259
259
  "examples": [
260
260
  "asyncapi optimize ./asyncapi.yaml",
261
261
  "asyncapi optimize ./asyncapi.yaml --no-tty",
262
- "asyncapi optimize ./asyncapi.yaml --optimization=remove-components,reuse-components,move-to-components --no-tty",
263
- "asyncapi optimize ./asyncapi.yaml --optimization=remove-components,reuse-components,move-to-components --output=terminal --no-tty"
262
+ "asyncapi optimize ./asyncapi.yaml --optimization=remove-components --optimization=reuse-components --optimization=move-to-components --no-tty",
263
+ "asyncapi optimize ./asyncapi.yaml --optimization=remove-components --output=terminal --no-tty"
264
264
  ],
265
265
  "flags": {
266
266
  "help": {
@@ -402,6 +402,48 @@
402
402
  "validate.js"
403
403
  ]
404
404
  },
405
+ "config:analytics": {
406
+ "aliases": [],
407
+ "args": {},
408
+ "description": "Enable or disable analytics for metrics collection",
409
+ "flags": {
410
+ "help": {
411
+ "char": "h",
412
+ "description": "Show CLI help.",
413
+ "name": "help",
414
+ "allowNo": false,
415
+ "type": "boolean"
416
+ },
417
+ "disable": {
418
+ "char": "d",
419
+ "description": "disable analytics",
420
+ "name": "disable",
421
+ "allowNo": false,
422
+ "type": "boolean"
423
+ },
424
+ "enable": {
425
+ "char": "e",
426
+ "description": "enable analytics",
427
+ "name": "enable",
428
+ "allowNo": false,
429
+ "type": "boolean"
430
+ }
431
+ },
432
+ "hasDynamicHelp": false,
433
+ "hiddenAliases": [],
434
+ "id": "config:analytics",
435
+ "pluginAlias": "@asyncapi/cli",
436
+ "pluginName": "@asyncapi/cli",
437
+ "pluginType": "core",
438
+ "strict": true,
439
+ "isESM": false,
440
+ "relativePath": [
441
+ "lib",
442
+ "commands",
443
+ "config",
444
+ "analytics.js"
445
+ ]
446
+ },
405
447
  "config": {
406
448
  "aliases": [],
407
449
  "args": {},
@@ -1436,5 +1478,5 @@
1436
1478
  ]
1437
1479
  }
1438
1480
  },
1439
- "version": "1.7.3"
1481
+ "version": "1.8.1"
1440
1482
  }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@asyncapi/cli",
3
3
  "description": "All in one CLI for all AsyncAPI tools",
4
- "version": "1.7.3",
4
+ "version": "1.8.1",
5
5
  "author": "@asyncapi",
6
6
  "bin": {
7
- "asyncapi": "./bin/run"
7
+ "asyncapi": "./bin/run_bin"
8
8
  },
9
9
  "bugs": "https://github.com/asyncapi/cli/issues",
10
10
  "dependencies": {
@@ -12,18 +12,19 @@
12
12
  "@asyncapi/bundler": "^0.4.0",
13
13
  "@asyncapi/converter": "^1.4.15",
14
14
  "@asyncapi/diff": "^0.4.1",
15
- "@asyncapi/generator": "^1.17.13",
15
+ "@asyncapi/generator": "^1.17.14",
16
16
  "@asyncapi/modelina": "^3.4.5",
17
17
  "@asyncapi/openapi-schema-parser": "^3.0.16",
18
18
  "@asyncapi/optimizer": "^0.2.7",
19
- "@asyncapi/parser": "^3.0.9",
19
+ "@asyncapi/parser": "^3.0.12",
20
20
  "@asyncapi/protobuf-schema-parser": "^3.2.8",
21
21
  "@asyncapi/raml-dt-schema-parser": "^4.0.14",
22
22
  "@asyncapi/studio": "^0.20.0",
23
23
  "@oclif/core": "^1.26.2",
24
24
  "@oclif/errors": "^1.3.6",
25
25
  "@oclif/plugin-not-found": "^2.3.22",
26
- "@smoya/multi-parser": "^4.0.0",
26
+ "@smoya/asyncapi-adoption-metrics": "^2.4.4",
27
+ "@smoya/multi-parser": "^5.0.5",
27
28
  "@stoplight/spectral-cli": "6.9.0",
28
29
  "ajv": "^8.12.0",
29
30
  "chalk": "^4.1.0",
@@ -42,6 +43,7 @@
42
43
  "serve-handler": "^6.1.3",
43
44
  "strip-ansi": "^6.0.0",
44
45
  "unzipper": "^0.10.11",
46
+ "uuid": "^9.0.1",
45
47
  "wrap-ansi": "^9.0.0",
46
48
  "ws": "^8.2.3"
47
49
  },
@@ -61,6 +63,7 @@
61
63
  "@types/node-fetch": "^2.5.12",
62
64
  "@types/rimraf": "^3.0.2",
63
65
  "@types/serve-handler": "^6.1.1",
66
+ "@types/uuid": "^9.0.8",
64
67
  "@types/wrap-ansi": "^8.0.1",
65
68
  "@types/ws": "^8.2.0",
66
69
  "@typescript-eslint/eslint-plugin": "^5.38.1",
@@ -139,7 +142,7 @@
139
142
  "dev": "tsc --watch",
140
143
  "docker:build": "docker build -t asyncapi/cli:latest .",
141
144
  "generate:readme:create": "printf '\n\n# Usage\n\n<!-- usage -->\n\n# Commands\n\n<!-- commands -->\n' > scripts/README.md",
142
- "generate:readme:commands": "npm run build && cd scripts && DEBUG=* oclif readme",
145
+ "generate:readme:commands": "npm run build && cd scripts && cross-env DEBUG=* oclif readme",
143
146
  "generate:assets": "npm run generate:readme:toc && npm run generate:commands",
144
147
  "generate:commands": "npm run generate:readme:create && npm run generate:readme:commands && node ./scripts/updateUsageDocs.js && rimraf ./scripts/README.md",
145
148
  "generate:readme:toc": "markdown-toc -i README.md",