@scallywag/validation 1.0.0 → 1.0.4
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/README.md +1372 -0
- package/dist/env.d.ts +56 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +262 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware.d.ts +85 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +407 -0
- package/dist/middleware.js.map +1 -0
- package/dist/sanitization.d.ts +41 -0
- package/dist/sanitization.d.ts.map +1 -0
- package/dist/sanitization.js +111 -0
- package/dist/sanitization.js.map +1 -0
- package/dist/schemas.d.ts +231 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +245 -0
- package/dist/schemas.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/types.d.ts +136 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +16 -0
- package/dist/types.js.map +1 -0
- package/dist/validators.d.ts +111 -0
- package/dist/validators.d.ts.map +1 -0
- package/dist/validators.js +324 -0
- package/dist/validators.js.map +1 -0
- package/dist/wrappers.d.ts +117 -0
- package/dist/wrappers.d.ts.map +1 -0
- package/dist/wrappers.js +184 -0
- package/dist/wrappers.js.map +1 -0
- package/dist/zod-schema-converter.d.ts +80 -0
- package/dist/zod-schema-converter.d.ts.map +1 -0
- package/dist/zod-schema-converter.js +97 -0
- package/dist/zod-schema-converter.js.map +1 -0
- package/package.json +40 -1
- package/index.js +0 -1
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation Wrappers
|
|
3
|
+
*
|
|
4
|
+
* High-level wrapper functions for common validation patterns.
|
|
5
|
+
* These provide ergonomic APIs for JSON parsing with schema validation
|
|
6
|
+
* and type-safe assertion helpers.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
import type { ValidationError } from './types';
|
|
10
|
+
/**
|
|
11
|
+
* Error thrown when JSON parsing fails
|
|
12
|
+
*/
|
|
13
|
+
export declare class JsonParseError extends Error {
|
|
14
|
+
readonly code: "JSON_PARSE_ERROR";
|
|
15
|
+
readonly rawInput: string;
|
|
16
|
+
constructor(message: string, rawInput: string, cause?: Error);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Error thrown when schema validation fails
|
|
20
|
+
*/
|
|
21
|
+
export declare class SchemaValidationError extends Error {
|
|
22
|
+
readonly code: "SCHEMA_VALIDATION_ERROR";
|
|
23
|
+
readonly errors: ValidationError[];
|
|
24
|
+
readonly value: unknown;
|
|
25
|
+
constructor(message: string, errors: ValidationError[], value: unknown);
|
|
26
|
+
/**
|
|
27
|
+
* Get a formatted summary of validation errors
|
|
28
|
+
*/
|
|
29
|
+
getErrorSummary(): string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parse a JSON string and validate it against a Zod schema.
|
|
33
|
+
*
|
|
34
|
+
* Combines JSON.parse() with Zod validation in a single operation,
|
|
35
|
+
* providing type-safe parsing with clear error types.
|
|
36
|
+
*
|
|
37
|
+
* @param json - The JSON string to parse
|
|
38
|
+
* @param schema - The Zod schema to validate against
|
|
39
|
+
* @returns The parsed and validated data with full type inference
|
|
40
|
+
* @throws JsonParseError if the JSON string is malformed
|
|
41
|
+
* @throws SchemaValidationError if the parsed data fails schema validation
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* const UserSchema = z.object(\{
|
|
45
|
+
* id: z.string().uuid(),
|
|
46
|
+
* name: z.string().min(1),
|
|
47
|
+
* email: z.string().email(),
|
|
48
|
+
* \});
|
|
49
|
+
*
|
|
50
|
+
* // Fully typed: user is \{ id: string; name: string; email: string \}
|
|
51
|
+
* const user = parseJsonWithSchema(jsonString, UserSchema);
|
|
52
|
+
*
|
|
53
|
+
* // Error handling - catch JsonParseError for invalid JSON
|
|
54
|
+
* // and SchemaValidationError for validation failures
|
|
55
|
+
*/
|
|
56
|
+
export declare function parseJsonWithSchema<T>(json: string, schema: z.ZodSchema<T>): T;
|
|
57
|
+
/**
|
|
58
|
+
* Assert that a value conforms to a Zod schema, narrowing the type.
|
|
59
|
+
*
|
|
60
|
+
* This is a type assertion function that throws if validation fails,
|
|
61
|
+
* allowing TypeScript to narrow the type after the assertion.
|
|
62
|
+
*
|
|
63
|
+
* @param value - The value to validate
|
|
64
|
+
* @param schema - The Zod schema to validate against
|
|
65
|
+
* @throws SchemaValidationError if validation fails
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* const ConfigSchema = z.object(\{ port: z.number(), host: z.string() \});
|
|
69
|
+
*
|
|
70
|
+
* function loadConfig(rawConfig: unknown): void \{
|
|
71
|
+
* // After this line, TypeScript knows rawConfig is \{ port: number; host: string \}
|
|
72
|
+
* assertSchema(rawConfig, ConfigSchema);
|
|
73
|
+
* // Type-safe access to rawConfig.host and rawConfig.port
|
|
74
|
+
* \}
|
|
75
|
+
*/
|
|
76
|
+
export declare function assertSchema<T>(value: unknown, schema: z.ZodSchema<T>): asserts value is T;
|
|
77
|
+
/**
|
|
78
|
+
* Type guard version of assertSchema that returns a boolean instead of throwing.
|
|
79
|
+
*
|
|
80
|
+
* Useful when you want to check if a value matches a schema without throwing,
|
|
81
|
+
* while still getting type narrowing in the true branch.
|
|
82
|
+
*
|
|
83
|
+
* @param value - The value to check
|
|
84
|
+
* @param schema - The Zod schema to validate against
|
|
85
|
+
* @returns True if the value matches the schema, false otherwise
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* function handleMessage(msg: unknown): void \{
|
|
89
|
+
* if (isSchema(msg, TextMessageSchema)) \{
|
|
90
|
+
* // msg is typed as TextMessage here
|
|
91
|
+
* \} else if (isSchema(msg, ImageMessageSchema)) \{
|
|
92
|
+
* // msg is typed as ImageMessage here
|
|
93
|
+
* \}
|
|
94
|
+
* \}
|
|
95
|
+
*/
|
|
96
|
+
export declare function isSchema<T>(value: unknown, schema: z.ZodSchema<T>): value is T;
|
|
97
|
+
/**
|
|
98
|
+
* Parse JSON string safely, returning the parsed value or a default.
|
|
99
|
+
*
|
|
100
|
+
* Use this when you need to parse JSON before applying a Zod schema,
|
|
101
|
+
* or when the schema is determined dynamically.
|
|
102
|
+
*
|
|
103
|
+
* @param json - The JSON string to parse
|
|
104
|
+
* @param defaultValue - Value to return if parsing fails
|
|
105
|
+
* @returns The parsed value as unknown, or the default value
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* // Parse request body, defaulting to empty object on failure
|
|
110
|
+
* const body = safeParseJson(text, {});
|
|
111
|
+
*
|
|
112
|
+
* // Then validate with a schema
|
|
113
|
+
* const validated = MySchema.parse(body);
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export declare function safeParseJson(json: string, defaultValue?: unknown): unknown;
|
|
117
|
+
//# sourceMappingURL=wrappers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrappers.d.ts","sourceRoot":"","sources":["../wrappers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C;;GAEG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC,SAAgB,IAAI,EAAG,kBAAkB,CAAU;IACnD,SAAgB,QAAQ,EAAE,MAAM,CAAC;gBAErB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAgB7D;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,SAAgB,IAAI,EAAG,yBAAyB,CAAU;IAC1D,SAAgB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1C,SAAgB,KAAK,EAAE,OAAO,CAAC;gBAEnB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,EAAE,KAAK,EAAE,OAAO;IAUtE;;OAEG;IACI,eAAe,IAAI,MAAM;CAGjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GACrB,CAAC,CAuCH;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,KAAK,IAAI,CAAC,CAsBpB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACxB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GACrB,KAAK,IAAI,CAAC,CAEZ;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,YAAY,GAAE,OAAc,GAC3B,OAAO,CAMT"}
|
package/dist/wrappers.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation Wrappers
|
|
3
|
+
*
|
|
4
|
+
* High-level wrapper functions for common validation patterns.
|
|
5
|
+
* These provide ergonomic APIs for JSON parsing with schema validation
|
|
6
|
+
* and type-safe assertion helpers.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Error thrown when JSON parsing fails
|
|
10
|
+
*/
|
|
11
|
+
export class JsonParseError extends Error {
|
|
12
|
+
constructor(message, rawInput, cause) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.code = 'JSON_PARSE_ERROR';
|
|
15
|
+
this.name = 'JsonParseError';
|
|
16
|
+
this.rawInput = rawInput;
|
|
17
|
+
if (cause !== undefined) {
|
|
18
|
+
Object.defineProperty(this, 'cause', {
|
|
19
|
+
value: cause,
|
|
20
|
+
writable: false,
|
|
21
|
+
enumerable: false,
|
|
22
|
+
configurable: false,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
if (Error.captureStackTrace) {
|
|
26
|
+
Error.captureStackTrace(this, this.constructor);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Error thrown when schema validation fails
|
|
32
|
+
*/
|
|
33
|
+
export class SchemaValidationError extends Error {
|
|
34
|
+
constructor(message, errors, value) {
|
|
35
|
+
super(message);
|
|
36
|
+
this.code = 'SCHEMA_VALIDATION_ERROR';
|
|
37
|
+
this.name = 'SchemaValidationError';
|
|
38
|
+
this.errors = errors;
|
|
39
|
+
this.value = value;
|
|
40
|
+
if (Error.captureStackTrace) {
|
|
41
|
+
Error.captureStackTrace(this, this.constructor);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get a formatted summary of validation errors
|
|
46
|
+
*/
|
|
47
|
+
getErrorSummary() {
|
|
48
|
+
return this.errors.map((err) => `${err.field}: ${err.message}`).join('; ');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Parse a JSON string and validate it against a Zod schema.
|
|
53
|
+
*
|
|
54
|
+
* Combines JSON.parse() with Zod validation in a single operation,
|
|
55
|
+
* providing type-safe parsing with clear error types.
|
|
56
|
+
*
|
|
57
|
+
* @param json - The JSON string to parse
|
|
58
|
+
* @param schema - The Zod schema to validate against
|
|
59
|
+
* @returns The parsed and validated data with full type inference
|
|
60
|
+
* @throws JsonParseError if the JSON string is malformed
|
|
61
|
+
* @throws SchemaValidationError if the parsed data fails schema validation
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* const UserSchema = z.object(\{
|
|
65
|
+
* id: z.string().uuid(),
|
|
66
|
+
* name: z.string().min(1),
|
|
67
|
+
* email: z.string().email(),
|
|
68
|
+
* \});
|
|
69
|
+
*
|
|
70
|
+
* // Fully typed: user is \{ id: string; name: string; email: string \}
|
|
71
|
+
* const user = parseJsonWithSchema(jsonString, UserSchema);
|
|
72
|
+
*
|
|
73
|
+
* // Error handling - catch JsonParseError for invalid JSON
|
|
74
|
+
* // and SchemaValidationError for validation failures
|
|
75
|
+
*/
|
|
76
|
+
export function parseJsonWithSchema(json, schema) {
|
|
77
|
+
// Step 1: Parse JSON
|
|
78
|
+
let parsed;
|
|
79
|
+
try {
|
|
80
|
+
parsed = JSON.parse(json);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
const message = error instanceof SyntaxError
|
|
84
|
+
? `Invalid JSON: ${error.message}`
|
|
85
|
+
: 'Invalid JSON: Unknown parsing error';
|
|
86
|
+
throw new JsonParseError(message, json, error instanceof Error ? error : undefined);
|
|
87
|
+
}
|
|
88
|
+
// Step 2: Validate against schema
|
|
89
|
+
const result = schema.safeParse(parsed);
|
|
90
|
+
if (result.success) {
|
|
91
|
+
return result.data;
|
|
92
|
+
}
|
|
93
|
+
// Convert ZodError to ValidationError array
|
|
94
|
+
const validationErrors = result.error.issues.map((issue) => ({
|
|
95
|
+
field: issue.path.join('.') || 'root',
|
|
96
|
+
message: issue.message,
|
|
97
|
+
code: issue.code,
|
|
98
|
+
value: 'received' in issue ? issue.received : undefined,
|
|
99
|
+
}));
|
|
100
|
+
throw new SchemaValidationError(`Schema validation failed: ${validationErrors.length} error(s)`, validationErrors, parsed);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Assert that a value conforms to a Zod schema, narrowing the type.
|
|
104
|
+
*
|
|
105
|
+
* This is a type assertion function that throws if validation fails,
|
|
106
|
+
* allowing TypeScript to narrow the type after the assertion.
|
|
107
|
+
*
|
|
108
|
+
* @param value - The value to validate
|
|
109
|
+
* @param schema - The Zod schema to validate against
|
|
110
|
+
* @throws SchemaValidationError if validation fails
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* const ConfigSchema = z.object(\{ port: z.number(), host: z.string() \});
|
|
114
|
+
*
|
|
115
|
+
* function loadConfig(rawConfig: unknown): void \{
|
|
116
|
+
* // After this line, TypeScript knows rawConfig is \{ port: number; host: string \}
|
|
117
|
+
* assertSchema(rawConfig, ConfigSchema);
|
|
118
|
+
* // Type-safe access to rawConfig.host and rawConfig.port
|
|
119
|
+
* \}
|
|
120
|
+
*/
|
|
121
|
+
export function assertSchema(value, schema) {
|
|
122
|
+
const result = schema.safeParse(value);
|
|
123
|
+
if (result.success) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
// Convert ZodError to ValidationError array
|
|
127
|
+
const validationErrors = result.error.issues.map((issue) => ({
|
|
128
|
+
field: issue.path.join('.') || 'root',
|
|
129
|
+
message: issue.message,
|
|
130
|
+
code: issue.code,
|
|
131
|
+
value: 'received' in issue ? issue.received : undefined,
|
|
132
|
+
}));
|
|
133
|
+
throw new SchemaValidationError(`Assertion failed: value does not match schema`, validationErrors, value);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Type guard version of assertSchema that returns a boolean instead of throwing.
|
|
137
|
+
*
|
|
138
|
+
* Useful when you want to check if a value matches a schema without throwing,
|
|
139
|
+
* while still getting type narrowing in the true branch.
|
|
140
|
+
*
|
|
141
|
+
* @param value - The value to check
|
|
142
|
+
* @param schema - The Zod schema to validate against
|
|
143
|
+
* @returns True if the value matches the schema, false otherwise
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* function handleMessage(msg: unknown): void \{
|
|
147
|
+
* if (isSchema(msg, TextMessageSchema)) \{
|
|
148
|
+
* // msg is typed as TextMessage here
|
|
149
|
+
* \} else if (isSchema(msg, ImageMessageSchema)) \{
|
|
150
|
+
* // msg is typed as ImageMessage here
|
|
151
|
+
* \}
|
|
152
|
+
* \}
|
|
153
|
+
*/
|
|
154
|
+
export function isSchema(value, schema) {
|
|
155
|
+
return schema.safeParse(value).success;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Parse JSON string safely, returning the parsed value or a default.
|
|
159
|
+
*
|
|
160
|
+
* Use this when you need to parse JSON before applying a Zod schema,
|
|
161
|
+
* or when the schema is determined dynamically.
|
|
162
|
+
*
|
|
163
|
+
* @param json - The JSON string to parse
|
|
164
|
+
* @param defaultValue - Value to return if parsing fails
|
|
165
|
+
* @returns The parsed value as unknown, or the default value
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```typescript
|
|
169
|
+
* // Parse request body, defaulting to empty object on failure
|
|
170
|
+
* const body = safeParseJson(text, {});
|
|
171
|
+
*
|
|
172
|
+
* // Then validate with a schema
|
|
173
|
+
* const validated = MySchema.parse(body);
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
export function safeParseJson(json, defaultValue = null) {
|
|
177
|
+
try {
|
|
178
|
+
return JSON.parse(json);
|
|
179
|
+
}
|
|
180
|
+
catch (_a) {
|
|
181
|
+
return defaultValue;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=wrappers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrappers.js","sourceRoot":"","sources":["../wrappers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod Schema Converter
|
|
3
|
+
*
|
|
4
|
+
* Converts Zod schemas to JSON Schema using Zod 4's native toJSONSchema() method.
|
|
5
|
+
* This enables a single source of truth: define schemas in Zod, derive JSON Schema
|
|
6
|
+
* for MCP tools, OpenAPI docs, and discovery metadata automatically.
|
|
7
|
+
*
|
|
8
|
+
* @module kernel/validation/zod-schema-converter
|
|
9
|
+
*/
|
|
10
|
+
import type { ZodSchema } from 'zod';
|
|
11
|
+
/**
|
|
12
|
+
* JSON Schema type - the result of toJSONSchema()
|
|
13
|
+
*/
|
|
14
|
+
export type JsonSchema = Record<string, unknown>;
|
|
15
|
+
/**
|
|
16
|
+
* Converts a Zod schema to JSON Schema using Zod 4's native method.
|
|
17
|
+
*
|
|
18
|
+
* @param schema - The Zod schema to convert
|
|
19
|
+
* @returns JSON Schema representation of the Zod schema
|
|
20
|
+
* @throws Error if schema doesn't support toJSONSchema (non-Zod 4)
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const userSchema = z.object({ name: z.string(), age: z.number() });
|
|
25
|
+
* const jsonSchema = zodToJsonSchema(userSchema);
|
|
26
|
+
* // { type: 'object', properties: { name: { type: 'string' }, age: { type: 'number' } }, required: ['name', 'age'] }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function zodToJsonSchema(schema: ZodSchema): JsonSchema;
|
|
30
|
+
/**
|
|
31
|
+
* Safely converts a Zod schema to JSON Schema, returning undefined on failure.
|
|
32
|
+
* Useful when schema conversion is optional and shouldn't break the flow.
|
|
33
|
+
*
|
|
34
|
+
* @param schema - The Zod schema to convert (may be undefined)
|
|
35
|
+
* @returns JSON Schema representation or undefined
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* const schema = validation?.input;
|
|
40
|
+
* const jsonSchema = safeZodToJsonSchema(schema);
|
|
41
|
+
* // Returns undefined if schema is undefined or conversion fails
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function safeZodToJsonSchema(schema: ZodSchema | undefined): JsonSchema | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Schema extraction result for method input/output schemas.
|
|
47
|
+
*/
|
|
48
|
+
export interface MethodSchemas {
|
|
49
|
+
/** JSON Schema for method input parameters */
|
|
50
|
+
input?: JsonSchema | undefined;
|
|
51
|
+
/** JSON Schema for method return value */
|
|
52
|
+
output?: JsonSchema | undefined;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Extracts JSON Schema from Zod schemas for method input and output.
|
|
56
|
+
* Used by ConventionProcessor to embed schemas in discovery metadata.
|
|
57
|
+
*
|
|
58
|
+
* @param inputSchema - Zod schema for method input (optional)
|
|
59
|
+
* @param outputSchema - Zod schema for method output (optional)
|
|
60
|
+
* @returns Object with input/output JSON Schemas (undefined if not provided)
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* const CreateEventSchema = z.object({ title: z.string() });
|
|
65
|
+
* const EventResponseSchema = z.object({ event: z.object({ id: z.string() }) });
|
|
66
|
+
*
|
|
67
|
+
* const schemas = extractMethodSchemas(CreateEventSchema, EventResponseSchema);
|
|
68
|
+
* // { input: { type: 'object', ... }, output: { type: 'object', ... } }
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export declare function extractMethodSchemas(inputSchema?: ZodSchema, outputSchema?: ZodSchema): MethodSchemas;
|
|
72
|
+
/**
|
|
73
|
+
* Checks if a value is a Zod schema with toJSONSchema support.
|
|
74
|
+
* Useful for runtime type checking in dynamic scenarios.
|
|
75
|
+
*
|
|
76
|
+
* @param value - Value to check
|
|
77
|
+
* @returns True if value is a Zod schema that supports JSON Schema conversion
|
|
78
|
+
*/
|
|
79
|
+
export declare function isZodSchemaWithJsonSupport(value: unknown): value is ZodSchema;
|
|
80
|
+
//# sourceMappingURL=zod-schema-converter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod-schema-converter.d.ts","sourceRoot":"","sources":["../zod-schema-converter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAErC;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEjD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,CAc7D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,GAAG,SAAS,GAC5B,UAAU,GAAG,SAAS,CAUxB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,8CAA8C;IAC9C,KAAK,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAC/B,0CAA0C;IAC1C,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,CAAC,EAAE,SAAS,EACvB,YAAY,CAAC,EAAE,SAAS,GACvB,aAAa,CAKf;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAW7E"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod Schema Converter
|
|
3
|
+
*
|
|
4
|
+
* Converts Zod schemas to JSON Schema using Zod 4's native toJSONSchema() method.
|
|
5
|
+
* This enables a single source of truth: define schemas in Zod, derive JSON Schema
|
|
6
|
+
* for MCP tools, OpenAPI docs, and discovery metadata automatically.
|
|
7
|
+
*
|
|
8
|
+
* @module kernel/validation/zod-schema-converter
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Converts a Zod schema to JSON Schema using Zod 4's native method.
|
|
12
|
+
*
|
|
13
|
+
* @param schema - The Zod schema to convert
|
|
14
|
+
* @returns JSON Schema representation of the Zod schema
|
|
15
|
+
* @throws Error if schema doesn't support toJSONSchema (non-Zod 4)
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const userSchema = z.object({ name: z.string(), age: z.number() });
|
|
20
|
+
* const jsonSchema = zodToJsonSchema(userSchema);
|
|
21
|
+
* // { type: 'object', properties: { name: { type: 'string' }, age: { type: 'number' } }, required: ['name', 'age'] }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export function zodToJsonSchema(schema) {
|
|
25
|
+
// Zod 4 schemas have toJSONSchema() method directly
|
|
26
|
+
// Type assertion needed because ZodSchema base type doesn't expose it
|
|
27
|
+
const schemaWithMethod = schema;
|
|
28
|
+
if (typeof schemaWithMethod.toJSONSchema === 'function') {
|
|
29
|
+
return schemaWithMethod.toJSONSchema();
|
|
30
|
+
}
|
|
31
|
+
throw new Error('Schema does not support toJSONSchema(). Ensure Zod 4+ is installed and the schema is a valid Zod schema.');
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Safely converts a Zod schema to JSON Schema, returning undefined on failure.
|
|
35
|
+
* Useful when schema conversion is optional and shouldn't break the flow.
|
|
36
|
+
*
|
|
37
|
+
* @param schema - The Zod schema to convert (may be undefined)
|
|
38
|
+
* @returns JSON Schema representation or undefined
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const schema = validation?.input;
|
|
43
|
+
* const jsonSchema = safeZodToJsonSchema(schema);
|
|
44
|
+
* // Returns undefined if schema is undefined or conversion fails
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export function safeZodToJsonSchema(schema) {
|
|
48
|
+
if (!schema) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
return zodToJsonSchema(schema);
|
|
53
|
+
}
|
|
54
|
+
catch (_a) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Extracts JSON Schema from Zod schemas for method input and output.
|
|
60
|
+
* Used by ConventionProcessor to embed schemas in discovery metadata.
|
|
61
|
+
*
|
|
62
|
+
* @param inputSchema - Zod schema for method input (optional)
|
|
63
|
+
* @param outputSchema - Zod schema for method output (optional)
|
|
64
|
+
* @returns Object with input/output JSON Schemas (undefined if not provided)
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const CreateEventSchema = z.object({ title: z.string() });
|
|
69
|
+
* const EventResponseSchema = z.object({ event: z.object({ id: z.string() }) });
|
|
70
|
+
*
|
|
71
|
+
* const schemas = extractMethodSchemas(CreateEventSchema, EventResponseSchema);
|
|
72
|
+
* // { input: { type: 'object', ... }, output: { type: 'object', ... } }
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export function extractMethodSchemas(inputSchema, outputSchema) {
|
|
76
|
+
return {
|
|
77
|
+
input: safeZodToJsonSchema(inputSchema),
|
|
78
|
+
output: safeZodToJsonSchema(outputSchema),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Checks if a value is a Zod schema with toJSONSchema support.
|
|
83
|
+
* Useful for runtime type checking in dynamic scenarios.
|
|
84
|
+
*
|
|
85
|
+
* @param value - Value to check
|
|
86
|
+
* @returns True if value is a Zod schema that supports JSON Schema conversion
|
|
87
|
+
*/
|
|
88
|
+
export function isZodSchemaWithJsonSupport(value) {
|
|
89
|
+
if (typeof value !== 'object' || value === null) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
const maybeSchema = value;
|
|
93
|
+
return (typeof maybeSchema['toJSONSchema'] === 'function' &&
|
|
94
|
+
typeof maybeSchema['parse'] === 'function' &&
|
|
95
|
+
typeof maybeSchema['safeParse'] === 'function');
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=zod-schema-converter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zod-schema-converter.js","sourceRoot":"","sources":["../zod-schema-converter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,eAAe,CAAC,MAAiB;IAC/C,oDAAoD;IACpD,sEAAsE;IACtE,MAAM,gBAAgB,GAAG,MAExB,CAAC;IAEF,IAAI,OAAO,gBAAgB,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;QACxD,OAAO,gBAAgB,CAAC,YAAY,EAAE,CAAC;IACzC,CAAC;IAED,MAAM,IAAI,KAAK,CACb,0GAA0G,CAC3G,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAA6B;IAE7B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,CAAC;QACH,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAAC,WAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAYD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,oBAAoB,CAClC,WAAuB,EACvB,YAAwB;IAExB,OAAO;QACL,KAAK,EAAE,mBAAmB,CAAC,WAAW,CAAC;QACvC,MAAM,EAAE,mBAAmB,CAAC,YAAY,CAAC;KAC1C,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,0BAA0B,CAAC,KAAc;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,WAAW,GAAG,KAAgC,CAAC;IACrD,OAAO,CACL,OAAO,WAAW,CAAC,cAAc,CAAC,KAAK,UAAU;QACjD,OAAO,WAAW,CAAC,OAAO,CAAC,KAAK,UAAU;QAC1C,OAAO,WAAW,CAAC,WAAW,CAAC,KAAK,UAAU,CAC/C,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1 +1,40 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"name": "@scallywag/validation",
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"description": "ScallywagOS validation - Zod schemas, sanitization, XSS/SQL injection prevention",
|
|
5
|
+
"main": "./index.ts",
|
|
6
|
+
"types": "./index.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"registry": "https://registry.npmjs.org/",
|
|
12
|
+
"access": "restricted",
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./*": {
|
|
21
|
+
"types": "./dist/*.d.ts",
|
|
22
|
+
"import": "./dist/*.js"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/We-Are-Scallywag/scallywagOS.git",
|
|
29
|
+
"directory": "packages/kernel/validation"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsc --build tsconfig.build.json",
|
|
33
|
+
"prepublishOnly": "pnpm run build",
|
|
34
|
+
"clean": "rm -rf dist"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@scallywag/gateway": "workspace:*",
|
|
38
|
+
"@scallywag/security": "workspace:*"
|
|
39
|
+
}
|
|
40
|
+
}
|
package/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
// test
|