@pnmougel/monaco-rest-client v0.0.29
Monaco Rest client
This package provides a rest client for the monaco editor.
Demo
Configuration
You can configure the rest client language with the following options :
param | default | type | description |
---|---|---|---|
validate | true | boolean | If set to false , disable schema validation |
allowTrailingComma | true | boolean | If set to false , trailing commas will generate error |
schemaDef | undefined | object | Allows to define custom schema. See bellow. |
singleRequest | false | boolean | If true , only a single request is allowed. |
allowComments | true | boolean | If false , comments will generate errors. |
openApiSpec | undefined | OpenAPIObject | The OpenApi specification to use |
customOptions | {} | object | Custom options that can be used by custom resolvers |
customPathCompletion | undefined | CustomPathCompletionResolver | Function used to resolve custom path param |
customQueryCompletion | undefined | CustomQueryCompletionResolver | Function used to resolve custom query param |
customBodyCompletion | undefined | CustomBodyCompletionResolver | Function used to resolve custom body param |
features | object | Allows to disable monaco features. By default, all features are enabled. |
Configure the rest client
You can configure the rest client either at startup with the setupRestCLient
function.
const options: RestClientOptions = {...}
// At creation
const restClient = setupRestClient(monaco, options)
// Update options
restClient.options = options
When the options are updated, the webworker will also be restarted.
Set configuration option for a specific model
If you have multiple monaco editor in the same page and you want them to have different options, you can use setModelOptions
to define custom options for a specific model.
// Setup editor model
const modelUri = 'inmemory://model.json'
const model = monaco.editor.createModel('...', 'rest-client-lang', modelUri);
// Default language options
const restClient = setupRestClient(monaco, {})
// Options that will be used only for the provided model
restClient.setModelOptions(modelUri, {})
Custom completions
You can provide custom function to add custom completions items to the language, for example to propose custom completion of path parameters.
You can define the functions customPathCompletion
, customQueryCompletion
and customBodyCompletion
respectively for the path, query parameter and body contexts
Each of these function must return Promise<CustomCompletionItem[]>
or CustomCompletionItem[]
. The array can be empty if there is no completion to provide.
export interface CustomCompletionItem {
// Label displayed in the completion result
label: string;
// Optional description for the item
description?: string;
// Integer corresponding to the completion icon
kind: number;
// Optional type that will be displayed at the right of the label and in the infobox
type?: string;
}
Custom path completion
const options: RestClientOptions = {
customPathCompletion: (
// Name of the path parameter without the surrounding `{` and `}`
paramName: string,
// The schema corresponding to the path parameter
paramSchema: any,
// The `customOptions` parameter (see below "Provide options to custom completer")
options: any) => {}
}
Custom body completion
const options: RestClientOptions = {
customBodyCompletion: (
// 'key' if the completion corresponds to an object 'key', 'value' otherwise.
kind: 'key' | 'value',
// The schema corresponding to completion
schema: any,
// Object describing the current endpoint.
ctx: CustomBodyCompletionContext,
// The `customOptions` parameter (see below "Provide options to custom completer")
options: any) => {}
}
Custom query param completion
const options: RestClientOptions = {
customQueryCompletion: (
// 'key' if the completion corresponds to an query param key
// 'value' if the completion corresponds to an query param value
kind: 'key' | 'value',
// Name of the query key if kind is `key`
paramName: string,
// The schema corresponding to completion
paramSchema: any,
// The `customOptions` parameter (see below "Provide options to custom completer")
options: any) => {}
}
Example
const options: RestClientOptions = {
customPathCompletion: (paramName: string, paramSchema: any, options: any) => {
if(paramName === 'index') {
return [{
label: 'Test 1',
description: paramSchema.description,
kind: 1,
}, {
label: 'Test 2',
description: paramSchema.description,
kind: 2,
}]
} else {
return []
}
}
}
Provide options to custom completer
The completion functions will be run in the webworker context, thus you will not be able to access any of your client application context (e.g., window
). If you want to pass options to these functions, use the customOptions
parameter.
window.serverUrl = 'https://...'
const options: RestClientOptions = {
customOptions: {
test: 'https://...'
},
customPathCompletion: (paramName: string, paramSchema: any, options: any) => {
// This will be generate an error at runtome.
// `window` is not defined in the webworker context
fetch(window.serverUrl)
// This will work
fetch(options.serverUrl)
}
}
Define custom schema
Instead of allowing the user to write an endpoint (e.g., GET /_search
) you can force the language to validate only against a JSON schema. The behavior of the language will then be very similar to the monaco bundled json
language.
There is three ways to define a custom schema :
- Provide the path and method refering to a schema in the specification
/**
* The schema used for the json will be the schema corresponding of the `GET /_search` endpoint
*/
const options: RestClientOptions = {
schemaDef: {
type: 'path',
path: '_search',
method: 'GET'
}
}
- Provide a ref to a schema in the specification
/**
* The schema used for the json will be the schema resolved for the ref `#/components/search/Request` in the specification
*/
const options: RestClientOptions = {
schemaDef: {
type: 'ref',
$ref: '#/components/search/Request'
}
}
- Provide a completely custom schema not necessarily existing in the specification.
/**
* The schema used for the json will be the custom schema { type: 'object', properties: {...}}
*/
const options: RestClientOptions = {
schemaDef: {
type: 'schema',
schema: {
type: 'object',
properties: {...}
}
}
}
Disable monaco features
You can disable specific monaco features using the features
parameter.
const options: RestClientOptions = {
features: {
// Disable completion
completionItems: false,
// Disable tooltip on hover
hovers: false,
// Disable folding
foldingRanges: false,
// Disable request validation
diagnostics: false,
// Disable request formating
rangeFormatting: false,
// Disable code lens (e.g., run action)
codeLens: false,
// Disable tokenization (if this is disabled, most of the other features are likely to not run correctly)
tokens: false,
}
}
Install & usage
To use this package you MUST use monaco-editor-core
and not monaco-editor
npm i @pnmougel/monaco-rest-client monaco-editor-core
Webpack config
In the webpack config, add an entry point for the web worker.
module.exports = {
entry: {
// Rest client webworker
'rest-client.worker': '@pnmougel/monaco-rest-client/dist/rest-client.worker.js',
// Monaco webworker
'editor.worker': 'monaco-editor-core/esm/vs/editor/editor.worker.js',
// Other entrypoints
},
output: {
filename: (chunkData) => {
switch (chunkData.chunk.name) {
case 'editor.worker':
return 'editor.worker.js';
case 'rest-client.worker':
return "rest-client.worker.js"
default:
return '[name].bundle.js'
}
},
},
}
Vue-cli fix
In the optimization.splitChunks.cacheGroups
section of your webpack config ensure that the chunks
parameter of each entry is either not set or set to async
. If you are using vue-cli
it is likely to be the case.
You can check the generated webpack config for vue with the command vue inspect
.
To fix this behavior enable chainWebpack
in vue.config.js
{
...
chainWebpack: config => {
const splitChunks = config.optimization.get('splitChunks')
Object.entries(splitChunks.cacheGroups).forEach(([key, value]) => {
value.chunks = 'async'
})
config.optimization.splitChunks(splitChunks)
}
}
Application setup
Load the webworkers in the entry point of your application and setup the rest client language
import { restClientLanguageId, setupRestClient } from '@pnmougel/monaco-rest-client'
import * as monaco from 'monaco-editor-core'
(window as any).MonacoEnvironment = {
getWorker: (moduleId: string, label: string) => {
if (label === restClientLanguageId) {
return new Worker('./rest-client.worker.js')
}
return new Worker('./editor.worker.js')
},
}
const restClient = setupRestClient(monaco, {
allowTrailingComma: true,
openApiSpec: esSpec,
features: {
codeLens: true,
},
customOptions: {},
customPathCompletion,
customBodyCompletion,
})
Enable an open api spec for an editor
import { restClientLanguageId } from '@pnmougel/monaco-rest-client'
const openApiSpec: {
// Your open api specification
}
const editor = monaco.editor.create(...)
restClient.setOpenApiSpec(openApiSpec, editor.getModel())
Register a query runner
// Register the editor action to run queries
restClient.registerRunQueryAction(editor)
restClient.setQueryRunner(editor.getModel().uri.toString(), (query) => {
console.log(query)
})
NPM commands
Deploy the package
npm publish
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago