@tthr/vue 0.0.83 → 0.0.85

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 (36) hide show
  1. package/nuxt/module.js +7 -9
  2. package/nuxt/module.ts +7 -9
  3. package/nuxt/runtime/composables.ts +638 -0
  4. package/nuxt/runtime/plugin.client.ts +34 -0
  5. package/nuxt/runtime/server/mutation.post.ts +53 -0
  6. package/nuxt/runtime/server/plugins/cron.ts +377 -0
  7. package/nuxt/runtime/server/query.post.ts +51 -0
  8. package/nuxt/runtime/server/utils/handler.ts +375 -0
  9. package/nuxt/runtime/server/utils/{tether.js → tether.ts} +78 -29
  10. package/package.json +6 -9
  11. package/dist/nuxt.d.ts +0 -14
  12. package/dist/nuxt.d.ts.map +0 -1
  13. package/dist/nuxt.js +0 -48
  14. package/dist/nuxt.js.map +0 -1
  15. package/dist/runtime/composables.d.ts +0 -73
  16. package/dist/runtime/composables.d.ts.map +0 -1
  17. package/dist/runtime/composables.js +0 -112
  18. package/dist/runtime/composables.js.map +0 -1
  19. package/dist/runtime/plugin.d.ts +0 -11
  20. package/dist/runtime/plugin.d.ts.map +0 -1
  21. package/dist/runtime/plugin.js +0 -33
  22. package/dist/runtime/plugin.js.map +0 -1
  23. package/nuxt/runtime/composables.d.ts +0 -142
  24. package/nuxt/runtime/composables.d.ts.map +0 -1
  25. package/nuxt/runtime/composables.js +0 -414
  26. package/nuxt/runtime/composables.js.map +0 -1
  27. package/nuxt/runtime/plugin.client.d.ts +0 -17
  28. package/nuxt/runtime/plugin.client.d.ts.map +0 -1
  29. package/nuxt/runtime/plugin.client.js +0 -21
  30. package/nuxt/runtime/plugin.client.js.map +0 -1
  31. package/nuxt/runtime/server/mutation.post.js +0 -373
  32. package/nuxt/runtime/server/plugins/cron.d.ts +0 -38
  33. package/nuxt/runtime/server/plugins/cron.d.ts.map +0 -1
  34. package/nuxt/runtime/server/plugins/cron.js +0 -621
  35. package/nuxt/runtime/server/plugins/cron.js.map +0 -1
  36. package/nuxt/runtime/server/query.post.js +0 -372
@@ -0,0 +1,375 @@
1
+ /**
2
+ * Shared handler utilities for Tether server routes
3
+ *
4
+ * Provides function registry loading, database proxy creation,
5
+ * auth context building, and logging — used by both query and mutation handlers.
6
+ */
7
+
8
+ import { createError, getHeader, getCookie, type H3Event } from 'h3';
9
+ import { useRuntimeConfig } from '#imports';
10
+
11
+ // ============================================================================
12
+ // Logging
13
+ // ============================================================================
14
+
15
+ let verboseLogging = false;
16
+ const PREFIX = '[Tether]';
17
+
18
+ export const log = {
19
+ debug: (...args: unknown[]) => { if (verboseLogging) console.log(PREFIX, ...args); },
20
+ info: (...args: unknown[]) => console.log(PREFIX, ...args),
21
+ warn: (...args: unknown[]) => console.warn(PREFIX, ...args),
22
+ error: (...args: unknown[]) => console.error(PREFIX, ...args),
23
+ };
24
+
25
+ // ============================================================================
26
+ // Config
27
+ // ============================================================================
28
+
29
+ export interface TetherServerConfig {
30
+ apiKey: string;
31
+ url: string;
32
+ projectId: string;
33
+ }
34
+
35
+ /**
36
+ * Read and validate Tether config from runtime config + env vars.
37
+ * Throws H3 errors if required values are missing.
38
+ */
39
+ export function getConfig(): TetherServerConfig {
40
+ const config = useRuntimeConfig();
41
+ verboseLogging = config.tether?.verbose || process.env.TETHER_VERBOSE === 'true';
42
+
43
+ const apiKey = config.tether?.apiKey || process.env.TETHER_API_KEY;
44
+ const url = config.tether?.url || process.env.TETHER_URL || 'https://tether-api.strands.gg';
45
+ const projectId = config.tether?.projectId || process.env.TETHER_PROJECT_ID;
46
+
47
+ if (!apiKey) {
48
+ throw createError({
49
+ statusCode: 500,
50
+ message: 'Tether API key not configured. Set TETHER_API_KEY environment variable.',
51
+ });
52
+ }
53
+
54
+ if (!projectId) {
55
+ throw createError({
56
+ statusCode: 500,
57
+ message: 'Tether project ID not configured.',
58
+ });
59
+ }
60
+
61
+ return { apiKey, url, projectId };
62
+ }
63
+
64
+ // ============================================================================
65
+ // Function Registry
66
+ // ============================================================================
67
+
68
+ interface TetherFunction {
69
+ handler: (ctx: unknown) => Promise<unknown>;
70
+ [key: string]: unknown;
71
+ }
72
+
73
+ type FunctionRegistry = Record<string, Record<string, TetherFunction>>;
74
+
75
+ let functionRegistry: FunctionRegistry | null = null;
76
+ let registryError: Error | null = null;
77
+
78
+ /**
79
+ * Load the user's custom functions from ~/tether/functions (once).
80
+ */
81
+ async function loadFunctionRegistry(): Promise<void> {
82
+ if (functionRegistry !== null || registryError !== null) return;
83
+
84
+ try {
85
+ log.debug('Loading custom functions from ~~/tether/functions/index.ts');
86
+ const functions = await import('~~/tether/functions/index.ts').catch((err: Error) => {
87
+ log.debug('Failed to import functions:', err.message);
88
+ return null;
89
+ });
90
+
91
+ if (functions) {
92
+ log.debug('Loaded function modules:', Object.keys(functions));
93
+ functionRegistry = functions as FunctionRegistry;
94
+ } else {
95
+ log.debug('No custom functions found, will proxy all requests');
96
+ functionRegistry = {};
97
+ }
98
+ } catch (error: unknown) {
99
+ const err = error instanceof Error ? error : new Error(String(error));
100
+ log.debug('Could not load custom functions:', err.message);
101
+ registryError = err;
102
+ functionRegistry = {};
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Look up a function by name (e.g. "channel.getMyChannels").
108
+ * Returns null if no custom function is registered.
109
+ */
110
+ export async function lookupFunction(name: string): Promise<TetherFunction | null> {
111
+ await loadFunctionRegistry();
112
+
113
+ if (!functionRegistry || !name) return null;
114
+
115
+ const parts = name.split('.');
116
+ if (parts.length !== 2) return null;
117
+
118
+ const [moduleName, fnName] = parts;
119
+ const mod = functionRegistry[moduleName];
120
+ if (!mod) return null;
121
+
122
+ const fn = mod[fnName];
123
+ if (fn && typeof fn === 'object' && typeof fn.handler === 'function') {
124
+ return fn;
125
+ }
126
+
127
+ return null;
128
+ }
129
+
130
+ // ============================================================================
131
+ // Database Proxy
132
+ // ============================================================================
133
+
134
+ /**
135
+ * Create a database proxy that routes calls to Tether's CRUD endpoints.
136
+ */
137
+ export function createDatabaseProxy(apiKey: string, url: string, projectId: string) {
138
+ return new Proxy({} as Record<string, unknown>, {
139
+ get(_target, tableName: string) {
140
+ const makeRequest = async (operation: string, args: Record<string, unknown>) => {
141
+ const response = await fetch(`${url}/api/v1/projects/${projectId}/query`, {
142
+ method: 'POST',
143
+ headers: {
144
+ 'Content-Type': 'application/json',
145
+ 'Authorization': `Bearer ${apiKey}`,
146
+ },
147
+ body: JSON.stringify({
148
+ function: `${tableName}.${operation}`,
149
+ args,
150
+ }),
151
+ });
152
+
153
+ if (!response.ok) {
154
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
155
+ throw new Error(error.error || `Database operation failed: ${tableName}.${operation}`);
156
+ }
157
+
158
+ const result = await response.json();
159
+ return result.data;
160
+ };
161
+
162
+ const makeMutation = async (operation: string, args: Record<string, unknown>) => {
163
+ const response = await fetch(`${url}/api/v1/projects/${projectId}/mutation`, {
164
+ method: 'POST',
165
+ headers: {
166
+ 'Content-Type': 'application/json',
167
+ 'Authorization': `Bearer ${apiKey}`,
168
+ },
169
+ body: JSON.stringify({
170
+ function: `${tableName}.${operation}`,
171
+ args,
172
+ }),
173
+ });
174
+
175
+ if (!response.ok) {
176
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
177
+ throw new Error(error.error || `Database operation failed: ${tableName}.${operation}`);
178
+ }
179
+
180
+ const result = await response.json();
181
+ return result.data;
182
+ };
183
+
184
+ return {
185
+ findMany: async (options?: { where?: Record<string, unknown>; limit?: number; offset?: number; orderBy?: string | Record<string, string>; orderDir?: string }) => {
186
+ const args: Record<string, unknown> = {};
187
+ if (options?.where) args.where = options.where;
188
+ if (options?.limit) args.limit = options.limit;
189
+ if (options?.offset) args.offset = options.offset;
190
+ if (options?.orderBy) {
191
+ if (typeof options.orderBy === 'string') {
192
+ args.orderBy = options.orderBy;
193
+ } else if (typeof options.orderBy === 'object') {
194
+ const [column, dir] = Object.entries(options.orderBy)[0] || [];
195
+ if (column) {
196
+ args.orderBy = column;
197
+ args.orderDir = dir?.toUpperCase?.() || 'ASC';
198
+ }
199
+ }
200
+ }
201
+ if (options?.orderDir) args.orderDir = options.orderDir;
202
+ return makeRequest('list', args);
203
+ },
204
+ findFirst: async (options?: { where?: Record<string, unknown> }) => {
205
+ const args: Record<string, unknown> = { limit: 1 };
206
+ if (options?.where) args.where = options.where;
207
+ const results = await makeRequest('list', args);
208
+ return results?.[0] ?? null;
209
+ },
210
+ findUnique: async (options?: { where?: Record<string, unknown> }) => {
211
+ const args: Record<string, unknown> = { limit: 1 };
212
+ if (options?.where) args.where = options.where;
213
+ const results = await makeRequest('list', args);
214
+ return results?.[0] ?? null;
215
+ },
216
+ findById: async (id: unknown) => {
217
+ return makeRequest('get', { id });
218
+ },
219
+ count: async (options?: { where?: Record<string, unknown> }) => {
220
+ const args: Record<string, unknown> = {};
221
+ if (options?.where) args.where = options.where;
222
+ const result = await makeRequest('count', args);
223
+ return result?.count ?? 0;
224
+ },
225
+ insert: async (data: unknown) => {
226
+ return makeMutation('create', { data });
227
+ },
228
+ insertMany: async (items: unknown[]) => {
229
+ const results: unknown[] = [];
230
+ for (const data of items) {
231
+ const result = await makeMutation('create', { data });
232
+ results.push(result);
233
+ }
234
+ return results;
235
+ },
236
+ create: async (options: { data: unknown }) => {
237
+ return makeMutation('create', { data: options.data });
238
+ },
239
+ update: async (options: { where: Record<string, unknown>; data: unknown }) => {
240
+ const id = options.where?._id ?? options.where?.id;
241
+ if (!id) {
242
+ throw new Error('Update requires an _id in the where clause');
243
+ }
244
+ const result = await makeMutation('update', { id, data: options.data });
245
+ return result?.rowsAffected ?? 0;
246
+ },
247
+ upsert: async (options: { where: Record<string, unknown>; create: unknown; update: unknown }) => {
248
+ const results = await makeRequest('list', { where: options.where, limit: 1 }).catch(() => []);
249
+ const existing = results?.[0] ?? null;
250
+
251
+ if (existing) {
252
+ const id = existing._id ?? existing.id;
253
+ if (!id) {
254
+ throw new Error('Found record has no _id or id field for update');
255
+ }
256
+ await makeMutation('update', { id, data: options.update });
257
+ return { ...existing, ...options.update };
258
+ } else {
259
+ return makeMutation('create', { data: options.create });
260
+ }
261
+ },
262
+ delete: async (options: { where: Record<string, unknown> }) => {
263
+ const id = options.where?._id ?? options.where?.id;
264
+ if (id) {
265
+ const result = await makeMutation('delete', { id });
266
+ return result?.rowsAffected ?? 0;
267
+ }
268
+ const result = await makeMutation('deleteMany', { where: options.where });
269
+ return result?.rowsAffected ?? 0;
270
+ },
271
+ deleteById: async (id: unknown) => {
272
+ const result = await makeMutation('delete', { id });
273
+ return (result?.rowsAffected ?? 0) > 0;
274
+ },
275
+ };
276
+ },
277
+ });
278
+ }
279
+
280
+ // ============================================================================
281
+ // Auth Context
282
+ // ============================================================================
283
+
284
+ interface UserIdentity {
285
+ subject: string;
286
+ email?: string;
287
+ name?: string;
288
+ }
289
+
290
+ /**
291
+ * Build auth context by extracting and validating tokens from the request.
292
+ */
293
+ export async function buildAuthContext(event: H3Event, url: string, projectId: string) {
294
+ let userIdentity: UserIdentity | null = null;
295
+
296
+ const authHeader = getHeader(event, 'authorization');
297
+ const strandsToken = getHeader(event, 'x-strands-token');
298
+ const cookieToken = getCookie(event, 'strands_oauth_token');
299
+
300
+ if (strandsToken || cookieToken || authHeader?.startsWith('Bearer ')) {
301
+ const token = strandsToken || cookieToken || authHeader?.replace('Bearer ', '');
302
+ if (token) {
303
+ try {
304
+ const authResponse = await fetch(`${url}/api/v1/projects/${projectId}/auth/validate`, {
305
+ method: 'POST',
306
+ headers: { 'Content-Type': 'application/json' },
307
+ body: JSON.stringify({ accessToken: token }),
308
+ });
309
+ if (authResponse.ok) {
310
+ const authData = await authResponse.json();
311
+ if (authData.valid) {
312
+ userIdentity = {
313
+ subject: authData.userId,
314
+ email: authData.email,
315
+ name: authData.name,
316
+ };
317
+ }
318
+ }
319
+ } catch (authError: unknown) {
320
+ const err = authError instanceof Error ? authError : new Error(String(authError));
321
+ log.warn('Auth validation failed:', err.message);
322
+ }
323
+ }
324
+ }
325
+
326
+ const auth = {
327
+ getUserIdentity: async () => userIdentity,
328
+ };
329
+
330
+ const ctx = {
331
+ auth: {
332
+ userId: userIdentity?.subject ?? null,
333
+ claims: userIdentity ?? {},
334
+ },
335
+ userId: userIdentity?.subject ?? null,
336
+ };
337
+
338
+ return { auth, ctx };
339
+ }
340
+
341
+ // ============================================================================
342
+ // Proxy to Tether API
343
+ // ============================================================================
344
+
345
+ /**
346
+ * Proxy a request directly to the Tether API (for generic CRUD when no custom function exists).
347
+ */
348
+ export async function proxyToTetherApi(
349
+ config: TetherServerConfig,
350
+ endpoint: 'query' | 'mutation',
351
+ functionName: string,
352
+ args: unknown
353
+ ) {
354
+ const response = await fetch(`${config.url}/api/v1/projects/${config.projectId}/${endpoint}`, {
355
+ method: 'POST',
356
+ headers: {
357
+ 'Content-Type': 'application/json',
358
+ 'Authorization': `Bearer ${config.apiKey}`,
359
+ },
360
+ body: JSON.stringify({
361
+ function: functionName,
362
+ args,
363
+ }),
364
+ });
365
+
366
+ if (!response.ok) {
367
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
368
+ throw createError({
369
+ statusCode: response.status,
370
+ message: error.error || `${endpoint === 'query' ? 'Query' : 'Mutation'} failed`,
371
+ });
372
+ }
373
+
374
+ return response.json();
375
+ }
@@ -20,13 +20,77 @@
20
20
 
21
21
  import { createError } from 'h3';
22
22
 
23
+ // ============================================================================
24
+ // Types
25
+ // ============================================================================
26
+
27
+ interface AssetMetadata {
28
+ id: string;
29
+ filename: string;
30
+ contentType: string;
31
+ size: number;
32
+ sha256: string;
33
+ createdAt: string;
34
+ metadata: Record<string, unknown>;
35
+ }
36
+
37
+ interface UploadUrlOptions {
38
+ filename: string;
39
+ contentType: string;
40
+ metadata?: Record<string, unknown>;
41
+ }
42
+
43
+ interface ListAssetsOptions {
44
+ limit?: number;
45
+ offset?: number;
46
+ contentType?: string;
47
+ }
48
+
49
+ interface TetherServerClient {
50
+ query: (name: string, args?: unknown) => Promise<unknown>;
51
+ mutation: (name: string, args?: unknown) => Promise<unknown>;
52
+ storage: {
53
+ generateUploadUrl: (options: UploadUrlOptions) => Promise<{ assetId: string; uploadUrl: string; expiresAt: string }>;
54
+ confirmUpload: (assetId: string, sha256?: string) => Promise<AssetMetadata>;
55
+ getUrl: (assetId: string) => Promise<string>;
56
+ getMetadata: (assetId: string) => Promise<AssetMetadata>;
57
+ delete: (assetId: string) => Promise<void>;
58
+ list: (options?: ListAssetsOptions) => Promise<{ assets: AssetMetadata[]; totalCount: number }>;
59
+ };
60
+ projectId: string;
61
+ url: string;
62
+ }
63
+
64
+ // ============================================================================
65
+ // Helpers
66
+ // ============================================================================
67
+
68
+ /**
69
+ * Map snake_case API response to camelCase
70
+ */
71
+ function mapAssetMetadata(asset: Record<string, unknown>): AssetMetadata {
72
+ return {
73
+ id: asset.id as string,
74
+ filename: asset.filename as string,
75
+ contentType: asset.content_type as string,
76
+ size: asset.size as number,
77
+ sha256: asset.sha256 as string,
78
+ createdAt: asset.created_at as string,
79
+ metadata: (asset.metadata as Record<string, unknown>) ?? {},
80
+ };
81
+ }
82
+
83
+ // ============================================================================
84
+ // Main Export
85
+ // ============================================================================
86
+
23
87
  /**
24
88
  * Get a Tether client for use in server-side code
25
89
  *
26
- * @param {unknown} _event - The H3 event (optional, used for request context)
90
+ * @param _event - The H3 event (optional, used for request context)
27
91
  * @returns A Tether client with query, mutation, and storage methods
28
92
  */
29
- export function useTetherServer(_event) {
93
+ export function useTetherServer(_event?: unknown): TetherServerClient {
30
94
  // Use process.env directly to avoid #imports dependency
31
95
  // The Nuxt module sets NUXT_TETHER_* vars from runtime config
32
96
  const apiKey = process.env.NUXT_TETHER_API_KEY || process.env.TETHER_API_KEY;
@@ -52,7 +116,7 @@ export function useTetherServer(_event) {
52
116
  'Authorization': `Bearer ${apiKey}`,
53
117
  };
54
118
 
55
- async function query(name, args) {
119
+ async function query(name: string, args?: unknown): Promise<unknown> {
56
120
  const response = await fetch(`${url}/api/v1/projects/${projectId}/query`, {
57
121
  method: 'POST',
58
122
  headers,
@@ -71,7 +135,7 @@ export function useTetherServer(_event) {
71
135
  return result.data;
72
136
  }
73
137
 
74
- async function mutation(name, args) {
138
+ async function mutation(name: string, args?: unknown): Promise<unknown> {
75
139
  const response = await fetch(`${url}/api/v1/projects/${projectId}/mutation`, {
76
140
  method: 'POST',
77
141
  headers,
@@ -91,7 +155,7 @@ export function useTetherServer(_event) {
91
155
  }
92
156
 
93
157
  const storage = {
94
- async generateUploadUrl(options) {
158
+ async generateUploadUrl(options: UploadUrlOptions) {
95
159
  const response = await fetch(`${url}/api/v1/projects/${projectId}/assets/upload-url`, {
96
160
  method: 'POST',
97
161
  headers,
@@ -112,13 +176,13 @@ export function useTetherServer(_event) {
112
176
 
113
177
  const result = await response.json();
114
178
  return {
115
- assetId: result.asset_id,
116
- uploadUrl: result.upload_url,
117
- expiresAt: result.expires_at,
179
+ assetId: result.asset_id as string,
180
+ uploadUrl: result.upload_url as string,
181
+ expiresAt: result.expires_at as string,
118
182
  };
119
183
  },
120
184
 
121
- async confirmUpload(assetId, sha256) {
185
+ async confirmUpload(assetId: string, sha256?: string) {
122
186
  const response = await fetch(`${url}/api/v1/projects/${projectId}/assets/${assetId}/complete`, {
123
187
  method: 'POST',
124
188
  headers,
@@ -137,7 +201,7 @@ export function useTetherServer(_event) {
137
201
  return mapAssetMetadata(result.asset);
138
202
  },
139
203
 
140
- async getUrl(assetId) {
204
+ async getUrl(assetId: string): Promise<string> {
141
205
  const response = await fetch(`${url}/api/v1/projects/${projectId}/assets/${assetId}/url`, {
142
206
  method: 'GET',
143
207
  headers,
@@ -155,7 +219,7 @@ export function useTetherServer(_event) {
155
219
  return result.url;
156
220
  },
157
221
 
158
- async getMetadata(assetId) {
222
+ async getMetadata(assetId: string): Promise<AssetMetadata> {
159
223
  const response = await fetch(`${url}/api/v1/projects/${projectId}/assets/${assetId}`, {
160
224
  method: 'GET',
161
225
  headers,
@@ -173,7 +237,7 @@ export function useTetherServer(_event) {
173
237
  return mapAssetMetadata(result.asset);
174
238
  },
175
239
 
176
- async delete(assetId) {
240
+ async delete(assetId: string): Promise<void> {
177
241
  const response = await fetch(`${url}/api/v1/projects/${projectId}/assets/${assetId}`, {
178
242
  method: 'DELETE',
179
243
  headers,
@@ -188,7 +252,7 @@ export function useTetherServer(_event) {
188
252
  }
189
253
  },
190
254
 
191
- async list(options) {
255
+ async list(options?: ListAssetsOptions) {
192
256
  const params = new URLSearchParams();
193
257
  if (options?.limit) params.set('limit', String(options.limit));
194
258
  if (options?.offset) params.set('offset', String(options.offset));
@@ -213,7 +277,7 @@ export function useTetherServer(_event) {
213
277
  const result = await response.json();
214
278
  return {
215
279
  assets: result.assets.map(mapAssetMetadata),
216
- totalCount: result.total_count,
280
+ totalCount: result.total_count as number,
217
281
  };
218
282
  },
219
283
  };
@@ -226,18 +290,3 @@ export function useTetherServer(_event) {
226
290
  url,
227
291
  };
228
292
  }
229
-
230
- /**
231
- * Map snake_case API response to camelCase
232
- */
233
- function mapAssetMetadata(asset) {
234
- return {
235
- id: asset.id,
236
- filename: asset.filename,
237
- contentType: asset.content_type,
238
- size: asset.size,
239
- sha256: asset.sha256,
240
- createdAt: asset.created_at,
241
- metadata: asset.metadata,
242
- };
243
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tthr/vue",
3
- "version": "0.0.83",
3
+ "version": "0.0.85",
4
4
  "description": "Tether Vue/Nuxt SDK",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -17,11 +17,11 @@
17
17
  "./nuxt": {
18
18
  "import": "./nuxt/module.ts"
19
19
  },
20
- "./nuxt/runtime/server/plugins/cron.js": {
21
- "import": "./nuxt/runtime/server/plugins/cron.js"
20
+ "./nuxt/runtime/server/plugins/cron": {
21
+ "import": "./nuxt/runtime/server/plugins/cron.ts"
22
22
  },
23
- "./nuxt/runtime/server/utils/tether.js": {
24
- "import": "./nuxt/runtime/server/utils/tether.js"
23
+ "./nuxt/runtime/server/utils/tether": {
24
+ "import": "./nuxt/runtime/server/utils/tether.ts"
25
25
  }
26
26
  },
27
27
  "files": [
@@ -29,10 +29,7 @@
29
29
  "nuxt/module.ts",
30
30
  "nuxt/module.js",
31
31
  "nuxt/module.js.map",
32
- "nuxt/runtime/**/*.js",
33
- "nuxt/runtime/**/*.js.map",
34
- "nuxt/runtime/**/*.d.ts",
35
- "nuxt/runtime/**/*.d.ts.map",
32
+ "nuxt/runtime/**/*.ts",
36
33
  "nuxt/runtime/**/*.vue"
37
34
  ],
38
35
  "dependencies": {
package/dist/nuxt.d.ts DELETED
@@ -1,14 +0,0 @@
1
- /**
2
- * @tthr/vue/nuxt - Tether Nuxt Module
3
- *
4
- * Automatically configures Tether for Nuxt applications.
5
- */
6
- export interface TetherModuleOptions {
7
- /** Project ID from Tether dashboard */
8
- projectId?: string;
9
- /** API endpoint (defaults to Tether Cloud) */
10
- url?: string;
11
- }
12
- declare const _default: import("@nuxt/schema").NuxtModule<TetherModuleOptions, TetherModuleOptions, false>;
13
- export default _default;
14
- //# sourceMappingURL=nuxt.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"nuxt.d.ts","sourceRoot":"","sources":["../src/nuxt.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,WAAW,mBAAmB;IAClC,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;;AAED,wBA2CG"}
package/dist/nuxt.js DELETED
@@ -1,48 +0,0 @@
1
- /**
2
- * @tthr/vue/nuxt - Tether Nuxt Module
3
- *
4
- * Automatically configures Tether for Nuxt applications.
5
- */
6
- import { defineNuxtModule, addPlugin, createResolver, addImports } from '@nuxt/kit';
7
- export default defineNuxtModule({
8
- meta: {
9
- name: '@tthr/vue',
10
- configKey: 'tether',
11
- compatibility: {
12
- nuxt: '>=3.0.0',
13
- },
14
- },
15
- defaults: {
16
- projectId: undefined,
17
- url: undefined,
18
- },
19
- setup(options, nuxt) {
20
- const resolver = createResolver(import.meta.url);
21
- // Add runtime config
22
- nuxt.options.runtimeConfig.public.tether = {
23
- projectId: options.projectId || '',
24
- url: options.url || 'https://api.tether.strands.gg',
25
- };
26
- // Add the plugin that initialises Tether
27
- addPlugin({
28
- src: resolver.resolve('./runtime/plugin'),
29
- mode: 'client',
30
- });
31
- // Auto-import composables
32
- addImports([
33
- {
34
- name: 'useQuery',
35
- from: resolver.resolve('./runtime/composables'),
36
- },
37
- {
38
- name: 'useMutation',
39
- from: resolver.resolve('./runtime/composables'),
40
- },
41
- {
42
- name: 'useTether',
43
- from: resolver.resolve('./runtime/composables'),
44
- },
45
- ]);
46
- },
47
- });
48
- //# sourceMappingURL=nuxt.js.map
package/dist/nuxt.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"nuxt.js","sourceRoot":"","sources":["../src/nuxt.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AASpF,eAAe,gBAAgB,CAAsB;IACnD,IAAI,EAAE;QACJ,IAAI,EAAE,WAAW;QACjB,SAAS,EAAE,QAAQ;QACnB,aAAa,EAAE;YACb,IAAI,EAAE,SAAS;SAChB;KACF;IACD,QAAQ,EAAE;QACR,SAAS,EAAE,SAAS;QACpB,GAAG,EAAE,SAAS;KACf;IACD,KAAK,CAAC,OAAO,EAAE,IAAI;QACjB,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEjD,qBAAqB;QACrB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,GAAG;YACzC,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE;YAClC,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,+BAA+B;SACpD,CAAC;QAEF,yCAAyC;QACzC,SAAS,CAAC;YACR,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC;YACzC,IAAI,EAAE,QAAQ;SACf,CAAC,CAAC;QAEH,0BAA0B;QAC1B,UAAU,CAAC;YACT;gBACE,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,uBAAuB,CAAC;aAChD;YACD;gBACE,IAAI,EAAE,aAAa;gBACnB,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,uBAAuB,CAAC;aAChD;YACD;gBACE,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,uBAAuB,CAAC;aAChD;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC"}