@the-open-engine/zeroshot 6.28.0 → 6.29.1

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 (283) hide show
  1. package/README.md +3 -3
  2. package/cli/index.js +20 -224
  3. package/docker/zeroshot-cluster/Dockerfile +2 -3
  4. package/lib/cluster/client.cjs +30 -7
  5. package/lib/cluster/client.d.cts +52 -0
  6. package/lib/cluster/client.d.mts +52 -0
  7. package/lib/cluster/client.d.ts +4 -6
  8. package/lib/cluster/client.mjs +32 -9
  9. package/lib/cluster/connection-state.cjs +25 -0
  10. package/lib/cluster/connection-state.d.cts +13 -0
  11. package/lib/cluster/connection-state.d.mts +13 -0
  12. package/lib/cluster/connection-state.d.ts +13 -0
  13. package/lib/cluster/connection-state.mjs +21 -0
  14. package/lib/cluster/connection-types.cjs +2 -0
  15. package/lib/cluster/connection-types.d.cts +33 -0
  16. package/lib/cluster/connection-types.d.mts +33 -0
  17. package/lib/cluster/connection-types.d.ts +33 -0
  18. package/lib/cluster/connection-types.mjs +1 -0
  19. package/lib/cluster/connection.cjs +18 -46
  20. package/lib/cluster/connection.d.cts +26 -0
  21. package/lib/cluster/connection.d.mts +26 -0
  22. package/lib/cluster/connection.d.ts +7 -25
  23. package/lib/cluster/connection.mjs +12 -42
  24. package/lib/cluster/errors.cjs +9 -1
  25. package/lib/cluster/errors.d.cts +29 -0
  26. package/lib/cluster/errors.d.mts +29 -0
  27. package/lib/cluster/errors.d.ts +4 -0
  28. package/lib/cluster/errors.mjs +7 -0
  29. package/lib/cluster/frames.d.cts +12 -0
  30. package/lib/cluster/frames.d.mts +12 -0
  31. package/lib/cluster/generated/protocol-schema.d.cts +1 -0
  32. package/lib/cluster/generated/protocol-schema.d.mts +1 -0
  33. package/lib/cluster/generated/protocol.d.cts +781 -0
  34. package/lib/cluster/generated/protocol.d.mts +781 -0
  35. package/lib/cluster/index.cjs +2 -2
  36. package/lib/cluster/index.d.cts +13 -0
  37. package/lib/cluster/index.d.mts +13 -0
  38. package/lib/cluster/index.d.ts +3 -3
  39. package/lib/cluster/index.mjs +2 -2
  40. package/lib/cluster/json-source.cjs +1 -0
  41. package/lib/cluster/json-source.d.cts +5 -0
  42. package/lib/cluster/json-source.d.mts +5 -0
  43. package/lib/cluster/json-source.d.ts +1 -0
  44. package/lib/cluster/json-source.mjs +1 -0
  45. package/lib/cluster/payload-value.cjs +1 -0
  46. package/lib/cluster/payload-value.d.cts +8 -0
  47. package/lib/cluster/payload-value.d.mts +8 -0
  48. package/lib/cluster/payload-value.d.ts +1 -0
  49. package/lib/cluster/payload-value.mjs +1 -0
  50. package/lib/cluster/queue.d.cts +15 -0
  51. package/lib/cluster/queue.d.mts +15 -0
  52. package/lib/cluster/socket.cjs +8 -0
  53. package/lib/cluster/socket.d.cts +13 -0
  54. package/lib/cluster/socket.d.mts +13 -0
  55. package/lib/cluster/socket.d.ts +2 -0
  56. package/lib/cluster/socket.mjs +7 -0
  57. package/lib/cluster/subscriptions.d.cts +73 -0
  58. package/lib/cluster/subscriptions.d.mts +73 -0
  59. package/lib/cluster/subscriptions.d.ts +5 -1
  60. package/lib/cluster/validators.cjs +1 -0
  61. package/lib/cluster/validators.d.cts +7 -0
  62. package/lib/cluster/validators.d.mts +7 -0
  63. package/lib/cluster/validators.d.ts +1 -0
  64. package/lib/cluster/validators.mjs +1 -0
  65. package/lib/cluster-worker/engine-adapter.js +1 -11
  66. package/lib/cluster-worker/engine-input.js +14 -0
  67. package/lib/hosted-session/authority.cjs +61 -0
  68. package/lib/hosted-session/authority.d.cts +3 -0
  69. package/lib/hosted-session/authority.d.mts +3 -0
  70. package/lib/hosted-session/authority.d.ts +3 -0
  71. package/lib/hosted-session/authority.mjs +57 -0
  72. package/lib/hosted-session/coordinator.cjs +78 -51
  73. package/lib/hosted-session/coordinator.d.cts +11 -0
  74. package/lib/hosted-session/coordinator.d.mts +11 -0
  75. package/lib/hosted-session/coordinator.d.ts +4 -2
  76. package/lib/hosted-session/coordinator.mjs +75 -51
  77. package/lib/hosted-session/errors.cjs +25 -0
  78. package/lib/hosted-session/errors.d.cts +10 -0
  79. package/lib/hosted-session/errors.d.mts +10 -0
  80. package/lib/hosted-session/errors.d.ts +10 -0
  81. package/lib/hosted-session/errors.mjs +19 -0
  82. package/lib/hosted-session/index.cjs +4 -1
  83. package/lib/hosted-session/index.d.cts +2 -0
  84. package/lib/hosted-session/index.d.mts +2 -0
  85. package/lib/hosted-session/index.d.ts +2 -2
  86. package/lib/hosted-session/index.mjs +1 -1
  87. package/lib/hosted-session/reconnecting-watch.cjs +131 -0
  88. package/lib/hosted-session/reconnecting-watch.d.cts +13 -0
  89. package/lib/hosted-session/reconnecting-watch.d.mts +13 -0
  90. package/lib/hosted-session/reconnecting-watch.d.ts +13 -0
  91. package/lib/hosted-session/reconnecting-watch.mjs +127 -0
  92. package/lib/hosted-session/types.d.cts +32 -0
  93. package/lib/hosted-session/types.d.mts +32 -0
  94. package/lib/hosted-session/types.d.ts +19 -7
  95. package/lib/hosted-target/access-url.cjs +44 -0
  96. package/lib/hosted-target/access-url.d.cts +2 -0
  97. package/lib/hosted-target/access-url.d.mts +2 -0
  98. package/lib/hosted-target/access-url.d.ts +2 -0
  99. package/lib/hosted-target/access-url.mjs +41 -0
  100. package/lib/hosted-target/adapter-request.cjs +12 -0
  101. package/lib/hosted-target/adapter-request.d.cts +17 -0
  102. package/lib/hosted-target/adapter-request.d.mts +17 -0
  103. package/lib/hosted-target/adapter-request.d.ts +17 -0
  104. package/lib/hosted-target/adapter-request.mjs +9 -0
  105. package/lib/hosted-target/adapter-types.cjs +2 -0
  106. package/lib/hosted-target/adapter-types.d.cts +27 -0
  107. package/lib/hosted-target/adapter-types.d.mts +27 -0
  108. package/lib/hosted-target/adapter-types.d.ts +27 -0
  109. package/lib/hosted-target/adapter-types.mjs +1 -0
  110. package/lib/hosted-target/bounds.cjs +10 -0
  111. package/lib/hosted-target/bounds.d.cts +7 -0
  112. package/lib/hosted-target/bounds.d.mts +7 -0
  113. package/lib/hosted-target/bounds.d.ts +7 -0
  114. package/lib/hosted-target/bounds.mjs +7 -0
  115. package/lib/hosted-target/capsule-error-response.cjs +76 -0
  116. package/lib/hosted-target/capsule-error-response.d.cts +2 -0
  117. package/lib/hosted-target/capsule-error-response.d.mts +2 -0
  118. package/lib/hosted-target/capsule-error-response.d.ts +2 -0
  119. package/lib/hosted-target/capsule-error-response.mjs +73 -0
  120. package/lib/hosted-target/errors.cjs +88 -0
  121. package/lib/hosted-target/errors.d.cts +36 -0
  122. package/lib/hosted-target/errors.d.mts +36 -0
  123. package/lib/hosted-target/errors.d.ts +36 -0
  124. package/lib/hosted-target/errors.mjs +75 -0
  125. package/lib/hosted-target/index.cjs +16 -0
  126. package/lib/hosted-target/index.d.cts +3 -0
  127. package/lib/hosted-target/index.d.mts +3 -0
  128. package/lib/hosted-target/index.d.ts +3 -0
  129. package/lib/hosted-target/index.mjs +2 -0
  130. package/lib/hosted-target/response-validation.cjs +169 -0
  131. package/lib/hosted-target/response-validation.d.cts +5 -0
  132. package/lib/hosted-target/response-validation.d.mts +5 -0
  133. package/lib/hosted-target/response-validation.d.ts +5 -0
  134. package/lib/hosted-target/response-validation.mjs +163 -0
  135. package/lib/hosted-target/retry-executor.cjs +51 -0
  136. package/lib/hosted-target/retry-executor.d.cts +8 -0
  137. package/lib/hosted-target/retry-executor.d.mts +8 -0
  138. package/lib/hosted-target/retry-executor.d.ts +8 -0
  139. package/lib/hosted-target/retry-executor.mjs +48 -0
  140. package/lib/hosted-target/retry.cjs +78 -0
  141. package/lib/hosted-target/retry.d.cts +9 -0
  142. package/lib/hosted-target/retry.d.mts +9 -0
  143. package/lib/hosted-target/retry.d.ts +9 -0
  144. package/lib/hosted-target/retry.mjs +73 -0
  145. package/lib/hosted-target/target-adapter.cjs +10 -0
  146. package/lib/hosted-target/target-adapter.d.cts +3 -0
  147. package/lib/hosted-target/target-adapter.d.mts +3 -0
  148. package/lib/hosted-target/target-adapter.d.ts +3 -0
  149. package/lib/hosted-target/target-adapter.mjs +7 -0
  150. package/lib/hosted-target/types.cjs +4 -0
  151. package/lib/hosted-target/types.d.cts +50 -0
  152. package/lib/hosted-target/types.d.mts +50 -0
  153. package/lib/hosted-target/types.d.ts +50 -0
  154. package/lib/hosted-target/types.mjs +1 -0
  155. package/lib/hosted-target/zero-cloud-v1-adapter.cjs +185 -0
  156. package/lib/hosted-target/zero-cloud-v1-adapter.d.cts +13 -0
  157. package/lib/hosted-target/zero-cloud-v1-adapter.d.mts +13 -0
  158. package/lib/hosted-target/zero-cloud-v1-adapter.d.ts +13 -0
  159. package/lib/hosted-target/zero-cloud-v1-adapter.mjs +181 -0
  160. package/lib/target/bounded-response.cjs +51 -0
  161. package/lib/target/bounded-response.d.cts +1 -0
  162. package/lib/target/bounded-response.d.mts +1 -0
  163. package/lib/target/bounded-response.d.ts +1 -0
  164. package/lib/target/bounded-response.js +51 -0
  165. package/lib/target/bounded-response.mjs +48 -0
  166. package/lib/target/credential-lock.js +1 -3
  167. package/lib/target/credential-store.js +9 -4
  168. package/lib/target/device-flow.cjs +213 -0
  169. package/lib/target/device-flow.d.cts +54 -0
  170. package/lib/target/device-flow.d.mts +54 -0
  171. package/lib/target/device-flow.d.ts +26 -10
  172. package/lib/target/device-flow.js +162 -53
  173. package/lib/target/device-flow.mjs +203 -0
  174. package/lib/target/discovery-errors.cjs +10 -0
  175. package/lib/target/discovery-errors.d.cts +3 -0
  176. package/lib/target/discovery-errors.d.mts +3 -0
  177. package/lib/target/discovery-errors.d.ts +3 -0
  178. package/lib/target/discovery-errors.js +10 -0
  179. package/lib/target/discovery-errors.mjs +6 -0
  180. package/lib/target/discovery-sections.cjs +191 -0
  181. package/lib/target/discovery-sections.d.cts +52 -0
  182. package/lib/target/discovery-sections.d.mts +52 -0
  183. package/lib/target/discovery-sections.d.ts +52 -0
  184. package/lib/target/discovery-sections.js +191 -0
  185. package/lib/target/discovery-sections.mjs +179 -0
  186. package/lib/target/discovery-validation.cjs +109 -0
  187. package/lib/target/discovery-validation.d.cts +28 -0
  188. package/lib/target/discovery-validation.d.mts +28 -0
  189. package/lib/target/discovery-validation.d.ts +28 -0
  190. package/lib/target/discovery-validation.js +109 -0
  191. package/lib/target/discovery-validation.mjs +99 -0
  192. package/lib/target/discovery.cjs +112 -0
  193. package/lib/target/discovery.d.cts +74 -0
  194. package/lib/target/discovery.d.mts +74 -0
  195. package/lib/target/discovery.d.ts +68 -5
  196. package/lib/target/discovery.js +93 -101
  197. package/lib/target/discovery.mjs +105 -0
  198. package/lib/target/index.d.ts +6 -6
  199. package/lib/target/index.js +36 -36
  200. package/lib/target/oauth-http.d.ts +2 -0
  201. package/lib/target/oauth-http.js +25 -0
  202. package/lib/target/refresh-exchange.d.ts +11 -0
  203. package/lib/target/refresh-exchange.js +24 -0
  204. package/lib/target/refresh-revocation.d.ts +8 -0
  205. package/lib/target/refresh-revocation.js +19 -0
  206. package/lib/target/route-template.cjs +85 -0
  207. package/lib/target/route-template.d.cts +7 -0
  208. package/lib/target/route-template.d.mts +7 -0
  209. package/lib/target/route-template.d.ts +7 -0
  210. package/lib/target/route-template.js +85 -0
  211. package/lib/target/route-template.mjs +81 -0
  212. package/lib/target/session-errors.d.ts +4 -0
  213. package/lib/target/session-errors.js +12 -0
  214. package/lib/target/session-verification.d.ts +10 -0
  215. package/lib/target/session-verification.js +42 -0
  216. package/lib/target/target-registry.d.ts +7 -3
  217. package/lib/target/target-registry.js +41 -10
  218. package/lib/target/target-session-manager.d.ts +48 -0
  219. package/lib/target/target-session-manager.js +226 -0
  220. package/lib/target/target-session.d.ts +39 -31
  221. package/lib/target/target-session.js +63 -150
  222. package/lib/target/token-response.cjs +51 -0
  223. package/lib/target/token-response.d.cts +7 -0
  224. package/lib/target/token-response.d.mts +7 -0
  225. package/lib/target/token-response.d.ts +7 -0
  226. package/lib/target/token-response.js +51 -0
  227. package/lib/target/token-response.mjs +48 -0
  228. package/package.json +16 -6
  229. package/scripts/audit-production-dependencies.js +150 -0
  230. package/scripts/build-cluster.js +23 -3
  231. package/scripts/opcore-agent-gate.js +159 -0
  232. package/scripts/opcore-agent-tool-overlays.js +154 -0
  233. package/scripts/opcore-introduced-check.js +288 -0
  234. package/src/cluster/client.ts +42 -15
  235. package/src/cluster/connection-state.ts +33 -0
  236. package/src/cluster/connection-types.ts +28 -0
  237. package/src/cluster/connection.ts +37 -68
  238. package/src/cluster/errors.ts +5 -0
  239. package/src/cluster/index.ts +3 -1
  240. package/src/cluster/json-source.ts +1 -0
  241. package/src/cluster/payload-value.ts +1 -0
  242. package/src/cluster/socket.ts +13 -0
  243. package/src/cluster/subscriptions.ts +7 -2
  244. package/src/cluster/validators.ts +1 -0
  245. package/src/cluster/ws.d.ts +1 -1
  246. package/src/hosted-session/authority.ts +77 -0
  247. package/src/hosted-session/coordinator.ts +113 -56
  248. package/src/hosted-session/errors.ts +21 -0
  249. package/src/hosted-session/index.ts +14 -2
  250. package/src/hosted-session/reconnecting-watch.ts +148 -0
  251. package/src/hosted-session/types.ts +22 -8
  252. package/src/hosted-target/access-url.ts +46 -0
  253. package/src/hosted-target/adapter-request.ts +28 -0
  254. package/src/hosted-target/adapter-types.ts +39 -0
  255. package/src/hosted-target/bounds.ts +1 -0
  256. package/src/hosted-target/capsule-error-response.ts +107 -0
  257. package/src/hosted-target/errors.ts +36 -35
  258. package/src/hosted-target/index.ts +10 -23
  259. package/src/hosted-target/response-validation.ts +170 -62
  260. package/src/hosted-target/retry-executor.ts +62 -0
  261. package/src/hosted-target/retry.ts +47 -11
  262. package/src/hosted-target/target-adapter.ts +12 -8
  263. package/src/hosted-target/types.ts +19 -18
  264. package/src/hosted-target/zero-cloud-v1-adapter.ts +229 -316
  265. package/src/target/bounded-response.ts +68 -0
  266. package/src/target/credential-lock.ts +1 -3
  267. package/src/target/credential-store.ts +14 -10
  268. package/src/target/device-flow.ts +206 -71
  269. package/src/target/discovery-errors.ts +6 -0
  270. package/src/target/discovery-sections.ts +251 -0
  271. package/src/target/discovery-validation.ts +144 -0
  272. package/src/target/discovery.ts +163 -115
  273. package/src/target/index.ts +15 -11
  274. package/src/target/oauth-http.ts +27 -0
  275. package/src/target/refresh-exchange.ts +36 -0
  276. package/src/target/refresh-revocation.ts +29 -0
  277. package/src/target/route-template.ts +105 -0
  278. package/src/target/session-errors.ts +9 -0
  279. package/src/target/session-verification.ts +51 -0
  280. package/src/target/target-registry.ts +60 -27
  281. package/src/target/target-session-manager.ts +285 -0
  282. package/src/target/target-session.ts +105 -222
  283. package/src/target/token-response.ts +62 -0
@@ -0,0 +1 @@
1
+ export declare function readBoundedResponseJson(response: Response, maxBytes: number, error: (kind: 'size' | 'json') => Error): Promise<unknown>;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readBoundedResponseJson = readBoundedResponseJson;
4
+ async function declaredResponseBytes(response, maxBytes, error) {
5
+ const declared = response.headers.get('content-length');
6
+ if (declared === null)
7
+ return 0;
8
+ if (!/^\d+$/.test(declared) || Number(declared) > maxBytes) {
9
+ await response.body?.cancel().catch(() => undefined);
10
+ throw error('size');
11
+ }
12
+ return Number(declared);
13
+ }
14
+ function growBuffer(bytes, required, used, maxBytes) {
15
+ const capacity = Math.min(maxBytes, Math.max(required, Math.max(bytes.byteLength * 2, 8 * 1024)));
16
+ const grown = new Uint8Array(capacity);
17
+ grown.set(bytes.subarray(0, used));
18
+ return grown;
19
+ }
20
+ function decodeJson(bytes, error) {
21
+ try {
22
+ return JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(bytes));
23
+ }
24
+ catch {
25
+ throw error('json');
26
+ }
27
+ }
28
+ async function readBoundedResponseJson(response, maxBytes, error) {
29
+ const declaredBytes = await declaredResponseBytes(response, maxBytes, error);
30
+ const reader = response.body?.getReader();
31
+ if (reader === undefined)
32
+ return decodeJson(new Uint8Array(), error);
33
+ let bytes = new Uint8Array(Math.min(maxBytes, Math.max(declaredBytes, 8 * 1024)));
34
+ let total = 0;
35
+ while (true) {
36
+ const { done, value } = await reader.read();
37
+ if (done)
38
+ break;
39
+ const nextTotal = total + value.byteLength;
40
+ if (nextTotal > maxBytes) {
41
+ await reader.cancel().catch(() => undefined);
42
+ throw error('size');
43
+ }
44
+ if (nextTotal > bytes.byteLength) {
45
+ bytes = growBuffer(bytes, nextTotal, total, maxBytes);
46
+ }
47
+ bytes.set(value, total);
48
+ total = nextTotal;
49
+ }
50
+ return decodeJson(bytes.subarray(0, total), error);
51
+ }
@@ -0,0 +1,48 @@
1
+ async function declaredResponseBytes(response, maxBytes, error) {
2
+ const declared = response.headers.get('content-length');
3
+ if (declared === null)
4
+ return 0;
5
+ if (!/^\d+$/.test(declared) || Number(declared) > maxBytes) {
6
+ await response.body?.cancel().catch(() => undefined);
7
+ throw error('size');
8
+ }
9
+ return Number(declared);
10
+ }
11
+ function growBuffer(bytes, required, used, maxBytes) {
12
+ const capacity = Math.min(maxBytes, Math.max(required, Math.max(bytes.byteLength * 2, 8 * 1024)));
13
+ const grown = new Uint8Array(capacity);
14
+ grown.set(bytes.subarray(0, used));
15
+ return grown;
16
+ }
17
+ function decodeJson(bytes, error) {
18
+ try {
19
+ return JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(bytes));
20
+ }
21
+ catch {
22
+ throw error('json');
23
+ }
24
+ }
25
+ export async function readBoundedResponseJson(response, maxBytes, error) {
26
+ const declaredBytes = await declaredResponseBytes(response, maxBytes, error);
27
+ const reader = response.body?.getReader();
28
+ if (reader === undefined)
29
+ return decodeJson(new Uint8Array(), error);
30
+ let bytes = new Uint8Array(Math.min(maxBytes, Math.max(declaredBytes, 8 * 1024)));
31
+ let total = 0;
32
+ while (true) {
33
+ const { done, value } = await reader.read();
34
+ if (done)
35
+ break;
36
+ const nextTotal = total + value.byteLength;
37
+ if (nextTotal > maxBytes) {
38
+ await reader.cancel().catch(() => undefined);
39
+ throw error('size');
40
+ }
41
+ if (nextTotal > bytes.byteLength) {
42
+ bytes = growBuffer(bytes, nextTotal, total, maxBytes);
43
+ }
44
+ bytes.set(value, total);
45
+ total = nextTotal;
46
+ }
47
+ return decodeJson(bytes.subarray(0, total), error);
48
+ }
@@ -32,7 +32,5 @@ async function acquireTargetLock(targetId) {
32
32
  maxTimeout: LOCK_RETRY_MAX_TIMEOUT_MS,
33
33
  },
34
34
  });
35
- return async () => {
36
- await release();
37
- };
35
+ return release;
38
36
  }
@@ -71,12 +71,17 @@ class KeyringCredentialStore {
71
71
  return entry.getPassword();
72
72
  }
73
73
  catch {
74
- return null;
74
+ throw new CredentialStoreUnavailableError('The secure credential store could not be read.');
75
75
  }
76
76
  }
77
77
  async set(service, account, token) {
78
- const entry = new this.Entry(service, account);
79
- entry.setPassword(token);
78
+ try {
79
+ const entry = new this.Entry(service, account);
80
+ entry.setPassword(token);
81
+ }
82
+ catch {
83
+ throw new CredentialStoreUnavailableError('The secure credential store could not be updated.');
84
+ }
80
85
  }
81
86
  async delete(service, account) {
82
87
  try {
@@ -84,7 +89,7 @@ class KeyringCredentialStore {
84
89
  entry.deletePassword();
85
90
  }
86
91
  catch {
87
- // Already deleted or not present
92
+ throw new CredentialStoreUnavailableError('The secure credential store could not be cleared.');
88
93
  }
89
94
  }
90
95
  }
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UnboundSessionError = exports.DeviceFlowExpiredError = exports.DeviceFlowDeniedError = exports.parseTokenResponse = void 0;
4
+ exports.oauthFormRequest = oauthFormRequest;
5
+ exports.requestDeviceCode = requestDeviceCode;
6
+ exports.pollForToken = pollForToken;
7
+ const bounded_response_js_1 = require("./bounded-response.cjs");
8
+ const token_response_js_1 = require("./token-response.cjs");
9
+ var token_response_js_2 = require("./token-response.cjs");
10
+ Object.defineProperty(exports, "parseTokenResponse", { enumerable: true, get: function () { return token_response_js_2.parseTokenResponse; } });
11
+ function exchangeFields(exchange) {
12
+ if (exchange === undefined)
13
+ return {};
14
+ if ('grantType' in exchange) {
15
+ return {
16
+ grant_type: exchange.grantType,
17
+ device_token: exchange.deviceToken,
18
+ device_label: exchange.deviceLabel,
19
+ audience: exchange.audience,
20
+ };
21
+ }
22
+ return {
23
+ device_token: exchange.token,
24
+ device_label: exchange.label,
25
+ audience: 'admin',
26
+ };
27
+ }
28
+ class DeviceFlowDeniedError extends Error {
29
+ constructor() {
30
+ super('Device authorization denied by user');
31
+ this.name = 'DeviceFlowDeniedError';
32
+ }
33
+ }
34
+ exports.DeviceFlowDeniedError = DeviceFlowDeniedError;
35
+ class DeviceFlowExpiredError extends Error {
36
+ constructor() {
37
+ super('Device authorization code expired');
38
+ this.name = 'DeviceFlowExpiredError';
39
+ }
40
+ }
41
+ exports.DeviceFlowExpiredError = DeviceFlowExpiredError;
42
+ class UnboundSessionError extends Error {
43
+ verificationUri;
44
+ constructor(verificationUri) {
45
+ super(`Session not bound to an organization. Re-approve at ${verificationUri} and select an organization.`);
46
+ this.name = 'UnboundSessionError';
47
+ this.verificationUri = verificationUri;
48
+ }
49
+ }
50
+ exports.UnboundSessionError = UnboundSessionError;
51
+ const DEFAULT_CLOCK = { now: () => Date.now() };
52
+ const MAX_OAUTH_RESPONSE_BYTES = 64 * 1024;
53
+ const MAX_DEVICE_CODE_BYTES = 16 * 1024;
54
+ const LOOPBACK_HOSTS = Object.freeze({
55
+ '127.0.0.1': true,
56
+ '::1': true,
57
+ '[::1]': true,
58
+ });
59
+ const MAX_URI_BYTES = 4 * 1024;
60
+ function oauthFormRequest(body, signal) {
61
+ const init = {
62
+ method: 'POST',
63
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
64
+ body: body.toString(),
65
+ redirect: 'error',
66
+ };
67
+ if (signal !== undefined)
68
+ init.signal = signal;
69
+ return init;
70
+ }
71
+ async function requireResponseRoute(response, expectedUrl) {
72
+ if (!response.url || new URL(response.url).href === expectedUrl)
73
+ return;
74
+ await response.body?.cancel().catch(() => undefined);
75
+ throw new Error('OAuth response changed target route or authority');
76
+ }
77
+ async function readBoundedJson(response) {
78
+ return (0, bounded_response_js_1.readBoundedResponseJson)(response, MAX_OAUTH_RESPONSE_BYTES, (kind) => new Error(kind === 'size' ? 'OAuth response exceeds the size limit' : 'OAuth response is malformed'));
79
+ }
80
+ function boundedString(value, maxBytes) {
81
+ return (typeof value === 'string' &&
82
+ value.length > 0 &&
83
+ new TextEncoder().encode(value).byteLength <= maxBytes);
84
+ }
85
+ function safeVerificationAuthority(url, allowQuery) {
86
+ const literalLoopback = LOOPBACK_HOSTS[url.hostname] === true;
87
+ return !url.username && !url.password && !url.hash &&
88
+ (allowQuery || !url.search) &&
89
+ (url.protocol === 'https:' || (url.protocol === 'http:' && literalLoopback));
90
+ }
91
+ function verificationUrl(value, allowQuery) {
92
+ if (!boundedString(value, MAX_URI_BYTES) ||
93
+ /[\u0000-\u0020\u007f]|\s/u.test(value)) {
94
+ return false;
95
+ }
96
+ try {
97
+ const url = new URL(value);
98
+ return url.href === value && safeVerificationAuthority(url, allowQuery);
99
+ }
100
+ catch {
101
+ return false;
102
+ }
103
+ }
104
+ function deviceFieldsValid(device) {
105
+ const fields = Object.keys(device);
106
+ const required = ['device_code', 'user_code', 'verification_uri', 'expires_in', 'interval'];
107
+ return fields.every((field) => required.includes(field) || field === 'verification_uri_complete') && required.every((field) => field in device);
108
+ }
109
+ function deviceStringsValid(device) {
110
+ return boundedString(device.device_code, MAX_DEVICE_CODE_BYTES) &&
111
+ boundedString(device.user_code, 256) &&
112
+ verificationUrl(device.verification_uri, false) &&
113
+ (device.verification_uri_complete === undefined ||
114
+ verificationUrl(device.verification_uri_complete, true));
115
+ }
116
+ function deviceTimingValid(device) {
117
+ return Number.isSafeInteger(device.expires_in) &&
118
+ device.expires_in >= 1 &&
119
+ device.expires_in <= 86_400 &&
120
+ Number.isSafeInteger(device.interval) &&
121
+ device.interval >= 0 &&
122
+ device.interval <= 300;
123
+ }
124
+ function browserAuthorityMatches(device) {
125
+ return device.verification_uri_complete === undefined ||
126
+ new URL(device.verification_uri_complete).origin ===
127
+ new URL(device.verification_uri).origin;
128
+ }
129
+ function parseDeviceCodeResponse(value) {
130
+ const device = object(value, 'Device code');
131
+ if (!deviceFieldsValid(device) || !deviceStringsValid(device) ||
132
+ !deviceTimingValid(device) || !browserAuthorityMatches(device)) {
133
+ throw new Error('Device code response is malformed');
134
+ }
135
+ return Object.freeze(device);
136
+ }
137
+ function parseOAuthError(value) {
138
+ const error = object(value, 'OAuth error');
139
+ if (Object.keys(error).length !== 1 || typeof error.error !== 'string') {
140
+ throw new Error('OAuth error response is malformed');
141
+ }
142
+ return error.error;
143
+ }
144
+ function object(value, field) {
145
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
146
+ throw new Error(`${field} response is malformed`);
147
+ }
148
+ return value;
149
+ }
150
+ function sleep(ms, signal) {
151
+ return new Promise((resolve, reject) => {
152
+ if (signal?.aborted) {
153
+ reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));
154
+ return;
155
+ }
156
+ const timer = setTimeout(resolve, ms);
157
+ signal?.addEventListener('abort', () => {
158
+ clearTimeout(timer);
159
+ reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));
160
+ }, { once: true });
161
+ });
162
+ }
163
+ async function requestDeviceCode(deviceAuthorizationEndpoint, clientId, http, signal) {
164
+ const body = new URLSearchParams({ client_id: clientId });
165
+ const response = await http.fetch(deviceAuthorizationEndpoint, oauthFormRequest(body, signal));
166
+ await requireResponseRoute(response, deviceAuthorizationEndpoint);
167
+ if (!response.ok) {
168
+ parseOAuthError(await readBoundedJson(response));
169
+ throw new Error(`Device code request failed (${response.status})`);
170
+ }
171
+ return parseDeviceCodeResponse(await readBoundedJson(response));
172
+ }
173
+ async function parsePollResponse(response) {
174
+ if (response.ok)
175
+ return (0, token_response_js_1.parseTokenResponse)(await readBoundedJson(response));
176
+ const error = parseOAuthError(await readBoundedJson(response));
177
+ if (error === 'authorization_pending' || error === 'slow_down')
178
+ return error;
179
+ if (error === 'access_denied')
180
+ throw new DeviceFlowDeniedError();
181
+ if (error === 'expired_token')
182
+ throw new DeviceFlowExpiredError();
183
+ throw new Error('Token endpoint returned an unsupported OAuth error');
184
+ }
185
+ function pollBody(request) {
186
+ return new URLSearchParams({
187
+ grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
188
+ device_code: request.deviceCode,
189
+ client_id: request.clientId,
190
+ ...exchangeFields(request.exchange),
191
+ });
192
+ }
193
+ async function pollForToken(request) {
194
+ const clock = request.clock ?? DEFAULT_CLOCK;
195
+ const deadline = clock.now() + request.expiresIn * 1000;
196
+ let currentInterval = request.interval;
197
+ while (clock.now() < deadline) {
198
+ if (request.signal?.aborted) {
199
+ throw request.signal.reason ?? new DOMException('Aborted', 'AbortError');
200
+ }
201
+ await sleep(currentInterval * 1000, request.signal);
202
+ const response = await request.http.fetch(request.tokenEndpoint, oauthFormRequest(pollBody(request), request.signal));
203
+ const result = await parsePollResponse(response);
204
+ if (result === 'authorization_pending')
205
+ continue;
206
+ if (result === 'slow_down') {
207
+ currentInterval += 5;
208
+ continue;
209
+ }
210
+ return result;
211
+ }
212
+ throw new DeviceFlowExpiredError();
213
+ }
@@ -0,0 +1,54 @@
1
+ import { type TokenResponse } from './token-response.js';
2
+ export { parseTokenResponse, type TokenResponse } from './token-response.js';
3
+ export interface DeviceCodeResponse {
4
+ readonly device_code: string;
5
+ readonly user_code: string;
6
+ readonly verification_uri: string;
7
+ readonly verification_uri_complete?: string;
8
+ readonly expires_in: number;
9
+ readonly interval: number;
10
+ }
11
+ export interface DeviceExchangeContext {
12
+ readonly grantType: string;
13
+ readonly deviceToken: string;
14
+ readonly deviceLabel: string;
15
+ readonly audience: string;
16
+ }
17
+ export interface DeviceIdentity {
18
+ readonly token: string;
19
+ readonly label: string;
20
+ }
21
+ export interface HttpTransport {
22
+ fetch(url: string, init: RequestInit & {
23
+ redirect: 'error';
24
+ }): Promise<Response>;
25
+ }
26
+ export interface Clock {
27
+ now(): number;
28
+ }
29
+ export declare class DeviceFlowDeniedError extends Error {
30
+ constructor();
31
+ }
32
+ export declare class DeviceFlowExpiredError extends Error {
33
+ constructor();
34
+ }
35
+ export declare class UnboundSessionError extends Error {
36
+ readonly verificationUri: string;
37
+ constructor(verificationUri: string);
38
+ }
39
+ export declare function oauthFormRequest(body: URLSearchParams, signal?: AbortSignal): RequestInit & {
40
+ redirect: 'error';
41
+ };
42
+ export declare function requestDeviceCode(deviceAuthorizationEndpoint: string, clientId: string, http: HttpTransport, signal?: AbortSignal): Promise<DeviceCodeResponse>;
43
+ export interface PollForTokenRequest {
44
+ readonly tokenEndpoint: string;
45
+ readonly clientId: string;
46
+ readonly deviceCode: string;
47
+ readonly interval: number;
48
+ readonly expiresIn: number;
49
+ readonly http: HttpTransport;
50
+ readonly clock?: Clock;
51
+ readonly signal?: AbortSignal;
52
+ readonly exchange?: DeviceExchangeContext | DeviceIdentity;
53
+ }
54
+ export declare function pollForToken(request: PollForTokenRequest): Promise<TokenResponse>;
@@ -0,0 +1,54 @@
1
+ import { type TokenResponse } from './token-response.js';
2
+ export { parseTokenResponse, type TokenResponse } from './token-response.js';
3
+ export interface DeviceCodeResponse {
4
+ readonly device_code: string;
5
+ readonly user_code: string;
6
+ readonly verification_uri: string;
7
+ readonly verification_uri_complete?: string;
8
+ readonly expires_in: number;
9
+ readonly interval: number;
10
+ }
11
+ export interface DeviceExchangeContext {
12
+ readonly grantType: string;
13
+ readonly deviceToken: string;
14
+ readonly deviceLabel: string;
15
+ readonly audience: string;
16
+ }
17
+ export interface DeviceIdentity {
18
+ readonly token: string;
19
+ readonly label: string;
20
+ }
21
+ export interface HttpTransport {
22
+ fetch(url: string, init: RequestInit & {
23
+ redirect: 'error';
24
+ }): Promise<Response>;
25
+ }
26
+ export interface Clock {
27
+ now(): number;
28
+ }
29
+ export declare class DeviceFlowDeniedError extends Error {
30
+ constructor();
31
+ }
32
+ export declare class DeviceFlowExpiredError extends Error {
33
+ constructor();
34
+ }
35
+ export declare class UnboundSessionError extends Error {
36
+ readonly verificationUri: string;
37
+ constructor(verificationUri: string);
38
+ }
39
+ export declare function oauthFormRequest(body: URLSearchParams, signal?: AbortSignal): RequestInit & {
40
+ redirect: 'error';
41
+ };
42
+ export declare function requestDeviceCode(deviceAuthorizationEndpoint: string, clientId: string, http: HttpTransport, signal?: AbortSignal): Promise<DeviceCodeResponse>;
43
+ export interface PollForTokenRequest {
44
+ readonly tokenEndpoint: string;
45
+ readonly clientId: string;
46
+ readonly deviceCode: string;
47
+ readonly interval: number;
48
+ readonly expiresIn: number;
49
+ readonly http: HttpTransport;
50
+ readonly clock?: Clock;
51
+ readonly signal?: AbortSignal;
52
+ readonly exchange?: DeviceExchangeContext | DeviceIdentity;
53
+ }
54
+ export declare function pollForToken(request: PollForTokenRequest): Promise<TokenResponse>;
@@ -1,3 +1,5 @@
1
+ import { type TokenResponse } from './token-response.js';
2
+ export { parseTokenResponse, type TokenResponse } from './token-response.js';
1
3
  export interface DeviceCodeResponse {
2
4
  readonly device_code: string;
3
5
  readonly user_code: string;
@@ -6,15 +8,15 @@ export interface DeviceCodeResponse {
6
8
  readonly expires_in: number;
7
9
  readonly interval: number;
8
10
  }
9
- export interface TokenResponse {
10
- readonly access_token: string;
11
- readonly refresh_token: string;
12
- readonly token_type: string;
13
- readonly expires_in: number;
14
- readonly organization?: {
15
- readonly id: string;
16
- readonly name: string;
17
- };
11
+ export interface DeviceExchangeContext {
12
+ readonly grantType: string;
13
+ readonly deviceToken: string;
14
+ readonly deviceLabel: string;
15
+ readonly audience: string;
16
+ }
17
+ export interface DeviceIdentity {
18
+ readonly token: string;
19
+ readonly label: string;
18
20
  }
19
21
  export interface HttpTransport {
20
22
  fetch(url: string, init: RequestInit & {
@@ -34,5 +36,19 @@ export declare class UnboundSessionError extends Error {
34
36
  readonly verificationUri: string;
35
37
  constructor(verificationUri: string);
36
38
  }
39
+ export declare function oauthFormRequest(body: URLSearchParams, signal?: AbortSignal): RequestInit & {
40
+ redirect: 'error';
41
+ };
37
42
  export declare function requestDeviceCode(deviceAuthorizationEndpoint: string, clientId: string, http: HttpTransport, signal?: AbortSignal): Promise<DeviceCodeResponse>;
38
- export declare function pollForToken(tokenEndpoint: string, clientId: string, deviceCode: string, interval: number, expiresIn: number, http: HttpTransport, clock?: Clock, signal?: AbortSignal): Promise<TokenResponse>;
43
+ export interface PollForTokenRequest {
44
+ readonly tokenEndpoint: string;
45
+ readonly clientId: string;
46
+ readonly deviceCode: string;
47
+ readonly interval: number;
48
+ readonly expiresIn: number;
49
+ readonly http: HttpTransport;
50
+ readonly clock?: Clock;
51
+ readonly signal?: AbortSignal;
52
+ readonly exchange?: DeviceExchangeContext | DeviceIdentity;
53
+ }
54
+ export declare function pollForToken(request: PollForTokenRequest): Promise<TokenResponse>;