@sparkleideas/security 3.0.0-alpha.10
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 +234 -0
- package/__tests__/acceptance/security-compliance.test.ts +674 -0
- package/__tests__/credential-generator.test.ts +310 -0
- package/__tests__/fixtures/configurations.ts +419 -0
- package/__tests__/fixtures/index.ts +21 -0
- package/__tests__/helpers/create-mock.ts +469 -0
- package/__tests__/helpers/index.ts +32 -0
- package/__tests__/input-validator.test.ts +381 -0
- package/__tests__/integration/security-flow.test.ts +606 -0
- package/__tests__/password-hasher.test.ts +239 -0
- package/__tests__/path-validator.test.ts +302 -0
- package/__tests__/safe-executor.test.ts +292 -0
- package/__tests__/token-generator.test.ts +371 -0
- package/__tests__/unit/credential-generator.test.ts +182 -0
- package/__tests__/unit/password-hasher.test.ts +359 -0
- package/__tests__/unit/path-validator.test.ts +509 -0
- package/__tests__/unit/safe-executor.test.ts +667 -0
- package/__tests__/unit/token-generator.test.ts +310 -0
- package/package.json +28 -0
- package/src/CVE-REMEDIATION.ts +251 -0
- package/src/application/index.ts +10 -0
- package/src/application/services/security-application-service.ts +193 -0
- package/src/credential-generator.ts +368 -0
- package/src/domain/entities/security-context.ts +173 -0
- package/src/domain/index.ts +17 -0
- package/src/domain/services/security-domain-service.ts +296 -0
- package/src/index.ts +271 -0
- package/src/input-validator.ts +466 -0
- package/src/password-hasher.ts +270 -0
- package/src/path-validator.ts +525 -0
- package/src/safe-executor.ts +525 -0
- package/src/token-generator.ts +463 -0
- package/tmp.json +0 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input Validator - Comprehensive Input Validation
|
|
3
|
+
*
|
|
4
|
+
* Provides Zod-based validation schemas for all security-critical inputs.
|
|
5
|
+
*
|
|
6
|
+
* Security Properties:
|
|
7
|
+
* - Type-safe validation
|
|
8
|
+
* - Custom error messages
|
|
9
|
+
* - Sanitization transforms
|
|
10
|
+
* - Reusable schemas
|
|
11
|
+
*
|
|
12
|
+
* @module v3/security/input-validator
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { z } from 'zod';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Custom error map for security-focused messages
|
|
19
|
+
*/
|
|
20
|
+
const securityErrorMap: z.ZodErrorMap = (issue, ctx) => {
|
|
21
|
+
switch (issue.code) {
|
|
22
|
+
case z.ZodIssueCode.too_big:
|
|
23
|
+
return { message: `Input exceeds maximum allowed size` };
|
|
24
|
+
case z.ZodIssueCode.too_small:
|
|
25
|
+
return { message: `Input below minimum required size` };
|
|
26
|
+
case z.ZodIssueCode.invalid_string:
|
|
27
|
+
if (issue.validation === 'email') {
|
|
28
|
+
return { message: 'Invalid email format' };
|
|
29
|
+
}
|
|
30
|
+
if (issue.validation === 'url') {
|
|
31
|
+
return { message: 'Invalid URL format' };
|
|
32
|
+
}
|
|
33
|
+
if (issue.validation === 'uuid') {
|
|
34
|
+
return { message: 'Invalid UUID format' };
|
|
35
|
+
}
|
|
36
|
+
return { message: 'Invalid string format' };
|
|
37
|
+
default:
|
|
38
|
+
return { message: ctx.defaultError };
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// Apply custom error map globally for this module
|
|
43
|
+
z.setErrorMap(securityErrorMap);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Common validation patterns as reusable regex
|
|
47
|
+
*/
|
|
48
|
+
const PATTERNS = {
|
|
49
|
+
// Safe identifier: alphanumeric with underscore/hyphen
|
|
50
|
+
SAFE_IDENTIFIER: /^[a-zA-Z][a-zA-Z0-9_-]*$/,
|
|
51
|
+
|
|
52
|
+
// Safe filename: alphanumeric with dot, underscore, hyphen
|
|
53
|
+
SAFE_FILENAME: /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/,
|
|
54
|
+
|
|
55
|
+
// Safe path segment: no traversal
|
|
56
|
+
SAFE_PATH_SEGMENT: /^[^<>:"|?*\x00-\x1f]+$/,
|
|
57
|
+
|
|
58
|
+
// No shell metacharacters
|
|
59
|
+
NO_SHELL_CHARS: /^[^;&|`$(){}><\n\r\0]+$/,
|
|
60
|
+
|
|
61
|
+
// Semantic version
|
|
62
|
+
SEMVER: /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Validation limits
|
|
67
|
+
*/
|
|
68
|
+
const LIMITS = {
|
|
69
|
+
MIN_PASSWORD_LENGTH: 8,
|
|
70
|
+
MAX_PASSWORD_LENGTH: 128,
|
|
71
|
+
MAX_EMAIL_LENGTH: 254,
|
|
72
|
+
MAX_IDENTIFIER_LENGTH: 64,
|
|
73
|
+
MAX_PATH_LENGTH: 4096,
|
|
74
|
+
MAX_CONTENT_LENGTH: 1024 * 1024, // 1MB
|
|
75
|
+
MAX_ARRAY_LENGTH: 1000,
|
|
76
|
+
MAX_OBJECT_KEYS: 100,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// ============================================================================
|
|
80
|
+
// Base Validation Schemas
|
|
81
|
+
// ============================================================================
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Safe string that cannot contain shell metacharacters
|
|
85
|
+
*/
|
|
86
|
+
export const SafeStringSchema = z.string()
|
|
87
|
+
.min(1, 'String cannot be empty')
|
|
88
|
+
.max(LIMITS.MAX_CONTENT_LENGTH, 'String too long')
|
|
89
|
+
.regex(PATTERNS.NO_SHELL_CHARS, 'String contains invalid characters');
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Safe identifier for IDs, names, etc.
|
|
93
|
+
*/
|
|
94
|
+
export const IdentifierSchema = z.string()
|
|
95
|
+
.min(1, 'Identifier cannot be empty')
|
|
96
|
+
.max(LIMITS.MAX_IDENTIFIER_LENGTH, 'Identifier too long')
|
|
97
|
+
.regex(PATTERNS.SAFE_IDENTIFIER, 'Invalid identifier format');
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Safe filename
|
|
101
|
+
*/
|
|
102
|
+
export const FilenameSchema = z.string()
|
|
103
|
+
.min(1, 'Filename cannot be empty')
|
|
104
|
+
.max(255, 'Filename too long')
|
|
105
|
+
.regex(PATTERNS.SAFE_FILENAME, 'Invalid filename format');
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Email schema with length limit
|
|
109
|
+
*/
|
|
110
|
+
export const EmailSchema = z.string()
|
|
111
|
+
.email('Invalid email format')
|
|
112
|
+
.max(LIMITS.MAX_EMAIL_LENGTH, 'Email too long')
|
|
113
|
+
.toLowerCase();
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Password schema with complexity requirements
|
|
117
|
+
*/
|
|
118
|
+
export const PasswordSchema = z.string()
|
|
119
|
+
.min(LIMITS.MIN_PASSWORD_LENGTH, `Password must be at least ${LIMITS.MIN_PASSWORD_LENGTH} characters`)
|
|
120
|
+
.max(LIMITS.MAX_PASSWORD_LENGTH, `Password must not exceed ${LIMITS.MAX_PASSWORD_LENGTH} characters`)
|
|
121
|
+
.refine((val) => /[A-Z]/.test(val), 'Password must contain uppercase letter')
|
|
122
|
+
.refine((val) => /[a-z]/.test(val), 'Password must contain lowercase letter')
|
|
123
|
+
.refine((val) => /\d/.test(val), 'Password must contain digit');
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* UUID schema
|
|
127
|
+
*/
|
|
128
|
+
export const UUIDSchema = z.string().uuid('Invalid UUID format');
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* URL schema with HTTPS enforcement
|
|
132
|
+
*/
|
|
133
|
+
export const HttpsUrlSchema = z.string()
|
|
134
|
+
.url('Invalid URL format')
|
|
135
|
+
.refine(
|
|
136
|
+
(val) => val.startsWith('https://'),
|
|
137
|
+
'URL must use HTTPS'
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* URL schema (allows HTTP for development)
|
|
142
|
+
*/
|
|
143
|
+
export const UrlSchema = z.string()
|
|
144
|
+
.url('Invalid URL format');
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Semantic version schema
|
|
148
|
+
*/
|
|
149
|
+
export const SemverSchema = z.string()
|
|
150
|
+
.regex(PATTERNS.SEMVER, 'Invalid semantic version format');
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Port number schema
|
|
154
|
+
*/
|
|
155
|
+
export const PortSchema = z.number()
|
|
156
|
+
.int('Port must be an integer')
|
|
157
|
+
.min(1, 'Port must be at least 1')
|
|
158
|
+
.max(65535, 'Port must be at most 65535');
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* IP address schema (v4)
|
|
162
|
+
*/
|
|
163
|
+
export const IPv4Schema = z.string()
|
|
164
|
+
.ip({ version: 'v4', message: 'Invalid IPv4 address' });
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* IP address schema (v4 or v6)
|
|
168
|
+
*/
|
|
169
|
+
export const IPSchema = z.string()
|
|
170
|
+
.ip({ message: 'Invalid IP address' });
|
|
171
|
+
|
|
172
|
+
// ============================================================================
|
|
173
|
+
// Authentication Schemas
|
|
174
|
+
// ============================================================================
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* User role schema
|
|
178
|
+
*/
|
|
179
|
+
export const UserRoleSchema = z.enum([
|
|
180
|
+
'admin',
|
|
181
|
+
'operator',
|
|
182
|
+
'developer',
|
|
183
|
+
'viewer',
|
|
184
|
+
'service',
|
|
185
|
+
]);
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Permission schema
|
|
189
|
+
*/
|
|
190
|
+
export const PermissionSchema = z.enum([
|
|
191
|
+
'swarm.create',
|
|
192
|
+
'swarm.read',
|
|
193
|
+
'swarm.update',
|
|
194
|
+
'swarm.delete',
|
|
195
|
+
'swarm.scale',
|
|
196
|
+
'agent.spawn',
|
|
197
|
+
'agent.read',
|
|
198
|
+
'agent.terminate',
|
|
199
|
+
'task.create',
|
|
200
|
+
'task.read',
|
|
201
|
+
'task.cancel',
|
|
202
|
+
'metrics.read',
|
|
203
|
+
'system.admin',
|
|
204
|
+
'api.access',
|
|
205
|
+
]);
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Login request schema
|
|
209
|
+
*/
|
|
210
|
+
export const LoginRequestSchema = z.object({
|
|
211
|
+
email: EmailSchema,
|
|
212
|
+
password: z.string().min(1, 'Password is required'),
|
|
213
|
+
mfaCode: z.string().length(6, 'MFA code must be 6 digits').optional(),
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* User creation schema
|
|
218
|
+
*/
|
|
219
|
+
export const CreateUserSchema = z.object({
|
|
220
|
+
email: EmailSchema,
|
|
221
|
+
password: PasswordSchema,
|
|
222
|
+
role: UserRoleSchema,
|
|
223
|
+
permissions: z.array(PermissionSchema).optional(),
|
|
224
|
+
isActive: z.boolean().optional().default(true),
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* API key creation schema
|
|
229
|
+
*/
|
|
230
|
+
export const CreateApiKeySchema = z.object({
|
|
231
|
+
name: IdentifierSchema,
|
|
232
|
+
permissions: z.array(PermissionSchema).optional(),
|
|
233
|
+
expiresAt: z.date().optional(),
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// ============================================================================
|
|
237
|
+
// Agent & Task Schemas
|
|
238
|
+
// ============================================================================
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Agent type schema
|
|
242
|
+
*/
|
|
243
|
+
export const AgentTypeSchema = z.enum([
|
|
244
|
+
'coder',
|
|
245
|
+
'reviewer',
|
|
246
|
+
'tester',
|
|
247
|
+
'planner',
|
|
248
|
+
'researcher',
|
|
249
|
+
'security-architect',
|
|
250
|
+
'security-auditor',
|
|
251
|
+
'memory-specialist',
|
|
252
|
+
'swarm-specialist',
|
|
253
|
+
'integration-architect',
|
|
254
|
+
'performance-engineer',
|
|
255
|
+
'core-architect',
|
|
256
|
+
'test-architect',
|
|
257
|
+
'queen-coordinator',
|
|
258
|
+
'project-coordinator',
|
|
259
|
+
]);
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Agent spawn request schema
|
|
263
|
+
*/
|
|
264
|
+
export const SpawnAgentSchema = z.object({
|
|
265
|
+
type: AgentTypeSchema,
|
|
266
|
+
id: IdentifierSchema.optional(),
|
|
267
|
+
config: z.record(z.unknown()).optional(),
|
|
268
|
+
timeout: z.number().positive().optional(),
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Task input schema
|
|
273
|
+
*/
|
|
274
|
+
export const TaskInputSchema = z.object({
|
|
275
|
+
taskId: UUIDSchema,
|
|
276
|
+
content: SafeStringSchema.max(10000, 'Task content too long'),
|
|
277
|
+
agentType: AgentTypeSchema,
|
|
278
|
+
priority: z.enum(['low', 'medium', 'high', 'critical']).optional(),
|
|
279
|
+
metadata: z.record(z.unknown()).optional(),
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// ============================================================================
|
|
283
|
+
// Command & Path Schemas
|
|
284
|
+
// ============================================================================
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Command argument schema
|
|
288
|
+
*/
|
|
289
|
+
export const CommandArgumentSchema = z.string()
|
|
290
|
+
.max(1024, 'Argument too long')
|
|
291
|
+
.refine(
|
|
292
|
+
(val) => !val.includes('\0'),
|
|
293
|
+
'Argument contains null byte'
|
|
294
|
+
)
|
|
295
|
+
.refine(
|
|
296
|
+
(val) => !/[;&|`$(){}><]/.test(val),
|
|
297
|
+
'Argument contains shell metacharacters'
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Path schema
|
|
302
|
+
*/
|
|
303
|
+
export const PathSchema = z.string()
|
|
304
|
+
.max(LIMITS.MAX_PATH_LENGTH, 'Path too long')
|
|
305
|
+
.refine(
|
|
306
|
+
(val) => !val.includes('\0'),
|
|
307
|
+
'Path contains null byte'
|
|
308
|
+
)
|
|
309
|
+
.refine(
|
|
310
|
+
(val) => !val.includes('..'),
|
|
311
|
+
'Path contains traversal pattern'
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
// ============================================================================
|
|
315
|
+
// Configuration Schemas
|
|
316
|
+
// ============================================================================
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Security configuration schema
|
|
320
|
+
*/
|
|
321
|
+
export const SecurityConfigSchema = z.object({
|
|
322
|
+
bcryptRounds: z.number().int().min(10).max(20).default(12),
|
|
323
|
+
jwtExpiresIn: z.string().default('24h'),
|
|
324
|
+
sessionTimeout: z.number().positive().default(3600000),
|
|
325
|
+
maxLoginAttempts: z.number().int().positive().default(5),
|
|
326
|
+
lockoutDuration: z.number().positive().default(900000),
|
|
327
|
+
requireMFA: z.boolean().default(false),
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Executor configuration schema
|
|
332
|
+
*/
|
|
333
|
+
export const ExecutorConfigSchema = z.object({
|
|
334
|
+
allowedCommands: z.array(IdentifierSchema).min(1),
|
|
335
|
+
blockedPatterns: z.array(z.string()).optional(),
|
|
336
|
+
timeout: z.number().positive().default(30000),
|
|
337
|
+
maxBuffer: z.number().positive().default(10 * 1024 * 1024),
|
|
338
|
+
cwd: PathSchema.optional(),
|
|
339
|
+
allowSudo: z.boolean().default(false),
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// ============================================================================
|
|
343
|
+
// Sanitization Functions
|
|
344
|
+
// ============================================================================
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Sanitizes a string by removing dangerous characters
|
|
348
|
+
*/
|
|
349
|
+
export function sanitizeString(input: string): string {
|
|
350
|
+
return input
|
|
351
|
+
.replace(/\0/g, '') // Remove null bytes
|
|
352
|
+
.replace(/[<>]/g, '') // Remove HTML brackets
|
|
353
|
+
.replace(/javascript:/gi, '') // Remove javascript: protocol
|
|
354
|
+
.replace(/data:/gi, '') // Remove data: protocol
|
|
355
|
+
.trim();
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Sanitizes HTML entities
|
|
360
|
+
*/
|
|
361
|
+
export function sanitizeHtml(input: string): string {
|
|
362
|
+
return input
|
|
363
|
+
.replace(/&/g, '&')
|
|
364
|
+
.replace(/</g, '<')
|
|
365
|
+
.replace(/>/g, '>')
|
|
366
|
+
.replace(/"/g, '"')
|
|
367
|
+
.replace(/'/g, ''');
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Sanitizes a path by removing traversal patterns
|
|
372
|
+
*/
|
|
373
|
+
export function sanitizePath(input: string): string {
|
|
374
|
+
return input
|
|
375
|
+
.replace(/\0/g, '') // Remove null bytes
|
|
376
|
+
.replace(/\.\./g, '') // Remove traversal patterns
|
|
377
|
+
.replace(/\/+/g, '/') // Normalize slashes
|
|
378
|
+
.replace(/^\//, '') // Remove leading slash
|
|
379
|
+
.trim();
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// ============================================================================
|
|
383
|
+
// Validation Helper Class
|
|
384
|
+
// ============================================================================
|
|
385
|
+
|
|
386
|
+
export class InputValidator {
|
|
387
|
+
/**
|
|
388
|
+
* Validates input against a schema
|
|
389
|
+
*/
|
|
390
|
+
static validate<T>(schema: z.ZodSchema<T>, input: unknown): T {
|
|
391
|
+
return schema.parse(input);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Safely validates input, returning result
|
|
396
|
+
*/
|
|
397
|
+
static safeParse<T>(schema: z.ZodSchema<T>, input: unknown): z.SafeParseReturnType<unknown, T> {
|
|
398
|
+
return schema.safeParse(input);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Validates email
|
|
403
|
+
*/
|
|
404
|
+
static validateEmail(email: string): string {
|
|
405
|
+
return EmailSchema.parse(email);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Validates password
|
|
410
|
+
*/
|
|
411
|
+
static validatePassword(password: string): string {
|
|
412
|
+
return PasswordSchema.parse(password);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Validates identifier
|
|
417
|
+
*/
|
|
418
|
+
static validateIdentifier(id: string): string {
|
|
419
|
+
return IdentifierSchema.parse(id);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Validates path
|
|
424
|
+
*/
|
|
425
|
+
static validatePath(path: string): string {
|
|
426
|
+
return PathSchema.parse(path);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Validates command argument
|
|
431
|
+
*/
|
|
432
|
+
static validateCommandArg(arg: string): string {
|
|
433
|
+
return CommandArgumentSchema.parse(arg);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Validates login request
|
|
438
|
+
*/
|
|
439
|
+
static validateLoginRequest(data: unknown): z.infer<typeof LoginRequestSchema> {
|
|
440
|
+
return LoginRequestSchema.parse(data);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Validates user creation request
|
|
445
|
+
*/
|
|
446
|
+
static validateCreateUser(data: unknown): z.infer<typeof CreateUserSchema> {
|
|
447
|
+
return CreateUserSchema.parse(data);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Validates task input
|
|
452
|
+
*/
|
|
453
|
+
static validateTaskInput(data: unknown): z.infer<typeof TaskInputSchema> {
|
|
454
|
+
return TaskInputSchema.parse(data);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// ============================================================================
|
|
459
|
+
// Export all schemas for direct use
|
|
460
|
+
// ============================================================================
|
|
461
|
+
|
|
462
|
+
export {
|
|
463
|
+
z,
|
|
464
|
+
PATTERNS,
|
|
465
|
+
LIMITS,
|
|
466
|
+
};
|