naystack 1.8.19 → 1.9.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 (122) hide show
  1. package/README.md +94 -34
  2. package/dist/auth/client.cjs.js +2 -2
  3. package/dist/auth/client.esm.js +2 -2
  4. package/dist/auth/email/client.cjs.js +2 -2
  5. package/dist/auth/email/client.esm.js +2 -2
  6. package/dist/auth/email/index.cjs.js +2 -2
  7. package/dist/auth/email/index.esm.js +2 -2
  8. package/dist/auth/email/next.cjs.js +2 -2
  9. package/dist/auth/email/next.esm.js +2 -2
  10. package/dist/auth/email/routes/delete.cjs.js +2 -2
  11. package/dist/auth/email/routes/delete.esm.js +2 -2
  12. package/dist/auth/email/routes/get.cjs.js +2 -2
  13. package/dist/auth/email/routes/get.esm.js +2 -2
  14. package/dist/auth/email/routes/post.cjs.js +2 -2
  15. package/dist/auth/email/routes/post.esm.js +2 -2
  16. package/dist/auth/email/routes/put.cjs.js +2 -2
  17. package/dist/auth/email/routes/put.esm.js +2 -2
  18. package/dist/auth/email/token.cjs.js +2 -2
  19. package/dist/auth/email/token.esm.js +2 -2
  20. package/dist/auth/email/utils.cjs.js +2 -2
  21. package/dist/auth/email/utils.esm.js +2 -2
  22. package/dist/auth/google/get.cjs.js +2 -2
  23. package/dist/auth/google/get.esm.js +2 -2
  24. package/dist/auth/google/index.cjs.js +2 -2
  25. package/dist/auth/google/index.esm.js +2 -2
  26. package/dist/auth/index.cjs.js +4 -306
  27. package/dist/auth/index.d.mts +0 -5
  28. package/dist/auth/index.d.ts +0 -5
  29. package/dist/auth/index.esm.js +3 -302
  30. package/dist/auth/token-store.cjs.js +2 -2
  31. package/dist/auth/token-store.esm.js +2 -2
  32. package/dist/env.cjs.js +3 -3
  33. package/dist/env.d.mts +3 -2
  34. package/dist/env.d.ts +3 -2
  35. package/dist/env.esm.js +3 -3
  36. package/dist/file/client.cjs.js +2 -2
  37. package/dist/file/client.esm.js +2 -2
  38. package/dist/file/index.cjs.js +2 -2
  39. package/dist/file/index.esm.js +2 -2
  40. package/dist/file/put.cjs.js +2 -2
  41. package/dist/file/put.esm.js +2 -2
  42. package/dist/file/setup.cjs.js +2 -2
  43. package/dist/file/setup.esm.js +2 -2
  44. package/dist/file/utils.cjs.js +2 -2
  45. package/dist/file/utils.esm.js +2 -2
  46. package/dist/graphql/client.cjs.js +2 -2
  47. package/dist/graphql/client.esm.js +2 -2
  48. package/dist/graphql/index.cjs.js +2 -2
  49. package/dist/graphql/index.esm.js +2 -2
  50. package/dist/graphql/init.cjs.js +2 -2
  51. package/dist/graphql/init.esm.js +2 -2
  52. package/dist/graphql/links.cjs.js +2 -2
  53. package/dist/graphql/links.esm.js +2 -2
  54. package/dist/graphql/next.cjs.js +2 -2
  55. package/dist/graphql/next.esm.js +2 -2
  56. package/dist/graphql/server.cjs.js +2 -2
  57. package/dist/graphql/server.esm.js +2 -2
  58. package/dist/graphql/utils.cjs.js +2 -2
  59. package/dist/graphql/utils.esm.js +2 -2
  60. package/dist/socials/connect.cjs.js +151 -0
  61. package/dist/socials/connect.d.mts +70 -0
  62. package/dist/socials/connect.d.ts +70 -0
  63. package/dist/socials/connect.esm.js +126 -0
  64. package/dist/socials/index.cjs.js +344 -21
  65. package/dist/socials/index.d.mts +8 -2
  66. package/dist/socials/index.d.ts +8 -2
  67. package/dist/socials/index.esm.js +334 -20
  68. package/dist/socials/instagram/adapter.cjs.js +275 -0
  69. package/dist/socials/instagram/adapter.d.mts +30 -0
  70. package/dist/socials/instagram/adapter.d.ts +30 -0
  71. package/dist/socials/instagram/adapter.esm.js +248 -0
  72. package/dist/{auth/instagram/utils.cjs.js → socials/instagram/auth.cjs.js} +43 -41
  73. package/dist/socials/instagram/auth.d.mts +52 -0
  74. package/dist/socials/instagram/auth.d.ts +52 -0
  75. package/dist/{auth/instagram/utils.esm.js → socials/instagram/auth.esm.js} +37 -35
  76. package/dist/socials/instagram/getters.d.mts +1 -0
  77. package/dist/socials/instagram/getters.d.ts +1 -0
  78. package/dist/socials/instagram/setters.cjs.js +33 -17
  79. package/dist/socials/instagram/setters.d.mts +1 -0
  80. package/dist/socials/instagram/setters.d.ts +1 -0
  81. package/dist/socials/instagram/setters.esm.js +33 -17
  82. package/dist/socials/instagram/types.d.mts +2 -1
  83. package/dist/socials/instagram/types.d.ts +2 -1
  84. package/dist/socials/meta/container.cjs.js +34 -16
  85. package/dist/socials/meta/container.d.mts +5 -27
  86. package/dist/socials/meta/container.d.ts +5 -27
  87. package/dist/socials/meta/container.esm.js +33 -17
  88. package/dist/socials/provider.cjs.js +18 -0
  89. package/dist/socials/provider.d.mts +52 -0
  90. package/dist/socials/provider.d.ts +52 -0
  91. package/dist/socials/provider.esm.js +0 -0
  92. package/dist/socials/threads/getters.d.mts +1 -0
  93. package/dist/socials/threads/getters.d.ts +1 -0
  94. package/dist/socials/threads/setters.cjs.js +33 -17
  95. package/dist/socials/threads/setters.d.mts +1 -0
  96. package/dist/socials/threads/setters.d.ts +1 -0
  97. package/dist/socials/threads/setters.esm.js +33 -17
  98. package/dist/socials/threads/types.d.mts +2 -1
  99. package/dist/socials/threads/types.d.ts +2 -1
  100. package/dist/socials/types.cjs.js +43 -0
  101. package/dist/socials/types.d.mts +99 -0
  102. package/dist/socials/types.d.ts +99 -0
  103. package/dist/socials/types.esm.js +17 -0
  104. package/dist/socials/utils/poll.cjs.js +59 -0
  105. package/dist/socials/utils/poll.d.mts +85 -0
  106. package/dist/socials/utils/poll.d.ts +85 -0
  107. package/dist/socials/utils/poll.esm.js +33 -0
  108. package/dist/utils/client/index.cjs.js +2 -2
  109. package/dist/utils/client/index.esm.js +2 -2
  110. package/dist/utils/client/seo.cjs.js +2 -2
  111. package/dist/utils/client/seo.esm.js +2 -2
  112. package/package.json +1 -1
  113. package/dist/auth/instagram/index.cjs.js +0 -388
  114. package/dist/auth/instagram/index.d.mts +0 -58
  115. package/dist/auth/instagram/index.d.ts +0 -58
  116. package/dist/auth/instagram/index.esm.js +0 -359
  117. package/dist/auth/instagram/route.cjs.js +0 -368
  118. package/dist/auth/instagram/route.d.mts +0 -15
  119. package/dist/auth/instagram/route.d.ts +0 -15
  120. package/dist/auth/instagram/route.esm.js +0 -343
  121. package/dist/auth/instagram/utils.d.mts +0 -57
  122. package/dist/auth/instagram/utils.d.ts +0 -57
@@ -20,11 +20,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/socials/index.ts
21
21
  var socials_exports = {};
22
22
  __export(socials_exports, {
23
+ InstagramProvider: () => InstagramProvider,
23
24
  MetaMediaType: () => MetaMediaType,
25
+ SocialMediaKind: () => SocialMediaKind,
26
+ SocialPlatform: () => SocialPlatform,
24
27
  canPublishToInstagram: () => canPublishToInstagram,
25
28
  createInstagramPost: () => createInstagramPost,
26
29
  createThread: () => createThread,
27
30
  createThreadsPost: () => createThreadsPost,
31
+ getInstagramAuthorizationURL: () => getInstagramAuthorizationURL,
28
32
  getInstagramConversation: () => getInstagramConversation,
29
33
  getInstagramConversationByUser: () => getInstagramConversationByUser,
30
34
  getInstagramConversations: () => getInstagramConversations,
@@ -33,18 +37,203 @@ __export(socials_exports, {
33
37
  getInstagramMedia: () => getInstagramMedia,
34
38
  getInstagramMessage: () => getInstagramMessage,
35
39
  getInstagramUser: () => getInstagramUser,
40
+ getLongLivedInstagramToken: () => getLongLivedInstagramToken,
36
41
  getThread: () => getThread,
37
42
  getThreads: () => getThreads,
38
43
  getThreadsData: () => getThreadsData,
39
44
  getThreadsReplies: () => getThreadsReplies,
45
+ pollUntilReady: () => pollUntilReady,
40
46
  readGraphID: () => readGraphID,
47
+ refreshInstagramAccessToken: () => refreshInstagramAccessToken,
41
48
  replyToInstagramComment: () => replyToInstagramComment,
42
49
  sendInstagramMessage: () => sendInstagramMessage,
43
50
  setupInstagramWebhook: () => setupInstagramWebhook,
44
- setupThreadsWebhook: () => setupThreadsWebhook
51
+ setupSocialAuth: () => setupSocialAuth,
52
+ setupThreadsWebhook: () => setupThreadsWebhook,
53
+ withRetry: () => withRetry
45
54
  });
46
55
  module.exports = __toCommonJS(socials_exports);
47
56
 
57
+ // src/socials/connect.ts
58
+ var import_server2 = require("next/server");
59
+
60
+ // src/auth/email/token.ts
61
+ var import_bcryptjs = require("bcryptjs");
62
+ var import_jsonwebtoken = require("jsonwebtoken");
63
+ var import_headers = require("next/headers");
64
+ var import_navigation = require("next/navigation");
65
+ var import_server = require("next/server");
66
+
67
+ // src/env.ts
68
+ var EXTRA_ENV = globalThis.__NAYSTACK_ENV__ || (globalThis.__NAYSTACK_ENV__ = {});
69
+ var getEnvValue = (key) => {
70
+ switch (key) {
71
+ case "NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */:
72
+ return process.env.NEXT_PUBLIC_GRAPHQL_ENDPOINT || EXTRA_ENV.GRAPHQL_ENDPOINT;
73
+ case "NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT" /* NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT */:
74
+ return process.env.NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT || EXTRA_ENV.EMAIL_AUTH_ENDPOINT;
75
+ case "NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT" /* NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT */:
76
+ return process.env.NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT || EXTRA_ENV.GOOGLE_AUTH_ENDPOINT;
77
+ case "NEXT_PUBLIC_SOCIAL_AUTH_ENDPOINT" /* NEXT_PUBLIC_SOCIAL_AUTH_ENDPOINT */:
78
+ return process.env.NEXT_PUBLIC_SOCIAL_AUTH_ENDPOINT || EXTRA_ENV.SOCIAL_AUTH_ENDPOINT;
79
+ case "NEXT_PUBLIC_FILE_ENDPOINT" /* NEXT_PUBLIC_FILE_ENDPOINT */:
80
+ return process.env.NEXT_PUBLIC_FILE_ENDPOINT || EXTRA_ENV.FILE_ENDPOINT;
81
+ case "NEXT_PUBLIC_BASE_URL" /* NEXT_PUBLIC_BASE_URL */:
82
+ return process.env.NEXT_PUBLIC_BASE_URL || EXTRA_ENV.BASE_URL;
83
+ case "REFRESH_KEY" /* REFRESH_KEY */:
84
+ return process.env.REFRESH_KEY;
85
+ case "SIGNING_KEY" /* SIGNING_KEY */:
86
+ return process.env.SIGNING_KEY;
87
+ case "INSTAGRAM_CLIENT_SECRET" /* INSTAGRAM_CLIENT_SECRET */:
88
+ return process.env.INSTAGRAM_CLIENT_SECRET;
89
+ case "INSTAGRAM_CLIENT_ID" /* INSTAGRAM_CLIENT_ID */:
90
+ return process.env.INSTAGRAM_CLIENT_ID;
91
+ case "GOOGLE_CLIENT_SECRET" /* GOOGLE_CLIENT_SECRET */:
92
+ return process.env.GOOGLE_CLIENT_SECRET;
93
+ case "GOOGLE_CLIENT_ID" /* GOOGLE_CLIENT_ID */:
94
+ return process.env.GOOGLE_CLIENT_ID;
95
+ case "TURNSTILE_KEY" /* TURNSTILE_KEY */:
96
+ return process.env.TURNSTILE_KEY;
97
+ case "S3_ACCESS_KEY_ID" /* S3_ACCESS_KEY_ID */:
98
+ return process.env.S3_ACCESS_KEY_ID;
99
+ case "S3_ACCESS_KEY_SECRET" /* S3_ACCESS_KEY_SECRET */:
100
+ return process.env.S3_ACCESS_KEY_SECRET;
101
+ case "S3_REGION" /* S3_REGION */:
102
+ return process.env.S3_REGION;
103
+ case "S3_BUCKET" /* S3_BUCKET */:
104
+ return process.env.S3_BUCKET;
105
+ case "NODE_ENV" /* NODE_ENV */:
106
+ return process.env.NODE_ENV;
107
+ default:
108
+ return process.env[key];
109
+ }
110
+ };
111
+ function getEnv(key, skipCheck) {
112
+ const value = getEnvValue(key);
113
+ if (!skipCheck && !value) throw new Error(`${key} is not defined`);
114
+ return value;
115
+ }
116
+
117
+ // src/auth/email/token.ts
118
+ function getUserIdFromAccessToken(accessToken) {
119
+ if (accessToken)
120
+ try {
121
+ const decoded = (0, import_jsonwebtoken.verify)(accessToken, getEnv("SIGNING_KEY" /* SIGNING_KEY */));
122
+ if (typeof decoded !== "string" && typeof decoded.id === "number")
123
+ return decoded.id;
124
+ } catch (e) {
125
+ if (!(e instanceof import_jsonwebtoken.JsonWebTokenError)) console.error(e, "errors");
126
+ return null;
127
+ }
128
+ return null;
129
+ }
130
+
131
+ // src/socials/connect.ts
132
+ function setupSocialAuth({
133
+ providers,
134
+ endpoint,
135
+ onConnect,
136
+ redirectURL,
137
+ errorRedirectURL,
138
+ scopes
139
+ }) {
140
+ const handleError = (message) => import_server2.NextResponse.redirect(`${errorRedirectURL}?error=${message}`);
141
+ const GET = async (req, ctx) => {
142
+ const { platform } = await ctx.params;
143
+ const provider = providers.find((p) => p.platform === platform);
144
+ if (!provider) return handleError("Unsupported platform");
145
+ const code = req.nextUrl.searchParams.get("code");
146
+ const error = req.nextUrl.searchParams.get("error");
147
+ const state = req.nextUrl.searchParams.get("state");
148
+ if (error) return handleError(error);
149
+ if (!state) return handleError("Invalid request");
150
+ const redirectURI = `${endpoint}/${provider.platform}`;
151
+ if (!code) {
152
+ return import_server2.NextResponse.redirect(
153
+ provider.auth.authorizationURL({
154
+ state,
155
+ redirectURI,
156
+ scopes: scopes?.[provider.platform]
157
+ }),
158
+ 302
159
+ );
160
+ }
161
+ const exchanged = await provider.auth.exchangeCode({ code, redirectURI });
162
+ if (!exchanged) return handleError("Couldn't connect your account");
163
+ const { platformUserId, ...tokens } = exchanged;
164
+ const profile = await provider.fetchProfile(tokens.accessToken);
165
+ if (!profile) return handleError("Couldn't read your profile");
166
+ const errorMessage = await onConnect({
167
+ platform: provider.platform,
168
+ profile: {
169
+ ...profile,
170
+ platformUserId: profile.platformUserId ?? platformUserId
171
+ },
172
+ tokens,
173
+ userId: getUserIdFromAccessToken(state)
174
+ });
175
+ if (errorMessage) return handleError(errorMessage);
176
+ return import_server2.NextResponse.redirect(redirectURL);
177
+ };
178
+ return { GET };
179
+ }
180
+
181
+ // src/socials/types.ts
182
+ var SocialPlatform = /* @__PURE__ */ ((SocialPlatform2) => {
183
+ SocialPlatform2["Instagram"] = "instagram";
184
+ SocialPlatform2["YouTube"] = "youtube";
185
+ SocialPlatform2["TikTok"] = "tiktok";
186
+ return SocialPlatform2;
187
+ })(SocialPlatform || {});
188
+ var SocialMediaKind = /* @__PURE__ */ ((SocialMediaKind2) => {
189
+ SocialMediaKind2["Image"] = "image";
190
+ SocialMediaKind2["Video"] = "video";
191
+ SocialMediaKind2["Carousel"] = "carousel";
192
+ return SocialMediaKind2;
193
+ })(SocialMediaKind || {});
194
+
195
+ // src/socials/instagram/auth.ts
196
+ var getInstagramAuthorizationURL = (state, redirectURI, scopes = ["instagram_business_basic"]) => `https://www.instagram.com/oauth/authorize/?client_id=${getEnv(
197
+ "INSTAGRAM_CLIENT_ID" /* INSTAGRAM_CLIENT_ID */
198
+ )}&response_type=code&enable_fb_login=0&force_authentication=1&scope=${scopes.join(",")}&state=${state}&redirect_uri=${redirectURI}#weblink`;
199
+ async function getLongLivedInstagramToken(code, redirectURI) {
200
+ const formData = new FormData();
201
+ formData.set("client_id", getEnv("INSTAGRAM_CLIENT_ID" /* INSTAGRAM_CLIENT_ID */));
202
+ formData.set("client_secret", getEnv("INSTAGRAM_CLIENT_SECRET" /* INSTAGRAM_CLIENT_SECRET */));
203
+ formData.set("grant_type", "authorization_code");
204
+ formData.set("redirect_uri", redirectURI);
205
+ formData.set("code", code);
206
+ const shortRes = await fetch("https://api.instagram.com/oauth/access_token", {
207
+ method: "POST",
208
+ body: formData
209
+ });
210
+ if (!shortRes.ok) return void 0;
211
+ const shortResData = await shortRes.json();
212
+ if (!shortResData.access_token) return void 0;
213
+ const longRes = await fetch(
214
+ `https://graph.instagram.com/access_token?grant_type=ig_exchange_token&access_token=${shortResData.access_token}&client_secret=${getEnv("INSTAGRAM_CLIENT_SECRET" /* INSTAGRAM_CLIENT_SECRET */)}`
215
+ );
216
+ if (!longRes.ok) return void 0;
217
+ const longResData = await longRes.json();
218
+ return {
219
+ accessToken: longResData.access_token,
220
+ userId: shortResData.user_id,
221
+ expiresIn: longResData.expires_in,
222
+ permissions: shortResData.permissions
223
+ };
224
+ }
225
+ async function refreshInstagramAccessToken(token) {
226
+ const request = await fetch(
227
+ `https://graph.instagram.com/refresh_access_token?grant_type=ig_refresh_token&access_token=${token}`
228
+ );
229
+ const response = await request.json();
230
+ if (!response.access_token) return void 0;
231
+ return {
232
+ accessToken: response.access_token,
233
+ expiresIn: response.expires_in
234
+ };
235
+ }
236
+
48
237
  // src/socials/meta/request.ts
49
238
  function createGraphClient(baseURL) {
50
239
  const buildURL = (token, path, params = {}) => {
@@ -177,25 +366,151 @@ var canPublishToInstagram = async (token) => {
177
366
  return true;
178
367
  };
179
368
 
180
- // src/socials/meta/container.ts
369
+ // src/socials/instagram/adapter.ts
370
+ var PROFILE_FIELDS = [
371
+ "id",
372
+ "user_id",
373
+ "username",
374
+ "name",
375
+ "profile_picture_url",
376
+ "followers_count",
377
+ "media_count"
378
+ ];
379
+ var MEDIA_FIELDS = [
380
+ "id",
381
+ "caption",
382
+ "media_type",
383
+ "media_url",
384
+ "permalink",
385
+ "thumbnail_url",
386
+ "timestamp",
387
+ "like_count",
388
+ "comments_count"
389
+ ];
390
+ var expiresAt = (seconds) => seconds ? new Date(Date.now() + seconds * 1e3) : void 0;
391
+ function toKind(mediaType) {
392
+ if (mediaType === "VIDEO") return "video" /* Video */;
393
+ if (mediaType === "CAROUSEL_ALBUM") return "carousel" /* Carousel */;
394
+ return "image" /* Image */;
395
+ }
396
+ function toPost(media) {
397
+ const kind = toKind(media.media_type);
398
+ return {
399
+ platform: "instagram" /* Instagram */,
400
+ platformMediaId: media.id,
401
+ permalink: media.permalink,
402
+ // A video's `media_url` is the .mp4 itself, so it is never a stand-in for a
403
+ // missing poster frame — better no thumbnail than one that can't render.
404
+ thumbnail: media.thumbnail_url ?? (kind === "video" /* Video */ ? null : media.media_url ?? null),
405
+ mediaURL: media.media_url ?? null,
406
+ caption: media.caption ?? null,
407
+ kind,
408
+ publishedAt: media.timestamp,
409
+ likes: media.like_count ?? null,
410
+ comments: media.comments_count ?? null,
411
+ // Both need the Insights API; the basic media fields carry neither.
412
+ views: null,
413
+ shares: null,
414
+ metadata: {}
415
+ };
416
+ }
417
+ var InstagramProvider = {
418
+ platform: "instagram" /* Instagram */,
419
+ auth: {
420
+ authorizationURL: ({ state, redirectURI, scopes }) => getInstagramAuthorizationURL(
421
+ state,
422
+ redirectURI,
423
+ scopes
424
+ ),
425
+ exchangeCode: async ({ code, redirectURI }) => {
426
+ const result = await getLongLivedInstagramToken(code, redirectURI);
427
+ if (!result) {
428
+ console.error("[naystack] Instagram code exchange returned no token");
429
+ return null;
430
+ }
431
+ return {
432
+ accessToken: result.accessToken,
433
+ platformUserId: result.userId || null,
434
+ expiresAt: expiresAt(result.expiresIn),
435
+ scopes: result.permissions
436
+ };
437
+ },
438
+ refresh: async ({ accessToken }) => {
439
+ const refreshed = await refreshInstagramAccessToken(accessToken);
440
+ if (!refreshed) return null;
441
+ return {
442
+ accessToken: refreshed.accessToken,
443
+ expiresAt: expiresAt(refreshed.expiresIn)
444
+ };
445
+ }
446
+ },
447
+ fetchProfile: async (accessToken) => {
448
+ const user = await getInstagramUser(
449
+ accessToken,
450
+ void 0,
451
+ PROFILE_FIELDS
452
+ );
453
+ if (!user?.username) return null;
454
+ return {
455
+ platform: "instagram" /* Instagram */,
456
+ // `user_id` is what the OAuth exchange hands back, so preferring it keeps
457
+ // one account's id identical however it was read.
458
+ platformUserId: user.user_id || user.id || null,
459
+ username: user.username,
460
+ displayName: user.name ?? null,
461
+ avatar: user.profile_picture_url ?? null,
462
+ followers: user.followers_count ?? 0,
463
+ contentCount: user.media_count ?? 0,
464
+ metadata: {}
465
+ };
466
+ },
467
+ fetchMedia: async (accessToken, options) => {
468
+ const result = await getInstagramMedia(
469
+ accessToken,
470
+ MEDIA_FIELDS,
471
+ options?.limit
472
+ );
473
+ if (!result?.data) return [];
474
+ return result.data.map(toPost);
475
+ }
476
+ };
477
+
478
+ // src/socials/utils/poll.ts
181
479
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
182
- async function waitForContainer(getState, { intervalMS = 5e3, timeoutMS = 3e5 } = {}) {
480
+ async function pollUntilReady(read, isPending, { intervalMS = 5e3, timeoutMS = 3e5 } = {}) {
183
481
  const deadline = Date.now() + timeoutMS;
184
- let state = await getState();
482
+ let state = await read();
185
483
  if (!state) {
186
484
  await sleep(2e3);
187
485
  return null;
188
486
  }
189
- while (state?.status === "IN_PROGRESS" && Date.now() < deadline) {
487
+ while (state && isPending(state) && Date.now() < deadline) {
190
488
  await sleep(intervalMS);
191
- state = await getState();
489
+ state = await read();
192
490
  }
193
491
  return state;
194
492
  }
493
+ async function withRetry(run, options = {}) {
494
+ const attempts = Math.max(1, options.attempts ?? 3);
495
+ const backoffMS = options.backoffMS ?? 2e3;
496
+ for (let attempt = 1; attempt <= attempts; attempt++) {
497
+ const result = await run(attempt);
498
+ if (result) return result;
499
+ if (attempt < attempts) {
500
+ const delayMS = backoffMS * 2 ** (attempt - 1);
501
+ options.onRetry?.(attempt, attempts, delayMS);
502
+ await sleep(delayMS);
503
+ }
504
+ }
505
+ return null;
506
+ }
507
+
508
+ // src/socials/meta/container.ts
195
509
  function createPublisher(platform) {
196
510
  const isReady = async (token, id, label, wait) => {
197
- const state = await waitForContainer(
511
+ const state = await pollUntilReady(
198
512
  () => platform.getStatus(token, id),
513
+ (current) => current.status === "IN_PROGRESS",
199
514
  wait
200
515
  );
201
516
  if (state && state.status !== "FINISHED" && state.status !== "PUBLISHED") {
@@ -206,22 +521,21 @@ function createPublisher(platform) {
206
521
  }
207
522
  return true;
208
523
  };
209
- const createReady = async (token, params, label, wait, retry) => {
210
- const attempts = Math.max(1, retry?.attempts ?? 3);
211
- const backoffMS = retry?.backoffMS ?? 2e3;
212
- for (let attempt = 1; attempt <= attempts; attempt++) {
524
+ const createReady = (token, params, label, wait, retry) => withRetry(
525
+ async () => {
213
526
  const id = await platform.createContainer(token, params);
214
- if (id && await isReady(token, id, label, wait)) return id;
215
- if (attempt < attempts) {
216
- const delay = backoffMS * 2 ** (attempt - 1);
527
+ if (!id || !await isReady(token, id, label, wait)) return null;
528
+ return id;
529
+ },
530
+ {
531
+ ...retry,
532
+ onRetry: (attempt, attempts, delayMS) => {
217
533
  console.warn(
218
- `[naystack] ${platform.name} ${label} attempt ${attempt}/${attempts} failed \u2014 retrying in ${delay}ms`
534
+ `[naystack] ${platform.name} ${label} attempt ${attempt}/${attempts} failed \u2014 retrying in ${delayMS}ms`
219
535
  );
220
- await sleep(delay);
221
536
  }
222
537
  }
223
- return null;
224
- };
538
+ );
225
539
  return {
226
540
  /** Creates a container, waits for it to finish processing, then publishes it. */
227
541
  publish: async (token, params, wait, retry) => {
@@ -384,11 +698,11 @@ var sendInstagramMessage = (token, to, text) => {
384
698
  };
385
699
 
386
700
  // src/socials/meta/webhook.ts
387
- var import_server = require("next/server");
701
+ var import_server3 = require("next/server");
388
702
  var verifyWebhook = (secret) => (req) => {
389
703
  const params = req.nextUrl.searchParams;
390
704
  if (params.get("hub.verify_token") === secret) {
391
- return new import_server.NextResponse(params.get("hub.challenge"));
705
+ return new import_server3.NextResponse(params.get("hub.challenge"));
392
706
  }
393
707
  };
394
708
 
@@ -522,11 +836,15 @@ var setupThreadsWebhook = (options) => {
522
836
  };
523
837
  // Annotate the CommonJS export names for ESM import in node:
524
838
  0 && (module.exports = {
839
+ InstagramProvider,
525
840
  MetaMediaType,
841
+ SocialMediaKind,
842
+ SocialPlatform,
526
843
  canPublishToInstagram,
527
844
  createInstagramPost,
528
845
  createThread,
529
846
  createThreadsPost,
847
+ getInstagramAuthorizationURL,
530
848
  getInstagramConversation,
531
849
  getInstagramConversationByUser,
532
850
  getInstagramConversations,
@@ -535,13 +853,18 @@ var setupThreadsWebhook = (options) => {
535
853
  getInstagramMedia,
536
854
  getInstagramMessage,
537
855
  getInstagramUser,
856
+ getLongLivedInstagramToken,
538
857
  getThread,
539
858
  getThreads,
540
859
  getThreadsData,
541
860
  getThreadsReplies,
861
+ pollUntilReady,
542
862
  readGraphID,
863
+ refreshInstagramAccessToken,
543
864
  replyToInstagramComment,
544
865
  sendInstagramMessage,
545
866
  setupInstagramWebhook,
546
- setupThreadsWebhook
867
+ setupSocialAuth,
868
+ setupThreadsWebhook,
869
+ withRetry
547
870
  });
@@ -1,14 +1,20 @@
1
+ export { SetupSocialAuthOptions, SocialConnection, setupSocialAuth } from './connect.mjs';
2
+ export { InstagramProvider } from './instagram/adapter.mjs';
3
+ export { InstagramScope, getInstagramAuthorizationURL, getLongLivedInstagramToken, refreshInstagramAccessToken } from './instagram/auth.mjs';
1
4
  export { canPublishToInstagram, getInstagramConversation, getInstagramConversationByUser, getInstagramConversations, getInstagramConversationsByUser, getInstagramMedia, getInstagramMessage, getInstagramUser } from './instagram/getters.mjs';
2
5
  export { createInstagramPost, replyToInstagramComment, sendInstagramMessage } from './instagram/setters.mjs';
3
6
  export { InstagramConversation, InstagramMedia, InstagramMessage, InstagramPostInput, InstagramPostMedia, InstagramUser } from './instagram/types.mjs';
4
7
  export { getInstagramData } from './instagram/utils.mjs';
5
8
  export { setupInstagramWebhook } from './instagram/webhook.mjs';
6
- export { RetryOptions, WaitForContainerOptions } from './meta/container.mjs';
9
+ export { WaitForContainerOptions } from './meta/container.mjs';
7
10
  export { GraphClient, GraphRequestOptions, readGraphID } from './meta/request.mjs';
8
11
  export { GraphError, GraphParams, MetaMediaType } from './meta/types.mjs';
12
+ export { SocialProvider } from './provider.mjs';
9
13
  export { getThread, getThreads, getThreadsReplies } from './threads/getters.mjs';
10
14
  export { createThread, createThreadsPost } from './threads/setters.mjs';
11
- export { getThreadsData } from './threads/utils.mjs';
12
15
  export { ThreadsPost, ThreadsPostInput, ThreadsPostMedia } from './threads/types.mjs';
16
+ export { getThreadsData } from './threads/utils.mjs';
13
17
  export { setupThreadsWebhook } from './threads/webhook.mjs';
18
+ export { SocialMediaKind, SocialPlatform, SocialPost, SocialProfile, SocialTokens } from './types.mjs';
19
+ export { PollOptions, RetryOptions, pollUntilReady, withRetry } from './utils/poll.mjs';
14
20
  import 'next/server';
@@ -1,14 +1,20 @@
1
+ export { SetupSocialAuthOptions, SocialConnection, setupSocialAuth } from './connect.js';
2
+ export { InstagramProvider } from './instagram/adapter.js';
3
+ export { InstagramScope, getInstagramAuthorizationURL, getLongLivedInstagramToken, refreshInstagramAccessToken } from './instagram/auth.js';
1
4
  export { canPublishToInstagram, getInstagramConversation, getInstagramConversationByUser, getInstagramConversations, getInstagramConversationsByUser, getInstagramMedia, getInstagramMessage, getInstagramUser } from './instagram/getters.js';
2
5
  export { createInstagramPost, replyToInstagramComment, sendInstagramMessage } from './instagram/setters.js';
3
6
  export { InstagramConversation, InstagramMedia, InstagramMessage, InstagramPostInput, InstagramPostMedia, InstagramUser } from './instagram/types.js';
4
7
  export { getInstagramData } from './instagram/utils.js';
5
8
  export { setupInstagramWebhook } from './instagram/webhook.js';
6
- export { RetryOptions, WaitForContainerOptions } from './meta/container.js';
9
+ export { WaitForContainerOptions } from './meta/container.js';
7
10
  export { GraphClient, GraphRequestOptions, readGraphID } from './meta/request.js';
8
11
  export { GraphError, GraphParams, MetaMediaType } from './meta/types.js';
12
+ export { SocialProvider } from './provider.js';
9
13
  export { getThread, getThreads, getThreadsReplies } from './threads/getters.js';
10
14
  export { createThread, createThreadsPost } from './threads/setters.js';
11
- export { getThreadsData } from './threads/utils.js';
12
15
  export { ThreadsPost, ThreadsPostInput, ThreadsPostMedia } from './threads/types.js';
16
+ export { getThreadsData } from './threads/utils.js';
13
17
  export { setupThreadsWebhook } from './threads/webhook.js';
18
+ export { SocialMediaKind, SocialPlatform, SocialPost, SocialProfile, SocialTokens } from './types.js';
19
+ export { PollOptions, RetryOptions, pollUntilReady, withRetry } from './utils/poll.js';
14
20
  import 'next/server';