@asyncapi/cli 2.15.0 → 2.16.0

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.
@@ -155,5 +155,5 @@ NewFile.description = 'Creates a new asyncapi file';
155
155
  NewFile.flags = (0, file_flags_1.fileFlags)(getExamplesFlagDescription());
156
156
  NewFile.examples = [
157
157
  'asyncapi new\t - start creation of a file in interactive mode',
158
- 'asyncapi new --file-name=my-asyncapi.yml --example=default-example.yml --no-tty\t - create a new file with a specific name, using one of the examples and without interactive mode'
158
+ 'asyncapi new --file-name=my-asyncapi.yaml --example=default-example.yaml --no-tty\t - create a new file with a specific name, using one of the examples and without interactive mode'
159
159
  ];
@@ -6,5 +6,8 @@ export default class StartStudio extends Command {
6
6
  file: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
7
7
  port: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
8
8
  };
9
+ static readonly args: {
10
+ 'spec-file': import("@oclif/core/lib/interfaces").Arg<string | undefined, Record<string, unknown>>;
11
+ };
9
12
  run(): Promise<void>;
10
13
  }
@@ -5,13 +5,35 @@ const base_1 = tslib_1.__importDefault(require("../../core/base"));
5
5
  const Studio_1 = require("../../core/models/Studio");
6
6
  const SpecificationFile_1 = require("../../core/models/SpecificationFile");
7
7
  const studio_flags_1 = require("../../core/flags/start/studio.flags");
8
+ const core_1 = require("@oclif/core");
8
9
  class StartStudio extends base_1.default {
9
10
  run() {
11
+ var _a;
10
12
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
11
- const { flags } = yield this.parse(StartStudio);
12
- const filePath = flags.file || (yield (0, SpecificationFile_1.load)()).getFilePath();
13
+ const { args, flags } = yield this.parse(StartStudio);
14
+ if (flags.file) {
15
+ this.warn('The file flag has been removed and is being replaced by the argument spec-file. Please pass the filename directly like `asyncapi start studio asyncapi.yml`');
16
+ }
17
+ let filePath = (_a = args['spec-file']) !== null && _a !== void 0 ? _a : flags.file;
13
18
  const port = flags.port;
14
- this.specFile = yield (0, SpecificationFile_1.load)(filePath);
19
+ if (!filePath) {
20
+ try {
21
+ filePath = ((yield (0, SpecificationFile_1.load)()).getFilePath());
22
+ this.log(`Loaded specification from: ${filePath}`);
23
+ }
24
+ catch (error) {
25
+ filePath = '';
26
+ this.error('No file specified.');
27
+ }
28
+ }
29
+ try {
30
+ this.specFile = yield (0, SpecificationFile_1.load)(filePath);
31
+ }
32
+ catch (error) {
33
+ if (filePath) {
34
+ this.error(error);
35
+ }
36
+ }
15
37
  this.metricsMetadata.port = port;
16
38
  (0, Studio_1.start)(filePath, port);
17
39
  });
@@ -20,3 +42,6 @@ class StartStudio extends base_1.default {
20
42
  exports.default = StartStudio;
21
43
  StartStudio.description = 'starts a new local instance of Studio';
22
44
  StartStudio.flags = (0, studio_flags_1.studioFlags)();
45
+ StartStudio.args = {
46
+ 'spec-file': core_1.Args.string({ description: 'spec path, url, or context-name', required: false }),
47
+ };
package/lib/core/base.js CHANGED
@@ -43,6 +43,10 @@ class default_1 extends core_1.Command {
43
43
  return yield _super.catch.call(this, err);
44
44
  }
45
45
  catch (e) {
46
+ if (e.message.includes('EEXIT: 0')) {
47
+ process.exitCode = 0;
48
+ return;
49
+ }
46
50
  if (e instanceof Error) {
47
51
  this.logToStderr(`${e.name}: ${e.message}`);
48
52
  process.exitCode = 1;
@@ -5,7 +5,7 @@ const core_1 = require("@oclif/core");
5
5
  const studioFlags = () => {
6
6
  return {
7
7
  help: core_1.Flags.help({ char: 'h' }),
8
- file: core_1.Flags.string({ char: 'f', description: 'path to the AsyncAPI file to link with Studio' }),
8
+ file: core_1.Flags.string({ char: 'f', description: 'path to the AsyncAPI file to link with Studio', deprecated: true }),
9
9
  port: core_1.Flags.integer({ char: 'p', description: 'port in which to start Studio' }),
10
10
  };
11
11
  };
@@ -20,30 +20,32 @@ function isValidFilePath(filePath) {
20
20
  return (0, fs_1.existsSync)(filePath);
21
21
  }
22
22
  function start(filePath, port = exports.DEFAULT_PORT) {
23
- if (!isValidFilePath(filePath)) {
23
+ if (filePath && !isValidFilePath(filePath)) {
24
24
  throw new specification_file_1.SpecificationFileNotFound(filePath);
25
25
  }
26
- chokidar_1.default.watch(filePath).on('all', (event, path) => {
27
- switch (event) {
28
- case 'add':
29
- case 'change':
30
- getFileContent(path).then((code) => {
26
+ if (filePath) {
27
+ chokidar_1.default.watch(filePath).on('all', (event, path) => {
28
+ switch (event) {
29
+ case 'add':
30
+ case 'change':
31
+ getFileContent(path).then((code) => {
32
+ messageQueue.push(JSON.stringify({
33
+ type: 'file:changed',
34
+ code,
35
+ }));
36
+ sendQueuedMessages();
37
+ });
38
+ break;
39
+ case 'unlink':
31
40
  messageQueue.push(JSON.stringify({
32
- type: 'file:changed',
33
- code,
41
+ type: 'file:deleted',
42
+ filePath,
34
43
  }));
35
44
  sendQueuedMessages();
36
- });
37
- break;
38
- case 'unlink':
39
- messageQueue.push(JSON.stringify({
40
- type: 'file:deleted',
41
- filePath,
42
- }));
43
- sendQueuedMessages();
44
- break;
45
- }
46
- });
45
+ break;
46
+ }
47
+ });
48
+ }
47
49
  const server = (0, http_1.createServer)((request, response) => {
48
50
  //not all CLI users use npm. Some package managers put dependencies in different weird places
49
51
  //this is why we need to first figure out where exactly is the index.html located
@@ -67,17 +69,26 @@ function start(filePath, port = exports.DEFAULT_PORT) {
67
69
  const wsServer = new ws_1.WebSocketServer({ noServer: true });
68
70
  wsServer.on('connection', (socket) => {
69
71
  sockets.push(socket);
70
- getFileContent(filePath).then((code) => {
72
+ if (filePath) {
73
+ getFileContent(filePath).then((code) => {
74
+ messageQueue.push(JSON.stringify({
75
+ type: 'file:loaded',
76
+ code,
77
+ }));
78
+ sendQueuedMessages();
79
+ });
80
+ }
81
+ else {
71
82
  messageQueue.push(JSON.stringify({
72
83
  type: 'file:loaded',
73
- code,
84
+ code: '',
74
85
  }));
75
86
  sendQueuedMessages();
76
- });
87
+ }
77
88
  socket.on('message', (event) => {
78
89
  try {
79
90
  const json = JSON.parse(event);
80
- if (json.type === 'file:update') {
91
+ if (filePath && json.type === 'file:update') {
81
92
  saveFileContent(filePath, json.code);
82
93
  }
83
94
  else {
@@ -97,7 +108,12 @@ function start(filePath, port = exports.DEFAULT_PORT) {
97
108
  const url = `http://localhost:${port}?liveServer=${port}&studio-version=${package_json_1.version}`;
98
109
  console.log(`Studio is now running at ${url}.`);
99
110
  console.log(`You can open this URL in your web browser, and if needed, press ${(0, picocolors_1.gray)('Ctrl + C')} to stop the process.`);
100
- console.log(`Watching changes on file ${filePath}`);
111
+ if (filePath) {
112
+ console.log(`Watching changes on file ${filePath}`);
113
+ }
114
+ else {
115
+ console.warn('Warning: No file was provided, and we couldn\'t find a default file (like "asyncapi.yaml" or "asyncapi.json") in the current folder. Starting Studio with a blank workspace.');
116
+ }
101
117
  (0, open_1.default)(url);
102
118
  });
103
119
  }
@@ -1210,7 +1210,7 @@
1210
1210
  "description": "Creates a new asyncapi file",
1211
1211
  "examples": [
1212
1212
  "asyncapi new\t - start creation of a file in interactive mode",
1213
- "asyncapi new --file-name=my-asyncapi.yml --example=default-example.yml --no-tty\t - create a new file with a specific name, using one of the examples and without interactive mode"
1213
+ "asyncapi new --file-name=my-asyncapi.yaml --example=default-example.yaml --no-tty\t - create a new file with a specific name, using one of the examples and without interactive mode"
1214
1214
  ],
1215
1215
  "flags": {
1216
1216
  "help": {
@@ -1340,7 +1340,7 @@
1340
1340
  "description": "Creates a new asyncapi file",
1341
1341
  "examples": [
1342
1342
  "asyncapi new\t - start creation of a file in interactive mode",
1343
- "asyncapi new --file-name=my-asyncapi.yml --example=default-example.yml --no-tty\t - create a new file with a specific name, using one of the examples and without interactive mode"
1343
+ "asyncapi new --file-name=my-asyncapi.yaml --example=default-example.yaml --no-tty\t - create a new file with a specific name, using one of the examples and without interactive mode"
1344
1344
  ],
1345
1345
  "flags": {
1346
1346
  "help": {
@@ -1494,7 +1494,13 @@
1494
1494
  },
1495
1495
  "start:studio": {
1496
1496
  "aliases": [],
1497
- "args": {},
1497
+ "args": {
1498
+ "spec-file": {
1499
+ "description": "spec path, url, or context-name",
1500
+ "name": "spec-file",
1501
+ "required": false
1502
+ }
1503
+ },
1498
1504
  "description": "starts a new local instance of Studio",
1499
1505
  "flags": {
1500
1506
  "help": {
@@ -1506,6 +1512,7 @@
1506
1512
  },
1507
1513
  "file": {
1508
1514
  "char": "f",
1515
+ "deprecated": true,
1509
1516
  "description": "path to the AsyncAPI file to link with Studio",
1510
1517
  "name": "file",
1511
1518
  "hasDynamicHelp": false,
@@ -1810,5 +1817,5 @@
1810
1817
  ]
1811
1818
  }
1812
1819
  },
1813
- "version": "2.15.0"
1820
+ "version": "2.16.0"
1814
1821
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@asyncapi/cli",
3
3
  "description": "All in one CLI for all AsyncAPI tools",
4
- "version": "2.15.0",
4
+ "version": "2.16.0",
5
5
  "author": "@asyncapi",
6
6
  "bin": {
7
7
  "asyncapi": "./bin/run_bin"