diff --git a/package.json b/package.json index cd2b4573..47f2ec6f 100644 --- a/package.json +++ b/package.json @@ -22,15 +22,17 @@ "babel-preset-stage-0": "^6.5.0", "co": "^4.4.0", "instagram-node": "^0.5.1", - "koa-bodyparser": "^2.0.1", + "koa": "^2.0.0-alpha.3", + "koa-bodyparser": "^3.0.0", + "koa-compose": "^3.1.0", "koa-conditional-get": "^1.0.2", + "koa-convert": "^1.2.0", "koa-etag": "^2.0.0", "koa-helmet": "^1.0.0", "koa-logger": "^1.2.2", "koa-prerender": "^1.0.3", - "koa-route": "^2.4.0", + "koa-route": "^3.1.0", "koa-static": "^2.0.0", - "koa": "^1.2.0", "mz": "^2.3.1", "promised-mongo": "git+https://git@github.com/tmshv/promised-mongo", "sitemap": "^1.5.0", diff --git a/src/core/collective.js b/src/core/collective.js index f103d8d4..f8ff67de 100644 --- a/src/core/collective.js +++ b/src/core/collective.js @@ -1,7 +1,7 @@ import {c} from '../core/db'; -export function* getCollective(query={}, show={}) { - let data = yield c('collective').find(query, show); +export async function getCollective(query={}, show={}) { + let data = await c('collective').find(query, show); if (!data) { return null; } diff --git a/src/core/schedule.js b/src/core/schedule.js index 9bad62c9..ca8dbae8 100644 --- a/src/core/schedule.js +++ b/src/core/schedule.js @@ -6,8 +6,8 @@ import {populate, scheduleDate} from '../models/schedule'; import {shortifyName} from '../models/collective'; import {courses} from '../models/course'; -export function* getSchedule(period, semester) { - let data = yield c('schedules').findOne({ +export async function getSchedule(period, semester) { + let data = await c('schedules').findOne({ period: period, semester: semester }); @@ -15,8 +15,8 @@ export function* getSchedule(period, semester) { return null; } -export function* getScheduleList() { - let list = yield c('schedules') +export async function getScheduleList() { + let list = await c('schedules') .find({}, {period: 1, semester: 1}) .toArray(); return list @@ -28,8 +28,8 @@ export function* getScheduleList() { }); } -export function* populateSchedule(schedule) { - let collective = yield getCollective({}, {id: 1, name: 1}); +export async function populateSchedule(schedule) { + let collective = await getCollective({}, {id: 1, name: 1}); let collective_dict = collective.reduce((dict, i) => { dict[i.id] = i.name; return dict; diff --git a/src/middlewares/ensureServiceAuth.js b/src/middlewares/ensureServiceAuth.js new file mode 100644 index 00000000..e83a83c8 --- /dev/null +++ b/src/middlewares/ensureServiceAuth.js @@ -0,0 +1,14 @@ +import {checkAuth} from '../core/service'; + +export function ensureServiceAuth() { + return async (ctx, next) => { + let service = ctx.request.headers['x-service-name']; + let token = ctx.request.headers['x-service-token']; + + if (!checkAuth(service, token)) { + ctx.status = 401; + } else { + await next(); + } + }; +} diff --git a/src/routes/404.js b/src/routes/404.js index 8f706ce0..bddf1507 100644 --- a/src/routes/404.js +++ b/src/routes/404.js @@ -1,26 +1,26 @@ import {index, accepts} from './'; export default function () { - return function *(next) { - yield next; + return async(ctx) => { + if (ctx.status != 404) return; - if (404 != this.status) return; + ctx.status = 404; + ctx.body = 'lol found'; - this.status = 404; - yield accepts({ + await accepts({ 'text/html': index(), - - 'text/plain': function *() { - this.type = 'text/plain'; - this.body = 'Page not found'; + 'text/plain': async ctx => { + ctx.type = 'text/plain'; + ctx.body = 'Page not found'; }, - 'application/json': function *() { - this.type = 'application/json'; - this.body = { + 'application/json': async ctx => { + ctx.type = 'application/json'; + ctx.body = { + error: 404, message: 'Not Found' }; } - }); + })(ctx); }; }; \ No newline at end of file diff --git a/src/routes/api/feed.js b/src/routes/api/feed.js new file mode 100644 index 00000000..9e9839a5 --- /dev/null +++ b/src/routes/api/feed.js @@ -0,0 +1,15 @@ +import {put} from 'koa-route'; +import compose from 'koa-compose'; +import {ensureServiceAuth} from '../../middlewares/ensureServiceAuth'; + +export function add() { + return put('/api/v1/feed', compose([ + ensureServiceAuth(), + async ctx => { + let post = ctx.body; + ctx.body = { + pong: post + }; + } + ])); +} diff --git a/src/routes/api/index.js b/src/routes/api/index.js new file mode 100644 index 00000000..0a031397 --- /dev/null +++ b/src/routes/api/index.js @@ -0,0 +1,8 @@ +import {add as feedAdd} from './feed'; +import compose from 'koa-compose'; + +export default function () { + return compose([ + feedAdd() + ]); +}; diff --git a/src/routes/articles.js b/src/routes/articles.js index 48880d8d..0af181b1 100644 --- a/src/routes/articles.js +++ b/src/routes/articles.js @@ -1,38 +1,28 @@ import route from 'koa-route'; import {c} from '../core/db'; import {accepts, index} from './'; -import {sortBy} from '../utils/sort'; -export default function (app) { +async function exists(ctx, id) { + let i = await article(id); + return i ? true : false; +} - function* exists(id) { - let i = yield c('events').findOne({id: id}); - if (!i) { - i = yield c('timeline').findOne({id: id}); - } - return i ? true : false; +async function article(id){ + let i = await c('events').findOne({id: id}); + if (!i) { + i = await c('timeline').findOne({id: id}); } + return i; +} - app.use(route.get('/article/:id', accepts({ - //'text/html': function* (id){ - // let test = yield exists(id); - // if(test){ - // return yield index(); - // }else{ - // this.status = 404; - // return yield index(); - // } - //}, +export default function () { + return route.get('/article/:id', accepts({ 'text/html': index(exists), 'text/plain': index(exists), - 'application/json': function* (id) { - let i = yield c('events').findOne({id: id}); - if (!i) { - i = yield c('timeline').findOne({id: id}); - } - - if (!i) this.status = 404; - else this.body = i; + 'application/json': async (ctx, id) => { + let i = await article(id); + if (!i) ctx.status = 404; + else ctx.body = i; } - }))); + })) }; diff --git a/src/routes/documents.js b/src/routes/documents.js index c9094f26..b5de9a82 100644 --- a/src/routes/documents.js +++ b/src/routes/documents.js @@ -1,68 +1,73 @@ +import compose from 'koa-compose'; import route from 'koa-route'; import {index, json, accepts} from './'; import {c} from '../core/db'; -function* exists(id) { - let i = yield c('documents').findOne({id: id}); +async function exists(ctx, id) { + let i = await c('documents').findOne({id: id}); return i ? true : false; } -export default function (app) { - [ - [ - '/documents', - json(function *() { - let query = {}; - this.body = yield c('documents') - .find(query) - .toArray(); - }) - ], - [ - '/documents/type/:type', - function *(type) { - let types = { - 'document': ['documents', {type: 'document'}, populateDocPreview], - 'award': ['documents', {type: 'award'}, populateDocPreview] - }; - - if (type in types) { - let [collection, query, mapFn] = types[type]; - - let docs = yield c(collection) - .find(query) - .toArray(); - - if (mapFn) docs = yield docs.map(mapFn); - - this.body = docs; - } else { - this.status = 404; - } - } - ], - [ - '/documents/:id', - accepts({ - 'text/html': index(exists), - 'text/plain': index(exists), - 'application/json': function* (id) { - let i = yield c('documents').findOne({id: id}); - if (!i) this.status = 404; - else { - i = yield populateDocPreview(i); - this.body = i; - } - } - }) - ] - ].forEach(item => { - let [path, fn] = item; - app.use(route.get(path, fn)); - }); +export default function () { + return compose([ + documents(), + document(), + type() + ]); }; -function* populateDocPreview(doc) { - doc.preview = yield c('images').findOne({_id: doc.preview}); +function documents() { + return route.get('/documents', json( + async(ctx) => { + let query = {}; + ctx.body = await c('documents') + .find(query) + .toArray(); + } + )); +} + +function document() { + return route.get('/documents/:id', accepts({ + 'text/html': index(exists), + 'text/plain': index(exists), + 'application/json': async(ctx, id) => { + let i = await c('documents').findOne({id: id}); + if (!i) ctx.status = 404; + else { + i = await populateDocPreview(i); + ctx.body = i; + } + } + })); +} + +function type() { + return route.get('/documents/type/:type', async(ctx, type) => { + let types = { + 'document': ['documents', {type: 'document'}, populateDocPreview], + 'award': ['documents', {type: 'award'}, populateDocPreview] + }; + + if (type in types) { + let [collection, query, mapFn] = types[type]; + + let docs = await c(collection) + .find(query) + .toArray(); + + if (mapFn) docs = await Promise.all( + docs.map(mapFn) + ); + + ctx.body = docs; + } else { + ctx.status = 404; + } + }); +} + +async function populateDocPreview(doc) { + doc.preview = await c('images').findOne({_id: doc.preview}); return doc; } diff --git a/src/routes/events.js b/src/routes/events.js index a2dc83f4..9c350f21 100644 --- a/src/routes/events.js +++ b/src/routes/events.js @@ -3,34 +3,34 @@ import {c} from '../core/db'; import {json} from './'; import {sortBy} from '../utils/sort'; -export default function (app) { - let sortByDate = sortBy( - i => (new Date(i.date)) - .getTime() - ); +let sortByDate = sortBy( + i => (new Date(i.date)) + .getTime() +); - app.use(route.get('/events/:page?', json( - function *() { - let limit = parseInt(this.query['limit']) || 10; - let skip = parseInt(this.query['skip']) || 0; +export default function () { + return route.get('/events/:page?', json( + async(ctx) => { + let limit = parseInt(ctx.query['limit']) || 10; + let skip = parseInt(ctx.query['skip']) || 0; let query = {}; - let documents = yield c('events') + let documents = await c('events') .find(query) .sort({date: -1}) .skip(skip) .limit(limit) .toArray(); - let total = yield c('events') + let total = await c('events') .find(query).count(); - this.body = { + ctx.body = { skip: skip, limit: limit, total: total, data: documents }; } - ))); + )); }; diff --git a/src/routes/gallery.js b/src/routes/gallery.js index 261ee6d6..714e814b 100644 --- a/src/routes/gallery.js +++ b/src/routes/gallery.js @@ -1,33 +1,14 @@ import co from 'co'; +import compose from 'koa-compose'; import route from 'koa-route'; import {c} from '../core/db'; import {json} from './'; -export default function (app) { - app.use(route.get('/gallery', json( - function *() { - let query = {}; - let fields = ['_id', 'id', 'title', 'date']; - //.reduce((f, i) => { - // f[i] = 1; - // return f; - //}, {}); - - let albums = yield c('albums') - .find(query) - .toArray(); - - //albums = albums.map(i => { - // return fields.reduce((a, key)=> { - // a[key] = i[key]; - // return a; - // }, {}); - //}); - - albums = yield albums.map(processAlbum); - this.body = albums; - } - ))); +export default function () { + return compose([ + gallery(), + album() + ]); //app.use(route.get('/gallery/:year', json( // function *(year) { @@ -45,28 +26,46 @@ export default function (app) { // this.body = albums; // } //))); +}; - app.use(route.get('/album/:id', json( - function *(id) { - //year = parseInt(year); - //course = '/' + course; - //album = '/' + album; - //let start = new Date(year, 0, 1); - //let end = new Date(year, 11, 31); - //let query = { - // date: {$gte: start, $lt: end}, - // course_uri: course, - // uri: album - //}; +function gallery(){ + return route.get('/gallery', json( + async(ctx) => { + let query = {}; + let fields = ['_id', 'id', 'title', 'date']; + //.reduce((f, i) => { + // f[i] = 1; + // return f; + //}, {}); - let record = yield c('albums').findOne({ + let albums = await c('albums') + .find(query) + .toArray(); + + //albums = albums.map(i => { + // return fields.reduce((a, key)=> { + // a[key] = i[key]; + // return a; + // }, {}); + //}); + + albums = await Promise.all(albums.map(processAlbum)); + ctx.body = albums; + } + )); +} + +function album(){ + return route.get('/album/:id', json( + async(ctx, id) => { + let record = await c('albums').findOne({ id: id }); - record = yield processAlbum(record); - this.body = record; + record = await processAlbum(record); + ctx.body = record; } - ))); -}; + )); +} let processAlbum = album => co(function *() { //album.url = `/gallery/{year}{course}{album}` diff --git a/src/routes/index.js b/src/routes/index.js index 00cbacad..cf12a5fd 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -1,5 +1,6 @@ import fs from 'mz/fs'; import route from 'koa-route'; +import compose from 'koa-compose'; import {map, assign} from '../utils/common'; import config from '../config'; @@ -16,19 +17,19 @@ import articles from './articles'; let main = () => route.get('/', index()); -export function routes(app){ - app.use(main()); - - sitemap(app); - schedule(app); - news(app); - gallery(app); - documents(app); - events(app); - articles(app); - teachers(app); - - app.use(error404()); +export function routes(){ + return compose([ + main(), + sitemap(), + schedule(), + news(), + gallery(), + documents(), + teachers(), + events(), + articles(), + error404() + ]); } export function queryObject() { @@ -36,9 +37,9 @@ export function queryObject() { let toFalse = map(false, i => i === 'false'); const processors = [toTrue, toFalse]; - return function *(next) { - let query = this.query; - this.query = Object.keys(query) + return async (ctx, next) => { + let query = ctx.query; + ctx.query = Object.keys(query) .reduce((query, key) => assign( query, key, @@ -46,23 +47,22 @@ export function queryObject() { .reduce((value, fn) => fn(value), query[key]) ), query); - yield next; + await next(); } } -export function accepts(routes, def) { - return function *() { - let req = this.request; +export function accepts(routes) { + return async function (ctx) { + let request = ctx.request; let types = Object.keys(routes) - .filter(type => req.accepts(type)); + .filter(type => request.accepts(type)); if (types.length) { - let type = types[0]; - yield routes[type].apply(this, arguments); - } else if (def) { - yield def; + let fn = routes[types[0]]; + + await fn.apply(ctx, arguments); } else { - this.status = 406; + ctx.status = 406; } }; } @@ -70,21 +70,21 @@ export function accepts(routes, def) { export function index(fn) { let filename = config['defaultIndex']; - return function *() { + return async function (ctx){ let test = true; - if(fn) test = yield fn.apply(this, arguments); + if (fn) test = await fn.apply(ctx, arguments); - if(!test) { - this.status = 404; - } + if (!test) ctx.status = 404; - this.type = 'text/html'; - this.body = fs.createReadStream(filename); + ctx.type = 'text/html'; + ctx.body = fs.createReadStream(filename); } } -export const json = fn => accepts({ - 'text/html': index(), - 'text/plain': index(), - 'application/json': fn -}); +export function json(fn){ + return accepts({ + 'text/html': index(), + 'text/plain': index(), + 'application/json': fn + }); +} diff --git a/src/routes/news.js b/src/routes/news.js index 6315573d..3b8e31c3 100644 --- a/src/routes/news.js +++ b/src/routes/news.js @@ -1,32 +1,38 @@ +import compose from 'koa-compose'; import route from 'koa-route'; -import {accepts, index} from './'; +import {accepts} from './'; import {c} from '../core/db'; import {sortBy} from '../utils/sort'; -export default function (app) { - let sortNewsByDate = sortBy( - i => (new Date(i.date)) - .getTime() - ); +const sortNewsByDate = sortBy( + i => (new Date(i.date)) + .getTime() +); - app.use(route.get('/news', accepts({ - 'text/html': function *() { - this.redirect('/'); - }, - 'text/plain': function *() { - this.redirect('/'); - }, - 'application/json': function *() { - let limit = parseInt(this.query['limit']) || 10; - let skip = parseInt(this.query['skip']) || 0; +const redirect = async ctx => ctx.redirect('/'); + +export default function () { + return compose([ + news(), + pinned() + ]); +}; + +function news() { + return route.get('/news', accepts({ + 'text/html': redirect, + 'text/plain': redirect, + 'application/json': async ctx => { + let limit = parseInt(ctx.query['limit']) || 10; + let skip = parseInt(ctx.query['skip']) || 0; let query = {}; - if (this.query.type) query.type = this.query.type; + if (ctx.query.type) query.type = ctx.query.type; let pinned = []; if(skip == 0) { const now = new Date(); - pinned = yield c('timeline') + pinned = await c('timeline') .find({until: {$gte: now}}) .toArray() .then(i => i.sort(sortNewsByDate)); @@ -35,7 +41,7 @@ export default function (app) { let sid = id => id + ''; let pinnedIds = pinned.map(p => sid(p['_id'])); - let posts = yield c('timeline') + let posts = await c('timeline') .find(query) .sort({date: -1}) .skip(skip) @@ -45,23 +51,21 @@ export default function (app) { i => pinnedIds.indexOf(sid(i['_id'])) < 0 )); - this.body = pinned.concat(posts); + ctx.body = pinned.concat(posts); } - }))); + })); +} - app.use(route.get('/news/pinned', accepts({ - 'text/html': function *() { - this.redirect('/'); - }, - 'text/plain': function *() { - this.redirect('/'); - }, - 'application/json': function *() { +function pinned(){ + return route.get('/news/pinned', accepts({ + 'text/html': redirect, + 'text/plain': redirect, + 'application/json': async ctx => { let now = new Date(); - this.body = yield c('timeline') + ctx.body = await c('timeline') .find({until: {$gte: now}}) .toArray() .then(i => i.sort(sortNewsByDate)); } - }))); -}; + })); +} diff --git a/src/routes/schedule.js b/src/routes/schedule.js index d624a308..25ff01fa 100644 --- a/src/routes/schedule.js +++ b/src/routes/schedule.js @@ -1,38 +1,45 @@ +import compose from 'koa-compose'; +import co from 'co'; import route from 'koa-route'; import {json} from './'; import {getSchedule, getScheduleList, populateSchedule} from '../core/schedule'; -export default function (app) { - app.use( - route.get('/schedule/list', json( - function *() { - this.type = 'application/json'; - let data = yield getScheduleList(); - if (!data) this.status = 404; - else this.body = data; - } - )) - ); - - app.use( - route.get('/schedule/:period?/:semester?', json( - function *(period, semester) { - this.type = 'application/json'; - - let data = yield getSchedule(period, semester); - if (!data) { - this.status = 404; - return; - } - - let doPopulate = this.query.populate || false; - if (doPopulate) { - data.schedule = yield populateSchedule(data.schedule); - } - - this.body = data; - } - )) - ); +export default function () { + return compose([ + list(), + schedule() + ]); }; + +function list() { + return route.get('/schedule/list', json( + async(ctx) => { + ctx.type = 'application/json'; + let data = await getScheduleList(); + if (!data) ctx.status = 404; + else ctx.body = data; + } + )) +} + +function schedule() { + return route.get('/schedule/:period?/:semester?', json( + async(ctx, period, semester) => { + ctx.type = 'application/json'; + + let data = await getSchedule(period, semester); + if (!data) { + ctx.status = 404; + return; + } + + let doPopulate = ctx.query.populate || false; + if (doPopulate) { + data.schedule = await populateSchedule(data.schedule); + } + + ctx.body = data; + } + )) +} \ No newline at end of file diff --git a/src/routes/sitemap.js b/src/routes/sitemap.js index b30f5cbe..73d0916d 100644 --- a/src/routes/sitemap.js +++ b/src/routes/sitemap.js @@ -5,41 +5,39 @@ import {c} from '../core/db'; import {homeUrl, sitemapCacheTime} from '../config'; import menu from '../models/menu'; -export default function (app) { - app.use(route.get('/sitemap.xml', function *() { - let urls = yield [ +export default function () { + return route.get('/sitemap.xml', async ctx => { + let urls = await Promise.all([ getMenuUrls(), getGalleryUrls(), getTeacherUrls(), getEventsUrls(), getNewsUrls() - ]; + ]); urls = urls.reduce((urls, i) => urls.concat(i)); - let sm = sitemap.createSitemap({ + let map = sitemap.createSitemap({ hostname: homeUrl, cacheTime: sitemapCacheTime, urls: urls }); - this.set('Content-Type', 'application/xml'); - this.body = yield new Promise(resolve => sm.toXML(resolve)); - })); + ctx.set('Content-Type', 'application/xml'); + ctx.body = map.toString(); + }) }; -function *getMenuUrls() { +async function getMenuUrls(frequency='daily') { return menu .filter(i => 'url' in i) - .map(function (item) { - return { - url: item.url, - changefreq: 'daily' - } - }); + .map(i => ({ + url: i.url, + changefreq: frequency + })); } -function *getGalleryUrls() { - let docs = yield c('albums') +async function getGalleryUrls() { + let docs = await c('albums') .find({}) .toArray(); @@ -51,8 +49,8 @@ function *getGalleryUrls() { }); } -function *getTeacherUrls() { - let docs = yield c('collective') +async function getTeacherUrls() { + let docs = await c('collective') .find({}) .toArray(); @@ -64,8 +62,8 @@ function *getTeacherUrls() { }); } -function *getEventsUrls() { - let docs = yield c('events') +async function getEventsUrls() { + let docs = await c('events') .find({}) .toArray(); @@ -77,8 +75,8 @@ function *getEventsUrls() { }); } -function *getNewsUrls() { - let docs = yield c('timeline') +async function getNewsUrls() { + let docs = await c('timeline') .find({type: 'post'}) .toArray(); diff --git a/src/routes/teachers.js b/src/routes/teachers.js index 97668a3f..8cfac548 100644 --- a/src/routes/teachers.js +++ b/src/routes/teachers.js @@ -1,4 +1,5 @@ import co from 'co'; +import compose from 'koa-compose'; import route from 'koa-route'; import {index, json} from './'; import {sortByPattern} from '../utils/sort'; @@ -7,42 +8,55 @@ import {c} from '../core/db'; let split = d => s => s.split(d); let toArray = split(','); -export default function (app) { - app.use(route.get('/collective', index())); - - app.use(route.get('/teacher/list', json( - function *() { - this.type = 'application/json'; - let pattern = toArray(this.query.sort || ''); - - let data = yield c('collective').find(); - if (!data) { - this.status = 404; - return; - } - - let collective = yield data - .map(processProfile); - - this.body = sortByPattern(collective, pattern, i => i.id); - } - ))); - - app.use(route.get('/teacher/:id', json( - function *(id) { - this.type = 'application/json'; - - let data = yield c('collective').findOne({id: id}); - if (!data) { - this.status = 404; - return; - } - - this.body = yield processProfile(data); - } - ))) +export default function () { + return compose([ + collective(), + list(), + teacher() + ]); }; +function collective() { + return route.get('/collective', index()); +} + +function list() { + return route.get('/teacher/list', json( + async(ctx) => { + ctx.type = 'application/json'; + let pattern = toArray(ctx.query.sort || ''); + + let data = await c('collective').find(); + if (!data) { + ctx.status = 404; + return; + } + + let collective = await Promise.all( + data.map(processProfile) + ); + + ctx.body = sortByPattern(collective, pattern, i => i.id); + } + )); +} + +function teacher() { + return route.get('/teacher/:id', json( + async (ctx, id) => { + ctx.type = 'application/json'; + + let data = await c('collective').findOne({id: id}); + if (!data) { + ctx.status = 404; + return; + } + + ctx.body = await processProfile(data); + } + )) +} + let processProfile = profile => co(function *() { let imageId = profile.picture; profile.picture = yield c('images').findOne({_id: imageId}); diff --git a/src/server.js b/src/server.js index 490324ec..1acbfb63 100644 --- a/src/server.js +++ b/src/server.js @@ -1,7 +1,8 @@ import path from 'path'; -import koa from 'koa'; +import Koa from 'koa'; import serve from 'koa-static'; import logger from 'koa-logger'; +import convert from 'koa-convert'; import conditional from 'koa-conditional-get'; import etag from 'koa-etag'; import prerender from 'koa-prerender'; @@ -11,40 +12,42 @@ import bodyParser from 'koa-bodyparser'; import config from './config'; import {redirectionTable} from './config'; import {routes, queryObject} from './routes'; -// import api from './routes/api'; +import api from './routes/api'; import {redirect} from './routes/redirect'; const dirPublic = path.join(__dirname, '../public'); const dirTemplates = path.join(__dirname, 'templates'); export function server(){ - const app = koa(); + const $ = convert; + + const app = new Koa(); app.proxy = true; app.use(bodyParser()); - app.use(logger()); - // api(app); - app.use(conditional()); - app.use(etag()); + app.use($(logger())); + app.use(api()); + app.use($(conditional())); + app.use($(etag())); app.use(prerenderRmFragment()); - app.use(prerender(config.prerender)); - app.use(serve(dirPublic)); - app.use(serve(dirTemplates)); - app.use(redirect(redirectionTable)); - app.use(helmet()); + app.use($(prerender(config.prerender))); + app.use($(serve(dirPublic))); + app.use($(serve(dirTemplates))); + app.use($(redirect(redirectionTable))); + app.use($(helmet())); app.use(queryObject()); - routes(app); + app.use(routes()); return app; } function prerenderRmFragment(){ - return function *(next) { - yield* next; + return async (ctx, next) => { + await next(); try { - let xp = this.response.header['x-prerender'] == 'true'; - if (xp) this.body = this.body.replace('', ''); + let xp = ctx.response.header['x-prerender'] == 'true'; + if (xp) ctx.body = ctx.body.replace('', ''); } catch (e) { } }