@asyncapi/cli 0.51.12 → 0.52.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.
@@ -9,7 +9,7 @@
9
9
  "version": "0.1.0",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
- "@asyncapi/glee": "^0.23.2"
12
+ "@asyncapi/glee": "^0.23.5"
13
13
  },
14
14
  "engines": {
15
15
  "node": ">=14.15.1"
@@ -219,13 +219,13 @@
219
219
  }
220
220
  },
221
221
  "node_modules/@asyncapi/glee": {
222
- "version": "0.23.2",
223
- "resolved": "https://registry.npmjs.org/@asyncapi/glee/-/glee-0.23.2.tgz",
224
- "integrity": "sha512-6UDwNamtF3cPnifnkviLRlC4c0htuQWuWWz7M9lJhPfnJ6PuE7y5gxO+TT88nOVmR+Y8LzKKw0QAoFIeM95CMQ==",
222
+ "version": "0.23.5",
223
+ "resolved": "https://registry.npmjs.org/@asyncapi/glee/-/glee-0.23.5.tgz",
224
+ "integrity": "sha512-J5rGqGKB0OA624xnvGwqMYTa08W98yU0/aW9sdpoS13U+eJ09yrqG+01Gj2rDIHqf3ovgxarh7gfgnx184pZGg==",
225
225
  "dependencies": {
226
226
  "@asyncapi/generator": "^1.9.18",
227
227
  "@asyncapi/html-template": "^0.24.10",
228
- "@asyncapi/markdown-template": "^1.3.0",
228
+ "@asyncapi/markdown-template": "^1.3.2",
229
229
  "@asyncapi/parser": "^1.13.1",
230
230
  "@types/jest": "^27.4.0",
231
231
  "@types/qs": "^6.9.7",
@@ -279,21 +279,21 @@
279
279
  }
280
280
  },
281
281
  "node_modules/@asyncapi/markdown-template": {
282
- "version": "1.3.0",
283
- "resolved": "https://registry.npmjs.org/@asyncapi/markdown-template/-/markdown-template-1.3.0.tgz",
284
- "integrity": "sha512-VMtIk8Bcr2BJQWCoqkkgef0KqDfxD5sGLm/nrWoF7//c3rZsGM9hzBHMo1tur0w13Nnr59nqEK5mok8JQ9s+XA==",
282
+ "version": "1.3.2",
283
+ "resolved": "https://registry.npmjs.org/@asyncapi/markdown-template/-/markdown-template-1.3.2.tgz",
284
+ "integrity": "sha512-C3oKLu+v1Krvc4kciQIygoQumft829ayq20AjAcbT7sIN1f9cB7Xla/tYe1aCLE+7XMJuQrLCM2qpsx3iRI2dA==",
285
285
  "dependencies": {
286
286
  "@asyncapi/generator-filters": "^2.1.0",
287
287
  "@asyncapi/generator-react-sdk": "^0.2.23",
288
- "@asyncapi/parser": "2.0.3",
288
+ "@asyncapi/parser": "^2.1.0",
289
289
  "openapi-sampler": "^1.3.0",
290
290
  "yaml": "^1.10.2"
291
291
  }
292
292
  },
293
293
  "node_modules/@asyncapi/markdown-template/node_modules/@asyncapi/parser": {
294
- "version": "2.0.3",
295
- "resolved": "https://registry.npmjs.org/@asyncapi/parser/-/parser-2.0.3.tgz",
296
- "integrity": "sha512-2gtIQOaCz8sR70JFREpg6UwgUBboC/26JcAGySkXY/f1ayjcfDoNLi4LsDvmu6G21qLrGN2lI83i8iLG1AzTAw==",
294
+ "version": "2.1.0",
295
+ "resolved": "https://registry.npmjs.org/@asyncapi/parser/-/parser-2.1.0.tgz",
296
+ "integrity": "sha512-78jjN3eW4ZmgJEa6Ap15lofzADCeItO4wHcAY2Jod3qLB1xf1zFDZQdtm3VSHYLeLhwoC1A33bAtzEf7M5P2bg==",
297
297
  "dependencies": {
298
298
  "@asyncapi/specs": "^5.1.0",
299
299
  "@openapi-contrib/openapi-schema-to-json-schema": "~3.2.0",
@@ -11889,13 +11889,13 @@
11889
11889
  }
11890
11890
  },
11891
11891
  "@asyncapi/glee": {
11892
- "version": "0.23.2",
11893
- "resolved": "https://registry.npmjs.org/@asyncapi/glee/-/glee-0.23.2.tgz",
11894
- "integrity": "sha512-6UDwNamtF3cPnifnkviLRlC4c0htuQWuWWz7M9lJhPfnJ6PuE7y5gxO+TT88nOVmR+Y8LzKKw0QAoFIeM95CMQ==",
11892
+ "version": "0.23.5",
11893
+ "resolved": "https://registry.npmjs.org/@asyncapi/glee/-/glee-0.23.5.tgz",
11894
+ "integrity": "sha512-J5rGqGKB0OA624xnvGwqMYTa08W98yU0/aW9sdpoS13U+eJ09yrqG+01Gj2rDIHqf3ovgxarh7gfgnx184pZGg==",
11895
11895
  "requires": {
11896
11896
  "@asyncapi/generator": "^1.9.18",
11897
11897
  "@asyncapi/html-template": "^0.24.10",
11898
- "@asyncapi/markdown-template": "^1.3.0",
11898
+ "@asyncapi/markdown-template": "^1.3.2",
11899
11899
  "@asyncapi/parser": "^1.13.1",
11900
11900
  "@types/jest": "^27.4.0",
11901
11901
  "@types/qs": "^6.9.7",
@@ -11943,21 +11943,21 @@
11943
11943
  }
11944
11944
  },
11945
11945
  "@asyncapi/markdown-template": {
11946
- "version": "1.3.0",
11947
- "resolved": "https://registry.npmjs.org/@asyncapi/markdown-template/-/markdown-template-1.3.0.tgz",
11948
- "integrity": "sha512-VMtIk8Bcr2BJQWCoqkkgef0KqDfxD5sGLm/nrWoF7//c3rZsGM9hzBHMo1tur0w13Nnr59nqEK5mok8JQ9s+XA==",
11946
+ "version": "1.3.2",
11947
+ "resolved": "https://registry.npmjs.org/@asyncapi/markdown-template/-/markdown-template-1.3.2.tgz",
11948
+ "integrity": "sha512-C3oKLu+v1Krvc4kciQIygoQumft829ayq20AjAcbT7sIN1f9cB7Xla/tYe1aCLE+7XMJuQrLCM2qpsx3iRI2dA==",
11949
11949
  "requires": {
11950
11950
  "@asyncapi/generator-filters": "^2.1.0",
11951
11951
  "@asyncapi/generator-react-sdk": "^0.2.23",
11952
- "@asyncapi/parser": "2.0.3",
11952
+ "@asyncapi/parser": "^2.1.0",
11953
11953
  "openapi-sampler": "^1.3.0",
11954
11954
  "yaml": "^1.10.2"
11955
11955
  },
11956
11956
  "dependencies": {
11957
11957
  "@asyncapi/parser": {
11958
- "version": "2.0.3",
11959
- "resolved": "https://registry.npmjs.org/@asyncapi/parser/-/parser-2.0.3.tgz",
11960
- "integrity": "sha512-2gtIQOaCz8sR70JFREpg6UwgUBboC/26JcAGySkXY/f1ayjcfDoNLi4LsDvmu6G21qLrGN2lI83i8iLG1AzTAw==",
11958
+ "version": "2.1.0",
11959
+ "resolved": "https://registry.npmjs.org/@asyncapi/parser/-/parser-2.1.0.tgz",
11960
+ "integrity": "sha512-78jjN3eW4ZmgJEa6Ap15lofzADCeItO4wHcAY2Jod3qLB1xf1zFDZQdtm3VSHYLeLhwoC1A33bAtzEf7M5P2bg==",
11961
11961
  "requires": {
11962
11962
  "@asyncapi/specs": "^5.1.0",
11963
11963
  "@openapi-contrib/openapi-schema-to-json-schema": "~3.2.0",
@@ -24,6 +24,6 @@
24
24
  },
25
25
  "homepage": "https://github.com/asyncapi/glee-hello-world#readme",
26
26
  "dependencies": {
27
- "@asyncapi/glee": "^0.23.2"
27
+ "@asyncapi/glee": "^0.23.5"
28
28
  }
29
29
  }
@@ -4,23 +4,39 @@ const tslib_1 = require("tslib");
4
4
  const core_1 = require("@oclif/core");
5
5
  const base_1 = tslib_1.__importDefault(require("../../../base"));
6
6
  const Context_1 = require("../../../models/Context");
7
+ const context_error_1 = require("../../../errors/context-error");
7
8
  class ContextAdd extends base_1.default {
8
9
  run() {
9
10
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
10
11
  const { args } = yield this.parse(ContextAdd);
11
12
  const contextName = args['context-name'];
12
13
  const specFilePath = args['spec-file-path'];
13
- yield (0, Context_1.addContext)(contextName, specFilePath);
14
- this.log(`Added context "${contextName}".\n\nYou can set it as your current context: asyncapi config context use ${contextName}\nYou can use this context when needed by passing ${contextName} as a parameter: asyncapi validate ${contextName}`);
14
+ try {
15
+ yield (0, Context_1.addContext)(contextName, specFilePath);
16
+ this.log(`Added context "${contextName}".\n\nYou can set it as your current context: asyncapi config context use ${contextName}\nYou can use this context when needed by passing ${contextName} as a parameter: asyncapi validate ${contextName}`);
17
+ }
18
+ catch (e) {
19
+ if (e instanceof (context_error_1.MissingContextFileError || context_error_1.ContextFileWrongFormatError)) {
20
+ this.log('You have no context file configured. Run "asyncapi config context init" to initialize it.');
21
+ return;
22
+ }
23
+ {
24
+ throw e;
25
+ }
26
+ }
15
27
  });
16
28
  }
17
29
  }
18
30
  exports.default = ContextAdd;
19
- ContextAdd.description = 'Add or modify a context in the store';
31
+ ContextAdd.description = 'Add a context to the store';
20
32
  ContextAdd.flags = {
21
- help: core_1.Flags.help({ char: 'h' })
33
+ help: core_1.Flags.help({ char: 'h' }),
22
34
  };
23
35
  ContextAdd.args = [
24
36
  { name: 'context-name', description: 'context name', required: true },
25
- { name: 'spec-file-path', description: 'file path of the spec file', required: true }
37
+ {
38
+ name: 'spec-file-path',
39
+ description: 'file path of the spec file',
40
+ required: true,
41
+ },
26
42
  ];
@@ -4,16 +4,40 @@ const tslib_1 = require("tslib");
4
4
  const core_1 = require("@oclif/core");
5
5
  const base_1 = tslib_1.__importDefault(require("../../../base"));
6
6
  const Context_1 = require("../../../models/Context");
7
+ const context_error_1 = require("../../../errors/context-error");
7
8
  class ContextCurrent extends base_1.default {
8
9
  run() {
9
10
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
10
- const { current, context } = yield (0, Context_1.getCurrentContext)();
11
- this.log(`${current}: ${context}`);
11
+ let fileContent;
12
+ try {
13
+ fileContent = yield (0, Context_1.getCurrentContext)();
14
+ }
15
+ catch (e) {
16
+ if (e instanceof (context_error_1.MissingContextFileError || context_error_1.ContextFileWrongFormatError)) {
17
+ this.log('You have no context file configured. Run "asyncapi config context init" to initialize it.');
18
+ return;
19
+ }
20
+ else if (e instanceof context_error_1.ContextFileEmptyError) {
21
+ this.log(`Context file "${Context_1.CONTEXT_FILE_PATH}" is empty.`);
22
+ return;
23
+ }
24
+ else if (e instanceof context_error_1.ContextNotFoundError ||
25
+ (fileContent && !fileContent.current)) {
26
+ this.log('No context is set as current. Run "asyncapi config context" to see all available options.');
27
+ return;
28
+ }
29
+ {
30
+ throw e;
31
+ }
32
+ }
33
+ if (fileContent) {
34
+ this.log(`${fileContent.current}: ${fileContent.context}`);
35
+ }
12
36
  });
13
37
  }
14
38
  }
15
39
  exports.default = ContextCurrent;
16
40
  ContextCurrent.description = 'Shows the current context that is being used';
17
41
  ContextCurrent.flags = {
18
- help: core_1.Flags.help({ char: 'h' })
42
+ help: core_1.Flags.help({ char: 'h' }),
19
43
  };
@@ -0,0 +1,13 @@
1
+ import Command from '../../../base';
2
+ export default class ContextEdit extends Command {
3
+ static description: string;
4
+ static flags: {
5
+ help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
6
+ };
7
+ static args: {
8
+ name: string;
9
+ description: string;
10
+ required: boolean;
11
+ }[];
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const core_1 = require("@oclif/core");
5
+ const base_1 = tslib_1.__importDefault(require("../../../base"));
6
+ const Context_1 = require("../../../models/Context");
7
+ const context_error_1 = require("../../../errors/context-error");
8
+ class ContextEdit extends base_1.default {
9
+ run() {
10
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
11
+ const { args } = yield this.parse(ContextEdit);
12
+ const contextName = args['context-name'];
13
+ const newSpecFilePath = args['new-spec-file-path'];
14
+ try {
15
+ yield (0, Context_1.editContext)(contextName, newSpecFilePath);
16
+ this.log(`Edited context "${contextName}".\n\nYou can set it as your current context: asyncapi config context use ${contextName}\nYou can use this context when needed by passing ${contextName} as a parameter: asyncapi validate ${contextName}`);
17
+ }
18
+ catch (e) {
19
+ if (e instanceof (context_error_1.MissingContextFileError || context_error_1.ContextFileWrongFormatError)) {
20
+ this.log('You have no context file configured. Run "asyncapi config context init" to initialize it.');
21
+ return;
22
+ }
23
+ else if (e instanceof context_error_1.ContextFileEmptyError) {
24
+ this.log(`Context file "${Context_1.CONTEXT_FILE_PATH}" is empty.`);
25
+ return;
26
+ }
27
+ {
28
+ throw e;
29
+ }
30
+ }
31
+ });
32
+ }
33
+ }
34
+ exports.default = ContextEdit;
35
+ ContextEdit.description = 'Edit a context in the store';
36
+ ContextEdit.flags = {
37
+ help: core_1.Flags.help({ char: 'h' }),
38
+ };
39
+ ContextEdit.args = [
40
+ { name: 'context-name', description: 'context name', required: true },
41
+ {
42
+ name: 'new-spec-file-path',
43
+ description: 'new file path of the spec file',
44
+ required: true,
45
+ },
46
+ ];
@@ -1,4 +1,5 @@
1
1
  import Command from '../../../base';
2
2
  export default class Context extends Command {
3
+ static description: string;
3
4
  run(): Promise<void>;
4
5
  }
@@ -13,3 +13,4 @@ class Context extends base_1.default {
13
13
  }
14
14
  }
15
15
  exports.default = Context;
16
+ Context.description = 'Manage short aliases for full paths to AsyncAPI documents';
@@ -0,0 +1,14 @@
1
+ import Command from '../../../base';
2
+ export default class ContextInit extends Command {
3
+ static description: string;
4
+ static flags: {
5
+ help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
6
+ };
7
+ static contextFilePathMessage: string;
8
+ static args: {
9
+ name: string;
10
+ description: string;
11
+ required: boolean;
12
+ }[];
13
+ run(): Promise<void>;
14
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const core_1 = require("@oclif/core");
5
+ const base_1 = tslib_1.__importDefault(require("../../../base"));
6
+ const Context_1 = require("../../../models/Context");
7
+ class ContextInit extends base_1.default {
8
+ run() {
9
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
10
+ const { args } = yield this.parse(ContextInit);
11
+ const contextFilePath = args['context-file-path'];
12
+ const contextWritePath = yield (0, Context_1.initContext)(contextFilePath);
13
+ this.log(`Initialized context ${contextWritePath}`);
14
+ });
15
+ }
16
+ }
17
+ exports.default = ContextInit;
18
+ ContextInit.description = 'Initialize context';
19
+ ContextInit.flags = {
20
+ help: core_1.Flags.help({ char: 'h' }),
21
+ };
22
+ ContextInit.contextFilePathMessage = `Specify directory in which context file should be created:
23
+ - current directory : asyncapi config context init . (default)
24
+ - root of current repository : asyncapi config context init ./
25
+ - user's home directory : asyncapi config context init ~`;
26
+ ContextInit.args = [
27
+ {
28
+ name: 'context-file-path',
29
+ description: `${ContextInit.contextFilePathMessage}`,
30
+ required: false,
31
+ },
32
+ ];
@@ -4,18 +4,36 @@ const tslib_1 = require("tslib");
4
4
  const core_1 = require("@oclif/core");
5
5
  const base_1 = tslib_1.__importDefault(require("../../../base"));
6
6
  const Context_1 = require("../../../models/Context");
7
+ const context_error_1 = require("../../../errors/context-error");
7
8
  class ContextList extends base_1.default {
8
9
  run() {
9
10
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
10
- const fileContent = yield (0, Context_1.loadContextFile)();
11
- for (const [contextName, filePath] of Object.entries(fileContent.store)) {
12
- this.log(`${contextName}: ${filePath}`);
11
+ try {
12
+ const fileContent = yield (0, Context_1.loadContextFile)();
13
+ if (yield (0, Context_1.isContextFileEmpty)(fileContent)) {
14
+ this.log(`Context file "${Context_1.CONTEXT_FILE_PATH}" is empty.`);
15
+ return;
16
+ }
17
+ if (fileContent) {
18
+ for (const [contextName, filePath] of Object.entries(fileContent.store)) {
19
+ this.log(`${contextName}: ${filePath}`);
20
+ }
21
+ }
22
+ }
23
+ catch (e) {
24
+ if (e instanceof (context_error_1.MissingContextFileError || context_error_1.ContextFileWrongFormatError)) {
25
+ this.log('You have no context file configured. Run "asyncapi config context init" to initialize it.');
26
+ return;
27
+ }
28
+ {
29
+ throw e;
30
+ }
13
31
  }
14
32
  });
15
33
  }
16
34
  }
17
35
  exports.default = ContextList;
18
- ContextList.description = 'List all the stored context in the store';
36
+ ContextList.description = 'List all the stored contexts in the store';
19
37
  ContextList.flags = {
20
- help: core_1.Flags.help({ char: 'h' })
38
+ help: core_1.Flags.help({ char: 'h' }),
21
39
  };
@@ -4,6 +4,7 @@ const tslib_1 = require("tslib");
4
4
  const core_1 = require("@oclif/core");
5
5
  const base_1 = tslib_1.__importDefault(require("../../../base"));
6
6
  const Context_1 = require("../../../models/Context");
7
+ const context_error_1 = require("../../../errors/context-error");
7
8
  class ContextRemove extends base_1.default {
8
9
  run() {
9
10
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
@@ -13,8 +14,18 @@ class ContextRemove extends base_1.default {
13
14
  yield (0, Context_1.removeContext)(contextName);
14
15
  this.log(`${contextName} successfully deleted`);
15
16
  }
16
- catch (err) {
17
- this.error(err);
17
+ catch (e) {
18
+ if (e instanceof (context_error_1.MissingContextFileError || context_error_1.ContextFileWrongFormatError)) {
19
+ this.log('You have no context file configured. Run "asyncapi config context init" to initialize it.');
20
+ return;
21
+ }
22
+ else if (e instanceof context_error_1.ContextFileEmptyError) {
23
+ this.log(`Context file "${Context_1.CONTEXT_FILE_PATH}" is empty.`);
24
+ return;
25
+ }
26
+ {
27
+ throw e;
28
+ }
18
29
  }
19
30
  });
20
31
  }
@@ -22,8 +33,12 @@ class ContextRemove extends base_1.default {
22
33
  exports.default = ContextRemove;
23
34
  ContextRemove.description = 'Delete a context from the store';
24
35
  ContextRemove.flags = {
25
- help: core_1.Flags.help({ char: 'h' })
36
+ help: core_1.Flags.help({ char: 'h' }),
26
37
  };
27
38
  ContextRemove.args = [
28
- { name: 'context-name', description: 'Name of the context to delete', required: true }
39
+ {
40
+ name: 'context-name',
41
+ description: 'Name of the context to delete',
42
+ required: true,
43
+ },
29
44
  ];
@@ -4,21 +4,41 @@ const tslib_1 = require("tslib");
4
4
  const core_1 = require("@oclif/core");
5
5
  const base_1 = tslib_1.__importDefault(require("../../../base"));
6
6
  const Context_1 = require("../../../models/Context");
7
+ const context_error_1 = require("../../../errors/context-error");
7
8
  class ContextUse extends base_1.default {
8
9
  run() {
9
10
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
10
11
  const { args } = yield this.parse(ContextUse);
11
12
  const contextName = args['context-name'];
12
- yield (0, Context_1.setCurrentContext)(contextName);
13
- this.log(`${contextName} is set as current`);
13
+ try {
14
+ yield (0, Context_1.setCurrentContext)(contextName);
15
+ this.log(`${contextName} is set as current`);
16
+ }
17
+ catch (e) {
18
+ if (e instanceof (context_error_1.MissingContextFileError || context_error_1.ContextFileWrongFormatError)) {
19
+ this.log('You have no context file configured. Run "asyncapi config context init" to initialize it.');
20
+ return;
21
+ }
22
+ else if (e instanceof context_error_1.ContextFileEmptyError) {
23
+ this.log(`Context file "${Context_1.CONTEXT_FILE_PATH}" is empty.`);
24
+ return;
25
+ }
26
+ {
27
+ throw e;
28
+ }
29
+ }
14
30
  });
15
31
  }
16
32
  }
17
33
  exports.default = ContextUse;
18
34
  ContextUse.description = 'Set a context as current';
19
35
  ContextUse.flags = {
20
- help: core_1.Flags.help({ char: 'h' })
36
+ help: core_1.Flags.help({ char: 'h' }),
21
37
  };
22
38
  ContextUse.args = [
23
- { name: 'context-name', description: 'name of the saved context', required: true }
39
+ {
40
+ name: 'context-name',
41
+ description: 'name of the saved context',
42
+ required: true,
43
+ },
24
44
  ];
@@ -8,7 +8,19 @@ export declare class MissingContextFileError extends ContextError {
8
8
  export declare class MissingCurrentContextError extends ContextError {
9
9
  constructor();
10
10
  }
11
- export declare class ContextNotFound extends ContextError {
11
+ export declare class ContextNotFoundError extends ContextError {
12
12
  constructor(contextName: string);
13
13
  }
14
+ export declare class ContextAlreadyExistsError extends ContextError {
15
+ constructor(contextName: string, contextFileName: string);
16
+ }
17
+ export declare class ContextFileWrongFormatError extends ContextError {
18
+ constructor(contextFileName: string);
19
+ }
20
+ export declare class ContextFileEmptyError extends ContextError {
21
+ constructor(contextFileName: string);
22
+ }
23
+ export declare class ContextFileWriteError extends ContextError {
24
+ constructor(contextFileName: string);
25
+ }
14
26
  export {};
@@ -1,8 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ContextNotFound = exports.MissingCurrentContextError = exports.MissingContextFileError = exports.NO_CONTEXTS_SAVED = void 0;
4
- const CONTEXT_NOT_FOUND = (contextName) => `Context "${contextName}" does not exists.`;
5
- const MISSING_CURRENT_CONTEXT = 'No context is set as current, please set a current context.';
3
+ exports.ContextFileWriteError = exports.ContextFileEmptyError = exports.ContextFileWrongFormatError = exports.ContextAlreadyExistsError = exports.ContextNotFoundError = exports.MissingCurrentContextError = exports.MissingContextFileError = exports.NO_CONTEXTS_SAVED = void 0;
6
4
  exports.NO_CONTEXTS_SAVED = `These are your options to specify in the CLI what AsyncAPI file should be used:
7
5
  - You can provide a path to the AsyncAPI file: asyncapi <command> path/to/file/asyncapi.yml
8
6
  - You can provide URL to the AsyncAPI file: asyncapi <command> https://example.com/path/to/file/asyncapi.yml
@@ -10,6 +8,12 @@ exports.NO_CONTEXTS_SAVED = `These are your options to specify in the CLI what A
10
8
  - 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 config context use mycontext
11
9
  - 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
10
  `;
11
+ const MISSING_CURRENT_CONTEXT = 'No context is set as current, please set a current context.';
12
+ const CONTEXT_NOT_FOUND = (contextName) => `Context "${contextName}" does not exist.`;
13
+ const CONTEXT_ALREADY_EXISTS = (contextName, contextFileName) => `Context with name "${contextName}" already exists in context file "${contextFileName}".`;
14
+ const CONTEXT_FILE_WRONG_FORMAT = (contextFileName) => `Context file "${contextFileName}" has wrong format. Make sure your context file follows the structure described in section "Context File structure" at https://www.asyncapi.com/docs/tools/cli/context#context-file-structure`;
15
+ const CONTEXT_FILE_EMPTY = (contextFileName) => `Context file "${contextFileName}" is empty.`;
16
+ const CONTEXT_FILE_WRITE_ERROR = (contextFileName) => `Error writing context file "${contextFileName}".`;
13
17
  class ContextError extends Error {
14
18
  constructor() {
15
19
  super();
@@ -30,10 +34,38 @@ class MissingCurrentContextError extends ContextError {
30
34
  }
31
35
  }
32
36
  exports.MissingCurrentContextError = MissingCurrentContextError;
33
- class ContextNotFound extends ContextError {
37
+ class ContextNotFoundError extends ContextError {
34
38
  constructor(contextName) {
35
39
  super();
36
40
  this.message = CONTEXT_NOT_FOUND(contextName);
37
41
  }
38
42
  }
39
- exports.ContextNotFound = ContextNotFound;
43
+ exports.ContextNotFoundError = ContextNotFoundError;
44
+ class ContextAlreadyExistsError extends ContextError {
45
+ constructor(contextName, contextFileName) {
46
+ super();
47
+ this.message = CONTEXT_ALREADY_EXISTS(contextName, contextFileName);
48
+ }
49
+ }
50
+ exports.ContextAlreadyExistsError = ContextAlreadyExistsError;
51
+ class ContextFileWrongFormatError extends ContextError {
52
+ constructor(contextFileName) {
53
+ super();
54
+ this.message = CONTEXT_FILE_WRONG_FORMAT(contextFileName);
55
+ }
56
+ }
57
+ exports.ContextFileWrongFormatError = ContextFileWrongFormatError;
58
+ class ContextFileEmptyError extends ContextError {
59
+ constructor(contextFileName) {
60
+ super();
61
+ this.message = CONTEXT_FILE_EMPTY(contextFileName);
62
+ }
63
+ }
64
+ exports.ContextFileEmptyError = ContextFileEmptyError;
65
+ class ContextFileWriteError extends ContextError {
66
+ constructor(contextFileName) {
67
+ super();
68
+ this.message = CONTEXT_FILE_WRITE_ERROR(contextFileName);
69
+ }
70
+ }
71
+ exports.ContextFileWriteError = ContextFileWriteError;
@@ -1,4 +1,5 @@
1
1
  export declare const DEFAULT_CONTEXT_FILE_PATH: string;
2
+ export declare let CONTEXT_FILE_PATH: string;
2
3
  export interface IContextFile {
3
4
  current?: string;
4
5
  readonly store: {
@@ -9,9 +10,12 @@ export interface ICurrentContext {
9
10
  readonly current: string;
10
11
  readonly context: string;
11
12
  }
13
+ export declare function initContext(contextFilePath: string): Promise<string>;
12
14
  export declare function loadContext(contextName?: string): Promise<string>;
13
15
  export declare function addContext(contextName: string, pathToFile: string): Promise<void>;
14
16
  export declare function removeContext(contextName: string): Promise<void>;
15
17
  export declare function getCurrentContext(): Promise<ICurrentContext>;
16
18
  export declare function setCurrentContext(contextName: string): Promise<void>;
19
+ export declare function editContext(contextName: string, pathToFile: string): Promise<void>;
17
20
  export declare function loadContextFile(): Promise<IContextFile>;
21
+ export declare function isContextFileEmpty(fileContent: IContextFile): Promise<boolean>;
@@ -1,28 +1,110 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.loadContextFile = exports.setCurrentContext = exports.getCurrentContext = exports.removeContext = exports.addContext = exports.loadContext = exports.DEFAULT_CONTEXT_FILE_PATH = void 0;
3
+ exports.isContextFileEmpty = exports.loadContextFile = exports.editContext = exports.setCurrentContext = exports.getCurrentContext = exports.removeContext = exports.addContext = exports.loadContext = exports.initContext = exports.CONTEXT_FILE_PATH = exports.DEFAULT_CONTEXT_FILE_PATH = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const fs_1 = require("fs");
6
6
  const path = tslib_1.__importStar(require("path"));
7
7
  const os = tslib_1.__importStar(require("os"));
8
8
  const context_error_1 = require("../errors/context-error");
9
9
  const { readFile, writeFile } = fs_1.promises;
10
- const CONTEXT_FILENAME = process.env.CONTEXT_FILENAME || '.asyncapi';
11
- exports.DEFAULT_CONTEXT_FILE_PATH = path.resolve(process.env.CONTEXT_FILE_PATH || os.homedir(), CONTEXT_FILENAME);
10
+ // `repoRootPath` is optimistically assigned current working directory's
11
+ // filesystem path because chances are it will become 'official' repository root
12
+ // down the execution.
13
+ //
14
+ // `REPO_ROOT_PATH` will be converted to a real constant after migration of the
15
+ // codebase to ES2022 or higher and introduction of construction
16
+ //
17
+ // const REPO_ROOT_PATH = await getRepoRootPath(process.cwd());
18
+ //
19
+ // See explanation of the situation with `CONTEXT_FILE_PATH` below.
20
+ let REPO_ROOT_PATH = process.cwd();
21
+ getRepoRootPath(process.cwd());
22
+ const DEFAULT_CONTEXT_FILENAME = '.asyncapi-cli';
23
+ const DEFAULT_CONTEXT_FILE_LOCATION = os.homedir();
24
+ exports.DEFAULT_CONTEXT_FILE_PATH = path.resolve(DEFAULT_CONTEXT_FILE_LOCATION, DEFAULT_CONTEXT_FILENAME);
25
+ const CONTEXT_FILENAME = process.env.CUSTOM_CONTEXT_FILENAME || DEFAULT_CONTEXT_FILENAME;
26
+ const CONTEXT_FILE_LOCATION = process.env.CUSTOM_CONTEXT_FILE_LOCATION || DEFAULT_CONTEXT_FILE_LOCATION;
27
+ // Usage of promises for assignment of their resolved values to constants is
28
+ // known to be troublesome:
29
+ // https://www.reddit.com/r/learnjavascript/comments/p7p7zw/assigning_data_from_a_promise_to_a_constant
30
+ //
31
+ // In this particular case and usage of ES6, there is a race condition during
32
+ // code execution, due to faster assignment of default values to
33
+ // `CONTEXT_FILE_PATH` than resolution of the promise. This is the cause
34
+ // `CONTEXT_FILE_PATH` will always pick default values for context file's path
35
+ // instead of waiting for resolution of the promise from `getContextFilePath()`.
36
+ // The situation might become better with use of top-level await which should
37
+ // pause code execution, until promise in construction
38
+ //
39
+ // const CONTEXT_FILE_PATH = await getContextFilePath() || path.resolve(CONTEXT_FILE_LOCATION, CONTEXT_FILENAME) || DEFAULT_CONTEXT_FILE_PATH;
40
+ //
41
+ // is resolved, but for this to be checked, all codebase (including
42
+ // `@oclif/core`) needs to be migrated to ES2022 or higher.
43
+ //
44
+ // Until then `CONTEXT_FILE_PATH` name is mimicking a `const` while right now it
45
+ // is a `let` reassigned inside of `getContextFilePath()`.
46
+ exports.CONTEXT_FILE_PATH = path.resolve(CONTEXT_FILE_LOCATION, CONTEXT_FILENAME) ||
47
+ exports.DEFAULT_CONTEXT_FILE_PATH;
48
+ // Sonar recognizes next line as a bug `Promises must be awaited, end with a
49
+ // call to .catch, or end with a call to .then with a rejection handler.` but
50
+ // due to absence of top-level await in ES6, this bug cannot be fixed without
51
+ // migrating the codebase to ES2022 or higher, thus suppressing Sonar analysis
52
+ // for this line.
53
+ getContextFilePath(); // NOSONAR
54
+ function initContext(contextFilePath) {
55
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
56
+ const fileContent = {
57
+ store: {},
58
+ };
59
+ let contextWritePath = '';
60
+ // prettier-ignore
61
+ switch (contextFilePath) {
62
+ /* eslint-disable indent */
63
+ case '.':
64
+ contextWritePath = process.cwd() + path.sep + CONTEXT_FILENAME;
65
+ break;
66
+ case './':
67
+ contextWritePath = REPO_ROOT_PATH + path.sep + CONTEXT_FILENAME;
68
+ break;
69
+ // There are two variants of `~` case because tilde expansion in UNIX
70
+ // systems is not a guaranteed feature - sometimes `~` can return just `~`
71
+ // instead of home directory path.
72
+ // https://stackoverflow.com/questions/491877/how-to-find-a-users-home-directory-on-linux-or-unix#comment17161699_492669
73
+ case os.homedir():
74
+ contextWritePath = os.homedir() + path.sep + CONTEXT_FILENAME;
75
+ break;
76
+ case '~':
77
+ contextWritePath = os.homedir() + path.sep + CONTEXT_FILENAME;
78
+ break;
79
+ default:
80
+ contextWritePath = process.cwd() + path.sep + CONTEXT_FILENAME;
81
+ }
82
+ try {
83
+ yield writeFile(contextWritePath, JSON.stringify(fileContent), {
84
+ encoding: 'utf8',
85
+ });
86
+ }
87
+ catch (e) {
88
+ throw new context_error_1.ContextFileWriteError(contextWritePath);
89
+ }
90
+ return contextWritePath;
91
+ });
92
+ }
93
+ exports.initContext = initContext;
12
94
  function loadContext(contextName) {
13
95
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
14
96
  const fileContent = yield loadContextFile();
15
97
  if (contextName) {
16
98
  const context = fileContent.store[String(contextName)];
17
99
  if (!context) {
18
- throw new context_error_1.ContextNotFound(contextName);
100
+ throw new context_error_1.ContextNotFoundError(contextName);
19
101
  }
20
102
  return context;
21
103
  }
22
104
  else if (fileContent.current) {
23
105
  const context = fileContent.store[fileContent.current];
24
106
  if (!context) {
25
- throw new context_error_1.ContextNotFound(fileContent.current);
107
+ throw new context_error_1.ContextNotFoundError(fileContent.current);
26
108
  }
27
109
  return context;
28
110
  }
@@ -32,23 +114,14 @@ function loadContext(contextName) {
32
114
  exports.loadContext = loadContext;
33
115
  function addContext(contextName, pathToFile) {
34
116
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
35
- let fileContent;
36
- try {
37
- fileContent = yield loadContextFile();
38
- }
39
- catch (err) {
40
- if (err instanceof context_error_1.MissingContextFileError) {
41
- fileContent = {
42
- store: {
43
- [contextName]: pathToFile,
44
- }
45
- };
46
- }
47
- else {
48
- throw err;
49
- }
117
+ const fileContent = yield loadContextFile();
118
+ // If context file already has context name similar to the one specified as
119
+ // an argument, notify user about it (throw `ContextAlreadyExistsError`
120
+ // error) and exit.
121
+ if (fileContent.store.hasOwnProperty.call(fileContent.store, contextName)) {
122
+ throw new context_error_1.ContextAlreadyExistsError(contextName, exports.CONTEXT_FILE_PATH);
50
123
  }
51
- fileContent.store[String(contextName)] = pathToFile;
124
+ fileContent.store[String(contextName)] = String(pathToFile);
52
125
  yield saveContextFile(fileContent);
53
126
  });
54
127
  }
@@ -56,8 +129,11 @@ exports.addContext = addContext;
56
129
  function removeContext(contextName) {
57
130
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
58
131
  const fileContent = yield loadContextFile();
132
+ if (yield isContextFileEmpty(fileContent)) {
133
+ throw new context_error_1.ContextFileEmptyError(exports.CONTEXT_FILE_PATH);
134
+ }
59
135
  if (!fileContent.store[String(contextName)]) {
60
- throw new context_error_1.ContextNotFound(contextName);
136
+ throw new context_error_1.ContextNotFoundError(contextName);
61
137
  }
62
138
  if (fileContent.current === contextName) {
63
139
  delete fileContent.current;
@@ -70,6 +146,9 @@ exports.removeContext = removeContext;
70
146
  function getCurrentContext() {
71
147
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
72
148
  const fileContent = yield loadContextFile();
149
+ if (yield isContextFileEmpty(fileContent)) {
150
+ throw new context_error_1.ContextFileEmptyError(exports.CONTEXT_FILE_PATH);
151
+ }
73
152
  const context = yield loadContext();
74
153
  return {
75
154
  current: fileContent.current,
@@ -81,36 +160,162 @@ exports.getCurrentContext = getCurrentContext;
81
160
  function setCurrentContext(contextName) {
82
161
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
83
162
  const fileContent = yield loadContextFile();
163
+ if (yield isContextFileEmpty(fileContent)) {
164
+ throw new context_error_1.ContextFileEmptyError(exports.CONTEXT_FILE_PATH);
165
+ }
84
166
  if (!fileContent.store[String(contextName)]) {
85
- throw new context_error_1.ContextNotFound(contextName);
167
+ throw new context_error_1.ContextNotFoundError(contextName);
86
168
  }
87
- fileContent.current = contextName;
169
+ fileContent.current = String(contextName);
88
170
  yield saveContextFile(fileContent);
89
171
  });
90
172
  }
91
173
  exports.setCurrentContext = setCurrentContext;
174
+ function editContext(contextName, pathToFile) {
175
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
176
+ // The expression is not wrapped in a `try...catch` block and is allowed to
177
+ // throw automatically because it is assumed that `loadContextFile()` works
178
+ // with a 100%-existing valid file in this case, thus if it threw anyway -
179
+ // some REAL error happened and user should know about it.
180
+ const fileContent = yield loadContextFile();
181
+ if (yield isContextFileEmpty(fileContent)) {
182
+ throw new context_error_1.ContextFileEmptyError(exports.CONTEXT_FILE_PATH);
183
+ }
184
+ fileContent.store[String(contextName)] = String(pathToFile);
185
+ yield saveContextFile(fileContent);
186
+ });
187
+ }
188
+ exports.editContext = editContext;
92
189
  function loadContextFile() {
93
190
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
191
+ let fileContent;
192
+ // If the context file cannot be read then it's a 'MissingContextFileError'
193
+ // error.
94
194
  try {
95
- return JSON.parse(yield readFile(exports.DEFAULT_CONTEXT_FILE_PATH, { encoding: 'utf8' }));
195
+ yield readFile(exports.CONTEXT_FILE_PATH, { encoding: 'utf8' });
96
196
  }
97
197
  catch (e) {
98
198
  throw new context_error_1.MissingContextFileError();
99
199
  }
200
+ // If the context file cannot be parsed then it's a
201
+ // 'ContextFileWrongFormatError' error.
202
+ try {
203
+ fileContent = JSON.parse(yield readFile(exports.CONTEXT_FILE_PATH, { encoding: 'utf8' }));
204
+ }
205
+ catch (e) {
206
+ // https://stackoverflow.com/questions/29797946/handling-bad-json-parse-in-node-safely
207
+ throw new context_error_1.ContextFileWrongFormatError(exports.CONTEXT_FILE_PATH);
208
+ }
209
+ // If the context file cannot be validated then it's a
210
+ // 'ContextFileWrongFormatError' error.
211
+ if (!(yield isContextFileValid(fileContent))) {
212
+ throw new context_error_1.ContextFileWrongFormatError(exports.CONTEXT_FILE_PATH);
213
+ }
214
+ return fileContent;
100
215
  });
101
216
  }
102
217
  exports.loadContextFile = loadContextFile;
103
218
  function saveContextFile(fileContent) {
104
219
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
105
220
  try {
106
- writeFile(exports.DEFAULT_CONTEXT_FILE_PATH, JSON.stringify({
221
+ yield writeFile(exports.CONTEXT_FILE_PATH, JSON.stringify({
107
222
  current: fileContent.current,
108
- store: fileContent.store
223
+ store: fileContent.store,
109
224
  }), { encoding: 'utf8' });
110
- return fileContent;
111
225
  }
112
- catch (error) {
113
- return;
226
+ catch (e) {
227
+ throw new context_error_1.ContextFileWriteError(exports.CONTEXT_FILE_PATH);
228
+ }
229
+ });
230
+ }
231
+ function getRepoRootPath(repoRootPath) {
232
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
233
+ // Asynchronous `fs.exists()` is deprecated, asynchronous `fs.stat()`
234
+ // introduces race condition, thus synchronous functions are used.
235
+ let pathToCheck = `${repoRootPath}${path.sep}.git`;
236
+ // If directory where `init` was requested in, happens to contain `.git`
237
+ // directory, then it surely is a root of repository, no need to search
238
+ // further and `REPO_ROOT_PATH` will remain as it was.
239
+ if ((0, fs_1.existsSync)(pathToCheck) && (0, fs_1.lstatSync)(pathToCheck).isDirectory()) {
240
+ return null;
241
+ }
242
+ // Directory where `init` was requested in, did not happen to contain `.git`
243
+ // directory, so preparation for iterating through array of filesystem paths
244
+ // is started.
245
+ const repoRootPathArray = repoRootPath.split(path.sep);
246
+ // Last element in array is thrown away because it is already known that it
247
+ // does not contain directory `.git`.
248
+ repoRootPathArray.pop();
249
+ // Backwards search of the array of filesystem paths will now be performed.
250
+ let i = repoRootPathArray.length - 1;
251
+ while (i > 0) {
252
+ pathToCheck = `${repoRootPathArray.join(path.sep)}${path.sep}.git`;
253
+ if ((0, fs_1.existsSync)(pathToCheck) && (0, fs_1.lstatSync)(pathToCheck).isDirectory()) {
254
+ REPO_ROOT_PATH = repoRootPathArray.join(path.sep);
255
+ return REPO_ROOT_PATH;
256
+ }
257
+ // Last (`0th`) element is an empty string, so if directory `.git` was not
258
+ // found on 1st element (last actual directory in filesystem), the search
259
+ // does not need to continue and `REPO_ROOT_PATH` will remain having the
260
+ // value of current (where `init` was requested in) directory.
261
+ if (i === 1) {
262
+ return null;
263
+ }
264
+ repoRootPathArray.pop();
265
+ i--;
266
+ }
267
+ return null;
268
+ });
269
+ }
270
+ function getContextFilePath() {
271
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
272
+ const currentPath = process
273
+ .cwd()
274
+ .slice(REPO_ROOT_PATH.length + 1)
275
+ .split(path.sep);
276
+ currentPath.unshift(REPO_ROOT_PATH);
277
+ for (let i = currentPath.length; i >= 0; i--) {
278
+ const currentPathString = currentPath[0]
279
+ ? currentPath.join(path.sep) + path.sep + CONTEXT_FILENAME
280
+ : os.homedir() + path.sep + CONTEXT_FILENAME;
281
+ // This `try...catch` is a part of `for` loop and is used only to swallow
282
+ // errors if the file does not exist or cannot be read, to continue
283
+ // uninterrupted execution of the loop.
284
+ try {
285
+ // If a file is found which can be read and passed validation as a
286
+ // legitimate context file, then it is considered a legitimate context
287
+ // file indeed.
288
+ const fileContent = JSON.parse(yield readFile(currentPathString, {
289
+ encoding: 'utf8',
290
+ }));
291
+ if (fileContent &&
292
+ (yield isContextFileValid(fileContent))) {
293
+ exports.CONTEXT_FILE_PATH = currentPathString;
294
+ return exports.CONTEXT_FILE_PATH;
295
+ }
296
+ }
297
+ catch (e) { } // eslint-disable-line
298
+ currentPath.pop();
114
299
  }
300
+ return null;
301
+ });
302
+ }
303
+ function isContextFileValid(fileContent) {
304
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
305
+ // Validation of context file's format against interface `IContextFile`.
306
+ return ([1, 2].includes(Object.keys(fileContent).length) &&
307
+ fileContent.hasOwnProperty.call(fileContent, 'store') &&
308
+ !Array.from(Object.keys(fileContent.store)).find((elem) => typeof elem !== 'string') &&
309
+ !Array.from(Object.values(fileContent.store)).find((elem) => typeof elem !== 'string'));
310
+ });
311
+ }
312
+ function isContextFileEmpty(fileContent) {
313
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
314
+ // If context file contains only one empty property `store` then the whole
315
+ // context file is considered empty.
316
+ return (fileContent &&
317
+ Object.keys(fileContent).length === 1 &&
318
+ Object.keys(fileContent.store).length === 0);
115
319
  });
116
320
  }
321
+ exports.isContextFileEmpty = isContextFileEmpty;
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.51.12",
2
+ "version": "0.52.0",
3
3
  "commands": {
4
4
  "bundle": {
5
5
  "id": "bundle",
@@ -914,7 +914,7 @@
914
914
  },
915
915
  "config:context:add": {
916
916
  "id": "config:context:add",
917
- "description": "Add or modify a context in the store",
917
+ "description": "Add a context to the store",
918
918
  "strict": true,
919
919
  "pluginName": "@asyncapi/cli",
920
920
  "pluginAlias": "@asyncapi/cli",
@@ -961,8 +961,39 @@
961
961
  },
962
962
  "args": {}
963
963
  },
964
+ "config:context:edit": {
965
+ "id": "config:context:edit",
966
+ "description": "Edit a context in the store",
967
+ "strict": true,
968
+ "pluginName": "@asyncapi/cli",
969
+ "pluginAlias": "@asyncapi/cli",
970
+ "pluginType": "core",
971
+ "aliases": [],
972
+ "flags": {
973
+ "help": {
974
+ "name": "help",
975
+ "type": "boolean",
976
+ "char": "h",
977
+ "description": "Show CLI help.",
978
+ "allowNo": false
979
+ }
980
+ },
981
+ "args": {
982
+ "context-name": {
983
+ "name": "context-name",
984
+ "description": "context name",
985
+ "required": true
986
+ },
987
+ "new-spec-file-path": {
988
+ "name": "new-spec-file-path",
989
+ "description": "new file path of the spec file",
990
+ "required": true
991
+ }
992
+ }
993
+ },
964
994
  "config:context": {
965
995
  "id": "config:context",
996
+ "description": "Manage short aliases for full paths to AsyncAPI documents",
966
997
  "strict": true,
967
998
  "pluginName": "@asyncapi/cli",
968
999
  "pluginAlias": "@asyncapi/cli",
@@ -971,9 +1002,35 @@
971
1002
  "flags": {},
972
1003
  "args": {}
973
1004
  },
1005
+ "config:context:init": {
1006
+ "id": "config:context:init",
1007
+ "description": "Initialize context",
1008
+ "strict": true,
1009
+ "pluginName": "@asyncapi/cli",
1010
+ "pluginAlias": "@asyncapi/cli",
1011
+ "pluginType": "core",
1012
+ "aliases": [],
1013
+ "flags": {
1014
+ "help": {
1015
+ "name": "help",
1016
+ "type": "boolean",
1017
+ "char": "h",
1018
+ "description": "Show CLI help.",
1019
+ "allowNo": false
1020
+ }
1021
+ },
1022
+ "args": {
1023
+ "context-file-path": {
1024
+ "name": "context-file-path",
1025
+ "description": "Specify directory in which context file should be created:\n - current directory : asyncapi config context init . (default)\n - root of current repository : asyncapi config context init ./\n - user's home directory : asyncapi config context init ~",
1026
+ "required": false
1027
+ }
1028
+ },
1029
+ "contextFilePathMessage": "Specify directory in which context file should be created:\n - current directory : asyncapi config context init . (default)\n - root of current repository : asyncapi config context init ./\n - user's home directory : asyncapi config context init ~"
1030
+ },
974
1031
  "config:context:list": {
975
1032
  "id": "config:context:list",
976
- "description": "List all the stored context in the store",
1033
+ "description": "List all the stored contexts in the store",
977
1034
  "strict": true,
978
1035
  "pluginName": "@asyncapi/cli",
979
1036
  "pluginAlias": "@asyncapi/cli",
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": "0.51.12",
4
+ "version": "0.52.0",
5
5
  "author": "@asyncapi",
6
6
  "bin": {
7
7
  "asyncapi": "./bin/run"
@@ -150,7 +150,7 @@
150
150
  "release": "semantic-release",
151
151
  "pretest": "npm run build",
152
152
  "test": "npm run test:unit",
153
- "test:unit": "cross-env NODE_ENV=development TEST=1 CONTEXT_FILENAME=\"./test.asyncapi\" CONTEXT_FILE_PATH=\"./\" jest --coverage -i",
153
+ "test:unit": "cross-env NODE_ENV=development TEST=1 CUSTOM_CONTEXT_FILENAME=\"test.asyncapi-cli\" CUSTOM_CONTEXT_FILE_LOCATION=\"\" jest --coverage -i",
154
154
  "get-version": "echo $npm_package_version"
155
155
  },
156
156
  "types": "lib/index.d.ts"