@tthr/server 0.0.3 → 0.0.5
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.ts +156 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +235 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -12,11 +12,33 @@ export interface AuthContext {
|
|
|
12
12
|
claims: Record<string, unknown>;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* Database client type - represents the generated db object
|
|
16
16
|
*/
|
|
17
|
-
export
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
export type DatabaseClient = Record<string, {
|
|
18
|
+
findMany: (options?: unknown) => Promise<unknown[]>;
|
|
19
|
+
findFirst: (options?: unknown) => Promise<unknown | null>;
|
|
20
|
+
findUnique: (options?: unknown) => Promise<unknown | null>;
|
|
21
|
+
findById: (id: unknown) => Promise<unknown | null>;
|
|
22
|
+
count: (options?: unknown) => Promise<number>;
|
|
23
|
+
insert: (data: unknown) => Promise<unknown>;
|
|
24
|
+
insertMany: (data: unknown[]) => Promise<unknown[]>;
|
|
25
|
+
create: (options: {
|
|
26
|
+
data: unknown;
|
|
27
|
+
}) => Promise<unknown>;
|
|
28
|
+
update: (options: {
|
|
29
|
+
where: unknown;
|
|
30
|
+
data: unknown;
|
|
31
|
+
}) => Promise<number>;
|
|
32
|
+
upsert: (options: {
|
|
33
|
+
where: unknown;
|
|
34
|
+
create: unknown;
|
|
35
|
+
update: unknown;
|
|
36
|
+
}) => Promise<unknown>;
|
|
37
|
+
delete: (options: {
|
|
38
|
+
where: unknown;
|
|
39
|
+
}) => Promise<number>;
|
|
40
|
+
deleteById: (id: unknown) => Promise<boolean>;
|
|
41
|
+
}>;
|
|
20
42
|
/**
|
|
21
43
|
* Tether context for actions - provides access to queries, mutations, and env vars
|
|
22
44
|
*/
|
|
@@ -40,32 +62,56 @@ export interface TetherContext {
|
|
|
40
62
|
env: Record<string, string | undefined>;
|
|
41
63
|
}
|
|
42
64
|
/**
|
|
43
|
-
*
|
|
65
|
+
* Execution context with auth info
|
|
44
66
|
*/
|
|
45
|
-
export interface
|
|
67
|
+
export interface ExecutionCtx {
|
|
46
68
|
auth: AuthContext;
|
|
47
|
-
|
|
69
|
+
userId: string | null;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Base handler context (without args) for queries/mutations with no arguments
|
|
73
|
+
*/
|
|
74
|
+
export interface BaseHandlerContext {
|
|
75
|
+
/** Database client for the project */
|
|
76
|
+
db: DatabaseClient;
|
|
77
|
+
/** Execution context with auth info */
|
|
78
|
+
ctx: ExecutionCtx;
|
|
48
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Query/Mutation handler context with typed args
|
|
82
|
+
*/
|
|
83
|
+
export type FunctionHandlerContext<TArgs> = TArgs extends void ? BaseHandlerContext : BaseHandlerContext & {
|
|
84
|
+
args: TArgs;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Action handler context with typed args
|
|
88
|
+
*/
|
|
89
|
+
export type ActionHandlerCtx<TArgs> = TArgs extends void ? BaseHandlerContext & {
|
|
90
|
+
tether: TetherContext;
|
|
91
|
+
} : BaseHandlerContext & {
|
|
92
|
+
args: TArgs;
|
|
93
|
+
tether: TetherContext;
|
|
94
|
+
};
|
|
49
95
|
/**
|
|
50
96
|
* Query function definition
|
|
51
97
|
*/
|
|
52
98
|
export interface QueryDefinition<TArgs, TResult> {
|
|
53
99
|
args?: ZodType<TArgs>;
|
|
54
|
-
handler: (
|
|
100
|
+
handler: (context: FunctionHandlerContext<TArgs>) => Promise<TResult> | TResult;
|
|
55
101
|
}
|
|
56
102
|
/**
|
|
57
103
|
* Mutation function definition
|
|
58
104
|
*/
|
|
59
105
|
export interface MutationDefinition<TArgs, TResult> {
|
|
60
106
|
args?: ZodType<TArgs>;
|
|
61
|
-
handler: (
|
|
107
|
+
handler: (context: FunctionHandlerContext<TArgs>) => Promise<TResult> | TResult;
|
|
62
108
|
}
|
|
63
109
|
/**
|
|
64
110
|
* Action function definition
|
|
65
111
|
*/
|
|
66
112
|
export interface ActionDefinition<TArgs, TResult> {
|
|
67
113
|
args?: ZodType<TArgs>;
|
|
68
|
-
handler: (
|
|
114
|
+
handler: (context: ActionHandlerCtx<TArgs>) => Promise<TResult> | TResult;
|
|
69
115
|
}
|
|
70
116
|
/**
|
|
71
117
|
* Define a query function
|
|
@@ -75,20 +121,28 @@ export interface ActionDefinition<TArgs, TResult> {
|
|
|
75
121
|
* @example
|
|
76
122
|
* ```ts
|
|
77
123
|
* export const list = query({
|
|
78
|
-
*
|
|
79
|
-
*
|
|
124
|
+
* args: z.object({
|
|
125
|
+
* limit: z.number().optional().default(20),
|
|
126
|
+
* }),
|
|
127
|
+
* handler: async ({ args, db }) => {
|
|
128
|
+
* return db.posts.findMany({
|
|
129
|
+
* orderBy: { createdAt: 'desc' },
|
|
130
|
+
* limit: args.limit,
|
|
131
|
+
* });
|
|
80
132
|
* },
|
|
81
133
|
* });
|
|
82
134
|
*
|
|
83
|
-
* export const
|
|
84
|
-
* args: z.object({ id: z.
|
|
85
|
-
* handler: async ({
|
|
86
|
-
* return db.posts.
|
|
135
|
+
* export const get = query({
|
|
136
|
+
* args: z.object({ id: z.string() }),
|
|
137
|
+
* handler: async ({ args, db }) => {
|
|
138
|
+
* return db.posts.findUnique({
|
|
139
|
+
* where: { id: args.id },
|
|
140
|
+
* });
|
|
87
141
|
* },
|
|
88
142
|
* });
|
|
89
143
|
* ```
|
|
90
144
|
*/
|
|
91
|
-
export declare function query<TArgs = void, TResult = unknown>(definition: QueryDefinition<TArgs, TResult>
|
|
145
|
+
export declare function query<TArgs = void, TResult = unknown>(definition: QueryDefinition<TArgs, TResult>): QueryDefinition<TArgs, TResult>;
|
|
92
146
|
/**
|
|
93
147
|
* Define a mutation function
|
|
94
148
|
*
|
|
@@ -98,11 +152,21 @@ export declare function query<TArgs = void, TResult = unknown>(definition: Query
|
|
|
98
152
|
* ```ts
|
|
99
153
|
* export const create = mutation({
|
|
100
154
|
* args: z.object({
|
|
101
|
-
* title: z.string(),
|
|
102
|
-
* content: z.string(),
|
|
155
|
+
* title: z.string().min(1),
|
|
156
|
+
* content: z.string().optional(),
|
|
103
157
|
* }),
|
|
104
|
-
* handler: async ({
|
|
105
|
-
*
|
|
158
|
+
* handler: async ({ args, ctx, db }) => {
|
|
159
|
+
* const id = crypto.randomUUID();
|
|
160
|
+
* await db.posts.create({
|
|
161
|
+
* data: {
|
|
162
|
+
* id,
|
|
163
|
+
* title: args.title,
|
|
164
|
+
* content: args.content ?? '',
|
|
165
|
+
* authorId: ctx.userId,
|
|
166
|
+
* createdAt: new Date().toISOString(),
|
|
167
|
+
* },
|
|
168
|
+
* });
|
|
169
|
+
* return { id };
|
|
106
170
|
* },
|
|
107
171
|
* });
|
|
108
172
|
* ```
|
|
@@ -121,18 +185,18 @@ export declare function mutation<TArgs = void, TResult = unknown>(definition: Mu
|
|
|
121
185
|
* args: z.object({
|
|
122
186
|
* orderId: z.string(),
|
|
123
187
|
* }),
|
|
124
|
-
* handler: async ({
|
|
188
|
+
* handler: async ({ args, tether }) => {
|
|
125
189
|
* // Call a query
|
|
126
|
-
* const order = await tether.query('orders.get', { id: orderId });
|
|
190
|
+
* const order = await tether.query('orders.get', { id: args.orderId });
|
|
127
191
|
*
|
|
128
192
|
* // Use environment variables
|
|
129
193
|
* const response = await fetch('https://api.stripe.com/v1/charges', {
|
|
130
194
|
* headers: { Authorization: `Bearer ${tether.env.STRIPE_SECRET_KEY}` },
|
|
131
|
-
*
|
|
195
|
+
* body: new URLSearchParams({ amount: String(order.total) }),
|
|
132
196
|
* });
|
|
133
197
|
*
|
|
134
198
|
* // Call a mutation
|
|
135
|
-
* await tether.mutation('orders.update', { id: orderId, status: 'paid' });
|
|
199
|
+
* await tether.mutation('orders.update', { id: args.orderId, status: 'paid' });
|
|
136
200
|
*
|
|
137
201
|
* return { success: true };
|
|
138
202
|
* },
|
|
@@ -163,5 +227,72 @@ export declare class TetherServerClient {
|
|
|
163
227
|
* Create a server-side Tether client
|
|
164
228
|
*/
|
|
165
229
|
export declare function createClient(options: ServerClientOptions): TetherServerClient;
|
|
230
|
+
/**
|
|
231
|
+
* Runtime configuration
|
|
232
|
+
*/
|
|
233
|
+
export interface TetherRuntimeConfig {
|
|
234
|
+
/** Tether API URL */
|
|
235
|
+
url: string;
|
|
236
|
+
/** Project ID */
|
|
237
|
+
projectId: string;
|
|
238
|
+
/** API key or auth token */
|
|
239
|
+
apiKey?: string;
|
|
240
|
+
/** Auth token function (for user context) */
|
|
241
|
+
authToken?: string | (() => string | Promise<string>);
|
|
242
|
+
/** Whether to send logs to Tether (default: true in production) */
|
|
243
|
+
enableLogging?: boolean;
|
|
244
|
+
/** Batch size before flushing logs (default: 10) */
|
|
245
|
+
batchSize?: number;
|
|
246
|
+
/** Flush interval in ms (default: 5000) */
|
|
247
|
+
flushInterval?: number;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Initialise the Tether runtime
|
|
251
|
+
*
|
|
252
|
+
* Call this once at app startup to enable console capture and logging.
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* ```ts
|
|
256
|
+
* // In your Nuxt plugin or app entry
|
|
257
|
+
* import { initTetherRuntime } from '@tthr/server';
|
|
258
|
+
*
|
|
259
|
+
* initTetherRuntime({
|
|
260
|
+
* url: process.env.TETHER_URL!,
|
|
261
|
+
* projectId: process.env.TETHER_PROJECT_ID!,
|
|
262
|
+
* apiKey: process.env.TETHER_API_KEY,
|
|
263
|
+
* });
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
export declare function initTetherRuntime(config: TetherRuntimeConfig): void;
|
|
267
|
+
/**
|
|
268
|
+
* Get the current runtime config
|
|
269
|
+
*/
|
|
270
|
+
export declare function getRuntimeConfig(): TetherRuntimeConfig | null;
|
|
271
|
+
/**
|
|
272
|
+
* Execute a function with Tether console capture
|
|
273
|
+
*
|
|
274
|
+
* Wraps the function execution to capture all console.* calls and send them
|
|
275
|
+
* to Tether for dashboard visibility.
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* ```ts
|
|
279
|
+
* // In your Nuxt server route
|
|
280
|
+
* import { executeWithLogging } from '@tthr/server';
|
|
281
|
+
* import { list } from '~/tether/functions/posts';
|
|
282
|
+
*
|
|
283
|
+
* export default defineEventHandler(async (event) => {
|
|
284
|
+
* return executeWithLogging('posts.list', async (ctx) => {
|
|
285
|
+
* return list.handler(ctx);
|
|
286
|
+
* }, { db, ctx });
|
|
287
|
+
* });
|
|
288
|
+
* ```
|
|
289
|
+
*/
|
|
290
|
+
export declare function executeWithLogging<TResult>(functionName: string, fn: () => Promise<TResult> | TResult): Promise<TResult>;
|
|
291
|
+
/**
|
|
292
|
+
* Manually flush any pending logs
|
|
293
|
+
*
|
|
294
|
+
* Call this before your server shuts down to ensure all logs are sent.
|
|
295
|
+
*/
|
|
296
|
+
export declare function flushTetherLogs(): Promise<void>;
|
|
166
297
|
export { z };
|
|
167
298
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,KAAK,OAAO,EAAE,MAAM,KAAK,CAAC;AAEtC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -12,25 +12,28 @@ import { z } from 'zod';
|
|
|
12
12
|
* @example
|
|
13
13
|
* ```ts
|
|
14
14
|
* export const list = query({
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* args: z.object({
|
|
16
|
+
* limit: z.number().optional().default(20),
|
|
17
|
+
* }),
|
|
18
|
+
* handler: async ({ args, db }) => {
|
|
19
|
+
* return db.posts.findMany({
|
|
20
|
+
* orderBy: { createdAt: 'desc' },
|
|
21
|
+
* limit: args.limit,
|
|
22
|
+
* });
|
|
17
23
|
* },
|
|
18
24
|
* });
|
|
19
25
|
*
|
|
20
|
-
* export const
|
|
21
|
-
* args: z.object({ id: z.
|
|
22
|
-
* handler: async ({
|
|
23
|
-
* return db.posts.
|
|
26
|
+
* export const get = query({
|
|
27
|
+
* args: z.object({ id: z.string() }),
|
|
28
|
+
* handler: async ({ args, db }) => {
|
|
29
|
+
* return db.posts.findUnique({
|
|
30
|
+
* where: { id: args.id },
|
|
31
|
+
* });
|
|
24
32
|
* },
|
|
25
33
|
* });
|
|
26
34
|
* ```
|
|
27
35
|
*/
|
|
28
36
|
export function query(definition) {
|
|
29
|
-
if (typeof definition === 'function') {
|
|
30
|
-
return {
|
|
31
|
-
handler: (_, ctx) => definition(ctx),
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
37
|
return definition;
|
|
35
38
|
}
|
|
36
39
|
/**
|
|
@@ -42,11 +45,21 @@ export function query(definition) {
|
|
|
42
45
|
* ```ts
|
|
43
46
|
* export const create = mutation({
|
|
44
47
|
* args: z.object({
|
|
45
|
-
* title: z.string(),
|
|
46
|
-
* content: z.string(),
|
|
48
|
+
* title: z.string().min(1),
|
|
49
|
+
* content: z.string().optional(),
|
|
47
50
|
* }),
|
|
48
|
-
* handler: async ({
|
|
49
|
-
*
|
|
51
|
+
* handler: async ({ args, ctx, db }) => {
|
|
52
|
+
* const id = crypto.randomUUID();
|
|
53
|
+
* await db.posts.create({
|
|
54
|
+
* data: {
|
|
55
|
+
* id,
|
|
56
|
+
* title: args.title,
|
|
57
|
+
* content: args.content ?? '',
|
|
58
|
+
* authorId: ctx.userId,
|
|
59
|
+
* createdAt: new Date().toISOString(),
|
|
60
|
+
* },
|
|
61
|
+
* });
|
|
62
|
+
* return { id };
|
|
50
63
|
* },
|
|
51
64
|
* });
|
|
52
65
|
* ```
|
|
@@ -67,18 +80,18 @@ export function mutation(definition) {
|
|
|
67
80
|
* args: z.object({
|
|
68
81
|
* orderId: z.string(),
|
|
69
82
|
* }),
|
|
70
|
-
* handler: async ({
|
|
83
|
+
* handler: async ({ args, tether }) => {
|
|
71
84
|
* // Call a query
|
|
72
|
-
* const order = await tether.query('orders.get', { id: orderId });
|
|
85
|
+
* const order = await tether.query('orders.get', { id: args.orderId });
|
|
73
86
|
*
|
|
74
87
|
* // Use environment variables
|
|
75
88
|
* const response = await fetch('https://api.stripe.com/v1/charges', {
|
|
76
89
|
* headers: { Authorization: `Bearer ${tether.env.STRIPE_SECRET_KEY}` },
|
|
77
|
-
*
|
|
90
|
+
* body: new URLSearchParams({ amount: String(order.total) }),
|
|
78
91
|
* });
|
|
79
92
|
*
|
|
80
93
|
* // Call a mutation
|
|
81
|
-
* await tether.mutation('orders.update', { id: orderId, status: 'paid' });
|
|
94
|
+
* await tether.mutation('orders.update', { id: args.orderId, status: 'paid' });
|
|
82
95
|
*
|
|
83
96
|
* return { success: true };
|
|
84
97
|
* },
|
|
@@ -138,6 +151,209 @@ export class TetherServerClient {
|
|
|
138
151
|
export function createClient(options) {
|
|
139
152
|
return new TetherServerClient(options);
|
|
140
153
|
}
|
|
154
|
+
// Global runtime instance
|
|
155
|
+
let _runtimeConfig = null;
|
|
156
|
+
let _logBuffer = [];
|
|
157
|
+
let _flushTimer = null;
|
|
158
|
+
/**
|
|
159
|
+
* Initialise the Tether runtime
|
|
160
|
+
*
|
|
161
|
+
* Call this once at app startup to enable console capture and logging.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```ts
|
|
165
|
+
* // In your Nuxt plugin or app entry
|
|
166
|
+
* import { initTetherRuntime } from '@tthr/server';
|
|
167
|
+
*
|
|
168
|
+
* initTetherRuntime({
|
|
169
|
+
* url: process.env.TETHER_URL!,
|
|
170
|
+
* projectId: process.env.TETHER_PROJECT_ID!,
|
|
171
|
+
* apiKey: process.env.TETHER_API_KEY,
|
|
172
|
+
* });
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
export function initTetherRuntime(config) {
|
|
176
|
+
_runtimeConfig = {
|
|
177
|
+
enableLogging: process.env.NODE_ENV === 'production',
|
|
178
|
+
batchSize: 10,
|
|
179
|
+
flushInterval: 5000,
|
|
180
|
+
...config,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Get the current runtime config
|
|
185
|
+
*/
|
|
186
|
+
export function getRuntimeConfig() {
|
|
187
|
+
return _runtimeConfig;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Flush pending logs to Tether
|
|
191
|
+
*/
|
|
192
|
+
async function flushLogs() {
|
|
193
|
+
if (!_runtimeConfig || _logBuffer.length === 0)
|
|
194
|
+
return;
|
|
195
|
+
const logs = _logBuffer.splice(0, _logBuffer.length);
|
|
196
|
+
try {
|
|
197
|
+
const token = typeof _runtimeConfig.authToken === 'function'
|
|
198
|
+
? await _runtimeConfig.authToken()
|
|
199
|
+
: _runtimeConfig.authToken ?? _runtimeConfig.apiKey;
|
|
200
|
+
const response = await fetch(`${_runtimeConfig.url}/api/v1/projects/${_runtimeConfig.projectId}/logs`, {
|
|
201
|
+
method: 'POST',
|
|
202
|
+
headers: {
|
|
203
|
+
'Content-Type': 'application/json',
|
|
204
|
+
...(token ? { 'Authorization': `Bearer ${token}` } : {}),
|
|
205
|
+
},
|
|
206
|
+
body: JSON.stringify({ logs }),
|
|
207
|
+
});
|
|
208
|
+
if (!response.ok) {
|
|
209
|
+
// Re-add logs on failure (with limit to prevent memory issues)
|
|
210
|
+
if (_logBuffer.length < 1000) {
|
|
211
|
+
_logBuffer.unshift(...logs);
|
|
212
|
+
}
|
|
213
|
+
console.error('[Tether] Failed to send logs:', response.statusText);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
// Re-add logs on failure
|
|
218
|
+
if (_logBuffer.length < 1000) {
|
|
219
|
+
_logBuffer.unshift(...logs);
|
|
220
|
+
}
|
|
221
|
+
console.error('[Tether] Failed to send logs:', error);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Schedule a flush of logs
|
|
226
|
+
*/
|
|
227
|
+
function scheduleFlush() {
|
|
228
|
+
if (_flushTimer)
|
|
229
|
+
return;
|
|
230
|
+
_flushTimer = setTimeout(() => {
|
|
231
|
+
_flushTimer = null;
|
|
232
|
+
flushLogs();
|
|
233
|
+
}, _runtimeConfig?.flushInterval ?? 5000);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Add a log entry to the buffer
|
|
237
|
+
*/
|
|
238
|
+
function addLog(entry) {
|
|
239
|
+
if (!_runtimeConfig?.enableLogging)
|
|
240
|
+
return;
|
|
241
|
+
_logBuffer.push(entry);
|
|
242
|
+
// Flush if batch size reached
|
|
243
|
+
if (_logBuffer.length >= (_runtimeConfig.batchSize ?? 10)) {
|
|
244
|
+
flushLogs();
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
scheduleFlush();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Create a wrapped console that captures logs for a specific function execution
|
|
252
|
+
*/
|
|
253
|
+
function createTetherConsole(functionName, executionId) {
|
|
254
|
+
const originalConsole = globalThis.console;
|
|
255
|
+
const createMethod = (level) => {
|
|
256
|
+
return (...args) => {
|
|
257
|
+
// Still call original console
|
|
258
|
+
originalConsole[level](...args);
|
|
259
|
+
// Capture for Tether
|
|
260
|
+
const message = args
|
|
261
|
+
.map(arg => typeof arg === 'string' ? arg : JSON.stringify(arg))
|
|
262
|
+
.join(' ');
|
|
263
|
+
// Extract structured data if first arg is an object
|
|
264
|
+
const data = args.length === 1 && typeof args[0] === 'object' && args[0] !== null
|
|
265
|
+
? args[0]
|
|
266
|
+
: args.length > 1
|
|
267
|
+
? args
|
|
268
|
+
: undefined;
|
|
269
|
+
addLog({
|
|
270
|
+
function: functionName,
|
|
271
|
+
level,
|
|
272
|
+
message,
|
|
273
|
+
data,
|
|
274
|
+
execution_id: executionId,
|
|
275
|
+
timestamp: new Date().toISOString(),
|
|
276
|
+
});
|
|
277
|
+
};
|
|
278
|
+
};
|
|
279
|
+
// Create a proxy that wraps console methods
|
|
280
|
+
return new Proxy(originalConsole, {
|
|
281
|
+
get(target, prop) {
|
|
282
|
+
if (prop === 'log')
|
|
283
|
+
return createMethod('log');
|
|
284
|
+
if (prop === 'info')
|
|
285
|
+
return createMethod('info');
|
|
286
|
+
if (prop === 'warn')
|
|
287
|
+
return createMethod('warn');
|
|
288
|
+
if (prop === 'error')
|
|
289
|
+
return createMethod('error');
|
|
290
|
+
if (prop === 'debug')
|
|
291
|
+
return createMethod('debug');
|
|
292
|
+
return target[prop];
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Generate a unique execution ID
|
|
298
|
+
*/
|
|
299
|
+
function generateExecutionId() {
|
|
300
|
+
return `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Execute a function with Tether console capture
|
|
304
|
+
*
|
|
305
|
+
* Wraps the function execution to capture all console.* calls and send them
|
|
306
|
+
* to Tether for dashboard visibility.
|
|
307
|
+
*
|
|
308
|
+
* @example
|
|
309
|
+
* ```ts
|
|
310
|
+
* // In your Nuxt server route
|
|
311
|
+
* import { executeWithLogging } from '@tthr/server';
|
|
312
|
+
* import { list } from '~/tether/functions/posts';
|
|
313
|
+
*
|
|
314
|
+
* export default defineEventHandler(async (event) => {
|
|
315
|
+
* return executeWithLogging('posts.list', async (ctx) => {
|
|
316
|
+
* return list.handler(ctx);
|
|
317
|
+
* }, { db, ctx });
|
|
318
|
+
* });
|
|
319
|
+
* ```
|
|
320
|
+
*/
|
|
321
|
+
export async function executeWithLogging(functionName, fn) {
|
|
322
|
+
const executionId = generateExecutionId();
|
|
323
|
+
const tetherConsole = createTetherConsole(functionName, executionId);
|
|
324
|
+
// Store original console
|
|
325
|
+
const originalConsole = globalThis.console;
|
|
326
|
+
try {
|
|
327
|
+
// Replace global console
|
|
328
|
+
globalThis.console = tetherConsole;
|
|
329
|
+
// Execute function
|
|
330
|
+
const result = await fn();
|
|
331
|
+
return result;
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
// Log the error
|
|
335
|
+
tetherConsole.error(error instanceof Error ? error.message : String(error), error instanceof Error ? { stack: error.stack } : undefined);
|
|
336
|
+
throw error;
|
|
337
|
+
}
|
|
338
|
+
finally {
|
|
339
|
+
// Restore original console
|
|
340
|
+
globalThis.console = originalConsole;
|
|
341
|
+
// Flush logs after execution (don't await to not block response)
|
|
342
|
+
flushLogs().catch(() => { });
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Manually flush any pending logs
|
|
347
|
+
*
|
|
348
|
+
* Call this before your server shuts down to ensure all logs are sent.
|
|
349
|
+
*/
|
|
350
|
+
export async function flushTetherLogs() {
|
|
351
|
+
if (_flushTimer) {
|
|
352
|
+
clearTimeout(_flushTimer);
|
|
353
|
+
_flushTimer = null;
|
|
354
|
+
}
|
|
355
|
+
await flushLogs();
|
|
356
|
+
}
|
|
141
357
|
// Re-export zod for convenience
|
|
142
358
|
export { z };
|
|
143
359
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAgB,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|