@tthr/vue 0.0.23 → 0.0.25

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.
@@ -217,7 +217,7 @@ useTetherSubscription('comments.list', undefined, (data) => {
217
217
  if (!grouped[comment.postId]) {
218
218
  grouped[comment.postId] = [];
219
219
  }
220
- grouped[comment.postId].push(comment);
220
+ grouped[comment.postId]!.push(comment);
221
221
  }
222
222
  postComments.value = grouped;
223
223
  }
@@ -251,11 +251,8 @@ async function handleCreateComment(postId: string) {
251
251
 
252
252
  try {
253
253
  await createComment.mutate({
254
- id: crypto.randomUUID(),
255
254
  postId,
256
255
  content: newCommentText.value.trim(),
257
- authorId: 'demo-user',
258
- createdAt: new Date().toISOString(),
259
256
  });
260
257
  newCommentText.value = '';
261
258
  // Refresh comments for this post
@@ -298,12 +295,8 @@ async function handleCreatePost() {
298
295
 
299
296
  try {
300
297
  await createPost.mutate({
301
- id: crypto.randomUUID(),
302
298
  title: newPostTitle.value.trim(),
303
299
  content: '',
304
- authorId: 'demo-user',
305
- createdAt: new Date().toISOString(),
306
- updatedAt: new Date().toISOString(),
307
300
  });
308
301
  newPostTitle.value = '';
309
302
  await posts.refetch();
@@ -21,12 +21,18 @@ async function loadFunctionRegistry() {
21
21
  try {
22
22
  // Try to import the user's functions index
23
23
  // This path is relative to the Nuxt app's server runtime
24
- const functions = await import('~~/tether/functions/index.ts').catch(() => null);
24
+ console.log('[Tether] Loading custom functions from ~~/tether/functions/index.ts');
25
+ const functions = await import('~~/tether/functions/index.ts').catch((err) => {
26
+ console.warn('[Tether] Failed to import functions:', err.message);
27
+ return null;
28
+ });
25
29
 
26
30
  if (functions) {
31
+ console.log('[Tether] Loaded function modules:', Object.keys(functions));
27
32
  functionRegistry = functions;
28
33
  } else {
29
34
  // No custom functions found - that's OK, we'll proxy everything
35
+ console.log('[Tether] No custom functions found, will proxy all requests');
30
36
  functionRegistry = {};
31
37
  }
32
38
  } catch (error) {
@@ -234,10 +240,12 @@ export default defineEventHandler(async (event) => {
234
240
 
235
241
  // Try to find a custom function
236
242
  const customFn = lookupFunction(body.function);
243
+ console.log(`[Tether] Mutation: ${body.function}, custom function found: ${!!customFn}`);
237
244
 
238
245
  if (customFn) {
239
246
  // Execute locally with database proxy
240
247
  try {
248
+ console.log(`[Tether] Executing custom mutation: ${body.function}`);
241
249
  const db = createDatabaseProxy(apiKey, url, projectId);
242
250
 
243
251
  // Create auth context - try to get user identity from request
@@ -247,24 +255,29 @@ export default defineEventHandler(async (event) => {
247
255
  const authHeader = getHeader(event, 'authorization');
248
256
  const strandsToken = getHeader(event, 'x-strands-token');
249
257
 
250
- // If using Strands auth, try to validate the token
258
+ // If using Strands auth, validate the token via Tether server
251
259
  if (strandsToken || authHeader?.startsWith('Bearer ')) {
252
260
  const token = strandsToken || authHeader?.replace('Bearer ', '');
253
261
  if (token) {
254
262
  try {
255
- // Try to fetch user identity from Strands auth service
256
- const authResponse = await fetch('https://accounts.strands.gg/api/auth/me', {
257
- headers: { 'Authorization': `Bearer ${token}` },
263
+ // Validate token via Tether server (which checks if Strands Auth is enabled)
264
+ const authResponse = await fetch(`${url}/api/v1/projects/${projectId}/auth/validate`, {
265
+ method: 'POST',
266
+ headers: { 'Content-Type': 'application/json' },
267
+ body: JSON.stringify({ accessToken: token }),
258
268
  });
259
269
  if (authResponse.ok) {
260
- const userData = await authResponse.json();
261
- userIdentity = {
262
- subject: userData.id || userData.sub,
263
- email: userData.email,
264
- ...userData,
265
- };
270
+ const authData = await authResponse.json();
271
+ if (authData.valid) {
272
+ userIdentity = {
273
+ subject: authData.userId,
274
+ email: authData.email,
275
+ name: authData.name,
276
+ };
277
+ }
266
278
  }
267
- } catch {
279
+ } catch (authError) {
280
+ console.warn('[Tether] Auth validation failed:', authError.message);
268
281
  // Auth validation failed - continue without identity
269
282
  }
270
283
  }
@@ -291,9 +304,11 @@ export default defineEventHandler(async (event) => {
291
304
 
292
305
  return { data: result };
293
306
  } catch (error) {
307
+ console.error(`[Tether] Mutation ${body.function} failed:`, error);
294
308
  throw createError({
295
309
  statusCode: 500,
296
310
  message: error.message || 'Mutation execution failed',
311
+ data: { function: body.function, error: String(error) },
297
312
  });
298
313
  }
299
314
  }
@@ -255,24 +255,29 @@ export default defineEventHandler(async (event) => {
255
255
  const authHeader = getHeader(event, 'authorization');
256
256
  const strandsToken = getHeader(event, 'x-strands-token');
257
257
 
258
- // If using Strands auth, try to validate the token
258
+ // If using Strands auth, validate the token via Tether server
259
259
  if (strandsToken || authHeader?.startsWith('Bearer ')) {
260
260
  const token = strandsToken || authHeader?.replace('Bearer ', '');
261
261
  if (token) {
262
262
  try {
263
- // Try to fetch user identity from Strands auth service
264
- const authResponse = await fetch('https://accounts.strands.gg/api/auth/me', {
265
- headers: { 'Authorization': `Bearer ${token}` },
263
+ // Validate token via Tether server (which checks if Strands Auth is enabled)
264
+ const authResponse = await fetch(`${url}/api/v1/projects/${projectId}/auth/validate`, {
265
+ method: 'POST',
266
+ headers: { 'Content-Type': 'application/json' },
267
+ body: JSON.stringify({ accessToken: token }),
266
268
  });
267
269
  if (authResponse.ok) {
268
- const userData = await authResponse.json();
269
- userIdentity = {
270
- subject: userData.id || userData.sub,
271
- email: userData.email,
272
- ...userData,
273
- };
270
+ const authData = await authResponse.json();
271
+ if (authData.valid) {
272
+ userIdentity = {
273
+ subject: authData.userId,
274
+ email: authData.email,
275
+ name: authData.name,
276
+ };
277
+ }
274
278
  }
275
- } catch {
279
+ } catch (authError) {
280
+ console.warn('[Tether] Auth validation failed:', authError.message);
276
281
  // Auth validation failed - continue without identity
277
282
  }
278
283
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tthr/vue",
3
- "version": "0.0.23",
3
+ "version": "0.0.25",
4
4
  "description": "Tether Vue/Nuxt SDK",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -22,11 +22,6 @@
22
22
  "dist",
23
23
  "nuxt"
24
24
  ],
25
- "scripts": {
26
- "build": "tsc",
27
- "dev": "tsc --watch",
28
- "typecheck": "tsc --noEmit"
29
- },
30
25
  "dependencies": {
31
26
  "@nuxt/kit": "^3.14.0",
32
27
  "@tthr/client": "latest",
@@ -37,5 +32,10 @@
37
32
  },
38
33
  "peerDependencies": {
39
34
  "vue": "^3.0.0"
35
+ },
36
+ "scripts": {
37
+ "build": "tsc",
38
+ "dev": "tsc --watch",
39
+ "typecheck": "tsc --noEmit"
40
40
  }
41
- }
41
+ }