brightspace-mcp-server 1.6.3 → 3.0.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 (127) hide show
  1. package/README.md +43 -35
  2. package/build/api/client.d.ts +37 -10
  3. package/build/api/client.d.ts.map +1 -1
  4. package/build/api/client.js +158 -100
  5. package/build/api/client.js.map +1 -1
  6. package/build/api/errors.d.ts +4 -0
  7. package/build/api/errors.d.ts.map +1 -1
  8. package/build/api/errors.js +7 -0
  9. package/build/api/errors.js.map +1 -1
  10. package/build/auth/auth-cooldown.d.ts +24 -0
  11. package/build/auth/auth-cooldown.d.ts.map +1 -0
  12. package/build/auth/auth-cooldown.js +60 -0
  13. package/build/auth/auth-cooldown.js.map +1 -0
  14. package/build/auth/auth-lock.d.ts +7 -0
  15. package/build/auth/auth-lock.d.ts.map +1 -0
  16. package/build/auth/auth-lock.js +162 -0
  17. package/build/auth/auth-lock.js.map +1 -0
  18. package/build/auth/auth-runner.d.ts +30 -9
  19. package/build/auth/auth-runner.d.ts.map +1 -1
  20. package/build/auth/auth-runner.js +171 -56
  21. package/build/auth/auth-runner.js.map +1 -1
  22. package/build/auth/browser-auth.d.ts +19 -87
  23. package/build/auth/browser-auth.d.ts.map +1 -1
  24. package/build/auth/browser-auth.js +266 -614
  25. package/build/auth/browser-auth.js.map +1 -1
  26. package/build/auth/browser-state-store.d.ts +19 -0
  27. package/build/auth/browser-state-store.d.ts.map +1 -0
  28. package/build/auth/browser-state-store.js +101 -0
  29. package/build/auth/browser-state-store.js.map +1 -0
  30. package/build/auth/credential-store.d.ts +29 -0
  31. package/build/auth/credential-store.d.ts.map +1 -0
  32. package/build/auth/credential-store.js +233 -0
  33. package/build/auth/credential-store.js.map +1 -0
  34. package/build/auth/encrypted-store.d.ts +25 -0
  35. package/build/auth/encrypted-store.d.ts.map +1 -0
  36. package/build/auth/encrypted-store.js +61 -0
  37. package/build/auth/encrypted-store.js.map +1 -0
  38. package/build/auth/legacy-profile.d.ts +3 -0
  39. package/build/auth/legacy-profile.d.ts.map +1 -0
  40. package/build/auth/legacy-profile.js +41 -0
  41. package/build/auth/legacy-profile.js.map +1 -0
  42. package/build/auth/legacy-state.d.ts +14 -0
  43. package/build/auth/legacy-state.d.ts.map +1 -0
  44. package/build/auth/legacy-state.js +107 -0
  45. package/build/auth/legacy-state.js.map +1 -0
  46. package/build/auth/purdue-sso.d.ts +25 -36
  47. package/build/auth/purdue-sso.d.ts.map +1 -1
  48. package/build/auth/purdue-sso.js +210 -191
  49. package/build/auth/purdue-sso.js.map +1 -1
  50. package/build/auth/session-store.d.ts +16 -38
  51. package/build/auth/session-store.d.ts.map +1 -1
  52. package/build/auth/session-store.js +157 -152
  53. package/build/auth/session-store.js.map +1 -1
  54. package/build/auth/sso-flow.d.ts +16 -4
  55. package/build/auth/sso-flow.d.ts.map +1 -1
  56. package/build/auth/sso-flow.js +24 -2
  57. package/build/auth/sso-flow.js.map +1 -1
  58. package/build/auth/suny-sso.d.ts +6 -2
  59. package/build/auth/suny-sso.d.ts.map +1 -1
  60. package/build/auth/suny-sso.js +17 -24
  61. package/build/auth/suny-sso.js.map +1 -1
  62. package/build/auth/token-manager.d.ts +10 -3
  63. package/build/auth/token-manager.d.ts.map +1 -1
  64. package/build/auth/token-manager.js +62 -26
  65. package/build/auth/token-manager.js.map +1 -1
  66. package/build/auth/token-mint.d.ts +2 -2
  67. package/build/auth/token-mint.d.ts.map +1 -1
  68. package/build/auth/token-mint.js +31 -9
  69. package/build/auth/token-mint.js.map +1 -1
  70. package/build/auth-cli.d.ts +1 -7
  71. package/build/auth-cli.d.ts.map +1 -1
  72. package/build/auth-cli.js +71 -70
  73. package/build/auth-cli.js.map +1 -1
  74. package/build/index.js +20 -64
  75. package/build/index.js.map +1 -1
  76. package/build/setup.js +44 -19
  77. package/build/setup.js.map +1 -1
  78. package/build/tools/tool-helpers.d.ts +7 -1
  79. package/build/tools/tool-helpers.d.ts.map +1 -1
  80. package/build/tools/tool-helpers.js +96 -11
  81. package/build/tools/tool-helpers.js.map +1 -1
  82. package/build/types/index.d.ts +6 -0
  83. package/build/types/index.d.ts.map +1 -1
  84. package/build/utils/browser-install.d.ts +23 -0
  85. package/build/utils/browser-install.d.ts.map +1 -0
  86. package/build/utils/browser-install.js +33 -0
  87. package/build/utils/browser-install.js.map +1 -0
  88. package/build/utils/commands.d.ts +26 -0
  89. package/build/utils/commands.d.ts.map +1 -0
  90. package/build/utils/commands.js +26 -0
  91. package/build/utils/commands.js.map +1 -0
  92. package/build/utils/config-store.d.ts +1 -0
  93. package/build/utils/config-store.d.ts.map +1 -1
  94. package/build/utils/config-store.js +3 -0
  95. package/build/utils/config-store.js.map +1 -1
  96. package/build/utils/config.d.ts +2 -1
  97. package/build/utils/config.d.ts.map +1 -1
  98. package/build/utils/config.js +32 -10
  99. package/build/utils/config.js.map +1 -1
  100. package/build/utils/download-errors.d.ts +45 -0
  101. package/build/utils/download-errors.d.ts.map +1 -0
  102. package/build/utils/download-errors.js +45 -0
  103. package/build/utils/download-errors.js.map +1 -0
  104. package/build/utils/download-helpers.d.ts.map +1 -1
  105. package/build/utils/download-helpers.js +2 -1
  106. package/build/utils/download-helpers.js.map +1 -1
  107. package/build/utils/file-validator.d.ts +1 -1
  108. package/build/utils/file-validator.d.ts.map +1 -1
  109. package/build/utils/file-validator.js +47 -7
  110. package/build/utils/file-validator.js.map +1 -1
  111. package/build/utils/install-sites.d.ts +61 -0
  112. package/build/utils/install-sites.d.ts.map +1 -0
  113. package/build/utils/install-sites.js +207 -0
  114. package/build/utils/install-sites.js.map +1 -0
  115. package/build/utils/secure-config.d.ts +6 -0
  116. package/build/utils/secure-config.d.ts.map +1 -0
  117. package/build/utils/secure-config.js +57 -0
  118. package/build/utils/secure-config.js.map +1 -0
  119. package/build/utils/self-update.d.ts +61 -0
  120. package/build/utils/self-update.d.ts.map +1 -0
  121. package/build/utils/self-update.js +92 -0
  122. package/build/utils/self-update.js.map +1 -0
  123. package/build/utils/update-checker.d.ts +85 -7
  124. package/build/utils/update-checker.d.ts.map +1 -1
  125. package/build/utils/update-checker.js +141 -36
  126. package/build/utils/update-checker.js.map +1 -1
  127. package/package.json +4 -2
@@ -10,20 +10,60 @@ import { discoverVersions } from "./version-discovery.js";
10
10
  import { ApiError, RateLimitError, NetworkError } from "./errors.js";
11
11
  import { withRetry, isRetryableFailure, retryAfterMsFrom } from "./retry.js";
12
12
  import { log } from "../utils/logger.js";
13
+ import { AUTH_COMMAND } from "../utils/commands.js";
14
+ /** An ordinary course HTML link to the login page is not an expired session. */
15
+ function isExpiredSessionRedirect(body, baseUrl) {
16
+ const expiredTarget = (target) => {
17
+ try {
18
+ const url = new URL(target.replace(/&/gi, "&").replace(/\\\//g, "/"), baseUrl);
19
+ return url.origin === new URL(baseUrl).origin && url.pathname === "/d2l/login" &&
20
+ url.searchParams.get("sessionExpired") === "1";
21
+ }
22
+ catch {
23
+ return false;
24
+ }
25
+ };
26
+ for (const script of body.matchAll(/<script\b[^>]*>([\s\S]*?)<\/script\s*>/gi)) {
27
+ const redirect = /(?:(?:window|document)\s*\.\s*)?location\s*(?:\.\s*(?:replace|assign)\s*\(\s*|(?:\.\s*href\s*)?=\s*)(["'])(.*?)\1/g;
28
+ for (const match of script[1].matchAll(redirect)) {
29
+ if (expiredTarget(match[2]))
30
+ return true;
31
+ }
32
+ }
33
+ for (const meta of body.matchAll(/<meta\b[^>]*>/gi)) {
34
+ const attributes = new Map([...meta[0].matchAll(/([\w-]+)\s*=\s*(["'])(.*?)\2/g)].map(match => [match[1].toLowerCase(), match[3]]));
35
+ if (attributes.get("http-equiv")?.toLowerCase() !== "refresh")
36
+ continue;
37
+ const target = attributes.get("content")?.match(/^\s*\d+(?:\.\d+)?\s*;\s*url\s*=\s*(.*?)\s*$/i)?.[1];
38
+ if (target && expiredTarget(target))
39
+ return true;
40
+ }
41
+ return false;
42
+ }
13
43
  /**
14
- * The marker in the HTML stub a dead session gets instead of a payload. D2L
15
- * answers HTTP 200 on that path, so the status alone cannot detect it.
44
+ * Stand-ins for the discovered LP and LE versions.
45
+ *
46
+ * lp(), le(), and leGlobal() are synchronous path builders called from about
47
+ * forty places across the tools, but the versions they need come from a
48
+ * network request. Emitting a placeholder and substituting it inside get()
49
+ * and getRaw() keeps that request off the startup path without turning every
50
+ * one of those call sites async, and it means a newly added tool cannot
51
+ * forget to wait for discovery: the path it builds carries the requirement.
52
+ *
53
+ * Braces are used because D2L paths never contain them, so a substitution can
54
+ * never collide with a real path segment.
16
55
  */
17
- const EXPIRED_SESSION_MARKER = "sessionExpired=1";
56
+ const LP_VERSION = "{lp}";
57
+ const LE_VERSION = "{le}";
18
58
  /**
19
59
  * D2L API client with authentication, caching, rate limiting, and version discovery.
20
60
  *
21
61
  * Key features:
22
- * - Auto-discovers LP/LE versions from /d2l/api/versions/
62
+ * - Auto-discovers LP/LE versions from /d2l/api/versions/ on the first request
23
63
  * - Supports both Bearer tokens and cookie-based auth (auto-detected via "cookie:" prefix)
24
64
  * - Client-side rate limiting using token bucket algorithm
25
65
  * - In-memory response caching with per-data-type TTLs
26
- * - 401 retry logic: retry once with fresh token, then clear and throw
66
+ * - 401 recovery: refresh the token before requesting browser authentication
27
67
  * - HTTPS-only enforcement
28
68
  * - Browser-like User-Agent for requests
29
69
  * - Raw response passthrough (no transformation)
@@ -38,6 +78,8 @@ export class D2LApiClient {
38
78
  onAuthExpired;
39
79
  retryConfig;
40
80
  versions = null;
81
+ /** Single in-flight discovery, so concurrent first requests share one fetch. */
82
+ versionsInFlight = null;
41
83
  constructor(options) {
42
84
  // HTTPS-only enforcement, on a parsed URL rather than a string prefix so
43
85
  // a malformed base cannot slip through as "not http".
@@ -69,23 +111,66 @@ export class D2LApiClient {
69
111
  log("DEBUG", `D2LApiClient initialized for ${this.baseUrl}`);
70
112
  }
71
113
  /**
72
- * Initialize the client by discovering API versions.
73
- * Must be called before making API requests.
114
+ * Discover the API versions, joining a discovery already in flight.
115
+ *
116
+ * Called from get() and getRaw() rather than at startup, so the server
117
+ * answers tools/list without touching the network and a user who never
118
+ * calls a tool never pays for a request. Nothing needs to call this
119
+ * directly.
120
+ */
121
+ async ensureVersions() {
122
+ if (this.versions)
123
+ return this.versions;
124
+ if (!this.versionsInFlight) {
125
+ // The latch is released by the flow that owns it, as it settles, so a
126
+ // failed discovery is never replayed: the request after a network blip
127
+ // starts a fresh fetch instead of inheriting the stale rejection.
128
+ const flow = discoverVersions(this.baseUrl, this.timeoutMs)
129
+ .then(versions => {
130
+ this.versions = versions;
131
+ log("INFO", `D2L API versions discovered: LP ${versions.lp}, LE ${versions.le}`);
132
+ return versions;
133
+ })
134
+ .finally(() => {
135
+ if (this.versionsInFlight === flow)
136
+ this.versionsInFlight = null;
137
+ });
138
+ this.versionsInFlight = flow;
139
+ }
140
+ return this.versionsInFlight;
141
+ }
142
+ /**
143
+ * Discover API versions eagerly. Idempotent, and no longer required:
144
+ * requests discover on demand. Kept for callers that want the network
145
+ * failure up front rather than on the first tool call.
74
146
  */
75
147
  async initialize() {
76
- this.versions = await discoverVersions(this.baseUrl, this.timeoutMs);
77
- log("INFO", `D2L API versions discovered: LP ${this.versions.lp}, LE ${this.versions.le}`);
148
+ await this.ensureVersions();
78
149
  }
79
150
  /**
80
151
  * Get discovered API versions.
81
- * @throws Error if initialize() hasn't been called yet
152
+ * @throws Error if no request has discovered them yet
82
153
  */
83
154
  get apiVersions() {
84
155
  if (!this.versions) {
85
- throw new Error("API client not initialized. Call initialize() before accessing apiVersions.");
156
+ throw new Error("API versions have not been discovered yet. They are fetched on the first request.");
86
157
  }
87
158
  return this.versions;
88
159
  }
160
+ /**
161
+ * Substitute the discovered versions into a path built by lp(), le(), or
162
+ * leGlobal(), discovering them first if no request has yet.
163
+ *
164
+ * A path that carries no placeholder is returned untouched and costs
165
+ * nothing: a bookmark page whose URL came back fully resolved from D2L
166
+ * does not trigger a discovery of its own.
167
+ */
168
+ async resolvePath(path) {
169
+ if (!path.includes(LP_VERSION) && !path.includes(LE_VERSION))
170
+ return path;
171
+ const { lp, le } = await this.ensureVersions();
172
+ return path.split(LP_VERSION).join(lp).split(LE_VERSION).join(le);
173
+ }
89
174
  /**
90
175
  * Make a GET request to the D2L API.
91
176
  *
@@ -96,30 +181,19 @@ export class D2LApiClient {
96
181
  * @throws NetworkError on network/fetch failures
97
182
  */
98
183
  async get(path, options) {
99
- // Check cache first
184
+ // Checked before the path is resolved, and keyed by the path as the caller
185
+ // wrote it, so a cached read needs neither version discovery nor a token.
100
186
  if (options?.ttl && this.cache.has(path)) {
101
187
  log("DEBUG", `Cache hit: ${path}`);
102
188
  return this.cache.get(path);
103
189
  }
104
- // Get authentication token, auto-reauth if expired
105
- let token = await this.tokenManager.getToken();
106
- if (!token) {
107
- token = await this.tryAutoReauth(path);
108
- }
109
- const authed = token;
110
- // Transient failures are retried inside the rate limiter, so every
111
- // attempt pays for a bucket token and a retry storm cannot bypass it.
112
- try {
113
- return await this.retrying(() => this.throttled(() => this.makeRequest(path, authed, options)));
114
- }
115
- catch (error) {
116
- if (error instanceof ApiError && error.status === 401) {
117
- // Final attempt: auto-reauth and retry once
118
- const freshToken = await this.tryAutoReauth(path);
119
- return await this.throttled(() => this.makeRequest(path, freshToken, options));
120
- }
121
- throw error;
190
+ const resolved = await this.resolvePath(path);
191
+ const data = await this.withAuthentication(resolved, token => this.makeRequest(resolved, token));
192
+ if (options?.ttl) {
193
+ this.cache.set(path, data, options.ttl);
194
+ log("DEBUG", `Cached response for ${path} (TTL: ${options.ttl}ms)`);
122
195
  }
196
+ return data;
123
197
  }
124
198
  /**
125
199
  * Make a GET request to the D2L API and return raw Response object.
@@ -132,23 +206,42 @@ export class D2LApiClient {
132
206
  * @throws NetworkError on network/fetch failures
133
207
  */
134
208
  async getRaw(path) {
135
- // Get authentication token, auto-reauth if expired
209
+ const resolved = await this.resolvePath(path);
210
+ return this.withAuthentication(resolved, token => this.makeRawRequest(resolved, token));
211
+ }
212
+ /** One HTTP refresh and at most one browser login per caller. */
213
+ async withAuthentication(path, request) {
136
214
  let token = await this.tokenManager.getToken();
215
+ let authenticated = false;
137
216
  if (!token) {
138
217
  token = await this.tryAutoReauth(path);
218
+ authenticated = true;
139
219
  }
140
- const authed = token;
220
+ const send = (current) => this.retrying(() => this.throttled(() => request(current)));
141
221
  try {
142
- return await this.retrying(() => this.throttled(() => this.makeRawRequest(path, authed)));
222
+ return await send(token);
143
223
  }
144
224
  catch (error) {
145
- if (error instanceof ApiError && error.status === 401) {
146
- // Final attempt: auto-reauth and retry once
147
- const freshToken = await this.tryAutoReauth(path);
148
- return await this.throttled(() => this.makeRawRequest(path, freshToken));
225
+ if (!(error instanceof ApiError) || error.status !== 401)
226
+ throw error;
227
+ if (authenticated)
228
+ throw error;
229
+ }
230
+ // A rejected JWT does not prove its underlying cookie is expired. Read a
231
+ // token written by another process or mint over HTTP before opening login.
232
+ // TokenRefreshError propagates here, so a temporary outage never starts MFA.
233
+ const fresh = await this.tokenManager.getToken(token.accessToken);
234
+ if (fresh && fresh.accessToken !== token.accessToken) {
235
+ try {
236
+ return await send(fresh);
237
+ }
238
+ catch (error) {
239
+ if (!(error instanceof ApiError) || error.status !== 401)
240
+ throw error;
149
241
  }
150
- throw error;
151
242
  }
243
+ const loggedIn = await this.tryAutoReauth(path, fresh?.accessToken ?? token.accessToken);
244
+ return send(loggedIn);
152
245
  }
153
246
  /** One rate limiter token per attempt. */
154
247
  async throttled(fn) {
@@ -167,12 +260,12 @@ export class D2LApiClient {
167
260
  * Attempt auto-reauthentication via the onAuthExpired callback.
168
261
  * If successful, returns the fresh token. Otherwise throws 401 ApiError.
169
262
  */
170
- async tryAutoReauth(path) {
263
+ async tryAutoReauth(path, rejectedAccessToken) {
171
264
  if (this.onAuthExpired) {
172
265
  log("INFO", "Attempting auto-reauthentication...");
173
266
  const success = await this.onAuthExpired();
174
267
  if (success) {
175
- const freshToken = await this.tokenManager.getToken();
268
+ const freshToken = await this.tokenManager.getToken(rejectedAccessToken);
176
269
  if (freshToken) {
177
270
  log("INFO", "Auto-reauthentication succeeded, retrying request");
178
271
  return freshToken;
@@ -180,39 +273,24 @@ export class D2LApiClient {
180
273
  }
181
274
  log("WARN", "Auto-reauthentication did not produce a valid token");
182
275
  }
183
- throw new ApiError(401, path, "Session expired. Please re-authenticate via brightspace-auth.");
276
+ throw new ApiError(401, path, `Session expired. Please re-authenticate via ${AUTH_COMMAND}.`);
184
277
  }
185
278
  /**
186
- * Internal method to make HTTP request with 401 retry logic.
279
+ * Make one HTTP request. Authentication recovery is shared with raw downloads.
187
280
  */
188
- async makeRequest(path, token, options, isRetry = false) {
281
+ async makeRequest(path, token) {
189
282
  const url = `${this.baseUrl}${path}`;
190
283
  const headers = this.buildAuthHeaders(token);
191
284
  try {
192
- log("DEBUG", `${isRetry ? "Retrying" : "Requesting"} GET ${path}`);
285
+ log("DEBUG", `Requesting GET ${path}`);
193
286
  const response = await fetch(url, {
194
287
  method: "GET",
195
288
  headers,
196
289
  signal: AbortSignal.timeout(this.timeoutMs),
197
290
  });
198
- // Handle 401 with retry logic
291
+ // Preserve cookie material: a 401 only rejects this access token.
199
292
  if (response.status === 401) {
200
- if (isRetry) {
201
- // Second 401 - clear token and throw
202
- log("DEBUG", "Second 401 response, clearing token");
203
- await this.tokenManager.clearToken();
204
- throw new ApiError(401, path, "Session expired. Please re-authenticate via brightspace-auth.");
205
- }
206
- // First 401 - try to get fresher token
207
- log("DEBUG", "First 401 response, attempting retry with fresh token");
208
- const freshToken = await this.tokenManager.getToken();
209
- if (!freshToken || freshToken.accessToken === token.accessToken) {
210
- // No fresher token available
211
- await this.tokenManager.clearToken();
212
- throw new ApiError(401, path, "Session expired. Please re-authenticate via brightspace-auth.");
213
- }
214
- // Retry with fresh token
215
- return await this.makeRequest(path, freshToken, options, true);
293
+ throw new ApiError(401, path, "Brightspace rejected the access token.");
216
294
  }
217
295
  // Handle 429 rate limiting
218
296
  if (response.status === 429) {
@@ -242,17 +320,12 @@ export class D2LApiClient {
242
320
  catch {
243
321
  // Only now consider the stub: a real payload that merely mentions the
244
322
  // marker still parses, so it can never be misread as a dead session.
245
- if (responseBody.includes(EXPIRED_SESSION_MARKER)) {
323
+ if (isExpiredSessionRedirect(responseBody, this.baseUrl)) {
246
324
  log("DEBUG", "Response carried the session-expired stub, treating it as a 401");
247
- await this.tokenManager.clearToken();
248
- throw new ApiError(401, path, "Session expired. Please re-authenticate via brightspace-auth.");
325
+ throw new ApiError(401, path, `Session expired. Please re-authenticate via ${AUTH_COMMAND}.`);
249
326
  }
250
327
  throw new ApiError(response.status, path, `Expected JSON from ${path} but the body did not parse`);
251
328
  }
252
- if (options?.ttl) {
253
- this.cache.set(path, data, options.ttl);
254
- log("DEBUG", `Cached response for ${path} (TTL: ${options.ttl}ms)`);
255
- }
256
329
  return data;
257
330
  }
258
331
  catch (error) {
@@ -268,36 +341,21 @@ export class D2LApiClient {
268
341
  }
269
342
  }
270
343
  /**
271
- * Internal method to make HTTP request for raw binary data with 401 retry logic.
344
+ * Make one HTTP request for raw binary data.
272
345
  */
273
- async makeRawRequest(path, token, isRetry = false) {
346
+ async makeRawRequest(path, token) {
274
347
  const url = `${this.baseUrl}${path}`;
275
348
  const headers = this.buildAuthHeaders(token);
276
349
  try {
277
- log("DEBUG", `${isRetry ? "Retrying" : "Requesting"} GET ${path} (raw)`);
350
+ log("DEBUG", `Requesting GET ${path} (raw)`);
278
351
  const response = await fetch(url, {
279
352
  method: "GET",
280
353
  headers,
281
354
  signal: AbortSignal.timeout(this.timeoutMs),
282
355
  });
283
- // Handle 401 with retry logic
356
+ // Preserve cookie material for the shared HTTP refresh path.
284
357
  if (response.status === 401) {
285
- if (isRetry) {
286
- // Second 401 - clear token and throw
287
- log("DEBUG", "Second 401 response, clearing token");
288
- await this.tokenManager.clearToken();
289
- throw new ApiError(401, path, "Session expired. Please re-authenticate via brightspace-auth.");
290
- }
291
- // First 401 - try to get fresher token
292
- log("DEBUG", "First 401 response, attempting retry with fresh token");
293
- const freshToken = await this.tokenManager.getToken();
294
- if (!freshToken || freshToken.accessToken === token.accessToken) {
295
- // No fresher token available
296
- await this.tokenManager.clearToken();
297
- throw new ApiError(401, path, "Session expired. Please re-authenticate via brightspace-auth.");
298
- }
299
- // Retry with fresh token
300
- return await this.makeRawRequest(path, freshToken, true);
358
+ throw new ApiError(401, path, "Brightspace rejected the access token.");
301
359
  }
302
360
  // Handle 429 rate limiting
303
361
  if (response.status === 429) {
@@ -327,10 +385,9 @@ export class D2LApiClient {
327
385
  const contentType = (response.headers.get("content-type") ?? "").toLowerCase();
328
386
  if (contentType.startsWith("text/html")) {
329
387
  const body = await response.text();
330
- if (body.includes(EXPIRED_SESSION_MARKER)) {
388
+ if (isExpiredSessionRedirect(body, this.baseUrl)) {
331
389
  log("DEBUG", "File download answered with the session-expired stub, treating it as a 401");
332
- await this.tokenManager.clearToken();
333
- throw new ApiError(401, path, "Session expired. Please re-authenticate via brightspace-auth.");
390
+ throw new ApiError(401, path, `Session expired. Please re-authenticate via ${AUTH_COMMAND}.`);
334
391
  }
335
392
  // A legitimate HTML page: hand back an equivalent response with the
336
393
  // body we already consumed.
@@ -378,31 +435,32 @@ export class D2LApiClient {
378
435
  }
379
436
  /**
380
437
  * Build path for LP (Learning Platform) API endpoints.
438
+ *
439
+ * The version is left as a placeholder and substituted by get() or getRaw()
440
+ * once it has been discovered. See LP_VERSION above.
441
+ *
381
442
  * @param path - Path within LP API (e.g., "/users/whoami")
382
- * @returns Full versioned path (e.g., "/d2l/api/lp/1.56/users/whoami")
443
+ * @returns Versioned path template (e.g., "/d2l/api/lp/{lp}/users/whoami")
383
444
  */
384
445
  lp(path) {
385
- const { lp } = this.apiVersions;
386
- return `/d2l/api/lp/${lp}${path}`;
446
+ return `/d2l/api/lp/${LP_VERSION}${path}`;
387
447
  }
388
448
  /**
389
449
  * Build path for LE (Learning Environment) API endpoints with orgUnitId.
390
450
  * @param orgUnitId - Organizational unit ID (course ID)
391
451
  * @param path - Path within LE API (e.g., "/content/root/")
392
- * @returns Full versioned path (e.g., "/d2l/api/le/1.91/123456/content/root/")
452
+ * @returns Versioned path template (e.g., "/d2l/api/le/{le}/123456/content/root/")
393
453
  */
394
454
  le(orgUnitId, path) {
395
- const { le } = this.apiVersions;
396
- return `/d2l/api/le/${le}/${orgUnitId}${path}`;
455
+ return `/d2l/api/le/${LE_VERSION}/${orgUnitId}${path}`;
397
456
  }
398
457
  /**
399
458
  * Build path for global LE (Learning Environment) API endpoints without orgUnitId.
400
459
  * @param path - Path within LE API (e.g., "/enrollments/myenrollments/")
401
- * @returns Full versioned path (e.g., "/d2l/api/le/1.91/enrollments/myenrollments/")
460
+ * @returns Versioned path template (e.g., "/d2l/api/le/{le}/enrollments/myenrollments/")
402
461
  */
403
462
  leGlobal(path) {
404
- const { le } = this.apiVersions;
405
- return `/d2l/api/le/${le}${path}`;
463
+ return `/d2l/api/le/${LE_VERSION}${path}`;
406
464
  }
407
465
  /**
408
466
  * Clear all cached responses.
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,gBAAgB,EAAoB,MAAM,YAAY,CAAC;AAC/F,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAEzC;;;GAGG;AACH,MAAM,sBAAsB,GAAG,kBAAkB,CAAC;AAElD;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,YAAY;IACN,OAAO,CAAS;IAChB,YAAY,CAAsC;IAClD,KAAK,CAAW;IAChB,WAAW,CAAc;IACzB,SAAS,CAAY;IACrB,SAAS,CAAS;IAClB,aAAa,CAA0B;IACvC,WAAW,CAAc;IAClC,QAAQ,GAAuB,IAAI,CAAC;IAE5C,YAAY,OAA4B;QACtC,yEAAyE;QACzE,sDAAsD;QACtD,IAAI,UAAe,CAAC;QACpB,IAAI,CAAC;YACH,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,UAAU,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CACb,uFAAuF,CACxF,CAAC;QACJ,CAAC;QAED,oCAAoC;QACpC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QACzC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC;QAC7C,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;QAC3C,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;QAEvC,yCAAyC;QACzC,IAAI,CAAC,SAAS,GAAG,EAAE,GAAG,kBAAkB,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;QAEjE,oCAAoC;QACpC,IAAI,CAAC,KAAK,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI;YACjD,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,CAAC;SACd,CAAC;QACF,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAChC,eAAe,CAAC,QAAQ,EACxB,eAAe,CAAC,UAAU,CAC3B,CAAC;QAEF,GAAG,CAAC,OAAO,EAAE,gCAAgC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,UAAU;QACd,IAAI,CAAC,QAAQ,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACrE,GAAG,CACD,MAAM,EACN,mCAAmC,IAAI,CAAC,QAAQ,CAAC,EAAE,QAAQ,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAC9E,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,IAAI,WAAW;QACb,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CACb,6EAA6E,CAC9E,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,GAAG,CAAI,IAAY,EAAE,OAA0B;QACnD,oBAAoB;QACpB,IAAI,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,GAAG,CAAC,OAAO,EAAE,cAAc,IAAI,EAAE,CAAC,CAAC;YACnC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAM,CAAC;QACnC,CAAC;QAED,mDAAmD;QACnD,IAAI,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;QAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC;QAErB,mEAAmE;QACnE,sEAAsE;QACtE,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAC9B,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAI,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CACjE,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACtD,4CAA4C;gBAC5C,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;gBAClD,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAI,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;YACpF,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,mDAAmD;QACnD,IAAI,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;QAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC;QAErB,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAC9B,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CACxD,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACtD,4CAA4C;gBAC5C,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;gBAClD,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;YAC3E,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,0CAA0C;IAClC,KAAK,CAAC,SAAS,CAAI,EAAoB;QAC7C,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QACjC,OAAO,EAAE,EAAE,CAAC;IACd,CAAC;IAED,yEAAyE;IACjE,QAAQ,CAAI,EAAoB;QACtC,OAAO,SAAS,CAAC,EAAE,EAAE;YACnB,GAAG,IAAI,CAAC,WAAW;YACnB,WAAW,EAAE,kBAAkB;YAC/B,YAAY,EAAE,gBAAgB;SAC/B,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,aAAa,CAAC,IAAY;QACtC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,GAAG,CAAC,MAAM,EAAE,qCAAqC,CAAC,CAAC;YACnD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;YAC3C,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;gBACtD,IAAI,UAAU,EAAE,CAAC;oBACf,GAAG,CAAC,MAAM,EAAE,mDAAmD,CAAC,CAAC;oBACjE,OAAO,UAAU,CAAC;gBACpB,CAAC;YACH,CAAC;YACD,GAAG,CAAC,MAAM,EAAE,qDAAqD,CAAC,CAAC;QACrE,CAAC;QACD,MAAM,IAAI,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,+DAA+D,CAAC,CAAC;IACjG,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,WAAW,CACvB,IAAY,EACZ,KAAgB,EAChB,OAA0B,EAC1B,UAAmB,KAAK;QAExB,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAE7C,IAAI,CAAC;YACH,GAAG,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,QAAQ,IAAI,EAAE,CAAC,CAAC;YAEnE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,KAAK;gBACb,OAAO;gBACP,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;aAC5C,CAAC,CAAC;YAEH,8BAA8B;YAC9B,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,IAAI,OAAO,EAAE,CAAC;oBACZ,qCAAqC;oBACrC,GAAG,CAAC,OAAO,EAAE,qCAAqC,CAAC,CAAC;oBACpD,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC;oBACrC,MAAM,IAAI,QAAQ,CAChB,GAAG,EACH,IAAI,EACJ,+DAA+D,CAChE,CAAC;gBACJ,CAAC;gBAED,uCAAuC;gBACvC,GAAG,CAAC,OAAO,EAAE,uDAAuD,CAAC,CAAC;gBACtE,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;gBAEtD,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,WAAW,KAAK,KAAK,CAAC,WAAW,EAAE,CAAC;oBAChE,6BAA6B;oBAC7B,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC;oBACrC,MAAM,IAAI,QAAQ,CAChB,GAAG,EACH,IAAI,EACJ,+DAA+D,CAChE,CAAC;gBACJ,CAAC;gBAED,yBAAyB;gBACzB,OAAO,MAAM,IAAI,CAAC,WAAW,CAAI,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;YACpE,CAAC;YAED,2BAA2B;YAC3B,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;gBACvD,MAAM,iBAAiB,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAC5E,MAAM,IAAI,cAAc,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;YACpD,CAAC;YAED,gDAAgD;YAChD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC3C,MAAM,IAAI,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;YAC9C,CAAC;YAED,gCAAgC;YAChC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC3C,MAAM,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;YAC1D,CAAC;YAED,qEAAqE;YACrE,yEAAyE;YACzE,2EAA2E;YAC3E,yEAAyE;YACzE,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAE3C,IAAI,IAAO,CAAC;YACZ,IAAI,CAAC;gBACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAM,CAAC;YACvC,CAAC;YAAC,MAAM,CAAC;gBACP,sEAAsE;gBACtE,qEAAqE;gBACrE,IAAI,YAAY,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAAC;oBAClD,GAAG,CAAC,OAAO,EAAE,iEAAiE,CAAC,CAAC;oBAChF,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC;oBACrC,MAAM,IAAI,QAAQ,CAChB,GAAG,EACH,IAAI,EACJ,+DAA+D,CAChE,CAAC;gBACJ,CAAC;gBACD,MAAM,IAAI,QAAQ,CAChB,QAAQ,CAAC,MAAM,EACf,IAAI,EACJ,sBAAsB,IAAI,6BAA6B,CACxD,CAAC;YACJ,CAAC;YAED,IAAI,OAAO,EAAE,GAAG,EAAE,CAAC;gBACjB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;gBACxC,GAAG,CAAC,OAAO,EAAE,uBAAuB,IAAI,UAAU,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;YACtE,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,0BAA0B;YAC1B,IACE,KAAK,YAAY,QAAQ;gBACzB,KAAK,YAAY,cAAc;gBAC/B,KAAK,YAAY,YAAY,EAC7B,CAAC;gBACD,MAAM,KAAK,CAAC;YACd,CAAC;YAED,4BAA4B;YAC5B,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,MAAM,IAAI,YAAY,CACpB,cAAc,IAAI,YAAY,OAAO,EAAE,EACvC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAC3C,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc,CAC1B,IAAY,EACZ,KAAgB,EAChB,UAAmB,KAAK;QAExB,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAE7C,IAAI,CAAC;YACH,GAAG,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,QAAQ,IAAI,QAAQ,CAAC,CAAC;YAEzE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,KAAK;gBACb,OAAO;gBACP,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;aAC5C,CAAC,CAAC;YAEH,8BAA8B;YAC9B,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,IAAI,OAAO,EAAE,CAAC;oBACZ,qCAAqC;oBACrC,GAAG,CAAC,OAAO,EAAE,qCAAqC,CAAC,CAAC;oBACpD,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC;oBACrC,MAAM,IAAI,QAAQ,CAChB,GAAG,EACH,IAAI,EACJ,+DAA+D,CAChE,CAAC;gBACJ,CAAC;gBAED,uCAAuC;gBACvC,GAAG,CAAC,OAAO,EAAE,uDAAuD,CAAC,CAAC;gBACtE,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;gBAEtD,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,WAAW,KAAK,KAAK,CAAC,WAAW,EAAE,CAAC;oBAChE,6BAA6B;oBAC7B,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC;oBACrC,MAAM,IAAI,QAAQ,CAChB,GAAG,EACH,IAAI,EACJ,+DAA+D,CAChE,CAAC;gBACJ,CAAC;gBAED,yBAAyB;gBACzB,OAAO,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;YAC3D,CAAC;YAED,2BAA2B;YAC3B,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;gBACvD,MAAM,iBAAiB,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAC5E,MAAM,IAAI,cAAc,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;YACpD,CAAC;YAED,6DAA6D;YAC7D,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC3C,MAAM,IAAI,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;YAC9C,CAAC;YAED,8BAA8B;YAC9B,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,MAAM,IAAI,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,gBAAgB,CAAC,CAAC;YAClD,CAAC;YAED,gCAAgC;YAChC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC3C,MAAM,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;YAC1D,CAAC;YAED,kEAAkE;YAClE,iEAAiE;YACjE,qEAAqE;YACrE,iEAAiE;YACjE,uBAAuB;YACvB,MAAM,WAAW,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YAC/E,IAAI,WAAW,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;gBACxC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACnC,IAAI,IAAI,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAAC;oBAC1C,GAAG,CAAC,OAAO,EAAE,4EAA4E,CAAC,CAAC;oBAC3F,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC;oBACrC,MAAM,IAAI,QAAQ,CAChB,GAAG,EACH,IAAI,EACJ,+DAA+D,CAChE,CAAC;gBACJ,CAAC;gBACD,oEAAoE;gBACpE,4BAA4B;gBAC5B,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;oBACxB,MAAM,EAAE,QAAQ,CAAC,MAAM;oBACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;oBAC/B,OAAO,EAAE,QAAQ,CAAC,OAAO;iBAC1B,CAAC,CAAC;YACL,CAAC;YAED,4CAA4C;YAC5C,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,0BAA0B;YAC1B,IACE,KAAK,YAAY,QAAQ;gBACzB,KAAK,YAAY,cAAc;gBAC/B,KAAK,YAAY,YAAY,EAC7B,CAAC;gBACD,MAAM,KAAK,CAAC;YACd,CAAC;YAED,4BAA4B;YAC5B,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,MAAM,IAAI,YAAY,CACpB,cAAc,IAAI,YAAY,OAAO,EAAE,EACvC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAC3C,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,gBAAgB,CAAC,KAAgB;QACvC,MAAM,OAAO,GAA2B;YACtC,YAAY,EACV,gFAAgF;SACnF,CAAC;QAEF,8DAA8D;QAC9D,IAAI,KAAK,CAAC,WAAW,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5C,wDAAwD;YACxD,OAAO,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YACnD,GAAG,CAAC,OAAO,EAAE,mCAAmC,CAAC,CAAC;QACpD,CAAC;aAAM,CAAC;YACN,oBAAoB;YACpB,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,CAAC,WAAW,EAAE,CAAC;YACzD,GAAG,CAAC,OAAO,EAAE,mCAAmC,CAAC,CAAC;QACpD,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;OAIG;IACH,EAAE,CAAC,IAAY;QACb,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;QAChC,OAAO,eAAe,EAAE,GAAG,IAAI,EAAE,CAAC;IACpC,CAAC;IAED;;;;;OAKG;IACH,EAAE,CAAC,SAAiB,EAAE,IAAY;QAChC,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;QAChC,OAAO,eAAe,EAAE,IAAI,SAAS,GAAG,IAAI,EAAE,CAAC;IACjD,CAAC;IAED;;;;OAIG;IACH,QAAQ,CAAC,IAAY;QACnB,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;QAChC,OAAO,eAAe,EAAE,GAAG,IAAI,EAAE,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,GAAG,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;CACF"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
@@ -20,4 +20,8 @@ export declare class RateLimitError extends ApiError {
20
20
  export declare class NetworkError extends AuthError {
21
21
  constructor(message: string, cause?: Error);
22
22
  }
23
+ /** A temporary token-mint failure must never start browser authentication. */
24
+ export declare class TokenRefreshError extends NetworkError {
25
+ constructor(detail: string, cause?: Error);
26
+ }
23
27
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,qBAAa,QAAS,SAAQ,SAAS;aAEnB,MAAM,EAAE,MAAM;aACd,QAAQ,EAAE,MAAM;aAEhB,YAAY,CAAC,EAAE,MAAM;gBAHrB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChC,OAAO,EAAE,MAAM,EACC,YAAY,CAAC,EAAE,MAAM,YAAA,EACrC,KAAK,CAAC,EAAE,KAAK;CAKhB;AAGD,qBAAa,SAAU,SAAQ,QAAQ;gBAEnC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,KAAK;CAKhB;AAGD,qBAAa,cAAe,SAAQ,QAAQ;aAGxB,UAAU,CAAC,EAAE,MAAM;gBADnC,QAAQ,EAAE,MAAM,EACA,UAAU,CAAC,EAAE,MAAM,YAAA;CAQtC;AAID,qBAAa,YAAa,SAAQ,SAAS;gBAC7B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAI3C"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,qBAAa,QAAS,SAAQ,SAAS;aAEnB,MAAM,EAAE,MAAM;aACd,QAAQ,EAAE,MAAM;aAEhB,YAAY,CAAC,EAAE,MAAM;gBAHrB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChC,OAAO,EAAE,MAAM,EACC,YAAY,CAAC,EAAE,MAAM,YAAA,EACrC,KAAK,CAAC,EAAE,KAAK;CAKhB;AAGD,qBAAa,SAAU,SAAQ,QAAQ;gBAEnC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,KAAK;CAKhB;AAGD,qBAAa,cAAe,SAAQ,QAAQ;aAGxB,UAAU,CAAC,EAAE,MAAM;gBADnC,QAAQ,EAAE,MAAM,EACA,UAAU,CAAC,EAAE,MAAM,YAAA;CAQtC;AAID,qBAAa,YAAa,SAAQ,SAAS;gBAC7B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAI3C;AAED,8EAA8E;AAC9E,qBAAa,iBAAkB,SAAQ,YAAY;gBACrC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAI1C"}
@@ -44,4 +44,11 @@ export class NetworkError extends AuthError {
44
44
  this.name = "NetworkError";
45
45
  }
46
46
  }
47
+ /** A temporary token-mint failure must never start browser authentication. */
48
+ export class TokenRefreshError extends NetworkError {
49
+ constructor(detail, cause) {
50
+ super(`Token refresh is temporarily unavailable: ${detail}. Your saved session was retained. Try again later.`, cause);
51
+ this.name = "TokenRefreshError";
52
+ }
53
+ }
47
54
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,qCAAqC;AACrC,MAAM,OAAO,QAAS,SAAQ,SAAS;IAEnB;IACA;IAEA;IAJlB,YACkB,MAAc,EACd,QAAgB,EAChC,OAAe,EACC,YAAqB,EACrC,KAAa;QAEb,KAAK,CAAC,2BAA2B,MAAM,QAAQ,QAAQ,KAAK,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;QAN9D,WAAM,GAAN,MAAM,CAAQ;QACd,aAAQ,GAAR,QAAQ,CAAQ;QAEhB,iBAAY,GAAZ,YAAY,CAAS;QAIrC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF;AAED,iEAAiE;AACjE,MAAM,OAAO,SAAU,SAAQ,QAAQ;IACrC,YACE,MAAc,EACd,QAAgB,EAChB,OAAe,EACf,YAAqB,EACrB,KAAa;QAEb,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,2CAA2C;AAC3C,MAAM,OAAO,cAAe,SAAQ,QAAQ;IAGxB;IAFlB,YACE,QAAgB,EACA,UAAmB;QAEnC,MAAM,OAAO,GAAG,UAAU;YACxB,CAAC,CAAC,0CAA0C,UAAU,GAAG;YACzD,CAAC,CAAC,2BAA2B,CAAC;QAChC,KAAK,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QALd,eAAU,GAAV,UAAU,CAAS;QAMnC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,4CAA4C;AAC5C,2CAA2C;AAC3C,MAAM,OAAO,YAAa,SAAQ,SAAS;IACzC,YAAY,OAAe,EAAE,KAAa;QACxC,KAAK,CAAC,+BAA+B,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;QACvD,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,qCAAqC;AACrC,MAAM,OAAO,QAAS,SAAQ,SAAS;IAEnB;IACA;IAEA;IAJlB,YACkB,MAAc,EACd,QAAgB,EAChC,OAAe,EACC,YAAqB,EACrC,KAAa;QAEb,KAAK,CAAC,2BAA2B,MAAM,QAAQ,QAAQ,KAAK,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;QAN9D,WAAM,GAAN,MAAM,CAAQ;QACd,aAAQ,GAAR,QAAQ,CAAQ;QAEhB,iBAAY,GAAZ,YAAY,CAAS;QAIrC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF;AAED,iEAAiE;AACjE,MAAM,OAAO,SAAU,SAAQ,QAAQ;IACrC,YACE,MAAc,EACd,QAAgB,EAChB,OAAe,EACf,YAAqB,EACrB,KAAa;QAEb,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,2CAA2C;AAC3C,MAAM,OAAO,cAAe,SAAQ,QAAQ;IAGxB;IAFlB,YACE,QAAgB,EACA,UAAmB;QAEnC,MAAM,OAAO,GAAG,UAAU;YACxB,CAAC,CAAC,0CAA0C,UAAU,GAAG;YACzD,CAAC,CAAC,2BAA2B,CAAC;QAChC,KAAK,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QALd,eAAU,GAAV,UAAU,CAAS;QAMnC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,4CAA4C;AAC5C,2CAA2C;AAC3C,MAAM,OAAO,YAAa,SAAQ,SAAS;IACzC,YAAY,OAAe,EAAE,KAAa;QACxC,KAAK,CAAC,+BAA+B,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;QACvD,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED,8EAA8E;AAC9E,MAAM,OAAO,iBAAkB,SAAQ,YAAY;IACjD,YAAY,MAAc,EAAE,KAAa;QACvC,KAAK,CAAC,6CAA6C,MAAM,qDAAqD,EAAE,KAAK,CAAC,CAAC;QACvH,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * How long automatic sign-in pauses after a missed MFA prompt.
3
+ *
4
+ * Long enough to stop a hot loop of phone prompts, short enough that tapping
5
+ * the wrong number costs a coffee break rather than an afternoon. This was
6
+ * four hours, which meant one mistyped number disabled background sign-in
7
+ * until dinner, with nothing on screen explaining why.
8
+ */
9
+ export declare const MFA_COOLDOWN_MS: number;
10
+ export declare class AuthenticationCooldownError extends Error {
11
+ readonly retryAt: number;
12
+ readonly code = "AUTH_COOLDOWN";
13
+ constructor(retryAt: number);
14
+ }
15
+ /** Non-secret retry metadata. Call only while holding the authentication lock. */
16
+ export declare class AuthCooldown {
17
+ private readonly file;
18
+ constructor(sessionDir: string);
19
+ assertAllowed(): Promise<void>;
20
+ recordMfaFailure(): Promise<void>;
21
+ clear(): Promise<void>;
22
+ private write;
23
+ }
24
+ //# sourceMappingURL=auth-cooldown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-cooldown.d.ts","sourceRoot":"","sources":["../../src/auth/auth-cooldown.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,QAAgB,CAAC;AAE7C,qBAAa,2BAA4B,SAAQ,KAAK;aAExB,OAAO,EAAE,MAAM;IAD3C,QAAQ,CAAC,IAAI,mBAAmB;gBACJ,OAAO,EAAE,MAAM;CAU5C;AAED,kFAAkF;AAClF,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAClB,UAAU,EAAE,MAAM;IAIxB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAY9B,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAId,KAAK;CAMpB"}
@@ -0,0 +1,60 @@
1
+ import * as fs from "node:fs/promises";
2
+ import * as path from "node:path";
3
+ import { randomUUID } from "node:crypto";
4
+ import { AUTH_COMMAND } from "../utils/commands.js";
5
+ /**
6
+ * How long automatic sign-in pauses after a missed MFA prompt.
7
+ *
8
+ * Long enough to stop a hot loop of phone prompts, short enough that tapping
9
+ * the wrong number costs a coffee break rather than an afternoon. This was
10
+ * four hours, which meant one mistyped number disabled background sign-in
11
+ * until dinner, with nothing on screen explaining why.
12
+ */
13
+ export const MFA_COOLDOWN_MS = 5 * 60 * 1000;
14
+ export class AuthenticationCooldownError extends Error {
15
+ retryAt;
16
+ code = "AUTH_COOLDOWN";
17
+ constructor(retryAt) {
18
+ // Say it the way a person would. A timestamp tells someone staring at a
19
+ // stalled chat window nothing they can act on.
20
+ const minutes = Math.max(1, Math.ceil((retryAt - Date.now()) / 60000));
21
+ super(`The last sign-in prompt was not approved, so automatic sign-in is paused for ${minutes} more minute${minutes === 1 ? "" : "s"}. ` +
22
+ `To sign in right now, run this in a terminal: ${AUTH_COMMAND}`);
23
+ this.retryAt = retryAt;
24
+ this.name = "AuthenticationCooldownError";
25
+ }
26
+ }
27
+ /** Non-secret retry metadata. Call only while holding the authentication lock. */
28
+ export class AuthCooldown {
29
+ file;
30
+ constructor(sessionDir) {
31
+ this.file = path.join(sessionDir, "auth-status.json");
32
+ }
33
+ async assertAllowed() {
34
+ let content;
35
+ try {
36
+ content = await fs.readFile(this.file, "utf8");
37
+ }
38
+ catch (error) {
39
+ if (error.code === "ENOENT")
40
+ return;
41
+ throw error;
42
+ }
43
+ const status = JSON.parse(content);
44
+ if (typeof status.retryAt === "number" && status.retryAt > Date.now())
45
+ throw new AuthenticationCooldownError(status.retryAt);
46
+ }
47
+ async recordMfaFailure() {
48
+ await this.write({ retryAt: Date.now() + MFA_COOLDOWN_MS });
49
+ }
50
+ async clear() {
51
+ await this.write({ retryAt: 0 });
52
+ }
53
+ async write(status) {
54
+ await fs.mkdir(path.dirname(this.file), { recursive: true, mode: 0o700 });
55
+ const temporary = `${this.file}.${randomUUID()}.tmp`;
56
+ await fs.writeFile(temporary, JSON.stringify(status), { mode: 0o600, flag: "wx" });
57
+ await fs.rename(temporary, this.file);
58
+ }
59
+ }
60
+ //# sourceMappingURL=auth-cooldown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-cooldown.js","sourceRoot":"","sources":["../../src/auth/auth-cooldown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAE7C,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IAExB;IADnB,IAAI,GAAG,eAAe,CAAC;IAChC,YAA4B,OAAe;QACzC,wEAAwE;QACxE,+CAA+C;QAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;QACvE,KAAK,CACH,gFAAgF,OAAO,eAAe,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI;YAClI,iDAAiD,YAAY,EAAE,CAChE,CAAC;QAPwB,YAAO,GAAP,OAAO,CAAQ;QAQzC,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;IAC5C,CAAC;CACF;AAED,kFAAkF;AAClF,MAAM,OAAO,YAAY;IACN,IAAI,CAAS;IAC9B,YAAY,UAAkB;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,IAAI,OAAe,CAAC;QACpB,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO;YAC/D,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAyB,CAAC;QAC3D,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE;YAAE,MAAM,IAAI,2BAA2B,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/H,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,eAAe,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC;IAEO,KAAK,CAAC,KAAK,CAAC,MAA2B;QAC7C,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1E,MAAM,SAAS,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,UAAU,EAAE,MAAM,CAAC;QACrD,MAAM,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACnF,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ export declare class AuthenticationInProgressError extends Error {
2
+ readonly code = "AUTH_IN_PROGRESS";
3
+ constructor();
4
+ }
5
+ /** Acquire a process-shared lock without waiting or relying on its age. */
6
+ export declare function acquireProcessLock(lockPath: string): Promise<() => Promise<void>>;
7
+ //# sourceMappingURL=auth-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-lock.d.ts","sourceRoot":"","sources":["../../src/auth/auth-lock.ts"],"names":[],"mappings":"AAwCA,qBAAa,6BAA8B,SAAQ,KAAK;IACtD,QAAQ,CAAC,IAAI,sBAAsB;;CAKpC;AA2DD,2EAA2E;AAC3E,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAIvF"}