Merge pull request #665 from SkynetLabs/website

new siasky.net website
This commit is contained in:
Karol Wypchło 2021-04-19 17:18:31 +02:00 committed by GitHub
commit c8a7b1a2ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
299 changed files with 67655 additions and 1219 deletions

View File

@ -17,7 +17,7 @@ updates:
assignees:
- kwypchlo
- package-ecosystem: npm
directory: "/packages/webapp"
directory: "/packages/website"
schedule:
interval: weekly
time: "10:00"

View File

@ -1,31 +0,0 @@
name: Deploy webapp to Skynet
on:
pull_request:
paths:
- "packages/webapp/**"
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v1
with:
node-version: 14.x
- name: Install dependencies
run: yarn
- name: "Build webapp"
run: yarn workspace webapp build
env:
GATSBY_API_URL: "https://siasky.net"
- name: "Deploy to Skynet"
uses: kwypchlo/deploy-to-skynet-action@main
with:
upload-dir: packages/webapp/public
github-token: ${{ secrets.GITHUB_TOKEN }}

46
.github/workflows/deploy-website.yml vendored Normal file
View File

@ -0,0 +1,46 @@
name: Deploy website to Skynet
on:
pull_request:
paths:
- "packages/website/**"
defaults:
run:
working-directory: packages/website
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v2
with:
node-version: 15.x
- name: Install dependencies
run: npm i --force
- name: "Build website"
run: npm run build
- name: "Integration tests"
uses: cypress-io/github-action@v2
env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
working-directory: packages/website
install: false
record: true
start: npm run serve
wait-on: "http://127.0.0.1:9000"
- name: "Deploy to Skynet"
uses: kwypchlo/deploy-to-skynet-action@main
with:
upload-dir: packages/website/public
github-token: ${{ secrets.GITHUB_TOKEN }}
registry-seed: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && secrets.WEBSITE_REGISTRY_SEED || '' }}

3
.gitignore vendored
View File

@ -58,6 +58,9 @@ typings/
# Mac files
.DS_Store
# vscode
.vscode
# Yarn
yarn-error.log
.pnp/

View File

@ -32,11 +32,11 @@ Mongo needs a couple of extra steps in order to start a secure cluster.
- Open port 27017 on all nodes that will take part in the cluster. Ideally, you would only open the port for the other
nodes in the cluster.
- Manually run an initialisation `docker run` with extra environment variables that will initialise the admin user with
a password (example below).
- Manually add a `mgkey` file under `./docker/data/mongo` with the respective secret (
see [Mongo's keyfile access control](https://docs.mongodb.com/manual/tutorial/enforce-keyfile-access-control-in-existing-replica-set/)
for details).
- Manually run an initialisation `docker run` with extra environment variables that will initialise the admin user with
a password (example below).
- During the initialisation run mentioned above, we need to make two extra steps within the container:
- Change the ownership of `mgkey` to `mongodb:mongodb`
- Change its permissions to 400

View File

@ -7,11 +7,6 @@ x-logging: &default-logging
max-file: "3"
services:
webapp:
build:
args:
WITH_ACCOUNTS: 1 # enable accounts frontend
nginx:
environment:
- ACCOUNTS_ENABLED=1
@ -124,7 +119,7 @@ services:
- NEXT_PUBLIC_SKYNET_PORTAL_API=${SKYNET_PORTAL_API}
- NEXT_PUBLIC_SKYNET_DASHBOARD_URL=${SKYNET_DASHBOARD_URL}
- NEXT_PUBLIC_KRATOS_BROWSER_URL=${SKYNET_DASHBOARD_URL}/.ory/kratos/public
- NEXT_PUBLIC_KRATOS_PUBLIC_URL=${SKYNET_DASHBOARD_URL}/.ory/kratos/public
- NEXT_PUBLIC_KRATOS_PUBLIC_URL=http://oathkeeper:4455/.ory/kratos/public
- NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=${STRIPE_PUBLISHABLE_KEY}
volumes:
- ./docker/data/dashboard/.next:/usr/app/.next
@ -133,6 +128,8 @@ services:
ipv4_address: 10.10.10.85
expose:
- 3000
depends_on:
- oathkeeper
oathkeeper:
image: oryd/oathkeeper:v0.38

View File

@ -82,16 +82,17 @@ services:
- sia
- health-check
- handshake-api
- website
webapp:
website:
build:
context: ./packages/webapp
context: ./packages/website
dockerfile: Dockerfile
container_name: webapp
container_name: website
restart: unless-stopped
logging: *default-logging
volumes:
- ./docker/data/webapp/.cache:/usr/app/.cache
env_file:
- .env
networks:
shared:
ipv4_address: 10.10.10.35

View File

@ -1,4 +1,4 @@
FROM node:15.12.0-alpine
FROM node:15.14.0-alpine
WORKDIR /opt/hsd

View File

@ -1,5 +1,11 @@
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=skynet:10m max_size=10g inactive=24h use_temp_path=off;
# this runs before forking out nginx worker processes
init_by_lua_block {
require "cjson"
require "socket.http"
}
# ratelimit specified IPs
geo $limit {
default 0;
@ -78,11 +84,11 @@ server {
include /etc/nginx/conf.d/include/cors;
proxy_pass http://webapp:9000;
proxy_pass http://website:9000;
}
location /docs {
proxy_pass https://skynethq.github.io/skynet-docs;
proxy_pass https://skynetlabs.github.io/skynet-docs;
}
location /skynet/blocklist {
@ -296,12 +302,11 @@ server {
if ngx.status == ngx.HTTP_OK or ngx.status == ngx.HTTP_NOT_FOUND then
local http = require("socket.http")
local headers = { Cookie = ngx.req.get_headers()["Cookie"] }
local method = ngx.req.get_method() == ngx.HTTP_GET and "read" or "write"
local ok, statusCode, headers, statusText = http.request {
url = "http://accounts:3000/track/registry/" .. method,
method = "POST",
headers = headers
headers = ngx.req.get_headers()
}
if statusCode ~= ngx.HTTP_NO_CONTENT and statusCode ~= ngx.HTTP_UNAUTHORIZED then
ngx.log(ngx.ERR, "accounts endpoint /track/registry/" .. method .. " failed with error " .. statusCode)
@ -362,8 +367,11 @@ server {
local skylink = ngx.header["Skynet-Skylink"]
if skylink and ngx.status >= ngx.HTTP_OK and ngx.status < ngx.HTTP_SPECIAL_RESPONSE then
local http = require("socket.http")
local headers = { Cookie = ngx.req.get_headers()["Cookie"] }
local ok, statusCode, headers, statusText = http.request { url = "http://accounts:3000/track/upload/" .. skylink, method = "POST", headers = headers }
local ok, statusCode, headers, statusText = http.request {
url = "http://accounts:3000/track/upload/" .. skylink,
method = "POST",
headers = ngx.req.get_headers()
}
if statusCode ~= ngx.HTTP_NO_CONTENT and statusCode ~= ngx.HTTP_UNAUTHORIZED then
ngx.log(ngx.ERR, "accounts endpoint /track/upload/" .. skylink .. " failed with error " .. statusCode)
end
@ -408,12 +416,11 @@ server {
local skylink = ngx.header["Skynet-Skylink"]
if skylink and ngx.status >= ngx.HTTP_OK and ngx.status < ngx.HTTP_SPECIAL_RESPONSE then
local http = require("socket.http")
local headers = { Cookie = ngx.req.get_headers()["Cookie"] }
local query = table.concat({ "status=" .. ngx.status, "bytes=" .. ngx.var.body_bytes_sent }, "&")
local ok, statusCode, headers, statusText = http.request {
url = "http://accounts:3000/track/download/" .. skylink .. "?" .. query,
method = "POST",
headers = headers
headers = ngx.req.get_headers()
}
if statusCode ~= ngx.HTTP_NO_CONTENT and statusCode ~= ngx.HTTP_UNAUTHORIZED then
ngx.log(ngx.ERR, "accounts endpoint /track/download/" .. skylink .. " failed with error " .. statusCode)
@ -458,6 +465,33 @@ server {
proxy_pass http://127.0.0.1/$uri?attachment=true&$args;
}
location /__internal/do/not/use/authenticated {
include /etc/nginx/conf.d/include/cors;
charset utf-8;
charset_types application/json;
default_type application/json;
content_by_lua_block {
local json = require('cjson')
-- this block runs only when accounts are enabled
if os.getenv("ACCOUNTS_ENABLED", "0") == "0" then
ngx.say(json.encode{authenticated = false})
return ngx.exit(ngx.HTTP_OK)
end
local res = ngx.location.capture("/accounts/user", { copy_all_vars = true })
if res.status == ngx.HTTP_OK then
local limits = json.decode(res.body)
ngx.say(json.encode{authenticated = limits.tier > 0})
return ngx.exit(ngx.HTTP_OK)
end
ngx.say(json.encode{authenticated = false})
return ngx.exit(ngx.HTTP_OK)
}
}
location /accounts {
internal; # internal endpoint only
access_log off; # do not log traffic

View File

@ -3,12 +3,12 @@ FROM golang AS sia-builder
ENV GOOS linux
ENV GOARCH amd64
ARG branch=master
ARG branch=portal-latest
RUN git clone https://gitlab.com/SkynetLabs/skyd.git Sia --single-branch --branch ${branch}
RUN make release --directory Sia
FROM nebulouslabs/sia:1.5.5
FROM nebulouslabs/sia:latest
COPY --from=sia-builder /go/bin/skyd /usr/bin/siad
COPY --from=sia-builder /go/bin/skyc /usr/bin/siac

View File

@ -1,4 +1,4 @@
FROM node:15.12.0-alpine
FROM node:15.14.0-alpine
WORKDIR /usr/app
@ -10,6 +10,7 @@ RUN yarn --no-lockfile
COPY public ./public
COPY src ./src
COPY styles ./styles
COPY next.config.js .
COPY postcss.config.js .
COPY tailwind.config.js .

View File

@ -0,0 +1,5 @@
module.exports = {
future: {
webpack5: true,
},
};

View File

@ -4,6 +4,7 @@ import SelfServiceMessages from "./SelfServiceMessages";
export default function SelfServiceForm({ flow, config, fieldsConfig, title, button = "Submit" }) {
const fields = config.fields
.filter((field) => !field.name.startsWith("traits.name")) // drop name fields
.map((field) => ({ ...field, ...fieldsConfig[field.name] }))
.sort((a, b) => (a.position < b.position ? -1 : 1));
const formik = useFormik({

View File

@ -1,58 +0,0 @@
import { Client, Environment } from "square";
import { StatusCodes } from "http-status-codes";
const client = new Client({
environment: Environment.Sandbox,
accessToken: process.env.SQUARE_ACCESS_TOKEN,
});
const api = {
GET: async (req, res) => {
const user = "R7R0NY1Z8WT11D43564EEFKTYR"; // req.headers["x-user"];
try {
const { result: customerResult } = await client.customersApi.retrieveCustomer(user);
const { customer } = customerResult;
res.json(customer.cards);
} catch (error) {
res.json([]);
}
},
// POST: async (req, res) => {
// const user = req.headers["x-user"];
// const card = {
// cardNonce: "YOUR_CARD_NONCE",
// cardholderName: "Amelia Earhart",
// billingAddress: {},
// verificationToken: "verification_token0",
// };
// card.bodyBillingAddress.addressLine1 = "500 Electric Ave";
// card.bodyBillingAddress.addressLine2 = "Suite 600";
// card.bodyBillingAddress.addressLine3 = "address_line_38";
// card.bodyBillingAddress.locality = "New York";
// card.bodyBillingAddress.sublocality = "sublocality2";
// card.bodyBillingAddress.administrativeDistrictLevel1 = "NY";
// card.bodyBillingAddress.postalCode = "10003";
// card.bodyBillingAddress.country = "US";
// try {
// const { result } = await client.customersApi.createCustomerCard(user, card);
// res.status(StatusCodes.NO_CONTENT);
// } catch (error) {
// console.log(Object.keys(error));
// res.status(StatusCodes.BAD_REQUEST);
// }
// },
};
export default (req, res) => {
if (req.method in api) {
api[req.method](req, res);
} else {
res.status(StatusCodes.NOT_FOUND);
}
};

View File

@ -1,45 +0,0 @@
import { Client, Environment } from "square";
import { StatusCodes } from "http-status-codes";
const client = new Client({
environment: Environment.Sandbox,
accessToken: process.env.SQUARE_ACCESS_TOKEN,
});
const api = {
GET: async (req, res) => {
const user = "NBE7TRXZPGZXNBD64JB6DR5AGR"; // req.headers["x-user"];
try {
// get locations for invoices search query
const { result: locationsResponse } = await client.locationsApi.listLocations();
const { locations } = locationsResponse;
// create invoices serach query
const locationIds = locations.map(({ id }) => id);
const customerIds = [user];
const filter = { locationIds, customerIds };
const sort = { field: "INVOICE_SORT_DATE", order: "DESC" };
const query = { filter, sort };
// query invoices with given search criteria
const { result: invoicesResponse } = await client.invoicesApi.searchInvoices({ query, limit: 10 });
const { invoices } = invoicesResponse;
res.json(invoices);
} catch (error) {
console.log(error);
console.log(error?.errors);
res.json([]); // todo: error handling
}
},
};
export default (req, res) => {
if (req.method in api) {
return api[req.method](req, res);
}
return res.status(StatusCodes.NOT_FOUND);
};

View File

@ -1,46 +0,0 @@
import { Client, Environment } from "square";
import { StatusCodes } from "http-status-codes";
const client = new Client({
environment: Environment.Sandbox,
accessToken: process.env.SQUARE_ACCESS_TOKEN,
});
const api = {
GET: async (req, res) => {
try {
const user = "NBE7TRXZPGZXNBD64JB6DR5AGR"; // req.headers["x-user"];
// create subscriptions search query
const query = { filter: { customerIds: [user] } };
// query subscriptions with given search criteria
const { result: subscriptionsResponse } = await client.subscriptionsApi.searchSubscriptions({ query });
const { subscriptions } = subscriptionsResponse;
// get active subscription
const subscription = subscriptions.find(({ status }) => status === "ACTIVE");
if (!subscription) {
return res.status(StatusCodes.NO_CONTENT).end(); // no active subscription found
}
console.log("....", subscription);
return res.json(subscription);
} catch (error) {
console.log(error);
console.log(error?.errors);
return res.status(StatusCodes.BAD_REQUEST).end(); // todo: error handling
}
},
};
export default (req, res) => {
if (req.method in api) {
return api[req.method](req, res);
}
return res.status(StatusCodes.NOT_FOUND).end();
};

View File

@ -1,55 +0,0 @@
import { Client, Environment } from "square";
import { StatusCodes } from "http-status-codes";
const client = new Client({
environment: Environment.Sandbox,
accessToken: process.env.SQUARE_ACCESS_TOKEN,
});
const cancelSubscription = async (id) => {
const { result: subscriptionsResponse } = await client.subscriptionsApi.cancelSubscription(id);
const { subscription } = subscriptionsResponse;
return subscription;
};
const getActiveSubscription = async (customerId) => {
// create subscriptions search query
const query = { filter: { customerIds: [customerId] } };
// query subscriptions with given search criteria
const { result: subscriptionsResponse } = await client.subscriptionsApi.searchSubscriptions({ query });
const { subscriptions } = subscriptionsResponse;
// get active subscription with a set cancellation date
return subscriptions.find(({ status, canceledDate }) => status === "ACTIVE" && !canceledDate);
};
const api = {
POST: async (req, res) => {
try {
const user = "NBE7TRXZPGZXNBD64JB6DR5AGR"; // req.headers["x-user"];
const subscription = await getActiveSubscription(user);
if (!subscription) {
return res.status(StatusCodes.BAD_REQUEST).end(); // no active subscription found
}
const canceledSubscription = await cancelSubscription(subscription.id);
return res.json(canceledSubscription);
} catch (error) {
console.log(error.errors);
return res.status(StatusCodes.BAD_REQUEST).end(); // todo: error handling
}
},
};
export default (req, res) => {
if (req.method in api) {
return api[req.method](req, res);
}
return res.status(StatusCodes.NOT_FOUND).end();
};

View File

@ -1,58 +0,0 @@
import { Client, Environment } from "square";
import { StatusCodes } from "http-status-codes";
const client = new Client({
environment: Environment.Sandbox,
accessToken: process.env.SQUARE_ACCESS_TOKEN,
});
const updateSubscription = async (id, body) => {
const { result: subscriptionsResponse } = await client.subscriptionsApi.updateSubscription(id, body);
const { subscription } = subscriptionsResponse;
return subscription;
};
const getActiveCanceledSubscription = async (customerId) => {
// create subscriptions search query
const query = { filter: { customerIds: [customerId] } };
// query subscriptions with given search criteria
const { result: subscriptionsResponse } = await client.subscriptionsApi.searchSubscriptions({ query });
const { subscriptions } = subscriptionsResponse;
// get active subscription with a set cancellation date
return subscriptions.find(({ status, canceledDate }) => status === "ACTIVE" && canceledDate);
};
const api = {
POST: async (req, res) => {
try {
const user = "NBE7TRXZPGZXNBD64JB6DR5AGR"; // req.headers["x-user"];
const subscription = await getActiveCanceledSubscription(user);
if (!subscription) {
return res.status(StatusCodes.BAD_REQUEST).end(); // no active subscription with cancel date found
}
// update the subscription setting empty canceledDate
const updatedSubscription = await updateSubscription(subscription.id, {
subscription: { ...subscription, canceledDate: "" },
});
return res.json(updatedSubscription);
} catch (error) {
console.log(error.errors);
return res.status(StatusCodes.BAD_REQUEST).end(); // todo: error handling
}
},
};
export default (req, res) => {
if (req.method in api) {
return api[req.method](req, res);
}
return res.status(StatusCodes.NOT_FOUND).end();
};

View File

@ -53,7 +53,6 @@ export default async (req, res) => {
res.json({ sessionId: session.id });
} catch (error) {
console.log(error);
res.status(StatusCodes.BAD_REQUEST).json({ error: { message: error.message } });
}
};

View File

@ -200,7 +200,7 @@ export default function Home({ plans }) {
<div className="ml-5 w-0 flex-1">
<dt className="text-sm font-medium text-gray-500 truncate">Storage used</dt>
<dd className="flex items-baseline">
<div className="text-2xl font-semibold text-grey-900">{prettyBytes(stats?.storageUsed ?? 0)}</div>
<div className="text-2xl font-semibold text-grey-900">{prettyBytes(stats?.totalUploadsSize ?? 0)}</div>
</dd>
</div>
</div>

View File

@ -83,7 +83,9 @@ export default function Payments({ plans, user: initialUserData, stats: initialS
<div className="bg-white overflow-hidden shadow rounded-lg">
<div className="px-4 py-5 sm:p-6">
<dt className="text-sm font-medium text-gray-500 truncate">Storage used</dt>
<dd className="mt-1 text-3xl font-semibold text-gray-900">{prettyBytes(stats.storageUsed)}</dd>
<dd className="mt-1 text-3xl font-semibold text-gray-900">
{prettyBytes(stats?.totalUploadsSize ?? 0)}
</dd>
</div>
</div>
</dl>

View File

@ -30,14 +30,10 @@ export const getServerSideProps = authServerSideProps(async (context) => {
headers: { cookie: context.req.headers.cookie },
});
console.log(flow, status, data);
if (status === 200) return { props: { flow: data } };
throw new Error(`Failed to retrieve flow ${flow} with code ${status}`);
} catch (error) {
console.log(error);
return {
redirect: {
permanent: false,

View File

@ -1,4 +1,4 @@
FROM node:15.12.0-alpine
FROM node:15.14.0-alpine
WORKDIR /usr/app

View File

@ -1,4 +1,4 @@
FROM node:15.12.0-alpine
FROM node:15.14.0-alpine
WORKDIR /usr/app

View File

@ -4,7 +4,6 @@
"main": "index.js",
"license": "MIT",
"dependencies": {
"body-parser": "^1.19.0",
"deep-object-diff": "^1.1.0",
"express": "^4.17.1",
"http-status-codes": "^2.1.2",

View File

@ -5,7 +5,6 @@ if (!process.env.PORTAL_URL) {
}
const express = require("express");
const bodyparser = require("body-parser");
const db = require("./db");
const host = process.env.HOSTNAME || "0.0.0.0";
@ -13,8 +12,8 @@ const port = Number(process.env.PORT) || 3100;
const server = express();
server.use(bodyparser.urlencoded({ extended: false }));
server.use(bodyparser.json());
server.use(express.urlencoded({ extended: false }));
server.use(express.json());
server.use((req, res, next) => {
db.read();
next();

View File

@ -1,3 +1,4 @@
# gatsby files
.cache/
public
public
package-lock.json

View File

@ -1,4 +1,4 @@
FROM node:15.12.0-alpine
FROM node:15.14.0-alpine
RUN apk update && apk add autoconf automake libtool gcc make g++ zlib-dev file nasm util-linux

77
packages/website/.gitignore vendored Normal file
View File

@ -0,0 +1,77 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# dotenv environment variable files
.env*
# gatsby files
.cache/
public
# Mac files
.DS_Store
# Yarn
yarn-error.log
.pnp/
.pnp.js
# Yarn Integrity file
.yarn-integrity
# Npm
# package-lock.json
# Cypress
cypress/screenshots
cypress/videos

View File

@ -0,0 +1,4 @@
.cache
package.json
package-lock.json
public

View File

@ -0,0 +1,3 @@
{
"printWidth": 120
}

View File

@ -0,0 +1,49 @@
module.exports = {
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
{
name: "@storybook/addon-postcss",
options: {
postcssLoaderOptions: {
implementation: require("postcss"),
},
},
},
],
webpackFinal: async (config) => {
// Transpile Gatsby module because Gatsby includes un-transpiled ES6 code.
config.module.rules[0].exclude = [/node_modules\/(?!(gatsby)\/)/];
// use installed babel-loader which is v8.0-beta (which is meant to work with @babel/core@7)
config.module.rules[0].use[0].loader = require.resolve("babel-loader");
// use @babel/preset-react for JSX and env (instead of staged presets)
config.module.rules[0].use[0].options.presets = [
require.resolve("@babel/preset-react"),
require.resolve("@babel/preset-env"),
];
config.module.rules[0].use[0].options.plugins = [
// use @babel/plugin-proposal-class-properties for class arrow functions
require.resolve("@babel/plugin-proposal-class-properties"),
// use babel-plugin-remove-graphql-queries to remove static queries from components when rendering in storybook
require.resolve("babel-plugin-remove-graphql-queries"),
];
// implement svg import support
config.module.rules.find((rule) => rule.test && rule.test.test(".svg")).exclude = /\.svg$/;
config.module.rules.push({
test: /\.svg$/,
enforce: "pre",
use: [
{
loader: require.resolve("react-svg-loader"),
options: { svgo: { plugins: [{ removeViewBox: false }] } },
},
],
});
// Prefer Gatsby ES6 entrypoint (module) over commonjs (main) entrypoint
config.resolve.mainFields = ["browser", "module", "main"];
return config;
},
};

View File

@ -0,0 +1,55 @@
import { action } from "@storybook/addon-actions";
import "normalize.css";
import "@fontsource/sora";
import "@fontsource/source-sans-pro";
import "./tailwind.css";
// Gatsby's Link overrides:
// Gatsby Link calls the `enqueue` & `hovering` methods on the global variable ___loader.
// This global object isn't set in storybook context, requiring you to override it to empty functions (no-op),
// so Gatsby Link doesn't throw any errors.
global.___loader = {
enqueue: () => {},
hovering: () => {},
};
// This global variable is prevents the "__BASE_PATH__ is not defined" error inside Storybook.
global.__BASE_PATH__ = "/";
// Navigating through a gatsby app using gatsby-link or any other gatsby component will use the `___navigate` method.
// In Storybook it makes more sense to log an action than doing an actual navigate. Checkout the actions addon docs for more info: https://github.com/storybookjs/storybook/tree/master/addons/actions.
window.___navigate = (pathname) => {
action("NavigateTo:")(pathname);
};
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
layout: "fullscreen",
viewport: {
viewports: {
mobile: {
name: "Mobile",
styles: {
height: "667px",
width: "375px",
},
type: "mobile",
},
tablet: {
name: "Tablet",
styles: {
height: "1366px",
width: "1024px",
},
type: "tablet",
},
},
},
backgrounds: {
default: "light",
values: [
{ name: "dark", value: "#0d0d0d" },
{ name: "light", value: "#ffffff" },
],
},
};

View File

@ -0,0 +1,3 @@
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";

View File

@ -0,0 +1,27 @@
FROM node:15.14.0-alpine
RUN apk update && apk add autoconf automake build-base libtool nasm pkgconfig
WORKDIR /usr/app
COPY package.json .
COPY package-lock.json .
ENV GATSBY_TELEMETRY_DISABLED 1
RUN npm i
COPY data ./data
COPY src ./src
COPY static ./static
COPY gatsby-browser.js .
COPY gatsby-config.js .
COPY gatsby-node.js .
COPY gatsby-ssr.js .
COPY postcss.config.js .
COPY tailwind.config.js .
RUN npm run build
EXPOSE 9000
CMD ["sh", "-c", "npm run serve -- --host 0.0.0.0"]

View File

@ -0,0 +1,5 @@
{
"baseUrl": "http://127.0.0.1:9000",
"projectId": "gey76p",
"videoUploadOnPasses": false
}

View File

@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}

View File

@ -0,0 +1,35 @@
/// <reference types="cypress" />
context("Skynet website", () => {
beforeEach(() => {
cy.visit("");
});
it("should render page title", () => {
cy.contains("Decentralized Internet");
});
// it("should be able to upload a file", () => {
// cy.intercept("POST", "/skynet/skyfile").as("upload");
// const fileName = "check.json";
// cy.wait(1000); // delay for drag-and-drop to work properly every time
// cy.get('.home-upload input[type="file"]').attachFile(fileName, { subjectType: "drag-n-drop" });
// cy.get(".home-upload").scrollIntoView();
// cy.get(".home-uploaded-files").children().should("have.length", 1);
// // wait max 2 minutes, the portal might be slow at times
// cy.wait("@upload", { responseTimeout: 2 * 60 * 1000 });
// cy.contains(".upload-file", fileName).within(() => {
// cy.get(".url")
// .invoke("text")
// .should("match", /\/[a-zA-Z0-9-_]{46}/);
// cy.contains("Copy Link").click();
// cy.contains("Copied!").should("be.visible");
// });
// });
});

View File

@ -0,0 +1,22 @@
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
/**
* @type {Cypress.PluginConfig}
*/
// eslint-disable-next-line no-unused-vars
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}

View File

@ -0,0 +1,27 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
import "cypress-file-upload";

View File

@ -0,0 +1,20 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')

View File

@ -0,0 +1,52 @@
- header: Skynet Labs
links:
- title: About us
to: /about
- title: Brand Guidelines
href: https://support.siasky.net/key-concepts/skynet-brand-guidelines
- title: Careers
href: https://jobs.lever.co/nebulous
- title: Terms of Use
href: /terms.pdf
- title: Privacy Policy
href: /privacy.pdf
- header: Developers
links:
- title: Developer Guide
href: https://support.siasky.net/the-technology/developing-on-skynet
- title: API & SDK Documentation
href: https://siasky.net/docs/
- title: Portal Setup
href: https://support.siasky.net/the-technology/running-a-web-portal
- title: Github
href: https://github.com/SkynetLabs
- title: Gitlab
href: https://gitlab.com/SkynetLabs
- header: Technology
links:
- title: What is Skynet?
href: https://support.siasky.net
- title: Frequent Questions
href: https://support.siasky.net/key-concepts/faqs
- title: Skynet Wiki
href: https://skynetwiki.tech
- title: Support
href: https://support.siasky.net
- header: Ecosystem
links:
- title: Sia Foundation
href: https://sia.tech
- title: Sia Foundation Forum
href: https://forum.sia.tech
- title: SiaStats
href: https://siastats.info
- title: Skynet AppStore
href: https://skapp.hns.siasky.net/
- header: Skynet Webportals
links:
- title: Siasky.net
href: https://siasky.net
- title: SkyPortal.xyz
href: https://skyportal.xyz
- title: Skydrain.net
href: https://skydrain.net

View File

@ -0,0 +1,22 @@
- name: A.Capital Ventures
image: ./investors/investors-logo-1.png
- name: Bain Capital
image: ./investors/investors-logo-2.png
- name: Bessemer Venture Partners
image: ./investors/investors-logo-3.png
- name: Collab
image: ./investors/investors-logo-4.png
- name: Dragonfly Capital
image: ./investors/investors-logo-5.png
- name: Fenbushi Capital
image: ./investors/investors-logo-6.png
- name: First Star Ventures
image: ./investors/investors-logo-7.png
- name: Hack VC
image: ./investors/investors-logo-8.png
- name: INBlockchain
image: ./investors/investors-logo-9.png
- name: Paradigm
image: ./investors/investors-logo-10.png
- name: SV Angel
image: ./investors/investors-logo-11.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1,22 @@
navigation:
- title: Home
to: /
- title: About
to: /about
- title: Developers
to: /developers
- title: News
to: /news
team:
- name: "Chris Schinnerl"
position: "VP of Technology"
image: images/team/chris-schinnerl.png
social:
- github: https://github.com/ChrisSchinnerl
- gitlab: https://gitlab.com/ChrisSchinnerl
- twitter: https://twitter.com/ChrisSchinnerl
- name: Steve Funk
position: Head of Support
image: images/team/steve-funk.png
social:
- linkedin: https://www.linkedin.com/in/stevengfunk

View File

@ -0,0 +1,10 @@
---
title: "A Deep Dive into Skynet"
date: "2021-02-09"
description: An introduction and a point of reference on all things Skynet. Intended for all audiences & each section has been written to be…
thumbnail: ./thumbnail.png
categories: ["blog"]
author: David Vorick
avatar: ../../team/david-vorick.png
external: https://blog.sia.tech/a-deep-dive-into-skynet-a0fa037feea
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 KiB

View File

@ -0,0 +1,10 @@
---
title: "Announcing Skynet Premium Plans: Faster Speeds and Longer Pinning"
date: "2021-03-24"
description: Skynet Labs announces accounts with faster speeds and greater amounts of stored data, laying the foundation for future content…
thumbnail: ./thumbnail.png
categories: ["blog"]
author: David Vorick
avatar: ../../team/david-vorick.png
external: https://blog.sia.tech/announcing-skynet-premium-plans-faster-speeds-and-longer-pinning-b5469814d2c3
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 KiB

View File

@ -0,0 +1,10 @@
---
title: "Built to Explore: The Skynet Spring 2021 Hackathon!"
date: "2021-04-01"
description: Put your DApp to the test with real end-users in this exciting 3 phase hackathon. $25,000+ in prizes and open to devs and nondevs alike!
thumbnail: ./thumbnail.png
categories: ["blog"]
author: David Vorick
avatar: ../../team/david-vorick.png
external: https://blog.sia.tech/built-to-explore-the-skynet-spring-2021-hackathon-a0cff382bb0c
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

View File

@ -0,0 +1,41 @@
---
title: "Sia Announces $3M Seed Round to Accelerate Development and Adoption of the Web3 platform Skynet"
date: "2020-09-22"
description: "Paradigm leads the round of financing; Nebulous to solely focus on Skynet"
author: "Skynet Labs"
categories: ["press release"]
avatar: "../images/skynet-avatar.png"
thumbnail: "../images/press-release.png"
---
**Boston, MA September 22nd, 2020** — Nebulous, the company building the Sia decentralized cloud storage platform and the Skynet application hosting platform, today announced it has closed a \$3M funding round led by Paradigm with participation from Bain Capital Ventures, Bessemer Venture Partners, A.Capital, Collaborative Fund, Dragonfly Capital Partners, Hack VC, INBlockchain, First Star Ventures, and other notable investors. The round will help the company scale and accelerate the development and adoption of Skynet.
Todays internet monopolized by tech giants struggles with fundamental challenges in privacy, reliability, and has excessive control over our data and the way we interact with the world. Skynet enables high speed, low cost, and superior infrastructure to serve as the storage foundation for a free Internet. Where data is globally accessible, user-controlled, censorship-resistant, and not fragmented in walled gardens.
Skynet empowers developers to deploy applications to a decentralized network in just minutes and be immediately available to everyone across the world. Importantly, end-users can directly access content on Skynet without needing to run full nodes or deal with cryptocurrencies. It paves the path for more powerful applications, more dynamic user experiences, and disintermediates the web to ensure that publishers and creators are paid the full amount that they deserve. Skynet enables the decentralized web ecosystem to realize the full potential of a free internet.
“The possibilities created by Skynet blow our minds. The project has enabled a growing ecosystem of builders to quickly prototype censorship-resistant applications and interactive websites including interfaces to Ethereum smart contracts like Uniswap,” said Dan Robinson, Research Partner at Paradigm. “Were investing in the Skynet team because we believe they have the right combination of talent, experience, and community to shepherd us into the era of the Decentralized Web.”
Nebulous launched the Skynet platform back in February 2020 and since then has seen accelerated growth in developer interest and usage. More than 1.6 million files have been uploaded and shared amounting to 10+ TB of data using Skynet. A thriving community of developers has built over 100 applications in the span of a few months including a Video Streaming app SkyLive, Blogging apps like Wakio and Skyblog Builder, Video & Image gallery app SkyGallery, and a Decentralized AppStore Skydroid. The full list of Skynet Apps can be explored at the Skynet AppStore. We believe the next generation of Twitter, Medium, TikTok will be built on Skynet.
By building on the Sia network, Skynet delivers a 10x reduction in storage costs and a 100x reduction in bandwidth costs when compared to centralized providers, without sacrificing performance or reliability. Skynet achieves 1 gigabit per second in download and uploads speeds, with more improvements coming in future releases.
“For the first time, the decentralized web feels within reach. Were not talking about a web that is technically feasible yet crippled compared to the centralized alternatives, we are talking about a decentralized web that will become an unstoppable force” said David Vorick, Nebulous CEO and Skynet Lead Developer. “Ten years from now, using centralized applications instead of decentralized applications will feel like using a fax machine instead of email.”
In addition to the funding news, Nebulous is announcing its rebranding to Skynet to solely focused on developing and growing the Skynet ecosystem. Next-generation applications are already being built on Skynet with more developers joining the community every day. Skynet is different from any platform or technology than has ever been built before. Because of that, we are thrilled to be doubling down on what we know will become the future of the Internet.
Interested in Skynet? Learn more at siasky.net, join us on Discord, or email us at hello@sia.tech.
Want to help us re-decentralize the Internet? Nebulous is hiring for positions in marketing and developer evangelism. Learn more about our projects and apply today!
## About Nebulous
Nebulous builds uncompromising software infrastructure for the decentralized internet. This includes Sia, the leading decentralized cloud storage platform, and Skynet, a content and application hosting platform.
Nebulous defines uncompromising infrastructure as scalable, trustless, secure, and most important fully decentralized. In a blockchain industry filled with hype but lacking substance, Nebulous stands out as one of the few deeply technical teams that consistently deliver real products with significant potential.
Nebulous, Inc. was founded in 2014 and is headquartered in Boston. Before the round led by Paradigm, Nebulous was funded by Bain Capital Ventures, A.Capital, Bessemer Venture Partners, Dragonfly Capital Partners, First Star Ventures, and other notable investors.
## About Paradigm
Paradigm is a crypto-focused investment firm based in San Francisco founded by Fred Ehrsam and Matt Huang. The firm makes investments focusing on crypto and blockchain technologies from the earliest stages of ideation through maturity. Prior to founding Paradigm, Fred co-founded Coinbase, the largest cryptocurrency company in the US, and Matt was a partner at Sequoia Capital focusing on early-stage venture investments including leading the firms cryptocurrency efforts.

View File

@ -0,0 +1,234 @@
---
title: Hello World
date: "2015-05-01T22:12:03.284Z"
description: "Hello World"
author: Nicole Tay
avatar: ../../team/nicole-tay.png
hidden: true
---
This is my first post on my new fake blog! How exciting!
I'm sure I'll write a lot more interesting things in the future.
Oh, and here's a great quote from this Wikipedia on
[salted duck eggs](https://en.wikipedia.org/wiki/Salted_duck_egg).
> A salted duck egg is a Chinese preserved food product made by soaking duck
> eggs in brine, or packing each egg in damp, salted charcoal. In Asian
> supermarkets, these eggs are sometimes sold covered in a thick layer of salted
> charcoal paste. The eggs may also be sold with the salted paste removed,
> wrapped in plastic, and vacuum packed. From the salt curing process, the
> salted duck eggs have a briny aroma, a gelatin-like egg white and a
> firm-textured, round yolk that is bright orange-red in color.
![Chinese Salty Egg](./salty_egg.jpg)
You can also write code blocks here!
```js
const saltyDuckEgg = "chinese preserved food product";
```
| Number | Title | Year |
| :----- | :--------------------------------------- | ---: |
| 1 | Harry Potter and the Philosophers Stone | 2001 |
| 2 | Harry Potter and the Chamber of Secrets | 2002 |
| 3 | Harry Potter and the Prisoner of Azkaban | 2004 |
[View raw (TEST.md)](https://raw.github.com/adamschwartz/github-markdown-kitchen-sink/master/README.md)
This is a paragraph.
This is a paragraph.
# Header 1
## Header 2
Header 1
========
Header 2
--------
# Header 1
## Header 2
### Header 3
#### Header 4
##### Header 5
###### Header 6
# Header 1
## Header 2
### Header 3
#### Header 4
##### Header 5
###### Header 6
# Header 1
## Header 2
### Header 3
#### Header 4
##### Header 5
###### Header 6
# Header 1 #
## Header 2 ##
### Header 3 ###
#### Header 4 ####
##### Header 5 #####
###### Header 6 ######
> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
> ## This is a header.
>
> 1. This is the first list item.
> 2. This is the second list item.
>
> Here's some example code:
>
> Markdown.generate();
> ## This is a header.
> 1. This is the first list item.
> 2. This is the second list item.
>
> Here's some example code:
>
> Markdown.generate();
- Red
- Green
- Blue
* Red
* Green
* Blue
- Red
- Green
- Blue
```markdown
- Red
- Green
- Blue
* Red
* Green
* Blue
- Red
- Green
- Blue
```
- `code goes` here in this line
- **bold** goes here
```markdown
- `code goes` here in this line
- **bold** goes here
```
1. Buy flour and salt
1. Mix together with water
1. Bake
```markdown
1. Buy flour and salt
1. Mix together with water
1. Bake
```
1. `code goes` here in this line
1. **bold** goes here
```markdown
1. `code goes` here in this line
1. **bold** goes here
```
Paragraph:
Code
<!-- -->
Paragraph:
Code
---
---
---
---
---
* * *
***
*****
- - -
---------------------------------------
This is [an example](http://example.com "Example") link.
[This link](http://example.com) has no title attr.
This is [an example][id] reference-style link.
[id]: http://example.com "Optional Title"
This is [an example](http://example.com "Example") link.
[This link](http://example.com) has no title attr.
This is [an example] [id] reference-style link.
[id]: http://example.com "Optional Title"
_single asterisks_
_single underscores_
**double asterisks**
**double underscores**
*single asterisks*
_single underscores_
**double asterisks**
__double underscores__
This paragraph has some `code` in it.
This paragraph has some `code` in it.
![Alt Text](https://placehold.it/200x50 "Image Title")
![Alt Text](https://placehold.it/200x50 "Image Title")

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -0,0 +1,10 @@
---
title: Introducing Skynet Labs
date: "2021-04-02"
description: Nebulous rebrands to Skynet Labs with decentralized internet as the cornerstone of our mission.
thumbnail: ./thumbnail.png
categories: ["blog"]
author: Manasi Vora
avatar: ../../team/manasi-vora.png
external: https://blog.sia.tech/introducing-skynet-labs-434c852cce07
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

View File

@ -0,0 +1,10 @@
---
title: "Launching the Sia Foundation"
date: "2021-01-13"
description: Sia v1.5.4 release incorporates the Foundation Hardfork scheduled to activate around midnight, February 3rd, at block height 298,000
thumbnail: ./thumbnail.png
categories: ["blog"]
author: Luke Champine
avatar: ../../team/luke-champine.png
external: https://blog.sia.tech/launching-the-sia-foundation-ee47dfab4d2c
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,17 @@
---
title: My Second Post!
date: "2015-05-06T23:46:37.121Z"
description: Wow! I love blogging so much already.
author: Daniel Helm
avatar: ../../team/daniel-helm.png
hidden: true
---
Wow! I love blogging so much already.
Did you know that "despite its name, salted duck eggs can also be made from
chicken eggs, though the taste and texture will be somewhat different, and the
egg yolk will be less rich."?
([Wikipedia Link](https://en.wikipedia.org/wiki/Salted_duck_egg))
Yeah, I didn't either.

View File

@ -0,0 +1,111 @@
---
title: New Beginnings
date: "2015-05-28T22:40:32.169Z"
description: This is a custom description for SEO and Open Graph purposes, rather than the default generated excerpt. Simply add a description field to the frontmatter.
author: Karol Wypchlo
avatar: ../../team/karol-wypchlo.png
hidden: true
---
Far far away, behind the word mountains, far from the countries Vokalia and
Consonantia, there live the blind texts. Separated they live in Bookmarksgrove
right at the coast of the Semantics, a large language ocean. A small river named
Duden flows by their place and supplies it with the necessary regelialia.
## On deer horse aboard tritely yikes and much
The Big Oxmox advised her not to do so, because there were thousands of bad
Commas, wild Question Marks and devious Semikoli, but the Little Blind Text
didnt listen. She packed her seven versalia, put her initial into the belt and
made herself on the way.
- This however showed weasel
- Well uncritical so misled
- this is very interesting
- Goodness much until that fluid owl
When she reached the first hills of the **Italic Mountains**, she had a last
view back on the skyline of her hometown _Bookmarksgrove_, the headline of
[Alphabet Village](http://google.com) and the subline of her own road, the Line
Lane. Pityful a rhetoric question ran over her cheek, then she continued her
way. On her way she met a copy.
### Overlaid the jeepers uselessly much excluding
But nothing the copy said could convince her and so it didnt take long until a
few insidious Copy Writers ambushed her, made her drunk with
[Longe and Parole](http://google.com) and dragged her into their agency, where
they abused her for their projects again and again. And if she hasnt been
rewritten, then they are still using her.
> Far far away, behind the word mountains, far from the countries Vokalia and
> Consonantia, there live the blind texts. Separated they live in Bookmarksgrove
> right at the coast of the Semantics, a large language ocean.
It is a paradisematic country, in which roasted parts of sentences fly into your
mouth. Even the all-powerful Pointing has no control about the blind texts it is
an almost unorthographic life One day however a small line of blind text by the
name of Lorem Ipsum decided to leave for the far World of Grammar.
### According a funnily until pre-set or arrogant well cheerful
The Big Oxmox advised her not to do so, because there were thousands of bad
Commas, wild Question Marks and devious Semikoli, but the Little Blind Text
didnt listen. She packed her seven versalia, put her initial into the belt and
made herself on the way.
1. So baboon this
2. Mounted militant weasel gregariously admonishingly straightly hey
3. Dear foresaw hungry and much some overhung
4. Rash opossum less because less some amid besides yikes jeepers frenetic
impassive fruitlessly shut
When she reached the first hills of the Italic Mountains, she had a last view
back on the skyline of her hometown Bookmarksgrove, the headline of Alphabet
Village and the subline of her own road, the Line Lane. Pityful a rhetoric
question ran over her cheek, then she continued her way. On her way she met a
copy.
> The copy warned the Little Blind Text, that where it came from it would have
> been rewritten a thousand times and everything that was left from its origin
> would be the word "and" and the Little Blind Text should turn around and
> return to its own, safe country.
But nothing the copy said could convince her and so it didnt take long until a
few insidious Copy Writers ambushed her, made her drunk with Longe and Parole
and dragged her into their agency, where they abused her for their projects
again and again. And if she hasnt been rewritten, then they are still using
her. Far far away, behind the word mountains, far from the countries Vokalia and
Consonantia, there live the blind texts.
#### Silent delightfully including because before one up barring chameleon
Separated they live in Bookmarksgrove right at the coast of the Semantics, a
large language ocean. A small river named Duden flows by their place and
supplies it with the necessary regelialia. It is a paradisematic country, in
which roasted parts of sentences fly into your mouth.
Even the all-powerful Pointing has no control about the blind texts it is an
almost unorthographic life One day however a small line of blind text by the
name of Lorem Ipsum decided to leave for the far World of Grammar. The Big Oxmox
advised her not to do so, because there were thousands of bad Commas, wild
Question Marks and devious Semikoli, but the Little Blind Text didnt listen.
##### Wherever far wow thus a squirrel raccoon jeez jaguar this from along
She packed her seven versalia, put her initial into the belt and made herself on
the way. When she reached the first hills of the Italic Mountains, she had a
last view back on the skyline of her hometown Bookmarksgrove, the headline of
Alphabet Village and the subline of her own road, the Line Lane. Pityful a
rhetoric question ran over her cheek, then she continued her way. On her way she
met a copy.
###### Slapped cozy a that lightheartedly and far
The copy warned the Little Blind Text, that where it came from it would have
been rewritten a thousand times and everything that was left from its origin
would be the word "and" and the Little Blind Text should turn around and return
to its own, safe country. But nothing the copy said could convince her and so it
didnt take long until a few insidious Copy Writers ambushed her, made her drunk
with Longe and Parole and dragged her into their agency, where they abused her
for their projects again and again.

View File

@ -0,0 +1,28 @@
---
title: "Skynet Introduces Premium Accounts, Sets the Foundation for New Creator Economies"
date: "2021-03-22"
description: "Premium accounts support creators while giving users up to 20 TB of data storage per month and other perks."
author: "Skynet Labs"
categories: ["press release"]
avatar: "../images/skynet-avatar.png"
thumbnail: "../images/press-release.png"
---
**BOSTON, Massachusetts, March 22, 2021** — Skynet Labs introduces new paid accounts and sets the stage for recursive content monetization. To celebrate, Skynet is giving out premium accounts to the first 100 users who sign up at siasky.net. The giveaway includes 1 TB of storage and 3 months of censorship-resistant file pinning. Skynet is a decentralized CDN and foundation for a new, decentralized internet. It is an open protocol for building decentralized applications, and is built on top of Sia, a decentralized storage network.
Soon, creators will be able to set the price per view or download of their work and earn directly from their blogs, photos, and videos in real time. In this way, recursive content monetization reduces artists dependency on traditional advertising to make ends meet. When users pay for premium accounts in fiat, they provide a steady revenue stream from which to pay out content creators.
Application developers will also benefit from content monetization. Like content creators, developers can attach price tags to their applications. Per David Vorick, Skynet Labs CEO and Lead Developer, “We believe that developers and content creators alike should be able to earn income off of their hard work so long as they have users that appreciate what they do.”
Skynet Labs has always been committed to the freedom of expression, information, and importantly, access. Therefore, Skynets Free account tier supporting up to 100 GB of data, seeks to ensure that financial barriers never prohibit users and developers from participating in the Skynet ecosystem. Once a user meets their data cap, service on Skynet will continue but at reduced speeds, in a way similar to data plans for smartphones.
Overall, users can opt for one of three paid tiers: $5/month with 1 TB, $20/month with 4 TB, or \$80/month with 20 TB of data. Skynet Premium also comes with significant performance boosts: users will be able to pin content and browse Skynet faster, in particular any pages with monetized content. The benefits of a premium account are not purely in performance—these users are actively fueling a new creator economy, and a revolution that gives creators everywhere the power they deserve.
## About Skynet Labs 
Skynet Labs, formerly known as Nebulous, builds uncompromising software infrastructure for the decentralized internet. This includes Sia, the leading decentralized cloud storage platform, and Skynet, a content hosting and application development platform.
Skynet Labs defines uncompromising infrastructure as scalable, trustless, secure, and most importantly fully decentralized. In a blockchain industry filled with hype but lacking substance, Skynet Labs stands out as one of the few deeply technical teams that consistently delivers real products with significant potential.
Nebulous, Inc. was founded in 2014 and is backed by Paradigm, Bain Capital Ventures, A.Capital, Bessemer Venture Partners, Dragonfly Capital Partners, First Star Ventures, and other notable investors.
Learn more at siasky.net, join us on Discord, and email us at hello@sia.tech.

View File

@ -0,0 +1,35 @@
---
title: "Skynet Announces SkyDB, Unlocking a Fully Decentralized Internet"
date: "2020-10-15"
description: "SkyDB enables decentralized social media to take on `The Social Dilemma`"
author: "Skynet Labs"
categories: ["press release"]
avatar: "../images/skynet-avatar.png"
thumbnail: "../images/press-release.png"
---
**Boston, MA October 15th, 2020** — Skynet Labs, the company building the Sia decentralized cloud storage platform and the Skynet application hosting platform, today announced the launch of SkyDB, a framework that allows developers to build feature-complete applications that compete with the likes of Youtube, Twitter, Instagram, and Tiktok.
The fabric of our society and the way we interact with each other has been heavily influenced and altered by the rise of social media platforms. Biased algorithms amplify stereotypes, constant streams of content compete for our attention, and manipulated narratives wedge digital divides across political ideologies and cultural identities. As pertinently pointed out by the popular Social Dilemma documentary, “We have moved from a tools-based technology environment to an addiction and manipulation based technology environment"
SkyDB enables developers to realize the full potential of a Free Internet. Building these Web3 applications not only has benefits of privacy and control over ones data but it ushers innovation currently impossible in the siloed centralized web of today. SkyDB is a framework that allows users to create decentralized accounts and store mutable data in those accounts which can be accessed globally from any device. The user does not need to sync any blockchains or run any special software — a normal web browser is sufficient. For more details on the inner workings of SkyDB and the potential it unlocks, check out our latest blog post.
“Today is a turning point in history where the decentralized web starts to eat the centralized web,” said David Vorick, Skynet Labs CEO and lead developer. “Skynet gives developers more tools to create better experiences for users. Skynet in many senses is the first true cloud, where all data is available everywhere, regardless of the original application.”
Skynet was launched back in February 2020 and since then has seen accelerated growth in developer interest and usage. Users around the world have uploaded more than 2.5 million files amounting to 15+ TeraBytes of data using Skynet. In October, Skynet crossed a record-high of 150,000 downloads in a single day.
A thriving community of developers has built over 150 applications in the span of a few months including a Video Streaming app SkyLive, Blogging apps like Wakio and Skyblog Builder, Video & Image gallery app SkyGallery, a Decentralized AppStore Skydroid. The full list of Skynet Apps can be explored at the Skynet AppStore, and an English language Wikipedia clone.
“Next-generation applications are already being built on Skynet with more developers joining the community every day,” said Manasi Vora, Skynet Labs VP Strategy & Operations. “Skynet shines in how its easy to use not just for developers but also for the end-users, a rarity in the blockchain space.”
By building on the Sia network, Skynet delivers a 10x reduction in storage costs and a 100x reduction in bandwidth costs when compared to centralized providers, without sacrificing performance or reliability. Skynet achieves 1 gigabit per second in download and uploads speeds, with more improvements coming in future releases.
Interested in Skynet? Learn more at Siasky.net join us on Discord, and email us at hello@sia.tech.
## About Skynet Labs
Skynet Labs, previously known as Nebulous, builds uncompromising software infrastructure for the decentralized internet. This includes Sia, the leading decentralized cloud storage platform, and Skynet, a content and application hosting platform.
Skynet Labs defines uncompromising infrastructure as scalable, trustless, secure, and most important fully decentralized. In a blockchain industry filled with hype but lacking substance, Skynet Labs stands out as one of the few deeply technical teams that consistently deliver real products with significant potential.
Nebulous, Inc. was founded in 2014 and is headquartered in Boston. It is funded by Paradigm, Bain Capital Ventures, A.Capital, Bessemer Venture Partners, Dragonfly Capital Partners, First Star Ventures, and other notable investors.

View File

@ -0,0 +1,37 @@
---
title: "Sia Announces Skynet, the Storage Foundation for a Free Internet"
description: "Skynet is available with Sia version 1.4.3 and ready to use today!"
date: "2020-02-18"
author: "Skynet Labs"
categories: ["press release"]
avatar: "../images/skynet-avatar.png"
thumbnail: "../images/press-release.png"
---
**Boston, MA February 18, 2020** — Nebulous, the company building the Sia decentralized cloud storage network, today announced the launch of Skynet, a decentralized CDN and file sharing platform for application developers. Skynet enables high speed, low cost, and superior infrastructure to serve as the storage foundation for a free Internet.
Todays decentralized applications (dapps) largely rely on centralized data storage providers like Amazon, due to the lack of reliable, fast, and production-ready decentralized alternatives. This makes it difficult for developers to build truly decentralized applications and prevents the dapp ecosystem from realizing the real potential of a Free Internet.
Skynet provides an easy-to-use data storage and publishing mechanism on which developers can build decentralized applications. With a simple API and SDKs for popular programming languages, Skynet empowers developers to easily integrate decentralized storage into their applications. Importantly, end-users can directly access files on Skynet without needing to run full nodes or deal with cryptocurrencies.
By building on the Sia Network, Skynet delivers a 10x reduction in storage costs and a 100x reduction in bandwidth costs when compared to centralized providers, without sacrificing performance or reliability. Amazingly, Skynet achieves 1 gigabit per second in download and uploads speeds, with more improvements coming in future releases.
“After seven years of nonstop work, applications built on decentralized storage are finally viable. I can say without a doubt that Skynet is the most powerful tech we've ever built” said David Vorick, Nebulous CEO and Sia Lead Developer. “Skynet makes it possible for content and applications to be deployed to a decentralized network just in seconds and be immediately available to everyone across the world.”
Our vision for Skynet involves supporting decentralized content publishing. Whether through news articles, blog posts, music, or video, Nebulous envisions Skynet as a decentralized and censorship-resistant foundation for content creators to deliver media their audience cares about. No more de-platforming, no more exploitation.
“One place where Skynet shines is speed. Page loading is almost instant. Deployment to Skynet is also almost instant. Weve demonstrated that decentralized storage can be as fast as its centralized competitors” said Manasi Vora, Nebulous Head of Product Strategy. “With storage and bandwidth prices so low, we expect Skynet to enable previously unimaginable applications and spark a renaissance in media-heavy applications.”
Since Sias launch in 2015, users have stored over 4 PB of data across over 1 million storage smart contracts. Currently, the Sia network has 2.2 PB of available storage capacity and Sia software has been downloaded over 1 million times. Sia has a thriving community of third-party developers who have launched file sharing websites like PixelDrain and Storewise, cloud offerings like Filebase and Arzen,and companion apps like Decentralizer and SiaCentral.
Interested in Skynet? Learn more at Siasky.net join us on Discord, and email us at hello@sia.tech.
Want to help us re-decentralize the Internet? Nebulous is hiring for positions in engineering and operations. Learn more about our projects and apply today!
## About Skynet Labs 
Nebulous builds uncompromising blockchain hardware and software infrastructure for the decentralized internet. This includes Sia, the leading decentralized cloud storage platform, and Obelisk, a producer of blockchain-related hardware.
Nebulous defines uncompromising infrastructure as scalable, trustless, secure, and most important fully decentralized. In a blockchain industry filled with hype but lacking substance, Nebulous stands out as one of the few deeply technical teams that consistently delivers real products with significant potential.
Nebulous, Inc. was founded in 2014 and is headquartered in Boston. Nebulous is funded by Bain Capital Ventures, A.Capital, Raptor Group, First Star Ventures, and other notable investors.

View File

@ -0,0 +1,10 @@
---
title: "Skynet Community Update — March 2021"
date: "2021-03-10"
description: Get updated on the Skynet and Sia ecosystem for the past few months.
thumbnail: ./thumbnail.png
categories: ["blog"]
author: Steve Funk
avatar: ../../team/steve-funk.png
external: https://blog.sia.tech/skynet-community-update-march-2021-960426c9abce
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View File

@ -0,0 +1,10 @@
---
title: "The Skynet License"
date: "2021-03-18"
description: New source code license by Skynet Labs that enables a sustainable business model while empowering freedom
thumbnail: ./thumbnail.png
categories: ["blog"]
author: David Vorick
avatar: ../../team/david-vorick.png
external: https://blog.sia.tech/the-skynet-license-cf62d5c358c5
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

View File

@ -0,0 +1,19 @@
<svg xmlns="http://www.w3.org/2000/svg" width="80" height="80" viewBox="0 0 80 80">
<defs>
<filter id="1-a">
<feColorMatrix in="SourceGraphic" values="0 0 0 0 0.050980 0 0 0 0 0.050980 0 0 0 0 0.050980 0 0 0 1.000000 0"/>
</filter>
</defs>
<g fill="none" fill-rule="evenodd">
<path fill="#00C65E" d="M29.031876,20.9098666 L28.9376,20.9996 L26.0006,32.418457 L26.0002217,47.4850772 C15.5253909,39.5307935 9.94339742,30.0594707 13.1535,24.4995 C15.3983377,20.6113901 21.4491262,19.4904168 29.031876,20.9098666 Z"/>
<g filter="url(#1-a)">
<g transform="translate(10 9)">
<path stroke="#222829" stroke-width="2" d="M25.1486,1.9116 C26.6606,0.6766 28.2946,-0.0004 30.0006,-0.0004 C37.7326,-0.0004 44.0006,13.8786 44.0006,30.9996 C44.0006,48.1206 37.7326,61.9996 30.0006,61.9996 C22.2676,61.9996 16.0006,48.1206 16.0006,30.9996 C16.0006,23.8406 17.0956,17.2476 18.9376,11.9996"/>
<path stroke="#222829" stroke-width="2" d="M57.6955,41.9185 C57.8795,43.6185 57.6145,45.1705 56.8465,46.4995 C52.9805,53.1955 37.8275,51.6855 23.0005,43.1245 C8.1735,34.5645 -0.7125,22.1955 3.1535,15.4995 C7.0195,8.8035 22.1735,10.3145 37.0005,18.8745 C43.2405,22.4785 48.4285,26.7565 52.0565,31.0025"/>
<path stroke="#222829" stroke-width="2" d="M2.3049,41.9155 C2.1199,43.6165 2.3859,45.1695 3.1539,46.4995 C7.0199,53.1955 22.1729,51.6855 36.9999,43.1245 C51.8269,34.5645 60.7129,22.1955 56.8469,15.4995 C52.9809,8.8035 37.8269,10.3145 22.9999,18.8745 C16.7599,22.4785 11.5729,26.7545 7.9459,30.9995"/>
<path stroke="#222829" stroke-width="2" d="M6.0002 38.9995C6.0002 40.6565 4.6562 41.9995 3.0002 41.9995 1.3442 41.9995.0002 40.6565.0002 38.9995.0002 37.3435 1.3442 35.9995 3.0002 35.9995 4.6562 35.9995 6.0002 37.3435 6.0002 38.9995zM60.0002 38.9995C60.0002 40.6565 58.6562 41.9995 57.0002 41.9995 55.3442 41.9995 54.0002 40.6565 54.0002 38.9995 54.0002 37.3435 55.3442 35.9995 57.0002 35.9995 58.6562 35.9995 60.0002 37.3435 60.0002 38.9995zM26.0002 3.9995C26.0002 5.6565 24.6562 6.9995 23.0002 6.9995 21.3442 6.9995 20.0002 5.6565 20.0002 3.9995 20.0002 2.3435 21.3442.9995 23.0002.9995 24.6562.9995 26.0002 2.3435 26.0002 3.9995zM21.0002 38.9995C21.0002 32.9995 27.0002 31.9995 27.0002 31.9995M39.0002 38.9995C39.0002 32.9995 33.0002 31.9995 33.0002 31.9995"/>
<path stroke="#222829" stroke-width="2" d="M35.0002,26.4995 C35.0002,29.9995 33.0372,32.9995 30.0002,32.9995 C26.9632,32.9995 25.0002,29.9995 25.0002,26.4995 C25.0002,22.9995 26.0002,20.9995 30.0002,20.9995 C34.0002,20.9995 35.0002,22.9995 35.0002,26.4995 Z"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,6 @@
- cards:
- title: Own your data
description: No one owns or controls your account data except for you. Ownership extends to original blogs, music, and videos too. This is all possible through decentralized apps built on decentralized storage.
image: ./assets/own-your-data.svg
- title: Censorship-resistant content
description: Today, censorship can come arbitrarily, top-down, and as a tool to silence expression. Post and share content on Skynet, or use Skynet as a fail-over for your website if a service provider goes down.

View File

@ -0,0 +1,92 @@
- name: David Vorick
position: CEO and Lead Developer
image: ./team/david-vorick.png
social:
github: https://github.com/DavidVorick
gitlab: https://gitlab.com/DavidVorick
twitter: https://twitter.com/davidvorick
- name: Chris Schinnerl
position: VP of Technology
image: ./team/chris-schinnerl.png
social:
github: https://github.com/ChrisSchinnerl
gitlab: https://gitlab.com/ChrisSchinnerl
twitter: https://twitter.com/ChrisSchinnerl
- name: Steve Funk
position: Head of Support
image: ./team/steve-funk.png
social:
linkedin: https://www.linkedin.com/in/stevengfunk
- name: Matt Sevey
position: Engineering Manager
image: ./team/matt-sevey.png
social:
github: https://github.com/MSevey
gitlab: https://gitlab.com/MSevey
linkedin: https://www.linkedin.com/in/sevey
twitter: https://twitter.com/MJSevey
- name: Manasi Vora
position: VP of Strategy and Ops
image: ./team/manasi-vora.png
social:
linkedin: https://linkedin.com/in/manasi-vora-cfa-bb9a1715
twitter: https://twitter.com/manasilvora
- name: PJ Brone
position: Core Developer
image: ./team/pj-brone.png
social:
github: https://github.com/peterjan
gitlab: https://gitlab.com/pjbrone
linkedin: https://www.linkedin.com/in/peterjanbrone
twitter: https://twitter.com/peterjanbrone
- name: Marcin Swieczkowski
position: Core Developer
image: ./team/marcin-swieczkowski.png
social:
github: https://github.com/m-cat
gitlab: https://gitlab.com/m-cat
- name: Karol Wypchlo
position: Full Stack Developer
image: ./team/karol-wypchlo.png
social:
github: https://github.com/kwypchlo
gitlab: https://gitlab.com/kwypchlo
linkedin: https://www.linkedin.com/in/karolwypchlo/
twitter: https://twitter.com/kwypchlo
- name: Ivaylo Novakov
position: Core Developer
image: ./team/ivaylo-novakov.png
social:
github: https://github.com/ro-tex
gitlab: https://gitlab.com/ro-tex
linkedin: https://www.linkedin.com/in/inovakov/
twitter: https://twitter.com/inovakov
- name: Filip Rysavy
position: Testing Developer
image: ./team/filip-rysavy.png
social:
linkedin: https://www.linkedin.com/in/filiprysavy/
- name: Nicole Tay
position: Head of Marketing
image: ./team/nicole-tay.png
social:
linkedin: https://www.linkedin.com/in/nicolehtay/
twitter: https://twitter.com/NicoleHTay
- name: Daniel Helm
position: Developer Evangelist
image: ./team/daniel-helm.png
social:
github: https://github.com/dghelm
linkedin: https://www.linkedin.com/in/dghelm/
twitter: https://twitter.com/danielgileshelm

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,23 @@
/**
* Implement Gatsby's Browser APIs in this file.
*
* See: https://www.gatsbyjs.com/docs/browser-apis/
*/
import "normalize.css";
import "@fontsource/sora/300.css"; // light
import "@fontsource/sora/400.css"; // normal
import "@fontsource/sora/500.css"; // medium
import "@fontsource/sora/600.css"; // semibold
import "@fontsource/source-sans-pro/400.css"; // normal
import "@fontsource/source-sans-pro/600.css"; // semibold
import "./src/styles/global.css";
import * as React from "react";
import Layout from "./src/components/Layout";
export const wrapPageElement = ({ element, props }) => {
// props provide same data to Layout as Page element will get
// including location, data, etc - you don't need to pass it
return <Layout {...props}>{element}</Layout>;
};

View File

@ -0,0 +1,122 @@
const { defaultIcons } = require("gatsby-plugin-manifest/common");
module.exports = {
siteMetadata: {
title: `Skynet`,
description: `Skynet is a decentralized file sharing and content distribution protocol`,
author: `Skynet Labs`,
siteUrl: `https://siasky.net`,
image: `https://siasky.net/icons/icon-512x512.png`,
},
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `src`,
path: `${__dirname}/src/`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `data`,
path: `${__dirname}/data/`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/data/news`,
name: `news`,
},
},
`gatsby-plugin-postcss`,
`gatsby-plugin-react-helmet`,
`gatsby-plugin-image`,
`gatsby-plugin-sharp`,
`gatsby-plugin-react-svg`,
`gatsby-plugin-robots-txt`,
`gatsby-transformer-sharp`,
`gatsby-transformer-json`,
`gatsby-transformer-yaml`,
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
{
resolve: `gatsby-remark-classes`,
options: {
classMap: {
heading: "font-semibold text-palette-600",
paragraph: "font-content text-base text-palette-400",
strong: "font-semibold",
link: "text-primary hover:underline transition-colors duration-200",
"heading[depth=1]": "text-4xl",
"heading[depth=2]": "text-3xl",
"paragraph + paragraph": "mt-8",
"paragraph + heading": "mt-20",
"heading + paragraph": "mt-12",
},
},
},
{
resolve: `gatsby-remark-images`,
options: {
maxWidth: 630,
},
},
{
resolve: `gatsby-remark-responsive-iframe`,
options: {
wrapperStyle: `margin-bottom: 1.0725rem`,
},
},
`gatsby-remark-prismjs`,
`gatsby-remark-copy-linked-files`,
`gatsby-remark-smartypants`,
],
},
},
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `Skynet`,
short_name: `Skynet`,
start_url: `/`,
background_color: `#f1f7f2`,
theme_color: `#f1f7f2`,
display: `minimal-ui`,
icon: `src/images/logo.svg`, // This path is relative to the root of the site.
icons: [
...defaultIcons,
// when we're serving content from the portal on our pathnames that do not have
// favicon defined (basically all non-html content), we want the browsers to be
// able to fall back to favicon.ico (firefox does that)
{
src: `favicon.ico`,
sizes: `32x32`,
type: `image/x-icon`,
},
],
},
},
{
resolve: "gatsby-plugin-matomo",
options: {
siteId: 3,
matomoUrl: "https://surveillance.sia.tech",
siteUrl: "https://siasky.net",
},
},
],
// mapping: {
// "MarkdownRemark.frontmatter.author": `teamYaml`,
// },
};

View File

@ -0,0 +1,122 @@
const path = require(`path`);
const { createFilePath } = require(`gatsby-source-filesystem`);
exports.onCreateWebpackConfig = ({ actions }) => {
actions.setWebpackConfig({
resolve: {
fallback: {
crypto: require.resolve("crypto-browserify"),
stream: require.resolve("stream-browserify"),
},
},
});
};
exports.createPages = async ({ graphql, actions, reporter }) => {
const { createPage } = actions;
// Define a template for news post
const PostTemplate = path.resolve(`./src/templates/news-post.js`);
// Get all markdown news posts sorted by date and all possible authors
const result = await graphql(
`
{
allMarkdownRemark(
sort: { fields: [frontmatter___date], order: ASC }
filter: { frontmatter: { external: { eq: null } } }
) {
nodes {
id
fields {
slug
}
}
}
}
`
);
if (result.errors) {
reporter.panicOnBuild(`There was an error loading your news posts`, result.errors);
return;
}
const posts = result.data.allMarkdownRemark.nodes;
// Create news posts pages
// But only if there's at least one markdown file found at "/data/news" (defined in gatsby-config.js)
// `context` is available in the template as a prop and as a variable in GraphQL
if (posts.length > 0) {
posts.forEach((post, index) => {
const previousPostId = index === 0 ? null : posts[index - 1].id;
const nextPostId = index === posts.length - 1 ? null : posts[index + 1].id;
createPage({
path: post.fields.slug,
component: PostTemplate,
context: {
id: post.id,
previousPostId,
nextPostId,
},
});
});
}
};
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions;
if (node.internal.type === `MarkdownRemark`) {
const value = createFilePath({ node, getNode });
createNodeField({
name: `slug`,
node,
value,
});
}
};
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions;
// Explicitly define the siteMetadata {} object
// This way those will always be defined even if removed from gatsby-config.js
// Also explicitly define the Markdown frontmatter
// This way the "MarkdownRemark" queries will return `null` even when no
// news posts are stored inside "/data/news" instead of returning an error
createTypes(`
type SiteSiteMetadata {
author: String
siteUrl: String
social: Social
}
type Author {
name: String
summary: String
}
type Social {
twitter: String
}
type MarkdownRemark implements Node {
frontmatter: Frontmatter
fields: Fields
}
type Frontmatter {
title: String
description: String
date: Date @dateformat
author: String
external: String
hidden: Boolean
categories: [String]
}
type Fields {
slug: String
}
`);
};

View File

@ -0,0 +1,7 @@
/**
* Implement Gatsby's SSR (Server Side Rendering) APIs in this file.
*
* See: https://www.gatsbyjs.com/docs/ssr-apis/
*/
// You can delete this file if you're not using it

Some files were not shown because too many files have changed in this diff Show More