@asyncapi/cli 0.8.0 → 0.9.2

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.
Files changed (42) hide show
  1. package/README.md +9 -47
  2. package/assets/examples/anyof.yml +31 -0
  3. package/assets/examples/application-headers.yml +83 -0
  4. package/assets/examples/correlation-id.yml +144 -0
  5. package/assets/examples/default-example.yaml +23 -0
  6. package/assets/examples/examples.json +58 -0
  7. package/assets/examples/gitter-streaming.yml +164 -0
  8. package/assets/examples/mercure.yml +49 -0
  9. package/assets/examples/not.yml +24 -0
  10. package/assets/examples/oneof.yml +46 -0
  11. package/assets/examples/rpc-client.yml +69 -0
  12. package/assets/examples/rpc-server.yml +66 -0
  13. package/assets/examples/simple.yml +23 -0
  14. package/assets/examples/slack-rtm.yml +884 -0
  15. package/assets/examples/streetlights-kafka.yml +163 -0
  16. package/assets/examples/streetlights-mqtt.yml +209 -0
  17. package/assets/examples/websocket-gemini.yml +213 -0
  18. package/lib/base.js +2 -1
  19. package/lib/commands/config/context/add.js +2 -1
  20. package/lib/commands/config/context/current.js +2 -1
  21. package/lib/commands/config/context/list.js +2 -1
  22. package/lib/commands/config/context/remove.js +2 -1
  23. package/lib/commands/config/context/use.js +2 -1
  24. package/lib/commands/config/context.js +2 -1
  25. package/lib/commands/config.js +2 -1
  26. package/lib/commands/new.d.ts +17 -0
  27. package/lib/commands/new.js +126 -0
  28. package/lib/commands/start/studio.d.ts +12 -0
  29. package/lib/commands/start/studio.js +23 -0
  30. package/lib/commands/validate.js +3 -2
  31. package/lib/errors/specification-file.d.ts +1 -1
  32. package/lib/errors/specification-file.js +6 -1
  33. package/lib/models/Context.js +8 -7
  34. package/lib/models/SpecificationFile.js +16 -8
  35. package/lib/models/Studio.d.ts +2 -0
  36. package/lib/models/Studio.js +110 -0
  37. package/oclif.manifest.json +1 -1
  38. package/package.json +16 -12
  39. package/lib/help/command.d.ts +0 -5
  40. package/lib/help/command.js +0 -58
  41. package/lib/help/index.d.ts +0 -8
  42. package/lib/help/index.js +0 -49
@@ -0,0 +1,17 @@
1
+ import { flags } from '@oclif/command';
2
+ import Command from '../base';
3
+ export default class New extends Command {
4
+ static description: string;
5
+ static flags: {
6
+ help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
7
+ 'file-name': flags.IOptionFlag<string | undefined>;
8
+ example: flags.IOptionFlag<string | undefined>;
9
+ studio: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
10
+ port: import("@oclif/parser/lib/flags").IOptionFlag<number | undefined>;
11
+ 'no-tty': import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
12
+ };
13
+ static args: never[];
14
+ run(): Promise<void>;
15
+ runInteractive(): Promise<void>;
16
+ createAsyncapiFile(fileName: string, selectedTemplate: string): Promise<void>;
17
+ }
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const fs_1 = require("fs");
5
+ const command_1 = require("@oclif/command");
6
+ const base_1 = tslib_1.__importDefault(require("../base"));
7
+ const inquirer = tslib_1.__importStar(require("inquirer"));
8
+ const Studio_1 = require("../models/Studio");
9
+ const path_1 = require("path");
10
+ const { writeFile, readFile } = fs_1.promises;
11
+ const DEFAULT_ASYNCAPI_FILE_NAME = 'asyncapi.yaml';
12
+ const DEFAULT_ASYNCAPI_TEMPLATE = 'default-example.yaml';
13
+ class New extends base_1.default {
14
+ async run() {
15
+ const { flags } = this.parse(New);
16
+ const isTTY = process.stdout.isTTY;
17
+ if (!flags['no-tty'] && isTTY) {
18
+ return this.runInteractive();
19
+ }
20
+ const fileName = flags['file-name'] || DEFAULT_ASYNCAPI_FILE_NAME;
21
+ const template = flags['example'] || DEFAULT_ASYNCAPI_TEMPLATE;
22
+ this.createAsyncapiFile(fileName, template);
23
+ if (flags.studio) {
24
+ if (isTTY) {
25
+ Studio_1.start(fileName, flags.port || Studio_1.DEFAULT_PORT);
26
+ }
27
+ else {
28
+ this.warn('Warning: --studio flag was passed but the terminal is not interactive. Ignoring...');
29
+ }
30
+ }
31
+ }
32
+ async runInteractive() {
33
+ const { flags } = this.parse(New);
34
+ let fileName = flags['file-name'];
35
+ let selectedTemplate = flags['example'];
36
+ let openStudio = flags.studio;
37
+ let examples = [];
38
+ const questions = [];
39
+ if (!fileName) {
40
+ questions.push({
41
+ name: 'filename',
42
+ message: 'name of the file?',
43
+ type: 'input',
44
+ default: DEFAULT_ASYNCAPI_FILE_NAME,
45
+ });
46
+ }
47
+ try {
48
+ const exampleFiles = await readFile(path_1.resolve(__dirname, '../../assets/examples/examples.json'), { encoding: 'utf8' });
49
+ examples = JSON.parse(exampleFiles);
50
+ }
51
+ catch (error) {
52
+ // no examples found
53
+ }
54
+ if (!selectedTemplate && examples.length > 0) {
55
+ questions.push({
56
+ name: 'use-example',
57
+ message: 'would you like to start your new file from one of our examples?',
58
+ type: 'confirm',
59
+ default: true,
60
+ });
61
+ questions.push({
62
+ type: 'list',
63
+ name: 'selectedTemplate',
64
+ message: 'What example would you like to use?',
65
+ choices: examples,
66
+ when: (answers) => {
67
+ return answers['use-example'];
68
+ },
69
+ });
70
+ }
71
+ if (openStudio === undefined) {
72
+ questions.push({
73
+ name: 'studio',
74
+ message: 'open in Studio?',
75
+ type: 'confirm',
76
+ default: true,
77
+ });
78
+ }
79
+ if (questions.length) {
80
+ const answers = await inquirer.prompt(questions);
81
+ if (!fileName) {
82
+ fileName = answers.filename;
83
+ }
84
+ if (!selectedTemplate) {
85
+ selectedTemplate = answers.selectedTemplate;
86
+ }
87
+ if (openStudio === undefined) {
88
+ openStudio = answers.studio;
89
+ }
90
+ }
91
+ fileName = fileName || DEFAULT_ASYNCAPI_FILE_NAME;
92
+ selectedTemplate = selectedTemplate || DEFAULT_ASYNCAPI_TEMPLATE;
93
+ await this.createAsyncapiFile(fileName, selectedTemplate);
94
+ if (openStudio) {
95
+ Studio_1.start(fileName, flags.port || Studio_1.DEFAULT_PORT);
96
+ }
97
+ }
98
+ async createAsyncapiFile(fileName, selectedTemplate) {
99
+ const asyncApiFile = await readFile(path_1.resolve(__dirname, '../../assets/examples/', selectedTemplate), { encoding: 'utf8' });
100
+ const fileNameHasFileExtension = fileName.includes('.');
101
+ const fileNameToWriteToDisk = fileNameHasFileExtension ? fileName : `${fileName}.yaml`;
102
+ try {
103
+ const content = await readFile(fileNameToWriteToDisk, { encoding: 'utf8' });
104
+ if (content !== '') {
105
+ console.log(`File ${fileNameToWriteToDisk} already exists. Ignoring...`);
106
+ return;
107
+ }
108
+ }
109
+ catch (e) {
110
+ // File does not exist. Proceed creating it...
111
+ }
112
+ await writeFile(fileNameToWriteToDisk, asyncApiFile, { encoding: 'utf8' });
113
+ console.log(`Created file ${fileNameToWriteToDisk}...`);
114
+ }
115
+ }
116
+ exports.default = New;
117
+ New.description = 'creates a new asyncapi file';
118
+ New.flags = {
119
+ help: command_1.flags.help({ char: 'h' }),
120
+ 'file-name': command_1.flags.string({ char: 'n', description: 'name of the file' }),
121
+ example: command_1.flags.string({ char: 'e', description: 'name of the example to use' }),
122
+ studio: command_1.flags.boolean({ char: 's', description: 'open in Studio' }),
123
+ port: command_1.flags.integer({ char: 'p', description: 'port in which to start Studio' }),
124
+ 'no-tty': command_1.flags.boolean({ description: 'do not use an interactive terminal' }),
125
+ };
126
+ New.args = [];
@@ -0,0 +1,12 @@
1
+ import { flags } from '@oclif/command';
2
+ import Command from '../../base';
3
+ export default class StartStudio extends Command {
4
+ static description: string;
5
+ static flags: {
6
+ help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
7
+ file: flags.IOptionFlag<string | undefined>;
8
+ port: import("@oclif/parser/lib/flags").IOptionFlag<number | undefined>;
9
+ };
10
+ static args: never[];
11
+ run(): Promise<void>;
12
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const command_1 = require("@oclif/command");
5
+ const base_1 = tslib_1.__importDefault(require("../../base"));
6
+ const Studio_1 = require("../../models/Studio");
7
+ const SpecificationFile_1 = require("../../models/SpecificationFile");
8
+ class StartStudio extends base_1.default {
9
+ async run() {
10
+ const { flags } = this.parse(StartStudio);
11
+ const filePath = flags.file || (await SpecificationFile_1.load()).getPath();
12
+ const port = flags.port;
13
+ Studio_1.start(filePath, port);
14
+ }
15
+ }
16
+ exports.default = StartStudio;
17
+ StartStudio.description = 'starts a new local instance of Studio';
18
+ StartStudio.flags = {
19
+ help: command_1.flags.help({ char: 'h' }),
20
+ file: command_1.flags.string({ char: 'f', description: 'path to the AsyncAPI file to link with Studio' }),
21
+ port: command_1.flags.integer({ char: 'p', description: 'port in which to start Studio' }),
22
+ };
23
+ StartStudio.args = [];
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
3
4
  const command_1 = require("@oclif/command");
4
- const parser = require("@asyncapi/parser");
5
- const base_1 = require("../base");
5
+ const parser = tslib_1.__importStar(require("@asyncapi/parser"));
6
+ const base_1 = tslib_1.__importDefault(require("../base"));
6
7
  const validation_error_1 = require("../errors/validation-error");
7
8
  const SpecificationFile_1 = require("../models/SpecificationFile");
8
9
  const specification_file_1 = require("../errors/specification-file");
@@ -2,6 +2,6 @@ declare class SpecificationFileError extends Error {
2
2
  constructor();
3
3
  }
4
4
  export declare class SpecificationFileNotFound extends SpecificationFileError {
5
- constructor(filePath: string);
5
+ constructor(filePath?: string);
6
6
  }
7
7
  export {};
@@ -10,7 +10,12 @@ class SpecificationFileError extends Error {
10
10
  class SpecificationFileNotFound extends SpecificationFileError {
11
11
  constructor(filePath) {
12
12
  super();
13
- this.message = `File ${filePath} does not exist.`;
13
+ if (filePath) {
14
+ this.message = `File ${filePath} does not exist.`;
15
+ }
16
+ else {
17
+ this.message = 'We could not find any AsyncAPI file.';
18
+ }
14
19
  }
15
20
  }
16
21
  exports.SpecificationFileNotFound = SpecificationFileNotFound;
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.loadContextFile = exports.setCurrentContext = exports.getCurrentContext = exports.removeContext = exports.addContext = exports.loadContext = exports.DEFAULT_CONTEXT_FILE_PATH = void 0;
4
+ const tslib_1 = require("tslib");
4
5
  const fs_1 = require("fs");
5
- const path = require("path");
6
- const os = require("os");
6
+ const path = tslib_1.__importStar(require("path"));
7
+ const os = tslib_1.__importStar(require("os"));
7
8
  const context_error_1 = require("../errors/context-error");
8
9
  const { readFile, writeFile } = fs_1.promises;
9
10
  const isTestEnv = !!process.env.TEST;
@@ -12,7 +13,7 @@ exports.DEFAULT_CONTEXT_FILE_PATH = path.resolve(os.homedir(), CONTEXT_FILENAME)
12
13
  async function loadContext(contextName) {
13
14
  const fileContent = await loadContextFile();
14
15
  if (contextName) {
15
- const context = fileContent.store[contextName];
16
+ const context = fileContent.store[String(contextName)];
16
17
  if (!context) {
17
18
  throw new context_error_1.ContextNotFound(contextName);
18
19
  }
@@ -45,19 +46,19 @@ async function addContext(contextName, pathToFile) {
45
46
  throw err;
46
47
  }
47
48
  }
48
- fileContent.store[contextName] = pathToFile;
49
+ fileContent.store[String(contextName)] = pathToFile;
49
50
  await saveContextFile(fileContent);
50
51
  }
51
52
  exports.addContext = addContext;
52
53
  async function removeContext(contextName) {
53
54
  const fileContent = await loadContextFile();
54
- if (!fileContent.store[contextName]) {
55
+ if (!fileContent.store[String(contextName)]) {
55
56
  throw new context_error_1.ContextNotFound(contextName);
56
57
  }
57
58
  if (fileContent.current === contextName) {
58
59
  delete fileContent.current;
59
60
  }
60
- delete fileContent.store[contextName];
61
+ delete fileContent.store[String(contextName)];
61
62
  await saveContextFile(fileContent);
62
63
  }
63
64
  exports.removeContext = removeContext;
@@ -72,7 +73,7 @@ async function getCurrentContext() {
72
73
  exports.getCurrentContext = getCurrentContext;
73
74
  async function setCurrentContext(contextName) {
74
75
  const fileContent = await loadContextFile();
75
- if (!fileContent.store[contextName]) {
76
+ if (!fileContent.store[String(contextName)]) {
76
77
  throw new context_error_1.ContextNotFound(contextName);
77
78
  }
78
79
  fileContent.current = contextName;
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.fileExists = exports.nameType = exports.load = void 0;
4
+ const tslib_1 = require("tslib");
4
5
  const fs_1 = require("fs");
5
- const path = require("path");
6
+ const path = tslib_1.__importStar(require("path"));
6
7
  const Context_1 = require("./Context");
7
- const validation_error_1 = require("../errors/validation-error");
8
8
  const specification_file_1 = require("../errors/specification-file");
9
9
  const { readFile, lstat } = fs_1.promises;
10
10
  const allowedFileNames = [
@@ -36,16 +36,18 @@ async function load(filePathOrContextName) {
36
36
  return new SpecificationFile(filePathOrContextName);
37
37
  }
38
38
  try {
39
- return loadFromContext();
39
+ return await loadFromContext();
40
40
  }
41
41
  catch (e) {
42
- // We did our best...
42
+ if (!filePathOrContextName) {
43
+ throw e;
44
+ }
43
45
  }
44
46
  const autoDetectedSpecFile = await detectSpecFile();
45
47
  if (autoDetectedSpecFile) {
46
48
  return new SpecificationFile(autoDetectedSpecFile);
47
49
  }
48
- throw new validation_error_1.ValidationError({ type: 'no-spec-found' });
50
+ throw new specification_file_1.SpecificationFileNotFound();
49
51
  }
50
52
  exports.load = load;
51
53
  async function nameType(name) {
@@ -80,8 +82,14 @@ async function loadFromContext(contextName) {
80
82
  return new SpecificationFile(context);
81
83
  }
82
84
  async function detectSpecFile() {
83
- const existingFileNames = allowedFileNames.map(async (filename) => {
84
- return (await fileExists(path.resolve(process.cwd(), filename))) ? filename : undefined;
85
- });
85
+ const existingFileNames = await Promise.all(allowedFileNames.map(async (filename) => {
86
+ try {
87
+ const exists = await fileExists(path.resolve(process.cwd(), filename));
88
+ return exists ? filename : undefined;
89
+ }
90
+ catch (e) {
91
+ // We did our best...
92
+ }
93
+ }));
86
94
  return existingFileNames.find(filename => filename !== undefined);
87
95
  }
@@ -0,0 +1,2 @@
1
+ export declare const DEFAULT_PORT = 3210;
2
+ export declare function start(filePath: string, port?: number): void;
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.start = exports.DEFAULT_PORT = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const fs_1 = require("fs");
6
+ const path_1 = require("path");
7
+ const http_1 = require("http");
8
+ const serve_handler_1 = tslib_1.__importDefault(require("serve-handler"));
9
+ const ws_1 = require("ws");
10
+ const chokidar_1 = tslib_1.__importDefault(require("chokidar"));
11
+ const open_1 = tslib_1.__importDefault(require("open"));
12
+ const { readFile, writeFile } = fs_1.promises;
13
+ const sockets = [];
14
+ const messageQueue = [];
15
+ exports.DEFAULT_PORT = 3210;
16
+ function start(filePath, port = exports.DEFAULT_PORT) {
17
+ chokidar_1.default.watch(filePath).on('all', (event, path) => {
18
+ switch (event) {
19
+ case 'add':
20
+ case 'change':
21
+ getFileContent(path).then((code) => {
22
+ messageQueue.push(JSON.stringify({
23
+ type: 'file:changed',
24
+ code,
25
+ }));
26
+ sendQueuedMessages();
27
+ });
28
+ break;
29
+ case 'unlink':
30
+ messageQueue.push(JSON.stringify({
31
+ type: 'file:deleted',
32
+ filePath,
33
+ }));
34
+ sendQueuedMessages();
35
+ break;
36
+ }
37
+ });
38
+ const server = http_1.createServer((request, response) => {
39
+ return serve_handler_1.default(request, response, {
40
+ public: path_1.resolve(__dirname, '../../node_modules/@asyncapi/studio/build'),
41
+ });
42
+ });
43
+ server.on('upgrade', (request, socket, head) => {
44
+ if (request.url === '/live-server') {
45
+ wsServer.handleUpgrade(request, socket, head, (sock) => {
46
+ wsServer.emit('connection', sock, request);
47
+ });
48
+ }
49
+ else {
50
+ socket.destroy();
51
+ }
52
+ });
53
+ const wsServer = new ws_1.WebSocketServer({ noServer: true });
54
+ wsServer.on('connection', (socket) => {
55
+ sockets.push(socket);
56
+ getFileContent(filePath).then((code) => {
57
+ messageQueue.push(JSON.stringify({
58
+ type: 'file:loaded',
59
+ code,
60
+ }));
61
+ sendQueuedMessages();
62
+ });
63
+ socket.on('message', (event) => {
64
+ try {
65
+ const json = JSON.parse(event);
66
+ if (json.type === 'file:update') {
67
+ saveFileContent(filePath, json.code);
68
+ }
69
+ else {
70
+ console.warn('Live Server: An unknown event has been received. See details:');
71
+ console.log(json);
72
+ }
73
+ }
74
+ catch (e) {
75
+ console.error(`Live Server: An invalid event has been received. See details:\n${event}`);
76
+ }
77
+ });
78
+ });
79
+ wsServer.on('close', (socket) => {
80
+ sockets.splice(sockets.findIndex(s => s === socket));
81
+ });
82
+ server.listen(port, () => {
83
+ const url = `http://localhost:${port}?liveServer=${port}`;
84
+ console.log(`Studio is running at ${url}`);
85
+ console.log(`Watching changes on file ${filePath}`);
86
+ open_1.default(url);
87
+ });
88
+ }
89
+ exports.start = start;
90
+ function sendQueuedMessages() {
91
+ while (messageQueue.length && sockets.length) {
92
+ const nextMessage = messageQueue.shift();
93
+ for (const socket of sockets) {
94
+ socket.send(nextMessage);
95
+ }
96
+ }
97
+ }
98
+ function getFileContent(filePath) {
99
+ return new Promise((resolve) => {
100
+ readFile(filePath, { encoding: 'utf8' })
101
+ .then((code) => {
102
+ resolve(code);
103
+ })
104
+ .catch(console.error);
105
+ });
106
+ }
107
+ function saveFileContent(filePath, fileContent) {
108
+ writeFile(filePath, fileContent, { encoding: 'utf8' })
109
+ .catch(console.error);
110
+ }
@@ -1 +1 @@
1
- {"version":"0.8.0","commands":{"config":{"id":"config","description":"access configs","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"validate":{"id":"validate","description":"validate asyncapi file","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"spec-file","description":"spec path or context-name","required":false}]},"config:context":{"id":"config:context","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"config:context:add":{"id":"config:context:add","description":"Add or modify a context in the store","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"context-name","description":"context name","required":true},{"name":"spec-file-path","description":"file path of the spec file","required":true}]},"config:context:current":{"id":"config:context:current","description":"Shows the current context that is being used","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"config:context:list":{"id":"config:context:list","description":"List all the stored context in the store","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"config:context:remove":{"id":"config:context:remove","description":"Delete a context from the store","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"context-name","description":"Name of the context to delete","required":true}]},"config:context:use":{"id":"config:context:use","description":"Set a context as current","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"context-name","description":"name of the saved context","required":true}]}}}
1
+ {"version":"0.9.2","commands":{"config":{"id":"config","description":"access configs","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"new":{"id":"new","description":"creates a new asyncapi file","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"file-name":{"name":"file-name","type":"option","char":"n","description":"name of the file"},"example":{"name":"example","type":"option","char":"e","description":"name of the example to use"},"studio":{"name":"studio","type":"boolean","char":"s","description":"open in Studio","allowNo":false},"port":{"name":"port","type":"option","char":"p","description":"port in which to start Studio"},"no-tty":{"name":"no-tty","type":"boolean","description":"do not use an interactive terminal","allowNo":false}},"args":[]},"validate":{"id":"validate","description":"validate asyncapi file","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"spec-file","description":"spec path or context-name","required":false}]},"config:context":{"id":"config:context","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"start:studio":{"id":"start:studio","description":"starts a new local instance of Studio","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"file":{"name":"file","type":"option","char":"f","description":"path to the AsyncAPI file to link with Studio"},"port":{"name":"port","type":"option","char":"p","description":"port in which to start Studio"}},"args":[]},"config:context:add":{"id":"config:context:add","description":"Add or modify a context in the store","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"context-name","description":"context name","required":true},{"name":"spec-file-path","description":"file path of the spec file","required":true}]},"config:context:current":{"id":"config:context:current","description":"Shows the current context that is being used","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"config:context:list":{"id":"config:context:list","description":"List all the stored context in the store","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"config:context:remove":{"id":"config:context:remove","description":"Delete a context from the store","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"context-name","description":"Name of the context to delete","required":true}]},"config:context:use":{"id":"config:context:use","description":"Set a context as current","pluginName":"@asyncapi/cli","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"context-name","description":"name of the saved context","required":true}]}}}
package/package.json CHANGED
@@ -1,25 +1,30 @@
1
1
  {
2
2
  "name": "@asyncapi/cli",
3
3
  "description": "All in one CLI for all AsyncAPI tools",
4
- "version": "0.8.0",
4
+ "version": "0.9.2",
5
5
  "author": "@asyncapi",
6
6
  "bin": {
7
7
  "asyncapi": "./bin/run"
8
8
  },
9
9
  "bugs": "https://github.com/asyncapi/cli/issues",
10
10
  "dependencies": {
11
- "@asyncapi/parser": "^1.9.1",
11
+ "@asyncapi/parser": "^1.11.0",
12
+ "@asyncapi/studio": "^0.3.2",
12
13
  "@fmvilas/oclif-plugin-spaced-commands": "^1.0.4",
13
14
  "@oclif/command": "^1.8.0",
14
15
  "@oclif/config": "^1.17.0",
15
16
  "@oclif/plugin-help": "^3.2.3",
16
- "chalk": "^4.1.0",
17
- "indent-string": "^4.0.0",
18
- "lodash.template": "^4.4.0",
17
+ "@types/inquirer": "^8.1.3",
18
+ "@types/ws": "^8.2.0",
19
+ "chokidar": "^3.5.2",
20
+ "inquirer": "^8.2.0",
21
+ "open": "^8.4.0",
19
22
  "reflect-metadata": "^0.1.13",
20
- "strip-ansi": "^6.0.0",
23
+ "request": "^2.88.2",
24
+ "serve-handler": "^6.1.3",
21
25
  "tslib": "^1.14.1",
22
- "wrap-ansi": "^4.0.0"
26
+ "unzipper": "^0.10.11",
27
+ "ws": "^8.2.3"
23
28
  },
24
29
  "devDependencies": {
25
30
  "@oclif/dev-cli": "^1.26.0",
@@ -29,10 +34,9 @@
29
34
  "@semantic-release/npm": "^7.1.3",
30
35
  "@semantic-release/release-notes-generator": "^9.0.2",
31
36
  "@types/chai": "^4.2.21",
32
- "@types/lodash.template": "^4.4.4",
33
37
  "@types/mocha": "^5.2.7",
34
38
  "@types/node": "^10.17.60",
35
- "@types/wrap-ansi": "^8.0.1",
39
+ "@types/serve-handler": "^6.1.1",
36
40
  "@typescript-eslint/eslint-plugin": "^4.28.4",
37
41
  "@typescript-eslint/parser": "^4.28.4",
38
42
  "acorn": "^8.5.0",
@@ -61,6 +65,7 @@
61
65
  "files": [
62
66
  "/bin",
63
67
  "/lib",
68
+ "/assets",
64
69
  "/npm-shrinkwrap.json",
65
70
  "/oclif.manifest.json"
66
71
  ],
@@ -76,8 +81,7 @@
76
81
  "plugins": [
77
82
  "@oclif/plugin-help",
78
83
  "@fmvilas/oclif-plugin-spaced-commands"
79
- ],
80
- "helpClass": "./src/help/index.ts"
84
+ ]
81
85
  },
82
86
  "publishConfig": {
83
87
  "access": "public"
@@ -105,7 +109,7 @@
105
109
  },
106
110
  "repository": "asyncapi/cli",
107
111
  "scripts": {
108
- "build": "tsc",
112
+ "build": "node scripts/fetch-asyncapi-example.js && tsc",
109
113
  "bump:version": "npm --no-git-tag-version --allow-same-version version $VERSION",
110
114
  "dev": "tsc --watch",
111
115
  "generate:assets": "npm run generate:readme:toc",
@@ -1,5 +0,0 @@
1
- import CommandHelp from '@oclif/plugin-help/lib/command';
2
- import * as Config from '@oclif/config';
3
- export default class CommandHelper extends CommandHelp {
4
- flags(flags: Config.Command.Flag[]): string | undefined;
5
- }
@@ -1,58 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const command_1 = require("@oclif/plugin-help/lib/command");
4
- const list_1 = require("@oclif/plugin-help/lib/list");
5
- const chalk = require("chalk");
6
- const indent = require("indent-string");
7
- const { underline, bold, } = chalk;
8
- const { dim, } = chalk;
9
- class CommandHelper extends command_1.default {
10
- flags(flags) {
11
- if (flags.length === 0) {
12
- return;
13
- }
14
- const body = list_1.renderList(flags.map(flag => {
15
- var _a;
16
- let left = flag.helpLabel;
17
- if (!left) {
18
- const label = [];
19
- if (flag.char) {
20
- label.push(`-${flag.char[0]}`);
21
- }
22
- if (flag.name) {
23
- if (flag.type === 'boolean' && flag.allowNo) {
24
- label.push(`--[no-]${flag.name.trim()}`);
25
- }
26
- else {
27
- label.push(`--${flag.name.trim()}`);
28
- }
29
- }
30
- left = label.join(', ');
31
- }
32
- if (flag.type === 'option') {
33
- let value = flag.helpValue || flag.name;
34
- if (!flag.helpValue && flag.options) {
35
- value = flag.options.join('|');
36
- }
37
- if (!value.includes('|')) {
38
- value = underline(value);
39
- }
40
- left += `=${value}`;
41
- }
42
- let right = flag.description || '';
43
- // `flag.default` is not always a string (typing bug), hence `toString()`
44
- if (flag.type === 'option' && (flag.default || ((_a = flag.default) === null || _a === void 0 ? void 0 : _a.toString()) === '0')) {
45
- right = `[default: ${flag.default}] ${right}`;
46
- }
47
- if (flag.required) {
48
- right = `(required) ${right}`;
49
- }
50
- return [left, dim(right.trim())];
51
- }), { stripAnsi: this.opts.stripAnsi, maxWidth: this.opts.maxWidth - 2 });
52
- return [
53
- bold('FLAGS'),
54
- indent(body, 2),
55
- ].join('\n');
56
- }
57
- }
58
- exports.default = CommandHelper;
@@ -1,8 +0,0 @@
1
- import Help from '@oclif/plugin-help';
2
- import * as Config from '@oclif/config';
3
- export default class CustomHelp extends Help {
4
- showRootHelp(): void;
5
- showTopicHelp(topic: Config.Topic): void;
6
- showCommandHelp(command: Config.Command): void;
7
- formatCommand(command: Config.Command): string;
8
- }