@cat-factory/integrations 0.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 (242) hide show
  1. package/LICENSE +21 -0
  2. package/dist/index.d.ts +68 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +84 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/modules/datadog/DatadogClient.d.ts +54 -0
  7. package/dist/modules/datadog/DatadogClient.d.ts.map +1 -0
  8. package/dist/modules/datadog/DatadogClient.js +132 -0
  9. package/dist/modules/datadog/DatadogClient.js.map +1 -0
  10. package/dist/modules/datadog/DatadogReleaseHealthProvider.d.ts +30 -0
  11. package/dist/modules/datadog/DatadogReleaseHealthProvider.d.ts.map +1 -0
  12. package/dist/modules/datadog/DatadogReleaseHealthProvider.js +101 -0
  13. package/dist/modules/datadog/DatadogReleaseHealthProvider.js.map +1 -0
  14. package/dist/modules/datadog/datadog.logic.d.ts +37 -0
  15. package/dist/modules/datadog/datadog.logic.d.ts.map +1 -0
  16. package/dist/modules/datadog/datadog.logic.js +90 -0
  17. package/dist/modules/datadog/datadog.logic.js.map +1 -0
  18. package/dist/modules/documents/ConfluenceProvider.d.ts +29 -0
  19. package/dist/modules/documents/ConfluenceProvider.d.ts.map +1 -0
  20. package/dist/modules/documents/ConfluenceProvider.js +180 -0
  21. package/dist/modules/documents/ConfluenceProvider.js.map +1 -0
  22. package/dist/modules/documents/DocumentConnectionService.d.ts +30 -0
  23. package/dist/modules/documents/DocumentConnectionService.d.ts.map +1 -0
  24. package/dist/modules/documents/DocumentConnectionService.js +69 -0
  25. package/dist/modules/documents/DocumentConnectionService.js.map +1 -0
  26. package/dist/modules/documents/DocumentImportService.d.ts +34 -0
  27. package/dist/modules/documents/DocumentImportService.d.ts.map +1 -0
  28. package/dist/modules/documents/DocumentImportService.js +83 -0
  29. package/dist/modules/documents/DocumentImportService.js.map +1 -0
  30. package/dist/modules/documents/DocumentLinkService.d.ts +31 -0
  31. package/dist/modules/documents/DocumentLinkService.d.ts.map +1 -0
  32. package/dist/modules/documents/DocumentLinkService.js +75 -0
  33. package/dist/modules/documents/DocumentLinkService.js.map +1 -0
  34. package/dist/modules/documents/DocumentPlannerService.d.ts +23 -0
  35. package/dist/modules/documents/DocumentPlannerService.d.ts.map +1 -0
  36. package/dist/modules/documents/DocumentPlannerService.js +96 -0
  37. package/dist/modules/documents/DocumentPlannerService.js.map +1 -0
  38. package/dist/modules/documents/GitHubDocsProvider.d.ts +42 -0
  39. package/dist/modules/documents/GitHubDocsProvider.d.ts.map +1 -0
  40. package/dist/modules/documents/GitHubDocsProvider.js +86 -0
  41. package/dist/modules/documents/GitHubDocsProvider.js.map +1 -0
  42. package/dist/modules/documents/NotionProvider.d.ts +32 -0
  43. package/dist/modules/documents/NotionProvider.d.ts.map +1 -0
  44. package/dist/modules/documents/NotionProvider.js +221 -0
  45. package/dist/modules/documents/NotionProvider.js.map +1 -0
  46. package/dist/modules/documents/confluence.logic.d.ts +37 -0
  47. package/dist/modules/documents/confluence.logic.d.ts.map +1 -0
  48. package/dist/modules/documents/confluence.logic.js +133 -0
  49. package/dist/modules/documents/confluence.logic.js.map +1 -0
  50. package/dist/modules/documents/documents.logic.d.ts +22 -0
  51. package/dist/modules/documents/documents.logic.d.ts.map +1 -0
  52. package/dist/modules/documents/documents.logic.js +138 -0
  53. package/dist/modules/documents/documents.logic.js.map +1 -0
  54. package/dist/modules/documents/github-docs.logic.d.ts +52 -0
  55. package/dist/modules/documents/github-docs.logic.d.ts.map +1 -0
  56. package/dist/modules/documents/github-docs.logic.js +94 -0
  57. package/dist/modules/documents/github-docs.logic.js.map +1 -0
  58. package/dist/modules/documents/notion.logic.d.ts +31 -0
  59. package/dist/modules/documents/notion.logic.d.ts.map +1 -0
  60. package/dist/modules/documents/notion.logic.js +142 -0
  61. package/dist/modules/documents/notion.logic.js.map +1 -0
  62. package/dist/modules/email/EmailConnectionService.d.ts +34 -0
  63. package/dist/modules/email/EmailConnectionService.d.ts.map +1 -0
  64. package/dist/modules/email/EmailConnectionService.js +82 -0
  65. package/dist/modules/email/EmailConnectionService.js.map +1 -0
  66. package/dist/modules/email/adapters.d.ts +39 -0
  67. package/dist/modules/email/adapters.d.ts.map +1 -0
  68. package/dist/modules/email/adapters.js +79 -0
  69. package/dist/modules/email/adapters.js.map +1 -0
  70. package/dist/modules/environments/EnvironmentConnectionService.d.ts +42 -0
  71. package/dist/modules/environments/EnvironmentConnectionService.d.ts.map +1 -0
  72. package/dist/modules/environments/EnvironmentConnectionService.js +120 -0
  73. package/dist/modules/environments/EnvironmentConnectionService.js.map +1 -0
  74. package/dist/modules/environments/EnvironmentProvisioningService.d.ts +56 -0
  75. package/dist/modules/environments/EnvironmentProvisioningService.d.ts.map +1 -0
  76. package/dist/modules/environments/EnvironmentProvisioningService.js +153 -0
  77. package/dist/modules/environments/EnvironmentProvisioningService.js.map +1 -0
  78. package/dist/modules/environments/EnvironmentTeardownService.d.ts +24 -0
  79. package/dist/modules/environments/EnvironmentTeardownService.d.ts.map +1 -0
  80. package/dist/modules/environments/EnvironmentTeardownService.js +54 -0
  81. package/dist/modules/environments/EnvironmentTeardownService.js.map +1 -0
  82. package/dist/modules/environments/HttpEnvironmentProvider.d.ts +30 -0
  83. package/dist/modules/environments/HttpEnvironmentProvider.d.ts.map +1 -0
  84. package/dist/modules/environments/HttpEnvironmentProvider.js +316 -0
  85. package/dist/modules/environments/HttpEnvironmentProvider.js.map +1 -0
  86. package/dist/modules/environments/environments.logic.d.ts +50 -0
  87. package/dist/modules/environments/environments.logic.d.ts.map +1 -0
  88. package/dist/modules/environments/environments.logic.js +257 -0
  89. package/dist/modules/environments/environments.logic.js.map +1 -0
  90. package/dist/modules/github/GitHubInstallationService.d.ts +66 -0
  91. package/dist/modules/github/GitHubInstallationService.d.ts.map +1 -0
  92. package/dist/modules/github/GitHubInstallationService.js +143 -0
  93. package/dist/modules/github/GitHubInstallationService.js.map +1 -0
  94. package/dist/modules/github/GitHubService.d.ts +29 -0
  95. package/dist/modules/github/GitHubService.d.ts.map +1 -0
  96. package/dist/modules/github/GitHubService.js +61 -0
  97. package/dist/modules/github/GitHubService.js.map +1 -0
  98. package/dist/modules/github/GitHubSyncService.d.ts +97 -0
  99. package/dist/modules/github/GitHubSyncService.d.ts.map +1 -0
  100. package/dist/modules/github/GitHubSyncService.js +241 -0
  101. package/dist/modules/github/GitHubSyncService.js.map +1 -0
  102. package/dist/modules/github/RepoProvisioningService.d.ts +26 -0
  103. package/dist/modules/github/RepoProvisioningService.d.ts.map +1 -0
  104. package/dist/modules/github/RepoProvisioningService.js +36 -0
  105. package/dist/modules/github/RepoProvisioningService.js.map +1 -0
  106. package/dist/modules/github/WebhookService.d.ts +28 -0
  107. package/dist/modules/github/WebhookService.d.ts.map +1 -0
  108. package/dist/modules/github/WebhookService.js +156 -0
  109. package/dist/modules/github/WebhookService.js.map +1 -0
  110. package/dist/modules/github/projection.logic.d.ts +95 -0
  111. package/dist/modules/github/projection.logic.d.ts.map +1 -0
  112. package/dist/modules/github/projection.logic.js +94 -0
  113. package/dist/modules/github/projection.logic.js.map +1 -0
  114. package/dist/modules/github/provisioning.logic.d.ts +11 -0
  115. package/dist/modules/github/provisioning.logic.d.ts.map +1 -0
  116. package/dist/modules/github/provisioning.logic.js +18 -0
  117. package/dist/modules/github/provisioning.logic.js.map +1 -0
  118. package/dist/modules/incident/incident.logic.d.ts +16 -0
  119. package/dist/modules/incident/incident.logic.d.ts.map +1 -0
  120. package/dist/modules/incident/incident.logic.js +23 -0
  121. package/dist/modules/incident/incident.logic.js.map +1 -0
  122. package/dist/modules/incidentio/IncidentIoEnrichmentProvider.d.ts +26 -0
  123. package/dist/modules/incidentio/IncidentIoEnrichmentProvider.d.ts.map +1 -0
  124. package/dist/modules/incidentio/IncidentIoEnrichmentProvider.js +84 -0
  125. package/dist/modules/incidentio/IncidentIoEnrichmentProvider.js.map +1 -0
  126. package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.d.ts +27 -0
  127. package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.d.ts.map +1 -0
  128. package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.js +65 -0
  129. package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.js.map +1 -0
  130. package/dist/modules/providers/ApiKeyService.d.ts +73 -0
  131. package/dist/modules/providers/ApiKeyService.d.ts.map +1 -0
  132. package/dist/modules/providers/ApiKeyService.js +122 -0
  133. package/dist/modules/providers/ApiKeyService.js.map +1 -0
  134. package/dist/modules/providers/LocalModelEndpointService.d.ts +52 -0
  135. package/dist/modules/providers/LocalModelEndpointService.d.ts.map +1 -0
  136. package/dist/modules/providers/LocalModelEndpointService.js +131 -0
  137. package/dist/modules/providers/LocalModelEndpointService.js.map +1 -0
  138. package/dist/modules/providers/PersonalSubscriptionService.d.ts +94 -0
  139. package/dist/modules/providers/PersonalSubscriptionService.d.ts.map +1 -0
  140. package/dist/modules/providers/PersonalSubscriptionService.js +218 -0
  141. package/dist/modules/providers/PersonalSubscriptionService.js.map +1 -0
  142. package/dist/modules/providers/ProviderSubscriptionService.d.ts +75 -0
  143. package/dist/modules/providers/ProviderSubscriptionService.d.ts.map +1 -0
  144. package/dist/modules/providers/ProviderSubscriptionService.js +130 -0
  145. package/dist/modules/providers/ProviderSubscriptionService.js.map +1 -0
  146. package/dist/modules/providers/localModelUrl.d.ts +7 -0
  147. package/dist/modules/providers/localModelUrl.d.ts.map +1 -0
  148. package/dist/modules/providers/localModelUrl.js +67 -0
  149. package/dist/modules/providers/localModelUrl.js.map +1 -0
  150. package/dist/modules/providers/providers.logic.d.ts +23 -0
  151. package/dist/modules/providers/providers.logic.d.ts.map +1 -0
  152. package/dist/modules/providers/providers.logic.js +46 -0
  153. package/dist/modules/providers/providers.logic.js.map +1 -0
  154. package/dist/modules/runners/HttpRunnerPoolProvider.d.ts +51 -0
  155. package/dist/modules/runners/HttpRunnerPoolProvider.d.ts.map +1 -0
  156. package/dist/modules/runners/HttpRunnerPoolProvider.js +304 -0
  157. package/dist/modules/runners/HttpRunnerPoolProvider.js.map +1 -0
  158. package/dist/modules/runners/RunnerPoolConnectionService.d.ts +47 -0
  159. package/dist/modules/runners/RunnerPoolConnectionService.d.ts.map +1 -0
  160. package/dist/modules/runners/RunnerPoolConnectionService.js +98 -0
  161. package/dist/modules/runners/RunnerPoolConnectionService.js.map +1 -0
  162. package/dist/modules/runners/RunnerPoolTransport.d.ts +11 -0
  163. package/dist/modules/runners/RunnerPoolTransport.d.ts.map +1 -0
  164. package/dist/modules/runners/RunnerPoolTransport.js +61 -0
  165. package/dist/modules/runners/RunnerPoolTransport.js.map +1 -0
  166. package/dist/modules/runners/runners.logic.d.ts +16 -0
  167. package/dist/modules/runners/runners.logic.d.ts.map +1 -0
  168. package/dist/modules/runners/runners.logic.js +52 -0
  169. package/dist/modules/runners/runners.logic.js.map +1 -0
  170. package/dist/modules/slack/SlackApiClient.d.ts +67 -0
  171. package/dist/modules/slack/SlackApiClient.d.ts.map +1 -0
  172. package/dist/modules/slack/SlackApiClient.js +132 -0
  173. package/dist/modules/slack/SlackApiClient.js.map +1 -0
  174. package/dist/modules/slack/SlackConnectionService.d.ts +41 -0
  175. package/dist/modules/slack/SlackConnectionService.d.ts.map +1 -0
  176. package/dist/modules/slack/SlackConnectionService.js +136 -0
  177. package/dist/modules/slack/SlackConnectionService.js.map +1 -0
  178. package/dist/modules/slack/SlackMemberMappingService.d.ts +17 -0
  179. package/dist/modules/slack/SlackMemberMappingService.d.ts.map +1 -0
  180. package/dist/modules/slack/SlackMemberMappingService.js +28 -0
  181. package/dist/modules/slack/SlackMemberMappingService.js.map +1 -0
  182. package/dist/modules/slack/SlackNotificationChannel.d.ts +45 -0
  183. package/dist/modules/slack/SlackNotificationChannel.d.ts.map +1 -0
  184. package/dist/modules/slack/SlackNotificationChannel.js +84 -0
  185. package/dist/modules/slack/SlackNotificationChannel.js.map +1 -0
  186. package/dist/modules/slack/SlackSettingsService.d.ts +16 -0
  187. package/dist/modules/slack/SlackSettingsService.d.ts.map +1 -0
  188. package/dist/modules/slack/SlackSettingsService.js +41 -0
  189. package/dist/modules/slack/SlackSettingsService.js.map +1 -0
  190. package/dist/modules/slack/slack.logic.d.ts +55 -0
  191. package/dist/modules/slack/slack.logic.d.ts.map +1 -0
  192. package/dist/modules/slack/slack.logic.js +149 -0
  193. package/dist/modules/slack/slack.logic.js.map +1 -0
  194. package/dist/modules/tasks/GitHubIssuesProvider.d.ts +50 -0
  195. package/dist/modules/tasks/GitHubIssuesProvider.d.ts.map +1 -0
  196. package/dist/modules/tasks/GitHubIssuesProvider.js +92 -0
  197. package/dist/modules/tasks/GitHubIssuesProvider.js.map +1 -0
  198. package/dist/modules/tasks/JiraProvider.d.ts +29 -0
  199. package/dist/modules/tasks/JiraProvider.d.ts.map +1 -0
  200. package/dist/modules/tasks/JiraProvider.js +114 -0
  201. package/dist/modules/tasks/JiraProvider.js.map +1 -0
  202. package/dist/modules/tasks/TaskConnectionService.d.ts +30 -0
  203. package/dist/modules/tasks/TaskConnectionService.d.ts.map +1 -0
  204. package/dist/modules/tasks/TaskConnectionService.js +69 -0
  205. package/dist/modules/tasks/TaskConnectionService.js.map +1 -0
  206. package/dist/modules/tasks/TaskImportService.d.ts +34 -0
  207. package/dist/modules/tasks/TaskImportService.d.ts.map +1 -0
  208. package/dist/modules/tasks/TaskImportService.js +96 -0
  209. package/dist/modules/tasks/TaskImportService.js.map +1 -0
  210. package/dist/modules/tasks/TaskLinkService.d.ts +30 -0
  211. package/dist/modules/tasks/TaskLinkService.d.ts.map +1 -0
  212. package/dist/modules/tasks/TaskLinkService.js +56 -0
  213. package/dist/modules/tasks/TaskLinkService.js.map +1 -0
  214. package/dist/modules/tasks/github-issues.logic.d.ts +35 -0
  215. package/dist/modules/tasks/github-issues.logic.d.ts.map +1 -0
  216. package/dist/modules/tasks/github-issues.logic.js +67 -0
  217. package/dist/modules/tasks/github-issues.logic.js.map +1 -0
  218. package/dist/modules/tasks/jira.logic.d.ts +28 -0
  219. package/dist/modules/tasks/jira.logic.d.ts.map +1 -0
  220. package/dist/modules/tasks/jira.logic.js +151 -0
  221. package/dist/modules/tasks/jira.logic.js.map +1 -0
  222. package/dist/modules/tasks/tasks.logic.d.ts +12 -0
  223. package/dist/modules/tasks/tasks.logic.d.ts.map +1 -0
  224. package/dist/modules/tasks/tasks.logic.js +17 -0
  225. package/dist/modules/tasks/tasks.logic.js.map +1 -0
  226. package/dist/modules/tracker/TicketTrackerService.d.ts +45 -0
  227. package/dist/modules/tracker/TicketTrackerService.d.ts.map +1 -0
  228. package/dist/modules/tracker/TicketTrackerService.js +52 -0
  229. package/dist/modules/tracker/TicketTrackerService.js.map +1 -0
  230. package/dist/modules/tracker/base64.d.ts +2 -0
  231. package/dist/modules/tracker/base64.d.ts.map +1 -0
  232. package/dist/modules/tracker/base64.js +18 -0
  233. package/dist/modules/tracker/base64.js.map +1 -0
  234. package/dist/modules/tracker/github.create.logic.d.ts +16 -0
  235. package/dist/modules/tracker/github.create.logic.d.ts.map +1 -0
  236. package/dist/modules/tracker/github.create.logic.js +25 -0
  237. package/dist/modules/tracker/github.create.logic.js.map +1 -0
  238. package/dist/modules/tracker/jira.create.logic.d.ts +31 -0
  239. package/dist/modules/tracker/jira.create.logic.d.ts.map +1 -0
  240. package/dist/modules/tracker/jira.create.logic.js +59 -0
  241. package/dist/modules/tracker/jira.create.logic.js.map +1 -0
  242. package/package.json +36 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnvironmentProvisioningService.d.ts","sourceRoot":"","sources":["../../../src/modules/environments/EnvironmentProvisioningService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,KAAK,EAAqB,6BAA6B,EAAE,MAAM,qBAAqB,CAAA;AAC3F,OAAO,KAAK,EACV,mBAAmB,EACnB,gBAAgB,EAEhB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAErF,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAA;AAQrF,MAAM,WAAW,0CAA0C;IACzD,iBAAiB,EAAE,4BAA4B,CAAA;IAC/C,mBAAmB,EAAE,mBAAmB,CAAA;IACxC,6BAA6B,EAAE,6BAA6B,CAAA;IAC5D,YAAY,EAAE,YAAY,CAAA;IAC1B,WAAW,EAAE,WAAW,CAAA;IACxB,KAAK,EAAE,KAAK,CAAA;IACZ,wFAAwF;IACxF,SAAS,CAAC,EAAE,eAAe,CAAA;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,qFAAqF;IACrF,OAAO,CAAC,EAAE,gBAAgB,CAAA;CAC3B;AAYD,2EAA2E;AAC3E,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,MAAM,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAA;IACnC,MAAM,EAAE,uBAAuB,GAAG,IAAI,CAAA;IACtC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED,qBAAa,8BAA8B;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,0CAA0C,EAAI;IAEjF,OAAO,KAAK,SAAS,GAEpB;IAED,mFAAmF;IAC7E,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA2D/D;IAED,+EAA+E;IACzE,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA6B/E;IAED,kDAAkD;IAC5C,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAGnE;IAED,uDAAuD;IACjD,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAGlF;IAED,wEAAwE;IAClE,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAI5F;IAED;;;OAGG;IACG,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAS/F;IAED,OAAO,CAAC,aAAa;YAUP,aAAa;YAKb,aAAa;YAKb,aAAa;CAK5B"}
@@ -0,0 +1,153 @@
1
+ import { assertFound, STRICT_URL_SAFETY_POLICY } from '@cat-factory/kernel';
2
+ import { assertSafeEnvironmentUrl, recordToHandle } from './environments.logic.js';
3
+ /** Flatten a typed provision context into `{{input.*}}` string vars (skips empties). */
4
+ function contextInputs(context) {
5
+ if (!context)
6
+ return {};
7
+ const out = {};
8
+ for (const [key, value] of Object.entries(context)) {
9
+ if (value !== undefined && value !== null && value !== '')
10
+ out[key] = String(value);
11
+ }
12
+ return out;
13
+ }
14
+ export class EnvironmentProvisioningService {
15
+ deps;
16
+ constructor(deps) {
17
+ this.deps = deps;
18
+ }
19
+ get urlPolicy() {
20
+ return this.deps.urlPolicy ?? STRICT_URL_SAFETY_POLICY;
21
+ }
22
+ /** Provision an environment, persisting an encrypted record keyed by block/run. */
23
+ async provision(args) {
24
+ const { workspaceId } = args;
25
+ const { manifest } = await this.deps.connectionService.requireConnection(workspaceId);
26
+ const resolveSecret = await this.deps.connectionService.resolveSecrets(workspaceId);
27
+ // Expose the block id as `{{input.blockId}}` even on a manual provision, so a
28
+ // manifest can template against it without the caller having to repeat it. The
29
+ // typed git/PR/repo context is flattened into the same namespace for the manifest
30
+ // path. Explicit inputs win over the derived block id + context.
31
+ const inputs = {};
32
+ if (args.blockId)
33
+ inputs.blockId = args.blockId;
34
+ Object.assign(inputs, contextInputs(args.context));
35
+ Object.assign(inputs, args.inputs);
36
+ const provisioned = await this.deps.environmentProvider.provision({
37
+ manifest,
38
+ inputs,
39
+ ...(args.context ? { provisionContext: args.context } : {}),
40
+ resolveSecret,
41
+ });
42
+ if (provisioned.url) {
43
+ assertSafeEnvironmentUrl(provisioned.url, 'environment URL', this.urlPolicy);
44
+ }
45
+ // A block holds at most one live environment: supersede any prior one.
46
+ if (args.blockId) {
47
+ const prior = await this.deps.environmentRegistryRepository.getByBlock(workspaceId, args.blockId);
48
+ if (prior) {
49
+ await this.deps.environmentRegistryRepository.softDelete(workspaceId, prior.id, this.deps.clock.now());
50
+ }
51
+ }
52
+ const now = this.deps.clock.now();
53
+ const record = {
54
+ id: this.deps.idGenerator.next('env'),
55
+ workspaceId,
56
+ blockId: args.blockId ?? null,
57
+ executionId: args.executionId ?? null,
58
+ providerId: manifest.providerId,
59
+ externalId: provisioned.externalId,
60
+ url: provisioned.url,
61
+ status: provisioned.status,
62
+ accessCipher: await this.encryptAccess(provisioned.access),
63
+ provisionFieldsCipher: await this.deps.secretCipher.encrypt(JSON.stringify(provisioned.fields)),
64
+ createdAt: now,
65
+ expiresAt: this.resolveExpiry(provisioned, manifest.defaultTtlMs, now),
66
+ lastError: provisioned.status === 'failed' ? 'Provisioning failed' : null,
67
+ deletedAt: null,
68
+ };
69
+ await this.deps.environmentRegistryRepository.insert(record);
70
+ return recordToHandle(record);
71
+ }
72
+ /** Re-poll the provider for an environment's status and persist any change. */
73
+ async refreshStatus(workspaceId, id) {
74
+ const record = assertFound(await this.deps.environmentRegistryRepository.get(workspaceId, id), 'Environment', id);
75
+ const { manifest } = await this.deps.connectionService.requireConnection(workspaceId);
76
+ const resolveSecret = await this.deps.connectionService.resolveSecrets(workspaceId);
77
+ const provisionFields = await this.decryptFields(record.provisionFieldsCipher);
78
+ const provisioned = await this.deps.environmentProvider.status({
79
+ manifest,
80
+ externalId: record.externalId,
81
+ provisionFields,
82
+ resolveSecret,
83
+ });
84
+ if (provisioned.url) {
85
+ assertSafeEnvironmentUrl(provisioned.url, 'environment URL', this.urlPolicy);
86
+ }
87
+ const patch = {
88
+ status: provisioned.status,
89
+ url: provisioned.url,
90
+ externalId: provisioned.externalId ?? record.externalId,
91
+ expiresAt: this.resolveExpiry(provisioned, manifest.defaultTtlMs, record.createdAt),
92
+ accessCipher: await this.encryptAccess(provisioned.access),
93
+ };
94
+ await this.deps.environmentRegistryRepository.update(workspaceId, id, patch);
95
+ return recordToHandle({ ...record, ...patch });
96
+ }
97
+ /** List a workspace's environments (no creds). */
98
+ async listHandles(workspaceId) {
99
+ const records = await this.deps.environmentRegistryRepository.listByWorkspace(workspaceId);
100
+ return records.map((r) => recordToHandle(r));
101
+ }
102
+ /** A single environment handle (no creds), or null. */
103
+ async getHandle(workspaceId, id) {
104
+ const record = await this.deps.environmentRegistryRepository.get(workspaceId, id);
105
+ return record ? recordToHandle(record) : null;
106
+ }
107
+ /** A single environment handle WITH decrypted access creds, or null. */
108
+ async getHandleWithAccess(workspaceId, id) {
109
+ const record = await this.deps.environmentRegistryRepository.get(workspaceId, id);
110
+ if (!record)
111
+ return null;
112
+ return recordToHandle(record, await this.decryptAccess(record.accessCipher));
113
+ }
114
+ /**
115
+ * The live environment provisioned for a block, with decrypted access — the
116
+ * discovery entry point the execution engine calls to enrich tester context.
117
+ */
118
+ async resolveForBlock(workspaceId, blockId) {
119
+ const record = await this.deps.environmentRegistryRepository.getByBlock(workspaceId, blockId);
120
+ if (!record)
121
+ return null;
122
+ return {
123
+ url: record.url,
124
+ status: record.status,
125
+ access: await this.decryptAccess(record.accessCipher),
126
+ expiresAt: record.expiresAt,
127
+ };
128
+ }
129
+ resolveExpiry(provisioned, defaultTtlMs, base) {
130
+ if (provisioned.expiresAt !== null)
131
+ return provisioned.expiresAt;
132
+ if (defaultTtlMs)
133
+ return base + defaultTtlMs;
134
+ return null;
135
+ }
136
+ async encryptAccess(access) {
137
+ if (!access)
138
+ return null;
139
+ return this.deps.secretCipher.encrypt(JSON.stringify(access));
140
+ }
141
+ async decryptAccess(cipher) {
142
+ if (!cipher)
143
+ return null;
144
+ return JSON.parse(await this.deps.secretCipher.decrypt(cipher));
145
+ }
146
+ async decryptFields(cipher) {
147
+ if (!cipher)
148
+ return {};
149
+ const parsed = JSON.parse(await this.deps.secretCipher.decrypt(cipher));
150
+ return parsed && typeof parsed === 'object' ? parsed : {};
151
+ }
152
+ }
153
+ //# sourceMappingURL=EnvironmentProvisioningService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnvironmentProvisioningService.js","sourceRoot":"","sources":["../../../src/modules/environments/EnvironmentProvisioningService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { Clock } from '@cat-factory/kernel';
2
+ import type { EnvironmentRegistryRepository } from '@cat-factory/kernel';
3
+ import type { EnvironmentProvider } from '@cat-factory/kernel';
4
+ import type { SecretCipher } from '@cat-factory/kernel';
5
+ import type { EnvironmentHandle } from '@cat-factory/kernel';
6
+ import type { EnvironmentConnectionService } from './EnvironmentConnectionService.js';
7
+ export interface EnvironmentTeardownServiceDependencies {
8
+ connectionService: EnvironmentConnectionService;
9
+ environmentProvider: EnvironmentProvider;
10
+ environmentRegistryRepository: EnvironmentRegistryRepository;
11
+ secretCipher: SecretCipher;
12
+ clock: Clock;
13
+ }
14
+ export declare class EnvironmentTeardownService {
15
+ private readonly deps;
16
+ constructor(deps: EnvironmentTeardownServiceDependencies);
17
+ /** Tear down a single environment and tombstone its record. */
18
+ teardown(workspaceId: string, id: string): Promise<EnvironmentHandle>;
19
+ /** Tear down every environment whose TTL has elapsed. Returns the count swept. */
20
+ sweepExpired(now: number): Promise<number>;
21
+ private teardownRecord;
22
+ private decryptFields;
23
+ }
24
+ //# sourceMappingURL=EnvironmentTeardownService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnvironmentTeardownService.d.ts","sourceRoot":"","sources":["../../../src/modules/environments/EnvironmentTeardownService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,EAAqB,6BAA6B,EAAE,MAAM,qBAAqB,CAAA;AAC3F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAE5D,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAA;AAQrF,MAAM,WAAW,sCAAsC;IACrD,iBAAiB,EAAE,4BAA4B,CAAA;IAC/C,mBAAmB,EAAE,mBAAmB,CAAA;IACxC,6BAA6B,EAAE,6BAA6B,CAAA;IAC5D,YAAY,EAAE,YAAY,CAAA;IAC1B,KAAK,EAAE,KAAK,CAAA;CACb;AAED,qBAAa,0BAA0B;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,sCAAsC,EAAI;IAE7E,+DAA+D;IACzD,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAQ1E;IAED,kFAAkF;IAC5E,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAa/C;YAEa,cAAc;YAsBd,aAAa;CAK5B"}
@@ -0,0 +1,54 @@
1
+ import { assertFound } from '@cat-factory/kernel';
2
+ import { recordToHandle } from './environments.logic.js';
3
+ export class EnvironmentTeardownService {
4
+ deps;
5
+ constructor(deps) {
6
+ this.deps = deps;
7
+ }
8
+ /** Tear down a single environment and tombstone its record. */
9
+ async teardown(workspaceId, id) {
10
+ const record = assertFound(await this.deps.environmentRegistryRepository.get(workspaceId, id), 'Environment', id);
11
+ await this.teardownRecord(record);
12
+ return recordToHandle({ ...record, status: 'torn_down' });
13
+ }
14
+ /** Tear down every environment whose TTL has elapsed. Returns the count swept. */
15
+ async sweepExpired(now) {
16
+ const expired = await this.deps.environmentRegistryRepository.listExpired(now);
17
+ let swept = 0;
18
+ for (const record of expired) {
19
+ try {
20
+ await this.teardownRecord(record);
21
+ swept++;
22
+ }
23
+ catch {
24
+ // Best-effort: a failing provider must not block the rest of the sweep.
25
+ // The record stays live and is retried on the next pass.
26
+ }
27
+ }
28
+ return swept;
29
+ }
30
+ async teardownRecord(record) {
31
+ const connection = await this.deps.connectionService
32
+ .requireConnection(record.workspaceId)
33
+ .catch(() => null);
34
+ // If the provider was unregistered we can't call its API; just tombstone.
35
+ if (connection) {
36
+ const resolveSecret = await this.deps.connectionService.resolveSecrets(record.workspaceId);
37
+ const provisionFields = await this.decryptFields(record.provisionFieldsCipher);
38
+ await this.deps.environmentProvider.teardown({
39
+ manifest: connection.manifest,
40
+ externalId: record.externalId,
41
+ provisionFields,
42
+ resolveSecret,
43
+ });
44
+ }
45
+ await this.deps.environmentRegistryRepository.softDelete(record.workspaceId, record.id, this.deps.clock.now());
46
+ }
47
+ async decryptFields(cipher) {
48
+ if (!cipher)
49
+ return {};
50
+ const parsed = JSON.parse(await this.deps.secretCipher.decrypt(cipher));
51
+ return parsed && typeof parsed === 'object' ? parsed : {};
52
+ }
53
+ }
54
+ //# sourceMappingURL=EnvironmentTeardownService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnvironmentTeardownService.js","sourceRoot":"","sources":["../../../src/modules/environments/EnvironmentTeardownService.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEjD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAexD,MAAM,OAAO,0BAA0B;IACR,IAAI;IAAjC,YAA6B,IAA4C;oBAA5C,IAAI;IAA2C,CAAC;IAE7E,+DAA+D;IAC/D,KAAK,CAAC,QAAQ,CAAC,WAAmB,EAAE,EAAU;QAC5C,MAAM,MAAM,GAAG,WAAW,CACxB,MAAM,IAAI,CAAC,IAAI,CAAC,6BAA6B,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,EAClE,aAAa,EACb,EAAE,CACH,CAAA;QACD,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;QACjC,OAAO,cAAc,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAA;IAC3D,CAAC;IAED,kFAAkF;IAClF,KAAK,CAAC,YAAY,CAAC,GAAW;QAC5B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,6BAA6B,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;QAC9E,IAAI,KAAK,GAAG,CAAC,CAAA;QACb,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;gBACjC,KAAK,EAAE,CAAA;YACT,CAAC;YAAC,MAAM,CAAC;gBACP,wEAAwE;gBACxE,yDAAyD;YAC3D,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,MAAyB;QACpD,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,iBAAiB;aACjD,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC;aACrC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;QACpB,0EAA0E;QAC1E,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;YAC1F,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAA;YAC9E,MAAM,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC;gBAC3C,QAAQ,EAAE,UAAU,CAAC,QAAQ;gBAC7B,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,eAAe;gBACf,aAAa;aACd,CAAC,CAAA;QACJ,CAAC;QACD,MAAM,IAAI,CAAC,IAAI,CAAC,6BAA6B,CAAC,UAAU,CACtD,MAAM,CAAC,WAAW,EAClB,MAAM,CAAC,EAAE,EACT,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CACtB,CAAA;IACH,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,MAAqB;QAC/C,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAA;QACtB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;QACvE,OAAO,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAE,MAAiC,CAAC,CAAC,CAAC,EAAE,CAAA;IACvF,CAAC;CACF"}
@@ -0,0 +1,30 @@
1
+ import { type EnvironmentProvider, type EnvironmentStatusRequest, type EnvironmentTeardownRequest, type EnvironmentStatus, type ProvisionEnvironmentRequest, type ProvisionedEnvironment, type UrlSafetyPolicy } from '@cat-factory/kernel';
2
+ /** Carries the HTTP status so the API can surface a meaningful (redacted) error. */
3
+ export declare class EnvironmentApiError extends Error {
4
+ readonly status: number;
5
+ constructor(status: number, message: string);
6
+ }
7
+ export interface HttpEnvironmentProviderOptions {
8
+ defaultTimeoutMs?: number;
9
+ /** URL/host safety policy; defaults to strict (https-only, no private hosts). */
10
+ urlPolicy?: UrlSafetyPolicy;
11
+ }
12
+ export declare class HttpEnvironmentProvider implements EnvironmentProvider {
13
+ private readonly defaultTimeoutMs;
14
+ private readonly urlPolicy;
15
+ /** Per-isolate OAuth token cache, keyed by token URL + client id. */
16
+ private readonly oauthCache;
17
+ constructor(options?: HttpEnvironmentProviderOptions);
18
+ provision(req: ProvisionEnvironmentRequest): Promise<ProvisionedEnvironment>;
19
+ status(req: EnvironmentStatusRequest): Promise<ProvisionedEnvironment>;
20
+ teardown(req: EnvironmentTeardownRequest): Promise<{
21
+ status: EnvironmentStatus;
22
+ }>;
23
+ private execute;
24
+ private buildUrl;
25
+ private authHeaders;
26
+ private oauthToken;
27
+ private mapResponse;
28
+ private mapAccess;
29
+ }
30
+ //# sourceMappingURL=HttpEnvironmentProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpEnvironmentProvider.d.ts","sourceRoot":"","sources":["../../../src/modules/environments/HttpEnvironmentProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,mBAAmB,EAExB,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,iBAAiB,EACtB,KAAK,2BAA2B,EAEhC,KAAK,sBAAsB,EAE3B,KAAK,eAAe,EAErB,MAAM,qBAAqB,CAAA;AAqB5B,oFAAoF;AACpF,qBAAa,mBAAoB,SAAQ,KAAK;IAE1C,QAAQ,CAAC,MAAM,EAAE,MAAM;IADzB,YACW,MAAM,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,EAIhB;CACF;AAqFD,MAAM,WAAW,8BAA8B;IAC7C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,iFAAiF;IACjF,SAAS,CAAC,EAAE,eAAe,CAAA;CAC5B;AAED,qBAAa,uBAAwB,YAAW,mBAAmB;IACjE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAQ;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,qEAAqE;IACrE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0D;IAErF,YAAY,OAAO,GAAE,8BAAmC,EAGvD;IAEK,SAAS,CAAC,GAAG,EAAE,2BAA2B,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAajF;IAEK,MAAM,CAAC,GAAG,EAAE,wBAAwB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAwB3E;IAEK,QAAQ,CAAC,GAAG,EAAE,0BAA0B,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,iBAAiB,CAAA;KAAE,CAAC,CAatF;YAIa,OAAO;IAmDrB,OAAO,CAAC,QAAQ;YAoBF,WAAW;YAgCX,UAAU;IAsDxB,OAAO,CAAC,WAAW;IA4BnB,OAAO,CAAC,SAAS;CAiBlB"}
@@ -0,0 +1,316 @@
1
+ import { STRICT_URL_SAFETY_POLICY, } from '@cat-factory/kernel';
2
+ import * as environmentsLogic from './environments.logic.js';
3
+ // The single generic adapter that interprets ANY environment manifest. There are
4
+ // no per-provider presets: an org's self-rolled management API is described as
5
+ // HTTP request templates with `{{var}}` interpolation, an auth scheme, and a
6
+ // dot-path mapping from its (arbitrary) response onto the canonical handle.
7
+ //
8
+ // Security: every URL is SSRF-guarded before it is fetched; the per-tenant
9
+ // secrets are resolved in-memory via the injected resolver and only ever placed
10
+ // in request headers — never logged or echoed in errors (error bodies are
11
+ // length-capped and carry no request headers).
12
+ const DEFAULT_TIMEOUT_MS = 15_000;
13
+ const MAX_RESPONSE_CHARS = 200_000;
14
+ /** Hard cap on the bytes read off any response body (mirrors MAX_RESPONSE_CHARS). */
15
+ const MAX_RESPONSE_BYTES = MAX_RESPONSE_CHARS;
16
+ /** Bound the redirect chain so a permitted first hop can't walk us anywhere. */
17
+ const MAX_REDIRECTS = 5;
18
+ const USER_AGENT = 'cat-factory';
19
+ /** Carries the HTTP status so the API can surface a meaningful (redacted) error. */
20
+ export class EnvironmentApiError extends Error {
21
+ status;
22
+ constructor(status, message) {
23
+ super(message);
24
+ this.status = status;
25
+ this.name = 'EnvironmentApiError';
26
+ }
27
+ }
28
+ /**
29
+ * `fetch` with redirects followed by hand so the SSRF guard runs against EVERY
30
+ * hop, not just the first URL. With the default `redirect: 'follow'` a permitted
31
+ * host can 302 to an internal target (e.g. 169.254.169.254) — or downgrade
32
+ * https→http — and the runtime would follow it unchecked. We force
33
+ * `redirect: 'manual'`, re-resolve the `Location` against the current URL, and
34
+ * re-run the same `assertSafe` guard (which also enforces https-only) before
35
+ * following. A redirect target that fails the guard throws exactly as an invalid
36
+ * initial URL would.
37
+ */
38
+ async function safeFetch(url, init, assertSafe) {
39
+ let current = url;
40
+ for (let hop = 0;; hop++) {
41
+ assertSafe(current);
42
+ const res = await fetch(current, { ...init, redirect: 'manual' });
43
+ if (res.status >= 300 && res.status < 400) {
44
+ const location = res.headers.get('location');
45
+ if (!location)
46
+ return res;
47
+ if (hop >= MAX_REDIRECTS) {
48
+ throw new EnvironmentApiError(502, 'Environment provider returned too many redirects');
49
+ }
50
+ // Resolve relative redirects against the current URL, then re-validate.
51
+ current = new URL(location, current).toString();
52
+ continue;
53
+ }
54
+ return res;
55
+ }
56
+ }
57
+ /**
58
+ * Read a response body with a running byte cap so a hostile/huge response can't
59
+ * OOM the isolate. Checks the declared Content-Length first, then enforces the
60
+ * cap while streaming. When `throwOnOverflow` is false (error snippets) the body
61
+ * is truncated instead of throwing.
62
+ */
63
+ async function readCappedText(res, maxBytes, throwOnOverflow = true) {
64
+ const declared = res.headers.get('content-length');
65
+ if (declared && Number(declared) > maxBytes) {
66
+ if (throwOnOverflow) {
67
+ throw new EnvironmentApiError(502, 'Environment provider response too large');
68
+ }
69
+ }
70
+ const body = res.body;
71
+ if (!body)
72
+ return '';
73
+ const reader = body.getReader();
74
+ const chunks = [];
75
+ let total = 0;
76
+ try {
77
+ for (;;) {
78
+ const { done, value } = await reader.read();
79
+ if (done)
80
+ break;
81
+ if (!value)
82
+ continue;
83
+ total += value.byteLength;
84
+ if (total > maxBytes) {
85
+ await reader.cancel();
86
+ if (throwOnOverflow) {
87
+ throw new EnvironmentApiError(502, 'Environment provider response too large');
88
+ }
89
+ chunks.push(value);
90
+ break;
91
+ }
92
+ chunks.push(value);
93
+ }
94
+ }
95
+ finally {
96
+ reader.releaseLock();
97
+ }
98
+ const merged = new Uint8Array(chunks.reduce((n, c) => n + c.byteLength, 0));
99
+ let offset = 0;
100
+ for (const c of chunks) {
101
+ merged.set(c, offset);
102
+ offset += c.byteLength;
103
+ }
104
+ return new TextDecoder().decode(merged).slice(0, maxBytes);
105
+ }
106
+ export class HttpEnvironmentProvider {
107
+ defaultTimeoutMs;
108
+ urlPolicy;
109
+ /** Per-isolate OAuth token cache, keyed by token URL + client id. */
110
+ oauthCache = new Map();
111
+ constructor(options = {}) {
112
+ this.defaultTimeoutMs = options.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS;
113
+ this.urlPolicy = options.urlPolicy ?? STRICT_URL_SAFETY_POLICY;
114
+ }
115
+ async provision(req) {
116
+ const json = await this.execute(req.manifest, req.manifest.provision, {
117
+ input: req.inputs,
118
+ provision: {},
119
+ }, req.resolveSecret);
120
+ // A successful provision call defaults to 'ready' unless the manifest maps a
121
+ // status string (e.g. an async provisioner returning 'pending').
122
+ return this.mapResponse(req.manifest, json, 'ready');
123
+ }
124
+ async status(req) {
125
+ if (!req.manifest.status) {
126
+ // No status endpoint declared: treat the environment as ready and echo what
127
+ // we captured at provision time.
128
+ return {
129
+ externalId: req.externalId,
130
+ url: req.provisionFields.url ?? null,
131
+ status: 'ready',
132
+ expiresAt: null,
133
+ access: null,
134
+ fields: req.provisionFields,
135
+ };
136
+ }
137
+ const json = await this.execute(req.manifest, req.manifest.status, {
138
+ input: {},
139
+ provision: req.provisionFields,
140
+ }, req.resolveSecret);
141
+ const mapped = this.mapResponse(req.manifest, json, 'ready');
142
+ return { ...mapped, externalId: mapped.externalId ?? req.externalId };
143
+ }
144
+ async teardown(req) {
145
+ if (req.manifest.teardown) {
146
+ await this.execute(req.manifest, req.manifest.teardown, {
147
+ input: {},
148
+ provision: req.provisionFields,
149
+ }, req.resolveSecret);
150
+ }
151
+ return { status: 'torn_down' };
152
+ }
153
+ // --- internals ----------------------------------------------------------
154
+ async execute(manifest, template, scope, resolveSecret) {
155
+ const url = this.buildUrl(manifest.baseUrl, template, scope);
156
+ const headers = {
157
+ accept: 'application/json',
158
+ 'user-agent': USER_AGENT,
159
+ ...(await this.authHeaders(manifest.auth, resolveSecret)),
160
+ };
161
+ for (const h of template.headers ?? []) {
162
+ headers[h.name] = environmentsLogic.interpolateTemplate(h.value, scope);
163
+ }
164
+ let body;
165
+ if (template.bodyTemplate !== undefined && template.method !== 'GET') {
166
+ body = environmentsLogic.interpolateTemplate(template.bodyTemplate, scope);
167
+ if (!headers['content-type'])
168
+ headers['content-type'] = 'application/json';
169
+ }
170
+ const res = await safeFetch(url, {
171
+ method: template.method,
172
+ headers,
173
+ body,
174
+ signal: AbortSignal.timeout(template.timeoutMs ?? this.defaultTimeoutMs),
175
+ }, (u) => environmentsLogic.assertSafeEnvironmentUrl(u, 'request URL', this.urlPolicy));
176
+ if (!res.ok) {
177
+ const errText = await readCappedText(res, MAX_RESPONSE_BYTES, false).catch(() => '');
178
+ throw new EnvironmentApiError(res.status, `Environment provider ${template.method} → ${res.status}: ${errText.slice(0, 300)}`);
179
+ }
180
+ const text = await readCappedText(res, MAX_RESPONSE_BYTES);
181
+ if (!text)
182
+ return {};
183
+ try {
184
+ return JSON.parse(text);
185
+ }
186
+ catch {
187
+ // Non-JSON responses leave the mapping to resolve to nulls.
188
+ return {};
189
+ }
190
+ }
191
+ buildUrl(baseUrl, template, scope) {
192
+ const base = baseUrl.replace(/\/+$/, '');
193
+ const path = environmentsLogic.interpolateTemplate(template.pathTemplate, scope);
194
+ let url = path ? `${base}${path.startsWith('/') ? '' : '/'}${path}` : base;
195
+ const query = (template.query ?? [])
196
+ .map((q) => `${encodeURIComponent(q.key)}=${encodeURIComponent(environmentsLogic.interpolateTemplate(q.value, scope))}`)
197
+ .join('&');
198
+ if (query)
199
+ url += `${url.includes('?') ? '&' : '?'}${query}`;
200
+ return url;
201
+ }
202
+ async authHeaders(auth, resolveSecret) {
203
+ const secret = (key) => {
204
+ const value = resolveSecret(key);
205
+ if (value === undefined)
206
+ throw new EnvironmentApiError(500, `Missing secret '${key}'`);
207
+ return value;
208
+ };
209
+ switch (auth.type) {
210
+ case 'none':
211
+ return {};
212
+ case 'api_key':
213
+ return { [auth.headerName]: `${auth.valuePrefix ?? ''}${secret(auth.secretRef.key)}` };
214
+ case 'bearer':
215
+ return { authorization: `Bearer ${secret(auth.secretRef.key)}` };
216
+ case 'basic':
217
+ return {
218
+ authorization: `Basic ${btoa(`${secret(auth.usernameSecretRef.key)}:${secret(auth.passwordSecretRef.key)}`)}`,
219
+ };
220
+ case 'oauth2_client_credentials':
221
+ return { authorization: `Bearer ${await this.oauthToken(auth, secret)}` };
222
+ case 'custom_headers': {
223
+ const headers = {};
224
+ for (const h of auth.headers)
225
+ headers[h.name] = secret(h.secretRef.key);
226
+ return headers;
227
+ }
228
+ }
229
+ }
230
+ async oauthToken(auth, secret) {
231
+ const clientId = secret(auth.clientIdSecretRef.key);
232
+ const cacheKey = `${auth.tokenUrl}::${clientId}`;
233
+ const cached = this.oauthCache.get(cacheKey);
234
+ if (cached && cached.expiresAt > Date.now() + 5_000)
235
+ return cached.token;
236
+ const form = new URLSearchParams({
237
+ grant_type: 'client_credentials',
238
+ client_id: clientId,
239
+ client_secret: secret(auth.clientSecretSecretRef.key),
240
+ });
241
+ if (auth.scope)
242
+ form.set('scope', auth.scope);
243
+ if (auth.audience)
244
+ form.set('audience', auth.audience);
245
+ const res = await safeFetch(auth.tokenUrl, {
246
+ method: 'POST',
247
+ headers: {
248
+ 'content-type': 'application/x-www-form-urlencoded',
249
+ accept: 'application/json',
250
+ 'user-agent': USER_AGENT,
251
+ },
252
+ body: form.toString(),
253
+ signal: AbortSignal.timeout(this.defaultTimeoutMs),
254
+ }, (u) => environmentsLogic.assertSafeEnvironmentUrl(u, 'OAuth token URL', this.urlPolicy));
255
+ if (!res.ok) {
256
+ const text = await readCappedText(res, MAX_RESPONSE_BYTES, false).catch(() => '');
257
+ throw new EnvironmentApiError(res.status, `OAuth token request → ${res.status}: ${text.slice(0, 200)}`);
258
+ }
259
+ const tokenText = await readCappedText(res, MAX_RESPONSE_BYTES);
260
+ const json = (() => {
261
+ try {
262
+ return JSON.parse(tokenText);
263
+ }
264
+ catch {
265
+ return null;
266
+ }
267
+ })();
268
+ if (!json?.access_token) {
269
+ throw new EnvironmentApiError(502, 'OAuth token response missing access_token');
270
+ }
271
+ const ttlMs = (typeof json.expires_in === 'number' ? json.expires_in : 300) * 1000;
272
+ this.oauthCache.set(cacheKey, { token: json.access_token, expiresAt: Date.now() + ttlMs });
273
+ return json.access_token;
274
+ }
275
+ mapResponse(manifest, json, fallbackStatus) {
276
+ const r = manifest.response;
277
+ const externalId = environmentsLogic.extractString(json, r.externalIdPath) ?? null;
278
+ const url = environmentsLogic.extractString(json, r.urlPath) ?? null;
279
+ const rawStatus = environmentsLogic.extractString(json, r.statusPath);
280
+ const status = environmentsLogic.mapStatus(rawStatus, r.statusMap, fallbackStatus);
281
+ const expiresAt = r.expiresAtPath
282
+ ? environmentsLogic.coerceExpiresAt(environmentsLogic.extractByPath(json, r.expiresAtPath))
283
+ : null;
284
+ const fields = {};
285
+ if (externalId)
286
+ fields.externalId = externalId;
287
+ if (url)
288
+ fields.url = url;
289
+ return {
290
+ externalId,
291
+ url,
292
+ status,
293
+ expiresAt,
294
+ access: this.mapAccess(r.access, json),
295
+ fields,
296
+ };
297
+ }
298
+ mapAccess(mapping, json) {
299
+ if (!mapping)
300
+ return null;
301
+ const access = { scheme: mapping.scheme };
302
+ if (mapping.scheme === 'bearer') {
303
+ access.token = environmentsLogic.extractString(json, mapping.tokenPath);
304
+ }
305
+ else if (mapping.scheme === 'basic') {
306
+ access.username = environmentsLogic.extractString(json, mapping.usernamePath);
307
+ access.password = environmentsLogic.extractString(json, mapping.passwordPath);
308
+ }
309
+ else if (mapping.scheme === 'custom_header') {
310
+ access.headerName = mapping.headerName;
311
+ access.headerValue = environmentsLogic.extractString(json, mapping.headerValuePath);
312
+ }
313
+ return access;
314
+ }
315
+ }
316
+ //# sourceMappingURL=HttpEnvironmentProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpEnvironmentProvider.js","sourceRoot":"","sources":["../../../src/modules/environments/HttpEnvironmentProvider.ts"],"names":[],"mappings":"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"}