UNPKG

5.11 kBPlain TextView Raw
1require! \prelude-ls : {each, unchars}
2_ = require 'underscore'
3N = null
4Request = require './Request'
5require! {\../Helpers/Debug}
6express = require \express
7Client = require '../../test/common/client'
8http = require 'http'
9body-parser = require \body-parser
10express-session = require 'express-session'
11
12debug = new Debug "N::Route", Debug.colors.purple
13
14class Route
15
16 basePath: '/api/'
17 apiVersion: 1
18 rname: ''
19
20 (resource, @config) ->
21
22 @resource = resource || @resource
23
24 N := require '../..' if not N?
25
26 if @resource
27 if typeof(@resource) is 'function'
28 @rname = @resource.lname
29 else if typeof(@resource) is 'string'
30 @rname = @resource
31 @resource = undefined
32 N.Config() if not N.config?
33 else
34 throw new Error 'Route needs a Resource (or at least a name)'
35
36 @debug = new Debug "N::Route::#{@rname}", Debug.colors.purple
37
38 N.Config!
39 if N.consoleMode
40 return
41
42 if not N.app?
43 N.Route._InitServer!
44
45 @app = N.app
46
47 @name = @rname + 's'
48
49 if @rname[*-1] is 'y'
50 @name = @rname[til @name.length - 2]*'' + 'ies'
51
52 @Config()
53
54 @_InitServer = ->
55 N := require '../..' if not N?
56
57 if N.app?
58 debug.Log 'Server already started.'
59 return
60
61 N.express = express
62
63 N.app = express!
64
65 N.app.use bodyParser.urlencoded extended: true
66
67 N.app.use bodyParser.json extended: true
68
69 sessions =
70 key: \N
71 secret: \N
72 resave: true
73 saveUninitialized: true
74
75 if N.config?.store?.type is \redis
76 RedisStore = require(\connect-redis)(express-session)
77
78 N.sessionStore = new RedisStore do
79 host: N.config.store.host || \localhost
80
81 sessions.store = N.sessionStore
82
83 N.app.use express-session sessions
84
85 debug.Log 'Creating server'
86
87 N.server = http.createServer N.app
88
89 N.client = new Client N.app
90
91
92 N.server.listen N.config?.port || 3000
93
94 N.bus.emit \listening
95
96 debug.Log "Listening to 0.0.0.0: #{(N.config?.port || 3000)}"
97
98 _WrapRequest: (fName, args) ->
99 Req = new Request args
100 try
101 ret = @[fName] Req
102 if ret?
103 switch
104 | ret._promise? =>
105 ret
106 .Then -> Req.Send it
107 .Catch -> Req.SendError it
108 | _ => Req.Send ret
109 else if ret is null => Req.Send null
110 catch e
111 Req.SendError e
112
113 _Add: (type, url, ...middle, done) ->
114 if not done?
115 done = url
116 url = switch type
117 | \all => \*
118 | _ => \/
119
120 if not middle.length and typeof(url) is 'function'
121 middle.push url
122 url = switch type
123 | \all => \*
124 | _ => \/
125
126 @debug.Log "Declaring Route: #{type} => #{url} "
127
128 if not @[type + url]?
129 @[type + url] = done
130
131 #FIXME: code clarity
132 if middle.length
133 middle.push (...args) ~>
134 @debug.Log "Request on: #{type} => #{url} "
135 @_WrapRequest type + url, args
136 @app.route(@basePath + @apiVersion + '/' + @name + url)[type].apply @app.route(@basePath + @apiVersion + '/' + @name + url), middle
137 else
138 @app.route(@basePath + @apiVersion + '/' + @name + url)[type] (...args) ~>
139 @debug.Log "Request on: #{type} => #{url} "
140 @_WrapRequest type + url, args
141
142 else
143 @[type + url] = done
144
145 Config: ->
146
147 @Extend = ->
148 class ExtendedRoute extends @
149
150_set = (verb) ~>
151 Route::[verb] = (...args) ->
152 args.unshift verb[0].toLowerCase() + verb[1 til verb.length]*''
153 @_Add.apply @, args
154
155
156each _set, <[ All Post Get Put Delete ]>
157
158class Collection extends Route
159
160 Config: ->
161 super()
162 @All \/:id* ~> it.SetInstance @resource.Fetch +it.params.id
163 @Get ~> @resource.List it.query
164 @Post ~> @resource.Create it.body
165 @Get \/:id ~> it.instance
166 @Put \/:id ~> it.instance.Set it.body
167 @Delete \/:id ~> it.instance.Delete!
168
169# class SingleRoute extends Route
170#
171# ->
172#
173# @resource.Init()
174# @rname = @resource.lname
175#
176# @name = @rname
177#
178# @debug = new Debug "N::Route::#{@rname}", Debug.colors.purple
179#
180# if @rname[*-1] is 'y'
181# @name = @rname[ til @ name.length]*'' + 'ies'
182#
183# N := require '../..' if not N?
184# if not N.app?
185# Route._InitServer!
186# @app = N.app
187# # @resource.Init()
188#
189# #Resource creation if non-existant
190# @resource.Fetch 1, (err, result) ~>
191# if err? and @resource.config?.schema? and
192# _(@resource.config.schema).filter((item) ->
193# not item.default? and not item.optional?).length
194# throw new Error """
195# SingleRoute used with schema Resource and non existant row at id = 1.
196# Please add it manualy to your DB system before continuing.'
197# """
198# if err?
199# @resource.Create {}, (err, res) ->
200#
201# @All ~> it.SetInstance @resource.Fetch 1
202# @Get ~> it.instance
203# @Put ~> it.instance.ExtendSafe it.body; it.instance.Save!
204#
205# @Config()
206
207Route.Collection = Collection
208# Route.SingleRoute = SingleRoute
209module.exports = Route
210
211# Route.Collection = require \./Collection