dsh-coding-subscription-oauth 0.6.5 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -2
- package/CONTRIBUTING.md +1 -1
- package/INSTALL.md +13 -8
- package/README.de.md +5 -5
- package/README.es.md +5 -5
- package/README.fr.md +5 -5
- package/README.ja.md +5 -5
- package/README.ko.md +5 -5
- package/README.md +7 -6
- package/README.pt-BR.md +5 -5
- package/README.ru.md +5 -5
- package/README.zh-CN.md +7 -6
- package/compatibility/dsh-bom.json +8 -2
- package/docs/00-project-rules.md +3 -2
- package/docs/02-architecture.md +5 -5
- package/docs/02-architecture.zh-CN.md +5 -5
- package/lib/adapter.d.ts.map +1 -1
- package/lib/auth-routes.d.ts +10 -1
- package/lib/auth-routes.d.ts.map +1 -1
- package/lib/bin.js +483 -50
- package/lib/bin.js.map +4 -4
- package/lib/client.js +5 -5
- package/lib/client.js.map +4 -4
- package/lib/compatibility.d.ts +0 -1
- package/lib/compatibility.d.ts.map +1 -1
- package/lib/gateway-protocol.d.ts +3 -3
- package/lib/gateway-protocol.d.ts.map +1 -1
- package/lib/grok-errors.d.ts +2 -2
- package/lib/grok-errors.d.ts.map +1 -1
- package/lib/http-json.d.ts +2 -2
- package/lib/http-json.d.ts.map +1 -1
- package/lib/ids.d.ts +4 -0
- package/lib/ids.d.ts.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +679 -163
- package/lib/index.js.map +4 -4
- package/lib/kimi-errors.d.ts +2 -2
- package/lib/kimi-errors.d.ts.map +1 -1
- package/lib/oauth-session.d.ts +2 -0
- package/lib/oauth-session.d.ts.map +1 -1
- package/lib/session.d.ts +2 -0
- package/lib/session.d.ts.map +1 -1
- package/lib/store.d.ts +73 -1
- package/lib/store.d.ts.map +1 -1
- package/package.json +9 -8
- package/scripts/verify-adapter-host.mjs +70 -0
- package/lib/runtime/gateway-protocol.d.ts +0 -47
- package/lib/runtime/gateway-protocol.d.ts.map +0 -1
- package/lib/runtime/grok-errors.d.ts +0 -13
- package/lib/runtime/grok-errors.d.ts.map +0 -1
- package/lib/runtime/http-json.d.ts +0 -10
- package/lib/runtime/http-json.d.ts.map +0 -1
- package/lib/runtime/kimi-errors.d.ts +0 -13
- package/lib/runtime/kimi-errors.d.ts.map +0 -1
package/lib/index.js
CHANGED
|
@@ -25609,7 +25609,7 @@ import { dirname as dirname6, join as join8 } from "node:path";
|
|
|
25609
25609
|
import { assertUsableApiKey, RetryPolicySchema } from "@deepseek-ai/dsh-llm";
|
|
25610
25610
|
import z2 from "@deepseek-ai/schemastery";
|
|
25611
25611
|
|
|
25612
|
-
// node_modules/.pnpm/dsh-coding-oauth-core@0.1.1/node_modules/dsh-coding-oauth-core/lib/proxy.js
|
|
25612
|
+
// node_modules/.pnpm/dsh-coding-oauth-core@0.1.2_@deepseek-ai+dsh-llm@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@_82bbdc1424db474a5d3f648945c0fadb/node_modules/dsh-coding-oauth-core/lib/proxy.js
|
|
25613
25613
|
var import_undici = __toESM(require_undici(), 1);
|
|
25614
25614
|
var DEFAULT_PROXIED_HOSTS = [
|
|
25615
25615
|
"auth.x.ai",
|
|
@@ -25744,7 +25744,7 @@ function grokBuildProxyInEffect() {
|
|
|
25744
25744
|
return codingOAuthProxyInEffect();
|
|
25745
25745
|
}
|
|
25746
25746
|
|
|
25747
|
-
// node_modules/.pnpm/dsh-coding-oauth-core@0.1.1/node_modules/dsh-coding-oauth-core/lib/route-registration.js
|
|
25747
|
+
// node_modules/.pnpm/dsh-coding-oauth-core@0.1.2_@deepseek-ai+dsh-llm@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@_82bbdc1424db474a5d3f648945c0fadb/node_modules/dsh-coding-oauth-core/lib/route-registration.js
|
|
25748
25748
|
function releaseRegistrationsSynchronously(disposers) {
|
|
25749
25749
|
for (const dispose of [...disposers].reverse()) {
|
|
25750
25750
|
try {
|
|
@@ -25780,7 +25780,7 @@ function setupAtomicallySynchronously(registry, setup) {
|
|
|
25780
25780
|
return onceSynchronously(disposers);
|
|
25781
25781
|
}
|
|
25782
25782
|
|
|
25783
|
-
// node_modules/.pnpm/dsh-coding-oauth-core@0.1.1/node_modules/dsh-coding-oauth-core/lib/ids.js
|
|
25783
|
+
// node_modules/.pnpm/dsh-coding-oauth-core@0.1.2_@deepseek-ai+dsh-llm@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@_82bbdc1424db474a5d3f648945c0fadb/node_modules/dsh-coding-oauth-core/lib/ids.js
|
|
25784
25784
|
var XAI_PI_PROVIDER = "xai";
|
|
25785
25785
|
var CODEX_PI_PROVIDER = "openai-codex";
|
|
25786
25786
|
var KIMI_PI_PROVIDER = "kimi-coding";
|
|
@@ -25808,7 +25808,7 @@ var CLAUDE_CODE_OAUTH_MODELS_CACHE_FILENAME = ".claude-code-oauth-models.json";
|
|
|
25808
25808
|
var DEFAULT_GROK_BUILD_MODEL = "grok-4.6";
|
|
25809
25809
|
var GROK_BUILD_STREAM_IDLE_TIMEOUT_MS = 3e5;
|
|
25810
25810
|
|
|
25811
|
-
// node_modules/.pnpm/dsh-coding-oauth-core@0.1.1/node_modules/dsh-coding-oauth-core/lib/state-contract.js
|
|
25811
|
+
// node_modules/.pnpm/dsh-coding-oauth-core@0.1.2_@deepseek-ai+dsh-llm@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@_82bbdc1424db474a5d3f648945c0fadb/node_modules/dsh-coding-oauth-core/lib/state-contract.js
|
|
25812
25812
|
var CAPABILITY_SETTINGS_NAMESPACE = "coding-subscription-oauth";
|
|
25813
25813
|
var GATEWAY_KEY_FILENAME = ".coding-oauth-gateway.json";
|
|
25814
25814
|
var IMAGINE_MEDIA_STORE_DIRNAME = ".dsh-coding-subscription-oauth-media";
|
|
@@ -25861,7 +25861,115 @@ var CODING_OAUTH_MANAGEMENT_PATHS = Object.freeze([
|
|
|
25861
25861
|
GATEWAY_ROTATE_PATH
|
|
25862
25862
|
]);
|
|
25863
25863
|
|
|
25864
|
-
// node_modules/.pnpm/dsh-coding-oauth-core@0.1.1/node_modules/dsh-coding-oauth-core/lib/
|
|
25864
|
+
// node_modules/.pnpm/dsh-coding-oauth-core@0.1.2_@deepseek-ai+dsh-llm@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@_82bbdc1424db474a5d3f648945c0fadb/node_modules/dsh-coding-oauth-core/lib/http-json.js
|
|
25865
|
+
var JSON_BODY_LIMIT_BYTES = 64 * 1024;
|
|
25866
|
+
var JsonRequestError = class extends Error {
|
|
25867
|
+
statusCode;
|
|
25868
|
+
constructor(statusCode, message) {
|
|
25869
|
+
super(message);
|
|
25870
|
+
this.name = "JsonRequestError";
|
|
25871
|
+
this.statusCode = statusCode;
|
|
25872
|
+
}
|
|
25873
|
+
};
|
|
25874
|
+
function declaredLength(request) {
|
|
25875
|
+
const value = request.headers["content-length"];
|
|
25876
|
+
if (typeof value !== "string" || !/^\d+$/u.test(value))
|
|
25877
|
+
return void 0;
|
|
25878
|
+
const length = Number(value);
|
|
25879
|
+
return Number.isSafeInteger(length) ? length : void 0;
|
|
25880
|
+
}
|
|
25881
|
+
function readJsonRequest(request, limit = JSON_BODY_LIMIT_BYTES) {
|
|
25882
|
+
const length = declaredLength(request);
|
|
25883
|
+
if (length !== void 0 && length > limit) {
|
|
25884
|
+
request.resume();
|
|
25885
|
+
return Promise.reject(new JsonRequestError(413, "request body is too large"));
|
|
25886
|
+
}
|
|
25887
|
+
return new Promise((resolve8, reject) => {
|
|
25888
|
+
const chunks = [];
|
|
25889
|
+
let size = 0;
|
|
25890
|
+
let settled = false;
|
|
25891
|
+
const cleanup = () => {
|
|
25892
|
+
request.removeListener("data", onData);
|
|
25893
|
+
request.removeListener("end", onEnd);
|
|
25894
|
+
request.removeListener("error", onError);
|
|
25895
|
+
request.removeListener("aborted", onAborted);
|
|
25896
|
+
};
|
|
25897
|
+
const fail = (error) => {
|
|
25898
|
+
if (settled)
|
|
25899
|
+
return;
|
|
25900
|
+
settled = true;
|
|
25901
|
+
cleanup();
|
|
25902
|
+
request.resume();
|
|
25903
|
+
reject(error);
|
|
25904
|
+
};
|
|
25905
|
+
const onData = (value) => {
|
|
25906
|
+
if (settled)
|
|
25907
|
+
return;
|
|
25908
|
+
const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value);
|
|
25909
|
+
size += chunk.byteLength;
|
|
25910
|
+
if (size > limit) {
|
|
25911
|
+
fail(new JsonRequestError(413, "request body is too large"));
|
|
25912
|
+
return;
|
|
25913
|
+
}
|
|
25914
|
+
chunks.push(chunk);
|
|
25915
|
+
};
|
|
25916
|
+
const onEnd = () => {
|
|
25917
|
+
if (settled)
|
|
25918
|
+
return;
|
|
25919
|
+
settled = true;
|
|
25920
|
+
cleanup();
|
|
25921
|
+
const text = Buffer.concat(chunks, size).toString("utf8").trim();
|
|
25922
|
+
if (text.length === 0) {
|
|
25923
|
+
resolve8({});
|
|
25924
|
+
return;
|
|
25925
|
+
}
|
|
25926
|
+
try {
|
|
25927
|
+
resolve8(JSON.parse(text));
|
|
25928
|
+
} catch {
|
|
25929
|
+
reject(new JsonRequestError(400, "request body must contain valid JSON"));
|
|
25930
|
+
}
|
|
25931
|
+
};
|
|
25932
|
+
const onError = () => fail(new JsonRequestError(400, "request body could not be read"));
|
|
25933
|
+
const onAborted = () => fail(new JsonRequestError(400, "request body was aborted"));
|
|
25934
|
+
request.on("data", onData);
|
|
25935
|
+
request.once("end", onEnd);
|
|
25936
|
+
request.once("error", onError);
|
|
25937
|
+
request.once("aborted", onAborted);
|
|
25938
|
+
});
|
|
25939
|
+
}
|
|
25940
|
+
function requestErrorStatus(error, fallback) {
|
|
25941
|
+
return error instanceof JsonRequestError ? error.statusCode : fallback;
|
|
25942
|
+
}
|
|
25943
|
+
|
|
25944
|
+
// node_modules/.pnpm/dsh-coding-oauth-core@0.1.2_@deepseek-ai+dsh-llm@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@_82bbdc1424db474a5d3f648945c0fadb/node_modules/dsh-coding-oauth-core/lib/grok-errors.js
|
|
25945
|
+
var XAI_CAPACITY = /\b(?:at\s+capacity|high\s+demand|priority\s+processing|overloaded)\b/i;
|
|
25946
|
+
function isXaiCapacityError(detail) {
|
|
25947
|
+
return XAI_CAPACITY.test(detail);
|
|
25948
|
+
}
|
|
25949
|
+
function remapXaiCapacityFailure(failure) {
|
|
25950
|
+
if (!isXaiCapacityError(failure.message))
|
|
25951
|
+
return failure;
|
|
25952
|
+
return { ...failure, code: "RATE_LIMIT" };
|
|
25953
|
+
}
|
|
25954
|
+
|
|
25955
|
+
// node_modules/.pnpm/dsh-coding-oauth-core@0.1.2_@deepseek-ai+dsh-llm@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@_82bbdc1424db474a5d3f648945c0fadb/node_modules/dsh-coding-oauth-core/lib/kimi-errors.js
|
|
25956
|
+
import { CONTEXT_WINDOW_EXCEEDED_CODE, isContextWindowExceededError } from "@deepseek-ai/dsh-llm";
|
|
25957
|
+
var KIMI_CONTEXT_CAPACITY = /\bsupports only\s+\d+\s*k\s+context\b/i;
|
|
25958
|
+
function isMisclassifiedContextWindowError(detail) {
|
|
25959
|
+
return isContextWindowExceededError(detail) || KIMI_CONTEXT_CAPACITY.test(detail);
|
|
25960
|
+
}
|
|
25961
|
+
function remapAuthFailureIfContextOverflow(failure) {
|
|
25962
|
+
if (failure.code !== "AUTH" || !isMisclassifiedContextWindowError(failure.message))
|
|
25963
|
+
return failure;
|
|
25964
|
+
return { ...failure, code: CONTEXT_WINDOW_EXCEEDED_CODE };
|
|
25965
|
+
}
|
|
25966
|
+
|
|
25967
|
+
// node_modules/.pnpm/dsh-coding-oauth-core@0.1.2_@deepseek-ai+dsh-llm@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@_82bbdc1424db474a5d3f648945c0fadb/node_modules/dsh-coding-oauth-core/lib/gateway-protocol.js
|
|
25968
|
+
function isThinkingLevel(value) {
|
|
25969
|
+
return value === "off" || value === "minimal" || value === "low" || value === "medium" || value === "high" || value === "xhigh" || value === "max";
|
|
25970
|
+
}
|
|
25971
|
+
|
|
25972
|
+
// node_modules/.pnpm/dsh-coding-oauth-core@0.1.2_@deepseek-ai+dsh-llm@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@_82bbdc1424db474a5d3f648945c0fadb/node_modules/dsh-coding-oauth-core/lib/index.js
|
|
25865
25973
|
var CODING_OAUTH_CORE_ABI = "dsh-coding-oauth-core/v1";
|
|
25866
25974
|
var STORE_SYMBOL = /* @__PURE__ */ Symbol.for("dsh.coding-oauth-core.runtime-store");
|
|
25867
25975
|
function resolveCodingOAuthScope(context) {
|
|
@@ -26068,29 +26176,6 @@ import { PiAiAdapter } from "@deepseek-ai/dsh-llm-pi-ai";
|
|
|
26068
26176
|
|
|
26069
26177
|
// src/alias-adapter.ts
|
|
26070
26178
|
import { LlmAdapter, LlmError } from "@deepseek-ai/dsh-llm";
|
|
26071
|
-
|
|
26072
|
-
// src/runtime/grok-errors.ts
|
|
26073
|
-
var XAI_CAPACITY = /\b(?:at\s+capacity|high\s+demand|priority\s+processing|overloaded)\b/i;
|
|
26074
|
-
function isXaiCapacityError(detail) {
|
|
26075
|
-
return XAI_CAPACITY.test(detail);
|
|
26076
|
-
}
|
|
26077
|
-
function remapXaiCapacityFailure(failure) {
|
|
26078
|
-
if (!isXaiCapacityError(failure.message)) return failure;
|
|
26079
|
-
return { ...failure, code: "RATE_LIMIT" };
|
|
26080
|
-
}
|
|
26081
|
-
|
|
26082
|
-
// src/runtime/kimi-errors.ts
|
|
26083
|
-
import { CONTEXT_WINDOW_EXCEEDED_CODE, isContextWindowExceededError } from "@deepseek-ai/dsh-llm";
|
|
26084
|
-
var KIMI_CONTEXT_CAPACITY = /\bsupports only\s+\d+\s*k\s+context\b/i;
|
|
26085
|
-
function isMisclassifiedContextWindowError(detail) {
|
|
26086
|
-
return isContextWindowExceededError(detail) || KIMI_CONTEXT_CAPACITY.test(detail);
|
|
26087
|
-
}
|
|
26088
|
-
function remapAuthFailureIfContextOverflow(failure) {
|
|
26089
|
-
if (failure.code !== "AUTH" || !isMisclassifiedContextWindowError(failure.message)) return failure;
|
|
26090
|
-
return { ...failure, code: CONTEXT_WINDOW_EXCEEDED_CODE };
|
|
26091
|
-
}
|
|
26092
|
-
|
|
26093
|
-
// src/alias-adapter.ts
|
|
26094
26179
|
function normalizeReplayForRoute(message, route2, nativeReplayProvider) {
|
|
26095
26180
|
if (message.role !== "assistant" || message.source.kind !== "model") return message;
|
|
26096
26181
|
if (message.source.provider !== route2) {
|
|
@@ -26174,6 +26259,11 @@ var AliasLlmAdapter = class extends LlmAdapter {
|
|
|
26174
26259
|
}
|
|
26175
26260
|
};
|
|
26176
26261
|
|
|
26262
|
+
// src/ids.ts
|
|
26263
|
+
var CODING_OAUTH_API_BASE = "/plugins/dsh-grok-build";
|
|
26264
|
+
var CODING_OAUTH_ACCOUNTS_SET_ACTIVE_PATH = `${CODING_OAUTH_API_BASE}/oauth/accounts/set-active`;
|
|
26265
|
+
var CODING_OAUTH_ACCOUNTS_REMOVE_PATH = `${CODING_OAUTH_API_BASE}/oauth/accounts/remove`;
|
|
26266
|
+
|
|
26177
26267
|
// src/provider.ts
|
|
26178
26268
|
import { createProvider } from "@earendil-works/pi-ai";
|
|
26179
26269
|
import { openAIResponsesApi } from "@earendil-works/pi-ai/api/openai-responses.lazy";
|
|
@@ -27040,6 +27130,8 @@ function profile(provider, displayName, piProvider, retryPolicy, headers) {
|
|
|
27040
27130
|
"dsh-coding-subscription-oauth retryPolicy"
|
|
27041
27131
|
),
|
|
27042
27132
|
configuredMaxTokens: /* @__PURE__ */ new Map(),
|
|
27133
|
+
// Host dsh-llm-pi-ai 0.1.5+ calls modelErrors.get during resolveModel (#38).
|
|
27134
|
+
modelErrors: /* @__PURE__ */ new Map(),
|
|
27043
27135
|
...REQUEST_IMAGE_POLICY,
|
|
27044
27136
|
...headers === void 0 ? {} : { headers },
|
|
27045
27137
|
piProvider
|
|
@@ -27304,6 +27396,7 @@ async function importGrokAuth(store, filename = grokAuthPath()) {
|
|
|
27304
27396
|
}
|
|
27305
27397
|
|
|
27306
27398
|
// src/store.ts
|
|
27399
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
27307
27400
|
import { mkdir, rm } from "node:fs/promises";
|
|
27308
27401
|
import { dirname, join as join3, resolve as resolve3 } from "node:path";
|
|
27309
27402
|
import { withFileLock, writeFileAtomic } from "@deepseek-ai/dsh-atomic-write";
|
|
@@ -28061,25 +28154,17 @@ function nonEmptyString2(value) {
|
|
|
28061
28154
|
}
|
|
28062
28155
|
|
|
28063
28156
|
// src/store.ts
|
|
28064
|
-
var AUTH_FORMAT_VERSION =
|
|
28065
|
-
|
|
28066
|
-
|
|
28067
|
-
|
|
28068
|
-
|
|
28069
|
-
|
|
28070
|
-
|
|
28071
|
-
|
|
28072
|
-
|
|
28073
|
-
|
|
28074
|
-
|
|
28075
|
-
const document = value;
|
|
28076
|
-
if (document["version"] !== AUTH_FORMAT_VERSION) {
|
|
28077
|
-
throw new Error(`${label}: ${filename} has unsupported auth format version ${String(document["version"])}`);
|
|
28078
|
-
}
|
|
28079
|
-
if (Object.keys(document).some((key) => key !== "version" && key !== "credential")) {
|
|
28080
|
-
throw new Error(`${label}: ${filename} contains an unknown top-level field`);
|
|
28081
|
-
}
|
|
28082
|
-
const raw = document["credential"];
|
|
28157
|
+
var AUTH_FORMAT_VERSION = 2;
|
|
28158
|
+
var AUTH_FORMAT_VERSION_V1 = 1;
|
|
28159
|
+
var OAUTH_MAX_ACCOUNTS = 8;
|
|
28160
|
+
var MAX_ACCOUNTS = OAUTH_MAX_ACCOUNTS;
|
|
28161
|
+
var LEGACY_ACCOUNT_ID = "legacy";
|
|
28162
|
+
var ACCOUNT_ID_PATTERN = /^[A-Za-z0-9._:@+-]+$/u;
|
|
28163
|
+
var UNCHANGED = /* @__PURE__ */ Symbol("unchanged");
|
|
28164
|
+
function isValidAccountId(value) {
|
|
28165
|
+
return typeof value === "string" && value.length > 0 && value.length <= 128 && ACCOUNT_ID_PATTERN.test(value);
|
|
28166
|
+
}
|
|
28167
|
+
function parseOAuthCredential(raw, filename, label) {
|
|
28083
28168
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
28084
28169
|
throw new Error(`${label}: ${filename} credential must be an object`);
|
|
28085
28170
|
}
|
|
@@ -28088,23 +28173,178 @@ function parseDocument(text, filename, label) {
|
|
|
28088
28173
|
if (Object.keys(credential).some((key) => !allowed.has(key))) {
|
|
28089
28174
|
throw new Error(`${label}: ${filename} credential contains an unknown field`);
|
|
28090
28175
|
}
|
|
28091
|
-
if (credential
|
|
28176
|
+
if (credential.type !== "oauth") throw new Error(`${label}: ${filename} credential type must be oauth`);
|
|
28092
28177
|
for (const key of ["access", "refresh"]) {
|
|
28093
28178
|
if (typeof credential[key] !== "string" || credential[key].length === 0) {
|
|
28094
28179
|
throw new Error(`${label}: ${filename} credential ${key} must be a non-empty string`);
|
|
28095
28180
|
}
|
|
28096
28181
|
}
|
|
28097
|
-
if (credential
|
|
28182
|
+
if (credential.accountId !== void 0 && (typeof credential.accountId !== "string" || credential.accountId.length === 0)) {
|
|
28098
28183
|
throw new Error(`${label}: ${filename} credential accountId must be a non-empty string when present`);
|
|
28099
28184
|
}
|
|
28100
|
-
if (typeof credential
|
|
28185
|
+
if (typeof credential.expires !== "number" || !Number.isFinite(credential.expires) || credential.expires <= 0) {
|
|
28101
28186
|
throw new Error(`${label}: ${filename} credential expires must be a positive finite number`);
|
|
28102
28187
|
}
|
|
28103
|
-
return
|
|
28188
|
+
return credential;
|
|
28189
|
+
}
|
|
28190
|
+
function parseAccountRecord(raw, filename, label, index) {
|
|
28191
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
28192
|
+
throw new Error(`${label}: ${filename} accounts[${String(index)}] must be an object`);
|
|
28193
|
+
}
|
|
28194
|
+
const record2 = raw;
|
|
28195
|
+
const allowed = /* @__PURE__ */ new Set(["id", "label", "credential", "createdAt"]);
|
|
28196
|
+
if (Object.keys(record2).some((key) => !allowed.has(key))) {
|
|
28197
|
+
throw new Error(`${label}: ${filename} accounts[${String(index)}] contains an unknown field`);
|
|
28198
|
+
}
|
|
28199
|
+
if (!isValidAccountId(record2.id)) {
|
|
28200
|
+
throw new Error(`${label}: ${filename} accounts[${String(index)}].id is not a valid account id`);
|
|
28201
|
+
}
|
|
28202
|
+
if (record2.label !== void 0 && (typeof record2.label !== "string" || record2.label.length === 0)) {
|
|
28203
|
+
throw new Error(`${label}: ${filename} accounts[${String(index)}].label must be a non-empty string when present`);
|
|
28204
|
+
}
|
|
28205
|
+
if (typeof record2.createdAt !== "number" || !Number.isFinite(record2.createdAt) || record2.createdAt <= 0) {
|
|
28206
|
+
throw new Error(`${label}: ${filename} accounts[${String(index)}].createdAt must be a positive finite number`);
|
|
28207
|
+
}
|
|
28208
|
+
const credential = parseOAuthCredential(record2.credential, filename, label);
|
|
28209
|
+
return {
|
|
28210
|
+
id: record2.id,
|
|
28211
|
+
...record2.label === void 0 ? {} : { label: record2.label },
|
|
28212
|
+
credential,
|
|
28213
|
+
createdAt: record2.createdAt
|
|
28214
|
+
};
|
|
28215
|
+
}
|
|
28216
|
+
function parseDocumentV2(document, filename, label) {
|
|
28217
|
+
if (Object.keys(document).some((key) => key !== "version" && key !== "activeAccountId" && key !== "accounts")) {
|
|
28218
|
+
throw new Error(`${label}: ${filename} contains an unknown top-level field`);
|
|
28219
|
+
}
|
|
28220
|
+
if (!isValidAccountId(document.activeAccountId)) {
|
|
28221
|
+
throw new Error(`${label}: ${filename} activeAccountId is not a valid account id`);
|
|
28222
|
+
}
|
|
28223
|
+
if (!Array.isArray(document.accounts)) {
|
|
28224
|
+
throw new Error(`${label}: ${filename} accounts must be an array`);
|
|
28225
|
+
}
|
|
28226
|
+
if (document.accounts.length < 1 || document.accounts.length > MAX_ACCOUNTS) {
|
|
28227
|
+
throw new Error(`${label}: ${filename} accounts must contain between 1 and ${String(MAX_ACCOUNTS)} entries`);
|
|
28228
|
+
}
|
|
28229
|
+
const accounts = document.accounts.map((entry, index) => parseAccountRecord(entry, filename, label, index));
|
|
28230
|
+
const ids = /* @__PURE__ */ new Set();
|
|
28231
|
+
for (const account of accounts) {
|
|
28232
|
+
if (ids.has(account.id)) {
|
|
28233
|
+
throw new Error(`${label}: ${filename} accounts contains a duplicate id`);
|
|
28234
|
+
}
|
|
28235
|
+
ids.add(account.id);
|
|
28236
|
+
}
|
|
28237
|
+
if (!ids.has(document.activeAccountId)) {
|
|
28238
|
+
throw new Error(`${label}: ${filename} activeAccountId does not match any account`);
|
|
28239
|
+
}
|
|
28240
|
+
return {
|
|
28241
|
+
version: AUTH_FORMAT_VERSION,
|
|
28242
|
+
activeAccountId: document.activeAccountId,
|
|
28243
|
+
accounts
|
|
28244
|
+
};
|
|
28245
|
+
}
|
|
28246
|
+
function parseDocumentV1(document, filename, label) {
|
|
28247
|
+
if (Object.keys(document).some((key) => key !== "version" && key !== "credential")) {
|
|
28248
|
+
throw new Error(`${label}: ${filename} contains an unknown top-level field`);
|
|
28249
|
+
}
|
|
28250
|
+
return parseOAuthCredential(document.credential, filename, label);
|
|
28251
|
+
}
|
|
28252
|
+
function parseDocument(text, filename, label) {
|
|
28253
|
+
let value;
|
|
28254
|
+
try {
|
|
28255
|
+
value = JSON.parse(text);
|
|
28256
|
+
} catch {
|
|
28257
|
+
throw new Error(`${label}: ${filename} is not valid JSON`);
|
|
28258
|
+
}
|
|
28259
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
28260
|
+
throw new Error(`${label}: ${filename} must contain an object`);
|
|
28261
|
+
}
|
|
28262
|
+
const document = value;
|
|
28263
|
+
if (document.version === AUTH_FORMAT_VERSION_V1) {
|
|
28264
|
+
return { document: migrateV1Credential(parseDocumentV1(document, filename, label)), migratedFromV1: true };
|
|
28265
|
+
}
|
|
28266
|
+
if (document.version === AUTH_FORMAT_VERSION) {
|
|
28267
|
+
return { document: parseDocumentV2(document, filename, label), migratedFromV1: false };
|
|
28268
|
+
}
|
|
28269
|
+
throw new Error(`${label}: ${filename} has unsupported auth format version ${String(document.version)}`);
|
|
28270
|
+
}
|
|
28271
|
+
function migrateV1Credential(credential) {
|
|
28272
|
+
const accountIdField = credential.accountId;
|
|
28273
|
+
const id = isValidAccountId(accountIdField) ? accountIdField : LEGACY_ACCOUNT_ID;
|
|
28274
|
+
return {
|
|
28275
|
+
version: AUTH_FORMAT_VERSION,
|
|
28276
|
+
activeAccountId: id,
|
|
28277
|
+
accounts: [
|
|
28278
|
+
{
|
|
28279
|
+
id,
|
|
28280
|
+
credential: cloneCredential2(credential),
|
|
28281
|
+
createdAt: Date.now()
|
|
28282
|
+
}
|
|
28283
|
+
]
|
|
28284
|
+
};
|
|
28104
28285
|
}
|
|
28105
28286
|
function cloneCredential2(credential) {
|
|
28106
28287
|
return structuredClone(credential);
|
|
28107
28288
|
}
|
|
28289
|
+
function cloneDocument(document) {
|
|
28290
|
+
return structuredClone(document);
|
|
28291
|
+
}
|
|
28292
|
+
function activeCredential(document) {
|
|
28293
|
+
const active = document.accounts.find((account) => account.id === document.activeAccountId);
|
|
28294
|
+
if (active === void 0) {
|
|
28295
|
+
throw new Error("active account missing from document");
|
|
28296
|
+
}
|
|
28297
|
+
return cloneCredential2(active.credential);
|
|
28298
|
+
}
|
|
28299
|
+
function resolveAccountIdForCredential(credential) {
|
|
28300
|
+
const accountIdField = credential.accountId;
|
|
28301
|
+
if (isValidAccountId(accountIdField)) return accountIdField;
|
|
28302
|
+
return `acct-${randomBytes2(8).toString("hex")}`;
|
|
28303
|
+
}
|
|
28304
|
+
function documentFromCredential(credential) {
|
|
28305
|
+
const id = resolveAccountIdForCredential(credential);
|
|
28306
|
+
return {
|
|
28307
|
+
version: AUTH_FORMAT_VERSION,
|
|
28308
|
+
activeAccountId: id,
|
|
28309
|
+
accounts: [
|
|
28310
|
+
{
|
|
28311
|
+
id,
|
|
28312
|
+
credential: cloneCredential2(credential),
|
|
28313
|
+
createdAt: Date.now()
|
|
28314
|
+
}
|
|
28315
|
+
]
|
|
28316
|
+
};
|
|
28317
|
+
}
|
|
28318
|
+
function withUpdatedActiveCredential(document, credential) {
|
|
28319
|
+
const accounts = document.accounts.map(
|
|
28320
|
+
(account) => account.id === document.activeAccountId ? { ...account, credential: cloneCredential2(credential) } : cloneAccount(account)
|
|
28321
|
+
);
|
|
28322
|
+
return {
|
|
28323
|
+
version: AUTH_FORMAT_VERSION,
|
|
28324
|
+
activeAccountId: document.activeAccountId,
|
|
28325
|
+
accounts
|
|
28326
|
+
};
|
|
28327
|
+
}
|
|
28328
|
+
function cloneAccount(account) {
|
|
28329
|
+
return {
|
|
28330
|
+
id: account.id,
|
|
28331
|
+
...account.label === void 0 ? {} : { label: account.label },
|
|
28332
|
+
credential: cloneCredential2(account.credential),
|
|
28333
|
+
createdAt: account.createdAt
|
|
28334
|
+
};
|
|
28335
|
+
}
|
|
28336
|
+
function summarizeAccount(account) {
|
|
28337
|
+
const accountIdField = account.credential.accountId;
|
|
28338
|
+
return {
|
|
28339
|
+
id: account.id,
|
|
28340
|
+
...account.label === void 0 ? {} : { label: account.label },
|
|
28341
|
+
expires: account.credential.expires,
|
|
28342
|
+
...typeof accountIdField === "string" && accountIdField.length > 0 ? { accountId: accountIdField } : {}
|
|
28343
|
+
};
|
|
28344
|
+
}
|
|
28345
|
+
function validatedDocument(document, filename, label) {
|
|
28346
|
+
return parseDocument(JSON.stringify(document), filename, label).document;
|
|
28347
|
+
}
|
|
28108
28348
|
function oauthCredentialPath(basename, dshHome) {
|
|
28109
28349
|
if (basename.length === 0 || basename.length > 128 || basename === "." || basename === ".." || !/^\.?[A-Za-z0-9][A-Za-z0-9._-]*$/u.test(basename)) {
|
|
28110
28350
|
throw new TypeError("OAuth credential basename must be a safe local filename");
|
|
@@ -28123,6 +28363,7 @@ var OAuthCredentialFileStore = class {
|
|
|
28123
28363
|
providerId;
|
|
28124
28364
|
label;
|
|
28125
28365
|
filename;
|
|
28366
|
+
loginPersist;
|
|
28126
28367
|
async readCurrent() {
|
|
28127
28368
|
return this.loadCurrent({ allowUnreadable: false });
|
|
28128
28369
|
}
|
|
@@ -28132,6 +28373,10 @@ var OAuthCredentialFileStore = class {
|
|
|
28132
28373
|
* Unsafe/symlink/wrong-owner/too-large files still throw.
|
|
28133
28374
|
*/
|
|
28134
28375
|
async loadCurrent(options) {
|
|
28376
|
+
const loaded = await this.loadDocument({ allowUnreadable: options.allowUnreadable, persistMigration: false });
|
|
28377
|
+
return loaded === void 0 ? void 0 : activeCredential(loaded.document);
|
|
28378
|
+
}
|
|
28379
|
+
async loadDocument(options) {
|
|
28135
28380
|
let text;
|
|
28136
28381
|
try {
|
|
28137
28382
|
text = (await readHardenedOAuthSourceFile(this.filename)).text;
|
|
@@ -28143,7 +28388,11 @@ var OAuthCredentialFileStore = class {
|
|
|
28143
28388
|
throw error;
|
|
28144
28389
|
}
|
|
28145
28390
|
try {
|
|
28146
|
-
|
|
28391
|
+
const parsed = parseDocument(text, this.filename, this.label);
|
|
28392
|
+
if (options.persistMigration && parsed.migratedFromV1) {
|
|
28393
|
+
await this.writeDocument(parsed.document);
|
|
28394
|
+
}
|
|
28395
|
+
return parsed;
|
|
28147
28396
|
} catch (error) {
|
|
28148
28397
|
if (options.allowUnreadable) return void 0;
|
|
28149
28398
|
throw error;
|
|
@@ -28161,6 +28410,91 @@ var OAuthCredentialFileStore = class {
|
|
|
28161
28410
|
throw error;
|
|
28162
28411
|
}
|
|
28163
28412
|
}
|
|
28413
|
+
async writeDocument(document) {
|
|
28414
|
+
const validated = validatedDocument(document, this.filename, this.label);
|
|
28415
|
+
await this.assertDestinationReplaceable();
|
|
28416
|
+
await writeFileAtomic(this.filename, `${JSON.stringify(validated, null, 2)}
|
|
28417
|
+
`, {
|
|
28418
|
+
mode: 384,
|
|
28419
|
+
dirMode: 448
|
|
28420
|
+
});
|
|
28421
|
+
return cloneDocument(validated);
|
|
28422
|
+
}
|
|
28423
|
+
nextDocumentAfterLogin(current, credential, options) {
|
|
28424
|
+
const parsed = parseOAuthCredential(credential, this.filename, this.label);
|
|
28425
|
+
if (options.mode === "overwrite-active") {
|
|
28426
|
+
if (current === void 0) return documentFromCredential(parsed);
|
|
28427
|
+
if (options.confirmOverwrite !== true) {
|
|
28428
|
+
throw new Error(`${this.label}: confirmOverwrite is required to replace the active account`);
|
|
28429
|
+
}
|
|
28430
|
+
return withUpdatedActiveCredential(current, parsed);
|
|
28431
|
+
}
|
|
28432
|
+
const id = resolveAccountIdForCredential(parsed);
|
|
28433
|
+
if (current === void 0) {
|
|
28434
|
+
return {
|
|
28435
|
+
version: AUTH_FORMAT_VERSION,
|
|
28436
|
+
activeAccountId: id,
|
|
28437
|
+
accounts: [
|
|
28438
|
+
{
|
|
28439
|
+
id,
|
|
28440
|
+
credential: cloneCredential2(parsed),
|
|
28441
|
+
createdAt: Date.now()
|
|
28442
|
+
}
|
|
28443
|
+
]
|
|
28444
|
+
};
|
|
28445
|
+
}
|
|
28446
|
+
const existingIndex = current.accounts.findIndex((account) => account.id === id);
|
|
28447
|
+
if (existingIndex < 0 && current.accounts.length >= MAX_ACCOUNTS) {
|
|
28448
|
+
throw new Error(`${this.label}: at most ${String(MAX_ACCOUNTS)} accounts may be stored`);
|
|
28449
|
+
}
|
|
28450
|
+
const accounts = current.accounts.map(cloneAccount);
|
|
28451
|
+
if (existingIndex >= 0) {
|
|
28452
|
+
const existing = accounts[existingIndex];
|
|
28453
|
+
if (existing === void 0) {
|
|
28454
|
+
throw new Error(`${this.label}: account "${id}" is not stored`);
|
|
28455
|
+
}
|
|
28456
|
+
accounts[existingIndex] = {
|
|
28457
|
+
id,
|
|
28458
|
+
...existing.label === void 0 ? {} : { label: existing.label },
|
|
28459
|
+
credential: cloneCredential2(parsed),
|
|
28460
|
+
createdAt: existing.createdAt
|
|
28461
|
+
};
|
|
28462
|
+
} else {
|
|
28463
|
+
accounts.push({
|
|
28464
|
+
id,
|
|
28465
|
+
credential: cloneCredential2(parsed),
|
|
28466
|
+
createdAt: Date.now()
|
|
28467
|
+
});
|
|
28468
|
+
}
|
|
28469
|
+
return {
|
|
28470
|
+
version: AUTH_FORMAT_VERSION,
|
|
28471
|
+
activeAccountId: id,
|
|
28472
|
+
accounts
|
|
28473
|
+
};
|
|
28474
|
+
}
|
|
28475
|
+
async mutateDocument(options, fn) {
|
|
28476
|
+
await mkdir(dirname(this.filename), { recursive: true, mode: 448 });
|
|
28477
|
+
return withFileLock(this.filename, async () => {
|
|
28478
|
+
const loaded = await this.loadDocument({
|
|
28479
|
+
allowUnreadable: options.allowUnreadable,
|
|
28480
|
+
persistMigration: false
|
|
28481
|
+
});
|
|
28482
|
+
const current = loaded === void 0 ? void 0 : loaded.document;
|
|
28483
|
+
const migratedFromV1 = loaded?.migratedFromV1 === true;
|
|
28484
|
+
const next = await fn(current === void 0 ? void 0 : cloneDocument(current));
|
|
28485
|
+
if (next === UNCHANGED) {
|
|
28486
|
+
if (migratedFromV1 && current !== void 0) {
|
|
28487
|
+
return this.writeDocument(current);
|
|
28488
|
+
}
|
|
28489
|
+
return current === void 0 ? void 0 : cloneDocument(current);
|
|
28490
|
+
}
|
|
28491
|
+
if (next === void 0) {
|
|
28492
|
+
await rm(this.filename, { force: true });
|
|
28493
|
+
return void 0;
|
|
28494
|
+
}
|
|
28495
|
+
return this.writeDocument(next);
|
|
28496
|
+
});
|
|
28497
|
+
}
|
|
28164
28498
|
async read(providerId) {
|
|
28165
28499
|
return providerId === this.providerId ? this.readCurrent() : void 0;
|
|
28166
28500
|
}
|
|
@@ -28171,27 +28505,42 @@ var OAuthCredentialFileStore = class {
|
|
|
28171
28505
|
if (providerId !== this.providerId) {
|
|
28172
28506
|
throw new Error(`${this.label}: credential store does not own provider "${providerId}"`);
|
|
28173
28507
|
}
|
|
28174
|
-
await
|
|
28175
|
-
|
|
28176
|
-
const
|
|
28177
|
-
|
|
28178
|
-
if (candidate
|
|
28179
|
-
|
|
28180
|
-
|
|
28181
|
-
|
|
28182
|
-
|
|
28183
|
-
|
|
28184
|
-
|
|
28185
|
-
|
|
28186
|
-
);
|
|
28187
|
-
await this.assertDestinationReplaceable();
|
|
28188
|
-
await writeFileAtomic(this.filename, `${JSON.stringify(document, null, 2)}
|
|
28189
|
-
`, {
|
|
28190
|
-
mode: 384,
|
|
28191
|
-
dirMode: 448
|
|
28192
|
-
});
|
|
28193
|
-
return cloneCredential2(document.credential);
|
|
28508
|
+
const document = await this.mutateDocument({ allowUnreadable: true }, async (current) => {
|
|
28509
|
+
const active = current === void 0 ? void 0 : activeCredential(current);
|
|
28510
|
+
const candidate = await fn(active);
|
|
28511
|
+
if (candidate === void 0) return UNCHANGED;
|
|
28512
|
+
if (candidate.type !== "oauth") {
|
|
28513
|
+
throw new Error(`${this.label}: ${this.filename} credential type must be oauth`);
|
|
28514
|
+
}
|
|
28515
|
+
if (this.loginPersist !== void 0) {
|
|
28516
|
+
return this.nextDocumentAfterLogin(current, candidate, this.loginPersist);
|
|
28517
|
+
}
|
|
28518
|
+
if (current === void 0) return documentFromCredential(candidate);
|
|
28519
|
+
return withUpdatedActiveCredential(current, candidate);
|
|
28194
28520
|
});
|
|
28521
|
+
return document === void 0 ? void 0 : activeCredential(document);
|
|
28522
|
+
}
|
|
28523
|
+
/**
|
|
28524
|
+
* Redirect `modify` writes (pi-ai `models.login`) through multi-account upsert
|
|
28525
|
+
* semantics for the duration of `fn`.
|
|
28526
|
+
*/
|
|
28527
|
+
async runLoginPersist(options, fn) {
|
|
28528
|
+
if (this.loginPersist !== void 0) {
|
|
28529
|
+
throw new Error(`${this.label}: login persist already in progress`);
|
|
28530
|
+
}
|
|
28531
|
+
this.loginPersist = options;
|
|
28532
|
+
try {
|
|
28533
|
+
return await fn();
|
|
28534
|
+
} finally {
|
|
28535
|
+
this.loginPersist = void 0;
|
|
28536
|
+
}
|
|
28537
|
+
}
|
|
28538
|
+
/** Persist a login/import credential without going through pi-ai `modify`. */
|
|
28539
|
+
async persistLoginCredential(credential, options) {
|
|
28540
|
+
await this.mutateDocument(
|
|
28541
|
+
{ allowUnreadable: true },
|
|
28542
|
+
async (current) => this.nextDocumentAfterLogin(current, credential, options)
|
|
28543
|
+
);
|
|
28195
28544
|
}
|
|
28196
28545
|
/**
|
|
28197
28546
|
* Force the next `getAuth()` to refresh by backdating `expires` into the past.
|
|
@@ -28216,6 +28565,163 @@ var OAuthCredentialFileStore = class {
|
|
|
28216
28565
|
await mkdir(dirname(this.filename), { recursive: true, mode: 448 });
|
|
28217
28566
|
await withFileLock(this.filename, () => rm(this.filename, { force: true }));
|
|
28218
28567
|
}
|
|
28568
|
+
/** Read-only account list for Settings / API. Never includes tokens. */
|
|
28569
|
+
async listAccounts() {
|
|
28570
|
+
const document = await this.mutateDocument({ allowUnreadable: false }, async (current) => {
|
|
28571
|
+
if (current === void 0) return UNCHANGED;
|
|
28572
|
+
return UNCHANGED;
|
|
28573
|
+
});
|
|
28574
|
+
if (document === void 0) return [];
|
|
28575
|
+
return document.accounts.map(summarizeAccount);
|
|
28576
|
+
}
|
|
28577
|
+
async getActiveAccountId() {
|
|
28578
|
+
const document = await this.mutateDocument({ allowUnreadable: false }, async (current) => {
|
|
28579
|
+
if (current === void 0) return UNCHANGED;
|
|
28580
|
+
return UNCHANGED;
|
|
28581
|
+
});
|
|
28582
|
+
return document?.activeAccountId;
|
|
28583
|
+
}
|
|
28584
|
+
/**
|
|
28585
|
+
* Read one account's credential without changing activeAccountId.
|
|
28586
|
+
* Used by the optional quota-aware pool proxy for sticky per-request routing.
|
|
28587
|
+
*/
|
|
28588
|
+
async readAccount(id) {
|
|
28589
|
+
if (!isValidAccountId(id)) return void 0;
|
|
28590
|
+
const document = await this.mutateDocument({ allowUnreadable: false }, async (current) => {
|
|
28591
|
+
if (current === void 0) return UNCHANGED;
|
|
28592
|
+
return UNCHANGED;
|
|
28593
|
+
});
|
|
28594
|
+
const account = document?.accounts.find((entry) => entry.id === id);
|
|
28595
|
+
return account === void 0 ? void 0 : cloneCredential2(account.credential);
|
|
28596
|
+
}
|
|
28597
|
+
/**
|
|
28598
|
+
* Serialized refresh/write for one account id. Does not move activeAccountId.
|
|
28599
|
+
* Returns undefined when the account is absent (caller treats as missing credential).
|
|
28600
|
+
*/
|
|
28601
|
+
async modifyAccount(id, fn) {
|
|
28602
|
+
if (!isValidAccountId(id)) {
|
|
28603
|
+
throw new TypeError(`${this.label}: account id is invalid`);
|
|
28604
|
+
}
|
|
28605
|
+
const document = await this.mutateDocument({ allowUnreadable: true }, async (current) => {
|
|
28606
|
+
if (current === void 0) return UNCHANGED;
|
|
28607
|
+
const index = current.accounts.findIndex((account2) => account2.id === id);
|
|
28608
|
+
if (index < 0) return UNCHANGED;
|
|
28609
|
+
const existing = current.accounts[index];
|
|
28610
|
+
if (existing === void 0) return UNCHANGED;
|
|
28611
|
+
const candidate = await fn(cloneCredential2(existing.credential));
|
|
28612
|
+
if (candidate === void 0) return UNCHANGED;
|
|
28613
|
+
if (candidate.type !== "oauth") {
|
|
28614
|
+
throw new Error(`${this.label}: ${this.filename} credential type must be oauth`);
|
|
28615
|
+
}
|
|
28616
|
+
const accounts = current.accounts.map(cloneAccount);
|
|
28617
|
+
const target = accounts[index];
|
|
28618
|
+
if (target === void 0) return UNCHANGED;
|
|
28619
|
+
accounts[index] = {
|
|
28620
|
+
...target,
|
|
28621
|
+
credential: cloneCredential2(candidate)
|
|
28622
|
+
};
|
|
28623
|
+
return {
|
|
28624
|
+
version: AUTH_FORMAT_VERSION,
|
|
28625
|
+
activeAccountId: current.activeAccountId,
|
|
28626
|
+
accounts
|
|
28627
|
+
};
|
|
28628
|
+
});
|
|
28629
|
+
if (document === void 0) return void 0;
|
|
28630
|
+
const account = document.accounts.find((entry) => entry.id === id);
|
|
28631
|
+
return account === void 0 ? void 0 : cloneCredential2(account.credential);
|
|
28632
|
+
}
|
|
28633
|
+
async setActiveAccount(id) {
|
|
28634
|
+
if (!isValidAccountId(id)) {
|
|
28635
|
+
throw new TypeError(`${this.label}: account id is invalid`);
|
|
28636
|
+
}
|
|
28637
|
+
await this.mutateDocument({ allowUnreadable: false }, async (current) => {
|
|
28638
|
+
if (current === void 0) {
|
|
28639
|
+
throw new Error(`${this.label}: no credential accounts are stored`);
|
|
28640
|
+
}
|
|
28641
|
+
if (!current.accounts.some((account) => account.id === id)) {
|
|
28642
|
+
throw new Error(`${this.label}: account "${id}" is not stored`);
|
|
28643
|
+
}
|
|
28644
|
+
if (current.activeAccountId === id) return UNCHANGED;
|
|
28645
|
+
return {
|
|
28646
|
+
version: AUTH_FORMAT_VERSION,
|
|
28647
|
+
activeAccountId: id,
|
|
28648
|
+
accounts: current.accounts.map(cloneAccount)
|
|
28649
|
+
};
|
|
28650
|
+
});
|
|
28651
|
+
}
|
|
28652
|
+
async upsertAccount(input) {
|
|
28653
|
+
if (!isValidAccountId(input.id)) {
|
|
28654
|
+
throw new TypeError(`${this.label}: account id is invalid`);
|
|
28655
|
+
}
|
|
28656
|
+
if (input.label !== void 0 && (typeof input.label !== "string" || input.label.length === 0)) {
|
|
28657
|
+
throw new TypeError(`${this.label}: account label must be a non-empty string when present`);
|
|
28658
|
+
}
|
|
28659
|
+
const credential = parseOAuthCredential(input.credential, this.filename, this.label);
|
|
28660
|
+
await this.mutateDocument({ allowUnreadable: false }, async (current) => {
|
|
28661
|
+
if (current === void 0) {
|
|
28662
|
+
return {
|
|
28663
|
+
version: AUTH_FORMAT_VERSION,
|
|
28664
|
+
activeAccountId: input.id,
|
|
28665
|
+
accounts: [
|
|
28666
|
+
{
|
|
28667
|
+
id: input.id,
|
|
28668
|
+
...input.label === void 0 ? {} : { label: input.label },
|
|
28669
|
+
credential: cloneCredential2(credential),
|
|
28670
|
+
createdAt: Date.now()
|
|
28671
|
+
}
|
|
28672
|
+
]
|
|
28673
|
+
};
|
|
28674
|
+
}
|
|
28675
|
+
const existingIndex = current.accounts.findIndex((account) => account.id === input.id);
|
|
28676
|
+
if (existingIndex < 0 && current.accounts.length >= MAX_ACCOUNTS) {
|
|
28677
|
+
throw new Error(`${this.label}: at most ${String(MAX_ACCOUNTS)} accounts may be stored`);
|
|
28678
|
+
}
|
|
28679
|
+
const accounts = current.accounts.map(cloneAccount);
|
|
28680
|
+
if (existingIndex >= 0) {
|
|
28681
|
+
const existing = accounts[existingIndex];
|
|
28682
|
+
if (existing === void 0) {
|
|
28683
|
+
throw new Error(`${this.label}: account "${input.id}" is not stored`);
|
|
28684
|
+
}
|
|
28685
|
+
accounts[existingIndex] = {
|
|
28686
|
+
id: input.id,
|
|
28687
|
+
...input.label !== void 0 ? { label: input.label } : existing.label === void 0 ? {} : { label: existing.label },
|
|
28688
|
+
credential: cloneCredential2(credential),
|
|
28689
|
+
createdAt: existing.createdAt
|
|
28690
|
+
};
|
|
28691
|
+
} else {
|
|
28692
|
+
accounts.push({
|
|
28693
|
+
id: input.id,
|
|
28694
|
+
...input.label === void 0 ? {} : { label: input.label },
|
|
28695
|
+
credential: cloneCredential2(credential),
|
|
28696
|
+
createdAt: Date.now()
|
|
28697
|
+
});
|
|
28698
|
+
}
|
|
28699
|
+
return {
|
|
28700
|
+
version: AUTH_FORMAT_VERSION,
|
|
28701
|
+
activeAccountId: input.makeActive === true ? input.id : current.activeAccountId,
|
|
28702
|
+
accounts
|
|
28703
|
+
};
|
|
28704
|
+
});
|
|
28705
|
+
}
|
|
28706
|
+
async removeAccount(id) {
|
|
28707
|
+
if (!isValidAccountId(id)) {
|
|
28708
|
+
throw new TypeError(`${this.label}: account id is invalid`);
|
|
28709
|
+
}
|
|
28710
|
+
await this.mutateDocument({ allowUnreadable: false }, async (current) => {
|
|
28711
|
+
if (current === void 0) return UNCHANGED;
|
|
28712
|
+
const accounts = current.accounts.filter((account) => account.id !== id).map(cloneAccount);
|
|
28713
|
+
if (accounts.length === current.accounts.length) return UNCHANGED;
|
|
28714
|
+
if (accounts.length === 0) return void 0;
|
|
28715
|
+
const fallback = accounts[0];
|
|
28716
|
+
if (fallback === void 0) return void 0;
|
|
28717
|
+
const activeAccountId = current.activeAccountId === id ? fallback.id : current.activeAccountId;
|
|
28718
|
+
return {
|
|
28719
|
+
version: AUTH_FORMAT_VERSION,
|
|
28720
|
+
activeAccountId,
|
|
28721
|
+
accounts
|
|
28722
|
+
};
|
|
28723
|
+
});
|
|
28724
|
+
}
|
|
28219
28725
|
};
|
|
28220
28726
|
var GrokBuildCredentialStore = class extends OAuthCredentialFileStore {
|
|
28221
28727
|
constructor(filename = grokBuildAuthPath()) {
|
|
@@ -28248,85 +28754,9 @@ async function importGrokBuildSession(session, filename) {
|
|
|
28248
28754
|
await session.refreshLiveCatalog();
|
|
28249
28755
|
}
|
|
28250
28756
|
|
|
28251
|
-
// src/runtime/http-json.ts
|
|
28252
|
-
var JSON_BODY_LIMIT_BYTES = 64 * 1024;
|
|
28253
|
-
var JsonRequestError = class extends Error {
|
|
28254
|
-
statusCode;
|
|
28255
|
-
constructor(statusCode, message) {
|
|
28256
|
-
super(message);
|
|
28257
|
-
this.name = "JsonRequestError";
|
|
28258
|
-
this.statusCode = statusCode;
|
|
28259
|
-
}
|
|
28260
|
-
};
|
|
28261
|
-
function declaredLength(request) {
|
|
28262
|
-
const value = request.headers["content-length"];
|
|
28263
|
-
if (typeof value !== "string" || !/^\d+$/u.test(value)) return void 0;
|
|
28264
|
-
const length = Number(value);
|
|
28265
|
-
return Number.isSafeInteger(length) ? length : void 0;
|
|
28266
|
-
}
|
|
28267
|
-
function readJsonRequest(request, limit = JSON_BODY_LIMIT_BYTES) {
|
|
28268
|
-
const length = declaredLength(request);
|
|
28269
|
-
if (length !== void 0 && length > limit) {
|
|
28270
|
-
request.resume();
|
|
28271
|
-
return Promise.reject(new JsonRequestError(413, "request body is too large"));
|
|
28272
|
-
}
|
|
28273
|
-
return new Promise((resolve8, reject) => {
|
|
28274
|
-
const chunks = [];
|
|
28275
|
-
let size = 0;
|
|
28276
|
-
let settled = false;
|
|
28277
|
-
const cleanup = () => {
|
|
28278
|
-
request.removeListener("data", onData);
|
|
28279
|
-
request.removeListener("end", onEnd);
|
|
28280
|
-
request.removeListener("error", onError);
|
|
28281
|
-
request.removeListener("aborted", onAborted);
|
|
28282
|
-
};
|
|
28283
|
-
const fail = (error) => {
|
|
28284
|
-
if (settled) return;
|
|
28285
|
-
settled = true;
|
|
28286
|
-
cleanup();
|
|
28287
|
-
request.resume();
|
|
28288
|
-
reject(error);
|
|
28289
|
-
};
|
|
28290
|
-
const onData = (value) => {
|
|
28291
|
-
if (settled) return;
|
|
28292
|
-
const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value);
|
|
28293
|
-
size += chunk.byteLength;
|
|
28294
|
-
if (size > limit) {
|
|
28295
|
-
fail(new JsonRequestError(413, "request body is too large"));
|
|
28296
|
-
return;
|
|
28297
|
-
}
|
|
28298
|
-
chunks.push(chunk);
|
|
28299
|
-
};
|
|
28300
|
-
const onEnd = () => {
|
|
28301
|
-
if (settled) return;
|
|
28302
|
-
settled = true;
|
|
28303
|
-
cleanup();
|
|
28304
|
-
const text = Buffer.concat(chunks, size).toString("utf8").trim();
|
|
28305
|
-
if (text.length === 0) {
|
|
28306
|
-
resolve8({});
|
|
28307
|
-
return;
|
|
28308
|
-
}
|
|
28309
|
-
try {
|
|
28310
|
-
resolve8(JSON.parse(text));
|
|
28311
|
-
} catch {
|
|
28312
|
-
reject(new JsonRequestError(400, "request body must contain valid JSON"));
|
|
28313
|
-
}
|
|
28314
|
-
};
|
|
28315
|
-
const onError = () => fail(new JsonRequestError(400, "request body could not be read"));
|
|
28316
|
-
const onAborted = () => fail(new JsonRequestError(400, "request body was aborted"));
|
|
28317
|
-
request.on("data", onData);
|
|
28318
|
-
request.once("end", onEnd);
|
|
28319
|
-
request.once("error", onError);
|
|
28320
|
-
request.once("aborted", onAborted);
|
|
28321
|
-
});
|
|
28322
|
-
}
|
|
28323
|
-
function requestErrorStatus(error, fallback) {
|
|
28324
|
-
return error instanceof JsonRequestError ? error.statusCode : fallback;
|
|
28325
|
-
}
|
|
28326
|
-
|
|
28327
28757
|
// src/oauth.ts
|
|
28328
28758
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
28329
|
-
import { createHash as createHash2, randomBytes as
|
|
28759
|
+
import { createHash as createHash2, randomBytes as randomBytes3 } from "node:crypto";
|
|
28330
28760
|
import { createServer } from "node:http";
|
|
28331
28761
|
var GROK_BUILD_OAUTH_ISSUER = "https://auth.x.ai";
|
|
28332
28762
|
var APPROVED_GROK_ISSUER_ORIGIN2 = "https://auth.x.ai";
|
|
@@ -28493,12 +28923,12 @@ async function discoverOAuthEndpoints(issuer, signal, options = {}) {
|
|
|
28493
28923
|
return parsed;
|
|
28494
28924
|
}
|
|
28495
28925
|
function generatePkce() {
|
|
28496
|
-
const verifier =
|
|
28926
|
+
const verifier = randomBytes3(32).toString("base64url");
|
|
28497
28927
|
const challenge = createHash2("sha256").update(verifier).digest("base64url");
|
|
28498
28928
|
return { verifier, challenge };
|
|
28499
28929
|
}
|
|
28500
28930
|
function randomToken() {
|
|
28501
|
-
return
|
|
28931
|
+
return randomBytes3(16).toString("base64url");
|
|
28502
28932
|
}
|
|
28503
28933
|
function buildAuthorizeUrl(endpoints, params, redirectUri, challenge, state, nonce) {
|
|
28504
28934
|
const url = new URL(endpoints.authorization_endpoint);
|
|
@@ -28983,6 +29413,14 @@ function waitForPromptAbort(prompt) {
|
|
|
28983
29413
|
async function grokImportAvailable() {
|
|
28984
29414
|
return (await probeGrokAuth()).available;
|
|
28985
29415
|
}
|
|
29416
|
+
async function signedInAccountFields(store) {
|
|
29417
|
+
const accounts = [...await store.listAccounts()];
|
|
29418
|
+
const activeAccountId = await store.getActiveAccountId();
|
|
29419
|
+
if (activeAccountId === void 0 || accounts.length === 0) {
|
|
29420
|
+
throw new Error("signed-in status requires at least one stored account");
|
|
29421
|
+
}
|
|
29422
|
+
return { accounts, activeAccountId };
|
|
29423
|
+
}
|
|
28986
29424
|
var GrokBuildWebAuth = class {
|
|
28987
29425
|
constructor(session) {
|
|
28988
29426
|
this.session = session;
|
|
@@ -29042,6 +29480,16 @@ var GrokBuildWebAuth = class {
|
|
|
29042
29480
|
await this.session.setSelectedModels(ids);
|
|
29043
29481
|
this.state = await this.readStoredStatus();
|
|
29044
29482
|
}
|
|
29483
|
+
async setActiveAccount(id) {
|
|
29484
|
+
await this.session.store.setActiveAccount(id);
|
|
29485
|
+
this.session.notifyCredentialChange();
|
|
29486
|
+
this.state = await this.readStoredStatus();
|
|
29487
|
+
}
|
|
29488
|
+
async removeAccount(id) {
|
|
29489
|
+
await this.session.store.removeAccount(id);
|
|
29490
|
+
this.session.notifyCredentialChange();
|
|
29491
|
+
this.state = await this.readStoredStatus();
|
|
29492
|
+
}
|
|
29045
29493
|
async signOut() {
|
|
29046
29494
|
this.cancellation?.abort(new Error("grok-build: sign-in cancelled"));
|
|
29047
29495
|
await this.operation?.catch(() => void 0);
|
|
@@ -29159,6 +29607,7 @@ var GrokBuildWebAuth = class {
|
|
|
29159
29607
|
if (!stored.authenticated) return { status: "signed-out", grokImportAvailable: grok };
|
|
29160
29608
|
const available = this.session.availableModels().map((model) => model.id);
|
|
29161
29609
|
const selected = this.session.selectedModelIds();
|
|
29610
|
+
const accounts = await signedInAccountFields(this.session.store);
|
|
29162
29611
|
return {
|
|
29163
29612
|
status: "signed-in",
|
|
29164
29613
|
models: this.session.visibleModels().map((model) => model.id),
|
|
@@ -29166,6 +29615,7 @@ var GrokBuildWebAuth = class {
|
|
|
29166
29615
|
selected: selected ?? available,
|
|
29167
29616
|
catalogSource: this.session.catalogSource,
|
|
29168
29617
|
grokImportAvailable: grok,
|
|
29618
|
+
...accounts,
|
|
29169
29619
|
...this.session.catalogError === void 0 ? {} : { catalogError: this.session.catalogError }
|
|
29170
29620
|
};
|
|
29171
29621
|
}
|
|
@@ -29248,6 +29698,16 @@ var SubscriptionWebAuth = class {
|
|
|
29248
29698
|
await this.session.setSelectedModels(ids);
|
|
29249
29699
|
this.state = await this.readStoredStatus();
|
|
29250
29700
|
}
|
|
29701
|
+
async setActiveAccount(id) {
|
|
29702
|
+
await this.session.store.setActiveAccount(id);
|
|
29703
|
+
this.session.notifyCredentialChange();
|
|
29704
|
+
this.state = await this.readStoredStatus();
|
|
29705
|
+
}
|
|
29706
|
+
async removeAccount(id) {
|
|
29707
|
+
await this.session.store.removeAccount(id);
|
|
29708
|
+
this.session.notifyCredentialChange();
|
|
29709
|
+
this.state = await this.readStoredStatus();
|
|
29710
|
+
}
|
|
29251
29711
|
async signOut() {
|
|
29252
29712
|
this.cancellation?.abort(new Error(`${this.session.definition.route}: sign-in cancelled`));
|
|
29253
29713
|
await this.operation?.catch(() => void 0);
|
|
@@ -29280,7 +29740,14 @@ var SubscriptionWebAuth = class {
|
|
|
29280
29740
|
const base = this.baseStatus();
|
|
29281
29741
|
try {
|
|
29282
29742
|
const stored = await this.session.status();
|
|
29283
|
-
|
|
29743
|
+
if (!stored.authenticated) return { ...base, status: "signed-out" };
|
|
29744
|
+
const accounts = await signedInAccountFields(this.session.store);
|
|
29745
|
+
return {
|
|
29746
|
+
...base,
|
|
29747
|
+
status: "signed-in",
|
|
29748
|
+
...accounts,
|
|
29749
|
+
...stored.expiresAt === void 0 ? {} : { expiresAt: stored.expiresAt }
|
|
29750
|
+
};
|
|
29284
29751
|
} catch (error) {
|
|
29285
29752
|
return { ...base, status: "error", message: safeMessage(error) };
|
|
29286
29753
|
}
|
|
@@ -29660,6 +30127,50 @@ function registerCodingOAuthRoutes(ctx, grokSession, subscriptionSessions, owner
|
|
|
29660
30127
|
json(res, requestErrorStatus(error, 500), { error: safeMessage(error) });
|
|
29661
30128
|
}
|
|
29662
30129
|
}
|
|
30130
|
+
}),
|
|
30131
|
+
webServer.register({
|
|
30132
|
+
kind: "exact",
|
|
30133
|
+
path: CODING_OAUTH_ACCOUNTS_SET_ACTIVE_PATH,
|
|
30134
|
+
handler: async (req, res) => {
|
|
30135
|
+
if (req.method !== "POST") return json(res, 405, { error: "method not allowed" });
|
|
30136
|
+
const decision = ownerRequestPolicy.authorize(req);
|
|
30137
|
+
if (!decision.authorized || decision.accessMode === void 0) return json(res, 403, { error: "forbidden" });
|
|
30138
|
+
try {
|
|
30139
|
+
const body = recordBody(await readJsonRequest(req));
|
|
30140
|
+
const slug = providerSlug(body);
|
|
30141
|
+
const accountId = body["accountId"];
|
|
30142
|
+
if (typeof accountId !== "string" || accountId.trim().length === 0) {
|
|
30143
|
+
return json(res, 400, { error: "accountId must be a non-empty string" });
|
|
30144
|
+
}
|
|
30145
|
+
if (slug === "grok") await grok.setActiveAccount(accountId);
|
|
30146
|
+
else await subscription(slug).setActiveAccount(accountId);
|
|
30147
|
+
json(res, 200, await allStatus(decision.accessMode));
|
|
30148
|
+
} catch (error) {
|
|
30149
|
+
json(res, requestErrorStatus(error, 500), { error: safeMessage(error) });
|
|
30150
|
+
}
|
|
30151
|
+
}
|
|
30152
|
+
}),
|
|
30153
|
+
webServer.register({
|
|
30154
|
+
kind: "exact",
|
|
30155
|
+
path: CODING_OAUTH_ACCOUNTS_REMOVE_PATH,
|
|
30156
|
+
handler: async (req, res) => {
|
|
30157
|
+
if (req.method !== "POST") return json(res, 405, { error: "method not allowed" });
|
|
30158
|
+
const decision = ownerRequestPolicy.authorize(req);
|
|
30159
|
+
if (!decision.authorized || decision.accessMode === void 0) return json(res, 403, { error: "forbidden" });
|
|
30160
|
+
try {
|
|
30161
|
+
const body = recordBody(await readJsonRequest(req));
|
|
30162
|
+
const slug = providerSlug(body);
|
|
30163
|
+
const accountId = body["accountId"];
|
|
30164
|
+
if (typeof accountId !== "string" || accountId.trim().length === 0) {
|
|
30165
|
+
return json(res, 400, { error: "accountId must be a non-empty string" });
|
|
30166
|
+
}
|
|
30167
|
+
if (slug === "grok") await grok.removeAccount(accountId);
|
|
30168
|
+
else await subscription(slug).removeAccount(accountId);
|
|
30169
|
+
json(res, 200, await allStatus(decision.accessMode));
|
|
30170
|
+
} catch (error) {
|
|
30171
|
+
json(res, requestErrorStatus(error, 500), { error: safeMessage(error) });
|
|
30172
|
+
}
|
|
30173
|
+
}
|
|
29663
30174
|
})
|
|
29664
30175
|
]);
|
|
29665
30176
|
return releaseRoutes;
|
|
@@ -30596,7 +31107,7 @@ import { lookup as dnsLookup } from "node:dns/promises";
|
|
|
30596
31107
|
import { isIP as isIP2 } from "node:net";
|
|
30597
31108
|
|
|
30598
31109
|
// src/media-store.ts
|
|
30599
|
-
import { createHash as createHash3, randomBytes as
|
|
31110
|
+
import { createHash as createHash3, randomBytes as randomBytes4 } from "node:crypto";
|
|
30600
31111
|
import { constants as fsConstants } from "node:fs";
|
|
30601
31112
|
import { chmod, link, lstat as lstat2, mkdir as mkdir2, open as open2, readdir, unlink } from "node:fs/promises";
|
|
30602
31113
|
import { dirname as dirname2, isAbsolute, join as join4, relative, resolve as resolve4, sep } from "node:path";
|
|
@@ -30629,7 +31140,7 @@ function sha256Hex(data) {
|
|
|
30629
31140
|
return createHash3("sha256").update(data).digest("hex");
|
|
30630
31141
|
}
|
|
30631
31142
|
function generateArtifactId() {
|
|
30632
|
-
return
|
|
31143
|
+
return randomBytes4(16).toString("hex");
|
|
30633
31144
|
}
|
|
30634
31145
|
function clampPositive(value, ceiling, label) {
|
|
30635
31146
|
const raw = value ?? ceiling;
|
|
@@ -30816,7 +31327,7 @@ async function writeExclusiveFile(root, path, data) {
|
|
|
30816
31327
|
throw collision;
|
|
30817
31328
|
}
|
|
30818
31329
|
const payload = typeof data === "string" ? Buffer.from(data) : data;
|
|
30819
|
-
const temporary = join4(dirname2(target), `.tmp-${
|
|
31330
|
+
const temporary = join4(dirname2(target), `.tmp-${randomBytes4(8).toString("hex")}`);
|
|
30820
31331
|
const handle = await openNoFollow(
|
|
30821
31332
|
temporary,
|
|
30822
31333
|
fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL,
|
|
@@ -33429,7 +33940,6 @@ var DSH_EXACT_BOM = Object.freeze({
|
|
|
33429
33940
|
"@deepseek-ai/dsh-atomic-write": "0.1.1-rc.2",
|
|
33430
33941
|
"@deepseek-ai/dsh-attachment": "0.1.1-rc.2",
|
|
33431
33942
|
"@deepseek-ai/dsh-client-locale": "0.1.1-rc.2",
|
|
33432
|
-
"@deepseek-ai/dsh-client-runtime": "0.1.1-rc.2",
|
|
33433
33943
|
"@deepseek-ai/dsh-client-ui-settings": "0.1.1-rc.2",
|
|
33434
33944
|
"@deepseek-ai/dsh-client-ui-slots": "0.1.1-rc.2",
|
|
33435
33945
|
"@deepseek-ai/dsh-client-web": "0.1.1-rc.2",
|
|
@@ -33571,7 +34081,7 @@ function createDshHostAdapter(context) {
|
|
|
33571
34081
|
}
|
|
33572
34082
|
|
|
33573
34083
|
// src/gateway-auth.ts
|
|
33574
|
-
import { randomBytes as
|
|
34084
|
+
import { randomBytes as randomBytes5, timingSafeEqual as timingSafeEqual3 } from "node:crypto";
|
|
33575
34085
|
import { mkdir as mkdir3 } from "node:fs/promises";
|
|
33576
34086
|
import { dirname as dirname3, join as join5, resolve as resolve5 } from "node:path";
|
|
33577
34087
|
import { writeFileAtomic as writeFileAtomic3 } from "@deepseek-ai/dsh-atomic-write";
|
|
@@ -33581,7 +34091,7 @@ function gatewayKeyPath(dshHome) {
|
|
|
33581
34091
|
return resolve5(join5(resolveDshHome2(dshHome), GATEWAY_KEY_FILENAME));
|
|
33582
34092
|
}
|
|
33583
34093
|
function generateGatewayApiKey() {
|
|
33584
|
-
return
|
|
34094
|
+
return randomBytes5(32).toString("base64url");
|
|
33585
34095
|
}
|
|
33586
34096
|
function gatewayKeysEqual(left, right) {
|
|
33587
34097
|
const a = Buffer.from(left);
|
|
@@ -33637,11 +34147,6 @@ async function persistGatewayKeyDocument(path, document) {
|
|
|
33637
34147
|
`, { mode: 384 });
|
|
33638
34148
|
}
|
|
33639
34149
|
|
|
33640
|
-
// src/runtime/gateway-protocol.ts
|
|
33641
|
-
function isThinkingLevel(value) {
|
|
33642
|
-
return value === "off" || value === "minimal" || value === "low" || value === "medium" || value === "high" || value === "xhigh" || value === "max";
|
|
33643
|
-
}
|
|
33644
|
-
|
|
33645
34150
|
// src/gateway-backend.ts
|
|
33646
34151
|
var GatewayRequestError = class extends Error {
|
|
33647
34152
|
constructor(status, code, message) {
|
|
@@ -35479,6 +35984,10 @@ var OAuthProviderSession = class {
|
|
|
35479
35984
|
async invalidateAccessToken() {
|
|
35480
35985
|
await this.store.invalidate(this.definition.nativeProviderId);
|
|
35481
35986
|
}
|
|
35987
|
+
/** Refresh host discovery after an account switch/remove without a full logout. */
|
|
35988
|
+
notifyCredentialChange() {
|
|
35989
|
+
this.onCatalogChange?.();
|
|
35990
|
+
}
|
|
35482
35991
|
async storedCredential() {
|
|
35483
35992
|
const credential = await this.store.read(this.definition.nativeProviderId);
|
|
35484
35993
|
return credential?.type === "oauth" ? credential : void 0;
|
|
@@ -35643,6 +36152,10 @@ var GrokBuildSession = class {
|
|
|
35643
36152
|
async invalidateAccessToken() {
|
|
35644
36153
|
await this.store.invalidate(XAI_PI_PROVIDER);
|
|
35645
36154
|
}
|
|
36155
|
+
/** Refresh host discovery after an account switch/remove without a full logout. */
|
|
36156
|
+
notifyCredentialChange() {
|
|
36157
|
+
this.onCatalogChange?.();
|
|
36158
|
+
}
|
|
35646
36159
|
async logout() {
|
|
35647
36160
|
try {
|
|
35648
36161
|
await this.store.delete(XAI_PI_PROVIDER);
|
|
@@ -36125,6 +36638,7 @@ export {
|
|
|
36125
36638
|
KIMI_CODE_OAUTH_ROUTE,
|
|
36126
36639
|
KIMI_PI_PROVIDER,
|
|
36127
36640
|
LOOPBACK_OWNER_REQUEST_POLICY,
|
|
36641
|
+
OAUTH_MAX_ACCOUNTS,
|
|
36128
36642
|
OAUTH_PROVIDER_DEFINITIONS,
|
|
36129
36643
|
OAuthCredentialFileStore,
|
|
36130
36644
|
OAuthProviderSession,
|
|
@@ -36163,6 +36677,7 @@ export {
|
|
|
36163
36677
|
importGrokBuildFromGrok,
|
|
36164
36678
|
importGrokBuildSession,
|
|
36165
36679
|
inject,
|
|
36680
|
+
isValidAccountId,
|
|
36166
36681
|
loginGrokBuild,
|
|
36167
36682
|
loginGrokBuildPkce,
|
|
36168
36683
|
loginGrokBuildSession,
|
|
@@ -36181,6 +36696,7 @@ export {
|
|
|
36181
36696
|
refreshGrokBuildToken,
|
|
36182
36697
|
registerCodingOAuthRoutes,
|
|
36183
36698
|
registerGrokBuildAuthRoutes,
|
|
36699
|
+
resolveAccountIdForCredential,
|
|
36184
36700
|
resolveOAuthParams,
|
|
36185
36701
|
safeMessage,
|
|
36186
36702
|
thinkingLevelMapFromLiveEfforts
|