@distilled.cloud/stripe 1.0.0-rc.16 → 1.0.0-rc.17
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.
- package/lib/.lazy.json +1 -0
- package/lib/_bundle/lazy.js +4 -0
- package/lib/_bundle/sdk.js +2 -0
- package/lib/_bundle/sdk.js.map +1 -0
- package/lib/credentials.js +1 -34
- package/lib/errors.js +1 -130
- package/lib/index.js +1 -14
- package/lib/index.lazy.js +8 -0
- package/lib/pagination.js +1 -28
- package/lib/protocol.js +1 -471
- package/lib/retry.js +1 -33
- package/lib/services/index.js +0 -2
- package/lib/services/stripe.js +919 -2188
- package/lib/services/stripe.js.map +1 -0
- package/lib/services.lazy/index.js +3 -0
- package/lib/services.lazy/stripe.js +4 -0
- package/lib/traits.js +1 -16
- package/lib/webhooks.js +1 -160
- package/lib/webhooks.js.map +1 -1
- package/package.json +6 -8
- package/lib/credentials.js.map +0 -1
- package/lib/errors.js.map +0 -1
- package/lib/pagination.js.map +0 -1
- package/lib/protocol.js.map +0 -1
- package/lib/retry.js.map +0 -1
- package/lib/services/index.js.map +0 -1
- package/lib/traits.js.map +0 -1
- /package/lib/{index.js.map → index.lazy.js.map} +0 -0
package/lib/protocol.js
CHANGED
|
@@ -1,471 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { debugHttp } from "@distilled.cloud/core/debug";
|
|
3
|
-
import { ConfigError, HTTP_STATUS_MAP, InternalServerError, BadRequest, Conflict, Forbidden, Locked, NotFound, UnprocessableEntity, } from "@distilled.cloud/core/errors";
|
|
4
|
-
import { buildRequest, getAnn, getProps, hasPropAnn, makeRequest, mapKeys, mapsVerbatim, matchTypedError, nameOf, } from "@distilled.cloud/core/protocol-http";
|
|
5
|
-
import { hasSensitive, hasSensitiveMember, unwrapRedactedDeep, wrapSensitive, } from "@distilled.cloud/core/protocol-rest";
|
|
6
|
-
import { checkResponse, withholdActual } from "@distilled.cloud/core/response-validation";
|
|
7
|
-
import { parseRetryAfterForStatus } from "@distilled.cloud/core/retry-after";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
import * as Context from "effect/Context";
|
|
40
|
-
import * as Effect from "effect/Effect";
|
|
41
|
-
import * as HttpBody from "effect/http/HttpBody";
|
|
42
|
-
import * as HttpClient from "effect/http/HttpClient";
|
|
43
|
-
import * as HttpClientRequest from "effect/http/HttpClientRequest";
|
|
44
|
-
import * as Layer from "effect/Layer";
|
|
45
|
-
import * as Redacted from "effect/Redacted";
|
|
46
|
-
import { Credentials } from "./credentials.js";
|
|
47
|
-
import { ApiError, CardError, ExternalDependencyFailed, IdempotencyError, InvalidRequestError, PaymentError, STRIPE_HTTP_STATUS_MAP, StripeParseError, UnknownStripeError, } from "./errors.js";
|
|
48
|
-
import { bodySymbol, headerSymbol, httpSymbol, labelSymbol, querySymbol, } from "./traits.js";
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
export class RequestOptions extends /*@__PURE__*/ /*@__PURE__*/ Context.Service()("StripeRequestOptions") {
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
export const withRequestOptions = (options) => Effect.provide(Layer.succeed(RequestOptions, options));
|
|
67
|
-
const stripeRequestHeaders = (options) => {
|
|
68
|
-
const headers = {};
|
|
69
|
-
if (options?.idempotencyKey !== undefined) {
|
|
70
|
-
headers["Idempotency-Key"] = options.idempotencyKey;
|
|
71
|
-
}
|
|
72
|
-
if (options?.stripeAccount !== undefined) {
|
|
73
|
-
headers["Stripe-Account"] = options.stripeAccount;
|
|
74
|
-
}
|
|
75
|
-
if (options?.stripeContext !== undefined) {
|
|
76
|
-
headers["Stripe-Context"] = options.stripeContext;
|
|
77
|
-
}
|
|
78
|
-
if (options?.apiVersion !== undefined) {
|
|
79
|
-
headers["Stripe-Version"] = options.apiVersion;
|
|
80
|
-
}
|
|
81
|
-
return headers;
|
|
82
|
-
};
|
|
83
|
-
// Bridge: Protocol.decode is typed as Effect<unknown> (no error channel), but
|
|
84
|
-
// Stripe failures are real typed errors that an operation re-surfaces via its
|
|
85
|
-
// `errors: [...]` list / StripeOpError annotation. Fail with the instance and
|
|
86
|
-
// erase the error type here; the generated annotations reintroduce it.
|
|
87
|
-
const fail = (e) => Effect.fail(e);
|
|
88
|
-
// =============================================================================
|
|
89
|
-
// Stripe query / form encoding (ported from distilled v0)
|
|
90
|
-
// =============================================================================
|
|
91
|
-
const BODYLESS = /*@__PURE__*/ new Set(["GET", "HEAD"]);
|
|
92
|
-
const appendQueryValue = (query, key, value) => {
|
|
93
|
-
if (value === undefined || value === null)
|
|
94
|
-
return;
|
|
95
|
-
query.append(key, typeof value === "boolean" ? (value ? "true" : "false") : String(value));
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const appendStripeQuery = (query, key, value) => {
|
|
102
|
-
if (value === undefined || value === null)
|
|
103
|
-
return;
|
|
104
|
-
if (Array.isArray(value)) {
|
|
105
|
-
for (const item of value)
|
|
106
|
-
appendQueryValue(query, `${key}[]`, item);
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
if (typeof value === "object" && !(value instanceof Date)) {
|
|
110
|
-
for (const [nestedKey, nestedValue] of Object.entries(value)) {
|
|
111
|
-
appendStripeQuery(query, `${key}[${nestedKey}]`, nestedValue);
|
|
112
|
-
}
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
appendQueryValue(query, key, value);
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const flattenToFormPairs = (obj, prefix = "") => {
|
|
128
|
-
const pairs = [];
|
|
129
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
130
|
-
if (value === undefined || value === null)
|
|
131
|
-
continue;
|
|
132
|
-
const fullKey = prefix ? `${prefix}[${key}]` : key;
|
|
133
|
-
if (Array.isArray(value)) {
|
|
134
|
-
for (let i = 0; i < value.length; i++) {
|
|
135
|
-
const item = value[i];
|
|
136
|
-
if (item !== null &&
|
|
137
|
-
item !== undefined &&
|
|
138
|
-
typeof item === "object" &&
|
|
139
|
-
!Array.isArray(item)) {
|
|
140
|
-
pairs.push(...flattenToFormPairs(item, `${fullKey}[${i}]`));
|
|
141
|
-
}
|
|
142
|
-
else if (item !== undefined && item !== null) {
|
|
143
|
-
pairs.push([`${fullKey}[${i}]`, String(item)]);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
else if (typeof value === "object") {
|
|
148
|
-
pairs.push(...flattenToFormPairs(value, fullKey));
|
|
149
|
-
}
|
|
150
|
-
else if (typeof value === "boolean") {
|
|
151
|
-
pairs.push([fullKey, value ? "true" : "false"]);
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
pairs.push([fullKey, String(value)]);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
return pairs;
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
const buildFormUrlEncoded = (body) => {
|
|
161
|
-
const params = new URLSearchParams();
|
|
162
|
-
for (const [key, value] of flattenToFormPairs(body)) {
|
|
163
|
-
params.append(key, value);
|
|
164
|
-
}
|
|
165
|
-
return params.toString();
|
|
166
|
-
};
|
|
167
|
-
const requestPlans = /*@__PURE__*/ new WeakMap();
|
|
168
|
-
const requestPlanFor = (inputAst) => {
|
|
169
|
-
let plan = requestPlans.get(inputAst);
|
|
170
|
-
if (plan !== undefined)
|
|
171
|
-
return plan;
|
|
172
|
-
const http = getAnn(inputAst, httpSymbol);
|
|
173
|
-
if (!http) {
|
|
174
|
-
throw new Error("operation input is missing the Http() trait");
|
|
175
|
-
}
|
|
176
|
-
const members = getProps(inputAst).map((prop) => {
|
|
177
|
-
const key = String(prop.name);
|
|
178
|
-
if (hasPropAnn(prop, labelSymbol)) {
|
|
179
|
-
return {
|
|
180
|
-
key,
|
|
181
|
-
bind: "label",
|
|
182
|
-
name: nameOf(prop, labelSymbol),
|
|
183
|
-
type: prop.type,
|
|
184
|
-
verbatim: true,
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
if (hasPropAnn(prop, headerSymbol)) {
|
|
188
|
-
const name = nameOf(prop, headerSymbol).toLowerCase();
|
|
189
|
-
return { key, bind: "header", name, type: prop.type, verbatim: true };
|
|
190
|
-
}
|
|
191
|
-
if (hasPropAnn(prop, querySymbol)) {
|
|
192
|
-
return {
|
|
193
|
-
key,
|
|
194
|
-
bind: "query",
|
|
195
|
-
name: nameOf(prop, querySymbol),
|
|
196
|
-
type: prop.type,
|
|
197
|
-
verbatim: true,
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
return {
|
|
201
|
-
key,
|
|
202
|
-
bind: "body",
|
|
203
|
-
name: nameOf(prop, bodySymbol),
|
|
204
|
-
type: prop.type,
|
|
205
|
-
verbatim: mapsVerbatim(prop.type, "encode"),
|
|
206
|
-
};
|
|
207
|
-
});
|
|
208
|
-
plan = { http, members, known: new Set(members.map((m) => m.key)) };
|
|
209
|
-
requestPlans.set(inputAst, plan);
|
|
210
|
-
return plan;
|
|
211
|
-
};
|
|
212
|
-
const requestFor = (creds, options, input, inputAst) => {
|
|
213
|
-
const { http, members, known } = requestPlanFor(inputAst);
|
|
214
|
-
const baseHeaders = {
|
|
215
|
-
Authorization: `Bearer ${Redacted.value(creds.apiKey)}`,
|
|
216
|
-
...stripeRequestHeaders(options),
|
|
217
|
-
Accept: "application/json",
|
|
218
|
-
};
|
|
219
|
-
// Multipart (POST /v1/files): core's buildRequest speaks multipart
|
|
220
|
-
// form-data (file parts + JSON-encoded object parts) -- same behavior as
|
|
221
|
-
// v0's buildFormData.
|
|
222
|
-
if (http.contentType === "multipart") {
|
|
223
|
-
return buildRequest({
|
|
224
|
-
input: unwrapRedactedDeep(input),
|
|
225
|
-
inputAst,
|
|
226
|
-
baseUrl: creds.apiBaseUrl,
|
|
227
|
-
headers: baseHeaders,
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
const inputObj = (unwrapRedactedDeep(input) ?? {});
|
|
231
|
-
const headers = baseHeaders;
|
|
232
|
-
const body = {};
|
|
233
|
-
let bodyKeys = 0;
|
|
234
|
-
let query;
|
|
235
|
-
let uri = http.uri;
|
|
236
|
-
for (let i = 0; i < members.length; i++) {
|
|
237
|
-
const m = members[i];
|
|
238
|
-
const value = inputObj[m.key];
|
|
239
|
-
if (value === undefined)
|
|
240
|
-
continue;
|
|
241
|
-
switch (m.bind) {
|
|
242
|
-
case "label":
|
|
243
|
-
uri = uri.replace(`{${m.name}}`, encodeURIComponent(String(value)));
|
|
244
|
-
break;
|
|
245
|
-
case "header":
|
|
246
|
-
headers[m.name] = String(value);
|
|
247
|
-
break;
|
|
248
|
-
case "query":
|
|
249
|
-
// Stripe bracket expansion, not dotted params (`created[gte]=1`).
|
|
250
|
-
appendStripeQuery((query ??= new URLSearchParams()), m.name, value);
|
|
251
|
-
break;
|
|
252
|
-
default:
|
|
253
|
-
body[m.name] = m.verbatim ? value : mapKeys(m.type, value, "encode");
|
|
254
|
-
bodyKeys++;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
// Input keys the schema doesn't know pass through as body fields -- the
|
|
258
|
-
// generated schemas can lag the real API, and silently dropping them
|
|
259
|
-
// would break working callers.
|
|
260
|
-
for (const key in inputObj) {
|
|
261
|
-
if (known.has(key) || !Object.hasOwn(inputObj, key))
|
|
262
|
-
continue;
|
|
263
|
-
const value = inputObj[key];
|
|
264
|
-
if (value === undefined)
|
|
265
|
-
continue;
|
|
266
|
-
body[key] = value;
|
|
267
|
-
bodyKeys++;
|
|
268
|
-
}
|
|
269
|
-
// v0's normalizeStripeGetQuery: GET inputs carry no body -- flatten the
|
|
270
|
-
// body-bound members into the query string with bracket notation.
|
|
271
|
-
const bodyless = BODYLESS.has(http.method);
|
|
272
|
-
if (bodyless && bodyKeys > 0) {
|
|
273
|
-
for (const [key, value] of Object.entries(body)) {
|
|
274
|
-
appendStripeQuery((query ??= new URLSearchParams()), key, value);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
const qs = query === undefined ? "" : query.toString();
|
|
278
|
-
const url = qs ? `${creds.apiBaseUrl}${uri}?${qs}` : `${creds.apiBaseUrl}${uri}`;
|
|
279
|
-
if (debugHttp()) {
|
|
280
|
-
console.error(`[distilled] ${http.method} ${url}` +
|
|
281
|
-
(bodyKeys && !bodyless ? ` body=${JSON.stringify(body).slice(0, 400)}` : ""));
|
|
282
|
-
}
|
|
283
|
-
const request = makeRequest(http.method, url, headers);
|
|
284
|
-
if (bodyless || bodyKeys === 0)
|
|
285
|
-
return request;
|
|
286
|
-
return HttpClientRequest.setBody(request, http.contentType === "form-urlencoded"
|
|
287
|
-
? HttpBody.text(buildFormUrlEncoded(body), "application/x-www-form-urlencoded")
|
|
288
|
-
: // The /v2/* operations are plain JSON.
|
|
289
|
-
HttpBody.jsonUnsafe(body));
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const withCredentials = (context, f) => API.withValue(Context.get(context, Credentials), f);
|
|
299
|
-
const encode = ({ input, inputAst }) => Effect.withFiber((fiber) => {
|
|
300
|
-
const context = fiber.context;
|
|
301
|
-
return withCredentials(context, (creds) => Effect.succeed(requestFor(creds, Context.getOrUndefined(context, RequestOptions), input, inputAst)));
|
|
302
|
-
});
|
|
303
|
-
// =============================================================================
|
|
304
|
-
// Response decoding / error matching (ported from v0's matchError)
|
|
305
|
-
// =============================================================================
|
|
306
|
-
const str = (v) => (typeof v === "string" ? v : undefined);
|
|
307
|
-
// Structural views of the status maps for numeric lookup (the const objects'
|
|
308
|
-
// per-status class types don't unify without widening the constructor).
|
|
309
|
-
const stripeStatusMap = STRIPE_HTTP_STATUS_MAP;
|
|
310
|
-
const coreStatusMap = HTTP_STATUS_MAP;
|
|
311
|
-
|
|
312
|
-
const stripeErrorEnvelope = (errorBody) => {
|
|
313
|
-
const envelope = errorBody !== null && typeof errorBody === "object"
|
|
314
|
-
? errorBody.error
|
|
315
|
-
: undefined;
|
|
316
|
-
return envelope !== null && typeof envelope === "object"
|
|
317
|
-
? envelope
|
|
318
|
-
: undefined;
|
|
319
|
-
};
|
|
320
|
-
const stripeErrorMessage = (errorBody) => {
|
|
321
|
-
const message = stripeErrorEnvelope(errorBody)?.message;
|
|
322
|
-
return typeof message === "string" ? message : undefined;
|
|
323
|
-
};
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
const matchStripeError = (status, errorBody, headers) => {
|
|
334
|
-
const err = stripeErrorEnvelope(errorBody);
|
|
335
|
-
// v0 parity: an unparseable envelope (no `error.type` string) is an
|
|
336
|
-
// UnknownStripeError carrying the raw body.
|
|
337
|
-
if (!err || typeof err.type !== "string") {
|
|
338
|
-
return new UnknownStripeError({ body: errorBody });
|
|
339
|
-
}
|
|
340
|
-
const common = {
|
|
341
|
-
message: str(err.message),
|
|
342
|
-
code: str(err.code),
|
|
343
|
-
doc_url: str(err.doc_url),
|
|
344
|
-
request_log_url: str(err.request_log_url),
|
|
345
|
-
};
|
|
346
|
-
// Match by Stripe error type first for richer error info.
|
|
347
|
-
switch (err.type) {
|
|
348
|
-
case "card_error":
|
|
349
|
-
return new CardError({
|
|
350
|
-
...common,
|
|
351
|
-
decline_code: str(err.decline_code),
|
|
352
|
-
charge: str(err.charge),
|
|
353
|
-
param: str(err.param),
|
|
354
|
-
advice_code: str(err.advice_code),
|
|
355
|
-
network_advice_code: str(err.network_advice_code),
|
|
356
|
-
network_decline_code: str(err.network_decline_code),
|
|
357
|
-
payment_method_type: str(err.payment_method_type),
|
|
358
|
-
});
|
|
359
|
-
case "idempotency_error":
|
|
360
|
-
return new IdempotencyError(common);
|
|
361
|
-
case "invalid_request_error":
|
|
362
|
-
return new InvalidRequestError({ ...common, param: str(err.param) });
|
|
363
|
-
case "api_error":
|
|
364
|
-
return new ApiError({ ...common, param: str(err.param) });
|
|
365
|
-
}
|
|
366
|
-
// Fall back to Stripe-specific HTTP status codes (402, 424).
|
|
367
|
-
const StripeErrorClass = stripeStatusMap[status];
|
|
368
|
-
if (StripeErrorClass) {
|
|
369
|
-
return new StripeErrorClass({
|
|
370
|
-
message: common.message,
|
|
371
|
-
code: common.code,
|
|
372
|
-
...(str(err.decline_code) !== undefined ? { decline_code: str(err.decline_code) } : {}),
|
|
373
|
-
...(str(err.charge) !== undefined ? { charge: str(err.charge) } : {}),
|
|
374
|
-
...(str(err.param) !== undefined ? { param: str(err.param) } : {}),
|
|
375
|
-
...(common.doc_url !== undefined ? { doc_url: common.doc_url } : {}),
|
|
376
|
-
...(common.request_log_url !== undefined ? { request_log_url: common.request_log_url } : {}),
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
|
-
// Fall back to standard HTTP status errors (400, 401, 403, 404, ...).
|
|
380
|
-
const CoreErrorClass = coreStatusMap[status];
|
|
381
|
-
if (CoreErrorClass) {
|
|
382
|
-
return new CoreErrorClass({
|
|
383
|
-
message: common.message ?? "",
|
|
384
|
-
retryAfter: parseRetryAfterForStatus(status, headers),
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
// Unmapped 5xx (e.g. proxy statuses) -> retryable server error (v1
|
|
388
|
-
// convention; v0 fell through to UnknownStripeError here).
|
|
389
|
-
if (status >= 500) {
|
|
390
|
-
return new InternalServerError({
|
|
391
|
-
message: common.message ?? `HTTP ${status}`,
|
|
392
|
-
retryAfter: parseRetryAfterForStatus(status, headers),
|
|
393
|
-
});
|
|
394
|
-
}
|
|
395
|
-
return new UnknownStripeError({
|
|
396
|
-
type: str(err.type),
|
|
397
|
-
code: common.code,
|
|
398
|
-
message: common.message,
|
|
399
|
-
param: str(err.param),
|
|
400
|
-
body: errorBody,
|
|
401
|
-
});
|
|
402
|
-
};
|
|
403
|
-
const decodeResponse = (context, response, outputAst, errorClasses) => Effect.matchEffect(response.text, {
|
|
404
|
-
onFailure: Effect.die,
|
|
405
|
-
onSuccess: (read) => {
|
|
406
|
-
// Read as text and parse tolerantly -- error pages can be non-JSON.
|
|
407
|
-
const text = read ?? "";
|
|
408
|
-
if (debugHttp()) {
|
|
409
|
-
console.error(`[distilled] <- ${response.status} ${text.slice(0, 400)}`);
|
|
410
|
-
}
|
|
411
|
-
let json;
|
|
412
|
-
let nonJson = false;
|
|
413
|
-
if (text.trim().length > 0) {
|
|
414
|
-
try {
|
|
415
|
-
json = JSON.parse(text);
|
|
416
|
-
}
|
|
417
|
-
catch {
|
|
418
|
-
nonJson = true;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
const status = response.status;
|
|
422
|
-
const headers = response.headers;
|
|
423
|
-
if (status >= 400) {
|
|
424
|
-
const errorBody = nonJson ? text : json;
|
|
425
|
-
const message = stripeErrorMessage(errorBody) ??
|
|
426
|
-
(nonJson && text.trim() ? text.trim() : `HTTP ${status}`);
|
|
427
|
-
const typed = matchTypedError(errorClasses, status, [{ message }], {
|
|
428
|
-
body: nonJson ? text : json,
|
|
429
|
-
headers,
|
|
430
|
-
});
|
|
431
|
-
if (typed !== undefined)
|
|
432
|
-
return fail(typed);
|
|
433
|
-
return fail(matchStripeError(status, errorBody, headers));
|
|
434
|
-
}
|
|
435
|
-
// 2xx: the response body IS the payload (no envelope). Wire->TS key
|
|
436
|
-
// mapping is schema-driven; sensitive members come back Redacted.
|
|
437
|
-
// Strict mode checks the mapped body against the output schema first.
|
|
438
|
-
// For an output with sensitive members, a non-JSON body fails in every
|
|
439
|
-
// mode and parse errors withhold the body.
|
|
440
|
-
const withholdBody = hasSensitiveMember(outputAst);
|
|
441
|
-
if (nonJson && withholdBody) {
|
|
442
|
-
return fail(new StripeParseError({ body: "[REDACTED]", cause: "Invalid JSON response" }));
|
|
443
|
-
}
|
|
444
|
-
const body = nonJson ? text : (json ?? {});
|
|
445
|
-
const mapped = mapsVerbatim(outputAst, "decode") ? body : mapKeys(outputAst, body, "decode");
|
|
446
|
-
const cause = checkResponse(context, outputAst, mapped);
|
|
447
|
-
if (cause !== undefined) {
|
|
448
|
-
return fail(new StripeParseError({
|
|
449
|
-
body: withholdBody ? "[REDACTED]" : nonJson ? text : json,
|
|
450
|
-
cause: withholdBody ? withholdActual(cause) : cause,
|
|
451
|
-
}));
|
|
452
|
-
}
|
|
453
|
-
return Effect.succeed(hasSensitive(outputAst) ? wrapSensitive(outputAst, mapped) : mapped);
|
|
454
|
-
},
|
|
455
|
-
});
|
|
456
|
-
const call = (op, input) => Effect.withFiber((fiber) => {
|
|
457
|
-
const context = fiber.context;
|
|
458
|
-
return withCredentials(context, (creds) => {
|
|
459
|
-
const request = requestFor(creds, Context.getOrUndefined(context, RequestOptions), input, op.inputAst);
|
|
460
|
-
const client = Context.get(context, HttpClient.HttpClient);
|
|
461
|
-
return Effect.flatMap(client.execute(request), (response) => decodeResponse(context, response, op.outputAst, op.errors));
|
|
462
|
-
});
|
|
463
|
-
});
|
|
464
|
-
export const StripeProtocol = /*@__PURE__*/ Layer.succeed(API.Protocol,
|
|
465
|
-
/*@__PURE__*/ API.Protocol.of({
|
|
466
|
-
// Erase encode's Credentials requirement (see comment above).
|
|
467
|
-
encode: (args) => encode(args),
|
|
468
|
-
decode: ({ response, outputAst, errors }) => Effect.withFiber((fiber) => decodeResponse(fiber.context, response, outputAst, errors)),
|
|
469
|
-
call,
|
|
470
|
-
}));
|
|
471
|
-
//# sourceMappingURL=protocol.js.map
|
|
1
|
+
export { protocol$RequestOptions as RequestOptions, protocol$StripeProtocol as StripeProtocol, protocol$withRequestOptions as withRequestOptions } from "./_bundle/sdk.js";
|
package/lib/retry.js
CHANGED
|
@@ -1,33 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
import * as Context from "effect/Context";
|
|
18
|
-
import * as Effect from "effect/Effect";
|
|
19
|
-
import * as Layer from "effect/Layer";
|
|
20
|
-
export { makeDefault, jittered, capped, throttlingOptions, transientOptions, throttlingFactory, transientFactory, } from "@distilled.cloud/core/retry";
|
|
21
|
-
|
|
22
|
-
export class Retry extends /*@__PURE__*/ /*@__PURE__*/ Context.Service()("StripeRetry") {
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const policy = (optionsOrFactory) => Effect.provide(Layer.succeed(Retry, optionsOrFactory));
|
|
26
|
-
|
|
27
|
-
export const none = /*@__PURE__*/ Effect.provide(
|
|
28
|
-
/*@__PURE__*/ Layer.succeed(Retry, { while: () => false }));
|
|
29
|
-
|
|
30
|
-
export const throttling = /*@__PURE__*/ policy(throttlingFactory);
|
|
31
|
-
|
|
32
|
-
export const transient = /*@__PURE__*/ policy(transientFactory);
|
|
33
|
-
//# sourceMappingURL=retry.js.map
|
|
1
|
+
export { retry$Retry as Retry, retry$capped as capped, retry$jittered as jittered, retry$makeDefault as makeDefault, retry$none as none, retry$policy as policy, retry$throttling as throttling, retry$throttlingFactory as throttlingFactory, retry$throttlingOptions as throttlingOptions, retry$transient as transient, retry$transientFactory as transientFactory, retry$transientOptions as transientOptions } from "./_bundle/sdk.js";
|
package/lib/services/index.js
CHANGED