naystack 1.8.12 → 1.8.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +189 -31
  2. package/dist/auth/index.cjs.js +158 -18
  3. package/dist/auth/index.d.mts +3 -1
  4. package/dist/auth/index.d.ts +3 -1
  5. package/dist/auth/index.esm.js +158 -18
  6. package/dist/auth/instagram/index.cjs.js +158 -18
  7. package/dist/auth/instagram/index.d.mts +6 -1
  8. package/dist/auth/instagram/index.d.ts +6 -1
  9. package/dist/auth/instagram/index.esm.js +158 -18
  10. package/dist/auth/instagram/route.cjs.js +158 -18
  11. package/dist/auth/instagram/route.d.mts +3 -1
  12. package/dist/auth/instagram/route.d.ts +3 -1
  13. package/dist/auth/instagram/route.esm.js +158 -18
  14. package/dist/auth/instagram/utils.cjs.js +2 -2
  15. package/dist/auth/instagram/utils.d.mts +13 -2
  16. package/dist/auth/instagram/utils.d.ts +13 -2
  17. package/dist/auth/instagram/utils.esm.js +2 -2
  18. package/dist/file/setup.d.mts +13 -5
  19. package/dist/file/setup.d.ts +13 -5
  20. package/dist/index.d.mts +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/socials/index.cjs.js +298 -72
  23. package/dist/socials/index.d.mts +6 -4
  24. package/dist/socials/index.d.ts +6 -4
  25. package/dist/socials/index.esm.js +296 -72
  26. package/dist/socials/instagram/getters.cjs.js +76 -25
  27. package/dist/socials/instagram/getters.d.mts +56 -6
  28. package/dist/socials/instagram/getters.d.ts +56 -6
  29. package/dist/socials/instagram/getters.esm.js +74 -25
  30. package/dist/socials/instagram/setters.cjs.js +192 -14
  31. package/dist/socials/instagram/setters.d.mts +43 -3
  32. package/dist/socials/instagram/setters.d.ts +43 -3
  33. package/dist/socials/instagram/setters.esm.js +191 -14
  34. package/dist/socials/instagram/types.d.mts +48 -11
  35. package/dist/socials/instagram/types.d.ts +48 -11
  36. package/dist/socials/instagram/utils.cjs.js +28 -15
  37. package/dist/socials/instagram/utils.d.mts +7 -18
  38. package/dist/socials/instagram/utils.d.ts +7 -18
  39. package/dist/socials/instagram/utils.esm.js +26 -14
  40. package/dist/socials/instagram/webhook.cjs.js +1 -1
  41. package/dist/socials/instagram/webhook.esm.js +1 -1
  42. package/dist/socials/meta/container.cjs.js +82 -0
  43. package/dist/socials/meta/container.d.mts +38 -0
  44. package/dist/socials/meta/container.d.ts +38 -0
  45. package/dist/socials/meta/container.esm.js +57 -0
  46. package/dist/socials/meta/request.cjs.js +60 -0
  47. package/dist/socials/meta/request.d.mts +50 -0
  48. package/dist/socials/meta/request.d.ts +50 -0
  49. package/dist/socials/meta/request.esm.js +34 -0
  50. package/dist/socials/meta/types.cjs.js +34 -0
  51. package/dist/socials/meta/types.d.mts +51 -0
  52. package/dist/socials/meta/types.d.ts +51 -0
  53. package/dist/socials/meta/types.esm.js +9 -0
  54. package/dist/socials/{meta-webhook.cjs.js → meta/webhook.cjs.js} +4 -4
  55. package/dist/socials/{meta-webhook.esm.js → meta/webhook.esm.js} +1 -1
  56. package/dist/socials/threads/getters.cjs.js +36 -11
  57. package/dist/socials/threads/getters.d.mts +23 -2
  58. package/dist/socials/threads/getters.d.ts +23 -2
  59. package/dist/socials/threads/getters.esm.js +35 -11
  60. package/dist/socials/threads/setters.cjs.js +150 -44
  61. package/dist/socials/threads/setters.d.mts +25 -34
  62. package/dist/socials/threads/setters.d.ts +25 -34
  63. package/dist/socials/threads/setters.esm.js +149 -41
  64. package/dist/socials/threads/types.d.mts +40 -1
  65. package/dist/socials/threads/types.d.ts +40 -1
  66. package/dist/socials/threads/utils.cjs.js +29 -11
  67. package/dist/socials/threads/utils.d.mts +8 -17
  68. package/dist/socials/threads/utils.d.ts +8 -17
  69. package/dist/socials/threads/utils.esm.js +27 -10
  70. package/dist/socials/threads/webhook.cjs.js +1 -1
  71. package/dist/socials/threads/webhook.esm.js +1 -1
  72. package/package.json +1 -1
  73. /package/dist/socials/{meta-webhook.d.mts → meta/webhook.d.mts} +0 -0
  74. /package/dist/socials/{meta-webhook.d.ts → meta/webhook.d.ts} +0 -0
@@ -0,0 +1,38 @@
1
+ import { GraphParams, ContainerState } from './types.js';
2
+
3
+ /**
4
+ * Polling settings for a media container.
5
+ *
6
+ * @property intervalMS - Delay between status checks. Default: `5000`.
7
+ * @property timeoutMS - Give up after this long. Default: `300000` (Meta stops processing after ~5 min).
8
+ *
9
+ * @category Socials
10
+ */
11
+ type WaitForContainerOptions = {
12
+ intervalMS?: number;
13
+ timeoutMS?: number;
14
+ };
15
+ /**
16
+ * Wires up the create → wait → publish flow Meta platforms share. Instagram and
17
+ * Threads differ only in their endpoints, so each builds one publisher and every
18
+ * post shape goes through it.
19
+ *
20
+ * @param platform.name - Used in error logs, e.g. `"Instagram"`.
21
+ * @param platform.createContainer - Creates a container, resolving to its id.
22
+ * @param platform.getStatus - Reads a container's state by id.
23
+ * @param platform.publish - Publishes a finished container, resolving to the post id.
24
+ * @returns `{ publish, createChildren }`.
25
+ */
26
+ declare function createPublisher(platform: {
27
+ name: string;
28
+ createContainer: (token: string, params: GraphParams) => Promise<string | null>;
29
+ getStatus: (token: string, id: string) => Promise<ContainerState | null>;
30
+ publish: (token: string, creationID: string) => Promise<string | null>;
31
+ }): {
32
+ /** Creates a container, waits for it to finish processing, then publishes it. */
33
+ publish: (token: string, params: GraphParams, wait?: WaitForContainerOptions) => Promise<string | null>;
34
+ /** Creates and awaits every carousel child, resolving to their ids — or `null` if any failed. */
35
+ createChildren: (token: string, items: GraphParams[], wait?: WaitForContainerOptions) => Promise<string[] | null>;
36
+ };
37
+
38
+ export { type WaitForContainerOptions, createPublisher };
@@ -0,0 +1,57 @@
1
+ // src/socials/meta/container.ts
2
+ var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
3
+ async function waitForContainer(getState, { intervalMS = 5e3, timeoutMS = 3e5 } = {}) {
4
+ const deadline = Date.now() + timeoutMS;
5
+ let state = await getState();
6
+ if (!state) {
7
+ await sleep(2e3);
8
+ return null;
9
+ }
10
+ while (state?.status === "IN_PROGRESS" && Date.now() < deadline) {
11
+ await sleep(intervalMS);
12
+ state = await getState();
13
+ }
14
+ return state;
15
+ }
16
+ function createPublisher(platform) {
17
+ const isReady = async (token, id, label, wait) => {
18
+ const state = await waitForContainer(
19
+ () => platform.getStatus(token, id),
20
+ wait
21
+ );
22
+ if (state && state.status !== "FINISHED" && state.status !== "PUBLISHED") {
23
+ console.error(
24
+ `[naystack] ${platform.name} ${label} ${id} is ${state.status}${state.error ? `: ${state.error}` : ""}`
25
+ );
26
+ return false;
27
+ }
28
+ return true;
29
+ };
30
+ return {
31
+ /** Creates a container, waits for it to finish processing, then publishes it. */
32
+ publish: async (token, params, wait) => {
33
+ const containerID = await platform.createContainer(token, params);
34
+ if (!containerID) return null;
35
+ if (!await isReady(token, containerID, "container", wait)) return null;
36
+ return platform.publish(token, containerID);
37
+ },
38
+ /** Creates and awaits every carousel child, resolving to their ids — or `null` if any failed. */
39
+ createChildren: async (token, items, wait) => {
40
+ const children = [];
41
+ for (const item of items) {
42
+ const childID = await platform.createContainer(token, {
43
+ ...item,
44
+ is_carousel_item: true
45
+ });
46
+ if (!childID) return null;
47
+ if (!await isReady(token, childID, "carousel item", wait))
48
+ return null;
49
+ children.push(childID);
50
+ }
51
+ return children;
52
+ }
53
+ };
54
+ }
55
+ export {
56
+ createPublisher
57
+ };
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/socials/meta/request.ts
21
+ var request_exports = {};
22
+ __export(request_exports, {
23
+ createGraphClient: () => createGraphClient,
24
+ readGraphID: () => readGraphID
25
+ });
26
+ module.exports = __toCommonJS(request_exports);
27
+ function createGraphClient(baseURL) {
28
+ const buildURL = (token, path, params = {}) => {
29
+ const search = new URLSearchParams();
30
+ for (const [key, value] of Object.entries(params)) {
31
+ if (value !== void 0) search.set(key, String(value));
32
+ }
33
+ search.set("access_token", token);
34
+ return `${baseURL}/${path}?${search.toString()}`;
35
+ };
36
+ const request = async (token, path, options = {}) => {
37
+ const response = await fetch(buildURL(token, path, options.params), {
38
+ method: options.method || (options.body ? "POST" : "GET"),
39
+ headers: {
40
+ Authorization: `Bearer ${token}`,
41
+ ...options.body ? { "Content-Type": "application/json" } : {}
42
+ },
43
+ ...options.body ? { body: JSON.stringify(options.body) } : {}
44
+ });
45
+ return response.json().catch(() => null);
46
+ };
47
+ return { buildURL, request };
48
+ }
49
+ function readGraphID(label, result) {
50
+ if (result?.error) {
51
+ console.error(`[naystack] ${label} failed: ${result.error.message}`);
52
+ return null;
53
+ }
54
+ return result?.id || null;
55
+ }
56
+ // Annotate the CommonJS export names for ESM import in node:
57
+ 0 && (module.exports = {
58
+ createGraphClient,
59
+ readGraphID
60
+ });
@@ -0,0 +1,50 @@
1
+ import { GraphParams, GraphError } from './types.mjs';
2
+
3
+ /**
4
+ * Options for a single Graph API request.
5
+ *
6
+ * @property params - Query parameters. Most Graph mutations take their arguments here, not in a body.
7
+ * @property method - Defaults to `"POST"` when `body` is set, `"GET"` otherwise.
8
+ * @property body - JSON body, for the few endpoints that need one (e.g. Instagram messaging).
9
+ *
10
+ * @category Socials
11
+ */
12
+ type GraphRequestOptions = {
13
+ params?: GraphParams;
14
+ method?: "GET" | "POST";
15
+ body?: object;
16
+ };
17
+ /**
18
+ * A Graph API client bound to one platform's base URL.
19
+ *
20
+ * @category Socials
21
+ */
22
+ type GraphClient = {
23
+ buildURL: (token: string, path: string, params?: GraphParams) => string;
24
+ request: <T>(token: string, path: string, options?: GraphRequestOptions) => Promise<(T & GraphError) | null>;
25
+ };
26
+ /**
27
+ * Creates a Graph API client for a base URL (Instagram, Threads — same protocol,
28
+ * different host and version).
29
+ *
30
+ * Every param is URL-encoded, so captions may contain spaces, `&`, `#` and newlines.
31
+ *
32
+ * @param baseURL - Versioned API root, e.g. `"https://graph.instagram.com/v23.0"`.
33
+ * @returns `{ buildURL, request }`.
34
+ * @category Socials
35
+ */
36
+ declare function createGraphClient(baseURL: string): GraphClient;
37
+ /**
38
+ * Unwraps the `id` from a Graph API response, logging the API's own message
39
+ * when the call failed. Keeps publishing helpers to a single `null` return.
40
+ *
41
+ * @param label - Name used in the error log, e.g. `"Instagram media container"`.
42
+ * @param result - Raw Graph API response.
43
+ * @returns The id, or `null` on error.
44
+ * @category Socials
45
+ */
46
+ declare function readGraphID(label: string, result: ({
47
+ id?: string;
48
+ } & GraphError) | null): string | null;
49
+
50
+ export { type GraphClient, type GraphRequestOptions, createGraphClient, readGraphID };
@@ -0,0 +1,50 @@
1
+ import { GraphParams, GraphError } from './types.js';
2
+
3
+ /**
4
+ * Options for a single Graph API request.
5
+ *
6
+ * @property params - Query parameters. Most Graph mutations take their arguments here, not in a body.
7
+ * @property method - Defaults to `"POST"` when `body` is set, `"GET"` otherwise.
8
+ * @property body - JSON body, for the few endpoints that need one (e.g. Instagram messaging).
9
+ *
10
+ * @category Socials
11
+ */
12
+ type GraphRequestOptions = {
13
+ params?: GraphParams;
14
+ method?: "GET" | "POST";
15
+ body?: object;
16
+ };
17
+ /**
18
+ * A Graph API client bound to one platform's base URL.
19
+ *
20
+ * @category Socials
21
+ */
22
+ type GraphClient = {
23
+ buildURL: (token: string, path: string, params?: GraphParams) => string;
24
+ request: <T>(token: string, path: string, options?: GraphRequestOptions) => Promise<(T & GraphError) | null>;
25
+ };
26
+ /**
27
+ * Creates a Graph API client for a base URL (Instagram, Threads — same protocol,
28
+ * different host and version).
29
+ *
30
+ * Every param is URL-encoded, so captions may contain spaces, `&`, `#` and newlines.
31
+ *
32
+ * @param baseURL - Versioned API root, e.g. `"https://graph.instagram.com/v23.0"`.
33
+ * @returns `{ buildURL, request }`.
34
+ * @category Socials
35
+ */
36
+ declare function createGraphClient(baseURL: string): GraphClient;
37
+ /**
38
+ * Unwraps the `id` from a Graph API response, logging the API's own message
39
+ * when the call failed. Keeps publishing helpers to a single `null` return.
40
+ *
41
+ * @param label - Name used in the error log, e.g. `"Instagram media container"`.
42
+ * @param result - Raw Graph API response.
43
+ * @returns The id, or `null` on error.
44
+ * @category Socials
45
+ */
46
+ declare function readGraphID(label: string, result: ({
47
+ id?: string;
48
+ } & GraphError) | null): string | null;
49
+
50
+ export { type GraphClient, type GraphRequestOptions, createGraphClient, readGraphID };
@@ -0,0 +1,34 @@
1
+ // src/socials/meta/request.ts
2
+ function createGraphClient(baseURL) {
3
+ const buildURL = (token, path, params = {}) => {
4
+ const search = new URLSearchParams();
5
+ for (const [key, value] of Object.entries(params)) {
6
+ if (value !== void 0) search.set(key, String(value));
7
+ }
8
+ search.set("access_token", token);
9
+ return `${baseURL}/${path}?${search.toString()}`;
10
+ };
11
+ const request = async (token, path, options = {}) => {
12
+ const response = await fetch(buildURL(token, path, options.params), {
13
+ method: options.method || (options.body ? "POST" : "GET"),
14
+ headers: {
15
+ Authorization: `Bearer ${token}`,
16
+ ...options.body ? { "Content-Type": "application/json" } : {}
17
+ },
18
+ ...options.body ? { body: JSON.stringify(options.body) } : {}
19
+ });
20
+ return response.json().catch(() => null);
21
+ };
22
+ return { buildURL, request };
23
+ }
24
+ function readGraphID(label, result) {
25
+ if (result?.error) {
26
+ console.error(`[naystack] ${label} failed: ${result.error.message}`);
27
+ return null;
28
+ }
29
+ return result?.id || null;
30
+ }
31
+ export {
32
+ createGraphClient,
33
+ readGraphID
34
+ };
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/socials/meta/types.ts
21
+ var types_exports = {};
22
+ __export(types_exports, {
23
+ MetaMediaType: () => MetaMediaType
24
+ });
25
+ module.exports = __toCommonJS(types_exports);
26
+ var MetaMediaType = /* @__PURE__ */ ((MetaMediaType2) => {
27
+ MetaMediaType2["Photo"] = "photo";
28
+ MetaMediaType2["Video"] = "video";
29
+ return MetaMediaType2;
30
+ })(MetaMediaType || {});
31
+ // Annotate the CommonJS export names for ESM import in node:
32
+ 0 && (module.exports = {
33
+ MetaMediaType
34
+ });
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Types for Meta's Graph protocol — the request/response shape Instagram and
3
+ * Threads share. Platforms outside Meta don't use these.
4
+ *
5
+ * @module
6
+ */
7
+ /**
8
+ * Query parameters for a Graph API request. Values are stringified and URL-encoded;
9
+ * `undefined` entries are dropped, so optional params can be passed inline.
10
+ *
11
+ * @category Socials
12
+ */
13
+ type GraphParams = Record<string, string | number | boolean | undefined>;
14
+ /**
15
+ * Meta Graph API error response shape (Instagram, Threads).
16
+ *
17
+ * @property error - Error details from the API (message, type, code, subcode, trace id).
18
+ *
19
+ * @category Socials
20
+ */
21
+ type GraphError = {
22
+ error?: {
23
+ message: string;
24
+ type: string;
25
+ code: number;
26
+ error_subcode: number;
27
+ fbtrace_id: string;
28
+ };
29
+ };
30
+ /**
31
+ * Processing status of a media container, before it can be published.
32
+ * Shared vocabulary across Instagram (`status_code`) and Threads (`status`).
33
+ *
34
+ * @category Socials
35
+ */
36
+ type ContainerStatus = "EXPIRED" | "ERROR" | "FINISHED" | "IN_PROGRESS" | "PUBLISHED";
37
+ /**
38
+ * A container's processing status plus the API's reason when it failed.
39
+ *
40
+ * @category Socials
41
+ */
42
+ type ContainerState = {
43
+ status: ContainerStatus;
44
+ error?: string;
45
+ };
46
+ declare enum MetaMediaType {
47
+ Photo = "photo",
48
+ Video = "video"
49
+ }
50
+
51
+ export { type ContainerState, type ContainerStatus, type GraphError, type GraphParams, MetaMediaType };
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Types for Meta's Graph protocol — the request/response shape Instagram and
3
+ * Threads share. Platforms outside Meta don't use these.
4
+ *
5
+ * @module
6
+ */
7
+ /**
8
+ * Query parameters for a Graph API request. Values are stringified and URL-encoded;
9
+ * `undefined` entries are dropped, so optional params can be passed inline.
10
+ *
11
+ * @category Socials
12
+ */
13
+ type GraphParams = Record<string, string | number | boolean | undefined>;
14
+ /**
15
+ * Meta Graph API error response shape (Instagram, Threads).
16
+ *
17
+ * @property error - Error details from the API (message, type, code, subcode, trace id).
18
+ *
19
+ * @category Socials
20
+ */
21
+ type GraphError = {
22
+ error?: {
23
+ message: string;
24
+ type: string;
25
+ code: number;
26
+ error_subcode: number;
27
+ fbtrace_id: string;
28
+ };
29
+ };
30
+ /**
31
+ * Processing status of a media container, before it can be published.
32
+ * Shared vocabulary across Instagram (`status_code`) and Threads (`status`).
33
+ *
34
+ * @category Socials
35
+ */
36
+ type ContainerStatus = "EXPIRED" | "ERROR" | "FINISHED" | "IN_PROGRESS" | "PUBLISHED";
37
+ /**
38
+ * A container's processing status plus the API's reason when it failed.
39
+ *
40
+ * @category Socials
41
+ */
42
+ type ContainerState = {
43
+ status: ContainerStatus;
44
+ error?: string;
45
+ };
46
+ declare enum MetaMediaType {
47
+ Photo = "photo",
48
+ Video = "video"
49
+ }
50
+
51
+ export { type ContainerState, type ContainerStatus, type GraphError, type GraphParams, MetaMediaType };
@@ -0,0 +1,9 @@
1
+ // src/socials/meta/types.ts
2
+ var MetaMediaType = /* @__PURE__ */ ((MetaMediaType2) => {
3
+ MetaMediaType2["Photo"] = "photo";
4
+ MetaMediaType2["Video"] = "video";
5
+ return MetaMediaType2;
6
+ })(MetaMediaType || {});
7
+ export {
8
+ MetaMediaType
9
+ };
@@ -17,12 +17,12 @@ var __copyProps = (to, from, except, desc) => {
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
 
20
- // src/socials/meta-webhook.ts
21
- var meta_webhook_exports = {};
22
- __export(meta_webhook_exports, {
20
+ // src/socials/meta/webhook.ts
21
+ var webhook_exports = {};
22
+ __export(webhook_exports, {
23
23
  verifyWebhook: () => verifyWebhook
24
24
  });
25
- module.exports = __toCommonJS(meta_webhook_exports);
25
+ module.exports = __toCommonJS(webhook_exports);
26
26
  var import_server = require("next/server");
27
27
  var verifyWebhook = (secret) => (req) => {
28
28
  const params = req.nextUrl.searchParams;
@@ -1,4 +1,4 @@
1
- // src/socials/meta-webhook.ts
1
+ // src/socials/meta/webhook.ts
2
2
  import { NextResponse } from "next/server";
3
3
  var verifyWebhook = (secret) => (req) => {
4
4
  const params = req.nextUrl.searchParams;
@@ -22,39 +22,64 @@ var getters_exports = {};
22
22
  __export(getters_exports, {
23
23
  getThread: () => getThread,
24
24
  getThreads: () => getThreads,
25
+ getThreadsContainerStatus: () => getThreadsContainerStatus,
25
26
  getThreadsReplies: () => getThreadsReplies
26
27
  });
27
28
  module.exports = __toCommonJS(getters_exports);
28
29
 
29
- // src/socials/threads/utils.ts
30
- function getThreadsURL(token, path, params) {
31
- return `https://graph.threads.net/v1.0/${path}?${Object.keys(params).map((key) => `${key}=${params[key]}`).join("&")}&access_token=${token}`;
32
- }
33
- function getThreadsData(token, path, params, method) {
34
- return fetch(getThreadsURL(token, path, params), {
35
- method: method || "GET"
36
- }).then((res) => res.json());
30
+ // src/socials/meta/request.ts
31
+ function createGraphClient(baseURL) {
32
+ const buildURL = (token, path, params = {}) => {
33
+ const search = new URLSearchParams();
34
+ for (const [key, value] of Object.entries(params)) {
35
+ if (value !== void 0) search.set(key, String(value));
36
+ }
37
+ search.set("access_token", token);
38
+ return `${baseURL}/${path}?${search.toString()}`;
39
+ };
40
+ const request = async (token, path, options = {}) => {
41
+ const response = await fetch(buildURL(token, path, options.params), {
42
+ method: options.method || (options.body ? "POST" : "GET"),
43
+ headers: {
44
+ Authorization: `Bearer ${token}`,
45
+ ...options.body ? { "Content-Type": "application/json" } : {}
46
+ },
47
+ ...options.body ? { body: JSON.stringify(options.body) } : {}
48
+ });
49
+ return response.json().catch(() => null);
50
+ };
51
+ return { buildURL, request };
37
52
  }
38
53
 
54
+ // src/socials/threads/utils.ts
55
+ var client = createGraphClient("https://graph.threads.net/v1.0");
56
+ var getThreadsData = client.request;
57
+
39
58
  // src/socials/threads/getters.ts
40
59
  var getThread = (token, id, fields) => {
41
60
  return getThreadsData(token, id, {
42
- fields: fields ? fields.join(",") : "text,permalink,username"
61
+ params: { fields: fields ? fields.join(",") : "text,permalink,username" }
43
62
  });
44
63
  };
45
64
  var getThreads = (token, fields) => {
46
65
  return getThreadsData(token, "me/threads", {
47
- fields: fields ? fields.join(",") : "text,permalink,username"
66
+ params: { fields: fields ? fields.join(",") : "text,permalink,username" }
48
67
  }).then((res) => res?.data);
49
68
  };
50
69
  var getThreadsReplies = (token, id, fields) => {
51
70
  return getThreadsData(token, `${id}/replies`, {
52
- fields: fields ? fields.join(",") : "text,username,permalink"
71
+ params: { fields: fields ? fields.join(",") : "text,username,permalink" }
53
72
  }).then((res) => res?.data);
54
73
  };
74
+ var getThreadsContainerStatus = async (token, id) => {
75
+ const result = await getThreadsData(token, id, { params: { fields: "status,error_message" } });
76
+ if (!result?.status) return null;
77
+ return { status: result.status, error: result.error_message };
78
+ };
55
79
  // Annotate the CommonJS export names for ESM import in node:
56
80
  0 && (module.exports = {
57
81
  getThread,
58
82
  getThreads,
83
+ getThreadsContainerStatus,
59
84
  getThreadsReplies
60
85
  });
@@ -1,4 +1,6 @@
1
+ import { GraphError, ContainerState } from '../meta/types.mjs';
1
2
  import { ThreadsPost } from './types.mjs';
3
+ import '../meta/container.mjs';
2
4
 
3
5
  /**
4
6
  * Fetches a single Threads post by id.
@@ -18,7 +20,7 @@ import { ThreadsPost } from './types.mjs';
18
20
  *
19
21
  * @category Socials
20
22
  */
21
- declare const getThread: <T = ThreadsPost>(token: string, id: string, fields?: string[]) => Promise<T | null>;
23
+ declare const getThread: <T = ThreadsPost>(token: string, id: string, fields?: string[]) => Promise<(T & GraphError) | null>;
22
24
  /**
23
25
  * Fetches the authenticated user's Threads posts.
24
26
  *
@@ -60,5 +62,24 @@ declare const getThreads: <T = ThreadsPost>(token: string, fields?: string[]) =>
60
62
  * @category Socials
61
63
  */
62
64
  declare const getThreadsReplies: <T = ThreadsPost>(token: string, id: string, fields?: string[]) => Promise<T[] | undefined>;
65
+ /**
66
+ * Reads a media container's processing status. Image, video and carousel
67
+ * containers must reach `FINISHED` before they can be published.
68
+ *
69
+ * @param token - Threads access token.
70
+ * @param id - Container id from `createThreadsContainer`.
71
+ * @returns Promise of `{ status, error? }`, or `null` if the status was unreadable.
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * import { getThreadsContainerStatus } from "naystack/socials";
76
+ *
77
+ * const state = await getThreadsContainerStatus(accessToken, containerId);
78
+ * if (state?.status === "FINISHED") await publishThreadsContainer(accessToken, containerId);
79
+ * ```
80
+ *
81
+ * @category Socials
82
+ */
83
+ declare const getThreadsContainerStatus: (token: string, id: string) => Promise<ContainerState | null>;
63
84
 
64
- export { getThread, getThreads, getThreadsReplies };
85
+ export { getThread, getThreads, getThreadsContainerStatus, getThreadsReplies };
@@ -1,4 +1,6 @@
1
+ import { GraphError, ContainerState } from '../meta/types.js';
1
2
  import { ThreadsPost } from './types.js';
3
+ import '../meta/container.js';
2
4
 
3
5
  /**
4
6
  * Fetches a single Threads post by id.
@@ -18,7 +20,7 @@ import { ThreadsPost } from './types.js';
18
20
  *
19
21
  * @category Socials
20
22
  */
21
- declare const getThread: <T = ThreadsPost>(token: string, id: string, fields?: string[]) => Promise<T | null>;
23
+ declare const getThread: <T = ThreadsPost>(token: string, id: string, fields?: string[]) => Promise<(T & GraphError) | null>;
22
24
  /**
23
25
  * Fetches the authenticated user's Threads posts.
24
26
  *
@@ -60,5 +62,24 @@ declare const getThreads: <T = ThreadsPost>(token: string, fields?: string[]) =>
60
62
  * @category Socials
61
63
  */
62
64
  declare const getThreadsReplies: <T = ThreadsPost>(token: string, id: string, fields?: string[]) => Promise<T[] | undefined>;
65
+ /**
66
+ * Reads a media container's processing status. Image, video and carousel
67
+ * containers must reach `FINISHED` before they can be published.
68
+ *
69
+ * @param token - Threads access token.
70
+ * @param id - Container id from `createThreadsContainer`.
71
+ * @returns Promise of `{ status, error? }`, or `null` if the status was unreadable.
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * import { getThreadsContainerStatus } from "naystack/socials";
76
+ *
77
+ * const state = await getThreadsContainerStatus(accessToken, containerId);
78
+ * if (state?.status === "FINISHED") await publishThreadsContainer(accessToken, containerId);
79
+ * ```
80
+ *
81
+ * @category Socials
82
+ */
83
+ declare const getThreadsContainerStatus: (token: string, id: string) => Promise<ContainerState | null>;
63
84
 
64
- export { getThread, getThreads, getThreadsReplies };
85
+ export { getThread, getThreads, getThreadsContainerStatus, getThreadsReplies };