@whyour/qinglong 2.19.2-2 → 2.20.0-2

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 (112) 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/start.sh +2 -3
  18. package/shell/task.sh +19 -10
  19. package/shell/update.sh +1 -0
  20. package/static/build/api/dependence.js +7 -1
  21. package/static/build/api/env.js +30 -4
  22. package/static/build/api/script.js +48 -8
  23. package/static/build/api/subscription.js +3 -3
  24. package/static/build/api/system.js +19 -26
  25. package/static/build/api/user.js +2 -1
  26. package/static/build/app.js +96 -18
  27. package/static/build/config/index.js +2 -2
  28. package/static/build/config/util.js +24 -1
  29. package/static/build/data/cron.js +4 -0
  30. package/static/build/data/env.js +3 -1
  31. package/static/build/data/notify.js +1 -0
  32. package/static/build/loaders/db.js +29 -35
  33. package/static/build/loaders/deps.js +22 -5
  34. package/static/build/loaders/express.js +19 -10
  35. package/static/build/loaders/initData.js +25 -1
  36. package/static/build/loaders/initTask.js +6 -0
  37. package/static/build/loaders/sock.js +10 -12
  38. package/static/build/protos/api.js +336 -1
  39. package/static/build/schedule/addCron.js +2 -2
  40. package/static/build/schedule/api.js +100 -1
  41. package/static/build/schedule/delCron.js +1 -1
  42. package/static/build/schedule/health.js +2 -3
  43. package/static/build/services/cron.js +54 -20
  44. package/static/build/services/dependence.js +6 -5
  45. package/static/build/services/env.js +9 -2
  46. package/static/build/services/notify.js +17 -5
  47. package/static/build/services/schedule.js +4 -4
  48. package/static/build/services/sshKey.js +24 -4
  49. package/static/build/services/subscription.js +11 -8
  50. package/static/build/services/system.js +15 -0
  51. package/static/build/services/user.js +83 -4
  52. package/static/build/shared/auth.js +40 -0
  53. package/static/build/shared/logStreamManager.js +104 -0
  54. package/static/build/shared/runCron.js +23 -0
  55. package/static/build/validation/schedule.js +39 -2
  56. package/static/dist/1147.856bb861.async.js +1 -0
  57. package/static/dist/1379.f91563a1.async.js +1 -0
  58. package/static/dist/{2208.3bc521b1.async.js → 2208.7bf7e296.async.js} +1 -1
  59. package/static/dist/3191.da7f3e07.async.js +1 -0
  60. package/static/dist/5691.931f59c5.async.js +1 -0
  61. package/static/dist/7571.4f6240b1.async.js +1 -0
  62. package/static/dist/{8826.3ab4ad84.async.js → 8826.5f289c4d.async.js} +1 -1
  63. package/static/dist/index.html +2 -2
  64. package/static/dist/preload_helper.0fb920eb.js +1 -0
  65. package/static/dist/{src__pages__crontab__detail.ee431270.async.js → src__pages__crontab__detail.b07f0c0a.async.js} +1 -1
  66. package/static/dist/src__pages__crontab__index.6b90d8c5.async.js +1 -0
  67. package/static/dist/{src__pages__crontab__logModal.57501983.async.js → src__pages__crontab__logModal.5e6a4bf2.async.js} +1 -1
  68. package/static/dist/src__pages__crontab__modal.2d3d4953.async.js +1 -0
  69. package/static/dist/src__pages__dependence__modal.86604072.async.js +1 -0
  70. package/static/dist/{src__pages__env__editNameModal.665393cd.async.js → src__pages__env__editNameModal.79b7cf83.async.js} +1 -1
  71. package/static/dist/src__pages__env__index.a0a2fece.async.js +1 -0
  72. package/static/dist/{src__pages__env__modal.168498f9.async.js → src__pages__env__modal.b84c1173.async.js} +1 -1
  73. package/static/dist/{src__pages__error__index.d9beeda3.async.js → src__pages__error__index.01fac00e.async.js} +1 -1
  74. package/static/dist/{src__pages__initialization__index.2403c031.async.js → src__pages__initialization__index.2e49cf43.async.js} +1 -1
  75. package/static/dist/src__pages__script__editModal.cbf4ec0e.async.js +1 -0
  76. package/static/dist/{src__pages__script__editNameModal.e36cd111.async.js → src__pages__script__editNameModal.05441c89.async.js} +1 -1
  77. package/static/dist/src__pages__script__index.d6e9cb23.async.js +1 -0
  78. package/static/dist/{src__pages__script__renameModal.f9756f26.async.js → src__pages__script__renameModal.3bb00014.async.js} +1 -1
  79. package/static/dist/src__pages__script__saveModal.8417503a.async.js +1 -0
  80. package/static/dist/{src__pages__script__setting.8c2727b4.async.js → src__pages__script__setting.5a2a2a2c.async.js} +1 -1
  81. package/static/dist/{src__pages__setting__appModal.5a39121e.async.js → src__pages__setting__appModal.7f763fa7.async.js} +1 -1
  82. package/static/dist/src__pages__setting__dependence.e64c4554.async.js +1 -0
  83. package/static/dist/src__pages__setting__index.3a220288.async.js +1 -0
  84. package/static/dist/src__pages__setting__notification.49003b2f.async.js +1 -0
  85. package/static/dist/src__pages__setting__other.0d931d6f.async.js +1 -0
  86. package/static/dist/src__pages__setting__security.a916e056.async.js +1 -0
  87. package/static/dist/{src__pages__setting__systemLog.fc5bdc78.async.js → src__pages__setting__systemLog.cbb0a3bb.async.js} +1 -1
  88. package/static/dist/src__pages__subscription__modal.ade477c1.async.js +1 -0
  89. package/static/dist/umi.e7cba995.js +1 -0
  90. package/version.yaml +46 -9
  91. package/docker/front.conf +0 -61
  92. package/docker/nginx.conf +0 -45
  93. package/static/dist/2995.2eb218b3.async.js +0 -1
  94. package/static/dist/3191.cc1e31cd.async.js +0 -1
  95. package/static/dist/4046.7fbcfa02.async.js +0 -1
  96. package/static/dist/5713.8519f547.async.js +0 -1
  97. package/static/dist/8851.503b1e64.async.js +0 -1
  98. package/static/dist/preload_helper.9c086410.js +0 -1
  99. package/static/dist/src__pages__crontab__index.af4cb04a.async.js +0 -1
  100. package/static/dist/src__pages__crontab__modal.21258e08.async.js +0 -1
  101. package/static/dist/src__pages__dependence__modal.6639424a.async.js +0 -1
  102. package/static/dist/src__pages__env__index.70340ba7.async.js +0 -1
  103. package/static/dist/src__pages__script__editModal.f1741417.async.js +0 -1
  104. package/static/dist/src__pages__script__index.82b42e11.async.js +0 -1
  105. package/static/dist/src__pages__script__saveModal.e885e133.async.js +0 -1
  106. package/static/dist/src__pages__setting__dependence.a46e873d.async.js +0 -1
  107. package/static/dist/src__pages__setting__index.9be4775c.async.js +0 -1
  108. package/static/dist/src__pages__setting__notification.299f6b96.async.js +0 -1
  109. package/static/dist/src__pages__setting__other.60924a56.async.js +0 -1
  110. package/static/dist/src__pages__setting__security.e7371daa.async.js +0 -1
  111. package/static/dist/src__pages__subscription__modal.a7fd6a3c.async.js +0 -1
  112. 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/start.sh CHANGED
@@ -93,16 +93,15 @@ log_with_style() {
93
93
  printf "\n[%s] [%7s] %s\n" "${timestamp}" "${level}" "${message}"
94
94
  }
95
95
 
96
- log_with_style "INFO" "🚀 1. 检测配置文件..."
96
+ log_with_style "INFO" "🚀 1. 检测配置文件..."
97
97
  import_config "$@"
98
98
  make_dir /etc/nginx/conf.d
99
99
  make_dir /run/nginx
100
- init_nginx
101
100
  fix_config
102
101
 
103
102
  pm2 l &>/dev/null
104
103
 
105
- log_with_style "INFO" "🔄 2. 启动 nginx..."
104
+ log_with_style "INFO" "🔄 2. 启动 nginx..."
106
105
  nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf
107
106
 
108
107
  log_with_style "INFO" "⚙️ 3. 启动 pm2 服务..."
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) {
@@ -133,6 +160,7 @@ exports.default = (app) => {
133
160
  originFilename = filename;
134
161
  }
135
162
  const originFilePath = (0, path_1.join)(path, `${originFilename.replace(/\//g, '')}`);
163
+ await fs.mkdir(path, { recursive: true });
136
164
  const filePath = (0, path_1.join)(path, `${filename.replace(/\//g, '')}`);
137
165
  const fileExists = await (0, util_1.fileExist)(filePath);
138
166
  if (fileExists) {
@@ -175,12 +203,15 @@ exports.default = (app) => {
175
203
  route.delete('/', (0, celebrate_1.celebrate)({
176
204
  body: celebrate_1.Joi.object({
177
205
  filename: celebrate_1.Joi.string().required(),
178
- path: celebrate_1.Joi.string().allow(''),
206
+ path: celebrate_1.Joi.string().optional().allow(''),
179
207
  type: celebrate_1.Joi.string().optional(),
180
208
  }),
181
209
  }), async (req, res, next) => {
182
210
  try {
183
211
  let { filename, path } = req.body;
212
+ if (!path) {
213
+ path = '';
214
+ }
184
215
  const scriptService = typedi_1.Container.get(script_1.default);
185
216
  const filePath = scriptService.checkFilePath(path, filename);
186
217
  if (!filePath) {
@@ -235,6 +266,9 @@ exports.default = (app) => {
235
266
  const logger = typedi_1.Container.get('logger');
236
267
  try {
237
268
  let { filename, content, path } = req.body;
269
+ if (!path) {
270
+ path = '';
271
+ }
238
272
  const { name, ext } = (0, path_1.parse)(filename);
239
273
  const filePath = (0, path_1.join)(config_1.default.scriptPath, path, `${name}.swap${ext}`);
240
274
  await (0, utils_1.writeFileWithLock)(filePath, content || '');
@@ -255,6 +289,9 @@ exports.default = (app) => {
255
289
  }), async (req, res, next) => {
256
290
  try {
257
291
  let { filename, path, pid } = req.body;
292
+ if (!path) {
293
+ path = '';
294
+ }
258
295
  const { name, ext } = (0, path_1.parse)(filename);
259
296
  const filePath = (0, path_1.join)(config_1.default.scriptPath, path, `${name}.swap${ext}`);
260
297
  const logPath = (0, path_1.join)(config_1.default.logPath, path, `${name}.swap`);
@@ -277,7 +314,10 @@ exports.default = (app) => {
277
314
  }),
278
315
  }), async (req, res, next) => {
279
316
  try {
280
- let { filename, path, type, newFilename } = req.body;
317
+ let { filename, path, newFilename } = req.body;
318
+ if (!path) {
319
+ path = '';
320
+ }
281
321
  const filePath = (0, path_1.join)(config_1.default.scriptPath, path, filename);
282
322
  const newPath = (0, path_1.join)(config_1.default.scriptPath, path, newFilename);
283
323
  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) {