This commit is contained in:
ポール ウェッブ 2019-01-30 16:15:10 -06:00
parent fa29381a5c
commit 1663bc49f8
16 changed files with 219 additions and 83 deletions

View file

@ -11,8 +11,13 @@ import html from "choo/html";
// E X P O R T // E X P O R T
export default () => html` export default () => html`
<div class="api__header page__markup"> <div class="api-content__body">
<h1>lbrycrd APIs</h1> <h2>lbrycrd APIs</h2>
<p>Methods and signatures provided by the <a href="/glossary#lbrycrd">lbrycrd</a> blockchain daemon are documented below. To build, download, or run lbrycrd, see the project <a href="https://github.com/lbryio/lbrycrd/blob/master/README.md">README</a>.</p> <p>Methods and signatures provided by the <a href="/glossary#lbrycrd">lbrycrd</a> blockchain daemon are documented below. To build, download, or run lbrycrd, see the project <a href="https://github.com/lbryio/lbrycrd/blob/master/README.md">README</a>.</p>
</div> </div>
<div class="api-content__intro">
<p>You can find the repo for this API on GitHub:</p>
<pre><code>https://github.com/lbryio/lbry</code></pre>
</div>
`; `;

View file

@ -11,8 +11,13 @@ import html from "choo/html";
// E X P O R T // E X P O R T
export default () => html` export default () => html`
<div class="api__header page__markup"> <div class="api-content__body">
<h1>lbry-sdk APIs</h1> <h2>lbry-sdk APIs</h2>
<p>Methods and signatures provided by the <a href="/glossary#lbry-sdk">lbry-sdk</a> daemon are documented below. To build, download, or run the daemon, see the project <a href="https://github.com/lbryio/lbry/blob/master/README.md">README</a>.</p> <p>Methods and signatures provided by the <a href="/glossary#lbry-sdk">lbry-sdk</a> daemon are documented below. To build, download, or run the daemon, see the project <a href="https://github.com/lbryio/lbry/blob/master/README.md">README</a>.</p>
</div> </div>
<div class="api-content__intro">
<p>You can find the repo for this API on GitHub:</p>
<pre><code>https://github.com/lbryio/lbrycrd</code></pre>
</div>
`; `;

View file

@ -9,6 +9,7 @@ import exists from "fs-exists-sync";
import fm from "front-matter"; import fm from "front-matter";
import fs from "graceful-fs"; import fs from "graceful-fs";
import html from "choo/html"; import html from "choo/html";
import m from "markdown-it";
import markdownAnchor from "markdown-it-anchor"; import markdownAnchor from "markdown-it-anchor";
import markdownSup from "@module/markdown-it-sup"; import markdownSup from "@module/markdown-it-sup";
import path from "path"; import path from "path";
@ -17,7 +18,7 @@ import raw from "choo/html/raw";
// U T I L S // U T I L S
const numberRegex = /^[0-9]/g; const numberRegex = /^[0-9]/g;
const md = require("markdown-it")({ const md = m({
html: true, html: true,
typographer: true typographer: true
}).use(markdownSup) }).use(markdownSup)
@ -32,7 +33,9 @@ const md = require("markdown-it")({
.replace(/\)/g, "") .replace(/\)/g, "")
.replace(/,/g, ""); .replace(/,/g, "");
if (finalString.match(numberRegex)) finalString = `_${finalString}`; if (finalString.match(numberRegex))
finalString = `_${finalString}`;
return finalString; return finalString;
} }
}); });

View file

@ -14,23 +14,49 @@ document.getElementById("input-search").value = "";
// Activate search // Activate search
document.getElementById("input-search").addEventListener("keyup", () => { document.getElementById("input-search").addEventListener("keyup", () => {
if (document.getElementById("input-search").value) if (document.getElementById("input-search").value)
document.querySelector(".api__toc__search__clear").classList.add("active"); document.querySelector(".api-toc__search-clear").classList.add("active");
else else
document.querySelector(".api__toc__search__clear").classList.remove("active"); document.querySelector(".api-toc__search-clear").classList.remove("active");
}); });
// Cancel search // Cancel search
document.querySelector(".api__toc__search__clear").addEventListener("click", () => { document.querySelector(".api-toc__search-clear").addEventListener("click", () => {
document.getElementById("input-search").value = ""; document.getElementById("input-search").value = "";
document.querySelector(".api__toc__search__clear").classList.remove("active"); document.querySelector(".api-toc__search-clear").classList.remove("active");
jets.destroy(); jets.destroy();
reinitJets(); reinitJets();
}); });
// H E L P E R // Code toggles
handleApiLanguageToggles("curl");
handleApiLanguageToggles("lbrynet");
handleApiLanguageToggles("python");
// H E L P E R S
function handleApiLanguageToggles(language) {
document.getElementById(`toggle-${language}`).addEventListener("click", () => {
const codeExamples = document.querySelectorAll(`[data-api-example-type="${language}"]`);
const examples = document.querySelectorAll("[data-api-example-type]");
const toggles = document.querySelectorAll("*[id^='toggle-']");
for (const example of examples)
example.classList.remove("active");
for (const example of codeExamples)
example.classList.add("active");
for (const toggle of toggles)
toggle.classList.remove("active");
document.getElementById(`toggle-${language}`).classList.add("active");
});
}
function reinitJets() { function reinitJets() {
jets = new Jets({ jets = new Jets({

View file

@ -61,7 +61,8 @@ server
next(); next();
}) })
.ready(err => { .ready(err => {
if (err) throw err; if (err)
throw err;
server.ws.on("connection", socket => { server.ws.on("connection", socket => {
socket.on("message", data => { socket.on("message", data => {

View file

@ -15,7 +15,7 @@
} }
} }
.api__header { .api-header {
padding: 2rem; padding: 2rem;
position: relative; position: relative;
@ -33,20 +33,20 @@
/*! /*!
* API | Table of Contents * API | Table of Contents
* *
* @class .api__toc * @class .api-toc
* @class .api__toc__search * @class .api-toc__search
* @class .api__toc__search__field * @class .api-toc__search-field
* *
* @class .api__toc__search__clear * @class .api-toc__search-clear
* @state {.active} * @state {.active}
* *
* @class .api__toc__items * @class .api-toc__items
* *
* @class .api__toc__item * @class .api-toc__item
* @state {:hover} * @state {:hover}
**/ **/
.api__toc { .api-toc {
width: 200px; height: calc(100vh - 4rem); // navigation is 4rem tall width: 200px; height: calc(100vh - 4rem); // navigation is 4rem tall
bottom: 0; left: 0; bottom: 0; left: 0;
@ -59,11 +59,11 @@
z-index: 3; z-index: 3;
} }
.api__toc__search { .api-toc__search {
position: relative; position: relative;
} }
.api__toc__search__field { .api-toc__search-field {
width: 100%; width: 100%;
padding: 0.25rem calc(2rem + 4px) 0.25rem 0.75rem; padding: 0.25rem calc(2rem + 4px) 0.25rem 0.75rem;
@ -72,7 +72,7 @@
line-height: 2rem; line-height: 2rem;
} }
.api__toc__search__clear { .api-toc__search-clear {
width: 1.25rem; height: 1.25rem; width: 1.25rem; height: 1.25rem;
top: 0.6rem; right: 0.75rem; top: 0.6rem; right: 0.75rem;
@ -97,7 +97,7 @@
} }
} }
.api__toc__items { .api-toc__items {
font-size: 0.8rem; font-size: 0.8rem;
line-height: 1.33; line-height: 1.33;
list-style-type: none; list-style-type: none;
@ -105,7 +105,7 @@
padding-bottom: 1rem; padding-bottom: 1rem;
} }
.api__toc__item { .api-toc__item {
&:hover { &:hover {
background-color: $lbry-gray-2; background-color: $lbry-gray-2;
} }
@ -116,12 +116,12 @@
} }
} }
.api__content { .api-content {
width: calc(100% - 200px); width: calc(100% - 200px);
float: right; float: right;
} }
.api__documentation { .api-documentation {
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(50%, 1fr)); grid-template-columns: repeat(auto-fit, minmax(50%, 1fr));
@ -182,18 +182,30 @@
} }
} }
.api__content__body { .api-content__body {
padding: 2rem; padding: 2rem;
border-bottom: 1px solid $lbry-gray-1; // rgba($lbry-gray-1, 0.3); border-bottom: 1px solid $lbry-gray-1;
a {
transition: color 0.2s;
&:not(:hover) {
color: $lbry-teal-3;
} }
.api__content__body__arguments { &:hover {
color: $lbry-teal-5;
}
}
}
.api-content__body-arguments {
border: 1px solid $lbry-gray-2; border: 1px solid $lbry-gray-2;
border-radius: 3px; border-radius: 3px;
list-style-type: none; list-style-type: none;
} }
.api__content__body__argument { .api-content__body-argument {
&:not(:last-of-type) { &:not(:last-of-type) {
border-bottom: 1px solid $lbry-gray-2; border-bottom: 1px solid $lbry-gray-2;
} }
@ -234,14 +246,56 @@
} }
} }
.api__content__example { .api-content__example,
.api-content__intro {
padding: 2rem; padding: 2rem;
background-color: rgba($lbry-black, 0.9); background-color: rgba($lbry-black, 0.9);
border-bottom: 1px solid rgba($lbry-white, 0.1); border-bottom: 1px solid rgba($lbry-white, 0.1);
color: $lbry-white; color: $lbry-white;
position: relative;
pre { pre {
background-color: $lbry-black; background-color: $lbry-black;
} }
} }
.api-content__items {
width: 100%;
padding: 1rem 2rem;
top: 4rem; right: 0;
background-color: $lbry-black;
position: sticky;
z-index: 10;
}
.api-content__item {
padding: 0.25rem 0.75rem;
border-radius: 0.2rem;
display: inline-block;
font-size: 0.8rem;
transition: background-color 0.2s;
&:not(:last-of-type) {
margin-right: 0.5rem;
}
&:not(:hover) {
background-color: $lbry-gray-5;
}
&.active,
&:hover {
background-color: $lbry-teal-4;
}
}
pre {
&[data-api-example-type] {
&:not(.active) {
display: none;
}
}
}

View file

@ -16,7 +16,9 @@ import redirects from "@data/redirects.json";
const blockchainApi = "https://cdn.jsdelivr.net/gh/lbryio/lbrycrd@master/contrib/devtools/generated/api_v1.json"; const blockchainApi = "https://cdn.jsdelivr.net/gh/lbryio/lbrycrd@master/contrib/devtools/generated/api_v1.json";
const cache = new Map(); const cache = new Map();
const sdkApi = "https://cdn.jsdelivr.net/gh/lbryio/lbry@master/docs/api.json"; const sdkApi = process.env.NODE_ENV === "development" ?
"https://cdn.jsdelivr.net/gh/lbryio/lbry@generate_examples/docs/api.json" : // TODO: Remove when `generate_examples` is merged into master
"https://cdn.jsdelivr.net/gh/lbryio/lbry@master/docs/api.json";
@ -36,18 +38,25 @@ export default async(state) => {
return asyncHtml` return asyncHtml`
<div class="__slate"> <div class="__slate">
<aside class="api__toc"> <aside class="api-toc">
<div class="api__toc__search"> <div class="api-toc__search">
<input class="api__toc__search__field" id="input-search" placeholder="Search" type="search"/> <input class="api-toc__search-field" id="input-search" placeholder="Search" type="search"/>
<div class="api__toc__search__clear" id="clear-search" title="Clear search query">&times;</div> <div class="api-toc__search-clear" id="clear-search" title="Clear search query">&times;</div>
<ul class="api__toc__search__results"></ul> <ul class="api-toc__search-results"></ul>
</div> </div>
<ul class="api__toc__items" id="toc" role="navigation">${createApiSidebar(apiResponse)}</ul> <ul class="api-toc__items" id="toc" role="navigation">${createApiSidebar(apiResponse)}</ul>
</aside> </aside>
<section class="api__content"> <section class="api-content">
<div class="api-documentation" id="toc-content">
<div>&nbsp;</div>
<nav class="api-content__items">
<button class="api-content__item" id="toggle-curl" type="button">curl</button>
<button class="api-content__item" id="toggle-lbrynet" type="button">lbrynet</button>
<button class="api-content__item" id="toggle-python" type="button">python</button>
</nav>
${createApiHeader(state.params.wildcard)} ${createApiHeader(state.params.wildcard)}
<div class="api__documentation" id="toc-content">
${createApiContent(apiResponse)} ${createApiContent(apiResponse)}
</div> </div>
</section> </section>
@ -55,6 +64,10 @@ export default async(state) => {
<script src="/assets/scripts/plugins/jets.js"></script> <script src="/assets/scripts/plugins/jets.js"></script>
<script src="/assets/scripts/api.js"></script> <script src="/assets/scripts/api.js"></script>
<script>
document.getElementById("toggle-curl").click();
</script>
`; `;
} }
@ -101,18 +114,17 @@ function createApiContent(apiDetails) {
apiDetailsReturns = JSON.parse(JSON.stringify(apiDetail.returns)); apiDetailsReturns = JSON.parse(JSON.stringify(apiDetail.returns));
apiContent.push(` apiContent.push(`
<div class="api__content__body"> <div class="api-content__body">
<h2 id="${apiDetail.name}">${apiDetail.name}</h2> <h2 id="${apiDetail.name}">${apiDetail.name}</h2>
<p>${apiDetail.description}</p> <p>${apiDetail.description}</p>
${apiDetail.arguments.length ? `<h3>Arguments</h3><ul class="api__content__body__arguments">${renderArguments(apiDetail.arguments).join("")}</ul>` : ""} ${apiDetail.arguments.length ? `<h3>Arguments</h3><ul class="api-content__body-arguments">${renderArguments(apiDetail.arguments).join("")}</ul>` : ""}
<h3>Returns</h3> ${!apiDetail.examples || !apiDetail.examples.length ? (`<h3>Returns</h3><pre><code>${dedent(apiDetailsReturns)}</code></pre>`) : ""}
<pre><code>${dedent(apiDetailsReturns)}</code></pre>
</div> </div>
<div class="api__content__example"> <div class="api-content__example">
<pre><code>// example(s) for ${apiDetail.name} to come later</code></pre> ${apiDetail.examples && apiDetail.examples.length ? renderExamples(apiDetail.examples).join("") : `<pre><code>// example(s) for ${apiDetail.name} to come later</code></pre>`}
</div> </div>
`); `);
} }
@ -138,7 +150,7 @@ function createApiSidebar(apiDetails) {
for (const apiDetail of apiDetails) { for (const apiDetail of apiDetails) {
apiSidebar.push(` apiSidebar.push(`
<li class="api__toc__item"> <li class="api-toc__item">
<a href="#${apiDetail.name}" title="Go to ${apiDetail.name} section"> <a href="#${apiDetail.name}" title="Go to ${apiDetail.name} section">
${apiDetail.name} ${apiDetail.name}
</a> </a>
@ -182,7 +194,7 @@ function renderArguments(args) {
for (const arg of args) { for (const arg of args) {
argumentContent.push(` argumentContent.push(`
<li class="api__content__body__argument"> <li class="api-content__body-argument">
<div class="left"> <div class="left">
<strong>${arg.name}</strong><br/> <strong>${arg.name}</strong><br/>
${arg.is_required === true ? "" : "<span>optional</span>" }<span>${arg.type}</span> ${arg.is_required === true ? "" : "<span>optional</span>" }<span>${arg.type}</span>
@ -195,3 +207,21 @@ function renderArguments(args) {
return argumentContent; return argumentContent;
} }
function renderExamples(args) {
const exampleContent = [];
for (const arg of args) {
exampleContent.push(`
<h3>${arg.title}</h3><br/>
<pre data-api-example-type="curl"><code>${arg.curl}</code></pre>
<pre data-api-example-type="lbrynet"><code>${arg.lbrynet}</code></pre>
<pre data-api-example-type="python"><code>${arg.python}</code></pre>
<h3>Output</h3><br/>
<pre><code>${arg.output}</code></pre>
`);
}
return exampleContent;
}

View file

@ -19,7 +19,10 @@ import page404 from "./404";
// E X P O R T // E X P O R T
export default (state, emit) => { // eslint-disable-line export default (state, emit) => { // eslint-disable-line
const partialPath = state.route === "resources/*" ? `resources/${state.params.wildcard}` : state.params.wildcard; const partialPath = state.route === "resources/*" ?
`resources/${state.params.wildcard}` :
state.params.wildcard;
const path = `./documents/${partialPath}.md`; const path = `./documents/${partialPath}.md`;
if (!fs.existsSync(path)) if (!fs.existsSync(path))
@ -46,13 +49,22 @@ export default (state, emit) => { // eslint-disable-line
let pageScript = ""; let pageScript = "";
if (partialPath === "glossary") if (partialPath === "glossary")
pageScript = "<script>" + fs.readFileSync(`${process.cwd()}/app/components/client/glossary-scripts.js`, "utf-8") + "</script>"; pageScript =
"<script>" +
fs.readFileSync(`${process.cwd()}/app/components/client/glossary-scripts.js`, "utf-8") +
"</script>";
if (partialPath === "overview") if (partialPath === "overview")
pageScript = "<script>" + fs.readFileSync(`${process.cwd()}/app/components/client/ecosystem-scripts.js`, "utf-8") + "</script>"; pageScript =
"<script>" +
fs.readFileSync(`${process.cwd()}/app/components/client/ecosystem-scripts.js`, "utf-8") +
"</script>";
if (partialPath === "playground") if (partialPath === "playground")
pageScript = "<script>" + fs.readFileSync(`${process.cwd()}/app/components/client/playground-scripts.js`, "utf-8") + "</script>"; pageScript =
"<script>" +
fs.readFileSync(`${process.cwd()}/app/components/client/playground-scripts.js`, "utf-8") +
"</script>";
return html` return html`
<article class="page" itemtype="http://schema.org/BlogPosting"> <article class="page" itemtype="http://schema.org/BlogPosting">

View file

@ -11,7 +11,7 @@
"dependencies": { "dependencies": {
"@babel/polyfill": "^7.2.5", "@babel/polyfill": "^7.2.5",
"@inc/fastify-ws": "^1.1.0", "@inc/fastify-ws": "^1.1.0",
"@octokit/rest": "^16.13.1", "@octokit/rest": "^16.13.4",
"@slack/client": "^4.8.0", "@slack/client": "^4.8.0",
"async": "^2.6.1", "async": "^2.6.1",
"async-es": "^2.6.1", "async-es": "^2.6.1",
@ -62,9 +62,9 @@
"@babel/preset-env": "^7.3.1", "@babel/preset-env": "^7.3.1",
"@babel/register": "^7.0.0", "@babel/register": "^7.0.0",
"@inc/eslint-config": "^1.1.2", "@inc/eslint-config": "^1.1.2",
"@inc/sasslint-config": "^1.1.2", "@inc/sasslint-config": "^1.1.3",
"@lbry/color": "^1.1.0", "@lbry/color": "^1.1.0",
"@lbry/components": "^1.8.1", "@lbry/components": "^1.9.0",
"eslint": "^5.12.1", "eslint": "^5.12.1",
"husky": "^1.3.1", "husky": "^1.3.1",
"nodemon": "^1.18.9", "nodemon": "^1.18.9",