@asyncapi/cli 0.13.0 β†’ 0.14.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.
package/README.md CHANGED
@@ -69,8 +69,9 @@ USAGE
69
69
 
70
70
  COMMANDS
71
71
  config access configs
72
- help display help for asyncapi
72
+ diff find diff between two asyncapi files
73
73
  new creates a new asyncapi file
74
+ start starts a new local instance of Studio
74
75
  validate validate asyncapi file
75
76
  ```
76
77
 
@@ -92,3 +93,34 @@ UX developed for the CLI should be compliant with [Command Line Interface Guidel
92
93
  ### Command Structure and Patterns
93
94
 
94
95
  We are following `verb + noun` and `namespace + noun + [verb]` pattern for making our commands and arguments. For example `asyncapi validate <spec-file-path>` and `asyncapi config context add <context-name> <spec-file-path>`.
96
+
97
+ ## Contributors
98
+
99
+ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
100
+
101
+ <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
102
+ <!-- prettier-ignore-start -->
103
+ <!-- markdownlint-disable -->
104
+ <table>
105
+ <tr>
106
+ <td align="center"><a href="https://github.com/jotamusik"><img src="https://avatars.githubusercontent.com/u/14940638?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jorge Aguiar MartΓ­n</b></sub></a><br /><a href="https://github.com/asyncapi/cli/commits?author=jotamusik" title="Code">πŸ’»</a> <a href="#ideas-jotamusik" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="https://github.com/asyncapi/cli/commits?author=jotamusik" title="Tests">⚠️</a> <a href="https://github.com/asyncapi/cli/commits?author=jotamusik" title="Documentation">πŸ“–</a></td>
107
+ <td align="center"><a href="https://www.brainfart.dev/"><img src="https://avatars.githubusercontent.com/u/6995927?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lukasz Gornicki</b></sub></a><br /><a href="#ideas-derberg" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="https://github.com/asyncapi/cli/commits?author=derberg" title="Code">πŸ’»</a> <a href="https://github.com/asyncapi/cli/pulls?q=is%3Apr+reviewed-by%3Aderberg" title="Reviewed Pull Requests">πŸ‘€</a> <a href="#maintenance-derberg" title="Maintenance">🚧</a></td>
108
+ <td align="center"><a href="https://souvik.vercel.app/"><img src="https://avatars.githubusercontent.com/u/41781438?v=4?s=100" width="100px;" alt=""/><br /><sub><b>souvik</b></sub></a><br /><a href="https://github.com/asyncapi/cli/commits?author=Souvikns" title="Code">πŸ’»</a> <a href="#ideas-Souvikns" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="https://github.com/asyncapi/cli/commits?author=Souvikns" title="Tests">⚠️</a> <a href="https://github.com/asyncapi/cli/pulls?q=is%3Apr+reviewed-by%3ASouvikns" title="Reviewed Pull Requests">πŸ‘€</a> <a href="#maintenance-Souvikns" title="Maintenance">🚧</a> <a href="https://github.com/asyncapi/cli/commits?author=Souvikns" title="Documentation">πŸ“–</a></td>
109
+ <td align="center"><a href="https://boyney.io/"><img src="https://avatars.githubusercontent.com/u/3268013?v=4?s=100" width="100px;" alt=""/><br /><sub><b>David Boyne</b></sub></a><br /><a href="https://github.com/asyncapi/cli/commits?author=boyney123" title="Code">πŸ’»</a> <a href="#ideas-boyney123" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="#maintenance-boyney123" title="Maintenance">🚧</a></td>
110
+ <td align="center"><a href="http://www.fmvilas.com/"><img src="https://avatars.githubusercontent.com/u/242119?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Fran MΓ©ndez</b></sub></a><br /><a href="https://github.com/asyncapi/cli/commits?author=fmvilas" title="Code">πŸ’»</a> <a href="#ideas-fmvilas" title="Ideas, Planning, & Feedback">πŸ€”</a> <a href="https://github.com/asyncapi/cli/pulls?q=is%3Apr+reviewed-by%3Afmvilas" title="Reviewed Pull Requests">πŸ‘€</a></td>
111
+ <td align="center"><a href="https://github.com/magicmatatjahu"><img src="https://avatars.githubusercontent.com/u/20404945?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Maciej UrbaΕ„czyk</b></sub></a><br /><a href="https://github.com/asyncapi/cli/pulls?q=is%3Apr+reviewed-by%3Amagicmatatjahu" title="Reviewed Pull Requests">πŸ‘€</a> <a href="#maintenance-magicmatatjahu" title="Maintenance">🚧</a> <a href="#ideas-magicmatatjahu" title="Ideas, Planning, & Feedback">πŸ€”</a></td>
112
+ <td align="center"><a href="https://aayushsahu.com/"><img src="https://avatars.githubusercontent.com/u/54525741?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Aayush Kumar Sahu</b></sub></a><br /><a href="https://github.com/asyncapi/cli/commits?author=aayushmau5" title="Code">πŸ’»</a> <a href="https://github.com/asyncapi/cli/commits?author=aayushmau5" title="Tests">⚠️</a></td>
113
+ </tr>
114
+ <tr>
115
+ <td align="center"><a href="https://github.com/mihirterna"><img src="https://avatars.githubusercontent.com/u/31316452?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mihir Kulkarni</b></sub></a><br /><a href="https://github.com/asyncapi/cli/commits?author=mihirterna" title="Code">πŸ’»</a></td>
116
+ <td align="center"><a href="https://imabp.github.io/resume/"><img src="https://avatars.githubusercontent.com/u/53480076?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Abir</b></sub></a><br /><a href="https://github.com/asyncapi/cli/commits?author=imabp" title="Tests">⚠️</a></td>
117
+ <td align="center"><a href="https://github.com/peter-rr"><img src="https://avatars.githubusercontent.com/u/81691177?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Peter Ramos</b></sub></a><br /><a href="https://github.com/asyncapi/cli/commits?author=peter-rr" title="Code">πŸ’»</a></td>
118
+ </tr>
119
+ </table>
120
+
121
+ <!-- markdownlint-restore -->
122
+ <!-- prettier-ignore-end -->
123
+
124
+ <!-- ALL-CONTRIBUTORS-LIST:END -->
125
+
126
+ This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
@@ -8,6 +8,7 @@ export default class Diff extends Command {
8
8
  format: flags.IOptionFlag<string>;
9
9
  type: flags.IOptionFlag<string>;
10
10
  overrides: flags.IOptionFlag<string | undefined>;
11
+ watch: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
11
12
  };
12
13
  static args: {
13
14
  name: string;
@@ -11,6 +11,8 @@ const base_1 = tslib_1.__importDefault(require("../base"));
11
11
  const validation_error_1 = require("../errors/validation-error");
12
12
  const specification_file_1 = require("../errors/specification-file");
13
13
  const diff_error_1 = require("../errors/diff-error");
14
+ const globals_1 = require("../globals");
15
+ const flags_1 = require("../flags");
14
16
  const { readFile } = fs_1.promises;
15
17
  class Diff extends base_1.default {
16
18
  async run() {
@@ -20,9 +22,11 @@ class Diff extends base_1.default {
20
22
  const outputFormat = flags['format'];
21
23
  const outputType = flags['type'];
22
24
  const overrideFilePath = flags['overrides'];
25
+ const watchMode = flags['watch'];
23
26
  let firstDocument, secondDocument;
24
27
  try {
25
28
  firstDocument = await SpecificationFile_1.load(firstDocumentPath);
29
+ enableWatch(watchMode, { spec: firstDocument, handler: this, handlerName: 'diff', docVersion: 'old', label: 'DIFF_OLD' });
26
30
  }
27
31
  catch (err) {
28
32
  if (err instanceof specification_file_1.SpecificationFileNotFound) {
@@ -37,6 +41,7 @@ class Diff extends base_1.default {
37
41
  }
38
42
  try {
39
43
  secondDocument = await SpecificationFile_1.load(secondDocumentPath);
44
+ enableWatch(watchMode, { spec: secondDocument, handler: this, handlerName: 'diff', docVersion: 'new', label: 'DIFF_NEW' });
40
45
  }
41
46
  catch (err) {
42
47
  if (err instanceof specification_file_1.SpecificationFileNotFound) {
@@ -116,6 +121,7 @@ Diff.flags = {
116
121
  char: 'o',
117
122
  description: 'path to JSON file containing the override properties',
118
123
  }),
124
+ watch: flags_1.watchFlag
119
125
  };
120
126
  Diff.args = [
121
127
  {
@@ -149,3 +155,12 @@ async function readOverrideFile(path) {
149
155
  throw new diff_error_1.DiffOverrideJSONError();
150
156
  }
151
157
  }
158
+ /**
159
+ * function to enable watchmode.
160
+ * The function is abstracted here, to avoid eslint cognitive complexity error.
161
+ */
162
+ const enableWatch = (status, watcher) => {
163
+ if (status) {
164
+ globals_1.specWatcher(watcher);
165
+ }
166
+ };
@@ -3,6 +3,7 @@ export default class Validate extends Command {
3
3
  static description: string;
4
4
  static flags: {
5
5
  help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
6
+ watch: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
6
7
  };
7
8
  static args: {
8
9
  name: string;
@@ -6,25 +6,16 @@ const parser = tslib_1.__importStar(require("@asyncapi/parser"));
6
6
  const base_1 = tslib_1.__importDefault(require("../base"));
7
7
  const validation_error_1 = require("../errors/validation-error");
8
8
  const SpecificationFile_1 = require("../models/SpecificationFile");
9
- const specification_file_1 = require("../errors/specification-file");
9
+ const globals_1 = require("../globals");
10
+ const flags_1 = require("../flags");
10
11
  class Validate extends base_1.default {
11
12
  async run() {
12
- const { args } = this.parse(Validate);
13
+ const { args, flags } = this.parse(Validate); // NOSONAR
13
14
  const filePath = args['spec-file'];
14
- let specFile;
15
- try {
16
- specFile = await SpecificationFile_1.load(filePath);
17
- }
18
- catch (err) {
19
- if (err instanceof specification_file_1.SpecificationFileNotFound) {
20
- this.error(new validation_error_1.ValidationError({
21
- type: 'invalid-file',
22
- filepath: filePath
23
- }));
24
- }
25
- else {
26
- this.error(err);
27
- }
15
+ const watchMode = flags['watch'];
16
+ const specFile = await SpecificationFile_1.load(filePath);
17
+ if (watchMode) {
18
+ globals_1.specWatcher({ spec: specFile, handler: this, handlerName: 'validate' });
28
19
  }
29
20
  try {
30
21
  if (specFile.getFilePath()) {
@@ -47,7 +38,8 @@ class Validate extends base_1.default {
47
38
  exports.default = Validate;
48
39
  Validate.description = 'validate asyncapi file';
49
40
  Validate.flags = {
50
- help: command_1.flags.help({ char: 'h' })
41
+ help: command_1.flags.help({ char: 'h' }),
42
+ watch: flags_1.watchFlag
51
43
  };
52
44
  Validate.args = [
53
45
  { name: 'spec-file', description: 'spec path, url, or context-name', required: false },
@@ -1,3 +1,4 @@
1
+ export declare const NO_CONTEXTS_SAVED = "Specify what AsyncAPI file to be used.\nThese are your options to specify in the CLI what AsyncAPI file should be used:\n - You can provide a path to the AsyncAPI file: asyncapi <command> path/to/file/asyncapi\n - You can also pass a saved context that points to your AsyncAPI file: asyncapi <command> context-name\n - In case you did not specify a context that you want to use, the CLI checks if there is a default context and uses it. To set default context run: asyncapi context use mycontext\n - In case you did not provide any reference to AsyncAPI file and there is no default context, the CLI detects if in your current working directory you have files like asyncapi.json, asyncapi.yaml, asyncapi.yml. Just rename your file accordingly.\n";
1
2
  declare class ContextError extends Error {
2
3
  constructor();
3
4
  }
@@ -1,9 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ContextNotFound = exports.MissingCurrentContextError = exports.MissingContextFileError = void 0;
4
- const NO_CONTEXTS_SAVED = 'No contexts saved yet, run asyncapi --help to learn more';
3
+ exports.ContextNotFound = exports.MissingCurrentContextError = exports.MissingContextFileError = exports.NO_CONTEXTS_SAVED = void 0;
5
4
  const CONTEXT_NOT_FOUND = (contextName) => `Context "${contextName}" does not exists.`;
6
5
  const MISSING_CURRENT_CONTEXT = 'No context is set as current, please set a current context.';
6
+ exports.NO_CONTEXTS_SAVED = `Specify what AsyncAPI file to be used.
7
+ These are your options to specify in the CLI what AsyncAPI file should be used:
8
+ - You can provide a path to the AsyncAPI file: asyncapi <command> path/to/file/asyncapi
9
+ - You can also pass a saved context that points to your AsyncAPI file: asyncapi <command> context-name
10
+ - In case you did not specify a context that you want to use, the CLI checks if there is a default context and uses it. To set default context run: asyncapi context use mycontext
11
+ - In case you did not provide any reference to AsyncAPI file and there is no default context, the CLI detects if in your current working directory you have files like asyncapi.json, asyncapi.yaml, asyncapi.yml. Just rename your file accordingly.
12
+ `;
7
13
  class ContextError extends Error {
8
14
  constructor() {
9
15
  super();
@@ -13,7 +19,7 @@ class ContextError extends Error {
13
19
  class MissingContextFileError extends ContextError {
14
20
  constructor() {
15
21
  super();
16
- this.message = NO_CONTEXTS_SAVED;
22
+ this.message = exports.NO_CONTEXTS_SAVED;
17
23
  }
18
24
  }
19
25
  exports.MissingContextFileError = MissingContextFileError;
@@ -7,4 +7,9 @@ export declare class SpecificationFileNotFound extends SpecificationFileError {
7
7
  export declare class SpecificationURLNotFound extends SpecificationFileError {
8
8
  constructor(URL: string);
9
9
  }
10
+ declare type From = 'file' | 'url' | 'context';
11
+ export declare class ErrorLoadingSpec extends Error {
12
+ private readonly errorMessages;
13
+ constructor(from?: From, param?: string);
14
+ }
10
15
  export {};
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SpecificationURLNotFound = exports.SpecificationFileNotFound = void 0;
3
+ exports.ErrorLoadingSpec = exports.SpecificationURLNotFound = exports.SpecificationFileNotFound = void 0;
4
+ const context_error_1 = require("./context-error");
4
5
  class SpecificationFileError extends Error {
5
6
  constructor() {
6
7
  super();
@@ -26,3 +27,28 @@ class SpecificationURLNotFound extends SpecificationFileError {
26
27
  }
27
28
  }
28
29
  exports.SpecificationURLNotFound = SpecificationURLNotFound;
30
+ class ErrorLoadingSpec extends Error {
31
+ constructor(from, param) {
32
+ super();
33
+ this.errorMessages = {
34
+ default: context_error_1.NO_CONTEXTS_SAVED
35
+ };
36
+ if (from === 'file') {
37
+ this.name = 'error loading AsyncAPI document from file';
38
+ this.message = `${param} is an invalid file path`;
39
+ }
40
+ if (from === 'url') {
41
+ this.name = 'error loading AsyncAPI docuement from url';
42
+ this.message = `${param} is an invalid url`;
43
+ }
44
+ if (from === 'context') {
45
+ this.name = 'error loading AsyncAPI document from context';
46
+ this.message = `${param} is an invalid context name`;
47
+ }
48
+ if (!from) {
49
+ this.name = 'error locating AsyncAPI document';
50
+ this.message = this.errorMessages.default;
51
+ }
52
+ }
53
+ }
54
+ exports.ErrorLoadingSpec = ErrorLoadingSpec;
@@ -27,11 +27,21 @@ class ValidationError extends Error {
27
27
  for (const e of err.validationErrors) {
28
28
  const errorHasTitle = !!e.title;
29
29
  const errorHasLocation = !!e.location;
30
- if (errorHasLocation) {
30
+ /*
31
+ * All the conditions below are needed since validationErrors (from ParserError) come from Parser JS library,
32
+ * so we cannot assure that all the fields or properties are always provided in the error. There might be cases
33
+ * that even title is not provided.
34
+ */
35
+ if (errorHasTitle && errorHasLocation) {
31
36
  errorsInfo.push(`${e.title} ${e.location.startLine}:${e.location.startColumn}`);
37
+ continue;
32
38
  }
33
39
  if (errorHasTitle) {
34
40
  errorsInfo.push(`${e.title}`);
41
+ continue;
42
+ }
43
+ if (errorHasLocation) {
44
+ errorsInfo.push(`${e.location.startLine}:${e.location.startColumn}`);
35
45
  }
36
46
  }
37
47
  }
package/lib/flags.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare const watchFlag: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
package/lib/flags.js ADDED
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.watchFlag = void 0;
4
+ const command_1 = require("@oclif/command");
5
+ exports.watchFlag = command_1.flags.boolean({
6
+ char: 'w',
7
+ description: 'Enable watch mode'
8
+ });
@@ -0,0 +1,10 @@
1
+ import Command from './base';
2
+ import { Specification } from './models/SpecificationFile';
3
+ export declare type specWatcherParams = {
4
+ spec: Specification;
5
+ handler: Command;
6
+ handlerName: string;
7
+ label?: string;
8
+ docVersion?: 'old' | 'new';
9
+ };
10
+ export declare const specWatcher: (params: specWatcherParams) => void;
package/lib/globals.js ADDED
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.specWatcher = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const chokidar_1 = tslib_1.__importDefault(require("chokidar"));
6
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
+ const GreenLog = chalk_1.default.hex('#00FF00');
8
+ const OrangeLog = chalk_1.default.hex('#FFA500');
9
+ const CHOKIDAR_CONFIG = {
10
+ // awaitWriteFinish: true // Used for large size specification files.
11
+ };
12
+ const WATCH_MESSAGES = {
13
+ logOnStart: (filePath) => console.log(GreenLog(`Watching AsyncAPI file at ${filePath}\n`)),
14
+ logOnChange: (handlerName) => console.log(OrangeLog(`Change detected, running ${handlerName}\n`)),
15
+ logOnAutoDisable: (docVersion = '') => console.log(OrangeLog(`Watch mode for ${docVersion || 'AsyncAPI'} file was not enabled.`), OrangeLog('\nINFO: Watch works only with files from local file system\n'))
16
+ };
17
+ const CHOKIDAR_INSTANCE_STORE = new Map();
18
+ exports.specWatcher = (params) => {
19
+ if (!params.spec.getFilePath()) {
20
+ return WATCH_MESSAGES.logOnAutoDisable(params.docVersion);
21
+ }
22
+ if (CHOKIDAR_INSTANCE_STORE.get(params.label || '_default')) {
23
+ return;
24
+ }
25
+ const filePath = params.spec.getFilePath();
26
+ try {
27
+ WATCH_MESSAGES.logOnStart(filePath);
28
+ chokidar_1.default
29
+ .watch(filePath, CHOKIDAR_CONFIG)
30
+ .on('change', async () => {
31
+ WATCH_MESSAGES.logOnChange(params.handlerName);
32
+ try {
33
+ await params.handler.run();
34
+ }
35
+ catch (err) {
36
+ await params.handler.catch(err);
37
+ }
38
+ });
39
+ CHOKIDAR_INSTANCE_STORE.set(params.label || '_default', true);
40
+ }
41
+ catch (error) {
42
+ console.log(error);
43
+ }
44
+ };
@@ -18,7 +18,13 @@ export default class SpecificationFile {
18
18
  getPath(): string;
19
19
  read(): Promise<string>;
20
20
  }
21
- export declare function load(filePathOrContextName?: string): Promise<Specification>;
21
+ interface LoadType {
22
+ file?: boolean;
23
+ url?: boolean;
24
+ context?: boolean;
25
+ }
26
+ export declare function load(filePathOrContextName?: string, loadType?: LoadType): Promise<Specification>;
22
27
  export declare function nameType(name: string): Promise<string>;
23
28
  export declare function isURL(urlpath: string): Promise<boolean>;
24
29
  export declare function fileExists(name: string): Promise<boolean>;
30
+ export {};
@@ -7,6 +7,7 @@ const path = tslib_1.__importStar(require("path"));
7
7
  const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
8
8
  const Context_1 = require("./Context");
9
9
  const specification_file_1 = require("../errors/specification-file");
10
+ const context_error_1 = require("../errors/context-error");
10
11
  const { readFile, lstat } = fs_1.promises;
11
12
  const allowedFileNames = [
12
13
  'asyncapi.json',
@@ -32,15 +33,25 @@ class Specification {
32
33
  return this.fileURL;
33
34
  }
34
35
  static async fromFile(filepath) {
35
- return new Specification(await readFile(filepath, { encoding: 'utf8' }), { filepath });
36
+ let spec;
37
+ try {
38
+ spec = await readFile(filepath, { encoding: 'utf8' });
39
+ }
40
+ catch (error) {
41
+ throw new specification_file_1.ErrorLoadingSpec('file', filepath);
42
+ }
43
+ return new Specification(spec, { filepath });
36
44
  }
37
45
  static async fromURL(URLpath) {
38
46
  let response;
39
47
  try {
40
48
  response = await node_fetch_1.default(URLpath, { method: 'GET' });
49
+ if (!response.ok) {
50
+ throw new specification_file_1.ErrorLoadingSpec('url', URLpath);
51
+ }
41
52
  }
42
53
  catch (error) {
43
- throw new specification_file_1.SpecificationURLNotFound(URLpath);
54
+ throw new specification_file_1.ErrorLoadingSpec('url', URLpath);
44
55
  }
45
56
  return new Specification(await (response === null || response === void 0 ? void 0 : response.text()), { fileURL: URLpath });
46
57
  }
@@ -58,8 +69,18 @@ class SpecificationFile {
58
69
  }
59
70
  }
60
71
  exports.default = SpecificationFile;
61
- async function load(filePathOrContextName) {
72
+ /* eslint-disable sonarjs/cognitive-complexity */
73
+ async function load(filePathOrContextName, loadType) {
62
74
  if (filePathOrContextName) {
75
+ if (loadType === null || loadType === void 0 ? void 0 : loadType.file) {
76
+ return Specification.fromFile(filePathOrContextName);
77
+ }
78
+ if (loadType === null || loadType === void 0 ? void 0 : loadType.context) {
79
+ return loadFromContext(filePathOrContextName);
80
+ }
81
+ if (loadType === null || loadType === void 0 ? void 0 : loadType.url) {
82
+ return Specification.fromURL(filePathOrContextName);
83
+ }
63
84
  const type = await nameType(filePathOrContextName);
64
85
  if (type === TYPE_CONTEXT_NAME) {
65
86
  return loadFromContext(filePathOrContextName);
@@ -78,11 +99,11 @@ async function load(filePathOrContextName) {
78
99
  if (autoDetectedSpecFile) {
79
100
  return Specification.fromFile(autoDetectedSpecFile);
80
101
  }
81
- if (!filePathOrContextName || !autoDetectedSpecFile) {
82
- throw e;
102
+ if (e instanceof context_error_1.MissingContextFileError) {
103
+ throw new specification_file_1.ErrorLoadingSpec();
83
104
  }
105
+ throw e;
84
106
  }
85
- throw new specification_file_1.SpecificationFileNotFound();
86
107
  }
87
108
  exports.load = load;
88
109
  async function nameType(name) {
@@ -118,16 +139,24 @@ async function fileExists(name) {
118
139
  if ((await lstat(name)).isFile()) {
119
140
  return true;
120
141
  }
121
- throw new specification_file_1.SpecificationFileNotFound(name);
142
+ throw new specification_file_1.ErrorLoadingSpec('file', name);
122
143
  }
123
144
  catch (e) {
124
- throw new specification_file_1.SpecificationFileNotFound(name);
145
+ throw new specification_file_1.ErrorLoadingSpec('file', name);
125
146
  }
126
147
  }
127
148
  exports.fileExists = fileExists;
128
149
  async function loadFromContext(contextName) {
129
- const context = await Context_1.loadContext(contextName);
130
- return Specification.fromFile(context);
150
+ try {
151
+ const context = await Context_1.loadContext(contextName);
152
+ return Specification.fromFile(context);
153
+ }
154
+ catch (error) {
155
+ if (error instanceof context_error_1.MissingContextFileError) {
156
+ throw new specification_file_1.ErrorLoadingSpec();
157
+ }
158
+ throw error;
159
+ }
131
160
  }
132
161
  async function detectSpecFile() {
133
162
  const existingFileNames = await Promise.all(allowedFileNames.map(async (filename) => {
@@ -1 +1 @@
1
- {"version":"0.13.0","commands":{"config":{"id":"config","description":"access configs","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"diff":{"id":"diff","description":"find diff between two asyncapi files","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"format":{"name":"format","type":"option","char":"f","description":"format of the output","options":["json"],"default":"json"},"type":{"name":"type","type":"option","char":"t","description":"type of the output","options":["breaking","non-breaking","unclassified","all"],"default":"all"},"overrides":{"name":"overrides","type":"option","char":"o","description":"path to JSON file containing the override properties"}},"args":[{"name":"old","description":"old spec path, URL or context-name","required":true},{"name":"new","description":"new spec path, URL or context-name","required":true}]},"new":{"id":"new","description":"creates a new asyncapi file","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"file-name":{"name":"file-name","type":"option","char":"n","description":"name of the file"},"example":{"name":"example","type":"option","char":"e","description":"name of the example to use"},"studio":{"name":"studio","type":"boolean","char":"s","description":"open in Studio","allowNo":false},"port":{"name":"port","type":"option","char":"p","description":"port in which to start Studio"},"no-tty":{"name":"no-tty","type":"boolean","description":"do not use an interactive terminal","allowNo":false}},"args":[]},"start":{"id":"start","description":"starts a new local instance of Studio","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"validate":{"id":"validate","description":"validate asyncapi file","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"spec-file","description":"spec path, url, or context-name","required":false}]},"config:context":{"id":"config:context","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"start:studio":{"id":"start:studio","description":"starts a new local instance of Studio","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"file":{"name":"file","type":"option","char":"f","description":"path to the AsyncAPI file to link with Studio"},"port":{"name":"port","type":"option","char":"p","description":"port in which to start Studio"}},"args":[]},"config:context:add":{"id":"config:context:add","description":"Add or modify a context in the store","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"context-name","description":"context name","required":true},{"name":"spec-file-path","description":"file path of the spec file","required":true}]},"config:context:current":{"id":"config:context:current","description":"Shows the current context that is being used","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"config:context:list":{"id":"config:context:list","description":"List all the stored context in the store","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"config:context:remove":{"id":"config:context:remove","description":"Delete a context from the store","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"context-name","description":"Name of the context to delete","required":true}]},"config:context:use":{"id":"config:context:use","description":"Set a context as current","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"context-name","description":"name of the saved context","required":true}]}}}
1
+ {"version":"0.14.0","commands":{"config":{"id":"config","description":"access configs","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"diff":{"id":"diff","description":"find diff between two asyncapi files","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"format":{"name":"format","type":"option","char":"f","description":"format of the output","options":["json"],"default":"json"},"type":{"name":"type","type":"option","char":"t","description":"type of the output","options":["breaking","non-breaking","unclassified","all"],"default":"all"},"overrides":{"name":"overrides","type":"option","char":"o","description":"path to JSON file containing the override properties"},"watch":{"name":"watch","type":"boolean","char":"w","description":"Enable watch mode","allowNo":false}},"args":[{"name":"old","description":"old spec path, URL or context-name","required":true},{"name":"new","description":"new spec path, URL or context-name","required":true}]},"new":{"id":"new","description":"creates a new asyncapi file","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"file-name":{"name":"file-name","type":"option","char":"n","description":"name of the file"},"example":{"name":"example","type":"option","char":"e","description":"name of the example to use"},"studio":{"name":"studio","type":"boolean","char":"s","description":"open in Studio","allowNo":false},"port":{"name":"port","type":"option","char":"p","description":"port in which to start Studio"},"no-tty":{"name":"no-tty","type":"boolean","description":"do not use an interactive terminal","allowNo":false}},"args":[]},"start":{"id":"start","description":"starts a new local instance of Studio","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"validate":{"id":"validate","description":"validate asyncapi file","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"watch":{"name":"watch","type":"boolean","char":"w","description":"Enable watch mode","allowNo":false}},"args":[{"name":"spec-file","description":"spec path, url, or context-name","required":false}]},"config:context":{"id":"config:context","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"start:studio":{"id":"start:studio","description":"starts a new local instance of Studio","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"file":{"name":"file","type":"option","char":"f","description":"path to the AsyncAPI file to link with Studio"},"port":{"name":"port","type":"option","char":"p","description":"port in which to start Studio"}},"args":[]},"config:context:add":{"id":"config:context:add","description":"Add or modify a context in the store","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"context-name","description":"context name","required":true},{"name":"spec-file-path","description":"file path of the spec file","required":true}]},"config:context:current":{"id":"config:context:current","description":"Shows the current context that is being used","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"config:context:list":{"id":"config:context:list","description":"List all the stored context in the store","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"config:context:remove":{"id":"config:context:remove","description":"Delete a context from the store","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"context-name","description":"Name of the context to delete","required":true}]},"config:context:use":{"id":"config:context:use","description":"Set a context as current","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"context-name","description":"name of the saved context","required":true}]}}}
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@asyncapi/cli",
3
3
  "description": "All in one CLI for all AsyncAPI tools",
4
- "version": "0.13.0",
4
+ "version": "0.14.0",
5
5
  "author": "@asyncapi",
6
6
  "bin": {
7
7
  "asyncapi": "./bin/run"
8
8
  },
9
9
  "bugs": "https://github.com/asyncapi/cli/issues",
10
10
  "dependencies": {
11
- "@asyncapi/diff": "^0.2.2",
11
+ "@asyncapi/diff": "^0.3.0",
12
12
  "@asyncapi/parser": "^1.14.0",
13
13
  "@asyncapi/studio": "^0.9.0",
14
14
  "@fmvilas/oclif-plugin-spaced-commands": "^1.0.4",