@whyour/qinglong 0.5.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README-en.md +18 -0
- package/README.md +18 -0
- package/docker/docker-entrypoint.sh +4 -3
- package/docker/nginx.conf +1 -1
- package/package.json +7 -3
- package/shell/share.sh +6 -70
- package/shell/update.sh +66 -22
- package/static/build/api/system.js +47 -9
- package/static/build/config/index.js +5 -0
- package/static/build/config/util.js +9 -1
- package/static/build/data/cron.js +3 -3
- package/static/build/data/dependence.js +16 -4
- package/static/build/loaders/initData.js +1 -1
- package/static/build/loaders/initTask.js +3 -3
- package/static/build/loaders/server.js +23 -8
- package/static/build/services/dependence.js +37 -10
- package/static/build/services/system.js +44 -1
- package/static/build/shared/pLimit.js +6 -6
- package/static/dist/1138.c3a50127.async.js +4 -0
- package/static/dist/{4804.183d71af.async.js → 1295.06026141.async.js} +3 -3
- package/static/dist/3330.950e8570.async.js +1 -0
- package/static/dist/3669.4f05548e.async.js +3 -0
- package/static/dist/37.8af37a28.async.js +6 -0
- package/static/dist/3800.34124d62.async.js +2 -0
- package/static/dist/{4163.a1d279c3.async.js → 4163.a363bae0.async.js} +1 -1
- package/static/dist/5035.ac19ee2f.async.js +67 -0
- package/static/dist/{7567.a224d0a6.async.js → 6556.f0e353dc.async.js} +2 -2
- package/static/dist/6644.5df1dec2.async.js +62 -0
- package/static/dist/7393.86229389.async.js +1 -0
- package/static/dist/8044.a70b53d2.async.js +18 -0
- package/static/dist/{8844.8525fd2e.async.js → 806.b28198b3.async.js} +2 -2
- package/static/dist/819.a02c513d.async.js +4 -0
- package/static/dist/8347.c3ea8f4e.async.js +6 -0
- package/static/dist/8969.2ad6c360.async.js +1 -0
- package/static/dist/index.html +1 -1
- package/static/dist/layouts__index.34e4586a.async.js +1 -0
- package/static/dist/{src__pages__404.8794c158.async.js → src__pages__404.970a2ae1.async.js} +1 -1
- package/static/dist/src__pages__config__index.215d2363.async.js +22 -0
- package/static/dist/src__pages__crontab__detail.bd91d91a.async.js +3 -0
- package/static/dist/src__pages__crontab__index.26308df9.async.js +19 -0
- package/static/dist/src__pages__crontab__logModal.c4254d3f.async.js +2 -0
- package/static/dist/src__pages__crontab__modal.eebf3433.async.js +5 -0
- package/static/dist/src__pages__crontab__type.136454fe.async.js +1 -0
- package/static/dist/src__pages__crontab__viewManageModal.4013da38.async.js +1 -0
- package/static/dist/src__pages__dependence__index.c863e8a7.async.js +2 -0
- package/static/dist/{src__pages__script__saveModal.312a0beb.async.js → src__pages__dependence__logModal.d1ee1a9f.async.js} +2 -2
- package/static/dist/src__pages__dependence__modal.58ad2c1a.async.js +5 -0
- package/static/dist/src__pages__diff__index.9f5c7a8e.async.js +5 -0
- package/static/dist/src__pages__env__editNameModal.07873464.async.js +4 -0
- package/static/dist/src__pages__env__index.f90a2f57.async.js +2 -0
- package/static/dist/src__pages__env__modal.50ed7bfe.async.js +5 -0
- package/static/dist/src__pages__error__index.dd1a4c16.async.js +4 -0
- package/static/dist/src__pages__initialization__index.af6852bf.async.js +21 -0
- package/static/dist/src__pages__log__index.e6c628e8.async.js +1 -0
- package/static/dist/src__pages__login__index.419baa77.async.js +2 -0
- package/static/dist/src__pages__script__editModal.3ae4162a.async.js +4 -0
- package/static/dist/{src__pages__script__renameModal.ea3b6689.async.js → src__pages__script__editNameModal.c2c2fd10.async.js} +2 -2
- package/static/dist/src__pages__script__index.a1f04db0.async.js +23 -0
- package/static/dist/src__pages__script__renameModal.c7990ca9.async.js +4 -0
- package/static/dist/src__pages__script__saveModal.d0a7e413.async.js +4 -0
- package/static/dist/src__pages__script__setting.d79e1f45.async.js +4 -0
- package/static/dist/src__pages__setting__about.5138ea49.async.js +1 -0
- package/static/dist/src__pages__setting__appModal.457f03c0.async.js +4 -0
- package/static/dist/src__pages__setting__checkUpdate.e8512ada.async.js +1 -0
- package/static/dist/src__pages__setting__index.b8a741cf.async.js +2 -0
- package/static/dist/src__pages__setting__loginLog.195a2809.async.js +18 -0
- package/static/dist/src__pages__setting__notification.5156672c.async.js +21 -0
- package/static/dist/src__pages__setting__other.8e242852.async.js +1 -0
- package/static/dist/src__pages__setting__progress.bd2dfeee.async.js +1 -0
- package/static/dist/src__pages__setting__security.70bccf38.async.js +4 -0
- package/static/dist/src__pages__subscription__index.3233e4c5.async.js +2 -0
- package/static/dist/src__pages__subscription__logModal.ef8e52b8.async.js +2 -0
- package/static/dist/src__pages__subscription__modal.b8fe92d2.async.js +4 -0
- package/static/dist/umi.f60e35ef.js +12 -0
- package/version.yaml +6 -5
- package/static/dist/1654.e06fbac5.async.js +0 -1
- package/static/dist/3800.5488ae14.async.js +0 -2
- package/static/dist/4346.5ab6fdc1.async.js +0 -1
- package/static/dist/4491.3c2d8653.async.js +0 -4
- package/static/dist/5008.c612bbdb.async.js +0 -11
- package/static/dist/5035.2489750b.async.js +0 -67
- package/static/dist/7393.d9ed4b3a.async.js +0 -1
- package/static/dist/8037.386b415d.async.js +0 -1
- package/static/dist/8612.b6557431.async.js +0 -1
- package/static/dist/8657.805a96f7.async.js +0 -18
- package/static/dist/921.198cefa6.async.js +0 -6
- package/static/dist/9583.49d0845f.async.js +0 -4
- package/static/dist/layouts__index.3db43e0b.async.js +0 -1
- package/static/dist/src__pages__config__index.7fb61af5.async.js +0 -22
- package/static/dist/src__pages__crontab__detail.32a7846b.async.js +0 -3
- package/static/dist/src__pages__crontab__index.5af3329c.async.js +0 -19
- package/static/dist/src__pages__crontab__logModal.22faa907.async.js +0 -2
- package/static/dist/src__pages__crontab__modal.6d17fdcf.async.js +0 -5
- package/static/dist/src__pages__crontab__type.ff7e0172.async.js +0 -1
- package/static/dist/src__pages__crontab__viewManageModal.2dea2918.async.js +0 -1
- package/static/dist/src__pages__dependence__index.3b140a79.async.js +0 -2
- package/static/dist/src__pages__dependence__logModal.e49658d5.async.js +0 -4
- package/static/dist/src__pages__dependence__modal.94ff002a.async.js +0 -5
- package/static/dist/src__pages__diff__index.240e4991.async.js +0 -5
- package/static/dist/src__pages__env__editNameModal.047bb3ba.async.js +0 -4
- package/static/dist/src__pages__env__index.48602d18.async.js +0 -2
- package/static/dist/src__pages__env__modal.8b48ffa4.async.js +0 -5
- package/static/dist/src__pages__error__index.a4305d27.async.js +0 -4
- package/static/dist/src__pages__initialization__index.978a7f09.async.js +0 -21
- package/static/dist/src__pages__log__index.ae245070.async.js +0 -1
- package/static/dist/src__pages__login__index.8eb4df8e.async.js +0 -2
- package/static/dist/src__pages__script__editModal.02b12902.async.js +0 -4
- package/static/dist/src__pages__script__editNameModal.2773cb7b.async.js +0 -4
- package/static/dist/src__pages__script__index.679510cd.async.js +0 -6
- package/static/dist/src__pages__script__setting.11abc6ae.async.js +0 -4
- package/static/dist/src__pages__setting__about.1460b7fa.async.js +0 -1
- package/static/dist/src__pages__setting__appModal.74267529.async.js +0 -4
- package/static/dist/src__pages__setting__checkUpdate.ce2e30bb.async.js +0 -4
- package/static/dist/src__pages__setting__index.0bfefeff.async.js +0 -2
- package/static/dist/src__pages__setting__loginLog.0708083b.async.js +0 -18
- package/static/dist/src__pages__setting__notification.15a286d0.async.js +0 -21
- package/static/dist/src__pages__setting__other.00a69cf4.async.js +0 -1
- package/static/dist/src__pages__setting__security.62b6b562.async.js +0 -4
- package/static/dist/src__pages__subscription__index.708b6c8f.async.js +0 -2
- package/static/dist/src__pages__subscription__logModal.3a1a8e58.async.js +0 -2
- package/static/dist/src__pages__subscription__modal.c034f25a.async.js +0 -4
- package/static/dist/umi.fb5757cf.js +0 -11
- /package/static/dist/{9439.59dcf306.chunk.css → 1095.59dcf306.chunk.css} +0 -0
- /package/static/dist/{8612.d2d0a2c7.chunk.css → 8969.d2d0a2c7.chunk.css} +0 -0
package/README-en.md
CHANGED
|
@@ -35,6 +35,24 @@ Timed task management platform supporting Python3, JavaScript, Shell, Typescript
|
|
|
35
35
|
- Support dark mode
|
|
36
36
|
- Support cell phone operation
|
|
37
37
|
|
|
38
|
+
## Version
|
|
39
|
+
### docker
|
|
40
|
+
|
|
41
|
+
The `latest` image is built on `alpine` and the `debian` image is built on `debian-slim`. If you need to use a dependency that is not supported by `alpine`, it is recommended that you use the `debian` image.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
docker pull whyour/qinglong:latest
|
|
45
|
+
docker pull whyour/qinglong:debian
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### npm
|
|
49
|
+
|
|
50
|
+
The npm version supports `debian/ubuntu/centos/alpine` systems and requires `node/python3` to be installed.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm i @whyour/qinglong
|
|
54
|
+
```
|
|
55
|
+
|
|
38
56
|
## Deployment
|
|
39
57
|
|
|
40
58
|
### Docker (Recommended)
|
package/README.md
CHANGED
|
@@ -37,6 +37,24 @@ Timed task management platform supporting Python3, JavaScript, Shell, Typescript
|
|
|
37
37
|
- 支持暗黑模式
|
|
38
38
|
- 支持手机端操作
|
|
39
39
|
|
|
40
|
+
## 版本
|
|
41
|
+
### docker
|
|
42
|
+
|
|
43
|
+
`latest` 镜像是基于 `alpine` 构建,`debian` 镜像是基于 `debian-slim` 构建。如果需要使用 `alpine` 不支持的依赖,建议使用 `debian` 镜像
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
docker pull whyour/qinglong:latest
|
|
47
|
+
docker pull whyour/qinglong:debian
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### npm
|
|
51
|
+
|
|
52
|
+
npm 版本支持 `debian/ubuntu/centos/alpine` 系统,需要自行安装 `node/python3`
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm i @whyour/qinglong
|
|
56
|
+
```
|
|
57
|
+
|
|
40
58
|
## 部署
|
|
41
59
|
|
|
42
60
|
### docker (推荐)
|
|
@@ -4,8 +4,6 @@ dir_shell=/ql/shell
|
|
|
4
4
|
. $dir_shell/share.sh
|
|
5
5
|
link_shell
|
|
6
6
|
|
|
7
|
-
export isFirstStartServer=true
|
|
8
|
-
|
|
9
7
|
echo -e "======================1. 检测配置文件========================\n"
|
|
10
8
|
make_dir /etc/nginx/conf.d
|
|
11
9
|
make_dir /run/nginx
|
|
@@ -25,7 +23,10 @@ if [[ "$is_equal_registry" == "" ]]; then
|
|
|
25
23
|
cd && pnpm config set registry $NpmMirror
|
|
26
24
|
pnpm install -g
|
|
27
25
|
fi
|
|
28
|
-
|
|
26
|
+
if [[ ! -s $dir_scripts/package.json ]] || [[ $(diff $dir_sample/package.json $dir_scripts/package.json) ]]; then
|
|
27
|
+
cp -f $dir_sample/package.json $dir_scripts/package.json
|
|
28
|
+
npm_install_2 $dir_scripts
|
|
29
|
+
fi
|
|
29
30
|
echo
|
|
30
31
|
|
|
31
32
|
echo -e "======================3. 启动nginx========================\n"
|
package/docker/nginx.conf
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whyour/qinglong",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Timed task management platform supporting Python3, JavaScript, Shell, Typescript",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -107,6 +107,7 @@
|
|
|
107
107
|
"serve-handler": "^6.1.3",
|
|
108
108
|
"sockjs": "^0.3.24",
|
|
109
109
|
"sqlite3": "git+https://github.com/whyour/node-sqlite3.git#v1.0.3",
|
|
110
|
+
"tar": "^6.1.15",
|
|
110
111
|
"toad-scheduler": "^1.6.0",
|
|
111
112
|
"typedi": "^0.10.0",
|
|
112
113
|
"uuid": "^8.3.2",
|
|
@@ -124,6 +125,7 @@
|
|
|
124
125
|
"@types/cross-spawn": "^6.0.2",
|
|
125
126
|
"@types/express": "^4.17.13",
|
|
126
127
|
"@types/express-jwt": "^6.0.4",
|
|
128
|
+
"@types/file-saver": "^2.0.5",
|
|
127
129
|
"@types/js-yaml": "^4.0.5",
|
|
128
130
|
"@types/jsonwebtoken": "^8.5.8",
|
|
129
131
|
"@types/lodash": "^4.14.185",
|
|
@@ -139,15 +141,18 @@
|
|
|
139
141
|
"@types/serve-handler": "^6.1.1",
|
|
140
142
|
"@types/sockjs": "^0.3.33",
|
|
141
143
|
"@types/sockjs-client": "^1.5.1",
|
|
144
|
+
"@types/tar": "^6.1.5",
|
|
142
145
|
"@types/uuid": "^8.3.4",
|
|
143
|
-
"@umijs/max": "^4.0.
|
|
146
|
+
"@umijs/max": "^4.0.72",
|
|
144
147
|
"@umijs/ssr-darkreader": "^4.9.45",
|
|
145
148
|
"ansi-to-react": "^6.1.6",
|
|
146
149
|
"antd": "^4.24.8",
|
|
147
150
|
"antd-img-crop": "^4.2.3",
|
|
151
|
+
"axios": "^1.4.0",
|
|
148
152
|
"codemirror": "^5.65.2",
|
|
149
153
|
"compression-webpack-plugin": "9.2.0",
|
|
150
154
|
"concurrently": "^7.0.0",
|
|
155
|
+
"file-saver": "^2.0.5",
|
|
151
156
|
"lint-staged": "^13.0.3",
|
|
152
157
|
"monaco-editor": "0.33.0",
|
|
153
158
|
"nodemon": "^2.0.15",
|
|
@@ -170,7 +175,6 @@
|
|
|
170
175
|
"tslib": "^2.4.0",
|
|
171
176
|
"tsx": "^3.12.3",
|
|
172
177
|
"typescript": "4.8.4",
|
|
173
|
-
"umi-request": "^1.4.0",
|
|
174
178
|
"vh-check": "^2.0.5",
|
|
175
179
|
"virtualizedtableforantd4": "1.3.0",
|
|
176
180
|
"webpack": "^5.70.0",
|
package/shell/share.sh
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## 目录
|
|
4
4
|
dir_root=$QL_DIR
|
|
5
|
+
dir_tmp=$dir_root/.tmp
|
|
5
6
|
dir_data=$dir_root/data
|
|
6
7
|
|
|
7
8
|
if [[ $QL_DATA_DIR ]]; then
|
|
@@ -180,6 +181,7 @@ define_cmd() {
|
|
|
180
181
|
}
|
|
181
182
|
|
|
182
183
|
fix_config() {
|
|
184
|
+
make_dir $dir_tmp
|
|
183
185
|
make_dir $dir_static
|
|
184
186
|
make_dir $dir_data
|
|
185
187
|
make_dir $dir_config
|
|
@@ -268,6 +270,7 @@ npm_install_sub() {
|
|
|
268
270
|
else
|
|
269
271
|
pnpm install --loglevel error --production
|
|
270
272
|
fi
|
|
273
|
+
exit_status=$?
|
|
271
274
|
}
|
|
272
275
|
|
|
273
276
|
npm_install_2() {
|
|
@@ -288,90 +291,22 @@ diff_and_copy() {
|
|
|
288
291
|
fi
|
|
289
292
|
}
|
|
290
293
|
|
|
291
|
-
update_depend() {
|
|
292
|
-
local dir_current=$(pwd)
|
|
293
|
-
|
|
294
|
-
if [[ ! -s $dir_scripts/package.json ]] || [[ $(diff $dir_sample/package.json $dir_scripts/package.json) ]]; then
|
|
295
|
-
cp -f $dir_sample/package.json $dir_scripts/package.json
|
|
296
|
-
npm_install_2 $dir_scripts
|
|
297
|
-
fi
|
|
298
|
-
|
|
299
|
-
cd $dir_current
|
|
300
|
-
}
|
|
301
|
-
|
|
302
294
|
git_clone_scripts() {
|
|
303
295
|
local url="$1"
|
|
304
296
|
local dir="$2"
|
|
305
297
|
local branch="$3"
|
|
306
298
|
local proxy="$4"
|
|
307
299
|
[[ $branch ]] && local part_cmd="-b $branch "
|
|
308
|
-
echo -e "
|
|
300
|
+
echo -e "开始拉取仓库 ${uniq_path} 到 $dir\n"
|
|
309
301
|
|
|
310
302
|
set_proxy "$proxy"
|
|
311
303
|
|
|
312
304
|
git clone --depth=1 $part_cmd $url $dir
|
|
313
305
|
exit_status=$?
|
|
314
306
|
|
|
315
|
-
reset_branch "$branch" "$dir"
|
|
316
|
-
|
|
317
307
|
unset_proxy
|
|
318
308
|
}
|
|
319
309
|
|
|
320
|
-
git_pull_scripts() {
|
|
321
|
-
local dir_current=$(pwd)
|
|
322
|
-
local dir_work="$1"
|
|
323
|
-
local branch="$2"
|
|
324
|
-
local proxy="$3"
|
|
325
|
-
cd $dir_work
|
|
326
|
-
echo -e "开始更新仓库:$dir_work"
|
|
327
|
-
set_proxy "$proxy"
|
|
328
|
-
|
|
329
|
-
if [[ ! $branch ]]; then
|
|
330
|
-
branch=$(cd $dir_work && git remote show origin | grep 'HEAD branch' | cut -d' ' -f5)
|
|
331
|
-
fi
|
|
332
|
-
|
|
333
|
-
local pre_commit_id=$(git rev-parse --short HEAD)
|
|
334
|
-
reset_branch "$branch" "$dir_work"
|
|
335
|
-
|
|
336
|
-
git fetch --depth 1 origin $branch
|
|
337
|
-
exit_status=$?
|
|
338
|
-
|
|
339
|
-
reset_branch "$branch" "$dir_work"
|
|
340
|
-
local cur_commit_id=$(git rev-parse --short HEAD)
|
|
341
|
-
if [[ $cur_commit_id != $pre_commit_id ]]; then
|
|
342
|
-
exit_status=0
|
|
343
|
-
fi
|
|
344
|
-
|
|
345
|
-
unset_proxy
|
|
346
|
-
cd $dir_current
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
reset_romote_url() {
|
|
350
|
-
local dir_current=$(pwd)
|
|
351
|
-
local dir_work=$1
|
|
352
|
-
local url=$2
|
|
353
|
-
local branch="$3"
|
|
354
|
-
|
|
355
|
-
cd $dir_work
|
|
356
|
-
if [[ -d "$dir_work/.git" ]]; then
|
|
357
|
-
[[ -f ".git/index.lock" ]] && rm -f .git/index.lock >/dev/null
|
|
358
|
-
git remote set-url origin $url &>/dev/null
|
|
359
|
-
else
|
|
360
|
-
git init
|
|
361
|
-
git remote add origin $url &>/dev/null
|
|
362
|
-
fi
|
|
363
|
-
|
|
364
|
-
cd $dir_current
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
reset_branch() {
|
|
368
|
-
local branch="$1"
|
|
369
|
-
local part_cmd="origin/${branch}"
|
|
370
|
-
git remote set-branches origin $branch
|
|
371
|
-
git reset --hard $part_cmd &>/dev/null
|
|
372
|
-
git checkout -b $branch $part_cmd &>/dev/null
|
|
373
|
-
}
|
|
374
|
-
|
|
375
310
|
random_range() {
|
|
376
311
|
local beg=$1
|
|
377
312
|
local end=$2
|
|
@@ -383,7 +318,8 @@ reload_pm2() {
|
|
|
383
318
|
# 代理会影响 grpc 服务
|
|
384
319
|
unset_proxy
|
|
385
320
|
pm2 flush &>/dev/null
|
|
386
|
-
pm2 startOrGracefulReload $file_ecosystem_js
|
|
321
|
+
pm2 startOrGracefulReload $file_ecosystem_js --update-env
|
|
322
|
+
pm2 sendSignal SIGKILL panel &>/dev/null
|
|
387
323
|
}
|
|
388
324
|
|
|
389
325
|
diff_time() {
|
package/shell/update.sh
CHANGED
|
@@ -229,58 +229,98 @@ usage() {
|
|
|
229
229
|
echo -e "9. $cmd_update resettfa # 禁用两步登录"
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
+
reload_qinglong() {
|
|
233
|
+
local reload_target="${1}"
|
|
234
|
+
local primary_branch="master"
|
|
235
|
+
if [[ "${QL_BRANCH}" == "develop" ]]; then
|
|
236
|
+
primary_branch="develop"
|
|
237
|
+
fi
|
|
238
|
+
|
|
239
|
+
if [[ "$reload_target" == 'system' ]]; then
|
|
240
|
+
cp -rf ${dir_tmp}/qinglong-${primary_branch}/* ${dir_root}/
|
|
241
|
+
rm -rf $dir_static/*
|
|
242
|
+
cp -rf ${dir_tmp}/qinglong-static-${primary_branch}/* ${dir_static}/
|
|
243
|
+
cp -f $file_config_sample $dir_config/config.sample.sh
|
|
244
|
+
fi
|
|
245
|
+
|
|
246
|
+
if [[ "$reload_target" == 'data' ]]; then
|
|
247
|
+
cp -rf ${dir_tmp}/data ${dir_root}/
|
|
248
|
+
fi
|
|
249
|
+
|
|
250
|
+
reload_pm2
|
|
251
|
+
}
|
|
252
|
+
|
|
232
253
|
## 更新qinglong
|
|
233
254
|
update_qinglong() {
|
|
255
|
+
rm -rf ${dir_tmp}/*
|
|
234
256
|
local mirror="gitee"
|
|
257
|
+
local downloadQLUrl="https://gitee.com/whyour/qinglong/repository/archive"
|
|
258
|
+
local downloadStaticUrl="https://gitee.com/whyour/qinglong-static/repository/archive"
|
|
235
259
|
local githubStatus=$(curl -s -m 2 -IL "https://google.com" | grep 200)
|
|
236
260
|
if [[ ! -z $githubStatus ]]; then
|
|
237
261
|
mirror="github"
|
|
262
|
+
downloadQLUrl="https://github.com/whyour/qinglong/archive/refs/heads"
|
|
263
|
+
downloadStaticUrl="https://github.com/whyour/qinglong-static/archive/refs/heads"
|
|
238
264
|
fi
|
|
239
265
|
echo -e "使用 ${mirror} 源更新...\n"
|
|
240
|
-
export isFirstStartServer=false
|
|
241
266
|
|
|
242
267
|
local primary_branch="master"
|
|
243
268
|
if [[ "${QL_BRANCH}" == "develop" ]]; then
|
|
244
269
|
primary_branch="develop"
|
|
245
270
|
fi
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
271
|
+
|
|
272
|
+
wget -cqO "${dir_tmp}/ql.zip" "${downloadQLUrl}/${primary_branch}.zip"
|
|
273
|
+
exit_status=$?
|
|
249
274
|
|
|
250
275
|
if [[ $exit_status -eq 0 ]]; then
|
|
251
276
|
echo -e "\n更新青龙源文件成功...\n"
|
|
252
|
-
cp -f $file_config_sample $dir_config/config.sample.sh
|
|
253
|
-
update_depend
|
|
254
277
|
|
|
255
|
-
|
|
256
|
-
[[ "$ql_depend_old" != "$ql_depend_new" ]] && npm_install_2 $dir_root
|
|
278
|
+
unzip -oq ${dir_tmp}/ql.zip -d ${dir_tmp}
|
|
257
279
|
|
|
258
|
-
update_qinglong_static
|
|
280
|
+
update_qinglong_static
|
|
259
281
|
else
|
|
260
282
|
echo -e "\n更新青龙源文件失败,请检查网络...\n"
|
|
261
283
|
fi
|
|
262
284
|
}
|
|
263
285
|
|
|
264
286
|
update_qinglong_static() {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
local url="https://${mirror}.com/whyour/qinglong-static.git"
|
|
268
|
-
rm -rf ${ql_static_repo} &>/dev/null
|
|
269
|
-
git_clone_scripts ${url} ${ql_static_repo} ${primary_branch}
|
|
287
|
+
wget -cqO "${dir_tmp}/static.zip" "${downloadStaticUrl}/${primary_branch}.zip"
|
|
288
|
+
exit_status=$?
|
|
270
289
|
|
|
271
290
|
if [[ $exit_status -eq 0 ]]; then
|
|
272
291
|
echo -e "\n更新青龙静态资源成功...\n"
|
|
292
|
+
unzip -oq ${dir_tmp}/static.zip -d ${dir_tmp}
|
|
293
|
+
|
|
294
|
+
check_update_dep
|
|
295
|
+
else
|
|
296
|
+
echo -e "\n更新青龙静态资源失败,请检查网络...\n"
|
|
297
|
+
fi
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
check_update_dep() {
|
|
301
|
+
echo -e "\n开始检测依赖...\n"
|
|
302
|
+
if [[ $(diff $dir_sample/package.json $dir_scripts/package.json) ]]; then
|
|
303
|
+
cp -f $dir_sample/package.json $dir_scripts/package.json
|
|
304
|
+
npm_install_2 $dir_scripts
|
|
305
|
+
fi
|
|
306
|
+
if [[ $(diff $dir_root/package.json ${dir_tmp}/qinglong-${primary_branch}/package.json) ]]; then
|
|
307
|
+
npm_install_2 "${dir_tmp}/qinglong-${primary_branch}"
|
|
308
|
+
fi
|
|
309
|
+
|
|
310
|
+
if [[ $exit_status -eq 0 ]]; then
|
|
311
|
+
echo -e "\n依赖检测安装成功...\n"
|
|
312
|
+
echo -e "\n更新包下载成功...\n"
|
|
313
|
+
|
|
314
|
+
if [[ "$needRestart" == 'true' ]]; then
|
|
315
|
+
cp -rf ${dir_tmp}/qinglong-${primary_branch}/* ${dir_root}/
|
|
316
|
+
rm -rf $dir_static/*
|
|
317
|
+
cp -rf ${dir_tmp}/qinglong-static-${primary_branch}/* ${dir_static}/
|
|
318
|
+
cp -f $file_config_sample $dir_config/config.sample.sh
|
|
273
319
|
|
|
274
|
-
rm -rf $dir_static/*
|
|
275
|
-
cp -rf $ql_static_repo/* $dir_static
|
|
276
|
-
if [[ $no_restart != "no-restart" ]]; then
|
|
277
|
-
nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf
|
|
278
|
-
echo -e "重启面板中..."
|
|
279
|
-
sleep 3
|
|
280
320
|
reload_pm2
|
|
281
321
|
fi
|
|
282
322
|
else
|
|
283
|
-
echo -e "\n
|
|
323
|
+
echo -e "\n依赖检测安装失败,请检查网络...\n"
|
|
284
324
|
fi
|
|
285
325
|
}
|
|
286
326
|
|
|
@@ -456,7 +496,11 @@ main() {
|
|
|
456
496
|
case $p1 in
|
|
457
497
|
update)
|
|
458
498
|
fix_config
|
|
459
|
-
|
|
499
|
+
local needRestart=${p2:-"true"}
|
|
500
|
+
eval update_qinglong $cmd
|
|
501
|
+
;;
|
|
502
|
+
reload)
|
|
503
|
+
eval reload_qinglong "$p2" $cmd
|
|
460
504
|
;;
|
|
461
505
|
extra)
|
|
462
506
|
eval run_extra_shell $cmd
|
|
@@ -33,10 +33,19 @@ const config_1 = __importDefault(require("../config"));
|
|
|
33
33
|
const system_1 = __importDefault(require("../services/system"));
|
|
34
34
|
const celebrate_1 = require("celebrate");
|
|
35
35
|
const user_1 = __importDefault(require("../services/user"));
|
|
36
|
-
const env_1 = require("../data/env");
|
|
37
36
|
const util_1 = require("../config/util");
|
|
38
37
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
38
|
+
const multer_1 = __importDefault(require("multer"));
|
|
39
39
|
const route = (0, express_1.Router)();
|
|
40
|
+
const storage = multer_1.default.diskStorage({
|
|
41
|
+
destination: function (req, file, cb) {
|
|
42
|
+
cb(null, config_1.default.tmpPath);
|
|
43
|
+
},
|
|
44
|
+
filename: function (req, file, cb) {
|
|
45
|
+
cb(null, 'data.tgz');
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
const upload = (0, multer_1.default)({ storage: storage });
|
|
40
49
|
exports.default = (app) => {
|
|
41
50
|
app.use('/system', route);
|
|
42
51
|
route.get('/', async (req, res, next) => {
|
|
@@ -44,11 +53,7 @@ exports.default = (app) => {
|
|
|
44
53
|
try {
|
|
45
54
|
const userService = typedi_1.Container.get(user_1.default);
|
|
46
55
|
const authInfo = await userService.getUserInfo();
|
|
47
|
-
const
|
|
48
|
-
const { version, changeLog, changeLogLink } = await (0, util_1.parseVersion)(config_1.default.versionFile);
|
|
49
|
-
const lastCommitTime = (await (0, util_1.promiseExec)(`cd ${config_1.default.rootPath} && git show -s --format=%ai | head -1`)).replace('\n', '');
|
|
50
|
-
const lastCommitId = (await (0, util_1.promiseExec)(`cd ${config_1.default.rootPath} && git rev-parse --short HEAD`)).replace('\n', '');
|
|
51
|
-
const branch = (await (0, util_1.promiseExec)(`cd ${config_1.default.rootPath} && git symbolic-ref --short HEAD`)).replace('\n', '');
|
|
56
|
+
const { version, changeLog, changeLogLink, publishTime } = await (0, util_1.parseVersion)(config_1.default.versionFile);
|
|
52
57
|
let isInitialized = true;
|
|
53
58
|
if (Object.keys(authInfo).length === 2 &&
|
|
54
59
|
authInfo.username === 'admin' &&
|
|
@@ -60,9 +65,8 @@ exports.default = (app) => {
|
|
|
60
65
|
data: {
|
|
61
66
|
isInitialized,
|
|
62
67
|
version,
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
branch,
|
|
68
|
+
publishTime: (0, dayjs_1.default)(publishTime).unix(),
|
|
69
|
+
branch: process.env.QL_BRANCH || 'master',
|
|
66
70
|
changeLog,
|
|
67
71
|
changeLogLink,
|
|
68
72
|
},
|
|
@@ -122,6 +126,21 @@ exports.default = (app) => {
|
|
|
122
126
|
return next(e);
|
|
123
127
|
}
|
|
124
128
|
});
|
|
129
|
+
route.put('/reload', (0, celebrate_1.celebrate)({
|
|
130
|
+
body: celebrate_1.Joi.object({
|
|
131
|
+
type: celebrate_1.Joi.string().required(),
|
|
132
|
+
}),
|
|
133
|
+
}), async (req, res, next) => {
|
|
134
|
+
const logger = typedi_1.Container.get('logger');
|
|
135
|
+
try {
|
|
136
|
+
const systemService = typedi_1.Container.get(system_1.default);
|
|
137
|
+
const result = await systemService.reloadSystem(req.body.type);
|
|
138
|
+
res.send(result);
|
|
139
|
+
}
|
|
140
|
+
catch (e) {
|
|
141
|
+
return next(e);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
125
144
|
route.put('/notify', (0, celebrate_1.celebrate)({
|
|
126
145
|
body: celebrate_1.Joi.object({
|
|
127
146
|
title: celebrate_1.Joi.string().required(),
|
|
@@ -187,5 +206,24 @@ exports.default = (app) => {
|
|
|
187
206
|
return next(e);
|
|
188
207
|
}
|
|
189
208
|
});
|
|
209
|
+
route.put('/data/export', async (req, res, next) => {
|
|
210
|
+
try {
|
|
211
|
+
const systemService = typedi_1.Container.get(system_1.default);
|
|
212
|
+
await systemService.exportData(res);
|
|
213
|
+
}
|
|
214
|
+
catch (e) {
|
|
215
|
+
return next(e);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
route.put('/data/import', upload.single('data'), async (req, res, next) => {
|
|
219
|
+
try {
|
|
220
|
+
const systemService = typedi_1.Container.get(system_1.default);
|
|
221
|
+
const result = await systemService.importData();
|
|
222
|
+
res.send(result);
|
|
223
|
+
}
|
|
224
|
+
catch (e) {
|
|
225
|
+
return next(e);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
190
228
|
};
|
|
191
229
|
//# sourceMappingURL=system.js.map
|
|
@@ -20,6 +20,7 @@ const lastVersionFile = `https://qn.whyour.cn/version.yaml`;
|
|
|
20
20
|
const rootPath = process.env.QL_DIR;
|
|
21
21
|
const envFound = dotenv_1.default.config({ path: path_1.default.join(rootPath, '.env') });
|
|
22
22
|
let dataPath = path_1.default.join(rootPath, 'data/');
|
|
23
|
+
const tmpPath = path_1.default.join(rootPath, '.tmp/');
|
|
23
24
|
if (process.env.QL_DATA_DIR) {
|
|
24
25
|
dataPath = process.env.QL_DATA_DIR;
|
|
25
26
|
}
|
|
@@ -43,6 +44,7 @@ const authError = '错误的用户名密码,请重试';
|
|
|
43
44
|
const loginFaild = '请先登录!';
|
|
44
45
|
const configString = 'config sample crontab shareCode diy';
|
|
45
46
|
const versionFile = path_1.default.join(rootPath, 'version.yaml');
|
|
47
|
+
const dataTgzFile = path_1.default.join(tmpPath, 'data.tgz');
|
|
46
48
|
if (envFound.error) {
|
|
47
49
|
throw new Error("⚠️ Couldn't find .env file ⚠️");
|
|
48
50
|
}
|
|
@@ -58,6 +60,9 @@ exports.default = {
|
|
|
58
60
|
prefix: '/api',
|
|
59
61
|
},
|
|
60
62
|
rootPath,
|
|
63
|
+
tmpPath,
|
|
64
|
+
dataPath,
|
|
65
|
+
dataTgzFile,
|
|
61
66
|
configString,
|
|
62
67
|
loginFaild,
|
|
63
68
|
authError,
|
|
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.getUniqPath = exports.parseContentVersion = exports.parseVersion = exports.getPid = exports.killTask = exports.psTree = exports.parseBody = exports.parseHeaders = exports.promiseExec = exports.emptyDir = exports.readDir = exports.readDirs = exports.dirSort = exports.concurrentRun = exports.handleLogPath = exports.createFile = exports.fileExist = exports.getPlatform = exports.getNetIp = exports.getToken = exports.createRandomString = exports.getLastModifyFilePath = exports.getFileContentByName = void 0;
|
|
29
|
+
exports.getUniqPath = exports.parseContentVersion = exports.parseVersion = exports.getPid = exports.killTask = exports.psTree = exports.parseBody = exports.parseHeaders = exports.promiseExecSuccess = exports.promiseExec = exports.emptyDir = exports.readDir = exports.readDirs = exports.dirSort = exports.concurrentRun = exports.handleLogPath = exports.createFile = exports.fileExist = exports.getPlatform = exports.getNetIp = exports.getToken = exports.createRandomString = exports.getLastModifyFilePath = exports.getFileContentByName = void 0;
|
|
30
30
|
const fs = __importStar(require("fs"));
|
|
31
31
|
const path = __importStar(require("path"));
|
|
32
32
|
const got_1 = __importDefault(require("got"));
|
|
@@ -391,6 +391,14 @@ function promiseExec(command) {
|
|
|
391
391
|
});
|
|
392
392
|
}
|
|
393
393
|
exports.promiseExec = promiseExec;
|
|
394
|
+
function promiseExecSuccess(command) {
|
|
395
|
+
return new Promise((resolve) => {
|
|
396
|
+
(0, child_process_1.exec)(command, { maxBuffer: 200 * 1024 * 1024, encoding: 'utf8' }, (err, stdout, stderr) => {
|
|
397
|
+
resolve(stdout || '');
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
exports.promiseExecSuccess = promiseExecSuccess;
|
|
394
402
|
function parseHeaders(headers) {
|
|
395
403
|
if (!headers)
|
|
396
404
|
return {};
|
|
@@ -30,9 +30,9 @@ exports.Crontab = Crontab;
|
|
|
30
30
|
var CrontabStatus;
|
|
31
31
|
(function (CrontabStatus) {
|
|
32
32
|
CrontabStatus[CrontabStatus["running"] = 0] = "running";
|
|
33
|
-
CrontabStatus[CrontabStatus["queued"] =
|
|
34
|
-
CrontabStatus[CrontabStatus["idle"] =
|
|
35
|
-
CrontabStatus[CrontabStatus["disabled"] =
|
|
33
|
+
CrontabStatus[CrontabStatus["queued"] = 0.5] = "queued";
|
|
34
|
+
CrontabStatus[CrontabStatus["idle"] = 1] = "idle";
|
|
35
|
+
CrontabStatus[CrontabStatus["disabled"] = 2] = "disabled";
|
|
36
36
|
})(CrontabStatus = exports.CrontabStatus || (exports.CrontabStatus = {}));
|
|
37
37
|
exports.CrontabModel = _1.sequelize.define('Crontab', {
|
|
38
38
|
name: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DependenceModel = exports.unInstallDependenceCommandTypes = exports.InstallDependenceCommandTypes = exports.DependenceTypes = exports.DependenceStatus = exports.Dependence = void 0;
|
|
3
|
+
exports.DependenceModel = exports.unInstallDependenceCommandTypes = exports.versionDependenceCommandTypes = exports.GetDependenceCommandTypes = exports.InstallDependenceCommandTypes = exports.DependenceTypes = exports.DependenceStatus = exports.Dependence = void 0;
|
|
4
4
|
const _1 = require(".");
|
|
5
5
|
const sequelize_1 = require("sequelize");
|
|
6
6
|
class Dependence {
|
|
@@ -12,7 +12,7 @@ class Dependence {
|
|
|
12
12
|
: DependenceStatus.queued;
|
|
13
13
|
this.type = options.type || DependenceTypes.nodejs;
|
|
14
14
|
this.timestamp = new Date().toString();
|
|
15
|
-
this.name = options.name;
|
|
15
|
+
this.name = options.name.trim();
|
|
16
16
|
this.log = options.log || [];
|
|
17
17
|
this.remark = options.remark || '';
|
|
18
18
|
}
|
|
@@ -37,13 +37,25 @@ var DependenceTypes;
|
|
|
37
37
|
var InstallDependenceCommandTypes;
|
|
38
38
|
(function (InstallDependenceCommandTypes) {
|
|
39
39
|
InstallDependenceCommandTypes[InstallDependenceCommandTypes["pnpm add -g"] = 0] = "pnpm add -g";
|
|
40
|
-
InstallDependenceCommandTypes[InstallDependenceCommandTypes["pip3 install"] = 1] = "pip3 install";
|
|
40
|
+
InstallDependenceCommandTypes[InstallDependenceCommandTypes["pip3 install --disable-pip-version-check --root-user-action=ignore"] = 1] = "pip3 install --disable-pip-version-check --root-user-action=ignore";
|
|
41
41
|
InstallDependenceCommandTypes[InstallDependenceCommandTypes["apt install -y"] = 2] = "apt install -y";
|
|
42
42
|
})(InstallDependenceCommandTypes = exports.InstallDependenceCommandTypes || (exports.InstallDependenceCommandTypes = {}));
|
|
43
|
+
var GetDependenceCommandTypes;
|
|
44
|
+
(function (GetDependenceCommandTypes) {
|
|
45
|
+
GetDependenceCommandTypes[GetDependenceCommandTypes["pnpm ls -g "] = 0] = "pnpm ls -g ";
|
|
46
|
+
GetDependenceCommandTypes[GetDependenceCommandTypes["pip3 list --disable-pip-version-check"] = 1] = "pip3 list --disable-pip-version-check";
|
|
47
|
+
GetDependenceCommandTypes[GetDependenceCommandTypes["apk info"] = 2] = "apk info";
|
|
48
|
+
})(GetDependenceCommandTypes = exports.GetDependenceCommandTypes || (exports.GetDependenceCommandTypes = {}));
|
|
49
|
+
var versionDependenceCommandTypes;
|
|
50
|
+
(function (versionDependenceCommandTypes) {
|
|
51
|
+
versionDependenceCommandTypes[versionDependenceCommandTypes["@"] = 0] = "@";
|
|
52
|
+
versionDependenceCommandTypes[versionDependenceCommandTypes["=="] = 1] = "==";
|
|
53
|
+
versionDependenceCommandTypes[versionDependenceCommandTypes["="] = 2] = "=";
|
|
54
|
+
})(versionDependenceCommandTypes = exports.versionDependenceCommandTypes || (exports.versionDependenceCommandTypes = {}));
|
|
43
55
|
var unInstallDependenceCommandTypes;
|
|
44
56
|
(function (unInstallDependenceCommandTypes) {
|
|
45
57
|
unInstallDependenceCommandTypes[unInstallDependenceCommandTypes["pnpm remove -g"] = 0] = "pnpm remove -g";
|
|
46
|
-
unInstallDependenceCommandTypes[unInstallDependenceCommandTypes["pip3 uninstall -y"] = 1] = "pip3 uninstall -y";
|
|
58
|
+
unInstallDependenceCommandTypes[unInstallDependenceCommandTypes["pip3 uninstall --disable-pip-version-check --root-user-action=ignore -y"] = 1] = "pip3 uninstall --disable-pip-version-check --root-user-action=ignore -y";
|
|
47
59
|
unInstallDependenceCommandTypes[unInstallDependenceCommandTypes["apt remove"] = 2] = "apt remove";
|
|
48
60
|
})(unInstallDependenceCommandTypes = exports.unInstallDependenceCommandTypes || (exports.unInstallDependenceCommandTypes = {}));
|
|
49
61
|
exports.DependenceModel = _1.sequelize.define('Dependence', {
|
|
@@ -32,7 +32,7 @@ exports.default = async () => {
|
|
|
32
32
|
}
|
|
33
33
|
});
|
|
34
34
|
// 初始化更新所有任务状态为空闲
|
|
35
|
-
await cron_1.CrontabModel.update({ status: cron_1.CrontabStatus.idle }, { where: {
|
|
35
|
+
await cron_1.CrontabModel.update({ status: cron_1.CrontabStatus.idle }, { where: {} });
|
|
36
36
|
// 初始化时安装所有处于安装中,安装成功,安装失败的依赖
|
|
37
37
|
dependence_2.DependenceModel.findAll({
|
|
38
38
|
where: {},
|
|
@@ -31,15 +31,15 @@ exports.default = async () => {
|
|
|
31
31
|
});
|
|
32
32
|
// 运行删除日志任务
|
|
33
33
|
const data = await systemService.getSystemConfig();
|
|
34
|
-
if (data && data.info && data.info.
|
|
34
|
+
if (data && data.info && data.info.logRemoveFrequency) {
|
|
35
35
|
const rmlogCron = {
|
|
36
36
|
id: data.id,
|
|
37
37
|
name: '删除日志',
|
|
38
|
-
command: `ql rmlog ${data.info.
|
|
38
|
+
command: `ql rmlog ${data.info.logRemoveFrequency}`,
|
|
39
39
|
};
|
|
40
40
|
await scheduleService.cancelIntervalTask(rmlogCron);
|
|
41
41
|
scheduleService.createIntervalTask(rmlogCron, {
|
|
42
|
-
days: data.info.
|
|
42
|
+
days: data.info.logRemoveFrequency,
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
45
|
// 运行所有订阅
|
|
@@ -8,17 +8,32 @@ const sock_1 = __importDefault(require("./sock"));
|
|
|
8
8
|
exports.default = async ({ server }) => {
|
|
9
9
|
await (0, sock_1.default)({ server });
|
|
10
10
|
logger_1.default.info('✌️ Sock loaded');
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
let exitTime = 0;
|
|
12
|
+
let timer;
|
|
13
|
+
process.on('SIGINT', (singal) => {
|
|
14
|
+
logger_1.default.warn(`Server need close, singal ${singal}`);
|
|
15
|
+
exitTime++;
|
|
16
|
+
if (exitTime >= 3) {
|
|
17
|
+
logger_1.default.warn('Forcing server close');
|
|
18
|
+
clearTimeout(timer);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
13
21
|
server.close(() => {
|
|
14
|
-
|
|
22
|
+
if (timer) {
|
|
23
|
+
clearTimeout(timer);
|
|
24
|
+
}
|
|
25
|
+
timer = setTimeout(() => {
|
|
15
26
|
process.exit();
|
|
16
|
-
},
|
|
27
|
+
}, 15000);
|
|
17
28
|
});
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
29
|
+
});
|
|
30
|
+
process.on('uncaughtException', (error) => {
|
|
31
|
+
logger_1.default.error('Uncaught exception:', error);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
});
|
|
34
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
35
|
+
logger_1.default.error('Unhandled rejection:', reason);
|
|
36
|
+
process.exit(1);
|
|
22
37
|
});
|
|
23
38
|
};
|
|
24
39
|
//# sourceMappingURL=server.js.map
|