@formfeed/sdk 0.3.11 → 0.3.13

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/index.js CHANGED
@@ -11,7 +11,10 @@ function multipart(fields, file) {
11
11
  form.set("file", blob, name);
12
12
  for (const [key, value] of Object.entries(fields)) {
13
13
  if (value === void 0) continue;
14
- form.set(key, typeof value === "string" ? value : typeof value === "object" ? JSON.stringify(value) : String(value));
14
+ form.set(
15
+ key,
16
+ typeof value === "string" ? value : typeof value === "object" ? JSON.stringify(value) : String(value)
17
+ );
15
18
  }
16
19
  return form;
17
20
  }
@@ -41,7 +44,10 @@ function randomKey() {
41
44
  if (c?.randomUUID) return c.randomUUID();
42
45
  return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
43
46
  }
44
- var withKey = (options) => ({ ...options, idempotencyKey: options.idempotencyKey ?? randomKey() });
47
+ var withKey = (options) => ({
48
+ ...options,
49
+ idempotencyKey: options.idempotencyKey ?? randomKey()
50
+ });
45
51
  var idOf = (source) => typeof source === "string" ? source : source.id;
46
52
  var Formfeed = class {
47
53
  baseUrl;
@@ -51,14 +57,28 @@ var Formfeed = class {
51
57
  timeoutMs;
52
58
  extraHeaders;
53
59
  constructor(options) {
54
- if (!options.apiKey) throw new FormfeedError("invalid_request", "apiKey is required", 0);
60
+ if (!options.apiKey)
61
+ throw new FormfeedError("invalid_request", "apiKey is required", 0);
55
62
  this.apiKey = options.apiKey;
56
- this.baseUrl = (options.baseUrl ?? hosts[options.region ?? "eu"]).replace(/\/$/, "");
63
+ this.baseUrl = (options.baseUrl ?? hosts[options.region ?? "eu"]).replace(
64
+ /\/$/,
65
+ ""
66
+ );
57
67
  this.fetchImpl = options.fetch ?? globalThis.fetch;
58
68
  this.maxRetries = options.maxRetries ?? 3;
59
69
  this.timeoutMs = options.timeoutMs ?? 12e4;
60
- this.extraHeaders = Object.fromEntries(Object.entries(options.headers ?? {}).map(([name, value]) => [name.toLowerCase(), value]));
61
- if (!this.fetchImpl) throw new FormfeedError("invalid_request", "fetch is not available; pass options.fetch", 0);
70
+ this.extraHeaders = Object.fromEntries(
71
+ Object.entries(options.headers ?? {}).map(([name, value]) => [
72
+ name.toLowerCase(),
73
+ value
74
+ ])
75
+ );
76
+ if (!this.fetchImpl)
77
+ throw new FormfeedError(
78
+ "invalid_request",
79
+ "fetch is not available; pass options.fetch",
80
+ 0
81
+ );
62
82
  }
63
83
  renders = {
64
84
  /** Renders a template, HTML or URL. Sync by default; `mode: 'async'` returns a queued render. */
@@ -66,16 +86,26 @@ var Formfeed = class {
66
86
  ...options,
67
87
  idempotencyKey: options.idempotencyKey ?? randomKey()
68
88
  }),
69
- get: (id, options = {}) => this.request("GET", `/renders/${encodeURIComponent(id)}`, void 0, options),
89
+ get: (id, options = {}) => this.request(
90
+ "GET",
91
+ `/renders/${encodeURIComponent(id)}`,
92
+ void 0,
93
+ options
94
+ ),
70
95
  /** Polls until the render succeeded or failed (async renders). */
71
96
  waitFor: async (id, options = {}) => {
72
97
  const deadline = Date.now() + (options.timeoutMs ?? 12e4);
73
98
  const interval = options.intervalMs ?? 1e3;
74
99
  for (; ; ) {
75
100
  const render = await this.renders.get(id, { signal: options.signal });
76
- if (render.status === "succeeded" || render.status === "failed") return render;
101
+ if (render.status === "succeeded" || render.status === "failed")
102
+ return render;
77
103
  if (Date.now() + interval > deadline)
78
- throw new FormfeedError("timeout", `render ${id} did not finish within the wait time`, 0);
104
+ throw new FormfeedError(
105
+ "timeout",
106
+ `render ${id} did not finish within the wait time`,
107
+ 0
108
+ );
79
109
  await sleep(interval, options.signal);
80
110
  }
81
111
  },
@@ -83,17 +113,34 @@ var Formfeed = class {
83
113
  download: async (render, options = {}) => {
84
114
  const target = typeof render === "string" ? await this.renders.get(render, options) : render;
85
115
  if (!target.download_url)
86
- throw new FormfeedError("not_ready", `render ${target.id} has no output (${target.status})`, 0);
87
- const res = await this.fetchImpl(target.download_url, { signal: options.signal });
88
- if (!res.ok) throw new FormfeedError("download_failed", `download answered HTTP ${res.status}`, res.status);
116
+ throw new FormfeedError(
117
+ "not_ready",
118
+ `render ${target.id} has no output (${target.status})`,
119
+ 0
120
+ );
121
+ const res = await this.fetchImpl(target.download_url, {
122
+ signal: options.signal
123
+ });
124
+ if (!res.ok)
125
+ throw new FormfeedError(
126
+ "download_failed",
127
+ `download answered HTTP ${res.status}`,
128
+ res.status
129
+ );
89
130
  return new Uint8Array(await res.arrayBuffer());
90
131
  },
91
132
  /** Page of renders, newest first. */
92
133
  list: (query = {}, options = {}) => {
93
134
  const params = new URLSearchParams();
94
- for (const [k, v] of Object.entries(query)) if (v !== void 0 && v !== null && v !== "") params.set(k, String(v));
135
+ for (const [k, v] of Object.entries(query))
136
+ if (v !== void 0 && v !== null && v !== "") params.set(k, String(v));
95
137
  const qs = params.toString();
96
- return this.request("GET", `/renders${qs ? `?${qs}` : ""}`, void 0, options);
138
+ return this.request(
139
+ "GET",
140
+ `/renders${qs ? `?${qs}` : ""}`,
141
+ void 0,
142
+ options
143
+ );
97
144
  },
98
145
  /** Every render matching the query, following the cursor. */
99
146
  all: async (query = {}, options = {}) => {
@@ -107,12 +154,22 @@ var Formfeed = class {
107
154
  return out;
108
155
  },
109
156
  /** Removes the stored files of a render before they expire. Needs the `file:delete` scope. */
110
- deleteOutputs: (id, options = {}) => this.request("DELETE", `/renders/${encodeURIComponent(id)}/outputs`, void 0, options),
157
+ deleteOutputs: (id, options = {}) => this.request(
158
+ "DELETE",
159
+ `/renders/${encodeURIComponent(id)}/outputs`,
160
+ void 0,
161
+ options
162
+ ),
111
163
  /**
112
164
  * The stored request of a render, to render it again. Needs `render:input`; throws
113
165
  * `render_input_expired` (410) when the workspace keeps no requests or the period ended.
114
166
  */
115
- input: (id, options = {}) => this.request("GET", `/renders/${encodeURIComponent(id)}/input`, void 0, options),
167
+ input: (id, options = {}) => this.request(
168
+ "GET",
169
+ `/renders/${encodeURIComponent(id)}/input`,
170
+ void 0,
171
+ options
172
+ ),
116
173
  batch: (request, options = {}) => this.request("POST", "/renders/batch", request, {
117
174
  ...options,
118
175
  idempotencyKey: options.idempotencyKey ?? randomKey()
@@ -124,10 +181,30 @@ var Formfeed = class {
124
181
  * 0.5 units each on live keys; info is free.
125
182
  */
126
183
  pdf = {
127
- merge: (sources, output = {}, options = {}) => this.request("POST", "/pdf/merge", { ...output, sources: sources.map(idOf) }, withKey(options)),
128
- protect: (source, protect, options = {}) => this.request("POST", "/pdf/protect", { ...protect, source: idOf(source) }, withKey(options)),
129
- watermark: (source, watermark, options = {}) => this.request("POST", "/pdf/watermark", { ...watermark, source: idOf(source) }, withKey(options)),
130
- info: (source, options = {}) => this.request("POST", "/pdf/info", { source: idOf(source) }, options),
184
+ merge: (sources, output = {}, options = {}) => this.request(
185
+ "POST",
186
+ "/pdf/merge",
187
+ { ...output, sources: sources.map(idOf) },
188
+ withKey(options)
189
+ ),
190
+ protect: (source, protect, options = {}) => this.request(
191
+ "POST",
192
+ "/pdf/protect",
193
+ { ...protect, source: idOf(source) },
194
+ withKey(options)
195
+ ),
196
+ watermark: (source, watermark, options = {}) => this.request(
197
+ "POST",
198
+ "/pdf/watermark",
199
+ { ...watermark, source: idOf(source) },
200
+ withKey(options)
201
+ ),
202
+ info: (source, options = {}) => this.request(
203
+ "POST",
204
+ "/pdf/info",
205
+ { source: idOf(source) },
206
+ options
207
+ ),
131
208
  /**
132
209
  * Converts an office document to a PDF render (Starter plan and above): an uploaded file (Word,
133
210
  * Excel, PowerPoint, OpenDocument, RTF or HTML, up to 20 MB, not kept), or the output of a Word or
@@ -136,8 +213,18 @@ var Formfeed = class {
136
213
  */
137
214
  convert: (source, convert = {}, options = {}) => {
138
215
  if (typeof source === "object" && "file" in source)
139
- return this.request("POST", "/pdf/convert", multipart({ ...convert }, source.file), withKey(options));
140
- return this.request("POST", "/pdf/convert", { ...convert, source: idOf(source) }, withKey(options));
216
+ return this.request(
217
+ "POST",
218
+ "/pdf/convert",
219
+ multipart({ ...convert }, source.file),
220
+ withKey(options)
221
+ );
222
+ return this.request(
223
+ "POST",
224
+ "/pdf/convert",
225
+ { ...convert, source: idOf(source) },
226
+ withKey(options)
227
+ );
141
228
  }
142
229
  };
143
230
  /**
@@ -149,7 +236,10 @@ var Formfeed = class {
149
236
  files = {
150
237
  /** Uploads a file; the same name replaces the existing file in place and keeps its URL. */
151
238
  upload: (file, options = {}) => {
152
- const blob = file.data instanceof Blob ? file.data : new Blob([file.data], file.contentType ? { type: file.contentType } : {});
239
+ const blob = file.data instanceof Blob ? file.data : new Blob(
240
+ [file.data],
241
+ file.contentType ? { type: file.contentType } : {}
242
+ );
153
243
  const form = new FormData();
154
244
  form.set("file", blob, file.name);
155
245
  form.set("name", file.name);
@@ -158,9 +248,15 @@ var Formfeed = class {
158
248
  /** Page of files, newest first. */
159
249
  list: (query = {}, options = {}) => {
160
250
  const params = new URLSearchParams();
161
- for (const [k, v] of Object.entries(query)) if (v !== void 0 && v !== null && v !== "") params.set(k, String(v));
251
+ for (const [k, v] of Object.entries(query))
252
+ if (v !== void 0 && v !== null && v !== "") params.set(k, String(v));
162
253
  const qs = params.toString();
163
- return this.request("GET", `/files${qs ? `?${qs}` : ""}`, void 0, options);
254
+ return this.request(
255
+ "GET",
256
+ `/files${qs ? `?${qs}` : ""}`,
257
+ void 0,
258
+ options
259
+ );
164
260
  },
165
261
  /** Every file matching the query, following the cursor. */
166
262
  all: async (query = {}, options = {}) => {
@@ -173,9 +269,19 @@ var Formfeed = class {
173
269
  } while (cursor);
174
270
  return out;
175
271
  },
176
- get: (id, options = {}) => this.request("GET", `/files/${encodeURIComponent(id)}`, void 0, options),
272
+ get: (id, options = {}) => this.request(
273
+ "GET",
274
+ `/files/${encodeURIComponent(id)}`,
275
+ void 0,
276
+ options
277
+ ),
177
278
  /** Removes the file and its bytes; templates that name it render a missing image afterwards. */
178
- delete: (file, options = {}) => this.request("DELETE", `/files/${encodeURIComponent(idOf(file))}`, void 0, options)
279
+ delete: (file, options = {}) => this.request(
280
+ "DELETE",
281
+ `/files/${encodeURIComponent(idOf(file))}`,
282
+ void 0,
283
+ options
284
+ )
179
285
  };
180
286
  /** The organisation's brand kit, read-only through the API (it is edited in the app). Needs `template:read`. */
181
287
  brand = {
@@ -187,19 +293,44 @@ var Formfeed = class {
187
293
  */
188
294
  partials = {
189
295
  /** Every shared partial, without its source. */
190
- list: async (options = {}) => (await this.request("GET", "/partials", void 0, options)).data,
296
+ list: async (options = {}) => (await this.request(
297
+ "GET",
298
+ "/partials",
299
+ void 0,
300
+ options
301
+ )).data,
191
302
  /** One partial with its source. */
192
- get: (name, options = {}) => this.request("GET", `/partials/${encodeURIComponent(name)}`, void 0, options),
303
+ get: (name, options = {}) => this.request(
304
+ "GET",
305
+ `/partials/${encodeURIComponent(name)}`,
306
+ void 0,
307
+ options
308
+ ),
193
309
  /** Creates or replaces a partial; pass `base_version` to fail with 409 when it changed since you read it. */
194
310
  put: async (name, input, options = {}) => {
195
- const { status, body } = await this.send("PUT", `/partials/${encodeURIComponent(name)}`, input, options);
311
+ const { status, body } = await this.send(
312
+ "PUT",
313
+ `/partials/${encodeURIComponent(name)}`,
314
+ input,
315
+ options
316
+ );
196
317
  return { partial: body, created: status === 201 };
197
318
  },
198
319
  /** Removes a partial; templates that still include it fail to render afterwards. */
199
- delete: (name, options = {}) => this.request("DELETE", `/partials/${encodeURIComponent(name)}`, void 0, options)
320
+ delete: (name, options = {}) => this.request(
321
+ "DELETE",
322
+ `/partials/${encodeURIComponent(name)}`,
323
+ void 0,
324
+ options
325
+ )
200
326
  };
201
327
  jobs = {
202
- get: (id, options = {}) => this.request("GET", `/jobs/${encodeURIComponent(id)}`, void 0, options),
328
+ get: (id, options = {}) => this.request(
329
+ "GET",
330
+ `/jobs/${encodeURIComponent(id)}`,
331
+ void 0,
332
+ options
333
+ ),
203
334
  waitFor: async (id, options = {}) => {
204
335
  const deadline = Date.now() + (options.timeoutMs ?? 6e5);
205
336
  const interval = options.intervalMs ?? 2e3;
@@ -207,37 +338,77 @@ var Formfeed = class {
207
338
  const job = await this.jobs.get(id, { signal: options.signal });
208
339
  if (job.status !== "queued" && job.status !== "processing") return job;
209
340
  if (Date.now() + interval > deadline)
210
- throw new FormfeedError("timeout", `job ${id} did not finish within the wait time`, 0);
341
+ throw new FormfeedError(
342
+ "timeout",
343
+ `job ${id} did not finish within the wait time`,
344
+ 0
345
+ );
211
346
  await sleep(interval, options.signal);
212
347
  }
213
348
  }
214
349
  };
215
350
  webhooks = {
216
- list: async (options = {}) => (await this.request("GET", "/webhooks", void 0, options)).data,
351
+ list: async (options = {}) => (await this.request(
352
+ "GET",
353
+ "/webhooks",
354
+ void 0,
355
+ options
356
+ )).data,
217
357
  create: (input, options = {}) => this.request("POST", "/webhooks", input, options),
218
- update: (id, patch, options = {}) => this.request("PUT", `/webhooks/${encodeURIComponent(id)}`, patch, options),
219
- delete: (id, options = {}) => this.request("DELETE", `/webhooks/${encodeURIComponent(id)}`, void 0, options),
220
- test: (id, options = {}) => this.request("POST", `/webhooks/${encodeURIComponent(id)}/test`, void 0, options),
358
+ update: (id, patch, options = {}) => this.request(
359
+ "PUT",
360
+ `/webhooks/${encodeURIComponent(id)}`,
361
+ patch,
362
+ options
363
+ ),
364
+ delete: (id, options = {}) => this.request(
365
+ "DELETE",
366
+ `/webhooks/${encodeURIComponent(id)}`,
367
+ void 0,
368
+ options
369
+ ),
370
+ test: (id, options = {}) => this.request(
371
+ "POST",
372
+ `/webhooks/${encodeURIComponent(id)}/test`,
373
+ void 0,
374
+ options
375
+ ),
221
376
  /**
222
377
  * Sends a stored event (`evt_…`) again as a new delivery to a registered endpoint (`webhook:manage`)
223
378
  * or a running listen session (`webhook:listen`).
224
379
  */
225
- resend: (eventId, endpointId, options = {}) => this.request("POST", `/webhooks/events/${encodeURIComponent(eventId)}/resend`, { endpoint_id: endpointId }, options),
380
+ resend: (eventId, endpointId, options = {}) => this.request(
381
+ "POST",
382
+ `/webhooks/events/${encodeURIComponent(eventId)}/resend`,
383
+ { endpoint_id: endpointId },
384
+ options
385
+ ),
226
386
  /**
227
387
  * Listen sessions, what `formfeed listen` uses. Needs `webhook:listen`. Starting a session ends the
228
388
  * previous one of the same key; the WebSocket itself is up to the caller.
229
389
  */
230
390
  listen: {
231
391
  start: (input = {}, options = {}) => this.request("POST", "/webhooks/listen", input, options),
232
- end: (id, options = {}) => this.request("DELETE", `/webhooks/listen/${encodeURIComponent(id)}`, void 0, options)
392
+ end: (id, options = {}) => this.request(
393
+ "DELETE",
394
+ `/webhooks/listen/${encodeURIComponent(id)}`,
395
+ void 0,
396
+ options
397
+ )
233
398
  }
234
399
  };
235
400
  templates = {
236
401
  list: (query = {}, options = {}) => {
237
402
  const params = new URLSearchParams();
238
- for (const [k, v] of Object.entries(query)) if (v !== void 0 && v !== null && v !== "") params.set(k, String(v));
403
+ for (const [k, v] of Object.entries(query))
404
+ if (v !== void 0 && v !== null && v !== "") params.set(k, String(v));
239
405
  const qs = params.toString();
240
- return this.request("GET", `/templates${qs ? `?${qs}` : ""}`, void 0, options);
406
+ return this.request(
407
+ "GET",
408
+ `/templates${qs ? `?${qs}` : ""}`,
409
+ void 0,
410
+ options
411
+ );
241
412
  },
242
413
  /** Every template of the workspace, following the cursor. */
243
414
  all: async (query = {}, options = {}) => {
@@ -250,27 +421,63 @@ var Formfeed = class {
250
421
  } while (cursor);
251
422
  return out;
252
423
  },
253
- get: (idOrSlug, options = {}) => this.request("GET", `/templates/${encodeURIComponent(idOrSlug)}`, void 0, options),
424
+ get: (idOrSlug, options = {}) => this.request(
425
+ "GET",
426
+ `/templates/${encodeURIComponent(idOrSlug)}`,
427
+ void 0,
428
+ options
429
+ ),
254
430
  /** A Word or PowerPoint template (`kind` `docx` or `pptx`) is created from its `file`, sent as multipart. */
255
431
  create: (input, options = {}) => {
256
432
  if (isOfficeInput(input) && input.file) {
257
433
  const { file, ...fields } = input;
258
- return this.request("POST", "/templates", multipart(fields, file), options);
434
+ return this.request(
435
+ "POST",
436
+ "/templates",
437
+ multipart(fields, file),
438
+ options
439
+ );
259
440
  }
260
441
  return this.request("POST", "/templates", input, options);
261
442
  },
262
- update: (idOrSlug, patch, options = {}) => this.request("PUT", `/templates/${encodeURIComponent(idOrSlug)}`, patch, options),
263
- archive: (idOrSlug, options = {}) => this.request("DELETE", `/templates/${encodeURIComponent(idOrSlug)}`, void 0, options),
443
+ update: (idOrSlug, patch, options = {}) => this.request(
444
+ "PUT",
445
+ `/templates/${encodeURIComponent(idOrSlug)}`,
446
+ patch,
447
+ options
448
+ ),
449
+ archive: (idOrSlug, options = {}) => this.request(
450
+ "DELETE",
451
+ `/templates/${encodeURIComponent(idOrSlug)}`,
452
+ void 0,
453
+ options
454
+ ),
264
455
  versions: {
265
- list: async (idOrSlug, options = {}) => (await this.request("GET", `/templates/${encodeURIComponent(idOrSlug)}/versions`, void 0, options)).data,
456
+ list: async (idOrSlug, options = {}) => (await this.request(
457
+ "GET",
458
+ `/templates/${encodeURIComponent(idOrSlug)}/versions`,
459
+ void 0,
460
+ options
461
+ )).data,
266
462
  /** `which`: 'published', 'latest', a version number or a channel name (its main version). Carries the files. */
267
- get: (idOrSlug, which = "published", options = {}) => this.request("GET", `/templates/${encodeURIComponent(idOrSlug)}/versions/${encodeURIComponent(String(which))}`, void 0, options),
463
+ get: (idOrSlug, which = "published", options = {}) => this.request(
464
+ "GET",
465
+ `/templates/${encodeURIComponent(idOrSlug)}/versions/${encodeURIComponent(String(which))}`,
466
+ void 0,
467
+ options
468
+ ),
268
469
  /** For a Word or PowerPoint template, pass `file` to replace the document; without it the latest file is kept. */
269
470
  create: (idOrSlug, input, options = {}) => {
270
471
  const path = `/templates/${encodeURIComponent(idOrSlug)}/versions`;
271
472
  if (isOfficeInput(input)) {
272
473
  const { file, ...fields } = input;
273
- if (file) return this.request("POST", path, multipart(fields, file), options);
474
+ if (file)
475
+ return this.request(
476
+ "POST",
477
+ path,
478
+ multipart(fields, file),
479
+ options
480
+ );
274
481
  return this.request("POST", path, fields, options);
275
482
  }
276
483
  return this.request("POST", path, input, options);
@@ -299,7 +506,12 @@ var Formfeed = class {
299
506
  * uses the version the channel points at. Moves reach renders within a minute.
300
507
  */
301
508
  channels: {
302
- list: (idOrSlug, options = {}) => this.request("GET", `/templates/${encodeURIComponent(idOrSlug)}/channels`, void 0, options),
509
+ list: (idOrSlug, options = {}) => this.request(
510
+ "GET",
511
+ `/templates/${encodeURIComponent(idOrSlug)}/channels`,
512
+ void 0,
513
+ options
514
+ ),
303
515
  /** Creates or moves a channel; on `published` this publishes. */
304
516
  set: (idOrSlug, name, move, options = {}) => {
305
517
  const { allowBreaking, ...rest } = options;
@@ -333,19 +545,39 @@ var Formfeed = class {
333
545
  schema: (idOrSlug, options = {}) => {
334
546
  const { version, ...rest } = options;
335
547
  const query = version === void 0 ? "" : `?version=${encodeURIComponent(String(version))}`;
336
- return this.request("GET", `/templates/${encodeURIComponent(idOrSlug)}/schema${query}`, void 0, rest);
548
+ return this.request(
549
+ "GET",
550
+ `/templates/${encodeURIComponent(idOrSlug)}/schema${query}`,
551
+ void 0,
552
+ rest
553
+ );
337
554
  },
338
555
  /**
339
556
  * Checks a version with data without rendering: syntax, header and footer, missing partials,
340
557
  * runtime errors and the data against the stored schema. Free. Without `data`, the version's
341
558
  * sample data is checked. `version` takes a channel name too.
342
559
  */
343
- validate: (idOrSlug, input = {}, options = {}) => this.request("POST", `/templates/${encodeURIComponent(idOrSlug)}/validate`, input, options)
560
+ validate: (idOrSlug, input = {}, options = {}) => this.request(
561
+ "POST",
562
+ `/templates/${encodeURIComponent(idOrSlug)}/validate`,
563
+ input,
564
+ options
565
+ )
344
566
  };
345
567
  account = {
346
- get: (options = {}) => this.request("GET", "/account", void 0, options),
568
+ get: (options = {}) => this.request(
569
+ "GET",
570
+ "/account",
571
+ void 0,
572
+ options
573
+ ),
347
574
  /** Units of the current period, or of `YYYY-MM`, with a daily series and a breakdown per template. */
348
- usage: (period = "current", options = {}) => this.request("GET", `/usage?period=${encodeURIComponent(period)}`, void 0, options)
575
+ usage: (period = "current", options = {}) => this.request(
576
+ "GET",
577
+ `/usage?period=${encodeURIComponent(period)}`,
578
+ void 0,
579
+ options
580
+ )
349
581
  };
350
582
  /** Workspaces of the key's organisation. Needs `workspace:delete`, which no key has by default. */
351
583
  workspaces = {
@@ -353,7 +585,12 @@ var Formfeed = class {
353
585
  * Deletes a workspace: it leaves the app and the API at once, its keys are revoked and its content
354
586
  * is removed after 30 days. The organisation's last workspace is refused with `last_workspace`.
355
587
  */
356
- delete: (id, options = {}) => this.request("DELETE", `/workspaces/${encodeURIComponent(id)}`, void 0, options)
588
+ delete: (id, options = {}) => this.request(
589
+ "DELETE",
590
+ `/workspaces/${encodeURIComponent(id)}`,
591
+ void 0,
592
+ options
593
+ )
357
594
  };
358
595
  channelAction(idOrSlug, name, action, options) {
359
596
  const { allowBreaking, ...rest } = options;
@@ -381,13 +618,21 @@ var Formfeed = class {
381
618
  ...this.extraHeaders
382
619
  };
383
620
  const isForm = typeof FormData !== "undefined" && body instanceof FormData;
384
- if (body !== void 0 && !isForm) headers["content-type"] = "application/json";
385
- if (options.idempotencyKey) headers["idempotency-key"] = options.idempotencyKey;
621
+ if (body !== void 0 && !isForm)
622
+ headers["content-type"] = "application/json";
623
+ if (options.idempotencyKey)
624
+ headers["idempotency-key"] = options.idempotencyKey;
386
625
  let attempt = 0;
387
626
  for (; ; ) {
388
627
  const controller = new AbortController();
389
- const timer = setTimeout(() => controller.abort(new Error("request timed out")), this.timeoutMs);
390
- options.signal?.addEventListener("abort", () => controller.abort(options.signal?.reason));
628
+ const timer = setTimeout(
629
+ () => controller.abort(new Error("request timed out")),
630
+ this.timeoutMs
631
+ );
632
+ options.signal?.addEventListener(
633
+ "abort",
634
+ () => controller.abort(options.signal?.reason)
635
+ );
391
636
  let res;
392
637
  try {
393
638
  res = await this.fetchImpl(url, {
@@ -403,22 +648,38 @@ var Formfeed = class {
403
648
  await sleep(this.backoff(attempt, null), options.signal);
404
649
  continue;
405
650
  }
406
- throw new FormfeedError("network_error", e instanceof Error ? e.message : String(e), 0);
651
+ throw new FormfeedError(
652
+ "network_error",
653
+ e instanceof Error ? e.message : String(e),
654
+ 0
655
+ );
407
656
  }
408
657
  clearTimeout(timer);
409
658
  if ((res.status === 429 || res.status === 503) && attempt < this.maxRetries) {
410
659
  attempt++;
411
- await sleep(this.backoff(attempt, res.headers.get("retry-after")), options.signal);
660
+ await sleep(
661
+ this.backoff(attempt, res.headers.get("retry-after")),
662
+ options.signal
663
+ );
412
664
  continue;
413
665
  }
414
666
  if (res.status === 204) return { status: 204, body: void 0 };
415
- if (as === "bytes" && res.ok) return { status: res.status, body: new Uint8Array(await res.arrayBuffer()) };
667
+ if (as === "bytes" && res.ok)
668
+ return {
669
+ status: res.status,
670
+ body: new Uint8Array(await res.arrayBuffer())
671
+ };
416
672
  const text = await res.text();
417
673
  let json = null;
418
674
  try {
419
675
  json = text ? JSON.parse(text) : null;
420
676
  } catch {
421
- if (res.ok) throw new FormfeedError("invalid_response", `the API answered HTTP ${res.status} with a body that is not JSON`, res.status);
677
+ if (res.ok)
678
+ throw new FormfeedError(
679
+ "invalid_response",
680
+ `the API answered HTTP ${res.status} with a body that is not JSON`,
681
+ res.status
682
+ );
422
683
  }
423
684
  if (!res.ok) {
424
685
  const problem = json ?? {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formfeed/sdk",
3
- "version": "0.3.11",
3
+ "version": "0.3.13",
4
4
  "description": "Formfeed API client: renders, templates, webhooks. No dependencies, Web APIs only.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/types/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { Formfeed, FormfeedError } from './lib/client.cjs';
2
- export type { Template, TemplateCreate, TemplateFiles, TemplateKind, TemplateListOptions, TemplateValidation, VersionRef, TemplateVersion, TemplateVersionCreate, TemplateFile, OfficeTemplateKind, OfficeTemplateCreate, OfficeVersionCreate, OfficeFileUpload, ConvertOptions, VersionStatus, BatchRequest, Channel, ChannelList, ChannelMove, Brand, SharedPartial, SharedPartialPut, SharedPartialPutResult, Diagnostic, Engine, FileListOptions, FileUpload, FormfeedOptions, FormfeedTemplates, Job, LibraryFile, OutputFormat, PdfInfo, PdfOutputOptions, PdfPermission, PostProcessing, Problem, StorageDelivery, StorageDeliveryEvent, StorageError, StorageOption, WebhookEventType, ProtectOptions, Region, Render, RenderListOptions, RenderRequest, RenderStatus, TemplateData, TypedRenderRequest, RequestOptions, SchemaChange, SchemaCheck, SchemaGuardOptions, Usage, WaitOptions, WatermarkOptions, WebhookEndpoint, WebhookEndpointCreate, WebhookEndpointUpdate, WebhookEnvironment, WebhookResend, ListenSession, ListenSessionOptions, RenderInput, } from './lib/client.cjs';
2
+ export type { Template, TemplateCreate, TemplateFiles, TemplateKind, TemplateListOptions, TemplateValidation, VersionRef, TemplateVersion, TemplateVersionCreate, TemplateFile, OfficeTemplateKind, OfficeTemplateCreate, OfficeVersionCreate, OfficeFileUpload, ConvertOptions, VersionStatus, BatchRequest, Channel, ChannelList, ChannelMove, Brand, SharedPartial, SharedPartialPut, SharedPartialPutResult, Diagnostic, Engine, FileListOptions, FileUpload, FormfeedOptions, FormfeedTemplates, Job, LibraryFile, OutputFormat, PdfInfo, PdfOutputOptions, PdfPermission, PostProcessing, Einvoice, EinvoiceMessage, EinvoiceOptions, Accessibility, AccessibilityFailure, AccessibilityWarning, PdfUaOptions, Problem, StorageDelivery, StorageDeliveryEvent, StorageError, StorageOption, WebhookEventType, ProtectOptions, Region, Render, RenderListOptions, RenderRequest, RenderStatus, TemplateData, TypedRenderRequest, RequestOptions, SchemaChange, SchemaCheck, SchemaGuardOptions, Usage, WaitOptions, WatermarkOptions, WebhookEndpoint, WebhookEndpointCreate, WebhookEndpointUpdate, WebhookEnvironment, WebhookResend, ListenSession, ListenSessionOptions, RenderInput, } from './lib/client.cjs';
3
3
  export { parseWebhookEvent, verifyWebhookSignature } from './lib/webhooks.cjs';
4
4
  export type { VerifyOptions } from './lib/webhooks.cjs';
package/types/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { Formfeed, FormfeedError } from './lib/client.js';
2
- export type { Template, TemplateCreate, TemplateFiles, TemplateKind, TemplateListOptions, TemplateValidation, VersionRef, TemplateVersion, TemplateVersionCreate, TemplateFile, OfficeTemplateKind, OfficeTemplateCreate, OfficeVersionCreate, OfficeFileUpload, ConvertOptions, VersionStatus, BatchRequest, Channel, ChannelList, ChannelMove, Brand, SharedPartial, SharedPartialPut, SharedPartialPutResult, Diagnostic, Engine, FileListOptions, FileUpload, FormfeedOptions, FormfeedTemplates, Job, LibraryFile, OutputFormat, PdfInfo, PdfOutputOptions, PdfPermission, PostProcessing, Problem, StorageDelivery, StorageDeliveryEvent, StorageError, StorageOption, WebhookEventType, ProtectOptions, Region, Render, RenderListOptions, RenderRequest, RenderStatus, TemplateData, TypedRenderRequest, RequestOptions, SchemaChange, SchemaCheck, SchemaGuardOptions, Usage, WaitOptions, WatermarkOptions, WebhookEndpoint, WebhookEndpointCreate, WebhookEndpointUpdate, WebhookEnvironment, WebhookResend, ListenSession, ListenSessionOptions, RenderInput, } from './lib/client.js';
2
+ export type { Template, TemplateCreate, TemplateFiles, TemplateKind, TemplateListOptions, TemplateValidation, VersionRef, TemplateVersion, TemplateVersionCreate, TemplateFile, OfficeTemplateKind, OfficeTemplateCreate, OfficeVersionCreate, OfficeFileUpload, ConvertOptions, VersionStatus, BatchRequest, Channel, ChannelList, ChannelMove, Brand, SharedPartial, SharedPartialPut, SharedPartialPutResult, Diagnostic, Engine, FileListOptions, FileUpload, FormfeedOptions, FormfeedTemplates, Job, LibraryFile, OutputFormat, PdfInfo, PdfOutputOptions, PdfPermission, PostProcessing, Einvoice, EinvoiceMessage, EinvoiceOptions, Accessibility, AccessibilityFailure, AccessibilityWarning, PdfUaOptions, Problem, StorageDelivery, StorageDeliveryEvent, StorageError, StorageOption, WebhookEventType, ProtectOptions, Region, Render, RenderListOptions, RenderRequest, RenderStatus, TemplateData, TypedRenderRequest, RequestOptions, SchemaChange, SchemaCheck, SchemaGuardOptions, Usage, WaitOptions, WatermarkOptions, WebhookEndpoint, WebhookEndpointCreate, WebhookEndpointUpdate, WebhookEnvironment, WebhookResend, ListenSession, ListenSessionOptions, RenderInput, } from './lib/client.js';
3
3
  export { parseWebhookEvent, verifyWebhookSignature } from './lib/webhooks.js';
4
4
  export type { VerifyOptions } from './lib/webhooks.js';