@tabsircg/fb-sdk 1.0.4 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +59 -367
  2. package/dist/client.d.ts +9 -2
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +2 -0
  5. package/dist/client.js.map +1 -1
  6. package/dist/httpClient.d.ts +9 -7
  7. package/dist/httpClient.d.ts.map +1 -1
  8. package/dist/httpClient.js +27 -18
  9. package/dist/httpClient.js.map +1 -1
  10. package/dist/internal/batchable.d.ts +4 -0
  11. package/dist/internal/batchable.d.ts.map +1 -0
  12. package/dist/internal/batchable.js +24 -0
  13. package/dist/internal/batchable.js.map +1 -0
  14. package/dist/internal/fetchers.d.ts +6 -8
  15. package/dist/internal/fetchers.d.ts.map +1 -1
  16. package/dist/internal/fetchers.js +34 -50
  17. package/dist/internal/fetchers.js.map +1 -1
  18. package/dist/resources/InsightResource.d.ts +2 -2
  19. package/dist/resources/PageResource.d.ts +1 -1
  20. package/dist/resources/PageResource.d.ts.map +1 -1
  21. package/dist/resources/PageResource.js +7 -17
  22. package/dist/resources/PageResource.js.map +1 -1
  23. package/dist/resources/PostResource.d.ts +1 -1
  24. package/dist/resources/PostResource.d.ts.map +1 -1
  25. package/dist/resources/PostResource.js +3 -7
  26. package/dist/resources/PostResource.js.map +1 -1
  27. package/dist/resources/UserResource.d.ts +2 -2
  28. package/dist/resources/UserResource.d.ts.map +1 -1
  29. package/dist/resources/UserResource.js +4 -8
  30. package/dist/resources/UserResource.js.map +1 -1
  31. package/dist/resources/comment/CommentResource.d.ts +2 -6
  32. package/dist/resources/comment/CommentResource.d.ts.map +1 -1
  33. package/dist/resources/comment/CommentResource.js +3 -5
  34. package/dist/resources/comment/CommentResource.js.map +1 -1
  35. package/dist/resources/comment/PageCommentResouorce.d.ts +9 -4
  36. package/dist/resources/comment/PageCommentResouorce.d.ts.map +1 -1
  37. package/dist/resources/comment/PageCommentResouorce.js +6 -26
  38. package/dist/resources/comment/PageCommentResouorce.js.map +1 -1
  39. package/dist/resources/createBatchResource.d.ts +17 -0
  40. package/dist/resources/createBatchResource.d.ts.map +1 -0
  41. package/dist/resources/createBatchResource.js +25 -0
  42. package/dist/resources/createBatchResource.js.map +1 -0
  43. package/dist/types/facebookpost.d.ts +11 -4
  44. package/dist/types/facebookpost.d.ts.map +1 -1
  45. package/dist/types/shared.d.ts +18 -8
  46. package/dist/types/shared.d.ts.map +1 -1
  47. package/dist/types/shared.js.map +1 -1
  48. package/dist/types/webhook.d.ts +37 -16
  49. package/dist/types/webhook.d.ts.map +1 -1
  50. package/package.json +9 -5
package/README.md CHANGED
@@ -1,384 +1,76 @@
1
- # fb-sdk
1
+ # @tabsircg/fb-sdk
2
2
 
3
- A typed Node.js SDK for the Facebook Graph API (v25.0). Select only the fields you need, get full autocomplete while writing the selector, strict compile-time validation that rejects unknown fields, and a return type narrowed to exactly what you selected — all without runtime overhead.
3
+ A strongly-typed, modern TypeScript SDK for the Facebook Graph API (v25.0). It provides a fluent, resource-based interface with automatic `camelCase` `snake_case` transformation, seamless request batching, and an advanced type-safe field selector system that mimics GraphQL.
4
4
 
5
- ## Installation
5
+ ## Tech Stack
6
+ - **TypeScript** (v5.9.3) - Core language and advanced type system
7
+ - **Axios** (v1.13.6) - HTTP client for interacting with the Graph API
8
+ - **form-data** (v4.0.5) - For handling multipart/form-data (used in batching and media uploads)
9
+ - **dotenv** (v17.3.1) - Environment variable management
10
+ - **tsx** (v4.21.0) - For rapid development and execution of TypeScript files
6
11
 
7
- ```bash
8
- npm install fb-sdk
9
- ```
10
-
11
- **Requirements:** Node.js 18+, TypeScript 5.9+
12
-
13
- **Dependencies:** `axios`, `form-data`
14
-
15
- ## Quick Start
16
-
17
- ```typescript
18
- import { fbGraph } from "fb-sdk";
19
-
20
- const fb = fbGraph("your-access-token");
21
-
22
- // Get a post — only the fields you select exist on the result
23
- const post = await fb.post("postId").get({
24
- id: true,
25
- message: true,
26
- comments: {
27
- options: { filter: "toplevel" },
28
- fields: { id: true, message: true },
29
- },
30
- });
31
-
32
- post.id; // string
33
- post.message; // string | undefined
34
- post.comments.data[0].message; // string
35
- post.comments.paging; // Paging
36
- // post.fullPicture — compile error, not selected
37
- ```
38
-
39
- ## Field Selection
40
-
41
- Every `get` and `list` method accepts a **field selector** — an object whose shape mirrors the resource type. You pick fields by setting them to `true`. The SDK converts this object into the Graph API `fields` query parameter and infers a return type containing only the selected fields.
42
-
43
- ### Scalar fields
44
-
45
- ```typescript
46
- { id: true, message: true }
47
- // → fields=id,message
48
- ```
49
-
50
- ### Nested objects
51
-
52
- For non-collection nested objects, nest the selector directly:
53
-
54
- ```typescript
55
- { picture: { data: { url: true, height: true } } }
56
- // → fields=picture{data{url,height}}
57
- ```
58
-
59
- You can also pass `true` to select all fields of a nested object:
60
-
61
- ```typescript
62
- {
63
- picture: true;
64
- }
65
- // → fields=picture
66
- ```
67
-
68
- ### Edges (collections)
69
-
70
- Edges — like `comments` on a post — are paginated collections. They require the `{ fields }` wrapper:
71
-
72
- ```typescript
73
- {
74
- comments: {
75
- fields: { id: true, message: true }
76
- }
77
- }
78
- // → fields=comments{id,message}
79
- ```
80
-
81
- Passing `true` selects all fields on the edge's items:
82
-
83
- ```typescript
84
- {
85
- comments: true;
86
- }
87
- // → fields=comments
88
- ```
89
-
90
- ### Edge options
12
+ ## Environment Variables
91
13
 
92
- Some edges accept extra parameters (limit, pagination cursors, filters). These go in `options`:
14
+ No required environment variables are hardcoded into the SDK itself. However, to interact with the Facebook Graph API, you must supply a valid Access Token when initializing the client wrapper.
93
15
 
94
- ```typescript
95
- {
96
- comments: {
97
- options: { filter: "toplevel", limit: 10 },
98
- fields: { id: true, message: true }
99
- }
100
- }
101
- // → fields=comments.filter(toplevel).limit(10){id,message}
102
- ```
103
-
104
- Available options vary per edge. The `comments` edge supports `filter` and `summary` on top of the base `limit`, `after`, and `before`. The SDK infers the correct options type for each edge — you get autocomplete for what's available.
105
-
106
- ### Return type narrowing
107
-
108
- The return type contains **only** what you selected. If you select `{ id: true, message: true }` on a `FacebookPost`, the result type is `{ id: string; message: string | undefined }` — not the full `FacebookPost`. This applies recursively to nested objects and edges.
109
-
110
- When an edge has option-dependent response fields (e.g., `comments` includes a `summary` object), those fields appear in the return type only when `options` is provided in the selector.
111
-
112
- ## Available Resources
113
-
114
- ### `fb.post(postId)`
115
-
116
- Operations on a specific post by ID.
117
-
118
- #### `fb.post(postId).get(fields)`
119
-
120
- Fetch a single post.
121
-
122
- ```typescript
123
- const post = await fb.post("postId").get({
124
- id: true,
125
- statusType: true,
126
- createdTime: true,
127
- shares: true,
128
- reactions: true,
129
- });
130
- ```
131
-
132
- #### `fb.post(postId).expire(time, type)`
133
-
134
- Set an expiration on a post.
135
-
136
- ```typescript
137
- await fb.post("postId").expire(Date.now() + 86400000, "expire_only");
138
- ```
139
-
140
- #### `fb.post(postId).comments.list(fields)`
141
-
142
- Fetch comments on a post. Also provides a `.create(data)` method to add a comment.
143
-
144
- ```typescript
145
- const comments = await fb.post("postId").comments.list({
146
- id: true,
147
- message: true,
148
- from: { name: true },
149
- });
150
- // comments.data — Comment[]
151
- // comments.paging — Paging
152
-
153
- // Create a comment
154
- const newComment = await fb.post("postId").comments.create({
155
- message: "Hello world!"
156
- });
157
- ```
158
-
159
- ---
160
-
161
- ### `fb.me`
162
-
163
- Operations on the authenticated user.
164
-
165
- #### `fb.me.get(fields)`
166
-
167
- Fetch the current user's profile.
168
-
169
- ```typescript
170
- const me = await fb.me.get({ id: true, name: true });
171
- ```
172
-
173
- #### `fb.me.accounts(fields)`
174
-
175
- List Facebook Pages the user manages.
176
-
177
- ```typescript
178
- const pages = await fb.me.accounts({
179
- id: true,
180
- name: true,
181
- accessToken: true,
182
- });
183
- // pages.data — FacebookPage[]
184
- // pages.paging — Paging
185
- ```
16
+ For development (`npm run dev`), you likely need to configure your `.env` file with a token to test against `src/temp/test.ts` (though `dotenv` usage is up to the consumer).
186
17
 
187
- ---
18
+ ## Scripts
188
19
 
189
- ### `fb.page(pageId)`
20
+ | Command | Description |
21
+ | :--- | :--- |
22
+ | `npm run build` | Compiles the TypeScript source code to JavaScript ES2022 format inside the `dist/` directory. |
23
+ | `npm run dev` | Runs the scratchpad/test file located at `src/temp/test.ts` using `tsx`. Useful for local testing. |
24
+ | `npm run prepublishOnly` | Automatically runs `npm run build` prior to publishing the package to npm. |
190
25
 
191
- Operations scoped to a specific Page. Returns sub-resources for posts, videos, reels, images, and aggregated comments.
192
-
193
- ```typescript
194
- const page = fb.page("pageId");
195
- ```
196
-
197
- #### `page.posts.list(query)`
198
-
199
- List posts on a Page. Note: to fetch a specific post, use `fb.post(postId).get()`.
200
-
201
- ```typescript
202
- const feed = await page.posts.list({
203
- fields: { id: true, message: true, createdTime: true },
204
- });
205
- ```
206
-
207
- #### `page.comments.list(query, config)`
208
-
209
- Fetch an aggregated stream of comments across recent page posts.
210
-
211
- ```typescript
212
- const allComments = await page.comments.list({
213
- fields: { id: true, message: true, createdTime: true }
214
- });
215
- ```
216
-
217
- #### `page.videos.list(query)` / `page.videos.publish(data)`
218
-
219
- List videos or publish a new video.
220
-
221
- ```typescript
222
- const videos = await page.videos.list({
223
- fields: { id: true, title: true, status: true },
224
- });
225
-
226
- const { postId } = await page.videos.publish({
227
- fileUrl: "https://example.com/video.mp4",
228
- title: "My Video",
229
- description: "A description",
230
- thumbnailUrl: "https://example.com/thumb.jpg",
231
- });
232
- ```
233
-
234
- Publishing handles the upload, waits for processing via polling, and returns the resulting post ID. Throws `FacebookUploadError` on failure.
235
-
236
- #### `page.reels.list(query)` / `page.reels.publish(data)`
237
-
238
- List or publish reels. Publishing uses Facebook's resumable upload protocol (start session → upload file → finish session) and polls until the reel is processed.
239
-
240
- ```typescript
241
- const { postId } = await page.reels.publish({
242
- fileUrl: "https://example.com/reel.mp4",
243
- title: "My Reel",
244
- thumbnailUrl: "https://example.com/thumb.jpg",
245
- });
246
- ```
247
-
248
- #### `page.images.list(query)` / `page.images.publish(data)`
249
-
250
- List or publish images.
251
-
252
- ```typescript
253
- const { postId } = await page.images.publish({
254
- url: "https://example.com/image.jpg",
255
- caption: "My image",
256
- });
257
- ```
258
-
259
- ---
260
-
261
- ### `fb.comment(commentId)`
262
-
263
- Operations to manage a single comment node.
264
-
265
- ```typescript
266
- const myComment = fb.comment("commentId");
267
-
268
- // Update message
269
- await myComment.update({ message: "new message" });
270
-
271
- // Like / unlike
272
- await myComment.like();
273
- await myComment.unlike();
274
-
275
- // Delete
276
- await myComment.delete();
277
-
278
- // Get nested replies
279
- const subComments = await myComment.replies.list({ id: true, message: true });
280
- ```
281
-
282
- ## Adding New Endpoints
283
-
284
- To add a new resource or edge, follow this pattern:
285
-
286
- ### 1. Define the raw type
287
-
288
- Create or update a file in `src/types/`. Define the raw interface with snake_case keys matching the Facebook API response:
289
-
290
- ```typescript
291
- // src/types/facebookstory.ts
292
- import { KeysToCamel } from "../lib/transformCase.js";
293
-
294
- interface FacebookStoryRaw {
295
- id: string;
296
- created_time: string;
297
- media_url: string;
298
- }
299
- export type FacebookStory = KeysToCamel<FacebookStoryRaw>;
300
- ```
301
-
302
- ### 2. Define edge options (if needed)
303
-
304
- If the edge supports custom parameters beyond the base `limit`/`after`/`before`, extend `EdgeOptions` in `src/types/shared.ts`:
305
-
306
- ```typescript
307
- export interface StoryEdgeOptions extends EdgeOptions {
308
- since?: number;
309
- }
310
- ```
311
-
312
- ### 3. Use `CollectionOf` for edges with option-dependent fields
313
-
314
- If the edge's response includes extra fields only when certain options are passed, use `CollectionOf` with an intersection:
26
+ ## Quick Start
315
27
 
316
28
  ```typescript
317
- interface ParentRaw {
318
- stories: CollectionOf<FacebookStoryRaw, StoryEdgeOptions> & {
319
- extra_field: string; // only present when options are provided
320
- };
29
+ import { createFbSdk } from '@tabsircg/fb-sdk';
30
+
31
+ // 1. Initialize the SDK factory (optionally pass configuration like a Store)
32
+ const sdkFactory = createFbSdk();
33
+
34
+ // 2. Instantiate the client with a Page or User Access Token
35
+ const sdk = sdkFactory("EAAGYourAccessTokenHere...");
36
+
37
+ async function run() {
38
+ // Fetch a page's recent posts, selecting specific fields
39
+ const posts = await sdk.page("PAGE_ID").posts.list({
40
+ fields: {
41
+ id: true,
42
+ message: true,
43
+ createdTime: true
44
+ },
45
+ options: {
46
+ limit: 5
47
+ }
48
+ });
49
+
50
+ console.log("Recent posts:", posts.data);
51
+
52
+ // Example: Publish a new image
53
+ const publishTarget = await sdk.page("PAGE_ID").images.publish({
54
+ url: "https://example.com/image.png",
55
+ message: "Hello world!"
56
+ });
57
+
58
+ console.log("Published Post ID:", publishTarget.postId);
321
59
  }
322
- ```
323
-
324
- ### 4. Create the resource
325
-
326
- In `src/resources/`, create a factory function using `GetNode` and `ListEdge` types:
327
-
328
- ```typescript
329
- import { GetNode, ListEdge } from "../types/shared.js";
330
- import { FacebookStory } from "../types/facebookstory.js";
331
60
 
332
- export type ListStories = ListEdge<FacebookStory>;
333
- export type GetStory = GetNode<FacebookStory>;
334
-
335
- export const createStoryResource = (http: HttpClient, pageId: string) => {
336
- const list: ListStories = async (query) =>
337
- http.get(`/${pageId}/stories`, {
338
- params: { fields: toGraphFields(query.fields), ...query.options },
339
- });
340
-
341
- const get: GetStory = async (fields) =>
342
- http.get(`/${pageId}`, {
343
- params: { fields: toGraphFields(fields) },
344
- });
345
-
346
- return { list, get };
347
- };
61
+ run().catch(console.error);
348
62
  ```
349
63
 
350
- ### 5. Wire into the SDK
351
-
352
- Add the resource to the appropriate factory in `src/client.ts`:
353
-
354
- ```typescript
355
- export function fbGraph(accessToken: string) {
356
- const http = createHttpClient(accessToken);
357
- return {
358
- post: (postId: string) => createPostResource(http, postId),
359
- page: (pageId: string) => ({
360
- ...createPageResource(http, pageId),
361
- stories: createStoryResource(http, pageId),
362
- }),
363
- me: createUserResource(http),
364
- };
365
- }
366
- ```
367
-
368
- ## Type System Overview
369
-
370
- The SDK's type system follows a three-stage pipeline:
371
-
372
- ### 1. Selector generation (`FbFieldSelector<T>`)
373
-
374
- Given a resource type `T`, `FbFieldSelector<T>` generates the shape of a valid field selector object. Scalar fields become `true | undefined`. Nested objects become recursive selectors or `true`. Collection edges become `{ options?: O; fields: FbFieldSelector<Inner> } | true`, where `O` is the edge-specific options type extracted from the `CollectionOf` phantom type. Recursion depth is bounded by a `Decrement` counter (default depth: 1 level of nesting).
375
-
376
- ### 2. Strict validation (`DeepStrict<Valid, Inferred>`)
377
-
378
- TypeScript's structural type system doesn't reject excess properties when generics are involved. `DeepStrict` solves this by mapping every key in the inferred selector — if the key exists in the valid selector shape, it passes through; otherwise it becomes `never`, causing a compile error. This gives you red squiggles on typos and invalid fields.
64
+ ## Common Errors & Fixes
379
65
 
380
- ### 3. Return type narrowing (`FbPickDeep<T, F>`)
66
+ **FacebookUploadError**
67
+ - *Symptom:* The SDK throws an error during a video or reel upload, typically containing a `FacebookMedia["status"]` payload.
68
+ - *Fix:* This is an asynchronous processing error on Facebook's side. The SDK polls the status of uploads. Inspect the error message (extracted via `getProcessingError` in `poller.ts`) which might indicate unsupported codecs, file size limits exceeded, or temporary Facebook outages.
381
69
 
382
- `FbPickDeep<T, F>` walks the resource type `T` in parallel with your selector `F` and keeps only the fields you selected. For collections, it wraps the picked inner type in `{ data: Picked[]; paging: Paging }`. If the selector included `options`, option-dependent fields (defined via `& { ... }` on `CollectionOf`) are also included via `CleanCollection`.
70
+ **Batching Issues ("API Error code 2/3")**
71
+ - *Symptom:* `sdk.batch([ ...requests ])` fails with a confusing Graph API error.
72
+ - *Fix:* Ensure all requests inside the batch call were invoked without `await`. A `BatchableRequest` triggers a standard HTTP call if awaited, but returns `{ method, relative_url }` otherwise which the `batch` method leverages.
383
73
 
384
- The result is end-to-end type safety: autocomplete guides you to valid fields, the compiler rejects invalid ones, and the return type contains exactly what you asked for.
74
+ **Type errors on `fields` selector**
75
+ - *Symptom:* TypeScript complains when selecting nested fields like `comments: { ... }`.
76
+ - *Fix:* Verify that the nested property is defined as an object or `CollectionOf<T>` in the type definitions (`src/types/`). Ensure you use the exact camelCase keys for fields (e.g., `createdTime` instead of `created_time`).
package/dist/client.d.ts CHANGED
@@ -295,7 +295,7 @@ export declare function createFbSdk(config?: FbSdkConfig): (accessToken: string)
295
295
  endTime?: string;
296
296
  }[];
297
297
  };
298
- }, 1>>(query: import("./client.js").InsightQuery<{
298
+ }, 10>>(query: import("./client.js").InsightQuery<{
299
299
  postMediaView: {
300
300
  name: "post_media_view";
301
301
  values: {
@@ -1136,7 +1136,7 @@ export declare function createFbSdk(config?: FbSdkConfig): (accessToken: string)
1136
1136
  endTime?: string;
1137
1137
  }[];
1138
1138
  };
1139
- }, 1>>(query: import("./client.js").InsightQuery<{
1139
+ }, 10>>(query: import("./client.js").InsightQuery<{
1140
1140
  pageMediaView: {
1141
1141
  name: "page_media_view";
1142
1142
  values: {
@@ -1679,6 +1679,13 @@ export declare function createFbSdk(config?: FbSdkConfig): (accessToken: string)
1679
1679
  accounts: import("./resources/UserResource.js").ListAccounts;
1680
1680
  };
1681
1681
  http: HttpClient;
1682
+ batch: <const T extends readonly import("./client.js").BatchSubRequest[]>(requests: T, options?: import("./resources/createBatchResource.js").BatchRequestOptions) => Promise<{ -readonly [K in keyof T]: T[K] extends import("./client.js").BatchableRequest<infer R> ? {
1683
+ status: number;
1684
+ data: R;
1685
+ } : {
1686
+ status: number;
1687
+ data: any;
1688
+ }; }>;
1682
1689
  };
1683
1690
  export { createMemoryStore } from "./store/memory.js";
1684
1691
  export { createRedisStore } from "./store/redis.js";
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js CHANGED
@@ -3,6 +3,7 @@ import { createPostResource } from "./resources/PostResource.js";
3
3
  import { createPageResource } from "./resources/PageResource.js";
4
4
  import { createUserResource } from "./resources/UserResource.js";
5
5
  import { createCommentResource } from "./resources/comment/CommentResource.js";
6
+ import { createBatchResource } from "./resources/createBatchResource.js";
6
7
  export function createFbSdk(config = {}) {
7
8
  return (accessToken) => {
8
9
  const http = createHttpClient(accessToken);
@@ -12,6 +13,7 @@ export function createFbSdk(config = {}) {
12
13
  comment: (commentId) => createCommentResource({ http, id: commentId, config }),
13
14
  me: createUserResource({ http, config, id: "me" }),
14
15
  http,
16
+ batch: createBatchResource(http),
15
17
  };
16
18
  };
17
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAc,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AAa/E,MAAM,UAAU,WAAW,CAAC,SAAsB,EAAE;IAClD,OAAO,CAAC,WAAmB,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAC3C,OAAO;YACL,IAAI,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YAC1E,IAAI,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YAC1E,OAAO,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,qBAAqB,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;YACtF,EAAE,EAAE,kBAAkB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;YAClD,IAAI;SACL,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAc,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AAE/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAYzE,MAAM,UAAU,WAAW,CAAC,SAAsB,EAAE;IAClD,OAAO,CAAC,WAAmB,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAC3C,OAAO;YACL,IAAI,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YAC1E,IAAI,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YAC1E,OAAO,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,qBAAqB,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;YACtF,EAAE,EAAE,kBAAkB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;YAClD,IAAI;YACJ,KAAK,EAAE,mBAAmB,CAAC,IAAI,CAAC;SACjC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -1,8 +1,10 @@
1
1
  import { AxiosRequestConfig } from "axios";
2
+ import { KeysToCamel } from "./lib/transformCase.js";
2
3
  import FormData from "form-data";
4
+ import { BatchableRequest } from "./client.js";
3
5
  export declare const api: import("axios").AxiosInstance;
4
6
  interface HttpResponse<T> {
5
- data: T;
7
+ data: KeysToCamel<T>;
6
8
  status: number;
7
9
  }
8
10
  type Options = AxiosRequestConfig & {
@@ -13,12 +15,12 @@ type RawOptions = AxiosRequestConfig & {
13
15
  };
14
16
  type Data = FormData | Record<string, unknown> | null;
15
17
  export interface HttpClient {
16
- get<T>(path: string, options: RawOptions): Promise<HttpResponse<T>>;
17
- get<T>(path: string, options?: Options): Promise<T>;
18
- post<T>(path: string, data: Data, options: RawOptions): Promise<HttpResponse<T>>;
19
- post<T>(path: string, data: Data, options?: Options): Promise<T>;
20
- delete<T>(path: string, options: RawOptions): Promise<HttpResponse<T>>;
21
- delete<T>(path: string, options?: Options): Promise<T>;
18
+ get<T>(path: string, options: RawOptions): BatchableRequest<HttpResponse<T>>;
19
+ get<T>(path: string, options?: Options): BatchableRequest<T>;
20
+ post<T>(path: string, data: Data, options: RawOptions): BatchableRequest<HttpResponse<T>>;
21
+ post<T>(path: string, data: Data, options?: Options): BatchableRequest<T>;
22
+ delete<T>(path: string, options: RawOptions): BatchableRequest<HttpResponse<T>>;
23
+ delete<T>(path: string, options?: Options): BatchableRequest<T>;
22
24
  getToken(): string;
23
25
  }
24
26
  export declare function createHttpClient(accessToken: string): HttpClient;
@@ -1 +1 @@
1
- {"version":3,"file":"httpClient.d.ts","sourceRoot":"","sources":["../src/httpClient.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAElD,OAAO,QAAQ,MAAM,WAAW,CAAC;AAEjC,eAAO,MAAM,GAAG,+BAA8B,CAAC;AAO/C,UAAU,YAAY,CAAC,CAAC;IACtB,IAAI,EAAE,CAAC,CAAC;IACR,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,OAAO,GAAG,kBAAkB,GAAG;IAAE,IAAI,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AACrD,KAAK,UAAU,GAAG,kBAAkB,GAAG;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC;AACtD,KAAK,IAAI,GAAG,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;AAEtD,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAEpD,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IACjF,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAEjE,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAEvD,QAAQ,IAAI,MAAM,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CAgChE"}
1
+ {"version":3,"file":"httpClient.d.ts","sourceRoot":"","sources":["../src/httpClient.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,EAAE,WAAW,EAAuB,MAAM,wBAAwB,CAAC;AAC1E,OAAO,QAAQ,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,eAAO,MAAM,GAAG,+BAA8B,CAAC;AAO/C,UAAU,YAAY,CAAC,CAAC;IACtB,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,OAAO,GAAG,kBAAkB,GAAG;IAAE,IAAI,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AACrD,KAAK,UAAU,GAAG,kBAAkB,GAAG;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC;AACtD,KAAK,IAAI,GAAG,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;AAEtD,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7E,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAE7D,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,GAAG,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1F,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAE1E,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAEhE,QAAQ,IAAI,MAAM,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CAwChE"}
@@ -1,6 +1,7 @@
1
1
  import axios from "axios";
2
2
  import { toCamel, toSnakeObj } from "./lib/transformCase.js";
3
3
  import FormData from "form-data";
4
+ import { createBatchableRequest, buildRelativeUrl } from "./internal/batchable.js";
4
5
  export const api = axios.create({ family: 4 });
5
6
  const fbApi = axios.create({
6
7
  baseURL: "https://graph.facebook.com/v25.0",
@@ -9,29 +10,37 @@ const fbApi = axios.create({
9
10
  });
10
11
  export function createHttpClient(accessToken) {
11
12
  return {
12
- get: async (path, options) => {
13
- const res = await fbApi.get(path, {
14
- params: { access_token: accessToken, ...options?.params },
13
+ get: (path, options) => {
14
+ const params = options?.params ?? {};
15
+ return createBatchableRequest("GET", buildRelativeUrl(path, params), async () => {
16
+ const res = await fbApi.get(path, {
17
+ params: { access_token: accessToken, ...params },
18
+ });
19
+ const data = toCamel(res.data);
20
+ return options?.safe ? { data, status: res.status } : data;
15
21
  });
16
- const data = toCamel(res.data);
17
- return options?.safe ? { data, status: res.status } : data;
18
22
  },
19
- post: async (path, data, options) => {
20
- const isForm = data instanceof FormData;
21
- const res = await fbApi.post(path, isForm ? data : toSnakeObj(data), {
22
- headers: isForm ? data.getHeaders() : {},
23
- ...(options?.safe && { validateStatus: (s) => s === 200 || s === 504 }),
24
- params: { access_token: accessToken },
23
+ post: (path, data, options) => {
24
+ return createBatchableRequest("POST", buildRelativeUrl(path, {}), async () => {
25
+ const isForm = data instanceof FormData;
26
+ const res = await fbApi.post(path, isForm ? data : toSnakeObj(data), {
27
+ headers: isForm ? data.getHeaders() : {},
28
+ ...(options?.safe && { validateStatus: (s) => s === 200 || s === 504 }),
29
+ params: { access_token: accessToken },
30
+ });
31
+ const body = toCamel(res.data);
32
+ return options?.safe ? { data: body, status: res.status } : body;
25
33
  });
26
- const body = toCamel(res.data);
27
- return options?.safe ? { data: body, status: res.status } : body;
28
34
  },
29
- delete: async (path, options) => {
30
- const res = await fbApi.delete(path, {
31
- params: { access_token: accessToken, ...options?.params },
35
+ delete: (path, options) => {
36
+ const params = options?.params ?? {};
37
+ return createBatchableRequest("DELETE", buildRelativeUrl(path, params), async () => {
38
+ const res = await fbApi.delete(path, {
39
+ params: { access_token: accessToken, ...params },
40
+ });
41
+ const data = toCamel(res.data);
42
+ return options?.safe ? { data, status: res.status } : data;
32
43
  });
33
- const data = toCamel(res.data);
34
- return options?.safe ? { data, status: res.status } : data;
35
44
  },
36
45
  getToken: () => accessToken,
37
46
  };
@@ -1 +1 @@
1
- {"version":3,"file":"httpClient.js","sourceRoot":"","sources":["../src/httpClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAA6B,MAAM,OAAO,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,QAAQ,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;AAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;IACzB,OAAO,EAAE,kCAAkC;IAC3C,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,EAAE,iBAAiB,EAAE,mBAAmB,EAAE;CACpD,CAAC,CAAC;AAwBH,MAAM,UAAU,gBAAgB,CAAC,WAAmB;IAClD,OAAO;QACL,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;YAC3B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE;gBAChC,MAAM,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE;aAC1D,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC/B,OAAO,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7D,CAAC;QAED,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;YAClC,MAAM,MAAM,GAAG,IAAI,YAAY,QAAQ,CAAC;YACxC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;gBACnE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE;gBACxC,GAAG,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,cAAc,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;gBAC/E,MAAM,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE;aACtC,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAE/B,OAAO,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACnE,CAAC;QAED,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;YAC9B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE;gBACnC,MAAM,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE;aAC1D,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC/B,OAAO,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7D,CAAC;QAED,QAAQ,EAAE,GAAG,EAAE,CAAC,WAAW;KAC5B,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"httpClient.js","sourceRoot":"","sources":["../src/httpClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAA6B,MAAM,OAAO,CAAC;AAClD,OAAO,EAAe,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,QAAQ,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGnF,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;AAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;IACzB,OAAO,EAAE,kCAAkC;IAC3C,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,EAAE,iBAAiB,EAAE,mBAAmB,EAAE;CACpD,CAAC,CAAC;AAwBH,MAAM,UAAU,gBAAgB,CAAC,WAAmB;IAClD,OAAO;QACL,GAAG,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;YACrB,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,EAAE,CAAC;YACrC,OAAO,sBAAsB,CAAC,KAAK,EAAE,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,KAAK,IAAI,EAAE;gBAC9E,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE;oBAChC,MAAM,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE;iBACjD,CAAC,CAAC;gBACH,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC/B,OAAO,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YAC7D,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;YAC5B,OAAO,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,KAAK,IAAI,EAAE;gBAC3E,MAAM,MAAM,GAAG,IAAI,YAAY,QAAQ,CAAC;gBACxC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;oBACnE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE;oBACxC,GAAG,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,cAAc,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;oBAC/E,MAAM,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE;iBACtC,CAAC,CAAC;gBACH,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAE/B,OAAO,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACnE,CAAC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;YACxB,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,EAAE,CAAC;YACrC,OAAO,sBAAsB,CAAC,QAAQ,EAAE,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,KAAK,IAAI,EAAE;gBACjF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE;oBACnC,MAAM,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE;iBACjD,CAAC,CAAC;gBACH,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC/B,OAAO,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YAC7D,CAAC,CAAC,CAAC;QACL,CAAC;QAED,QAAQ,EAAE,GAAG,EAAE,CAAC,WAAW;KAC5B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { BatchableRequest } from "../client.js";
2
+ export declare function createBatchableRequest<T>(method: string, relativeUrl: string, executor: () => Promise<T>): BatchableRequest<T>;
3
+ export declare function buildRelativeUrl(path: string, params: Record<string, unknown>): string;
4
+ //# sourceMappingURL=batchable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batchable.d.ts","sourceRoot":"","sources":["../../src/internal/batchable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGhD,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACzB,gBAAgB,CAAC,CAAC,CAAC,CAWrB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAUtF"}