@getvision/adapter-express 0.0.0-develop-20251031183955

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/.eslintrc.js ADDED
@@ -0,0 +1,9 @@
1
+ /** @type {import("eslint").Linter.Config} */
2
+ module.exports = {
3
+ root: true,
4
+ extends: ["@repo/eslint-config/base.js"],
5
+ parser: "@typescript-eslint/parser",
6
+ parserOptions: {
7
+ project: true,
8
+ },
9
+ };
@@ -0,0 +1 @@
1
+ $ tsc
package/README.md ADDED
@@ -0,0 +1,266 @@
1
+ # @getvision/adapter-express
2
+
3
+ Express.js adapter for Vision Dashboard.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @getvision/adapter-express
9
+ # or
10
+ npm install @getvision/adapter-express
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import express from 'express'
17
+ import { visionMiddleware, enableAutoDiscovery, zValidator } from '@getvision/adapter-express'
18
+ import { z } from 'zod'
19
+
20
+ const app = express()
21
+
22
+ // Add Vision middleware (development only)
23
+ if (process.env.NODE_ENV === 'development') {
24
+ app.use(visionMiddleware({ port: 9500 }))
25
+ }
26
+
27
+ // JSON parser
28
+ app.use(express.json())
29
+
30
+ // Your routes
31
+ app.get('/users', (req, res) => {
32
+ res.json({ users: [] })
33
+ })
34
+
35
+ // Zod validation (typed + auto-documented in Vision)
36
+ const createUser = z.object({
37
+ name: z.string().min(1).describe('Full name'),
38
+ email: z.string().email().describe('Email'),
39
+ age: z.number().int().positive().optional().describe('Age (optional)'),
40
+ })
41
+
42
+ app.post('/users', zValidator('body', createUser), (req, res) => {
43
+ res.status(201).json(req.body)
44
+ })
45
+
46
+ // Enable auto-discovery after routes
47
+ if (process.env.NODE_ENV === 'development') {
48
+ // Auto-group routes by first path segment (Users, Root, etc.)
49
+ enableAutoDiscovery(app)
50
+
51
+ // Or provide manual services grouping with glob-like patterns
52
+ // e.g. `/users/*` → "Users" service
53
+ // `/auth/*` → "Auth" service
54
+ // Unmatched → "Uncategorized"
55
+ //
56
+ // enableAutoDiscovery(app, { services: [
57
+ // { name: 'Users', description: 'User management', routes: ['/users/*'] },
58
+ // { name: 'Auth', routes: ['/auth/*'] }
59
+ // ]})
60
+ }
61
+
62
+ app.listen(3000)
63
+ ```
64
+
65
+ Visit `http://localhost:9500` to see the dashboard! 🎉
66
+
67
+ ## Features
68
+
69
+ ### Automatic Request Tracing
70
+ Every request is automatically traced with:
71
+ - HTTP method, path, query params
72
+ - Request/response headers and body (captured before/after send)
73
+ - Status code and duration
74
+ - Response capture
75
+ - Root `http.request` span with child spans (DB, etc.)
76
+
77
+ ### Custom Spans
78
+ Track operations within requests:
79
+
80
+ ```typescript
81
+ import { useVisionSpan } from '@getvision/adapter-express'
82
+
83
+ app.get('/users', async (req, res) => {
84
+ const withSpan = useVisionSpan()
85
+
86
+ const users = withSpan('db.query', {
87
+ 'db.system': 'postgresql',
88
+ 'db.table': 'users'
89
+ }, () => {
90
+ return db.select().from(users).all()
91
+ })
92
+
93
+ res.json({ users })
94
+ })
95
+ ```
96
+
97
+ ### Auto-Discovery (Services Catalog)
98
+ Automatically discover all routes:
99
+
100
+ ```typescript
101
+ enableAutoDiscovery(app)
102
+ ```
103
+
104
+ This will register all routes with Vision for the service catalog.
105
+
106
+ ## API
107
+
108
+ ### `visionMiddleware(options?)`
109
+
110
+ Express middleware for Vision.
111
+
112
+ **Options:**
113
+ ```typescript
114
+ interface VisionExpressOptions {
115
+ port?: number // Dashboard port (default: 9500)
116
+ enabled?: boolean // Enable Vision (default: true)
117
+ maxTraces?: number // Max traces to store (default: 1000)
118
+ maxLogs?: number // Max logs to store (default: 10000)
119
+ logging?: boolean // Console logging (default: true)
120
+ cors?: boolean // Auto CORS for dashboard (default: true)
121
+ service?: {
122
+ name?: string // Service name
123
+ version?: string // Service version
124
+ description?: string // Service description
125
+ integrations?: {
126
+ database?: string // Database connection
127
+ redis?: string // Redis connection
128
+ [key: string]: string | undefined
129
+ }
130
+ }
131
+ }
132
+ ```
133
+
134
+ ### `enableAutoDiscovery(app, options?)`
135
+
136
+ Enable automatic route discovery for Express app.
137
+
138
+ **Note:** Call this after all routes are defined.
139
+
140
+ ```ts
141
+ type ServiceDefinition = {
142
+ name: string
143
+ description?: string
144
+ routes: string[] // e.g. ['/users/*']
145
+ }
146
+
147
+ enableAutoDiscovery(app, {
148
+ services: [
149
+ { name: 'Users', routes: ['/users/*'] },
150
+ ]
151
+ })
152
+ ```
153
+
154
+ ### `useVisionSpan()`
155
+
156
+ Get span helper for current request. Child spans are automatically parented to the root `http.request` span for the current request.
157
+
158
+ **Returns:** `(name, attributes, fn) => result`
159
+
160
+ ```typescript
161
+ const withSpan = useVisionSpan()
162
+
163
+ const result = withSpan('operation.name', {
164
+ 'attr.key': 'value'
165
+ }, () => {
166
+ // Your operation
167
+ return result
168
+ })
169
+ ```
170
+
171
+ ### `getVisionContext()`
172
+
173
+ Get current Vision context.
174
+
175
+ **Returns:** `{ vision: VisionCore, traceId: string, rootSpanId: string }`
176
+
177
+ ```typescript
178
+ import { getVisionContext } from '@getvision/adapter-express'
179
+
180
+ app.get('/debug', (req, res) => {
181
+ const { vision, traceId } = getVisionContext()
182
+ res.json({ traceId })
183
+ })
184
+ ```
185
+
186
+ ### `getVisionInstance()`
187
+
188
+ Get the global Vision instance.
189
+
190
+ **Returns:** `VisionCore | null`
191
+
192
+ ## Environment Variables
193
+
194
+ ```bash
195
+ VISION_ENABLED=true # Enable/disable Vision
196
+ VISION_PORT=9500 # Dashboard port
197
+ NODE_ENV=development # Environment
198
+
199
+ # CORS notes
200
+ # Dashboard adds/needs headers: X-Vision-Trace-Id, X-Vision-Session
201
+ # The middleware auto-sets:
202
+ # Access-Control-Allow-Origin: *
203
+ # Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
204
+ # Access-Control-Allow-Headers: Content-Type, Authorization, X-Vision-Trace-Id, X-Vision-Session
205
+ # Access-Control-Expose-Headers: X-Vision-Trace-Id, X-Vision-Session
206
+ ```
207
+
208
+ ## Example
209
+
210
+ See [examples/express-basic](../../examples/express) for a complete example.
211
+
212
+ ## Integration with ORMs
213
+
214
+ ### Prisma
215
+
216
+ ```typescript
217
+ app.get('/users', async (req, res) => {
218
+ const withSpan = useVisionSpan()
219
+
220
+ const users = await withSpan('db.query', {
221
+ 'db.system': 'postgresql',
222
+ 'db.operation': 'findMany'
223
+ }, async () => {
224
+ return await prisma.user.findMany()
225
+ })
226
+
227
+ res.json({ users })
228
+ })
229
+ ```
230
+
231
+ ### TypeORM
232
+
233
+ ```typescript
234
+ app.get('/users', async (req, res) => {
235
+ const withSpan = useVisionSpan()
236
+
237
+ const users = await withSpan('db.query', {
238
+ 'db.system': 'postgresql',
239
+ 'db.table': 'users'
240
+ }, async () => {
241
+ return await userRepository.find()
242
+ })
243
+
244
+ res.json({ users })
245
+ })
246
+ ```
247
+
248
+ ## TypeScript
249
+
250
+ Full TypeScript support included.
251
+
252
+ ```typescript
253
+ import type { VisionExpressOptions } from '@getvision/adapter-express'
254
+
255
+ const options: VisionExpressOptions = {
256
+ port: 9500,
257
+ service: {
258
+ name: 'my-api',
259
+ version: '1.0.0'
260
+ }
261
+ }
262
+ ```
263
+
264
+ ## License
265
+
266
+ MIT
@@ -0,0 +1,84 @@
1
+ import type { Request, Response, NextFunction, Application } from 'express';
2
+ import { VisionCore } from '@getvision/core';
3
+ import type { VisionExpressOptions, ServiceDefinition } from '@getvision/core';
4
+ interface VisionContext {
5
+ vision: VisionCore;
6
+ traceId: string;
7
+ rootSpanId: string;
8
+ }
9
+ /**
10
+ * Get current vision context (vision instance and traceId)
11
+ * Available in route handlers when using visionMiddleware
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * app.get('/users', (req, res) => {
16
+ * const { vision, traceId } = getVisionContext()
17
+ * // ...
18
+ * })
19
+ * ```
20
+ */
21
+ export declare function getVisionContext(): VisionContext;
22
+ /**
23
+ * Create span helper using current trace context
24
+ * Child spans will be nested under the root http.request span
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * app.get('/users', async (req, res) => {
29
+ * const withSpan = useVisionSpan()
30
+ *
31
+ * const users = withSpan('db.select', { 'db.table': 'users' }, () => {
32
+ * return db.select().from(users).all()
33
+ * })
34
+ * })
35
+ * ```
36
+ */
37
+ export declare function useVisionSpan(): <T>(name: string, attributes: Record<string, any> | undefined, fn: () => T) => T;
38
+ /**
39
+ * Express middleware for Vision Dashboard
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * import express from 'express'
44
+ * import { visionMiddleware } from '@getvision/adapter-express'
45
+ *
46
+ * const app = express()
47
+ *
48
+ * if (process.env.NODE_ENV === 'development') {
49
+ * app.use(visionMiddleware({ port: 9500 }))
50
+ * }
51
+ *
52
+ * app.get('/hello', (req, res) => {
53
+ * res.json({ message: 'Hello!' })
54
+ * })
55
+ *
56
+ * app.listen(3000)
57
+ * ```
58
+ */
59
+ export declare function visionMiddleware(options?: VisionExpressOptions): (req: Request, res: Response, next: NextFunction) => void;
60
+ /**
61
+ * Enable automatic route discovery for Express app
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * const app = express()
66
+ * app.use(visionMiddleware())
67
+ *
68
+ * // Define routes...
69
+ * app.get('/users', handler)
70
+ * app.post('/users', handler)
71
+ *
72
+ * // Enable auto-discovery after all routes defined
73
+ * enableAutoDiscovery(app)
74
+ * ```
75
+ */
76
+ export declare function enableAutoDiscovery(app: Application, options?: {
77
+ services?: ServiceDefinition[];
78
+ }): void;
79
+ /**
80
+ * Get the current Vision instance
81
+ */
82
+ export declare function getVisionInstance(): VisionCore | null;
83
+ export { zValidator, getRouteSchema, getAllRouteSchemas } from './zod-validator';
84
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAC3E,OAAO,EACL,UAAU,EAGX,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAiB,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAK7F,UAAU,aAAa;IACrB,MAAM,EAAE,UAAU,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;CACnB;AAID;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAMhD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,KAInB,CAAC,EACP,MAAM,MAAM,EACZ,YAAY,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,YAAK,EACpC,IAAI,MAAM,CAAC,KACV,CAAC,CAqCL;AAMD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,oBAAyB,SAIlD,OAAO,OAAO,QAAQ,QAAQ,YAAY,UA8L1D;AAuFD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAA;CAAE,GAAG,IAAI,CA+FxG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,GAAG,IAAI,CAErD;AAGD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA"}