-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathserver.js
130 lines (108 loc) · 4.17 KB
/
server.js
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import { red, green, cyan, bold } from 'colorette'
const path = require('path')
const fs = require('fs')
const http = require('http')
const handler = require('serve-handler')
const pkg = require('./package.json')
console.log('👀 watch & serve 🤲\n###################\n')
const port = pkg.config.port
const destDir = 'dist/'
const devScriptInFile = 'dev.user.js'
const outFile = path.join(destDir, 'out.js')
const hyperlink = (url, title) => `\u001B]8;;${url}\u0007${title || url}\u001B]8;;\u0007`
fs.mkdir('dist/', { recursive: true }, () => null)
// Start web server
const server = http.createServer((request, response) => {
return handler(request, response, {
public: destDir
})
})
server.listen(port, () => {
console.log(`Running webserver at ${hyperlink(`http://localhost:${port}`)}`)
})
// Create the userscript for development 'dist/dev.user.js'
const devScriptOutFile = path.join(destDir, devScriptInFile)
console.log(cyan(`generate development userscript ${bold(devScriptInFile)} → ${bold(devScriptOutFile)}...`))
// Read dev script
const devScriptContent = fs.readFileSync(devScriptInFile, 'utf8').replace(/%PORT%/gm, port.toString())
// Read require configuration
const requires = require('./requires.json')
// Read userscript
let userScriptFile = null
for (const file of fs.readdirSync('.')) {
if (file.endsWith('.user.js') && !file.endsWith('dev.user.js')) {
userScriptFile = file
break
}
}
const userScriptContent = fs.readFileSync(userScriptFile, 'utf8')
// Copy header from userscript to devscript
let header = userScriptContent.split('// ==/UserScript==', 1)[0]
const grants = []
if (header.indexOf('GM.xmlHttpRequest') === -1) {
grants.push('GM.xmlHttpRequest')
}
if (header.indexOf('GM.setValue') === -1) {
grants.push('GM.setValue')
}
if (header.indexOf('GM.getValue') === -1) {
grants.push('GM.getValue')
}
if (grants) {
grants.forEach(function (fname) {
header += `\n// @grant ${fname}\n`
})
}
// Remove @require
if (header.indexOf('@require') !== -1) {
for (const match of header.matchAll(/@require\s+(.+)/gm)) {
const requireUrl = match[1]
if (requireUrl in requires) {
console.log(red(`Using local @require ${requireUrl} in ${requires[requireUrl]}`))
header = header.replace(new RegExp('//\\s*@require\\s+' + requireUrl.replace('.', '\\.'), ''), '')
}
}
}
header += '\n// @connect localhost'
// Write devscript to file
const outContent = `${header}\n// ==/UserScript==\n\n${devScriptContent}`
fs.writeFileSync(devScriptOutFile, outContent)
console.log(green(`created ${bold(devScriptOutFile)}. Please install in Tampermonkey: `) + hyperlink(`http://localhost:${port}/${devScriptInFile}`))
// Create out.js
const fileWatchers = {}
function updateOut (event, filename) {
if (filename) {
const stats = fs.statSync(fileWatchers[filename][0])
if (stats.size === 0 || stats.mtime.valueOf() === fileWatchers[filename][1].valueOf()) {
return
}
fileWatchers[filename][1] = stats.mtime
const userScriptContent = fs.readFileSync(userScriptFile, 'utf8')
const parts = userScriptContent.split('// ==/UserScript==')
const header = parts.shift()
const script = parts.join('// ==/UserScript==')
// Insert @require code from requires.json
let requiresContent = []
if (header.indexOf('@require') !== -1) {
for (const match of header.matchAll(/@require\s+(.+)/gm)) {
const requireUrl = match[1]
if (requireUrl in requires) {
const content = fs.readFileSync(requires[requireUrl], 'utf8')
requiresContent.push(content.split('// ==/UserScript==').pop())
}
}
}
requiresContent = requiresContent.join('\n\n')
const outContent = `${header}\n// ==/UserScript==\n\n${requiresContent}\n${script}`
fs.writeFileSync(outFile, outContent)
console.log(`${fileWatchers[filename][0]} file changed -> Updated ${outFile}`)
}
}
// Watch for file changes
fileWatchers[path.basename(userScriptFile)] = [userScriptFile, new Date(0)]
fs.watch(userScriptFile, updateOut)
for (const url in requires) {
fileWatchers[path.basename(requires[url])] = [requires[url], new Date(0)]
fs.watch(requires[url], updateOut)
}
updateOut(null, path.basename(userScriptFile))