@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.mjs
CHANGED
|
@@ -18,15 +18,16 @@ function resolveConfig(config) {
|
|
|
18
18
|
signInUrl: config.signInUrl || "/sign-in",
|
|
19
19
|
signUpUrl: config.signUpUrl || "/sign-up",
|
|
20
20
|
afterSignInUrl: config.afterSignInUrl || "/dashboard",
|
|
21
|
-
afterSignOutUrl: config.afterSignOutUrl || "/"
|
|
21
|
+
afterSignOutUrl: config.afterSignOutUrl || "/",
|
|
22
|
+
tokenStorage: config.tokenStorage || "localStorage"
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
// src/client.ts
|
|
26
27
|
var _refreshPromise = null;
|
|
27
|
-
async function refreshTokens(apiUrl, appKey) {
|
|
28
|
-
const refreshToken = typeof window !== "undefined" ? localStorage.getItem(TOKEN_KEYS.refreshToken) : null;
|
|
29
|
-
if (!refreshToken) return false;
|
|
28
|
+
async function refreshTokens(apiUrl, appKey, useCookies) {
|
|
29
|
+
const refreshToken = typeof window !== "undefined" && !useCookies ? localStorage.getItem(TOKEN_KEYS.refreshToken) : null;
|
|
30
|
+
if (!useCookies && !refreshToken) return false;
|
|
30
31
|
let orgId = null;
|
|
31
32
|
try {
|
|
32
33
|
const orgStr = localStorage.getItem(TOKEN_KEYS.org);
|
|
@@ -34,18 +35,22 @@ async function refreshTokens(apiUrl, appKey) {
|
|
|
34
35
|
} catch {
|
|
35
36
|
}
|
|
36
37
|
try {
|
|
37
|
-
const
|
|
38
|
+
const refreshUrl = useCookies ? `${apiUrl}/auth/refresh?setCookie=true` : `${apiUrl}/auth/refresh`;
|
|
39
|
+
const res = await fetch(refreshUrl, {
|
|
38
40
|
method: "POST",
|
|
39
41
|
headers: {
|
|
40
42
|
"Content-Type": "application/json",
|
|
41
43
|
"X-GitHat-App-Key": appKey
|
|
42
44
|
},
|
|
43
|
-
|
|
45
|
+
credentials: useCookies ? "include" : "same-origin",
|
|
46
|
+
body: JSON.stringify(useCookies ? { orgId } : { refreshToken, orgId })
|
|
44
47
|
});
|
|
45
48
|
if (!res.ok) return false;
|
|
46
49
|
const data = await res.json();
|
|
47
|
-
if (
|
|
48
|
-
|
|
50
|
+
if (!useCookies) {
|
|
51
|
+
if (data.accessToken) localStorage.setItem(TOKEN_KEYS.accessToken, data.accessToken);
|
|
52
|
+
if (data.refreshToken) localStorage.setItem(TOKEN_KEYS.refreshToken, data.refreshToken);
|
|
53
|
+
}
|
|
49
54
|
if (data.org) localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.org));
|
|
50
55
|
return true;
|
|
51
56
|
} catch {
|
|
@@ -55,23 +60,30 @@ async function refreshTokens(apiUrl, appKey) {
|
|
|
55
60
|
function clearAuth() {
|
|
56
61
|
if (typeof window === "undefined") return;
|
|
57
62
|
Object.values(TOKEN_KEYS).forEach((key) => localStorage.removeItem(key));
|
|
58
|
-
window.dispatchEvent(
|
|
59
|
-
|
|
60
|
-
|
|
63
|
+
window.dispatchEvent(
|
|
64
|
+
new CustomEvent("githat:auth-changed", {
|
|
65
|
+
detail: { user: null, org: null, signedIn: false }
|
|
66
|
+
})
|
|
67
|
+
);
|
|
61
68
|
}
|
|
62
|
-
function createClient(apiUrl, appKey) {
|
|
63
|
-
|
|
69
|
+
function createClient(apiUrl, appKey, options = {}) {
|
|
70
|
+
const { useCookies = false } = options;
|
|
71
|
+
async function fetchApi(endpoint, fetchOptions = {}) {
|
|
64
72
|
const url = `${apiUrl}${endpoint}`;
|
|
65
|
-
const token = typeof window !== "undefined" ? localStorage.getItem(TOKEN_KEYS.accessToken) : null;
|
|
73
|
+
const token = typeof window !== "undefined" && !useCookies ? localStorage.getItem(TOKEN_KEYS.accessToken) : null;
|
|
66
74
|
const headers = {
|
|
67
75
|
"Content-Type": "application/json",
|
|
68
76
|
"X-GitHat-App-Key": appKey,
|
|
69
77
|
...token && { Authorization: `Bearer ${token}` },
|
|
70
|
-
...
|
|
78
|
+
...fetchOptions.headers
|
|
71
79
|
};
|
|
72
80
|
let response;
|
|
73
81
|
try {
|
|
74
|
-
response = await fetch(url, {
|
|
82
|
+
response = await fetch(url, {
|
|
83
|
+
...fetchOptions,
|
|
84
|
+
headers,
|
|
85
|
+
credentials: useCookies ? "include" : "same-origin"
|
|
86
|
+
});
|
|
75
87
|
} catch (networkError) {
|
|
76
88
|
if (networkError instanceof TypeError) {
|
|
77
89
|
const isMissingKey = !appKey || !appKey.startsWith("pk_live_");
|
|
@@ -81,27 +93,26 @@ function createClient(apiUrl, appKey) {
|
|
|
81
93
|
"Missing GitHat API key. Add NEXT_PUBLIC_GITHAT_PUBLISHABLE_KEY to .env.local"
|
|
82
94
|
);
|
|
83
95
|
}
|
|
84
|
-
throw new Error(
|
|
85
|
-
"Unable to connect to GitHat API. Check your network connection."
|
|
86
|
-
);
|
|
96
|
+
throw new Error("Unable to connect to GitHat API. Check your network connection.");
|
|
87
97
|
}
|
|
88
98
|
throw networkError;
|
|
89
99
|
}
|
|
90
100
|
if (response.status === 401) {
|
|
91
101
|
if (!_refreshPromise) {
|
|
92
|
-
_refreshPromise = refreshTokens(apiUrl, appKey).finally(() => {
|
|
102
|
+
_refreshPromise = refreshTokens(apiUrl, appKey, useCookies).finally(() => {
|
|
93
103
|
_refreshPromise = null;
|
|
94
104
|
});
|
|
95
105
|
}
|
|
96
106
|
const refreshed = await _refreshPromise;
|
|
97
107
|
if (refreshed) {
|
|
98
|
-
const newToken = localStorage.getItem(TOKEN_KEYS.accessToken);
|
|
108
|
+
const newToken = !useCookies && typeof window !== "undefined" ? localStorage.getItem(TOKEN_KEYS.accessToken) : null;
|
|
99
109
|
const retryResponse = await fetch(url, {
|
|
100
|
-
...
|
|
110
|
+
...fetchOptions,
|
|
101
111
|
headers: {
|
|
102
112
|
...headers,
|
|
103
113
|
...newToken && { Authorization: `Bearer ${newToken}` }
|
|
104
|
-
}
|
|
114
|
+
},
|
|
115
|
+
credentials: useCookies ? "include" : "same-origin"
|
|
105
116
|
});
|
|
106
117
|
const retryData = await retryResponse.json();
|
|
107
118
|
if (!retryResponse.ok) throw new Error(retryData.error || "Request failed");
|
|
@@ -122,38 +133,57 @@ import { jsx } from "react/jsx-runtime";
|
|
|
122
133
|
var GitHatContext = createContext(null);
|
|
123
134
|
function GitHatProvider({ config: rawConfig, children }) {
|
|
124
135
|
const config = useMemo(() => resolveConfig(rawConfig), [rawConfig]);
|
|
125
|
-
const
|
|
136
|
+
const useCookies = config.tokenStorage === "cookie";
|
|
137
|
+
const clientRef = useRef(createClient(config.apiUrl, config.publishableKey, { useCookies }));
|
|
126
138
|
const [user, setUser] = useState(null);
|
|
127
139
|
const [org, setOrg] = useState(null);
|
|
128
140
|
const [isSignedIn, setIsSignedIn] = useState(false);
|
|
129
141
|
const [isLoading, setIsLoading] = useState(true);
|
|
130
142
|
const [authError, setAuthError] = useState(null);
|
|
131
143
|
useEffect(() => {
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (
|
|
144
|
+
const validateSession = async () => {
|
|
145
|
+
try {
|
|
146
|
+
if (!useCookies) {
|
|
147
|
+
const token = localStorage.getItem(TOKEN_KEYS.accessToken);
|
|
148
|
+
const storedUser = localStorage.getItem(TOKEN_KEYS.user);
|
|
149
|
+
if (!token || !storedUser) {
|
|
150
|
+
setIsLoading(false);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const data = await clientRef.current.fetchApi("/auth/me");
|
|
155
|
+
if (data.user) {
|
|
156
|
+
setUser(data.user);
|
|
157
|
+
setOrg(data.currentOrg || null);
|
|
158
|
+
setIsSignedIn(true);
|
|
159
|
+
setAuthError(null);
|
|
160
|
+
if (!useCookies) {
|
|
161
|
+
localStorage.setItem(TOKEN_KEYS.user, JSON.stringify(data.user));
|
|
162
|
+
if (data.currentOrg) {
|
|
163
|
+
localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.currentOrg));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
} catch (err) {
|
|
168
|
+
const error = err;
|
|
169
|
+
if (error.message === "Session expired") {
|
|
144
170
|
clientRef.current.clearAuth();
|
|
145
|
-
} else {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
171
|
+
} else if (!useCookies) {
|
|
172
|
+
const storedUser = localStorage.getItem(TOKEN_KEYS.user);
|
|
173
|
+
if (storedUser) {
|
|
174
|
+
try {
|
|
175
|
+
setUser(JSON.parse(storedUser));
|
|
176
|
+
setIsSignedIn(true);
|
|
177
|
+
} catch {
|
|
178
|
+
}
|
|
149
179
|
}
|
|
150
|
-
setAuthError(
|
|
180
|
+
setAuthError(error.message || "Failed to verify session");
|
|
151
181
|
}
|
|
152
|
-
}
|
|
153
|
-
} else {
|
|
182
|
+
}
|
|
154
183
|
setIsLoading(false);
|
|
155
|
-
}
|
|
156
|
-
|
|
184
|
+
};
|
|
185
|
+
validateSession();
|
|
186
|
+
}, [useCookies]);
|
|
157
187
|
useEffect(() => {
|
|
158
188
|
const handleAuthChanged = (e) => {
|
|
159
189
|
const detail = e.detail;
|
|
@@ -171,30 +201,36 @@ function GitHatProvider({ config: rawConfig, children }) {
|
|
|
171
201
|
return () => window.removeEventListener("githat:auth-changed", handleAuthChanged);
|
|
172
202
|
}, []);
|
|
173
203
|
const signIn = useCallback(async (email, password) => {
|
|
174
|
-
const
|
|
204
|
+
const loginUrl = useCookies ? "/auth/login?setCookie=true" : "/auth/login";
|
|
205
|
+
const data = await clientRef.current.fetchApi(loginUrl, {
|
|
175
206
|
method: "POST",
|
|
176
207
|
body: JSON.stringify({ email, password })
|
|
177
208
|
});
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
209
|
+
if (!useCookies && data.accessToken && data.refreshToken) {
|
|
210
|
+
localStorage.setItem(TOKEN_KEYS.accessToken, data.accessToken);
|
|
211
|
+
localStorage.setItem(TOKEN_KEYS.refreshToken, data.refreshToken);
|
|
212
|
+
localStorage.setItem(TOKEN_KEYS.user, JSON.stringify(data.user));
|
|
213
|
+
if (data.org) localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.org));
|
|
214
|
+
}
|
|
182
215
|
setUser(data.user);
|
|
183
216
|
setOrg(data.org || null);
|
|
184
217
|
setIsSignedIn(true);
|
|
185
218
|
window.dispatchEvent(new CustomEvent("githat:auth-changed", {
|
|
186
219
|
detail: { user: data.user, org: data.org, signedIn: true }
|
|
187
220
|
}));
|
|
188
|
-
}, []);
|
|
221
|
+
}, [useCookies]);
|
|
189
222
|
const signUp = useCallback(async (signUpData) => {
|
|
190
|
-
const
|
|
223
|
+
const registerUrl = useCookies ? "/auth/register?setCookie=true" : "/auth/register";
|
|
224
|
+
const data = await clientRef.current.fetchApi(registerUrl, {
|
|
191
225
|
method: "POST",
|
|
192
226
|
body: JSON.stringify(signUpData)
|
|
193
227
|
});
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
228
|
+
if (!useCookies && data.accessToken && data.refreshToken) {
|
|
229
|
+
localStorage.setItem(TOKEN_KEYS.accessToken, data.accessToken);
|
|
230
|
+
localStorage.setItem(TOKEN_KEYS.refreshToken, data.refreshToken);
|
|
231
|
+
localStorage.setItem(TOKEN_KEYS.user, JSON.stringify(data.user));
|
|
232
|
+
if (data.org) localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.org));
|
|
233
|
+
}
|
|
198
234
|
setUser(data.user);
|
|
199
235
|
setOrg(data.org || null);
|
|
200
236
|
setIsSignedIn(true);
|
|
@@ -202,10 +238,11 @@ function GitHatProvider({ config: rawConfig, children }) {
|
|
|
202
238
|
detail: { user: data.user, org: data.org, signedIn: true }
|
|
203
239
|
}));
|
|
204
240
|
return { requiresVerification: !data.user.emailVerified, email: signUpData.email };
|
|
205
|
-
}, []);
|
|
241
|
+
}, [useCookies]);
|
|
206
242
|
const signOut = useCallback(async () => {
|
|
207
243
|
try {
|
|
208
|
-
|
|
244
|
+
const logoutUrl = useCookies ? "/auth/logout?setCookie=true" : "/auth/logout";
|
|
245
|
+
await clientRef.current.fetchApi(logoutUrl, { method: "POST" });
|
|
209
246
|
} catch {
|
|
210
247
|
}
|
|
211
248
|
clientRef.current.clearAuth();
|
|
@@ -215,22 +252,24 @@ function GitHatProvider({ config: rawConfig, children }) {
|
|
|
215
252
|
if (typeof window !== "undefined" && config.afterSignOutUrl) {
|
|
216
253
|
window.location.href = config.afterSignOutUrl;
|
|
217
254
|
}
|
|
218
|
-
}, [config.afterSignOutUrl]);
|
|
255
|
+
}, [config.afterSignOutUrl, useCookies]);
|
|
219
256
|
const switchOrg = useCallback(async (orgId) => {
|
|
220
257
|
try {
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
if (
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
258
|
+
const switchUrl = useCookies ? `/user/orgs/${orgId}/switch?setCookie=true` : `/user/orgs/${orgId}/switch`;
|
|
259
|
+
const data = await clientRef.current.fetchApi(switchUrl, { method: "POST" });
|
|
260
|
+
if (!useCookies) {
|
|
261
|
+
if (data.accessToken) localStorage.setItem(TOKEN_KEYS.accessToken, data.accessToken);
|
|
262
|
+
if (data.refreshToken) localStorage.setItem(TOKEN_KEYS.refreshToken, data.refreshToken);
|
|
263
|
+
localStorage.setItem(TOKEN_KEYS.org, JSON.stringify(data.org));
|
|
264
|
+
}
|
|
265
|
+
setOrg(data.org);
|
|
227
266
|
window.dispatchEvent(new CustomEvent("githat:auth-changed", {
|
|
228
|
-
detail: { user, org:
|
|
267
|
+
detail: { user, org: data.org, signedIn: true }
|
|
229
268
|
}));
|
|
230
269
|
} catch (e) {
|
|
231
270
|
console.error("Org switch failed:", e);
|
|
232
271
|
}
|
|
233
|
-
}, [user]);
|
|
272
|
+
}, [user, useCookies]);
|
|
234
273
|
const value = useMemo(() => ({
|
|
235
274
|
user,
|
|
236
275
|
org,
|
|
@@ -247,7 +286,7 @@ function GitHatProvider({ config: rawConfig, children }) {
|
|
|
247
286
|
}
|
|
248
287
|
|
|
249
288
|
// src/hooks.ts
|
|
250
|
-
import { useContext, useMemo as useMemo2 } from "react";
|
|
289
|
+
import { useContext, useMemo as useMemo2, useCallback as useCallback2 } from "react";
|
|
251
290
|
function useAuth() {
|
|
252
291
|
const ctx = useContext(GitHatContext);
|
|
253
292
|
if (!ctx) throw new Error("useAuth must be used within a <GitHatProvider>");
|
|
@@ -259,14 +298,119 @@ function useGitHat() {
|
|
|
259
298
|
() => createClient(ctx.config.apiUrl, ctx.config.publishableKey),
|
|
260
299
|
[ctx.config.apiUrl, ctx.config.publishableKey]
|
|
261
300
|
);
|
|
301
|
+
const getOrgMetadata = useCallback2(async () => {
|
|
302
|
+
if (!ctx.org?.id) {
|
|
303
|
+
throw new Error("No active organization");
|
|
304
|
+
}
|
|
305
|
+
const response = await client.fetchApi(
|
|
306
|
+
`/orgs/${ctx.org.id}/metadata`
|
|
307
|
+
);
|
|
308
|
+
return response.metadata || {};
|
|
309
|
+
}, [client, ctx.org?.id]);
|
|
310
|
+
const updateOrgMetadata = useCallback2(
|
|
311
|
+
async (updates) => {
|
|
312
|
+
if (!ctx.org?.id) {
|
|
313
|
+
throw new Error("No active organization");
|
|
314
|
+
}
|
|
315
|
+
const response = await client.fetchApi(
|
|
316
|
+
`/orgs/${ctx.org.id}/metadata`,
|
|
317
|
+
{
|
|
318
|
+
method: "PATCH",
|
|
319
|
+
body: JSON.stringify(updates)
|
|
320
|
+
}
|
|
321
|
+
);
|
|
322
|
+
return response.metadata || {};
|
|
323
|
+
},
|
|
324
|
+
[client, ctx.org?.id]
|
|
325
|
+
);
|
|
262
326
|
return {
|
|
263
327
|
fetch: client.fetchApi,
|
|
264
328
|
getUserOrgs: () => client.fetchApi("/user/orgs"),
|
|
265
329
|
verifyMCP: (domain) => client.fetchApi(`/verify/mcp/${domain}`),
|
|
266
|
-
verifyAgent: (wallet) => client.fetchApi(`/verify/agent/${wallet}`)
|
|
330
|
+
verifyAgent: (wallet) => client.fetchApi(`/verify/agent/${wallet}`),
|
|
331
|
+
getOrgMetadata,
|
|
332
|
+
updateOrgMetadata
|
|
267
333
|
};
|
|
268
334
|
}
|
|
269
335
|
|
|
336
|
+
// src/data.ts
|
|
337
|
+
import { useMemo as useMemo3 } from "react";
|
|
338
|
+
function useData() {
|
|
339
|
+
const ctx = useAuth();
|
|
340
|
+
const client = useMemo3(
|
|
341
|
+
() => createClient(ctx.config.apiUrl, ctx.config.publishableKey),
|
|
342
|
+
[ctx.config.apiUrl, ctx.config.publishableKey]
|
|
343
|
+
);
|
|
344
|
+
return useMemo3(() => ({
|
|
345
|
+
/**
|
|
346
|
+
* Store an item in a collection. If the item exists, it will be updated.
|
|
347
|
+
* @param collection - Collection name (e.g., 'orders', 'users')
|
|
348
|
+
* @param data - Data object with required `id` field
|
|
349
|
+
*/
|
|
350
|
+
put: async (collection, data) => {
|
|
351
|
+
if (!data.id) {
|
|
352
|
+
throw new Error('Data must include an "id" field');
|
|
353
|
+
}
|
|
354
|
+
return client.fetchApi(`/data/${collection}/${data.id}`, {
|
|
355
|
+
method: "PUT",
|
|
356
|
+
body: JSON.stringify(data)
|
|
357
|
+
});
|
|
358
|
+
},
|
|
359
|
+
/**
|
|
360
|
+
* Get a single item from a collection.
|
|
361
|
+
* @param collection - Collection name
|
|
362
|
+
* @param id - Item ID
|
|
363
|
+
*/
|
|
364
|
+
get: async (collection, id) => {
|
|
365
|
+
try {
|
|
366
|
+
const result = await client.fetchApi(`/data/${collection}/${id}`);
|
|
367
|
+
return result.item;
|
|
368
|
+
} catch (err) {
|
|
369
|
+
if (err instanceof Error && err.message === "Item not found") {
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
throw err;
|
|
373
|
+
}
|
|
374
|
+
},
|
|
375
|
+
/**
|
|
376
|
+
* Query items from a collection with optional filters and pagination.
|
|
377
|
+
* @param collection - Collection name
|
|
378
|
+
* @param options - Query options (limit, cursor, filter)
|
|
379
|
+
*/
|
|
380
|
+
query: async (collection, options = {}) => {
|
|
381
|
+
const params = new URLSearchParams();
|
|
382
|
+
if (options.limit) params.set("limit", options.limit.toString());
|
|
383
|
+
if (options.cursor) params.set("cursor", options.cursor);
|
|
384
|
+
if (options.filter) params.set("filter", JSON.stringify(options.filter));
|
|
385
|
+
const queryString = params.toString();
|
|
386
|
+
const url = `/data/${collection}${queryString ? `?${queryString}` : ""}`;
|
|
387
|
+
return client.fetchApi(url);
|
|
388
|
+
},
|
|
389
|
+
/**
|
|
390
|
+
* Delete an item from a collection.
|
|
391
|
+
* @param collection - Collection name
|
|
392
|
+
* @param id - Item ID
|
|
393
|
+
*/
|
|
394
|
+
remove: async (collection, id) => {
|
|
395
|
+
return client.fetchApi(`/data/${collection}/${id}`, {
|
|
396
|
+
method: "DELETE"
|
|
397
|
+
});
|
|
398
|
+
},
|
|
399
|
+
/**
|
|
400
|
+
* Batch operations (put/delete) on a collection.
|
|
401
|
+
* Maximum 100 operations per request.
|
|
402
|
+
* @param collection - Collection name
|
|
403
|
+
* @param operations - Array of operations
|
|
404
|
+
*/
|
|
405
|
+
batch: async (collection, operations) => {
|
|
406
|
+
return client.fetchApi(`/data/${collection}/batch`, {
|
|
407
|
+
method: "POST",
|
|
408
|
+
body: JSON.stringify({ operations })
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
}), [client]);
|
|
412
|
+
}
|
|
413
|
+
|
|
270
414
|
// src/components/SignInForm.tsx
|
|
271
415
|
import { useState as useState2 } from "react";
|
|
272
416
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
@@ -639,6 +783,7 @@ export {
|
|
|
639
783
|
UserButton,
|
|
640
784
|
VerifiedBadge,
|
|
641
785
|
useAuth,
|
|
786
|
+
useData,
|
|
642
787
|
useGitHat
|
|
643
788
|
};
|
|
644
789
|
//# sourceMappingURL=index.mjs.map
|