@followgate/js 0.3.0 → 0.5.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.
- package/dist/index.d.mts +74 -50
- package/dist/index.d.ts +74 -50
- package/dist/index.js +223 -194
- package/dist/index.mjs +221 -193
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,276 +1,243 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
var DEFAULT_API_URL = "https://api.followgate.app";
|
|
3
|
+
var FollowGateError = class extends Error {
|
|
4
|
+
constructor(message, code, hint) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.code = code;
|
|
7
|
+
this.hint = hint;
|
|
8
|
+
this.name = "FollowGateError";
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
function isValidApiKeyFormat(apiKey) {
|
|
12
|
+
return /^fg_(live|test)_[a-zA-Z0-9_-]+$/.test(apiKey);
|
|
13
|
+
}
|
|
3
14
|
var FollowGateClient = class {
|
|
4
15
|
config = null;
|
|
5
16
|
listeners = /* @__PURE__ */ new Map();
|
|
6
17
|
currentUser = null;
|
|
7
|
-
|
|
8
|
-
pendingUsername = null;
|
|
18
|
+
completedActions = [];
|
|
9
19
|
/**
|
|
10
20
|
* Initialize the SDK
|
|
21
|
+
* @throws {FollowGateError} If configuration is invalid
|
|
11
22
|
*/
|
|
12
23
|
init(config) {
|
|
24
|
+
if (!config.appId || typeof config.appId !== "string") {
|
|
25
|
+
throw new FollowGateError(
|
|
26
|
+
"[FollowGate] Missing or invalid appId",
|
|
27
|
+
"INVALID_APP_ID",
|
|
28
|
+
"Get your App ID from https://followgate.app/dashboard. Make sure NEXT_PUBLIC_FOLLOWGATE_APP_ID is set in your environment."
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
if (config.appId.trim() === "" || config.appId === "undefined") {
|
|
32
|
+
throw new FollowGateError(
|
|
33
|
+
"[FollowGate] appId is empty or undefined",
|
|
34
|
+
"EMPTY_APP_ID",
|
|
35
|
+
"Your appId appears to be empty. This often happens when environment variables are not properly configured. Check that NEXT_PUBLIC_FOLLOWGATE_APP_ID is set and rebuild your application."
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
if (!config.apiKey || typeof config.apiKey !== "string") {
|
|
39
|
+
throw new FollowGateError(
|
|
40
|
+
"[FollowGate] Missing or invalid apiKey",
|
|
41
|
+
"INVALID_API_KEY",
|
|
42
|
+
"Get your API Key from https://followgate.app/dashboard. Make sure NEXT_PUBLIC_FOLLOWGATE_API_KEY is set in your environment."
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
if (config.apiKey.trim() === "" || config.apiKey === "undefined") {
|
|
46
|
+
throw new FollowGateError(
|
|
47
|
+
"[FollowGate] apiKey is empty or undefined",
|
|
48
|
+
"EMPTY_API_KEY",
|
|
49
|
+
"Your apiKey appears to be empty. This often happens when environment variables are not properly configured at BUILD TIME (not runtime). Set NEXT_PUBLIC_FOLLOWGATE_API_KEY and REBUILD your application."
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
if (!isValidApiKeyFormat(config.apiKey)) {
|
|
53
|
+
throw new FollowGateError(
|
|
54
|
+
`[FollowGate] Invalid API key format: "${config.apiKey.substring(0, 10)}..."`,
|
|
55
|
+
"INVALID_API_KEY_FORMAT",
|
|
56
|
+
'API keys should start with "fg_live_" (production) or "fg_test_" (development). Get a valid key from https://followgate.app/dashboard'
|
|
57
|
+
);
|
|
58
|
+
}
|
|
13
59
|
this.config = {
|
|
14
60
|
...config,
|
|
15
61
|
apiUrl: config.apiUrl || DEFAULT_API_URL
|
|
16
62
|
};
|
|
17
|
-
this.handleAuthCallback();
|
|
18
63
|
this.restoreSession();
|
|
19
64
|
if (config.debug) {
|
|
20
65
|
console.log("[FollowGate] Initialized with appId:", config.appId);
|
|
66
|
+
console.log(
|
|
67
|
+
"[FollowGate] API Key:",
|
|
68
|
+
config.apiKey.substring(0, 12) + "..."
|
|
69
|
+
);
|
|
21
70
|
if (this.currentUser) {
|
|
22
71
|
console.log("[FollowGate] Restored user:", this.currentUser.username);
|
|
23
72
|
}
|
|
24
73
|
}
|
|
25
74
|
}
|
|
26
75
|
/**
|
|
27
|
-
*
|
|
28
|
-
* This
|
|
76
|
+
* Set the user's social username
|
|
77
|
+
* This is the main entry point - no OAuth needed!
|
|
29
78
|
*/
|
|
30
|
-
|
|
79
|
+
setUsername(username, platform = "twitter") {
|
|
31
80
|
if (!this.config) {
|
|
32
81
|
throw new Error("[FollowGate] SDK not initialized. Call init() first.");
|
|
33
82
|
}
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
83
|
+
const normalizedUsername = username.startsWith("@") ? username.slice(1) : username;
|
|
84
|
+
this.currentUser = {
|
|
85
|
+
username: normalizedUsername,
|
|
86
|
+
platform
|
|
87
|
+
};
|
|
88
|
+
if (typeof localStorage !== "undefined") {
|
|
89
|
+
localStorage.setItem("followgate_user", JSON.stringify(this.currentUser));
|
|
38
90
|
}
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
authUrl,
|
|
42
|
-
"followgate_auth",
|
|
43
|
-
"width=600,height=700"
|
|
44
|
-
);
|
|
45
|
-
if (!popup) {
|
|
46
|
-
this.emit("error", { message: "Popup blocked" });
|
|
47
|
-
}
|
|
48
|
-
} else {
|
|
49
|
-
window.location.href = authUrl;
|
|
91
|
+
if (this.config.debug) {
|
|
92
|
+
console.log("[FollowGate] Username set:", normalizedUsername);
|
|
50
93
|
}
|
|
51
94
|
}
|
|
52
95
|
/**
|
|
53
|
-
* Get current
|
|
96
|
+
* Get current user
|
|
54
97
|
*/
|
|
55
98
|
getUser() {
|
|
56
99
|
return this.currentUser;
|
|
57
100
|
}
|
|
58
101
|
/**
|
|
59
|
-
* Check if
|
|
102
|
+
* Check if username is set
|
|
60
103
|
*/
|
|
61
|
-
|
|
62
|
-
return this.currentUser !== null
|
|
104
|
+
hasUsername() {
|
|
105
|
+
return this.currentUser !== null;
|
|
63
106
|
}
|
|
64
107
|
/**
|
|
65
|
-
*
|
|
108
|
+
* Clear stored session
|
|
66
109
|
*/
|
|
67
|
-
|
|
110
|
+
reset() {
|
|
68
111
|
this.currentUser = null;
|
|
69
|
-
this.
|
|
70
|
-
this.pendingUsername = null;
|
|
112
|
+
this.completedActions = [];
|
|
71
113
|
if (typeof localStorage !== "undefined") {
|
|
72
|
-
localStorage.removeItem("followgate_token");
|
|
73
114
|
localStorage.removeItem("followgate_user");
|
|
74
|
-
localStorage.removeItem("
|
|
115
|
+
localStorage.removeItem("followgate_actions");
|
|
116
|
+
localStorage.removeItem("followgate_unlocked");
|
|
75
117
|
}
|
|
76
118
|
if (this.config?.debug) {
|
|
77
|
-
console.log("[FollowGate]
|
|
119
|
+
console.log("[FollowGate] Session reset");
|
|
78
120
|
}
|
|
79
121
|
}
|
|
122
|
+
// ============================================
|
|
123
|
+
// Intent URL Methods
|
|
124
|
+
// ============================================
|
|
80
125
|
/**
|
|
81
|
-
*
|
|
126
|
+
* Get follow intent URL for a platform
|
|
82
127
|
*/
|
|
83
|
-
|
|
84
|
-
return this.
|
|
128
|
+
getFollowUrl(platform, target) {
|
|
129
|
+
return this.buildIntentUrl({ platform, action: "follow", target });
|
|
85
130
|
}
|
|
86
131
|
/**
|
|
87
|
-
*
|
|
132
|
+
* Get repost/retweet intent URL for a platform
|
|
88
133
|
*/
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
throw new Error(
|
|
92
|
-
"[FollowGate] No pending username state. User is either not authenticated or username is already set."
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
const normalizedUsername = username.startsWith("@") ? username.slice(1) : username;
|
|
96
|
-
this.currentUser = {
|
|
97
|
-
userId: "user_input",
|
|
98
|
-
username: normalizedUsername,
|
|
99
|
-
platform: "twitter"
|
|
100
|
-
};
|
|
101
|
-
this.authToken = this.pendingUsername.token;
|
|
102
|
-
if (typeof localStorage !== "undefined") {
|
|
103
|
-
localStorage.setItem("followgate_token", this.authToken);
|
|
104
|
-
localStorage.setItem("followgate_user", JSON.stringify(this.currentUser));
|
|
105
|
-
localStorage.removeItem("followgate_pending_username");
|
|
106
|
-
}
|
|
107
|
-
this.pendingUsername = null;
|
|
108
|
-
this.emit("authenticated", this.currentUser);
|
|
109
|
-
if (this.config?.debug) {
|
|
110
|
-
console.log("[FollowGate] Username set manually:", normalizedUsername);
|
|
111
|
-
}
|
|
134
|
+
getRepostUrl(platform, target) {
|
|
135
|
+
return this.buildIntentUrl({ platform, action: "repost", target });
|
|
112
136
|
}
|
|
113
137
|
/**
|
|
114
|
-
*
|
|
138
|
+
* Get like intent URL for a platform
|
|
115
139
|
*/
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const params = new URLSearchParams(window.location.search);
|
|
119
|
-
const token = params.get("followgate_token");
|
|
120
|
-
const username = params.get("followgate_user");
|
|
121
|
-
const needsUsername = params.get("followgate_needs_username") === "true";
|
|
122
|
-
if (token && needsUsername) {
|
|
123
|
-
this.pendingUsername = {
|
|
124
|
-
needsUsername: true,
|
|
125
|
-
token
|
|
126
|
-
};
|
|
127
|
-
if (typeof localStorage !== "undefined") {
|
|
128
|
-
localStorage.setItem(
|
|
129
|
-
"followgate_pending_username",
|
|
130
|
-
JSON.stringify(this.pendingUsername)
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
const url = new URL(window.location.href);
|
|
134
|
-
url.searchParams.delete("followgate_token");
|
|
135
|
-
url.searchParams.delete("followgate_needs_username");
|
|
136
|
-
window.history.replaceState({}, "", url.toString());
|
|
137
|
-
if (this.config?.debug) {
|
|
138
|
-
console.log("[FollowGate] OAuth successful, username input needed");
|
|
139
|
-
}
|
|
140
|
-
} else if (token && username) {
|
|
141
|
-
this.authToken = token;
|
|
142
|
-
this.currentUser = {
|
|
143
|
-
userId: "",
|
|
144
|
-
// Will be set from token verification
|
|
145
|
-
username,
|
|
146
|
-
platform: "twitter"
|
|
147
|
-
};
|
|
148
|
-
if (typeof localStorage !== "undefined") {
|
|
149
|
-
localStorage.setItem("followgate_token", token);
|
|
150
|
-
localStorage.setItem(
|
|
151
|
-
"followgate_user",
|
|
152
|
-
JSON.stringify(this.currentUser)
|
|
153
|
-
);
|
|
154
|
-
}
|
|
155
|
-
const url = new URL(window.location.href);
|
|
156
|
-
url.searchParams.delete("followgate_token");
|
|
157
|
-
url.searchParams.delete("followgate_user");
|
|
158
|
-
window.history.replaceState({}, "", url.toString());
|
|
159
|
-
this.emit("authenticated", this.currentUser);
|
|
160
|
-
if (this.config?.debug) {
|
|
161
|
-
console.log("[FollowGate] User authenticated:", username);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
140
|
+
getLikeUrl(platform, target) {
|
|
141
|
+
return this.buildIntentUrl({ platform, action: "like", target });
|
|
164
142
|
}
|
|
165
143
|
/**
|
|
166
|
-
*
|
|
144
|
+
* Open intent URL in new window
|
|
167
145
|
*/
|
|
168
|
-
|
|
169
|
-
if (
|
|
170
|
-
|
|
171
|
-
if (pendingJson) {
|
|
172
|
-
try {
|
|
173
|
-
this.pendingUsername = JSON.parse(pendingJson);
|
|
174
|
-
if (this.config?.debug) {
|
|
175
|
-
console.log("[FollowGate] Restored pending username state");
|
|
176
|
-
}
|
|
177
|
-
return;
|
|
178
|
-
} catch {
|
|
179
|
-
localStorage.removeItem("followgate_pending_username");
|
|
180
|
-
}
|
|
146
|
+
async openIntent(options) {
|
|
147
|
+
if (!this.config) {
|
|
148
|
+
throw new Error("[FollowGate] SDK not initialized. Call init() first.");
|
|
181
149
|
}
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
try {
|
|
186
|
-
this.authToken = token;
|
|
187
|
-
this.currentUser = JSON.parse(userJson);
|
|
188
|
-
} catch {
|
|
189
|
-
localStorage.removeItem("followgate_token");
|
|
190
|
-
localStorage.removeItem("followgate_user");
|
|
191
|
-
}
|
|
150
|
+
const url = this.buildIntentUrl(options);
|
|
151
|
+
if (this.config.debug) {
|
|
152
|
+
console.log("[FollowGate] Opening intent:", url);
|
|
192
153
|
}
|
|
154
|
+
await this.trackEvent("intent_opened", { ...options });
|
|
155
|
+
window.open(url, "_blank", "width=600,height=700");
|
|
193
156
|
}
|
|
157
|
+
// ============================================
|
|
158
|
+
// Completion Methods
|
|
159
|
+
// ============================================
|
|
194
160
|
/**
|
|
195
|
-
*
|
|
161
|
+
* Mark an action as completed (trust-first)
|
|
162
|
+
* Call this when user confirms they did the action
|
|
196
163
|
*/
|
|
197
|
-
async
|
|
164
|
+
async complete(options) {
|
|
198
165
|
if (!this.config) {
|
|
199
166
|
throw new Error("[FollowGate] SDK not initialized. Call init() first.");
|
|
200
167
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
168
|
+
if (!this.currentUser) {
|
|
169
|
+
throw new Error(
|
|
170
|
+
"[FollowGate] No username set. Call setUsername() first."
|
|
171
|
+
);
|
|
204
172
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
173
|
+
const alreadyCompleted = this.completedActions.some(
|
|
174
|
+
(a) => a.platform === options.platform && a.action === options.action && a.target === options.target
|
|
175
|
+
);
|
|
176
|
+
if (!alreadyCompleted) {
|
|
177
|
+
this.completedActions.push(options);
|
|
178
|
+
this.saveCompletedActions();
|
|
210
179
|
}
|
|
211
|
-
await this.trackEvent("
|
|
180
|
+
await this.trackEvent("action_completed", {
|
|
181
|
+
...options,
|
|
182
|
+
username: this.currentUser.username
|
|
183
|
+
});
|
|
212
184
|
this.emit("complete", {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
target: options.target
|
|
185
|
+
...options,
|
|
186
|
+
username: this.currentUser.username
|
|
216
187
|
});
|
|
188
|
+
if (this.config.debug) {
|
|
189
|
+
console.log("[FollowGate] Action completed:", options);
|
|
190
|
+
}
|
|
217
191
|
}
|
|
218
192
|
/**
|
|
219
|
-
*
|
|
193
|
+
* Mark the gate as unlocked
|
|
194
|
+
* Call this when all required actions are done
|
|
220
195
|
*/
|
|
221
|
-
async
|
|
196
|
+
async unlock() {
|
|
222
197
|
if (!this.config) {
|
|
223
198
|
throw new Error("[FollowGate] SDK not initialized. Call init() first.");
|
|
224
199
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
});
|
|
239
|
-
const data = await response.json();
|
|
240
|
-
return data.success && data.data?.verified === true;
|
|
241
|
-
} catch (error) {
|
|
242
|
-
if (this.config.debug) {
|
|
243
|
-
console.error("[FollowGate] Verification error:", error);
|
|
244
|
-
}
|
|
245
|
-
return false;
|
|
200
|
+
if (typeof localStorage !== "undefined") {
|
|
201
|
+
localStorage.setItem("followgate_unlocked", "true");
|
|
202
|
+
}
|
|
203
|
+
await this.trackEvent("gate_unlocked", {
|
|
204
|
+
username: this.currentUser?.username,
|
|
205
|
+
actions: this.completedActions
|
|
206
|
+
});
|
|
207
|
+
this.emit("unlocked", {
|
|
208
|
+
username: this.currentUser?.username,
|
|
209
|
+
actions: this.completedActions
|
|
210
|
+
});
|
|
211
|
+
if (this.config.debug) {
|
|
212
|
+
console.log("[FollowGate] Gate unlocked!");
|
|
246
213
|
}
|
|
247
214
|
}
|
|
248
215
|
/**
|
|
249
|
-
*
|
|
216
|
+
* Check if gate is unlocked
|
|
250
217
|
*/
|
|
251
|
-
|
|
252
|
-
if (
|
|
253
|
-
|
|
254
|
-
await fetch(`${this.config.apiUrl}/api/v1/events`, {
|
|
255
|
-
method: "POST",
|
|
256
|
-
headers: {
|
|
257
|
-
"Content-Type": "application/json",
|
|
258
|
-
"X-API-Key": this.config.apiKey
|
|
259
|
-
},
|
|
260
|
-
body: JSON.stringify({
|
|
261
|
-
event,
|
|
262
|
-
platform: options.platform,
|
|
263
|
-
action: options.action,
|
|
264
|
-
target: options.target,
|
|
265
|
-
externalUserId: options.userId
|
|
266
|
-
})
|
|
267
|
-
});
|
|
268
|
-
} catch (error) {
|
|
269
|
-
if (this.config.debug) {
|
|
270
|
-
console.warn("[FollowGate] Failed to track event:", error);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
218
|
+
isUnlocked() {
|
|
219
|
+
if (typeof localStorage === "undefined") return false;
|
|
220
|
+
return localStorage.getItem("followgate_unlocked") === "true";
|
|
273
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* Get unlock status with details
|
|
224
|
+
*/
|
|
225
|
+
getUnlockStatus() {
|
|
226
|
+
return {
|
|
227
|
+
unlocked: this.isUnlocked(),
|
|
228
|
+
username: this.currentUser?.username,
|
|
229
|
+
completedActions: [...this.completedActions]
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Get completed actions
|
|
234
|
+
*/
|
|
235
|
+
getCompletedActions() {
|
|
236
|
+
return [...this.completedActions];
|
|
237
|
+
}
|
|
238
|
+
// ============================================
|
|
239
|
+
// Event System
|
|
240
|
+
// ============================================
|
|
274
241
|
/**
|
|
275
242
|
* Register event listener
|
|
276
243
|
*/
|
|
@@ -286,6 +253,42 @@ var FollowGateClient = class {
|
|
|
286
253
|
off(event, callback) {
|
|
287
254
|
this.listeners.get(event)?.delete(callback);
|
|
288
255
|
}
|
|
256
|
+
// ============================================
|
|
257
|
+
// Private Methods
|
|
258
|
+
// ============================================
|
|
259
|
+
/**
|
|
260
|
+
* Restore session from localStorage
|
|
261
|
+
*/
|
|
262
|
+
restoreSession() {
|
|
263
|
+
if (typeof localStorage === "undefined") return;
|
|
264
|
+
const userJson = localStorage.getItem("followgate_user");
|
|
265
|
+
if (userJson) {
|
|
266
|
+
try {
|
|
267
|
+
this.currentUser = JSON.parse(userJson);
|
|
268
|
+
} catch {
|
|
269
|
+
localStorage.removeItem("followgate_user");
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
const actionsJson = localStorage.getItem("followgate_actions");
|
|
273
|
+
if (actionsJson) {
|
|
274
|
+
try {
|
|
275
|
+
this.completedActions = JSON.parse(actionsJson);
|
|
276
|
+
} catch {
|
|
277
|
+
localStorage.removeItem("followgate_actions");
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Save completed actions to localStorage
|
|
283
|
+
*/
|
|
284
|
+
saveCompletedActions() {
|
|
285
|
+
if (typeof localStorage !== "undefined") {
|
|
286
|
+
localStorage.setItem(
|
|
287
|
+
"followgate_actions",
|
|
288
|
+
JSON.stringify(this.completedActions)
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
289
292
|
/**
|
|
290
293
|
* Build intent URL for platform
|
|
291
294
|
*/
|
|
@@ -347,6 +350,30 @@ var FollowGateClient = class {
|
|
|
347
350
|
throw new Error(`[FollowGate] Unsupported LinkedIn action: ${action}`);
|
|
348
351
|
}
|
|
349
352
|
}
|
|
353
|
+
/**
|
|
354
|
+
* Track analytics event
|
|
355
|
+
*/
|
|
356
|
+
async trackEvent(event, data) {
|
|
357
|
+
if (!this.config) return;
|
|
358
|
+
try {
|
|
359
|
+
await fetch(`${this.config.apiUrl}/api/v1/events`, {
|
|
360
|
+
method: "POST",
|
|
361
|
+
headers: {
|
|
362
|
+
"Content-Type": "application/json",
|
|
363
|
+
"X-API-Key": this.config.apiKey
|
|
364
|
+
},
|
|
365
|
+
body: JSON.stringify({
|
|
366
|
+
event,
|
|
367
|
+
appId: this.config.appId,
|
|
368
|
+
...data
|
|
369
|
+
})
|
|
370
|
+
});
|
|
371
|
+
} catch (error) {
|
|
372
|
+
if (this.config.debug) {
|
|
373
|
+
console.warn("[FollowGate] Failed to track event:", error);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
350
377
|
emit(event, data) {
|
|
351
378
|
this.listeners.get(event)?.forEach((callback) => callback(data));
|
|
352
379
|
}
|
|
@@ -354,5 +381,6 @@ var FollowGateClient = class {
|
|
|
354
381
|
var FollowGate = new FollowGateClient();
|
|
355
382
|
export {
|
|
356
383
|
FollowGate,
|
|
357
|
-
FollowGateClient
|
|
384
|
+
FollowGateClient,
|
|
385
|
+
FollowGateError
|
|
358
386
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@followgate/js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "FollowGate SDK - Grow your audience with every download. Require social actions (follow, repost) before users can access your app.",
|
|
5
5
|
"author": "FollowGate <hello@followgate.app>",
|
|
6
6
|
"homepage": "https://followgate.app",
|