Skip to content

Commit 099662a

Browse files
committed
init
0 parents  commit 099662a

36 files changed

+25031
-0
lines changed

.eslintrc.js

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
const path = require("path");
2+
3+
module.exports = {
4+
parser: "@typescript-eslint/parser",
5+
plugins: ["@typescript-eslint", "graphql"],
6+
extends: [
7+
"eslint:recommended",
8+
"plugin:react/recommended",
9+
"plugin:@typescript-eslint/recommended",
10+
"prettier",
11+
],
12+
parserOptions: {
13+
ecmaFeatures: {
14+
jsx: true,
15+
},
16+
ecmaVersion: 6,
17+
project: "./tsconfig.json",
18+
sourceType: "module",
19+
},
20+
settings: {
21+
react: {
22+
version: "detect",
23+
},
24+
},
25+
env: {
26+
es6: true,
27+
browser: true,
28+
jest: true,
29+
node: true,
30+
},
31+
rules: {
32+
semi: [2, "always"],
33+
"@typescript-eslint/explicit-function-return-type": "off",
34+
"@typescript-eslint/explicit-member-accessibility": "off",
35+
"@typescript-eslint/indent": "off",
36+
"@typescript-eslint/member-delimiter-style": "off",
37+
"@typescript-eslint/no-explicit-any": "off",
38+
"@typescript-eslint/no-var-requires": "off",
39+
"@typescript-eslint/no-use-before-define": "off",
40+
"@typescript-eslint/prefer-interface": "off",
41+
"@typescript-eslint/no-unused-vars": [
42+
"error",
43+
{
44+
argsIgnorePattern: "^_",
45+
},
46+
],
47+
"graphql/template-strings": [
48+
"error",
49+
{
50+
env: "relay",
51+
schemaJsonFilepath: path.resolve(__dirname, "./schema.json"),
52+
tagName: "graphql",
53+
},
54+
],
55+
"no-console": [
56+
"error",
57+
{
58+
allow: ["warn", "error"],
59+
},
60+
],
61+
"react/display-name": 0,
62+
"react/prop-types": 0,
63+
"no-undef": 0,
64+
},
65+
};

.gitignore

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
.DS_Store
2+
.env
3+
.yarn-integrity
4+
yarn-debug.log
5+
yarn-error.log
6+
7+
node_modules/
8+
typings/
9+
10+
# Gatsby files
11+
.cache/
12+
public
13+
schema.json
14+
schema.graphql
15+
16+
feeds/output

.vscode/settings.json

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"files.exclude": {
3+
".git/": true,
4+
"node_modules/": false,
5+
"public/": false
6+
},
7+
"search.exclude": {
8+
"**/.cache": true,
9+
"**/node_modules": true,
10+
"**/public": true
11+
},
12+
"editor.rulers": [80],
13+
"editor.tabSize": 2,
14+
"editor.formatOnSave": true,
15+
"eslint.autoFixOnSave": true,
16+
"eslint.validate": [
17+
{
18+
"language": "javascript",
19+
"autoFix": true
20+
},
21+
{
22+
"language": "javascriptreact",
23+
"autoFix": true
24+
},
25+
{
26+
"language": "typescript",
27+
"autoFix": true
28+
},
29+
{
30+
"language": "typescriptreact",
31+
"autoFix": true
32+
}
33+
],
34+
"tslint.enable": false,
35+
"typescript.tsdk": "./node_modules/typescript/lib",
36+
"debug.node.autoAttach": "off",
37+
"javascript.validate.enable": false,
38+
"typescript.format.enable": false,
39+
"typescript.format.insertSpaceAfterCommaDelimiter": false,
40+
"typescript.check.npmIsInstalled": false,
41+
"javascript.autoClosingTags": false,
42+
"typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": false,
43+
"typescript.format.insertSpaceAfterKeywordsInControlFlowStatements": false,
44+
"typescript.tsc.autoDetect": "on",
45+
"typescript.validate.enable": true,
46+
"markdown.extension.toc.githubCompatibility": true
47+
}

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2019 Owen Kelly
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Owen Kelly
2+
3+
4+
Based on:
5+
- https://github.com/damassi/gatsby-starter-typescript-rebass-netlifycms

feeds/index.ts

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Convert source.opml to an object
2+
// traverse the object in parallel and download the rss feed
3+
// convert the rss feed to js
4+
// pull the top 3 items from each feed
5+
// pipe those items into a gatsby site
6+
7+
import { Process } from "./process";
8+
9+
Process({ source: "../source.opml", output: "./output" });

feeds/opml.ts

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
interface OPML {
2+
title: string;
3+
children?: (Folder)[] | null;
4+
}
5+
interface Folder {
6+
text: string;
7+
title: string;
8+
children?: (Feed)[] | null;
9+
}
10+
interface Feed {
11+
type: string;
12+
text: string;
13+
title: string;
14+
xmlurl: string;
15+
htmlurl: string;
16+
folder: string;
17+
items?: FeedItem[];
18+
}
19+
20+
export interface FeedItem {
21+
creator: string;
22+
title: string;
23+
link: string;
24+
pubDate: string;
25+
"dc:creator": string;
26+
content: string;
27+
contentSnippet: string;
28+
guid: string;
29+
categories?: (null)[] | null;
30+
isoDate: string;
31+
}
32+
33+
export { OPML, Folder, Feed };

feeds/process.ts

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import * as fs from "fs";
2+
import * as path from "path";
3+
import * as opmlToJSON from "opml-to-json";
4+
import * as rimraf from "rimraf";
5+
6+
import * as Parser from "rss-parser";
7+
8+
import { OPML } from "./opml";
9+
10+
let parser = new Parser({
11+
headers: {
12+
Accept: "application/rss+xml",
13+
"User-Agent": "goodengineering.dev",
14+
},
15+
});
16+
17+
async function Process({ source, output }: { source: string; output: string }) {
18+
const opmlRaw = fs.readFileSync(path.join(__dirname, source));
19+
20+
const opml: OPML = await new Promise((resolve, reject) =>
21+
opmlToJSON(opmlRaw, (err, json) => {
22+
if (err) {
23+
reject(err);
24+
}
25+
resolve(json);
26+
})
27+
);
28+
29+
if (!opml.children) {
30+
return;
31+
}
32+
33+
rimraf.sync(path.join(__dirname, output));
34+
35+
await Promise.all(
36+
opml.children
37+
.map(
38+
folder =>
39+
folder.children &&
40+
folder.children.map(async feed => {
41+
try {
42+
const url = new URL(feed.htmlurl);
43+
44+
const items = await parser.parseURL(feed.xmlurl);
45+
46+
await fs.mkdirSync(path.join(__dirname, output, url.hostname), {
47+
recursive: true,
48+
});
49+
50+
await fs.writeFileSync(
51+
path.join(__dirname, output, url.hostname, "feed.json"),
52+
JSON.stringify({ ...feed, ...items }, null, 2),
53+
{ encoding: "utf8" }
54+
);
55+
return true;
56+
} catch (err) {
57+
return true;
58+
}
59+
})
60+
)
61+
.reduce((a, b) => a.concat(b), [])
62+
);
63+
}
64+
65+
export { Process };

feeds/tsconfig.json

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"compilerOptions": {
3+
"module": "commonjs",
4+
"allowJs": true,
5+
"allowSyntheticDefaultImports": true,
6+
"baseUrl": "./",
7+
"jsx": "react",
8+
"lib": ["dom", "esnext", "es2015", "es2016", "es2017"],
9+
"moduleResolution": "node",
10+
"noImplicitAny": false,
11+
"noUnusedLocals": true,
12+
"noUnusedParameters": true,
13+
"plugins": [
14+
{
15+
"name": "typescript-styled-plugin"
16+
}
17+
],
18+
"target": "es2015",
19+
"paths": {
20+
"@src/*": ["./src/*"],
21+
"@vendor/*": ["./vendor/*"]
22+
}
23+
},
24+
"include": ["**/*.ts", "**/*.tsx"],
25+
"exclude": ["node_modules/*", "public/*"]
26+
}

gatsby-browser.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// @ts-check
2+
3+
export { wrapRootElement } from "./src/App";

gatsby-config.js

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// @ts-check
2+
3+
module.exports = {
4+
siteMetadata: {
5+
title: "Good Engineering",
6+
description: "Stories from the top engineering blogs in one place.",
7+
author: "Owen Kelly",
8+
},
9+
10+
plugins: [
11+
"gatsby-plugin-netlify-cache",
12+
{
13+
resolve: `gatsby-plugin-prefetch-google-fonts`,
14+
options: {
15+
fonts: [
16+
{
17+
family: `IBM Plex Serif`,
18+
variants: [`400`],
19+
},
20+
{
21+
family: `IBM Plex Mono`,
22+
variants: [`400`, `400i`, `800`],
23+
},
24+
],
25+
},
26+
},
27+
{
28+
resolve: `gatsby-plugin-typography`,
29+
options: {
30+
pathToConfigModule: `src/theme/typography`,
31+
omitGoogleFont: true,
32+
},
33+
},
34+
{
35+
resolve: "gatsby-source-filesystem",
36+
options: {
37+
name: "posts",
38+
path: `${__dirname}/feeds/output/`,
39+
},
40+
},
41+
"gatsby-plugin-catch-links",
42+
"gatsby-plugin-typescript",
43+
"gatsby-plugin-react-helmet",
44+
{
45+
resolve: "gatsby-plugin-styled-components",
46+
options: {
47+
ssr: true,
48+
},
49+
},
50+
{
51+
resolve: "gatsby-plugin-react-svg",
52+
options: {
53+
rule: {
54+
include: /src/,
55+
},
56+
},
57+
},
58+
],
59+
};

0 commit comments

Comments
 (0)