@cartanova/qgrid-cli 1.0.3 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/dist/application/qgrid/pool.js +15 -6
- package/bundle/dist/application/qgrid/qgrid.frame.js +17 -22
- package/bundle/dist/application/qgrid/qgrid.types.js +5 -2
- package/bundle/dist/application/request-log/request-log.model.js +2 -2
- package/bundle/dist/sonamu.config.js +5 -2
- package/bundle/src/application/qgrid/pool.ts +17 -7
- package/bundle/src/application/qgrid/qgrid.frame.ts +18 -25
- package/bundle/src/application/qgrid/qgrid.types.ts +1 -1
- package/bundle/src/application/request-log/request-log.model.ts +2 -2
- package/bundle/src/sonamu.config.ts +1 -1
- package/bundle/web-dist/{web-dist/client/assets/index-DlPchHBY.js → client/assets/index-C0m8rRjO.js} +2 -2
- package/bundle/web-dist/client/assets/{routes-CagDz23B.js → routes-B1eOXnpo.js} +1 -1
- package/bundle/web-dist/client/assets/{show-aXUGa0gm.js → show-BztN6MXO.js} +1 -1
- package/bundle/web-dist/client/assets/tokens-rR2_-Pte.js +1 -0
- package/bundle/web-dist/client/index.html +1 -1
- package/bundle/web-dist/server/assets/{tokens-JH6FsnWZ.js → tokens-ARL5AOAh.js} +4 -1
- package/bundle/web-dist/server/entry-server.generated.js +1 -1
- package/dist/cli.js +34 -25
- package/package.json +11 -11
- package/bundle/dist/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorate.js +0 -9
- package/bundle/dist/dist/_virtual/_@oxc-project_runtime@0.122.0/helpers/decorateMetadata.js +0 -6
- package/bundle/dist/dist/_virtual/_rolldown/runtime.js +0 -15
- package/bundle/dist/dist/application/qgrid/oauth.js +0 -140
- package/bundle/dist/dist/application/qgrid/pool.js +0 -100
- package/bundle/dist/dist/application/qgrid/qgrid.frame.js +0 -280
- package/bundle/dist/dist/application/qgrid/qgrid.types.js +0 -79
- package/bundle/dist/dist/application/qgrid/worker.js +0 -183
- package/bundle/dist/dist/application/queries.generated.js +0 -31
- package/bundle/dist/dist/application/request-log/request-log.model.js +0 -113
- package/bundle/dist/dist/application/request-log/request-log.types.js +0 -13
- package/bundle/dist/dist/application/sonamu.generated.js +0 -99
- package/bundle/dist/dist/application/sonamu.generated.sso.js +0 -34
- package/bundle/dist/dist/application/token/token.model.js +0 -157
- package/bundle/dist/dist/application/token/token.types.js +0 -22
- package/bundle/dist/dist/i18n/en.js +0 -63
- package/bundle/dist/dist/i18n/ko.js +0 -62
- package/bundle/dist/dist/i18n/sd.generated.js +0 -272
- package/bundle/dist/dist/index.js +0 -11
- package/bundle/dist/dist/migrations/20260410171405_create__request_logs.js +0 -26
- package/bundle/dist/dist/migrations/20260410171406_create__tokens.js +0 -24
- package/bundle/dist/dist/migrations/20260411120624_alter_tokens_alter2.js +0 -16
- package/bundle/dist/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +0 -155
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_expect@4.1.2/node_modules/@vitest/expect/dist/index.js +0 -1484
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.2/node_modules/@vitest/pretty-format/dist/index.js +0 -887
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/chunk-artifact.js +0 -2746
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/index.js +0 -8
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/utils.js +0 -8
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_snapshot@4.1.2/node_modules/@vitest/snapshot/dist/index.js +0 -662
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_spy@4.1.2/node_modules/@vitest/spy/dist/index.js +0 -386
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +0 -82
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/constants.js +0 -48
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/diff.js +0 -1307
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/display.js +0 -558
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/error.js +0 -33
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/helpers.js +0 -226
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/offset.js +0 -27
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/serialize.js +0 -77
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/source-map.js +0 -374
- package/bundle/dist/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/timers.js +0 -37
- package/bundle/dist/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.js +0 -2886
- package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.js +0 -10
- package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.js +0 -109
- package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.js +0 -10
- package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.js +0 -10
- package/bundle/dist/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.js +0 -10
- package/bundle/dist/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +0 -1127
- package/bundle/dist/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +0 -21
- package/bundle/dist/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +0 -432
- package/bundle/dist/dist/node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.js +0 -506
- package/bundle/dist/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js +0 -86
- package/bundle/dist/dist/node_modules/.pnpm/vite@8.0.3_@emnapi_core@1.9.2_@emnapi_runtime@1.9.2_@types_node@25.0.7_esbuild@0.27.4_jiti@2.6.1_sass@1.98.0_tsx@4.21.0/node_modules/vite/dist/node/module-runner.js +0 -426
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +0 -6
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/benchmark.CX_oY03V.js +0 -41
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/evaluatedModules.Dg1zASAC.js +0 -19
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/index.Chj8NDwU.js +0 -202
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/index.DOa3dzoN.js +0 -16
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js +0 -59
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/test.p_J6dB8a.js +0 -2910
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js +0 -44
- package/bundle/dist/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_vite@8.0.3_@emnapi_core@1.9.2__bb31087278f97a39b31b92010beab980/node_modules/vitest/dist/index.js +0 -28
- package/bundle/dist/dist/sonamu.config.js +0 -196
- package/bundle/dist/dist/testing/fixture.js +0 -8
- package/bundle/dist/dist/testing/global.js +0 -9
- package/bundle/dist/dist/testing/setup-mocks.js +0 -17
- package/bundle/dist/dist/utils/subset-loaders.js +0 -12
- package/bundle/src/src/application/qgrid/oauth.ts +0 -181
- package/bundle/src/src/application/qgrid/pool.ts +0 -132
- package/bundle/src/src/application/qgrid/qgrid.frame.ts +0 -275
- package/bundle/src/src/application/qgrid/qgrid.types.ts +0 -117
- package/bundle/src/src/application/qgrid/worker.ts +0 -234
- package/bundle/src/src/application/queries.generated.ts +0 -59
- package/bundle/src/src/application/request-log/request-log.entity.json +0 -75
- package/bundle/src/src/application/request-log/request-log.model.ts +0 -155
- package/bundle/src/src/application/request-log/request-log.types.ts +0 -15
- package/bundle/src/src/application/sonamu.generated.http +0 -187
- package/bundle/src/src/application/sonamu.generated.sso.ts +0 -66
- package/bundle/src/src/application/sonamu.generated.ts +0 -135
- package/bundle/src/src/application/token/token.entity.json +0 -37
- package/bundle/src/src/application/token/token.model.ts +0 -160
- package/bundle/src/src/application/token/token.types.ts +0 -26
- package/bundle/src/src/i18n/en.ts +0 -59
- package/bundle/src/src/i18n/ko.ts +0 -59
- package/bundle/src/src/i18n/sd.generated.ts +0 -384
- package/bundle/src/src/index.ts +0 -6
- package/bundle/src/src/migrations/20260410171405_create__request_logs.ts +0 -23
- package/bundle/src/src/migrations/20260410171406_create__tokens.ts +0 -21
- package/bundle/src/src/migrations/20260411120624_alter_tokens_alter2.ts +0 -15
- package/bundle/src/src/sonamu.config.ts +0 -248
- package/bundle/src/src/testing/fixture.ts +0 -6
- package/bundle/src/src/testing/global.ts +0 -6
- package/bundle/src/src/testing/setup-mocks.ts +0 -44
- package/bundle/src/src/typings/fastify.d.ts +0 -8
- package/bundle/src/src/typings/sonamu.d.ts +0 -17
- package/bundle/src/src/utils/subset-loaders.ts +0 -11
- package/bundle/web-dist/client/assets/index-DlPchHBY.js +0 -116
- package/bundle/web-dist/client/assets/tokens-DRkXtZ3Q.js +0 -1
- package/bundle/web-dist/web-dist/client/assets/index-vZsvyuFn.css +0 -1
- package/bundle/web-dist/web-dist/client/assets/rolldown-runtime-Dw2cE7zH.js +0 -1
- package/bundle/web-dist/web-dist/client/assets/routes-CagDz23B.js +0 -1
- package/bundle/web-dist/web-dist/client/assets/sd.generated-BrQoQXvv.js +0 -47
- package/bundle/web-dist/web-dist/client/assets/services.generated-BspO2L0j.js +0 -1
- package/bundle/web-dist/web-dist/client/assets/show-aXUGa0gm.js +0 -29
- package/bundle/web-dist/web-dist/client/assets/tokens-DRkXtZ3Q.js +0 -1
- package/bundle/web-dist/web-dist/client/assets/vendor-react-DH4kUfK2.js +0 -9
- package/bundle/web-dist/web-dist/client/assets/vendor-tanstack-CUxlo6YN.js +0 -1
- package/bundle/web-dist/web-dist/client/index.html +0 -18
- package/bundle/web-dist/web-dist/server/assets/react-dom-CGIzOSuj.js +0 -335
- package/bundle/web-dist/web-dist/server/assets/routes-ClzReRep.js +0 -490
- package/bundle/web-dist/web-dist/server/assets/sd.generated-BnonqqKr.js +0 -21694
- package/bundle/web-dist/web-dist/server/assets/services.generated-D5ABD5fr.js +0 -836
- package/bundle/web-dist/web-dist/server/assets/show-C9pcdSxc.js +0 -23364
- package/bundle/web-dist/web-dist/server/assets/tokens-JH6FsnWZ.js +0 -860
- package/bundle/web-dist/web-dist/server/entry-server.generated.js +0 -44646
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import "../../_virtual/_rolldown/runtime.js";
|
|
2
|
-
import { createHash, randomBytes } from "node:crypto";
|
|
3
|
-
//#region src/application/qgrid/oauth.ts
|
|
4
|
-
/**
|
|
5
|
-
* OAuth 유틸 — Claude Code 소스의 OAuth 플로우 그대로 재현
|
|
6
|
-
*/
|
|
7
|
-
const CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
|
|
8
|
-
const AUTHORIZE_URL = "https://claude.com/cai/oauth/authorize";
|
|
9
|
-
const TOKEN_URL = "https://platform.claude.com/v1/oauth/token";
|
|
10
|
-
const ALL_SCOPES = [
|
|
11
|
-
"org:create_api_key",
|
|
12
|
-
"user:profile",
|
|
13
|
-
"user:inference",
|
|
14
|
-
"user:sessions:claude_code",
|
|
15
|
-
"user:mcp_servers",
|
|
16
|
-
"user:file_upload"
|
|
17
|
-
];
|
|
18
|
-
const REFRESH_SCOPES = [
|
|
19
|
-
"user:profile",
|
|
20
|
-
"user:inference",
|
|
21
|
-
"user:sessions:claude_code",
|
|
22
|
-
"user:mcp_servers",
|
|
23
|
-
"user:file_upload"
|
|
24
|
-
];
|
|
25
|
-
function base64URLEncode(buffer) {
|
|
26
|
-
return buffer.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
27
|
-
}
|
|
28
|
-
function generatePKCE() {
|
|
29
|
-
const codeVerifier = base64URLEncode(randomBytes(32));
|
|
30
|
-
return {
|
|
31
|
-
codeVerifier,
|
|
32
|
-
codeChallenge: base64URLEncode(createHash("sha256").update(codeVerifier).digest()),
|
|
33
|
-
state: base64URLEncode(randomBytes(32))
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
function buildAuthUrl(codeChallenge, state, redirectUri) {
|
|
37
|
-
const url = new URL(AUTHORIZE_URL);
|
|
38
|
-
url.searchParams.append("code", "true");
|
|
39
|
-
url.searchParams.append("client_id", CLIENT_ID);
|
|
40
|
-
url.searchParams.append("response_type", "code");
|
|
41
|
-
url.searchParams.append("redirect_uri", redirectUri);
|
|
42
|
-
url.searchParams.append("scope", ALL_SCOPES.join(" "));
|
|
43
|
-
url.searchParams.append("code_challenge", codeChallenge);
|
|
44
|
-
url.searchParams.append("code_challenge_method", "S256");
|
|
45
|
-
url.searchParams.append("state", state);
|
|
46
|
-
return url.toString();
|
|
47
|
-
}
|
|
48
|
-
async function exchangeCodeForTokens(code, codeVerifier, state, redirectUri) {
|
|
49
|
-
const res = await fetch(TOKEN_URL, {
|
|
50
|
-
method: "POST",
|
|
51
|
-
headers: { "Content-Type": "application/json" },
|
|
52
|
-
body: JSON.stringify({
|
|
53
|
-
grant_type: "authorization_code",
|
|
54
|
-
code,
|
|
55
|
-
redirect_uri: redirectUri,
|
|
56
|
-
client_id: CLIENT_ID,
|
|
57
|
-
code_verifier: codeVerifier,
|
|
58
|
-
state
|
|
59
|
-
})
|
|
60
|
-
});
|
|
61
|
-
if (!res.ok) {
|
|
62
|
-
const text = await res.text();
|
|
63
|
-
throw new Error(`Token exchange failed (${res.status}): ${text}`);
|
|
64
|
-
}
|
|
65
|
-
const data = await res.json();
|
|
66
|
-
return {
|
|
67
|
-
accessToken: data.access_token,
|
|
68
|
-
refreshToken: data.refresh_token,
|
|
69
|
-
expiresAt: Date.now() + data.expires_in * 1e3,
|
|
70
|
-
scope: data.scope,
|
|
71
|
-
accountUuid: data.account?.uuid,
|
|
72
|
-
emailAddress: data.account?.email_address
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
async function refreshAccessToken(refreshToken) {
|
|
76
|
-
const res = await fetch(TOKEN_URL, {
|
|
77
|
-
method: "POST",
|
|
78
|
-
headers: { "Content-Type": "application/json" },
|
|
79
|
-
body: JSON.stringify({
|
|
80
|
-
grant_type: "refresh_token",
|
|
81
|
-
refresh_token: refreshToken,
|
|
82
|
-
client_id: CLIENT_ID,
|
|
83
|
-
scope: REFRESH_SCOPES.join(" ")
|
|
84
|
-
})
|
|
85
|
-
});
|
|
86
|
-
if (!res.ok) {
|
|
87
|
-
const text = await res.text();
|
|
88
|
-
throw new Error(`Token refresh failed (${res.status}): ${text}`);
|
|
89
|
-
}
|
|
90
|
-
const data = await res.json();
|
|
91
|
-
return {
|
|
92
|
-
accessToken: data.access_token,
|
|
93
|
-
refreshToken: data.refresh_token ?? refreshToken,
|
|
94
|
-
expiresAt: Date.now() + data.expires_in * 1e3,
|
|
95
|
-
scope: data.scope
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
const usageCache = {};
|
|
99
|
-
const USAGE_API_CACHE_TTL = 6e4;
|
|
100
|
-
async function fetchUsage(accessToken) {
|
|
101
|
-
const cacheKey = accessToken.slice(-10);
|
|
102
|
-
const cached = usageCache[cacheKey];
|
|
103
|
-
if (cached && Date.now() - cached.cachedAt < USAGE_API_CACHE_TTL) {
|
|
104
|
-
console.log(`[usage] cache hit: ${cacheKey}`);
|
|
105
|
-
return cached.data;
|
|
106
|
-
}
|
|
107
|
-
const res = await fetch("https://api.anthropic.com/api/oauth/usage", {
|
|
108
|
-
headers: {
|
|
109
|
-
Authorization: `Bearer ${accessToken}`,
|
|
110
|
-
"Content-Type": "application/json",
|
|
111
|
-
"anthropic-beta": "oauth-2025-04-20"
|
|
112
|
-
},
|
|
113
|
-
signal: AbortSignal.timeout(5e3)
|
|
114
|
-
});
|
|
115
|
-
if (!res.ok) {
|
|
116
|
-
const text = await res.text();
|
|
117
|
-
let errorMessage = `Error ${res.status}`;
|
|
118
|
-
try {
|
|
119
|
-
errorMessage = JSON.parse(text).error?.message ?? errorMessage;
|
|
120
|
-
} catch {}
|
|
121
|
-
console.warn(`[usage] ${res.status}: ${errorMessage}`);
|
|
122
|
-
if (cached?.data && !cached.data.error) return cached.data;
|
|
123
|
-
const errorResult = { error: errorMessage };
|
|
124
|
-
usageCache[cacheKey] = {
|
|
125
|
-
data: errorResult,
|
|
126
|
-
cachedAt: Date.now()
|
|
127
|
-
};
|
|
128
|
-
return errorResult;
|
|
129
|
-
}
|
|
130
|
-
const data = await res.json();
|
|
131
|
-
usageCache[cacheKey] = {
|
|
132
|
-
data,
|
|
133
|
-
cachedAt: Date.now()
|
|
134
|
-
};
|
|
135
|
-
return data;
|
|
136
|
-
}
|
|
137
|
-
//#endregion
|
|
138
|
-
export { buildAuthUrl, exchangeCodeForTokens, fetchUsage, generatePKCE, refreshAccessToken };
|
|
139
|
-
|
|
140
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2F1dGguanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3FncmlkL29hdXRoLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogT0F1dGgg7Jyg7Yu4IOKAlCBDbGF1ZGUgQ29kZSDshozsiqTsnZggT0F1dGgg7ZSM66Gc7JqwIOq3uOuMgOuhnCDsnqztmIRcbiAqL1xuaW1wb3J0IHsgY3JlYXRlSGFzaCwgcmFuZG9tQnl0ZXMgfSBmcm9tIFwibm9kZTpjcnlwdG9cIjtcblxuaW1wb3J0IHR5cGUgeyBVc2FnZVJlc3BvbnNlIH0gZnJvbSBcIi4vcWdyaWQudHlwZXNcIjtcblxuY29uc3QgQ0xJRU5UX0lEID0gXCI5ZDFjMjUwYS1lNjFiLTQ0ZDktODhlZC01OTQ0ZDE5NjJmNWVcIjtcbmNvbnN0IEFVVEhPUklaRV9VUkwgPSBcImh0dHBzOi8vY2xhdWRlLmNvbS9jYWkvb2F1dGgvYXV0aG9yaXplXCI7XG5jb25zdCBUT0tFTl9VUkwgPSBcImh0dHBzOi8vcGxhdGZvcm0uY2xhdWRlLmNvbS92MS9vYXV0aC90b2tlblwiO1xuXG4vLyBsb2dpbiDsi5wg7IKs7JqpIChhdXRob3JpemUgVVJMKVxuY29uc3QgQUxMX1NDT1BFUyA9IFtcbiAgXCJvcmc6Y3JlYXRlX2FwaV9rZXlcIixcbiAgXCJ1c2VyOnByb2ZpbGVcIixcbiAgXCJ1c2VyOmluZmVyZW5jZVwiLFxuICBcInVzZXI6c2Vzc2lvbnM6Y2xhdWRlX2NvZGVcIixcbiAgXCJ1c2VyOm1jcF9zZXJ2ZXJzXCIsXG4gIFwidXNlcjpmaWxlX3VwbG9hZFwiLFxuXTtcblxuLy8gcmVmcmVzaCDsi5wg7IKs7JqpIChvcmc6Y3JlYXRlX2FwaV9rZXkg7KCc7Jm4KVxuY29uc3QgUkVGUkVTSF9TQ09QRVMgPSBbXG4gIFwidXNlcjpwcm9maWxlXCIsXG4gIFwidXNlcjppbmZlcmVuY2VcIixcbiAgXCJ1c2VyOnNlc3Npb25zOmNsYXVkZV9jb2RlXCIsXG4gIFwidXNlcjptY3Bfc2VydmVyc1wiLFxuICBcInVzZXI6ZmlsZV91cGxvYWRcIixcbl07XG5cbmZ1bmN0aW9uIGJhc2U2NFVSTEVuY29kZShidWZmZXI6IEJ1ZmZlcik6IHN0cmluZyB7XG4gIHJldHVybiBidWZmZXIudG9TdHJpbmcoXCJiYXNlNjRcIikucmVwbGFjZSgvXFwrL2csIFwiLVwiKS5yZXBsYWNlKC9cXC8vZywgXCJfXCIpLnJlcGxhY2UoLz0vZywgXCJcIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVBLQ0UoKTogeyBjb2RlVmVyaWZpZXI6IHN0cmluZzsgY29kZUNoYWxsZW5nZTogc3RyaW5nOyBzdGF0ZTogc3RyaW5nIH0ge1xuICBjb25zdCBjb2RlVmVyaWZpZXIgPSBiYXNlNjRVUkxFbmNvZGUocmFuZG9tQnl0ZXMoMzIpKTtcbiAgY29uc3QgY29kZUNoYWxsZW5nZSA9IGJhc2U2NFVSTEVuY29kZShjcmVhdGVIYXNoKFwic2hhMjU2XCIpLnVwZGF0ZShjb2RlVmVyaWZpZXIpLmRpZ2VzdCgpKTtcbiAgY29uc3Qgc3RhdGUgPSBiYXNlNjRVUkxFbmNvZGUocmFuZG9tQnl0ZXMoMzIpKTtcbiAgcmV0dXJuIHsgY29kZVZlcmlmaWVyLCBjb2RlQ2hhbGxlbmdlLCBzdGF0ZSB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRBdXRoVXJsKGNvZGVDaGFsbGVuZ2U6IHN0cmluZywgc3RhdGU6IHN0cmluZywgcmVkaXJlY3RVcmk6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHVybCA9IG5ldyBVUkwoQVVUSE9SSVpFX1VSTCk7XG4gIHVybC5zZWFyY2hQYXJhbXMuYXBwZW5kKFwiY29kZVwiLCBcInRydWVcIik7XG4gIHVybC5zZWFyY2hQYXJhbXMuYXBwZW5kKFwiY2xpZW50X2lkXCIsIENMSUVOVF9JRCk7XG4gIHVybC5zZWFyY2hQYXJhbXMuYXBwZW5kKFwicmVzcG9uc2VfdHlwZVwiLCBcImNvZGVcIik7XG4gIHVybC5zZWFyY2hQYXJhbXMuYXBwZW5kKFwicmVkaXJlY3RfdXJpXCIsIHJlZGlyZWN0VXJpKTtcbiAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJzY29wZVwiLCBBTExfU0NPUEVTLmpvaW4oXCIgXCIpKTtcbiAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJjb2RlX2NoYWxsZW5nZVwiLCBjb2RlQ2hhbGxlbmdlKTtcbiAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJjb2RlX2NoYWxsZW5nZV9tZXRob2RcIiwgXCJTMjU2XCIpO1xuICB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcInN0YXRlXCIsIHN0YXRlKTtcbiAgcmV0dXJuIHVybC50b1N0cmluZygpO1xufVxuXG5leHBvcnQgdHlwZSBPQXV0aFRva2VucyA9IHtcbiAgYWNjZXNzVG9rZW46IHN0cmluZztcbiAgcmVmcmVzaFRva2VuOiBzdHJpbmc7XG4gIGV4cGlyZXNBdDogbnVtYmVyO1xuICBzY29wZTogc3RyaW5nO1xuICBhY2NvdW50VXVpZD86IHN0cmluZztcbiAgZW1haWxBZGRyZXNzPzogc3RyaW5nO1xufTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGV4Y2hhbmdlQ29kZUZvclRva2VucyhcbiAgY29kZTogc3RyaW5nLFxuICBjb2RlVmVyaWZpZXI6IHN0cmluZyxcbiAgc3RhdGU6IHN0cmluZyxcbiAgcmVkaXJlY3RVcmk6IHN0cmluZyxcbik6IFByb21pc2U8T0F1dGhUb2tlbnM+IHtcbiAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2goVE9LRU5fVVJMLCB7XG4gICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICBoZWFkZXJzOiB7IFwiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiIH0sXG4gICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgZ3JhbnRfdHlwZTogXCJhdXRob3JpemF0aW9uX2NvZGVcIixcbiAgICAgIGNvZGUsXG4gICAgICByZWRpcmVjdF91cmk6IHJlZGlyZWN0VXJpLFxuICAgICAgY2xpZW50X2lkOiBDTElFTlRfSUQsXG4gICAgICBjb2RlX3ZlcmlmaWVyOiBjb2RlVmVyaWZpZXIsXG4gICAgICBzdGF0ZSxcbiAgICB9KSxcbiAgfSk7XG4gIGlmICghcmVzLm9rKSB7XG4gICAgY29uc3QgdGV4dCA9IGF3YWl0IHJlcy50ZXh0KCk7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBUb2tlbiBleGNoYW5nZSBmYWlsZWQgKCR7cmVzLnN0YXR1c30pOiAke3RleHR9YCk7XG4gIH1cblxuICBjb25zdCBkYXRhID0gKGF3YWl0IHJlcy5qc29uKCkpIGFzIHtcbiAgICBhY2Nlc3NfdG9rZW46IHN0cmluZztcbiAgICByZWZyZXNoX3Rva2VuOiBzdHJpbmc7XG4gICAgZXhwaXJlc19pbjogbnVtYmVyO1xuICAgIHNjb3BlOiBzdHJpbmc7XG4gICAgYWNjb3VudD86IHsgdXVpZDogc3RyaW5nOyBlbWFpbF9hZGRyZXNzOiBzdHJpbmcgfTtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIGFjY2Vzc1Rva2VuOiBkYXRhLmFjY2Vzc190b2tlbixcbiAgICByZWZyZXNoVG9rZW46IGRhdGEucmVmcmVzaF90b2tlbixcbiAgICBleHBpcmVzQXQ6IERhdGUubm93KCkgKyBkYXRhLmV4cGlyZXNfaW4gKiAxMDAwLFxuICAgIHNjb3BlOiBkYXRhLnNjb3BlLFxuICAgIGFjY291bnRVdWlkOiBkYXRhLmFjY291bnQ/LnV1aWQsXG4gICAgZW1haWxBZGRyZXNzOiBkYXRhLmFjY291bnQ/LmVtYWlsX2FkZHJlc3MsXG4gIH07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWZyZXNoQWNjZXNzVG9rZW4ocmVmcmVzaFRva2VuOiBzdHJpbmcpOiBQcm9taXNlPE9BdXRoVG9rZW5zPiB7XG4gIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKFRPS0VOX1VSTCwge1xuICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgaGVhZGVyczogeyBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIiB9LFxuICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIGdyYW50X3R5cGU6IFwicmVmcmVzaF90b2tlblwiLFxuICAgICAgcmVmcmVzaF90b2tlbjogcmVmcmVzaFRva2VuLFxuICAgICAgY2xpZW50X2lkOiBDTElFTlRfSUQsXG4gICAgICBzY29wZTogUkVGUkVTSF9TQ09QRVMuam9pbihcIiBcIiksXG4gICAgfSksXG4gIH0pO1xuICBpZiAoIXJlcy5vaykge1xuICAgIGNvbnN0IHRleHQgPSBhd2FpdCByZXMudGV4dCgpO1xuICAgIHRocm93IG5ldyBFcnJvcihgVG9rZW4gcmVmcmVzaCBmYWlsZWQgKCR7cmVzLnN0YXR1c30pOiAke3RleHR9YCk7XG4gIH1cbiAgY29uc3QgZGF0YSA9IChhd2FpdCByZXMuanNvbigpKSBhcyB7XG4gICAgYWNjZXNzX3Rva2VuOiBzdHJpbmc7XG4gICAgcmVmcmVzaF90b2tlbjogc3RyaW5nO1xuICAgIGV4cGlyZXNfaW46IG51bWJlcjtcbiAgICBzY29wZTogc3RyaW5nO1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgYWNjZXNzVG9rZW46IGRhdGEuYWNjZXNzX3Rva2VuLFxuICAgIHJlZnJlc2hUb2tlbjogZGF0YS5yZWZyZXNoX3Rva2VuID8/IHJlZnJlc2hUb2tlbixcbiAgICBleHBpcmVzQXQ6IERhdGUubm93KCkgKyBkYXRhLmV4cGlyZXNfaW4gKiAxMDAwLFxuICAgIHNjb3BlOiBkYXRhLnNjb3BlLFxuICB9O1xufVxuXG5jb25zdCB1c2FnZUNhY2hlOiBSZWNvcmQ8c3RyaW5nLCB7IGRhdGE6IFVzYWdlUmVzcG9uc2U7IGNhY2hlZEF0OiBudW1iZXIgfT4gPSB7fTtcbmNvbnN0IFVTQUdFX0FQSV9DQUNIRV9UVEwgPSA2MF8wMDA7IC8vIDHrtoRcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZldGNoVXNhZ2UoYWNjZXNzVG9rZW46IHN0cmluZyk6IFByb21pc2U8VXNhZ2VSZXNwb25zZT4ge1xuICBjb25zdCBjYWNoZUtleSA9IGFjY2Vzc1Rva2VuLnNsaWNlKC0xMCk7XG4gIGNvbnN0IGNhY2hlZCA9IHVzYWdlQ2FjaGVbY2FjaGVLZXldO1xuICBpZiAoY2FjaGVkICYmIERhdGUubm93KCkgLSBjYWNoZWQuY2FjaGVkQXQgPCBVU0FHRV9BUElfQ0FDSEVfVFRMKSB7XG4gICAgY29uc29sZS5sb2coYFt1c2FnZV0gY2FjaGUgaGl0OiAke2NhY2hlS2V5fWApO1xuICAgIHJldHVybiBjYWNoZWQuZGF0YTtcbiAgfVxuXG4gIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKFwiaHR0cHM6Ly9hcGkuYW50aHJvcGljLmNvbS9hcGkvb2F1dGgvdXNhZ2VcIiwge1xuICAgIGhlYWRlcnM6IHtcbiAgICAgIEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHthY2Nlc3NUb2tlbn1gLFxuICAgICAgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgICBcImFudGhyb3BpYy1iZXRhXCI6IFwib2F1dGgtMjAyNS0wNC0yMFwiLFxuICAgIH0sXG4gICAgc2lnbmFsOiBBYm9ydFNpZ25hbC50aW1lb3V0KDUwMDApLFxuICB9KTtcbiAgaWYgKCFyZXMub2spIHtcbiAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVzLnRleHQoKTtcblxuICAgIC8vIO2MjOyLsSDsi5zrj4TtlbTshJwg7JeQ65+sIOuplOyLnOyngCDstpTstpxcbiAgICBsZXQgZXJyb3JNZXNzYWdlID0gYEVycm9yICR7cmVzLnN0YXR1c31gO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKHRleHQpO1xuICAgICAgZXJyb3JNZXNzYWdlID0gcGFyc2VkLmVycm9yPy5tZXNzYWdlID8/IGVycm9yTWVzc2FnZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIO2MjOyLsSDslYgg65CY66m0IOq4sOuzuCDrqZTsi5zsp4BcbiAgICB9XG5cbiAgICBjb25zb2xlLndhcm4oYFt1c2FnZV0gJHtyZXMuc3RhdHVzfTogJHtlcnJvck1lc3NhZ2V9YCk7XG5cbiAgICAvLyDsnbTsoIQg7ISx6rO1IOy6kOyLnCDsnojsnLzrqbQg7Jyg7KeAXG4gICAgaWYgKGNhY2hlZD8uZGF0YSAmJiAhY2FjaGVkLmRhdGEuZXJyb3IpIHJldHVybiBjYWNoZWQuZGF0YTtcblxuICAgIC8vIOyLpO2MqOuPhCDsupDsi5wgKOuwmOuztSDtmLjstpwg67Cp7KeAKVxuICAgIGNvbnN0IGVycm9yUmVzdWx0ID0geyBlcnJvcjogZXJyb3JNZXNzYWdlIH07XG4gICAgdXNhZ2VDYWNoZVtjYWNoZUtleV0gPSB7IGRhdGE6IGVycm9yUmVzdWx0LCBjYWNoZWRBdDogRGF0ZS5ub3coKSB9O1xuICAgIHJldHVybiBlcnJvclJlc3VsdDtcbiAgfVxuXG4gIGNvbnN0IGRhdGEgPSAoYXdhaXQgcmVzLmpzb24oKSkgYXMgVXNhZ2VSZXNwb25zZTtcbiAgLy8gY2FjaGUgaW52YWxpZGF0ZVxuICB1c2FnZUNhY2hlW2NhY2hlS2V5XSA9IHsgZGF0YSwgY2FjaGVkQXQ6IERhdGUubm93KCkgfTtcbiAgcmV0dXJuIGRhdGE7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQU9BLE1BQU0sWUFBWTtBQUNsQixNQUFNLGdCQUFnQjtBQUN0QixNQUFNLFlBQVk7QUFHbEIsTUFBTSxhQUFhO0NBQ2pCO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNEO0FBR0QsTUFBTSxpQkFBaUI7Q0FDckI7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNEO0FBRUQsU0FBUyxnQkFBZ0IsUUFBd0I7QUFDL0MsUUFBTyxPQUFPLFNBQVMsU0FBUyxDQUFDLFFBQVEsT0FBTyxJQUFJLENBQUMsUUFBUSxPQUFPLElBQUksQ0FBQyxRQUFRLE1BQU0sR0FBRzs7QUFHNUYsU0FBZ0IsZUFBK0U7Q0FDN0YsTUFBTSxlQUFlLGdCQUFnQixZQUFZLEdBQUcsQ0FBQztBQUdyRCxRQUFPO0VBQUU7RUFBYyxlQUZELGdCQUFnQixXQUFXLFNBQVMsQ0FBQyxPQUFPLGFBQWEsQ0FBQyxRQUFRLENBQUM7RUFFbkQsT0FEeEIsZ0JBQWdCLFlBQVksR0FBRyxDQUFDO0VBQ0Q7O0FBRy9DLFNBQWdCLGFBQWEsZUFB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
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import "../../_virtual/_rolldown/runtime.js";
|
|
2
|
-
import { QuotaError } from "./qgrid.types.js";
|
|
3
|
-
import { Worker } from "./worker.js";
|
|
4
|
-
//#region src/application/qgrid/pool.ts
|
|
5
|
-
var ClaudePool = class {
|
|
6
|
-
workers = /* @__PURE__ */ new Map();
|
|
7
|
-
quotaExhausted = /* @__PURE__ */ new Set();
|
|
8
|
-
requestCounts = /* @__PURE__ */ new Map();
|
|
9
|
-
lastUsedToken = "";
|
|
10
|
-
size;
|
|
11
|
-
model;
|
|
12
|
-
timeout;
|
|
13
|
-
cwd;
|
|
14
|
-
maxCalls;
|
|
15
|
-
constructor(config) {
|
|
16
|
-
this.size = config.size ?? 3;
|
|
17
|
-
this.model = config.model ?? "sonnet";
|
|
18
|
-
this.timeout = config.timeout ?? 3e5;
|
|
19
|
-
this.cwd = config.cwd ?? "/tmp/qgrid";
|
|
20
|
-
this.maxCalls = config.maxCalls ?? 500;
|
|
21
|
-
config.tokens.forEach((token) => {
|
|
22
|
-
this.createWorkers(token);
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
getStats(tokenNames) {
|
|
26
|
-
return [...this.workers.keys()].map((token) => ({
|
|
27
|
-
token,
|
|
28
|
-
name: tokenNames?.get(token) ?? "Unknown Key",
|
|
29
|
-
requests: this.requestCounts.get(token) ?? 0,
|
|
30
|
-
active: !this.quotaExhausted.has(token)
|
|
31
|
-
}));
|
|
32
|
-
}
|
|
33
|
-
selectWorker() {
|
|
34
|
-
const candidates = [...this.workers.entries()].filter(([token]) => !this.quotaExhausted.has(token)).flatMap(([, workers]) => workers);
|
|
35
|
-
if (candidates.length === 0) return null;
|
|
36
|
-
return candidates.reduce((best, w) => w.getQueueDepth() < best.getQueueDepth() ? w : best);
|
|
37
|
-
}
|
|
38
|
-
async query(input, timeoutMs) {
|
|
39
|
-
const triedTokens = /* @__PURE__ */ new Set();
|
|
40
|
-
while (true) {
|
|
41
|
-
const worker = this.selectWorker();
|
|
42
|
-
if (!worker) throw new QuotaError("All tokens exhausted");
|
|
43
|
-
if (triedTokens.has(worker.tokenId)) throw new QuotaError("All tokens exhausted");
|
|
44
|
-
try {
|
|
45
|
-
const result = await worker.query(input, timeoutMs);
|
|
46
|
-
this.lastUsedToken = worker.tokenId;
|
|
47
|
-
this.requestCounts.set(worker.tokenId, (this.requestCounts.get(worker.tokenId) ?? 0) + 1);
|
|
48
|
-
return result;
|
|
49
|
-
} catch (err) {
|
|
50
|
-
if (err instanceof QuotaError) {
|
|
51
|
-
this.quotaExhausted.add(worker.tokenId);
|
|
52
|
-
triedTokens.add(worker.tokenId);
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
throw err;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
kill() {
|
|
60
|
-
[...this.workers.values()].flat().forEach((w) => {
|
|
61
|
-
w.kill();
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
createWorkers(token) {
|
|
65
|
-
if (this.workers.has(token)) return;
|
|
66
|
-
const workerConfig = {
|
|
67
|
-
token,
|
|
68
|
-
model: this.model,
|
|
69
|
-
timeout: this.timeout,
|
|
70
|
-
cwd: this.cwd,
|
|
71
|
-
maxCalls: this.maxCalls
|
|
72
|
-
};
|
|
73
|
-
const workers = Array.from({ length: this.size }, () => new Worker(workerConfig));
|
|
74
|
-
this.workers.set(token, workers);
|
|
75
|
-
this.requestCounts.set(token, 0);
|
|
76
|
-
}
|
|
77
|
-
destroyWorkers(token) {
|
|
78
|
-
const workers = this.workers.get(token);
|
|
79
|
-
if (!workers) return;
|
|
80
|
-
workers.forEach((w) => {
|
|
81
|
-
w.kill();
|
|
82
|
-
});
|
|
83
|
-
this.workers.delete(token);
|
|
84
|
-
this.quotaExhausted.delete(token);
|
|
85
|
-
this.requestCounts.delete(token);
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
let pool = null;
|
|
89
|
-
function initPool(tokens) {
|
|
90
|
-
pool = new ClaudePool({ tokens });
|
|
91
|
-
return pool;
|
|
92
|
-
}
|
|
93
|
-
function getPool() {
|
|
94
|
-
if (!pool) throw new Error("Pool not initialized. Call initPool() first.");
|
|
95
|
-
return pool;
|
|
96
|
-
}
|
|
97
|
-
//#endregion
|
|
98
|
-
export { ClaudePool, getPool, initPool };
|
|
99
|
-
|
|
100
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9vbC5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBwbGljYXRpb24vcWdyaWQvcG9vbC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENsYXVkZVBvb2wg4oCUIOupgO2LsCDthqDtgbAg7ZSE66Gc7IS47IqkIO2SgC5cbiAqXG4gKiAyLWxheWVyIOyVhO2CpO2FjeyymDogQ2xhdWRlUG9vbCDihpIgV29ya2VyIChmbGF0KVxuICogLSBNYXA8dG9rZW4sIFdvcmtlcltdPuuhnCDthqDtgbDrs4Qg7JuM7LukIOq0gOumrCAo7JuQ67O4IO2GoO2BsOydtCDtgqQpXG4gKiAtIGxlYXN0LXF1ZXVlLWRlcHRoIOudvOyasO2MhVxuICogLSDtiKzrqoXtlZwg7L+87YSwIGZhaWxvdmVyIChRdW90YUVycm9yIOyLnCDri6Trpbgg7Yag7YGw7Jy866GcIOyekOuPmSDsnqzsi5zrj4QpXG4gKiAtIOybjOy7pCDqtIDrpqzrp4wg64u064u5IChEQiDsnZjsobQg7JeG7J2MKVxuICovXG5pbXBvcnQgdHlwZSB7IENsaVJlc3VsdCwgUG9vbENvbmZpZywgUXVlcnlJbnB1dCwgVG9rZW5TdGF0cyB9IGZyb20gXCIuL3FncmlkLnR5cGVzXCI7XG5pbXBvcnQgeyBRdW90YUVycm9yIH0gZnJvbSBcIi4vcWdyaWQudHlwZXNcIjtcbmltcG9ydCB7IFdvcmtlciwgdHlwZSBXb3JrZXJDb25maWcgfSBmcm9tIFwiLi93b3JrZXJcIjtcblxuZXhwb3J0IGNsYXNzIENsYXVkZVBvb2wge1xuICB3b3JrZXJzID0gbmV3IE1hcDxzdHJpbmcsIFdvcmtlcltdPigpO1xuICBxdW90YUV4aGF1c3RlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICByZXF1ZXN0Q291bnRzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgbGFzdFVzZWRUb2tlbiA9IFwiXCI7XG4gIHNpemU6IG51bWJlcjtcbiAgbW9kZWw6IHN0cmluZztcbiAgdGltZW91dDogbnVtYmVyO1xuICBjd2Q6IHN0cmluZztcbiAgbWF4Q2FsbHM6IG51bWJlcjtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IFBvb2xDb25maWcpIHtcbiAgICB0aGlzLnNpemUgPSBjb25maWcuc2l6ZSA/PyAzO1xuICAgIHRoaXMubW9kZWwgPSBjb25maWcubW9kZWwgPz8gXCJzb25uZXRcIjtcbiAgICB0aGlzLnRpbWVvdXQgPSBjb25maWcudGltZW91dCA/PyAzMDBfMDAwO1xuICAgIHRoaXMuY3dkID0gY29uZmlnLmN3ZCA/PyBcIi90bXAvcWdyaWRcIjtcbiAgICB0aGlzLm1heENhbGxzID0gY29uZmlnLm1heENhbGxzID8/IDUwMDtcblxuICAgIGNvbmZpZy50b2tlbnMuZm9yRWFjaCgodG9rZW4pID0+IHtcbiAgICAgIHRoaXMuY3JlYXRlV29ya2Vycyh0b2tlbik7XG4gICAgfSk7XG4gIH1cblxuICBnZXRTdGF0cyh0b2tlbk5hbWVzPzogTWFwPHN0cmluZywgc3RyaW5nPik6IFRva2VuU3RhdHNbXSB7XG4gICAgcmV0dXJuIFsuLi50aGlzLndvcmtlcnMua2V5cygpXS5tYXAoKHRva2VuKSA9PiAoe1xuICAgICAgdG9rZW4sXG4gICAgICBuYW1lOiB0b2tlbk5hbWVzPy5nZXQodG9rZW4pID8/IFwiVW5rbm93biBLZXlcIixcbiAgICAgIHJlcXVlc3RzOiB0aGlzLnJlcXVlc3RDb3VudHMuZ2V0KHRva2VuKSA/PyAwLFxuICAgICAgYWN0aXZlOiAhdGhpcy5xdW90YUV4aGF1c3RlZC5oYXModG9rZW4pLFxuICAgIH0pKTtcbiAgfVxuXG4gIHNlbGVjdFdvcmtlcigpOiBXb3JrZXIgfCBudWxsIHtcbiAgICBjb25zdCBjYW5kaWRhdGVzID0gWy4uLnRoaXMud29ya2Vycy5lbnRyaWVzKCldXG4gICAgICAuZmlsdGVyKChbdG9rZW5dKSA9PiAhdGhpcy5xdW90YUV4aGF1c3RlZC5oYXModG9rZW4pKVxuICAgICAgLmZsYXRNYXAoKFssIHdvcmtlcnNdKSA9PiB3b3JrZXJzKTtcblxuICAgIGlmIChjYW5kaWRhdGVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XG5cbiAgICByZXR1cm4gY2FuZGlkYXRlcy5yZWR1Y2UoKGJlc3QsIHcpID0+ICh3LmdldFF1ZXVlRGVwdGgoKSA8IGJlc3QuZ2V0UXVldWVEZXB0aCgpID8gdyA6IGJlc3QpKTtcbiAgfVxuXG4gIGFzeW5jIHF1ZXJ5KGlucHV0OiBRdWVyeUlucHV0LCB0aW1lb3V0TXM/OiBudW1iZXIpOiBQcm9taXNlPENsaVJlc3VsdD4ge1xuICAgIGNvbnN0IHRyaWVkVG9rZW5zID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgY29uc3Qgd29ya2VyID0gdGhpcy5zZWxlY3RXb3JrZXIoKTtcbiAgICAgIGlmICghd29ya2VyKSB7XG4gICAgICAgIHRocm93IG5ldyBRdW90YUVycm9yKFwiQWxsIHRva2VucyBleGhhdXN0ZWRcIik7XG4gICAgICB9XG5cbiAgICAgIGlmICh0cmllZFRva2Vucy5oYXMod29ya2VyLnRva2VuSWQpKSB7XG4gICAgICAgIHRocm93IG5ldyBRdW90YUVycm9yKFwiQWxsIHRva2VucyBleGhhdXN0ZWRcIik7XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdvcmtlci5xdWVyeShpbnB1dCwgdGltZW91dE1zKTtcbiAgICAgICAgdGhpcy5sYXN0VXNlZFRva2VuID0gd29ya2VyLnRva2VuSWQ7XG4gICAgICAgIHRoaXMucmVxdWVzdENvdW50cy5zZXQod29ya2VyLnRva2VuSWQsICh0aGlzLnJlcXVlc3RDb3VudHMuZ2V0KHdvcmtlci50b2tlbklkKSA/PyAwKSArIDEpO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIFF1b3RhRXJyb3IpIHtcbiAgICAgICAgICB0aGlzLnF1b3RhRXhoYXVzdGVkLmFkZCh3b3JrZXIudG9rZW5JZCk7XG4gICAgICAgICAgdHJpZWRUb2tlbnMuYWRkKHdvcmtlci50b2tlbklkKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAga2lsbCgpOiB2b2lkIHtcbiAgICBbLi4udGhpcy53b3JrZXJzLnZhbHVlcygpXS5mbGF0KCkuZm9yRWFjaCgodykgPT4ge1xuICAgICAgdy5raWxsKCk7XG4gICAgfSk7XG4gIH1cblxuICBjcmVhdGVXb3JrZXJzKHRva2VuOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy53b3JrZXJzLmhhcyh0b2tlbikpIHJldHVybjtcblxuICAgIGNvbnN0IHdvcmtlckNvbmZpZzogV29ya2VyQ29uZmlnID0ge1xuICAgICAgdG9rZW4sXG4gICAgICBtb2RlbDogdGhpcy5tb2RlbCxcbiAgICAgIHRpbWVvdXQ6IHRoaXMudGltZW91dCxcbiAgICAgIGN3ZDogdGhpcy5jd2QsXG4gICAgICBtYXhDYWxsczogdGhpcy5tYXhDYWxscyxcbiAgICB9O1xuXG4gICAgY29uc3Qgd29ya2VycyA9IEFycmF5LmZyb20oeyBsZW5ndGg6IHRoaXMuc2l6ZSB9LCAoKSA9PiBuZXcgV29ya2VyKHdvcmtlckNvbmZpZykpO1xuICAgIHRoaXMud29ya2Vycy5zZXQodG9rZW4sIHdvcmtlcnMpO1xuICAgIHRoaXMucmVxdWVzdENvdW50cy5zZXQodG9rZW4sIDApO1xuICB9XG5cbiAgZGVzdHJveVdvcmtlcnModG9rZW46IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHdvcmtlcnMgPSB0aGlzLndvcmtlcnMuZ2V0KHRva2VuKTtcbiAgICBpZiAoIXdvcmtlcnMpIHJldHVybjtcblxuICAgIHdvcmtlcnMuZm9yRWFjaCgodykgPT4ge1xuICAgICAgdy5raWxsKCk7XG4gICAgfSk7XG4gICAgdGhpcy53b3JrZXJzLmRlbGV0ZSh0b2tlbik7XG4gICAgdGhpcy5xdW90YUV4aGF1c3RlZC5kZWxldGUodG9rZW4pO1xuICAgIHRoaXMucmVxdWVzdENvdW50cy5kZWxldGUodG9rZW4pO1xuICB9XG59XG5cbi8vIFBvb2wg7Iux6riA7YS0IOq0gOumrFxubGV0IHBvb2w6IENsYXVkZVBvb2wgfCBudWxsID0gbnVsbDtcblxuZXhwb3J0IGZ1bmN0aW9uIGluaXRQb29sKHRva2Vuczogc3RyaW5nW10pOiBDbGF1ZGVQb29sIHtcbiAgcG9vbCA9IG5ldyBDbGF1ZGVQb29sKHsgdG9rZW5zIH0pO1xuICByZXR1cm4gcG9vbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFBvb2woKTogQ2xhdWRlUG9vbCB7XG4gIGlmICghcG9vbCkgdGhyb3cgbmV3IEVycm9yKFwiUG9vbCBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdFBvb2woKSBmaXJzdC5cIik7XG4gIHJldHVybiBwb29sO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7O0FBYUEsSUFBYSxhQUFiLE1BQXdCO0NBQ3RCLDBCQUFVLElBQUksS0FBdUI7Q0FDckMsaUNBQWlCLElBQUksS0FBYTtDQUNsQyxnQ0FBZ0IsSUFBSSxLQUFxQjtDQUN6QyxnQkFBZ0I7Q0FDaEI7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUVBLFlBQVksUUFBb0I7QUFDOUIsT0FBSyxPQUFPLE9BQU8sUUFBUTtBQUMzQixPQUFLLFFBQVEsT0FBTyxTQUFTO0FBQzdCLE9BQUssVUFBVSxPQUFPLFdBQVc7QUFDakMsT0FBSyxNQUFNLE9BQU8sT0FBTztBQUN6QixPQUFLLFdBQVcsT0FBTyxZQUFZO0FBRW5DLFNBQU8sT0FBTyxTQUFTLFVBQVU7QUFDL0IsUUFBSyxjQUFjLE1BQU07SUFDekI7O0NBR0osU0FBUyxZQUFnRDtBQUN2RCxTQUFPLENBQUMsR0FBRyxLQUFLLFFBQVEsTUFBTSxDQUFDLENBQUMsS0FBSyxXQUFXO0dBQzlDO0dBQ0EsTUFBTSxZQUFZLElBQUksTUFBTSxJQUFJO0dBQ2hDLFVBQVUsS0FBSyxjQUFjLElBQUksTUFBTSxJQUFJO0dBQzNDLFFBQVEsQ0FBQyxLQUFLLGVBQWUsSUFBSSxNQUFNO0dBQ3hDLEVBQUU7O0NBR0wsZUFBOEI7RUFDNUIsTUFBTSxhQUFhLENBQUMsR0FBRyxLQUFLLFFBQVEsU0FBUyxDQUFDLENBQzNDLFFBQVEsQ0FBQyxXQUFXLENBQUMsS0FBSyxlQUFlLElBQUksTUFBTSxDQUFDLENBQ3BELFNBQVMsR0FBRyxhQUFhLFFBQVE7QUFFcEMsTUFBSSxXQUFXLFdBQVcsRUFBRyxRQUFPO0FBRXBDLFNBQU8sV0FBVyxRQUFRLE1BQU0sTUFBTyxFQUFFLGVBQWUsR0FBRyxLQUFLLGVBQWUsR0FBRyxJQUFJLEtBQU07O0NBRzlGLE1BQU0sTUFBTSxPQUFtQixXQUF3QztFQUNyRSxNQUFNLDhCQUFjLElBQUksS0FBYTtBQUVyQyxTQUFPLE1BQU07R0FDWCxNQUFNLFNBQVMsS0FBSyxjQUFjO0FBQ2xDLE9BQUksQ0FBQyxPQUNILE9BQU0sSUFBSSxXQUFXLHVCQUF1QjtBQUc5QyxPQUFJLFlBQVksSUFBSSxPQUFPLFFBQVEsQ0FDakMsT0FBTSxJQUFJLFdBQVcsdUJBQXVCO0FBRzlDLE9BQUk7SUFDRixNQUFNLFNBQVMsTUFBTSxPQUFPLE1BQU0sT0FBTyxVQUFVO0FBQ25ELFNBQUssZ0JBQWdCLE9BQU87QUFDNUIsU0FBSyxjQUFjLElBQUksT0FBTyxVQUFVLEtBQUssY0FBYyxJQUFJLE9BQU8sUUFBUSxJQUFJLEtBQUssRUFBRTtBQUV6RixXQUFPO1lBQ0EsS0FBSztBQUNaLFFBQUksZUFBZSxZQUFZO0FBQzdCLFVBQUssZUFBZSxJQUFJLE9BQU8sUUFBUTtBQUN2QyxpQkFBWSxJQUFJLE9BQU8sUUFBUTtBQUMvQjs7QUFFRixVQUFNOzs7O0NBS1osT0FBYTtBQUNYLEdBQUMsR0FBRyxLQUFLLFFBQVEsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsTUFBTTtBQUMvQyxLQUFFLE1BQU07SUFDUjs7Q0FHSixjQUFjLE9BQXFCO0FBQ2pDLE1BQUksS0FBSyxRQUFRLElBQUksTUFBTSxDQUFFO0VBRTdCLE1BQU0sZUFBNkI7R0FDakM7R0FDQSxPQUFPLEtBQUs7R0FDWixTQUFTLEtBQUs7R0FDZCxLQUFLLEtBQUs7R0FDVixVQUFVLEtBQUs7R0FDaEI7RUFFRCxNQUFNLFVBQVUsTUFBTSxLQUFLLEVBQUUsUUFBUSxLQUFLLE1BQU0sUUFBUSxJQUFJLE9BQU8sYUFBYSxDQUFDO0FBQ2pGLE9BQUssUUFBUSxJQUFJLE9BQU8sUUFBUTtBQUNoQyxPQUFLLGNBQWMsSUFBSSxPQUFPLEVBQUU7O0NBR2xDLGVBQWUsT0FBcUI7RUFDbEMsTUFBTSxVQUFVLEtBQUssUUFBUSxJQUFJLE1BQU07QUFDdkMsTUFBSSxDQUFDLFFBQVM7QUFFZCxVQUFRLFNBQVMsTUFBTTtBQUNyQixLQUFFLE1BQU07SUFDUjtBQUNGLE9BQUssUUFBUSxPQUFPLE1BQU07QUFDMUIsT0FBSyxlQUFlLE9BQU8sTUFBTTtBQUNqQyxPQUFLLGNBQWMsT0FBTyxNQUFNOzs7QUFLcEMsSUFBSSxPQUEwQjtBQUU5QixTQUFnQixTQUFTLFFBQThCO0FBQ3JELFFBQU8sSUFBSSxXQUFXLEVBQUUsUUFBUSxDQUFDO0FBQ2pDLFFBQU87O0FBR1QsU0FBZ0IsVUFBc0I7QUFDcEMsS0FBSSxDQUFDLEtBQU0sT0FBTSxJQUFJLE1BQU0sK0NBQStDO0FBQzFFLFFBQU8ifQ==
|
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
import "../../_virtual/_rolldown/runtime.js";
|
|
2
|
-
import { buildAuthUrl, exchangeCodeForTokens, fetchUsage, generatePKCE, refreshAccessToken } from "./oauth.js";
|
|
3
|
-
import { getPool } from "./pool.js";
|
|
4
|
-
import { __decorateMetadata } from "../../_virtual/_@oxc-project_runtime@0.122.0/helpers/decorateMetadata.js";
|
|
5
|
-
import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.122.0/helpers/decorate.js";
|
|
6
|
-
import { RequestLogModel } from "../request-log/request-log.model.js";
|
|
7
|
-
import { TokenModel } from "../token/token.model.js";
|
|
8
|
-
import { BaseFrameClass, api } from "sonamu";
|
|
9
|
-
//#region src/application/qgrid/qgrid.frame.ts
|
|
10
|
-
const pendingOAuth = /* @__PURE__ */ new Map();
|
|
11
|
-
var QgridFrameClass = class extends BaseFrameClass {
|
|
12
|
-
constructor() {
|
|
13
|
-
super("Qgrid");
|
|
14
|
-
}
|
|
15
|
-
async query(prompt, system, timeout) {
|
|
16
|
-
const pool = getPool();
|
|
17
|
-
const result = await pool.query({
|
|
18
|
-
system,
|
|
19
|
-
prompt
|
|
20
|
-
}, timeout);
|
|
21
|
-
TokenModel.findByToken("A", pool.lastUsedToken).then((tokenEntry) => {
|
|
22
|
-
RequestLogModel.save([{
|
|
23
|
-
token_name: tokenEntry?.name ?? "Unknown Key",
|
|
24
|
-
query: system ? `[System]\n${system}\n\n[User]\n${prompt}` : prompt,
|
|
25
|
-
response: result.text,
|
|
26
|
-
input_tokens: result.usage.input_tokens,
|
|
27
|
-
output_tokens: result.usage.output_tokens,
|
|
28
|
-
cache_read_tokens: result.usage.cache_read_input_tokens,
|
|
29
|
-
cache_creation_tokens: result.usage.cache_creation_input_tokens,
|
|
30
|
-
duration_ms: result.durationMs
|
|
31
|
-
}]);
|
|
32
|
-
}).catch((e) => console.error("requestLog save failed:", e));
|
|
33
|
-
return result;
|
|
34
|
-
}
|
|
35
|
-
async stats() {
|
|
36
|
-
const pool = getPool();
|
|
37
|
-
const entries = await TokenModel.findActive("A");
|
|
38
|
-
const tokenNames = new Map(entries.map((e) => [e.token, e.name]));
|
|
39
|
-
return pool.getStats(tokenNames);
|
|
40
|
-
}
|
|
41
|
-
async addToken(token, name, refreshToken) {
|
|
42
|
-
await TokenModel.save([{
|
|
43
|
-
token,
|
|
44
|
-
name,
|
|
45
|
-
...refreshToken && refreshToken.length > 0 ? { refresh_token: refreshToken } : {}
|
|
46
|
-
}]);
|
|
47
|
-
getPool().createWorkers(token);
|
|
48
|
-
return { added: true };
|
|
49
|
-
}
|
|
50
|
-
async updateToken(token, name, newToken, refreshToken) {
|
|
51
|
-
const pool = getPool();
|
|
52
|
-
const entry = await TokenModel.findByToken("A", token);
|
|
53
|
-
if (!entry) return { updated: false };
|
|
54
|
-
const hasNewToken = newToken !== void 0 && newToken.length > 0;
|
|
55
|
-
const hasRefreshToken = refreshToken !== void 0 && refreshToken.length > 0;
|
|
56
|
-
await TokenModel.save([{
|
|
57
|
-
id: entry.id,
|
|
58
|
-
token: hasNewToken ? newToken : entry.token,
|
|
59
|
-
name: name !== void 0 ? name : entry.name,
|
|
60
|
-
...hasRefreshToken ? { refresh_token: refreshToken } : {}
|
|
61
|
-
}]);
|
|
62
|
-
if (hasNewToken) {
|
|
63
|
-
pool.destroyWorkers(token);
|
|
64
|
-
pool.createWorkers(newToken);
|
|
65
|
-
}
|
|
66
|
-
return { updated: true };
|
|
67
|
-
}
|
|
68
|
-
async removeToken(token) {
|
|
69
|
-
const pool = getPool();
|
|
70
|
-
if (!pool.workers.has(token)) return { removed: false };
|
|
71
|
-
const entry = await TokenModel.findByToken("A", token);
|
|
72
|
-
if (entry) await TokenModel.del([entry.id]);
|
|
73
|
-
pool.destroyWorkers(token);
|
|
74
|
-
return { removed: true };
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
*
|
|
78
|
-
* @param id token_id
|
|
79
|
-
* 토큰 활성화/비활성화 토글 (pool 워커 생성/제거 & DB의 active 필드 업데이트)
|
|
80
|
-
*
|
|
81
|
-
* @returns 토큰 활성화 여부
|
|
82
|
-
*/
|
|
83
|
-
async toggleToken(id) {
|
|
84
|
-
const pool = getPool();
|
|
85
|
-
const entry = await TokenModel.findOne("A", { id });
|
|
86
|
-
if (!entry) return { active: false };
|
|
87
|
-
const newActive = !entry.active;
|
|
88
|
-
await TokenModel.save([{
|
|
89
|
-
id,
|
|
90
|
-
token: entry.token,
|
|
91
|
-
active: newActive,
|
|
92
|
-
name: entry.name
|
|
93
|
-
}]);
|
|
94
|
-
if (newActive) pool.createWorkers(entry.token);
|
|
95
|
-
else pool.destroyWorkers(entry.token);
|
|
96
|
-
return { active: newActive };
|
|
97
|
-
}
|
|
98
|
-
async oauthStart(name) {
|
|
99
|
-
const { codeVerifier, codeChallenge, state } = generatePKCE();
|
|
100
|
-
const redirectUri = `http://localhost:${process.env.PORT ?? "44900"}/callback`;
|
|
101
|
-
const authUrl = buildAuthUrl(codeChallenge, state, redirectUri);
|
|
102
|
-
pendingOAuth.set(state, {
|
|
103
|
-
codeVerifier,
|
|
104
|
-
name,
|
|
105
|
-
redirectUri
|
|
106
|
-
});
|
|
107
|
-
setTimeout(() => pendingOAuth.delete(state), 3e5);
|
|
108
|
-
return { authUrl };
|
|
109
|
-
}
|
|
110
|
-
async handleOAuthCallback(code, state, reply) {
|
|
111
|
-
const pool = getPool();
|
|
112
|
-
const pending = pendingOAuth.get(state);
|
|
113
|
-
if (!pending) return reply.redirect("/?oauth=error&reason=invalid_state");
|
|
114
|
-
pendingOAuth.delete(state);
|
|
115
|
-
try {
|
|
116
|
-
const tokens = await exchangeCodeForTokens(code, pending.codeVerifier, state, pending.redirectUri);
|
|
117
|
-
if (tokens.accountUuid) {
|
|
118
|
-
const oldEntries = await TokenModel.findByAccountUuid("A", tokens.accountUuid);
|
|
119
|
-
for (const old of oldEntries) {
|
|
120
|
-
pool.destroyWorkers(old.token);
|
|
121
|
-
await TokenModel.del([old.id]);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
await TokenModel.save([{
|
|
125
|
-
token: tokens.accessToken,
|
|
126
|
-
name: pending.name,
|
|
127
|
-
refresh_token: tokens.refreshToken,
|
|
128
|
-
expires_at: tokens.expiresAt ? BigInt(tokens.expiresAt) : null,
|
|
129
|
-
account_uuid: tokens.accountUuid
|
|
130
|
-
}]);
|
|
131
|
-
pool.createWorkers(tokens.accessToken);
|
|
132
|
-
return reply.redirect(`/?oauth=success&name=${encodeURIComponent(pending.name)}`);
|
|
133
|
-
} catch (e) {
|
|
134
|
-
return reply.redirect(`/?oauth=error&reason=${encodeURIComponent(e.message)}`);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
async usage(tokenName) {
|
|
138
|
-
const pool = getPool();
|
|
139
|
-
const { rows: allTokens } = await TokenModel.findMany("A");
|
|
140
|
-
const entry = tokenName ? allTokens.find((e) => e.name === tokenName) : allTokens.findLast((e) => e.active);
|
|
141
|
-
if (!entry) return { error: "NOT_FOUND" };
|
|
142
|
-
let accessToken = entry.token;
|
|
143
|
-
if (entry.expires_at && Number(entry.expires_at) < Date.now() && entry.refresh_token) try {
|
|
144
|
-
accessToken = await this.refreshToken(pool, entry);
|
|
145
|
-
} catch (e) {
|
|
146
|
-
console.warn(`[usage] refresh failed for ${entry.name}: ${e.message}`);
|
|
147
|
-
return { error: "re-login required" };
|
|
148
|
-
}
|
|
149
|
-
const result = await fetchUsage(accessToken);
|
|
150
|
-
if (result.error && entry.refresh_token) try {
|
|
151
|
-
accessToken = await this.refreshToken(pool, entry);
|
|
152
|
-
return await fetchUsage(accessToken);
|
|
153
|
-
} catch (e) {
|
|
154
|
-
console.warn(`[usage] refresh failed for ${entry.name}: ${e.message}`);
|
|
155
|
-
return { error: "re-login required" };
|
|
156
|
-
}
|
|
157
|
-
return result;
|
|
158
|
-
}
|
|
159
|
-
async refreshToken(pool, token) {
|
|
160
|
-
if (!token.refresh_token) throw new Error("No refresh token");
|
|
161
|
-
const refreshed = await refreshAccessToken(token.refresh_token);
|
|
162
|
-
await TokenModel.save([{
|
|
163
|
-
id: token.id,
|
|
164
|
-
token: refreshed.accessToken,
|
|
165
|
-
refresh_token: refreshed.refreshToken,
|
|
166
|
-
expires_at: BigInt(refreshed.expiresAt),
|
|
167
|
-
name: token.name ?? ""
|
|
168
|
-
}]);
|
|
169
|
-
pool.destroyWorkers(token.token);
|
|
170
|
-
pool.createWorkers(refreshed.accessToken);
|
|
171
|
-
return refreshed.accessToken;
|
|
172
|
-
}
|
|
173
|
-
async health() {
|
|
174
|
-
const pool = getPool();
|
|
175
|
-
return {
|
|
176
|
-
status: "ok",
|
|
177
|
-
workers: [...pool.workers.values()].flat().length,
|
|
178
|
-
activeTokens: pool.workers.size - pool.quotaExhausted.size
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
};
|
|
182
|
-
__decorate([
|
|
183
|
-
api({
|
|
184
|
-
httpMethod: "POST",
|
|
185
|
-
clients: ["axios", "tanstack-mutation"]
|
|
186
|
-
}),
|
|
187
|
-
__decorateMetadata("design:type", Function),
|
|
188
|
-
__decorateMetadata("design:paramtypes", [
|
|
189
|
-
String,
|
|
190
|
-
String,
|
|
191
|
-
Number
|
|
192
|
-
]),
|
|
193
|
-
__decorateMetadata("design:returntype", Promise)
|
|
194
|
-
], QgridFrameClass.prototype, "query", null);
|
|
195
|
-
__decorate([
|
|
196
|
-
api({
|
|
197
|
-
httpMethod: "GET",
|
|
198
|
-
clients: ["axios", "tanstack-query"]
|
|
199
|
-
}),
|
|
200
|
-
__decorateMetadata("design:type", Function),
|
|
201
|
-
__decorateMetadata("design:paramtypes", []),
|
|
202
|
-
__decorateMetadata("design:returntype", Promise)
|
|
203
|
-
], QgridFrameClass.prototype, "stats", null);
|
|
204
|
-
__decorate([
|
|
205
|
-
api({
|
|
206
|
-
httpMethod: "POST",
|
|
207
|
-
clients: ["axios", "tanstack-mutation"]
|
|
208
|
-
}),
|
|
209
|
-
__decorateMetadata("design:type", Function),
|
|
210
|
-
__decorateMetadata("design:paramtypes", [
|
|
211
|
-
String,
|
|
212
|
-
String,
|
|
213
|
-
String
|
|
214
|
-
]),
|
|
215
|
-
__decorateMetadata("design:returntype", Promise)
|
|
216
|
-
], QgridFrameClass.prototype, "addToken", null);
|
|
217
|
-
__decorate([
|
|
218
|
-
api({
|
|
219
|
-
httpMethod: "POST",
|
|
220
|
-
clients: ["axios", "tanstack-mutation"]
|
|
221
|
-
}),
|
|
222
|
-
__decorateMetadata("design:type", Function),
|
|
223
|
-
__decorateMetadata("design:paramtypes", [
|
|
224
|
-
String,
|
|
225
|
-
String,
|
|
226
|
-
String,
|
|
227
|
-
String
|
|
228
|
-
]),
|
|
229
|
-
__decorateMetadata("design:returntype", Promise)
|
|
230
|
-
], QgridFrameClass.prototype, "updateToken", null);
|
|
231
|
-
__decorate([
|
|
232
|
-
api({
|
|
233
|
-
httpMethod: "POST",
|
|
234
|
-
clients: ["axios", "tanstack-mutation"]
|
|
235
|
-
}),
|
|
236
|
-
__decorateMetadata("design:type", Function),
|
|
237
|
-
__decorateMetadata("design:paramtypes", [String]),
|
|
238
|
-
__decorateMetadata("design:returntype", Promise)
|
|
239
|
-
], QgridFrameClass.prototype, "removeToken", null);
|
|
240
|
-
__decorate([
|
|
241
|
-
api({
|
|
242
|
-
httpMethod: "POST",
|
|
243
|
-
clients: ["axios", "tanstack-mutation"]
|
|
244
|
-
}),
|
|
245
|
-
__decorateMetadata("design:type", Function),
|
|
246
|
-
__decorateMetadata("design:paramtypes", [Number]),
|
|
247
|
-
__decorateMetadata("design:returntype", Promise)
|
|
248
|
-
], QgridFrameClass.prototype, "toggleToken", null);
|
|
249
|
-
__decorate([
|
|
250
|
-
api({
|
|
251
|
-
httpMethod: "POST",
|
|
252
|
-
clients: ["axios", "tanstack-mutation"]
|
|
253
|
-
}),
|
|
254
|
-
__decorateMetadata("design:type", Function),
|
|
255
|
-
__decorateMetadata("design:paramtypes", [String]),
|
|
256
|
-
__decorateMetadata("design:returntype", Promise)
|
|
257
|
-
], QgridFrameClass.prototype, "oauthStart", null);
|
|
258
|
-
__decorate([
|
|
259
|
-
api({
|
|
260
|
-
httpMethod: "GET",
|
|
261
|
-
clients: ["axios", "tanstack-query"]
|
|
262
|
-
}),
|
|
263
|
-
__decorateMetadata("design:type", Function),
|
|
264
|
-
__decorateMetadata("design:paramtypes", [String]),
|
|
265
|
-
__decorateMetadata("design:returntype", Promise)
|
|
266
|
-
], QgridFrameClass.prototype, "usage", null);
|
|
267
|
-
__decorate([
|
|
268
|
-
api({
|
|
269
|
-
httpMethod: "GET",
|
|
270
|
-
clients: ["axios", "tanstack-query"]
|
|
271
|
-
}),
|
|
272
|
-
__decorateMetadata("design:type", Function),
|
|
273
|
-
__decorateMetadata("design:paramtypes", []),
|
|
274
|
-
__decorateMetadata("design:returntype", Promise)
|
|
275
|
-
], QgridFrameClass.prototype, "health", null);
|
|
276
|
-
const QgridFrame = new QgridFrameClass();
|
|
277
|
-
//#endregion
|
|
278
|
-
export { QgridFrame };
|
|
279
|
-
|
|
280
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicWdyaWQuZnJhbWUuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3FncmlkL3FncmlkLmZyYW1lLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgRmFzdGlmeVJlcGx5IH0gZnJvbSBcImZhc3RpZnlcIjtcbmltcG9ydCB7IGFwaSwgQmFzZUZyYW1lQ2xhc3MgfSBmcm9tIFwic29uYW11XCI7XG5cbmltcG9ydCB7IFJlcXVlc3RMb2dNb2RlbCB9IGZyb20gXCIuLi9yZXF1ZXN0LWxvZy9yZXF1ZXN0LWxvZy5tb2RlbFwiO1xuaW1wb3J0IHsgVG9rZW5Nb2RlbCB9IGZyb20gXCIuLi90b2tlbi90b2tlbi5tb2RlbFwiO1xuaW1wb3J0IHR5cGUgeyBSZWZyZXNoVG9rZW5QYXJhbXMgfSBmcm9tIFwiLi4vdG9rZW4vdG9rZW4udHlwZXNcIjtcbmltcG9ydCB7XG4gIGJ1aWxkQXV0aFVybCxcbiAgZXhjaGFuZ2VDb2RlRm9yVG9rZW5zLFxuICBmZXRjaFVzYWdlLFxuICBnZW5lcmF0ZVBLQ0UsXG4gIHJlZnJlc2hBY2Nlc3NUb2tlbixcbn0gZnJvbSBcIi4vb2F1dGhcIjtcbmltcG9ydCB7IHR5cGUgQ2xhdWRlUG9vbCwgZ2V0UG9vbCB9IGZyb20gXCIuL3Bvb2xcIjtcbmltcG9ydCB0eXBlIHtcbiAgQ2xpUmVzdWx0LFxuICBIZWFsdGhSZXNwb25zZSxcbiAgT0F1dGhTdGFydFJlc3VsdCxcbiAgVG9rZW5TdGF0cyxcbiAgVXNhZ2VSZXNwb25zZSxcbn0gZnJvbSBcIi4vcWdyaWQudHlwZXNcIjtcblxuLy8gUEtDRSDshLjshZgg66mU66qo66asIOyggOyepSAoc3RhdGUg4oaSIHsgY29kZVZlcmlmaWVyLCBuYW1lLCByZWRpcmVjdFVyaSB9KVxuY29uc3QgcGVuZGluZ09BdXRoID0gbmV3IE1hcDxzdHJpbmcsIHsgY29kZVZlcmlmaWVyOiBzdHJpbmc7IG5hbWU6IHN0cmluZzsgcmVkaXJlY3RVcmk6IHN0cmluZyB9PigpO1xuXG5jbGFzcyBRZ3JpZEZyYW1lQ2xhc3MgZXh0ZW5kcyBCYXNlRnJhbWVDbGFzcyB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKFwiUWdyaWRcIik7XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJQT1NUXCIsIGNsaWVudHM6IFtcImF4aW9zXCIsIFwidGFuc3RhY2stbXV0YXRpb25cIl0gfSlcbiAgYXN5bmMgcXVlcnkocHJvbXB0OiBzdHJpbmcsIHN5c3RlbT86IHN0cmluZywgdGltZW91dD86IG51bWJlcik6IFByb21pc2U8Q2xpUmVzdWx0PiB7XG4gICAgY29uc3QgcG9vbCA9IGdldFBvb2woKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwb29sLnF1ZXJ5KHsgc3lzdGVtLCBwcm9tcHQgfSwgdGltZW91dCk7XG5cbiAgICAvLyDroZzqt7gg6riw66GdIOyLpO2MqO2VtOuPhCDsv7zrpqwg6rKw6rO864qUIOuwmO2ZmFxuICAgIFRva2VuTW9kZWwuZmluZEJ5VG9rZW4oXCJBXCIsIHBvb2wubGFzdFVzZWRUb2tlbilcbiAgICAgIC50aGVuKCh0b2tlbkVudHJ5KSA9PiB7XG4gICAgICAgIFJlcXVlc3RMb2dNb2RlbC5zYXZlKFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0b2tlbl9uYW1lOiB0b2tlbkVudHJ5Py5uYW1lID8/IFwiVW5rbm93biBLZXlcIixcbiAgICAgICAgICAgIHF1ZXJ5OiBzeXN0ZW0gPyBgW1N5c3RlbV1cXG4ke3N5c3RlbX1cXG5cXG5bVXNlcl1cXG4ke3Byb21wdH1gIDogcHJvbXB0LFxuICAgICAgICAgICAgcmVzcG9uc2U6IHJlc3VsdC50ZXh0LFxuICAgICAgICAgICAgaW5wdXRfdG9rZW5zOiByZXN1bHQudXNhZ2UuaW5wdXRfdG9rZW5zLFxuICAgICAgICAgICAgb3V0cHV0X3Rva2VuczogcmVzdWx0LnVzYWdlLm91dHB1dF90b2tlbnMsXG4gICAgICAgICAgICBjYWNoZV9yZWFkX3Rva2VuczogcmVzdWx0LnVzYWdlLmNhY2hlX3JlYWRfaW5wdXRfdG9rZW5zLFxuICAgICAgICAgICAgY2FjaGVfY3JlYXRpb25fdG9rZW5zOiByZXN1bHQudXNhZ2UuY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zLFxuICAgICAgICAgICAgZHVyYXRpb25fbXM6IHJlc3VsdC5kdXJhdGlvbk1zLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoZSkgPT4gY29uc29sZS5lcnJvcihcInJlcXVlc3RMb2cgc2F2ZSBmYWlsZWQ6XCIsIGUpKTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJHRVRcIiwgY2xpZW50czogW1wiYXhpb3NcIiwgXCJ0YW5zdGFjay1xdWVyeVwiXSB9KVxuICBhc3luYyBzdGF0cygpOiBQcm9taXNlPFRva2VuU3RhdHNbXT4ge1xuICAgIGNvbnN0IHBvb2wgPSBnZXRQb29sKCk7XG4gICAgY29uc3QgZW50cmllcyA9IGF3YWl0IFRva2VuTW9kZWwuZmluZEFjdGl2ZShcIkFcIik7XG4gICAgY29uc3QgdG9rZW5OYW1lcyA9IG5ldyBNYXAoZW50cmllcy5tYXAoKGUpID0+IFtlLnRva2VuLCBlLm5hbWVdKSk7XG4gICAgcmV0dXJuIHBvb2wuZ2V0U3RhdHModG9rZW5OYW1lcyk7XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJQT1NUXCIsIGNsaWVudHM6IFtcImF4aW9zXCIsIFwidGFuc3RhY2stbXV0YXRpb25cIl0gfSlcbiAgYXN5bmMgYWRkVG9rZW4odG9rZW46IHN0cmluZywgbmFtZTogc3RyaW5nLCByZWZyZXNoVG9rZW4/OiBzdHJpbmcpOiBQcm9taXNlPHsgYWRkZWQ6IGJvb2xlYW4gfT4ge1xuICAgIGF3YWl0IFRva2VuTW9kZWwuc2F2ZShbXG4gICAgICB7XG4gICAgICAgIHRva2VuLFxuICAgICAgICBuYW1lLFxuICAgICAgICAuLi4ocmVmcmVzaFRva2VuICYmIHJlZnJlc2hUb2tlbi5sZW5ndGggPiAwID8geyByZWZyZXNoX3Rva2VuOiByZWZyZXNoVG9rZW4gfSA6IHt9KSxcbiAgICAgIH0sXG4gICAgXSk7XG4gICAgZ2V0UG9vbCgpLmNyZWF0ZVdvcmtlcnModG9rZW4pO1xuICAgIHJldHVybiB7IGFkZGVkOiB0cnVlIH07XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJQT1NUXCIsIGNsaWVudHM6IFtcImF4aW9zXCIsIFwidGFuc3RhY2stbXV0YXRpb25cIl0gfSlcbiAgYXN5bmMgdXBkYXRlVG9rZW4oXG4gICAgdG9rZW46IHN0cmluZyxcbiAgICBuYW1lPzogc3RyaW5nLFxuICAgIG5ld1Rva2VuPzogc3RyaW5nLFxuICAgIHJlZnJlc2hUb2tlbj86IHN0cmluZyxcbiAgKTogUHJvbWlzZTx7IHVwZGF0ZWQ6IGJvb2xlYW4gfT4ge1xuICAgIGNvbnN0IHBvb2wgPSBnZXRQb29sKCk7XG4gICAgY29uc3QgZW50cnkgPSBhd2FpdCBUb2tlbk1vZGVsLmZpbmRCeVRva2VuKFwiQVwiLCB0b2tlbik7XG4gICAgaWYgKCFlbnRyeSkgcmV0dXJuIHsgdXBkYXRlZDogZmFsc2UgfTtcblxuICAgIGNvbnN0IGhhc05ld1Rva2VuID0gbmV3VG9rZW4gIT09IHVuZGVmaW5lZCAmJiBuZXdUb2tlbi5sZW5ndGggPiAwO1xuICAgIGNvbnN0IGhhc1JlZnJlc2hUb2tlbiA9IHJlZnJlc2hUb2tlbiAhPT0gdW5kZWZpbmVkICYmIHJlZnJlc2hUb2tlbi5sZW5ndGggPiAwO1xuICAgIGF3YWl0IFRva2VuTW9kZWwuc2F2ZShbXG4gICAgICB7XG4gICAgICAgIGlkOiBlbnRyeS5pZCxcbiAgICAgICAgdG9rZW46IGhhc05ld1Rva2VuID8gbmV3VG9rZW4gOiBlbnRyeS50b2tlbixcbiAgICAgICAgbmFtZTogbmFtZSAhPT0gdW5kZWZpbmVkID8gbmFtZSA6IGVudHJ5Lm5hbWUsXG4gICAgICAgIC4uLihoYXNSZWZyZXNoVG9rZW4gPyB7IHJlZnJlc2hfdG9rZW46IHJlZnJlc2hUb2tlbiB9IDoge30pLFxuICAgICAgfSxcbiAgICBdKTtcblxuICAgIGlmIChoYXNOZXdUb2tlbikge1xuICAgICAgcG9vbC5kZXN0cm95V29ya2Vycyh0b2tlbik7XG4gICAgICBwb29sLmNyZWF0ZVdvcmtlcnMobmV3VG9rZW4pO1xuICAgIH1cbiAgICByZXR1cm4geyB1cGRhdGVkOiB0cnVlIH07XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJQT1NUXCIsIGNsaWVudHM6IFtcImF4aW9zXCIsIFwidGFuc3RhY2stbXV0YXRpb25cIl0gfSlcbiAgYXN5bmMgcmVtb3ZlVG9rZW4odG9rZW46IHN0cmluZyk6IFByb21pc2U8eyByZW1vdmVkOiBib29sZWFuIH0+IHtcbiAgICBjb25zdCBwb29sID0gZ2V0UG9vbCgpO1xuICAgIGlmICghcG9vbC53b3JrZXJzLmhhcyh0b2tlbikpIHJldHVybiB7IHJlbW92ZWQ6IGZhbHNlIH07XG5cbiAgICBjb25zdCBlbnRyeSA9IGF3YWl0IFRva2VuTW9kZWwuZmluZEJ5VG9rZW4oXCJBXCIsIHRva2VuKTtcbiAgICBpZiAoZW50cnkpIGF3YWl0IFRva2VuTW9kZWwuZGVsKFtlbnRyeS5pZF0pO1xuICAgIHBvb2wuZGVzdHJveVdvcmtlcnModG9rZW4pO1xuICAgIHJldHVybiB7IHJlbW92ZWQ6IHRydWUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0gaWQgdG9rZW5faWRcbiAgICog7Yag7YGwIO2ZnOyEse2ZlC/ruYTtmZzshLHtmZQg7Yag6riAIChwb29sIOybjOy7pCDsg53shLEv7KCc6rGwICYgRELsnZggYWN0aXZlIO2VhOuTnCDsl4XrjbDsnbTtirgpXG4gICAqXG4gICAqIEByZXR1cm5zIO2GoO2BsCDtmZzshLHtmZQg7Jes67aAXG4gICAqL1xuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJQT1NUXCIsIGNsaWVudHM6IFtcImF4aW9zXCIsIFwidGFuc3RhY2stbXV0YXRpb25cIl0gfSlcbiAgYXN5bmMgdG9nZ2xlVG9rZW4oaWQ6IG51bWJlcik6IFByb21pc2U8eyBhY3RpdmU6IGJvb2xlYW4gfT4ge1xuICAgIGNvbnN0IHBvb2wgPSBnZXRQb29sKCk7XG4gICAgY29uc3QgZW50cnkgPSBhd2FpdCBUb2tlbk1vZGVsLmZpbmRPbmUoXCJBXCIsIHsgaWQgfSk7XG4gICAgaWYgKCFlbnRyeSkgcmV0dXJuIHsgYWN0aXZlOiBmYWxzZSB9O1xuXG4gICAgY29uc3QgbmV3QWN0aXZlID0gIWVudHJ5LmFjdGl2ZTtcbiAgICBhd2FpdCBUb2tlbk1vZGVsLnNhdmUoW3sgaWQsIHRva2VuOiBlbnRyeS50b2tlbiwgYWN0aXZlOiBuZXdBY3RpdmUsIG5hbWU6IGVudHJ5Lm5hbWUgfV0pO1xuXG4gICAgLy8g7Yag7YGw7J2YIOyDiOuhnOyatCDsg4Htg5zqsIAg7Zmc7ISx7ZmU66m0L+u5hO2ZnOyEse2ZlOuptFxuICAgIGlmIChuZXdBY3RpdmUpIHtcbiAgICAgIC8vIOybjOy7pCDsg53shLFcbiAgICAgIHBvb2wuY3JlYXRlV29ya2VycyhlbnRyeS50b2tlbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIOybjOy7pCDsoJzqsbBcbiAgICAgIHBvb2wuZGVzdHJveVdvcmtlcnMoZW50cnkudG9rZW4pO1xuICAgIH1cblxuICAgIHJldHVybiB7IGFjdGl2ZTogbmV3QWN0aXZlIH07XG4gIH1cblxuICAvLyBPQXV0aCDroZzqt7jsnbg6IGF1dGhVcmwg7IOd7ISxICjtlITroaDtirjsl5DshJwg7J20IEFQSSDtmLjstpwg7ZuEIGF1dGhVcmzroZwg66as64uk7J2066CJ7Yq4KVxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJQT1NUXCIsIGNsaWVudHM6IFtcImF4aW9zXCIsIFwidGFuc3RhY2stbXV0YXRpb25cIl0gfSlcbiAgYXN5bmMgb2F1dGhTdGFydChuYW1lOiBzdHJpbmcpOiBQcm9taXNlPE9BdXRoU3RhcnRSZXN1bHQ+IHtcbiAgICBjb25zdCB7IGNvZGVWZXJpZmllciwgY29kZUNoYWxsZW5nZSwgc3RhdGUgfSA9IGdlbmVyYXRlUEtDRSgpO1xuXG4gICAgY29uc3Qgc2VydmVyUG9ydCA9IHByb2Nlc3MuZW52LlBPUlQgPz8gXCI0NDkwMFwiO1xuICAgIGNvbnN0IHJlZGlyZWN0VXJpID0gYGh0dHA6Ly9sb2NhbGhvc3Q6JHtzZXJ2ZXJQb3J0fS9jYWxsYmFja2A7XG4gICAgY29uc3QgYXV0aFVybCA9IGJ1aWxkQXV0aFVybChjb2RlQ2hhbGxlbmdlLCBzdGF0ZSwgcmVkaXJlY3RVcmkpO1xuXG4gICAgLy8gUEtDReulvCDrqZTrqqjrpqzsl5Ag7KCA7J6lICg167aEIFRUTClcbiAgICBwZW5kaW5nT0F1dGguc2V0KHN0YXRlLCB7IGNvZGVWZXJpZmllciwgbmFtZSwgcmVkaXJlY3RVcmkgfSk7XG4gICAgc2V0VGltZW91dCgoKSA9PiBwZW5kaW5nT0F1dGguZGVsZXRlKHN0YXRlKSwgMzAwXzAwMCk7XG5cbiAgICByZXR1cm4geyBhdXRoVXJsIH07XG4gIH1cblxuICAvLyBPQXV0aCDsvZzrsLEg7LKY66asIOKAlCBzb25hbXUuY29uZmlnLnRz7J2YIGN1c3RvbSDrnbzsmrDtirjsl5DshJwg7Zi47Lac65CoXG4gIGFzeW5jIGhhbmRsZU9BdXRoQ2FsbGJhY2soY29kZTogc3RyaW5nLCBzdGF0ZTogc3RyaW5nLCByZXBseTogRmFzdGlmeVJlcGx5KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcG9vbCA9IGdldFBvb2woKTtcbiAgICBjb25zdCBwZW5kaW5nID0gcGVuZGluZ09BdXRoLmdldChzdGF0ZSk7XG4gICAgaWYgKCFwZW5kaW5nKSB7XG4gICAgICByZXR1cm4gcmVwbHkucmVkaXJlY3QoXCIvP29hdXRoPWVycm9yJnJlYXNvbj1pbnZhbGlkX3N0YXRlXCIpO1xuICAgIH1cbiAgICBwZW5kaW5nT0F1dGguZGVsZXRlKHN0YXRlKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB0b2tlbnMgPSBhd2FpdCBleGNoYW5nZUNvZGVGb3JUb2tlbnMoXG4gICAgICAgIGNvZGUsXG4gICAgICAgIHBlbmRpbmcuY29kZVZlcmlmaWVyLFxuICAgICAgICBzdGF0ZSxcbiAgICAgICAgcGVuZGluZy5yZWRpcmVjdFVyaSxcbiAgICAgICk7XG5cbiAgICAgIC8vIOqwmeydgCDqs4TsoJXsnZgg7J207KCEIO2GoO2BsOydtCDsnojsnLzrqbQg6rWQ7LK0XG4gICAgICBpZiAodG9rZW5zLmFjY291bnRVdWlkKSB7XG4gICAgICAgIGNvbnN0IG9sZEVudHJpZXMgPSBhd2FpdCBUb2tlbk1vZGVsLmZpbmRCeUFjY291bnRVdWlkKFwiQVwiLCB0b2tlbnMuYWNjb3VudFV1aWQpO1xuICAgICAgICBmb3IgKGNvbnN0IG9sZCBvZiBvbGRFbnRyaWVzKSB7XG4gICAgICAgICAgcG9vbC5kZXN0cm95V29ya2VycyhvbGQudG9rZW4pO1xuICAgICAgICAgIGF3YWl0IFRva2VuTW9kZWwuZGVsKFtvbGQuaWRdKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyDsg4gg7Yag7YGwIOyggOyepSArIHBvb2zsl5Ag65Ox66GdXG4gICAgICBhd2FpdCBUb2tlbk1vZGVsLnNhdmUoW1xuICAgICAgICB7XG4gICAgICAgICAgdG9rZW46IHRva2Vucy5hY2Nlc3NUb2tlbixcbiAgICAgICAgICBuYW1lOiBwZW5kaW5nLm5hbWUsXG4gICAgICAgICAgcmVmcmVzaF90b2tlbjogdG9rZW5zLnJlZnJlc2hUb2tlbixcbiAgICAgICAgICBleHBpcmVzX2F0OiB0b2tlbnMuZXhwaXJlc0F0ID8gQmlnSW50KHRva2Vucy5leHBpcmVzQXQpIDogbnVsbCxcbiAgICAgICAgICBhY2NvdW50X3V1aWQ6IHRva2Vucy5hY2NvdW50VXVpZCxcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuICAgICAgcG9vbC5jcmVhdGVXb3JrZXJzKHRva2Vucy5hY2Nlc3NUb2tlbik7XG5cbiAgICAgIHJldHVybiByZXBseS5yZWRpcmVjdChgLz9vYXV0aD1zdWNjZXNzJm5hbWU9JHtlbmNvZGVVUklDb21wb25lbnQocGVuZGluZy5uYW1lKX1gKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gcmVwbHkucmVkaXJlY3QoYC8/b2F1dGg9ZXJyb3ImcmVhc29uPSR7ZW5jb2RlVVJJQ29tcG9uZW50KChlIGFzIEVycm9yKS5tZXNzYWdlKX1gKTtcbiAgICB9XG4gIH1cblxuICAvLyDthqDtgbAg7IKs7Jqp65+JIOyhsO2ajCAoT0F1dGggdXNhZ2UgQVBJKVxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJHRVRcIiwgY2xpZW50czogW1wiYXhpb3NcIiwgXCJ0YW5zdGFjay1xdWVyeVwiXSB9KVxuICBhc3luYyB1c2FnZSh0b2tlbk5hbWU/OiBzdHJpbmcpOiBQcm9taXNlPFVzYWdlUmVzcG9uc2U+IHtcbiAgICBjb25zdCBwb29sID0gZ2V0UG9vbCgpO1xuICAgIGNvbnN0IHsgcm93czogYWxsVG9rZW5zIH0gPSBhd2FpdCBUb2tlbk1vZGVsLmZpbmRNYW55KFwiQVwiKTtcbiAgICBjb25zdCBlbnRyeSA9IHRva2VuTmFtZVxuICAgICAgPyBhbGxUb2tlbnMuZmluZCgoZSkgPT4gZS5uYW1lID09PSB0b2tlbk5hbWUpXG4gICAgICA6IGFsbFRva2Vucy5maW5kTGFzdCgoZSkgPT4gZS5hY3RpdmUpO1xuXG4gICAgaWYgKCFlbnRyeSkgcmV0dXJuIHsgZXJyb3I6IFwiTk9UX0ZPVU5EXCIgfTtcblxuICAgIC8vIOunjOujjCDtmZXsnbggKyByZWZyZXNoIOyLnOuPhFxuICAgIGxldCBhY2Nlc3NUb2tlbiA9IGVudHJ5LnRva2VuO1xuICAgIGNvbnN0IGlzRXhwaXJlZCA9IGVudHJ5LmV4cGlyZXNfYXQgJiYgTnVtYmVyKGVudHJ5LmV4cGlyZXNfYXQpIDwgRGF0ZS5ub3coKTtcblxuICAgIGlmIChpc0V4cGlyZWQgJiYgZW50cnkucmVmcmVzaF90b2tlbikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYWNjZXNzVG9rZW4gPSBhd2FpdCB0aGlzLnJlZnJlc2hUb2tlbihwb29sLCBlbnRyeSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgW3VzYWdlXSByZWZyZXNoIGZhaWxlZCBmb3IgJHtlbnRyeS5uYW1lfTogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgICAgcmV0dXJuIHsgZXJyb3I6IFwicmUtbG9naW4gcmVxdWlyZWRcIiB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHVzYWdlIO2YuOy2nFxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZldGNoVXNhZ2UoYWNjZXNzVG9rZW4pO1xuXG4gICAgLy8g7J247KadIOyXkOufrOuptCByZWZyZXNoX3Rva2Vu7Jy866GcIOyerOyLnOuPhFxuICAgIGlmIChyZXN1bHQuZXJyb3IgJiYgZW50cnkucmVmcmVzaF90b2tlbikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYWNjZXNzVG9rZW4gPSBhd2FpdCB0aGlzLnJlZnJlc2hUb2tlbihwb29sLCBlbnRyeSk7XG4gICAgICAgIHJldHVybiBhd2FpdCBmZXRjaFVzYWdlKGFjY2Vzc1Rva2VuKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGBbdXNhZ2VdIHJlZnJlc2ggZmFpbGVkIGZvciAke2VudHJ5Lm5hbWV9OiAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfWApO1xuICAgICAgICByZXR1cm4geyBlcnJvcjogXCJyZS1sb2dpbiByZXF1aXJlZFwiIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGFzeW5jIHJlZnJlc2hUb2tlbihwb29sOiBDbGF1ZGVQb29sLCB0b2tlbjogUmVmcmVzaFRva2VuUGFyYW1zKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBpZiAoIXRva2VuLnJlZnJlc2hfdG9rZW4pIHRocm93IG5ldyBFcnJvcihcIk5vIHJlZnJlc2ggdG9rZW5cIik7XG4gICAgY29uc3QgcmVmcmVzaGVkID0gYXdhaXQgcmVmcmVzaEFjY2Vzc1Rva2VuKHRva2VuLnJlZnJlc2hfdG9rZW4pO1xuICAgIGF3YWl0IFRva2VuTW9kZWwuc2F2ZShbXG4gICAgICB7XG4gICAgICAgIGlkOiB0b2tlbi5pZCxcbiAgICAgICAgdG9rZW46IHJlZnJlc2hlZC5hY2Nlc3NUb2tlbixcbiAgICAgICAgcmVmcmVzaF90b2tlbjogcmVmcmVzaGVkLnJlZnJlc2hUb2tlbixcbiAgICAgICAgZXhwaXJlc19hdDogQmlnSW50KHJlZnJlc2hlZC5leHBpcmVzQXQpLFxuICAgICAgICBuYW1lOiB0b2tlbi5uYW1lID8/IFwiXCIsXG4gICAgICB9LFxuICAgIF0pO1xuICAgIHBvb2wuZGVzdHJveVdvcmtlcnModG9rZW4udG9rZW4pO1xuICAgIHBvb2wuY3JlYXRlV29ya2VycyhyZWZyZXNoZWQuYWNjZXNzVG9rZW4pO1xuICAgIHJldHVybiByZWZyZXNoZWQuYWNjZXNzVG9rZW47XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJHRVRcIiwgY2xpZW50czogW1wiYXhpb3NcIiwgXCJ0YW5zdGFjay1xdWVyeVwiXSB9KVxuICBhc3luYyBoZWFsdGgoKTogUHJvbWlzZTxIZWFsdGhSZXNwb25zZT4ge1xuICAgIGNvbnN0IHBvb2wgPSBnZXRQb29sKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1czogXCJva1wiLFxuICAgICAgd29ya2VyczogWy4uLnBvb2wud29ya2Vycy52YWx1ZXMoKV0uZmxhdCgpLmxlbmd0aCxcbiAgICAgIGFjdGl2ZVRva2VuczogcG9vbC53b3JrZXJzLnNpemUgLSBwb29sLnF1b3RhRXhoYXVzdGVkLnNpemUsXG4gICAgfTtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgUWdyaWRGcmFtZSA9IG5ldyBRZ3JpZEZyYW1lQ2xhc3MoKTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBdUJBLE1BQU0sK0JBQWUsSUFBSSxLQUEwRTtBQUVuRyxJQUFNLGtCQUFOLGNBQThCLGVBQWU7Q0FDM0MsY0FBYztBQUNaLFFBQU0sUUFBUTs7Q0FHaEIsTUFDTSxNQUFNLFFBQWdCLFFBQWlCLFNBQXNDO0VBQ2pGLE1BQU0sT0FBTyxTQUFTO0VBQ3RCLE1BQU0sU0FB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
|