Moved client-side markdown rendering to this server
This commit is contained in:
Generated
+89
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "news-server",
|
||||
"version": "1.3.1",
|
||||
"version": "1.4.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "news-server",
|
||||
"version": "1.3.1",
|
||||
"version": "1.4.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"cors": "^2.8.5",
|
||||
@@ -14,6 +14,7 @@
|
||||
"express": "^4.17.1",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"mariadb": "^2.5.4",
|
||||
"markdown-it": "^12.3.0",
|
||||
"sequelize": "^6.6.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -120,6 +121,11 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"node_modules/array-flatten": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
@@ -567,6 +573,14 @@
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/entities": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
|
||||
"integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-goat": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
|
||||
@@ -1032,6 +1046,14 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/linkify-it": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
|
||||
"integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
|
||||
"dependencies": {
|
||||
"uc.micro": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
@@ -1149,6 +1171,26 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/markdown-it": {
|
||||
"version": "12.3.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.0.tgz",
|
||||
"integrity": "sha512-T345UZZ6ejQWTjG6PSEHplzNy5m4kF6zvUpHVDv8Snl/pEU0OxIK0jGg8YLVNwJvT8E0YJC7/2UvssJDk/wQCQ==",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1",
|
||||
"entities": "~2.1.0",
|
||||
"linkify-it": "^3.0.1",
|
||||
"mdurl": "^1.0.1",
|
||||
"uc.micro": "^1.0.5"
|
||||
},
|
||||
"bin": {
|
||||
"markdown-it": "bin/markdown-it.js"
|
||||
}
|
||||
},
|
||||
"node_modules/mdurl": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
|
||||
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
|
||||
},
|
||||
"node_modules/media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
@@ -1903,6 +1945,11 @@
|
||||
"is-typedarray": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/uc.micro": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
|
||||
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
|
||||
},
|
||||
"node_modules/undefsafe": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz",
|
||||
@@ -2136,6 +2183,11 @@
|
||||
"picomatch": "^2.0.4"
|
||||
}
|
||||
},
|
||||
"argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"array-flatten": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
@@ -2492,6 +2544,11 @@
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"entities": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
|
||||
"integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w=="
|
||||
},
|
||||
"escape-goat": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
|
||||
@@ -2859,6 +2916,14 @@
|
||||
"package-json": "^6.3.0"
|
||||
}
|
||||
},
|
||||
"linkify-it": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
|
||||
"integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
|
||||
"requires": {
|
||||
"uc.micro": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
@@ -2959,6 +3024,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"markdown-it": {
|
||||
"version": "12.3.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.0.tgz",
|
||||
"integrity": "sha512-T345UZZ6ejQWTjG6PSEHplzNy5m4kF6zvUpHVDv8Snl/pEU0OxIK0jGg8YLVNwJvT8E0YJC7/2UvssJDk/wQCQ==",
|
||||
"requires": {
|
||||
"argparse": "^2.0.1",
|
||||
"entities": "~2.1.0",
|
||||
"linkify-it": "^3.0.1",
|
||||
"mdurl": "^1.0.1",
|
||||
"uc.micro": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"mdurl": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
|
||||
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
|
||||
},
|
||||
"media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
@@ -3519,6 +3601,11 @@
|
||||
"is-typedarray": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"uc.micro": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
|
||||
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
|
||||
},
|
||||
"undefsafe": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz",
|
||||
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "news-server",
|
||||
"version": "1.3.1",
|
||||
"version": "1.4.0",
|
||||
"description": "An API centric news server. Uses Sequelize and mariaDB by default.",
|
||||
"main": "server/server.js",
|
||||
"scripts": {
|
||||
@@ -24,6 +24,7 @@
|
||||
"express": "^4.17.1",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"mariadb": "^2.5.4",
|
||||
"markdown-it": "^12.3.0",
|
||||
"sequelize": "^6.6.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -25,6 +25,11 @@ const articles = sequelize.define('articles', {
|
||||
defaultValue: ''
|
||||
},
|
||||
|
||||
rendered: {
|
||||
type: Sequelize.TEXT,
|
||||
defaultValue: ''
|
||||
},
|
||||
|
||||
edits: {
|
||||
type: Sequelize.INTEGER(11),
|
||||
defaultValue: 0
|
||||
|
||||
@@ -2,6 +2,14 @@ const Sequelize = require('sequelize');
|
||||
const sequelize = require('..');
|
||||
|
||||
const revisions = sequelize.define('revisions', {
|
||||
index: {
|
||||
type: Sequelize.INTEGER(11),
|
||||
allowNull: false,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
unique: true
|
||||
},
|
||||
|
||||
title: {
|
||||
type: Sequelize.TEXT,
|
||||
defaultValue: ''
|
||||
@@ -17,6 +25,11 @@ const revisions = sequelize.define('revisions', {
|
||||
defaultValue: ''
|
||||
},
|
||||
|
||||
rendered: {
|
||||
type: Sequelize.TEXT,
|
||||
defaultValue: ''
|
||||
},
|
||||
|
||||
originalIndex: {
|
||||
type: Sequelize.INTEGER(11),
|
||||
default: null
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const { Op } = require('sequelize');
|
||||
const { articles, revisions } = require('../database/models');
|
||||
const markdownIt = require('markdown-it')();
|
||||
|
||||
const route = async (req, res) => {
|
||||
//get the existing record
|
||||
@@ -20,6 +21,7 @@ const route = async (req, res) => {
|
||||
title: record.title,
|
||||
author: record.author,
|
||||
body: record.body,
|
||||
rendered: record.rendered,
|
||||
originalIndex: record.index
|
||||
});
|
||||
|
||||
@@ -28,6 +30,7 @@ const route = async (req, res) => {
|
||||
title: req.body.title || record.title,
|
||||
author: req.body.author || record.author,
|
||||
body: req.body.body || record.body,
|
||||
rendered: markdownIt.render(req.body.body) || record.rendered,
|
||||
edits: record.edits + 1
|
||||
}, {
|
||||
where: {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const { articles } = require('../database/models');
|
||||
const markdownIt = require('markdown-it')();
|
||||
|
||||
const route = async (req, res) => {
|
||||
//check for missing data
|
||||
@@ -18,7 +19,8 @@ const route = async (req, res) => {
|
||||
const [instance, created] = await articles.upsert({
|
||||
title: req.body.title,
|
||||
author: req.body.author,
|
||||
body: req.body.body
|
||||
body: req.body.body,
|
||||
rendered: markdownIt.render(req.body.body),
|
||||
});
|
||||
|
||||
if (!created) {
|
||||
|
||||
@@ -7,7 +7,7 @@ const query = (ascending, metadataOnly) => async (req, res) => {
|
||||
if (req.params.id && typeof(parseInt(req.params.id)) === 'number') {
|
||||
const result = await articles.findOne({
|
||||
attributes: [
|
||||
'index', 'title', 'author', 'edits', 'createdAt', 'updatedAt', ...(!metadataOnly ? ['body'] : [])
|
||||
'index', 'title', 'author', 'edits', 'createdAt', 'updatedAt', ...(!metadataOnly ? ['body', 'rendered'] : [])
|
||||
],
|
||||
where: {
|
||||
index: {
|
||||
@@ -24,7 +24,7 @@ const query = (ascending, metadataOnly) => async (req, res) => {
|
||||
else {
|
||||
const result = await articles.findAndCountAll({
|
||||
attributes: [
|
||||
'index', 'title', 'author', 'edits', 'createdAt', 'updatedAt', ...(!metadataOnly ? ['body'] : [])
|
||||
'index', 'title', 'author', 'edits', 'createdAt', 'updatedAt', ...(!metadataOnly ? ['body', 'rendered'] : [])
|
||||
],
|
||||
order: [
|
||||
['index', ascending ? 'ASC' : 'DESC']
|
||||
|
||||
@@ -20,6 +20,7 @@ const route = async (req, res) => {
|
||||
title: record.title,
|
||||
author: record.author,
|
||||
body: record.body,
|
||||
rendered: record.rendered,
|
||||
originalIndex: record.index
|
||||
});
|
||||
|
||||
|
||||
@@ -26,4 +26,48 @@ app.get('*', (req, res) => {
|
||||
server.listen(process.env.WEB_PORT || 3100, async (err) => {
|
||||
await database.sync();
|
||||
console.log(`listening to localhost:${process.env.WEB_PORT || 3100}`);
|
||||
|
||||
//parse the unrendered data from the database
|
||||
const markdownIt = require('markdown-it')();
|
||||
const { articles, revisions } = require('./database/models');
|
||||
|
||||
const missingArticles = await articles.findAll({
|
||||
where: {
|
||||
rendered: ''
|
||||
}
|
||||
});
|
||||
|
||||
const missingRevisions = await revisions.findAll({
|
||||
where: {
|
||||
rendered: ''
|
||||
}
|
||||
});
|
||||
|
||||
await Promise.all(
|
||||
missingArticles.map(async ma => {
|
||||
ma.update({
|
||||
rendered: markdownIt.render(ma.body)
|
||||
}, {
|
||||
where: {
|
||||
index: ma.index
|
||||
}
|
||||
});
|
||||
})
|
||||
)
|
||||
.then(result => {if (result.length > 0) console.log('Rendered articles in HTML'); })
|
||||
;
|
||||
|
||||
await Promise.all(
|
||||
missingRevisions.map(async mr => {
|
||||
mr.update({
|
||||
rendered: markdownIt.render(mr.body)
|
||||
}, {
|
||||
where: {
|
||||
index: mr.index
|
||||
}
|
||||
});
|
||||
})
|
||||
)
|
||||
.then(result => {if (result.length > 0) console.log('Rendered revisions in HTML'); })
|
||||
;
|
||||
});
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE articles ADD COLUMN rendered TEXT DEFAULT "" AFTER body;
|
||||
|
||||
ALTER TABLE revisions ADD COLUMN rendered TEXT DEFAULT "" AFTER body;
|
||||
|
||||
Reference in New Issue
Block a user