@justanalyticsapp/node 0.1.0

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 (52) hide show
  1. package/dist/client.d.ts +286 -0
  2. package/dist/client.js +681 -0
  3. package/dist/client.js.map +1 -0
  4. package/dist/context.d.ts +126 -0
  5. package/dist/context.js +170 -0
  6. package/dist/context.js.map +1 -0
  7. package/dist/errors.d.ts +135 -0
  8. package/dist/errors.js +180 -0
  9. package/dist/errors.js.map +1 -0
  10. package/dist/index.d.ts +301 -0
  11. package/dist/index.js +314 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/integrations/express.d.ts +77 -0
  14. package/dist/integrations/express.js +87 -0
  15. package/dist/integrations/express.js.map +1 -0
  16. package/dist/integrations/http.d.ts +129 -0
  17. package/dist/integrations/http.js +465 -0
  18. package/dist/integrations/http.js.map +1 -0
  19. package/dist/integrations/metrics.d.ts +110 -0
  20. package/dist/integrations/metrics.js +313 -0
  21. package/dist/integrations/metrics.js.map +1 -0
  22. package/dist/integrations/next.d.ts +252 -0
  23. package/dist/integrations/next.js +480 -0
  24. package/dist/integrations/next.js.map +1 -0
  25. package/dist/integrations/pg.d.ts +169 -0
  26. package/dist/integrations/pg.js +616 -0
  27. package/dist/integrations/pg.js.map +1 -0
  28. package/dist/integrations/pino.d.ts +52 -0
  29. package/dist/integrations/pino.js +153 -0
  30. package/dist/integrations/pino.js.map +1 -0
  31. package/dist/integrations/redis.d.ts +190 -0
  32. package/dist/integrations/redis.js +597 -0
  33. package/dist/integrations/redis.js.map +1 -0
  34. package/dist/integrations/winston.d.ts +48 -0
  35. package/dist/integrations/winston.js +99 -0
  36. package/dist/integrations/winston.js.map +1 -0
  37. package/dist/logger.d.ts +148 -0
  38. package/dist/logger.js +162 -0
  39. package/dist/logger.js.map +1 -0
  40. package/dist/span.d.ts +192 -0
  41. package/dist/span.js +197 -0
  42. package/dist/span.js.map +1 -0
  43. package/dist/transport.d.ts +246 -0
  44. package/dist/transport.js +654 -0
  45. package/dist/transport.js.map +1 -0
  46. package/dist/utils/headers.d.ts +60 -0
  47. package/dist/utils/headers.js +93 -0
  48. package/dist/utils/headers.js.map +1 -0
  49. package/dist/utils/id.d.ts +23 -0
  50. package/dist/utils/id.js +36 -0
  51. package/dist/utils/id.js.map +1 -0
  52. package/package.json +65 -0
@@ -0,0 +1,252 @@
1
+ /**
2
+ * @file packages/node-sdk/src/integrations/next.ts
3
+ * @description Next.js integration for JustAnalytics Node.js SDK.
4
+ *
5
+ * Implements Story 044 - Next.js Integration
6
+ *
7
+ * Provides zero-config initialization via Next.js 15+ instrumentation.ts hook,
8
+ * API route tracing wrappers, middleware tracing, and Server Component helpers.
9
+ *
10
+ * Quick Start (Next.js 15+):
11
+ * ```typescript
12
+ * // instrumentation.ts
13
+ * export { register } from '@justanalyticsapp/node/next';
14
+ * ```
15
+ *
16
+ * With custom config:
17
+ * ```typescript
18
+ * // instrumentation.ts
19
+ * import { withJustAnalytics } from '@justanalyticsapp/node/next';
20
+ *
21
+ * export function register() {
22
+ * withJustAnalytics({
23
+ * siteId: 'site_abc123',
24
+ * apiKey: 'ja_sk_...',
25
+ * serviceName: 'my-next-app',
26
+ * environment: 'production',
27
+ * });
28
+ * }
29
+ * ```
30
+ *
31
+ * API Route Tracing:
32
+ * ```typescript
33
+ * // app/api/users/[id]/route.ts
34
+ * import { withTracing } from '@justanalyticsapp/node/next';
35
+ *
36
+ * export const GET = withTracing(async (req, { params }) => {
37
+ * const user = await db.users.findUnique({ where: { id: params.id } });
38
+ * return Response.json(user);
39
+ * });
40
+ * ```
41
+ *
42
+ * Middleware Tracing:
43
+ * ```typescript
44
+ * // middleware.ts
45
+ * import { withMiddlewareTracing } from '@justanalyticsapp/node/next';
46
+ *
47
+ * export default withMiddlewareTracing(async (req) => {
48
+ * // your middleware logic
49
+ * return NextResponse.next();
50
+ * });
51
+ * ```
52
+ *
53
+ * Server Component Tracing:
54
+ * ```typescript
55
+ * // app/users/[id]/page.tsx
56
+ * import { traceServerComponent } from '@justanalyticsapp/node/next';
57
+ *
58
+ * export default async function UserPage({ params }) {
59
+ * return traceServerComponent('UserPage', async () => {
60
+ * const user = await getUser(params.id);
61
+ * return <UserProfile user={user} />;
62
+ * });
63
+ * }
64
+ * ```
65
+ *
66
+ * References:
67
+ * - Story 035 - Node.js SDK Core (JA.init, JA.startSpan, context)
68
+ * - Story 036 - HTTP Auto-Instrumentation (parent span creation)
69
+ * - Next.js instrumentation.ts: https://nextjs.org/docs/app/building-your-application/optimizing/instrumentation
70
+ */
71
+ import { JustAnalyticsOptions } from '../client';
72
+ /**
73
+ * Minimal NextRequest interface to avoid importing from 'next/server'.
74
+ * Follows the same pattern as express.ts's minimal Express types.
75
+ */
76
+ export interface NextRequestLike {
77
+ /** HTTP method */
78
+ method: string;
79
+ /** Full request URL string */
80
+ url: string;
81
+ /** Next.js-specific parsed URL (available on NextRequest) */
82
+ nextUrl?: {
83
+ pathname: string;
84
+ searchParams?: URLSearchParams;
85
+ };
86
+ /** Request headers */
87
+ headers: {
88
+ get(name: string): string | null;
89
+ };
90
+ }
91
+ /**
92
+ * Minimal NextResponse-like interface.
93
+ */
94
+ export interface NextResponseLike {
95
+ /** HTTP status code */
96
+ status: number;
97
+ /** Response headers */
98
+ headers: {
99
+ get(name: string): string | null;
100
+ };
101
+ }
102
+ /**
103
+ * A Next.js App Router API route handler signature.
104
+ */
105
+ export type NextRouteHandler = (req: NextRequestLike, context?: {
106
+ params?: Record<string, string | string[]>;
107
+ }) => Response | Promise<Response>;
108
+ /**
109
+ * A Next.js middleware function signature.
110
+ */
111
+ export type NextMiddlewareFunction = (req: NextRequestLike) => NextResponseLike | Response | Promise<NextResponseLike | Response>;
112
+ /**
113
+ * An async Server Component render function.
114
+ */
115
+ export type ServerComponentFunction<T> = () => T | Promise<T>;
116
+ /**
117
+ * Configuration options specific to the Next.js integration.
118
+ * Extends JustAnalyticsOptions with Next.js-specific defaults.
119
+ */
120
+ export interface NextJustAnalyticsOptions extends Partial<JustAnalyticsOptions> {
121
+ /**
122
+ * Whether to auto-detect configuration from environment variables.
123
+ * When true (default), reads JUSTANALYTICS_SITE_ID, JUSTANALYTICS_API_KEY,
124
+ * JUSTANALYTICS_SERVICE_NAME, JUSTANALYTICS_ENVIRONMENT, JUSTANALYTICS_URL.
125
+ */
126
+ autoDetectEnv?: boolean;
127
+ }
128
+ /**
129
+ * Initialize JustAnalytics with Next.js-optimized defaults.
130
+ *
131
+ * Reads configuration from environment variables when not explicitly provided.
132
+ * Safe to call multiple times (idempotent -- delegates to JA.init()'s guard).
133
+ *
134
+ * Environment variables (in order of priority: explicit config > env var > default):
135
+ * - `JUSTANALYTICS_SITE_ID` -- site ID
136
+ * - `JUSTANALYTICS_API_KEY` -- API key
137
+ * - `JUSTANALYTICS_SERVICE_NAME` -- service name (default: `'next-app'`)
138
+ * - `JUSTANALYTICS_ENVIRONMENT` -- environment (default: `NODE_ENV || 'development'`)
139
+ * - `JUSTANALYTICS_URL` -- server URL
140
+ *
141
+ * If `siteId` or `apiKey` are missing after merging config and env vars,
142
+ * the function logs a warning and returns without calling `init()`.
143
+ *
144
+ * @param config - Optional configuration overrides
145
+ */
146
+ export declare function withJustAnalytics(config?: NextJustAnalyticsOptions): void;
147
+ /**
148
+ * Next.js instrumentation.ts register() hook.
149
+ *
150
+ * Export this directly from your instrumentation.ts:
151
+ * ```typescript
152
+ * export { register } from '@justanalyticsapp/node/next';
153
+ * ```
154
+ *
155
+ * Only initializes on the Node.js runtime (skips edge runtime).
156
+ * Designed for Next.js 15+ where `instrumentation.ts` is stable.
157
+ * For Next.js 13-14, call `withJustAnalytics()` manually.
158
+ */
159
+ export declare function register(): void;
160
+ /**
161
+ * Extract the Next.js route pattern from a request.
162
+ *
163
+ * Checks Next.js internal headers in priority order:
164
+ * 1. `x-invoke-path` -- Next.js 14.1+ sets this to the file-system route
165
+ * 2. `x-matched-path` -- Some Next.js versions use this header
166
+ * 3. `x-nextjs-page` -- Older Next.js versions (13.x) may set this
167
+ * 4. Falls back to `req.nextUrl.pathname` or raw URL pathname
168
+ *
169
+ * Query strings are stripped from the returned pattern.
170
+ *
171
+ * @param req - The incoming request
172
+ * @returns The route pattern string (e.g., '/api/users/[id]')
173
+ */
174
+ export declare function extractRoutePattern(req: NextRequestLike): string;
175
+ /**
176
+ * Wrap a Next.js API route handler with tracing.
177
+ *
178
+ * Creates a server span wrapping the handler execution. The span is named
179
+ * `{METHOD} {routePattern}` (e.g., `GET /api/users/[id]`) and includes
180
+ * Next.js-specific attributes.
181
+ *
182
+ * If the SDK is not initialized, the handler is called directly (no-op pass-through).
183
+ * Never throws -- all instrumentation errors are caught silently.
184
+ *
185
+ * @param handler - The route handler function
186
+ * @returns A wrapped handler with automatic tracing
187
+ *
188
+ * @example
189
+ * ```typescript
190
+ * // app/api/users/[id]/route.ts
191
+ * import { withTracing } from '@justanalyticsapp/node/next';
192
+ *
193
+ * export const GET = withTracing(async (req, { params }) => {
194
+ * const user = await db.users.findUnique({ where: { id: params.id } });
195
+ * return Response.json(user);
196
+ * });
197
+ * ```
198
+ */
199
+ export declare function withTracing(handler: NextRouteHandler): NextRouteHandler;
200
+ /**
201
+ * Wrap Next.js middleware with tracing.
202
+ *
203
+ * Creates a span with operation name `middleware` and kind `'server'`.
204
+ * Captures the response status and any `x-middleware-rewrite` or
205
+ * `x-middleware-redirect` headers as span attributes.
206
+ *
207
+ * If the SDK is not initialized, the middleware is called directly (no-op pass-through).
208
+ * Never throws -- all instrumentation errors are caught silently.
209
+ *
210
+ * @param middleware - The middleware function
211
+ * @returns A wrapped middleware with automatic tracing
212
+ *
213
+ * @example
214
+ * ```typescript
215
+ * // middleware.ts
216
+ * import { withMiddlewareTracing } from '@justanalyticsapp/node/next';
217
+ *
218
+ * export default withMiddlewareTracing(async (req) => {
219
+ * // your middleware logic
220
+ * return NextResponse.next();
221
+ * });
222
+ * ```
223
+ */
224
+ export declare function withMiddlewareTracing(middleware: NextMiddlewareFunction): NextMiddlewareFunction;
225
+ /**
226
+ * Wrap an async Server Component render in a traced span.
227
+ *
228
+ * The span has kind `'internal'` and operation name `RSC {name}`
229
+ * (e.g., `RSC UserProfile`). It sets `next.rsc: true` to distinguish
230
+ * from API route spans.
231
+ *
232
+ * If the SDK is not initialized, the function is called directly (no-op pass-through).
233
+ * Never throws -- all instrumentation errors are caught silently.
234
+ *
235
+ * @param name - Component name for the span (e.g., 'UserProfile')
236
+ * @param fn - The async render function
237
+ * @returns The result of fn()
238
+ *
239
+ * @example
240
+ * ```typescript
241
+ * // app/users/[id]/page.tsx
242
+ * import { traceServerComponent } from '@justanalyticsapp/node/next';
243
+ *
244
+ * export default async function UserPage({ params }) {
245
+ * return traceServerComponent('UserPage', async () => {
246
+ * const user = await getUser(params.id);
247
+ * return <UserProfile user={user} />;
248
+ * });
249
+ * }
250
+ * ```
251
+ */
252
+ export declare function traceServerComponent<T>(name: string, fn: ServerComponentFunction<T>): T | Promise<T>;