@edge-sky/dsh-oauth-adapter 0.1.1-rc.10
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.i18n.yaml +4 -0
- package/README.md +41 -0
- package/README.zh.md +41 -0
- package/cordis.patch.yml +6 -0
- package/lib/authorization-fallback.d.ts +19 -0
- package/lib/authorization-fallback.js +24 -0
- package/lib/client.js +683 -0
- package/lib/index.d.ts +41 -0
- package/lib/index.js +509 -0
- package/lib/invariant.d.ts +9 -0
- package/lib/invariant.js +11 -0
- package/lib/protocol.d.ts +121 -0
- package/lib/protocol.js +83 -0
- package/lib/types/client/OAuthAccountsSection.d.ts +12 -0
- package/lib/types/client/index.d.ts +16 -0
- package/lib/types/client/locales.d.ts +36 -0
- package/lib/types/client/store.d.ts +58 -0
- package/lib/types/client/styles.d.ts +3 -0
- package/lib/types/protocol.d.ts +121 -0
- package/package.json +147 -0
package/lib/protocol.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/** Shared browser/Host wire vocabulary for the OAuth account surface. */
|
|
2
|
+
export const OAUTH_SOCKET_PATH = '/_edge-sky/dsh-oauth';
|
|
3
|
+
export const OAUTH_SOCKET_PROTOCOL = 'dsh-oauth-v1';
|
|
4
|
+
export const MAX_FRAME_BYTES = 16 * 1024;
|
|
5
|
+
export const MAX_ANSWER_LENGTH = 8 * 1024;
|
|
6
|
+
export const PROVIDERS = [
|
|
7
|
+
{
|
|
8
|
+
id: 'openai-codex', key: 'llm-pi-ai/openai-codex', fallbackLabel: 'OpenAI Codex',
|
|
9
|
+
modelGroupLabel: 'OpenAI Codex (OAuth)',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
id: 'github-copilot', key: 'llm-pi-ai/github-copilot', fallbackLabel: 'GitHub Copilot',
|
|
13
|
+
modelGroupLabel: 'GitHub Copilot (OAuth)',
|
|
14
|
+
},
|
|
15
|
+
];
|
|
16
|
+
const ID_PATTERN = /^[A-Za-z0-9_-]{1,128}$/;
|
|
17
|
+
function isRecord(value) {
|
|
18
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
19
|
+
}
|
|
20
|
+
function exactKeys(value, expected) {
|
|
21
|
+
const actual = Object.keys(value).sort();
|
|
22
|
+
const sortedExpected = [...expected].sort();
|
|
23
|
+
return actual.length === sortedExpected.length && actual.every((key, index) => key === sortedExpected[index]);
|
|
24
|
+
}
|
|
25
|
+
function isId(value) {
|
|
26
|
+
return typeof value === 'string' && ID_PATTERN.test(value);
|
|
27
|
+
}
|
|
28
|
+
export function isProviderId(value) {
|
|
29
|
+
return PROVIDERS.some(provider => provider.id === value);
|
|
30
|
+
}
|
|
31
|
+
/** Parse one untrusted browser frame without retaining its raw text. */
|
|
32
|
+
export function parseClientCommand(raw) {
|
|
33
|
+
let candidate;
|
|
34
|
+
try {
|
|
35
|
+
candidate = JSON.parse(raw);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return { ok: false, message: 'message is not valid JSON' };
|
|
39
|
+
}
|
|
40
|
+
if (!isRecord(candidate) || typeof candidate.type !== 'string') {
|
|
41
|
+
return { ok: false, message: 'message must be an object with a type' };
|
|
42
|
+
}
|
|
43
|
+
const requestId = isId(candidate.requestId) ? candidate.requestId : undefined;
|
|
44
|
+
if (requestId === undefined)
|
|
45
|
+
return { ok: false, message: 'requestId is invalid' };
|
|
46
|
+
switch (candidate.type) {
|
|
47
|
+
case 'refresh':
|
|
48
|
+
return exactKeys(candidate, ['requestId', 'type'])
|
|
49
|
+
? { ok: true, value: { type: 'refresh', requestId } }
|
|
50
|
+
: { ok: false, requestId, message: 'refresh contains unknown fields' };
|
|
51
|
+
case 'begin':
|
|
52
|
+
case 'forget': {
|
|
53
|
+
if (!exactKeys(candidate, ['provider', 'requestId', 'type'])) {
|
|
54
|
+
return { ok: false, requestId, message: `${candidate.type} contains unknown fields` };
|
|
55
|
+
}
|
|
56
|
+
if (!isProviderId(candidate.provider)) {
|
|
57
|
+
return { ok: false, requestId, message: 'provider is unsupported' };
|
|
58
|
+
}
|
|
59
|
+
return { ok: true, value: { type: candidate.type, requestId, provider: candidate.provider } };
|
|
60
|
+
}
|
|
61
|
+
case 'cancel':
|
|
62
|
+
if (!exactKeys(candidate, ['attemptId', 'requestId', 'type']) || !isId(candidate.attemptId)) {
|
|
63
|
+
return { ok: false, requestId, message: 'cancel fields are invalid' };
|
|
64
|
+
}
|
|
65
|
+
return { ok: true, value: { type: 'cancel', requestId, attemptId: candidate.attemptId } };
|
|
66
|
+
case 'respond':
|
|
67
|
+
if (!exactKeys(candidate, ['attemptId', 'promptId', 'requestId', 'type', 'value'])
|
|
68
|
+
|| !isId(candidate.attemptId) || !isId(candidate.promptId)
|
|
69
|
+
|| typeof candidate.value !== 'string' || candidate.value.length > MAX_ANSWER_LENGTH) {
|
|
70
|
+
return { ok: false, requestId, message: 'respond fields are invalid' };
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
ok: true,
|
|
74
|
+
value: {
|
|
75
|
+
type: 'respond', requestId, attemptId: candidate.attemptId,
|
|
76
|
+
promptId: candidate.promptId, value: candidate.value,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
default:
|
|
80
|
+
return { ok: false, requestId, message: 'message type is unsupported' };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** OAuth account settings page. */
|
|
2
|
+
import type { InjectFace } from '@deepseek-ai/dsh-client-ui-slots';
|
|
3
|
+
import type { OAuthLocaleKey } from './locales.js';
|
|
4
|
+
import type { OAuthAccountsController } from './store.js';
|
|
5
|
+
export interface OAuthAccountsInjected {
|
|
6
|
+
controller: OAuthAccountsController;
|
|
7
|
+
t: (key: OAuthLocaleKey) => string;
|
|
8
|
+
}
|
|
9
|
+
export type OAuthAccountsSectionProps = Partial<InjectFace<OAuthAccountsInjected>>;
|
|
10
|
+
/** Render the standalone OAuth Accounts settings section. */
|
|
11
|
+
export declare function OAuthAccountsSection(props: OAuthAccountsSectionProps): JSX.Element | null;
|
|
12
|
+
//# sourceMappingURL=OAuthAccountsSection.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Browser half of the standalone DSH OAuth Accounts page. */
|
|
2
|
+
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
3
|
+
import { type OAuthLocaleKey } from './locales.js';
|
|
4
|
+
export { OAuthAccountsSection } from './OAuthAccountsSection.js';
|
|
5
|
+
export { OAuthAccountsController } from './store.js';
|
|
6
|
+
export type { OAuthAccountsSnapshot, AttemptView } from './store.js';
|
|
7
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
8
|
+
interface LocaleNamespaceMap {
|
|
9
|
+
'settings.oauth-accounts': OAuthLocaleKey;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/** Required browser services for settings placement and localized copy. */
|
|
13
|
+
export declare const inject: string[];
|
|
14
|
+
/** Register the OAuth account page and its app-lifetime connection controller. */
|
|
15
|
+
export declare function apply(ctx: ClientContext): void;
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** English copy for the OAuth accounts page. */
|
|
2
|
+
export declare const en: {
|
|
3
|
+
readonly nav: "OAuth Accounts";
|
|
4
|
+
readonly title: "OAuth Accounts";
|
|
5
|
+
readonly intro: "Connect subscription-backed providers. Their models appear in separate OAuth groups, apart from API-key providers.";
|
|
6
|
+
readonly ready: "Connected · Models ready";
|
|
7
|
+
readonly connectedNoModels: "Connected · Model route unavailable";
|
|
8
|
+
readonly disconnected: "Not connected";
|
|
9
|
+
readonly authorizing: "Sign-in in progress";
|
|
10
|
+
readonly unavailable: "OAuth is unavailable in this DSH installation.";
|
|
11
|
+
readonly connect: "Connect";
|
|
12
|
+
readonly reconnect: "Reconnect";
|
|
13
|
+
readonly cancel: "Cancel";
|
|
14
|
+
readonly forget: "Sign out";
|
|
15
|
+
readonly retry: "Retry connection";
|
|
16
|
+
readonly starting: "Preparing a secure sign-in session…";
|
|
17
|
+
readonly awaitingAction: "Action required to continue sign-in.";
|
|
18
|
+
readonly waitingProvider: "Waiting for the provider to complete sign-in…";
|
|
19
|
+
readonly authorized: "Sign-in completed.";
|
|
20
|
+
readonly cancelled: "Sign-in was cancelled.";
|
|
21
|
+
readonly failed: "Sign-in failed.";
|
|
22
|
+
readonly technicalDetails: "Technical details";
|
|
23
|
+
readonly submit: "Continue";
|
|
24
|
+
readonly copy: "Copy code";
|
|
25
|
+
readonly copied: "Copied";
|
|
26
|
+
readonly openLink: "Open authorization page";
|
|
27
|
+
readonly externalLink: "External provider page";
|
|
28
|
+
readonly githubDomainPrompt: "GitHub Enterprise domain";
|
|
29
|
+
readonly githubDomainHint: "Leave blank to use github.com.";
|
|
30
|
+
readonly loading: "Loading account status…";
|
|
31
|
+
readonly hostDisconnected: "The OAuth connection to DSH was interrupted.";
|
|
32
|
+
};
|
|
33
|
+
/** Simplified Chinese copy for the OAuth accounts page. */
|
|
34
|
+
export declare const zh: Record<keyof typeof en, string>;
|
|
35
|
+
export type OAuthLocaleKey = keyof typeof en;
|
|
36
|
+
//# sourceMappingURL=locales.d.ts.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** Browser state machine for the plugin-owned OAuth WebSocket. */
|
|
2
|
+
import type { AccountView, PromptView, ProviderId, ServerMessage } from '../protocol.js';
|
|
3
|
+
export interface NoticeView {
|
|
4
|
+
message: string;
|
|
5
|
+
url?: string;
|
|
6
|
+
code?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ActivePromptView {
|
|
9
|
+
id: string;
|
|
10
|
+
prompt: PromptView;
|
|
11
|
+
}
|
|
12
|
+
export interface AttemptView {
|
|
13
|
+
id?: string;
|
|
14
|
+
provider: ProviderId;
|
|
15
|
+
phase: 'starting' | 'running' | 'authorized' | 'cancelled' | 'failed';
|
|
16
|
+
notice?: NoticeView;
|
|
17
|
+
prompt?: ActivePromptView;
|
|
18
|
+
error?: string;
|
|
19
|
+
errorDetail?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface OAuthAccountsSnapshot {
|
|
22
|
+
connection: 'connecting' | 'open' | 'reconnecting' | 'closed';
|
|
23
|
+
accounts: readonly AccountView[];
|
|
24
|
+
attempt?: AttemptView;
|
|
25
|
+
error?: string;
|
|
26
|
+
errorDetail?: string;
|
|
27
|
+
}
|
|
28
|
+
type Listener = () => void;
|
|
29
|
+
/** Remove interaction-only content once an authorization attempt settles. */
|
|
30
|
+
export declare function settleAttemptView(attempt: AttemptView, status: Extract<ServerMessage, {
|
|
31
|
+
type: 'settled';
|
|
32
|
+
}>['status']): AttemptView;
|
|
33
|
+
/** Hide a successful attempt after the account snapshot confirms its model route. */
|
|
34
|
+
export declare function reconcileAttemptView(attempt: AttemptView | undefined, accounts: readonly AccountView[]): AttemptView | undefined;
|
|
35
|
+
/** App-lifetime controller; reconnects without persisting provider messages or answers. */
|
|
36
|
+
export declare class OAuthAccountsController {
|
|
37
|
+
private snapshot;
|
|
38
|
+
private readonly listeners;
|
|
39
|
+
private socket;
|
|
40
|
+
private reconnectTimer;
|
|
41
|
+
private reconnectDelay;
|
|
42
|
+
private disposed;
|
|
43
|
+
constructor();
|
|
44
|
+
readonly subscribe: (listener: Listener) => (() => void);
|
|
45
|
+
readonly getSnapshot: () => OAuthAccountsSnapshot;
|
|
46
|
+
begin(provider: ProviderId): void;
|
|
47
|
+
respond(attemptId: string, promptId: string, value: string): void;
|
|
48
|
+
cancel(attemptId: string): void;
|
|
49
|
+
forget(provider: ProviderId): void;
|
|
50
|
+
retry(): void;
|
|
51
|
+
dispose(): void;
|
|
52
|
+
private connect;
|
|
53
|
+
private send;
|
|
54
|
+
private receive;
|
|
55
|
+
private update;
|
|
56
|
+
}
|
|
57
|
+
export {};
|
|
58
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/** Plugin-owned styles, injected and removed with the browser Cordis fiber. */
|
|
2
|
+
export declare const styles = "\n.dsh-oauth-section{display:flex;flex-direction:column;gap:12px;max-width:720px;color:var(--dsw-alias-label-primary)}\n.dsh-oauth-title{margin:0;font-size:16px;line-height:24px;font-weight:500}\n.dsh-oauth-intro,.dsh-oauth-muted{margin:0;font-size:13px;line-height:20px;color:var(--dsw-alias-label-tertiary)}\n.dsh-oauth-error{display:flex;flex-direction:column;gap:6px;margin:0;padding:8px 10px;border-radius:8px;background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px}.dsh-oauth-error p{margin:0}.dsh-oauth-error pre{box-sizing:border-box;max-width:100%;max-height:320px;margin:0;padding:8px;border:1px solid var(--dsw-alias-border-l2);border-radius:6px;overflow:auto;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-primary);font:11px/17px ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;white-space:pre-wrap;overflow-wrap:anywhere}.dsh-oauth-error-details summary{cursor:pointer;color:var(--dsw-alias-label-secondary);user-select:none}.dsh-oauth-error-details[open] summary{margin-bottom:6px}\n.dsh-oauth-list{display:flex;flex-direction:column;gap:8px;margin:4px 0 0;padding:0;list-style:none}\n.dsh-oauth-card{display:flex;flex-direction:column;gap:10px;padding:12px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px}\n.dsh-oauth-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.dsh-oauth-name{font-size:14px;font-weight:500}.dsh-oauth-state{display:inline-flex;align-items:center;gap:6px;padding:3px 8px;border-radius:999px;background:var(--dsw-alias-interactive-bg-hover);font-size:12px;color:var(--dsw-alias-label-secondary)}\n.dsh-oauth-dot{width:7px;height:7px;border-radius:50%;background:var(--dsw-alias-label-tertiary)}.dsh-oauth-state[data-state=ready] .dsh-oauth-dot{background:var(--dsw-alias-state-success-primary)}.dsh-oauth-state[data-state=warning] .dsh-oauth-dot{background:var(--dsw-alias-state-error-primary)}.dsh-oauth-state[data-state=authorizing] .dsh-oauth-dot{background:var(--dsw-alias-button-info-fill)}\n.dsh-oauth-actions{display:flex;gap:6px;margin-left:auto}.dsh-oauth-button{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;min-height:30px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:15px;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;line-height:18px;cursor:pointer}.dsh-oauth-button[data-variant=primary]{border-color:transparent;background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.dsh-oauth-button[data-variant=danger]{border-color:transparent;color:var(--dsw-alias-state-error-primary)}.dsh-oauth-button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.dsh-oauth-button[data-variant=primary]:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover);color:var(--dsw-alias-label-primary-foreground)}.dsh-oauth-button[data-variant=danger]:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}.dsh-oauth-button:focus-visible{outline:none;box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}.dsh-oauth-button:disabled{cursor:not-allowed;opacity:.4}\n.dsh-oauth-flow{display:flex;flex-direction:column;gap:8px;padding-top:10px;border-top:1px solid var(--dsw-alias-border-l3);font-size:13px;line-height:20px}.dsh-oauth-link{display:grid;grid-template-columns:minmax(0,1fr) auto auto;align-items:center;gap:8px;padding:9px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:9px;background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);text-decoration:none}.dsh-oauth-link:hover{background:var(--dsw-alias-interactive-bg-hover-solid)}.dsh-oauth-link-label{font-weight:500}.dsh-oauth-link-host{max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-tertiary);font-size:12px}.dsh-oauth-link-icon{color:var(--dsw-alias-brand-text)}.dsh-oauth-code{display:flex;align-items:center;gap:8px}.dsh-oauth-code code{padding:5px 8px;border-radius:6px;background:var(--dsw-alias-bg-module-platform);font-size:14px;letter-spacing:.08em}\n.dsh-oauth-prompt{display:flex;flex-direction:column;gap:7px}.dsh-oauth-input,.dsh-oauth-select{box-sizing:border-box;width:100%;height:34px;padding:0 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-primary)}\n";
|
|
3
|
+
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/** Shared browser/Host wire vocabulary for the OAuth account surface. */
|
|
2
|
+
export declare const OAUTH_SOCKET_PATH = "/_edge-sky/dsh-oauth";
|
|
3
|
+
export declare const OAUTH_SOCKET_PROTOCOL = "dsh-oauth-v1";
|
|
4
|
+
export declare const MAX_FRAME_BYTES: number;
|
|
5
|
+
export declare const MAX_ANSWER_LENGTH: number;
|
|
6
|
+
export declare const PROVIDERS: readonly [{
|
|
7
|
+
readonly id: "openai-codex";
|
|
8
|
+
readonly key: "llm-pi-ai/openai-codex";
|
|
9
|
+
readonly fallbackLabel: "OpenAI Codex";
|
|
10
|
+
readonly modelGroupLabel: "OpenAI Codex (OAuth)";
|
|
11
|
+
}, {
|
|
12
|
+
readonly id: "github-copilot";
|
|
13
|
+
readonly key: "llm-pi-ai/github-copilot";
|
|
14
|
+
readonly fallbackLabel: "GitHub Copilot";
|
|
15
|
+
readonly modelGroupLabel: "GitHub Copilot (OAuth)";
|
|
16
|
+
}];
|
|
17
|
+
export type ProviderId = (typeof PROVIDERS)[number]['id'];
|
|
18
|
+
export interface AccountView {
|
|
19
|
+
provider: ProviderId;
|
|
20
|
+
label: string;
|
|
21
|
+
available: boolean;
|
|
22
|
+
configured: boolean;
|
|
23
|
+
/** Whether llm-pi-ai currently exposes this OAuth provider as a model route. */
|
|
24
|
+
modelsEnabled: boolean;
|
|
25
|
+
writable: boolean;
|
|
26
|
+
inFlight: boolean;
|
|
27
|
+
}
|
|
28
|
+
export type PromptView = {
|
|
29
|
+
kind: 'text';
|
|
30
|
+
message: string;
|
|
31
|
+
placeholder?: string;
|
|
32
|
+
/** Whether an empty response has provider-defined meaning. */
|
|
33
|
+
allowEmpty?: boolean;
|
|
34
|
+
} | {
|
|
35
|
+
kind: 'secret';
|
|
36
|
+
message: string;
|
|
37
|
+
placeholder?: string;
|
|
38
|
+
} | {
|
|
39
|
+
kind: 'select';
|
|
40
|
+
message: string;
|
|
41
|
+
options: readonly {
|
|
42
|
+
id: string;
|
|
43
|
+
label: string;
|
|
44
|
+
description?: string;
|
|
45
|
+
}[];
|
|
46
|
+
};
|
|
47
|
+
export type ClientCommand = {
|
|
48
|
+
type: 'refresh';
|
|
49
|
+
requestId: string;
|
|
50
|
+
} | {
|
|
51
|
+
type: 'begin';
|
|
52
|
+
requestId: string;
|
|
53
|
+
provider: ProviderId;
|
|
54
|
+
} | {
|
|
55
|
+
type: 'respond';
|
|
56
|
+
requestId: string;
|
|
57
|
+
attemptId: string;
|
|
58
|
+
promptId: string;
|
|
59
|
+
value: string;
|
|
60
|
+
} | {
|
|
61
|
+
type: 'cancel';
|
|
62
|
+
requestId: string;
|
|
63
|
+
attemptId: string;
|
|
64
|
+
} | {
|
|
65
|
+
type: 'forget';
|
|
66
|
+
requestId: string;
|
|
67
|
+
provider: ProviderId;
|
|
68
|
+
};
|
|
69
|
+
export type OAuthErrorCode = 'invalid-message' | 'unsupported-provider' | 'authorization-unavailable' | 'busy' | 'invalid-attempt' | 'invalid-prompt' | 'credential-read-only' | 'model-route-unavailable' | 'sign-in-failed' | 'operation-failed';
|
|
70
|
+
export type ServerMessage = {
|
|
71
|
+
type: 'snapshot';
|
|
72
|
+
requestId?: string;
|
|
73
|
+
accounts: readonly AccountView[];
|
|
74
|
+
} | {
|
|
75
|
+
type: 'started';
|
|
76
|
+
requestId: string;
|
|
77
|
+
attemptId: string;
|
|
78
|
+
provider: ProviderId;
|
|
79
|
+
} | {
|
|
80
|
+
type: 'notice';
|
|
81
|
+
attemptId: string;
|
|
82
|
+
message: string;
|
|
83
|
+
url?: string;
|
|
84
|
+
code?: string;
|
|
85
|
+
} | {
|
|
86
|
+
type: 'prompt';
|
|
87
|
+
attemptId: string;
|
|
88
|
+
promptId: string;
|
|
89
|
+
prompt: PromptView;
|
|
90
|
+
} | {
|
|
91
|
+
type: 'prompt-withdrawn';
|
|
92
|
+
attemptId: string;
|
|
93
|
+
promptId: string;
|
|
94
|
+
} | {
|
|
95
|
+
type: 'settled';
|
|
96
|
+
attemptId: string;
|
|
97
|
+
status: 'authorized' | 'cancelled' | 'failed';
|
|
98
|
+
} | {
|
|
99
|
+
type: 'ack';
|
|
100
|
+
requestId: string;
|
|
101
|
+
} | {
|
|
102
|
+
type: 'error';
|
|
103
|
+
requestId?: string;
|
|
104
|
+
attemptId?: string;
|
|
105
|
+
code: OAuthErrorCode;
|
|
106
|
+
message: string;
|
|
107
|
+
/** Bounded, credential-redacted Host diagnostic for optional UI expansion. */
|
|
108
|
+
detail?: string;
|
|
109
|
+
};
|
|
110
|
+
export type CommandParseResult = {
|
|
111
|
+
ok: true;
|
|
112
|
+
value: ClientCommand;
|
|
113
|
+
} | {
|
|
114
|
+
ok: false;
|
|
115
|
+
requestId?: string;
|
|
116
|
+
message: string;
|
|
117
|
+
};
|
|
118
|
+
export declare function isProviderId(value: unknown): value is ProviderId;
|
|
119
|
+
/** Parse one untrusted browser frame without retaining its raw text. */
|
|
120
|
+
export declare function parseClientCommand(raw: string): CommandParseResult;
|
|
121
|
+
//# sourceMappingURL=protocol.d.ts.map
|
package/package.json
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@edge-sky/dsh-oauth-adapter",
|
|
3
|
+
"description": "Web OAuth account surface for official DSH authorization flows",
|
|
4
|
+
"version": "0.1.1-rc.10",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "edge-sky",
|
|
7
|
+
"url": "https://github.com/edge-sky"
|
|
8
|
+
},
|
|
9
|
+
"publishConfig": {
|
|
10
|
+
"access": "public"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/edge-sky/dsh-oauth.git"
|
|
15
|
+
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": "^22.19.0 || >=24.0.0"
|
|
18
|
+
},
|
|
19
|
+
"type": "module",
|
|
20
|
+
"main": "lib/index.js",
|
|
21
|
+
"types": "lib/index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./lib/index.d.ts",
|
|
25
|
+
"default": "./lib/index.js"
|
|
26
|
+
},
|
|
27
|
+
"./invariant": {
|
|
28
|
+
"types": "./lib/invariant.d.ts",
|
|
29
|
+
"default": "./lib/invariant.js"
|
|
30
|
+
},
|
|
31
|
+
"./authorization-fallback": {
|
|
32
|
+
"types": "./lib/authorization-fallback.d.ts",
|
|
33
|
+
"default": "./lib/authorization-fallback.js"
|
|
34
|
+
},
|
|
35
|
+
"./client": {
|
|
36
|
+
"types": "./lib/types/client/index.d.ts",
|
|
37
|
+
"default": "./lib/client.js"
|
|
38
|
+
},
|
|
39
|
+
"./src/*": "./src/*",
|
|
40
|
+
"./package.json": "./package.json"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"cordis.patch.yml",
|
|
44
|
+
"lib/**/*.js",
|
|
45
|
+
"lib/**/*.d.ts"
|
|
46
|
+
],
|
|
47
|
+
"license": "MIT",
|
|
48
|
+
"dsh": {
|
|
49
|
+
"bundle": {
|
|
50
|
+
"patch": "./cordis.patch.yml"
|
|
51
|
+
},
|
|
52
|
+
"client": {
|
|
53
|
+
"inject": [
|
|
54
|
+
"@deepseek-ai/dsh-client-runtime",
|
|
55
|
+
"@deepseek-ai/dsh-client-ui-settings",
|
|
56
|
+
"@deepseek-ai/dsh-client-locale"
|
|
57
|
+
],
|
|
58
|
+
"platform": "web"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"peerDependencies": {
|
|
62
|
+
"@deepseek-ai/cordis": ">=4.0.1",
|
|
63
|
+
"@deepseek-ai/dsh-client-locale": ">=0.1.1-rc.2",
|
|
64
|
+
"@deepseek-ai/dsh-client-runtime": ">=0.1.1-rc.2",
|
|
65
|
+
"@deepseek-ai/dsh-client-ui-settings": ">=0.1.1-rc.2",
|
|
66
|
+
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.1-rc.2",
|
|
67
|
+
"@deepseek-ai/dsh-credentials": ">=0.1.1-rc.2",
|
|
68
|
+
"@deepseek-ai/dsh-host-webserver": ">=0.1.1-rc.2",
|
|
69
|
+
"@deepseek-ai/dsh-invariants": ">=0.1.1-rc.2",
|
|
70
|
+
"@deepseek-ai/dsh-llm": ">=0.1.1-rc.2",
|
|
71
|
+
"@deepseek-ai/dsh-llm-pi-ai": ">=0.1.1-rc.2",
|
|
72
|
+
"@deepseek-ai/dsh-settings": ">=0.1.1-rc.2",
|
|
73
|
+
"react": ">=18.2.0"
|
|
74
|
+
},
|
|
75
|
+
"peerDependenciesMeta": {
|
|
76
|
+
"@deepseek-ai/cordis": {
|
|
77
|
+
"optional": true
|
|
78
|
+
},
|
|
79
|
+
"@deepseek-ai/dsh-client-locale": {
|
|
80
|
+
"optional": true
|
|
81
|
+
},
|
|
82
|
+
"@deepseek-ai/dsh-client-runtime": {
|
|
83
|
+
"optional": true
|
|
84
|
+
},
|
|
85
|
+
"@deepseek-ai/dsh-client-ui-settings": {
|
|
86
|
+
"optional": true
|
|
87
|
+
},
|
|
88
|
+
"@deepseek-ai/dsh-client-ui-slots": {
|
|
89
|
+
"optional": true
|
|
90
|
+
},
|
|
91
|
+
"@deepseek-ai/dsh-credentials": {
|
|
92
|
+
"optional": true
|
|
93
|
+
},
|
|
94
|
+
"@deepseek-ai/dsh-host-webserver": {
|
|
95
|
+
"optional": true
|
|
96
|
+
},
|
|
97
|
+
"@deepseek-ai/dsh-invariants": {
|
|
98
|
+
"optional": true
|
|
99
|
+
},
|
|
100
|
+
"@deepseek-ai/dsh-llm": {
|
|
101
|
+
"optional": true
|
|
102
|
+
},
|
|
103
|
+
"@deepseek-ai/dsh-llm-pi-ai": {
|
|
104
|
+
"optional": true
|
|
105
|
+
},
|
|
106
|
+
"@deepseek-ai/dsh-settings": {
|
|
107
|
+
"optional": true
|
|
108
|
+
},
|
|
109
|
+
"react": {
|
|
110
|
+
"optional": true
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"dependencies": {
|
|
114
|
+
"@deepseek-ai/dsh-authorization": ">=0.1.1-rc.2",
|
|
115
|
+
"@deepseek-ai/schemastery": "^3.18.1",
|
|
116
|
+
"ws": "^8.18.3"
|
|
117
|
+
},
|
|
118
|
+
"devDependencies": {
|
|
119
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
120
|
+
"@deepseek-ai/dsh-client-locale": "0.1.1-rc.2",
|
|
121
|
+
"@deepseek-ai/dsh-client-runtime": "0.1.1-rc.2",
|
|
122
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.1-rc.2",
|
|
123
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.1-rc.2",
|
|
124
|
+
"@deepseek-ai/dsh-credentials": "0.1.1-rc.2",
|
|
125
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.1-rc.2",
|
|
126
|
+
"@deepseek-ai/dsh-invariants": "0.1.1-rc.2",
|
|
127
|
+
"@deepseek-ai/dsh-llm": "0.1.1-rc.2",
|
|
128
|
+
"@deepseek-ai/dsh-llm-pi-ai": "0.1.1-rc.2",
|
|
129
|
+
"@deepseek-ai/dsh-settings": "0.1.1-rc.2",
|
|
130
|
+
"@types/node": "^22.20.0",
|
|
131
|
+
"@types/react": "~18.3.1",
|
|
132
|
+
"@types/react-dom": "~18.3.1",
|
|
133
|
+
"@types/ws": "^8.18.1",
|
|
134
|
+
"react": "^18.2.0",
|
|
135
|
+
"react-dom": "^18.2.0",
|
|
136
|
+
"tsdown": "^0.22.2",
|
|
137
|
+
"typescript": "^6.0.3",
|
|
138
|
+
"vitest": "^4.1.8"
|
|
139
|
+
},
|
|
140
|
+
"scripts": {
|
|
141
|
+
"build": "tsdown && pnpm run build:host && pnpm run build:client:types",
|
|
142
|
+
"build:host": "tsc -p tsconfig.json",
|
|
143
|
+
"build:client:types": "tsc -p tsconfig.client.json",
|
|
144
|
+
"test": "pnpm run build && vitest run",
|
|
145
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.client.json --noEmit"
|
|
146
|
+
}
|
|
147
|
+
}
|