Package Exports
- quasar-json-api
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (quasar-json-api) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
quasar-json-api
Description
The quasar-json-api
is a library to normalize and validate your JSON Api for a Quasar Component, Directive, Mixin or Plugin.
As well, it'll create Vetur
compliant files, so that when using vscode
with vetur
you get suggestions and completions.
The output of the results will be placed in the dist/api and dist/vetur folders, respectively.
Usage
Before proceeding, make sure you are using the Quasar build system from the UI kit.
$ yarn add --dev quasar-json-api
In your build
folder, create a file called: build.api.js
Add the following to it:
const path = require('path')
global.rootDir = path.resolve(__dirname, '..')
global.distDir = path.resolve(__dirname, '../dist')
require('quasar-json-api')()
In your build/index.js
find the createFolder('dist')
command and modify as follows:
createFolder('dist')
createFolder('dist/api')
createFolder('dist/vetur')
In your build/script.javascript.js
find the build(builds)
command and modify as follows:
build(builds)
.then(() => {
require('./build.api')
})
In your `package.json, add the following:
"vetur": {
"tags": "dist/vetur/tags.json",
"attributes": "dist/vetur/attributes.json"
},
That's it!
When you build your Component or Directive via yarn build
(from your UI kit templated package), your JSON API will be Normalized and Validated and the output will be placed in the dist/api
folder.
JSON API
The JSON API can be used to simplify your component/directive by having a consistent JSON structure that can be read by several libraries. This is currently supported by Quasar's command-line via quasar describe <component|directive>
. It is also supported by the JSON API Viewer component.
JSON API can be parsed for one or more Components, Directives, Plugins, or utility libraries.
Top-Level Blocks
There are several top-level blocks:
- meta
- props
- events
- slots
- scopedSlots
- methods
Meta
The meta object currently contains a single docsUrl key, which is the location to your documentation. This is used by the quasar describe ...
command-line utility.
Example:
"meta": {
"docsUrl": "https://quasarframework.github.io/quasar-ui-qmediaplayer/docs"
},
Anatomy of an Object
An object describes a portion of your API. Let's say you want to describe a property called backgroundColor. You need to change any camel-case names to snake-case, so when described, this property now becomes background-color.
Example:
"background-color": {
"type": "String",
"category": "style",
"desc": "Color name for component from the [Quasar Color Pallete](https://quasar.dev/style/color-palette)",
"applicable": [ "Audio", "Video" ],
"examples": [
"background-color=\"black\"",
"background-color=\"teal-10\""
]
},
Available keys for described objects are:
- type (required) | [String | Array]
- category (required) | String
- desc (required) | String
- applicable | [String | Array]
- examples (required, unless type is Boolean) | Array
- required | Boolean
- values | Array
- definition | Object
- reactive | Boolean
- sync | Boolean
- link | String (URL)
- addedIn | String
- params | Object
- returns | Any
- scope | Object (scopedSlots only)
Not all keys are applicable to all the top-level blocks.
Types
The available types are:
- Boolean
- String
- Number
- Object
- Array
- Date
- Event
- FileList
- Map
- Promise
- Function
- MultipleTypes
- Error
- Component
Describing
Let's look at a longer property description:
"sources": {
"type": "Array",
"category": "model",
"desc": "The one or more sources for Video or Audio. The browser will pick the best one to play based on available codecs on the client's system",
"applicable": [ "Audio", "Video" ],
"definition": {
"src": {
"type": "String",
"desc": "Path to a source",
"examples": [
"src='https://your-server/your-video.mov'",
"src='https://your-server/your-audio.mp3'"
]
},
"type": {
"type": "String",
"desc": "The kind of source",
"examples": [
"type='video/mp4'",
"type='audio/mp3'"
]
}
},
"examples": [
":sources=\"[{ src: 'https://your-server/your-video.mov', type: 'video/mp4' }]\"",
":sources=\"[{ src: 'https://your-server/your-audio.mp3', type: 'audio/mp3' }]\""
]
},
And, here is an example of a property that is a Function:
"extend": {
"type": "Function",
"category": "extend",
"desc": "Used to extend the markdown processor. You can use any 'markdown-it' plugin or write your own",
"params": {
"md": {
"type": "Object",
"desc": "The `markdown-it` instance",
"__exemption": [ "examples" ]
}
},
"examples": [
":extend=\"extendMarkdownFn\"",
":extend=\"(md) => extendMarkdownFn(md)\""
],
"returns": null
},
Notice for the params section, we defer the required example by using "__exemption": [ "examples" ] instead. Some objects just don't make sense to have an example, if you have examples elsewhere for that object.
Let's look at one more property that takes a Function so you get a feel for the JSON:
"drag-over-func": {
"type": "Function",
"category": "behavior",
"desc": "The function to handle dragover events",
"params": {
"event": {
"type": "Object",
"desc": "The event associated with the dragover",
"__exemption": [ "examples" ]
},
"timestamp": {
"type": "Object",
"desc": "The timestamp object associated with the date and optional time (if an interval)",
"__exemption": [ "examples" ]
},
"type": {
"type": "String",
"desc": "This can be 'day', 'interval' or 'resource'",
"examples": [
"day",
"interval",
"resource"
]
},
"index": {
"type": "Number",
"desc": "The column-count index location of the start of the drag (only available if property `column-count` is set)",
"__exemption": [ "examples" ]
}
},
"applicable": [
"All"
],
"returns": {
"type": "Boolean",
"desc": "If the event was handled"
},
"examples": [
":drag-over-func=\"onDragOver\""
]
},
Notice in the previous example, the return type was just null. In the example above, the return type is slightly more sophisticated.
Let's describe an event:
"toc": {
"desc": "If `toc` property is `true` then if a TOC is generated it is emitted via this event",
"params": {
"tocData": {
"type": "Array",
"desc": "Array of one or more TOC data objects",
"definition": {
"id": {
"type": "String",
"desc": "The id for the TOC header",
"__exemption": [ "examples" ]
},
"label": {
"type": "String",
"desc": "The TOC header label",
"__exemption": [ "examples" ]
},
"level": {
"type": "Number",
"desc": "The TOC header type (1=h1, 2=h2, etc)",
"__exemption": [ "examples" ]
},
"children": {
"type": "Array",
"desc": "This is normally empty, unless you pass this toc array to the `makeTree` method",
"__exemption": [ "examples" ]
}
}
}
}
}
You will notice some of the keys used for properties do not apply, even if it was required.
Let's describe a slot and scopedSlot:
"spinner": {
"desc": "Slot for replacing the default spinner/loading icon",
"applicable": [ "Audio", "Video" ]
},
"column-header-before": {
"desc": "Use to render items before the column header",
"scope": {
"data": {
"type": "Object",
"desc": "Timestamp object",
"__exemption": [ "examples" ]
}
},
"applicable": [
"day"
]
},
"column-header-after": {
"desc": "Use to render items after the column header",
"scope": {
"data": {
"type": "Object",
"desc": "Timestamp object",
"__exemption": [ "examples" ]
}
},
"applicable": [
"day"
]
},
Notice for scopedSlots the use of the scope key.
Methods
When a JSON file is parsed, a corresponding JS file of the same name is located. If found, this file is also parsed. When the methods section is parsed, it looks for private vs public methods. Private methods should start with two underscores (__). If a method is found, that is public and not described in your JSON API, this will cause an error. Either make the method private or add a section for it in your JSON API.
If a described method does not include a returns key, then it is assumed to be undefined.
Here is an example of describing a method:
"move": {
"desc": "Triggers component to move for count iterations, depending on positive (forwards) or negative (backwards) value",
"applicable": [ "All"],
"params": {
"count": {
"type": "Number",
"desc": "The amount of iterations to move (negative for backwards, positive for forwards)",
"examples": [
"-5 (moves 5 iterations backward - if in `month` view, this would be -5 months",
"5 (moves 5 iterations forward - if in `day` view, this would be 5 days"
]
}
}
},
JSON API Examples
Donate
If you appreciate the work that went into this, please consider donating to Quasar or Jeff.
License
MIT (c) Jeff Galbraith jeff@quasar.dev