bump node to 22 and fixing broken stuff
This commit is contained in:
parent
a3ec616fd4
commit
420d0c6635
40 changed files with 7774 additions and 6208 deletions
15
.env.sample
15
.env.sample
|
@ -2,15 +2,9 @@
|
||||||
# HTTPS is assumed for security reasons
|
# HTTPS is assumed for security reasons
|
||||||
DAEMON_URL=
|
DAEMON_URL=
|
||||||
|
|
||||||
# These are for powering the LBRY Developer Program
|
|
||||||
# /developer-program
|
|
||||||
GITHUB_APP_ID=
|
|
||||||
GITHUB_APP_SECRET=
|
|
||||||
REWARD_URL=api.lbry.com
|
|
||||||
|
|
||||||
# https://developer.github.com/apps/building-oauth-apps/creating-an-oauth-app
|
# https://developer.github.com/apps/building-oauth-apps/creating-an-oauth-app
|
||||||
# We use this to show the GitHub feed on the homepage
|
# We use this to show the GitHub feed on the homepage
|
||||||
GITHUB_OAUTH_TOKEN=
|
GITHUB_TOKEN=
|
||||||
|
|
||||||
# You can use openssl to generate impossible to guess tokens
|
# You can use openssl to generate impossible to guess tokens
|
||||||
# Ideally you would have a reference to this on your daemon so make sure that server is secure!
|
# Ideally you would have a reference to this on your daemon so make sure that server is secure!
|
||||||
|
@ -23,10 +17,3 @@ LBRY_DAEMON_IMAGES_PATH=
|
||||||
# Usually 443
|
# Usually 443
|
||||||
# This is commented-out for local development
|
# This is commented-out for local development
|
||||||
PORT=
|
PORT=
|
||||||
|
|
||||||
# https://devcenter.heroku.com/articles/rediscloud
|
|
||||||
REDISCLOUD_URL=
|
|
||||||
|
|
||||||
# https://api.slack.com/incoming-webhooks
|
|
||||||
# We get notified when issues with this app happens, directly in Slack
|
|
||||||
SLACK_WEBHOOK_URL=
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
FROM node:10.2.1
|
FROM node:22
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY package.json package.json
|
COPY package.json package.json
|
||||||
COPY package-lock.json package-lock.json
|
COPY package-lock.json package-lock.json
|
||||||
|
|
||||||
RUN npm install
|
RUN npm install --force
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|
||||||
CMD [ "npm", "start" ]
|
CMD [ "npm", "start", "--force" ]
|
|
@ -11,8 +11,8 @@ import ssr from "choo-ssr";
|
||||||
|
|
||||||
// U T I L S
|
// U T I L S
|
||||||
|
|
||||||
import head from "~component/head";
|
import head from "./components/head";
|
||||||
import wrapper from "~component/wrapper";
|
import wrapper from "./components/wrapper";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,97 +0,0 @@
|
||||||
"use strict"; /* global document, fetch, history, send, window */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
document.getElementById("get-started").onclick = event => {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
send({
|
|
||||||
message: "auth me with github"
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
if (window.location.search.includes("?code=")) {
|
|
||||||
document.querySelector("developer-program").innerHTML = `
|
|
||||||
<form onsubmit="return false;">
|
|
||||||
<input-submit>
|
|
||||||
<input id="walletAddress" placeholder="Your LBRY wallet address" type="text"/>
|
|
||||||
<input id="oauthCode" type="hidden" value="${window.location.search.split("?code=").pop()}"/>
|
|
||||||
<button id="creditsAcquire" title="Get LBRY credits" type="button">Get credits</button>
|
|
||||||
</input-submit>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<h4>Need An Address?</h4>
|
|
||||||
<p>To receive your LBC, you'll need a wallet address. While graphical wallets are available, the recommended path for engineers is to:</p>
|
|
||||||
|
|
||||||
<ol>
|
|
||||||
<li>Download <a href="https://github.com/lbryio/lbry-sdk/releases">the LBRY SDK</a>.</li>
|
|
||||||
<li>Launch the command-line utility (<code>./lbrynet start</code>).</li>
|
|
||||||
<li>Run <code>./lbrynet address unused</code> and copy the <code>id</code> field.</li>
|
|
||||||
</ol>
|
|
||||||
`;
|
|
||||||
|
|
||||||
history.replaceState({}, "", window.location.pathname); // clean up URL bar
|
|
||||||
}
|
|
||||||
|
|
||||||
if (document.getElementById("creditsAcquire")) {
|
|
||||||
document.getElementById("walletAddress").addEventListener("keyup", event => {
|
|
||||||
const key = event.keyCode ? event.keyCode : event.which;
|
|
||||||
|
|
||||||
if (key === 13)
|
|
||||||
document.getElementById("creditsAcquire").click();
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById("creditsAcquire").onclick = () => {
|
|
||||||
send({
|
|
||||||
address: document.getElementById("walletAddress").value,
|
|
||||||
code: document.getElementById("oauthCode").value,
|
|
||||||
message: "verify github token"
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelector("developer-program").innerHTML = "<p><em>Awaiting response from LBRY server...</em></p>";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function syncWithApi(data) { // eslint-disable-line no-unused-vars
|
|
||||||
const address = data.address;
|
|
||||||
const code = data.code;
|
|
||||||
|
|
||||||
if (code === null) {
|
|
||||||
document.querySelector("developer-program").innerHTML =
|
|
||||||
"<p><strong>There was an issue with accessing GitHub's API. Please try again later.</strong></p>";
|
|
||||||
}
|
|
||||||
|
|
||||||
fetch(`https://api.lbry.com/reward/new?github_token=${code}&reward_type=github_developer&wallet_address=${address}`)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(result => {
|
|
||||||
switch(true) {
|
|
||||||
case result.error === "This reward is limited to 1 per person":
|
|
||||||
document.querySelector("developer-program").innerHTML =
|
|
||||||
"<p>You have already claimed this reward. This reward is limited to <strong>ONE</strong> per person. Your enthusiasm is appreciated.</p>";
|
|
||||||
return;
|
|
||||||
|
|
||||||
case Boolean(result.error):
|
|
||||||
document.querySelector("developer-program").innerHTML =
|
|
||||||
`<p>${result.error}</p>`;
|
|
||||||
return;
|
|
||||||
|
|
||||||
case result.success:
|
|
||||||
result = result.data;
|
|
||||||
document.querySelector("developer-program").innerHTML =
|
|
||||||
`<p><strong>Success!</strong> Your wallet has been credited with ${result.reward_amount} LBC.</p><p>We have a great reference for the <a href="/api/sdk">LBRY SDK here</a> to help you get started.</p><p>You can see proof of this transaction on <a href="https://explorer.lbry.com/tx/${result.transaction_id}">our Blockchain Explorer</a>.</p>`;
|
|
||||||
return;
|
|
||||||
|
|
||||||
default:
|
|
||||||
console.info(data); // eslint-disable-line no-console
|
|
||||||
document.querySelector("developer-program").innerHTML =
|
|
||||||
"<p><strong>No success or error was received so the LBRY API might be down.<br/>Please try again later.</strong></p>";
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error(error);
|
|
||||||
|
|
||||||
// Idk what the error would be (probably a 500) so let's just have this message
|
|
||||||
document.querySelector("developer-program").innerHTML =
|
|
||||||
"<p><strong>LBRY API is down. Please try again later.</strong></p>";
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// I M P O R T
|
|
||||||
|
|
||||||
import html from "choo/html";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// E X P O R T
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
if (
|
|
||||||
!process.env.GITHUB_APP_ID ||
|
|
||||||
!process.env.GITHUB_APP_SECRET ||
|
|
||||||
!process.env.REWARD_URL
|
|
||||||
) {
|
|
||||||
return html`
|
|
||||||
<developer-program>
|
|
||||||
<p><strong>Environment variables required to enable functionality are missing.</strong></p>
|
|
||||||
</developer-program>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<developer-program>
|
|
||||||
<button class="button" id="get-started">Claim Developer LBC</button>
|
|
||||||
<small class="meta">This will authenticate you with GitHub to prove eligibility as well as mark you as a follower of LBRY.</small>
|
|
||||||
</developer-program>
|
|
||||||
`;
|
|
||||||
};
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// U T I L
|
// U T I L
|
||||||
|
|
||||||
import markdown from "~component/markdown";
|
import markdown from "../../components/markdown";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// U T I L
|
// U T I L
|
||||||
|
|
||||||
import markdown from "~component/markdown";
|
import markdown from "../../components/markdown";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// U T I L
|
// U T I L
|
||||||
|
|
||||||
import markdown from "~component/markdown";
|
import markdown from "../../components/markdown";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// U T I L
|
// U T I L
|
||||||
|
|
||||||
import markdown from "~component/markdown";
|
import markdown from "../../components/markdown";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// U T I L
|
// U T I L
|
||||||
|
|
||||||
import markdown from "~component/markdown";
|
import markdown from "../../components/markdown";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// U T I L
|
// U T I L
|
||||||
|
|
||||||
import markdown from "~component/markdown";
|
import markdown from "../../components/markdown";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// U T I L
|
// U T I L
|
||||||
|
|
||||||
import markdown from "~component/markdown";
|
import markdown from "../../components/markdown";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import html from "choo/html";
|
||||||
|
|
||||||
// U T I L
|
// U T I L
|
||||||
|
|
||||||
import config from "~root/config";
|
import config from "../../config";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ import html from "choo/html";
|
||||||
// U T I L S
|
// U T I L S
|
||||||
|
|
||||||
import editLink from "./edit-link";
|
import editLink from "./edit-link";
|
||||||
import emailSubscribe from "./email-subscribe";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,15 +19,11 @@ export default state => {
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<section class="email-subscribe-container">
|
|
||||||
${emailSubscribe()}
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<div class="inner-wrap">
|
<div class="inner-wrap">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<a href="//${process.env.NODE_ENV === "development" ? "localhost:8000" : "lbry.com"}" title="Rediscover content freedom">← LBRY.com</a> |
|
<a href="//lbry.org" title="Rediscover content freedom">← LBRY.org</a> |
|
||||||
${editLink(state.href)}
|
${editLink(state.href)}
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
@ -40,6 +35,5 @@ export default state => {
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<script src="/assets/scripts/app.js"></script>
|
|
||||||
`;
|
`;
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,7 +8,7 @@ import html from "choo/html";
|
||||||
|
|
||||||
// U T I L
|
// U T I L
|
||||||
|
|
||||||
import config from "~root/config";
|
import config from "../../config";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,8 +61,8 @@ export default (state, emit) => {
|
||||||
<link rel="icon" href="/assets/favicon.svg" type="image/svg+xml"/>
|
<link rel="icon" href="/assets/favicon.svg" type="image/svg+xml"/>
|
||||||
<link rel="mask-icon" href="/assets/favicon.svg" color="${config.meta.color}"/>
|
<link rel="mask-icon" href="/assets/favicon.svg" color="${config.meta.color}"/>
|
||||||
<link rel="shortcut icon" href="/assets/favicon.ico"/>
|
<link rel="shortcut icon" href="/assets/favicon.ico"/>
|
||||||
<link rel="stylesheet" href="https://rsms.me/inter/inter.css"/>
|
<link rel="preconnect" href="https://fonts.bunny.net">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/tonsky/FiraCode@master/distr/fira_code.css"/>
|
<link href="https://fonts.bunny.net/css?family=inter:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet" />
|
||||||
<link rel="stylesheet" href="/assets/bundle.css"/>
|
<link rel="stylesheet" href="/assets/bundle.css"/>
|
||||||
|
|
||||||
<script src="/assets/scripts/sockets.js"></script>
|
<script src="/assets/scripts/sockets.js"></script>
|
||||||
|
|
|
@ -26,7 +26,7 @@ export default links => {
|
||||||
// H E L P E R
|
// H E L P E R
|
||||||
|
|
||||||
function returnLinkTemplate(title, description, destination, label) {
|
function returnLinkTemplate(title, description, destination, label) {
|
||||||
return `
|
return html`
|
||||||
<li class="link-grid__link">
|
<li class="link-grid__link">
|
||||||
<p class="link-grid__title"><strong>${title}</strong></p>
|
<p class="link-grid__title"><strong>${title}</strong></p>
|
||||||
<p class="link-grid__description">${description}</p>
|
<p class="link-grid__description">${description}</p>
|
||||||
|
|
|
@ -11,7 +11,7 @@ import fs from "graceful-fs";
|
||||||
import html from "choo/html";
|
import html from "choo/html";
|
||||||
import m from "markdown-it";
|
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 "../modules/markdown-it-sup";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import raw from "choo/html/raw";
|
import raw from "choo/html/raw";
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,9 @@ import html from "choo/html";
|
||||||
export default currentUrl => {
|
export default currentUrl => {
|
||||||
const links = [
|
const links = [
|
||||||
{
|
{
|
||||||
name: "LBRY.com",
|
name: "LBRY.org",
|
||||||
title: "Escape the techno scene",
|
title: "Escape the techno scene",
|
||||||
url: process.env.NODE_ENV === "development" ? "http://localhost:8000" : "https://lbry.com"
|
url: "https://lbry.org"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Overview",
|
name: "Overview",
|
||||||
|
|
|
@ -8,7 +8,7 @@ import asyncHtml from "choo-async/html";
|
||||||
|
|
||||||
// U T I L S
|
// U T I L S
|
||||||
|
|
||||||
import config from "~root/config";
|
import config from "../../config";
|
||||||
import footer from "./footer";
|
import footer from "./footer";
|
||||||
import navigation from "./navigation";
|
import navigation from "./navigation";
|
||||||
|
|
||||||
|
@ -29,15 +29,5 @@ export default children => (state, emit) => {
|
||||||
${children.default(state, emit)}
|
${children.default(state, emit)}
|
||||||
${footer(state, emit)}
|
${footer(state, emit)}
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script>
|
|
||||||
(function(i,s,o,g,r,a,m){i["GoogleAnalyticsObject"]=r;i[r]=i[r]||function(){
|
|
||||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
|
||||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|
||||||
})(window,document,"script","https://www.google-analytics.com/analytics.js","ga");
|
|
||||||
|
|
||||||
ga("create", "${config.ga}", "auto");
|
|
||||||
ga("send", "pageview");
|
|
||||||
</script>
|
|
||||||
`;
|
`;
|
||||||
};
|
};
|
||||||
|
|
10
app/dist/scripts/sockets.js
vendored
10
app/dist/scripts/sockets.js
vendored
|
@ -25,11 +25,6 @@ function initializeWebSocketConnection() {
|
||||||
let data = JSON.parse(socket.data);
|
let data = JSON.parse(socket.data);
|
||||||
|
|
||||||
switch(true) {
|
switch(true) {
|
||||||
case data.message === "github token status":
|
|
||||||
data = data.data;
|
|
||||||
syncWithApi(data); // eslint-disable-line no-undef
|
|
||||||
break;
|
|
||||||
|
|
||||||
case data.message === "notification": // TODO: Make work with appending so multiple notifications can be sent
|
case data.message === "notification": // TODO: Make work with appending so multiple notifications can be sent
|
||||||
document.getElementById("flash-container").innerHTML =
|
document.getElementById("flash-container").innerHTML =
|
||||||
`<div class="flash active${data.type ? " " + data.type : ""}">${data.details}</div>`;
|
`<div class="flash active${data.type ? " " + data.type : ""}">${data.details}</div>`;
|
||||||
|
@ -93,11 +88,6 @@ function initializeWebSocketConnection() {
|
||||||
if (data.class)
|
if (data.class)
|
||||||
document.querySelector(data.selector).classList.add(data.class);
|
document.querySelector(data.selector).classList.add(data.class);
|
||||||
|
|
||||||
if (data.selector !== "#emailMessage") {
|
|
||||||
document.getElementById("emailAddress").value = "";
|
|
||||||
document.getElementById("emailMessage").innerHTML = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.example === 2) {
|
if (data.example === 2) {
|
||||||
detectLanguageAndUpdate(); // eslint-disable-line no-undef
|
detectLanguageAndUpdate(); // eslint-disable-line no-undef
|
||||||
initCanvas(); // eslint-disable-line no-undef
|
initCanvas(); // eslint-disable-line no-undef
|
||||||
|
|
|
@ -4,19 +4,17 @@
|
||||||
|
|
||||||
// I M P O R T S
|
// I M P O R T S
|
||||||
|
|
||||||
import got from "got";
|
|
||||||
import prism from "prismjs";
|
import prism from "prismjs";
|
||||||
import raw from "choo/html/raw";
|
import raw from "choo/html/raw";
|
||||||
import stringifyObject from "stringify-object";
|
import stringifyObject from "stringify-object";
|
||||||
|
|
||||||
// U T I L S
|
// U T I L S
|
||||||
|
|
||||||
import messageSlack from "./slack";
|
|
||||||
import publishMeme from "./publish-meme";
|
import publishMeme from "./publish-meme";
|
||||||
import lbrytvAPI from "~helper/lbrytv-sdk";
|
import lbrytvAPI from "../helpers/lbrytv-sdk";
|
||||||
|
|
||||||
import randomString from "./random-string";
|
import randomString from "./random-string";
|
||||||
import { send } from "~socket";
|
import { send } from "../sockets";
|
||||||
import uploadImage from "./upload-image";
|
import uploadImage from "./upload-image";
|
||||||
|
|
||||||
const allowedQueryMethods = [
|
const allowedQueryMethods = [
|
||||||
|
@ -164,14 +162,6 @@ export default async(data, socket) => {
|
||||||
type: "error"
|
type: "error"
|
||||||
});
|
});
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== "development") {
|
|
||||||
messageSlack({
|
|
||||||
message: "```" + JSON.parse(JSON.stringify(memePublishError.error)) + "```",
|
|
||||||
pretext: "_Someone is going through the Playground after a response has been parsed_",
|
|
||||||
title: `DAEMON ERROR | ${environment}`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch(imageUploadError) {
|
} catch(imageUploadError) {
|
||||||
|
@ -181,14 +171,6 @@ export default async(data, socket) => {
|
||||||
type: "error"
|
type: "error"
|
||||||
});
|
});
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== "development") {
|
|
||||||
messageSlack({
|
|
||||||
message: "```" + imageUploadError.status + "```",
|
|
||||||
pretext: "_Someone attempted to upload a meme to the web daemon and it failed_",
|
|
||||||
title: `DAEMON ERROR | ${environment}`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,10 +203,8 @@ export default async(data, socket) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
messageSlack({
|
console.log(error);
|
||||||
message: "```" + error + "```",
|
|
||||||
title: "DAEMON ERROR: resolve"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -250,7 +230,7 @@ export default async(data, socket) => {
|
||||||
`https://${process.env.DAEMON_URL}/${resolveMethod}`;
|
`https://${process.env.DAEMON_URL}/${resolveMethod}`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await got(queryUrl, queryOptions);
|
const response = await fetch(queryUrl, queryOptions);
|
||||||
|
|
||||||
switch(true) {
|
switch(true) {
|
||||||
case data.example === 3:
|
case data.example === 3:
|
||||||
|
@ -289,11 +269,6 @@ export default async(data, socket) => {
|
||||||
return response.body.result[Object.keys(response.body.result)[0]];
|
return response.body.result[Object.keys(response.body.result)[0]];
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
messageSlack({
|
|
||||||
message: "```" + error + "```",
|
|
||||||
pretext: "_Someone is going through the Playground and the daemon is not running_",
|
|
||||||
title: `DAEMON ERROR | ${environment}`
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,44 +4,20 @@
|
||||||
|
|
||||||
// P A C K A G E S
|
// P A C K A G E S
|
||||||
|
|
||||||
import async from "async";
|
|
||||||
import color from "colorette";
|
|
||||||
import Octokit from "@octokit/rest";
|
|
||||||
import redis from "redis";
|
|
||||||
|
|
||||||
// U T I L S
|
// U T I L S
|
||||||
|
|
||||||
import messageSlack from "~helper/slack";
|
import relativeDate from "../modules/relative-date";
|
||||||
import relativeDate from "~module/relative-date";
|
|
||||||
|
|
||||||
let octokit;
|
|
||||||
|
|
||||||
// R E D I S
|
|
||||||
|
|
||||||
let client;
|
|
||||||
|
|
||||||
if (process.env.GITHUB_OAUTH_TOKEN) {
|
|
||||||
octokit = new Octokit({
|
|
||||||
auth: `token ${process.env.GITHUB_OAUTH_TOKEN}`
|
|
||||||
});
|
|
||||||
} else process.stdout.write(`${color.red("[missing]")} GitHub token\n`);
|
|
||||||
|
|
||||||
if (process.env.REDISCLOUD_URL) {
|
|
||||||
client = redis.createClient(process.env.REDISCLOUD_URL);
|
|
||||||
|
|
||||||
client.on("error", redisError => {
|
|
||||||
process.env.NODE_ENV === "development" ?
|
|
||||||
process.stdout.write(`\n${color.yellow("Unable to connect to Redis client.")}\nYou may be missing an .env file or your connection was reset.`) :
|
|
||||||
messageSlack(
|
|
||||||
"\n" +
|
|
||||||
"> *REDIS ERROR:* ```" + JSON.parse(JSON.stringify(redisError)) + "```" + "\n" +
|
|
||||||
"> _Cause: Someone is trying to run LBRY.tech locally without environment variables OR Heroku is busted_\n"
|
|
||||||
)
|
|
||||||
;
|
|
||||||
});
|
|
||||||
} else process.stdout.write(`${color.red("[missing]")} Redis client URL\n`);
|
|
||||||
|
|
||||||
|
|
||||||
|
let githubFeed;
|
||||||
|
let lastGithubFeedUpdate;
|
||||||
|
updateGithubFeed();
|
||||||
|
|
||||||
|
// Update the feed every 5 minutes
|
||||||
|
setInterval(async () => {
|
||||||
|
githubFeed = await updateGithubFeed();
|
||||||
|
}, 5 * 60 * 1000);
|
||||||
|
|
||||||
// P R O G R A M
|
// P R O G R A M
|
||||||
|
|
||||||
|
@ -264,17 +240,13 @@ function generateEvent(event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateGitHubFeed(displayGitHubFeed) {
|
async function generateGitHubFeed(displayGitHubFeed) {
|
||||||
if (process.env.REDISCLOUD_URL) {
|
await githubFeed;
|
||||||
client.zrevrange("events", 0, 9, (err, reply) => {
|
if (!githubFeed) return;
|
||||||
if (err) return; // TODO: Render a div with nice error message
|
|
||||||
|
|
||||||
const events = [];
|
|
||||||
const renderedEvents = [];
|
const renderedEvents = [];
|
||||||
|
|
||||||
reply.forEach(item => events.push(JSON.parse(item)));
|
for (const event of githubFeed) {
|
||||||
|
|
||||||
for (const event of events) {
|
|
||||||
const repoName = `
|
const repoName = `
|
||||||
<a href="${generateUrl("repo", event)}" title="View this repo on GitHub" target="_blank" rel="noopener noreferrer"><strong>${event.repo.name}</strong></a>
|
<a href="${generateUrl("repo", event)}" title="View this repo on GitHub" target="_blank" rel="noopener noreferrer"><strong>${event.repo.name}</strong></a>
|
||||||
`;
|
`;
|
||||||
|
@ -294,19 +266,15 @@ function generateGitHubFeed(displayGitHubFeed) {
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateGithubFeed(); // TODO: Update `.last-updated` every minute
|
|
||||||
|
|
||||||
displayGitHubFeed(`
|
displayGitHubFeed(`
|
||||||
<h3>GitHub</h3>
|
<h3>GitHub</h3>
|
||||||
<h5 class="last-updated">Last updated: ${new Date().format("YYYY-MM-DD")
|
<h5 class="last-updated">Last updated: ${lastGithubFeedUpdate.format("YYYY-MM-DD")
|
||||||
.replace(/-/g, "·")} at ${new Date().add(-4, "hours")
|
.replace(/-/g, "·")} at ${lastGithubFeedUpdate
|
||||||
.format("UTC:H:mm:ss A")
|
.format("UTC:H:mm:ss A")
|
||||||
.toLowerCase()} EST</h5>
|
.toLowerCase()} UTC</h5>
|
||||||
|
|
||||||
${renderedEvents.join("")}
|
${renderedEvents.join("")}
|
||||||
`);
|
`);
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateUrl(type, event) {
|
function generateUrl(type, event) {
|
||||||
|
@ -343,33 +311,25 @@ function generateUrl(type, event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateGithubFeed() {
|
async function updateGithubFeed() {
|
||||||
octokit.activity.listPublicEventsForOrg({
|
let response;
|
||||||
org: "lbryio",
|
|
||||||
per_page: 20,
|
try {
|
||||||
page: 1
|
lastGithubFeedUpdate = new Date();
|
||||||
}).then(({ data }) => {
|
|
||||||
async.eachSeries(data, (item, callback) => {
|
response = await fetch(`https://api.github.com/orgs/lbryfoundation/events`, process.env.GITHUB_TOKEN && {
|
||||||
const eventString = JSON.stringify(item);
|
headers: {
|
||||||
|
'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
|
||||||
client.zrank("events", eventString, (err, reply) => {
|
|
||||||
if (err)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (reply === null)
|
githubFeed = await response.json();
|
||||||
client.zadd("events", item.id, eventString, callback);
|
|
||||||
else
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}, () => client.zremrangebyrank("events", 0, -51)); // Keep the latest 50 events
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
messageSlack(
|
|
||||||
"\n" +
|
|
||||||
"> *GITHUB FEED ERROR:* ```" + JSON.parse(JSON.stringify(err)) + "```" + "\n" +
|
|
||||||
"> _Cause: GitHub feed refresh_\n"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
import messageSlack from "./slack";
|
|
||||||
const request = require("request");
|
const request = require("request");
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,18 +25,10 @@ const resolve = function(urls) {
|
||||||
|
|
||||||
request(options, function(error, response, daemonResponse) {
|
request(options, function(error, response, daemonResponse) {
|
||||||
if (error) {
|
if (error) {
|
||||||
messageSlack({
|
|
||||||
message: "```" + error + "```",
|
|
||||||
title: "DAEMON ERROR: resolve"
|
|
||||||
});
|
|
||||||
return reject(new Error("DAEMON ERROR: resolve"));
|
return reject(new Error("DAEMON ERROR: resolve"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Object.prototype.hasOwnProperty.call(daemonResponse, "error")) {
|
if (Object.prototype.hasOwnProperty.call(daemonResponse, "error")) {
|
||||||
messageSlack({
|
|
||||||
message: "```" + daemonResponse.error + "```",
|
|
||||||
title: "DAEMON ERROR: resolve"
|
|
||||||
});
|
|
||||||
return reject(new Error("DAEMON ERROR: resolve"));
|
return reject(new Error("DAEMON ERROR: resolve"));
|
||||||
} else
|
} else
|
||||||
return resolve(daemonResponse.result);
|
return resolve(daemonResponse.result);
|
||||||
|
@ -86,18 +77,10 @@ const getTrending = function() {
|
||||||
|
|
||||||
request(options, function(error, response, daemonResponse) {
|
request(options, function(error, response, daemonResponse) {
|
||||||
if (error) {
|
if (error) {
|
||||||
messageSlack({
|
|
||||||
message: "```" + error + "```",
|
|
||||||
title: "DAEMON ERROR: trending"
|
|
||||||
});
|
|
||||||
return reject(new Error("DAEMON ERROR: trending"));
|
return reject(new Error("DAEMON ERROR: trending"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Object.prototype.hasOwnProperty.call(daemonResponse, "error")) {
|
if (Object.prototype.hasOwnProperty.call(daemonResponse, "error")) {
|
||||||
messageSlack({
|
|
||||||
message: "```" + daemonResponse.error + "```",
|
|
||||||
title: "DAEMON ERROR: trending"
|
|
||||||
});
|
|
||||||
return reject(JSON.stringify(daemonResponse));
|
return reject(JSON.stringify(daemonResponse));
|
||||||
} else
|
} else
|
||||||
return resolve(daemonResponse.result.items);
|
return resolve(daemonResponse.result.items);
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
// I M P O R T
|
// I M P O R T
|
||||||
|
|
||||||
import got from "got";
|
|
||||||
|
|
||||||
// U T I L
|
// U T I L
|
||||||
|
|
||||||
|
@ -18,6 +17,7 @@ const queryUrl = process.env.NODE_ENV === "development" ?
|
||||||
|
|
||||||
export default async(publishMetadata) => {
|
export default async(publishMetadata) => {
|
||||||
const options = {
|
const options = {
|
||||||
|
method: 'PUT',
|
||||||
body: {
|
body: {
|
||||||
authorization: process.env.LBRY_DAEMON_ACCESS_TOKEN,
|
authorization: process.env.LBRY_DAEMON_ACCESS_TOKEN,
|
||||||
metadata: publishMetadata
|
metadata: publishMetadata
|
||||||
|
@ -26,7 +26,7 @@ export default async(publishMetadata) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await got.put(queryUrl, options);
|
const response = await fetch(queryUrl, options);
|
||||||
return response.body; // eslint-disable-line padding-line-between-statements
|
return response.body; // eslint-disable-line padding-line-between-statements
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
return error;
|
return error;
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// I M P O R T
|
|
||||||
|
|
||||||
import { IncomingWebhook } from "@slack/client";
|
|
||||||
|
|
||||||
// U T I L S
|
|
||||||
|
|
||||||
require("dotenv").config();
|
|
||||||
|
|
||||||
const environmentMessage = process.env.NODE_ENV === "development" ?
|
|
||||||
"\n_— in DEVELOPMENT_" :
|
|
||||||
"\n_— in PRODUCTION_";
|
|
||||||
|
|
||||||
const slackUrl = process.env.SLACK_WEBHOOK_URL || "";
|
|
||||||
const slackWebhook = new IncomingWebhook(slackUrl);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// P R O G R A M
|
|
||||||
|
|
||||||
export default ({ message, pretext, title }) => {
|
|
||||||
if (!slackUrl) return;
|
|
||||||
pretext = pretext || "" + environmentMessage;
|
|
||||||
|
|
||||||
slackWebhook.send({
|
|
||||||
attachments: [{
|
|
||||||
mrkdwn_in: [
|
|
||||||
"text",
|
|
||||||
"pretext"
|
|
||||||
],
|
|
||||||
pretext: pretext || "",
|
|
||||||
text: message || "",
|
|
||||||
title: title || ""
|
|
||||||
}]
|
|
||||||
}, (error, response) => { // eslint-disable-line no-unused-vars
|
|
||||||
if (error) console.log(error); // eslint-disable-line no-console
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
// I M P O R T
|
// I M P O R T
|
||||||
|
|
||||||
import got from "got";
|
|
||||||
|
|
||||||
// U T I L
|
// U T I L
|
||||||
|
|
||||||
|
@ -18,6 +17,7 @@ const queryUrl = process.env.NODE_ENV === "development" ?
|
||||||
|
|
||||||
export default async(imageSource) => {
|
export default async(imageSource) => {
|
||||||
const options = {
|
const options = {
|
||||||
|
method: 'POST',
|
||||||
body: {
|
body: {
|
||||||
authorization: process.env.LBRY_DAEMON_ACCESS_TOKEN,
|
authorization: process.env.LBRY_DAEMON_ACCESS_TOKEN,
|
||||||
image: imageSource
|
image: imageSource
|
||||||
|
@ -26,7 +26,7 @@ export default async(imageSource) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await got.post(queryUrl, options);
|
const response = await fetch(queryUrl, options);
|
||||||
return response.body; // eslint-disable-line padding-line-between-statements
|
return response.body; // eslint-disable-line padding-line-between-statements
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
return error;
|
return error;
|
||||||
|
|
31
app/index.js
31
app/index.js
|
@ -6,9 +6,7 @@
|
||||||
|
|
||||||
import * as color from "colorette";
|
import * as color from "colorette";
|
||||||
import compress from "fastify-compress";
|
import compress from "fastify-compress";
|
||||||
import cors from "cors";
|
|
||||||
import fastify from "fastify";
|
import fastify from "fastify";
|
||||||
import helmet from "fastify-helmet";
|
|
||||||
import ssr from "choo-ssr/fastify";
|
import ssr from "choo-ssr/fastify";
|
||||||
import statik from "fastify-static";
|
import statik from "fastify-static";
|
||||||
import websockets from "fastify-ws";
|
import websockets from "fastify-ws";
|
||||||
|
@ -16,26 +14,12 @@ import websockets from "fastify-ws";
|
||||||
// U T I L S
|
// U T I L S
|
||||||
|
|
||||||
import handleSocketMessages from "./sockets";
|
import handleSocketMessages from "./sockets";
|
||||||
import messageSlack from "~helper/slack";
|
import redirects from "./data/redirects.json";
|
||||||
import redirects from "~data/redirects.json";
|
|
||||||
|
|
||||||
const server = fastify({
|
const server = fastify({
|
||||||
logger: {
|
logger: {
|
||||||
level: "warn",
|
level: "warn",
|
||||||
prettyPrint: process.env.NODE_ENV === "development",
|
prettyPrint: process.env.NODE_ENV === "development",
|
||||||
redact: ["req.headers.authorization"],
|
|
||||||
serializers: {
|
|
||||||
req(req) {
|
|
||||||
return {
|
|
||||||
headers: req.headers,
|
|
||||||
hostname: req.hostname,
|
|
||||||
method: req.method,
|
|
||||||
remoteAddress: req.ip,
|
|
||||||
remotePort: req.connection.remotePort,
|
|
||||||
url: req.url
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -44,14 +28,8 @@ const server = fastify({
|
||||||
// P R O G R A M
|
// P R O G R A M
|
||||||
|
|
||||||
server
|
server
|
||||||
.use(cors())
|
|
||||||
.register(compress)
|
.register(compress)
|
||||||
.register(websockets)
|
.register(websockets)
|
||||||
.register(helmet, {
|
|
||||||
hidePoweredBy: {
|
|
||||||
setTo: "LBRY"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.register(statik, {
|
.register(statik, {
|
||||||
prefix: "/assets/",
|
prefix: "/assets/",
|
||||||
root: `${__dirname}/dist/`
|
root: `${__dirname}/dist/`
|
||||||
|
@ -84,10 +62,5 @@ server
|
||||||
// B E G I N
|
// B E G I N
|
||||||
|
|
||||||
server.listen(process.env.PORT || 8080, process.env.IP || "0.0.0.0", async() => {
|
server.listen(process.env.PORT || 8080, process.env.IP || "0.0.0.0", async() => {
|
||||||
process.env.NODE_ENV === "development" ?
|
process.stdout.write(`\n— ${color.green("⚡")} ${server.server.address().port}\n`)
|
||||||
process.stdout.write(`\n— ${color.green("⚡")} ${server.server.address().port}\n`) :
|
|
||||||
messageSlack({
|
|
||||||
message: `Server started at port \`${server.server.address().port}\``,
|
|
||||||
title: "APP BOOT"
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
@import "partials/animation";
|
@import "partials/animation";
|
||||||
@import "partials/ecosystem";
|
@import "partials/ecosystem";
|
||||||
@import "partials/email-subscribe";
|
|
||||||
@import "partials/feature-links";
|
@import "partials/feature-links";
|
||||||
@import "partials/flash";
|
@import "partials/flash";
|
||||||
@import "partials/footer";
|
@import "partials/footer";
|
||||||
|
@ -22,7 +21,6 @@
|
||||||
|
|
||||||
@import "pages/api";
|
@import "pages/api";
|
||||||
@import "pages/contributing";
|
@import "pages/contributing";
|
||||||
@import "pages/developer";
|
|
||||||
@import "pages/documentation";
|
@import "pages/documentation";
|
||||||
@import "pages/home";
|
@import "pages/home";
|
||||||
@import "pages/page";
|
@import "pages/page";
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
developer-program {
|
|
||||||
@extend %markdown;
|
|
||||||
|
|
||||||
input-submit {
|
|
||||||
padding-top: 0.5rem;
|
|
||||||
|
|
||||||
button {
|
|
||||||
color: $lbry-white;
|
|
||||||
padding-right: 1.5rem;
|
|
||||||
padding-left: 1.5rem;
|
|
||||||
transition: background-color 0.2s;
|
|
||||||
|
|
||||||
&:not(:hover) {
|
|
||||||
background-color: $lbry-black;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: $lbry-teal-4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
margin: 1rem auto;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
small {
|
|
||||||
display: block;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,137 +0,0 @@
|
||||||
.newsletter-cta {
|
|
||||||
background-color: $lbry-gray-1;
|
|
||||||
padding-top: 1rem;
|
|
||||||
padding-bottom: 1rem;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
> div:first-of-type {
|
|
||||||
margin-right: auto;
|
|
||||||
margin-left: auto;
|
|
||||||
|
|
||||||
@media (min-width: 551px) {
|
|
||||||
width: 500px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 550px) {
|
|
||||||
width: 90%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
@include clearfix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsletter-cta__title {
|
|
||||||
font-size: 0.8rem;
|
|
||||||
letter-spacing: 0.05rem;
|
|
||||||
margin-bottom: 0.75rem;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsletter-cta__input,
|
|
||||||
.newsletter-cta__submit {
|
|
||||||
@extend .__button-padding-horizontal;
|
|
||||||
border-style: solid;
|
|
||||||
border-width: 1px;
|
|
||||||
|
|
||||||
@media (max-width: 550px) {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsletter-cta__input {
|
|
||||||
height: 38px;
|
|
||||||
|
|
||||||
background-color: $lbry-white;
|
|
||||||
font-size: 1rem;
|
|
||||||
transition: border 0.2s;
|
|
||||||
|
|
||||||
@media (min-width: 551px) {
|
|
||||||
width: calc(100% - 112px);
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 550px) {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:not(:focus) {
|
|
||||||
border-top-color: $lbry-black;
|
|
||||||
border-left-color: $lbry-black;
|
|
||||||
|
|
||||||
@media (min-width: 551px) {
|
|
||||||
border-right-color: transparent;
|
|
||||||
border-bottom-color: $lbry-black;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 550px) {
|
|
||||||
border-right-color: $lbry-black;
|
|
||||||
border-bottom-color: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
border-top-color: $lbry-teal-5;
|
|
||||||
border-left-color: $lbry-teal-5;
|
|
||||||
|
|
||||||
@media (min-width: 551px) {
|
|
||||||
border-right-color: transparent;
|
|
||||||
border-bottom-color: $lbry-teal-5;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 550px) {
|
|
||||||
border-right-color: $lbry-teal-5;
|
|
||||||
border-bottom-color: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsletter-cta__submit {
|
|
||||||
@extend .__button-basic;
|
|
||||||
@extend .__button-padding-vertical;
|
|
||||||
color: $lbry-white;
|
|
||||||
|
|
||||||
@media (min-width: 551px) {
|
|
||||||
width: 112px; height: 38px;
|
|
||||||
left: -1px;
|
|
||||||
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 550px) {
|
|
||||||
top: -1px;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:not(:hover) {
|
|
||||||
background-color: $lbry-black;
|
|
||||||
border-color: $lbry-black;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: $lbry-teal-3;
|
|
||||||
border-color: $lbry-teal-5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsletter-cta__message {
|
|
||||||
@include clearfix;
|
|
||||||
color: $lbry-white;
|
|
||||||
cursor: default;
|
|
||||||
display: inline-block;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
&:not(:empty) {
|
|
||||||
margin: 0.5rem auto 0; padding: 0.25rem 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:not(.error) {
|
|
||||||
background-color: $lbry-teal-3;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.error {
|
|
||||||
background-color: $lbry-red-3;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -65,7 +65,7 @@
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(:first-of-type):not([href="http://localhost:8000"]):not([href="https://lbry.com"]) {
|
&:not(:first-of-type):not([href="http://localhost:8000"]):not([href="https://lbry.org"]) {
|
||||||
&::after {
|
&::after {
|
||||||
width: 100%; height: 3px;
|
width: 100%; height: 3px;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -96,13 +96,13 @@
|
||||||
line-height: 4rem;
|
line-height: 4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not([href="http://localhost:8000"]):not([href="https://lbry.com"]) {
|
&:not([href="http://localhost:8000"]):not([href="https://lbry.org"]) {
|
||||||
padding-right: 0.5rem;
|
padding-right: 0.5rem;
|
||||||
padding-left: 0.5rem;
|
padding-left: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
&[href="http://localhost:8000"],
|
&[href="http://localhost:8000"],
|
||||||
&[href="https://lbry.com"] {
|
&[href="https://lbry.org"] {
|
||||||
color: $lbry-white;
|
color: $lbry-white;
|
||||||
margin-right: 0.5rem;
|
margin-right: 0.5rem;
|
||||||
padding-right: 1rem;
|
padding-right: 1rem;
|
||||||
|
|
121
app/sockets.js
121
app/sockets.js
|
@ -4,25 +4,16 @@
|
||||||
|
|
||||||
// I M P O R T S
|
// I M P O R T S
|
||||||
|
|
||||||
import got from "got";
|
|
||||||
import html from "choo/html";
|
import html from "choo/html";
|
||||||
|
|
||||||
// U T I L S
|
// U T I L S
|
||||||
|
|
||||||
import apiPage from "~view/api";
|
import apiPage from "./views/api";
|
||||||
import fetchMetadata from "~helper/fetch-metadata";
|
import fetchMetadata from "./helpers/fetch-metadata";
|
||||||
import lbrytvAPI from "~helper/lbrytv-sdk";
|
import lbrytvAPI from "./helpers/lbrytv-sdk";
|
||||||
import { generateGitHubFeed } from "~helper/github";
|
import { generateGitHubFeed } from "./helpers/github";
|
||||||
import messageSlack from "~helper/slack";
|
|
||||||
import { URL } from "url";
|
import { URL } from "url";
|
||||||
|
|
||||||
const githubAppId = process.env.GITHUB_APP_ID;
|
|
||||||
const githubAppSecret = process.env.GITHUB_APP_SECRET;
|
|
||||||
|
|
||||||
// const githubAppId = process.env.GITHUB_APP_ID_TEST;
|
|
||||||
// const githubAppSecret = process.env.GITHUB_APP_SECRET_TEST;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// P R O G R A M
|
// P R O G R A M
|
||||||
|
|
||||||
|
@ -31,14 +22,6 @@ export default async(socket, action) => {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch(true) {
|
switch(true) {
|
||||||
case action.message === "auth me with github":
|
|
||||||
getGitHubUserToken(socket);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case action.message === "verify github token":
|
|
||||||
verifyGitHubToken(action, socket);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case action.message === "fetch metadata":
|
case action.message === "fetch metadata":
|
||||||
fetchMetadata(action, socket);
|
fetchMetadata(action, socket);
|
||||||
break;
|
break;
|
||||||
|
@ -87,11 +70,6 @@ export default async(socket, action) => {
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case action.message === "subscribe":
|
|
||||||
newsletterSubscribe(action, socket);
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
case action.message === "view different documentation version":
|
case action.message === "view different documentation version":
|
||||||
send(socket, {
|
send(socket, {
|
||||||
element: "div",
|
element: "div",
|
||||||
|
@ -134,7 +112,7 @@ function generateContent(exampleNumber, displayTrendingContent) {
|
||||||
for (const r in responses) {
|
for (const r in responses) {
|
||||||
const part = responses[r];
|
const part = responses[r];
|
||||||
|
|
||||||
if (part.value && part.value.thumbnail.url) {
|
if (part.value && part.value.thumbnail && part.value.thumbnail.url) {
|
||||||
renderedContentCollection.push(`
|
renderedContentCollection.push(`
|
||||||
<section class="playground-content__trend">
|
<section class="playground-content__trend">
|
||||||
<figure
|
<figure
|
||||||
|
@ -359,13 +337,6 @@ function generateMemeCreator(socket) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getGitHubUserToken(socket) {
|
|
||||||
send(socket, {
|
|
||||||
message: "redirect",
|
|
||||||
url: `https://github.com/login/oauth/authorize?client_id=${githubAppId}&scope=public_repo,user:email`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeImageSourceSecure(url) {
|
function makeImageSourceSecure(url) {
|
||||||
if (!url || !url.length)
|
if (!url || !url.length)
|
||||||
return url;
|
return url;
|
||||||
|
@ -378,88 +349,6 @@ function makeImageSourceSecure(url) {
|
||||||
return originalUrl.href;
|
return originalUrl.href;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function newsletterSubscribe(data, socket) {
|
|
||||||
const email = data.email;
|
|
||||||
|
|
||||||
if (!validateEmail(email)) {
|
|
||||||
send(socket, {
|
|
||||||
class: "error",
|
|
||||||
html: "Your email address is invalid",
|
|
||||||
message: "updated html",
|
|
||||||
selector: "#emailMessage"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await got.post(`https://api.lbry.com/list/subscribe?email=${encodeURIComponent(email)}&tag=developer`);
|
|
||||||
|
|
||||||
return send(socket, {
|
|
||||||
html: "Thank you! Please confirm subscription in your inbox.",
|
|
||||||
message: "updated html",
|
|
||||||
selector: "#emailMessage"
|
|
||||||
});
|
|
||||||
} catch(error) {
|
|
||||||
const response = JSON.parse(error.body);
|
|
||||||
|
|
||||||
if (!response.success) {
|
|
||||||
messageSlack({
|
|
||||||
message: `via ${email}: ${response.error}`,
|
|
||||||
title: "NEWSLETTER ERROR"
|
|
||||||
});
|
|
||||||
|
|
||||||
return send(socket, {
|
|
||||||
class: "error",
|
|
||||||
html: response.error,
|
|
||||||
message: "updated html",
|
|
||||||
selector: "#emailMessage"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
messageSlack({
|
|
||||||
message: `via ${email} (strange error): ${response.error}`,
|
|
||||||
title: "NEWSLETTER ERROR"
|
|
||||||
});
|
|
||||||
|
|
||||||
return send(socket, {
|
|
||||||
class: "error",
|
|
||||||
html: "Something is terribly wrong",
|
|
||||||
message: "updated html",
|
|
||||||
selector: "#emailMessage"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function send(transport, data) {
|
export function send(transport, data) {
|
||||||
return transport.send(JSON.stringify(data));
|
return transport.send(JSON.stringify(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateEmail(email) {
|
|
||||||
const emailRegex = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\\.,;:\s@"]{2,})$/i;
|
|
||||||
return emailRegex.test(String(email)); // eslint-disable-line padding-line-between-statements
|
|
||||||
}
|
|
||||||
|
|
||||||
async function verifyGitHubToken(data, socket) {
|
|
||||||
const code = data.code;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await got.post(`https://github.com/login/oauth/access_token?client_id=${githubAppId}&client_secret=${githubAppSecret}&code=${code}`, { json: true });
|
|
||||||
|
|
||||||
const response = {
|
|
||||||
address: data.address,
|
|
||||||
code: result.body.access_token
|
|
||||||
};
|
|
||||||
|
|
||||||
return send(socket, {
|
|
||||||
data: response,
|
|
||||||
message: "github token status"
|
|
||||||
});
|
|
||||||
} catch(verificationError) {
|
|
||||||
console.log(verificationError.body); // eslint-disable-line no-console
|
|
||||||
|
|
||||||
return send(socket, {
|
|
||||||
details: verificationError.body,
|
|
||||||
message: "notification",
|
|
||||||
type: "error"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -6,24 +6,18 @@
|
||||||
|
|
||||||
import asyncHtml from "choo-async/html";
|
import asyncHtml from "choo-async/html";
|
||||||
import dedent from "dedent";
|
import dedent from "dedent";
|
||||||
import got from "got";
|
|
||||||
import Octokit from "@octokit/rest";
|
|
||||||
|
|
||||||
// U T I L S
|
// U T I L S
|
||||||
|
|
||||||
import headerBlockchain from "~component/api/header-blockchain";
|
import headerBlockchain from "../components/api/header-blockchain";
|
||||||
import headerSdk from "~component/api/header-sdk";
|
import headerSdk from "../components/api/header-sdk";
|
||||||
import redirects from "~data/redirects.json";
|
import redirects from "../data/redirects.json";
|
||||||
|
|
||||||
const cache = new Map();
|
const cache = new Map();
|
||||||
const filePathBlockchain = "/contrib/devtools/generated/api_v1.json";
|
const filePathBlockchain = "/contrib/devtools/generated/api_v1.json";
|
||||||
const filePathSdk = "docs/api.json";
|
const filePathSdk = "docs/api.json";
|
||||||
const rawGitHubBase = "https://cdn.jsdelivr.net/gh/lbryfoundation/";
|
const rawGitHubBase = "https://cdn.jsdelivr.net/gh/lbryfoundation/";
|
||||||
|
|
||||||
const octokit = new Octokit({
|
|
||||||
auth: `token ${process.env.GITHUB_OAUTH_TOKEN}`
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// E X P O R T
|
// E X P O R T
|
||||||
|
@ -51,7 +45,7 @@ export default async(state) => {
|
||||||
<div class="__slate">
|
<div class="__slate">
|
||||||
<aside class="api-toc">
|
<aside class="api-toc">
|
||||||
<select class="api-toc__select" onchange="changeDocumentationVersion(value);">
|
<select class="api-toc__select" onchange="changeDocumentationVersion(value);">
|
||||||
${renderVersionSelector(wildcard, tags, tag)}
|
${asyncHtml(renderVersionSelector(wildcard, tags, tag))}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<div class="api-toc__search">
|
<div class="api-toc__search">
|
||||||
|
@ -61,7 +55,7 @@ export default async(state) => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="api-toc__commands" id="toc" role="navigation">
|
<ul class="api-toc__commands" id="toc" role="navigation">
|
||||||
${wildcard === "sdk" ? createSdkSidebar(apiResponse) : createApiSidebar(apiResponse)}
|
${asyncHtml(wildcard === "sdk" ? createSdkSidebar(apiResponse) : createApiSidebar(apiResponse))}
|
||||||
</ul>
|
</ul>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
|
@ -70,11 +64,11 @@ export default async(state) => {
|
||||||
<div></div>
|
<div></div>
|
||||||
|
|
||||||
<nav class="api-content__items">
|
<nav class="api-content__items">
|
||||||
${renderCodeLanguageToggles(wildcard)}
|
${asyncHtml(renderCodeLanguageToggles(wildcard))}
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
${createApiHeader(wildcard, currentTag)}
|
${asyncHtml(createApiHeader(wildcard, currentTag))}
|
||||||
${wildcard === "sdk" ? createSdkContent(apiResponse) : createApiContent(apiResponse)}
|
${asyncHtml(wildcard === "sdk" ? createSdkContent(apiResponse) : createApiContent(apiResponse))}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -297,12 +291,17 @@ async function parseApiFile({ repo, tag }) {
|
||||||
return Promise.reject(new Error("Failed to fetch API docs"));
|
return Promise.reject(new Error("Failed to fetch API docs"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// const response = await got(apiFileLink, { cache, json: true });
|
// if (cache.has(apiFileLink)) {
|
||||||
console.log(apiFileLink);
|
// console.log("Using cache for " + apiFileLink);
|
||||||
|
// return cache.get(apiFileLink);
|
||||||
|
// }
|
||||||
|
|
||||||
const response = await fetch(apiFileLink);
|
const response = await fetch(apiFileLink);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return response.json();
|
const json = response.json();
|
||||||
|
// cache.set(apiFileLink, json);
|
||||||
|
return json;
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
return "Issue loading API documentation";
|
return "Issue loading API documentation";
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import html from "choo/html";
|
||||||
|
|
||||||
// U T I L
|
// U T I L
|
||||||
|
|
||||||
import linkGrid from "~component/link-grid";
|
import linkGrid from "../components/link-grid";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import raw from "choo/html/raw";
|
||||||
|
|
||||||
// U T I L S
|
// U T I L S
|
||||||
|
|
||||||
import markdown from "~component/markdown";
|
import markdown from "../components/markdown";
|
||||||
import page404 from "./404";
|
import page404 from "./404";
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,10 +56,6 @@ export default (state, emit) => { // eslint-disable-line
|
||||||
let pageScript = "";
|
let pageScript = "";
|
||||||
|
|
||||||
switch(true) {
|
switch(true) {
|
||||||
case partialPath === "developer-program":
|
|
||||||
pageScript = renderClientScript("devprogram-scripts");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case partialPath === "glossary":
|
case partialPath === "glossary":
|
||||||
pageScript = renderClientScript("glossary-scripts");
|
pageScript = renderClientScript("glossary-scripts");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -9,7 +9,7 @@ module.exports = exports = {
|
||||||
github: {
|
github: {
|
||||||
branch: "master",
|
branch: "master",
|
||||||
linkText: "Edit this page on GitHub",
|
linkText: "Edit this page on GitHub",
|
||||||
repo: "lbryio/lbry.tech"
|
repo: "LBRYFoundation/tech.lbry.org"
|
||||||
},
|
},
|
||||||
meta: {
|
meta: {
|
||||||
color: "#222",
|
color: "#222",
|
||||||
|
|
9
docker-compose.yml
Normal file
9
docker-compose.yml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
services:
|
||||||
|
lbry-tech:
|
||||||
|
build:
|
||||||
|
context: ./
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
ports:
|
||||||
|
- ${PORT:-8080}:8080
|
||||||
|
environment:
|
||||||
|
- GITHUB_TOKEN=${GITHUB_TOKEN}
|
2
index.js
2
index.js
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// P A C K A G E S
|
// P A C K A G E S
|
||||||
|
|
||||||
require('module-alias/register')
|
// require('module-alias/register')
|
||||||
require("@babel/register");
|
require("@babel/register");
|
||||||
require("@babel/polyfill");
|
require("@babel/polyfill");
|
||||||
require("date-format-lite");
|
require("date-format-lite");
|
||||||
|
|
13074
package-lock.json
generated
13074
package-lock.json
generated
File diff suppressed because it is too large
Load diff
31
package.json
31
package.json
|
@ -1,18 +1,7 @@
|
||||||
{
|
{
|
||||||
"_moduleAliases": {
|
|
||||||
"~component": "app/components",
|
|
||||||
"~data": "app/data",
|
|
||||||
"~helper": "app/helpers",
|
|
||||||
"~module": "app/modules",
|
|
||||||
"~root": ".",
|
|
||||||
"~socket": "app/sockets.js",
|
|
||||||
"~view": "app/views"
|
|
||||||
},
|
|
||||||
"author": "LBRY Team",
|
"author": "LBRY Team",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/polyfill": "^7.4.4",
|
"@babel/polyfill": "^7.4.4",
|
||||||
"@octokit/rest": "^16.28.7",
|
|
||||||
"@slack/client": "^5.0.2",
|
|
||||||
"async": "^3.1.0",
|
"async": "^3.1.0",
|
||||||
"async-es": "^3.1.0",
|
"async-es": "^3.1.0",
|
||||||
"choo": "6.13.3",
|
"choo": "6.13.3",
|
||||||
|
@ -21,20 +10,16 @@
|
||||||
"choo-ssr": "^0.2.1",
|
"choo-ssr": "^0.2.1",
|
||||||
"choo-websocket": "^2.0.0",
|
"choo-websocket": "^2.0.0",
|
||||||
"colorette": "^1.1.0",
|
"colorette": "^1.1.0",
|
||||||
"cors": "^2.8.5",
|
|
||||||
"cron": "^1.7.1",
|
|
||||||
"date-format-lite": "^17.7.0",
|
"date-format-lite": "^17.7.0",
|
||||||
"decamelize": "^3.2.0",
|
"decamelize": "^3.2.0",
|
||||||
"dedent": "^0.7.0",
|
"dedent": "^0.7.0",
|
||||||
"dotenv": "^8.0.0",
|
"dotenv": "^8.0.0",
|
||||||
"fastify": "~2.7.1",
|
"fastify": "~2.7.1",
|
||||||
"fastify-compress": "^0.10.0",
|
"fastify-compress": "^0.10.0",
|
||||||
"fastify-helmet": "^3.0.1",
|
|
||||||
"fastify-static": "^2.5.0",
|
"fastify-static": "^2.5.0",
|
||||||
"fastify-ws": "^1.0.3",
|
"fastify-ws": "^1.0.3",
|
||||||
"front-matter": "^3.0.2",
|
"front-matter": "^3.0.2",
|
||||||
"fs-exists-sync": "^0.1.0",
|
"fs-exists-sync": "^0.1.0",
|
||||||
"got": "^9.6.0",
|
|
||||||
"graceful-fs": "^4.2.1",
|
"graceful-fs": "^4.2.1",
|
||||||
"link-module-alias": "^1.2.0",
|
"link-module-alias": "^1.2.0",
|
||||||
"make-promises-safe": "^5.0.0",
|
"make-promises-safe": "^5.0.0",
|
||||||
|
@ -44,7 +29,6 @@
|
||||||
"prismjs": "^1.17.1",
|
"prismjs": "^1.17.1",
|
||||||
"redis": "^2.8.0",
|
"redis": "^2.8.0",
|
||||||
"request": "latest",
|
"request": "latest",
|
||||||
"slack-node": "^0.1.8",
|
|
||||||
"socket.io": "^2.2.0",
|
"socket.io": "^2.2.0",
|
||||||
"stringify-object": "^3.3.0"
|
"stringify-object": "^3.3.0"
|
||||||
},
|
},
|
||||||
|
@ -64,24 +48,20 @@
|
||||||
"@babel/plugin-syntax-import-meta": "7.2.0",
|
"@babel/plugin-syntax-import-meta": "7.2.0",
|
||||||
"@babel/preset-env": "^7.5.5",
|
"@babel/preset-env": "^7.5.5",
|
||||||
"@babel/register": "^7.5.5",
|
"@babel/register": "^7.5.5",
|
||||||
"eslint-config": "^0.3.0",
|
|
||||||
"@springernature/sasslint-config": "^1.2.1",
|
|
||||||
"@lbry/color": "^1.1.1",
|
"@lbry/color": "^1.1.1",
|
||||||
"@lbry/components": "^2019.6.22",
|
"@lbry/components": "^2019.6.22",
|
||||||
|
"@springernature/sasslint-config": "^1.2.1",
|
||||||
"eslint": "^6.1.0",
|
"eslint": "^6.1.0",
|
||||||
|
"eslint-config": "^0.3.0",
|
||||||
"husky": "^3.0.2",
|
"husky": "^3.0.2",
|
||||||
"nodemon": "^1.19.1",
|
"nodemon": "^1.19.1",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"pino-pretty": "^3.2.0",
|
"pino-pretty": "^3.2.0",
|
||||||
"sass": "^1.22.9",
|
"sass": "^1.22.9",
|
||||||
"sass-lint": "^1.13.1",
|
"sass-lint": "^1.13.1",
|
||||||
"snazzy": "^8.0.0",
|
|
||||||
"standardx": "^4.0.0",
|
"standardx": "^4.0.0",
|
||||||
"updates": "^8.5.1"
|
"updates": "^8.5.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
|
||||||
"node": "10.2.x"
|
|
||||||
},
|
|
||||||
"husky": {
|
"husky": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
"pre-commit": "npm run format && npm run test:sass && git add -A :/"
|
"pre-commit": "npm run format && npm run test:sass && git add -A :/"
|
||||||
|
@ -89,15 +69,10 @@
|
||||||
},
|
},
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
"name": "lbry.tech",
|
"name": "lbry.tech",
|
||||||
"optionalDependencies": {
|
|
||||||
"win-node-env": "^0.4.0"
|
|
||||||
},
|
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"css": "sass --load-path=node_modules --update app/sass:app/dist --style compressed",
|
"css": "sass --load-path=node_modules --update app/sass:app/dist --style compressed",
|
||||||
"format": "eslint . --fix --ignore-pattern '/app/dist/'",
|
"format": "eslint . --fix --ignore-pattern '/app/dist/'",
|
||||||
"postinstall": "link-module-alias",
|
|
||||||
"preinstall": "command -v link-module-alias;link-module-alias clean || true",
|
|
||||||
"start": "npm i && npm run css && NODE_ENV=production node index.js",
|
"start": "npm i && npm run css && NODE_ENV=production node index.js",
|
||||||
"test": "run-s test:*",
|
"test": "run-s test:*",
|
||||||
"test:dependencies": "updates --update ./ --exclude prismjs",
|
"test:dependencies": "updates --update ./ --exclude prismjs",
|
||||||
|
@ -112,5 +87,5 @@
|
||||||
"app/dist"
|
"app/dist"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"version": "5.3.2"
|
"version": "6.0.0"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue