@distilled.cloud/stackit 0.0.0-stage → 1.0.0-rc.14

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 (298) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +33 -2
  3. package/lib/credentials.d.ts +29 -0
  4. package/lib/credentials.d.ts.map +1 -0
  5. package/lib/credentials.js +49 -0
  6. package/lib/credentials.js.map +1 -0
  7. package/lib/errors.d.ts +36 -0
  8. package/lib/errors.d.ts.map +1 -0
  9. package/lib/errors.js +26 -0
  10. package/lib/errors.js.map +1 -0
  11. package/lib/index.d.ts +30 -0
  12. package/lib/index.d.ts.map +1 -0
  13. package/lib/index.js +30 -0
  14. package/lib/index.js.map +1 -0
  15. package/lib/pagination.d.ts +9 -0
  16. package/lib/pagination.d.ts.map +1 -0
  17. package/lib/pagination.js +45 -0
  18. package/lib/pagination.js.map +1 -0
  19. package/lib/protocol.d.ts +32 -0
  20. package/lib/protocol.d.ts.map +1 -0
  21. package/lib/protocol.js +147 -0
  22. package/lib/protocol.js.map +1 -0
  23. package/lib/protocol.test.d.ts +2 -0
  24. package/lib/protocol.test.d.ts.map +1 -0
  25. package/lib/protocol.test.js +181 -0
  26. package/lib/protocol.test.js.map +1 -0
  27. package/lib/retry.d.ts +31 -0
  28. package/lib/retry.d.ts.map +1 -0
  29. package/lib/retry.js +31 -0
  30. package/lib/retry.js.map +1 -0
  31. package/lib/services/alb.d.ts +603 -0
  32. package/lib/services/alb.d.ts.map +1 -0
  33. package/lib/services/alb.js +513 -0
  34. package/lib/services/alb.js.map +1 -0
  35. package/lib/services/alb_waf.d.ts +526 -0
  36. package/lib/services/alb_waf.d.ts.map +1 -0
  37. package/lib/services/alb_waf.js +521 -0
  38. package/lib/services/alb_waf.js.map +1 -0
  39. package/lib/services/authorization.d.ts +251 -0
  40. package/lib/services/authorization.d.ts.map +1 -0
  41. package/lib/services/authorization.js +323 -0
  42. package/lib/services/authorization.js.map +1 -0
  43. package/lib/services/automation.d.ts +321 -0
  44. package/lib/services/automation.d.ts.map +1 -0
  45. package/lib/services/automation.js +363 -0
  46. package/lib/services/automation.js.map +1 -0
  47. package/lib/services/cdn.d.ts +1239 -0
  48. package/lib/services/cdn.d.ts.map +1 -0
  49. package/lib/services/cdn.js +906 -0
  50. package/lib/services/cdn.js.map +1 -0
  51. package/lib/services/certificates.d.ts +201 -0
  52. package/lib/services/certificates.d.ts.map +1 -0
  53. package/lib/services/certificates.js +179 -0
  54. package/lib/services/certificates.js.map +1 -0
  55. package/lib/services/cost.d.ts +222 -0
  56. package/lib/services/cost.d.ts.map +1 -0
  57. package/lib/services/cost.js +177 -0
  58. package/lib/services/cost.js.map +1 -0
  59. package/lib/services/dns.d.ts +842 -0
  60. package/lib/services/dns.d.ts.map +1 -0
  61. package/lib/services/dns.js +726 -0
  62. package/lib/services/dns.js.map +1 -0
  63. package/lib/services/dremio.d.ts +358 -0
  64. package/lib/services/dremio.d.ts.map +1 -0
  65. package/lib/services/dremio.js +317 -0
  66. package/lib/services/dremio.js.map +1 -0
  67. package/lib/services/edge.d.ts +312 -0
  68. package/lib/services/edge.d.ts.map +1 -0
  69. package/lib/services/edge.js +357 -0
  70. package/lib/services/edge.js.map +1 -0
  71. package/lib/services/functions.d.ts +409 -0
  72. package/lib/services/functions.d.ts.map +1 -0
  73. package/lib/services/functions.js +399 -0
  74. package/lib/services/functions.js.map +1 -0
  75. package/lib/services/git.d.ts +497 -0
  76. package/lib/services/git.d.ts.map +1 -0
  77. package/lib/services/git.js +520 -0
  78. package/lib/services/git.js.map +1 -0
  79. package/lib/services/iaas.d.ts +2986 -0
  80. package/lib/services/iaas.d.ts.map +1 -0
  81. package/lib/services/iaas.js +3543 -0
  82. package/lib/services/iaas.js.map +1 -0
  83. package/lib/services/index.d.ts +51 -0
  84. package/lib/services/index.d.ts.map +1 -0
  85. package/lib/services/index.js +52 -0
  86. package/lib/services/index.js.map +1 -0
  87. package/lib/services/intake.d.ts +555 -0
  88. package/lib/services/intake.d.ts.map +1 -0
  89. package/lib/services/intake.js +475 -0
  90. package/lib/services/intake.js.map +1 -0
  91. package/lib/services/kms.d.ts +654 -0
  92. package/lib/services/kms.d.ts.map +1 -0
  93. package/lib/services/kms.js +663 -0
  94. package/lib/services/kms.js.map +1 -0
  95. package/lib/services/lb_ip_lists.d.ts +160 -0
  96. package/lib/services/lb_ip_lists.d.ts.map +1 -0
  97. package/lib/services/lb_ip_lists.js +154 -0
  98. package/lib/services/lb_ip_lists.js.map +1 -0
  99. package/lib/services/load_balancer.d.ts +563 -0
  100. package/lib/services/load_balancer.d.ts.map +1 -0
  101. package/lib/services/load_balancer.js +497 -0
  102. package/lib/services/load_balancer.js.map +1 -0
  103. package/lib/services/logme.d.ts +516 -0
  104. package/lib/services/logme.d.ts.map +1 -0
  105. package/lib/services/logme.js +574 -0
  106. package/lib/services/logme.js.map +1 -0
  107. package/lib/services/logs.d.ts +436 -0
  108. package/lib/services/logs.d.ts.map +1 -0
  109. package/lib/services/logs.js +475 -0
  110. package/lib/services/logs.js.map +1 -0
  111. package/lib/services/mariadb.d.ts +479 -0
  112. package/lib/services/mariadb.d.ts.map +1 -0
  113. package/lib/services/mariadb.js +551 -0
  114. package/lib/services/mariadb.js.map +1 -0
  115. package/lib/services/model_experiments.d.ts +306 -0
  116. package/lib/services/model_experiments.d.ts.map +1 -0
  117. package/lib/services/model_experiments.js +336 -0
  118. package/lib/services/model_experiments.js.map +1 -0
  119. package/lib/services/model_serving.d.ts +289 -0
  120. package/lib/services/model_serving.d.ts.map +1 -0
  121. package/lib/services/model_serving.js +287 -0
  122. package/lib/services/model_serving.js.map +1 -0
  123. package/lib/services/mongodb_flex.d.ts +826 -0
  124. package/lib/services/mongodb_flex.d.ts.map +1 -0
  125. package/lib/services/mongodb_flex.js +803 -0
  126. package/lib/services/mongodb_flex.js.map +1 -0
  127. package/lib/services/object_storage.d.ts +470 -0
  128. package/lib/services/object_storage.d.ts.map +1 -0
  129. package/lib/services/object_storage.js +540 -0
  130. package/lib/services/object_storage.js.map +1 -0
  131. package/lib/services/observability.d.ts +2750 -0
  132. package/lib/services/observability.d.ts.map +1 -0
  133. package/lib/services/observability.js +3158 -0
  134. package/lib/services/observability.js.map +1 -0
  135. package/lib/services/opensearch.d.ts +505 -0
  136. package/lib/services/opensearch.d.ts.map +1 -0
  137. package/lib/services/opensearch.js +563 -0
  138. package/lib/services/opensearch.js.map +1 -0
  139. package/lib/services/pim.d.ts +997 -0
  140. package/lib/services/pim.d.ts.map +1 -0
  141. package/lib/services/pim.js +736 -0
  142. package/lib/services/pim.js.map +1 -0
  143. package/lib/services/postgres_flex.d.ts +854 -0
  144. package/lib/services/postgres_flex.d.ts.map +1 -0
  145. package/lib/services/postgres_flex.js +853 -0
  146. package/lib/services/postgres_flex.js.map +1 -0
  147. package/lib/services/pubsub.d.ts +489 -0
  148. package/lib/services/pubsub.d.ts.map +1 -0
  149. package/lib/services/pubsub.js +519 -0
  150. package/lib/services/pubsub.js.map +1 -0
  151. package/lib/services/rabbitmq.d.ts +523 -0
  152. package/lib/services/rabbitmq.d.ts.map +1 -0
  153. package/lib/services/rabbitmq.js +574 -0
  154. package/lib/services/rabbitmq.js.map +1 -0
  155. package/lib/services/registry.d.ts +212 -0
  156. package/lib/services/registry.d.ts.map +1 -0
  157. package/lib/services/registry.js +198 -0
  158. package/lib/services/registry.js.map +1 -0
  159. package/lib/services/resource_manager.d.ts +458 -0
  160. package/lib/services/resource_manager.d.ts.map +1 -0
  161. package/lib/services/resource_manager.js +473 -0
  162. package/lib/services/resource_manager.js.map +1 -0
  163. package/lib/services/run_command.d.ts +175 -0
  164. package/lib/services/run_command.d.ts.map +1 -0
  165. package/lib/services/run_command.js +185 -0
  166. package/lib/services/run_command.js.map +1 -0
  167. package/lib/services/sca.d.ts +553 -0
  168. package/lib/services/sca.d.ts.map +1 -0
  169. package/lib/services/sca.js +445 -0
  170. package/lib/services/sca.js.map +1 -0
  171. package/lib/services/scf.d.ts +498 -0
  172. package/lib/services/scf.d.ts.map +1 -0
  173. package/lib/services/scf.js +670 -0
  174. package/lib/services/scf.js.map +1 -0
  175. package/lib/services/secrets_manager.d.ts +505 -0
  176. package/lib/services/secrets_manager.d.ts.map +1 -0
  177. package/lib/services/secrets_manager.js +613 -0
  178. package/lib/services/secrets_manager.js.map +1 -0
  179. package/lib/services/server_backup.d.ts +380 -0
  180. package/lib/services/server_backup.d.ts.map +1 -0
  181. package/lib/services/server_backup.js +454 -0
  182. package/lib/services/server_backup.js.map +1 -0
  183. package/lib/services/server_update.d.ts +292 -0
  184. package/lib/services/server_update.d.ts.map +1 -0
  185. package/lib/services/server_update.js +352 -0
  186. package/lib/services/server_update.js.map +1 -0
  187. package/lib/services/service_account.d.ts +465 -0
  188. package/lib/services/service_account.d.ts.map +1 -0
  189. package/lib/services/service_account.js +506 -0
  190. package/lib/services/service_account.js.map +1 -0
  191. package/lib/services/service_enablement.d.ts +149 -0
  192. package/lib/services/service_enablement.d.ts.map +1 -0
  193. package/lib/services/service_enablement.js +157 -0
  194. package/lib/services/service_enablement.js.map +1 -0
  195. package/lib/services/sfs.d.ts +721 -0
  196. package/lib/services/sfs.d.ts.map +1 -0
  197. package/lib/services/sfs.js +790 -0
  198. package/lib/services/sfs.js.map +1 -0
  199. package/lib/services/ske.d.ts +562 -0
  200. package/lib/services/ske.d.ts.map +1 -0
  201. package/lib/services/ske.js +558 -0
  202. package/lib/services/ske.js.map +1 -0
  203. package/lib/services/sqlserverflex.d.ts +956 -0
  204. package/lib/services/sqlserverflex.d.ts.map +1 -0
  205. package/lib/services/sqlserverflex.js +936 -0
  206. package/lib/services/sqlserverflex.js.map +1 -0
  207. package/lib/services/stackit_marketplace.d.ts +288 -0
  208. package/lib/services/stackit_marketplace.d.ts.map +1 -0
  209. package/lib/services/stackit_marketplace.js +379 -0
  210. package/lib/services/stackit_marketplace.js.map +1 -0
  211. package/lib/services/telemetry_link.d.ts +443 -0
  212. package/lib/services/telemetry_link.d.ts.map +1 -0
  213. package/lib/services/telemetry_link.js +532 -0
  214. package/lib/services/telemetry_link.js.map +1 -0
  215. package/lib/services/telemetry_router.d.ts +493 -0
  216. package/lib/services/telemetry_router.d.ts.map +1 -0
  217. package/lib/services/telemetry_router.js +484 -0
  218. package/lib/services/telemetry_router.js.map +1 -0
  219. package/lib/services/ufw.d.ts +295 -0
  220. package/lib/services/ufw.d.ts.map +1 -0
  221. package/lib/services/ufw.js +279 -0
  222. package/lib/services/ufw.js.map +1 -0
  223. package/lib/services/valkey.d.ts +505 -0
  224. package/lib/services/valkey.d.ts.map +1 -0
  225. package/lib/services/valkey.js +567 -0
  226. package/lib/services/valkey.js.map +1 -0
  227. package/lib/services/vpn.d.ts +1024 -0
  228. package/lib/services/vpn.d.ts.map +1 -0
  229. package/lib/services/vpn.js +931 -0
  230. package/lib/services/vpn.js.map +1 -0
  231. package/lib/services/workflows.d.ts +600 -0
  232. package/lib/services/workflows.d.ts.map +1 -0
  233. package/lib/services/workflows.js +508 -0
  234. package/lib/services/workflows.js.map +1 -0
  235. package/lib/traits.d.ts +24 -0
  236. package/lib/traits.d.ts.map +1 -0
  237. package/lib/traits.js +15 -0
  238. package/lib/traits.js.map +1 -0
  239. package/package.json +85 -3
  240. package/src/credentials.ts +84 -0
  241. package/src/errors.ts +50 -0
  242. package/src/index.ts +34 -0
  243. package/src/pagination.ts +57 -0
  244. package/src/protocol.test.ts +304 -0
  245. package/src/protocol.ts +225 -0
  246. package/src/retry.ts +47 -0
  247. package/src/services/alb.ts +1326 -0
  248. package/src/services/alb_waf.ts +1288 -0
  249. package/src/services/authorization.ts +704 -0
  250. package/src/services/automation.ts +796 -0
  251. package/src/services/cdn.ts +2576 -0
  252. package/src/services/certificates.ts +418 -0
  253. package/src/services/cost.ts +449 -0
  254. package/src/services/dns.ts +1936 -0
  255. package/src/services/dremio.ts +753 -0
  256. package/src/services/edge.ts +780 -0
  257. package/src/services/functions.ts +957 -0
  258. package/src/services/git.ts +1194 -0
  259. package/src/services/iaas.ts +7878 -0
  260. package/src/services/index.ts +51 -0
  261. package/src/services/intake.ts +1166 -0
  262. package/src/services/kms.ts +1537 -0
  263. package/src/services/lb_ip_lists.ts +342 -0
  264. package/src/services/load_balancer.ts +1266 -0
  265. package/src/services/logme.ts +1284 -0
  266. package/src/services/logs.ts +1049 -0
  267. package/src/services/mariadb.ts +1212 -0
  268. package/src/services/model_experiments.ts +741 -0
  269. package/src/services/model_serving.ts +654 -0
  270. package/src/services/mongodb_flex.ts +1932 -0
  271. package/src/services/object_storage.ts +1195 -0
  272. package/src/services/observability.ts +7364 -0
  273. package/src/services/opensearch.ts +1265 -0
  274. package/src/services/pim.ts +1985 -0
  275. package/src/services/postgres_flex.ts +2080 -0
  276. package/src/services/pubsub.ts +1193 -0
  277. package/src/services/rabbitmq.ts +1310 -0
  278. package/src/services/registry.ts +446 -0
  279. package/src/services/resource_manager.ts +1072 -0
  280. package/src/services/run_command.ts +413 -0
  281. package/src/services/sca.ts +1187 -0
  282. package/src/services/scf.ts +1396 -0
  283. package/src/services/secrets_manager.ts +1317 -0
  284. package/src/services/server_backup.ts +983 -0
  285. package/src/services/server_update.ts +738 -0
  286. package/src/services/service_account.ts +1121 -0
  287. package/src/services/service_enablement.ts +330 -0
  288. package/src/services/sfs.ts +1831 -0
  289. package/src/services/ske.ts +1386 -0
  290. package/src/services/sqlserverflex.ts +2307 -0
  291. package/src/services/stackit_marketplace.ts +787 -0
  292. package/src/services/telemetry_link.ts +1166 -0
  293. package/src/services/telemetry_router.ts +1110 -0
  294. package/src/services/ufw.ts +654 -0
  295. package/src/services/valkey.ts +1266 -0
  296. package/src/services/vpn.ts +2365 -0
  297. package/src/services/workflows.ts +1249 -0
  298. package/src/traits.ts +60 -0
@@ -0,0 +1,225 @@
1
+ import * as API from "@distilled.cloud/core/api";
2
+ import {
3
+ HTTP_STATUS_MAP,
4
+ InternalServerError,
5
+ type ConfigError,
6
+ } from "@distilled.cloud/core/errors";
7
+ import {
8
+ buildRequest,
9
+ getAnn,
10
+ mapKeys,
11
+ matchTypedError,
12
+ } from "@distilled.cloud/core/protocol-http";
13
+ import {
14
+ unwrapRedactedDeep,
15
+ wrapSensitive,
16
+ type RestErrorEnvelope,
17
+ } from "@distilled.cloud/core/protocol-rest";
18
+ import { validateResponse } from "@distilled.cloud/core/response-validation";
19
+ import { parseRetryAfterForStatus } from "@distilled.cloud/core/retry-after";
20
+ import { httpSymbol } from "@distilled.cloud/core/trait";
21
+ /**
22
+ * StackitProtocol — the shared bearer-REST protocol instantiated for STACKIT.
23
+ *
24
+ * STACKIT speaks plain JSON with no success envelope. FAILURES are
25
+ * `{ "message": "...", "error": "..." }` (the `ErrorMessage` schema most
26
+ * product specs share). Each product has its own host, baked into the
27
+ * generated operation's `T.Http({ baseUrl })` from the OpenAPI `servers`
28
+ * entry; this protocol reads that URL and rewrites it for the configured
29
+ * region (`eu01` by default).
30
+ *
31
+ * Auth is `Authorization: Bearer <token>`. The API version is a PATH
32
+ * segment (`/v1`, `/v2`, …), so the generated operations carry versioned
33
+ * routes against a version-less host.
34
+ */
35
+ import * as Effect from "effect/Effect";
36
+ import type * as HttpClient from "effect/http/HttpClient";
37
+ import type * as HttpClientError from "effect/http/HttpClientError";
38
+ import type * as HttpClientRequest from "effect/http/HttpClientRequest";
39
+ import type * as HttpClientResponse from "effect/http/HttpClientResponse";
40
+ import * as Layer from "effect/Layer";
41
+ import * as Redacted from "effect/Redacted";
42
+ import type * as AST from "effect/SchemaAST";
43
+ import { Credentials, type Config } from "./credentials.ts";
44
+ import { StackitParseError, UnknownStackitError } from "./errors.ts";
45
+ import type { DefaultErrors } from "./errors.ts";
46
+ import type { StackitHttpTrait } from "./traits.ts";
47
+
48
+ /**
49
+ * Error channel shared by every generated STACKIT operation. Generated
50
+ * service files annotate operations with `API.OperationMethod<I, O,
51
+ * StackitOpError, StackitOpContext>` explicitly so the compiler never infers
52
+ * these back out of the schema generics.
53
+ */
54
+ export type StackitOpError =
55
+ | DefaultErrors
56
+ | UnknownStackitError
57
+ | StackitParseError
58
+ | ConfigError
59
+ | HttpClientError.HttpClientError;
60
+
61
+ /** Context (requirements) shared by every generated STACKIT operation. */
62
+ export type StackitOpContext = Credentials | HttpClient.HttpClient;
63
+
64
+ /**
65
+ * Rewrite a spec `servers` URL for the configured region.
66
+ *
67
+ * • `{region}` still in the template (IaaS v1:
68
+ * `https://iaas.api.{region}stackit.cloud`, default `eu01.`) is
69
+ * substituted. A glued `{region}stackit` means the spec's default
70
+ * includes the trailing dot.
71
+ * • `https://<svc>.api.stackit.cloud` becomes
72
+ * `https://<svc>.api.<region>.stackit.cloud`.
73
+ * • `region === "global"` leaves the URL alone (after dropping any
74
+ * leftover `{region}`).
75
+ */
76
+ export const applyRegion = (specUrl: string, region: string): string => {
77
+ if (specUrl.includes("{region}")) {
78
+ if (region === "global") return specUrl.replaceAll("{region}", "");
79
+ const glued = specUrl.includes("{region}stackit");
80
+ const value = glued && !region.endsWith(".") ? `${region}.` : region;
81
+ return specUrl.replaceAll("{region}", value);
82
+ }
83
+ if (region === "global") return specUrl;
84
+ return specUrl.replace(
85
+ /^(https:\/\/[a-z0-9-]+)\.api\.stackit\.cloud(?=[:/?]|$)/i,
86
+ `$1.api.${region}.stackit.cloud`,
87
+ );
88
+ };
89
+
90
+ const errorEnvelope = (body: unknown): RestErrorEnvelope | undefined => {
91
+ if (body === null || typeof body !== "object") return undefined;
92
+ const b = body as Record<string, unknown>;
93
+ const message = typeof b.message === "string" ? b.message : undefined;
94
+ const code =
95
+ typeof b.error === "string"
96
+ ? b.error
97
+ : typeof b.code === "string" || typeof b.code === "number"
98
+ ? b.code
99
+ : undefined;
100
+ if (message === undefined && code === undefined) return undefined;
101
+ return { code, message };
102
+ };
103
+
104
+ const fail = (e: unknown): Effect.Effect<never> => Effect.fail(e) as Effect.Effect<never>;
105
+
106
+ const baseUrlFor = (creds: Config, inputAst: AST.AST): string => {
107
+ if (creds.apiBaseUrl !== undefined && creds.apiBaseUrl !== "") {
108
+ return creds.apiBaseUrl;
109
+ }
110
+ const http = getAnn(inputAst, httpSymbol) as StackitHttpTrait | undefined;
111
+ const specUrl = http?.baseUrl;
112
+ if (typeof specUrl !== "string" || specUrl === "") {
113
+ throw new Error("STACKIT operation is missing T.Http({ baseUrl }) — regenerate from convert");
114
+ }
115
+ return applyRegion(specUrl, creds.region);
116
+ };
117
+
118
+ export const StackitProtocol: Layer.Layer<API.Protocol> = Layer.succeed(
119
+ API.Protocol,
120
+ API.Protocol.of({
121
+ encode: ({ input, inputAst }: { readonly input: unknown; readonly inputAst: AST.AST }) =>
122
+ Effect.gen(function* () {
123
+ const resolve = yield* Credentials;
124
+ const creds = yield* resolve;
125
+ return buildRequest({
126
+ input: unwrapRedactedDeep(input),
127
+ inputAst,
128
+ baseUrl: baseUrlFor(creds, inputAst),
129
+ headers: {
130
+ Authorization: `Bearer ${Redacted.value(creds.token)}`,
131
+ },
132
+ });
133
+ }) as Effect.Effect<HttpClientRequest.HttpClientRequest>,
134
+ decode: ({
135
+ response,
136
+ outputAst,
137
+ errors: errorClasses,
138
+ }: {
139
+ readonly response: HttpClientResponse.HttpClientResponse;
140
+ readonly outputAst: AST.AST;
141
+ readonly errors: ReadonlyArray<unknown>;
142
+ }) =>
143
+ Effect.gen(function* () {
144
+ const text = (yield* response.text.pipe(Effect.orDie)) ?? "";
145
+ if (process.env.DISTILLED_DEBUG_HTTP) {
146
+ console.error(`[distilled] <- ${response.status} ${text.slice(0, 400)}`);
147
+ }
148
+ let json: unknown;
149
+ let nonJson = false;
150
+ if (text.trim().length > 0) {
151
+ try {
152
+ json = JSON.parse(text);
153
+ } catch {
154
+ nonJson = true;
155
+ }
156
+ }
157
+ const status = response.status;
158
+ const headers = response.headers as Record<string, string | undefined>;
159
+
160
+ if (status >= 400) {
161
+ const env = (nonJson ? undefined : errorEnvelope(json)) ?? {};
162
+ const message = env.message ?? (nonJson && text.trim() ? text.trim() : `HTTP ${status}`);
163
+
164
+ const typed = matchTypedError(
165
+ errorClasses,
166
+ status,
167
+ [
168
+ {
169
+ code: typeof env.code === "number" ? env.code : undefined,
170
+ message,
171
+ },
172
+ ],
173
+ { body: nonJson ? text : json, headers },
174
+ );
175
+ if (typed !== undefined) return yield* fail(typed);
176
+
177
+ const StatusErrorClass = (
178
+ HTTP_STATUS_MAP as Record<
179
+ number,
180
+ (new (args: { message: string; retryAfter?: unknown }) => unknown) | undefined
181
+ >
182
+ )[status];
183
+ if (StatusErrorClass) {
184
+ return yield* fail(
185
+ new StatusErrorClass({
186
+ message,
187
+ retryAfter: parseRetryAfterForStatus(status, headers),
188
+ }),
189
+ );
190
+ }
191
+
192
+ if (status >= 500) {
193
+ return yield* fail(
194
+ new InternalServerError({
195
+ message,
196
+ retryAfter: parseRetryAfterForStatus(status, headers),
197
+ }),
198
+ );
199
+ }
200
+
201
+ return yield* fail(
202
+ new UnknownStackitError({
203
+ code:
204
+ typeof env.code === "string"
205
+ ? env.code
206
+ : env.code !== undefined
207
+ ? String(env.code)
208
+ : undefined,
209
+ message,
210
+ body: nonJson ? text : json,
211
+ }),
212
+ );
213
+ }
214
+
215
+ // Strict mode checks the mapped body against the output schema.
216
+ const body: unknown = nonJson ? text : (json ?? {});
217
+ const mapped = yield* validateResponse(
218
+ outputAst,
219
+ mapKeys(outputAst, body, "decode"),
220
+ (cause) => new StackitParseError({ body: nonJson ? text : json, cause }),
221
+ ).pipe(Effect.catch(fail));
222
+ return wrapSensitive(outputAst, mapped);
223
+ }),
224
+ }),
225
+ );
package/src/retry.ts ADDED
@@ -0,0 +1,47 @@
1
+ import { type Policy, throttlingFactory, transientFactory } from "@distilled.cloud/core/retry";
2
+ /**
3
+ * STACKIT retry configuration.
4
+ *
5
+ * Defines the per-SDK `Retry` Context.Service tag that generated operations
6
+ * wire into `API.make`. Callers can install a blanket retry policy at the
7
+ * layer level and have every STACKIT API call below it pick it up:
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import * as Stackit from "@distilled.cloud/stackit";
12
+ *
13
+ * myEffect.pipe(Stackit.Retry.transient);
14
+ * ```
15
+ */
16
+ import * as Context from "effect/Context";
17
+ import * as Effect from "effect/Effect";
18
+ import * as Layer from "effect/Layer";
19
+
20
+ export {
21
+ type Options,
22
+ type Factory,
23
+ type Policy,
24
+ makeDefault,
25
+ jittered,
26
+ capped,
27
+ throttlingOptions,
28
+ transientOptions,
29
+ throttlingFactory,
30
+ transientFactory,
31
+ } from "@distilled.cloud/core/retry";
32
+
33
+ /** Context tag for configuring retry behavior of STACKIT API calls. */
34
+ export class Retry extends Context.Service<Retry, Policy>()("StackitRetry") {}
35
+
36
+ /** Provides a custom retry policy to every STACKIT API call below it. */
37
+ export const policy = (optionsOrFactory: Policy) =>
38
+ Effect.provide(Layer.succeed(Retry, optionsOrFactory));
39
+
40
+ /** Disables all automatic retries. */
41
+ export const none = Effect.provide(Layer.succeed(Retry, { while: () => false }));
42
+
43
+ /** Apply the throttling retry policy (retries throttling errors indefinitely). */
44
+ export const throttling = policy(throttlingFactory);
45
+
46
+ /** Apply the transient retry policy (retries all transient errors indefinitely). */
47
+ export const transient = policy(transientFactory);