@whyour/qinglong 2.19.2-2 → 2.20.0-1

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.
Files changed (107) hide show
  1. package/.env.example +1 -2
  2. package/README-en.md +4 -2
  3. package/README.md +4 -2
  4. package/back/protos/api.proto +17 -0
  5. package/docker/310.Dockerfile +23 -6
  6. package/docker/Dockerfile +22 -6
  7. package/docker/docker-entrypoint.sh +27 -14
  8. package/package.json +8 -9
  9. package/sample/notify.js +18 -2
  10. package/sample/notify.py +15 -0
  11. package/sample/ql_sample.js +28 -0
  12. package/shell/api.sh +8 -48
  13. package/shell/check.sh +5 -22
  14. package/shell/preload/client.js +6 -1
  15. package/shell/pub.sh +4 -4
  16. package/shell/share.sh +32 -55
  17. package/shell/task.sh +19 -10
  18. package/shell/update.sh +1 -0
  19. package/static/build/api/dependence.js +7 -1
  20. package/static/build/api/env.js +30 -4
  21. package/static/build/api/script.js +47 -8
  22. package/static/build/api/subscription.js +3 -3
  23. package/static/build/api/system.js +19 -26
  24. package/static/build/api/user.js +2 -1
  25. package/static/build/app.js +96 -18
  26. package/static/build/config/index.js +2 -2
  27. package/static/build/config/util.js +24 -1
  28. package/static/build/data/cron.js +4 -0
  29. package/static/build/data/env.js +3 -1
  30. package/static/build/data/notify.js +1 -0
  31. package/static/build/loaders/db.js +29 -35
  32. package/static/build/loaders/deps.js +22 -5
  33. package/static/build/loaders/express.js +19 -10
  34. package/static/build/loaders/initData.js +25 -1
  35. package/static/build/loaders/initTask.js +6 -0
  36. package/static/build/loaders/sock.js +10 -12
  37. package/static/build/protos/api.js +336 -1
  38. package/static/build/schedule/addCron.js +2 -2
  39. package/static/build/schedule/api.js +100 -1
  40. package/static/build/schedule/delCron.js +1 -1
  41. package/static/build/schedule/health.js +2 -3
  42. package/static/build/services/cron.js +54 -20
  43. package/static/build/services/dependence.js +6 -5
  44. package/static/build/services/env.js +9 -2
  45. package/static/build/services/notify.js +17 -5
  46. package/static/build/services/schedule.js +4 -4
  47. package/static/build/services/sshKey.js +24 -4
  48. package/static/build/services/subscription.js +11 -8
  49. package/static/build/services/system.js +15 -0
  50. package/static/build/services/user.js +83 -4
  51. package/static/build/shared/auth.js +40 -0
  52. package/static/build/shared/logStreamManager.js +104 -0
  53. package/static/build/shared/runCron.js +23 -0
  54. package/static/build/validation/schedule.js +39 -2
  55. package/static/dist/1147.856bb861.async.js +1 -0
  56. package/static/dist/1379.f91563a1.async.js +1 -0
  57. package/static/dist/{2208.3bc521b1.async.js → 2208.7bf7e296.async.js} +1 -1
  58. package/static/dist/3191.da7f3e07.async.js +1 -0
  59. package/static/dist/5691.931f59c5.async.js +1 -0
  60. package/static/dist/7571.4f6240b1.async.js +1 -0
  61. package/static/dist/{8826.3ab4ad84.async.js → 8826.5f289c4d.async.js} +1 -1
  62. package/static/dist/index.html +2 -2
  63. package/static/dist/preload_helper.17d7028f.js +1 -0
  64. package/static/dist/{src__pages__crontab__detail.ee431270.async.js → src__pages__crontab__detail.b07f0c0a.async.js} +1 -1
  65. package/static/dist/src__pages__crontab__index.6b90d8c5.async.js +1 -0
  66. package/static/dist/{src__pages__crontab__logModal.57501983.async.js → src__pages__crontab__logModal.5e6a4bf2.async.js} +1 -1
  67. package/static/dist/src__pages__crontab__modal.2d3d4953.async.js +1 -0
  68. package/static/dist/src__pages__dependence__modal.86604072.async.js +1 -0
  69. package/static/dist/{src__pages__env__editNameModal.665393cd.async.js → src__pages__env__editNameModal.79b7cf83.async.js} +1 -1
  70. package/static/dist/src__pages__env__index.a0a2fece.async.js +1 -0
  71. package/static/dist/{src__pages__env__modal.168498f9.async.js → src__pages__env__modal.b84c1173.async.js} +1 -1
  72. package/static/dist/{src__pages__error__index.d9beeda3.async.js → src__pages__error__index.01fac00e.async.js} +1 -1
  73. package/static/dist/{src__pages__initialization__index.2403c031.async.js → src__pages__initialization__index.2e49cf43.async.js} +1 -1
  74. package/static/dist/{src__pages__script__editNameModal.e36cd111.async.js → src__pages__script__editNameModal.05441c89.async.js} +1 -1
  75. package/static/dist/{src__pages__script__index.82b42e11.async.js → src__pages__script__index.6a23d7b5.async.js} +1 -1
  76. package/static/dist/{src__pages__script__renameModal.f9756f26.async.js → src__pages__script__renameModal.3bb00014.async.js} +1 -1
  77. package/static/dist/{src__pages__script__saveModal.e885e133.async.js → src__pages__script__saveModal.03cc698b.async.js} +1 -1
  78. package/static/dist/{src__pages__script__setting.8c2727b4.async.js → src__pages__script__setting.5a2a2a2c.async.js} +1 -1
  79. package/static/dist/{src__pages__setting__appModal.5a39121e.async.js → src__pages__setting__appModal.7f763fa7.async.js} +1 -1
  80. package/static/dist/src__pages__setting__dependence.e64c4554.async.js +1 -0
  81. package/static/dist/src__pages__setting__index.3a220288.async.js +1 -0
  82. package/static/dist/src__pages__setting__notification.49003b2f.async.js +1 -0
  83. package/static/dist/src__pages__setting__other.0d931d6f.async.js +1 -0
  84. package/static/dist/src__pages__setting__security.a916e056.async.js +1 -0
  85. package/static/dist/{src__pages__setting__systemLog.fc5bdc78.async.js → src__pages__setting__systemLog.cbb0a3bb.async.js} +1 -1
  86. package/static/dist/src__pages__subscription__modal.ade477c1.async.js +1 -0
  87. package/static/dist/umi.ba9d6227.js +1 -0
  88. package/version.yaml +46 -9
  89. package/docker/front.conf +0 -61
  90. package/docker/nginx.conf +0 -45
  91. package/static/dist/2995.2eb218b3.async.js +0 -1
  92. package/static/dist/3191.cc1e31cd.async.js +0 -1
  93. package/static/dist/4046.7fbcfa02.async.js +0 -1
  94. package/static/dist/5713.8519f547.async.js +0 -1
  95. package/static/dist/8851.503b1e64.async.js +0 -1
  96. package/static/dist/preload_helper.9c086410.js +0 -1
  97. package/static/dist/src__pages__crontab__index.af4cb04a.async.js +0 -1
  98. package/static/dist/src__pages__crontab__modal.21258e08.async.js +0 -1
  99. package/static/dist/src__pages__dependence__modal.6639424a.async.js +0 -1
  100. package/static/dist/src__pages__env__index.70340ba7.async.js +0 -1
  101. package/static/dist/src__pages__setting__dependence.a46e873d.async.js +0 -1
  102. package/static/dist/src__pages__setting__index.9be4775c.async.js +0 -1
  103. package/static/dist/src__pages__setting__notification.299f6b96.async.js +0 -1
  104. package/static/dist/src__pages__setting__other.60924a56.async.js +0 -1
  105. package/static/dist/src__pages__setting__security.e7371daa.async.js +0 -1
  106. package/static/dist/src__pages__subscription__modal.a7fd6a3c.async.js +0 -1
  107. package/static/dist/umi.5b8ae363.js +0 -1
@@ -5,7 +5,7 @@ const { join } = require('path');
5
5
  class GrpcClient {
6
6
  static #config = {
7
7
  protoPath: join(process.env.QL_DIR, 'back/protos/api.proto'),
8
- serverAddress: '0.0.0.0:5500',
8
+ serverAddress: `0.0.0.0:${process.env.GRPC_PORT || '5500'}`,
9
9
  protoOptions: {
10
10
  keepCase: true,
11
11
  longs: String,
@@ -33,6 +33,11 @@ class GrpcClient {
33
33
  'createCron',
34
34
  'updateCron',
35
35
  'deleteCrons',
36
+ 'getCrons',
37
+ 'getCronById',
38
+ 'enableCrons',
39
+ 'disableCrons',
40
+ 'runCrons',
36
41
  ];
37
42
 
38
43
  #client;
package/shell/pub.sh CHANGED
@@ -11,16 +11,16 @@ ts-node-transpile-only sample/tool.ts
11
11
 
12
12
  string=$(cat version.yaml | grep "version" | egrep "[^ ]*" -o | egrep "\d\.*")
13
13
  version="v$string"
14
- echo -e "当前版本$version"
14
+ echo -e "当前版本$version-debian"
15
15
 
16
16
  echo -e "删除已经存在的本地tag"
17
- git tag -d "$version" &>/dev/null
17
+ git tag -d "$version-debian" &>/dev/null
18
18
 
19
19
  echo -e "删除已经存在的远程tag"
20
- git push origin :refs/tags/$version &>/dev/null
20
+ git push origin :refs/tags/$version-debian &>/dev/null
21
21
 
22
22
  echo -e "创建新tag"
23
- git tag -a "$version" -m "release $version"
23
+ git tag -a "$version-debian" -m "release $version-debian"
24
24
 
25
25
  echo -e "提交tag"
26
26
  git push --tags
package/shell/share.sh CHANGED
@@ -48,8 +48,6 @@ export file_notify_py=$dir_scripts/notify.py
48
48
  export file_notify_js=$dir_scripts/sendNotify.js
49
49
  export file_test_js=$dir_scripts/ql_sample.js
50
50
  export file_test_py=$dir_scripts/ql_sample.py
51
- export nginx_app_conf=$dir_root/docker/front.conf
52
- export nginx_conf=$dir_root/docker/nginx.conf
53
51
  export dep_notify_py=$dir_dep/notify.py
54
52
  export dep_notify_js=$dir_dep/sendNotify.js
55
53
 
@@ -61,15 +59,10 @@ list_own_user=$dir_list_tmp/own_user.list
61
59
  list_own_add=$dir_list_tmp/own_add.list
62
60
  list_own_drop=$dir_list_tmp/own_drop.list
63
61
 
64
- ## 软连接及其原始文件对应关系
65
62
  link_name=(
66
63
  task
67
64
  ql
68
65
  )
69
- original_name=(
70
- task.sh
71
- update.sh
72
- )
73
66
 
74
67
  init_env() {
75
68
  local pnpm_global_path=$(pnpm root -g 2>/dev/null)
@@ -86,15 +79,20 @@ init_env() {
86
79
  export PYTHONUNBUFFERED=1
87
80
  }
88
81
 
82
+ load_ql_envs() {
83
+ ql_base_url=${QlBaseUrl:-"/"}
84
+ ql_port=${QlPort:-"5700"}
85
+ ql_grpc_port=${QlGrpcPort:-"5500"}
86
+ current_branch=${QL_BRANCH:-""}
87
+ }
88
+
89
89
  import_config() {
90
90
  [[ -f $file_config_user ]] && . $file_config_user
91
91
 
92
- ql_base_url=${QlBaseUrl:-"/"}
93
- ql_port=${QlPort:-"5700"}
92
+ load_ql_envs
94
93
  command_timeout_time=${CommandTimeoutTime:-""}
95
94
  file_extensions=${RepoFileExtensions:-"js py"}
96
95
  proxy_url=${ProxyUrl:-""}
97
- current_branch=${QL_BRANCH:-""}
98
96
 
99
97
  if [[ -n "${DefaultCronRule}" ]]; then
100
98
  default_cron="${DefaultCronRule}"
@@ -211,10 +209,6 @@ fix_config() {
211
209
  cp -f $file_test_py_sample $file_test_py
212
210
  fi
213
211
 
214
- if [[ -s /etc/nginx/conf.d/default.conf ]]; then
215
- cat /dev/null >/etc/nginx/conf.d/default.conf
216
- fi
217
-
218
212
  if [[ ! -s $dep_notify_js ]]; then
219
213
  cp -f $file_notify_js_sample $dep_notify_js
220
214
  fi
@@ -278,14 +272,35 @@ random_range() {
278
272
 
279
273
  delete_pm2() {
280
274
  cd $dir_root
281
- pm2 delete ecosystem.config.js
275
+ # Try to delete PM2 processes, but don't fail if PM2 is not available
276
+ pm2 delete ecosystem.config.js 2>/dev/null || true
277
+ # Also try to kill any directly spawned node processes
278
+ pkill -f "node.*static/build/app.js" 2>/dev/null || true
282
279
  }
283
280
 
284
281
  reload_pm2() {
285
282
  cd $dir_root
286
283
  restore_env_vars
287
- pm2 flush &>/dev/null
288
- pm2 startOrGracefulReload ecosystem.config.js --update-env
284
+
285
+ # Try to start PM2, but handle failures gracefully
286
+ if pm2 flush &>/dev/null && pm2 startOrGracefulReload ecosystem.config.js --update-env; then
287
+ return 0
288
+ else
289
+ local exit_code=$?
290
+ echo "警告: PM2 启动失败 (退出码: $exit_code),可能是由于硬件不兼容"
291
+ echo "正在尝试直接使用 Node.js 启动服务..."
292
+
293
+ # Kill any existing node processes for qinglong
294
+ pkill -f "node.*static/build/app.js" 2>/dev/null || true
295
+
296
+ # Start node directly in the background
297
+ nohup node static/build/app.js > $dir_log/qinglong.log 2>&1 &
298
+ local node_pid=$!
299
+
300
+ echo "已使用 Node.js 直接启动服务 (PID: $node_pid)"
301
+ echo "注意: 使用此模式时,部分 PM2 管理功能将不可用"
302
+ return 0
303
+ fi
289
304
  }
290
305
 
291
306
  diff_time() {
@@ -334,44 +349,6 @@ format_timestamp() {
334
349
  fi
335
350
  }
336
351
 
337
- init_nginx() {
338
- cp -f $nginx_conf /etc/nginx/nginx.conf
339
- cp -f $nginx_app_conf /etc/nginx/conf.d/front.conf
340
- local location_url="/"
341
- local aliasStr=""
342
- local rootStr=""
343
- if [[ $ql_base_url != "/" ]]; then
344
- if [[ $ql_base_url != /* ]]; then
345
- ql_base_url="/$ql_base_url"
346
- fi
347
- if [[ $ql_base_url != */ ]]; then
348
- ql_base_url="$ql_base_url/"
349
- fi
350
- location_url="^~${ql_base_url%*/}"
351
- aliasStr="alias ${dir_static}/dist;"
352
- if ! grep -q "<base href=\"$ql_base_url\">" "${dir_static}/dist/index.html"; then
353
- awk -v text="<base href=\"$ql_base_url\">" '/<link/ && !inserted {print text; inserted=1} 1' "${dir_static}/dist/index.html" >temp.html
354
- mv temp.html "${dir_static}/dist/index.html"
355
- fi
356
- else
357
- rootStr="root ${dir_static}/dist;"
358
- fi
359
- sed -i "s,QL_ALIAS_CONFIG,${aliasStr},g" /etc/nginx/conf.d/front.conf
360
- sed -i "s,QL_ROOT_CONFIG,${rootStr},g" /etc/nginx/conf.d/front.conf
361
- sed -i "s,QL_BASE_URL_LOCATION,${location_url},g" /etc/nginx/conf.d/front.conf
362
- sed -i "s,QL_BASE_URL,${ql_base_url},g" /etc/nginx/conf.d/front.conf
363
-
364
- local ipv6=$(ip a | grep inet6)
365
- local ipv6Str=""
366
- if [[ $ipv6 ]]; then
367
- ipv6Str="listen [::]:${ql_port} ipv6only=on;"
368
- fi
369
-
370
- local ipv4Str="listen ${ql_port};"
371
- sed -i "s,IPV6_CONFIG,${ipv6Str},g" /etc/nginx/conf.d/front.conf
372
- sed -i "s,IPV4_CONFIG,${ipv4Str},g" /etc/nginx/conf.d/front.conf
373
- }
374
-
375
352
  get_env_array() {
376
353
  exported_variables=()
377
354
  while IFS= read -r line; do
package/shell/task.sh CHANGED
@@ -46,18 +46,22 @@ handle_log_path() {
46
46
 
47
47
  time=$(date "+$mtime_format")
48
48
  log_time=$(format_log_time "$mtime_format" "$time")
49
- log_dir_tmp="${file_param##*/}"
50
- if [[ $file_param =~ "/" ]]; then
51
- if [[ $file_param == /* ]]; then
52
- log_dir_tmp_path="${file_param:1}"
53
- else
54
- log_dir_tmp_path="${file_param}"
49
+ if [[ -z $log_name ]]; then
50
+ log_dir_tmp="${file_param##*/}"
51
+ if [[ $file_param =~ "/" ]]; then
52
+ if [[ $file_param == /* ]]; then
53
+ log_dir_tmp_path="${file_param:1}"
54
+ else
55
+ log_dir_tmp_path="${file_param}"
56
+ fi
55
57
  fi
58
+ log_dir_tmp_path="${log_dir_tmp_path%/*}"
59
+ log_dir_tmp_path="${log_dir_tmp_path##*/}"
60
+ [[ $log_dir_tmp_path ]] && log_dir_tmp="${log_dir_tmp_path}_${log_dir_tmp}"
61
+ log_dir="${log_dir_tmp%.*}${suffix}"
62
+ else
63
+ log_dir="$log_name"
56
64
  fi
57
- log_dir_tmp_path="${log_dir_tmp_path%/*}"
58
- log_dir_tmp_path="${log_dir_tmp_path##*/}"
59
- [[ $log_dir_tmp_path ]] && log_dir_tmp="${log_dir_tmp_path}_${log_dir_tmp}"
60
- log_dir="${log_dir_tmp%.*}${suffix}"
61
65
  log_path="$log_dir/$log_time.log"
62
66
 
63
67
  if [[ ${real_log_path:=} ]]; then
@@ -73,6 +77,11 @@ handle_log_path() {
73
77
  if [[ "${real_time:=}" == "true" ]]; then
74
78
  cmd=""
75
79
  fi
80
+
81
+ if [[ "${log_dir:=}" == "/dev/null" ]]; then
82
+ cmd=">> /dev/null"
83
+ log_path="/dev/null"
84
+ fi
76
85
  }
77
86
 
78
87
  format_params() {
package/shell/update.sh CHANGED
@@ -3,6 +3,7 @@
3
3
  dir_shell=$QL_DIR/shell
4
4
  . $dir_shell/share.sh
5
5
  . $dir_shell/api.sh
6
+ load_ql_envs
6
7
  . $dir_shell/env.sh
7
8
 
8
9
  send_mark=$dir_shell/send_mark
@@ -10,7 +10,13 @@ const celebrate_1 = require("celebrate");
10
10
  const route = (0, express_1.Router)();
11
11
  exports.default = (app) => {
12
12
  app.use('/dependencies', route);
13
- route.get('/', async (req, res, next) => {
13
+ route.get('/', (0, celebrate_1.celebrate)({
14
+ query: celebrate_1.Joi.object({
15
+ searchValue: celebrate_1.Joi.string().optional().allow(''),
16
+ type: celebrate_1.Joi.string().optional().allow(''),
17
+ status: celebrate_1.Joi.string().optional().allow(''),
18
+ }),
19
+ }), async (req, res, next) => {
14
20
  const logger = typedi_1.Container.get('logger');
15
21
  try {
16
22
  const dependenceService = typedi_1.Container.get(dependence_1.default);
@@ -3,14 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const express_1 = require("express");
7
- const typedi_1 = require("typedi");
8
- const env_1 = __importDefault(require("../services/env"));
9
6
  const celebrate_1 = require("celebrate");
7
+ const express_1 = require("express");
8
+ const fs_1 = __importDefault(require("fs"));
10
9
  const multer_1 = __importDefault(require("multer"));
10
+ const typedi_1 = require("typedi");
11
11
  const config_1 = __importDefault(require("../config"));
12
- const fs_1 = __importDefault(require("fs"));
13
12
  const util_1 = require("../config/util");
13
+ const env_1 = __importDefault(require("../services/env"));
14
14
  const route = (0, express_1.Router)();
15
15
  const storage = multer_1.default.diskStorage({
16
16
  destination: function (req, file, cb) {
@@ -164,6 +164,32 @@ exports.default = (app) => {
164
164
  return next(e);
165
165
  }
166
166
  });
167
+ route.put('/pin', (0, celebrate_1.celebrate)({
168
+ body: celebrate_1.Joi.array().items(celebrate_1.Joi.number().required()),
169
+ }), async (req, res, next) => {
170
+ const logger = typedi_1.Container.get('logger');
171
+ try {
172
+ const envService = typedi_1.Container.get(env_1.default);
173
+ const data = await envService.pin(req.body);
174
+ return res.send({ code: 200, data });
175
+ }
176
+ catch (e) {
177
+ return next(e);
178
+ }
179
+ });
180
+ route.put('/unpin', (0, celebrate_1.celebrate)({
181
+ body: celebrate_1.Joi.array().items(celebrate_1.Joi.number().required()),
182
+ }), async (req, res, next) => {
183
+ const logger = typedi_1.Container.get('logger');
184
+ try {
185
+ const envService = typedi_1.Container.get(env_1.default);
186
+ const data = await envService.unPin(req.body);
187
+ return res.send({ code: 200, data });
188
+ }
189
+ catch (e) {
190
+ return next(e);
191
+ }
192
+ });
167
193
  route.post('/upload', upload.single('env'), async (req, res, next) => {
168
194
  const logger = typedi_1.Container.get('logger');
169
195
  try {
@@ -48,7 +48,11 @@ const storage = multer_1.default.diskStorage({
48
48
  const upload = (0, multer_1.default)({ storage: storage });
49
49
  exports.default = (app) => {
50
50
  app.use('/scripts', route);
51
- route.get('/', async (req, res, next) => {
51
+ route.get('/', (0, celebrate_1.celebrate)({
52
+ query: celebrate_1.Joi.object({
53
+ path: celebrate_1.Joi.string().optional().allow(''),
54
+ }),
55
+ }), async (req, res, next) => {
52
56
  const logger = typedi_1.Container.get('logger');
53
57
  try {
54
58
  let result = [];
@@ -83,27 +87,50 @@ exports.default = (app) => {
83
87
  return next(e);
84
88
  }
85
89
  });
86
- route.get('/detail', async (req, res, next) => {
90
+ route.get('/detail', (0, celebrate_1.celebrate)({
91
+ query: celebrate_1.Joi.object({
92
+ path: celebrate_1.Joi.string().optional().allow(''),
93
+ file: celebrate_1.Joi.string().required(),
94
+ }),
95
+ }), async (req, res, next) => {
96
+ var _a;
87
97
  try {
88
98
  const scriptService = typedi_1.Container.get(script_1.default);
89
- const content = await scriptService.getFile(req.query.path, req.query.file);
99
+ const content = await scriptService.getFile(((_a = req.query) === null || _a === void 0 ? void 0 : _a.path) || '', req.query.file);
90
100
  res.send({ code: 200, data: content });
91
101
  }
92
102
  catch (e) {
93
103
  return next(e);
94
104
  }
95
105
  });
96
- route.get('/:file', async (req, res, next) => {
106
+ route.get('/:file', (0, celebrate_1.celebrate)({
107
+ params: celebrate_1.Joi.object({
108
+ file: celebrate_1.Joi.string().required(),
109
+ }),
110
+ query: celebrate_1.Joi.object({
111
+ path: celebrate_1.Joi.string().optional().allow(''),
112
+ }),
113
+ }), async (req, res, next) => {
114
+ var _a;
97
115
  try {
98
116
  const scriptService = typedi_1.Container.get(script_1.default);
99
- const content = await scriptService.getFile(req.query.path, req.params.file);
117
+ const content = await scriptService.getFile(((_a = req.query) === null || _a === void 0 ? void 0 : _a.path) || '', req.params.file);
100
118
  res.send({ code: 200, data: content });
101
119
  }
102
120
  catch (e) {
103
121
  return next(e);
104
122
  }
105
123
  });
106
- route.post('/', upload.single('file'), async (req, res, next) => {
124
+ route.post('/', upload.single('file'), (0, celebrate_1.celebrate)({
125
+ body: celebrate_1.Joi.object({
126
+ filename: celebrate_1.Joi.string().required(),
127
+ path: celebrate_1.Joi.string().optional().allow(''),
128
+ content: celebrate_1.Joi.string().optional().allow(''),
129
+ originFilename: celebrate_1.Joi.string().optional().allow(''),
130
+ directory: celebrate_1.Joi.string().optional().allow(''),
131
+ file: celebrate_1.Joi.string().optional().allow(''),
132
+ }),
133
+ }), async (req, res, next) => {
107
134
  try {
108
135
  let { filename, path, content, originFilename, directory } = req.body;
109
136
  if (!path) {
@@ -175,12 +202,15 @@ exports.default = (app) => {
175
202
  route.delete('/', (0, celebrate_1.celebrate)({
176
203
  body: celebrate_1.Joi.object({
177
204
  filename: celebrate_1.Joi.string().required(),
178
- path: celebrate_1.Joi.string().allow(''),
205
+ path: celebrate_1.Joi.string().optional().allow(''),
179
206
  type: celebrate_1.Joi.string().optional(),
180
207
  }),
181
208
  }), async (req, res, next) => {
182
209
  try {
183
210
  let { filename, path } = req.body;
211
+ if (!path) {
212
+ path = '';
213
+ }
184
214
  const scriptService = typedi_1.Container.get(script_1.default);
185
215
  const filePath = scriptService.checkFilePath(path, filename);
186
216
  if (!filePath) {
@@ -235,6 +265,9 @@ exports.default = (app) => {
235
265
  const logger = typedi_1.Container.get('logger');
236
266
  try {
237
267
  let { filename, content, path } = req.body;
268
+ if (!path) {
269
+ path = '';
270
+ }
238
271
  const { name, ext } = (0, path_1.parse)(filename);
239
272
  const filePath = (0, path_1.join)(config_1.default.scriptPath, path, `${name}.swap${ext}`);
240
273
  await (0, utils_1.writeFileWithLock)(filePath, content || '');
@@ -255,6 +288,9 @@ exports.default = (app) => {
255
288
  }), async (req, res, next) => {
256
289
  try {
257
290
  let { filename, path, pid } = req.body;
291
+ if (!path) {
292
+ path = '';
293
+ }
258
294
  const { name, ext } = (0, path_1.parse)(filename);
259
295
  const filePath = (0, path_1.join)(config_1.default.scriptPath, path, `${name}.swap${ext}`);
260
296
  const logPath = (0, path_1.join)(config_1.default.logPath, path, `${name}.swap`);
@@ -277,7 +313,10 @@ exports.default = (app) => {
277
313
  }),
278
314
  }), async (req, res, next) => {
279
315
  try {
280
- let { filename, path, type, newFilename } = req.body;
316
+ let { filename, path, newFilename } = req.body;
317
+ if (!path) {
318
+ path = '';
319
+ }
281
320
  const filePath = (0, path_1.join)(config_1.default.scriptPath, path, filename);
282
321
  const newPath = (0, path_1.join)(config_1.default.scriptPath, path, newFilename);
283
322
  await fs.rename(filePath, newPath);
@@ -7,7 +7,7 @@ const express_1 = require("express");
7
7
  const typedi_1 = require("typedi");
8
8
  const subscription_1 = __importDefault(require("../services/subscription"));
9
9
  const celebrate_1 = require("celebrate");
10
- const cron_parser_1 = __importDefault(require("cron-parser"));
10
+ const cron_parser_1 = require("cron-parser");
11
11
  const route = (0, express_1.Router)();
12
12
  exports.default = (app) => {
13
13
  app.use('/subscriptions', route);
@@ -55,7 +55,7 @@ exports.default = (app) => {
55
55
  const logger = typedi_1.Container.get('logger');
56
56
  try {
57
57
  if (!req.body.schedule ||
58
- cron_parser_1.default.parseExpression(req.body.schedule).hasNext()) {
58
+ cron_parser_1.CronExpressionParser.parse(req.body.schedule).hasNext()) {
59
59
  const subscriptionService = typedi_1.Container.get(subscription_1.default);
60
60
  const data = await subscriptionService.create(req.body);
61
61
  return res.send({ code: 200, data });
@@ -163,7 +163,7 @@ exports.default = (app) => {
163
163
  try {
164
164
  if (!req.body.schedule ||
165
165
  typeof req.body.schedule === 'object' ||
166
- cron_parser_1.default.parseExpression(req.body.schedule).hasNext()) {
166
+ cron_parser_1.CronExpressionParser.parse(req.body.schedule).hasNext()) {
167
167
  const subscriptionService = typedi_1.Container.get(subscription_1.default);
168
168
  const data = await subscriptionService.update(req.body);
169
169
  return res.send({ code: 200, data });
@@ -1,34 +1,10 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
4
  };
28
5
  Object.defineProperty(exports, "__esModule", { value: true });
29
6
  const express_1 = require("express");
30
7
  const typedi_1 = require("typedi");
31
- const fs = __importStar(require("fs/promises"));
32
8
  const config_1 = __importDefault(require("../config"));
33
9
  const system_1 = __importDefault(require("../services/system"));
34
10
  const celebrate_1 = require("celebrate");
@@ -36,6 +12,7 @@ const user_1 = __importDefault(require("../services/user"));
36
12
  const util_1 = require("../config/util");
37
13
  const dayjs_1 = __importDefault(require("dayjs"));
38
14
  const multer_1 = __importDefault(require("multer"));
15
+ const logStreamManager_1 = require("../shared/logStreamManager");
39
16
  const route = (0, express_1.Router)();
40
17
  const storage = multer_1.default.diskStorage({
41
18
  destination: function (req, file, cb) {
@@ -245,17 +222,19 @@ exports.default = (app) => {
245
222
  res.setHeader('QL-Task-Log', `${logPath}`);
246
223
  },
247
224
  onEnd: async (cp, endTime, diff) => {
225
+ // Close the stream after task completion
226
+ await logStreamManager_1.logStreamManager.closeStream(await (0, util_1.handleLogPath)(logPath));
248
227
  res.end();
249
228
  },
250
229
  onError: async (message) => {
251
230
  res.write(message);
252
231
  const absolutePath = await (0, util_1.handleLogPath)(logPath);
253
- await fs.appendFile(absolutePath, message);
232
+ await logStreamManager_1.logStreamManager.write(absolutePath, message);
254
233
  },
255
234
  onLog: async (message) => {
256
235
  res.write(message);
257
236
  const absolutePath = await (0, util_1.handleLogPath)(logPath);
258
- await fs.appendFile(absolutePath, message);
237
+ await logStreamManager_1.logStreamManager.write(absolutePath, message);
259
238
  },
260
239
  });
261
240
  }
@@ -357,6 +336,20 @@ exports.default = (app) => {
357
336
  return next(e);
358
337
  }
359
338
  });
339
+ route.put('/config/global-ssh-key', (0, celebrate_1.celebrate)({
340
+ body: celebrate_1.Joi.object({
341
+ globalSshKey: celebrate_1.Joi.string().allow('').allow(null),
342
+ }),
343
+ }), async (req, res, next) => {
344
+ try {
345
+ const systemService = typedi_1.Container.get(system_1.default);
346
+ const result = await systemService.updateGlobalSshKey(req.body);
347
+ res.send(result);
348
+ }
349
+ catch (e) {
350
+ return next(e);
351
+ }
352
+ });
360
353
  route.put('/config/dependence-clean', (0, celebrate_1.celebrate)({
361
354
  body: celebrate_1.Joi.object({
362
355
  type: celebrate_1.Joi.string().allow(''),
@@ -50,7 +50,8 @@ exports.default = (app) => {
50
50
  const logger = typedi_1.Container.get('logger');
51
51
  try {
52
52
  const userService = typedi_1.Container.get(user_1.default);
53
- await userService.logout(req.platform);
53
+ const token = (0, util_1.getToken)(req);
54
+ await userService.logout(req.platform, token);
54
55
  res.send({ code: 200 });
55
56
  }
56
57
  catch (e) {