brightspace-mcp-server 1.5.1 → 1.6.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 (73) hide show
  1. package/README.md +2 -2
  2. package/build/api/cache.d.ts.map +1 -1
  3. package/build/api/cache.js +6 -0
  4. package/build/api/cache.js.map +1 -1
  5. package/build/api/client.d.ts +5 -0
  6. package/build/api/client.d.ts.map +1 -1
  7. package/build/api/client.js +57 -14
  8. package/build/api/client.js.map +1 -1
  9. package/build/api/paginate.d.ts +23 -0
  10. package/build/api/paginate.d.ts.map +1 -0
  11. package/build/api/paginate.js +94 -0
  12. package/build/api/paginate.js.map +1 -0
  13. package/build/api/retry.d.ts +42 -0
  14. package/build/api/retry.d.ts.map +1 -0
  15. package/build/api/retry.js +50 -0
  16. package/build/api/retry.js.map +1 -0
  17. package/build/api/types.d.ts +3 -0
  18. package/build/api/types.d.ts.map +1 -1
  19. package/build/api/types.js.map +1 -1
  20. package/build/auth/browser-auth.d.ts.map +1 -1
  21. package/build/auth/browser-auth.js +2 -1
  22. package/build/auth/browser-auth.js.map +1 -1
  23. package/build/auth/session-store.d.ts.map +1 -1
  24. package/build/auth/session-store.js +4 -4
  25. package/build/auth/session-store.js.map +1 -1
  26. package/build/index.js +3 -2
  27. package/build/index.js.map +1 -1
  28. package/build/tools/get-assignment-files.d.ts +12 -0
  29. package/build/tools/get-assignment-files.d.ts.map +1 -0
  30. package/build/tools/get-assignment-files.js +170 -0
  31. package/build/tools/get-assignment-files.js.map +1 -0
  32. package/build/tools/get-assignments.d.ts.map +1 -1
  33. package/build/tools/get-assignments.js +58 -27
  34. package/build/tools/get-assignments.js.map +1 -1
  35. package/build/tools/get-classlist-emails.d.ts.map +1 -1
  36. package/build/tools/get-classlist-emails.js +4 -6
  37. package/build/tools/get-classlist-emails.js.map +1 -1
  38. package/build/tools/get-course-content.d.ts.map +1 -1
  39. package/build/tools/get-course-content.js +12 -2
  40. package/build/tools/get-course-content.js.map +1 -1
  41. package/build/tools/get-my-courses.d.ts.map +1 -1
  42. package/build/tools/get-my-courses.js +4 -7
  43. package/build/tools/get-my-courses.js.map +1 -1
  44. package/build/tools/get-roster.d.ts.map +1 -1
  45. package/build/tools/get-roster.js +33 -24
  46. package/build/tools/get-roster.js.map +1 -1
  47. package/build/tools/index.d.ts +1 -0
  48. package/build/tools/index.d.ts.map +1 -1
  49. package/build/tools/index.js +1 -0
  50. package/build/tools/index.js.map +1 -1
  51. package/build/tools/schemas.d.ts +8 -0
  52. package/build/tools/schemas.d.ts.map +1 -1
  53. package/build/tools/schemas.js +14 -0
  54. package/build/tools/schemas.js.map +1 -1
  55. package/build/utils/atomic-write.d.ts +18 -0
  56. package/build/utils/atomic-write.d.ts.map +1 -0
  57. package/build/utils/atomic-write.js +84 -0
  58. package/build/utils/atomic-write.js.map +1 -0
  59. package/build/utils/config-store.d.ts.map +1 -1
  60. package/build/utils/config-store.js +2 -3
  61. package/build/utils/config-store.js.map +1 -1
  62. package/build/utils/logger.d.ts.map +1 -1
  63. package/build/utils/logger.js +45 -1
  64. package/build/utils/logger.js.map +1 -1
  65. package/build/utils/update-checker.d.ts +30 -5
  66. package/build/utils/update-checker.d.ts.map +1 -1
  67. package/build/utils/update-checker.js +79 -45
  68. package/build/utils/update-checker.js.map +1 -1
  69. package/build/utils/zip-extract.d.ts +15 -0
  70. package/build/utils/zip-extract.d.ts.map +1 -0
  71. package/build/utils/zip-extract.js +170 -0
  72. package/build/utils/zip-extract.js.map +1 -0
  73. package/package.json +1 -1
package/README.md CHANGED
@@ -71,7 +71,7 @@ You still need to run `npx brightspace-mcp-server setup` first to save your cred
71
71
 
72
72
  ## Session Expired?
73
73
 
74
- You should rarely see this. Access tokens are re-minted from your saved session cookie in the background (no browser, about 200 ms), and a browser only opens when the Brightspace session itself has ended, typically after days. If that automatic re-login fails, run:
74
+ You should rarely see this. Access tokens are re-minted from your saved session cookie in the background (no browser, about 200 ms), and a browser only opens when the Brightspace session itself has ended, typically after a day or two. If that automatic re-login fails, run:
75
75
 
76
76
  ```bash
77
77
  npx brightspace-mcp-server auth
@@ -98,7 +98,7 @@ npx brightspace-mcp-server auth
98
98
  - Your username and password stay on your machine in `~/.brightspace-mcp/config.json`, readable only by your user (mode 0600). They are typed into your school's real login page and nowhere else.
99
99
  - Session tokens and cookies live in `~/.d2l-session/`, encrypted with AES-256-GCM.
100
100
  - All traffic to Brightspace is HTTPS.
101
- - The only other network call is a version check against the npm registry on startup.
101
+ - On startup the server asks the npm registry whether a newer version exists. When running through `npx`, it clears this package's own stale npx cache directories so the next start downloads the new version. It never installs anything itself. Set `D2L_NO_UPDATE_CHECK=1` to turn the check off.
102
102
  - Read only: this server never submits, posts, or changes anything in Brightspace.
103
103
 
104
104
  ## Contributing & Forking
@@ -1 +1 @@
1
- {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/api/cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,qBAAa,QAAQ,CAAC,CAAC,GAAG,OAAO;IAC/B,OAAO,CAAC,KAAK,CAAoC;IAEjD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAgB/C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAK/B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAU5B,KAAK,IAAI,IAAI;IASb,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/api/cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,qBAAa,QAAQ,CAAC,CAAC,GAAG,OAAO;IAC/B,OAAO,CAAC,KAAK,CAAoC;IAEjD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAsB/C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAK/B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAU5B,KAAK,IAAI,IAAI;IASb,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
@@ -15,6 +15,12 @@ export class TTLCache {
15
15
  const timerId = setTimeout(() => {
16
16
  this.cache.delete(key);
17
17
  }, ttlMs);
18
+ // An idle cache entry must not hold the process open: a one hour
19
+ // enrollments TTL would otherwise keep the event loop alive after the
20
+ // last request has been answered.
21
+ if (typeof timerId.unref === "function") {
22
+ timerId.unref();
23
+ }
18
24
  // Store entry
19
25
  this.cache.set(key, { data: value, timerId });
20
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/api/cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,MAAM,OAAO,QAAQ;IACX,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEjD,GAAG,CAAC,GAAW,EAAE,KAAQ,EAAE,KAAa;QACtC,qCAAqC;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,QAAQ,EAAE,CAAC;YACb,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;QAED,yCAAyC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC,EAAE,KAAK,CAAC,CAAC;QAEV,cAAc;QACd,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,GAAG,CAAC,GAAW;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,OAAO,KAAK,EAAE,IAAI,CAAC;IACrB,CAAC;IAED,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,KAAK,EAAE,CAAC;YACV,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK;QACH,mBAAmB;QACnB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;QACD,YAAY;QACZ,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;CACF"}
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/api/cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,MAAM,OAAO,QAAQ;IACX,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEjD,GAAG,CAAC,GAAW,EAAE,KAAQ,EAAE,KAAa;QACtC,qCAAqC;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,QAAQ,EAAE,CAAC;YACb,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;QAED,yCAAyC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC,EAAE,KAAK,CAAC,CAAC;QACV,iEAAiE;QACjE,sEAAsE;QACtE,kCAAkC;QAClC,IAAI,OAAQ,OAAkC,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YACnE,OAAiC,CAAC,KAAK,EAAE,CAAC;QAC7C,CAAC;QAED,cAAc;QACd,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,GAAG,CAAC,GAAW;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,OAAO,KAAK,EAAE,IAAI,CAAC;IACrB,CAAC;IAED,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,KAAK,EAAE,CAAC;YACV,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK;QACH,mBAAmB;QACnB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;QACD,YAAY;QACZ,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;CACF"}
@@ -25,6 +25,7 @@ export declare class D2LApiClient {
25
25
  private readonly cacheTTLs;
26
26
  private readonly timeoutMs;
27
27
  private readonly onAuthExpired?;
28
+ private readonly retryConfig;
28
29
  private versions;
29
30
  constructor(options: D2LApiClientOptions);
30
31
  /**
@@ -60,6 +61,10 @@ export declare class D2LApiClient {
60
61
  * @throws NetworkError on network/fetch failures
61
62
  */
62
63
  getRaw(path: string): Promise<Response>;
64
+ /** One rate limiter token per attempt. */
65
+ private throttled;
66
+ /** Retry 429, 5xx, and network failures. A 401 is never retried here. */
67
+ private retrying;
63
68
  /**
64
69
  * Attempt auto-reauthentication via the onAuthExpired callback.
65
70
  * If successful, returns the fresh token. Otherwise throws 401 ApiError.
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAwB,MAAM,YAAY,CAAC;AAczF;;;;;;;;;;;;GAYG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsC;IACnE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAyB;IACxD,OAAO,CAAC,QAAQ,CAA4B;gBAEhC,OAAO,EAAE,mBAAmB;IA+BxC;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQjC;;;OAGG;IACH,IAAI,WAAW,IAAI,WAAW,CAO7B;IAED;;;;;;;;OAQG;IACG,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC;IA6BlE;;;;;;;;;OASG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAuB7C;;;OAGG;YACW,aAAa;IAgB3B;;OAEG;YACW,WAAW;IAyHzB;;OAEG;YACW,cAAc;IA6F5B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAoBxB;;;;OAIG;IACH,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAKxB;;;;;OAKG;IACH,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAK3C;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAK9B;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;OAEG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;CACF"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAwB,MAAM,YAAY,CAAC;AAezF;;;;;;;;;;;;GAYG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsC;IACnE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAyB;IACxD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAA4B;gBAEhC,OAAO,EAAE,mBAAmB;IAuCxC;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQjC;;;OAGG;IACH,IAAI,WAAW,IAAI,WAAW,CAO7B;IAED;;;;;;;;OAQG;IACG,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC;IA8BlE;;;;;;;;;OASG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAsB7C,0CAA0C;YAC5B,SAAS;IAKvB,yEAAyE;IACzE,OAAO,CAAC,QAAQ;IAQhB;;;OAGG;YACW,aAAa;IAgB3B;;OAEG;YACW,WAAW;IAyHzB;;OAEG;YACW,cAAc;IAuH5B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAoBxB;;;;OAIG;IACH,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAKxB;;;;;OAKG;IACH,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAK3C;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAK9B;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;OAEG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;CACF"}
@@ -8,6 +8,7 @@ import { TTLCache } from "./cache.js";
8
8
  import { TokenBucket } from "./rate-limiter.js";
9
9
  import { discoverVersions } from "./version-discovery.js";
10
10
  import { ApiError, RateLimitError, NetworkError } from "./errors.js";
11
+ import { withRetry, isRetryableFailure, retryAfterMsFrom } from "./retry.js";
11
12
  import { log } from "../utils/logger.js";
12
13
  /**
13
14
  * The marker in the HTML stub a dead session gets instead of a payload. D2L
@@ -35,10 +36,19 @@ export class D2LApiClient {
35
36
  cacheTTLs;
36
37
  timeoutMs;
37
38
  onAuthExpired;
39
+ retryConfig;
38
40
  versions = null;
39
41
  constructor(options) {
40
- // HTTPS-only enforcement
41
- if (options.baseUrl.startsWith("http://")) {
42
+ // HTTPS-only enforcement, on a parsed URL rather than a string prefix so
43
+ // a malformed base cannot slip through as "not http".
44
+ let parsedBase;
45
+ try {
46
+ parsedBase = new URL(options.baseUrl);
47
+ }
48
+ catch {
49
+ throw new Error(`Invalid D2L base URL: ${options.baseUrl}`);
50
+ }
51
+ if (parsedBase.protocol !== "https:") {
42
52
  throw new Error("HTTPS is required for D2L API client. HTTP URLs are not allowed for security reasons.");
43
53
  }
44
54
  // Strip trailing slash from baseUrl
@@ -46,6 +56,7 @@ export class D2LApiClient {
46
56
  this.tokenManager = options.tokenManager;
47
57
  this.timeoutMs = options.timeoutMs ?? 30_000;
48
58
  this.onAuthExpired = options.onAuthExpired;
59
+ this.retryConfig = options.retry ?? {};
49
60
  // Merge user-provided TTLs with defaults
50
61
  this.cacheTTLs = { ...DEFAULT_CACHE_TTLS, ...options.cacheTTLs };
51
62
  // Initialize cache and rate limiter
@@ -90,22 +101,22 @@ export class D2LApiClient {
90
101
  log("DEBUG", `Cache hit: ${path}`);
91
102
  return this.cache.get(path);
92
103
  }
93
- // Enforce rate limit
94
- await this.rateLimiter.consume();
95
- // Get authentication token — auto-reauth if expired
104
+ // Get authentication token, auto-reauth if expired
96
105
  let token = await this.tokenManager.getToken();
97
106
  if (!token) {
98
107
  token = await this.tryAutoReauth(path);
99
108
  }
100
- // Make request with retry logic
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.
101
112
  try {
102
- return await this.makeRequest(path, token, options);
113
+ return await this.retrying(() => this.throttled(() => this.makeRequest(path, authed, options)));
103
114
  }
104
115
  catch (error) {
105
116
  if (error instanceof ApiError && error.status === 401) {
106
117
  // Final attempt: auto-reauth and retry once
107
118
  const freshToken = await this.tryAutoReauth(path);
108
- return await this.makeRequest(path, freshToken, options);
119
+ return await this.throttled(() => this.makeRequest(path, freshToken, options));
109
120
  }
110
121
  throw error;
111
122
  }
@@ -121,26 +132,37 @@ export class D2LApiClient {
121
132
  * @throws NetworkError on network/fetch failures
122
133
  */
123
134
  async getRaw(path) {
124
- // Enforce rate limit
125
- await this.rateLimiter.consume();
126
- // Get authentication token — auto-reauth if expired
135
+ // Get authentication token, auto-reauth if expired
127
136
  let token = await this.tokenManager.getToken();
128
137
  if (!token) {
129
138
  token = await this.tryAutoReauth(path);
130
139
  }
131
- // Make request with retry logic
140
+ const authed = token;
132
141
  try {
133
- return await this.makeRawRequest(path, token);
142
+ return await this.retrying(() => this.throttled(() => this.makeRawRequest(path, authed)));
134
143
  }
135
144
  catch (error) {
136
145
  if (error instanceof ApiError && error.status === 401) {
137
146
  // Final attempt: auto-reauth and retry once
138
147
  const freshToken = await this.tryAutoReauth(path);
139
- return await this.makeRawRequest(path, freshToken);
148
+ return await this.throttled(() => this.makeRawRequest(path, freshToken));
140
149
  }
141
150
  throw error;
142
151
  }
143
152
  }
153
+ /** One rate limiter token per attempt. */
154
+ async throttled(fn) {
155
+ await this.rateLimiter.consume();
156
+ return fn();
157
+ }
158
+ /** Retry 429, 5xx, and network failures. A 401 is never retried here. */
159
+ retrying(fn) {
160
+ return withRetry(fn, {
161
+ ...this.retryConfig,
162
+ shouldRetry: isRetryableFailure,
163
+ retryAfterMs: retryAfterMsFrom,
164
+ });
165
+ }
144
166
  /**
145
167
  * Attempt auto-reauthentication via the onAuthExpired callback.
146
168
  * If successful, returns the fresh token. Otherwise throws 401 ApiError.
@@ -297,6 +319,27 @@ export class D2LApiClient {
297
319
  const responseText = await response.text();
298
320
  throw new ApiError(response.status, path, responseText);
299
321
  }
322
+ // A dead session answers a file request the same way it answers a
323
+ // JSON one: HTTP 200 carrying an HTML stub that redirects to the
324
+ // login page. Left alone, that stub would be saved to disk under the
325
+ // file's own name. Only HTML is inspected, so real downloads are
326
+ // never buffered here.
327
+ const contentType = (response.headers.get("content-type") ?? "").toLowerCase();
328
+ if (contentType.startsWith("text/html")) {
329
+ const body = await response.text();
330
+ if (body.includes(EXPIRED_SESSION_MARKER)) {
331
+ 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.");
334
+ }
335
+ // A legitimate HTML page: hand back an equivalent response with the
336
+ // body we already consumed.
337
+ return new Response(body, {
338
+ status: response.status,
339
+ statusText: response.statusText,
340
+ headers: response.headers,
341
+ });
342
+ }
300
343
  // Return raw response for caller to process
301
344
  return response;
302
345
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Purdue Brightspace MCP Server
3
+ * Copyright (c) 2026 Rohan Muppa. All rights reserved.
4
+ * Licensed under MIT - see LICENSE file for details.
5
+ */
6
+ import type { D2LApiClient } from "./client.js";
7
+ export interface PaginateOptions {
8
+ /** Cache TTL, passed through to the client on every page. */
9
+ ttl?: number;
10
+ }
11
+ /**
12
+ * Every item across every page of a { Items, PagingInfo } endpoint, in order.
13
+ */
14
+ export declare function fetchAllItems<T>(apiClient: D2LApiClient, firstPath: string, options?: PaginateOptions): Promise<T[]>;
15
+ /**
16
+ * Every object across every page of a { Objects, Next } endpoint, in order.
17
+ *
18
+ * Next arrives either as a full next-page URL or as a bare bookmark, so the
19
+ * absolute form is reduced to its path and query and anything else is treated
20
+ * as a bookmark against the first path.
21
+ */
22
+ export declare function fetchAllObjects<T>(apiClient: D2LApiClient, firstPath: string, options?: PaginateOptions): Promise<T[]>;
23
+ //# sourceMappingURL=paginate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paginate.d.ts","sourceRoot":"","sources":["../../src/api/paginate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAyBhD,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAQD;;GAEG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,SAAS,EAAE,YAAY,EACvB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,CAAC,EAAE,CAAC,CA6Bd;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,CAAC,EACrC,SAAS,EAAE,YAAY,EACvB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,CAAC,EAAE,CAAC,CA4Bd"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Purdue Brightspace MCP Server
3
+ * Copyright (c) 2026 Rohan Muppa. All rights reserved.
4
+ * Licensed under MIT - see LICENSE file for details.
5
+ */
6
+ import { log } from "../utils/logger.js";
7
+ /**
8
+ * Bookmark pagination for the two envelopes D2L answers with.
9
+ *
10
+ * Both loops are bounded twice over: a page ceiling, and a set of the
11
+ * bookmarks already followed. A server that keeps saying "there is more" and
12
+ * hands back the same bookmark would otherwise hang the tool forever.
13
+ */
14
+ const MAX_PAGES = 200;
15
+ /** The first path with a bookmark appended, opening the query string if needed. */
16
+ function withBookmark(firstPath, bookmark) {
17
+ const separator = firstPath.includes("?") ? "&" : "?";
18
+ return `${firstPath}${separator}bookmark=${encodeURIComponent(bookmark)}`;
19
+ }
20
+ /**
21
+ * Every item across every page of a { Items, PagingInfo } endpoint, in order.
22
+ */
23
+ export async function fetchAllItems(apiClient, firstPath, options) {
24
+ const items = [];
25
+ const seen = new Set();
26
+ let path = firstPath;
27
+ let pages = 0;
28
+ while (path !== null) {
29
+ if (pages >= MAX_PAGES) {
30
+ log("WARN", `Pagination stopped at the ${MAX_PAGES} page ceiling`, { firstPath });
31
+ break;
32
+ }
33
+ const response = await apiClient.get(path, options);
34
+ pages += 1;
35
+ items.push(...(response?.Items ?? []));
36
+ const paging = response?.PagingInfo;
37
+ const bookmark = paging?.Bookmark;
38
+ if (!paging?.HasMoreItems || !bookmark)
39
+ break;
40
+ if (seen.has(bookmark)) {
41
+ log("WARN", "Pagination stopped: the server repeated a bookmark", { firstPath });
42
+ break;
43
+ }
44
+ seen.add(bookmark);
45
+ path = withBookmark(firstPath, bookmark);
46
+ }
47
+ return items;
48
+ }
49
+ /**
50
+ * Every object across every page of a { Objects, Next } endpoint, in order.
51
+ *
52
+ * Next arrives either as a full next-page URL or as a bare bookmark, so the
53
+ * absolute form is reduced to its path and query and anything else is treated
54
+ * as a bookmark against the first path.
55
+ */
56
+ export async function fetchAllObjects(apiClient, firstPath, options) {
57
+ const objects = [];
58
+ const seen = new Set();
59
+ let path = firstPath;
60
+ let pages = 0;
61
+ while (path !== null) {
62
+ if (pages >= MAX_PAGES) {
63
+ log("WARN", `Pagination stopped at the ${MAX_PAGES} page ceiling`, { firstPath });
64
+ break;
65
+ }
66
+ const response = await apiClient.get(path, options);
67
+ pages += 1;
68
+ objects.push(...(response?.Objects ?? []));
69
+ const next = response?.Next;
70
+ if (!next)
71
+ break;
72
+ if (seen.has(next)) {
73
+ log("WARN", "Pagination stopped: the server repeated a next page", { firstPath });
74
+ break;
75
+ }
76
+ seen.add(next);
77
+ path = nextPath(firstPath, next);
78
+ }
79
+ return objects;
80
+ }
81
+ /** A Next value resolved to a request path. */
82
+ function nextPath(firstPath, next) {
83
+ if (/^https?:\/\//i.test(next)) {
84
+ const url = new URL(next);
85
+ return `${url.pathname}${url.search}`;
86
+ }
87
+ // A Next that begins with a slash is already a path, not a bookmark.
88
+ // Appending it as one would ask for a page that does not exist.
89
+ if (next.startsWith("/")) {
90
+ return next;
91
+ }
92
+ return withBookmark(firstPath, next);
93
+ }
94
+ //# sourceMappingURL=paginate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paginate.js","sourceRoot":"","sources":["../../src/api/paginate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Purdue Brightspace MCP Server
3
+ * Copyright (c) 2026 Rohan Muppa. All rights reserved.
4
+ * Licensed under MIT. See LICENSE file for details.
5
+ */
6
+ /**
7
+ * Retry transient failures with exponential backoff and jitter.
8
+ *
9
+ * What counts as transient is decided by the caller through `shouldRetry`,
10
+ * so this module knows nothing about HTTP. A 429 that names a Retry-After is
11
+ * honored verbatim, even past `maxMs`, because the server has told us
12
+ * exactly when to come back and guessing sooner only earns another 429.
13
+ *
14
+ * `sleep` and `jitter` are injectable so the backoff sequence is testable
15
+ * without fake timers.
16
+ */
17
+ export interface RetryConfig {
18
+ /** Total attempts including the first. Default 3. */
19
+ maxAttempts?: number;
20
+ /** Backoff before the second attempt, doubled thereafter. Default 250. */
21
+ initialMs?: number;
22
+ /** Ceiling on the computed backoff. Default 5000. Retry-After ignores it. */
23
+ maxMs?: number;
24
+ sleep?: (ms: number) => Promise<void>;
25
+ /** Returns a number in [0, 1). Default Math.random. */
26
+ jitter?: () => number;
27
+ }
28
+ export interface RetryOptions extends RetryConfig {
29
+ shouldRetry: (error: unknown) => boolean;
30
+ /** Milliseconds the failure itself asked us to wait, if it did. */
31
+ retryAfterMs?: (error: unknown) => number | undefined;
32
+ }
33
+ export declare function withRetry<T>(fn: () => Promise<T>, options: RetryOptions): Promise<T>;
34
+ /**
35
+ * Exactly three things get better by waiting: a rate limit, a server-side
36
+ * failure, and a dropped connection. A 401 needs a new token, a 403 needs
37
+ * permission, a 404 needs a different path. None of those are retried.
38
+ */
39
+ export declare function isRetryableFailure(error: unknown): boolean;
40
+ /** The Retry-After a 429 carried, in milliseconds, or undefined. */
41
+ export declare function retryAfterMsFrom(error: unknown): number | undefined;
42
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/api/retry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,WAAW;IAC1B,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;IACzC,mEAAmE;IACnE,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;CACvD;AAOD,wBAAsB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CA4B1F;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAI1D;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAKnE"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Purdue Brightspace MCP Server
3
+ * Copyright (c) 2026 Rohan Muppa. All rights reserved.
4
+ * Licensed under MIT. See LICENSE file for details.
5
+ */
6
+ import { ApiError, NetworkError, RateLimitError } from "./errors.js";
7
+ const JITTER_FRACTION = 0.3;
8
+ const defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
9
+ export async function withRetry(fn, options) {
10
+ const { maxAttempts = 3, initialMs = 250, maxMs = 5000, sleep = defaultSleep, jitter = Math.random, shouldRetry, retryAfterMs, } = options;
11
+ for (let attempt = 1;; attempt++) {
12
+ try {
13
+ return await fn();
14
+ }
15
+ catch (error) {
16
+ if (attempt >= maxAttempts || !shouldRetry(error))
17
+ throw error;
18
+ const requested = retryAfterMs?.(error);
19
+ let delay;
20
+ if (requested !== undefined) {
21
+ delay = requested;
22
+ }
23
+ else {
24
+ const base = Math.min(initialMs * 2 ** (attempt - 1), maxMs);
25
+ delay = Math.round(base + base * JITTER_FRACTION * jitter());
26
+ }
27
+ await sleep(delay);
28
+ }
29
+ }
30
+ }
31
+ /**
32
+ * Exactly three things get better by waiting: a rate limit, a server-side
33
+ * failure, and a dropped connection. A 401 needs a new token, a 403 needs
34
+ * permission, a 404 needs a different path. None of those are retried.
35
+ */
36
+ export function isRetryableFailure(error) {
37
+ if (error instanceof RateLimitError)
38
+ return true;
39
+ if (error instanceof ApiError)
40
+ return error.status >= 500 && error.status <= 599;
41
+ return error instanceof NetworkError;
42
+ }
43
+ /** The Retry-After a 429 carried, in milliseconds, or undefined. */
44
+ export function retryAfterMsFrom(error) {
45
+ if (error instanceof RateLimitError && typeof error.retryAfter === "number" && error.retryAfter > 0) {
46
+ return error.retryAfter * 1000;
47
+ }
48
+ return undefined;
49
+ }
50
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/api/retry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAgCrE,MAAM,eAAe,GAAG,GAAG,CAAC;AAE5B,MAAM,YAAY,GAAG,CAAC,EAAU,EAAiB,EAAE,CACjD,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAEpD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAI,EAAoB,EAAE,OAAqB;IAC5E,MAAM,EACJ,WAAW,GAAG,CAAC,EACf,SAAS,GAAG,GAAG,EACf,KAAK,GAAG,IAAI,EACZ,KAAK,GAAG,YAAY,EACpB,MAAM,GAAG,IAAI,CAAC,MAAM,EACpB,WAAW,EACX,YAAY,GACb,GAAG,OAAO,CAAC;IAEZ,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,OAAO,IAAI,WAAW,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;gBAAE,MAAM,KAAK,CAAC;YAE/D,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC;YACxC,IAAI,KAAa,CAAC;YAClB,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC5B,KAAK,GAAG,SAAS,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;gBAC7D,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,GAAG,eAAe,GAAG,MAAM,EAAE,CAAC,CAAC;YAC/D,CAAC;YACD,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,IAAI,KAAK,YAAY,cAAc;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,KAAK,YAAY,QAAQ;QAAE,OAAO,KAAK,CAAC,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC;IACjF,OAAO,KAAK,YAAY,YAAY,CAAC;AACvC,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,IAAI,KAAK,YAAY,cAAc,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;QACpG,OAAO,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;IACjC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import type { TokenData } from "../types/index.js";
7
7
  import type { TokenManager } from "../auth/token-manager.js";
8
+ import type { RetryConfig } from "./retry.js";
8
9
  export interface ApiVersions {
9
10
  lp: string;
10
11
  le: string;
@@ -31,6 +32,8 @@ export interface D2LApiClientOptions {
31
32
  timeoutMs?: number;
32
33
  /** Called when auth is expired and retries are exhausted. Return true if re-auth succeeded. */
33
34
  onAuthExpired?: () => Promise<boolean>;
35
+ /** Backoff for 429, 5xx, and network failures. See retry.ts for defaults. */
36
+ retry?: RetryConfig;
34
37
  }
35
38
  export type { TokenData };
36
39
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG7D,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ;AAGD,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAGD,eAAO,MAAM,kBAAkB,EAAE,SAQhC,CAAC;AAGF,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,YAAY,CAAC;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+FAA+F;IAC/F,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CACxC;AAGD,YAAY,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ;AAGD,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAGD,eAAO,MAAM,kBAAkB,EAAE,SAQhC,CAAC;AAGF,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,YAAY,CAAC;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+FAA+F;IAC/F,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,6EAA6E;IAC7E,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAGD,YAAY,EAAE,SAAS,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAsBH,uCAAuC;AACvC,MAAM,CAAC,MAAM,kBAAkB,GAAc;IAC3C,WAAW,EAAE,SAAS,EAAE,SAAS;IACjC,aAAa,EAAE,SAAS,EAAE,SAAS;IACnC,aAAa,EAAE,OAAO,EAAE,QAAQ;IAChC,MAAM,EAAE,OAAO,EAAE,QAAQ;IACzB,WAAW,EAAE,OAAO,EAAE,SAAS;IAC/B,MAAM,EAAE,SAAS,EAAE,SAAS;IAC5B,OAAO,EAAE,SAAS,EAAE,SAAS;CAC9B,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAuBH,uCAAuC;AACvC,MAAM,CAAC,MAAM,kBAAkB,GAAc;IAC3C,WAAW,EAAE,SAAS,EAAE,SAAS;IACjC,aAAa,EAAE,SAAS,EAAE,SAAS;IACnC,aAAa,EAAE,OAAO,EAAE,QAAQ;IAChC,MAAM,EAAE,OAAO,EAAE,QAAQ;IACzB,WAAW,EAAE,OAAO,EAAE,SAAS;IAC/B,MAAM,EAAE,SAAS,EAAE,SAAS;IAC5B,OAAO,EAAE,SAAS,EAAE,SAAS;CAC9B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"browser-auth.d.ts","sourceRoot":"","sources":["../../src/auth/browser-auth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AA2B9D,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,OAAO,CAAU;gBAEb,MAAM,EAAE,SAAS;IAK7B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAwB5B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAoBhC;;;;;;;;;;;;;OAaG;mBACkB,oBAAoB;IA8CzC;;;;OAIG;YACW,wBAAwB;IAoBhC,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC;IA6KxC;;;;OAIG;YACW,eAAe;IAyD7B;;;OAGG;YACW,aAAa;IAmC3B;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IA+B9B;;;OAGG;YACW,gBAAgB;IA8C9B,4EAA4E;YAC9D,MAAM;IAQpB;;;OAGG;YACW,cAAc;IAoB5B;;;;;OAKG;YACW,cAAc;IAiB5B;;;OAGG;YACW,mBAAmB;IAsCjC,6EAA6E;YAC/D,UAAU;IAIxB;;;OAGG;YACW,wBAAwB;IAyCtC;;;;;OAKG;YACW,sBAAsB;IAoCpC;;;;OAIG;YACW,eAAe;IAyC7B;;;OAGG;YACW,gBAAgB;IAgE9B;;;OAGG;YACW,kBAAkB;IAiChC;;;OAGG;YACW,gBAAgB;YA8FhB,gBAAgB;IAc9B;;;;;OAKG;YACW,sBAAsB;IA4DpC;;;;;;;;;OASG;YACW,yBAAyB;CAiExC"}
1
+ {"version":3,"file":"browser-auth.d.ts","sourceRoot":"","sources":["../../src/auth/browser-auth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AA2B9D,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,OAAO,CAAU;gBAEb,MAAM,EAAE,SAAS;IAK7B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAwB5B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAoBhC;;;;;;;;;;;;;OAaG;mBACkB,oBAAoB;IA8CzC;;;;OAIG;YACW,wBAAwB;IAoBhC,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC;IA6KxC;;;;OAIG;YACW,eAAe;IAyD7B;;;OAGG;YACW,aAAa;IAmC3B;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IA+B9B;;;OAGG;YACW,gBAAgB;IA8C9B,4EAA4E;YAC9D,MAAM;IAQpB;;;OAGG;YACW,cAAc;IAoB5B;;;;;OAKG;YACW,cAAc;IAiB5B;;;OAGG;YACW,mBAAmB;IAsCjC,6EAA6E;YAC/D,UAAU;IAIxB;;;OAGG;YACW,wBAAwB;IAyCtC;;;;;OAKG;YACW,sBAAsB;IAoCpC;;;;OAIG;YACW,eAAe;IAyC7B;;;OAGG;YACW,gBAAgB;IAgE9B;;;OAGG;YACW,kBAAkB;IAiChC;;;OAGG;YACW,gBAAgB;YA8FhB,gBAAgB;IAc9B;;;;;OAKG;YACW,sBAAsB;IA+DpC;;;;;;;;;OASG;YACW,yBAAyB;CAiExC"}
@@ -3,7 +3,6 @@
3
3
  * Copyright (c) 2026 Rohan Muppa. All rights reserved.
4
4
  * Licensed under MIT — see LICENSE file for details.
5
5
  */
6
- import { chromium } from "playwright";
7
6
  import * as path from "node:path";
8
7
  import * as fs from "node:fs/promises";
9
8
  import * as os from "node:os";
@@ -850,6 +849,8 @@ export class BrowserAuth {
850
849
  * On timeout, we clear lock files and retry once.
851
850
  */
852
851
  async launchBrowserWithRetry(browserDataDir, options) {
852
+ // The only place the browser is needed, so the only place it is loaded.
853
+ const { chromium } = await import("playwright");
853
854
  // Validate lock files before every launch attempt
854
855
  await this.validateAndClearLockFiles(browserDataDir);
855
856
  try {