-
Notifications
You must be signed in to change notification settings - Fork 4
/
urara.js
127 lines (113 loc) · 3.41 KB
/
urara.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
/**
* Urara.JS
* Version: 200
*/
import { promises as fs } from 'fs'
import * as path from 'path'
import chokidar from 'chokidar'
import chalk from 'chalk'
const config = {
extensions: ['svelte', 'md', 'js', 'ts'],
catch: ['ENOENT', 'EEXIST']
}
const check = ext => (config.extensions.includes(ext) ? 'src/routes' : 'static')
const log = (color, msg, dest) =>
console.log(
chalk.dim(new Date().toLocaleTimeString() + ' ') +
chalk.magentaBright.bold('[urara] ') +
chalk[color](msg + ' ') +
chalk.dim(dest ?? '')
)
const error = err => {
if (config.catch.includes(err.code)) {
console.log(
chalk.dim(new Date().toLocaleTimeString() + ' ') +
chalk.redBright.bold('[urara] ') +
chalk.red('error ') +
chalk.dim(err.message)
)
} else {
throw err
}
}
const cpFile = (src, { stat = 'copy', dest = path.join(check(path.parse(src).ext.slice(1)), src.slice(6)) } = {}) =>
fs
.copyFile(src, dest)
.then(log('green', `${stat} file`, dest))
.catch(error)
const rmFile = (src, { dest = path.join(check(path.parse(src).ext.slice(1)), src.slice(6)) } = {}) =>
fs.rm(dest).then(log('yellow', 'remove file', dest)).catch(error)
const cpDir = src =>
fs.readdir(src, { withFileTypes: true }).then(files =>
files.forEach(file => {
const dest = path.join(src, file.name)
if (file.isDirectory()) {
mkDir(dest)
cpDir(dest)
} else if (file.name.startsWith('.')) {
log('cyan', 'ignore file', dest)
} else {
cpFile(dest)
}
})
)
const mkDir = (src, { dest = [path.join('src/routes', src.slice(6)), path.join('static', src.slice(6))] } = {}) => {
dest.forEach(path => fs.mkdir(path).then(log('green', 'make dir', path)).catch(error))
}
const rmDir = (src, { dest = [path.join('src/routes', src.slice(6)), path.join('static', src.slice(6))] } = {}) => {
dest.forEach(path => fs.rm(path, { force: true, recursive: true }).then(log('yellow', 'remove dir', path)).catch(error))
}
const cleanDir = src =>
fs.readdir(src, { withFileTypes: true }).then(files => {
files.forEach(file => {
const dest = path.join(src, file.name)
file.isDirectory() ? rmDir(dest) : file.name.startsWith('.') ? log('cyan', 'ignore file', dest) : rmFile(dest)
})
})
const build = () => {
mkDir('static', { dest: ['static'] })
cpDir('urara')
}
const clean = () => {
cleanDir('urara')
rmDir('static', { dest: ['static'] })
}
switch (process.argv[2]) {
case 'watch':
{
let watcher = chokidar.watch('urara', {
ignored: file => path.basename(file).startsWith('.')
})
watcher
.on('add', file => cpFile(file))
.on('change', file => cpFile(file, { stat: 'update' }))
.on('unlink', file => rmFile(file))
.on('addDir', dir => mkDir(dir))
.on('unlinkDir', dir => rmDir(dir))
.on('error', error => log('red', 'error', error))
.on('ready', () => log('cyan', 'copy complete. ready for changes'))
process
.on('SIGINT', () => {
log('red', 'sigint')
clean()
watcher?.close()
})
.on('SIGTERM', () => {
log('red', 'sigterm')
watcher?.close()
})
.on('exit', () => {
log('red', 'exit')
})
}
break
case 'build':
build()
break
case 'clean':
clean()
break
default:
log('red', 'error', 'invalid arguments')
break
}