@githat/nextjs 0.2.1 → 0.3.1
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 +141 -2
- package/dist/index.d.ts +141 -2
- package/dist/index.js +244 -98
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +214 -69
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.d.mts +39 -2
- package/dist/middleware.d.ts +39 -2
- package/dist/middleware.js +82 -5
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +72 -5
- package/dist/middleware.mjs.map +1 -1
- package/dist/server.d.mts +115 -0
- package/dist/server.d.ts +115 -0
- package/dist/server.js +186 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +147 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +9 -1
package/dist/index.js
CHANGED
|
@@ -31,6 +31,7 @@ __export(src_exports, {
|
|
|
31
31
|
UserButton: () => UserButton,
|
|
32
32
|
VerifiedBadge: () => VerifiedBadge,
|
|
33
33
|
useAuth: () => useAuth,
|
|
34
|
+
useData: () => useData,
|
|
34
35
|
useGitHat: () => useGitHat
|
|
35
36
|
});
|
|
36
37
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -53,15 +54,16 @@ function resolveConfig(config) {
|
|
|
53
54
|
signInUrl: config.signInUrl || "/sign-in",
|
|
54
55
|
signUpUrl: config.signUpUrl || "/sign-up",
|
|
55
56
|
afterSignInUrl: config.afterSignInUrl || "/dashboard",
|
|
56
|
-
afterSignOutUrl: config.afterSignOutUrl || "/"
|
|
57
|
+
afterSignOutUrl: config.afterSignOutUrl || "/",
|
|
58
|
+
tokenStorage: config.tokenStorage || "localStorage"
|
|
57
59
|
};
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
// src/client.ts
|
|
61
63
|
var _refreshPromise = null;
|
|
62
|
-
async function refreshTokens(apiUrl, appKey) {
|
|
63
|
-
const refreshToken = typeof window !== "undefined" ? localStorage.getItem(TOKEN_KEYS.refreshToken) : null;
|
|
64
|
-
if (!refreshToken) return false;
|
|
64
|
+
async function refreshTokens(apiUrl, appKey, useCookies) {
|
|
65
|
+
const refreshToken = typeof window !== "undefined" && !useCookies ? localStorage.getItem(TOKEN_KEYS.refreshToken) : null;
|
|
66
|
+
if (!useCookies && !refreshToken) return false;
|
|
65
67
|
let orgId = null;
|
|
66
68
|
try {
|
|
67
69
|
const orgStr = localStorage.getItem(TOKEN_KEYS.org);
|
|
@@ -69,18 +71,22 @@ async function refreshTokens(apiUrl, appKey) {
|
|
|
69
71
|
} catch {
|
|
70
72
|
}
|
|
71
73
|
try {
|
|
72
|
-
const
|
|
74
|
+
const refreshUrl = useCookies ? `${apiUrl}/auth/refresh?setCookie=true` : `${apiUrl}/auth/refresh`;
|
|
75
|
+
const res = await fetch(refreshUrl, {
|
|
73
76
|
method: "POST",
|
|
74
77
|
headers: {
|
|
75
78
|
"Content-Type": "application/json",
|
|
76
79
|
"X-GitHat-App-Key": appKey
|
|
77
80
|
},
|
|
78
|
-
|
|
81
|
+
credentials: useCookies ? "include" : "same-origin",
|
|
82
|
+
body: JSON.stringify(useCookies ? { orgId } : { refreshToken, orgId })
|
|
79
83
|
});
|
|
80
84
|
if (!res.ok) return false;
|
|
81
85
|
const data = await res.json();
|
|
82
|
-
if (
|
|
83
|
-
|
|
86
|
+
if (!useCookies) {
|
|
87
|
+
if (data.accessToken) localStorage.setItem(TOKEN_KEYS.accessToken, data.accessToken);
|
|
88
|
+
if (data.refreshToken) localStorage.setItem(TOKEN_KEYS.refreshToken, data.refreshToken);
|
|
89
|
+
}
|
|
84
90
|
if (data.org) localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.org));
|
|
85
91
|
return true;
|
|
86
92
|
} catch {
|
|
@@ -90,23 +96,30 @@ async function refreshTokens(apiUrl, appKey) {
|
|
|
90
96
|
function clearAuth() {
|
|
91
97
|
if (typeof window === "undefined") return;
|
|
92
98
|
Object.values(TOKEN_KEYS).forEach((key) => localStorage.removeItem(key));
|
|
93
|
-
window.dispatchEvent(
|
|
94
|
-
|
|
95
|
-
|
|
99
|
+
window.dispatchEvent(
|
|
100
|
+
new CustomEvent("githat:auth-changed", {
|
|
101
|
+
detail: { user: null, org: null, signedIn: false }
|
|
102
|
+
})
|
|
103
|
+
);
|
|
96
104
|
}
|
|
97
|
-
function createClient(apiUrl, appKey) {
|
|
98
|
-
|
|
105
|
+
function createClient(apiUrl, appKey, options = {}) {
|
|
106
|
+
const { useCookies = false } = options;
|
|
107
|
+
async function fetchApi(endpoint, fetchOptions = {}) {
|
|
99
108
|
const url = `${apiUrl}${endpoint}`;
|
|
100
|
-
const token = typeof window !== "undefined" ? localStorage.getItem(TOKEN_KEYS.accessToken) : null;
|
|
109
|
+
const token = typeof window !== "undefined" && !useCookies ? localStorage.getItem(TOKEN_KEYS.accessToken) : null;
|
|
101
110
|
const headers = {
|
|
102
111
|
"Content-Type": "application/json",
|
|
103
112
|
"X-GitHat-App-Key": appKey,
|
|
104
113
|
...token && { Authorization: `Bearer ${token}` },
|
|
105
|
-
...
|
|
114
|
+
...fetchOptions.headers
|
|
106
115
|
};
|
|
107
116
|
let response;
|
|
108
117
|
try {
|
|
109
|
-
response = await fetch(url, {
|
|
118
|
+
response = await fetch(url, {
|
|
119
|
+
...fetchOptions,
|
|
120
|
+
headers,
|
|
121
|
+
credentials: useCookies ? "include" : "same-origin"
|
|
122
|
+
});
|
|
110
123
|
} catch (networkError) {
|
|
111
124
|
if (networkError instanceof TypeError) {
|
|
112
125
|
const isMissingKey = !appKey || !appKey.startsWith("pk_live_");
|
|
@@ -116,27 +129,26 @@ function createClient(apiUrl, appKey) {
|
|
|
116
129
|
"Missing GitHat API key. Add NEXT_PUBLIC_GITHAT_PUBLISHABLE_KEY to .env.local"
|
|
117
130
|
);
|
|
118
131
|
}
|
|
119
|
-
throw new Error(
|
|
120
|
-
"Unable to connect to GitHat API. Check your network connection."
|
|
121
|
-
);
|
|
132
|
+
throw new Error("Unable to connect to GitHat API. Check your network connection.");
|
|
122
133
|
}
|
|
123
134
|
throw networkError;
|
|
124
135
|
}
|
|
125
136
|
if (response.status === 401) {
|
|
126
137
|
if (!_refreshPromise) {
|
|
127
|
-
_refreshPromise = refreshTokens(apiUrl, appKey).finally(() => {
|
|
138
|
+
_refreshPromise = refreshTokens(apiUrl, appKey, useCookies).finally(() => {
|
|
128
139
|
_refreshPromise = null;
|
|
129
140
|
});
|
|
130
141
|
}
|
|
131
142
|
const refreshed = await _refreshPromise;
|
|
132
143
|
if (refreshed) {
|
|
133
|
-
const newToken = localStorage.getItem(TOKEN_KEYS.accessToken);
|
|
144
|
+
const newToken = !useCookies && typeof window !== "undefined" ? localStorage.getItem(TOKEN_KEYS.accessToken) : null;
|
|
134
145
|
const retryResponse = await fetch(url, {
|
|
135
|
-
...
|
|
146
|
+
...fetchOptions,
|
|
136
147
|
headers: {
|
|
137
148
|
...headers,
|
|
138
149
|
...newToken && { Authorization: `Bearer ${newToken}` }
|
|
139
|
-
}
|
|
150
|
+
},
|
|
151
|
+
credentials: useCookies ? "include" : "same-origin"
|
|
140
152
|
});
|
|
141
153
|
const retryData = await retryResponse.json();
|
|
142
154
|
if (!retryResponse.ok) throw new Error(retryData.error || "Request failed");
|
|
@@ -157,38 +169,57 @@ var import_jsx_runtime = require("react/jsx-runtime");
|
|
|
157
169
|
var GitHatContext = (0, import_react.createContext)(null);
|
|
158
170
|
function GitHatProvider({ config: rawConfig, children }) {
|
|
159
171
|
const config = (0, import_react.useMemo)(() => resolveConfig(rawConfig), [rawConfig]);
|
|
160
|
-
const
|
|
172
|
+
const useCookies = config.tokenStorage === "cookie";
|
|
173
|
+
const clientRef = (0, import_react.useRef)(createClient(config.apiUrl, config.publishableKey, { useCookies }));
|
|
161
174
|
const [user, setUser] = (0, import_react.useState)(null);
|
|
162
175
|
const [org, setOrg] = (0, import_react.useState)(null);
|
|
163
176
|
const [isSignedIn, setIsSignedIn] = (0, import_react.useState)(false);
|
|
164
177
|
const [isLoading, setIsLoading] = (0, import_react.useState)(true);
|
|
165
178
|
const [authError, setAuthError] = (0, import_react.useState)(null);
|
|
166
179
|
(0, import_react.useEffect)(() => {
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if (
|
|
180
|
+
const validateSession = async () => {
|
|
181
|
+
try {
|
|
182
|
+
if (!useCookies) {
|
|
183
|
+
const token = localStorage.getItem(TOKEN_KEYS.accessToken);
|
|
184
|
+
const storedUser = localStorage.getItem(TOKEN_KEYS.user);
|
|
185
|
+
if (!token || !storedUser) {
|
|
186
|
+
setIsLoading(false);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const data = await clientRef.current.fetchApi("/auth/me");
|
|
191
|
+
if (data.user) {
|
|
192
|
+
setUser(data.user);
|
|
193
|
+
setOrg(data.currentOrg || null);
|
|
194
|
+
setIsSignedIn(true);
|
|
195
|
+
setAuthError(null);
|
|
196
|
+
if (!useCookies) {
|
|
197
|
+
localStorage.setItem(TOKEN_KEYS.user, JSON.stringify(data.user));
|
|
198
|
+
if (data.currentOrg) {
|
|
199
|
+
localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.currentOrg));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
} catch (err) {
|
|
204
|
+
const error = err;
|
|
205
|
+
if (error.message === "Session expired") {
|
|
179
206
|
clientRef.current.clearAuth();
|
|
180
|
-
} else {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
207
|
+
} else if (!useCookies) {
|
|
208
|
+
const storedUser = localStorage.getItem(TOKEN_KEYS.user);
|
|
209
|
+
if (storedUser) {
|
|
210
|
+
try {
|
|
211
|
+
setUser(JSON.parse(storedUser));
|
|
212
|
+
setIsSignedIn(true);
|
|
213
|
+
} catch {
|
|
214
|
+
}
|
|
184
215
|
}
|
|
185
|
-
setAuthError(
|
|
216
|
+
setAuthError(error.message || "Failed to verify session");
|
|
186
217
|
}
|
|
187
|
-
}
|
|
188
|
-
} else {
|
|
218
|
+
}
|
|
189
219
|
setIsLoading(false);
|
|
190
|
-
}
|
|
191
|
-
|
|
220
|
+
};
|
|
221
|
+
validateSession();
|
|
222
|
+
}, [useCookies]);
|
|
192
223
|
(0, import_react.useEffect)(() => {
|
|
193
224
|
const handleAuthChanged = (e) => {
|
|
194
225
|
const detail = e.detail;
|
|
@@ -206,30 +237,36 @@ function GitHatProvider({ config: rawConfig, children }) {
|
|
|
206
237
|
return () => window.removeEventListener("githat:auth-changed", handleAuthChanged);
|
|
207
238
|
}, []);
|
|
208
239
|
const signIn = (0, import_react.useCallback)(async (email, password) => {
|
|
209
|
-
const
|
|
240
|
+
const loginUrl = useCookies ? "/auth/login?setCookie=true" : "/auth/login";
|
|
241
|
+
const data = await clientRef.current.fetchApi(loginUrl, {
|
|
210
242
|
method: "POST",
|
|
211
243
|
body: JSON.stringify({ email, password })
|
|
212
244
|
});
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
245
|
+
if (!useCookies && data.accessToken && data.refreshToken) {
|
|
246
|
+
localStorage.setItem(TOKEN_KEYS.accessToken, data.accessToken);
|
|
247
|
+
localStorage.setItem(TOKEN_KEYS.refreshToken, data.refreshToken);
|
|
248
|
+
localStorage.setItem(TOKEN_KEYS.user, JSON.stringify(data.user));
|
|
249
|
+
if (data.org) localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.org));
|
|
250
|
+
}
|
|
217
251
|
setUser(data.user);
|
|
218
252
|
setOrg(data.org || null);
|
|
219
253
|
setIsSignedIn(true);
|
|
220
254
|
window.dispatchEvent(new CustomEvent("githat:auth-changed", {
|
|
221
255
|
detail: { user: data.user, org: data.org, signedIn: true }
|
|
222
256
|
}));
|
|
223
|
-
}, []);
|
|
257
|
+
}, [useCookies]);
|
|
224
258
|
const signUp = (0, import_react.useCallback)(async (signUpData) => {
|
|
225
|
-
const
|
|
259
|
+
const registerUrl = useCookies ? "/auth/register?setCookie=true" : "/auth/register";
|
|
260
|
+
const data = await clientRef.current.fetchApi(registerUrl, {
|
|
226
261
|
method: "POST",
|
|
227
262
|
body: JSON.stringify(signUpData)
|
|
228
263
|
});
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
264
|
+
if (!useCookies && data.accessToken && data.refreshToken) {
|
|
265
|
+
localStorage.setItem(TOKEN_KEYS.accessToken, data.accessToken);
|
|
266
|
+
localStorage.setItem(TOKEN_KEYS.refreshToken, data.refreshToken);
|
|
267
|
+
localStorage.setItem(TOKEN_KEYS.user, JSON.stringify(data.user));
|
|
268
|
+
if (data.org) localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.org));
|
|
269
|
+
}
|
|
233
270
|
setUser(data.user);
|
|
234
271
|
setOrg(data.org || null);
|
|
235
272
|
setIsSignedIn(true);
|
|
@@ -237,10 +274,11 @@ function GitHatProvider({ config: rawConfig, children }) {
|
|
|
237
274
|
detail: { user: data.user, org: data.org, signedIn: true }
|
|
238
275
|
}));
|
|
239
276
|
return { requiresVerification: !data.user.emailVerified, email: signUpData.email };
|
|
240
|
-
}, []);
|
|
277
|
+
}, [useCookies]);
|
|
241
278
|
const signOut = (0, import_react.useCallback)(async () => {
|
|
242
279
|
try {
|
|
243
|
-
|
|
280
|
+
const logoutUrl = useCookies ? "/auth/logout?setCookie=true" : "/auth/logout";
|
|
281
|
+
await clientRef.current.fetchApi(logoutUrl, { method: "POST" });
|
|
244
282
|
} catch {
|
|
245
283
|
}
|
|
246
284
|
clientRef.current.clearAuth();
|
|
@@ -250,22 +288,24 @@ function GitHatProvider({ config: rawConfig, children }) {
|
|
|
250
288
|
if (typeof window !== "undefined" && config.afterSignOutUrl) {
|
|
251
289
|
window.location.href = config.afterSignOutUrl;
|
|
252
290
|
}
|
|
253
|
-
}, [config.afterSignOutUrl]);
|
|
291
|
+
}, [config.afterSignOutUrl, useCookies]);
|
|
254
292
|
const switchOrg = (0, import_react.useCallback)(async (orgId) => {
|
|
255
293
|
try {
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
if (
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
294
|
+
const switchUrl = useCookies ? `/user/orgs/${orgId}/switch?setCookie=true` : `/user/orgs/${orgId}/switch`;
|
|
295
|
+
const data = await clientRef.current.fetchApi(switchUrl, { method: "POST" });
|
|
296
|
+
if (!useCookies) {
|
|
297
|
+
if (data.accessToken) localStorage.setItem(TOKEN_KEYS.accessToken, data.accessToken);
|
|
298
|
+
if (data.refreshToken) localStorage.setItem(TOKEN_KEYS.refreshToken, data.refreshToken);
|
|
299
|
+
localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.org));
|
|
300
|
+
}
|
|
301
|
+
setOrg(data.org);
|
|
262
302
|
window.dispatchEvent(new CustomEvent("githat:auth-changed", {
|
|
263
|
-
detail: { user, org:
|
|
303
|
+
detail: { user, org: data.org, signedIn: true }
|
|
264
304
|
}));
|
|
265
305
|
} catch (e) {
|
|
266
306
|
console.error("Org switch failed:", e);
|
|
267
307
|
}
|
|
268
|
-
}, [user]);
|
|
308
|
+
}, [user, useCookies]);
|
|
269
309
|
const value = (0, import_react.useMemo)(() => ({
|
|
270
310
|
user,
|
|
271
311
|
org,
|
|
@@ -294,23 +334,128 @@ function useGitHat() {
|
|
|
294
334
|
() => createClient(ctx.config.apiUrl, ctx.config.publishableKey),
|
|
295
335
|
[ctx.config.apiUrl, ctx.config.publishableKey]
|
|
296
336
|
);
|
|
337
|
+
const getOrgMetadata = (0, import_react2.useCallback)(async () => {
|
|
338
|
+
if (!ctx.org?.id) {
|
|
339
|
+
throw new Error("No active organization");
|
|
340
|
+
}
|
|
341
|
+
const response = await client.fetchApi(
|
|
342
|
+
`/orgs/${ctx.org.id}/metadata`
|
|
343
|
+
);
|
|
344
|
+
return response.metadata || {};
|
|
345
|
+
}, [client, ctx.org?.id]);
|
|
346
|
+
const updateOrgMetadata = (0, import_react2.useCallback)(
|
|
347
|
+
async (updates) => {
|
|
348
|
+
if (!ctx.org?.id) {
|
|
349
|
+
throw new Error("No active organization");
|
|
350
|
+
}
|
|
351
|
+
const response = await client.fetchApi(
|
|
352
|
+
`/orgs/${ctx.org.id}/metadata`,
|
|
353
|
+
{
|
|
354
|
+
method: "PATCH",
|
|
355
|
+
body: JSON.stringify(updates)
|
|
356
|
+
}
|
|
357
|
+
);
|
|
358
|
+
return response.metadata || {};
|
|
359
|
+
},
|
|
360
|
+
[client, ctx.org?.id]
|
|
361
|
+
);
|
|
297
362
|
return {
|
|
298
363
|
fetch: client.fetchApi,
|
|
299
364
|
getUserOrgs: () => client.fetchApi("/user/orgs"),
|
|
300
365
|
verifyMCP: (domain) => client.fetchApi(`/verify/mcp/${domain}`),
|
|
301
|
-
verifyAgent: (wallet) => client.fetchApi(`/verify/agent/${wallet}`)
|
|
366
|
+
verifyAgent: (wallet) => client.fetchApi(`/verify/agent/${wallet}`),
|
|
367
|
+
getOrgMetadata,
|
|
368
|
+
updateOrgMetadata
|
|
302
369
|
};
|
|
303
370
|
}
|
|
304
371
|
|
|
305
|
-
// src/
|
|
372
|
+
// src/data.ts
|
|
306
373
|
var import_react3 = require("react");
|
|
374
|
+
function useData() {
|
|
375
|
+
const ctx = useAuth();
|
|
376
|
+
const client = (0, import_react3.useMemo)(
|
|
377
|
+
() => createClient(ctx.config.apiUrl, ctx.config.publishableKey),
|
|
378
|
+
[ctx.config.apiUrl, ctx.config.publishableKey]
|
|
379
|
+
);
|
|
380
|
+
return (0, import_react3.useMemo)(() => ({
|
|
381
|
+
/**
|
|
382
|
+
* Store an item in a collection. If the item exists, it will be updated.
|
|
383
|
+
* @param collection - Collection name (e.g., 'orders', 'users')
|
|
384
|
+
* @param data - Data object with required `id` field
|
|
385
|
+
*/
|
|
386
|
+
put: async (collection, data) => {
|
|
387
|
+
if (!data.id) {
|
|
388
|
+
throw new Error('Data must include an "id" field');
|
|
389
|
+
}
|
|
390
|
+
return client.fetchApi(`/data/${collection}/${data.id}`, {
|
|
391
|
+
method: "PUT",
|
|
392
|
+
body: JSON.stringify(data)
|
|
393
|
+
});
|
|
394
|
+
},
|
|
395
|
+
/**
|
|
396
|
+
* Get a single item from a collection.
|
|
397
|
+
* @param collection - Collection name
|
|
398
|
+
* @param id - Item ID
|
|
399
|
+
*/
|
|
400
|
+
get: async (collection, id) => {
|
|
401
|
+
try {
|
|
402
|
+
const result = await client.fetchApi(`/data/${collection}/${id}`);
|
|
403
|
+
return result.item;
|
|
404
|
+
} catch (err) {
|
|
405
|
+
if (err instanceof Error && err.message === "Item not found") {
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
throw err;
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
/**
|
|
412
|
+
* Query items from a collection with optional filters and pagination.
|
|
413
|
+
* @param collection - Collection name
|
|
414
|
+
* @param options - Query options (limit, cursor, filter)
|
|
415
|
+
*/
|
|
416
|
+
query: async (collection, options = {}) => {
|
|
417
|
+
const params = new URLSearchParams();
|
|
418
|
+
if (options.limit) params.set("limit", options.limit.toString());
|
|
419
|
+
if (options.cursor) params.set("cursor", options.cursor);
|
|
420
|
+
if (options.filter) params.set("filter", JSON.stringify(options.filter));
|
|
421
|
+
const queryString = params.toString();
|
|
422
|
+
const url = `/data/${collection}${queryString ? `?${queryString}` : ""}`;
|
|
423
|
+
return client.fetchApi(url);
|
|
424
|
+
},
|
|
425
|
+
/**
|
|
426
|
+
* Delete an item from a collection.
|
|
427
|
+
* @param collection - Collection name
|
|
428
|
+
* @param id - Item ID
|
|
429
|
+
*/
|
|
430
|
+
remove: async (collection, id) => {
|
|
431
|
+
return client.fetchApi(`/data/${collection}/${id}`, {
|
|
432
|
+
method: "DELETE"
|
|
433
|
+
});
|
|
434
|
+
},
|
|
435
|
+
/**
|
|
436
|
+
* Batch operations (put/delete) on a collection.
|
|
437
|
+
* Maximum 100 operations per request.
|
|
438
|
+
* @param collection - Collection name
|
|
439
|
+
* @param operations - Array of operations
|
|
440
|
+
*/
|
|
441
|
+
batch: async (collection, operations) => {
|
|
442
|
+
return client.fetchApi(`/data/${collection}/batch`, {
|
|
443
|
+
method: "POST",
|
|
444
|
+
body: JSON.stringify({ operations })
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
}), [client]);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// src/components/SignInForm.tsx
|
|
451
|
+
var import_react4 = require("react");
|
|
307
452
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
308
453
|
function SignInForm({ onSuccess, signUpUrl, forgotPasswordUrl }) {
|
|
309
454
|
const { signIn, config } = useAuth();
|
|
310
|
-
const [email, setEmail] = (0,
|
|
311
|
-
const [password, setPassword] = (0,
|
|
312
|
-
const [error, setError] = (0,
|
|
313
|
-
const [loading, setLoading] = (0,
|
|
455
|
+
const [email, setEmail] = (0, import_react4.useState)("");
|
|
456
|
+
const [password, setPassword] = (0, import_react4.useState)("");
|
|
457
|
+
const [error, setError] = (0, import_react4.useState)("");
|
|
458
|
+
const [loading, setLoading] = (0, import_react4.useState)(false);
|
|
314
459
|
const emailValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
|
315
460
|
const handleSubmit = async (e) => {
|
|
316
461
|
e.preventDefault();
|
|
@@ -396,15 +541,15 @@ function SignInForm({ onSuccess, signUpUrl, forgotPasswordUrl }) {
|
|
|
396
541
|
}
|
|
397
542
|
|
|
398
543
|
// src/components/SignUpForm.tsx
|
|
399
|
-
var
|
|
544
|
+
var import_react5 = require("react");
|
|
400
545
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
401
546
|
function SignUpForm({ onSuccess, signInUrl }) {
|
|
402
547
|
const { signUp, config } = useAuth();
|
|
403
|
-
const [name, setName] = (0,
|
|
404
|
-
const [email, setEmail] = (0,
|
|
405
|
-
const [password, setPassword] = (0,
|
|
406
|
-
const [error, setError] = (0,
|
|
407
|
-
const [loading, setLoading] = (0,
|
|
548
|
+
const [name, setName] = (0, import_react5.useState)("");
|
|
549
|
+
const [email, setEmail] = (0, import_react5.useState)("");
|
|
550
|
+
const [password, setPassword] = (0, import_react5.useState)("");
|
|
551
|
+
const [error, setError] = (0, import_react5.useState)("");
|
|
552
|
+
const [loading, setLoading] = (0, import_react5.useState)(false);
|
|
408
553
|
const emailValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
|
409
554
|
const passwordValid = password.length >= 8 && /[A-Z]/.test(password) && /[a-z]/.test(password) && /\d/.test(password);
|
|
410
555
|
const handleSubmit = async (e) => {
|
|
@@ -510,31 +655,31 @@ function SignUpForm({ onSuccess, signInUrl }) {
|
|
|
510
655
|
}
|
|
511
656
|
|
|
512
657
|
// src/components/SignInButton.tsx
|
|
513
|
-
var
|
|
658
|
+
var import_react6 = require("react");
|
|
514
659
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
515
660
|
function SignInButton({ className, children, href }) {
|
|
516
|
-
const ctx = (0,
|
|
661
|
+
const ctx = (0, import_react6.useContext)(GitHatContext);
|
|
517
662
|
const url = href || ctx?.config.signInUrl || "/sign-in";
|
|
518
663
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { href: url, className: className || "githat-button githat-button-primary", "aria-label": "Sign in", children: children || "Sign in" });
|
|
519
664
|
}
|
|
520
665
|
|
|
521
666
|
// src/components/SignUpButton.tsx
|
|
522
|
-
var
|
|
667
|
+
var import_react7 = require("react");
|
|
523
668
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
524
669
|
function SignUpButton({ className, children, href }) {
|
|
525
|
-
const ctx = (0,
|
|
670
|
+
const ctx = (0, import_react7.useContext)(GitHatContext);
|
|
526
671
|
const url = href || ctx?.config.signUpUrl || "/sign-up";
|
|
527
672
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("a", { href: url, className: className || "githat-button githat-button-outline", "aria-label": "Sign up", children: children || "Sign up" });
|
|
528
673
|
}
|
|
529
674
|
|
|
530
675
|
// src/components/UserButton.tsx
|
|
531
|
-
var
|
|
676
|
+
var import_react8 = require("react");
|
|
532
677
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
533
678
|
function UserButton() {
|
|
534
679
|
const { user, org, isSignedIn, signOut } = useAuth();
|
|
535
|
-
const [open, setOpen] = (0,
|
|
536
|
-
const ref = (0,
|
|
537
|
-
(0,
|
|
680
|
+
const [open, setOpen] = (0, import_react8.useState)(false);
|
|
681
|
+
const ref = (0, import_react8.useRef)(null);
|
|
682
|
+
(0, import_react8.useEffect)(() => {
|
|
538
683
|
const handleClickOutside = (e) => {
|
|
539
684
|
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
540
685
|
};
|
|
@@ -561,23 +706,23 @@ function UserButton() {
|
|
|
561
706
|
}
|
|
562
707
|
|
|
563
708
|
// src/components/OrgSwitcher.tsx
|
|
564
|
-
var
|
|
709
|
+
var import_react9 = require("react");
|
|
565
710
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
566
711
|
function OrgSwitcher() {
|
|
567
712
|
const { org, isSignedIn, switchOrg } = useAuth();
|
|
568
713
|
const githat = useGitHat();
|
|
569
|
-
const [orgs, setOrgs] = (0,
|
|
570
|
-
const [orgsLoading, setOrgsLoading] = (0,
|
|
571
|
-
const [open, setOpen] = (0,
|
|
572
|
-
const ref = (0,
|
|
573
|
-
(0,
|
|
714
|
+
const [orgs, setOrgs] = (0, import_react9.useState)([]);
|
|
715
|
+
const [orgsLoading, setOrgsLoading] = (0, import_react9.useState)(false);
|
|
716
|
+
const [open, setOpen] = (0, import_react9.useState)(false);
|
|
717
|
+
const ref = (0, import_react9.useRef)(null);
|
|
718
|
+
(0, import_react9.useEffect)(() => {
|
|
574
719
|
if (isSignedIn) {
|
|
575
720
|
setOrgsLoading(true);
|
|
576
721
|
githat.getUserOrgs().then((data) => setOrgs(data.orgs || [])).catch(() => {
|
|
577
722
|
}).finally(() => setOrgsLoading(false));
|
|
578
723
|
}
|
|
579
724
|
}, [isSignedIn]);
|
|
580
|
-
(0,
|
|
725
|
+
(0, import_react9.useEffect)(() => {
|
|
581
726
|
const handleClickOutside = (e) => {
|
|
582
727
|
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
583
728
|
};
|
|
@@ -611,15 +756,15 @@ function OrgSwitcher() {
|
|
|
611
756
|
}
|
|
612
757
|
|
|
613
758
|
// src/components/VerifiedBadge.tsx
|
|
614
|
-
var
|
|
759
|
+
var import_react10 = require("react");
|
|
615
760
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
616
761
|
var CACHE_TTL = 5 * 60 * 1e3;
|
|
617
762
|
var cache = /* @__PURE__ */ new Map();
|
|
618
763
|
function VerifiedBadge({ type, identifier, label }) {
|
|
619
764
|
const githat = useGitHat();
|
|
620
|
-
const [verified, setVerified] = (0,
|
|
621
|
-
const mounted = (0,
|
|
622
|
-
(0,
|
|
765
|
+
const [verified, setVerified] = (0, import_react10.useState)(null);
|
|
766
|
+
const mounted = (0, import_react10.useRef)(true);
|
|
767
|
+
(0, import_react10.useEffect)(() => {
|
|
623
768
|
mounted.current = true;
|
|
624
769
|
const key = `${type}:${identifier}`;
|
|
625
770
|
const cached = cache.get(key);
|
|
@@ -675,6 +820,7 @@ function ProtectedRoute({ children, fallback }) {
|
|
|
675
820
|
UserButton,
|
|
676
821
|
VerifiedBadge,
|
|
677
822
|
useAuth,
|
|
823
|
+
useData,
|
|
678
824
|
useGitHat
|
|
679
825
|
});
|
|
680
826
|
//# sourceMappingURL=index.js.map
|