More development
This commit is contained in:
parent
f35c195680
commit
a2b1fc9bc8
13 changed files with 114 additions and 208 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -59,6 +59,7 @@ typings/
|
|||
|
||||
# Local development config file
|
||||
config/config.json
|
||||
config.json
|
||||
package-lock.json
|
||||
public/assets/app.js
|
||||
public/assets/app.css
|
||||
|
|
|
@ -149,122 +149,6 @@ Article.prototype = createPrototype({
|
|||
is_featured: false,
|
||||
})
|
||||
},
|
||||
|
||||
/*parent() {
|
||||
return this.belongsTo(Page, 'parent_id')
|
||||
},
|
||||
|
||||
banner() {
|
||||
return this.belongsTo(Media, 'banner_id')
|
||||
},
|
||||
|
||||
media() {
|
||||
return this.belongsTo(Media, 'media_id')
|
||||
},
|
||||
|
||||
staff() {
|
||||
return this.belongsTo(Staff, 'staff_id')
|
||||
},
|
||||
|
||||
files() {
|
||||
return this.hasManyFiltered(File, 'file', 'article_id')
|
||||
.query(qb => {
|
||||
qb.orderBy('id', 'asc')
|
||||
})
|
||||
},*/
|
||||
|
||||
/*getAll(ctx, where = {}, withRelated = [], orderBy = 'id', limitToday = false) {
|
||||
return this.query(qb => {
|
||||
this.baseQueryAll(ctx, qb, where, orderBy)
|
||||
if (limitToday) {
|
||||
qb.where('published_at', '<=', (new Date()).toISOString())
|
||||
}
|
||||
})
|
||||
.fetchPage({
|
||||
pageSize: ctx.state.pagination.perPage,
|
||||
page: ctx.state.pagination.page,
|
||||
withRelated,
|
||||
ctx: ctx,
|
||||
})
|
||||
.then(result => {
|
||||
ctx.state.pagination.total = result.pagination.rowCount
|
||||
return result
|
||||
})
|
||||
},
|
||||
|
||||
getSingle(id, withRelated = [], require = true, ctx = null, limitToday = false) {
|
||||
return this.query(qb => {
|
||||
qb.where(subq => {
|
||||
subq.where({ id: Number(id) || 0 })
|
||||
.orWhere({ path: id })
|
||||
})
|
||||
if (limitToday && (!ctx || !ctx.state.user || ctx.state.user.level < 10)) {
|
||||
qb.where('published_at', '<=', (new Date()).toISOString())
|
||||
}
|
||||
})
|
||||
.fetch({ require, withRelated, ctx })
|
||||
},
|
||||
|
||||
async getFeatured(withRelated = [], ctx = null) {
|
||||
let data = await this.query(qb => {
|
||||
qb.where({ is_featured: true })
|
||||
.where('published_at', '<=', (new Date()).toISOString())
|
||||
})
|
||||
.fetch({ require: false, withRelated, ctx })
|
||||
if (!data) {
|
||||
data = await this.query(qb => {
|
||||
qb.where('published_at', '<=', (new Date()).toISOString())
|
||||
.whereNotNull('banner_id')
|
||||
})
|
||||
.fetch({ require: false, withRelated, ctx })
|
||||
}
|
||||
return data
|
||||
},
|
||||
|
||||
getAllFromPage(ctx, pageId, withRelated = [], orderBy = 'id', limitToday = false) {
|
||||
return this.query(qb => {
|
||||
this.baseQueryAll(ctx, qb, {}, orderBy)
|
||||
qb.leftOuterJoin('pages', 'articles.parent_id', 'pages.id')
|
||||
qb.where(subq => {
|
||||
subq.where('pages.id', pageId)
|
||||
.orWhere('pages.parent_id', pageId)
|
||||
})
|
||||
if (limitToday) {
|
||||
qb.where('published_at', '<=', (new Date()).toISOString())
|
||||
}
|
||||
qb.select('articles.*')
|
||||
})
|
||||
.fetchPage({
|
||||
pageSize: ctx.state.pagination.perPage,
|
||||
page: ctx.state.pagination.page,
|
||||
withRelated,
|
||||
ctx: ctx,
|
||||
})
|
||||
.then(result => {
|
||||
ctx.state.pagination.total = result.pagination.rowCount
|
||||
return result
|
||||
})
|
||||
},
|
||||
|
||||
setAllUnfeatured() {
|
||||
return bookshelf.knex('articles')
|
||||
.where({ is_featured: true })
|
||||
.update({
|
||||
is_featured: false,
|
||||
})
|
||||
},
|
||||
|
||||
getFrontpageArticles(page = 1) {
|
||||
return this.query(qb => {
|
||||
qb.orderBy('published_at', 'DESC')
|
||||
.where('published_at', '<=', (new Date()).toISOString())
|
||||
})
|
||||
.fetchPage({
|
||||
pageSize: 10,
|
||||
page: page,
|
||||
withRelated: ['files', 'media', 'banner', 'parent', 'staff'],
|
||||
})
|
||||
},*/
|
||||
})
|
||||
|
||||
const articleInstance = new Article()
|
||||
|
|
|
@ -46,45 +46,44 @@ nconf.env({
|
|||
})
|
||||
|
||||
|
||||
// Load package.json for name and such
|
||||
let pckg = JSON.parse(readFileSync('./package.json'))
|
||||
// Load empty overrides that can be overwritten later
|
||||
nconf.overrides({})
|
||||
|
||||
pckg = _.pick(pckg, ['name', 'version', 'description', 'author', 'license', 'homepage'])
|
||||
|
||||
if (nconf.get('DATABASE_URL')) {
|
||||
pckg.knex = { connection: nconf.get('DATABASE_URL') }
|
||||
}
|
||||
|
||||
// Load overrides as second priority
|
||||
nconf.overrides(pckg)
|
||||
|
||||
|
||||
// Load any overrides from the appropriate config file
|
||||
let configFile = 'config/config.json'
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (nconf.get('NODE_ENV') === 'test') {
|
||||
configFile = 'config/config.test.json'
|
||||
}
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (nconf.get('NODE_ENV') === 'production') {
|
||||
configFile = 'config/config.production.json'
|
||||
}
|
||||
|
||||
nconf.file('main', configFile)
|
||||
|
||||
// Load defaults
|
||||
nconf.file('default', 'config/config.default.json')
|
||||
|
||||
|
||||
// Final sanity checks
|
||||
/* istanbul ignore if */
|
||||
if (typeof global.it === 'function' & !nconf.inTest()) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Critical: potentially running test on production enviroment. Shutting down.')
|
||||
process.exit(1)
|
||||
}
|
||||
nconf.defaults({
|
||||
"NODE_ENV": "development",
|
||||
"knex": {
|
||||
"client": "pg",
|
||||
"connection": {
|
||||
"host" : "127.0.0.1",
|
||||
"user" : "postgres",
|
||||
"password" : "postgres",
|
||||
"database" : "nfpmoe"
|
||||
},
|
||||
"connectionslave": null,
|
||||
"migrations": {
|
||||
},
|
||||
"acquireConnectionTimeout": 10000
|
||||
},
|
||||
"frontend": {
|
||||
"url": "http://beta01.nfp.moe"
|
||||
},
|
||||
"jwt": {
|
||||
"secret": "this-is-my-secret",
|
||||
"options": {
|
||||
"expiresIn": 604800
|
||||
}
|
||||
},
|
||||
"sessionsecret": "this-is-session-secret-lol",
|
||||
"bcrypt": 5,
|
||||
"fileSize": 524288000,
|
||||
"upload": {
|
||||
"baseurl": "https://cdn.nfp.is",
|
||||
"port": "2111",
|
||||
"host": "storage01.nfp.is",
|
||||
"name": "nfpmoe-dev",
|
||||
"secret": "nfpmoe-dev"
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
export default nconf
|
||||
|
|
15
api/knex.mjs
15
api/knex.mjs
|
@ -3,7 +3,6 @@ import knexCore from 'knex-core'
|
|||
|
||||
import config from './config.mjs'
|
||||
import defaults from './defaults.mjs'
|
||||
import log from './log.mjs'
|
||||
|
||||
const knex = knexCore(config.get('knex'))
|
||||
|
||||
|
@ -73,14 +72,24 @@ export function createPrototype(opts) {
|
|||
},
|
||||
|
||||
async getAllQuery(query, queryContext = null) {
|
||||
console.log('1')
|
||||
let context = (queryContext || query).queryContext()
|
||||
if (!context.tables) throw new Error('getAll was called before query')
|
||||
let tables = context.tables
|
||||
let tableMap = new Map(tables)
|
||||
|
||||
let data = await query
|
||||
try {
|
||||
console.log(query)
|
||||
console.log(query.toString())
|
||||
let data = await query
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
throw err
|
||||
}
|
||||
console.log('3')
|
||||
|
||||
if (data.length === 0) {
|
||||
console.log('e1')
|
||||
return data
|
||||
}
|
||||
|
||||
|
@ -176,6 +185,8 @@ export function createPrototype(opts) {
|
|||
}
|
||||
}
|
||||
|
||||
console.log('2')
|
||||
|
||||
return out
|
||||
},
|
||||
|
||||
|
|
28
api/log.mjs
28
api/log.mjs
|
@ -1,28 +0,0 @@
|
|||
import bunyan from 'bunyan-lite'
|
||||
import config from './config.mjs'
|
||||
import * as defaults from './defaults.mjs'
|
||||
|
||||
// Clone the settings as we will be touching
|
||||
// on them slightly.
|
||||
let settings = defaults.default(config.get('bunyan'))
|
||||
|
||||
// Replace any instance of 'process.stdout' with the
|
||||
// actual reference to the process.stdout.
|
||||
for (let i = 0; i < settings.streams.length; i++) {
|
||||
/* istanbul ignore else */
|
||||
if (settings.streams[i].stream === 'process.stdout') {
|
||||
settings.streams[i].stream = process.stdout
|
||||
}
|
||||
}
|
||||
|
||||
// Create our logger.
|
||||
const log = bunyan.createLogger(settings)
|
||||
|
||||
export default log
|
||||
|
||||
log.logMiddleware = () =>
|
||||
(ctx, next) => {
|
||||
ctx.log = log
|
||||
|
||||
return next()
|
||||
}
|
|
@ -25,7 +25,7 @@ export default class PageRoutes {
|
|||
async getSinglePage(ctx) {
|
||||
await this.security.ensureIncludes(ctx)
|
||||
|
||||
ctx.body = await this.Page.getSingle(ctx.params.id, ctx.state.filter.includes, true, ctx)
|
||||
ctx.body = await this.Page.getSingle(ctx.params.pageId, ctx.state.filter.includes, true, ctx)
|
||||
}
|
||||
|
||||
/** POST: /api/pages */
|
||||
|
|
|
@ -11,11 +11,9 @@ export default class ParserMiddleware {
|
|||
}
|
||||
|
||||
contextParser() {
|
||||
return (ctx, next) => {
|
||||
return (ctx) => {
|
||||
ctx.state.pagination = this.pagination.parsePagination(ctx)
|
||||
ctx.state.filter = this.pagination.parseFilter(ctx)
|
||||
|
||||
return next()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
import path from 'path'
|
||||
import fs from 'fs/promises'
|
||||
import { Flaska, FileResponse, HttpError } from 'flaska'
|
||||
import { Flaska, FileResponse, HttpError, QueryHandler } from 'flaska'
|
||||
|
||||
import config from './config.mjs'
|
||||
import PageRoutes from './page/routes.mjs'
|
||||
import ArticleRoutes from './article/routes.mjs'
|
||||
import ParserMiddleware from './parser/middleware.mjs'
|
||||
|
||||
export function run(http, port, core) {
|
||||
let localUtil = new core.sc.Util(import.meta.url)
|
||||
|
@ -8,11 +13,29 @@ export function run(http, port, core) {
|
|||
|
||||
const flaska = new Flaska({
|
||||
log: core.log,
|
||||
nonce: ['script-src'],
|
||||
nonceCacheLength: 50,
|
||||
defaultHeaders: {
|
||||
'Server': 'Flaska',
|
||||
'X-Content-Type-Options': 'nosniff',
|
||||
'Content-Security-Policy': `default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * data: blob:; object-src 'none'; frame-ancestors 'none'; script-src 'self'`,
|
||||
'Cross-Origin-Opener-Policy': 'same-origin',
|
||||
'Cross-Origin-Resource-Policy': 'same-origin',
|
||||
'Cross-Origin-Embedder-Policy': 'require-corp',
|
||||
},
|
||||
}, http)
|
||||
|
||||
if (config.get('NODE_ENV') === 'development') {
|
||||
flaska.devMode()
|
||||
}
|
||||
|
||||
const parser = new ParserMiddleware()
|
||||
|
||||
flaska.before(function(ctx) {
|
||||
ctx.state.started = new Date().getTime()
|
||||
})
|
||||
flaska.before(QueryHandler())
|
||||
flaska.before(parser.contextParser())
|
||||
|
||||
flaska.after(function(ctx) {
|
||||
let ended = new Date().getTime()
|
||||
|
@ -33,6 +56,16 @@ export function run(http, port, core) {
|
|||
status: ctx.status,
|
||||
}, `<-- ${status}${ctx.method} ${ctx.url}`)
|
||||
})
|
||||
|
||||
const page = new PageRoutes()
|
||||
flaska.get('/api/pagetree', page.getPageTree.bind(page))
|
||||
flaska.get('/api/pages', page.getAllPages.bind(page))
|
||||
flaska.get('/api/pages/:pageId', page.getSinglePage.bind(page))
|
||||
|
||||
const article = new ArticleRoutes()
|
||||
flaska.get('/api/articles/public', article.getPublicAllArticles.bind(article))
|
||||
flaska.get('/api/articles/public/:id', article.getPublicSingleArticle.bind(article))
|
||||
flaska.get('/api/pages/:pageId/articles/public', article.getPublicAllPageArticles.bind(article))
|
||||
|
||||
flaska.get('/::file', function(ctx) {
|
||||
if (ctx.params.file.startsWith('api/')) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { createPrototype, safeColumns } from '../knex.mjs'
|
||||
import bcrypt from 'bcrypt'
|
||||
// import bcrypt from 'bcrypt'
|
||||
/*import config from '../config.mjs'*/
|
||||
|
||||
/* Staff model:
|
||||
|
|
11
db.json
11
db.json
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"core": {
|
||||
"version": 1,
|
||||
"nfp_moe": {
|
||||
"active": "static",
|
||||
"latestInstalled": "",
|
||||
"updater": "",
|
||||
"versions": []
|
||||
}
|
||||
}
|
||||
}
|
20
dev.mjs
20
dev.mjs
|
@ -1,10 +1,22 @@
|
|||
import fs from 'fs'
|
||||
import { ServiceCore } from 'service-core'
|
||||
import * as index from './index.mjs'
|
||||
|
||||
var core = new ServiceCore('nfp_moe', import.meta.url)
|
||||
core.setConfig({
|
||||
port: 4030,
|
||||
})
|
||||
var core = new ServiceCore('nfp_moe', import.meta.url, 4030, '')
|
||||
|
||||
let config = {
|
||||
frontend: {
|
||||
url: 'http://localhost:4030'
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
config = JSON.parse(fs.readFileSync('./config.json'))
|
||||
} catch {}
|
||||
|
||||
config.port = 4030
|
||||
|
||||
core.setConfig(config)
|
||||
core.init(index).then(function() {
|
||||
return core.run()
|
||||
})
|
|
@ -1,7 +1,12 @@
|
|||
import { run } from "./api/server_flaska.mjs"
|
||||
import config from './api/config.mjs'
|
||||
|
||||
export function start(http, port, ctx) {
|
||||
return run(http, port, ctx)
|
||||
config.stores.overrides.store = ctx.config
|
||||
|
||||
return import('./api/server_flaska.mjs')
|
||||
.then(function(server) {
|
||||
return server.run(http, port, ctx)
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
"scripts": {
|
||||
"start": "node --experimental-modules index.mjs",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "asbundle app/index.js public/assets/app.js && asbundle app/admin.js public/assets/admin.js",
|
||||
"bla": "sass --help",
|
||||
"build:prod": "sass -s compressed app/app.scss public/assets/app.css && sass -s compressed app/admin.scss public/assets/admin.css && asbundle app/index.js public/assets/app.js && asbundle app/admin.js public/assets/admin.js",
|
||||
"build": "sass app/app.scss public/assets/app.css && sass app/admin.scss public/assets/admin.css && asbundle app/index.js public/assets/app.js && asbundle app/admin.js public/assets/admin.js",
|
||||
"build:watch": "npm-watch build",
|
||||
"dev:server": "node dev.mjs | bunyan",
|
||||
"dev:server:watch": "npm-watch dev:server",
|
||||
|
|
Loading…
Reference in a new issue