Coder Social home page Coder Social logo

asyncapi / cli Goto Github PK

View Code? Open in Web Editor NEW
172.0 12.0 135.0 22.43 MB

CLI to work with your AsyncAPI files. You can validate them and in the future use a generator and even bootstrap a new file. Contributions are welcomed!

Home Page: https://www.asyncapi.com/tools/cli

License: Apache License 2.0

TypeScript 94.89% JavaScript 4.62% Batchfile 0.04% Dockerfile 0.46%
hacktoberfest cli nodejs typescript get-global-node-release-workflows get-global-releaserc get-global-docs-autoupdate docker

cli's Introduction

AsyncAPI CLI

CLI to work with your AsyncAPI files. Currently under development, we are working to bring more features.

GitHub license PR testing - if Node project npm

Table of contents

Installation

Learn how to install the AsyncAPI CLI by following the instructions in the installation guide.

Usage

The usage guide provides information about different ways to use the CLI.

Contributing

Read CONTRIBUTING guide.

Set up development environment

Follow these steps:

  • Clone the repo.
  • Run npm install to install all the required dependencies
  • Run npm run test to make sure everything is properly set up
  • Run npm run build and then bin/run to try new CLI locally

The UX developed for the CLI should comply with the Command Line Interface Guideline

Command Structure and Patterns

We are following verb + noun and namespace + noun + [verb] pattern for making our commands and arguments. For example asyncapi validate <spec-file-path> and asyncapi config context add <context-name> <spec-file-path>.

Contributors

Thanks go to these wonderful people (emoji key):

Jorge Aguiar MartΓ­n
Jorge Aguiar MartΓ­n

πŸ’» πŸ€” ⚠️ πŸ“–
Lukasz Gornicki
Lukasz Gornicki

πŸ€” πŸ’» πŸ‘€ 🚧
souvik
souvik

πŸ’» πŸ€” ⚠️ πŸ‘€ 🚧 πŸ“–
David Boyne
David Boyne

πŸ’» πŸ€” 🚧
Fran MΓ©ndez
Fran MΓ©ndez

πŸ’» πŸ€” πŸ‘€
Maciej UrbaΕ„czyk
Maciej UrbaΕ„czyk

πŸ‘€ 🚧 πŸ€”
Aayush Kumar Sahu
Aayush Kumar Sahu

πŸ’» ⚠️
Mihir Kulkarni
Mihir Kulkarni

πŸ’»
Abir
Abir

⚠️ πŸ’»
Peter Ramos
Peter Ramos

πŸ’»
Samriddhi
Samriddhi

⚠️
Pranay Kharabe
Pranay Kharabe

πŸ’»
Damilola Oladele
Damilola Oladele

πŸ“–
Abhay Garg
Abhay Garg

πŸ’» ⚠️
Sambhav Gupta
Sambhav Gupta

πŸ’» ⚠️
Hippolyte Vergnol
Hippolyte Vergnol

πŸ’» πŸš‡
Jente Vets
Jente Vets

πŸ’»
Rishi
Rishi

πŸ’»
Ashish Padhy
Ashish Padhy

πŸ’»
Meet Agrawal
Meet Agrawal

πŸš‡
Chinmay Shewale
Chinmay Shewale

πŸ’» ⚠️
Mahfuza Humayra Mohona
Mahfuza Humayra Mohona

πŸ“–
Heiko Henning
Heiko Henning

πŸ’»
Zack_Aayush
Zack_Aayush

πŸ’»
Ayush Nautiyal
Ayush Nautiyal

πŸ’»
AnishKacham
AnishKacham

πŸ’»
Viacheslav Turovskyi
Viacheslav Turovskyi

πŸ’»
Amanpreet Singh Bedi
Amanpreet Singh Bedi

πŸ’»
Debajyoti Halder
Debajyoti Halder

πŸ’»
Savio Dias
Savio Dias

πŸ’»
Jonas Lagoni
Jonas Lagoni

πŸ’» πŸ€” πŸ‘€ ⚠️
Khuda Dad Nomani
Khuda Dad Nomani

πŸ’» πŸ“–
Sergio Moya
Sergio Moya

πŸ’»
Vishal Sharma
Vishal Sharma

πŸ’»

This project follows the all-contributors specification. Contributions of any kind welcome!

cli's People

Contributors

aayushmau5 avatar aayushsaini101 avatar activus-d avatar aeworxet avatar allcontributors[bot] avatar amzani avatar anishkacham avatar asyncapi-bot avatar athul0491 avatar ayushnau avatar boyney123 avatar chinma-yyy avatar cyberhippo avatar dependabot[bot] avatar derberg avatar fmvilas avatar helios2003 avatar imabp avatar jonaslagoni avatar jotamusik avatar kaushik-rishi avatar khudadad414 avatar magicmatatjahu avatar mhmohona avatar peter-rr avatar prayutsu avatar savio629 avatar shurtu-gal avatar smoya avatar souvikns avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cli's Issues

Fetching examples from master causes errors during release

Describe the bug

because of

const SPEC_EXAMPLES_ZIP_URL = 'https://github.com/asyncapi/spec/archive/refs/heads/master.zip';

that is in https://github.com/asyncapi/cli/blob/master/scripts/fetch-asyncapi-example.js#L9 script, we will always have few hours during spec release where CLI will fail in development, on ci/cd. It is because it is fetching stuff from master, that was already released, like now, we released spec 2.3. But CLI is not updated with parser that supports 2.3 cause it is not yet released

so we need to use:

const SPEC_EXAMPLES_ZIP_URL = 'https://github.com/asyncapi/spec/archive/refs/tags/v2.2.0.zip';

but then it means we have to have a manual bump of CLI, unless we improve the script to somehow check what version it should fetch. Like maybe use parser before fetching, to check what is the latest version of the spec that it is using πŸ€”

Improve help message with list of available examples

Reason/Context

Doing asyncapi new --file-name=asyncapi.yml --example=default-example.yaml --no-tty us super cool, but to get default-example.yaml you need to navigate to CLI installation, go into assets/examples and see the list of examples, or check if they will be listed in the interactive mode. You also need to kind of guess if example name is just the file name or filename with its extension.

So great feature is kind of hidden from users.

Description

Now I get:

$  asyncapi new --help

creates a new asyncapi file

USAGE
  $ asyncapi new

OPTIONS
  -e, --example=example      name of the example to use
  -h, --help                 show CLI help
  -n, --file-name=file-name  name of the file
  -p, --port=port            port in which to start Studio
  -s, --studio               open in Studio
  --no-tty                   do not use an interactive terminal

I should get:

$  asyncapi new --help

creates a new asyncapi file

USAGE
  $ asyncapi new

OPTIONS
  -e, --example=example.fileExtension      name of the example to use. Available examples are:
                                                - default-example.yml
                                                - somethingElseWithSpecificProtocol.json (MQTT)
  -h, --help                 show CLI help
  -n, --file-name=file-name  name of the file
  -p, --port=port            port in which to start Studio
  -s, --studio               open in Studio
  --no-tty                   do not use an interactive terminal

Bonus would be to see also example for asyncapi new at the bottom of help like:

EXAMPLES
  asyncapi new               start creation of a file in interactive mode
  asyncapi new --file-name=my-asyncapi.yml --example=default-example.yml --no-tty        create new file with specific name, using one of examples and without interactive emode

should `start studio` try and find a local file?

Reason/Context

Was playing around with the CLI tool and trying to get the studio running on my machine, but when I ran asyncapi start studio it was asking me for context to be set ( I assume that is a CLI thing ).

When I run asyncapi start studio --file=asyncapi.yml it works as expected.

I wonder if the asyncapi start studio should at least try and find a local asyncapi file in the directory before falling back to that context solution?

Why we need this improvement?

Just means we could tell people to run asyncapi start studio in any directory with an AsyncAPI file. Which I think is a better developer experience vs having to know about this context stuff.

Add `start studio` command

In asyncapi/studio#80 has been proposed to add the start studio command, which:

  • should start local instance of our Studio (first we have to implement it)
  • should start local instance of API - asyncapi/studio#86
  • should run a simple server that would support the filesystem to be able to read/write content from/to files

For example, a user could use this command to edit an AsyncAPI document in their favorite IDE, but could also see immediatelly changes in the rendered html-template. The local server would see the changes in the AsyncAPI document - including references to local files - and then pass such a file to the Studio, where the user could use UI to do necessary things like model generation, optimizations, check for changes between versions, etc.

Create `create-template` in AsyncAPI organization

Reason/Context

Stumbled upon this and thought it would be perfect for the generator. We could offer a way to use the init function which will allow people to more quickly setup new templates.

By creating create-template in the AsyncAPI scope we can do the following example commands:

  • npm init @asyncapi/template --react
  • npm init @asyncapi/template --nunjucks
  • npm init @asyncapi/template

Description

This will significantly speed up the process of creating new ones and make it more accessible for people. This is similar to what React have - https://github.com/facebook/create-react-app

Make contexts shareable

Reason/Context

Currently, contexts are stored in the user's home directory. I think it would be cool to store the contexts in the repo directory so they can be shared.

Description

This would work the same way package.json works. The asyncapi CLI would seek for the file (let's call it .asyncapi) in the CWD and, if not found, it would look for it in the parent directory, then the parent of the parent, etc.

The cool thing is that if you don't want to share it, you could just place the file in your home dir, effectively behaving as it is now (global). Also, the global context would be the fallback if a "local" one is not found in a specific project.

Also, this would remove the need to set up contexts yourself manually. Since the file is already in the repo, running asyncapi will already load the context automatically.

Additionally, this eliminates the problem where a user doesn't have permission to write to disk. Very likely to happen in private built in-house CI systems (this was the case at New Relic).

add `watch` option

Reason/Context

We need native way for watching AsyncAPI resource and reiterate given command on it. So basically asyncapi validate -w works in a way that whenever users introduce change in a file, validation runs on it again without invoking it.

sure user can now just install watcher like brew install watch and do watch asyncapi validate, but this should be considered as a temporary workaround that is not a good UX.

Description

When working on this functionality we need to look on current functionality on Generator CLI and its current issues, to fix them here in the CLI -> asyncapi/generator#537 (comment)

Collaboratively editing files through the Studio

Reason/Context

Comes from #78 (comment).

Imagine having the possibility to open Studio locally through the CLI and start editing AsyncAPI files right away. This is what #78 is about.

But in addition, imagine doing that in collaboration with some other folks in real-time.
This is what this feature request is about. Editing AsyncAPI files collaboratively, in real-time, with other users. All through the Studio running on each user machine.

Description

Studio with localtunnel (3)

TL;DR: One user acts as the file owner. Its own CLI file server will be exposed publicly and a public URL will be generated. Others can join editing the same file by running a new CLI command such as start studio <shared-public-url>.

Technical details

In order to expose the file owner CLI file server, we would use Localtunnel, a node package that exposes your localhost to the outside, generating for you a public URL.
It can either run as executable or be invoked through its library, doesn't need anything else (i.e. [ngrok[(ngrok.com) requires the user to be registered). This is ideal for us because we could automate it by just using the node library when a certain command is called, e.g. share studio or similar.

The URL that localtunnel gives, it's a URL that points to their public proxy server (.loca.lt is how URLs look).

Something that is also possible is to host our own copy of the proxy server, which is available here. This will allow us to configure our DNS to point to the proxy server, where generated URLs will then look like <random-id>-studio.asyncapi.io.
However, the pros and cons should be carefully taken into consideration. For example, the cost of maintaining our own service.

Persisting context for multiple projects

context should be optional, and I still should be able to pass context with a flag in case I'm doing some automation, or working with multiple files.

context should also be smart in the way that if I do not have context set, and I do not pass --context command, CLI check if there are files called asyncapi.json/yml/yaml in workdir, and picks them up.

context should most probably be persisted in a file.

I think we should store the context as a key:value pair of the directory the command was invoked to the context path

asyncapi context /path/to/spec/file

this command will save the {process.cwd(): "/path/to/spec/file"}, this way we can persist
the context for that specific folder/workspaces.

not getting the right error when calling `asyncapi validate` or `asyncapi start studio` without context and without file in work dir

When I have no context and no asyncapi file in my work dir I get: ContextError: No context is set as current, please set a current context but should get:

Unable to perform validation. Specify what AsyncAPI file should be validated.
These are your options to specify in the CLI what AsyncAPI file should be used:
  - You can provide a path to the AsyncAPI file: asyncapi validate path/to/file/asyncapi.yml
  - You can also pass a saved context that points to your AsyncAPI file: asyncapi validate mycontext
  - In case you did not specify a context that you want to use, the CLI checks if there is a default context and uses it. To set default context run: asyncapi context use mycontext
  - 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.

I think we need to pull https://github.com/asyncapi/cli/blob/master/src/errors/validation-error.ts#L19 to more generic error and also fix

return await loadFromContext();

more details #130 (comment)

Ability to regenerate functions

Reason/Context

When you run npx create-glee-app it will scaffold your application which is great. But as time goes on and my async API file changes, new functions may be added or ones removed, etc.

I think it would be useful to have a command that could just regenerate the functions?

It could give users the ability to just re-generate functions rather than having to add them and edit them themselfs.

Validation of default files in CWD does not work when I have no files in the context

This is how you can reproduce it:

$ asyncapi context list
myapp1 : /Users/wookiee/sources/cli/test/spec.yaml
$ asyncapi context current
No context is set as current, please set a current context.
$ asyncapi validate
File: /Users/wookiee/sources/cli/asyncapi.yaml successfully validated!
$ asyncapi context remove myapp1
context deleted successfully
$ asyncapi context list
No contexts saved yet.
$ asyncapi validate
No contexts saved yet, run asyncapi --help to know more.

in case I do asyncapi validate and, flags like --context or --files are not passed, and there is no default context + no contexts at all, the validation of default files from CWD should work

Add `asyncapi optimize` command

This issue is for https://www.openforce.tech/ participants. If you do not participate in this even please pick up other issue from this repo, there is plenty of help needed πŸ˜„

Reason/Context

We need to enable the community to use all AsyncAPI tools in CLI if only possible -> https://github.com/asyncapi/optimizer

Description

  • add new command asyncapi optimize that uses https://github.com/asyncapi/optimizer and enable users to optimize single AsyncAPI file
  • user should be able to pass one files to the optimizer asyncapi optimize <context/filepath/url> (getting file from context or filepath or URL is already provided in CLI, you just use load function)
  • by default it would optimize the document and print to the terminal, but user should be able to specify to get only the report, with flag --report
  • by default full optimization is done, but user should be able to specify --rules where user can provide rules that should be applied by optimizer

This issue is for https://www.openforce.tech/ participants. If you do not participate in this even please pick up other issue from this repo, there is plenty of help needed πŸ˜„

@KhudaDad414 pinging you so you are aware πŸ˜„

Separate module for loading spec path automatically

Reason/Context

Every command works on a specification file, so loading the spec file is most of the time the first thing every command is doing so It makes sense to have a hook that returns the spec file.
The different ways the user can pass in the spec file path

  • --file flag
  • --context flag
  • current context
  • working dir

Having this feature will help the user run multiple commands on a spec file without passing in the spec path every time.

asyncapi validate

generator features

CLI will be porting all the functionalities from the generator CLI, so as of now the supported options and commands by the generator CLI are

arguments

<asyncapi> <template>
<asyncapi> - path to the asyncapi file
<template> - template name

Options

  • -d, --disable-hook [hooks...] disable a specific hook type or hooks from a given hook type
  • --debug to enable specific errors in the console
  • -i, --install installs the template and its dependencies (defaults to false)
  • -n, --no-overwrite <glob> glob or path of the file(s) to skip when regenerating
  • -o, --output <outputDir> directory where to put the generated files (defaults to current directory)
  • -p, --param <name=value> additional param to pass to templates
  • --force-write force writing of the generated files to given directory even if it is a git repo with unstaged files or not empty dir (defaults to false)
  • --watch-template watches the template directory and the AsyncAPI document, and re-generate the files when changes occur. Ignores the output directory.
  • --map-base-url <url:folder> maps all schema references from base url to local folder

Running integration testing the global context file is getting updated

Describe the bug

The context service loads from the .asyncapi file that is in the home directory, and when I was developing, It was kind of annoying because after the tests run I always had a new .asyncapi file. If our service takes the global context file's path as an argument I can create other dummy files for testing.

Expected behavior

It would be nice to configure the root context service to load context from different files.

CLI is breaking in production!

Describe the bug

CLI is working fine in the development environment, but in production, it is breaking, no command is usable and most probably this is happening because of some plugin issue.

image

(node:11624) [MODULE_NOT_FOUND] Error Plugin: @asyncapi/cli: Cannot find module '@oclif/plugin-help/lib/command'
Require stack:
- C:\Users\XRIG\AppData\Roaming\npm\node_modules\@asyncapi\cli\node_modules\@fmvilas\oclif-plugin-spaced-commands\lib\hooks\init.js
- C:\Users\XRIG\AppData\Roaming\npm\node_modules\@asyncapi\cli\node_modules\@oclif\config\lib\config.js
- C:\Users\XRIG\AppData\Roaming\npm\node_modules\@asyncapi\cli\node_modules\@oclif\config\lib\index.js
- C:\Users\XRIG\AppData\Roaming\npm\node_modules\@asyncapi\cli\node_modules\@oclif\command\lib\command.js
- C:\Users\XRIG\AppData\Roaming\npm\node_modules\@asyncapi\cli\node_modules\@oclif\command\lib\index.js
- C:\Users\XRIG\AppData\Roaming\npm\node_modules\@asyncapi\cli\bin\run
module: @oclif/[email protected]
task: runHook init
plugin: @asyncapi/cli
root: C:\Users\XRIG\AppData\Roaming\npm\node_modules\@asyncapi\cli
See more details with DEBUG=*
(Use `node --trace-warnings ...` to show where the warning was created)
    Error: Unable to load configured help class "./lib/help", failed with message:
    Cannot find module '@oclif/plugin-help/lib/command'
    Require stack:
    - C:\Users\XRIG\AppData\Roaming\npm\node_modules\@asyncapi\cli\lib\help\CommandHelper.js
    - C:\Users\XRIG\AppData\Roaming\npm\node_modules\@asyncapi\cli\lib\help\index.js
    -
    C:\Users\XRIG\AppData\Roaming\npm\node_modules\@asyncapi\cli\node_modules\@oclif\help\lib\util.js
    - C:\Users\XRIG\AppData\Roaming\npm\node_modules\@asyncapi\cli\node_modules\@oclif\help\lib\comman
    d.js
    -
    C:\Users\XRIG\AppData\Roaming\npm\node_modules\@asyncapi\cli\node_modules\@oclif\help\lib\index.js
    - C:\Users\XRIG\AppData\Roaming\npm\node_modules\@asyncapi\cli\node_modules\@oclif\command\lib\com
    mand.js
    - C:\Users\XRIG\AppData\Roaming\npm\node_modules\@asyncapi\cli\node_modules\@oclif\command\lib\ind
    ex.js
    - C:\Users\XRIG\AppData\Roaming\npm\node_modules\@asyncapi\cli\bin\run

How to Reproduce

Since we are not using oclif-dev pack there is no way to reproduce this error it is just failing in the production, so to reproduce this error -

  • Install cli globally - npm install -g @asyncapi/cli
  • Try printing cli help - asyncapi --help

Add `asyncapi bundle` command

This issue is for https://www.openforce.tech/ participants. If you do not participate in this even please pick up other issue from this repo, there is plenty of help needed πŸ˜„

Reason/Context

We need to enable the community to use all AsyncAPI tools in CLI if only possible -> https://github.com/asyncapi/bundler

Description

  • add new command asyncapi bundle that uses https://github.com/asyncapi/bundler and enable users to bundle multiple AsyncAPI files into one
  • user should be able to pass multiple files to the bundler asyncapi bundler <context-1/filepath1/url1> <context-2/filepath2/url2> <context-3/filepath3/url>3 (getting file from context or filepath or URL is already provided in CLI, you just use load function)

This issue is for https://www.openforce.tech/ participants. If you do not participate in this even please pick up other issue from this repo, there is plenty of help needed πŸ˜„

@Souvikns pinging you so you are aware πŸ˜„

Integrate `asyncapi/diff` in the CLI

Since the asyncapi/diff library is, now, usable, we can integrate it into the AsyncAPI CLI.

My idea for the command usage:

asyncapi diff --files <file1.yml> <file2.yml>
asyncapi diff --contexts file1 file2

So, we need to think about some things:

  • How to output the data
  • Where to output the data
  • The flags which will specify the type of output

How to output the data:

For this, I'm thinking of having a flag --<format>. For started, we can provide output in JSON format. Then, in the future, we can go to HTML based output, markdown, etc.

asyncapi diff --files <file1.yml> <file2.yml> --json
asyncapi diff --files <file1.yml> <file2.yml> --html

Where to output the data:

Now the question arises, where do we output the data. In a file? In the terminal?
Looking at OpenAPI diff tool, we can also provide an optional <file> option along with --<format> flag. --<format> <file>. The default output will be in the terminal.

asyncapi diff --files <file1.yml> <file2.yml> --json <file-output>
asyncapi diff --files <file1.yml> <file2.yml> --html <file-output>

The flags which will specify the type of output:

Since the diff library provides a bunch of helpers function which provide different output(ex. only breaking changes, only non-breaking changes), we can provide a flag to do this through the CLI. The default will provide the full output.
ex.

asyncapi diff --files <file1.yml> <file2.yml> --json <file> --breaking # for breaking changes
asyncapi diff --files <file1.yml> <file2.yml> --json <file> --non-breaking # for non-breaking changes

Any thoughts on this idea?

Add a command to get a version of the CLI

Reason/Context

I want to be able to quickly check what version of CLI am I using. GitHub CLI, kubectl and git support it as a command and a flag (I guess because people are just used to different ways of getting this information)

Description

Please try answering few of those questions

  • we can have it both as command asyncapi version and option asyncapi --version
  • output should say:
    asyncapi version 0.3.0
    https://github.com/asyncapi/cli/releases/tag/v0.3.0
    

Update the missing arguments message

export const MISSING_ARGUMENTS = 'Missing arguments.';

It should say what arguments are missing, For example for the command asyncapi context add <context-name> <spec-path>
The message should be something like this.

Missing arguments: context-name
run asyncapi <command> --help to know more. 

A couple of things needs to be changed -

  • export const MISSING_ARGUMENTS = 'Missing arguments.';
    it has to be converted into a function that would accept parameter_name and command.
  • Then update the Error class
    export class MissingArgumentstError extends Error {
    constructor() {
    super();
    this.message = messages.MISSING_ARGUMENTS;
    }
    }
  • and finally updated all the instances where this error has been thrown.

allow user to pick a template from the `new` command

Reason/Context

Please try answering few of those questions

At the moment the new command generates a basic AsyncAPI for the user, but it would be nice if we asked them some more questions like:

  • What protocol would you like to use (MQTT, WebSockets, HTTP, None)
  • Based on what they select it generates using the correct template.

How will this change help?

I think just more flexibility for the CLI tool and give people more options, users will come from all backgrounds, giving them a helping hand with their chosen protocol might really help.

Make CLI repo hacktoberfest ready.

Why we should take part in Hacktoberfest?

β–Ά Check here

With Hacktoberfest right around the corner, we need to prepare the repository. Things we need to do -

  • Add Hacktoberfest topic to the repository
  • Create Suitable labels for hacktoberfest
    • Hacktoberfest
    • hacktoberfest-accepted
    • spam
  • Update the readme to let others know that we are taking part in hacktoberfest and how they can find suitable issues to contribute.
  • Open up beginner-friendly issues (suggestion required)

Enable users to use CLI without installing NodeJS

Reason/Context

AsyncAPI CLI is supposed to be a tool that exposes all asyncapi tools to the community and makes it easier for the community to work with AsyncAPI files. This means it must be easy to access for folks that are not NodeJS fans and we should not force users to install NodeJS.

Description

Brew for MacOS

Get us in brew and then automate release of upgrades. I already opened a PR Homebrew/homebrew-core#92115 and will drive it forward and then come up with GH workflow to automate release (upgrade PR) of new versions.

Executable for Linux, Mac and Windows

Start using https://github.com/vercel/pkg and enrich our release pipeline (super easy with semantic-releases, I can help) to produce an executable for the CLI + have quick instructions how one can download it and use it

Chocolatey for Windows

Get us in chocolatey and then automate release of upgrades. We need windows users that can lead it.

Improvement with help command

feel wierd, let us leave it as it is, just use ' instead of " and please create a followup issue to clear that out, maybe we actually should have help as command and not flag πŸ€”

Originally posted by @derberg in #14 (comment)

Suggestion: get rid of context or making it optional

Disclaimer: Don't take the tone of this issue too seriously, it's just a representation of a user's frustration, not necessarily mine πŸ˜„ Read this as a story.


Alright! AsyncAPI has a CLI, this is cool. I'm gonna install it and validate my file.

npm install -g @asyncapi/cli

Lovely. Let's now validate my AsyncAPI file:

$ asyncapi validate
No contexts saved yet, run asyncapi --help to know more.

Oh! My fault, I have to provide the file name:

$ asyncapi validate asyncapi.yml
No contexts saved yet, run asyncapi --help to know more.

❗ πŸ˜•

context? what the f*ck is a context? what do they mean by context? ok, let me try with asyncapi --help:

(redacted)
       context
                current  show the current set context
                list     show the list of all stored context
                remove  <context-name> remove a context from the store
                use <context-name>  set any context as current
                add <context-name> <filepath> add/update new context

  Examples
        $ asyncapi context add dummy ./asyncapi.yml
        $ asyncapi validate --context=dummy
        $ asyncapi validate --file=./asyncapi.yml

🀦 Ok, now I know I can create contexts, list contexts, remove contexts, and obviously add them. But I still don't know what is a "context".

HOW DO I VALIDATE MY FILE FOR GOD SAKE!? :rage1:

Oh, wait, from the examples I can guess I need to add my file to a "context" and then run asyncapi validate --context=my-context. Let's do that.

Cool! How do I name my context? Let me think about it well so I don't create a stupid context name for later. Or maybe I can just use "test" for now. I wonder where this information is stored πŸ€”

Anyway, let's just use "test"

asyncapi context add test ./asyncapi.yml
asyncapi validate

Cool, it works now. Oh wait, there was a shorter way! 🀦 I could just have done:

asyncapi validate --file=./asyncapi.yml

Do you see where I'm going? I agree contexts can be useful for experienced and regular users but for newcomers, having to deal with the burden of contexts for simple things like validating a file is such a huge barrier that shouldn't exist.

My proposal is that we remove contexts completely. I think they may make sense in the future β€”who knows?β€” but for now, this is only making things more difficult to reason about. Instead, we can rely on a convention over and then configuration style. For instance:

asyncapi validate

Would look for files with the name asyncapi.yml, asyncapi.yaml, or asyncapi.json in the current directory. If it's found, it validates the file. If it's not, it fails and shows a message saying it couldn't find an asyncapi file and suggesting how to continue.

Following what we discussed on #1, I think asyncapi verb noun should be respected. The noun may be optional when we can easily default to something. Like this case or the case of asyncapi new which could be the equivalent of asyncapi new file. I'm always in favor of options/flags over arguments but if an option is mandatory, it's not an option.

But Fran, my file is called something else, like spec.yml and I still want to benefit from short commands

Cool, now we introduce contexts. The user is going to enable the "contexts" feature knowing what they're doing and on purpose.

$ asyncapi enable contexts
Awesome! From now on, I'll use the `default` context.

Please add your AsyncAPI file to the context:

asyncapi update context your-asyncapi-file.yml
$ asyncapi update context spec.yml
βœ…  Your AsyncAPI file (spec.yml) has been added to the `default` context.

Note I keep using the pattern asyncapi verb noun and I'm always trying to go ahead of the user. For instance, I decided there's going to be a default context (eliminating the need to think about a name). Users should be able to customize the name if they prefer, doing asyncapi enable contexts --context=my-context-name. With asyncapi update context your-asyncapi-file.yml, we could even go further and make the file name optional, and if you run asyncapi update context the CLI will prompt you a file name or fail if stdin is not interactive.

Summary

In short, I think we should be making the UX seamless for newcomers and let experienced and avid users to get the most out of the CLI by letting them configure the behavior. Let's assume defaults and conventions whenever possible. Let's make them configurable via options/flags or interactive terminal when possible.

version command does not work for -v

Describe the bug

As per the help message version command should work for both -V and --version. As of now version command is automatically handled by meow and it only supports for --version string.

How to Reproduce

If you run the command asyncapi --version the version number is output but when you do asyncapi -v you don't get the version number as output.

  • Screenshots

image

Expected behavior

Should print version number for both --version and -v flag.

Enable SonarCloud scans

We scan all AsyncAPI project with SonarCloud to check for code smells, security issues and other things like it. We use their official bot for it. In case of this project we cannot do it -> https://community.sonarsource.com/t/project-is-not-analysed-as-there-is-no-code-but-actually-there-is/48747/4. We would have to make an exception here and configure dedicated GitHub Action.

So my question is:

  1. Do we really need @sindresorhus/tsconfig what is the advantage and what we loose once we remove it?
  2. If we really need this configuration, how about we commit it to the repo? it is just one file, no dev dependencies. I think in this case it is acceptable to have this dev dep committed into the repo

What is your opinion folks? I personally do not like exceptions, they complicate lives, so prefer to use one of above solutions instead of treating CLI as a special project

`asyncapi start studio --file=random-file-that-does-not-exisit` launches studio but then displays a message that the file cannot be watched

Describe the bug

If you run the command asyncapi start studio --file=random-file-that-does-not-exist (for a file that does not exist) the studio will continue to open (with default spec) and the terminal will give an error.

[Error: ENOENT: no such file or directory, open 'exampleasdadsads'] {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: 'random-file-that-does-not-exist'
}

I think it might be a better developer experience if we just failed and not launch the studio?

Update Doc: Instructions for editor setup and auto linting.

Reason/Context

Please try answering a few of those questions

  • Why do we need this improvement?
    Improves Developer Experience, by auto-linting before any commit is made.

  • How will this change help?
    Adds auto-linting before any commit is made locally. Developers need to focus on the code, not on linting.
    Also removes, the occurrences of unnecessary future commits which just includes linting.

  • What is the motivation?
    I had to face linting issues while opening a PR. This will fix a lot of issues, whenever someone commits,

Description

Please try answering few of those questions

  • What changes have to be introduced?
    Setup Husky and configure pre-commit hooks

  • Will this be a breaking change?
    No.

  • How could it be implemented/designed?
    Using Husky Pre-commit hook

User should have an easy way to check a list of all template params without reading docs

Reason/Context

Many templates have very different parameters that they support. Template params are always described in template configuration, to which we have access, so dropping them into the logs should not be a big deal

Description

  • add some meaningful flag that user can use to log params
  • logs that talk about warnings and errors while using template params should always have a hint about how to log all available params

Add `convert` command

Our comverter-js has builded custom CLI, but we should move it to the main CLI.

AC:

  • add new convert command to the CLI
  • add tests for new command
  • update docs (Readme.md) with new command
  • add --help flag
  • to discuss: should we remove --id flag from https://github.com/asyncapi/converter-js CLi? It's only needed between 1.X.X -> 2.X.X.

Usage (my proposition):

asyncapi convert --file {FILE} --to 2.1.0 // convert to the 2.1.0 version
asyncapi convert --file {FILE} --to latest // convert to the latest version of spec
asyncapi convert --file {FILE} // convert to the latest version of spec (omit the `--to` flag)
asyncapi convert --file {FILE} --output {OUTPUT_FILE} // convert and save in the `output`

Maybe we should treat --to as standalone argument?

asyncapi convert --file {FILE} 2.1.0 // convert to the 2.1.0 version

I have also problem with --output flag, because I don't know if we should follow with custom CLI for converter:

image

Any suggestions?

Also we should consider saving the converted spec to the existing context, it means that user will operate on some context and action like:

asyncapi convert --context {CONTEXT} --to 2.1.0

will save the output to the {CONTEXT}.

Some my questions about the future of the command:

  • should we only focus on converting the AsyncAPI, or maybe extend it with converting OpenAPI to the AsyncAPI? and another specs 😏
  • should we also add option to convert the RAML, AVRO etc formats to our Schema Object format - similar to our custom parsers for formats, but as standalone command in our CLI?

@derberg @Souvikns What do you think?

No file extension when user defines the name of the file (using new command)

Describe the bug

When user uses the new command they can provide the filename of the file.

For example, if I put myNewFile as a value, the file is created OK, but no file extension is added.

I think it might be a better experience if we detect if no extension is on the file and just put the yaml extension of the file for them?

Integrate modelina to generate models

Reason/Context

Sometimes you just want to generate the data models for the payloads in your AsyncAPI file, therefore I would like to integrate Modelina with the CLI, so we can offer an easy way for users to generate them.

Description

As a start, I would like to integrate it with no customization, at least for now, so you can only select the output language and nothing more.

But which format of commands is best fitting?

I think something like the following should be fine: asyncapi generate models --language=ts

Support passing url to AsyncAPI file

Reason/Context

The initial version of CLI that we soon merge in supports files from the file system. We should support remote files as parser and generator already support it.

Description

  • User passes --context as https://raw.githubusercontent.com/asyncapi/asyncapi/master/examples/2.0.0/simple.yml.
  • Even though the parser has parseFromURL option, it doesn't mean that all tools in the figure will support it from day 1. For example, the diff library doesn't have to include any dependency to fetch to pull spec from the remote. This means we need to have independent functionality that fetches the spec from remote if we detect that context points to URL

Better way to handle Error messages

I and @magicmatatjahu were talking about this. We can improve the way error messages are handled. Right now there are a bunch of try/catch blocks making the code messy. Also, the error is generated from separated places. Would be better to have a discussion on this.

Architecture refactor proposal

As the result of the live stream @Souvikns and I did together discussing the CLI architecture, we came up with the following suggestion:

Captura de pantalla 2021-10-18 a las 18 39 12

  1. OClif will do all the routing logic (yellow in the diagram).
  2. All the commands logic should be on the command handlers (orange in the diagram).
  3. We extract only 2 entities/models/services/call it whatever you prefer: SpecFile and Context. The first one helps us work with spec files (or even URLs in the future). The logic where we decide if we should read from the context or fall back to implicit names (asyncapi.[yaml,json,yml]) is encapsulated in the SpecFile entity, obviously relying on Context entity for any context-related operation.

We noticed that all commands are related to a specification file (existing or to be created), with the exception of:

  • Removing a context
  • Setting a context as the default one
  • Renaming a context

(and there may be others in the future)

We acknowledge that this architecture is good enough for what we want right now because it's simple and straightforward. If it presents some challenges in the future, we'll look after them and decide if and how to re-architecture. Time will tell :)

CLI Specification

WIP
Setting up a context
The user will be able to set a specification file once and all actions after setting it, will be related to that specification file

Validation

Setup an option to be able to watch a specification file and reload the output when the file change

Generation

New Specification File

Some examples (from @derberg):

asyncapi set context ./asyncapi.yml
asyncapi validate --context=./asyncapi.yml
asyncapi validate #in case context was set
asyncapi create --context=./asyncapi.yml 
asyncapi get channels --context=./asyncapi.yml
asyncapi add channel
asyncapi new #new is not really a verb nor action but makes more sense than create I think

asyncapi generate --template=@asyncapi/html-template --context=./asyncapi.yml --output=./folder
asyncapi generate --model=java --context=./asyncapi.yml --output=./folder
asyncapi generate --model=java --context=./asyncapi.yml#/components/schemas/userCreate --output=./folder
asyncapi generate --model=java --context=(asyncapi get schema userCreate) --output=./folder

Always follow the same structure (verb + noun, noun + verb, or namespace + verb + noun)

I think we should be following a structure, regardless of the command at hand. For instance:

asyncapi validate file

Is following the verb + noun approach. Whereas:

asyncapi context add

Is reversing it to noun + verb.

In #1, I suggested we use verb + noun because it reads naturally. However, after thinking about how to flip contexts and how to occasionally evolve them to accept multiple asyncapi files, it seems the noun + verb might work better here. Just like the Github CLI. So for instance, if I want to add one more asyncapi file to a context, how would it be?

asyncapi add context # that sounds like adding a context not "adding to" a context
asyncapi add-to context # clear but ugly

So maybe it's a better idea to go for something like:

asyncapi context add # Creates a context
asyncapi context add file # Adds a file to a context

In this case, the structure would be something like noun + verb + [noun] (being the last noun optional). To avoid confusion, I suggest we call it namespace + verb + [noun] because the first noun actually works like a namespace.

Find difference between two spec docs

Reason/Context

Would be nice to have a dedicated set of commands related to finding differences in two spec documents and generate UI, or visualizing the changes right in the command line for a quick refference.

This would provide a set of tools that could be used in the development process of event-driven process.

My motivation for raising this issue is to have a discussion on the features that the CLI would be implementing so as to have a clear picture of the AsyncApiDiff's use case

We need a local server for mocking our tests.

Reason/Context

I see that @fmvilas already reviews, so from my point of view I only suggest to log a followup issue, something good for the first contribution, to make sure tests do not rely on external resources. Basically, external resources are risky to use in tests and can cause tests to be flaky, like randomly failing just because the external resource is not available. So follow up should describe that tests should actually start independent server hosting asyncapi file, like we do in parser -> https://github.com/asyncapi/parser-js/blob/master/package.json#L20

This issue is related to #110 (comment)

Hide detailed error when file not found

There are 2 bugs related to some recent functionality:

  1. When you want to add to the context a file that does not exist I get errors like
 ERROR  specification file not found in that path.

 dist/hooks/context/contextService.js:55:19

 52:     }
 53:     addContext(context, key, specFile) {
 54:         if (specFile.isNotValid()) {
 55:             throw new models_1.SpecFileNotFoundError();
 56:         }
 57:         context.store[String(key)] = specFile.getSpecificationName();
 58:         return context;

 - ContextService.addContext (dist/hooks/context/contextService.js:55:19)
 - Object.addContext (dist/hooks/context/hooks.js:45:55)
 - AddContext (dist/components/Context/Context.js:45:60)
 - renderWithHooks (node_modules/react-reconciler/cjs/react-reconciler.development.js:6036:18)
 - mountIndeterminateComponent (node_modules/react-reconciler/cjs/react-reconciler.development.js:8570:13)
 - beginWork$1 (node_modules/react-reconciler/cjs/react-reconciler.development.js:9938:16)
 - Object.invokeGuardedCallbackImpl (node_modules/react-reconciler/cjs/react-reconciler.development.js:11563:10)
 - invokeGuardedCallback (node_modules/react-reconciler/cjs/react-reconciler.development.js:11740:31)
 - beginWork$$1 (node_modules/react-reconciler/cjs/react-reconciler.development.js:15778:7)
 - performUnitOfWork (node_modules/react-reconciler/cjs/react-reconciler.development.js:14696:12)

and instead, I should just see errors like AsyncAPI file not found under ${PATH} path

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.