dsh-plugin-subscription-oauth 0.0.0-stage → 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.
Files changed (82) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +413 -2
  3. package/cordis.patch.yml +13 -0
  4. package/lib/auth/device-flow.d.ts +112 -0
  5. package/lib/auth/device-flow.js +319 -0
  6. package/lib/auth/device-id.d.ts +31 -0
  7. package/lib/auth/device-id.js +58 -0
  8. package/lib/auth/flow.d.ts +33 -0
  9. package/lib/auth/flow.js +12 -0
  10. package/lib/auth/glm-flow.d.ts +99 -0
  11. package/lib/auth/glm-flow.js +194 -0
  12. package/lib/auth/headers.d.ts +61 -0
  13. package/lib/auth/headers.js +106 -0
  14. package/lib/auth/pkce-flow.d.ts +78 -0
  15. package/lib/auth/pkce-flow.js +205 -0
  16. package/lib/auth/provider-controller.d.ts +241 -0
  17. package/lib/auth/provider-controller.js +502 -0
  18. package/lib/auth/registry.d.ts +91 -0
  19. package/lib/auth/registry.js +149 -0
  20. package/lib/auth/rpc.d.ts +31 -0
  21. package/lib/auth/rpc.js +200 -0
  22. package/lib/auth/store.d.ts +99 -0
  23. package/lib/auth/store.js +213 -0
  24. package/lib/auth/tokens.d.ts +76 -0
  25. package/lib/auth/tokens.js +103 -0
  26. package/lib/client/SubscriptionsSection.d.ts +34 -0
  27. package/lib/client/SubscriptionsSection.js +742 -0
  28. package/lib/client/index.d.ts +36 -0
  29. package/lib/client/index.js +47 -0
  30. package/lib/client/locales.d.ts +187 -0
  31. package/lib/client/locales.js +185 -0
  32. package/lib/client/styles.d.ts +18 -0
  33. package/lib/client/styles.js +257 -0
  34. package/lib/client/subscriptions-rpc.d.ts +24 -0
  35. package/lib/client/subscriptions-rpc.js +44 -0
  36. package/lib/client.js +2078 -0
  37. package/lib/client.js.map +1 -0
  38. package/lib/constants.d.ts +79 -0
  39. package/lib/constants.js +91 -0
  40. package/lib/errors.d.ts +28 -0
  41. package/lib/errors.js +34 -0
  42. package/lib/http.d.ts +24 -0
  43. package/lib/http.js +98 -0
  44. package/lib/index.d.ts +57 -0
  45. package/lib/index.js +185 -0
  46. package/lib/protocol.d.ts +316 -0
  47. package/lib/protocol.js +29 -0
  48. package/lib/providers/antigravity-catalog.d.ts +53 -0
  49. package/lib/providers/antigravity-catalog.js +269 -0
  50. package/lib/providers/antigravity.d.ts +331 -0
  51. package/lib/providers/antigravity.js +821 -0
  52. package/lib/providers/auto.d.ts +151 -0
  53. package/lib/providers/auto.js +351 -0
  54. package/lib/providers/catalog.d.ts +69 -0
  55. package/lib/providers/catalog.js +78 -0
  56. package/lib/providers/common.d.ts +51 -0
  57. package/lib/providers/common.js +169 -0
  58. package/lib/providers/glm-provider.d.ts +41 -0
  59. package/lib/providers/glm-provider.js +165 -0
  60. package/lib/providers/glm.d.ts +159 -0
  61. package/lib/providers/glm.js +445 -0
  62. package/lib/providers/grok.d.ts +224 -0
  63. package/lib/providers/grok.js +700 -0
  64. package/lib/providers/kimi-provider.d.ts +45 -0
  65. package/lib/providers/kimi-provider.js +148 -0
  66. package/lib/providers/kimi.d.ts +151 -0
  67. package/lib/providers/kimi.js +400 -0
  68. package/lib/providers/responses-stream.d.ts +58 -0
  69. package/lib/providers/responses-stream.js +115 -0
  70. package/lib/providers/usage.d.ts +65 -0
  71. package/lib/providers/usage.js +309 -0
  72. package/lib/settings.d.ts +122 -0
  73. package/lib/settings.js +333 -0
  74. package/lib/translate/antigravity-schema.d.ts +24 -0
  75. package/lib/translate/antigravity-schema.js +174 -0
  76. package/lib/translate/antigravity.d.ts +184 -0
  77. package/lib/translate/antigravity.js +419 -0
  78. package/lib/translate/responses.d.ts +156 -0
  79. package/lib/translate/responses.js +395 -0
  80. package/lib/translate/sse.d.ts +27 -0
  81. package/lib/translate/sse.js +82 -0
  82. package/package.json +126 -4
@@ -0,0 +1,241 @@
1
+ /**
2
+ * The per-provider login/lifecycle controller: the single place one route's
3
+ * Settings state is derived from.
4
+ *
5
+ * A login is completed by the *browser*, so `login()` returns as soon as a
6
+ * prompt exists and the attempt settles in the background; every later
7
+ * `status()` call reports whether it is still pending, and a failure is recorded
8
+ * so the card can show why instead of silently returning to "logged out".
9
+ *
10
+ * Everything provider-specific arrives through {@link ProviderSpec}, the token
11
+ * manager, and the login flow, so the same controller serves a device-flow
12
+ * provider and a loopback-redirect provider.
13
+ *
14
+ * @module dsh-plugin-subscription-oauth/auth/provider-controller
15
+ */
16
+ import type { DetailRow, LoginPrompt, ProviderStatus, ProviderUsage, UsageWindow } from '../protocol.js';
17
+ import type { CatalogEntry } from '../providers/catalog.js';
18
+ import type { ModelPreferences } from '../settings.js';
19
+ import type { AuthFlow } from './flow.js';
20
+ import type { SessionBase, TokenStore } from './store.js';
21
+ import type { TokenManager } from './tokens.js';
22
+ /** A login that has just started. */
23
+ export interface ProviderLoginStart {
24
+ prompt: LoginPrompt;
25
+ status: ProviderStatus;
26
+ }
27
+ /** A completed token refresh. */
28
+ export interface ProviderRefreshResult {
29
+ account: string;
30
+ expiresAt: number;
31
+ status: ProviderStatus;
32
+ }
33
+ /** A completed usage read, carrying this route's own status. */
34
+ export interface ProviderUsageResult {
35
+ usage: readonly ProviderUsage[];
36
+ error?: string;
37
+ status: ProviderStatus;
38
+ }
39
+ /** The provider-owned half of one route. */
40
+ export interface ProviderSpec<S extends SessionBase> {
41
+ /** Provider route key, e.g. `kimi`. */
42
+ readonly id: string;
43
+ readonly displayName: string;
44
+ /** Where a user manages the underlying subscription. */
45
+ readonly codeUrl?: string;
46
+ /** Absolute path of the credential file, for the manage dialog. */
47
+ readonly credentialFile: string;
48
+ /** Whether the live model list is consulted. */
49
+ readonly discovery: boolean;
50
+ /**
51
+ * What this route itself serves: its shipped and live-discovered models, without
52
+ * the ids the user added by hand.
53
+ *
54
+ * The pair with {@link ProviderSpec.catalog} is what separates a synced model from
55
+ * a manual entry once the adapter merges both into one list.
56
+ */
57
+ readonly catalogOwn?: () => readonly CatalogEntry[];
58
+ /** Context advertised for a model id the user added by hand. */
59
+ readonly fallbackContextWindow?: number;
60
+ /** Model the picker preselects. */
61
+ readonly defaultModel?: string;
62
+ /** The curated catalog, live ids included once discovery has run. */
63
+ catalog(): readonly CatalogEntry[];
64
+ /** Live model ids, or undefined when unavailable. */
65
+ discover(accessToken: string): Promise<readonly string[] | undefined>;
66
+ /** Connection facts for the manage dialog. */
67
+ details(): readonly DetailRow[];
68
+ /** Called with the live ids once discovery succeeded, so the route re-announces. */
69
+ applyDiscovery?(ids: readonly string[]): void;
70
+ /** Read one account's plan and metered allowances, when the provider states them. */
71
+ usage?(accessToken: string, account: string): Promise<ProviderUsageRead | undefined>;
72
+ }
73
+ /** What a provider's usage read returns, before the controller stamps it. */
74
+ export interface ProviderUsageRead {
75
+ plan?: string;
76
+ renewsAt?: number;
77
+ windows: readonly UsageWindow[];
78
+ /**
79
+ * Why these figures are not the provider's primary accounting.
80
+ *
81
+ * A route that had to publish a substitute says so here, and the note travels
82
+ * with the figures so the page never presents the substitute as the plan's own.
83
+ */
84
+ usageError?: string;
85
+ }
86
+ /** Constructor dependencies for {@link ProviderController}. */
87
+ export interface ProviderControllerOptions<S extends SessionBase> {
88
+ readonly spec: ProviderSpec<S>;
89
+ readonly store: TokenStore<S>;
90
+ readonly tokens: TokenManager<S>;
91
+ readonly flow: AuthFlow<S>;
92
+ /** Model-visibility preferences, shared across providers. */
93
+ readonly preferences: ModelPreferences;
94
+ /** Invoked when the catalog or its visibility changed, so the picker re-queries. */
95
+ readonly onCatalogChanged?: () => void;
96
+ readonly onWarn?: (message: string) => void;
97
+ }
98
+ export declare class ProviderController<S extends SessionBase> {
99
+ private readonly options;
100
+ /** Live catalog ids, once discovery succeeded this session. */
101
+ private discovered;
102
+ /** Last background failure a user should see. */
103
+ private lastError;
104
+ /** Most recent eager-refresh failure, cleared once a refresh succeeds. */
105
+ private lastRefreshError;
106
+ /**
107
+ * Usage figures recently read, keyed by account.
108
+ *
109
+ * The entry is a short-lived coalescing cache, not a stored reading: an
110
+ * allowance moves as the account is used, so a figure kept for the whole
111
+ * session would keep answering with the state of the first read and the card
112
+ * would look like it never noticed an update.
113
+ */
114
+ private readonly usageByAccount;
115
+ /** Why the last usage read failed, when it did. */
116
+ private usageError;
117
+ /** Accounts whose grant the provider refused, so only a new login helps. */
118
+ private readonly refused;
119
+ constructor(options: ProviderControllerOptions<S>);
120
+ /** Provider route key. */
121
+ get id(): string;
122
+ /** Human name for selectors and diagnostics. */
123
+ get displayName(): string;
124
+ /** Absolute path of the credential file this route reads. */
125
+ get credentialFile(): string;
126
+ /** Current state of the route. */
127
+ status(): Promise<ProviderStatus>;
128
+ /**
129
+ * Refresh the default account's token when it is at or near its margin.
130
+ *
131
+ * Best-effort by design: a transient failure leaves the stored session alone
132
+ * and the next model call retries. A permanent failure is recorded so the card
133
+ * can tell the user to sign in again instead of silently showing a dead token.
134
+ */
135
+ private refreshIfLapsing;
136
+ /** The catalog as the page lists it, in the user's order. */
137
+ private modelSummaries;
138
+ /** This route's catalog after the user's order and visibility are applied. */
139
+ private resolveOrdered;
140
+ /**
141
+ * Begin an interactive login, returning the prompt to display.
142
+ *
143
+ * The returned status is already `busy`, because the attempt is registered
144
+ * before this resolves; the login itself settles in the background.
145
+ *
146
+ * @param account - existing account key to replace, for a re-login.
147
+ * @returns the pending prompt plus a fresh status.
148
+ */
149
+ login(account?: string): Promise<ProviderLoginStart>;
150
+ /** Persist the account once the browser approves, or record why it did not. */
151
+ private completeLogin;
152
+ /** Abandon the pending authorization, when one exists. */
153
+ cancel(): Promise<ProviderStatus>;
154
+ /** Forget one account (the default one when none is named). */
155
+ logout(account?: string): Promise<ProviderStatus>;
156
+ /** Promote one account to default. */
157
+ setDefault(account: string): Promise<ProviderStatus>;
158
+ /**
159
+ * Refresh one account's access token now.
160
+ *
161
+ * @param account - account to refresh; the default one when omitted.
162
+ * @returns the refreshed expiry and a fresh status.
163
+ * @throws {ProviderError} with `REAUTH_REQUIRED` when the account must sign in again.
164
+ */
165
+ refresh(account?: string): Promise<ProviderRefreshResult>;
166
+ /**
167
+ * Re-read the endpoint's live model list.
168
+ *
169
+ * @param force - fetch again even when a list was already read this session.
170
+ * @returns a fresh status.
171
+ */
172
+ discover(force?: boolean): Promise<ProviderStatus>;
173
+ /**
174
+ * Drop hand-added ids the route's own catalog now covers.
175
+ *
176
+ * Discovery is the authority on what the endpoint serves, so once it reports an
177
+ * id the manual entry has done its job.
178
+ *
179
+ * @param ids - the ids discovery reported.
180
+ */
181
+ private forgetDiscovered;
182
+ /**
183
+ * Set whether one model appears in the session model picker.
184
+ *
185
+ * The route is re-announced so the picker re-queries the catalog; a model
186
+ * hidden here stays resolvable, so a session that already selected it keeps
187
+ * working.
188
+ *
189
+ * @param id - model id as the catalog reports it.
190
+ * @param visible - whether the picker should offer it.
191
+ * @returns a fresh status.
192
+ * @throws {ProviderError} with `MODEL_NOT_FOUND` when the id is not in the catalog.
193
+ */
194
+ setModelVisible(id: string, visible: boolean): Promise<ProviderStatus>;
195
+ /**
196
+ * Replace this route's model order with the arrangement the user dropped into
197
+ * place.
198
+ *
199
+ * The page sends the complete list it displays, so a drop is one atomic
200
+ * statement of intent rather than a sequence of moves. Ids are validated
201
+ * against the catalog first: a stale page could otherwise persist a list
202
+ * naming a model this build no longer has.
203
+ *
204
+ * @param ids - every catalog model id, in the order the user arranged them.
205
+ * @returns a fresh status.
206
+ * @throws {ProviderError} when an id is not a rankable catalog model.
207
+ */
208
+ setModelOrder(ids: readonly string[]): Promise<ProviderStatus>;
209
+ /**
210
+ * Add one model id by hand, for a model this build's catalog does not know yet.
211
+ *
212
+ * The endpoint is the only authority on which ids it serves, so the id is
213
+ * checked for shape rather than against a list: a model released after this
214
+ * build must be usable without waiting for a plugin update.
215
+ *
216
+ * @param id - the model id to publish on this route.
217
+ * @returns a fresh status.
218
+ * @throws {ProviderError} when the id is unusable or already known.
219
+ */
220
+ addModel(id: string): Promise<ProviderStatus>;
221
+ /**
222
+ * Forget one hand-added model id.
223
+ * @param id - the id to drop from this route.
224
+ * @returns a fresh status.
225
+ */
226
+ removeModel(id: string): Promise<ProviderStatus>;
227
+ /**
228
+ * Read every account's plan and metered allowances.
229
+ *
230
+ * A provider that states no usage answers with an empty list rather than an
231
+ * error, and one account's failure never hides the others' figures.
232
+ *
233
+ * @param force - read again even when figures were already read this session.
234
+ * @returns the figures plus a fresh status.
235
+ */
236
+ usage(force?: boolean): Promise<ProviderUsageResult>;
237
+ /** Re-read the credential file and the preferences, after an external change. */
238
+ reload(): Promise<ProviderStatus>;
239
+ }
240
+ /** Re-exported so provider modules need one import for their catalog types. */
241
+ export type { CatalogEntry, UsageWindow };