@sinnu-dev/sdk 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -85,7 +85,7 @@ for await (const tx of sinnu.transactions.listAll({ status: "approved" })) {
85
85
 
86
86
  ## Estornar uma venda
87
87
 
88
- O estorno é sempre do valor total da transação.
88
+ O estorno é sempre do valor total da transação. A chave precisa do escopo `transactions:refund`; sem ele, a API responde `403`.
89
89
 
90
90
  ```ts
91
91
  const tx = await sinnu.transactions.refund("ID_DA_TRANSACAO", {
package/dist/index.cjs CHANGED
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
 
30
20
  // src/index.ts
@@ -53,8 +43,467 @@ __export(index_exports, {
53
43
  });
54
44
  module.exports = __toCommonJS(index_exports);
55
45
 
56
- // src/client.ts
57
- var import_openapi_fetch = __toESM(require("openapi-fetch"), 1);
46
+ // node_modules/openapi-fetch/dist/index.js
47
+ var PATH_PARAM_RE = /\{[^{}]+\}/g;
48
+ var supportsRequestInitExt = () => {
49
+ return typeof process === "object" && Number.parseInt(process?.versions?.node?.substring(0, 2)) >= 18 && process.versions.undici;
50
+ };
51
+ function randomID() {
52
+ return Math.random().toString(36).slice(2, 11);
53
+ }
54
+ function createClient(clientOptions) {
55
+ let {
56
+ baseUrl = "",
57
+ Request: CustomRequest = globalThis.Request,
58
+ fetch: baseFetch = globalThis.fetch,
59
+ querySerializer: globalQuerySerializer,
60
+ bodySerializer: globalBodySerializer,
61
+ headers: baseHeaders,
62
+ requestInitExt = void 0,
63
+ ...baseOptions
64
+ } = { ...clientOptions };
65
+ requestInitExt = supportsRequestInitExt() ? requestInitExt : void 0;
66
+ baseUrl = removeTrailingSlash(baseUrl);
67
+ const middlewares = [];
68
+ async function coreFetch(schemaPath, fetchOptions) {
69
+ const {
70
+ baseUrl: localBaseUrl,
71
+ fetch: fetch2 = baseFetch,
72
+ Request = CustomRequest,
73
+ headers,
74
+ params = {},
75
+ parseAs = "json",
76
+ querySerializer: requestQuerySerializer,
77
+ bodySerializer = globalBodySerializer ?? defaultBodySerializer,
78
+ body,
79
+ ...init
80
+ } = fetchOptions || {};
81
+ let finalBaseUrl = baseUrl;
82
+ if (localBaseUrl) {
83
+ finalBaseUrl = removeTrailingSlash(localBaseUrl) ?? baseUrl;
84
+ }
85
+ let querySerializer = typeof globalQuerySerializer === "function" ? globalQuerySerializer : createQuerySerializer(globalQuerySerializer);
86
+ if (requestQuerySerializer) {
87
+ querySerializer = typeof requestQuerySerializer === "function" ? requestQuerySerializer : createQuerySerializer({
88
+ ...typeof globalQuerySerializer === "object" ? globalQuerySerializer : {},
89
+ ...requestQuerySerializer
90
+ });
91
+ }
92
+ const serializedBody = body === void 0 ? void 0 : bodySerializer(
93
+ body,
94
+ // Note: we declare mergeHeaders() both here and below because it’s a bit of a chicken-or-egg situation:
95
+ // bodySerializer() needs all headers so we aren’t dropping ones set by the user, however,
96
+ // the result of this ALSO sets the lowest-priority content-type header. So we re-merge below,
97
+ // setting the content-type at the very beginning to be overwritten.
98
+ // Lastly, based on the way headers work, it’s not a simple “present-or-not” check becauase null intentionally un-sets headers.
99
+ mergeHeaders(baseHeaders, headers, params.header)
100
+ );
101
+ const finalHeaders = mergeHeaders(
102
+ // with no body, we should not to set Content-Type
103
+ serializedBody === void 0 || // if serialized body is FormData; browser will correctly set Content-Type & boundary expression
104
+ serializedBody instanceof FormData ? {} : {
105
+ "Content-Type": "application/json"
106
+ },
107
+ baseHeaders,
108
+ headers,
109
+ params.header
110
+ );
111
+ const requestInit = {
112
+ redirect: "follow",
113
+ ...baseOptions,
114
+ ...init,
115
+ body: serializedBody,
116
+ headers: finalHeaders
117
+ };
118
+ let id;
119
+ let options;
120
+ let request = new CustomRequest(
121
+ createFinalURL(schemaPath, { baseUrl: finalBaseUrl, params, querySerializer }),
122
+ requestInit
123
+ );
124
+ let response;
125
+ for (const key in init) {
126
+ if (!(key in request)) {
127
+ request[key] = init[key];
128
+ }
129
+ }
130
+ if (middlewares.length) {
131
+ id = randomID();
132
+ options = Object.freeze({
133
+ baseUrl: finalBaseUrl,
134
+ fetch: fetch2,
135
+ parseAs,
136
+ querySerializer,
137
+ bodySerializer
138
+ });
139
+ for (const m of middlewares) {
140
+ if (m && typeof m === "object" && typeof m.onRequest === "function") {
141
+ const result = await m.onRequest({
142
+ request,
143
+ schemaPath,
144
+ params,
145
+ options,
146
+ id
147
+ });
148
+ if (result) {
149
+ if (result instanceof CustomRequest) {
150
+ request = result;
151
+ } else if (result instanceof Response) {
152
+ response = result;
153
+ break;
154
+ } else {
155
+ throw new Error("onRequest: must return new Request() or Response() when modifying the request");
156
+ }
157
+ }
158
+ }
159
+ }
160
+ }
161
+ if (!response) {
162
+ try {
163
+ response = await fetch2(request, requestInitExt);
164
+ } catch (error2) {
165
+ let errorAfterMiddleware = error2;
166
+ if (middlewares.length) {
167
+ for (let i = middlewares.length - 1; i >= 0; i--) {
168
+ const m = middlewares[i];
169
+ if (m && typeof m === "object" && typeof m.onError === "function") {
170
+ const result = await m.onError({
171
+ request,
172
+ error: errorAfterMiddleware,
173
+ schemaPath,
174
+ params,
175
+ options,
176
+ id
177
+ });
178
+ if (result) {
179
+ if (result instanceof Response) {
180
+ errorAfterMiddleware = void 0;
181
+ response = result;
182
+ break;
183
+ }
184
+ if (result instanceof Error) {
185
+ errorAfterMiddleware = result;
186
+ continue;
187
+ }
188
+ throw new Error("onError: must return new Response() or instance of Error");
189
+ }
190
+ }
191
+ }
192
+ }
193
+ if (errorAfterMiddleware) {
194
+ throw errorAfterMiddleware;
195
+ }
196
+ }
197
+ if (middlewares.length) {
198
+ for (let i = middlewares.length - 1; i >= 0; i--) {
199
+ const m = middlewares[i];
200
+ if (m && typeof m === "object" && typeof m.onResponse === "function") {
201
+ const result = await m.onResponse({
202
+ request,
203
+ response,
204
+ schemaPath,
205
+ params,
206
+ options,
207
+ id
208
+ });
209
+ if (result) {
210
+ if (!(result instanceof Response)) {
211
+ throw new Error("onResponse: must return new Response() when modifying the response");
212
+ }
213
+ response = result;
214
+ }
215
+ }
216
+ }
217
+ }
218
+ }
219
+ if (response.status === 204 || request.method === "HEAD" || response.headers.get("Content-Length") === "0") {
220
+ return response.ok ? { data: void 0, response } : { error: void 0, response };
221
+ }
222
+ if (response.ok) {
223
+ if (parseAs === "stream") {
224
+ return { data: response.body, response };
225
+ }
226
+ return { data: await response[parseAs](), response };
227
+ }
228
+ let error = await response.text();
229
+ try {
230
+ error = JSON.parse(error);
231
+ } catch {
232
+ }
233
+ return { error, response };
234
+ }
235
+ return {
236
+ request(method, url, init) {
237
+ return coreFetch(url, { ...init, method: method.toUpperCase() });
238
+ },
239
+ /** Call a GET endpoint */
240
+ GET(url, init) {
241
+ return coreFetch(url, { ...init, method: "GET" });
242
+ },
243
+ /** Call a PUT endpoint */
244
+ PUT(url, init) {
245
+ return coreFetch(url, { ...init, method: "PUT" });
246
+ },
247
+ /** Call a POST endpoint */
248
+ POST(url, init) {
249
+ return coreFetch(url, { ...init, method: "POST" });
250
+ },
251
+ /** Call a DELETE endpoint */
252
+ DELETE(url, init) {
253
+ return coreFetch(url, { ...init, method: "DELETE" });
254
+ },
255
+ /** Call a OPTIONS endpoint */
256
+ OPTIONS(url, init) {
257
+ return coreFetch(url, { ...init, method: "OPTIONS" });
258
+ },
259
+ /** Call a HEAD endpoint */
260
+ HEAD(url, init) {
261
+ return coreFetch(url, { ...init, method: "HEAD" });
262
+ },
263
+ /** Call a PATCH endpoint */
264
+ PATCH(url, init) {
265
+ return coreFetch(url, { ...init, method: "PATCH" });
266
+ },
267
+ /** Call a TRACE endpoint */
268
+ TRACE(url, init) {
269
+ return coreFetch(url, { ...init, method: "TRACE" });
270
+ },
271
+ /** Register middleware */
272
+ use(...middleware) {
273
+ for (const m of middleware) {
274
+ if (!m) {
275
+ continue;
276
+ }
277
+ if (typeof m !== "object" || !("onRequest" in m || "onResponse" in m || "onError" in m)) {
278
+ throw new Error("Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`");
279
+ }
280
+ middlewares.push(m);
281
+ }
282
+ },
283
+ /** Unregister middleware */
284
+ eject(...middleware) {
285
+ for (const m of middleware) {
286
+ const i = middlewares.indexOf(m);
287
+ if (i !== -1) {
288
+ middlewares.splice(i, 1);
289
+ }
290
+ }
291
+ }
292
+ };
293
+ }
294
+ function serializePrimitiveParam(name, value, options) {
295
+ if (value === void 0 || value === null) {
296
+ return "";
297
+ }
298
+ if (typeof value === "object") {
299
+ throw new Error(
300
+ "Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these."
301
+ );
302
+ }
303
+ return `${name}=${options?.allowReserved === true ? value : encodeURIComponent(value)}`;
304
+ }
305
+ function serializeObjectParam(name, value, options) {
306
+ if (!value || typeof value !== "object") {
307
+ return "";
308
+ }
309
+ const values = [];
310
+ const joiner = {
311
+ simple: ",",
312
+ label: ".",
313
+ matrix: ";"
314
+ }[options.style] || "&";
315
+ if (options.style !== "deepObject" && options.explode === false) {
316
+ for (const k in value) {
317
+ values.push(k, options.allowReserved === true ? value[k] : encodeURIComponent(value[k]));
318
+ }
319
+ const final2 = values.join(",");
320
+ switch (options.style) {
321
+ case "form": {
322
+ return `${name}=${final2}`;
323
+ }
324
+ case "label": {
325
+ return `.${final2}`;
326
+ }
327
+ case "matrix": {
328
+ return `;${name}=${final2}`;
329
+ }
330
+ default: {
331
+ return final2;
332
+ }
333
+ }
334
+ }
335
+ for (const k in value) {
336
+ const finalName = options.style === "deepObject" ? `${name}[${k}]` : k;
337
+ values.push(serializePrimitiveParam(finalName, value[k], options));
338
+ }
339
+ const final = values.join(joiner);
340
+ return options.style === "label" || options.style === "matrix" ? `${joiner}${final}` : final;
341
+ }
342
+ function serializeArrayParam(name, value, options) {
343
+ if (!Array.isArray(value)) {
344
+ return "";
345
+ }
346
+ if (options.explode === false) {
347
+ const joiner2 = { form: ",", spaceDelimited: "%20", pipeDelimited: "|" }[options.style] || ",";
348
+ const final = (options.allowReserved === true ? value : value.map((v) => encodeURIComponent(v))).join(joiner2);
349
+ switch (options.style) {
350
+ case "simple": {
351
+ return final;
352
+ }
353
+ case "label": {
354
+ return `.${final}`;
355
+ }
356
+ case "matrix": {
357
+ return `;${name}=${final}`;
358
+ }
359
+ // case "spaceDelimited":
360
+ // case "pipeDelimited":
361
+ default: {
362
+ return `${name}=${final}`;
363
+ }
364
+ }
365
+ }
366
+ const joiner = { simple: ",", label: ".", matrix: ";" }[options.style] || "&";
367
+ const values = [];
368
+ for (const v of value) {
369
+ if (options.style === "simple" || options.style === "label") {
370
+ values.push(options.allowReserved === true ? v : encodeURIComponent(v));
371
+ } else {
372
+ values.push(serializePrimitiveParam(name, v, options));
373
+ }
374
+ }
375
+ return options.style === "label" || options.style === "matrix" ? `${joiner}${values.join(joiner)}` : values.join(joiner);
376
+ }
377
+ function createQuerySerializer(options) {
378
+ return function querySerializer(queryParams) {
379
+ const search = [];
380
+ if (queryParams && typeof queryParams === "object") {
381
+ for (const name in queryParams) {
382
+ const value = queryParams[name];
383
+ if (value === void 0 || value === null) {
384
+ continue;
385
+ }
386
+ if (Array.isArray(value)) {
387
+ if (value.length === 0) {
388
+ continue;
389
+ }
390
+ search.push(
391
+ serializeArrayParam(name, value, {
392
+ style: "form",
393
+ explode: true,
394
+ ...options?.array,
395
+ allowReserved: options?.allowReserved || false
396
+ })
397
+ );
398
+ continue;
399
+ }
400
+ if (typeof value === "object") {
401
+ search.push(
402
+ serializeObjectParam(name, value, {
403
+ style: "deepObject",
404
+ explode: true,
405
+ ...options?.object,
406
+ allowReserved: options?.allowReserved || false
407
+ })
408
+ );
409
+ continue;
410
+ }
411
+ search.push(serializePrimitiveParam(name, value, options));
412
+ }
413
+ }
414
+ return search.join("&");
415
+ };
416
+ }
417
+ function defaultPathSerializer(pathname, pathParams) {
418
+ let nextURL = pathname;
419
+ for (const match of pathname.match(PATH_PARAM_RE) ?? []) {
420
+ let name = match.substring(1, match.length - 1);
421
+ let explode = false;
422
+ let style = "simple";
423
+ if (name.endsWith("*")) {
424
+ explode = true;
425
+ name = name.substring(0, name.length - 1);
426
+ }
427
+ if (name.startsWith(".")) {
428
+ style = "label";
429
+ name = name.substring(1);
430
+ } else if (name.startsWith(";")) {
431
+ style = "matrix";
432
+ name = name.substring(1);
433
+ }
434
+ if (!pathParams || pathParams[name] === void 0 || pathParams[name] === null) {
435
+ continue;
436
+ }
437
+ const value = pathParams[name];
438
+ if (Array.isArray(value)) {
439
+ nextURL = nextURL.replace(match, serializeArrayParam(name, value, { style, explode }));
440
+ continue;
441
+ }
442
+ if (typeof value === "object") {
443
+ nextURL = nextURL.replace(match, serializeObjectParam(name, value, { style, explode }));
444
+ continue;
445
+ }
446
+ if (style === "matrix") {
447
+ nextURL = nextURL.replace(match, `;${serializePrimitiveParam(name, value)}`);
448
+ continue;
449
+ }
450
+ nextURL = nextURL.replace(match, style === "label" ? `.${encodeURIComponent(value)}` : encodeURIComponent(value));
451
+ }
452
+ return nextURL;
453
+ }
454
+ function defaultBodySerializer(body, headers) {
455
+ if (body instanceof FormData) {
456
+ return body;
457
+ }
458
+ if (headers) {
459
+ const contentType = headers.get instanceof Function ? headers.get("Content-Type") ?? headers.get("content-type") : headers["Content-Type"] ?? headers["content-type"];
460
+ if (contentType === "application/x-www-form-urlencoded") {
461
+ return new URLSearchParams(body).toString();
462
+ }
463
+ }
464
+ return JSON.stringify(body);
465
+ }
466
+ function createFinalURL(pathname, options) {
467
+ let finalURL = `${options.baseUrl}${pathname}`;
468
+ if (options.params?.path) {
469
+ finalURL = defaultPathSerializer(finalURL, options.params.path);
470
+ }
471
+ let search = options.querySerializer(options.params.query ?? {});
472
+ if (search.startsWith("?")) {
473
+ search = search.substring(1);
474
+ }
475
+ if (search) {
476
+ finalURL += `?${search}`;
477
+ }
478
+ return finalURL;
479
+ }
480
+ function mergeHeaders(...allHeaders) {
481
+ const finalHeaders = new Headers();
482
+ for (const h of allHeaders) {
483
+ if (!h || typeof h !== "object") {
484
+ continue;
485
+ }
486
+ const iterator = h instanceof Headers ? h.entries() : Object.entries(h);
487
+ for (const [k, v] of iterator) {
488
+ if (v === null) {
489
+ finalHeaders.delete(k);
490
+ } else if (Array.isArray(v)) {
491
+ for (const v2 of v) {
492
+ finalHeaders.append(k, v2);
493
+ }
494
+ } else if (v !== void 0) {
495
+ finalHeaders.set(k, v);
496
+ }
497
+ }
498
+ }
499
+ return finalHeaders;
500
+ }
501
+ function removeTrailingSlash(url) {
502
+ if (url.endsWith("/")) {
503
+ return url.substring(0, url.length - 1);
504
+ }
505
+ return url;
506
+ }
58
507
 
59
508
  // src/errors.ts
60
509
  var SinnuError = class extends Error {
@@ -125,7 +574,7 @@ function assertApiKey(apiKey) {
125
574
  }
126
575
  function createTypedClient(options) {
127
576
  assertApiKey(options.apiKey);
128
- return (0, import_openapi_fetch.default)({
577
+ return createClient({
129
578
  baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,
130
579
  fetch: options.fetch,
131
580
  headers: {
@@ -328,7 +777,7 @@ var Transactions = class {
328
777
  async get(id) {
329
778
  return this.http.request(`/api/transactions/${encodeURIComponent(id)}/`);
330
779
  }
331
- /** Estorna (refund) uma transação. */
780
+ /** Estorna (refund) uma transação, sempre pelo valor total. Exige o escopo `transactions:refund` na chave. */
332
781
  async refund(id, body = {}) {
333
782
  return this.http.request(
334
783
  `/api/transactions/${encodeURIComponent(id)}/refund/`,
package/dist/index.d.cts CHANGED
@@ -178,7 +178,7 @@ interface paths {
178
178
  put?: never;
179
179
  /**
180
180
  * Estornar transação
181
- * @description Solicita o estorno total de uma transação paga. `reason` e `note` são opcionais e servem para registro interno. Reenvios podem usar `Idempotency-Key`.
181
+ * @description Solicita o estorno total de uma transação paga. Exige o escopo `transactions:refund` na chave de API; o `read` não concede estorno. `reason` e `note` são opcionais e servem para registro interno. Reenvios podem usar `Idempotency-Key`.
182
182
  */
183
183
  post: operations["transactions_refund"];
184
184
  delete?: never;
@@ -854,7 +854,7 @@ interface operations {
854
854
  "application/json": components["schemas"]["SinnuTransaction"];
855
855
  };
856
856
  };
857
- /** @description Sua chave de API não tem permissão para solicitar estorno. */
857
+ /** @description Sua chave de API não tem o escopo `transactions:refund`, exigido para solicitar estorno. */
858
858
  403: {
859
859
  headers: {
860
860
  [name: string]: unknown;
@@ -1114,7 +1114,7 @@ declare class Transactions {
1114
1114
  list(params?: ListTransactionsParams): Promise<Page<Transaction>>;
1115
1115
  /** Busca uma transação pelo id. */
1116
1116
  get(id: string): Promise<Transaction>;
1117
- /** Estorna (refund) uma transação. */
1117
+ /** Estorna (refund) uma transação, sempre pelo valor total. Exige o escopo `transactions:refund` na chave. */
1118
1118
  refund(id: string, body?: RefundTransactionBody): Promise<Transaction>;
1119
1119
  /** Itera todas as transações, página a página. */
1120
1120
  listAll(params?: ListTransactionsParams): AsyncGenerator<Transaction>;
package/dist/index.d.ts CHANGED
@@ -178,7 +178,7 @@ interface paths {
178
178
  put?: never;
179
179
  /**
180
180
  * Estornar transação
181
- * @description Solicita o estorno total de uma transação paga. `reason` e `note` são opcionais e servem para registro interno. Reenvios podem usar `Idempotency-Key`.
181
+ * @description Solicita o estorno total de uma transação paga. Exige o escopo `transactions:refund` na chave de API; o `read` não concede estorno. `reason` e `note` são opcionais e servem para registro interno. Reenvios podem usar `Idempotency-Key`.
182
182
  */
183
183
  post: operations["transactions_refund"];
184
184
  delete?: never;
@@ -854,7 +854,7 @@ interface operations {
854
854
  "application/json": components["schemas"]["SinnuTransaction"];
855
855
  };
856
856
  };
857
- /** @description Sua chave de API não tem permissão para solicitar estorno. */
857
+ /** @description Sua chave de API não tem o escopo `transactions:refund`, exigido para solicitar estorno. */
858
858
  403: {
859
859
  headers: {
860
860
  [name: string]: unknown;
@@ -1114,7 +1114,7 @@ declare class Transactions {
1114
1114
  list(params?: ListTransactionsParams): Promise<Page<Transaction>>;
1115
1115
  /** Busca uma transação pelo id. */
1116
1116
  get(id: string): Promise<Transaction>;
1117
- /** Estorna (refund) uma transação. */
1117
+ /** Estorna (refund) uma transação, sempre pelo valor total. Exige o escopo `transactions:refund` na chave. */
1118
1118
  refund(id: string, body?: RefundTransactionBody): Promise<Transaction>;
1119
1119
  /** Itera todas as transações, página a página. */
1120
1120
  listAll(params?: ListTransactionsParams): AsyncGenerator<Transaction>;
package/dist/index.js CHANGED
@@ -1,5 +1,464 @@
1
- // src/client.ts
2
- import createOpenApiClient from "openapi-fetch";
1
+ // node_modules/openapi-fetch/dist/index.js
2
+ var PATH_PARAM_RE = /\{[^{}]+\}/g;
3
+ var supportsRequestInitExt = () => {
4
+ return typeof process === "object" && Number.parseInt(process?.versions?.node?.substring(0, 2)) >= 18 && process.versions.undici;
5
+ };
6
+ function randomID() {
7
+ return Math.random().toString(36).slice(2, 11);
8
+ }
9
+ function createClient(clientOptions) {
10
+ let {
11
+ baseUrl = "",
12
+ Request: CustomRequest = globalThis.Request,
13
+ fetch: baseFetch = globalThis.fetch,
14
+ querySerializer: globalQuerySerializer,
15
+ bodySerializer: globalBodySerializer,
16
+ headers: baseHeaders,
17
+ requestInitExt = void 0,
18
+ ...baseOptions
19
+ } = { ...clientOptions };
20
+ requestInitExt = supportsRequestInitExt() ? requestInitExt : void 0;
21
+ baseUrl = removeTrailingSlash(baseUrl);
22
+ const middlewares = [];
23
+ async function coreFetch(schemaPath, fetchOptions) {
24
+ const {
25
+ baseUrl: localBaseUrl,
26
+ fetch: fetch2 = baseFetch,
27
+ Request = CustomRequest,
28
+ headers,
29
+ params = {},
30
+ parseAs = "json",
31
+ querySerializer: requestQuerySerializer,
32
+ bodySerializer = globalBodySerializer ?? defaultBodySerializer,
33
+ body,
34
+ ...init
35
+ } = fetchOptions || {};
36
+ let finalBaseUrl = baseUrl;
37
+ if (localBaseUrl) {
38
+ finalBaseUrl = removeTrailingSlash(localBaseUrl) ?? baseUrl;
39
+ }
40
+ let querySerializer = typeof globalQuerySerializer === "function" ? globalQuerySerializer : createQuerySerializer(globalQuerySerializer);
41
+ if (requestQuerySerializer) {
42
+ querySerializer = typeof requestQuerySerializer === "function" ? requestQuerySerializer : createQuerySerializer({
43
+ ...typeof globalQuerySerializer === "object" ? globalQuerySerializer : {},
44
+ ...requestQuerySerializer
45
+ });
46
+ }
47
+ const serializedBody = body === void 0 ? void 0 : bodySerializer(
48
+ body,
49
+ // Note: we declare mergeHeaders() both here and below because it’s a bit of a chicken-or-egg situation:
50
+ // bodySerializer() needs all headers so we aren’t dropping ones set by the user, however,
51
+ // the result of this ALSO sets the lowest-priority content-type header. So we re-merge below,
52
+ // setting the content-type at the very beginning to be overwritten.
53
+ // Lastly, based on the way headers work, it’s not a simple “present-or-not” check becauase null intentionally un-sets headers.
54
+ mergeHeaders(baseHeaders, headers, params.header)
55
+ );
56
+ const finalHeaders = mergeHeaders(
57
+ // with no body, we should not to set Content-Type
58
+ serializedBody === void 0 || // if serialized body is FormData; browser will correctly set Content-Type & boundary expression
59
+ serializedBody instanceof FormData ? {} : {
60
+ "Content-Type": "application/json"
61
+ },
62
+ baseHeaders,
63
+ headers,
64
+ params.header
65
+ );
66
+ const requestInit = {
67
+ redirect: "follow",
68
+ ...baseOptions,
69
+ ...init,
70
+ body: serializedBody,
71
+ headers: finalHeaders
72
+ };
73
+ let id;
74
+ let options;
75
+ let request = new CustomRequest(
76
+ createFinalURL(schemaPath, { baseUrl: finalBaseUrl, params, querySerializer }),
77
+ requestInit
78
+ );
79
+ let response;
80
+ for (const key in init) {
81
+ if (!(key in request)) {
82
+ request[key] = init[key];
83
+ }
84
+ }
85
+ if (middlewares.length) {
86
+ id = randomID();
87
+ options = Object.freeze({
88
+ baseUrl: finalBaseUrl,
89
+ fetch: fetch2,
90
+ parseAs,
91
+ querySerializer,
92
+ bodySerializer
93
+ });
94
+ for (const m of middlewares) {
95
+ if (m && typeof m === "object" && typeof m.onRequest === "function") {
96
+ const result = await m.onRequest({
97
+ request,
98
+ schemaPath,
99
+ params,
100
+ options,
101
+ id
102
+ });
103
+ if (result) {
104
+ if (result instanceof CustomRequest) {
105
+ request = result;
106
+ } else if (result instanceof Response) {
107
+ response = result;
108
+ break;
109
+ } else {
110
+ throw new Error("onRequest: must return new Request() or Response() when modifying the request");
111
+ }
112
+ }
113
+ }
114
+ }
115
+ }
116
+ if (!response) {
117
+ try {
118
+ response = await fetch2(request, requestInitExt);
119
+ } catch (error2) {
120
+ let errorAfterMiddleware = error2;
121
+ if (middlewares.length) {
122
+ for (let i = middlewares.length - 1; i >= 0; i--) {
123
+ const m = middlewares[i];
124
+ if (m && typeof m === "object" && typeof m.onError === "function") {
125
+ const result = await m.onError({
126
+ request,
127
+ error: errorAfterMiddleware,
128
+ schemaPath,
129
+ params,
130
+ options,
131
+ id
132
+ });
133
+ if (result) {
134
+ if (result instanceof Response) {
135
+ errorAfterMiddleware = void 0;
136
+ response = result;
137
+ break;
138
+ }
139
+ if (result instanceof Error) {
140
+ errorAfterMiddleware = result;
141
+ continue;
142
+ }
143
+ throw new Error("onError: must return new Response() or instance of Error");
144
+ }
145
+ }
146
+ }
147
+ }
148
+ if (errorAfterMiddleware) {
149
+ throw errorAfterMiddleware;
150
+ }
151
+ }
152
+ if (middlewares.length) {
153
+ for (let i = middlewares.length - 1; i >= 0; i--) {
154
+ const m = middlewares[i];
155
+ if (m && typeof m === "object" && typeof m.onResponse === "function") {
156
+ const result = await m.onResponse({
157
+ request,
158
+ response,
159
+ schemaPath,
160
+ params,
161
+ options,
162
+ id
163
+ });
164
+ if (result) {
165
+ if (!(result instanceof Response)) {
166
+ throw new Error("onResponse: must return new Response() when modifying the response");
167
+ }
168
+ response = result;
169
+ }
170
+ }
171
+ }
172
+ }
173
+ }
174
+ if (response.status === 204 || request.method === "HEAD" || response.headers.get("Content-Length") === "0") {
175
+ return response.ok ? { data: void 0, response } : { error: void 0, response };
176
+ }
177
+ if (response.ok) {
178
+ if (parseAs === "stream") {
179
+ return { data: response.body, response };
180
+ }
181
+ return { data: await response[parseAs](), response };
182
+ }
183
+ let error = await response.text();
184
+ try {
185
+ error = JSON.parse(error);
186
+ } catch {
187
+ }
188
+ return { error, response };
189
+ }
190
+ return {
191
+ request(method, url, init) {
192
+ return coreFetch(url, { ...init, method: method.toUpperCase() });
193
+ },
194
+ /** Call a GET endpoint */
195
+ GET(url, init) {
196
+ return coreFetch(url, { ...init, method: "GET" });
197
+ },
198
+ /** Call a PUT endpoint */
199
+ PUT(url, init) {
200
+ return coreFetch(url, { ...init, method: "PUT" });
201
+ },
202
+ /** Call a POST endpoint */
203
+ POST(url, init) {
204
+ return coreFetch(url, { ...init, method: "POST" });
205
+ },
206
+ /** Call a DELETE endpoint */
207
+ DELETE(url, init) {
208
+ return coreFetch(url, { ...init, method: "DELETE" });
209
+ },
210
+ /** Call a OPTIONS endpoint */
211
+ OPTIONS(url, init) {
212
+ return coreFetch(url, { ...init, method: "OPTIONS" });
213
+ },
214
+ /** Call a HEAD endpoint */
215
+ HEAD(url, init) {
216
+ return coreFetch(url, { ...init, method: "HEAD" });
217
+ },
218
+ /** Call a PATCH endpoint */
219
+ PATCH(url, init) {
220
+ return coreFetch(url, { ...init, method: "PATCH" });
221
+ },
222
+ /** Call a TRACE endpoint */
223
+ TRACE(url, init) {
224
+ return coreFetch(url, { ...init, method: "TRACE" });
225
+ },
226
+ /** Register middleware */
227
+ use(...middleware) {
228
+ for (const m of middleware) {
229
+ if (!m) {
230
+ continue;
231
+ }
232
+ if (typeof m !== "object" || !("onRequest" in m || "onResponse" in m || "onError" in m)) {
233
+ throw new Error("Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`");
234
+ }
235
+ middlewares.push(m);
236
+ }
237
+ },
238
+ /** Unregister middleware */
239
+ eject(...middleware) {
240
+ for (const m of middleware) {
241
+ const i = middlewares.indexOf(m);
242
+ if (i !== -1) {
243
+ middlewares.splice(i, 1);
244
+ }
245
+ }
246
+ }
247
+ };
248
+ }
249
+ function serializePrimitiveParam(name, value, options) {
250
+ if (value === void 0 || value === null) {
251
+ return "";
252
+ }
253
+ if (typeof value === "object") {
254
+ throw new Error(
255
+ "Deeply-nested arrays/objects aren\u2019t supported. Provide your own `querySerializer()` to handle these."
256
+ );
257
+ }
258
+ return `${name}=${options?.allowReserved === true ? value : encodeURIComponent(value)}`;
259
+ }
260
+ function serializeObjectParam(name, value, options) {
261
+ if (!value || typeof value !== "object") {
262
+ return "";
263
+ }
264
+ const values = [];
265
+ const joiner = {
266
+ simple: ",",
267
+ label: ".",
268
+ matrix: ";"
269
+ }[options.style] || "&";
270
+ if (options.style !== "deepObject" && options.explode === false) {
271
+ for (const k in value) {
272
+ values.push(k, options.allowReserved === true ? value[k] : encodeURIComponent(value[k]));
273
+ }
274
+ const final2 = values.join(",");
275
+ switch (options.style) {
276
+ case "form": {
277
+ return `${name}=${final2}`;
278
+ }
279
+ case "label": {
280
+ return `.${final2}`;
281
+ }
282
+ case "matrix": {
283
+ return `;${name}=${final2}`;
284
+ }
285
+ default: {
286
+ return final2;
287
+ }
288
+ }
289
+ }
290
+ for (const k in value) {
291
+ const finalName = options.style === "deepObject" ? `${name}[${k}]` : k;
292
+ values.push(serializePrimitiveParam(finalName, value[k], options));
293
+ }
294
+ const final = values.join(joiner);
295
+ return options.style === "label" || options.style === "matrix" ? `${joiner}${final}` : final;
296
+ }
297
+ function serializeArrayParam(name, value, options) {
298
+ if (!Array.isArray(value)) {
299
+ return "";
300
+ }
301
+ if (options.explode === false) {
302
+ const joiner2 = { form: ",", spaceDelimited: "%20", pipeDelimited: "|" }[options.style] || ",";
303
+ const final = (options.allowReserved === true ? value : value.map((v) => encodeURIComponent(v))).join(joiner2);
304
+ switch (options.style) {
305
+ case "simple": {
306
+ return final;
307
+ }
308
+ case "label": {
309
+ return `.${final}`;
310
+ }
311
+ case "matrix": {
312
+ return `;${name}=${final}`;
313
+ }
314
+ // case "spaceDelimited":
315
+ // case "pipeDelimited":
316
+ default: {
317
+ return `${name}=${final}`;
318
+ }
319
+ }
320
+ }
321
+ const joiner = { simple: ",", label: ".", matrix: ";" }[options.style] || "&";
322
+ const values = [];
323
+ for (const v of value) {
324
+ if (options.style === "simple" || options.style === "label") {
325
+ values.push(options.allowReserved === true ? v : encodeURIComponent(v));
326
+ } else {
327
+ values.push(serializePrimitiveParam(name, v, options));
328
+ }
329
+ }
330
+ return options.style === "label" || options.style === "matrix" ? `${joiner}${values.join(joiner)}` : values.join(joiner);
331
+ }
332
+ function createQuerySerializer(options) {
333
+ return function querySerializer(queryParams) {
334
+ const search = [];
335
+ if (queryParams && typeof queryParams === "object") {
336
+ for (const name in queryParams) {
337
+ const value = queryParams[name];
338
+ if (value === void 0 || value === null) {
339
+ continue;
340
+ }
341
+ if (Array.isArray(value)) {
342
+ if (value.length === 0) {
343
+ continue;
344
+ }
345
+ search.push(
346
+ serializeArrayParam(name, value, {
347
+ style: "form",
348
+ explode: true,
349
+ ...options?.array,
350
+ allowReserved: options?.allowReserved || false
351
+ })
352
+ );
353
+ continue;
354
+ }
355
+ if (typeof value === "object") {
356
+ search.push(
357
+ serializeObjectParam(name, value, {
358
+ style: "deepObject",
359
+ explode: true,
360
+ ...options?.object,
361
+ allowReserved: options?.allowReserved || false
362
+ })
363
+ );
364
+ continue;
365
+ }
366
+ search.push(serializePrimitiveParam(name, value, options));
367
+ }
368
+ }
369
+ return search.join("&");
370
+ };
371
+ }
372
+ function defaultPathSerializer(pathname, pathParams) {
373
+ let nextURL = pathname;
374
+ for (const match of pathname.match(PATH_PARAM_RE) ?? []) {
375
+ let name = match.substring(1, match.length - 1);
376
+ let explode = false;
377
+ let style = "simple";
378
+ if (name.endsWith("*")) {
379
+ explode = true;
380
+ name = name.substring(0, name.length - 1);
381
+ }
382
+ if (name.startsWith(".")) {
383
+ style = "label";
384
+ name = name.substring(1);
385
+ } else if (name.startsWith(";")) {
386
+ style = "matrix";
387
+ name = name.substring(1);
388
+ }
389
+ if (!pathParams || pathParams[name] === void 0 || pathParams[name] === null) {
390
+ continue;
391
+ }
392
+ const value = pathParams[name];
393
+ if (Array.isArray(value)) {
394
+ nextURL = nextURL.replace(match, serializeArrayParam(name, value, { style, explode }));
395
+ continue;
396
+ }
397
+ if (typeof value === "object") {
398
+ nextURL = nextURL.replace(match, serializeObjectParam(name, value, { style, explode }));
399
+ continue;
400
+ }
401
+ if (style === "matrix") {
402
+ nextURL = nextURL.replace(match, `;${serializePrimitiveParam(name, value)}`);
403
+ continue;
404
+ }
405
+ nextURL = nextURL.replace(match, style === "label" ? `.${encodeURIComponent(value)}` : encodeURIComponent(value));
406
+ }
407
+ return nextURL;
408
+ }
409
+ function defaultBodySerializer(body, headers) {
410
+ if (body instanceof FormData) {
411
+ return body;
412
+ }
413
+ if (headers) {
414
+ const contentType = headers.get instanceof Function ? headers.get("Content-Type") ?? headers.get("content-type") : headers["Content-Type"] ?? headers["content-type"];
415
+ if (contentType === "application/x-www-form-urlencoded") {
416
+ return new URLSearchParams(body).toString();
417
+ }
418
+ }
419
+ return JSON.stringify(body);
420
+ }
421
+ function createFinalURL(pathname, options) {
422
+ let finalURL = `${options.baseUrl}${pathname}`;
423
+ if (options.params?.path) {
424
+ finalURL = defaultPathSerializer(finalURL, options.params.path);
425
+ }
426
+ let search = options.querySerializer(options.params.query ?? {});
427
+ if (search.startsWith("?")) {
428
+ search = search.substring(1);
429
+ }
430
+ if (search) {
431
+ finalURL += `?${search}`;
432
+ }
433
+ return finalURL;
434
+ }
435
+ function mergeHeaders(...allHeaders) {
436
+ const finalHeaders = new Headers();
437
+ for (const h of allHeaders) {
438
+ if (!h || typeof h !== "object") {
439
+ continue;
440
+ }
441
+ const iterator = h instanceof Headers ? h.entries() : Object.entries(h);
442
+ for (const [k, v] of iterator) {
443
+ if (v === null) {
444
+ finalHeaders.delete(k);
445
+ } else if (Array.isArray(v)) {
446
+ for (const v2 of v) {
447
+ finalHeaders.append(k, v2);
448
+ }
449
+ } else if (v !== void 0) {
450
+ finalHeaders.set(k, v);
451
+ }
452
+ }
453
+ }
454
+ return finalHeaders;
455
+ }
456
+ function removeTrailingSlash(url) {
457
+ if (url.endsWith("/")) {
458
+ return url.substring(0, url.length - 1);
459
+ }
460
+ return url;
461
+ }
3
462
 
4
463
  // src/errors.ts
5
464
  var SinnuError = class extends Error {
@@ -70,7 +529,7 @@ function assertApiKey(apiKey) {
70
529
  }
71
530
  function createTypedClient(options) {
72
531
  assertApiKey(options.apiKey);
73
- return createOpenApiClient({
532
+ return createClient({
74
533
  baseUrl: options.baseUrl ?? DEFAULT_BASE_URL,
75
534
  fetch: options.fetch,
76
535
  headers: {
@@ -273,7 +732,7 @@ var Transactions = class {
273
732
  async get(id) {
274
733
  return this.http.request(`/api/transactions/${encodeURIComponent(id)}/`);
275
734
  }
276
- /** Estorna (refund) uma transação. */
735
+ /** Estorna (refund) uma transação, sempre pelo valor total. Exige o escopo `transactions:refund` na chave. */
277
736
  async refund(id, body = {}) {
278
737
  return this.http.request(
279
738
  `/api/transactions/${encodeURIComponent(id)}/refund/`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinnu-dev/sdk",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "SDK oficial da Sinnu para Node.js e TypeScript: cobre com Pix e cartão por links de pagamento, acompanhe transações e valide webhooks.",
5
5
  "keywords": [
6
6
  "sinnu",