Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Adi-204/cli into inspect
Browse files Browse the repository at this point in the history
  • Loading branch information
Adi-204 committed Jan 24, 2025
2 parents 8dabafe + 07514e6 commit 5f2476c
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 69 deletions.
5 changes: 5 additions & 0 deletions .changeset/five-moles-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@asyncapi/cli": patch
---

Added UI/UX improvements to start command
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @asyncapi/cli

## 2.16.0

### Minor Changes

- a37e124: Deprecate the --file flag in `start studio` command

## 2.15.0

### Minor Changes
Expand Down
4 changes: 2 additions & 2 deletions action-template.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: 'Generator, Validator, Converter and others - all in one for your AsyncAPI docs'
description: 'Use this action to generate docs or code from your AsyncAPI document. Use default templates or provide your custom ones.'
name: 'AsyncAPI CLI Action'
description: 'One stop solution for all your AsyncAPI Specification needs in github actions.'
inputs:
cli_version:
description: 'Version of AsyncAPI CLI to be used. This is only needed if you want to test with a specific version of AsyncAPI CLI. Default is latest which is also the recommended option.'
Expand Down
6 changes: 3 additions & 3 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: 'Generator, Validator, Converter and others - all in one for your AsyncAPI docs'
description: 'Use this action to generate docs or code from your AsyncAPI document. Use default templates or provide your custom ones.'
name: 'AsyncAPI CLI Action'
description: 'One stop solution for all your AsyncAPI Specification needs in github actions.'
inputs:
cli_version:
description: 'Version of AsyncAPI CLI to be used. This is only needed if you want to test with a specific version of AsyncAPI CLI. Default is latest which is also the recommended option.'
Expand Down Expand Up @@ -38,7 +38,7 @@ runs:
using: 'docker'
# This is the image that will be used to run the action.
# IMPORTANT: The version has to be changed manually in your PRs.
image: 'docker://asyncapi/github-action-for-cli:2.15.0'
image: 'docker://asyncapi/github-action-for-cli:2.16.0'
args:
- ${{ inputs.cli_version }}
- ${{ inputs.command }}
Expand Down
62 changes: 33 additions & 29 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,33 +38,35 @@ USAGE
# Commands

<!-- commands -->
* [`asyncapi bundle`](#asyncapi-bundle)
* [`asyncapi config`](#asyncapi-config)
* [`asyncapi config analytics`](#asyncapi-config-analytics)
* [`asyncapi config context`](#asyncapi-config-context)
* [`asyncapi config context add CONTEXT-NAME SPEC-FILE-PATH`](#asyncapi-config-context-add-context-name-spec-file-path)
* [`asyncapi config context current`](#asyncapi-config-context-current)
* [`asyncapi config context edit CONTEXT-NAME NEW-SPEC-FILE-PATH`](#asyncapi-config-context-edit-context-name-new-spec-file-path)
* [`asyncapi config context init [CONTEXT-FILE-PATH]`](#asyncapi-config-context-init-context-file-path)
* [`asyncapi config context list`](#asyncapi-config-context-list)
* [`asyncapi config context remove CONTEXT-NAME`](#asyncapi-config-context-remove-context-name)
* [`asyncapi config context use CONTEXT-NAME`](#asyncapi-config-context-use-context-name)
* [`asyncapi config versions`](#asyncapi-config-versions)
* [`asyncapi convert [SPEC-FILE] [PROXYHOST] [PROXYPORT]`](#asyncapi-convert-spec-file-proxyhost-proxyport)
* [`asyncapi diff OLD NEW`](#asyncapi-diff-old-new)
* [`asyncapi format [SPEC-FILE]`](#asyncapi-format-spec-file)
* [`asyncapi generate`](#asyncapi-generate)
* [`asyncapi generate fromTemplate ASYNCAPI TEMPLATE`](#asyncapi-generate-fromtemplate-asyncapi-template)
* [`asyncapi generate models LANGUAGE FILE`](#asyncapi-generate-models-language-file)
* [`asyncapi new`](#asyncapi-new)
* [`asyncapi new file`](#asyncapi-new-file)
* [`asyncapi new glee`](#asyncapi-new-glee)
* [`asyncapi new template`](#asyncapi-new-template)
* [`asyncapi optimize [SPEC-FILE] [PROXYHOST] [PROXYPORT]`](#asyncapi-optimize-spec-file-proxyhost-proxyport)
* [`asyncapi pretty SPEC-FILE`](#asyncapi-pretty-spec-file)
* [`asyncapi start`](#asyncapi-start)
* [`asyncapi start studio`](#asyncapi-start-studio)
* [`asyncapi validate [SPEC-FILE] [PROXYHOST] [PROXYPORT]`](#asyncapi-validate-spec-file-proxyhost-proxyport)
- [Usage](#usage)
- [Commands](#commands)
- [`asyncapi bundle`](#asyncapi-bundle)
- [`asyncapi config`](#asyncapi-config)
- [`asyncapi config analytics`](#asyncapi-config-analytics)
- [`asyncapi config context`](#asyncapi-config-context)
- [`asyncapi config context add CONTEXT-NAME SPEC-FILE-PATH`](#asyncapi-config-context-add-context-name-spec-file-path)
- [`asyncapi config context current`](#asyncapi-config-context-current)
- [`asyncapi config context edit CONTEXT-NAME NEW-SPEC-FILE-PATH`](#asyncapi-config-context-edit-context-name-new-spec-file-path)
- [`asyncapi config context init [CONTEXT-FILE-PATH]`](#asyncapi-config-context-init-context-file-path)
- [`asyncapi config context list`](#asyncapi-config-context-list)
- [`asyncapi config context remove CONTEXT-NAME`](#asyncapi-config-context-remove-context-name)
- [`asyncapi config context use CONTEXT-NAME`](#asyncapi-config-context-use-context-name)
- [`asyncapi config versions`](#asyncapi-config-versions)
- [`asyncapi convert [SPEC-FILE] [PROXYHOST] [PROXYPORT]`](#asyncapi-convert-spec-file-proxyhost-proxyport)
- [`asyncapi diff OLD NEW`](#asyncapi-diff-old-new)
- [`asyncapi format [SPEC-FILE]`](#asyncapi-format-spec-file)
- [`asyncapi generate`](#asyncapi-generate)
- [`asyncapi generate fromTemplate ASYNCAPI TEMPLATE`](#asyncapi-generate-fromtemplate-asyncapi-template)
- [`asyncapi generate models LANGUAGE FILE`](#asyncapi-generate-models-language-file)
- [`asyncapi new`](#asyncapi-new)
- [`asyncapi new file`](#asyncapi-new-file)
- [`asyncapi new glee`](#asyncapi-new-glee)
- [`asyncapi new template`](#asyncapi-new-template)
- [`asyncapi optimize [SPEC-FILE] [PROXYHOST] [PROXYPORT]`](#asyncapi-optimize-spec-file-proxyhost-proxyport)
- [`asyncapi pretty SPEC-FILE`](#asyncapi-pretty-spec-file)
- [`asyncapi start`](#asyncapi-start)
- [`asyncapi start studio`](#asyncapi-start-studio)
- [`asyncapi validate [SPEC-FILE] [PROXYHOST] [PROXYPORT]`](#asyncapi-validate-spec-file-proxyhost-proxyport)

## `asyncapi bundle`

Expand Down Expand Up @@ -786,10 +788,12 @@ starts a new local instance of Studio

```
USAGE
$ asyncapi start studio [-h] [-f <value>] [-p <value>]
$ asyncapi start studio [SPEC_FILE] [-h] [-p <value>]
ARGUMENTS
SPEC-FILE spec path, url, or context-name
FLAGS
-f, --file=<value> path to the AsyncAPI file to link with Studio
-h, --help Show CLI help.
-p, --port=<value> port in which to start Studio
Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@asyncapi/cli",
"description": "All in one CLI for all AsyncAPI tools",
"version": "2.15.0",
"version": "2.16.0",
"author": "@asyncapi",
"bin": {
"asyncapi": "./bin/run_bin"
Expand Down
34 changes: 29 additions & 5 deletions src/commands/start/studio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,44 @@ import Command from '../../core/base';
import { start as startStudio } from '../../core/models/Studio';
import { load } from '../../core/models/SpecificationFile';
import { studioFlags } from '../../core/flags/start/studio.flags';
import { Args } from '@oclif/core';

export default class StartStudio extends Command {
static description = 'starts a new local instance of Studio';

static flags = studioFlags();

static readonly args = {
'spec-file': Args.string({ description: 'spec path, url, or context-name', required: false }),
};

async run() {
const { flags } = await this.parse(StartStudio);
const filePath = flags.file || (await load()).getFilePath();
const { args, flags } = await this.parse(StartStudio);

if (flags.file) {
this.warn('The file flag has been removed and is being replaced by the argument spec-file. Please pass the filename directly like `asyncapi start studio asyncapi.yml`');
}

let filePath = args['spec-file'] ?? flags.file;

const port = flags.port;

this.specFile = await load(filePath);
if (!filePath) {
try {
filePath = ((await load()).getFilePath());
this.log(`Loaded specification from: ${filePath}`);
} catch (error) {
filePath = '';
this.error('No file specified.');
}
}
try {
this.specFile = await load(filePath);
} catch (error) {
if (filePath) {
this.error(error as Error);
}
}
this.metricsMetadata.port = port;

startStudio(filePath as string, port);
}
}
4 changes: 4 additions & 0 deletions src/core/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ export default abstract class extends Command {
try {
return await super.catch(err);
} catch (e: any) {
if (e.message.includes('EEXIT: 0')) {
process.exitCode = 0;
return;
}
if (e instanceof Error) {
this.logToStderr(`${e.name}: ${e.message}`);
process.exitCode = 1;
Expand Down
2 changes: 1 addition & 1 deletion src/core/flags/start/studio.flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Flags } from '@oclif/core';
export const studioFlags = () => {
return {
help: Flags.help({ char: 'h' }),
file: Flags.string({ char: 'f', description: 'path to the AsyncAPI file to link with Studio' }),
file: Flags.string({ char: 'f', description: 'path to the AsyncAPI file to link with Studio', deprecated: true }),
port: Flags.integer({ char: 'p', description: 'port in which to start Studio' }),
};
};
73 changes: 45 additions & 28 deletions src/core/models/Studio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import chokidar from 'chokidar';
import open from 'open';
import path from 'path';
import { version as studioVersion } from '@asyncapi/studio/package.json';
import { gray } from 'picocolors';
import { blueBright,redBright } from 'picocolors';

const { readFile, writeFile } = fPromises;

Expand All @@ -21,30 +21,32 @@ function isValidFilePath(filePath: string): boolean {
}

export function start(filePath: string, port: number = DEFAULT_PORT): void {
if (!isValidFilePath(filePath)) {
if (filePath && !isValidFilePath(filePath)) {
throw new SpecificationFileNotFound(filePath);
}
chokidar.watch(filePath).on('all', (event, path) => {
switch (event) {
case 'add':
case 'change':
getFileContent(path).then((code:string) => {
if (filePath) {
chokidar.watch(filePath).on('all', (event, path) => {
switch (event) {
case 'add':
case 'change':
getFileContent(path).then((code: string) => {
messageQueue.push(JSON.stringify({
type: 'file:changed',
code,
}));
sendQueuedMessages();
});
break;
case 'unlink':
messageQueue.push(JSON.stringify({
type: 'file:changed',
code,
type: 'file:deleted',
filePath,
}));
sendQueuedMessages();
});
break;
case 'unlink':
messageQueue.push(JSON.stringify({
type: 'file:deleted',
filePath,
}));
sendQueuedMessages();
break;
}
});
break;
}
});
}

const server = createServer((request, response) => {
//not all CLI users use npm. Some package managers put dependencies in different weird places
Expand All @@ -71,18 +73,26 @@ export function start(filePath: string, port: number = DEFAULT_PORT): void {

wsServer.on('connection', (socket: any) => {
sockets.push(socket);
getFileContent(filePath).then((code: string) => {
if (filePath) {
getFileContent(filePath).then((code: string) => {
messageQueue.push(JSON.stringify({
type: 'file:loaded',
code,
}));
sendQueuedMessages();
});
} else {
messageQueue.push(JSON.stringify({
type: 'file:loaded',
code,
code: '',
}));
sendQueuedMessages();
});
}

socket.on('message', (event: string) => {
try {
const json:any = JSON.parse(event);
if (json.type === 'file:update') {
const json: any = JSON.parse(event);
if (filePath && json.type === 'file:update') {
saveFileContent(filePath, json.code);
} else {
console.warn('Live Server: An unknown event has been received. See details:');
Expand All @@ -100,9 +110,16 @@ export function start(filePath: string, port: number = DEFAULT_PORT): void {

server.listen(port, () => {
const url = `http://localhost:${port}?liveServer=${port}&studio-version=${studioVersion}`;
console.log(`Studio is now running at ${url}.`);
console.log(`You can open this URL in your web browser, and if needed, press ${gray('Ctrl + C')} to stop the process.`);
console.log(`Watching changes on file ${filePath}`);
console.log(`🎉 Connected to Live Server running at ${blueBright(url)}.`);
console.log(`🌐 Open this URL in your web browser: ${blueBright(url)}`);
console.log(`🛑 If needed, press ${redBright('Ctrl + C')} to stop the process.`);
if (filePath) {
console.log(`👁️ Watching changes on file ${blueBright(filePath)}`);
} else {
console.warn(
'Warning: No file was provided, and we couldn\'t find a default file (like "asyncapi.yaml" or "asyncapi.json") in the current folder. Starting Studio with a blank workspace.'
);
}
open(url);
});
}
Expand Down

0 comments on commit 5f2476c

Please sign in to comment.