/
server.coffee
105 lines (87 loc) · 2.87 KB
/
server.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
fs = require 'fs'
path = require 'path'
express = require 'express'
mustache = require 'mustache'
detective = require 'detective'
stitch = require 'stitch'
# Config
projectPath = process.cwd()
projectName = path.basename projectPath.toLowerCase()
builtinsPath = path.join(__dirname, 'static', 'gesso_modules')
buildDir = 'build'
buildFile = projectName
buildFile += '.js' if projectName.substr(projectName.length - 3) != '.js'
buildPath = path.join buildDir, buildFile
buildUrl = '/build/' + buildFile
extensions = ['.js', '.json']
entryModules = ['main']
# The web application
app = express.createServer()
app.use '/static', express.static(path.join(__dirname, 'static'))
app.set 'views', path.join(__dirname, 'views')
app.set 'view options',
layout: false
app.register '.html',
compile: (source, options) ->
(locals) ->
mustache.to_html source, locals
exports.app = app
# Views
app.get '/', (req, res) ->
res.render 'index.html',
script: buildUrl
width: 800
height: 600
app.get buildUrl, (req, res) ->
console.log 'Building ' + buildFile + '...'
files = walkModules entryModules, ''
# TODO: Remove this once stitch is working
files.push(projectPath)
files.push(builtinsPath)
p = stitch.createPackage
paths: files
p.compile (err, source) ->
throw err if err
source += "require('main')\n"
fs.writeFileSync buildPath, source, 'utf8'
console.log 'Done!'
res.contentType buildPath
res.send sendFile buildPath
# Helpers
sendFile = (file) ->
fs.readFileSync file, 'utf8'
walkModules = (names, currentFile) ->
fileLists = names.map (name) ->
walkModule name, currentFile
fileLists.reduce concat, []
walkModule = (name, currentFile) ->
file = resolve name, currentFile
# Check for existing module
if not path.existsSync file
console.log "\nWarning: No such module '" + file + "'\n at " + currentFile
return []
contents = fs.readFileSync file, 'utf8'
requires = detective contents
fileLists = requires.map (name) ->
walkModule name, file
fileLists.reduce concat, [file]
resolve = (name, currentFile) ->
dir = if currentFile then path.dirname(currentFile) else projectPath
norm = path.normalize name
file = path.join dir, norm
# Check whether the file is within the project directory
if file.substring(0, projectPath.length) != projectPath
console.log '\nWarning: A required file is located outside of the project: "' + name + '"\n at ' + currentFile
if not path.extname(file)
# Check for existing file with the installed extension handlers
for ext in extensions
if path.existsSync file + ext
return file + ext
# No local file found, check for builtin module
isModuleName = path.basename(norm) == norm
if isModuleName
builtin = path.join(builtinsPath, norm) + '.js'
return builtin if path.existsSync builtin
return norm
concat = (a, b) ->
a.concat b