@getvision/adapter-express 0.0.10 → 0.1.0-6e5c887-develop

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @getvision/adapter-express
2
2
 
3
+ ## 0.0.11
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [d5bfbe0]
8
+ - @getvision/core@0.1.0
9
+
3
10
  ## 0.0.10
4
11
 
5
12
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -81,4 +81,5 @@ export declare function enableAutoDiscovery(app: Application, options?: {
81
81
  */
82
82
  export declare function getVisionInstance(): VisionCore | null;
83
83
  export { zValidator, getRouteSchema, getAllRouteSchemas } from './zod-validator';
84
+ export { validator } from './validator';
84
85
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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,EAIX,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,UAkM1D;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"}
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,EAKX,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAiB,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAI7F,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,UAkM1D;AAuFD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAA;CAAE,GAAG,IAAI,CA8FxG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,GAAG,IAAI,CAErD;AAGD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAEhF,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA"}
package/dist/index.js CHANGED
@@ -1,6 +1,5 @@
1
- import { VisionCore, autoDetectPackageInfo, autoDetectIntegrations, runInTraceContext, } from '@getvision/core';
1
+ import { VisionCore, autoDetectPackageInfo, autoDetectIntegrations, runInTraceContext, generateTemplate, } from '@getvision/core';
2
2
  import { AsyncLocalStorage } from 'async_hooks';
3
- import { generateZodTemplate } from './zod-utils';
4
3
  const visionContext = new AsyncLocalStorage();
5
4
  /**
6
5
  * Get current vision context (vision instance and traceId)
@@ -396,8 +395,7 @@ export function enableAutoDiscovery(app, options) {
396
395
  };
397
396
  if (schema) {
398
397
  route.schema = schema;
399
- // Generate template from Zod schema
400
- const requestBody = generateZodTemplate(schema);
398
+ const requestBody = generateTemplate(schema);
401
399
  if (requestBody) {
402
400
  route.requestBody = requestBody;
403
401
  }
@@ -437,3 +435,4 @@ export function getVisionInstance() {
437
435
  }
438
436
  // Export Zod validator for schema-based validation
439
437
  export { zValidator, getRouteSchema, getAllRouteSchemas } from './zod-validator';
438
+ export { validator } from './validator';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Re-export validation types from @vision/core
3
+ */
4
+ export type { StandardSchemaV1, ValidationSchema, ValidationErrorResponse } from '@getvision/core';
5
+ export { ValidationError, createValidationErrorResponse, UniversalValidator } from '@getvision/core';
6
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACxB,MAAM,iBAAiB,CAAA;AAExB,OAAO,EACL,eAAe,EACf,6BAA6B,EAC7B,kBAAkB,EACnB,MAAM,iBAAiB,CAAA"}
package/dist/types.js ADDED
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Re-export validation types from @vision/core
3
+ */
4
+ export { ValidationError, createValidationErrorResponse, UniversalValidator } from '@getvision/core';
@@ -0,0 +1,43 @@
1
+ import type { RequestHandler } from 'express';
2
+ import type { ZodTypeAny } from 'zod';
3
+ import type { StandardSchemaV1, ValidationSchema } from '@getvision/core';
4
+ /**
5
+ * Get stored schema for a route
6
+ */
7
+ export declare function getRouteSchema(method: string, path: string): ValidationSchema | undefined;
8
+ /**
9
+ * Get all stored schemas
10
+ */
11
+ export declare function getAllRouteSchemas(): Map<string, {
12
+ method: string;
13
+ path: string;
14
+ schema: ValidationSchema;
15
+ target: string;
16
+ }>;
17
+ /**
18
+ * Universal validator middleware for Express that supports any Standard Schema-compliant library
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * import { validator } from '@getvision/adapter-express'
23
+ * import { z } from 'zod'
24
+ *
25
+ * const schema = z.object({
26
+ * name: z.string().describe('User name'),
27
+ * email: z.string().email().describe('User email'),
28
+ * })
29
+ *
30
+ * app.post('/users', validator('body', schema), (req, res) => {
31
+ * // req.body is now typed and validated
32
+ * const { name, email } = req.body
33
+ * res.json({ name, email })
34
+ * })
35
+ * ```
36
+ */
37
+ export declare function validator<S extends ZodTypeAny>(target: 'body', schema: S): RequestHandler<any, any, import('zod').infer<S>, any>;
38
+ export declare function validator<S extends ZodTypeAny>(target: 'query', schema: S): RequestHandler<any, any, any, import('zod').infer<S>>;
39
+ export declare function validator<S extends ZodTypeAny>(target: 'params', schema: S): RequestHandler<import('zod').infer<S>, any, any, any>;
40
+ export declare function validator<S extends StandardSchemaV1<any, any>>(target: 'body', schema: S): RequestHandler<any, any, StandardSchemaV1.Infer<S>['output'], any>;
41
+ export declare function validator<S extends StandardSchemaV1<any, any>>(target: 'query', schema: S): RequestHandler<any, any, any, StandardSchemaV1.Infer<S>['output']>;
42
+ export declare function validator<S extends StandardSchemaV1<any, any>>(target: 'params', schema: S): RequestHandler<StandardSchemaV1.Infer<S>['output'], any, any, any>;
43
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmC,cAAc,EAAE,MAAM,SAAS,CAAA;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AACrC,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAUzE;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAGzF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,GAAG,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAE5H;AAID;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,UAAU,EAC5C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,CAAC,GACR,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;AAExD,wBAAgB,SAAS,CAAC,CAAC,SAAS,UAAU,EAC5C,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,CAAC,GACR,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AAExD,wBAAgB,SAAS,CAAC,CAAC,SAAS,UAAU,EAC5C,MAAM,EAAE,QAAQ,EAChB,MAAM,EAAE,CAAC,GACR,cAAc,CAAC,OAAO,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAExD,wBAAgB,SAAS,CAAC,CAAC,SAAS,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,EAC5D,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,CAAC,GACR,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAA;AAErE,wBAAgB,SAAS,CAAC,CAAC,SAAS,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,EAC5D,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,CAAC,GACR,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;AAErE,wBAAgB,SAAS,CAAC,CAAC,SAAS,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,EAC5D,MAAM,EAAE,QAAQ,EAChB,MAAM,EAAE,CAAC,GACR,cAAc,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA"}
@@ -0,0 +1,72 @@
1
+ import { ValidationError, createValidationErrorResponse, UniversalValidator } from '@getvision/core';
2
+ // Store schemas for Vision introspection
3
+ const routeSchemas = new Map();
4
+ /**
5
+ * Get stored schema for a route
6
+ */
7
+ export function getRouteSchema(method, path) {
8
+ const key = `${method}:${path}`;
9
+ return routeSchemas.get(key)?.schema;
10
+ }
11
+ /**
12
+ * Get all stored schemas
13
+ */
14
+ export function getAllRouteSchemas() {
15
+ return routeSchemas;
16
+ }
17
+ export function validator(target, schema) {
18
+ const middleware = (req, res, next) => {
19
+ // Store schema for Vision (we'll update it later with actual route info)
20
+ const key = `${req.method}:${req.route?.path || req.path}`;
21
+ if (req.route?.path) {
22
+ routeSchemas.set(key, {
23
+ method: req.method,
24
+ path: req.route.path,
25
+ schema,
26
+ target,
27
+ });
28
+ }
29
+ // Get data to validate based on target
30
+ let data;
31
+ switch (target) {
32
+ case 'body':
33
+ data = req.body;
34
+ break;
35
+ case 'query':
36
+ data = req.query;
37
+ break;
38
+ case 'params':
39
+ data = req.params;
40
+ break;
41
+ default:
42
+ return next(new Error(`Invalid validation target: ${target}`));
43
+ }
44
+ try {
45
+ // Validate data using UniversalValidator
46
+ const validated = UniversalValidator.parse(schema, data);
47
+ // Store validated data back
48
+ switch (target) {
49
+ case 'body':
50
+ req.body = validated;
51
+ break;
52
+ case 'query':
53
+ req.query = validated;
54
+ break;
55
+ case 'params':
56
+ req.params = validated;
57
+ break;
58
+ }
59
+ next();
60
+ }
61
+ catch (error) {
62
+ if (error instanceof ValidationError) {
63
+ const requestId = req.headers['x-request-id'];
64
+ return res.status(400).json(createValidationErrorResponse(error.issues, requestId));
65
+ }
66
+ next(error);
67
+ }
68
+ };
69
+ middleware.__visionSchema = schema;
70
+ middleware.__visionTarget = target;
71
+ return middleware;
72
+ }
@@ -14,6 +14,7 @@ export declare function getAllRouteSchemas(): Map<string, {
14
14
  }>;
15
15
  type ValidateTarget = 'body' | 'query' | 'params';
16
16
  /**
17
+ * @deprecated Use validator instead
17
18
  * Zod validator middleware for Express
18
19
  * Similar to @hono/zod-validator but stores schema for Vision introspection
19
20
  *
@@ -1 +1 @@
1
- {"version":3,"file":"zod-validator.d.ts","sourceRoot":"","sources":["../src/zod-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmC,cAAc,EAAE,MAAM,SAAS,CAAA;AAC9E,OAAO,KAAK,EAAE,SAAS,EAAY,MAAM,KAAK,CAAA;AAK9C;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAGlF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,GAAG,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC,CAErG;AAED,KAAK,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;AAEjD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,EAC5C,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,CAAC,GACR,cAAc,CA6DhB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,cAAc,GAAG,SAAS,GAAG,SAAS,CAG/E"}
1
+ {"version":3,"file":"zod-validator.d.ts","sourceRoot":"","sources":["../src/zod-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmC,cAAc,EAAE,MAAM,SAAS,CAAA;AAC9E,OAAO,KAAK,EAAE,SAAS,EAAY,MAAM,KAAK,CAAA;AAK9C;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAGlF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,GAAG,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC,CAErG;AAED,KAAK,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;AAEjD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,EAC5C,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,CAAC,GACR,cAAc,CA6DhB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,cAAc,GAAG,SAAS,GAAG,SAAS,CAG/E"}
@@ -14,6 +14,7 @@ export function getAllRouteSchemas() {
14
14
  return routeSchemas;
15
15
  }
16
16
  /**
17
+ * @deprecated Use validator instead
17
18
  * Zod validator middleware for Express
18
19
  * Similar to @hono/zod-validator but stores schema for Vision introspection
19
20
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getvision/adapter-express",
3
- "version": "0.0.10",
3
+ "version": "0.1.0-6e5c887-develop",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./src/index.ts"
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "license": "MIT",
14
14
  "dependencies": {
15
- "@getvision/core": "0.0.8",
15
+ "@getvision/core": "0.1.0",
16
16
  "zod": "^4.1.11"
17
17
  },
18
18
  "peerDependencies": {
package/src/index.ts CHANGED
@@ -4,10 +4,10 @@ import {
4
4
  autoDetectPackageInfo,
5
5
  autoDetectIntegrations,
6
6
  runInTraceContext,
7
+ generateTemplate,
7
8
  } from '@getvision/core'
8
9
  import type { RouteMetadata, VisionExpressOptions, ServiceDefinition } from '@getvision/core'
9
10
  import { AsyncLocalStorage } from 'async_hooks'
10
- import { generateZodTemplate } from './zod-utils'
11
11
 
12
12
  // Context storage for vision, traceId, and rootSpanId
13
13
  interface VisionContext {
@@ -483,8 +483,7 @@ export function enableAutoDiscovery(app: Application, options?: { services?: Ser
483
483
 
484
484
  if (schema) {
485
485
  route.schema = schema
486
- // Generate template from Zod schema
487
- const requestBody = generateZodTemplate(schema)
486
+ const requestBody = generateTemplate(schema)
488
487
  if (requestBody) {
489
488
  route.requestBody = requestBody
490
489
  }
@@ -532,3 +531,5 @@ export function getVisionInstance(): VisionCore | null {
532
531
 
533
532
  // Export Zod validator for schema-based validation
534
533
  export { zValidator, getRouteSchema, getAllRouteSchemas } from './zod-validator'
534
+
535
+ export { validator } from './validator'
package/src/types.ts ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Re-export validation types from @vision/core
3
+ */
4
+
5
+ export type {
6
+ StandardSchemaV1,
7
+ ValidationSchema,
8
+ ValidationErrorResponse
9
+ } from '@getvision/core'
10
+
11
+ export {
12
+ ValidationError,
13
+ createValidationErrorResponse,
14
+ UniversalValidator
15
+ } from '@getvision/core'
@@ -0,0 +1,146 @@
1
+ import type { Request, Response, NextFunction, RequestHandler } from 'express'
2
+ import type { ZodTypeAny } from 'zod'
3
+ import type { StandardSchemaV1, ValidationSchema } from '@getvision/core'
4
+ import {
5
+ ValidationError,
6
+ createValidationErrorResponse,
7
+ UniversalValidator
8
+ } from '@getvision/core'
9
+
10
+ // Store schemas for Vision introspection
11
+ const routeSchemas = new Map<string, { method: string; path: string; schema: ValidationSchema; target: string }>()
12
+
13
+ /**
14
+ * Get stored schema for a route
15
+ */
16
+ export function getRouteSchema(method: string, path: string): ValidationSchema | undefined {
17
+ const key = `${method}:${path}`
18
+ return routeSchemas.get(key)?.schema
19
+ }
20
+
21
+ /**
22
+ * Get all stored schemas
23
+ */
24
+ export function getAllRouteSchemas(): Map<string, { method: string; path: string; schema: ValidationSchema; target: string }> {
25
+ return routeSchemas
26
+ }
27
+
28
+ type ValidateTarget = 'body' | 'query' | 'params'
29
+
30
+ /**
31
+ * Universal validator middleware for Express that supports any Standard Schema-compliant library
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * import { validator } from '@getvision/adapter-express'
36
+ * import { z } from 'zod'
37
+ *
38
+ * const schema = z.object({
39
+ * name: z.string().describe('User name'),
40
+ * email: z.string().email().describe('User email'),
41
+ * })
42
+ *
43
+ * app.post('/users', validator('body', schema), (req, res) => {
44
+ * // req.body is now typed and validated
45
+ * const { name, email } = req.body
46
+ * res.json({ name, email })
47
+ * })
48
+ * ```
49
+ */
50
+ export function validator<S extends ZodTypeAny>(
51
+ target: 'body',
52
+ schema: S
53
+ ): RequestHandler<any, any, import('zod').infer<S>, any>
54
+
55
+ export function validator<S extends ZodTypeAny>(
56
+ target: 'query',
57
+ schema: S
58
+ ): RequestHandler<any, any, any, import('zod').infer<S>>
59
+
60
+ export function validator<S extends ZodTypeAny>(
61
+ target: 'params',
62
+ schema: S
63
+ ): RequestHandler<import('zod').infer<S>, any, any, any>
64
+
65
+ export function validator<S extends StandardSchemaV1<any, any>>(
66
+ target: 'body',
67
+ schema: S
68
+ ): RequestHandler<any, any, StandardSchemaV1.Infer<S>['output'], any>
69
+
70
+ export function validator<S extends StandardSchemaV1<any, any>>(
71
+ target: 'query',
72
+ schema: S
73
+ ): RequestHandler<any, any, any, StandardSchemaV1.Infer<S>['output']>
74
+
75
+ export function validator<S extends StandardSchemaV1<any, any>>(
76
+ target: 'params',
77
+ schema: S
78
+ ): RequestHandler<StandardSchemaV1.Infer<S>['output'], any, any, any>
79
+
80
+ export function validator(
81
+ target: ValidateTarget,
82
+ schema: ValidationSchema
83
+ ): RequestHandler {
84
+ const middleware: RequestHandler = (req: Request, res: Response, next: NextFunction) => {
85
+ // Store schema for Vision (we'll update it later with actual route info)
86
+ const key = `${req.method}:${req.route?.path || req.path}`
87
+ if (req.route?.path) {
88
+ routeSchemas.set(key, {
89
+ method: req.method,
90
+ path: req.route.path,
91
+ schema,
92
+ target,
93
+ })
94
+ }
95
+
96
+ // Get data to validate based on target
97
+ let data: unknown
98
+ switch (target) {
99
+ case 'body':
100
+ data = req.body
101
+ break
102
+ case 'query':
103
+ data = req.query
104
+ break
105
+ case 'params':
106
+ data = req.params
107
+ break
108
+ default:
109
+ return next(new Error(`Invalid validation target: ${target}`))
110
+ }
111
+
112
+ try {
113
+ // Validate data using UniversalValidator
114
+ const validated = UniversalValidator.parse(schema, data)
115
+
116
+ // Store validated data back
117
+ switch (target) {
118
+ case 'body':
119
+ req.body = validated
120
+ break
121
+ case 'query':
122
+ req.query = validated as any
123
+ break
124
+ case 'params':
125
+ req.params = validated as any
126
+ break
127
+ }
128
+
129
+ next()
130
+ } catch (error) {
131
+ if (error instanceof ValidationError) {
132
+ const requestId = req.headers['x-request-id'] as string
133
+ return res.status(400).json(
134
+ createValidationErrorResponse(error.issues, requestId)
135
+ )
136
+ }
137
+ next(error)
138
+ }
139
+ }
140
+
141
+ // Attach schema to middleware for Vision introspection
142
+ ;(middleware as any).__visionSchema = schema
143
+ ;(middleware as any).__visionTarget = target
144
+
145
+ return middleware
146
+ }
@@ -22,6 +22,7 @@ export function getAllRouteSchemas(): Map<string, { method: string; path: string
22
22
  type ValidateTarget = 'body' | 'query' | 'params'
23
23
 
24
24
  /**
25
+ * @deprecated Use validator instead
25
26
  * Zod validator middleware for Express
26
27
  * Similar to @hono/zod-validator but stores schema for Vision introspection
27
28
  *
@@ -1,7 +0,0 @@
1
- import type { ZodType } from 'zod';
2
- import type { RequestBodySchema } from '@getvision/core';
3
- /**
4
- * Generate JSON template with comments from Zod schema
5
- */
6
- export declare function generateZodTemplate(schema: ZodType): RequestBodySchema | undefined;
7
- //# sourceMappingURL=zod-utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"zod-utils.d.ts","sourceRoot":"","sources":["../src/zod-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAyB,MAAM,KAAK,CAAA;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAe,MAAM,iBAAiB,CAAA;AAErE;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,iBAAiB,GAAG,SAAS,CAalF"}
package/dist/zod-utils.js DELETED
@@ -1,145 +0,0 @@
1
- /**
2
- * Generate JSON template with comments from Zod schema
3
- */
4
- export function generateZodTemplate(schema) {
5
- try {
6
- const fields = extractZodFields(schema);
7
- const template = generateJsonTemplate(fields);
8
- return {
9
- template,
10
- fields,
11
- };
12
- }
13
- catch (error) {
14
- console.warn('Failed to generate template from Zod schema:', error);
15
- return undefined;
16
- }
17
- }
18
- /**
19
- * Extract fields from Zod schema (supports v3 and v4)
20
- */
21
- function extractZodFields(schema, path = []) {
22
- const fields = [];
23
- // Support both v3 (_def) and v4 (def)
24
- const def = schema.def || schema._def;
25
- if (!def)
26
- return fields;
27
- // Unwrap ZodOptional, ZodNullable, ZodDefault - not needed for top level object
28
- let unwrapped = schema;
29
- const currentDef = unwrapped.def || unwrapped._def;
30
- const typeName = currentDef?.type || currentDef?.typeName;
31
- if (typeName === 'object' || typeName === 'ZodObject') {
32
- // Get shape - it can be a function (getter) or direct object
33
- const shapeValue = currentDef?.shape;
34
- const shape = typeof shapeValue === 'function' ? shapeValue() : shapeValue;
35
- for (const [key, value] of Object.entries(shape || {})) {
36
- const fieldSchema = value;
37
- const fieldDef = fieldSchema.def || fieldSchema._def;
38
- const isOptional = fieldSchema.type === 'optional' ||
39
- fieldDef?.type === 'optional' ||
40
- fieldDef?.typeName === 'ZodOptional' ||
41
- fieldDef?.typeName === 'ZodDefault';
42
- // Get description - might be in wrapped schema for optional fields
43
- let description = fieldDef?.description || fieldSchema.description;
44
- if (!description && fieldDef?.wrapped) {
45
- const wrappedDef = fieldDef.wrapped.def || fieldDef.wrapped._def;
46
- description = wrappedDef?.description || fieldDef.wrapped.description;
47
- }
48
- // Determine type
49
- let fieldType = getZodType(fieldSchema);
50
- // Check for nested objects/arrays
51
- const nested = extractZodFields(fieldSchema, [...path, key]);
52
- fields.push({
53
- name: key,
54
- type: fieldType,
55
- description,
56
- required: !isOptional,
57
- nested: nested.length > 0 ? nested : undefined,
58
- example: getZodExample(fieldSchema, fieldType),
59
- });
60
- }
61
- }
62
- return fields;
63
- }
64
- /**
65
- * Get Zod type as string (supports v3 and v4)
66
- */
67
- function getZodType(schema) {
68
- let unwrapped = schema;
69
- let def = unwrapped.def || unwrapped._def;
70
- // Unwrap optional/nullable/default
71
- while (def?.type === 'optional' ||
72
- def?.type === 'nullable' ||
73
- def?.type === 'default' ||
74
- def?.typeName === 'ZodOptional' ||
75
- def?.typeName === 'ZodNullable' ||
76
- def?.typeName === 'ZodDefault') {
77
- unwrapped = def?.innerType || def?.wrapped || unwrapped;
78
- def = unwrapped.def || unwrapped._def;
79
- }
80
- // Support both v4 (type) and v3 (typeName)
81
- const typeName = def?.type || def?.typeName || unwrapped.type;
82
- switch (typeName) {
83
- case 'string':
84
- case 'ZodString':
85
- return 'string';
86
- case 'number':
87
- case 'ZodNumber':
88
- return 'number';
89
- case 'boolean':
90
- case 'ZodBoolean':
91
- return 'boolean';
92
- case 'array':
93
- case 'ZodArray':
94
- return 'array';
95
- case 'object':
96
- case 'ZodObject':
97
- return 'object';
98
- case 'enum':
99
- case 'ZodEnum':
100
- return 'enum';
101
- case 'date':
102
- case 'ZodDate':
103
- return 'date';
104
- default:
105
- return 'any';
106
- }
107
- }
108
- /**
109
- * Get example value for Zod type
110
- */
111
- function getZodExample(schema, type) {
112
- switch (type) {
113
- case 'string': return '';
114
- case 'number': return 0;
115
- case 'boolean': return false;
116
- case 'array': return [];
117
- case 'object': return {};
118
- default: return null;
119
- }
120
- }
121
- /**
122
- * Generate JSONC template with comments
123
- */
124
- function generateJsonTemplate(fields, indent = 0) {
125
- const lines = [];
126
- const spacing = ' '.repeat(indent);
127
- lines.push('{');
128
- fields.forEach((field, index) => {
129
- const isLast = index === fields.length - 1;
130
- const description = field.description || field.name;
131
- // Add comment
132
- lines.push(`${spacing} // ${description}`);
133
- // Add field
134
- let value;
135
- if (field.nested && field.nested.length > 0) {
136
- value = generateJsonTemplate(field.nested, indent + 1);
137
- }
138
- else {
139
- value = JSON.stringify(field.example);
140
- }
141
- lines.push(`${spacing} "${field.name}": ${value}${isLast ? '' : ','}`);
142
- });
143
- lines.push(`${spacing}}`);
144
- return lines.join('\n');
145
- }
package/src/zod-utils.ts DELETED
@@ -1,170 +0,0 @@
1
- import type { ZodType, ZodObject, ZodTypeAny } from 'zod'
2
- import type { RequestBodySchema, SchemaField } from '@getvision/core'
3
-
4
- /**
5
- * Generate JSON template with comments from Zod schema
6
- */
7
- export function generateZodTemplate(schema: ZodType): RequestBodySchema | undefined {
8
- try {
9
- const fields = extractZodFields(schema)
10
- const template = generateJsonTemplate(fields)
11
-
12
- return {
13
- template,
14
- fields,
15
- }
16
- } catch (error) {
17
- console.warn('Failed to generate template from Zod schema:', error)
18
- return undefined
19
- }
20
- }
21
-
22
- /**
23
- * Extract fields from Zod schema (supports v3 and v4)
24
- */
25
- function extractZodFields(schema: ZodTypeAny, path: string[] = []): SchemaField[] {
26
- const fields: SchemaField[] = []
27
-
28
- // Support both v3 (_def) and v4 (def)
29
- const def = (schema as any).def || (schema as any)._def
30
- if (!def) return fields
31
-
32
- // Unwrap ZodOptional, ZodNullable, ZodDefault - not needed for top level object
33
- let unwrapped: any = schema
34
-
35
- const currentDef = (unwrapped as any).def || (unwrapped as any)._def
36
- const typeName = currentDef?.type || currentDef?.typeName
37
-
38
- if (typeName === 'object' || typeName === 'ZodObject') {
39
- // Get shape - it can be a function (getter) or direct object
40
- const shapeValue = currentDef?.shape
41
- const shape = typeof shapeValue === 'function' ? shapeValue() : shapeValue
42
-
43
- for (const [key, value] of Object.entries(shape || {})) {
44
- const fieldSchema: any = value
45
- const fieldDef = fieldSchema.def || fieldSchema._def
46
- const isOptional = fieldSchema.type === 'optional' ||
47
- fieldDef?.type === 'optional' ||
48
- fieldDef?.typeName === 'ZodOptional' ||
49
- fieldDef?.typeName === 'ZodDefault'
50
-
51
- // Get description - might be in wrapped schema for optional fields
52
- let description = fieldDef?.description || fieldSchema.description
53
- if (!description && fieldDef?.wrapped) {
54
- const wrappedDef = fieldDef.wrapped.def || fieldDef.wrapped._def
55
- description = wrappedDef?.description || fieldDef.wrapped.description
56
- }
57
-
58
- // Determine type
59
- let fieldType = getZodType(fieldSchema)
60
-
61
- // Check for nested objects/arrays
62
- const nested = extractZodFields(fieldSchema, [...path, key])
63
-
64
- fields.push({
65
- name: key,
66
- type: fieldType,
67
- description,
68
- required: !isOptional,
69
- nested: nested.length > 0 ? nested : undefined,
70
- example: getZodExample(fieldSchema, fieldType),
71
- })
72
- }
73
- }
74
-
75
- return fields
76
- }
77
-
78
- /**
79
- * Get Zod type as string (supports v3 and v4)
80
- */
81
- function getZodType(schema: ZodTypeAny): string {
82
- let unwrapped: any = schema
83
- let def = (unwrapped as any).def || (unwrapped as any)._def
84
-
85
- // Unwrap optional/nullable/default
86
- while (def?.type === 'optional' ||
87
- def?.type === 'nullable' ||
88
- def?.type === 'default' ||
89
- def?.typeName === 'ZodOptional' ||
90
- def?.typeName === 'ZodNullable' ||
91
- def?.typeName === 'ZodDefault') {
92
- unwrapped = def?.innerType || def?.wrapped || unwrapped
93
- def = (unwrapped as any).def || (unwrapped as any)._def
94
- }
95
-
96
- // Support both v4 (type) and v3 (typeName)
97
- const typeName = def?.type || def?.typeName || (unwrapped as any).type
98
-
99
- switch (typeName) {
100
- case 'string':
101
- case 'ZodString':
102
- return 'string'
103
- case 'number':
104
- case 'ZodNumber':
105
- return 'number'
106
- case 'boolean':
107
- case 'ZodBoolean':
108
- return 'boolean'
109
- case 'array':
110
- case 'ZodArray':
111
- return 'array'
112
- case 'object':
113
- case 'ZodObject':
114
- return 'object'
115
- case 'enum':
116
- case 'ZodEnum':
117
- return 'enum'
118
- case 'date':
119
- case 'ZodDate':
120
- return 'date'
121
- default:
122
- return 'any'
123
- }
124
- }
125
-
126
- /**
127
- * Get example value for Zod type
128
- */
129
- function getZodExample(schema: ZodTypeAny, type: string): any {
130
- switch (type) {
131
- case 'string': return ''
132
- case 'number': return 0
133
- case 'boolean': return false
134
- case 'array': return []
135
- case 'object': return {}
136
- default: return null
137
- }
138
- }
139
-
140
- /**
141
- * Generate JSONC template with comments
142
- */
143
- function generateJsonTemplate(fields: SchemaField[], indent = 0): string {
144
- const lines: string[] = []
145
- const spacing = ' '.repeat(indent)
146
-
147
- lines.push('{')
148
-
149
- fields.forEach((field, index) => {
150
- const isLast = index === fields.length - 1
151
- const description = field.description || field.name
152
-
153
- // Add comment
154
- lines.push(`${spacing} // ${description}`)
155
-
156
- // Add field
157
- let value: string
158
- if (field.nested && field.nested.length > 0) {
159
- value = generateJsonTemplate(field.nested, indent + 1)
160
- } else {
161
- value = JSON.stringify(field.example)
162
- }
163
-
164
- lines.push(`${spacing} "${field.name}": ${value}${isLast ? '' : ','}`)
165
- })
166
-
167
- lines.push(`${spacing}}`)
168
-
169
- return lines.join('\n')
170
- }