@cartanova/qgrid-cli 2.6.7 → 2.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/dist/application/monit/monit.frame.js +2 -2
- package/bundle/dist/application/qgrid/expired-token-reminder.js +45 -15
- package/bundle/dist/application/qgrid/oauth.js +1 -1
- package/bundle/dist/application/qgrid/qgrid.frame.js +3 -3
- package/bundle/dist/application/qgrid/slack-user-map.js +5 -14
- package/bundle/dist/application/qgrid/token-death.js +3 -2
- package/bundle/dist/application/qgrid/tool-emulation.js +1 -1
- package/bundle/dist/application/queries.generated.js +8 -2
- package/bundle/dist/application/request-log/request-log.model.js +2 -2
- package/bundle/dist/application/request-log-step/request-log-step.model.js +1 -1
- package/bundle/dist/application/setting/setting.constant.js +226 -0
- package/bundle/dist/application/setting/setting.model.js +254 -0
- package/bundle/dist/application/setting/setting.store.js +66 -0
- package/bundle/dist/application/setting/setting.types.js +51 -0
- package/bundle/dist/application/sonamu.generated.js +32 -2
- package/bundle/dist/application/sonamu.generated.sso.js +12 -2
- package/bundle/dist/application/token/token.model.js +1 -1
- package/bundle/dist/i18n/en.js +3 -1
- package/bundle/dist/i18n/ko.js +3 -1
- package/bundle/dist/i18n/sd.generated.js +9 -1
- package/bundle/dist/migrations/20260808194708_create__settings.js +24 -0
- package/bundle/dist/sonamu.config.js +8 -2
- package/bundle/dist/utils/providers/openai/openai-worker-pool-config.js +21 -6
- package/bundle/dist/utils/quiet-hours.js +47 -0
- package/bundle/dist/utils/slack-notify.js +16 -5
- package/bundle/src/application/qgrid/expired-token-reminder.test.ts +147 -2
- package/bundle/src/application/qgrid/expired-token-reminder.ts +66 -16
- package/bundle/src/application/qgrid/slack-user-map.test.ts +23 -0
- package/bundle/src/application/qgrid/slack-user-map.ts +4 -14
- package/bundle/src/application/qgrid/token-death.ts +2 -0
- package/bundle/src/application/queries.generated.ts +21 -1
- package/bundle/src/application/setting/setting.constant.test.ts +109 -0
- package/bundle/src/application/setting/setting.constant.ts +250 -0
- package/bundle/src/application/setting/setting.entity.json +59 -0
- package/bundle/src/application/setting/setting.model.ts +277 -0
- package/bundle/src/application/setting/setting.store.test.ts +87 -0
- package/bundle/src/application/setting/setting.store.ts +85 -0
- package/bundle/src/application/setting/setting.types.ts +53 -0
- package/bundle/src/application/sonamu.generated.http +54 -0
- package/bundle/src/application/sonamu.generated.sso.ts +21 -0
- package/bundle/src/application/sonamu.generated.ts +51 -0
- package/bundle/src/i18n/en.ts +2 -0
- package/bundle/src/i18n/ko.ts +2 -0
- package/bundle/src/i18n/sd.generated.ts +8 -0
- package/bundle/src/migrations/20260808194708_create__settings.ts +19 -0
- package/bundle/src/sonamu.config.ts +12 -0
- package/bundle/src/utils/providers/openai/openai-dispatcher.test.ts +12 -0
- package/bundle/src/utils/providers/openai/openai-worker-pool-config.ts +43 -5
- package/bundle/src/utils/quiet-hours.ts +79 -0
- package/bundle/src/utils/slack-notify.test.ts +171 -20
- package/bundle/src/utils/slack-notify.ts +31 -4
- package/bundle/web-dist/client/assets/index-DnnliAzf.js +78 -0
- package/bundle/web-dist/client/assets/index-rdbxJinT.css +1 -0
- package/bundle/web-dist/client/assets/{logs-CUO9Q0UT.js → logs-5gACO5tJ.js} +1 -1
- package/bundle/web-dist/client/assets/{monit-Dy7UtqC2.js → monit-DRCc50GU.js} +1 -1
- package/bundle/web-dist/client/assets/plus-p4vtg6LN.js +1 -0
- package/bundle/web-dist/client/assets/{routes-B6gfQrph.js → routes-DBdI9Ba1.js} +2 -2
- package/bundle/web-dist/client/assets/{sd.generated-DYdwSB2I.js → sd.generated-Bwa7rses.js} +1 -1
- package/bundle/web-dist/client/assets/services.generated-BzwTuZRP.js +1 -0
- package/bundle/web-dist/client/assets/settings-B62_r1i4.js +1 -0
- package/bundle/web-dist/client/assets/{show-Bi0QYUVm.js → show-BCRrSc8-.js} +1 -1
- package/bundle/web-dist/client/assets/tokens-CDiXKYGf.js +1 -0
- package/bundle/web-dist/client/assets/{use-oauth-login-flow-Cx6BlvXM.js → use-oauth-login-flow-Qqg4koSg.js} +1 -1
- package/bundle/web-dist/client/index.html +3 -3
- package/bundle/web-dist/server/assets/{lazyRouteComponent-BaZaveNc.js → lazyRouteComponent-Ws7I6fL-.js} +2 -1
- package/bundle/web-dist/server/assets/{logs-DMOw3SjD.js → logs-C1rxLh8H.js} +4 -4
- package/bundle/web-dist/server/assets/{monit-UmcqHroX.js → monit-C8gx9Sar.js} +3 -2
- package/bundle/web-dist/server/assets/plus-BISXNqRU.js +19 -0
- package/bundle/web-dist/server/assets/react-dom-D7duWOwf.js +462 -0
- package/bundle/web-dist/server/assets/{routes-BfoQmYud.js → routes-ZW_Ih5Em.js} +11 -7
- package/bundle/web-dist/server/assets/{sd.generated-B0xqnHEo.js → sd.generated-LO-h1_16.js} +13 -461
- package/bundle/web-dist/server/assets/{services.generated-DqAKskAS.js → services.generated-CZIChgHV.js} +119 -2
- package/bundle/web-dist/server/assets/settings--aoatERH.js +382 -0
- package/bundle/web-dist/server/assets/{show-C-oSdzHX.js → show-BY27w9oi.js} +4 -4
- package/bundle/web-dist/server/assets/{tokens-Dkd_uXEk.js → tokens-DIObtTuZ.js} +17 -72
- package/bundle/web-dist/server/assets/{use-oauth-login-flow-YM1nsd-H.js → use-oauth-login-flow-V3k8PSqQ.js} +2 -2
- package/bundle/web-dist/server/entry-server.generated.js +54 -18
- package/package.json +1 -1
- package/skills/qgrid/references/cli-env-and-server-boot.md +17 -2
- package/skills/qgrid/references/openai-codex-runtime.md +1 -1
- package/skills/qgrid/references/sonamu-api-web-flow.md +2 -0
- package/skills/qgrid/references/token-auth-quota-lifecycle.md +2 -0
- package/bundle/web-dist/client/assets/index-B4GlN1IX.css +0 -1
- package/bundle/web-dist/client/assets/index-CV_rp3zE.js +0 -78
- package/bundle/web-dist/client/assets/services.generated-BsAvotjG.js +0 -1
- package/bundle/web-dist/client/assets/tokens-BAuYgBl6.js +0 -1
- /package/bundle/web-dist/server/assets/{cost-CSH_t17I.js → cost-DzjfVtUr.js} +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { monitLogBuffer } from "./log-buffer.js";
|
|
2
|
-
import { resolveOpenAIWorkerPoolConfig } from "../../utils/providers/openai/openai-worker-pool-config.js";
|
|
3
|
-
import { QgridDispatcher } from "../qgrid/qgrid.dispatcher.js";
|
|
4
2
|
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorateMetadata.js";
|
|
5
3
|
import __decorate from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorate.js";
|
|
4
|
+
import { resolveOpenAIWorkerPoolConfig } from "../../utils/providers/openai/openai-worker-pool-config.js";
|
|
5
|
+
import { QgridDispatcher } from "../qgrid/qgrid.dispatcher.js";
|
|
6
6
|
import { BaseFrameClass, DB, api } from "sonamu";
|
|
7
7
|
//#region src/application/monit/monit.frame.ts
|
|
8
8
|
/**
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getSetting } from "../setting/setting.store.js";
|
|
1
2
|
import { SLACK_COLOR, notifySlack } from "../../utils/slack-notify.js";
|
|
2
3
|
import { TokenModel } from "../token/token.model.js";
|
|
3
4
|
import { getSlackUserMap, mentionFor } from "./slack-user-map.js";
|
|
@@ -17,6 +18,12 @@ import { getLogger } from "@logtape/logtape";
|
|
|
17
18
|
*/
|
|
18
19
|
const logger = getLogger(["qgrid", "expired-reminder"]);
|
|
19
20
|
const MINUTE_MS = 6e4;
|
|
21
|
+
const defaultDeps = {
|
|
22
|
+
findInactive: () => TokenModel.findInactive("A"),
|
|
23
|
+
getSlackUserMap,
|
|
24
|
+
readSetting: getSetting,
|
|
25
|
+
sendSlack: notifySlack
|
|
26
|
+
};
|
|
20
27
|
/**
|
|
21
28
|
* 1건이면 제목(subject)에 토큰명이 이미 있으므로 본문에서는 뺀다 — 같은 이름을 두 번 쓰면
|
|
22
29
|
* 읽는 사람이 다른 정보인 줄 알고 한 번 더 본다. 여러 건이면 제목이 건수라 본문에 남긴다.
|
|
@@ -30,31 +37,54 @@ function buildReminderContext(tokens, userMap) {
|
|
|
30
37
|
return mention ? `${mention} ${label}` : label;
|
|
31
38
|
}), "재로그인이 필요합니다"].filter(Boolean).join("\n");
|
|
32
39
|
}
|
|
33
|
-
async function sendReminder(
|
|
34
|
-
const inactive = await
|
|
35
|
-
if (inactive.length === 0) return;
|
|
36
|
-
|
|
40
|
+
async function sendReminder(deps, urgent = false) {
|
|
41
|
+
const inactive = await deps.findInactive();
|
|
42
|
+
if (inactive.length === 0) return 0;
|
|
43
|
+
const userMap = deps.getSlackUserMap();
|
|
44
|
+
await deps.sendSlack({
|
|
37
45
|
title: "세션 만료",
|
|
38
46
|
subject: inactive.length > 1 ? `${inactive.length}건` : inactive[0].name ?? "unnamed",
|
|
39
47
|
context: buildReminderContext(inactive, userMap),
|
|
40
|
-
color: SLACK_COLOR.bad
|
|
48
|
+
color: SLACK_COLOR.bad,
|
|
49
|
+
urgent
|
|
41
50
|
});
|
|
51
|
+
return inactive.length;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 화면의 "지금 보내기". 사람이 직접 누른 것이므로 조용 시간·마스터 스위치를 통과시킨다 —
|
|
55
|
+
* 눌렀는데 아무 일도 안 일어나면 버튼이 고장 난 것으로 읽힌다.
|
|
56
|
+
*
|
|
57
|
+
* 보낸 건수를 돌려줘 호출부가 "보낼 대상 없음"과 "보냄"을 구분해 보여준다.
|
|
58
|
+
*/
|
|
59
|
+
function sendExpiredTokenReminderNow(deps = defaultDeps) {
|
|
60
|
+
return sendReminder(deps, true);
|
|
42
61
|
}
|
|
43
62
|
let timer = null;
|
|
63
|
+
function scheduleExpiredTokenReminder(runNow, deps) {
|
|
64
|
+
stopExpiredTokenReminder();
|
|
65
|
+
if (deps.readSetting("slack.remindersEnabled", "SLACK_REMINDERS_ENABLED") === "false") {
|
|
66
|
+
logger.info("expired token reminder disabled");
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const minutes = Number(deps.readSetting("slack.expiryReminderMinutes", "SLACK_EXPIRY_REMINDER_INTERVAL_MINUTES") ?? 0);
|
|
70
|
+
if (!Number.isFinite(minutes) || minutes <= 0) return;
|
|
71
|
+
logger.info(`expired token reminder every ${minutes}m (${deps.getSlackUserMap().size} user mappings)`);
|
|
72
|
+
const run = () => sendReminder(deps).catch((e) => logger.warn(`reminder failed: ${e.message}`));
|
|
73
|
+
if (runNow) run();
|
|
74
|
+
timer = setInterval(run, minutes * MINUTE_MS);
|
|
75
|
+
}
|
|
44
76
|
/**
|
|
45
77
|
* `SLACK_EXPIRY_REMINDER_INTERVAL_MINUTES` 가 양수일 때만 켜진다. 미설정·0 이면 비활성.
|
|
46
78
|
*
|
|
47
79
|
* 인스턴스가 여러 개면 각자 보낸다. 만료 순간 알림과 달리 상태 변화가 없어 DB 로 억제할 수
|
|
48
80
|
* 없고, 하루 몇 건 수준이라 중복을 감수하는 편이 잠금 장치를 두는 것보다 낫다.
|
|
49
81
|
*/
|
|
50
|
-
function startExpiredTokenReminder() {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
run();
|
|
57
|
-
timer = setInterval(run, minutes * MINUTE_MS);
|
|
82
|
+
function startExpiredTokenReminder(deps = defaultDeps) {
|
|
83
|
+
scheduleExpiredTokenReminder(true, deps);
|
|
84
|
+
}
|
|
85
|
+
/** 설정 변경 시 기존 타이머만 새 주기로 교체한다. 저장 자체가 알림을 보내지는 않는다. */
|
|
86
|
+
function rescheduleExpiredTokenReminder(deps = defaultDeps) {
|
|
87
|
+
scheduleExpiredTokenReminder(false, deps);
|
|
58
88
|
}
|
|
59
89
|
function stopExpiredTokenReminder() {
|
|
60
90
|
if (!timer) return;
|
|
@@ -62,6 +92,6 @@ function stopExpiredTokenReminder() {
|
|
|
62
92
|
timer = null;
|
|
63
93
|
}
|
|
64
94
|
//#endregion
|
|
65
|
-
export { buildReminderContext, startExpiredTokenReminder, stopExpiredTokenReminder };
|
|
95
|
+
export { buildReminderContext, rescheduleExpiredTokenReminder, sendExpiredTokenReminderNow, startExpiredTokenReminder, stopExpiredTokenReminder };
|
|
66
96
|
|
|
67
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwaXJlZC10b2tlbi1yZW1pbmRlci5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBwbGljYXRpb24vcWdyaWQvZXhwaXJlZC10b2tlbi1yZW1pbmRlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIOyEuOyFmCDrp4zro4wg7JWM66a8IOuwmOuztS5cbiAqXG4gKiDrp4zro4wg7Iic6rCE7J2YIOyVjOumvChgdG9rZW4tZGVhdGgudHNgKeydgCDqt7jrlYwg7LGE64SQ7J2EIOuztOyngCDslYrsnLzrqbQg64aT7Lmc64ukLiDsnqzroZzqt7jsnbjsnYAg7IKs656M7J20XG4gKiDtlbTslbwg7ZWY64qUIOydvOydtOudvCDrhpPsuZjrqbQg7Yag7YGw7J20IOqzhOyGjSDruaDsp4Qg7LGE66GcIOuCqOuKlOuLpC4g6re4656Y7IScIOyVhOyngSDsnqzroZzqt7jsnbjrkJjsp4Ag7JWK7J2AXG4gKiDthqDtgbDsnYQg6rCZ7J2AIOusuOq1rOuhnCDri6Tsi5wg7JWM66aw64ukIOKAlCDsgqzqsbTsnbQg7ZWY64KY7J2066+A66GcIOyVjOumvOuPhCDtlZwg7KKF66WY64ukLlxuICpcbiAqIOyXrOufrCDthqDtgbDsnbQg66eM66OM64+
|
|
97
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwaXJlZC10b2tlbi1yZW1pbmRlci5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBwbGljYXRpb24vcWdyaWQvZXhwaXJlZC10b2tlbi1yZW1pbmRlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIOyEuOyFmCDrp4zro4wg7JWM66a8IOuwmOuztS5cbiAqXG4gKiDrp4zro4wg7Iic6rCE7J2YIOyVjOumvChgdG9rZW4tZGVhdGgudHNgKeydgCDqt7jrlYwg7LGE64SQ7J2EIOuztOyngCDslYrsnLzrqbQg64aT7Lmc64ukLiDsnqzroZzqt7jsnbjsnYAg7IKs656M7J20XG4gKiDtlbTslbwg7ZWY64qUIOydvOydtOudvCDrhpPsuZjrqbQg7Yag7YGw7J20IOqzhOyGjSDruaDsp4Qg7LGE66GcIOuCqOuKlOuLpC4g6re4656Y7IScIOyVhOyngSDsnqzroZzqt7jsnbjrkJjsp4Ag7JWK7J2AXG4gKiDthqDtgbDsnYQg6rCZ7J2AIOusuOq1rOuhnCDri6Tsi5wg7JWM66aw64ukIOKAlCDsgqzqsbTsnbQg7ZWY64KY7J2066+A66GcIOyVjOumvOuPhCDtlZwg7KKF66WY64ukLlxuICpcbiAqIOyXrOufrCDthqDtgbDsnbQg66eM66OM64+8IOyeiOycvOuptCDtlZwg66mU7Iuc7KeA7JeQIOuqqOydgOuLpC4g7Yag7YGw66eI64ukIOuplOyLnOyngOulvCDrs7TrgrTrqbQg7LGE64SQ7J20IOyLnOuBhOufrOybjFxuICog7KCV7J6RIOydve2eiOyngCDslYrripTri6QuXG4gKlxuICog67mE7Zmc7ISxIO2GoO2BsOydtCDsl4bsnLzrqbQg67O064K07KeAIOyViuuKlOuLpCDigJQgXCLsnbTsg4Eg7JeG7J2MXCLsnYQg7KO86riw7KCB7Jy866GcIOyVjOumrOuptCDssYTrhJDsnbQg66y0646M7KeE64ukLlxuICovXG5pbXBvcnQgeyBnZXRMb2dnZXIgfSBmcm9tIFwiQGxvZ3RhcGUvbG9ndGFwZVwiO1xuXG5pbXBvcnQgeyBub3RpZnlTbGFjaywgU0xBQ0tfQ09MT1IgfSBmcm9tIFwiLi4vLi4vdXRpbHMvc2xhY2stbm90aWZ5XCI7XG5pbXBvcnQgeyBnZXRTZXR0aW5nIH0gZnJvbSBcIi4uL3NldHRpbmcvc2V0dGluZy5zdG9yZVwiO1xuaW1wb3J0IHsgVG9rZW5Nb2RlbCB9IGZyb20gXCIuLi90b2tlbi90b2tlbi5tb2RlbFwiO1xuaW1wb3J0IHsgZ2V0U2xhY2tVc2VyTWFwLCBtZW50aW9uRm9yIH0gZnJvbSBcIi4vc2xhY2stdXNlci1tYXBcIjtcblxuY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwiZXhwaXJlZC1yZW1pbmRlclwiXSk7XG5cbmNvbnN0IE1JTlVURV9NUyA9IDYwXzAwMDtcblxuZXhwb3J0IHR5cGUgRXhwaXJlZFRva2VuUmVtaW5kZXJEZXBzID0ge1xuICBmaW5kSW5hY3RpdmU6ICgpID0+IFByb21pc2U8eyBuYW1lOiBzdHJpbmcgfCBudWxsOyBwcm92aWRlcjogc3RyaW5nIH1bXT47XG4gIGdldFNsYWNrVXNlck1hcDogKCkgPT4gTWFwPHN0cmluZywgc3RyaW5nPjtcbiAgcmVhZFNldHRpbmc6IHR5cGVvZiBnZXRTZXR0aW5nO1xuICBzZW5kU2xhY2s6IHR5cGVvZiBub3RpZnlTbGFjaztcbn07XG5cbmNvbnN0IGRlZmF1bHREZXBzOiBFeHBpcmVkVG9rZW5SZW1pbmRlckRlcHMgPSB7XG4gIGZpbmRJbmFjdGl2ZTogKCkgPT4gVG9rZW5Nb2RlbC5maW5kSW5hY3RpdmUoXCJBXCIpLFxuICBnZXRTbGFja1VzZXJNYXAsXG4gIHJlYWRTZXR0aW5nOiBnZXRTZXR0aW5nLFxuICBzZW5kU2xhY2s6IG5vdGlmeVNsYWNrLFxufTtcblxuLyoqXG4gKiAx6rG07J2066m0IOygnOuqqShzdWJqZWN0KeyXkCDthqDtgbDrqoXsnbQg7J2066+4IOyeiOycvOuvgOuhnCDrs7jrrLjsl5DshJzripQg67qA64ukIOKAlCDqsJnsnYAg7J2066aE7J2EIOuRkCDrsogg7JOw66m0XG4gKiDsnb3ripQg7IKs656M7J20IOuLpOuluCDsoJXrs7Tsnbgg7KSEIOyVjOqzoCDtlZwg67KIIOuNlCDrs7jri6QuIOyXrOufrCDqsbTsnbTrqbQg7KCc66qp7J20IOqxtOyImOudvCDrs7jrrLjsl5Ag64Ko6ri064ukLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRSZW1pbmRlckNvbnRleHQoXG4gIHRva2VuczogeyBuYW1lOiBzdHJpbmcgfCBudWxsOyBwcm92aWRlcjogc3RyaW5nIH1bXSxcbiAgdXNlck1hcDogTWFwPHN0cmluZywgc3RyaW5nPixcbik6IHN0cmluZyB7XG4gIGNvbnN0IHNob3dMYWJlbCA9IHRva2Vucy5sZW5ndGggPiAxO1xuICBjb25zdCBsaW5lcyA9IHRva2Vucy5tYXAoKHRva2VuKSA9PiB7XG4gICAgY29uc3QgbWVudGlvbiA9IG1lbnRpb25Gb3IodG9rZW4ubmFtZSwgdXNlck1hcCk7XG4gICAgY29uc3QgbGFiZWwgPSB0b2tlbi5uYW1lID8/IFwidW5uYW1lZFwiO1xuICAgIGlmICghc2hvd0xhYmVsKSByZXR1cm4gbWVudGlvbjtcbiAgICByZXR1cm4gbWVudGlvbiA/IGAke21lbnRpb259ICR7bGFiZWx9YCA6IGxhYmVsO1xuICB9KTtcbiAgcmV0dXJuIFsuLi5saW5lcywgXCLsnqzroZzqt7jsnbjsnbQg7ZWE7JqU7ZWp64uI64ukXCJdLmZpbHRlcihCb29sZWFuKS5qb2luKFwiXFxuXCIpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBzZW5kUmVtaW5kZXIoZGVwczogRXhwaXJlZFRva2VuUmVtaW5kZXJEZXBzLCB1cmdlbnQgPSBmYWxzZSk6IFByb21pc2U8bnVtYmVyPiB7XG4gIGNvbnN0IGluYWN0aXZlID0gYXdhaXQgZGVwcy5maW5kSW5hY3RpdmUoKTtcbiAgaWYgKGluYWN0aXZlLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDA7XG5cbiAgY29uc3QgdXNlck1hcCA9IGRlcHMuZ2V0U2xhY2tVc2VyTWFwKCk7XG5cbiAgYXdhaXQgZGVwcy5zZW5kU2xhY2soe1xuICAgIC8vIOunjOujjCDsiJzqsIQg7JWM66a86rO8IOqwmeydgCDsoJzrqqnsnYQg7JO064ukLiDqsJnsnYAg7IKs6rG07J2066+A66GcIOuLpOuluCDsnbTrpoTsnYQg67aZ7J2066m0IOuzhOqwnCDrrLjsoJzroZwg7J297Z6M64ukLlxuICAgIHRpdGxlOiBcIuyEuOyFmCDrp4zro4xcIixcbiAgICBzdWJqZWN0OiBpbmFjdGl2ZS5sZW5ndGggPiAxID8gYCR7aW5hY3RpdmUubGVuZ3RofeqxtGAgOiAoaW5hY3RpdmVbMF0hLm5hbWUgPz8gXCJ1bm5hbWVkXCIpLFxuICAgIGNvbnRleHQ6IGJ1aWxkUmVtaW5kZXJDb250ZXh0KGluYWN0aXZlLCB1c2VyTWFwKSxcbiAgICBjb2xvcjogU0xBQ0tfQ09MT1IuYmFkLFxuICAgIHVyZ2VudCxcbiAgfSk7XG4gIHJldHVybiBpbmFjdGl2ZS5sZW5ndGg7XG59XG5cbi8qKlxuICog7ZmU66m07J2YIFwi7KeA6riIIOuztOuCtOq4sFwiLiDsgqzrnozsnbQg7KeB7KCRIOuIhOuluCDqsoPsnbTrr4DroZwg7KGw7JqpIOyLnOqwhMK366eI7Iqk7YSwIOyKpOychOy5mOulvCDthrXqs7zsi5ztgqjri6Qg4oCUXG4gKiDriIzroIDripTrjbAg7JWE66y0IOydvOuPhCDslYgg7J287Ja064KY66m0IOuyhO2KvOydtCDqs6DsnqUg64KcIOqyg+ycvOuhnCDsnb3tnozri6QuXG4gKlxuICog67O064K4IOqxtOyImOulvCDrj4zroKTspJgg7Zi47Lac67aA6rCAIFwi67O064K8IOuMgOyDgSDsl4bsnYxcIuqzvCBcIuuztOuDhFwi7J2EIOq1rOu2hO2VtCDrs7Tsl6zspIDri6QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZW5kRXhwaXJlZFRva2VuUmVtaW5kZXJOb3coXG4gIGRlcHM6IEV4cGlyZWRUb2tlblJlbWluZGVyRGVwcyA9IGRlZmF1bHREZXBzLFxuKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgcmV0dXJuIHNlbmRSZW1pbmRlcihkZXBzLCB0cnVlKTtcbn1cblxubGV0IHRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRJbnRlcnZhbD4gfCBudWxsID0gbnVsbDtcblxuZnVuY3Rpb24gc2NoZWR1bGVFeHBpcmVkVG9rZW5SZW1pbmRlcihydW5Ob3c6IGJvb2xlYW4sIGRlcHM6IEV4cGlyZWRUb2tlblJlbWluZGVyRGVwcyk6IHZvaWQge1xuICBzdG9wRXhwaXJlZFRva2VuUmVtaW5kZXIoKTtcblxuICAvLyDso7zquLAg6rCS6rO8IOuzhOqwnOyduCDsiqTsnITsuZjri6QuIOq6vOuPhCDso7zquLDripQg64Ko7JWEIOyeiOyWtCDri6Tsi5wg7LykIOuVjCDqs6DrpbTrjZgg6rCS7J20IOq3uOuMgOuhnOuLpC5cbiAgaWYgKGRlcHMucmVhZFNldHRpbmcoXCJzbGFjay5yZW1pbmRlcnNFbmFibGVkXCIsIFwiU0xBQ0tfUkVNSU5ERVJTX0VOQUJMRURcIikgPT09IFwiZmFsc2VcIikge1xuICAgIGxvZ2dlci5pbmZvKFwiZXhwaXJlZCB0b2tlbiByZW1pbmRlciBkaXNhYmxlZFwiKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBtaW51dGVzID0gTnVtYmVyKFxuICAgIGRlcHMucmVhZFNldHRpbmcoXCJzbGFjay5leHBpcnlSZW1pbmRlck1pbnV0ZXNcIiwgXCJTTEFDS19FWFBJUllfUkVNSU5ERVJfSU5URVJWQUxfTUlOVVRFU1wiKSA/PyAwLFxuICApO1xuICBpZiAoIU51bWJlci5pc0Zpbml0ZShtaW51dGVzKSB8fCBtaW51dGVzIDw9IDApIHJldHVybjtcblxuICBsb2dnZXIuaW5mbyhcbiAgICBgZXhwaXJlZCB0b2tlbiByZW1pbmRlciBldmVyeSAke21pbnV0ZXN9bSAoJHtkZXBzLmdldFNsYWNrVXNlck1hcCgpLnNpemV9IHVzZXIgbWFwcGluZ3MpYCxcbiAgKTtcblxuICBjb25zdCBydW4gPSAoKSA9PlxuICAgIHNlbmRSZW1pbmRlcihkZXBzKS5jYXRjaCgoZSkgPT4gbG9nZ2VyLndhcm4oYHJlbWluZGVyIGZhaWxlZDogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKSk7XG5cbiAgaWYgKHJ1bk5vdykgdm9pZCBydW4oKTtcbiAgdGltZXIgPSBzZXRJbnRlcnZhbChydW4sIG1pbnV0ZXMgKiBNSU5VVEVfTVMpO1xufVxuXG4vKipcbiAqIGBTTEFDS19FWFBJUllfUkVNSU5ERVJfSU5URVJWQUxfTUlOVVRFU2Ag6rCAIOyWkeyImOydvCDrlYzrp4wg7Lyc7KeE64ukLiDrr7jshKTsoJXCtzAg7J2066m0IOu5hO2ZnOyEsS5cbiAqXG4gKiDsnbjsiqTthLTsiqTqsIAg7Jes65+sIOqwnOuptCDqsIHsnpAg67O064K464ukLiDrp4zro4wg7Iic6rCEIOyVjOumvOqzvCDri6zrpqwg7IOB7YOcIOuzgO2ZlOqwgCDsl4bslrQgREIg66GcIOyWteygnO2VoCDsiJhcbiAqIOyXhuqzoCwg7ZWY66OoIOuqhyDqsbQg7IiY7KSA7J206528IOykkeuzteydhCDqsJDsiJjtlZjripQg7Y647J20IOyeoOq4iCDsnqXsuZjrpbwg65GQ64qUIOqyg+uztOuLpCDrgqvri6QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGFydEV4cGlyZWRUb2tlblJlbWluZGVyKGRlcHM6IEV4cGlyZWRUb2tlblJlbWluZGVyRGVwcyA9IGRlZmF1bHREZXBzKTogdm9pZCB7XG4gIC8vIOq4sOuPmSDsp4Htm4Tsl5Drj4Qg7ZWcIOuyiCDrs7Trgrjri6QuIOyerOq4sOuPmeydgCDrsLDtj6zrgpgg7J6l7JWgIOuzteq1rCDrlYwg7J287Ja064KY64qU642wLCDqt7gg7Iuc7KCQ7JeQIOydtOuvuFxuICAvLyDrp4zro4zrkJwg7Yag7YGw7J20IOyeiOycvOuptCDssqsg7KO86riw6rCAIOuPjCDrlYzquYzsp4Ag7KGw7Jqp7ZWcIOqyg+ydtCDsnbTsg4HtlZjri6QuXG4gIHNjaGVkdWxlRXhwaXJlZFRva2VuUmVtaW5kZXIodHJ1ZSwgZGVwcyk7XG59XG5cbi8qKiDshKTsoJUg67OA6rK9IOyLnCDquLDsobQg7YOA7J2066i466eMIOyDiCDso7zquLDroZwg6rWQ7LK07ZWc64ukLiDsoIDsnqUg7J6Q7LK06rCAIOyVjOumvOydhCDrs7TrgrTsp4DripQg7JWK64qU64ukLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc2NoZWR1bGVFeHBpcmVkVG9rZW5SZW1pbmRlcihkZXBzOiBFeHBpcmVkVG9rZW5SZW1pbmRlckRlcHMgPSBkZWZhdWx0RGVwcyk6IHZvaWQge1xuICBzY2hlZHVsZUV4cGlyZWRUb2tlblJlbWluZGVyKGZhbHNlLCBkZXBzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN0b3BFeHBpcmVkVG9rZW5SZW1pbmRlcigpOiB2b2lkIHtcbiAgaWYgKCF0aW1lcikgcmV0dXJuO1xuICBjbGVhckludGVydmFsKHRpbWVyKTtcbiAgdGltZXIgPSBudWxsO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtQkEsTUFBTSxTQUFTLFVBQVUsQ0FBQyxTQUFTLGtCQUFrQixDQUFDO0FBRXRELE1BQU0sWUFBWTtBQVNsQixNQUFNLGNBQXdDO0NBQzVDLG9CQUFvQixXQUFXLGFBQWEsR0FBRztDQUMvQztDQUNBLGFBQWE7Q0FDYixXQUFXO0FBQ2I7Ozs7O0FBTUEsU0FBZ0IscUJBQ2QsUUFDQSxTQUNRO0NBQ1IsTUFBTSxZQUFZLE9BQU8sU0FBUztDQU9sQyxPQUFPLENBQUMsR0FOTSxPQUFPLEtBQUssVUFBVTtFQUNsQyxNQUFNLFVBQVUsV0FBVyxNQUFNLE1BQU0sT0FBTztFQUM5QyxNQUFNLFFBQVEsTUFBTSxRQUFRO0VBQzVCLElBQUksQ0FBQyxXQUFXLE9BQU87RUFDdkIsT0FBTyxVQUFVLEdBQUcsUUFBUSxHQUFHLFVBQVU7Q0FDM0MsQ0FDVyxHQUFPLGFBQWEsQ0FBQyxDQUFDLE9BQU8sT0FBTyxDQUFDLENBQUMsS0FBSyxJQUFJO0FBQzVEO0FBRUEsZUFBZSxhQUFhLE1BQWdDLFNBQVMsT0FBd0I7Q0FDM0YsTUFBTSxXQUFXLE1BQU0sS0FBSyxhQUFhO0NBQ3pDLElBQUksU0FBUyxXQUFXLEdBQUcsT0FBTztDQUVsQyxNQUFNLFVBQVUsS0FBSyxnQkFBZ0I7Q0FFckMsTUFBTSxLQUFLLFVBQVU7RUFFbkIsT0FBTztFQUNQLFNBQVMsU0FBUyxTQUFTLElBQUksR0FBRyxTQUFTLE9BQU8sS0FBTSxTQUFTLEVBQUUsQ0FBRSxRQUFRO0VBQzdFLFNBQVMscUJBQXFCLFVBQVUsT0FBTztFQUMvQyxPQUFPLFlBQVk7RUFDbkI7Q0FDRixDQUFDO0NBQ0QsT0FBTyxTQUFTO0FBQ2xCOzs7Ozs7O0FBUUEsU0FBZ0IsNEJBQ2QsT0FBaUMsYUFDaEI7Q0FDakIsT0FBTyxhQUFhLE1BQU0sSUFBSTtBQUNoQztBQUVBLElBQUksUUFBK0M7QUFFbkQsU0FBUyw2QkFBNkIsUUFBaUIsTUFBc0M7Q0FDM0YseUJBQXlCO0NBR3pCLElBQUksS0FBSyxZQUFZLDBCQUEwQix5QkFBeUIsTUFBTSxTQUFTO0VBQ3JGLE9BQU8sS0FBSyxpQ0FBaUM7RUFDN0M7Q0FDRjtDQUVBLE1BQU0sVUFBVSxPQUNkLEtBQUssWUFBWSwrQkFBK0Isd0NBQXdDLEtBQUssQ0FDL0Y7Q0FDQSxJQUFJLENBQUMsT0FBTyxTQUFTLE9BQU8sS0FBSyxXQUFXLEdBQUc7Q0FFL0MsT0FBTyxLQUNMLGdDQUFnQyxRQUFRLEtBQUssS0FBSyxnQkFBZ0IsQ0FBQyxDQUFDLEtBQUssZ0JBQzNFO0NBRUEsTUFBTSxZQUNKLGFBQWEsSUFBSSxDQUFDLENBQUMsT0FBTyxNQUFNLE9BQU8sS0FBSyxvQkFBcUIsRUFBWSxTQUFTLENBQUM7Q0FFekYsSUFBSSxRQUFRLEFBQUssSUFBSTtDQUNyQixRQUFRLFlBQVksS0FBSyxVQUFVLFNBQVM7QUFDOUM7Ozs7Ozs7QUFRQSxTQUFnQiwwQkFBMEIsT0FBaUMsYUFBbUI7Q0FHNUYsNkJBQTZCLE1BQU0sSUFBSTtBQUN6Qzs7QUFHQSxTQUFnQiwrQkFBK0IsT0FBaUMsYUFBbUI7Q0FDakcsNkJBQTZCLE9BQU8sSUFBSTtBQUMxQztBQUVBLFNBQWdCLDJCQUFpQztDQUMvQyxJQUFJLENBQUMsT0FBTztDQUNaLGNBQWMsS0FBSztDQUNuQixRQUFRO0FBQ1YifQ==
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorate.js";
|
|
1
3
|
import { getAccessToken, getExpiresAt, getRefreshToken } from "../../utils/providers/common/credentials.js";
|
|
2
4
|
import { CallerSchemaValidationError } from "../../utils/providers/common/schema-validation.js";
|
|
3
5
|
import { StreamEvents } from "./qgrid.types.js";
|
|
4
6
|
import { ToolSchemaCompositionError } from "./tool-emulation-schema.js";
|
|
5
7
|
import { QgridDispatcher, buildAndValidateStrictOutputSchema } from "./qgrid.dispatcher.js";
|
|
6
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorateMetadata.js";
|
|
7
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorate.js";
|
|
8
8
|
import { TokenModel } from "../token/token.model.js";
|
|
9
9
|
import { CONSOLE_CALLBACK_URL, RefreshFailedError, buildAuthUrl, exchangeCodeForTokens, fetchUsage, generatePKCE, refreshAccessToken } from "./oauth.js";
|
|
10
10
|
import { MICRO_USD, RequestLogModel } from "../request-log/request-log.model.js";
|
|
@@ -12,8 +12,8 @@ import { afterQuery, beforeQuery, finishRunAborted, finishRunWithError } from ".
|
|
|
12
12
|
import { TokenCredentials } from "../token/token.types.js";
|
|
13
13
|
import { deactivateAuthDeadToken, notifyTokenAdded } from "./token-death.js";
|
|
14
14
|
import { BadRequestException, BaseFrameClass, Sonamu, api, stream } from "sonamu";
|
|
15
|
-
import crypto from "node:crypto";
|
|
16
15
|
import { getLogger } from "@logtape/logtape";
|
|
16
|
+
import crypto from "node:crypto";
|
|
17
17
|
import { getCacheManagerRef } from "sonamu/cache";
|
|
18
18
|
//#region src/application/qgrid/qgrid.frame.ts
|
|
19
19
|
const pendingStreams = /* @__PURE__ */ new Map();
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getSetting } from "../setting/setting.store.js";
|
|
1
2
|
//#region src/application/qgrid/slack-user-map.ts
|
|
2
3
|
/**
|
|
3
4
|
* 토큰 소유자 → Slack 사용자 멘션.
|
|
@@ -30,20 +31,10 @@ function mentionFor(tokenName, userMap) {
|
|
|
30
31
|
const userId = userMap.get(ownerOf(tokenName));
|
|
31
32
|
return userId ? `<@${userId}>` : "";
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
* 호출되므로 캐시해 둔다.
|
|
36
|
-
*/
|
|
37
|
-
let cached = null;
|
|
38
|
-
function getSlackUserMap() {
|
|
39
|
-
cached ??= parseSlackUserMap(process.env.SLACK_USER_MAP);
|
|
40
|
-
return cached;
|
|
41
|
-
}
|
|
42
|
-
/** 테스트에서 env 를 바꿔 끼울 때 쓴다. */
|
|
43
|
-
function resetSlackUserMapCache() {
|
|
44
|
-
cached = null;
|
|
34
|
+
function getSlackUserMap(readSetting = getSetting) {
|
|
35
|
+
return parseSlackUserMap(readSetting("slack.userMap", "SLACK_USER_MAP"));
|
|
45
36
|
}
|
|
46
37
|
//#endregion
|
|
47
|
-
export { getSlackUserMap, mentionFor, ownerOf, parseSlackUserMap
|
|
38
|
+
export { getSlackUserMap, mentionFor, ownerOf, parseSlackUserMap };
|
|
48
39
|
|
|
49
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhY2stdXNlci1tYXAuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3FncmlkL3NsYWNrLXVzZXItbWFwLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICog7Yag7YGwIOyGjOycoOyekCDihpIgU2xhY2sg7IKs7Jqp7J6QIOupmOyFmC5cbiAqXG4gKiBTbGFjayDtkZzsi5wg7J2066aE6rO8IO2GoO2BsOuqheydtCDsnpDso7wg7Ja06riL64KYKGhhemXihpJoYXplLmxlZSwgYnllb25nanVu4oaScG90YWRvcykgYHVzZXJzLmxpc3RgXG4gKiDsnpDrj5kg66ek7Lmt7J2AIOyhsOyaqe2eiCDsi6TtjKjtlZzri6QuIOupmOyFmOydtCDruaDsp4DrqbQg7JWM66a87J20IOqwnOyduOyXkOqyjCDri7/sp4Ag7JWK7JWEIOuqqeyggSDsnpDssrTqsIBcbiAqIOyCrOudvOyngOuvgOuhnCBgU0xBQ0tfVVNFUl9NQVBgIOuqheyLnCDrp6TtlZHrp4wg7JO064ukLlxuICpcbiAqIOqzteyaqSDqs4TsoJUoYnlzdWNvLCBkZXYtY29tbW9uIOuTsSnsnYAg66ek7ZWR7JeQIOuEo+
|
|
40
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhY2stdXNlci1tYXAuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3FncmlkL3NsYWNrLXVzZXItbWFwLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICog7Yag7YGwIOyGjOycoOyekCDihpIgU2xhY2sg7IKs7Jqp7J6QIOupmOyFmC5cbiAqXG4gKiBTbGFjayDtkZzsi5wg7J2066aE6rO8IO2GoO2BsOuqheydtCDsnpDso7wg7Ja06riL64KYKGhhemXihpJoYXplLmxlZSwgYnllb25nanVu4oaScG90YWRvcykgYHVzZXJzLmxpc3RgXG4gKiDsnpDrj5kg66ek7Lmt7J2AIOyhsOyaqe2eiCDsi6TtjKjtlZzri6QuIOupmOyFmOydtCDruaDsp4DrqbQg7JWM66a87J20IOqwnOyduOyXkOqyjCDri7/sp4Ag7JWK7JWEIOuqqeyggSDsnpDssrTqsIBcbiAqIOyCrOudvOyngOuvgOuhnCBgU0xBQ0tfVVNFUl9NQVBgIOuqheyLnCDrp6TtlZHrp4wg7JO064ukLlxuICpcbiAqIOqzteyaqSDqs4TsoJUoYnlzdWNvLCBkZXYtY29tbW9uIOuTsSnsnYAg66ek7ZWR7JeQIOuEo+yngCDslYrripTri6Qg4oCUIOupmOyFmCDsl4bsnbQg7J2066aE66eMIOuCmOqwgOuKlCDqsoPsnbRcbiAqIOunnuuKlCDrj5nsnpHsnbTri6QuXG4gKi9cblxuaW1wb3J0IHsgZ2V0U2V0dGluZyB9IGZyb20gXCIuLi9zZXR0aW5nL3NldHRpbmcuc3RvcmVcIjtcblxuLyoqIGDthqDtgbDrqoU6U2xhY2tVc2VySWRgIOuqqeuhneydhCDtjIzsi7HtlZzri6QuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VTbGFja1VzZXJNYXAocmF3OiBzdHJpbmcgfCB1bmRlZmluZWQpOiBNYXA8c3RyaW5nLCBzdHJpbmc+IHtcbiAgY29uc3QgbWFwID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgaWYgKCFyYXcpIHJldHVybiBtYXA7XG5cbiAgZm9yIChjb25zdCBlbnRyeSBvZiByYXcuc3BsaXQoXCIsXCIpKSB7XG4gICAgY29uc3QgW25hbWUsIHVzZXJJZF0gPSBlbnRyeS5zcGxpdChcIjpcIikubWFwKChzKSA9PiBzLnRyaW0oKSk7XG4gICAgaWYgKG5hbWUgJiYgdXNlcklkKSBtYXAuc2V0KG5hbWUsIHVzZXJJZCk7XG4gIH1cbiAgcmV0dXJuIG1hcDtcbn1cblxuLyoqIGBhbnRocm9waWMveWRzYCDihpIgYHlkc2AuIHByb3ZpZGVyIHByZWZpeCDsl4bsnbQg7KCA7J6l65CcIOydtOumhOuPhCDqt7jrjIDroZwg67Cb64qU64ukLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG93bmVyT2YodG9rZW5OYW1lOiBzdHJpbmcgfCBudWxsKTogc3RyaW5nIHtcbiAgaWYgKCF0b2tlbk5hbWUpIHJldHVybiBcIlwiO1xuICBjb25zdCBzbGFzaCA9IHRva2VuTmFtZS5pbmRleE9mKFwiL1wiKTtcbiAgcmV0dXJuIHNsYXNoID09PSAtMSA/IHRva2VuTmFtZSA6IHRva2VuTmFtZS5zbGljZShzbGFzaCArIDEpO1xufVxuXG4vKiog66ek7ZWR7J20IOyeiOycvOuptCBgPEBVLi4uPmAsIOyXhuycvOuptCDruYgg66y47J6Q7Je0LiDtmLjstpzrtoDqsIAg66mY7IWYIOycoOustOuhnCDrrLjqtazrpbwg6rOg66W464ukLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lbnRpb25Gb3IodG9rZW5OYW1lOiBzdHJpbmcgfCBudWxsLCB1c2VyTWFwOiBNYXA8c3RyaW5nLCBzdHJpbmc+KTogc3RyaW5nIHtcbiAgY29uc3QgdXNlcklkID0gdXNlck1hcC5nZXQob3duZXJPZih0b2tlbk5hbWUpKTtcbiAgcmV0dXJuIHVzZXJJZCA/IGA8QCR7dXNlcklkfT5gIDogXCJcIjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNsYWNrVXNlck1hcChyZWFkU2V0dGluZzogdHlwZW9mIGdldFNldHRpbmcgPSBnZXRTZXR0aW5nKTogTWFwPHN0cmluZywgc3RyaW5nPiB7XG4gIHJldHVybiBwYXJzZVNsYWNrVXNlck1hcChyZWFkU2V0dGluZyhcInNsYWNrLnVzZXJNYXBcIiwgXCJTTEFDS19VU0VSX01BUFwiKSk7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFjQSxTQUFnQixrQkFBa0IsS0FBOEM7Q0FDOUUsTUFBTSxzQkFBTSxJQUFJLElBQW9CO0NBQ3BDLElBQUksQ0FBQyxLQUFLLE9BQU87Q0FFakIsS0FBSyxNQUFNLFNBQVMsSUFBSSxNQUFNLEdBQUcsR0FBRztFQUNsQyxNQUFNLENBQUMsTUFBTSxVQUFVLE1BQU0sTUFBTSxHQUFHLENBQUMsQ0FBQyxLQUFLLE1BQU0sRUFBRSxLQUFLLENBQUM7RUFDM0QsSUFBSSxRQUFRLFFBQVEsSUFBSSxJQUFJLE1BQU0sTUFBTTtDQUMxQztDQUNBLE9BQU87QUFDVDs7QUFHQSxTQUFnQixRQUFRLFdBQWtDO0NBQ3hELElBQUksQ0FBQyxXQUFXLE9BQU87Q0FDdkIsTUFBTSxRQUFRLFVBQVUsUUFBUSxHQUFHO0NBQ25DLE9BQU8sVUFBVSxLQUFLLFlBQVksVUFBVSxNQUFNLFFBQVEsQ0FBQztBQUM3RDs7QUFHQSxTQUFnQixXQUFXLFdBQTBCLFNBQXNDO0NBQ3pGLE1BQU0sU0FBUyxRQUFRLElBQUksUUFBUSxTQUFTLENBQUM7Q0FDN0MsT0FBTyxTQUFTLEtBQUssT0FBTyxLQUFLO0FBQ25DO0FBRUEsU0FBZ0IsZ0JBQWdCLGNBQWlDLFlBQWlDO0NBQ2hHLE9BQU8sa0JBQWtCLFlBQVksaUJBQWlCLGdCQUFnQixDQUFDO0FBQ3pFIn0=
|
|
@@ -70,7 +70,8 @@ function notifyLastActiveTokenDying(token, reasonCode) {
|
|
|
70
70
|
token.provider,
|
|
71
71
|
reasonCode
|
|
72
72
|
].filter(Boolean).join(" · ") + " · 풀이 비지 않도록 유지 중입니다. 전 토큰이 동시에 실패했다면 client_id 취소나 OAuth 계약 변경을 의심하세요",
|
|
73
|
-
color: SLACK_COLOR.bad
|
|
73
|
+
color: SLACK_COLOR.bad,
|
|
74
|
+
urgent: true
|
|
74
75
|
});
|
|
75
76
|
}
|
|
76
77
|
/** 로그인이 완료돼 토큰이 저장됐을 때. 신규·재로그인을 가리지 않는다. */
|
|
@@ -90,4 +91,4 @@ function notifyTokenAdded(name, provider) {
|
|
|
90
91
|
//#endregion
|
|
91
92
|
export { deactivateAuthDeadToken, notifyTokenAdded };
|
|
92
93
|
|
|
93
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4tZGVhdGguanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3FncmlkL3Rva2VuLWRlYXRoLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICog7IS47IWYIOunjOujjChhdXRoLWRlYWQpIO2GoO2BsOydmCDrnbzsmrDtjIUg7KCc7Jm4IOyngOygkC5cbiAqXG4gKiByZWZyZXNoIOqwgCDsnqzroZzqt7jsnbgg7Jm4IOuzteq1rCDrtojqsIDtlZwg7Iuk7Yyo66W8IOuwmO2ZmO2VnCDsiJzqsITsl5Drp4wg7Zi47Lac65Cc64ukLiDruYTtmZzshLHtmZTripRcbiAqIGBhY3RpdmU9dHJ1ZWAg7KGw6rG067aAIOqwseyLoCAx7ZqM7J206rOgLCDqt7gg6rCx7Iug7J2EIOydtOq4tCDtlITroZzshLjsiqTrp4wgU2xhY2sg7JWM66a87J2EIOuztOuCuOuLpCDigJRcbiAqIOqzteycoCBEQiDrpbwg7JOw64qUIOyduOyKpO2EtOyKpOqwgCDrqofsnbTrk6Ag7IKs6rG064u5IOyVjOumvOydgCAx6rG07J2064ukLlxuICovXG5pbXBvcnQgeyBnZXRMb2dnZXIgfSBmcm9tIFwiQGxvZ3RhcGUvbG9ndGFwZVwiO1xuXG5pbXBvcnQgeyBnZXRSZWZyZXNoVG9rZW4gfSBmcm9tIFwiLi4vLi4vdXRpbHMvcHJvdmlkZXJzL2NvbW1vbi9jcmVkZW50aWFsc1wiO1xuaW1wb3J0IHsgbm90aWZ5U2xhY2ssIFNMQUNLX0NPTE9SIH0gZnJvbSBcIi4uLy4uL3V0aWxzL3NsYWNrLW5vdGlmeVwiO1xuaW1wb3J0IHsgVG9rZW5Nb2RlbCB9IGZyb20gXCIuLi90b2tlbi90b2tlbi5tb2RlbFwiO1xuaW1wb3J0IHsgZ2V0U2xhY2tVc2VyTWFwLCBtZW50aW9uRm9yIH0gZnJvbSBcIi4vc2xhY2stdXNlci1tYXBcIjtcblxuY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwidG9rZW4tZGVhdGhcIl0pO1xuXG50eXBlIERlYWRUb2tlblJlZiA9IHtcbiAgaWQ6IG51bWJlcjtcbiAgbmFtZTogc3RyaW5nO1xuICBwcm92aWRlcjogc3RyaW5nO1xufTtcblxuLyoqXG4gKiBAcGFyYW0gdXNlZFJlZnJlc2hUb2tlbiDsi6TtjKjtlZwg7JqU7LKt7J20IOyLpOygnOuhnCDsgqzsmqntlZwgcmVmcmVzaCB0b2tlbi5cbiAqICAgcmVmcmVzaCB0b2tlbiDsnYAg7ZqM7KCEIOyggOyepeuQmOuvgOuhnCwg7J2066+4IO2ajOyghOuQnCDsmJsg7Yag7YGw7Jy866GcIOuKpuqyjCDrj4TssKntlZwg7J6s7Iuc64+E6rCAXG4gKiAgIDQwMCDsnYQg67Cb64qUIOqyg+
|
|
94
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4tZGVhdGguanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3FncmlkL3Rva2VuLWRlYXRoLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICog7IS47IWYIOunjOujjChhdXRoLWRlYWQpIO2GoO2BsOydmCDrnbzsmrDtjIUg7KCc7Jm4IOyngOygkC5cbiAqXG4gKiByZWZyZXNoIOqwgCDsnqzroZzqt7jsnbgg7Jm4IOuzteq1rCDrtojqsIDtlZwg7Iuk7Yyo66W8IOuwmO2ZmO2VnCDsiJzqsITsl5Drp4wg7Zi47Lac65Cc64ukLiDruYTtmZzshLHtmZTripRcbiAqIGBhY3RpdmU9dHJ1ZWAg7KGw6rG067aAIOqwseyLoCAx7ZqM7J206rOgLCDqt7gg6rCx7Iug7J2EIOydtOq4tCDtlITroZzshLjsiqTrp4wgU2xhY2sg7JWM66a87J2EIOuztOuCuOuLpCDigJRcbiAqIOqzteycoCBEQiDrpbwg7JOw64qUIOyduOyKpO2EtOyKpOqwgCDrqofsnbTrk6Ag7IKs6rG064u5IOyVjOumvOydgCAx6rG07J2064ukLlxuICovXG5pbXBvcnQgeyBnZXRMb2dnZXIgfSBmcm9tIFwiQGxvZ3RhcGUvbG9ndGFwZVwiO1xuXG5pbXBvcnQgeyBnZXRSZWZyZXNoVG9rZW4gfSBmcm9tIFwiLi4vLi4vdXRpbHMvcHJvdmlkZXJzL2NvbW1vbi9jcmVkZW50aWFsc1wiO1xuaW1wb3J0IHsgbm90aWZ5U2xhY2ssIFNMQUNLX0NPTE9SIH0gZnJvbSBcIi4uLy4uL3V0aWxzL3NsYWNrLW5vdGlmeVwiO1xuaW1wb3J0IHsgVG9rZW5Nb2RlbCB9IGZyb20gXCIuLi90b2tlbi90b2tlbi5tb2RlbFwiO1xuaW1wb3J0IHsgZ2V0U2xhY2tVc2VyTWFwLCBtZW50aW9uRm9yIH0gZnJvbSBcIi4vc2xhY2stdXNlci1tYXBcIjtcblxuY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwidG9rZW4tZGVhdGhcIl0pO1xuXG50eXBlIERlYWRUb2tlblJlZiA9IHtcbiAgaWQ6IG51bWJlcjtcbiAgbmFtZTogc3RyaW5nO1xuICBwcm92aWRlcjogc3RyaW5nO1xufTtcblxuLyoqXG4gKiBAcGFyYW0gdXNlZFJlZnJlc2hUb2tlbiDsi6TtjKjtlZwg7JqU7LKt7J20IOyLpOygnOuhnCDsgqzsmqntlZwgcmVmcmVzaCB0b2tlbi5cbiAqICAgcmVmcmVzaCB0b2tlbiDsnYAg7ZqM7KCEIOyggOyepeuQmOuvgOuhnCwg7J2066+4IO2ajOyghOuQnCDsmJsg7Yag7YGw7Jy866GcIOuKpuqyjCDrj4TssKntlZwg7J6s7Iuc64+E6rCAXG4gKiAgIDQwMCDsnYQg67Cb64qUIOqyg+ydgCDsoJXsg4Eg66CI7J207Iqk64ukLiBEQiDsnZgg7ZiE7J6sIOqwkuqzvCDri6TrpbTrqbQg7IKs66ed7Jy866GcIOuztOyngCDslYrripTri6QuXG4gKiBAcGFyYW0gcmVhc29uQ29kZSBgcHJvdmlkZXI6Y29kZWAg7ZiV7YOc7J2YIOuCtOu2gCDsvZTrk5wuIHByb3ZpZGVyIOydkeuLtSDrs7jrrLjsl5DripQg6rOE7KCVIOydtOuplOydvOydtOuCmFxuICogICDthqDtgbAg7KGw6rCB7J20IOyEnuydvCDsiJgg7J6I7Ja0IHJhdyDrqZTsi5zsp4Drpbwg6re464yA66GcIOyVjOumvOyXkCDsi6Psp4Ag7JWK64qU64ukLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVhY3RpdmF0ZUF1dGhEZWFkVG9rZW4oXG4gIHRva2VuOiBEZWFkVG9rZW5SZWYsXG4gIHVzZWRSZWZyZXNoVG9rZW46IHN0cmluZyxcbiAgcmVhc29uQ29kZTogc3RyaW5nLFxuKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IGN1cnJlbnQgPSBhd2FpdCBUb2tlbk1vZGVsLmZpbmRPbmUoXCJBXCIsIHsgaWQ6IHRva2VuLmlkIH0pO1xuICBpZiAoIWN1cnJlbnQpIHJldHVybiBmYWxzZTtcblxuICBjb25zdCBjdXJyZW50UmVmcmVzaFRva2VuID0gZ2V0UmVmcmVzaFRva2VuKGN1cnJlbnQuY3JlZGVudGlhbHMpO1xuICBpZiAoY3VycmVudFJlZnJlc2hUb2tlbiAmJiBjdXJyZW50UmVmcmVzaFRva2VuICE9PSB1c2VkUmVmcmVzaFRva2VuKSB7XG4gICAgbG9nZ2VyLmluZm8oXG4gICAgICBgc2tpcHBpbmcgYXV0aC1kZWF0aCBmb3IgJHt0b2tlbi5uYW1lfShpZD0ke3Rva2VuLmlkfSk6IHJlZnJlc2ggdG9rZW4gcm90YXRlZCBzaW5jZSB0aGlzIGF0dGVtcHRgLFxuICAgICk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgeyBkZWFjdGl2YXRlZCwga2VwdEFzTGFzdEFjdGl2ZSB9ID0gYXdhaXQgVG9rZW5Nb2RlbC5kZWFjdGl2YXRlSWZBY3RpdmUodG9rZW4uaWQpO1xuICBpZiAoIWRlYWN0aXZhdGVkKSB7XG4gICAgaWYgKGtlcHRBc0xhc3RBY3RpdmUpIG5vdGlmeUxhc3RBY3RpdmVUb2tlbkR5aW5nKHRva2VuLCByZWFzb25Db2RlKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBsb2dnZXIud2FybihgdG9rZW4gZGVhY3RpdmF0ZWQgKGF1dGggZGVhZCk6ICR7dG9rZW4ubmFtZX0oaWQ9JHt0b2tlbi5pZH0pIHJlYXNvbj0ke3JlYXNvbkNvZGV9YCk7XG4gIC8vIOunjOujjCDsp4Htm4TqsIAg7J6s66Gc6re47J247ZWY6riwIOqwgOyepSDsoovsnYAg7YOA7J2067CN7J2064ukLiDshozsnKDsnpDrpbwg66mY7IWY7ZW0IOq3uCDsiJzqsIQg64u57IKs7J6Q7JeQ6rKMXG4gIC8vIOq9guuKlOuLpCDigJQg64uk7J207KCc7Iqk7Yq466W8IOq4sOuLpOumrOuptCDri6TsnYwg7KO86riw6rmM7KeAIO2GoO2BsOydtCDruaDsp4Qg7LGE66GcIOuCqOuKlOuLpC5cbiAgY29uc3QgbWVudGlvbiA9IG1lbnRpb25Gb3IodG9rZW4ubmFtZSwgZ2V0U2xhY2tVc2VyTWFwKCkpO1xuICB2b2lkIG5vdGlmeVNsYWNrKHtcbiAgICB0aXRsZTogXCLshLjshZgg66eM66OMXCIsXG4gICAgc3ViamVjdDogdG9rZW4ubmFtZSxcbiAgICBjb250ZXh0OiBbbWVudGlvbiwgdG9rZW4ucHJvdmlkZXIsIHJlYXNvbkNvZGUsIFwi7J6s66Gc6re47J247J20IO2VhOyalO2VqeuLiOuLpFwiXVxuICAgICAgLmZpbHRlcihCb29sZWFuKVxuICAgICAgLmpvaW4oXCIgwrcgXCIpLFxuICAgIGNvbG9yOiBTTEFDS19DT0xPUi5iYWQsXG4gIH0pO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiDrp4jsp4Drp4kg7Zmc7ISxIO2GoO2BsOydtCDso73sl4jsnYQg65WM7J2YIOyVjOumvCDsv6jri6TsmrQuXG4gKlxuICog7J20IOqyveyasCDthqDtgbDsnYAg67mE7Zmc7ISx7ZmU65CY7KeAIOyViuqzoCDsgrTslYTrgqjsnLzrr4DroZwsIOuSpOuUsOultOuKlCDsmpTssq3rp4jri6Qg6rCZ7J2AIOyLpO2MqOulvCDrsJjrs7XtlbRcbiAqIOyVjOumvOydtCDtj63so7ztlZzri6QuIOu5hO2ZnOyEse2ZlCDshLHqs7Ug6rK966Gc6rCAIOyhsOqxtOu2gCBVUERBVEUg66GcIOykkeuzteydhCDrp4nripQg6rKD6rO8IOuLrOumrCDsl6zquLDsl5RcbiAqIOyDge2DnCDrs4DtmZTqsIAg7JeG7Ja0IERCIOuhnCDslrXsoJztlaAg7IiYIOyXhuuLpCDigJQgcHJvdmlkZXIg64uo7JyE66GcIOyLnOqwhCDssL3snYQg65GU64ukLlxuICovXG5jb25zdCBMQVNUX0FDVElWRV9BTEVSVF9DT09MRE9XTl9NUyA9IDMwICogNjAgKiAxMDAwO1xuY29uc3QgbGFzdEFjdGl2ZUFsZXJ0QXQgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuXG5mdW5jdGlvbiBub3RpZnlMYXN0QWN0aXZlVG9rZW5EeWluZyh0b2tlbjogRGVhZFRva2VuUmVmLCByZWFzb25Db2RlOiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgcHJldmlvdXMgPSBsYXN0QWN0aXZlQWxlcnRBdC5nZXQodG9rZW4ucHJvdmlkZXIpO1xuICBpZiAocHJldmlvdXMgIT09IHVuZGVmaW5lZCAmJiBub3cgLSBwcmV2aW91cyA8IExBU1RfQUNUSVZFX0FMRVJUX0NPT0xET1dOX01TKSByZXR1cm47XG4gIGxhc3RBY3RpdmVBbGVydEF0LnNldCh0b2tlbi5wcm92aWRlciwgbm93KTtcblxuICBjb25zdCBtZW50aW9uID0gbWVudGlvbkZvcih0b2tlbi5uYW1lLCBnZXRTbGFja1VzZXJNYXAoKSk7XG4gIHZvaWQgbm90aWZ5U2xhY2soe1xuICAgIHRpdGxlOiBcIuuniOyngOuniSDthqDtgbAg7IKs66edXCIsXG4gICAgc3ViamVjdDogdG9rZW4ubmFtZSxcbiAgICBjb250ZXh0OlxuICAgICAgW21lbnRpb24sIHRva2VuLnByb3ZpZGVyLCByZWFzb25Db2RlXS5maWx0ZXIoQm9vbGVhbikuam9pbihcIiDCtyBcIikgK1xuICAgICAgYCDCtyDtkoDsnbQg67mE7KeAIOyViuuPhOuhnSDsnKDsp4Ag7KSR7J6F64uI64ukLiBgICtcbiAgICAgIGDsoIQg7Yag7YGw7J20IOuPmeyLnOyXkCDsi6TtjKjtlojri6TrqbQgY2xpZW50X2lkIOy3qOyGjOuCmCBPQXV0aCDqs4Tslb0g67OA6rK97J2EIOydmOyLrO2VmOyEuOyalGAsXG4gICAgY29sb3I6IFNMQUNLX0NPTE9SLmJhZCxcbiAgICAvLyBwcm92aWRlciDsoITssrTqsIAg7KO97JeI64uk64qUIOyLoO2YuOuLpC4g7KGw7JqpIOyLnOqwhOyXkCDrrLvtnojrqbQg64uk7J2MIOq3vOustOydvOq5jOyngCDshJzruYTsiqTqsIAg66mI7LaY64ukLlxuICAgIHVyZ2VudDogdHJ1ZSxcbiAgfSk7XG59XG5cbi8qKiDroZzqt7jsnbjsnbQg7JmE66OM64+8IO2GoO2BsOydtCDsoIDsnqXrkJDsnYQg65WMLiDsi6Dqt5zCt+yerOuhnOq3uOyduOydhCDqsIDrpqzsp4Ag7JWK64qU64ukLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vdGlmeVRva2VuQWRkZWQobmFtZTogc3RyaW5nLCBwcm92aWRlcjogc3RyaW5nKTogdm9pZCB7XG4gIGxvZ2dlci5pbmZvKGB0b2tlbiBhZGRlZDogJHtuYW1lfSAoJHtwcm92aWRlcn0pYCk7XG4gIGNvbnN0IG1lbnRpb24gPSBtZW50aW9uRm9yKG5hbWUsIGdldFNsYWNrVXNlck1hcCgpKTtcbiAgdm9pZCBub3RpZnlTbGFjayh7XG4gICAgdGl0bGU6IFwi7Yag7YGwIOy2lOqwgFwiLFxuICAgIHN1YmplY3Q6IG5hbWUsXG4gICAgY29udGV4dDogW21lbnRpb24sIHByb3ZpZGVyLCBcIuyalOyyrSDsspjrpqzsl5Ag7IKs7Jqp65Cp64uI64ukXCJdLmZpbHRlcihCb29sZWFuKS5qb2luKFwiIMK3IFwiKSxcbiAgICBjb2xvcjogU0xBQ0tfQ09MT1IuZ29vZCxcbiAgfSk7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFjQSxNQUFNLFNBQVMsVUFBVSxDQUFDLFNBQVMsYUFBYSxDQUFDOzs7Ozs7OztBQWVqRCxlQUFzQix3QkFDcEIsT0FDQSxrQkFDQSxZQUNrQjtDQUNsQixNQUFNLFVBQVUsTUFBTSxXQUFXLFFBQVEsS0FBSyxFQUFFLElBQUksTUFBTSxHQUFHLENBQUM7Q0FDOUQsSUFBSSxDQUFDLFNBQVMsT0FBTztDQUVyQixNQUFNLHNCQUFzQixnQkFBZ0IsUUFBUSxXQUFXO0NBQy9ELElBQUksdUJBQXVCLHdCQUF3QixrQkFBa0I7RUFDbkUsT0FBTyxLQUNMLDJCQUEyQixNQUFNLEtBQUssTUFBTSxNQUFNLEdBQUcsNENBQ3ZEO0VBQ0EsT0FBTztDQUNUO0NBRUEsTUFBTSxFQUFFLGFBQWEscUJBQXFCLE1BQU0sV0FBVyxtQkFBbUIsTUFBTSxFQUFFO0NBQ3RGLElBQUksQ0FBQyxhQUFhO0VBQ2hCLElBQUksa0JBQWtCLDJCQUEyQixPQUFPLFVBQVU7RUFDbEUsT0FBTztDQUNUO0NBRUEsT0FBTyxLQUFLLGtDQUFrQyxNQUFNLEtBQUssTUFBTSxNQUFNLEdBQUcsV0FBVyxZQUFZO0NBRy9GLE1BQU0sVUFBVSxXQUFXLE1BQU0sTUFBTSxnQkFBZ0IsQ0FBQztDQUN4RCxBQUFLLFlBQVk7RUFDZixPQUFPO0VBQ1AsU0FBUyxNQUFNO0VBQ2YsU0FBUztHQUFDO0dBQVMsTUFBTTtHQUFVO0dBQVk7RUFBYSxDQUFDLENBQzFELE9BQU8sT0FBTyxDQUFDLENBQ2YsS0FBSyxLQUFLO0VBQ2IsT0FBTyxZQUFZO0NBQ3JCLENBQUM7Q0FDRCxPQUFPO0FBQ1Q7Ozs7Ozs7O0FBU0EsTUFBTSxnQ0FBZ0MsT0FBVTtBQUNoRCxNQUFNLG9DQUFvQixJQUFJLElBQW9CO0FBRWxELFNBQVMsMkJBQTJCLE9BQXFCLFlBQTBCO0NBQ2pGLE1BQU0sTUFBTSxLQUFLLElBQUk7Q0FDckIsTUFBTSxXQUFXLGtCQUFrQixJQUFJLE1BQU0sUUFBUTtDQUNyRCxJQUFJLGFBQWEsVUFBYSxNQUFNLFdBQVcsK0JBQStCO0NBQzlFLGtCQUFrQixJQUFJLE1BQU0sVUFBVSxHQUFHO0NBRXpDLE1BQU0sVUFBVSxXQUFXLE1BQU0sTUFBTSxnQkFBZ0IsQ0FBQztDQUN4RCxBQUFLLFlBQVk7RUFDZixPQUFPO0VBQ1AsU0FBUyxNQUFNO0VBQ2YsU0FDRTtHQUFDO0dBQVMsTUFBTTtHQUFVO0VBQVUsQ0FBQyxDQUFDLE9BQU8sT0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLLElBQ2hFO0VBRUYsT0FBTyxZQUFZO0VBRW5CLFFBQVE7Q0FDVixDQUFDO0FBQ0g7O0FBR0EsU0FBZ0IsaUJBQWlCLE1BQWMsVUFBd0I7Q0FDckUsT0FBTyxLQUFLLGdCQUFnQixLQUFLLElBQUksU0FBUyxFQUFFO0NBRWhELEFBQUssWUFBWTtFQUNmLE9BQU87RUFDUCxTQUFTO0VBQ1QsU0FBUztHQUpLLFdBQVcsTUFBTSxnQkFBZ0IsQ0FJckM7R0FBUztHQUFVO0VBQWMsQ0FBQyxDQUFDLE9BQU8sT0FBTyxDQUFDLENBQUMsS0FBSyxLQUFLO0VBQ3ZFLE9BQU8sWUFBWTtDQUNyQixDQUFDO0FBQ0gifQ==
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { getLogger } from "@logtape/logtape";
|
|
1
2
|
import { Buffer } from "node:buffer";
|
|
2
3
|
import { z } from "zod";
|
|
3
|
-
import { getLogger } from "@logtape/logtape";
|
|
4
4
|
//#region src/application/qgrid/tool-emulation.ts
|
|
5
5
|
const STRUCTURED_ENVELOPE_LIMITS = {
|
|
6
6
|
maxUtf8Bytes: 512 * 1024,
|
|
@@ -13,6 +13,12 @@ let TokenService;
|
|
|
13
13
|
_TokenService.getToken = (subset, id) => createSSRQuery("TokenModel", "findById", [subset, id], ["Token", "getToken"]);
|
|
14
14
|
_TokenService.getTokens = (subset, rawParams) => createSSRQuery("TokenModel", "findMany", [subset, rawParams], ["Token", "getTokens"]);
|
|
15
15
|
})(TokenService || (TokenService = {}));
|
|
16
|
+
let SettingService;
|
|
17
|
+
(function(_SettingService) {
|
|
18
|
+
_SettingService.getSetting = (subset, id) => createSSRQuery("SettingModel", "findById", [subset, id], ["Setting", "getSetting"]);
|
|
19
|
+
_SettingService.getSettings = (subset, rawParams) => createSSRQuery("SettingModel", "findMany", [subset, rawParams], ["Setting", "getSettings"]);
|
|
20
|
+
_SettingService.getSettingList = () => createSSRQuery("SettingModel", "listSettings", [], ["Setting", "getSettingList"]);
|
|
21
|
+
})(SettingService || (SettingService = {}));
|
|
16
22
|
let RequestLogStepService;
|
|
17
23
|
(function(_RequestLogStepService) {
|
|
18
24
|
_RequestLogStepService.getRequestLogStep = (subset, id) => createSSRQuery("RequestLogStepModel", "findById", [subset, id], ["RequestLogStep", "getRequestLogStep"]);
|
|
@@ -38,6 +44,6 @@ let MonitService;
|
|
|
38
44
|
_MonitService.monitInfo = () => createSSRQuery("MonitFrame", "monitInfo", [], ["Monit", "monitInfo"]);
|
|
39
45
|
})(MonitService || (MonitService = {}));
|
|
40
46
|
//#endregion
|
|
41
|
-
export { MonitService, QgridService, RequestLogService, RequestLogStepService, TokenService };
|
|
47
|
+
export { MonitService, QgridService, RequestLogService, RequestLogStepService, SettingService, TokenService };
|
|
42
48
|
|
|
43
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,
|
|
49
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcmllcy5nZW5lcmF0ZWQuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3F1ZXJpZXMuZ2VuZXJhdGVkLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGdlbmVyYXRlZFxuICog7KeB7KCRIOyImOygle2VmOyngCDrp4jshLjsmpQuXG4gKi9cblxuLyogb3hsaW50LWRpc2FibGUgKi9cblxuaW1wb3J0IHR5cGUgeyBTU1JRdWVyeSB9IGZyb20gXCJzb25hbXUvc3NyXCI7XG5cbi8vIFNTUlF1ZXJ5IO2XrO2NvCDtlajsiJhcbmZ1bmN0aW9uIGNyZWF0ZVNTUlF1ZXJ5KFxuICBtb2RlbE5hbWU6IHN0cmluZyxcbiAgbWV0aG9kTmFtZTogc3RyaW5nLFxuICBwYXJhbXM6IGFueVtdLFxuICBzZXJ2aWNlS2V5OiBbc3RyaW5nLCBzdHJpbmddLFxuKTogU1NSUXVlcnkge1xuICByZXR1cm4geyBtb2RlbE5hbWUsIG1ldGhvZE5hbWUsIHBhcmFtcywgc2VydmljZUtleSwgX19icmFuZDogXCJTU1JRdWVyeVwiIH0gYXMgU1NSUXVlcnk7XG59XG5cbmltcG9ydCB7IFJlcXVlc3RMb2dTdGVwTGlzdFBhcmFtcyB9IGZyb20gXCIuL3JlcXVlc3QtbG9nLXN0ZXAvcmVxdWVzdC1sb2ctc3RlcC50eXBlc1wiO1xuaW1wb3J0IHsgUmVxdWVzdExvZ0xpc3RQYXJhbXMgfSBmcm9tIFwiLi9yZXF1ZXN0LWxvZy9yZXF1ZXN0LWxvZy50eXBlc1wiO1xuaW1wb3J0IHsgU2V0dGluZ0xpc3RQYXJhbXMgfSBmcm9tIFwiLi9zZXR0aW5nL3NldHRpbmcudHlwZXNcIjtcbmltcG9ydCB7XG4gIFRva2VuU3Vic2V0S2V5LFxuICBTZXR0aW5nU3Vic2V0S2V5LFxuICBSZXF1ZXN0TG9nU3RlcFN1YnNldEtleSxcbiAgUmVxdWVzdExvZ1N1YnNldEtleSxcbn0gZnJvbSBcIi4vc29uYW11LmdlbmVyYXRlZFwiO1xuaW1wb3J0IHsgVG9rZW5MaXN0UGFyYW1zIH0gZnJvbSBcIi4vdG9rZW4vdG9rZW4udHlwZXNcIjtcblxuZXhwb3J0IG5hbWVzcGFjZSBUb2tlblNlcnZpY2Uge1xuICBleHBvcnQgY29uc3QgZ2V0VG9rZW4gPSA8VCBleHRlbmRzIFRva2VuU3Vic2V0S2V5PihzdWJzZXQ6IFQsIGlkOiBudW1iZXIpOiBTU1JRdWVyeSA9PlxuICAgIGNyZWF0ZVNTUlF1ZXJ5KFwiVG9rZW5Nb2RlbFwiLCBcImZpbmRCeUlkXCIsIFtzdWJzZXQsIGlkXSwgW1wiVG9rZW5cIiwgXCJnZXRUb2tlblwiXSk7XG5cbiAgZXhwb3J0IGNvbnN0IGdldFRva2VucyA9IDxUIGV4dGVuZHMgVG9rZW5TdWJzZXRLZXksIExQIGV4dGVuZHMgVG9rZW5MaXN0UGFyYW1zPihcbiAgICBzdWJzZXQ6IFQsXG4gICAgcmF3UGFyYW1zPzogTFAsXG4gICk6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXCJUb2tlbk1vZGVsXCIsIFwiZmluZE1hbnlcIiwgW3N1YnNldCwgcmF3UGFyYW1zXSwgW1wiVG9rZW5cIiwgXCJnZXRUb2tlbnNcIl0pO1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIFNldHRpbmdTZXJ2aWNlIHtcbiAgZXhwb3J0IGNvbnN0IGdldFNldHRpbmcgPSA8VCBleHRlbmRzIFNldHRpbmdTdWJzZXRLZXk+KHN1YnNldDogVCwgaWQ6IG51bWJlcik6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXCJTZXR0aW5nTW9kZWxcIiwgXCJmaW5kQnlJZFwiLCBbc3Vic2V0LCBpZF0sIFtcIlNldHRpbmdcIiwgXCJnZXRTZXR0aW5nXCJdKTtcblxuICBleHBvcnQgY29uc3QgZ2V0U2V0dGluZ3MgPSA8VCBleHRlbmRzIFNldHRpbmdTdWJzZXRLZXksIExQIGV4dGVuZHMgU2V0dGluZ0xpc3RQYXJhbXM+KFxuICAgIHN1YnNldDogVCxcbiAgICByYXdQYXJhbXM/OiBMUCxcbiAgKTogU1NSUXVlcnkgPT5cbiAgICBjcmVhdGVTU1JRdWVyeShcIlNldHRpbmdNb2RlbFwiLCBcImZpbmRNYW55XCIsIFtzdWJzZXQsIHJhd1BhcmFtc10sIFtcIlNldHRpbmdcIiwgXCJnZXRTZXR0aW5nc1wiXSk7XG5cbiAgZXhwb3J0IGNvbnN0IGdldFNldHRpbmdMaXN0ID0gKCk6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXCJTZXR0aW5nTW9kZWxcIiwgXCJsaXN0U2V0dGluZ3NcIiwgW10sIFtcIlNldHRpbmdcIiwgXCJnZXRTZXR0aW5nTGlzdFwiXSk7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgUmVxdWVzdExvZ1N0ZXBTZXJ2aWNlIHtcbiAgZXhwb3J0IGNvbnN0IGdldFJlcXVlc3RMb2dTdGVwID0gPFQgZXh0ZW5kcyBSZXF1ZXN0TG9nU3RlcFN1YnNldEtleT4oXG4gICAgc3Vic2V0OiBULFxuICAgIGlkOiBudW1iZXIsXG4gICk6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXG4gICAgICBcIlJlcXVlc3RMb2dTdGVwTW9kZWxcIixcbiAgICAgIFwiZmluZEJ5SWRcIixcbiAgICAgIFtzdWJzZXQsIGlkXSxcbiAgICAgIFtcIlJlcXVlc3RMb2dTdGVwXCIsIFwiZ2V0UmVxdWVzdExvZ1N0ZXBcIl0sXG4gICAgKTtcblxuICBleHBvcnQgY29uc3QgZ2V0UmVxdWVzdExvZ1N0ZXBzID0gPFxuICAgIFQgZXh0ZW5kcyBSZXF1ZXN0TG9nU3RlcFN1YnNldEtleSxcbiAgICBMUCBleHRlbmRzIFJlcXVlc3RMb2dTdGVwTGlzdFBhcmFtcyxcbiAgPihcbiAgICBzdWJzZXQ6IFQsXG4gICAgcmF3UGFyYW1zPzogTFAsXG4gICk6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXG4gICAgICBcIlJlcXVlc3RMb2dTdGVwTW9kZWxcIixcbiAgICAgIFwiZmluZE1hbnlcIixcbiAgICAgIFtzdWJzZXQsIHJhd1BhcmFtc10sXG4gICAgICBbXCJSZXF1ZXN0TG9nU3RlcFwiLCBcImdldFJlcXVlc3RMb2dTdGVwc1wiXSxcbiAgICApO1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIFJlcXVlc3RMb2dTZXJ2aWNlIHtcbiAgZXhwb3J0IGNvbnN0IGdldFJlcXVlc3RMb2cgPSA8VCBleHRlbmRzIFJlcXVlc3RMb2dTdWJzZXRLZXk+KHN1YnNldDogVCwgaWQ6IG51bWJlcik6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXCJSZXF1ZXN0TG9nTW9kZWxcIiwgXCJmaW5kQnlJZFwiLCBbc3Vic2V0LCBpZF0sIFtcIlJlcXVlc3RMb2dcIiwgXCJnZXRSZXF1ZXN0TG9nXCJdKTtcblxuICBleHBvcnQgY29uc3QgZ2V0UmVxdWVzdExvZ3MgPSA8VCBleHRlbmRzIFJlcXVlc3RMb2dTdWJzZXRLZXksIExQIGV4dGVuZHMgUmVxdWVzdExvZ0xpc3RQYXJhbXM+KFxuICAgIHN1YnNldDogVCxcbiAgICByYXdQYXJhbXM/OiBMUCxcbiAgKTogU1NSUXVlcnkgPT5cbiAgICBjcmVhdGVTU1JRdWVyeShcbiAgICAgIFwiUmVxdWVzdExvZ01vZGVsXCIsXG4gICAgICBcImZpbmRNYW55XCIsXG4gICAgICBbc3Vic2V0LCByYXdQYXJhbXNdLFxuICAgICAgW1wiUmVxdWVzdExvZ1wiLCBcImdldFJlcXVlc3RMb2dzXCJdLFxuICAgICk7XG59XG5cbmV4cG9ydCBuYW1lc3BhY2UgUWdyaWRTZXJ2aWNlIHtcbiAgZXhwb3J0IGNvbnN0IHN0YXRzID0gKCk6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXCJRZ3JpZEZyYW1lXCIsIFwic3RhdHNcIiwgW10sIFtcIlFncmlkXCIsIFwic3RhdHNcIl0pO1xuXG4gIGV4cG9ydCBjb25zdCB0b3RhbENvc3QgPSAocGFyYW1zPzogUmVxdWVzdExvZ0xpc3RQYXJhbXMpOiBTU1JRdWVyeSA9PlxuICAgIGNyZWF0ZVNTUlF1ZXJ5KFwiUWdyaWRGcmFtZVwiLCBcInRvdGFsQ29zdFwiLCBbcGFyYW1zXSwgW1wiUWdyaWRcIiwgXCJ0b3RhbENvc3RcIl0pO1xuXG4gIGV4cG9ydCBjb25zdCBwcm9qZWN0TmFtZXMgPSAoKTogU1NSUXVlcnkgPT5cbiAgICBjcmVhdGVTU1JRdWVyeShcIlFncmlkRnJhbWVcIiwgXCJwcm9qZWN0TmFtZXNcIiwgW10sIFtcIlFncmlkXCIsIFwicHJvamVjdE5hbWVzXCJdKTtcblxuICBleHBvcnQgY29uc3QgbW9kZWxOYW1lcyA9ICgpOiBTU1JRdWVyeSA9PlxuICAgIGNyZWF0ZVNTUlF1ZXJ5KFwiUWdyaWRGcmFtZVwiLCBcIm1vZGVsTmFtZXNcIiwgW10sIFtcIlFncmlkXCIsIFwibW9kZWxOYW1lc1wiXSk7XG5cbiAgZXhwb3J0IGNvbnN0IHVzYWdlID0gKHRva2VuSWQ/OiBudW1iZXIpOiBTU1JRdWVyeSA9PlxuICAgIGNyZWF0ZVNTUlF1ZXJ5KFwiUWdyaWRGcmFtZVwiLCBcInVzYWdlXCIsIFt0b2tlbklkXSwgW1wiUWdyaWRcIiwgXCJ1c2FnZVwiXSk7XG5cbiAgZXhwb3J0IGNvbnN0IGhlYWx0aCA9ICgpOiBTU1JRdWVyeSA9PlxuICAgIGNyZWF0ZVNTUlF1ZXJ5KFwiUWdyaWRGcmFtZVwiLCBcImhlYWx0aFwiLCBbXSwgW1wiUWdyaWRcIiwgXCJoZWFsdGhcIl0pO1xufVxuXG5leHBvcnQgbmFtZXNwYWNlIE1vbml0U2VydmljZSB7XG4gIGV4cG9ydCBjb25zdCBtb25pdExvZ3MgPSAoY3Vyc29yPzogbnVtYmVyKTogU1NSUXVlcnkgPT5cbiAgICBjcmVhdGVTU1JRdWVyeShcIk1vbml0RnJhbWVcIiwgXCJtb25pdExvZ3NcIiwgW2N1cnNvcl0sIFtcIk1vbml0XCIsIFwibW9uaXRMb2dzXCJdKTtcblxuICBleHBvcnQgY29uc3QgbW9uaXRJbmZvID0gKCk6IFNTUlF1ZXJ5ID0+XG4gICAgY3JlYXRlU1NSUXVlcnkoXCJNb25pdEZyYW1lXCIsIFwibW9uaXRJbmZvXCIsIFtdLCBbXCJNb25pdFwiLCBcIm1vbml0SW5mb1wiXSk7XG59XG4iXSwibWFwcGluZ3MiOiI7QUFVQSxTQUFTLGVBQ1AsV0FDQSxZQUNBLFFBQ0EsWUFDVTtDQUNWLE9BQU87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
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { SD } from "../../i18n/sd.generated.js";
|
|
2
|
-
import {
|
|
2
|
+
import { requestLogLoaderQueries, requestLogSubsetQueries } from "../sonamu.generated.sso.js";
|
|
3
3
|
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorateMetadata.js";
|
|
4
4
|
import __decorate from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorate.js";
|
|
5
|
-
import {
|
|
5
|
+
import { calculateCostUsd } from "../../utils/providers/common/model-cost.js";
|
|
6
6
|
import { BadRequestException, BaseModelClass, NotFoundException, Puri, api, asArray, transactional } from "sonamu";
|
|
7
7
|
//#region src/application/request-log/request-log.model.ts
|
|
8
8
|
const MICRO_USD = 1e6;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SD } from "../../i18n/sd.generated.js";
|
|
2
|
+
import { requestLogStepLoaderQueries, requestLogStepSubsetQueries } from "../sonamu.generated.sso.js";
|
|
2
3
|
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorateMetadata.js";
|
|
3
4
|
import __decorate from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorate.js";
|
|
4
|
-
import { requestLogStepLoaderQueries, requestLogStepSubsetQueries } from "../sonamu.generated.sso.js";
|
|
5
5
|
import { BadRequestException, BaseModelClass, NotFoundException, api, asArray, exhaustive } from "sonamu";
|
|
6
6
|
//#region src/application/request-log-step/request-log-step.model.ts
|
|
7
7
|
var RequestLogStepModelClass = class extends BaseModelClass {
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
//#region src/application/setting/setting.constant.ts
|
|
2
|
+
/** 64 GiB 운영 호스트에서 세 자리 오입력을 막는 설정 상한. 안전을 보장하는 값은 아니다. */
|
|
3
|
+
const MAX_OPENAI_ESTIMATED_RSS_GIB = 32;
|
|
4
|
+
const MAX_OPENAI_MIN_HOST_AVAILABLE_GIB = 64;
|
|
5
|
+
const SETTING_DEFS = [
|
|
6
|
+
{
|
|
7
|
+
key: "openai.autoscale",
|
|
8
|
+
fallback: "true",
|
|
9
|
+
group: "openai",
|
|
10
|
+
envKey: "QGRID_OPENAI_AUTOSCALE",
|
|
11
|
+
label: "OpenAI 워커 오토스케일",
|
|
12
|
+
kind: "boolean",
|
|
13
|
+
applies: "restart",
|
|
14
|
+
help: "끄면 워커 수가 최소값으로 고정됩니다"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
key: "openai.minWorkersPerToken",
|
|
18
|
+
fallback: "1",
|
|
19
|
+
group: "openai",
|
|
20
|
+
envKey: "QGRID_OPENAI_MIN_WORKERS_PER_TOKEN",
|
|
21
|
+
label: "토큰당 최소 워커",
|
|
22
|
+
kind: "integer",
|
|
23
|
+
applies: "restart",
|
|
24
|
+
min: 1,
|
|
25
|
+
max: 20
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
key: "openai.maxWorkersPerToken",
|
|
29
|
+
fallback: "3",
|
|
30
|
+
group: "openai",
|
|
31
|
+
envKey: "QGRID_OPENAI_MAX_WORKERS_PER_TOKEN",
|
|
32
|
+
label: "토큰당 최대 워커",
|
|
33
|
+
kind: "integer",
|
|
34
|
+
applies: "restart",
|
|
35
|
+
min: 1,
|
|
36
|
+
max: 20,
|
|
37
|
+
help: "오토스케일이 꺼져 있으면 무시됩니다"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
key: "openai.maxEstimatedRssGiB",
|
|
41
|
+
fallback: "16",
|
|
42
|
+
group: "openai",
|
|
43
|
+
envKey: "QGRID_OPENAI_MAX_ESTIMATED_RSS_GIB",
|
|
44
|
+
label: "워커 메모리 상한 (GiB)",
|
|
45
|
+
kind: "number",
|
|
46
|
+
applies: "restart",
|
|
47
|
+
min: 1,
|
|
48
|
+
max: 32,
|
|
49
|
+
help: "이 추정치를 넘기면 워커를 더 늘리지 않습니다. 올릴수록 OOM 위험이 커지며 상한은 오입력 방지용입니다"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
key: "openai.minHostAvailableGiB",
|
|
53
|
+
fallback: "20",
|
|
54
|
+
group: "openai",
|
|
55
|
+
envKey: "QGRID_OPENAI_MIN_HOST_AVAILABLE_GIB",
|
|
56
|
+
label: "호스트 여유 메모리 하한 (GiB)",
|
|
57
|
+
kind: "number",
|
|
58
|
+
applies: "restart",
|
|
59
|
+
min: 0,
|
|
60
|
+
max: 64,
|
|
61
|
+
help: "호스트 여유가 이 값 아래면 스케일업을 멈춥니다. 확장을 끄려면 오토스케일을 끄세요"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
key: "slack.enabled",
|
|
65
|
+
fallback: "true",
|
|
66
|
+
group: "slack",
|
|
67
|
+
envKey: "SLACK_ENABLED",
|
|
68
|
+
label: "Slack 알림",
|
|
69
|
+
kind: "boolean",
|
|
70
|
+
applies: "immediate",
|
|
71
|
+
help: "연휴처럼 규칙으로 잡을 수 없는 기간에 끕니다. 서비스 정지급 장애 알림은 꺼도 전달됩니다"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
key: "slack.remindersEnabled",
|
|
75
|
+
fallback: "true",
|
|
76
|
+
group: "slack",
|
|
77
|
+
envKey: "SLACK_REMINDERS_ENABLED",
|
|
78
|
+
label: "만료 알림 반복",
|
|
79
|
+
kind: "boolean",
|
|
80
|
+
applies: "immediate",
|
|
81
|
+
help: "끄면 반복만 멈추고 만료 순간의 알림은 그대로 갑니다"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
key: "slack.expiryReminderMinutes",
|
|
85
|
+
fallback: "60",
|
|
86
|
+
group: "slack",
|
|
87
|
+
envKey: "SLACK_EXPIRY_REMINDER_INTERVAL_MINUTES",
|
|
88
|
+
label: "반복 주기",
|
|
89
|
+
kind: "preset",
|
|
90
|
+
applies: "immediate",
|
|
91
|
+
presets: [
|
|
92
|
+
10,
|
|
93
|
+
30,
|
|
94
|
+
60,
|
|
95
|
+
180
|
|
96
|
+
],
|
|
97
|
+
help: "재로그인이 필요한 토큰이 남아 있는 동안 이 주기로 다시 알립니다"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
key: "slack.quietFromHour",
|
|
101
|
+
fallback: "20",
|
|
102
|
+
group: "slack",
|
|
103
|
+
envKey: "SLACK_QUIET_FROM_HOUR",
|
|
104
|
+
label: "조용 시간 시작",
|
|
105
|
+
kind: "integer",
|
|
106
|
+
applies: "immediate",
|
|
107
|
+
min: 0,
|
|
108
|
+
max: 23,
|
|
109
|
+
help: "이 시각부터 알리지 않습니다 (한국 시간)"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
key: "slack.quietUntilHour",
|
|
113
|
+
fallback: "8",
|
|
114
|
+
group: "slack",
|
|
115
|
+
envKey: "SLACK_QUIET_UNTIL_HOUR",
|
|
116
|
+
label: "조용 시간 종료",
|
|
117
|
+
kind: "integer",
|
|
118
|
+
applies: "immediate",
|
|
119
|
+
min: 0,
|
|
120
|
+
max: 23,
|
|
121
|
+
help: "이 시각부터 다시 알립니다. 시작보다 빠르면 자정을 넘는 구간이 됩니다"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
key: "slack.notifyOnWeekends",
|
|
125
|
+
fallback: "false",
|
|
126
|
+
group: "slack",
|
|
127
|
+
envKey: "SLACK_NOTIFY_ON_WEEKENDS",
|
|
128
|
+
label: "주말에도 알림",
|
|
129
|
+
kind: "boolean",
|
|
130
|
+
applies: "immediate",
|
|
131
|
+
help: "켜면 주말에도 위의 조용 시간 규칙만 적용됩니다"
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
key: "slack.channelId",
|
|
135
|
+
fallback: "",
|
|
136
|
+
group: "slackConnection",
|
|
137
|
+
envKey: "SLACK_CHANNEL_ID",
|
|
138
|
+
label: "Slack 채널 ID",
|
|
139
|
+
kind: "string",
|
|
140
|
+
applies: "immediate",
|
|
141
|
+
help: "사용자 ID(U...)를 넣으면 그 사람 DM 으로 갑니다"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
key: "slack.userMap",
|
|
145
|
+
fallback: "",
|
|
146
|
+
group: "slackConnection",
|
|
147
|
+
envKey: "SLACK_USER_MAP",
|
|
148
|
+
label: "Slack 사용자 매핑",
|
|
149
|
+
kind: "string",
|
|
150
|
+
applies: "immediate",
|
|
151
|
+
help: "토큰명:SlackUserId 를 쉼표로. 공용 계정은 넣지 않습니다"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
key: "slack.botToken",
|
|
155
|
+
fallback: "",
|
|
156
|
+
group: "slackConnection",
|
|
157
|
+
envKey: "SLACK_BOT_TOKEN",
|
|
158
|
+
label: "Slack 봇 토큰",
|
|
159
|
+
kind: "secret",
|
|
160
|
+
applies: "immediate"
|
|
161
|
+
}
|
|
162
|
+
];
|
|
163
|
+
function findSettingDef(key) {
|
|
164
|
+
return SETTING_DEFS.find((d) => d.key === key);
|
|
165
|
+
}
|
|
166
|
+
/** 저장 전 검증. 잘못된 값이 들어가면 런타임에서 조용히 기본값으로 떨어져 원인을 찾기 어렵다. */
|
|
167
|
+
function validateSettingValue(def, raw) {
|
|
168
|
+
const trimmed = raw.trim();
|
|
169
|
+
if (def.kind === "boolean") {
|
|
170
|
+
if (!["true", "false"].includes(trimmed)) return {
|
|
171
|
+
ok: false,
|
|
172
|
+
error: "true 또는 false"
|
|
173
|
+
};
|
|
174
|
+
return {
|
|
175
|
+
ok: true,
|
|
176
|
+
value: trimmed
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
if (def.kind === "preset") {
|
|
180
|
+
const parsed = Number(trimmed);
|
|
181
|
+
if (!def.presets?.includes(parsed)) return {
|
|
182
|
+
ok: false,
|
|
183
|
+
error: `${def.presets?.join(", ") ?? ""} 중 하나여야 합니다`
|
|
184
|
+
};
|
|
185
|
+
return {
|
|
186
|
+
ok: true,
|
|
187
|
+
value: String(parsed)
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
if (def.kind === "integer" || def.kind === "number") {
|
|
191
|
+
const parsed = Number(trimmed);
|
|
192
|
+
if (!Number.isFinite(parsed)) return {
|
|
193
|
+
ok: false,
|
|
194
|
+
error: "숫자를 입력하세요"
|
|
195
|
+
};
|
|
196
|
+
if (def.kind === "integer" && !Number.isInteger(parsed)) return {
|
|
197
|
+
ok: false,
|
|
198
|
+
error: "정수를 입력하세요"
|
|
199
|
+
};
|
|
200
|
+
if (def.min !== void 0 && parsed < def.min) return {
|
|
201
|
+
ok: false,
|
|
202
|
+
error: `${def.min} 이상이어야 합니다`
|
|
203
|
+
};
|
|
204
|
+
if (def.max !== void 0 && parsed > def.max) return {
|
|
205
|
+
ok: false,
|
|
206
|
+
error: `${def.max} 이하여야 합니다`
|
|
207
|
+
};
|
|
208
|
+
return {
|
|
209
|
+
ok: true,
|
|
210
|
+
value: String(parsed)
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
return {
|
|
214
|
+
ok: true,
|
|
215
|
+
value: trimmed
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/** 화면에 그대로 내려보내면 안 되는 값. 앞뒤만 남긴다. */
|
|
219
|
+
function maskSecret(value) {
|
|
220
|
+
if (value.length <= 12) return "***";
|
|
221
|
+
return `${value.slice(0, 8)}...${value.slice(-4)}`;
|
|
222
|
+
}
|
|
223
|
+
//#endregion
|
|
224
|
+
export { MAX_OPENAI_ESTIMATED_RSS_GIB, MAX_OPENAI_MIN_HOST_AVAILABLE_GIB, SETTING_DEFS, findSettingDef, maskSecret, validateSettingValue };
|
|
225
|
+
|
|
226
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dGluZy5jb25zdGFudC5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBwbGljYXRpb24vc2V0dGluZy9zZXR0aW5nLmNvbnN0YW50LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICog6rSA66asIOqwgOuKpe2VnCDrn7Dtg4DsnoQg7ISk7KCVIOuqqeuhnS5cbiAqXG4gKiDtgqTCt2VudiDsnbTrpoTCt+2DgOyehcK36rKA7Kad7J2EIO2VnCDqs7Psl5Ag66qo7JWEIEFQSSDsmYAgVUkg6rCAIOqwmeydgCDsoJXsnZjrpbwg67O464ukLiDsl6zquLAg7JeG64qUIGVudiDripRcbiAqIO2ZlOuptOyXkOyEnCDrsJTqv4Ag7IiYIOyXhuuLpCDigJQgREIg7KCR7IaNIOygleuztOuCmCDtj6ztirjsspjrn7wg7ISc67KE6rCAIOucqOq4sCDsoITsl5Ag7ZWE7JqU7ZWcIOqwkuuTpOydtOuLpC5cbiAqXG4gKiBgc2V0dGluZ3NgIO2FjOydtOu4lOydgCBgKGtleSwgdmFsdWUpYCDrrLjsnpDsl7Qg7IyN66eMIOuLtOuKlCDqt7jrpofsnbTrnbwoYHNldHRpbmcuZW50aXR5Lmpzb25gKSxcbiAqIFwi7J20IO2CpOqwgCDsoJXsiJjsnbjsp4DCt+uylOychOqwgCDslrzrp4jsnbjsp4DCt+2ZlOuptOyXkCDrrZDrnbzqs6Ag7JO47KeAXCLrpbwg64u07J2EIOqzs+ydtCDrlLDroZwg7ZWE7JqU7ZWY64ukLlxuICog6re4IOuplO2DgOuNsOydtO2EsOqwgCDsl6zquLAg7J6I64ukIOKAlCBEQiDsiqTtgqTrp4jqsIAg7JWE64uI6528IOyVseydtCDslYTripQg7IOB7IiYIOuqqeuhneydtOuLpC5cbiAqL1xuXG5leHBvcnQgdHlwZSBTZXR0aW5nS2luZCA9IFwiYm9vbGVhblwiIHwgXCJpbnRlZ2VyXCIgfCBcIm51bWJlclwiIHwgXCJzdHJpbmdcIiB8IFwic2VjcmV0XCIgfCBcInByZXNldFwiO1xuXG4vKipcbiAqIO2ZlOuptOyXkOyEnCDrrLbslrQg67O07Jes7KSEIOuLqOychC4g7Y+J7Y+J7ZWY6rKMIOuCmOyXtO2VmOuptCDslrTrlJTrpbwg67SQ7JW8IO2VoOyngCDslYwg7IiYIOyXhuuLpC5cbiAqXG4gKiBTbGFjayDsnYAgXCLslrjsoJwg67O064K86rmMXCIoc2xhY2sp7JmAIFwi7Ja065SU66GcIOuztOuCvOq5jFwiKHNsYWNrQ29ubmVjdGlvbinrpbwg64KY64iI64ukIOKAlCDslZ7snYAg7Jq07JiBXG4gKiDspJEg7J6Q7KO8IOunjOyngOqzoCDrkqTripQg7ZWcIOuyiCDrp57stpTrqbQg64Gd7J206528IOyImOuqheydtCDri6TrpbTri6QuXG4gKi9cbmV4cG9ydCB0eXBlIFNldHRpbmdHcm91cCA9IFwib3BlbmFpXCIgfCBcInNsYWNrXCIgfCBcInNsYWNrQ29ubmVjdGlvblwiO1xuXG5leHBvcnQgdHlwZSBTZXR0aW5nRGVmID0ge1xuICBrZXk6IHN0cmluZztcbiAgZ3JvdXA6IFNldHRpbmdHcm91cDtcbiAgZW52S2V5OiBzdHJpbmc7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIGtpbmQ6IFNldHRpbmdLaW5kO1xuICAvKiog7KCB7JqpIOyLnOygkC4g7JuM7LukIOyEpOygleydgCBkaXNwYXRjaGVyIOyDneyEseyekOyXkOyEnCDtlZwg67KI66eMIOydve2YgCDsnqzsi5zsnpHsnbQg7ZWE7JqU7ZWY64ukLiAqL1xuICBhcHBsaWVzOiBcImltbWVkaWF0ZVwiIHwgXCJyZXN0YXJ0XCI7XG4gIG1pbj86IG51bWJlcjtcbiAgbWF4PzogbnVtYmVyO1xuICAvKiogYHByZXNldGAg7KKF66WY7JeQ7IScIOqzoOulvCDsiJgg7J6I64qUIOqwki4g7J20IOuqqeuhnSDrsJbsnZgg6rCS7J2AIOyggOyepeuQmOyngCDslYrripTri6QuICovXG4gIHByZXNldHM/OiBudW1iZXJbXTtcbiAgLyoqXG4gICAqIOyggOyepeqwkuuPhCBlbnYg64+EIOyXhuydhCDrlYwg7Iuk7KCc66GcIOyggeyaqeuQmOuKlCDqsJIuIO2ZlOuptOydhCDruYTsm4zrkZDrqbQgXCLshKTsoJUg7JWIIOuQqFwi7Jy866GcIOydve2eiOyngOunjFxuICAgKiDsi6TsoJzroZzripQg7J20IOqwkuydtCDrj4zqs6Ag7J6I64ukIOKAlCDshozruYTsspjsnZgg6riw67O46rCS6rO8IOuwmOuTnOyLnCDqsJnslYTslbwg7ZWc64ukLlxuICAgKi9cbiAgZmFsbGJhY2s6IHN0cmluZztcbiAgaGVscD86IHN0cmluZztcbn07XG5cbi8qKiA2NCBHaUIg7Jq07JiBIO2YuOyKpO2KuOyXkOyEnCDshLgg7J6Q66asIOyYpOyeheugpeydhCDrp4nripQg7ISk7KCVIOyDge2VnC4g7JWI7KCE7J2EIOuztOyepe2VmOuKlCDqsJLsnYAg7JWE64uI64ukLiAqL1xuZXhwb3J0IGNvbnN0IE1BWF9PUEVOQUlfRVNUSU1BVEVEX1JTU19HSUIgPSAzMjtcbmV4cG9ydCBjb25zdCBNQVhfT1BFTkFJX01JTl9IT1NUX0FWQUlMQUJMRV9HSUIgPSA2NDtcblxuZXhwb3J0IGNvbnN0IFNFVFRJTkdfREVGUzogU2V0dGluZ0RlZltdID0gW1xuICB7XG4gICAga2V5OiBcIm9wZW5haS5hdXRvc2NhbGVcIixcbiAgICBmYWxsYmFjazogXCJ0cnVlXCIsXG4gICAgZ3JvdXA6IFwib3BlbmFpXCIsXG4gICAgZW52S2V5OiBcIlFHUklEX09QRU5BSV9BVVRPU0NBTEVcIixcbiAgICBsYWJlbDogXCJPcGVuQUkg7JuM7LukIOyYpO2GoOyKpOy8gOydvFwiLFxuICAgIGtpbmQ6IFwiYm9vbGVhblwiLFxuICAgIGFwcGxpZXM6IFwicmVzdGFydFwiLFxuICAgIGhlbHA6IFwi64GE66m0IOybjOy7pCDsiJjqsIAg7LWc7IaM6rCS7Jy866GcIOqzoOygleuQqeuLiOuLpFwiLFxuICB9LFxuICB7XG4gICAga2V5OiBcIm9wZW5haS5taW5Xb3JrZXJzUGVyVG9rZW5cIixcbiAgICBmYWxsYmFjazogXCIxXCIsXG4gICAgZ3JvdXA6IFwib3BlbmFpXCIsXG4gICAgZW52S2V5OiBcIlFHUklEX09QRU5BSV9NSU5fV09SS0VSU19QRVJfVE9LRU5cIixcbiAgICBsYWJlbDogXCLthqDtgbDri7kg7LWc7IaMIOybjOy7pFwiLFxuICAgIGtpbmQ6IFwiaW50ZWdlclwiLFxuICAgIGFwcGxpZXM6IFwicmVzdGFydFwiLFxuICAgIG1pbjogMSxcbiAgICBtYXg6IDIwLFxuICB9LFxuICB7XG4gICAga2V5OiBcIm9wZW5haS5tYXhXb3JrZXJzUGVyVG9rZW5cIixcbiAgICBmYWxsYmFjazogXCIzXCIsXG4gICAgZ3JvdXA6IFwib3BlbmFpXCIsXG4gICAgZW52S2V5OiBcIlFHUklEX09QRU5BSV9NQVhfV09SS0VSU19QRVJfVE9LRU5cIixcbiAgICBsYWJlbDogXCLthqDtgbDri7kg7LWc64yAIOybjOy7pFwiLFxuICAgIGtpbmQ6IFwiaW50ZWdlclwiLFxuICAgIGFwcGxpZXM6IFwicmVzdGFydFwiLFxuICAgIG1pbjogMSxcbiAgICBtYXg6IDIwLFxuICAgIGhlbHA6IFwi7Jik7Yag7Iqk7LyA7J287J20IOq6vOyguCDsnojsnLzrqbQg66y07Iuc65Cp64uI64ukXCIsXG4gIH0sXG4gIHtcbiAgICBrZXk6IFwib3BlbmFpLm1heEVzdGltYXRlZFJzc0dpQlwiLFxuICAgIGZhbGxiYWNrOiBcIjE2XCIsXG4gICAgZ3JvdXA6IFwib3BlbmFpXCIsXG4gICAgZW52S2V5OiBcIlFHUklEX09QRU5BSV9NQVhfRVNUSU1BVEVEX1JTU19HSUJcIixcbiAgICBsYWJlbDogXCLsm4zsu6Qg66mU66qo66asIOyDge2VnCAoR2lCKVwiLFxuICAgIGtpbmQ6IFwibnVtYmVyXCIsXG4gICAgYXBwbGllczogXCJyZXN0YXJ0XCIsXG4gICAgbWluOiAxLFxuICAgIG1heDogTUFYX09QRU5BSV9FU1RJTUFURURfUlNTX0dJQixcbiAgICBoZWxwOiBcIuydtCDstpTsoJXsuZjrpbwg64SY6riw66m0IOybjOy7pOulvCDrjZQg64qY66as7KeAIOyViuyKteuLiOuLpC4g7Jis66a07IiY66GdIE9PTSDsnITtl5jsnbQg7Luk7KeA66mwIOyDge2VnOydgCDsmKTsnoXroKUg67Cp7KeA7Jqp7J6F64uI64ukXCIsXG4gIH0sXG4gIHtcbiAgICBrZXk6IFwib3BlbmFpLm1pbkhvc3RBdmFpbGFibGVHaUJcIixcbiAgICBmYWxsYmFjazogXCIyMFwiLFxuICAgIGdyb3VwOiBcIm9wZW5haVwiLFxuICAgIGVudktleTogXCJRR1JJRF9PUEVOQUlfTUlOX0hPU1RfQVZBSUxBQkxFX0dJQlwiLFxuICAgIGxhYmVsOiBcIu2YuOyKpO2KuCDsl6zsnKAg66mU66qo66asIO2VmO2VnCAoR2lCKVwiLFxuICAgIGtpbmQ6IFwibnVtYmVyXCIsXG4gICAgYXBwbGllczogXCJyZXN0YXJ0XCIsXG4gICAgbWluOiAwLFxuICAgIG1heDogTUFYX09QRU5BSV9NSU5fSE9TVF9BVkFJTEFCTEVfR0lCLFxuICAgIGhlbHA6IFwi7Zi47Iqk7Yq4IOyXrOycoOqwgCDsnbQg6rCSIOyVhOuemOuptCDsiqTsvIDsnbzsl4XsnYQg66mI7Lal64uI64ukLiDtmZXsnqXsnYQg64GE66Ck66m0IOyYpO2GoOyKpOy8gOydvOydhCDrgYTshLjsmpRcIixcbiAgfSxcbiAge1xuICAgIGtleTogXCJzbGFjay5lbmFibGVkXCIsXG4gICAgZmFsbGJhY2s6IFwidHJ1ZVwiLFxuICAgIGdyb3VwOiBcInNsYWNrXCIsXG4gICAgZW52S2V5OiBcIlNMQUNLX0VOQUJMRURcIixcbiAgICBsYWJlbDogXCJTbGFjayDslYzrprxcIixcbiAgICBraW5kOiBcImJvb2xlYW5cIixcbiAgICBhcHBsaWVzOiBcImltbWVkaWF0ZVwiLFxuICAgIGhlbHA6IFwi7Jew7Zy07LKY65+8IOq3nOy5meycvOuhnCDsnqHsnYQg7IiYIOyXhuuKlCDquLDqsITsl5Ag64GV64uI64ukLiDshJzruYTsiqQg7KCV7KeA6riJIOyepeyVoCDslYzrprzsnYAg6rq864+EIOyghOuLrOuQqeuLiOuLpFwiLFxuICB9LFxuICB7XG4gICAga2V5OiBcInNsYWNrLnJlbWluZGVyc0VuYWJsZWRcIixcbiAgICBmYWxsYmFjazogXCJ0cnVlXCIsXG4gICAgZ3JvdXA6IFwic2xhY2tcIixcbiAgICBlbnZLZXk6IFwiU0xBQ0tfUkVNSU5ERVJTX0VOQUJMRURcIixcbiAgICBsYWJlbDogXCLrp4zro4wg7JWM66a8IOuwmOuztVwiLFxuICAgIGtpbmQ6IFwiYm9vbGVhblwiLFxuICAgIGFwcGxpZXM6IFwiaW1tZWRpYXRlXCIsXG4gICAgaGVscDogXCLrgYTrqbQg67CY67O166eMIOupiOy2lOqzoCDrp4zro4wg7Iic6rCE7J2YIOyVjOumvOydgCDqt7jrjIDroZwg6rCR64uI64ukXCIsXG4gIH0sXG4gIHtcbiAgICBrZXk6IFwic2xhY2suZXhwaXJ5UmVtaW5kZXJNaW51dGVzXCIsXG4gICAgZmFsbGJhY2s6IFwiNjBcIixcbiAgICBncm91cDogXCJzbGFja1wiLFxuICAgIGVudktleTogXCJTTEFDS19FWFBJUllfUkVNSU5ERVJfSU5URVJWQUxfTUlOVVRFU1wiLFxuICAgIGxhYmVsOiBcIuuwmOuztSDso7zquLBcIixcbiAgICBraW5kOiBcInByZXNldFwiLFxuICAgIGFwcGxpZXM6IFwiaW1tZWRpYXRlXCIsXG4gICAgLy8g7J6Q7JygIOyeheugpSDrjIDsi6Ag6rOg7KCVIOyEoO2DneyngOulvCDsk7Tri6Qg4oCUIFwi7Ja866eI64KYIOyekOyjvCDsnqzstIntlaDquYxcIuudvOyEnCAx67aEIOuLqOychCDsoJXrsIDrj4TqsIBcbiAgICAvLyDsnZjrr7gg7JeG6rOgLCDsnpjrqrsg64Sj7Jy866m0IOyxhOuEkOydtCDsi5zrgYTrn6zsm4zsp4Tri6QuIOuBhOuKlCDqsoPsnYAgcmVtaW5kZXJzRW5hYmxlZCDqsIAg66eh64qU64ukLlxuICAgIHByZXNldHM6IFsxMCwgMzAsIDYwLCAxODBdLFxuICAgIGhlbHA6IFwi7J6s66Gc6re47J247J20IO2VhOyalO2VnCDthqDtgbDsnbQg64Ko7JWEIOyeiOuKlCDrj5nslYgg7J20IOyjvOq4sOuhnCDri6Tsi5wg7JWM66a964uI64ukXCIsXG4gIH0sXG4gIHtcbiAgICBrZXk6IFwic2xhY2sucXVpZXRGcm9tSG91clwiLFxuICAgIGZhbGxiYWNrOiBcIjIwXCIsXG4gICAgZ3JvdXA6IFwic2xhY2tcIixcbiAgICBlbnZLZXk6IFwiU0xBQ0tfUVVJRVRfRlJPTV9IT1VSXCIsXG4gICAgbGFiZWw6IFwi7KGw7JqpIOyLnOqwhCDsi5zsnpFcIixcbiAgICBraW5kOiBcImludGVnZXJcIixcbiAgICBhcHBsaWVzOiBcImltbWVkaWF0ZVwiLFxuICAgIG1pbjogMCxcbiAgICBtYXg6IDIzLFxuICAgIGhlbHA6IFwi7J20IOyLnOqwgeu2gO2EsCDslYzrpqzsp4Ag7JWK7Iq164uI64ukICjtlZzqta0g7Iuc6rCEKVwiLFxuICB9LFxuICB7XG4gICAga2V5OiBcInNsYWNrLnF1aWV0VW50aWxIb3VyXCIsXG4gICAgZmFsbGJhY2s6IFwiOFwiLFxuICAgIGdyb3VwOiBcInNsYWNrXCIsXG4gICAgZW52S2V5OiBcIlNMQUNLX1FVSUVUX1VOVElMX0hPVVJcIixcbiAgICBsYWJlbDogXCLsobDsmqkg7Iuc6rCEIOyiheujjFwiLFxuICAgIGtpbmQ6IFwiaW50ZWdlclwiLFxuICAgIGFwcGxpZXM6IFwiaW1tZWRpYXRlXCIsXG4gICAgbWluOiAwLFxuICAgIG1heDogMjMsXG4gICAgaGVscDogXCLsnbQg7Iuc6rCB67aA7YSwIOuLpOyLnCDslYzrpr3ri4jri6QuIOyLnOyekeuztOuLpCDruaDrpbTrqbQg7J6Q7KCV7J2EIOuEmOuKlCDqtazqsITsnbQg65Cp64uI64ukXCIsXG4gIH0sXG4gIHtcbiAgICBrZXk6IFwic2xhY2subm90aWZ5T25XZWVrZW5kc1wiLFxuICAgIGZhbGxiYWNrOiBcImZhbHNlXCIsXG4gICAgZ3JvdXA6IFwic2xhY2tcIixcbiAgICBlbnZLZXk6IFwiU0xBQ0tfTk9USUZZX09OX1dFRUtFTkRTXCIsXG4gICAgbGFiZWw6IFwi7KO866eQ7JeQ64+EIOyVjOumvFwiLFxuICAgIGtpbmQ6IFwiYm9vbGVhblwiLFxuICAgIGFwcGxpZXM6IFwiaW1tZWRpYXRlXCIsXG4gICAgaGVscDogXCLsvJzrqbQg7KO866eQ7JeQ64+EIOychOydmCDsobDsmqkg7Iuc6rCEIOq3nOy5meunjCDsoIHsmqnrkKnri4jri6RcIixcbiAgfSxcbiAge1xuICAgIGtleTogXCJzbGFjay5jaGFubmVsSWRcIixcbiAgICBmYWxsYmFjazogXCJcIixcbiAgICBncm91cDogXCJzbGFja0Nvbm5lY3Rpb25cIixcbiAgICBlbnZLZXk6IFwiU0xBQ0tfQ0hBTk5FTF9JRFwiLFxuICAgIGxhYmVsOiBcIlNsYWNrIOyxhOuEkCBJRFwiLFxuICAgIGtpbmQ6IFwic3RyaW5nXCIsXG4gICAgYXBwbGllczogXCJpbW1lZGlhdGVcIixcbiAgICBoZWxwOiBcIuyCrOyaqeyekCBJRChVLi4uKeulvCDrhKPsnLzrqbQg6re4IOyCrOuejCBETSDsnLzroZwg6rCR64uI64ukXCIsXG4gIH0sXG4gIHtcbiAgICBrZXk6IFwic2xhY2sudXNlck1hcFwiLFxuICAgIGZhbGxiYWNrOiBcIlwiLFxuICAgIGdyb3VwOiBcInNsYWNrQ29ubmVjdGlvblwiLFxuICAgIGVudktleTogXCJTTEFDS19VU0VSX01BUFwiLFxuICAgIGxhYmVsOiBcIlNsYWNrIOyCrOyaqeyekCDrp6TtlZFcIixcbiAgICBraW5kOiBcInN0cmluZ1wiLFxuICAgIGFwcGxpZXM6IFwiaW1tZWRpYXRlXCIsXG4gICAgaGVscDogXCLthqDtgbDrqoU6U2xhY2tVc2VySWQg66W8IOyJvO2RnOuhnC4g6rO17JqpIOqzhOygleydgCDrhKPsp4Ag7JWK7Iq164uI64ukXCIsXG4gIH0sXG4gIHtcbiAgICBrZXk6IFwic2xhY2suYm90VG9rZW5cIixcbiAgICBmYWxsYmFjazogXCJcIixcbiAgICBncm91cDogXCJzbGFja0Nvbm5lY3Rpb25cIixcbiAgICBlbnZLZXk6IFwiU0xBQ0tfQk9UX1RPS0VOXCIsXG4gICAgbGFiZWw6IFwiU2xhY2sg67SHIO2GoO2BsFwiLFxuICAgIGtpbmQ6IFwic2VjcmV0XCIsXG4gICAgYXBwbGllczogXCJpbW1lZGlhdGVcIixcbiAgfSxcbl07XG5cbmV4cG9ydCBmdW5jdGlvbiBmaW5kU2V0dGluZ0RlZihrZXk6IHN0cmluZyk6IFNldHRpbmdEZWYgfCB1bmRlZmluZWQge1xuICByZXR1cm4gU0VUVElOR19ERUZTLmZpbmQoKGQpID0+IGQua2V5ID09PSBrZXkpO1xufVxuXG4vKiog7KCA7J6lIOyghCDqsoDspp0uIOyemOuqu+uQnCDqsJLsnbQg65Ok7Ja06rCA66m0IOufsO2DgOyehOyXkOyEnCDsobDsmqntnogg6riw67O46rCS7Jy866GcIOuWqOyWtOyguCDsm5DsnbjsnYQg7LC+6riwIOyWtOugteuLpC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVNldHRpbmdWYWx1ZShcbiAgZGVmOiBTZXR0aW5nRGVmLFxuICByYXc6IHN0cmluZyxcbik6IHsgb2s6IHRydWU7IHZhbHVlOiBzdHJpbmcgfSB8IHsgb2s6IGZhbHNlOyBlcnJvcjogc3RyaW5nIH0ge1xuICBjb25zdCB0cmltbWVkID0gcmF3LnRyaW0oKTtcblxuICBpZiAoZGVmLmtpbmQgPT09IFwiYm9vbGVhblwiKSB7XG4gICAgaWYgKCFbXCJ0cnVlXCIsIFwiZmFsc2VcIl0uaW5jbHVkZXModHJpbW1lZCkpIHJldHVybiB7IG9rOiBmYWxzZSwgZXJyb3I6IFwidHJ1ZSDrmJDripQgZmFsc2VcIiB9O1xuICAgIHJldHVybiB7IG9rOiB0cnVlLCB2YWx1ZTogdHJpbW1lZCB9O1xuICB9XG5cbiAgaWYgKGRlZi5raW5kID09PSBcInByZXNldFwiKSB7XG4gICAgLy8g7ZmU66m07J2AIOuyhO2KvOunjCDso7zsp4Drp4wgQVBJIOuKlCDslYTrrLQg6rCS7J2064KYIOuwm+ydhCDsiJgg7J6I64ukLiDrqqnroZ0g67CW7J2YIOqwkuydtCDrk6TslrTsmKTrqbRcbiAgICAvLyDtmZTrqbTsl5DshJwg7JWE66y0IOuyhO2KvOuPhCDshKDtg53rj7wg67O07J207KeAIOyViuyVhCBcIuyZnCDslYgg67CU64CM7KeAXCLqsIAg65Cc64ukLlxuICAgIGNvbnN0IHBhcnNlZCA9IE51bWJlcih0cmltbWVkKTtcbiAgICBpZiAoIWRlZi5wcmVzZXRzPy5pbmNsdWRlcyhwYXJzZWQpKSB7XG4gICAgICByZXR1cm4geyBvazogZmFsc2UsIGVycm9yOiBgJHtkZWYucHJlc2V0cz8uam9pbihcIiwgXCIpID8/IFwiXCJ9IOykkSDtlZjrgpjsl6zslbwg7ZWp64uI64ukYCB9O1xuICAgIH1cbiAgICByZXR1cm4geyBvazogdHJ1ZSwgdmFsdWU6IFN0cmluZyhwYXJzZWQpIH07XG4gIH1cblxuICBpZiAoZGVmLmtpbmQgPT09IFwiaW50ZWdlclwiIHx8IGRlZi5raW5kID09PSBcIm51bWJlclwiKSB7XG4gICAgY29uc3QgcGFyc2VkID0gTnVtYmVyKHRyaW1tZWQpO1xuICAgIGlmICghTnVtYmVyLmlzRmluaXRlKHBhcnNlZCkpIHJldHVybiB7IG9rOiBmYWxzZSwgZXJyb3I6IFwi7Iir7J6Q66W8IOyeheugpe2VmOyEuOyalFwiIH07XG4gICAgaWYgKGRlZi5raW5kID09PSBcImludGVnZXJcIiAmJiAhTnVtYmVyLmlzSW50ZWdlcihwYXJzZWQpKSB7XG4gICAgICByZXR1cm4geyBvazogZmFsc2UsIGVycm9yOiBcIuygleyImOulvCDsnoXroKXtlZjshLjsmpRcIiB9O1xuICAgIH1cbiAgICBpZiAoZGVmLm1pbiAhPT0gdW5kZWZpbmVkICYmIHBhcnNlZCA8IGRlZi5taW4pIHtcbiAgICAgIHJldHVybiB7IG9rOiBmYWxzZSwgZXJyb3I6IGAke2RlZi5taW59IOydtOyDgeydtOyWtOyVvCDtlanri4jri6RgIH07XG4gICAgfVxuICAgIGlmIChkZWYubWF4ICE9PSB1bmRlZmluZWQgJiYgcGFyc2VkID4gZGVmLm1heCkge1xuICAgICAgcmV0dXJuIHsgb2s6IGZhbHNlLCBlcnJvcjogYCR7ZGVmLm1heH0g7J207ZWY7Jes7JW8IO2VqeuLiOuLpGAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHsgb2s6IHRydWUsIHZhbHVlOiBTdHJpbmcocGFyc2VkKSB9O1xuICB9XG5cbiAgcmV0dXJuIHsgb2s6IHRydWUsIHZhbHVlOiB0cmltbWVkIH07XG59XG5cbi8qKiDtmZTrqbTsl5Ag6re464yA66GcIOuCtOugpOuztOuCtOuptCDslYgg65CY64qUIOqwki4g7JWe65Kk66eMIOuCqOq4tOuLpC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXNrU2VjcmV0KHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAodmFsdWUubGVuZ3RoIDw9IDEyKSByZXR1cm4gXCIqKipcIjtcbiAgcmV0dXJuIGAke3ZhbHVlLnNsaWNlKDAsIDgpfS4uLiR7dmFsdWUuc2xpY2UoLTQpfWA7XG59XG4iXSwibWFwcGluZ3MiOiI7O0FBMENBLE1BQWEsK0JBQStCO0FBQzVDLE1BQWEsb0NBQW9DO0FBRWpELE1BQWEsZUFBNkI7Q0FDeEM7RUFDRSxLQUFLO0VBQ0wsVUFBVTtFQUNWLE9BQU87RUFDUCxRQUFRO0VBQ1IsT0FBTztFQUNQLE1BQU07RUFDTixTQUFTO0VBQ1QsTUFBTTtDQUNSO0NBQ0E7RUFDRSxLQUFLO0VBQ0wsVUFBVTtFQUNWLE9BQU87RUFDUCxRQUFRO0VBQ1IsT0FBTztFQUNQLE1BQU07RUFDTixTQUFTO0VBQ1QsS0FBSztFQUNMLEtBQUs7Q0FDUDtDQUNBO0VBQ0UsS0FBSztFQUNMLFVBQVU7RUFDVixPQUFPO0VBQ1AsUUFBUTtFQUNSLE9BQU87RUFDUCxNQUFNO0VBQ04sU0FBUztFQUNULEtBQUs7RUFDTCxLQUFLO0VBQ0wsTUFBTTtDQUNSO0NBQ0E7RUFDRSxLQUFLO0VBQ0wsVUFBVTtFQUNWLE9BQU87RUFDUCxRQUFRO0VBQ1IsT0FBTztFQUNQLE1BQU07RUFDTixTQUFTO0VBQ1QsS0FBSztFQUNMLEtBQUE7RUFDQSxNQUFNO0NBQ1I7Q0FDQTtFQUNFLEtBQUs7RUFDTCxVQUFVO0VBQ1YsT0FBTztFQUNQLFFBQVE7RUFDUixPQUFPO0VBQ1AsTUFBTTtFQUNOLFNBQVM7RUFDVCxLQUFLO0VBQ0wsS0FBQTtFQUNBLE1BQU07Q0FDUjtDQUNBO0VBQ0UsS0FBSztFQUNMLFVBQVU7RUFDVixPQUFP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
|