1 | Package = require './package'
|
2 | _ = require 'underscore'
|
3 | coffee = require 'coffee-script'
|
4 | ejs = require 'ejs'
|
5 | fs = require 'fs'
|
6 | path = require 'path'
|
7 |
|
8 | template = fs.readFileSync(path.join __dirname, 'template.ejs.js').toString().replace(/\n/g, '')
|
9 |
|
10 | ###
|
11 | Jspackle connect middleware
|
12 |
|
13 | This piece of a middleware is recommended for development usage only. For
|
14 | production deployed systems, combine your pacakge using `jspackle build` and
|
15 | serve statically.
|
16 |
|
17 | Creates a request handler that will handle all requests that start with
|
18 | the given `urlPath`, based on the package defined by the jspackle config
|
19 | file described in `confPath`.
|
20 |
|
21 | Eg:
|
22 | connect.createServer(jspackle.connect('/path/to/jspackle.json', '/js/my_project.js'), ....);
|
23 |
|
24 | When a request is made to `/js/my_project.js`, Jspackle serves a JavaScript file that
|
25 | synchronously loads all of the source files described in `/path/to/jspackle.json`:
|
26 |
|
27 | GET: `/js/my_project.js/foo.js`
|
28 | GET: `/js/my_project.js/bar.js`
|
29 |
|
30 | These requests are also caught by the jspackle middleware, which finds the source
|
31 | files based on the package configs, reads the given source file off of disc and
|
32 | serves it to the browser. Using CoffeeScript? That's fine! Sources that end with
|
33 | `.coffee` will be compiled in real-time in memory by the jspackle middleware and
|
34 | served back as JavaScript.
|
35 | ###
|
36 |
|
37 |
|
38 | ###
|
39 | Serves the provided string of JavaScript source to as
|
40 | the result of request object provided.
|
41 | ###
|
42 | serveJavaScript = (res, source='')->
|
43 | res.statusCode = 200
|
44 | res.setHeader 'Content-type', 'text/javascript'
|
45 | res.end source
|
46 |
|
47 | ###
|
48 | Returns a 500 error
|
49 | ###
|
50 | error = (err, res)->
|
51 | console.error err
|
52 | res.statusCode = 500
|
53 | res.end err
|
54 |
|
55 | ###
|
56 | Compiles the provided CoffeeScript source and send it as the
|
57 | response.
|
58 | ###
|
59 | serveCoffeeScript = (res, source)->
|
60 | try
|
61 | source = coffee.compile source
|
62 | serveJavaScript res, source
|
63 | catch e
|
64 | error e, res
|
65 |
|
66 | ###
|
67 | Loads the source at the given path.
|
68 | ###
|
69 | loadSource = (pack, source, res)->
|
70 | try
|
71 | fs.readFile path.join(pack.opts.root, pack.opts.source_folder, source), (err, data)->
|
72 | return error err, res if err
|
73 | data = data.toString()
|
74 | serve = if source.match new RegExp '\.coffee$' then serveCoffeeScript else serveJavaScript
|
75 | serve res, data
|
76 | catch e
|
77 | error e, res
|
78 |
|
79 | ###
|
80 | A function generator:
|
81 | Creates a middleware function for serving jspackle packages in 'development'
|
82 | mode.
|
83 | ###
|
84 | module.exports = (confPath, urlPath)->
|
85 |
|
86 | configs =
|
87 | url: urlPath
|
88 |
|
89 | package = JSON.parse fs.readFileSync confPath
|
90 | p = new Package root: path.dirname(confPath)+'/', path: path.basename(confPath)
|
91 |
|
92 | ###
|
93 | Creates a main JavaScript file which synchronously loads all the
|
94 | development sources in order via XHR
|
95 | ###
|
96 | _.extend configs, package
|
97 | main = ejs.render template, configs
|
98 |
|
99 | (req, res, next)->
|
100 | url = req.url.split('?')[0]
|
101 | if url is urlPath
|
102 | serveJavaScript res, main
|
103 | else if url.match new RegExp "^#{urlPath}"
|
104 | loadSource p, url.replace(urlPath, ''), res
|
105 | else
|
106 | next()
|