@tthr/vue 0.0.44 → 0.0.45

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/nuxt/module.js CHANGED
@@ -18,7 +18,7 @@
18
18
  * Environment variables (in .env):
19
19
  * - TETHER_API_KEY: Your project's API key (required, kept server-side)
20
20
  */
21
- import { defineNuxtModule, addPlugin, createResolver, addImports, addComponent, addServerHandler, addServerImports } from '@nuxt/kit';
21
+ import { defineNuxtModule, addPlugin, createResolver, addImports, addComponent, addServerHandler, addServerImports, addTemplate } from '@nuxt/kit';
22
22
  export default defineNuxtModule({
23
23
  meta: {
24
24
  name: '@tthr/vue',
@@ -131,5 +131,144 @@ export default defineNuxtModule({
131
131
  nitroConfig.externals.inline = nitroConfig.externals.inline || [];
132
132
  nitroConfig.externals.inline.push('@tthr/vue');
133
133
  });
134
+ // Generate a server plugin to auto-register cron handlers from tether/functions
135
+ // This runs at build time and creates a plugin that imports user's functions
136
+ addTemplate({
137
+ filename: 'server/plugins/tether-functions.ts',
138
+ write: true,
139
+ getContents: () => `
140
+ /**
141
+ * Auto-generated plugin to register Tether functions as cron handlers
142
+ * This file is generated by @tthr/vue/nuxt module
143
+ */
144
+ import { defineNitroPlugin } from 'nitropack/runtime';
145
+ import { registerCronHandler } from '@tthr/vue/nuxt/runtime/server/plugins/cron.js';
146
+ import { useTetherServer } from '@tthr/vue/nuxt/runtime/server/utils/tether.js';
147
+
148
+ // Import all functions from tether/functions
149
+ // @ts-ignore - user's functions may not exist yet
150
+ import * as tetherFunctions from '~/tether/functions';
151
+
152
+ /**
153
+ * Create a simple logger for function execution
154
+ */
155
+ function createLogger(functionName: string) {
156
+ const prefix = \`[Tether] \${functionName}\`;
157
+ return {
158
+ log: (msg: string, data?: unknown) => console.log(prefix, msg, data !== undefined ? data : ''),
159
+ info: (msg: string, data?: unknown) => console.log(prefix, msg, data !== undefined ? data : ''),
160
+ warn: (msg: string, data?: unknown) => console.warn(prefix, msg, data !== undefined ? data : ''),
161
+ error: (msg: string, data?: unknown) => console.error(prefix, msg, data !== undefined ? data : ''),
162
+ debug: (msg: string, data?: unknown) => console.debug(prefix, msg, data !== undefined ? data : ''),
163
+ };
164
+ }
165
+
166
+ /**
167
+ * Create the handler context for a function
168
+ */
169
+ function createHandlerContext(functionName: string, args: unknown) {
170
+ const tether = useTetherServer(null as any);
171
+ const log = createLogger(functionName);
172
+
173
+ // Create db proxy that uses tether server client
174
+ // TODO: This is a placeholder - proper db operations need to be implemented
175
+ const db = new Proxy({}, {
176
+ get(_, tableName: string) {
177
+ return {
178
+ findMany: async (options?: any) => {
179
+ // Call Tether API for db operations
180
+ return tether.query(\`_db.\${tableName}.findMany\`, options);
181
+ },
182
+ findFirst: async (options?: any) => {
183
+ return tether.query(\`_db.\${tableName}.findFirst\`, options);
184
+ },
185
+ findUnique: async (options?: any) => {
186
+ return tether.query(\`_db.\${tableName}.findUnique\`, options);
187
+ },
188
+ findById: async (id: unknown) => {
189
+ return tether.query(\`_db.\${tableName}.findById\`, { id });
190
+ },
191
+ count: async (options?: any) => {
192
+ return tether.query(\`_db.\${tableName}.count\`, options);
193
+ },
194
+ create: async (options: any) => {
195
+ return tether.mutation(\`_db.\${tableName}.create\`, options);
196
+ },
197
+ insert: async (data: any) => {
198
+ return tether.mutation(\`_db.\${tableName}.insert\`, { data });
199
+ },
200
+ insertMany: async (data: any[]) => {
201
+ return tether.mutation(\`_db.\${tableName}.insertMany\`, { data });
202
+ },
203
+ update: async (options: any) => {
204
+ return tether.mutation(\`_db.\${tableName}.update\`, options);
205
+ },
206
+ upsert: async (options: any) => {
207
+ return tether.mutation(\`_db.\${tableName}.upsert\`, options);
208
+ },
209
+ delete: async (options: any) => {
210
+ return tether.mutation(\`_db.\${tableName}.delete\`, options);
211
+ },
212
+ deleteById: async (id: unknown) => {
213
+ return tether.mutation(\`_db.\${tableName}.deleteById\`, { id });
214
+ },
215
+ };
216
+ },
217
+ });
218
+
219
+ // Create tether context for actions
220
+ const tetherContext = {
221
+ query: tether.query.bind(tether),
222
+ mutation: tether.mutation.bind(tether),
223
+ env: new Proxy({}, {
224
+ get(_, key: string) {
225
+ return process.env[key];
226
+ },
227
+ }),
228
+ };
229
+
230
+ return {
231
+ args,
232
+ db,
233
+ ctx: { auth: { userId: null, claims: {} }, userId: null },
234
+ log,
235
+ tether: tetherContext,
236
+ };
237
+ }
238
+
239
+ export default defineNitroPlugin(() => {
240
+ console.log('[Tether] Auto-registering functions from tether/functions...');
241
+
242
+ // Iterate through all exported modules
243
+ for (const [moduleName, moduleExports] of Object.entries(tetherFunctions)) {
244
+ if (!moduleExports || typeof moduleExports !== 'object') continue;
245
+
246
+ // Iterate through all exports in each module
247
+ for (const [fnName, fnDef] of Object.entries(moduleExports as Record<string, any>)) {
248
+ // Check if it's a Tether function definition (has handler property)
249
+ if (!fnDef || typeof fnDef !== 'object' || typeof fnDef.handler !== 'function') continue;
250
+
251
+ const fullName = \`\${moduleName}.\${fnName}\`;
252
+
253
+ // Register the cron handler
254
+ registerCronHandler(fullName, async (args: unknown) => {
255
+ const context = createHandlerContext(fullName, args);
256
+ return fnDef.handler(context);
257
+ });
258
+
259
+ console.log(\`[Tether] Registered handler: \${fullName}\`);
260
+ }
261
+ }
262
+
263
+ console.log('[Tether] Function registration complete');
264
+ });
265
+ `,
266
+ });
267
+ // Add the generated plugin to Nitro
268
+ nuxt.hook('nitro:config', (nitroConfig) => {
269
+ nitroConfig.plugins = nitroConfig.plugins || [];
270
+ // Add our generated plugin after the cron plugin
271
+ nitroConfig.plugins.push('#build/server/plugins/tether-functions');
272
+ });
134
273
  },
135
274
  });
package/nuxt/module.ts CHANGED
@@ -155,5 +155,146 @@ export default defineNuxtModule<TetherModuleOptions>({
155
155
  nitroConfig.externals.inline = nitroConfig.externals.inline || [];
156
156
  nitroConfig.externals.inline.push('@tthr/vue');
157
157
  });
158
+
159
+ // Generate a server plugin to auto-register cron handlers from tether/functions
160
+ // This runs at build time and creates a plugin that imports user's functions
161
+ addTemplate({
162
+ filename: 'server/plugins/tether-functions.ts',
163
+ write: true,
164
+ getContents: () => `
165
+ /**
166
+ * Auto-generated plugin to register Tether functions as cron handlers
167
+ * This file is generated by @tthr/vue/nuxt module
168
+ */
169
+ import { defineNitroPlugin } from 'nitropack/runtime';
170
+ import { registerCronHandler } from '@tthr/vue/nuxt/runtime/server/plugins/cron.js';
171
+ import { useTetherServer } from '@tthr/vue/nuxt/runtime/server/utils/tether.js';
172
+
173
+ // Import all functions from tether/functions
174
+ // @ts-ignore - user's functions may not exist yet
175
+ import * as tetherFunctions from '~/tether/functions';
176
+
177
+ /**
178
+ * Create a simple logger for function execution
179
+ */
180
+ function createLogger(functionName: string) {
181
+ const prefix = \`[Tether] \${functionName}\`;
182
+ return {
183
+ log: (msg: string, data?: unknown) => console.log(prefix, msg, data !== undefined ? data : ''),
184
+ info: (msg: string, data?: unknown) => console.log(prefix, msg, data !== undefined ? data : ''),
185
+ warn: (msg: string, data?: unknown) => console.warn(prefix, msg, data !== undefined ? data : ''),
186
+ error: (msg: string, data?: unknown) => console.error(prefix, msg, data !== undefined ? data : ''),
187
+ debug: (msg: string, data?: unknown) => console.debug(prefix, msg, data !== undefined ? data : ''),
188
+ };
189
+ }
190
+
191
+ /**
192
+ * Create the handler context for a function
193
+ */
194
+ function createHandlerContext(functionName: string, args: unknown) {
195
+ const tether = useTetherServer(null as any);
196
+ const log = createLogger(functionName);
197
+
198
+ // Create db proxy that uses tether server client
199
+ // TODO: This is a placeholder - proper db operations need to be implemented
200
+ const db = new Proxy({}, {
201
+ get(_, tableName: string) {
202
+ return {
203
+ findMany: async (options?: any) => {
204
+ // Call Tether API for db operations
205
+ return tether.query(\`_db.\${tableName}.findMany\`, options);
206
+ },
207
+ findFirst: async (options?: any) => {
208
+ return tether.query(\`_db.\${tableName}.findFirst\`, options);
209
+ },
210
+ findUnique: async (options?: any) => {
211
+ return tether.query(\`_db.\${tableName}.findUnique\`, options);
212
+ },
213
+ findById: async (id: unknown) => {
214
+ return tether.query(\`_db.\${tableName}.findById\`, { id });
215
+ },
216
+ count: async (options?: any) => {
217
+ return tether.query(\`_db.\${tableName}.count\`, options);
218
+ },
219
+ create: async (options: any) => {
220
+ return tether.mutation(\`_db.\${tableName}.create\`, options);
221
+ },
222
+ insert: async (data: any) => {
223
+ return tether.mutation(\`_db.\${tableName}.insert\`, { data });
224
+ },
225
+ insertMany: async (data: any[]) => {
226
+ return tether.mutation(\`_db.\${tableName}.insertMany\`, { data });
227
+ },
228
+ update: async (options: any) => {
229
+ return tether.mutation(\`_db.\${tableName}.update\`, options);
230
+ },
231
+ upsert: async (options: any) => {
232
+ return tether.mutation(\`_db.\${tableName}.upsert\`, options);
233
+ },
234
+ delete: async (options: any) => {
235
+ return tether.mutation(\`_db.\${tableName}.delete\`, options);
236
+ },
237
+ deleteById: async (id: unknown) => {
238
+ return tether.mutation(\`_db.\${tableName}.deleteById\`, { id });
239
+ },
240
+ };
241
+ },
242
+ });
243
+
244
+ // Create tether context for actions
245
+ const tetherContext = {
246
+ query: tether.query.bind(tether),
247
+ mutation: tether.mutation.bind(tether),
248
+ env: new Proxy({}, {
249
+ get(_, key: string) {
250
+ return process.env[key];
251
+ },
252
+ }),
253
+ };
254
+
255
+ return {
256
+ args,
257
+ db,
258
+ ctx: { auth: { userId: null, claims: {} }, userId: null },
259
+ log,
260
+ tether: tetherContext,
261
+ };
262
+ }
263
+
264
+ export default defineNitroPlugin(() => {
265
+ console.log('[Tether] Auto-registering functions from tether/functions...');
266
+
267
+ // Iterate through all exported modules
268
+ for (const [moduleName, moduleExports] of Object.entries(tetherFunctions)) {
269
+ if (!moduleExports || typeof moduleExports !== 'object') continue;
270
+
271
+ // Iterate through all exports in each module
272
+ for (const [fnName, fnDef] of Object.entries(moduleExports as Record<string, any>)) {
273
+ // Check if it's a Tether function definition (has handler property)
274
+ if (!fnDef || typeof fnDef !== 'object' || typeof fnDef.handler !== 'function') continue;
275
+
276
+ const fullName = \`\${moduleName}.\${fnName}\`;
277
+
278
+ // Register the cron handler
279
+ registerCronHandler(fullName, async (args: unknown) => {
280
+ const context = createHandlerContext(fullName, args);
281
+ return fnDef.handler(context);
282
+ });
283
+
284
+ console.log(\`[Tether] Registered handler: \${fullName}\`);
285
+ }
286
+ }
287
+
288
+ console.log('[Tether] Function registration complete');
289
+ });
290
+ `,
291
+ });
292
+
293
+ // Add the generated plugin to Nitro
294
+ nuxt.hook('nitro:config' as any, (nitroConfig: any) => {
295
+ nitroConfig.plugins = nitroConfig.plugins || [];
296
+ // Add our generated plugin after the cron plugin
297
+ nitroConfig.plugins.push('#build/server/plugins/tether-functions');
298
+ });
158
299
  },
159
300
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tthr/vue",
3
- "version": "0.0.44",
3
+ "version": "0.0.45",
4
4
  "description": "Tether Vue/Nuxt SDK",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",