@leansdk/leanrc
Version:
LeanRC is a MVC framework for creating graceful applications
245 lines (224 loc) • 8.72 kB
text/coffeescript
# This file is part of LeanRC.
#
# LeanRC is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# LeanRC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with LeanRC. If not, see <https://www.gnu.org/licenses/>.
# accepts = require 'accepts'
# createError = require 'http-errors'
assert = require 'assert'
Stream = require 'stream'
###
Идеи взяты из https://github.com/koajs/koa/blob/master/lib/context.js
###
module.exports = (Module)->
{
DEVELOPMENT
AnyT, NilT
FuncG, UnionG, MaybeG
RequestInterface, ResponseInterface, SwitchInterface, CookiesInterface
ContextInterface
CoreObject
Request, Response, Cookies
Utils: { _, statuses }
} = Module::
class Context extends CoreObject
ContextInterface
Module
req: Object # native request object
res: Object # native response object
request: MaybeG RequestInterface
response: MaybeG ResponseInterface
cookies: MaybeG CookiesInterface
accept: Object
state: MaybeG Object
switch: SwitchInterface
respond: MaybeG Boolean
routePath: MaybeG String
pathParams: MaybeG Object
transaction: MaybeG Object
session: MaybeG Object
# database: String # возможно это тоже надо получать из метода из отдельного модуля
throw: FuncG([UnionG(String, Number), MaybeG(String), MaybeG Object]),
default: (args...)->
createError = require 'http-errors'
throw createError args...
assert: FuncG([AnyT, MaybeG(UnionG String, Number), MaybeG(String), MaybeG Object]),
default: assert
onerror: FuncG([MaybeG AnyT]),
default: (err)->
return unless err?
unless _.isError err
err = new Error "non-error thrown: #{err}"
headerSent = no
if or not
headerSent = err.headerSent = yes
.getViewComponent().emit 'error', err, @
return if headerSent
{res} = @
if _.isFunction res.getHeaderNames
res.getHeaderNames().forEach (name)-> res.removeHeader name
if (vlHeaderNames = Object.keys res.headers ? {}).length > 0
vlHeaderNames.forEach (name)-> res.removeHeader name
err.headers ? {}
= 'text'
err.status = 404 if 'ENOENT' is err.code
err.status = 500 if not _.isNumber(err.status) or not statuses[err.status]
code = statuses[err.status]
msg = if err.expose
err.message
else
code
message =
error: yes
errorNum: err.status
errorMessage: msg
code: err.code ? code
if .configs.environment is DEVELOPMENT
message.exception = "#{err.name ? 'Error'}: #{msg}"
message.stacktrace = err.stack.split '\n'
= err.status
message = JSON.stringify message
= Buffer.byteLength message
.end message
return
# Request aliases
header: Object,
get: -> .header
headers: Object,
get: -> .headers
method: String,
get: -> .method
set: (method)-> .method = method
url: String,
get: -> .url
set: (url)-> .url = url
originalUrl: String
origin: String,
get: -> .origin
href: String,
get: -> .href
path: String,
get: -> .path
set: (path)-> .path = path
query: Object,
get: -> .query
set: (query)-> .query = query
querystring: String,
get: -> .querystring
set: (querystring)-> .querystring = querystring
host: String,
get: -> .host
hostname: String,
get: -> .hostname
fresh: Boolean,
get: -> .fresh
stale: Boolean,
get: -> .stale
socket: Object,
get: -> .socket
protocol: String,
get: -> .protocol
secure: Boolean,
get: -> .secure
ip: String,
get: -> .ip
ips: Array,
get: -> .ips
subdomains: Array,
get: -> .subdomains
'is': FuncG([UnionG String, Array], UnionG String, Boolean, NilT),
default: (args...)-> .is args...
accepts: FuncG([MaybeG UnionG String, Array], UnionG String, Array, Boolean),
default: (args...)-> .accepts args...
acceptsEncodings: FuncG([MaybeG UnionG String, Array], UnionG String, Array),
default: (args...)-> .acceptsEncodings args...
acceptsCharsets: FuncG([MaybeG UnionG String, Array], UnionG String, Array),
default: (args...)-> .acceptsCharsets args...
acceptsLanguages: FuncG([MaybeG UnionG String, Array], UnionG String, Array),
default: (args...)-> .acceptsLanguages args...
get: FuncG(String, String),
default: (args...)-> .get args...
# Response aliases
body: MaybeG(UnionG String, Buffer, Object, Array, Number, Boolean, Stream),
get: -> .body
set: (body)-> .body = body
status: MaybeG(Number),
get: -> .status
set: (status)-> .status = status
message: String,
get: -> .message
set: (message)-> .message = message
length: Number,
get: -> .length
set: (length)-> .length = length
writable: Boolean,
get: -> .writable
type: MaybeG(String),
get: -> .type
set: (type)-> .type = type
headerSent: MaybeG(Boolean),
get: -> .headerSent
redirect: FuncG([String, MaybeG String]),
default: (args...)-> .redirect args...
attachment: FuncG(String),
default: (args...)-> .attachment args...
set: FuncG([UnionG(String, Object), MaybeG AnyT]),
default: (args...)-> .set args...
append: FuncG([String, UnionG String, Array]),
default: (args...)-> .append args...
vary: FuncG(String),
default: (args...)-> .vary args...
flushHeaders: Function,
default: (args...)-> .flushHeaders args...
remove: FuncG(String),
default: (args...)-> .remove args...
lastModified: MaybeG(Date),
set: (date)-> .lastModified = date
etag: String,
set: (etag)-> .etag = etag
# toJSON: Function,
# default: ->
# # request: .toJSON()
# # response: .toJSON()
# # app: .constructor.NAME
# originalUrl:
# req: '<original req>'
# res: '<original res>'
# socket: '<original node socket or undefined>'
# inspect: Function,
# default: ->
restoreObject: Function,
default: ->
throw new Error "restoreObject method not supported for #{@name}"
yield return
replicateObject: Function,
default: ->
throw new Error "replicateObject method not supported for #{@name}"
yield return
init: FuncG([Object, Object, SwitchInterface]),
default: (req, res, switchInstanse)->
accepts = require 'accepts'
= req
= res
= switchInstanse
= req.url
= accepts req
= Request.new(@)
= Response.new(@)
key = .configs.cookieKey
secure = req.secure
= Cookies.new req, res, {key, secure}
= {}
return