@vestig/next 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.
Files changed (86) hide show
  1. package/README.md +290 -0
  2. package/dist/client/hooks.d.ts +95 -0
  3. package/dist/client/hooks.d.ts.map +1 -0
  4. package/dist/client/hooks.js +128 -0
  5. package/dist/client/hooks.js.map +1 -0
  6. package/dist/client/index.d.ts +4 -0
  7. package/dist/client/index.d.ts.map +1 -0
  8. package/dist/client/index.js +9 -0
  9. package/dist/client/index.js.map +1 -0
  10. package/dist/client/provider.d.ts +66 -0
  11. package/dist/client/provider.d.ts.map +1 -0
  12. package/dist/client/provider.js +126 -0
  13. package/dist/client/provider.js.map +1 -0
  14. package/dist/client/transport.d.ts +59 -0
  15. package/dist/client/transport.d.ts.map +1 -0
  16. package/dist/client/transport.js +148 -0
  17. package/dist/client/transport.js.map +1 -0
  18. package/dist/client.d.ts +43 -0
  19. package/dist/client.d.ts.map +1 -0
  20. package/dist/client.js +47 -0
  21. package/dist/client.js.map +1 -0
  22. package/dist/config/defaults.d.ts +10 -0
  23. package/dist/config/defaults.d.ts.map +1 -0
  24. package/dist/config/defaults.js +72 -0
  25. package/dist/config/defaults.js.map +1 -0
  26. package/dist/config/index.d.ts +116 -0
  27. package/dist/config/index.d.ts.map +1 -0
  28. package/dist/config/index.js +27 -0
  29. package/dist/config/index.js.map +1 -0
  30. package/dist/config/loader.d.ts +21 -0
  31. package/dist/config/loader.d.ts.map +1 -0
  32. package/dist/config/loader.js +31 -0
  33. package/dist/config/loader.js.map +1 -0
  34. package/dist/index.d.ts +42 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +43 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/route/handler.d.ts +56 -0
  39. package/dist/route/handler.d.ts.map +1 -0
  40. package/dist/route/handler.js +250 -0
  41. package/dist/route/handler.js.map +1 -0
  42. package/dist/route/index.d.ts +2 -0
  43. package/dist/route/index.d.ts.map +1 -0
  44. package/dist/route/index.js +3 -0
  45. package/dist/route/index.js.map +1 -0
  46. package/dist/server/index.d.ts +5 -0
  47. package/dist/server/index.d.ts.map +1 -0
  48. package/dist/server/index.js +10 -0
  49. package/dist/server/index.js.map +1 -0
  50. package/dist/server/middleware.d.ts +108 -0
  51. package/dist/server/middleware.d.ts.map +1 -0
  52. package/dist/server/middleware.js +182 -0
  53. package/dist/server/middleware.js.map +1 -0
  54. package/dist/server/route-handler.d.ts +93 -0
  55. package/dist/server/route-handler.d.ts.map +1 -0
  56. package/dist/server/route-handler.js +160 -0
  57. package/dist/server/route-handler.js.map +1 -0
  58. package/dist/server/server-action.d.ts +74 -0
  59. package/dist/server/server-action.d.ts.map +1 -0
  60. package/dist/server/server-action.js +132 -0
  61. package/dist/server/server-action.js.map +1 -0
  62. package/dist/server/server-component.d.ts +87 -0
  63. package/dist/server/server-component.d.ts.map +1 -0
  64. package/dist/server/server-component.js +122 -0
  65. package/dist/server/server-component.js.map +1 -0
  66. package/dist/types.d.ts +80 -0
  67. package/dist/types.d.ts.map +1 -0
  68. package/dist/types.js +5 -0
  69. package/dist/types.js.map +1 -0
  70. package/dist/utils/headers.d.ts +38 -0
  71. package/dist/utils/headers.d.ts.map +1 -0
  72. package/dist/utils/headers.js +42 -0
  73. package/dist/utils/headers.js.map +1 -0
  74. package/dist/utils/index.d.ts +4 -0
  75. package/dist/utils/index.d.ts.map +1 -0
  76. package/dist/utils/index.js +4 -0
  77. package/dist/utils/index.js.map +1 -0
  78. package/dist/utils/metadata.d.ts +41 -0
  79. package/dist/utils/metadata.d.ts.map +1 -0
  80. package/dist/utils/metadata.js +46 -0
  81. package/dist/utils/metadata.js.map +1 -0
  82. package/dist/utils/timing.d.ts +31 -0
  83. package/dist/utils/timing.d.ts.map +1 -0
  84. package/dist/utils/timing.js +46 -0
  85. package/dist/utils/timing.js.map +1 -0
  86. package/package.json +88 -0
@@ -0,0 +1,182 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { createCorrelationContext, createLogger, createTraceparent, parseTraceparent, } from 'vestig';
3
+ import { CORRELATION_HEADERS } from '../utils/headers';
4
+ import { createRequestTiming, formatDuration } from '../utils/timing';
5
+ // Default options
6
+ const DEFAULT_OPTIONS = {
7
+ level: 'info',
8
+ enabled: true,
9
+ sanitize: 'default',
10
+ namespace: 'middleware',
11
+ skipPaths: ['/_next', '/favicon.ico', '/api/vestig'],
12
+ requestIdHeader: CORRELATION_HEADERS.REQUEST_ID,
13
+ timing: true,
14
+ requestLogLevel: 'info',
15
+ responseLogLevel: 'info',
16
+ structured: true,
17
+ };
18
+ // Cached logger per middleware instance
19
+ const loggerCache = new WeakMap();
20
+ function getOrCreateLogger(options) {
21
+ const cached = loggerCache.get(options);
22
+ if (cached)
23
+ return cached;
24
+ const logger = createLogger({
25
+ level: options.level,
26
+ enabled: options.enabled,
27
+ sanitize: options.sanitize,
28
+ namespace: options.namespace,
29
+ structured: options.structured,
30
+ });
31
+ loggerCache.set(options, logger);
32
+ return logger;
33
+ }
34
+ /**
35
+ * Create vestig middleware with custom configuration
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * // middleware.ts
40
+ * import { createVestigMiddleware } from '@vestig/next/middleware'
41
+ *
42
+ * export const middleware = createVestigMiddleware({
43
+ * skipPaths: ['/health', '/metrics'],
44
+ * })
45
+ *
46
+ * export const config = {
47
+ * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
48
+ * }
49
+ * ```
50
+ */
51
+ export function createVestigMiddleware(options = {}) {
52
+ const mergedOptions = { ...DEFAULT_OPTIONS, ...options };
53
+ return function vestigMiddleware(request) {
54
+ // Skip configured paths
55
+ const pathname = request.nextUrl.pathname;
56
+ const skipPaths = mergedOptions.skipPaths;
57
+ if (skipPaths.some((p) => pathname.startsWith(p))) {
58
+ return NextResponse.next();
59
+ }
60
+ const logger = getOrCreateLogger(mergedOptions);
61
+ const log = logger.child('request');
62
+ const timing = createRequestTiming();
63
+ // Extract or generate correlation context
64
+ const requestIdHeader = mergedOptions.requestIdHeader;
65
+ const existingRequestId = request.headers.get(requestIdHeader) ?? undefined;
66
+ const traceparent = request.headers.get(CORRELATION_HEADERS.TRACEPARENT);
67
+ const parsed = traceparent ? parseTraceparent(traceparent) : null;
68
+ const ctx = createCorrelationContext({
69
+ requestId: existingRequestId,
70
+ traceId: parsed?.traceId,
71
+ spanId: parsed?.spanId,
72
+ });
73
+ // Log incoming request
74
+ const requestLogLevel = mergedOptions.requestLogLevel;
75
+ log[requestLogLevel]('Request received', {
76
+ method: request.method,
77
+ path: pathname,
78
+ search: request.nextUrl.search || undefined,
79
+ userAgent: request.headers.get('user-agent')?.slice(0, 100),
80
+ ip: request.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ??
81
+ request.headers.get('x-real-ip'),
82
+ requestId: ctx.requestId,
83
+ traceId: ctx.traceId,
84
+ });
85
+ // Create new headers with correlation IDs
86
+ const requestHeaders = new Headers(request.headers);
87
+ requestHeaders.set(CORRELATION_HEADERS.REQUEST_ID, ctx.requestId);
88
+ requestHeaders.set(CORRELATION_HEADERS.TRACE_ID, ctx.traceId);
89
+ requestHeaders.set(CORRELATION_HEADERS.SPAN_ID, ctx.spanId);
90
+ requestHeaders.set(CORRELATION_HEADERS.TRACEPARENT, createTraceparent(ctx.traceId, ctx.spanId));
91
+ // Create response with updated headers
92
+ const response = NextResponse.next({
93
+ request: {
94
+ headers: requestHeaders,
95
+ },
96
+ });
97
+ // Add correlation headers to response
98
+ response.headers.set(CORRELATION_HEADERS.REQUEST_ID, ctx.requestId);
99
+ response.headers.set(CORRELATION_HEADERS.TRACE_ID, ctx.traceId);
100
+ // Log response with timing if enabled
101
+ if (mergedOptions.timing) {
102
+ const duration = timing.complete();
103
+ const responseLogLevel = mergedOptions.responseLogLevel;
104
+ log[responseLogLevel]('Response sent', {
105
+ method: request.method,
106
+ path: pathname,
107
+ duration: formatDuration(duration),
108
+ durationMs: duration,
109
+ requestId: ctx.requestId,
110
+ });
111
+ }
112
+ return response;
113
+ };
114
+ }
115
+ /**
116
+ * Pre-configured vestig middleware for direct export (deprecated, use proxy instead)
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * // middleware.ts (deprecated in Next.js 16+)
121
+ * export { vestigMiddleware as middleware } from '@vestig/next/middleware'
122
+ *
123
+ * export const config = {
124
+ * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
125
+ * }
126
+ * ```
127
+ * @deprecated Use createVestigProxy for Next.js 16+
128
+ */
129
+ export const vestigMiddleware = createVestigMiddleware();
130
+ /**
131
+ * Create vestig proxy for Next.js 16+ (replaces middleware)
132
+ *
133
+ * In Next.js 16, middleware.ts was renamed to proxy.ts and runs on Node.js runtime
134
+ * instead of Edge runtime.
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * // proxy.ts (Next.js 16+)
139
+ * import { createVestigProxy } from '@vestig/next/middleware'
140
+ *
141
+ * export const proxy = createVestigProxy({
142
+ * skipPaths: ['/health', '/metrics'],
143
+ * })
144
+ *
145
+ * export const config = {
146
+ * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
147
+ * }
148
+ * ```
149
+ */
150
+ export function createVestigProxy(options = {}) {
151
+ // Proxy uses the same implementation as middleware
152
+ // but is exported with the correct name for proxy.ts
153
+ return createVestigMiddleware(options);
154
+ }
155
+ /**
156
+ * Pre-configured vestig proxy for direct export
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * // proxy.ts (Next.js 16+)
161
+ * export { vestigProxy as proxy } from '@vestig/next/middleware'
162
+ *
163
+ * export const config = {
164
+ * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
165
+ * }
166
+ * ```
167
+ */
168
+ export const vestigProxy = createVestigProxy();
169
+ /**
170
+ * Helper to create proxy/middleware config matcher
171
+ */
172
+ export function createProxyMatcher(options = {}) {
173
+ const include = options.include ?? ['/((?!_next/static|_next/image|favicon.ico).*)'];
174
+ return {
175
+ matcher: include,
176
+ };
177
+ }
178
+ /**
179
+ * @deprecated Use createProxyMatcher instead
180
+ */
181
+ export const createMiddlewareMatcher = createProxyMatcher;
182
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/server/middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ import { type LogLevel, type SanitizePreset } from 'vestig';
2
+ import type { RouteHandler, WithVestigOptions } from '../types';
3
+ type NextRequest = Request & {
4
+ nextUrl?: URL;
5
+ };
6
+ type RouteContext = {
7
+ params: Promise<Record<string, string>>;
8
+ };
9
+ export interface RouteHandlerOptions extends WithVestigOptions {
10
+ /** Log level for the route handler logger */
11
+ level?: LogLevel;
12
+ /** Enable/disable logging */
13
+ enabled?: boolean;
14
+ /** PII sanitization preset */
15
+ sanitize?: SanitizePreset;
16
+ /** Use structured JSON output */
17
+ structured?: boolean;
18
+ /** Additional context to include in all logs */
19
+ context?: Record<string, unknown>;
20
+ }
21
+ /**
22
+ * Wrap a route handler with vestig logging
23
+ *
24
+ * Provides automatic:
25
+ * - Request correlation (requestId, traceId, spanId)
26
+ * - Request/response logging with timing
27
+ * - Context propagation
28
+ * - Error logging
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * // app/api/users/route.ts
33
+ * import { withVestig } from '@vestig/next'
34
+ *
35
+ * export const GET = withVestig(
36
+ * async (request, { log, ctx, timing }) => {
37
+ * log.debug('Fetching users from database')
38
+ *
39
+ * const users = await db.users.findMany()
40
+ *
41
+ * log.info('Users fetched', {
42
+ * count: users.length,
43
+ * duration: `${timing.elapsed().toFixed(2)}ms`,
44
+ * })
45
+ *
46
+ * return Response.json({
47
+ * users,
48
+ * meta: { requestId: ctx.requestId },
49
+ * })
50
+ * },
51
+ * { namespace: 'api:users' }
52
+ * )
53
+ * ```
54
+ */
55
+ export declare function withVestig<T = Response>(handler: RouteHandler<T>, options?: RouteHandlerOptions): (request: NextRequest, routeContext?: RouteContext) => Promise<T>;
56
+ /**
57
+ * Create route handlers for all HTTP methods at once
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * // app/api/users/route.ts
62
+ * import { createRouteHandlers } from '@vestig/next'
63
+ *
64
+ * export const { GET, POST, DELETE } = createRouteHandlers(
65
+ * {
66
+ * async GET(req, { log }) {
67
+ * log.info('Fetching users')
68
+ * return Response.json(users)
69
+ * },
70
+ * async POST(req, { log }) {
71
+ * log.info('Creating user')
72
+ * return Response.json(user, { status: 201 })
73
+ * },
74
+ * async DELETE(req, { log, params }) {
75
+ * log.info('Deleting user', { id: params.id })
76
+ * return new Response(null, { status: 204 })
77
+ * },
78
+ * },
79
+ * { namespace: 'api:users' }
80
+ * )
81
+ * ```
82
+ */
83
+ export declare function createRouteHandlers(handlers: {
84
+ GET?: RouteHandler;
85
+ POST?: RouteHandler;
86
+ PUT?: RouteHandler;
87
+ PATCH?: RouteHandler;
88
+ DELETE?: RouteHandler;
89
+ HEAD?: RouteHandler;
90
+ OPTIONS?: RouteHandler;
91
+ }, options?: RouteHandlerOptions): Record<string, ReturnType<typeof withVestig>>;
92
+ export {};
93
+ //# sourceMappingURL=route-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-handler.d.ts","sourceRoot":"","sources":["../../src/server/route-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,QAAQ,EAEb,KAAK,cAAc,EAInB,MAAM,QAAQ,CAAA;AACf,OAAO,KAAK,EAAE,YAAY,EAAuB,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAKpF,KAAK,WAAW,GAAG,OAAO,GAAG;IAAE,OAAO,CAAC,EAAE,GAAG,CAAA;CAAE,CAAA;AAC9C,KAAK,YAAY,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAAE,CAAA;AAE/D,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC7D,6CAA6C;IAC7C,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,cAAc,CAAA;IACzB,iCAAiC;IACjC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,UAAU,CAAC,CAAC,GAAG,QAAQ,EACtC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EACxB,OAAO,GAAE,mBAAwB,GAC/B,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC,CAAC,CAmFnE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,mBAAmB,CAClC,QAAQ,EAAE;IACT,GAAG,CAAC,EAAE,YAAY,CAAA;IAClB,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,GAAG,CAAC,EAAE,YAAY,CAAA;IAClB,KAAK,CAAC,EAAE,YAAY,CAAA;IACpB,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,OAAO,CAAC,EAAE,YAAY,CAAA;CACtB,EACD,OAAO,GAAE,mBAAwB,GAC/B,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAa/C"}
@@ -0,0 +1,160 @@
1
+ import { createCorrelationContext, createLogger, withContext, } from 'vestig';
2
+ import { extractCorrelationHeaders, setCorrelationHeaders } from '../utils/headers';
3
+ import { extractRequestMetadata } from '../utils/metadata';
4
+ import { createRequestTiming, formatDuration } from '../utils/timing';
5
+ const DEFAULT_OPTIONS = {
6
+ level: 'info',
7
+ enabled: true,
8
+ sanitize: 'default',
9
+ structured: true,
10
+ logRequest: true,
11
+ logResponse: true,
12
+ };
13
+ /**
14
+ * Wrap a route handler with vestig logging
15
+ *
16
+ * Provides automatic:
17
+ * - Request correlation (requestId, traceId, spanId)
18
+ * - Request/response logging with timing
19
+ * - Context propagation
20
+ * - Error logging
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * // app/api/users/route.ts
25
+ * import { withVestig } from '@vestig/next'
26
+ *
27
+ * export const GET = withVestig(
28
+ * async (request, { log, ctx, timing }) => {
29
+ * log.debug('Fetching users from database')
30
+ *
31
+ * const users = await db.users.findMany()
32
+ *
33
+ * log.info('Users fetched', {
34
+ * count: users.length,
35
+ * duration: `${timing.elapsed().toFixed(2)}ms`,
36
+ * })
37
+ *
38
+ * return Response.json({
39
+ * users,
40
+ * meta: { requestId: ctx.requestId },
41
+ * })
42
+ * },
43
+ * { namespace: 'api:users' }
44
+ * )
45
+ * ```
46
+ */
47
+ export function withVestig(handler, options = {}) {
48
+ const mergedOptions = { ...DEFAULT_OPTIONS, ...options };
49
+ return async (request, routeContext) => {
50
+ const timing = createRequestTiming();
51
+ // Create base logger
52
+ const baseLogger = createLogger({
53
+ level: mergedOptions.level,
54
+ enabled: mergedOptions.enabled,
55
+ sanitize: mergedOptions.sanitize,
56
+ structured: mergedOptions.structured,
57
+ context: mergedOptions.context,
58
+ });
59
+ const log = mergedOptions.namespace
60
+ ? baseLogger.child(mergedOptions.namespace)
61
+ : baseLogger.child('api');
62
+ // Extract correlation context from request headers
63
+ const correlationHeaders = extractCorrelationHeaders(request.headers);
64
+ const ctx = createCorrelationContext({
65
+ requestId: correlationHeaders.requestId,
66
+ traceId: correlationHeaders.traceId,
67
+ spanId: correlationHeaders.spanId,
68
+ });
69
+ // Get route params
70
+ const params = routeContext?.params ? await routeContext.params : {};
71
+ // Create handler context
72
+ const handlerContext = {
73
+ log,
74
+ ctx,
75
+ params,
76
+ timing: {
77
+ start: timing.start,
78
+ elapsed: () => timing.elapsed(),
79
+ mark: (name) => timing.mark(name),
80
+ },
81
+ };
82
+ return withContext(ctx, async () => {
83
+ // Log request if enabled
84
+ if (mergedOptions.logRequest !== false) {
85
+ const metadata = extractRequestMetadata(request);
86
+ log.info('Request received', {
87
+ ...metadata,
88
+ requestId: ctx.requestId,
89
+ traceId: ctx.traceId,
90
+ });
91
+ }
92
+ try {
93
+ const result = await handler(request, handlerContext);
94
+ // Log response if enabled and result is Response
95
+ if (mergedOptions.logResponse !== false && result instanceof Response) {
96
+ const duration = timing.complete();
97
+ log.info('Response sent', {
98
+ status: result.status,
99
+ duration: formatDuration(duration),
100
+ durationMs: duration,
101
+ requestId: ctx.requestId,
102
+ });
103
+ // Add correlation headers to response
104
+ setCorrelationHeaders(result.headers, ctx);
105
+ }
106
+ return result;
107
+ }
108
+ catch (error) {
109
+ const duration = timing.complete();
110
+ log.error('Request failed', {
111
+ error,
112
+ duration: formatDuration(duration),
113
+ durationMs: duration,
114
+ requestId: ctx.requestId,
115
+ });
116
+ throw error;
117
+ }
118
+ });
119
+ };
120
+ }
121
+ /**
122
+ * Create route handlers for all HTTP methods at once
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * // app/api/users/route.ts
127
+ * import { createRouteHandlers } from '@vestig/next'
128
+ *
129
+ * export const { GET, POST, DELETE } = createRouteHandlers(
130
+ * {
131
+ * async GET(req, { log }) {
132
+ * log.info('Fetching users')
133
+ * return Response.json(users)
134
+ * },
135
+ * async POST(req, { log }) {
136
+ * log.info('Creating user')
137
+ * return Response.json(user, { status: 201 })
138
+ * },
139
+ * async DELETE(req, { log, params }) {
140
+ * log.info('Deleting user', { id: params.id })
141
+ * return new Response(null, { status: 204 })
142
+ * },
143
+ * },
144
+ * { namespace: 'api:users' }
145
+ * )
146
+ * ```
147
+ */
148
+ export function createRouteHandlers(handlers, options = {}) {
149
+ const result = {};
150
+ for (const [method, handler] of Object.entries(handlers)) {
151
+ if (handler) {
152
+ result[method] = withVestig(handler, {
153
+ ...options,
154
+ namespace: options.namespace ?? `api:${method.toLowerCase()}`,
155
+ });
156
+ }
157
+ }
158
+ return result;
159
+ }
160
+ //# sourceMappingURL=route-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-handler.js","sourceRoot":"","sources":["../../src/server/route-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,wBAAwB,EACxB,YAAY,EACZ,WAAW,GACX,MAAM,QAAQ,CAAA;AAEf,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AACnF,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAkBrE,MAAM,eAAe,GAAwB;IAC5C,KAAK,EAAE,MAAM;IACb,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,SAAS;IACnB,UAAU,EAAE,IAAI;IAChB,UAAU,EAAE,IAAI;IAChB,WAAW,EAAE,IAAI;CACjB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,UAAU,UAAU,CACzB,OAAwB,EACxB,UAA+B,EAAE;IAEjC,MAAM,aAAa,GAAG,EAAE,GAAG,eAAe,EAAE,GAAG,OAAO,EAAE,CAAA;IAExD,OAAO,KAAK,EAAE,OAAoB,EAAE,YAA2B,EAAE,EAAE;QAClE,MAAM,MAAM,GAAG,mBAAmB,EAAE,CAAA;QAEpC,qBAAqB;QACrB,MAAM,UAAU,GAAG,YAAY,CAAC;YAC/B,KAAK,EAAE,aAAa,CAAC,KAAK;YAC1B,OAAO,EAAE,aAAa,CAAC,OAAO;YAC9B,QAAQ,EAAE,aAAa,CAAC,QAAQ;YAChC,UAAU,EAAE,aAAa,CAAC,UAAU;YACpC,OAAO,EAAE,aAAa,CAAC,OAAO;SAC9B,CAAC,CAAA;QAEF,MAAM,GAAG,GAAG,aAAa,CAAC,SAAS;YAClC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC;YAC3C,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAE1B,mDAAmD;QACnD,MAAM,kBAAkB,GAAG,yBAAyB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QACrE,MAAM,GAAG,GAAG,wBAAwB,CAAC;YACpC,SAAS,EAAE,kBAAkB,CAAC,SAAS;YACvC,OAAO,EAAE,kBAAkB,CAAC,OAAO;YACnC,MAAM,EAAE,kBAAkB,CAAC,MAAM;SACjC,CAAC,CAAA;QAEF,mBAAmB;QACnB,MAAM,MAAM,GAAG,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;QAEpE,yBAAyB;QACzB,MAAM,cAAc,GAAwB;YAC3C,GAAG;YACH,GAAG;YACH,MAAM;YACN,MAAM,EAAE;gBACP,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE;gBAC/B,IAAI,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;aACzC;SACD,CAAA;QAED,OAAO,WAAW,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE;YAClC,yBAAyB;YACzB,IAAI,aAAa,CAAC,UAAU,KAAK,KAAK,EAAE,CAAC;gBACxC,MAAM,QAAQ,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAA;gBAChD,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE;oBAC5B,GAAG,QAAQ;oBACX,SAAS,EAAE,GAAG,CAAC,SAAS;oBACxB,OAAO,EAAE,GAAG,CAAC,OAAO;iBACpB,CAAC,CAAA;YACH,CAAC;YAED,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,CAAA;gBAErD,iDAAiD;gBACjD,IAAI,aAAa,CAAC,WAAW,KAAK,KAAK,IAAI,MAAM,YAAY,QAAQ,EAAE,CAAC;oBACvE,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAA;oBAClC,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE;wBACzB,MAAM,EAAE,MAAM,CAAC,MAAM;wBACrB,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC;wBAClC,UAAU,EAAE,QAAQ;wBACpB,SAAS,EAAE,GAAG,CAAC,SAAS;qBACxB,CAAC,CAAA;oBAEF,sCAAsC;oBACtC,qBAAqB,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;gBAC3C,CAAC;gBAED,OAAO,MAAM,CAAA;YACd,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAA;gBAClC,GAAG,CAAC,KAAK,CAAC,gBAAgB,EAAE;oBAC3B,KAAK;oBACL,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC;oBAClC,UAAU,EAAE,QAAQ;oBACpB,SAAS,EAAE,GAAG,CAAC,SAAS;iBACxB,CAAC,CAAA;gBACF,MAAM,KAAK,CAAA;YACZ,CAAC;QACF,CAAC,CAAC,CAAA;IACH,CAAC,CAAA;AACF,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,mBAAmB,CAClC,QAQC,EACD,UAA+B,EAAE;IAEjC,MAAM,MAAM,GAAkD,EAAE,CAAA;IAEhE,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1D,IAAI,OAAO,EAAE,CAAC;YACb,MAAM,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,OAAO,EAAE;gBACpC,GAAG,OAAO;gBACV,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,OAAO,MAAM,CAAC,WAAW,EAAE,EAAE;aAC7D,CAAC,CAAA;QACH,CAAC;IACF,CAAC;IAED,OAAO,MAAM,CAAA;AACd,CAAC"}
@@ -0,0 +1,74 @@
1
+ import { type LogLevel, type SanitizePreset } from 'vestig';
2
+ import type { ServerAction, VestigActionOptions } from '../types';
3
+ export interface ActionOptions extends VestigActionOptions {
4
+ /** Log level for the action logger */
5
+ level?: LogLevel;
6
+ /** Enable/disable logging */
7
+ enabled?: boolean;
8
+ /** PII sanitization preset */
9
+ sanitize?: SanitizePreset;
10
+ /** Use structured JSON output */
11
+ structured?: boolean;
12
+ /** Additional context to include in all logs */
13
+ context?: Record<string, unknown>;
14
+ }
15
+ /**
16
+ * Wrap a server action with vestig logging
17
+ *
18
+ * Provides automatic:
19
+ * - Request correlation (from headers)
20
+ * - Action start/end logging with timing
21
+ * - Error logging
22
+ * - Context propagation
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * // app/actions/user-actions.ts
27
+ * 'use server'
28
+ *
29
+ * import { vestigAction } from '@vestig/next'
30
+ *
31
+ * export const createUser = vestigAction(
32
+ * async (data: { name: string; email: string }, { log, ctx }) => {
33
+ * log.debug('Validating user data')
34
+ *
35
+ * if (!data.email.includes('@')) {
36
+ * log.warn('Invalid email provided')
37
+ * throw new Error('Invalid email')
38
+ * }
39
+ *
40
+ * log.debug('Creating user in database')
41
+ * const user = await db.users.create({ data })
42
+ *
43
+ * log.info('User created successfully', { userId: user.id })
44
+ *
45
+ * return user
46
+ * },
47
+ * { namespace: 'actions:createUser' }
48
+ * )
49
+ * ```
50
+ */
51
+ export declare function vestigAction<TInput, TOutput>(action: ServerAction<TInput, TOutput>, options?: ActionOptions): (input: TInput) => Promise<TOutput>;
52
+ /**
53
+ * Type-safe action creator with inferred types
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const createUser = createVestigAction({
58
+ * namespace: 'users:create',
59
+ * action: async (data: CreateUserInput, { log }) => {
60
+ * log.info('Creating user')
61
+ * return await db.users.create({ data })
62
+ * },
63
+ * })
64
+ * ```
65
+ */
66
+ export declare function createVestigAction<TInput, TOutput>(config: {
67
+ namespace?: string;
68
+ logInput?: boolean;
69
+ logOutput?: boolean;
70
+ level?: LogLevel;
71
+ sanitize?: SanitizePreset;
72
+ action: ServerAction<TInput, TOutput>;
73
+ }): (input: TInput) => Promise<TOutput>;
74
+ //# sourceMappingURL=server-action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-action.d.ts","sourceRoot":"","sources":["../../src/server/server-action.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,QAAQ,EAEb,KAAK,cAAc,EAInB,MAAM,QAAQ,CAAA;AACf,OAAO,KAAK,EAAiB,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAIhF,MAAM,WAAW,aAAc,SAAQ,mBAAmB;IACzD,sCAAsC;IACtC,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,cAAc,CAAA;IACzB,iCAAiC;IACjC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,EAC3C,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,OAAO,GAAE,aAAkB,GACzB,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAuErC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,QAAQ,CAAC,EAAE,cAAc,CAAA;IACzB,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAQtC"}
@@ -0,0 +1,132 @@
1
+ import { headers } from 'next/headers';
2
+ import { createCorrelationContext, createLogger, withContext, } from 'vestig';
3
+ import { CORRELATION_HEADERS } from '../utils/headers';
4
+ import { createRequestTiming, formatDuration } from '../utils/timing';
5
+ const DEFAULT_OPTIONS = {
6
+ level: 'info',
7
+ enabled: true,
8
+ sanitize: 'default',
9
+ structured: true,
10
+ logInput: false,
11
+ logOutput: false,
12
+ };
13
+ /**
14
+ * Wrap a server action with vestig logging
15
+ *
16
+ * Provides automatic:
17
+ * - Request correlation (from headers)
18
+ * - Action start/end logging with timing
19
+ * - Error logging
20
+ * - Context propagation
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * // app/actions/user-actions.ts
25
+ * 'use server'
26
+ *
27
+ * import { vestigAction } from '@vestig/next'
28
+ *
29
+ * export const createUser = vestigAction(
30
+ * async (data: { name: string; email: string }, { log, ctx }) => {
31
+ * log.debug('Validating user data')
32
+ *
33
+ * if (!data.email.includes('@')) {
34
+ * log.warn('Invalid email provided')
35
+ * throw new Error('Invalid email')
36
+ * }
37
+ *
38
+ * log.debug('Creating user in database')
39
+ * const user = await db.users.create({ data })
40
+ *
41
+ * log.info('User created successfully', { userId: user.id })
42
+ *
43
+ * return user
44
+ * },
45
+ * { namespace: 'actions:createUser' }
46
+ * )
47
+ * ```
48
+ */
49
+ export function vestigAction(action, options = {}) {
50
+ const mergedOptions = { ...DEFAULT_OPTIONS, ...options };
51
+ return async (input) => {
52
+ const headersList = await headers();
53
+ const timing = createRequestTiming();
54
+ // Create base logger
55
+ const baseLogger = createLogger({
56
+ level: mergedOptions.level,
57
+ enabled: mergedOptions.enabled,
58
+ sanitize: mergedOptions.sanitize,
59
+ structured: mergedOptions.structured,
60
+ context: mergedOptions.context,
61
+ });
62
+ const log = mergedOptions.namespace
63
+ ? baseLogger.child(mergedOptions.namespace)
64
+ : baseLogger.child('action');
65
+ // Extract correlation context from headers
66
+ const requestId = headersList.get(CORRELATION_HEADERS.REQUEST_ID) ?? undefined;
67
+ const traceId = headersList.get(CORRELATION_HEADERS.TRACE_ID) ?? undefined;
68
+ const spanId = headersList.get(CORRELATION_HEADERS.SPAN_ID) ?? undefined;
69
+ const ctx = createCorrelationContext({ requestId, traceId, spanId });
70
+ const actionContext = { log, ctx };
71
+ return withContext(ctx, async () => {
72
+ // Log action start
73
+ const startLog = {
74
+ requestId: ctx.requestId,
75
+ inputType: typeof input,
76
+ };
77
+ if (mergedOptions.logInput) {
78
+ startLog.input = input;
79
+ }
80
+ log.info('Action started', startLog);
81
+ try {
82
+ const result = await action(input, actionContext);
83
+ const duration = timing.complete();
84
+ const endLog = {
85
+ duration: formatDuration(duration),
86
+ durationMs: duration,
87
+ requestId: ctx.requestId,
88
+ success: true,
89
+ };
90
+ if (mergedOptions.logOutput) {
91
+ endLog.output = result;
92
+ }
93
+ log.info('Action completed', endLog);
94
+ return result;
95
+ }
96
+ catch (error) {
97
+ const duration = timing.complete();
98
+ log.error('Action failed', {
99
+ error,
100
+ duration: formatDuration(duration),
101
+ durationMs: duration,
102
+ requestId: ctx.requestId,
103
+ });
104
+ throw error;
105
+ }
106
+ });
107
+ };
108
+ }
109
+ /**
110
+ * Type-safe action creator with inferred types
111
+ *
112
+ * @example
113
+ * ```typescript
114
+ * const createUser = createVestigAction({
115
+ * namespace: 'users:create',
116
+ * action: async (data: CreateUserInput, { log }) => {
117
+ * log.info('Creating user')
118
+ * return await db.users.create({ data })
119
+ * },
120
+ * })
121
+ * ```
122
+ */
123
+ export function createVestigAction(config) {
124
+ return vestigAction(config.action, {
125
+ namespace: config.namespace,
126
+ logInput: config.logInput,
127
+ logOutput: config.logOutput,
128
+ level: config.level,
129
+ sanitize: config.sanitize,
130
+ });
131
+ }
132
+ //# sourceMappingURL=server-action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-action.js","sourceRoot":"","sources":["../../src/server/server-action.ts"],"names":[],"mappings":"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"}