@vymalo/opencode-oauth2 0.2.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/LICENSE +21 -0
- package/README.md +213 -0
- package/dist/cache.d.ts +9 -0
- package/dist/cache.js +91 -0
- package/dist/cache.js.map +1 -0
- package/dist/config.d.ts +97 -0
- package/dist/config.js +179 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/logging.d.ts +11 -0
- package/dist/logging.js +59 -0
- package/dist/logging.js.map +1 -0
- package/dist/model-discovery.d.ts +9 -0
- package/dist/model-discovery.js +74 -0
- package/dist/model-discovery.js.map +1 -0
- package/dist/model-normalization.d.ts +4 -0
- package/dist/model-normalization.js +86 -0
- package/dist/model-normalization.js.map +1 -0
- package/dist/oauth/browser.d.ts +1 -0
- package/dist/oauth/browser.js +29 -0
- package/dist/oauth/browser.js.map +1 -0
- package/dist/oauth/client.d.ts +56 -0
- package/dist/oauth/client.js +436 -0
- package/dist/oauth/client.js.map +1 -0
- package/dist/oauth/device-code.d.ts +22 -0
- package/dist/oauth/device-code.js +240 -0
- package/dist/oauth/device-code.js.map +1 -0
- package/dist/oauth/discovery.d.ts +8 -0
- package/dist/oauth/discovery.js +38 -0
- package/dist/oauth/discovery.js.map +1 -0
- package/dist/oauth/http-utils.d.ts +33 -0
- package/dist/oauth/http-utils.js +129 -0
- package/dist/oauth/http-utils.js.map +1 -0
- package/dist/oauth/local-callback.d.ts +10 -0
- package/dist/oauth/local-callback.js +82 -0
- package/dist/oauth/local-callback.js.map +1 -0
- package/dist/oauth/pkce.d.ts +5 -0
- package/dist/oauth/pkce.js +13 -0
- package/dist/oauth/pkce.js.map +1 -0
- package/dist/oauth/subject-token.d.ts +20 -0
- package/dist/oauth/subject-token.js +86 -0
- package/dist/oauth/subject-token.js.map +1 -0
- package/dist/opencode.d.ts +11 -0
- package/dist/opencode.js +347 -0
- package/dist/opencode.js.map +1 -0
- package/dist/plugin.d.ts +47 -0
- package/dist/plugin.js +220 -0
- package/dist/plugin.js.map +1 -0
- package/dist/scheduler.d.ts +11 -0
- package/dist/scheduler.js +44 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/types.d.ts +37 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type LogLevel = "debug" | "info" | "warn" | "error";
|
|
2
|
+
export interface LogFields {
|
|
3
|
+
[key: string]: unknown;
|
|
4
|
+
}
|
|
5
|
+
export interface Logger {
|
|
6
|
+
debug(event: string, fields?: LogFields): void;
|
|
7
|
+
info(event: string, fields?: LogFields): void;
|
|
8
|
+
warn(event: string, fields?: LogFields): void;
|
|
9
|
+
error(event: string, fields?: LogFields): void;
|
|
10
|
+
}
|
|
11
|
+
export declare function createJsonConsoleLogger(minLevel?: LogLevel): Logger;
|
package/dist/logging.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const LOG_LEVEL_PRIORITY = {
|
|
2
|
+
debug: 10,
|
|
3
|
+
info: 20,
|
|
4
|
+
warn: 30,
|
|
5
|
+
error: 40
|
|
6
|
+
};
|
|
7
|
+
function redactFields(fields) {
|
|
8
|
+
if (!fields) {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
const redacted = {};
|
|
12
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
13
|
+
if (/token|secret|password/i.test(key)) {
|
|
14
|
+
redacted[key] = "[redacted]";
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
redacted[key] = value;
|
|
18
|
+
}
|
|
19
|
+
return redacted;
|
|
20
|
+
}
|
|
21
|
+
export function createJsonConsoleLogger(minLevel = "info") {
|
|
22
|
+
const minPriority = LOG_LEVEL_PRIORITY[minLevel];
|
|
23
|
+
const log = (level, event, fields) => {
|
|
24
|
+
if (LOG_LEVEL_PRIORITY[level] < minPriority) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const payload = {
|
|
28
|
+
ts: new Date().toISOString(),
|
|
29
|
+
level,
|
|
30
|
+
event,
|
|
31
|
+
...(redactFields(fields) ?? {})
|
|
32
|
+
};
|
|
33
|
+
const line = JSON.stringify(payload);
|
|
34
|
+
if (level === "error") {
|
|
35
|
+
console.error(line);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (level === "warn") {
|
|
39
|
+
console.warn(line);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
console.log(line);
|
|
43
|
+
};
|
|
44
|
+
return {
|
|
45
|
+
debug(event, fields) {
|
|
46
|
+
log("debug", event, fields);
|
|
47
|
+
},
|
|
48
|
+
info(event, fields) {
|
|
49
|
+
log("info", event, fields);
|
|
50
|
+
},
|
|
51
|
+
warn(event, fields) {
|
|
52
|
+
log("warn", event, fields);
|
|
53
|
+
},
|
|
54
|
+
error(event, fields) {
|
|
55
|
+
log("error", event, fields);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=logging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging.js","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"AAEA,MAAM,kBAAkB,GAA6B;IACnD,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,EAAE;IACR,KAAK,EAAE,EAAE;CACV,CAAC;AAaF,SAAS,YAAY,CAAC,MAAkB;IACtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACvC,QAAQ,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC;YAC7B,SAAS;QACX,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACxB,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,WAAqB,MAAM;IACjE,MAAM,WAAW,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAEjD,MAAM,GAAG,GAAG,CAAC,KAAe,EAAE,KAAa,EAAE,MAAkB,EAAQ,EAAE;QACvE,IAAI,kBAAkB,CAAC,KAAK,CAAC,GAAG,WAAW,EAAE,CAAC;YAC5C,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG;YACd,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,KAAK;YACL,KAAK;YACL,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;SAChC,CAAC;QAEF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QAED,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,CAAC,KAAK,EAAE,MAAM;YACjB,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,MAAM;YAChB,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,MAAM;YAChB,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAC7B,CAAC;QACD,KAAK,CAAC,KAAK,EAAE,MAAM;YACjB,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAC9B,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Logger } from "./logging.js";
|
|
2
|
+
import type { RawModel, TokenSet } from "./types.js";
|
|
3
|
+
export interface ModelDiscoveryOptions {
|
|
4
|
+
fetchImpl?: typeof fetch;
|
|
5
|
+
timeoutMs?: number;
|
|
6
|
+
logger?: Logger;
|
|
7
|
+
}
|
|
8
|
+
export declare function buildModelsUrl(baseURL: string): string;
|
|
9
|
+
export declare function fetchModels(baseURL: string, token: TokenSet, options?: ModelDiscoveryOptions): Promise<RawModel[]>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { readResponseBodyPreview, redactUrl, scrubSecrets } from "./oauth/http-utils.js";
|
|
2
|
+
export function buildModelsUrl(baseURL) {
|
|
3
|
+
const url = new URL(baseURL);
|
|
4
|
+
const path = url.pathname.replace(/\/+$/, "");
|
|
5
|
+
if (path.endsWith("/v1")) {
|
|
6
|
+
url.pathname = `${path}/models`;
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
url.pathname = `${path}/v1/models`;
|
|
10
|
+
}
|
|
11
|
+
return url.toString();
|
|
12
|
+
}
|
|
13
|
+
function parseModelsResponse(payload) {
|
|
14
|
+
const candidates = Array.isArray(payload)
|
|
15
|
+
? payload
|
|
16
|
+
: payload && typeof payload === "object" && Array.isArray(payload.data)
|
|
17
|
+
? payload.data
|
|
18
|
+
: [];
|
|
19
|
+
const models = [];
|
|
20
|
+
for (const item of candidates) {
|
|
21
|
+
if (!item || typeof item !== "object") {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
const id = item.id;
|
|
25
|
+
if (typeof id !== "string" || id.length === 0) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
models.push(item);
|
|
29
|
+
}
|
|
30
|
+
return models;
|
|
31
|
+
}
|
|
32
|
+
export async function fetchModels(baseURL, token, options = {}) {
|
|
33
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
34
|
+
const timeoutMs = options.timeoutMs ?? 15_000;
|
|
35
|
+
const modelsUrl = buildModelsUrl(baseURL);
|
|
36
|
+
const controller = new AbortController();
|
|
37
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
38
|
+
try {
|
|
39
|
+
const response = await fetchImpl(modelsUrl, {
|
|
40
|
+
method: "GET",
|
|
41
|
+
headers: {
|
|
42
|
+
Accept: "application/json",
|
|
43
|
+
Authorization: `${token.tokenType || "Bearer"} ${token.accessToken}`
|
|
44
|
+
},
|
|
45
|
+
signal: controller.signal
|
|
46
|
+
});
|
|
47
|
+
if (!response.ok) {
|
|
48
|
+
const safeUrl = redactUrl(modelsUrl);
|
|
49
|
+
// Log the body separately at warn-level so the structured logger's
|
|
50
|
+
// redaction filter has a chance to scrub matching keys, and so the body
|
|
51
|
+
// never lands inside a thrown error.message (which callers like
|
|
52
|
+
// syncServer log verbatim).
|
|
53
|
+
const preview = await readResponseBodyPreview(response, 500);
|
|
54
|
+
if (preview) {
|
|
55
|
+
options.logger?.warn("model_discovery_error_body", {
|
|
56
|
+
modelsUrl: safeUrl,
|
|
57
|
+
status: response.status,
|
|
58
|
+
bodyPreview: scrubSecrets(preview)
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
throw new Error(`model discovery failed (${response.status}) at ${safeUrl}`);
|
|
62
|
+
}
|
|
63
|
+
const payload = (await response.json());
|
|
64
|
+
const models = parseModelsResponse(payload);
|
|
65
|
+
if (models.length === 0) {
|
|
66
|
+
options.logger?.warn("model_discovery_empty", { modelsUrl: redactUrl(modelsUrl) });
|
|
67
|
+
}
|
|
68
|
+
return models;
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
clearTimeout(timeout);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=model-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-discovery.js","sourceRoot":"","sources":["../src/model-discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ModelDiff, NormalizedModel, RawModel } from "./types.js";
|
|
2
|
+
export declare function normalizeModelId(modelId: string, overrides?: Record<string, string>): string;
|
|
3
|
+
export declare function normalizeModelList(models: RawModel[], overrides?: Record<string, string>): NormalizedModel[];
|
|
4
|
+
export declare function diffModels(previous: NormalizedModel[], next: NormalizedModel[]): ModelDiff;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
const TOKEN_OVERRIDES = {
|
|
2
|
+
ai: "AI",
|
|
3
|
+
api: "API",
|
|
4
|
+
cpu: "CPU",
|
|
5
|
+
gpu: "GPU",
|
|
6
|
+
glm: "GLM",
|
|
7
|
+
gpt: "GPT",
|
|
8
|
+
llm: "LLM",
|
|
9
|
+
nlp: "NLP",
|
|
10
|
+
ocr: "OCR",
|
|
11
|
+
tts: "TTS",
|
|
12
|
+
stt: "STT"
|
|
13
|
+
};
|
|
14
|
+
function titleCase(token) {
|
|
15
|
+
if (token.length === 0) {
|
|
16
|
+
return token;
|
|
17
|
+
}
|
|
18
|
+
return token[0].toUpperCase() + token.slice(1).toLowerCase();
|
|
19
|
+
}
|
|
20
|
+
function normalizeToken(token) {
|
|
21
|
+
const lower = token.toLowerCase();
|
|
22
|
+
if (TOKEN_OVERRIDES[lower]) {
|
|
23
|
+
return TOKEN_OVERRIDES[lower];
|
|
24
|
+
}
|
|
25
|
+
if (/^\d+$/.test(token)) {
|
|
26
|
+
return token;
|
|
27
|
+
}
|
|
28
|
+
if (/^\d+[a-z]$/i.test(token)) {
|
|
29
|
+
const suffix = token.at(-1)?.toLowerCase() ?? "";
|
|
30
|
+
if (["b", "k", "m", "g", "t"].includes(suffix)) {
|
|
31
|
+
return `${token.slice(0, -1)}${suffix.toUpperCase()}`;
|
|
32
|
+
}
|
|
33
|
+
return `${token.slice(0, -1)}${suffix}`;
|
|
34
|
+
}
|
|
35
|
+
if (/^[a-z]+\d+[a-z0-9]*$/i.test(token)) {
|
|
36
|
+
return token[0].toUpperCase() + token.slice(1).toLowerCase();
|
|
37
|
+
}
|
|
38
|
+
if (/^\d+[a-z]+$/i.test(token)) {
|
|
39
|
+
return `${token.match(/^\d+/)?.[0] ?? ""}${token.replace(/^\d+/, "").toLowerCase()}`;
|
|
40
|
+
}
|
|
41
|
+
return titleCase(token);
|
|
42
|
+
}
|
|
43
|
+
export function normalizeModelId(modelId, overrides) {
|
|
44
|
+
if (overrides?.[modelId]) {
|
|
45
|
+
return overrides[modelId];
|
|
46
|
+
}
|
|
47
|
+
const normalizedTokens = modelId
|
|
48
|
+
.split(/[-_/:]+/g)
|
|
49
|
+
.map((token) => token.trim())
|
|
50
|
+
.filter((token) => token.length > 0)
|
|
51
|
+
.map((token) => normalizeToken(token));
|
|
52
|
+
if (normalizedTokens.length === 0) {
|
|
53
|
+
return modelId;
|
|
54
|
+
}
|
|
55
|
+
return normalizedTokens.join(" ");
|
|
56
|
+
}
|
|
57
|
+
export function normalizeModelList(models, overrides) {
|
|
58
|
+
return models.map((model) => ({
|
|
59
|
+
id: model.id,
|
|
60
|
+
displayName: normalizeModelId(model.id, overrides)
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
export function diffModels(previous, next) {
|
|
64
|
+
const previousMap = new Map(previous.map((model) => [model.id, model.displayName]));
|
|
65
|
+
const nextMap = new Map(next.map((model) => [model.id, model.displayName]));
|
|
66
|
+
const added = [];
|
|
67
|
+
const removed = [];
|
|
68
|
+
const renamed = [];
|
|
69
|
+
for (const [id, displayName] of nextMap.entries()) {
|
|
70
|
+
if (!previousMap.has(id)) {
|
|
71
|
+
added.push(id);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const previousName = previousMap.get(id);
|
|
75
|
+
if (previousName && previousName !== displayName) {
|
|
76
|
+
renamed.push({ id, before: previousName, after: displayName });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
for (const id of previousMap.keys()) {
|
|
80
|
+
if (!nextMap.has(id)) {
|
|
81
|
+
removed.push(id);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return { added, removed, renamed };
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=model-normalization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-normalization.js","sourceRoot":"","sources":["../src/model-normalization.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function openExternalUrl(url: string): Promise<void>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
export async function openExternalUrl(url) {
|
|
3
|
+
await new Promise((resolve, reject) => {
|
|
4
|
+
let command;
|
|
5
|
+
let args;
|
|
6
|
+
if (process.platform === "darwin") {
|
|
7
|
+
command = "open";
|
|
8
|
+
args = [url];
|
|
9
|
+
}
|
|
10
|
+
else if (process.platform === "win32") {
|
|
11
|
+
command = "cmd";
|
|
12
|
+
args = ["/c", "start", "", url];
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
command = "xdg-open";
|
|
16
|
+
args = [url];
|
|
17
|
+
}
|
|
18
|
+
const child = spawn(command, args, {
|
|
19
|
+
stdio: "ignore",
|
|
20
|
+
detached: true
|
|
21
|
+
});
|
|
22
|
+
child.once("error", reject);
|
|
23
|
+
child.once("spawn", () => {
|
|
24
|
+
child.unref();
|
|
25
|
+
resolve();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/oauth/browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAW;IAC/C,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,IAAI,OAAe,CAAC;QACpB,IAAI,IAAc,CAAC;QAEnB,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAClC,OAAO,GAAG,MAAM,CAAC;YACjB,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACf,CAAC;aAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACxC,OAAO,GAAG,KAAK,CAAC;YAChB,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,UAAU,CAAC;YACrB,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACf,CAAC;QAED,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YACjC,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;QAEH,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;YACvB,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { OAuthServerConfig } from "../config.js";
|
|
2
|
+
import type { Logger } from "../logging.js";
|
|
3
|
+
import type { TokenSet } from "../types.js";
|
|
4
|
+
interface OAuthClientOptions {
|
|
5
|
+
fetchImpl?: typeof fetch;
|
|
6
|
+
logger: Logger;
|
|
7
|
+
timeoutMs: number;
|
|
8
|
+
onAuthorizationUrl?: (url: string) => Promise<void> | void;
|
|
9
|
+
tokenExpirySkewMs?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function toTokenSet(payload: Record<string, unknown>, options?: {
|
|
12
|
+
fallbackRefreshToken?: string;
|
|
13
|
+
requireRefreshToken?: boolean;
|
|
14
|
+
}): TokenSet;
|
|
15
|
+
export declare class OAuthClient {
|
|
16
|
+
private readonly server;
|
|
17
|
+
private readonly fetchImpl;
|
|
18
|
+
private readonly logger;
|
|
19
|
+
private readonly timeoutMs;
|
|
20
|
+
private readonly onAuthorizationUrl?;
|
|
21
|
+
private readonly tokenExpirySkewMs;
|
|
22
|
+
constructor(server: OAuthServerConfig, options: OAuthClientOptions);
|
|
23
|
+
private isTokenValid;
|
|
24
|
+
/**
|
|
25
|
+
* POST to a token endpoint with an AbortController-backed timeout. Without
|
|
26
|
+
* this, a stalled IdP would block the warmup path indefinitely (the plugin
|
|
27
|
+
* runs token requests at config-hook time for cached/client_credentials
|
|
28
|
+
* paths).
|
|
29
|
+
*/
|
|
30
|
+
private postWithTimeout;
|
|
31
|
+
ensureToken(current?: TokenSet, options?: {
|
|
32
|
+
interactive?: boolean;
|
|
33
|
+
}): Promise<TokenSet>;
|
|
34
|
+
private loginClientCredentials;
|
|
35
|
+
private loginJwtBearer;
|
|
36
|
+
private loginTokenExchange;
|
|
37
|
+
/**
|
|
38
|
+
* Shared driver for jwt_bearer and token_exchange. Both grants:
|
|
39
|
+
* - resolve a platform-supplied JWT from `subjectTokenSource`
|
|
40
|
+
* - POST it to the token endpoint with grant-specific form fields
|
|
41
|
+
* - get back an access token (refresh token is NOT expected for either)
|
|
42
|
+
*/
|
|
43
|
+
private postFederatedGrant;
|
|
44
|
+
/**
|
|
45
|
+
* Resolve endpoints for the configured flow. Skips OIDC discovery entirely
|
|
46
|
+
* when the explicit endpoints needed for the flow are all present in config
|
|
47
|
+
* — discovery is unavailable on RFC 8414-only servers and on Keycloak
|
|
48
|
+
* realms where the well-known doc is locked down.
|
|
49
|
+
*/
|
|
50
|
+
private resolveEndpoints;
|
|
51
|
+
private hasExplicitEndpointsForFlow;
|
|
52
|
+
private refreshToken;
|
|
53
|
+
private loginDeviceCode;
|
|
54
|
+
private loginInteractive;
|
|
55
|
+
}
|
|
56
|
+
export {};
|