mirror of
https://github.com/oceanprotocol/docs.git
synced 2024-11-26 19:49:26 +01:00
Merge branch 'master' into feature/get-consume-flow
This commit is contained in:
commit
f07ded1e1f
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,3 +7,4 @@ yarn-error.log
|
||||
.DS_Store
|
||||
.env
|
||||
.env.*
|
||||
data/squid-js.json
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -2,3 +2,6 @@
|
||||
path = external/dev-ocean
|
||||
url = https://github.com/oceanprotocol/dev-ocean
|
||||
branch = master
|
||||
[submodule "external/squid-js"]
|
||||
path = external/squid-js
|
||||
url = https://github.com/oceanprotocol/squid-js.git
|
||||
|
52
README.md
52
README.md
@ -82,37 +82,37 @@ All Markdown files should use
|
||||
|
||||
1. The file must begin with a section called YAML frontmatter that looks like this:
|
||||
|
||||
```md
|
||||
---
|
||||
title: This is the Title in Title Case
|
||||
description: A short description of the page.
|
||||
---
|
||||
```md
|
||||
---
|
||||
title: This is the Title in Title Case
|
||||
description: A short description of the page.
|
||||
---
|
||||
|
||||
Markdown content begins here.
|
||||
```
|
||||
Markdown content begins here.
|
||||
```
|
||||
|
||||
For external documents in other repos, defining the `slug` and `section` is required:
|
||||
For external documents in other repos, defining the `slug` and `section` is required:
|
||||
|
||||
```md
|
||||
---
|
||||
title: This is the Title in Title Case
|
||||
description: A short description of the page.
|
||||
slug: /concepts/architecture/
|
||||
section: concepts
|
||||
---
|
||||
```md
|
||||
---
|
||||
title: This is the Title in Title Case
|
||||
description: A short description of the page.
|
||||
slug: /concepts/architecture/
|
||||
section: concepts
|
||||
---
|
||||
|
||||
Markdown content begins here.
|
||||
```
|
||||
Markdown content begins here.
|
||||
```
|
||||
|
||||
Note: The `description` value will be rendered on-page below the title, and it will also be used for description tags in the HTML head.
|
||||
Note: The `description` value will be rendered on-page below the title, and it will also be used for description tags in the HTML head.
|
||||
|
||||
2. Don't include the page title or description in the Markdown section. That is, don't begin the Markdown content with `# This is the Title in Title Case`. Just write as if that were already there.
|
||||
3. start your heading levels with `h2`, so `## My heading`
|
||||
4. Internal links to other docs pages should be:
|
||||
1. Don't include the page title or description in the Markdown section. That is, don't begin the Markdown content with `# This is the Title in Title Case`. Just write as if that were already there.
|
||||
2. start your heading levels with `h2`, so `## My heading`
|
||||
3. Internal links to other docs pages should be:
|
||||
- to a absolute URL without the host, that looks like `/concepts/terminology/` with slashes on the beginning and end, and with no `.md` or `.html` at the end (before the last slash).
|
||||
- when linking from external repos, to the _full absolute URL_, such as `https://docs.oceanprotocol.com/hello/you-are-awesome/`
|
||||
5. no TOC please, this will be generated automatically from all headings
|
||||
6. for images and media, you can keep them in the original repo. Images will be automatically grabbed by the docs site on querying. When doing that, docs site will generate all sorts of image sizes to handle proper responsive images, so no need to keep an eye on image dimensions or file sizes
|
||||
4. no TOC please, this will be generated automatically from all headings
|
||||
5. for images and media, you can keep them in the original repo. Images will be automatically grabbed by the docs site on querying. When doing that, docs site will generate all sorts of image sizes to handle proper responsive images, so no need to keep an eye on image dimensions or file sizes
|
||||
|
||||
**Have a look at [docs.oceanprotocol.com/test/](https://docs.oceanprotocol.com/test/) to see what content elements can be used in all Markdown files included in docs site.**
|
||||
|
||||
@ -207,9 +207,11 @@ For more information about stylistic issues, take a look at the section in the t
|
||||
|
||||
#### TypeDoc specs
|
||||
|
||||
Reference pages based on generated `json` file from TypeDoc.
|
||||
Reference pages based on generated `json` file from TypeDoc. TypeScript-based projects are included as git submodules under `./external`.
|
||||
|
||||
_Coming soon... see [#45](https://github.com/oceanprotocol/docs/issues/45)_
|
||||
On site build, TypeDoc will automatically generate the required `json` spec file into `./data/squid-js.json` and create pages from it. The data from these json files is then used by the TypeDoc template.
|
||||
|
||||
To update the specs to the most recent version, the `./external/squid-js` submodule needs to be manuall updated. That's it, on next site build a new spec will be used.
|
||||
|
||||
## Development
|
||||
|
||||
|
@ -12,7 +12,7 @@ The following components expose a consumable REST API which are documented on th
|
||||
|
||||
Those are sourced from their respective Swagger specs. On this site you can't execute the documented API calls yet. If you need this, you can run a component's local Swagger UI as outlined in the repository instructions on GitHub.
|
||||
|
||||
References of all the functions and methods used in our libraries are not yet integrated here. For now, have a look at the respective repos for more infos:
|
||||
References of all the functions and methods used in our libraries:
|
||||
|
||||
<repo name="squid-js"></repo>
|
||||
<repo name="squid-py"></repo>
|
||||
|
@ -1,6 +1,5 @@
|
||||
---
|
||||
title: API Reference
|
||||
description:
|
||||
title: Squid-py API Reference
|
||||
---
|
||||
|
||||
ReadTheDocs hosts the [squid-py API Reference Docs](https://squid-py.readthedocs.io/en/latest/).
|
||||
|
@ -20,7 +20,13 @@
|
||||
- group: Libraries
|
||||
items:
|
||||
- name: squid-js
|
||||
links:
|
||||
- name: API reference
|
||||
url: /references/squid-js/
|
||||
- name: squid-py
|
||||
links:
|
||||
- name: API reference
|
||||
url: /references/squid-py/
|
||||
- name: squid-java
|
||||
|
||||
- group: OceanDB
|
||||
|
@ -3,16 +3,6 @@
|
||||
- title: API References
|
||||
link: /references/introduction/
|
||||
|
||||
# - group: squid-js
|
||||
# items:
|
||||
# - title: API Reference
|
||||
# link: /references/squid-js/
|
||||
|
||||
- group: squid-py
|
||||
items:
|
||||
- title: API Reference
|
||||
link: /references/squid-py/
|
||||
|
||||
- group: aquarius
|
||||
items:
|
||||
- title: API Reference
|
||||
@ -22,3 +12,13 @@
|
||||
items:
|
||||
- title: API Reference
|
||||
link: /references/brizo/
|
||||
|
||||
- group: squid-js
|
||||
items:
|
||||
- title: API Reference
|
||||
link: /references/squid-js/
|
||||
|
||||
- group: squid-py
|
||||
items:
|
||||
- title: API Reference
|
||||
link: /references/squid-py/
|
||||
|
2
external/dev-ocean
vendored
2
external/dev-ocean
vendored
@ -1 +1 @@
|
||||
Subproject commit 79786228757f8e39092d9dd5adf387097f0b02f6
|
||||
Subproject commit bb4bd802b318f68b2f4a9568bbb0d25bde7e24a9
|
1
external/squid-js
vendored
Submodule
1
external/squid-js
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 89cd8fd744ad5c61273b5da595e33f3b80c29c4f
|
@ -153,7 +153,7 @@ exports.createPages = ({ graphql, actions }) => {
|
||||
// Create pages from swagger json files
|
||||
//
|
||||
const apiSwaggerTemplate = path.resolve(
|
||||
'./src/templates/ApiSwagger.jsx'
|
||||
'./src/templates/Swagger/index.jsx'
|
||||
)
|
||||
|
||||
const petStoreSlug = '/references/petstore/'
|
||||
@ -197,6 +197,58 @@ exports.createPages = ({ graphql, actions }) => {
|
||||
}
|
||||
})
|
||||
|
||||
//
|
||||
// Create pages from TypeDoc json files
|
||||
//
|
||||
const typeDocSpecs = ['./data/squid-js.json']
|
||||
const typedocTemplate = path.resolve(
|
||||
'./src/templates/Typedoc/index.jsx'
|
||||
)
|
||||
|
||||
typeDocSpecs.forEach(spec => {
|
||||
const typedoc = require(spec) // eslint-disable-line
|
||||
|
||||
const name = path
|
||||
.basename(spec)
|
||||
.split('.json')
|
||||
.join('')
|
||||
|
||||
const slug = `/references/${name}/`
|
||||
|
||||
createPage({
|
||||
path: slug,
|
||||
component: typedocTemplate,
|
||||
context: {
|
||||
slug,
|
||||
typedoc,
|
||||
// TODO: defining these classes for inclusion
|
||||
// needs to be handled somewhere else to keep
|
||||
// it generic for all TypeDoc specs
|
||||
classes: [
|
||||
'ocean/Ocean',
|
||||
'ocean/OceanAccounts',
|
||||
'ocean/OceanAssets',
|
||||
'ocean/OceanAgreements',
|
||||
'ocean/Account',
|
||||
'ocean/DID',
|
||||
'ocean/ServiceAgreements/ServiceAgreement',
|
||||
'ddo/DDO',
|
||||
'ddo/Service',
|
||||
'aquarius/AquariusProvider',
|
||||
'aquarius/Aquarius',
|
||||
'aquarius/query/SearchQuery',
|
||||
'brizo/BrizoProvider',
|
||||
'brizo/Brizo',
|
||||
'keeper/Keeper',
|
||||
'keeper/Web3Provider',
|
||||
'secretstore/SecretStoreProvider',
|
||||
'models/Config',
|
||||
'models/Balance'
|
||||
]
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
//
|
||||
// create redirects
|
||||
//
|
||||
|
15
package.json
15
package.json
@ -5,8 +5,8 @@
|
||||
"author": "Ocean Protocol <devops@oceanprotocol.com>",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"build": "gatsby build",
|
||||
"start": "gatsby develop",
|
||||
"build": "npm run typedoc && gatsby build",
|
||||
"start": "npm run typedoc && gatsby develop",
|
||||
"ssr": "npm run build && serve -s public/",
|
||||
"format:js": "prettier --write '**/*.{js,jsx}'",
|
||||
"format:css": "prettier-stylelint --write --quiet 'src/**/*.{css,scss}'",
|
||||
@ -19,7 +19,8 @@
|
||||
"lint:yml": "prettier '**/*.{yml,yaml}' --list-different",
|
||||
"lint": "run-p --continue-on-error lint:js lint:css lint:md lint:yml",
|
||||
"test": "npm run lint",
|
||||
"deploy": "./scripts/deploy.sh"
|
||||
"deploy": "./scripts/deploy.sh",
|
||||
"typedoc": "node ./scripts/typedoc.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@oceanprotocol/art": "^2.1.0",
|
||||
@ -33,7 +34,7 @@
|
||||
"gatsby-plugin-offline": "^2.0.19",
|
||||
"gatsby-plugin-react-helmet": "^3.0.4",
|
||||
"gatsby-plugin-sass": "^2.0.7",
|
||||
"gatsby-plugin-sharp": "^2.0.15",
|
||||
"gatsby-plugin-sharp": "^2.0.17",
|
||||
"gatsby-plugin-sitemap": "^2.0.3",
|
||||
"gatsby-plugin-svgr": "^2.0.1",
|
||||
"gatsby-remark-autolink-headers": "^2.0.12",
|
||||
@ -57,10 +58,12 @@
|
||||
"react": "^16.6.3",
|
||||
"react-dom": "^16.6.3",
|
||||
"react-helmet": "^5.2.0",
|
||||
"react-scrollspy": "^3.3.5",
|
||||
"rehype-react": "^3.1.0",
|
||||
"remark": "^10.0.1",
|
||||
"remark-react": "^5.0.0",
|
||||
"slugify": "^1.3.4",
|
||||
"smoothscroll-polyfill": "^0.4.3",
|
||||
"swagger-client": "^3.8.22"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -72,12 +75,14 @@
|
||||
"eslint-plugin-prettier": "^3.0.0",
|
||||
"markdownlint-cli": "^0.13.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"ora": "^3.0.0",
|
||||
"prettier": "^1.15.3",
|
||||
"prettier-stylelint": "^0.4.2",
|
||||
"stylelint": "^9.9.0",
|
||||
"stylelint-config-bigchaindb": "^1.2.1",
|
||||
"stylelint-config-css-modules": "^1.3.0",
|
||||
"stylelint-config-standard": "^18.2.0"
|
||||
"stylelint-config-standard": "^18.2.0",
|
||||
"typedoc": "^0.14.2"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
66
scripts/typedoc.js
Normal file
66
scripts/typedoc.js
Normal file
@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/* eslint-disable no-console, security/detect-child-process, security/detect-non-literal-fs-filename */
|
||||
|
||||
const fs = require('fs')
|
||||
const typedoc = require('typedoc')
|
||||
const typescript = require('typescript')
|
||||
const ora = require('ora')
|
||||
const squidJsPackage = require('../external/squid-js/package.json')
|
||||
const { exec } = require('child_process')
|
||||
|
||||
const { description, version } = squidJsPackage
|
||||
|
||||
// Setup our paths, relative to project root
|
||||
const outPath = './data/squid-js.json'
|
||||
const files = ['./external/squid-js/src/squid.ts']
|
||||
|
||||
// specifically point to tsconfig, otherwise TypeDoc fails
|
||||
const config = typescript.findConfigFile(
|
||||
'./external/squid-js',
|
||||
typescript.sys.fileExists
|
||||
)
|
||||
|
||||
// npm install for squid-js
|
||||
const spinnerNpm = ora('Installing submodule dependencies...').start()
|
||||
const install = exec(
|
||||
'cd ./external/squid-js && npm i && git checkout package-lock.json'
|
||||
)
|
||||
|
||||
install.on('exit', () => {
|
||||
spinnerNpm.succeed('Installed submodule dependencies.')
|
||||
generateJson()
|
||||
})
|
||||
|
||||
const generateJson = () => {
|
||||
const spinnerTypedoc = ora('Generating TypeDoc json...').start()
|
||||
|
||||
// Setup our TypeDoc app
|
||||
const app = new typedoc.Application({
|
||||
tsconfig: config
|
||||
})
|
||||
|
||||
const src = app.expandInputFiles(files)
|
||||
const project = app.convert(src)
|
||||
|
||||
// Generate the JSON file
|
||||
app.generateJson(project, outPath)
|
||||
|
||||
// Parse and modify json output
|
||||
const jsonOrig = JSON.parse(fs.readFileSync(outPath, 'utf8'))
|
||||
|
||||
const jsonFinal = {
|
||||
info: {
|
||||
title: 'Squid-js',
|
||||
description,
|
||||
version,
|
||||
sourceUrl:
|
||||
'https://github.com/oceanprotocol/squid-js/tree/develop/src/'
|
||||
},
|
||||
...jsonOrig
|
||||
}
|
||||
|
||||
fs.writeFileSync(outPath, JSON.stringify(jsonFinal, null, 4))
|
||||
|
||||
spinnerTypedoc.succeed('Generated TypeDoc json.')
|
||||
}
|
85
src/components/Scroll.jsx
Normal file
85
src/components/Scroll.jsx
Normal file
@ -0,0 +1,85 @@
|
||||
import smoothscroll from 'smoothscroll-polyfill'
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
export default class TocScroll extends React.Component {
|
||||
static propTypes = {
|
||||
type: PropTypes.string,
|
||||
element: PropTypes.string,
|
||||
offset: PropTypes.number,
|
||||
timeout: PropTypes.number,
|
||||
children: PropTypes.node.isRequired
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
smoothscroll.polyfill()
|
||||
}
|
||||
|
||||
handleClick = e => {
|
||||
e.preventDefault()
|
||||
|
||||
let elem = 0
|
||||
let scroll = true
|
||||
const { type, element, offset, timeout } = this.props
|
||||
|
||||
if (type && element) {
|
||||
switch (type) {
|
||||
case 'class':
|
||||
// eslint-disable-next-line prefer-destructuring
|
||||
elem = document.getElementsByClassName(element)[0]
|
||||
scroll = !!elem
|
||||
break
|
||||
case 'id':
|
||||
elem = document.getElementById(element)
|
||||
scroll = !!elem
|
||||
break
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
if (scroll) {
|
||||
this.scrollTo(elem, offset, timeout)
|
||||
|
||||
// update browser url
|
||||
if (typeof window !== 'undefined') {
|
||||
window.history.pushState({}, null, `#${element}`)
|
||||
}
|
||||
} else {
|
||||
console.log(`Element not found: ${element}`) // eslint-disable-line
|
||||
}
|
||||
}
|
||||
|
||||
scrollTo(element, offSet = 0, timeout = null) {
|
||||
const elemPos = element
|
||||
? element.getBoundingClientRect().top + window.pageYOffset
|
||||
: 0
|
||||
|
||||
if (timeout) {
|
||||
setTimeout(() => {
|
||||
window.scroll({
|
||||
top: elemPos + offSet,
|
||||
left: 0,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
}, timeout)
|
||||
} else {
|
||||
window.scroll({
|
||||
top: elemPos + offSet,
|
||||
left: 0,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<a
|
||||
onClick={this.handleClick}
|
||||
href={`#${this.props.element}`}
|
||||
{...this.props}
|
||||
>
|
||||
{this.props.children}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
}
|
@ -34,13 +34,10 @@ SidebarLink.propTypes = {
|
||||
linkClasses: PropTypes.string
|
||||
}
|
||||
|
||||
const SidebarList = ({ items, location, toc, tableOfContents }) => (
|
||||
const SidebarList = ({ items, location, toc, tocComponent }) => (
|
||||
<div className={styles.list}>
|
||||
{toc ? (
|
||||
<div
|
||||
className={styles.toc}
|
||||
dangerouslySetInnerHTML={{ __html: tableOfContents }}
|
||||
/>
|
||||
<div className={styles.toc}>{tocComponent}</div>
|
||||
) : (
|
||||
<ul>
|
||||
{items.map((item, j) => (
|
||||
@ -65,7 +62,7 @@ SidebarList.propTypes = {
|
||||
items: PropTypes.array.isRequired,
|
||||
location: PropTypes.object.isRequired,
|
||||
toc: PropTypes.bool,
|
||||
tableOfContents: PropTypes.string
|
||||
tocComponent: PropTypes.object
|
||||
}
|
||||
|
||||
const SidebarGroupTitle = ({ group }) => (
|
||||
@ -104,19 +101,13 @@ export default class Sidebar extends Component {
|
||||
location: PropTypes.object.isRequired,
|
||||
collapsed: PropTypes.bool,
|
||||
toc: PropTypes.bool,
|
||||
tableOfContents: PropTypes.string
|
||||
tocComponent: PropTypes.element
|
||||
}
|
||||
|
||||
static defaultProps = { location: { pathname: '/' } }
|
||||
|
||||
render() {
|
||||
const {
|
||||
sidebar,
|
||||
location,
|
||||
collapsed,
|
||||
toc,
|
||||
tableOfContents
|
||||
} = this.props
|
||||
const { sidebar, location, collapsed, toc, tocComponent } = this.props
|
||||
|
||||
if (sidebar) {
|
||||
try {
|
||||
@ -143,7 +134,7 @@ export default class Sidebar extends Component {
|
||||
group={group}
|
||||
location={location}
|
||||
toc={toc}
|
||||
tableOfContents={tableOfContents}
|
||||
tocComponent={tocComponent}
|
||||
/>
|
||||
) : (
|
||||
<SidebarGroupTitle group={group} />
|
||||
|
@ -16,8 +16,8 @@
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
@ -79,22 +79,50 @@
|
||||
&:focus {
|
||||
transform: none;
|
||||
color: $brand-purple;
|
||||
|
||||
:global(.setup) & {
|
||||
color: $brand-blue;
|
||||
}
|
||||
|
||||
:global(.tutorials) & {
|
||||
color: $orange;
|
||||
}
|
||||
|
||||
:global(.references) & {
|
||||
color: $green;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.toc {
|
||||
ul {
|
||||
padding-left: 0;
|
||||
margin: 0;
|
||||
|
||||
ul {
|
||||
padding-left: $spacer / 2;
|
||||
margin: 0;
|
||||
border-left: 1px solid $brand-grey-lighter;
|
||||
margin-left: $spacer;
|
||||
font-size: $font-size-small;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
padding-top: $spacer / 12;
|
||||
padding-bottom: $spacer / 12;
|
||||
}
|
||||
|
||||
code {
|
||||
background: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
[data-deprecated='true'] code {
|
||||
opacity: .5;
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
@ -111,4 +139,16 @@
|
||||
color: $orange;
|
||||
border-left-color: $orange;
|
||||
}
|
||||
|
||||
:global(.references) & {
|
||||
color: $green;
|
||||
border-left-color: $green;
|
||||
}
|
||||
}
|
||||
|
||||
.scrollspyActive {
|
||||
> a {
|
||||
color: $green;
|
||||
border-left-color: $green;
|
||||
}
|
||||
}
|
||||
|
@ -283,11 +283,11 @@ samp {
|
||||
}
|
||||
|
||||
:not(pre) > code {
|
||||
background: darken($brand-white, 5%) !important;
|
||||
color: $brand-grey-dark !important;
|
||||
background: darken($brand-white, 5%);
|
||||
color: $brand-grey-dark;
|
||||
display: inline-block;
|
||||
padding-left: .3rem !important;
|
||||
padding-right: .3rem !important;
|
||||
padding-left: .3rem;
|
||||
padding-right: .3rem;
|
||||
}
|
||||
|
||||
pre {
|
||||
|
@ -1,321 +0,0 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { graphql } from 'gatsby'
|
||||
import Helmet from 'react-helmet'
|
||||
import slugify from 'slugify'
|
||||
import Layout from '../components/Layout'
|
||||
import Content from '../components/Content'
|
||||
import HeaderSection from '../components/HeaderSection'
|
||||
import Sidebar from '../components/Sidebar'
|
||||
import DocHeader from '../components/DocHeader'
|
||||
import DocFooter from '../components/DocFooter'
|
||||
import SEO from '../components/Seo'
|
||||
import stylesDoc from './Doc.module.scss'
|
||||
import styles from './ApiSwagger.module.scss'
|
||||
|
||||
const cleanKey = key => {
|
||||
let keyCleaned = key
|
||||
|
||||
if (key.includes('aquarius')) {
|
||||
keyCleaned = key.replace(/\/api\/v1\/aquarius/gi, '')
|
||||
}
|
||||
|
||||
if (key.includes('brizo')) {
|
||||
keyCleaned = key.replace(/\/api\/v1\/brizo/gi, '')
|
||||
}
|
||||
|
||||
return keyCleaned
|
||||
}
|
||||
|
||||
const toc = api => {
|
||||
const items = Object.keys(api.paths).map(
|
||||
key => `<li key=${key}>
|
||||
<a href="#${slugify(cleanKey(key))}"><code>${cleanKey(
|
||||
key
|
||||
)}</code></a>
|
||||
</li>`
|
||||
)
|
||||
|
||||
return `<ul>${items}</ul>`
|
||||
}
|
||||
|
||||
const SwaggerMeta = ({ contact, license }) => (
|
||||
<ul className={styles.swaggerMeta}>
|
||||
{contact && (
|
||||
<li>
|
||||
<a href={`mailto:${contact.email}`}>{contact.email}</a>
|
||||
</li>
|
||||
)}
|
||||
{license && (
|
||||
<li>
|
||||
<a href={license.url}>{license.name}</a>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
)
|
||||
|
||||
SwaggerMeta.propTypes = {
|
||||
contact: PropTypes.object,
|
||||
license: PropTypes.object
|
||||
}
|
||||
|
||||
const ParameterExample = ({ properties }) => (
|
||||
//
|
||||
// HEADS UP!
|
||||
//
|
||||
// Constructing the example request body here based on the defined properties
|
||||
// where `key` is the name of the property, and `properties[key].example` is
|
||||
// the value for it.
|
||||
//
|
||||
// Making prism.js pick up on the strings only output didn't work out so well
|
||||
// so the spans and classes this plugin would add are added manually here. Since we
|
||||
// include the prism css file globally this is picked up by that.
|
||||
//
|
||||
// But this can only work if all keys and values are manually constructed here, which
|
||||
// is almost impossible to do for deep nested objects or arrays as example value. Running
|
||||
// that code through `JSON.stringify` won't syntax highlight that part of the code.
|
||||
//
|
||||
<pre className="language-json">
|
||||
<code className="language-json">
|
||||
{'{'}
|
||||
{properties &&
|
||||
Object.keys(properties).map(key => (
|
||||
<div key={key}>
|
||||
<span className="token property">{` "${key}"`}</span>
|
||||
<span className="token operator">{`: `}</span>
|
||||
{properties[key].type === 'string' && (
|
||||
<span className="token string">{`"${
|
||||
properties[key].example
|
||||
}"`}</span>
|
||||
)}
|
||||
{(properties[key].type === 'integer' ||
|
||||
properties[key].type === 'number') && (
|
||||
<span className="token number">
|
||||
{`${properties[key].example}`}
|
||||
</span>
|
||||
)}
|
||||
{(properties[key].type === 'array' ||
|
||||
properties[key].type === 'object') &&
|
||||
JSON.stringify(properties[key].example, null, 2)}
|
||||
,
|
||||
</div>
|
||||
))}
|
||||
{'}'}
|
||||
</code>
|
||||
</pre>
|
||||
)
|
||||
|
||||
ParameterExample.propTypes = {
|
||||
properties: PropTypes.object
|
||||
}
|
||||
|
||||
const Parameters = ({ parameters }) => (
|
||||
<>
|
||||
<h4 className={styles.subHeading}>Parameters</h4>
|
||||
|
||||
{parameters.map(parameter => {
|
||||
const { name, type, required, description, schema } = parameter
|
||||
|
||||
return (
|
||||
<div className={styles.parameters} key={parameter.name}>
|
||||
<h5>
|
||||
<code>{name}</code>
|
||||
{required && (
|
||||
<span
|
||||
className={styles.parameterRequired}
|
||||
title="required parameter"
|
||||
>
|
||||
*
|
||||
</span>
|
||||
)}
|
||||
<span className={styles.parameterType}>{type}</span>
|
||||
</h5>
|
||||
|
||||
<p>{description}</p>
|
||||
|
||||
{schema && (
|
||||
<ParameterExample properties={schema.properties} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</>
|
||||
)
|
||||
|
||||
const Responses = ({ responses }) => (
|
||||
<>
|
||||
<h4 className={styles.subHeading}>Responses</h4>
|
||||
{Object.keys(responses).map(key => (
|
||||
<div key={key} className={styles.response}>
|
||||
<code>{key}</code> {responses[key].description}
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
|
||||
const Method = ({ keyName, value }) => {
|
||||
const { summary, description, parameters, responses } = value
|
||||
|
||||
return (
|
||||
<div className={styles.method}>
|
||||
<h3 className={styles.pathMethod} data-type={keyName}>
|
||||
{keyName}
|
||||
</h3>
|
||||
|
||||
<p>{summary}</p>
|
||||
|
||||
{description && <p>{description}</p>}
|
||||
|
||||
{/*
|
||||
{consumes &&
|
||||
consumes.map((item, i) => (
|
||||
<div key={i}>
|
||||
<code>{item}</code>
|
||||
</div>
|
||||
))}
|
||||
*/}
|
||||
|
||||
{parameters && parameters.length && (
|
||||
<Parameters parameters={parameters} />
|
||||
)}
|
||||
{responses && Object.keys(responses).length !== 0 && (
|
||||
<Responses responses={responses} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Method.propTypes = {
|
||||
keyName: PropTypes.string,
|
||||
value: PropTypes.object
|
||||
}
|
||||
|
||||
const Paths = ({ paths }) =>
|
||||
Object.entries(paths).map(([key, value]) => (
|
||||
<div key={key}>
|
||||
<h2 id={slugify(cleanKey(key))} className={styles.pathName}>
|
||||
<code>{cleanKey(key)}</code>
|
||||
</h2>
|
||||
|
||||
{Object.entries(value).map(([key, value]) => (
|
||||
<Method key={key} keyName={key} value={value} />
|
||||
))}
|
||||
</div>
|
||||
))
|
||||
|
||||
const BasePath = ({ host, basePath }) => (
|
||||
<div className={styles.basePath}>
|
||||
<h2>Base Path</h2>
|
||||
<code>
|
||||
<span>{host}</span>
|
||||
{basePath}
|
||||
</code>
|
||||
</div>
|
||||
)
|
||||
|
||||
BasePath.propTypes = {
|
||||
host: PropTypes.string,
|
||||
basePath: PropTypes.string
|
||||
}
|
||||
|
||||
export default class ApiSwaggerTemplate extends Component {
|
||||
static propTypes = {
|
||||
data: PropTypes.object.isRequired,
|
||||
location: PropTypes.object.isRequired,
|
||||
pageContext: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
render() {
|
||||
const { location, data, pageContext } = this.props
|
||||
const sections = data.allSectionsYaml.edges
|
||||
const { api } = pageContext
|
||||
const { host, basePath, info, paths } = api
|
||||
const { title, description, version, license, contact } = info
|
||||
|
||||
// output section title as defined in sections.yml
|
||||
const sectionTitle = sections.map(({ node }) => {
|
||||
// compare section against section title from sections.yml
|
||||
if (node.title.toLowerCase().includes('references')) {
|
||||
return node.title
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<body className={'references'} />
|
||||
</Helmet>
|
||||
|
||||
<SEO
|
||||
title={title}
|
||||
description={description}
|
||||
slug={pageContext.slug}
|
||||
article
|
||||
/>
|
||||
|
||||
<Layout location={location}>
|
||||
<HeaderSection title={sectionTitle} />
|
||||
|
||||
<Content>
|
||||
<main className={stylesDoc.wrapper}>
|
||||
<aside className={stylesDoc.sidebar}>
|
||||
<Sidebar
|
||||
location={location}
|
||||
sidebar={'references'}
|
||||
collapsed
|
||||
toc
|
||||
tableOfContents={toc(api)
|
||||
.split(',')
|
||||
.join('')}
|
||||
/>
|
||||
</aside>
|
||||
<article className={stylesDoc.main}>
|
||||
<DocHeader
|
||||
title={title}
|
||||
description={description}
|
||||
prepend={
|
||||
<span className={styles.version}>
|
||||
{version}
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
|
||||
{(contact || license) && (
|
||||
<SwaggerMeta
|
||||
contact={contact}
|
||||
license={license}
|
||||
/>
|
||||
)}
|
||||
|
||||
{(host || basePath) && (
|
||||
<BasePath host={host} basePath={basePath} />
|
||||
)}
|
||||
|
||||
<Paths paths={paths} />
|
||||
|
||||
<DocFooter
|
||||
url={`https://github.com/oceanprotocol/${title.toLowerCase()}`}
|
||||
externalName={`${title} Swagger spec`}
|
||||
/>
|
||||
</article>
|
||||
</main>
|
||||
</Content>
|
||||
</Layout>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export const apiSwaggerQuery = graphql`
|
||||
query {
|
||||
allSectionsYaml {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
description
|
||||
link
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
@ -26,8 +26,8 @@ const DocMain = ({ title, description, tableOfContents, post, single }) => (
|
||||
|
||||
DocMain.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
description: PropTypes.string.isRequired,
|
||||
tableOfContents: PropTypes.string,
|
||||
description: PropTypes.string,
|
||||
tableOfContents: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
|
||||
post: PropTypes.object.isRequired,
|
||||
single: PropTypes.bool
|
||||
}
|
||||
@ -38,22 +38,25 @@ export default class DocTemplate extends Component {
|
||||
location: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
// output section title as defined in sections.yml
|
||||
sectionTitle = this.props.data.allSectionsYaml.edges.map(({ node }) => {
|
||||
// compare section against section title from sections.yml
|
||||
if (
|
||||
node.title
|
||||
.toLowerCase()
|
||||
.includes(this.props.data.markdownRemark.fields.section)
|
||||
) {
|
||||
return node.title
|
||||
}
|
||||
})
|
||||
|
||||
render() {
|
||||
const { location } = this.props
|
||||
const post = this.props.data.markdownRemark
|
||||
const sections = this.props.data.allSectionsYaml.edges
|
||||
const { section, slug } = post.fields
|
||||
const { title, description } = post.frontmatter
|
||||
const { tableOfContents } = post
|
||||
|
||||
// output section title as defined in sections.yml
|
||||
const sectionTitle = sections.map(({ node }) => {
|
||||
// compare section against section title from sections.yml
|
||||
if (node.title.toLowerCase().includes(section)) {
|
||||
return node.title
|
||||
}
|
||||
})
|
||||
|
||||
const isApiSection = location.pathname.includes('/references/')
|
||||
|
||||
return (
|
||||
@ -70,7 +73,9 @@ export default class DocTemplate extends Component {
|
||||
/>
|
||||
|
||||
<Layout location={location}>
|
||||
<HeaderSection title={section ? sectionTitle : title} />
|
||||
<HeaderSection
|
||||
title={section ? this.sectionTitle : title}
|
||||
/>
|
||||
|
||||
<Content>
|
||||
{section ? (
|
||||
|
@ -14,6 +14,7 @@
|
||||
@media (min-width: $break-point--medium) {
|
||||
width: 27%;
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
order: 1;
|
||||
|
||||
+ .main {
|
||||
@ -47,3 +48,9 @@
|
||||
max-width: 73%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.version {
|
||||
font-size: $font-size-base;
|
||||
font-family: $font-family-monospace;
|
||||
color: $brand-grey-light;
|
||||
}
|
||||
|
151
src/templates/Swagger/Paths.jsx
Normal file
151
src/templates/Swagger/Paths.jsx
Normal file
@ -0,0 +1,151 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import slugify from 'slugify'
|
||||
import { cleanPathKey } from './utils'
|
||||
import styles from './Paths.module.scss'
|
||||
|
||||
const ParameterExample = ({ properties }) => (
|
||||
//
|
||||
// HEADS UP!
|
||||
//
|
||||
// Constructing the example request body here based on the defined properties
|
||||
// where `key` is the name of the property, and `properties[key].example` is
|
||||
// the value for it.
|
||||
//
|
||||
// Making prism.js pick up on the strings only output didn't work out so well
|
||||
// so the spans and classes this plugin would add are added manually here. Since we
|
||||
// include the prism css file globally this is picked up by that.
|
||||
//
|
||||
// But this can only work if all keys and values are manually constructed here, which
|
||||
// is almost impossible to do for deep nested objects or arrays as example value. Running
|
||||
// that code through `JSON.stringify` won't syntax highlight that part of the code.
|
||||
//
|
||||
<pre className="language-json">
|
||||
<code className="language-json">
|
||||
{'{'}
|
||||
{properties &&
|
||||
Object.keys(properties).map(key => (
|
||||
<div key={key}>
|
||||
<span className="token property">{` "${key}"`}</span>
|
||||
<span className="token operator">{`: `}</span>
|
||||
{properties[key].type === 'string' && (
|
||||
<span className="token string">{`"${
|
||||
properties[key].example
|
||||
}"`}</span>
|
||||
)}
|
||||
{(properties[key].type === 'integer' ||
|
||||
properties[key].type === 'number') && (
|
||||
<span className="token number">
|
||||
{`${properties[key].example}`}
|
||||
</span>
|
||||
)}
|
||||
{(properties[key].type === 'array' ||
|
||||
properties[key].type === 'object') &&
|
||||
JSON.stringify(properties[key].example, null, 2)}
|
||||
,
|
||||
</div>
|
||||
))}
|
||||
{'}'}
|
||||
</code>
|
||||
</pre>
|
||||
)
|
||||
|
||||
ParameterExample.propTypes = {
|
||||
properties: PropTypes.object
|
||||
}
|
||||
|
||||
const Parameters = ({ parameters }) => (
|
||||
<>
|
||||
<h4 className={styles.subHeading}>Parameters</h4>
|
||||
|
||||
{parameters.map(parameter => {
|
||||
const { name, type, required, description, schema } = parameter
|
||||
|
||||
return (
|
||||
<div className={styles.parameters} key={parameter.name}>
|
||||
<h5>
|
||||
<code>{name}</code>
|
||||
{required && (
|
||||
<span
|
||||
className={styles.parameterRequired}
|
||||
title="required parameter"
|
||||
>
|
||||
*
|
||||
</span>
|
||||
)}
|
||||
<span className={styles.parameterType}>{type}</span>
|
||||
</h5>
|
||||
|
||||
<p>{description}</p>
|
||||
|
||||
{schema && (
|
||||
<ParameterExample properties={schema.properties} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</>
|
||||
)
|
||||
|
||||
const Responses = ({ responses }) => (
|
||||
<>
|
||||
<h4 className={styles.subHeading}>Responses</h4>
|
||||
{Object.keys(responses).map(key => (
|
||||
<div key={key} className={styles.response}>
|
||||
<code>{key}</code> {responses[key].description}
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
|
||||
const Method = ({ keyName, value }) => {
|
||||
const { summary, description, parameters, responses } = value
|
||||
|
||||
return (
|
||||
<div className={styles.method}>
|
||||
<h3 className={styles.pathMethod} data-type={keyName}>
|
||||
{keyName}
|
||||
</h3>
|
||||
|
||||
<p>{summary}</p>
|
||||
|
||||
{description && <p>{description}</p>}
|
||||
|
||||
{/*
|
||||
{consumes &&
|
||||
consumes.map((item, i) => (
|
||||
<div key={i}>
|
||||
<code>{item}</code>
|
||||
</div>
|
||||
))}
|
||||
*/}
|
||||
|
||||
{parameters && parameters.length && (
|
||||
<Parameters parameters={parameters} />
|
||||
)}
|
||||
{responses && Object.keys(responses).length !== 0 && (
|
||||
<Responses responses={responses} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Method.propTypes = {
|
||||
keyName: PropTypes.string,
|
||||
value: PropTypes.object
|
||||
}
|
||||
|
||||
const Paths = ({ paths }) =>
|
||||
Object.entries(paths).map(([key, value]) => (
|
||||
<div key={key} id={slugify(cleanPathKey(key))}>
|
||||
<h2 className={styles.pathName}>
|
||||
<code>{cleanPathKey(key)}</code>
|
||||
</h2>
|
||||
|
||||
{Object.entries(value).map(([key, value]) => (
|
||||
<Method key={key} keyName={key} value={value} />
|
||||
))}
|
||||
</div>
|
||||
))
|
||||
|
||||
export default Paths
|
@ -1,52 +1,5 @@
|
||||
@import 'variables';
|
||||
|
||||
.version {
|
||||
font-size: $font-size-base;
|
||||
font-family: $font-family-monospace;
|
||||
color: $brand-grey-light;
|
||||
}
|
||||
|
||||
.swaggerMeta {
|
||||
margin-top: -($spacer);
|
||||
padding: 0;
|
||||
font-size: $font-size-small;
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
margin-left: $spacer;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&:before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.basePath {
|
||||
margin-top: $spacer;
|
||||
|
||||
h2 {
|
||||
font-size: $font-size-h3;
|
||||
border-bottom: 1px solid $brand-grey-lighter;
|
||||
padding-bottom: $spacer / 2;
|
||||
margin-top: $spacer * 2;
|
||||
margin-bottom: $spacer;
|
||||
}
|
||||
|
||||
span {
|
||||
color: $brand-grey-light;
|
||||
}
|
||||
|
||||
code {
|
||||
// stylelint-disable-next-line
|
||||
font-size: $font-size-large !important;
|
||||
font-weight: $font-weight-bold;
|
||||
}
|
||||
}
|
||||
|
||||
.pathName {
|
||||
font-size: $font-size-h3;
|
||||
border-bottom: 1px solid $brand-grey-lighter;
|
43
src/templates/Swagger/Toc.jsx
Normal file
43
src/templates/Swagger/Toc.jsx
Normal file
@ -0,0 +1,43 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import slugify from 'slugify'
|
||||
import Scrollspy from 'react-scrollspy'
|
||||
import Scroll from '../../components/Scroll'
|
||||
import { cleanPathKey } from './utils'
|
||||
import stylesSidebar from '../../components/Sidebar.module.scss'
|
||||
|
||||
const Toc = ({ data }) => {
|
||||
let Ids = []
|
||||
|
||||
const items = Object.keys(data.paths).map(key => {
|
||||
Ids.push(slugify(cleanPathKey(key)))
|
||||
|
||||
return (
|
||||
<li key={key}>
|
||||
<Scroll
|
||||
type="id"
|
||||
element={`${slugify(cleanPathKey(key))}`}
|
||||
offset={-20}
|
||||
>
|
||||
<code>{cleanPathKey(key)}</code>
|
||||
</Scroll>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
|
||||
return (
|
||||
<Scrollspy
|
||||
items={Ids}
|
||||
currentClassName={stylesSidebar.scrollspyActive}
|
||||
offset={-100}
|
||||
>
|
||||
{items}
|
||||
</Scrollspy>
|
||||
)
|
||||
}
|
||||
|
||||
Toc.propTypes = {
|
||||
data: PropTypes.oneOfType([PropTypes.array, PropTypes.object])
|
||||
}
|
||||
|
||||
export default Toc
|
152
src/templates/Swagger/index.jsx
Normal file
152
src/templates/Swagger/index.jsx
Normal file
@ -0,0 +1,152 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { graphql } from 'gatsby'
|
||||
import Helmet from 'react-helmet'
|
||||
|
||||
import Layout from '../../components/Layout'
|
||||
import Content from '../../components/Content'
|
||||
import HeaderSection from '../../components/HeaderSection'
|
||||
import Sidebar from '../../components/Sidebar'
|
||||
import DocHeader from '../../components/DocHeader'
|
||||
import DocFooter from '../../components/DocFooter'
|
||||
import SEO from '../../components/Seo'
|
||||
|
||||
import Toc from './Toc'
|
||||
import Paths from './Paths'
|
||||
|
||||
import stylesDoc from '../Doc.module.scss'
|
||||
import styles from './index.module.scss'
|
||||
|
||||
const SwaggerMeta = ({ contact, license }) => (
|
||||
<ul className={styles.swaggerMeta}>
|
||||
{contact && (
|
||||
<li>
|
||||
<a href={`mailto:${contact.email}`}>{contact.email}</a>
|
||||
</li>
|
||||
)}
|
||||
{license && (
|
||||
<li>
|
||||
<a href={license.url}>{license.name}</a>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
)
|
||||
|
||||
SwaggerMeta.propTypes = {
|
||||
contact: PropTypes.object,
|
||||
license: PropTypes.object
|
||||
}
|
||||
|
||||
const BasePath = ({ host, basePath }) => (
|
||||
<div className={styles.basePath}>
|
||||
<h2>Base Path</h2>
|
||||
<code>
|
||||
<span>{host}</span>
|
||||
{basePath}
|
||||
</code>
|
||||
</div>
|
||||
)
|
||||
|
||||
BasePath.propTypes = {
|
||||
host: PropTypes.string,
|
||||
basePath: PropTypes.string
|
||||
}
|
||||
|
||||
export default class ApiSwaggerTemplate extends Component {
|
||||
static propTypes = {
|
||||
data: PropTypes.object.isRequired,
|
||||
location: PropTypes.object.isRequired,
|
||||
pageContext: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
// output section title as defined in sections.yml
|
||||
sectionTitle = this.props.data.allSectionsYaml.edges.map(({ node }) => {
|
||||
// compare section against section title from sections.yml
|
||||
if (node.title.toLowerCase().includes('references')) {
|
||||
return node.title
|
||||
}
|
||||
})
|
||||
|
||||
render() {
|
||||
const { location, pageContext } = this.props
|
||||
const { api } = pageContext
|
||||
const { host, basePath, info, paths } = api
|
||||
const { title, description, version, license, contact } = info
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<body className={'references'} />
|
||||
</Helmet>
|
||||
|
||||
<SEO
|
||||
title={title}
|
||||
description={description}
|
||||
slug={pageContext.slug}
|
||||
article
|
||||
/>
|
||||
|
||||
<Layout location={location}>
|
||||
<HeaderSection title={this.sectionTitle} />
|
||||
|
||||
<Content>
|
||||
<main className={stylesDoc.wrapper}>
|
||||
<aside className={stylesDoc.sidebar}>
|
||||
<Sidebar
|
||||
location={location}
|
||||
sidebar={'references'}
|
||||
collapsed
|
||||
toc
|
||||
tocComponent={<Toc data={api} />}
|
||||
/>
|
||||
</aside>
|
||||
<article className={stylesDoc.main}>
|
||||
<DocHeader
|
||||
title={title}
|
||||
description={description}
|
||||
prepend={
|
||||
<span className={stylesDoc.version}>
|
||||
{version}
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
|
||||
{(contact || license) && (
|
||||
<SwaggerMeta
|
||||
contact={contact}
|
||||
license={license}
|
||||
/>
|
||||
)}
|
||||
|
||||
{(host || basePath) && (
|
||||
<BasePath host={host} basePath={basePath} />
|
||||
)}
|
||||
|
||||
<Paths paths={paths} />
|
||||
|
||||
<DocFooter
|
||||
url={`https://github.com/oceanprotocol/${title.toLowerCase()}`}
|
||||
externalName={`${title} Swagger spec`}
|
||||
/>
|
||||
</article>
|
||||
</main>
|
||||
</Content>
|
||||
</Layout>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export const apiSwaggerQuery = graphql`
|
||||
query {
|
||||
allSectionsYaml {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
description
|
||||
link
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
42
src/templates/Swagger/index.module.scss
Normal file
42
src/templates/Swagger/index.module.scss
Normal file
@ -0,0 +1,42 @@
|
||||
@import 'variables';
|
||||
|
||||
.swaggerMeta {
|
||||
margin-top: -($spacer);
|
||||
padding: 0;
|
||||
font-size: $font-size-small;
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
margin-left: $spacer;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&:before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.basePath {
|
||||
margin-top: $spacer;
|
||||
|
||||
h2 {
|
||||
font-size: $font-size-h3;
|
||||
border-bottom: 1px solid $brand-grey-lighter;
|
||||
padding-bottom: $spacer / 2;
|
||||
margin-top: $spacer * 2;
|
||||
margin-bottom: $spacer;
|
||||
}
|
||||
|
||||
span {
|
||||
color: $brand-grey-light;
|
||||
}
|
||||
|
||||
code {
|
||||
// stylelint-disable-next-line
|
||||
font-size: $font-size-large !important;
|
||||
font-weight: $font-weight-bold;
|
||||
}
|
||||
}
|
13
src/templates/Swagger/utils.js
Normal file
13
src/templates/Swagger/utils.js
Normal file
@ -0,0 +1,13 @@
|
||||
export const cleanPathKey = key => {
|
||||
let keyCleaned = key
|
||||
|
||||
if (key.includes('aquarius')) {
|
||||
keyCleaned = key.replace(/\/api\/v1\/aquarius/gi, '')
|
||||
}
|
||||
|
||||
if (key.includes('brizo')) {
|
||||
keyCleaned = key.replace(/\/api\/v1\/brizo/gi, '')
|
||||
}
|
||||
|
||||
return keyCleaned
|
||||
}
|
252
src/templates/Typedoc/Entities.jsx
Normal file
252
src/templates/Typedoc/Entities.jsx
Normal file
@ -0,0 +1,252 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import slugify from 'slugify'
|
||||
import Scroll from '../../components/Scroll'
|
||||
import styles from './Entities.module.scss'
|
||||
import { filterByKindOfProperty } from './utils'
|
||||
|
||||
const Type = ({ type }) => {
|
||||
let isArray = false
|
||||
if (type.type === 'array') {
|
||||
isArray = true
|
||||
type = type.elementType
|
||||
}
|
||||
const { name, type: typeOfType, typeArguments, id } = type
|
||||
const isInternal = typeOfType === 'reference' && id
|
||||
|
||||
return (
|
||||
<div className={styles.type}>
|
||||
<span>
|
||||
{isInternal && (
|
||||
<Scroll type="id" element={`${slugify(name)}`} offset={-20}>
|
||||
{type.name}
|
||||
</Scroll>
|
||||
)}
|
||||
{!isInternal && <span>{type.name}</span>}
|
||||
</span>
|
||||
|
||||
{typeArguments && (
|
||||
<span>
|
||||
<span className={styles.typeSymbol}><</span>
|
||||
<span>
|
||||
{typeArguments.map((typeArgument, i) => (
|
||||
<span key={i}>
|
||||
{i !== 0 && (
|
||||
<span className={styles.typeSymbol}>
|
||||
,{' '}
|
||||
</span>
|
||||
)}
|
||||
<Type type={typeArgument} key={i} />
|
||||
</span>
|
||||
))}
|
||||
</span>
|
||||
<span className={styles.typeSymbol}>></span>
|
||||
</span>
|
||||
)}
|
||||
|
||||
{isArray && <span className={styles.typeSymbol}>[]</span>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Type.propTypes = {
|
||||
type: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
const PropertyDetails = ({ property }) => {
|
||||
const { type } = property
|
||||
return (
|
||||
<div>
|
||||
<Type type={type} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
PropertyDetails.propTypes = {
|
||||
property: PropTypes.object
|
||||
}
|
||||
|
||||
const MethodDetails = ({ property }) => {
|
||||
const signature = property.signatures[0]
|
||||
const { parameters, type } = signature
|
||||
return (
|
||||
<>
|
||||
{parameters && parameters.length && (
|
||||
<div>
|
||||
<h4 className={styles.subHeading}>Parameters</h4>
|
||||
|
||||
{parameters.map(parameter => {
|
||||
const { name, type, flags, comment } = parameter
|
||||
const { isOptional } = flags
|
||||
const description =
|
||||
comment && (comment.text || comment.shortText)
|
||||
|
||||
return (
|
||||
<div
|
||||
className={styles.parameters}
|
||||
key={parameter.name}
|
||||
>
|
||||
<h5>
|
||||
<code>{name}</code>
|
||||
{isOptional && (
|
||||
<span
|
||||
className={styles.parameterOptional}
|
||||
title="optional parameter"
|
||||
>
|
||||
?
|
||||
</span>
|
||||
)}
|
||||
</h5>
|
||||
<Type type={type} />
|
||||
|
||||
<p>{description}</p>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{type && (
|
||||
<div>
|
||||
<h4 className={styles.subHeading}>Returns</h4>
|
||||
|
||||
<Type type={type} />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
MethodDetails.propTypes = {
|
||||
property: PropTypes.object
|
||||
}
|
||||
|
||||
const PropertyWrapper = ({ property, sourceUrl, parentAnchor }) => {
|
||||
const {
|
||||
name,
|
||||
kindString,
|
||||
flags,
|
||||
signatures,
|
||||
sources,
|
||||
decorators
|
||||
} = property
|
||||
const { isPublic, isStatic } = flags
|
||||
const signature = signatures && signatures[0]
|
||||
const comment = (signature && signature.comment) || property.comment
|
||||
const { fileName, line } = sources[0]
|
||||
const deprecation = (decorators || []).filter(
|
||||
({ name }) => name === 'deprecated'
|
||||
)[0] // Assuming deprecated annotation
|
||||
let deprecatedUse, deprecatedSlug
|
||||
if (deprecation) {
|
||||
deprecatedUse = deprecation.arguments.alternative.replace(/('|")/g, '')
|
||||
deprecatedSlug = slugify(deprecatedUse.replace('.', '-'))
|
||||
}
|
||||
|
||||
const sourceLink = `${sourceUrl}${fileName}#L${line}`
|
||||
|
||||
return (
|
||||
<div
|
||||
className={styles.property}
|
||||
data-private={!isPublic}
|
||||
data-deprecated={!!deprecation}
|
||||
id={`${parentAnchor}-${slugify(name)}`}
|
||||
>
|
||||
<h3 className={styles.propertyName}>{name}</h3>
|
||||
|
||||
<div
|
||||
className={styles.propertyType}
|
||||
data-type={kindString.toLowerCase()}
|
||||
>
|
||||
{kindString}
|
||||
</div>
|
||||
|
||||
{isStatic && <div className={styles.propertyModifier}>static</div>}
|
||||
{!isPublic && (
|
||||
<div className={styles.propertyModifier} data-secondary>
|
||||
private
|
||||
</div>
|
||||
)}
|
||||
|
||||
{comment && !deprecation && (
|
||||
<div className={styles.propertyDescription}>
|
||||
{comment.text || comment.shortText}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{deprecation && (
|
||||
<div className={styles.deprecation}>
|
||||
<strong>Deprecated</strong>: use{' '}
|
||||
<code>
|
||||
<Scroll
|
||||
type="id"
|
||||
element={`${deprecatedSlug}`}
|
||||
offset={-20}
|
||||
>
|
||||
{deprecatedUse}
|
||||
</Scroll>
|
||||
</code>{' '}
|
||||
instead
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!deprecation &&
|
||||
(() => {
|
||||
switch (kindString) {
|
||||
case 'Method':
|
||||
return <MethodDetails property={property} />
|
||||
case 'Property':
|
||||
return <PropertyDetails property={property} />
|
||||
}
|
||||
})()}
|
||||
|
||||
{fileName && (
|
||||
<a
|
||||
className={styles.sourceLink}
|
||||
href={sourceLink}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{`${fileName}#L${line}`}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
PropertyWrapper.propTypes = {
|
||||
property: PropTypes.object,
|
||||
sourceUrl: PropTypes.string,
|
||||
parentAnchor: PropTypes.string
|
||||
}
|
||||
|
||||
const Entities = ({ entities, sourceUrl }) =>
|
||||
entities.map(({ name, comment, children }) => (
|
||||
<div key={name} id={slugify(name)}>
|
||||
<h2 className={styles.entityName}>
|
||||
<code>{name}</code>
|
||||
</h2>
|
||||
|
||||
{comment && (
|
||||
<div className={styles.entityDescription}>
|
||||
{comment.text || comment.shortText}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{children.filter(filterByKindOfProperty).map(property => (
|
||||
<PropertyWrapper
|
||||
key={`${name}/${property.id}`}
|
||||
property={property}
|
||||
sourceUrl={sourceUrl}
|
||||
parentAnchor={slugify(name)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
))
|
||||
|
||||
Entities.propTypes = {
|
||||
entities: PropTypes.array.isRequired,
|
||||
sourceUrl: PropTypes.string
|
||||
}
|
||||
|
||||
export default Entities
|
173
src/templates/Typedoc/Entities.module.scss
Normal file
173
src/templates/Typedoc/Entities.module.scss
Normal file
@ -0,0 +1,173 @@
|
||||
@import 'variables';
|
||||
|
||||
.entityName {
|
||||
font-size: $font-size-h2;
|
||||
border-bottom: 1px solid $brand-grey-lighter;
|
||||
padding-bottom: $spacer / 2;
|
||||
margin-top: $spacer * 2;
|
||||
margin-bottom: $spacer;
|
||||
|
||||
code {
|
||||
// stylelint-disable declaration-no-important
|
||||
background: none !important;
|
||||
padding: 0 !important;
|
||||
// stylelint-enable declaration-no-important
|
||||
}
|
||||
}
|
||||
|
||||
.entityDescription {
|
||||
padding-bottom: $spacer;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.property {
|
||||
padding: $spacer / 2;
|
||||
border: 1px solid $brand-grey-lighter;
|
||||
margin-bottom: $spacer;
|
||||
border-radius: $border-radius;
|
||||
position: relative;
|
||||
|
||||
&[data-deprecated='true'] {
|
||||
> *:not(.deprecation) {
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
code {
|
||||
opacity: 1;
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.sourceLink {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.propertyName,
|
||||
.propertyType,
|
||||
.propertyModifier {
|
||||
font-size: $font-size-base;
|
||||
font-family: $font-family-monospace;
|
||||
margin-bottom: $spacer / 4;
|
||||
margin-top: 0;
|
||||
display: inline-block;
|
||||
padding: 0 $spacer / 4;
|
||||
border-radius: $border-radius;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.propertyName {
|
||||
font-size: $font-size-large;
|
||||
padding: 0;
|
||||
margin-right: $spacer / 3;
|
||||
}
|
||||
|
||||
.propertyType,
|
||||
.propertyModifier {
|
||||
font-size: $font-size-small;
|
||||
color: $brand-grey;
|
||||
margin-right: $spacer / 4;
|
||||
}
|
||||
|
||||
.propertyType {
|
||||
&[data-type='method'] {
|
||||
background: rgba($green, .3);
|
||||
}
|
||||
|
||||
&[data-type='property'] {
|
||||
background: rgba($yellow, .3);
|
||||
}
|
||||
}
|
||||
|
||||
.propertyModifier {
|
||||
background: rgba($red, .2);
|
||||
|
||||
&[data-secondary] {
|
||||
background: rgba($brand-blue, .2);
|
||||
}
|
||||
}
|
||||
|
||||
.propertyDescription {
|
||||
margin-bottom: $spacer;
|
||||
}
|
||||
|
||||
.sourceLink {
|
||||
display: block;
|
||||
font-size: $font-size-mini;
|
||||
color: $brand-grey-light;
|
||||
margin-top: $spacer / 2;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
@media (min-width: $break-point--large) {
|
||||
margin-top: 0;
|
||||
position: absolute;
|
||||
bottom: $spacer / 2;
|
||||
right: $spacer / 2;
|
||||
}
|
||||
}
|
||||
|
||||
.deprecation {
|
||||
font-size: $font-size-small;
|
||||
margin-top: $spacer / 4;
|
||||
|
||||
strong {
|
||||
color: $brand-grey-light;
|
||||
}
|
||||
}
|
||||
|
||||
.type {
|
||||
display: inline-block;
|
||||
color: $brand-grey;
|
||||
font-family: $font-family-monospace;
|
||||
font-size: $font-size-small;
|
||||
|
||||
a {
|
||||
&:hover {
|
||||
opacity: .6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.typeSymbol {
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.subHeading {
|
||||
font-size: $font-size-base;
|
||||
border-bottom: 1px solid $brand-grey-lighter;
|
||||
padding-bottom: $spacer / 4;
|
||||
margin-bottom: $spacer / 4;
|
||||
color: $brand-grey;
|
||||
}
|
||||
|
||||
.parameters {
|
||||
margin-top: $spacer / 1.5;
|
||||
|
||||
h5,
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: $font-size-small;
|
||||
margin-bottom: $spacer / 4;
|
||||
margin-right: $spacer / 4;
|
||||
margin-left: -(.2rem);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
code {
|
||||
padding: .2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.parameterOptional {
|
||||
font-size: $font-size-small;
|
||||
vertical-align: top;
|
||||
color: $brand-purple;
|
||||
}
|
63
src/templates/Typedoc/Toc.jsx
Normal file
63
src/templates/Typedoc/Toc.jsx
Normal file
@ -0,0 +1,63 @@
|
||||
import React, { PureComponent } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import slugify from 'slugify'
|
||||
import Scrollspy from 'react-scrollspy'
|
||||
import Scroll from '../../components/Scroll'
|
||||
import { filterByKindOfProperty } from './utils'
|
||||
import stylesSidebar from '../../components/Sidebar.module.scss'
|
||||
|
||||
export default class Toc extends PureComponent {
|
||||
static propTypes = {
|
||||
data: PropTypes.array
|
||||
}
|
||||
|
||||
subItems = (children, parentName) =>
|
||||
children.filter(filterByKindOfProperty).map(({ name, decorators }) => {
|
||||
const deprecation = (decorators || []).filter(
|
||||
({ name }) => name === 'deprecated'
|
||||
)[0] // Assuming deprecated annotation
|
||||
|
||||
return (
|
||||
<li key={name}>
|
||||
<Scroll
|
||||
type="id"
|
||||
element={`${parentName}-${slugify(name)}`}
|
||||
data-deprecated={!!deprecation}
|
||||
offset={-20}
|
||||
>
|
||||
<code>{name}</code>
|
||||
</Scroll>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
|
||||
items = this.props.data.map(({ name, children }) => {
|
||||
let subIds = []
|
||||
const parentName = name
|
||||
|
||||
subIds.push(
|
||||
children.filter(filterByKindOfProperty).map(({ name }) => {
|
||||
return `${parentName}-${slugify(name)}`
|
||||
})
|
||||
)
|
||||
|
||||
return (
|
||||
<li key={name}>
|
||||
<Scroll type="id" element={`${slugify(name)}`} offset={-20}>
|
||||
<code>{name}</code>
|
||||
</Scroll>
|
||||
<Scrollspy
|
||||
items={subIds[0]}
|
||||
currentClassName={stylesSidebar.scrollspyActive}
|
||||
offset={-30}
|
||||
>
|
||||
{this.subItems(children, name)}
|
||||
</Scrollspy>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
|
||||
render() {
|
||||
return <ul>{this.items}</ul>
|
||||
}
|
||||
}
|
109
src/templates/Typedoc/index.jsx
Normal file
109
src/templates/Typedoc/index.jsx
Normal file
@ -0,0 +1,109 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { graphql } from 'gatsby'
|
||||
import Helmet from 'react-helmet'
|
||||
import Layout from '../../components/Layout'
|
||||
import Content from '../../components/Content'
|
||||
import HeaderSection from '../../components/HeaderSection'
|
||||
import Sidebar from '../../components/Sidebar'
|
||||
import DocHeader from '../../components/DocHeader'
|
||||
import SEO from '../../components/Seo'
|
||||
import { cleanTypedocData } from './utils'
|
||||
|
||||
import Entities from './Entities'
|
||||
import Toc from './Toc'
|
||||
|
||||
import stylesDoc from '../Doc.module.scss'
|
||||
|
||||
export default class TypedocTemplate extends Component {
|
||||
static propTypes = {
|
||||
data: PropTypes.object.isRequired,
|
||||
location: PropTypes.object.isRequired,
|
||||
pageContext: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
typedocCleaned = cleanTypedocData(
|
||||
this.props.pageContext.typedoc,
|
||||
this.props.pageContext.classes
|
||||
)
|
||||
|
||||
// output section title as defined in sections.yml
|
||||
sectionTitle = this.props.data.allSectionsYaml.edges.map(({ node }) => {
|
||||
// compare section against section title from sections.yml
|
||||
if (node.title.toLowerCase().includes('references')) {
|
||||
return node.title
|
||||
}
|
||||
})
|
||||
|
||||
render() {
|
||||
const { location, pageContext } = this.props
|
||||
const { typedoc } = pageContext
|
||||
const { info } = typedoc
|
||||
const { title, description, version, sourceUrl } = info
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<body className={'references'} />
|
||||
</Helmet>
|
||||
|
||||
<SEO
|
||||
title={title}
|
||||
description={description}
|
||||
slug={pageContext.slug}
|
||||
article
|
||||
/>
|
||||
|
||||
<Layout location={location}>
|
||||
<HeaderSection title={this.sectionTitle} />
|
||||
|
||||
<Content>
|
||||
<main className={stylesDoc.wrapper}>
|
||||
<aside className={stylesDoc.sidebar}>
|
||||
<Sidebar
|
||||
location={location}
|
||||
sidebar={'references'}
|
||||
collapsed
|
||||
toc
|
||||
tocComponent={
|
||||
<Toc data={this.typedocCleaned} />
|
||||
}
|
||||
/>
|
||||
</aside>
|
||||
<article className={stylesDoc.main}>
|
||||
<DocHeader
|
||||
title={title}
|
||||
description={description}
|
||||
prepend={
|
||||
<span className={stylesDoc.version}>
|
||||
{version}
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
|
||||
<Entities
|
||||
entities={this.typedocCleaned}
|
||||
sourceUrl={sourceUrl}
|
||||
/>
|
||||
</article>
|
||||
</main>
|
||||
</Content>
|
||||
</Layout>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export const TypedocQuery = graphql`
|
||||
query {
|
||||
allSectionsYaml {
|
||||
edges {
|
||||
node {
|
||||
title
|
||||
description
|
||||
link
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
34
src/templates/Typedoc/utils.js
Normal file
34
src/templates/Typedoc/utils.js
Normal file
@ -0,0 +1,34 @@
|
||||
export const cleanTypedocData = (data, useClasses) => {
|
||||
const nodes = data.children
|
||||
|
||||
const cleanData = nodes
|
||||
.map(node => ({
|
||||
...node,
|
||||
name: node.name.replace(/"/g, ''),
|
||||
child: node.children && node.children[0]
|
||||
}))
|
||||
.filter(({ name }) => (useClasses || []).includes(name))
|
||||
.sort((a, b) => useClasses.indexOf(a.name) - useClasses.indexOf(b.name))
|
||||
.map(({ child }) => child)
|
||||
.map(node => ({
|
||||
...node,
|
||||
children: node.children.sort((a, b) => a.id - b.id)
|
||||
}))
|
||||
|
||||
return cleanData
|
||||
}
|
||||
|
||||
// more kinds: 'Property', 'Class'
|
||||
const showKindOfProperty = {
|
||||
Method: { onlyPublic: true },
|
||||
Property: { onlyPublic: true }
|
||||
}
|
||||
|
||||
export const filterByKindOfProperty = ({ kindString, flags }) => {
|
||||
const config = showKindOfProperty[kindString]
|
||||
if (!config) return
|
||||
|
||||
if (config.onlyPublic && !flags.isPublic) return
|
||||
|
||||
return true
|
||||
}
|
Loading…
Reference in New Issue
Block a user