Files
2023-01-03 00:04:38 +00:00

560 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SwaggerEditor
SwaggerEditor is using **forked** Create React App as it's building infrastructure.
## Table of Contents
- [Getting started](#getting-started)
- [Installation](#installation)
- [Usage](#usage)
- [Development](#development)
- [Prerequisites](#prerequisites)
- [Setting up](#setting-up)
- [Setting up on MacOS](#setting-up-on-macos)
- [npm scripts](#npm-scripts)
- [Build artifacts](#build-artifacts)
- [Package mapping](#package-mapping)
- [Documentation](#documentation)
- [Docker](#docker)
- [License](#license)
## Getting started
### Installation
SwaggerEditor is currently hosted on [GitHub packages registry](https://docs.github.com/en/packages/learn-github-packages/introduction-to-github-packages).
For installing SwaggerEditor npm package from GitHub packages registry, create `.npmrc` file in your current directory and add
the following line to it:
```
@swagger-api:registry=https://npm.pkg.github.com
```
#### Prerequisites
Using [Node.js](https://nodejs.org/) [active LTS version](https://nodejs.org/en/about/releases/) is recommended.
[node-gyp](https://www.npmjs.com/package/node-gyp) is used to build some fragments that require [Python 3.x](https://www.python.org/downloads/).
[emscripten](https://emscripten.org/docs/getting_started/downloads.html) or [docker](https://www.docker.com/) needs to be installed
on your operating system as well. We strongly recommend going with a docker option.
You can now install SwaggerEditor package using `npm`:
```sh
$ npm install @swagger-api/swagger-editor
````
For more information about installing npm packages from GitHub packages registry please visit [Installing a package](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-npm-registry#installing-a-package)
section in their documentation.
### Usage
Install the package:
```sh
$ npm install @swagger-api/swagger-editor
````
Use the package in you application:
**index.js**:
```js
import React from 'react';
import ReactDOM from 'react-dom';
import SwaggerEditor from '@swagger-api/swagger-editor';
import '@swagger-api/swagger-editor/swagger-editor.css';
const url = "https://raw.githubusercontent.com/asyncapi/spec/v2.2.0/examples/streetlights-kafka.yml";
const MyApp = () => (
<div>
<h1>SwaggerEditor Integration</h1>
<SwaggerEditor url={url} />
</div>
);
self.MonacoEnvironment = {
/**
* We're building into the dist/ folder. When application starts on
* URL=https://example.com then SwaggerEditor will look for
* `apidom.worker.js` on https://example.com/dist/apidom.worker.js and
* `editor.worker` on https://example.com/dist/editor.worker.js.
*/
baseUrl: `${document.baseURI || location.href}/dist/`,
}
ReactDOM.render(<MyApp />, document.getElementById('swagger-editor'));
```
**webpack.config.js** (webpack@5)
Install dependencies needed for webpack@5 to properly build SwaggerEditor.
```sh
$ npm i stream-browserify --save-dev
$ npm i process --save-dev
$ npm i https-browserify --save-dev
$ npm i stream-http --save-dev
$ npm i util --save-dev
```
```js
const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'production',
entry: {
app: './index.js',
'apidom.worker': '@swagger-api/swagger-editor/apidom.worker',
'editor.worker': '@swagger-api/swagger-editor/editor.worker',
},
output: {
globalObject: 'self',
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
resolve: {
fallback: {
path: false,
fs: false,
http: require.resolve('stream-http'), // required for asyncapi parser
https: require.resolve('https-browserify'), // required for asyncapi parser
stream: require.resolve('stream-browserify'),
util: require.resolve('util'),
zlib: false,
},
alias: {
// This alias doesn't pull any languages into bundles and works as monaco-editor-core was installed
'monaco-editor$': 'monaco-editor/esm/vs/editor/edcore.main.js',
// This alias make sure we don't pull two different versions of monaco-editor
'monaco-editor': '/node_modules/monaco-editor',
},
},
plugins: [
new webpack.ProvidePlugin({
process: 'process/browser.js',
Buffer: ['buffer', 'Buffer'],
}),
],
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
/**
* The default way in which webpack loads wasm files wont work in a worker,
* so we will have to disable webpacks default handling of wasm files and
* then fetch the wasm file by using the file path that we get using file-loader.
*
* Resource: https://pspdfkit.com/blog/2020/webassembly-in-a-web-worker/
*
* Alternatively, WASM file can be bundled directly into JavaScript bundle as data URLs.
* This configuration reduces the complexity of WASM file loading
* but increases the overal bundle size:
*
* {
* test: /\.wasm$/,
* type: 'asset/inline',
* }
*/
{
test: /\.wasm$/,
loader: 'file-loader',
type: 'javascript/auto', // this disables webpacks default handling of wasm
},
]
}
};
```
Alternative **webpack.config.js** (webpack@5)
We've already built Web Workers fragments for you, and they're located inside our npm distribution
package in `dist/umd/` directory. In order to avoid complexity of building the Web Worker fragments you can
use those fragments directly. This setup will work both for **production** and **development** (webpack-dev-server)
and will significantly shorten your build process.
Install `copy-webpack-plugin` and other needed dependencies.
```sh
$ npm i copy-webpack-plugin --save-dev
$ npm i stream-browserify --save-dev
$ npm i process --save-dev
$ npm i https-browserify --save-dev
$ npm i stream-http --save-dev
$ npm i util --save-dev
```
```js
const path = require('path');
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
mode: 'production',
entry: {
app: './index.js',
},
output: {
globalObject: 'self',
filename: 'static/js/[name].js',
path: path.resolve(__dirname, 'dist')
},
resolve: {
fallback: {
path: false,
fs: false,
http: require.resolve('stream-http'), // required for asyncapi parser
https: require.resolve('https-browserify'), // required for asyncapi parser
stream: require.resolve('stream-browserify'),
util: require.resolve('util'),
zlib: false,
},
alias: {
// This alias doesn't pull any languages into bundles and works as monaco-editor-core was installed
'monaco-editor$': 'monaco-editor/esm/vs/editor/edcore.main.js',
// This alias make sure we don't pull two different versions of monaco-editor
'monaco-editor': '/node_modules/monaco-editor',
}
},
plugins: [
new webpack.ProvidePlugin({
process: 'process/browser.js',
Buffer: ['buffer', 'Buffer'],
}),
new CopyWebpackPlugin({
patterns: [
{
from: 'node_modules/@swagger-api/swagger-editor/dist/umd/apidom.worker.js',
to: 'static/js',
},
{
from: 'node_modules/@swagger-api/swagger-editor/dist/umd/editor.worker.js',
to: 'static/js',
}
]
}),
],
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
};
```
## Development
### Prerequisites
[Node.js](https://nodejs.org/) >= 16.13.0 and `npm >= 8.1.0` are the minimum required versions that this repo runs on.
We recommend using the latest version of Node.js@16 though. We're using [node-gyp](https://www.npmjs.com/package/node-gyp) to build some fragments that require [Python 3.x](https://www.python.org/downloads/).
[emscripten](https://emscripten.org/docs/getting_started/downloads.html) or [docker](https://www.docker.com/) needs to be installed
on your operating system. We strongly recommend going with a docker option.
### Setting up
If you use [nvm](https://github.com/nvm-sh/nvm), running following command inside this repository
will automatically pick the right Node.js version for you:
```sh
$ nvm use
```
This repository is using npm packages from [https://www.npmjs.com/](npmjs.com) and [GitHub packages registry](https://docs.github.com/en/packages/learn-github-packages/introduction-to-github-packages).
To successfully install npm packages that SwaggerEditor requires, you need to [Authenticate to GitHub Packages](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-npm-registry#authenticating-to-github-packages).
We recommend that you [authenticate using GitHub PAT (Personal Access Token)](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-npm-registry#authenticating-with-a-personal-access-token).
**Create a new ~/.npmrc file if one doesn't exist.**
```sh
//npm.pkg.github.com/:_authToken=TOKEN
```
Alternatively, to authenticate by logging in to npm, use the `npm login` command,
replacing USERNAME with your GitHub username, TOKEN with your personal access token (classic),
and PUBLIC-EMAIL-ADDRESS with your email address.
```sh
$ npm login --scope=@swagger-api --registry=https://npm.pkg.github.com
> Username: USERNAME
> Password: TOKEN
> Email: PUBLIC-EMAIL-ADDRESS
```
Run the following commands to set up the repository for local development:
```sh
$ git submodule init
$ git submodule update
$ npm i
$ npm start
```
#### Setting up on MacOS
With the combination of MacOS and Node.js 16, there is a known compatibility issue of installing and building the `tree-sitter` dependency. The workaround is to globally install `>=npm@8.1.x` (for lerna/apidom monorepo) but use Node.js 14 to install/build tree-sitter.
Although the prerequisite is to use Node@16.13, at this point we don't rely on any specific feature from Node.js 16.13 (except for `>=npm@8.1.x`).
```sh
$ npm install -g npm
$ npm --version
```
Assuming we are using [nvm](https://github.com/nvm-sh/nvm) to manage Node versions:
```sh
$ nvm use v14
```
Then follow the installation steps above.
### npm scripts
**Lint**
```sh
$ npm run lint
```
**Runs unit and integration tests**
```sh
$ npm test
```
**Runs E2E Cypress tests**
Usage in **development** environment:
```sh
$ npm run cy:dev
```
Usage in **Continuos Integration (CI)** environment:
```sh
$ npm run cy:ci
```
**Build**
```sh
$ npm run build
````
This script will build all the SwaggerEditor build artifacts - `app`, `esm` and `umd`.
### Build artifacts
After building artifacts, every two new directories will be created: `build/` and `dist/`.
**build/**
```sh
$ npm run build:app
$ npm run build:app:serve
```
Builds and serves standalone SwaggerEditor application and all it's assets on `http://localhost:3050/`.
**dist/esm/**
```sh
$ npm run build:bundle:esm
```
This bundle is suited for consumption by 3rd parties,
which want to use SwaggerEditor as a library in their own applications and have their own build process.
**dist/umd/**
```sh
$ npm run build:bundle:umd
```
SwaggerEditor UMD bundle exports SwaggerEditor symbol on global object.
It's bundled with React defined as external. This allows consumer to use his own version of React + ReactDOM and mount SwaggerEditor lazily.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta
name="description"
content="SwaggerEditor"
/>
<title>SwaggerEditor</title>
<link rel="stylesheet" href="./swagger-editor.css" />
</head>
<body>
<div id="swagger-editor"></div>
<script src="https://unpkg.com/react@17/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js" crossorigin></script>
<script src="./dist/umd/swagger-editor.js"></script>
<script>
const props = {
url: 'https://raw.githubusercontent.com/asyncapi/spec/v2.2.0/examples/streetlights-kafka.yml',
};
const element = React.createElement(SwaggerEditor, props);
const domContainer = document.querySelector('#swagger-editor');
ReactDOM.render(element, domContainer);
</script>
</body>
</html>
```
**npm**
SwaggerEditor is released as `@swagger-api/swagger-editor` npm package on [GitHub packages registry](https://docs.github.com/en/packages/learn-github-packages/introduction-to-github-packages).
Package can also be produced manually by running following commands (assuming you're already followed [setting up](#setting-up) steps):
```sh
$ npm run build:bundle:esm
$ npm run build:bundle:umd
$ npm pack
```
### Package mapping
SwaggerEditor maps its [build artifacts](#build-artifacts) in `package.json` file in following way:
```json
"unpkg": "./dist/umd/swagger-editor.js",
"module": "./dist/esm/swagger-editor.js",
"browser": "./dist/esm/swagger-editor.js",
"jsnext:main": "./dist/esm/swagger-editor.js",
"exports": {
"./package.json": "./package.json",
"./swagger-editor.css": "./dist/esm/swagger-editor.css",
".": {
"browser": "./dist/esm/swagger-editor.js"
},
"./apidom.worker": {
"browser": "./dist/esm/apidom.worker.js"
},
"./editor.worker": {
"browser": "./dist/esm/editor.worker.js"
}
}
```
To learn more about these fields please refer to [webpack mainFields documentation](https://webpack.js.org/configuration/resolve/#resolvemainfields)
or to [Node.js Modules: Packages documentation](https://nodejs.org/docs/latest-v16.x/api/packages.html).
## Documentation
### Customization
- [Plug points](./docs/customization/plug-points/README.md)
### Environment Variables
It is possible to use an environment variable to specify a local JSON/YAML file or a remote URL for SwaggerEditor to load on startup.
These environment variables will get baked in during build time into build artifacts.
Environment variables currently available:
| Variable name | Description |
|-----------------------------|:----------------------------------------------------------------------------------------------------------:|
| `REACT_APP_DEFINITION_FILE` | Specifies a local file path, and the specified file must also be present in the `/public/static` directory |
| `REACT_APP_DEFINITION_URL` | Specifies a remote URL. This environment variable currently takes precedence over `REACT_APP_SWAGGER_FILE` |
| `REACT_APP_VERSION` | Specifies the version of this app. The version is read from `package.json` file. |
Sample environment variable values can be found in `.env` file. For more information about using
environment variables, please refer to [adding Custom Environment Variables](https://create-react-app.dev/docs/adding-custom-environment-variables/)
section of Create React App documentation.
### Using preview plugins in SwaggerUI
SwaggerEditor comes with number of `preview` plugins that are responsible for rendering
the definition that's being created in the editor. These plugins include:
- **EditorPreviewAsyncAPIPlugin** - AsyncAPI specification rendering support
- **EditorPreviewAPIDesignSystemsPlugin** - API Design Systems rendering support
With a bit of adapting, we can use these plugins with SwaggerUI to provide ability
to render AsyncAPI or API Design Systems definitions with SwaggerUI.
```js
import React from 'react';
import ReactDOM from 'react-dom';
import SwaggerUI from 'swagger-ui-react';
import 'swagger-ui-react/swagger-ui.css';
import SwaggerEditor from '@swagger-api/swagger-editor';
const plugins = [
SwaggerEditor.plugins.EditorContentType,
SwaggerEditor.plugins.EditorPreviewAsyncAPI,
SwaggerEditor.plugins.EditorPreviewAPIDesignSystems,
SwaggerEditor.plugins.SwaggerUIAdapter,
];
ReactDOM.render(
<SwaggerUI
plugins={plugins}
url="https://raw.githubusercontent.com/asyncapi/spec/v2.4.0/examples/streetlights-kafka.yml"
/>,
document.getElementById('swagger-ui')
);
```
The key here is `SwaggerUIAdapter` plugin which adapts SwaggerEditor plugins to use
directly with SwaggerUI.
## Docker
### Pre-built DockerHub image
SwaggerEditor is available as a pre-built docker image hosted on [DockerHub](https://hub.docker.com/r/swaggerapi/swagger-editor/tags?page=1&name=next-v5).
```sh
$ docker pull swaggerapi/swagger-editor:next-v5
$ docker run -d -p 8080:80 swaggerapi/swagger-editor:next-v5
```
### Building locally
**Privileged image**:
```sh
$ npm run build:app
$ docker build . -t swaggerapi/swagger-editor:next-v5
$ docker run -d -p 8080:80 swaggerapi/swagger-editor:next-v5
```
Now open your browser at `http://localhost:8080/`.
**Unprivileged image**:
```sh
$ npm run build:app
$ docker build . -f Dockerfile.unprivileged -t swaggerapi/swagger-editor:next-v5-unprivileged
$ docker run -d -p 8080:8080 swaggerapi/swagger-editor:next-v5-unprivileged
```
Now open your browser at `http://localhost:8080/`.
> **No** custom environment variables are currently supported by SwaggerEditor.
## License
SwaggerEditor is licensed under [Apache 2.0 license](https://github.com/swagger-api/swagger-editor/blob/next/LICENSES/Apache-2.0.txt).
SwaggerEditor comes with an explicit [NOTICE](https://github.com/swagger-api/apidom/blob/next/NOTICE) file
containing additional legal notifications and information.
This project uses [REUSE specification](https://reuse.software/spec/) that defines a standardized method
for declaring copyright and licensing for software projects.