@whyour/qinglong 2.20.2-3 → 2.21.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.
Files changed (218) hide show
  1. package/.env.example +5 -0
  2. package/AGENTS.md +43 -0
  3. package/CLAUDE.md +43 -0
  4. package/README-en.md +11 -0
  5. package/README.md +11 -0
  6. package/docker/Dockerfile +51 -69
  7. package/docker/Dockerfile.310 +94 -0
  8. package/docker/Dockerfile.debian +120 -0
  9. package/docker/{310.Dockerfile → Dockerfile.debian310} +13 -5
  10. package/docker/docker-entrypoint.sh +95 -3
  11. package/docs/PROJECT_ARCHITECTURE.md +550 -0
  12. package/package.json +28 -25
  13. package/sample/config.sample.sh +12 -1
  14. package/sample/notify.js +81 -9
  15. package/sample/notify.py +54 -11
  16. package/shell/api.sh +44 -20
  17. package/shell/bot.sh +30 -16
  18. package/shell/check.sh +21 -19
  19. package/shell/lang/en.sh +105 -0
  20. package/shell/lang/zh.sh +105 -0
  21. package/shell/otask.sh +114 -28
  22. package/shell/preload/client.js +20 -2
  23. package/shell/preload/esm-loader.mjs +41 -0
  24. package/shell/preload/sitecustomize.js +36 -0
  25. package/shell/pub.sh +8 -8
  26. package/shell/rmlog.sh +5 -5
  27. package/shell/share.sh +49 -30
  28. package/shell/start.sh +40 -27
  29. package/shell/task.sh +10 -2
  30. package/shell/update.sh +22 -22
  31. package/static/build/api/config.js +17 -7
  32. package/static/build/api/cron.js +38 -1
  33. package/static/build/api/dashboard.js +337 -0
  34. package/static/build/api/env.js +40 -2
  35. package/static/build/api/index.js +2 -0
  36. package/static/build/api/log.js +5 -4
  37. package/static/build/api/script.js +34 -9
  38. package/static/build/api/system.js +16 -1
  39. package/static/build/api/user.js +6 -5
  40. package/static/build/app.js +3 -0
  41. package/static/build/config/const.js +7 -6
  42. package/static/build/config/container.js +12 -0
  43. package/static/build/config/grpcCerts.js +150 -0
  44. package/static/build/config/index.js +6 -0
  45. package/static/build/config/util.js +66 -15
  46. package/static/build/data/cron.js +3 -1
  47. package/static/build/data/cronStats.js +59 -0
  48. package/static/build/data/env.js +2 -0
  49. package/static/build/data/notify.js +11 -1
  50. package/static/build/data/runningInstance.js +57 -0
  51. package/static/build/loaders/app.js +1 -1
  52. package/static/build/loaders/db.js +6 -0
  53. package/static/build/loaders/express.js +2 -1
  54. package/static/build/loaders/initData.js +19 -2
  55. package/static/build/loaders/initFile.js +2 -0
  56. package/static/build/schedule/api.js +1 -1
  57. package/static/build/schedule/client.js +9 -1
  58. package/static/build/schedule/health.js +1 -1
  59. package/static/build/services/config.js +19 -5
  60. package/static/build/services/cron.js +118 -8
  61. package/static/build/services/env.js +31 -3
  62. package/static/build/services/grpc.js +32 -6
  63. package/static/build/services/http.js +33 -18
  64. package/static/build/services/notify.js +40 -3
  65. package/static/build/services/open.js +2 -1
  66. package/static/build/services/sshKey.js +6 -3
  67. package/static/build/services/subscription.js +2 -1
  68. package/static/build/services/system.js +22 -7
  69. package/static/build/services/user.js +8 -7
  70. package/static/build/shared/i18n.js +105 -0
  71. package/static/build/shared/pLimit.js +12 -1
  72. package/static/build/shared/runCron.js +5 -0
  73. package/static/build/validation/schedule.js +1 -0
  74. package/static/dist/1089.0ecc5383.async.js +1 -0
  75. package/static/dist/1147.c420132e.async.js +1 -0
  76. package/static/dist/1192.4e5740f2.async.js +1 -0
  77. package/static/dist/1214.c6469b53.async.js +1 -0
  78. package/static/dist/134.54df9e38.async.js +1 -0
  79. package/static/dist/1352.96a77e1d.async.js +1 -0
  80. package/static/dist/{1765.d8e002d7.async.js → 1765.5ac01a93.async.js} +1 -1
  81. package/static/dist/1836.f0b74cf1.async.js +1 -0
  82. package/static/dist/{1885.e0d00d2d.async.js → 1885.e1ea09f6.async.js} +1 -1
  83. package/static/dist/1967.3f3945d0.async.js +1 -0
  84. package/static/dist/{2096.383c1047.async.js → 2096.6d98fd12.async.js} +1 -1
  85. package/static/dist/2208.f7ba3dfa.async.js +1 -0
  86. package/static/dist/2286.164bb089.async.js +1 -0
  87. package/static/dist/2476.4e9b0992.async.js +1 -0
  88. package/static/dist/2537.2b262ee0.async.js +1 -0
  89. package/static/dist/{255.12f03ab2.async.js → 255.8a80b983.async.js} +1 -1
  90. package/static/dist/2635.d4c59d23.async.js +1 -0
  91. package/static/dist/2808.cdc0995c.async.js +1 -0
  92. package/static/dist/{2821.be3dc88e.async.js → 2821.651f31e5.async.js} +1 -1
  93. package/static/dist/2986.4c49eef7.async.js +1 -0
  94. package/static/dist/300.08ac9875.async.js +1 -0
  95. package/static/dist/{3191.70bc19db.async.js → 3191.63263871.async.js} +1 -1
  96. package/static/dist/3714.8d6dba9e.async.js +1 -0
  97. package/static/dist/3906.a5eee612.async.js +1 -0
  98. package/static/dist/{6541.a6d499de.async.js → 3948.4fe809fd.async.js} +1 -1
  99. package/static/dist/{5171.7fc6d0a2.async.js → 4573.16f19278.async.js} +1 -1
  100. package/static/dist/{4859.93e63ea6.async.js → 4859.6592cebb.async.js} +1 -1
  101. package/static/dist/4887.8e3ae573.async.js +1 -0
  102. package/static/dist/{4902.54ecbdb5.async.js → 4902.555f92ab.async.js} +1 -1
  103. package/static/dist/{4934.1ca6b6b0.async.js → 4934.f3539d08.async.js} +1 -1
  104. package/static/dist/5077.cbd111cd.async.js +1 -0
  105. package/static/dist/{6247.b550d996.async.js → 5157.7c5af144.async.js} +1 -1
  106. package/static/dist/{540.481d4708.async.js → 540.19ddf020.async.js} +1 -1
  107. package/static/dist/{5970.10ac4f16.async.js → 5970.d3a6e7bd.async.js} +1 -1
  108. package/static/dist/{6013.2d7bb12a.async.js → 6013.4e38de36.async.js} +1 -1
  109. package/static/dist/{6016.9c379049.async.js → 6016.1e6574b6.async.js} +1 -1
  110. package/static/dist/{6035.5889ddc7.async.js → 6035.32ebfad9.async.js} +1 -1
  111. package/static/dist/6339.ab305e96.async.js +1 -0
  112. package/static/dist/6569.55177f6a.async.js +1 -0
  113. package/static/dist/6610.c111af7e.async.js +1 -0
  114. package/static/dist/{3034.6413c38e.async.js → 6638.87a163d2.async.js} +1 -1
  115. package/static/dist/{6646.5fc37228.async.js → 6646.95e92533.async.js} +1 -1
  116. package/static/dist/6665.1d099ad1.async.js +1 -0
  117. package/static/dist/{7355.b7c0562f.async.js → 7355.f9f263d8.async.js} +1 -1
  118. package/static/dist/{7384.065ccae2.async.js → 7384.1bb449d5.async.js} +1 -1
  119. package/static/dist/7441.ee1bf2bb.async.js +1 -0
  120. package/static/dist/{7508.a31662a3.async.js → 7508.7dcee91c.async.js} +1 -1
  121. package/static/dist/{7802.6b73f16a.async.js → 7802.34255805.async.js} +1 -1
  122. package/static/dist/{7984.e6bb9378.async.js → 7984.594296a5.async.js} +1 -1
  123. package/static/dist/{5653.4fce7ce8.async.js → 8033.5cb31493.async.js} +1 -1
  124. package/static/dist/8147.2fb55202.async.js +1 -0
  125. package/static/dist/8187.48c130d6.async.js +1 -0
  126. package/static/dist/8495.d53e15ca.async.js +1 -0
  127. package/static/dist/8587.315b06c0.async.js +1 -0
  128. package/static/dist/8826.2447a104.async.js +1 -0
  129. package/static/dist/{2742.4852aac8.async.js → 8865.ed665d31.async.js} +1 -1
  130. package/static/dist/901.7ee5c6d3.async.js +1 -0
  131. package/static/dist/9271.231db2ce.async.js +1 -0
  132. package/static/dist/9323.a33f47da.async.js +1 -0
  133. package/static/dist/{9730.30083c91.async.js → 9730.801665a3.async.js} +1 -1
  134. package/static/dist/{9761.627ca3b5.async.js → 9761.360a19d8.async.js} +1 -1
  135. package/static/dist/index.html +2 -2
  136. package/static/dist/layouts__index.a7a2bfe0.async.js +1 -0
  137. package/static/dist/layouts__index.adf0692f.chunk.css +1 -0
  138. package/static/dist/preload_helper.0431c0f3.js +1 -0
  139. package/static/dist/{src__pages__config__index.622b6ee8.async.js → src__pages__config__index.a22ff7dc.async.js} +1 -1
  140. package/static/dist/{src__pages__crontab__const.323d5124.async.js → src__pages__crontab__const.aba07deb.async.js} +1 -1
  141. package/static/dist/src__pages__crontab__detail.b9c36808.async.js +1 -0
  142. package/static/dist/src__pages__crontab__index.fed99fd0.async.js +1 -0
  143. package/static/dist/{src__pages__crontab__logModal.5e6a4bf2.async.js → src__pages__crontab__logModal.0b8cce8c.async.js} +1 -1
  144. package/static/dist/src__pages__crontab__modal.f7041c7c.async.js +1 -0
  145. package/static/dist/src__pages__crontab__type.d7af36e5.async.js +1 -0
  146. package/static/dist/{src__pages__crontab__viewCreateModal.ffcf7a24.async.js → src__pages__crontab__viewCreateModal.4d589f66.async.js} +1 -1
  147. package/static/dist/{src__pages__crontab__viewManageModal.c2724575.async.js → src__pages__crontab__viewManageModal.0e317746.async.js} +1 -1
  148. package/static/dist/src__pages__dashboard__index.b30f2f47.async.js +1 -0
  149. package/static/dist/{src__pages__dependence__logModal.f123e2ac.async.js → src__pages__dependence__logModal.0681830b.async.js} +1 -1
  150. package/static/dist/src__pages__dependence__modal.11124896.async.js +1 -0
  151. package/static/dist/src__pages__env__editNameModal.5d264b25.async.js +1 -0
  152. package/static/dist/src__pages__env__index.baa27d4e.async.js +1 -0
  153. package/static/dist/src__pages__env__modal.7f2ef1bc.async.js +1 -0
  154. package/static/dist/src__pages__error__index.f156b45e.async.js +1 -0
  155. package/static/dist/src__pages__initialization__index.e96d4ba8.async.js +1 -0
  156. package/static/dist/{src__pages__log__index.cf00c9af.async.js → src__pages__log__index.e0978bae.async.js} +1 -1
  157. package/static/dist/{src__pages__login__index.cd6e3152.async.js → src__pages__login__index.8c813eb1.async.js} +1 -1
  158. package/static/dist/{src__pages__script__components__UnsupportedFilePreview__index.39074c68.async.js → src__pages__script__components__UnsupportedFilePreview__index.c347a13a.async.js} +1 -1
  159. package/static/dist/src__pages__script__editNameModal.3e7e100d.async.js +1 -0
  160. package/static/dist/src__pages__script__index.2765d1b8.async.js +1 -0
  161. package/static/dist/src__pages__script__renameModal.5e987ef5.async.js +1 -0
  162. package/static/dist/src__pages__script__saveModal.3f9d23d6.async.js +1 -0
  163. package/static/dist/src__pages__script__setting.a535793a.async.js +1 -0
  164. package/static/dist/src__pages__setting__appModal.251cd14f.async.js +1 -0
  165. package/static/dist/src__pages__setting__dependence.8a7a9529.async.js +1 -0
  166. package/static/dist/src__pages__setting__index.cc85fdfb.async.js +1 -0
  167. package/static/dist/src__pages__setting__notification.390fc905.async.js +1 -0
  168. package/static/dist/src__pages__setting__other.b22d2165.async.js +1 -0
  169. package/static/dist/src__pages__setting__security.598720a8.async.js +1 -0
  170. package/static/dist/src__pages__setting__systemLog.67406721.async.js +1 -0
  171. package/static/dist/{src__pages__subscription__logModal.0caa7283.async.js → src__pages__subscription__logModal.3864b37f.async.js} +1 -1
  172. package/static/dist/src__pages__subscription__modal.3562c670.async.js +1 -0
  173. package/static/dist/{umi.ef8199a4.js → umi.ca04a019.js} +1 -1
  174. package/version.yaml +33 -4
  175. package/sample/notify.py.save +0 -1010
  176. package/static/dist/105.85a5c47a.async.js +0 -1
  177. package/static/dist/1083.f86ce804.async.js +0 -1
  178. package/static/dist/1147.32f41a88.async.js +0 -1
  179. package/static/dist/1352.ab6da08e.async.js +0 -1
  180. package/static/dist/1690.f0290540.async.js +0 -1
  181. package/static/dist/1742.6cbe5aca.async.js +0 -1
  182. package/static/dist/2208.8e3a7325.async.js +0 -1
  183. package/static/dist/5312.74b95311.async.js +0 -1
  184. package/static/dist/5691.931f59c5.async.js +0 -1
  185. package/static/dist/6159.55cb068a.async.js +0 -1
  186. package/static/dist/7025.f4080d63.async.js +0 -1
  187. package/static/dist/739.6be5552a.async.js +0 -1
  188. package/static/dist/7571.4f6240b1.async.js +0 -1
  189. package/static/dist/786.59fc381c.async.js +0 -1
  190. package/static/dist/8317.c44c1ebd.async.js +0 -1
  191. package/static/dist/8826.0291edfd.async.js +0 -1
  192. package/static/dist/955.3c9481f7.async.js +0 -1
  193. package/static/dist/layouts__index.1fce90e0.chunk.css +0 -1
  194. package/static/dist/layouts__index.8dcf1576.async.js +0 -1
  195. package/static/dist/preload_helper.116a62f6.js +0 -1
  196. package/static/dist/src__pages__crontab__detail.b07f0c0a.async.js +0 -1
  197. package/static/dist/src__pages__crontab__index.2e2e1096.async.js +0 -1
  198. package/static/dist/src__pages__crontab__modal.4d8c2a22.async.js +0 -1
  199. package/static/dist/src__pages__crontab__type.db7c1858.async.js +0 -1
  200. package/static/dist/src__pages__dependence__modal.631ffb5b.async.js +0 -1
  201. package/static/dist/src__pages__env__editNameModal.ff85ef8c.async.js +0 -1
  202. package/static/dist/src__pages__env__index.a0a2fece.async.js +0 -1
  203. package/static/dist/src__pages__env__modal.d1004662.async.js +0 -1
  204. package/static/dist/src__pages__error__index.1bc3c90b.async.js +0 -1
  205. package/static/dist/src__pages__initialization__index.8b1cbaf9.async.js +0 -1
  206. package/static/dist/src__pages__script__editNameModal.53424d49.async.js +0 -1
  207. package/static/dist/src__pages__script__index.e65df827.async.js +0 -1
  208. package/static/dist/src__pages__script__renameModal.4bbe7fb1.async.js +0 -1
  209. package/static/dist/src__pages__script__saveModal.cf449f3c.async.js +0 -1
  210. package/static/dist/src__pages__script__setting.b345d59a.async.js +0 -1
  211. package/static/dist/src__pages__setting__appModal.03faec89.async.js +0 -1
  212. package/static/dist/src__pages__setting__dependence.4495c7b6.async.js +0 -1
  213. package/static/dist/src__pages__setting__index.6919c399.async.js +0 -1
  214. package/static/dist/src__pages__setting__notification.d6a3884f.async.js +0 -1
  215. package/static/dist/src__pages__setting__other.0d931d6f.async.js +0 -1
  216. package/static/dist/src__pages__setting__security.91cb545f.async.js +0 -1
  217. package/static/dist/src__pages__setting__systemLog.1d433a48.async.js +0 -1
  218. package/static/dist/src__pages__subscription__modal.0b84f6cf.async.js +0 -1
@@ -9,6 +9,7 @@ const config_1 = __importDefault(require("../config"));
9
9
  const system_1 = __importDefault(require("../services/system"));
10
10
  const celebrate_1 = require("celebrate");
11
11
  const user_1 = __importDefault(require("../services/user"));
12
+ const i18n_1 = require("../shared/i18n");
12
13
  const util_1 = require("../config/util");
13
14
  const dayjs_1 = __importDefault(require("dayjs"));
14
15
  const multer_1 = __importDefault(require("multer"));
@@ -316,7 +317,7 @@ exports.default = (app) => {
316
317
  try {
317
318
  const userService = typedi_1.Container.get(user_1.default);
318
319
  await userService.resetAuthInfo(req.body);
319
- res.send({ code: 200, message: '更新成功' });
320
+ res.send({ code: 200, message: (0, i18n_1.t)('更新成功') });
320
321
  }
321
322
  catch (e) {
322
323
  return next(e);
@@ -336,6 +337,20 @@ exports.default = (app) => {
336
337
  return next(e);
337
338
  }
338
339
  });
340
+ route.put('/config/lang', (0, celebrate_1.celebrate)({
341
+ body: celebrate_1.Joi.object({
342
+ lang: celebrate_1.Joi.string().allow('').allow(null),
343
+ }),
344
+ }), async (req, res, next) => {
345
+ try {
346
+ const systemService = typedi_1.Container.get(system_1.default);
347
+ const result = await systemService.updateLanguage(req.body);
348
+ res.send(result);
349
+ }
350
+ catch (e) {
351
+ return next(e);
352
+ }
353
+ });
339
354
  route.put('/config/global-ssh-key', (0, celebrate_1.celebrate)({
340
355
  body: celebrate_1.Joi.object({
341
356
  globalSshKey: celebrate_1.Joi.string().allow('').allow(null),
@@ -12,6 +12,7 @@ const path_1 = __importDefault(require("path"));
12
12
  const uuid_1 = require("uuid");
13
13
  const express_rate_limit_1 = __importDefault(require("express-rate-limit"));
14
14
  const config_1 = __importDefault(require("../config"));
15
+ const i18n_1 = require("../shared/i18n");
15
16
  const util_1 = require("../config/util");
16
17
  const route = (0, express_1.Router)();
17
18
  const storage = multer_1.default.diskStorage({
@@ -66,11 +67,11 @@ exports.default = (app) => {
66
67
  }), async (req, res, next) => {
67
68
  try {
68
69
  if ((0, util_1.isDemoEnv)()) {
69
- return res.send({ code: 450, message: '未知错误' });
70
+ return res.send({ code: 450, message: (0, i18n_1.t)('未知错误') });
70
71
  }
71
72
  const userService = typedi_1.Container.get(user_1.default);
72
73
  await userService.updateUsernameAndPassword(req.body);
73
- res.send({ code: 200, message: '更新成功' });
74
+ res.send({ code: 200, message: (0, i18n_1.t)('更新成功') });
74
75
  }
75
76
  catch (e) {
76
77
  return next(e);
@@ -121,11 +122,11 @@ exports.default = (app) => {
121
122
  return next(e);
122
123
  }
123
124
  });
124
- route.put('/two-factor/deactive', async (req, res, next) => {
125
+ route.put('/two-factor/deactivate', async (req, res, next) => {
125
126
  const logger = typedi_1.Container.get('logger');
126
127
  try {
127
128
  const userService = typedi_1.Container.get(user_1.default);
128
- const data = await userService.deactiveTwoFactor();
129
+ const data = await userService.deactivateTwoFactor();
129
130
  res.send({ code: 200, data });
130
131
  }
131
132
  catch (e) {
@@ -192,7 +193,7 @@ exports.default = (app) => {
192
193
  try {
193
194
  const userService = typedi_1.Container.get(user_1.default);
194
195
  await userService.updateUsernameAndPassword(req.body);
195
- res.send({ code: 200, message: '更新成功' });
196
+ res.send({ code: 200, message: (0, i18n_1.t)('更新成功') });
196
197
  }
197
198
  catch (e) {
198
199
  return next(e);
@@ -224,6 +224,9 @@ class Application {
224
224
  }
225
225
  }
226
226
  async startHttpService() {
227
+ // 在导入任何 gRPC 客户端模块之前初始化 mTLS 证书
228
+ const { initGrpcCerts } = await Promise.resolve().then(() => __importStar(require('./config/grpcCerts')));
229
+ await initGrpcCerts();
227
230
  this.setupMiddlewares();
228
231
  const { HttpServerService } = await Promise.resolve().then(() => __importStar(require('./services/http')));
229
232
  this.httpServerService = typedi_1.Container.get(HttpServerService);
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LINUX_DEPENDENCE_COMMAND = exports.NotificationModeStringMap = exports.PYTHON_INSTALL_DIR = exports.SAMPLE_FILES = exports.QL_PREFIX = exports.TASK_PREFIX = exports.QL_COMMAND = exports.TASK_COMMAND = exports.LOG_END_SYMBOL = void 0;
4
+ const container_1 = require("./container");
4
5
  exports.LOG_END_SYMBOL = '     ';
5
6
  exports.TASK_COMMAND = 'task';
6
7
  exports.QL_COMMAND = 'ql';
@@ -49,17 +50,17 @@ exports.NotificationModeStringMap = {
49
50
  };
50
51
  exports.LINUX_DEPENDENCE_COMMAND = {
51
52
  Debian: {
52
- install: 'apt-get install -y',
53
- uninstall: 'apt-get remove -y',
54
- info: 'dpkg-query -s',
53
+ install: (0, container_1.maybeSudo)('apt-get install -y'),
54
+ uninstall: (0, container_1.maybeSudo)('apt-get remove -y'),
55
+ info: (0, container_1.maybeSudo)('dpkg-query -s'),
55
56
  check(info) {
56
57
  return info.includes('install ok installed');
57
58
  },
58
59
  },
59
60
  Ubuntu: {
60
- install: 'apt-get install -y',
61
- uninstall: 'apt-get remove -y',
62
- info: 'dpkg-query -s',
61
+ install: (0, container_1.maybeSudo)('apt-get install -y'),
62
+ uninstall: (0, container_1.maybeSudo)('apt-get remove -y'),
63
+ info: (0, container_1.maybeSudo)('dpkg-query -s'),
63
64
  check(info) {
64
65
  return info.includes('install ok installed');
65
66
  },
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.maybeSudo = exports.isInContainer = void 0;
4
+ function isInContainer() {
5
+ return process.env.QL_CONTAINER === 'true';
6
+ }
7
+ exports.isInContainer = isInContainer;
8
+ function maybeSudo(cmd) {
9
+ return isInContainer() ? `sudo ${cmd}` : cmd;
10
+ }
11
+ exports.maybeSudo = maybeSudo;
12
+ //# sourceMappingURL=container.js.map
@@ -0,0 +1,150 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.getGrpcCerts = exports.initGrpcCerts = void 0;
30
+ const child_process_1 = require("child_process");
31
+ const fs = __importStar(require("fs/promises"));
32
+ const os = __importStar(require("os"));
33
+ const path_1 = __importDefault(require("path"));
34
+ const index_1 = __importDefault(require("./index"));
35
+ const util_1 = require("./util");
36
+ const logger_1 = __importDefault(require("../loaders/logger"));
37
+ const certDir = path_1.default.join(index_1.default.configPath, 'grpc');
38
+ const caKeyPath = path_1.default.join(certDir, 'ca.key');
39
+ const caCertPath = path_1.default.join(certDir, 'ca.crt');
40
+ const serverKeyPath = path_1.default.join(certDir, 'server.key');
41
+ const serverCertPath = path_1.default.join(certDir, 'server.crt');
42
+ const clientKeyPath = path_1.default.join(certDir, 'client.key');
43
+ const clientCertPath = path_1.default.join(certDir, 'client.crt');
44
+ let cachedConfig = null;
45
+ function run(cmd, execOpts) {
46
+ const opts = Object.assign({ stdio: 'pipe', timeout: 30000, encoding: 'utf-8' }, execOpts);
47
+ return (0, child_process_1.execSync)(cmd, opts).trim();
48
+ }
49
+ async function tmpFile(prefix) {
50
+ const dir = (await (0, util_1.fileExist)(certDir)) ? certDir : os.tmpdir();
51
+ await fs.mkdir(dir, { recursive: true });
52
+ return path_1.default.join(dir, `.${prefix}_${Date.now()}_${Math.random().toString(36).slice(2)}.pem`);
53
+ }
54
+ async function generateAllCerts() {
55
+ logger_1.default.info('Generating gRPC mTLS certificates...');
56
+ const caKeyTmp = await tmpFile('ca_key');
57
+ const caCertTmp = await tmpFile('ca_cert');
58
+ const serverKeyTmp = await tmpFile('server_key');
59
+ const serverCsrTmp = await tmpFile('server_csr');
60
+ const serverExtTmp = await tmpFile('server_ext');
61
+ const clientKeyTmp = await tmpFile('client_key');
62
+ const clientCsrTmp = await tmpFile('client_csr');
63
+ const clientExtTmp = await tmpFile('client_ext');
64
+ const srlTmp = path_1.default.join(path_1.default.dirname(caKeyTmp), '.grpc_ca.srl');
65
+ const cleanup = async () => {
66
+ for (const f of [caKeyTmp, caCertTmp, serverKeyTmp, serverCsrTmp, serverExtTmp,
67
+ clientKeyTmp, clientCsrTmp, clientExtTmp, srlTmp]) {
68
+ try {
69
+ await fs.unlink(f);
70
+ }
71
+ catch (_a) { }
72
+ }
73
+ };
74
+ try {
75
+ // 1. CA(私钥直接存盘,证书写入临时文件供签发使用)
76
+ run(`openssl genrsa -out '${caKeyTmp}' 2048 2>/dev/null`);
77
+ run(`openssl req -new -x509 -days 3650 -key '${caKeyTmp}' -out '${caCertTmp}' -subj '/CN=qinglong-ca/O=qinglong/C=CN' 2>/dev/null`);
78
+ const caKey = await fs.readFile(caKeyTmp, 'utf-8');
79
+ const caCert = await fs.readFile(caCertTmp, 'utf-8');
80
+ await fs.mkdir(certDir, { recursive: true });
81
+ await fs.writeFile(caKeyPath, caKey, { mode: 0o600 });
82
+ // 2. 服务端
83
+ run(`openssl genrsa -out '${serverKeyTmp}' 2048 2>/dev/null`);
84
+ run(`openssl req -new -key '${serverKeyTmp}' -out '${serverCsrTmp}' -subj '/CN=grpc-server' 2>/dev/null`);
85
+ await fs.writeFile(serverExtTmp, 'subjectAltName=DNS:localhost,IP:127.0.0.1,IP:::1\n');
86
+ const serverCert = run(`openssl x509 -req -days 3650 -in '${serverCsrTmp}' -CA '${caCertTmp}' -CAkey '${caKeyTmp}' -CAcreateserial -extfile '${serverExtTmp}' 2>/dev/null`);
87
+ const serverKey = await fs.readFile(serverKeyTmp, 'utf-8');
88
+ // 3. 客户端
89
+ run(`openssl genrsa -out '${clientKeyTmp}' 2048 2>/dev/null`);
90
+ run(`openssl req -new -key '${clientKeyTmp}' -out '${clientCsrTmp}' -subj '/CN=grpc-client' 2>/dev/null`);
91
+ await fs.writeFile(clientExtTmp, 'extendedKeyUsage=clientAuth\n');
92
+ const clientCert = run(`openssl x509 -req -days 3650 -in '${clientCsrTmp}' -CA '${caCertTmp}' -CAkey '${caKeyTmp}' -CAcreateserial -extfile '${clientExtTmp}' 2>/dev/null`);
93
+ const clientKey = await fs.readFile(clientKeyTmp, 'utf-8');
94
+ await cleanup();
95
+ logger_1.default.info('gRPC mTLS certificates generated successfully');
96
+ return { caCert, serverCert, serverKey, clientCert, clientKey };
97
+ }
98
+ catch (e) {
99
+ await cleanup();
100
+ throw e;
101
+ }
102
+ }
103
+ async function saveCerts(tlsConfig) {
104
+ await fs.mkdir(certDir, { recursive: true });
105
+ await fs.writeFile(caCertPath, tlsConfig.caCert, { mode: 0o644 });
106
+ await fs.writeFile(serverCertPath, tlsConfig.serverCert, { mode: 0o644 });
107
+ await fs.writeFile(serverKeyPath, tlsConfig.serverKey, { mode: 0o600 });
108
+ await fs.writeFile(clientCertPath, tlsConfig.clientCert, { mode: 0o644 });
109
+ await fs.writeFile(clientKeyPath, tlsConfig.clientKey, { mode: 0o600 });
110
+ logger_1.default.info(`gRPC mTLS certificates saved to ${certDir}`);
111
+ }
112
+ async function loadExistingCerts() {
113
+ const exists = await Promise.all([
114
+ (0, util_1.fileExist)(caCertPath),
115
+ (0, util_1.fileExist)(serverCertPath),
116
+ (0, util_1.fileExist)(serverKeyPath),
117
+ (0, util_1.fileExist)(clientCertPath),
118
+ (0, util_1.fileExist)(clientKeyPath),
119
+ ]);
120
+ if (exists.some((e) => !e)) {
121
+ return null;
122
+ }
123
+ const [caCert, serverCert, serverKey, clientCert, clientKey] = await Promise.all([
124
+ fs.readFile(caCertPath, 'utf-8'),
125
+ fs.readFile(serverCertPath, 'utf-8'),
126
+ fs.readFile(serverKeyPath, 'utf-8'),
127
+ fs.readFile(clientCertPath, 'utf-8'),
128
+ fs.readFile(clientKeyPath, 'utf-8'),
129
+ ]);
130
+ logger_1.default.info('Loaded existing gRPC mTLS certificates from disk');
131
+ return { caCert, serverCert, serverKey, clientCert, clientKey };
132
+ }
133
+ async function initGrpcCerts() {
134
+ if (cachedConfig) {
135
+ return cachedConfig;
136
+ }
137
+ let tlsConfig = await loadExistingCerts();
138
+ if (!tlsConfig) {
139
+ tlsConfig = await generateAllCerts();
140
+ await saveCerts(tlsConfig);
141
+ }
142
+ cachedConfig = tlsConfig;
143
+ return tlsConfig;
144
+ }
145
+ exports.initGrpcCerts = initGrpcCerts;
146
+ function getGrpcCerts() {
147
+ return cachedConfig;
148
+ }
149
+ exports.getGrpcCerts = getGrpcCerts;
150
+ //# sourceMappingURL=grpcCerts.js.map
@@ -11,6 +11,8 @@ dotenv_1.default.config({
11
11
  const config = {
12
12
  port: parseInt(process.env.BACK_PORT || '5700', 10),
13
13
  grpcPort: parseInt(process.env.GRPC_PORT || '5500', 10),
14
+ bindHost: process.env.BIND_HOST || '::',
15
+ bindHostGrpc: process.env.BIND_HOST_GRPC || '::',
14
16
  nodeEnv: process.env.NODE_ENV || 'development',
15
17
  isDevelopment: process.env.NODE_ENV === 'development',
16
18
  isProduction: process.env.NODE_ENV === 'production',
@@ -77,6 +79,7 @@ const jsEnvFile = path_1.default.join(preloadPath, 'env.js');
77
79
  const pyEnvFile = path_1.default.join(preloadPath, 'env.py');
78
80
  const jsNotifyFile = path_1.default.join(preloadPath, '__ql_notify__.js');
79
81
  const pyNotifyFile = path_1.default.join(preloadPath, '__ql_notify__.py');
82
+ const langEnvFile = path_1.default.join(preloadPath, 'lang_env.sh');
80
83
  const confFile = path_1.default.join(configPath, 'config.sh');
81
84
  const crontabFile = path_1.default.join(configPath, 'crontab.list');
82
85
  const authConfigFile = path_1.default.join(configPath, 'auth.json');
@@ -116,6 +119,7 @@ exports.default = Object.assign(Object.assign({}, config), { jwt: config.jwt, ba
116
119
  pyEnvFile,
117
120
  jsNotifyFile,
118
121
  pyNotifyFile,
122
+ langEnvFile,
119
123
  dbPath,
120
124
  uploadPath,
121
125
  configPath,
@@ -131,6 +135,8 @@ exports.default = Object.assign(Object.assign({}, config), { jwt: config.jwt, ba
131
135
  'env.js',
132
136
  'env.py',
133
137
  'token.json',
138
+ 'grpc',
139
+ '__pycache__',
134
140
  ], writePathList: [configPath, scriptPath], bakPath, apiWhiteList: [
135
141
  '/api/user/login',
136
142
  '/api/health',
@@ -43,8 +43,38 @@ const utils_1 = require("../shared/utils");
43
43
  const dependence_1 = require("../data/dependence");
44
44
  const undici_1 = require("undici");
45
45
  const os_1 = __importDefault(require("os"));
46
+ const container_1 = require("./container");
46
47
  __exportStar(require("./share"), exports);
47
48
  let osType;
49
+ function getOsTypeSync() {
50
+ var _a;
51
+ // 1. 环境变量覆盖
52
+ const envOs = (_a = process.env.QL_OS_TYPE) === null || _a === void 0 ? void 0 : _a.toLowerCase();
53
+ if (envOs === 'alpine')
54
+ return 'Alpine';
55
+ if (envOs === 'debian')
56
+ return 'Debian';
57
+ if (envOs === 'ubuntu')
58
+ return 'Ubuntu';
59
+ // 2. 模块缓存(由 detectOS 设置)
60
+ if (osType)
61
+ return osType;
62
+ // 3. 能力检测:检查包管理器二进制
63
+ try {
64
+ (0, child_process_1.execSync)('which apt-get', { stdio: 'ignore' });
65
+ return 'Debian';
66
+ }
67
+ catch (_b) {
68
+ try {
69
+ (0, child_process_1.execSync)('which apk', { stdio: 'ignore' });
70
+ return 'Alpine';
71
+ }
72
+ catch (_c) {
73
+ // macOS / 未知系统
74
+ }
75
+ }
76
+ return undefined;
77
+ }
48
78
  async function getFileContentByName(fileName) {
49
79
  const _exsit = await fileExist(fileName);
50
80
  if (_exsit) {
@@ -233,7 +263,10 @@ async function readDirs(dir, baseDir = '', blacklist = [], sort = dirSort) {
233
263
  }
234
264
  exports.readDirs = readDirs;
235
265
  async function readDir(dir, baseDir = '', blacklist = []) {
236
- const absoluteDir = path.join(baseDir, dir);
266
+ const absoluteDir = path.resolve(baseDir, dir);
267
+ if (!absoluteDir.startsWith(path.resolve(baseDir))) {
268
+ return [];
269
+ }
237
270
  const relativePath = path.relative(baseDir, absoluteDir);
238
271
  try {
239
272
  const files = await fs.readdir(absoluteDir);
@@ -487,8 +520,8 @@ async function setSystemTimezone(timezone) {
487
520
  if (!(await fileExist(`/usr/share/zoneinfo/${timezone}`))) {
488
521
  throw new Error('Invalid timezone');
489
522
  }
490
- await promiseExec(`ln -sf /usr/share/zoneinfo/${timezone} /etc/localtime`);
491
- await promiseExec(`echo "${timezone}" > /etc/timezone`);
523
+ await promiseExec((0, container_1.maybeSudo)(`ln -sf /usr/share/zoneinfo/${timezone} /etc/localtime`));
524
+ await promiseExec(`echo "${timezone}" | ${(0, container_1.maybeSudo)('tee /etc/timezone')}`);
492
525
  return true;
493
526
  }
494
527
  catch (error) {
@@ -512,7 +545,9 @@ except:
512
545
  spec=u.find_spec(name)
513
546
  print(name if spec else '')
514
547
  ''')"`,
515
- [dependence_1.DependenceTypes.linux]: `apt-get info ${name}`,
548
+ [dependence_1.DependenceTypes.linux]: getOsTypeSync() === 'Alpine'
549
+ ? `apk info -es ${name}`
550
+ : (0, container_1.maybeSudo)(`dpkg-query -s ${name}`),
516
551
  };
517
552
  return baseCommands[type];
518
553
  }
@@ -521,7 +556,9 @@ function getInstallCommand(type, name) {
521
556
  const baseCommands = {
522
557
  [dependence_1.DependenceTypes.nodejs]: 'pnpm add -g',
523
558
  [dependence_1.DependenceTypes.python3]: 'pip3 install --disable-pip-version-check --root-user-action=ignore',
524
- [dependence_1.DependenceTypes.linux]: 'apt install -y',
559
+ [dependence_1.DependenceTypes.linux]: getOsTypeSync() === 'Alpine'
560
+ ? 'apk add --no-check-certificate'
561
+ : (0, container_1.maybeSudo)('apt-get install -y'),
525
562
  };
526
563
  let command = baseCommands[type];
527
564
  if (type === dependence_1.DependenceTypes.python3 && const_1.PYTHON_INSTALL_DIR) {
@@ -534,7 +571,9 @@ function getUninstallCommand(type, name) {
534
571
  const baseCommands = {
535
572
  [dependence_1.DependenceTypes.nodejs]: 'pnpm remove -g',
536
573
  [dependence_1.DependenceTypes.python3]: 'pip3 uninstall --disable-pip-version-check --root-user-action=ignore -y',
537
- [dependence_1.DependenceTypes.linux]: 'apt remove -y',
574
+ [dependence_1.DependenceTypes.linux]: getOsTypeSync() === 'Alpine'
575
+ ? 'apk del'
576
+ : (0, container_1.maybeSudo)('apt-get remove -y'),
538
577
  };
539
578
  return `${baseCommands[type]} ${name.trim()}`;
540
579
  }
@@ -560,8 +599,22 @@ function isAlpine(osReleaseInfo) {
560
599
  return osReleaseInfo.includes('Alpine');
561
600
  }
562
601
  async function detectOS() {
602
+ var _a;
563
603
  if (osType)
564
604
  return osType;
605
+ const envOs = (_a = process.env.QL_OS_TYPE) === null || _a === void 0 ? void 0 : _a.toLowerCase();
606
+ if (envOs === 'alpine') {
607
+ osType = 'Alpine';
608
+ return osType;
609
+ }
610
+ if (envOs === 'debian') {
611
+ osType = 'Debian';
612
+ return osType;
613
+ }
614
+ if (envOs === 'ubuntu') {
615
+ osType = 'Ubuntu';
616
+ return osType;
617
+ }
565
618
  const platform = os_1.default.platform();
566
619
  if (platform === 'linux') {
567
620
  const osReleaseInfo = await getOSReleaseInfo();
@@ -612,37 +665,35 @@ async function replaceDomainInFile(filePath, oldDomainWithScheme, newDomainWithS
612
665
  await (0, utils_1.writeFileWithLock)(filePath, updatedContent);
613
666
  }
614
667
  async function _updateLinuxMirror(osType, mirrorDomainWithScheme) {
668
+ const S = (0, container_1.isInContainer)() ? 'sudo ' : '';
615
669
  let filePath, currentDomainWithScheme;
616
670
  switch (osType) {
617
671
  case 'Debian':
618
672
  filePath = '/etc/apt/sources.list.d/debian.sources';
619
673
  currentDomainWithScheme = await getCurrentMirrorDomain(filePath);
620
674
  if (currentDomainWithScheme) {
621
- await replaceDomainInFile(filePath, currentDomainWithScheme, mirrorDomainWithScheme || 'http://deb.debian.org');
622
- return 'apt-get update';
675
+ return `${S}sed -i 's|${currentDomainWithScheme}|${mirrorDomainWithScheme || 'http://deb.debian.org'}|g' ${filePath} || (${S}mkdir -p /etc/apt/sources.list.d && echo -e "Types: deb\\nURIs: ${mirrorDomainWithScheme || 'http://deb.debian.org'}\\nSuites: \\$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2) \\$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2)-updates\\nComponents: main\\nSigned-By: /usr/share/keyrings/debian-archive-keyring.gpg" | ${S}tee ${filePath}) && ${S}apt-get update`;
623
676
  }
624
677
  else {
625
- throw Error(`Current mirror domain not found.`);
678
+ return `${S}mkdir -p /etc/apt/sources.list.d && echo -e "Types: deb\\nURIs: ${mirrorDomainWithScheme || 'http://deb.debian.org'}\\nSuites: \\$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2) \\$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2)-updates\\nComponents: main\\nSigned-By: /usr/share/keyrings/debian-archive-keyring.gpg" | ${S}tee ${filePath} && ${S}apt-get update`;
626
679
  }
627
680
  case 'Ubuntu':
628
681
  filePath = '/etc/apt/sources.list.d/ubuntu.sources';
629
682
  currentDomainWithScheme = await getCurrentMirrorDomain(filePath);
630
683
  if (currentDomainWithScheme) {
631
- await replaceDomainInFile(filePath, currentDomainWithScheme, mirrorDomainWithScheme || 'http://archive.ubuntu.com');
632
- return 'apt-get update';
684
+ return `${S}sed -i 's|${currentDomainWithScheme}|${mirrorDomainWithScheme || 'http://archive.ubuntu.com'}|g' ${filePath} || (${S}mkdir -p /etc/apt/sources.list.d && echo -e "Types: deb\\nURIs: ${mirrorDomainWithScheme || 'http://archive.ubuntu.com'}\\nSuites: \\$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2) \\$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2)-updates \\$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2)-backports\\nComponents: main restricted universe multiverse\\nSigned-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg" | ${S}tee ${filePath}) && ${S}apt-get update`;
633
685
  }
634
686
  else {
635
- throw Error(`Current mirror domain not found.`);
687
+ return `${S}mkdir -p /etc/apt/sources.list.d && echo -e "Types: deb\\nURIs: ${mirrorDomainWithScheme || 'http://archive.ubuntu.com'}\\nSuites: \\$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2) \\$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2)-updates \\$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2)-backports\\nComponents: main restricted universe multiverse\\nSigned-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg" | ${S}tee ${filePath} && ${S}apt-get update`;
636
688
  }
637
689
  case 'Alpine':
638
690
  filePath = '/etc/apk/repositories';
639
691
  currentDomainWithScheme = await getCurrentMirrorDomain(filePath);
640
692
  if (currentDomainWithScheme) {
641
- await replaceDomainInFile(filePath, currentDomainWithScheme, mirrorDomainWithScheme || 'http://dl-cdn.alpinelinux.org');
642
- return 'apk update';
693
+ return `sed -i 's|${currentDomainWithScheme}|${mirrorDomainWithScheme || 'http://dl-cdn.alpinelinux.org'}|g' ${filePath} || (mkdir -p /etc/apk && echo -e "\\$(grep VERSION_ID /etc/os-release | cut -d= -f2 | cut -d. -f1,2)/main\\n\\$(grep VERSION_ID /etc/os-release | cut -d= -f2 | cut -d. -f1,2)/community" | sed "s|^|${mirrorDomainWithScheme || 'http://dl-cdn.alpinelinux.org'}/alpine/v|" | tee ${filePath}) && apk update`;
643
694
  }
644
695
  else {
645
- throw Error(`Current mirror domain not found.`);
696
+ return `mkdir -p /etc/apk && echo -e "\\$(grep VERSION_ID /etc/os-release | cut -d= -f2 | cut -d. -f1,2)/main\\n\\$(grep VERSION_ID /etc/os-release | cut -d= -f2 | cut -d. -f1,2)/community" | sed "s|^|${mirrorDomainWithScheme || 'http://dl-cdn.alpinelinux.org'}/alpine/v|" | tee ${filePath} && apk update`;
646
697
  }
647
698
  default:
648
699
  throw Error('Unsupported OS type for updating mirrors.');
@@ -29,15 +29,16 @@ class Crontab {
29
29
  this.task_after = options.task_after;
30
30
  this.log_name = options.log_name;
31
31
  this.allow_multiple_instances = options.allow_multiple_instances || 0;
32
+ this.work_dir = options.work_dir;
32
33
  }
33
34
  }
34
35
  exports.Crontab = Crontab;
35
36
  var CrontabStatus;
36
37
  (function (CrontabStatus) {
37
38
  CrontabStatus[CrontabStatus["running"] = 0] = "running";
38
- CrontabStatus[CrontabStatus["queued"] = 0.5] = "queued";
39
39
  CrontabStatus[CrontabStatus["idle"] = 1] = "idle";
40
40
  CrontabStatus[CrontabStatus["disabled"] = 2] = "disabled";
41
+ CrontabStatus[CrontabStatus["queued"] = 3] = "queued";
41
42
  })(CrontabStatus || (exports.CrontabStatus = CrontabStatus = {}));
42
43
  exports.CrontabModel = _1.sequelize.define('Crontab', {
43
44
  name: {
@@ -69,5 +70,6 @@ exports.CrontabModel = _1.sequelize.define('Crontab', {
69
70
  task_after: sequelize_1.DataTypes.STRING,
70
71
  log_name: sequelize_1.DataTypes.STRING,
71
72
  allow_multiple_instances: sequelize_1.DataTypes.NUMBER,
73
+ work_dir: sequelize_1.DataTypes.STRING,
72
74
  });
73
75
  //# sourceMappingURL=cron.js.map
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CrontabStatModel = exports.CrontabStat = void 0;
4
+ const sequelize_1 = require("sequelize");
5
+ const _1 = require(".");
6
+ class CrontabStat {
7
+ constructor(options) {
8
+ this.id = options.id;
9
+ this.ref_id = options.ref_id;
10
+ this.date = options.date;
11
+ this.run_count = options.run_count || 0;
12
+ this.success_count = options.success_count || 0;
13
+ this.fail_count = options.fail_count || 0;
14
+ this.total_time = options.total_time || 0;
15
+ this.max_time = options.max_time || 0;
16
+ }
17
+ }
18
+ exports.CrontabStat = CrontabStat;
19
+ exports.CrontabStatModel = _1.sequelize.define('CrontabStat', {
20
+ id: {
21
+ type: sequelize_1.DataTypes.INTEGER,
22
+ primaryKey: true,
23
+ autoIncrement: true,
24
+ },
25
+ ref_id: {
26
+ type: sequelize_1.DataTypes.NUMBER,
27
+ allowNull: false,
28
+ },
29
+ date: {
30
+ type: sequelize_1.DataTypes.STRING,
31
+ allowNull: false,
32
+ },
33
+ run_count: {
34
+ type: sequelize_1.DataTypes.NUMBER,
35
+ defaultValue: 0,
36
+ },
37
+ success_count: {
38
+ type: sequelize_1.DataTypes.NUMBER,
39
+ defaultValue: 0,
40
+ },
41
+ fail_count: {
42
+ type: sequelize_1.DataTypes.NUMBER,
43
+ defaultValue: 0,
44
+ },
45
+ total_time: {
46
+ type: sequelize_1.DataTypes.NUMBER,
47
+ defaultValue: 0,
48
+ },
49
+ max_time: {
50
+ type: sequelize_1.DataTypes.NUMBER,
51
+ defaultValue: 0,
52
+ },
53
+ }, {
54
+ indexes: [
55
+ { unique: true, fields: ['ref_id', 'date'] },
56
+ { fields: ['date'] },
57
+ ],
58
+ });
59
+ //# sourceMappingURL=cronStats.js.map
@@ -16,6 +16,7 @@ class Env {
16
16
  this.name = options.name;
17
17
  this.remarks = options.remarks || '';
18
18
  this.isPinned = options.isPinned || 0;
19
+ this.labels = options.labels || [];
19
20
  }
20
21
  }
21
22
  exports.Env = Env;
@@ -36,5 +37,6 @@ exports.EnvModel = _1.sequelize.define('Env', {
36
37
  name: { type: sequelize_1.DataTypes.STRING, unique: 'compositeIndex' },
37
38
  remarks: sequelize_1.DataTypes.STRING,
38
39
  isPinned: sequelize_1.DataTypes.NUMBER,
40
+ labels: sequelize_1.DataTypes.JSON,
39
41
  });
40
42
  //# sourceMappingURL=env.js.map
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WxPusherBotNotification = exports.NtfyNotification = exports.LarkNotification = exports.WebhookNotification = exports.ChronocatNotification = exports.PushMeNotification = exports.EmailNotification = exports.WePlusBotNotification = exports.PushPlusNotification = exports.IGotNotification = exports.AibotkNotification = exports.WeWorkAppNotification = exports.WeWorkBotNotification = exports.DingtalkBotNotification = exports.TelegramBotNotification = exports.BarkNotification = exports.synologyChatNotification = exports.PushDeerNotification = exports.ServerChanNotification = exports.GoCqHttpBotNotification = exports.GotifyNotification = exports.NotificationMode = void 0;
3
+ exports.OpeniLinkNotification = exports.WxPusherBotNotification = exports.NtfyNotification = exports.LarkNotification = exports.WebhookNotification = exports.ChronocatNotification = exports.PushMeNotification = exports.EmailNotification = exports.WePlusBotNotification = exports.PushPlusNotification = exports.IGotNotification = exports.AibotkNotification = exports.WeWorkAppNotification = exports.WeWorkBotNotification = exports.DingtalkBotNotification = exports.TelegramBotNotification = exports.BarkNotification = exports.synologyChatNotification = exports.PushDeerNotification = exports.ServerChanNotification = exports.GoCqHttpBotNotification = exports.GotifyNotification = exports.NotificationMode = void 0;
4
4
  var NotificationMode;
5
5
  (function (NotificationMode) {
6
6
  NotificationMode["gotify"] = "gotify";
@@ -24,6 +24,7 @@ var NotificationMode;
24
24
  NotificationMode["chronocat"] = "Chronocat";
25
25
  NotificationMode["ntfy"] = "ntfy";
26
26
  NotificationMode["wxPusherBot"] = "wxPusherBot";
27
+ NotificationMode["openiLink"] = "openiLink";
27
28
  })(NotificationMode || (exports.NotificationMode = NotificationMode = {}));
28
29
  class NotificationBaseInfo {
29
30
  }
@@ -222,4 +223,13 @@ class WxPusherBotNotification extends NotificationBaseInfo {
222
223
  }
223
224
  }
224
225
  exports.WxPusherBotNotification = WxPusherBotNotification;
226
+ class OpeniLinkNotification extends NotificationBaseInfo {
227
+ constructor() {
228
+ super(...arguments);
229
+ this.openiLinkAppToken = '';
230
+ this.openiLinkHubUrl = '';
231
+ this.openiLinkContextToken = '';
232
+ }
233
+ }
234
+ exports.OpeniLinkNotification = OpeniLinkNotification;
225
235
  //# sourceMappingURL=notify.js.map