@the-open-engine/zeroshot 6.29.0 → 6.30.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 (347) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/cli/index.js +2 -4
  3. package/lib/agent-cli-provider/adapters/codex.d.ts.map +1 -1
  4. package/lib/agent-cli-provider/adapters/codex.js +0 -1
  5. package/lib/agent-cli-provider/adapters/codex.js.map +1 -1
  6. package/lib/agent-cli-provider/contract-actions.d.ts +1 -1
  7. package/lib/agent-cli-provider/contract-actions.d.ts.map +1 -1
  8. package/lib/agent-cli-provider/contract-actions.js +5 -5
  9. package/lib/agent-cli-provider/contract-actions.js.map +1 -1
  10. package/lib/agent-cli-provider/contract-invoke.d.ts +1 -1
  11. package/lib/agent-cli-provider/contract-invoke.d.ts.map +1 -1
  12. package/lib/agent-cli-provider/contract-invoke.js +2 -2
  13. package/lib/agent-cli-provider/contract-invoke.js.map +1 -1
  14. package/lib/agent-cli-provider/contract-support.d.ts +1 -1
  15. package/lib/agent-cli-provider/contract-support.d.ts.map +1 -1
  16. package/lib/agent-cli-provider/contract-support.js +2 -2
  17. package/lib/agent-cli-provider/contract-support.js.map +1 -1
  18. package/lib/agent-cli-provider/contract.d.ts +1 -0
  19. package/lib/agent-cli-provider/contract.d.ts.map +1 -1
  20. package/lib/agent-cli-provider/contract.js +1 -1
  21. package/lib/agent-cli-provider/contract.js.map +1 -1
  22. package/lib/agent-cli-provider/index.d.ts +1 -1
  23. package/lib/agent-cli-provider/index.d.ts.map +1 -1
  24. package/lib/agent-cli-provider/index.js +2 -1
  25. package/lib/agent-cli-provider/index.js.map +1 -1
  26. package/lib/agent-cli-provider/provider-registry.d.ts +1 -0
  27. package/lib/agent-cli-provider/provider-registry.d.ts.map +1 -1
  28. package/lib/agent-cli-provider/provider-registry.js +4 -0
  29. package/lib/agent-cli-provider/provider-registry.js.map +1 -1
  30. package/lib/agent-cli-provider/single-agent-runtime.d.ts +3 -3
  31. package/lib/agent-cli-provider/single-agent-runtime.d.ts.map +1 -1
  32. package/lib/agent-cli-provider/single-agent-runtime.js +22 -48
  33. package/lib/agent-cli-provider/single-agent-runtime.js.map +1 -1
  34. package/lib/cluster/client.cjs +30 -7
  35. package/lib/cluster/client.d.cts +52 -0
  36. package/lib/cluster/client.d.mts +52 -0
  37. package/lib/cluster/client.d.ts +4 -6
  38. package/lib/cluster/client.mjs +32 -9
  39. package/lib/cluster/connection-state.cjs +25 -0
  40. package/lib/cluster/connection-state.d.cts +13 -0
  41. package/lib/cluster/connection-state.d.mts +13 -0
  42. package/lib/cluster/connection-state.d.ts +13 -0
  43. package/lib/cluster/connection-state.mjs +21 -0
  44. package/lib/{target/hosted-run/contracts.js → cluster/connection-types.cjs} +0 -1
  45. package/lib/cluster/connection-types.d.cts +33 -0
  46. package/lib/cluster/connection-types.d.mts +33 -0
  47. package/lib/cluster/connection-types.d.ts +33 -0
  48. package/lib/cluster/connection-types.mjs +1 -0
  49. package/lib/cluster/connection.cjs +18 -46
  50. package/lib/cluster/connection.d.cts +26 -0
  51. package/lib/cluster/connection.d.mts +26 -0
  52. package/lib/cluster/connection.d.ts +7 -25
  53. package/lib/cluster/connection.mjs +12 -42
  54. package/lib/cluster/errors.cjs +9 -1
  55. package/lib/cluster/errors.d.cts +29 -0
  56. package/lib/cluster/errors.d.mts +29 -0
  57. package/lib/cluster/errors.d.ts +4 -0
  58. package/lib/cluster/errors.mjs +7 -0
  59. package/lib/cluster/frames.d.cts +12 -0
  60. package/lib/cluster/frames.d.mts +12 -0
  61. package/lib/cluster/generated/protocol-schema.d.cts +1 -0
  62. package/lib/cluster/generated/protocol-schema.d.mts +1 -0
  63. package/lib/cluster/generated/protocol.d.cts +781 -0
  64. package/lib/cluster/generated/protocol.d.mts +781 -0
  65. package/lib/cluster/index.cjs +2 -2
  66. package/lib/cluster/index.d.cts +13 -0
  67. package/lib/cluster/index.d.mts +13 -0
  68. package/lib/cluster/index.d.ts +3 -3
  69. package/lib/cluster/index.mjs +2 -2
  70. package/lib/cluster/json-source.cjs +1 -0
  71. package/lib/cluster/json-source.d.cts +5 -0
  72. package/lib/cluster/json-source.d.mts +5 -0
  73. package/lib/cluster/json-source.d.ts +1 -0
  74. package/lib/cluster/json-source.mjs +1 -0
  75. package/lib/cluster/payload-value.cjs +1 -0
  76. package/lib/cluster/payload-value.d.cts +8 -0
  77. package/lib/cluster/payload-value.d.mts +8 -0
  78. package/lib/cluster/payload-value.d.ts +1 -0
  79. package/lib/cluster/payload-value.mjs +1 -0
  80. package/lib/cluster/queue.d.cts +15 -0
  81. package/lib/cluster/queue.d.mts +15 -0
  82. package/lib/cluster/socket.cjs +8 -0
  83. package/lib/cluster/socket.d.cts +13 -0
  84. package/lib/cluster/socket.d.mts +13 -0
  85. package/lib/cluster/socket.d.ts +2 -0
  86. package/lib/cluster/socket.mjs +7 -0
  87. package/lib/cluster/subscriptions.d.cts +73 -0
  88. package/lib/cluster/subscriptions.d.mts +73 -0
  89. package/lib/cluster/subscriptions.d.ts +5 -1
  90. package/lib/cluster/validators.cjs +1 -0
  91. package/lib/cluster/validators.d.cts +7 -0
  92. package/lib/cluster/validators.d.mts +7 -0
  93. package/lib/cluster/validators.d.ts +1 -0
  94. package/lib/cluster/validators.mjs +1 -0
  95. package/lib/cluster-worker/engine-adapter-common.js +37 -0
  96. package/lib/cluster-worker/engine-adapter.js +24 -30
  97. package/lib/cluster-worker/engine-start.js +59 -0
  98. package/lib/cluster-worker/index.js +49 -67
  99. package/lib/cluster-worker/profiles.js +1 -42
  100. package/lib/cluster-worker/runtime-dependencies.js +49 -0
  101. package/lib/cluster-worker/runtime-support.js +2 -34
  102. package/lib/cluster-worker/terminal-normalizer.js +9 -10
  103. package/lib/hosted-session/authority.cjs +61 -0
  104. package/lib/hosted-session/authority.d.cts +3 -0
  105. package/lib/hosted-session/authority.d.mts +3 -0
  106. package/lib/hosted-session/authority.d.ts +3 -0
  107. package/lib/hosted-session/authority.mjs +57 -0
  108. package/lib/hosted-session/coordinator.cjs +78 -51
  109. package/lib/hosted-session/coordinator.d.cts +11 -0
  110. package/lib/hosted-session/coordinator.d.mts +11 -0
  111. package/lib/hosted-session/coordinator.d.ts +4 -2
  112. package/lib/hosted-session/coordinator.mjs +75 -51
  113. package/lib/hosted-session/errors.cjs +25 -0
  114. package/lib/hosted-session/errors.d.cts +10 -0
  115. package/lib/hosted-session/errors.d.mts +10 -0
  116. package/lib/hosted-session/errors.d.ts +10 -0
  117. package/lib/hosted-session/errors.mjs +19 -0
  118. package/lib/hosted-session/index.cjs +4 -1
  119. package/lib/hosted-session/index.d.cts +2 -0
  120. package/lib/hosted-session/index.d.mts +2 -0
  121. package/lib/hosted-session/index.d.ts +2 -2
  122. package/lib/hosted-session/index.mjs +1 -1
  123. package/lib/hosted-session/reconnecting-watch.cjs +131 -0
  124. package/lib/hosted-session/reconnecting-watch.d.cts +13 -0
  125. package/lib/hosted-session/reconnecting-watch.d.mts +13 -0
  126. package/lib/hosted-session/reconnecting-watch.d.ts +13 -0
  127. package/lib/hosted-session/reconnecting-watch.mjs +127 -0
  128. package/lib/hosted-session/types.d.cts +32 -0
  129. package/lib/hosted-session/types.d.mts +32 -0
  130. package/lib/hosted-session/types.d.ts +19 -7
  131. package/lib/hosted-target/access-url.cjs +44 -0
  132. package/lib/hosted-target/access-url.d.cts +2 -0
  133. package/lib/hosted-target/access-url.d.mts +2 -0
  134. package/lib/hosted-target/access-url.d.ts +2 -0
  135. package/lib/hosted-target/access-url.mjs +41 -0
  136. package/lib/hosted-target/adapter-request.cjs +12 -0
  137. package/lib/hosted-target/adapter-request.d.cts +17 -0
  138. package/lib/hosted-target/adapter-request.d.mts +17 -0
  139. package/lib/hosted-target/adapter-request.d.ts +17 -0
  140. package/lib/hosted-target/adapter-request.mjs +9 -0
  141. package/lib/hosted-target/adapter-types.cjs +2 -0
  142. package/lib/hosted-target/adapter-types.d.cts +27 -0
  143. package/lib/hosted-target/adapter-types.d.mts +27 -0
  144. package/lib/hosted-target/adapter-types.d.ts +27 -0
  145. package/lib/hosted-target/adapter-types.mjs +1 -0
  146. package/lib/hosted-target/bounds.cjs +10 -0
  147. package/lib/hosted-target/bounds.d.cts +7 -0
  148. package/lib/hosted-target/bounds.d.mts +7 -0
  149. package/lib/hosted-target/bounds.d.ts +7 -0
  150. package/lib/hosted-target/bounds.mjs +7 -0
  151. package/lib/hosted-target/capsule-error-response.cjs +76 -0
  152. package/lib/hosted-target/capsule-error-response.d.cts +2 -0
  153. package/lib/hosted-target/capsule-error-response.d.mts +2 -0
  154. package/lib/hosted-target/capsule-error-response.d.ts +2 -0
  155. package/lib/hosted-target/capsule-error-response.mjs +73 -0
  156. package/lib/hosted-target/errors.cjs +88 -0
  157. package/lib/hosted-target/errors.d.cts +36 -0
  158. package/lib/hosted-target/errors.d.mts +36 -0
  159. package/lib/hosted-target/errors.d.ts +36 -0
  160. package/lib/hosted-target/errors.mjs +75 -0
  161. package/lib/hosted-target/index.cjs +16 -0
  162. package/lib/hosted-target/index.d.cts +3 -0
  163. package/lib/hosted-target/index.d.mts +3 -0
  164. package/lib/hosted-target/index.d.ts +3 -0
  165. package/lib/hosted-target/index.mjs +2 -0
  166. package/lib/hosted-target/response-validation.cjs +169 -0
  167. package/lib/hosted-target/response-validation.d.cts +5 -0
  168. package/lib/hosted-target/response-validation.d.mts +5 -0
  169. package/lib/hosted-target/response-validation.d.ts +5 -0
  170. package/lib/hosted-target/response-validation.mjs +163 -0
  171. package/lib/hosted-target/retry-executor.cjs +51 -0
  172. package/lib/hosted-target/retry-executor.d.cts +8 -0
  173. package/lib/hosted-target/retry-executor.d.mts +8 -0
  174. package/lib/hosted-target/retry-executor.d.ts +8 -0
  175. package/lib/hosted-target/retry-executor.mjs +48 -0
  176. package/lib/hosted-target/retry.cjs +78 -0
  177. package/lib/hosted-target/retry.d.cts +9 -0
  178. package/lib/hosted-target/retry.d.mts +9 -0
  179. package/lib/hosted-target/retry.d.ts +9 -0
  180. package/lib/hosted-target/retry.mjs +73 -0
  181. package/lib/hosted-target/target-adapter.cjs +10 -0
  182. package/lib/hosted-target/target-adapter.d.cts +3 -0
  183. package/lib/hosted-target/target-adapter.d.mts +3 -0
  184. package/lib/hosted-target/target-adapter.d.ts +3 -0
  185. package/lib/hosted-target/target-adapter.mjs +7 -0
  186. package/lib/hosted-target/types.cjs +4 -0
  187. package/lib/hosted-target/types.d.cts +50 -0
  188. package/lib/hosted-target/types.d.mts +50 -0
  189. package/lib/hosted-target/types.d.ts +50 -0
  190. package/lib/hosted-target/types.mjs +1 -0
  191. package/lib/hosted-target/zero-cloud-v1-adapter.cjs +185 -0
  192. package/lib/hosted-target/zero-cloud-v1-adapter.d.cts +13 -0
  193. package/lib/hosted-target/zero-cloud-v1-adapter.d.mts +13 -0
  194. package/lib/hosted-target/zero-cloud-v1-adapter.d.ts +13 -0
  195. package/lib/hosted-target/zero-cloud-v1-adapter.mjs +181 -0
  196. package/lib/start-cluster.js +3 -3
  197. package/lib/target/bounded-response.cjs +51 -0
  198. package/lib/target/bounded-response.d.cts +1 -0
  199. package/lib/target/bounded-response.d.mts +1 -0
  200. package/lib/target/bounded-response.d.ts +1 -0
  201. package/lib/target/bounded-response.js +51 -0
  202. package/lib/target/bounded-response.mjs +48 -0
  203. package/lib/target/credential-lock.js +1 -3
  204. package/lib/target/credential-store.js +9 -4
  205. package/lib/target/device-flow.cjs +213 -0
  206. package/lib/target/device-flow.d.cts +54 -0
  207. package/lib/target/device-flow.d.mts +54 -0
  208. package/lib/target/device-flow.d.ts +26 -14
  209. package/lib/target/device-flow.js +162 -58
  210. package/lib/target/device-flow.mjs +203 -0
  211. package/lib/target/discovery-errors.cjs +10 -0
  212. package/lib/target/discovery-errors.d.cts +3 -0
  213. package/lib/target/discovery-errors.d.mts +3 -0
  214. package/lib/target/discovery-errors.d.ts +3 -0
  215. package/lib/target/discovery-errors.js +10 -0
  216. package/lib/target/discovery-errors.mjs +6 -0
  217. package/lib/target/discovery-sections.cjs +191 -0
  218. package/lib/target/discovery-sections.d.cts +52 -0
  219. package/lib/target/discovery-sections.d.mts +52 -0
  220. package/lib/target/discovery-sections.d.ts +52 -0
  221. package/lib/target/discovery-sections.js +191 -0
  222. package/lib/target/discovery-sections.mjs +179 -0
  223. package/lib/target/discovery-validation.cjs +109 -0
  224. package/lib/target/discovery-validation.d.cts +28 -0
  225. package/lib/target/discovery-validation.d.mts +28 -0
  226. package/lib/target/discovery-validation.d.ts +28 -0
  227. package/lib/target/discovery-validation.js +109 -0
  228. package/lib/target/discovery-validation.mjs +99 -0
  229. package/lib/target/discovery.cjs +112 -0
  230. package/lib/target/discovery.d.cts +74 -0
  231. package/lib/target/discovery.d.mts +74 -0
  232. package/lib/target/discovery.d.ts +67 -5
  233. package/lib/target/discovery.js +94 -79
  234. package/lib/target/discovery.mjs +105 -0
  235. package/lib/target/index.d.ts +6 -6
  236. package/lib/target/index.js +36 -36
  237. package/lib/target/oauth-http.d.ts +2 -0
  238. package/lib/target/oauth-http.js +25 -0
  239. package/lib/target/refresh-exchange.d.ts +11 -0
  240. package/lib/target/refresh-exchange.js +24 -0
  241. package/lib/target/refresh-revocation.d.ts +8 -0
  242. package/lib/target/refresh-revocation.js +19 -0
  243. package/lib/target/route-template.cjs +85 -0
  244. package/lib/target/route-template.d.cts +7 -0
  245. package/lib/target/route-template.d.mts +7 -0
  246. package/lib/target/route-template.d.ts +7 -0
  247. package/lib/target/route-template.js +85 -0
  248. package/lib/target/route-template.mjs +81 -0
  249. package/lib/target/session-errors.d.ts +4 -0
  250. package/lib/target/session-errors.js +12 -0
  251. package/lib/target/session-verification.d.ts +10 -0
  252. package/lib/target/session-verification.js +42 -0
  253. package/lib/target/target-registry.d.ts +7 -3
  254. package/lib/target/target-registry.js +41 -10
  255. package/lib/target/target-session-manager.d.ts +48 -0
  256. package/lib/target/target-session-manager.js +226 -0
  257. package/lib/target/target-session.d.ts +39 -32
  258. package/lib/target/target-session.js +63 -151
  259. package/lib/target/token-response.cjs +51 -0
  260. package/lib/target/token-response.d.cts +7 -0
  261. package/lib/target/token-response.d.mts +7 -0
  262. package/lib/target/token-response.d.ts +7 -0
  263. package/lib/target/token-response.js +51 -0
  264. package/lib/target/token-response.mjs +48 -0
  265. package/package.json +14 -7
  266. package/protocol/openengine-cluster/v1/worker.schema.json +171 -9
  267. package/scripts/build-cluster.js +23 -3
  268. package/scripts/opcore-introduced-check.js +0 -2
  269. package/src/agent-cli-provider/adapters/codex.ts +0 -1
  270. package/src/agent-cli-provider/contract-actions.ts +9 -5
  271. package/src/agent-cli-provider/contract-invoke.ts +3 -2
  272. package/src/agent-cli-provider/contract-support.ts +12 -6
  273. package/src/agent-cli-provider/contract.ts +6 -1
  274. package/src/agent-cli-provider/index.ts +1 -0
  275. package/src/agent-cli-provider/provider-registry.ts +4 -0
  276. package/src/agent-cli-provider/single-agent-runtime.ts +32 -45
  277. package/src/cluster/client.ts +42 -15
  278. package/src/cluster/connection-state.ts +33 -0
  279. package/src/cluster/connection-types.ts +28 -0
  280. package/src/cluster/connection.ts +37 -68
  281. package/src/cluster/errors.ts +5 -0
  282. package/src/cluster/index.ts +3 -1
  283. package/src/cluster/json-source.ts +1 -0
  284. package/src/cluster/payload-value.ts +1 -0
  285. package/src/cluster/socket.ts +13 -0
  286. package/src/cluster/subscriptions.ts +7 -2
  287. package/src/cluster/validators.ts +1 -0
  288. package/src/cluster/ws.d.ts +1 -1
  289. package/src/hosted-session/authority.ts +77 -0
  290. package/src/hosted-session/coordinator.ts +113 -56
  291. package/src/hosted-session/errors.ts +21 -0
  292. package/src/hosted-session/index.ts +14 -2
  293. package/src/hosted-session/reconnecting-watch.ts +148 -0
  294. package/src/hosted-session/types.ts +22 -8
  295. package/src/hosted-target/access-url.ts +46 -0
  296. package/src/hosted-target/adapter-request.ts +28 -0
  297. package/src/hosted-target/adapter-types.ts +39 -0
  298. package/src/hosted-target/bounds.ts +1 -0
  299. package/src/hosted-target/capsule-error-response.ts +107 -0
  300. package/src/hosted-target/errors.ts +36 -35
  301. package/src/hosted-target/index.ts +10 -23
  302. package/src/hosted-target/response-validation.ts +170 -62
  303. package/src/hosted-target/retry-executor.ts +62 -0
  304. package/src/hosted-target/retry.ts +47 -11
  305. package/src/hosted-target/target-adapter.ts +12 -8
  306. package/src/hosted-target/types.ts +19 -18
  307. package/src/hosted-target/zero-cloud-v1-adapter.ts +229 -316
  308. package/src/isolation-manager.js +1 -16
  309. package/src/target/bounded-response.ts +68 -0
  310. package/src/target/credential-lock.ts +1 -3
  311. package/src/target/credential-store.ts +14 -10
  312. package/src/target/device-flow.ts +209 -85
  313. package/src/target/discovery-errors.ts +6 -0
  314. package/src/target/discovery-sections.ts +251 -0
  315. package/src/target/discovery-validation.ts +144 -0
  316. package/src/target/discovery.ts +163 -97
  317. package/src/target/index.ts +15 -11
  318. package/src/target/oauth-http.ts +27 -0
  319. package/src/target/refresh-exchange.ts +36 -0
  320. package/src/target/refresh-revocation.ts +29 -0
  321. package/src/target/route-template.ts +105 -0
  322. package/src/target/session-errors.ts +9 -0
  323. package/src/target/session-verification.ts +51 -0
  324. package/src/target/target-registry.ts +60 -27
  325. package/src/target/target-session-manager.ts +285 -0
  326. package/src/target/target-session.ts +105 -226
  327. package/src/target/token-response.ts +62 -0
  328. package/docker/zeroshot-oecp/Cargo.toml +0 -12
  329. package/docker/zeroshot-oecp/Dockerfile +0 -65
  330. package/docker/zeroshot-oecp/src/main.rs +0 -32
  331. package/lib/target/bounded-json.d.ts +0 -6
  332. package/lib/target/bounded-json.js +0 -43
  333. package/lib/target/hosted-run/client.d.ts +0 -26
  334. package/lib/target/hosted-run/client.js +0 -158
  335. package/lib/target/hosted-run/commands.d.ts +0 -4
  336. package/lib/target/hosted-run/commands.js +0 -113
  337. package/lib/target/hosted-run/contracts.d.ts +0 -49
  338. package/lib/target/hosted-run/input.d.ts +0 -5
  339. package/lib/target/hosted-run/input.js +0 -200
  340. package/lib/target/hosted-run.d.ts +0 -4
  341. package/lib/target/hosted-run.js +0 -12
  342. package/src/target/bounded-json.ts +0 -48
  343. package/src/target/hosted-run/client.ts +0 -198
  344. package/src/target/hosted-run/commands.ts +0 -140
  345. package/src/target/hosted-run/contracts.ts +0 -53
  346. package/src/target/hosted-run/input.ts +0 -199
  347. package/src/target/hosted-run.ts +0 -8
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.expandRoute = exports.TargetDiscoveryError = void 0;
4
+ exports.discoverTarget = discoverTarget;
5
+ exports.discoverTargetSessionEndpoints = discoverTargetSessionEndpoints;
6
+ const bounded_response_js_1 = require("./bounded-response.cjs");
7
+ const discovery_errors_js_1 = require("./discovery-errors.cjs");
8
+ const discovery_validation_js_1 = require("./discovery-validation.cjs");
9
+ const discovery_sections_js_1 = require("./discovery-sections.cjs");
10
+ var discovery_errors_js_2 = require("./discovery-errors.cjs");
11
+ Object.defineProperty(exports, "TargetDiscoveryError", { enumerable: true, get: function () { return discovery_errors_js_2.TargetDiscoveryError; } });
12
+ var route_template_js_1 = require("./route-template.cjs");
13
+ Object.defineProperty(exports, "expandRoute", { enumerable: true, get: function () { return route_template_js_1.expandRoute; } });
14
+ const DISCOVERY_PATH = '/.well-known/openengine-hosted-target';
15
+ const MAX_DISCOVERY_BYTES = 64 * 1024;
16
+ const DEVICE_GRANT = 'urn:ietf:params:oauth:grant-type:device_code';
17
+ const CAPSULE_AUDIENCE = 'capsule';
18
+ const ROOT_FIELDS = [
19
+ 'kind',
20
+ 'adapter',
21
+ 'protocol',
22
+ 'binding',
23
+ 'endpoint',
24
+ 'pagination',
25
+ 'cache_policy',
26
+ 'schema_links',
27
+ 'capsule_protocol',
28
+ 'oauth',
29
+ 'organization_binding',
30
+ 'capability_flags',
31
+ 'sizes',
32
+ 'session',
33
+ 'transport',
34
+ 'extensions',
35
+ ];
36
+ async function readBoundedJson(response) {
37
+ return (0, bounded_response_js_1.readBoundedResponseJson)(response, MAX_DISCOVERY_BYTES, (kind) => new discovery_errors_js_1.TargetDiscoveryError(kind === 'size' ? 'response exceeds the size limit' : 'response is not valid UTF-8 JSON'));
38
+ }
39
+ async function fetchDocument(http, url) {
40
+ const response = await http.fetch(url, {
41
+ method: 'GET',
42
+ headers: { Accept: 'application/json' },
43
+ redirect: 'error',
44
+ });
45
+ if (response.url && new URL(response.url).href !== url) {
46
+ await response.body?.cancel().catch(() => undefined);
47
+ throw new discovery_errors_js_1.TargetDiscoveryError('request changed target route or authority');
48
+ }
49
+ if (!response.ok) {
50
+ await response.body?.cancel().catch(() => undefined);
51
+ throw new discovery_errors_js_1.TargetDiscoveryError(`request failed with status ${response.status}`);
52
+ }
53
+ return (0, discovery_validation_js_1.record)(await readBoundedJson(response), 'response');
54
+ }
55
+ async function discoverTarget(targetUrl, http) {
56
+ const target = new URL(targetUrl);
57
+ const origin = target.origin;
58
+ const discovery = await fetchDocument(http, new URL(DISCOVERY_PATH, target).href);
59
+ (0, discovery_validation_js_1.exact)(discovery.kind, 'openengine.hosted-target/v1', 'kind');
60
+ const adapter = (0, discovery_sections_js_1.parseAdapter)(discovery);
61
+ const endpoint = (0, discovery_sections_js_1.parseEndpoint)(discovery, origin);
62
+ const capsule = (0, discovery_sections_js_1.parseCapsule)(discovery, origin);
63
+ const oauth = (0, discovery_sections_js_1.parseOAuth)(discovery, origin);
64
+ (0, discovery_validation_js_1.exact)(discovery.organization_binding, 'device_approval', 'organization_binding');
65
+ const capabilityFlags = (0, discovery_validation_js_1.exactStringSet)(discovery.capability_flags, 'capability_flags', [
66
+ 'capsule_allocate',
67
+ 'capsule_read',
68
+ 'capsule_terminate',
69
+ 'capsule_access',
70
+ 'connections_onboarding',
71
+ ]);
72
+ const sizes = (0, discovery_sections_js_1.parseSizes)(discovery);
73
+ const session = (0, discovery_sections_js_1.parseSession)(discovery);
74
+ const transport = (0, discovery_sections_js_1.parseTransport)(discovery);
75
+ const credentialInstall = (0, discovery_sections_js_1.parseExtensions)(discovery, origin);
76
+ const metadata = await fetchDocument(http, oauth.metadataUrl);
77
+ (0, discovery_sections_js_1.validateOAuthMetadata)(metadata, origin, [
78
+ oauth.deviceAuthorizationEndpoint,
79
+ oauth.tokenEndpoint,
80
+ oauth.revocationEndpoint,
81
+ ]);
82
+ const additional = Object.freeze(Object.fromEntries(Object.entries(discovery).filter(([key]) => !ROOT_FIELDS.includes(key))));
83
+ return Object.freeze({
84
+ origin,
85
+ adapter,
86
+ endpoint: endpoint.url,
87
+ endpointCapabilities: endpoint.capabilities,
88
+ pagination: endpoint.pagination,
89
+ sizes,
90
+ oauth,
91
+ session,
92
+ capsule,
93
+ transport,
94
+ capabilityFlags,
95
+ credentialInstall,
96
+ additional,
97
+ });
98
+ }
99
+ async function discoverTargetSessionEndpoints(targetUrl, http) {
100
+ const descriptor = await discoverTarget(targetUrl, http);
101
+ return Object.freeze({
102
+ deviceAuthorizationEndpoint: descriptor.oauth.deviceAuthorizationEndpoint,
103
+ tokenEndpoint: descriptor.oauth.tokenEndpoint,
104
+ revocationEndpoint: descriptor.oauth.revocationEndpoint,
105
+ clientId: descriptor.oauth.clientId,
106
+ capsuleApiBaseUrl: descriptor.capsule.baseUrl.replace(/\/$/, ''),
107
+ deviceGrantType: descriptor.oauth.deviceGrantType,
108
+ audience: descriptor.oauth.audience,
109
+ sessionEndpoint: new URL(descriptor.session.routeTemplate.template, descriptor.origin).href,
110
+ descriptor,
111
+ });
112
+ }
@@ -0,0 +1,74 @@
1
+ import type { HttpTransport } from './device-flow.js';
2
+ import type { RouteTemplate } from './route-template.js';
3
+ import { type CredentialInstallDescriptor } from './discovery-validation.js';
4
+ export type { CredentialInstallDescriptor } from './discovery-validation.js';
5
+ export { TargetDiscoveryError } from './discovery-errors.js';
6
+ export { expandRoute, type RouteTemplate } from './route-template.js';
7
+ declare const DEVICE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
8
+ declare const CAPSULE_AUDIENCE = "capsule";
9
+ export interface TargetDiscoveryDescriptor {
10
+ readonly origin: string;
11
+ readonly adapter: {
12
+ readonly name: 'fargate' | 'docker' | 'local';
13
+ readonly majorVersion: 1;
14
+ };
15
+ readonly endpoint: string;
16
+ readonly endpointCapabilities: readonly ['exec', 'log_stream'];
17
+ readonly pagination: {
18
+ readonly defaultPageSize: number;
19
+ readonly maxPageSize: number;
20
+ };
21
+ readonly sizes: {
22
+ readonly catalog: readonly ('tiny' | 'small' | 'standard' | 'large')[];
23
+ readonly default: 'tiny' | 'small' | 'standard' | 'large';
24
+ };
25
+ readonly oauth: {
26
+ readonly metadataUrl: string;
27
+ readonly deviceAuthorizationEndpoint: string;
28
+ readonly tokenEndpoint: string;
29
+ readonly revocationEndpoint: string;
30
+ readonly clientId: string;
31
+ readonly deviceGrantType: typeof DEVICE_GRANT;
32
+ readonly audience: typeof CAPSULE_AUDIENCE;
33
+ };
34
+ readonly session: {
35
+ readonly routeTemplate: RouteTemplate;
36
+ readonly method: 'GET';
37
+ };
38
+ readonly capsule: {
39
+ readonly baseUrl: string;
40
+ readonly routes: {
41
+ readonly allocate: RouteTemplate;
42
+ readonly list: RouteTemplate;
43
+ readonly inspect: RouteTemplate;
44
+ readonly terminate: RouteTemplate;
45
+ readonly limits: RouteTemplate;
46
+ readonly access: RouteTemplate;
47
+ };
48
+ };
49
+ readonly transport: {
50
+ readonly websocketRouteTemplate: RouteTemplate;
51
+ readonly unauthorizedStatus: 401;
52
+ readonly closeCodes: {
53
+ readonly expired: 4401;
54
+ readonly revoked: 4403;
55
+ };
56
+ };
57
+ readonly capabilityFlags: readonly string[];
58
+ readonly credentialInstall: CredentialInstallDescriptor | null;
59
+ readonly additional: Readonly<Record<string, unknown>>;
60
+ }
61
+ /** Compatibility projection. New callers should retain the complete descriptor. */
62
+ export interface TargetSessionEndpoints {
63
+ readonly deviceAuthorizationEndpoint: string;
64
+ readonly tokenEndpoint: string;
65
+ readonly revocationEndpoint: string;
66
+ readonly clientId: string;
67
+ readonly capsuleApiBaseUrl: string;
68
+ readonly deviceGrantType: typeof DEVICE_GRANT;
69
+ readonly audience: typeof CAPSULE_AUDIENCE;
70
+ readonly sessionEndpoint: string;
71
+ readonly descriptor: TargetDiscoveryDescriptor;
72
+ }
73
+ export declare function discoverTarget(targetUrl: string, http: HttpTransport): Promise<TargetDiscoveryDescriptor>;
74
+ export declare function discoverTargetSessionEndpoints(targetUrl: string, http: HttpTransport): Promise<TargetSessionEndpoints>;
@@ -0,0 +1,74 @@
1
+ import type { HttpTransport } from './device-flow.js';
2
+ import type { RouteTemplate } from './route-template.js';
3
+ import { type CredentialInstallDescriptor } from './discovery-validation.js';
4
+ export type { CredentialInstallDescriptor } from './discovery-validation.js';
5
+ export { TargetDiscoveryError } from './discovery-errors.js';
6
+ export { expandRoute, type RouteTemplate } from './route-template.js';
7
+ declare const DEVICE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
8
+ declare const CAPSULE_AUDIENCE = "capsule";
9
+ export interface TargetDiscoveryDescriptor {
10
+ readonly origin: string;
11
+ readonly adapter: {
12
+ readonly name: 'fargate' | 'docker' | 'local';
13
+ readonly majorVersion: 1;
14
+ };
15
+ readonly endpoint: string;
16
+ readonly endpointCapabilities: readonly ['exec', 'log_stream'];
17
+ readonly pagination: {
18
+ readonly defaultPageSize: number;
19
+ readonly maxPageSize: number;
20
+ };
21
+ readonly sizes: {
22
+ readonly catalog: readonly ('tiny' | 'small' | 'standard' | 'large')[];
23
+ readonly default: 'tiny' | 'small' | 'standard' | 'large';
24
+ };
25
+ readonly oauth: {
26
+ readonly metadataUrl: string;
27
+ readonly deviceAuthorizationEndpoint: string;
28
+ readonly tokenEndpoint: string;
29
+ readonly revocationEndpoint: string;
30
+ readonly clientId: string;
31
+ readonly deviceGrantType: typeof DEVICE_GRANT;
32
+ readonly audience: typeof CAPSULE_AUDIENCE;
33
+ };
34
+ readonly session: {
35
+ readonly routeTemplate: RouteTemplate;
36
+ readonly method: 'GET';
37
+ };
38
+ readonly capsule: {
39
+ readonly baseUrl: string;
40
+ readonly routes: {
41
+ readonly allocate: RouteTemplate;
42
+ readonly list: RouteTemplate;
43
+ readonly inspect: RouteTemplate;
44
+ readonly terminate: RouteTemplate;
45
+ readonly limits: RouteTemplate;
46
+ readonly access: RouteTemplate;
47
+ };
48
+ };
49
+ readonly transport: {
50
+ readonly websocketRouteTemplate: RouteTemplate;
51
+ readonly unauthorizedStatus: 401;
52
+ readonly closeCodes: {
53
+ readonly expired: 4401;
54
+ readonly revoked: 4403;
55
+ };
56
+ };
57
+ readonly capabilityFlags: readonly string[];
58
+ readonly credentialInstall: CredentialInstallDescriptor | null;
59
+ readonly additional: Readonly<Record<string, unknown>>;
60
+ }
61
+ /** Compatibility projection. New callers should retain the complete descriptor. */
62
+ export interface TargetSessionEndpoints {
63
+ readonly deviceAuthorizationEndpoint: string;
64
+ readonly tokenEndpoint: string;
65
+ readonly revocationEndpoint: string;
66
+ readonly clientId: string;
67
+ readonly capsuleApiBaseUrl: string;
68
+ readonly deviceGrantType: typeof DEVICE_GRANT;
69
+ readonly audience: typeof CAPSULE_AUDIENCE;
70
+ readonly sessionEndpoint: string;
71
+ readonly descriptor: TargetDiscoveryDescriptor;
72
+ }
73
+ export declare function discoverTarget(targetUrl: string, http: HttpTransport): Promise<TargetDiscoveryDescriptor>;
74
+ export declare function discoverTargetSessionEndpoints(targetUrl: string, http: HttpTransport): Promise<TargetSessionEndpoints>;
@@ -1,12 +1,74 @@
1
- import type { HttpTransport } from './device-flow.ts';
1
+ import type { HttpTransport } from './device-flow.js';
2
+ import type { RouteTemplate } from './route-template.js';
3
+ import { type CredentialInstallDescriptor } from './discovery-validation.js';
4
+ export type { CredentialInstallDescriptor } from './discovery-validation.js';
5
+ export { TargetDiscoveryError } from './discovery-errors.js';
6
+ export { expandRoute, type RouteTemplate } from './route-template.js';
7
+ declare const DEVICE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
8
+ declare const CAPSULE_AUDIENCE = "capsule";
9
+ export interface TargetDiscoveryDescriptor {
10
+ readonly origin: string;
11
+ readonly adapter: {
12
+ readonly name: 'fargate' | 'docker' | 'local';
13
+ readonly majorVersion: 1;
14
+ };
15
+ readonly endpoint: string;
16
+ readonly endpointCapabilities: readonly ['exec', 'log_stream'];
17
+ readonly pagination: {
18
+ readonly defaultPageSize: number;
19
+ readonly maxPageSize: number;
20
+ };
21
+ readonly sizes: {
22
+ readonly catalog: readonly ('tiny' | 'small' | 'standard' | 'large')[];
23
+ readonly default: 'tiny' | 'small' | 'standard' | 'large';
24
+ };
25
+ readonly oauth: {
26
+ readonly metadataUrl: string;
27
+ readonly deviceAuthorizationEndpoint: string;
28
+ readonly tokenEndpoint: string;
29
+ readonly revocationEndpoint: string;
30
+ readonly clientId: string;
31
+ readonly deviceGrantType: typeof DEVICE_GRANT;
32
+ readonly audience: typeof CAPSULE_AUDIENCE;
33
+ };
34
+ readonly session: {
35
+ readonly routeTemplate: RouteTemplate;
36
+ readonly method: 'GET';
37
+ };
38
+ readonly capsule: {
39
+ readonly baseUrl: string;
40
+ readonly routes: {
41
+ readonly allocate: RouteTemplate;
42
+ readonly list: RouteTemplate;
43
+ readonly inspect: RouteTemplate;
44
+ readonly terminate: RouteTemplate;
45
+ readonly limits: RouteTemplate;
46
+ readonly access: RouteTemplate;
47
+ };
48
+ };
49
+ readonly transport: {
50
+ readonly websocketRouteTemplate: RouteTemplate;
51
+ readonly unauthorizedStatus: 401;
52
+ readonly closeCodes: {
53
+ readonly expired: 4401;
54
+ readonly revoked: 4403;
55
+ };
56
+ };
57
+ readonly capabilityFlags: readonly string[];
58
+ readonly credentialInstall: CredentialInstallDescriptor | null;
59
+ readonly additional: Readonly<Record<string, unknown>>;
60
+ }
61
+ /** Compatibility projection. New callers should retain the complete descriptor. */
2
62
  export interface TargetSessionEndpoints {
3
63
  readonly deviceAuthorizationEndpoint: string;
4
64
  readonly tokenEndpoint: string;
5
- readonly revocationEndpoint?: string;
65
+ readonly revocationEndpoint: string;
6
66
  readonly clientId: string;
7
67
  readonly capsuleApiBaseUrl: string;
68
+ readonly deviceGrantType: typeof DEVICE_GRANT;
69
+ readonly audience: typeof CAPSULE_AUDIENCE;
70
+ readonly sessionEndpoint: string;
71
+ readonly descriptor: TargetDiscoveryDescriptor;
8
72
  }
9
- export declare class TargetDiscoveryError extends Error {
10
- constructor(message: string);
11
- }
73
+ export declare function discoverTarget(targetUrl: string, http: HttpTransport): Promise<TargetDiscoveryDescriptor>;
12
74
  export declare function discoverTargetSessionEndpoints(targetUrl: string, http: HttpTransport): Promise<TargetSessionEndpoints>;
@@ -1,48 +1,40 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TargetDiscoveryError = void 0;
3
+ exports.expandRoute = exports.TargetDiscoveryError = void 0;
4
+ exports.discoverTarget = discoverTarget;
4
5
  exports.discoverTargetSessionEndpoints = discoverTargetSessionEndpoints;
5
- const bounded_json_ts_1 = require("./bounded-json.js");
6
+ const bounded_response_js_1 = require("./bounded-response.js");
7
+ const discovery_errors_js_1 = require("./discovery-errors.js");
8
+ const discovery_validation_js_1 = require("./discovery-validation.js");
9
+ const discovery_sections_js_1 = require("./discovery-sections.js");
10
+ var discovery_errors_js_2 = require("./discovery-errors.js");
11
+ Object.defineProperty(exports, "TargetDiscoveryError", { enumerable: true, get: function () { return discovery_errors_js_2.TargetDiscoveryError; } });
12
+ var route_template_js_1 = require("./route-template.js");
13
+ Object.defineProperty(exports, "expandRoute", { enumerable: true, get: function () { return route_template_js_1.expandRoute; } });
6
14
  const DISCOVERY_PATH = '/.well-known/openengine-hosted-target';
7
15
  const MAX_DISCOVERY_BYTES = 64 * 1024;
8
- class TargetDiscoveryError extends Error {
9
- constructor(message) {
10
- super(`Target discovery failed: ${message}`);
11
- this.name = 'TargetDiscoveryError';
12
- }
13
- }
14
- exports.TargetDiscoveryError = TargetDiscoveryError;
15
- function record(value, field) {
16
- if (value === null || typeof value !== 'object' || Array.isArray(value)) {
17
- throw new TargetDiscoveryError(`${field} must be an object`);
18
- }
19
- return value;
20
- }
21
- function stringField(source, field) {
22
- const value = source[field];
23
- if (typeof value !== 'string' || value.length === 0) {
24
- throw new TargetDiscoveryError(`${field} must be a non-empty string`);
25
- }
26
- return value;
27
- }
28
- function safeEndpoint(value, field, serviceOrigin) {
29
- if (typeof value !== 'string') {
30
- throw new TargetDiscoveryError(`${field} must be an absolute URL`);
31
- }
32
- let endpoint;
33
- try {
34
- endpoint = new URL(value);
35
- }
36
- catch {
37
- throw new TargetDiscoveryError(`${field} must be an absolute URL`);
38
- }
39
- if (endpoint.username || endpoint.password || endpoint.search || endpoint.hash) {
40
- throw new TargetDiscoveryError(`${field} contains forbidden URL components`);
41
- }
42
- if (endpoint.origin !== serviceOrigin) {
43
- throw new TargetDiscoveryError(`${field} must remain on the target origin`);
44
- }
45
- return endpoint.href;
16
+ const DEVICE_GRANT = 'urn:ietf:params:oauth:grant-type:device_code';
17
+ const CAPSULE_AUDIENCE = 'capsule';
18
+ const ROOT_FIELDS = [
19
+ 'kind',
20
+ 'adapter',
21
+ 'protocol',
22
+ 'binding',
23
+ 'endpoint',
24
+ 'pagination',
25
+ 'cache_policy',
26
+ 'schema_links',
27
+ 'capsule_protocol',
28
+ 'oauth',
29
+ 'organization_binding',
30
+ 'capability_flags',
31
+ 'sizes',
32
+ 'session',
33
+ 'transport',
34
+ 'extensions',
35
+ ];
36
+ async function readBoundedJson(response) {
37
+ return (0, bounded_response_js_1.readBoundedResponseJson)(response, MAX_DISCOVERY_BYTES, (kind) => new discovery_errors_js_1.TargetDiscoveryError(kind === 'size' ? 'response exceeds the size limit' : 'response is not valid UTF-8 JSON'));
46
38
  }
47
39
  async function fetchDocument(http, url) {
48
40
  const response = await http.fetch(url, {
@@ -50,48 +42,71 @@ async function fetchDocument(http, url) {
50
42
  headers: { Accept: 'application/json' },
51
43
  redirect: 'error',
52
44
  });
45
+ if (response.url && new URL(response.url).href !== url) {
46
+ await response.body?.cancel().catch(() => undefined);
47
+ throw new discovery_errors_js_1.TargetDiscoveryError('request changed target route or authority');
48
+ }
53
49
  if (!response.ok) {
54
- throw new TargetDiscoveryError(`request failed with status ${response.status}`);
50
+ await response.body?.cancel().catch(() => undefined);
51
+ throw new discovery_errors_js_1.TargetDiscoveryError(`request failed with status ${response.status}`);
55
52
  }
56
- const body = await (0, bounded_json_ts_1.readBoundedJson)(response, MAX_DISCOVERY_BYTES, {
57
- tooLarge: () => new TargetDiscoveryError('response exceeds the size limit'),
58
- invalid: () => new TargetDiscoveryError('response is not valid JSON'),
59
- });
60
- return record(body, 'response');
53
+ return (0, discovery_validation_js_1.record)(await readBoundedJson(response), 'response');
61
54
  }
62
- async function discoverTargetSessionEndpoints(targetUrl, http) {
55
+ async function discoverTarget(targetUrl, http) {
63
56
  const target = new URL(targetUrl);
57
+ const origin = target.origin;
64
58
  const discovery = await fetchDocument(http, new URL(DISCOVERY_PATH, target).href);
65
- if (discovery.kind !== 'openengine.hosted-target/v1') {
66
- throw new TargetDiscoveryError('unsupported hosted-target version');
67
- }
68
- if (discovery.organization_binding !== 'device_approval') {
69
- throw new TargetDiscoveryError('unsupported organization binding');
70
- }
71
- const oauth = record(discovery.oauth, 'oauth');
72
- const capsuleProtocol = record(discovery.capsule_protocol, 'capsule_protocol');
73
- if (capsuleProtocol.name !== 'openengine.capsules/v1' || capsuleProtocol.major_version !== 1) {
74
- throw new TargetDiscoveryError('unsupported capsule protocol');
75
- }
76
- const capsuleApiBaseUrl = safeEndpoint(capsuleProtocol.base_url, 'capsule_protocol.base_url', target.origin).replace(/\/$/, '');
77
- const metadataUrl = safeEndpoint(oauth.metadata_url, 'oauth.metadata_url', target.origin);
78
- const deviceEndpoint = safeEndpoint(oauth.device_authorization_endpoint, 'oauth.device_authorization_endpoint', target.origin);
79
- const tokenEndpoint = safeEndpoint(oauth.token_endpoint, 'oauth.token_endpoint', target.origin);
80
- const clientId = stringField(oauth, 'client_id');
81
- const metadata = await fetchDocument(http, metadataUrl);
82
- const metadataDeviceEndpoint = safeEndpoint(metadata.device_authorization_endpoint, 'device_authorization_endpoint', target.origin);
83
- const metadataTokenEndpoint = safeEndpoint(metadata.token_endpoint, 'token_endpoint', target.origin);
84
- if (metadataDeviceEndpoint !== deviceEndpoint || metadataTokenEndpoint !== tokenEndpoint) {
85
- throw new TargetDiscoveryError('OAuth metadata does not match hosted-target discovery');
86
- }
87
- const revocationEndpoint = metadata.revocation_endpoint === undefined
88
- ? undefined
89
- : safeEndpoint(metadata.revocation_endpoint, 'revocation_endpoint', target.origin);
90
- return {
91
- deviceAuthorizationEndpoint: deviceEndpoint,
92
- tokenEndpoint,
93
- ...(revocationEndpoint === undefined ? {} : { revocationEndpoint }),
94
- clientId,
95
- capsuleApiBaseUrl,
96
- };
59
+ (0, discovery_validation_js_1.exact)(discovery.kind, 'openengine.hosted-target/v1', 'kind');
60
+ const adapter = (0, discovery_sections_js_1.parseAdapter)(discovery);
61
+ const endpoint = (0, discovery_sections_js_1.parseEndpoint)(discovery, origin);
62
+ const capsule = (0, discovery_sections_js_1.parseCapsule)(discovery, origin);
63
+ const oauth = (0, discovery_sections_js_1.parseOAuth)(discovery, origin);
64
+ (0, discovery_validation_js_1.exact)(discovery.organization_binding, 'device_approval', 'organization_binding');
65
+ const capabilityFlags = (0, discovery_validation_js_1.exactStringSet)(discovery.capability_flags, 'capability_flags', [
66
+ 'capsule_allocate',
67
+ 'capsule_read',
68
+ 'capsule_terminate',
69
+ 'capsule_access',
70
+ 'connections_onboarding',
71
+ ]);
72
+ const sizes = (0, discovery_sections_js_1.parseSizes)(discovery);
73
+ const session = (0, discovery_sections_js_1.parseSession)(discovery);
74
+ const transport = (0, discovery_sections_js_1.parseTransport)(discovery);
75
+ const credentialInstall = (0, discovery_sections_js_1.parseExtensions)(discovery, origin);
76
+ const metadata = await fetchDocument(http, oauth.metadataUrl);
77
+ (0, discovery_sections_js_1.validateOAuthMetadata)(metadata, origin, [
78
+ oauth.deviceAuthorizationEndpoint,
79
+ oauth.tokenEndpoint,
80
+ oauth.revocationEndpoint,
81
+ ]);
82
+ const additional = Object.freeze(Object.fromEntries(Object.entries(discovery).filter(([key]) => !ROOT_FIELDS.includes(key))));
83
+ return Object.freeze({
84
+ origin,
85
+ adapter,
86
+ endpoint: endpoint.url,
87
+ endpointCapabilities: endpoint.capabilities,
88
+ pagination: endpoint.pagination,
89
+ sizes,
90
+ oauth,
91
+ session,
92
+ capsule,
93
+ transport,
94
+ capabilityFlags,
95
+ credentialInstall,
96
+ additional,
97
+ });
98
+ }
99
+ async function discoverTargetSessionEndpoints(targetUrl, http) {
100
+ const descriptor = await discoverTarget(targetUrl, http);
101
+ return Object.freeze({
102
+ deviceAuthorizationEndpoint: descriptor.oauth.deviceAuthorizationEndpoint,
103
+ tokenEndpoint: descriptor.oauth.tokenEndpoint,
104
+ revocationEndpoint: descriptor.oauth.revocationEndpoint,
105
+ clientId: descriptor.oauth.clientId,
106
+ capsuleApiBaseUrl: descriptor.capsule.baseUrl.replace(/\/$/, ''),
107
+ deviceGrantType: descriptor.oauth.deviceGrantType,
108
+ audience: descriptor.oauth.audience,
109
+ sessionEndpoint: new URL(descriptor.session.routeTemplate.template, descriptor.origin).href,
110
+ descriptor,
111
+ });
97
112
  }
@@ -0,0 +1,105 @@
1
+ import { readBoundedResponseJson } from './bounded-response.mjs';
2
+ import { TargetDiscoveryError } from './discovery-errors.mjs';
3
+ import { exact, exactStringSet, record, } from './discovery-validation.mjs';
4
+ import { parseAdapter, parseCapsule, parseEndpoint, parseExtensions, parseOAuth, parseSession, parseSizes, parseTransport, validateOAuthMetadata, } from './discovery-sections.mjs';
5
+ export { TargetDiscoveryError } from './discovery-errors.mjs';
6
+ export { expandRoute } from './route-template.mjs';
7
+ const DISCOVERY_PATH = '/.well-known/openengine-hosted-target';
8
+ const MAX_DISCOVERY_BYTES = 64 * 1024;
9
+ const DEVICE_GRANT = 'urn:ietf:params:oauth:grant-type:device_code';
10
+ const CAPSULE_AUDIENCE = 'capsule';
11
+ const ROOT_FIELDS = [
12
+ 'kind',
13
+ 'adapter',
14
+ 'protocol',
15
+ 'binding',
16
+ 'endpoint',
17
+ 'pagination',
18
+ 'cache_policy',
19
+ 'schema_links',
20
+ 'capsule_protocol',
21
+ 'oauth',
22
+ 'organization_binding',
23
+ 'capability_flags',
24
+ 'sizes',
25
+ 'session',
26
+ 'transport',
27
+ 'extensions',
28
+ ];
29
+ async function readBoundedJson(response) {
30
+ return readBoundedResponseJson(response, MAX_DISCOVERY_BYTES, (kind) => new TargetDiscoveryError(kind === 'size' ? 'response exceeds the size limit' : 'response is not valid UTF-8 JSON'));
31
+ }
32
+ async function fetchDocument(http, url) {
33
+ const response = await http.fetch(url, {
34
+ method: 'GET',
35
+ headers: { Accept: 'application/json' },
36
+ redirect: 'error',
37
+ });
38
+ if (response.url && new URL(response.url).href !== url) {
39
+ await response.body?.cancel().catch(() => undefined);
40
+ throw new TargetDiscoveryError('request changed target route or authority');
41
+ }
42
+ if (!response.ok) {
43
+ await response.body?.cancel().catch(() => undefined);
44
+ throw new TargetDiscoveryError(`request failed with status ${response.status}`);
45
+ }
46
+ return record(await readBoundedJson(response), 'response');
47
+ }
48
+ export async function discoverTarget(targetUrl, http) {
49
+ const target = new URL(targetUrl);
50
+ const origin = target.origin;
51
+ const discovery = await fetchDocument(http, new URL(DISCOVERY_PATH, target).href);
52
+ exact(discovery.kind, 'openengine.hosted-target/v1', 'kind');
53
+ const adapter = parseAdapter(discovery);
54
+ const endpoint = parseEndpoint(discovery, origin);
55
+ const capsule = parseCapsule(discovery, origin);
56
+ const oauth = parseOAuth(discovery, origin);
57
+ exact(discovery.organization_binding, 'device_approval', 'organization_binding');
58
+ const capabilityFlags = exactStringSet(discovery.capability_flags, 'capability_flags', [
59
+ 'capsule_allocate',
60
+ 'capsule_read',
61
+ 'capsule_terminate',
62
+ 'capsule_access',
63
+ 'connections_onboarding',
64
+ ]);
65
+ const sizes = parseSizes(discovery);
66
+ const session = parseSession(discovery);
67
+ const transport = parseTransport(discovery);
68
+ const credentialInstall = parseExtensions(discovery, origin);
69
+ const metadata = await fetchDocument(http, oauth.metadataUrl);
70
+ validateOAuthMetadata(metadata, origin, [
71
+ oauth.deviceAuthorizationEndpoint,
72
+ oauth.tokenEndpoint,
73
+ oauth.revocationEndpoint,
74
+ ]);
75
+ const additional = Object.freeze(Object.fromEntries(Object.entries(discovery).filter(([key]) => !ROOT_FIELDS.includes(key))));
76
+ return Object.freeze({
77
+ origin,
78
+ adapter,
79
+ endpoint: endpoint.url,
80
+ endpointCapabilities: endpoint.capabilities,
81
+ pagination: endpoint.pagination,
82
+ sizes,
83
+ oauth,
84
+ session,
85
+ capsule,
86
+ transport,
87
+ capabilityFlags,
88
+ credentialInstall,
89
+ additional,
90
+ });
91
+ }
92
+ export async function discoverTargetSessionEndpoints(targetUrl, http) {
93
+ const descriptor = await discoverTarget(targetUrl, http);
94
+ return Object.freeze({
95
+ deviceAuthorizationEndpoint: descriptor.oauth.deviceAuthorizationEndpoint,
96
+ tokenEndpoint: descriptor.oauth.tokenEndpoint,
97
+ revocationEndpoint: descriptor.oauth.revocationEndpoint,
98
+ clientId: descriptor.oauth.clientId,
99
+ capsuleApiBaseUrl: descriptor.capsule.baseUrl.replace(/\/$/, ''),
100
+ deviceGrantType: descriptor.oauth.deviceGrantType,
101
+ audience: descriptor.oauth.audience,
102
+ sessionEndpoint: new URL(descriptor.session.routeTemplate.template, descriptor.origin).href,
103
+ descriptor,
104
+ });
105
+ }
@@ -1,6 +1,6 @@
1
- export { CredentialStoreUnavailableError, KeyringCredentialStore, FakeCredentialStore, targetServiceKey, TARGET_ACCOUNT, type TargetCredentialStore, } from './credential-store.ts';
2
- export { acquireTargetLock } from './credential-lock.ts';
3
- export { requestDeviceCode, pollForToken, DeviceFlowDeniedError, DeviceFlowExpiredError, UnboundSessionError, type DeviceCodeResponse, type TokenResponse, type HttpTransport, type Clock, } from './device-flow.ts';
4
- export { addTarget, removeTarget, getTarget, listTargets, updateTargetOrganization, validateTargetName, normalizeAndValidateUrl, TargetNameInvalidError, TargetNameExistsError, TargetNotFoundError, TargetUrlInvalidError, type TargetRecord, type SettingsPort, } from './target-registry.ts';
5
- export { targetLogin, refreshAccessToken, getAccessTokenProvider, revokeAndCleanup, LoginRequiredError, type BrowserOpener, type TargetSessionDeps, type TargetAccessTokenProvider, } from './target-session.ts';
6
- export { discoverTargetSessionEndpoints, TargetDiscoveryError, type TargetSessionEndpoints, } from './discovery.ts';
1
+ export { CredentialStoreUnavailableError, KeyringCredentialStore, FakeCredentialStore, targetServiceKey, TARGET_ACCOUNT, type TargetCredentialStore, } from './credential-store.js';
2
+ export { acquireTargetLock } from './credential-lock.js';
3
+ export { requestDeviceCode, pollForToken, parseTokenResponse, DeviceFlowDeniedError, DeviceFlowExpiredError, UnboundSessionError, type DeviceCodeResponse, type DeviceExchangeContext, type TokenResponse, type HttpTransport, type Clock, } from './device-flow.js';
4
+ export { addTarget, removeTarget, getTarget, listTargets, updateTargetOrganization, validateTargetName, normalizeAndValidateUrl, TargetNameInvalidError, TargetNameExistsError, TargetNotFoundError, TargetUrlInvalidError, type TargetRecord, type SettingsPort, } from './target-registry.js';
5
+ export { TargetSessionManager, LoginRequiredError, type BrowserOpener, type TargetSessionDeps, type TargetSessionManagerInit, } from './target-session.js';
6
+ export { discoverTarget, discoverTargetSessionEndpoints, expandRoute, TargetDiscoveryError, type CredentialInstallDescriptor, type RouteTemplate, type TargetDiscoveryDescriptor, type TargetSessionEndpoints, } from './discovery.js';