added database and express server

This commit is contained in:
notnull 2019-02-07 18:47:35 -08:00
parent 8b89ec32f1
commit 9e90002113
18 changed files with 4963 additions and 41 deletions

35
api/articles.js Normal file
View File

@ -0,0 +1,35 @@
const router = require('express').Router()
const { Article } = require('../db/models')
module.exports = router
router.get('/', async (req, res, next) => {
try {
const articles = await Article.findAll()
res.status(201).send(articles)
} catch (err) {
next(err)
}
})
router.get('/:id', async (req, res, next) => {
try {
const article = await Article.findById(req.params.id)
console.log(article.title)
console.log("by: " + article.author)
console.log(article.text)
res.status(201).send(article)
} catch (err) {
next(err)
}
})
router.post('/', async (req, res, next) => {
const body = req.body
try {
const article = await Article.create(body)
res.redirect(article.id)
} catch (err) {
next(err)
}
})

19
api/index.js Executable file
View File

@ -0,0 +1,19 @@
const router = require('express').Router()
module.exports = router
router.use('/items', require('./items'))
router.use('/articles', require('./articles'))
router.get('/', async (req, res, next) => {
try {
res.send('/n-------/nHello from Express!/n--------/n')
} catch (err) {
next(err)
}
})
router.use((req, res, next) => {
const error = new Error('Not Found!!!!!!!')
error.status = 404
next(error)
})

23
api/items.js Executable file
View File

@ -0,0 +1,23 @@
const router = require('express').Router()
const { Item } = require('../db/models')
module.exports = router
router.get('/', async (req, res, next) => {
try {
const items = await Item.findAll()
res.status(201).send(items)
} catch (err) {
next(err)
}
})
router.post('/', async (req, res, next) => {
try {
const item = await Item.create(req.body)
res.status(201).json(item)
} catch (err) {
next(err)
}
})

1
api/postcommand Normal file
View File

@ -0,0 +1 @@
curl -d {"title":"", "text": ""} -H Content-Type: application/json -X POST http://localhost:1337/api/articles

26
ascii.js Normal file
View File

@ -0,0 +1,26 @@
const ascii = String.raw`
. .
* . . . . *
. . . . . .
o . .
. . . .
0 . anarchy
. . , planet , ,
. \ . .
. . \ ,
. o . . .
. . . \ , .
#\##\# . .
# #O##\### .
. . #*# #\##\### .
. ##*# #\##\## .
. . ##*# #o##\# .
. *# #\# . .
\ . .
____^/\___^--____/\____O______________/\/\---/\___________--
/\^ ^ ^ ^ ^^ ^ '\ ^ ^
-- - -- - - --- __ ^
-- __ ___-- ^ ^`
module.exports = ascii

25
db/db.js Executable file
View File

@ -0,0 +1,25 @@
const Sequelize = require('sequelize')
const pkg = require('../package.json')
const databaseName = pkg.name + (process.env.NODE_ENV === 'test' ? '-test' : '')
const createDB = () => {
const db = new Sequelize(
process.env.DATABASE_URL || `postgres://localhost:5432/${databaseName}`,
{
logging: false,
operatorsAliases: false
}
)
return db
}
const db = createDB()
module.exports = db
// This is a global Mocha hook used for resource cleanup.
// Otherwise, Mocha v4+ does not exit after tests.
if (process.env.NODE_ENV === 'test') {
after('close database connection', () => db.close())
}

1248
db/desert.txt Normal file

File diff suppressed because it is too large Load Diff

6
db/index.js Executable file
View File

@ -0,0 +1,6 @@
const db = require('./db')
// register models
require('./models')
module.exports = db

20
db/models/article.js Normal file
View File

@ -0,0 +1,20 @@
const Sequelize = require('sequelize')
const db = require('../db')
const Article = db.define('articles', {
title: {
type: Sequelize.STRING,
allowNull: false
},
author: {
type: Sequelize.STRING,
defaultValue: "anonymous"
},
text: {
type: Sequelize.TEXT,
allowNull: false
},
})
module.exports = Article

4
db/models/index.js Executable file
View File

@ -0,0 +1,4 @@
const Item = require('./item')
const Article = require('./article')
module.exports = { Item, Article }

11
db/models/item.js Executable file
View File

@ -0,0 +1,11 @@
const Sequelize = require('sequelize')
const db = require('../db')
const Item = db.define('items', {
name: {
type: Sequelize.STRING,
allowNull: false
}
})
module.exports = Item

37
db/seed.js Executable file
View File

@ -0,0 +1,37 @@
const db = require('../db')
const fs = require("fs")
const { Item, Article } = require('./models')
const desert = fs.readFileSync("/home/notnull/projex/bootstrap/server/db/desert.txt", "utf8")
const testItem = {
name: 'item'
}
const testArticle = {
title: "Desert",
text: desert
}
console.log(Article)
async function runSeed() {
await db.sync({ force: true })
console.log('db synced!')
console.log('seeding...')
try {
await Item.create(testItem)
await Article.create(testArticle)
console.log('seeded successfully')
} catch (err) {
console.error(err)
process.exitCode = 1
} finally {
console.log('closing db connection')
await db.close()
console.log('db connection closed')
}
}
runSeed()

42
hn-client.js Normal file
View File

@ -0,0 +1,42 @@
const fetch = require("node-fetch");
// implemented from: https://github.com/HackerNews/API
const HN_PREFIX = "https://hacker-news.firebaseio.com/v0/";
const TOP_STORIES = "topstories";
const ITEM = "item";
function hnFetch(type, id = "") {
const url = id
? `${HN_PREFIX}${type}/${id}.json`
: `${HN_PREFIX}${type}.json`;
return fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json"
}
})
.then(res => {
if (!isStatusOk(res.status)) {
throw res;
}
return res.json();
})
.then(res => res)
.catch(error => console.error(error));
}
function isStatusOk(statusCode) {
return statusCode === 200 || statusCode === 304;
}
async function main() {
const storyIds = await hnFetch(TOP_STORIES);
const stories = await Promise.all(
storyIds.slice(0, 20).map(storyId => hnFetch(ITEM, storyId))
);
console.log(stories.map(story => { delete story.kids; return story; }));
}
main();

65
index.js Normal file → Executable file
View File

@ -1,42 +1,35 @@
const fetch = require("node-fetch");
const express = require('express')
const path = require('path')
const app = express()
const morgan = require('morgan')
const ascii = require('./ascii')
const port = process.env.PORT || 1337
// implemented from: https://github.com/HackerNews/API
app.use(morgan('tiny'))
const HN_PREFIX = "https://hacker-news.firebaseio.com/v0/";
// body parsing middleware
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(require('body-parser').text())
app.use('/api', require('./api'))
const TOP_STORIES = "topstories";
const ITEM = "item";
function hnFetch(type, id = "") {
const url = id
? `${HN_PREFIX}${type}/${id}.json`
: `${HN_PREFIX}${type}.json`;
return fetch(url, {
method: "GET",
headers: {
"Content-Type": "application/json"
}
})
.then(res => {
if (!isStatusOk(res.status)) {
throw res;
}
return res.json();
})
.then(res => res)
.catch(error => console.error(error));
if (process.env.NODE_ENV === 'production') {
// Express will serve up production assets
app.use(express.static(path.join(__dirname, '..', 'client', 'build')))
}
app.get('*', (req, res) =>
res.sendFile(path.resolve(__dirname, '..', 'client', 'public', 'index.html'))
)
function isStatusOk(statusCode) {
return statusCode === 200 || statusCode === 304;
}
async function main() {
const storyIds = await hnFetch(TOP_STORIES);
const stories = await Promise.all(
storyIds.slice(0, 20).map(storyId => hnFetch(ITEM, storyId))
);
// error handling endware
app.use((err, req, res, next) => {
console.error(err)
console.error(err.stack)
res.status(err.status || 500).send(err.message || 'Internal server error.')
next()
})
console.log(stories.map(story => { delete story.kids; return story; }));
}
main();
app.listen(port, () => {
console.log('\n' + ascii + '\n')
console.log(`Doin' haxor stuff on port ${port}`)
})

3418
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,16 +3,30 @@
"version": "1.0.0",
"description": "TODO",
"main": "index.js",
"scripts": {
"test": "mocha ."
"author": "anarchyplanet",
"license": "Ⓐ",
"bugs": {
"url": "https://irc.anarchyplanet.org/git/notnull/server/issues"
},
"homepage": "irc.anarchyplanet.org",
"repository": {
"type": "git",
"url": "ssh://git@irc.anarchyplanet.org:2222/notnull/hacker-news-cli.git"
},
"author": "",
"license": "MIT",
"scripts": {
"test": "mocha .",
"seed": "node db/seed.js",
"start": "nodemon index"
},
"dependencies": {
"node-fetch": "^2.3.0"
"node-fetch": "^2.3.0",
"axios": "^0.18.0",
"concurrently": "^4.0.1",
"express": "^4.16.4",
"http-proxy-middleware": "^0.19.0",
"morgan": "^1.9.1",
"nodemon": "^1.18.9",
"pg": "^7.5.0",
"sequelize": "^4.39.1"
}
}