@asyncapi/cli 0.51.13 → 0.52.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.
- package/assets/create-glee-app/templates/default/package-lock.json +54 -54
- package/lib/commands/config/context/add.js +21 -5
- package/lib/commands/config/context/current.js +27 -3
- package/lib/commands/config/context/edit.d.ts +13 -0
- package/lib/commands/config/context/edit.js +46 -0
- package/lib/commands/config/context/index.d.ts +1 -0
- package/lib/commands/config/context/index.js +1 -0
- package/lib/commands/config/context/init.d.ts +14 -0
- package/lib/commands/config/context/init.js +32 -0
- package/lib/commands/config/context/list.js +23 -5
- package/lib/commands/config/context/remove.js +19 -4
- package/lib/commands/config/context/use.js +24 -4
- package/lib/errors/context-error.d.ts +13 -1
- package/lib/errors/context-error.js +37 -5
- package/lib/models/Context.d.ts +4 -0
- package/lib/models/Context.js +235 -30
- package/oclif.manifest.json +60 -3
- package/package.json +3 -3
|
@@ -203,9 +203,9 @@
|
|
|
203
203
|
}
|
|
204
204
|
},
|
|
205
205
|
"node_modules/@asyncapi/generator-react-sdk/node_modules/semver": {
|
|
206
|
-
"version": "5.7.
|
|
207
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.
|
|
208
|
-
"integrity": "sha512-
|
|
206
|
+
"version": "5.7.2",
|
|
207
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
|
208
|
+
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
|
209
209
|
"bin": {
|
|
210
210
|
"semver": "bin/semver"
|
|
211
211
|
}
|
|
@@ -510,9 +510,9 @@
|
|
|
510
510
|
}
|
|
511
511
|
},
|
|
512
512
|
"node_modules/@babel/core/node_modules/semver": {
|
|
513
|
-
"version": "6.3.
|
|
514
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.
|
|
515
|
-
"integrity": "sha512-
|
|
513
|
+
"version": "6.3.1",
|
|
514
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
|
515
|
+
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
|
516
516
|
"peer": true,
|
|
517
517
|
"bin": {
|
|
518
518
|
"semver": "bin/semver.js"
|
|
@@ -581,9 +581,9 @@
|
|
|
581
581
|
}
|
|
582
582
|
},
|
|
583
583
|
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
|
|
584
|
-
"version": "6.3.
|
|
585
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.
|
|
586
|
-
"integrity": "sha512-
|
|
584
|
+
"version": "6.3.1",
|
|
585
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
|
586
|
+
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
|
587
587
|
"bin": {
|
|
588
588
|
"semver": "bin/semver.js"
|
|
589
589
|
}
|
|
@@ -616,9 +616,9 @@
|
|
|
616
616
|
}
|
|
617
617
|
},
|
|
618
618
|
"node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": {
|
|
619
|
-
"version": "6.3.
|
|
620
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.
|
|
621
|
-
"integrity": "sha512-
|
|
619
|
+
"version": "6.3.1",
|
|
620
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
|
621
|
+
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
|
622
622
|
"bin": {
|
|
623
623
|
"semver": "bin/semver.js"
|
|
624
624
|
}
|
|
@@ -640,9 +640,9 @@
|
|
|
640
640
|
}
|
|
641
641
|
},
|
|
642
642
|
"node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": {
|
|
643
|
-
"version": "6.3.
|
|
644
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.
|
|
645
|
-
"integrity": "sha512-
|
|
643
|
+
"version": "6.3.1",
|
|
644
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
|
645
|
+
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
|
646
646
|
"bin": {
|
|
647
647
|
"semver": "bin/semver.js"
|
|
648
648
|
}
|
|
@@ -664,9 +664,9 @@
|
|
|
664
664
|
}
|
|
665
665
|
},
|
|
666
666
|
"node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": {
|
|
667
|
-
"version": "6.3.
|
|
668
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.
|
|
669
|
-
"integrity": "sha512-
|
|
667
|
+
"version": "6.3.1",
|
|
668
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
|
669
|
+
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
|
670
670
|
"bin": {
|
|
671
671
|
"semver": "bin/semver.js"
|
|
672
672
|
}
|
|
@@ -2007,9 +2007,9 @@
|
|
|
2007
2007
|
}
|
|
2008
2008
|
},
|
|
2009
2009
|
"node_modules/@babel/preset-env/node_modules/semver": {
|
|
2010
|
-
"version": "6.3.
|
|
2011
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.
|
|
2012
|
-
"integrity": "sha512-
|
|
2010
|
+
"version": "6.3.1",
|
|
2011
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
|
2012
|
+
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
|
2013
2013
|
"bin": {
|
|
2014
2014
|
"semver": "bin/semver.js"
|
|
2015
2015
|
}
|
|
@@ -4243,9 +4243,9 @@
|
|
|
4243
4243
|
}
|
|
4244
4244
|
},
|
|
4245
4245
|
"node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
|
|
4246
|
-
"version": "6.3.
|
|
4247
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.
|
|
4248
|
-
"integrity": "sha512-
|
|
4246
|
+
"version": "6.3.1",
|
|
4247
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
|
4248
|
+
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
|
4249
4249
|
"bin": {
|
|
4250
4250
|
"semver": "bin/semver.js"
|
|
4251
4251
|
}
|
|
@@ -10334,9 +10334,9 @@
|
|
|
10334
10334
|
}
|
|
10335
10335
|
},
|
|
10336
10336
|
"node_modules/semver": {
|
|
10337
|
-
"version": "7.
|
|
10338
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-7.
|
|
10339
|
-
"integrity": "sha512-
|
|
10337
|
+
"version": "7.5.4",
|
|
10338
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
|
10339
|
+
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
|
|
10340
10340
|
"dependencies": {
|
|
10341
10341
|
"lru-cache": "^6.0.0"
|
|
10342
10342
|
},
|
|
@@ -11877,9 +11877,9 @@
|
|
|
11877
11877
|
}
|
|
11878
11878
|
},
|
|
11879
11879
|
"semver": {
|
|
11880
|
-
"version": "5.7.
|
|
11881
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.
|
|
11882
|
-
"integrity": "sha512-
|
|
11880
|
+
"version": "5.7.2",
|
|
11881
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
|
11882
|
+
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="
|
|
11883
11883
|
},
|
|
11884
11884
|
"source-map": {
|
|
11885
11885
|
"version": "0.5.7",
|
|
@@ -12139,9 +12139,9 @@
|
|
|
12139
12139
|
},
|
|
12140
12140
|
"dependencies": {
|
|
12141
12141
|
"semver": {
|
|
12142
|
-
"version": "6.3.
|
|
12143
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.
|
|
12144
|
-
"integrity": "sha512-
|
|
12142
|
+
"version": "6.3.1",
|
|
12143
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
|
12144
|
+
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
|
12145
12145
|
"peer": true
|
|
12146
12146
|
}
|
|
12147
12147
|
}
|
|
@@ -12194,9 +12194,9 @@
|
|
|
12194
12194
|
}
|
|
12195
12195
|
},
|
|
12196
12196
|
"semver": {
|
|
12197
|
-
"version": "6.3.
|
|
12198
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.
|
|
12199
|
-
"integrity": "sha512-
|
|
12197
|
+
"version": "6.3.1",
|
|
12198
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
|
12199
|
+
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
|
|
12200
12200
|
},
|
|
12201
12201
|
"yallist": {
|
|
12202
12202
|
"version": "3.1.1",
|
|
@@ -12222,9 +12222,9 @@
|
|
|
12222
12222
|
},
|
|
12223
12223
|
"dependencies": {
|
|
12224
12224
|
"semver": {
|
|
12225
|
-
"version": "6.3.
|
|
12226
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.
|
|
12227
|
-
"integrity": "sha512-
|
|
12225
|
+
"version": "6.3.1",
|
|
12226
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
|
12227
|
+
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
|
|
12228
12228
|
}
|
|
12229
12229
|
}
|
|
12230
12230
|
},
|
|
@@ -12239,9 +12239,9 @@
|
|
|
12239
12239
|
},
|
|
12240
12240
|
"dependencies": {
|
|
12241
12241
|
"semver": {
|
|
12242
|
-
"version": "6.3.
|
|
12243
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.
|
|
12244
|
-
"integrity": "sha512-
|
|
12242
|
+
"version": "6.3.1",
|
|
12243
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
|
12244
|
+
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
|
|
12245
12245
|
}
|
|
12246
12246
|
}
|
|
12247
12247
|
},
|
|
@@ -12259,9 +12259,9 @@
|
|
|
12259
12259
|
},
|
|
12260
12260
|
"dependencies": {
|
|
12261
12261
|
"semver": {
|
|
12262
|
-
"version": "6.3.
|
|
12263
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.
|
|
12264
|
-
"integrity": "sha512-
|
|
12262
|
+
"version": "6.3.1",
|
|
12263
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
|
12264
|
+
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
|
|
12265
12265
|
}
|
|
12266
12266
|
}
|
|
12267
12267
|
},
|
|
@@ -13144,9 +13144,9 @@
|
|
|
13144
13144
|
},
|
|
13145
13145
|
"dependencies": {
|
|
13146
13146
|
"semver": {
|
|
13147
|
-
"version": "6.3.
|
|
13148
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.
|
|
13149
|
-
"integrity": "sha512-
|
|
13147
|
+
"version": "6.3.1",
|
|
13148
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
|
13149
|
+
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
|
|
13150
13150
|
}
|
|
13151
13151
|
}
|
|
13152
13152
|
},
|
|
@@ -14875,9 +14875,9 @@
|
|
|
14875
14875
|
},
|
|
14876
14876
|
"dependencies": {
|
|
14877
14877
|
"semver": {
|
|
14878
|
-
"version": "6.3.
|
|
14879
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.
|
|
14880
|
-
"integrity": "sha512-
|
|
14878
|
+
"version": "6.3.1",
|
|
14879
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
|
14880
|
+
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
|
|
14881
14881
|
}
|
|
14882
14882
|
}
|
|
14883
14883
|
},
|
|
@@ -19393,9 +19393,9 @@
|
|
|
19393
19393
|
}
|
|
19394
19394
|
},
|
|
19395
19395
|
"semver": {
|
|
19396
|
-
"version": "7.
|
|
19397
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-7.
|
|
19398
|
-
"integrity": "sha512-
|
|
19396
|
+
"version": "7.5.4",
|
|
19397
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
|
19398
|
+
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
|
|
19399
19399
|
"requires": {
|
|
19400
19400
|
"lru-cache": "^6.0.0"
|
|
19401
19401
|
}
|
|
@@ -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
|
-
|
|
14
|
-
|
|
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
|
|
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
|
-
{
|
|
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
|
-
|
|
11
|
-
|
|
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
|
+
];
|
|
@@ -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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
|
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 (
|
|
17
|
-
|
|
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
|
-
{
|
|
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
|
-
|
|
13
|
-
|
|
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
|
-
{
|
|
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
|
|
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.
|
|
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
|
|
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.
|
|
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;
|
package/lib/models/Context.d.ts
CHANGED
|
@@ -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>;
|
package/lib/models/Context.js
CHANGED
|
@@ -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
|
-
|
|
11
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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 (
|
|
113
|
-
|
|
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;
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
2
|
+
"version": "0.52.1",
|
|
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
|
|
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
|
|
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.
|
|
4
|
+
"version": "0.52.1",
|
|
5
5
|
"author": "@asyncapi",
|
|
6
6
|
"bin": {
|
|
7
7
|
"asyncapi": "./bin/run"
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"@asyncapi/converter": "^1.3.1",
|
|
14
14
|
"@asyncapi/diff": "^0.4.1",
|
|
15
15
|
"@asyncapi/generator": "^1.10.11",
|
|
16
|
-
"@asyncapi/modelina": "^1.8.
|
|
16
|
+
"@asyncapi/modelina": "^1.8.9",
|
|
17
17
|
"@asyncapi/openapi-schema-parser": "^3.0.3",
|
|
18
18
|
"@asyncapi/optimizer": "^0.2.1",
|
|
19
19
|
"@asyncapi/parser": "^2.1.0",
|
|
@@ -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
|
|
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"
|