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
@@ -0,0 +1,30 @@
1
+ import { SocialProvider } from '../provider.mjs';
2
+ import '../types.mjs';
3
+
4
+ /**
5
+ * Instagram as a normalized {@link SocialProvider}.
6
+ *
7
+ * A ready-made singleton — import and call it, there is nothing to construct.
8
+ * Credentials are read from the environment inside the `auth` methods, so
9
+ * `fetchProfile` and `fetchMedia` need only a token and work in a process that
10
+ * has no Instagram OAuth configuration at all.
11
+ *
12
+ * Wraps the platform-specific helpers rather than replacing them:
13
+ * {@link getInstagramUser} and {@link getInstagramMedia} remain the way to reach
14
+ * fields this normalization drops.
15
+ *
16
+ * Requires env vars for `auth` only: `INSTAGRAM_CLIENT_ID`, `INSTAGRAM_CLIENT_SECRET`.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * import { InstagramProvider } from "naystack/socials";
21
+ *
22
+ * const profile = await InstagramProvider.fetchProfile(accessToken);
23
+ * const posts = await InstagramProvider.fetchMedia?.(accessToken, { limit: 6 });
24
+ * ```
25
+ *
26
+ * @category Socials
27
+ */
28
+ declare const InstagramProvider: SocialProvider;
29
+
30
+ export { InstagramProvider };
@@ -0,0 +1,30 @@
1
+ import { SocialProvider } from '../provider.js';
2
+ import '../types.js';
3
+
4
+ /**
5
+ * Instagram as a normalized {@link SocialProvider}.
6
+ *
7
+ * A ready-made singleton — import and call it, there is nothing to construct.
8
+ * Credentials are read from the environment inside the `auth` methods, so
9
+ * `fetchProfile` and `fetchMedia` need only a token and work in a process that
10
+ * has no Instagram OAuth configuration at all.
11
+ *
12
+ * Wraps the platform-specific helpers rather than replacing them:
13
+ * {@link getInstagramUser} and {@link getInstagramMedia} remain the way to reach
14
+ * fields this normalization drops.
15
+ *
16
+ * Requires env vars for `auth` only: `INSTAGRAM_CLIENT_ID`, `INSTAGRAM_CLIENT_SECRET`.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * import { InstagramProvider } from "naystack/socials";
21
+ *
22
+ * const profile = await InstagramProvider.fetchProfile(accessToken);
23
+ * const posts = await InstagramProvider.fetchMedia?.(accessToken, { limit: 6 });
24
+ * ```
25
+ *
26
+ * @category Socials
27
+ */
28
+ declare const InstagramProvider: SocialProvider;
29
+
30
+ export { InstagramProvider };
@@ -0,0 +1,248 @@
1
+ // src/env.ts
2
+ var EXTRA_ENV = globalThis.__NAYSTACK_ENV__ || (globalThis.__NAYSTACK_ENV__ = {});
3
+ var getEnvValue = (key) => {
4
+ switch (key) {
5
+ case "NEXT_PUBLIC_GRAPHQL_ENDPOINT" /* NEXT_PUBLIC_GRAPHQL_ENDPOINT */:
6
+ return process.env.NEXT_PUBLIC_GRAPHQL_ENDPOINT || EXTRA_ENV.GRAPHQL_ENDPOINT;
7
+ case "NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT" /* NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT */:
8
+ return process.env.NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT || EXTRA_ENV.EMAIL_AUTH_ENDPOINT;
9
+ case "NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT" /* NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT */:
10
+ return process.env.NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT || EXTRA_ENV.GOOGLE_AUTH_ENDPOINT;
11
+ case "NEXT_PUBLIC_SOCIAL_AUTH_ENDPOINT" /* NEXT_PUBLIC_SOCIAL_AUTH_ENDPOINT */:
12
+ return process.env.NEXT_PUBLIC_SOCIAL_AUTH_ENDPOINT || EXTRA_ENV.SOCIAL_AUTH_ENDPOINT;
13
+ case "NEXT_PUBLIC_FILE_ENDPOINT" /* NEXT_PUBLIC_FILE_ENDPOINT */:
14
+ return process.env.NEXT_PUBLIC_FILE_ENDPOINT || EXTRA_ENV.FILE_ENDPOINT;
15
+ case "NEXT_PUBLIC_BASE_URL" /* NEXT_PUBLIC_BASE_URL */:
16
+ return process.env.NEXT_PUBLIC_BASE_URL || EXTRA_ENV.BASE_URL;
17
+ case "REFRESH_KEY" /* REFRESH_KEY */:
18
+ return process.env.REFRESH_KEY;
19
+ case "SIGNING_KEY" /* SIGNING_KEY */:
20
+ return process.env.SIGNING_KEY;
21
+ case "INSTAGRAM_CLIENT_SECRET" /* INSTAGRAM_CLIENT_SECRET */:
22
+ return process.env.INSTAGRAM_CLIENT_SECRET;
23
+ case "INSTAGRAM_CLIENT_ID" /* INSTAGRAM_CLIENT_ID */:
24
+ return process.env.INSTAGRAM_CLIENT_ID;
25
+ case "GOOGLE_CLIENT_SECRET" /* GOOGLE_CLIENT_SECRET */:
26
+ return process.env.GOOGLE_CLIENT_SECRET;
27
+ case "GOOGLE_CLIENT_ID" /* GOOGLE_CLIENT_ID */:
28
+ return process.env.GOOGLE_CLIENT_ID;
29
+ case "TURNSTILE_KEY" /* TURNSTILE_KEY */:
30
+ return process.env.TURNSTILE_KEY;
31
+ case "S3_ACCESS_KEY_ID" /* S3_ACCESS_KEY_ID */:
32
+ return process.env.S3_ACCESS_KEY_ID;
33
+ case "S3_ACCESS_KEY_SECRET" /* S3_ACCESS_KEY_SECRET */:
34
+ return process.env.S3_ACCESS_KEY_SECRET;
35
+ case "S3_REGION" /* S3_REGION */:
36
+ return process.env.S3_REGION;
37
+ case "S3_BUCKET" /* S3_BUCKET */:
38
+ return process.env.S3_BUCKET;
39
+ case "NODE_ENV" /* NODE_ENV */:
40
+ return process.env.NODE_ENV;
41
+ default:
42
+ return process.env[key];
43
+ }
44
+ };
45
+ function getEnv(key, skipCheck) {
46
+ const value = getEnvValue(key);
47
+ if (!skipCheck && !value) throw new Error(`${key} is not defined`);
48
+ return value;
49
+ }
50
+
51
+ // src/socials/instagram/auth.ts
52
+ var getInstagramAuthorizationURL = (state, redirectURI, scopes = ["instagram_business_basic"]) => `https://www.instagram.com/oauth/authorize/?client_id=${getEnv(
53
+ "INSTAGRAM_CLIENT_ID" /* INSTAGRAM_CLIENT_ID */
54
+ )}&response_type=code&enable_fb_login=0&force_authentication=1&scope=${scopes.join(",")}&state=${state}&redirect_uri=${redirectURI}#weblink`;
55
+ async function getLongLivedInstagramToken(code, redirectURI) {
56
+ const formData = new FormData();
57
+ formData.set("client_id", getEnv("INSTAGRAM_CLIENT_ID" /* INSTAGRAM_CLIENT_ID */));
58
+ formData.set("client_secret", getEnv("INSTAGRAM_CLIENT_SECRET" /* INSTAGRAM_CLIENT_SECRET */));
59
+ formData.set("grant_type", "authorization_code");
60
+ formData.set("redirect_uri", redirectURI);
61
+ formData.set("code", code);
62
+ const shortRes = await fetch("https://api.instagram.com/oauth/access_token", {
63
+ method: "POST",
64
+ body: formData
65
+ });
66
+ if (!shortRes.ok) return void 0;
67
+ const shortResData = await shortRes.json();
68
+ if (!shortResData.access_token) return void 0;
69
+ const longRes = await fetch(
70
+ `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 */)}`
71
+ );
72
+ if (!longRes.ok) return void 0;
73
+ const longResData = await longRes.json();
74
+ return {
75
+ accessToken: longResData.access_token,
76
+ userId: shortResData.user_id,
77
+ expiresIn: longResData.expires_in,
78
+ permissions: shortResData.permissions
79
+ };
80
+ }
81
+ async function refreshInstagramAccessToken(token) {
82
+ const request = await fetch(
83
+ `https://graph.instagram.com/refresh_access_token?grant_type=ig_refresh_token&access_token=${token}`
84
+ );
85
+ const response = await request.json();
86
+ if (!response.access_token) return void 0;
87
+ return {
88
+ accessToken: response.access_token,
89
+ expiresIn: response.expires_in
90
+ };
91
+ }
92
+
93
+ // src/socials/meta/request.ts
94
+ function createGraphClient(baseURL) {
95
+ const buildURL = (token, path, params = {}) => {
96
+ const search = new URLSearchParams();
97
+ for (const [key, value] of Object.entries(params)) {
98
+ if (value !== void 0) search.set(key, String(value));
99
+ }
100
+ search.set("access_token", token);
101
+ return `${baseURL}/${path}?${search.toString()}`;
102
+ };
103
+ const request = async (token, path, options = {}) => {
104
+ const response = await fetch(buildURL(token, path, options.params), {
105
+ method: options.method || (options.body ? "POST" : "GET"),
106
+ headers: {
107
+ Authorization: `Bearer ${token}`,
108
+ ...options.body ? { "Content-Type": "application/json" } : {}
109
+ },
110
+ ...options.body ? { body: JSON.stringify(options.body) } : {}
111
+ });
112
+ return response.json().catch(() => null);
113
+ };
114
+ return { buildURL, request };
115
+ }
116
+
117
+ // src/socials/instagram/utils.ts
118
+ var client = createGraphClient("https://graph.instagram.com/v23.0");
119
+ var getInstagramData = client.request;
120
+
121
+ // src/socials/instagram/getters.ts
122
+ var getInstagramUser = (token, id, fields) => {
123
+ return getInstagramData(token, id || "me", {
124
+ params: {
125
+ fields: fields ? fields.join(",") : "username,followers_count,media_count"
126
+ }
127
+ });
128
+ };
129
+ var getInstagramMedia = (token, fields, limit = 12) => {
130
+ return getInstagramData(token, "me/media", {
131
+ params: {
132
+ fields: fields ? fields.join(",") : "like_count,comments_count,permalink",
133
+ limit
134
+ }
135
+ });
136
+ };
137
+
138
+ // src/socials/instagram/adapter.ts
139
+ var PROFILE_FIELDS = [
140
+ "id",
141
+ "user_id",
142
+ "username",
143
+ "name",
144
+ "profile_picture_url",
145
+ "followers_count",
146
+ "media_count"
147
+ ];
148
+ var MEDIA_FIELDS = [
149
+ "id",
150
+ "caption",
151
+ "media_type",
152
+ "media_url",
153
+ "permalink",
154
+ "thumbnail_url",
155
+ "timestamp",
156
+ "like_count",
157
+ "comments_count"
158
+ ];
159
+ var expiresAt = (seconds) => seconds ? new Date(Date.now() + seconds * 1e3) : void 0;
160
+ function toKind(mediaType) {
161
+ if (mediaType === "VIDEO") return "video" /* Video */;
162
+ if (mediaType === "CAROUSEL_ALBUM") return "carousel" /* Carousel */;
163
+ return "image" /* Image */;
164
+ }
165
+ function toPost(media) {
166
+ const kind = toKind(media.media_type);
167
+ return {
168
+ platform: "instagram" /* Instagram */,
169
+ platformMediaId: media.id,
170
+ permalink: media.permalink,
171
+ // A video's `media_url` is the .mp4 itself, so it is never a stand-in for a
172
+ // missing poster frame — better no thumbnail than one that can't render.
173
+ thumbnail: media.thumbnail_url ?? (kind === "video" /* Video */ ? null : media.media_url ?? null),
174
+ mediaURL: media.media_url ?? null,
175
+ caption: media.caption ?? null,
176
+ kind,
177
+ publishedAt: media.timestamp,
178
+ likes: media.like_count ?? null,
179
+ comments: media.comments_count ?? null,
180
+ // Both need the Insights API; the basic media fields carry neither.
181
+ views: null,
182
+ shares: null,
183
+ metadata: {}
184
+ };
185
+ }
186
+ var InstagramProvider = {
187
+ platform: "instagram" /* Instagram */,
188
+ auth: {
189
+ authorizationURL: ({ state, redirectURI, scopes }) => getInstagramAuthorizationURL(
190
+ state,
191
+ redirectURI,
192
+ scopes
193
+ ),
194
+ exchangeCode: async ({ code, redirectURI }) => {
195
+ const result = await getLongLivedInstagramToken(code, redirectURI);
196
+ if (!result) {
197
+ console.error("[naystack] Instagram code exchange returned no token");
198
+ return null;
199
+ }
200
+ return {
201
+ accessToken: result.accessToken,
202
+ platformUserId: result.userId || null,
203
+ expiresAt: expiresAt(result.expiresIn),
204
+ scopes: result.permissions
205
+ };
206
+ },
207
+ refresh: async ({ accessToken }) => {
208
+ const refreshed = await refreshInstagramAccessToken(accessToken);
209
+ if (!refreshed) return null;
210
+ return {
211
+ accessToken: refreshed.accessToken,
212
+ expiresAt: expiresAt(refreshed.expiresIn)
213
+ };
214
+ }
215
+ },
216
+ fetchProfile: async (accessToken) => {
217
+ const user = await getInstagramUser(
218
+ accessToken,
219
+ void 0,
220
+ PROFILE_FIELDS
221
+ );
222
+ if (!user?.username) return null;
223
+ return {
224
+ platform: "instagram" /* Instagram */,
225
+ // `user_id` is what the OAuth exchange hands back, so preferring it keeps
226
+ // one account's id identical however it was read.
227
+ platformUserId: user.user_id || user.id || null,
228
+ username: user.username,
229
+ displayName: user.name ?? null,
230
+ avatar: user.profile_picture_url ?? null,
231
+ followers: user.followers_count ?? 0,
232
+ contentCount: user.media_count ?? 0,
233
+ metadata: {}
234
+ };
235
+ },
236
+ fetchMedia: async (accessToken, options) => {
237
+ const result = await getInstagramMedia(
238
+ accessToken,
239
+ MEDIA_FIELDS,
240
+ options?.limit
241
+ );
242
+ if (!result?.data) return [];
243
+ return result.data.map(toPost);
244
+ }
245
+ };
246
+ export {
247
+ InstagramProvider
248
+ };
@@ -17,14 +17,14 @@ var __copyProps = (to, from, except, desc) => {
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
 
20
- // src/auth/instagram/utils.ts
21
- var utils_exports = {};
22
- __export(utils_exports, {
20
+ // src/socials/instagram/auth.ts
21
+ var auth_exports = {};
22
+ __export(auth_exports, {
23
23
  getInstagramAuthorizationURL: () => getInstagramAuthorizationURL,
24
- getLongLivedToken: () => getLongLivedToken,
25
- getRefreshedInstagramAccessToken: () => getRefreshedInstagramAccessToken
24
+ getLongLivedInstagramToken: () => getLongLivedInstagramToken,
25
+ refreshInstagramAccessToken: () => refreshInstagramAccessToken
26
26
  });
27
- module.exports = __toCommonJS(utils_exports);
27
+ module.exports = __toCommonJS(auth_exports);
28
28
 
29
29
  // src/env.ts
30
30
  var EXTRA_ENV = globalThis.__NAYSTACK_ENV__ || (globalThis.__NAYSTACK_ENV__ = {});
@@ -36,8 +36,8 @@ var getEnvValue = (key) => {
36
36
  return process.env.NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT || EXTRA_ENV.EMAIL_AUTH_ENDPOINT;
37
37
  case "NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT" /* NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT */:
38
38
  return process.env.NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT || EXTRA_ENV.GOOGLE_AUTH_ENDPOINT;
39
- case "NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT" /* NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT */:
40
- return process.env.NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT || EXTRA_ENV.INSTAGRAM_AUTH_ENDPOINT;
39
+ case "NEXT_PUBLIC_SOCIAL_AUTH_ENDPOINT" /* NEXT_PUBLIC_SOCIAL_AUTH_ENDPOINT */:
40
+ return process.env.NEXT_PUBLIC_SOCIAL_AUTH_ENDPOINT || EXTRA_ENV.SOCIAL_AUTH_ENDPOINT;
41
41
  case "NEXT_PUBLIC_FILE_ENDPOINT" /* NEXT_PUBLIC_FILE_ENDPOINT */:
42
42
  return process.env.NEXT_PUBLIC_FILE_ENDPOINT || EXTRA_ENV.FILE_ENDPOINT;
43
43
  case "NEXT_PUBLIC_BASE_URL" /* NEXT_PUBLIC_BASE_URL */:
@@ -76,48 +76,50 @@ function getEnv(key, skipCheck) {
76
76
  return value;
77
77
  }
78
78
 
79
- // src/auth/instagram/utils.ts
80
- async function getRefreshedInstagramAccessToken(token) {
81
- const request = await fetch(
82
- `https://graph.instagram.com/refresh_access_token?grant_type=ig_refresh_token&access_token=${token}`
83
- );
84
- const response = await request.json();
85
- return response.access_token;
86
- }
87
- async function getLongLivedToken(code, redirectURL, clientId, clientSecret) {
79
+ // src/socials/instagram/auth.ts
80
+ var getInstagramAuthorizationURL = (state, redirectURI, scopes = ["instagram_business_basic"]) => `https://www.instagram.com/oauth/authorize/?client_id=${getEnv(
81
+ "INSTAGRAM_CLIENT_ID" /* INSTAGRAM_CLIENT_ID */
82
+ )}&response_type=code&enable_fb_login=0&force_authentication=1&scope=${scopes.join(",")}&state=${state}&redirect_uri=${redirectURI}#weblink`;
83
+ async function getLongLivedInstagramToken(code, redirectURI) {
88
84
  const formData = new FormData();
89
- formData.set("client_id", clientId);
90
- formData.set("client_secret", clientSecret);
85
+ formData.set("client_id", getEnv("INSTAGRAM_CLIENT_ID" /* INSTAGRAM_CLIENT_ID */));
86
+ formData.set("client_secret", getEnv("INSTAGRAM_CLIENT_SECRET" /* INSTAGRAM_CLIENT_SECRET */));
91
87
  formData.set("grant_type", "authorization_code");
92
- formData.set("redirect_uri", redirectURL);
88
+ formData.set("redirect_uri", redirectURI);
93
89
  formData.set("code", code);
94
90
  const shortRes = await fetch("https://api.instagram.com/oauth/access_token", {
95
91
  method: "POST",
96
92
  body: formData
97
93
  });
98
- if (shortRes.ok) {
99
- const shortResData = await shortRes.json();
100
- if (shortResData.access_token) {
101
- const shortLivedToken = shortResData.access_token;
102
- const longRes = await fetch(
103
- `https://graph.instagram.com/access_token?grant_type=ig_exchange_token&access_token=${shortLivedToken}&client_secret=${getEnv("INSTAGRAM_CLIENT_SECRET" /* INSTAGRAM_CLIENT_SECRET */)}`
104
- );
105
- if (longRes.ok) {
106
- const longResData = await longRes.json();
107
- return {
108
- accessToken: longResData.access_token,
109
- userId: shortResData.user_id
110
- };
111
- }
112
- }
113
- }
94
+ if (!shortRes.ok) return void 0;
95
+ const shortResData = await shortRes.json();
96
+ if (!shortResData.access_token) return void 0;
97
+ const longRes = await fetch(
98
+ `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 */)}`
99
+ );
100
+ if (!longRes.ok) return void 0;
101
+ const longResData = await longRes.json();
102
+ return {
103
+ accessToken: longResData.access_token,
104
+ userId: shortResData.user_id,
105
+ expiresIn: longResData.expires_in,
106
+ permissions: shortResData.permissions
107
+ };
108
+ }
109
+ async function refreshInstagramAccessToken(token) {
110
+ const request = await fetch(
111
+ `https://graph.instagram.com/refresh_access_token?grant_type=ig_refresh_token&access_token=${token}`
112
+ );
113
+ const response = await request.json();
114
+ if (!response.access_token) return void 0;
115
+ return {
116
+ accessToken: response.access_token,
117
+ expiresIn: response.expires_in
118
+ };
114
119
  }
115
- var getInstagramAuthorizationURL = (token, scopes = ["instagram_business_basic"]) => `https://www.instagram.com/oauth/authorize/?client_id=${getEnv(
116
- "INSTAGRAM_CLIENT_ID" /* INSTAGRAM_CLIENT_ID */
117
- )}&response_type=code&enable_fb_login=0&force_authentication=1&scope=${scopes.join(",")}&state=${token}&redirect_uri=${getEnv("NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT" /* NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT */)}#weblink`;
118
120
  // Annotate the CommonJS export names for ESM import in node:
119
121
  0 && (module.exports = {
120
122
  getInstagramAuthorizationURL,
121
- getLongLivedToken,
122
- getRefreshedInstagramAccessToken
123
+ getLongLivedInstagramToken,
124
+ refreshInstagramAccessToken
123
125
  });
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Permissions requestable during Instagram Login OAuth. `instagram_business_basic`
3
+ * is enough to read a profile; publishing needs `instagram_business_content_publish`.
4
+ *
5
+ * Widening the scopes only affects users who authorize afterwards — tokens already
6
+ * stored keep the permissions they were granted, so existing users must reconnect.
7
+ *
8
+ * @category Socials
9
+ */
10
+ type InstagramScope = "instagram_business_basic" | "instagram_business_content_publish" | "instagram_business_manage_messages" | "instagram_business_manage_comments" | "instagram_business_manage_insights";
11
+ /**
12
+ * Builds the Instagram OAuth authorization URL.
13
+ *
14
+ * **Server-only** — reads the non-public `INSTAGRAM_CLIENT_ID`. The client id still
15
+ * ends up in the URL the browser follows; it is simply built here rather than
16
+ * shipped in the client bundle.
17
+ *
18
+ * @param state - Passed back by Instagram on the callback; typically the logged-in user's access token.
19
+ * @param redirectURI - Where Instagram sends the user back. Must match a URI registered with Meta verbatim.
20
+ * @param scopes - Default: `["instagram_business_basic"]`.
21
+ *
22
+ * @category Socials
23
+ */
24
+ declare const getInstagramAuthorizationURL: (state: string, redirectURI: string, scopes?: InstagramScope[]) => string;
25
+ /**
26
+ * Exchanges an OAuth code for a long-lived Instagram access token.
27
+ *
28
+ * @param code - Authorization code from the callback.
29
+ * @param redirectURI - The same URI used to obtain the code.
30
+ * @returns `{ accessToken, userId, expiresIn, permissions }`, or `undefined` if either exchange failed.
31
+ *
32
+ * @category Socials
33
+ */
34
+ declare function getLongLivedInstagramToken(code: string, redirectURI: string): Promise<{
35
+ accessToken: string;
36
+ userId: string | undefined;
37
+ expiresIn: number;
38
+ permissions: string[] | undefined;
39
+ } | undefined>;
40
+ /**
41
+ * Refreshes a long-lived Instagram token.
42
+ *
43
+ * @returns `{ accessToken, expiresIn }` (seconds), or `undefined` if the refresh failed.
44
+ *
45
+ * @category Socials
46
+ */
47
+ declare function refreshInstagramAccessToken(token: string): Promise<{
48
+ accessToken: string;
49
+ expiresIn: number | undefined;
50
+ } | undefined>;
51
+
52
+ export { type InstagramScope, getInstagramAuthorizationURL, getLongLivedInstagramToken, refreshInstagramAccessToken };
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Permissions requestable during Instagram Login OAuth. `instagram_business_basic`
3
+ * is enough to read a profile; publishing needs `instagram_business_content_publish`.
4
+ *
5
+ * Widening the scopes only affects users who authorize afterwards — tokens already
6
+ * stored keep the permissions they were granted, so existing users must reconnect.
7
+ *
8
+ * @category Socials
9
+ */
10
+ type InstagramScope = "instagram_business_basic" | "instagram_business_content_publish" | "instagram_business_manage_messages" | "instagram_business_manage_comments" | "instagram_business_manage_insights";
11
+ /**
12
+ * Builds the Instagram OAuth authorization URL.
13
+ *
14
+ * **Server-only** — reads the non-public `INSTAGRAM_CLIENT_ID`. The client id still
15
+ * ends up in the URL the browser follows; it is simply built here rather than
16
+ * shipped in the client bundle.
17
+ *
18
+ * @param state - Passed back by Instagram on the callback; typically the logged-in user's access token.
19
+ * @param redirectURI - Where Instagram sends the user back. Must match a URI registered with Meta verbatim.
20
+ * @param scopes - Default: `["instagram_business_basic"]`.
21
+ *
22
+ * @category Socials
23
+ */
24
+ declare const getInstagramAuthorizationURL: (state: string, redirectURI: string, scopes?: InstagramScope[]) => string;
25
+ /**
26
+ * Exchanges an OAuth code for a long-lived Instagram access token.
27
+ *
28
+ * @param code - Authorization code from the callback.
29
+ * @param redirectURI - The same URI used to obtain the code.
30
+ * @returns `{ accessToken, userId, expiresIn, permissions }`, or `undefined` if either exchange failed.
31
+ *
32
+ * @category Socials
33
+ */
34
+ declare function getLongLivedInstagramToken(code: string, redirectURI: string): Promise<{
35
+ accessToken: string;
36
+ userId: string | undefined;
37
+ expiresIn: number;
38
+ permissions: string[] | undefined;
39
+ } | undefined>;
40
+ /**
41
+ * Refreshes a long-lived Instagram token.
42
+ *
43
+ * @returns `{ accessToken, expiresIn }` (seconds), or `undefined` if the refresh failed.
44
+ *
45
+ * @category Socials
46
+ */
47
+ declare function refreshInstagramAccessToken(token: string): Promise<{
48
+ accessToken: string;
49
+ expiresIn: number | undefined;
50
+ } | undefined>;
51
+
52
+ export { type InstagramScope, getInstagramAuthorizationURL, getLongLivedInstagramToken, refreshInstagramAccessToken };
@@ -8,8 +8,8 @@ var getEnvValue = (key) => {
8
8
  return process.env.NEXT_PUBLIC_EMAIL_AUTH_ENDPOINT || EXTRA_ENV.EMAIL_AUTH_ENDPOINT;
9
9
  case "NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT" /* NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT */:
10
10
  return process.env.NEXT_PUBLIC_GOOGLE_AUTH_ENDPOINT || EXTRA_ENV.GOOGLE_AUTH_ENDPOINT;
11
- case "NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT" /* NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT */:
12
- return process.env.NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT || EXTRA_ENV.INSTAGRAM_AUTH_ENDPOINT;
11
+ case "NEXT_PUBLIC_SOCIAL_AUTH_ENDPOINT" /* NEXT_PUBLIC_SOCIAL_AUTH_ENDPOINT */:
12
+ return process.env.NEXT_PUBLIC_SOCIAL_AUTH_ENDPOINT || EXTRA_ENV.SOCIAL_AUTH_ENDPOINT;
13
13
  case "NEXT_PUBLIC_FILE_ENDPOINT" /* NEXT_PUBLIC_FILE_ENDPOINT */:
14
14
  return process.env.NEXT_PUBLIC_FILE_ENDPOINT || EXTRA_ENV.FILE_ENDPOINT;
15
15
  case "NEXT_PUBLIC_BASE_URL" /* NEXT_PUBLIC_BASE_URL */:
@@ -48,47 +48,49 @@ function getEnv(key, skipCheck) {
48
48
  return value;
49
49
  }
50
50
 
51
- // src/auth/instagram/utils.ts
52
- async function getRefreshedInstagramAccessToken(token) {
53
- const request = await fetch(
54
- `https://graph.instagram.com/refresh_access_token?grant_type=ig_refresh_token&access_token=${token}`
55
- );
56
- const response = await request.json();
57
- return response.access_token;
58
- }
59
- async function getLongLivedToken(code, redirectURL, clientId, clientSecret) {
51
+ // src/socials/instagram/auth.ts
52
+ var getInstagramAuthorizationURL = (state, redirectURI, scopes = ["instagram_business_basic"]) => `https://www.instagram.com/oauth/authorize/?client_id=${getEnv(
53
+ "INSTAGRAM_CLIENT_ID" /* INSTAGRAM_CLIENT_ID */
54
+ )}&response_type=code&enable_fb_login=0&force_authentication=1&scope=${scopes.join(",")}&state=${state}&redirect_uri=${redirectURI}#weblink`;
55
+ async function getLongLivedInstagramToken(code, redirectURI) {
60
56
  const formData = new FormData();
61
- formData.set("client_id", clientId);
62
- formData.set("client_secret", clientSecret);
57
+ formData.set("client_id", getEnv("INSTAGRAM_CLIENT_ID" /* INSTAGRAM_CLIENT_ID */));
58
+ formData.set("client_secret", getEnv("INSTAGRAM_CLIENT_SECRET" /* INSTAGRAM_CLIENT_SECRET */));
63
59
  formData.set("grant_type", "authorization_code");
64
- formData.set("redirect_uri", redirectURL);
60
+ formData.set("redirect_uri", redirectURI);
65
61
  formData.set("code", code);
66
62
  const shortRes = await fetch("https://api.instagram.com/oauth/access_token", {
67
63
  method: "POST",
68
64
  body: formData
69
65
  });
70
- if (shortRes.ok) {
71
- const shortResData = await shortRes.json();
72
- if (shortResData.access_token) {
73
- const shortLivedToken = shortResData.access_token;
74
- const longRes = await fetch(
75
- `https://graph.instagram.com/access_token?grant_type=ig_exchange_token&access_token=${shortLivedToken}&client_secret=${getEnv("INSTAGRAM_CLIENT_SECRET" /* INSTAGRAM_CLIENT_SECRET */)}`
76
- );
77
- if (longRes.ok) {
78
- const longResData = await longRes.json();
79
- return {
80
- accessToken: longResData.access_token,
81
- userId: shortResData.user_id
82
- };
83
- }
84
- }
85
- }
66
+ if (!shortRes.ok) return void 0;
67
+ const shortResData = await shortRes.json();
68
+ if (!shortResData.access_token) return void 0;
69
+ const longRes = await fetch(
70
+ `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 */)}`
71
+ );
72
+ if (!longRes.ok) return void 0;
73
+ const longResData = await longRes.json();
74
+ return {
75
+ accessToken: longResData.access_token,
76
+ userId: shortResData.user_id,
77
+ expiresIn: longResData.expires_in,
78
+ permissions: shortResData.permissions
79
+ };
80
+ }
81
+ async function refreshInstagramAccessToken(token) {
82
+ const request = await fetch(
83
+ `https://graph.instagram.com/refresh_access_token?grant_type=ig_refresh_token&access_token=${token}`
84
+ );
85
+ const response = await request.json();
86
+ if (!response.access_token) return void 0;
87
+ return {
88
+ accessToken: response.access_token,
89
+ expiresIn: response.expires_in
90
+ };
86
91
  }
87
- var getInstagramAuthorizationURL = (token, scopes = ["instagram_business_basic"]) => `https://www.instagram.com/oauth/authorize/?client_id=${getEnv(
88
- "INSTAGRAM_CLIENT_ID" /* INSTAGRAM_CLIENT_ID */
89
- )}&response_type=code&enable_fb_login=0&force_authentication=1&scope=${scopes.join(",")}&state=${token}&redirect_uri=${getEnv("NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT" /* NEXT_PUBLIC_INSTAGRAM_AUTH_ENDPOINT */)}#weblink`;
90
92
  export {
91
93
  getInstagramAuthorizationURL,
92
- getLongLivedToken,
93
- getRefreshedInstagramAccessToken
94
+ getLongLivedInstagramToken,
95
+ refreshInstagramAccessToken
94
96
  };
@@ -1,6 +1,7 @@
1
1
  import { GraphError, ContainerState } from '../meta/types.mjs';
2
2
  import { InstagramConversation, InstagramMedia, InstagramMessage, InstagramUser } from './types.mjs';
3
3
  import '../meta/container.mjs';
4
+ import '../utils/poll.mjs';
4
5
 
5
6
  /**
6
7
  * Fetches an Instagram user's profile. Defaults to the authenticated user (`"me"`).
@@ -1,6 +1,7 @@
1
1
  import { GraphError, ContainerState } from '../meta/types.js';
2
2
  import { InstagramConversation, InstagramMedia, InstagramMessage, InstagramUser } from './types.js';
3
3
  import '../meta/container.js';
4
+ import '../utils/poll.js';
4
5
 
5
6
  /**
6
7
  * Fetches an Instagram user's profile. Defaults to the authenticated user (`"me"`).